예제 #1
0
        public void TestFailureDetection1()
        {
            Failure?failure = null;
            var     handler = new Mock <IFailureHandler>();

            handler.Setup(x => x.OnFailure(It.IsAny <Failure>()))
            .Callback((Failure x) => failure = x);

            using (var silo = new SharpRemote.Hosting.OutOfProcessSilo(failureHandler: handler.Object))
            {
                silo.Start();

                var proxy = silo.CreateGrain <IVoidMethodNoParameters>(typeof(KillsProcess));
                new Action(proxy.Do)
                .ShouldThrow <ConnectionLostException>(
                    "Because the host process is lost while the method is invoked and therefore the connection to the host process was lost and is the reason for the method to not execute properly");

                WaitFor(() => silo.HasProcessFailed, TimeSpan.FromSeconds(1))
                .Should()
                .BeTrue(
                    "Because an aborted thread that is currently invoking a remote method call should cause SharpRemote to kill the host process and report failure");
                silo.IsProcessRunning.Should().BeFalse();

                WaitFor(() => failure != null, TimeSpan.FromSeconds(1))
                .Should().BeTrue("Because the IFailureHandler should've been notified in time");

                (failure == Failure.ConnectionFailure ||
                 failure == Failure.HostProcessExited).Should().BeTrue();
            }
        }
예제 #2
0
        public void TestFailureDetection4()
        {
            using (var handle = new ManualResetEvent(false))
            {
                Resolution?resolution = null;

                var handler = new Mock <IFailureHandler>();
                handler.Setup(x => x.OnResolutionFinished(It.IsAny <Failure>(), It.IsAny <Decision>(), It.IsAny <Resolution>()))
                .Callback((Failure f, Decision d, Resolution r) =>
                {
                    resolution = r;
                    handle.Set();
                });

                using (var silo = new SharpRemote.Hosting.OutOfProcessSilo(failureHandler: handler.Object))
                {
                    silo.Start();
                    IVoidMethodNoParameters proxy = silo.CreateGrain <IVoidMethodNoParameters, CausesAccessViolation>();

                    new Action(proxy.Do).ShouldThrow <ConnectionLostException>();

                    handle.WaitOne(TimeSpan.FromSeconds(5)).Should().BeTrue();
                    resolution.Should().Be(Resolution.Stopped);
                }
            }
        }
예제 #3
0
        public void TestFailureDetection2()
        {
            Failure?   failure    = null;
            Decision?  decision   = null;
            Resolution?resolution = null;

            var handler = new Mock <IFailureHandler>();

            handler.Setup(x => x.OnResolutionFinished(It.IsAny <Failure>(), It.IsAny <Decision>(), It.IsAny <Resolution>()))
            .Callback((Failure f, Decision d, Resolution r) =>
            {
                failure    = f;
                decision   = d;
                resolution = r;
            });

            using (var silo = new SharpRemote.Hosting.OutOfProcessSilo(failureHandler: handler.Object))
            {
                silo.Start();

                var proxy = silo.CreateGrain <IVoidMethodNoParameters>(typeof(AbortsThread));
                new Action(proxy.Do)
                .ShouldThrow <ConnectionLostException>(
                    "Because the host process is lost while the method is invoked and therefore the connection to the host process was lost and is the reason for the method to not execute properly");

                WaitFor(() => silo.HasProcessFailed, TimeSpan.FromSeconds(1))
                .Should().BeTrue("Because an unexpected exit of the host process counts as a failure");
                silo.IsProcessRunning.Should().BeFalse();

                WaitFor(() => resolution != null, TimeSpan.FromSeconds(1)).Should().BeTrue();
                (failure == Failure.ConnectionFailure ||
                 failure == Failure.HostProcessExited).Should().BeTrue("because we expected either a ConnectionFailure or HostProcessExited, but found: {0}", failure);
                resolution.Should().Be(Resolution.Stopped);
            }
        }
