Beispiel #1
0
        public async Task TestGraphLoggerCollapsed()
        {
            CustomLogger  logger = new CustomLogger();
            Configuration config = Configuration.Create().WithVerbosityEnabled();

            var graphBuilder = new ActorRuntimeLogGraphBuilder(false);

            graphBuilder.CollapseMachineInstances = true;

            var           tcs     = TaskCompletionSource.Create <bool>();
            IActorRuntime runtime = CreateTestRuntime(config, tcs, logger);

            runtime.RegisterLog(graphBuilder);

            ActorId serverId = runtime.CreateActor(typeof(Server));

            runtime.CreateActor(typeof(Client), new ClientSetupEvent(serverId));
            runtime.CreateActor(typeof(Client), new ClientSetupEvent(serverId));
            runtime.CreateActor(typeof(Client), new ClientSetupEvent(serverId));

            await WaitAsync(tcs.Task, 5000000);

            await Task.Delay(1000);

            string actual = graphBuilder.Graph.ToString();

            Assert.Contains("<Node Id='Microsoft.Coyote.Production.Tests.Actors.CustomActorRuntimeLogTests+Client.Client' Label='Client'/>", actual);
            Assert.Contains("<Node Id='Microsoft.Coyote.Production.Tests.Actors.CustomActorRuntimeLogTests+Server.Complete' Label='Complete'/>", actual);

            logger.Dispose();
        }
Beispiel #2
0
        public void TestQuiescentNetwork()
        {
            this.Test(async r =>
            {
                var graphBuilder = new ActorRuntimeLogGraphBuilder(false);
                r.RegisterLog(graphBuilder);

                var op = new ActorHaltedEventGroup();
                var id = r.CreateActor(typeof(NetworkActor), null, op);
                op.AddActor(id);

                // spawn 5 children, each child spawns 4 grand children and those spawn 3, etc.
                // so we should get 1 + 5 + (5*4) + (5*4*3) + (5*4*3*2) actors in this network = 206
                // actors before they are all halted.
                r.SendEvent(id, new SpawnEvent()
                {
                    Count = 5
                }, op);
                var result = await this.GetResultAsync(op.Task);

                string dgml = graphBuilder.Graph.ToString();
                Assert.Equal(206, op.Count);
            },
                      configuration: Configuration.Create().WithPCTStrategy(true));
        }
        public void TestGraphLoggerCollapsed()
        {
            this.Test(async runtime =>
            {
                using (CustomLogger logger = new CustomLogger())
                {
                    runtime.Logger = logger;

                    var graphBuilder = new ActorRuntimeLogGraphBuilder(false)
                    {
                        CollapseMachineInstances = true
                    };

                    var tcs = new TaskCompletionSource <bool>();
                    runtime.RegisterMonitor <TestMonitor>();
                    runtime.Monitor <TestMonitor>(new SetupEvent(tcs));
                    runtime.RegisterLog(graphBuilder);

                    ActorId serverId = runtime.CreateActor(typeof(Server));
                    runtime.CreateActor(typeof(Client), new ClientSetupEvent(serverId));
                    runtime.CreateActor(typeof(Client), new ClientSetupEvent(serverId));
                    runtime.CreateActor(typeof(Client), new ClientSetupEvent(serverId));

                    await this.WaitAsync(tcs.Task, 5000);
                    await Task.Delay(1000);
                    Assert.True(tcs.Task.IsCompleted, "The task await returned but the task is not completed???");

                    string actual = graphBuilder.Graph.ToString();

                    Assert.Contains("<Node Id='Microsoft.Coyote.Actors.Tests.CustomActorRuntimeLogTests+Client.Client' Label='Client'/>", actual);
                    Assert.Contains("<Node Id='Microsoft.Coyote.Actors.Tests.CustomActorRuntimeLogTests+Server.Complete' Label='Complete'/>", actual);
                }
            }, this.GetConfiguration());
        }
        public void TestGraphLoggerInstances()
        {
            Configuration config = Configuration.Create().WithVerbosityEnabled();

            this.Test(new Func <IActorRuntime, Task>(async(runtime) =>
            {
                using (CustomLogger logger = new CustomLogger())
                {
                    runtime.SetLogger(logger);

                    var graphBuilder = new ActorRuntimeLogGraphBuilder(false);

                    var tcs = TaskCompletionSource.Create <bool>();
                    runtime.RegisterMonitor <TestMonitor>();
                    runtime.Monitor <TestMonitor>(new SetupEvent(tcs));
                    runtime.RegisterLog(graphBuilder);

                    ActorId serverId = runtime.CreateActor(typeof(Server));
                    runtime.CreateActor(typeof(Client), new ClientSetupEvent(serverId));
                    runtime.CreateActor(typeof(Client), new ClientSetupEvent(serverId));
                    runtime.CreateActor(typeof(Client), new ClientSetupEvent(serverId));

                    await this.WaitAsync(tcs.Task);
                    await Task.Delay(1000);
                    Assert.True(tcs.Task.IsCompleted, "The task await returned but the task is not completed???");

                    string actual = graphBuilder.Graph.ToString();
                    actual        = actual.RemoveInstanceIds();

                    Assert.Contains("<Node Id='Microsoft.Coyote.Production.Tests.Actors.CustomActorRuntimeLogTests+Client().Client()' Label='Client()'/>", actual);
                    Assert.Contains("<Node Id='Microsoft.Coyote.Production.Tests.Actors.CustomActorRuntimeLogTests+Server().Complete' Label='Complete'/>", actual);
                    Assert.Contains("<Node Id='Microsoft.Coyote.Production.Tests.Actors.CustomActorRuntimeLogTests+TestMonitor.Init' Label='Init'/>", actual);
                }
            }), config);
        }
