private void RunProcess(ObservableProcess process, Action <LineOut> onLine = null)
        {
            var capturedLines       = new List <string>();
            ExceptionDispatchInfo e = null;

            process.SubscribeLines(line =>
            {
                capturedLines.Add(line.Line);
                onLine?.Invoke(line);
            },
                                   exception => e = ExceptionDispatchInfo.Capture(exception));

            var completed = process.WaitForCompletion(_defaultTimeout);

            if (!completed)
            {
                process.Dispose();
                throw new TerraformResourceException(
                          $"terraform {_resourceDirectory} timed out after {_defaultTimeout}", -1, capturedLines);
            }

            if (e != null)
            {
                throw new TerraformResourceException(
                          $"terraform {_resourceDirectory} did not succeed", e.SourceException);
            }

            if (process.ExitCode != 0)
            {
                throw new TerraformResourceException(
                          $"terraform {_resourceDirectory} did not succeed", process.ExitCode.Value, capturedLines);
            }
        }
Example #2
0
        public void SingleLine()
        {
            var seen    = new List <string>();
            var process = new ObservableProcess(TestCaseArguments(nameof(SingleLine)));

            process.SubscribeLines(c => seen.Add(c.Line), e => throw e);
            process.WaitForCompletion(WaitTimeout);

            seen.Should().NotBeEmpty().And.HaveCount(1, string.Join(Environment.NewLine, seen));
            seen[0].Should().Be(nameof(SingleLine));
        }
Example #3
0
        /// <summary>
        /// Starts the sample application and returns the <see cref="Uri" /> on which the application
        /// can be reached.
        /// </summary>
        /// <param name="targetFramework">
        /// The target framework under which to run the profiled app. Must be a version supported in
        /// the TargetFrameworks of the profiled app
        /// </param>
        /// <param name="timeout">A timeout to wait for the process to complete.</param>
        /// <param name="environmentVariables">
        /// The environment variables to start the sample app with. The profiler
        /// environment variables will be added.
        /// </param>
        /// <param name="msBuildProperties">
        ///	MsBuild properties passed to dotnet publish when compiling the sample app.
        /// Appended to dotnet publish with the form <code>-p:{key}={value}</code>
        /// </param>
        /// <param name="onNext">delegate to call when line is received</param>
        /// <param name="onException">delegate to call when exception occurs</param>
        /// <returns></returns>
        public void Start(
            string targetFramework,
            TimeSpan timeout,
            IDictionary <string, string> environmentVariables = null,
            IDictionary <string, string> msBuildProperties    = null,
            Action <LineOut> onNext        = null,
            Action <Exception> onException = null,
            bool doNotWaitForCompletion    = false,
            bool useLocalhostHttp5000      = false
            )
        {
            var properties       = CreateMsBuildProperties(msBuildProperties);
            var outputDirectory  = GetPublishOutputDirectory(targetFramework, properties);
            var workingDirectory = Path.Combine(_projectDirectory, _publishDirectory, outputDirectory);

            Publish(targetFramework, workingDirectory, properties);

            environmentVariables ??= new Dictionary <string, string>();
            environmentVariables["CORECLR_ENABLE_PROFILING"] = "1";
            environmentVariables["CORECLR_PROFILER"]         = ProfilerClassId;
            environmentVariables["CORECLR_PROFILER_PATH"]    = _profilerPath;

            environmentVariables["COR_ENABLE_PROFILING"] = "1";
            environmentVariables["COR_PROFILER"]         = ProfilerClassId;
            environmentVariables["COR_PROFILER_PATH"]    = _profilerPath;

            environmentVariables["ELASTIC_APM_PROFILER_HOME"] =
                Path.Combine(SolutionPaths.Root, "src", "Elastic.Apm.Profiler.Managed", "bin", "Release");
            environmentVariables["ELASTIC_APM_PROFILER_INTEGRATIONS"] =
                Path.Combine(SolutionPaths.Root, "src", "Elastic.Apm.Profiler.Managed", "integrations.yml");

            environmentVariables["ELASTIC_APM_PROFILER_LOG"] = "trace";
            // log to relative logs directory for managed loader
            environmentVariables["ELASTIC_APM_PROFILER_LOG_DIR"] = Path.Combine(SolutionPaths.Root, "logs");

            //environmentVariables["ELASTIC_APM_PROFILER_LOG_TARGETS"] = "file;stdout";
            //environmentVariables["ELASTIC_APM_PROFILER_LOG_IL"] = "true";

            // use the .exe for net461
            var arguments = targetFramework == "net461"
                                ? new StartArguments(Path.Combine(workingDirectory, $"{_projectName}.exe"))
                                : useLocalhostHttp5000 ? new StartArguments("dotnet", $"{_projectName}.dll", "--urls", "http://localhost:5000") : new StartArguments("dotnet", $"{_projectName}.dll");

            arguments.Environment      = environmentVariables;
            arguments.WorkingDirectory = workingDirectory;

            _process = new ObservableProcess(arguments);
            _process.SubscribeLines(onNext ?? (_ => { }), onException ?? (_ => { }));

            if (!doNotWaitForCompletion)
            {
                _process.WaitForCompletion(timeout);
            }
        }
