// TODO: Make the core baselining algorithm support BaselineFilteringMode.ToIncludedArtifacts private static SarifLog Baseline(SarifLog baselineLog, SarifLog currentLog) { // Baseline the complete log ISarifLogMatcher matcher = ResultMatchingBaselinerFactory.GetDefaultResultMatchingBaseliner(); SarifLog outputLog = matcher.Match(new[] { baselineLog }, new[] { currentLog }).First(); // Is this an incremental scan? BaselineFilteringMode filteringMode = currentLog.GetBaselineFilteringMode(); // Mark all Results which are NOT in the new run as 'Unchanged' if (filteringMode == BaselineFilteringMode.ToIncludedArtifacts) { HashSet <string> includedArtifacts = new HashSet <string>(currentLog.AllResultArtifactUris().Select(uri => uri.OriginalString)); foreach (Result result in outputLog.EnumerateResults()) { if (!ContainsUriInSet(result, includedArtifacts)) { result.BaselineState = BaselineState.Unchanged; } } } // Ensure the Baseline is sorted for fast future baselining SortForBaselining(outputLog); return(outputLog); }
public void AddLog(SarifLog currentLog) { foreach (Result result in currentLog.EnumerateResults()) { DetailByGuid[result.Guid] = Details(result); } }
public BaseliningSummary RunSeries(string seriesPath, string reportingName, int debugLogIndex = -1, int debugResultIndex = -1) { string outputLogPath = Path.ChangeExtension(seriesPath.Replace($"\\{InputFolderName}\\", $"\\{OutputFolderName}\\"), ".log"); BaseliningSummary seriesSummary = new BaseliningSummary(Path.GetFileName(seriesPath)); Directory.CreateDirectory(Path.GetDirectoryName(outputLogPath)); using (Stream outputStream = File.Create(outputLogPath)) using (BaseliningDetailLogger logger = new BaseliningDetailLogger(seriesPath, outputStream)) { // Load the original baseline SarifLog baseline = LoadBaseline(seriesPath); // Baseline each log in order foreach (LogInSeries current in LoadSeriesLogs(seriesPath)) { if (debugLogIndex == current.LogIndex && Debugger.IsAttached) { Debugger.Break(); DebugResultComparison(baseline, current.Log, $"{debugLogIndex:d3} {debugResultIndex:d3}"); } SarifLog newBaseline = Baseline(baseline, current.Log); if (debugLogIndex == current.LogIndex) { List <Result> absentResults = newBaseline.EnumerateResults().Where((r) => r.BaselineState == BaselineState.Absent).ToList(); List <Result> newResults = newBaseline.EnumerateResults().Where((r) => r.BaselineState == BaselineState.New).ToList(); } BaseliningSummary fileSummary = new BaseliningSummary(Path.GetFileNameWithoutExtension(current.FilePath)); fileSummary.Add(newBaseline, baseline, current.Log); seriesSummary.AddCounts(fileSummary); logger.Write(newBaseline, baseline, fileSummary); baseline = newBaseline; } } EnrichSeries(seriesPath); string comparisonResult = CompareToExpected(outputLogPath); Console.WriteLine($" - {comparisonResult}{seriesSummary.ToString(reportingName)}"); return(seriesSummary); }
public static void AssignResultRIDs(SarifLog log, int logIndex) { // RIDs are ascending integers in sorted-for-baselining order SortForBaselining(log); // Set as the GUID and clear the CorrelationGuid so that // the RID for both matched Results can be found after baselining int resultIndex = 0; foreach (Result result in log.EnumerateResults()) { result.Guid = $"{logIndex:d3} {resultIndex:d3}"; result.CorrelationGuid = null; resultIndex++; } }
public void Write(SarifLog newBaselineLog, SarifLog baselineLog, BaseliningSummary summary) { Dictionary <string, Result> baselineResultsByGuid = new Dictionary <string, Result>(); foreach (Result result in baselineLog.EnumerateResults()) { baselineResultsByGuid[result.CorrelationGuid ?? result.Guid] = result; } Writer.WriteLine(); Writer.WriteLine($" {summary}"); foreach (Result result in newBaselineLog.EnumerateResults()) { switch (result.BaselineState) { case BaselineState.Absent: Write('-', result.Guid); break; case BaselineState.New: Write('+', result.Guid); break; case BaselineState.Unchanged: case BaselineState.Updated: // Find and write old Result from previous Baseline (to get pre-merged properties) Result previousResult = null; baselineResultsByGuid.TryGetValue(result.CorrelationGuid, out previousResult); if (previousResult == null) { // Write '?' for the Previous if we couldn't look it up Write('=', result.Guid); Write('?', result.CorrelationGuid); } else if (result.Guid != previousResult.Guid) { // Only Log Unchanged results from the latest log (with a new Guid) Write('=', result.Guid); Write(' ', previousResult.Guid); } break; } } }
public void Add(SarifLog newBaselineLog, SarifLog baselineLog, SarifLog currentLog) { Dictionary <string, ResultCounts> newAndRemovedPerUri = new Dictionary <string, ResultCounts>(); foreach (Result result in newBaselineLog.EnumerateResults()) { // Track New+Absent results per distinct first Result Uri Uri first = result.AllArtifactUris().FirstOrDefault(); ResultCounts counts = null; if (!newAndRemovedPerUri.TryGetValue(first?.OriginalString ?? "", out counts)) { counts = new ResultCounts(); newAndRemovedPerUri[first.OriginalString] = counts; } counts.Add(result); } ChurnCount += newAndRemovedPerUri.Values.Sum(counts => counts.ChurnCount); NewResultTotal += newAndRemovedPerUri.Values.Sum(counts => counts.NewCount); ResultCount += currentLog.EnumerateResults().Count(); }
public static Result FindByGuid(this SarifLog log, string guid) { return(log.EnumerateResults().Where(result => result.CorrelationGuid == guid || result.Guid == guid).FirstOrDefault()); }