Fix ShortPaxosSimulationTest.simulationTest

Patch by Alex Petrov, reviewed by Sam Tunnicliffe for CASSANDRA-19058
This commit is contained in:
Alex Petrov 2023-12-07 19:13:19 +01:00
parent 0989a219ad
commit 9db161f038
11 changed files with 45 additions and 28 deletions

View File

@ -320,7 +320,7 @@ public enum CassandraRelevantProperties
* *
* This is a dev/CI only property. Do not use otherwise. * This is a dev/CI only property. Do not use otherwise.
*/ */
JUNIT_STORAGE_COMPATIBILITY_MODE("cassandra.junit_storage_compatibility_mode", StorageCompatibilityMode.CASSANDRA_4.toString()), JUNIT_STORAGE_COMPATIBILITY_MODE("cassandra.junit_storage_compatibility_mode", StorageCompatibilityMode.NONE.toString()),
/** startup checks properties */ /** startup checks properties */
LIBJEMALLOC("cassandra.libjemalloc"), LIBJEMALLOC("cassandra.libjemalloc"),
/** Line separator ("\n" on UNIX). */ /** Line separator ("\n" on UNIX). */

View File

@ -5023,7 +5023,7 @@ public class DatabaseDescriptor
{ {
// Config is null for junits that don't load the config. Get from env var that CI/build.xml sets // Config is null for junits that don't load the config. Get from env var that CI/build.xml sets
if (conf == null) if (conf == null)
return CassandraRelevantProperties.JUNIT_STORAGE_COMPATIBILITY_MODE.getEnum(StorageCompatibilityMode.CASSANDRA_4); return CassandraRelevantProperties.JUNIT_STORAGE_COMPATIBILITY_MODE.getEnum(StorageCompatibilityMode.NONE);
else else
return conf.storage_compatibility_mode; return conf.storage_compatibility_mode;
} }

View File

@ -224,7 +224,20 @@ public class MessagingService extends MessagingServiceMBeanImpl implements Messa
VERSION_50(13), VERSION_50(13),
VERSION_51(14); VERSION_51(14);
public static final Version CURRENT = DatabaseDescriptor.getStorageCompatibilityMode().isBefore(5) ? VERSION_40 : VERSION_51; public static final Version CURRENT;
static
{
if (DatabaseDescriptor.getStorageCompatibilityMode().isBefore(5))
{
logger.warn("Starting in storage compatibility mode " + DatabaseDescriptor.getStorageCompatibilityMode());
CURRENT = VERSION_40;
}
else
{
CURRENT = VERSION_51;
}
}
public final int value; public final int value;

View File

