public async Task ExecuteMutationAsync_WhenExecuteMutationAndTestsPass_ShouldSetMutationsAsSurvived() { var compiler = ProjectCompilerCreator.CreatePositiveCompiler(_fileSystem); var testRunner = TestRunnerClientCreator.CreatePositive(); var mutationDocumentExecutor = new MutationDocumentExecutor(compiler, _dependency, testRunner, _fileSystem); var result = await mutationDocumentExecutor.ExecuteMutationAsync(_config, _mutationDocument); Assert.IsTrue(result.Survived); }
public void ExecuteMutationAsync_WhenExecuteMutationAndNoMappingMatch_ShouldThrowException() { _config.MutationProjects.First().MappedTestProjects = new List <string> { "TestProject2" }; var compiler = ProjectCompilerCreator.CreatePositiveCompiler(_fileSystem); var testRunner = TestRunnerClientCreator.CreatePositive(); var mutationDocumentExecutor = new MutationDocumentExecutor(compiler, _dependency, testRunner, _fileSystem); Assert.ThrowsAsync <MutationDocumentException>(async() => await mutationDocumentExecutor.ExecuteMutationAsync(_config, _mutationDocument)); }
public async Task ExecuteMutationAsync_WhenExecuteMutationAndCancel_ShouldGetMutationCancelled() { var compiler = ProjectCompilerCreator.CreatePositiveCompiler(_fileSystem); var testRunner = TestRunnerClientCreator.CreatePositive(); var cancellation = new CancellationTokenSource(); var token = cancellation.Token; cancellation.Cancel(); var mutationDocumentExecutor = new MutationDocumentExecutor(compiler, _dependency, testRunner, _fileSystem); var result = await mutationDocumentExecutor.ExecuteMutationAsync(_config, _mutationDocument, token); Assert.AreEqual("Mutation cancelled", result.UnexpectedError); }
public async Task <MutationDocumentResult> Handle(ExecuteMutationCommand command, CancellationToken cancellationToken) { return(await _mutationDocumentExecutor.ExecuteMutationAsync(command.Config, command.Mutation)); }
public async Task <IList <MutationDocumentResult> > Handle(ExecuteMutationsCommand command, CancellationToken cancellationToken) { var semaphoreSlim = new SemaphoreSlim(command.Config.NumberOfTestRunInstances, command.Config.NumberOfTestRunInstances); var results = new List <MutationDocumentResult>(); var mutationDocuments = new Queue <MutationDocument>(command.MutationDocuments); var currentRunningDocuments = new List <Task>(); var numberOfMutationsLeft = command.MutationDocuments.Count; var mutationRunLoggers = command.Config.MutationRunLoggers?.Select(m => _mutationRunLoggerFactory.GetMutationRunLogger(m)).ToList() ?? new List <IMutationRunLogger>(); LogTo.Info($"Total number of mutations generated: {numberOfMutationsLeft}"); mutationRunLoggers.ForEach(m => m.LogBeforeRun(command.MutationDocuments)); await Task.Run(() => { while (mutationDocuments.Any()) { semaphoreSlim.Wait(); var document = mutationDocuments.Dequeue(); currentRunningDocuments.Add(Task.Run(async() => { MutationDocumentResult result = null; try { mutationRunLoggers.ForEach(m => m.LogBeforeMutation(document)); command.MutationDocumentStartedCallback?.Invoke(document); var resultTask = _mutationDocumentExecutor.ExecuteMutationAsync(command.Config, document); result = await resultTask; } catch (Exception ex) { LogTo.WarnException($"Unexpected exception when running {document.MutationName}", ex); result = new MutationDocumentResult { Id = document.Id, UnexpectedError = ex.Message }; } finally { lock (results) { results.Add(result); var survived = results.Count(r => r.Survived && (r.CompilationResult != null && r.CompilationResult.IsSuccess) && r.UnexpectedError == null); var killed = results.Count(r => !r.Survived && (r.CompilationResult != null && r.CompilationResult.IsSuccess) && r.UnexpectedError == null); var compileErrors = results.Count(r => r.CompilationResult != null && !r.CompilationResult.IsSuccess); var unknownErrors = results.Count(r => r.UnexpectedError != null); Interlocked.Decrement(ref numberOfMutationsLeft); LogTo.Info($"Current progress: {{ Survived: {survived}, Killed: {killed}, CompileErrors: {compileErrors}, UnknownErrors: {unknownErrors}, MutationsLeft: {numberOfMutationsLeft} }}"); mutationRunLoggers.ForEach(m => m.LogAfterMutation(document, results, numberOfMutationsLeft)); } semaphoreSlim.Release(); command.MutationDocumentCompledtedCallback?.Invoke(result); } })); } }); // Wait for the final ones await Task.WhenAll(currentRunningDocuments); if (results.Any()) { LogTo.Info($"Your mutation score: {GetMutationScore(results)}%"); } return(results); }
public async Task <MutationRunResult> Handle(ExecuteMutationsCommand command, CancellationToken cancellationToken) { var semaphoreSlim = new SemaphoreSlim(command.Config.NumberOfTestRunInstances, command.Config.NumberOfTestRunInstances); var results = new List <MutationDocumentResult>(); var mutationDocuments = new Queue <MutationDocument>(command.MutationDocuments); var currentRunningDocuments = new List <Task>(); var start = DateTime.Now; var numberOfMutationsLeft = command.MutationDocuments.Count; _mutationRunLoggerManager.Initialize(command.Config.MutationRunLoggers); Log.Info($"Total number of mutations generated: {numberOfMutationsLeft}"); _mutationRunLoggerManager.LogBeforeRun(command.MutationDocuments); await Task.Run(() => { while (mutationDocuments.Any()) { if (cancellationToken.IsCancellationRequested) { Log.Info("Cancellation requested (mutation run)"); return; } semaphoreSlim.Wait(); var document = mutationDocuments.Dequeue(); currentRunningDocuments.Add(Task.Run(async() => { MutationDocumentResult result = null; try { _mutationRunLoggerManager.LogBeforeMutation(document); command.MutationDocumentStartedCallback?.Invoke(document); var resultTask = _mutationDocumentExecutor.ExecuteMutationAsync(command.Config, document, cancellationToken); result = await resultTask; } catch (Exception ex) { Log.Warn($"Unexpected exception when running {document.MutationName}", ex); Log.Info("Will put it in the unknown category."); result = new MutationDocumentResult { Id = document.Id, UnexpectedError = ex.Message, }; } finally { lock (results) { results.Add(result); Interlocked.Decrement(ref numberOfMutationsLeft); _mutationRunLoggerManager.LogAfterMutation(document, results, numberOfMutationsLeft); } semaphoreSlim.Release(); command.MutationDocumentCompledtedCallback?.Invoke(result); } })); } }); // Wait for the final ones await Task.WhenAll(currentRunningDocuments); var mutationRunResult = new MutationRunResult(results, cancellationToken.IsCancellationRequested, DateTime.Now - start); if (cancellationToken.IsCancellationRequested) { Log.Info("Mutation run was cancelled"); } else { Log.Info($"Your mutation score: {mutationRunResult.GetMutationScore()}%"); } return(mutationRunResult); }