31
31
import org .elasticsearch .test .MockLogAppender ;
32
32
import org .elasticsearch .test .MockLogAppender .LoggingExpectation ;
33
33
import org .elasticsearch .threadpool .ThreadPool ;
34
+ import org .elasticsearch .transport .ActionNotFoundTransportException ;
34
35
import org .elasticsearch .xpack .core .transform .action .GetCheckpointAction ;
35
36
import org .elasticsearch .xpack .core .transform .transforms .SourceConfig ;
36
37
import org .elasticsearch .xpack .core .transform .transforms .TransformCheckpoint ;
67
68
68
69
public class DefaultCheckpointProviderTests extends ESTestCase {
69
70
70
- private static Logger checkpointProviderLogger = LogManager .getLogger (DefaultCheckpointProvider .class );
71
+ private static final Logger checkpointProviderLogger = LogManager .getLogger (DefaultCheckpointProvider .class );
71
72
72
73
private Clock clock ;
73
74
private Client client ;
@@ -96,7 +97,7 @@ public void setUpMocks() {
96
97
transformAuditor = MockTransformAuditor .createMockAuditor ();
97
98
}
98
99
99
- public void testReportSourceIndexChangesRunsEmpty () throws Exception {
100
+ public void testReportSourceIndexChangesRunsEmpty () {
100
101
String transformId = getTestName ();
101
102
TransformConfig transformConfig = TransformConfigTests .randomTransformConfig (transformId );
102
103
DefaultCheckpointProvider provider = newCheckpointProvider (transformConfig );
@@ -138,7 +139,7 @@ public void testReportSourceIndexChangesRunsEmpty() throws Exception {
138
139
);
139
140
}
140
141
141
- public void testReportSourceIndexChangesAddDelete () throws Exception {
142
+ public void testReportSourceIndexChangesAddDelete () {
142
143
String transformId = getTestName ();
143
144
TransformConfig transformConfig = TransformConfigTests .randomTransformConfig (transformId );
144
145
DefaultCheckpointProvider provider = newCheckpointProvider (transformConfig );
@@ -197,7 +198,7 @@ public void testReportSourceIndexChangesAddDelete() throws Exception {
197
198
);
198
199
}
199
200
200
- public void testReportSourceIndexChangesAddDeleteMany () throws Exception {
201
+ public void testReportSourceIndexChangesAddDeleteMany () {
201
202
String transformId = getTestName ();
202
203
TransformConfig transformConfig = TransformConfigTests .randomTransformConfig (transformId );
203
204
DefaultCheckpointProvider provider = newCheckpointProvider (transformConfig );
@@ -231,29 +232,88 @@ public void testReportSourceIndexChangesAddDeleteMany() throws Exception {
231
232
}
232
233
233
234
public void testHandlingShardFailures () throws Exception {
234
- String transformId = getTestName ();
235
- String indexName = "some-index" ;
235
+ var transformId = getTestName ();
236
+ var indexName = "some-index" ;
236
237
TransformConfig transformConfig = new TransformConfig .Builder (TransformConfigTests .randomTransformConfig (transformId )).setSource (
237
238
new SourceConfig (indexName )
238
239
).build ();
239
240
240
- RemoteClusterResolver remoteClusterResolver = mock (RemoteClusterResolver .class );
241
+ var remoteClusterResolver = mock (RemoteClusterResolver .class );
241
242
doReturn (new RemoteClusterResolver .ResolvedIndices (Collections .emptyMap (), Collections .singletonList (indexName ))).when (
242
243
remoteClusterResolver
243
244
).resolve (transformConfig .getSource ().getIndex ());
244
245
246
+ mockGetIndexResponse (indexName );
247
+ mockIndicesStatsResponse (indexName );
248
+ mockGetCheckpointAction ();
249
+
250
+ var provider = new DefaultCheckpointProvider (
251
+ clock ,
252
+ parentTaskClient ,
253
+ remoteClusterResolver ,
254
+ transformConfigManager ,
255
+ transformAuditor ,
256
+ transformConfig
257
+ );
258
+
259
+ var latch = new CountDownLatch (1 );
260
+ provider .createNextCheckpoint (
261
+ null ,
262
+ new LatchedActionListener <>(
263
+ ActionListener .wrap (
264
+ response -> fail ("This test case must fail" ),
265
+ e -> assertThat (
266
+ e .getMessage (),
267
+ startsWith (
268
+ "Source has [7] failed shards, first shard failure: [some-index][3] failed, "
269
+ + "reason [java.lang.Exception: something's wrong"
270
+ )
271
+ )
272
+ ),
273
+ latch
274
+ )
275
+ );
276
+ assertTrue (latch .await (1 , TimeUnit .MILLISECONDS ));
277
+ }
278
+
279
+ private void mockGetIndexResponse (String indexName ) {
245
280
GetIndexResponse getIndexResponse = new GetIndexResponse (new String [] { indexName }, null , null , null , null , null );
246
281
doAnswer (withResponse (getIndexResponse )).when (client ).execute (eq (GetIndexAction .INSTANCE ), any (), any ());
282
+ }
247
283
284
+ private void mockIndicesStatsResponse (String indexName ) {
248
285
IndicesStatsResponse indicesStatsResponse = mock (IndicesStatsResponse .class );
249
286
doReturn (7 ).when (indicesStatsResponse ).getFailedShards ();
250
287
doReturn (
251
288
new DefaultShardOperationFailedException [] {
252
289
new DefaultShardOperationFailedException (indexName , 3 , new Exception ("something's wrong" )) }
253
290
).when (indicesStatsResponse ).getShardFailures ();
254
291
doAnswer (withResponse (indicesStatsResponse )).when (client ).execute (eq (IndicesStatsAction .INSTANCE ), any (), any ());
292
+ }
255
293
256
- DefaultCheckpointProvider provider = new DefaultCheckpointProvider (
294
+ private void mockGetCheckpointAction () {
295
+ doAnswer (invocationOnMock -> {
296
+ ActionListener <?> listener = invocationOnMock .getArgument (2 );
297
+ listener .onFailure (new ActionNotFoundTransportException ("This should fail." ));
298
+ return null ;
299
+ }).when (client ).execute (eq (GetCheckpointAction .INSTANCE ), any (), any ());
300
+ }
301
+
302
+ public void testHandlingNoClusters () throws Exception {
303
+ var transformId = getTestName ();
304
+ var indexName = "some-missing-index" ;
305
+ var transformConfig = new TransformConfig .Builder (TransformConfigTests .randomTransformConfig (transformId )).setSource (
306
+ new SourceConfig (indexName )
307
+ ).build ();
308
+
309
+ var remoteClusterResolver = mock (RemoteClusterResolver .class );
310
+ doReturn (new RemoteClusterResolver .ResolvedIndices (Map .of (), List .of ())).when (remoteClusterResolver )
311
+ .resolve (transformConfig .getSource ().getIndex ());
312
+
313
+ mockGetIndexResponse (indexName );
314
+ mockIndicesStatsResponse (indexName );
315
+
316
+ var provider = new DefaultCheckpointProvider (
257
317
clock ,
258
318
parentTaskClient ,
259
319
remoteClusterResolver ,
@@ -262,24 +322,18 @@ public void testHandlingShardFailures() throws Exception {
262
322
transformConfig
263
323
);
264
324
265
- CountDownLatch latch = new CountDownLatch (1 );
325
+ var latch = new CountDownLatch (1 );
266
326
provider .createNextCheckpoint (
267
327
null ,
268
328
new LatchedActionListener <>(
269
329
ActionListener .wrap (
270
330
response -> fail ("This test case must fail" ),
271
- e -> assertThat (
272
- e .getMessage (),
273
- startsWith (
274
- "Source has [7] failed shards, first shard failure: [some-index][3] failed, "
275
- + "reason [java.lang.Exception: something's wrong"
276
- )
277
- )
331
+ e -> assertThat (e .getMessage (), equalTo ("No clusters exist for [some-missing-index]" ))
278
332
),
279
333
latch
280
334
)
281
335
);
282
- latch .await (10 , TimeUnit .SECONDS );
336
+ assertTrue ( latch .await (1 , TimeUnit .MILLISECONDS ) );
283
337
}
284
338
285
339
public void testSourceHasChanged () throws InterruptedException {
@@ -407,8 +461,7 @@ private DefaultCheckpointProvider newCheckpointProvider(TransformConfig transfor
407
461
);
408
462
}
409
463
410
- private void assertExpectation (LoggingExpectation loggingExpectation , AuditExpectation auditExpectation , Runnable codeBlock )
411
- throws IllegalAccessException {
464
+ private void assertExpectation (LoggingExpectation loggingExpectation , AuditExpectation auditExpectation , Runnable codeBlock ) {
412
465
MockLogAppender mockLogAppender = new MockLogAppender ();
413
466
mockLogAppender .start ();
414
467
@@ -429,10 +482,9 @@ private void assertExpectation(LoggingExpectation loggingExpectation, AuditExpec
429
482
}
430
483
}
431
484
432
- @ SuppressWarnings ("unchecked" )
433
485
private static <Response > Answer <Response > withResponse (Response response ) {
434
486
return invocationOnMock -> {
435
- ActionListener <Response > listener = ( ActionListener < Response >) invocationOnMock .getArguments ()[ 2 ] ;
487
+ ActionListener <Response > listener = invocationOnMock .getArgument ( 2 ) ;
436
488
listener .onResponse (response );
437
489
return null ;
438
490
};
0 commit comments