예제 #4
0
        public void TestPerformanceManyClients()
        {
            TimeSpan time = TimeSpan.FromSeconds(5);
            int      num  = 0;

            using (var silo = new SharpRemote.Hosting.OutOfProcessSilo())
            {
                silo.Start();

                IVoidMethod grain = silo.CreateGrain <IVoidMethod, DoesNothing>();
                // Optimization phase
                const int numOptPasses = 100;

                for (int i = 0; i < numOptPasses; ++i)
                {
                    grain.DoStuff();
                }

                // Measurement phase
                const int numClients = 16;
                var       clients    = new Thread[numClients];
                for (int clientIndex = 0; clientIndex < numClients; ++clientIndex)
                {
                    clients[clientIndex] = new Thread(() =>
                    {
                        var watch           = new Stopwatch();
                        const int batchSize = 64;
                        watch.Start();
                        while (watch.Elapsed < time)
                        {
                            for (int i = 0; i < batchSize; ++i)
                            {
                                grain.DoStuff();
                            }
                            num += batchSize;
                        }
                        watch.Stop();
                    });
                    clients[clientIndex].Start();
                }


                foreach (Thread thread in clients)
                {
                    thread.Join();
                }

                int    numSeconds = 5;
                double ops        = 1.0 * num / numSeconds;
                Console.WriteLine("Total calls: {0}", num);
                Console.WriteLine("OP/s: {0:F2}k/s", ops / 1000);
                Console.WriteLine("Sent: {0}, {1}/s", FormatSize(silo.NumBytesSent), FormatSize(silo.NumBytesSent / numSeconds));
                Console.WriteLine("Received: {0}, {1}/s", FormatSize(silo.NumBytesReceived),
                                  FormatSize(silo.NumBytesReceived / numSeconds));
                Console.WriteLine("Latency: {0}ns", (int)silo.RoundtripTime.Ticks * 100);
            }
        }
예제 #5
0
        public void TestFailureDetection9()
        {
            using (var handle = new ManualResetEvent(false))
            {
                Resolution?resolution = null;

                var handler = new Mock <IFailureHandler>();
                handler.Setup(x => x.OnResolutionFinished(It.IsAny <Failure>(), It.IsAny <Decision>(), It.IsAny <Resolution>()))
                .Callback((Failure f, Decision d, Resolution r) =>
                {
                    resolution = r;
                    handle.Set();
                });

                var settings = new PostMortemSettings
                {
                    CollectMinidumps     = true,
                    SuppressErrorWindows = true,
                    HandleCrtPureVirtualFunctionCalls = true,
#if DEBUG
                    RuntimeVersions = CRuntimeVersions._110 | CRuntimeVersions.Debug,
#else
                    RuntimeVersions = CRuntimeVersions._110 | CRuntimeVersions.Release,
#endif
                    NumMinidumpsRetained = 1,
                    MinidumpFolder       = Path.Combine(Path.GetTempPath(), "SharpRemote", "dumps"),
                    MinidumpName         = "Host"
                };

                if (Directory.Exists(settings.MinidumpFolder))
                {
                    Directory.Delete(settings.MinidumpFolder, true);
                }

                using (var silo = new SharpRemote.Hosting.OutOfProcessSilo(postMortemSettings: settings))
                {
                    silo.Start();
                    IVoidMethodNoParameters proxy = silo.CreateGrain <IVoidMethodNoParameters, CausesPureVirtualFunctionCall>();

                    DateTime beforeFailure = DateTime.Now;
                    new Action(proxy.Do).ShouldThrow <ConnectionLostException>();
                    DateTime afterFailure = DateTime.Now;


                    // Not only should a failure have been detected, but a dump should've been created and stored
                    // on disk..

                    List <string> files = Directory.EnumerateFiles(settings.MinidumpFolder).ToList();
                    files.Count.Should().Be(1, "Because exactly one minidump should've been created");

                    var file = new FileInfo(files[0]);
                    file.Name.Should().EndWith(".dmp");
                    file.LastWriteTime.Should().BeOnOrAfter(beforeFailure);
                    file.LastWriteTime.Should().BeOnOrBefore(afterFailure);
                }
            }
        }
