mirror of https://github.com/winsw/winsw
Simplify syntax
parent
466b5264e1
commit
941e67d08c
|
@ -91,21 +91,19 @@ namespace winsw
|
|||
|
||||
try
|
||||
{
|
||||
using (var tr = new StreamReader(file, Encoding.UTF8))
|
||||
using var tr = new StreamReader(file, Encoding.UTF8);
|
||||
string? line;
|
||||
while ((line = tr.ReadLine()) != null)
|
||||
{
|
||||
string? line;
|
||||
while ((line = tr.ReadLine()) != null)
|
||||
LogEvent("Handling copy: " + line);
|
||||
string[] tokens = line.Split('>');
|
||||
if (tokens.Length > 2)
|
||||
{
|
||||
LogEvent("Handling copy: " + line);
|
||||
string[] tokens = line.Split('>');
|
||||
if (tokens.Length > 2)
|
||||
{
|
||||
LogEvent("Too many delimiters in " + line);
|
||||
continue;
|
||||
}
|
||||
|
||||
CopyFile(tokens[0], tokens[1]);
|
||||
LogEvent("Too many delimiters in " + line);
|
||||
continue;
|
||||
}
|
||||
|
||||
CopyFile(tokens[0], tokens[1]);
|
||||
}
|
||||
}
|
||||
finally
|
||||
|
@ -186,7 +184,7 @@ namespace winsw
|
|||
}
|
||||
}
|
||||
|
||||
protected override void OnStart(string[] _)
|
||||
protected override void OnStart(string[] args)
|
||||
{
|
||||
_envs = _descriptor.EnvironmentVariables;
|
||||
// TODO: Disabled according to security concerns in https://github.com/kohsuke/winsw/issues/54
|
||||
|
@ -490,11 +488,11 @@ namespace winsw
|
|||
bool isCLIMode = _args.Length > 0;
|
||||
|
||||
// If descriptor is not specified, initialize the new one (and load configs from there)
|
||||
var d = descriptor ?? new ServiceDescriptor();
|
||||
descriptor ??= new ServiceDescriptor();
|
||||
|
||||
// Configure the wrapper-internal logging.
|
||||
// STDIN and STDOUT of the child process will be handled independently.
|
||||
InitLoggers(d, isCLIMode);
|
||||
InitLoggers(descriptor, isCLIMode);
|
||||
|
||||
if (isCLIMode) // CLI mode, in-service mode otherwise
|
||||
{
|
||||
|
@ -502,7 +500,7 @@ namespace winsw
|
|||
|
||||
// Get service info for the future use
|
||||
Win32Services svc = new WmiRoot().GetCollection<Win32Services>();
|
||||
Win32Service s = svc.Select(d.Id);
|
||||
Win32Service s = svc.Select(descriptor.Id);
|
||||
|
||||
var args = new List<string>(Array.AsReadOnly(_args));
|
||||
if (args[0] == "/redirect")
|
||||
|
@ -530,14 +528,14 @@ namespace winsw
|
|||
args[0] = args[0].ToLower();
|
||||
if (args[0] == "install")
|
||||
{
|
||||
Log.Info("Installing the service with id '" + d.Id + "'");
|
||||
Log.Info("Installing the service with id '" + descriptor.Id + "'");
|
||||
|
||||
// Check if the service exists
|
||||
if (s != null)
|
||||
{
|
||||
Console.WriteLine("Service with id '" + d.Id + "' already exists");
|
||||
Console.WriteLine("Service with id '" + descriptor.Id + "' already exists");
|
||||
Console.WriteLine("To install the service, delete the existing one or change service Id in the configuration file");
|
||||
throw new Exception("Installation failure: Service with id '" + d.Id + "' already exists");
|
||||
throw new Exception("Installation failure: Service with id '" + descriptor.Id + "' already exists");
|
||||
}
|
||||
|
||||
string? username = null;
|
||||
|
@ -561,11 +559,11 @@ namespace winsw
|
|||
}
|
||||
else
|
||||
{
|
||||
if (d.HasServiceAccount())
|
||||
if (descriptor.HasServiceAccount())
|
||||
{
|
||||
username = d.ServiceAccountUser;
|
||||
password = d.ServiceAccountPassword;
|
||||
setallowlogonasaserviceright = d.AllowServiceAcountLogonRight;
|
||||
username = descriptor.ServiceAccountUser;
|
||||
password = descriptor.ServiceAccountPassword;
|
||||
setallowlogonasaserviceright = descriptor.AllowServiceAcountLogonRight;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -575,16 +573,16 @@ namespace winsw
|
|||
}
|
||||
|
||||
svc.Create(
|
||||
d.Id,
|
||||
d.Caption,
|
||||
"\"" + d.ExecutablePath + "\"",
|
||||
descriptor.Id,
|
||||
descriptor.Caption,
|
||||
"\"" + descriptor.ExecutablePath + "\"",
|
||||
ServiceType.OwnProcess,
|
||||
ErrorControl.UserNotified,
|
||||
d.StartMode,
|
||||
d.Interactive,
|
||||
descriptor.StartMode,
|
||||
descriptor.Interactive,
|
||||
username,
|
||||
password,
|
||||
d.ServiceDependencies);
|
||||
descriptor.ServiceDependencies);
|
||||
|
||||
// update the description
|
||||
/* Somehow this doesn't work, even though it doesn't report an error
|
||||
|
@ -594,29 +592,30 @@ namespace winsw
|
|||
*/
|
||||
|
||||
// so using a classic method to set the description. Ugly.
|
||||
Registry.LocalMachine.OpenSubKey("System").OpenSubKey("CurrentControlSet").OpenSubKey("Services")
|
||||
.OpenSubKey(d.Id, true).SetValue("Description", d.Description);
|
||||
Registry.LocalMachine
|
||||
.OpenSubKey("System")
|
||||
.OpenSubKey("CurrentControlSet")
|
||||
.OpenSubKey("Services")
|
||||
.OpenSubKey(descriptor.Id, true)
|
||||
.SetValue("Description", descriptor.Description);
|
||||
|
||||
var actions = d.FailureActions;
|
||||
var isDelayedAutoStart = d.StartMode == StartMode.Automatic && d.DelayedAutoStart;
|
||||
var actions = descriptor.FailureActions;
|
||||
var isDelayedAutoStart = descriptor.StartMode == StartMode.Automatic && descriptor.DelayedAutoStart;
|
||||
if (actions.Count > 0 || isDelayedAutoStart)
|
||||
{
|
||||
using (ServiceManager scm = new ServiceManager())
|
||||
{
|
||||
using (Service sc = scm.Open(d.Id))
|
||||
{
|
||||
// Delayed auto start
|
||||
if (isDelayedAutoStart)
|
||||
{
|
||||
sc.SetDelayedAutoStart(true);
|
||||
}
|
||||
using ServiceManager scm = new ServiceManager();
|
||||
using Service sc = scm.Open(descriptor.Id);
|
||||
|
||||
// Set the failure actions
|
||||
if (actions.Count > 0)
|
||||
{
|
||||
sc.ChangeConfig(d.ResetFailureAfter, actions);
|
||||
}
|
||||
}
|
||||
// Delayed auto start
|
||||
if (isDelayedAutoStart)
|
||||
{
|
||||
sc.SetDelayedAutoStart(true);
|
||||
}
|
||||
|
||||
// Set the failure actions
|
||||
if (actions.Count > 0)
|
||||
{
|
||||
sc.ChangeConfig(descriptor.ResetFailureAfter, actions);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -625,10 +624,10 @@ namespace winsw
|
|||
|
||||
if (args[0] == "uninstall")
|
||||
{
|
||||
Log.Info("Uninstalling the service with id '" + d.Id + "'");
|
||||
Log.Info("Uninstalling the service with id '" + descriptor.Id + "'");
|
||||
if (s == null)
|
||||
{
|
||||
Log.Warn("The service with id '" + d.Id + "' does not exist. Nothing to uninstall");
|
||||
Log.Warn("The service with id '" + descriptor.Id + "' does not exist. Nothing to uninstall");
|
||||
return; // there's no such service, so consider it already uninstalled
|
||||
}
|
||||
|
||||
|
@ -636,7 +635,7 @@ namespace winsw
|
|||
{
|
||||
// We could fail the opeartion here, but it would be an incompatible change.
|
||||
// So it is just a warning
|
||||
Log.Warn("The service with id '" + d.Id + "' is running. It may be impossible to uninstall it");
|
||||
Log.Warn("The service with id '" + descriptor.Id + "' is running. It may be impossible to uninstall it");
|
||||
}
|
||||
|
||||
try
|
||||
|
@ -647,7 +646,7 @@ namespace winsw
|
|||
{
|
||||
if (e.ErrorCode == ReturnValue.ServiceMarkedForDeletion)
|
||||
{
|
||||
Log.Error("Failed to uninstall the service with id '" + d.Id + "'"
|
||||
Log.Error("Failed to uninstall the service with id '" + descriptor.Id + "'"
|
||||
+ ". It has been marked for deletion.");
|
||||
|
||||
// TODO: change the default behavior to Error?
|
||||
|
@ -655,7 +654,7 @@ namespace winsw
|
|||
}
|
||||
else
|
||||
{
|
||||
Log.Fatal("Failed to uninstall the service with id '" + d.Id + "'. WMI Error code is '" + e.ErrorCode + "'");
|
||||
Log.Fatal("Failed to uninstall the service with id '" + descriptor.Id + "'. WMI Error code is '" + e.ErrorCode + "'");
|
||||
}
|
||||
|
||||
throw e;
|
||||
|
@ -666,7 +665,7 @@ namespace winsw
|
|||
|
||||
if (args[0] == "start")
|
||||
{
|
||||
Log.Info("Starting the service with id '" + d.Id + "'");
|
||||
Log.Info("Starting the service with id '" + descriptor.Id + "'");
|
||||
if (s == null)
|
||||
ThrowNoSuchService();
|
||||
|
||||
|
@ -676,7 +675,7 @@ namespace winsw
|
|||
|
||||
if (args[0] == "stop")
|
||||
{
|
||||
Log.Info("Stopping the service with id '" + d.Id + "'");
|
||||
Log.Info("Stopping the service with id '" + descriptor.Id + "'");
|
||||
if (s == null)
|
||||
ThrowNoSuchService();
|
||||
|
||||
|
@ -686,7 +685,7 @@ namespace winsw
|
|||
|
||||
if (args[0] == "restart")
|
||||
{
|
||||
Log.Info("Restarting the service with id '" + d.Id + "'");
|
||||
Log.Info("Restarting the service with id '" + descriptor.Id + "'");
|
||||
if (s == null)
|
||||
ThrowNoSuchService();
|
||||
|
||||
|
@ -696,7 +695,7 @@ namespace winsw
|
|||
while (s.Started)
|
||||
{
|
||||
Thread.Sleep(1000);
|
||||
s = svc.Select(d.Id);
|
||||
s = svc.Select(descriptor.Id);
|
||||
}
|
||||
|
||||
s.StartService();
|
||||
|
@ -705,12 +704,12 @@ namespace winsw
|
|||
|
||||
if (args[0] == "restart!")
|
||||
{
|
||||
Log.Info("Restarting the service with id '" + d.Id + "'");
|
||||
Log.Info("Restarting the service with id '" + descriptor.Id + "'");
|
||||
|
||||
// run restart from another process group. see README.md for why this is useful.
|
||||
|
||||
STARTUPINFO si = default;
|
||||
bool result = Kernel32.CreateProcess(null, d.ExecutablePath + " restart", IntPtr.Zero, IntPtr.Zero, false, 0x200/*CREATE_NEW_PROCESS_GROUP*/, IntPtr.Zero, null, ref si, out _);
|
||||
bool result = Kernel32.CreateProcess(null, descriptor.ExecutablePath + " restart", IntPtr.Zero, IntPtr.Zero, false, 0x200/*CREATE_NEW_PROCESS_GROUP*/, IntPtr.Zero, null, ref si, out _);
|
||||
if (!result)
|
||||
{
|
||||
throw new Exception("Failed to invoke restart: " + Marshal.GetLastWin32Error());
|
||||
|
@ -721,7 +720,7 @@ namespace winsw
|
|||
|
||||
if (args[0] == "status")
|
||||
{
|
||||
Log.Debug("User requested the status of the process with id '" + d.Id + "'");
|
||||
Log.Debug("User requested the status of the process with id '" + descriptor.Id + "'");
|
||||
if (s == null)
|
||||
Console.WriteLine("NonExistent");
|
||||
else if (s.Started)
|
||||
|
@ -734,7 +733,7 @@ namespace winsw
|
|||
|
||||
if (args[0] == "test")
|
||||
{
|
||||
WrapperService wsvc = new WrapperService(d);
|
||||
WrapperService wsvc = new WrapperService(descriptor);
|
||||
wsvc.OnStart(args.ToArray());
|
||||
Thread.Sleep(1000);
|
||||
wsvc.OnStop();
|
||||
|
@ -743,7 +742,7 @@ namespace winsw
|
|||
|
||||
if (args[0] == "testwait")
|
||||
{
|
||||
WrapperService wsvc = new WrapperService(d);
|
||||
WrapperService wsvc = new WrapperService(descriptor);
|
||||
wsvc.OnStart(args.ToArray());
|
||||
Console.WriteLine("Press any key to stop the service...");
|
||||
Console.Read();
|
||||
|
@ -773,7 +772,7 @@ namespace winsw
|
|||
Log.Info("Starting ServiceWrapper in the service mode");
|
||||
}
|
||||
|
||||
Run(new WrapperService(d));
|
||||
Run(new WrapperService(descriptor));
|
||||
}
|
||||
|
||||
private static void InitLoggers(ServiceDescriptor d, bool enableCLILogging)
|
||||
|
@ -839,10 +838,9 @@ namespace winsw
|
|||
private static string ReadPassword()
|
||||
{
|
||||
StringBuilder buf = new StringBuilder();
|
||||
ConsoleKeyInfo key;
|
||||
while (true)
|
||||
{
|
||||
key = Console.ReadKey(true);
|
||||
ConsoleKeyInfo key = Console.ReadKey(true);
|
||||
if (key.Key == ConsoleKey.Enter)
|
||||
{
|
||||
return buf.ToString();
|
||||
|
@ -870,7 +868,7 @@ namespace winsw
|
|||
printAvailableCommandsInfo();
|
||||
Console.WriteLine();
|
||||
Console.WriteLine("Extra options:");
|
||||
Console.WriteLine("- '/redirect' - redirect the wrapper's STDOUT and STDERR to the specified file");
|
||||
Console.WriteLine(" /redirect redirect the wrapper's STDOUT and STDERR to the specified file");
|
||||
Console.WriteLine();
|
||||
printVersion();
|
||||
Console.WriteLine("More info: https://github.com/kohsuke/winsw");
|
||||
|
@ -880,18 +878,19 @@ namespace winsw
|
|||
// TODO: Rework to enum in winsw-2.0
|
||||
private static void printAvailableCommandsInfo()
|
||||
{
|
||||
Console.WriteLine("Available commands:");
|
||||
Console.WriteLine("- 'install' - install the service to Windows Service Controller");
|
||||
Console.WriteLine("- 'uninstall' - uninstall the service");
|
||||
Console.WriteLine("- 'start' - start the service (must be installed before)");
|
||||
Console.WriteLine("- 'stop' - stop the service");
|
||||
Console.WriteLine("- 'restart' - restart the service");
|
||||
Console.WriteLine("- 'restart!' - self-restart (can be called from child processes)");
|
||||
Console.WriteLine("- 'status' - check the current status of the service");
|
||||
Console.WriteLine("- 'test' - check if the service can be started and then stopped");
|
||||
Console.WriteLine("- 'testwait' - starts the service and waits until a key is pressed then stops the service");
|
||||
Console.WriteLine("- 'version' - print the version info");
|
||||
Console.WriteLine("- 'help' - print the help info (aliases: -h,--help,-?,/?)");
|
||||
Console.WriteLine(
|
||||
@"Available commands:
|
||||
install install the service to Windows Service Controller
|
||||
uninstall uninstall the service
|
||||
start start the service (must be installed before)
|
||||
stop stop the service
|
||||
restart restart the service
|
||||
restart! self-restart (can be called from child processes)
|
||||
status check the current status of the service
|
||||
test check if the service can be started and then stopped
|
||||
testwait starts the service and waits until a key is pressed then stops the service
|
||||
version print the version info
|
||||
help print the help info (aliases: -h,--help,-?,/?)");
|
||||
}
|
||||
|
||||
private static void printVersion()
|
||||
|
|
|
@ -439,9 +439,9 @@ namespace winsw
|
|||
// Next day so check if file can be zipped
|
||||
ZipFiles(baseDirectory, extension, baseFileName);
|
||||
}
|
||||
catch (Exception et)
|
||||
catch (Exception ex)
|
||||
{
|
||||
EventLogger.LogEvent(string.Format("Failed to to trigger auto roll at time event due to: {0}", et.Message));
|
||||
EventLogger.LogEvent($"Failed to to trigger auto roll at time event due to: {ex.Message}");
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
@ -503,7 +503,7 @@ namespace winsw
|
|||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
EventLogger.LogEvent(string.Format("Failed to roll size time log: {0}", e.Message));
|
||||
EventLogger.LogEvent($"Failed to roll size time log: {e.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -635,12 +635,12 @@ namespace winsw
|
|||
}
|
||||
else
|
||||
{
|
||||
throw new IOException(string.Format("File {0} does not follow the pattern provided", f));
|
||||
throw new IOException($"File {f} does not follow the pattern provided");
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new IOException(string.Format("Failed to process file {0} due to error {1}", f, e.Message), e);
|
||||
throw new IOException($"Failed to process file {f} due to error {e.Message}", e);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -245,7 +245,6 @@ namespace winsw.Native
|
|||
|
||||
// initialize an unicode-string for the privilege name
|
||||
LSA_UNICODE_STRING[] userRights = new LSA_UNICODE_STRING[1];
|
||||
userRights[0] = default;
|
||||
userRights[0].Buffer = Marshal.StringToHGlobalUni(privilegeName);
|
||||
userRights[0].Length = (ushort)(privilegeName.Length * UnicodeEncoding.CharSize);
|
||||
userRights[0].MaximumLength = (ushort)((privilegeName.Length + 1) * UnicodeEncoding.CharSize);
|
||||
|
|
|
@ -64,35 +64,30 @@ namespace winsw
|
|||
return PeriodicityType.ERRONEOUS;
|
||||
}
|
||||
|
||||
private DateTime nextTriggeringTime(DateTime input, long increment)
|
||||
private DateTime nextTriggeringTime(DateTime input, long increment) => periodicityType switch
|
||||
{
|
||||
DateTime output;
|
||||
switch (periodicityType)
|
||||
{
|
||||
case PeriodicityType.TOP_OF_MILLISECOND:
|
||||
output = new DateTime(input.Year, input.Month, input.Day, input.Hour, input.Minute, input.Second, input.Millisecond);
|
||||
output = output.AddMilliseconds(increment);
|
||||
return output;
|
||||
case PeriodicityType.TOP_OF_SECOND:
|
||||
output = new DateTime(input.Year, input.Month, input.Day, input.Hour, input.Minute, input.Second);
|
||||
output = output.AddSeconds(increment);
|
||||
return output;
|
||||
case PeriodicityType.TOP_OF_MINUTE:
|
||||
output = new DateTime(input.Year, input.Month, input.Day, input.Hour, input.Minute, 0);
|
||||
output = output.AddMinutes(increment);
|
||||
return output;
|
||||
case PeriodicityType.TOP_OF_HOUR:
|
||||
output = new DateTime(input.Year, input.Month, input.Day, input.Hour, 0, 0);
|
||||
output = output.AddHours(increment);
|
||||
return output;
|
||||
case PeriodicityType.TOP_OF_DAY:
|
||||
output = new DateTime(input.Year, input.Month, input.Day);
|
||||
output = output.AddDays(increment);
|
||||
return output;
|
||||
default:
|
||||
throw new Exception("invalid periodicity type: " + periodicityType);
|
||||
}
|
||||
}
|
||||
PeriodicityType.TOP_OF_MILLISECOND =>
|
||||
new DateTime(input.Year, input.Month, input.Day, input.Hour, input.Minute, input.Second, input.Millisecond)
|
||||
.AddMilliseconds(increment),
|
||||
|
||||
PeriodicityType.TOP_OF_SECOND =>
|
||||
new DateTime(input.Year, input.Month, input.Day, input.Hour, input.Minute, input.Second)
|
||||
.AddSeconds(increment),
|
||||
|
||||
PeriodicityType.TOP_OF_MINUTE =>
|
||||
new DateTime(input.Year, input.Month, input.Day, input.Hour, input.Minute, 0)
|
||||
.AddMinutes(increment),
|
||||
|
||||
PeriodicityType.TOP_OF_HOUR =>
|
||||
new DateTime(input.Year, input.Month, input.Day, input.Hour, 0, 0)
|
||||
.AddHours(increment),
|
||||
|
||||
PeriodicityType.TOP_OF_DAY =>
|
||||
new DateTime(input.Year, input.Month, input.Day)
|
||||
.AddDays(increment),
|
||||
|
||||
_ => throw new Exception("invalid periodicity type: " + periodicityType),
|
||||
};
|
||||
|
||||
public PeriodicityType periodicityType { get; set; }
|
||||
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Generic;
|
||||
using System.Xml;
|
||||
using log4net;
|
||||
using winsw.Extensions;
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
using System;
|
||||
using System.Xml;
|
||||
using System.Xml;
|
||||
using winsw.Util;
|
||||
|
||||
namespace winsw.Plugins.SharedDirectoryMapper
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace winsw.Plugins.SharedDirectoryMapper
|
||||
{
|
||||
|
|
|
@ -144,10 +144,7 @@ namespace winswTests
|
|||
.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), () =>
|
||||
{
|
||||
var d = GetSingleEntry(sd);
|
||||
});
|
||||
ExceptionHelper.AssertFails("Cannot parse <auth> Enum value from string 'digest'", typeof(InvalidDataException), () => _ = GetSingleEntry(sd));
|
||||
}
|
||||
|
||||
private Download GetSingleEntry(ServiceDescriptor sd)
|
||||
|
@ -163,10 +160,7 @@ namespace winswTests
|
|||
.WithDownload(download)
|
||||
.ToServiceDescriptor(true);
|
||||
|
||||
ExceptionHelper.assertFails(expectedMessagePart, expectedExceptionType ?? typeof(InvalidDataException), () =>
|
||||
{
|
||||
var d = GetSingleEntry(sd);
|
||||
});
|
||||
ExceptionHelper.AssertFails(expectedMessagePart, expectedExceptionType ?? typeof(InvalidDataException), () => _ = GetSingleEntry(sd));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,27 +16,27 @@ namespace winswTests.Extensions
|
|||
{
|
||||
ServiceDescriptor _testServiceDescriptor;
|
||||
|
||||
string testExtension = GetExtensionClassNameWithAssembly(typeof(RunawayProcessKillerExtension));
|
||||
readonly string testExtension = GetExtensionClassNameWithAssembly(typeof(RunawayProcessKillerExtension));
|
||||
|
||||
[SetUp]
|
||||
public void SetUp()
|
||||
{
|
||||
string seedXml = "<?xml version=\"1.0\" encoding=\"utf-8\" ?>"
|
||||
+ "<service> "
|
||||
+ " <id>SERVICE_NAME</id> "
|
||||
+ " <name>Jenkins Slave</name> "
|
||||
+ " <description>This service runs a slave for Jenkins continuous integration system.</description> "
|
||||
+ " <executable>C:\\Program Files\\Java\\jre7\\bin\\java.exe</executable> "
|
||||
+ " <arguments>-Xrs -jar \\\"%BASE%\\slave.jar\\\" -jnlpUrl ...</arguments> "
|
||||
+ " <logmode>rotate</logmode> "
|
||||
+ " <extensions> "
|
||||
+ " <extension enabled=\"true\" className=\"" + testExtension + "\" id=\"killRunawayProcess\"> "
|
||||
+ " <pidfile>foo/bar/pid.txt</pidfile>"
|
||||
+ " <stopTimeout>5000</stopTimeout> "
|
||||
+ " <stopParentFirst>true</stopParentFirst>"
|
||||
+ " </extension> "
|
||||
+ " </extensions> "
|
||||
+ "</service>";
|
||||
string seedXml =
|
||||
$@"<service>
|
||||
<id>SERVICE_NAME</id>
|
||||
<name>Jenkins Slave</name>
|
||||
<description>This service runs a slave for Jenkins continuous integration system.</description>
|
||||
<executable>C:\Program Files\Java\jre7\bin\java.exe</executable>
|
||||
<arguments>-Xrs -jar \""%BASE%\slave.jar\"" -jnlpUrl ...</arguments>
|
||||
<logmode>rotate</logmode>
|
||||
<extensions>
|
||||
<extension enabled=""true"" className=""{testExtension}"" id=""killRunawayProcess"">
|
||||
<pidfile>foo/bar/pid.txt</pidfile>
|
||||
<stopTimeout>5000</stopTimeout>
|
||||
<stopParentFirst>true</stopParentFirst>
|
||||
</extension>
|
||||
</extensions>
|
||||
</service>";
|
||||
_testServiceDescriptor = ServiceDescriptor.FromXML(seedXml);
|
||||
}
|
||||
|
||||
|
|
|
@ -10,34 +10,34 @@ namespace winswTests.Extensions
|
|||
{
|
||||
ServiceDescriptor _testServiceDescriptor;
|
||||
|
||||
string testExtension = GetExtensionClassNameWithAssembly(typeof(SharedDirectoryMapper));
|
||||
readonly string testExtension = GetExtensionClassNameWithAssembly(typeof(SharedDirectoryMapper));
|
||||
|
||||
[SetUp]
|
||||
public void SetUp()
|
||||
{
|
||||
string seedXml = "<?xml version=\"1.0\" encoding=\"utf-8\" ?>"
|
||||
+ "<service> "
|
||||
+ " <id>SERVICE_NAME</id> "
|
||||
+ " <name>Jenkins Slave</name> "
|
||||
+ " <description>This service runs a slave for Jenkins continuous integration system.</description> "
|
||||
+ " <executable>C:\\Program Files\\Java\\jre7\\bin\\java.exe</executable> "
|
||||
+ " <arguments>-Xrs -jar \\\"%BASE%\\slave.jar\\\" -jnlpUrl ...</arguments> "
|
||||
+ " <logmode>rotate</logmode> "
|
||||
+ " <extensions> "
|
||||
+ " <extension enabled=\"true\" className=\"" + testExtension + "\" id=\"mapNetworDirs\"> "
|
||||
+ " <mapping> "
|
||||
+ " <map enabled=\"false\" label=\"N:\" uncpath=\"\\\\UNC\"/> "
|
||||
+ " <map enabled=\"false\" label=\"M:\" uncpath=\"\\\\UNC2\"/> "
|
||||
+ " </mapping> "
|
||||
+ " </extension> "
|
||||
+ " <extension enabled=\"true\" className=\"" + testExtension + "\" id=\"mapNetworDirs2\"> "
|
||||
+ " <mapping> "
|
||||
+ " <map enabled=\"false\" label=\"X:\" uncpath=\"\\\\UNC\"/> "
|
||||
+ " <map enabled=\"false\" label=\"Y:\" uncpath=\"\\\\UNC2\"/> "
|
||||
+ " </mapping> "
|
||||
+ " </extension> "
|
||||
+ " </extensions> "
|
||||
+ "</service>";
|
||||
string seedXml =
|
||||
$@"<service>
|
||||
<id>SERVICE_NAME</id>
|
||||
<name>Jenkins Slave</name>
|
||||
<description>This service runs a slave for Jenkins continuous integration system.</description>
|
||||
<executable>C:\Program Files\Java\jre7\bin\java.exe</executable>
|
||||
<arguments>-Xrs -jar \""%BASE%\slave.jar\"" -jnlpUrl ...</arguments>
|
||||
<logmode>rotate</logmode>
|
||||
<extensions>
|
||||
<extension enabled=""true"" className=""{testExtension}"" id=""mapNetworDirs"">
|
||||
<mapping>
|
||||
<map enabled=""false"" label=""N:"" uncpath=""\\UNC""/>
|
||||
<map enabled=""false"" label=""M:"" uncpath=""\\UNC2""/>
|
||||
</mapping>
|
||||
</extension>
|
||||
<extension enabled=""true"" className=""{testExtension}"" id=""mapNetworDirs2"">
|
||||
<mapping>
|
||||
<map enabled=""false"" label=""X:"" uncpath=""\\UNC""/>
|
||||
<map enabled=""false"" label=""Y:"" uncpath=""\\UNC2""/>
|
||||
</mapping>
|
||||
</extension>
|
||||
</extensions>
|
||||
</service>";
|
||||
_testServiceDescriptor = ServiceDescriptor.FromXML(seedXml);
|
||||
}
|
||||
|
||||
|
|
|
@ -21,24 +21,23 @@ namespace winswTests
|
|||
[SetUp]
|
||||
public void SetUp()
|
||||
{
|
||||
const string seedXml = "<service>"
|
||||
+ "<id>service.exe</id>"
|
||||
+ "<name>Service</name>"
|
||||
+ "<description>The service.</description>"
|
||||
+ "<executable>node.exe</executable>"
|
||||
+ "<arguments>My Arguments</arguments>"
|
||||
+ "<logmode>rotate</logmode>"
|
||||
+ "<serviceaccount>"
|
||||
+ "<domain>" + Domain + "</domain>"
|
||||
+ "<user>" + Username + "</user>"
|
||||
+ "<password>" + Password + "</password>"
|
||||
+ "<allowservicelogon>" + AllowServiceAccountLogonRight + "</allowservicelogon>"
|
||||
+ "</serviceaccount>"
|
||||
+ "<workingdirectory>"
|
||||
+ ExpectedWorkingDirectory
|
||||
+ "</workingdirectory>"
|
||||
+ @"<logpath>C:\logs</logpath>"
|
||||
+ "</service>";
|
||||
string seedXml =
|
||||
$@"<service>
|
||||
<id>service.exe</id>
|
||||
<name>Service</name>
|
||||
<description>The service.</description>
|
||||
<executable>node.exe</executable>
|
||||
<arguments>My Arguments</arguments>
|
||||
<logmode>rotate</logmode>
|
||||
<serviceaccount>
|
||||
<domain>{Domain}</domain>
|
||||
<user>{Username}</user>
|
||||
<password>{Password}</password>
|
||||
<allowservicelogon>{AllowServiceAccountLogonRight}</allowservicelogon>
|
||||
</serviceaccount>
|
||||
<workingdirectory>{ExpectedWorkingDirectory}</workingdirectory>
|
||||
<logpath>C:\logs</logpath>
|
||||
</service>";
|
||||
_extendedServiceDescriptor = ServiceDescriptor.FromXML(seedXml);
|
||||
}
|
||||
|
||||
|
@ -51,54 +50,52 @@ namespace winswTests
|
|||
[Test]
|
||||
public void IncorrectStartMode()
|
||||
{
|
||||
const string SeedXml = "<service>"
|
||||
+ "<id>service.exe</id>"
|
||||
+ "<name>Service</name>"
|
||||
+ "<description>The service.</description>"
|
||||
+ "<executable>node.exe</executable>"
|
||||
+ "<arguments>My Arguments</arguments>"
|
||||
+ "<startmode>rotate</startmode>"
|
||||
+ "<logmode>rotate</logmode>"
|
||||
+ "<serviceaccount>"
|
||||
+ "<domain>" + Domain + "</domain>"
|
||||
+ "<user>" + Username + "</user>"
|
||||
+ "<password>" + Password + "</password>"
|
||||
+ "<allowservicelogon>" + AllowServiceAccountLogonRight + "</allowservicelogon>"
|
||||
+ "</serviceaccount>"
|
||||
+ "<workingdirectory>"
|
||||
+ ExpectedWorkingDirectory
|
||||
+ "</workingdirectory>"
|
||||
+ @"<logpath>C:\logs</logpath>"
|
||||
+ "</service>";
|
||||
string seedXml =
|
||||
$@"<service>
|
||||
<id>service.exe</id>
|
||||
<name>Service</name>
|
||||
<description>The service.</description>
|
||||
<executable>node.exe</executable>
|
||||
<arguments>My Arguments</arguments>
|
||||
<startmode>rotate</startmode>
|
||||
<logmode>rotate</logmode>
|
||||
<serviceaccount>
|
||||
<domain>{Domain}</domain>
|
||||
<user>{Username}</user>
|
||||
<password>{Password}</password>
|
||||
<allowservicelogon>{AllowServiceAccountLogonRight}</allowservicelogon>
|
||||
</serviceaccount>
|
||||
<workingdirectory>{ExpectedWorkingDirectory}</workingdirectory>
|
||||
<logpath>C:\logs</logpath>
|
||||
</service>";
|
||||
|
||||
_extendedServiceDescriptor = ServiceDescriptor.FromXML(SeedXml);
|
||||
Assert.Throws(typeof(ArgumentException), () => _ = _extendedServiceDescriptor.StartMode);
|
||||
_extendedServiceDescriptor = ServiceDescriptor.FromXML(seedXml);
|
||||
Assert.Throws<ArgumentException>(() => _ = _extendedServiceDescriptor.StartMode);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ChangedStartMode()
|
||||
{
|
||||
const string SeedXml = "<service>"
|
||||
+ "<id>service.exe</id>"
|
||||
+ "<name>Service</name>"
|
||||
+ "<description>The service.</description>"
|
||||
+ "<executable>node.exe</executable>"
|
||||
+ "<arguments>My Arguments</arguments>"
|
||||
+ "<startmode>manual</startmode>"
|
||||
+ "<logmode>rotate</logmode>"
|
||||
+ "<serviceaccount>"
|
||||
+ "<domain>" + Domain + "</domain>"
|
||||
+ "<user>" + Username + "</user>"
|
||||
+ "<password>" + Password + "</password>"
|
||||
+ "<allowservicelogon>" + AllowServiceAccountLogonRight + "</allowservicelogon>"
|
||||
+ "</serviceaccount>"
|
||||
+ "<workingdirectory>"
|
||||
+ ExpectedWorkingDirectory
|
||||
+ "</workingdirectory>"
|
||||
+ @"<logpath>C:\logs</logpath>"
|
||||
+ "</service>";
|
||||
string seedXml =
|
||||
$@"<service>
|
||||
<id>service.exe</id>
|
||||
<name>Service</name>
|
||||
<description>The service.</description>
|
||||
<executable>node.exe</executable>
|
||||
<arguments>My Arguments</arguments>
|
||||
<startmode>manual</startmode>
|
||||
<logmode>rotate</logmode>
|
||||
<serviceaccount>
|
||||
<domain>{Domain}</domain>
|
||||
<user>{Username}</user>
|
||||
<password>{Password}</password>
|
||||
<allowservicelogon>{AllowServiceAccountLogonRight}</allowservicelogon>
|
||||
</serviceaccount>
|
||||
<workingdirectory>{ExpectedWorkingDirectory}</workingdirectory>
|
||||
<logpath>C:\logs</logpath>
|
||||
</service>";
|
||||
|
||||
_extendedServiceDescriptor = ServiceDescriptor.FromXML(SeedXml);
|
||||
_extendedServiceDescriptor = ServiceDescriptor.FromXML(seedXml);
|
||||
Assert.That(_extendedServiceDescriptor.StartMode, Is.EqualTo(StartMode.Manual));
|
||||
}
|
||||
|
||||
|
|
|
@ -9,18 +9,17 @@ namespace winswTests.Util
|
|||
/// </summary>
|
||||
public static class CLITestHelper
|
||||
{
|
||||
private const string SeedXml = "<service>"
|
||||
+ "<id>service.exe</id>"
|
||||
+ "<name>Service</name>"
|
||||
+ "<description>The service.</description>"
|
||||
+ "<executable>node.exe</executable>"
|
||||
+ "<arguments>My Arguments</arguments>"
|
||||
+ "<logmode>rotate</logmode>"
|
||||
+ "<workingdirectory>"
|
||||
+ @"C:\winsw\workdir"
|
||||
+ "</workingdirectory>"
|
||||
+ @"<logpath>C:\winsw\logs</logpath>"
|
||||
+ "</service>";
|
||||
private const string SeedXml =
|
||||
@"<service>
|
||||
<id>service.exe</id>
|
||||
<name>Service</name>
|
||||
<description>The service.</description>
|
||||
<executable>node.exe</executable>
|
||||
<arguments>My Arguments</arguments>
|
||||
<logmode>rotate</logmode>
|
||||
<workingdirectory>C:\winsw\workdir</workingdirectory>
|
||||
<logpath>C:\winsw\logs</logpath>
|
||||
</service>";
|
||||
|
||||
private static readonly ServiceDescriptor DefaultServiceDescriptor = ServiceDescriptor.FromXML(SeedXml);
|
||||
|
||||
|
@ -33,15 +32,13 @@ namespace winswTests.Util
|
|||
/// <exception cref="Exception">Command failure</exception>
|
||||
public static string CLITest(string[] args, ServiceDescriptor descriptor = null)
|
||||
{
|
||||
using (StringWriter sw = new StringWriter())
|
||||
{
|
||||
TextWriter tmp = Console.Out;
|
||||
Console.SetOut(sw);
|
||||
WrapperService.Run(args, descriptor ?? DefaultServiceDescriptor);
|
||||
Console.SetOut(tmp);
|
||||
Console.Write(sw.ToString());
|
||||
return sw.ToString();
|
||||
}
|
||||
using StringWriter sw = new StringWriter();
|
||||
TextWriter tmp = Console.Out;
|
||||
Console.SetOut(sw);
|
||||
WrapperService.Run(args, descriptor ?? DefaultServiceDescriptor);
|
||||
Console.SetOut(tmp);
|
||||
Console.Write(sw.ToString());
|
||||
return sw.ToString();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -20,7 +20,7 @@ namespace winswTests.Util
|
|||
public string XMLComment { get; set; }
|
||||
public List<string> ExtensionXmls { get; private set; }
|
||||
|
||||
private List<string> configEntries;
|
||||
private readonly List<string> configEntries;
|
||||
|
||||
// TODO: Switch to the initializer?
|
||||
private ConfigXmlBuilder()
|
||||
|
|
|
@ -5,28 +5,10 @@ namespace winswTests.Util
|
|||
{
|
||||
class ExceptionHelper
|
||||
{
|
||||
public static void assertFails(string expectedMessagePart, Type expectedExceptionType, ExceptionHelperExecutionBody body)
|
||||
public static void AssertFails(string expectedMessagePart, Type expectedExceptionType, TestDelegate body)
|
||||
{
|
||||
try
|
||||
{
|
||||
body();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.Out.WriteLine("Caught exception: " + ex);
|
||||
Assert.That(ex, Is.InstanceOf(expectedExceptionType ?? typeof(Exception)), "Wrong exception type");
|
||||
if (expectedMessagePart != null)
|
||||
{
|
||||
Assert.That(ex.Message, Does.Contain(expectedMessagePart), "Wrong error message");
|
||||
}
|
||||
|
||||
// Else the exception is fine
|
||||
return;
|
||||
}
|
||||
|
||||
Assert.Fail("Expected exception " + expectedExceptionType + " to be thrown by the operation");
|
||||
Exception exception = Assert.Throws(expectedExceptionType ?? typeof(Exception), body);
|
||||
StringAssert.Contains(expectedMessagePart, exception.Message);
|
||||
}
|
||||
}
|
||||
|
||||
public delegate void ExceptionHelperExecutionBody();
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using NUnit.Framework;
|
||||
using winsw.Util;
|
||||
|
||||
|
@ -38,12 +38,11 @@ namespace winswTests.Util
|
|||
var envVars = FilesystemTestHelper.parseSetOutput(envFile);
|
||||
string[] keys = new string[envVars.Count];
|
||||
envVars.Keys.CopyTo(keys, 0);
|
||||
String availableVars = "[" + string.Join(",", keys) + "]";
|
||||
string availableVars = "[" + string.Join(",", keys) + "]";
|
||||
Assert.That(envVars.ContainsKey("TEST_KEY"), "No TEST_KEY in the injected vars: " + availableVars);
|
||||
|
||||
// And just ensure that the parsing logic is case-sensitive
|
||||
Assert.That(!envVars.ContainsKey("test_key"), "Test error: the environment parsing logic is case-insensitive");
|
||||
|
||||
}
|
||||
|
||||
[Test]
|
||||
|
@ -51,8 +50,8 @@ namespace winswTests.Util
|
|||
{
|
||||
var tmpDir = FilesystemTestHelper.CreateTmpDirectory();
|
||||
string scriptFile = Path.Combine(tmpDir, "print_lots_to_stdout.bat");
|
||||
var lotsOfStdOut = string.Join(string.Empty, _Range(1, 1000));
|
||||
File.WriteAllText(scriptFile, string.Format("echo \"{0}\"", lotsOfStdOut));
|
||||
var lotsOfStdOut = string.Join(string.Empty, Enumerable.Range(1, 1000));
|
||||
File.WriteAllText(scriptFile, $"echo \"{lotsOfStdOut}\"");
|
||||
|
||||
Process proc = new Process();
|
||||
var ps = proc.StartInfo;
|
||||
|
@ -65,16 +64,5 @@ namespace winswTests.Util
|
|||
Assert.Fail("Process " + proc + " didn't exit after 5 seconds");
|
||||
}
|
||||
}
|
||||
|
||||
private string[] _Range(int start, int limit)
|
||||
{
|
||||
var range = new List<string>();
|
||||
for (var i = start; i < limit; i++)
|
||||
{
|
||||
range.Add(i.ToString());
|
||||
}
|
||||
|
||||
return range.ToArray();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>net40;net461;netcoreapp3.1</TargetFrameworks>
|
||||
<LangVersion>latest</LangVersion>
|
||||
<Version><!-- Populated by AppVeyor --></Version>
|
||||
<RootNamespace>winswTests</RootNamespace>
|
||||
</PropertyGroup>
|
||||
|
|
Loading…
Reference in New Issue