Beispiel #5
0
        public void TestGraphLogger()
        {
            Configuration config = Configuration.Create().WithVerbosityEnabled();

            this.Test(async runtime =>
            {
                using (CustomLogger logger = new CustomLogger())
                {
                    runtime.SetLogger(logger);
                    var tcs = TaskCompletionSource.Create <bool>();
                    runtime.RegisterMonitor <TestMonitor>();
                    runtime.Monitor <TestMonitor>(new SetupEvent(tcs));
                    var graphBuilder = new ActorRuntimeLogGraphBuilder(false);
                    runtime.RegisterLog(graphBuilder);
                    runtime.CreateActor(typeof(M));
                    await this.WaitAsync(tcs.Task);
                    await Task.Delay(200);
                    Assert.True(tcs.Task.IsCompleted, "The task await returned but the task is not completed???");

                    string expected = @"<DirectedGraph xmlns='http://schemas.microsoft.com/vs/2009/dgml'>
  <Nodes>
    <Node Id='Microsoft.Coyote.Production.Tests.Actors.CustomActorRuntimeLogTests+M(0)' Category='Actor' Group='Expanded'/>
    <Node Id='Microsoft.Coyote.Production.Tests.Actors.CustomActorRuntimeLogTests+M(0).M(0)' Label='M(0)'/>
    <Node Id='Microsoft.Coyote.Production.Tests.Actors.CustomActorRuntimeLogTests+N(1)' Category='StateMachine' Group='Expanded'/>
    <Node Id='Microsoft.Coyote.Production.Tests.Actors.CustomActorRuntimeLogTests+N(1).Act' Label='Act'/>
    <Node Id='Microsoft.Coyote.Production.Tests.Actors.CustomActorRuntimeLogTests+N(1).Init' Label='Init'/>
    <Node Id='Microsoft.Coyote.Production.Tests.Actors.CustomActorRuntimeLogTests+TestMonitor' Group='Expanded'/>
    <Node Id='Microsoft.Coyote.Production.Tests.Actors.CustomActorRuntimeLogTests+TestMonitor.Init' Label='Init'/>
  </Nodes>
  <Links>
    <Link Source='Microsoft.Coyote.Production.Tests.Actors.CustomActorRuntimeLogTests+M(0)' Target='Microsoft.Coyote.Production.Tests.Actors.CustomActorRuntimeLogTests+M(0).M(0)' Category='Contains'/>
    <Link Source='Microsoft.Coyote.Production.Tests.Actors.CustomActorRuntimeLogTests+M(0)' Target='Microsoft.Coyote.Production.Tests.Actors.CustomActorRuntimeLogTests+N(1)' Label='CreateActor' Index='0' EventId='CreateActor'/>
    <Link Source='Microsoft.Coyote.Production.Tests.Actors.CustomActorRuntimeLogTests+M(0).M(0)' Target='Microsoft.Coyote.Production.Tests.Actors.CustomActorRuntimeLogTests+N(1).Init' Label='E' Index='0' EventId='Microsoft.Coyote.Production.Tests.Actors.CustomActorRuntimeLogTests+E' HandledBy='Init'/>
    <Link Source='Microsoft.Coyote.Production.Tests.Actors.CustomActorRuntimeLogTests+M(0).M(0)' Target='Microsoft.Coyote.Production.Tests.Actors.CustomActorRuntimeLogTests+TestMonitor.Init' Label='CompletedEvent' Index='0' EventId='Microsoft.Coyote.Production.Tests.Actors.CustomActorRuntimeLogTests+CompletedEvent'/>
    <Link Source='Microsoft.Coyote.Production.Tests.Actors.CustomActorRuntimeLogTests+N(1)' Target='Microsoft.Coyote.Production.Tests.Actors.CustomActorRuntimeLogTests+N(1).Act' Category='Contains'/>
    <Link Source='Microsoft.Coyote.Production.Tests.Actors.CustomActorRuntimeLogTests+N(1)' Target='Microsoft.Coyote.Production.Tests.Actors.CustomActorRuntimeLogTests+N(1).Init' Category='Contains'/>
    <Link Source='Microsoft.Coyote.Production.Tests.Actors.CustomActorRuntimeLogTests+N(1).Act' Target='Microsoft.Coyote.Production.Tests.Actors.CustomActorRuntimeLogTests+M(0).M(0)' Label='E' Index='0' EventId='Microsoft.Coyote.Production.Tests.Actors.CustomActorRuntimeLogTests+E'/>
    <Link Source='Microsoft.Coyote.Production.Tests.Actors.CustomActorRuntimeLogTests+N(1).Init' Target='Microsoft.Coyote.Production.Tests.Actors.CustomActorRuntimeLogTests+N(1).Act' Label='E' Index='0' EventId='Microsoft.Coyote.Production.Tests.Actors.CustomActorRuntimeLogTests+E' HandledBy='Init'/>
    <Link Source='Microsoft.Coyote.Production.Tests.Actors.CustomActorRuntimeLogTests+TestMonitor' Target='Microsoft.Coyote.Production.Tests.Actors.CustomActorRuntimeLogTests+TestMonitor.Init' Category='Contains'/>
    <Link Source='Microsoft.Coyote.Production.Tests.Actors.CustomActorRuntimeLogTests+TestMonitor.Init' Target='Microsoft.Coyote.Production.Tests.Actors.CustomActorRuntimeLogTests+TestMonitor.Init' Label='CompletedEvent' Index='0' EventId='Microsoft.Coyote.Production.Tests.Actors.CustomActorRuntimeLogTests+CompletedEvent'/>
  </Links>
</DirectedGraph>
";

                    string dgml   = graphBuilder.Graph.ToString();
                    string actual = dgml.RemoveNonDeterministicValues();
                    expected      = expected.RemoveNonDeterministicValues();
                    Assert.Equal(expected, actual);
                }
            }, config);
        }
