private async Task ActionListExecutor_SecondActionFail(bool waitForCompletion) { await TestHostHelper.CreateCollectionRulesHost(_outputHelper, rootOptions => { rootOptions.CreateCollectionRule(DefaultRuleName) .AddExecuteActionAppAction(waitForCompletion, new string[] { ActionTestsConstants.ZeroExitCode }) .AddExecuteActionAppAction(waitForCompletion, new string[] { ActionTestsConstants.NonzeroExitCode }) .SetStartupTrigger(); }, async host => { ActionListExecutor executor = host.Services.GetService <ActionListExecutor>(); using CancellationTokenSource cancellationTokenSource = new CancellationTokenSource(DefaultTimeout); CollectionRuleOptions ruleOptions = host.Services.GetRequiredService <IOptionsMonitor <CollectionRuleOptions> >().Get(DefaultRuleName); ILogger <CollectionRuleService> logger = host.Services.GetRequiredService <ILogger <CollectionRuleService> >(); ISystemClock clock = host.Services.GetRequiredService <ISystemClock>(); CollectionRuleContext context = new(DefaultRuleName, ruleOptions, null, logger, clock); int callbackCount = 0; Action startCallback = () => callbackCount++; CollectionRuleActionExecutionException actionExecutionException = await Assert.ThrowsAsync <CollectionRuleActionExecutionException>( () => executor.ExecuteActions(context, startCallback, cancellationTokenSource.Token)); Assert.Equal(1, actionExecutionException.ActionIndex); Assert.Equal(string.Format(Strings.ErrorMessage_NonzeroExitCode, "1"), actionExecutionException.Message); VerifyStartCallbackCount(waitForCompletion, callbackCount); }); }
public async Task InvalidTokenReferenceTest() { string a2input1 = "$(Actions. badly formed"; string a2input2 = "$(Actions.a15.MissingAction)"; string a2input3 = "$(Actions.a1.MissingResult)"; LogRecord record = new LogRecord(); PassThroughOptions settings = null; await TestHostHelper.CreateCollectionRulesHost(_outputHelper, rootOptions => { CollectionRuleOptions options = rootOptions.CreateCollectionRule(DefaultRuleName) .AddPassThroughAction("a1", "a1input1", "a1input2", "a1input3") .AddPassThroughAction("a2", a2input1, a2input2, a2input3) .SetStartupTrigger(); settings = (PassThroughOptions)options.Actions.Last().Settings; }, host => { using CancellationTokenSource cancellationTokenSource = new CancellationTokenSource(TimeoutMs); CollectionRuleOptions ruleOptions = host.Services.GetRequiredService <IOptionsMonitor <CollectionRuleOptions> >().Get(DefaultRuleName); ILogger <CollectionRuleService> logger = host.Services.GetRequiredService <ILogger <CollectionRuleService> >(); ISystemClock clock = host.Services.GetRequiredService <ISystemClock>(); CollectionRuleContext context = new(DefaultRuleName, ruleOptions, null, logger, clock); ActionOptionsDependencyAnalyzer analyzer = ActionOptionsDependencyAnalyzer.Create(context); analyzer.GetActionDependencies(1); analyzer.SubstituteOptionValues(new Dictionary <string, CollectionRuleActionResult>(), 1, settings); Assert.Equal(3, record.Events.Count); Assert.Equal(LoggingEventIds.InvalidActionReferenceToken.Id(), record.Events[0].EventId.Id); Assert.Equal(LoggingEventIds.InvalidActionReference.Id(), record.Events[1].EventId.Id); Assert.Equal(LoggingEventIds.InvalidActionResultReference.Id(), record.Events[2].EventId.Id); }, serviceCollection =>
public async Task ActionListExecutor_AllActionsSucceed() { await TestHostHelper.CreateCollectionRulesHost(_outputHelper, rootOptions => { rootOptions.CreateCollectionRule(DefaultRuleName) .AddExecuteActionAppAction(new string[] { ActionTestsConstants.ZeroExitCode }) .AddExecuteActionAppAction(new string[] { ActionTestsConstants.ZeroExitCode }) .SetStartupTrigger(); }, async host => { ActionListExecutor executor = host.Services.GetService <ActionListExecutor>(); using CancellationTokenSource cancellationTokenSource = new CancellationTokenSource(DefaultTimeout); CollectionRuleOptions ruleOptions = host.Services.GetRequiredService <IOptionsMonitor <CollectionRuleOptions> >().Get(DefaultRuleName); ILogger <CollectionRuleService> logger = host.Services.GetRequiredService <ILogger <CollectionRuleService> >(); ISystemClock clock = host.Services.GetRequiredService <ISystemClock>(); CollectionRuleContext context = new(DefaultRuleName, ruleOptions, null, logger, clock); int callbackCount = 0; Action startCallback = () => callbackCount++; await executor.ExecuteActions(context, startCallback, cancellationTokenSource.Token); VerifyStartCallbackCount(waitForCompletion: false, callbackCount); }); }
public async Task ActionListExecutor_Dependencies() { const string Output1 = nameof(Output1); const string Output2 = nameof(Output2); const string Output3 = nameof(Output3); string a2input1 = FormattableString.Invariant($"$(Actions.a1.{Output1}) with $(Actions.a1.{Output2})T"); string a2input2 = FormattableString.Invariant($"$(Actions.a1.{Output2})"); string a2input3 = FormattableString.Invariant($"Output $(Actions.a1.{Output3}) trail"); PassThroughOptions a2Settings = null; await TestHostHelper.CreateCollectionRulesHost(_outputHelper, rootOptions => { CollectionRuleOptions options = rootOptions.CreateCollectionRule(DefaultRuleName) .AddPassThroughAction("a1", "a1input1", "a1input2", "a1input3") .AddPassThroughAction("a2", a2input1, a2input2, a2input3) .SetStartupTrigger(); a2Settings = (PassThroughOptions)options.Actions.Last().Settings; }, async host => { ActionListExecutor executor = host.Services.GetService <ActionListExecutor>(); using CancellationTokenSource cancellationTokenSource = new CancellationTokenSource(DefaultTimeout); CollectionRuleOptions ruleOptions = host.Services.GetRequiredService <IOptionsMonitor <CollectionRuleOptions> >().Get(DefaultRuleName); ILogger <CollectionRuleService> logger = host.Services.GetRequiredService <ILogger <CollectionRuleService> >(); ISystemClock clock = host.Services.GetRequiredService <ISystemClock>(); CollectionRuleContext context = new(DefaultRuleName, ruleOptions, null, logger, clock); int callbackCount = 0; Action startCallback = () => callbackCount++; IDictionary <string, CollectionRuleActionResult> results = await executor.ExecuteActions(context, startCallback, cancellationTokenSource.Token); //Verify that the original settings were not altered during execution. Assert.Equal(a2input1, a2Settings.Input1); Assert.Equal(a2input2, a2Settings.Input2); Assert.Equal(a2input3, a2Settings.Input3); Assert.Equal(1, callbackCount); Assert.Equal(2, results.Count); Assert.True(results.TryGetValue("a2", out CollectionRuleActionResult a2result)); Assert.Equal(3, a2result.OutputValues.Count); Assert.True(a2result.OutputValues.TryGetValue(Output1, out string a2output1)); Assert.Equal("a1input1 with a1input2T", a2output1); Assert.True(a2result.OutputValues.TryGetValue(Output2, out string a2output2)); Assert.Equal("a1input2", a2output2); Assert.True(a2result.OutputValues.TryGetValue(Output3, out string a2output3)); Assert.Equal("Output a1input3 trail", a2output3); }, serviceCollection => { serviceCollection.RegisterCollectionRuleAction <PassThroughActionFactory, PassThroughOptions>(nameof(PassThroughAction)); }); }
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); }); }); }
public async Task DuplicateActionNamesTest() { await TestHostHelper.CreateCollectionRulesHost(_outputHelper, rootOptions => { CollectionRuleOptions options = rootOptions.CreateCollectionRule(DefaultRuleName) .AddPassThroughAction("a1", "a1input1", "a1input2", "a1input3") .AddPassThroughAction("a2", "a1input1", "a1input2", "a1input3") .AddPassThroughAction("a1", "a1input1", "a1input2", "a1input3") .SetStartupTrigger(); }, host => { //Expecting duplicate action name Assert.Throws <OptionsValidationException>(() => host.Services.GetRequiredService <IOptionsMonitor <CollectionRuleOptions> >().Get(DefaultRuleName)); }, serviceCollection => { serviceCollection.RegisterCollectionRuleAction <PassThroughActionFactory, PassThroughOptions>(nameof(PassThroughAction)); }); }
public async Task CollectGCDumpAction_Success(TargetFrameworkMoniker tfm) { using TemporaryDirectory tempDirectory = new(_outputHelper); await TestHostHelper.CreateCollectionRulesHost(_outputHelper, rootOptions => { rootOptions.AddFileSystemEgress(ActionTestsConstants.ExpectedEgressProvider, tempDirectory.FullName); rootOptions.CreateCollectionRule(DefaultRuleName) .AddCollectGCDumpAction(ActionTestsConstants.ExpectedEgressProvider) .SetStartupTrigger(); }, async host => { CollectGCDumpOptions options = ActionTestsHelper.GetActionOptions <CollectGCDumpOptions>(host, DefaultRuleName); ICollectionRuleActionFactoryProxy factory; Assert.True(host.Services.GetService <ICollectionRuleActionOperations>().TryCreateFactory(KnownCollectionRuleActions.CollectGCDump, 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.GCDumpTimeout); string egressPath = ActionTestsHelper.ValidateEgressPath(result); using FileStream gcdumpStream = new(egressPath, FileMode.Open, FileAccess.Read); Assert.NotNull(gcdumpStream); await ValidateGCDump(gcdumpStream); await runner.SendCommandAsync(TestAppScenarios.AsyncWait.Commands.Continue); }); }); }
public async Task CollectTraceAction_ProfileSuccess(TargetFrameworkMoniker tfm, TraceProfile traceProfile) { using TemporaryDirectory tempDirectory = new(_outputHelper); await TestHostHelper.CreateCollectionRulesHost(_outputHelper, rootOptions => { rootOptions.AddFileSystemEgress(ActionTestsConstants.ExpectedEgressProvider, tempDirectory.FullName); rootOptions.CreateCollectionRule(DefaultRuleName) .AddCollectTraceAction(traceProfile, ActionTestsConstants.ExpectedEgressProvider, options => { options.Duration = TimeSpan.FromSeconds(2); }) .SetStartupTrigger(); }, async host => { await PerformTrace(host, tfm); }); }
public async Task CollectTraceAction_ProvidersSuccess(TargetFrameworkMoniker tfm) { List <EventPipeProvider> ExpectedProviders = new() { new() { Name = "Microsoft-Extensions-Logging" } }; using TemporaryDirectory tempDirectory = new(_outputHelper); await TestHostHelper.CreateCollectionRulesHost(_outputHelper, rootOptions => { rootOptions.AddFileSystemEgress(ActionTestsConstants.ExpectedEgressProvider, tempDirectory.FullName); rootOptions.CreateCollectionRule(DefaultRuleName) .AddCollectTraceAction(ExpectedProviders, ActionTestsConstants.ExpectedEgressProvider, options => { options.Duration = TimeSpan.FromSeconds(2); }) .SetStartupTrigger(); }, async host => { await PerformTrace(host, tfm); }); }
private async Task ValidateLogsActionAsync( LogsConfiguration configuration, Func <ChannelReader <LogEntry>, Task> callback, LogFormat logFormat, TargetFrameworkMoniker tfm) { using TemporaryDirectory tempDirectory = new(_outputHelper); await TestHostHelper.CreateCollectionRulesHost(_outputHelper, rootOptions => { rootOptions.AddFileSystemEgress(ActionTestsConstants.ExpectedEgressProvider, tempDirectory.FullName); rootOptions.CreateCollectionRule(DefaultRuleName) .AddCollectLogsAction(ActionTestsConstants.ExpectedEgressProvider, options => { options.Duration = CommonTestTimeouts.LogsDuration; options.FilterSpecs = configuration.FilterSpecs; options.DefaultLevel = configuration.LogLevel; options.Format = logFormat; options.UseAppFilters = configuration.UseAppFilters; }) .SetStartupTrigger(); }, async host => { CollectLogsOptions options = ActionTestsHelper.GetActionOptions <CollectLogsOptions>(host, DefaultRuleName); // This is reassigned here due to a quirk in which a null value in the dictionary has its key removed, thus causing LogsDefaultLevelFallbackActionTest to fail. By reassigning here, any keys with null values are maintained. options.FilterSpecs = configuration.FilterSpecs; ICollectionRuleActionFactoryProxy factory; Assert.True(host.Services.GetService <ICollectionRuleActionOperations>().TryCreateFactory(KnownCollectionRuleActions.CollectLogs, out factory)); using CancellationTokenSource endpointTokenSource = new CancellationTokenSource(CommonTestTimeouts.LogsTimeout); EndpointInfoSourceCallback endpointInfoCallback = new(_outputHelper); await using ServerSourceHolder sourceHolder = await _endpointUtilities.StartServerAsync(endpointInfoCallback); AppRunner runner = _endpointUtilities.CreateAppRunner(sourceHolder.TransportName, tfm); runner.ScenarioName = TestAppScenarios.Logger.Name; Task <IEndpointInfo> newEndpointInfoTask = endpointInfoCallback.WaitAddedEndpointInfoAsync(runner, CommonTestTimeouts.StartProcess); await runner.ExecuteAsync(async() => { IEndpointInfo endpointInfo = await newEndpointInfoTask; ICollectionRuleAction action = factory.Create(endpointInfo, options); using CancellationTokenSource cancellationTokenSource = new CancellationTokenSource(CommonTestTimeouts.LogsTimeout); CollectionRuleActionResult result; try { await action.StartAsync(cancellationTokenSource.Token); await runner.SendCommandAsync(TestAppScenarios.Logger.Commands.StartLogging); result = await action.WaitForCompletionAsync(cancellationTokenSource.Token); } finally { await Tools.Monitor.DisposableHelper.DisposeAsync(action); } string egressPath = ActionTestsHelper.ValidateEgressPath(result); using FileStream logsStream = new(egressPath, FileMode.Open, FileAccess.Read); Assert.NotNull(logsStream); await LogsTestUtilities.ValidateLogsEquality(logsStream, callback, logFormat, _outputHelper); }); }); }
private async Task ExecuteScenario( TargetFrameworkMoniker tfm, string scenarioName, string collectionRuleName, Action <Tools.Monitor.RootOptions> setup, Func <AppRunner, CollectionRulePipeline, PipelineCallbacks, Task> pipelineCallback, Action <IServiceCollection> servicesCallback = null) { EndpointInfoSourceCallback endpointInfoCallback = new(_outputHelper); EndpointUtilities endpointUtilities = new(_outputHelper); await using ServerSourceHolder sourceHolder = await endpointUtilities.StartServerAsync(endpointInfoCallback); AppRunner runner = new(_outputHelper, Assembly.GetExecutingAssembly(), tfm : tfm); runner.ConnectionMode = DiagnosticPortConnectionMode.Connect; runner.DiagnosticPortPath = sourceHolder.TransportName; runner.ScenarioName = scenarioName; Task <IEndpointInfo> endpointInfoTask = endpointInfoCallback.WaitAddedEndpointInfoAsync(runner, CommonTestTimeouts.StartProcess); await runner.ExecuteAsync(async() => { IEndpointInfo endpointInfo = await endpointInfoTask; await TestHostHelper.CreateCollectionRulesHost( _outputHelper, setup, async host => { ActionListExecutor actionListExecutor = host.Services.GetRequiredService <ActionListExecutor>(); ICollectionRuleTriggerOperations triggerOperations = host.Services.GetRequiredService <ICollectionRuleTriggerOperations>(); IOptionsMonitor <CollectionRuleOptions> optionsMonitor = host.Services.GetRequiredService <IOptionsMonitor <CollectionRuleOptions> >(); ILogger <CollectionRuleService> logger = host.Services.GetRequiredService <ILogger <CollectionRuleService> >(); ISystemClock clock = host.Services.GetRequiredService <ISystemClock>(); PipelineCallbacks callbacks = new(); CollectionRuleContext context = new( collectionRuleName, optionsMonitor.Get(collectionRuleName), endpointInfo, logger, clock, callbacks.NotifyActionsThrottled); await using CollectionRulePipeline pipeline = new( actionListExecutor, triggerOperations, context, callbacks.NotifyPipelineStarted); await pipelineCallback(runner, pipeline, callbacks); Assert.Equal(1, callbacks.StartedCount); }, servicesCallback); }); }