ServiceDescriptorTests.cs 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371
  1. using System;
  2. using System.Diagnostics;
  3. using NUnit.Framework;
  4. using winsw;
  5. namespace winswTests
  6. {
  7. using System;
  8. using WMI;
  9. using winswTests.Util;
  10. [TestFixture]
  11. public class ServiceDescriptorTests
  12. {
  13. private ServiceDescriptor _extendedServiceDescriptor;
  14. private const string ExpectedWorkingDirectory = @"Z:\Path\SubPath";
  15. private const string Username = "User";
  16. private const string Password = "Password";
  17. private const string Domain = "Domain";
  18. private const string AllowServiceAccountLogonRight = "true";
  19. [SetUp]
  20. public void SetUp()
  21. {
  22. const string seedXml = "<service>"
  23. + "<id>service.exe</id>"
  24. + "<name>Service</name>"
  25. + "<description>The service.</description>"
  26. + "<executable>node.exe</executable>"
  27. + "<arguments>My Arguments</arguments>"
  28. + "<logmode>rotate</logmode>"
  29. + "<serviceaccount>"
  30. + "<domain>" + Domain + "</domain>"
  31. + "<user>" + Username + "</user>"
  32. + "<password>" + Password + "</password>"
  33. + "<allowservicelogon>" + AllowServiceAccountLogonRight + "</allowservicelogon>"
  34. + "</serviceaccount>"
  35. + "<workingdirectory>"
  36. + ExpectedWorkingDirectory
  37. + "</workingdirectory>"
  38. + @"<logpath>C:\logs</logpath>"
  39. + "</service>";
  40. _extendedServiceDescriptor = ServiceDescriptor.FromXML(seedXml);
  41. }
  42. [Test]
  43. public void DefaultStartMode()
  44. {
  45. Assert.That(_extendedServiceDescriptor.StartMode, Is.EqualTo(StartMode.Automatic));
  46. }
  47. [Test]
  48. [ExpectedException(typeof(System.ArgumentException))]
  49. public void IncorrectStartMode()
  50. {
  51. const string SeedXml = "<service>"
  52. + "<id>service.exe</id>"
  53. + "<name>Service</name>"
  54. + "<description>The service.</description>"
  55. + "<executable>node.exe</executable>"
  56. + "<arguments>My Arguments</arguments>"
  57. + "<startmode>rotate</startmode>"
  58. + "<logmode>rotate</logmode>"
  59. + "<serviceaccount>"
  60. + "<domain>" + Domain + "</domain>"
  61. + "<user>" + Username + "</user>"
  62. + "<password>" + Password + "</password>"
  63. + "<allowservicelogon>" + AllowServiceAccountLogonRight + "</allowservicelogon>"
  64. + "</serviceaccount>"
  65. + "<workingdirectory>"
  66. + ExpectedWorkingDirectory
  67. + "</workingdirectory>"
  68. + @"<logpath>C:\logs</logpath>"
  69. + "</service>";
  70. _extendedServiceDescriptor = ServiceDescriptor.FromXML(SeedXml);
  71. Assert.That(_extendedServiceDescriptor.StartMode, Is.EqualTo(StartMode.Manual));
  72. }
  73. [Test]
  74. public void ChangedStartMode()
  75. {
  76. const string SeedXml = "<service>"
  77. + "<id>service.exe</id>"
  78. + "<name>Service</name>"
  79. + "<description>The service.</description>"
  80. + "<executable>node.exe</executable>"
  81. + "<arguments>My Arguments</arguments>"
  82. + "<startmode>manual</startmode>"
  83. + "<logmode>rotate</logmode>"
  84. + "<serviceaccount>"
  85. + "<domain>" + Domain + "</domain>"
  86. + "<user>" + Username + "</user>"
  87. + "<password>" + Password + "</password>"
  88. + "<allowservicelogon>" + AllowServiceAccountLogonRight + "</allowservicelogon>"
  89. + "</serviceaccount>"
  90. + "<workingdirectory>"
  91. + ExpectedWorkingDirectory
  92. + "</workingdirectory>"
  93. + @"<logpath>C:\logs</logpath>"
  94. + "</service>";
  95. _extendedServiceDescriptor = ServiceDescriptor.FromXML(SeedXml);
  96. Assert.That(_extendedServiceDescriptor.StartMode, Is.EqualTo(StartMode.Manual));
  97. }
  98. [Test]
  99. public void VerifyWorkingDirectory()
  100. {
  101. Debug.WriteLine("_extendedServiceDescriptor.WorkingDirectory :: " + _extendedServiceDescriptor.WorkingDirectory);
  102. Assert.That(_extendedServiceDescriptor.WorkingDirectory, Is.EqualTo(ExpectedWorkingDirectory));
  103. }
  104. [Test]
  105. public void VerifyServiceLogonRight()
  106. {
  107. Assert.That(_extendedServiceDescriptor.AllowServiceAcountLogonRight, Is.EqualTo(true));
  108. }
  109. [Test]
  110. public void VerifyUsername()
  111. {
  112. Debug.WriteLine("_extendedServiceDescriptor.WorkingDirectory :: " + _extendedServiceDescriptor.WorkingDirectory);
  113. Assert.That(_extendedServiceDescriptor.ServiceAccountUser, Is.EqualTo(Domain + "\\" + Username));
  114. }
  115. [Test]
  116. public void VerifyPassword()
  117. {
  118. Debug.WriteLine("_extendedServiceDescriptor.WorkingDirectory :: " + _extendedServiceDescriptor.WorkingDirectory);
  119. Assert.That(_extendedServiceDescriptor.ServiceAccountPassword, Is.EqualTo(Password));
  120. }
  121. [Test]
  122. public void Priority()
  123. {
  124. var sd = ServiceDescriptor.FromXML("<service><id>test</id><priority>normal</priority></service>");
  125. Assert.That(sd.Priority, Is.EqualTo(ProcessPriorityClass.Normal));
  126. sd = ServiceDescriptor.FromXML("<service><id>test</id><priority>idle</priority></service>");
  127. Assert.That(sd.Priority, Is.EqualTo(ProcessPriorityClass.Idle));
  128. sd = ServiceDescriptor.FromXML("<service><id>test</id></service>");
  129. Assert.That(sd.Priority, Is.EqualTo(ProcessPriorityClass.Normal));
  130. }
  131. [Test]
  132. public void StopParentProcessFirstIsFalseByDefault()
  133. {
  134. Assert.False(_extendedServiceDescriptor.StopParentProcessFirst);
  135. }
  136. [Test]
  137. public void CanParseStopParentProcessFirst()
  138. {
  139. const string seedXml = "<service>"
  140. + "<stopparentprocessfirst>true</stopparentprocessfirst>"
  141. + "</service>";
  142. var serviceDescriptor = ServiceDescriptor.FromXML(seedXml);
  143. Assert.True(serviceDescriptor.StopParentProcessFirst);
  144. }
  145. [Test]
  146. public void CanParseStopTimeout()
  147. {
  148. const string seedXml = "<service>"
  149. + "<stoptimeout>60sec</stoptimeout>"
  150. + "</service>";
  151. var serviceDescriptor = ServiceDescriptor.FromXML(seedXml);
  152. Assert.That(serviceDescriptor.StopTimeout, Is.EqualTo(TimeSpan.FromSeconds(60)));
  153. }
  154. [Test]
  155. public void CanParseStopTimeoutFromMinutes()
  156. {
  157. const string seedXml = "<service>"
  158. + "<stoptimeout>10min</stoptimeout>"
  159. + "</service>";
  160. var serviceDescriptor = ServiceDescriptor.FromXML(seedXml);
  161. Assert.That(serviceDescriptor.StopTimeout, Is.EqualTo(TimeSpan.FromMinutes(10)));
  162. }
  163. [Test]
  164. public void LogModeRollBySize()
  165. {
  166. const string seedXml = "<service>"
  167. + "<logpath>c:\\</logpath>"
  168. + "<log mode=\"roll-by-size\">"
  169. + "<sizeThreshold>112</sizeThreshold>"
  170. + "<keepFiles>113</keepFiles>"
  171. + "</log>"
  172. + "</service>";
  173. var serviceDescriptor = ServiceDescriptor.FromXML(seedXml);
  174. serviceDescriptor.BaseName = "service";
  175. var logHandler = serviceDescriptor.LogHandler as SizeBasedRollingLogAppender;
  176. Assert.NotNull(logHandler);
  177. Assert.That(logHandler.SizeTheshold, Is.EqualTo(112 * 1024));
  178. Assert.That(logHandler.FilesToKeep, Is.EqualTo(113));
  179. }
  180. [Test]
  181. public void LogModeRollByTime()
  182. {
  183. const string seedXml = "<service>"
  184. + "<logpath>c:\\</logpath>"
  185. + "<log mode=\"roll-by-time\">"
  186. + "<period>7</period>"
  187. + "<pattern>log pattern</pattern>"
  188. + "</log>"
  189. + "</service>";
  190. var serviceDescriptor = ServiceDescriptor.FromXML(seedXml);
  191. serviceDescriptor.BaseName = "service";
  192. var logHandler = serviceDescriptor.LogHandler as TimeBasedRollingLogAppender;
  193. Assert.NotNull(logHandler);
  194. Assert.That(logHandler.Period, Is.EqualTo(7));
  195. Assert.That(logHandler.Pattern, Is.EqualTo("log pattern"));
  196. }
  197. [Test]
  198. public void VerifyServiceLogonRightGraceful()
  199. {
  200. const string seedXml="<service>"
  201. + "<serviceaccount>"
  202. + "<domain>" + Domain + "</domain>"
  203. + "<user>" + Username + "</user>"
  204. + "<password>" + Password + "</password>"
  205. + "<allowservicelogon>true1</allowservicelogon>"
  206. + "</serviceaccount>"
  207. + "</service>";
  208. var serviceDescriptor = ServiceDescriptor.FromXML(seedXml);
  209. Assert.That(serviceDescriptor.AllowServiceAcountLogonRight, Is.EqualTo(false));
  210. }
  211. [Test]
  212. public void VerifyServiceLogonRightOmitted()
  213. {
  214. const string seedXml = "<service>"
  215. + "<serviceaccount>"
  216. + "<domain>" + Domain + "</domain>"
  217. + "<user>" + Username + "</user>"
  218. + "<password>" + Password + "</password>"
  219. + "</serviceaccount>"
  220. + "</service>";
  221. var serviceDescriptor = ServiceDescriptor.FromXML(seedXml);
  222. Assert.That(serviceDescriptor.AllowServiceAcountLogonRight, Is.EqualTo(false));
  223. }
  224. [Test]
  225. public void VerifyWaitHint_FullXML()
  226. {
  227. var sd = ConfigXmlBuilder.create()
  228. .WithTag("waithint", "20 min")
  229. .ToServiceDescriptor(true);
  230. Assert.That(sd.WaitHint, Is.EqualTo(TimeSpan.FromMinutes(20)));
  231. }
  232. /// <summary>
  233. /// Test for https://github.com/kohsuke/winsw/issues/159
  234. /// </summary>
  235. [Test]
  236. public void VerifyWaitHint_XMLWithoutVersion()
  237. {
  238. var sd = ConfigXmlBuilder.create(printXMLVersion: false)
  239. .WithTag("waithint", "21 min")
  240. .ToServiceDescriptor(true);
  241. Assert.That(sd.WaitHint, Is.EqualTo(TimeSpan.FromMinutes(21)));
  242. }
  243. [Test]
  244. public void VerifyWaitHint_XMLWithoutComment()
  245. {
  246. var sd = ConfigXmlBuilder.create(xmlComment: null)
  247. .WithTag("waithint", "22 min")
  248. .ToServiceDescriptor(true);
  249. Assert.That(sd.WaitHint, Is.EqualTo(TimeSpan.FromMinutes(22)));
  250. }
  251. [Test]
  252. public void VerifyWaitHint_XMLWithoutVersionAndComment()
  253. {
  254. var sd = ConfigXmlBuilder.create(xmlComment: null, printXMLVersion: false)
  255. .WithTag("waithint", "23 min")
  256. .ToServiceDescriptor(true);
  257. Assert.That(sd.WaitHint, Is.EqualTo(TimeSpan.FromMinutes(23)));
  258. }
  259. [Test]
  260. public void VerifySleepTime()
  261. {
  262. var sd = ConfigXmlBuilder.create().WithTag("sleeptime", "3 hrs").ToServiceDescriptor(true);
  263. Assert.That(sd.SleepTime, Is.EqualTo(TimeSpan.FromHours(3)));
  264. }
  265. [Test]
  266. public void VerifyResetFailureAfter()
  267. {
  268. var sd = ConfigXmlBuilder.create().WithTag("resetfailure", "75 sec").ToServiceDescriptor(true);
  269. Assert.That(sd.ResetFailureAfter, Is.EqualTo(TimeSpan.FromSeconds(75)));
  270. }
  271. [Test]
  272. public void VerifyStopTimeout()
  273. {
  274. var sd = ConfigXmlBuilder.create().WithTag("stoptimeout", "35 secs").ToServiceDescriptor(true);
  275. Assert.That(sd.StopTimeout, Is.EqualTo(TimeSpan.FromSeconds(35)));
  276. }
  277. /// <summary>
  278. /// https://github.com/kohsuke/winsw/issues/178
  279. /// </summary>
  280. [Test]
  281. public void Arguments_LegacyParam()
  282. {
  283. var sd = ConfigXmlBuilder.create().WithTag("arguments", "arg").ToServiceDescriptor(true);
  284. Assert.That(sd.Arguments, Is.EqualTo("arg"));
  285. }
  286. [Test]
  287. public void Arguments_NewParam_Single()
  288. {
  289. var sd = ConfigXmlBuilder.create()
  290. .WithTag("argument", "--arg1=2")
  291. .ToServiceDescriptor(true);
  292. Assert.That(sd.Arguments, Is.EqualTo(" --arg1=2"));
  293. }
  294. [Test]
  295. public void Arguments_NewParam_MultipleArgs()
  296. {
  297. var sd = ConfigXmlBuilder.create()
  298. .WithTag("argument", "--arg1=2")
  299. .WithTag("argument", "--arg2=123")
  300. .WithTag("argument", "--arg3=null")
  301. .ToServiceDescriptor(true);
  302. Assert.That(sd.Arguments, Is.EqualTo(" --arg1=2 --arg2=123 --arg3=null"));
  303. }
  304. /// <summary>
  305. /// Ensures that the new single-argument field has a higher priority.
  306. /// </summary>
  307. [Test]
  308. public void Arguments_Bothparam_Priorities()
  309. {
  310. var sd = ConfigXmlBuilder.create()
  311. .WithTag("arguments", "--arg1=2 --arg2=3")
  312. .WithTag("argument", "--arg2=123")
  313. .WithTag("argument", "--arg3=null")
  314. .ToServiceDescriptor(true);
  315. Assert.That(sd.Arguments, Is.EqualTo(" --arg2=123 --arg3=null"));
  316. }
  317. [TestCase(true)]
  318. [TestCase(false)]
  319. public void DelayedStart_RoundTrip(bool enabled)
  320. {
  321. var bldr = ConfigXmlBuilder.create();
  322. if (enabled) {
  323. bldr = bldr.WithDelayedAutoStart();
  324. }
  325. var sd = bldr.ToServiceDescriptor();
  326. Assert.That(sd.DelayedAutoStart, Is.EqualTo(enabled));
  327. }
  328. }
  329. }