Example #1
0
        public int Run(RewriteOptions options)
        {
            try
            {
                Console.WriteLine($"Rewriting '{options.InputFilePath}' => '{options.OutputFilePath}'...");
                Stopwatch w = Stopwatch.StartNew();

                bool valid = ValidateOptions(options);
                if (!valid)
                {
                    return(FAILURE);
                }

                string actualOutputPath = CommandUtilities.GetTransformedOutputFileName(options);

                SarifLog actualLog = null;

                string inputVersion = SniffVersion(options.InputFilePath);
                if (!inputVersion.Equals(SarifUtilities.StableSarifVersion))
                {
                    actualLog = TransformFileToVersionTwo(options.InputFilePath, inputVersion);
                }
                else
                {
                    actualLog = ReadSarifFile <SarifLog>(_fileSystem, options.InputFilePath);
                }

                OptionallyEmittedData dataToInsert = options.DataToInsert.ToFlags();
                OptionallyEmittedData dataToRemove = options.DataToRemove.ToFlags();
                IDictionary <string, ArtifactLocation> originalUriBaseIds = options.ConstructUriBaseIdsDictionary();

                SarifLog reformattedLog = new RemoveOptionalDataVisitor(dataToRemove).VisitSarifLog(actualLog);
                reformattedLog = new InsertOptionalDataVisitor(dataToInsert, originalUriBaseIds).VisitSarifLog(reformattedLog);

                if (options.SarifOutputVersion == SarifVersion.OneZeroZero)
                {
                    var visitor = new SarifCurrentToVersionOneVisitor();
                    visitor.VisitSarifLog(reformattedLog);

                    WriteSarifFile(_fileSystem, visitor.SarifLogVersionOne, actualOutputPath, options.Minify, SarifContractResolverVersionOne.Instance);
                }
                else
                {
                    WriteSarifFile(_fileSystem, reformattedLog, actualOutputPath, options.Minify);
                }

                w.Stop();
                Console.WriteLine($"Rewrite completed in {w.Elapsed}.");
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex);
                return(FAILURE);
            }

            return(SUCCESS);
        }
Example #2
0
        public int Run(RewriteOptions rewriteOptions)
        {
            try
            {
                Console.WriteLine($"Rewriting '{rewriteOptions.InputFilePath}' => '{rewriteOptions.OutputFilePath}'...");
                Stopwatch w = Stopwatch.StartNew();

                bool valid = ValidateOptions(rewriteOptions);
                if (!valid)
                {
                    return(FAILURE);
                }

                SarifLog actualLog = ReadSarifFile <SarifLog>(_fileSystem, rewriteOptions.InputFilePath);

                OptionallyEmittedData dataToInsert = rewriteOptions.DataToInsert.ToFlags();
                OptionallyEmittedData dataToRemove = rewriteOptions.DataToRemove.ToFlags();
                IDictionary <string, ArtifactLocation> originalUriBaseIds = rewriteOptions.ConstructUriBaseIdsDictionary();

                SarifLog reformattedLog = new RemoveOptionalDataVisitor(dataToRemove).VisitSarifLog(actualLog);
                reformattedLog = new InsertOptionalDataVisitor(dataToInsert, originalUriBaseIds).VisitSarifLog(reformattedLog);

                string fileName = CommandUtilities.GetTransformedOutputFileName(rewriteOptions);

                WriteSarifFile(_fileSystem, reformattedLog, fileName, rewriteOptions.Formatting);

                w.Stop();
                Console.WriteLine($"Rewrite completed in {w.Elapsed}.");
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex);
                return(FAILURE);
            }

            return(SUCCESS);
        }
