mirror of https://github.com/apache/cassandra
Fix non-determinism of repair fuzz tests by passing randomizer to RetryStrategy
patch by Nivy Kani; reviewed by David Capwell, Jyothsna Konisa for CASSANDRA-21087
This commit is contained in:
parent
86e024b416
commit
bc9773ea0a
|
|
@ -22,12 +22,16 @@ import java.util.Objects;
|
|||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import accord.utils.RandomSource;
|
||||
|
||||
import org.apache.cassandra.config.DurationSpec.LongMillisecondsBound;
|
||||
import org.apache.cassandra.repair.SharedContext;
|
||||
import org.apache.cassandra.service.RetryStrategy;
|
||||
import org.apache.cassandra.service.TimeoutStrategy.LatencySourceFactory;
|
||||
import org.apache.cassandra.service.WaitStrategy;
|
||||
|
||||
import static org.apache.cassandra.service.RetryStrategy.randomizers;
|
||||
|
||||
public class RetrySpec
|
||||
{
|
||||
public static class MaxAttempt
|
||||
|
|
@ -161,7 +165,9 @@ public class RetrySpec
|
|||
{
|
||||
if (!spec.isEnabled())
|
||||
return WaitStrategy.None.INSTANCE;
|
||||
return RetryStrategy.parse(spec.baseSleepTime.toMilliseconds() + "ms * 2^attempts <= " + spec.maxSleepTime.toMilliseconds() + "ms,retries=" + (spec.maxAttempts.value - 1), LatencySourceFactory.none());
|
||||
RandomSource randomSource = RandomSource.wrap(ctx.random().get());
|
||||
RetryStrategy.WaitRandomizer randomizer = randomizers(randomSource).uniform();
|
||||
return RetryStrategy.parse((int) (0.5 * spec.baseSleepTime.toMilliseconds()) + "ms * 2^attempts ... " + (int) (1.5 * spec.baseSleepTime.toMilliseconds()) + "ms * 2^attempts <= " + spec.maxSleepTime.toMilliseconds() + "ms,retries=" + (spec.maxAttempts.value - 1), LatencySourceFactory.none(), randomizer);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -18,13 +18,21 @@
|
|||
|
||||
package org.apache.cassandra.service;
|
||||
|
||||
import java.util.Random;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.function.IntFunction;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import org.assertj.core.api.Assertions;
|
||||
import org.junit.Test;
|
||||
|
||||
import accord.utils.Gen;
|
||||
import accord.utils.RandomTestRunner;
|
||||
|
||||
import org.apache.cassandra.config.DurationSpec;
|
||||
import org.apache.cassandra.config.RetrySpec;
|
||||
import org.apache.cassandra.repair.SharedContext;
|
||||
|
||||
public class RetryStrategyTest
|
||||
{
|
||||
@Test
|
||||
|
|
@ -64,6 +72,31 @@ public class RetryStrategyTest
|
|||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void seededWaitRandomizer()
|
||||
{
|
||||
RetrySpec spec = new RetrySpec(new RetrySpec.MaxAttempt(10),
|
||||
new DurationSpec.LongMillisecondsBound("200ms"),
|
||||
new DurationSpec.LongMillisecondsBound("1000ms"));
|
||||
long wait1 = RetrySpec.toStrategy(sharedContext(100), spec).computeWait(1, TimeUnit.MILLISECONDS);
|
||||
long wait2 = RetrySpec.toStrategy(sharedContext(100), spec).computeWait(1, TimeUnit.MILLISECONDS);
|
||||
long wait3 = RetrySpec.toStrategy(sharedContext(200), spec).computeWait(1, TimeUnit.MILLISECONDS);
|
||||
Assertions.assertThat(wait1).isEqualTo(wait2);
|
||||
Assertions.assertThat(wait1).isNotEqualTo(wait3);
|
||||
}
|
||||
|
||||
private static SharedContext sharedContext(long seed)
|
||||
{
|
||||
return new SharedContext.ForwardingSharedContext(SharedContext.Global.instance)
|
||||
{
|
||||
@Override
|
||||
public Supplier<Random> random()
|
||||
{
|
||||
return () -> new Random(seed);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private static class TestLatencySourceFactory implements TimeoutStrategy.LatencySourceFactory
|
||||
{
|
||||
|
||||
|
|
@ -73,4 +106,4 @@ public class RetryStrategyTest
|
|||
return percentile -> 10;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue