Example #1
0
        static void Main(string[] args)
        {
            var nodeIndex        = CommandLine.GetInt32("multinode.index");
            var assemblyFileName = CommandLine.GetProperty("multinode.test-assembly");
            var typeName         = CommandLine.GetProperty("multinode.test-class");
            var testName         = CommandLine.GetProperty("multinode.test-method");
            var displayName      = testName;

            Thread.Sleep(TimeSpan.FromSeconds(10));

            using (var controller = new XunitFrontController(assemblyFileName))
            {
                /* need to pass in just the assembly name to Discovery, not the full path
                 * i.e. "Akka.Cluster.Tests.MultiNode.dll"
                 * not "bin/Release/Akka.Cluster.Tests.MultiNode.dll" - this will cause
                 * the Discovery class to actually not find any indivudal specs to run
                 */
                var assemblyName = Path.GetFileName(assemblyFileName);
                Console.WriteLine("Running specs for {0} [{1}]", assemblyName, assemblyFileName);
                using (var discovery = new Discovery(assemblyName, typeName))
                {
                    using (var sink = new Sink(nodeIndex))
                    {
                        Thread.Sleep(10000);
                        try
                        {
                            controller.Find(true, discovery, TestFrameworkOptions.ForDiscovery());
                            discovery.Finished.WaitOne();
                            controller.RunTests(discovery.TestCases, sink, TestFrameworkOptions.ForExecution());
                        }
                        catch (AggregateException ex)
                        {
                            var specFail = new SpecFail(nodeIndex, displayName);
                            specFail.FailureExceptionTypes.Add(ex.GetType().ToString());
                            specFail.FailureMessages.Add(ex.Message);
                            specFail.FailureStackTraces.Add(ex.StackTrace);
                            foreach (var innerEx in ex.Flatten().InnerExceptions)
                            {
                                specFail.FailureExceptionTypes.Add(innerEx.GetType().ToString());
                                specFail.FailureMessages.Add(innerEx.Message);
                                specFail.FailureStackTraces.Add(innerEx.StackTrace);
                            }
                            Console.WriteLine(specFail);
                            Environment.Exit(1); //signal failure
                        }
                        catch (Exception ex)
                        {
                            var specFail = new SpecFail(nodeIndex, displayName);
                            specFail.FailureExceptionTypes.Add(ex.GetType().ToString());
                            specFail.FailureMessages.Add(ex.Message);
                            specFail.FailureStackTraces.Add(ex.StackTrace);
                            Console.WriteLine(specFail);
                            Environment.Exit(1); //signal failure
                        }
                        sink.Finished.WaitOne();
                        Environment.Exit(sink.Passed ? 0 : 1);
                    }
                }
            }
        }
Example #2
0
        static void Main(string[] args)
        {
            var nodeIndex = CommandLine.GetInt32("multinode.index");
            var assemblyFileName = CommandLine.GetProperty("multinode.test-assembly");
            var typeName = CommandLine.GetProperty("multinode.test-class");
            var testName = CommandLine.GetProperty("multinode.test-method");
            var displayName = testName;

            Thread.Sleep(TimeSpan.FromSeconds(10));

            using (var controller = new XunitFrontController(assemblyFileName))
            {
                /* need to pass in just the assembly name to Discovery, not the full path
                 * i.e. "Akka.Cluster.Tests.MultiNode.dll"
                 * not "bin/Release/Akka.Cluster.Tests.MultiNode.dll" - this will cause
                 * the Discovery class to actually not find any indivudal specs to run
                 */
                var assemblyName = Path.GetFileName(assemblyFileName);
                Console.WriteLine("Running specs for {0} [{1}]", assemblyName, assemblyFileName);
                using (var discovery = new Discovery(assemblyName, typeName))
                {
                    using (var sink = new Sink(nodeIndex))
                    {
                        Thread.Sleep(10000);
                        try
                        {
                            controller.Find(true, discovery, TestFrameworkOptions.ForDiscovery());
                            discovery.Finished.WaitOne();
                            controller.RunTests(discovery.TestCases, sink, TestFrameworkOptions.ForExecution());
                        }
                        catch (AggregateException ex)
                        {
                            var specFail = new SpecFail(nodeIndex, displayName);
                            specFail.FailureExceptionTypes.Add(ex.GetType().ToString());
                            specFail.FailureMessages.Add(ex.Message);
                            specFail.FailureStackTraces.Add(ex.StackTrace);
                            foreach (var innerEx in ex.Flatten().InnerExceptions)
                            {
                                specFail.FailureExceptionTypes.Add(innerEx.GetType().ToString());
                                specFail.FailureMessages.Add(innerEx.Message);
                                specFail.FailureStackTraces.Add(innerEx.StackTrace);
                            }
                            Console.WriteLine(specFail);
                            Environment.Exit(1); //signal failure
                        }
                        catch (Exception ex)
                        {
                            var specFail = new SpecFail(nodeIndex, displayName);
                            specFail.FailureExceptionTypes.Add(ex.GetType().ToString());
                            specFail.FailureMessages.Add(ex.Message);
                            specFail.FailureStackTraces.Add(ex.StackTrace);
                            Console.WriteLine(specFail);
                            Environment.Exit(1); //signal failure
                        }
                        sink.Finished.WaitOne();
                        Environment.Exit(sink.Passed ? 0 : 1);
                    }
                }
            }
        }
