View Javadoc
1   /**
2    * Logback: the reliable, generic, fast and flexible logging framework.
3    * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
4    *
5    * This program and the accompanying materials are dual-licensed under
6    * either the terms of the Eclipse Public License v1.0 as published by
7    * the Eclipse Foundation
8    *
9    *   or (per the licensee's choosing)
10   *
11   * under the terms of the GNU Lesser General Public License version 2.1
12   * as published by the Free Software Foundation.
13   */
14  package ch.qos.logback.core.net;
15  
16  import static org.junit.Assert.assertEquals;
17  import static org.junit.Assert.assertFalse;
18  import static org.junit.Assert.assertTrue;
19  import static org.mockito.Matchers.anyInt;
20  import static org.mockito.Mockito.mock;
21  import static org.mockito.Mockito.spy;
22  import static org.mockito.Mockito.timeout;
23  import static org.mockito.Mockito.verify;
24  import static org.mockito.Mockito.when;
25  
26  import java.io.IOException;
27  import java.io.ObjectInputStream;
28  import java.io.OutputStream;
29  import java.io.Serializable;
30  import java.net.ServerSocket;
31  import java.net.Socket;
32  import java.util.concurrent.LinkedBlockingDeque;
33  import java.util.concurrent.ScheduledExecutorService;
34  import java.util.concurrent.TimeUnit;
35  
36  import org.junit.After;
37  import org.junit.Before;
38  import org.junit.Test;
39  
40  import ch.qos.logback.core.net.mock.MockContext;
41  import ch.qos.logback.core.net.server.test.ServerSocketUtil;
42  import ch.qos.logback.core.spi.PreSerializationTransformer;
43  import ch.qos.logback.core.util.ExecutorServiceUtil;
44  
45  /**
46   * Integration tests for {@link ch.qos.logback.core.net.AbstractSocketAppender}.
47   *
48   * @author Carl Harris
49   * @author Sebastian Gröbler
50   */
51  public class AbstractSocketAppenderIntegrationTest {
52  
53      private static final int TIMEOUT = 2000;
54  
55      private ScheduledExecutorService executorService = ExecutorServiceUtil.newScheduledExecutorService();
56      private MockContext mockContext = new MockContext(executorService);
57      private AutoFlushingObjectWriter objectWriter;
58      private ObjectWriterFactory objectWriterFactory = new SpyProducingObjectWriterFactory();
59      private LinkedBlockingDeque<String> deque = spy(new LinkedBlockingDeque<String>(1));
60      private QueueFactory queueFactory = mock(QueueFactory.class);
61      private InstrumentedSocketAppender instrumentedAppender = new InstrumentedSocketAppender(queueFactory, objectWriterFactory);
62  
63      @Before
64      public void setUp() throws Exception {
65          when(queueFactory.<String> newLinkedBlockingDeque(anyInt())).thenReturn(deque);
66          instrumentedAppender.setContext(mockContext);
67      }
68  
69      @After
70      public void tearDown() throws Exception {
71          instrumentedAppender.stop();
72          assertFalse(instrumentedAppender.isStarted());
73          executorService.shutdownNow();
74          assertTrue(executorService.awaitTermination(TIMEOUT, TimeUnit.MILLISECONDS));
75      }
76  
77      @Test
78      public void dispatchesEvents() throws Exception {
79  
80          // given
81          ServerSocket serverSocket = ServerSocketUtil.createServerSocket();
82          instrumentedAppender.setRemoteHost(serverSocket.getInetAddress().getHostAddress());
83          instrumentedAppender.setPort(serverSocket.getLocalPort());
84          instrumentedAppender.start();
85  
86          Socket appenderSocket = serverSocket.accept();
87          serverSocket.close();
88  
89          // when
90          instrumentedAppender.append("some event");
91  
92          // wait for event to be taken from deque and being written into the stream
93          verify(deque, timeout(TIMEOUT).atLeastOnce()).takeFirst();
94          verify(objectWriter, timeout(TIMEOUT)).write("some event");
95  
96          // then
97          ObjectInputStream ois = new ObjectInputStream(appenderSocket.getInputStream());
98          assertEquals("some event", ois.readObject());
99          appenderSocket.close();
100     }
101 
102     private static class InstrumentedSocketAppender extends AbstractSocketAppender<String> {
103 
104         public InstrumentedSocketAppender(QueueFactory queueFactory, ObjectWriterFactory objectWriterFactory) {
105             super(queueFactory, objectWriterFactory);
106         }
107 
108         @Override
109         protected void postProcessEvent(String event) {
110         }
111 
112         @Override
113         protected PreSerializationTransformer<String> getPST() {
114             return new PreSerializationTransformer<String>() {
115                 public Serializable transform(String event) {
116                     return event;
117                 }
118             };
119         }
120     }
121 
122     private class SpyProducingObjectWriterFactory extends ObjectWriterFactory {
123 
124         @Override
125         public AutoFlushingObjectWriter newAutoFlushingObjectWriter(OutputStream outputStream) throws IOException {
126             objectWriter = spy(super.newAutoFlushingObjectWriter(outputStream));
127             return objectWriter;
128         }
129     }
130 }