public async Task TriggerAnalysisAsync_AnalysisFails_NotifiesOfFailure() { void MockSubProcessCall(Action <Message> message, Request request, ISonarLintSettings settings, ILogger logger, CancellationToken token) { throw new NullReferenceException("test"); } var testSubject = new TestableCLangAnalyzer(telemetryManagerMock.Object, new ConfigurableSonarLintSettings(), rulesConfigProviderMock.Object, serviceProviderWithValidProjectItem.Object, analysisNotifierMock.Object, testLogger, cFamilyIssueConverterMock.Object); testSubject.SetCallSubProcessBehaviour(MockSubProcessCall); var filePath = "c:\\test.cpp"; await testSubject.TriggerAnalysisAsync(new Request { File = filePath }, Mock.Of <IIssueConsumer>(), analysisNotifierMock.Object, CancellationToken.None); analysisNotifierMock.Verify(x => x.AnalysisStarted(filePath), Times.Once); analysisNotifierMock.Verify(x => x.AnalysisFailed(filePath, It.Is <NullReferenceException>(e => e.Message == "test")), Times.Once); analysisNotifierMock.VerifyNoOtherCalls(); }
public void TriggerAnalysisAsync_AnalysisIsCancelled_NotifiesOfCancellation() { var mockConsumer = new Mock <IIssueConsumer>(); var subProcess = new SubProcessSimulator(); var testSubject = new TestableCLangAnalyzer(telemetryManagerMock.Object, new ConfigurableSonarLintSettings(), rulesConfigProviderMock.Object, serviceProviderWithValidProjectItem.Object, analysisNotifierMock.Object, testLogger, cFamilyIssueConverterMock.Object); testSubject.SetCallSubProcessBehaviour(subProcess.CallSubProcess); using var cts = new CancellationTokenSource(); try { // Call the CLangAnalyzer on another thread (that thread is blocked by subprocess wrapper) var filePath = "c:\\test.cpp"; var analysisTask = Task.Run(() => testSubject.TriggerAnalysisAsync(new Request { File = filePath }, mockConsumer.Object, analysisNotifierMock.Object, cts.Token)); subProcess.WaitUntilSubProcessCalledByAnalyzer(); cts.Cancel(); // Tell the subprocess mock there are no more messages and wait for the analyzer method to complete subProcess.SignalNoMoreIssues(); bool succeeded = analysisTask.Wait(10000); succeeded.Should().BeTrue(); analysisNotifierMock.Verify(x => x.AnalysisStarted(filePath), Times.Once); analysisNotifierMock.Verify(x => x.AnalysisCancelled(filePath), Times.Once); analysisNotifierMock.VerifyNoOtherCalls(); } finally { // Unblock the subprocess wrapper in case of errors so it can finish subProcess.SignalNoMoreIssues(); } }
public void TriggerAnalysisAsync_IssuesForInactiveRulesAreNotStreamed() { const string fileName = "c:\\data\\aaa\\bbb\file.txt"; var rulesConfig = new DummyCFamilyRulesConfig("c") .AddRule("inactiveRule", isActive: false) .AddRule("activeRule", isActive: true); var request = new Request { File = fileName, RulesConfiguration = rulesConfig, CFamilyLanguage = rulesConfig.LanguageKey }; var inactiveRuleMessage = new Message("inactiveRule", fileName, 1, 1, 1, 1, "inactive message", false, Array.Empty <MessagePart>()); var activeRuleMessage = new Message("activeRule", fileName, 2, 2, 2, 2, "active message", false, Array.Empty <MessagePart>()); var convertedActiveMessage = Mock.Of <IAnalysisIssue>(); cFamilyIssueConverterMock .Setup(x => x.Convert(activeRuleMessage, request.CFamilyLanguage, rulesConfig)) .Returns(convertedActiveMessage); var mockConsumer = new Mock <IIssueConsumer>(); var subProcess = new SubProcessSimulator(); var testSubject = new TestableCLangAnalyzer(telemetryManagerMock.Object, new ConfigurableSonarLintSettings(), rulesConfigProviderMock.Object, serviceProviderWithValidProjectItem.Object, analysisNotifierMock.Object, testLogger, cFamilyIssueConverterMock.Object); testSubject.SetCallSubProcessBehaviour(subProcess.CallSubProcess); try { // Call the CLangAnalyzer on another thread (that thread is blocked by subprocess wrapper) var analysisTask = Task.Run(() => testSubject.TriggerAnalysisAsync(request, mockConsumer.Object, analysisNotifierMock.Object, CancellationToken.None)); subProcess.WaitUntilSubProcessCalledByAnalyzer(); // Stream the inactive rule message to the analyzer subProcess.PassMessageToCLangAnalyzer(inactiveRuleMessage); mockConsumer.Verify(x => x.Accept(fileName, It.IsAny <IEnumerable <IAnalysisIssue> >()), Times.Never); // Now stream an active rule message subProcess.PassMessageToCLangAnalyzer(activeRuleMessage); mockConsumer.Verify(x => x.Accept(fileName, It.IsAny <IEnumerable <IAnalysisIssue> >()), Times.Once); var suppliedIssues = (IEnumerable <IAnalysisIssue>)mockConsumer.Invocations[0].Arguments[1]; suppliedIssues.Count().Should().Be(1); suppliedIssues.First().Should().Be(convertedActiveMessage); // Tell the subprocess mock there are no more messages and wait for the analyzer method to complete subProcess.SignalNoMoreIssues(); bool succeeded = analysisTask.Wait(10000); succeeded.Should().BeTrue(); analysisNotifierMock.Verify(x => x.AnalysisStarted(fileName), Times.Once); analysisNotifierMock.Verify(x => x.AnalysisFinished(fileName, 1, It.IsAny <TimeSpan>()), Times.Once); analysisNotifierMock.VerifyNoOtherCalls(); } finally { // Unblock the subprocess wrapper in case of errors so it can finish subProcess.SignalNoMoreIssues(); } }