public void ShouldKillTheSpawnedProcess()
        {
            var winswId     = "myAppWithRunaway";
            var extensionId = "runawayProcessKiller";
            var tmpDir      = FilesystemTestHelper.CreateTmpDirectory();

            // Prepare the env var
            String varName = WinSWSystem.ENVVAR_NAME_SERVICE_ID;
            var    env     = new Dictionary <string, string>();

            env.Add("varName", winswId);

            // Spawn the test process
            var scriptFile = Path.Combine(tmpDir, "dosleep.bat");
            var envFile    = Path.Combine(tmpDir, "env.txt");

            File.WriteAllText(scriptFile, "set > " + envFile + "\nsleep 100500");
            Process proc = new Process();
            var     ps   = proc.StartInfo;

            ps.FileName = scriptFile;
            ProcessHelper.StartProcessAndCallbackForExit(proc, envVars: env);

            try
            {
                // Generate extension and ensure that the roundtrip is correct
                //TODO: checkWinSWEnvironmentVariable should be true, but it does not work due to proc.StartInfo.EnvironmentVariables
                var pidfile = Path.Combine(tmpDir, "process.pid");
                var sd      = ConfigXmlBuilder.create(id: winswId)
                              .WithRunawayProcessKiller(new RunawayProcessKillerExtension(pidfile, checkWinSWEnvironmentVariable: false), extensionId)
                              .ToServiceDescriptor();
                WinSWExtensionManager manager = new WinSWExtensionManager(sd);
                manager.LoadExtensions();
                var extension = manager.Extensions[extensionId] as RunawayProcessKillerExtension;
                Assert.IsNotNull(extension, "RunawayProcessKillerExtension should be loaded");
                Assert.AreEqual(pidfile, extension.Pidfile, "PidFile should have been retained during the config roundtrip");

                // Inject PID
                File.WriteAllText(pidfile, proc.Id.ToString());

                // Try to terminate
                Assert.That(!proc.HasExited, "Process " + proc + " has exited before the RunawayProcessKiller extension invocation");
                extension.OnWrapperStarted();
                Assert.That(proc.HasExited, "Process " + proc + " should have been terminated by RunawayProcessKiller");
            }
            finally
            {
                if (!proc.HasExited)
                {
                    Console.Error.WriteLine("Test: Killing runaway process with ID=" + proc.Id);
                    ProcessHelper.StopProcessAndChildren(proc.Id, TimeSpan.FromMilliseconds(100), false);
                    if (!proc.HasExited)
                    {
                        // The test is failed here anyway, but we add additional diagnostics info
                        Console.Error.WriteLine("Test: ProcessHelper failed to properly terminate process with ID=" + proc.Id);
                    }
                }
            }
        }
Example #2
0
        public void VerifyWaitHint_FullXML()
        {
            var sd = ConfigXmlBuilder.create()
                     .WithTag("waithint", "20 min")
                     .ToServiceDescriptor(true);

            Assert.That(sd.WaitHint, Is.EqualTo(TimeSpan.FromMinutes(20)));
        }
Example #3
0
        private void AssertInitializationFails(Download download, string expectedMessagePart = null)
        {
            var sd = ConfigXmlBuilder.create()
                     .WithDownload(download)
                     .ToServiceDescriptor(true);

            Assert.That(() => this.GetSingleEntry(sd), Throws.TypeOf <InvalidDataException>().With.Message.StartsWith(expectedMessagePart));
        }
Example #4
0
        public void VerifyWaitHint_XMLWithoutVersionAndComment()
        {
            var sd = ConfigXmlBuilder.create(xmlComment: null, printXMLVersion: false)
                     .WithTag("waithint", "23 min")
                     .ToServiceDescriptor(true);

            Assert.That(sd.WaitHint, Is.EqualTo(TimeSpan.FromMinutes(23)));
        }
Example #5
0
        public void Arguments_NewParam_Single()
        {
            var sd = ConfigXmlBuilder.create()
                     .WithTag("argument", "--arg1=2")
                     .ToServiceDescriptor(true);

            Assert.That(sd.Arguments, Is.EqualTo(" --arg1=2"));
        }
Example #6
0
        private void AssertInitializationFails(Download download, string expectedMessagePart = null, Type expectedExceptionType = null)
        {
            var sd = ConfigXmlBuilder.create()
                     .WithDownload(download)
                     .ToServiceDescriptor(true);

            ExceptionHelper.AssertFails(expectedMessagePart, expectedExceptionType ?? typeof(InvalidDataException), () => _ = GetSingleEntry(sd));
        }