Example #3
0
        static void Main(string[] args)
        {
            var nodeIndex = CommandLine.GetInt32("multinode.index");
            var assemblyName = CommandLine.GetProperty("multinode.test-assembly");
            var typeName = CommandLine.GetProperty("multinode.test-class");
            var testName = CommandLine.GetProperty("multinode.test-method");
            var displayName = testName;

            Thread.Sleep(TimeSpan.FromSeconds(10));

            using (var controller = new XunitFrontController(assemblyName))
            {
                using (var discovery = new Discovery(assemblyName, typeName))
                {
                    using (var sink = new Sink(nodeIndex))
                    {
                        Thread.Sleep(10000);
                        try
                        {
                            controller.Find(true, discovery, TestFrameworkOptions.ForDiscovery());
                            discovery.Finished.WaitOne();
                            controller.RunTests(discovery.TestCases, sink, TestFrameworkOptions.ForExecution());
                        }
                        catch (AggregateException ex)
                        {
                            var specFail = new SpecFail(nodeIndex, displayName);
                            specFail.FailureExceptionTypes.Add(ex.GetType().ToString());
                            specFail.FailureMessages.Add(ex.Message);
                            specFail.FailureStackTraces.Add(ex.StackTrace);
                            foreach (var innerEx in ex.Flatten().InnerExceptions)
                            {
                                specFail.FailureExceptionTypes.Add(innerEx.GetType().ToString());
                                specFail.FailureMessages.Add(innerEx.Message);
                                specFail.FailureStackTraces.Add(innerEx.StackTrace);
                            }
                            Console.WriteLine(specFail);
                            Environment.Exit(1); //signal failure
                        }
                        catch (Exception ex)
                        {
                            var specFail = new SpecFail(nodeIndex, displayName);
                            specFail.FailureExceptionTypes.Add(ex.GetType().ToString());
                            specFail.FailureMessages.Add(ex.Message);
                            specFail.FailureStackTraces.Add(ex.StackTrace);
                            Console.WriteLine(specFail);
                            Environment.Exit(1); //signal failure
                        }
                        sink.Finished.WaitOne();
                        Environment.Exit(sink.Passed ? 0 : 1);
                    }
                }
            }
        }
