public void SarifLog_SplitPerRun() { var random = new Random(); SarifLog sarifLog = RandomSarifLogGenerator.GenerateSarifLogWithRuns(random, 1); sarifLog.Split(SplittingStrategy.PerRun).Should().HaveCount(1); sarifLog = RandomSarifLogGenerator.GenerateSarifLogWithRuns(random, 3); sarifLog.Split(SplittingStrategy.PerRun).Should().HaveCount(3); }
public void SarifLogResultMatcher_MatchMultipleCurrentLogsWithNoBaseline() { Random random = RandomSarifLogGenerator.GenerateRandomAndLog(this.output); SarifLog mostRecentLog = RandomSarifLogGenerator.GenerateSarifLogWithRuns(random, 1); SarifLog oldestLog = mostRecentLog.DeepClone(); string sharedPropertyName = nameof(sharedPropertyName); string currentSharedPropertyValue = Guid.NewGuid().ToString(); string uniqueToMostRecentPropertyName = nameof(uniqueToMostRecentPropertyName); string uniqueToMostRecentPropertyValue = Guid.NewGuid().ToString(); string uniqueToOldestPropertyName = nameof(uniqueToOldestPropertyName); string uniqueToOldestPropertyValue = Guid.NewGuid().ToString(); mostRecentLog.Runs[0].SetProperty(sharedPropertyName, currentSharedPropertyValue); oldestLog.Runs[0].SetProperty(sharedPropertyName, currentSharedPropertyValue); mostRecentLog.Runs[0].SetProperty(uniqueToMostRecentPropertyName, uniqueToMostRecentPropertyValue); oldestLog.Runs[0].SetProperty(uniqueToOldestPropertyName, uniqueToOldestPropertyValue); SarifLog calculatedNextBaseline = s_preserveOldestPropertyBagMatcher.Match( previousLogs: null, currentLogs: new SarifLog[] { oldestLog, mostRecentLog }).First(); calculatedNextBaseline.Runs[0].Properties.Should().NotBeNull(); calculatedNextBaseline.Runs[0].Properties.Count.Should().Be(2); string value = null; // The default property bag matching behavior is to retain the oldest property bag available. Since we have no // baseline in this test, we expect the preserved property bag to be associated with the first (i.e., oldest) // run in the currentLogs property calculatedNextBaseline.Runs[0].GetProperty(sharedPropertyName).Should().Be(currentSharedPropertyValue); calculatedNextBaseline.Runs[0].TryGetProperty(uniqueToOldestPropertyName, out value).Should().BeTrue(); calculatedNextBaseline.Runs[0].GetProperty(uniqueToOldestPropertyName).Should().Be(uniqueToOldestPropertyValue); calculatedNextBaseline.Runs[0].TryGetProperty(uniqueToMostRecentPropertyName, out value).Should().BeFalse(); calculatedNextBaseline = s_preserveMostRecentPropertyBagMatcher.Match( previousLogs: null, currentLogs: new SarifLog[] { oldestLog, mostRecentLog }).First(); calculatedNextBaseline.Runs[0].Properties.Should().NotBeNull(); calculatedNextBaseline.Runs[0].Properties.Count.Should().Be(2); calculatedNextBaseline.Runs[0].GetProperty(sharedPropertyName).Should().Be(currentSharedPropertyValue); calculatedNextBaseline.Runs[0].TryGetProperty(uniqueToMostRecentPropertyName, out value).Should().BeTrue(); calculatedNextBaseline.Runs[0].GetProperty(uniqueToMostRecentPropertyName).Should().Be(uniqueToMostRecentPropertyValue); calculatedNextBaseline.Runs[0].TryGetProperty(uniqueToOldestPropertyName, out value).Should().BeFalse(); }
public void DefaultBaseline_SameResults_AllExisting() { Random random = RandomSarifLogGenerator.GenerateRandomAndLog(this.output); Run baseline = RandomSarifLogGenerator.GenerateRandomRunWithoutDuplicateIssues(random, DefaultBaseline.ResultBaselineEquals.DefaultInstance, random.Next(100) + 5); Run next = baseline.DeepClone(); Run result = defaultBaseliner.CreateBaselinedRun(baseline, next); result.Results.Should().OnlyContain(r => r.BaselineState == BaselineState.Unchanged); result.Results.Should().HaveCount(baseline.Results.Count()); }
public void StrictBaseline_SameResults_AllExisting() { Random random = RandomSarifLogGenerator.GenerateRandomAndLog(this.output); Run baseline = RandomSarifLogGenerator.GenerateRandomRunWithoutDuplicateIssues(random, Result.ValueComparer, random.Next(100) + 5); Run next = baseline.DeepClone(); Run result = strictBaseliner.CreateBaselinedRun(baseline, next); result.Results.Should().OnlyContain(r => r.BaselineState == BaselineState.Existing); result.Results.Should().HaveCount(baseline.Results.Count()); }
public void MergeStage_SingleFile_ReturnedUnchanged(int runs) { Random random = RandomSarifLogGenerator.GenerateRandomAndLog(this.output); SarifLog log = RandomSarifLogGenerator.GenerateSarifLogWithRuns(random, runs); SarifLog processed = Merge.Fold(new List <SarifLog>() { log }); processed.ShouldBeEquivalentTo(log); }
public void SarifLogResultMatcher_BaselinesTwoSimpleSarifLogs() { Random random = RandomSarifLogGenerator.GenerateRandomAndLog(this.output); SarifLog baselineLog = RandomSarifLogGenerator.GenerateSarifLogWithRuns(random, 1); SarifLog currentLog = baselineLog.DeepClone(); baselineLog.Runs[0].InstanceGuid = Guid.NewGuid().ToString(); currentLog.Runs[0].InstanceGuid = Guid.NewGuid().ToString(); if (currentLog.Runs[0].Results.Any()) { currentLog.Runs[0].Results[0].Tags.Add("New Unused Tag"); } foreach (Result result in baselineLog.Runs[0].Results) { result.CorrelationGuid = Guid.NewGuid().ToString(); } SarifLog calculatedNextBaseline = baseliner.Match(new SarifLog[] { baselineLog }, new SarifLog[] { currentLog }).First(); calculatedNextBaseline.Runs.Should().HaveCount(1); if (currentLog.Runs[0].Results.Any()) { calculatedNextBaseline.Runs[0].Results.Should().HaveCount(currentLog.Runs[0].Results.Count + 1); calculatedNextBaseline.Runs[0].Results.Where(r => string.IsNullOrEmpty(r.CorrelationGuid)).Should().HaveCount(0); calculatedNextBaseline.Runs[0].Results.Where(r => r.BaselineState == BaselineState.Absent).Should().HaveCount(1); calculatedNextBaseline.Runs[0].Results.Where(r => r.BaselineState == BaselineState.Absent).First().TryGetProperty(SarifLogResultMatcher.ResultMatchingResultPropertyName, out Dictionary <string, string> AbsentResultProperties).Should().BeTrue(); AbsentResultProperties.Should().ContainKey("Run"); AbsentResultProperties["Run"].Should().BeEquivalentTo(baselineLog.Runs[0].InstanceGuid); if (currentLog.Runs[0].Results.Count > 1) { calculatedNextBaseline.Runs[0].Results.Where(r => r.BaselineState == BaselineState.Existing).Should().HaveCount(currentLog.Runs[0].Results.Count - 1); calculatedNextBaseline.Runs[0].Results.Where(r => r.BaselineState == BaselineState.Existing).First().TryGetProperty(SarifLogResultMatcher.ResultMatchingResultPropertyName, out Dictionary <string, string> CurrentResultProperties).Should().BeTrue(); CurrentResultProperties.Should().ContainKey("Run"); CurrentResultProperties["Run"].Should().BeEquivalentTo(currentLog.Runs[0].InstanceGuid); } calculatedNextBaseline.Runs[0].Results.Where(r => r.BaselineState == BaselineState.New).Should().HaveCount(1); calculatedNextBaseline.Runs[0].Results.Where(r => r.BaselineState == BaselineState.New).First().TryGetProperty(SarifLogResultMatcher.ResultMatchingResultPropertyName, out Dictionary <string, string> NewResultProperties).Should().BeTrue(); NewResultProperties.Should().ContainKey("Run"); NewResultProperties["Run"].Should().BeEquivalentTo(currentLog.Runs[0].InstanceGuid); } }
public void DefaultBaseline_RemovedResult_Absent() { Random random = RandomSarifLogGenerator.GenerateRandomAndLog(this.output); Run baseline = RandomSarifLogGenerator.GenerateRandomRunWithoutDuplicateIssues(random, DefaultBaseline.ResultBaselineEquals.DefaultInstance, random.Next(100) + 5); Run next = baseline.DeepClone(); next.Results.RemoveAt(0); Run result = defaultBaseliner.CreateBaselinedRun(baseline, next); result.Results.Where(r => r.BaselineState == BaselineState.Absent).Should().ContainSingle(); result.Results.Should().HaveCount(baseline.Results.Count()); }
public void DefaultBaseline_ChangedResultOnNonTrackedField_Existing() { Random random = RandomSarifLogGenerator.GenerateRandomAndLog(this.output); Run baseline = RandomSarifLogGenerator.GenerateRandomRunWithoutDuplicateIssues(random, DefaultBaseline.ResultBaselineEquals.DefaultInstance, random.Next(100) + 5); Run next = baseline.DeepClone(); next.Results[0].Message = "new message"; Run result = defaultBaseliner.CreateBaselinedRun(baseline, next); result.Results.Should().OnlyContain(r => r.BaselineState == BaselineState.Existing); result.Results.Should().HaveCount(baseline.Results.Count()); }
public void DefaultBaseline_ChangedResultOnThumbprint_AbsentAndNew() { Random random = RandomSarifLogGenerator.GenerateRandomAndLog(this.output); Run baseline = RandomSarifLogGenerator.GenerateRandomRunWithoutDuplicateIssues(random, DefaultBaseline.ResultBaselineEquals.DefaultInstance, 5); Run next = baseline.DeepClone(); next.Results[0].ToolFingerprintContribution = "New fingerprint"; Run result = defaultBaseliner.CreateBaselinedRun(baseline, next); result.Results.Where(r => r.BaselineState == BaselineState.New).Should().ContainSingle(); result.Results.Where(r => r.BaselineState == BaselineState.Absent).Should().ContainSingle(); result.Results.Should().HaveCount(baseline.Results.Count() + 1); }
public void RebaseUriVisitor_VisitRun_CorrectlyPatchesFileDictionaryKeys() { Random random = RandomSarifLogGenerator.GenerateRandomAndLog(this.output); Run oldRun = RandomSarifLogGenerator.GenerateRandomRun(random); RebaseUriVisitor rebaseUriVisitor = new RebaseUriVisitor("SRCROOT", new Uri(@"C:\src\")); Run newRun = rebaseUriVisitor.VisitRun(oldRun); newRun.Properties.Should().ContainKey(RebaseUriVisitor.BaseUriDictionaryName); newRun.Files.Keys.Where(k => k.StartsWith(@"C:\src\")).Should().BeEmpty(); }
public void RebaseUriVisitor_VisitRun_CorrectlyPatchesFileDictionaryKeys() { Random random = RandomSarifLogGenerator.GenerateRandomAndLog(this.output); Run oldRun = RandomSarifLogGenerator.GenerateRandomRun(random); RebaseUriVisitor rebaseUriVisitor = new RebaseUriVisitor("SRCROOT", new Uri(@"C:\src\")); Run newRun = rebaseUriVisitor.VisitRun(oldRun); newRun.OriginalUriBaseIds.Should().ContainKey("SRCROOT"); newRun.Artifacts.Where(f => f.Location.Uri.OriginalString.StartsWith(@"C:\src\")).Should().BeEmpty(); }
public void RebaseUriVisitor_VisitRun_DoesNotPatchFileDictionaryKeysWhenNotABaseUri() { Random random = RandomSarifLogGenerator.GenerateRandomAndLog(this.output); Run oldRun = RandomSarifLogGenerator.GenerateRandomRun(random); RebaseUriVisitor rebaseUriVisitor = new RebaseUriVisitor("SRCROOT", new Uri(@"C:\bld\")); Run newRun = rebaseUriVisitor.VisitRun(oldRun); newRun.OriginalUriBaseIds.Should().ContainKey("SRCROOT"); // Random sarif log generator uses "C:\src\" as the root. newRun.Artifacts.Should().BeEquivalentTo(oldRun.Artifacts); }
public void RebaseUriVisitor_VisitRun_AddsBaseUriDictionaryWhenNotPresent() { Random random = RandomSarifLogGenerator.GenerateRandomAndLog(this.output); Run oldRun = RandomSarifLogGenerator.GenerateRandomRun(random); RebaseUriVisitor rebaseUriVisitor = new RebaseUriVisitor("SRCROOT", new Uri(@"C:\src\root")); Run newRun = rebaseUriVisitor.VisitRun(oldRun); IDictionary <string, Uri> baseUriDictionary = newRun.OriginalUriBaseIds; baseUriDictionary.Should().ContainKey("SRCROOT"); baseUriDictionary.Should().ContainValue(new Uri(@"C:\src\root")); }
public void StrictBaseline_ChangedResult_AbsentAndNew() { Random random = RandomSarifLogGenerator.GenerateRandomAndLog(this.output); random = new Random(181968016); Run baseline = RandomSarifLogGenerator.GenerateRandomRunWithoutDuplicateIssues(random, Result.ValueComparer, random.Next(100) + 5); Run next = baseline.DeepClone(); next.Results[0].RuleId += "V2"; Run result = strictBaseliner.CreateBaselinedRun(baseline, next); result.Results.Where(r => r.BaselineState == BaselineState.New).Should().ContainSingle(); result.Results.Where(r => r.BaselineState == BaselineState.Absent).Should().ContainSingle(); result.Results.Should().HaveCount(baseline.Results.Count() + 1); }
public void RebaseUriVisitor_VisitRun_AddsBaseUriDictionaryWhenNotPresent() { Random random = RandomSarifLogGenerator.GenerateRandomAndLog(this.output); Run oldRun = RandomSarifLogGenerator.GenerateRandomRun(random); RebaseUriVisitor rebaseUriVisitor = new RebaseUriVisitor("SRCROOT", new Uri(@"C:\src\root")); Run newRun = rebaseUriVisitor.VisitRun(oldRun); newRun.Properties.Should().ContainKey(RebaseUriVisitor.BaseUriDictionaryName); Dictionary <string, Uri> baseUriDictionary = RebaseUriVisitor.DeserializePropertyDictionary(newRun.Properties[RebaseUriVisitor.BaseUriDictionaryName]); baseUriDictionary.Should().ContainKey("SRCROOT"); baseUriDictionary.Should().ContainValue(new Uri(@"C:\src\root")); }
public void TestMerge_WorksAsExpected() { Random random = RandomSarifLogGenerator.GenerateRandomAndLog(this.output); List <SarifLog> logs = new List <SarifLog>(); List <SarifLog> secondLogSet = new List <SarifLog>(); int count = random.Next(10) + 1; for (int i = 0; i < count; i++) { SarifLog log = RandomSarifLogGenerator.GenerateSarifLogWithRuns(random, random.Next(1, 10)); logs.Add(log); secondLogSet.Add(log.DeepClone()); } SarifLog combinedLog = logs.Merge(); combinedLog.Runs.Count.Should().Be(secondLogSet.Select(l => l.Runs == null ? 0 : l.Runs.Count).Sum()); }
public void SarifLogResultMatcher_BaselinesSarifLogsWithProperties() { Random random = RandomSarifLogGenerator.GenerateRandomAndLog(this.output); SarifLog baselineLog = RandomSarifLogGenerator.GenerateSarifLogWithRuns(random, 1); SarifLog currentLog = baselineLog.DeepClone(); string sharedPropertyName = nameof(sharedPropertyName); string currentSharedPropertyValue = Guid.NewGuid().ToString(); string uniqueToBaselinePropertyName = nameof(uniqueToBaselinePropertyName); string uniqueToBaselinePropertyValue = Guid.NewGuid().ToString(); string uniqueToCurrentPropertyName = nameof(uniqueToCurrentPropertyName); string uniqueToCurrentPropertyValue = Guid.NewGuid().ToString(); baselineLog.Runs[0].SetProperty(sharedPropertyName, currentSharedPropertyValue); currentLog.Runs[0].SetProperty(sharedPropertyName, currentSharedPropertyValue); baselineLog.Runs[0].SetProperty(uniqueToBaselinePropertyName, uniqueToBaselinePropertyValue); currentLog.Runs[0].SetProperty(uniqueToCurrentPropertyName, uniqueToCurrentPropertyValue); SarifLog calculatedNextBaseline = s_preserveOldestPropertyBagMatcher.Match(new SarifLog[] { baselineLog }, new SarifLog[] { currentLog }).First(); string value = null; // The default property bag matching behavior is to retain the property bag in its entirety from the baseline calculatedNextBaseline.Runs[0].Properties.Should().NotBeNull(); calculatedNextBaseline.Runs[0].Properties.Count.Should().Be(2); calculatedNextBaseline.Runs[0].GetProperty(sharedPropertyName).Should().Be(currentSharedPropertyValue); calculatedNextBaseline.Runs[0].GetProperty(uniqueToBaselinePropertyName).Should().Be(uniqueToBaselinePropertyValue); calculatedNextBaseline.Runs[0].TryGetProperty(uniqueToCurrentPropertyName, out value).Should().BeFalse(); calculatedNextBaseline = s_preserveMostRecentPropertyBagMatcher.Match(new SarifLog[] { baselineLog }, new SarifLog[] { currentLog }).First(); // The default property bag matching behavior is to retain the property bag in its entirety from the baseline calculatedNextBaseline.Runs[0].Properties.Should().NotBeNull(); calculatedNextBaseline.Runs[0].Properties.Count.Should().Be(2); calculatedNextBaseline.Runs[0].GetProperty(sharedPropertyName).Should().Be(currentSharedPropertyValue); calculatedNextBaseline.Runs[0].GetProperty(uniqueToCurrentPropertyName).Should().Be(uniqueToCurrentPropertyValue); calculatedNextBaseline.Runs[0].TryGetProperty(uniqueToBaselinePropertyName, out value).Should().BeFalse(); }
public void DefaultBaseline_NewResultAdded_New() { Random random = RandomSarifLogGenerator.GenerateRandomAndLog(this.output); Run baseline = RandomSarifLogGenerator.GenerateRandomRunWithoutDuplicateIssues(random, DefaultBaseline.ResultBaselineEquals.DefaultInstance, random.Next(100) + 5); Run next = baseline.DeepClone(); next.Results.Add(RandomSarifLogGenerator.GenerateFakeResults(random, new List <string>() { "NEWTESTRESULT" }, new List <Uri>() { new Uri(@"c:\test\testfile") }, 1).First()); Run result = defaultBaseliner.CreateBaselinedRun(baseline, next); result.Results.Where(r => r.BaselineState == BaselineState.New).Should().ContainSingle(); result.Results.Should().HaveCount(baseline.Results.Count() + 1); }
public void SarifLogResultMatcher_CurrentLogEmpty_AllAbsent() { Random random = RandomSarifLogGenerator.GenerateRandomAndLog(this.output); SarifLog baselineLog = RandomSarifLogGenerator.GenerateSarifLogWithRuns(random, 1); SarifLog currentLog = new SarifLog(); currentLog.Runs = new Run[] { new Run() }; baselineLog.Runs[0].AutomationDetails = new RunAutomationDetails { Guid = Guid.NewGuid().ToString() }; currentLog.Runs[0].AutomationDetails = new RunAutomationDetails { Guid = Guid.NewGuid().ToString() }; currentLog.Runs[0].Tool = new Tool() { Driver = new ToolComponent { Name = "Test" } }; foreach (Result result in baselineLog.Runs[0].Results) { result.CorrelationGuid = Guid.NewGuid().ToString(); } SarifLog calculatedNextBaseline = s_preserveOldestPropertyBagMatcher.Match(new SarifLog[] { baselineLog }, new SarifLog[] { currentLog }).First(); calculatedNextBaseline.Runs.Should().HaveCount(1); if (baselineLog.Runs[0].Results.Any()) { calculatedNextBaseline.Runs[0].Results.Should().HaveCount(baselineLog.Runs[0].Results.Count); calculatedNextBaseline.Runs[0].Results.Where(r => string.IsNullOrEmpty(r.CorrelationGuid)).Should().HaveCount(0); calculatedNextBaseline.Runs[0].Results.Where(r => r.BaselineState == BaselineState.Absent).Should().HaveCount(baselineLog.Runs[0].Results.Count); calculatedNextBaseline.Runs[0].Results.Where(r => r.BaselineState == BaselineState.Absent).First().TryGetProperty(SarifLogResultMatcher.ResultMatchingResultPropertyName, out Dictionary <string, string> AbsentResultProperties).Should().BeTrue(); AbsentResultProperties.Should().ContainKey("Run"); AbsentResultProperties["Run"].Should().BeEquivalentTo(baselineLog.Runs[0].AutomationDetails.Guid); } }
public void MergeStage_MultipleFiles_MergeCorrectly(int fileCount) { Random random = RandomSarifLogGenerator.GenerateRandomAndLog(this.output); List <SarifLog> logs = new List <SarifLog>(); for (int i = 0; i < fileCount; i++) { logs.Add(RandomSarifLogGenerator.GenerateSarifLogWithRuns(random, random.Next(5))); } SarifLog merged = Merge.Fold(logs); foreach (var log in logs) { if (log.Runs != null) { log.Runs.Should().BeSubsetOf(merged.Runs); } } }
public void SarifLogResultMatcher_PreservesPropertiesProperly() { Random random = RandomSarifLogGenerator.GenerateRandomAndLog(this.output); SarifLog baselineLog = RandomSarifLogGenerator.GenerateSarifLogWithRuns(random, 1); SarifLog currentLog = baselineLog.DeepClone(); string baselinePropertyValue = Guid.NewGuid().ToString(); string currentPropertyValue = Guid.NewGuid().ToString(); SetPropertyOnAllFileAndResultObjects(baselineLog, "Key", baselinePropertyValue); SetPropertyOnAllFileAndResultObjects(currentLog, "Key", currentPropertyValue); SarifLog matchedLog = s_preserveOldestPropertyBagMatcher.Match(baselineLog.DeepClone(), currentLog.DeepClone()); matchedLog.Runs[0].Results?.Where((r) => { return(r.GetProperty("Key") == baselinePropertyValue); }).Count().Should().Be(matchedLog.Runs[0].Results.Count); matchedLog.Runs[0].Artifacts?.Where((r) => { return(r.GetProperty("Key") == baselinePropertyValue); }).Count().Should().Be(matchedLog.Runs[0].Artifacts.Count); // Retain property bag values from most current run matchedLog = s_preserveMostRecentPropertyBagMatcher.Match(baselineLog.DeepClone(), currentLog.DeepClone()); matchedLog.Runs[0].Results?.Where((r) => { return(r.GetProperty("Key") == currentPropertyValue); }).Count().Should().Be(matchedLog.Runs[0].Results.Count); matchedLog.Runs[0].Artifacts?.Where((r) => { return(r.GetProperty("Key") == currentPropertyValue); }).Count().Should().Be(matchedLog.Runs[0].Artifacts.Count); }
public void SarifLogResultMatcher_PreviousLogEmpty_WorksAsExpected() { Random random = RandomSarifLogGenerator.GenerateRandomAndLog(this.output); SarifLog currentLog = RandomSarifLogGenerator.GenerateSarifLogWithRuns(random, 1); currentLog.Runs[0].AutomationDetails = new RunAutomationDetails { Guid = Guid.NewGuid().ToString() }; SarifLog calculatedNextBaseline = s_preserveOldestPropertyBagMatcher.Match(new SarifLog[0], new SarifLog[] { currentLog }).First(); calculatedNextBaseline.Runs.Should().HaveCount(1); if (currentLog.Runs[0].Results.Any()) { // We should have the same number of results. calculatedNextBaseline.Runs[0].Results.Should().HaveCount(currentLog.Runs[0].Results.Count); // They should all have correllation ids calculatedNextBaseline.Runs[0] .Results.Where(r => string.IsNullOrEmpty(r.CorrelationGuid)).Should().HaveCount(0); // They should all be new. calculatedNextBaseline.Runs[0] .Results.Where(r => r.BaselineState == BaselineState.New).Should().HaveCount(currentLog.Runs[0].Results.Count); // And they should have the correct property set. calculatedNextBaseline.Runs[0] .Results.Where(r => r.BaselineState == BaselineState.New) .First().TryGetProperty( SarifLogResultMatcher.ResultMatchingResultPropertyName, out Dictionary <string, object> NewResultProperties) .Should().BeTrue(); NewResultProperties.Should().ContainKey("Run"); NewResultProperties["Run"].Should().BeEquivalentTo(currentLog.Runs[0].AutomationDetails.Guid); } }
public void SarifLogResultMatcher_BaselinesTwoSimpleSarifLogs() { Random random = RandomSarifLogGenerator.GenerateRandomAndLog(this.output); SarifLog baselineLog = RandomSarifLogGenerator.GenerateSarifLogWithRuns(random, 1); SarifLog currentLog = baselineLog.DeepClone(); baselineLog.Runs[0].AutomationDetails = new RunAutomationDetails { Guid = Guid.NewGuid().ToString() }; currentLog.Runs[0].AutomationDetails = new RunAutomationDetails { Guid = Guid.NewGuid().ToString() }; // This code exists to force a result to diverge from the previous run. By modifying this tag, // we ensure that at least one result will be regarded as new (which implies one result // will be regarded as going absent). if (currentLog.Runs[0].Results.Any()) { currentLog.Runs[0].Results[0].Tags.Add("New Unused Tag"); } string propertyName = "WeLikePi"; float propertyValue = 3.14159F; baselineLog.Runs[0].SetProperty(propertyName, propertyValue); foreach (Result result in baselineLog.Runs[0].Results) { result.CorrelationGuid = Guid.NewGuid().ToString(); } SarifLog calculatedNextBaseline = s_preserveOldestPropertyBagMatcher.Match(new SarifLog[] { baselineLog }, new SarifLog[] { currentLog }).First(); calculatedNextBaseline.Runs.Should().HaveCount(1); calculatedNextBaseline.Runs[0].Properties.Should().NotBeNull(); calculatedNextBaseline.Runs[0].GetProperty <float>(propertyName).Should().Be(propertyValue); if (currentLog.Runs[0].Results.Any()) { calculatedNextBaseline.Runs[0].Results.Should().HaveCount(currentLog.Runs[0].Results.Count + 1); calculatedNextBaseline.Runs[0].Results.Where(r => string.IsNullOrEmpty(r.CorrelationGuid)).Should().HaveCount(0); calculatedNextBaseline.Runs[0].Results.Where(r => r.BaselineState == BaselineState.Absent).Should().HaveCount(1); calculatedNextBaseline.Runs[0].Results.Where(r => r.BaselineState == BaselineState.Absent).First().TryGetProperty(SarifLogResultMatcher.ResultMatchingResultPropertyName, out Dictionary <string, string> AbsentResultProperties).Should().BeTrue(); AbsentResultProperties.Should().ContainKey("Run"); AbsentResultProperties["Run"].Should().BeEquivalentTo(baselineLog.Runs[0].AutomationDetails.Guid); if (currentLog.Runs[0].Results.Count > 1) { calculatedNextBaseline.Runs[0].Results.Where(r => r.BaselineState == BaselineState.Unchanged).Should().HaveCount(currentLog.Runs[0].Results.Count - 1); calculatedNextBaseline.Runs[0].Results.Where(r => r.BaselineState == BaselineState.Unchanged).First().TryGetProperty(SarifLogResultMatcher.ResultMatchingResultPropertyName, out Dictionary <string, string> CurrentResultProperties).Should().BeTrue(); CurrentResultProperties.Should().ContainKey("Run"); CurrentResultProperties["Run"].Should().BeEquivalentTo(currentLog.Runs[0].AutomationDetails.Guid); } calculatedNextBaseline.Runs[0].Results.Where(r => r.BaselineState == BaselineState.New).Should().HaveCount(1); calculatedNextBaseline.Runs[0].Results.Where(r => r.BaselineState == BaselineState.New).First().TryGetProperty(SarifLogResultMatcher.ResultMatchingResultPropertyName, out Dictionary <string, string> NewResultProperties).Should().BeTrue(); NewResultProperties.Should().ContainKey("Run"); NewResultProperties["Run"].Should().BeEquivalentTo(currentLog.Runs[0].AutomationDetails.Guid); } }