Пример #1
0
        private async Task BasicProcessInfoTestCore(bool useAsync)
        {
            using TestRunner runner = new TestRunner(CommonHelper.GetTraceePathWithArgs(targetFramework: "net5.0"), output);
            runner.Start();

            try
            {
                DiagnosticsClientApiShim clientShim = new DiagnosticsClientApiShim(new DiagnosticsClient(runner.Pid), useAsync);

                ProcessInfo processInfo = await clientShim.GetProcessInfo();

                Assert.NotNull(processInfo);
                Assert.Equal(runner.Pid, (int)processInfo.ProcessId);
                Assert.NotNull(processInfo.CommandLine);
                Assert.NotNull(processInfo.OperatingSystem);
                Assert.NotNull(processInfo.ProcessArchitecture);
                //Assert.Equal("Tracee", processInfo.ManagedEntrypointAssemblyName);
                //Version clrVersion = ParseVersionRemoveLabel(processInfo.ClrProductVersionString);
                //Assert.True(clrVersion >= new Version(6, 0, 0));
            }
            finally
            {
                runner.PrintStatus();
            }
        }
Пример #2
0
        /// <summary>
        /// Get process information with entrypoint information with exponential backoff on retries.
        /// </summary>
        private async Task <ProcessInfo> GetProcessInfoWithEntrypointAsync(DiagnosticsClientApiShim shim)
        {
            int       retryMilliseconds = 5;
            int       currentAttempt    = 1;
            const int maxAttempts       = 10;

            _output.WriteLine("Getting process info with entrypoint:");
            while (currentAttempt <= maxAttempts)
            {
                _output.WriteLine("- Attempt {0} of {1}.", currentAttempt, maxAttempts);

                ProcessInfo processInfo = await shim.GetProcessInfo();

                Assert.NotNull(processInfo);

                if (!string.IsNullOrEmpty(processInfo.ManagedEntrypointAssemblyName))
                {
                    _output.WriteLine("Got process info with entrypoint.");
                    return(processInfo);
                }

                currentAttempt++;

                if (currentAttempt != maxAttempts)
                {
                    _output.WriteLine("  Waiting {0} ms.", retryMilliseconds);

                    await Task.Delay(retryMilliseconds);

                    retryMilliseconds = Math.Min(2 * retryMilliseconds, 500);
                }
            }

            throw new InvalidOperationException("Unable to get process info with entrypoint.");
        }
Пример #3
0
        /// <summary>
        /// Test for the method overload: public EventPipeSession StartEventPipeSession(EventPipeProvider provider, bool requestRundown=true, int circularBufferMB=256)
        /// </summary>
        private async Task StartEventPipeSessionWithSingleProviderTestCore(bool useAsync)
        {
            using TestRunner runner = new TestRunner(CommonHelper.GetTraceePathWithArgs(), output);
            runner.Start(timeoutInMSPipeCreation: 15_000, testProcessTimeout: 60_000);
            DiagnosticsClientApiShim clientShim = new DiagnosticsClientApiShim(new DiagnosticsClient(runner.Pid), useAsync);

            using (var session = await clientShim.StartEventPipeSession(new EventPipeProvider("Microsoft-Windows-DotNETRuntime", EventLevel.Informational)))
            {
                Assert.True(session.EventStream != null);
            }
            runner.Stop();
        }
Пример #4
0
        /// <summary>
        /// Tries to start an EventPipe session on a non-existent process
        /// </summary>
        private async Task EventPipeSessionUnavailableTestCore(bool useAsync)
        {
            List <int> pids         = new List <int>(DiagnosticsClient.GetPublishedProcesses());
            int        arbitraryPid = 1;

            DiagnosticsClientApiShim clientShim = new DiagnosticsClientApiShim(new DiagnosticsClient(arbitraryPid), useAsync);

            await Assert.ThrowsAsync <ServerNotAvailableException>(() => clientShim.StartEventPipeSession(new List <EventPipeProvider>()
            {
                new EventPipeProvider("Microsoft-Windows-DotNETRuntime", EventLevel.Informational)
            }));
        }
