Search in sources :

Example 1 with Action

use of org.apache.cassandra.simulator.Action in project cassandra by apache.

the class SimulationTestBase method simulate.

public static void simulate(IIsolatedExecutor.SerializableRunnable[] runnables, IIsolatedExecutor.SerializableRunnable check) {
    RandomSource random = new RandomSource.Default();
    SimulatedWaits waits = new SimulatedWaits(random);
    SimulatedTime time = new SimulatedTime(random, 1577836800000L, /*Jan 1st UTC*/
    new LongRange(1, 100, MILLISECONDS, NANOSECONDS), UNIFORM, UNIFORM.period(new LongRange(10L, 60L, SECONDS, NANOSECONDS), random));
    SimulatedExecution execution = new SimulatedExecution();
    InstanceClassLoader classLoader = new InstanceClassLoader(1, 1, AbstractCluster.CURRENT_VERSION.classpath, Thread.currentThread().getContextClassLoader(), AbstractCluster.getSharedClassPredicate(ISOLATE, SHARE, ANY, SIMULATION), new InterceptClasses(() -> 1.0f, () -> 1.0f, NemesisFieldSelectors.get())::apply);
    ThreadGroup tg = new ThreadGroup("test");
    InterceptorOfGlobalMethods interceptorOfGlobalMethods = waits.interceptGlobalMethods(classLoader);
    InterceptingExecutorFactory factory = execution.factory(interceptorOfGlobalMethods, classLoader, tg);
    IsolatedExecutor.transferAdhoc((IIsolatedExecutor.SerializableConsumer<ExecutorFactory>) ExecutorFactory.Global::unsafeSet, classLoader).accept(factory);
    IsolatedExecutor.transferAdhoc((IIsolatedExecutor.SerializableBiConsumer<InterceptorOfGlobalMethods, IntSupplier>) InterceptorOfGlobalMethods.Global::unsafeSet, classLoader).accept(interceptorOfGlobalMethods, () -> {
        if (InterceptibleThread.isDeterministic())
            throw failWithOOM();
        return random.uniform(Integer.MIN_VALUE, Integer.MAX_VALUE);
    });
    SimulatedSystems simulated = new SimulatedSystems(random, time, waits, null, execution, null, null, null, new FutureActionScheduler() {

        @Override
        public Deliver shouldDeliver(int from, int to) {
            return Deliver.DELIVER;
        }

        @Override
        public long messageDeadlineNanos(int from, int to) {
            return 0;
        }

        @Override
        public long messageTimeoutNanos(long expiresAfterNanos) {
            return 0;
        }

        @Override
        public long messageFailureNanos(int from, int to) {
            return 0;
        }

        @Override
        public long schedulerDelayNanos() {
            return 0;
        }
    }, new Debug(), new Failures());
    RunnableActionScheduler runnableScheduler = new RunnableActionScheduler.RandomUniform(random);
    Action entrypoint = new Action("entrypoint", Action.Modifiers.NONE, Action.Modifiers.NONE) {

        protected ActionList performSimple() {
            Action[] actions = new Action[runnables.length];
            for (int i = 0; i < runnables.length; i++) actions[i] = toAction(runnables[i], classLoader, factory, simulated);
            return ActionList.of(actions);
        }
    };
    ActionSchedule testSchedule = new ActionSchedule(simulated.time, simulated.futureScheduler, () -> 0, new Work(UNLIMITED, runnableScheduler, Collections.singletonList(ActionList.of(entrypoint))));
    Iterators.advance(testSchedule, Integer.MAX_VALUE);
    ActionSchedule checkSchedule = new ActionSchedule(simulated.time, simulated.futureScheduler, () -> 0, new Work(UNLIMITED, runnableScheduler, Collections.singletonList(ActionList.of(toAction(check, classLoader, factory, simulated)))));
    Iterators.advance(checkSchedule, Integer.MAX_VALUE);
}
Also used : Action(org.apache.cassandra.simulator.Action) SimulatedTime(org.apache.cassandra.simulator.systems.SimulatedTime) ActionSchedule(org.apache.cassandra.simulator.ActionSchedule) InstanceClassLoader(org.apache.cassandra.distributed.shared.InstanceClassLoader) RunnableActionScheduler(org.apache.cassandra.simulator.RunnableActionScheduler) InterceptClasses(org.apache.cassandra.simulator.asm.InterceptClasses) LongRange(org.apache.cassandra.simulator.utils.LongRange) Work(org.apache.cassandra.simulator.ActionSchedule.Work) InterceptingExecutorFactory(org.apache.cassandra.simulator.systems.InterceptingExecutorFactory) Debug(org.apache.cassandra.simulator.Debug) RandomSource(org.apache.cassandra.simulator.RandomSource) FutureActionScheduler(org.apache.cassandra.simulator.FutureActionScheduler) SimulatedWaits(org.apache.cassandra.simulator.systems.SimulatedWaits) Failures(org.apache.cassandra.simulator.systems.Failures) SimulatedExecution(org.apache.cassandra.simulator.systems.SimulatedExecution) SimulatedSystems(org.apache.cassandra.simulator.systems.SimulatedSystems) InterceptorOfGlobalMethods(org.apache.cassandra.simulator.systems.InterceptorOfGlobalMethods)