Example #4
0
        static void Main(string[] args)
        {
            var nodeIndex    = CommandLine.GetInt32("multinode.index");
            var assemblyName = CommandLine.GetProperty("multinode.test-assembly");
            var typeName     = CommandLine.GetProperty("multinode.test-class");
            var testName     = CommandLine.GetProperty("multinode.test-method");
            var displayName  = testName;

            Thread.Sleep(TimeSpan.FromSeconds(10));

            using (var controller = new XunitFrontController(assemblyName))
            {
                using (var sink = new Sink(nodeIndex))
                {
                    Thread.Sleep(10000);
                    try
                    {
                        controller.RunTests(
                            new[]
                        {
                            new Xunit1TestCase(assemblyName, null, typeName, testName, displayName, null,
                                               "MultiNodeTest")
                        }, sink, new TestFrameworkOptions());
                    }
                    catch (AggregateException ex)
                    {
                        var specFail = new SpecFail(nodeIndex, displayName);
                        specFail.FailureExceptionTypes.Add(ex.GetType().ToString());
                        specFail.FailureMessages.Add(ex.Message);
                        specFail.FailureStackTraces.Add(ex.StackTrace);
                        foreach (var innerEx in ex.Flatten().InnerExceptions)
                        {
                            specFail.FailureExceptionTypes.Add(innerEx.GetType().ToString());
                            specFail.FailureMessages.Add(innerEx.Message);
                            specFail.FailureStackTraces.Add(innerEx.StackTrace);
                        }
                        Console.WriteLine(specFail);
                        Environment.Exit(1); //signal failure
                    }
                    catch (Exception ex)
                    {
                        var specFail = new SpecFail(nodeIndex, displayName);
                        specFail.FailureExceptionTypes.Add(ex.GetType().ToString());
                        specFail.FailureMessages.Add(ex.Message);
                        specFail.FailureStackTraces.Add(ex.StackTrace);
                        Console.WriteLine(specFail);
                        Environment.Exit(1); //signal failure
                    }
                    sink.Finished.WaitOne();
                    Environment.Exit(sink.Passed ? 0 : 1);
                }
            }
        }
Example #5
0
        public bool OnMessage(IMessageSinkMessage message)
        {
            var resultMessage = message as ITestResultMessage;
            if (resultMessage != null)
            {
                _logger.Tell(resultMessage.Output);
                Console.WriteLine(resultMessage.Output);
            }
            var testPassed = message as ITestPassed;
            if (testPassed != null)
            {
                //the MultiNodeTestRunner uses 1-based indexing, which is why we have to add 1 to the index.
                var specPass = new SpecPass(_nodeIndex + 1, testPassed.TestCase.DisplayName);
                _logger.Tell(specPass.ToString());
                Console.WriteLine(specPass.ToString()); //so the message also shows up in the individual per-node build log
                Passed = true;
                return true;
            }
            var testFailed = message as ITestFailed;
            if (testFailed != null)
            {
                //the MultiNodeTestRunner uses 1-based indexing, which is why we have to add 1 to the index.
                var specFail = new SpecFail(_nodeIndex + 1, testFailed.TestCase.DisplayName);
                foreach (var failedMessage in testFailed.Messages) specFail.FailureMessages.Add(failedMessage);
                foreach (var stackTrace in testFailed.StackTraces) specFail.FailureStackTraces.Add(stackTrace);
                foreach(var exceptionType in testFailed.ExceptionTypes) specFail.FailureExceptionTypes.Add(exceptionType);
                _logger.Tell(specFail.ToString());
                Console.WriteLine(specFail.ToString());
                return true;
            }
            var errorMessage = message as ErrorMessage;
            if (errorMessage != null)
            {
                var specFail = new SpecFail(_nodeIndex + 1, "ERRORED");
                foreach (var failedMessage in errorMessage.Messages) specFail.FailureMessages.Add(failedMessage);
                foreach (var stackTrace in errorMessage.StackTraces) specFail.FailureStackTraces.Add(stackTrace);
                foreach (var exceptionType in errorMessage.ExceptionTypes) specFail.FailureExceptionTypes.Add(exceptionType);
                _logger.Tell(specFail.ToString());
                Console.WriteLine(specFail.ToString());
            }
            if (message is ITestAssemblyFinished)
            {
                Finished.Set();
            }

            return true;
        }