Beispiel #6
0
        public async Task TestGraphLogger()
        {
            CustomLogger  logger = new CustomLogger();
            Configuration config = Configuration.Create().WithVerbosityEnabled();

            var           graphBuilder = new ActorRuntimeLogGraphBuilder(false);
            var           tcs          = TaskCompletionSource.Create <bool>();
            IActorRuntime runtime      = CreateTestRuntime(config, tcs, logger);

            runtime.RegisterLog(graphBuilder);

            runtime.CreateActor(typeof(M));

            await WaitAsync(tcs.Task);

            await Task.Delay(200);

            string expected = @"<DirectedGraph xmlns='http://schemas.microsoft.com/vs/2009/dgml'>
  <Nodes>
    <Node Id='M()' Category='Actor' Group='Expanded'/>
    <Node Id='M().M()' Label='M()'/>
    <Node Id='N()' Category='StateMachine' Group='Expanded'/>
    <Node Id='N().Act' Label='Act'/>
    <Node Id='N().Init' Label='Init'/>
    <Node Id='TestMonitor' Group='Expanded'/>
    <Node Id='TestMonitor.Init' Label='Init'/>
    <Node Id='TestMonitor.OnCompleted' Label='OnCompleted'/>
  </Nodes>
  <Links>
    <Link Source='M().M()' Target='N().Init' Label='E' Index='' EventId='E' HandledBy='Init'/>
    <Link Source='M().M()' Target='TestMonitor.Init' Label='CompletedEvent' Index='' EventId='CompletedEvent'/>
    <Link Source='M()' Target='M().M()' Category='Contains'/>
    <Link Source='N().Act' Target='M().M()' Label='E' Index='' EventId='E'/>
    <Link Source='N().Init' Target='N().Act' Label='E' Index='' EventId='E' HandledBy='Init'/>
    <Link Source='N()' Target='N().Act' Category='Contains'/>
    <Link Source='N()' Target='N().Init' Category='Contains'/>
    <Link Source='TestMonitor.Init' Target='TestMonitor.OnCompleted' Label='CompletedEvent' Index='' EventId='CompletedEvent'/>
    <Link Source='TestMonitor' Target='TestMonitor.Init' Category='Contains'/>
    <Link Source='TestMonitor' Target='TestMonitor.OnCompleted' Category='Contains'/>
  </Links>
</DirectedGraph>
";

            string actual = RemoveNonDeterministicValuesFromReport(graphBuilder.Graph.ToString());

            Assert.Equal(expected, actual);

            logger.Dispose();
        }
