private TestRunResult RunTestSession(IList <Mutant> mutantsToTest, ITimeoutValueCalculator timeoutMs, TestUpdateHandler updateHandler, bool forceSingle) { TestRunResult result; Logger.LogTrace($"Testing {string.Join(" ,", mutantsToTest.Select(x => x.DisplayName))}."); if (forceSingle && mutantsToTest.Count > 1) { foreach (var mutant in mutantsToTest) { var localResult = TestRunner.TestMultipleMutants(timeoutMs, new[] { mutant }, updateHandler); mutant.AnalyzeTestRun(localResult.FailingTests, localResult.RanTests, localResult.TimedOutTests); } return(new TestRunResult(true)); } else { result = TestRunner.TestMultipleMutants(timeoutMs, mutantsToTest.ToList(), updateHandler); if (updateHandler == null) { foreach (var mutant in mutantsToTest) { mutant.AnalyzeTestRun(result.FailingTests, result.RanTests, result.TimedOutTests); } } } return(result); }
public void Test(IList <Mutant> mutantsToTest, ITimeoutValueCalculator timeoutMs, TestUpdateHandler updateHandler) { var forceSingle = false; while (mutantsToTest.Any()) { var result = RunTestSession(mutantsToTest, timeoutMs, updateHandler, forceSingle); Logger.LogTrace( $"Test run for {string.Join(" ,", mutantsToTest.Select(x => x.DisplayName))} is {(result.FailingTests.Count == 0 ? "success" : "failed")} with output: {result.ResultMessage}"); var remainingMutants = mutantsToTest.Where((m) => m.ResultStatus == MutantStatus.NotRun).ToList(); if (remainingMutants.Count == mutantsToTest.Count) { // the test failed to get any conclusive results if (!result.SessionTimedOut) { // something bad happened. Logger.LogError($"Stryker failed to test {remainingMutants.Count} mutant(s)."); return; } // test session's results have been corrupted by the time out // we retry and run tests one by one, if necessary if (remainingMutants.Count == 1) { // only one mutant was tested, we mark it as timeout. remainingMutants[0].ResultStatus = MutantStatus.Timeout; remainingMutants.Clear(); } else { // we don't know which tests timed out, we rerun all tests in dedicated sessions forceSingle = true; } } if (remainingMutants.Any()) { Logger.LogDebug("Not all mutants were tested."); } mutantsToTest = remainingMutants; } }
public TestRunResult RunAll(ITimeoutValueCalculator timeoutMs, Mutant activeMutant, TestUpdateHandler update) { return(TestMultipleMutants(timeoutMs, activeMutant == null ? null : new List <Mutant> { activeMutant }, update)); }
public InitialTestRun(TestRunResult result, ITimeoutValueCalculator timeoutValueCalculator) { Result = result; TimeoutValueCalculator = timeoutValueCalculator; }
public TestRunResult TestMultipleMutants(ITimeoutValueCalculator timeoutCalc, IReadOnlyList <Mutant> mutants, TestUpdateHandler update) { var mutantTestsMap = new Dictionary <int, ITestGuids>(); var needAll = true; ICollection <Guid> testCases; int?timeOutMs = timeoutCalc?.DefaultTimeout; if (mutants != null) { // if we optimize the number of tests to run if (_options.OptimizationMode.HasFlag(OptimizationModes.CoverageBasedTest)) { needAll = false; foreach (var mutant in mutants) { ITestListDescription tests; if ((mutant.IsStaticValue && !_options.OptimizationMode.HasFlag(OptimizationModes.CaptureCoveragePerTest)) || mutant.MustRunAgainstAllTests) { tests = TestsGuidList.EveryTest(); needAll = true; } else { tests = mutant.CoveringTests; } mutantTestsMap.Add(mutant.Id, tests); } testCases = needAll ? null : mutants.SelectMany(m => m.CoveringTests.GetGuids()).ToList(); _logger.LogTrace($"{RunnerId}: Testing [{string.Join(',', mutants.Select(m => m.DisplayName))}] " + $"against {(testCases == null ? "all tests." : string.Join(", ", testCases))}."); if (testCases?.Count == 0) { return(new TestRunResult(TestsGuidList.NoTest(), TestsGuidList.NoTest(), TestsGuidList.NoTest(), "Mutants are not covered by any test!", TimeSpan.Zero)); } if (timeoutCalc != null && testCases != null) { // compute time out var duration = (int)testCases.Select(id => _vsTests[id].InitialRunTime.TotalMilliseconds).Sum(); timeOutMs = timeoutCalc.CalculateTimeoutValue(duration); } } else { if (mutants.Count > 1) { throw new GeneralStrykerException("Internal error: trying to test multiple mutants simultaneously without 'perTest' coverage analysis."); } mutantTestsMap.Add(mutants[0].Id, TestsGuidList.EveryTest()); testCases = null; } } else { testCases = null; } var numberTestCases = testCases == null ? 0 : testCases.Count; var expectedTests = needAll ? DiscoverTests().Count : numberTestCases; void HandleUpdate(IRunResults handler) { var handlerTestResults = handler.TestResults; if (mutants == null) { return; } var tests = handlerTestResults.Count == DiscoverTests().Count ? (ITestGuids)TestsGuidList.EveryTest() : new WrappedGuidsEnumeration(handlerTestResults.Select(t => t.TestCase.Id)); var failedTest = new WrappedGuidsEnumeration(handlerTestResults.Where(tr => tr.Outcome == TestOutcome.Failed) .Select(t => t.TestCase.Id)); var timedOutTest = new WrappedGuidsEnumeration(handler.TestsInTimeout?.Select(t => t.Id)); var remainingMutants = update?.Invoke(mutants, failedTest, tests, timedOutTest); if (handlerTestResults.Count >= expectedTests || remainingMutants != false || _aborted) { return; } // all mutants status have been resolved, we can stop _logger.LogDebug($"{RunnerId}: Each mutant's fate has been established, we can stop."); _vsTestConsole.CancelTestRun(); _aborted = true; } _logger.LogDebug("Using {0} ms as testrun timeout", timeOutMs.ToString() ?? "no"); var testResults = RunTestSession(mutantTestsMap, needAll, GenerateRunSettings(timeOutMs, mutants != null, false, mutantTestsMap), HandleUpdate); return(BuildTestRunResult(testResults, expectedTests)); }