Example #7
0
        public void Should_Fail_On_Unsupported_AuthType()
        {
            // TODO: will need refactoring once all fields are being parsed on startup
            var sd = ConfigXmlBuilder.create()
                     .WithRawEntry("<download from=\"http://www.nosuchhostexists.foo.myorg/foo.xml\" to=\"%BASE%\\foo.xml\" auth=\"digest\"/>")
                     .ToServiceDescriptor(true);

            Assert.That(() => this.GetSingleEntry(sd), Throws.TypeOf <InvalidDataException>().With.Message.StartsWith("Cannot parse <auth> Enum value from string 'digest'"));
        }
Example #8
0
        public void AuthType_Is_CaseInsensitive(string authType)
        {
            var sd = ConfigXmlBuilder.create()
                     .WithRawEntry("<download from=\"http://www.nosuchhostexists.foo.myorg/foo.xml\" to=\"%BASE%\\foo.xml\" auth=\"" + authType + "\"/>")
                     .ToServiceDescriptor(true);
            var loaded = this.GetSingleEntry(sd);

            Assert.That(loaded.Auth, Is.EqualTo(Download.AuthType.Sspi));
        }
Example #9
0
        public void Should_Fail_On_Unsupported_AuthType()
        {
            // TODO: will need refactoring once all fields are being parsed on startup
            var sd = ConfigXmlBuilder.create()
                     .WithRawEntry("<download from=\"http://www.nosuchhostexists.foo.myorg/foo.xml\" to=\"%BASE%\\foo.xml\" auth=\"digest\"/>")
                     .ToServiceDescriptor(true);

            ExceptionHelper.AssertFails("Cannot parse <auth> Enum value from string 'digest'", typeof(InvalidDataException), () => _ = GetSingleEntry(sd));
        }
Example #10
0
        public void Download_FailOnError_Undefined()
        {
            var sd = ConfigXmlBuilder.create()
                     .WithRawEntry("<download from=\"http://www.nosuchhostexists.foo.myorg/foo.xml\" to=\"%BASE%\\foo.xml\"/>")
                     .ToServiceDescriptor(true);

            var loaded = this.GetSingleEntry(sd);

            Assert.That(loaded.FailOnError, Is.False);
        }
Example #11
0
        public void Arguments_Bothparam_Priorities()
        {
            var sd = ConfigXmlBuilder.create()
                     .WithTag("arguments", "--arg1=2 --arg2=3")
                     .WithTag("argument", "--arg2=123")
                     .WithTag("argument", "--arg3=null")
                     .ToServiceDescriptor(true);

            Assert.That(sd.Arguments, Is.EqualTo(" --arg2=123 --arg3=null"));
        }
Example #12
0
        public void Arguments_NewParam_MultipleArgs()
        {
            var sd = ConfigXmlBuilder.create()
                     .WithTag("argument", "--arg1=2")
                     .WithTag("argument", "--arg2=123")
                     .WithTag("argument", "--arg3=null")
                     .ToServiceDescriptor(true);

            Assert.That(sd.Arguments, Is.EqualTo(" --arg1=2 --arg2=123 --arg3=null"));
        }
Example #13
0
        public void ShouldKillTheSpawnedProcess()
        {
            Assert.Ignore();

            var winswId     = "myAppWithRunaway";
            var extensionId = "runawayProcessKiller";
            var tmpDir      = FilesystemTestHelper.CreateTmpDirectory();

            // Spawn the test process
            Process proc = new Process();
            var     ps   = proc.StartInfo;

            ps.FileName               = "cmd.exe";
            ps.Arguments              = "/c pause";
            ps.UseShellExecute        = false;
            ps.RedirectStandardOutput = true;
            ps.EnvironmentVariables[WinSWSystem.ENVVAR_NAME_SERVICE_ID] = winswId;
            proc.Start();

            try
            {
                // Generate extension and ensure that the roundtrip is correct
                var pidfile = Path.Combine(tmpDir, "process.pid");
                var sd      = ConfigXmlBuilder.create(id: winswId)
                              .WithRunawayProcessKiller(new RunawayProcessKillerExtension(pidfile), extensionId)
                              .ToServiceDescriptor();
                WinSWExtensionManager manager = new WinSWExtensionManager(sd);
                manager.LoadExtensions();
                var extension = manager.Extensions[extensionId] as RunawayProcessKillerExtension;
                Assert.IsNotNull(extension, "RunawayProcessKillerExtension should be loaded");
                Assert.AreEqual(pidfile, extension.Pidfile, "PidFile should have been retained during the config roundtrip");

                // Inject PID
                File.WriteAllText(pidfile, proc.Id.ToString());

                // Try to terminate
                Assert.That(!proc.HasExited, "Process " + proc + " has exited before the RunawayProcessKiller extension invocation");
                _ = proc.StandardOutput.Read();
                extension.OnWrapperStarted();
                Assert.That(proc.HasExited, "Process " + proc + " should have been terminated by RunawayProcessKiller");
            }
            finally
            {
                if (!proc.HasExited)
                {
                    Console.Error.WriteLine("Test: Killing runaway process with ID=" + proc.Id);
                    ProcessHelper.StopProcessAndChildren(proc.Id, TimeSpan.FromMilliseconds(100), false);
                    if (!proc.HasExited)
                    {
                        // The test is failed here anyway, but we add additional diagnostics info
                        Console.Error.WriteLine("Test: ProcessHelper failed to properly terminate process with ID=" + proc.Id);
                    }
                }
            }
        }