Example #6
0
        public void MessageSink_should_be_able_to_infer_message_type()
        {
            var specPass = new SpecPass(1, GetType().Assembly.GetName().Name);
            var specFail = new SpecFail(1, GetType().Assembly.GetName().Name);

            var loggingActor = Sys.ActorOf<LoggingActor>();
            Sys.EventStream.Subscribe(TestActor, typeof(Debug));
            loggingActor.Tell("LOG ME!");

            //capture the logged message
            var foundMessage = ExpectMsg<Debug>();

            //format the string as it would appear when reported by multinode test runner
            var nodeMessageStr = "[NODE1]" + foundMessage;
            var nodeMessageFragment = "[NODE1]      Only part of a message!";
            var runnerMessageStr = foundMessage.ToString();

            MessageSink.DetermineMessageType(nodeMessageStr).ShouldBe(MessageSink.MultiNodeTestRunnerMessageType.NodeLogMessage);
            MessageSink.DetermineMessageType(runnerMessageStr).ShouldBe(MessageSink.MultiNodeTestRunnerMessageType.RunnerLogMessage);
            MessageSink.DetermineMessageType(specPass.ToString()).ShouldBe(MessageSink.MultiNodeTestRunnerMessageType.NodePassMessage);
            MessageSink.DetermineMessageType(specFail.ToString()).ShouldBe(MessageSink.MultiNodeTestRunnerMessageType.NodeFailMessage);
            MessageSink.DetermineMessageType("[Node2][FAIL-EXCEPTION] Type: Xunit.Sdk.TrueException").ShouldBe(MessageSink.MultiNodeTestRunnerMessageType.NodeFailureException);
            MessageSink.DetermineMessageType(nodeMessageFragment).ShouldBe(MessageSink.MultiNodeTestRunnerMessageType.NodeLogFragment);
            MessageSink.DetermineMessageType("foo!").ShouldBe(MessageSink.MultiNodeTestRunnerMessageType.Unknown);
        }
Example #7
0
        public void MessageSink_should_parse_Node_SpecFail_message_correctly()
        {
            var specFail = new SpecFail(1, GetType().Assembly.GetName().Name);
            NodeCompletedSpecWithFail nodeCompletedSpecWithFail;
            MessageSink.TryParseFailureMessage(specFail.ToString(), out nodeCompletedSpecWithFail)
                .ShouldBeTrue("should have been able to parse node failure message");

            Assert.Equal(specFail.NodeIndex, nodeCompletedSpecWithFail.NodeIndex);
        }
Example #8
0
        public bool OnMessage(IMessageSinkMessage message)
        {
            var resultMessage = message as ITestResultMessage;

            if (resultMessage != null)
            {
                _logger.Tell(resultMessage.Output);
                Console.WriteLine(resultMessage.Output);
            }
            var testPassed = message as ITestPassed;

            if (testPassed != null)
            {
                //the MultiNodeTestRunner uses 1-based indexing, which is why we have to add 1 to the index.
                var specPass = new SpecPass(_nodeIndex + 1, _nodeRole, testPassed.TestCase.DisplayName);
                _logger.Tell(specPass.ToString());
                Console.WriteLine(specPass.ToString()); //so the message also shows up in the individual per-node build log
                Passed = true;
                return(true);
            }
            var testFailed = message as ITestFailed;

            if (testFailed != null)
            {
                //the MultiNodeTestRunner uses 1-based indexing, which is why we have to add 1 to the index.
                var specFail = new SpecFail(_nodeIndex + 1, _nodeRole, testFailed.TestCase.DisplayName);
                foreach (var failedMessage in testFailed.Messages)
                {
                    specFail.FailureMessages.Add(failedMessage);
                }
                foreach (var stackTrace in testFailed.StackTraces)
                {
                    specFail.FailureStackTraces.Add(stackTrace);
                }
                foreach (var exceptionType in testFailed.ExceptionTypes)
                {
                    specFail.FailureExceptionTypes.Add(exceptionType);
                }
                _logger.Tell(specFail.ToString());
                Console.WriteLine(specFail.ToString());
                return(true);
            }
            var errorMessage = message as ErrorMessage;

            if (errorMessage != null)
            {
                var specFail = new SpecFail(_nodeIndex + 1, _nodeRole, "ERRORED");
                foreach (var failedMessage in errorMessage.Messages)
                {
                    specFail.FailureMessages.Add(failedMessage);
                }
                foreach (var stackTrace in errorMessage.StackTraces)
                {
                    specFail.FailureStackTraces.Add(stackTrace);
                }
                foreach (var exceptionType in errorMessage.ExceptionTypes)
                {
                    specFail.FailureExceptionTypes.Add(exceptionType);
                }
                _logger.Tell(specFail.ToString());
                Console.WriteLine(specFail.ToString());
            }
            if (message is ITestAssemblyFinished)
            {
                Finished.Set();
            }

            return(true);
        }
