From 9724a88536368e917620a9c0121a123097d8adb4 Mon Sep 17 00:00:00 2001 From: Justin Perez Date: Fri, 7 Jul 2023 08:52:49 -0700 Subject: [PATCH] tests: verify json schema (#638) --- Directory.Packages.props | 3 +- docs/schema/manifest.schema.json | 92 +++++++++---------- .../JsonSchemaTests.cs | 70 ++++++++++++++ ...mponentDetection.VerificationTests.csproj} | 3 +- 4 files changed, 120 insertions(+), 48 deletions(-) create mode 100644 test/Microsoft.ComponentDetection.VerificationTests/JsonSchemaTests.cs rename test/Microsoft.ComponentDetection.VerificationTests/{Microsoft.DependencyDetective.VerificationTests.csproj => Microsoft.ComponentDetection.VerificationTests.csproj} (93%) diff --git a/Directory.Packages.props b/Directory.Packages.props index 75fb2d90c..dccf14c1c 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -26,6 +26,7 @@ + @@ -48,4 +49,4 @@ - + \ No newline at end of file diff --git a/docs/schema/manifest.schema.json b/docs/schema/manifest.schema.json index d5e0f5073..95bf231cf 100644 --- a/docs/schema/manifest.schema.json +++ b/docs/schema/manifest.schema.json @@ -100,24 +100,24 @@ "null" ], "items": { - "type": "integer", + "type": "string", "enum": [ - 0, - 1, - 2, - 3, - 4, - 6, - 7, - 8, - 9, - 10, - 11, - 12, - 13, - 14, - 15, - 16 + "Other", + "NuGet", + "Npm", + "Maven", + "Git", + "RubyGems", + "Cargo", + "Pip", + "Go", + "DockerImage", + "Pod", + "Linux", + "Conda", + "Spdx", + "Vcpkg", + "DockerReference" ] } } @@ -262,16 +262,16 @@ }, "dependencyScope": { "type": [ - "integer", + "string", "null" ], "enum": [ null, - 0, - 1, - 2, - 3, - 4 + "MavenCompile", + "MavenRuntime", + "MavenProvided", + "MavenSystem", + "MavenTest" ] }, "topLevelReferrers": { @@ -326,24 +326,24 @@ ], "properties": { "type": { - "type": "integer", + "type": "string", "enum": [ - 0, - 1, - 2, - 3, - 4, - 6, - 7, - 8, - 9, - 10, - 11, - 12, - 13, - 14, - 15, - 16 + "Other", + "NuGet", + "Npm", + "Maven", + "Git", + "RubyGems", + "Cargo", + "Pip", + "Go", + "DockerImage", + "Pod", + "Linux", + "Conda", + "Spdx", + "Vcpkg", + "DockerReference" ] }, "id": { @@ -394,13 +394,13 @@ } }, "resultCode": { - "type": "integer", + "type": "string", "enum": [ - 0, - 1, - 2, - 3, - 4 + "Success", + "PartialSuccess", + "Error", + "InputError", + "TimeoutError" ] }, "sourceDirectory": { diff --git a/test/Microsoft.ComponentDetection.VerificationTests/JsonSchemaTests.cs b/test/Microsoft.ComponentDetection.VerificationTests/JsonSchemaTests.cs new file mode 100644 index 000000000..2b34d6792 --- /dev/null +++ b/test/Microsoft.ComponentDetection.VerificationTests/JsonSchemaTests.cs @@ -0,0 +1,70 @@ +namespace Microsoft.ComponentDetection.VerificationTests; + +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Threading.Tasks; +using FluentAssertions; +using Microsoft.ComponentDetection.Contracts.BcdeModels; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using Newtonsoft.Json.Linq; +using Newtonsoft.Json.Schema; +using Newtonsoft.Json.Schema.Generation; + +[TestClass] +public class JsonSchemaTests +{ + private string manifestFile; + private JSchema repoManifestSchema; + private DirectoryInfo artifactsDir; + + [TestInitialize] + public async Task InitializeAsync() + { + var docsDir = new DirectoryInfo(Path.Combine(Environment.GetEnvironmentVariable("GITHUB_WORKSPACE"), "docs", "schema")); + + this.artifactsDir = new DirectoryInfo(Environment.GetEnvironmentVariable("GITHUB_NEW_ARTIFACTS_DIR")); + this.manifestFile = await ReadFileAsync(this.artifactsDir, "ScanManifest*.json"); + this.repoManifestSchema = JSchema.Parse(await ReadFileAsync(docsDir, "manifest.schema.json")); + } + + private static async Task ReadFileAsync(DirectoryInfo dir, string pattern) + { + var files = dir.GetFiles(pattern); + files.Should().HaveCountGreaterThan(0, $"There should be at least one file matching the pattern {pattern}"); + return await File.ReadAllTextAsync(files.First().FullName); + } + + [TestMethod] + public void CheckJsonSchemaUpdated() + { + var currentSchema = CreateCurrentSchema(); + + // Write schema to output dir + var schemaFile = Path.Combine(this.artifactsDir.FullName, "manifest.schema.json"); + File.WriteAllText(schemaFile, currentSchema.ToString()); + + JToken.DeepEquals(this.repoManifestSchema, currentSchema).Should().BeTrue($"The schema in docs should be updated to match the current schema."); + } + + [TestMethod] + public void VerifyManifestConformsJsonSchema() + { + var manifest = JObject.Parse(this.manifestFile); + var valid = manifest.IsValid(this.repoManifestSchema, out IList errors); + + valid.Should().BeTrue($"The manifest generated from CD should conform to the JSON Schema in `docs/schema`. Errors: {string.Join(Environment.NewLine, errors)}"); + } + + private static JSchema CreateCurrentSchema() + { + var generator = new JSchemaGenerator(); + generator.GenerationProviders.Add(new StringEnumGenerationProvider()); + + var schema = generator.Generate(typeof(ScanResult)); + schema.ExtensionData.Add("$schema", "http://json-schema.org/draft-07/schema#"); + + return schema; + } +} diff --git a/test/Microsoft.ComponentDetection.VerificationTests/Microsoft.DependencyDetective.VerificationTests.csproj b/test/Microsoft.ComponentDetection.VerificationTests/Microsoft.ComponentDetection.VerificationTests.csproj similarity index 93% rename from test/Microsoft.ComponentDetection.VerificationTests/Microsoft.DependencyDetective.VerificationTests.csproj rename to test/Microsoft.ComponentDetection.VerificationTests/Microsoft.ComponentDetection.VerificationTests.csproj index 4e635aa46..c52db9524 100644 --- a/test/Microsoft.ComponentDetection.VerificationTests/Microsoft.DependencyDetective.VerificationTests.csproj +++ b/test/Microsoft.ComponentDetection.VerificationTests/Microsoft.ComponentDetection.VerificationTests.csproj @@ -1,4 +1,4 @@ - + true @@ -21,6 +21,7 @@ +