Example 2 with Action

use of org.apache.cassandra.simulator.Action in project cassandra by apache.

the class SimulatedAction method applyToMessage.

Action applyToMessage(IInvokableInstance from, IInvokableInstance to, IMessage message) {
    Executor executor = to.executorFor(message.verb());
    if (executor instanceof ImmediateExecutor)
        executor = to.executor();
    InterceptedExecution.InterceptedTaskExecution task = new InterceptedRunnableExecution((InterceptingExecutor) executor, () -> to.receiveMessageWithInvokingThread(message));
    Verb verb = Verb.fromId(message.verb());
    Modifiers self = verbModifiers.getOrDefault(verb, NONE);
    int fromNum = from.config().num();
    int toNum = to.config().num();
    Deliver deliver;
    if (is(Modifier.RELIABLE) || self.is(Modifier.RELIABLE))
        deliver = DELIVER;
    else
        deliver = simulated.futureScheduler.shouldDeliver(fromNum, toNum);
    Action action;
    switch(deliver) {
        default:
            throw new AssertionError();
        case DELIVER:
            {
                Object description = lazy(() -> String.format("%s(%d) from %s to %s", Verb.fromId(message.verb()), message.id(), message.from(), to.broadcastAddress()));
                OrderOn orderOn = task.executor.orderAppliesAfterScheduling();
                action = applyTo(description, MESSAGE, orderOn, self, verb, task);
                action.setDeadline(simulated.futureScheduler.messageDeadlineNanos(fromNum, toNum));
                break;
            }
        case FAILURE:
        case TIMEOUT:
            {
                task.cancel();
                self = DROP.with(self);
                InetSocketAddress failedOn;
                IInvokableInstance notify;
                if (verb.isResponse()) {
                    failedOn = from.broadcastAddress();
                    notify = to;
                } else {
                    failedOn = to.broadcastAddress();
                    notify = from;
                }
                InterceptedExecution.InterceptedTaskExecution failTask = new InterceptedRunnableExecution((InterceptingExecutor) notify.executorFor(verb.id), () -> notify.unsafeApplyOnThisThread((socketAddress, id, isTimeout) -> {
                    InetAddressAndPort address = InetAddressAndPort.getByAddress(socketAddress);
                    RequestCallbacks.CallbackInfo callback = instance().callbacks.remove(id, address);
                    if (callback != null) {
                        RequestCallback<?> invokeOn = (RequestCallback<?>) callback.callback;
                        RequestFailureReason reason = isTimeout ? RequestFailureReason.TIMEOUT : RequestFailureReason.UNKNOWN;
                        invokeOn.onFailure(address, reason);
                    }
                    return null;
                }, failedOn, message.id(), deliver == TIMEOUT));
                Object description = (lazy(() -> String.format("Report Timeout of %s(%d) from %s to %s", Verb.fromId(message.verb()), message.id(), failedOn, notify.broadcastAddress())));
                OrderOn orderOn = failTask.executor.orderAppliesAfterScheduling();
                action = applyTo(description, MESSAGE, orderOn, self, failTask);
                switch(deliver) {
                    default:
                        throw new AssertionError();
                    case TIMEOUT:
                        long expiresAfterNanos = from.unsafeApplyOnThisThread(id -> Verb.fromId(id).expiresAfterNanos(), (verb.isResponse() ? forVerb : verb).id);
                        action.setDeadline(simulated.futureScheduler.messageTimeoutNanos(expiresAfterNanos));
                        break;
                    case FAILURE:
                        action.setDeadline(simulated.futureScheduler.messageFailureNanos(toNum, fromNum));
                        break;
                }
                break;
            }
    }
    return action;
}
Also used : Actions(org.apache.cassandra.simulator.Actions) START_TASK(org.apache.cassandra.simulator.Action.Modifiers.START_TASK) InetAddressAndPort(org.apache.cassandra.locator.InetAddressAndPort) OrderOn(org.apache.cassandra.simulator.OrderOn) DELIVER(org.apache.cassandra.simulator.FutureActionScheduler.Deliver.DELIVER) TASK(org.apache.cassandra.simulator.systems.SimulatedAction.Kind.TASK) LazyToString.lazy(org.apache.cassandra.utils.LazyToString.lazy) START_DAEMON_TASK(org.apache.cassandra.simulator.Action.Modifiers.START_DAEMON_TASK) InterceptedRunnableExecution(org.apache.cassandra.simulator.systems.InterceptedExecution.InterceptedRunnableExecution) ActionList(org.apache.cassandra.simulator.ActionList) RequestCallbacks(org.apache.cassandra.net.RequestCallbacks) Deliver(org.apache.cassandra.simulator.FutureActionScheduler.Deliver) IMessage(org.apache.cassandra.distributed.api.IMessage) ArrayList(java.util.ArrayList) MESSAGE(org.apache.cassandra.simulator.systems.SimulatedAction.Kind.MESSAGE) UNBOUNDED_WAIT(org.apache.cassandra.simulator.systems.InterceptedWait.Kind.UNBOUNDED_WAIT) SIMULATION(org.apache.cassandra.utils.Shared.Scope.SIMULATION) Map(java.util.Map) WAKE_UP_THREAD(org.apache.cassandra.simulator.Action.Modifiers.WAKE_UP_THREAD) TIMEOUT(org.apache.cassandra.simulator.FutureActionScheduler.Deliver.TIMEOUT) MessagingService.instance(org.apache.cassandra.net.MessagingService.instance) START_THREAD(org.apache.cassandra.simulator.Action.Modifiers.START_THREAD) Action(org.apache.cassandra.simulator.Action) Nullable(javax.annotation.Nullable) EnumMap(java.util.EnumMap) Executor(java.util.concurrent.Executor) NONE(org.apache.cassandra.simulator.Action.Modifiers.NONE) DROP(org.apache.cassandra.simulator.Action.Modifiers.DROP) Verb(org.apache.cassandra.net.Verb) RequestFailureReason(org.apache.cassandra.exceptions.RequestFailureReason) RequestCallback(org.apache.cassandra.net.RequestCallback) START_INFINITE_LOOP(org.apache.cassandra.simulator.Action.Modifiers.START_INFINITE_LOOP) InetSocketAddress(java.net.InetSocketAddress) START_SCHEDULED_TASK(org.apache.cassandra.simulator.Action.Modifiers.START_SCHEDULED_TASK) START_TIMEOUT_TASK(org.apache.cassandra.simulator.Action.Modifiers.START_TIMEOUT_TASK) List(java.util.List) IInvokableInstance(org.apache.cassandra.distributed.api.IInvokableInstance) TriggerListener(org.apache.cassandra.simulator.systems.InterceptedWait.TriggerListener) SCHEDULED_TIMEOUT(org.apache.cassandra.simulator.systems.SimulatedAction.Kind.SCHEDULED_TIMEOUT) Shared(org.apache.cassandra.utils.Shared) LOG(org.apache.cassandra.simulator.Debug.Info.LOG) ImmediateExecutor(org.apache.cassandra.concurrent.ImmediateExecutor) Collections(java.util.Collections) LazyToString(org.apache.cassandra.utils.LazyToString) Deliver(org.apache.cassandra.simulator.FutureActionScheduler.Deliver) Action(org.apache.cassandra.simulator.Action) InetAddressAndPort(org.apache.cassandra.locator.InetAddressAndPort) IInvokableInstance(org.apache.cassandra.distributed.api.IInvokableInstance) InterceptedRunnableExecution(org.apache.cassandra.simulator.systems.InterceptedExecution.InterceptedRunnableExecution) InetSocketAddress(java.net.InetSocketAddress) OrderOn(org.apache.cassandra.simulator.OrderOn) Executor(java.util.concurrent.Executor) ImmediateExecutor(org.apache.cassandra.concurrent.ImmediateExecutor) RequestFailureReason(org.apache.cassandra.exceptions.RequestFailureReason) RequestCallback(org.apache.cassandra.net.RequestCallback) ImmediateExecutor(org.apache.cassandra.concurrent.ImmediateExecutor) Verb(org.apache.cassandra.net.Verb) RequestCallbacks(org.apache.cassandra.net.RequestCallbacks)

