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.
*/
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 */
LIBJEMALLOC("cassandra.libjemalloc"),
/** 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
if (conf == null)
return CassandraRelevantProperties.JUNIT_STORAGE_COMPATIBILITY_MODE.getEnum(StorageCompatibilityMode.CASSANDRA_4);
return CassandraRelevantProperties.JUNIT_STORAGE_COMPATIBILITY_MODE.getEnum(StorageCompatibilityMode.NONE);
else
return conf.storage_compatibility_mode;
}

View File

@ -224,7 +224,20 @@ public class MessagingService extends MessagingServiceMBeanImpl implements Messa
VERSION_50(13),
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;

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. " +
"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 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());
for (TableId tableId : message.tableIds)
@ -115,7 +116,8 @@ public class PrepareMessage extends RepairMessage
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();
List<TableId> tableIds = new ArrayList<>(tableIdCount);

View File

@ -16,12 +16,11 @@
* limitations under the License.
*/
package org.apache.cassandra.simulator.test;
package org.apache.cassandra.simulator;
import java.util.concurrent.TimeUnit;
import org.apache.cassandra.simulator.FutureActionScheduler;
import org.apache.cassandra.simulator.RandomSource;
import org.apache.cassandra.simulator.systems.SimulatedTime;
import org.apache.cassandra.simulator.utils.LongRange;
@ -35,19 +34,16 @@ import static java.util.concurrent.TimeUnit.NANOSECONDS;
public class AlwaysDeliverNetworkScheduler implements FutureActionScheduler
{
private final SimulatedTime time;
private final RandomSource randomSource;
private final LongRange schedulerDelay = new LongRange(0, 50, MICROSECONDS, NANOSECONDS);
private final long delayNanos;
AlwaysDeliverNetworkScheduler(SimulatedTime time, RandomSource randomSource)
public AlwaysDeliverNetworkScheduler(SimulatedTime time, RandomSource randomSource)
{
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.randomSource = randomSource;
this.delayNanos = dealayNanos;
}
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))
{
default: throw new AssertionError();
case IMMEDIATE: return new RunnableActionScheduler.Immediate();
case SEQUENTIAL: return new RunnableActionScheduler.Sequential();
case UNIFORM: return new RunnableActionScheduler.RandomUniform(random);
case RANDOM_WALK: return new RunnableActionScheduler.RandomWalk(random);

View File

@ -16,7 +16,7 @@
* limitations under the License.
*/
package org.apache.cassandra.simulator.test;
package org.apache.cassandra.simulator;
import java.util.HashMap;
import java.util.Map;
@ -26,8 +26,6 @@ import java.util.concurrent.TimeUnit;
import org.slf4j.Logger;
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.utils.ChanceRange;
import org.apache.cassandra.simulator.utils.KindOfSequence;
@ -53,7 +51,7 @@ public class FixedLossNetworkScheduler implements FutureActionScheduler
final KindOfSequence.Decision delayChance;
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.time = time;

View File

@ -26,7 +26,7 @@ import org.apache.cassandra.simulator.utils.KindOfSequence;
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
{

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

View File

@ -75,6 +75,7 @@ class PaxosClusterSimulation extends ClusterSimulation<PaxosSimulation> implemen
{
super(random, seed, uniqueNum, builder,
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_state_purging", "repaired")
.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.ActionSchedule;
import org.apache.cassandra.simulator.Actions;
import org.apache.cassandra.simulator.AlwaysDeliverNetworkScheduler;
import org.apache.cassandra.simulator.ClusterSimulation;
import org.apache.cassandra.simulator.Debug;
import org.apache.cassandra.simulator.FixedLossNetworkScheduler;
import org.apache.cassandra.simulator.FutureActionScheduler;
import org.apache.cassandra.simulator.OrderOn;
import org.apache.cassandra.simulator.RandomSource;
@ -394,6 +396,11 @@ public class HarrySimulatorTest
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)
{
Map<Verb, FutureActionScheduler> perVerbFutureActionScheduler = schedulers.apply(this);
@ -523,7 +530,7 @@ public class HarrySimulatorTest
{
HarrySimulation current = simulation;
if (i == 0)
current = current.withSchedulers((s) -> Collections.emptyMap());
current = current.withScheduler(new RunnableActionScheduler.Immediate()).withSchedulers((s) -> Collections.emptyMap());
current.withSchedule(phases[i]).run();
}
}
@ -534,7 +541,6 @@ public class HarrySimulatorTest
}
}
}
;
}
/**