// thread in the middle of resizing (when constructing the new partition state).
// This depends on DegraderLoadBalancerState to call the clock at least once to initialize
// partition 1. If that changes, you'll have to change clock-related constants below.
final PauseClock clock = new PauseClock();
final DegraderLoadBalancerState subject
= new DegraderLoadBalancerStrategyV3
(new DegraderLoadBalancerStrategyConfig(5000, 1, null, Collections.<String, Object>emptyMap(),
clock, 1, 1, 1, 1, 1, 1, 1, 1),
SERVICE_NAME, null).getState();
Thread getPartition1 = new Thread()
{
@Override
public void run()
{
subject.getPartitionState(1); // resize the array as a side-effect
}
};
assertNotNull(subject.getPartitionState(0));
final long clockCalled = clock._calls.get();
assertTrue(clockCalled > 0, "clock not called"); // 1 partition initialized (so far)
clock._paused = new CountDownLatch(1);
clock._resume = new CountDownLatch(1);
getPartition1.start();
assertTrue(clock._paused.await(60, TimeUnit.SECONDS));
// Now getPartition1 has started resizing the array.
final PartitionDegraderLoadBalancerState newState = newPartitionState(0, 0);
assertNotSame(subject.getPartitionState(0), newState);
subject.setPartitionState(0, newState);
assertSame(subject.getPartitionState(0), newState);
clock._resume.countDown();
getPartition1.join(60000);
assertFalse(getPartition1.isAlive());
// Now getPartition1 has finished resizing the array.
assertSame(subject.getPartitionState(0), newState); // as before
assertTrue(clock._calls.get() > clockCalled, "clock not called again"); // 2 partitions initialized
}