Migrate tests to xUnit

pull/586/head
NextTurn 2018-11-27 00:00:00 +08:00 committed by Next Turn
parent e8726d7c1b
commit 885beb89a2
15 changed files with 258 additions and 326 deletions

View File

@ -0,0 +1,18 @@
using System;
using winsw;
using Xunit;
namespace winswTests
{
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
internal sealed class ElevatedFactAttribute : FactAttribute
{
internal ElevatedFactAttribute()
{
if (!Program.IsProcessElevated())
{
this.Skip = "Access is denied";
}
}
}
}

View File

@ -1,9 +1,9 @@
using System.IO;
using System.Reflection;
using System;
using System.IO;
using System.Xml;
using NUnit.Framework;
using winsw;
using winswTests.Util;
using Xunit;
namespace winswTests.Configuration
{
@ -11,38 +11,37 @@ namespace winswTests.Configuration
/// Tests example configuration files.
/// The test uses a relative path to example files, which is based on the current project structure.
/// </summary>
[TestFixture]
public class ExamplesTest
{
[Test]
[Fact]
public void AllOptionsConfigShouldDeclareDefaults()
{
ServiceDescriptor desc = Load("complete");
Assert.That(desc.Id, Is.EqualTo("myapp"));
Assert.That(desc.Caption, Is.EqualTo("MyApp Service (powered by WinSW)"));
Assert.That(desc.Description, Is.EqualTo("This service is a service created from a sample configuration"));
Assert.That(desc.Executable, Is.EqualTo("%BASE%\\myExecutable.exe"));
Assert.Equal("myapp", desc.Id);
Assert.Equal("MyApp Service (powered by WinSW)", desc.Caption);
Assert.Equal("This service is a service created from a sample configuration", desc.Description);
Assert.Equal("%BASE%\\myExecutable.exe", desc.Executable);
ServiceDescriptorAssert.AssertAllOptionalPropertiesAreDefault(desc);
}
[Test]
[Fact]
public void MinimalConfigShouldDeclareDefaults()
{
ServiceDescriptor desc = Load("minimal");
Assert.That(desc.Id, Is.EqualTo("myapp"));
Assert.That(desc.Caption, Is.EqualTo("MyApp Service (powered by WinSW)"));
Assert.That(desc.Description, Is.EqualTo("This service is a service created from a minimal configuration"));
Assert.That(desc.Executable, Is.EqualTo("%BASE%\\myExecutable.exe"));
Assert.Equal("myapp", desc.Id);
Assert.Equal("MyApp Service (powered by WinSW)", desc.Caption);
Assert.Equal("This service is a service created from a minimal configuration", desc.Description);
Assert.Equal("%BASE%\\myExecutable.exe", desc.Executable);
ServiceDescriptorAssert.AssertAllOptionalPropertiesAreDefault(desc);
}
private static ServiceDescriptor Load(string exampleName)
{
string directory = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
string directory = Environment.CurrentDirectory;
while (true)
{
if (File.Exists(Path.Combine(directory, ".gitignore")))
@ -51,11 +50,11 @@ namespace winswTests.Configuration
}
directory = Path.GetDirectoryName(directory);
Assert.That(directory, Is.Not.Null);
Assert.NotNull(directory);
}
string path = Path.Combine(directory, $@"samples\sample-{exampleName}.xml");
Assert.That(path, Does.Exist);
Assert.True(File.Exists(path));
XmlDocument dom = new XmlDocument();
dom.Load(path);

View File

@ -1,17 +1,16 @@
using System.IO;
using NUnit.Framework;
using winsw;
using winswTests.Util;
using Xunit;
namespace winswTests
{
[TestFixture]
public class DownloadConfigTests
{
private const string From = "https://www.nosuchhostexists.foo.myorg/foo.xml";
private const string To = "%BASE%\\foo.xml";
[Test]
[Fact]
public void Roundtrip_Defaults()
{
// Roundtrip data
@ -22,14 +21,14 @@ namespace winswTests
var loaded = GetSingleEntry(sd);
// Check default values
Assert.That(loaded.FailOnError, Is.False);
Assert.That(loaded.Auth, Is.EqualTo(Download.AuthType.none));
Assert.That(loaded.Username, Is.Null);
Assert.That(loaded.Password, Is.Null);
Assert.That(loaded.UnsecureAuth, Is.False);
Assert.False(loaded.FailOnError);
Assert.Equal(Download.AuthType.none, loaded.Auth);
Assert.Null(loaded.Username);
Assert.Null(loaded.Password);
Assert.False(loaded.UnsecureAuth);
}
[Test]
[Fact]
public void Roundtrip_BasicAuth()
{
// Roundtrip data
@ -40,14 +39,14 @@ namespace winswTests
var loaded = 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);
Assert.True(loaded.FailOnError);
Assert.Equal(Download.AuthType.basic, loaded.Auth);
Assert.Equal("aUser", loaded.Username);
Assert.Equal("aPassword", loaded.Password);
Assert.True(loaded.UnsecureAuth);
}
[Test]
[Fact]
public void Roundtrip_SSPI()
{
// Roundtrip data
@ -58,18 +57,18 @@ namespace winswTests
var loaded = 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);
Assert.False(loaded.FailOnError);
Assert.Equal(Download.AuthType.sspi, loaded.Auth);
Assert.Null(loaded.Username);
Assert.Null(loaded.Password);
Assert.False(loaded.UnsecureAuth);
}
[TestCase("http://")]
[TestCase("ftp://")]
[TestCase("file://")]
[TestCase("jar://")]
[TestCase("\\\\")] // UNC
[Theory]
[InlineData("http://")]
[InlineData("ftp://")]
[InlineData("file://")]
[InlineData("\\\\")] // UNC
public void RejectBasicAuth_With_UnsecureProtocol(string protocolPrefix)
{
string unsecureFrom = protocolPrefix + "myServer.com:8080/file.txt";
@ -77,14 +76,14 @@ namespace winswTests
AssertInitializationFails(d, "Warning: you're sending your credentials in clear text to the server");
}
[Test]
[Fact]
public void RejectBasicAuth_Without_Username()
{
var d = new Download(From, To, auth: Download.AuthType.basic, username: null, password: "aPassword");
AssertInitializationFails(d, "Basic Auth is enabled, but username is not specified");
}
[Test]
[Fact]
public void RejectBasicAuth_Without_Password()
{
var d = new Download(From, To, auth: Download.AuthType.basic, username: "aUser", password: null);
@ -94,8 +93,9 @@ namespace winswTests
/// <summary>
/// Ensures that the fail-on-error field is being processed correctly.
/// </summary>
[TestCase(true)]
[TestCase(false)]
[Theory]
[InlineData(true)]
[InlineData(false)]
public void Download_FailOnError(bool failOnError)
{
Download d = new Download(From, To, failOnError);
@ -105,15 +105,15 @@ namespace winswTests
.ToServiceDescriptor(true);
var loaded = 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");
Assert.Equal(From, loaded.From);
Assert.Equal(To, loaded.To);
Assert.Equal(failOnError, loaded.FailOnError);
}
/// <summary>
/// Ensures that the fail-on-error field is being processed correctly.
/// </summary>
[Test]
[Fact]
public void Download_FailOnError_Undefined()
{
var sd = ConfigXmlBuilder.create()
@ -121,23 +121,24 @@ namespace winswTests
.ToServiceDescriptor(true);
var loaded = GetSingleEntry(sd);
Assert.That(loaded.FailOnError, Is.False);
Assert.False(loaded.FailOnError);
}
[TestCase("sspi")]
[TestCase("SSPI")]
[TestCase("SsPI")]
[TestCase("Sspi")]
[Theory]
[InlineData("sspi")]
[InlineData("SSPI")]
[InlineData("SsPI")]
[InlineData("Sspi")]
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 = GetSingleEntry(sd);
Assert.That(loaded.Auth, Is.EqualTo(Download.AuthType.sspi));
Assert.Equal(Download.AuthType.sspi, loaded.Auth);
}
[Test]
[Fact]
public void Should_Fail_On_Unsupported_AuthType()
{
// TODO: will need refactoring once all fields are being parsed on startup
@ -145,12 +146,14 @@ namespace winswTests
.WithRawEntry("<download from=\"http://www.nosuchhostexists.foo.myorg/foo.xml\" to=\"%BASE%\\foo.xml\" auth=\"digest\"/>")
.ToServiceDescriptor(true);
Assert.That(() => GetSingleEntry(sd), Throws.TypeOf<InvalidDataException>().With.Message.StartsWith("Cannot parse <auth> Enum value from string 'digest'"));
var e = Assert.Throws<InvalidDataException>(() => GetSingleEntry(sd));
Assert.StartsWith("Cannot parse <auth> Enum value from string 'digest'", e.Message);
}
[TestCase("http://", "127.0.0.1:80", "egarcia", "Passw0rd")]
[TestCase("https://", "myurl.com.co:2298", "MyUsername", "P@ssw:rd")]
[TestCase("http://", "192.168.0.8:3030")]
[Theory]
[InlineData("http://", "127.0.0.1:80", "egarcia", "Passw0rd")]
[InlineData("https://", "myurl.com.co:2298", "MyUsername", "P@ssw:rd")]
[InlineData("http://", "192.168.0.8:3030")]
public void Proxy_Credentials(string protocol, string address, string username = null, string password = null)
{
CustomProxyInformation cpi;
@ -163,25 +166,24 @@ namespace winswTests
cpi = new CustomProxyInformation(protocol + username + ":" + password + "@" + address + "/");
}
Assert.That(cpi.ServerAddress, Is.EqualTo(protocol + address + "/"));
Assert.Equal(protocol + address + "/", cpi.ServerAddress);
if (string.IsNullOrEmpty(username))
{
Assert.IsNull(cpi.Credentials);
Assert.Null(cpi.Credentials);
}
else
{
Assert.IsNotNull(cpi.Credentials);
Assert.That(cpi.Credentials.UserName, Is.EqualTo(username));
Assert.That(cpi.Credentials.Password, Is.EqualTo(password));
Assert.NotNull(cpi.Credentials);
Assert.Equal(username, cpi.Credentials.UserName);
Assert.Equal(password, cpi.Credentials.Password);
}
}
private Download GetSingleEntry(ServiceDescriptor sd)
{
var downloads = sd.Downloads.ToArray();
Assert.That(downloads.Length, Is.EqualTo(1), "Service Descriptor is expected to have only one entry");
return downloads[0];
return Assert.Single(downloads);
}
private void AssertInitializationFails(Download download, string expectedMessagePart = null)
@ -190,7 +192,8 @@ namespace winswTests
.WithDownload(download)
.ToServiceDescriptor(true);
Assert.That(() => GetSingleEntry(sd), Throws.TypeOf<InvalidDataException>().With.Message.StartsWith(expectedMessagePart));
var e = Assert.Throws<InvalidDataException>(() => GetSingleEntry(sd));
Assert.StartsWith(expectedMessagePart, e.Message);
}
}
}

