@@ -275,6 +275,7 @@ public void testProcessFileChanges() throws Exception {
275275 return null ;
276276 }).when (controller ).process (any (), any (XContentParser .class ), any (), any ());
277277
278+ // Await on some latches when files change so we can sync up
278279 CountDownLatch processFileCreationLatch = new CountDownLatch (1 );
279280 doAnswer (i -> {
280281 try {
@@ -283,25 +284,28 @@ public void testProcessFileChanges() throws Exception {
283284 processFileCreationLatch .countDown ();
284285 }
285286 }).when (fileSettingsService ).processFile (eq (watchedFile ), eq (true ));
287+ CountDownLatch processFileChangeLatch = new CountDownLatch (1 );
288+ doAnswer (i -> {
289+ try {
290+ return i .callRealMethod ();
291+ } finally {
292+ processFileChangeLatch .countDown ();
293+ }
294+ }).when (fileSettingsService ).processFile (eq (watchedFile ), eq (false ));
286295
287296 Files .createDirectories (fileSettingsService .watchedFileDir ());
288297 // contents of the JSON don't matter, we just need a file to exist
289298 writeTestFile (watchedFile , "{}" );
290299
300+ // It's important to configure all the mocks before calling start() here,
301+ // because otherwise there can be races between configuration and use of mocks
302+ // which leads to a UnfinishedStubbingException.
303+
291304 fileSettingsService .start ();
292305 fileSettingsService .clusterChanged (new ClusterChangedEvent ("test" , clusterService .state (), ClusterState .EMPTY_STATE ));
293306
294307 longAwait (processFileCreationLatch );
295308
296- CountDownLatch processFileChangeLatch = new CountDownLatch (1 );
297- doAnswer (i -> {
298- try {
299- return i .callRealMethod ();
300- } finally {
301- processFileChangeLatch .countDown ();
302- }
303- }).when (fileSettingsService ).processFile (eq (watchedFile ), eq (false ));
304-
305309 verify (fileSettingsService , times (1 )).processFile (eq (watchedFile ), eq (true ));
306310 verify (controller , times (1 )).process (any (), any (XContentParser .class ), eq (ReservedStateVersionCheck .HIGHER_OR_SAME_VERSION ), any ());
307311
@@ -328,10 +332,8 @@ public void testInvalidJSON() throws Exception {
328332 // Don't really care about the initial state
329333 Files .createDirectories (fileSettingsService .watchedFileDir ());
330334 doNothing ().when (fileSettingsService ).processInitialFilesMissing ();
331- fileSettingsService .start ();
332- fileSettingsService .clusterChanged (new ClusterChangedEvent ("test" , clusterService .state (), ClusterState .EMPTY_STATE ));
333335
334- // Now break the JSON and wait
336+ // Prepare to await on a barrier when the file changes so we can sync up
335337 CyclicBarrier fileChangeBarrier = new CyclicBarrier (2 );
336338 doAnswer ((Answer <?>) invocation -> {
337339 try {
@@ -340,6 +342,12 @@ public void testInvalidJSON() throws Exception {
340342 awaitOrBust (fileChangeBarrier );
341343 }
342344 }).when (fileSettingsService ).onProcessFileChangesException (eq (watchedFile ), any ());
345+
346+ // Kick off the service
347+ fileSettingsService .start ();
348+ fileSettingsService .clusterChanged (new ClusterChangedEvent ("test" , clusterService .state (), ClusterState .EMPTY_STATE ));
349+
350+ // Now break the JSON and wait
343351 writeTestFile (watchedFile , "test_invalid_JSON" );
344352 awaitOrBust (fileChangeBarrier );
345353
0 commit comments