1 package org.apache.maven.plugin.surefire.extensions;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import org.apache.maven.plugin.surefire.log.api.ConsoleLogger;
23 import org.apache.maven.surefire.api.booter.MasterProcessChannelEncoder;
24 import org.apache.maven.surefire.booter.spi.SurefireMasterProcessChannelProcessorFactory;
25 import org.apache.maven.surefire.api.event.Event;
26 import org.apache.maven.surefire.extensions.EventHandler;
27 import org.apache.maven.surefire.extensions.ForkNodeArguments;
28 import org.apache.maven.surefire.extensions.util.CountdownCloseable;
29 import org.apache.maven.surefire.api.report.ConsoleOutputReceiver;
30 import org.junit.Test;
31
32 import javax.annotation.Nonnull;
33 import java.io.Closeable;
34 import java.nio.ByteBuffer;
35 import java.nio.channels.ReadableByteChannel;
36 import java.util.concurrent.CountDownLatch;
37 import java.util.concurrent.TimeUnit;
38 import java.util.concurrent.atomic.AtomicInteger;
39 import java.util.concurrent.atomic.AtomicLong;
40
41 import static org.fest.assertions.Assertions.assertThat;
42 import static org.mockito.ArgumentMatchers.any;
43 import static org.mockito.Mockito.mock;
44 import static org.mockito.Mockito.when;
45
46
47
48
49 @SuppressWarnings( "checkstyle:magicnumber" )
50 public class E2ETest
51 {
52 private static final String LONG_STRING =
53 "0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789";
54
55 @Test
56 public void test() throws Exception
57 {
58 ConsoleLogger logger = mock( ConsoleLogger.class );
59 ForkNodeArguments arguments = mock( ForkNodeArguments.class );
60 when( arguments.getForkChannelId() ).thenReturn( 1 );
61 when( arguments.getConsoleLogger() ).thenReturn( logger );
62 final SurefireForkChannel server = new SurefireForkChannel( arguments );
63
64 final String connection = server.getForkNodeConnectionString();
65
66 final SurefireMasterProcessChannelProcessorFactory factory = new SurefireMasterProcessChannelProcessorFactory();
67 factory.connect( connection );
68 final MasterProcessChannelEncoder encoder = factory.createEncoder();
69
70 System.gc();
71
72 TimeUnit.SECONDS.sleep( 3L );
73
74 final CountDownLatch awaitHandlerFinished = new CountDownLatch( 2 );
75
76 Thread t = new Thread()
77 {
78 @Override
79 public void run()
80 {
81 ConsoleOutputReceiver target = new ConsoleOutputReceiver()
82 {
83 @Override
84 public void writeTestOutput( String output, boolean newLine, boolean stdout )
85 {
86 encoder.stdOut( output, true );
87 }
88 };
89
90
91
92
93
94
95 try
96 {
97 long t1 = System.currentTimeMillis();
98 for ( int i = 0; i < 400_000; i++ )
99 {
100
101 encoder.stdOut( LONG_STRING, true );
102 }
103 long t2 = System.currentTimeMillis();
104 long spent = t2 - t1;
105
106
107 System.out.println( spent + "ms on write" );
108 awaitHandlerFinished.countDown();
109 }
110 catch ( Exception e )
111 {
112 e.printStackTrace();
113 }
114 }
115 };
116 t.setDaemon( true );
117 t.start();
118
119 server.connectToClient();
120
121 final AtomicLong readTime = new AtomicLong();
122
123 EventHandler<Event> h = new EventHandler<Event>()
124 {
125 private final AtomicInteger counter = new AtomicInteger();
126 private volatile long t1;
127
128 @Override
129 public void handleEvent( @Nonnull Event event )
130 {
131 try
132 {
133 if ( counter.getAndIncrement() == 0 )
134 {
135 t1 = System.currentTimeMillis();
136 }
137
138 long t2 = System.currentTimeMillis();
139 long spent = t2 - t1;
140
141 if ( counter.get() % 100_000 == 0 )
142 {
143 System.out.println( spent + "ms: " + counter.get() );
144 }
145
146 if ( counter.get() == 320_000 )
147 {
148 readTime.set( spent );
149 System.out.println( spent + "ms on read" );
150 awaitHandlerFinished.countDown();
151 }
152 }
153 catch ( Exception e )
154 {
155 e.printStackTrace();
156 }
157 }
158 };
159
160 Closeable c = new Closeable()
161 {
162 @Override
163 public void close()
164 {
165 }
166 };
167
168 ReadableByteChannel stdOut = mock( ReadableByteChannel.class );
169 when( stdOut.read( any( ByteBuffer.class ) ) ).thenReturn( -1 );
170 server.bindEventHandler( h, new CountdownCloseable( c, 1 ), stdOut )
171 .start();
172
173 assertThat( awaitHandlerFinished.await( 30L, TimeUnit.SECONDS ) )
174 .isTrue();
175
176 factory.close();
177 server.close();
178
179
180
181 assertThat( readTime.get() )
182 .describedAs( "The performance test should assert 2s of read time. "
183 + "The limit 6s guarantees that the read time does not exceed this limit on overloaded CPU." )
184 .isPositive()
185 .isLessThanOrEqualTo( 6_000L );
186 }
187 }