Example #3
0
        public int Run(FileWorkItemsOptions options, IFileSystem fileSystem)
        {
            if (!ValidateOptions(options, fileSystem))
            {
                return(FAILURE);
            }

            // For unit tests: allow us to just validate the options and return.
            if (s_validateOptionsOnly)
            {
                return(SUCCESS);
            }

            string projectName = options.ProjectUri.GetProjectName();

            string logFileContents = fileSystem.ReadAllText(options.InputFilePath);

            EnsureValidSarifLogFile(logFileContents, options.InputFilePath);

            FilingTarget filingTarget = FilingTargetFactory.CreateFilingTarget(options.ProjectUriString);
            var          filer        = new WorkItemFiler(filingTarget);

            SarifLog sarifLog = JsonConvert.DeserializeObject <SarifLog>(logFileContents);

            if (options.DataToRemove != null)
            {
                var dataRemovingVisitor = new RemoveOptionalDataVisitor(options.DataToRemove.ToFlags());
                dataRemovingVisitor.Visit(sarifLog);
            }

            for (int runIndex = 0; runIndex < sarifLog.Runs.Count; ++runIndex)
            {
                if (sarifLog.Runs[runIndex]?.Results?.Count > 0)
                {
                    IList <SarifLog> logsToProcess = new List <SarifLog>(new SarifLog[] { sarifLog });

                    if (options.GroupingStrategy != GroupingStrategy.PerRun)
                    {
                        SplittingVisitor visitor = (options.GroupingStrategy == GroupingStrategy.PerRunPerRule
                            ? (SplittingVisitor) new PerRunPerRuleSplittingVisitor()
                            : new PerRunPerTargetPerRuleSplittingVisitor());

                        visitor.VisitRun(sarifLog.Runs[runIndex]);
                        logsToProcess = visitor.SplitSarifLogs;
                    }

                    IList <WorkItemFilingMetadata> workItemMetadata = new List <WorkItemFilingMetadata>(logsToProcess.Count);

                    for (int splitFileIndex = 0; splitFileIndex < logsToProcess.Count; splitFileIndex++)
                    {
                        SarifLog splitLog = logsToProcess[splitFileIndex];
                        workItemMetadata.Add(splitLog.CreateWorkItemFilingMetadata(projectName, options.TemplateFilePath));
                    }

                    try
                    {
                        IEnumerable <WorkItemFilingMetadata> filedWorkItems = filer.FileWorkItems(options.ProjectUri, workItemMetadata, options.PersonalAccessToken).Result;

                        Console.WriteLine($"Created {filedWorkItems.Count()} work items for run {runIndex}.");
                    }
                    catch (Exception ex)
                    {
                        Console.Error.WriteLine(ex);
                    }
                }
            }

            Console.WriteLine($"Writing log with work item Ids to {options.OutputFilePath}.");
            WriteSarifFile <SarifLog>(fileSystem, sarifLog, options.OutputFilePath, (options.PrettyPrint ? Formatting.Indented : Formatting.None));

            return(SUCCESS);
        }
