Source:
<code>void testSplitAndMergeInfluenceOnChangeListenerInvocations() throws InterruptedException { int firstSegment = 0; int secondSegment = 1; CountDownLatch addedStatusLatch = new CountDownLatch(4); <START> CountDownLatch removedStatusLatch = new CountDownLatch(3); <END> EventTrackerStatusChangeListener statusChangeListener = updatedTrackerStatus -> { EventTrackerStatus eventTrackerStatus = updatedTrackerStatus.values().iterator().next(); if (eventTrackerStatus.trackerAdded()) { addedStatusLatch.countDown(); } else if (eventTrackerStatus.trackerRemoved()) { removedStatusLatch.countDown(); } }; TrackingEventProcessorConfiguration tepConfiguration = TrackingEventProcessorConfiguration.forParallelProcessing(2) .andEventTrackerStatusChangeListener(statusChangeListener); initProcessor(tepConfiguration); tokenStore.initializeTokenSegments(testSubject.getName(), 1); publishEvents(2); testSubject.start(); waitForSegmentStart(firstSegment); assertTrue(testSubject.splitSegment(firstSegment).join(), "Expected split to succeed"); assertArrayEquals(new int[]{firstSegment, secondSegment}, tokenStore.fetchSegments(testSubject.getName())); waitForSegmentStart(secondSegment); assertWithin( 50, TimeUnit.MILLISECONDS, () -> assertTrue(testSubject.mergeSegment(firstSegment).join(), "Expected merge to succeed") ); assertArrayEquals(new int[]{firstSegment}, tokenStore.fetchSegments(testSubject.getName())); waitForSegmentStart(firstSegment); assertTrue(addedStatusLatch.await(5, TimeUnit.SECONDS)); assertTrue(removedStatusLatch.await(5, TimeUnit.SECONDS)); }</code><technical_language>more update invocation validation? :-(</technical_language>

Target:
void testSplitAndMergeInfluenceOnChangeListenerInvocations() throws InterruptedException { int firstSegment = 0; int secondSegment = 1; CountDownLatch addedStatusLatch = new CountDownLatch(4); CountDownLatch updatedStatusLatch = new CountDownLatch(1); CountDownLatch removedStatusLatch = new CountDownLatch(3); EventTrackerStatusChangeListener statusChangeListener = updatedTrackerStatus -> { assertEquals(1, updatedTrackerStatus.size()); EventTrackerStatus eventTrackerStatus = updatedTrackerStatus.values().iterator().next(); if (eventTrackerStatus.trackerAdded()) { addedStatusLatch.countDown(); } else if (eventTrackerStatus.trackerRemoved()) { removedStatusLatch.countDown(); } else { updatedStatusLatch.countDown(); } }; TrackingEventProcessorConfiguration tepConfiguration = TrackingEventProcessorConfiguration.forParallelProcessing(2) .andEventTrackerStatusChangeListener(statusChangeListener); initProcessor(tepConfiguration); tokenStore.initializeTokenSegments(testSubject.getName(), 1); publishEvents(2); testSubject.start(); waitForSegmentStart(firstSegment); assertTrue(testSubject.splitSegment(firstSegment).join(), "Expected split to succeed"); assertArrayEquals(new int[]{firstSegment, secondSegment}, tokenStore.fetchSegments(testSubject.getName())); waitForSegmentStart(secondSegment); assertWithin( 50, TimeUnit.MILLISECONDS, () -> assertTrue(testSubject.mergeSegment(firstSegment).join(), "Expected merge to succeed") ); assertArrayEquals(new int[]{firstSegment}, tokenStore.fetchSegments(testSubject.getName())); waitForSegmentStart(firstSegment); assertTrue(addedStatusLatch.await(5, TimeUnit.SECONDS)); assertTrue(updatedStatusLatch.await(5, TimeUnit.SECONDS)); assertTrue(removedStatusLatch.await(5, TimeUnit.SECONDS)); }