protected override void ReadInputFile() { try { using (var sourceStream = new FileStream(InputFilePath, FileMode.Open, FileAccess.Read)) using (var binaryReader = new BinaryReader(sourceStream)) { var fileInfo = new FileInfo(InputFilePath); var fileSize = fileInfo.Length; const int intSize = 4; var chunkId = 0; while (fileSize > 0 && !hasError) { var chunkSize = binaryReader.ReadInt32(); var bytes = binaryReader.ReadBytes(chunkSize); InputQueue.Enqueue(new Chunk(chunkId++, bytes)); fileSize -= (chunkSize + intSize); if (fileSize == 0) { InputQueue.ReadComplete(); } } } } catch (Exception e) { hasError = true; } }
public void AddAsciiInput(string ascii) { foreach (char item in ascii) { InputQueue.Enqueue(item); } }
public async Task RunPluginTaskAsync(IExecutionContext context, string plugin, Dictionary <string, string> inputs, Dictionary <string, string> environment, Variables runtimeVariables, EventHandler <ProcessDataReceivedEventArgs> outputHandler) { ArgUtil.NotNullOrEmpty(plugin, nameof(plugin)); // Only allow plugins we defined if (!_taskPlugins.Contains(plugin)) { throw new NotSupportedException(plugin); } // Resolve the working directory. string workingDirectory = HostContext.GetDirectory(WellKnownDirectory.Work); ArgUtil.Directory(workingDirectory, nameof(workingDirectory)); // Agent.PluginHost string file = Path.Combine(HostContext.GetDirectory(WellKnownDirectory.Bin), $"Agent.PluginHost{Util.IOUtil.ExeExtension}"); ArgUtil.File(file, $"Agent.PluginHost{Util.IOUtil.ExeExtension}"); // Agent.PluginHost's arguments string arguments = $"task \"{plugin}\""; // construct plugin context var target = context.StepTarget(); AgentTaskPluginExecutionContext pluginContext = new AgentTaskPluginExecutionContext { Inputs = inputs, Repositories = context.Repositories, Endpoints = context.Endpoints, Container = target is ContainerInfo ? target as ContainerInfo : null, //TODO: Figure out if this needs to have all the containers or just the one for the current step JobSettings = context.JobSettings, }; // variables runtimeVariables.CopyInto(pluginContext.Variables); context.TaskVariables.CopyInto(pluginContext.TaskVariables); using (var processInvoker = HostContext.CreateService <IProcessInvoker>()) { var redirectStandardIn = new InputQueue <string>(); redirectStandardIn.Enqueue(JsonUtility.ToString(pluginContext)); processInvoker.OutputDataReceived += outputHandler; processInvoker.ErrorDataReceived += outputHandler; // Execute the process. Exit code 0 should always be returned. // A non-zero exit code indicates infrastructural failure. // Task failure should be communicated over STDOUT using ## commands. await processInvoker.ExecuteAsync(workingDirectory : workingDirectory, fileName : file, arguments : arguments, environment : environment, requireExitCodeZero : true, outputEncoding : Encoding.UTF8, killProcessOnCancel : false, redirectStandardIn : redirectStandardIn, cancellationToken : context.CancellationToken); } }
protected override void ReadInFile() { try { var fileSize = InputFileStream.Length; using (var binaryReader = new BinaryReader(InputFileStream)) { var chunkId = 0; while (fileSize > 0 && HasError == null) { var currentChunkSize = fileSize > Const.ChunkSize ? Const.ChunkSize : fileSize; var bytes = binaryReader.ReadBytes((int)currentChunkSize); InputQueue.Enqueue(new Chunk(chunkId++, bytes)); fileSize -= currentChunkSize; if (fileSize == 0) { InputQueue.ReadComplete(); } } } } catch (Exception e) { SingleLogger.log.Error($"(Your exception is :{e.Message} , send a log file for us from the folder /bin/Debug/myapp.log"); SingleLogger.log.Debug($"(Your exception is :{e.Message} , send a log file for us from the folder /bin/Debug/myapp.log"); HasError = e; } }
public void Multiple_enqueues_then_dequeues_complete_sync_in_order() { InputQueue<string> queue = new InputQueue<string>(); queue.Enqueue("a"); queue.Enqueue("b"); Task<string> task = queue.DequeueAsync(); Assert.Equal(TaskStatus.RanToCompletion, task.Status); Assert.Equal("a", task.Result); task = queue.DequeueAsync(); Assert.Equal(TaskStatus.RanToCompletion, task.Status); Assert.Equal("b", task.Result); }
public void Multiple_enqueues_then_dequeues_complete_sync_in_order() { InputQueue <string> queue = new InputQueue <string>(); queue.Enqueue("a"); queue.Enqueue("b"); Task <string> task = queue.DequeueAsync(); Assert.Equal(TaskStatus.RanToCompletion, task.Status); Assert.Equal("a", task.Result); task = queue.DequeueAsync(); Assert.Equal(TaskStatus.RanToCompletion, task.Status); Assert.Equal("b", task.Result); }
public void Enqueue_then_dequeue_repeated_twice_completes_sync() { InputQueue<string> queue = new InputQueue<string>(); queue.Enqueue("a"); Task<string> task = queue.DequeueAsync(); Assert.Equal(TaskStatus.RanToCompletion, task.Status); Assert.Equal("a", task.Result); queue.Enqueue("b"); task = queue.DequeueAsync(); Assert.Equal(TaskStatus.RanToCompletion, task.Status); Assert.Equal("b", task.Result); }
public IntcodeComputer(int[] memory, IEnumerable <int> inputs) { Memory = memory; foreach (var input in inputs) { InputQueue.Enqueue(input); } OutputBuffer = new List <int>(); }
public void Enqueue_then_dequeue_repeated_twice_completes_sync() { InputQueue <string> queue = new InputQueue <string>(); queue.Enqueue("a"); Task <string> task = queue.DequeueAsync(); Assert.Equal(TaskStatus.RanToCompletion, task.Status); Assert.Equal("a", task.Result); queue.Enqueue("b"); task = queue.DequeueAsync(); Assert.Equal(TaskStatus.RanToCompletion, task.Status); Assert.Equal("b", task.Result); }
public void Dispose_causes_subsequent_enqueue_and_dequeue_to_throw_ObjectDisposed() { InputQueue <string> queue = new InputQueue <string>(); queue.Dispose(); Assert.Throws <ObjectDisposedException>(() => queue.Enqueue("a")); Assert.Throws <ObjectDisposedException>(() => queue.DequeueAsync()); }
/// <summary> /// Add a GenericInput into the InputQueque. /// </summary> /// <param name="gi">A GenericInput to add to the Queque.</param> /// <returns>Returns true if the GenericInput has been inserted successfully, else false.</returns> public static bool AddInputItem(GenericInput gi) { lock (input_queue_lock) { int count_before_add = InputQueue.Count; InputQueue.Enqueue(gi); int count_after_add = InputQueue.Count; return(count_after_add > count_before_add); } }
public void Dequeue_completes_after_enqueue() { InputQueue<string> queue = new InputQueue<string>(); Task<string> task = queue.DequeueAsync(); Assert.False(task.IsCompleted); queue.Enqueue("a"); Assert.Equal(TaskStatus.RanToCompletion, task.Status); Assert.Equal("a", task.Result); }
public void Dequeue_completes_after_enqueue() { InputQueue <string> queue = new InputQueue <string>(); Task <string> task = queue.DequeueAsync(); Assert.False(task.IsCompleted); queue.Enqueue("a"); Assert.Equal(TaskStatus.RanToCompletion, task.Status); Assert.Equal("a", task.Result); }
public void QueueInput(IReadOnlyCollection <AsciiKey> keys) { //0.K foreach (var key in keys) { // Escape key processing may skip the normal input queue, // to make 'Quit Game' as reliably available as possible. if (key == Keys.Escape && ShouldClearQueueOnEscape()) { InputQueue.Clear(); return; } InputQueue.Enqueue(key); } }
public async Task RunPluginTaskAsync(IExecutionContext context, string plugin, Dictionary <string, string> inputs, Dictionary <string, string> environment, Variables runtimeVariables, EventHandler <ProcessDataReceivedEventArgs> outputHandler) { ArgUtil.NotNullOrEmpty(plugin, nameof(plugin)); // Only allow plugins we defined if (!_taskPlugins.Contains(plugin)) { throw new NotSupportedException(plugin); } // Resolve the working directory. string workingDirectory = HostContext.GetDirectory(WellKnownDirectory.Work); ArgUtil.Directory(workingDirectory, nameof(workingDirectory)); // Agent.PluginHost string file = Path.Combine(HostContext.GetDirectory(WellKnownDirectory.Bin), $"Agent.PluginHost{Util.IOUtil.ExeExtension}"); ArgUtil.File(file, $"Agent.PluginHost{Util.IOUtil.ExeExtension}"); var pluginContext = GeneratePluginExecutionContext(context, inputs, runtimeVariables); using (var processInvoker = HostContext.CreateService <IProcessInvoker>()) using (var redirectStandardIn = new InputQueue <string>()) { redirectStandardIn.Enqueue(JsonUtility.ToString(pluginContext)); processInvoker.OutputDataReceived += outputHandler; processInvoker.ErrorDataReceived += outputHandler; // Execute the process. Exit code 0 should always be returned. // A non-zero exit code indicates infrastructural failure. // Task failure should be communicated over STDOUT using ## commands. // Agent.PluginHost's arguments string arguments = $"task \"{plugin}\""; await processInvoker.ExecuteAsync(workingDirectory : workingDirectory, fileName : file, arguments : arguments, environment : environment, requireExitCodeZero : true, outputEncoding : Encoding.UTF8, killProcessOnCancel : false, redirectStandardIn : redirectStandardIn, cancellationToken : context.CancellationToken); } }
public long Run(params long[] inputParams) { long rv = 0; RelativeBase = 0; InstructionPtr = 0; Array.ForEach(inputParams, e => InputQueue.Enqueue(e)); bool running = true; while (running) { rv = RunNext(); running = rv == long.MinValue; } return(rv); }
private async Task <int> ExecuteDockerCommandAsync(IExecutionContext context, string command, string options, IList <string> standardIns = null, CancellationToken cancellationToken = default(CancellationToken)) { string arg = $"{command} {options}".Trim(); context.Command($"{DockerPath} {arg}"); var processInvoker = HostContext.CreateService <IProcessInvoker>(); processInvoker.OutputDataReceived += delegate(object sender, ProcessDataReceivedEventArgs message) { context.Output(message.Data); }; processInvoker.ErrorDataReceived += delegate(object sender, ProcessDataReceivedEventArgs message) { context.Output(message.Data); }; InputQueue <string> redirectStandardIn = null; if (standardIns != null) { redirectStandardIn = new InputQueue <string>(); foreach (var input in standardIns) { redirectStandardIn.Enqueue(input); } } using (redirectStandardIn) { return(await processInvoker.ExecuteAsync( workingDirectory : HostContext.GetDirectory(WellKnownDirectory.Work), fileName : DockerPath, arguments : arg, environment : null, requireExitCodeZero : false, outputEncoding : null, killProcessOnCancel : false, redirectStandardIn : redirectStandardIn, cancellationToken : cancellationToken)); } }
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 void HandleFromServerManager(IViewNet.Common.Models.Packet Message) { if (Message.Code == 1111) // SetDetectionType { //Send to all children the detection type Input.Process(new IViewNet.Common.Models.Packet(5555, "SetDetectionType", Message.Content)); } else if (Message.Code == 1112) // SetOrientation { //Set the orientation of the image and then send it to the children } else if (Message.Code == 1113) // GetDetectedFrame { Input.Enqueue(new Frame(Message.Content, FrameCounter)); FrameCounter++; } else { Logger.Log(new Log("Invalid packet code: " + Message.Code, ConsoleColor.Red)); } }
private void ProcessGameInstruction() { if (XPos < 0 && YPos == 0) { Score = TileID; Console.WriteLine("Score = {0}", Score); } else { switch (TileID) { case 3: // paddle position PaddleX = XPos; break; case 4: // ball position BallX = XPos; if (PaddleX == BallX) { InputQueue.Enqueue(0); // leave paddle horizontal } else if (PaddleX > BallX) { InputQueue.Enqueue(-1); // move left } else { InputQueue.Enqueue(1); // move right } break; default: break; } } }
private async Task ProcessPluginCommandAsync(IAsyncCommandContext context, AgentCommandPluginExecutionContext pluginContext, string plugin, Command command, CancellationToken token) { // Resolve the working directory. string workingDirectory = HostContext.GetDirectory(WellKnownDirectory.Work); ArgUtil.Directory(workingDirectory, nameof(workingDirectory)); // Agent.PluginHost string file = Path.Combine(HostContext.GetDirectory(WellKnownDirectory.Bin), $"Agent.PluginHost{Util.IOUtil.ExeExtension}"); // Agent.PluginHost's arguments string arguments = $"command \"{plugin}\""; // Execute the process. Exit code 0 should always be returned. // A non-zero exit code indicates infrastructural failure. // Any content coming from STDERR will indicate the command process failed. // We can't use ## command for plugin to communicate, since we are already processing ## command using (var processInvoker = HostContext.CreateService <IProcessInvoker>()) { object stderrLock = new object(); List <string> stderr = new List <string>(); processInvoker.OutputDataReceived += (object sender, ProcessDataReceivedEventArgs e) => { context.Output(e.Data); }; processInvoker.ErrorDataReceived += (object sender, ProcessDataReceivedEventArgs e) => { lock (stderrLock) { stderr.Add(e.Data); }; }; var redirectStandardIn = new InputQueue <string>(); redirectStandardIn.Enqueue(JsonUtility.ToString(pluginContext)); int returnCode = await processInvoker.ExecuteAsync(workingDirectory : workingDirectory, fileName : file, arguments : arguments, environment : null, requireExitCodeZero : false, outputEncoding : null, killProcessOnCancel : false, redirectStandardIn : redirectStandardIn, cancellationToken : token); if (returnCode != 0) { context.Output(string.Join(Environment.NewLine, stderr)); throw new ProcessExitCodeException(returnCode, file, arguments); } else if (stderr.Count > 0) { throw new InvalidOperationException(string.Join(Environment.NewLine, stderr)); } else { // Everything works fine. // Return code is 0. // No STDERR comes out. } } }
public async Task <int> ExecuteAsync(string workingDirectory, string fileName, string arguments, IDictionary <string, string> environment, bool requireExitCodeZero, Encoding outputEncoding, bool killProcessOnCancel, bool inheritConsoleHandler, CancellationToken cancellationToken) { // make sure container exist. ArgUtil.NotNull(Container, nameof(Container)); ArgUtil.NotNullOrEmpty(Container.ContainerId, nameof(Container.ContainerId)); var dockerManger = HostContext.GetService <IDockerCommandManager>(); string containerEnginePath = dockerManger.DockerPath; ContainerStandardInPayload payload = new ContainerStandardInPayload() { ExecutionHandler = fileName, ExecutionHandlerWorkingDirectory = workingDirectory, ExecutionHandlerArguments = arguments, ExecutionHandlerEnvironment = environment, ExecutionHandlerPrependPath = PrependPath }; // copy the intermediate script (containerHandlerInvoker.js) into Agent_TempDirectory // Background: // We rely on environment variables to send task execution information from agent to task execution engine (node/powershell) // Those task execution information will include all the variables and secrets customer has. // The only way to pass environment variables to `docker exec` is through command line arguments, ex: `docker exec -e myenv=myvalue -e mysecert=mysecretvalue ...` // Since command execution may get log into system event log which might cause secret leaking. // We use this intermediate script to read everything from STDIN, then launch the task execution engine (node/powershell) and redirect STDOUT/STDERR string tempDir = Path.Combine(HostContext.GetDirectory(WellKnownDirectory.Work), Constants.Path.TempDirectory); string targetEntryScript = Path.Combine(tempDir, "containerHandlerInvoker.js"); HostContext.GetTrace(nameof(ContainerStepHost)).Info($"Copying containerHandlerInvoker.js to {tempDir}"); File.Copy(Path.Combine(HostContext.GetDirectory(WellKnownDirectory.Bin), "containerHandlerInvoker.js.template"), targetEntryScript, true); string node; if (!string.IsNullOrEmpty(Container.CustomNodePath)) { node = Container.CustomNodePath; } else { node = Container.TranslateToContainerPath(Path.Combine(HostContext.GetDirectory(WellKnownDirectory.Externals), "node", "bin", $"node{IOUtil.ExeExtension}")); } string entryScript = Container.TranslateContainerPathForImageOS(PlatformUtil.HostOS, Container.TranslateToContainerPath(targetEntryScript)); string userArgs = ""; if (!PlatformUtil.RunningOnWindows) { userArgs = $"-u {Container.CurrentUserId}"; } string containerExecutionArgs = $"exec -i {userArgs} {Container.ContainerId} {node} {entryScript}"; using (var processInvoker = HostContext.CreateService <IProcessInvoker>()) { processInvoker.OutputDataReceived += OutputDataReceived; processInvoker.ErrorDataReceived += ErrorDataReceived; outputEncoding = null; // Let .NET choose the default. if (PlatformUtil.RunningOnWindows) { // It appears that node.exe outputs UTF8 when not in TTY mode. outputEncoding = Encoding.UTF8; } var redirectStandardIn = new InputQueue <string>(); var payloadJson = JsonUtility.ToString(payload); redirectStandardIn.Enqueue(payloadJson); HostContext.GetTrace(nameof(ContainerStepHost)).Info($"Payload: {payloadJson}"); return(await processInvoker.ExecuteAsync(workingDirectory : HostContext.GetDirectory(WellKnownDirectory.Work), fileName : containerEnginePath, arguments : containerExecutionArgs, environment : null, requireExitCodeZero : requireExitCodeZero, outputEncoding : outputEncoding, killProcessOnCancel : killProcessOnCancel, redirectStandardIn : redirectStandardIn, inheritConsoleHandler : inheritConsoleHandler, cancellationToken : cancellationToken)); } }
public async Task RunPluginTaskAsync(IExecutionContext context, string plugin, Dictionary <string, string> inputs, Dictionary <string, string> environment, Variables runtimeVariables, EventHandler <ProcessDataReceivedEventArgs> outputHandler) { ArgUtil.NotNullOrEmpty(plugin, nameof(plugin)); // Only allow plugins we defined if (!_taskPlugins.Contains(plugin)) { throw new NotSupportedException(plugin); } // Resolve the working directory. string workingDirectory = HostContext.GetDirectory(WellKnownDirectory.Work); ArgUtil.Directory(workingDirectory, nameof(workingDirectory)); // Agent.PluginHost string file = Path.Combine(HostContext.GetDirectory(WellKnownDirectory.Bin), $"Agent.PluginHost{Util.IOUtil.ExeExtension}"); ArgUtil.File(file, $"Agent.PluginHost{Util.IOUtil.ExeExtension}"); // Agent.PluginHost's arguments string arguments = $"task \"{plugin}\""; // construct plugin context var target = context.StepTarget(); Variables.TranslationMethod translateToHostPath = Variables.DefaultStringTranslator; ContainerInfo containerInfo = target as ContainerInfo; // Since plugins run on the host, but the inputs and variables have already been translated // to the container path, we need to convert them back to the host path // TODO: look to see if there is a better way to not have translate these back if (containerInfo != null) { var newInputs = new Dictionary <string, string>(); foreach (var entry in inputs) { newInputs[entry.Key] = containerInfo.TranslateToHostPath(entry.Value); } inputs = newInputs; translateToHostPath = (string val) => { return(containerInfo.TranslateToHostPath(val)); }; } AgentTaskPluginExecutionContext pluginContext = new AgentTaskPluginExecutionContext { Inputs = inputs, Repositories = context.Repositories, Endpoints = context.Endpoints, Container = containerInfo, //TODO: Figure out if this needs to have all the containers or just the one for the current step JobSettings = context.JobSettings, }; // variables runtimeVariables.CopyInto(pluginContext.Variables, translateToHostPath); context.TaskVariables.CopyInto(pluginContext.TaskVariables, translateToHostPath); using (var processInvoker = HostContext.CreateService <IProcessInvoker>()) { var redirectStandardIn = new InputQueue <string>(); redirectStandardIn.Enqueue(JsonUtility.ToString(pluginContext)); processInvoker.OutputDataReceived += outputHandler; processInvoker.ErrorDataReceived += outputHandler; // Execute the process. Exit code 0 should always be returned. // A non-zero exit code indicates infrastructural failure. // Task failure should be communicated over STDOUT using ## commands. await processInvoker.ExecuteAsync(workingDirectory : workingDirectory, fileName : file, arguments : arguments, environment : environment, requireExitCodeZero : true, outputEncoding : Encoding.UTF8, killProcessOnCancel : false, redirectStandardIn : redirectStandardIn, cancellationToken : context.CancellationToken); } }
/// <summary> /// Receives the table element data from the calling app (e.g. B2S.Server providing data through the plugin interface).<br/> /// The received data is put in a queue and the internal thread of the framework is notified about the availability of new data. /// </summary> /// <param name="TableElementTypeChar">The table element type char as specified in the TableElementTypeEnum.</param> /// <param name="Number">The number of the TableElement.</param> /// <param name="Value">The value of the TableElement.</param> public void ReceiveData(char TableElementTypeChar, int Number, int Value) { InputQueue.Enqueue(TableElementTypeChar, Number, Value); MainThreadSignal(); //ThreadInfoList.HeartBeat("Data delivery"); }
public Task StartAsync(IExecutionContext context, List <IStep> steps, CancellationToken token) { Trace.Entering(); ArgUtil.NotNull(context, nameof(context)); List <PluginInfo> enabledPlugins = new List <PluginInfo>(); if (context.Variables.GetBoolean("agent.disablelogplugin") ?? false) { // all log plugs are disabled context.Debug("All log plugins are disabled."); } else { foreach (var plugin in _logPlugins) { if (context.Variables.GetBoolean($"agent.disablelogplugin.{plugin.Key}") ?? false) { // skip plugin context.Debug($"Log plugin '{plugin.Key}' is disabled."); continue; } else { enabledPlugins.Add(plugin.Value); } } } if (enabledPlugins.Count > 0) { // Resolve the working directory. string workingDirectory = HostContext.GetDirectory(WellKnownDirectory.Work); ArgUtil.Directory(workingDirectory, nameof(workingDirectory)); // Agent.PluginHost string file = Path.Combine(HostContext.GetDirectory(WellKnownDirectory.Bin), $"Agent.PluginHost{Util.IOUtil.ExeExtension}"); ArgUtil.File(file, $"Agent.PluginHost{Util.IOUtil.ExeExtension}"); // Agent.PluginHost's arguments string arguments = $"log \"{_instanceId.ToString("D")}\""; var processInvoker = HostContext.CreateService <IProcessInvoker>(); processInvoker.OutputDataReceived += (object sender, ProcessDataReceivedEventArgs e) => { if (e.Data != null) { _outputs.Enqueue(e.Data); } }; processInvoker.ErrorDataReceived += (object sender, ProcessDataReceivedEventArgs e) => { if (e.Data != null) { _outputs.Enqueue(e.Data); } }; _pluginHostProcess?.Dispose(); _pluginHostProcess = processInvoker.ExecuteAsync(workingDirectory: workingDirectory, fileName: file, arguments: arguments, environment: null, requireExitCodeZero: true, outputEncoding: Encoding.UTF8, killProcessOnCancel: true, redirectStandardIn: _redirectedStdin, inheritConsoleHandler: false, keepStandardInOpen: true, cancellationToken: token); // construct plugin context AgentLogPluginHostContext pluginContext = new AgentLogPluginHostContext { PluginAssemblies = new List <string>(), Repositories = context.Repositories, Endpoints = context.Endpoints, Variables = new Dictionary <string, VariableValue>(), Steps = new Dictionary <string, Pipelines.TaskStepDefinitionReference>() }; // plugins pluginContext.PluginAssemblies.AddRange(_logPlugins.Values.Select(x => x.AssemblyName)); var target = context.StepTarget(); Variables.TranslationMethod translateToHostPath = Variables.DefaultStringTranslator; ContainerInfo containerInfo = target as ContainerInfo; // Since plugins run on the host, but the inputs and variables have already been translated // to the container path, we need to convert them back to the host path // TODO: look to see if there is a better way to not have translate these back if (containerInfo != null) { translateToHostPath = (string val) => { return(containerInfo.TranslateToHostPath(val)); }; } // variables context.Variables.CopyInto(pluginContext.Variables, translateToHostPath); // steps foreach (var step in steps) { var taskStep = step as ITaskRunner; if (taskStep != null) { pluginContext.Steps[taskStep.ExecutionContext.Id.ToString("D")] = taskStep.Task.Reference; } } Trace.Info("Send serialized context through STDIN"); _redirectedStdin.Enqueue(JsonUtility.ToString(pluginContext)); foreach (var plugin in _logPlugins) { context.Output($"Plugin: '{plugin.Value.FriendlyName}' is running in background."); } } return(Task.CompletedTask); }
public void Dispose_causes_subsequent_enqueue_and_dequeue_to_throw_ObjectDisposed() { InputQueue<string> queue = new InputQueue<string>(); queue.Dispose(); Assert.Throws<ObjectDisposedException>(() => queue.Enqueue("a")); Assert.Throws<ObjectDisposedException>(() => queue.DequeueAsync()); }
public void AddInput(int value) { InputQueue.Enqueue(value); TryReleaseSemaphore(); }
public Task StartAsync(IExecutionContext context, List <IStep> steps, CancellationToken token) { Trace.Entering(); ArgUtil.NotNull(context, nameof(context)); List <PluginInfo> enabledPlugins = new List <PluginInfo>(); if (context.Variables.GetBoolean("agent.disablelogplugin") ?? false) { // all log plugs are disabled context.Debug("All log plugins are disabled."); } else { foreach (var plugin in _logPlugins) { if (context.Variables.GetBoolean($"agent.disablelogplugin.{plugin.Key}") ?? false) { // skip plugin context.Debug($"Log plugin '{plugin.Key}' is disabled."); continue; } else { enabledPlugins.Add(plugin.Value); } } } if (enabledPlugins.Count > 0) { // Resolve the working directory. string workingDirectory = HostContext.GetDirectory(WellKnownDirectory.Work); ArgUtil.Directory(workingDirectory, nameof(workingDirectory)); // Agent.PluginHost string file = Path.Combine(HostContext.GetDirectory(WellKnownDirectory.Bin), $"Agent.PluginHost{Util.IOUtil.ExeExtension}"); ArgUtil.File(file, $"Agent.PluginHost{Util.IOUtil.ExeExtension}"); // Agent.PluginHost's arguments string arguments = $"log \"{_instanceId.ToString("D")}\""; var processInvoker = HostContext.CreateService <IProcessInvoker>(); processInvoker.OutputDataReceived += (object sender, ProcessDataReceivedEventArgs e) => { if (!string.IsNullOrEmpty(e.Data)) { _outputs.Enqueue(e.Data); } }; processInvoker.ErrorDataReceived += (object sender, ProcessDataReceivedEventArgs e) => { if (!string.IsNullOrEmpty(e.Data)) { _outputs.Enqueue(e.Data); } }; _pluginHostProcess = processInvoker.ExecuteAsync(workingDirectory: workingDirectory, fileName: file, arguments: arguments, environment: null, requireExitCodeZero: true, outputEncoding: Encoding.UTF8, killProcessOnCancel: true, redirectStandardIn: _redirectedStdin, cancellationToken: token); // construct plugin context AgentLogPluginHostContext pluginContext = new AgentLogPluginHostContext { PluginAssemblies = new List <string>(), Repositories = context.Repositories, Endpoints = context.Endpoints, Variables = new Dictionary <string, VariableValue>(), Steps = new Dictionary <string, Pipelines.TaskStepDefinitionReference>() }; // plugins pluginContext.PluginAssemblies.AddRange(_logPlugins.Values.Select(x => x.AssemblyName)); // variables foreach (var publicVar in context.Variables.Public) { pluginContext.Variables[publicVar.Key] = publicVar.Value; } foreach (var privateVar in context.Variables.Private) { pluginContext.Variables[privateVar.Key] = new VariableValue(privateVar.Value, true); } // steps foreach (var step in steps) { var taskStep = step as ITaskRunner; if (taskStep != null) { pluginContext.Steps[taskStep.ExecutionContext.Id.ToString("D")] = taskStep.Task.Reference; } } Trace.Info("Send serialized context through STDIN"); _redirectedStdin.Enqueue(JsonUtility.ToString(pluginContext)); foreach (var plugin in _logPlugins) { context.Output($"Plugin: '{plugin.Value.FriendlyName}' is running in background."); } } return(Task.CompletedTask); }