Example #4
0
        public void DelayedWriter()
        {
            var seen         = new List <string>();
            var process      = new ObservableProcess(TestCaseArguments(nameof(DelayedWriter)));
            var subscription = process.SubscribeLines(c => seen.Add(c.Line));

            subscription.Dispose();
            process.WaitForCompletion(WaitTimeout);

            //disposing the subscription did not kill the process
            process.ExitCode.Should().Be(20);
            seen.Should().BeEmpty(string.Join(Environment.NewLine, seen));
        }
        public void SubscribeLinesSeesAllLines()
        {
            var args = TestCaseArguments("TrailingLines");
            var o    = new ObservableProcess(args);
            var seen = new List <LineOut>();

            o.SubscribeLines(l => seen.Add(l));
            o.WaitForCompletion(WaitTimeout);
            seen.Should().NotBeEmpty().And.HaveCount(_expected.Count(c => c == '\n'));
            for (var i = 0; i < seen.Count; i++)
            {
                seen[i].Line.Should().Be(_expectedLines[i], i.ToString());
            }
        }
Example #6
0
        public void SubscribeLinesSeesAllLines()
        {
            var args = TestCaseArguments("MoreText");
            var o    = new ObservableProcess(args);
            var seen = new List <LineOut>();

            o.SubscribeLines(l => seen.Add(l));
            o.WaitForCompletion(WaitTimeout);
            seen.Should().NotBeEmpty().And.HaveCount(_expectedLines.Length, string.Join("\r\n", seen.Select(s => s.Line)));
            for (var i = 0; i < seen.Count; i++)
            {
                seen[i].Line.Should().Be(_expectedLines[i], i.ToString());
            }
        }
Example #7
0
        public void DelayedWriterStopWaitToShort()
        {
            var seen = new List <string>();
            var args = TestCaseArguments(nameof(DelayedWriter));

            args.WaitForExit = TimeSpan.FromMilliseconds(200);
            var process = new ObservableProcess(args);

            process.SubscribeLines(c => seen.Add(c.Line));
            process.Dispose();
            process.WaitForCompletion(WaitTimeout);

            process.ExitCode.Should().Be(-1);
            seen.Should().BeEmpty(string.Join(Environment.NewLine, seen));
        }
Example #8
0
        public void DelayedWriterRunsToCompletion()
        {
            var       seen         = new List <string>();
            Exception ex           = null;
            var       process      = new ObservableProcess(TestCaseArguments(nameof(DelayedWriter)));
            var       subscription = process.SubscribeLines(c => seen.Add(c.Line), e => ex = e);

            process.WaitForCompletion(WaitTimeout);

            process.ExitCode.Should().Be(20);
            ex.Should().BeNull();

            seen.Should().NotBeEmpty().And.HaveCount(1, string.Join(Environment.NewLine, seen));
            seen[0].Should().Be(nameof(DelayedWriter));
        }
Example #9
0
        public void SingleLineNoEnterCharacters()
        {
            var seen    = new List <char[]>();
            var process = new ObservableProcess(TestCaseArguments(nameof(SingleLineNoEnter)));

            process.Subscribe(c => seen.Add(c.Characters));
            process.WaitForCompletion(WaitTimeout);

            seen.Should().NotBeEmpty().And.HaveCount(1, string.Join(Environment.NewLine, seen));
            var chars = nameof(SingleLineNoEnter).ToCharArray();

            seen[0].Should()
            .HaveCount(chars.Length)
            .And.ContainInOrder(chars);
        }
Example #10
0
        public void DelayedWriterStopNoWaitDispose()
        {
            var seen = new List <string>();
            var args = TestCaseArguments(nameof(DelayedWriter));

            args.WaitForExit = null;             //never wait for exit
            var process = new ObservableProcess(args);

            process.SubscribeLines(c => seen.Add(c.Line));
            process.Dispose();
            process.WaitForCompletion(WaitTimeout);

            //disposing the process itself will stop the underlying Process
            process.ExitCode.Should().NotHaveValue();
            seen.Should().BeEmpty(string.Join(Environment.NewLine, seen));
        }
Example #11
0
        public void ReadKeyFirst()
        {
            var seen    = new List <string>();
            var process = new ObservableProcess(TestCaseArguments(nameof(ReadKeyFirst)));

            process.ProcessStarted += (standardInput) =>
            {
                //this particular program does not output anything and expect user input immediatly
                //OnNext on the observable is only called on output so we need to write on the started event
                process.StandardInput.Write("y");
            };
            process.SubscribeLines(c => seen.Add(c.Line));
            process.WaitForCompletion(WaitTimeout);

            seen.Should().NotBeEmpty().And.HaveCount(1, string.Join(Environment.NewLine, seen));
            seen[0].Should().Be($"y{nameof(ReadKeyFirst)}");
        }