Пример #5
0
        private async Task BasicProcessInfoTestCore(bool useAsync, bool suspend)
        {
            using TestRunner runner = new TestRunner(CommonHelper.GetTraceePathWithArgs(targetFramework: "net5.0"), _output);
            if (suspend)
            {
                runner.SuspendDefaultDiagnosticPort();
            }
            runner.Start();

            try
            {
                DiagnosticsClientApiShim clientShim = new DiagnosticsClientApiShim(new DiagnosticsClient(runner.Pid), useAsync);

                // While suspended, the runtime will not provide entrypoint information.
                ProcessInfo processInfoBeforeResume = null;
                if (suspend)
                {
                    processInfoBeforeResume = await clientShim.GetProcessInfo();

                    ValidateProcessInfo(runner.Pid, processInfoBeforeResume);
                    Assert.True(string.IsNullOrEmpty(processInfoBeforeResume.ManagedEntrypointAssemblyName));

                    await clientShim.ResumeRuntime();
                }

                // The entrypoint information is available some short time after the runtime
                // begins to execute. Retry getting process information until entrypoint is available.
                ProcessInfo processInfo = await GetProcessInfoWithEntrypointAsync(clientShim);

                ValidateProcessInfo(runner.Pid, processInfo);
                Assert.Equal("Tracee", processInfo.ManagedEntrypointAssemblyName);

                // Validate values before resume (except for entrypoint) are the same after resume.
                if (suspend)
                {
                    Assert.Equal(processInfoBeforeResume.ProcessId, processInfo.ProcessId);
                    Assert.Equal(processInfoBeforeResume.RuntimeInstanceCookie, processInfo.RuntimeInstanceCookie);
                    Assert.Equal(processInfoBeforeResume.CommandLine, processInfo.CommandLine);
                    Assert.Equal(processInfoBeforeResume.OperatingSystem, processInfo.OperatingSystem);
                    Assert.Equal(processInfoBeforeResume.ProcessArchitecture, processInfo.ProcessArchitecture);
                    Assert.Equal(processInfoBeforeResume.ClrProductVersionString, processInfo.ClrProductVersionString);
                }
            }
            finally
            {
                runner.PrintStatus();
            }
        }
        /// <summary>
        /// A simple test that collects process environment.
        /// </summary>
        private async Task BasicEnvTestCore(bool useAsync)
        {
            // as the attribute says, this test requires 5.0-rc1 or newer.  This has been tested locally on
            // an rc1 build and passes.  It is equivalent to the dotnet/runtime version of this test.
            using TestRunner runner = new TestRunner(CommonHelper.GetTraceePathWithArgs(targetFramework: "net5.0"), output);
            string testKey = "FOO";
            string testVal = "BAR";

            runner.AddEnvVar(testKey, testVal);
            runner.Start(timeoutInMSPipeCreation: 3000);
            var clientShim = new DiagnosticsClientApiShim(new DiagnosticsClient(runner.Pid), useAsync);
            Dictionary <string, string> env = await clientShim.GetProcessEnvironment();

            Assert.True(env.ContainsKey(testKey) && env[testKey].Equals(testVal));

            runner.Stop();
        }