Example 3 with Action

use of org.apache.cassandra.simulator.Action in project cassandra by apache.

the class PairOfSequencesPaxosSimulation method plan.

public ActionPlan plan() {
    ActionPlan plan = new KeyspaceActions(simulated, KEYSPACE, TABLE, CREATE_TABLE, cluster, clusterOptions, serialConsistency, this, primaryKeys, debug).plan();
    plan = plan.encapsulate(ActionPlan.setUpTearDown(ActionList.of(cluster.stream().map(i -> simulated.run("Insert Partitions", i, executeForPrimaryKeys(INSERT1, primaryKeys)))), ActionList.of(cluster.stream().map(i -> simulated.run("Delete Partitions", i, executeForPrimaryKeys(DELETE1, primaryKeys))))));
    final int nodes = cluster.size();
    for (int primaryKey : primaryKeys) historyCheckers.add(new HistoryChecker(primaryKey));
    List<Supplier<Action>> primaryKeyActions = new ArrayList<>();
    for (int pki = 0; pki < primaryKeys.length; ++pki) {
        int primaryKey = primaryKeys[pki];
        HistoryChecker historyChecker = historyCheckers.get(pki);
        Supplier<Action> supplier = new Supplier<Action>() {

            int i = 0;

            @Override
            public Action get() {
                int node = simulated.random.uniform(1, nodes + 1);
                IInvokableInstance instance = cluster.get(node);
                switch(serialConsistency) {
                    default:
                        throw new AssertionError();
                    case LOCAL_SERIAL:
                        if (simulated.snitch.dcOf(node) > 0) {
                            // perform some queries against these nodes but don't expect them to be linearizable
                            return new NonVerifyingOperation(i++, instance, serialConsistency, primaryKey, historyChecker);
                        }
                    case SERIAL:
                        return simulated.random.decide(readRatio) ? new VerifyingOperation(i++, instance, serialConsistency, primaryKey, historyChecker) : new ModifyingOperation(i++, instance, ANY, serialConsistency, primaryKey, historyChecker);
                }
            }

            @Override
            public String toString() {
                return Integer.toString(primaryKey);
            }
        };
        final ActionListener listener = debug.debug(PARTITION, simulated.time, cluster, KEYSPACE, primaryKey);
        if (listener != null) {
            Supplier<Action> wrap = supplier;
            supplier = new Supplier<Action>() {

                @Override
                public Action get() {
                    Action action = wrap.get();
                    action.register(listener);
                    return action;
                }

                @Override
                public String toString() {
                    return wrap.toString();
                }
            };
        }
        primaryKeyActions.add(supplier);
    }
    List<Integer> available = IntStream.range(0, primaryKeys.length).boxed().collect(Collectors.toList());
    Action stream = Actions.infiniteStream(concurrency, new Supplier<Action>() {

        @Override
        public Action get() {
            int i = simulated.random.uniform(0, available.size());
            int next = available.get(i);
            available.set(i, available.get(available.size() - 1));
            available.remove(available.size() - 1);
            long untilNanos = simulated.time.nanoTime() + SECONDS.toNanos(simulateKeyForSeconds.select(simulated.random));
            int concurrency = withinKeyConcurrency.select(simulated.random);
            Supplier<Action> supplier = primaryKeyActions.get(next);
            // while this stream is finite, it participates in an infinite stream via its parent, so we want to permit termination while it's running
            return Actions.infiniteStream(concurrency, new Supplier<Action>() {

                @Override
                public Action get() {
                    if (simulated.time.nanoTime() >= untilNanos) {
                        available.add(next);
                        return null;
                    }
                    return supplier.get();
                }

                @Override
                public String toString() {
                    return supplier.toString();
                }
            });
        }

        @Override
        public String toString() {
            return "Primary Key Actions";
        }
    });
    return simulated.execution.plan().encapsulate(plan).encapsulate(ActionPlan.interleave(singletonList(ActionList.of(stream))));
}
Also used : Action(org.apache.cassandra.simulator.Action) IInvokableInstance(org.apache.cassandra.distributed.api.IInvokableInstance) ArrayList(java.util.ArrayList) ActionPlan(org.apache.cassandra.simulator.ActionPlan) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) ActionListener(org.apache.cassandra.simulator.ActionListener) KeyspaceActions(org.apache.cassandra.simulator.cluster.KeyspaceActions) LongSupplier(java.util.function.LongSupplier) Supplier(java.util.function.Supplier)

