@Test
public void testUpdate() {

    SyncStatusTracker tracker = new SyncStatusTracker(listener, "commit-tracker", 10);
    // When leader-1 sends the first update message the listener should receive a syncStatus notification
    // with status set to false
    tracker.update("leader-1", 100, 99);
    FollowerInitialSyncUpStatus status =
            MessageCollectorActor.getFirstMatching(listener, FollowerInitialSyncUpStatus.class);
    assertEquals(false, status.isInitialSyncDone());
    MessageCollectorActor.clearMessages(listener);
    // At a minimum the follower should have the commit index that the new leader sent it in the first message
    // Also the commit index must be below the syncThreshold. If both conditions are met a new sync status
    // message with status = true should be expected
    tracker.update("leader-1", 105, 101);
    status = MessageCollectorActor.getFirstMatching(listener, FollowerInitialSyncUpStatus.class);
    assertEquals(true, status.isInitialSyncDone());
    MessageCollectorActor.clearMessages(listener);
    // If a subsequent message is received and if the difference between the followers commit index and
    // the leaders commit index is below the syncThreshold then no status notification must be issues
    tracker.update("leader-1", 108, 101);
    status = MessageCollectorActor.getFirstMatching(listener, FollowerInitialSyncUpStatus.class);
    assertNull("No status message should be received", status);
    // If the follower falls behind the leader by more than the syncThreshold then the listener should
    // receive a syncStatus notification with status = false
    tracker.update("leader-1", 150, 101);
    status = MessageCollectorActor.getFirstMatching(listener, FollowerInitialSyncUpStatus.class);
    assertNotNull("No sync status message was received", status);
    assertEquals(false, status.isInitialSyncDone());
    MessageCollectorActor.clearMessages(listener);
    // If the follower is not caught up yet it should not receive any further notification
    tracker.update("leader-1", 150, 125);
    status = MessageCollectorActor.getFirstMatching(listener, FollowerInitialSyncUpStatus.class);
    assertNull("No status message should be received", status);
    // Once the syncThreshold is met a new syncStatus notification should be issued
    tracker.update("leader-1", 160, 155);
    status = MessageCollectorActor.getFirstMatching(listener, FollowerInitialSyncUpStatus.class);
    assertEquals(true, status.isInitialSyncDone());
    MessageCollectorActor.clearMessages(listener);
    // When a new leader starts sending update messages a new syncStatus notification should be immediately
    // triggered with status = false
    tracker.update("leader-2", 160, 155);
    status = MessageCollectorActor.getFirstMatching(listener, FollowerInitialSyncUpStatus.class);
    assertEquals(false, status.isInitialSyncDone());
    MessageCollectorActor.clearMessages(listener);
    // If an update is received from a new leader which is still below the minimum expected index then
    // syncStatus should not be changed
    tracker.update("leader-2", 160, 159);
    status = MessageCollectorActor.getFirstMatching(listener, FollowerInitialSyncUpStatus.class);
    assertNull("No status message should be received", status);
}