Пример #7
0
        /// <summary>
        /// Checks if we can create an EventPipeSession and can get some expected events out of it.
        /// </summary>
        private async Task EventPipeSessionStreamTestCore(bool useAsync)
        {
            TestRunner runner = new TestRunner(CommonHelper.GetTraceePathWithArgs(), output);

            runner.Start(timeoutInMSPipeCreation: 15_000, testProcessTimeout: 60_000);
            DiagnosticsClientApiShim clientShim = new DiagnosticsClientApiShim(new DiagnosticsClient(runner.Pid), useAsync);

            runner.PrintStatus();
            output.WriteLine($"[{DateTime.Now.ToString()}] Trying to start an EventPipe session on process {runner.Pid}");
            using (var session = await clientShim.StartEventPipeSession(new List <EventPipeProvider>()
            {
                new EventPipeProvider("System.Runtime", EventLevel.Informational, 0, new Dictionary <string, string>()
                {
                    { "EventCounterIntervalSec", "1" }
                })
            }))
            {
                var evntCnt = 0;

                Task streamTask = Task.Run(() => {
                    var source          = new EventPipeEventSource(session.EventStream);
                    source.Dynamic.All += (TraceEvent obj) => {
                        output.WriteLine("Got an event");
                        evntCnt += 1;
                    };
                    try
                    {
                        source.Process();
                    }
                    catch (Exception e)
                    {
                        // This exception can happen if the target process exits while EventPipeEventSource is in the middle of reading from the pipe.
                        output.WriteLine("Error encountered while processing events");
                        output.WriteLine(e.ToString());
                    }
                    finally
                    {
                        runner.Stop();
                    }
                });
                output.WriteLine("Waiting for stream Task");
                streamTask.Wait(10000);
                output.WriteLine("Done waiting for stream Task");
                Assert.True(evntCnt > 0);
            }
        }
Пример #8
0
        private async Task ResumeRuntime(IpcEndpointInfo info, bool useAsync)
        {
            var clientShim = new DiagnosticsClientApiShim(new DiagnosticsClient(info.Endpoint), useAsync);

            _outputHelper.WriteLine($"{info.RuntimeInstanceCookie}: Resuming runtime instance.");
            try
            {
                await clientShim.ResumeRuntime(DefaultPositiveVerificationTimeout);

                _outputHelper.WriteLine($"{info.RuntimeInstanceCookie}: Resumed successfully.");
            }
            catch (ServerErrorException ex)
            {
                // Runtime likely does not understand the ResumeRuntime command.
                _outputHelper.WriteLine($"{info.RuntimeInstanceCookie}: {ex.Message}");
            }
        }
Пример #9
0
        /// <summary>
        /// Verifies that a client can handle multiple operations simultaneously.
        /// </summary>
        private async Task VerifySingleSession(IpcEndpointInfo info, bool useAsync)
        {
            await VerifyWaitForConnection(info, useAsync);

            var clientShim = new DiagnosticsClientApiShim(new DiagnosticsClient(info.Endpoint), useAsync);

            _outputHelper.WriteLine($"{info.RuntimeInstanceCookie}: Creating session #1.");
            var providers = new List <EventPipeProvider>();

            providers.Add(new EventPipeProvider(
                              "System.Runtime",
                              EventLevel.Informational,
                              0,
                              new Dictionary <string, string>()
            {
                { "EventCounterIntervalSec", "1" }
            }));
            using var session = await clientShim.StartEventPipeSession(providers);

            _outputHelper.WriteLine($"{info.RuntimeInstanceCookie}: Verifying session produces events.");
            await VerifyEventStreamProvidesEventsAsync(info, session, 1);

            _outputHelper.WriteLine($"{info.RuntimeInstanceCookie}: Session verification complete.");
        }
Пример #10
0
 public static Task <EventPipeSession> StartEventPipeSession(this DiagnosticsClientApiShim shim, EventPipeProvider provider)
 {
     return(shim.StartEventPipeSession(provider, DefaultPositiveVerificationTimeout));
 }
Пример #11
0
 public static Task ResumeRuntime(this DiagnosticsClientApiShim shim)
 {
     return(shim.ResumeRuntime(DefaultPositiveVerificationTimeout));
 }
Пример #12
0
 public static Task <ProcessInfo> GetProcessInfo(this DiagnosticsClientApiShim shim)
 {
     return(shim.GetProcessInfo(DefaultPositiveVerificationTimeout));
 }
Пример #13
0
 public static Task <Dictionary <string, string> > GetProcessEnvironment(this DiagnosticsClientApiShim shim)
 {
     return(shim.GetProcessEnvironment(DefaultPositiveVerificationTimeout));
 }