예제 #6
0
 public void TestGetProperty()
 {
     using (var silo = new SharpRemote.Hosting.OutOfProcessSilo())
     {
         silo.Start();
         IGetInt64Property grain = silo.CreateGrain <IGetInt64Property, ReturnsInt64Max>();
         grain.Value.Should().Be(Int64.MaxValue);
         grain.Value.Should().Be(Int64.MaxValue);
     }
 }
예제 #7
0
        public void TestCreateGrain1()
        {
            using (var silo = new SharpRemote.Hosting.OutOfProcessSilo())
            {
                silo.Start();

                var proxy = silo.CreateGrain <IGetStringProperty>(typeof(GetStringPropertyImplementation));
                proxy.Value.Should().Be("Foobar");
            }
        }
예제 #8
0
        public void TestFailureDetection3()
        {
            Failure?   failure1   = null;
            Failure?   failure2   = null;
            Decision?  decision   = null;
            Resolution?resolution = null;

            var handler = new Mock <IFailureHandler>();

            handler.Setup(x => x.OnFailure(It.IsAny <Failure>()))
            .Callback((Failure f) => failure1 = f);
            handler.Setup(x => x.OnResolutionFinished(It.IsAny <Failure>(), It.IsAny <Decision>(), It.IsAny <Resolution>()))
            .Callback((Failure f, Decision d, Resolution r) =>
            {
                failure2   = f;
                decision   = d;
                resolution = r;
            });

            var settings = new FailureSettings
            {
                HeartbeatSettings =
                {
                    ReportSkippedHeartbeatsAsFailureWithDebuggerAttached = true,
                    Interval                                             = TimeSpan.FromMilliseconds(100),
                    SkippedHeartbeatThreshold                            = 4
                }
            };

            using (var silo = new SharpRemote.Hosting.OutOfProcessSilo(failureSettings: settings, failureHandler: handler.Object))
            {
                silo.Start();

                var proxy = silo.CreateGrain <IVoidMethodNoParameters>(typeof(DeadlocksProcess));
                new Action(() =>
                {
                    Task.Factory.StartNew(proxy.Do, TaskCreationOptions.LongRunning)
                    .Wait(TimeSpan.FromSeconds(10))
                    .Should().BeTrue("Because the silo should've detected the deadlock in time");
                })
                .ShouldThrow <ConnectionLostException>(
                    "Because the host process is lost while the method is invoked and therefore the connection to the host process was lost and is the reason for the method to not execute properly");

                WaitFor(() => silo.HasProcessFailed, TimeSpan.FromSeconds(1))
                .Should()
                .BeTrue("Because the heartbeat mechanism should have detected that the endpoint doesn't respond anymore");
                WaitFor(() => failure1 != null, TimeSpan.FromSeconds(1)).Should().BeTrue();
                WaitFor(() => failure2 != null, TimeSpan.FromSeconds(1)).Should().BeTrue();

                silo.IsProcessRunning.Should().BeFalse();
                failure1.Should().Be(Failure.HeartbeatFailure);
                failure2.Should().Be(failure1);
                resolution.Should().Be(Resolution.Stopped);
            }
        }
예제 #9
0
        public void TestUseByReferenceTypeAfterRestart()
        {
            using (var logCollector = new LogCollector(new [] { "SharpRemote.EndPoints.ProxyStorage" }, new [] { Level.Debug }))
                using (var silo = new SharpRemote.Hosting.OutOfProcessSilo(failureHandler: new RestartOnFailureStrategy()))
                {
                    logCollector.AutoPrint(TestContext.Progress);
                    silo.Start();

                    var factory = silo.CreateGrain <IAdvancedFactory>(typeof(AdvancedFactory));
                    var proxyToByReferenceClass = factory.Create(typeof(ByReferenceClass));
                    var id = GetIdOf(proxyToByReferenceClass);
                    Console.WriteLine("ObjectId: {0}", id);

                    RestartHost(silo);

                    factory = silo.CreateGrain <IAdvancedFactory>(typeof(AdvancedFactory));
                    var proxyToObject = factory.Create(typeof(Handle));
                    var otherId       = GetIdOf(proxyToObject);
                    Console.WriteLine("ObjectId: {0}", otherId);
                }
        }
