mirror of https://github.com/winsw/winsw
[JENKINS-42744] - Reproduce the issue in the unit test
parent
615519f6a3
commit
9fc518a3d0
|
@ -118,7 +118,6 @@ namespace winsw.Util
|
|||
}
|
||||
}
|
||||
|
||||
//TODO: generalize API
|
||||
/// <summary>
|
||||
/// Starts a process and asynchronosly waits for its termination.
|
||||
/// Once the process exits, the callback will be invoked.
|
||||
|
@ -129,24 +128,27 @@ namespace winsw.Util
|
|||
/// <param name="envVars">Additional environment variables</param>
|
||||
/// <param name="workingDirectory">Working directory</param>
|
||||
/// <param name="priority">Priority</param>
|
||||
/// <param name="callback">Completion callback</param>
|
||||
public static void StartProcessAndCallbackForExit(Process processToStart, String executable, string arguments, Dictionary<string, string> envVars,
|
||||
string workingDirectory, ProcessPriorityClass priority, ProcessCompletionCallback callback)
|
||||
/// <param name="callback">Completion callback. If null, the completion won't be monitored</param>
|
||||
public static void StartProcessAndCallbackForExit(Process processToStart, String executable = null, string arguments = null, Dictionary<string, string> envVars = null,
|
||||
string workingDirectory = null, ProcessPriorityClass? priority = null, ProcessCompletionCallback callback = null)
|
||||
{
|
||||
var ps = processToStart.StartInfo;
|
||||
ps.FileName = executable;
|
||||
ps.Arguments = arguments;
|
||||
ps.WorkingDirectory = workingDirectory;
|
||||
ps.FileName = executable ?? ps.FileName;
|
||||
ps.Arguments = arguments ?? ps.Arguments;
|
||||
ps.WorkingDirectory = workingDirectory ?? ps.WorkingDirectory;
|
||||
ps.CreateNoWindow = false;
|
||||
ps.UseShellExecute = false;
|
||||
ps.RedirectStandardInput = true; // this creates a pipe for stdin to the new process, instead of having it inherit our stdin.
|
||||
ps.RedirectStandardOutput = true;
|
||||
ps.RedirectStandardError = true;
|
||||
|
||||
foreach (string key in envVars.Keys)
|
||||
if (envVars != null)
|
||||
{
|
||||
Environment.SetEnvironmentVariable(key, envVars[key]);
|
||||
// ps.EnvironmentVariables[key] = envs[key]; // bugged (lower cases all variable names due to StringDictionary being used, see http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=326163)
|
||||
foreach (string key in envVars.Keys)
|
||||
{
|
||||
Environment.SetEnvironmentVariable(key, envVars[key]);
|
||||
// ps.EnvironmentVariables[key] = envs[key]; // bugged (lower cases all variable names due to StringDictionary being used, see http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=326163)
|
||||
}
|
||||
}
|
||||
|
||||
//TODO: move outside, stubbed to reproduce the issue
|
||||
|
@ -157,15 +159,20 @@ namespace winsw.Util
|
|||
processToStart.Start();
|
||||
Logger.Info("Started process " + processToStart.Id);
|
||||
|
||||
if (priority != ProcessPriorityClass.Normal)
|
||||
processToStart.PriorityClass = priority;
|
||||
if (priority != null && priority.Value != ProcessPriorityClass.Normal)
|
||||
{
|
||||
processToStart.PriorityClass = priority.Value;
|
||||
}
|
||||
|
||||
// monitor the completion of the process
|
||||
StartThread(delegate
|
||||
if (callback != null)
|
||||
{
|
||||
processToStart.WaitForExit();
|
||||
callback(processToStart);
|
||||
});
|
||||
StartThread(delegate
|
||||
{
|
||||
processToStart.WaitForExit();
|
||||
callback(processToStart);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
|
||||
namespace winswTests.Util
|
||||
{
|
||||
class FilesystemTestHelper
|
||||
{
|
||||
/// <summary>
|
||||
/// Creates a temporary directory for testing.
|
||||
/// </summary>
|
||||
/// <returns>tmp Dir</returns>
|
||||
public static string CreateTmpDirectory(String testName = null)
|
||||
{
|
||||
string tempDirectory = Path.Combine(Path.GetTempPath(), "winswTests_" + (testName ?? "") + Path.GetRandomFileName());
|
||||
Directory.CreateDirectory(tempDirectory);
|
||||
Console.Out.WriteLine("Created the temporary directory: {0}", tempDirectory);
|
||||
return tempDirectory;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Parses output of the "set" command from the file
|
||||
/// </summary>
|
||||
/// <param name="filePath">File path</param>
|
||||
/// <returns>Dictionary of the strings.</returns>
|
||||
public static Dictionary<string, string> parseSetOutput(string filePath)
|
||||
{
|
||||
Dictionary<string, string> res = new Dictionary<string, string>();
|
||||
var lines = File.ReadAllLines(filePath);
|
||||
foreach(var line in lines) {
|
||||
line.Split("=".ToCharArray(), 2);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
using System;
|
||||
using System.Diagnostics;
|
||||
using NUnit.Framework;
|
||||
using winsw;
|
||||
using System.IO;
|
||||
using winsw.Util;
|
||||
|
||||
namespace winswTests.Util
|
||||
{
|
||||
|
||||
[TestFixture]
|
||||
class ProcessHelperTest
|
||||
{
|
||||
/// <summary>
|
||||
/// Also reported as <a href="https://issues.jenkins-ci.org/browse/JENKINS-42744">JENKINS-42744</a>
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void ShouldPropagateVariablesInUppercase()
|
||||
{
|
||||
var tmpDir = FilesystemTestHelper.CreateTmpDirectory();
|
||||
String envFile = Path.Combine(tmpDir, "env.properties");
|
||||
String scriptFile = Path.Combine(tmpDir, "printenv.bat");
|
||||
File.WriteAllText(scriptFile, "set > " + envFile);
|
||||
|
||||
|
||||
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");
|
||||
}
|
||||
|
||||
// Check several veriables, which are expected to be in Uppercase
|
||||
var envVars = FilesystemTestHelper.parseSetOutput(envFile);
|
||||
Assert.That(envVars.ContainsKey("PROCESSOR_ARCHITECTURE"), "No PROCESSOR_ARCHITECTURE in the injected vars");
|
||||
Assert.That(envVars.ContainsKey("COMPUTERNAME"), "No COMPUTERNAME in the injected vars");
|
||||
Assert.That(envVars.ContainsKey("PATHEXT"), "No PATHEXT in the injected vars");
|
||||
|
||||
// And just ensure that the parsing logic is case-sensitive
|
||||
Assert.That(!envVars.ContainsKey("computername"), "Test error: the environment parsing logic is case-insensitive");
|
||||
|
||||
}
|
||||
}
|
||||
}
|
|
@ -60,6 +60,8 @@
|
|||
<Compile Include="Extensions\RunawayProcessKillerTest.cs" />
|
||||
<Compile Include="Extensions\SharedDirectoryMapperTest.cs" />
|
||||
<Compile Include="MainTest.cs" />
|
||||
<Compile Include="Util\FilesystemTestHelper.cs" />
|
||||
<Compile Include="Util\ProcessHelperTest.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="ServiceDescriptorTests.cs" />
|
||||
<Compile Include="Util\CLITestHelper.cs" />
|
||||
|
|
Loading…
Reference in New Issue