001/** 002 * Logback: the reliable, generic, fast and flexible logging framework. 003 * Copyright (C) 1999-2015, QOS.ch. All rights reserved. 004 * 005 * This program and the accompanying materials are dual-licensed under 006 * either the terms of the Eclipse Public License v1.0 as published by 007 * the Eclipse Foundation 008 * 009 * or (per the licensee's choosing) 010 * 011 * under the terms of the GNU Lesser General Public License version 2.1 012 * as published by the Free Software Foundation. 013 */ 014package ch.qos.logback.core.net; 015 016import static org.junit.Assert.assertEquals; 017import static org.junit.Assert.assertFalse; 018import static org.junit.Assert.assertTrue; 019import static org.mockito.Matchers.anyInt; 020import static org.mockito.Mockito.mock; 021import static org.mockito.Mockito.spy; 022import static org.mockito.Mockito.timeout; 023import static org.mockito.Mockito.verify; 024import static org.mockito.Mockito.when; 025 026import java.io.IOException; 027import java.io.ObjectInputStream; 028import java.io.OutputStream; 029import java.io.Serializable; 030import java.net.ServerSocket; 031import java.net.Socket; 032import java.util.concurrent.LinkedBlockingDeque; 033import java.util.concurrent.ScheduledExecutorService; 034import java.util.concurrent.TimeUnit; 035 036import org.junit.After; 037import org.junit.Before; 038import org.junit.Test; 039 040import ch.qos.logback.core.net.mock.MockContext; 041import ch.qos.logback.core.net.server.test.ServerSocketUtil; 042import ch.qos.logback.core.spi.PreSerializationTransformer; 043import ch.qos.logback.core.util.ExecutorServiceUtil; 044 045/** 046 * Integration tests for {@link ch.qos.logback.core.net.AbstractSocketAppender}. 047 * 048 * @author Carl Harris 049 * @author Sebastian Gröbler 050 */ 051public class AbstractSocketAppenderIntegrationTest { 052 053 private static final int TIMEOUT = 2000; 054 055 private ScheduledExecutorService executorService = ExecutorServiceUtil.newScheduledExecutorService(); 056 private MockContext mockContext = new MockContext(executorService); 057 private AutoFlushingObjectWriter objectWriter; 058 private ObjectWriterFactory objectWriterFactory = new SpyProducingObjectWriterFactory(); 059 private LinkedBlockingDeque<String> deque = spy(new LinkedBlockingDeque<String>(1)); 060 private QueueFactory queueFactory = mock(QueueFactory.class); 061 private InstrumentedSocketAppender instrumentedAppender = new InstrumentedSocketAppender(queueFactory, objectWriterFactory); 062 063 @Before 064 public void setUp() throws Exception { 065 when(queueFactory.<String> newLinkedBlockingDeque(anyInt())).thenReturn(deque); 066 instrumentedAppender.setContext(mockContext); 067 } 068 069 @After 070 public void tearDown() throws Exception { 071 instrumentedAppender.stop(); 072 assertFalse(instrumentedAppender.isStarted()); 073 executorService.shutdownNow(); 074 assertTrue(executorService.awaitTermination(TIMEOUT, TimeUnit.MILLISECONDS)); 075 } 076 077 @Test 078 public void dispatchesEvents() throws Exception { 079 080 // given 081 ServerSocket serverSocket = ServerSocketUtil.createServerSocket(); 082 instrumentedAppender.setRemoteHost(serverSocket.getInetAddress().getHostAddress()); 083 instrumentedAppender.setPort(serverSocket.getLocalPort()); 084 instrumentedAppender.start(); 085 086 Socket appenderSocket = serverSocket.accept(); 087 serverSocket.close(); 088 089 // when 090 instrumentedAppender.append("some event"); 091 092 // wait for event to be taken from deque and being written into the stream 093 verify(deque, timeout(TIMEOUT).atLeastOnce()).takeFirst(); 094 verify(objectWriter, timeout(TIMEOUT)).write("some event"); 095 096 // then 097 ObjectInputStream ois = new ObjectInputStream(appenderSocket.getInputStream()); 098 assertEquals("some event", ois.readObject()); 099 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}