private string GetArgOrPrompt( string name, string description, string defaultValue, Func <string, bool> validator) { // Check for the arg in the command line parser. ArgUtil.NotNull(validator, nameof(validator)); string result = GetArg(name); // Return the arg if it is not empty and is valid. _trace.Info($"Arg '{name}': '{result}'"); if (!string.IsNullOrEmpty(result)) { // After read the arg from input commandline args, remove it from Arg dictionary, // This will help if bad arg value passed through CommandLine arg, when ConfigurationManager ask CommandSetting the second time, // It will prompt for input intead of continue use the bad input. _trace.Info($"Remove {name} from Arg dictionary."); RemoveArg(name); if (validator(result)) { return(result); } _trace.Info("Arg is invalid."); } // Otherwise prompt for the arg. return(_promptManager.ReadValue( argName: name, description: description, secret: Constants.Agent.CommandLine.Args.Secrets.Any(x => string.Equals(x, name, StringComparison.OrdinalIgnoreCase)), defaultValue: defaultValue, validator: validator, unattended: Unattended)); }
private void Prepare(TestHostContext hostContext) { _trace = hostContext.GetTrace(); // Prepare the sources directory. The workspace helper will not return any // matches if the sources directory does not exist with something in it. _sourcesDirectory = Path.Combine(hostContext.GetDirectory(WellKnownDirectory.Bin), Path.GetRandomFileName()); _sourceFile = Path.Combine(_sourcesDirectory, "some file"); Directory.CreateDirectory(_sourcesDirectory); File.WriteAllText(path: _sourceFile, contents: "some contents"); // Prepare a basic definition workspace. _workspaceName = "ws_1_1"; _definitionMappings = new[] { new TfsVCSourceProvider.DefinitionWorkspaceMapping { LocalPath = "", MappingType = TfsVCSourceProvider.DefinitionMappingType.Map, ServerPath = "$/*", }, new TfsVCSourceProvider.DefinitionWorkspaceMapping { LocalPath = "myProj", MappingType = TfsVCSourceProvider.DefinitionMappingType.Map, ServerPath = "$/myProj", }, new TfsVCSourceProvider.DefinitionWorkspaceMapping { LocalPath = "myProj/Drops", MappingType = TfsVCSourceProvider.DefinitionMappingType.Cloak, ServerPath = "$/myProj/Drops", }, new TfsVCSourceProvider.DefinitionWorkspaceMapping { LocalPath = "otherProj/mydir", MappingType = TfsVCSourceProvider.DefinitionMappingType.Map, ServerPath = "$/otherProj/mydir/*", }, }; _executionContext = new Mock <IExecutionContext>(); _executionContext .Setup(x => x.WriteDebug) .Returns(true); _executionContext .Setup(x => x.Write(It.IsAny <string>(), It.IsAny <string>())) .Callback((string tag, string message) => _trace.Info($"[ExecutionContext]{tag} {message}")); }
// // Private helpers. // private string GetArgOrPrompt( string name, string description, string defaultValue, Func <string, bool> validator) { // Check for the arg in the command line parser. ArgUtil.NotNull(validator, nameof(validator)); string result; if (!_parser.Args.TryGetValue(name, out result)) { result = null; } // Return the arg if it is not empty and is valid. _trace.Info($"Arg '{name}': '{result}'"); if (!string.IsNullOrEmpty(result)) { if (validator(result)) { return(result); } _trace.Info("Arg is invalid."); } // Otherwise prompt for the arg. return(_promptManager.ReadValue( argName: name, description: description, secret: Constants.Agent.CommandLine.Args.Secrets.Any(x => string.Equals(x, name, StringComparison.OrdinalIgnoreCase)), defaultValue: defaultValue, validator: validator, unattended: Unattended)); }
private void WatcherOnChanged(string file) { Tracing.Info(string.Format("File change: {0}", file)); var context = Generator.BuildContext(parameters.Path, parameters.DestinationPath, parameters.IncludeDrafts); if (parameters.CleanTarget && FileSystem.Directory.Exists(context.OutputFolder)) { FileSystem.Directory.Delete(context.OutputFolder, true); } engine.Process(context, true); foreach (var t in transforms) { t.Transform(context); } }
public void WhichReturnsNullWhenNotFound() { using (TestHostContext hc = new TestHostContext(this)) { //Arrange Tracing trace = hc.GetTrace(); // Act. string nosuch = WhichUtil.Which("no-such-file-cf7e351f", trace: trace); trace.Info($"result: {nosuch ?? string.Empty}"); // Assert. Assert.True(string.IsNullOrEmpty(nosuch), "Path should not be resolved"); } }
public void UseWhichFindGit() { using (TestHostContext hc = new TestHostContext(this)) { //Arrange Tracing trace = hc.GetTrace(); // Act. string gitPath = WhichUtil.Which("git", trace: trace); trace.Info($"Which(\"git\") returns: {gitPath ?? string.Empty}"); // Assert. Assert.True(!string.IsNullOrEmpty(gitPath) && File.Exists(gitPath), $"Unable to find Git through: {nameof(WhichUtil.Which)}"); } }
// Constructor. public CommandSettings(IHostContext context, string[] args) { ArgUtil.NotNull(context, nameof(context)); _context = context; _promptManager = context.GetService <IPromptManager>(); _secretMasker = context.GetService <ISecretMasker>(); _trace = context.GetTrace(nameof(CommandSettings)); // Parse the command line args. _parser = new CommandLineParser( hostContext: context, secretArgNames: Constants.Agent.CommandLine.Args.Secrets); _parser.Parse(args); // Store and remove any args passed via environment variables. IDictionary environment = Environment.GetEnvironmentVariables(); string envPrefix = "VSTS_AGENT_INPUT_"; foreach (DictionaryEntry entry in environment) { // Test if starts with VSTS_AGENT_INPUT_. string fullKey = entry.Key as string ?? string.Empty; if (fullKey.StartsWith(envPrefix, StringComparison.OrdinalIgnoreCase)) { string val = (entry.Value as string ?? string.Empty).Trim(); if (!string.IsNullOrEmpty(val)) { // Extract the name. string name = fullKey.Substring(envPrefix.Length); // Mask secrets. bool secret = Constants.Agent.CommandLine.Args.Secrets.Any(x => string.Equals(x, name, StringComparison.OrdinalIgnoreCase)); if (secret) { _secretMasker.AddValue(val); } // Store the value. _envArgs[name] = val; } // Remove from the environment block. _trace.Info($"Removing env var: '{fullKey}'"); Environment.SetEnvironmentVariable(fullKey, null); } } }
public async Task TestCancel() { const int SecondsToRun = 20; using (TestHostContext hc = new TestHostContext(this)) using (var tokenSource = new CancellationTokenSource()) { Tracing trace = hc.GetTrace(); var processInvoker = new ProcessInvokerWrapper(); processInvoker.Initialize(hc); Stopwatch watch = Stopwatch.StartNew(); Task execTask; #if OS_WINDOWS execTask = processInvoker.ExecuteAsync("", "cmd.exe", $"/c \"choice /T {SecondsToRun} /D y\"", null, tokenSource.Token); #else execTask = processInvoker.ExecuteAsync("", "bash", $"-c \"sleep {SecondsToRun}s\"", null, tokenSource.Token); #endif await Task.Delay(500); tokenSource.Cancel(); try { await execTask; } catch (OperationCanceledException) { trace.Info("Get expected OperationCanceledException."); } Assert.True(execTask.IsCompleted); Assert.True(!execTask.IsFaulted); Assert.True(execTask.IsCanceled); watch.Stop(); long elapsedSeconds = watch.ElapsedMilliseconds / 1000; #if ARM // if cancellation fails, then execution time is more than 15 seconds // longer time to compensate for a slower ARM environment (e.g. Raspberry Pi) long expectedSeconds = (SecondsToRun * 3) / 4; #else // if cancellation fails, then execution time is more than 10 seconds long expectedSeconds = SecondsToRun / 2; #endif Assert.True(elapsedSeconds <= expectedSeconds, $"cancellation failed, because task took too long to run. {elapsedSeconds}"); } }
public Variables(IHostContext hostContext, IDictionary <string, string> copy, IList <MaskHint> maskHints, out List <string> warnings) { // Store/Validate args. _hostContext = hostContext; _secretMasker = _hostContext.GetService <ISecretMasker>(); _trace = _hostContext.GetTrace(nameof(Variables)); ArgUtil.NotNull(hostContext, nameof(hostContext)); // Validate the dictionary, rmeove any variable with empty variable name. ArgUtil.NotNull(copy, nameof(copy)); if (copy.Keys.Any(k => string.IsNullOrWhiteSpace(k))) { _trace.Info($"Remove {copy.Keys.Count(k => string.IsNullOrWhiteSpace(k))} variables with empty variable name."); } // Filter/validate the mask hints. ArgUtil.NotNull(maskHints, nameof(maskHints)); MaskHint[] variableMaskHints = maskHints.Where(x => x.Type == MaskType.Variable).ToArray(); foreach (MaskHint maskHint in variableMaskHints) { string maskHintValue = maskHint.Value; ArgUtil.NotNullOrEmpty(maskHintValue, nameof(maskHintValue)); } // Initialize the variable dictionary. IEnumerable <Variable> variables = from string name in copy.Keys where !string.IsNullOrWhiteSpace(name) join MaskHint maskHint in variableMaskHints // Join the variable names with the variable mask hints. on name.ToUpperInvariant() equals maskHint.Value.ToUpperInvariant() into maskHintGrouping select new Variable( name: name, value: copy[name] ?? string.Empty, secret: maskHintGrouping.Any()); foreach (Variable variable in variables) { // Store the variable. The initial secret values have already been // registered by the Worker class. _nonexpanded[variable.Name] = variable; } // Recursively expand the variables. RecalculateExpanded(out warnings); }
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 void Create() { try { if (!fileSystem.Directory.Exists(directory)) { fileSystem.Directory.CreateDirectory(directory); } if (string.Equals("liquid", engine, StringComparison.InvariantCultureIgnoreCase)) { CreateDirectories(); fileSystem.File.WriteAllText(Path.Combine(directory, @"rss.xml"), Properties.Liquid.Rss); fileSystem.File.WriteAllText(Path.Combine(directory, @"atom.xml"), Properties.Liquid.Atom); fileSystem.File.WriteAllText(Path.Combine(directory, @"sitemap.xml"), Properties.Liquid.Sitemap); fileSystem.File.WriteAllText(Path.Combine(directory, @"_layouts", "layout.html"), Properties.Liquid.Layout); fileSystem.File.WriteAllText(Path.Combine(directory, @"_layouts", "post.html"), Properties.Liquid.Post); fileSystem.File.WriteAllText(Path.Combine(directory, @"index.html"), Properties.Liquid.Index); fileSystem.File.WriteAllText(Path.Combine(directory, @"about.md"), Properties.Liquid.About); fileSystem.File.WriteAllText(Path.Combine(directory, @"_posts", string.Format("{0}-myfirstpost.md", DateTime.Today.ToString("yyyy-MM-dd"))), Properties.Liquid.FirstPost); fileSystem.File.WriteAllText(Path.Combine(directory, @"css", "style.css"), Properties.Resources.Style); fileSystem.File.WriteAllText(Path.Combine(directory, @"_config.yml"), Properties.Liquid.Config); fileSystem.File.WriteAllText(Path.Combine(directory, @"_includes", "head.html"), Properties.Liquid.Head); CreateImages(); Tracing.Info("Pretzel site template has been created"); } else { Tracing.Info("Templating Engine not found"); return; } foreach (var additionalIngredient in additionalIngredients) { additionalIngredient.MixIn(directory); } } catch (Exception ex) { Tracing.Error("Error trying to create template: {0}", ex); } }
public async void CreateSessionWithOriginalCredential() { using (TestHostContext tc = CreateTestContext()) using (var tokenSource = new CancellationTokenSource()) { Tracing trace = tc.GetTrace(); // Arrange. var expectedSession = new TaskAgentSession(); _runnerServer .Setup(x => x.CreateAgentSessionAsync( _settings.PoolId, It.Is <TaskAgentSession>(y => y != null), tokenSource.Token)) .Returns(Task.FromResult(expectedSession)); _credMgr.Setup(x => x.LoadCredentials()).Returns(new VssCredentials()); var originalCred = new CredentialData() { Scheme = Constants.Configuration.OAuth }; originalCred.Data["authorizationUrl"] = "https://s.server"; originalCred.Data["clientId"] = "d842fd7b-61b0-4a80-96b4-f2797c353897"; _store.Setup(x => x.GetCredentials()).Returns(originalCred); _store.Setup(x => x.GetMigratedCredentials()).Returns(default(CredentialData)); // Act. MessageListener listener = new MessageListener(); listener.Initialize(tc); bool result = await listener.CreateSessionAsync(tokenSource.Token); trace.Info("result: {0}", result); // Assert. Assert.True(result); _runnerServer .Verify(x => x.CreateAgentSessionAsync( _settings.PoolId, It.Is <TaskAgentSession>(y => y != null), tokenSource.Token), Times.Once()); } }
public void DetectFromDirectory(IDictionary <string, ISiteEngine> engines, SiteContext context) { foreach (var engine in engines) { if (!engine.Value.CanProcess(context)) { continue; } Tracing.Info("Recommended engine for directory: '{0}'", engine.Key); Template = engine.Key; return; } if (Template == null) { Template = "liquid"; } }
Task NewServerCallback(IDictionary <string, object> env) { var path = (string)env[OwinConstants.RequestPath]; Tracing.Info(path); if (!content.IsAvailable(path)) { var response = new Response(env) { ContentType = path.MimeType() }; using (var writer = new StreamWriter(response.OutputStream)) { writer.Write("Page not found: " + path); } return(TaskHelpers.Completed()); } if (path.MimeType().IsBinaryMime()) { var fileContents = content.GetBinaryContent(path); var response = new Response(env) { ContentType = path.MimeType() }; response.Headers["Content-Range"] = new[] { string.Format("bytes 0-{0}", (fileContents.Length - 1)) }; response.Headers["Content-Length"] = new[] { fileContents.Length.ToString(CultureInfo.InvariantCulture) }; response.Write(new ArraySegment <byte>(fileContents)); } else { var response = new Response(env) { ContentType = path.MimeType() }; using (var writer = new StreamWriter(response.OutputStream)) { writer.Write(content.GetContent(path)); } } return(TaskHelpers.Completed()); }
public override void ReadCredential(IHostContext context, Dictionary <string, string> args, bool enforceSupplied) { Tracing trace = context.GetTrace("PersonalAccessToken"); trace.Info("ReadCredentials()"); var wizard = context.GetService <IConsoleWizard>(); trace.Verbose("reading token"); string tokenVal = wizard.ReadValue("token", "PersonalAccessToken", true, String.Empty, // can do better Validators.NonEmptyValidator, args, enforceSupplied); CredentialData.Data["token"] = tokenVal; }
public async Task SuccessExitsWithCodeZero() { using (TestHostContext hc = new TestHostContext(this)) { Tracing trace = hc.GetTrace(); Int32 exitCode = -1; var processInvoker = new ProcessInvokerWrapper(); processInvoker.Initialize(hc); #if OS_WINDOWS exitCode = await processInvoker.ExecuteAsync("", "cmd.exe", "/c \"dir >nul\"", null, CancellationToken.None); #endif #if (OS_OSX || OS_LINUX) exitCode = await processInvoker.ExecuteAsync("", "bash", "-c echo .", null, CancellationToken.None); #endif trace.Info("Exit Code: {0}", exitCode); Assert.Equal(0, exitCode); } }
private void ImportPost(BloggerPost post) { var header = new { title = post.Title, date = post.Published, layout = "post", categories = post.Categories, tags = post.Tags }; var yamlHeader = string.Format("---\r\n{0}---\r\n\r\n", header.ToYaml()); var postContent = yamlHeader + post.Content; string fileName = string.Format(@"{0}-{1}.md", post.Published.ToString("yyyy-MM-dd"), post.Title); //not sure about post name foreach (char c in System.IO.Path.GetInvalidFileNameChars()) { fileName = fileName.Replace(c, '_'); } // replace some valid ones too fileName = fileName.Replace(' ', '-'); fileName = fileName.Replace('\u00A0', '-'); try { var postsPath = Path.Combine(pathToSite, "_posts"); var path = Path.Combine(postsPath, fileName); if (!fileSystem.Directory.Exists(postsPath)) { fileSystem.Directory.CreateDirectory(postsPath); } fileSystem.File.WriteAllText(path, postContent); } catch (Exception e) { Tracing.Info("Failed to write out {0}", fileName); Tracing.Debug(e.Message); } }
/// <summary> /// Processes a single item. /// </summary> /// <param name="input">The input to process.</param> /// <returns>The output of the process.</returns> public override IAssetFile Process(IAssetFile input) { try { // !!!!!!!! // NOT USED // !!!!!!!! // Only processes .ts files if (input.Extension != ".ts") { return(input); } // Measure var watch = new Stopwatch(); watch.Start(); // compiles a TS file var output = TypeScriptCompiler.Compile(input.Content.AsString()); // We've compiled watch.Stop(); // Compiled successfully Tracing.Info("TypeScript", "Compiled " + input.RelativeName + ", " + watch.ElapsedMilliseconds + " ms."); // Return processed output return(AssetOutputFile.Create( from: input, content: output, extension: "js" )); } catch (Exception ex) { // We didn't manage to create anything Tracing.Error("TypeScript", ex); return(null); } }
protected override Task <int> Execute(BakeCommandArguments arguments) { Tracing.Info("bake - transforming content into a website"); var siteContext = Generator.BuildContext(arguments.Source, arguments.Destination, arguments.Drafts); if (arguments.CleanTarget && FileSystem.Directory.Exists(siteContext.OutputFolder)) { FileSystem.Directory.Delete(siteContext.OutputFolder, true); } if (string.IsNullOrWhiteSpace(arguments.Template)) { arguments.DetectFromDirectory(TemplateEngines.Engines, siteContext); } var engine = TemplateEngines[arguments.Template]; if (engine != null) { var watch = new Stopwatch(); watch.Start(); engine.Initialize(); engine.Process(siteContext); foreach (var t in Transforms) { t.Transform(siteContext); } engine.CompressSitemap(siteContext, FileSystem); watch.Stop(); Tracing.Info("done - took {0}ms", watch.ElapsedMilliseconds); } else { Tracing.Info("Cannot find engine for input: '{0}'", arguments.Template); return(Task.FromResult(1)); } return(Task.FromResult(0)); }
#pragma warning restore 649 public void Execute(IEnumerable <string> arguments) { Tracing.Info("bake - transforming content into a website"); parameters.Parse(arguments); var siteContext = Generator.BuildContext(parameters.Path, parameters.DestinationPath, parameters.IncludeDrafts); if (parameters.CleanTarget && FileSystem.Directory.Exists(siteContext.OutputFolder)) { FileSystem.Directory.Delete(siteContext.OutputFolder, true); } if (string.IsNullOrWhiteSpace(parameters.Template)) { parameters.DetectFromDirectory(templateEngines.Engines, siteContext); } var engine = templateEngines[parameters.Template]; if (engine != null) { var watch = new Stopwatch(); watch.Start(); engine.Initialize(); engine.Process(siteContext); foreach (var t in transforms) { t.Transform(siteContext); } engine.CompressSitemap(siteContext, FileSystem); watch.Stop(); Tracing.Info(string.Format("done - took {0}ms", watch.ElapsedMilliseconds)); } else { Tracing.Info(String.Format("Cannot find engine for input: '{0}'", parameters.Template)); } }
/// <summary> /// Gets or adds a view from the cache. /// </summary> /// <param name="input">The input asset.</param> /// <param name="valueFactory">A function that produces the value that should be added to the cache in case it does not already exist.</param> /// <returns></returns> public IViewTemplate Update(IAssetFile input) { // Prepare the cache key var cacheName = input .RelativeName .Replace(input.Extension, String.Empty) .Replace(@"\", @"/"); // Attach usings too var content = this.GetUsings() + Environment.NewLine + input.Content.AsString(); Tracing.Info("Template", cacheName); // Update the map Cache.AddOrUpdate(cacheName, content, (k, v) => content ); return(new ViewTemplate(cacheName)); }
private static void Main(string[] args) { var parameters = BaseParameters.Parse(args, new FileSystem()); InitializeTrace(parameters.Debug); var program = new Program(); Tracing.Info("starting pretzel..."); Tracing.Debug("V{0}", Assembly.GetExecutingAssembly().GetName().Version); program.Compose(parameters); if (parameters.Help || !args.Any()) { program.ShowHelp(parameters.Options); return; } program.Run(parameters); }
/// <summary> /// Processes a single item. /// </summary> /// <param name="input">The input to process.</param> /// <returns>The output of the process.</returns> public override IAssetFile Process(IAssetFile input) { try { // Minify javascript var minifier = new Minifier(); var content = minifier.MinifyJavaScript(input.Content.AsString()); // Compiled successfully Tracing.Info("JS", "Minified " + input.RelativeName); // Return processed output return(AssetOutputFile.Create(input, content)); } catch (Exception ex) { // We didn't manage to create anything Tracing.Error("JS", ex); return(null); } }
private string RenderContent(string file, string contents, IDictionary <string, object> header) { string html; try { var contentsWithoutHeader = contents.ExcludeHeader(); html = string.Equals(Path.GetExtension(file), ".md", StringComparison.InvariantCultureIgnoreCase) ? Markdown.Transform(contentsWithoutHeader) : contentsWithoutHeader; html = contentTransformers.Aggregate(html, (current, contentTransformer) => contentTransformer.Transform(current)); } catch (Exception e) { Tracing.Info(String.Format("Error ({0}) converting {1}", e.Message, file)); Tracing.Debug(e.ToString()); html = String.Format("<p><b>Error converting markdown</b></p><pre>{0}</pre>", contents); } return(html); }
public void MixIn(string directory) { if (!Arguments.Azure) { return; } // Move everything under the _source folder var sourceFolder = Path.Combine(directory, "_source"); if (!fileSystem.Directory.Exists(sourceFolder)) { fileSystem.Directory.CreateDirectory(sourceFolder); } foreach (var file in fileSystem.Directory.GetFiles(directory)) { var trimStart = file.Replace(directory, string.Empty).TrimStart(Path.DirectorySeparatorChar); fileSystem.File.Move(file, Path.Combine(sourceFolder, trimStart)); } foreach (var directoryToMove in fileSystem.Directory.GetDirectories(directory).Where(n => new DirectoryInfo(n).Name != "_source")) { var trimStart = directoryToMove.Replace(directory, string.Empty).TrimStart(Path.DirectorySeparatorChar); fileSystem.Directory.Move(directoryToMove, Path.Combine(sourceFolder, trimStart)); } fileSystem.File.WriteAllText(Path.Combine(directory, @"Shim.cs"), Properties.RazorAzure.Shim); fileSystem.File.WriteAllText(Path.Combine(directory, @"Shim.csproj"), Properties.RazorAzure.ShimProject); fileSystem.File.WriteAllText(Path.Combine(directory, @"Shim.sln"), Properties.RazorAzure.ShimSolution); var currentPath = assembly.GetEntryAssemblyLocation(); var destination = Path.Combine(directory, "Pretzel.exe"); if (!fileSystem.File.Exists(destination)) { fileSystem.File.Copy(currentPath, destination); } Tracing.Info("Shim project added to allow deployment to azure websites"); }
public async void CreatesSession() { using (TestHostContext tc = CreateTestContext()) using (var tokenSource = new CancellationTokenSource()) { Tracing trace = tc.GetTrace(); // Arrange. var expectedSession = new TaskAgentSession(); _runnerServer .Setup(x => x.CreateAgentSessionAsync( _settings.PoolId, It.Is <TaskAgentSession>(y => y != null), tokenSource.Token)) .Returns(Task.FromResult(expectedSession)); _credMgr.Setup(x => x.LoadCredentials()).Returns(new VssCredentials()); _store.Setup(x => x.GetCredentials()).Returns(new CredentialData() { Scheme = Constants.Configuration.OAuthAccessToken }); _store.Setup(x => x.GetMigratedCredentials()).Returns(default(CredentialData)); // Act. MessageListener listener = new MessageListener(); listener.Initialize(tc); bool result = await listener.CreateSessionAsync(tokenSource.Token); trace.Info("result: {0}", result); // Assert. Assert.True(result); _runnerServer .Verify(x => x.CreateAgentSessionAsync( _settings.PoolId, It.Is <TaskAgentSession>(y => y != null), tokenSource.Token), Times.Once()); } }
public async Task OomScoreAdjIsWriten_FromEnv() { // We are on a system that supports oom_score_adj in procfs as assumed by ProcessInvoker string testProcPath = $"/proc/{Process.GetCurrentProcess().Id}/oom_score_adj"; if (File.Exists(testProcPath)) { using (TestHostContext hc = new TestHostContext(this)) using (var tokenSource = new CancellationTokenSource()) { Tracing trace = hc.GetTrace(); using (var processInvoker = new ProcessInvokerWrapper()) { processInvoker.Initialize(hc); int oomScoreAdj = -9999; processInvoker.OutputDataReceived += (object sender, ProcessDataReceivedEventArgs e) => { oomScoreAdj = int.Parse(e.Data); tokenSource.Cancel(); }; try { var proc = await processInvoker.ExecuteAsync("", "bash", "-c \"cat /proc/$$/oom_score_adj\"", new Dictionary <string, string> { { "PIPELINE_JOB_OOMSCOREADJ", "1234" } }, false, null, false, null, false, false, highPriorityProcess : false, cancellationToken : tokenSource.Token); Assert.Equal(oomScoreAdj, 1234); } catch (OperationCanceledException) { trace.Info("Caught expected OperationCanceledException"); } } } } }
public static async Task SetEncoding(IHostContext hostContext, Tracing trace, CancellationToken cancellationToken) { #if OS_WINDOWS try { if (Console.InputEncoding.CodePage != 65001) { using (var p = hostContext.CreateService <IProcessInvoker>()) { // Use UTF8 code page int exitCode = await p.ExecuteAsync(workingDirectory : hostContext.GetDirectory(WellKnownDirectory.Work), fileName : WhichUtil.Which("chcp", true, trace), arguments : "65001", environment : null, requireExitCodeZero : false, outputEncoding : null, killProcessOnCancel : false, redirectStandardIn : null, inheritConsoleHandler : true, cancellationToken : cancellationToken); if (exitCode == 0) { trace.Info("Successfully returned to code page 65001 (UTF8)"); } else { trace.Warning($"'chcp 65001' failed with exit code {exitCode}"); } } } } catch (Exception ex) { trace.Warning($"'chcp 65001' failed with exception {ex.Message}"); } #endif // Dummy variable to prevent compiler error CS1998: "This async method lacks 'await' operators and will run synchronously..." await Task.CompletedTask; }
private string RenderContent(string file, string contents, IDictionary <string, object> header) { string html; try { var contentsWithoutHeader = contents.ExcludeHeader(); html = Path.GetExtension(file).IsMarkdownFile() ? CommonMark.CommonMarkConverter.Convert(contentsWithoutHeader).Trim() : contentsWithoutHeader; html = contentTransformers.Aggregate(html, (current, contentTransformer) => contentTransformer.Transform(current)); } catch (Exception e) { Tracing.Info(String.Format("Error ({0}) converting {1}", e.Message, file)); Tracing.Debug(e.ToString()); html = String.Format("<p><b>Error converting markdown</b></p><pre>{0}</pre>", contents); } return(html); }
private string SafeReadLine(string file) { string postFirstLine; try { using (var reader = fileSystem.File.OpenText(file)) { postFirstLine = reader.ReadLine(); } } catch (IOException) { if (SanityCheck.IsLockedByAnotherProcess(file)) { Tracing.Info(String.Format("File {0} is locked by another process. Skipping", file)); return(string.Empty); } var fileInfo = fileSystem.FileInfo.FromFileName(file); var tempFile = Path.Combine(Path.GetTempPath(), fileInfo.Name); try { fileInfo.CopyTo(tempFile, true); using (var streamReader = fileSystem.File.OpenText(tempFile)) { return(streamReader.ReadLine()); } } finally { if (fileSystem.File.Exists(tempFile)) { fileSystem.File.Delete(tempFile); } } } return(postFirstLine); }
// Return code definition: (this will be used by service host to determine whether it will re-launch agent.listener) // 0: Agent exit // 1: Terminate failure // 2: Retriable failure // 3: Exit for self update public async static Task<int> MainAsync(string[] args) { using (HostContext context = new HostContext("Agent")) { s_trace = context.GetTrace("AgentProcess"); s_trace.Info($"Agent is built for {Constants.Agent.Platform} - {BuildConstants.AgentPackage.PackageName}."); s_trace.Info($"RuntimeInformation: {RuntimeInformation.OSDescription}."); // Validate the binaries intended for one OS are not running on a different OS. switch (Constants.Agent.Platform) { case Constants.OSPlatform.Linux: if (!RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) { Console.WriteLine(StringUtil.Loc("NotLinux")); return Constants.Agent.ReturnCode.TerminatedError; } break; case Constants.OSPlatform.OSX: if (!RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) { Console.WriteLine(StringUtil.Loc("NotOSX")); return Constants.Agent.ReturnCode.TerminatedError; } break; case Constants.OSPlatform.Windows: if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { Console.WriteLine(StringUtil.Loc("NotWindows")); return Constants.Agent.ReturnCode.TerminatedError; } break; default: Console.WriteLine(StringUtil.Loc("PlatformNotSupport", RuntimeInformation.OSDescription, Constants.Agent.Platform.ToString())); return Constants.Agent.ReturnCode.TerminatedError; } int rc = Constants.Agent.ReturnCode.Success; try { s_trace.Info($"Version: {Constants.Agent.Version}"); s_trace.Info($"Commit: {BuildConstants.Source.CommitHash}"); s_trace.Info($"Culture: {CultureInfo.CurrentCulture.Name}"); s_trace.Info($"UI Culture: {CultureInfo.CurrentUICulture.Name}"); // // TODO (bryanmac): Need VsoAgent.exe compat shim for SCM // That shim will also provide a compat arg parse // and translate / to -- etc... // // Parse the command line args. var command = new CommandSettings(context, args); s_trace.Info("Arguments parsed"); // Defer to the Agent class to execute the command. IAgent agent = context.GetService<IAgent>(); using (agent.TokenSource = new CancellationTokenSource()) { try { rc = await agent.ExecuteCommand(command); } catch (OperationCanceledException) when (agent.TokenSource.IsCancellationRequested) { s_trace.Info("Agent execution been cancelled."); } } } catch (Exception e) { Console.Error.WriteLine(StringUtil.Format("An error occured. {0}", e.Message)); s_trace.Error(e); rc = Constants.Agent.ReturnCode.RetryableError; } return rc; } }