public ContainerInfo CreateContainerInfo(Pipelines.ContainerResource container, Boolean isJobContainer = true) { ContainerInfo containerInfo = new ContainerInfo(container, isJobContainer); if (TestUtil.IsWindows()) { // Tool cache folder may come from ENV, so we need a unique folder to avoid collision containerInfo.PathMappings[this.GetDirectory(WellKnownDirectory.Tools)] = "C:\\__t"; containerInfo.PathMappings[this.GetDirectory(WellKnownDirectory.Work)] = "C:\\__w"; containerInfo.PathMappings[this.GetDirectory(WellKnownDirectory.Root)] = "C:\\__a"; // add -v '\\.\pipe\docker_engine:\\.\pipe\docker_engine' when they are available (17.09) } else { // Tool cache folder may come from ENV, so we need a unique folder to avoid collision containerInfo.PathMappings[this.GetDirectory(WellKnownDirectory.Tools)] = "/__t"; containerInfo.PathMappings[this.GetDirectory(WellKnownDirectory.Work)] = "/__w"; containerInfo.PathMappings[this.GetDirectory(WellKnownDirectory.Root)] = "/__a"; if (containerInfo.IsJobContainer) { containerInfo.MountVolumes.Add(new MountVolume("/var/run/docker.sock", "/var/run/docker.sock")); } } return(containerInfo); }
public async Task EnableWorkerCommandsByDefault() { using (TestHostContext hc = new TestHostContext(this)) { Tracing trace = hc.GetTrace(); Int32 exitCode = -1; List <string> stdout = new List <string>(); var processInvoker = new ProcessInvokerWrapper(); processInvoker.OutputDataReceived += (object sender, ProcessDataReceivedEventArgs e) => { stdout.Add(e.Data); }; processInvoker.Initialize(hc); exitCode = (TestUtil.IsWindows()) ? await processInvoker.ExecuteAsync("", "powershell.exe", $@"-NoLogo -Sta -NoProfile -NonInteractive -ExecutionPolicy Unrestricted -Command ""Write-Host '##vso somecommand'""", null, CancellationToken.None) : await processInvoker.ExecuteAsync("", "bash", "-c \"echo '##vso somecommand'\"", null, CancellationToken.None); trace.Info("Exit Code: {0}", exitCode); Assert.Equal(0, exitCode); Assert.True(stdout.Contains("##vso somecommand"), "##vso commands should not be escaped."); } }
public async Task RedirectSTDINCloseStream() { using (TestHostContext hc = new TestHostContext(this)) using (var redirectSTDIN = new InputQueue <string>()) { Tracing trace = hc.GetTrace(); Int32 exitCode = -1; List <string> stdout = new List <string>(); redirectSTDIN.Enqueue("Single line of STDIN"); using (var cancellationTokenSource = new CancellationTokenSource()) using (var processInvoker = new ProcessInvokerWrapper()) { processInvoker.OutputDataReceived += (object sender, ProcessDataReceivedEventArgs e) => { stdout.Add(e.Data); }; processInvoker.Initialize(hc); var proc = (TestUtil.IsWindows()) ? processInvoker.ExecuteAsync("", "cmd.exe", "/c more", null, false, null, false, redirectSTDIN, false, false, cancellationTokenSource.Token) : processInvoker.ExecuteAsync("", "bash", "-c \"read input; echo $input; read input; echo $input; read input; echo $input;\"", null, false, null, false, redirectSTDIN, false, false, cancellationTokenSource.Token); redirectSTDIN.Enqueue("More line of STDIN"); redirectSTDIN.Enqueue("More line of STDIN"); await Task.Delay(100); redirectSTDIN.Enqueue("More line of STDIN"); redirectSTDIN.Enqueue("More line of STDIN"); await Task.Delay(100); redirectSTDIN.Enqueue("More line of STDIN"); cancellationTokenSource.CancelAfter(100); try { exitCode = await proc; trace.Info("Exit Code: {0}", exitCode); } catch (Exception ex) { trace.Error(ex); } trace.Info("STDOUT: {0}", string.Join(Environment.NewLine, stdout)); Assert.False(stdout.Contains("More line of STDIN"), "STDIN should be closed after first input line."); } } }
public TestHostContext(object testClass, [CallerMemberName] string testName = "") { ArgUtil.NotNull(testClass, nameof(testClass)); ArgUtil.NotNullOrEmpty(testName, nameof(testName)); _loadContext = AssemblyLoadContext.GetLoadContext(typeof(TestHostContext).GetTypeInfo().Assembly); _loadContext.Unloading += LoadContext_Unloading; _testName = testName; // Trim the test assembly's root namespace from the test class's full name. _suiteName = testClass.GetType().FullName.Substring( startIndex: typeof(Tests.TestHostContext).FullName.LastIndexOf(nameof(TestHostContext))); _suiteName = _suiteName.Replace(".", "_"); // Setup the trace manager. TraceFileName = Path.Combine( Path.Combine(TestUtil.GetSrcPath(), "Test", "TestLogs"), $"trace_{_suiteName}_{_testName}.log"); if (File.Exists(TraceFileName)) { File.Delete(TraceFileName); } var traceListener = new HostTraceListener(TraceFileName); traceListener.DisableConsoleReporting = true; _secretMasker = new SecretMasker(); _secretMasker.AddValueEncoder(ValueEncoders.JsonStringEscape); _secretMasker.AddValueEncoder(ValueEncoders.UriDataEscape); _secretMasker.AddValueEncoder(ValueEncoders.BackslashEscape); _traceManager = new TraceManager(traceListener, _secretMasker); _trace = GetTrace(nameof(TestHostContext)); // inject a terminal in silent mode so all console output // goes to the test trace file _term = new Terminal(); _term.Silent = true; SetSingleton <ITerminal>(_term); EnqueueInstance <ITerminal>(_term); if (!TestUtil.IsWindows()) { string eulaFile = Path.Combine(GetDirectory(WellKnownDirectory.Externals), Constants.Path.TeeDirectory, "license.html"); Directory.CreateDirectory(GetDirectory(WellKnownDirectory.Externals)); Directory.CreateDirectory(Path.Combine(GetDirectory(WellKnownDirectory.Externals), Constants.Path.TeeDirectory)); File.WriteAllText(eulaFile, "testeulafile"); } }
public async Task SuccessExitsWithCodeZero() { using (TestHostContext hc = new TestHostContext(this)) { Tracing trace = hc.GetTrace(); Int32 exitCode = -1; var processInvoker = new ProcessInvokerWrapper(); processInvoker.Initialize(hc); exitCode = (TestUtil.IsWindows()) ? await processInvoker.ExecuteAsync("", "cmd.exe", "/c \"dir >nul\"", null, CancellationToken.None) : await processInvoker.ExecuteAsync("", "bash", "-c echo .", null, CancellationToken.None); trace.Info("Exit Code: {0}", exitCode); Assert.Equal(0, exitCode); } }
public async Task SuccessReadProcessEnv() { using (TestHostContext hc = new TestHostContext(this)) { Tracing trace = hc.GetTrace(); string envName = Guid.NewGuid().ToString(); string envValue = Guid.NewGuid().ToString(); Process sleep = null; try { // TODO: this was formerly skipped on Windows - why? hc.EnqueueInstance <IProcessInvoker>(new ProcessInvokerWrapper()); // sleep 15 seconds string sleepCmd = (TestUtil.IsWindows()) ? "powershell" : "sleep"; string sleepArgs = (TestUtil.IsWindows()) ? "-Command \"Start-Sleep -s 15\"" : "15s"; var startInfo = new ProcessStartInfo(sleepCmd, sleepArgs); startInfo.Environment[envName] = envValue; sleep = Process.Start(startInfo); var timeout = Process.GetProcessById(sleep.Id); while (timeout == null) { await Task.Delay(1500); timeout = Process.GetProcessById(sleep.Id); } try { await Task.Delay(2000); trace.Info($"Read env from {timeout.Id}"); var value = timeout.GetEnvironmentVariable(hc, envName); if (string.Equals(value, envValue, StringComparison.OrdinalIgnoreCase)) { trace.Info($"Find the env."); return; } else { Assert.True(false, "Expected environment '" + envValue + "' did not match actual '" + value + "'"); } } catch (Exception ex) { trace.Error(ex); Assert.True(false, "Fail to retrive process environment variable due to exception: " + ex.Message + "\n" + ex.StackTrace); } Assert.True(false, "Fail to retrive process environment variable."); } finally { try { sleep?.Kill(); } catch { } } } }