예제 #1
0
        public Task DumpTest(DiagnosticPortConnectionMode mode, DumpType type)
        {
#if !NET6_0_OR_GREATER
            // Capturing non-full dumps via diagnostic command works inconsistently
            // on Alpine for .NET 5 and lower (the dump command will return successfully, but)
            // the dump file will not exist). Only test other dump types on .NET 6+
            if (DistroInformation.IsAlpineLinux && type != DumpType.Full)
            {
                _outputHelper.WriteLine("Skipped on Alpine for .NET 5 and lower.");
                return(Task.CompletedTask);
            }
#endif

            return(ScenarioRunner.SingleTarget(
                       _outputHelper,
                       _httpClientFactory,
                       mode,
                       TestAppScenarios.AsyncWait.Name,
                       appValidate: async(runner, client) =>
            {
                int processId = await runner.ProcessIdTask;

                using ResponseStreamHolder holder = await client.CaptureDumpAsync(processId, type);
                Assert.NotNull(holder);

                // The dump operation may still be in progress but the process should still be discoverable.
                // If this check fails, then the dump operation is causing dotnet-monitor to not be able
                // to observe the process any more.
                ProcessInfo processInfo = await client.GetProcessAsync(processId);
                Assert.NotNull(processInfo);

                await DumpTestUtilities.ValidateDump(runner.Environment.ContainsKey(DumpTestUtilities.EnableElfDumpOnMacOS), holder.Stream);

                await runner.SendCommandAsync(TestAppScenarios.AsyncWait.Commands.Continue);
            },
                       configureApp: runner =>
            {
                // MachO not supported on .NET 5, only ELF: https://github.com/dotnet/runtime/blob/main/docs/design/coreclr/botr/xplat-minidump-generation.md#os-x
                if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX) && DotNetHost.RuntimeVersion.Major == 5)
                {
                    runner.Environment.Add(DumpTestUtilities.EnableElfDumpOnMacOS, "1");
                }
            },
                       configureTool: runner =>
            {
                string dumpTempFolder = Path.Combine(runner.TempPath, "Dumps");

                // The dump temp folder should not exist in order to test that capturing dumps into the folder
                // will work since dotnet-monitor should ensure the folder is created before issuing the dump command.
                Assert.False(Directory.Exists(dumpTempFolder), "The dump temp folder should not exist.");

                runner.ConfigurationFromEnvironment.SetDumpTempFolder(dumpTempFolder);
            }));
        }
예제 #2
0
        public async Task CollectDumpAction_Success(TargetFrameworkMoniker tfm, DumpType?dumpType)
        {
            // MacOS dumps inconsistently segfault the runtime on .NET 5: https://github.com/dotnet/dotnet-monitor/issues/174
            if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX) && tfm == TargetFrameworkMoniker.Net50)
            {
                return;
            }

            using TemporaryDirectory tempDirectory = new(_outputHelper);

            await TestHostHelper.CreateCollectionRulesHost(_outputHelper, rootOptions =>
            {
                rootOptions.AddFileSystemEgress(ActionTestsConstants.ExpectedEgressProvider, tempDirectory.FullName);

                rootOptions.CreateCollectionRule(DefaultRuleName)
                .AddCollectDumpAction(ActionTestsConstants.ExpectedEgressProvider, dumpType)
                .SetStartupTrigger();
            }, async host =>
            {
                CollectDumpOptions options = ActionTestsHelper.GetActionOptions <CollectDumpOptions>(host, DefaultRuleName);

                ICollectionRuleActionFactoryProxy factory;
                Assert.True(host.Services.GetService <ICollectionRuleActionOperations>().TryCreateFactory(KnownCollectionRuleActions.CollectDump, out factory));

                EndpointInfoSourceCallback callback         = new(_outputHelper);
                await using ServerSourceHolder sourceHolder = await _endpointUtilities.StartServerAsync(callback);

                AppRunner runner = _endpointUtilities.CreateAppRunner(sourceHolder.TransportName, tfm);

                Task <IEndpointInfo> newEndpointInfoTask = callback.WaitAddedEndpointInfoAsync(runner, CommonTestTimeouts.StartProcess);

                await runner.ExecuteAsync(async() =>
                {
                    IEndpointInfo endpointInfo = await newEndpointInfoTask;

                    ICollectionRuleAction action = factory.Create(endpointInfo, options);

                    CollectionRuleActionResult result = await ActionTestsHelper.ExecuteAndDisposeAsync(action, CommonTestTimeouts.DumpTimeout);

                    string egressPath = ActionTestsHelper.ValidateEgressPath(result);

                    using FileStream dumpStream = new(egressPath, FileMode.Open, FileAccess.Read);
                    Assert.NotNull(dumpStream);

                    await DumpTestUtilities.ValidateDump(runner.Environment.ContainsKey(DumpTestUtilities.EnableElfDumpOnMacOS), dumpStream);

                    await runner.SendCommandAsync(TestAppScenarios.AsyncWait.Commands.Continue);
                });
            });
        }