diff --git a/src/WinSW.Tests/CommandLineTests.cs b/src/WinSW.Tests/CommandLineTests.cs index d8eb883..ae2c6f1 100644 --- a/src/WinSW.Tests/CommandLineTests.cs +++ b/src/WinSW.Tests/CommandLineTests.cs @@ -17,15 +17,7 @@ namespace WinSW.Tests try { - _ = Helper.Test(new[] { "install", config.FullPath }, config); - - using var controller = new ServiceController(Helper.Name); - Assert.Equal(Helper.DisplayName, controller.DisplayName); - Assert.False(controller.CanStop); - Assert.False(controller.CanShutdown); - Assert.False(controller.CanPauseAndContinue); - Assert.Equal(ServiceControllerStatus.Stopped, controller.Status); - Assert.Equal(ServiceType.Win32OwnProcess, controller.ServiceType); + using var controller = CommandLineTestsUtils.ExecuteInstall(config); #if NET InterProcessCodeCoverageSession session = null; @@ -33,29 +25,11 @@ namespace WinSW.Tests { try { - _ = Helper.Test(new[] { "start", config.FullPath }, config); - controller.Refresh(); - Assert.Equal(ServiceControllerStatus.Running, controller.Status); - Assert.True(controller.CanStop); - - Assert.EndsWith( - ServiceMessages.StartedSuccessfully + Environment.NewLine, - File.ReadAllText(Path.ChangeExtension(config.FullPath, ".wrapper.log"))); - - if (Environment.GetEnvironmentVariable("System.DefinitionId") != null) - { - session = new InterProcessCodeCoverageSession(Helper.Name); - } + session = CommandLineTestsUtils.ExecuteStart(config, controller); } finally { - _ = Helper.Test(new[] { "stop", config.FullPath }, config); - controller.Refresh(); - Assert.Equal(ServiceControllerStatus.Stopped, controller.Status); - - Assert.EndsWith( - ServiceMessages.StoppedSuccessfully + Environment.NewLine, - File.ReadAllText(Path.ChangeExtension(config.FullPath, ".wrapper.log"))); + CommandLineTestsUtils.ExecuteStop(config, controller); } } finally @@ -66,7 +40,7 @@ namespace WinSW.Tests } finally { - _ = Helper.Test(new[] { "uninstall", config.FullPath }, config); + CommandLineTestsUtils.ExecuteUninstall(config); } } @@ -117,5 +91,125 @@ namespace WinSW.Tests File.Delete(outputPath); } } + + [ElevatedFact] + public void RestartConsoleAppTest() + { + using var config = Helper.TestXmlServiceConfig.FromXml(Helper.SeedXml); + + try + { + using var controller = CommandLineTestsUtils.ExecuteInstall(config); + +#if NET + InterProcessCodeCoverageSession session = null; + try + { + try + { + session = CommandLineTestsUtils.ExecuteStart(config, controller); + session = CommandLineTestsUtils.ExecuteStart(config, controller, true); + } + finally + { + CommandLineTestsUtils.ExecuteStop(config, controller); + } + } + finally + { + session?.Wait(); + } +#endif + } + finally + { + CommandLineTestsUtils.ExecuteUninstall(config); + } + } + + [ElevatedFact] + public void StatusConsoleAppBeforeAndAfterStartTest() + { + using var config = Helper.TestXmlServiceConfig.FromXml(Helper.SeedXml); + + try + { + using var controller = CommandLineTestsUtils.ExecuteInstall(config); + +#if NET + InterProcessCodeCoverageSession session = null; + try + { + try + { + Assert.Contains("Inactive (stopped)", CommandLineTestsUtils.ExecuteStatus(config)); + + session = CommandLineTestsUtils.ExecuteStart(config, controller); + + Assert.Contains("Active (running)", CommandLineTestsUtils.ExecuteStatus(config)); + } + finally + { + if (controller.Status == ServiceControllerStatus.Running) + { + CommandLineTestsUtils.ExecuteStop(config, controller); + } + + Assert.Contains("Inactive (stopped)", CommandLineTestsUtils.ExecuteStatus(config)); + } + } + finally + { + session?.Wait(); + } +#endif + } + finally + { + CommandLineTestsUtils.ExecuteUninstall(config); + } + } + + [ElevatedFact] + public void RefreshConsoleAppTest() + { + using var config = Helper.TestXmlServiceConfig.FromXml(Helper.SeedXml); + + try + { + using var controller = CommandLineTestsUtils.ExecuteInstall(config); + + Assert.Equal(Helper.DisplayName, controller.DisplayName); + + var newXml = Helper.CreateSeedXml("This is a test app"); + using var newConfig = Helper.TestXmlServiceConfig.FromXml(newXml, "RefreshConsoleAppTest_Bis"); + using var refreshController = CommandLineTestsUtils.ExecuteRefresh(newConfig); + Assert.Equal("This is a test app", refreshController.DisplayName); + } + finally + { + CommandLineTestsUtils.ExecuteUninstall(config); + } + } + + [ElevatedFact] + public void DevListConsoleAppNotRunTest() + { + using var config = Helper.TestXmlServiceConfig.FromXml(Helper.SeedXml); + + try + { + using var controller = CommandLineTestsUtils.ExecuteInstall(config); + + Program.TestExecutablePath = Layout.WinSWExe; + + Assert.Contains($"{config.DisplayName} ({config.Name})", CommandLineTestsUtils.ExecuteDevList()); + } + finally + { + Program.TestExecutablePath = null; + CommandLineTestsUtils.ExecuteUninstall(config); + } + } } } diff --git a/src/WinSW.Tests/LogAppenderTests.cs b/src/WinSW.Tests/LogAppenderTests.cs index f6887ae..ecaa716 100644 --- a/src/WinSW.Tests/LogAppenderTests.cs +++ b/src/WinSW.Tests/LogAppenderTests.cs @@ -1,6 +1,7 @@ using System.IO; using System.Linq; using System.Runtime.CompilerServices; +using WinSW.Tests.Util; using Xunit; using static System.IO.File; @@ -126,8 +127,7 @@ namespace WinSW.Tests internal static TestData Create([CallerMemberName] string name = null) { - string path = Path.Combine(Path.GetTempPath(), name); - _ = Directory.CreateDirectory(path); + string path = FilesystemTestHelper.CreateTmpDirectory(name); return new(name, path); } diff --git a/src/WinSW.Tests/SharedDirectoryMapperTests.cs b/src/WinSW.Tests/SharedDirectoryMapperTests.cs index f712834..f80c2e9 100644 --- a/src/WinSW.Tests/SharedDirectoryMapperTests.cs +++ b/src/WinSW.Tests/SharedDirectoryMapperTests.cs @@ -3,6 +3,7 @@ using System; using System.IO; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; +using WinSW.Tests.Util; using Xunit; namespace WinSW.Tests.Extensions @@ -70,8 +71,7 @@ namespace WinSW.Tests.Extensions internal static TestData Create([CallerMemberName] string name = null) { - string path = Path.Combine(Path.GetTempPath(), name); - _ = Directory.CreateDirectory(path); + string path = FilesystemTestHelper.CreateTmpDirectory(name); try { diff --git a/src/WinSW.Tests/Util/CommandLineTestHelper.cs b/src/WinSW.Tests/Util/CommandLineTestHelper.cs index 334fb4a..68e49a3 100644 --- a/src/WinSW.Tests/Util/CommandLineTestHelper.cs +++ b/src/WinSW.Tests/Util/CommandLineTestHelper.cs @@ -1,6 +1,7 @@ using System; using System.IO; using System.Runtime.CompilerServices; +using System.ServiceProcess; using System.Xml; using Xunit; @@ -14,10 +15,12 @@ namespace WinSW.Tests.Util public const string Name = "WinSW.Tests"; public const string DisplayName = "WinSW Test Service"; - internal static readonly string SeedXml = + internal static readonly string SeedXml = CreateSeedXml(DisplayName); + + internal static string CreateSeedXml(in string displayName) => $@" {Name} - {DisplayName} + {displayName} cmd.exe /c timeout /t -1 /nobreak "; @@ -105,23 +108,22 @@ $@" internal TestXmlServiceConfig(XmlDocument document, string name) : base(document) { - string directory = this.directory = Path.Combine(Path.GetTempPath(), name); - _ = Directory.CreateDirectory(directory); + string folder = this.directory = FilesystemTestHelper.CreateTmpDirectory(name); try { - string path = this.FullPath = Path.Combine(directory, "config.xml"); + string path = this.FullPath = Path.Combine(folder, "config.xml"); using (var file = File.CreateText(path)) { file.Write(SeedXml); } this.BaseName = name; - this.BasePath = Path.Combine(directory, name); + this.BasePath = Path.Combine(folder, name); } catch { - Directory.Delete(directory, true); + Directory.Delete(folder, true); throw; } } diff --git a/src/WinSW.Tests/Util/CommandLineTestsUtils.cs b/src/WinSW.Tests/Util/CommandLineTestsUtils.cs new file mode 100644 index 0000000..3df32a4 --- /dev/null +++ b/src/WinSW.Tests/Util/CommandLineTestsUtils.cs @@ -0,0 +1,70 @@ +using System; +using System.IO; +using System.ServiceProcess; +using Xunit; +using Helper = WinSW.Tests.Util.CommandLineTestHelper; + +namespace WinSW.Tests.Util +{ + internal static class CommandLineTestsUtils + { + internal static ServiceController ExecuteInstall(Helper.TestXmlServiceConfig config, string expectedName = Helper.DisplayName) + { + Helper.Test(["install", config.FullPath], config); + var controller = new ServiceController(Helper.Name); + Assert.Equal(expectedName, controller.DisplayName); + Assert.False(controller.CanStop); + Assert.False(controller.CanShutdown); + Assert.False(controller.CanPauseAndContinue); + Assert.Equal(ServiceControllerStatus.Stopped, controller.Status); + Assert.Equal(ServiceType.Win32OwnProcess, controller.ServiceType); + return controller; + } + + internal static void ExecuteUninstall(Helper.TestXmlServiceConfig config) => + Helper.Test(["uninstall", config.FullPath], config); + + internal static InterProcessCodeCoverageSession ExecuteStart(Helper.TestXmlServiceConfig config, ServiceController controller, bool isRestart = false) + { + var command = isRestart ? "restart" : "start"; + Helper.Test([command, config.FullPath], config); + controller.Refresh(); + Assert.Equal(ServiceControllerStatus.Running, controller.Status); + Assert.True(controller.CanStop); + + var wrapperOutput = File.ReadAllText(Path.ChangeExtension(config.FullPath, ".wrapper.log")); + Assert.EndsWith(ServiceMessages.StartedSuccessfully + Environment.NewLine, wrapperOutput); + + if (Environment.GetEnvironmentVariable("System.DefinitionId") != null) + { + return new InterProcessCodeCoverageSession(Helper.Name); + } + + return null; + } + + internal static void ExecuteStop(Helper.TestXmlServiceConfig config, ServiceController controller) + { + Helper.Test(["stop", config.FullPath], config); + controller.Refresh(); + Assert.Equal(ServiceControllerStatus.Stopped, controller.Status); + + var wrapperOutput = File.ReadAllText(Path.ChangeExtension(config.FullPath, ".wrapper.log")); + Assert.EndsWith(ServiceMessages.StoppedSuccessfully + Environment.NewLine, wrapperOutput); + } + + internal static string ExecuteStatus(Helper.TestXmlServiceConfig config) => + Helper.Test(["status", config.FullPath], config); + + internal static ServiceController ExecuteRefresh(Helper.TestXmlServiceConfig config) + { + Helper.Test(["refresh", config.FullPath], config); + var controller = new ServiceController(config.Name); + Assert.Equal(config.DisplayName, controller.DisplayName); + return controller; + } + + internal static string ExecuteDevList() => + Helper.Test(["dev", "list"]); + } +} diff --git a/src/WinSW.Tests/Util/FilesystemTestHelper.cs b/src/WinSW.Tests/Util/FilesystemTestHelper.cs index b81fc46..6533e39 100644 --- a/src/WinSW.Tests/Util/FilesystemTestHelper.cs +++ b/src/WinSW.Tests/Util/FilesystemTestHelper.cs @@ -2,7 +2,7 @@ namespace WinSW.Tests.Util { - internal class FilesystemTestHelper + internal static class FilesystemTestHelper { /// /// Creates a temporary directory for testing. diff --git a/src/WinSW.Tests/WinSW.Tests.csproj b/src/WinSW.Tests/WinSW.Tests.csproj index 95f40f1..f675c7f 100644 --- a/src/WinSW.Tests/WinSW.Tests.csproj +++ b/src/WinSW.Tests/WinSW.Tests.csproj @@ -6,18 +6,26 @@ - + runtime; build; native; contentfiles; analyzers; buildtransitive all - + all runtime; build; native; contentfiles; analyzers - + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + runtime; build; native; contentfiles; analyzers; buildtransitive all diff --git a/src/WinSW/WinSW.csproj b/src/WinSW/WinSW.csproj index 19bdada..43346aa 100644 --- a/src/WinSW/WinSW.csproj +++ b/src/WinSW/WinSW.csproj @@ -15,7 +15,6 @@ - true partial false false @@ -23,6 +22,7 @@ + true true