3
3
import org .junit .Test ;
4
4
import org .junit .runner .Description ;
5
5
6
- import java .util .concurrent .*;
6
+ import java .util .Random ;
7
+ import java .util .concurrent .Callable ;
8
+ import java .util .concurrent .CountDownLatch ;
9
+ import java .util .concurrent .CyclicBarrier ;
10
+ import java .util .concurrent .Executors ;
11
+ import java .util .concurrent .ExecutorService ;
12
+ import java .util .concurrent .TimeUnit ;
7
13
import java .util .concurrent .atomic .AtomicBoolean ;
8
14
import java .util .concurrent .atomic .AtomicInteger ;
9
15
@@ -58,16 +64,16 @@ public void run() {
58
64
}
59
65
60
66
private static class ExaminedListener extends RunListener {
61
- volatile boolean useMe = false ;
67
+ final boolean throwFromTestStarted ;
62
68
volatile boolean hasTestFailure = false ;
63
69
64
- ExaminedListener (boolean useMe ) {
65
- this .useMe = useMe ;
70
+ ExaminedListener (boolean throwFromTestStarted ) {
71
+ this .throwFromTestStarted = throwFromTestStarted ;
66
72
}
67
73
68
74
@ Override
69
75
public void testStarted (Description description ) throws Exception {
70
- if (!useMe ) {
76
+ if (!throwFromTestStarted ) {
71
77
throw new Exception ();
72
78
}
73
79
}
@@ -78,94 +84,88 @@ public void testFailure(Failure failure) throws Exception {
78
84
}
79
85
}
80
86
81
- @ Test
82
- public void reportConcurrentFailuresAfterAddListener () throws Exception {
83
- int totalListenersFailures = 0 ;
87
+ private abstract class AbstractConcurrentFailuresTest {
84
88
85
- final ExaminedListener [] examinedListeners = new ExaminedListener [1000 ];
86
- for (int i = 0 ; i < examinedListeners .length ; ++i ) {
87
- boolean fail = StrictMath .random () >= 0.5d ;
88
- if (fail ) {
89
- ++totalListenersFailures ;
90
- }
91
- examinedListeners [i ] = new ExaminedListener (!fail );
92
- }
89
+ protected abstract void addListener (ExaminedListener listener );
93
90
94
- final CyclicBarrier trigger = new CyclicBarrier ( 2 );
95
- final AtomicBoolean condition = new AtomicBoolean ( true ) ;
91
+ public void test () throws Exception {
92
+ int totalListenersFailures = 0 ;
96
93
97
- ExecutorService notificationsPool = Executors . newFixedThreadPool ( 4 );
98
- notificationsPool . submit ( new Callable < Void >() {
99
- public Void call () throws Exception {
100
- trigger . await () ;
101
- while ( condition . get () ) {
102
- notifier . fireTestStarted ( null ) ;
94
+ Random random = new Random ( 42 );
95
+ ExaminedListener [] examinedListeners = new ExaminedListener [ 1000 ];
96
+ for ( int i = 0 ; i < examinedListeners . length ; ++ i ) {
97
+ boolean fail = random . nextDouble () >= 0.5d ;
98
+ if ( fail ) {
99
+ ++ totalListenersFailures ;
103
100
}
104
- notifier .fireTestStarted (null );
105
- return null ;
101
+ examinedListeners [i ] = new ExaminedListener (!fail );
106
102
}
107
- });
108
-
109
- trigger .await ();
110
-
111
- for (ExaminedListener examinedListener : examinedListeners ) {
112
- notifier .addListener (examinedListener );
113
- }
114
103
115
- notificationsPool .shutdown ();
116
- condition .set (false );
117
- assertTrue (notificationsPool .awaitTermination (TIMEOUT , TimeUnit .SECONDS ));
104
+ final AtomicBoolean condition = new AtomicBoolean (true );
105
+ final CyclicBarrier trigger = new CyclicBarrier (2 );
106
+ final CountDownLatch latch = new CountDownLatch (10 );
107
+
108
+ ExecutorService notificationsPool = Executors .newFixedThreadPool (4 );
109
+ notificationsPool .submit (new Callable <Void >() {
110
+ public Void call () throws Exception {
111
+ trigger .await ();
112
+ while (condition .get ()) {
113
+ notifier .fireTestStarted (null );
114
+ latch .countDown ();
115
+ }
116
+ notifier .fireTestStarted (null );
117
+ return null ;
118
+ }
119
+ });
118
120
119
- if (totalListenersFailures != 0 ) {
120
- // If no listener failures, then all the listeners do not report any failure.
121
- int countTestFailures = examinedListeners .length - countReportedTestFailures (examinedListeners );
122
- assertThat (totalListenersFailures , is (countTestFailures ));
123
- }
124
- }
121
+ // Wait for callable to start
122
+ trigger .await (TIMEOUT , TimeUnit .SECONDS );
125
123
126
- @ Test
127
- public void reportConcurrentFailuresAfterAddFirstListener () throws Exception {
128
- int totalListenersFailures = 0 ;
124
+ // Wait for callable to fire a few events
125
+ latch .await (TIMEOUT , TimeUnit .SECONDS );
129
126
130
- final ExaminedListener [] examinedListeners = new ExaminedListener [1000 ];
131
- for (int i = 0 ; i < examinedListeners .length ; ++i ) {
132
- boolean fail = StrictMath .random () >= 0.5d ;
133
- if (fail ) {
134
- ++totalListenersFailures ;
127
+ for (ExaminedListener examinedListener : examinedListeners ) {
128
+ addListener (examinedListener );
135
129
}
136
- examinedListeners [i ] = new ExaminedListener (!fail );
137
- }
138
130
139
- final CyclicBarrier trigger = new CyclicBarrier (2 );
140
- final AtomicBoolean condition = new AtomicBoolean (true );
131
+ notificationsPool .shutdown ();
132
+ condition .set (false );
133
+ assertTrue (notificationsPool .awaitTermination (TIMEOUT , TimeUnit .SECONDS ));
141
134
142
- ExecutorService notificationsPool = Executors .newFixedThreadPool (4 );
143
- notificationsPool .submit (new Callable <Void >() {
144
- public Void call () throws Exception {
145
- trigger .await ();
146
- while (condition .get ()) {
147
- notifier .fireTestStarted (null );
148
- }
149
- notifier .fireTestStarted (null );
150
- return null ;
135
+ if (totalListenersFailures != 0 ) {
136
+ // If no listener failures, then all the listeners do not report any failure.
137
+ int countTestFailures = examinedListeners .length - countReportedTestFailures (examinedListeners );
138
+ assertThat (totalListenersFailures , is (countTestFailures ));
151
139
}
152
- });
153
-
154
- trigger .await ();
155
-
156
- for (ExaminedListener examinedListener : examinedListeners ) {
157
- notifier .addFirstListener (examinedListener );
158
140
}
141
+ }
159
142
160
- notificationsPool .shutdown ();
161
- condition .set (false );
162
- assertTrue (notificationsPool .awaitTermination (TIMEOUT , TimeUnit .SECONDS ));
143
+ /**
144
+ * Verifies that listeners added while tests are run concurrently are
145
+ * notified about test failures.
146
+ */
147
+ @ Test
148
+ public void reportConcurrentFailuresAfterAddListener () throws Exception {
149
+ new AbstractConcurrentFailuresTest () {
150
+ @ Override
151
+ protected void addListener (ExaminedListener listener ) {
152
+ notifier .addListener (listener );
153
+ }
154
+ }.test ();
155
+ }
163
156
164
- if (totalListenersFailures != 0 ) {
165
- // If no listener failures, then all the listeners do not report any failure.
166
- int countTestFailures = examinedListeners .length - countReportedTestFailures (examinedListeners );
167
- assertThat (totalListenersFailures , is (countTestFailures ));
168
- }
157
+ /**
158
+ * Verifies that listeners added with addFirstListener() while tests are run concurrently are
159
+ * notified about test failures.
160
+ */
161
+ @ Test
162
+ public void reportConcurrentFailuresAfterAddFirstListener () throws Exception {
163
+ new AbstractConcurrentFailuresTest () {
164
+ @ Override
165
+ protected void addListener (ExaminedListener listener ) {
166
+ notifier .addFirstListener (listener );
167
+ }
168
+ }.test ();
169
169
}
170
170
171
171
private static int countReportedTestFailures (ExaminedListener [] listeners ) {
0 commit comments