예제 #10
0
        public void TestStartStopStart2()
        {
            using (var silo = new SharpRemote.Hosting.OutOfProcessSilo())
            {
                silo.Start();

                var proxy = silo.CreateGrain <IReturnsType>(typeof(ReturnsTypeofString));
                proxy.Do().Should().Be <string>();

                silo.Stop();

                new Action(() => proxy.Do())
                .ShouldThrow <RemoteProcedureCallCanceledException>();
                new Action(() => silo.CreateGrain <IReturnsType>(typeof(ReturnsTypeofString)))
                .ShouldThrow <RemoteProcedureCallCanceledException>();

                silo.Start();

                var newProxy = silo.CreateGrain <IReturnsType>(typeof(ReturnsTypeofString));
                newProxy.Do().Should().Be <string>();
            }
        }
예제 #11
0
        public void TestPerformanceOneClientAsync()
        {
            TimeSpan time  = TimeSpan.FromSeconds(5);
            var      watch = new Stopwatch();
            int      num   = 0;

            using (var silo = new SharpRemote.Hosting.OutOfProcessSilo())
            {
                silo.Start();

                IReturnsTask grain = silo.CreateGrain <IReturnsTask, ReturnsTask>();

                // Optimization phase
                const int numOptPasses = 100;
                var       opts         = new Task[numOptPasses];
                for (int i = 0; i < numOptPasses; ++i)
                {
                    opts[i] = grain.DoStuff();
                }

                Task.WaitAll(opts);

                // Measurement phase

                const int batchSize = 1000;
                var       tasks     = new Task[batchSize];

                watch.Start();
                while (watch.Elapsed < time)
                {
                    for (int i = 0; i < batchSize; ++i)
                    {
                        tasks[i] = grain.DoStuff();
                    }
                    Task.WaitAll(tasks);

                    num += batchSize;
                }
                watch.Stop();

                double numSeconds = watch.Elapsed.TotalSeconds;
                double ops        = 1.0 * num / numSeconds;
                Console.WriteLine("Total calls: {0}", num);
                Console.WriteLine("OP/s: {0:F2}k/s", ops / 1000);
                Console.WriteLine("Sent: {0}, {1}/s", FormatSize(silo.NumBytesSent),
                                  FormatSize((long)(silo.NumBytesSent / numSeconds)));
                Console.WriteLine("Received: {0}, {1}/s", FormatSize(silo.NumBytesReceived),
                                  FormatSize((long)(silo.NumBytesReceived / numSeconds)));
                Console.WriteLine("Latency: {0}ns", (int)silo.RoundtripTime.Ticks * 100);
            }
        }
예제 #12
0
        public void TestCreate()
        {
            var customTypeResolver = new CustomTypeResolver1();

            using (var silo = new SharpRemote.Hosting.OutOfProcessSilo(codeGenerator: new CodeGenerator(customTypeResolver)))
            {
                silo.Start();

                customTypeResolver.GetTypeCalled.Should().Be(0);
                var grain = silo.CreateGrain <IReturnsType>(typeof(ReturnsTypeofString));
                customTypeResolver.GetTypeCalled.Should()
                .Be(0, "because the custom type resolver in this process didn't need to resolve anything yet");

                grain.Do().Should().Be <string>();
                customTypeResolver.GetTypeCalled.Should()
                .Be(1,
                    "Because the custom type resolver in this process should've been used to resolve typeof(string)");
            }
        }
