public static SuppressionModel ToSuppressionModel(this Suppression suppression, SarifErrorListItem sarifErrorListItem) { if (suppression == null) { return(null); } var model = new SuppressionModel(sarifErrorListItem) { Kind = suppression.Kind, Status = suppression.Status, }; return(model); }
internal void AddSuppressionToSarifLog(SuppressionModel suppressionModel) { if (suppressionModel?.SelectedErrorListItems?.Any() != true) { return; } int runIndex = -1; bool suppressionAdded = false; foreach (SarifErrorListItem item in suppressionModel.SelectedErrorListItems) { runIndex = runIndex == -1 ? item.RunIndex : runIndex; if (item.SarifResult != null) { if (item.SarifResult.Suppressions == null) { item.SarifResult.Suppressions = new List <Suppression>(); } var suppression = new Suppression { Status = suppressionModel.Status, Kind = SuppressionKind.External, }; item.SarifResult.Suppressions.Add(suppression); suppressionAdded = true; } } if (runIndex == -1 || !this.RunIndexToRunDataCache.TryGetValue(runIndex, out RunDataCache dataCache) || dataCache.SarifLog == null) { return; } if (suppressionAdded) { // add empty suppression for results don't have suppression // this is to satisfy sarif spec: either all results have non-null suppressions or have no suppressions // spec link: https://docs.oasis-open.org/sarif/sarif/v2.1.0/os/sarif-v2.1.0-os.html#_Toc34317661 // "The suppressions values for all result objects in theRun SHALL be either all null or all non-null. // "NOTE: The rationale is that an engineering system will generally evaluate all results for suppression, or none of them.Requiring that the suppressions values be either all null or all non - null enables a consumer to determine whether suppression information is available for the run by examining a single result object." foreach (SarifErrorListItem errorListItem in dataCache.SarifErrors) { if (errorListItem.SarifResult.Suppressions == null) { errorListItem.SarifResult.Suppressions = Array.Empty <Suppression>(); } } var serializer = new JsonSerializer() { Formatting = Formatting.Indented, }; using (var writer = new JsonTextWriter( new StreamWriter(this._fileSystem.FileCreate(dataCache.LogFilePath)))) { serializer.Serialize(writer, dataCache.SarifLog); } } }
public async Task <SarifLog> VerifySuppressionTests(dynamic testCase) { DateTime now = DateTime.UtcNow; string[] resultToBeSuppressed = testCase.ResultToBeSuppressed; string sarifLogFilePath = @"E:\Users\AnUser\Sarif\Logs\ResultsToSuppress.sarif"; var transformedContents = new StringBuilder(); var mockFileSystem = new Mock <IFileSystem>(); mockFileSystem .Setup(x => x.FileCreate(sarifLogFilePath)) .Returns(() => new StringBuilderFileStreamMock(transformedContents)); CodeAnalysisResultManager.Instance = new CodeAnalysisResultManager(mockFileSystem.Object); SarifLog sarifLog = CreateTestSarifLog(); await TestUtilities.InitializeTestEnvironmentAsync(sarifLog, sarifLogFilePath); IEnumerable <SarifErrorListItem> itemToBeSuppressed = CodeAnalysisResultManager.Instance .RunIndexToRunDataCache[CodeAnalysisResultManager.Instance.CurrentRunIndex] .SarifErrors.Where(i => resultToBeSuppressed.Contains(i.Rule.Id)); SuppressionModel model = testCase.Model; if (model != null && itemToBeSuppressed != null) { model.SelectedErrorListItems = itemToBeSuppressed; } sarifLog.Runs.First().HasSuppressedResults().Should().Be(false); CodeAnalysisResultManager.Instance.AddSuppressionToSarifLog(model); SarifLog suppressedLog = JsonConvert.DeserializeObject <SarifLog>(transformedContents.ToString()); if (!testCase.Expected.SuppressionAdded) { suppressedLog.Should().BeNull(); return(suppressedLog); } Run run = suppressedLog.Runs.First(); run.HasSuppressedResults().Should().Be(testCase.Expected.RunHasSuppressions); foreach (Result result in run.Results) { if (resultToBeSuppressed.Contains(result.RuleId)) { // suppressed result result.Suppressions.Should().NotBeNullOrEmpty(); result.Suppressions.Count.Should().Be(1); result.TryIsSuppressed(out bool isSuppressed).Should().Be(true); isSuppressed.Should().Be(model.Status == SuppressionStatus.Accepted); Suppression suppression = result.Suppressions.First(); suppression.Status.Should().Be(model.Status); suppression.Kind.Should().Be(model.Kind); } else { if (testCase.Expected.RunHasSuppressions) { // not suppressed result should have empty suppressions result.Suppressions.Should().NotBeNull(); result.Suppressions.Should().BeEmpty(); } } } return(suppressedLog); }