@ -89,13 +89,14 @@ public class PrepareMessage extends RepairMessage
} }
private static final String MIXED_MODE_ERROR = "Some nodes involved in repair are on an incompatible major version. " + private static final String MIXED_MODE_ERROR = "Some nodes involved in repair are on an incompatible major version. " +
"Repair is not supported in mixed major version clusters."; "Repair is not supported in mixed major version clusters (%d vs %d).";
public static final IVersionedSerializer<PrepareMessage> serializer = new IVersionedSerializer<PrepareMessage>() public static final IVersionedSerializer<PrepareMessage> serializer = new IVersionedSerializer<PrepareMessage>()
{ {
public void serialize(PrepareMessage message, DataOutputPlus out, int version) throws IOException public void serialize(PrepareMessage message, DataOutputPlus out, int version) throws IOException
{ {
Preconditions.checkArgument(version == MessagingService.current_version, MIXED_MODE_ERROR); Preconditions.checkArgument(version == MessagingService.current_version,
String.format(MIXED_MODE_ERROR, version, MessagingService.current_version));
out.writeInt(message.tableIds.size()); out.writeInt(message.tableIds.size());
for (TableId tableId : message.tableIds) for (TableId tableId : message.tableIds)
@ -115,7 +116,8 @@ public class PrepareMessage extends RepairMessage
public PrepareMessage deserialize(DataInputPlus in, int version) throws IOException public PrepareMessage deserialize(DataInputPlus in, int version) throws IOException
{ {
Preconditions.checkArgument(version == MessagingService.current_version, MIXED_MODE_ERROR); Preconditions.checkArgument(version == MessagingService.current_version,
String.format(MIXED_MODE_ERROR, version, MessagingService.current_version));
int tableIdCount = in.readInt(); int tableIdCount = in.readInt();
List<TableId> tableIds = new ArrayList<>(tableIdCount); List<TableId> tableIds = new ArrayList<>(tableIdCount);

View File

@ -16,12 +16,11 @@
* limitations under the License. * limitations under the License.
*/ */
package org.apache.cassandra.simulator.test; package org.apache.cassandra.simulator;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import org.apache.cassandra.simulator.FutureActionScheduler; import org.apache.cassandra.simulator.FutureActionScheduler;
import org.apache.cassandra.simulator.RandomSource;
import org.apache.cassandra.simulator.systems.SimulatedTime; import org.apache.cassandra.simulator.systems.SimulatedTime;
import org.apache.cassandra.simulator.utils.LongRange; import org.apache.cassandra.simulator.utils.LongRange;
@ -35,19 +34,16 @@ import static java.util.concurrent.TimeUnit.NANOSECONDS;
public class AlwaysDeliverNetworkScheduler implements FutureActionScheduler public class AlwaysDeliverNetworkScheduler implements FutureActionScheduler
{ {
private final SimulatedTime time; private final SimulatedTime time;
private final RandomSource randomSource;
private final LongRange schedulerDelay = new LongRange(0, 50, MICROSECONDS, NANOSECONDS);
private final long delayNanos; private final long delayNanos;
AlwaysDeliverNetworkScheduler(SimulatedTime time, RandomSource randomSource) public AlwaysDeliverNetworkScheduler(SimulatedTime time, RandomSource randomSource)
{ {
this(time, randomSource, TimeUnit.MILLISECONDS.toNanos(10)); this(time, randomSource, TimeUnit.MILLISECONDS.toNanos(10));
} }
AlwaysDeliverNetworkScheduler(SimulatedTime time, RandomSource randomSource, long dealayNanos) public AlwaysDeliverNetworkScheduler(SimulatedTime time, RandomSource randomSource, long dealayNanos)
{ {
this.time = time; this.time = time;
this.randomSource = randomSource;
this.delayNanos = dealayNanos; this.delayNanos = dealayNanos;
} }
public Deliver shouldDeliver(int from, int to) public Deliver shouldDeliver(int from, int to)

View File

@ -500,6 +500,7 @@ public class ClusterSimulation<S extends Simulation> implements AutoCloseable
switch (Choices.random(random, kinds).choose(random)) switch (Choices.random(random, kinds).choose(random))
{ {
default: throw new AssertionError(); default: throw new AssertionError();
case IMMEDIATE: return new RunnableActionScheduler.Immediate();
case SEQUENTIAL: return new RunnableActionScheduler.Sequential(); case SEQUENTIAL: return new RunnableActionScheduler.Sequential();
case UNIFORM: return new RunnableActionScheduler.RandomUniform(random); case UNIFORM: return new RunnableActionScheduler.RandomUniform(random);
case RANDOM_WALK: return new RunnableActionScheduler.RandomWalk(random); case RANDOM_WALK: return new RunnableActionScheduler.RandomWalk(random);

View File

@ -16,7 +16,7 @@
* limitations under the License. * limitations under the License.
*/ */
package org.apache.cassandra.simulator.test; package org.apache.cassandra.simulator;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
@ -26,8 +26,6 @@ import java.util.concurrent.TimeUnit;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.apache.cassandra.simulator.FutureActionScheduler;
import org.apache.cassandra.simulator.RandomSource;
import org.apache.cassandra.simulator.systems.SimulatedTime; import org.apache.cassandra.simulator.systems.SimulatedTime;
import org.apache.cassandra.simulator.utils.ChanceRange; import org.apache.cassandra.simulator.utils.ChanceRange;
import org.apache.cassandra.simulator.utils.KindOfSequence; import org.apache.cassandra.simulator.utils.KindOfSequence;
@ -53,7 +51,7 @@ public class FixedLossNetworkScheduler implements FutureActionScheduler
final KindOfSequence.Decision delayChance; final KindOfSequence.Decision delayChance;
final LongRange delayNanos, longDelayNanos; final LongRange delayNanos, longDelayNanos;
FixedLossNetworkScheduler(int nodes, RandomSource random, SimulatedTime time, KindOfSequence kind, float min, float max) public FixedLossNetworkScheduler(int nodes, RandomSource random, SimulatedTime time, KindOfSequence kind, float min, float max)
{ {
this.random = random; this.random = random;
this.time = time; this.time = time;

View File

@ -26,7 +26,7 @@ import org.apache.cassandra.simulator.utils.KindOfSequence;
public abstract class RunnableActionScheduler implements Consumer<Action> public abstract class RunnableActionScheduler implements Consumer<Action>
{ {
public enum Kind { RANDOM_WALK, UNIFORM, SEQUENTIAL } public enum Kind { RANDOM_WALK, UNIFORM, SEQUENTIAL, IMMEDIATE }
public static class Immediate extends RunnableActionScheduler public static class Immediate extends RunnableActionScheduler
{ {

View File

@ -183,7 +183,7 @@ public class KeyspaceActions extends ClusterActions
})); }));
} }
private PlacementSimulator.ReplicatedRanges placements(NodesByDc nodesByDc, NodeLookup lookup, int[] rfs) private PlacementSimulator.ReplicatedRanges placements(NodesByDc nodesByDc, int[] rfs)
{ {
List<PlacementSimulator.Node> nodes = new ArrayList<>(); List<PlacementSimulator.Node> nodes = new ArrayList<>();
for (int dcIdx = 0; dcIdx < nodesByDc.dcs.length; dcIdx++) for (int dcIdx = 0; dcIdx < nodesByDc.dcs.length; dcIdx++)
@ -262,10 +262,10 @@ public class KeyspaceActions extends ClusterActions
case JOIN: case JOIN:
{ {
Topology before = topology; Topology before = topology;
PlacementSimulator.ReplicatedRanges placementsBefore = placements(joined, nodeLookup, currentRf); PlacementSimulator.ReplicatedRanges placementsBefore = placements(joined, currentRf);
int join = registered.removeRandom(random, dc); int join = registered.removeRandom(random, dc);
joined.add(join); joined.add(join);
PlacementSimulator.ReplicatedRanges placementsAfter = placements(joined, nodeLookup, currentRf); PlacementSimulator.ReplicatedRanges placementsAfter = placements(joined, currentRf);
Topology during = recomputeTopology(placementsBefore, placementsAfter); Topology during = recomputeTopology(placementsBefore, placementsAfter);
updateTopology(during); updateTopology(during);
Topology after = recomputeTopology(placementsAfter, placementsAfter); Topology after = recomputeTopology(placementsAfter, placementsAfter);
@ -275,13 +275,13 @@ public class KeyspaceActions extends ClusterActions
case REPLACE: case REPLACE:
{ {
Topology before = topology; Topology before = topology;
PlacementSimulator.ReplicatedRanges placementsBefore = placements(joined, nodeLookup, currentRf); PlacementSimulator.ReplicatedRanges placementsBefore = placements(joined, currentRf);
int join = registered.removeRandom(random, dc); int join = registered.removeRandom(random, dc);
int leave = joined.selectRandom(random, dc); int leave = joined.selectRandom(random, dc);
joined.add(join); joined.add(join);
joined.remove(leave); joined.remove(leave);
left.add(leave); left.add(leave);
PlacementSimulator.ReplicatedRanges placementsAfter = placements(joined, nodeLookup, currentRf); PlacementSimulator.ReplicatedRanges placementsAfter = placements(joined, currentRf);
nodeLookup.setTokenOf(join, nodeLookup.tokenOf(leave)); nodeLookup.setTokenOf(join, nodeLookup.tokenOf(leave));
Topology during = recomputeTopology(placementsBefore, placementsAfter); Topology during = recomputeTopology(placementsBefore, placementsAfter);
updateTopology(during); updateTopology(during);
@ -296,10 +296,10 @@ public class KeyspaceActions extends ClusterActions
case LEAVE: case LEAVE:
{ {
Topology before = topology; Topology before = topology;
PlacementSimulator.ReplicatedRanges placementsBefore = placements(joined, nodeLookup, currentRf); PlacementSimulator.ReplicatedRanges placementsBefore = placements(joined, currentRf);
int leave = joined.removeRandom(random, dc); int leave = joined.removeRandom(random, dc);
left.add(leave); left.add(leave);
PlacementSimulator.ReplicatedRanges placementsAfter = placements(joined, nodeLookup, currentRf); PlacementSimulator.ReplicatedRanges placementsAfter = placements(joined, currentRf);
Topology during = recomputeTopology(placementsBefore, placementsAfter); Topology during = recomputeTopology(placementsBefore, placementsAfter);
updateTopology(during); updateTopology(during);
Topology after = recomputeTopology(placementsAfter, placementsAfter); Topology after = recomputeTopology(placementsAfter, placementsAfter);
@ -375,7 +375,7 @@ public class KeyspaceActions extends ClusterActions
private Topology recomputeTopology() private Topology recomputeTopology()
{ {
PlacementSimulator.ReplicatedRanges ranges = placements(joined, nodeLookup, currentRf); PlacementSimulator.ReplicatedRanges ranges = placements(joined, currentRf);
return recomputeTopology(ranges, ranges); return recomputeTopology(ranges, ranges);
} }

View File

@ -75,6 +75,7 @@ class PaxosClusterSimulation extends ClusterSimulation<PaxosSimulation> implemen
{ {
super(random, seed, uniqueNum, builder, super(random, seed, uniqueNum, builder,
config -> config.set("paxos_variant", builder.initialPaxosVariant.name()) config -> config.set("paxos_variant", builder.initialPaxosVariant.name())
.set("storage_compatibility_mode", "NONE")
.set("paxos_cache_size", (builder.stateCache != null ? builder.stateCache : random.uniformFloat() < 0.5) ? null : "0MiB") .set("paxos_cache_size", (builder.stateCache != null ? builder.stateCache : random.uniformFloat() < 0.5) ? null : "0MiB")
.set("paxos_state_purging", "repaired") .set("paxos_state_purging", "repaired")
.set("paxos_on_linearizability_violations", "log") .set("paxos_on_linearizability_violations", "log")

View File

@ -71,8 +71,10 @@ import org.apache.cassandra.simulator.Action;
import org.apache.cassandra.simulator.ActionList; import org.apache.cassandra.simulator.ActionList;
import org.apache.cassandra.simulator.ActionSchedule; import org.apache.cassandra.simulator.ActionSchedule;
import org.apache.cassandra.simulator.Actions; import org.apache.cassandra.simulator.Actions;
import org.apache.cassandra.simulator.AlwaysDeliverNetworkScheduler;
import org.apache.cassandra.simulator.ClusterSimulation; import org.apache.cassandra.simulator.ClusterSimulation;
import org.apache.cassandra.simulator.Debug; import org.apache.cassandra.simulator.Debug;
import org.apache.cassandra.simulator.FixedLossNetworkScheduler;
import org.apache.cassandra.simulator.FutureActionScheduler; import org.apache.cassandra.simulator.FutureActionScheduler;
import org.apache.cassandra.simulator.OrderOn; import org.apache.cassandra.simulator.OrderOn;
import org.apache.cassandra.simulator.RandomSource; import org.apache.cassandra.simulator.RandomSource;
@ -394,6 +396,11 @@ public class HarrySimulatorTest
this.schedule = schedule; this.schedule = schedule;
} }
public HarrySimulation withScheduler(RunnableActionScheduler scheduler)
{
return new HarrySimulation(simulated, scheduler, cluster, harryRun, (ignore) -> nodeState, schedule);
}
public HarrySimulation withSchedulers(Function<HarrySimulation, Map<Verb, FutureActionScheduler>> schedulers) public HarrySimulation withSchedulers(Function<HarrySimulation, Map<Verb, FutureActionScheduler>> schedulers)
{ {
Map<Verb, FutureActionScheduler> perVerbFutureActionScheduler = schedulers.apply(this); Map<Verb, FutureActionScheduler> perVerbFutureActionScheduler = schedulers.apply(this);
@ -523,7 +530,7 @@ public class HarrySimulatorTest
{ {
HarrySimulation current = simulation; HarrySimulation current = simulation;
if (i == 0) if (i == 0)
current = current.withSchedulers((s) -> Collections.emptyMap()); current = current.withScheduler(new RunnableActionScheduler.Immediate()).withSchedulers((s) -> Collections.emptyMap());
current.withSchedule(phases[i]).run(); current.withSchedule(phases[i]).run();
} }
} }
@ -534,7 +541,6 @@ public class HarrySimulatorTest
} }
} }
} }
;
} }
/** /**