Example #9
0
        static int Main(string[] args)
        {
            var nodeIndex        = CommandLine.GetInt32("multinode.index");
            var nodeRole         = CommandLine.GetProperty("multinode.role");
            var assemblyFileName = CommandLine.GetProperty("multinode.test-assembly");
            var typeName         = CommandLine.GetProperty("multinode.test-class");
            var testName         = CommandLine.GetProperty("multinode.test-method");
            var displayName      = testName;

            var listenAddress  = IPAddress.Parse(CommandLine.GetProperty("multinode.listen-address"));
            var listenPort     = CommandLine.GetInt32("multinode.listen-port");
            var listenEndpoint = new IPEndPoint(listenAddress, listenPort);

            var system    = ActorSystem.Create("NoteTestRunner-" + nodeIndex);
            var tcpClient = _logger = system.ActorOf <RunnerTcpClient>();

            system.Tcp().Tell(new Tcp.Connect(listenEndpoint), tcpClient);

#if CORECLR
            // In NetCore, if the assembly file hasn't been touched,
            // XunitFrontController would fail loading external assemblies and its dependencies.
            AssemblyLoadContext.Default.Resolving += (assemblyLoadContext, assemblyName) => DefaultOnResolving(assemblyLoadContext, assemblyName, assemblyFileName);
            var assembly = AssemblyLoadContext.Default.LoadFromAssemblyPath(assemblyFileName);
            DependencyContext.Load(assembly)
            .CompileLibraries
            .Where(dep => dep.Name.ToLower()
                   .Contains(assembly.FullName.Split(new[] { ',' })[0].ToLower()))
            .Select(dependency => AssemblyLoadContext.Default.LoadFromAssemblyName(new AssemblyName(dependency.Name)));
#endif

            Thread.Sleep(TimeSpan.FromSeconds(10));
            using (var controller = new XunitFrontController(AppDomainSupport.IfAvailable, assemblyFileName))
            {
                /* need to pass in just the assembly name to Discovery, not the full path
                 * i.e. "Akka.Cluster.Tests.MultiNode.dll"
                 * not "bin/Release/Akka.Cluster.Tests.MultiNode.dll" - this will cause
                 * the Discovery class to actually not find any individual specs to run
                 */
                var assemblyName = Path.GetFileName(assemblyFileName);
                Console.WriteLine("Running specs for {0} [{1}]", assemblyName, assemblyFileName);
                using (var discovery = new Discovery(assemblyName, typeName))
                {
                    using (var sink = new Sink(nodeIndex, nodeRole, tcpClient))
                    {
                        try
                        {
                            controller.Find(true, discovery, TestFrameworkOptions.ForDiscovery());
                            discovery.Finished.WaitOne();
                            controller.RunTests(discovery.TestCases, sink, TestFrameworkOptions.ForExecution());
                        }
                        catch (AggregateException ex)
                        {
                            var specFail = new SpecFail(nodeIndex, nodeRole, displayName);
                            specFail.FailureExceptionTypes.Add(ex.GetType().ToString());
                            specFail.FailureMessages.Add(ex.Message);
                            specFail.FailureStackTraces.Add(ex.StackTrace);
                            foreach (var innerEx in ex.Flatten().InnerExceptions)
                            {
                                specFail.FailureExceptionTypes.Add(innerEx.GetType().ToString());
                                specFail.FailureMessages.Add(innerEx.Message);
                                specFail.FailureStackTraces.Add(innerEx.StackTrace);
                            }
                            _logger.Tell(specFail.ToString());
                            Console.WriteLine(specFail);

                            //make sure message is send over the wire
                            FlushLogMessages();
                            Environment.Exit(1); //signal failure
                            return(1);
                        }
                        catch (Exception ex)
                        {
                            var specFail = new SpecFail(nodeIndex, nodeRole, displayName);
                            specFail.FailureExceptionTypes.Add(ex.GetType().ToString());
                            specFail.FailureMessages.Add(ex.Message);
                            specFail.FailureStackTraces.Add(ex.StackTrace);
                            _logger.Tell(specFail.ToString());
                            Console.WriteLine(specFail);

                            //make sure message is send over the wire
                            FlushLogMessages();
                            Environment.Exit(1); //signal failure
                            return(1);
                        }

                        var timedOut = false;
                        if (!sink.Finished.WaitOne(MaxProcessWaitTimeout)) //timed out
                        {
                            var line = string.Format("Timed out while waiting for test to complete after {0} ms",
                                                     MaxProcessWaitTimeout);
                            _logger.Tell(line);
                            Console.WriteLine(line);
                            timedOut = true;
                        }

                        FlushLogMessages();
                        system.Terminate().Wait();

                        Environment.Exit(sink.Passed && !timedOut ? 0 : 1);
                        return(sink.Passed ? 0 : 1);
                    }
                }
            }
        }
