From f89d546426cc2c4b57b99929c3d86570c3c0960f Mon Sep 17 00:00:00 2001 From: Cyrille DUPUYDAUBY Date: Sun, 24 Nov 2024 22:58:29 +0100 Subject: [PATCH 1/6] feat: restore use of env variables --- .../InjectedHelpers/MutantControl.cs | 4 ++- .../VsTest/VsTestContextInformation.cs | 25 +++++++++++++------ .../TestRunners/VsTest/VsTestDescription.cs | 3 +-- .../TestRunners/VsTest/VsTestRunner.cs | 25 ++++++++++++------- .../TestRunners/VsTest/VsTestRunnerPool.cs | 3 +-- .../CoverageCollector.cs | 8 +----- 6 files changed, 40 insertions(+), 28 deletions(-) diff --git a/src/Stryker.Core/Stryker.Core/InjectedHelpers/MutantControl.cs b/src/Stryker.Core/Stryker.Core/InjectedHelpers/MutantControl.cs index 38eaa1b541..1eed3837ad 100644 --- a/src/Stryker.Core/Stryker.Core/InjectedHelpers/MutantControl.cs +++ b/src/Stryker.Core/Stryker.Core/InjectedHelpers/MutantControl.cs @@ -48,7 +48,9 @@ public static bool IsActive(int id) if (ActiveMutant == ActiveMutantNotInitValue) { #pragma warning disable CS8600 - string environmentVariable = System.Environment.GetEnvironmentVariable("ActiveMutation"); + // get the environment variable storign the mutation id + string environmentVariableName = System.Environment.GetEnvironmentVariable("STRYKER_CONTROL_VAR"); + string environmentVariable = System.Environment.GetEnvironmentVariable(environmentVariableName); if (string.IsNullOrEmpty(environmentVariable)) { ActiveMutant = -1; diff --git a/src/Stryker.Core/Stryker.Core/TestRunners/VsTest/VsTestContextInformation.cs b/src/Stryker.Core/Stryker.Core/TestRunners/VsTest/VsTestContextInformation.cs index d6494261a6..cb8bfa31dc 100644 --- a/src/Stryker.Core/Stryker.Core/TestRunners/VsTest/VsTestContextInformation.cs +++ b/src/Stryker.Core/Stryker.Core/TestRunners/VsTest/VsTestContextInformation.cs @@ -93,19 +93,22 @@ public void Dispose() } /// - /// Starts a new VsTest instance and returns a wrapper to control it. + /// Starts a new VsTest instance and returns a wrapper to control it. /// /// Name of the instance to create (used in log files) /// a controlling the created instance. - public IVsTestConsoleWrapper BuildVsTestWrapper(string runnerId) + public IVsTestConsoleWrapper BuildVsTestWrapper(string runnerId, string controlVariable) { - var vsTestConsole = _wrapperBuilder(DetermineConsoleParameters(runnerId)); + var env = DetermineConsoleParameters(runnerId); + env.EnvironmentVariables["DOTNET_ROLL_FORWARD_ON_NO_CANDIDATE_FX"]="2"; + // we define a per runner control variable to prevent conflict + env.EnvironmentVariables["STRYKER_CONTROL_VAR"] = controlVariable; + var vsTestConsole = _wrapperBuilder(env); try { // Set roll forward on no candidate fx so vstest console can start on incompatible dotnet core runtimes - Environment.SetEnvironmentVariable("DOTNET_ROLL_FORWARD_ON_NO_CANDIDATE_FX", "2"); vsTestConsole.StartSession(); - vsTestConsole.InitializeExtensions(Enumerable.Empty()); + vsTestConsole.InitializeExtensions([]); } catch (Exception e) { @@ -188,7 +191,7 @@ public bool AddTestSource(string source, string frameworkVersion = null, string private void DiscoverTestsInSources(string newSource, string frameworkVersion = null, string platform = null) { - var wrapper = BuildVsTestWrapper("TestDiscoverer"); + var wrapper = BuildVsTestWrapper("TestDiscoverer", "NOT_NEEDED"); var messages = new List(); var handler = new DiscoveryEventHandler(messages); var settings = GenerateRunSettingsForDiscovery(frameworkVersion, platform); @@ -223,6 +226,13 @@ private void DiscoverTestsInSources(string newSource, string frameworkVersion = Tests.RegisterTests(VsTests.Values.Select(t => t.Description)); } + internal void RegisterDiscoveredTest(VsTestDescription vsTestDescription) + { + VsTests[vsTestDescription.Id] = vsTestDescription; + Tests.RegisterTest(vsTestDescription.Description); + TestsPerSource[vsTestDescription.Case.Source].Add(vsTestDescription.Id); + } + private void DetectTestFrameworks(ICollection tests) { if (tests == null) @@ -262,7 +272,7 @@ private string GenerateCoreSettings(int maxCpu, string frameworkVersion, string return $@" {Math.Max(0, maxCpu)} -{frameworkConfig}{platformConfig}{testCaseFilter} true +{frameworkConfig}{platformConfig}{testCaseFilter} true"; } @@ -309,4 +319,5 @@ public string GenerateRunSettings(int? timeout, bool forCoverage, Dictionary _initialResults = new List(); + private readonly ICollection _initialResults = []; private int _subCases; public VsTestDescription(TestCase testCase) diff --git a/src/Stryker.Core/Stryker.Core/TestRunners/VsTest/VsTestRunner.cs b/src/Stryker.Core/Stryker.Core/TestRunners/VsTest/VsTestRunner.cs index 0c5d275aac..410f3650d1 100644 --- a/src/Stryker.Core/Stryker.Core/TestRunners/VsTest/VsTestRunner.cs +++ b/src/Stryker.Core/Stryker.Core/TestRunners/VsTest/VsTestRunner.cs @@ -35,6 +35,7 @@ public sealed class VsTestRunner : IDisposable private const int MaxAttempts = 3; private string RunnerId => $"Runner {_id}"; + private string ControlVariableName => $"ACTIVE_MUTATION_{_id}"; public VsTestRunner(VsTestContextInformation context, int id, @@ -43,7 +44,7 @@ public VsTestRunner(VsTestContextInformation context, _context = context; _id = id; _logger = logger ?? ApplicationLogging.LoggerFactory.CreateLogger(); - _vsTestConsole = _context.BuildVsTestWrapper(RunnerId); + _vsTestConsole = _context.BuildVsTestWrapper(RunnerId, ControlVariableName); } public TestRunResult InitialTest(IProjectAndTests project) @@ -60,8 +61,7 @@ public TestRunResult InitialTest(IProjectAndTests project) if (!_context.VsTests.ContainsKey(result.TestCase.Id)) { var vsTestDescription = new VsTestDescription(result.TestCase); - _context.VsTests[result.TestCase.Id] = vsTestDescription; - _context.Tests.RegisterTest(vsTestDescription.Description); + _context.RegisterDiscoveredTest(vsTestDescription); _logger.LogWarning( "{RunnerId}: Initial test run encounter an unexpected test case ({DisplayName}), mutation tests may be inaccurate. Disable coverage analysis if you have doubts.", RunnerId, result.TestCase.DisplayName); @@ -84,7 +84,7 @@ public TestRunResult TestMultipleMutants(IProjectAndTests project, ITimeoutValue if (testCases?.Count == 0) { return new TestRunResult(_context.VsTests.Values, TestGuidsList.NoTest(), TestGuidsList.NoTest(), - TestGuidsList.NoTest(), "Mutants are not covered by any test!", Enumerable.Empty(), + TestGuidsList.NoTest(), "Mutants are not covered by any test!", [], TimeSpan.Zero); } @@ -115,7 +115,7 @@ void HandleUpdate(IRunResults handler) : new WrappedGuidsEnumeration(handlerTestResults.Select(t => t.TestCase.Id)); var failedTest = new WrappedGuidsEnumeration(handlerTestResults .Where(tr => tr.Outcome == TestOutcome.Failed) - .Select(t => t.TestCase.Id)); + .Select(t => t.TestCase.Id)); var timedOutTest = new WrappedGuidsEnumeration(handler.TestsInTimeout?.Select(t => t.Id)); var remainingMutants = update?.Invoke(mutants, failedTest, tests, timedOutTest); @@ -248,8 +248,13 @@ public IRunResults RunCoverageSession(ITestGuids testsToRun, IProjectAndTests pr } var runSettings = _context.GenerateRunSettings(timeOut, forCoverage, mutantTestsMap, projectAndTests.HelperNamespace, source.TargetFramework, source.TargetPlatform()); - _logger.LogTrace("{RunnerId}: testing assembly {source}.", RunnerId, source); + var activeId = -1; + if (mutantTestsMap!=null && mutantTestsMap.Count==1) + { + activeId = mutantTestsMap.Keys.First(); + } + Environment.SetEnvironmentVariable(ControlVariableName, activeId.ToString()); RunVsTest(tests, source.GetAssemblyPath(), runSettings, options, timeOut, runEventHandler); if (_currentSessionCancelled) @@ -281,13 +286,15 @@ private void RunVsTest(ITestGuids tests, string source, string runSettings, Test { if (tests.IsEveryTest) { - _vsTestConsole.RunTestsWithCustomTestHost(new[] { source }, runSettings, options, eventHandler, + _vsTestConsole.RunTestsWithCustomTestHost([source], runSettings, options, eventHandler, strykerVsTestHostLauncher); } else { + var actualTestCases = tests.GetGuids().Select(t => _context.VsTests[t].Case).ToList(); + var testCases = actualTestCases; _vsTestConsole.RunTestsWithCustomTestHost( - tests.GetGuids().Select(t => _context.VsTests[t].Case), + testCases, runSettings, options, eventHandler, strykerVsTestHostLauncher); } }); @@ -371,7 +378,7 @@ private void PrepareVsTestConsole() } } - _vsTestConsole = _context.BuildVsTestWrapper($"{RunnerId}-{_instanceCount}"); + _vsTestConsole = _context.BuildVsTestWrapper($"{RunnerId}-{_instanceCount}", ControlVariableName); } #region IDisposable Support diff --git a/src/Stryker.Core/Stryker.Core/TestRunners/VsTest/VsTestRunnerPool.cs b/src/Stryker.Core/Stryker.Core/TestRunners/VsTest/VsTestRunnerPool.cs index ab307e796e..4ede47d9ae 100644 --- a/src/Stryker.Core/Stryker.Core/TestRunners/VsTest/VsTestRunnerPool.cs +++ b/src/Stryker.Core/Stryker.Core/TestRunners/VsTest/VsTestRunnerPool.cs @@ -188,8 +188,7 @@ private bool ConvertSingleResult(TestResult testResult, ISet seenTestCases // ==> we need it to use this test against every mutation _logger.LogDebug("VsTestRunner: No coverage data for {TestCase}.", testResult.TestCase.DisplayName); seenTestCases.Add(testDescription.Id); - coverageRunResult = new CoverageRunResult(testCaseId, CoverageConfidence.Dubious, Enumerable.Empty(), - Enumerable.Empty(), Enumerable.Empty()); + coverageRunResult = new CoverageRunResult(testCaseId, CoverageConfidence.Dubious, [], [], []); } else { diff --git a/src/Stryker.DataCollector/Stryker.DataCollector/CoverageCollector.cs b/src/Stryker.DataCollector/Stryker.DataCollector/CoverageCollector.cs index c840b323ad..583ff1051f 100644 --- a/src/Stryker.DataCollector/Stryker.DataCollector/CoverageCollector.cs +++ b/src/Stryker.DataCollector/Stryker.DataCollector/CoverageCollector.cs @@ -29,7 +29,6 @@ public class CoverageCollector : InProcDataCollection private IDataCollectionSink _dataSink; private bool _coverageOn; private int _activeMutation = -1; - private bool _reportFailure; private Action _logger; private readonly IDictionary _mutantTestedBy = new Dictionary(); @@ -94,7 +93,6 @@ public void Initialize(IDataCollectionSink dataCollectionSink) { _dataSink = dataCollectionSink; _throwingListener = new ThrowingListener(); - SetLogger(Console.WriteLine); } public void SetLogger(Action logger) => _logger = logger; @@ -276,11 +274,7 @@ private void PublishCoverageData(DataCollectionContext dataCollectionContext) { // no test covered any mutations, so the controller was never properly initialized _dataSink.SendData(dataCollectionContext, PropertyName, ";"); - if (!_reportFailure) - { - _dataSink.SendData(dataCollectionContext, CoverageLog, $"Did not find type {_controlClassName}. Mutated assembly may not be covered by any test."); - _reportFailure = true; - } + _dataSink.SendData(dataCollectionContext, CoverageLog, $"Test {dataCollectionContext.TestCase.DisplayName} endend. No mutant covered so far."); return; } From 6ec42a3e841851b981a582f24c0f3c0a624cc9d1 Mon Sep 17 00:00:00 2001 From: Cyrille DUPUYDAUBY Date: Mon, 25 Nov 2024 09:19:57 +0100 Subject: [PATCH 2/6] feat: disable coverage analysis optimisation when no coverage is reported --- .../Library.FSharp.XUnit.fsproj | 2 +- .../Library.FSharp/Library.FSharp.fsproj | 2 +- .../TestRunners/VsTestRunnerPoolTests.cs | 7 +++--- .../CoverageAnalysis/CoverageAnalyser.cs | 22 ++++++++++++++----- .../Initialisation/InitialisationProcess.cs | 2 +- 5 files changed, 24 insertions(+), 11 deletions(-) diff --git a/integrationtest/TargetProjects/NetCore/Library.FSharp.XUnit/Library.FSharp.XUnit.fsproj b/integrationtest/TargetProjects/NetCore/Library.FSharp.XUnit/Library.FSharp.XUnit.fsproj index b8d9d83ad3..ec09f7212c 100644 --- a/integrationtest/TargetProjects/NetCore/Library.FSharp.XUnit/Library.FSharp.XUnit.fsproj +++ b/integrationtest/TargetProjects/NetCore/Library.FSharp.XUnit/Library.FSharp.XUnit.fsproj @@ -1,7 +1,7 @@ - net6.0 + net8.0 true diff --git a/integrationtest/TargetProjects/NetCore/Library.FSharp/Library.FSharp.fsproj b/integrationtest/TargetProjects/NetCore/Library.FSharp/Library.FSharp.fsproj index 6dffa25b92..bb01451bea 100644 --- a/integrationtest/TargetProjects/NetCore/Library.FSharp/Library.FSharp.fsproj +++ b/integrationtest/TargetProjects/NetCore/Library.FSharp/Library.FSharp.fsproj @@ -1,7 +1,7 @@ - net6.0 + net8.0 diff --git a/src/Stryker.Core/Stryker.Core.UnitTest/TestRunners/VsTestRunnerPoolTests.cs b/src/Stryker.Core/Stryker.Core.UnitTest/TestRunners/VsTestRunnerPoolTests.cs index f0f0233cd5..22ee4a81f1 100644 --- a/src/Stryker.Core/Stryker.Core.UnitTest/TestRunners/VsTestRunnerPoolTests.cs +++ b/src/Stryker.Core/Stryker.Core.UnitTest/TestRunners/VsTestRunnerPoolTests.cs @@ -257,7 +257,7 @@ public void IdentifyNonCoveredMutants() } [TestMethod] - public void WorksWhenAllMutantsAreIgnoredPool() + public void ShouldIgnoreCoverageAnalysisWhenEmpty() { var options = new StrykerOptions { @@ -270,7 +270,7 @@ public void WorksWhenAllMutantsAreIgnoredPool() var analyzer = new CoverageAnalyser(options); analyzer.DetermineTestCoverage(SourceProjectInfo, runner, new[] { Mutant, OtherMutant }, TestGuidsList.NoTest()); - Mutant.CoveringTests.Count.ShouldBe(0); + Mutant.CoveringTests.IsEveryTest.ShouldBeTrue(); } [TestMethod] @@ -666,8 +666,9 @@ public void DetectUnexpectedCase() var mockVsTest = BuildVsTestRunnerPool(options, out var runner); + var testResult = BuildCoverageTestResult("T0", new[] { "0;", "" }); var buildCase = BuildCase("unexpected", TestFrameworks.NUnit); - SetupMockCoverageRun(mockVsTest, new[] { new VsTest.TestResult(buildCase) { Outcome = VsTest.TestOutcome.Passed } }); + SetupMockCoverageRun(mockVsTest, new[] { new VsTest.TestResult(buildCase) { Outcome = VsTest.TestOutcome.Passed }, testResult }); var analyzer = new CoverageAnalyser(options); analyzer.DetermineTestCoverage(SourceProjectInfo, runner, new[] { Mutant, OtherMutant }, TestGuidsList.NoTest()); diff --git a/src/Stryker.Core/Stryker.Core/CoverageAnalysis/CoverageAnalyser.cs b/src/Stryker.Core/Stryker.Core/CoverageAnalysis/CoverageAnalyser.cs index 152170f27c..e10cb2a426 100644 --- a/src/Stryker.Core/Stryker.Core/CoverageAnalysis/CoverageAnalyser.cs +++ b/src/Stryker.Core/Stryker.Core/CoverageAnalysis/CoverageAnalyser.cs @@ -30,11 +30,7 @@ public void DetermineTestCoverage(IProjectAndTests project, ITestRunner runner, if (!_options.OptimizationMode.HasFlag(OptimizationModes.SkipUncoveredMutants) && !_options.OptimizationMode.HasFlag(OptimizationModes.CoverageBasedTest)) { - foreach (var mutant in mutants) - { - mutant.CoveringTests = TestGuidsList.EveryTest(); - mutant.AssessingTests = TestGuidsList.EveryTest(); - } + AssumeAllTestsAreNeeded(mutants); return; } @@ -42,9 +38,25 @@ public void DetermineTestCoverage(IProjectAndTests project, ITestRunner runner, ParseCoverage(runner.CaptureCoverage(project), mutants, new TestGuidsList(resultFailingTests.GetGuids())); } + private static void AssumeAllTestsAreNeeded(IEnumerable mutants) + { + foreach (var mutant in mutants) + { + mutant.CoveringTests = TestGuidsList.EveryTest(); + mutant.AssessingTests = TestGuidsList.EveryTest(); + } + } + private void ParseCoverage(IEnumerable coverage, IEnumerable mutantsToScan, TestGuidsList failedTests) { + if (coverage.Sum(c => c.MutationsCovered.Count) == 0) + { + _logger.LogError("It looks like the test coverage capture failed. Disable coverage based optimisation."); + AssumeAllTestsAreNeeded(mutantsToScan); + return; + } + var dubiousTests = new HashSet(); var trustedTests = new HashSet(); var testIds = new HashSet(); diff --git a/src/Stryker.Core/Stryker.Core/Initialisation/InitialisationProcess.cs b/src/Stryker.Core/Stryker.Core/Initialisation/InitialisationProcess.cs index 088cd0c9c8..7a63c6a9f0 100644 --- a/src/Stryker.Core/Stryker.Core/Initialisation/InitialisationProcess.cs +++ b/src/Stryker.Core/Stryker.Core/Initialisation/InitialisationProcess.cs @@ -158,7 +158,7 @@ private InitialTestRun InitialTest(IStrykerOptions options, SourceProjectInfo pr } throw new InputException( - "No test has been detected. Make sure your test project contains test and is compatible with VsTest." + + "No test result reported. Make sure your test project contains test and is compatible with VsTest." + string.Join(Environment.NewLine, projectInfo.Warnings)); } From f8aacd00664954c557762a5c26d2b5efacba8b20 Mon Sep 17 00:00:00 2001 From: Cyrille DUPUYDAUBY Date: Tue, 3 Dec 2024 11:31:30 +0100 Subject: [PATCH 3/6] fix: address PR comments --- .../Stryker.Core/InjectedHelpers/MutantControl.cs | 4 ++-- .../TestRunners/VsTest/VsTestContextInformation.cs | 7 ++++--- .../Stryker.Core/TestRunners/VsTest/VsTestRunner.cs | 2 +- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/Stryker.Core/Stryker.Core/InjectedHelpers/MutantControl.cs b/src/Stryker.Core/Stryker.Core/InjectedHelpers/MutantControl.cs index 557d69015b..7c85175d73 100644 --- a/src/Stryker.Core/Stryker.Core/InjectedHelpers/MutantControl.cs +++ b/src/Stryker.Core/Stryker.Core/InjectedHelpers/MutantControl.cs @@ -48,8 +48,8 @@ public static bool IsActive(int id) if (ActiveMutant == ActiveMutantNotInitValue) { #pragma warning disable CS8600 - // get the environment variable storign the mutation id - string environmentVariableName = System.Environment.GetEnvironmentVariable("STRYKER_CONTROL_VAR"); + // get the environment variable storing the mutation id + string environmentVariableName = System.Environment.GetEnvironmentVariable("STRYKER_MUTANT_ID_CONTROL_VAR"); if (environmentVariableName != null) { string environmentVariable = System.Environment.GetEnvironmentVariable(environmentVariableName); diff --git a/src/Stryker.Core/Stryker.Core/TestRunners/VsTest/VsTestContextInformation.cs b/src/Stryker.Core/Stryker.Core/TestRunners/VsTest/VsTestContextInformation.cs index cb8bfa31dc..4253d9ff0c 100644 --- a/src/Stryker.Core/Stryker.Core/TestRunners/VsTest/VsTestContextInformation.cs +++ b/src/Stryker.Core/Stryker.Core/TestRunners/VsTest/VsTestContextInformation.cs @@ -33,7 +33,7 @@ public sealed class VsTestContextInformation : IDisposable private TestFrameworks _testFramework; /// - /// Discovered tests (VsTest format) + /// Discovered tests (VsTest format) /// public IDictionary VsTests { get; private set; } @@ -43,7 +43,7 @@ public sealed class VsTestContextInformation : IDisposable public IDictionary> TestsPerSource { get; } = new Dictionary>(); /// - /// Tests (Stryker format) + /// Tests (Stryker format) /// public TestSet Tests { get; } = new(); @@ -96,13 +96,14 @@ public void Dispose() /// Starts a new VsTest instance and returns a wrapper to control it. /// /// Name of the instance to create (used in log files) + /// name of the env variable storing the active mutation id /// a controlling the created instance. public IVsTestConsoleWrapper BuildVsTestWrapper(string runnerId, string controlVariable) { var env = DetermineConsoleParameters(runnerId); env.EnvironmentVariables["DOTNET_ROLL_FORWARD_ON_NO_CANDIDATE_FX"]="2"; // we define a per runner control variable to prevent conflict - env.EnvironmentVariables["STRYKER_CONTROL_VAR"] = controlVariable; + env.EnvironmentVariables["STRYKER_MUTANT_ID_CONTROL_VAR"] = controlVariable; var vsTestConsole = _wrapperBuilder(env); try { diff --git a/src/Stryker.Core/Stryker.Core/TestRunners/VsTest/VsTestRunner.cs b/src/Stryker.Core/Stryker.Core/TestRunners/VsTest/VsTestRunner.cs index 410f3650d1..33174f82a1 100644 --- a/src/Stryker.Core/Stryker.Core/TestRunners/VsTest/VsTestRunner.cs +++ b/src/Stryker.Core/Stryker.Core/TestRunners/VsTest/VsTestRunner.cs @@ -250,7 +250,7 @@ public IRunResults RunCoverageSession(ITestGuids testsToRun, IProjectAndTests pr projectAndTests.HelperNamespace, source.TargetFramework, source.TargetPlatform()); _logger.LogTrace("{RunnerId}: testing assembly {source}.", RunnerId, source); var activeId = -1; - if (mutantTestsMap!=null && mutantTestsMap.Count==1) + if (mutantTestsMap is { Count: 1 }) { activeId = mutantTestsMap.Keys.First(); } From 02af9177f970de0a8ca4d8e63770dad7a3c68dec Mon Sep 17 00:00:00 2001 From: Cyrille DUPUYDAUBY Date: Tue, 3 Dec 2024 11:38:03 +0100 Subject: [PATCH 4/6] Restores F# test projects settings --- .../NetCore/Library.FSharp.XUnit/Library.FSharp.XUnit.fsproj | 2 +- .../TargetProjects/NetCore/Library.FSharp/Library.FSharp.fsproj | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/integrationtest/TargetProjects/NetCore/Library.FSharp.XUnit/Library.FSharp.XUnit.fsproj b/integrationtest/TargetProjects/NetCore/Library.FSharp.XUnit/Library.FSharp.XUnit.fsproj index ec09f7212c..b8d9d83ad3 100644 --- a/integrationtest/TargetProjects/NetCore/Library.FSharp.XUnit/Library.FSharp.XUnit.fsproj +++ b/integrationtest/TargetProjects/NetCore/Library.FSharp.XUnit/Library.FSharp.XUnit.fsproj @@ -1,7 +1,7 @@ - net8.0 + net6.0 true diff --git a/integrationtest/TargetProjects/NetCore/Library.FSharp/Library.FSharp.fsproj b/integrationtest/TargetProjects/NetCore/Library.FSharp/Library.FSharp.fsproj index bb01451bea..6dffa25b92 100644 --- a/integrationtest/TargetProjects/NetCore/Library.FSharp/Library.FSharp.fsproj +++ b/integrationtest/TargetProjects/NetCore/Library.FSharp/Library.FSharp.fsproj @@ -1,7 +1,7 @@ - net8.0 + net6.0 From bfd3200a5b331d93ec8fd1c4b11672da16268006 Mon Sep 17 00:00:00 2001 From: Cyrille DUPUYDAUBY Date: Tue, 3 Dec 2024 11:51:58 +0100 Subject: [PATCH 5/6] fix: minor design change --- src/Stryker.Core/Stryker.Core/Mutants/TestGuidsList.cs | 2 +- .../Stryker.Core/TestRunners/VsTest/VsTestRunner.cs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Stryker.Core/Stryker.Core/Mutants/TestGuidsList.cs b/src/Stryker.Core/Stryker.Core/Mutants/TestGuidsList.cs index 63aca9a96b..4d4588da56 100644 --- a/src/Stryker.Core/Stryker.Core/Mutants/TestGuidsList.cs +++ b/src/Stryker.Core/Stryker.Core/Mutants/TestGuidsList.cs @@ -77,7 +77,7 @@ public TestGuidsList Excluding(TestGuidsList testsToSkip) public static TestGuidsList NoTest() => NoTestAtAll; - public IEnumerable GetGuids() => _testGuids; + public IEnumerable GetGuids() => _testGuids ?? []; public bool ContainsAny(ITestGuids other) { diff --git a/src/Stryker.Core/Stryker.Core/TestRunners/VsTest/VsTestRunner.cs b/src/Stryker.Core/Stryker.Core/TestRunners/VsTest/VsTestRunner.cs index 33174f82a1..de6e99665c 100644 --- a/src/Stryker.Core/Stryker.Core/TestRunners/VsTest/VsTestRunner.cs +++ b/src/Stryker.Core/Stryker.Core/TestRunners/VsTest/VsTestRunner.cs @@ -180,7 +180,7 @@ private TestRunResult BuildTestRunResult(IRunResults testResults, int expectedTe // ranTests is the list of test that have been executed. We detect the special case where all (existing and found) tests have been executed. // this is needed when the tests list is not stable (mutations can generate variation for theories) and also helps for performance // so we assume that if executed at least as much test as have been detected, it means all tests have been executed - // EXCEPT when no test have been found. Otherwise, an empty test project would transform non covered mutants to survivors. + // EXCEPT when no test have been found. Otherwise, an empty test project would transform non-covered mutants to survivors. var ranTests = compressAll && totalCountOfTests > 0 && ranTestsCount >= totalCountOfTests ? (ITestGuids)TestGuidsList.EveryTest() : new WrappedGuidsEnumeration(testCases); @@ -240,7 +240,7 @@ public IRunResults RunCoverageSession(ITestGuids testsToRun, IProjectAndTests pr foreach (var source in projectAndTests.TestProjectsInfo.AnalyzerResults) { var testForSource = _context.TestsPerSource[source.GetAssemblyPath()]; - var testsForAssembly = new TestGuidsList(tests.GetGuids()?.Where(testForSource.Contains)); + var testsForAssembly = new TestGuidsList(tests.GetGuids().Where(testForSource.Contains)); if (!tests.IsEveryTest && testsForAssembly.Count == 0) { // skip empty assemblies From 5fecda8c9d73ce0ad3fca8536d0f8e2933c6da37 Mon Sep 17 00:00:00 2001 From: Rouke Broersma Date: Fri, 20 Dec 2024 12:22:52 +0100 Subject: [PATCH 6/6] Update src/Stryker.Core/Stryker.Core/TestRunners/VsTest/VsTestContextInformation.cs --- .../Stryker.Core/TestRunners/VsTest/VsTestContextInformation.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Stryker.Core/Stryker.Core/TestRunners/VsTest/VsTestContextInformation.cs b/src/Stryker.Core/Stryker.Core/TestRunners/VsTest/VsTestContextInformation.cs index 4253d9ff0c..c02b532532 100644 --- a/src/Stryker.Core/Stryker.Core/TestRunners/VsTest/VsTestContextInformation.cs +++ b/src/Stryker.Core/Stryker.Core/TestRunners/VsTest/VsTestContextInformation.cs @@ -101,13 +101,13 @@ public void Dispose() public IVsTestConsoleWrapper BuildVsTestWrapper(string runnerId, string controlVariable) { var env = DetermineConsoleParameters(runnerId); + // Set roll forward on no candidate fx so vstest console can start on incompatible dotnet core runtimes env.EnvironmentVariables["DOTNET_ROLL_FORWARD_ON_NO_CANDIDATE_FX"]="2"; // we define a per runner control variable to prevent conflict env.EnvironmentVariables["STRYKER_MUTANT_ID_CONTROL_VAR"] = controlVariable; var vsTestConsole = _wrapperBuilder(env); try { - // Set roll forward on no candidate fx so vstest console can start on incompatible dotnet core runtimes vsTestConsole.StartSession(); vsTestConsole.InitializeExtensions([]); }