public void ValidateCommand_AcceptsTargetFileWithSpaceInName() { // A minimal valid log file. string LogFileContents = @"{ ""$schema"": """ + SarifUtilities.SarifSchemaUri + @""", ""version"": ""2.0.0"", ""runs"": [ { ""tool"": { ""name"": ""TestTool"" }, ""results"": [] } ] }"; // A simple schema against which the log file successfully validates. // This way, we don't have to read the SARIF schema from disk to run this test. const string SchemaFileContents = @"{ ""$schema"": ""http://json-schema.org/draft-04/schema#"", ""type"": ""object"" }"; // Here's the space: const string LogFileDirectory = @"c:\Users\John Smith\logs"; const string LogFileName = "example.sarif"; string logFilePath = Path.Combine(LogFileDirectory, LogFileName); const string SchemaFilePath = @"c:\schemas\SimpleSchemaForTest.json"; var mockFileSystem = new Mock <IFileSystem>(); mockFileSystem.Setup(x => x.DirectoryExists(LogFileDirectory)).Returns(true); mockFileSystem.Setup(x => x.GetDirectoriesInDirectory(It.IsAny <string>())).Returns(new string[0]); mockFileSystem.Setup(x => x.GetFilesInDirectory(LogFileDirectory, LogFileName)).Returns(new string[] { logFilePath }); mockFileSystem.Setup(x => x.ReadAllText(logFilePath)).Returns(LogFileContents); mockFileSystem.Setup(x => x.ReadAllText(SchemaFilePath)).Returns(SchemaFileContents); var validateCommand = new ValidateCommand(mockFileSystem.Object); var options = new ValidateOptions { SchemaFilePath = SchemaFilePath, TargetFileSpecifiers = new string[] { logFilePath } }; int returnCode = validateCommand.Run(options); returnCode.Should().Be(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)); }
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 = ruleUnderTest.StartsWith("SARIF") && !shouldNotTransform.Contains(ruleUnderTest); var validateOptions = new ValidateOptions { SarifOutputVersion = SarifVersion.Current, TargetFileSpecifiers = new[] { inputLogFilePath }, OutputFilePath = actualLogFilePath, Quiet = true, UpdateInputsToCurrentSarif = updateInputsToCurrentSarif, PrettyPrint = true, Optimize = true, Verbose = true // Turn on note-level rules. }; 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>())); 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)); }