Example #12
0
        public static int Main()
        {
            var tessCase = TestBinary.TestCaseArguments("ControlC");
            var process  = new ObservableProcess(tessCase);

            process.SubscribeLines(c =>
            {
                //if (c.Line.EndsWith("4"))
                {
                    process.SendControlC();
                }
                Console.WriteLine(c.Line);
            }, e => Console.Error.WriteLine(e));

            process.WaitForCompletion(TimeSpan.FromSeconds(20));
            return(0);
        }
Example #13
0
        [SkipOnNonWindowsFact] public void ControlC()
        {
            var args = TestCaseArguments(nameof(ControlC));

            args.SendControlCFirst = true;

            var process = new ObservableProcess(args);
            var seen    = new List <string>();

            process.SubscribeLines(c =>
            {
                seen.Add(c.Line);
            });
            process.WaitForCompletion(TimeSpan.FromSeconds(1));

            seen.Should().NotBeEmpty().And.HaveCount(2, string.Join(Environment.NewLine, seen));
            seen[0].Should().Be("Written before control+c");
            seen[1].Should().Be("Written after control+c");
        }
Example #14
0
        public void ControlCNoWait()
        {
            var args = TestCaseArguments(nameof(ControlCNoWait));

            args.SendControlCFirst = true;

            var process = new ObservableProcess(args);

            var seen = new List <string>();

            process.SubscribeLines(c =>
            {
                seen.Add(c.Line);
            });
            process.WaitForCompletion(TimeSpan.FromSeconds(1));

            //process exits before its control c handler is invoked
            seen.Should().NotBeEmpty().And.HaveCount(1, string.Join(Environment.NewLine, seen));
            seen[0].Should().Be("Written before control+c");
        }
Example #15
0
        public void ReadKeyAfter()
        {
            var seen    = new List <string>();
            var process = new ObservableProcess(TestCaseArguments(nameof(ReadKeyAfter)));

            process.Subscribe(c =>
            {
                var chars = new string(c.Characters);
                seen.Add(chars);
                if (chars == "input:")
                {
                    process.StandardInput.Write("y");
                }
            });
            process.WaitForCompletion(WaitTimeout);

            seen.Should().NotBeEmpty().And.HaveCount(2, string.Join(Environment.NewLine, seen));
            seen[0].Should().Be($"input:");
            seen[1].Should().Be(nameof(ReadKeyAfter));
        }
        protected static void ExecuteBinary(string binary, string description, params string[] arguments)
        {
            Console.WriteLine($"Preparing to execute: {description} ...");
            var timeout = TimeSpan.FromSeconds(420);

            using (var p = new ObservableProcess(binary, arguments))
            {
                Console.WriteLine($"Executing: {binary} {string.Join(" ", arguments)}");
                p.Subscribe(c => Console.Write(c.Characters),
                            (e) =>
                {
                    Console.WriteLine($"Failed executing: {description} {e.Message} {e.StackTrace}");
                    throw e;
                },
                            () => Console.WriteLine($"Finished executing {description} exit code: {p.ExitCode}"));
                if (!p.WaitForCompletion(timeout))
                {
                    throw new Exception($"Timeout while executing {description} exceeded {timeout}");
                }
            }
        }
Example #17
0
        public void SlowOutput()
        {
            var       args                    = TestCaseArguments(nameof(SlowOutput));
            var       process                 = new ObservableProcess(args);
            var       consoleOut              = new List <LineOut>();
            Exception seenException           = null;
            bool?     readingBeforeCancelling = null;
            bool?     readingAfterCancelling  = null;

            process.SubscribeLines(c =>
            {
                consoleOut.Add(c);
                if (!c.Line.EndsWith("3"))
                {
                    return;
                }

                readingBeforeCancelling = process.IsActivelyReading;

                process.CancelAsyncReads();
                Task.Run(async() =>
                {
                    await Task.Delay(TimeSpan.FromSeconds(2));

                    readingAfterCancelling = process.IsActivelyReading;
                    process.StartAsyncReads();
                });
            }, e => seenException = e);

            process.WaitForCompletion(TimeSpan.FromSeconds(20));

            process.ExitCode.Should().HaveValue().And.Be(121);
            seenException.Should().BeNull();
            consoleOut.Should().NotBeEmpty()
            .And.Contain(l => l.Line.EndsWith("9"));

            readingBeforeCancelling.Should().HaveValue().And.BeTrue();
            readingAfterCancelling.Should().HaveValue().And.BeFalse();
        }