Example #4
0
        protected override string ConstructTestOutputFromInputResource(string inputResourceName, object parameter)
        {
            string v2LogText = GetResourceText(inputResourceName);

            string inputLogDirectory = this.OutputFolderPath;
            string inputLogFileName  = Path.GetFileName(inputResourceName);
            string inputLogFilePath  = Path.Combine(this.OutputFolderPath, inputLogFileName);

            string actualLogFilePath = Guid.NewGuid().ToString();

            string ruleUnderTest = Path.GetFileNameWithoutExtension(inputLogFilePath).Split('.')[1];

            // All SARIF rule prefixes require update to current release.
            // All rules with JSON prefix are low level syntax/deserialization checks.
            // We can't transform these test inputs as that operation fixes up erros in the file.
            bool updateInputsToCurrentSarif = ruleUnderTest.StartsWith("SARIF") ? true : false;

            var validateOptions = new ValidateOptions
            {
                SarifOutputVersion   = SarifVersion.Current,
                TargetFileSpecifiers = new[] { inputLogFilePath },
                OutputFilePath       = actualLogFilePath,
                Quiet = true,
                UpdateInputsToCurrentSarif = updateInputsToCurrentSarif,
                PrettyPrint = true,
                Optimize    = true
            };

            var mockFileSystem = new Mock <IFileSystem>();

            mockFileSystem.Setup(x => x.DirectoryExists(inputLogDirectory)).Returns(true);
            mockFileSystem.Setup(x => x.GetDirectoriesInDirectory(It.IsAny <string>())).Returns(new string[0]);
            mockFileSystem.Setup(x => x.GetFilesInDirectory(inputLogDirectory, inputLogFileName)).Returns(new string[] { inputLogFilePath });
            mockFileSystem.Setup(x => x.ReadAllText(inputLogFilePath)).Returns(v2LogText);
            mockFileSystem.Setup(x => x.ReadAllText(It.IsNotIn <string>(inputLogFilePath))).Returns <string>(path => File.ReadAllText(path));
            mockFileSystem.Setup(x => x.WriteAllText(It.IsAny <string>(), It.IsAny <string>()));

            var validateCommand = new ValidateCommand(mockFileSystem.Object);

            int returnCode = validateCommand.Run(validateOptions);

            if (validateCommand.ExecutionException != null)
            {
                Console.WriteLine(validateCommand.ExecutionException.ToString());
            }

            returnCode.Should().Be(0);

            SarifLog actualLog = JsonConvert.DeserializeObject <SarifLog>(File.ReadAllText(actualLogFilePath));

            // First, we'll strip any validation results that don't originate with the rule under test
            var newResults = new List <Result>();

            foreach (Result result in actualLog.Runs[0].Results)
            {
                if (result.RuleId == ruleUnderTest)
                {
                    newResults.Add(result);
                }
            }

            // Next, we'll remove non-deterministic information, most notably, timestamps emitted for the invocation data.
            var removeTimestampsVisitor = new RemoveOptionalDataVisitor(OptionallyEmittedData.NondeterministicProperties);

            removeTimestampsVisitor.Visit(actualLog);

            // Finally, we'll elide non-deterministic build root details
            var rebaseUrisVisitor = new RebaseUriVisitor("TEST_DIR", new Uri(inputLogDirectory));

            rebaseUrisVisitor.Visit(actualLog);

            // There are differences in log file output depending on whether we are invoking xunit
            // from within Visual Studio or at the command-line via xunit.exe. We elide these differences.

            ToolComponent driver = actualLog.Runs[0].Tool.Driver;

            driver.Name                  = "SARIF Functional Testing";
            driver.Version               = null;
            driver.FullName              = null;
            driver.SemanticVersion       = null;
            driver.DottedQuadFileVersion = null;
            driver.Product               = null;
            driver.Organization          = null;
            driver.Properties?.Clear();
            actualLog.Runs[0].OriginalUriBaseIds = null;

            return(JsonConvert.SerializeObject(actualLog, Formatting.Indented));
        }
