static void StartTimers(string sctx, SynchronizedLogger logger)
        {
            var ctx             = sctx.FromJson <DistributedStorageContext>();
            var lastStorageNode = ctx.StorageNodes.Last();

            foreach (var storageNode in ctx.StorageNodes)
            {
                if (storageNode == lastStorageNode)
                {
                    var setIfHandledTimeout = logger.MachineActionHandledSet((_1, _2, actionName) => actionName == "HandleTimeout");
                    var setIfEnteredExit    = logger.MachineActionHandledSet((_1, _2, actionName) => actionName == "EnterExit");
                    logger.ApplySynchronization(setIfHandledTimeout.And(setIfEnteredExit));
                }
                else
                {
                    var setIfHandledTimeout = logger.MachineActionHandledSet((_1, _2, actionName) => actionName == "HandleTimeout");
                    logger.ApplySynchronization(setIfHandledTimeout);
                }

                storageNode.Timeout(new Timeout());

                logger.WaitForWriting(3000);
            }
        }
        public void Context_should_not_return_same_Machine_if_it_is_in_remote_and_multi_application()
        {
            // Arrange
            var expected        = default(int);
            var actual          = default(int);
            var expected_Assign = new MarshalByRefAction <int>(i => expected = i);
            var actual_Assign   = new MarshalByRefAction <int>(i => actual = i);

            // Act
            AppDomain.CurrentDomain.RunAtIsolatedDomain((expected_Assign_, actual_Assign_) =>
            {
                var configuration         = Configuration.Create().WithVerbosityEnabled(2);
                var runtime               = PSharpRuntime.Create(configuration);
                var runtimeHost           = HostInfo.NewRuntimeHost(runtime);
                var logger                = new SynchronizedLogger(new InMemoryLogger());
                var setIfHandledHandshake = logger.MachineActionHandledSet((_1, _2, actionName) => actionName == "HandleHandshake");
                logger.ApplySynchronization(setIfHandledHandshake);
                runtimeHost.SetLogger(logger);
                using (var networkProvider = new DomainCommunicationProvider(runtimeHost, "servers"))
                {
                    var parameter = default(string);
                    {
                        runtimeHost.SetNetworkProvider(networkProvider);

                        var ctx    = runtimeHost.New <DistributedStorageContext>();
                        ctx.Server = runtimeHost.New(MachineInterface.Sender <IServerSender>().Bundler <IServerBundler>().Receiver <ServerReceiverWithoutBug>());
                        ctx.Server.Configure(new ConfigureServer(new MessageCollection(), null, null));
                        expected_Assign_.Invoke(RuntimeHelpers.GetHashCode(ctx.Server));
                        parameter = ctx.ToJson();
                    }

                    AppDomain.CurrentDomain.RunAtIsolatedDomain((actual_Assign__, parameter_) =>
                    {
                        var ctx = parameter_.FromJson <DistributedStorageContext>();
                        actual_Assign__.Invoke(RuntimeHelpers.GetHashCode(ctx.Server));
                        ctx.Server.Handshake(new HandshakeServer(null, new IStorageNodeSender[0]));
                    }, actual_Assign_, parameter);

                    logger.WaitForWriting(1000);
                }
            }, expected_Assign, actual_Assign);


            // Assert
            Assert.AreNotEqual(expected, actual);
        }
        public void Machine_should_transit_its_state_according_to_passed_event()
        {
            // Arrange
            var configuration    = Configuration.Create().WithMonitorsInProductionEnabled().WithVerbosityEnabled(2);
            var runtime          = PSharpRuntime.Create(configuration);
            var runtimeHost      = HostInfo.NewRuntimeHost(runtime);
            var logger           = new SynchronizedLogger(new InMemoryLogger());
            var setIfHandledSync = logger.MachineActionHandledSet((_1, _2, actionName) => actionName == "HandleSync");

            logger.ApplySynchronization(setIfHandledSync);
            runtimeHost.SetLogger(logger);
            var server = runtimeHost.New(MachineInterface.Sender <IServerSender>().Bundler <IServerBundler>().Receiver <ServerReceiverWithoutBug>());


            // Act
            var messages            = new MessageCollection();
            var safetyMonitorMock   = new Mock <ISafetyMonitorSender>();
            var livenessMonitorMock = new Mock <ILivenessMonitorSender>();

            server.Configure(new ConfigureServer(messages, safetyMonitorMock.Object, livenessMonitorMock.Object));

            var clientMock = new Mock <IClientSender>();
            var clientId   = runtime.CreateMachine(typeof(Client));

            clientMock.SetupGet(_ => _.Id).Returns(clientId);
            var storageNodeMock = new Mock <IStorageNodeSender>();
            var storageNodeId   = runtime.CreateMachine(typeof(StorageNode));

            storageNodeMock.Setup(_ => _.Id).Returns(storageNodeId);
            server.Handshake(new HandshakeServer(clientMock.Object, new[] { storageNodeMock.Object }));

            var clientReq = new ClientReq(42);

            server.ClientReq(clientReq);

            server.Sync(new Sync(storageNodeMock.Object, 0));


            // Assert
            Assert.That(logger.WaitForWriting(3000), Does.Contain("handled action 'HandleSync'"));
            livenessMonitorMock.Verify(_ => _.ClientReq(clientReq));
            storageNodeMock.Verify(_ => _.ReplReq(It.Is <ReplReq>(x => x.Data == clientReq.DataToReplicate)));
        }