26
26
import java .util .Collection ;
27
27
import java .util .Collections ;
28
28
import java .util .concurrent .CyclicBarrier ;
29
+ import java .util .concurrent .ExecutorService ;
30
+ import java .util .concurrent .Executors ;
29
31
import java .util .concurrent .TimeUnit ;
30
32
import java .util .concurrent .atomic .AtomicInteger ;
31
33
import java .util .concurrent .atomic .AtomicReference ;
32
34
35
+ import static org .hamcrest .CoreMatchers .instanceOf ;
36
+
33
37
public class GroupedActionListenerTests extends ESTestCase {
34
38
35
39
public void testNotifications () throws InterruptedException {
@@ -55,20 +59,17 @@ public void onFailure(Exception e) {
55
59
Thread [] threads = new Thread [numThreads ];
56
60
CyclicBarrier barrier = new CyclicBarrier (numThreads );
57
61
for (int i = 0 ; i < numThreads ; i ++) {
58
- threads [i ] = new Thread () {
59
- @ Override
60
- public void run () {
61
- try {
62
- barrier .await (10 , TimeUnit .SECONDS );
63
- } catch (Exception e ) {
64
- throw new AssertionError (e );
65
- }
66
- int c = 0 ;
67
- while ((c = count .incrementAndGet ()) <= groupSize ) {
68
- listener .onResponse (c -1 );
69
- }
62
+ threads [i ] = new Thread (() -> {
63
+ try {
64
+ barrier .await (10 , TimeUnit .SECONDS );
65
+ } catch (Exception e ) {
66
+ throw new AssertionError (e );
67
+ }
68
+ int c = 0 ;
69
+ while ((c = count .incrementAndGet ()) <= groupSize ) {
70
+ listener .onResponse (c -1 );
70
71
}
71
- };
72
+ }) ;
72
73
threads [i ].start ();
73
74
}
74
75
for (Thread t : threads ) {
@@ -100,11 +101,9 @@ public void onFailure(Exception e) {
100
101
excRef .set (e );
101
102
}
102
103
};
103
- Collection <Integer > defaults = randomBoolean () ? Collections .singletonList (-1 ) :
104
- Collections .emptyList ();
104
+ Collection <Integer > defaults = randomBoolean () ? Collections .singletonList (-1 ) : Collections .emptyList ();
105
105
int size = randomIntBetween (3 , 4 );
106
- GroupedActionListener <Integer > listener = new GroupedActionListener <>(result , size ,
107
- defaults );
106
+ GroupedActionListener <Integer > listener = new GroupedActionListener <>(result , size , defaults );
108
107
listener .onResponse (0 );
109
108
IOException ioException = new IOException ();
110
109
RuntimeException rtException = new RuntimeException ();
@@ -121,4 +120,23 @@ public void onFailure(Exception e) {
121
120
listener .onResponse (1 );
122
121
assertNull (resRef .get ());
123
122
}
123
+
124
+ public void testConcurrentFailures () throws InterruptedException {
125
+ AtomicReference <Exception > finalException = new AtomicReference <>();
126
+ int numGroups = randomIntBetween (10 , 100 );
127
+ GroupedActionListener <Void > listener = new GroupedActionListener <>(
128
+ ActionListener .wrap (r -> {}, finalException ::set ), numGroups , Collections .emptyList ());
129
+ ExecutorService executorService = Executors .newFixedThreadPool (numGroups );
130
+ for (int i = 0 ; i < numGroups ; i ++) {
131
+ executorService .submit (() -> listener .onFailure (new IOException ()));
132
+ }
133
+
134
+ executorService .shutdown ();
135
+ executorService .awaitTermination (10 , TimeUnit .SECONDS );
136
+
137
+ Exception exception = finalException .get ();
138
+ assertNotNull (exception );
139
+ assertThat (exception , instanceOf (IOException .class ));
140
+ assertEquals (numGroups - 1 , exception .getSuppressed ().length );
141
+ }
124
142
}
0 commit comments