Example #5
0
        protected override string ConstructTestOutputFromInputResource(string inputResourceName, object parameter)
        {
            string v2LogText = GetResourceText(inputResourceName);

            string inputLogDirectory = this.OutputFolderPath;
            string inputLogFileName  = Path.GetFileName(inputResourceName);
            string inputLogFilePath  = Path.Combine(this.OutputFolderPath, inputLogFileName);

            string actualLogFilePath = Guid.NewGuid().ToString();

            string ruleUnderTest = Path.GetFileNameWithoutExtension(inputLogFilePath).Split('.')[1];

            // All SARIF rule prefixes require update to current release.
            // All rules with JSON prefix are low level syntax/deserialization checks.
            // We can't transform these test inputs as that operation fixes up errors in the file.
            // Also, don't transform the tests for SARIF1011 or SARIF2008, because these rules
            // examine the actual contents of the $schema property.

            string[] shouldNotTransform = { "SARIF1011", "SARIF2008" };

            bool updateInputsToCurrentSarif = IsSarifRule(ruleUnderTest) &&
                                              !shouldNotTransform.Contains(ruleUnderTest);

            var validateOptions = new ValidateOptions
            {
                SarifOutputVersion   = SarifVersion.Current,
                TargetFileSpecifiers = new[] { inputLogFilePath },
                OutputFilePath       = actualLogFilePath,
                Quiet = true,
                UpdateInputsToCurrentSarif = updateInputsToCurrentSarif,
                PrettyPrint = true,
                Optimize    = true,
                Kind        = new List <ResultKind> {
                    ResultKind.Fail
                },
                Level = new List <FailureLevel> {
                    FailureLevel.Error, FailureLevel.Warning, FailureLevel.Note, FailureLevel.None
                },
            };

            var mockFileSystem = new Mock <IFileSystem>();

            mockFileSystem.Setup(x => x.DirectoryExists(inputLogDirectory)).Returns(true);
            mockFileSystem.Setup(x => x.DirectoryGetDirectories(It.IsAny <string>())).Returns(new string[0]);
            mockFileSystem.Setup(x => x.DirectoryGetFiles(inputLogDirectory, inputLogFileName)).Returns(new string[] { inputLogFilePath });
            mockFileSystem.Setup(x => x.FileReadAllText(inputLogFilePath)).Returns(v2LogText);
            mockFileSystem.Setup(x => x.FileReadAllText(It.IsNotIn <string>(inputLogFilePath))).Returns <string>(path => File.ReadAllText(path));
            mockFileSystem.Setup(x => x.FileWriteAllText(It.IsAny <string>(), It.IsAny <string>()));

            // Some rules are disabled by default, so create a configuration file that explicitly
            // enables the rule under test.
            using (TempFile configFile = CreateTempConfigFile(ruleUnderTest, parameter))
            {
                validateOptions.ConfigurationFilePath = configFile.Name;
                mockFileSystem.Setup(x => x.FileExists(validateOptions.ConfigurationFilePath)).Returns(true);

                var validateCommand = new ValidateCommand(mockFileSystem.Object);

                int returnCode = validateCommand.Run(validateOptions);

                if (validateCommand.ExecutionException != null)
                {
                    Console.WriteLine(validateCommand.ExecutionException.ToString());
                }

                returnCode.Should().Be(0);
            }

            string   actualLogFileContents = File.ReadAllText(actualLogFilePath);
            SarifLog actualLog             = JsonConvert.DeserializeObject <SarifLog>(actualLogFileContents);
            Run      run = actualLog.Runs[0];

            // First, we'll strip any validation results that don't originate with the rule under test.
            // But leave the results that originate from JSchema! Also, be careful because output files
            // from "valid" test cases don't have any results.
            run.Results = run.Results
                          ?.Where(r => IsRelevant(r.RuleId, ruleUnderTest))
                          ?.ToList();

            // Next, remove any rule metadata for those rules. The output files from "valid" test
            // cases don't have any rules.
            run.Tool.Driver.Rules = run.Tool.Driver.Rules
                                    ?.Where(r => IsRelevant(r.Id, ruleUnderTest))
                                    ?.ToList();

            // Since there's only one rule in the metadata, the ruleIndex for all remaining results
            // must be 0.
            foreach (Result result in run.Results)
            {
                result.RuleIndex = 0;
            }

            // Next, we'll remove non-deterministic information, most notably, timestamps emitted for the invocation data.
            var removeTimestampsVisitor = new RemoveOptionalDataVisitor(OptionallyEmittedData.NondeterministicProperties);

            removeTimestampsVisitor.Visit(actualLog);

            // Finally, we'll elide non-deterministic build root details
            var rebaseUrisVisitor = new RebaseUriVisitor("TEST_DIR", new Uri(inputLogDirectory));

            rebaseUrisVisitor.Visit(actualLog);

            // There are differences in log file output depending on whether we are invoking xunit
            // from within Visual Studio or at the command-line via xunit.exe. We elide these differences.

            ToolComponent driver = actualLog.Runs[0].Tool.Driver;

            driver.Name                  = "SARIF Functional Testing";
            driver.Version               = null;
            driver.FullName              = null;
            driver.SemanticVersion       = null;
            driver.DottedQuadFileVersion = null;
            driver.Product               = null;
            driver.Organization          = null;
            driver.Properties?.Clear();
            actualLog.Runs[0].OriginalUriBaseIds = null;

            return(JsonConvert.SerializeObject(actualLog, Formatting.Indented));
        }
        public virtual void FileWorkItems(SarifLog sarifLog)
        {
            sarifLog = sarifLog ?? throw new ArgumentNullException(nameof(sarifLog));

            this.FilingClient.Connect(this.FilingContext.PersonalAccessToken).Wait();

            OptionallyEmittedData optionallyEmittedData = this.FilingContext.DataToRemove;

            if (optionallyEmittedData != OptionallyEmittedData.None)
            {
                var dataRemovingVisitor = new RemoveOptionalDataVisitor(optionallyEmittedData);
                dataRemovingVisitor.Visit(sarifLog);
            }

            optionallyEmittedData = this.FilingContext.DataToInsert;
            if (optionallyEmittedData != OptionallyEmittedData.None)
            {
                var dataInsertingVisitor = new InsertOptionalDataVisitor(optionallyEmittedData);
                dataInsertingVisitor.Visit(sarifLog);
            }

            SplittingStrategy splittingStrategy = this.FilingContext.SplittingStrategy;

            if (splittingStrategy == SplittingStrategy.None)
            {
                FileWorkItemsHelper(sarifLog, this.FilingContext, this.FilingClient);
                return;
            }

            for (int runIndex = 0; runIndex < sarifLog.Runs?.Count; ++runIndex)
            {
                if (sarifLog.Runs[runIndex]?.Results?.Count > 0)
                {
                    IList <SarifLog> logsToProcess = new List <SarifLog>(new SarifLog[] { sarifLog });

                    if (splittingStrategy != SplittingStrategy.PerRun)
                    {
                        SplittingVisitor visitor;
                        switch (splittingStrategy)
                        {
                        case SplittingStrategy.PerRunPerRule:
                            visitor = new PerRunPerRuleSplittingVisitor();
                            break;

                        case SplittingStrategy.PerRunPerTarget:
                            visitor = new PerRunPerTargetSplittingVisitor();
                            break;

                        case SplittingStrategy.PerRunPerTargetPerRule:
                            visitor = new PerRunPerTargetPerRuleSplittingVisitor();
                            break;

                        // TODO: Implement PerResult and PerRun splittings strategies
                        //
                        //       https://github.com/microsoft/sarif-sdk/issues/1763
                        //       https://github.com/microsoft/sarif-sdk/issues/1762
                        //
                        case SplittingStrategy.PerResult:
                        case SplittingStrategy.PerRun:
                        default:
                            throw new ArgumentOutOfRangeException($"SplittingStrategy: {splittingStrategy}");
                        }

                        visitor.VisitRun(sarifLog.Runs[runIndex]);
                        logsToProcess = visitor.SplitSarifLogs;
                    }

                    for (int splitFileIndex = 0; splitFileIndex < logsToProcess.Count; splitFileIndex++)
                    {
                        SarifLog splitLog = logsToProcess[splitFileIndex];
                        FileWorkItemsHelper(splitLog, this.FilingContext, this.FilingClient);
                    }
                }
            }
        }
