static string StartClients(string sctx, SynchronizedLogger logger, out DomainCommunicationProvider clientsNetworkProvider)
        {
            var configuration = Configuration.Create().WithMonitorsInProductionEnabled().WithVerbosityEnabled(2);
            var runtime       = PSharpRuntime.Create(configuration);
            var runtimeHost   = HostInfo.NewRuntimeHost(runtime);

            clientsNetworkProvider = new DomainCommunicationProvider(runtimeHost, "clients");
            runtimeHost.SetNetworkProvider(clientsNetworkProvider);
            runtimeHost.SetLogger(logger);

            var messages = new MessageCollection();

            messages.CollectionChanged += (sender, e) => logger.WriteLine(e.NewItems[0].ToString());
            var ctx = sctx.FromJson <DistributedStorageContext>();

            var synchronizable = Synchronizable.Empty();

            foreach (var storageNode in ctx.StorageNodes)
            {
                var waitIfHandledReplReq = logger.MachineActionHandledWait((machineId, _, actionName) => Equals(machineId, storageNode.Id) && actionName == "HandleReplReq");
                synchronizable = synchronizable.Then(waitIfHandledReplReq.Delay(10));
            }
            logger.ApplySynchronization(synchronizable);

            NewClients(runtimeHost, ctx, messages);
            logger.WaitForWriting(6000);
            return(ctx.ToJson());
        }
        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);
        }
        static string StartStorageNodes(string sctx, IPublishableLogger logger, out DomainCommunicationProvider networkProvider)
        {
            var configuration = Configuration.Create().WithMonitorsInProductionEnabled().WithVerbosityEnabled(2);
            var runtime       = PSharpRuntime.Create(configuration);
            var runtimeHost   = HostInfo.NewRuntimeHost(runtime);

            networkProvider = new DomainCommunicationProvider(runtimeHost, "storage_nodes");
            runtimeHost.SetNetworkProvider(networkProvider);
            runtimeHost.SetLogger(logger);

            var messages = new MessageCollection();

            messages.CollectionChanged += (sender, e) => logger.WriteLine(e.NewItems[0].ToString());
            var ctx = sctx.FromJson <DistributedStorageContext>();

            NewStorageNodes(runtimeHost, ctx, messages);
            return(ctx.ToJson());
        }
        public void Context_should_not_return_same_Monitor_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().WithMonitorsInProductionEnabled();
                var runtime       = PSharpRuntime.Create(configuration);
                var runtimeHost   = HostInfo.NewRuntimeHost(runtime);
                using (var networkProvider = new DomainCommunicationProvider(runtimeHost, "monitors"))
                {
                    var parameter = default(string);
                    {
                        runtimeHost.SetNetworkProvider(networkProvider);

                        var ctx           = runtimeHost.New <DistributedStorageContext>();
                        ctx.SafetyMonitor = runtimeHost.New(MonitorInterface.Sender <ISafetyMonitorSender>().Bundler <ISafetyMonitorBundler>().Receiver <SafetyMonitorReceiver>());
                        ctx.SafetyMonitor.Configure(new ConfigureSafetyMonitor(new MessageCollection()));
                        expected_Assign_.Invoke(RuntimeHelpers.GetHashCode(ctx.SafetyMonitor));
                        parameter = ctx.ToJson();
                    }

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


            // Assert
            Assert.AreNotEqual(expected, actual);
        }
        public void Counter_can_communicate_remote_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().WithMonitorsInProductionEnabled();
                var runtime       = PSharpRuntime.Create(configuration);
                var runtimeHost   = HostInfo.NewRuntimeHost(runtime);
                using (var monitorsNetworkProvider = new DomainCommunicationProvider(runtimeHost, "monitors"))
                {
                    var parameter = default(string);
                    {
                        runtimeHost.SetNetworkProvider(monitorsNetworkProvider);

                        var counter = runtimeHost.NewDistributedCounter(42);
                        counter.Increment();
                        counter.Increment();
                        expected_Assign_.Invoke(counter.GetValue());
                        parameter = counter.ToJson();
                    }

                    AppDomain.CurrentDomain.RunAtIsolatedDomain((actual_Assign__, parameter_) =>
                    {
                        var counter = parameter_.FromJson <DistributedCounter>();
                        counter.Decrement();
                        actual_Assign__.Invoke(counter.GetValue());
                    }, actual_Assign_, parameter);
                }
            }, expected_Assign, actual_Assign);


            // Assert
            Assert.AreEqual(expected, actual + 1);
        }