pull/1098/merge
Alessio 2024-10-09 20:04:13 +00:00 committed by GitHub
commit 7c5cd0d2df
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 220 additions and 46 deletions

View File

@ -17,15 +17,7 @@ namespace WinSW.Tests
try try
{ {
_ = Helper.Test(new[] { "install", config.FullPath }, config); using var controller = CommandLineTestsUtils.ExecuteInstall(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);
#if NET #if NET
InterProcessCodeCoverageSession session = null; InterProcessCodeCoverageSession session = null;
@ -33,29 +25,11 @@ namespace WinSW.Tests
{ {
try try
{ {
_ = Helper.Test(new[] { "start", config.FullPath }, config); session = CommandLineTestsUtils.ExecuteStart(config, controller);
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);
}
} }
finally finally
{ {
_ = Helper.Test(new[] { "stop", config.FullPath }, config); CommandLineTestsUtils.ExecuteStop(config, controller);
controller.Refresh();
Assert.Equal(ServiceControllerStatus.Stopped, controller.Status);
Assert.EndsWith(
ServiceMessages.StoppedSuccessfully + Environment.NewLine,
File.ReadAllText(Path.ChangeExtension(config.FullPath, ".wrapper.log")));
} }
} }
finally finally
@ -66,7 +40,7 @@ namespace WinSW.Tests
} }
finally finally
{ {
_ = Helper.Test(new[] { "uninstall", config.FullPath }, config); CommandLineTestsUtils.ExecuteUninstall(config);
} }
} }
@ -117,5 +91,125 @@ namespace WinSW.Tests
File.Delete(outputPath); 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);
}
}
} }
} }

View File

@ -1,6 +1,7 @@
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
using WinSW.Tests.Util;
using Xunit; using Xunit;
using static System.IO.File; using static System.IO.File;
@ -126,8 +127,7 @@ namespace WinSW.Tests
internal static TestData Create([CallerMemberName] string name = null) internal static TestData Create([CallerMemberName] string name = null)
{ {
string path = Path.Combine(Path.GetTempPath(), name); string path = FilesystemTestHelper.CreateTmpDirectory(name);
_ = Directory.CreateDirectory(path);
return new(name, path); return new(name, path);
} }

View File

@ -3,6 +3,7 @@ using System;
using System.IO; using System.IO;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using WinSW.Tests.Util;
using Xunit; using Xunit;
namespace WinSW.Tests.Extensions namespace WinSW.Tests.Extensions
@ -70,8 +71,7 @@ namespace WinSW.Tests.Extensions
internal static TestData Create([CallerMemberName] string name = null) internal static TestData Create([CallerMemberName] string name = null)
{ {
string path = Path.Combine(Path.GetTempPath(), name); string path = FilesystemTestHelper.CreateTmpDirectory(name);
_ = Directory.CreateDirectory(path);
try try
{ {

View File

@ -1,6 +1,7 @@
using System; using System;
using System.IO; using System.IO;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
using System.ServiceProcess;
using System.Xml; using System.Xml;
using Xunit; using Xunit;
@ -14,10 +15,12 @@ namespace WinSW.Tests.Util
public const string Name = "WinSW.Tests"; public const string Name = "WinSW.Tests";
public const string DisplayName = "WinSW Test Service"; 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) =>
$@"<service> $@"<service>
<id>{Name}</id> <id>{Name}</id>
<name>{DisplayName}</name> <name>{displayName}</name>
<executable>cmd.exe</executable> <executable>cmd.exe</executable>
<arguments>/c timeout /t -1 /nobreak</arguments> <arguments>/c timeout /t -1 /nobreak</arguments>
</service>"; </service>";
@ -105,23 +108,22 @@ $@"<service>
internal TestXmlServiceConfig(XmlDocument document, string name) internal TestXmlServiceConfig(XmlDocument document, string name)
: base(document) : base(document)
{ {
string directory = this.directory = Path.Combine(Path.GetTempPath(), name); string folder = this.directory = FilesystemTestHelper.CreateTmpDirectory(name);
_ = Directory.CreateDirectory(directory);
try 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)) using (var file = File.CreateText(path))
{ {
file.Write(SeedXml); file.Write(SeedXml);
} }
this.BaseName = name; this.BaseName = name;
this.BasePath = Path.Combine(directory, name); this.BasePath = Path.Combine(folder, name);
} }
catch catch
{ {
Directory.Delete(directory, true); Directory.Delete(folder, true);
throw; throw;
} }
} }

View File

@ -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"]);
}
}

View File

@ -2,7 +2,7 @@
namespace WinSW.Tests.Util namespace WinSW.Tests.Util
{ {
internal class FilesystemTestHelper internal static class FilesystemTestHelper
{ {
/// <summary> /// <summary>
/// Creates a temporary directory for testing. /// Creates a temporary directory for testing.

View File

@ -6,18 +6,26 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="coverlet.collector" Version="3.1.0"> <PackageReference Include="coverlet.collector" Version="6.0.2">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets> <PrivateAssets>all</PrivateAssets>
</PackageReference> </PackageReference>
<PackageReference Include="Microsoft.Diagnostics.Runtime" Version="2.0.226801" /> <PackageReference Include="Microsoft.Diagnostics.Runtime" Version="2.0.226801" />
<PackageReference Include="Microsoft.Diagnostics.Runtime.Utilities" Version="2.0.0-rc.20303.3" /> <PackageReference Include="Microsoft.Diagnostics.Runtime.Utilities" Version="2.0.0-rc.20303.3" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.4.1" /> <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.11.1" />
<PackageReference Include="Microsoft.Windows.CsWin32" Version="0.2.188-beta"> <PackageReference Include="Microsoft.Windows.CsWin32" Version="0.2.188-beta">
<PrivateAssets>all</PrivateAssets> <PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference> </PackageReference>
<PackageReference Include="xunit" Version="2.4.2" /> <PackageReference Include="xunit" Version="2.9.2" />
<PackageReference Include="xunit.analyzers" Version="1.16.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="xunit.runner.console" Version="2.9.2">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.5"> <PackageReference Include="xunit.runner.visualstudio" Version="2.4.5">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets> <PrivateAssets>all</PrivateAssets>

View File

@ -15,7 +15,6 @@
</PropertyGroup> </PropertyGroup>
<PropertyGroup> <PropertyGroup>
<PublishTrimmed>true</PublishTrimmed>
<TrimMode>partial</TrimMode> <TrimMode>partial</TrimMode>
<DebuggerSupport>false</DebuggerSupport> <DebuggerSupport>false</DebuggerSupport>
<NullabilityInfoContextSupport>false</NullabilityInfoContextSupport> <NullabilityInfoContextSupport>false</NullabilityInfoContextSupport>
@ -23,6 +22,7 @@
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(TargetFramework)' == 'net7.0-windows' AND '$(RuntimeIdentifier)' != ''"> <PropertyGroup Condition="'$(TargetFramework)' == 'net7.0-windows' AND '$(RuntimeIdentifier)' != ''">
<PublishTrimmed>true</PublishTrimmed>
<PublishSingleFile>true</PublishSingleFile> <PublishSingleFile>true</PublishSingleFile>
</PropertyGroup> </PropertyGroup>