Example #7
0
        public virtual IReadOnlyList <SarifLog> SplitLogFile(SarifLog sarifLog)
        {
            IList <SarifLog> logsToProcess;

            using (Logger.BeginScopeContext(nameof(SplitLogFile)))
            {
                sarifLog = sarifLog ?? throw new ArgumentNullException(nameof(sarifLog));
                sarifLog.SetProperty("guid", Guid.NewGuid());

                this.FilingResult   = FilingResult.None;
                this.FiledWorkItems = new List <WorkItemModel>();

                sarifLog = sarifLog ?? throw new ArgumentNullException(nameof(sarifLog));

                Logger.LogInformation("Connecting to filing client: {accountOrOrganization}", this.FilingClient.AccountOrOrganization);
                this.FilingClient.Connect(this.FilingContext.PersonalAccessToken).Wait();

                OptionallyEmittedData optionallyEmittedData = this.FilingContext.DataToRemove;
                if (optionallyEmittedData != OptionallyEmittedData.None)
                {
                    Logger.LogDebug("Removing optional data.");
                    var dataRemovingVisitor = new RemoveOptionalDataVisitor(optionallyEmittedData);
                    dataRemovingVisitor.Visit(sarifLog);
                }

                optionallyEmittedData = this.FilingContext.DataToInsert;
                if (optionallyEmittedData != OptionallyEmittedData.None)
                {
                    Logger.LogDebug("Inserting optional data.");
                    var dataInsertingVisitor = new InsertOptionalDataVisitor(optionallyEmittedData);
                    dataInsertingVisitor.Visit(sarifLog);
                }

                using (Logger.BeginScopeContext("Splitting visitor"))
                {
                    SplittingStrategy splittingStrategy = this.FilingContext.SplittingStrategy;

                    Logger.LogInformation($"Splitting strategy - {splittingStrategy}");

                    if (splittingStrategy == SplittingStrategy.None)
                    {
                        return(new[] { sarifLog });
                    }

                    PartitionFunction <string> partitionFunction = null;

                    Stopwatch splittingStopwatch = Stopwatch.StartNew();

                    switch (splittingStrategy)
                    {
                    case SplittingStrategy.PerRun:
                    {
                        partitionFunction = (result) => result.ShouldBeFiled() ? "Include" : null;
                        break;
                    }

                    case SplittingStrategy.PerResult:
                    {
                        partitionFunction = (result) => result.ShouldBeFiled() ? Guid.NewGuid().ToString() : null;
                        break;
                    }

                    case SplittingStrategy.PerRunPerOrgPerEntityTypePerPartialFingerprint:
                    {
                        partitionFunction = (result) => result.ShouldBeFiled() ? result.GetFingerprintSplittingStrategyId() : null;
                        break;
                    }

                    case SplittingStrategy.PerRunPerOrgPerEntityTypePerRepositoryPerPartialFingerprint:
                    {
                        partitionFunction = (result) => result.ShouldBeFiled() ? result.GetPerRepositoryFingerprintSplittingStrategyId() : null;
                        break;
                    }

                    default:
                    {
                        throw new ArgumentOutOfRangeException($"SplittingStrategy: {splittingStrategy}");
                    }
                    }

                    Logger.LogDebug("Begin splitting logs");
                    var partitioningVisitor = new PartitioningVisitor <string>(partitionFunction, deepClone: false);
                    partitioningVisitor.VisitSarifLog(sarifLog);

                    Logger.LogDebug("Begin retrieving split logs");
                    logsToProcess = new List <SarifLog>(partitioningVisitor.GetPartitionLogs().Values);

                    Logger.LogDebug("End retrieving split logs");

                    var logsToProcessMetrics = new Dictionary <string, object>
                    {
                        { "splittingStrategy", splittingStrategy },
                        { "logsToProcessCount", logsToProcess.Count },
                        { "splittingDurationInMilliseconds", splittingStopwatch.ElapsedMilliseconds },
                    };

                    this.Logger.LogMetrics(EventIds.LogsToProcessMetrics, logsToProcessMetrics);
                    splittingStopwatch.Stop();
                }
            }

            if (logsToProcess != null && !this.FilingContext.ShouldFileUnchanged)
            {
                // Remove any logs that do not contain at least one result with a New or None baselinestate.
                logsToProcess = logsToProcess.Where(log => log?.Runs?.Any(run => run.Results?.Any(result => result.BaselineState == BaselineState.New || result.BaselineState == BaselineState.None) == true) == true).ToList();
            }

            return(logsToProcess.ToArray());
        }