Example 4 with Action

use of org.apache.cassandra.simulator.Action in project cassandra by apache.

the class OnClusterUpdateGossip method safeInvalidate.

@Override
protected Throwable safeInvalidate(boolean isCancellation) {
    ActionList list = cancel;
    if (list == null)
        return null;
    cancel = null;
    return list.safeForEach(Action::invalidate);
}
Also used : ReliableAction(org.apache.cassandra.simulator.Actions.ReliableAction) Action(org.apache.cassandra.simulator.Action) SimulatedAction(org.apache.cassandra.simulator.systems.SimulatedAction) ActionList(org.apache.cassandra.simulator.ActionList)

Aggregations

Action (org.apache.cassandra.simulator.Action)4 ArrayList (java.util.ArrayList)2 IInvokableInstance (org.apache.cassandra.distributed.api.IInvokableInstance)2 ActionList (org.apache.cassandra.simulator.ActionList)2 InetSocketAddress (java.net.InetSocketAddress)1 Collections (java.util.Collections)1 EnumMap (java.util.EnumMap)1 List (java.util.List)1 Map (java.util.Map)1 Executor (java.util.concurrent.Executor)1 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)1 LongSupplier (java.util.function.LongSupplier)1 Supplier (java.util.function.Supplier)1 Nullable (javax.annotation.Nullable)1 ImmediateExecutor (org.apache.cassandra.concurrent.ImmediateExecutor)1 IMessage (org.apache.cassandra.distributed.api.IMessage)1 InstanceClassLoader (org.apache.cassandra.distributed.shared.InstanceClassLoader)1 RequestFailureReason (org.apache.cassandra.exceptions.RequestFailureReason)1 InetAddressAndPort (org.apache.cassandra.locator.InetAddressAndPort)1 MessagingService.instance (org.apache.cassandra.net.MessagingService.instance)1