Exemplo n.º 1
0
        /// <summary>
        /// Executes a program entry point asynchronously, streaming some bytes as standard input,
        /// passing arguments and returning the result.
        /// </summary>
        /// <param name="mainAsync">The program entry point.</param>
        /// <param name="inputBytes">The bytes to be passed as standard input.</param>
        /// <param name="args">The arguments.</param>
        /// <returns>The <see cref="ExecuteResponse"/> returned by the simulated program run.</returns>
        public async Task <ExecuteResponse> ExecuteWithInputAsync(ProgramEntrypointAsync mainAsync, byte[] inputBytes, params string[] args)
        {
            await SyncContext.Clear;

            Covenant.Requires <ArgumentNullException>(mainAsync != null, nameof(mainAsync));
            Covenant.Requires <ArgumentNullException>(inputBytes != null, nameof(inputBytes));

            this.inputBytes = inputBytes;

            if (programThread != null)
            {
                throw new InvalidOperationException("Only one simulated [program] can run at a time.");
            }

            var orgSTDOUT = Console.Out;
            var orgSTDERR = Console.Error;

            try
            {
                // Capture standard output and error and stream the input
                // text as STDIN.

                var sbOut = new StringBuilder();
                var sbErr = new StringBuilder();

                using (var stdOutCapture = new StringWriter(sbOut))
                {
                    using (var stdErrCapture = new StringWriter(sbErr))
                    {
                        var exitCode = 0;

                        Console.SetOut(stdOutCapture);
                        Console.SetError(stdErrCapture);

                        // Simulate executing the program.

                        programThread = new Thread(new ThreadStart(() => exitCode = mainAsync(args).Result));
                        programThread.Start();
                        programThread.Join();
                        programThread = null;

                        return(await Task.FromResult(
                                   new ExecuteResponse()
                        {
                            ExitCode = exitCode,
                            OutputText = sbOut.ToString(),
                            ErrorText = sbErr.ToString()
                        }));
                    }
                }
            }
            finally
            {
                // Restore the standard files.

                Console.SetOut(orgSTDOUT);
                Console.SetError(orgSTDERR);
            }
        }
Exemplo n.º 2
0
        /// <summary>
        /// Executes a program entry point asynchronously, streaming some text as standard input,
        /// passing arguments and returning the result.
        /// </summary>
        /// <param name="mainAsync">The program entry point.</param>
        /// <param name="inputText">The text to be passed as standard input.</param>
        /// <param name="args">The arguments.</param>
        /// <returns>The <see cref="ExecuteResponse"/> returned by the simulated program run.</returns>
        public async Task <ExecuteResponse> ExecuteWithInputAsync(ProgramEntrypointAsync mainAsync, string inputText, params string[] args)
        {
            await SyncContext.Clear;

            Covenant.Requires <ArgumentNullException>(mainAsync != null, nameof(mainAsync));
            Covenant.Requires <ArgumentNullException>(inputText != null, nameof(inputText));

            return(await ExecuteWithInputAsync(mainAsync, Encoding.UTF8.GetBytes(inputText), args));
        }