16
16
* limitations under the License.
17
17
*/
18
18
19
- package org .apache .hadoop .fs .s3a ;
20
-
21
- import org .apache .hadoop .util .BlockingThreadPoolExecutorService ;
22
- import org .apache .hadoop .util .SemaphoredDelegatingExecutor ;
23
- import org .apache .hadoop .util .StopWatch ;
24
-
25
- import org .junit .AfterClass ;
26
- import org .junit .Rule ;
27
- import org .junit .Test ;
28
- import org .junit .rules .Timeout ;
29
- import org .slf4j .Logger ;
30
- import org .slf4j .LoggerFactory ;
19
+ package org .apache .hadoop .util ;
31
20
32
21
import java .util .concurrent .Callable ;
33
22
import java .util .concurrent .CountDownLatch ;
34
23
import java .util .concurrent .ExecutorService ;
35
24
import java .util .concurrent .Future ;
25
+ import java .util .concurrent .RejectedExecutionException ;
36
26
import java .util .concurrent .TimeUnit ;
37
27
38
- import static org .junit .Assert .assertEquals ;
28
+ import org .assertj .core .api .Assertions ;
29
+ import org .junit .After ;
30
+ import org .junit .Before ;
31
+ import org .junit .Test ;
32
+ import org .slf4j .Logger ;
33
+ import org .slf4j .LoggerFactory ;
34
+
35
+ import org .apache .hadoop .test .AbstractHadoopTestBase ;
36
+
37
+ import static org .apache .hadoop .test .LambdaTestUtils .intercept ;
39
38
40
39
/**
41
- * Basic test for S3A's blocking executor service.
40
+ * Test for the blocking executor service.
42
41
*/
43
- public class ITestBlockingThreadPoolExecutorService {
42
+ public class TestBlockingThreadPoolExecutorService extends AbstractHadoopTestBase {
44
43
45
44
private static final Logger LOG = LoggerFactory .getLogger (
46
- ITestBlockingThreadPoolExecutorService .class );
45
+ TestBlockingThreadPoolExecutorService .class );
47
46
48
47
private static final int NUM_ACTIVE_TASKS = 4 ;
48
+
49
49
private static final int NUM_WAITING_TASKS = 2 ;
50
+
50
51
private static final int TASK_SLEEP_MSEC = 100 ;
52
+
51
53
private static final int SHUTDOWN_WAIT_MSEC = 200 ;
54
+
52
55
private static final int SHUTDOWN_WAIT_TRIES = 5 ;
56
+
53
57
private static final int BLOCKING_THRESHOLD_MSEC = 50 ;
54
58
55
59
private static final Integer SOME_VALUE = 1337 ;
56
60
57
- private static BlockingThreadPoolExecutorService tpe ;
61
+ private BlockingThreadPoolExecutorService tpe ;
58
62
59
- @ Rule
60
- public Timeout testTimeout = new Timeout (60 , TimeUnit .SECONDS );
61
63
62
- @ AfterClass
63
- public static void afterClass () throws Exception {
64
+ @ Before
65
+ public void setup () throws Exception {
66
+ ensureCreated ();
67
+ }
68
+
69
+ @ After
70
+ public void teardown () throws Exception {
64
71
ensureDestroyed ();
65
72
}
66
73
74
+
67
75
/**
68
76
* Basic test of running one trivial task.
69
77
*/
70
78
@ Test
71
79
public void testSubmitCallable () throws Exception {
72
- ensureCreated ();
73
80
Future <Integer > f = tpe .submit (callableSleeper );
74
81
Integer v = f .get ();
75
- assertEquals ( SOME_VALUE , v );
82
+ Assertions . assertThat ( v ). isEqualTo ( SOME_VALUE );
76
83
}
77
84
78
85
/**
79
86
* More involved test, including detecting blocking when at capacity.
80
87
*/
81
88
@ Test
82
89
public void testSubmitRunnable () throws Exception {
83
- ensureCreated ();
84
90
verifyQueueSize (tpe , NUM_ACTIVE_TASKS + NUM_WAITING_TASKS );
85
91
}
86
92
@@ -102,27 +108,30 @@ protected void verifyQueueSize(ExecutorService executorService,
102
108
assertDidBlock (stopWatch );
103
109
}
104
110
105
- @ Test
106
- public void testShutdown () throws Exception {
107
- // Cover create / destroy, regardless of when this test case runs
108
- ensureCreated ();
109
- ensureDestroyed ();
110
-
111
- // Cover create, execute, destroy, regardless of when test case runs
112
- ensureCreated ();
113
- testSubmitRunnable ();
114
- ensureDestroyed ();
115
- }
116
-
117
111
@ Test
118
112
public void testChainedQueue () throws Throwable {
119
- ensureCreated ();
120
113
int size = 2 ;
121
114
ExecutorService wrapper = new SemaphoredDelegatingExecutor (tpe ,
122
115
size , true );
123
116
verifyQueueSize (wrapper , size );
124
117
}
125
118
119
+ @ Test
120
+ public void testShutdownQueueRejectsOperations () throws Throwable {
121
+ tpe .shutdown ();
122
+ Assertions .assertThat (tpe .isShutdown ())
123
+ .describedAs ("%s should be shutdown" , tpe )
124
+ .isTrue ();
125
+ // runnable
126
+ intercept (RejectedExecutionException .class , () ->
127
+ tpe .submit (failToRun ));
128
+ // callable
129
+ intercept (RejectedExecutionException .class , () ->
130
+ tpe .submit (() -> 0 ));
131
+ intercept (RejectedExecutionException .class , () ->
132
+ tpe .execute (failToRun ));
133
+ }
134
+
126
135
// Helper functions, etc.
127
136
128
137
private void assertDidBlock (StopWatch sw ) {
@@ -135,28 +144,27 @@ private void assertDidBlock(StopWatch sw) {
135
144
}
136
145
}
137
146
138
- private Runnable sleeper = new Runnable () {
139
- @ Override
140
- public void run () {
141
- String name = Thread .currentThread ().getName ();
142
- try {
143
- Thread .sleep (TASK_SLEEP_MSEC );
144
- } catch (InterruptedException e ) {
145
- LOG .info ("Thread {} interrupted." , name );
146
- Thread .currentThread ().interrupt ();
147
- }
148
- }
147
+ private Runnable failToRun = () -> {
148
+ throw new RuntimeException ("This runnable raises and exception" );
149
149
};
150
150
151
- private Callable <Integer > callableSleeper = new Callable <Integer >() {
152
- @ Override
153
- public Integer call () throws Exception {
154
- sleeper .run ();
155
- return SOME_VALUE ;
151
+ private Runnable sleeper = () -> {
152
+ String name = Thread .currentThread ().getName ();
153
+ try {
154
+ Thread .sleep (TASK_SLEEP_MSEC );
155
+ } catch (InterruptedException e ) {
156
+ LOG .info ("Thread {} interrupted." , name );
157
+ Thread .currentThread ().interrupt ();
156
158
}
157
159
};
158
160
161
+ private Callable <Integer > callableSleeper = () -> {
162
+ sleeper .run ();
163
+ return SOME_VALUE ;
164
+ };
165
+
159
166
private class LatchedSleeper implements Runnable {
167
+
160
168
private final CountDownLatch latch ;
161
169
162
170
LatchedSleeper (CountDownLatch latch ) {
@@ -178,7 +186,7 @@ public void run() {
178
186
/**
179
187
* Helper function to create thread pool under test.
180
188
*/
181
- private static void ensureCreated () throws Exception {
189
+ private void ensureCreated () throws Exception {
182
190
if (tpe == null ) {
183
191
LOG .debug ("Creating thread pool" );
184
192
tpe = BlockingThreadPoolExecutorService .newInstance (
@@ -191,7 +199,7 @@ private static void ensureCreated() throws Exception {
191
199
* Helper function to terminate thread pool under test, asserting that
192
200
* shutdown -> terminate works as expected.
193
201
*/
194
- private static void ensureDestroyed () throws Exception {
202
+ private void ensureDestroyed () throws Exception {
195
203
if (tpe == null ) {
196
204
return ;
197
205
}
0 commit comments