예제 #13
0
        public void TestPerformanceOneClientSync()
        {
            TimeSpan time  = TimeSpan.FromSeconds(5);
            var      watch = new Stopwatch();
            int      num   = 0;

            using (var silo = new SharpRemote.Hosting.OutOfProcessSilo())
            {
                silo.Start();

                IVoidMethod grain = silo.CreateGrain <IVoidMethod, DoesNothing>();

                // Optimization phase
                for (int i = 0; i < 100; ++i)
                {
                    grain.DoStuff();
                }

                // Measurement phase
                watch.Start();
                while (watch.Elapsed < time)
                {
                    for (int i = 0; i < 100; ++i)
                    {
                        grain.DoStuff();
                    }
                    num += 100;
                }
                watch.Stop();

                double numSeconds = watch.Elapsed.TotalSeconds;
                double ops        = 1.0 * num / numSeconds;
                Console.WriteLine("Total calls: {0}", num);
                Console.WriteLine("OP/s: {0:F2}k/s", ops / 1000);
                Console.WriteLine("Sent: {0}, {1}/s", FormatSize(silo.NumBytesSent),
                                  FormatSize((long)(silo.NumBytesSent / numSeconds)));
                Console.WriteLine("Received: {0}, {1}/s", FormatSize(silo.NumBytesReceived),
                                  FormatSize((long)(silo.NumBytesReceived / numSeconds)));
                Console.WriteLine("Latency: {0}ns", (int)silo.RoundtripTime.Ticks * 100);
            }
        }
예제 #14
0
        public void TestFailureDetection8()
        {
            using (var handle = new ManualResetEvent(false))
            {
                Resolution?resolution = null;

                var handler = new Mock <IFailureHandler>();
                handler.Setup(x => x.OnResolutionFinished(It.IsAny <Failure>(), It.IsAny <Decision>(), It.IsAny <Resolution>()))
                .Callback((Failure f, Decision d, Resolution r) =>
                {
                    resolution = r;
                    handle.Set();
                });

                var settings = new PostMortemSettings
                {
                    SuppressErrorWindows = true,
                    HandleCrtPureVirtualFunctionCalls = true,
#if DEBUG
                    RuntimeVersions = CRuntimeVersions._110 | CRuntimeVersions.Debug,
#else
                    RuntimeVersions = CRuntimeVersions._110 | CRuntimeVersions.Release,
#endif
                };

                using (var silo = new SharpRemote.Hosting.OutOfProcessSilo(postMortemSettings: settings))
                {
                    silo.Start();
                    IVoidMethodNoParameters proxy = silo.CreateGrain <IVoidMethodNoParameters, CausesPureVirtualFunctionCall>();

                    Task task = Task.Factory.StartNew(() => { new Action(proxy.Do).ShouldThrow <ConnectionLostException>(); });
                    //task.Wait(TimeSpan.FromSeconds(5)).Should().BeTrue();
                    task.Wait();

                    handle.WaitOne(TimeSpan.FromSeconds(5)).Should().BeTrue();
                    resolution.Should().Be(Resolution.Stopped);
                }
            }
        }
예제 #15
0
        public void TestFailureDetection5()
        {
            var settings = new PostMortemSettings
            {
                CollectMinidumps       = true,
                SuppressErrorWindows   = true,
                HandleAccessViolations = true,
                NumMinidumpsRetained   = 1,
                MinidumpFolder         = Path.Combine(Path.GetTempPath(), "SharpRemote", "dumps"),
                MinidumpName           = "Host"
            };

            if (Directory.Exists(settings.MinidumpFolder))
            {
                Directory.Delete(settings.MinidumpFolder, true);
            }

            using (var silo = new SharpRemote.Hosting.OutOfProcessSilo(postMortemSettings: settings))
            {
                silo.Start();
                IVoidMethodNoParameters proxy = silo.CreateGrain <IVoidMethodNoParameters, CausesAccessViolation>();

                DateTime beforeFailure = DateTime.Now;
                new Action(proxy.Do).ShouldThrow <ConnectionLostException>();
                DateTime afterFailure = DateTime.Now;

                // Not only should a failure have been detected, but a dump should've been created and stored
                // on disk..

                List <string> files = Directory.EnumerateFiles(settings.MinidumpFolder).ToList();
                files.Count.Should().Be(1, "Because exactly one minidump should've been created");

                var file = new FileInfo(files[0]);
                file.Name.Should().EndWith(".dmp");
                file.LastWriteTime.Should().BeOnOrAfter(beforeFailure);
                file.LastWriteTime.Should().BeOnOrBefore(afterFailure);
            }
        }