View File

@ -4,23 +4,21 @@ using System.Net;
using System.Net.Sockets;
using System.Runtime.CompilerServices;
using System.Threading.Tasks;
using NUnit.Framework;
using winsw;
using winswTests.Util;
using Xunit;
namespace winswTests
{
[TestFixture]
public class DownloadTests
public class DownloadTests : IDisposable
{
private readonly HttpListener globalListener = new HttpListener();
private readonly byte[] contents = { 0x57, 0x69, 0x6e, 0x53, 0x57 };
private string globalPrefix;
private readonly string globalPrefix;
[OneTimeSetUp]
public void SetUp()
public DownloadTests()
{
TcpListener tcpListener = new TcpListener(IPAddress.Loopback, 0);
tcpListener.Start();
@ -34,8 +32,7 @@ namespace winswTests
}
}
[OneTimeTearDown]
public void TearDown()
public void Dispose()
{
this.globalListener.Stop();
this.globalListener.Close();
@ -88,14 +85,14 @@ namespace winswTests
}
}
[Test]
[Fact]
public async Task TestHttpAsync()
{
await this.TestClientServerAsync(
async (source, dest) =>
{
await new Download(source, dest).PerformAsync();
Assert.That(File.ReadAllBytes(dest), Is.EqualTo(this.contents));
Assert.Equal(this.contents, File.ReadAllBytes(dest));
},
context =>
{
@ -104,14 +101,14 @@ namespace winswTests
});
}
[Test]
[Fact]
public async Task TestHttp_NoAuthAsync()
{
await this.TestClientServerAsync(
async (source, dest) =>
{
await new Download(source, dest, false, Download.AuthType.none).PerformAsync();
Assert.That(File.ReadAllBytes(dest), Is.EqualTo(this.contents));
Assert.Equal(this.contents, File.ReadAllBytes(dest));
},
context =>
{
@ -126,7 +123,7 @@ namespace winswTests
});
}
[Test]
[Fact]
public async Task TestHttp_BasicAuthAsync()
{
const string username = nameof(username);
@ -136,7 +133,7 @@ namespace winswTests
async (source, dest) =>
{
await new Download(source, dest, false, Download.AuthType.basic, username, password, true).PerformAsync();
Assert.That(File.ReadAllBytes(dest), Is.EqualTo(this.contents));
Assert.Equal(this.contents, File.ReadAllBytes(dest));
},
context =>
{
@ -153,7 +150,7 @@ namespace winswTests
AuthenticationSchemes.Basic);
}
[Test]
[Fact]
public async Task TestHttp_IfModifiedSince_ModifiedAsync()
{
DateTime lastModified = DateTime.Now.TrimToSeconds();
@ -165,8 +162,8 @@ namespace winswTests
File.WriteAllBytes(dest, this.contents);
File.SetLastWriteTime(dest, prevModified);
await new Download(source, dest).PerformAsync();
Assert.That(File.GetLastWriteTime(dest), Is.EqualTo(lastModified));
Assert.That(File.ReadAllBytes(dest), Is.Not.EqualTo(this.contents));
Assert.Equal(lastModified, File.GetLastWriteTime(dest));
Assert.NotEqual(this.contents, File.ReadAllBytes(dest));
},
context =>
{
@ -181,7 +178,7 @@ namespace winswTests
});
}
[Test]
[Fact]
public async Task TestHttp_IfModifiedSince_NotModifiedAsync()
{
DateTime lastModified = DateTime.Now.TrimToSeconds();
@ -192,8 +189,8 @@ namespace winswTests
File.WriteAllBytes(dest, this.contents);
File.SetLastWriteTime(dest, lastModified);
await new Download(source, dest).PerformAsync();
Assert.That(File.GetLastWriteTime(dest), Is.EqualTo(lastModified));
Assert.That(File.ReadAllBytes(dest), Is.EqualTo(this.contents));
Assert.Equal(lastModified, File.GetLastWriteTime(dest));
Assert.Equal(this.contents, File.ReadAllBytes(dest));
},
context =>
{
@ -208,16 +205,16 @@ namespace winswTests
});
}
[Test]
[Fact]
public async Task TestHttp_NotFound_ThrowsAsync()
{
await this.TestClientServerAsync(
async (source, dest) =>
{
WebException exception = await AsyncAssert.ThrowsAsync<WebException>(
WebException exception = await Assert.ThrowsAsync<WebException>(
async () => await new Download(source, dest).PerformAsync());
Assert.That(exception.Status, Is.EqualTo(WebExceptionStatus.ProtocolError));
Assert.Equal(WebExceptionStatus.ProtocolError, exception.Status);
},
context =>
{

View File

@ -1,25 +1,22 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using NUnit.Framework;
using winsw;
using winsw.Extensions;
using winsw.Plugins.RunawayProcessKiller;
using winsw.Util;
using winswTests.Util;
using Xunit;
namespace winswTests.Extensions
{
[TestFixture]
class RunawayProcessKillerExtensionTest : ExtensionTestBase
public class RunawayProcessKillerExtensionTest : ExtensionTestBase
{
ServiceDescriptor _testServiceDescriptor;
readonly ServiceDescriptor _testServiceDescriptor;
readonly string testExtension = GetExtensionClassNameWithAssembly(typeof(RunawayProcessKillerExtension));
[SetUp]
public void SetUp()
public RunawayProcessKillerExtensionTest()
{
string seedXml =
$@"<service>
@ -39,21 +36,21 @@ $@"<service>
_testServiceDescriptor = ServiceDescriptor.FromXML(seedXml);
}
[Test]
[Fact]
public void LoadExtensions()
{
WinSWExtensionManager manager = new WinSWExtensionManager(_testServiceDescriptor);
manager.LoadExtensions();
Assert.AreEqual(1, manager.Extensions.Count, "One extension should be loaded");
_ = Assert.Single(manager.Extensions);
// Check the file is correct
var extension = manager.Extensions["killRunawayProcess"] as RunawayProcessKillerExtension;
Assert.IsNotNull(extension, "RunawayProcessKillerExtension should be loaded");
Assert.AreEqual("foo/bar/pid.txt", extension.Pidfile, "Loaded PID file path is not equal to the expected one");
Assert.AreEqual(5000, extension.StopTimeout.TotalMilliseconds, "Loaded Stop Timeout is not equal to the expected one");
Assert.NotNull(extension);
Assert.Equal("foo/bar/pid.txt", extension.Pidfile);
Assert.Equal(5000, extension.StopTimeout.TotalMilliseconds);
}
[Test]
[Fact]
public void StartStopExtension()
{
WinSWExtensionManager manager = new WinSWExtensionManager(_testServiceDescriptor);
@ -62,11 +59,8 @@ $@"<service>
manager.FireBeforeWrapperStopped();
}
[Test]
public void ShouldKillTheSpawnedProcess()
internal void ShouldKillTheSpawnedProcess()
{
Assert.Ignore();
var winswId = "myAppWithRunaway";
var extensionId = "runaway-process-killer";
var tmpDir = FilesystemTestHelper.CreateTmpDirectory();
@ -91,17 +85,17 @@ $@"<service>
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");
Assert.NotNull(extension);
Assert.Equal(pidfile, extension.Pidfile);
// Inject PID
File.WriteAllText(pidfile, proc.Id.ToString());
// Try to terminate
Assert.That(!proc.HasExited, "Process " + proc + " has exited before the RunawayProcessKiller extension invocation");
Assert.False(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");
Assert.True(proc.HasExited, "Process " + proc + " should have been terminated by RunawayProcessKiller");
}
finally
{

View File

@ -1,19 +1,17 @@
using NUnit.Framework;
using winsw;
using winsw;
using winsw.Extensions;
using winsw.Plugins.SharedDirectoryMapper;
using Xunit;
namespace winswTests.Extensions
{
[TestFixture]
class SharedDirectoryMapperConfigTest : ExtensionTestBase
public class SharedDirectoryMapperConfigTest : ExtensionTestBase
{
ServiceDescriptor _testServiceDescriptor;
readonly ServiceDescriptor _testServiceDescriptor;
readonly string testExtension = GetExtensionClassNameWithAssembly(typeof(SharedDirectoryMapper));
[SetUp]
public void SetUp()
public SharedDirectoryMapperConfigTest()
{
string seedXml =
$@"<service>
@ -41,15 +39,15 @@ $@"<service>
_testServiceDescriptor = ServiceDescriptor.FromXML(seedXml);
}
[Test]
[Fact]
public void LoadExtensions()
{
WinSWExtensionManager manager = new WinSWExtensionManager(_testServiceDescriptor);
manager.LoadExtensions();
Assert.AreEqual(2, manager.Extensions.Count, "Two extensions should be loaded");
Assert.Equal(2, manager.Extensions.Count);
}
[Test]
[Fact]
public void StartStopExtension()
{
WinSWExtensionManager manager = new WinSWExtensionManager(_testServiceDescriptor);

View File

@ -3,16 +3,15 @@ using System;
using System.IO;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using NUnit.Framework;
using winsw.Plugins.SharedDirectoryMapper;
using Xunit;
namespace winswTests.Extensions
{
// TODO: Throws.TypeOf<ExtensionException>()
[TestFixture]
// TODO: Assert.Throws<ExtensionException>
public class SharedDirectoryMapperTests
{
[Test]
[ElevatedFact]
public void TestMap()
{
using TestData data = TestData.Create();
@ -21,12 +20,12 @@ namespace winswTests.Extensions
SharedDirectoryMapper mapper = new SharedDirectoryMapper(true, $@"\\{Environment.MachineName}\{data.name}", label);
mapper.OnWrapperStarted();
Assert.That($@"{label}\", Does.Exist);
Assert.True(Directory.Exists($@"{label}\"));
mapper.BeforeWrapperStopped();
Assert.That($@"{label}\", Does.Not.Exist);
Assert.False(Directory.Exists($@"{label}\"));
}
[Test]
[ElevatedFact]
public void TestDisableMapping()
{
using TestData data = TestData.Create();
@ -35,11 +34,11 @@ namespace winswTests.Extensions
SharedDirectoryMapper mapper = new SharedDirectoryMapper(enableMapping: false, $@"\\{Environment.MachineName}\{data.name}", label);
mapper.OnWrapperStarted();
Assert.That($@"{label}\", Does.Not.Exist);
Assert.False(Directory.Exists($@"{label}\"));
mapper.BeforeWrapperStopped();
}
[Test]
[ElevatedFact]
public void TestMap_PathEndsWithSlash_Throws()
{
using TestData data = TestData.Create();
@ -47,12 +46,12 @@ namespace winswTests.Extensions
const string label = "W:";
SharedDirectoryMapper mapper = new SharedDirectoryMapper(true, $@"\\{Environment.MachineName}\{data.name}\", label);
Assert.That(() => mapper.OnWrapperStarted(), Throws.Exception);
Assert.That($@"{label}\", Does.Not.Exist);
Assert.That(() => mapper.BeforeWrapperStopped(), Throws.Exception);
_ = Assert.ThrowsAny<Exception>(() => mapper.OnWrapperStarted());
Assert.False(Directory.Exists($@"{label}\"));
_ = Assert.ThrowsAny<Exception>(() => mapper.BeforeWrapperStopped());
}
[Test]
[ElevatedFact]
public void TestMap_LabelDoesNotEndWithColon_Throws()
{
using TestData data = TestData.Create();
@ -60,9 +59,9 @@ namespace winswTests.Extensions
const string label = "W";
SharedDirectoryMapper mapper = new SharedDirectoryMapper(true, $@"\\{Environment.MachineName}\{data.name}", label);
Assert.That(() => mapper.OnWrapperStarted(), Throws.Exception);
Assert.That($@"{label}\", Does.Not.Exist);
Assert.That(() => mapper.BeforeWrapperStopped(), Throws.Exception);
_ = Assert.ThrowsAny<Exception>(() => mapper.OnWrapperStarted());
Assert.False(Directory.Exists($@"{label}\"));
_ = Assert.ThrowsAny<Exception>(() => mapper.BeforeWrapperStopped());
}
private readonly ref struct TestData
@ -92,7 +91,7 @@ namespace winswTests.Extensions
};
uint error = NativeMethods.NetShareAdd(null, 2, shareInfo, out _);
Assert.That(error, Is.Zero);
Assert.Equal(0u, error);
return new TestData(name, path);
}
@ -108,7 +107,7 @@ namespace winswTests.Extensions
try
{
uint error = NativeMethods.NetShareDel(null, this.name);
Assert.That(error, Is.Zero);
Assert.Equal(0u, error);
}
finally
{

View File

@ -1,30 +1,27 @@
using System;
using System.ServiceProcess;
using NUnit.Framework;
using winsw;
using winswTests.Util;
using Xunit;
namespace winswTests
{
[TestFixture]
public class MainTest
{
[Test]
[ElevatedFact]
public void TestInstall()
{
TestHelper.RequireProcessElevated();
try
{
_ = CLITestHelper.CLITest(new[] { "install" });
using ServiceController controller = new ServiceController(CLITestHelper.Id);
Assert.That(controller.DisplayName, Is.EqualTo(CLITestHelper.Name));
Assert.That(controller.CanStop, Is.False);
Assert.That(controller.CanShutdown, Is.False);
Assert.That(controller.CanPauseAndContinue, Is.False);
Assert.That(controller.Status, Is.EqualTo(ServiceControllerStatus.Stopped));
Assert.That(controller.ServiceType, Is.EqualTo(ServiceType.Win32OwnProcess));
Assert.Equal(CLITestHelper.Name, 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);
}
finally
{
@ -32,47 +29,47 @@ namespace winswTests
}
}
[Test]
[Fact]
public void PrintVersion()
{
string expectedVersion = WrapperService.Version.ToString();
string cliOut = CLITestHelper.CLITest(new[] { "version" });
Assert.That(cliOut, Does.Contain(expectedVersion));
Assert.Contains(expectedVersion, cliOut);
}
[Test]
[Fact]
public void PrintHelp()
{
string expectedVersion = WrapperService.Version.ToString();
string cliOut = CLITestHelper.CLITest(new[] { "help" });
Assert.That(cliOut, Does.Contain(expectedVersion));
Assert.That(cliOut, Does.Contain("start"));
Assert.That(cliOut, Does.Contain("help"));
Assert.That(cliOut, Does.Contain("version"));
Assert.Contains(expectedVersion, cliOut);
Assert.Contains("start", cliOut);
Assert.Contains("help", cliOut);
Assert.Contains("version", cliOut);
// TODO: check all commands after the migration of ccommands to enum
}
[Test]
[Fact]
public void FailOnUnsupportedCommand()
{
const string commandName = "nonExistentCommand";
string expectedMessage = "Unknown command: " + commandName;
CLITestResult result = CLITestHelper.CLIErrorTest(new[] { commandName });
Assert.That(result.HasException, Is.True);
Assert.That(result.Out, Does.Contain(expectedMessage));
Assert.That(result.Exception.Message, Does.Contain(expectedMessage));
Assert.True(result.HasException);
Assert.Contains(expectedMessage, result.Out);
Assert.Contains(expectedMessage, result.Exception.Message);
}
/// <summary>
/// https://github.com/kohsuke/winsw/issues/206
/// </summary>
[Test]
[Fact]
public void ShouldNotPrintLogsForStatusCommand()
{
string cliOut = CLITestHelper.CLITest(new[] { "status" });
Assert.That(cliOut, Is.EqualTo("NonExistent" + Environment.NewLine).IgnoreCase);
Assert.Equal("NonExistent" + Environment.NewLine, cliOut);
}
}
}

View File

@ -1,13 +1,12 @@
using System;
using System.Diagnostics;
using System.ServiceProcess;
using NUnit.Framework;
using winsw;
using winswTests.Util;
using Xunit;
namespace winswTests
{
[TestFixture]
public class ServiceDescriptorTests
{
private ServiceDescriptor _extendedServiceDescriptor;
@ -18,8 +17,7 @@ namespace winswTests
private const string Domain = "Domain";
private const string AllowServiceAccountLogonRight = "true";
[SetUp]
public void SetUp()
public ServiceDescriptorTests()
{
string seedXml =
$@"<service>
@ -40,13 +38,13 @@ $@"<service>
_extendedServiceDescriptor = ServiceDescriptor.FromXML(seedXml);
}
[Test]
[Fact]
public void DefaultStartMode()
{
Assert.That(_extendedServiceDescriptor.StartMode, Is.EqualTo(ServiceStartMode.Automatic));
Assert.Equal(ServiceStartMode.Automatic, _extendedServiceDescriptor.StartMode);
}
[Test]
[Fact]
public void IncorrectStartMode()
{
string seedXml =
@ -68,10 +66,10 @@ $@"<service>
</service>";
_extendedServiceDescriptor = ServiceDescriptor.FromXML(seedXml);
Assert.That(() => _extendedServiceDescriptor.StartMode, Throws.ArgumentException);
Assert.Throws<ArgumentException>(() => _extendedServiceDescriptor.StartMode);
}
[Test]
[Fact]
public void ChangedStartMode()
{
string seedXml =
@ -93,50 +91,50 @@ $@"<service>
</service>";
_extendedServiceDescriptor = ServiceDescriptor.FromXML(seedXml);
Assert.That(_extendedServiceDescriptor.StartMode, Is.EqualTo(ServiceStartMode.Manual));
Assert.Equal(ServiceStartMode.Manual, _extendedServiceDescriptor.StartMode);
}
[Test]
[Fact]
public void VerifyWorkingDirectory()
{
Debug.WriteLine("_extendedServiceDescriptor.WorkingDirectory :: " + _extendedServiceDescriptor.WorkingDirectory);
Assert.That(_extendedServiceDescriptor.WorkingDirectory, Is.EqualTo(ExpectedWorkingDirectory));
Assert.Equal(ExpectedWorkingDirectory, _extendedServiceDescriptor.WorkingDirectory);
}
[Test]
[Fact]
public void VerifyServiceLogonRight()
{
Assert.That(_extendedServiceDescriptor.AllowServiceAcountLogonRight, Is.True);
Assert.True(_extendedServiceDescriptor.AllowServiceAcountLogonRight);
}
[Test]
[Fact]
public void VerifyUsername()
{
Debug.WriteLine("_extendedServiceDescriptor.WorkingDirectory :: " + _extendedServiceDescriptor.WorkingDirectory);
Assert.That(_extendedServiceDescriptor.ServiceAccountUserName, Is.EqualTo(Domain + "\\" + Username));
Assert.Equal(Domain + "\\" + Username, _extendedServiceDescriptor.ServiceAccountUserName);
}
[Test]
[Fact]
public void VerifyPassword()
{
Debug.WriteLine("_extendedServiceDescriptor.WorkingDirectory :: " + _extendedServiceDescriptor.WorkingDirectory);
Assert.That(_extendedServiceDescriptor.ServiceAccountPassword, Is.EqualTo(Password));
Assert.Equal(Password, _extendedServiceDescriptor.ServiceAccountPassword);
}
[Test]
[Fact]
public void Priority()
{
var sd = ServiceDescriptor.FromXML("<service><id>test</id><priority>normal</priority></service>");
Assert.That(sd.Priority, Is.EqualTo(ProcessPriorityClass.Normal));
Assert.Equal(ProcessPriorityClass.Normal, sd.Priority);
sd = ServiceDescriptor.FromXML("<service><id>test</id><priority>idle</priority></service>");
Assert.That(sd.Priority, Is.EqualTo(ProcessPriorityClass.Idle));
Assert.Equal(ProcessPriorityClass.Idle, sd.Priority);
sd = ServiceDescriptor.FromXML("<service><id>test</id></service>");
Assert.That(sd.Priority, Is.EqualTo(ProcessPriorityClass.Normal));
Assert.Equal(ProcessPriorityClass.Normal, sd.Priority);
}
[Test]
[Fact]
public void CanParseStopTimeout()
{
const string seedXml = "<service>"
@ -144,10 +142,10 @@ $@"<service>
+ "</service>";
var serviceDescriptor = ServiceDescriptor.FromXML(seedXml);
Assert.That(serviceDescriptor.StopTimeout, Is.EqualTo(TimeSpan.FromSeconds(60)));
Assert.Equal(TimeSpan.FromSeconds(60), serviceDescriptor.StopTimeout);
}
[Test]
[Fact]
public void CanParseStopTimeoutFromMinutes()
{
const string seedXml = "<service>"
@ -155,10 +153,10 @@ $@"<service>
+ "</service>";
var serviceDescriptor = ServiceDescriptor.FromXML(seedXml);
Assert.That(serviceDescriptor.StopTimeout, Is.EqualTo(TimeSpan.FromMinutes(10)));
Assert.Equal(TimeSpan.FromMinutes(10), serviceDescriptor.StopTimeout);
}
[Test]
[Fact]
public void CanParseLogname()
{
const string seedXml = "<service>"
@ -166,10 +164,10 @@ $@"<service>
+ "</service>";
var serviceDescriptor = ServiceDescriptor.FromXML(seedXml);
Assert.That(serviceDescriptor.LogName, Is.EqualTo("MyTestApp"));
Assert.Equal("MyTestApp", serviceDescriptor.LogName);
}
[Test]
[Fact]
public void CanParseOutfileDisabled()
{
const string seedXml = "<service>"
@ -177,10 +175,10 @@ $@"<service>
+ "</service>";
var serviceDescriptor = ServiceDescriptor.FromXML(seedXml);
Assert.That(serviceDescriptor.OutFileDisabled, Is.True);
Assert.True(serviceDescriptor.OutFileDisabled);
}
[Test]
[Fact]
public void CanParseErrfileDisabled()
{
const string seedXml = "<service>"
@ -188,10 +186,10 @@ $@"<service>
+ "</service>";
var serviceDescriptor = ServiceDescriptor.FromXML(seedXml);
Assert.That(serviceDescriptor.ErrFileDisabled, Is.True);
Assert.True(serviceDescriptor.ErrFileDisabled);
}
[Test]
[Fact]
public void CanParseOutfilePattern()
{
const string seedXml = "<service>"
@ -199,10 +197,10 @@ $@"<service>
+ "</service>";
var serviceDescriptor = ServiceDescriptor.FromXML(seedXml);
Assert.That(serviceDescriptor.OutFilePattern, Is.EqualTo(".out.test.log"));
Assert.Equal(".out.test.log", serviceDescriptor.OutFilePattern);
}
[Test]
[Fact]
public void CanParseErrfilePattern()
{
const string seedXml = "<service>"
@ -210,10 +208,10 @@ $@"<service>
+ "</service>";
var serviceDescriptor = ServiceDescriptor.FromXML(seedXml);
Assert.That(serviceDescriptor.ErrFilePattern, Is.EqualTo(".err.test.log"));
Assert.Equal(".err.test.log", serviceDescriptor.ErrFilePattern);
}
[Test]
[Fact]
public void LogModeRollBySize()
{
const string seedXml = "<service>"
@ -228,12 +226,12 @@ $@"<service>
serviceDescriptor.BaseName = "service";
var logHandler = serviceDescriptor.LogHandler as SizeBasedRollingLogAppender;
Assert.That(logHandler, Is.Not.Null);
Assert.That(logHandler.SizeTheshold, Is.EqualTo(112 * 1024));
Assert.That(logHandler.FilesToKeep, Is.EqualTo(113));
Assert.NotNull(logHandler);
Assert.Equal(112 * 1024, logHandler.SizeTheshold);
Assert.Equal(113, logHandler.FilesToKeep);
}
[Test]
[Fact]
public void LogModeRollByTime()
{
const string seedXml = "<service>"
@ -248,12 +246,12 @@ $@"<service>
serviceDescriptor.BaseName = "service";
var logHandler = serviceDescriptor.LogHandler as TimeBasedRollingLogAppender;
Assert.That(logHandler, Is.Not.Null);
Assert.That(logHandler.Period, Is.EqualTo(7));
Assert.That(logHandler.Pattern, Is.EqualTo("log pattern"));
Assert.NotNull(logHandler);
Assert.Equal(7, logHandler.Period);
Assert.Equal("log pattern", logHandler.Pattern);
}
[Test]
[Fact]
public void LogModeRollBySizeTime()
{
const string seedXml = "<service>"
@ -269,13 +267,13 @@ $@"<service>
serviceDescriptor.BaseName = "service";
var logHandler = serviceDescriptor.LogHandler as RollingSizeTimeLogAppender;
Assert.That(logHandler, Is.Not.Null);
Assert.That(logHandler.SizeTheshold, Is.EqualTo(10240 * 1024));
Assert.That(logHandler.FilePattern, Is.EqualTo("yyyy-MM-dd"));
Assert.That(logHandler.AutoRollAtTime, Is.EqualTo((TimeSpan?)new TimeSpan(0, 0, 0)));
Assert.NotNull(logHandler);
Assert.Equal(10240 * 1024, logHandler.SizeTheshold);
Assert.Equal("yyyy-MM-dd", logHandler.FilePattern);
Assert.Equal((TimeSpan?)new TimeSpan(0, 0, 0), logHandler.AutoRollAtTime);
}
[Test]
[Fact]
public void VerifyServiceLogonRightGraceful()
{
const string seedXml = "<service>"
@ -287,10 +285,10 @@ $@"<service>
+ "</serviceaccount>"
+ "</service>";
var serviceDescriptor = ServiceDescriptor.FromXML(seedXml);
Assert.That(serviceDescriptor.AllowServiceAcountLogonRight, Is.False);
Assert.False(serviceDescriptor.AllowServiceAcountLogonRight);
}
[Test]
[Fact]
public void VerifyServiceLogonRightOmitted()
{
const string seedXml = "<service>"
@ -301,89 +299,89 @@ $@"<service>
+ "</serviceaccount>"
+ "</service>";
var serviceDescriptor = ServiceDescriptor.FromXML(seedXml);
Assert.That(serviceDescriptor.AllowServiceAcountLogonRight, Is.False);
Assert.False(serviceDescriptor.AllowServiceAcountLogonRight);
}
[Test]
[Fact]
public void VerifyWaitHint_FullXML()
{
var sd = ConfigXmlBuilder.create()
.WithTag("waithint", "20 min")
.ToServiceDescriptor(true);
Assert.That(sd.WaitHint, Is.EqualTo(TimeSpan.FromMinutes(20)));
Assert.Equal(TimeSpan.FromMinutes(20), sd.WaitHint);
}
/// <summary>
/// Test for https://github.com/kohsuke/winsw/issues/159
/// </summary>
[Test]
[Fact]
public void VerifyWaitHint_XMLWithoutVersion()
{
var sd = ConfigXmlBuilder.create(printXMLVersion: false)
.WithTag("waithint", "21 min")
.ToServiceDescriptor(true);
Assert.That(sd.WaitHint, Is.EqualTo(TimeSpan.FromMinutes(21)));
Assert.Equal(TimeSpan.FromMinutes(21), sd.WaitHint);
}
[Test]
[Fact]
public void VerifyWaitHint_XMLWithoutComment()
{
var sd = ConfigXmlBuilder.create(xmlComment: null)
.WithTag("waithint", "22 min")
.ToServiceDescriptor(true);
Assert.That(sd.WaitHint, Is.EqualTo(TimeSpan.FromMinutes(22)));
Assert.Equal(TimeSpan.FromMinutes(22), sd.WaitHint);
}
[Test]
[Fact]
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)));
Assert.Equal(TimeSpan.FromMinutes(23), sd.WaitHint);
}
[Test]
[Fact]
public void VerifySleepTime()
{
var sd = ConfigXmlBuilder.create().WithTag("sleeptime", "3 hrs").ToServiceDescriptor(true);
Assert.That(sd.SleepTime, Is.EqualTo(TimeSpan.FromHours(3)));
Assert.Equal(TimeSpan.FromHours(3), sd.SleepTime);
}
[Test]
[Fact]
public void VerifyResetFailureAfter()
{
var sd = ConfigXmlBuilder.create().WithTag("resetfailure", "75 sec").ToServiceDescriptor(true);
Assert.That(sd.ResetFailureAfter, Is.EqualTo(TimeSpan.FromSeconds(75)));
Assert.Equal(TimeSpan.FromSeconds(75), sd.ResetFailureAfter);
}
[Test]
[Fact]
public void VerifyStopTimeout()
{
var sd = ConfigXmlBuilder.create().WithTag("stoptimeout", "35 secs").ToServiceDescriptor(true);
Assert.That(sd.StopTimeout, Is.EqualTo(TimeSpan.FromSeconds(35)));
Assert.Equal(TimeSpan.FromSeconds(35), sd.StopTimeout);
}
/// <summary>
/// https://github.com/kohsuke/winsw/issues/178
/// </summary>
[Test]
[Fact]
public void Arguments_LegacyParam()
{
var sd = ConfigXmlBuilder.create().WithTag("arguments", "arg").ToServiceDescriptor(true);
Assert.That(sd.Arguments, Is.EqualTo("arg"));
Assert.Equal("arg", sd.Arguments);
}
[Test]
[Fact]
public void Arguments_NewParam_Single()
{
var sd = ConfigXmlBuilder.create()
.WithTag("argument", "--arg1=2")
.ToServiceDescriptor(true);
Assert.That(sd.Arguments, Is.EqualTo(" --arg1=2"));
Assert.Equal(" --arg1=2", sd.Arguments);
}
[Test]
[Fact]
public void Arguments_NewParam_MultipleArgs()
{
var sd = ConfigXmlBuilder.create()
@ -391,13 +389,13 @@ $@"<service>
.WithTag("argument", "--arg2=123")
.WithTag("argument", "--arg3=null")
.ToServiceDescriptor(true);
Assert.That(sd.Arguments, Is.EqualTo(" --arg1=2 --arg2=123 --arg3=null"));
Assert.Equal(" --arg1=2 --arg2=123 --arg3=null", sd.Arguments);
}
/// <summary>
/// Ensures that the new single-argument field has a higher priority.
/// </summary>
[Test]
[Fact]
public void Arguments_Bothparam_Priorities()
{
var sd = ConfigXmlBuilder.create()
@ -405,11 +403,12 @@ $@"<service>
.WithTag("argument", "--arg2=123")
.WithTag("argument", "--arg3=null")
.ToServiceDescriptor(true);
Assert.That(sd.Arguments, Is.EqualTo(" --arg2=123 --arg3=null"));
Assert.Equal(" --arg2=123 --arg3=null", sd.Arguments);
}
[TestCase(true)]
[TestCase(false)]
[Theory]
[InlineData(true)]
[InlineData(false)]
public void DelayedStart_RoundTrip(bool enabled)
{
var bldr = ConfigXmlBuilder.create();
@ -419,7 +418,7 @@ $@"<service>
}
var sd = bldr.ToServiceDescriptor();
Assert.That(sd.DelayedAutoStart, Is.EqualTo(enabled));
Assert.Equal(enabled, sd.DelayedAutoStart);
}
}
}

View File

@ -1,27 +0,0 @@
using System;
using System.Threading.Tasks;
using NUnit.Framework;
using NUnit.Framework.Constraints;
namespace winswTests.Util
{
internal static class AsyncAssert
{
internal static async Task<TActual> ThrowsAsync<TActual>(AsyncTestDelegate code)
where TActual : Exception
{
Exception caught = null;
try
{
await code();
}
catch (Exception e)
{
caught = e;
}
Assert.That(caught, new ExceptionTypeConstraint(typeof(TActual)));
return (TActual)caught;
}
}
}

View File

@ -1,7 +1,7 @@
using System;
using System.IO;
using NUnit.Framework;
using winsw;
using Xunit;
namespace winswTests.Util
{
@ -54,7 +54,7 @@ $@"<service>
Console.SetError(tmpErr);
}
Assert.That(swErr.GetStringBuilder().Length, Is.Zero);
Assert.Equal(0, swErr.GetStringBuilder().Length);
Console.Write(swOut.ToString());
return swOut.ToString();
}

View File

@ -1,32 +0,0 @@
using System.Diagnostics;
using System.IO;
using System.Linq;
using NUnit.Framework;
using winsw.Util;
namespace winswTests.Util
{
[TestFixture]
class ProcessHelperTest
{
[Test]
public void ShouldNotHangWhenWritingLargeStringToStdOut()
{
var tmpDir = FilesystemTestHelper.CreateTmpDirectory();
string scriptFile = Path.Combine(tmpDir, "print_lots_to_stdout.bat");
var lotsOfStdOut = string.Join(string.Empty, Enumerable.Range(1, 1000));
File.WriteAllText(scriptFile, $"echo \"{lotsOfStdOut}\"");
Process proc = new Process();
var ps = proc.StartInfo;
ps.FileName = scriptFile;
ProcessHelper.StartProcessAndCallbackForExit(proc);
var exited = proc.WaitForExit(5000);
if (!exited)
{
Assert.Fail("Process " + proc + " didn't exit after 5 seconds");
}
}
}
}

View File

@ -1,8 +1,8 @@
using System.Collections.Generic;
using System.Reflection;
using NUnit.Framework;
using winsw;
using winsw.Configuration;
using Xunit;
namespace winswTests.Util
{
@ -14,12 +14,12 @@ namespace winswTests.Util
public static void AssertPropertyIsDefault(ServiceDescriptor desc, string property)
{
PropertyInfo actualProperty = typeof(ServiceDescriptor).GetProperty(property);
Assert.That(actualProperty, Is.Not.Null);
Assert.NotNull(actualProperty);
PropertyInfo defaultProperty = typeof(DefaultWinSWSettings).GetProperty(property);
Assert.That(defaultProperty, Is.Not.Null);
Assert.NotNull(defaultProperty);
Assert.That(actualProperty.GetValue(desc, null), Is.EqualTo(defaultProperty.GetValue(ServiceDescriptor.Defaults, null)));
Assert.Equal(defaultProperty.GetValue(ServiceDescriptor.Defaults, null), actualProperty.GetValue(desc, null));
}
public static void AssertPropertyIsDefault(ServiceDescriptor desc, List<string> properties)

View File

@ -1,16 +0,0 @@
using NUnit.Framework;
using winsw;
namespace winswTests.Util
{
internal static class TestHelper
{
internal static void RequireProcessElevated()
{
if (!Program.IsProcessElevated())
{
Assert.Ignore();
}
}
}
}

View File

@ -13,8 +13,11 @@
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.6.1" />
<PackageReference Include="NUnit" Version="3.12.0" />
<PackageReference Include="NUnit3TestAdapter" Version="3.16.1" />
<PackageReference Include="xunit" Version="2.4.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.2">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' != 'netcoreapp3.1'">