Example #10
0
        static int Main(string[] args)
        {
            var nodeIndex = CommandLine.GetInt32("multinode.index");
            var assemblyFileName = CommandLine.GetProperty("multinode.test-assembly");
            var typeName = CommandLine.GetProperty("multinode.test-class");
            var testName = CommandLine.GetProperty("multinode.test-method");
            var displayName = testName;

            var listenAddress = IPAddress.Parse(CommandLine.GetProperty("multinode.listen-address"));
            var listenPort = CommandLine.GetInt32("multinode.listen-port");
            var listenEndpoint = new IPEndPoint(listenAddress, listenPort);

            var system = ActorSystem.Create("NoteTestRunner-" + nodeIndex);
            var tcpClient = _logger = system.ActorOf<RunnerTcpClient>();
            system.Tcp().Tell(new Tcp.Connect(listenEndpoint), tcpClient);

            Thread.Sleep(TimeSpan.FromSeconds(10));
            using (var controller = new XunitFrontController(AppDomainSupport.IfAvailable, assemblyFileName))
            {
                /* need to pass in just the assembly name to Discovery, not the full path
                 * i.e. "Akka.Cluster.Tests.MultiNode.dll"
                 * not "bin/Release/Akka.Cluster.Tests.MultiNode.dll" - this will cause
                 * the Discovery class to actually not find any indivudal specs to run
                 */
                var assemblyName = Path.GetFileName(assemblyFileName);
                Console.WriteLine("Running specs for {0} [{1}]", assemblyName, assemblyFileName);
                using (var discovery = new Discovery(assemblyName, typeName))
                {
                    using (var sink = new Sink(nodeIndex, tcpClient))
                    {
                        try
                        {
                            controller.Find(true, discovery, TestFrameworkOptions.ForDiscovery());
                            discovery.Finished.WaitOne();
                            controller.RunTests(discovery.TestCases, sink, TestFrameworkOptions.ForExecution());
                        }
                        catch (AggregateException ex)
                        {
                            var specFail = new SpecFail(nodeIndex, displayName);
                            specFail.FailureExceptionTypes.Add(ex.GetType().ToString());
                            specFail.FailureMessages.Add(ex.Message);
                            specFail.FailureStackTraces.Add(ex.StackTrace);
                            foreach (var innerEx in ex.Flatten().InnerExceptions)
                            {
                                specFail.FailureExceptionTypes.Add(innerEx.GetType().ToString());
                                specFail.FailureMessages.Add(innerEx.Message);
                                specFail.FailureStackTraces.Add(innerEx.StackTrace);
                            }
                            _logger.Tell(specFail.ToString());
                            Console.WriteLine(specFail);

                            //make sure message is send over the wire
                            FlushLogMessages();
                            Environment.Exit(1); //signal failure
                            return 1;
                        }
                        catch (Exception ex)
                        {
                            var specFail = new SpecFail(nodeIndex, displayName);
                            specFail.FailureExceptionTypes.Add(ex.GetType().ToString());
                            specFail.FailureMessages.Add(ex.Message);
                            specFail.FailureStackTraces.Add(ex.StackTrace);
                            _logger.Tell(specFail.ToString());
                            Console.WriteLine(specFail);

                            //make sure message is send over the wire
                            FlushLogMessages();
                            Environment.Exit(1); //signal failure
                            return 1;
                        }

                        var timedOut = false;
                        if (!sink.Finished.WaitOne(MaxProcessWaitTimeout)) //timed out
                        {
                            var line = string.Format("Timed out while waiting for test to complete after {0} ms",
                                MaxProcessWaitTimeout);
                            _logger.Tell(line);
                            Console.WriteLine(line);
                            timedOut = true;
                        }

                        FlushLogMessages();
                        system.Terminate().Wait();

                        Environment.Exit(sink.Passed && !timedOut ? 0 : 1);
                        return sink.Passed ? 0 : 1;
                    }
                }
            }
        }
