Example #1
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();
        }
        /// <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 sample app. Must be a version supported in the TargetFrameworks of the sample app</param>
        /// <param name="environmentVariables">The environment variables to start the sample app with. The DOTNET_STARTUP_HOOKS environment variable will be added.</param>
        /// <returns></returns>
        public Uri Start(string targetFramework, IDictionary <string, string> environmentVariables = null)
        {
            var projectDirectory = Path.Combine(SolutionPaths.Root, "sample", ElasticApmStartuphookSampleProjectName);

            Publish(projectDirectory, targetFramework);

            var startupHookAssembly = UnzipStartupHook();

            environmentVariables ??= new Dictionary <string, string>();
            environmentVariables["DOTNET_STARTUP_HOOKS"] = startupHookAssembly;

            var arguments = new StartArguments("dotnet", $"{ElasticApmStartuphookSampleProjectName}.dll")
            {
                WorkingDirectory  = Path.Combine(projectDirectory, _publishDirectory, targetFramework),
                SendControlCFirst = true,
                Environment       = environmentVariables
            };

            var startHandle         = new ManualResetEvent(false);
            ExceptionDispatchInfo e = null;
            Uri uri = null;

            var capturedLines = new List <string>();
            var endpointRegex = new Regex(@"\s*Now listening on:\s*(?<endpoint>http\:[^\s]*)");

            _process = new ObservableProcess(arguments);
            _process.SubscribeLines(
                line =>
            {
                capturedLines.Add(line.Line);
                var match = endpointRegex.Match(line.Line);
                if (match.Success)
                {
                    try
                    {
                        var endpoint = match.Groups["endpoint"].Value.Trim();
                        uri          = new Uri(endpoint);
                    }
                    catch (Exception exception)
                    {
                        e = ExceptionDispatchInfo.Capture(exception);
                    }

                    startHandle.Set();
                }
            },
                exception => e = ExceptionDispatchInfo.Capture(exception));

            var timeout   = TimeSpan.FromMinutes(2);
            var signalled = startHandle.WaitOne(timeout);

            if (!signalled)
            {
                throw new Exception($"Could not start sample application within timeout {timeout}: "
                                    + string.Join(Environment.NewLine, capturedLines));
            }

            _process.CancelAsyncReads();
            e?.Throw();

            return(uri);
        }