diff --git a/build.cake b/build.cake index 9bfbbd3c4a8..786cd32a699 100644 --- a/build.cake +++ b/build.cake @@ -286,6 +286,22 @@ string ToolsExePath(string exeFileName) { return exePath; } +string PatchStrykerConfig(string path, Action patch) +{ + var json = System.IO.File.ReadAllText(path); + var config = Newtonsoft.Json.Linq.JObject.Parse(json); + + patch(config.Value("stryker-config")); + + // Create a new file to avoid polluting the Git tree + var tempPath = System.IO.Path.GetTempFileName(); + tempPath = System.IO.Path.ChangeExtension(tempPath, "json"); + + System.IO.File.WriteAllText(tempPath, config.ToString()); + + return tempPath; +} + void RunMutationTests(FilePath target, FilePath testProject) { var mutationScore = XmlPeek(target, "/Project/PropertyGroup/MutationScore/text()", new XmlPeekSettings { SuppressWarning = true }); @@ -294,6 +310,12 @@ void RunMutationTests(FilePath target, FilePath testProject) var isGitHubActions = Environment.GetEnvironmentVariable("GITHUB_ACTIONS") == "true"; var dashboardUrl = string.Empty; var moduleName = target.GetFilenameWithoutExtension().ToString(); + var strykerConfigPath = strykerConfig.FullPath; + + if (moduleName == "Polly.Testing") + { + strykerConfigPath = PatchStrykerConfig(strykerConfigPath, (config) => config.Remove("ignore-mutations")); + } if (isGitHubActions && !string.IsNullOrWhiteSpace(Environment.GetEnvironmentVariable("STRYKER_DASHBOARD_API_KEY"))) @@ -303,20 +325,19 @@ void RunMutationTests(FilePath target, FilePath testProject) dashboardUrl = $"https://dashboard.stryker-mutator.io/reports/{projectName}/{version}#mutant/{moduleName}"; - var config = Newtonsoft.Json.Linq.JObject.Parse(System.IO.File.ReadAllText(strykerConfig.FullPath)); - - var reporters = config["stryker-config"].Value("reporters"); - reporters.Add("dashboard"); - - config["stryker-config"]["reporters"] = reporters; - config["stryker-config"]["project-info"] = new Newtonsoft.Json.Linq.JObject() + strykerConfigPath = PatchStrykerConfig(strykerConfigPath, (config) => { - ["module"] = moduleName, - ["name"] = projectName, - ["version"] = version - }; + var reporters = config.Value("reporters"); + reporters.Add("dashboard"); - System.IO.File.WriteAllText(strykerConfig.FullPath, config.ToString()); + config["reporters"] = reporters; + config["project-info"] = new Newtonsoft.Json.Linq.JObject() + { + ["module"] = moduleName, + ["name"] = projectName, + ["version"] = version + }; + }); Information("Configured Stryker dashboard."); Information($"Mutation report will be available at {dashboardUrl}"); @@ -324,7 +345,7 @@ void RunMutationTests(FilePath target, FilePath testProject) Information($"Running mutation tests for '{targetFileName}'. Test Project: '{testProject}'"); - var args = $"stryker --project {targetFileName} --test-project {testProject.FullPath} --break-at {score} --config-file {strykerConfig} --output {strykerOutput}/{targetFileName}"; + var args = $"stryker --project {targetFileName} --test-project {testProject.FullPath} --break-at {score} --config-file {strykerConfigPath} --output {strykerOutput}/{targetFileName}"; var result = StartProcess("dotnet", args); if (result != 0) diff --git a/src/Polly.Testing/ResiliencePipelineExtensions.cs b/src/Polly.Testing/ResiliencePipelineExtensions.cs index feea4ad59d3..686776fc8ad 100644 --- a/src/Polly.Testing/ResiliencePipelineExtensions.cs +++ b/src/Polly.Testing/ResiliencePipelineExtensions.cs @@ -40,7 +40,11 @@ private static ResiliencePipelineDescriptor GetPipelineDescriptorCore(Pipelin var components = new List(); component.ExpandComponents(components); - var descriptors = components.OfType().Select(s => new ResilienceStrategyDescriptor(s.Options, GetStrategyInstance(s))).ToList().AsReadOnly(); + var descriptors = components + .OfType() + .Select(s => new ResilienceStrategyDescriptor(s.Options, GetStrategyInstance(s))) + .ToList() + .AsReadOnly(); return new ResiliencePipelineDescriptor( descriptors, @@ -73,7 +77,6 @@ private static void ExpandComponents(this PipelineComponent component, List pipelineGeneric = null!; + + // Act and Assert + Should.Throw(() => pipeline.GetPipelineDescriptor()).ParamName.ShouldBe("pipeline"); + Should.Throw(() => pipelineGeneric.GetPipelineDescriptor()).ParamName.ShouldBe("pipeline"); + } + [Fact] public void GetPipelineDescriptor_Generic_Ok() { - // arrange + // Arrange var strategy = new ResiliencePipelineBuilder() .AddFallback(new() { @@ -29,10 +41,11 @@ public void GetPipelineDescriptor_Generic_Ok() .ConfigureTelemetry(NullLoggerFactory.Instance) .Build(); - // act + // Act var descriptor = strategy.GetPipelineDescriptor(); - // assert + // Assert + descriptor.ShouldNotBeNull(); descriptor.IsReloadable.ShouldBeFalse(); descriptor.Strategies.Count.ShouldBe(7); descriptor.FirstStrategy.Options.ShouldBeOfType>(); @@ -58,7 +71,7 @@ public void GetPipelineDescriptor_Generic_Ok() [Fact] public void GetPipelineDescriptor_NonGeneric_Ok() { - // arrange + // Arrange var strategy = new ResiliencePipelineBuilder() .AddRetry(new()) .AddCircuitBreaker(new()) @@ -68,10 +81,11 @@ public void GetPipelineDescriptor_NonGeneric_Ok() .ConfigureTelemetry(NullLoggerFactory.Instance) .Build(); - // act + // Act var descriptor = strategy.GetPipelineDescriptor(); - // assert + // Assert + descriptor.ShouldNotBeNull(); descriptor.IsReloadable.ShouldBeFalse(); descriptor.Strategies.Count.ShouldBe(5); descriptor.Strategies[0].Options.ShouldBeOfType(); @@ -92,15 +106,16 @@ public void GetPipelineDescriptor_NonGeneric_Ok() [Fact] public void GetPipelineDescriptor_SingleStrategy_Ok() { - // arrange + // Arrange var strategy = new ResiliencePipelineBuilder() .AddTimeout(TimeSpan.FromSeconds(1)) .Build(); - // act + // Act var descriptor = strategy.GetPipelineDescriptor(); - // assert + // Assert + descriptor.ShouldNotBeNull(); descriptor.IsReloadable.ShouldBeFalse(); descriptor.Strategies.Count.ShouldBe(1); descriptor.Strategies[0].Options.ShouldBeOfType(); @@ -109,10 +124,11 @@ public void GetPipelineDescriptor_SingleStrategy_Ok() [Fact] public async Task GetPipelineDescriptor_Reloadable_Ok() { - // arrange + // Arrange using var source = new CancellationTokenSource(); await using var registry = new ResiliencePipelineRegistry(); - var strategy = registry.GetOrAddPipeline("dummy", (builder, context) => + + var pipeline = registry.GetOrAddPipeline("first", (builder, context) => { context.OnPipelineDisposed(() => { }); context.AddReloadToken(source.Token); @@ -122,10 +138,11 @@ public async Task GetPipelineDescriptor_Reloadable_Ok() .AddStrategy(_ => new CustomStrategy(), new TestOptions()); }); - // act - var descriptor = strategy.GetPipelineDescriptor(); + // Act + var descriptor = pipeline.GetPipelineDescriptor(); - // assert + // Assert + descriptor.ShouldNotBeNull(); descriptor.IsReloadable.ShouldBeTrue(); descriptor.Strategies.Count.ShouldBe(2); descriptor.Strategies[0].Options.ShouldBeOfType(); @@ -135,11 +152,16 @@ public async Task GetPipelineDescriptor_Reloadable_Ok() [Fact] public void GetPipelineDescriptor_InnerPipeline_Ok() { - var descriptor = new ResiliencePipelineBuilder() + // Arrange + var pipeline = new ResiliencePipelineBuilder() .AddPipeline(new ResiliencePipelineBuilder().AddConcurrencyLimiter(1).Build()) - .Build() - .GetPipelineDescriptor(); + .Build(); + + // Act + var descriptor = pipeline.GetPipelineDescriptor(); + // Assert + descriptor.ShouldNotBeNull(); descriptor.Strategies.Count.ShouldBe(1); descriptor.Strategies[0].Options.ShouldBeOfType(); }