Example #11
0
        static int Main(string[] args)
        {
            var nodeIndex        = CommandLine.GetInt32("multinode.index");
            var assemblyFileName = CommandLine.GetProperty("multinode.test-assembly");
            var typeName         = CommandLine.GetProperty("multinode.test-class");
            var testName         = CommandLine.GetProperty("multinode.test-method");
            var displayName      = testName;

            var listenAddress  = IPAddress.Parse(CommandLine.GetProperty("multinode.listen-address"));
            var listenPort     = CommandLine.GetInt32("multinode.listen-port");
            var listenEndpoint = new IPEndPoint(listenAddress, listenPort);

            var system    = ActorSystem.Create("NoteTestRunner-" + nodeIndex);
            var tcpClient = _logger = system.ActorOf <RunnerTcpClient>();

            system.Tcp().Tell(new Tcp.Connect(listenEndpoint), tcpClient);

            Thread.Sleep(TimeSpan.FromSeconds(10));

            using (var controller = new XunitFrontController(assemblyFileName))
            {
                /* need to pass in just the assembly name to Discovery, not the full path
                 * i.e. "Akka.Cluster.Tests.MultiNode.dll"
                 * not "bin/Release/Akka.Cluster.Tests.MultiNode.dll" - this will cause
                 * the Discovery class to actually not find any indivudal specs to run
                 */
                var assemblyName = Path.GetFileName(assemblyFileName);
                Console.WriteLine("Running specs for {0} [{1}]", assemblyName, assemblyFileName);
                using (var discovery = new Discovery(assemblyName, typeName))
                {
                    using (var sink = new Sink(nodeIndex, tcpClient))
                    {
                        Thread.Sleep(10000);
                        try
                        {
                            controller.Find(true, discovery, TestFrameworkOptions.ForDiscovery());
                            discovery.Finished.WaitOne();
                            controller.RunTests(discovery.TestCases, sink, TestFrameworkOptions.ForExecution());
                        }
                        catch (AggregateException ex)
                        {
                            var specFail = new SpecFail(nodeIndex, displayName);
                            specFail.FailureExceptionTypes.Add(ex.GetType().ToString());
                            specFail.FailureMessages.Add(ex.Message);
                            specFail.FailureStackTraces.Add(ex.StackTrace);
                            foreach (var innerEx in ex.Flatten().InnerExceptions)
                            {
                                specFail.FailureExceptionTypes.Add(innerEx.GetType().ToString());
                                specFail.FailureMessages.Add(innerEx.Message);
                                specFail.FailureStackTraces.Add(innerEx.StackTrace);
                            }
                            _logger.Tell(specFail.ToString());
                            Console.WriteLine(specFail);

                            //make sure message is send over the wire
                            FlushLogMessages();
                            Environment.Exit(1); //signal failure
                            return(1);
                        }
                        catch (Exception ex)
                        {
                            var specFail = new SpecFail(nodeIndex, displayName);
                            specFail.FailureExceptionTypes.Add(ex.GetType().ToString());
                            specFail.FailureMessages.Add(ex.Message);
                            specFail.FailureStackTraces.Add(ex.StackTrace);
                            _logger.Tell(specFail.ToString());
                            Console.WriteLine(specFail);

                            //make sure message is send over the wire
                            FlushLogMessages();
                            Environment.Exit(1); //signal failure
                            return(1);
                        }

                        var timedOut = false;
                        if (!sink.Finished.WaitOne(MaxProcessWaitTimeout)) //timed out
                        {
                            var line = string.Format("Timed out while waiting for test to complete after {0} ms",
                                                     MaxProcessWaitTimeout);
                            _logger.Tell(line);
                            Console.WriteLine(line);
                            timedOut = true;
                        }

                        FlushLogMessages();
                        system.Shutdown();
                        system.AwaitTermination();

                        Environment.Exit(sink.Passed && !timedOut ? 0 : 1);
                        return(sink.Passed ? 0 : 1);
                    }
                }
            }
        }