Beispiel #7
0
        private static async void PeriodicSaves(ActorRuntimeLogGraphBuilder log, string baseName)
        {
            while (true)
            {
                await Task.Delay(10000);

                Graph  graph    = log.SnapshotGraph(false);
                string filename = baseName + ".dgml";
                using (var stream = new StreamWriter(filename, false, Encoding.UTF8))
                {
                    Console.WriteLine("############ saved " + filename + " ##########################################");
                    graph.WriteDgml(stream, true);
                }
            }
        }
        public void TestQuiescentNetwork()
        {
            this.Test(async r =>
            {
                var graphBuilder = new ActorRuntimeLogGraphBuilder(false, false);
                r.RegisterLog(graphBuilder);

                var op = new ActorHaltedEventGroup();
                var id = r.CreateActor(typeof(NetworkActor), null, op);
                op.AddActor(id);

                // Spawn 4 children, each child spawns 3 children and those spawn 2, etc.
                // So we should get 41 (1 + 4 + (4*3) + (4*3*2)) actors in the network
                // before they are all halted.
                r.SendEvent(id, new SpawnEvent()
                {
                    Count = 4
                }, op);
                var result = await this.GetResultAsync(op.Task);
                Assert.Equal(41, op.Count);
            });
        }
Beispiel #9
0
        internal async Task RunAsync()
        {
            try
            {
                // We use the Topic/Subscription pattern which is a pub/sub model where each Server will send
                // messages to this Topic, and every other server has a Subscription to receive those messages.
                // If the Message has a "To" field then the server ignores the message as it was not meant for them.
                // Otherwise the Message is considered a "broadcast" to all servers and each server will handle it.
                // The client also has a subcription on the same topic and is how it broadcasts requests and receives
                // the final response from the elected Leader.
                var managementClient = new ManagementClient(this.ConnectionString);
                if (!await managementClient.TopicExistsAsync(this.TopicName))
                {
                    await managementClient.CreateTopicAsync(this.TopicName);
                }

                // then we need a subscription, whether we are client or server and the subscription name will be
                // the same as our local actorid.
                string subscriptionName = (this.ServerId < 0) ? "Client" : $"Server-{this.ServerId}";
                if (!await managementClient.SubscriptionExistsAsync(this.TopicName, subscriptionName))
                {
                    await managementClient.CreateSubscriptionAsync(
                        new SubscriptionDescription(this.TopicName, subscriptionName));
                }

                Console.WriteLine("Running " + subscriptionName);

                IActorRuntime runtime = RuntimeFactory.Create(Configuration.Create().WithVerbosityEnabled());

                if (this.GraphIt)
                {
                    var graphBuilder = new ActorRuntimeLogGraphBuilder(false);
                    runtime.RegisterLog(graphBuilder);
                    _ = Task.Run(() => { PeriodicSaves(graphBuilder, subscriptionName); });
                }

                // We create a new Coyote actor runtime instance, and pass an optional configuration
                // that increases the verbosity level to see the Coyote runtime log.
                runtime.OnFailure += RuntimeOnFailure;

                var topicClient = new TopicClient(this.ConnectionString, this.TopicName);

                // cluster manager needs the topic client in order to be able to broadcast messages using Azure Service Bus
                var clusterManager = runtime.CreateActor(typeof(AzureClusterManager), new AzureClusterManager.RegisterMessageBusEvent()
                {
                    TopicClient = topicClient
                });
                if (this.ServerId < 0)
                {
                    await this.RunClient(runtime, clusterManager, subscriptionName);
                }
                else
                {
                    await this.RunServer(runtime, clusterManager, subscriptionName);
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine($"{DateTime.Now} :: ex: {ex.ToString()}");
            }
        }