Example #14
0
        public void DelayedStart_RoundTrip(bool enabled)
        {
            var bldr = ConfigXmlBuilder.create();

            if (enabled)
            {
                bldr = bldr.WithDelayedAutoStart();
            }
            var sd = bldr.ToServiceDescriptor();

            Assert.That(sd.DelayedAutoStart, Is.EqualTo(enabled));
        }
Example #15
0
        public void Download_FailOnError(bool failOnError)
        {
            var d = new Download(From, To, failOnError);

            var sd = ConfigXmlBuilder.create()
                     .WithDownload(d)
                     .ToServiceDescriptor(true);

            var loaded = this.GetSingleEntry(sd);

            Assert.That(loaded.From, Is.EqualTo(From));
            Assert.That(loaded.To, Is.EqualTo(To));
            Assert.That(loaded.FailOnError, Is.EqualTo(failOnError), "Unexpected FailOnError value");
        }
Example #16
0
        public void Roundtrip_SSPI()
        {
            // Roundtrip data
            var d  = new Download(From, To, false, Download.AuthType.Sspi);
            var sd = ConfigXmlBuilder.create()
                     .WithDownload(d)
                     .ToServiceDescriptor(true);
            var loaded = this.GetSingleEntry(sd);

            // Check default values
            Assert.That(loaded.FailOnError, Is.False);
            Assert.That(loaded.Auth, Is.EqualTo(Download.AuthType.Sspi));
            Assert.That(loaded.Username, Is.Null);
            Assert.That(loaded.Password, Is.Null);
            Assert.That(loaded.UnsecureAuth, Is.False);
        }
Example #17
0
        public void Roundtrip_BasicAuth()
        {
            // Roundtrip data
            var d  = new Download(From, To, true, Download.AuthType.Basic, "aUser", "aPassword", true);
            var sd = ConfigXmlBuilder.create()
                     .WithDownload(d)
                     .ToServiceDescriptor(true);
            var loaded = this.GetSingleEntry(sd);

            // Check default values
            Assert.That(loaded.FailOnError, Is.True);
            Assert.That(loaded.Auth, Is.EqualTo(Download.AuthType.Basic));
            Assert.That(loaded.Username, Is.EqualTo("aUser"));
            Assert.That(loaded.Password, Is.EqualTo("aPassword"));
            Assert.That(loaded.UnsecureAuth, Is.True);
        }
Example #18
0
        public void Arguments_LegacyParam()
        {
            var sd = ConfigXmlBuilder.create().WithTag("arguments", "arg").ToServiceDescriptor(true);

            Assert.That(sd.Arguments, Is.EqualTo("arg"));
        }
Example #19
0
        public void VerifyStopTimeout()
        {
            var sd = ConfigXmlBuilder.create().WithTag("stoptimeout", "35 secs").ToServiceDescriptor(true);

            Assert.That(sd.StopTimeout, Is.EqualTo(TimeSpan.FromSeconds(35)));
        }
Example #20
0
        public void VerifyResetFailureAfter()
        {
            var sd = ConfigXmlBuilder.create().WithTag("resetfailure", "75 sec").ToServiceDescriptor(true);

            Assert.That(sd.ResetFailureAfter, Is.EqualTo(TimeSpan.FromSeconds(75)));
        }
Example #21
0
        public void VerifySleepTime()
        {
            var sd = ConfigXmlBuilder.create().WithTag("sleeptime", "3 hrs").ToServiceDescriptor(true);

            Assert.That(sd.SleepTime, Is.EqualTo(TimeSpan.FromHours(3)));
        }