Example #8
0
        public virtual SarifLog FileWorkItems(SarifLog sarifLog)
        {
            sarifLog = sarifLog ?? throw new ArgumentNullException(nameof(sarifLog));

            sarifLog.SetProperty("guid", Guid.NewGuid());

            using (Logger.BeginScope(nameof(FileWorkItems)))
            {
                this.FilingResult = FilingResult.None;
                this.FiledWorkItems = new List<WorkItemModel>();

                sarifLog = sarifLog ?? throw new ArgumentNullException(nameof(sarifLog));

                Logger.LogInformation("Connecting to filing client: {accountOrOrganization}", this.FilingClient.AccountOrOrganization);
                this.FilingClient.Connect(this.FilingContext.PersonalAccessToken).Wait();

                OptionallyEmittedData optionallyEmittedData = this.FilingContext.DataToRemove;
                if (optionallyEmittedData != OptionallyEmittedData.None)
                {
                    var dataRemovingVisitor = new RemoveOptionalDataVisitor(optionallyEmittedData);
                    dataRemovingVisitor.Visit(sarifLog);
                }

                optionallyEmittedData = this.FilingContext.DataToInsert;
                if (optionallyEmittedData != OptionallyEmittedData.None)
                {
                    var dataInsertingVisitor = new InsertOptionalDataVisitor(optionallyEmittedData);
                    dataInsertingVisitor.Visit(sarifLog);
                }

                SplittingStrategy splittingStrategy = this.FilingContext.SplittingStrategy;

                if (splittingStrategy == SplittingStrategy.None)
                {
                    FileWorkItemsHelper(sarifLog, this.FilingContext, this.FilingClient);
                    return sarifLog;
                }

                IList<SarifLog> logsToProcess;

                PartitionFunction<string> partitionFunction = null;

                Stopwatch splittingStopwatch = Stopwatch.StartNew();
                
                switch (splittingStrategy)
                {
                    case SplittingStrategy.PerRun:
                    {
                        partitionFunction = (result) => result.ShouldBeFiled() ? "Include" : null;
                        break;
                    }
                    case SplittingStrategy.PerResult:
                    {
                        partitionFunction = (result) => result.ShouldBeFiled() ? Guid.NewGuid().ToString() : null;
                        break;
                    }
                    default:
                    {
                        throw new ArgumentOutOfRangeException($"SplittingStrategy: {splittingStrategy}");
                    }
                }

                var partitioningVisitor = new PartitioningVisitor<string>(partitionFunction, deepClone: false);
                partitioningVisitor.VisitSarifLog(sarifLog);

                logsToProcess = new List<SarifLog>(partitioningVisitor.GetPartitionLogs().Values);

                var logsToProcessMetrics = new Dictionary<string, object>
                {
                    { "splittingStrategy", splittingStrategy },
                    { "logsToProcessCount", logsToProcess.Count },
                    { "splittingDurationInMilliseconds", splittingStopwatch.ElapsedMilliseconds },
                };

                this.Logger.LogMetrics(EventIds.LogsToProcessMetrics, logsToProcessMetrics);
                splittingStopwatch.Stop();

                for (int splitFileIndex = 0; splitFileIndex < logsToProcess.Count; splitFileIndex++)
                {
                    SarifLog splitLog = logsToProcess[splitFileIndex];
                    FileWorkItemsHelper(splitLog, this.FilingContext, this.FilingClient);
                }
            }

            return sarifLog;
        }