From 4ea132b3153553e2e6e0a5e2dc53c00ea1f74a2b Mon Sep 17 00:00:00 2001 From: Dave Tryon <45672944+DaveTryon@users.noreply.github.com> Date: Tue, 7 Jan 2025 11:49:47 -0800 Subject: [PATCH] Strip tests to just Targets E2E --- Microsoft.Sbom.sln | 42 -- ...onentDetectionToSBOMPackageAdapterTests.cs | 307 ---------- .../Microsoft.Sbom.Adapters.Tests.csproj | 23 - .../ApiConfigurationBuilderTests.cs | 193 ------ .../Config/ConfigSanitizerTests.cs | 397 ------------ .../Config/ConfigurationBuilderTestsBase.cs | 67 --- .../ConfigurationBuilderTestsForGeneration.cs | 298 --------- .../ConfigurationBuilderTestsForRedact.cs | 66 -- .../ConfigurationBuilderTestsForValidation.cs | 182 ------ .../Config/ConfigurationCLITests.cs | 61 -- .../Config/SBOMConfigTests.cs | 96 --- .../DirectoryPathIsWritableValidatorTests.cs | 50 -- .../ConsoleCapture.cs | 60 -- ...ntToExternalReferenceInfoConverterTests.cs | 115 ---- ...xternalReferenceInfoToPathConverterTest.cs | 119 ---- .../SbomToolManifestPathConverterTests.cs | 232 ------- .../Entities/FileValidationResultTest.cs | 45 -- .../output/ValidationResultGeneratorTests.cs | 304 ---------- .../ComponentToPackageInfoConverterTests.cs | 289 --------- .../Executors/DirectoryWalkerTests.cs | 109 ---- .../ExternalDocumentReferenceWriterTest.cs | 100 --- .../Executors/FileHasherTests.cs | 338 ----------- .../Executors/FileListEnumeratorTests.cs | 115 ---- .../Executors/HashValidatorTests.cs | 155 ----- .../LicenseInformationFetcherTests.cs | 163 ----- .../Executors/PackagesWalkerTests.cs | 238 -------- .../Executors/RelationshipGeneratorTest.cs | 129 ---- .../Executors/SBOMComponentsWalkerTests.cs | 130 ---- ...ReaderForExternalDocumentReferenceTests.cs | 194 ------ .../Filters/DownloadedRootPathFilterTests.cs | 58 -- .../Filters/ManifestFolderFilterTests.cs | 86 --- .../FormatValidatorTestStrings.cs | 197 ------ .../FormatValidator/FormatValidatorTests.cs | 185 ------ .../FormatValidator/SpdxExemplars.cs | 306 ---------- .../Hashing/HashCodeGeneratorTests.cs | 63 -- .../HttpRequestUtils.cs | 113 ---- .../Metadata/LocalMetadataProviderTest.cs | 56 -- .../Metadata/SbomApiMetadataProviderTest.cs | 72 --- .../Microsoft.Sbom.Api.Tests.csproj | 24 - .../Output/ManifestToolJsonSerializerTests.cs | 107 ---- .../PackageDetails/MavenUtilsTests.cs | 157 ----- .../PackageDetails/NugetUtilsTests.cs | 128 ---- .../PackageDetails/RubyGemsUtilsTests.cs | 188 ------ .../PackageDetails/SampleMetadataFiles.cs | 188 ------ test/Microsoft.Sbom.Api.Tests/PathUtils.cs | 46 -- .../SBOMGeneratorTest.cs | 103 ---- .../SignValidationProviderTests.cs | 55 -- .../TestManifestGenerator.cs | 151 ----- test/Microsoft.Sbom.Api.Tests/TestUtils.cs | 19 - ...mponentDetectionCliArgumentBuilderTests.cs | 323 ---------- .../ComponentDetectorCachedExecutorTest.cs | 54 -- .../ExternalReferenceDeduplicatorTests.cs | 140 ----- .../Utils/FileHashesDictionarySingleton.cs | 33 - .../Utils/FileSystemUtilsExtensionTest.cs | 45 -- .../Utils/FileTypeUtilsTest.cs | 36 -- .../Utils/IdentifierUtilsTests.cs | 35 -- .../Utils/OSUtilsTest.cs | 95 --- .../Utils/SBOMFileDedeplicatorTests.cs | 140 ----- .../RelationshipsArrayGeneratorTest.cs | 174 ------ .../Workflows/Helpers/SbomRedactorTests.cs | 159 ----- .../ManifestGenerationWorkflowTests.cs | 415 ------------- .../SbomParserBasedValidationWorkflowTests.cs | 382 ------------ .../Workflows/SbomRedactionWorkflowTests.cs | 159 ----- .../Workflows/ValidationWorkflowTestsBase.cs | 76 --- ...xtensions.DependencyInjection.Tests.csproj | 22 - ...entDetectionErrorsToWarningsLoggerTests.cs | 162 ----- ...Sbom.Parsers.Spdx22SbomParser.Tests.csproj | 15 - .../Parser/GeneratorTests.cs | 52 -- .../Parser/LargeJsonParserTests.cs | 38 -- .../Parser/ParserResults.cs | 23 - .../Parser/SbomFileParserTests.cs | 173 ------ .../Parser/SbomPackageParserTests.cs | 135 ----- .../Parser/SbomParserTests.cs | 102 ---- .../Parser/SbomParserTestsBase.cs | 68 --- .../Parser/SbomRelationshipParserTests.cs | 106 ---- .../ExternalDocumentReferenceStrings.cs | 119 ---- .../Parser/Strings/RelationshipStrings.cs | 96 --- .../Parser/Strings/SbomFileJsonStrings.cs | 354 ----------- .../Parser/Strings/SbomPackageStrings.cs | 567 ------------------ .../Parser/Strings/SbomParserStrings.cs | 171 ------ ...MetadataProviderIdentityExtensionsTests.cs | 188 ------ .../Utils/SPDXExtensionsTest.cs | 157 ----- .../Utils/SbomFormatConverterTests.cs | 52 -- ...Sbom.Parsers.Spdx30SbomParser.Tests.csproj | 17 - .../Parser/GeneratorTests.cs | 237 -------- .../JsonStrings/SbomDocCreationJsonStrings.cs | 74 --- .../JsonStrings/SbomExternalMapJsonStrings.cs | 26 - .../Parser/JsonStrings/SbomFileJsonStrings.cs | 61 -- .../JsonStrings/SbomPackageJsonStrings.cs | 134 ----- .../SbomRelationshipJsonStrings.cs | 22 - .../AbstractGenerateSbomTaskInputTests.cs | 375 ------------ .../AbstractGenerateSbomTaskTests.cs | 452 -------------- .../GenerateSbomTaskSPDX_2_2InputTests.cs | 15 - .../GenerateSbomTaskSPDX_2_2Tests.cs | 22 - .../Microsoft.Sbom.Targets.Tests.csproj | 42 -- .../Utility/GeneratedSbomValidator.cs | 138 ----- .../IntegrationTests.cs | 234 -------- .../Microsoft.Sbom.Tool.Tests.csproj | 18 - 98 files changed, 13652 deletions(-) delete mode 100644 test/Microsoft.Sbom.Adapters.Tests/ComponentDetectionToSBOMPackageAdapterTests.cs delete mode 100644 test/Microsoft.Sbom.Adapters.Tests/Microsoft.Sbom.Adapters.Tests.csproj delete mode 100644 test/Microsoft.Sbom.Api.Tests/ApiConfigurationBuilderTests.cs delete mode 100644 test/Microsoft.Sbom.Api.Tests/Config/ConfigSanitizerTests.cs delete mode 100644 test/Microsoft.Sbom.Api.Tests/Config/ConfigurationBuilderTestsBase.cs delete mode 100644 test/Microsoft.Sbom.Api.Tests/Config/ConfigurationBuilderTestsForGeneration.cs delete mode 100644 test/Microsoft.Sbom.Api.Tests/Config/ConfigurationBuilderTestsForRedact.cs delete mode 100644 test/Microsoft.Sbom.Api.Tests/Config/ConfigurationBuilderTestsForValidation.cs delete mode 100644 test/Microsoft.Sbom.Api.Tests/Config/ConfigurationCLITests.cs delete mode 100644 test/Microsoft.Sbom.Api.Tests/Config/SBOMConfigTests.cs delete mode 100644 test/Microsoft.Sbom.Api.Tests/Config/Validators/DirectoryPathIsWritableValidatorTests.cs delete mode 100644 test/Microsoft.Sbom.Api.Tests/ConsoleCapture.cs delete mode 100644 test/Microsoft.Sbom.Api.Tests/Converters/ComponentToExternalReferenceInfoConverterTests.cs delete mode 100644 test/Microsoft.Sbom.Api.Tests/Converters/ExternalReferenceInfoToPathConverterTest.cs delete mode 100644 test/Microsoft.Sbom.Api.Tests/Converters/SbomToolManifestPathConverterTests.cs delete mode 100644 test/Microsoft.Sbom.Api.Tests/Entities/FileValidationResultTest.cs delete mode 100644 test/Microsoft.Sbom.Api.Tests/Entities/output/ValidationResultGeneratorTests.cs delete mode 100644 test/Microsoft.Sbom.Api.Tests/Executors/ComponentToPackageInfoConverterTests.cs delete mode 100644 test/Microsoft.Sbom.Api.Tests/Executors/DirectoryWalkerTests.cs delete mode 100644 test/Microsoft.Sbom.Api.Tests/Executors/ExternalDocumentReferenceWriterTest.cs delete mode 100644 test/Microsoft.Sbom.Api.Tests/Executors/FileHasherTests.cs delete mode 100644 test/Microsoft.Sbom.Api.Tests/Executors/FileListEnumeratorTests.cs delete mode 100644 test/Microsoft.Sbom.Api.Tests/Executors/HashValidatorTests.cs delete mode 100644 test/Microsoft.Sbom.Api.Tests/Executors/LicenseInformationFetcherTests.cs delete mode 100644 test/Microsoft.Sbom.Api.Tests/Executors/PackagesWalkerTests.cs delete mode 100644 test/Microsoft.Sbom.Api.Tests/Executors/RelationshipGeneratorTest.cs delete mode 100644 test/Microsoft.Sbom.Api.Tests/Executors/SBOMComponentsWalkerTests.cs delete mode 100644 test/Microsoft.Sbom.Api.Tests/Executors/SPDXSBOMReaderForExternalDocumentReferenceTests.cs delete mode 100644 test/Microsoft.Sbom.Api.Tests/Filters/DownloadedRootPathFilterTests.cs delete mode 100644 test/Microsoft.Sbom.Api.Tests/Filters/ManifestFolderFilterTests.cs delete mode 100644 test/Microsoft.Sbom.Api.Tests/FormatValidator/FormatValidatorTestStrings.cs delete mode 100644 test/Microsoft.Sbom.Api.Tests/FormatValidator/FormatValidatorTests.cs delete mode 100644 test/Microsoft.Sbom.Api.Tests/FormatValidator/SpdxExemplars.cs delete mode 100644 test/Microsoft.Sbom.Api.Tests/Hashing/HashCodeGeneratorTests.cs delete mode 100644 test/Microsoft.Sbom.Api.Tests/HttpRequestUtils.cs delete mode 100644 test/Microsoft.Sbom.Api.Tests/Metadata/LocalMetadataProviderTest.cs delete mode 100644 test/Microsoft.Sbom.Api.Tests/Metadata/SbomApiMetadataProviderTest.cs delete mode 100644 test/Microsoft.Sbom.Api.Tests/Microsoft.Sbom.Api.Tests.csproj delete mode 100644 test/Microsoft.Sbom.Api.Tests/Output/ManifestToolJsonSerializerTests.cs delete mode 100644 test/Microsoft.Sbom.Api.Tests/PackageDetails/MavenUtilsTests.cs delete mode 100644 test/Microsoft.Sbom.Api.Tests/PackageDetails/NugetUtilsTests.cs delete mode 100644 test/Microsoft.Sbom.Api.Tests/PackageDetails/RubyGemsUtilsTests.cs delete mode 100644 test/Microsoft.Sbom.Api.Tests/PackageDetails/SampleMetadataFiles.cs delete mode 100644 test/Microsoft.Sbom.Api.Tests/PathUtils.cs delete mode 100644 test/Microsoft.Sbom.Api.Tests/SBOMGeneratorTest.cs delete mode 100644 test/Microsoft.Sbom.Api.Tests/SignValidator/SignValidationProviderTests.cs delete mode 100644 test/Microsoft.Sbom.Api.Tests/TestManifestGenerator.cs delete mode 100644 test/Microsoft.Sbom.Api.Tests/TestUtils.cs delete mode 100644 test/Microsoft.Sbom.Api.Tests/Utils/ComponentDetectionCliArgumentBuilderTests.cs delete mode 100644 test/Microsoft.Sbom.Api.Tests/Utils/ComponentDetectorCachedExecutorTest.cs delete mode 100644 test/Microsoft.Sbom.Api.Tests/Utils/ExternalReferenceDeduplicatorTests.cs delete mode 100644 test/Microsoft.Sbom.Api.Tests/Utils/FileHashesDictionarySingleton.cs delete mode 100644 test/Microsoft.Sbom.Api.Tests/Utils/FileSystemUtilsExtensionTest.cs delete mode 100644 test/Microsoft.Sbom.Api.Tests/Utils/FileTypeUtilsTest.cs delete mode 100644 test/Microsoft.Sbom.Api.Tests/Utils/IdentifierUtilsTests.cs delete mode 100644 test/Microsoft.Sbom.Api.Tests/Utils/OSUtilsTest.cs delete mode 100644 test/Microsoft.Sbom.Api.Tests/Utils/SBOMFileDedeplicatorTests.cs delete mode 100644 test/Microsoft.Sbom.Api.Tests/Workflows/Helpers/RelationshipsArrayGeneratorTest.cs delete mode 100644 test/Microsoft.Sbom.Api.Tests/Workflows/Helpers/SbomRedactorTests.cs delete mode 100644 test/Microsoft.Sbom.Api.Tests/Workflows/ManifestGenerationWorkflowTests.cs delete mode 100644 test/Microsoft.Sbom.Api.Tests/Workflows/SbomParserBasedValidationWorkflowTests.cs delete mode 100644 test/Microsoft.Sbom.Api.Tests/Workflows/SbomRedactionWorkflowTests.cs delete mode 100644 test/Microsoft.Sbom.Api.Tests/Workflows/ValidationWorkflowTestsBase.cs delete mode 100644 test/Microsoft.Sbom.Extensions.DependencyInjection.Tests/Microsoft.Sbom.Extensions.DependencyInjection.Tests.csproj delete mode 100644 test/Microsoft.Sbom.Extensions.DependencyInjection.Tests/RemapComponentDetectionErrorsToWarningsLoggerTests.cs delete mode 100644 test/Microsoft.Sbom.Parsers.Spdx22SbomParser.Tests/Microsoft.Sbom.Parsers.Spdx22SbomParser.Tests.csproj delete mode 100644 test/Microsoft.Sbom.Parsers.Spdx22SbomParser.Tests/Parser/GeneratorTests.cs delete mode 100644 test/Microsoft.Sbom.Parsers.Spdx22SbomParser.Tests/Parser/LargeJsonParserTests.cs delete mode 100644 test/Microsoft.Sbom.Parsers.Spdx22SbomParser.Tests/Parser/ParserResults.cs delete mode 100644 test/Microsoft.Sbom.Parsers.Spdx22SbomParser.Tests/Parser/SbomFileParserTests.cs delete mode 100644 test/Microsoft.Sbom.Parsers.Spdx22SbomParser.Tests/Parser/SbomPackageParserTests.cs delete mode 100644 test/Microsoft.Sbom.Parsers.Spdx22SbomParser.Tests/Parser/SbomParserTests.cs delete mode 100644 test/Microsoft.Sbom.Parsers.Spdx22SbomParser.Tests/Parser/SbomParserTestsBase.cs delete mode 100644 test/Microsoft.Sbom.Parsers.Spdx22SbomParser.Tests/Parser/SbomRelationshipParserTests.cs delete mode 100644 test/Microsoft.Sbom.Parsers.Spdx22SbomParser.Tests/Parser/Strings/ExternalDocumentReferenceStrings.cs delete mode 100644 test/Microsoft.Sbom.Parsers.Spdx22SbomParser.Tests/Parser/Strings/RelationshipStrings.cs delete mode 100644 test/Microsoft.Sbom.Parsers.Spdx22SbomParser.Tests/Parser/Strings/SbomFileJsonStrings.cs delete mode 100644 test/Microsoft.Sbom.Parsers.Spdx22SbomParser.Tests/Parser/Strings/SbomPackageStrings.cs delete mode 100644 test/Microsoft.Sbom.Parsers.Spdx22SbomParser.Tests/Parser/Strings/SbomParserStrings.cs delete mode 100644 test/Microsoft.Sbom.Parsers.Spdx22SbomParser.Tests/Utils/InternalMetadataProviderIdentityExtensionsTests.cs delete mode 100644 test/Microsoft.Sbom.Parsers.Spdx22SbomParser.Tests/Utils/SPDXExtensionsTest.cs delete mode 100644 test/Microsoft.Sbom.Parsers.Spdx22SbomParser.Tests/Utils/SbomFormatConverterTests.cs delete mode 100644 test/Microsoft.Sbom.Parsers.Spdx30SbomParser.Tests/Microsoft.Sbom.Parsers.Spdx30SbomParser.Tests.csproj delete mode 100644 test/Microsoft.Sbom.Parsers.Spdx30SbomParser.Tests/Parser/GeneratorTests.cs delete mode 100644 test/Microsoft.Sbom.Parsers.Spdx30SbomParser.Tests/Parser/JsonStrings/SbomDocCreationJsonStrings.cs delete mode 100644 test/Microsoft.Sbom.Parsers.Spdx30SbomParser.Tests/Parser/JsonStrings/SbomExternalMapJsonStrings.cs delete mode 100644 test/Microsoft.Sbom.Parsers.Spdx30SbomParser.Tests/Parser/JsonStrings/SbomFileJsonStrings.cs delete mode 100644 test/Microsoft.Sbom.Parsers.Spdx30SbomParser.Tests/Parser/JsonStrings/SbomPackageJsonStrings.cs delete mode 100644 test/Microsoft.Sbom.Parsers.Spdx30SbomParser.Tests/Parser/JsonStrings/SbomRelationshipJsonStrings.cs delete mode 100644 test/Microsoft.Sbom.Targets.Tests/AbstractGenerateSbomTaskInputTests.cs delete mode 100644 test/Microsoft.Sbom.Targets.Tests/AbstractGenerateSbomTaskTests.cs delete mode 100644 test/Microsoft.Sbom.Targets.Tests/GenerateSbomTaskSPDX_2_2InputTests.cs delete mode 100644 test/Microsoft.Sbom.Targets.Tests/GenerateSbomTaskSPDX_2_2Tests.cs delete mode 100644 test/Microsoft.Sbom.Targets.Tests/Microsoft.Sbom.Targets.Tests.csproj delete mode 100644 test/Microsoft.Sbom.Targets.Tests/Utility/GeneratedSbomValidator.cs delete mode 100644 test/Microsoft.Sbom.Tool.Tests/IntegrationTests.cs delete mode 100644 test/Microsoft.Sbom.Tool.Tests/Microsoft.Sbom.Tool.Tests.csproj diff --git a/Microsoft.Sbom.sln b/Microsoft.Sbom.sln index cd1421e7..5abd4a19 100644 --- a/Microsoft.Sbom.sln +++ b/Microsoft.Sbom.sln @@ -23,16 +23,10 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Sbom.Contracts", "src\Microsoft.Sbom.Contracts\Microsoft.Sbom.Contracts.csproj", "{AA73B697-C992-4940-8375-17B9B77AB351}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Sbom.Adapters.Tests", "test\Microsoft.Sbom.Adapters.Tests\Microsoft.Sbom.Adapters.Tests.csproj", "{4F5EA400-F98B-4010-A8E1-D55A96428B07}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Sbom.Parsers.Spdx22SbomParser", "src\Microsoft.Sbom.Parsers.Spdx22SbomParser\Microsoft.Sbom.Parsers.Spdx22SbomParser.csproj", "{86EC977D-A785-40FF-AE78-C1EC4254AFF8}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Sbom.Parsers.Spdx22SbomParser.Tests", "test\Microsoft.Sbom.Parsers.Spdx22SbomParser.Tests\Microsoft.Sbom.Parsers.Spdx22SbomParser.Tests.csproj", "{ADDEE422-40D1-48D9-A5FB-BBE990272B78}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Sbom.Api", "src\Microsoft.Sbom.Api\Microsoft.Sbom.Api.csproj", "{725723C5-DCA4-4BAD-8883-CC94E5F5A5A8}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Sbom.Api.Tests", "test\Microsoft.Sbom.Api.Tests\Microsoft.Sbom.Api.Tests.csproj", "{4F94EA4F-CC6B-4FA0-8A7E-654EAA26B625}" -EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "docs", "docs", "{1A9688BD-D306-4091-A319-FDE110A48CBD}" ProjectSection(SolutionItems) = preProject docs\building-from-source.md = docs\building-from-source.md @@ -47,20 +41,12 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Sbom.DotNetTool", EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Sbom.Extensions.DependencyInjection", "src\Microsoft.Sbom.Extensions.DependencyInjection\Microsoft.Sbom.Extensions.DependencyInjection.csproj", "{2EB7C6CC-5E40-4DAF-AF8B-D69736B601D9}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Sbom.Extensions.DependencyInjection.Tests", "test\Microsoft.Sbom.Extensions.DependencyInjection.Tests\Microsoft.Sbom.Extensions.DependencyInjection.Tests.csproj", "{EE4E2E03-7B4C-46E5-B9D2-89E84A18D787}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Sbom.Targets", "src\Microsoft.Sbom.Targets\Microsoft.Sbom.Targets.csproj", "{E6C3C851-EEA0-466E-BA36-73ED85F13EEA}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Sbom.Targets.Tests", "test\Microsoft.Sbom.Targets.Tests\Microsoft.Sbom.Targets.Tests.csproj", "{E31B914C-F24B-4DC8-ACC7-CAEA952563B8}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Sbom.Tool.Tests", "test\Microsoft.Sbom.Tool.Tests\Microsoft.Sbom.Tool.Tests.csproj", "{FC5A9799-7C44-4BFA-BA22-55DCAF1A1B9F}" -EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.Sbom.Targets.E2E.Tests", "test\Microsoft.Sbom.Targets.E2E.Tests\Microsoft.Sbom.Targets.E2E.Tests.csproj", "{3FDE7800-F61F-4C45-93AB-648A4C7979C7}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.Sbom.Parsers.Spdx30SbomParser", "src\Microsoft.Sbom.Parsers.Spdx30SbomParser\Microsoft.Sbom.Parsers.Spdx30SbomParser.csproj", "{476B9C87-293F-4BF7-B39A-EB732083409F}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.Sbom.Parsers.Spdx30SbomParser.Tests", "test\Microsoft.Sbom.Parsers.Spdx30SbomParser.Tests\Microsoft.Sbom.Parsers.Spdx30SbomParser.Tests.csproj", "{E3FE33BB-FAB2-4F60-B930-BEB736AACE25}" -EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -87,26 +73,14 @@ Global {AA73B697-C992-4940-8375-17B9B77AB351}.Debug|Any CPU.Build.0 = Debug|Any CPU {AA73B697-C992-4940-8375-17B9B77AB351}.Release|Any CPU.ActiveCfg = Release|Any CPU {AA73B697-C992-4940-8375-17B9B77AB351}.Release|Any CPU.Build.0 = Release|Any CPU - {4F5EA400-F98B-4010-A8E1-D55A96428B07}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {4F5EA400-F98B-4010-A8E1-D55A96428B07}.Debug|Any CPU.Build.0 = Debug|Any CPU - {4F5EA400-F98B-4010-A8E1-D55A96428B07}.Release|Any CPU.ActiveCfg = Release|Any CPU - {4F5EA400-F98B-4010-A8E1-D55A96428B07}.Release|Any CPU.Build.0 = Release|Any CPU {86EC977D-A785-40FF-AE78-C1EC4254AFF8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {86EC977D-A785-40FF-AE78-C1EC4254AFF8}.Debug|Any CPU.Build.0 = Debug|Any CPU {86EC977D-A785-40FF-AE78-C1EC4254AFF8}.Release|Any CPU.ActiveCfg = Release|Any CPU {86EC977D-A785-40FF-AE78-C1EC4254AFF8}.Release|Any CPU.Build.0 = Release|Any CPU - {ADDEE422-40D1-48D9-A5FB-BBE990272B78}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {ADDEE422-40D1-48D9-A5FB-BBE990272B78}.Debug|Any CPU.Build.0 = Debug|Any CPU - {ADDEE422-40D1-48D9-A5FB-BBE990272B78}.Release|Any CPU.ActiveCfg = Release|Any CPU - {ADDEE422-40D1-48D9-A5FB-BBE990272B78}.Release|Any CPU.Build.0 = Release|Any CPU {725723C5-DCA4-4BAD-8883-CC94E5F5A5A8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {725723C5-DCA4-4BAD-8883-CC94E5F5A5A8}.Debug|Any CPU.Build.0 = Debug|Any CPU {725723C5-DCA4-4BAD-8883-CC94E5F5A5A8}.Release|Any CPU.ActiveCfg = Release|Any CPU {725723C5-DCA4-4BAD-8883-CC94E5F5A5A8}.Release|Any CPU.Build.0 = Release|Any CPU - {4F94EA4F-CC6B-4FA0-8A7E-654EAA26B625}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {4F94EA4F-CC6B-4FA0-8A7E-654EAA26B625}.Debug|Any CPU.Build.0 = Debug|Any CPU - {4F94EA4F-CC6B-4FA0-8A7E-654EAA26B625}.Release|Any CPU.ActiveCfg = Release|Any CPU - {4F94EA4F-CC6B-4FA0-8A7E-654EAA26B625}.Release|Any CPU.Build.0 = Release|Any CPU {6C27560E-B0B0-44E3-B4AE-6FB92CE9FE4A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {6C27560E-B0B0-44E3-B4AE-6FB92CE9FE4A}.Debug|Any CPU.Build.0 = Debug|Any CPU {6C27560E-B0B0-44E3-B4AE-6FB92CE9FE4A}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -115,22 +89,10 @@ Global {2EB7C6CC-5E40-4DAF-AF8B-D69736B601D9}.Debug|Any CPU.Build.0 = Debug|Any CPU {2EB7C6CC-5E40-4DAF-AF8B-D69736B601D9}.Release|Any CPU.ActiveCfg = Release|Any CPU {2EB7C6CC-5E40-4DAF-AF8B-D69736B601D9}.Release|Any CPU.Build.0 = Release|Any CPU - {EE4E2E03-7B4C-46E5-B9D2-89E84A18D787}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {EE4E2E03-7B4C-46E5-B9D2-89E84A18D787}.Debug|Any CPU.Build.0 = Debug|Any CPU - {EE4E2E03-7B4C-46E5-B9D2-89E84A18D787}.Release|Any CPU.ActiveCfg = Release|Any CPU - {EE4E2E03-7B4C-46E5-B9D2-89E84A18D787}.Release|Any CPU.Build.0 = Release|Any CPU {E6C3C851-EEA0-466E-BA36-73ED85F13EEA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {E6C3C851-EEA0-466E-BA36-73ED85F13EEA}.Debug|Any CPU.Build.0 = Debug|Any CPU {E6C3C851-EEA0-466E-BA36-73ED85F13EEA}.Release|Any CPU.ActiveCfg = Release|Any CPU {E6C3C851-EEA0-466E-BA36-73ED85F13EEA}.Release|Any CPU.Build.0 = Release|Any CPU - {E31B914C-F24B-4DC8-ACC7-CAEA952563B8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {E31B914C-F24B-4DC8-ACC7-CAEA952563B8}.Debug|Any CPU.Build.0 = Debug|Any CPU - {E31B914C-F24B-4DC8-ACC7-CAEA952563B8}.Release|Any CPU.ActiveCfg = Release|Any CPU - {E31B914C-F24B-4DC8-ACC7-CAEA952563B8}.Release|Any CPU.Build.0 = Release|Any CPU - {FC5A9799-7C44-4BFA-BA22-55DCAF1A1B9F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {FC5A9799-7C44-4BFA-BA22-55DCAF1A1B9F}.Debug|Any CPU.Build.0 = Debug|Any CPU - {FC5A9799-7C44-4BFA-BA22-55DCAF1A1B9F}.Release|Any CPU.ActiveCfg = Release|Any CPU - {FC5A9799-7C44-4BFA-BA22-55DCAF1A1B9F}.Release|Any CPU.Build.0 = Release|Any CPU {3FDE7800-F61F-4C45-93AB-648A4C7979C7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {3FDE7800-F61F-4C45-93AB-648A4C7979C7}.Debug|Any CPU.Build.0 = Debug|Any CPU {3FDE7800-F61F-4C45-93AB-648A4C7979C7}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -139,10 +101,6 @@ Global {476B9C87-293F-4BF7-B39A-EB732083409F}.Debug|Any CPU.Build.0 = Debug|Any CPU {476B9C87-293F-4BF7-B39A-EB732083409F}.Release|Any CPU.ActiveCfg = Release|Any CPU {476B9C87-293F-4BF7-B39A-EB732083409F}.Release|Any CPU.Build.0 = Release|Any CPU - {E3FE33BB-FAB2-4F60-B930-BEB736AACE25}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {E3FE33BB-FAB2-4F60-B930-BEB736AACE25}.Debug|Any CPU.Build.0 = Debug|Any CPU - {E3FE33BB-FAB2-4F60-B930-BEB736AACE25}.Release|Any CPU.ActiveCfg = Release|Any CPU - {E3FE33BB-FAB2-4F60-B930-BEB736AACE25}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/test/Microsoft.Sbom.Adapters.Tests/ComponentDetectionToSBOMPackageAdapterTests.cs b/test/Microsoft.Sbom.Adapters.Tests/ComponentDetectionToSBOMPackageAdapterTests.cs deleted file mode 100644 index 932173b0..00000000 --- a/test/Microsoft.Sbom.Adapters.Tests/ComponentDetectionToSBOMPackageAdapterTests.cs +++ /dev/null @@ -1,307 +0,0 @@ -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using Microsoft.ComponentDetection.Contracts.Internal; -using Microsoft.ComponentDetection.Contracts.TypedComponent; -using Microsoft.Sbom.Adapters.Report; -using Microsoft.Sbom.Contracts; -using Microsoft.Sbom.Contracts.Enums; -using Microsoft.VisualStudio.TestTools.UnitTesting; - -namespace Microsoft.Sbom.Adapters.Tests; - -using Microsoft.Sbom.Adapters.ComponentDetection; - -[TestClass] -public class ComponentDetectionToSBOMPackageAdapterTests -{ - public TestContext TestContext { get; set; } - - [TestMethod] - public void BasicAdapterTest_Succeeds() - { -#pragma warning disable JSON002 // Probable JSON string detected - var json = @"{ - ""componentsFound"": [ - { - ""locationsFoundAt"": [ - ""/Public/Src/Tools/JavaScript/Tool.YarnGraphBuilder/src/package.json"" - ], - ""component"": { - ""name"": ""@microsoft/yarn-graph-builder"", - ""version"": ""1.0.0"", - ""hash"": null, - ""type"": ""Npm"", - ""id"": ""@microsoft/yarn-graph-builder 1.0.0 - Npm"", - ""author"": { - ""name"": ""some-name"" - } - }, - ""detectorId"": ""Npm"", - ""isDevelopmentDependency"": null, - ""topLevelReferrers"": [], - ""containerDetailIds"": [] - } - ], - ""detectorsInScan"": [], - ""ContainerDetailsMap"": {}, - ""resultCode"": ""Success"" - }"; -#pragma warning restore JSON002 // Probable JSON string detected - var (errors, packages) = GenerateJsonFileForTestAndRun(json); - - // Successful conversion - Assert.AreEqual(1, errors.Report.Count); - Assert.AreEqual(AdapterReportItemType.Success, errors.Report.First().Type); - - // Converted packaged is present and valid - Assert.IsNotNull(packages); - Assert.AreEqual(1, packages.Count); - Assert.IsNotNull(packages[0]); - Assert.AreEqual("@microsoft/yarn-graph-builder", packages[0].PackageName); - Assert.AreEqual("1.0.0", packages[0].PackageVersion); - - // This one contains no checksums, so verify that it is null - Assert.IsNotNull(packages[0].Checksum); - var checksums = packages[0].Checksum?.ToList(); - Assert.IsNotNull(checksums); - Assert.AreEqual(1, checksums.Count); - Assert.IsNull(checksums[0].ChecksumValue); - } - - [TestMethod] - public void NoComponents_Succeeds() - { -#pragma warning disable JSON002 // Probable JSON string detected - var json = @"{ - ""componentsFound"": [], - ""detectorsInScan"": [], - ""ContainerDetailsMap"": {}, - ""resultCode"": ""Success"" - }"; -#pragma warning restore JSON002 // Probable JSON string detected - var (errors, packages) = GenerateJsonFileForTestAndRun(json); - - Assert.IsNotNull(packages); - Assert.AreEqual(0, packages.Count); - Assert.AreEqual(1, errors.Report.Count); // Should still be successful even with no components - Assert.AreEqual(AdapterReportItemType.Success, errors.Report.First().Type); - } - - [TestMethod] - public void MalformedInput_ReturnsError() - { - var json = "{"; - var (errors, packages) = GenerateJsonFileForTestAndRun(json); - - Assert.AreEqual(1, errors.Report.Count); - Assert.AreEqual(AdapterReportItemType.Failure, errors.Report.First().Type); - Assert.IsTrue(errors.Report.First().Details.Contains("Unable to parse bcde-output.json", StringComparison.Ordinal)); - Assert.AreEqual(0, packages.Count); - } - - [TestMethod] - public void BadInput_ThrowsException() - { - Assert.ThrowsException(() => - { - var adapter = new ComponentDetectionToSBOMPackageAdapter(); - adapter.TryConvert("not/a/real/path"); - }); - } - - [TestMethod] - public void CargoComponent_ToSbomPackage() - { - var cargoComponent = new CargoComponent("name", "version"); - var scannedComponent = new ExtendedScannedComponent() { Component = cargoComponent }; - - var sbomPackage = scannedComponent.ToSbomPackage(new AdapterReport()); - - Assert.IsNotNull(sbomPackage.Id); - Assert.IsNotNull(sbomPackage.PackageUrl); - Assert.AreEqual(cargoComponent.Name, sbomPackage.PackageName); - Assert.AreEqual(cargoComponent.Version, sbomPackage.PackageVersion); - } - - [TestMethod] - public void ConanComponent_ToSbomPackage() - { - var md5 = Guid.NewGuid().ToString(); - var sha1Hash = Guid.NewGuid().ToString(); - - var conanComponent = new ConanComponent("name", "version", md5, sha1Hash); - var scannedComponent = new ExtendedScannedComponent() { Component = conanComponent }; - - var sbomPackage = scannedComponent.ToSbomPackage(new AdapterReport()); - - Assert.IsNotNull(sbomPackage.Id); - Assert.IsNotNull(sbomPackage.PackageUrl); - Assert.AreEqual(conanComponent.Name, sbomPackage.PackageName); - Assert.AreEqual(conanComponent.Version, sbomPackage.PackageVersion); - Assert.IsNotNull(sbomPackage.Checksum.First(x => x.ChecksumValue == conanComponent.Md5Hash)); - Assert.IsNotNull(sbomPackage.Checksum.First(x => x.ChecksumValue == conanComponent.Sha1Hash)); - Assert.AreEqual(conanComponent.PackageSourceURL, sbomPackage.PackageSource); - } - - [TestMethod] - public void CondaComponent_ToSbomPackage() - { - var condaComponent = new CondaComponent("name", "version", "build", "channel", "subdir", "namespace", "http://microsoft.com", "md5"); - var scannedComponent = new ExtendedScannedComponent() { Component = condaComponent }; - - var sbomPackage = scannedComponent.ToSbomPackage(new AdapterReport()); - - Assert.AreEqual(condaComponent.Id, sbomPackage.Id); - AssertPackageUrlIsCorrect(condaComponent.PackageUrl, sbomPackage.PackageUrl); - Assert.AreEqual(condaComponent.Name, sbomPackage.PackageName); - Assert.AreEqual(condaComponent.Version, sbomPackage.PackageVersion); - Assert.AreEqual(condaComponent.Url, sbomPackage.PackageSource); - Assert.AreEqual(condaComponent.MD5, sbomPackage.Checksum.First().ChecksumValue); - } - - [TestMethod] - public void DockerImageComponent_ToSbomPackage() - { - var dockerImageComponent = new DockerImageComponent("name", "version", "tag") { Digest = "digest" }; - var scannedComponent = new ExtendedScannedComponent() { Component = dockerImageComponent }; - - var sbomPackage = scannedComponent.ToSbomPackage(new AdapterReport()); - - Assert.AreEqual(dockerImageComponent.Id, sbomPackage.Id); - AssertPackageUrlIsCorrect(dockerImageComponent.PackageUrl, sbomPackage.PackageUrl); - Assert.AreEqual(dockerImageComponent.Name, sbomPackage.PackageName); - Assert.AreEqual(AlgorithmName.SHA256, sbomPackage.Checksum.First().Algorithm); - Assert.AreEqual(dockerImageComponent.Digest, sbomPackage.Checksum.First().ChecksumValue); - } - - [TestMethod] - public void NpmComponent_ToSbomPackage() - { - var npmComponent = new NpmComponent("name", "verison", author: new NpmAuthor("name", "email@contoso.com")); - var scannedComponent = new ExtendedScannedComponent() { Component = npmComponent }; - - var sbomPackage = scannedComponent.ToSbomPackage(new AdapterReport()); - - Assert.AreEqual(npmComponent.Id, sbomPackage.Id); - Assert.IsNotNull(npmComponent.PackageUrl); - Assert.AreEqual(npmComponent.PackageUrl.ToString(), sbomPackage.PackageUrl); - Assert.AreEqual(npmComponent.Name, sbomPackage.PackageName); - Assert.AreEqual(npmComponent.Version, sbomPackage.PackageVersion); - Assert.AreEqual($"Organization: {npmComponent.Author.Name} ({npmComponent.Author.Email})", sbomPackage.Supplier); - } - - [TestMethod] - public void NpmComponent_ToSbomPackage_NoAuthor() - { - var npmComponent = new NpmComponent("name", "verison"); - var scannedComponent = new ExtendedScannedComponent() { Component = npmComponent }; - - var sbomPackage = scannedComponent.ToSbomPackage(new AdapterReport()); - - Assert.AreEqual(npmComponent.Id, sbomPackage.Id); - Assert.IsNotNull(npmComponent.PackageUrl); - Assert.AreEqual(npmComponent.PackageUrl.ToString(), sbomPackage.PackageUrl); - Assert.AreEqual(npmComponent.Name, sbomPackage.PackageName); - Assert.AreEqual(npmComponent.Version, sbomPackage.PackageVersion); - Assert.IsNull(sbomPackage.Supplier); - } - - [TestMethod] - public void NuGetComponent_ToSbomPackage() - { - var nuGetComponent = new NuGetComponent("name", "version", new string[] { "Author Name1, Another Author" }); - var scannedComponent = new ExtendedScannedComponent() { Component = nuGetComponent }; - - var sbomPackage = scannedComponent.ToSbomPackage(new AdapterReport()); - - Assert.AreEqual(nuGetComponent.Id, sbomPackage.Id); - AssertPackageUrlIsCorrect(nuGetComponent.PackageUrl, sbomPackage.PackageUrl); - Assert.AreEqual(nuGetComponent.PackageUrl.ToString(), sbomPackage.PackageUrl); - Assert.AreEqual(nuGetComponent.Name, sbomPackage.PackageName); - Assert.AreEqual(nuGetComponent.Version, sbomPackage.PackageVersion); - Assert.AreEqual($"Organization: {nuGetComponent.Authors.First()}", sbomPackage.Supplier); - } - - [TestMethod] - public void NuGetComponent_ToSbomPackage_NoAuthor() - { - var nuGetComponent = new NuGetComponent("name", "version"); - var scannedComponent = new ExtendedScannedComponent() { Component = nuGetComponent }; - - var sbomPackage = scannedComponent.ToSbomPackage(new AdapterReport()); - - Assert.AreEqual(nuGetComponent.Id, sbomPackage.Id); - Assert.IsNotNull(nuGetComponent.PackageUrl); - Assert.AreEqual(nuGetComponent.PackageUrl.ToString(), sbomPackage.PackageUrl); - Assert.AreEqual(nuGetComponent.Name, sbomPackage.PackageName); - Assert.AreEqual(nuGetComponent.Version, sbomPackage.PackageVersion); - Assert.IsNull(sbomPackage.Supplier); - } - - [TestMethod] - public void PipComponent_ToSbomPackage() - { - var pipComponent = new PipComponent("name", "version"); - var scannedComponent = new ExtendedScannedComponent() { Component = pipComponent }; - - var sbomPackage = scannedComponent.ToSbomPackage(new AdapterReport()); - - Assert.AreEqual(pipComponent.Id, sbomPackage.Id); - Assert.IsNotNull(pipComponent.PackageUrl); - Assert.AreEqual(pipComponent.PackageUrl.ToString(), sbomPackage.PackageUrl); - Assert.AreEqual(pipComponent.Name, sbomPackage.PackageName); - Assert.AreEqual(pipComponent.Version, sbomPackage.PackageVersion); - } - - [TestMethod] - public void GitComponent_ToSbomPackage() - { - var uri = new Uri("https://microsoft.com"); - var gitComponent = new GitComponent(uri, "version"); - var scannedComponent = new ExtendedScannedComponent() { Component = gitComponent }; - - var sbomPackage = scannedComponent.ToSbomPackage(new AdapterReport()); - - Assert.AreEqual(gitComponent.Id, sbomPackage.Id); - AssertPackageUrlIsCorrect(gitComponent.PackageUrl, sbomPackage.PackageUrl); - } - - private void AssertPackageUrlIsCorrect(PackageUrl.PackageURL expectedPackageUrl, string actualPackageUrl) - { - if (expectedPackageUrl is null) - { - Assert.IsNull(actualPackageUrl); - return; - } - - Assert.AreEqual(expectedPackageUrl.ToString(), actualPackageUrl); - } - - private (AdapterReport report, List packages) GenerateJsonFileForTestAndRun(string json) - { - var baseDirectory = Path.Combine(TestContext.TestRunDirectory, Guid.NewGuid().ToString()); - var bcdeOutputPath = Path.Combine(baseDirectory, "bcde-output.json"); - - Directory.CreateDirectory(baseDirectory); - File.WriteAllText(bcdeOutputPath, json); - - var adapter = new ComponentDetectionToSBOMPackageAdapter(); - var (errors, packages) = adapter.TryConvert(bcdeOutputPath); - var output = packages.ToList(); - - // Clean up generated directories/files - File.Delete(bcdeOutputPath); - Directory.Delete(baseDirectory); - - // Unless the TryConvert call throws an exception, these should never be null - Assert.IsNotNull(packages); - Assert.IsNotNull(errors); - - return (errors, output); - } -} diff --git a/test/Microsoft.Sbom.Adapters.Tests/Microsoft.Sbom.Adapters.Tests.csproj b/test/Microsoft.Sbom.Adapters.Tests/Microsoft.Sbom.Adapters.Tests.csproj deleted file mode 100644 index 88135e16..00000000 --- a/test/Microsoft.Sbom.Adapters.Tests/Microsoft.Sbom.Adapters.Tests.csproj +++ /dev/null @@ -1,23 +0,0 @@ - - - - false - True - Microsoft.Sbom.Adapters.Tests - $(StrongNameSigningKeyFilePath) - - - - TRACE - - - - - - - - - - - - diff --git a/test/Microsoft.Sbom.Api.Tests/ApiConfigurationBuilderTests.cs b/test/Microsoft.Sbom.Api.Tests/ApiConfigurationBuilderTests.cs deleted file mode 100644 index 2059ab2b..00000000 --- a/test/Microsoft.Sbom.Api.Tests/ApiConfigurationBuilderTests.cs +++ /dev/null @@ -1,193 +0,0 @@ -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -using System; -using System.Collections.Generic; -using System.Diagnostics.Tracing; -using System.Linq; -using Microsoft.Sbom.Api.Config; -using Microsoft.Sbom.Common.Config; -using Microsoft.Sbom.Contracts; -using Microsoft.Sbom.Extensions.Entities; -using Microsoft.VisualStudio.TestTools.UnitTesting; -using Serilog.Events; - -namespace Microsoft.Sbom.Api.Tests; - -/// -/// Responsible for testing . -/// -[TestClass] -public class ApiConfigurationBuilderTests -{ - private const string RootPath = @"D:\TMP"; - private const int MinParallelism = 2; - private const int DefaultParallelism = 8; - private const int MaxParallelism = 48; - private const string PackageName = "packageName"; - private const string PackageVersion = "packageVersion"; - - private readonly SBOMMetadata metadata = new SBOMMetadata() - { - PackageName = PackageName, - PackageVersion = PackageVersion, - }; - - private readonly RuntimeConfiguration runtime = new RuntimeConfiguration() - { - Verbosity = EventLevel.Verbose, - WorkflowParallelism = DefaultParallelism, - DeleteManifestDirectoryIfPresent = true - }; - - private readonly string manifestDirPath = "manifestDirPath"; - private readonly List files = new List(); - private readonly List packages = new List(); - private readonly string externalDocumentRefListFile = "externalDocRef"; - private readonly string componentPath = @"D:\COMPONENT"; - - [TestMethod] - public void GetConfiguration_PopulateAll() - { - var specs = new List(); - specs.Add(new SbomSpecification("spdx", "2.2")); - - var expectedManifestInfo = new ManifestInfo() - { - Name = "spdx", - Version = "2.2" - }; - - var config = ApiConfigurationBuilder.GetConfiguration(RootPath, manifestDirPath, files, packages, metadata, specs, runtime, externalDocumentRefListFile, componentPath); - - Assert.AreEqual(RootPath, config.BuildDropPath.Value); - Assert.AreEqual(componentPath, config.BuildComponentPath.Value); - Assert.AreEqual(manifestDirPath, config.ManifestDirPath.Value); - Assert.AreEqual(ManifestToolActions.Generate, config.ManifestToolAction); - Assert.AreEqual(PackageName, config.PackageName.Value); - Assert.AreEqual(PackageVersion, config.PackageVersion.Value); - Assert.AreEqual(DefaultParallelism, config.Parallelism.Value); - Assert.AreEqual(LogEventLevel.Verbose, config.Verbosity.Value); - Assert.AreEqual(0, config.PackagesList.Value.ToList().Count); - Assert.AreEqual(0, config.FilesList.Value.ToList().Count); - Assert.AreEqual(externalDocumentRefListFile, config.ExternalDocumentReferenceListFile.Value); - Assert.AreEqual(1, config.ManifestInfo.Value.Count); - Assert.IsTrue(config.ManifestInfo.Value[0].Equals(expectedManifestInfo)); - - Assert.AreEqual(SettingSource.SBOMApi, config.BuildDropPath.Source); - Assert.AreEqual(SettingSource.SBOMApi, config.BuildComponentPath.Source); - Assert.AreEqual(SettingSource.SBOMApi, config.ManifestDirPath.Source); - Assert.AreEqual(SettingSource.SBOMApi, config.PackageName.Source); - Assert.AreEqual(SettingSource.SBOMApi, config.PackageVersion.Source); - Assert.AreEqual(SettingSource.SBOMApi, config.Parallelism.Source); - Assert.AreEqual(SettingSource.SBOMApi, config.Verbosity.Source); - Assert.AreEqual(SettingSource.SBOMApi, config.PackagesList.Source); - Assert.AreEqual(SettingSource.SBOMApi, config.FilesList.Source); - Assert.AreEqual(SettingSource.SBOMApi, config.ExternalDocumentReferenceListFile.Source); - Assert.AreEqual(SettingSource.SBOMApi, config.ManifestInfo.Source); - } - - [TestMethod] - public void GetConfiguration_NullProperties() - { - var config = ApiConfigurationBuilder.GetConfiguration(RootPath, manifestDirPath, null, null, metadata, null, runtime, null, componentPath); - - Assert.IsNull(config.PackagesList); - Assert.IsNull(config.FilesList); - Assert.IsNull(config.ExternalDocumentReferenceListFile); - Assert.IsNull(config.ManifestInfo); - } - - [TestMethod] - [DataRow(null)] - [DataRow(" ")] - public void GetConfiguration_NullComponentPath(string componentPath) - { - var config = ApiConfigurationBuilder.GetConfiguration(RootPath, manifestDirPath, null, null, metadata, null, runtime, null, componentPath); - - Assert.IsNull(config.BuildComponentPath); - } - - [TestMethod] - [DataRow(EventLevel.Informational, LogEventLevel.Information)] - [DataRow(EventLevel.Critical, LogEventLevel.Fatal)] - [DataRow(EventLevel.Error, LogEventLevel.Error)] - [DataRow(EventLevel.LogAlways, LogEventLevel.Verbose)] - [DataRow(EventLevel.Verbose, LogEventLevel.Verbose)] - [DataRow(EventLevel.Warning, LogEventLevel.Warning)] - public void GetConfiguration_ShouldMapVerbosity(EventLevel input, LogEventLevel output) - { - // This uses EventLevel to avoid exposing the serilog implementation to the caller - var runtime = new RuntimeConfiguration() - { - Verbosity = input - }; - - var config = ApiConfigurationBuilder.GetConfiguration( - RootPath, - string.Empty, - null, - null, - this.metadata, - null, - runtime); - - Assert.AreEqual(output, config.Verbosity.Value); - } - - [TestMethod] - [DataRow(MinParallelism - 1, DefaultParallelism)] - [DataRow(MaxParallelism + 1, DefaultParallelism)] - [DataRow(10, 10)] - [DataRow(null, DefaultParallelism)] - public void GetConfiguration_SantizeRuntimeConfig_Parallelism(int? input, int output) - { - var runtime = new RuntimeConfiguration() - { - Verbosity = EventLevel.Verbose, - }; - - if (input != null) - { - runtime.WorkflowParallelism = (int)input; - } - - var config = ApiConfigurationBuilder.GetConfiguration("random", null, null, null, metadata, null, runtime); - Assert.AreEqual(output, config.Parallelism.Value); - } - - [TestMethod] - public void GetConfiguration_DefaultRuntime() - { - var defaultRuntime = new RuntimeConfiguration - { - WorkflowParallelism = DefaultParallelism, - Verbosity = EventLevel.Warning, - DeleteManifestDirectoryIfPresent = false - }; - - var config = ApiConfigurationBuilder.GetConfiguration("random", null, null, null, metadata, null, null); - Assert.AreEqual(defaultRuntime.WorkflowParallelism, config.Parallelism.Value); - Assert.AreEqual(LogEventLevel.Warning, config.Verbosity.Value); - } - - [TestMethod] - [DataRow(" ")] - [DataRow(null)] - public void ThrowArgumentExceptionOnRootPathValues(string input) - { - Assert.ThrowsException(() => ApiConfigurationBuilder.GetConfiguration(input, null, null, null, null)); - } - - [TestMethod] - public void ThrowArgumentNulExceptionOnNullMetadata() - { - Assert.ThrowsException(() => ApiConfigurationBuilder.GetConfiguration("random", null, null, null, null)); - } - - [TestMethod] - public void ThrowArgumentExceptionOnSpecificationZero() - { - Assert.ThrowsException(() => ApiConfigurationBuilder.GetConfiguration("random", null, null, null, metadata, new List(), runtime)); - } -} diff --git a/test/Microsoft.Sbom.Api.Tests/Config/ConfigSanitizerTests.cs b/test/Microsoft.Sbom.Api.Tests/Config/ConfigSanitizerTests.cs deleted file mode 100644 index 72c6df8a..00000000 --- a/test/Microsoft.Sbom.Api.Tests/Config/ConfigSanitizerTests.cs +++ /dev/null @@ -1,397 +0,0 @@ -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Runtime.InteropServices; -using System.Security.Cryptography; -using Microsoft.Sbom.Api.Config; -using Microsoft.Sbom.Api.Exceptions; -using Microsoft.Sbom.Api.Executors; -using Microsoft.Sbom.Api.Hashing; -using Microsoft.Sbom.Api.Utils; -using Microsoft.Sbom.Common; -using Microsoft.Sbom.Common.Config; -using Microsoft.Sbom.Contracts.Enums; -using Microsoft.Sbom.Extensions.Entities; -using Microsoft.VisualStudio.TestTools.UnitTesting; -using Moq; -using PowerArgs; -using Constants = Microsoft.Sbom.Api.Utils.Constants; - -namespace Microsoft.Sbom.Api.Tests.Config; - -[TestClass] -public class ConfigSanitizerTests -{ - private Mock mockFileSystemUtils; - private Mock mockHashAlgorithmProvider; - private Mock mockAssemblyConfig; - private ConfigSanitizer configSanitizer; - private readonly bool isWindows = RuntimeInformation.IsOSPlatform(OSPlatform.Windows); - - [TestInitialize] - public void Initialize() - { - mockFileSystemUtils = new Mock(); - mockFileSystemUtils - .Setup(f => f.JoinPaths(It.IsAny(), It.IsAny())) - .Returns((string p1, string p2) => Path.Join(p1, p2)); - - mockHashAlgorithmProvider = new Mock(); - mockHashAlgorithmProvider - .Setup(h => h.Get(It.IsAny())) - .Returns((string a) => - { - if (a == "SHA256") - { - return new AlgorithmName(a, stream => SHA256.Create().ComputeHash(stream)); - } - - throw new UnsupportedHashAlgorithmException("Unsupported"); - }); - - mockAssemblyConfig = new Mock(); - - configSanitizer = new ConfigSanitizer(mockHashAlgorithmProvider.Object, mockFileSystemUtils.Object, mockAssemblyConfig.Object); - } - - /// - /// This method returns a configuration object with all the properties set to standard values, - /// which won't make the test fail. Change one value that you are testing in order to ensure you - /// are testing the correct config. - /// - /// - private Configuration GetConfigurationBaseObject() - { - return new Configuration - { - HashAlgorithm = new ConfigurationSetting - { - Source = SettingSource.CommandLine, - Value = new AlgorithmName("SHA256", null) - }, - BuildDropPath = new ConfigurationSetting - { - Source = SettingSource.Default, - Value = "dropPath" - }, - ManifestInfo = new ConfigurationSetting> - { - Source = SettingSource.Default, - Value = new List - { Constants.TestManifestInfo } - }, - Verbosity = new ConfigurationSetting - { - Source = SettingSource.Default, - Value = Serilog.Events.LogEventLevel.Information - } - }; - } - - [TestMethod] - public void SetValueForManifestInfoForValidation_Succeeds() - { - var config = GetConfigurationBaseObject(); - config.ManifestToolAction = ManifestToolActions.Validate; - configSanitizer.SanitizeConfig(config); - - mockAssemblyConfig.Verify(); - } - - [TestMethod] - public void NoValueForManifestInfoForValidation_Throws() - { - var config = GetConfigurationBaseObject(); - config.ManifestToolAction = ManifestToolActions.Validate; - config.ManifestInfo.Value.Clear(); - - Assert.ThrowsException(() => configSanitizer.SanitizeConfig(config)); - } - - [TestMethod] - public void NoValueForBuildDropPathForRedaction_Succeeds() - { - var config = GetConfigurationBaseObject(); - config.ManifestToolAction = ManifestToolActions.Redact; - config.BuildDropPath = null; - - configSanitizer.SanitizeConfig(config); - } - - [TestMethod] - public void NoValueForBuildDropPathForValidateFormat_Succeeds() - { - var config = GetConfigurationBaseObject(); - config.ManifestToolAction = ManifestToolActions.ValidateFormat; - config.BuildDropPath = null; - config.SbomPath = new ConfigurationSetting - { - Source = SettingSource.Default, - Value = "any non empty value" - }; - - configSanitizer.SanitizeConfig(config); - } - - [TestMethod] - public void NoValueForSbomPathForValidateFormat_Throws() - { - var config = GetConfigurationBaseObject(); - config.ManifestToolAction = ManifestToolActions.ValidateFormat; - config.SbomPath = null; - - Assert.ThrowsException(() => configSanitizer.SanitizeConfig(config)); - } - - [TestMethod] - public void NoValueForManifestInfoForValidation_SetsDefaultValue() - { - var config = GetConfigurationBaseObject(); - config.ManifestToolAction = ManifestToolActions.Validate; - config.ManifestInfo.Value.Clear(); - mockAssemblyConfig.SetupGet(a => a.DefaultManifestInfoForValidationAction).Returns(Constants.TestManifestInfo); - - var sanitizedConfig = configSanitizer.SanitizeConfig(config); - - Assert.IsNotNull(sanitizedConfig.ManifestInfo.Value); - Assert.AreEqual(1, sanitizedConfig.ManifestInfo.Value.Count); - Assert.AreEqual(Constants.TestManifestInfo, sanitizedConfig.ManifestInfo.Value.First()); - - mockAssemblyConfig.VerifyGet(a => a.DefaultManifestInfoForValidationAction); - } - - [TestMethod] - public void ForGenerateActionIgnoresEmptyAlgorithmName_Succeeds() - { - var config = GetConfigurationBaseObject(); - config.HashAlgorithm = null; - config.ManifestToolAction = ManifestToolActions.Generate; - var sanitizedConfig = configSanitizer.SanitizeConfig(config); - - Assert.IsNull(sanitizedConfig.HashAlgorithm); - } - - [TestMethod] - public void ForValidateGetsRealAlgorithmName_Succeeds_DoesNotThrow() - { - var config = GetConfigurationBaseObject(); - config.ManifestToolAction = ManifestToolActions.Validate; - var sanitizedConfig = configSanitizer.SanitizeConfig(config); - - Assert.IsNotNull(sanitizedConfig.HashAlgorithm); - - var result = config.HashAlgorithm.Value.ComputeHash(TestUtils.GenerateStreamFromString("Hekki")); - Assert.IsNotNull(result); - } - - [TestMethod] - public void ForValidateBadAlgorithmNameGetsRealAlgorithmName_Throws() - { - var config = GetConfigurationBaseObject(); - config.HashAlgorithm.Value = new AlgorithmName("a", null); - config.ManifestToolAction = ManifestToolActions.Validate; - Assert.ThrowsException(() => configSanitizer.SanitizeConfig(config)); - } - - [TestMethod] - public void NullManifestDirShouldUseDropPath_Succeeds() - { - var config = GetConfigurationBaseObject(); - config.ManifestToolAction = ManifestToolActions.Validate; - config.ManifestDirPath = null; - configSanitizer.SanitizeConfig(config); - - Assert.IsNotNull(config.ManifestDirPath); - Assert.IsNotNull(config.ManifestDirPath.Value); - - var expectedPath = Path.Join("dropPath", "_manifest"); - Assert.AreEqual(Path.GetFullPath(expectedPath), Path.GetFullPath(config.ManifestDirPath.Value)); - } - - [TestMethod] - public void ManifestDirShouldEndWithManifestDirForGenerate_Succeeds() - { - var config = GetConfigurationBaseObject(); - config.ManifestDirPath = new ConfigurationSetting("manifestDirPath"); - - config.ManifestToolAction = ManifestToolActions.Generate; - configSanitizer.SanitizeConfig(config); - - Assert.IsNotNull(config.ManifestDirPath); - Assert.IsNotNull(config.ManifestDirPath.Value); - - var expectedPath = Path.Join("manifestDirPath", "_manifest"); - Assert.AreEqual(Path.GetFullPath(expectedPath), Path.GetFullPath(config.ManifestDirPath.Value)); - } - - [TestMethod] - public void ManifestDirShouldNotAddManifestDirForValidate_Succeeds() - { - var config = GetConfigurationBaseObject(); - config.ManifestDirPath = new ConfigurationSetting - { - Source = SettingSource.Default, - Value = "manifestDirPath" - }; - - config.ManifestToolAction = ManifestToolActions.Validate; - configSanitizer.SanitizeConfig(config); - - Assert.IsNotNull(config.ManifestDirPath); - Assert.IsNotNull(config.ManifestDirPath.Value); - Assert.AreEqual("manifestDirPath", config.ManifestDirPath.Value); - } - - [TestMethod] - public void NullDefaultNamespaceUriBaseShouldReturnExistingValue_Succeeds() - { - mockAssemblyConfig.SetupGet(a => a.DefaultSBOMNamespaceBaseUri).Returns(string.Empty); - var config = GetConfigurationBaseObject(); - config.NamespaceUriBase = new ConfigurationSetting - { - Source = SettingSource.Default, - Value = "http://base.uri" - }; - - config.ManifestToolAction = ManifestToolActions.Generate; - configSanitizer.SanitizeConfig(config); - - Assert.AreEqual("http://base.uri", config.NamespaceUriBase.Value); - - mockAssemblyConfig.VerifyGet(a => a.DefaultSBOMNamespaceBaseUri); - } - - [TestMethod] - public void UserProviderNamespaceUriBaseShouldReturnProvidedValue_Succeeds() - { - mockAssemblyConfig.SetupGet(a => a.DefaultSBOMNamespaceBaseUri).Returns("http://internal.base.uri"); - var providedNamespaceValue = "http://base.uri"; - var config = GetConfigurationBaseObject(); - config.NamespaceUriBase = new ConfigurationSetting - { - Source = SettingSource.CommandLine, - Value = providedNamespaceValue - }; - - config.ManifestToolAction = ManifestToolActions.Generate; - configSanitizer.SanitizeConfig(config); - - Assert.AreEqual(providedNamespaceValue, config.NamespaceUriBase.Value); - Assert.AreEqual(SettingSource.CommandLine, config.NamespaceUriBase.Source); - - mockAssemblyConfig.VerifyGet(a => a.DefaultSBOMNamespaceBaseUri); - } - - [TestMethod] - public void ShouldGetPackageSupplierFromAsseblyConfig_Succeeds() - { - var organization = "Contoso International"; - mockAssemblyConfig.SetupGet(a => a.DefaultPackageSupplier).Returns(organization); - var config = GetConfigurationBaseObject(); - - config.ManifestToolAction = ManifestToolActions.Validate; - configSanitizer.SanitizeConfig(config); - - Assert.AreEqual(organization, config.PackageSupplier.Value); - - mockAssemblyConfig.VerifyGet(a => a.DefaultPackageSupplier); - } - - [TestMethod] - public void ShouldNotOverridePackageSupplierIfProvided_Succeeds() - { - var organization = "Contoso International"; - var actualOrg = "Contoso"; - mockAssemblyConfig.SetupGet(a => a.DefaultPackageSupplier).Returns(organization); - var config = GetConfigurationBaseObject(); - config.PackageSupplier = new ConfigurationSetting - { - Source = SettingSource.CommandLine, - Value = actualOrg - }; - - config.ManifestToolAction = ManifestToolActions.Validate; - configSanitizer.SanitizeConfig(config); - - Assert.AreEqual(config.PackageSupplier.Value, actualOrg); - } - - [TestMethod] - [DataRow(ManifestToolActions.Validate)] - [DataRow(ManifestToolActions.Generate)] - public void ConfigSantizer_Validate_ReplacesBackslashes_Linux(ManifestToolActions action) - { - if (!isWindows) - { - var config = GetConfigurationBaseObject(); - config.ManifestDirPath = new($"\\{nameof(config.ManifestDirPath)}\\", SettingSource.Default); - config.BuildDropPath = new($"\\{nameof(config.BuildDropPath)}\\", SettingSource.Default); - config.OutputPath = new($"\\{nameof(config.OutputPath)}\\", SettingSource.Default); - config.ConfigFilePath = new($"\\{nameof(config.ConfigFilePath)}\\", SettingSource.Default); - config.RootPathFilter = new($"\\{nameof(config.RootPathFilter)}\\", SettingSource.Default); - config.BuildComponentPath = new($"\\{nameof(config.BuildComponentPath)}\\", SettingSource.Default); - config.CatalogFilePath = new($"\\{nameof(config.CatalogFilePath)}\\", SettingSource.Default); - config.TelemetryFilePath = new($"\\{nameof(config.TelemetryFilePath)}\\", SettingSource.Default); - - config.ManifestToolAction = action; - configSanitizer.SanitizeConfig(config); - - Assert.IsTrue(config.ManifestDirPath.Value.StartsWith($"/{nameof(config.ManifestDirPath)}/", StringComparison.Ordinal)); - Assert.IsTrue(config.BuildDropPath.Value.StartsWith($"/{nameof(config.BuildDropPath)}/", StringComparison.Ordinal)); - Assert.IsTrue(config.OutputPath.Value.StartsWith($"/{nameof(config.OutputPath)}/", StringComparison.Ordinal)); - Assert.IsTrue(config.ConfigFilePath.Value.StartsWith($"/{nameof(config.ConfigFilePath)}/", StringComparison.Ordinal)); - Assert.IsTrue(config.RootPathFilter.Value.StartsWith($"/{nameof(config.RootPathFilter)}/", StringComparison.Ordinal)); - Assert.IsTrue(config.BuildComponentPath.Value.StartsWith($"/{nameof(config.BuildComponentPath)}/", StringComparison.Ordinal)); - Assert.IsTrue(config.CatalogFilePath.Value.StartsWith($"/{nameof(config.CatalogFilePath)}/", StringComparison.Ordinal)); - Assert.IsTrue(config.TelemetryFilePath.Value.StartsWith($"/{nameof(config.TelemetryFilePath)}/", StringComparison.Ordinal)); - } - } - - [TestMethod] - [DataRow(1, DisplayName = "Minimum value of 1")] - [DataRow(Common.Constants.MaxLicenseFetchTimeoutInSeconds, DisplayName = "Maximum Value of 86400")] - public void LicenseInformationTimeoutInSeconds_SanitizeMakesNoChanges(int value) - { - var config = GetConfigurationBaseObject(); - config.LicenseInformationTimeoutInSeconds = new(value, SettingSource.CommandLine); - - configSanitizer.SanitizeConfig(config); - - Assert.AreEqual(value, config.LicenseInformationTimeoutInSeconds.Value, "The value of LicenseInformationTimeoutInSeconds should remain the same through the sanitization process"); - } - - [TestMethod] - [DataRow(int.MinValue, Common.Constants.DefaultLicenseFetchTimeoutInSeconds, DisplayName = "Negative Value is changed to Default")] - [DataRow(0, Common.Constants.DefaultLicenseFetchTimeoutInSeconds, DisplayName = "Zero is changed to Default")] - [DataRow(Common.Constants.MaxLicenseFetchTimeoutInSeconds + 1, Common.Constants.MaxLicenseFetchTimeoutInSeconds, DisplayName = "Max Value + 1 is truncated")] - [DataRow(int.MaxValue, Common.Constants.MaxLicenseFetchTimeoutInSeconds, DisplayName = "int.MaxValue is truncated")] - public void LicenseInformationTimeoutInSeconds_SanitizeExceedsLimits(int value, int expected) - { - var config = GetConfigurationBaseObject(); - config.LicenseInformationTimeoutInSeconds = new(value, SettingSource.CommandLine); - - configSanitizer.SanitizeConfig(config); - - Assert.AreEqual(expected, config.LicenseInformationTimeoutInSeconds.Value, "The value of LicenseInformationTimeoutInSeconds should be sanitized to a valid value"); - } - - [TestMethod] - public void LicenseInformationTimeoutInSeconds_SanitizeNull() - { - var config = GetConfigurationBaseObject(); - config.LicenseInformationTimeoutInSeconds = null; - - configSanitizer.SanitizeConfig(config); - - Assert.AreEqual( - Common.Constants.DefaultLicenseFetchTimeoutInSeconds, - config.LicenseInformationTimeoutInSeconds.Value, - $"The value of LicenseInformationTimeoutInSeconds should be set to {Common.Constants.DefaultLicenseFetchTimeoutInSeconds}s when null"); - - Assert.AreEqual(SettingSource.Default, config.LicenseInformationTimeoutInSeconds.Source, "The source of LicenseInformationTimeoutInSeconds should be set to Default when null"); - } -} diff --git a/test/Microsoft.Sbom.Api.Tests/Config/ConfigurationBuilderTestsBase.cs b/test/Microsoft.Sbom.Api.Tests/Config/ConfigurationBuilderTestsBase.cs deleted file mode 100644 index 13640dad..00000000 --- a/test/Microsoft.Sbom.Api.Tests/Config/ConfigurationBuilderTestsBase.cs +++ /dev/null @@ -1,67 +0,0 @@ -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -using System; -using AutoMapper; -using Microsoft.Sbom.Api.Config.Validators; -using Microsoft.Sbom.Api.Hashing; -using Microsoft.Sbom.Api.Utils; -using Microsoft.Sbom.Common; -using Microsoft.Sbom.Common.Config.Validators; -using Microsoft.Sbom.Contracts.Entities; -using Microsoft.Sbom.Contracts.Interfaces; -using Moq; -using Constants = Microsoft.Sbom.Api.Utils.Constants; - -namespace Microsoft.Sbom.Api.Config.Tests; - -public class ConfigurationBuilderTestsBase -{ - protected Mock fileSystemUtilsMock; - protected private IMapper mapper; - protected ConfigValidator[] configValidators; - protected Mock mockAssemblyConfig; - - protected void Init() - { - fileSystemUtilsMock = new Mock(); - mockAssemblyConfig = new Mock(); - mockAssemblyConfig.SetupGet(a => a.DefaultManifestInfoForValidationAction).Returns(Constants.TestManifestInfo); - - configValidators = new ConfigValidator[] - { - new ValueRequiredValidator(mockAssemblyConfig.Object), - new FilePathIsWritableValidator(fileSystemUtilsMock.Object, mockAssemblyConfig.Object), - new IntRangeValidator(mockAssemblyConfig.Object), - new FileExistsValidator(fileSystemUtilsMock.Object, mockAssemblyConfig.Object), - new DirectoryExistsValidator(fileSystemUtilsMock.Object, mockAssemblyConfig.Object), - new DirectoryPathIsWritableValidator(fileSystemUtilsMock.Object, mockAssemblyConfig.Object), - new UriValidator(mockAssemblyConfig.Object) - }; - - var hashAlgorithmProvider = new HashAlgorithmProvider(new IAlgorithmNames[] { new AlgorithmNames() }); - hashAlgorithmProvider.Init(); - - var configSanitizer = new ConfigSanitizer(hashAlgorithmProvider, fileSystemUtilsMock.Object, mockAssemblyConfig.Object); - object Ctor(Type type) - { - if (type == typeof(ConfigPostProcessor)) - { - return new ConfigPostProcessor(configValidators, configSanitizer, fileSystemUtilsMock.Object); - } - - return Activator.CreateInstance(type); - } - - var mapperConfiguration = new MapperConfiguration(cfg => - { - cfg.ConstructServicesUsing(Ctor); - cfg.AddProfile(); - }); - - mapper = mapperConfiguration.CreateMapper(); - } - - protected const string JSONConfigWithManifestPath = $"{{ \"ManifestDirPath\": \"manifestDirPath\"}}"; - protected const string JSONConfigGoodWithManifestInfo = $"{{ \"ManifestInfo\": [{{ \"Name\":\"manifest\", \"Version\":\"1\"}}]}}"; -} diff --git a/test/Microsoft.Sbom.Api.Tests/Config/ConfigurationBuilderTestsForGeneration.cs b/test/Microsoft.Sbom.Api.Tests/Config/ConfigurationBuilderTestsForGeneration.cs deleted file mode 100644 index faf1dacc..00000000 --- a/test/Microsoft.Sbom.Api.Tests/Config/ConfigurationBuilderTestsForGeneration.cs +++ /dev/null @@ -1,298 +0,0 @@ -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -using System.IO; -using System.Threading.Tasks; -using Microsoft.Sbom.Api.Config.Args; -using Microsoft.Sbom.Api.Exceptions; -using Microsoft.Sbom.Api.Tests; -using Microsoft.Sbom.Api.Utils; -using Microsoft.Sbom.Common.Config; -using Microsoft.VisualStudio.TestTools.UnitTesting; -using Moq; -using PowerArgs; - -namespace Microsoft.Sbom.Api.Config.Tests; - -[TestClass] -public class ConfigurationBuilderTestsForGeneration : ConfigurationBuilderTestsBase -{ - [TestInitialize] - public void Setup() - { - Init(); - } - - [TestMethod] - public async Task ConfigurationBuilderTest_ForGenerator_CombinesConfigs() - { - var configFileParser = new ConfigFileParser(fileSystemUtilsMock.Object); - var cb = new ConfigurationBuilder(mapper, configFileParser); - - fileSystemUtilsMock.Setup(f => f.OpenRead(It.IsAny())).Returns(TestUtils.GenerateStreamFromString(JSONConfigGoodWithManifestInfo)); - fileSystemUtilsMock.Setup(f => f.DirectoryExists(It.IsAny())).Returns(true).Verifiable(); - fileSystemUtilsMock.Setup(f => f.DirectoryHasReadPermissions(It.IsAny())).Returns(true).Verifiable(); - fileSystemUtilsMock.Setup(f => f.DirectoryHasWritePermissions(It.IsAny())).Returns(true).Verifiable(); - fileSystemUtilsMock.Setup(f => f.JoinPaths(It.IsAny(), It.IsAny())).Returns(Path.Join(It.IsAny(), It.IsAny())).Verifiable(); - - var args = new GenerationArgs - { - BuildDropPath = "BuildDropPath", - ConfigFilePath = "config.json", - NamespaceUriBase = "https://base.uri", - PackageSupplier = "Contoso" - }; - - var configuration = await cb.GetConfiguration(args); - - Assert.AreEqual(SettingSource.CommandLine, configuration.BuildDropPath.Source); - Assert.AreEqual(SettingSource.CommandLine, configuration.ConfigFilePath.Source); - Assert.AreEqual(SettingSource.JsonConfig, configuration.ManifestInfo.Source); - - fileSystemUtilsMock.VerifyAll(); - } - - [TestMethod] - public async Task ConfigurationBuilderTest_ForGenerator_CombinesConfigs_CmdLineSucceeds() - { - var configFileParser = new ConfigFileParser(fileSystemUtilsMock.Object); - var cb = new ConfigurationBuilder(mapper, configFileParser); - - fileSystemUtilsMock.Setup(f => f.OpenRead(It.IsAny())).Returns(TestUtils.GenerateStreamFromString(JSONConfigGoodWithManifestInfo)); - fileSystemUtilsMock.Setup(f => f.DirectoryExists(It.IsAny())).Returns(true).Verifiable(); - fileSystemUtilsMock.Setup(f => f.DirectoryHasReadPermissions(It.IsAny())).Returns(true).Verifiable(); - fileSystemUtilsMock.Setup(f => f.DirectoryHasWritePermissions(It.IsAny())).Returns(true).Verifiable(); - fileSystemUtilsMock.Setup(f => f.JoinPaths(It.IsAny(), It.IsAny())).Returns(Path.Join(It.IsAny(), It.IsAny())).Verifiable(); - - var args = new GenerationArgs - { - BuildDropPath = "BuildDropPath", - ConfigFilePath = "config.json", - NamespaceUriBase = "https://base.uri", - PackageSupplier = "Contoso" - }; - - var configuration = await cb.GetConfiguration(args); - - Assert.AreEqual(SettingSource.CommandLine, configuration.BuildDropPath.Source); - Assert.AreEqual(SettingSource.CommandLine, configuration.ConfigFilePath.Source); - Assert.AreEqual(SettingSource.JsonConfig, configuration.ManifestInfo.Source); - - fileSystemUtilsMock.VerifyAll(); - } - - [TestMethod] - public async Task ConfigurationBuilderTest_Generation_BuildDropPathDoNotExist_Throws() - { - var configFileParser = new ConfigFileParser(fileSystemUtilsMock.Object); - var cb = new ConfigurationBuilder(mapper, configFileParser); - - fileSystemUtilsMock.Setup(f => f.DirectoryExists(It.IsAny())).Returns(false); - - var args = new GenerationArgs - { - BuildDropPath = "BuildDropPath", - NamespaceUriBase = "https://base.uri", - PackageSupplier = "Contoso" - }; - - await Assert.ThrowsExceptionAsync(() => cb.GetConfiguration(args)); - } - - [TestMethod] - public async Task ConfigurationBuilderTest_Generation_BuildDropPathNotWriteAccess_Throws() - { - var configFileParser = new ConfigFileParser(fileSystemUtilsMock.Object); - var cb = new ConfigurationBuilder(mapper, configFileParser); - - fileSystemUtilsMock.Setup(f => f.DirectoryExists(It.IsAny())).Returns(true); - fileSystemUtilsMock.Setup(f => f.DirectoryHasReadPermissions(It.IsAny())).Returns(true); - fileSystemUtilsMock.Setup(f => f.DirectoryHasWritePermissions(It.IsAny())).Returns(false); - - var args = new GenerationArgs - { - BuildDropPath = "BuildDropPath", - NamespaceUriBase = "https://base.uri", - PackageSupplier = "Contoso" - }; - - await Assert.ThrowsExceptionAsync(() => cb.GetConfiguration(args)); - } - - [TestMethod] - public async Task ConfigurationBuilderTest_Generation_DefaultManifestDirPath_AddsManifestDir() - { - var configFileParser = new ConfigFileParser(fileSystemUtilsMock.Object); - var cb = new ConfigurationBuilder(mapper, configFileParser); - - fileSystemUtilsMock.Setup(f => f.DirectoryExists(It.IsAny())).Returns(true); - fileSystemUtilsMock.Setup(f => f.DirectoryHasReadPermissions(It.IsAny())).Returns(true); - fileSystemUtilsMock.Setup(f => f.DirectoryHasWritePermissions(It.IsAny())).Returns(true); - fileSystemUtilsMock.Setup(f => f.JoinPaths(It.IsAny(), It.IsAny())).Returns((string p1, string p2) => Path.Join(p1, p2)); - - var args = new GenerationArgs - { - BuildDropPath = "BuildDropPath", - NamespaceUriBase = "https://base.uri", - PackageSupplier = "Contoso" - }; - - var config = await cb.GetConfiguration(args); - - Assert.IsNotNull(config); - Assert.IsNotNull(config.ManifestDirPath); - - var expectedPath = Path.Join(args.BuildDropPath, Constants.ManifestFolder); - Assert.AreEqual(Path.GetFullPath(expectedPath), Path.GetFullPath(config.ManifestDirPath.Value)); - - fileSystemUtilsMock.VerifyAll(); - } - - [TestMethod] - public async Task ConfigurationBuilderTest_Generation_UserManifestDirPath_AddsManifestDir() - { - var configFileParser = new ConfigFileParser(fileSystemUtilsMock.Object); - var cb = new ConfigurationBuilder(mapper, configFileParser); - - fileSystemUtilsMock.Setup(f => f.DirectoryExists(It.IsAny())).Returns(true); - fileSystemUtilsMock.Setup(f => f.DirectoryHasReadPermissions(It.IsAny())).Returns(true); - fileSystemUtilsMock.Setup(f => f.DirectoryHasWritePermissions(It.IsAny())).Returns(true); - fileSystemUtilsMock.Setup(f => f.JoinPaths(It.IsAny(), It.IsAny())).Returns((string p1, string p2) => Path.Join(p1, p2)); - - var args = new GenerationArgs - { - BuildDropPath = "BuildDropPath", - ManifestDirPath = "ManifestDirPath", - NamespaceUriBase = "https://base.uri", - PackageSupplier = "Contoso" - }; - - var config = await cb.GetConfiguration(args); - - Assert.IsNotNull(config); - Assert.IsNotNull(config.ManifestDirPath); - - var expectedPath = Path.Join("ManifestDirPath", Constants.ManifestFolder); - Assert.AreEqual(Path.GetFullPath(config.ManifestDirPath.Value), Path.GetFullPath(expectedPath)); - - fileSystemUtilsMock.VerifyAll(); - } - - [TestMethod] - public async Task ConfigurationBuilderTest_Generation_NSBaseUri_Validated() - { - var configFileParser = new ConfigFileParser(fileSystemUtilsMock.Object); - var cb = new ConfigurationBuilder(mapper, configFileParser); - - fileSystemUtilsMock.Setup(f => f.DirectoryExists(It.IsAny())).Returns(true); - fileSystemUtilsMock.Setup(f => f.DirectoryHasReadPermissions(It.IsAny())).Returns(true); - fileSystemUtilsMock.Setup(f => f.DirectoryHasWritePermissions(It.IsAny())).Returns(true); - fileSystemUtilsMock.Setup(f => f.JoinPaths(It.IsAny(), It.IsAny())).Returns((string p1, string p2) => Path.Join(p1, p2)); - - var args = new GenerationArgs - { - BuildDropPath = "BuildDropPath", - ManifestDirPath = "ManifestDirPath", - NamespaceUriBase = "https://base.uri", - PackageSupplier = "Contoso" - }; - - var config = await cb.GetConfiguration(args); - - Assert.IsNotNull(config); - Assert.IsNotNull(config.ManifestDirPath); - - var expectedPath = Path.Join("ManifestDirPath", Constants.ManifestFolder); - Assert.AreEqual(Path.GetFullPath(config.ManifestDirPath.Value), Path.GetFullPath(expectedPath)); - - fileSystemUtilsMock.VerifyAll(); - } - - [TestMethod] - public async Task ConfigurationBuilderTest_Generation_BadNSBaseUriWithDefaultValue_Succeds() - { - var configFileParser = new ConfigFileParser(fileSystemUtilsMock.Object); - var cb = new ConfigurationBuilder(mapper, configFileParser); - - mockAssemblyConfig.SetupGet(a => a.DefaultSBOMNamespaceBaseUri).Returns("https://uri"); - - fileSystemUtilsMock.Setup(f => f.DirectoryExists(It.IsAny())).Returns(true); - fileSystemUtilsMock.Setup(f => f.DirectoryHasReadPermissions(It.IsAny())).Returns(true); - fileSystemUtilsMock.Setup(f => f.DirectoryHasWritePermissions(It.IsAny())).Returns(true); - fileSystemUtilsMock.Setup(f => f.JoinPaths(It.IsAny(), It.IsAny())).Returns((string p1, string p2) => Path.Join(p1, p2)); - - var args = new GenerationArgs - { - BuildDropPath = "BuildDropPath", - ManifestDirPath = "ManifestDirPath", - NamespaceUriBase = "baduri", - PackageSupplier = "Contoso" - }; - - var config = await cb.GetConfiguration(args); - - Assert.IsNotNull(config); - Assert.IsNotNull(config.ManifestDirPath); - - var expectedPath = Path.Join("ManifestDirPath", Constants.ManifestFolder); - Assert.AreEqual(Path.GetFullPath(config.ManifestDirPath.Value), Path.GetFullPath(expectedPath)); - - fileSystemUtilsMock.VerifyAll(); - mockAssemblyConfig.VerifyGet(a => a.DefaultSBOMNamespaceBaseUri); - } - - [TestMethod] - public async Task ConfigurationBuilderTest_Generation_NullNSBaseUriChangesToDefault() - { - var configFileParser = new ConfigFileParser(fileSystemUtilsMock.Object); - var cb = new ConfigurationBuilder(mapper, configFileParser); - - fileSystemUtilsMock.Setup(f => f.DirectoryExists(It.IsAny())).Returns(true); - fileSystemUtilsMock.Setup(f => f.DirectoryHasReadPermissions(It.IsAny())).Returns(true); - fileSystemUtilsMock.Setup(f => f.DirectoryHasWritePermissions(It.IsAny())).Returns(true); - fileSystemUtilsMock.Setup(f => f.JoinPaths(It.IsAny(), It.IsAny())).Returns((string p1, string p2) => Path.Join(p1, p2)); - - var args = new GenerationArgs - { - BuildDropPath = "BuildDropPath", - ManifestDirPath = "ManifestDirPath", - NamespaceUriBase = null, - PackageSupplier = "Contoso" - }; - - var config = await cb.GetConfiguration(args); - - Assert.IsNotNull(config); - Assert.IsNotNull(args.ManifestDirPath); - Assert.IsNotNull(config.NamespaceUriBase); - Assert.AreEqual(config.ManifestDirPath.Value, Path.Join("ManifestDirPath", Constants.ManifestFolder)); - - fileSystemUtilsMock.VerifyAll(); - } - - [TestMethod] - [DataRow("baduri")] - [DataRow("https://")] - [DataRow("ww.com")] - [DataRow("https//test.com")] - public async Task ConfigurationBuilderTest_Generation_BadNSBaseUri_Fails(string badNsUri) - { - var configFileParser = new ConfigFileParser(fileSystemUtilsMock.Object); - var cb = new ConfigurationBuilder(mapper, configFileParser); - - fileSystemUtilsMock.Setup(f => f.DirectoryExists(It.IsAny())).Returns(true); - fileSystemUtilsMock.Setup(f => f.DirectoryHasReadPermissions(It.IsAny())).Returns(true); - fileSystemUtilsMock.Setup(f => f.DirectoryHasWritePermissions(It.IsAny())).Returns(true); - fileSystemUtilsMock.Setup(f => f.JoinPaths(It.IsAny(), It.IsAny())).Returns((string p1, string p2) => Path.Join(p1, p2)); - - var args = new GenerationArgs - { - BuildDropPath = "BuildDropPath", - ManifestDirPath = "ManifestDirPath", - NamespaceUriBase = badNsUri, - PackageSupplier = "Contoso" - }; - - await Assert.ThrowsExceptionAsync(() => cb.GetConfiguration(args), "The value of NamespaceUriBase must be a valid URI."); - } -} diff --git a/test/Microsoft.Sbom.Api.Tests/Config/ConfigurationBuilderTestsForRedact.cs b/test/Microsoft.Sbom.Api.Tests/Config/ConfigurationBuilderTestsForRedact.cs deleted file mode 100644 index 3eb8f91c..00000000 --- a/test/Microsoft.Sbom.Api.Tests/Config/ConfigurationBuilderTestsForRedact.cs +++ /dev/null @@ -1,66 +0,0 @@ -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -using System.IO; -using System.Threading.Tasks; -using Microsoft.Sbom.Api.Config.Args; -using Microsoft.Sbom.Common.Config; -using Microsoft.VisualStudio.TestTools.UnitTesting; -using Moq; -using PowerArgs; - -namespace Microsoft.Sbom.Api.Config.Tests; - -[TestClass] -public class ConfigurationBuilderTestsForRedact : ConfigurationBuilderTestsBase -{ - [TestInitialize] - public void Setup() - { - Init(); - } - - [TestMethod] - public async Task ConfigurationBuilderTest_ForRedact_CombinesConfigs() - { - var configFileParser = new ConfigFileParser(fileSystemUtilsMock.Object); - var cb = new ConfigurationBuilder(mapper, configFileParser); - - fileSystemUtilsMock.Setup(f => f.DirectoryExists(It.IsAny())).Returns(true).Verifiable(); - fileSystemUtilsMock.Setup(f => f.DirectoryHasReadPermissions(It.IsAny())).Returns(true).Verifiable(); - fileSystemUtilsMock.Setup(f => f.DirectoryHasWritePermissions(It.IsAny())).Returns(true).Verifiable(); - fileSystemUtilsMock.Setup(f => f.JoinPaths(It.IsAny(), It.IsAny())).Returns(Path.Join(It.IsAny(), It.IsAny())).Verifiable(); - - var args = new RedactArgs - { - SbomDir = "SbomDir", - OutputPath = "OutputPath" - }; - - var configuration = await cb.GetConfiguration(args); - - Assert.AreEqual(SettingSource.CommandLine, configuration.SbomDir.Source); - Assert.AreEqual(SettingSource.CommandLine, configuration.OutputPath.Source); - - fileSystemUtilsMock.VerifyAll(); - } - - [TestMethod] - public async Task ConfigurationBuilderTest_Redact_OuputPathNotWriteAccess_Throws() - { - var configFileParser = new ConfigFileParser(fileSystemUtilsMock.Object); - var cb = new ConfigurationBuilder(mapper, configFileParser); - - fileSystemUtilsMock.Setup(f => f.DirectoryExists(It.IsAny())).Returns(true); - fileSystemUtilsMock.Setup(f => f.DirectoryHasReadPermissions(It.IsAny())).Returns(true); - fileSystemUtilsMock.Setup(f => f.DirectoryHasWritePermissions(It.IsAny())).Returns(false); - - var args = new RedactArgs - { - SbomDir = "SbomDir", - OutputPath = "OutputPath" - }; - - await Assert.ThrowsExceptionAsync(() => cb.GetConfiguration(args)); - } -} diff --git a/test/Microsoft.Sbom.Api.Tests/Config/ConfigurationBuilderTestsForValidation.cs b/test/Microsoft.Sbom.Api.Tests/Config/ConfigurationBuilderTestsForValidation.cs deleted file mode 100644 index b9df8298..00000000 --- a/test/Microsoft.Sbom.Api.Tests/Config/ConfigurationBuilderTestsForValidation.cs +++ /dev/null @@ -1,182 +0,0 @@ -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -using System.IO; -using System.Threading.Tasks; -using AutoMapper; -using Microsoft.Sbom.Api.Config.Args; -using Microsoft.Sbom.Api.Tests; -using Microsoft.Sbom.Common.Config; -using Microsoft.Sbom.Contracts.Enums; -using Microsoft.VisualStudio.TestTools.UnitTesting; -using Moq; -using PowerArgs; -using Constants = Microsoft.Sbom.Api.Utils.Constants; - -namespace Microsoft.Sbom.Api.Config.Tests; - -[TestClass] -public class ConfigurationBuilderTestsForValidation : ConfigurationBuilderTestsBase -{ - [TestInitialize] - public void Setup() - { - Init(); - } - - [TestMethod] - public async Task ConfigurationBuilderTest_CombinesConfigs() - { - var configFileParser = new ConfigFileParser(fileSystemUtilsMock.Object); - var cb = new ConfigurationBuilder(mapper, configFileParser); - - fileSystemUtilsMock.Setup(f => f.OpenRead(It.IsAny())).Returns(TestUtils.GenerateStreamFromString(JSONConfigWithManifestPath)).Verifiable(); - fileSystemUtilsMock.Setup(f => f.DirectoryExists(It.IsAny())).Returns(true).Verifiable(); - fileSystemUtilsMock.Setup(f => f.DirectoryHasReadPermissions(It.IsAny())).Returns(true).Verifiable(); - fileSystemUtilsMock.Setup(f => f.GetDirectoryName(It.IsAny())).Returns("test").Verifiable(); - fileSystemUtilsMock.Setup(f => f.DirectoryHasWritePermissions(It.IsAny())).Returns(true).Verifiable(); - - var args = new ValidationArgs - { - BuildDropPath = "BuildDropPath", - ConfigFilePath = "config.json", - OutputPath = "Test", - HashAlgorithm = AlgorithmName.SHA512 - }; - - var configuration = await cb.GetConfiguration(args); - - Assert.AreEqual(SettingSource.CommandLine, configuration.BuildDropPath.Source); - Assert.AreEqual(SettingSource.CommandLine, configuration.ConfigFilePath.Source); - Assert.AreEqual(SettingSource.CommandLine, configuration.OutputPath.Source); - Assert.AreEqual(SettingSource.Default, configuration.Parallelism.Source); - Assert.AreEqual(Common.Constants.DefaultParallelism, configuration.Parallelism.Value); - Assert.AreEqual(SettingSource.CommandLine, configuration.HashAlgorithm.Source); - Assert.AreEqual(configuration.HashAlgorithm.Value, AlgorithmName.SHA512); - - fileSystemUtilsMock.VerifyAll(); - } - - [TestMethod] - public async Task ConfigurationBuilderTest_CombinesConfigs_DuplicateConfig_DefaultLoses() - { - var configFileParser = new ConfigFileParser(fileSystemUtilsMock.Object); - var cb = new ConfigurationBuilder(mapper, configFileParser); - - fileSystemUtilsMock.Setup(f => f.OpenRead(It.IsAny())).Returns(TestUtils.GenerateStreamFromString(JSONConfigWithManifestPath)).Verifiable(); - fileSystemUtilsMock.Setup(f => f.DirectoryExists(It.IsAny())).Returns(true).Verifiable(); - fileSystemUtilsMock.Setup(f => f.DirectoryHasReadPermissions(It.IsAny())).Returns(true).Verifiable(); - fileSystemUtilsMock.Setup(f => f.GetDirectoryName(It.IsAny())).Returns("test").Verifiable(); - fileSystemUtilsMock.Setup(f => f.DirectoryHasWritePermissions(It.IsAny())).Returns(true).Verifiable(); - - var args = new ValidationArgs - { - BuildDropPath = "BuildDropPath", - ConfigFilePath = "config.json", - OutputPath = "Test", - Parallelism = 4, - Verbosity = Serilog.Events.LogEventLevel.Fatal - }; - - var configuration = await cb.GetConfiguration(args); - - Assert.AreEqual(SettingSource.CommandLine, configuration.BuildDropPath.Source); - Assert.AreEqual(SettingSource.CommandLine, configuration.ConfigFilePath.Source); - Assert.AreEqual(SettingSource.CommandLine, configuration.OutputPath.Source); - Assert.AreEqual(SettingSource.CommandLine, configuration.Parallelism.Source); - Assert.AreEqual(Serilog.Events.LogEventLevel.Fatal, configuration.Verbosity.Value); - Assert.AreEqual(SettingSource.CommandLine, configuration.Verbosity.Source); - - fileSystemUtilsMock.VerifyAll(); - } - - [TestMethod] - public async Task ConfigurationBuilderTest_CombinesConfigs_DuplicateConfig_Throws() - { - var configFileParser = new ConfigFileParser(fileSystemUtilsMock.Object); - var cb = new ConfigurationBuilder(mapper, configFileParser); - - fileSystemUtilsMock.Setup(f => f.OpenRead(It.IsAny())).Returns(TestUtils.GenerateStreamFromString(JSONConfigWithManifestPath)); - - var args = new ValidationArgs - { - BuildDropPath = "BuildDropPath", - ConfigFilePath = "config.json", - OutputPath = "Test", - ManifestDirPath = "ManifestPath" - }; - - await Assert.ThrowsExceptionAsync(() => cb.GetConfiguration(args)); - } - - [TestMethod] - public async Task ConfigurationBuilderTest_CombinesConfigs_NegativeParallism_Throws() - { - var configFileParser = new ConfigFileParser(fileSystemUtilsMock.Object); - var cb = new ConfigurationBuilder(mapper, configFileParser); - - fileSystemUtilsMock.Setup(f => f.OpenRead(It.IsAny())).Returns(TestUtils.GenerateStreamFromString(JSONConfigWithManifestPath)); - - var args = new ValidationArgs - { - BuildDropPath = "BuildDropPath", - ConfigFilePath = "config.json", - OutputPath = "Test", - Parallelism = -1 - }; - - await Assert.ThrowsExceptionAsync(() => cb.GetConfiguration(args)); - } - - [TestMethod] - public async Task ConfigurationBuilderTest_Validation_DefaultManifestDirPath_AddsManifestDir() - { - var configFileParser = new ConfigFileParser(fileSystemUtilsMock.Object); - var cb = new ConfigurationBuilder(mapper, configFileParser); - - fileSystemUtilsMock.Setup(f => f.DirectoryExists(It.IsAny())).Returns(true).Verifiable(); - fileSystemUtilsMock.Setup(f => f.DirectoryHasReadPermissions(It.IsAny())).Returns(true).Verifiable(); - fileSystemUtilsMock.Setup(f => f.DirectoryHasWritePermissions(It.IsAny())).Returns(true).Verifiable(); - fileSystemUtilsMock.Setup(f => f.JoinPaths(It.IsAny(), It.IsAny())).Returns((string p1, string p2) => Path.Join(p1, p2)); - - var args = new ValidationArgs - { - OutputPath = "Test", - BuildDropPath = "BuildDropPath" - }; - - var config = await cb.GetConfiguration(args); - - Assert.IsNotNull(config); - Assert.IsNotNull(config.ManifestDirPath); - Assert.AreEqual(Path.Join("BuildDropPath", Constants.ManifestFolder), config.ManifestDirPath.Value); - - fileSystemUtilsMock.VerifyAll(); - } - - [TestMethod] - public async Task ConfigurationBuilderTest_Validation_UserManifestDirPath_DoesntManifestDir() - { - var configFileParser = new ConfigFileParser(fileSystemUtilsMock.Object); - var cb = new ConfigurationBuilder(mapper, configFileParser); - - fileSystemUtilsMock.Setup(f => f.DirectoryExists(It.IsAny())).Returns(true).Verifiable(); - fileSystemUtilsMock.Setup(f => f.DirectoryHasReadPermissions(It.IsAny())).Returns(true).Verifiable(); - fileSystemUtilsMock.Setup(f => f.DirectoryHasWritePermissions(It.IsAny())).Returns(true).Verifiable(); - - var args = new ValidationArgs - { - OutputPath = "Test", - BuildDropPath = "BuildDropPath", - ManifestDirPath = "ManifestDirPath" - }; - - var config = await cb.GetConfiguration(args); - - Assert.IsNotNull(config); - Assert.IsNotNull(config.ManifestDirPath); - Assert.AreEqual("ManifestDirPath", config.ManifestDirPath.Value); - - fileSystemUtilsMock.VerifyAll(); - } -} diff --git a/test/Microsoft.Sbom.Api.Tests/Config/ConfigurationCLITests.cs b/test/Microsoft.Sbom.Api.Tests/Config/ConfigurationCLITests.cs deleted file mode 100644 index 47d2f876..00000000 --- a/test/Microsoft.Sbom.Api.Tests/Config/ConfigurationCLITests.cs +++ /dev/null @@ -1,61 +0,0 @@ -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -using Microsoft.Sbom.Api.Config.Extensions; -using Microsoft.Sbom.Api.Utils; -using Microsoft.Sbom.Common.Config; -using Microsoft.VisualStudio.TestTools.UnitTesting; -using Moq; - -namespace Microsoft.Sbom.Api.Tests.Config; - -[TestClass] -public class ConfigurationCLITests -{ - private Mock mockConfiguration; - - [TestInitialize] - public void Setup() - { - mockConfiguration = new Mock(); - } - - [TestMethod] - public void Configuration_CommandLineParams() - { - // A property that is not a ComponentDetectorArgument - mockConfiguration.SetupProperty(c => c.BuildComponentPath, new ConfigurationSetting { Value = "build_component_path" }); - - // A named ComponentDetectorArgument - mockConfiguration.SetupProperty(c => c.DockerImagesToScan, new ConfigurationSetting { Value = "the_docker_image" }); - - // An unnamed ComponentDetectorArgument - mockConfiguration.SetupProperty(c => c.AdditionalComponentDetectorArgs, new ConfigurationSetting { Value = "--arg1 val1 --arg2 val2" }); - - var config = mockConfiguration.Object; - - var argBuilder = new ComponentDetectionCliArgumentBuilder() - .SourceDirectory("X:/") - .AddArg("defaultArg1", "val1") - .AddArg("defaultArg2", "val2"); - - var commandLineParams = config.ToComponentDetectorCommandLineParams(argBuilder); - - Assert.AreEqual("--SourceDirectory X:/ --DetectorArgs Timeout=900 --defaultArg1 val1 --defaultArg2 val2 --DockerImagesToScan the_docker_image --arg1 val1 --arg2 val2", string.Join(" ", commandLineParams)); - } - - [TestMethod] - public void Configuration_CommandLineParams_DefaultArgsOnly() - { - var config = mockConfiguration.Object; - - var argBuilder = new ComponentDetectionCliArgumentBuilder() - .SourceDirectory("X:/") - .AddArg("defaultArg1", "val1") - .AddArg("defaultArg2", "val2"); - - var commandLineParams = config.ToComponentDetectorCommandLineParams(argBuilder); - - Assert.AreEqual("--SourceDirectory X:/ --DetectorArgs Timeout=900 --defaultArg1 val1 --defaultArg2 val2", string.Join(" ", commandLineParams)); - } -} diff --git a/test/Microsoft.Sbom.Api.Tests/Config/SBOMConfigTests.cs b/test/Microsoft.Sbom.Api.Tests/Config/SBOMConfigTests.cs deleted file mode 100644 index 1b122ee5..00000000 --- a/test/Microsoft.Sbom.Api.Tests/Config/SBOMConfigTests.cs +++ /dev/null @@ -1,96 +0,0 @@ -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -using Microsoft.Sbom.Api.Manifest.Configuration; -using Microsoft.Sbom.Api.Metadata; -using Microsoft.Sbom.Api.Output.Telemetry; -using Microsoft.Sbom.Common.Config; -using Microsoft.Sbom.Contracts; -using Microsoft.Sbom.Extensions; -using Microsoft.VisualStudio.TestTools.UnitTesting; -using Moq; -using Serilog; - -namespace Microsoft.Sbom.Api.Tests.Config; - -[TestClass] -public class SBOMConfigTests -{ - private readonly Mock configHandler; - private readonly Configuration config; - private readonly Mock logger; - private readonly Mock recorder; - private readonly LocalMetadataProvider localMetadataProvider; - - public SBOMConfigTests() - { - configHandler = new Mock(); - config = new Configuration - { - PackageName = new ConfigurationSetting("the-package-name"), - PackageVersion = new ConfigurationSetting("the-package-version"), - NamespaceUriUniquePart = new ConfigurationSetting("some-custom-value-here"), - NamespaceUriBase = new ConfigurationSetting("http://sbom.microsoft") - }; - - logger = new Mock(); - recorder = new Mock(); - localMetadataProvider = new LocalMetadataProvider(config); - } - - [TestMethod] - public void SBOMConfig_DefaultMetadataProvider_Returned() - { - var metadataProviders = new IMetadataProvider[] { localMetadataProvider }; - var sbomConfigs = CreateSbomConfigs(metadataProviders); - - var uri = sbomConfigs.GetSBOMNamespaceUri(); - - Assert.AreEqual(localMetadataProvider.GetDocumentNamespaceUri(), uri); - } - - [TestMethod] - public void SBOMConfig_BuildEnvironmentMetadataProvider_Returned() - { - var sbomMetadata = new SBOMMetadata - { - PackageName = "sbom-package-name", - PackageVersion = "sbom-package-version", - BuildEnvironmentName = "the-build-envsdfgsdg" - }; - - var sbomApiMetadataProvider = new SBOMApiMetadataProvider(sbomMetadata, config); - var metadataProviders = new IMetadataProvider[] { localMetadataProvider, sbomApiMetadataProvider }; - var sbomConfigs = CreateSbomConfigs(metadataProviders); - - var uri = sbomConfigs.GetSBOMNamespaceUri(); - - Assert.AreEqual(sbomApiMetadataProvider.GetDocumentNamespaceUri(), uri); - } - - [TestMethod] - public void SBOMConfig_NoBuildEnvironmentName_DefaultMetadataProvider_Returned() - { - var sbomMetadata = new SBOMMetadata - { - PackageName = "sbom-package-name", - PackageVersion = "sbom-package-version", - BuildEnvironmentName = null - }; - - var sbomApiMetadataProvider = new SBOMApiMetadataProvider(sbomMetadata, config); - var metadataProviders = new IMetadataProvider[] { localMetadataProvider, sbomApiMetadataProvider }; - var sbomConfigs = CreateSbomConfigs(metadataProviders); - - var uri = sbomConfigs.GetSBOMNamespaceUri(); - - Assert.AreEqual(localMetadataProvider.GetDocumentNamespaceUri(), uri); - } - - private ISbomConfigProvider CreateSbomConfigs(IMetadataProvider[] metadataProviders) => - new SbomConfigProvider( - manifestConfigHandlers: new IManifestConfigHandler[] { configHandler.Object }, - metadataProviders: metadataProviders, - logger: logger.Object, - recorder: recorder.Object); -} diff --git a/test/Microsoft.Sbom.Api.Tests/Config/Validators/DirectoryPathIsWritableValidatorTests.cs b/test/Microsoft.Sbom.Api.Tests/Config/Validators/DirectoryPathIsWritableValidatorTests.cs deleted file mode 100644 index 21fcdd52..00000000 --- a/test/Microsoft.Sbom.Api.Tests/Config/Validators/DirectoryPathIsWritableValidatorTests.cs +++ /dev/null @@ -1,50 +0,0 @@ -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -using Microsoft.Sbom.Api.Config.Validators; -using Microsoft.Sbom.Api.Exceptions; -using Microsoft.Sbom.Api.Utils; -using Microsoft.Sbom.Common; -using Microsoft.VisualStudio.TestTools.UnitTesting; -using Moq; -using PowerArgs; - -namespace Microsoft.Sbom.Api.Tests.Config.Validators; - -[TestClass] -public class DirectoryPathIsWritableValidatorTests -{ - private readonly Mock mockAssemblyConfig = new Mock(); - - [TestMethod] - public void WhenDirectoryDoesNotExistsThrows() - { - var fileSystemUtilsMock = new Mock(); - fileSystemUtilsMock.Setup(f => f.DirectoryExists(It.IsAny())).Returns(false).Verifiable(); - - var validator = new DirectoryPathIsWritableValidator(fileSystemUtilsMock.Object, mockAssemblyConfig.Object); - Assert.ThrowsException(() => validator.ValidateInternal("property", "value", null)); - } - - [TestMethod] - public void WhenDirectoryDoesNotHaveWriteAccessThrows() - { - var fileSystemUtilsMock = new Mock(); - fileSystemUtilsMock.Setup(f => f.DirectoryExists(It.IsAny())).Returns(true).Verifiable(); - fileSystemUtilsMock.Setup(f => f.DirectoryHasWritePermissions(It.IsAny())).Returns(false).Verifiable(); - - var validator = new DirectoryPathIsWritableValidator(fileSystemUtilsMock.Object, mockAssemblyConfig.Object); - Assert.ThrowsException(() => validator.ValidateInternal("property", "value", null)); - } - - [TestMethod] - public void WhenDirectoryHasWriteAccess() - { - var fileSystemUtilsMock = new Mock(); - fileSystemUtilsMock.Setup(f => f.DirectoryExists(It.IsAny())).Returns(true).Verifiable(); - fileSystemUtilsMock.Setup(f => f.DirectoryHasWritePermissions(It.IsAny())).Returns(true).Verifiable(); - - var validator = new DirectoryPathIsWritableValidator(fileSystemUtilsMock.Object, mockAssemblyConfig.Object); - validator.ValidateInternal("property", "value", null); - } -} diff --git a/test/Microsoft.Sbom.Api.Tests/ConsoleCapture.cs b/test/Microsoft.Sbom.Api.Tests/ConsoleCapture.cs deleted file mode 100644 index 62f95641..00000000 --- a/test/Microsoft.Sbom.Api.Tests/ConsoleCapture.cs +++ /dev/null @@ -1,60 +0,0 @@ -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -namespace Microsoft.Sbom.Api.Tests; - -using System; -using System.IO; - -/// -/// A simple class to capture console output. Always wrap it in a try/finally block to -/// ensure that the original console output is restored. -/// -internal class ConsoleCapture -{ - private readonly TextWriter oldStdOut = Console.Out; - private readonly TextWriter oldStdError = Console.Error; - private TextWriter? stdOutWriter; - private TextWriter? stdErrWriter; - - /// - /// The content of the captured output to StdOut. Is only valid after the Restore method has been called. - /// - public string CapturedStdOut { get; private set; } = string.Empty; - - /// - /// The content of the captured output to StdError. Is only valid after the Restore method has been called. - /// - public string CapturedStdError { get; private set; } = string.Empty; - - public ConsoleCapture() - { - stdOutWriter = new StringWriter(); - Console.SetOut(stdOutWriter); - - stdErrWriter = new StringWriter(); - Console.SetError(stdErrWriter); - } - - /// - /// Restores the original console output and sets the Captured* properties - /// - public void Restore() - { - if (stdOutWriter is not null) - { - CapturedStdOut = stdOutWriter?.ToString() ?? string.Empty; - Console.SetOut(oldStdOut); - stdOutWriter?.Dispose(); - stdOutWriter = null; - } - - if (stdErrWriter is not null) - { - CapturedStdError = stdErrWriter?.ToString() ?? string.Empty; - Console.SetError(oldStdError); - stdErrWriter?.Dispose(); - stdErrWriter = null; - } - } -} diff --git a/test/Microsoft.Sbom.Api.Tests/Converters/ComponentToExternalReferenceInfoConverterTests.cs b/test/Microsoft.Sbom.Api.Tests/Converters/ComponentToExternalReferenceInfoConverterTests.cs deleted file mode 100644 index 5277cef0..00000000 --- a/test/Microsoft.Sbom.Api.Tests/Converters/ComponentToExternalReferenceInfoConverterTests.cs +++ /dev/null @@ -1,115 +0,0 @@ -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Channels; -using System.Threading.Tasks; -using Microsoft.ComponentDetection.Contracts.BcdeModels; -using Microsoft.ComponentDetection.Contracts.TypedComponent; -using Microsoft.Sbom.Api.Converters; -using Microsoft.Sbom.Api.Entities; -using Microsoft.VisualStudio.TestTools.UnitTesting; -using Moq; -using Serilog; - -namespace Microsoft.Sbom.Api.Tests.Converters; - -[TestClass] -public class ComponentToExternalReferenceInfoConverterTests -{ - private readonly Mock mockLogger = new Mock(); - - [TestMethod] - public async Task When_ConvertingComponentToExternalDocRefInfo_WithCommonCase_ThenTestPass() - { - var scannedComponents = from i in Enumerable.Range(1, 5) - select new ScannedComponent - { - Component = new SpdxComponent("SPDX-2.2", new Uri("http://test.uri"), $"sbom{i}", "123", $"elementId{i}", $"path{i}") - }; - - var componentsChannel = Channel.CreateUnbounded(); - foreach (var component in scannedComponents) - { - await componentsChannel.Writer.WriteAsync(component); - } - - componentsChannel.Writer.Complete(); - - var converter = new ComponentToExternalReferenceInfoConverter(mockLogger.Object); - var (results, errors) = converter.Convert(componentsChannel); - - var refs = await results.ReadAllAsync().ToListAsync(); - - await foreach (var error in errors.ReadAllAsync()) - { - Assert.Fail($"Caught exception: {error.ErrorType}"); - } - - var index = 1; - foreach (var reference in refs) - { - Assert.AreEqual($"sbom{index}", reference.ExternalDocumentName); - Assert.AreEqual(new Uri("http://test.uri").ToString(), reference.DocumentNamespace); - Assert.AreEqual($"elementId{index}", reference.DescribedElementID); - Assert.AreEqual($"path{index}", reference.Path); - Assert.AreEqual("123", reference.Checksum.First().ChecksumValue); - - index++; - } - - Assert.AreEqual(scannedComponents.ToList().Count, index - 1); - } - - [TestMethod] - public async Task When_ConvertingComponentToExternalDocRefInfo_WithWrongComponentType_ThenTestPass() - { - var scannnedComponent1 = new ScannedComponent - { - LocationsFoundAt = "test".Split(), - Component = new SpdxComponent("SPDX-2.2", new Uri("http://test.uri"), "sbom1", "123", "abcdef", "path1") - }; - var scannnedComponent2 = new ScannedComponent - { - LocationsFoundAt = "test".Split(), - Component = new SpdxComponent("SPDX-2.2", new Uri("http://test.uri"), "sbom2", "123", "abcdef", "path2") - }; - var scannnedComponent3 = new ScannedComponent - { - LocationsFoundAt = "test".Split(), - Component = new SpdxComponent("SPDX-2.2", new Uri("http://test.uri"), "sbom3", "123", "abcdef", "path3") - }; - var scannnedComponent4 = new ScannedComponent - { - LocationsFoundAt = "test".Split(), - Component = new NpmComponent("npmpackage", "1.0.0") - }; - - var scannedComponents = new List() - { - scannnedComponent1, - scannnedComponent2, - scannnedComponent3, - scannnedComponent4 - }; - - var componentsChannel = Channel.CreateUnbounded(); - foreach (var component in scannedComponents) - { - await componentsChannel.Writer.WriteAsync(component); - } - - componentsChannel.Writer.Complete(); - - var converter = new ComponentToExternalReferenceInfoConverter(mockLogger.Object); - var (results, errors) = converter.Convert(componentsChannel); - - var refs = await results.ReadAllAsync().ToListAsync(); - var errorList = await errors.ReadAllAsync().ToListAsync(); - - Assert.AreEqual(scannedComponents.Where(c => !(c.Component is SpdxComponent)).ToList().Count, errorList.Count); - Assert.AreEqual(scannedComponents.Where(c => c.Component is SpdxComponent).ToList().Count, refs.Count); - } -} diff --git a/test/Microsoft.Sbom.Api.Tests/Converters/ExternalReferenceInfoToPathConverterTest.cs b/test/Microsoft.Sbom.Api.Tests/Converters/ExternalReferenceInfoToPathConverterTest.cs deleted file mode 100644 index 785f7569..00000000 --- a/test/Microsoft.Sbom.Api.Tests/Converters/ExternalReferenceInfoToPathConverterTest.cs +++ /dev/null @@ -1,119 +0,0 @@ -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -using System.Collections.Generic; -using System.Linq; -using System.Threading.Channels; -using System.Threading.Tasks; -using Microsoft.Sbom.Api.Converters; -using Microsoft.Sbom.Api.Entities; -using Microsoft.Sbom.Extensions.Entities; -using Microsoft.VisualStudio.TestTools.UnitTesting; -using Moq; -using Serilog; - -namespace Microsoft.Sbom.Api.Tests.Converters; - -[TestClass] -public class ExternalReferenceInfoToPathConverterTest -{ - private readonly Mock mockLogger = new Mock(); - - [TestMethod] - public async Task When_ConvertingExternalDocRefInfoToPath_WithCommonCase_ThenTestPass() - { - var externalDocRef1 = new ExternalDocumentReferenceInfo() - { - Path = @"/path1" - }; - var externalDocRef2 = new ExternalDocumentReferenceInfo() - { - Path = @"/path2" - }; - var externalDocRef3 = new ExternalDocumentReferenceInfo() - { - Path = @"/path3" - }; - var externalDocRef4 = new ExternalDocumentReferenceInfo() - { - Path = @"/path4" - }; - - var externalDocRefs = new List() - { - externalDocRef1, externalDocRef2, externalDocRef3, externalDocRef4 - }; - - var externalDocRefChannel = Channel.CreateUnbounded(); - foreach (var externalDocRef in externalDocRefs) - { - await externalDocRefChannel.Writer.WriteAsync(externalDocRef); - } - - externalDocRefChannel.Writer.Complete(); - - var converter = new ExternalReferenceInfoToPathConverter(mockLogger.Object); - var (results, errors) = converter.Convert(externalDocRefChannel); - - var paths = await results.ReadAllAsync().ToListAsync(); - - await foreach (var error in errors.ReadAllAsync()) - { - Assert.Fail($"Caught exception: {error.ErrorType}"); - } - - var count = 1; - await foreach (var path in results.ReadAllAsync()) - { - Assert.Equals($"path{count}", path); - count++; - } - - Assert.AreEqual(externalDocRefs.Count, paths.Count); - } - - [TestMethod] - public async Task When_ConvertingExternalDocRefInfoToPath_WithMissingPath_ThenTestPass() - { - var externalDocRef1 = new ExternalDocumentReferenceInfo() - { - Path = @"/path1" - }; - var externalDocRef2 = new ExternalDocumentReferenceInfo() - { - Path = @"/path2" - }; - var externalDocRef3 = new ExternalDocumentReferenceInfo() - { - Path = @"/path3" - }; - var externalDocRef4 = new ExternalDocumentReferenceInfo() { }; - - var externalDocRefs = new List() - { - externalDocRef1, externalDocRef2, externalDocRef3, externalDocRef4 - }; - - var externalDocRefChannel = Channel.CreateUnbounded(); - foreach (var externalDocRef in externalDocRefs) - { - await externalDocRefChannel.Writer.WriteAsync(externalDocRef); - } - - externalDocRefChannel.Writer.Complete(); - - var converter = new ExternalReferenceInfoToPathConverter(mockLogger.Object); - var (results, errors) = converter.Convert(externalDocRefChannel); - - var paths = await results.ReadAllAsync().ToListAsync(); - var errorList = await errors.ReadAllAsync().ToListAsync(); - - await foreach (var error in errors.ReadAllAsync()) - { - Assert.Fail($"Caught exception: {error.ErrorType}"); - } - - Assert.AreEqual(3, paths.Count); - Assert.AreEqual(1, errorList.Count); - } -} diff --git a/test/Microsoft.Sbom.Api.Tests/Converters/SbomToolManifestPathConverterTests.cs b/test/Microsoft.Sbom.Api.Tests/Converters/SbomToolManifestPathConverterTests.cs deleted file mode 100644 index 314172d7..00000000 --- a/test/Microsoft.Sbom.Api.Tests/Converters/SbomToolManifestPathConverterTests.cs +++ /dev/null @@ -1,232 +0,0 @@ -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -using System.Runtime.InteropServices; -using Microsoft.Sbom.Api.Exceptions; -using Microsoft.Sbom.Api.Tests; -using Microsoft.Sbom.Common; -using Microsoft.Sbom.Common.Config; -using Microsoft.VisualStudio.TestTools.UnitTesting; -using Moq; -using PowerArgs; - -namespace Microsoft.Sbom.Api.Convertors.Tests; - -[TestClass] -public class SbomToolManifestPathConverterTests -{ - private Mock osUtils; - private Mock fileSystemUtils; - private Mock fileSystemExtensionUtils; - private Mock configurationMock; - private SbomToolManifestPathConverter converter; - - private bool isWindows; - - [TestInitialize] - public void Setup() - { - osUtils = new Mock(); - fileSystemUtils = new Mock(); - fileSystemExtensionUtils = new Mock(); - configurationMock = new Mock(); - - isWindows = RuntimeInformation.IsOSPlatform(OSPlatform.Windows); - - converter = new SbomToolManifestPathConverter(configurationMock.Object, osUtils.Object, fileSystemUtils.Object, fileSystemExtensionUtils.Object); - - fileSystemUtils.Setup(f => f.GetRelativePath(It.IsAny(), It.IsAny())) - .Returns((string r, string p) => PathUtils.GetRelativePath(r, p)); - fileSystemExtensionUtils.Setup(f => f.IsTargetPathInSource(It.IsAny(), It.IsAny())).Returns(true); - } - - [TestMethod] - [DataRow(nameof(OSPlatform.Windows))] - [DataRow(nameof(OSPlatform.Linux))] - [DataRow(nameof(OSPlatform.OSX))] -#if !NETFRAMEWORK - [DataRow(nameof(OSPlatform.FreeBSD))] -#endif - public void SbomToolManifestPathConverterTests_ValidPath_Succeeds(string osName) - { - var os = OSPlatform.Create(osName); - var rootPath = "/Sample/Root"; - - configurationMock.SetupGet(c => c.BuildDropPath).Returns(new ConfigurationSetting { Value = rootPath }); - osUtils.Setup(o => o.GetCurrentOSPlatform()).Returns(os); - - var (path, isOutsideDropPath) = converter.Convert(rootPath + "/hello/World"); - - if (os == OSPlatform.Windows && isWindows) - { - rootPath = @"C:\Sample\Root"; - - configurationMock.SetupGet(c => c.BuildDropPath).Returns(new ConfigurationSetting { Value = rootPath }); - - (path, isOutsideDropPath) = converter.Convert(rootPath + @"\hello\World"); - } - - Assert.AreEqual("/hello/World", path); - } - - [TestMethod] - [DataRow(nameof(OSPlatform.Windows))] - [DataRow(nameof(OSPlatform.Linux))] - [DataRow(nameof(OSPlatform.OSX))] - [DataRow(nameof(OSPlatform.FreeBSD))] - public void SbomToolManifestPathConverterTests_ValidPathWithDot_Succeeds_LinuxBased(string osName) - { - var os = OSPlatform.Create(osName); - var rootPath = "/Sample/Root/."; - - configurationMock.SetupGet(c => c.BuildDropPath).Returns(new ConfigurationSetting { Value = rootPath }); - osUtils.Setup(o => o.GetCurrentOSPlatform()).Returns(os); - - var (path, isOutsideDropPath) = converter.Convert(rootPath + "/hello/./World"); - - if (os == OSPlatform.Windows && isWindows) - { - rootPath = @"C:\Sample\Root\."; - - configurationMock.SetupGet(c => c.BuildDropPath).Returns(new ConfigurationSetting { Value = rootPath }); - - (path, isOutsideDropPath) = converter.Convert(rootPath + @"\hello\.\World"); - } - - Assert.AreEqual("/hello/World", path); - } - - [TestMethod] - [DataRow(nameof(OSPlatform.Windows))] - [DataRow(nameof(OSPlatform.Linux))] - [DataRow(nameof(OSPlatform.OSX))] -#if !NETFRAMEWORK - [DataRow(nameof(OSPlatform.FreeBSD))] -#endif - public void SbomToolManifestPathConverterTests_BuildDropPathRelative_Succeeds_LinuxBased(string osName) - { - var os = OSPlatform.Create(osName); - var rootPath = "Sample/./Root/"; - - configurationMock.SetupGet(c => c.BuildDropPath).Returns(new ConfigurationSetting { Value = rootPath }); - osUtils.Setup(o => o.GetCurrentOSPlatform()).Returns(os); - - var (path, isOutsideDropPath) = converter.Convert(rootPath + "/hello/./World"); - - if (os == OSPlatform.Windows && isWindows) - { - rootPath = @"Sample\.\Root\"; - - configurationMock.SetupGet(c => c.BuildDropPath).Returns(new ConfigurationSetting { Value = rootPath }); - - (path, isOutsideDropPath) = converter.Convert(rootPath + @"\hello\.\World"); - } - - Assert.AreEqual("/hello/World", path); - } - - [TestMethod] - public void SbomToolManifestPathConverterTests_CaseSensitive_Windows_Succeeds() - { - var os = OSPlatform.Windows; - if (!isWindows) - { - Assert.Inconclusive("This test will only run on Windows"); - } - - var rootPath = @"C:\Sample\Root"; - - configurationMock.SetupGet(c => c.BuildDropPath).Returns(new ConfigurationSetting { Value = rootPath }); - osUtils.Setup(o => o.GetCurrentOSPlatform()).Returns(os); - - var (path, isOutsideDropPath) = converter.Convert(@"C:\sample\Root" + @"\hello\World"); - Assert.AreEqual("/hello/World", path); - } - - [TestMethod] - public void SbomToolManifestPathConverterTests_CaseSensitive_FreeBSD_Succeeds() - { - var os = OSPlatform.FreeBSD; - if (isWindows) - { - Assert.Inconclusive("This test will only run on Linux"); - } - - var rootPath = @"/sample/Root"; - - configurationMock.SetupGet(c => c.BuildDropPath).Returns(new ConfigurationSetting { Value = rootPath }); - osUtils.Setup(o => o.GetCurrentOSPlatform()).Returns(os); - - var (path, isOutsideDropPath) = converter.Convert(rootPath + @"/hello/World"); - Assert.AreEqual("/hello/World", path); - } - - [TestMethod] - public void SbomToolManifestPathConverterTests_CaseSensitive_OSX_Fails() - { - var rootPath = @"C:\Sample\Root"; - configurationMock.SetupGet(c => c.BuildDropPath).Returns(new ConfigurationSetting { Value = rootPath }); - osUtils.Setup(o => o.GetCurrentOSPlatform()).Returns(OSPlatform.OSX); - fileSystemExtensionUtils.Setup(f => f.IsTargetPathInSource(It.IsAny(), It.IsAny())).Returns(false); - - Assert.ThrowsException(() => converter.Convert(@"C:\sample\Root" + @"\hello\World")); - } - - [TestMethod] - public void SbomToolManifestPathConverterTests_CaseSensitive_Linux_Fails() - { - var rootPath = @"C:\Sample\Root"; - configurationMock.SetupGet(c => c.BuildDropPath).Returns(new ConfigurationSetting { Value = rootPath }); - osUtils.Setup(o => o.GetCurrentOSPlatform()).Returns(OSPlatform.Linux); - fileSystemExtensionUtils.Setup(f => f.IsTargetPathInSource(It.IsAny(), It.IsAny())).Returns(false); - - Assert.ThrowsException(() => converter.Convert(@"C:\sample\Root" + @"\hello\World")); - } - - [TestMethod] - public void SbomToolManifestPathConverterTests_RootPathOutside_Fails() - { - var rootPath = @"C:\Sample\Root"; - - configurationMock.SetupGet(c => c.BuildDropPath).Returns(new ConfigurationSetting { Value = rootPath }); - osUtils.Setup(o => o.GetCurrentOSPlatform()).Returns(OSPlatform.Windows); - fileSystemExtensionUtils.Setup(f => f.IsTargetPathInSource(It.IsAny(), It.IsAny())).Returns(false); - - Assert.ThrowsException(() => converter.Convert(@"d:\Root\hello\World")); - } - - [TestMethod] - public void SbomToolManifestPathConverterTests_RootPathOutside_SbomOnDifferentDrive_Succeeds() - { - if (!isWindows) - { - Assert.Inconclusive("This test will only run on Windows"); - } - - var rootPath = @"C:\Sample\Root"; - var filePath = @"d:\Root\hello\World.spdx.json"; - var expectedPath = @"/d:/Root/hello/World.spdx.json"; - - configurationMock.SetupGet(c => c.BuildDropPath).Returns(new ConfigurationSetting { Value = rootPath }); - osUtils.Setup(o => o.GetCurrentOSPlatform()).Returns(OSPlatform.Windows); - var (path, isOutsideDropPath) = converter.Convert(filePath); - Assert.AreEqual(expectedPath, path); - } - - public void SbomToolManifestPathConverterTests_RootPathOutside_SbomOnSameDrive_Succeeds() - { - if (!isWindows) - { - Assert.Inconclusive("This test will only run on Windows"); - } - - var rootPath = @"C:\Sample\Root"; - var filePath = @"C:\Sample\hello\World.spdx.json"; - var expectedPath = @"/../hello/World.spdx.json"; - - configurationMock.SetupGet(c => c.BuildDropPath).Returns(new ConfigurationSetting { Value = rootPath }); - osUtils.Setup(o => o.GetCurrentOSPlatform()).Returns(OSPlatform.Windows); - var (path, isOutsideDropPath) = converter.Convert(filePath); - Assert.AreEqual(expectedPath, path); - } -} diff --git a/test/Microsoft.Sbom.Api.Tests/Entities/FileValidationResultTest.cs b/test/Microsoft.Sbom.Api.Tests/Entities/FileValidationResultTest.cs deleted file mode 100644 index 1de00383..00000000 --- a/test/Microsoft.Sbom.Api.Tests/Entities/FileValidationResultTest.cs +++ /dev/null @@ -1,45 +0,0 @@ -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -using Microsoft.Sbom.Api.Entities; -using Microsoft.Sbom.Contracts.Entities; -using Microsoft.VisualStudio.TestTools.UnitTesting; -using EntityErrorType = Microsoft.Sbom.Contracts.Enums.ErrorType; - -namespace Microsoft.Sbom.Api.Tests.Entities; - -[TestClass] -public class FileValidationResultTest -{ - [TestMethod] - [DataRow(ErrorType.AdditionalFile, EntityErrorType.FileError)] - [DataRow(ErrorType.FilteredRootPath, EntityErrorType.FileError)] - [DataRow(ErrorType.ManifestFolder, EntityErrorType.FileError)] - [DataRow(ErrorType.MissingFile, EntityErrorType.FileError)] - [DataRow(ErrorType.InvalidHash, EntityErrorType.HashingError)] - [DataRow(ErrorType.UnsupportedHashAlgorithm, EntityErrorType.HashingError)] - [DataRow(ErrorType.JsonSerializationError, EntityErrorType.JsonSerializationError)] - [DataRow(ErrorType.None, EntityErrorType.None)] - [DataRow(ErrorType.PackageError, EntityErrorType.PackageError)] - [DataRow(ErrorType.Other, EntityErrorType.Other)] - public void FileValidationResultErrorTypeMapping(ErrorType input, EntityErrorType expectedOutput) - { - var fileValidationResult = new FileValidationResult() { ErrorType = input, Path = "random" }; - var entityError = fileValidationResult.ToEntityError(); - - Assert.AreEqual(expectedOutput, entityError.ErrorType); - Assert.IsNull(entityError.Details); - - if (input == ErrorType.PackageError) - { - Assert.AreEqual("random", ((PackageEntity)entityError.Entity).Path); - Assert.AreEqual("random", ((PackageEntity)entityError.Entity).Name); - Assert.AreEqual(entityError.Entity.GetType(), typeof(PackageEntity)); - } - else - { - Assert.AreEqual("random", ((FileEntity)entityError.Entity).Path); - Assert.AreEqual(entityError.Entity.GetType(), typeof(FileEntity)); - } - } -} diff --git a/test/Microsoft.Sbom.Api.Tests/Entities/output/ValidationResultGeneratorTests.cs b/test/Microsoft.Sbom.Api.Tests/Entities/output/ValidationResultGeneratorTests.cs deleted file mode 100644 index e6121b42..00000000 --- a/test/Microsoft.Sbom.Api.Tests/Entities/output/ValidationResultGeneratorTests.cs +++ /dev/null @@ -1,304 +0,0 @@ -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -using System; -using System.Collections.Concurrent; -using System.Collections.Generic; -using Microsoft.Sbom.Api.Tests; -using Microsoft.Sbom.Api.Utils; -using Microsoft.Sbom.Common.Config; -using Microsoft.Sbom.Contracts; -using Microsoft.Sbom.Contracts.Enums; -using Microsoft.Sbom.Extensions.Entities; -using Microsoft.VisualStudio.TestTools.UnitTesting; -using Moq; - -namespace Microsoft.Sbom.Api.Entities.Output.Tests; - -[TestClass] -public class ValidationResultGeneratorTests -{ - [TestMethod] - public void ValidationResultGenerator_ShouldGenerateReportWithoutFailures() - { - var manifestData = GetDefaultManifestData(); - var configurationMock = GetDefaultConfigurationMock(ignoreMissing: false); - - var validationResultGenerator = new ValidationResultGenerator(configurationMock.Object); - var failures = new List(); - - failures.Add(new FileValidationResult() - { - Path = "/_manifest/manifestjson", - ErrorType = ErrorType.ManifestFolder - }); - - failures.Add(new FileValidationResult() - { - Path = "/child5/file8", - ErrorType = ErrorType.FilteredRootPath - }); - - var validationResultOutput = validationResultGenerator - .WithTotalFilesInManifest(manifestData.Count) - .WithSuccessCount(12) - .WithTotalDuration(TimeSpan.FromSeconds(5)) - .WithValidationResults(failures) - .Build(); - - Assert.AreEqual(Result.Success, validationResultOutput.Result); - Assert.AreEqual(0, validationResultOutput.ValidationErrors.Count); - Assert.AreEqual(12, validationResultOutput.Summary.ValidationTelemetery.TotalFilesInManifest); - Assert.AreEqual(0, validationResultOutput.Summary.ValidationTelemetery.FilesFailedCount); - Assert.AreEqual(12, validationResultOutput.Summary.ValidationTelemetery.FilesSuccessfulCount); - Assert.AreEqual(2, validationResultOutput.Summary.ValidationTelemetery.FilesSkippedCount); - } - - [TestMethod] - public void ValidationResultGenerator_ShouldGenerateReportWithoutFailuresIfIgnoreMissing() - { - var manifestData = GetDefaultManifestData(); - var configurationMock = GetDefaultConfigurationMock(ignoreMissing: true); - - var validationResultGenerator = new ValidationResultGenerator(configurationMock.Object); - var failures = new List(); - - failures.Add(new FileValidationResult() - { - Path = "/_manifest/manifestjson", - ErrorType = ErrorType.ManifestFolder - }); - - failures.Add(new FileValidationResult() - { - Path = "/child5/file8", - ErrorType = ErrorType.FilteredRootPath - }); - - var validationResultOutput = validationResultGenerator - .WithTotalFilesInManifest(manifestData.Count) - .WithSuccessCount(12) - .WithTotalDuration(TimeSpan.FromSeconds(5)) - .WithValidationResults(failures) - .Build(); - - Assert.AreEqual(Result.Success, validationResultOutput.Result); - Assert.AreEqual(0, validationResultOutput.ValidationErrors.Count); - Assert.AreEqual(12, validationResultOutput.Summary.ValidationTelemetery.TotalFilesInManifest); - Assert.AreEqual(0, validationResultOutput.Summary.ValidationTelemetery.FilesFailedCount); - Assert.AreEqual(12, validationResultOutput.Summary.ValidationTelemetery.FilesSuccessfulCount); - Assert.AreEqual(2, validationResultOutput.Summary.ValidationTelemetery.FilesSkippedCount); - } - - [TestMethod] - public void ValidationResultGenerator_IncorrectHashShouldCauseFailure() - { - var manifestData = GetDefaultManifestData(); - var configurationMock = GetDefaultConfigurationMock(ignoreMissing: false); - - var validationResultGenerator = new ValidationResultGenerator(configurationMock.Object); - var failures = new List(); - - failures.Add(new FileValidationResult() - { - Path = "/_manifest/manifestjson", - ErrorType = ErrorType.ManifestFolder - }); - - failures.Add(new FileValidationResult() - { - Path = "/child5/file8", - ErrorType = ErrorType.FilteredRootPath - }); - - failures.Add(new FileValidationResult() - { - Path = "/child2/grandchild1/file9", - ErrorType = ErrorType.InvalidHash - }); - - var validationResultOutput = validationResultGenerator - .WithTotalFilesInManifest(manifestData.Count) - .WithSuccessCount(11) - .WithTotalDuration(TimeSpan.FromSeconds(5)) - .WithValidationResults(failures) - .Build(); - - Assert.AreEqual(Result.Failure, validationResultOutput.Result); - Assert.AreEqual(1, validationResultOutput.ValidationErrors.Count); - Assert.AreEqual(12, validationResultOutput.Summary.ValidationTelemetery.TotalFilesInManifest); - Assert.AreEqual(1, validationResultOutput.Summary.ValidationTelemetery.FilesFailedCount); - Assert.AreEqual(11, validationResultOutput.Summary.ValidationTelemetery.FilesSuccessfulCount); - Assert.AreEqual(2, validationResultOutput.Summary.ValidationTelemetery.FilesSkippedCount); - } - - [TestMethod] - public void ValidationResultGenerator_MissingFileShouldCauseFailure() - { - var manifestData = GetDefaultManifestData(); - var configurationMock = GetDefaultConfigurationMock(ignoreMissing: false); - - var validationResultGenerator = new ValidationResultGenerator(configurationMock.Object); - var failures = new List(); - - failures.Add(new FileValidationResult() - { - Path = "/_manifest/manifestjson", - ErrorType = ErrorType.ManifestFolder - }); - - failures.Add(new FileValidationResult() - { - Path = "/child5/file8", - ErrorType = ErrorType.FilteredRootPath - }); - - failures.Add(new FileValidationResult() - { - Path = "/child2/grandchild2/file10", - ErrorType = ErrorType.MissingFile - }); - - var validationResultOutput = validationResultGenerator - .WithTotalFilesInManifest(manifestData.Count) - .WithSuccessCount(11) - .WithTotalDuration(TimeSpan.FromSeconds(5)) - .WithValidationResults(failures) - .Build(); - - Assert.AreEqual(Result.Failure, validationResultOutput.Result); - Assert.AreEqual(1, validationResultOutput.ValidationErrors.Count); - Assert.AreEqual(12, validationResultOutput.Summary.ValidationTelemetery.TotalFilesInManifest); - Assert.AreEqual(1, validationResultOutput.Summary.ValidationTelemetery.FilesFailedCount); - Assert.AreEqual(11, validationResultOutput.Summary.ValidationTelemetery.FilesSuccessfulCount); - Assert.AreEqual(2, validationResultOutput.Summary.ValidationTelemetery.FilesSkippedCount); - } - - [TestMethod] - public void ValidationResultGenerator_MissingFileShouldNotCauseFailureIfIgnoreMissing() - { - var manifestData = GetDefaultManifestData(); - var configurationMock = GetDefaultConfigurationMock(ignoreMissing: true); - - var validationResultGenerator = new ValidationResultGenerator(configurationMock.Object); - var failures = new List(); - - failures.Add(new FileValidationResult() - { - Path = "/_manifest/manifestjson", - ErrorType = ErrorType.ManifestFolder - }); - - failures.Add(new FileValidationResult() - { - Path = "/child5/file8", - ErrorType = ErrorType.FilteredRootPath - }); - - failures.Add(new FileValidationResult() - { - Path = "/child2/grandchild2/file10", - ErrorType = ErrorType.MissingFile - }); - - var validationResultOutput = validationResultGenerator - .WithTotalFilesInManifest(manifestData.Count) - .WithSuccessCount(12) - .WithTotalDuration(TimeSpan.FromSeconds(5)) - .WithValidationResults(failures) - .Build(); - - Assert.AreEqual(Result.Success, validationResultOutput.Result); - Assert.AreEqual(0, validationResultOutput.ValidationErrors.Count); - Assert.AreEqual(12, validationResultOutput.Summary.ValidationTelemetery.TotalFilesInManifest); - Assert.AreEqual(0, validationResultOutput.Summary.ValidationTelemetery.FilesFailedCount); - Assert.AreEqual(12, validationResultOutput.Summary.ValidationTelemetery.FilesSuccessfulCount); - Assert.AreEqual(3, validationResultOutput.Summary.ValidationTelemetery.FilesSkippedCount); - } - - [TestMethod] - public void ValidationResultGenerator_ShouldFailOnlyOnWrongHashIfIgnoreMissing() - { - var manifestData = GetDefaultManifestData(); - var configurationMock = GetDefaultConfigurationMock(ignoreMissing: true); - - var validationResultGenerator = new ValidationResultGenerator(configurationMock.Object); - var failures = new List(); - - failures.Add(new FileValidationResult() - { - Path = "/_manifest/manifestjson", - ErrorType = ErrorType.ManifestFolder - }); - - failures.Add(new FileValidationResult() - { - Path = "/child5/file8", - ErrorType = ErrorType.FilteredRootPath - }); - - failures.Add(new FileValidationResult() - { - Path = "/child2/grandchild2/file10", - ErrorType = ErrorType.MissingFile - }); - - failures.Add(new FileValidationResult() - { - Path = "/child2/grandchild1/file9", - ErrorType = ErrorType.InvalidHash - }); - - var validationResultOutput = validationResultGenerator - .WithTotalFilesInManifest(manifestData.Count) - .WithSuccessCount(11) - .WithTotalDuration(TimeSpan.FromSeconds(5)) - .WithValidationResults(failures) - .Build(); - - Assert.AreEqual(Result.Failure, validationResultOutput.Result); - Assert.AreEqual(1, validationResultOutput.ValidationErrors.Count); - Assert.AreEqual(12, validationResultOutput.Summary.ValidationTelemetery.TotalFilesInManifest); - Assert.AreEqual(1, validationResultOutput.Summary.ValidationTelemetery.FilesFailedCount); - Assert.AreEqual(11, validationResultOutput.Summary.ValidationTelemetery.FilesSuccessfulCount); - Assert.AreEqual(3, validationResultOutput.Summary.ValidationTelemetery.FilesSkippedCount); - } - - private static Mock GetDefaultConfigurationMock(bool ignoreMissing) - { - var configurationMock = new Mock(); - configurationMock.SetupGet(c => c.BuildDropPath).Returns(new ConfigurationSetting { Value = "/root" }); - configurationMock.SetupGet(c => c.ManifestDirPath).Returns(new ConfigurationSetting { Value = PathUtils.Join("/root", "_manifest") }); - configurationMock.SetupGet(c => c.Parallelism).Returns(new ConfigurationSetting { Value = 3 }); - configurationMock.SetupGet(c => c.HashAlgorithm).Returns(new ConfigurationSetting { Value = Constants.DefaultHashAlgorithmName }); - configurationMock.SetupGet(c => c.RootPathFilter).Returns(new ConfigurationSetting { Value = "child1;child2;child3" }); - configurationMock.SetupGet(c => c.ValidateSignature).Returns(new ConfigurationSetting { Value = true }); - configurationMock.SetupGet(c => c.IgnoreMissing).Returns(new ConfigurationSetting { Value = ignoreMissing }); - configurationMock.SetupGet(c => c.ManifestToolAction).Returns(ManifestToolActions.Validate); - return configurationMock; - } - - private static ManifestData GetDefaultManifestData() - { - IDictionary hashDictionary = new Dictionary - { - ["/_manifest/manifestjson"] = new Checksum[] { new Checksum { Algorithm = AlgorithmName.SHA256, ChecksumValue = "/root/_manifest/manifestjsonhash" } }, - ["/child1/file1"] = new Checksum[] { new Checksum { Algorithm = AlgorithmName.SHA256, ChecksumValue = "/root/child1/file1hash" } }, - ["/child1/file2"] = new Checksum[] { new Checksum { Algorithm = AlgorithmName.SHA256, ChecksumValue = "/root/child1/file2hash" } }, - ["/child2/file3"] = new Checksum[] { new Checksum { Algorithm = AlgorithmName.SHA256, ChecksumValue = "/root/child2/file3hash" } }, - ["/child2/file4"] = new Checksum[] { new Checksum { Algorithm = AlgorithmName.SHA256, ChecksumValue = "/root/child2/file4hash" } }, - ["/child2/file5"] = new Checksum[] { new Checksum { Algorithm = AlgorithmName.SHA256, ChecksumValue = "/root/child2/file5hash" } }, - ["/child3/file11"] = new Checksum[] { new Checksum { Algorithm = AlgorithmName.SHA256, ChecksumValue = "/root/child3/file11hash" } }, - ["/child3/file12"] = new Checksum[] { new Checksum { Algorithm = AlgorithmName.SHA256, ChecksumValue = "/root/child3/file12hash" } }, - ["/child2/grandchild1/file6"] = new Checksum[] { new Checksum { Algorithm = AlgorithmName.SHA256, ChecksumValue = "/root/child2/grandchild1/file6hash" } }, - ["/child5/file8"] = new Checksum[] { new Checksum { Algorithm = AlgorithmName.SHA256, ChecksumValue = "/root/child5/file8hash" } }, - ["/child2/grandchild1/file9"] = new Checksum[] { new Checksum { Algorithm = AlgorithmName.SHA256, ChecksumValue = "incorrectHash" } }, - ["/child2/grandchild2/file10"] = new Checksum[] { new Checksum { Algorithm = AlgorithmName.SHA256, ChecksumValue = "missingfile" } } - }; - return new ManifestData - { - HashesMap = new ConcurrentDictionary(hashDictionary, StringComparer.InvariantCultureIgnoreCase), - Count = hashDictionary.Keys.Count - }; - } -} diff --git a/test/Microsoft.Sbom.Api.Tests/Executors/ComponentToPackageInfoConverterTests.cs b/test/Microsoft.Sbom.Api.Tests/Executors/ComponentToPackageInfoConverterTests.cs deleted file mode 100644 index 93f9cf0b..00000000 --- a/test/Microsoft.Sbom.Api.Tests/Executors/ComponentToPackageInfoConverterTests.cs +++ /dev/null @@ -1,289 +0,0 @@ -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Channels; -using System.Threading.Tasks; -using Microsoft.ComponentDetection.Contracts.BcdeModels; -using Microsoft.ComponentDetection.Contracts.Internal; -using Microsoft.ComponentDetection.Contracts.TypedComponent; -using Microsoft.Sbom.Api.Entities; -using Microsoft.Sbom.Api.Manifest; -using Microsoft.Sbom.Api.Tests; -using Microsoft.Sbom.Api.Utils; -using Microsoft.Sbom.Common.Config; -using Microsoft.Sbom.Extensions; -using Microsoft.VisualStudio.TestTools.UnitTesting; -using Moq; -using HashAlgorithmName = Microsoft.Sbom.Contracts.Enums.AlgorithmName; -using ILogger = Serilog.ILogger; -using PackageInfo = Microsoft.Sbom.Contracts.SbomPackage; - -namespace Microsoft.Sbom.Api.Executors.Tests; - -using Microsoft.Sbom.Adapters.ComponentDetection; - -[TestClass] -public class ComponentToPackageInfoConverterTests -{ - private readonly Mock mockLogger = new Mock(); - private readonly Mock mockConfiguration = new Mock(); - private readonly ManifestGeneratorProvider manifestGeneratorProvider; - - [TestInitialize] - public void Setup() - { - } - - public ComponentToPackageInfoConverterTests() - { - mockConfiguration.SetupGet(c => c.ManifestToolAction).Returns(ManifestToolActions.Validate); - mockConfiguration.SetupGet(c => c.HashAlgorithm).Returns(new ConfigurationSetting { Value = Constants.DefaultHashAlgorithmName }); - mockConfiguration.SetupGet(c => c.BuildComponentPath).Returns(new ConfigurationSetting { Value = "root" }); - - manifestGeneratorProvider = new ManifestGeneratorProvider(new IManifestGenerator[] { new TestManifestGenerator() }); - manifestGeneratorProvider.Init(); - } - - [TestMethod] - public async Task ConvertTestAsync() - { - var scannedComponents = new List() - { - new ExtendedScannedComponent - { - LocationsFoundAt = "test".Split(), - Component = new NuGetComponent("nugetpackage", "1.0.0") - }, - new ExtendedScannedComponent - { - LocationsFoundAt = "test".Split(), - Component = new NuGetComponent("nugetpackage2", "1.0.0") - }, - new ExtendedScannedComponent - { - LocationsFoundAt = "test".Split(), - Component = new GitComponent(new Uri("http://test.uri"), "hash") - }, - new ExtendedScannedComponent - { - LocationsFoundAt = "test".Split(), - Component = new MavenComponent("groupId", "artifactId", "1.0.0") - } - }; - - var (output, errors) = await ConvertScannedComponents(scannedComponents); - - var expectedPackageNames = new List - { - "nugetpackage", "nugetpackage2", "http://test.uri/ : hash - Git", "groupId.artifactId" - }; - - CollectionAssert.AreEquivalent(expectedPackageNames, output.Select(c => c.PackageName).ToList()); - - Assert.IsNotNull(errors); - Assert.IsFalse(errors.Any()); - } - - [TestMethod] - public async Task ConvertNuGet_AuthorPopulated() - { - var scannedComponent = new ExtendedScannedComponent - { - Component = new NuGetComponent("nugetpackage", "1.0.0") - { - Authors = new[] { "author1", "author2" } - } - }; - - var packageInfo = await ConvertScannedComponent(scannedComponent); - - Assert.AreEqual($"Organization: {((NuGetComponent)scannedComponent.Component).Authors.First()}", packageInfo.Supplier); - } - - [TestMethod] - public async Task ConvertNuGet_AuthorNotPopulated() - { - var scannedComponent = new ExtendedScannedComponent - { - Component = new NuGetComponent("nugetpackage", "1.0.0") { Authors = null } - }; - - var packageInfo = await ConvertScannedComponent(scannedComponent); - - Assert.IsNull(packageInfo.Supplier); - } - - [TestMethod] - public async Task ConvertNuGet_LicenseConcludedPopulated() - { - var scannedComponent = new ExtendedScannedComponent - { - Component = new NuGetComponent("nugetpackage", "1.0.0") { Authors = null }, - LicenseConcluded = "MIT" - }; - - var packageInfo = await ConvertScannedComponent(scannedComponent); - - Assert.AreEqual("MIT", packageInfo.LicenseInfo.Concluded); - Assert.IsNull(packageInfo.LicenseInfo?.Declared); - } - - [TestMethod] - public async Task ConvertNuGet_LicenseDeclaredPopulated() - { - var scannedComponent = new ExtendedScannedComponent - { - Component = new NuGetComponent("nugetpackage", "1.0.0") { Authors = null }, - LicenseDeclared = "MIT" - }; - - var packageInfo = await ConvertScannedComponent(scannedComponent); - - Assert.AreEqual("MIT", packageInfo.LicenseInfo.Declared); - Assert.IsNull(packageInfo.LicenseInfo?.Concluded); - } - - [TestMethod] - public async Task ConvertNuGet_LicensesNotPopulated() - { - var scannedComponent = new ExtendedScannedComponent - { - Component = new NuGetComponent("nugetpackage", "1.0.0") { Authors = null }, - }; - - var packageInfo = await ConvertScannedComponent(scannedComponent); - - Assert.IsNull(packageInfo.LicenseInfo?.Concluded); - Assert.IsNull(packageInfo.LicenseInfo?.Declared); - } - - [TestMethod] - public async Task ConvertNpm_AuthorPopulated_Name() - { - var scannedComponent = new ExtendedScannedComponent - { - Component = new NpmComponent("nugetpackage", "1.0.0", author: new NpmAuthor("Suzy Author")) - }; - - var packageInfo = await ConvertScannedComponent(scannedComponent); - - Assert.AreEqual($"Organization: {((NpmComponent)scannedComponent.Component).Author.Name}", packageInfo.Supplier); - } - - [TestMethod] - public async Task ConvertNpm_AuthorPopulated_NameAndEmail() - { - var scannedComponent = new ExtendedScannedComponent - { - Component = new NpmComponent("nugetpackage", "1.0.0", author: new NpmAuthor("Suzy Author", "suzya@contoso.com")) - }; - - var packageInfo = await ConvertScannedComponent(scannedComponent); - - Assert.AreEqual($"Organization: {((NpmComponent)scannedComponent.Component).Author.Name} ({((NpmComponent)scannedComponent.Component).Author.Email})", packageInfo.Supplier); - } - - [TestMethod] - public async Task ConvertNpm_AuthorNotPopulated() - { - var scannedComponent = new ExtendedScannedComponent - { - Component = new NpmComponent("npmpackage", "1.0.0") { Author = null } - }; - - var packageInfo = await ConvertScannedComponent(scannedComponent); - - Assert.IsNull(packageInfo.Supplier); - } - - [TestMethod] - public async Task ConvertNpm_LicensePopulated() - { - var scannedComponent = new ExtendedScannedComponent - { - Component = new NpmComponent("npmpackage", "1.0.0") { Author = null }, - LicenseConcluded = "MIT" - }; - - var packageInfo = await ConvertScannedComponent(scannedComponent); - - Assert.AreEqual("MIT", packageInfo.LicenseInfo.Concluded); - } - - [TestMethod] - public async Task ConvertNpm_LicenseNotPopulated() - { - var scannedComponent = new ExtendedScannedComponent - { - Component = new NpmComponent("npmpackage", "1.0.0") { Author = null }, - }; - - var packageInfo = await ConvertScannedComponent(scannedComponent); - - Assert.IsNull(packageInfo.LicenseInfo?.Concluded); - } - - [TestMethod] - public async Task ConvertWorksWithBuildComponentPathNull() - { - var scannedComponents = new List() - { - new ExtendedScannedComponent - { - Component = new NuGetComponent("nugetpackage", "1.0.0") - }, - new ExtendedScannedComponent - { - Component = new NuGetComponent("nugetpackage2", "1.0.0") - }, - new ExtendedScannedComponent - { - Component = new GitComponent(new Uri("http://test.uri"), "hash") - }, - new ExtendedScannedComponent - { - Component = new MavenComponent("groupId", "artifactId", "1.0.0") - } - }; - - var (output, errors) = await ConvertScannedComponents(scannedComponents); - - var expectedPackageNames = new List - { - "nugetpackage", "nugetpackage2", "http://test.uri/ : hash - Git", "groupId.artifactId" - }; - - CollectionAssert.AreEquivalent(expectedPackageNames, output.Select(c => c.PackageName).ToList()); - - Assert.IsNotNull(errors); - Assert.IsFalse(errors.Any()); - } - - private async Task ConvertScannedComponent(ExtendedScannedComponent scannedComponent) - { - var componentsChannel = Channel.CreateUnbounded(); - await componentsChannel.Writer.WriteAsync(scannedComponent); - componentsChannel.Writer.Complete(); - var packageInfoConverter = new ComponentToPackageInfoConverter(mockLogger.Object); - var (output, _) = packageInfoConverter.Convert(componentsChannel); - var packageInfo = await output.ReadAsync(); - return packageInfo; - } - - private async Task<(IEnumerable, IEnumerable)> ConvertScannedComponents(IEnumerable scannedComponents) - { - var componentsChannel = Channel.CreateUnbounded(); - foreach (var scannedComponent in scannedComponents) - { - await componentsChannel.Writer.WriteAsync(scannedComponent); - } - - componentsChannel.Writer.Complete(); - var packageInfoConverter = new ComponentToPackageInfoConverter(mockLogger.Object); - var (output, errors) = packageInfoConverter.Convert(componentsChannel); - return (await output.ReadAllAsync().ToListAsync(), await errors.ReadAllAsync().ToListAsync()); - } -} diff --git a/test/Microsoft.Sbom.Api.Tests/Executors/DirectoryWalkerTests.cs b/test/Microsoft.Sbom.Api.Tests/Executors/DirectoryWalkerTests.cs deleted file mode 100644 index 0619ea2f..00000000 --- a/test/Microsoft.Sbom.Api.Tests/Executors/DirectoryWalkerTests.cs +++ /dev/null @@ -1,109 +0,0 @@ -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -using System; -using System.Collections.Generic; -using System.Threading.Tasks; -using Microsoft.Sbom.Api.Exceptions; -using Microsoft.Sbom.Common; -using Microsoft.Sbom.Common.Config; -using Microsoft.VisualStudio.TestTools.UnitTesting; -using Moq; -using Serilog; - -namespace Microsoft.Sbom.Api.Executors.Tests; - -[TestClass] -public class DirectoryWalkerTests -{ - private readonly Mock mockLogger = new Mock(); - private readonly Mock mockConfiguration = new Mock(); - - [TestInitialize] - public void TestInitialize() - { - mockConfiguration.Setup(c => c.FollowSymlinks).Returns(new ConfigurationSetting { Source = SettingSource.Default, Value = true }); - } - - [TestMethod] - public async Task DirectoryWalkerTests_ValidRoot_SucceedsAsync() - { - var files = new HashSet - { - @"Test\Sample\NoRead.txt", - @"Test\Sample\Sample.txt", - }; - - var mockFSUtils = new Mock(); - mockFSUtils.Setup(m => m.DirectoryExists(It.IsAny())).Returns(true).Verifiable(); - mockFSUtils.SetupSequence(m => m.GetDirectories(It.IsAny(), true)) - .Returns(new List() { "Sample" }) - .Returns(new List()); - mockFSUtils.Setup(m => m.GetFilesInDirectory(It.Is(d => d == "Sample"), true)).Returns(files).Verifiable(); - mockFSUtils.Setup(m => m.GetFilesInDirectory(It.Is(d => d == "Test"), true)).Returns(new List()).Verifiable(); - - var filesChannelReader = new DirectoryWalker(mockFSUtils.Object, mockLogger.Object, mockConfiguration.Object).GetFilesRecursively(@"Test"); - - await foreach (var file in filesChannelReader.file.ReadAllAsync()) - { - Assert.IsTrue(files.Remove(file)); - } - - await foreach (var file in filesChannelReader.file.ReadAllAsync()) - { - Assert.IsTrue(files.Remove(file)); - } - - await foreach (var error in filesChannelReader.errors.ReadAllAsync()) - { - Assert.Fail($"Error thrown for {error.Path}: {error.ErrorType}"); - } - - Assert.AreEqual(0, files.Count); - mockFSUtils.VerifyAll(); - } - - [TestMethod] - public void DirectoryWalkerTests_DirectoryDoesntExist_Fails() - { - var mockFSUtils = new Mock(); - mockFSUtils.Setup(m => m.DirectoryExists(It.IsAny())).Returns(false).Verifiable(); - Assert.ThrowsException(() => - new DirectoryWalker(mockFSUtils.Object, mockLogger.Object, mockConfiguration.Object).GetFilesRecursively(@"BadDir")); - mockFSUtils.VerifyAll(); - } - - [TestMethod] - public async Task DirectoryWalkerTests_UnreachableFile_FailsAsync() - { - var files = new HashSet - { - @"Test\SampleBadDir\Test.txt" - }; - var mockFSUtils = new Mock(); - mockFSUtils.Setup(m => m.DirectoryExists(It.IsAny())).Returns(true).Verifiable(); - mockFSUtils.SetupSequence(m => m.GetDirectories(It.IsAny(), true)) - .Returns(new List() { "Sample" }) - .Returns(new List() { "Failed" }); - mockFSUtils.Setup(m => m.GetFilesInDirectory(It.Is(d => d == "Sample"), true)).Returns(files).Verifiable(); - mockFSUtils.Setup(m => m.GetFilesInDirectory(It.Is(d => d == "Test"), true)).Returns(new List()).Verifiable(); - mockFSUtils.Setup(m => m.GetFilesInDirectory(It.Is(d => d == "Failed"), true)).Throws(new UnauthorizedAccessException()).Verifiable(); - - var filesChannelReader = new DirectoryWalker(mockFSUtils.Object, mockLogger.Object, mockConfiguration.Object).GetFilesRecursively(@"Test"); - var errorCount = 0; - - await foreach (var error in filesChannelReader.errors.ReadAllAsync()) - { - errorCount++; - } - - await foreach (var file in filesChannelReader.file.ReadAllAsync()) - { - Assert.IsTrue(files.Remove(file)); - } - - Assert.AreEqual(1, errorCount); - Assert.AreEqual(0, files.Count); - mockFSUtils.VerifyAll(); - } -} diff --git a/test/Microsoft.Sbom.Api.Tests/Executors/ExternalDocumentReferenceWriterTest.cs b/test/Microsoft.Sbom.Api.Tests/Executors/ExternalDocumentReferenceWriterTest.cs deleted file mode 100644 index a7e744af..00000000 --- a/test/Microsoft.Sbom.Api.Tests/Executors/ExternalDocumentReferenceWriterTest.cs +++ /dev/null @@ -1,100 +0,0 @@ -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -using System.Collections.Generic; -using System.Text.Json; -using System.Threading.Channels; -using System.Threading.Tasks; -using Microsoft.Sbom.Api.Executors; -using Microsoft.Sbom.Api.Manifest; -using Microsoft.Sbom.Api.Manifest.Configuration; -using Microsoft.Sbom.Api.Output; -using Microsoft.Sbom.Api.Output.Telemetry; -using Microsoft.Sbom.Api.Recorder; -using Microsoft.Sbom.Common; -using Microsoft.Sbom.Contracts; -using Microsoft.Sbom.Contracts.Enums; -using Microsoft.Sbom.Extensions; -using Microsoft.Sbom.Extensions.Entities; -using Microsoft.VisualStudio.TestTools.UnitTesting; -using Moq; -using Serilog; -using Constants = Microsoft.Sbom.Api.Utils.Constants; - -namespace Microsoft.Sbom.Api.Tests.Executors; - -[TestClass] -public class ExternalDocumentReferenceWriterTest -{ - private Mock mockLogger = new Mock(); - private Mock recorderMock = new Mock(); - private Mock fileSystemUtilsMock = new Mock(); - - [TestMethod] - public async Task PassExternalDocumentReferenceInfosChannel_ReturnsJsonDocWithSerializer() - { - var manifestGeneratorProvider = new ManifestGeneratorProvider(new IManifestGenerator[] { new TestManifestGenerator() }); - manifestGeneratorProvider.Init(); - var metadataBuilder = new MetadataBuilder( - mockLogger.Object, - manifestGeneratorProvider, - Constants.TestManifestInfo, - recorderMock.Object); - var jsonFilePath = "/root/_manifest/manifest.json"; - var sbomConfig = new SbomConfig(fileSystemUtilsMock.Object) - { - ManifestInfo = Constants.TestManifestInfo, - ManifestJsonDirPath = "/root/_manifest", - ManifestJsonFilePath = jsonFilePath, - MetadataBuilder = metadataBuilder, - Recorder = new SbomPackageDetailsRecorder() - }; - - var externalDocumentReferenceInfo = new ExternalDocumentReferenceInfo - { - ExternalDocumentName = "name", - DocumentNamespace = "namespace" - }; - var checksum = new Checksum - { - Algorithm = AlgorithmName.SHA1, - ChecksumValue = "abc" - }; - externalDocumentReferenceInfo.Checksum = new List { checksum }; - - var externalDocumentReferenceInfos = new List { externalDocumentReferenceInfo }; - var externalDocumentReferenceInfosChannel = Channel.CreateUnbounded(); - foreach (var data in externalDocumentReferenceInfos) - { - await externalDocumentReferenceInfosChannel.Writer.WriteAsync(data); - } - - externalDocumentReferenceInfosChannel.Writer.Complete(); - - var externalDocumentReferenceWriter = new ExternalDocumentReferenceWriter(manifestGeneratorProvider, mockLogger.Object); - var (results, errors) = externalDocumentReferenceWriter.Write(externalDocumentReferenceInfosChannel, new List { sbomConfig }); - - await foreach (var result in results.ReadAllAsync()) - { - var root = result.Document.RootElement; - - if (root.TryGetProperty("Document", out var documentNamespace)) - { - Assert.AreEqual("namespace", documentNamespace.GetString()); - } - else - { - Assert.Fail("Document property not found"); - } - - if (root.TryGetProperty("ExternalDocumentId", out var externalDocumentId)) - { - Assert.AreEqual("name", externalDocumentId.GetString()); - } - else - { - Assert.Fail("ExternalDocumentId property not found"); - } - } - } -} diff --git a/test/Microsoft.Sbom.Api.Tests/Executors/FileHasherTests.cs b/test/Microsoft.Sbom.Api.Tests/Executors/FileHasherTests.cs deleted file mode 100644 index 032d5e09..00000000 --- a/test/Microsoft.Sbom.Api.Tests/Executors/FileHasherTests.cs +++ /dev/null @@ -1,338 +0,0 @@ -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -using System; -using System.Collections.Concurrent; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Channels; -using System.Threading.Tasks; -using Microsoft.Sbom.Api.Convertors; -using Microsoft.Sbom.Api.Entities; -using Microsoft.Sbom.Api.Exceptions; -using Microsoft.Sbom.Api.Hashing; -using Microsoft.Sbom.Api.Manifest; -using Microsoft.Sbom.Api.Utils; -using Microsoft.Sbom.Common.Config; -using Microsoft.Sbom.Contracts; -using Microsoft.Sbom.Contracts.Enums; -using Microsoft.Sbom.Extensions; -using Microsoft.Sbom.Extensions.Entities; -using Microsoft.VisualStudio.TestTools.UnitTesting; -using Moq; -using Serilog; -using Constants = Microsoft.Sbom.Api.Utils.Constants; - -namespace Microsoft.Sbom.Api.Executors.Tests; - -[TestClass] -public class FileHasherTests -{ - private readonly Mock mockLogger = new Mock(); - private readonly Mock mockConfiguration = new Mock(); - - private readonly ConcurrentDictionary hashDict = new ConcurrentDictionary(); - private HashSet fileList = new HashSet(); - - [TestInitialize] - public void TestInitialize() - { - fileList = new HashSet() - { - "test1", - "test2", - "test3" - }; - foreach (var file in fileList) - { - hashDict[file] = new Checksum[] - { - new Checksum { Algorithm = AlgorithmName.SHA256, ChecksumValue = $"{file}_hash" } - }; - } - - ManifestDataSingleton.ResetDictionary(); - } - - [TestMethod] - public async Task FileHasherTest_Validate_MultipleFiles_SucceedsAsync() - { - var hashCodeGeneratorMock = new Mock(); - var manifestPathConverter = new Mock(); - - mockConfiguration.SetupGet(c => c.ManifestToolAction).Returns(ManifestToolActions.Validate); - mockConfiguration.SetupGet(c => c.HashAlgorithm).Returns(new ConfigurationSetting { Value = Constants.DefaultHashAlgorithmName }); - - hashCodeGeneratorMock.Setup(m => m.GenerateHashes( - It.IsAny(), - new AlgorithmName[] { Constants.DefaultHashAlgorithmName })) - .Returns(new Checksum[] - { - new Checksum { Algorithm = Constants.DefaultHashAlgorithmName, ChecksumValue = "hash" } - }); - manifestPathConverter.Setup(m => m.Convert(It.IsAny(), false)).Returns((string r, bool v) => (r, true)); - - var files = Channel.CreateUnbounded(); - (ChannelReader file, ChannelReader error) fileHashes - = new FileHasher( - hashCodeGeneratorMock.Object, - manifestPathConverter.Object, - mockLogger.Object, - mockConfiguration.Object, - new Mock().Object, - new ManifestGeneratorProvider(null), - new FileTypeUtils()) - .Run(files); - foreach (var file in fileList) - { - await files.Writer.WriteAsync(file); - } - - files.Writer.Complete(); - - await foreach (var fileHash in fileHashes.file.ReadAllAsync()) - { - Assert.IsTrue(fileList.Remove(fileHash.Path)); - Assert.AreEqual("hash", fileHash.Checksum.First().ChecksumValue); - Assert.IsNull(fileHash.FileTypes); - } - - Assert.AreEqual(0, fileHashes.error.Count); - hashCodeGeneratorMock.VerifyAll(); - manifestPathConverter.VerifyAll(); - mockConfiguration.VerifyAll(); - } - - [TestMethod] - public async Task FileHasherTest_Validate_ManifestPathConverterThrows_ReturnsValidationFailureAsync() - { - mockConfiguration.SetupGet(c => c.ManifestToolAction).Returns(ManifestToolActions.Validate); - mockConfiguration.SetupGet(c => c.HashAlgorithm).Returns(new ConfigurationSetting { Value = Constants.DefaultHashAlgorithmName }); - - var hashCodeGeneratorMock = new Mock(); - var manifestPathConverter = new Mock(); - - hashCodeGeneratorMock.Setup(m => m.GenerateHashes( - It.IsAny(), - new AlgorithmName[] { Constants.DefaultHashAlgorithmName })) - .Returns(new Checksum[] - { - new Checksum { Algorithm = Constants.DefaultHashAlgorithmName, ChecksumValue = "hash" } - }); - - manifestPathConverter.Setup(m => m.Convert(It.IsAny(), false)).Returns((string r, bool v) => (r, true)); - manifestPathConverter.Setup(m => m.Convert(It.Is(d => d == "test2"), false)).Throws(new InvalidPathException()); - - var fileHasher = new FileHasher( - hashCodeGeneratorMock.Object, - manifestPathConverter.Object, - mockLogger.Object, - mockConfiguration.Object, - new Mock().Object, - new ManifestGeneratorProvider(null), - new FileTypeUtils()) - { - ManifestData = ManifestDataSingleton.Instance - }; - - var files = Channel.CreateUnbounded(); - (ChannelReader file, ChannelReader error) fileHashes - = fileHasher.Run(files); - foreach (var file in fileList) - { - await files.Writer.WriteAsync(file); - } - - files.Writer.Complete(); - var errorCount = 0; - var filesCount = 0; - - await foreach (var fileHash in fileHashes.file.ReadAllAsync()) - { - Assert.IsTrue(fileList.Remove(fileHash.Path)); - Assert.AreEqual("hash", fileHash.Checksum.First().ChecksumValue); - Assert.IsNull(fileHash.FileTypes); - filesCount++; - } - - await foreach (var error in fileHashes.error.ReadAllAsync()) - { - Assert.AreEqual(Entities.ErrorType.Other, error.ErrorType); - errorCount++; - } - - Assert.AreEqual(3, ManifestDataSingleton.Instance.HashesMap.Count); - Assert.AreEqual(2, filesCount); - Assert.AreEqual(1, errorCount); - hashCodeGeneratorMock.VerifyAll(); - hashCodeGeneratorMock.Verify(h => h.GenerateHashes(It.IsAny(), It.IsAny()), Times.Exactly(2)); - manifestPathConverter.VerifyAll(); - mockConfiguration.VerifyAll(); - } - - [TestMethod] - public async Task FileHasherTest_Validate_HashError_ReturnsValidationFailureAsync() - { - mockConfiguration.SetupGet(c => c.ManifestToolAction).Returns(ManifestToolActions.Validate); - mockConfiguration.SetupGet(c => c.HashAlgorithm).Returns(new ConfigurationSetting { Value = Constants.DefaultHashAlgorithmName }); - - var hashCodeGeneratorMock = new Mock(); - var manifestPathConverter = new Mock(); - - hashCodeGeneratorMock.SetupSequence(m => m.GenerateHashes( - It.IsAny(), - new AlgorithmName[] { Constants.DefaultHashAlgorithmName })) - .Returns(new Checksum[] - { - new Checksum { Algorithm = Constants.DefaultHashAlgorithmName, ChecksumValue = "hash" } - }) - .Returns(new Checksum[] - { - new Checksum { Algorithm = Constants.DefaultHashAlgorithmName, ChecksumValue = string.Empty } - }) - .Throws(new UnauthorizedAccessException("Can't access file")); - manifestPathConverter.Setup(m => m.Convert(It.IsAny(), false)).Returns((string r, bool v) => (r, true)); - - var fileHasher = new FileHasher( - hashCodeGeneratorMock.Object, - manifestPathConverter.Object, - mockLogger.Object, - mockConfiguration.Object, - new Mock().Object, - new ManifestGeneratorProvider(null), - new FileTypeUtils()) - { - ManifestData = ManifestDataSingleton.Instance - }; - - var files = Channel.CreateUnbounded(); - (ChannelReader file, ChannelReader error) fileHashes - = fileHasher.Run(files); - foreach (var file in fileList) - { - await files.Writer.WriteAsync(file); - } - - files.Writer.Complete(); - var errorCount = 0; - var filesCount = 0; - - await foreach (var fileHash in fileHashes.file.ReadAllAsync()) - { - Assert.IsTrue(fileList.Remove(fileHash.Path)); - Assert.AreEqual("hash", fileHash.Checksum.First().ChecksumValue); - Assert.IsNull(fileHash.FileTypes); - filesCount++; - } - - await foreach (var error in fileHashes.error.ReadAllAsync()) - { - Assert.AreEqual(Entities.ErrorType.Other, error.ErrorType); - errorCount++; - } - - Assert.AreEqual(1, ManifestDataSingleton.Instance.HashesMap.Count); - Assert.AreEqual(1, filesCount); - Assert.AreEqual(2, errorCount); - hashCodeGeneratorMock.VerifyAll(); - manifestPathConverter.VerifyAll(); - mockConfiguration.VerifyAll(); - } - - [TestMethod] - public async Task FileHasherTest_Generate_MultipleFiles_SucceedsAsync() - { - var hashCodeGeneratorMock = new Mock(); - var manifestPathConverter = new Mock(); - - mockConfiguration.SetupGet(c => c.ManifestToolAction).Returns(ManifestToolActions.Generate); - - hashCodeGeneratorMock.Setup(m => m.GenerateHashes( - It.IsAny(), - new AlgorithmName[] { Constants.DefaultHashAlgorithmName })) - .Returns(new Checksum[] - { - new Checksum { Algorithm = Constants.DefaultHashAlgorithmName, ChecksumValue = "hash" } - }); - - var manifestInfoList = new List - { - ManifestInfo.Parse("test:1"), - ManifestInfo.Parse("test:2") - }; - - var generator1 = new Mock(); - var generator2 = new Mock(); - - generator1.Setup(g => g.RegisterManifest()).Returns(ManifestInfo.Parse("test:1")); - generator2.Setup(g => g.RequiredHashAlgorithms).Returns(new AlgorithmName[] { AlgorithmName.SHA256 }); - generator2.Setup(g => g.RegisterManifest()).Returns(ManifestInfo.Parse("test:2")); - - var manifestGenProvider = new ManifestGeneratorProvider(new IManifestGenerator[] - { - generator1.Object, - generator2.Object - }); - - manifestGenProvider.Init(); - - var sbomConfigs = new Mock(); - sbomConfigs.Setup(s => s.GetManifestInfos()).Returns(manifestInfoList); - - manifestPathConverter.Setup(m => m.Convert(It.IsAny(), It.IsAny())).Returns((string r, bool v) => (r, true)); - - var files = Channel.CreateUnbounded(); - (ChannelReader file, ChannelReader error) fileHashes - = new FileHasher( - hashCodeGeneratorMock.Object, - manifestPathConverter.Object, - mockLogger.Object, - mockConfiguration.Object, - sbomConfigs.Object, - manifestGenProvider, - new FileTypeUtils()) - .Run(files); - foreach (var file in fileList) - { - await files.Writer.WriteAsync(file); - } - - files.Writer.Complete(); - - await foreach (var fileHash in fileHashes.file.ReadAllAsync()) - { - Assert.IsTrue(fileList.Remove(fileHash.Path)); - Assert.AreEqual("hash", fileHash.Checksum.First().ChecksumValue); - Assert.IsNull(fileHash.FileTypes); - } - - Assert.AreEqual(0, fileHashes.error.Count); - hashCodeGeneratorMock.VerifyAll(); - manifestPathConverter.VerifyAll(); - mockConfiguration.VerifyAll(); - } - - private sealed class ManifestDataSingleton - { - private static readonly IDictionary HashDictionary = new Dictionary - { - ["test1"] = new Checksum[] { new Checksum { Algorithm = AlgorithmName.SHA256, ChecksumValue = "test1_hash" } }, - ["test2"] = new Checksum[] { new Checksum { Algorithm = AlgorithmName.SHA256, ChecksumValue = "test2_hash" } }, - ["test3"] = new Checksum[] { new Checksum { Algorithm = AlgorithmName.SHA256, ChecksumValue = "test3_hash" } }, - }; - - private static readonly Lazy - Lazy = - new Lazy( - () => new ManifestData { HashesMap = new ConcurrentDictionary(HashDictionary, StringComparer.InvariantCultureIgnoreCase) }); - - public static ManifestData Instance { get { return Lazy.Value; } } - - private ManifestDataSingleton() { } - - public static void ResetDictionary() - { - Lazy.Value.HashesMap = new ConcurrentDictionary(HashDictionary, StringComparer.InvariantCultureIgnoreCase); - } - } -} diff --git a/test/Microsoft.Sbom.Api.Tests/Executors/FileListEnumeratorTests.cs b/test/Microsoft.Sbom.Api.Tests/Executors/FileListEnumeratorTests.cs deleted file mode 100644 index 0c090b71..00000000 --- a/test/Microsoft.Sbom.Api.Tests/Executors/FileListEnumeratorTests.cs +++ /dev/null @@ -1,115 +0,0 @@ -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -using System; -using System.Collections.Generic; -using System.Threading.Tasks; -using Microsoft.Sbom.Api.Exceptions; -using Microsoft.Sbom.Common; -using Microsoft.VisualStudio.TestTools.UnitTesting; -using Moq; -using Serilog; - -namespace Microsoft.Sbom.Api.Executors.Tests; - -[TestClass] -public class FileListEnumeratorTests -{ - private readonly Mock mockLogger = new Mock(); - - [TestMethod] - public async Task ListWalkerTests_ValidListFile_SucceedsAsync() - { - var files = new List - { - @"d:\directorya\directoryb\file1.txt", - @"d:\directorya\directoryc\file3.txt", - }; - - var fileText = string.Join(Environment.NewLine, files); - var testFileName = "somefile"; - - var mockFSUtils = new Mock(); - mockFSUtils.Setup(m => m.ReadAllText(It.Is(d => d == testFileName))).Returns(fileText).Verifiable(); - mockFSUtils.Setup(m => m.FileExists(It.Is(d => d == testFileName))).Returns(true).Verifiable(); - mockFSUtils.Setup(m => m.FileExists(It.Is(d => d == files[0]))).Returns(true).Verifiable(); - mockFSUtils.Setup(m => m.FileExists(It.Is(d => d == files[1]))).Returns(true).Verifiable(); - mockFSUtils.Setup(m => m.AbsolutePath(It.Is(d => d == files[0]))).Returns(files[0]); - mockFSUtils.Setup(m => m.AbsolutePath(It.Is(d => d == files[1]))).Returns(files[1]); - - var filesChannelReader = new FileListEnumerator(mockFSUtils.Object, mockLogger.Object).GetFilesFromList(testFileName); - var errorCount = 0; - - await foreach (var error in filesChannelReader.errors.ReadAllAsync()) - { - Assert.AreEqual(Entities.ErrorType.MissingFile, error.ErrorType); - errorCount++; - } - - await foreach (var file in filesChannelReader.file.ReadAllAsync()) - { - Assert.IsTrue(files.Remove(file)); - } - - Assert.AreEqual(0, errorCount); - Assert.AreEqual(0, files.Count); - mockFSUtils.VerifyAll(); - } - - [TestMethod] - public void ListWalkerTests_ListFile_Null_Fails() - { - var mockFSUtils = new Mock(); - Assert.ThrowsException(() => - new FileListEnumerator(mockFSUtils.Object, mockLogger.Object).GetFilesFromList(null)); - mockFSUtils.VerifyAll(); - } - - [TestMethod] - public void ListWalkerTests_DirectoryDoesntExist_Fails() - { - var mockFSUtils = new Mock(); - Assert.ThrowsException(() => - new FileListEnumerator(mockFSUtils.Object, mockLogger.Object).GetFilesFromList(@"BadDir")); - mockFSUtils.VerifyAll(); - } - - [TestMethod] - public async Task ListWalkerTests_UnreachableFile_FailsAsync() - { - var files = new List - { - @"d:\directorya\directoryb\file1.txt", - @"d:\directorya\directoryc\file3.txt", - }; - - var fileText = string.Join(Environment.NewLine, files); - var testFileName = "somefile"; - - var mockFSUtils = new Mock(); - mockFSUtils.Setup(m => m.ReadAllText(It.Is(d => d == testFileName))).Returns(fileText).Verifiable(); - mockFSUtils.Setup(m => m.FileExists(It.Is(d => d == testFileName))).Returns(true).Verifiable(); - mockFSUtils.Setup(m => m.FileExists(It.Is(d => d == files[0]))).Returns(true).Verifiable(); - mockFSUtils.Setup(m => m.FileExists(It.Is(d => d == files[1]))).Returns(false).Verifiable(); - mockFSUtils.Setup(m => m.AbsolutePath(It.Is(d => d == files[0]))).Returns(files[0]); - mockFSUtils.Setup(m => m.AbsolutePath(It.Is(d => d == files[1]))).Returns(files[1]); - - var filesChannelReader = new FileListEnumerator(mockFSUtils.Object, mockLogger.Object).GetFilesFromList(testFileName); - var errorCount = 0; - - await foreach (var error in filesChannelReader.errors.ReadAllAsync()) - { - Assert.AreEqual(Entities.ErrorType.MissingFile, error.ErrorType); - errorCount++; - } - - await foreach (var file in filesChannelReader.file.ReadAllAsync()) - { - Assert.IsTrue(files.Remove(file)); - } - - Assert.AreEqual(1, errorCount); - Assert.AreEqual(1, files.Count); - mockFSUtils.VerifyAll(); - } -} diff --git a/test/Microsoft.Sbom.Api.Tests/Executors/HashValidatorTests.cs b/test/Microsoft.Sbom.Api.Tests/Executors/HashValidatorTests.cs deleted file mode 100644 index 2703c0d6..00000000 --- a/test/Microsoft.Sbom.Api.Tests/Executors/HashValidatorTests.cs +++ /dev/null @@ -1,155 +0,0 @@ -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -using System; -using System.Collections.Concurrent; -using System.Collections.Generic; -using System.Threading.Channels; -using System.Threading.Tasks; -using Microsoft.Sbom.Api.Entities; -using Microsoft.Sbom.Api.Utils; -using Microsoft.Sbom.Common.Config; -using Microsoft.Sbom.Contracts; -using Microsoft.Sbom.Contracts.Enums; -using Microsoft.Sbom.Extensions.Entities; -using Microsoft.VisualStudio.TestTools.UnitTesting; -using Moq; -using ErrorType = Microsoft.Sbom.Api.Entities.ErrorType; - -namespace Microsoft.Sbom.Api.Executors.Tests; - -[TestClass] -public class HashValidatorTests -{ - [TestMethod] - public async Task HashValidatorTest_ValidHash_SucceedsAsync() - { - var fileList = new HashSet() - { - "TEST1", - "TEST2", - "TEST3" - }; - var hashDict = new ConcurrentDictionary(StringComparer.InvariantCultureIgnoreCase); - foreach (var file in fileList) - { - hashDict[file.ToLower()] = new Checksum[] { new Checksum { Algorithm = AlgorithmName.SHA256, ChecksumValue = $"{file}_hash" } }; - } - - var configuration = new Mock(); - configuration.SetupGet(c => c.HashAlgorithm).Returns(new ConfigurationSetting { Value = Constants.DefaultHashAlgorithmName }); - - var files = Channel.CreateUnbounded(); - foreach (var file in fileList) - { - await files.Writer.WriteAsync(new InternalSbomFileInfo { Path = file.ToUpper(), Checksum = new Checksum[] { new Checksum { Algorithm = Constants.DefaultHashAlgorithmName, ChecksumValue = $"{file}_hash" } } }); - } - - files.Writer.Complete(); - - var validator = new HashValidator(configuration.Object, new ManifestData { HashesMap = hashDict }); - var validationResults = validator.Validate(files); - - await foreach (var output in validationResults.output.ReadAllAsync()) - { - Assert.IsTrue(fileList.Remove(output.Path)); - } - - Assert.AreEqual(0, fileList.Count); - Assert.AreEqual(0, validationResults.errors.Count); - } - - [TestMethod] - public async Task HashValidatorTest_InValidHash_ReturnsValidationErrorAsync() - { - var fileList = new HashSet() - { - "TEST1", - "TEST2", - "TEST3" - }; - - var hashDict = new ConcurrentDictionary(StringComparer.InvariantCultureIgnoreCase); - foreach (var file in fileList) - { - hashDict[file.ToLower()] = new Checksum[] { new Checksum { Algorithm = AlgorithmName.SHA256, ChecksumValue = $"{file}_hashInvalid" } }; - } - - var configuration = new Mock(); - configuration.SetupGet(c => c.HashAlgorithm).Returns(new ConfigurationSetting { Value = Constants.DefaultHashAlgorithmName }); - - var files = Channel.CreateUnbounded(); - foreach (var file in fileList) - { - await files.Writer.WriteAsync(new InternalSbomFileInfo { Path = file.ToUpper(), Checksum = new Checksum[] { new Checksum { Algorithm = Constants.DefaultHashAlgorithmName, ChecksumValue = $"{file}_hash" } } }); - } - - files.Writer.Complete(); - - var validator = new HashValidator(configuration.Object, new ManifestData { HashesMap = hashDict }); - var validationResults = validator.Validate(files); - - await foreach (var output in validationResults.output.ReadAllAsync()) - { - Assert.IsTrue(fileList.Remove(output.Path)); - } - - await foreach (var error in validationResults.errors.ReadAllAsync()) - { - Assert.AreEqual(ErrorType.InvalidHash, error.ErrorType); - Assert.IsTrue(fileList.Remove(error.Path)); - } - - Assert.AreEqual(0, fileList.Count); - } - - [TestMethod] - public async Task HashValidatorTest_AdditionalFile_ReturnsAdditionalFileFailureAsync() - { - var fileList = new HashSet() - { - "TEST1", - "TEST2", - "TEST3" - }; - - var hashDict = new ConcurrentDictionary(StringComparer.InvariantCultureIgnoreCase); - foreach (var file in fileList) - { - hashDict[file.ToLower()] = new Checksum[] { new Checksum { Algorithm = AlgorithmName.SHA256, ChecksumValue = $"{file}_hash" } }; - } - - var configuration = new Mock(); - configuration.SetupGet(c => c.HashAlgorithm).Returns(new ConfigurationSetting { Value = Constants.DefaultHashAlgorithmName }); - - var files = Channel.CreateUnbounded(); - var errors = Channel.CreateUnbounded(); - - foreach (var file in fileList) - { - await files.Writer.WriteAsync(new InternalSbomFileInfo { Path = file.ToUpper(), Checksum = new Checksum[] { new Checksum { Algorithm = Constants.DefaultHashAlgorithmName, ChecksumValue = $"{file}_hash" } } }); - } - - // Additional file. - await files.Writer.WriteAsync(new InternalSbomFileInfo { Path = "TEST4", Checksum = new Checksum[] { new Checksum { Algorithm = Constants.DefaultHashAlgorithmName, ChecksumValue = $"TEST4_hash" } } }); - - files.Writer.Complete(); - errors.Writer.Complete(); - - var validator = new HashValidator(configuration.Object, new ManifestData { HashesMap = hashDict }); - var validationResults = validator.Validate(files); - - await foreach (var error in validationResults.errors.ReadAllAsync()) - { - Assert.AreEqual(ErrorType.AdditionalFile, error.ErrorType); - Assert.AreEqual("TEST4", error.Path); - } - - await foreach (var output in validationResults.output.ReadAllAsync()) - { - Assert.IsTrue(fileList.Remove(output.Path)); - } - - Assert.AreEqual(0, fileList.Count); - } -} diff --git a/test/Microsoft.Sbom.Api.Tests/Executors/LicenseInformationFetcherTests.cs b/test/Microsoft.Sbom.Api.Tests/Executors/LicenseInformationFetcherTests.cs deleted file mode 100644 index a135a7be..00000000 --- a/test/Microsoft.Sbom.Api.Tests/Executors/LicenseInformationFetcherTests.cs +++ /dev/null @@ -1,163 +0,0 @@ -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -using System.Collections.Generic; -using Microsoft.ComponentDetection.Contracts.BcdeModels; -using Microsoft.ComponentDetection.Contracts.TypedComponent; -using Microsoft.Sbom.Api.Output.Telemetry; -using Microsoft.Sbom.Api.Tests; -using Microsoft.VisualStudio.TestTools.UnitTesting; -using Moq; -using ILogger = Serilog.ILogger; - -namespace Microsoft.Sbom.Api.Executors.Tests; - -[TestClass] -public class LicenseInformationFetcherTests -{ - private readonly Mock mockLogger = new Mock(); - private readonly Mock mockRecorder = new Mock(); - private readonly Mock mockLicenseInformationService = new Mock(); - - [TestMethod] - public void ConvertComponentsToListForApi_Npm() - { - var licenseInformationFetcher = new LicenseInformationFetcher(mockLogger.Object, mockRecorder.Object, mockLicenseInformationService.Object); - - var scannedComponents = new List - { - new ScannedComponent - { - Component = new NpmComponent("npmpackage", "1.0.0") { Author = null } - }, - - new ScannedComponent - { - Component = new NpmComponent("@npmpackageNamespace/testpackage", "1.0.0") { Author = null } - }, - }; - - var listOfComponentsForApi = licenseInformationFetcher.ConvertComponentsToListForApi(scannedComponents); - - Assert.AreEqual("npm/npmjs/-/npmpackage/1.0.0", listOfComponentsForApi[0]); - Assert.AreEqual("npm/npmjs/@npmpackagenamespace/testpackage/1.0.0", listOfComponentsForApi[1]); - } - - [TestMethod] - public void ConvertComponentToListForApi_NuGet() - { - var licenseInformationFetcher = new LicenseInformationFetcher(mockLogger.Object, mockRecorder.Object, mockLicenseInformationService.Object); - - var scannedComponents = new List - { - new ScannedComponent - { - Component = new NuGetComponent("nugetpackage", "1.0.0") - }, - - new ScannedComponent - { - Component = new NuGetComponent("@nugetpackage/testpackage", "1.0.0") - }, - }; - - var listOfComponentsForApi = licenseInformationFetcher.ConvertComponentsToListForApi(scannedComponents); - - Assert.AreEqual("nuget/nuget/-/nugetpackage/1.0.0", listOfComponentsForApi[0]); - Assert.AreEqual("nuget/nuget/@nugetpackage/testpackage/1.0.0", listOfComponentsForApi[1]); - } - - [TestMethod] - public void ConvertComponentToListForApi_Pypi() - { - var licenseInformationFetcher = new LicenseInformationFetcher(mockLogger.Object, mockRecorder.Object, mockLicenseInformationService.Object); - - var scannedComponents = new List - { - new ScannedComponent - { - Component = new PipComponent("pippackage", "1.0.0") - } - }; - - var listOfComponentsForApi = licenseInformationFetcher.ConvertComponentsToListForApi(scannedComponents); - - Assert.AreEqual("pypi/pypi/-/pippackage/1.0.0", listOfComponentsForApi[0]); - } - - [TestMethod] - public void ConvertComponentToListForApi_Gem() - { - var licenseInformationFetcher = new LicenseInformationFetcher(mockLogger.Object, mockRecorder.Object, mockLicenseInformationService.Object); - - var scannedComponents = new List - { - new ScannedComponent - { - Component = new RubyGemsComponent("gempackage", "1.0.0") - } - }; - - var listOfComponentsForApi = licenseInformationFetcher.ConvertComponentsToListForApi(scannedComponents); - - Assert.AreEqual("gem/rubygems/-/gempackage/1.0.0", listOfComponentsForApi[0]); - } - - [TestMethod] - public void ConvertComponentToListForApi_Pod() - { - var licenseInformationFetcher = new LicenseInformationFetcher(mockLogger.Object, mockRecorder.Object, mockLicenseInformationService.Object); - - var scannedComponents = new List - { - new ScannedComponent - { - Component = new PodComponent("podpackage", "1.0.0") - } - }; - - var listOfComponentsForApi = licenseInformationFetcher.ConvertComponentsToListForApi(scannedComponents); - - Assert.AreEqual("pod/cocoapods/-/podpackage/1.0.0", listOfComponentsForApi[0]); - } - - [TestMethod] - public void ConvertComponentToListForApi_Crate() - { - var licenseInformationFetcher = new LicenseInformationFetcher(mockLogger.Object, mockRecorder.Object, mockLicenseInformationService.Object); - - var scannedComponents = new List - { - new ScannedComponent - { - Component = new CargoComponent("cratepackage", "1.0.0") - } - }; - - var listOfComponentsForApi = licenseInformationFetcher.ConvertComponentsToListForApi(scannedComponents); - - Assert.AreEqual("crate/cratesio/-/cratepackage/1.0.0", listOfComponentsForApi[0]); - } - - [TestMethod] - public void ConvertClearlyDefinedApiResponseToList_GoodResponse() - { - var expectedKey = "json5@2.2.3"; - var expectedValue = "MIT"; - var licenseInformationFetcher = new LicenseInformationFetcher(mockLogger.Object, mockRecorder.Object, mockLicenseInformationService.Object); - - var licensesDictionary = licenseInformationFetcher.ConvertClearlyDefinedApiResponseToList(HttpRequestUtils.GoodClearlyDefinedAPIResponse); - - CollectionAssert.Contains(licensesDictionary, new KeyValuePair(expectedKey, expectedValue)); - } - - [TestMethod] - public void ConvertClearlyDefinedApiResponseToList_BadResponse() - { - var licenseInformationFetcher = new LicenseInformationFetcher(mockLogger.Object, mockRecorder.Object, mockLicenseInformationService.Object); - - var licensesDictionary = licenseInformationFetcher.ConvertClearlyDefinedApiResponseToList(HttpRequestUtils.BadClearlyDefinedAPIResponse); - - Assert.AreEqual(0, licensesDictionary.Count); - } -} diff --git a/test/Microsoft.Sbom.Api.Tests/Executors/PackagesWalkerTests.cs b/test/Microsoft.Sbom.Api.Tests/Executors/PackagesWalkerTests.cs deleted file mode 100644 index 480ee48a..00000000 --- a/test/Microsoft.Sbom.Api.Tests/Executors/PackagesWalkerTests.cs +++ /dev/null @@ -1,238 +0,0 @@ -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; -using Microsoft.ComponentDetection.Contracts; -using Microsoft.ComponentDetection.Contracts.BcdeModels; -using Microsoft.ComponentDetection.Contracts.TypedComponent; -using Microsoft.ComponentDetection.Orchestrator.Commands; -using Microsoft.Sbom.Adapters.ComponentDetection; -using Microsoft.Sbom.Api.Exceptions; -using Microsoft.Sbom.Api.Manifest.Configuration; -using Microsoft.Sbom.Api.PackageDetails; -using Microsoft.Sbom.Api.Utils; -using Microsoft.Sbom.Common; -using Microsoft.Sbom.Common.Config; -using Microsoft.Sbom.Extensions; -using Microsoft.Sbom.Extensions.Entities; -using Microsoft.VisualStudio.TestTools.UnitTesting; -using Moq; -using Serilog.Events; -using IComponentDetector = Microsoft.Sbom.Api.Utils.IComponentDetector; -using ILogger = Serilog.ILogger; - -namespace Microsoft.Sbom.Api.Executors.Tests; - -[TestClass] -public class PackagesWalkerTests -{ - private readonly Mock mockLogger = new Mock(); - private readonly Mock mockConfiguration = new Mock(); - private readonly Mock mockSbomConfigs = new Mock(); - private readonly Mock mockFileSystemUtils = new Mock(); - private readonly Mock mockLicenseInformationFetcher = new Mock(); - private readonly Mock mockPackageDetailsFactory = new Mock(); - - public PackagesWalkerTests() - { - ISbomConfig sbomConfig = new SbomConfig(mockFileSystemUtils.Object) - { - ManifestJsonFilePath = "testpath" - }; - mockConfiguration.SetupGet(c => c.Verbosity).Returns(new ConfigurationSetting { Value = LogEventLevel.Information }); - mockSbomConfigs.Setup(s => s.TryGet(It.IsAny(), out sbomConfig)).Returns(true); - } - - [TestMethod] - public async Task ScanSuccessTestAsync() - { - var scannedComponents = new List(); - for (var i = 1; i < 4; i++) - { - var scannedComponent = new ExtendedScannedComponent - { - Component = new NpmComponent("componentName", $"{i}") - }; - - scannedComponents.Add(scannedComponent); - } - - var scannedComponentOther = new ExtendedScannedComponent - { - Component = new NpmComponent("componentName", "3") - }; - - scannedComponents.Add(scannedComponentOther); - - var mockDetector = new Mock(new Mock().Object, new Mock().Object); - - var scanResult = new ScanResult - { - ResultCode = ProcessingResultCode.Success, - ComponentsFound = scannedComponents - }; - - mockDetector.Setup(o => o.ScanAsync(It.IsAny())).Returns(Task.FromResult(scanResult)); - var walker = new PackagesWalker(mockLogger.Object, mockDetector.Object, mockConfiguration.Object, mockSbomConfigs.Object, mockFileSystemUtils.Object, mockPackageDetailsFactory.Object, mockLicenseInformationFetcher.Object); - var packagesChannelReader = walker.GetComponents("root"); - - var countDistinctComponents = 0; - - await foreach (ExtendedScannedComponent package in packagesChannelReader.output.ReadAllAsync()) - { - countDistinctComponents++; - Assert.IsTrue(scannedComponents.Remove(package)); - } - - await foreach (var error in packagesChannelReader.error.ReadAllAsync()) - { - Assert.Fail($"Caught exception: {error.Message}"); - } - - Assert.AreEqual(1, scannedComponents.Count); - Assert.AreEqual(3, countDistinctComponents); - mockDetector.VerifyAll(); - } - - [TestMethod] - public async Task ScanCombinePackagesWithSameNameDifferentCase() - { - var scannedComponents = new List(); - for (var i = 1; i < 4; i++) - { - var scannedComponent = new ExtendedScannedComponent - { - Component = new NpmComponent("componentName", $"{i}") - }; - - scannedComponents.Add(scannedComponent); - } - - var scannedComponentOther = new ExtendedScannedComponent - { - // Component with changed case. should also match 'componentName' and - // thus only 3 components should be detected. - Component = new NpmComponent("ComponentName", "3") - }; - - scannedComponents.Add(scannedComponentOther); - - var mockDetector = new Mock(new Mock().Object, new Mock().Object); - - var scanResult = new ScanResult - { - ResultCode = ProcessingResultCode.Success, - ComponentsFound = scannedComponents - }; - - mockDetector.Setup(o => o.ScanAsync(It.IsAny())).Returns(Task.FromResult(scanResult)); - var walker = new PackagesWalker(mockLogger.Object, mockDetector.Object, mockConfiguration.Object, mockSbomConfigs.Object, mockFileSystemUtils.Object, mockPackageDetailsFactory.Object, mockLicenseInformationFetcher.Object); - var packagesChannelReader = walker.GetComponents("root"); - - var countDistinctComponents = 0; - - await foreach (ExtendedScannedComponent package in packagesChannelReader.output.ReadAllAsync()) - { - countDistinctComponents++; - Assert.IsTrue(scannedComponents.Remove(package)); - } - - await foreach (var error in packagesChannelReader.error.ReadAllAsync()) - { - Assert.Fail($"Caught exception: {error.Message}"); - } - - Assert.AreEqual(1, scannedComponents.Count); - Assert.AreEqual(3, countDistinctComponents); - mockDetector.VerifyAll(); - } - - [TestMethod] - public void ScanWithNullOrEmptyPathSuccessTest() - { - var mockDetector = new Mock(new Mock().Object, new Mock().Object); - - var walker = new PackagesWalker(mockLogger.Object, mockDetector.Object, mockConfiguration.Object, mockSbomConfigs.Object, mockFileSystemUtils.Object, mockPackageDetailsFactory.Object, mockLicenseInformationFetcher.Object); - walker.GetComponents(null); - walker.GetComponents(string.Empty); - - mockDetector.Verify(mock => mock.ScanAsync(It.IsAny()), Times.Never()); - } - - [TestMethod] - public async Task ScanFailureTestAsync() - { - var mockDetector = new Mock(new Mock().Object, new Mock().Object); - - var scanResult = new ScanResult - { - ResultCode = ProcessingResultCode.Error, - ComponentsFound = null - }; - - mockDetector.Setup(o => o.ScanAsync(It.IsAny())).Returns(Task.FromResult(scanResult)); - var walker = new PackagesWalker(mockLogger.Object, mockDetector.Object, mockConfiguration.Object, mockSbomConfigs.Object, mockFileSystemUtils.Object, mockPackageDetailsFactory.Object, mockLicenseInformationFetcher.Object); - var packagesChannelReader = walker.GetComponents("root"); - ComponentDetectorException actualError = null; - - await foreach (var package in packagesChannelReader.output.ReadAllAsync()) - { - Assert.Fail("Packages were still returned when the detector failed."); - } - - await foreach (var error in packagesChannelReader.error.ReadAllAsync()) - { - actualError = error; - } - - Assert.IsNotNull(actualError); - mockDetector.VerifyAll(); - } - - [TestMethod] - public async Task ScanIgnoreSbomComponents() - { - var scannedComponents = new List(); - for (var i = 1; i < 4; i++) - { - var scannedComponent = new ExtendedScannedComponent - { - Component = new NpmComponent("componentName", $"{i}") - }; - - scannedComponents.Add(scannedComponent); - } - - var scannedComponentOther = new ExtendedScannedComponent - { - Component = new SpdxComponent("SPDX-2.2", new Uri("http://test.com"), "componentName", "123", "abcdf", "path1") - }; - - scannedComponents.Add(scannedComponentOther); - - var mockDetector = new Mock(new Mock().Object, new Mock().Object); - - var scanResult = new ScanResult - { - ResultCode = ProcessingResultCode.Success, - ComponentsFound = scannedComponents - }; - - mockDetector.Setup(o => o.ScanAsync(It.IsAny())).Returns(Task.FromResult(scanResult)); - var walker = new PackagesWalker(mockLogger.Object, mockDetector.Object, mockConfiguration.Object, mockSbomConfigs.Object, mockFileSystemUtils.Object, mockPackageDetailsFactory.Object, mockLicenseInformationFetcher.Object); - var packagesChannelReader = walker.GetComponents("root"); - - var discoveredComponents = await packagesChannelReader.output.ReadAllAsync().ToListAsync(); - - await foreach (var error in packagesChannelReader.error.ReadAllAsync()) - { - Assert.Fail($"Caught exception: {error.Message}"); - } - - Assert.AreEqual(discoveredComponents.Count, scannedComponents.Where(c => !(c.Component is SpdxComponent)).ToList().Count); - mockDetector.VerifyAll(); - } -} diff --git a/test/Microsoft.Sbom.Api.Tests/Executors/RelationshipGeneratorTest.cs b/test/Microsoft.Sbom.Api.Tests/Executors/RelationshipGeneratorTest.cs deleted file mode 100644 index 08c8ae6c..00000000 --- a/test/Microsoft.Sbom.Api.Tests/Executors/RelationshipGeneratorTest.cs +++ /dev/null @@ -1,129 +0,0 @@ -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -using System; -using System.Collections.Generic; -using System.Text.Json; -using System.Threading; -using System.Threading.Channels; -using System.Threading.Tasks; -using Microsoft.Sbom.Api.Manifest; -using Microsoft.Sbom.Extensions; -using Microsoft.Sbom.Extensions.Entities; -using Microsoft.VisualStudio.TestTools.UnitTesting; -using Moq; - -namespace Microsoft.Sbom.Api.Executors.Tests; - -[TestClass] -public class RelationshipGeneratorTest -{ - /// - /// This repros a channel being orhpaned by not closing it in the face of exceptions. - /// - [TestMethod] - public async Task RunShouldHandleExceptionWithoutOrphaningChannel() - { - var mock = new Mock(); - mock.Setup(m => m.RegisterManifest()).Returns(new Mock().Object); - - var m = new ManifestGeneratorProvider(new IManifestGenerator[] { mock.Object }); - - var rg = new RelationshipGenerator(m); - var r = new Relationship() { RelationshipType = RelationshipType.DEPENDS_ON }; - var rs = new List { r }; - - var mi = new ManifestInfo - { - Name = "Test", - Version = "1", - }; - mock.Setup(m => m.RegisterManifest()).Returns(mi); - m.Init(); - - mock.Setup(m => m.GenerateJsonDocument(It.IsAny())).Throws(new InvalidOperationException()); - - var channel = rg.Run(rs.GetEnumerator(), mi); - - // This timeout will cause an OperationCanceledException to be thrown if the channel is orphaned - using var cts = new CancellationTokenSource(TimeSpan.FromSeconds(3)); - - // This will immidately return if the channel is closed. - // If the channel is orphaned this will block until the timeout is reached - // which will fail the test. - await channel.WaitToReadAsync(cts.Token); - } - - [TestMethod] - public async Task RunShouldReturnTwoResults() - { - var mock = new Mock(); - mock.Setup(m => m.RegisterManifest()).Returns(new Mock().Object); - - var m = new ManifestGeneratorProvider(new IManifestGenerator[] { mock.Object }); - - var rg = new RelationshipGenerator(m); - var r = new Relationship() { RelationshipType = RelationshipType.DEPENDS_ON, SourceElementId = "one", TargetElementId = "two" }; - var r2 = new Relationship() { RelationshipType = RelationshipType.CONTAINS, SourceElementId = "three", TargetElementId = "four" }; - var rs = new List { r, r2 }; - - var mi = new ManifestInfo - { - Name = "Test", - Version = "1", - }; - mock.Setup(m => m.RegisterManifest()).Returns(mi); - m.Init(); - - var j1 = JsonDocument.Parse(JsonSerializer.Serialize(r)); - var j2 = JsonDocument.Parse(JsonSerializer.Serialize(r2)); - - var g1 = new GenerationResult { Document = j1 }; - var g2 = new GenerationResult { Document = j2 }; - - mock.Setup(m => m.GenerateJsonDocument(It.Is(r => r.RelationshipType == RelationshipType.DEPENDS_ON))).Returns(g1); - mock.Setup(m => m.GenerateJsonDocument(It.Is(r => r.RelationshipType == RelationshipType.CONTAINS))).Returns(g2); - - var channel = rg.Run(rs.GetEnumerator(), mi); - - var docs = new List(); - await foreach (var jsonDoc in channel.ReadAllAsync()) - { - docs.Add(jsonDoc); - } - - Assert.IsTrue(docs.Contains(j1)); - Assert.IsTrue(docs.Contains(j2)); - Assert.AreEqual(2, docs.Count); - } - - [TestMethod] - public async Task RunShouldNotFailWithNull() - { - var mock = new Mock(); - mock.Setup(m => m.RegisterManifest()).Returns(new Mock().Object); - - var m = new ManifestGeneratorProvider(new IManifestGenerator[] { mock.Object }); - - var rg = new RelationshipGenerator(m); - var rs = new List(); - - var mi = new ManifestInfo - { - Name = "Test", - Version = "1", - }; - mock.Setup(m => m.RegisterManifest()).Returns(mi); - m.Init(); - - var channel = rg.Run(rs.GetEnumerator(), mi); - - var docs = new List(); - await foreach (var jsonDoc in channel.ReadAllAsync()) - { - docs.Add(jsonDoc); - } - - Assert.AreEqual(0, docs.Count); - } -} diff --git a/test/Microsoft.Sbom.Api.Tests/Executors/SBOMComponentsWalkerTests.cs b/test/Microsoft.Sbom.Api.Tests/Executors/SBOMComponentsWalkerTests.cs deleted file mode 100644 index 1c8ca3bd..00000000 --- a/test/Microsoft.Sbom.Api.Tests/Executors/SBOMComponentsWalkerTests.cs +++ /dev/null @@ -1,130 +0,0 @@ -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; -using Microsoft.ComponentDetection.Contracts; -using Microsoft.ComponentDetection.Contracts.BcdeModels; -using Microsoft.ComponentDetection.Contracts.TypedComponent; -using Microsoft.ComponentDetection.Orchestrator.Commands; -using Microsoft.Sbom.Adapters.ComponentDetection; -using Microsoft.Sbom.Api.Manifest.Configuration; -using Microsoft.Sbom.Api.PackageDetails; -using Microsoft.Sbom.Api.Utils; -using Microsoft.Sbom.Common; -using Microsoft.Sbom.Common.Config; -using Microsoft.Sbom.Extensions; -using Microsoft.Sbom.Extensions.Entities; -using Microsoft.VisualStudio.TestTools.UnitTesting; -using Moq; -using Serilog.Events; -using IComponentDetector = Microsoft.Sbom.Api.Utils.IComponentDetector; -using ILogger = Serilog.ILogger; - -namespace Microsoft.Sbom.Api.Executors.Tests; - -[TestClass] -public class SBOMComponentsWalkerTests -{ - private readonly Mock mockLogger = new Mock(); - private readonly Mock mockConfiguration = new Mock(); - private readonly Mock mockSbomConfigs = new Mock(); - private readonly Mock mockFileSystem = new Mock(); - private readonly Mock mockPackageDetailsFactory = new Mock(); - private readonly Mock mockLicenseInformationFetcher = new Mock(); - - public SBOMComponentsWalkerTests() - { - ISbomConfig sbomConfig = new SbomConfig(mockFileSystem.Object) - { - ManifestJsonFilePath = "testpath" - }; - mockConfiguration.SetupGet(c => c.Verbosity).Returns(new ConfigurationSetting { Value = LogEventLevel.Information }); - mockSbomConfigs.Setup(s => s.TryGet(It.IsAny(), out sbomConfig)).Returns(true); - } - - [TestMethod] - public async Task GetComponents() - { - var scannedComponents = new List(); - for (var i = 1; i < 4; i++) - { - var scannedComponent = new ExtendedScannedComponent - { - Component = new SpdxComponent("SPDX-2.2", new Uri("http://test.uri"), "componentName", $"123{i}", "abcdef", $"path{i}"), - DetectorId = "SPDX22SBOM" - }; - - scannedComponents.Add(scannedComponent); - } - - var mockDetector = new Mock(new Mock().Object, new Mock().Object); - - var scanResult = new ScanResult - { - ResultCode = ProcessingResultCode.Success, - ComponentsFound = scannedComponents - }; - - mockDetector.Setup(o => o.ScanAsync(It.IsAny())).Returns(Task.FromResult(scanResult)); - var walker = new SBOMComponentsWalker(mockLogger.Object, mockDetector.Object, mockConfiguration.Object, mockSbomConfigs.Object, mockFileSystem.Object, mockPackageDetailsFactory.Object, mockLicenseInformationFetcher.Object); - var packagesChannelReader = walker.GetComponents("root"); - - var discoveredComponents = await packagesChannelReader.output.ReadAllAsync().ToListAsync(); - - await foreach (var error in packagesChannelReader.error.ReadAllAsync()) - { - Assert.Fail($"Caught exception: {error.Message}"); - } - - Assert.AreEqual(discoveredComponents.Count, scannedComponents.Count); - mockDetector.VerifyAll(); - } - - [TestMethod] - public async Task GetComponentsWithFiltering() - { - var scannedComponents = new List(); - for (var i = 1; i < 4; i++) - { - var scannedComponent = new ExtendedScannedComponent - { - Component = new SpdxComponent("SPDX-2.2", new Uri("http://test.uri"), "componentName", $"123{i}", "abcdef", $"path{i}"), - DetectorId = "SPDX22SBOM" - }; - - scannedComponents.Add(scannedComponent); - } - - var nonSbomComponent = new ExtendedScannedComponent - { - Component = new NpmComponent("componentName", "123"), - DetectorId = "notSPDX22SBOM" - }; - scannedComponents.Add(nonSbomComponent); - - var mockDetector = new Mock(new Mock().Object, new Mock().Object); - - var scanResult = new ScanResult - { - ResultCode = ProcessingResultCode.Success, - ComponentsFound = scannedComponents - }; - - mockDetector.Setup(o => o.ScanAsync(It.IsAny())).Returns(Task.FromResult(scanResult)); - var walker = new SBOMComponentsWalker(mockLogger.Object, mockDetector.Object, mockConfiguration.Object, mockSbomConfigs.Object, mockFileSystem.Object, mockPackageDetailsFactory.Object, mockLicenseInformationFetcher.Object); - var packagesChannelReader = walker.GetComponents("root"); - - var discoveredComponents = await packagesChannelReader.output.ReadAllAsync().ToListAsync(); - - await foreach (var error in packagesChannelReader.error.ReadAllAsync()) - { - Assert.Fail($"Caught exception: {error.Message}"); - } - - Assert.AreEqual(discoveredComponents.Count, scannedComponents.Where(c => c.Component is SpdxComponent).ToList().Count); - mockDetector.VerifyAll(); - } -} diff --git a/test/Microsoft.Sbom.Api.Tests/Executors/SPDXSBOMReaderForExternalDocumentReferenceTests.cs b/test/Microsoft.Sbom.Api.Tests/Executors/SPDXSBOMReaderForExternalDocumentReferenceTests.cs deleted file mode 100644 index 7635412a..00000000 --- a/test/Microsoft.Sbom.Api.Tests/Executors/SPDXSBOMReaderForExternalDocumentReferenceTests.cs +++ /dev/null @@ -1,194 +0,0 @@ -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -using System.Collections.Generic; -using System.Linq; -using System.Threading.Channels; -using System.Threading.Tasks; -using Microsoft.Sbom.Api.Executors; -using Microsoft.Sbom.Api.Hashing; -using Microsoft.Sbom.Api.Manifest; -using Microsoft.Sbom.Common; -using Microsoft.Sbom.Common.Config; -using Microsoft.Sbom.Contracts; -using Microsoft.Sbom.Contracts.Enums; -using Microsoft.Sbom.Extensions; -using Microsoft.Sbom.Extensions.Entities; -using Microsoft.VisualStudio.TestTools.UnitTesting; -using Moq; -using Serilog; -using Constants = Microsoft.Sbom.Api.Utils.Constants; - -namespace Microsoft.Sbom.Api.Tests.Executors; - -[TestClass] -public class SPDXSBOMReaderForExternalDocumentReferenceTests -{ - private readonly Mock mockHashGenerator = new Mock(); - private readonly Mock mockLogger = new Mock(); - private readonly ISbomConfigProvider sbomConfigs; - private readonly Mock mockConfiguration = new Mock(); - private readonly ManifestGeneratorProvider manifestGeneratorProvider; - private readonly Mock fileSystemMock = new Mock(); - - private const string JsonMissingName = "{\"documentNamespace\": \"namespace\", \"spdxVersion\": \"SPDX-2.2\", \"documentDescribes\":[\"SPDXRef - RootPackage\"]}"; - private const string JsonMissingNamespace = "{\"name\": \"docname\",\"spdxVersion\": \"SPDX-2.2\", \"documentDescribes\":[\"SPDXRef - RootPackage\"]}"; - private const string JsonMissingVersion = "{\"name\": \"docname\",\"documentNamespace\": \"namespace\",\"documentDescribes\":[\"SPDXRef - RootPackage\"]}"; - private const string JsonInvalidVersion = "{\"name\": \"docname\",\"documentNamespace\": \"namespace\", \"spdxVersion\": \"SPDX-2.1\", \"documentDescribes\":[\"SPDXRef - RootPackage\"]}"; - private const string JsonMissingDocumentDescribe = "{\"name\": \"docname\",\"documentNamespace\": \"namespace\", \"spdxVersion\": \"SPDX-2.2\"}"; - - public SPDXSBOMReaderForExternalDocumentReferenceTests() - { - mockConfiguration.SetupGet(c => c.ManifestToolAction).Returns(ManifestToolActions.Validate); - mockConfiguration.SetupGet(c => c.HashAlgorithm).Returns(new ConfigurationSetting { Value = Constants.DefaultHashAlgorithmName }); - mockConfiguration.SetupGet(c => c.BuildComponentPath).Returns(new ConfigurationSetting { Value = "root" }); - - manifestGeneratorProvider = new ManifestGeneratorProvider(new IManifestGenerator[] { new TestManifestGenerator() }); - manifestGeneratorProvider.Init(); - - var sbomConfigsMock = new Mock(); - sbomConfigsMock.Setup(c => c.GetManifestInfos()).Returns(new[] { new ManifestInfo { Name = "TestManifest", Version = "1.0.0" } }); - sbomConfigs = sbomConfigsMock.Object; - } - - [TestMethod] - public async Task When_ParseSBOMFile_WithValidSPDXJson_ThenTestPass() - { - mockHashGenerator.Setup(h => h.GenerateHashes(It.IsAny(), It.IsAny())) - .Returns((string fileName, AlgorithmName[] algos) => - algos.Select(a => - new Checksum - { - ChecksumValue = "hash", - Algorithm = a - }) - .ToArray()); - - var json = "{\"name\": \"docname\",\"documentNamespace\": \"namespace\", \"spdxVersion\": \"SPDX-2.2\", \"documentDescribes\":[\"SPDXRef - RootPackage\"]}"; - fileSystemMock.Setup(f => f.OpenRead(It.IsAny())).Returns(TestUtils.GenerateStreamFromString(json)); - - var sbomLocations = new List - { - @"d:\directorya\directoryb\file1.spdx.json" - }; - - var sbomLocationChannel = Channel.CreateUnbounded(); - foreach (var sbomLocation in sbomLocations) - { - await sbomLocationChannel.Writer.WriteAsync(sbomLocation); - } - - sbomLocationChannel.Writer.Complete(); - - var spdxSBOMReaderForExternalDocumentReference = new SPDXSBOMReaderForExternalDocumentReference(mockHashGenerator.Object, mockLogger.Object, sbomConfigs, manifestGeneratorProvider, fileSystemMock.Object); - var (output, errors) = spdxSBOMReaderForExternalDocumentReference.ParseSBOMFile(sbomLocationChannel); - await foreach (var externalDocumentReferenceInfo in output.ReadAllAsync()) - { - Assert.AreEqual("namespace", externalDocumentReferenceInfo.DocumentNamespace); - } - - Assert.IsFalse(await errors.ReadAllAsync().AnyAsync()); - } - - [TestMethod] - public async Task When_ParseSBOMFile_WithIllFormatedJson_ThenReadAsyncFail() - { - mockHashGenerator.Setup(h => h.GenerateHashes(It.IsAny(), It.IsAny())) - .Returns((string fileName, AlgorithmName[] algos) => - algos.Select(a => - new Checksum - { - ChecksumValue = "hash", - Algorithm = a - }) - .ToArray()); - var json = "{\"name\": ,\"documentNamespace\": \"namespace\"}"; - fileSystemMock.Setup(f => f.OpenRead(It.IsAny())).Returns(TestUtils.GenerateStreamFromString(json)); - - var sbomLocations = new List - { - @"d:\directorya\directoryb\file1.spdx.json" - }; - - var sbomLocationChannel = Channel.CreateUnbounded(); - foreach (var sbomLocation in sbomLocations) - { - await sbomLocationChannel.Writer.WriteAsync(sbomLocation); - } - - sbomLocationChannel.Writer.Complete(); - - var spdxSBOMReaderForExternalDocumentReference = new SPDXSBOMReaderForExternalDocumentReference(mockHashGenerator.Object, mockLogger.Object, sbomConfigs, manifestGeneratorProvider, fileSystemMock.Object); - var (output, errors) = spdxSBOMReaderForExternalDocumentReference.ParseSBOMFile(sbomLocationChannel); - - Assert.IsTrue(await errors.ReadAllAsync().AnyAsync()); - Assert.IsFalse(await output.ReadAllAsync().AnyAsync()); - } - - [TestMethod] - public async Task When_ParseSBOMFile_WithNonSPDXFile_ThenDoNotReadFiles() - { - var nonSpdxSbomLocations = new List - { - @"d:\directorya\directoryb\file1.json" - }; - - var sbomLocationChannel = Channel.CreateUnbounded(); - foreach (var sbomLocation in nonSpdxSbomLocations) - { - await sbomLocationChannel.Writer.WriteAsync(sbomLocation); - } - - sbomLocationChannel.Writer.Complete(); - - var spdxSBOMReaderForExternalDocumentReference = new SPDXSBOMReaderForExternalDocumentReference(mockHashGenerator.Object, mockLogger.Object, sbomConfigs, manifestGeneratorProvider, fileSystemMock.Object); - var (output, errors) = spdxSBOMReaderForExternalDocumentReference.ParseSBOMFile(sbomLocationChannel); - - mockHashGenerator.VerifyNoOtherCalls(); - fileSystemMock.VerifyNoOtherCalls(); - - Assert.IsFalse(await errors.ReadAllAsync().AnyAsync()); - Assert.IsFalse(await output.ReadAllAsync().AnyAsync()); - } - - [TestMethod] - [DataRow(JsonMissingName)] - [DataRow(JsonMissingNamespace)] - [DataRow(JsonMissingVersion)] - [DataRow(JsonInvalidVersion)] - [DataRow(JsonMissingDocumentDescribe)] - public async Task When_ParseSBOMFile_WithSPDXDocumentIssues_ThenThrowException(string inputJson) - { - mockHashGenerator.Setup(h => h.GenerateHashes(It.IsAny(), It.IsAny())) - .Returns((string fileName, AlgorithmName[] algos) => - algos.Select(a => - new Checksum - { - ChecksumValue = "hash", - Algorithm = a - }) - .ToArray()); - - fileSystemMock.Setup(f => f.OpenRead(It.IsAny())).Returns(TestUtils.GenerateStreamFromString(inputJson)); - - var sbomLocations = new List - { - @"d:\directorya\directoryb\file1.spdx.json" - }; - - var sbomLocationChannel = Channel.CreateUnbounded(); - foreach (var sbomLocation in sbomLocations) - { - await sbomLocationChannel.Writer.WriteAsync(sbomLocation); - } - - sbomLocationChannel.Writer.Complete(); - - var spdxSBOMReaderForExternalDocumentReference = new SPDXSBOMReaderForExternalDocumentReference(mockHashGenerator.Object, mockLogger.Object, sbomConfigs, manifestGeneratorProvider, fileSystemMock.Object); - - var (output, errors) = spdxSBOMReaderForExternalDocumentReference.ParseSBOMFile(sbomLocationChannel); - - Assert.IsTrue(await errors.ReadAllAsync().AnyAsync()); - Assert.IsFalse(await output.ReadAllAsync().AnyAsync()); - } -} diff --git a/test/Microsoft.Sbom.Api.Tests/Filters/DownloadedRootPathFilterTests.cs b/test/Microsoft.Sbom.Api.Tests/Filters/DownloadedRootPathFilterTests.cs deleted file mode 100644 index 1c1a918c..00000000 --- a/test/Microsoft.Sbom.Api.Tests/Filters/DownloadedRootPathFilterTests.cs +++ /dev/null @@ -1,58 +0,0 @@ -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -using Microsoft.Sbom.Common; -using Microsoft.Sbom.Common.Config; -using Microsoft.VisualStudio.TestTools.UnitTesting; -using Moq; -using Serilog; - -namespace Microsoft.Sbom.Api.Filters.Tests; - -[TestClass] -public class DownloadedRootPathFilterTests -{ - private readonly Mock logger = new Mock(); - - [TestMethod] - public void DownloadedRootPathFilterTest_NoFilterPath_Succeeds() - { - var fileSystemMock = new Mock(); - - var configMock = new Mock(); - configMock.SetupGet(c => c.RootPathFilter).Returns((ConfigurationSetting)null); - - var filter = new DownloadedRootPathFilter(configMock.Object, fileSystemMock.Object, logger.Object); - filter.Init(); - - Assert.IsTrue(filter.IsValid("hello")); - Assert.IsTrue(filter.IsValid(null)); - Assert.IsTrue(filter.IsValid("c:/test")); - fileSystemMock.VerifyAll(); - configMock.VerifyAll(); - } - - [TestMethod] - public void DownloadedRootPathFilterTest_FilterPath_Succeeds() - { - var fileSystemMock = new Mock(); - fileSystemMock.Setup(f => f.JoinPaths(It.IsAny(), It.IsAny())).Returns((string r, string p) => $"{r}/{p}"); - - var configMock = new Mock(); - configMock.SetupGet(c => c.BuildDropPath).Returns(new ConfigurationSetting { Value = "C:/test" }); - configMock.SetupGet(c => c.RootPathFilter).Returns(new ConfigurationSetting { Value = "validPath" }); - - var filter = new DownloadedRootPathFilter(configMock.Object, fileSystemMock.Object, logger.Object); - filter.Init(); - - Assert.IsTrue(filter.IsValid("c:/test/validPath/test")); - Assert.IsTrue(filter.IsValid("c:/test/validPath")); - Assert.IsTrue(filter.IsValid("c:/test/validPath/test/me")); - Assert.IsFalse(filter.IsValid(null)); - Assert.IsFalse(filter.IsValid("c:/test/InvalidPath")); - Assert.IsFalse(filter.IsValid("c:/test/InvalidPath/f")); - - fileSystemMock.VerifyAll(); - configMock.VerifyAll(); - } -} diff --git a/test/Microsoft.Sbom.Api.Tests/Filters/ManifestFolderFilterTests.cs b/test/Microsoft.Sbom.Api.Tests/Filters/ManifestFolderFilterTests.cs deleted file mode 100644 index 7391e262..00000000 --- a/test/Microsoft.Sbom.Api.Tests/Filters/ManifestFolderFilterTests.cs +++ /dev/null @@ -1,86 +0,0 @@ -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -using System; -using System.Runtime.InteropServices; -using Microsoft.Sbom.Common; -using Microsoft.Sbom.Common.Config; -using Microsoft.VisualStudio.TestTools.UnitTesting; -using Moq; - -namespace Microsoft.Sbom.Api.Filters.Tests; - -[TestClass] -public class ManifestFolderFilterTests -{ - private bool isWindows; - - [TestInitialize] - public void Initialize() - { - isWindows = RuntimeInformation.IsOSPlatform(OSPlatform.Windows); - } - - [TestMethod] - public void ManifestFolderFilterTest_CheckAllManifestFolder_Succeeds() - { - // If OS is not windows then don't run the windows test. - if (!isWindows) - { - Assert.Inconclusive("Test is only valid on Windows."); - } - - var mockOSUtils = new Mock(); - mockOSUtils.Setup(o => o.GetFileSystemStringComparisonType()).Returns(StringComparison.CurrentCultureIgnoreCase); - - var configMock = new Mock(); - configMock.SetupGet(c => c.ManifestDirPath).Returns(new ConfigurationSetting { Value = "C:/test/_manifest" }); - - var filter = new ManifestFolderFilter(configMock.Object, mockOSUtils.Object); - filter.Init(); - - Assert.IsTrue(filter.IsValid("c:/test")); - Assert.IsFalse(filter.IsValid(null)); - Assert.IsTrue(filter.IsValid("c:/test/me")); - Assert.IsTrue(filter.IsValid("me")); - Assert.IsTrue(filter.IsValid("d:/me")); - Assert.IsTrue(filter.IsValid("c:/test\\me")); - Assert.IsTrue(filter.IsValid("c:\\test/me")); - Assert.IsFalse(filter.IsValid("c:/test/_manifest")); - Assert.IsFalse(filter.IsValid("c:/test/_manifest/manifest.json")); - Assert.IsFalse(filter.IsValid("c:\\test\\_manifest")); - Assert.IsFalse(filter.IsValid("c:/test/_manifest\\manifest.json")); - configMock.VerifyAll(); - } - - [TestMethod] - public void ManifestFolderFilterTest_CheckAllManifestFolder_Succeeds_LinuxBased() - { - // if OS is windows then don't run the linux test - if (isWindows) - { - Assert.Inconclusive("Test is only valid on Linux."); - } - - var mockOSUtils = new Mock(); - mockOSUtils.Setup(o => o.GetFileSystemStringComparisonType()).Returns(StringComparison.CurrentCultureIgnoreCase); - - var configMock = new Mock(); - configMock.SetupGet(c => c.ManifestDirPath).Returns(new ConfigurationSetting { Value = "home/test/_manifest" }); - - var filter = new ManifestFolderFilter(configMock.Object, mockOSUtils.Object); - filter.Init(); - - Assert.IsTrue(filter.IsValid("home/test")); - Assert.IsFalse(filter.IsValid(null)); - Assert.IsTrue(filter.IsValid("home/test/me")); - Assert.IsTrue(filter.IsValid("me")); - Assert.IsTrue(filter.IsValid("home/me")); - Assert.IsTrue(filter.IsValid("home/test\\me")); - Assert.IsTrue(filter.IsValid("home\\test/me")); - Assert.IsFalse(filter.IsValid("home/test/_manifest")); - Assert.IsFalse(filter.IsValid("home/test/_manifest/manifest.json")); - Assert.IsFalse(filter.IsValid("home/test/_manifest\\manifest.json")); - configMock.VerifyAll(); - } -} diff --git a/test/Microsoft.Sbom.Api.Tests/FormatValidator/FormatValidatorTestStrings.cs b/test/Microsoft.Sbom.Api.Tests/FormatValidator/FormatValidatorTestStrings.cs deleted file mode 100644 index 88457db1..00000000 --- a/test/Microsoft.Sbom.Api.Tests/FormatValidator/FormatValidatorTestStrings.cs +++ /dev/null @@ -1,197 +0,0 @@ -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -namespace Microsoft.Sbom.Api.Tests.FormatValidator; - -internal readonly struct FormatValidatorTestStrings -{ - // Means a legal 2.x SPDX with required SPDX properties, packages, and relationships. - // Files may be present but will be ignored. - public const string JsonSuitableForRedaction = /*lang=json,strict*/ @"{ - ""files"":[], - ""packages"":[], - ""relationships"":[], - ""externalDocumentRefs"":[], - ""spdxVersion"": ""SPDX-2.2"", - ""dataLicense"": ""CC0-1.0"", - ""SPDXID"": ""SPDXRef-DOCUMENT"", - ""name"": ""sbom-tool 1.0.0"", - ""documentNamespace"": ""https://microsoft.com/sbom-tool/test/sbom-tool/1.0.0/cuK7iCCPVEuSmgBfeFPc-g"", - ""creationInfo"": { - ""created"": ""2024-05-08T15:58:25Z"", - ""creators"": [ - ""Organization: Test"", - ""Tool: Microsoft.SBOMTool-2.2.5"" - ]}, - ""documentDescribes"": [ - ""SPDXRef-RootPackage"" - ]}"; - - public const string JsonMissingSpdxVersion = /*lang=json,strict*/ @"{ - ""files"":[], - ""packages"":[], - ""relationships"":[], - ""externalDocumentRefs"":[], - ""dataLicense"": ""CC0-1.0"", - ""SPDXID"": ""SPDXRef-DOCUMENT"", - ""name"": ""sbom-tool 1.0.0"", - ""documentNamespace"": ""https://microsoft.com/sbom-tool/test/sbom-tool/1.0.0/cuK7iCCPVEuSmgBfeFPc-g"", - ""creationInfo"": { - ""created"": ""2024-05-08T15:58:25Z"", - ""creators"": [ - ""Organization: Test"", - ""Tool: Microsoft.SBOMTool-2.2.5"" - ]}, - ""documentDescribes"": [ - ""SPDXRef-RootPackage"" - ]}"; - - public const string JsonMissingDocumentNamespace = /*lang=json,strict*/ @"{ - ""files"":[], - ""packages"":[], - ""relationships"":[], - ""externalDocumentRefs"":[], - ""dataLicense"": ""CC0-1.0"", - ""spdxVersion"": ""SPDX-2.2"", - ""name"": ""sbom-tool 1.0.0"", - ""SPDXID"": ""SPDXRef-DOCUMENT"", - ""creationInfo"": { - ""created"": ""2024-05-08T15:58:25Z"", - ""creators"": [ - ""Organization: Test"", - ""Tool: Microsoft.SBOMTool-2.2.5"" - ]}, - ""documentDescribes"": [ - ""SPDXRef-RootPackage"" - ]}"; - - public const string JsonMissingSpdxDataLicense = /*lang=json,strict*/ @"{ - ""files"":[], - ""packages"":[], - ""relationships"":[], - ""externalDocumentRefs"":[], - ""spdxVersion"": ""SPDX-2.2"", - ""SPDXID"": ""SPDXRef-DOCUMENT"", - ""name"": ""sbom-tool 1.0.0"", - ""documentNamespace"": ""https://microsoft.com/sbom-tool/test/sbom-tool/1.0.0/cuK7iCCPVEuSmgBfeFPc-g"", - ""creationInfo"": { - ""created"": ""2024-05-08T15:58:25Z"", - ""creators"": [ - ""Organization: Test"", - ""Tool: Microsoft.SBOMTool-2.2.5"" - ]}, - ""documentDescribes"": [ - ""SPDXRef-RootPackage"" - ]}"; - - public const string JsonMissingSpdxName = /*lang=json,strict*/ @"{ - ""files"":[], - ""packages"":[], - ""relationships"":[], - ""externalDocumentRefs"":[], - ""spdxVersion"": ""SPDX-2.2"", - ""SPDXID"": ""SPDXRef-DOCUMENT"", - ""dataLicense"": ""CC0-1.0"", - ""documentNamespace"": ""https://microsoft.com/sbom-tool/test/sbom-tool/1.0.0/cuK7iCCPVEuSmgBfeFPc-g"", - ""creationInfo"": { - ""created"": ""2024-05-08T15:58:25Z"", - ""creators"": [ - ""Organization: Test"", - ""Tool: Microsoft.SBOMTool-2.2.5"" - ]}, - ""documentDescribes"": [ - ""SPDXRef-RootPackage"" - ]}"; - - public const string JsonMissingSpdxPackages = /*lang=json,strict*/ @"{ - ""files"":[], - ""relationships"":[], - ""name"": ""sbom-tool 1.0.0"", - ""externalDocumentRefs"":[], - ""spdxVersion"": ""SPDX-2.2"", - ""SPDXID"": ""SPDXRef-DOCUMENT"", - ""dataLicense"": ""CC0-1.0"", - ""documentNamespace"": ""https://microsoft.com/sbom-tool/test/sbom-tool/1.0.0/cuK7iCCPVEuSmgBfeFPc-g"", - ""creationInfo"": { - ""created"": ""2024-05-08T15:58:25Z"", - ""creators"": [ - ""Organization: Test"", - ""Tool: Microsoft.SBOMTool-2.2.5"" - ]}, - ""documentDescribes"": [ - ""SPDXRef-RootPackage"" - ]}"; - - public const string JsonMissingSpdxRelationships = /*lang=json,strict*/ @"{ - ""files"":[], - ""packages"":[], - ""name"": ""sbom-tool 1.0.0"", - ""externalDocumentRefs"":[], - ""spdxVersion"": ""SPDX-2.2"", - ""SPDXID"": ""SPDXRef-DOCUMENT"", - ""dataLicense"": ""CC0-1.0"", - ""documentNamespace"": ""https://microsoft.com/sbom-tool/test/sbom-tool/1.0.0/cuK7iCCPVEuSmgBfeFPc-g"", - ""creationInfo"": { - ""created"": ""2024-05-08T15:58:25Z"", - ""creators"": [ - ""Organization: Test"", - ""Tool: Microsoft.SBOMTool-2.2.5"" - ]}, - ""documentDescribes"": [ - ""SPDXRef-RootPackage"" - ]}"; - - public const string JsonMissingSpdxCreationInfo = /*lang=json,strict*/ @"{ - ""files"":[], - ""packages"":[], - ""relationships"":[], - ""externalDocumentRefs"":[], - ""name"": ""sbom-tool 1.0.0"", - ""spdxVersion"": ""SPDX-2.2"", - ""SPDXID"": ""SPDXRef-DOCUMENT"", - ""dataLicense"": ""CC0-1.0"", - ""documentNamespace"": ""https://microsoft.com/sbom-tool/test/sbom-tool/1.0.0/cuK7iCCPVEuSmgBfeFPc-g"", - ""documentDescribes"": [ - ""SPDXRef-RootPackage"" - ]}"; - - public const string JsonUnsupportedSpdxVersion = /*lang=json,strict*/ @"{ - ""files"":[], - ""packages"":[], - ""relationships"":[], - ""name"": ""sbom-tool 1.0.0"", - ""externalDocumentRefs"":[], - ""spdxVersion"": ""SPDX-3.2"", - ""SPDXID"": ""SPDXRef-DOCUMENT"", - ""dataLicense"": ""CC0-1.0"", - ""documentNamespace"": ""https://microsoft.com/sbom-tool/test/sbom-tool/1.0.0/cuK7iCCPVEuSmgBfeFPc-g"", - ""creationInfo"": { - ""created"": ""2024-05-08T15:58:25Z"", - ""creators"": [ - ""Organization: Test"", - ""Tool: Microsoft.SBOMTool-2.2.5"" - ]}, - ""documentDescribes"": [ - ""SPDXRef-RootPackage"" - ]}"; - - public const string MalformedJson = @"{ - ""files"":[], - ""packages"":[], - ""relationships"":[], - ""name"": ""sbom-tool 1.0.0"", - ""externalDocumentRefs"":[, - ""spdxVersion"": ""SPDX-3.2"", - ""SPDXID"": ""SPDXRef-DOCUMENT"", - ""dataLicense"": ""CC0-1.0"", - ""documentNamespace"": ""https://microsoft.com/sbom-tool/test/sbom-tool/1.0.0/cuK7iCCPVEuSmgBfeFPc-g"", - ""creationInfo"": { - ""created"": ""2024-05-08T15:58:25Z"", - ""creators"": [ - ""Organization: Test"", - ""Tool: Microsoft.SBOMTool-2.2.5"" - ]}, - ""documentDescribes"": [ - ""SPDXRef-RootPackage"" - ]}"; -} diff --git a/test/Microsoft.Sbom.Api.Tests/FormatValidator/FormatValidatorTests.cs b/test/Microsoft.Sbom.Api.Tests/FormatValidator/FormatValidatorTests.cs deleted file mode 100644 index dd0a2565..00000000 --- a/test/Microsoft.Sbom.Api.Tests/FormatValidator/FormatValidatorTests.cs +++ /dev/null @@ -1,185 +0,0 @@ -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Microsoft.Sbom.Api.FormatValidator; -using Microsoft.Sbom.Utils; -using Microsoft.VisualStudio.TestTools.UnitTesting; - -namespace Microsoft.Sbom.Api.Tests.FormatValidator; - -[TestClass] -public class FormatValidatorTests -{ - [TestMethod] - public async Task FormatValidator_CanReadValidSbom() - { - using (var sbomStream = CreateStream(FormatValidatorTestStrings.JsonSuitableForRedaction)) - { - var sbom = new ValidatedSBOM(sbomStream); - var rawspdx = await sbom.GetRawSPDXDocument(); - var details = await sbom.GetValidationResults(); - - Assert.AreEqual(FormatValidationStatus.Valid, details.Status); - Assert.AreEqual(0, details.Errors.Count); - Assert.IsNotNull(rawspdx); - Assert.AreEqual("SPDX-2.2", rawspdx.Version); - Assert.AreEqual("CC0-1.0", rawspdx.DataLicense); - Assert.AreEqual("sbom-tool 1.0.0", rawspdx.Name); - Assert.AreEqual("https://microsoft.com/sbom-tool/test/sbom-tool/1.0.0/cuK7iCCPVEuSmgBfeFPc-g", rawspdx.DocumentNamespace); - Assert.AreEqual("2024-05-08T15:58:25Z", rawspdx.CreationInfo.Created); - Assert.IsNotNull(rawspdx.CreationInfo.Creators); - Assert.IsNotNull(rawspdx.DocumentDescribes); - } - } - - [DataTestMethod] - [DataRow(FormatValidatorTestStrings.JsonMissingSpdxVersion, "spdxVersion")] - [DataRow(FormatValidatorTestStrings.JsonMissingSpdxDataLicense, "dataLicense")] - [DataRow(FormatValidatorTestStrings.JsonMissingDocumentNamespace, "documentNamespace")] - [DataRow(FormatValidatorTestStrings.JsonMissingSpdxName, "name")] - [DataRow(FormatValidatorTestStrings.JsonMissingSpdxPackages, "packages")] - [DataRow(FormatValidatorTestStrings.JsonMissingSpdxRelationships, "relationships")] - [DataRow(FormatValidatorTestStrings.JsonMissingSpdxCreationInfo, "creationInfo")] - public async Task FormatValidator_FailsIfRequiredAttributeMissing(string json, string attribute) - { - using (var sbomStream = CreateStream(json)) - { - var sbom = new ValidatedSBOM(sbomStream); - var rawspdx = await sbom.GetRawSPDXDocument(); - var details = await sbom.GetValidationResults(); - - Assert.AreEqual(FormatValidationStatus.NotValid, details.Status); - Assert.IsTrue(details.Errors.Count > 0); - - // We want the error message to clearly signal the missing element. - Assert.IsTrue(ErrorContains(details.Errors, attribute)); - Assert.IsTrue(ErrorContains(details.Errors, "missing required properties")); - } - } - - [TestMethod] - public async Task FormatValidator_FailsForUnsupportedVersion() - { - // In the real world this is an unlikely scenario; SPDX v3 is so different from v2 that an attempt - // to deserialize using a v2 model will fail. So this is more likely to catch some scenario where - // the document was 2.x but the version was improperly serialized. - using (var sbomStream = CreateStream(FormatValidatorTestStrings.JsonUnsupportedSpdxVersion)) - { - var sbom = new ValidatedSBOM(sbomStream); - var rawspdx = await sbom.GetRawSPDXDocument(); - var details = await sbom.GetValidationResults(); - - Assert.AreEqual(FormatValidationStatus.NotValid, details.Status); - Assert.IsTrue(details.Errors.Count > 0); - - // We want the error message to clearly signal the erroring element. - Assert.IsTrue(ErrorContains(details.Errors, "SPDX-3.2 is not recognized")); - } - } - - [TestMethod] - public async Task FormatValidator_FailsForMalformedJson() - { - using (var sbomStream = CreateStream(FormatValidatorTestStrings.MalformedJson)) - { - var sbom = new ValidatedSBOM(sbomStream); - var rawspdx = await sbom.GetRawSPDXDocument(); - var details = await sbom.GetValidationResults(); - - Assert.AreEqual(FormatValidationStatus.NotValid, details.Status); - Assert.IsTrue(details.Errors.Count > 0); - - // We want the error message to indicate that this is a Json parse error, and providing - // context on where the error occurred is helpful too. - Assert.IsTrue(ErrorContains(details.Errors, "is an invalid start of a value")); - Assert.IsTrue(ErrorContains(details.Errors, "Path: $.externalDocumentRefs[0]")); - } - } - - [TestMethod] - public async Task FormatValidator_CanDeserializeAllSpdx23Attributes() - { - using (var sbomStream = CreateStream(SpdxExemplars.JsonSpdx23Exemplar)) - { - var sbom = new ValidatedSBOM(sbomStream); - var rawspdx = await sbom.GetRawSPDXDocument(); - var details = await sbom.GetValidationResults(); - - Assert.AreEqual(FormatValidationStatus.Valid, details.Status); - Assert.AreEqual("SPDXRef-DOCUMENT", rawspdx.SPDXID); - Assert.AreEqual("SPDX-2.3", rawspdx.Version); - Assert.AreEqual("CC0-1.0", rawspdx.DataLicense); - Assert.AreEqual(5, rawspdx.ExtractedLicensingInfos.ToList().Count); - Assert.AreEqual(1, rawspdx.ExternalDocumentReferences.ToList().Count); - Assert.AreEqual(3, rawspdx.Annotations.ToList().Count); - Assert.AreEqual(1, rawspdx.Snippets.ToList().Count); - } - } - - [TestMethod] - public void ValidationDetails_AggregateValidationStatus() - { - var details = new FormatValidationResults(); - details.AggregateValidationStatus(FormatValidationStatus.Valid); - Assert.AreEqual(FormatValidationStatus.Valid, details.Status); - - details.AggregateValidationStatus(FormatValidationStatus.Valid); - Assert.AreEqual(FormatValidationStatus.Valid, details.Status); - - details.AggregateValidationStatus(FormatValidationStatus.NotValid); - Assert.AreEqual(FormatValidationStatus.NotValid, details.Status); - - // Once we detect any validation failure, the status should always stay NotValid. - details.AggregateValidationStatus(FormatValidationStatus.Valid); - Assert.AreEqual(FormatValidationStatus.NotValid, details.Status); - } - - [TestMethod] - public void SPDXVersionParsing_CanParseVersion() - { - var version = "SPDX-2.3"; - var versionMatched = SPDXVersionParser.VersionMatchesRequiredVersion(version, 2); - Assert.IsTrue(versionMatched); - - version = "SPDX-2.2"; - versionMatched = SPDXVersionParser.VersionMatchesRequiredVersion(version, 2); - Assert.IsTrue(versionMatched); - - version = "version 2.2"; - versionMatched = SPDXVersionParser.VersionMatchesRequiredVersion(version, 2); - Assert.IsFalse(versionMatched); - - version = "SPDX-3.0"; - versionMatched = SPDXVersionParser.VersionMatchesRequiredVersion(version, 2); - Assert.IsFalse(versionMatched); - - version = "frimplepants"; - versionMatched = SPDXVersionParser.VersionMatchesRequiredVersion(version, 2); - Assert.IsFalse(versionMatched); - } - - private Stream CreateStream(string json) - { - var utf8BOM = Encoding.UTF8.GetString(Encoding.UTF8.Preamble); - var bytes = Encoding.UTF8.GetBytes(utf8BOM + json); - return new MemoryStream(bytes); - } - - private bool ErrorContains(List errors, string message) - { - foreach (var error in errors) - { - if (error.Contains(message)) - { - return true; - } - } - - return false; - } -} diff --git a/test/Microsoft.Sbom.Api.Tests/FormatValidator/SpdxExemplars.cs b/test/Microsoft.Sbom.Api.Tests/FormatValidator/SpdxExemplars.cs deleted file mode 100644 index fe8634b5..00000000 --- a/test/Microsoft.Sbom.Api.Tests/FormatValidator/SpdxExemplars.cs +++ /dev/null @@ -1,306 +0,0 @@ -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -namespace Microsoft.Sbom.Api.Tests.FormatValidator; - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -internal readonly struct SpdxExemplars -{ - public const string JsonSpdx23Exemplar = /*lang=json,strict*/ @"{ - ""SPDXID"" : ""SPDXRef-DOCUMENT"", - ""spdxVersion"" : ""SPDX-2.3"", - ""creationInfo"" : { - ""comment"" : ""This package has been shipped in source and binary form.\nThe binaries were created with gcc 4.5.1 and expect to link to\ncompatible system run time libraries."", - ""created"" : ""2010-01-29T18:30:22Z"", - ""creators"" : [ ""Tool: LicenseFind-1.0"", ""Organization: ExampleCodeInspect ()"", ""Person: Jane Doe ()"" ], - ""licenseListVersion"" : ""3.17"" - }, - ""name"" : ""SPDX-Tools-v2.0"", - ""dataLicense"" : ""CC0-1.0"", - ""comment"" : ""This document was created using SPDX 2.0 using licenses from the web site."", - ""externalDocumentRefs"" : [ { - ""externalDocumentId"" : ""DocumentRef-spdx-tool-1.2"", - ""checksum"" : { - ""algorithm"" : ""SHA1"", - ""checksumValue"" : ""d6a770ba38583ed4bb4525bd96e50461655d2759"" - }, - ""spdxDocument"" : ""http://spdx.org/spdxdocs/spdx-tools-v1.2-3F2504E0-4F89-41D3-9A0C-0305E82C3301"" - } ], - ""hasExtractedLicensingInfos"" : [ { - ""licenseId"" : ""LicenseRef-1"", - ""extractedText"" : ""/*\n * (c) Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 Hewlett-Packard Development Company, LP\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n * notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n * notice, this list of conditions and the following disclaimer in the\n * documentation and/or other materials provided with the distribution.\n * 3. The name of the author may not be used to endorse or promote products\n * derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/"" - }, { - ""licenseId"" : ""LicenseRef-2"", - ""extractedText"" : ""This package includes the GRDDL parser developed by Hewlett Packard under the following license:\n© Copyright 2007 Hewlett-Packard Development Company, LP\n\nRedistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: \n\nRedistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. \nRedistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. \nThe name of the author may not be used to endorse or promote products derived from this software without specific prior written permission. \nTHIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."" - }, { - ""licenseId"" : ""LicenseRef-4"", - ""extractedText"" : ""/*\n * (c) Copyright 2009 University of Bristol\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n * notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n * notice, this list of conditions and the following disclaimer in the\n * documentation and/or other materials provided with the distribution.\n * 3. The name of the author may not be used to endorse or promote products\n * derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/"" - }, { - ""licenseId"" : ""LicenseRef-Beerware-4.2"", - ""comment"" : ""The beerware license has a couple of other standard variants."", - ""extractedText"" : ""\""THE BEER-WARE LICENSE\"" (Revision 42):\nphk@FreeBSD.ORG wrote this file. As long as you retain this notice you\ncan do whatever you want with this stuff. If we meet some day, and you think this stuff is worth it, you can buy me a beer in return Poul-Henning Kamp"", - ""name"" : ""Beer-Ware License (Version 42)"", - ""seeAlsos"" : [ ""http://people.freebsd.org/~phk/"" ] - }, { - ""licenseId"" : ""LicenseRef-3"", - ""comment"" : ""This is tye CyperNeko License"", - ""extractedText"" : ""The CyberNeko Software License, Version 1.0\n\n \n(C) Copyright 2002-2005, Andy Clark. All rights reserved.\n \nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n\n1. Redistributions of source code must retain the above copyright\n notice, this list of conditions and the following disclaimer. \n\n2. Redistributions in binary form must reproduce the above copyright\n notice, this list of conditions and the following disclaimer in\n the documentation and/or other materials provided with the\n distribution.\n\n3. The end-user documentation included with the redistribution,\n if any, must include the following acknowledgment: \n \""This product includes software developed by Andy Clark.\""\n Alternately, this acknowledgment may appear in the software itself,\n if and wherever such third-party acknowledgments normally appear.\n\n4. The names \""CyberNeko\"" and \""NekoHTML\"" must not be used to endorse\n or promote products derived from this software without prior \n written permission. For written permission, please contact \n andyc@cyberneko.net.\n\n5. Products derived from this software may not be called \""CyberNeko\"",\n nor may \""CyberNeko\"" appear in their name, without prior written\n permission of the author.\n\nTHIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED\nWARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\nOF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\nDISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR OTHER CONTRIBUTORS\nBE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, \nOR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT \nOF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR \nBUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, \nWHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE \nOR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, \nEVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."", - ""name"" : ""CyberNeko License"", - ""seeAlsos"" : [ ""http://people.apache.org/~andyc/neko/LICENSE"", ""http://justasample.url.com"" ] - } ], - ""annotations"" : [ { - ""annotationDate"" : ""2010-01-29T18:30:22Z"", - ""annotationType"" : ""OTHER"", - ""annotator"" : ""Person: Jane Doe ()"", - ""comment"" : ""Document level annotation"" - }, { - ""annotationDate"" : ""2010-02-10T00:00:00Z"", - ""annotationType"" : ""REVIEW"", - ""annotator"" : ""Person: Joe Reviewer"", - ""comment"" : ""This is just an example. Some of the non-standard licenses look like they are actually BSD 3 clause licenses"" - }, { - ""annotationDate"" : ""2011-03-13T00:00:00Z"", - ""annotationType"" : ""REVIEW"", - ""annotator"" : ""Person: Suzanne Reviewer"", - ""comment"" : ""Another example reviewer."" - } ], - ""documentDescribes"" : [ ""SPDXRef-File"", ""SPDXRef-Package"" ], - ""documentNamespace"" : ""http://spdx.org/spdxdocs/spdx-example-444504E0-4F89-41D3-9A0C-0305E82C3301"", - ""packages"" : [ { - ""SPDXID"" : ""SPDXRef-Package"", - ""annotations"" : [ { - ""annotationDate"" : ""2011-01-29T18:30:22Z"", - ""annotationType"" : ""OTHER"", - ""annotator"" : ""Person: Package Commenter"", - ""comment"" : ""Package level annotation"" - } ], - ""attributionTexts"" : [ ""The GNU C Library is free software. See the file COPYING.LIB for copying conditions, and LICENSES for notices about a few contributions that require these additional notices to be distributed. License copyright years may be listed using range notation, e.g., 1996-2015, indicating that every year in the range, inclusive, is a copyrightable year that would otherwise be listed individually."" ], - ""builtDate"" : ""2011-01-29T18:30:22Z"", - ""checksums"" : [ { - ""algorithm"" : ""MD5"", - ""checksumValue"" : ""624c1abb3664f4b35547e7c73864ad24"" - }, { - ""algorithm"" : ""SHA1"", - ""checksumValue"" : ""85ed0817af83a24ad8da68c2b5094de69833983c"" - }, { - ""algorithm"" : ""SHA256"", - ""checksumValue"" : ""11b6d3ee554eedf79299905a98f9b9a04e498210b59f15094c916c91d150efcd"" - }, { - ""algorithm"" : ""BLAKE2b-384"", - ""checksumValue"" : ""aaabd89c926ab525c242e6621f2f5fa73aa4afe3d9e24aed727faaadd6af38b620bdb623dd2b4788b1c8086984af8706"" - } ], - ""copyrightText"" : ""Copyright 2008-2010 John Smith"", - ""description"" : ""The GNU C Library defines functions that are specified by the ISO C standard, as well as additional features specific to POSIX and other derivatives of the Unix operating system, and extensions specific to GNU systems."", - ""downloadLocation"" : ""http://ftp.gnu.org/gnu/glibc/glibc-ports-2.15.tar.gz"", - ""externalRefs"" : [ { - ""referenceCategory"" : ""SECURITY"", - ""referenceLocator"" : ""cpe:2.3:a:pivotal_software:spring_framework:4.1.0:*:*:*:*:*:*:*"", - ""referenceType"" : ""cpe23Type"" - }, { - ""comment"" : ""This is the external ref for Acme"", - ""referenceCategory"" : ""OTHER"", - ""referenceLocator"" : ""acmecorp/acmenator/4.1.3-alpha"", - ""referenceType"" : ""http://spdx.org/spdxdocs/spdx-example-444504E0-4F89-41D3-9A0C-0305E82C3301#LocationRef-acmeforge"" - } ], - ""filesAnalyzed"" : true, - ""homepage"" : ""http://ftp.gnu.org/gnu/glibc"", - ""licenseComments"" : ""The license for this project changed with the release of version x.y. The version of the project included here post-dates the license change."", - ""licenseConcluded"" : ""(LGPL-2.0-only OR LicenseRef-3)"", - ""licenseDeclared"" : ""(LGPL-2.0-only AND LicenseRef-3)"", - ""licenseInfoFromFiles"" : [ ""GPL-2.0-only"", ""LicenseRef-2"", ""LicenseRef-1"" ], - ""name"" : ""glibc"", - ""originator"" : ""Organization: ExampleCodeInspect (contact@example.com)"", - ""packageFileName"" : ""glibc-2.11.1.tar.gz"", - ""packageVerificationCode"" : { - ""packageVerificationCodeExcludedFiles"" : [ ""./package.spdx"" ], - ""packageVerificationCodeValue"" : ""d6a770ba38583ed4bb4525bd96e50461655d2758"" - }, - ""primaryPackagePurpose"" : ""SOURCE"", - ""hasFiles"" : [ ""SPDXRef-Specification"", ""SPDXRef-Specification"", ""SPDXRef-CommonsLangSrc"", ""SPDXRef-Specification"", ""SPDXRef-CommonsLangSrc"", ""SPDXRef-JenaLib"", ""SPDXRef-Specification"", ""SPDXRef-CommonsLangSrc"", ""SPDXRef-JenaLib"", ""SPDXRef-DoapSource"", ""SPDXRef-Specification"", ""SPDXRef-CommonsLangSrc"", ""SPDXRef-JenaLib"", ""SPDXRef-DoapSource"" ], - ""releaseDate"" : ""2012-01-29T18:30:22Z"", - ""sourceInfo"" : ""uses glibc-2_11-branch from git://sourceware.org/git/glibc.git."", - ""summary"" : ""GNU C library."", - ""supplier"" : ""Person: Jane Doe (jane.doe@example.com)"", - ""validUntilDate"" : ""2014-01-29T18:30:22Z"", - ""versionInfo"" : ""2.11.1"" - }, { - ""SPDXID"" : ""SPDXRef-fromDoap-1"", - ""copyrightText"" : ""NOASSERTION"", - ""downloadLocation"" : ""NOASSERTION"", - ""filesAnalyzed"" : false, - ""homepage"" : ""http://commons.apache.org/proper/commons-lang/"", - ""licenseConcluded"" : ""NOASSERTION"", - ""licenseDeclared"" : ""NOASSERTION"", - ""supplier"" : ""Person: Jane Doe (jane.doe@example.com)"", - ""name"" : ""Apache Commons Lang"" - }, { - ""SPDXID"" : ""SPDXRef-fromDoap-0"", - ""downloadLocation"" : ""https://search.maven.org/remotecontent?filepath=org/apache/jena/apache-jena/3.12.0/apache-jena-3.12.0.tar.gz"", - ""externalRefs"" : [ { - ""referenceCategory"" : ""PACKAGE-MANAGER"", - ""referenceLocator"" : ""pkg:maven/org.apache.jena/apache-jena@3.12.0"", - ""referenceType"" : ""purl"" - } ], - ""supplier"": ""NOASSERTION"", - ""filesAnalyzed"" : false, - ""homepage"" : ""http://www.openjena.org/"", - ""name"" : ""Jena"", - ""versionInfo"" : ""3.12.0"" - }, { - ""SPDXID"" : ""SPDXRef-Saxon"", - ""checksums"" : [ { - ""algorithm"" : ""SHA1"", - ""checksumValue"" : ""85ed0817af83a24ad8da68c2b5094de69833983c"" - } ], - ""copyrightText"" : ""Copyright Saxonica Ltd"", - ""description"" : ""The Saxon package is a collection of tools for processing XML documents."", - ""downloadLocation"" : ""https://sourceforge.net/projects/saxon/files/Saxon-B/8.8.0.7/saxonb8-8-0-7j.zip/download"", - ""filesAnalyzed"" : false, - ""homepage"" : ""http://saxon.sourceforge.net/"", - ""licenseComments"" : ""Other versions available for a commercial license"", - ""licenseConcluded"" : ""MPL-1.0"", - ""licenseDeclared"" : ""MPL-1.0"", - ""name"" : ""Saxon"", - ""packageFileName"" : ""saxonB-8.8.zip"", - ""supplier"" : ""Person: Jane Doe (jane.doe@example.com)"", - ""versionInfo"" : ""8.8"" - } ], - ""files"" : [ { - ""SPDXID"" : ""SPDXRef-DoapSource"", - ""checksums"" : [ { - ""algorithm"" : ""SHA1"", - ""checksumValue"" : ""2fd4e1c67a2d28fced849ee1bb76e7391b93eb12"" - } ], - ""copyrightText"" : ""Copyright 2010, 2011 Source Auditor Inc."", - ""fileContributors"" : [ ""Protecode Inc."", ""SPDX Technical Team Members"", ""Open Logic Inc."", ""Source Auditor Inc."", ""Black Duck Software In.c"" ], - ""fileName"" : ""./src/org/spdx/parser/DOAPProject.java"", - ""fileTypes"" : [ ""SOURCE"" ], - ""licenseConcluded"" : ""Apache-2.0"", - ""licenseInfoInFiles"" : [ ""Apache-2.0"" ] - }, { - ""SPDXID"" : ""SPDXRef-CommonsLangSrc"", - ""checksums"" : [ { - ""algorithm"" : ""SHA1"", - ""checksumValue"" : ""c2b4e1c67a2d28fced849ee1bb76e7391b93f125"" - } ], - ""comment"" : ""This file is used by Jena"", - ""copyrightText"" : ""Copyright 2001-2011 The Apache Software Foundation"", - ""fileContributors"" : [ ""Apache Software Foundation"" ], - ""fileName"" : ""./lib-source/commons-lang3-3.1-sources.jar"", - ""fileTypes"" : [ ""ARCHIVE"" ], - ""licenseConcluded"" : ""Apache-2.0"", - ""licenseInfoInFiles"" : [ ""Apache-2.0"" ], - ""noticeText"" : ""Apache Commons Lang\nCopyright 2001-2011 The Apache Software Foundation\n\nThis product includes software developed by\nThe Apache Software Foundation (http://www.apache.org/).\n\nThis product includes software from the Spring Framework,\nunder the Apache License 2.0 (see: StringUtils.containsWhitespace())"" - }, { - ""SPDXID"" : ""SPDXRef-JenaLib"", - ""checksums"" : [ { - ""algorithm"" : ""SHA1"", - ""checksumValue"" : ""3ab4e1c67a2d28fced849ee1bb76e7391b93f125"" - } ], - ""comment"" : ""This file belongs to Jena"", - ""copyrightText"" : ""(c) Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 Hewlett-Packard Development Company, LP"", - ""fileContributors"" : [ ""Apache Software Foundation"", ""Hewlett Packard Inc."" ], - ""fileName"" : ""./lib-source/jena-2.6.3-sources.jar"", - ""fileTypes"" : [ ""ARCHIVE"" ], - ""licenseComments"" : ""This license is used by Jena"", - ""licenseConcluded"" : ""LicenseRef-1"", - ""licenseInfoInFiles"" : [ ""LicenseRef-1"" ] - }, { - ""SPDXID"" : ""SPDXRef-Specification"", - ""checksums"" : [ { - ""algorithm"" : ""SHA1"", - ""checksumValue"" : ""fff4e1c67a2d28fced849ee1bb76e7391b93f125"" - } ], - ""comment"" : ""Specification Documentation"", - ""fileName"" : ""./docs/myspec.pdf"", - ""fileTypes"" : [ ""DOCUMENTATION"" ] - }, { - ""SPDXID"" : ""SPDXRef-File"", - ""annotations"" : [ { - ""annotationDate"" : ""2011-01-29T18:30:22Z"", - ""annotationType"" : ""OTHER"", - ""annotator"" : ""Person: File Commenter"", - ""comment"" : ""File level annotation"" - } ], - ""checksums"" : [ { - ""algorithm"" : ""SHA1"", - ""checksumValue"" : ""d6a770ba38583ed4bb4525bd96e50461655d2758"" - }, { - ""algorithm"" : ""MD5"", - ""checksumValue"" : ""624c1abb3664f4b35547e7c73864ad24"" - } ], - ""comment"" : ""The concluded license was taken from the package level that the file was included in.\nThis information was found in the COPYING.txt file in the xyz directory."", - ""copyrightText"" : ""Copyright 2008-2010 John Smith"", - ""fileContributors"" : [ ""The Regents of the University of California"", ""Modified by Paul Mundt lethal@linux-sh.org"", ""IBM Corporation"" ], - ""fileName"" : ""./package/foo.c"", - ""fileTypes"" : [ ""SOURCE"" ], - ""licenseComments"" : ""The concluded license was taken from the package level that the file was included in."", - ""licenseConcluded"" : ""(LGPL-2.0-only OR LicenseRef-2)"", - ""licenseInfoInFiles"" : [ ""GPL-2.0-only"", ""LicenseRef-2"" ], - ""noticeText"" : ""Copyright (c) 2001 Aaron Lehmann aaroni@vitelus.com\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \""Software\""), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: \nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \""AS IS\"", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE."" - } ], - ""snippets"" : [ { - ""SPDXID"" : ""SPDXRef-Snippet"", - ""comment"" : ""This snippet was identified as significant and highlighted in this Apache-2.0 file, when a commercial scanner identified it as being derived from file foo.c in package xyz which is licensed under GPL-2.0."", - ""copyrightText"" : ""Copyright 2008-2010 John Smith"", - ""licenseComments"" : ""The concluded license was taken from package xyz, from which the snippet was copied into the current file. The concluded license information was found in the COPYING.txt file in package xyz."", - ""licenseConcluded"" : ""GPL-2.0-only"", - ""licenseInfoInSnippets"" : [ ""GPL-2.0-only"" ], - ""name"" : ""from linux kernel"", - ""ranges"" : [ { - ""endPointer"" : { - ""offset"" : 420, - ""reference"" : ""SPDXRef-DoapSource"" - }, - ""startPointer"" : { - ""offset"" : 310, - ""reference"" : ""SPDXRef-DoapSource"" - } - }, { - ""endPointer"" : { - ""lineNumber"" : 23, - ""reference"" : ""SPDXRef-DoapSource"" - }, - ""startPointer"" : { - ""lineNumber"" : 5, - ""reference"" : ""SPDXRef-DoapSource"" - } - } ], - ""snippetFromFile"" : ""SPDXRef-DoapSource"" - } ], - ""relationships"" : [ { - ""spdxElementId"" : ""SPDXRef-DOCUMENT"", - ""relationshipType"" : ""CONTAINS"", - ""relatedSpdxElement"" : ""SPDXRef-Package"" - }, { - ""spdxElementId"" : ""SPDXRef-DOCUMENT"", - ""relationshipType"" : ""COPY_OF"", - ""relatedSpdxElement"" : ""DocumentRef-spdx-tool-1.2:SPDXRef-ToolsElement"" - }, { - ""spdxElementId"" : ""SPDXRef-Package"", - ""relationshipType"" : ""DYNAMIC_LINK"", - ""relatedSpdxElement"" : ""SPDXRef-Saxon"" - }, { - ""spdxElementId"" : ""SPDXRef-CommonsLangSrc"", - ""relationshipType"" : ""GENERATED_FROM"", - ""relatedSpdxElement"" : ""NOASSERTION"" - }, { - ""spdxElementId"" : ""SPDXRef-JenaLib"", - ""relationshipType"" : ""CONTAINS"", - ""relatedSpdxElement"" : ""SPDXRef-Package"" - }, { - ""spdxElementId"" : ""SPDXRef-Specification"", - ""relationshipType"" : ""SPECIFICATION_FOR"", - ""relatedSpdxElement"" : ""SPDXRef-fromDoap-0"" - }, { - ""spdxElementId"" : ""SPDXRef-File"", - ""relationshipType"" : ""GENERATED_FROM"", - ""relatedSpdxElement"" : ""SPDXRef-fromDoap-0"" - } ] -}"; -} diff --git a/test/Microsoft.Sbom.Api.Tests/Hashing/HashCodeGeneratorTests.cs b/test/Microsoft.Sbom.Api.Tests/Hashing/HashCodeGeneratorTests.cs deleted file mode 100644 index 27ebed43..00000000 --- a/test/Microsoft.Sbom.Api.Tests/Hashing/HashCodeGeneratorTests.cs +++ /dev/null @@ -1,63 +0,0 @@ -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -using System; -using System.IO; -using Microsoft.Sbom.Api.Tests; -using Microsoft.Sbom.Common; -using Microsoft.Sbom.Contracts; -using Microsoft.Sbom.Contracts.Enums; -using Microsoft.VisualStudio.TestTools.UnitTesting; -using Moq; -using PowerArgs; - -namespace Microsoft.Sbom.Api.Hashing.Tests; - -[TestClass] -public class HashCodeGeneratorTests -{ - [TestMethod] - public void GenerateHashTest_Returs2Hashes_Succeeds() - { - var hashAlgorithmNames = new - AlgorithmName[] { AlgorithmName.SHA256, AlgorithmName.SHA512 }; - var expectedHashes = new Checksum[] - { - new Checksum { Algorithm = AlgorithmName.SHA256, ChecksumValue = "185F8DB32271FE25F561A6FC938B2E264306EC304EDA518007D1764826381969" }, - new Checksum { Algorithm = AlgorithmName.SHA512, ChecksumValue = "3615F80C9D293ED7402687F94B22D58E529B8CC7916F8FAC7FDDF7FBD5AF4CF777D3D795A7A00A16BF7E7F3FB9561EE9BAAE480DA9FE7A18769E71886B03F315" } - }; - - var mockFileSystemUtils = new Mock(); - mockFileSystemUtils.Setup(f => f.OpenRead(It.IsAny())).Returns(TestUtils.GenerateStreamFromString("Hello")); - - var hashCodeGenerator = new HashCodeGenerator(mockFileSystemUtils.Object); - var fileHashes = hashCodeGenerator.GenerateHashes("/tmp/file", hashAlgorithmNames); - - Assert.AreEqual(2, fileHashes.Length); - CollectionAssert.AreEqual(expectedHashes, fileHashes); - mockFileSystemUtils.VerifyAll(); - } - - [TestMethod] - public void GenerateHashTest_FileReadFails_Throws() - { - var hashAlgorithmNames = new AlgorithmName[] { AlgorithmName.SHA256, AlgorithmName.SHA512 }; - var expectedHashes = new Checksum[] - { - new Checksum { Algorithm = AlgorithmName.SHA256, ChecksumValue = string.Empty }, - new Checksum { Algorithm = AlgorithmName.SHA512, ChecksumValue = string.Empty } - }; - - var mockFileSystemUtils = new Mock(); - mockFileSystemUtils.Setup(f => f.OpenRead(It.IsAny())).Throws(new IOException()); - - var hashCodeGenerator = new HashCodeGenerator(mockFileSystemUtils.Object); - Assert.ThrowsException(() => hashCodeGenerator.GenerateHashes("/tmp/file", hashAlgorithmNames)); - } - - [TestMethod] - public void GenerateHashTest_NullFileSystemUtils_Throws() - { - Assert.ThrowsException(() => new HashCodeGenerator(null)); - } -} diff --git a/test/Microsoft.Sbom.Api.Tests/HttpRequestUtils.cs b/test/Microsoft.Sbom.Api.Tests/HttpRequestUtils.cs deleted file mode 100644 index f5a859e1..00000000 --- a/test/Microsoft.Sbom.Api.Tests/HttpRequestUtils.cs +++ /dev/null @@ -1,113 +0,0 @@ -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -namespace Microsoft.Sbom.Api.Tests; - -internal class HttpRequestUtils -{ - public const string GoodClearlyDefinedAPIResponse = @"{ - ""npm/npmjs/-/json5/2.2.3"": { - ""described"": { - ""releaseDate"": ""2022-12-31"", - ""sourceLocation"": { - ""type"": ""git"", - ""provider"": ""github"", - ""namespace"": ""json5"", - ""name"": ""json5"", - ""revision"": ""c3a75242772a5026a49c4017a16d9b3543b62776"", - ""url"": ""https://github.com/json5/json5/tree/c3a75242772a5026a49c4017a16d9b3543b62776"" - }, - ""urls"": { - ""registry"": ""https://npmjs.com/package/json5"", - ""version"": ""https://npmjs.com/package/json5/v/2.2.3"", - ""download"": ""https://registry.npmjs.com/json5/-/json5-2.2.3.tgz"" - }, - ""projectWebsite"": ""http://json5.org/"", - ""issueTracker"": ""https://github.com/json5/json5/issues"", - ""hashes"": { - ""sha1"": ""78cd6f1a19bdc12b73db5ad0c61efd66c1e29283"", - ""sha256"": ""08afb33db600d11fc89b98fac4054f19d5d3e0fe527063116150e1ecc2d2377b"" - }, - ""files"": 20, - ""tools"": [ - ""clearlydefined/1.3.4"", - ""reuse/1.3.0"", - ""licensee/9.14.0"", - ""scancode/30.3.0"" - ], - ""toolScore"": { - ""total"": 100, - ""date"": 30, - ""source"": 70 - }, - ""score"": { - ""total"": 100, - ""date"": 30, - ""source"": 70 - } - }, - ""licensed"": { - ""declared"": ""MIT"", - ""toolScore"": { - ""total"": 61, - ""declared"": 30, - ""discovered"": 1, - ""consistency"": 0, - ""spdx"": 15, - ""texts"": 15 - }, - ""facets"": { - ""core"": { - ""attribution"": { - ""unknown"": 17, - ""parties"": [ - ""(c) 2019 Denis Pushkarev"", - ""copyright (c) 2019 Denis Pushkarev"", - ""Copyright (c) 2012-2018 Aseem Kishore, and others"" - ] - }, - ""discovered"": { - ""unknown"": 17, - ""expressions"": [ - ""MIT"", - ""MIT AND NOASSERTION"" - ] - }, - ""files"": 20 - } - }, - ""score"": { - ""total"": 61, - ""declared"": 30, - ""discovered"": 1, - ""consistency"": 0, - ""spdx"": 15, - ""texts"": 15 - } - }, - ""coordinates"": { - ""type"": ""npm"", - ""provider"": ""npmjs"", - ""name"": ""json5"", - ""revision"": ""2.2.3"" - }, - ""_meta"": { - ""schemaVersion"": ""1.6.1"", - ""updated"": ""2023-01-17T15:44:42.747Z"" - }, - ""scores"": { - ""effective"": 80, - ""tool"": 80 - } - }, -}"; - - public const string BadClearlyDefinedAPIResponse = @"{""score"": { - ""total"": 61, - ""declared"": 30, - ""discovered"": 1, - ""consistency"": 0, - ""spdx"": 15, - ""texts"": 15 - }}"; -} diff --git a/test/Microsoft.Sbom.Api.Tests/Metadata/LocalMetadataProviderTest.cs b/test/Microsoft.Sbom.Api.Tests/Metadata/LocalMetadataProviderTest.cs deleted file mode 100644 index d6c4a4d2..00000000 --- a/test/Microsoft.Sbom.Api.Tests/Metadata/LocalMetadataProviderTest.cs +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -using System; -using Microsoft.Sbom.Api.Metadata; -using Microsoft.Sbom.Common.Config; -using Microsoft.Sbom.Extensions.Entities; -using Microsoft.VisualStudio.TestTools.UnitTesting; - -namespace Microsoft.Sbom.Api.Tests.Metadata; - -[TestClass] -public class LocalMetadataProviderTest -{ - private Configuration config; - - [TestInitialize] - public void TestInitialize() - { - config = new Configuration - { - NamespaceUriUniquePart = new ConfigurationSetting("some-custom-value-here"), - NamespaceUriBase = new ConfigurationSetting("http://sbom.microsoft") - }; - } - - [TestMethod] - public void LocalMetadataProvider_GetDocumentNamespaceUri() - { - config.PackageName = new ConfigurationSetting("name"); - config.PackageVersion = new ConfigurationSetting("version"); - - var localMetadataProvider = new LocalMetadataProvider(config); - Assert.AreEqual("http://sbom.microsoft/name/version/some-custom-value-here", localMetadataProvider.GetDocumentNamespaceUri()); - } - - [TestMethod] - public void LocalMetadataProvider_WithNullConfiguration_ThrowArgumentNullException() - { - Assert.ThrowsException(() => new LocalMetadataProvider(null)); - } - - [TestMethod] - public void LocalMetadataProvider_WithNullSupplierAndTimestamp() - { - config.PackageName = new ConfigurationSetting("name"); - config.PackageVersion = new ConfigurationSetting("version"); - config.PackageSupplier = null; - config.GenerationTimestamp = null; - - var localMetadataProvider = new LocalMetadataProvider(config); - Assert.AreEqual(4, localMetadataProvider.MetadataDictionary.Count); - Assert.IsFalse(localMetadataProvider.MetadataDictionary.ContainsKey(MetadataKey.PackageSupplier)); - Assert.IsFalse(localMetadataProvider.MetadataDictionary.ContainsKey(MetadataKey.GenerationTimestamp)); - } -} diff --git a/test/Microsoft.Sbom.Api.Tests/Metadata/SbomApiMetadataProviderTest.cs b/test/Microsoft.Sbom.Api.Tests/Metadata/SbomApiMetadataProviderTest.cs deleted file mode 100644 index 4423c078..00000000 --- a/test/Microsoft.Sbom.Api.Tests/Metadata/SbomApiMetadataProviderTest.cs +++ /dev/null @@ -1,72 +0,0 @@ -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -using System; -using Microsoft.Sbom.Api.Metadata; -using Microsoft.Sbom.Common.Config; -using Microsoft.Sbom.Contracts; -using Microsoft.VisualStudio.TestTools.UnitTesting; - -namespace Microsoft.Sbom.Api.Tests.Metadata; - -[TestClass] -public class SbomApiMetadataProviderTest -{ - private Configuration config; - private SBOMMetadata metadata; - - [TestInitialize] - public void TestInitialize() - { - config = new Configuration - { - NamespaceUriUniquePart = new ConfigurationSetting("some-custom-value-here"), - NamespaceUriBase = new ConfigurationSetting("http://sbom.microsoft") - }; - metadata = new SBOMMetadata - { - BuildId = "buildId", - PackageName = "packageName", - PackageVersion = "packageVersion", - BuildName = "buildName", - RepositoryUri = "repositoryUri", - Branch = "branch", - CommitId = "commitId" - }; - } - - [TestMethod] - public void SbomApiMetadataProvider_BuildEnvironmentName_WithMetadata() - { - metadata.BuildEnvironmentName = "name"; - - var sbomApiMetadataProvider = new SBOMApiMetadataProvider(metadata, config); - Assert.AreEqual("name", sbomApiMetadataProvider.BuildEnvironmentName); - } - - [TestMethod] - public void SbomApiMetadataProvider_BuildEnvironmentName_WithoutMetadata() - { - var sbomApiMetadataProvider = new SBOMApiMetadataProvider(metadata, config); - Assert.IsNull(sbomApiMetadataProvider.BuildEnvironmentName); - } - - [TestMethod] - public void SbomApiMetadataProvider_GetDocumentNamespaceUri() - { - var sbomApiMetadataProvider = new SBOMApiMetadataProvider(metadata, config); - Assert.AreEqual("http://sbom.microsoft/packageName/packageVersion/some-custom-value-here", sbomApiMetadataProvider.GetDocumentNamespaceUri()); - } - - [TestMethod] - public void SbomApiMetadataProvider_WithNullConfiguration_ThrowArgumentNullException() - { - Assert.ThrowsException(() => new SBOMApiMetadataProvider(metadata, null)); - } - - [TestMethod] - public void SbomApiMetadataProvider_WithNullMetadata_ThrowArgumentNullException() - { - Assert.ThrowsException(() => new SBOMApiMetadataProvider(null, config)); - } -} diff --git a/test/Microsoft.Sbom.Api.Tests/Microsoft.Sbom.Api.Tests.csproj b/test/Microsoft.Sbom.Api.Tests/Microsoft.Sbom.Api.Tests.csproj deleted file mode 100644 index 5fa6a6af..00000000 --- a/test/Microsoft.Sbom.Api.Tests/Microsoft.Sbom.Api.Tests.csproj +++ /dev/null @@ -1,24 +0,0 @@ - - - - false - True - Microsoft.Sbom.Api.Tests - $(StrongNameSigningKeyFilePath) - - - - TRACE - - - - - - - - - - - - - diff --git a/test/Microsoft.Sbom.Api.Tests/Output/ManifestToolJsonSerializerTests.cs b/test/Microsoft.Sbom.Api.Tests/Output/ManifestToolJsonSerializerTests.cs deleted file mode 100644 index f3a3f8c1..00000000 --- a/test/Microsoft.Sbom.Api.Tests/Output/ManifestToolJsonSerializerTests.cs +++ /dev/null @@ -1,107 +0,0 @@ -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -using System; -using System.IO; -using System.Text; -using System.Text.Json; -using Microsoft.VisualStudio.TestTools.UnitTesting; - -namespace Microsoft.Sbom.Api.Output.Tests; - -[TestClass] -public class ManifestToolJsonSerializerTests -{ - private readonly string metadataString = "{\"header\":\"value\"}"; - - [TestMethod] - public void ManifestToolJsonSerializerTest_HappyPath_Succeeds() - { - var jsonDoc = JsonDocument.Parse("{\"hello\":\"world\"}"); - - string result = null; - - using (var stream = new MemoryStream()) - { - using (var serializer = new ManifestToolJsonSerializer(stream)) - { - serializer.StartJsonObject(); - serializer.StartJsonArray("Outputs"); - serializer.Write(jsonDoc); - serializer.EndJsonArray(); - serializer.WriteJsonString(metadataString); - serializer.FinalizeJsonObject(); - } - - result = Encoding.UTF8.GetString(stream.ToArray()); - } - - var expected = JsonSerializer.Serialize(JsonDocument.Parse("{\"Outputs\":[{\"hello\":\"world\"}],\"header\":\"value\"}"), new JsonSerializerOptions { WriteIndented = true }); - Assert.AreEqual(expected, result); - - using var stream2 = new MemoryStream(); - using var utfJsonWriter = new Utf8JsonWriter(stream2); - try - { - jsonDoc.WriteTo(utfJsonWriter); - Assert.Fail("Json document was not disposed by the serializer"); - } - catch (Exception e) - { - Assert.AreEqual(typeof(ObjectDisposedException), e.GetType()); - } - } - - [TestMethod] - public void ManifestToolJsonSerializerTest_HeaderWithoutArrayStart_Succeeds() - { - var jsonDoc = JsonDocument.Parse("{\"hello\":\"world\"}"); - - string result = null; - - using (var stream = new MemoryStream()) - { - using (var serializer = new ManifestToolJsonSerializer(stream)) - { - serializer.StartJsonObject(); - serializer.StartJsonArray("Outputs"); - serializer.Write(jsonDoc); - serializer.EndJsonArray(); - serializer.WriteJsonString(metadataString); - serializer.FinalizeJsonObject(); - } - - result = Encoding.UTF8.GetString(stream.ToArray()); - } - - var expected = JsonSerializer.Serialize(JsonDocument.Parse("{\"Outputs\":[{\"hello\":\"world\"}],\"header\":\"value\"}"), new JsonSerializerOptions { WriteIndented = true }); - Assert.AreEqual(expected, result); - - using var stream2 = new MemoryStream(); - using var utfJsonWriter = new Utf8JsonWriter(stream2); - try - { - jsonDoc.WriteTo(utfJsonWriter); - Assert.Fail("Json document was not disposed by the serializer"); - } - catch (Exception e) - { - Assert.AreEqual(typeof(ObjectDisposedException), e.GetType()); - } - } - - [TestMethod] - public void ManifestToolJsonSerializerTest_WriteDisposedJsonDocument_Fails() - { - var jsonDoc = JsonDocument.Parse("{\"hello\":\"world\"}"); - - using var stream = new MemoryStream(); - using var serializer = new ManifestToolJsonSerializer(stream); - - jsonDoc.Dispose(); - - serializer.StartJsonObject(); - serializer.WriteJsonString(metadataString); - Assert.ThrowsException(() => serializer.Write(jsonDoc)); - } -} diff --git a/test/Microsoft.Sbom.Api.Tests/PackageDetails/MavenUtilsTests.cs b/test/Microsoft.Sbom.Api.Tests/PackageDetails/MavenUtilsTests.cs deleted file mode 100644 index 131610a9..00000000 --- a/test/Microsoft.Sbom.Api.Tests/PackageDetails/MavenUtilsTests.cs +++ /dev/null @@ -1,157 +0,0 @@ -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -using System; -using System.IO; -using System.Runtime.InteropServices; -using System.Text; -using Microsoft.ComponentDetection.Contracts.BcdeModels; -using Microsoft.ComponentDetection.Contracts.TypedComponent; -using Microsoft.Sbom.Api.Output.Telemetry; -using Microsoft.Sbom.Api.PackageDetails; -using Microsoft.Sbom.Common; -using Microsoft.VisualStudio.TestTools.UnitTesting; -using Moq; -using Serilog; - -namespace Microsoft.Sbom.Api.Tests.PackageDetails; - -[TestClass] -public class MavenUtilsTests -{ - private readonly Mock mockFileSystemUtils = new Mock(); - private readonly Mock mockLogger = new Mock(); - private readonly Mock mockRecorder = new Mock(); - - private static readonly string EnvHomePath = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? "HOMEPATH" : "HOME"; - private static readonly string HomePath = Environment.GetEnvironmentVariable(EnvHomePath); - private static readonly string MavenPackagesPath = Path.Join(HomePath, ".m2/repository"); - - [TestMethod] - public void GetPomLocation_WhenPomExists_ShouldReturnPath() - { - var mavenUtils = new MavenUtils(mockFileSystemUtils.Object, mockLogger.Object, mockRecorder.Object); - - var scannedComponent = new ScannedComponent - { - Component = new MavenComponent("testGroupId", "testArtifactId", "1.0.0") - }; - - var pathToPom = Path.Join(MavenPackagesPath, "testgroupid/testartifactid/1.0.0/testartifactid-1.0.0.pom"); - - var expectedPath = Path.GetFullPath(pathToPom); - - mockFileSystemUtils.Setup(fs => fs.DirectoryHasReadPermissions(It.IsAny())).Returns(true); - mockFileSystemUtils.Setup(fs => fs.FileExists(It.IsAny())).Returns(true); - - var result = mavenUtils.GetMetadataLocation(scannedComponent); - - Assert.AreEqual(expectedPath, result); - } - - [TestMethod] - public void GetPomLocation_WhenPomDoesNotExist_ShouldReturnNull() - { - var mavenUtils = new MavenUtils(mockFileSystemUtils.Object, mockLogger.Object, mockRecorder.Object); - - var scannedComponent = new ScannedComponent - { - Component = new MavenComponent("testGroupId", "testArtifactId", "1.0.0") - }; - - mockFileSystemUtils.Setup(fs => fs.DirectoryHasReadPermissions(It.IsAny())).Returns(true); - mockFileSystemUtils.Setup(fs => fs.FileExists(It.IsAny())).Returns(false); - - var result = mavenUtils.GetMetadataLocation(scannedComponent); - - Assert.IsNull(result); - } - - [TestMethod] - public void ParsePom_WhenPomIsValid() - { - var mavenUtils = new MavenUtils(mockFileSystemUtils.Object, mockLogger.Object, mockRecorder.Object); - - var pomContent = SampleMetadataFiles.PomWithLicensesAndDevelopers; - - // Convert pomContent to an array of bytes - var pomBytes = Encoding.UTF8.GetBytes(pomContent); - - mockFileSystemUtils.Setup(fs => fs.DirectoryHasReadPermissions(It.IsAny())).Returns(true); - mockFileSystemUtils.Setup(fs => fs.FileExists(It.IsAny())).Returns(true); - mockFileSystemUtils.Setup(fs => fs.ReadAllBytes(It.IsAny())).Returns(pomBytes); - - var parsedInfo = mavenUtils.ParseMetadata(pomContent); - - Assert.AreEqual("test-package", parsedInfo.Name); - Assert.AreEqual("1.3", parsedInfo.Version); - Assert.AreEqual("New BSD License", parsedInfo.PackageDetails.License); - Assert.AreEqual("Person: Sample Name", parsedInfo.PackageDetails.Supplier); - } - - [TestMethod] - public void ParsePom_WithoutDeveloperSection() - { - var mavenUtils = new MavenUtils(mockFileSystemUtils.Object, mockLogger.Object, mockRecorder.Object); - - var pomContent = SampleMetadataFiles.PomWithoutDevelopersSection; - - // Convert pomContent to an array of bytes - var pomBytes = Encoding.UTF8.GetBytes(pomContent); - - mockFileSystemUtils.Setup(fs => fs.DirectoryHasReadPermissions(It.IsAny())).Returns(true); - mockFileSystemUtils.Setup(fs => fs.FileExists(It.IsAny())).Returns(true); - mockFileSystemUtils.Setup(fs => fs.ReadAllBytes(It.IsAny())).Returns(pomBytes); - - var parsedInfo = mavenUtils.ParseMetadata(pomContent); - - Assert.AreEqual("test-package", parsedInfo.Name); - Assert.AreEqual("1.3", parsedInfo.Version); - Assert.AreEqual("New BSD License", parsedInfo.PackageDetails.License); - Assert.IsTrue(string.IsNullOrEmpty(parsedInfo.PackageDetails.Supplier)); - } - - [TestMethod] - public void ParsePom_WithoutLicense() - { - var mavenUtils = new MavenUtils(mockFileSystemUtils.Object, mockLogger.Object, mockRecorder.Object); - - var pomContent = SampleMetadataFiles.PomWithoutLicense; - - // Convert pomContent to an array of bytes - var pomBytes = Encoding.UTF8.GetBytes(pomContent); - - mockFileSystemUtils.Setup(fs => fs.DirectoryHasReadPermissions(It.IsAny())).Returns(true); - mockFileSystemUtils.Setup(fs => fs.FileExists(It.IsAny())).Returns(true); - mockFileSystemUtils.Setup(fs => fs.ReadAllBytes(It.IsAny())).Returns(pomBytes); - - var parsedInfo = mavenUtils.ParseMetadata(pomContent); - - Assert.AreEqual("test-package", parsedInfo.Name); - Assert.AreEqual("1.3", parsedInfo.Version); - Assert.IsTrue(string.IsNullOrEmpty(parsedInfo.PackageDetails.License)); - Assert.AreEqual("Person: Sample Name", parsedInfo.PackageDetails.Supplier); - } - - [TestMethod] - public void ParsePom_WithOrganizationAndDevelopers_PopulatesAsOrganization() - { - var mavenUtils = new MavenUtils(mockFileSystemUtils.Object, mockLogger.Object, mockRecorder.Object); - - var pomContent = SampleMetadataFiles.PomWithDevelopersAndOrganization; - - // Convert pomContent to an array of bytes - var pomBytes = Encoding.UTF8.GetBytes(pomContent); - - mockFileSystemUtils.Setup(fs => fs.DirectoryHasReadPermissions(It.IsAny())).Returns(true); - mockFileSystemUtils.Setup(fs => fs.FileExists(It.IsAny())).Returns(true); - mockFileSystemUtils.Setup(fs => fs.ReadAllBytes(It.IsAny())).Returns(pomBytes); - - var parsedInfo = mavenUtils.ParseMetadata(pomContent); - - Assert.AreEqual("test-package", parsedInfo.Name); - Assert.AreEqual("1.3", parsedInfo.Version); - Assert.IsTrue(string.IsNullOrEmpty(parsedInfo.PackageDetails.License)); - Assert.AreEqual("Organization: Microsoft", parsedInfo.PackageDetails.Supplier); - } -} diff --git a/test/Microsoft.Sbom.Api.Tests/PackageDetails/NugetUtilsTests.cs b/test/Microsoft.Sbom.Api.Tests/PackageDetails/NugetUtilsTests.cs deleted file mode 100644 index 1bc11af2..00000000 --- a/test/Microsoft.Sbom.Api.Tests/PackageDetails/NugetUtilsTests.cs +++ /dev/null @@ -1,128 +0,0 @@ -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -using System.Text; -using Microsoft.ComponentDetection.Contracts.BcdeModels; -using Microsoft.ComponentDetection.Contracts.TypedComponent; -using Microsoft.Sbom.Api.Output.Telemetry; -using Microsoft.Sbom.Api.PackageDetails; -using Microsoft.Sbom.Common; -using Microsoft.VisualStudio.TestTools.UnitTesting; -using Moq; -using NuGet.Configuration; -using Serilog; - -namespace Microsoft.Sbom.Api.Tests.PackageDetails; - -[TestClass] -public class NugetUtilsTests -{ - private readonly Mock mockFileSystemUtils = new Mock(); - private readonly Mock mockLogger = new Mock(); - private readonly Mock mockRecorder = new Mock(); - - private static readonly string NugetPackagesPath = SettingsUtility.GetGlobalPackagesFolder(new NullSettings()); - - [TestMethod] - public void GetNuspecLocation_WhenNuspecExists_ShouldReturnPath() - { - var nugetUtils = new NugetUtils(mockFileSystemUtils.Object, mockLogger.Object, mockRecorder.Object); - - var scannedComponent = new ScannedComponent - { - Component = new NuGetComponent("testName", "1.0.0") - }; - - var nuspecPath = $"{NugetPackagesPath}{((NuGetComponent)scannedComponent.Component).Name.ToLower()}/{((NuGetComponent)scannedComponent.Component).Version}/{((NuGetComponent)scannedComponent.Component).Name.ToLower()}.nuspec"; - - mockFileSystemUtils.Setup(fs => fs.DirectoryHasReadPermissions(It.IsAny())).Returns(true); - mockFileSystemUtils.Setup(fs => fs.FileExists(It.IsAny())).Returns(true); - - var result = nugetUtils.GetMetadataLocation(scannedComponent); - - Assert.AreEqual(nuspecPath, result); - } - - [TestMethod] - public void GetNuspecLocation_WhenNuspecDoesNotExist_ShouldReturnNull() - { - var nugetUtils = new NugetUtils(mockFileSystemUtils.Object, mockLogger.Object, mockRecorder.Object); - - var scannedComponent = new ScannedComponent - { - Component = new NuGetComponent("testName", "1.0.0") - }; - - mockFileSystemUtils.Setup(fs => fs.DirectoryHasReadPermissions(It.IsAny())).Returns(true); - mockFileSystemUtils.Setup(fs => fs.FileExists(It.IsAny())).Returns(false); - - var result = nugetUtils.GetMetadataLocation(scannedComponent); - - Assert.IsNull(result); - } - - [TestMethod] - public void ParseNuspec_WhenNuspecIsValid() - { - var nugetUtils = new NugetUtils(mockFileSystemUtils.Object, mockLogger.Object, mockRecorder.Object); - - var nuspecContent = SampleMetadataFiles.NuspecWithValidLicenseAndAuthors; - - // Convert nuspecContent to an array of bytes - var nuspecBytes = Encoding.UTF8.GetBytes(nuspecContent); - - mockFileSystemUtils.Setup(fs => fs.DirectoryHasReadPermissions(It.IsAny())).Returns(true); - mockFileSystemUtils.Setup(fs => fs.FileExists(It.IsAny())).Returns(true); - mockFileSystemUtils.Setup(fs => fs.ReadAllBytes(It.IsAny())).Returns(nuspecBytes); - - var parsedPackageInfo = nugetUtils.ParseMetadata(nuspecContent); - - Assert.AreEqual("FakePackageName", parsedPackageInfo.Name); - Assert.AreEqual("1.0", parsedPackageInfo.Version); - Assert.AreEqual("FakeLicense", parsedPackageInfo.PackageDetails.License); - Assert.AreEqual("Organization: FakeAuthor", parsedPackageInfo.PackageDetails.Supplier); - } - - [TestMethod] - public void ParseNuspec_LicenseIsFile_SupplierSucceeds() - { - var nugetUtils = new NugetUtils(mockFileSystemUtils.Object, mockLogger.Object, mockRecorder.Object); - - var nuspecContent = SampleMetadataFiles.NuspecWithInvalidLicense; - - // Convert nuspecContent to an array of bytes - var nuspecBytes = Encoding.UTF8.GetBytes(nuspecContent); - - mockFileSystemUtils.Setup(fs => fs.DirectoryHasReadPermissions(It.IsAny())).Returns(true); - mockFileSystemUtils.Setup(fs => fs.FileExists(It.IsAny())).Returns(true); - mockFileSystemUtils.Setup(fs => fs.ReadAllBytes(It.IsAny())).Returns(nuspecBytes); - - var parsedPackageInfo = nugetUtils.ParseMetadata(nuspecContent); - - Assert.AreEqual("FakePackageName", parsedPackageInfo.Name); - Assert.AreEqual("1.0", parsedPackageInfo.Version); - Assert.AreEqual("Organization: FakeAuthor", parsedPackageInfo.PackageDetails.Supplier); - Assert.IsTrue(string.IsNullOrEmpty(parsedPackageInfo.PackageDetails.License)); - } - - [TestMethod] - public void ParseNuspec_NoAuthorFound_DoesNotFail() - { - var nugetUtils = new NugetUtils(mockFileSystemUtils.Object, mockLogger.Object, mockRecorder.Object); - - var nuspecContent = SampleMetadataFiles.NuspecWithoutAuthor; - - // Convert nuspecContent to an array of bytes - var nuspecBytes = Encoding.UTF8.GetBytes(nuspecContent); - - mockFileSystemUtils.Setup(fs => fs.DirectoryHasReadPermissions(It.IsAny())).Returns(true); - mockFileSystemUtils.Setup(fs => fs.FileExists(It.IsAny())).Returns(true); - mockFileSystemUtils.Setup(fs => fs.ReadAllBytes(It.IsAny())).Returns(nuspecBytes); - - var parsedPackageInfo = nugetUtils.ParseMetadata(nuspecContent); - - Assert.AreEqual("FakePackageName", parsedPackageInfo.Name); - Assert.AreEqual("1.0", parsedPackageInfo.Version); - Assert.IsTrue(string.IsNullOrEmpty(parsedPackageInfo.PackageDetails.Supplier)); - } -} diff --git a/test/Microsoft.Sbom.Api.Tests/PackageDetails/RubyGemsUtilsTests.cs b/test/Microsoft.Sbom.Api.Tests/PackageDetails/RubyGemsUtilsTests.cs deleted file mode 100644 index 6f3cc6b1..00000000 --- a/test/Microsoft.Sbom.Api.Tests/PackageDetails/RubyGemsUtilsTests.cs +++ /dev/null @@ -1,188 +0,0 @@ -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -using Microsoft.ComponentDetection.Contracts.BcdeModels; -using Microsoft.ComponentDetection.Contracts.TypedComponent; -using Microsoft.Sbom.Api.Output.Telemetry; -using Microsoft.Sbom.Api.PackageDetails; -using Microsoft.Sbom.Common; -using Microsoft.VisualStudio.TestTools.UnitTesting; -using Moq; -using Serilog; - -namespace Microsoft.Sbom.Api.Tests.PackageDetails; - -[TestClass] -public class RubyGemsUtilsTests -{ - private readonly Mock mockFileSystemUtils = new Mock(); - private readonly Mock mockLogger = new Mock(); - private readonly Mock mockRecorder = new Mock(); - private readonly Mock mockProcessExecutor = new Mock(); - - [TestMethod] - public void ParseValidGemspec_PopulatesSupplierAndMultipleLicenses() - { - var rubyGemsUtils = new RubyGemsUtils(mockFileSystemUtils.Object, mockLogger.Object, mockRecorder.Object, mockProcessExecutor.Object); - - var gemspecContent = SampleMetadataFiles.GemspecWithValidAuthorAndLicenses; - - mockFileSystemUtils.Setup(fs => fs.FileExists(It.IsAny())).Returns(true); - mockFileSystemUtils.Setup(fs => fs.ReadAllText(It.IsAny())).Returns(gemspecContent); - - var parsedGemspecInfo = rubyGemsUtils.ParseMetadata(gemspecContent); - - Assert.AreEqual("MIT, Ruby", parsedGemspecInfo.PackageDetails.License); - Assert.AreEqual("John Doe", parsedGemspecInfo.PackageDetails.Supplier); - Assert.AreEqual("sampleGem", parsedGemspecInfo.Name); - Assert.AreEqual("1.0.0", parsedGemspecInfo.Version); - } - - [TestMethod] - public void ParseValidGemspec_PopulatesSupplierAndSingleLicense() - { - var rubyGemsUtils = new RubyGemsUtils(mockFileSystemUtils.Object, mockLogger.Object, mockRecorder.Object, mockProcessExecutor.Object); - - var gemspecContent = SampleMetadataFiles.GemspecWithValidAuthorAndSingleLicense; - - mockFileSystemUtils.Setup(fs => fs.FileExists(It.IsAny())).Returns(true); - mockFileSystemUtils.Setup(fs => fs.ReadAllText(It.IsAny())).Returns(gemspecContent); - - var parsedGemspecInfo = rubyGemsUtils.ParseMetadata(gemspecContent); - - Assert.AreEqual("MIT", parsedGemspecInfo.PackageDetails.License); - Assert.AreEqual("John Doe", parsedGemspecInfo.PackageDetails.Supplier); - Assert.AreEqual("sampleGem", parsedGemspecInfo.Name); - Assert.AreEqual("1.0.0", parsedGemspecInfo.Version); - } - - [TestMethod] - public void ParseGemspec_WithoutLicense() - { - var rubyGemsUtils = new RubyGemsUtils(mockFileSystemUtils.Object, mockLogger.Object, mockRecorder.Object, mockProcessExecutor.Object); - - var gemspecContent = SampleMetadataFiles.GemspecWithoutLicense; - - mockFileSystemUtils.Setup(fs => fs.FileExists(It.IsAny())).Returns(true); - mockFileSystemUtils.Setup(fs => fs.ReadAllText(It.IsAny())).Returns(gemspecContent); - - var parsedGemspecInfo = rubyGemsUtils.ParseMetadata(gemspecContent); - - Assert.IsNull(parsedGemspecInfo.PackageDetails.License); - Assert.AreEqual("John Doe", parsedGemspecInfo.PackageDetails.Supplier); - Assert.AreEqual("sampleGem", parsedGemspecInfo.Name); - Assert.AreEqual("1.0.0", parsedGemspecInfo.Version); - } - - [TestMethod] - public void ParseGemspec_WithoutAuthor() - { - var rubyGemsUtils = new RubyGemsUtils(mockFileSystemUtils.Object, mockLogger.Object, mockRecorder.Object, mockProcessExecutor.Object); - - var gemspecContent = SampleMetadataFiles.GemspecWithoutAuthors; - - mockFileSystemUtils.Setup(fs => fs.FileExists(It.IsAny())).Returns(true); - mockFileSystemUtils.Setup(fs => fs.ReadAllText(It.IsAny())).Returns(gemspecContent); - - var parsedGemspecInfo = rubyGemsUtils.ParseMetadata(gemspecContent); - - Assert.AreEqual("MIT", parsedGemspecInfo.PackageDetails.License); - Assert.IsNull(parsedGemspecInfo.PackageDetails.Supplier); - Assert.AreEqual("sampleGem", parsedGemspecInfo.Name); - Assert.AreEqual("1.0.0", parsedGemspecInfo.Version); - } - - [TestMethod] - public void GetMetdataLocation_Succeeds_Returns_Path() - { - var rubyGemsUtils = new RubyGemsUtils(mockFileSystemUtils.Object, mockLogger.Object, mockRecorder.Object, mockProcessExecutor.Object); - - mockFileSystemUtils.Setup(fs => fs.FileExists(It.IsAny())).Returns(true); - mockProcessExecutor.Setup(process => process.ExecuteCommand(It.IsAny(), It.IsAny(), It.IsAny())).Returns("gem_base/specifications"); - - var scannedComponent = new ScannedComponent - { - Component = new RubyGemsComponent("testName", "1.0.0") - }; - - var gemspecLocation = rubyGemsUtils.GetMetadataLocation(scannedComponent); - - Assert.IsTrue(gemspecLocation.EndsWith("testname-1.0.0.gemspec", System.StringComparison.OrdinalIgnoreCase)); - } - - [TestMethod] - public void GetMetdataLocation_ExecuteCommand_Fails_Returns_Null() - { - var rubyGemsUtils = new RubyGemsUtils(mockFileSystemUtils.Object, mockLogger.Object, mockRecorder.Object, mockProcessExecutor.Object); - - mockFileSystemUtils.Setup(fs => fs.FileExists(It.IsAny())).Returns(true); - mockProcessExecutor.Setup(process => process.ExecuteCommand(It.IsAny(), It.IsAny(), It.IsAny())).Returns((string)null); - - var scannedComponent = new ScannedComponent - { - Component = new RubyGemsComponent("testName", "1.0.0") - }; - - var gemspecLocation = rubyGemsUtils.GetMetadataLocation(scannedComponent); - - Assert.IsNull(gemspecLocation); - } - - [TestMethod] - public void GetMetdataLocation_FileDoesNotExist_Returns_Null() - { - var rubyGemsUtils = new RubyGemsUtils(mockFileSystemUtils.Object, mockLogger.Object, mockRecorder.Object, mockProcessExecutor.Object); - - mockFileSystemUtils.Setup(fs => fs.FileExists(It.IsAny())).Returns(false); - mockProcessExecutor.Setup(process => process.ExecuteCommand(It.IsAny(), It.IsAny(), It.IsAny())).Returns("gem_base/specifications"); - - var scannedComponent = new ScannedComponent - { - Component = new RubyGemsComponent("testName", "1.0.0") - }; - - var gemspecLocation = rubyGemsUtils.GetMetadataLocation(scannedComponent); - - Assert.IsNull(gemspecLocation); - } - - [TestMethod] - [DataRow("gem_base/specifications;gem_base/specifications2;gem_base/specifications3")] - [DataRow("gem_base/specifications:gem_base/specifications2:gem_base/specifications3")] - public void GetMetadataLocation_Handles_Separators(string processExecutorOutput) - { - var rubyGemsUtils = new RubyGemsUtils(mockFileSystemUtils.Object, mockLogger.Object, mockRecorder.Object, mockProcessExecutor.Object); - - mockFileSystemUtils.Setup(fs => fs.FileExists(It.IsAny())).Returns(true); - mockFileSystemUtils.Setup(fs => fs.DirectoryExists(It.IsAny())).Returns(true); - mockProcessExecutor.Setup(process => process.ExecuteCommand(It.IsAny(), It.IsAny(), It.IsAny())).Returns(processExecutorOutput); - - var scannedComponent = new ScannedComponent - { - Component = new RubyGemsComponent("testName", "1.0.0") - }; - - var gemspecLocation = rubyGemsUtils.GetMetadataLocation(scannedComponent); - - Assert.IsTrue(gemspecLocation.EndsWith("testname-1.0.0.gemspec", System.StringComparison.OrdinalIgnoreCase)); - } - - [TestMethod] - public void GetMetadataLocation_Executor_Throws() - { - var rubyGemsUtils = new RubyGemsUtils(mockFileSystemUtils.Object, mockLogger.Object, mockRecorder.Object, mockProcessExecutor.Object); - - mockFileSystemUtils.Setup(fs => fs.FileExists(It.IsAny())).Returns(true); - mockFileSystemUtils.Setup(fs => fs.DirectoryExists(It.IsAny())).Returns(true); - mockProcessExecutor.Setup(process => process.ExecuteCommand(It.IsAny(), It.IsAny(), It.IsAny())).Throws(new System.Exception()); - - var scannedComponent = new ScannedComponent - { - Component = new RubyGemsComponent("testName", "1.0.0") - }; - - var gemspecLocation = rubyGemsUtils.GetMetadataLocation(scannedComponent); - - Assert.IsNull(gemspecLocation); - } -} diff --git a/test/Microsoft.Sbom.Api.Tests/PackageDetails/SampleMetadataFiles.cs b/test/Microsoft.Sbom.Api.Tests/PackageDetails/SampleMetadataFiles.cs deleted file mode 100644 index 68dbe8d6..00000000 --- a/test/Microsoft.Sbom.Api.Tests/PackageDetails/SampleMetadataFiles.cs +++ /dev/null @@ -1,188 +0,0 @@ -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -namespace Microsoft.Sbom.Api.Tests.PackageDetails; - -public static class SampleMetadataFiles -{ - public const string PomWithLicensesAndDevelopers = @" - - 4.0.0 - - org.test - test-package - 1.3 - pom - - - - New BSD License - http://www.opensource.org/licenses/bsd-license.php - repo - - - - - - SAMPLE - Sample Name - - Developer - - - - "; - - public const string PomWithoutDevelopersSection = @" - - 4.0.0 - - org.test - test-package - 1.3 - pom - - - - New BSD License - http://www.opensource.org/licenses/bsd-license.php - repo - - - "; - - public const string PomWithDevelopersAndOrganization = @" - - 4.0.0 - - org.test - test-package - 1.3 - pom - - - - SAMPLE - Sample Name - - Developer - - - - - - Microsoft - - - "; - - public const string PomWithoutLicense = @" - - 4.0.0 - - org.test - test-package - 1.3 - pom - - - - SAMPLE - Sample Name - - Developer - - - - SAMPLE - Sample Name2 - - Developer - - - - "; - - public const string NuspecWithValidLicenseAndAuthors = @" - - FakePackageName - 1.0 - FakeAuthor - FakeLicense - - - "; - - public const string NuspecWithInvalidLicense = @" - - FakePackageName - 1.0 - FakeAuthor - FakeLicense - - - "; - - public const string NuspecWithoutAuthor = @" - - FakePackageName - 1.0 - - - "; - - public const string GemspecWithValidAuthorAndLicenses = @"# -*- encoding: utf-8 -*- - # stub: sampleGem 1.0.0 ruby lib - - Gem::Specification.new do |s| - s.name = ""sampleGem"".freeze - s.version = ""1.0.0"" - - s.required_rubygems_version = Gem::Requirement.new("">= 0"".freeze) if s.respond_to? :required_rubygems_version= - s.require_paths = [""lib"".freeze] - s.authors = [""John Doe"".freeze, ""Joe Corcoran"".freeze, ""Russell Osborne"".freeze] - s.date = ""2023-10-07"" - s.licenses = [""MIT"".freeze, ""Ruby"".freeze] - end"; - - public const string GemspecWithValidAuthorAndSingleLicense = @"# -*- encoding: utf-8 -*- - # stub: sampleGem 1.0.0 ruby lib - - Gem::Specification.new do |s| - s.name = ""sampleGem"".freeze - s.version = ""1.0.0"" - - s.required_rubygems_version = Gem::Requirement.new("">= 0"".freeze) if s.respond_to? :required_rubygems_version= - s.require_paths = [""lib"".freeze] - s.authors = [""John Doe"".freeze, ""Joe Corcoran"".freeze, ""Russell Osborne"".freeze] - s.date = ""2023-10-07"" - s.license = [""MIT"".freeze] - end"; - - public const string GemspecWithoutAuthors = @"# -*- encoding: utf-8 -*- - # stub: sampleGem 1.0.0 ruby lib - - Gem::Specification.new do |s| - s.name = ""sampleGem"".freeze - s.version = ""1.0.0"" - - s.required_rubygems_version = Gem::Requirement.new("">= 0"".freeze) if s.respond_to? :required_rubygems_version= - s.require_paths = [""lib"".freeze] - s.date = ""2023-10-07"" - s.licenses = [""MIT"".freeze] - end"; - - public const string GemspecWithoutLicense = @"# -*- encoding: utf-8 -*- - # stub: sampleGem 1.0.0 ruby lib - - Gem::Specification.new do |s| - s.name = ""sampleGem"".freeze - s.version = ""1.0.0"" - - s.required_rubygems_version = Gem::Requirement.new("">= 0"".freeze) if s.respond_to? :required_rubygems_version= - s.require_paths = [""lib"".freeze] - s.authors = [""John Doe"".freeze, ""Joe Corcoran"".freeze, ""Russell Osborne"".freeze] - s.date = ""2023-10-07"" - end"; -} diff --git a/test/Microsoft.Sbom.Api.Tests/PathUtils.cs b/test/Microsoft.Sbom.Api.Tests/PathUtils.cs deleted file mode 100644 index 9ab619b4..00000000 --- a/test/Microsoft.Sbom.Api.Tests/PathUtils.cs +++ /dev/null @@ -1,46 +0,0 @@ -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -using System.IO; - -namespace Microsoft.Sbom.Api.Tests; - -/// -/// This class is responsible for providing Path functions that are provided -/// in either .net framework or .net core. -/// -/// -/// Comments are from API. -/// -internal class PathUtils -{ - /// - /// Create a relative path from one path to another. Paths will be resolved before calculating the difference. - /// Default path comparison for the active platform will be used (OrdinalIgnoreCase for Windows or Mac, Ordinal for Unix). - /// - /// The source path the output should be relative to. This path is always considered to be a directory. - /// The destination path. - /// The relative path or if the paths don't share the same root. - public static string GetRelativePath(string relativeTo, string path) - { - return Path.GetRelativePath(relativeTo, path); - } - - /// - /// Unlike Combine(), Join() methods do not consider rooting. They simply combine paths, ensuring that there - /// is a directory separator between them. - /// - public static string Join(string path1, string path2) - { - return Path.Join(path1, path2); - } - - /// - /// Unlike Combine(), Join() methods do not consider rooting. They simply combine paths, ensuring that there - /// is a directory separator between them. - /// - public static string Join(string path1, string path2, string path3) - { - return Path.Join(path1, path2, path3); - } -} diff --git a/test/Microsoft.Sbom.Api.Tests/SBOMGeneratorTest.cs b/test/Microsoft.Sbom.Api.Tests/SBOMGeneratorTest.cs deleted file mode 100644 index a1794d25..00000000 --- a/test/Microsoft.Sbom.Api.Tests/SBOMGeneratorTest.cs +++ /dev/null @@ -1,103 +0,0 @@ -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -using System.Collections.Generic; -using System.IO; -using System.Threading.Tasks; -using Microsoft.Sbom.Api.Config; -using Microsoft.Sbom.Api.Entities; -using Microsoft.Sbom.Api.Hashing; -using Microsoft.Sbom.Api.Manifest; -using Microsoft.Sbom.Api.Output.Telemetry; -using Microsoft.Sbom.Api.Utils; -using Microsoft.Sbom.Api.Workflows; -using Microsoft.Sbom.Common; -using Microsoft.Sbom.Common.Config.Validators; -using Microsoft.Sbom.Contracts; -using Microsoft.Sbom.Contracts.Entities; -using Microsoft.VisualStudio.TestTools.UnitTesting; -using Moq; -using EntityErrorType = Microsoft.Sbom.Contracts.Enums.ErrorType; - -namespace Microsoft.Sbom.Api.Tests; - -[TestClass] -public class SBOMGeneratorTest -{ - private readonly Mock fileSystemMock = new Mock(); - private SbomGenerator generator; - private Mock> mockWorkflow; - private Mock mockRecorder; - private Mock mockGeneratorProvider; - private Mock mockSanitizer; - private Mock mockHashAlgorithmProvider; - private Mock mockAssemblyConfig; - private RuntimeConfiguration runtimeConfiguration; - - [TestInitialize] - public void Setup() - { - fileSystemMock.Setup(f => f.DirectoryExists(It.IsAny())).Returns(true).Verifiable(); - fileSystemMock.Setup(f => f.DirectoryHasReadPermissions(It.IsAny())).Returns(true).Verifiable(); - fileSystemMock.Setup(f => f.DirectoryHasWritePermissions(It.IsAny())).Returns(true).Verifiable(); - fileSystemMock.Setup(f => f.JoinPaths(It.IsAny(), It.IsAny())).Returns((string p1, string p2) => Path.Join(p1, p2)); - - mockWorkflow = new Mock>(); - mockRecorder = new Mock(); - mockGeneratorProvider = new Mock(null); - mockHashAlgorithmProvider = new Mock(); - mockAssemblyConfig = new Mock(); - - mockSanitizer = new Mock(mockHashAlgorithmProvider.Object, fileSystemMock.Object, mockAssemblyConfig.Object); - - runtimeConfiguration = new RuntimeConfiguration - { - NamespaceUriBase = "https://base.uri" - }; - } - - [TestMethod] - public async Task When_GenerateSbomAsync_WithRecordedErrors_Then_PopulateEntityErrors() - { - var fileValidationResults = new List - { - new FileValidationResult() { Path = "random", ErrorType = ErrorType.Other } - }; - - mockRecorder.Setup(c => c.Errors).Returns(fileValidationResults).Verifiable(); - mockWorkflow.Setup(c => c.RunAsync()).Returns(Task.FromResult(true)).Verifiable(); - - var metadata = new SBOMMetadata() - { - PackageSupplier = "Contoso" - }; - - generator = new SbomGenerator(mockWorkflow.Object, mockGeneratorProvider.Object, mockRecorder.Object, new List(), mockSanitizer.Object); - var result = await generator.GenerateSbomAsync("rootPath", "compPath", metadata, runtimeConfiguration: runtimeConfiguration); - - Assert.AreEqual(1, result.Errors.Count); - Assert.AreEqual(EntityErrorType.Other, result.Errors[0].ErrorType); - Assert.AreEqual("random", ((FileEntity)result.Errors[0].Entity).Path); - mockRecorder.Verify(); - mockWorkflow.Verify(); - } - - [TestMethod] - public async Task When_GenerateSbomAsync_WithNoRecordedErrors_Then_EmptyEntityErrors() - { - mockRecorder.Setup(c => c.Errors).Returns(new List()).Verifiable(); - mockWorkflow.Setup(c => c.RunAsync()).Returns(Task.FromResult(true)).Verifiable(); - - var metadata = new SBOMMetadata() - { - PackageSupplier = "Contoso" - }; - - generator = new SbomGenerator(mockWorkflow.Object, mockGeneratorProvider.Object, mockRecorder.Object, new List(), mockSanitizer.Object); - var result = await generator.GenerateSbomAsync("rootPath", "compPath", metadata, runtimeConfiguration: runtimeConfiguration); - - Assert.AreEqual(0, result.Errors.Count); - mockRecorder.Verify(); - mockWorkflow.Verify(); - } -} diff --git a/test/Microsoft.Sbom.Api.Tests/SignValidator/SignValidationProviderTests.cs b/test/Microsoft.Sbom.Api.Tests/SignValidator/SignValidationProviderTests.cs deleted file mode 100644 index 60454adc..00000000 --- a/test/Microsoft.Sbom.Api.Tests/SignValidator/SignValidationProviderTests.cs +++ /dev/null @@ -1,55 +0,0 @@ -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -using System; -using System.Runtime.InteropServices; -using Microsoft.Sbom.Common; -using Microsoft.Sbom.Extensions; -using Microsoft.VisualStudio.TestTools.UnitTesting; -using Moq; - -namespace Microsoft.Sbom.Api.SignValidator.Tests; - -[TestClass] -public class SignValidationProviderTests -{ - [TestMethod] - public void SignValidationProvider_AddsValidator_Succeeds() - { - var mockSignValidator = new Mock(); - mockSignValidator.SetupGet(s => s.SupportedPlatform).Returns(OSPlatform.Windows); - - var mockOSUtils = new Mock(); - mockOSUtils.Setup(o => o.GetCurrentOSPlatform()).Returns(OSPlatform.Windows); - - var signValidator = new SignValidationProvider(new ISignValidator[] { mockSignValidator.Object }, mockOSUtils.Object); - signValidator.Init(); - Assert.IsTrue(signValidator.Get().Equals(mockSignValidator.Object)); - - mockOSUtils.VerifyAll(); - mockSignValidator.VerifyAll(); - } - - [TestMethod] - public void SignValidationProvider_NullValidators_Throws() - { - var mockOSUtils = new Mock(); - mockOSUtils.Setup(o => o.GetCurrentOSPlatform()).Returns(OSPlatform.Windows); - - Assert.ThrowsException(() => new SignValidationProvider(null, mockOSUtils.Object)); - } - - [TestMethod] - public void SignValidationProvider_NotFoundValidators_ReturnsNull() - { - var mockSignValidator = new Mock(); - mockSignValidator.SetupGet(s => s.SupportedPlatform).Returns(OSPlatform.Windows); - - var mockOSUtils = new Mock(); - mockOSUtils.Setup(o => o.GetCurrentOSPlatform()).Returns(OSPlatform.Linux); - - var signValidator = new SignValidationProvider(new ISignValidator[] { mockSignValidator.Object }, mockOSUtils.Object); - signValidator.Init(); - Assert.IsNull(signValidator.Get()); - } -} diff --git a/test/Microsoft.Sbom.Api.Tests/TestManifestGenerator.cs b/test/Microsoft.Sbom.Api.Tests/TestManifestGenerator.cs deleted file mode 100644 index 280d89a2..00000000 --- a/test/Microsoft.Sbom.Api.Tests/TestManifestGenerator.cs +++ /dev/null @@ -1,151 +0,0 @@ -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -using System; -using System.Collections.Generic; -using System.Diagnostics.CodeAnalysis; -using System.Linq; -using System.Text.Json; -using Microsoft.Sbom.Contracts; -using Microsoft.Sbom.Contracts.Enums; -using Microsoft.Sbom.Extensions; -using Microsoft.Sbom.Extensions.Entities; - -namespace Microsoft.Sbom.Api.Tests; - -internal class TestManifestGenerator : IManifestGenerator -{ - public AlgorithmName[] RequiredHashAlgorithms => new[] { - AlgorithmName.SHA256 - }; - - public string Version { get; set; } = "1.0.0"; - - public IList HeaderKeys => throw new NotImplementedException(); - - public string FilesArrayHeaderName => "Outputs"; - - public string PackagesArrayHeaderName => "Packages"; - - public string RelationshipsArrayHeaderName => "Relationships"; - - public string ExternalDocumentRefArrayHeaderName => "externalDocumentRefs"; - - public GenerationResult GenerateJsonDocument(InternalSbomFileInfo fileInfo) - { - if (fileInfo is null) - { - throw new ArgumentNullException(nameof(fileInfo)); - } - - if (fileInfo.Checksum == null || !fileInfo.Checksum.Any()) - { - throw new ArgumentException(nameof(fileInfo.Checksum)); - } - - if (string.IsNullOrWhiteSpace(fileInfo.Path)) - { - throw new ArgumentException(nameof(fileInfo.Path)); - } - - var jsonString = $@" -{{ - ""Source"":""{fileInfo.Path}"", - ""Sha256Hash"":""{fileInfo.Checksum.Where(h => h.Algorithm == AlgorithmName.SHA256).Select(h => h.ChecksumValue).FirstOrDefault()}"" -}} -"; - - return new GenerationResult - { - Document = JsonDocument.Parse(jsonString), - ResultMetadata = new ResultMetadata - { - EntityId = $"{fileInfo.Path}_{Guid.NewGuid()}" - } - }; - } - - public GenerationResult GenerateJsonDocument(SbomPackage packageInfo) - { - var jsonString = $@" -{{ - ""Name"": ""{packageInfo.PackageName}"" -}} -"; - - return new GenerationResult - { - Document = JsonDocument.Parse(jsonString), - ResultMetadata = new ResultMetadata - { - EntityId = $"{packageInfo.PackageName}_{Guid.NewGuid()}" - } - }; - } - - public GenerationResult GenerateJsonDocument(Relationship relationship) - { - return new GenerationResult - { - Document = JsonDocument.Parse(JsonSerializer.Serialize(relationship)) - }; - } - - public GenerationResult GenerateJsonDocument(ExternalDocumentReferenceInfo externalDocumentReferenceInfo) - { - var jsonString = $@" - {{ - ""ExternalDocumentId"":""{externalDocumentReferenceInfo.ExternalDocumentName}"", - ""Document"":""{externalDocumentReferenceInfo.DocumentNamespace}"" - }} - "; - - return new GenerationResult - { - Document = JsonDocument.Parse(jsonString), - ResultMetadata = new ResultMetadata - { - EntityId = $"{externalDocumentReferenceInfo.ExternalDocumentName}_{Guid.NewGuid()}" - } - }; - } - - [SuppressMessage("StyleCop.CSharp.NamingRules", "SA1313:Parameter names should begin with lower-case letter", Justification = "Discard variable has a _ name")] - public GenerationResult GenerateRootPackage(IInternalMetadataProvider _) - { - var jsonString = $@" -{{ - ""Name"": ""rootPackage"" -}} -"; - - return new GenerationResult - { - Document = JsonDocument.Parse(jsonString), - ResultMetadata = new ResultMetadata - { - DocumentId = "doc-rootPackage-Id", - EntityId = "rootPackage-Id" - } - }; - } - - public IDictionary GetMetadataDictionary(IInternalMetadataProvider internalMetadataProvider) - { - return new Dictionary - { - { "Version", "1.0.0" }, - { "Build", internalMetadataProvider.GetMetadata(MetadataKey.Build_BuildId) }, - { "Definition", internalMetadataProvider.GetMetadata(MetadataKey.Build_DefinitionName) }, - }; - } - - public ManifestInfo RegisterManifest() - { - return new ManifestInfo - { - Name = "TestManifest", - Version = "1.0.0" - }; - } -} diff --git a/test/Microsoft.Sbom.Api.Tests/TestUtils.cs b/test/Microsoft.Sbom.Api.Tests/TestUtils.cs deleted file mode 100644 index 83823673..00000000 --- a/test/Microsoft.Sbom.Api.Tests/TestUtils.cs +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -using System.IO; - -namespace Microsoft.Sbom.Api.Tests; - -internal class TestUtils -{ - public static Stream GenerateStreamFromString(string s) - { - var stream = new MemoryStream(); - var writer = new StreamWriter(stream); - writer.Write(s); - writer.Flush(); - stream.Position = 0; - return stream; - } -} diff --git a/test/Microsoft.Sbom.Api.Tests/Utils/ComponentDetectionCliArgumentBuilderTests.cs b/test/Microsoft.Sbom.Api.Tests/Utils/ComponentDetectionCliArgumentBuilderTests.cs deleted file mode 100644 index 45e0dec9..00000000 --- a/test/Microsoft.Sbom.Api.Tests/Utils/ComponentDetectionCliArgumentBuilderTests.cs +++ /dev/null @@ -1,323 +0,0 @@ -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading; -using Microsoft.ComponentDetection.Orchestrator.Commands; -using Microsoft.Sbom.Api.Utils; -using Microsoft.VisualStudio.TestTools.UnitTesting; -using PowerArgs; -using static Microsoft.Sbom.Api.Tests.Utils.ComponentDetectionCliArgumentBuilderTestsExtensions; - -namespace Microsoft.Sbom.Api.Tests.Utils; - -[TestClass] -public class ComponentDetectionCliArgumentBuilderTests -{ - public const int DefaultTimeout = 900; - - [TestMethod] - public void Build_Simple() - { - var expected = ExpectedArgs("--SourceDirectory", "X:/") - .WithDetectorArgs(); - - var builder = new ComponentDetectionCliArgumentBuilder() - .SourceDirectory("X:/"); - - var result = builder.Build(); - CollectionAssert.AreEqual(expected, result); - } - - [TestMethod] - public void Build_WithDetectorArgs() - { - var expected = ExpectedArgs("--SourceDirectory", "X:/") - .WithDetectorArgs("Hello=World,world=hello"); - - var builder = new ComponentDetectionCliArgumentBuilder() - .SourceDirectory("X:/") - .AddDetectorArg("Hello", "World") - .AddDetectorArg("world", "hello"); - - var result = builder.Build(); - CollectionAssert.AreEqual(expected, result); - } - - [TestMethod] - public void Build_WithArgs() - { - var expected = ExpectedArgs("--SourceDirectory", "X:/") - .WithDetectorArgs() - .WithArgs("--ManifestFile", "Hello", "--DirectoryExclusionList", "X:/hello"); - - var builder = new ComponentDetectionCliArgumentBuilder() - .SourceDirectory("X:/") - .AddArg("ManifestFile", "Hello") - .AddArg("--DirectoryExclusionList", "X:/hello"); - - var result = builder.Build(); - CollectionAssert.AreEqual(expected, result); - } - - [TestMethod] - public void Build_WithArgsDuplicate() - { - var expected = ExpectedArgs("--SourceDirectory", "X:/") - .WithDetectorArgs() - .WithArgs("--ManifestFile", "Hello", "--DirectoryExclusionList", "X:/hello"); - - var builder = new ComponentDetectionCliArgumentBuilder() - .SourceDirectory("X:/") - .AddArg("ManifestFile", "Hello") - .AddArg("--DirectoryExclusionList", "X:/hello") - .AddArg("ManifestFile", "Hello") - .AddArg("--DirectoryExclusionList", "X:/hello"); - - var result = builder.Build(); - CollectionAssert.AreEqual(expected, result); - } - - [TestMethod] - public void Build_ParseAndAddArgs() - { - var expected = ExpectedArgs("--SourceDirectory", "X:/") - .WithDetectorArgs() - .WithArgs("--ManifestFile", "Hello", "--DirectoryExclusionList", "X:/hello"); - - var builder = new ComponentDetectionCliArgumentBuilder() - .SourceDirectory("X:/") - .ParseAndAddArgs("--ManifestFile Hello --DirectoryExclusionList X:/hello"); - - var result = builder.Build(); - CollectionAssert.AreEqual(expected, result); - } - - [TestMethod] - public void Build_ParseAndAddArgsDuplicate() - { - var expected = ExpectedArgs("--SourceDirectory", "X:/") - .WithDetectorArgs() - .WithArgs("--ManifestFile", "Hello", "--DirectoryExclusionList", "X:/hello"); - - var builder = new ComponentDetectionCliArgumentBuilder() - .SourceDirectory("X:/") - .ParseAndAddArgs("--ManifestFile Hello --DirectoryExclusionList X:/hello") - .ParseAndAddArgs("--ManifestFile Hello --DirectoryExclusionList X:/hello") - .AddArg("ManifestFile", "Hello") - .AddArg("--DirectoryExclusionList", "X:/hello"); - - var result = builder.Build(); - CollectionAssert.AreEqual(expected, result); - } - - [TestMethod] - public void Build_AddNoValueArgs() - { - var expected = ExpectedArgs("--SourceDirectory", "X:/") - .WithDetectorArgs() - .WithArgs("--ManifestFile", "Hello", "--DirectoryExclusionList", "X:/hello", "--Help"); - - var builder = new ComponentDetectionCliArgumentBuilder() - .SourceDirectory("X:/") - .ParseAndAddArgs("--ManifestFile Hello --DirectoryExclusionList X:/hello") - .AddArg("Help"); - - var result = builder.Build(); - CollectionAssert.AreEqual(expected, result); - } - - [TestMethod] - public void Build_AddDetectorArgsViaAddArgCombineWithOtherDetectorArgs() - { - var expected = ExpectedArgs("--SourceDirectory", "X:/") - .WithDetectorArgs("SPDX=hello,Hello=World,world=hello"); - - var builder = new ComponentDetectionCliArgumentBuilder() - .SourceDirectory("X:/") - .AddArg("DetectorArgs", "SPDX=hello") - .AddDetectorArg("Hello", "World") - .AddDetectorArg("world", "hello"); - - var result = builder.Build(); - CollectionAssert.AreEqual(expected, result); - } - - [TestMethod] - public void AddArg_WithNullValue_Throws() - { - var builder = new ComponentDetectionCliArgumentBuilder(); - - Assert.ThrowsException(() => builder.AddArg("ManifestFile", null)); - } - - [TestMethod] - public void AddArg_WithInvalidArg_Throws() - { - var builder = new ComponentDetectionCliArgumentBuilder(); - - Assert.ThrowsException(() => builder.AddArg("--", "X:/hello")); - } - - [TestMethod] - public void Build_WithSpacesSourceDirectory() - { - var expected = ExpectedArgs("--SourceDirectory", "X:/path with spaces/") - .WithDetectorArgs(); - - var build = new ComponentDetectionCliArgumentBuilder() - .SourceDirectory("X:/path with spaces/"); - - var result = build.Build(); - CollectionAssert.AreEqual(expected, result); - } - - [TestMethod] - public void Build_WithSpacesInArgument() - { - var expected = ExpectedArgs("--SourceDirectory", "X:/path with spaces/") - .WithDetectorArgs() - .WithArgs("--MyArguemnt", "value with spaces"); - - var build = new ComponentDetectionCliArgumentBuilder() - .SourceDirectory("X:/path with spaces/") - .AddArg("MyArguemnt", "value with spaces"); - - var result = build.Build(); - CollectionAssert.AreEqual(expected, result); - } - - [TestMethod] - public void Build_WithSpacesInDetectorArgs() - { - var expected = ExpectedArgs("--SourceDirectory", "X:/path with spaces/") - .WithDetectorArgs("DetectorName=X:/complex/path with spaces"); - - var build = new ComponentDetectionCliArgumentBuilder() - .SourceDirectory("X:/path with spaces/") - .AddDetectorArg("DetectorName", "X:/complex/path with spaces"); - - var result = build.Build(); - CollectionAssert.AreEqual(expected, result); - } - - [TestMethod] - public void Build_DetectorArgs_DefaultTimeout() - { - var expected = ExpectedArgs() - .WithDetectorArgs($"Timeout={DefaultTimeout}"); - - var build = new ComponentDetectionCliArgumentBuilder() - .SourceDirectory("X:/"); - - var result = build.Build(); - CollectionAssert.AreEquivalent(expected, result[^2..]); - } - - [TestMethod] - public void Build_DetectorArgs_Timeout() - { - var timeout = 32789; - var expected = ExpectedArgs().WithDetectorArgs($"Timeout={timeout}"); - - var build = new ComponentDetectionCliArgumentBuilder() - .SourceDirectory("X:/") - .AddDetectorArg("Timeout", timeout.ToString()); - - var result = build.Build(); - CollectionAssert.AreEquivalent(expected, result[^2..]); - } - - [TestMethod] - public void Build_MultipleDetectorArgs_Timeout() - { - var timeout = 32789; - var expected = ExpectedArgs().WithDetectorArgs($"Timeout={timeout},Foo=bar"); - - var build = new ComponentDetectionCliArgumentBuilder() - .SourceDirectory("X:/") - .AddDetectorArg("Foo", "bar") - .AddDetectorArg("Timeout", timeout.ToString()); - - var result = build.Build(); - CollectionAssert.AreEquivalent(expected, result[^2..]); - } - - [TestMethod] - public void BuildScanSettings_ValidArgs() - { - var expected = new ScanSettings - { - ManifestFile = new System.IO.FileInfo("Hello"), - DirectoryExclusionList = new string[] { "X:/hello", "X:/world" }, - }; - - var builder = new ComponentDetectionCliArgumentBuilder() - .SourceDirectory("X:/") - .ParseAndAddArgs("--ManifestFile Hello --DirectoryExclusionList X:/hello;X:/world"); - - var parsedArgs = builder.Build(); - - var result = builder.BuildScanSettingsFromParsedArgs(parsedArgs); - - Assert.AreEqual(expected.ManifestFile.Name, result.ManifestFile.Name); - Assert.AreEqual(expected.DirectoryExclusionList.First(), result.DirectoryExclusionList.First()); - Assert.AreEqual(expected.DirectoryExclusionList.Count(), result.DirectoryExclusionList.Count()); - } - - [TestMethod] - public void BuildScanSettings_WithDetectorArgs() - { - var timeout = 32789; - var expected = new ScanSettings - { - DetectorArgs = new Dictionary - { - { "Timeout", timeout.ToString() }, - { "Foo", "bar" }, - }, - SourceDirectory = new System.IO.DirectoryInfo("X:/"), - }; - - var builder = new ComponentDetectionCliArgumentBuilder() - .SourceDirectory("X:/") - .AddDetectorArg("Foo", "bar") - .AddDetectorArg("Timeout", timeout.ToString()); - - var parsedArgs = builder.Build(); - - var result = builder.BuildScanSettingsFromParsedArgs(parsedArgs); - - Assert.AreEqual(expected.DetectorArgs.First().Key, result.DetectorArgs.First().Key); - Assert.AreEqual(expected.DetectorArgs.First().Value, result.DetectorArgs.First().Value); - Assert.AreEqual(expected.DetectorArgs.Count(), result.DetectorArgs.Count()); - Assert.AreEqual(expected.SourceDirectory.Name, result.SourceDirectory.Name); - } -} - -#pragma warning disable SA1402 // File may only contain a single type -internal static class ComponentDetectionCliArgumentBuilderTestsExtensions -#pragma warning restore SA1402 // File may only contain a single type -{ - internal static string[] ExpectedArgs(params string[] args) => args; - - internal static string[] WithArgs(this string[] args, params string[] moreArgs) => - Enumerable.Concat(args, moreArgs).ToArray(); - - internal static string[] WithDetectorArgs(this string[] args, string detectorArgs = "") - { - var defaultTimeoutArg = $"Timeout={ComponentDetectionCliArgumentBuilderTests.DefaultTimeout}"; - if (string.IsNullOrEmpty(detectorArgs)) - { - detectorArgs = defaultTimeoutArg; - } - else if (!detectorArgs.Contains("Timeout=")) - { - detectorArgs = string.Join(",", defaultTimeoutArg, detectorArgs); - } - - return args.WithArgs("--DetectorArgs", detectorArgs); - } -} diff --git a/test/Microsoft.Sbom.Api.Tests/Utils/ComponentDetectorCachedExecutorTest.cs b/test/Microsoft.Sbom.Api.Tests/Utils/ComponentDetectorCachedExecutorTest.cs deleted file mode 100644 index cbd67cfe..00000000 --- a/test/Microsoft.Sbom.Api.Tests/Utils/ComponentDetectorCachedExecutorTest.cs +++ /dev/null @@ -1,54 +0,0 @@ -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -using System.IO; -using System.Threading.Tasks; -using Microsoft.ComponentDetection.Contracts.BcdeModels; -using Microsoft.ComponentDetection.Orchestrator.Commands; -using Microsoft.Sbom.Api.Utils; -using Microsoft.VisualStudio.TestTools.UnitTesting; -using Moq; -using Serilog; - -namespace Microsoft.Sbom.Api.Tests.Utils; - -[TestClass] -public class ComponentDetectorCachedExecutorTest -{ - private readonly Mock logger = new Mock(); - private readonly Mock detector = new Mock(); - - [TestInitialize] - public void TestInitialize() - { - logger.Reset(); - detector.Reset(); - } - - [TestMethod] - public async Task Scan() - { - var executor = new ComponentDetectorCachedExecutor(logger.Object, detector.Object); - var arguments = new ScanSettings { SourceDirectory = new DirectoryInfo("test"), Debug = true }; - var expectedResult = new ScanResult(); - - detector.Setup(x => x.ScanAsync(arguments)).Returns(Task.FromResult(expectedResult)); - var result = await executor.ScanAsync(arguments); - Assert.AreEqual(expectedResult, result); - Assert.AreEqual(1, detector.Invocations.Count); - } - - [TestMethod] - public async Task ScanWithCache() - { - var executor = new ComponentDetectorCachedExecutor(logger.Object, detector.Object); - var arguments = new ScanSettings { SourceDirectory = new DirectoryInfo("test"), Debug = true }; - var expectedResult = new ScanResult(); - - detector.Setup(x => x.ScanAsync(arguments)).Returns(Task.FromResult(expectedResult)); - await executor.ScanAsync(arguments); - var result = await executor.ScanAsync(arguments); - Assert.AreEqual(expectedResult, result); - Assert.AreEqual(1, detector.Invocations.Count); - } -} diff --git a/test/Microsoft.Sbom.Api.Tests/Utils/ExternalReferenceDeduplicatorTests.cs b/test/Microsoft.Sbom.Api.Tests/Utils/ExternalReferenceDeduplicatorTests.cs deleted file mode 100644 index 8273c93f..00000000 --- a/test/Microsoft.Sbom.Api.Tests/Utils/ExternalReferenceDeduplicatorTests.cs +++ /dev/null @@ -1,140 +0,0 @@ -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -using System.Collections.Generic; -using System.Linq; -using System.Threading.Channels; -using System.Threading.Tasks; -using Microsoft.Sbom.Api.Executors; -using Microsoft.Sbom.Api.Utils; -using Microsoft.Sbom.Extensions.Entities; -using Microsoft.VisualStudio.TestTools.UnitTesting; - -namespace Microsoft.Sbom.Api.Tests.Utils; - -[TestClass] -public class ExternalReferenceDeduplicatorTests -{ - private readonly ChannelUtils channelUtils = new ChannelUtils(); - - [TestMethod] - public async Task When_DeduplicatingExternalDocRefInfo_WithSingleChannel_ThenTestPass() - { - var references = new List() - { - new ExternalDocumentReferenceInfo() - { - DocumentNamespace = "http://sbom.test/1" - }, - new ExternalDocumentReferenceInfo() - { - DocumentNamespace = "http://sbom.test/2" - }, - new ExternalDocumentReferenceInfo() - { - DocumentNamespace = "http://sbom.test/2" - }, - new ExternalDocumentReferenceInfo() - { - DocumentNamespace = "http://sbom.test/3" - }, - new ExternalDocumentReferenceInfo() - { - DocumentNamespace = "http://sbom.test/4" - }, - }; - - var inputChannel = Channel.CreateUnbounded(); - - foreach (var reference in references) - { - await inputChannel.Writer.WriteAsync(reference); - } - - inputChannel.Writer.Complete(); - - var deduplicator = new ExternalReferenceDeduplicator(); - var output = deduplicator.Deduplicate(inputChannel); - - var results = await output.ReadAllAsync().ToListAsync(); - - Assert.AreEqual(results.Count, references.Count - 1); - } - - [TestMethod] - public async Task When_DeduplicatingExternalDocRefInfo_WithConcurrentChannel_ThenTestPass() - { - var references = new List() - { - new ExternalDocumentReferenceInfo() - { - DocumentNamespace = "http://sbom.test/1" - }, - new ExternalDocumentReferenceInfo() - { - DocumentNamespace = "http://sbom.test/2" - }, - new ExternalDocumentReferenceInfo() - { - DocumentNamespace = "http://sbom.test/2" - }, - new ExternalDocumentReferenceInfo() - { - DocumentNamespace = "http://sbom.test/3" - }, - new ExternalDocumentReferenceInfo() - { - DocumentNamespace = "http://sbom.test/4" - }, - }; - - var deduplicator = new ExternalReferenceDeduplicator(); - - var task1 = Task.Run(async () => - { - var inputChannel = Channel.CreateUnbounded(); - - foreach (var reference in references) - { - await inputChannel.Writer.WriteAsync(reference); - } - - inputChannel.Writer.Complete(); - - var output = deduplicator.Deduplicate(inputChannel); - - return output; - }); - - var task2 = Task.Run(async () => - { - var inputChannel = Channel.CreateUnbounded(); - - foreach (var reference in references) - { - await inputChannel.Writer.WriteAsync(reference); - } - - inputChannel.Writer.Complete(); - - var output = deduplicator.Deduplicate(inputChannel); - - return output; - }); - - await Task.WhenAll(task1, task2); - var result = channelUtils.Merge(new ChannelReader[] { task1.Result, task2.Result }); - var resultList = await result.ReadAllAsync().ToListAsync(); - - Assert.AreEqual(resultList.Count, references.Count - 1); - } - - [TestMethod] - public void When_GetKeyForExternalDocRef_ThenTestPass() - { - var deduplicator = new ExternalReferenceDeduplicator(); - - Assert.AreEqual("http://sbom.test/1", deduplicator.GetKey(new ExternalDocumentReferenceInfo() { DocumentNamespace = "http://sbom.test/1" })); - Assert.IsNull(deduplicator.GetKey(null)); - } -} diff --git a/test/Microsoft.Sbom.Api.Tests/Utils/FileHashesDictionarySingleton.cs b/test/Microsoft.Sbom.Api.Tests/Utils/FileHashesDictionarySingleton.cs deleted file mode 100644 index eb9cf3c5..00000000 --- a/test/Microsoft.Sbom.Api.Tests/Utils/FileHashesDictionarySingleton.cs +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -using System; -using System.Collections.Concurrent; -using Microsoft.Sbom.Api.Manifest.FileHashes; - -namespace Microsoft.Sbom.Utils; - -/// -/// Singleton object to encapsulate a object. Only used for testing. -/// -public sealed class FileHashesDictionarySingleton -{ - private FileHashesDictionary dictionary; - - /// - /// Create a case insensitive dictionary for tests. - /// - private FileHashesDictionarySingleton() - => dictionary = new FileHashesDictionary(new ConcurrentDictionary(StringComparer.InvariantCultureIgnoreCase)); - - private static readonly Lazy Lazy = - new(() => new FileHashesDictionarySingleton()); - - public static FileHashesDictionary Instance => Lazy.Value.dictionary; - - /// - /// Resets the underlying dictionary. - /// - public static void Reset() - => Lazy.Value.dictionary = new FileHashesDictionary(new ConcurrentDictionary(StringComparer.InvariantCultureIgnoreCase)); -} diff --git a/test/Microsoft.Sbom.Api.Tests/Utils/FileSystemUtilsExtensionTest.cs b/test/Microsoft.Sbom.Api.Tests/Utils/FileSystemUtilsExtensionTest.cs deleted file mode 100644 index 4887b689..00000000 --- a/test/Microsoft.Sbom.Api.Tests/Utils/FileSystemUtilsExtensionTest.cs +++ /dev/null @@ -1,45 +0,0 @@ -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -using Microsoft.Sbom.Common; -using Microsoft.Sbom.Common.Extensions; -using Microsoft.VisualStudio.TestTools.UnitTesting; -using Moq; - -namespace Microsoft.Sbom.Api.Tests.Utils; - -[TestClass] -public class FileSystemUtilsExtensionTest -{ - private readonly Mock fileSystemUtilMock = new Mock(); - private readonly Mock osUtilMock = new Mock(); - private FileSystemUtilsExtension fileSystemUtilsExtension; - - private const string SourcePath = "/source/path"; - - [TestInitialize] - public void Setup() - { - fileSystemUtilsExtension = new FileSystemUtilsExtension(fileSystemUtilMock.Object, osUtilMock.Object); - osUtilMock.Setup(o => o.GetFileSystemStringComparisonType()).Returns(System.StringComparison.InvariantCultureIgnoreCase); - fileSystemUtilMock.Setup(f => f.AbsolutePath(SourcePath)).Returns($"C:{SourcePath}"); - } - - [TestMethod] - public void When_TargetPathIsOutsideOfSourcePath_Return_False() - { - var targetPath = "/source/outsidePath"; - fileSystemUtilMock.Setup(f => f.AbsolutePath(targetPath)).Returns($"C:{targetPath}"); - - Assert.IsFalse(fileSystemUtilsExtension.IsTargetPathInSource(targetPath, SourcePath)); - } - - [TestMethod] - public void When_TargetPathIsInsideOfSourcePath_Return_True() - { - var targetPath = "/source/path/insidePath"; - fileSystemUtilMock.Setup(f => f.AbsolutePath(targetPath)).Returns($"C:{targetPath}"); - - Assert.IsTrue(fileSystemUtilsExtension.IsTargetPathInSource(targetPath, SourcePath)); - } -} diff --git a/test/Microsoft.Sbom.Api.Tests/Utils/FileTypeUtilsTest.cs b/test/Microsoft.Sbom.Api.Tests/Utils/FileTypeUtilsTest.cs deleted file mode 100644 index ade11beb..00000000 --- a/test/Microsoft.Sbom.Api.Tests/Utils/FileTypeUtilsTest.cs +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -using Microsoft.Sbom.Api.Utils; -using Microsoft.Sbom.Contracts.Enums; -using Microsoft.VisualStudio.TestTools.UnitTesting; - -namespace Microsoft.Sbom.Api.Tests.Utils; - -[TestClass] -public class FileTypeUtilsTest -{ - private readonly FileTypeUtils fileTypeUtils = new FileTypeUtils(); - - [TestMethod] - public void When_GetFileTypeBy_WithSpdxFile_ThenReturnSPDXType() - { - var types = fileTypeUtils.GetFileTypesBy("random.spdx.json"); - Assert.AreEqual(1, types.Count); - Assert.AreEqual(FileType.SPDX, types[0]); - } - - [TestMethod] - public void When_GetFileTypeBy_WithNonNullFile_ThenReturnNull() - { - var types = fileTypeUtils.GetFileTypesBy("random"); - Assert.IsNull(types); - } - - [TestMethod] - public void When_GetFileTypeBy_WithNullFile_ThenReturnNull() - { - var types = fileTypeUtils.GetFileTypesBy(null); - Assert.IsNull(types); - } -} diff --git a/test/Microsoft.Sbom.Api.Tests/Utils/IdentifierUtilsTests.cs b/test/Microsoft.Sbom.Api.Tests/Utils/IdentifierUtilsTests.cs deleted file mode 100644 index bbdc5311..00000000 --- a/test/Microsoft.Sbom.Api.Tests/Utils/IdentifierUtilsTests.cs +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -using System; -using Microsoft.Sbom.Common.Utils; -using Microsoft.VisualStudio.TestTools.UnitTesting; - -namespace Microsoft.Sbom.Api.Utils.Tests; - -[TestClass] -public class IdentifierUtilsTests -{ - [TestMethod] - public void TryGetGuidFromShortGuidTest_Succeeds() - { - var shortGuid = IdentifierUtils.GetShortGuid(Guid.NewGuid()); - Assert.IsNotNull(shortGuid); - - Assert.IsTrue(IdentifierUtils.TryGetGuidFromShortGuid(shortGuid, out var guid)); - Assert.IsFalse(guid.Equals(Guid.Empty)); - } - - [TestMethod] - public void TryGetGuidFromShortGuidTest_BadString_Fails_DoesntThrow() - { - Assert.IsFalse(IdentifierUtils.TryGetGuidFromShortGuid(string.Empty, out var guid1)); - Assert.IsTrue(guid1.Equals(Guid.Empty)); - - Assert.IsFalse(IdentifierUtils.TryGetGuidFromShortGuid(null, out var guid2)); - Assert.IsTrue(guid2.Equals(Guid.Empty)); - - Assert.IsFalse(IdentifierUtils.TryGetGuidFromShortGuid("asdf", out var guid3)); - Assert.IsTrue(guid3.Equals(Guid.Empty)); - } -} diff --git a/test/Microsoft.Sbom.Api.Tests/Utils/OSUtilsTest.cs b/test/Microsoft.Sbom.Api.Tests/Utils/OSUtilsTest.cs deleted file mode 100644 index b4a1005f..00000000 --- a/test/Microsoft.Sbom.Api.Tests/Utils/OSUtilsTest.cs +++ /dev/null @@ -1,95 +0,0 @@ -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -using System.Collections; -using System.Collections.Generic; -using Microsoft.Sbom.Common; -using Microsoft.VisualStudio.TestTools.UnitTesting; -using Moq; -using Serilog; - -namespace Microsoft.Sbom.Api.Tests.Utils; - -[TestClass] -public class OSUtilsTest -{ - private readonly Mock logger = new Mock(); - - private readonly Mock environment = new Mock(); - - private OSUtils osUtils; - - private const string Variable = "Packaging.Variable"; - - [TestInitialize] - public void TestInitialize() - { - logger.Reset(); - environment.Reset(); - } - - [TestMethod] - public void GetEnvironmentVariable_SingleEnvVar() - { - IDictionary d = new Dictionary() - { - { "Agent", "a" }, - { Variable, "true" }, - }; - - environment.Setup(o => o.GetEnvironmentVariables()).Returns(d); - osUtils = new OSUtils(logger.Object, environment.Object); - - Assert.AreEqual("true", osUtils.GetEnvironmentVariable(Variable)); - environment.VerifyAll(); - logger.VerifyAll(); - } - - [TestMethod] - public void GetEnvironmentVariable_DuplicateEnvVar() - { - IDictionary d = new Dictionary() - { - { "Agent", "a" }, - { Variable, "true" }, - { Variable.ToLower(), "trueLower" }, - { Variable.ToUpper(), "trueUpper" }, - }; - - environment.Setup(o => o.GetEnvironmentVariables()).Returns(d); - osUtils = new OSUtils(logger.Object, environment.Object); - - Assert.AreEqual("true", osUtils.GetEnvironmentVariable(Variable)); - environment.VerifyAll(); - logger.Verify(o => o.Warning($"There are duplicate environment variables in different case for {Variable}, the value used is true"), Times.Once()); - } - - [TestMethod] - public void GetEnvironmentVariable_Null() - { - IDictionary d = new Dictionary() - { - { "Agent", "a" }, - }; - - environment.Setup(o => o.GetEnvironmentVariables()).Returns(d); - osUtils = new OSUtils(logger.Object, environment.Object); - - Assert.IsNull(osUtils.GetEnvironmentVariable(Variable)); - environment.VerifyAll(); - logger.VerifyAll(); - } - - [TestMethod] - public void GetEnvironmentVariable_NullFromEmptyEnvVar() - { - IDictionary d = new Dictionary() { }; - - environment.Setup(o => o.GetEnvironmentVariables()).Returns(d); - osUtils = new OSUtils(logger.Object, environment.Object); - - Assert.IsNull(osUtils.GetEnvironmentVariable(Variable)); - environment.VerifyAll(); - logger.VerifyAll(); - } -} diff --git a/test/Microsoft.Sbom.Api.Tests/Utils/SBOMFileDedeplicatorTests.cs b/test/Microsoft.Sbom.Api.Tests/Utils/SBOMFileDedeplicatorTests.cs deleted file mode 100644 index 608f5c42..00000000 --- a/test/Microsoft.Sbom.Api.Tests/Utils/SBOMFileDedeplicatorTests.cs +++ /dev/null @@ -1,140 +0,0 @@ -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -using System.Collections.Generic; -using System.Linq; -using System.Threading.Channels; -using System.Threading.Tasks; -using Microsoft.Sbom.Api.Executors; -using Microsoft.Sbom.Api.Utils; -using Microsoft.Sbom.Extensions.Entities; -using Microsoft.VisualStudio.TestTools.UnitTesting; - -namespace Microsoft.Sbom.Api.Tests.Utils; - -[TestClass] -public class SBOMFileDedeplicatorTests -{ - private readonly ChannelUtils channelUtils = new ChannelUtils(); - - [TestMethod] - public async Task When_DeduplicatingSBOMFile_WithSingleChannel_ThenTestPass() - { - var sbomFiles = new List() - { - new InternalSbomFileInfo() - { - Path = "./file1.txt" - }, - new InternalSbomFileInfo() - { - Path = "./file2.txt" - }, - new InternalSbomFileInfo() - { - Path = "./file2.txt" - }, - new InternalSbomFileInfo() - { - Path = "./file3.txt" - }, - new InternalSbomFileInfo() - { - Path = "./file4.txt" - } - }; - - var inputChannel = Channel.CreateUnbounded(); - - foreach (var sbomFile in sbomFiles) - { - await inputChannel.Writer.WriteAsync(sbomFile); - } - - inputChannel.Writer.Complete(); - - var deduplicator = new InternalSBOMFileInfoDeduplicator(); - var output = deduplicator.Deduplicate(inputChannel); - - var results = await output.ReadAllAsync().ToListAsync(); - - Assert.AreEqual(results.Count, sbomFiles.Count - 1); - } - - [TestMethod] - public async Task When_DeduplicatingSBOMFile_WithConcurrentChannel_ThenTestPass() - { - var sbomFiles = new List() - { - new InternalSbomFileInfo() - { - Path = "./file1.txt" - }, - new InternalSbomFileInfo() - { - Path = "./file2.txt" - }, - new InternalSbomFileInfo() - { - Path = "./file2.txt" - }, - new InternalSbomFileInfo() - { - Path = "./file3.txt" - }, - new InternalSbomFileInfo() - { - Path = "./file4.txt" - } - }; - - var deduplicator = new InternalSBOMFileInfoDeduplicator(); - - var task1 = Task.Run(async () => - { - var inputChannel = Channel.CreateUnbounded(); - - foreach (var fileInfo in sbomFiles) - { - await inputChannel.Writer.WriteAsync(fileInfo); - } - - inputChannel.Writer.Complete(); - - var output = deduplicator.Deduplicate(inputChannel); - - return output; - }); - - var task2 = Task.Run(async () => - { - var inputChannel = Channel.CreateUnbounded(); - - foreach (var fileInfo in sbomFiles) - { - await inputChannel.Writer.WriteAsync(fileInfo); - } - - inputChannel.Writer.Complete(); - - var output = deduplicator.Deduplicate(inputChannel); - - return output; - }); - - await Task.WhenAll(task1, task2); - var result = channelUtils.Merge(new ChannelReader[] { task1.Result, task2.Result }); - var resultList = await result.ReadAllAsync().ToListAsync(); - - Assert.AreEqual(resultList.Count, sbomFiles.Count - 1); - } - - [TestMethod] - public void When_GetKeyForSBOMFile_ThenTestPass() - { - var deduplicator = new InternalSBOMFileInfoDeduplicator(); - - Assert.AreEqual("./file1.txt", deduplicator.GetKey(new InternalSbomFileInfo() { Path = "./file1.txt" })); - Assert.IsNull(deduplicator.GetKey(null)); - } -} diff --git a/test/Microsoft.Sbom.Api.Tests/Workflows/Helpers/RelationshipsArrayGeneratorTest.cs b/test/Microsoft.Sbom.Api.Tests/Workflows/Helpers/RelationshipsArrayGeneratorTest.cs deleted file mode 100644 index 935721af..00000000 --- a/test/Microsoft.Sbom.Api.Tests/Workflows/Helpers/RelationshipsArrayGeneratorTest.cs +++ /dev/null @@ -1,174 +0,0 @@ -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Threading.Tasks; -using Microsoft.Sbom.Api.Executors; -using Microsoft.Sbom.Api.Manifest; -using Microsoft.Sbom.Api.Manifest.Configuration; -using Microsoft.Sbom.Api.Output; -using Microsoft.Sbom.Api.Output.Telemetry; -using Microsoft.Sbom.Api.Recorder; -using Microsoft.Sbom.Api.Workflows.Helpers; -using Microsoft.Sbom.Common; -using Microsoft.Sbom.Extensions; -using Microsoft.Sbom.Extensions.Entities; -using Microsoft.VisualStudio.TestTools.UnitTesting; -using Moq; -using Serilog; -using Constants = Microsoft.Sbom.Api.Utils.Constants; - -namespace Microsoft.Sbom.Api.Tests.Workflows.Helpers; - -[TestClass] -public class RelationshipsArrayGeneratorTest -{ - private RelationshipsArrayGenerator relationshipsArrayGenerator; - - private readonly Mock recorderMock = new Mock(); - private readonly Mock sbomConfigsMock = new Mock(); - private readonly Mock relationshipGeneratorMock = new Mock(new ManifestGeneratorProvider(null)); - private readonly Mock loggerMock = new Mock(); - private readonly Mock mockLogger = new Mock(); - private readonly Mock fileSystemUtilsMock = new Mock(); - private readonly ManifestGeneratorProvider manifestGeneratorProvider = new ManifestGeneratorProvider(new IManifestGenerator[] { new TestManifestGenerator() }); - private ISbomPackageDetailsRecorder recorder; - private IMetadataBuilder metadataBuilder; - private ISbomConfig sbomConfig; - private readonly ManifestInfo manifestInfo = new ManifestInfo(); - - private const string DocumentId = "documentId"; - private const string RootPackageId = "rootPackageId"; - private const string FileId1 = "fileId1"; - private const string FileId2 = "fileId2"; - private const string PackageId1 = "packageId1"; - private const string ExternalDocRefId1 = "externalDocRefId1"; - private const string ManifestJsonDirPath = "/root/_manifest"; - private const string JsonFilePath = "/root/_manifest/manifest.json"; - - private List relationships; - - [TestInitialize] - public void Setup() - { - recorder = new SbomPackageDetailsRecorder(); - relationships = new List(); - relationshipGeneratorMock.Setup(r => r.Run(It.IsAny>(), It.IsAny())) - .Callback, ManifestInfo>((relationship, manifestInfo) => - { - while (relationship.MoveNext()) - { - relationships.Add(relationship.Current); - } - }); - relationshipGeneratorMock.CallBase = true; - relationshipsArrayGenerator = new RelationshipsArrayGenerator(relationshipGeneratorMock.Object, new ChannelUtils(), loggerMock.Object, sbomConfigsMock.Object, recorderMock.Object); - manifestGeneratorProvider.Init(); - metadataBuilder = new MetadataBuilder( - mockLogger.Object, - manifestGeneratorProvider, - Constants.TestManifestInfo, - recorderMock.Object); - sbomConfig = new SbomConfig(fileSystemUtilsMock.Object) - { - ManifestInfo = Constants.TestManifestInfo, - ManifestJsonDirPath = ManifestJsonDirPath, - ManifestJsonFilePath = JsonFilePath, - MetadataBuilder = metadataBuilder, - Recorder = recorder, - }; - fileSystemUtilsMock.Setup(f => f.CreateDirectory(ManifestJsonDirPath)); - fileSystemUtilsMock.Setup(f => f.OpenWrite(JsonFilePath)).Returns(new MemoryStream()); - - sbomConfig.StartJsonSerialization(); - sbomConfig.JsonSerializer.StartJsonObject(); - - sbomConfigsMock.Setup(s => s.GetManifestInfos()).Returns(new List { manifestInfo }); - sbomConfigsMock.Setup(s => s.Get(manifestInfo)).Returns(sbomConfig); - } - - [TestMethod] - public async Task When_BaseGenerationDataExist_DescribesRelationshipsAreGenerated() - { - recorder.RecordDocumentId(DocumentId); - recorder.RecordRootPackageId(RootPackageId); - var results = await relationshipsArrayGenerator.GenerateAsync(); - - Assert.AreEqual(0, results.Count); - Assert.AreEqual(1, relationships.Count); - - var describesRelationships = relationships.Where(r => r.RelationshipType == RelationshipType.DESCRIBES); - Assert.AreEqual(1, describesRelationships.Count()); - var describesRelationship = describesRelationships.First(); - Assert.AreEqual(RootPackageId, describesRelationship.TargetElementId); - Assert.AreEqual(DocumentId, describesRelationship.SourceElementId); - } - - [TestMethod] - public async Task When_SPDXFileGenerationDataExist_DescribedByRelationshipsAreGenerated() - { - recorder.RecordDocumentId(DocumentId); - recorder.RecordRootPackageId(RootPackageId); - recorder.RecordFileId(FileId1); - recorder.RecordFileId(FileId2); - recorder.RecordSPDXFileId(FileId1); - var results = await relationshipsArrayGenerator.GenerateAsync(); - - Assert.AreEqual(0, results.Count); - Assert.AreEqual(2, relationships.Count); - - var describedByRelationships = relationships.Where(r => r.RelationshipType == RelationshipType.DESCRIBED_BY); - Assert.AreEqual(1, describedByRelationships.Count()); - var describedByRelationship = describedByRelationships.First(); - Assert.AreEqual(DocumentId, describedByRelationship.TargetElementId); - Assert.AreEqual(FileId1, describedByRelationship.SourceElementId); - } - - [TestMethod] - public async Task When_ExternalDocRefGenerationDataExist_PreReqRelationshipsAreGenerated() - { - recorder.RecordDocumentId(DocumentId); - recorder.RecordRootPackageId(RootPackageId); - recorder.RecordExternalDocumentReferenceIdAndRootElement(ExternalDocRefId1, RootPackageId); - var results = await relationshipsArrayGenerator.GenerateAsync(); - - Assert.AreEqual(0, results.Count); - Assert.AreEqual(2, relationships.Count); - - var preReqForRelationships = relationships.Where(r => r.RelationshipType == RelationshipType.PREREQUISITE_FOR); - Assert.AreEqual(1, preReqForRelationships.Count()); - var preReqForRelationship = preReqForRelationships.First(); - Assert.AreEqual(RootPackageId, preReqForRelationship.TargetElementId); - Assert.AreEqual(RootPackageId, preReqForRelationship.SourceElementId); - Assert.AreEqual(ExternalDocRefId1, preReqForRelationship.TargetElementExternalReferenceId); - } - - [TestMethod] - public async Task When_PackageGenerationDataExist_DependOnRelationshipsAreGenerated() - { - recorder.RecordDocumentId(DocumentId); - recorder.RecordRootPackageId(RootPackageId); - recorder.RecordPackageId(PackageId1, RootPackageId); - var results = await relationshipsArrayGenerator.GenerateAsync(); - - Assert.AreEqual(0, results.Count); - Assert.AreEqual(2, relationships.Count); - - var dependsOnRelationships = relationships.Where(r => r.RelationshipType == RelationshipType.DEPENDS_ON); - Assert.AreEqual(1, dependsOnRelationships.Count()); - var dependsOnRelationship = dependsOnRelationships.First(); - Assert.AreEqual(PackageId1, dependsOnRelationship.TargetElementId); - Assert.AreEqual(RootPackageId, dependsOnRelationship.SourceElementId); - } - - [TestMethod] - public async Task When_NoGenerationDataExist_NoRelationshipsAreGenerated() - { - var results = await relationshipsArrayGenerator.GenerateAsync(); - - Assert.AreEqual(0, results.Count); - Assert.AreEqual(0, relationships.Count); - } -} diff --git a/test/Microsoft.Sbom.Api.Tests/Workflows/Helpers/SbomRedactorTests.cs b/test/Microsoft.Sbom.Api.Tests/Workflows/Helpers/SbomRedactorTests.cs deleted file mode 100644 index 3817400c..00000000 --- a/test/Microsoft.Sbom.Api.Tests/Workflows/Helpers/SbomRedactorTests.cs +++ /dev/null @@ -1,159 +0,0 @@ -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; -using Microsoft.Sbom.Api.FormatValidator; -using Microsoft.Sbom.Api.Workflows.Helpers; -using Microsoft.Sbom.Parsers.Spdx22SbomParser.Entities; -using Microsoft.VisualStudio.TestTools.UnitTesting; -using Moq; -using Serilog; - -namespace Microsoft.Sbom.Api.Tests.Workflows.Helpers; - -[TestClass] -public class SbomRedactorTests -{ - private Mock mockLogger; - private Mock mockValidatedSbom; - - private SbomRedactor testSubject; - - [TestInitialize] - public void Init() - { - mockLogger = new Mock(); - mockValidatedSbom = new Mock(); - testSubject = new SbomRedactor(mockLogger.Object); - } - - [TestCleanup] - public void Reset() - { - mockLogger.VerifyAll(); - } - - [TestMethod] - public async Task SbomRedactor_RemovesFilesSection() - { - var mockSbom = new FormatEnforcedSPDX2 - { - Files = new List - { - new SPDXFile() - } - }; - mockValidatedSbom.Setup(x => x.GetRawSPDXDocument()).ReturnsAsync(mockSbom); - await testSubject.RedactSBOMAsync(mockValidatedSbom.Object); - Assert.IsNull(mockSbom.Files); - } - - [TestMethod] - public async Task SbomRedactor_RemovesPackageFileRefs() - { - var mockSbom = new FormatEnforcedSPDX2 - { - Packages = new List - { - new SPDXPackage() - { - SpdxId = "package-1", - HasFiles = new List - { - "file-1", - "file-2", - } - }, - new SPDXPackage() - { - SpdxId = "package-2", - SourceInfo = "source-info" - }, - new SPDXPackage() - { - SpdxId = "package-3", - } - } - }; - mockValidatedSbom.Setup(x => x.GetRawSPDXDocument()).ReturnsAsync(mockSbom); - await testSubject.RedactSBOMAsync(mockValidatedSbom.Object); - Assert.AreEqual(3, mockSbom.Packages.Count()); - foreach (var package in mockSbom.Packages) - { - Assert.IsNull(package.HasFiles); - Assert.IsNull(package.SourceInfo); - Assert.IsNotNull(package.SpdxId); - } - } - - [TestMethod] - public async Task SbomRedactor_RemovesRelationshipsWithFileRefs() - { - var unredactedRelationship = new SPDXRelationship() - { - SourceElementId = "source", - TargetElementId = "target", - RelationshipType = "relationship-3", - }; - var mockSbom = new FormatEnforcedSPDX2 - { - Relationships = new List - { - new SPDXRelationship() - { - SourceElementId = "SPDXRef-File-1", - TargetElementId = "target", - RelationshipType = "relationship-1", - }, - new SPDXRelationship() - { - SourceElementId = "source", - TargetElementId = "SPDXRef-File-2", - RelationshipType = "relationship-2", - }, - unredactedRelationship - } - }; - mockValidatedSbom.Setup(x => x.GetRawSPDXDocument()).ReturnsAsync(mockSbom); - await testSubject.RedactSBOMAsync(mockValidatedSbom.Object); - Assert.AreEqual(1, mockSbom.Relationships.Count()); - Assert.AreEqual(mockSbom.Relationships.First(), unredactedRelationship); - } - - [TestMethod] - public async Task SbomRedactor_UpdatesDocNamespaceForMsftSboms() - { - var docNamespace = "microsoft/test/namespace/fakeguid"; - var mockSbom = new FormatEnforcedSPDX2 - { - CreationInfo = new CreationInfo - { - Creators = new List { "Tool: Microsoft.SBOMTool" } - }, - DocumentNamespace = docNamespace - }; - mockValidatedSbom.Setup(x => x.GetRawSPDXDocument()).ReturnsAsync(mockSbom); - await testSubject.RedactSBOMAsync(mockValidatedSbom.Object); - Assert.IsTrue(mockSbom.DocumentNamespace.Contains("microsoft/test/namespace/")); - Assert.IsFalse(mockSbom.DocumentNamespace.Contains("fakeguid")); - } - - [TestMethod] - public async Task SbomRedactor_DoesNotEditDocNamespaceForNonMsftSboms() - { - var docNamespace = "test-namespace"; - var mockSbom = new FormatEnforcedSPDX2 - { - CreationInfo = new CreationInfo - { - Creators = new List { "non-msft-tool" } - }, - DocumentNamespace = docNamespace - }; - mockValidatedSbom.Setup(x => x.GetRawSPDXDocument()).ReturnsAsync(mockSbom); - await testSubject.RedactSBOMAsync(mockValidatedSbom.Object); - Assert.AreEqual(mockSbom.DocumentNamespace, docNamespace); - } -} diff --git a/test/Microsoft.Sbom.Api.Tests/Workflows/ManifestGenerationWorkflowTests.cs b/test/Microsoft.Sbom.Api.Tests/Workflows/ManifestGenerationWorkflowTests.cs deleted file mode 100644 index dbfacf17..00000000 --- a/test/Microsoft.Sbom.Api.Tests/Workflows/ManifestGenerationWorkflowTests.cs +++ /dev/null @@ -1,415 +0,0 @@ -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Text; -using System.Threading.Channels; -using System.Threading.Tasks; -using Microsoft.ComponentDetection.Contracts; -using Microsoft.ComponentDetection.Contracts.BcdeModels; -using Microsoft.ComponentDetection.Contracts.TypedComponent; -using Microsoft.ComponentDetection.Orchestrator.Commands; -using Microsoft.Sbom.Api.Convertors; -using Microsoft.Sbom.Api.Entities; -using Microsoft.Sbom.Api.Exceptions; -using Microsoft.Sbom.Api.Executors; -using Microsoft.Sbom.Api.Filters; -using Microsoft.Sbom.Api.Hashing; -using Microsoft.Sbom.Api.Manifest; -using Microsoft.Sbom.Api.Manifest.Configuration; -using Microsoft.Sbom.Api.Output; -using Microsoft.Sbom.Api.Output.Telemetry; -using Microsoft.Sbom.Api.PackageDetails; -using Microsoft.Sbom.Api.Providers; -using Microsoft.Sbom.Api.Providers.ExternalDocumentReferenceProviders; -using Microsoft.Sbom.Api.Providers.FilesProviders; -using Microsoft.Sbom.Api.Providers.PackagesProviders; -using Microsoft.Sbom.Api.Recorder; -using Microsoft.Sbom.Api.Tests; -using Microsoft.Sbom.Api.Utils; -using Microsoft.Sbom.Api.Workflows.Helpers; -using Microsoft.Sbom.Common; -using Microsoft.Sbom.Common.Config; -using Microsoft.Sbom.Contracts; -using Microsoft.Sbom.Contracts.Enums; -using Microsoft.Sbom.Extensions; -using Microsoft.Sbom.Extensions.Entities; -using Microsoft.VisualStudio.TestTools.UnitTesting; -using Moq; -using Newtonsoft.Json.Linq; -using Serilog.Events; -using Checksum = Microsoft.Sbom.Contracts.Checksum; -using Constants = Microsoft.Sbom.Api.Utils.Constants; -using IComponentDetector = Microsoft.Sbom.Api.Utils.IComponentDetector; -using ILogger = Serilog.ILogger; - -namespace Microsoft.Sbom.Api.Workflows.Tests; - -[TestClass] -public class ManifestGenerationWorkflowTests -{ - private readonly Mock recorderMock = new Mock(); - - private readonly Mock fileSystemMock = new Mock(); - private readonly Mock configurationMock = new Mock(); - private readonly Mock mockLogger = new Mock(); - private readonly Mock hashCodeGeneratorMock = new Mock(); - private readonly Mock mockOSUtils = new Mock(); - private readonly Mock mockConfigHandler = new Mock(); - private readonly Mock mockMetadataProvider = new Mock(); - private readonly Mock mockDetector = new Mock(new Mock().Object, new Mock().Object); - private readonly Mock> relationshipArrayGenerator = new Mock>(); - private readonly Mock packageInfoConverterMock = new Mock(); - private readonly Mock sBOMReaderForExternalDocumentReferenceMock = new Mock(); - private readonly Mock fileSystemUtilsExtensionMock = new Mock(); - private readonly Mock licenseInformationFetcherMock = new Mock(); - private readonly Mock mockPackageDetailsFactory = new Mock(); - - [TestInitialize] - public void Setup() - { - fileSystemMock.Setup(f => f.GetRelativePath(It.IsAny(), It.IsAny())) - .Returns((string r, string p) => PathUtils.GetRelativePath(r, p)); - fileSystemUtilsExtensionMock.Setup(f => f.IsTargetPathInSource(It.IsAny(), It.IsAny())).Returns(true); - } - - [TestMethod] - [DataRow(true, true)] - [DataRow(false, false)] - [DataRow(true, false)] - [DataRow(false, true)] - public async Task ManifestGenerationWorkflowTests_Succeeds(bool deleteExistingManifestDir, bool isDefaultSourceManifestDirPath) - { - var manifestGeneratorProvider = new ManifestGeneratorProvider(new IManifestGenerator[] { new TestManifestGenerator() }); - manifestGeneratorProvider.Init(); - - var metadataBuilder = new MetadataBuilder( - mockLogger.Object, - manifestGeneratorProvider, - Constants.TestManifestInfo, - recorderMock.Object); - var jsonFilePath = "/root/_manifest/manifest.json"; - - ISbomConfig sbomConfig = new SbomConfig(fileSystemMock.Object) - { - ManifestInfo = Constants.TestManifestInfo, - ManifestJsonDirPath = "/root/_manifest", - ManifestJsonFilePath = jsonFilePath, - MetadataBuilder = metadataBuilder, - Recorder = new SbomPackageDetailsRecorder() - }; - - mockConfigHandler.Setup(c => c.TryGetManifestConfig(out sbomConfig)).Returns(true); - mockMetadataProvider.SetupGet(m => m.MetadataDictionary).Returns(new Dictionary - { - { MetadataKey.Build_BuildId, 12 }, - { MetadataKey.Build_DefinitionName, "test" }, - }); - - var sbomConfigs = new SbomConfigProvider( - new IManifestConfigHandler[] { mockConfigHandler.Object }, - new IMetadataProvider[] { mockMetadataProvider.Object }, - mockLogger.Object, - recorderMock.Object); - - using var manifestStream = new MemoryStream(); - using var manifestWriter = new StreamWriter(manifestStream); - using var sha256Stream = new MemoryStream(); - using var sha256Writer = new StreamWriter(sha256Stream); - - fileSystemMock.Setup(f => f.DirectoryExists(It.IsAny())).Returns(true); - if (isDefaultSourceManifestDirPath) - { - configurationMock.SetupGet(c => c.ManifestDirPath) - .Returns(new ConfigurationSetting { Value = PathUtils.Join("/root", "_manifest") }); - fileSystemMock.Setup(f => f.DirectoryExists(It.Is(d => d == PathUtils.Join("/root", "_manifest")))) - .Returns(deleteExistingManifestDir); - - if (deleteExistingManifestDir) - { - mockOSUtils.Setup(o => o.GetEnvironmentVariable(It.IsAny())).Returns("true"); - fileSystemMock.Setup(f => f.DeleteDir(It.IsAny(), true)).Verifiable(); - } - } - else - { - configurationMock.SetupGet(c => c.ManifestDirPath).Returns(new ConfigurationSetting { Value = PathUtils.Join("/root", "_manifest"), Source = SettingSource.CommandLine }); - } - - configurationMock.SetupGet(c => c.BuildDropPath).Returns(new ConfigurationSetting { Value = "/root" }); - configurationMock.SetupGet(c => c.Parallelism).Returns(new ConfigurationSetting { Value = 3 }); - configurationMock.SetupGet(c => c.ManifestToolAction).Returns(ManifestToolActions.Generate); - configurationMock.SetupGet(c => c.BuildComponentPath).Returns(new ConfigurationSetting { Value = "/root" }); - configurationMock.SetupGet(c => c.FollowSymlinks).Returns(new ConfigurationSetting { Value = true }); - - fileSystemMock - .Setup(f => f.CreateDirectory( - It.Is(d => d == "/root/_manifest"))) - .Returns(new DirectoryInfo("/")); - fileSystemMock - .Setup(f => f.OpenWrite( - It.Is(d => d == "/root/_manifest/manifest.json"))) - .Returns(manifestWriter.BaseStream); - - fileSystemMock.Setup(f => f.GetDirectories(It.Is(c => c == "/root"), true)).Returns(new string[] { "child1", "child2", "child3", "_manifest" }); - fileSystemMock.Setup(f => f.GetDirectories(It.Is(c => c == "child1"), true)).Returns(new string[] { }); - fileSystemMock.Setup(f => f.GetDirectories(It.Is(c => c == "child2"), true)).Returns(new string[] { "grandchild1", "grandchild2" }); - - fileSystemMock.Setup(f => f.GetFilesInDirectory(It.Is(c => c == "child1"), true)).Returns(new string[] { "/root/child1/file1", "/root/child1/file2" }); - fileSystemMock.Setup(f => f.GetFilesInDirectory(It.Is(c => c == "child2"), true)).Returns(new string[] { "/root/child2/file3", "/root/child2/file4", "/root/child2/file5" }); - fileSystemMock.Setup(f => f.GetFilesInDirectory(It.Is(c => c == "child3"), true)).Returns(new string[] { "/root/child3/file11", "/root/child3/file12" }); - fileSystemMock.Setup(f => f.GetFilesInDirectory(It.Is(c => c == "_manifest"), true)).Returns(new string[] { "/root/_manifest/manifest.json", "/root/_manifest/manifest.cat" }); - - fileSystemMock.Setup(f => f.GetFilesInDirectory(It.Is(c => c == "grandchild1"), true)).Returns(new string[] { "/root/child2/grandchild1/file6", "/root/child2/grandchild1/file10" }); - fileSystemMock.Setup(f => f.GetFilesInDirectory(It.Is(c => c == "grandchild2"), true)).Returns(new string[] { "/root/child2/grandchild1/file7", "/root/child2/grandchild1/file9" }); - - fileSystemMock.Setup(f => f.GetRelativePath(It.IsAny(), It.IsAny())) - .Returns((string r, string p) => PathUtils.GetRelativePath(r, p)); - - fileSystemMock.Setup(f => f.FileExists(It.Is(c => c == jsonFilePath))).Returns(true); - fileSystemMock.Setup(f => f.OpenRead(It.Is(c => c == jsonFilePath))).Returns(TestUtils.GenerateStreamFromString("randomContent")); - fileSystemMock.Setup(f => f.WriteAllText(It.Is(c => c == "/root/_manifest/manifest.json.sha256"), It.IsAny())); - - hashCodeGeneratorMock.Setup(h => h.GenerateHashes(It.IsAny(), It.IsAny())) - .Returns((string fileName, AlgorithmName[] algos) => - algos.Select(a => - new Checksum - { - ChecksumValue = $"{fileName}hash", - Algorithm = a - }) - .ToArray()); - - var manifestFilterMock = new ManifestFolderFilter(configurationMock.Object, mockOSUtils.Object); - manifestFilterMock.Init(); - - var scannedComponents = new List(); - for (var i = 1; i < 4; i++) - { - var scannedComponent = new ScannedComponent - { - Component = new NpmComponent("componentName", $"{i}") - }; - - scannedComponents.Add(scannedComponent); - } - - var scanResult = new ScanResult - { - ResultCode = ProcessingResultCode.Success, - ComponentsFound = scannedComponents - }; - - mockDetector.Setup(o => o.ScanAsync(It.IsAny())).Returns(Task.FromResult(scanResult)); - - var packagesChannel = Channel.CreateUnbounded(); - var errorsChannel = Channel.CreateUnbounded(); - foreach (var component in scannedComponents) - { - await packagesChannel.Writer.WriteAsync(new SbomPackage { PackageName = component.GetHashCode().ToString() }); - } - - packagesChannel.Writer.Complete(); - errorsChannel.Writer.Complete(); - packageInfoConverterMock - .Setup(p => p.Convert(It.IsAny>())) - .Returns((packagesChannel, errorsChannel)); - - var externalDocumentReferenceChannel = Channel.CreateUnbounded(); - var externalDocumentReferenceErrorsChannel = Channel.CreateUnbounded(); - await externalDocumentReferenceChannel.Writer.WriteAsync(new ExternalDocumentReferenceInfo - { - DocumentNamespace = "namespace", - ExternalDocumentName = "name", - Checksum = new List { new Checksum { Algorithm = AlgorithmName.SHA1, - ChecksumValue = "abc" - } } - }); - externalDocumentReferenceChannel.Writer.Complete(); - externalDocumentReferenceErrorsChannel.Writer.Complete(); - sBOMReaderForExternalDocumentReferenceMock - .Setup(p => p.ParseSBOMFile(It.IsAny>())) - .Returns((externalDocumentReferenceChannel, externalDocumentReferenceErrorsChannel)); - - var directoryTraversingProvider = new DirectoryTraversingFileToJsonProvider( - configurationMock.Object, - new ChannelUtils(), - mockLogger.Object, - new FileHasher( - hashCodeGeneratorMock.Object, - new SbomToolManifestPathConverter(configurationMock.Object, mockOSUtils.Object, fileSystemMock.Object, fileSystemUtilsExtensionMock.Object), - mockLogger.Object, - configurationMock.Object, - sbomConfigs, - manifestGeneratorProvider, - new FileTypeUtils()), - new ManifestFolderFilterer(manifestFilterMock, mockLogger.Object), - new FileInfoWriter( - manifestGeneratorProvider, - mockLogger.Object), - new InternalSBOMFileInfoDeduplicator(), - new DirectoryWalker(fileSystemMock.Object, mockLogger.Object, configurationMock.Object)); - - var fileListBasedProvider = new FileListBasedFileToJsonProvider( - configurationMock.Object, - new ChannelUtils(), - mockLogger.Object, - new FileHasher( - hashCodeGeneratorMock.Object, - new SbomToolManifestPathConverter(configurationMock.Object, mockOSUtils.Object, fileSystemMock.Object, fileSystemUtilsExtensionMock.Object), - mockLogger.Object, - configurationMock.Object, - sbomConfigs, - manifestGeneratorProvider, - new FileTypeUtils()), - new ManifestFolderFilterer(manifestFilterMock, mockLogger.Object), - new FileInfoWriter( - manifestGeneratorProvider, - mockLogger.Object), - new InternalSBOMFileInfoDeduplicator(), - new FileListEnumerator(fileSystemMock.Object, mockLogger.Object)); - - var cgPackagesProvider = new CGScannedPackagesProvider( - configurationMock.Object, - new ChannelUtils(), - mockLogger.Object, - sbomConfigs, - new PackageInfoJsonWriter( - manifestGeneratorProvider, - mockLogger.Object), - packageInfoConverterMock.Object, - new PackagesWalker(mockLogger.Object, mockDetector.Object, configurationMock.Object, sbomConfigs, fileSystemMock.Object, mockPackageDetailsFactory.Object, licenseInformationFetcherMock.Object), - mockPackageDetailsFactory.Object, - licenseInformationFetcherMock.Object); - - var externalDocumentReferenceProvider = new ExternalDocumentReferenceProvider( - configurationMock.Object, - new ChannelUtils(), - mockLogger.Object, - new FileListEnumerator(fileSystemMock.Object, mockLogger.Object), - sBOMReaderForExternalDocumentReferenceMock.Object, - new ExternalDocumentReferenceWriter( - manifestGeneratorProvider, - mockLogger.Object), - new ExternalReferenceDeduplicator()); - - var sourcesProvider = new List - { - { fileListBasedProvider }, - { directoryTraversingProvider }, - { cgPackagesProvider }, - { externalDocumentReferenceProvider } - }; - - var fileArrayGenerator = new FileArrayGenerator(sbomConfigs, sourcesProvider, recorderMock.Object, mockLogger.Object); - - var packageArrayGenerator = new PackageArrayGenerator(mockLogger.Object, sbomConfigs, sourcesProvider, recorderMock.Object); - - var externalDocumentReferenceGenerator = new ExternalDocumentReferenceGenerator(mockLogger.Object, sbomConfigs, sourcesProvider, recorderMock.Object); - - relationshipArrayGenerator - .Setup(r => r.GenerateAsync()) - .ReturnsAsync(await Task.FromResult(new List())); - - var workflow = new SbomGenerationWorkflow( - configurationMock.Object, - fileSystemMock.Object, - mockLogger.Object, - fileArrayGenerator, - packageArrayGenerator, - relationshipArrayGenerator.Object, - externalDocumentReferenceGenerator, - sbomConfigs, - mockOSUtils.Object, - recorderMock.Object); - - Assert.IsTrue(await workflow.RunAsync()); - - var result = Encoding.UTF8.GetString(manifestStream.ToArray()); - var resultJson = JObject.Parse(result); - - Assert.AreEqual("1.0.0", resultJson["Version"]); - Assert.AreEqual(12, resultJson["Build"]); - Assert.AreEqual("test", resultJson["Definition"]); - - var outputs = resultJson["Outputs"]; - var sortedOutputs = new JArray(outputs.OrderBy(obj => (string)obj["Source"])); - var expectedSortedOutputs = new JArray(outputs.OrderBy(obj => (string)obj["Source"])); - - var packages = resultJson["Packages"]; - Assert.AreEqual(4, packages.Count()); - - Assert.IsTrue(JToken.DeepEquals(sortedOutputs, expectedSortedOutputs)); - - configurationMock.VerifyAll(); - fileSystemMock.VerifyAll(); - hashCodeGeneratorMock.VerifyAll(); - mockLogger.VerifyAll(); - fileSystemMock.Verify(x => x.FileExists(jsonFilePath), Times.Once); - fileSystemMock.Verify(x => x.WriteAllText($"{jsonFilePath}.sha256", It.IsAny()), Times.Once); - } - - [TestMethod] - public async Task ManifestGenerationWorkflowTests_SBOMDirExists_Throws() - { - configurationMock.SetupGet(x => x.ManifestDirPath).Returns(new ConfigurationSetting { Value = PathUtils.Join("/root", "_manifest"), Source = SettingSource.Default }); - fileSystemMock.Setup(f => f.DirectoryExists(It.IsAny())).Returns(true); - mockOSUtils.Setup(o => o.GetEnvironmentVariable(It.IsAny())).Returns("false"); - var sbomConfig = new SbomConfig(fileSystemMock.Object) - { - ManifestInfo = Constants.TestManifestInfo, - ManifestJsonDirPath = "/root/_manifest", - ManifestJsonFilePath = "/root/_manifest/manifest.json" - }; - var workflow = new SbomGenerationWorkflow( - configurationMock.Object, - fileSystemMock.Object, - mockLogger.Object, - new Mock>().Object, - new Mock>().Object, - new Mock>().Object, - new Mock>().Object, - new Mock().Object, - mockOSUtils.Object, - recorderMock.Object); - - Assert.IsFalse(await workflow.RunAsync()); - recorderMock.Verify(r => r.RecordException(It.IsAny()), Times.Once); - } - - [TestMethod] - public async Task ManifestGenerationWorkflowTests_SBOMDir_NotDefault_NotDeleted() - { - fileSystemMock.Setup(f => f.DirectoryExists(It.IsAny())).Returns(true); - var sbomConfig = new SbomConfig(fileSystemMock.Object) - { - ManifestInfo = Constants.TestManifestInfo, - ManifestJsonDirPath = "/root/_manifest", - ManifestJsonFilePath = "/root/_manifest/manifest.json" - }; - configurationMock.SetupGet(x => x.ManifestDirPath).Returns(new ConfigurationSetting { Value = PathUtils.Join("/root", "_manifest"), Source = SettingSource.CommandLine }); - fileSystemMock.Setup(f => f.DirectoryExists(It.IsAny())).Returns(true); - fileSystemMock.Setup(f => f.DeleteDir(It.IsAny(), true)).Verifiable(); - var fileArrayGeneratorMock = new Mock>(); - fileArrayGeneratorMock.Setup(f => f.GenerateAsync()).ReturnsAsync(new List { new FileValidationResult() }); - - var workflow = new SbomGenerationWorkflow( - configurationMock.Object, - fileSystemMock.Object, - mockLogger.Object, - fileArrayGeneratorMock.Object, - new Mock>().Object, - new Mock>().Object, - new Mock>().Object, - new Mock().Object, - mockOSUtils.Object, - recorderMock.Object); - - var result = await workflow.RunAsync(); - - fileSystemMock.Verify(f => f.DeleteDir(It.IsAny(), true), Times.Once); - Assert.IsFalse(result); - } -} diff --git a/test/Microsoft.Sbom.Api.Tests/Workflows/SbomParserBasedValidationWorkflowTests.cs b/test/Microsoft.Sbom.Api.Tests/Workflows/SbomParserBasedValidationWorkflowTests.cs deleted file mode 100644 index 14604f39..00000000 --- a/test/Microsoft.Sbom.Api.Tests/Workflows/SbomParserBasedValidationWorkflowTests.cs +++ /dev/null @@ -1,382 +0,0 @@ -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Threading.Tasks; -using Microsoft.Sbom.Api.Convertors; -using Microsoft.Sbom.Api.Entities.Output; -using Microsoft.Sbom.Api.Executors; -using Microsoft.Sbom.Api.Filters; -using Microsoft.Sbom.Api.Hashing; -using Microsoft.Sbom.Api.Manifest; -using Microsoft.Sbom.Api.Manifest.Configuration; -using Microsoft.Sbom.Api.Output; -using Microsoft.Sbom.Api.Output.Telemetry; -using Microsoft.Sbom.Api.Recorder; -using Microsoft.Sbom.Api.SignValidator; -using Microsoft.Sbom.Api.Tests; -using Microsoft.Sbom.Api.Utils; -using Microsoft.Sbom.Api.Workflows; -using Microsoft.Sbom.Api.Workflows.Helpers; -using Microsoft.Sbom.Common; -using Microsoft.Sbom.Common.Config; -using Microsoft.Sbom.Contracts; -using Microsoft.Sbom.Contracts.Enums; -using Microsoft.Sbom.Extensions; -using Microsoft.Sbom.Extensions.Entities; -using Microsoft.Sbom.JsonAsynchronousNodeKit; -using Microsoft.Sbom.Parser; -using Microsoft.Sbom.Utils; -using Microsoft.VisualStudio.TestTools.UnitTesting; -using Moq; -using Serilog; -using Constants = Microsoft.Sbom.Api.Utils.Constants; -using ErrorType = Microsoft.Sbom.Api.Entities.ErrorType; -using SpdxChecksum = Microsoft.Sbom.Parsers.Spdx22SbomParser.Entities.Checksum; - -namespace Microsoft.Sbom.Workflows; - -#nullable enable - -[TestClass] -public class SbomParserBasedValidationWorkflowTests : ValidationWorkflowTestsBase -{ - private const string CaseSensitiveMessageMarker = "case-sensitive"; - - private readonly Mock mockLogger = new(); - private readonly Mock mockOSUtils = new(); - private readonly Mock fileSystemUtilsExtensionMock = new(); - private readonly Mock signValidatorMock = new(); - private readonly Mock signValidationProviderMock = new(); - - [TestInitialize] - public void Init() - { - signValidatorMock.Setup(s => s.Validate()).Returns(true); - signValidationProviderMock.Setup(s => s.Get()).Returns(signValidatorMock.Object); - } - - [TestCleanup] - public void Reset() - { - FileHashesDictionarySingleton.Reset(); - } - - [TestMethod] - public async Task SbomParserBasedValidationWorkflowTests_ReturnsSuccessAndValidationFailures_IgnoreMissingTrue_Succeeds() - { - var manifestParserProvider = new Mock(); - var manifestInterface = new Mock(); - var sbomParser = new Mock(); - var configurationMock = new Mock(); - var sbomConfigs = new Mock(); - var fileSystemMock = GetDefaultFileSystemMock(); - var outputWriterMock = new Mock(); - var recorder = new Mock(); - var hashCodeGeneratorMock = new Mock(); - - var dictionary = GetSpdxFilesDictionary(); - dictionary["/child2/grandchild1/file9"] = new SpdxChecksum[] { new SpdxChecksum { Algorithm = AlgorithmName.SHA256.Name, ChecksumValue = "/root/child2/grandchild1/file9hash" } }; - dictionary["/child2/grandchild1/file7"] = new SpdxChecksum[] { new SpdxChecksum { Algorithm = AlgorithmName.SHA256.Name, ChecksumValue = "/root/child2/grandchild1/file7hash" } }; - dictionary["/child2/grandchild1/file10"] = new SpdxChecksum[] { new SpdxChecksum { Algorithm = AlgorithmName.SHA256.Name, ChecksumValue = "/root/child2/grandchild1/file10hash" } }; - - sbomParser.SetupSequence(p => p.Next()) - .Returns(new FilesResult(new ParserStateResult(SPDXParser.FilesProperty, GetSpdxFiles(dictionary), ExplicitField: true, YieldReturn: true))) - .Returns((ParserStateResult?)null); - - manifestInterface.Setup(m => m.CreateParser(It.IsAny())) - .Returns(sbomParser.Object); - manifestParserProvider.Setup(m => m.Get(It.IsAny())).Returns(manifestInterface.Object); - - configurationMock.SetupGet(c => c.BuildDropPath).Returns(new ConfigurationSetting { Value = "/root" }); - configurationMock.SetupGet(c => c.ManifestDirPath).Returns(new ConfigurationSetting { Value = PathUtils.Join("/root", "_manifest") }); - configurationMock.SetupGet(c => c.Parallelism).Returns(new ConfigurationSetting { Value = 3 }); - configurationMock.SetupGet(c => c.HashAlgorithm).Returns(new ConfigurationSetting { Value = Constants.DefaultHashAlgorithmName }); - configurationMock.SetupGet(c => c.RootPathFilter).Returns(new ConfigurationSetting { Value = "child1;child2;child3" }); - configurationMock.SetupGet(c => c.IgnoreMissing).Returns(new ConfigurationSetting { Value = true }); - configurationMock.SetupGet(c => c.ManifestToolAction).Returns(ManifestToolActions.Validate); - configurationMock.SetupGet(c => c.FollowSymlinks).Returns(new ConfigurationSetting { Value = true }); - configurationMock.SetupGet(c => c.ValidateSignature).Returns(new ConfigurationSetting { Value = true }); - configurationMock.SetupGet(c => c.ManifestInfo).Returns(new ConfigurationSetting> - { - Value = new List() { Constants.SPDX22ManifestInfo } - }); - - ISbomConfig sbomConfig = new SbomConfig(fileSystemMock.Object) - { - ManifestInfo = Constants.SPDX22ManifestInfo, - ManifestJsonDirPath = "/root/_manifest", - ManifestJsonFilePath = "/root/_manifest/spdx_2.2/manifest.spdx.json", - MetadataBuilder = null, - Recorder = new SbomPackageDetailsRecorder() - }; - sbomConfigs.Setup(c => c.Get(Constants.SPDX22ManifestInfo)).Returns(sbomConfig); - - fileSystemMock.Setup(f => f.OpenRead("/root/_manifest/spdx_2.2/manifest.spdx.json")).Returns(Stream.Null); - fileSystemMock.Setup(f => f.GetRelativePath(It.IsAny(), It.IsAny())) - .Returns((string r, string p) => PathUtils.GetRelativePath(r, p)); - - fileSystemUtilsExtensionMock.Setup(f => f.IsTargetPathInSource(It.IsAny(), It.IsAny())).Returns(true); - - var validationResultGenerator = new ValidationResultGenerator(configurationMock.Object); - - var directoryWalker = new DirectoryWalker(fileSystemMock.Object, mockLogger.Object, configurationMock.Object); - - hashCodeGeneratorMock.Setup(h => h.GenerateHashes( - It.IsAny(), - new AlgorithmName[] { Constants.DefaultHashAlgorithmName })) - .Returns((string fileName, AlgorithmName[] algos) => - new Checksum[] - { - new Checksum - { - ChecksumValue = $"{fileName}hash", - Algorithm = Constants.DefaultHashAlgorithmName - } - }); - - var fileHasher = new FileHasher( - hashCodeGeneratorMock.Object, - new SbomToolManifestPathConverter(configurationMock.Object, mockOSUtils.Object, fileSystemMock.Object, fileSystemUtilsExtensionMock.Object), - mockLogger.Object, - configurationMock.Object, - new Mock().Object, - new ManifestGeneratorProvider(null), - new FileTypeUtils()); - - var manifestFilterMock = new ManifestFolderFilter(configurationMock.Object, mockOSUtils.Object); - manifestFilterMock.Init(); - var fileFilterer = new ManifestFolderFilterer(manifestFilterMock, mockLogger.Object); - - var rootFileFilterMock = new DownloadedRootPathFilter(configurationMock.Object, fileSystemMock.Object, mockLogger.Object); - rootFileFilterMock.Init(); - - var osUtilsMock = new Mock(MockBehavior.Strict); - - var hashValidator = new ConcurrentSha256HashValidator(FileHashesDictionarySingleton.Instance); - var enumeratorChannel = new EnumeratorChannel(mockLogger.Object); - var fileConverter = new SbomFileToFileInfoConverter(new FileTypeUtils()); - var spdxFileFilterer = new FileFilterer(rootFileFilterMock, mockLogger.Object, configurationMock.Object, fileSystemMock.Object); - - var filesValidator = new FilesValidator( - directoryWalker, - configurationMock.Object, - mockLogger.Object, - fileHasher, - fileFilterer, - hashValidator, - enumeratorChannel, - fileConverter, - FileHashesDictionarySingleton.Instance, - spdxFileFilterer); - - var validator = new SbomParserBasedValidationWorkflow( - recorder.Object, - signValidationProviderMock.Object, - mockLogger.Object, - manifestParserProvider.Object, - configurationMock.Object, - sbomConfigs.Object, - filesValidator, - validationResultGenerator, - outputWriterMock.Object, - fileSystemMock.Object, - osUtilsMock.Object); - - var cc = new ConsoleCapture(); - - try - { - var result = await validator.RunAsync(); - Assert.IsTrue(result); - } - finally - { - cc.Restore(); - } - - var nodeValidationResults = validationResultGenerator.NodeValidationResults; - - var additionalFileErrors = nodeValidationResults.Where(a => a.ErrorType == ErrorType.AdditionalFile).ToList(); - Assert.AreEqual(0, additionalFileErrors.Count); - - var missingFileErrors = nodeValidationResults.Where(a => a.ErrorType == ErrorType.MissingFile).ToList(); - Assert.AreEqual(1, missingFileErrors.Count); - Assert.AreEqual("./child2/grandchild2/file10", missingFileErrors.First().Path); - - var invalidHashErrors = nodeValidationResults.Where(a => a.ErrorType == ErrorType.InvalidHash).ToList(); - Assert.AreEqual(0, invalidHashErrors.Count); - - var otherErrors = nodeValidationResults.Where(a => a.ErrorType == ErrorType.Other).ToList(); - Assert.AreEqual(0, otherErrors.Count); - - Assert.IsFalse(cc.CapturedStdOut.Contains(CaseSensitiveMessageMarker), "Case-sensitive marker should not have been output"); - - configurationMock.VerifyAll(); - signValidatorMock.VerifyAll(); - fileSystemMock.VerifyAll(); - osUtilsMock.VerifyAll(); - } - - [TestMethod] - public async Task SbomParserBasedValidationWorkflowTests_ReturnsSuccessAndValidationFailures_Succeeds() - { - var manifestParserProvider = new Mock(); - var manifestInterface = new Mock(); - var sbomParser = new Mock(); - var configurationMock = new Mock(); - var sbomConfigs = new Mock(); - var fileSystemMock = GetDefaultFileSystemMock(); - var outputWriterMock = new Mock(); - var recorder = new Mock(); - var hashCodeGeneratorMock = new Mock(); - - sbomParser.SetupSequence(p => p.Next()) - .Returns(new FilesResult(new ParserStateResult(SPDXParser.FilesProperty, GetSpdxFiles(GetSpdxFilesDictionary()), ExplicitField: true, YieldReturn: true))) - .Returns((ParserStateResult?)null); - - manifestInterface.Setup(m => m.CreateParser(It.IsAny())) - .Returns(sbomParser.Object); - manifestParserProvider.Setup(m => m.Get(It.IsAny())).Returns(manifestInterface.Object); - - configurationMock.SetupGet(c => c.BuildDropPath).Returns(new ConfigurationSetting { Value = "/root" }); - configurationMock.SetupGet(c => c.ManifestDirPath).Returns(new ConfigurationSetting { Value = PathUtils.Join("/root", "_manifest") }); - configurationMock.SetupGet(c => c.Parallelism).Returns(new ConfigurationSetting { Value = 3 }); - configurationMock.SetupGet(c => c.HashAlgorithm).Returns(new ConfigurationSetting { Value = Constants.DefaultHashAlgorithmName }); - configurationMock.SetupGet(c => c.RootPathFilter).Returns(new ConfigurationSetting { Value = "child1;child2;child3" }); - configurationMock.SetupGet(c => c.IgnoreMissing).Returns(new ConfigurationSetting { Value = false }); - configurationMock.SetupGet(c => c.ManifestToolAction).Returns(ManifestToolActions.Validate); - configurationMock.SetupGet(c => c.FollowSymlinks).Returns(new ConfigurationSetting { Value = true }); - configurationMock.SetupGet(c => c.ValidateSignature).Returns(new ConfigurationSetting { Value = true }); - configurationMock.SetupGet(c => c.ManifestInfo).Returns(new ConfigurationSetting> - { - Value = new List() { Constants.SPDX22ManifestInfo } - }); - - ISbomConfig sbomConfig = new SbomConfig(fileSystemMock.Object) - { - ManifestInfo = Constants.SPDX22ManifestInfo, - ManifestJsonDirPath = "/root/_manifest", - ManifestJsonFilePath = "/root/_manifest/spdx_2.2/manifest.spdx.json", - MetadataBuilder = null, - Recorder = new SbomPackageDetailsRecorder() - }; - sbomConfigs.Setup(c => c.Get(Constants.SPDX22ManifestInfo)).Returns(sbomConfig); - - fileSystemMock.Setup(f => f.OpenRead("/root/_manifest/spdx_2.2/manifest.spdx.json")).Returns(Stream.Null); - fileSystemMock.Setup(f => f.GetRelativePath(It.IsAny(), It.IsAny())) - .Returns((string r, string p) => PathUtils.GetRelativePath(r, p)); - - fileSystemUtilsExtensionMock.Setup(f => f.IsTargetPathInSource(It.IsAny(), It.IsAny())).Returns(true); - - var validationResultGenerator = new ValidationResultGenerator(configurationMock.Object); - - var directoryWalker = new DirectoryWalker(fileSystemMock.Object, mockLogger.Object, configurationMock.Object); - - hashCodeGeneratorMock.Setup(h => h.GenerateHashes( - It.IsAny(), - new AlgorithmName[] { Constants.DefaultHashAlgorithmName })) - .Returns((string fileName, AlgorithmName[] algos) => - new Checksum[] - { - new Checksum - { - ChecksumValue = $"{fileName}hash", - Algorithm = Constants.DefaultHashAlgorithmName - } - }); - - hashCodeGeneratorMock.Setup(h => h.GenerateHashes( - It.Is(a => a == "/root/child2/grandchild1/file10"), - new AlgorithmName[] { Constants.DefaultHashAlgorithmName })) - .Throws(new FileNotFoundException()); - - var fileHasher = new FileHasher( - hashCodeGeneratorMock.Object, - new SbomToolManifestPathConverter(configurationMock.Object, mockOSUtils.Object, fileSystemMock.Object, fileSystemUtilsExtensionMock.Object), - mockLogger.Object, - configurationMock.Object, - new Mock().Object, - new ManifestGeneratorProvider(null), - new FileTypeUtils()); - - var manifestFilterMock = new ManifestFolderFilter(configurationMock.Object, mockOSUtils.Object); - manifestFilterMock.Init(); - var fileFilterer = new ManifestFolderFilterer(manifestFilterMock, mockLogger.Object); - - var rootFileFilterMock = new DownloadedRootPathFilter(configurationMock.Object, fileSystemMock.Object, mockLogger.Object); - rootFileFilterMock.Init(); - - var osUtilsMock = new Mock(MockBehavior.Strict); - osUtilsMock.Setup(x => x.IsCaseSensitiveOS()).Returns(false); - - var hashValidator = new ConcurrentSha256HashValidator(FileHashesDictionarySingleton.Instance); - var enumeratorChannel = new EnumeratorChannel(mockLogger.Object); - var fileConverter = new SbomFileToFileInfoConverter(new FileTypeUtils()); - var spdxFileFilterer = new FileFilterer(rootFileFilterMock, mockLogger.Object, configurationMock.Object, fileSystemMock.Object); - - var filesValidator = new FilesValidator( - directoryWalker, - configurationMock.Object, - mockLogger.Object, - fileHasher, - fileFilterer, - hashValidator, - enumeratorChannel, - fileConverter, - FileHashesDictionarySingleton.Instance, - spdxFileFilterer); - - var validator = new SbomParserBasedValidationWorkflow( - recorder.Object, - signValidationProviderMock.Object, - mockLogger.Object, - manifestParserProvider.Object, - configurationMock.Object, - sbomConfigs.Object, - filesValidator, - validationResultGenerator, - outputWriterMock.Object, - fileSystemMock.Object, - osUtilsMock.Object); - - var cc = new ConsoleCapture(); - - try - { - var result = await validator.RunAsync(); - Assert.IsFalse(result); - } - finally - { - cc.Restore(); - } - - var nodeValidationResults = validationResultGenerator.NodeValidationResults; - - var additionalFileErrors = nodeValidationResults.Where(a => a.ErrorType == ErrorType.AdditionalFile).ToList(); - Assert.AreEqual(1, additionalFileErrors.Count); - Assert.AreEqual("./child2/grandchild1/file7", additionalFileErrors.First().Path); - - var missingFileErrors = nodeValidationResults.Where(a => a.ErrorType == ErrorType.MissingFile).ToList(); - Assert.AreEqual(1, missingFileErrors.Count); - Assert.AreEqual("./child2/grandchild2/file10", missingFileErrors.First().Path); - - var invalidHashErrors = nodeValidationResults.Where(a => a.ErrorType == ErrorType.InvalidHash).ToList(); - Assert.AreEqual(1, invalidHashErrors.Count); - Assert.AreEqual("./child2/grandchild1/file9", invalidHashErrors.First().Path); - - var otherErrors = nodeValidationResults.Where(a => a.ErrorType == ErrorType.Other).ToList(); - Assert.AreEqual(1, otherErrors.Count); - Assert.AreEqual("./child2/grandchild1/file10", otherErrors.First().Path); - - Assert.IsTrue(cc.CapturedStdOut.Contains(CaseSensitiveMessageMarker), "Case-sensitive marker should have been output"); - - configurationMock.VerifyAll(); - signValidatorMock.VerifyAll(); - fileSystemMock.VerifyAll(); - osUtilsMock.VerifyAll(); - } -} diff --git a/test/Microsoft.Sbom.Api.Tests/Workflows/SbomRedactionWorkflowTests.cs b/test/Microsoft.Sbom.Api.Tests/Workflows/SbomRedactionWorkflowTests.cs deleted file mode 100644 index 6adbb463..00000000 --- a/test/Microsoft.Sbom.Api.Tests/Workflows/SbomRedactionWorkflowTests.cs +++ /dev/null @@ -1,159 +0,0 @@ -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. - -using System; -using System.IO; -using System.Text; -using System.Threading.Tasks; -using Microsoft.Sbom.Api.FormatValidator; -using Microsoft.Sbom.Api.Workflows; -using Microsoft.Sbom.Api.Workflows.Helpers; -using Microsoft.Sbom.Common; -using Microsoft.Sbom.Common.Config; -using Microsoft.Sbom.Parsers.Spdx22SbomParser.Entities; -using Microsoft.VisualStudio.TestTools.UnitTesting; -using Moq; -using PowerArgs; -using Serilog; - -namespace Microsoft.Sbom.Workflows; - -#nullable enable - -[TestClass] -public class SbomRedactionWorkflowTests -{ - private Mock mockLogger; - private Mock configurationMock; - private Mock fileSystemUtilsMock; - private Mock validatedSBOMFactoryMock; - private Mock sbomRedactorMock; - private SbomRedactionWorkflow testSubject; - - private const string SbomPathStub = "sbom-path"; - private const string SbomDirStub = "sbom-dir"; - private const string OutDirStub = "out-dir"; - private const string OutPathStub = "out-path"; - private const string SbomFileNameStub = "sbom-name"; - - [TestInitialize] - public void Init() - { - mockLogger = new Mock(); - configurationMock = new Mock(); - fileSystemUtilsMock = new Mock(); - validatedSBOMFactoryMock = new Mock(); - sbomRedactorMock = new Mock(); - testSubject = new SbomRedactionWorkflow( - mockLogger.Object, - configurationMock.Object, - fileSystemUtilsMock.Object, - validatedSBOMFactoryMock.Object, - sbomRedactorMock.Object); - } - - [TestCleanup] - public void Reset() - { - mockLogger.VerifyAll(); - fileSystemUtilsMock.VerifyAll(); - configurationMock.VerifyAll(); - validatedSBOMFactoryMock.VerifyAll(); - sbomRedactorMock.VerifyAll(); - } - - [TestMethod] - public async Task SbomRedactionWorkflow_FailsOnNoSbomsProvided() - { - await Assert.ThrowsExceptionAsync(testSubject.RunAsync); - } - - [TestMethod] - public async Task SbomRedactionWorkflow_FailsOnMatchingInputOutputDirs() - { - configurationMock.SetupGet(c => c.SbomDir).Returns(new ConfigurationSetting { Value = SbomDirStub }); - configurationMock.SetupGet(c => c.OutputPath).Returns(new ConfigurationSetting { Value = SbomDirStub }); - fileSystemUtilsMock.Setup(m => m.DirectoryExists(SbomDirStub)).Returns(true).Verifiable(); - fileSystemUtilsMock.Setup(m => m.GetFullPath(SbomDirStub)).Returns(SbomDirStub).Verifiable(); - await Assert.ThrowsExceptionAsync(testSubject.RunAsync); - } - - [TestMethod] - public async Task SbomRedactionWorkflow_FailsOnExistingOutputSbom() - { - configurationMock.SetupGet(c => c.SbomPath).Returns(new ConfigurationSetting { Value = SbomPathStub }); - configurationMock.SetupGet(c => c.OutputPath).Returns(new ConfigurationSetting { Value = OutDirStub }); - fileSystemUtilsMock.Setup(m => m.FileExists(SbomPathStub)).Returns(true).Verifiable(); - fileSystemUtilsMock.Setup(m => m.GetDirectoryName(SbomPathStub)).Returns(SbomDirStub).Verifiable(); - fileSystemUtilsMock.Setup(m => m.DirectoryExists(OutDirStub)).Returns(true).Verifiable(); - fileSystemUtilsMock.Setup(m => m.GetFullPath(SbomDirStub)).Returns(SbomDirStub).Verifiable(); - fileSystemUtilsMock.Setup(m => m.GetFullPath(OutDirStub)).Returns(OutDirStub).Verifiable(); - - // GetOutputPath - fileSystemUtilsMock.Setup(m => m.GetFileName(SbomPathStub)).Returns(SbomFileNameStub).Verifiable(); - fileSystemUtilsMock.Setup(m => m.JoinPaths(OutDirStub, SbomFileNameStub)).Returns(OutPathStub).Verifiable(); - - // Output already file exists - fileSystemUtilsMock.Setup(m => m.FileExists(OutPathStub)).Returns(true).Verifiable(); - - await Assert.ThrowsExceptionAsync(testSubject.RunAsync); - } - - [TestMethod] - public async Task SbomRedactionWorkflow_FailsOnInvalidSboms() - { - SetUpDirStructure(); - - fileSystemUtilsMock.Setup(m => m.GetFilesInDirectory(SbomDirStub, true)).Returns(new string[] { SbomPathStub }).Verifiable(); - var validatedSbomMock = new Mock(); - validatedSBOMFactoryMock.Setup(m => m.CreateValidatedSBOM(SbomPathStub)).Returns(validatedSbomMock.Object).Verifiable(); - var validationRes = new FormatValidationResults(); - validationRes.AggregateValidationStatus(FormatValidationStatus.NotValid); - validatedSbomMock.Setup(m => m.GetValidationResults()).ReturnsAsync(validationRes).Verifiable(); - validatedSbomMock.Setup(m => m.Dispose()).Verifiable(); - - await Assert.ThrowsExceptionAsync(testSubject.RunAsync); - } - - [TestMethod] - public async Task SbomRedactionWorkflow_RunsRedactionOnValidSboms() - { - SetUpDirStructure(); - - fileSystemUtilsMock.Setup(m => m.GetFilesInDirectory(SbomDirStub, true)).Returns(new string[] { SbomPathStub }).Verifiable(); - var validatedSbomMock = new Mock(); - validatedSBOMFactoryMock.Setup(m => m.CreateValidatedSBOM(SbomPathStub)).Returns(validatedSbomMock.Object).Verifiable(); - var validationRes = new FormatValidationResults(); - validationRes.AggregateValidationStatus(FormatValidationStatus.Valid); - validatedSbomMock.Setup(m => m.GetValidationResults()).ReturnsAsync(validationRes).Verifiable(); - var redactedContent = new FormatEnforcedSPDX2() { Name = "redacted" }; - sbomRedactorMock.Setup(m => m.RedactSBOMAsync(validatedSbomMock.Object)).ReturnsAsync(redactedContent).Verifiable(); - var outStream = new MemoryStream(); - fileSystemUtilsMock.Setup(m => m.OpenWrite(OutPathStub)).Returns(outStream).Verifiable(); - validatedSbomMock.Setup(m => m.Dispose()).Verifiable(); - - var result = await testSubject.RunAsync(); - Assert.IsTrue(result); - var redactedResult = Encoding.ASCII.GetString(outStream.ToArray()); - Assert.IsTrue(redactedResult.Contains(@"""name"":""redacted""")); - } - - private void SetUpDirStructure() - { - configurationMock.SetupGet(c => c.SbomDir).Returns(new ConfigurationSetting { Value = SbomDirStub }); - configurationMock.SetupGet(c => c.OutputPath).Returns(new ConfigurationSetting { Value = OutDirStub }); - fileSystemUtilsMock.Setup(m => m.DirectoryExists(SbomDirStub)).Returns(true).Verifiable(); - fileSystemUtilsMock.Setup(m => m.DirectoryExists(OutDirStub)).Returns(true).Verifiable(); - fileSystemUtilsMock.Setup(m => m.GetFullPath(SbomDirStub)).Returns(SbomDirStub).Verifiable(); - fileSystemUtilsMock.Setup(m => m.GetFullPath(OutDirStub)).Returns(OutDirStub).Verifiable(); - - // GetOutputPath - fileSystemUtilsMock.Setup(m => m.GetFileName(SbomPathStub)).Returns(SbomFileNameStub).Verifiable(); - fileSystemUtilsMock.Setup(m => m.JoinPaths(OutDirStub, SbomFileNameStub)).Returns(OutPathStub).Verifiable(); - - // Output already file exists - fileSystemUtilsMock.Setup(m => m.FileExists(OutPathStub)).Returns(false).Verifiable(); - } -} diff --git a/test/Microsoft.Sbom.Api.Tests/Workflows/ValidationWorkflowTestsBase.cs b/test/Microsoft.Sbom.Api.Tests/Workflows/ValidationWorkflowTestsBase.cs deleted file mode 100644 index 9dd51595..00000000 --- a/test/Microsoft.Sbom.Api.Tests/Workflows/ValidationWorkflowTestsBase.cs +++ /dev/null @@ -1,76 +0,0 @@ -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -using System; -using System.Collections.Concurrent; -using System.Collections.Generic; -using System.Linq; -using Microsoft.Sbom.Common; -using Microsoft.Sbom.Contracts.Enums; -using Microsoft.Sbom.Extensions.Entities; -using Microsoft.Sbom.Parsers.Spdx22SbomParser.Entities; -using Moq; -using SbomChecksum = Microsoft.Sbom.Contracts.Checksum; -using SpdxChecksum = Microsoft.Sbom.Parsers.Spdx22SbomParser.Entities.Checksum; - -namespace Microsoft.Sbom.Workflows; - -public class ValidationWorkflowTestsBase -{ - protected static Mock GetDefaultFileSystemMock() - { - var fileSystemMock = new Mock(); - fileSystemMock.Setup(f => f.DirectoryExists(It.IsAny())).Returns(true); - fileSystemMock.Setup(f => f.GetDirectories(It.Is(c => c == "/root"), true)).Returns(new string[] { "child1", "child2", "child3", "_manifest" }); - fileSystemMock.Setup(f => f.GetDirectories(It.Is(c => c == "child1"), true)).Returns(new string[] { }); - fileSystemMock.Setup(f => f.GetDirectories(It.Is(c => c == "child2"), true)).Returns(new string[] { "grandchild1", "grandchild2" }); - - // File2 is cased differently than in GetFilesDictionary() to test case insensitivity. - fileSystemMock.Setup(f => f.GetFilesInDirectory(It.Is(c => c == "child1"), true)).Returns(new string[] { "/root/child1/file1", "/root/child1/File2" }); - fileSystemMock.Setup(f => f.GetFilesInDirectory(It.Is(c => c == "child2"), true)).Returns(new string[] { "/root/child2/file3", "/root/child2/file4", "/root/child2/file5" }); - fileSystemMock.Setup(f => f.GetFilesInDirectory(It.Is(c => c == "child3"), true)).Returns(new string[] { "/root/child3/file11", "/root/child3/file12" }); - fileSystemMock.Setup(f => f.GetFilesInDirectory(It.Is(c => c == "_manifest"), true)).Returns(new string[] { "/root/_manifest/manifest.json", "/root/_manifest/manifest.cat" }); - - fileSystemMock.Setup(f => f.GetFilesInDirectory(It.Is(c => c == "grandchild1"), true)).Returns(new string[] { "/root/child2/grandchild1/file6", "/root/child2/grandchild1/file10" }); - fileSystemMock.Setup(f => f.GetFilesInDirectory(It.Is(c => c == "grandchild2"), true)).Returns(new string[] { "/root/child2/grandchild1/file7", "/root/child2/grandchild1/file9" }); - fileSystemMock.Setup(f => f.JoinPaths(It.IsAny(), It.IsAny())).Returns((string r, string p) => $"{r}/{p}"); - - return fileSystemMock; - } - - protected IDictionary GetSpdxFilesDictionary() => new Dictionary - { - ["/child1/file1"] = new SpdxChecksum[] { new SpdxChecksum { Algorithm = AlgorithmName.SHA256.Name, ChecksumValue = "/root/child1/file1hash" } }, - ["/child1/file2"] = new SpdxChecksum[] { new SpdxChecksum { Algorithm = AlgorithmName.SHA256.Name, ChecksumValue = "/root/child1/file2hash" } }, - ["/child2/file3"] = new SpdxChecksum[] { new SpdxChecksum { Algorithm = AlgorithmName.SHA256.Name, ChecksumValue = "/root/child2/file3hash" } }, - ["/child2/file4"] = new SpdxChecksum[] { new SpdxChecksum { Algorithm = AlgorithmName.SHA256.Name, ChecksumValue = "/root/child2/file4hash" } }, - ["/child2/file5"] = new SpdxChecksum[] { new SpdxChecksum { Algorithm = AlgorithmName.SHA256.Name, ChecksumValue = "/root/child2/file5hash" } }, - ["/child3/file11"] = new SpdxChecksum[] { new SpdxChecksum { Algorithm = AlgorithmName.SHA256.Name, ChecksumValue = "/root/child3/file11hash" } }, - ["/child3/file12"] = new SpdxChecksum[] { new SpdxChecksum { Algorithm = AlgorithmName.SHA256.Name, ChecksumValue = "/root/child3/file12hash" } }, - ["/child2/grandchild1/file6"] = new SpdxChecksum[] { new SpdxChecksum { Algorithm = AlgorithmName.SHA256.Name, ChecksumValue = "/root/child2/grandchild1/file6hash" } }, - ["/child5/file8"] = new SpdxChecksum[] { new SpdxChecksum { Algorithm = AlgorithmName.SHA256.Name, ChecksumValue = "/root/child5/file8hash" } }, - ["/child2/grandchild1/file9"] = new SpdxChecksum[] { new SpdxChecksum { Algorithm = AlgorithmName.SHA256.Name, ChecksumValue = "incorrectHash" } }, - ["/child2/grandchild2/file10"] = new SpdxChecksum[] { new SpdxChecksum { Algorithm = AlgorithmName.SHA256.Name, ChecksumValue = "missingfile" } } - }; - - protected IDictionary GetSbomFilesDictionary() - { - var spdxDict = GetSpdxFilesDictionary(); - - return spdxDict.ToDictionary( - kvp => kvp.Key, - kvp => kvp.Value.Select(v => new SbomChecksum { Algorithm = AlgorithmName.FromString(v.Algorithm), ChecksumValue = v.ChecksumValue }).ToArray()); - } - - protected ManifestData GetDefaultManifestData() => new() - { - HashesMap = new ConcurrentDictionary(GetSbomFilesDictionary(), StringComparer.InvariantCultureIgnoreCase) - }; - - protected IEnumerable GetSpdxFiles(IDictionary dictionary) => dictionary - .Select(file => new SPDXFile - { - FileName = $".{file.Key}", // Prepend . - FileChecksums = file.Value.ToList(), - }); -} diff --git a/test/Microsoft.Sbom.Extensions.DependencyInjection.Tests/Microsoft.Sbom.Extensions.DependencyInjection.Tests.csproj b/test/Microsoft.Sbom.Extensions.DependencyInjection.Tests/Microsoft.Sbom.Extensions.DependencyInjection.Tests.csproj deleted file mode 100644 index 78dd7d6e..00000000 --- a/test/Microsoft.Sbom.Extensions.DependencyInjection.Tests/Microsoft.Sbom.Extensions.DependencyInjection.Tests.csproj +++ /dev/null @@ -1,22 +0,0 @@ - - - - false - True - Microsoft.Sbom.DependencyInjection.Tests - $(StrongNameSigningKeyFilePath) - - - - TRACE - - - - - - - - - - - diff --git a/test/Microsoft.Sbom.Extensions.DependencyInjection.Tests/RemapComponentDetectionErrorsToWarningsLoggerTests.cs b/test/Microsoft.Sbom.Extensions.DependencyInjection.Tests/RemapComponentDetectionErrorsToWarningsLoggerTests.cs deleted file mode 100644 index e847a149..00000000 --- a/test/Microsoft.Sbom.Extensions.DependencyInjection.Tests/RemapComponentDetectionErrorsToWarningsLoggerTests.cs +++ /dev/null @@ -1,162 +0,0 @@ -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using Microsoft.VisualStudio.TestTools.UnitTesting; -using Moq; -using Serilog; -using Serilog.Events; -using Serilog.Parsing; - -namespace Microsoft.Sbom.Extensions.DependencyInjection.Tests; - -[TestClass] -public class RemapComponentDetectionErrorsToWarningsLoggerTests -{ - private const string TestPropertyKey = "TestPropertyKey"; - - private Mock loggerMock; - private Func stackTraceProvider; - private ILogger testSubject; - private int testStackTraceCount; - private string? testStackTraceReturnValue; - - // We need a concrete implementation of MessageTemplateToken - internal class TestMessageTemplateToken : MessageTemplateToken - { - public override int Length => throw new NotImplementedException(); - - public override void Render(IReadOnlyDictionary properties, TextWriter output, IFormatProvider formatProvider = null) => throw new NotImplementedException(); - } - - // We need a concrete implementation of LogEventPropertyValue - internal class TestLogEventPropertyValue : LogEventPropertyValue - { - public override void Render(TextWriter output, string format = null, IFormatProvider formatProvider = null) => throw new NotImplementedException(); - } - - [TestInitialize] - public void TestInit() - { - loggerMock = new Mock(MockBehavior.Strict); - stackTraceProvider = TestGetStackTrace; - testStackTraceCount = 0; - testStackTraceReturnValue = null; - testSubject = new RemapComponentDetectionErrorsToWarningsLogger(loggerMock.Object, stackTraceProvider); - } - - [TestCleanup] - public void TestCleanup() - { - loggerMock.VerifyAll(); - } - - [TestMethod] - public void Constructor_LoggerIsNull_ThrowsNullArgumentException() - { - Assert.ThrowsException(() => new RemapComponentDetectionErrorsToWarningsLogger(null, stackTraceProvider)); - } - - [TestMethod] - public void Constructor_StackTraceProviderIsNull_ThrowsNullArgumentException() - { - Assert.ThrowsException(() => new RemapComponentDetectionErrorsToWarningsLogger(loggerMock.Object, null)); - } - - [TestMethod] - public void Write_LogEventLevelIsNotError_DoesNotCallStackTraceProvider_LogsEventAsSpecified() - { - var nonErrorLevels = Enum.GetValues(typeof(LogEventLevel)).Cast().Where((x) => x != LogEventLevel.Error); - foreach (var level in nonErrorLevels) - { - var logEvent = GetLogEvent(level); - loggerMock.Setup(x => x.Write(logEvent)).Verifiable(); - - testSubject.Write(logEvent); - - Assert.AreEqual(0, testStackTraceCount); - - // The VerifyAll and Reset calls are needed here because we need to confirm them for _each iteration_ of the loop. - loggerMock.VerifyAll(); - loggerMock.Reset(); - } - } - - [TestMethod] - public void Write_LogEventLevelIsError_StackTraceReturnsNull_LogsEventAsSpecified() - { - var logEvent = GetLogEvent(LogEventLevel.Error); - loggerMock.Setup(x => x.Write(logEvent)).Verifiable(); - - testSubject.Write(logEvent); - - Assert.AreEqual(1, testStackTraceCount); - } - - [TestMethod] - public void Write_LogEventLevelIsError_UsesDefaultStackTraceProvider_LogsEventAsSpecified() - { - var logEvent = GetLogEvent(LogEventLevel.Error); - loggerMock.Setup(x => x.Write(logEvent)).Verifiable(); - - // Use the production constructor here to force use of the default StackTraceProvider - new RemapComponentDetectionErrorsToWarningsLogger(loggerMock.Object).Write(logEvent); - - Assert.AreEqual(0, testStackTraceCount); - } - - [TestMethod] - public void Write_LogEventLevelIsError_StackTraceDoesNotContainComponentDetection_LogsEventAsSpecified() - { - var logEvent = GetLogEvent(LogEventLevel.Error); - loggerMock.Setup(x => x.Write(logEvent)).Verifiable(); - testStackTraceReturnValue = "at Microsoft.Sbom.Foo.Bar"; - - testSubject.Write(logEvent); - - Assert.AreEqual(1, testStackTraceCount); - } - - [TestMethod] - public void Write_LogEventLevelIsError_StackTraceContainsComponentDetection_LogsEventAsWarning() - { - LogEvent actualEvent = null; - var logEvent = GetLogEvent(LogEventLevel.Error); - loggerMock.Setup(x => x.Write(It.IsAny())).Callback((l) => actualEvent = l).Verifiable(); - testStackTraceReturnValue = "at Microsoft.ComponentDetection.Foo.Bar"; - - testSubject.Write(logEvent); - - Assert.AreEqual(1, testStackTraceCount); - - // Ensure that the LogEvent was correctly copied. Only the Level should be different - Assert.AreEqual(LogEventLevel.Warning, actualEvent.Level); - Assert.AreEqual(logEvent.Timestamp, actualEvent.Timestamp); - Assert.AreSame(logEvent.MessageTemplate, actualEvent.MessageTemplate); - Assert.AreEqual(logEvent.Properties.Count, actualEvent.Properties.Count); - Assert.AreEqual(1, actualEvent.Properties.Count); - Assert.IsInstanceOfType(logEvent.Properties[TestPropertyKey], typeof(TestLogEventPropertyValue)); - Assert.AreSame(logEvent.Properties[TestPropertyKey], actualEvent.Properties[TestPropertyKey]); - } - - // A helper function to return a LogEvent with the specified LogEventLevel - private LogEvent GetLogEvent(LogEventLevel logEventLevel) - { - return new LogEvent( - DateTimeOffset.Now, - logEventLevel, - null, - new MessageTemplate(new List { new TestMessageTemplateToken() }), - new LogEventProperty[1] { new LogEventProperty(TestPropertyKey, new TestLogEventPropertyValue()) }); - } - - // A helper function to allow us to easily test the StackTraceProvider functionality - private string TestGetStackTrace() - { - testStackTraceCount++; - return testStackTraceReturnValue; - } -} diff --git a/test/Microsoft.Sbom.Parsers.Spdx22SbomParser.Tests/Microsoft.Sbom.Parsers.Spdx22SbomParser.Tests.csproj b/test/Microsoft.Sbom.Parsers.Spdx22SbomParser.Tests/Microsoft.Sbom.Parsers.Spdx22SbomParser.Tests.csproj deleted file mode 100644 index 1d728eea..00000000 --- a/test/Microsoft.Sbom.Parsers.Spdx22SbomParser.Tests/Microsoft.Sbom.Parsers.Spdx22SbomParser.Tests.csproj +++ /dev/null @@ -1,15 +0,0 @@ - - - - false - $(NoWarn);NU1605 - Microsoft.Sbom.Parsers.Spdx22SbomParser.Tests - True - $(StrongNameSigningKeyFilePath) - - - - - - - diff --git a/test/Microsoft.Sbom.Parsers.Spdx22SbomParser.Tests/Parser/GeneratorTests.cs b/test/Microsoft.Sbom.Parsers.Spdx22SbomParser.Tests/Parser/GeneratorTests.cs deleted file mode 100644 index 5bdffb66..00000000 --- a/test/Microsoft.Sbom.Parsers.Spdx22SbomParser.Tests/Parser/GeneratorTests.cs +++ /dev/null @@ -1,52 +0,0 @@ -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -using Microsoft.Sbom.Contracts; -using Microsoft.Sbom.Parsers.Spdx22SbomParser; -using Microsoft.VisualStudio.TestTools.UnitTesting; - -namespace Microsoft.Sbom.Parser; - -[TestClass] -public class GeneratorTests -{ - [TestMethod] - public void GenerateJsonDocumentTest_FilesAnalyzed_IsFalse() - { - var generator = new Generator(); - - const string PackageUrl = "packageUrl"; - var packageInfo = new SbomPackage - { - PackageName = "test", - PackageUrl = PackageUrl, - FilesAnalyzed = false - }; - - var result = generator.GenerateJsonDocument(packageInfo); - var propertyExists = result.Document.RootElement.TryGetProperty("licenseInfoFromFiles", out var property); - - Assert.IsFalse(propertyExists); - } - - [TestMethod] - public void GenerateJsonDocumentTest_FilesAnalyzed_IsTrue() - { - var generator = new Generator(); - var expected = "[\"NOASSERTION\"]"; - - const string PackageUrl = "packageUrl"; - var packageInfo = new SbomPackage - { - PackageName = "test", - PackageUrl = PackageUrl, - FilesAnalyzed = true - }; - - var result = generator.GenerateJsonDocument(packageInfo); - var propertyExists = result.Document.RootElement.TryGetProperty("licenseInfoFromFiles", out var property); - - Assert.IsTrue(propertyExists); - Assert.AreEqual(expected.ToString(), property.ToString()); - } -} diff --git a/test/Microsoft.Sbom.Parsers.Spdx22SbomParser.Tests/Parser/LargeJsonParserTests.cs b/test/Microsoft.Sbom.Parsers.Spdx22SbomParser.Tests/Parser/LargeJsonParserTests.cs deleted file mode 100644 index cee2de2b..00000000 --- a/test/Microsoft.Sbom.Parsers.Spdx22SbomParser.Tests/Parser/LargeJsonParserTests.cs +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -using System.Collections; -using System.IO; -using System.Text; -using Microsoft.Sbom.JsonAsynchronousNodeKit.Exceptions; -using Microsoft.Sbom.Parser.Strings; -using Microsoft.VisualStudio.TestTools.UnitTesting; - -namespace Microsoft.Sbom.Parser; - -[TestClass] -public class LargeJsonParserTests -{ - [TestMethod] - public void LargeJsonParser_RequiresFullEnumeration() - { - var bytes = Encoding.UTF8.GetBytes(SbomPackageStrings.GoodJsonWith3PackagesString); - using var stream = new MemoryStream(bytes); - - var parser = new SPDXParser(stream); - - var result = parser.Next(); - Assert.AreEqual(SPDXParser.PackagesProperty, result.FieldName); - if (result.Result is IEnumerable enumerable) - { - Assert.IsNotNull(enumerable); - Assert.IsTrue(enumerable.GetEnumerator().MoveNext()); - - _ = Assert.ThrowsException(parser.Next); - } - else - { - Assert.Fail(); - } - } -} diff --git a/test/Microsoft.Sbom.Parsers.Spdx22SbomParser.Tests/Parser/ParserResults.cs b/test/Microsoft.Sbom.Parsers.Spdx22SbomParser.Tests/Parser/ParserResults.cs deleted file mode 100644 index 16309994..00000000 --- a/test/Microsoft.Sbom.Parsers.Spdx22SbomParser.Tests/Parser/ParserResults.cs +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -namespace Microsoft.Sbom.Parser; - -using System.Collections.Generic; -using Microsoft.Sbom.Parsers.Spdx22SbomParser.Entities; - -public class ParserResults -{ - public IEnumerable? Files { get; set; } - - public IEnumerable? Packages { get; set; } - - public IEnumerable? References { get; set; } - - public IEnumerable? Relationships { get; set; } - - public int? FilesCount = null; - public int? PackagesCount = null; - public int? ReferencesCount = null; - public int? RelationshipsCount = null; -} diff --git a/test/Microsoft.Sbom.Parsers.Spdx22SbomParser.Tests/Parser/SbomFileParserTests.cs b/test/Microsoft.Sbom.Parsers.Spdx22SbomParser.Tests/Parser/SbomFileParserTests.cs deleted file mode 100644 index 8ff7ea64..00000000 --- a/test/Microsoft.Sbom.Parsers.Spdx22SbomParser.Tests/Parser/SbomFileParserTests.cs +++ /dev/null @@ -1,173 +0,0 @@ -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -using System; -using System.IO; -using System.Linq; -using System.Text; -using Microsoft.Sbom.JsonAsynchronousNodeKit.Exceptions; -using Microsoft.Sbom.Parser.Strings; -using Microsoft.Sbom.Parsers.Spdx22SbomParser; -using Microsoft.Sbom.Utils; -using Microsoft.VisualStudio.TestTools.UnitTesting; - -namespace Microsoft.Sbom.Parser; - -[TestClass] -public class SbomFileParserTests : SbomParserTestsBase -{ - [TestMethod] - public void SkipSbomFilesTest() - { - var bytes = Encoding.UTF8.GetBytes(SbomFileJsonStrings.GoodJsonWith2FilesString); - using var stream = new MemoryStream(bytes); - var skippedProperties = new[] { "files" }; - - var parser = new SPDXParser(stream, skippedProperties: skippedProperties); - - var results = this.Parse(parser); - Assert.IsNull(results.FilesCount); - } - - [TestMethod] - public void MetadataPopulates() - { - var bytes = Encoding.UTF8.GetBytes(SbomFileJsonStrings.GoodJsonWith2FilesString); - using var stream = new MemoryStream(bytes); - - var parser = new SPDXParser(stream); - - var results = this.Parse(parser); - var metadata = parser.GetMetadata(); - - Assert.IsNotNull(metadata); - Assert.IsNotNull(metadata.CreationInfo); - var expectedTime = DateTime.Parse("2023-05-11T00:24:54Z").ToUniversalTime(); - Assert.AreEqual(expectedTime, metadata.CreationInfo.Created); - } - - [TestMethod] - public void ParseSbomFilesTest() - { - var bytes = Encoding.UTF8.GetBytes(SbomFileJsonStrings.GoodJsonWith2FilesString); - using var stream = new MemoryStream(bytes); - - var parser = new SPDXParser(stream); - - var results = this.Parse(parser); - - Assert.AreEqual(2, results.FilesCount); - } - - [TestMethod] - public void NullStreamThrows() - { - _ = Assert.ThrowsException(() => new SPDXParser(null)); - } - - [TestMethod] - public void StreamClosedTestReturnsNull() - { - var bytes = Encoding.UTF8.GetBytes(SbomFileJsonStrings.GoodJsonWith2FilesString); - using var stream = new MemoryStream(bytes); - - var parser = new SPDXParser(stream); - - Assert.ThrowsException(() => this.Parse(parser, stream, close: true)); - } - - [TestMethod] - public void StreamEmptyTestReturnsNull() - { - using var stream = new MemoryStream(); - stream.Read(new byte[Constants.ReadBufferSize]); - var buffer = new byte[Constants.ReadBufferSize]; - - Assert.ThrowsException(() => new SPDXParser(stream)); - } - - [TestMethod] - public void MissingPropertiesTest_ThrowsSHA256() - { - var bytes = Encoding.UTF8.GetBytes(SbomFileJsonStrings.JsonWith1FileMissingSHA256ChecksumsString); - using var stream = new MemoryStream(bytes); - - var parser = new SPDXParser(stream); - - var result = this.Parse(parser); - Assert.IsNotNull(result); - - Assert.ThrowsException(() => result.Files.Select(f => f.ToSbomFile()).ToList()); - } - - [DataTestMethod] - [DataRow(SbomFileJsonStrings.JsonWith1FileMissingNameString)] - [DataRow(SbomFileJsonStrings.JsonWith1FileMissingIDString)] - [DataRow(SbomFileJsonStrings.JsonWith1FileMissingChecksumsString)] - [DataRow(SbomFileJsonStrings.JsonWith1FileMissingCopyrightAndPathString)] - [TestMethod] - public void MissingPropertiesTest_Throws(string json) - { - var bytes = Encoding.UTF8.GetBytes(json); - using var stream = new MemoryStream(bytes); - - var parser = new SPDXParser(stream); - - _ = Assert.ThrowsException(() => this.Parse(parser)); - } - - [DataTestMethod] - [DataRow(SbomFileJsonStrings.GoodJsonWith1FileAdditionalObjectPropertyString)] - [DataRow(SbomFileJsonStrings.GoodJsonWith1FileAdditionalArrayPropertyString)] - [DataRow(SbomFileJsonStrings.GoodJsonWith1FileAdditionalStringPropertyString)] - [DataRow(SbomFileJsonStrings.GoodJsonWith1FileAdditionalValueArrayPropertyString)] - [TestMethod] - public void IgnoresAdditionalPropertiesTest(string json) - { - var bytes = Encoding.UTF8.GetBytes(json); - using var stream = new MemoryStream(bytes); - - var parser = new SPDXParser(stream); - - var result = this.Parse(parser); - - Assert.AreEqual(1, result.FilesCount); - } - - [DataTestMethod] - [DataRow(SbomFileJsonStrings.MalformedJson)] - [DataRow(SbomFileJsonStrings.MalformedJsonEmptyObject)] - [DataRow(SbomFileJsonStrings.MalformedJsonEmptyObjectNoArrayEnd)] - [TestMethod] - public void MalformedJsonTest_Throws(string json) - { - var bytes = Encoding.UTF8.GetBytes(json); - using var stream = new MemoryStream(bytes); - - var parser = new SPDXParser(stream); - - Assert.ThrowsException(() => this.Parse(parser)); - } - - [TestMethod] - public void EmptyArray_ValidJson() - { - var bytes = Encoding.UTF8.GetBytes(SbomFileJsonStrings.JsonEmptyArray); - using var stream = new MemoryStream(bytes); - - var parser = new SPDXParser(stream); - - var result = this.Parse(parser); - - Assert.AreEqual(0, result.FilesCount); - } - - [TestMethod] - public void NullOrEmptyBuffer_Throws() - { - var bytes = Encoding.UTF8.GetBytes(SbomFileJsonStrings.MalformedJson); - using var stream = new MemoryStream(bytes); - - Assert.ThrowsException(() => new SPDXParser(stream, bufferSize: 0)); - } -} diff --git a/test/Microsoft.Sbom.Parsers.Spdx22SbomParser.Tests/Parser/SbomPackageParserTests.cs b/test/Microsoft.Sbom.Parsers.Spdx22SbomParser.Tests/Parser/SbomPackageParserTests.cs deleted file mode 100644 index 141a5800..00000000 --- a/test/Microsoft.Sbom.Parsers.Spdx22SbomParser.Tests/Parser/SbomPackageParserTests.cs +++ /dev/null @@ -1,135 +0,0 @@ -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -using System; -using System.IO; -using System.Text; -using Microsoft.Sbom.JsonAsynchronousNodeKit.Exceptions; -using Microsoft.Sbom.Parser.Strings; -using Microsoft.Sbom.Parsers.Spdx22SbomParser; -using Microsoft.VisualStudio.TestTools.UnitTesting; - -namespace Microsoft.Sbom.Parser; - -[TestClass] -public class SbomPackageParserTests : SbomParserTestsBase -{ - [TestMethod] - public void ParseSbomPackagesTest() - { - var bytes = Encoding.UTF8.GetBytes(SbomPackageStrings.GoodJsonWith3PackagesString); - using var stream = new MemoryStream(bytes); - - var parser = new SPDXParser(stream); - - var result = this.Parse(parser); - - Assert.AreEqual(3, result.PackagesCount); - } - - [TestMethod] - public void StreamClosedTestReturnsNull() - { - var bytes = Encoding.UTF8.GetBytes(SbomPackageStrings.GoodJsonWith3PackagesString); - using var stream = new MemoryStream(bytes); - - var parser = new SPDXParser(stream); - - Assert.ThrowsException(() => this.Parse(parser, stream, close: true)); - } - - [TestMethod] - public void StreamEmptyTestThrowsException() - { - using var stream = new MemoryStream(); - stream.Read(new byte[Constants.ReadBufferSize]); - var buffer = new byte[Constants.ReadBufferSize]; - - Assert.ThrowsException(() => new SPDXParser(stream)); - } - - [DataTestMethod] - [DataRow(SbomPackageStrings.PackageJsonWith1PackageMissingDownloadLocation)] - [DataRow(SbomPackageStrings.PackageJsonWith1PackageMissingVersionInfo)] - public void MissingPropertiesTest_DoesNotThrow(string json) - { - var bytes = Encoding.UTF8.GetBytes(json); - using var stream = new MemoryStream(bytes); - - var parser = new SPDXParser(stream); - - var result = this.Parse(parser); - } - - [DataTestMethod] - [DataRow(SbomPackageStrings.PackageJsonWith1PackageMissingCopyrightText)] - [DataRow(SbomPackageStrings.PackageJsonWith1PackageMissingLicenseInfoFromFiles)] - [DataRow(SbomPackageStrings.PackageJsonWith1PackageMissingSupplier)] - [DataRow(SbomPackageStrings.PackageJsonWith1PackageMissingId)] - [DataRow(SbomPackageStrings.PackageJsonWith1PackageMissingLicenseConcluded)] - [DataRow(SbomPackageStrings.PackageJsonWith1PackageMissingLicenseDeclared)] - [DataRow(SbomPackageStrings.PackageJsonWith1PackageMissingName)] - [DataRow(SbomPackageStrings.PackageJsonWith1PackageBadReferenceType)] - [DataRow(SbomPackageStrings.PackageJsonWith1PackageMissingReferenceLocator)] - [DataRow(SbomPackageStrings.PackageJsonWith1PackageMissingPackageVerificationCode)] - [DataRow(SbomPackageStrings.PackageJsonWith1PackageFilesAnalyzedTrueAndMissingLicenseInfoFromFiles)] - public void MissingPropertiesTest_Throws(string json) - { - var bytes = Encoding.UTF8.GetBytes(json); - using var stream = new MemoryStream(bytes); - - var parser = new SPDXParser(stream); - - Assert.ThrowsException(() => this.Parse(parser)); - } - - [DataTestMethod] - [DataRow(SbomPackageStrings.PackageJsonWith1PackageAdditionalString)] - [DataRow(SbomPackageStrings.PackageJsonWith1PackageAdditionalArray)] - [DataRow(SbomPackageStrings.PackageJsonWith1PackageAdditionalObject)] - [DataRow(SbomPackageStrings.PackageJsonWith1PackageAdditionalArrayNoKey)] - public void IgnoresAdditionalPropertiesTest(string json) - { - var bytes = Encoding.UTF8.GetBytes(json); - using var stream = new MemoryStream(bytes); - - var parser = new SPDXParser(stream); - - var result = this.Parse(parser); - } - - [DataTestMethod] - [DataRow(SbomPackageStrings.MalformedJson)] - [DataRow(SbomPackageStrings.MalformedJsonEmptyObject)] - [DataRow(SbomPackageStrings.MalformedJsonEmptyObjectNoArrayEnd)] - [TestMethod] - public void MalformedJsonTest_Throws(string json) - { - var bytes = Encoding.UTF8.GetBytes(json); - using var stream = new MemoryStream(bytes); - - var parser = new SPDXParser(stream); - - Assert.ThrowsException(() => this.Parse(parser)); - } - - [TestMethod] - public void EmptyArray_ValidJson() - { - var bytes = Encoding.UTF8.GetBytes(SbomPackageStrings.MalformedJsonEmptyArray); - using var stream = new MemoryStream(bytes); - - var parser = new SPDXParser(stream); - - var result = this.Parse(parser); - } - - [TestMethod] - public void NullOrEmptyBuffer_Throws() - { - var bytes = Encoding.UTF8.GetBytes(SbomFileJsonStrings.MalformedJson); - using var stream = new MemoryStream(bytes); - - Assert.ThrowsException(() => new SPDXParser(stream, bufferSize: 0)); - } -} diff --git a/test/Microsoft.Sbom.Parsers.Spdx22SbomParser.Tests/Parser/SbomParserTests.cs b/test/Microsoft.Sbom.Parsers.Spdx22SbomParser.Tests/Parser/SbomParserTests.cs deleted file mode 100644 index fe1252ba..00000000 --- a/test/Microsoft.Sbom.Parsers.Spdx22SbomParser.Tests/Parser/SbomParserTests.cs +++ /dev/null @@ -1,102 +0,0 @@ -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -using System.IO; -using System.Text; -using Microsoft.Sbom.JsonAsynchronousNodeKit.Exceptions; -using Microsoft.Sbom.Parser.Strings; -using Microsoft.VisualStudio.TestTools.UnitTesting; - -namespace Microsoft.Sbom.Parser; - -[TestClass] -public class SbomParserTests : SbomParserTestsBase -{ - [TestMethod] - public void ParseWithBOMTest() - { - var utf8BOM = Encoding.UTF8.GetString(Encoding.UTF8.Preamble); - var bytes = Encoding.UTF8.GetBytes(utf8BOM + SbomParserStrings.JsonWithAll4Properties); - using var stream = new MemoryStream(bytes); - - var parser = new SPDXParser(stream); - - var result = this.Parse(parser); - - Assert.AreEqual(0, result.FilesCount); - - Assert.AreEqual(0, result.PackagesCount); - - Assert.AreEqual(0, result.RelationshipsCount); - - Assert.AreEqual(0, result.ReferencesCount); - } - - [TestMethod] - public void ParseMultiplePropertiesTest() - { - var bytes = Encoding.UTF8.GetBytes(SbomParserStrings.JsonWithAll4Properties); - using var stream = new MemoryStream(bytes); - - var parser = new SPDXParser(stream); - - var result = this.Parse(parser); - - Assert.AreEqual(0, result.FilesCount); - - Assert.AreEqual(0, result.PackagesCount); - - Assert.AreEqual(0, result.RelationshipsCount); - - Assert.AreEqual(0, result.ReferencesCount); - } - - [DataTestMethod] - [DataRow(SbomParserStrings.JsonWithMissingFiles)] - [DataRow(SbomParserStrings.JsonWithMissingPackages)] - [DataRow(SbomParserStrings.JsonWithMissingRelationships)] - public void MissingPropertyThrows(string json) - { - var bytes = Encoding.UTF8.GetBytes(json); - using var stream = new MemoryStream(bytes); - Assert.ThrowsException(() => this.IterateAllPropertiesAsync(stream)); - } - - [DataTestMethod] - [DataRow(SbomParserStrings.MalformedJson)] - [DataRow(SbomParserStrings.MalformedJsonIncorrectRefsType)] - [DataRow(SbomParserStrings.MalformedJsonIncorrectFilesType)] - [DataRow(SbomParserStrings.MalformedJsonIncorrectPackagesType)] - [DataRow(SbomParserStrings.MalformedJsonIncorrectRelationshipsType)] - public void MalformedJsonThrows(string json) - { - var bytes = Encoding.UTF8.GetBytes(json); - using var stream = new MemoryStream(bytes); - - Assert.ThrowsException(() => this.IterateAllPropertiesAsync(stream)); - } - - [DataTestMethod] - [DataRow(SbomParserStrings.MalformedJsonEmptyJsonObject)] - [DataRow(SbomParserStrings.MalformedJsonEmptyArrayObject)] - public void MalformedJsonEmptyValuesDoesNotThrow(string json) - { - var bytes = Encoding.UTF8.GetBytes(json); - using var stream = new MemoryStream(bytes); - this.IterateAllPropertiesAsync(stream); - } - - [TestMethod] - public void MissingReferencesDoesNotThrow() - { - var bytes = Encoding.UTF8.GetBytes(SbomParserStrings.JsonWithMissingReferences); - using var stream = new MemoryStream(bytes); - this.IterateAllPropertiesAsync(stream); - } - - private ParserResults IterateAllPropertiesAsync(Stream stream) - { - var parser = new SPDXParser(stream); - return this.Parse(parser); - } -} diff --git a/test/Microsoft.Sbom.Parsers.Spdx22SbomParser.Tests/Parser/SbomParserTestsBase.cs b/test/Microsoft.Sbom.Parsers.Spdx22SbomParser.Tests/Parser/SbomParserTestsBase.cs deleted file mode 100644 index 2ef1face..00000000 --- a/test/Microsoft.Sbom.Parsers.Spdx22SbomParser.Tests/Parser/SbomParserTestsBase.cs +++ /dev/null @@ -1,68 +0,0 @@ -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using Microsoft.Sbom.JsonAsynchronousNodeKit; -using Microsoft.Sbom.Parsers.Spdx22SbomParser.Entities; - -namespace Microsoft.Sbom.Parser; - -#nullable enable - -public abstract class SbomParserTestsBase -{ - public ParserResults Parse(SPDXParser parser, Stream? stream = null, bool close = false) - { - var results = new ParserResults(); - - ParserStateResult? result = null; - do - { - result = parser.Next(); - - if (close) - { - if (stream is not null) - { - stream.Close(); - } - else - { - throw new NotImplementedException("Can't close a stream without the stream."); - } - } - - if (result is not null) - { - var enumerable = result.Result as IEnumerable; - var list = enumerable?.ToList(); - var count = list?.Count; - switch (result.FieldName) - { - case SPDXParser.FilesProperty: - results.Files = list?.Cast(); - results.FilesCount = count; - break; - case SPDXParser.PackagesProperty: - results.Packages = list?.Cast(); - results.PackagesCount = count; - break; - case SPDXParser.ReferenceProperty: - results.References = list?.Cast(); - results.ReferencesCount = count; - break; - case SPDXParser.RelationshipsProperty: - results.Relationships = list?.Cast(); - results.RelationshipsCount = count; - break; - } - } - } - while (result is not null); - - return results; - } -} diff --git a/test/Microsoft.Sbom.Parsers.Spdx22SbomParser.Tests/Parser/SbomRelationshipParserTests.cs b/test/Microsoft.Sbom.Parsers.Spdx22SbomParser.Tests/Parser/SbomRelationshipParserTests.cs deleted file mode 100644 index f89c2a63..00000000 --- a/test/Microsoft.Sbom.Parsers.Spdx22SbomParser.Tests/Parser/SbomRelationshipParserTests.cs +++ /dev/null @@ -1,106 +0,0 @@ -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -using System; -using System.IO; -using System.Text; -using Microsoft.Sbom.JsonAsynchronousNodeKit.Exceptions; -using Microsoft.Sbom.Parser.Strings; -using Microsoft.VisualStudio.TestTools.UnitTesting; -using SbomConstants = Microsoft.Sbom.Parsers.Spdx22SbomParser.Constants; - -namespace Microsoft.Sbom.Parser; - -[TestClass] -public class SbomRelationshipParserTests : SbomParserTestsBase -{ - [TestMethod] - public void ParseSbomRelationshipsTest() - { - var bytes = Encoding.UTF8.GetBytes(RelationshipStrings.GoodJsonWith2RelationshipsString); - using var stream = new MemoryStream(bytes); - - var parser = new SPDXParser(stream); - - var result = this.Parse(parser); - - Assert.AreEqual(2, result.RelationshipsCount); - } - - [TestMethod] - public void StreamEmptyTestReturnsNull() - { - using var stream = new MemoryStream(); - stream.Read(new byte[SbomConstants.ReadBufferSize]); - var buffer = new byte[SbomConstants.ReadBufferSize]; - - Assert.ThrowsException(() => new SPDXParser(stream)); - } - - [DataTestMethod] - [DataRow(RelationshipStrings.JsonRelationshipsStringMissingElementId)] - [DataRow(RelationshipStrings.JsonRelationshipsStringMissingRelatedElement)] - [TestMethod] - public void MissingPropertiesTest_Throws(string json) - { - var bytes = Encoding.UTF8.GetBytes(json); - using var stream = new MemoryStream(bytes); - - var parser = new SPDXParser(stream, bufferSize: 50); - - Assert.ThrowsException(() => this.Parse(parser)); - } - - [DataTestMethod] - [DataRow(RelationshipStrings.GoodJsonWithRelationshipsStringAdditionalString)] - [DataRow(RelationshipStrings.GoodJsonWithRelationshipsStringAdditionalObject)] - [DataRow(RelationshipStrings.GoodJsonWithRelationshipsStringAdditionalArray)] - [DataRow(RelationshipStrings.GoodJsonWithRelationshipsStringAdditionalArrayNoKey)] - [TestMethod] - public void IgnoresAdditionalPropertiesTest(string json) - { - var bytes = Encoding.UTF8.GetBytes(json); - using var stream = new MemoryStream(bytes); - - var parser = new SPDXParser(stream); - - var result = this.Parse(parser); - - Assert.IsTrue(result.RelationshipsCount > 0); - } - - [DataTestMethod] - [DataRow(RelationshipStrings.MalformedJsonRelationshipsString)] - [TestMethod] - public void MalformedJsonTest_Throws(string json) - { - var bytes = Encoding.UTF8.GetBytes(json); - using var stream = new MemoryStream(bytes); - - var parser = new SPDXParser(stream); - - _ = Assert.ThrowsException(() => this.Parse(parser)); - } - - [TestMethod] - public void EmptyArray_ValidJson() - { - var bytes = Encoding.UTF8.GetBytes(RelationshipStrings.MalformedJsonEmptyArray); - using var stream = new MemoryStream(bytes); - - var parser = new SPDXParser(stream); - - var result = this.Parse(parser); - - Assert.AreEqual(0, result.RelationshipsCount); - } - - [TestMethod] - public void NullOrEmptyBuffer_Throws() - { - var bytes = Encoding.UTF8.GetBytes(SbomFileJsonStrings.MalformedJson); - using var stream = new MemoryStream(bytes); - - Assert.ThrowsException(() => new SPDXParser(stream, bufferSize: 0)); - } -} diff --git a/test/Microsoft.Sbom.Parsers.Spdx22SbomParser.Tests/Parser/Strings/ExternalDocumentReferenceStrings.cs b/test/Microsoft.Sbom.Parsers.Spdx22SbomParser.Tests/Parser/Strings/ExternalDocumentReferenceStrings.cs deleted file mode 100644 index fba772ca..00000000 --- a/test/Microsoft.Sbom.Parsers.Spdx22SbomParser.Tests/Parser/Strings/ExternalDocumentReferenceStrings.cs +++ /dev/null @@ -1,119 +0,0 @@ -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -namespace Microsoft.Sbom.Parser.Strings; - -internal readonly struct ExternalDocumentReferenceStrings -{ - public ExternalDocumentReferenceStrings() - { - } - - public const string GoodJsonWith2ExtDocumentRefsString = @"{ - ""externalDocumentRefs"": [ - { - ""externalDocumentId"": ""DocumentRef-LeftPad-1049-08ec1a34d54ae4e28e8b3c4cf6c5c141e67d1af1"", - ""spdxDocument"": ""https://sbom.microsoft/1:VF6zo7ndBEakT2mCbPwGug:mbFNG7JcLkCOpUAYBLp6Fw/28:1049/VUbyIvB6E0awQIFGAOI3Ug"", - ""checksum"": { - ""algorithm"": ""SHA1"", - ""checksumValue"": ""08ec1a34d54ae4e28e8b3c4cf6c5c141e67d1af1"" - }}, - { - ""externalDocumentId"": ""DocumentRef-Test-1049-08ec1a34d54ae4e28e8b3c4cf6c5c141e67d1af1"", - ""spdxDocument"": ""https://sbom.microsoft/1:VF6zo7ndBEakT2mCbPwGug:mbFNG7JcLkCOpUAYBLp6Fw/28:1049/Test2"", - ""checksum"": { - ""algorithm"": ""SHA1"", - ""checksumValue"": ""08ec1a34d5dsfasdf3234f4f432gd23ds2f432f"" - }}]}"; - - public const string JsonExtDocumentRefsStringMissingDocumentId = @"{ - ""externalDocumentRefs"": [{ - ""spdxDocument"": ""https://sbom.microsoft/1:VF6zo7ndBEakT2mCbPwGug:mbFNG7JcLkCOpUAYBLp6Fw/28:1049/VUbyIvB6E0awQIFGAOI3Ug"", - ""checksum"": { - ""algorithm"": ""SHA1"", - ""checksumValue"": ""08ec1a34d54ae4e28e8b3c4cf6c5c141e67d1af1"" - }}]}"; - - public const string JsonExtDocumentRefsStringMissingDocument = @"{ - ""externalDocumentRefs"": [{ - ""externalDocumentId"": ""DocumentRef-LeftPad-1049-08ec1a34d54ae4e28e8b3c4cf6c5c141e67d1af1"", - ""checksum"": { - ""algorithm"": ""SHA1"", - ""checksumValue"": ""08ec1a34d54ae4e28e8b3c4cf6c5c141e67d1af1"" - }}]}"; - - public const string JsonExtDocumentRefsStringMissingChecksum = @"{ - ""externalDocumentRefs"": [{ - ""externalDocumentId"": ""DocumentRef-LeftPad-1049-08ec1a34d54ae4e28e8b3c4cf6c5c141e67d1af1"", - ""spdxDocument"": ""https://sbom.microsoft/1:VF6zo7ndBEakT2mCbPwGug:mbFNG7JcLkCOpUAYBLp6Fw/28:1049/VUbyIvB6E0awQIFGAOI3Ug""]}"; - - public const string JsonExtDocumentRefsStringMissingSHA1Checksum = @"{ - ""externalDocumentRefs"": [{ - ""externalDocumentId"": ""DocumentRef-LeftPad-1049-08ec1a34d54ae4e28e8b3c4cf6c5c141e67d1af1"", - ""spdxDocument"": ""https://sbom.microsoft/1:VF6zo7ndBEakT2mCbPwGug:mbFNG7JcLkCOpUAYBLp6Fw/28:1049/VUbyIvB6E0awQIFGAOI3Ug"", - ""checksum"": { - ""algorithm"": ""SHA256"", - ""checksumValue"": ""08ec1a34d54ae4e28e8b3c4cf6c5c141e67d1af1"" - }}]}"; - - public const string EmptyArray = @"{ - ""externalDocumentRefs"": []}"; - - public const string JsonExtDocumentRefsStringAdditionalString = @"{ - ""externalDocumentRefs"": [ - { - ""externalDocumentId"": ""DocumentRef-LeftPad-1049-08ec1a34d54ae4e28e8b3c4cf6c5c141e67d1af1"", - ""additionalElement"": ""Additional value"", - ""spdxDocument"": ""https://sbom.microsoft/1:VF6zo7ndBEakT2mCbPwGug:mbFNG7JcLkCOpUAYBLp6Fw/28:1049/VUbyIvB6E0awQIFGAOI3Ug"", - ""checksum"": { - ""algorithm"": ""SHA1"", - ""checksumValue"": ""08ec1a34d54ae4e28e8b3c4cf6c5c141e67d1af1"" - }}]}"; - - public const string JsonExtDocumentRefsStringAdditionalObject = @"{ - ""externalDocumentRefs"": [ - { - ""externalDocumentId"": ""DocumentRef-LeftPad-1049-08ec1a34d54ae4e28e8b3c4cf6c5c141e67d1af1"", - ""spdxDocument"": ""https://sbom.microsoft/1:VF6zo7ndBEakT2mCbPwGug:mbFNG7JcLkCOpUAYBLp6Fw/28:1049/VUbyIvB6E0awQIFGAOI3Ug"", - ""checksum"": { - ""algorithm"": ""SHA1"", - ""checksumValue"": ""08ec1a34d54ae4e28e8b3c4cf6c5c141e67d1af1"" - }, - ""additionalProperty"": { - ""childAddtionalProperty"": ""Additional property value"" - }}]}"; - - public const string JsonExtDocumentRefsStringAdditionalArray = @"{ - ""externalDocumentRefs"": [ - { - ""externalDocumentId"": ""DocumentRef-LeftPad-1049-08ec1a34d54ae4e28e8b3c4cf6c5c141e67d1af1"", - ""spdxDocument"": ""https://sbom.microsoft/1:VF6zo7ndBEakT2mCbPwGug:mbFNG7JcLkCOpUAYBLp6Fw/28:1049/VUbyIvB6E0awQIFGAOI3Ug"", - ""checksum"": { - ""algorithm"": ""SHA1"", - ""checksumValue"": ""08ec1a34d54ae4e28e8b3c4cf6c5c141e67d1af1"" - }, - ""additionalProperty"": [ - {""childAddtionalProperty"": ""Additional property value"" }] - }]}"; - - public const string JsonExtDocumentRefsStringAdditionalArrayNoKey = @"{ - ""externalDocumentRefs"": [ - { - ""externalDocumentId"": ""DocumentRef-LeftPad-1049-08ec1a34d54ae4e28e8b3c4cf6c5c141e67d1af1"", - ""spdxDocument"": ""https://sbom.microsoft/1:VF6zo7ndBEakT2mCbPwGug:mbFNG7JcLkCOpUAYBLp6Fw/28:1049/VUbyIvB6E0awQIFGAOI3Ug"", - ""additionalProperty"": [""Additional value 1"", ""Additional value 2""], - ""checksum"": { - ""algorithm"": ""SHA1"", - ""checksumValue"": ""08ec1a34d54ae4e28e8b3c4cf6c5c141e67d1af1"" - }}]}"; - - public const string MalformedJson = @"{ - ""externalDocumentRefs"": [ - { - ""externalDocumentId"": ""DocumentRef-LeftPad-1049-08ec1a34d54ae4e28e8b3c4cf6c5c141e67d1af1"", - ""spdxDocument"" ""https://sbom.microsoft/1:VF6zo7ndBEakT2mCbPwGug:mbFNG7JcLkCOpUAYBLp6Fw/28:1049/VUbyIvB6E0awQIFGAOI3Ug"", - ""checksum"": { - ""algorithm"": ""SHA1"", - ""checksumValue"": ""08ec1a34d54ae4e28e8b3c4cf6c5c141e67d1af1"" - }}]}"; -} diff --git a/test/Microsoft.Sbom.Parsers.Spdx22SbomParser.Tests/Parser/Strings/RelationshipStrings.cs b/test/Microsoft.Sbom.Parsers.Spdx22SbomParser.Tests/Parser/Strings/RelationshipStrings.cs deleted file mode 100644 index 25eeb1b8..00000000 --- a/test/Microsoft.Sbom.Parsers.Spdx22SbomParser.Tests/Parser/Strings/RelationshipStrings.cs +++ /dev/null @@ -1,96 +0,0 @@ -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -namespace Microsoft.Sbom.Parser.Strings; - -internal readonly struct RelationshipStrings -{ - public RelationshipStrings() - { - } - - public const string GoodJsonWith2RelationshipsString = @"{ - ""relationships"": [ - { - ""relationshipType"": ""DEPENDS_ON"", - ""relatedSpdxElement"": ""SPDXRef-Package-342BA5C11805FDDCAF3A2BF48BFDCAB5C0240793089F89196209A39C580902E6"", - ""spdxElementId"": ""SPDXRef-RootPackage"" - }, - { - ""relationshipType"": ""DEPENDS_ON"", - ""relatedSpdxElement"": ""SPDXRef-Package-51F158669105E7517709DAA0BB58D31555101DE3988F1381C3501A7DD94042C7"", - ""spdxElementId"": ""SPDXRef-RootPackage"" - }], ""files"": [], ""packages"": []}"; - - public const string JsonRelationshipsStringMissingElementId = @"{ - ""relationships"": [ - { - ""relationshipType"": ""DEPENDS_ON"", - ""relatedSpdxElement"": ""SPDXRef-Package-342BA5C11805FDDCAF3A2BF48BFDCAB5C0240793089F89196209A39C580902E6"" - }], ""files"": [], ""packages"": []}"; - - public const string JsonRelationshipsStringMissingRelatedElement = @"{ - ""relationships"": [ - { - ""relationshipType"": ""DEPENDS_ON"", - ""spdxElementId"": ""SPDXRef-RootPackage"" - }], ""files"": [], ""packages"": []}"; - - public const string GoodJsonWithRelationshipsStringAdditionalString = @"{ - ""relationships"": [ - { - ""relationshipType"": ""DEPENDS_ON"", - ""relatedSpdxElement"": ""SPDXRef-Package-342BA5C11805FDDCAF3A2BF48BFDCAB5C0240793089F89196209A39C580902E6"", - ""spdxElementId"": ""SPDXRef-RootPackage"", - ""additionalElement"": ""Additional value"" - }], ""files"": [], ""packages"": []}"; - - public const string GoodJsonWithRelationshipsStringAdditionalObject = @"{ - ""relationships"": [ - { - ""relationshipType"": ""DEPENDS_ON"", - ""relatedSpdxElement"": ""SPDXRef-Package-342BA5C11805FDDCAF3A2BF48BFDCAB5C0240793089F89196209A39C580902E6"", - ""spdxElementId"": ""SPDXRef-RootPackage"", - ""additionalProperty"": { - ""childAddtionalProperty"": ""Additional property value"" - } - }], ""files"": [], ""packages"": []}"; - - public const string GoodJsonWithRelationshipsStringAdditionalArray = @"{ - ""relationships"": [ - { - ""relationshipType"": ""DEPENDS_ON"", - ""relatedSpdxElement"": ""SPDXRef-Package-342BA5C11805FDDCAF3A2BF48BFDCAB5C0240793089F89196209A39C580902E6"", - ""spdxElementId"": ""SPDXRef-RootPackage"", - ""additionalProperty"": [ - {""childAddtionalProperty"": ""Additional property value"" }] - }], ""files"": [], ""packages"": []}"; - - public const string GoodJsonWithRelationshipsStringAdditionalArrayNoKey = @"{ - ""relationships"": [ - { - ""relationshipType"": ""DEPENDS_ON"", - ""relatedSpdxElement"": ""SPDXRef-Package-342BA5C11805FDDCAF3A2BF48BFDCAB5C0240793089F89196209A39C580902E6"", - ""spdxElementId"": ""SPDXRef-RootPackage"", - ""additionalProperty"": [""Additional value 1"", ""Additional value 2""] - }], ""files"": [], ""packages"": []}"; - - public const string MalformedJsonRelationshipsString = @"{ - ""relationships"": [ - { - ""relationshipType"": ""DEPENDS_ON"", - ""relatedSpdxElement"": ""SPDXRef-Package-342BA5C11805FDDCAF3A2BF48BFDCAB5C0240793089F89196209A39C580902E6"", - ""spdxElementId"" ""SPDXRef-RootPackage"" - }], ""files"": [], ""packages"": []}"; - - public const string MalformedJsonEmptyArray = @"{ - ""files"": [], ""packages"": [], ""relationships"": []}"; - - public const string MalformedJsonRelationshipsStringBadRelationshipType = @"{ - ""relationships"": [ - { - ""relationshipType"": ""None"", - ""relatedSpdxElement"": ""SPDXRef-Package-342BA5C11805FDDCAF3A2BF48BFDCAB5C0240793089F89196209A39C580902E6"", - ""spdxElementId"": ""SPDXRef-RootPackage"" - }], ""files"": [], ""packages"": []}"; -} diff --git a/test/Microsoft.Sbom.Parsers.Spdx22SbomParser.Tests/Parser/Strings/SbomFileJsonStrings.cs b/test/Microsoft.Sbom.Parsers.Spdx22SbomParser.Tests/Parser/Strings/SbomFileJsonStrings.cs deleted file mode 100644 index bd82ee12..00000000 --- a/test/Microsoft.Sbom.Parsers.Spdx22SbomParser.Tests/Parser/Strings/SbomFileJsonStrings.cs +++ /dev/null @@ -1,354 +0,0 @@ -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -namespace Microsoft.Sbom.Parser.Strings; - -internal struct SbomFileJsonStrings -{ - public SbomFileJsonStrings() - { - } - - public const string GoodJsonWith2FilesString = @"{ - ""files"": [ - { - ""fileName"": ""./file1"", - ""SPDXID"": ""SPDXRef-File--sbom-tool-win-x64.exe-E55F25E239D8D3572D75D5CDC5CA24899FD4993F"", - ""checksums"": [ - { - ""algorithm"": ""SHA256"", - ""checksumValue"": ""56624d8ab67ac0e323bcac0ae1ec0656f1721c6bb60640ecf9b30e861062aad5"" - }, - { - ""algorithm"": ""SHA1"", - ""checksumValue"": ""e55f25e239d8d3572d75d5cdc5ca24899fd4993f"" - } - ], - ""licenseConcluded"": ""NOASSERTION"", - ""licenseInfoInFiles"": [ - ""NOASSERTION"" - ], - ""copyrightText"": ""NOASSERTION"" - }, - { - ""fileName"": ""./file2"", - ""SPDXID"": ""SPDXRef-File--test.xml-E55F25E239D8D3572D75D5CDC5CA24899FD4993E"", - ""checksums"": [ - { - ""algorithm"": ""SHA256"", - ""checksumValue"": ""56624d8ab67ac0e323bcac0ae1ec0656f1721c6bb60640ecf9b30e861062aad2"" - }, - { - ""algorithm"": ""SHA1"", - ""checksumValue"": ""e55f25e239d8d3572d75d5cdc5ca24899fd49932"" - } - ], - ""licenseConcluded"": ""NOASSERTION"", - ""licenseInfoInFiles"": [ - ""NOASSERTION"", ""GNU"" - ], - ""copyrightText"": ""NOASSERTION"" - } - ], ""packages"": [], ""relationships"": [], ""creationInfo"": { - ""created"": ""2023-05-11T00:24:54Z"", - ""creators"": [ - ""Organization: Microsoft"", - ""Tool: Microsoft.SBOMTool-1.1.0"" - ] - }}"; - - public const string MalformedJsonEmptyObjectNoArrayEnd = @"{ - ""files"": [{ - ""fileName"": ""./file1"", - ""SPDXID"": ""SPDXRef-File--sbom-tool-win-x64.exe-E55F25E239D8D3572D75D5CDC5CA24899FD4993F"", - ""checksums"": [ - { - ""algorithm"": ""SHA256"", - ""checksumValue"": ""56624d8ab67ac0e323bcac0ae1ec0656f1721c6bb60640ecf9b30e861062aad5"" - }, - { - ""algorithm"": ""SHA1"", - ""checksumValue"": ""e55f25e239d8d3572d75d5cdc5ca24899fd4993f"" - } - ], - ""licenseConcluded"": ""NOASSERTION"", - ""licenseInfoInFiles"": [ - ""NOASSERTION"" - , - ""copyrightText"": ""NOASSERTION"" - }], ""packages"": [], ""relationships"": []}"; - - public const string MalformedJsonEmptyObject = @"{""files"":{}"; - public const string MalformedJsonEmptyArray = @"{""files"": []"; - public const string JsonEmptyArray = @"{""files"": [], ""packages"": [], ""relationships"": []}"; - public const string MalformedJson = @"{ - ""files"": [ - { - ""fileName"": ""./file1"", - ""SPDXID"": ""SPDXRef-File--sbom-tool-win-x64.exe-E55F25E239D8D3572D75D5CDC5CA24899FD4993F"", - ""checksums"" [ - { - ""algorithm"": ""SHA256"", - ""checksumValue"": ""56624d8ab67ac0e323bcac0ae1ec0656f1721c6bb60640ecf9b30e861062aad5"" - }, - { - ""algorithm"": ""SHA1"", - ""checksumValue"": ""e55f25e239d8d3572d75d5cdc5ca24899fd4993f"" - } - ], - ""licenseConcluded"": ""NOASSERTION"", - ""licenseInfoInFiles"": [ - ""NOASSERTION"" - ], - ""copyrightText"": ""NOASSERTION"" - }], ""packages"": [], ""relationships"": []}"; - - public const string GoodJsonWith1FileAdditionalStringPropertyString = @"{ - ""files"": [ - { - ""fileName"": ""./additional"", - ""SPDXID"": ""SPDXRef-File--sbom-tool-win-x64.exe-E55F25E239D8D3572D75D5CDC5CA24899FD4993F"", - ""additionalProperty"": ""Additional property value"", - ""checksums"": [ - { - ""algorithm"": ""SHA256"", - ""checksumValue"": ""56624d8ab67ac0e323bcac0ae1ec0656f1721c6bb60640ecf9b30e861062aad5"" - }, - { - ""algorithm"": ""SHA1"", - ""checksumValue"": ""e55f25e239d8d3572d75d5cdc5ca24899fd4993f"" - } - ], - ""licenseConcluded"": ""NOASSERTION"", - ""licenseInfoInFiles"": [ - ""NOASSERTION"" - ], - ""copyrightText"": ""NOASSERTION"" - }], ""packages"": [], ""relationships"": []}"; - - public const string GoodJsonWith1FileAdditionalValueArrayPropertyString = @"{ - ""files"": [ - { - ""fileName"": ""./file1"", - ""SPDXID"": ""SPDXRef-File--sbom-tool-win-x64.exe-E55F25E239D8D3572D75D5CDC5CA24899FD4993F"", - ""additionalProperty"": [""Additional value 1"", ""Additional value 2""], - ""checksums"": [ - { - ""algorithm"": ""SHA256"", - ""checksumValue"": ""56624d8ab67ac0e323bcac0ae1ec0656f1721c6bb60640ecf9b30e861062aad5"" - }, - { - ""algorithm"": ""SHA1"", - ""checksumValue"": ""e55f25e239d8d3572d75d5cdc5ca24899fd4993f"" - } - ], - ""licenseConcluded"": ""NOASSERTION"", - ""licenseInfoInFiles"": [ - ""NOASSERTION"" - ], - ""copyrightText"": ""NOASSERTION"" - }], ""packages"": [], ""relationships"": []}"; - - public const string GoodJsonWith1FileAdditionalArrayPropertyString = @"{ - ""files"": [ - { - ""fileName"": ""./file1"", - ""SPDXID"": ""SPDXRef-File--sbom-tool-win-x64.exe-E55F25E239D8D3572D75D5CDC5CA24899FD4993F"", - ""additionalProperty"": [ - {""childAddtionalProperty"": ""Additional property value"" - }], - ""checksums"": [ - { - ""algorithm"": ""SHA256"", - ""checksumValue"": ""56624d8ab67ac0e323bcac0ae1ec0656f1721c6bb60640ecf9b30e861062aad5"" - }, - { - ""algorithm"": ""SHA1"", - ""checksumValue"": ""e55f25e239d8d3572d75d5cdc5ca24899fd4993f"" - } - ], - ""licenseConcluded"": ""NOASSERTION"", - ""licenseInfoInFiles"": [ - ""NOASSERTION"" - ], - ""copyrightText"": ""NOASSERTION"" - }], ""packages"": [], ""relationships"": []}"; - - public const string GoodJsonWith1FileAdditionalObjectPropertyString = @"{ - ""files"": [ - { - ""fileName"": ""./file1"", - ""SPDXID"": ""SPDXRef-File--sbom-tool-win-x64.exe-E55F25E239D8D3572D75D5CDC5CA24899FD4993F"", - ""additionalProperty"": { - ""childAddtionalProperty"": ""Additional property value"" - }, - ""checksums"": [ - { - ""algorithm"": ""SHA256"", - ""checksumValue"": ""56624d8ab67ac0e323bcac0ae1ec0656f1721c6bb60640ecf9b30e861062aad5"" - }, - { - ""algorithm"": ""SHA1"", - ""checksumValue"": ""e55f25e239d8d3572d75d5cdc5ca24899fd4993f"" - } - ], - ""licenseConcluded"": ""NOASSERTION"", - ""licenseInfoInFiles"": [ - ""NOASSERTION"" - ], - ""copyrightText"": ""NOASSERTION"" - }], ""packages"": [], ""relationships"": []}"; - - public const string JsonWith1FileMissingNameString = @"{ - ""files"": [ - { - ""SPDXID"": ""SPDXRef-File--sbom-tool-win-x64.exe-E55F25E239D8D3572D75D5CDC5CA24899FD4993F"", - ""checksums"": [ - { - ""algorithm"": ""SHA256"", - ""checksumValue"": ""56624d8ab67ac0e323bcac0ae1ec0656f1721c6bb60640ecf9b30e861062aad5"" - }, - { - ""algorithm"": ""SHA1"", - ""checksumValue"": ""e55f25e239d8d3572d75d5cdc5ca24899fd4993f"" - } - ], - ""licenseConcluded"": ""NOASSERTION"", - ""licenseInfoInFiles"": [ - ""NOASSERTION"" - ], - ""copyrightText"": ""NOASSERTION"" - }], ""packages"": [], ""relationships"": []}"; - - public const string JsonWith1FileMissingIDString = @"{ - ""files"": [ - { - ""fileName"": ""./file1"", - ""checksums"": [ - { - ""algorithm"": ""SHA256"", - ""checksumValue"": ""56624d8ab67ac0e323bcac0ae1ec0656f1721c6bb60640ecf9b30e861062aad5"" - }, - { - ""algorithm"": ""SHA1"", - ""checksumValue"": ""e55f25e239d8d3572d75d5cdc5ca24899fd4993f"" - } - ], - ""licenseConcluded"": ""NOASSERTION"", - ""licenseInfoInFiles"": [ - ""NOASSERTION"" - ], - ""copyrightText"": ""NOASSERTION"" - }], ""packages"": [], ""relationships"": []}"; - - public const string JsonWith1FileMissingChecksumsString = @"{ - ""files"": [ - { - ""fileName"": ""./file1"", - ""SPDXID"": ""SPDXRef-File--sbom-tool-win-x64.exe-E55F25E239D8D3572D75D5CDC5CA24899FD4993F"", - ""licenseConcluded"": ""NOASSERTION"", - ""licenseInfoInFiles"": [ - ""NOASSERTION"" - ], - ""copyrightText"": ""NOASSERTION"" - }], ""packages"": [], ""relationships"": []}"; - - public const string JsonWith1FileMissingSHA256ChecksumsString = @"{ - ""files"": [ - { - ""fileName"": ""./file1"", - ""SPDXID"": ""SPDXRef-File--sbom-tool-win-x64.exe-E55F25E239D8D3572D75D5CDC5CA24899FD4993F"", - ""checksums"": [ - { - ""algorithm"": ""SHA1"", - ""checksumValue"": ""e55f25e239d8d3572d75d5cdc5ca24899fd4993f"" - } - ], - ""licenseConcluded"": ""NOASSERTION"", - ""licenseInfoInFiles"": [ - ""NOASSERTION"" - ], - ""copyrightText"": ""NOASSERTION"" - }], ""packages"": [], ""relationships"": []}"; - - public const string JsonWith1FileMissingLicenseConcludedString = @"{ - ""files"": [ - { - ""fileName"": ""./file1"", - ""SPDXID"": ""SPDXRef-File--sbom-tool-win-x64.exe-E55F25E239D8D3572D75D5CDC5CA24899FD4993F"", - ""checksums"": [ - { - ""algorithm"": ""SHA256"", - ""checksumValue"": ""56624d8ab67ac0e323bcac0ae1ec0656f1721c6bb60640ecf9b30e861062aad5"" - }, - { - ""algorithm"": ""SHA1"", - ""checksumValue"": ""e55f25e239d8d3572d75d5cdc5ca24899fd4993f"" - } - ], - ""licenseInfoInFiles"": [ - ""NOASSERTION"" - ], - ""copyrightText"": ""NOASSERTION"" - }], ""packages"": [], ""relationships"": []}"; - - public const string JsonWith1FileMissingLicenseInfoInFilesString = @"{ - ""files"": [ - { - ""fileName"": ""./file1"", - ""SPDXID"": ""SPDXRef-File--sbom-tool-win-x64.exe-E55F25E239D8D3572D75D5CDC5CA24899FD4993F"", - ""checksums"": [ - { - ""algorithm"": ""SHA256"", - ""checksumValue"": ""56624d8ab67ac0e323bcac0ae1ec0656f1721c6bb60640ecf9b30e861062aad5"" - }, - { - ""algorithm"": ""SHA1"", - ""checksumValue"": ""e55f25e239d8d3572d75d5cdc5ca24899fd4993f"" - } - ], - ""licenseConcluded"": ""NOASSERTION"", - ""copyrightText"": ""NOASSERTION"" - }], ""packages"": [], ""relationships"": []}"; - - public const string JsonWith1FileMissingCopyrightString = @"{ - ""files"": [ - { - ""fileName"": ""./file1"", - ""SPDXID"": ""SPDXRef-File--sbom-tool-win-x64.exe-E55F25E239D8D3572D75D5CDC5CA24899FD4993F"", - ""checksums"": [ - { - ""algorithm"": ""SHA256"", - ""checksumValue"": ""56624d8ab67ac0e323bcac0ae1ec0656f1721c6bb60640ecf9b30e861062aad5"" - }, - { - ""algorithm"": ""SHA1"", - ""checksumValue"": ""e55f25e239d8d3572d75d5cdc5ca24899fd4993f"" - } - ], - ""licenseConcluded"": ""NOASSERTION"", - ""licenseInfoInFiles"": [ - ""NOASSERTION"" - ] - }], ""packages"": [], ""relationships"": []}"; - - public const string JsonWith1FileMissingCopyrightAndPathString = @"{ - ""files"": [ - { - ""SPDXID"": ""SPDXRef-File--sbom-tool-win-x64.exe-E55F25E239D8D3572D75D5CDC5CA24899FD4993F"", - ""checksums"": [ - { - ""algorithm"": ""SHA256"", - ""checksumValue"": ""56624d8ab67ac0e323bcac0ae1ec0656f1721c6bb60640ecf9b30e861062aad5"" - }, - { - ""algorithm"": ""SHA1"", - ""checksumValue"": ""e55f25e239d8d3572d75d5cdc5ca24899fd4993f"" - } - ], - ""licenseConcluded"": ""NOASSERTION"", - ""licenseInfoInFiles"": [ - ""NOASSERTION"" - ] - }], ""packages"": [], ""relationships"": []}"; -} diff --git a/test/Microsoft.Sbom.Parsers.Spdx22SbomParser.Tests/Parser/Strings/SbomPackageStrings.cs b/test/Microsoft.Sbom.Parsers.Spdx22SbomParser.Tests/Parser/Strings/SbomPackageStrings.cs deleted file mode 100644 index 98e165c2..00000000 --- a/test/Microsoft.Sbom.Parsers.Spdx22SbomParser.Tests/Parser/Strings/SbomPackageStrings.cs +++ /dev/null @@ -1,567 +0,0 @@ -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -namespace Microsoft.Sbom.Parser.Strings; - -internal struct SbomPackageStrings -{ - public SbomPackageStrings() - { - } - - public const string PackageJsonWith1PackageAdditionalString = @"{ - ""packages"": [{ - ""name"": ""pest"", - ""other"": ""tt"", - ""SPDXID"": ""SPDXRef-Package-1C4595D6D70121622649BB913859B18A3C0A2D49EC7D36279777025C4AC92303"", - ""downloadLocation"": ""NOASSERTION"", - ""filesAnalyzed"": false, - ""licenseConcluded"": ""NOASSERTION"", - ""licenseInfoFromFiles"": [ - ""NOASSERTION"" - ], - ""licenseDeclared"": ""NOASSERTION"", - ""copyrightText"": ""NOASSERTION"", - ""versionInfo"": ""1.0.0"", - ""externalRefs"": [ - { - ""referenceCategory"": ""PACKAGE_MANAGER"", - ""referenceType"": ""purl"", - ""referenceLocator"": ""pkg:nuget/pest%401.0.0"" - } - ], - ""supplier"": ""Organization: testa"" - }], ""files"":[], ""relationships"":[]}"; - - public const string PackageJsonWith1PackageAdditionalArray = @"{ - ""packages"": [{ - ""name"": ""pest"", - ""SPDXID"": ""SPDXRef-Package-1C4595D6D70121622649BB913859B18A3C0A2D49EC7D36279777025C4AC92303"", - ""downloadLocation"": ""NOASSERTION"", - ""filesAnalyzed"": false, - ""licenseConcluded"": ""NOASSERTION"", - ""licenseInfoFromFiles"": [ - ""NOASSERTION"" - ], - ""additionalProperty"": [ - {""childAddtionalProperty"": ""Additional property value"" }], - ""licenseDeclared"": ""NOASSERTION"", - ""copyrightText"": ""NOASSERTION"", - ""versionInfo"": ""1.0.0"", - ""externalRefs"": [ - { - ""referenceCategory"": ""PACKAGE_MANAGER"", - ""referenceType"": ""purl"", - ""referenceLocator"": ""pkg:nuget/pest%401.0.0"" - } - ], - ""supplier"": ""Organization: testa"" - }], ""files"":[], ""relationships"":[]}"; - - public const string PackageJsonWith1PackageAdditionalArrayNoKey = @"{ - ""packages"": [{ - ""name"": ""pest"", - ""SPDXID"": ""SPDXRef-Package-1C4595D6D70121622649BB913859B18A3C0A2D49EC7D36279777025C4AC92303"", - ""downloadLocation"": ""NOASSERTION"", - ""filesAnalyzed"": false, - ""licenseConcluded"": ""NOASSERTION"", - ""licenseInfoFromFiles"": [ - ""NOASSERTION"" - ], - ""additionalProperty"": [""Additional value 1"", ""Additional value 2""], - ""licenseDeclared"": ""NOASSERTION"", - ""copyrightText"": ""NOASSERTION"", - ""versionInfo"": ""1.0.0"", - ""externalRefs"": [ - { - ""referenceCategory"": ""PACKAGE_MANAGER"", - ""referenceType"": ""purl"", - ""referenceLocator"": ""pkg:nuget/pest%401.0.0"" - } - ], - ""supplier"": ""Organization: testa"" - }], ""files"":[], ""relationships"":[]}"; - - public const string PackageJsonWith1PackageAdditionalObject = @"{ - ""packages"": [{ - ""name"": ""pest"", - ""SPDXID"": ""SPDXRef-Package-1C4595D6D70121622649BB913859B18A3C0A2D49EC7D36279777025C4AC92303"", - ""downloadLocation"": ""NOASSERTION"", - ""filesAnalyzed"": false, - ""licenseConcluded"": ""NOASSERTION"", - ""licenseInfoFromFiles"": [ - ""NOASSERTION"" - ], - ""additionalProperty"": { - ""childAddtionalProperty"": ""Additional property value"" - }, - ""licenseDeclared"": ""NOASSERTION"", - ""copyrightText"": ""NOASSERTION"", - ""versionInfo"": ""1.0.0"", - ""externalRefs"": [ - { - ""referenceCategory"": ""PACKAGE_MANAGER"", - ""referenceType"": ""purl"", - ""referenceLocator"": ""pkg:nuget/pest%401.0.0"" - } - ], - ""supplier"": ""Organization: testa"" - }], ""files"":[], ""relationships"":[]}"; - - public const string MalformedJsonEmptyObject = @"{ - ""packages"":{}}"; - - public const string MalformedJsonEmptyObjectNoArrayEnd = @"{ - ""packages"":[}"; - - public const string MalformedJson = @"{ - ""packages"": [{ - ""name"": ""pest"", - ""SPDXID"": ""SPDXRef-Package-1C4595D6D70121622649BB913859B18A3C0A2D49EC7D36279777025C4AC92303"", - ""downloadLocation"": ""NOASSERTION"", - ""filesAnalyzed"": false, - ""licenseConcluded"": ""NOASSERTION"", - ""licenseInfoFromFiles"": [ - ""NOASSERTION"" - ], - ""licenseDeclared"": ""NOASSERTION"", - ""copyrightText"": ""NOASSERTION"", - ""versionInfo"": ""1.0.0, - ""externalRefs"": [ - { - ""referenceCategory"": ""PACKAGE_MANAGER"", - ""referenceType"": ""purl"", - ""referenceLocator"": ""pkg:nuget/pest%401.0.0"" - } - ], - ""supplier"": ""Organization: testa"" - }]}"; - - public const string PackageJsonWith1PackageFilesAnalyzedTrueAndMissingLicenseInfoFromFiles = @"{ - ""packages"": [{ - ""name"": ""pest"", - ""other"": ""tt"", - ""SPDXID"": ""SPDXRef-Package-1C4595D6D70121622649BB913859B18A3C0A2D49EC7D36279777025C4AC92303"", - ""downloadLocation"": ""NOASSERTION"", - ""filesAnalyzed"": true, - ""licenseConcluded"": ""NOASSERTION"", - ""licenseDeclared"": ""NOASSERTION"", - ""copyrightText"": ""NOASSERTION"", - ""versionInfo"": ""1.0.0"", - ""externalRefs"": [ - { - ""referenceCategory"": ""PACKAGE_MANAGER"", - ""referenceType"": ""purl"", - ""referenceLocator"": ""pkg:nuget/pest%401.0.0"" - } - ], - ""supplier"": ""Organization: testa"" - }]}"; - - public const string PackageJsonWith1PackageMissingPackageVerificationCode = @"{ - ""packages"": [{ - ""name"": ""pest"", - ""SPDXID"": ""SPDXRef-RootPackage"", - ""downloadLocation"": ""NOASSERTION"", - ""packageVerificationCode"": { - ""packageVerificationCodeValue"": """" - }, - ""filesAnalyzed"": true, - ""licenseConcluded"": ""NOASSERTION"", - ""licenseInfoFromFiles"": [ - ""NOASSERTION"" - ], - ""licenseDeclared"": ""NOASSERTION"", - ""copyrightText"": ""NOASSERTION"", - ""versionInfo"": ""1208"", - ""supplier"": ""Organization: Microsoft"", - ""hasFiles"": [ - ""SPDXRef-File--package-services-metadata-core-properties-16e5bdb646ef44f485b1227d6d005f14.psmdcp-81EC7E121D7F03CDE59C8A4570A7D75C7EBB063A"", - ""SPDXRef-File--packages.config-69B7910C6FC95DB019934AA3BE0CDFDC3F3F2D8E"", - ""SPDXRef-File--pest.nuspec-A2EBA85861EAFD340496A9A7948D193284A19408"", - ""SPDXRef-File---rels-.rels-2DBE1B6566BFF9F17C259FB7D8B21231D4F11857"", - ""SPDXRef-File---Content-Types-.xml-EB0036B6C11A1AF694FA8ABACA0A4C43584225DE"" - ] - }]}"; - - public const string PackageJsonWith1PackageMissingReferenceLocator = @"{ - ""packages"": [{ - ""name"": ""pest"", - ""SPDXID"": ""SPDXRef-RootPackage"", - ""downloadLocation"": ""NOASSERTION"", - ""packageVerificationCode"": { - ""packageVerificationCodeValue"": ""a2f8875f69c1b3814120e98bd3c0864e3c586a24"" - }, - ""filesAnalyzed"": true, - ""licenseConcluded"": ""NOASSERTION"", - ""licenseInfoFromFiles"": [ - ""NOASSERTION"" - ], - ""licenseDeclared"": ""NOASSERTION"", - ""copyrightText"": ""NOASSERTION"", - ""versionInfo"": ""1208"", - ""supplier"": ""Organization: Microsoft"", - ""hasFiles"": [ - ""SPDXRef-File--package-services-metadata-core-properties-16e5bdb646ef44f485b1227d6d005f14.psmdcp-81EC7E121D7F03CDE59C8A4570A7D75C7EBB063A"", - ""SPDXRef-File--packages.config-69B7910C6FC95DB019934AA3BE0CDFDC3F3F2D8E"", - ""SPDXRef-File--pest.nuspec-A2EBA85861EAFD340496A9A7948D193284A19408"", - ""SPDXRef-File---rels-.rels-2DBE1B6566BFF9F17C259FB7D8B21231D4F11857"", - ""SPDXRef-File---Content-Types-.xml-EB0036B6C11A1AF694FA8ABACA0A4C43584225DE"" - ], - ""externalRefs"": [ - { - ""referenceCategory"": ""PACKAGE_MANAGER"", - ""referenceType"": ""purl"", - } - ], - }]}"; - - public const string PackageJsonWith1PackageBadReferenceType = @"{ - ""packages"": [{ - ""name"": ""pest"", - ""SPDXID"": ""SPDXRef-RootPackage"", - ""downloadLocation"": ""NOASSERTION"", - ""packageVerificationCode"": { - ""packageVerificationCodeValue"": ""a2f8875f69c1b3814120e98bd3c0864e3c586a24"" - }, - ""filesAnalyzed"": true, - ""licenseConcluded"": ""NOASSERTION"", - ""licenseInfoFromFiles"": [ - ""NOASSERTION"" - ], - ""licenseDeclared"": ""NOASSERTION"", - ""copyrightText"": ""NOASSERTION"", - ""versionInfo"": ""1208"", - ""supplier"": ""Organization: Microsoft"", - ""hasFiles"": [ - ""SPDXRef-File--package-services-metadata-core-properties-16e5bdb646ef44f485b1227d6d005f14.psmdcp-81EC7E121D7F03CDE59C8A4570A7D75C7EBB063A"", - ""SPDXRef-File--packages.config-69B7910C6FC95DB019934AA3BE0CDFDC3F3F2D8E"", - ""SPDXRef-File--pest.nuspec-A2EBA85861EAFD340496A9A7948D193284A19408"", - ""SPDXRef-File---rels-.rels-2DBE1B6566BFF9F17C259FB7D8B21231D4F11857"", - ""SPDXRef-File---Content-Types-.xml-EB0036B6C11A1AF694FA8ABACA0A4C43584225DE"" - ], - ""externalRefs"": [ - { - ""referenceCategory"": ""PACKAGE_MANAGER"", - ""referenceType"": ""testss"", - ""referenceLocator"": ""pkg:nuget/System.Runtime.InteropServices.WindowsRuntime%404.3.0"" - } - ], - }]}"; - - public const string PackageJsonWith1PackageMissingName = @"{ - ""packages"": [{ - ""SPDXID"": ""SPDXRef-RootPackage"", - ""downloadLocation"": ""NOASSERTION"", - ""packageVerificationCode"": { - ""packageVerificationCodeValue"": ""a2f8875f69c1b3814120e98bd3c0864e3c586a24"" - }, - ""filesAnalyzed"": true, - ""licenseConcluded"": ""NOASSERTION"", - ""licenseInfoFromFiles"": [ - ""NOASSERTION"" - ], - ""licenseDeclared"": ""NOASSERTION"", - ""copyrightText"": ""NOASSERTION"", - ""versionInfo"": ""1208"", - ""supplier"": ""Organization: Microsoft"", - ""hasFiles"": [ - ""SPDXRef-File--package-services-metadata-core-properties-16e5bdb646ef44f485b1227d6d005f14.psmdcp-81EC7E121D7F03CDE59C8A4570A7D75C7EBB063A"", - ""SPDXRef-File--packages.config-69B7910C6FC95DB019934AA3BE0CDFDC3F3F2D8E"", - ""SPDXRef-File--pest.nuspec-A2EBA85861EAFD340496A9A7948D193284A19408"", - ""SPDXRef-File---rels-.rels-2DBE1B6566BFF9F17C259FB7D8B21231D4F11857"", - ""SPDXRef-File---Content-Types-.xml-EB0036B6C11A1AF694FA8ABACA0A4C43584225DE"" - ] - }]}"; - - public const string PackageJsonWith1PackageMissingId = @"{ - ""packages"": [{ - ""name"": ""Testing cross platform signing"", - ""downloadLocation"": ""NOASSERTION"", - ""packageVerificationCode"": { - ""packageVerificationCodeValue"": ""a2f8875f69c1b3814120e98bd3c0864e3c586a24"" - }, - ""filesAnalyzed"": true, - ""licenseConcluded"": ""NOASSERTION"", - ""licenseInfoFromFiles"": [ - ""NOASSERTION"" - ], - ""licenseDeclared"": ""NOASSERTION"", - ""copyrightText"": ""NOASSERTION"", - ""versionInfo"": ""1208"", - ""supplier"": ""Organization: Microsoft"", - ""hasFiles"": [ - ""SPDXRef-File--package-services-metadata-core-properties-16e5bdb646ef44f485b1227d6d005f14.psmdcp-81EC7E121D7F03CDE59C8A4570A7D75C7EBB063A"", - ""SPDXRef-File--packages.config-69B7910C6FC95DB019934AA3BE0CDFDC3F3F2D8E"", - ""SPDXRef-File--pest.nuspec-A2EBA85861EAFD340496A9A7948D193284A19408"", - ""SPDXRef-File---rels-.rels-2DBE1B6566BFF9F17C259FB7D8B21231D4F11857"", - ""SPDXRef-File---Content-Types-.xml-EB0036B6C11A1AF694FA8ABACA0A4C43584225DE"" - ] - }]}"; - - public const string PackageJsonWith1PackageMissingDownloadLocation = @"{ - ""packages"": [{ - ""name"": ""Testing cross platform signing"", - ""SPDXID"": ""SPDXRef-RootPackage"", - ""packageVerificationCode"": { - ""packageVerificationCodeValue"": ""a2f8875f69c1b3814120e98bd3c0864e3c586a24"" - }, - ""filesAnalyzed"": true, - ""licenseConcluded"": ""NOASSERTION"", - ""licenseInfoFromFiles"": [ - ""NOASSERTION"" - ], - ""licenseDeclared"": ""NOASSERTION"", - ""copyrightText"": ""NOASSERTION"", - ""versionInfo"": ""1208"", - ""supplier"": ""Organization: Microsoft"", - ""hasFiles"": [ - ""SPDXRef-File--package-services-metadata-core-properties-16e5bdb646ef44f485b1227d6d005f14.psmdcp-81EC7E121D7F03CDE59C8A4570A7D75C7EBB063A"", - ""SPDXRef-File--packages.config-69B7910C6FC95DB019934AA3BE0CDFDC3F3F2D8E"", - ""SPDXRef-File--pest.nuspec-A2EBA85861EAFD340496A9A7948D193284A19408"", - ""SPDXRef-File---rels-.rels-2DBE1B6566BFF9F17C259FB7D8B21231D4F11857"", - ""SPDXRef-File---Content-Types-.xml-EB0036B6C11A1AF694FA8ABACA0A4C43584225DE"" - ] - }], ""files"": [], ""relationships"":[]}"; - - public const string PackageJsonWith1PackageMissingFilesAnalyzed = @"{ - ""packages"": [{ - ""name"": ""Testing cross platform signing"", - ""SPDXID"": ""SPDXRef-RootPackage"", - ""downloadLocation"": ""NOASSERTION"", - ""packageVerificationCode"": { - ""packageVerificationCodeValue"": ""a2f8875f69c1b3814120e98bd3c0864e3c586a24"" - }, - ""licenseConcluded"": ""NOASSERTION"", - ""licenseInfoFromFiles"": [ - ""NOASSERTION"" - ], - ""licenseDeclared"": ""NOASSERTION"", - ""copyrightText"": ""NOASSERTION"", - ""versionInfo"": ""1208"", - ""supplier"": ""Organization: Microsoft"", - ""hasFiles"": [ - ""SPDXRef-File--package-services-metadata-core-properties-16e5bdb646ef44f485b1227d6d005f14.psmdcp-81EC7E121D7F03CDE59C8A4570A7D75C7EBB063A"", - ""SPDXRef-File--packages.config-69B7910C6FC95DB019934AA3BE0CDFDC3F3F2D8E"", - ""SPDXRef-File--pest.nuspec-A2EBA85861EAFD340496A9A7948D193284A19408"", - ""SPDXRef-File---rels-.rels-2DBE1B6566BFF9F17C259FB7D8B21231D4F11857"", - ""SPDXRef-File---Content-Types-.xml-EB0036B6C11A1AF694FA8ABACA0A4C43584225DE"" - ] - }]}"; - - public const string PackageJsonWith1PackageMissingLicenseConcluded = @"{ - ""packages"": [{ - ""name"": ""Testing cross platform signing"", - ""SPDXID"": ""SPDXRef-RootPackage"", - ""downloadLocation"": ""NOASSERTION"", - ""packageVerificationCode"": { - ""packageVerificationCodeValue"": ""a2f8875f69c1b3814120e98bd3c0864e3c586a24"" - }, - ""filesAnalyzed"": true, - ""licenseInfoFromFiles"": [ - ""NOASSERTION"" - ], - ""licenseDeclared"": ""NOASSERTION"", - ""copyrightText"": ""NOASSERTION"", - ""versionInfo"": ""1208"", - ""supplier"": ""Organization: Microsoft"", - ""hasFiles"": [ - ""SPDXRef-File--package-services-metadata-core-properties-16e5bdb646ef44f485b1227d6d005f14.psmdcp-81EC7E121D7F03CDE59C8A4570A7D75C7EBB063A"", - ""SPDXRef-File--packages.config-69B7910C6FC95DB019934AA3BE0CDFDC3F3F2D8E"", - ""SPDXRef-File--pest.nuspec-A2EBA85861EAFD340496A9A7948D193284A19408"", - ""SPDXRef-File---rels-.rels-2DBE1B6566BFF9F17C259FB7D8B21231D4F11857"", - ""SPDXRef-File---Content-Types-.xml-EB0036B6C11A1AF694FA8ABACA0A4C43584225DE"" - ] - }]}"; - - public const string PackageJsonWith1PackageMissingLicenseInfoFromFiles = @"{ - ""packages"": [{ - ""name"": ""Testing cross platform signing"", - ""SPDXID"": ""SPDXRef-RootPackage"", - ""downloadLocation"": ""NOASSERTION"", - ""packageVerificationCode"": { - ""packageVerificationCodeValue"": ""a2f8875f69c1b3814120e98bd3c0864e3c586a24"" - }, - ""filesAnalyzed"": true, - ""licenseConcluded"": ""NOASSERTION"", - ""licenseDeclared"": ""NOASSERTION"", - ""copyrightText"": ""NOASSERTION"", - ""versionInfo"": ""1208"", - ""supplier"": ""Organization: Microsoft"", - ""hasFiles"": [ - ""SPDXRef-File--package-services-metadata-core-properties-16e5bdb646ef44f485b1227d6d005f14.psmdcp-81EC7E121D7F03CDE59C8A4570A7D75C7EBB063A"", - ""SPDXRef-File--packages.config-69B7910C6FC95DB019934AA3BE0CDFDC3F3F2D8E"", - ""SPDXRef-File--pest.nuspec-A2EBA85861EAFD340496A9A7948D193284A19408"", - ""SPDXRef-File---rels-.rels-2DBE1B6566BFF9F17C259FB7D8B21231D4F11857"", - ""SPDXRef-File---Content-Types-.xml-EB0036B6C11A1AF694FA8ABACA0A4C43584225DE"" - ] - }]}"; - - public const string PackageJsonWith1PackageMissingLicenseDeclared = @"{ - ""packages"": [{ - ""name"": ""Testing cross platform signing"", - ""SPDXID"": ""SPDXRef-RootPackage"", - ""downloadLocation"": ""NOASSERTION"", - ""packageVerificationCode"": { - ""packageVerificationCodeValue"": ""a2f8875f69c1b3814120e98bd3c0864e3c586a24"" - }, - ""filesAnalyzed"": true, - ""licenseConcluded"": ""NOASSERTION"", - ""licenseInfoFromFiles"": [ - ""NOASSERTION"" - ], - ""copyrightText"": ""NOASSERTION"", - ""versionInfo"": ""1208"", - ""supplier"": ""Organization: Microsoft"", - ""hasFiles"": [ - ""SPDXRef-File--package-services-metadata-core-properties-16e5bdb646ef44f485b1227d6d005f14.psmdcp-81EC7E121D7F03CDE59C8A4570A7D75C7EBB063A"", - ""SPDXRef-File--packages.config-69B7910C6FC95DB019934AA3BE0CDFDC3F3F2D8E"", - ""SPDXRef-File--pest.nuspec-A2EBA85861EAFD340496A9A7948D193284A19408"", - ""SPDXRef-File---rels-.rels-2DBE1B6566BFF9F17C259FB7D8B21231D4F11857"", - ""SPDXRef-File---Content-Types-.xml-EB0036B6C11A1AF694FA8ABACA0A4C43584225DE"" - ] - }]}"; - - public const string PackageJsonWith1PackageMissingCopyrightText = @"{ - ""packages"": [{ - ""name"": ""Testing cross platform signing"", - ""SPDXID"": ""SPDXRef-RootPackage"", - ""downloadLocation"": ""NOASSERTION"", - ""packageVerificationCode"": { - ""packageVerificationCodeValue"": ""a2f8875f69c1b3814120e98bd3c0864e3c586a24"" - }, - ""filesAnalyzed"": true, - ""licenseConcluded"": ""NOASSERTION"", - ""licenseInfoFromFiles"": [ - ""NOASSERTION"" - ], - ""licenseDeclared"": ""NOASSERTION"", - ""versionInfo"": ""1208"", - ""supplier"": ""Organization: Microsoft"", - ""hasFiles"": [ - ""SPDXRef-File--package-services-metadata-core-properties-16e5bdb646ef44f485b1227d6d005f14.psmdcp-81EC7E121D7F03CDE59C8A4570A7D75C7EBB063A"", - ""SPDXRef-File--packages.config-69B7910C6FC95DB019934AA3BE0CDFDC3F3F2D8E"", - ""SPDXRef-File--pest.nuspec-A2EBA85861EAFD340496A9A7948D193284A19408"", - ""SPDXRef-File---rels-.rels-2DBE1B6566BFF9F17C259FB7D8B21231D4F11857"", - ""SPDXRef-File---Content-Types-.xml-EB0036B6C11A1AF694FA8ABACA0A4C43584225DE"" - ] - }]}"; - - public const string PackageJsonWith1PackageMissingVersionInfo = @"{ - ""packages"": [{ - ""name"": ""Testing cross platform signing"", - ""SPDXID"": ""SPDXRef-RootPackage"", - ""downloadLocation"": ""NOASSERTION"", - ""packageVerificationCode"": { - ""packageVerificationCodeValue"": ""a2f8875f69c1b3814120e98bd3c0864e3c586a24"" - }, - ""filesAnalyzed"": true, - ""licenseConcluded"": ""NOASSERTION"", - ""licenseInfoFromFiles"": [ - ""NOASSERTION"" - ], - ""licenseDeclared"": ""NOASSERTION"", - ""copyrightText"": ""NOASSERTION"", - ""supplier"": ""Organization: Microsoft"", - ""hasFiles"": [ - ""SPDXRef-File--package-services-metadata-core-properties-16e5bdb646ef44f485b1227d6d005f14.psmdcp-81EC7E121D7F03CDE59C8A4570A7D75C7EBB063A"", - ""SPDXRef-File--packages.config-69B7910C6FC95DB019934AA3BE0CDFDC3F3F2D8E"", - ""SPDXRef-File--pest.nuspec-A2EBA85861EAFD340496A9A7948D193284A19408"", - ""SPDXRef-File---rels-.rels-2DBE1B6566BFF9F17C259FB7D8B21231D4F11857"", - ""SPDXRef-File---Content-Types-.xml-EB0036B6C11A1AF694FA8ABACA0A4C43584225DE"" - ] - }], ""files"":[], ""relationships"":[]}"; - - public const string PackageJsonWith1PackageMissingSupplier = @"{ - ""packages"": [{ - ""name"": ""Testing cross platform signing"", - ""SPDXID"": ""SPDXRef-RootPackage"", - ""downloadLocation"": ""NOASSERTION"", - ""packageVerificationCode"": { - ""packageVerificationCodeValue"": ""a2f8875f69c1b3814120e98bd3c0864e3c586a24"" - }, - ""filesAnalyzed"": true, - ""licenseConcluded"": ""NOASSERTION"", - ""licenseInfoFromFiles"": [ - ""NOASSERTION"" - ], - ""licenseDeclared"": ""NOASSERTION"", - ""copyrightText"": ""NOASSERTION"", - ""versionInfo"": ""1208"", - ""hasFiles"": [ - ""SPDXRef-File--package-services-metadata-core-properties-16e5bdb646ef44f485b1227d6d005f14.psmdcp-81EC7E121D7F03CDE59C8A4570A7D75C7EBB063A"", - ""SPDXRef-File--packages.config-69B7910C6FC95DB019934AA3BE0CDFDC3F3F2D8E"", - ""SPDXRef-File--pest.nuspec-A2EBA85861EAFD340496A9A7948D193284A19408"", - ""SPDXRef-File---rels-.rels-2DBE1B6566BFF9F17C259FB7D8B21231D4F11857"", - ""SPDXRef-File---Content-Types-.xml-EB0036B6C11A1AF694FA8ABACA0A4C43584225DE"" - ] - }]}"; - - public const string MalformedJsonEmptyArray = @"{""files"": [], ""packages"": [], ""relationships"":[]}"; - - public const string GoodJsonWith3PackagesString = @"{ - ""packages"": [ - { - ""name"": ""pest"", - ""SPDXID"": ""SPDXRef-Package-1C4595D6D70121622649BB913859B18A3C0A2D49EC7D36279777025C4AC92303"", - ""downloadLocation"": ""NOASSERTION"", - ""filesAnalyzed"": false, - ""licenseConcluded"": ""NOASSERTION"", - ""licenseInfoFromFiles"": [ - ""NOASSERTION"" - ], - ""licenseDeclared"": ""NOASSERTION"", - ""copyrightText"": ""NOASSERTION"", - ""versionInfo"": ""1.0.0"", - ""externalRefs"": [ - { - ""referenceCategory"": ""PACKAGE_MANAGER"", - ""referenceType"": ""purl"", - ""referenceLocator"": ""pkg:nuget/pest%401.0.0"" - } - ], - ""supplier"": ""Organization: testa"" - }, - { - ""name"": ""Azure Pipelines Hosted Image win22"", - ""SPDXID"": ""SPDXRef-Package-8A7096C32BB7E49E0D8FEAB886ECEDDBF108DCBA505DD9E8AAB73C294F903EB2"", - ""downloadLocation"": ""NOASSERTION"", - ""filesAnalyzed"": false, - ""licenseConcluded"": ""NOASSERTION"", - ""licenseDeclared"": ""NOASSERTION"", - ""copyrightText"": ""NOASSERTION"", - ""versionInfo"": ""20220905.1"", - ""externalRefs"": [ - { - ""referenceCategory"": ""PACKAGE_MANAGER"", - ""referenceType"": ""purl"", - ""referenceLocator"": ""https://github.com/actions/virtual-environments"" - } - ], - ""supplier"": ""Organization: Microsoft/GitHub"" - }, - { - ""name"": ""Testing cross platform signing"", - ""SPDXID"": ""SPDXRef-RootPackage"", - ""downloadLocation"": ""NOASSERTION"", - ""packageVerificationCode"": { - ""packageVerificationCodeValue"": ""a2f8875f69c1b3814120e98bd3c0864e3c586a24"" - }, - ""filesAnalyzed"": true, - ""licenseConcluded"": ""NOASSERTION"", - ""licenseInfoFromFiles"": [ - ""NOASSERTION"" - ], - ""licenseDeclared"": ""NOASSERTION"", - ""copyrightText"": ""NOASSERTION"", - ""versionInfo"": ""1208"", - ""supplier"": ""Organization: Microsoft"", - ""hasFiles"": [ - ""SPDXRef-File--package-services-metadata-core-properties-16e5bdb646ef44f485b1227d6d005f14.psmdcp-81EC7E121D7F03CDE59C8A4570A7D75C7EBB063A"", - ""SPDXRef-File--packages.config-69B7910C6FC95DB019934AA3BE0CDFDC3F3F2D8E"", - ""SPDXRef-File--pest.nuspec-A2EBA85861EAFD340496A9A7948D193284A19408"", - ""SPDXRef-File---rels-.rels-2DBE1B6566BFF9F17C259FB7D8B21231D4F11857"", - ""SPDXRef-File---Content-Types-.xml-EB0036B6C11A1AF694FA8ABACA0A4C43584225DE"" - ] - }], ""files"":[], ""relationships"":[]}"; -} diff --git a/test/Microsoft.Sbom.Parsers.Spdx22SbomParser.Tests/Parser/Strings/SbomParserStrings.cs b/test/Microsoft.Sbom.Parsers.Spdx22SbomParser.Tests/Parser/Strings/SbomParserStrings.cs deleted file mode 100644 index e2a862e1..00000000 --- a/test/Microsoft.Sbom.Parsers.Spdx22SbomParser.Tests/Parser/Strings/SbomParserStrings.cs +++ /dev/null @@ -1,171 +0,0 @@ -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -namespace Microsoft.Sbom.Parser.Strings; - -internal readonly struct SbomParserStrings -{ - public const string JsonWithAll4Properties = @"{ - ""files"":[], - ""packages"":[], - ""testSkip1"":""testValue"", - ""testSkip2"":[], - ""relationships"":[], - ""testSkip3"":[""test"", ""test2""], - ""testSkip4"":[ - {""test1"":""val""}, - {""test2"":[{""test"":""final""}]}], - ""externalDocumentRefs"":[], - ""testSkip4"":{ - ""test"":{""rr"":22}}}"; - - public const string JsonWithMissingFiles = @"{ - ""packages"":[], - ""testSkip1"":""testValue"", - ""testSkip2"":[], - ""relationships"":[], - ""testSkip3"":[""test"", ""test2""], - ""testSkip4"":[ - {""test1"":""val""}, - {""test2"":[{""test"":""final""}]}], - ""externalDocumentRefs"":[], - ""testSkip4"":{ - ""test"":{""rr"":22}}}"; - - public const string JsonWithMissingPackages = @"{ - ""files"":[], - ""testSkip1"":""testValue"", - ""testSkip2"":[], - ""relationships"":[], - ""testSkip3"":[""test"", ""test2""], - ""testSkip4"":[ - {""test1"":""val""}, - {""test2"":[{""test"":""final""}]}], - ""externalDocumentRefs"":[], - ""testSkip4"":{ - ""test"":{""rr"":22}}}"; - - public const string JsonWithMissingRelationships = @"{ - ""files"":[], - ""packages"":[], - ""testSkip1"":""testValue"", - ""testSkip2"":[], - ""testSkip3"":[""test"", ""test2""], - ""testSkip4"":[ - {""test1"":""val""}, - {""test2"":[{""test"":""final""}]}], - ""externalDocumentRefs"":[], - ""testSkip4"":{ - ""test"":{""rr"":22}}}"; - - public const string JsonWithMissingReferences = @"{ - ""files"":[], - ""packages"":[], - ""testSkip1"":""testValue"", - ""testSkip2"":[], - ""relationships"":[], - ""testSkip3"":[""test"", ""test2""], - ""testSkip4"":[ - {""test1"":""val""}, - {""test2"":[{""test"":""final""}]}], - ""testSkip4"":{ - ""test"":{""rr"":22}}}"; - - public const string MalformedJson = @"{ - ""files"":[], - ""packages"":[], - ""testSkip1"":""testValue"", - ""testSkip2"":[], - ""relationships"":], - ""testSkip3"":[""test"", ""test2""], - ""testSkip4"":[ - {""test1"":""val""}, - {""test2"":[{""test"":""final""}]}], - ""externalDocumentRefs"":[], - ""testSkip4"":{ - ""test"":{""rr"":22}}}"; - - public const string MalformedJsonIncorrectFilesType = @"{ - ""files"":{}, - ""packages"":[], - ""testSkip1"":""testValue"", - ""testSkip2"":[], - ""relationships"":[], - ""testSkip3"":[""test"", ""test2""], - ""testSkip4"":[ - {""test1"":""val""}, - {""test2"":[{""test"":""final""}]}], - ""externalDocumentRefs"":[], - ""testSkip4"":{ - ""test"":{""rr"":22}}}"; - - public const string MalformedJsonIncorrectPackagesType = @"{ - ""files"":[], - ""packages"":{}, - ""testSkip1"":""testValue"", - ""testSkip2"":[], - ""relationships"":[], - ""testSkip3"":[""test"", ""test2""], - ""testSkip4"":[ - {""test1"":""val""}, - {""test2"":[{""test"":""final""}]}], - ""externalDocumentRefs"":[], - ""testSkip4"":{ - ""test"":{""rr"":22}}}"; - - public const string MalformedJsonIncorrectRefsType = @"{ - ""files"":[], - ""packages"":[], - ""testSkip1"":""testValue"", - ""testSkip2"":[], - ""relationships"":[], - ""testSkip3"":[""test"", ""test2""], - ""testSkip4"":[ - {""test1"":""val""}, - {""test2"":[{""test"":""final""}]}], - ""externalDocumentRefs"":{}, - ""testSkip4"":{ - ""test"":{""rr"":22}}}"; - - public const string MalformedJsonIncorrectRelationshipsType = @"{ - ""files"":[], - ""packages"":[], - ""testSkip1"":""testValue"", - ""testSkip2"":[], - ""relationships"":{}, - ""testSkip3"":[""test"", ""test2""], - ""testSkip4"":[ - {""test1"":""val""}, - {""test2"":[{""test"":""final""}]}], - ""externalDocumentRefs"":[], - ""testSkip4"":{ - ""test"":{""rr"":22}}}"; - - public const string MalformedJsonEmptyJsonObject = @"{ - ""files"":[], - ""packages"":[], - ""testSkip1"":""testValue"", - ""testSkip2"":[], - ""relationships"":[], - ""testSkip3"":[""test"", ""test2""], - ""testSkip4"":[ - {}, - {""test2"":[{""test"":""final""}]}], - ""externalDocumentRefs"":[], - ""testSkip4"":{ - ""test"":{""rr"":22}}}"; - - public const string MalformedJsonEmptyArrayObject = @"{ - ""files"":[], - ""packages"":[], - ""testSkip1"":""testValue"", - ""testSkip2"":[], - ""relationships"":[], - ""testSkip3"":[""test"", ""test2""], - ""testSkip4"":[ - {}, - {""test2"":[{""test"":""final""}]}], - ""externalDocumentRefs"":[], - ""testSkip4"":{ - ""test"":{""rr"":22}}}"; -} diff --git a/test/Microsoft.Sbom.Parsers.Spdx22SbomParser.Tests/Utils/InternalMetadataProviderIdentityExtensionsTests.cs b/test/Microsoft.Sbom.Parsers.Spdx22SbomParser.Tests/Utils/InternalMetadataProviderIdentityExtensionsTests.cs deleted file mode 100644 index 22195d59..00000000 --- a/test/Microsoft.Sbom.Parsers.Spdx22SbomParser.Tests/Utils/InternalMetadataProviderIdentityExtensionsTests.cs +++ /dev/null @@ -1,188 +0,0 @@ -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -using System; -using System.ComponentModel; -using System.Text.RegularExpressions; -using Microsoft.Sbom.Common; -using Microsoft.Sbom.Extensions; -using Microsoft.Sbom.Extensions.Entities; -using Microsoft.VisualStudio.TestTools.UnitTesting; -using Moq; - -namespace Microsoft.Sbom.Parsers.Spdx22SbomParser.Utils.Tests; - -[TestClass] -public class InternalMetadataProviderIdentityExtensionsTests -{ - [TestMethod] - public void GetGenerationTimestamp_Default_Test() - { - var mdProviderMock = new Mock(); - object time = null; - mdProviderMock.Setup(m => m.TryGetMetadata(MetadataKey.GenerationTimestamp, out time)) - .Returns(false); - - var timestamp = mdProviderMock.Object.GetGenerationTimestamp(); - - Assert.IsNotNull(timestamp); - var parsedDate = new DateTimeOffsetConverter().ConvertFromString(timestamp); - Assert.IsNotNull(parsedDate); - } - - [TestMethod] - public void GetGenerationTimestamp_Override_Test() - { - var mdProviderMock = new Mock(); - object time = "time"; - mdProviderMock.Setup(m => m.TryGetMetadata(MetadataKey.GenerationTimestamp, out time)) - .Returns(true); - - var timestamp = mdProviderMock.Object.GetGenerationTimestamp(); - - Assert.IsNotNull(timestamp); - Assert.IsTrue(timestamp.Equals("time")); - } - - [TestMethod] - public void GetPackageVersion_WherePackageVersionIsValid_ReturnPackageVersion() - { - var mdProviderMock = new Mock(); - var packageVersion = "version"; - - mdProviderMock.Setup(m => m.TryGetMetadata(MetadataKey.PackageVersion, out packageVersion)) - .Returns(true); - - var actualPackageVersion = mdProviderMock.Object.GetPackageVersion(); - - Assert.AreEqual(packageVersion, actualPackageVersion); - } - - [TestMethod] - [DataRow(null, false)] - [DataRow("", false)] - [DataRow(" ", false)] - public void GetPackageVersion_WherePackageVersionIsNullOrWhitespace_ReturnBuildId(string packageVersion, bool versionExist) - { - var buildId = "buildId"; - var mdProviderMock = new Mock(); - - mdProviderMock.Setup(m => m.TryGetMetadata(MetadataKey.PackageVersion, out packageVersion)) - .Returns(versionExist); - mdProviderMock.Setup(m => m.TryGetMetadata(MetadataKey.Build_BuildId, out buildId)) - .Returns(true); - - var actualPackageVersion = mdProviderMock.Object.GetPackageVersion(); - - Assert.AreEqual(buildId, actualPackageVersion); - } - - [TestMethod] - [DataRow(null, false)] - [DataRow("", false)] - [DataRow(" ", false)] - public void GetPackageVersion_WherePackageVersionAndBuildIdIsInvalid_Throw(string buildId, bool buildIdExist) - { - string packageVersion = null; - var mdProviderMock = new Mock(); - - mdProviderMock.Setup(m => m.TryGetMetadata(MetadataKey.PackageVersion, out packageVersion)) - .Returns(false); - mdProviderMock.Setup(m => m.TryGetMetadata(MetadataKey.Build_BuildId, out buildId)) - .Returns(buildIdExist); - - try - { - var actualPackageVersion = mdProviderMock.Object.GetPackageVersion(); - Assert.Fail(); - } - catch (Exception e) - { - Assert.AreEqual(typeof(ArgumentException), e.GetType()); - } - } - - [TestMethod] - public void GetPackageName_WherePackageNameIsValid_ReturnPackageName() - { - var mdProviderMock = new Mock(); - var packageName = "name"; - - mdProviderMock.Setup(m => m.TryGetMetadata(MetadataKey.PackageName, out packageName)) - .Returns(true); - - var actualPackageName = mdProviderMock.Object.GetPackageName(); - - Assert.AreEqual(packageName, actualPackageName); - } - - [TestMethod] - [DataRow(null, false)] - [DataRow("", false)] - [DataRow(" ", false)] - public void GetPackageName_WherePackageNameIsNullOrWhitespace_ReturnBuildDef(string packageName, bool nameExist) - { - var buildDef = "buildDef"; - var mdProviderMock = new Mock(); - - mdProviderMock.Setup(m => m.TryGetMetadata(MetadataKey.PackageVersion, out packageName)) - .Returns(nameExist); - mdProviderMock.Setup(m => m.TryGetMetadata(MetadataKey.Build_DefinitionName, out buildDef)) - .Returns(true); - - var actualPackageName = mdProviderMock.Object.GetPackageName(); - - Assert.AreEqual(buildDef, actualPackageName); - } - - [TestMethod] - [DataRow(null, false)] - [DataRow("", false)] - [DataRow(" ", false)] - public void GetPackageName_WherePackageNameAndBuildDefIsInvalid_Throw(string buildDef, bool buildDefExist) - { - string packageVersion = null; - var mdProviderMock = new Mock(); - - mdProviderMock.Setup(m => m.TryGetMetadata(MetadataKey.PackageName, out packageVersion)) - .Returns(false); - mdProviderMock.Setup(m => m.TryGetMetadata(MetadataKey.Build_BuildId, out buildDef)) - .Returns(buildDefExist); - - try - { - var actualPackageVersion = mdProviderMock.Object.GetPackageName(); - Assert.Fail(); - } - catch (Exception e) - { - Assert.AreEqual(typeof(ArgumentException), e.GetType()); - } - } - - [TestMethod] - public void GetSwidPurl_Succeeds() - { - var mdProviderMock = new Mock(); - var tagId = Guid.NewGuid(); - - var packageName = "name"; - var packageVersion = "1.0.0"; - object packageSupplier = "Microsoft"; - var namespaceUri = new Uri("https://test.com/"); - var expectedSwidPurlPattern = @"^pkg:swid\/Microsoft\/test.com\/name@1\.0\.0\?tag_id=.*"; - - mdProviderMock.Setup(m => m.TryGetMetadata(MetadataKey.PackageSupplier, out packageSupplier)) - .Returns(true); - mdProviderMock.Setup(m => m.TryGetMetadata(MetadataKey.PackageVersion, out packageVersion)) - .Returns(true); - mdProviderMock.Setup(m => m.TryGetMetadata(MetadataKey.PackageName, out packageName)) - .Returns(true); - mdProviderMock.Setup(m => m.GetSBOMNamespaceUri()) - .Returns(namespaceUri.ToString); - - var actualSwidPurl = mdProviderMock.Object.GetSwidTagId(); - - Assert.IsTrue(Regex.IsMatch(actualSwidPurl, expectedSwidPurlPattern)); - } -} diff --git a/test/Microsoft.Sbom.Parsers.Spdx22SbomParser.Tests/Utils/SPDXExtensionsTest.cs b/test/Microsoft.Sbom.Parsers.Spdx22SbomParser.Tests/Utils/SPDXExtensionsTest.cs deleted file mode 100644 index eaf025e0..00000000 --- a/test/Microsoft.Sbom.Parsers.Spdx22SbomParser.Tests/Utils/SPDXExtensionsTest.cs +++ /dev/null @@ -1,157 +0,0 @@ -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text.RegularExpressions; -using Microsoft.Sbom.Contracts; -using Microsoft.Sbom.Contracts.Enums; -using Microsoft.Sbom.Parsers.Spdx22SbomParser.Entities; -using Microsoft.Sbom.Parsers.Spdx22SbomParser.Entities.Enums; -using Microsoft.Sbom.Parsers.Spdx22SbomParser.Utils; -using Microsoft.VisualStudio.TestTools.UnitTesting; -using Checksum = Microsoft.Sbom.Contracts.Checksum; - -namespace SPDX22SBOMParserTest; - -[TestClass] -public class SPDXExtensionsTest -{ - private const string PackageUrl = "packageUrl"; - private readonly Regex spdxIdAllowedCharsRegex = new Regex("^[a-zA-Z0-9]*$"); - - private SPDXPackage spdxPackage = new SPDXPackage(); - private SbomPackage packageInfo = new SbomPackage(); - - [TestInitialize] - public void Setup() - { - spdxPackage = new SPDXPackage - { - Name = "packageName", - VersionInfo = "1.0.0" - }; - packageInfo = new SbomPackage - { - PackageUrl = PackageUrl - }; - } - - [TestMethod] - public void AddPackageUrlsTest_Success() - { - spdxPackage.AddPackageUrls(packageInfo); - var externalRef = spdxPackage.ExternalReferences.First(); - Assert.AreEqual(ReferenceCategory.PACKAGE_MANAGER.ToNormalizedString(), externalRef.ReferenceCategory); - - // ExternalRepositoryTypes are deserialized as strings for portability when handling 3P SBOMs, - // but in the context of this test we expect the value to align with a known enum value. So - // convert to enum for comparison. - Enum.TryParse(externalRef.Type, out var refType); - Assert.AreEqual(ExternalRepositoryType.purl, refType); - Assert.AreEqual(PackageUrl, externalRef.Locator); - } - - [TestMethod] - public void AddPackageUrlsTest_WithNullPackageInfo_Success() - { - spdxPackage.AddPackageUrls(null); - Assert.IsNull(spdxPackage.ExternalReferences); - } - - [TestMethod] - public void AddPackageUrlsTest_WithNullPackageUrl_Success() - { - packageInfo.PackageUrl = null; - spdxPackage.AddPackageUrls(packageInfo); - Assert.IsNull(spdxPackage.ExternalReferences); - } - - [TestMethod] - public void AddPackageUrlsTest_WithNonNullExternalRef_Success() - { - packageInfo.PackageUrl = null; - spdxPackage.ExternalReferences = new List(); - spdxPackage.AddPackageUrls(packageInfo); - Assert.AreEqual(0, spdxPackage.ExternalReferences.Count()); - } - - [DataTestMethod] - [DataRow("pkg:npm/glob@7.1.6", "pkg:npm/glob@7.1.6")] - [DataRow("https://github.com/actions/virtual-environments", "https://github.com/actions/virtual-environments")] - - public void AddPackageUrlsTest_WithSpecialCharacter_Success(string inputUrl, string expectedUrl) - { - spdxPackage = new SPDXPackage(); - spdxPackage.AddPackageUrls(new SbomPackage { PackageUrl = inputUrl }); - - var externalRef = spdxPackage.ExternalReferences.First(); - - Assert.AreEqual(ReferenceCategory.PACKAGE_MANAGER.ToNormalizedString(), externalRef.ReferenceCategory); - - // ExternalRepositoryTypes are deserialized as strings for portability when handling 3P SBOMs, - // but in the context of this test we expect the value to align with a known enum value. So - // convert to enum for comparison. - Enum.TryParse(externalRef.Type, out var refType); - Assert.AreEqual(ExternalRepositoryType.purl, refType); - Assert.AreEqual(expectedUrl, externalRef.Locator); - } - - [TestMethod] - public void AddPackageUrlsTest_WithNullSPDXPackage_Failure() - { - spdxPackage = null; - Assert.ThrowsException(() => spdxPackage.AddPackageUrls(packageInfo)); - } - - [TestMethod] - public void AddExternalReferenceSPDXID() - { - var name = "test"; - var hash = "ea70261b02144d5234ae990fa0ca4e0bcd8dc2a9"; - var checksum = new Checksum { Algorithm = AlgorithmName.SHA1, ChecksumValue = hash }; - - var reference = new SpdxExternalDocumentReference(); - var id = reference.AddExternalReferenceSpdxId(name, new Checksum[] { checksum }); - Assert.AreEqual(reference.ExternalDocumentId, id); - Assert.AreEqual(id, $"DocumentRef-{name}-{hash}"); - } - - [TestMethod] - public void AddSpdxIdTest_SpdxPackage_Success() - { - var spdxIdPrefex = "SPDXRef-Package-"; - spdxPackage.SpdxId = null; - - var spdxId = spdxPackage.AddSpdxId(packageInfo); - - Assert.AreEqual(spdxId, spdxPackage.SpdxId); - Assert.IsTrue(spdxId.StartsWith(spdxIdPrefex, StringComparison.Ordinal)); - Assert.IsTrue(spdxIdAllowedCharsRegex.IsMatch(spdxId.Split(spdxIdPrefex)[1])); - } - - [TestMethod] - public void AddSpdxIdTest_SpdxFile_Success() - { - var spdxFile = new SPDXFile { SPDXId = null }; - var fileName = "theFileName.txt"; - var checksums = new Checksum[] { new Checksum { Algorithm = AlgorithmName.SHA1, ChecksumValue = "the-hash-value" } }; - - var spdxId = spdxFile.AddSpdxId(fileName, checksums); - - Assert.AreEqual(spdxId, spdxFile.SPDXId); - } - - [TestMethod] - public void ReferenceCategoryToNormalizedString_DoesNotContainUnderscore() - { - foreach (ReferenceCategory referenceCategory in Enum.GetValues(typeof(ReferenceCategory))) - { - var value = referenceCategory.ToNormalizedString(); - Assert.IsFalse( - value.Contains('_'), - $"The value {value} of the {nameof(ReferenceCategory)} enum contains an underscore character."); - } - } -} diff --git a/test/Microsoft.Sbom.Parsers.Spdx22SbomParser.Tests/Utils/SbomFormatConverterTests.cs b/test/Microsoft.Sbom.Parsers.Spdx22SbomParser.Tests/Utils/SbomFormatConverterTests.cs deleted file mode 100644 index 1786ec1c..00000000 --- a/test/Microsoft.Sbom.Parsers.Spdx22SbomParser.Tests/Utils/SbomFormatConverterTests.cs +++ /dev/null @@ -1,52 +0,0 @@ -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -using System.Collections.Generic; -using Microsoft.Sbom.JsonAsynchronousNodeKit.Exceptions; -using Microsoft.Sbom.Parsers.Spdx22SbomParser.Entities; -using Microsoft.Sbom.Utils; -using Microsoft.VisualStudio.TestTools.UnitTesting; - -namespace Microsoft.Sbom.Parsers.Spdx22SbomParser.Utils.Tests; - -[TestClass] -public class SbomFormatConverterTests -{ - [TestMethod] - public void ToSbomPackage_HappyPath() - { - var spdxPackage = new SPDXPackage - { - Name = "name", - SpdxId = "spdxId", - LicenseConcluded = "licenseConcluded", - LicenseDeclared = "licenseDeclared", - CopyrightText = "copyright", - Supplier = "supplier", - }; - - var sbomPackage = spdxPackage.ToSbomPackage(); - - Assert.IsNotNull(sbomPackage); - Assert.AreEqual(spdxPackage.Name, sbomPackage.PackageName); - Assert.AreEqual(spdxPackage.SpdxId, sbomPackage.Id); - } - - [TestMethod] - public void ToSbomPackage_FailsOnEmptyLicenseInfo() - { - var spdxPackage = new SPDXPackage - { - Name = "name", - SpdxId = "spdxId", - LicenseConcluded = "licenseConcluded", - LicenseDeclared = "licenseDeclared", - CopyrightText = "copyright", - Supplier = "supplier", - FilesAnalyzed = true, - LicenseInfoFromFiles = new List(), - }; - - Assert.ThrowsException(spdxPackage.ToSbomPackage); - } -} diff --git a/test/Microsoft.Sbom.Parsers.Spdx30SbomParser.Tests/Microsoft.Sbom.Parsers.Spdx30SbomParser.Tests.csproj b/test/Microsoft.Sbom.Parsers.Spdx30SbomParser.Tests/Microsoft.Sbom.Parsers.Spdx30SbomParser.Tests.csproj deleted file mode 100644 index 4b348b38..00000000 --- a/test/Microsoft.Sbom.Parsers.Spdx30SbomParser.Tests/Microsoft.Sbom.Parsers.Spdx30SbomParser.Tests.csproj +++ /dev/null @@ -1,17 +0,0 @@ - - - - false - $(NoWarn);NU1605 - Microsoft.Sbom.Parsers.Spdx30SbomParser.Tests - True - $(StrongNameSigningKeyFilePath) - - - - - - - - - diff --git a/test/Microsoft.Sbom.Parsers.Spdx30SbomParser.Tests/Parser/GeneratorTests.cs b/test/Microsoft.Sbom.Parsers.Spdx30SbomParser.Tests/Parser/GeneratorTests.cs deleted file mode 100644 index 3055ada9..00000000 --- a/test/Microsoft.Sbom.Parsers.Spdx30SbomParser.Tests/Parser/GeneratorTests.cs +++ /dev/null @@ -1,237 +0,0 @@ -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -using System.Collections.Generic; -using System.Text.RegularExpressions; -using Microsoft.Sbom.Api.Manifest.Configuration; -using Microsoft.Sbom.Api.Metadata; -using Microsoft.Sbom.Api.Output.Telemetry; -using Microsoft.Sbom.Api.Recorder; -using Microsoft.Sbom.Common; -using Microsoft.Sbom.Common.Config; -using Microsoft.Sbom.Contracts; -using Microsoft.Sbom.Contracts.Enums; -using Microsoft.Sbom.Extensions; -using Microsoft.Sbom.Extensions.Entities; -using Microsoft.Sbom.Parser.JsonStrings; -using Microsoft.Sbom.Parsers.Spdx30SbomParser; -using Microsoft.VisualStudio.TestTools.UnitTesting; -using Moq; -using Constants = Microsoft.Sbom.Parsers.Spdx30SbomParser.Constants; -using ILogger = Serilog.ILogger; - -namespace Microsoft.Sbom.Parser; - -[TestClass] -public class GeneratorTests -{ - private readonly Generator generator = new Generator(); - private readonly Mock recorderMock = new Mock(MockBehavior.Strict); - private readonly Mock mockLogger = new Mock(MockBehavior.Strict); - private readonly Mock fileSystemMock = new Mock(MockBehavior.Strict); - private readonly Mock mockConfigHandler = new Mock(MockBehavior.Strict); - - [TestMethod] - public void GenerateJsonDocumentTest_DocumentCreation() - { - var sbomConfigs = CreateInternalMetadataProvider(); - var generatorResult = generator.GenerateJsonDocument(sbomConfigs); - var generatedJsonString = generatorResult.Document.RootElement.GetRawText(); - generatedJsonString = NormalizeString(generatedJsonString); - - var expectedJsonContentAsString = SbomDocCreationJsonStrings.DocCreationJsonString; - expectedJsonContentAsString = NormalizeString(expectedJsonContentAsString); - var regexPattern = ConvertJsonToRegex(expectedJsonContentAsString); - - Assert.IsFalse(generatedJsonString.Contains("null")); - Assert.IsTrue(Regex.IsMatch(generatedJsonString, regexPattern)); - } - - [TestMethod] - public void GenerateJsonDocumentTest_RootPackage() - { - var sbomConfigs = CreateInternalMetadataProvider(); - - var generatorResult = generator.GenerateRootPackage(sbomConfigs); - var generatedJsonString = generatorResult.Document.RootElement.GetRawText(); - generatedJsonString = NormalizeString(generatedJsonString); - - var expectedJsonContentAsString = SbomPackageJsonStrings.RootPackageJsonString; - expectedJsonContentAsString = NormalizeString(expectedJsonContentAsString); - var regexPattern = ConvertJsonToRegex(expectedJsonContentAsString); - - Assert.IsFalse(generatedJsonString.Contains("null")); - Assert.IsTrue(Regex.IsMatch(generatedJsonString, regexPattern)); - } - - [TestMethod] - public void GenerateJsonDocumentTest_Package() - { - var packageInfo = new SbomPackage - { - PackageName = "test", - PackageUrl = "packageUrl", - FilesAnalyzed = false - }; - - var generatorResult = generator.GenerateJsonDocument(packageInfo); - var generatedJsonString = generatorResult.Document.RootElement.GetRawText(); - generatedJsonString = NormalizeString(generatedJsonString); - - var expectedJsonContentAsString = SbomPackageJsonStrings.PackageWithNoAssertionAndPurlJsonString; - expectedJsonContentAsString = NormalizeString(expectedJsonContentAsString); - - Assert.IsFalse(generatedJsonString.Contains("null")); - Assert.AreEqual(expectedJsonContentAsString, generatedJsonString); - } - - [TestMethod] - public void GenerateJsonDocumentTest_File() - { - var fileInfo = new InternalSbomFileInfo - { - Checksum = GetSampleChecksums(), - FileCopyrightText = "sampleCopyright", - LicenseConcluded = "sampleLicense1", - LicenseInfoInFiles = new List { "sampleLicense1" }, - Path = "/sample/path", - }; - - var generatorResult = generator.GenerateJsonDocument(fileInfo); - var generatedJsonString = generatorResult.Document.RootElement.GetRawText(); - generatedJsonString = NormalizeString(generatedJsonString); - - var expectedJsonContentAsString = SbomFileJsonStrings.FileWithLicensesAndHashes; - expectedJsonContentAsString = NormalizeString(expectedJsonContentAsString); - - Assert.IsFalse(generatedJsonString.Contains("null")); - Assert.AreEqual(expectedJsonContentAsString, generatedJsonString); - } - - [TestMethod] - public void GenerateJsonDocumentTest_ExternalMap() - { - var externalDocInfo = new ExternalDocumentReferenceInfo - { - DocumentNamespace = "sample-namespace", - Checksum = GetSampleChecksums(), - ExternalDocumentName = "sample-external-doc", - }; - - var generatorResult = generator.GenerateJsonDocument(externalDocInfo); - var generatedJsonString = generatorResult.Document.RootElement.GetRawText(); - generatedJsonString = NormalizeString(generatedJsonString); - - var expectedJsonContentAsString = SbomExternalMapJsonStrings.ExternalMapJsonString; - expectedJsonContentAsString = NormalizeString(expectedJsonContentAsString); - - Assert.IsFalse(generatedJsonString.Contains("null")); - Assert.AreEqual(expectedJsonContentAsString, generatedJsonString); - } - - [TestMethod] - public void GenerateJsonDocumentTest_Relationship() - { - var relationshipInfo = new Relationship - { - SourceElementId = "source-id", - TargetElementId = "target-id", - RelationshipType = RelationshipType.DESCRIBES, - }; - - var generatorResult = generator.GenerateJsonDocument(relationshipInfo); - var generatedJsonString = generatorResult.Document.RootElement.GetRawText(); - generatedJsonString = NormalizeString(generatedJsonString); - - var expectedJsonContentAsString = SbomRelationshipJsonStrings.RelationshipJsonString; - expectedJsonContentAsString = NormalizeString(expectedJsonContentAsString); - - Assert.IsFalse(generatedJsonString.Contains("null")); - Assert.AreEqual(expectedJsonContentAsString, generatedJsonString); - } - - [TestCleanup] - public void Cleanup() - { - recorderMock.VerifyAll(); - mockLogger.VerifyAll(); - fileSystemMock.VerifyAll(); - mockConfigHandler.VerifyAll(); - } - - private string NormalizeString(string input) - { - return input.Replace("\r", string.Empty) - .Replace("\n", string.Empty) - .Replace(" ", string.Empty); - } - - private string ConvertJsonToRegex(string input) - { - var pattern = Regex.Escape(input); - - // Replace placeholders with appropriate regex patterns - pattern = pattern.Replace(@"\.\*", ".*"); - return pattern; - } - - private List GetSampleChecksums() - { - return new List - { - new Checksum - { - Algorithm = AlgorithmName.SHA1, - ChecksumValue = "sha1Value" - }, new Checksum - { - Algorithm = AlgorithmName.SHA256, - ChecksumValue = "sha256Value" - }, - }; - } - - private IInternalMetadataProvider CreateInternalMetadataProvider() - { - ISbomConfig sbomConfig = new SbomConfig(fileSystemMock.Object) - { - ManifestInfo = Constants.Spdx30ManifestInfo, - Recorder = new SbomPackageDetailsRecorder() - }; - - mockConfigHandler.Setup(c => c.TryGetManifestConfig(out sbomConfig)).Returns(true); - recorderMock.Setup(r => r.RecordSBOMFormat(Constants.Spdx30ManifestInfo, It.IsAny())); - mockLogger.Setup(l => l.Debug(It.IsAny())); - - var config = new Configuration - { - PackageName = new ConfigurationSetting("the-package-name"), - PackageVersion = new ConfigurationSetting("the-package-version"), - NamespaceUriUniquePart = new ConfigurationSetting("some-custom-value-here"), - NamespaceUriBase = new ConfigurationSetting("http://sbom.microsoft"), - PackageSupplier = new ConfigurationSetting("the-package-supplier"), - }; - - var sbomMetadata = new SBOMMetadata - { - PackageName = "sbom-package-name", - PackageVersion = "sbom-package-version", - BuildEnvironmentName = "the-build-envsdfgsdg", - }; - - var localMetadataProvider = new LocalMetadataProvider(config); - - var sbomApiMetadataProvider = new SBOMApiMetadataProvider(sbomMetadata, config); - var metadataProviders = new IMetadataProvider[] { localMetadataProvider, sbomApiMetadataProvider }; - IInternalMetadataProvider sbomConfigs = CreateSbomConfigs(metadataProviders); - - return sbomConfigs; - } - - private ISbomConfigProvider CreateSbomConfigs(IMetadataProvider[] metadataProviders) => - new SbomConfigProvider( - manifestConfigHandlers: new IManifestConfigHandler[] { mockConfigHandler.Object }, - metadataProviders: metadataProviders, - logger: mockLogger.Object, - recorder: recorderMock.Object); -} diff --git a/test/Microsoft.Sbom.Parsers.Spdx30SbomParser.Tests/Parser/JsonStrings/SbomDocCreationJsonStrings.cs b/test/Microsoft.Sbom.Parsers.Spdx30SbomParser.Tests/Parser/JsonStrings/SbomDocCreationJsonStrings.cs deleted file mode 100644 index 1394e2c4..00000000 --- a/test/Microsoft.Sbom.Parsers.Spdx30SbomParser.Tests/Parser/JsonStrings/SbomDocCreationJsonStrings.cs +++ /dev/null @@ -1,74 +0,0 @@ -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -namespace Microsoft.Sbom.Parser.JsonStrings; - -public static class SbomDocCreationJsonStrings -{ - [System.Diagnostics.CodeAnalysis.SuppressMessage("Style", "JSON002:Probable JSON string detected", Justification = "Need to use JSON string")] - public const string DocCreationJsonString = - @"[ - { - ""creationInfo"": ""_:creationinfo"", - ""name"": ""the-package-supplier"", - ""spdxId"": ""SPDXRef-Organization-4B8D792FFFFCD3AF92D53A739B6DF98DF2B1F367C2745DDC0085B30F51EBBC81"", - ""type"": ""Organization"" - }, - { - ""creationInfo"": ""_:creationinfo"", - ""name"": ""Microsoft.SBOMTool-.*"", - ""spdxId"": ""SPDXRef-Tool-.*"", - ""type"": ""Tool"" - }, - { - ""@id"": ""_:creationinfo"", - ""created"": "".*"", - ""createdBy"": [ - ""SPDXRef-Organization-4B8D792FFFFCD3AF92D53A739B6DF98DF2B1F367C2745DDC0085B30F51EBBC81"" - ], - ""createdUsing"": [ - ""SPDXRef-Tool-.*"" - ], - ""specVersion"": ""3.0"", - ""creationInfo"": ""_:creationinfo"", - ""spdxId"": ""SPDXRef-CreationInfo-0799B4D592549CF6159C30BA3E278BF063A6A241B8728C18E7AEC18BFC2CFF6F"", - ""type"": ""CreationInfo"" - }, - { - ""creationInfo"": ""_:creationinfo"", - ""name"": ""CC0-1.0"", - ""spdxId"": ""SPDXRef-AnyLicenseInfo-6E237C55B0583CB7BBA05562316C54B0A105ABA04775017E2253237B9A64613C"", - ""type"": ""AnyLicenseInfo"" - }, - { - ""dataLicense"": ""SPDXRef-AnyLicenseInfo-6E237C55B0583CB7BBA05562316C54B0A105ABA04775017E2253237B9A64613C"", - ""namespaceMap"": [ - { - ""namespace"": ""http://sbom.microsoft/sbom-package-name/sbom-package-version/some-custom-value-here"", - ""creationInfo"": ""_:creationinfo"", - ""spdxId"": ""SPDXRef-NamespaceMap-0C5D68EB49795A98E060EB263AC73F87322217857EB3057EBAC84A70F75E69BE"", - ""type"": ""NamespaceMap"" - } - ], - ""profileConformance"": [ - ""software"", - ""core"", - ""simpleLicensing"" - ], - ""creationInfo"": ""_:creationinfo"", - ""name"": ""the-package-namethe-package-version"", - ""spdxId"": ""SPDXRef-SpdxDocument-B93EED20C16A89A887B753958D42B794DD3C6570D3C2725B56B43477B38E05A1"", - ""type"": ""SpdxDocument"" - }, - { - ""from"": ""SPDXRef-AnyLicenseInfo-6E237C55B0583CB7BBA05562316C54B0A105ABA04775017E2253237B9A64613C"", - ""relationshipType"": ""HAS_DECLARED_LICENSE"", - ""to"": [ - ""SPDXRef-SpdxDocument-B93EED20C16A89A887B753958D42B794DD3C6570D3C2725B56B43477B38E05A1"" - ], - ""creationInfo"": ""_:creationinfo"", - ""spdxId"": ""SPDXRef-Relationship-222E099165617B282F2B424519FC133796AA0189D0238FD121CCF3B0340D4301"", - ""type"": ""Relationship"" - } - ]"; -} diff --git a/test/Microsoft.Sbom.Parsers.Spdx30SbomParser.Tests/Parser/JsonStrings/SbomExternalMapJsonStrings.cs b/test/Microsoft.Sbom.Parsers.Spdx30SbomParser.Tests/Parser/JsonStrings/SbomExternalMapJsonStrings.cs deleted file mode 100644 index ba5db4d0..00000000 --- a/test/Microsoft.Sbom.Parsers.Spdx30SbomParser.Tests/Parser/JsonStrings/SbomExternalMapJsonStrings.cs +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -namespace Microsoft.Sbom.Parser.JsonStrings; - -public static class SbomExternalMapJsonStrings -{ - [System.Diagnostics.CodeAnalysis.SuppressMessage("Style", "JSON002:Probable JSON string detected", Justification = "Need to use JSON string")] - public const string ExternalMapJsonString = - @" - { - ""externalSpdxId"": ""DocumentRef-sample-external-doc-sha1Value"", - ""creationInfo"": ""_:creationinfo"", - ""spdxId"": ""SPDXRef-ExternalMap-2AB84930C880E9632BC8FCFBC0BA22D66E2912252D3457ACB89A9DDE4745E2D0"", - ""verifiedUsing"": [ - { - ""algorithm"": ""sha1"", - ""hashValue"": ""sha1value"", - ""creationInfo"": ""_:creationinfo"", - ""spdxId"": ""SPDXRef-PackageVerificationCode-B1565820A5CDAC40E0520D23F9D0B1497F240DDC51D72EAC6423D97D952D444F"", - ""type"": ""PackageVerificationCode"" - } - ], - ""type"": ""ExternalMap"" - }"; -} diff --git a/test/Microsoft.Sbom.Parsers.Spdx30SbomParser.Tests/Parser/JsonStrings/SbomFileJsonStrings.cs b/test/Microsoft.Sbom.Parsers.Spdx30SbomParser.Tests/Parser/JsonStrings/SbomFileJsonStrings.cs deleted file mode 100644 index c05bc2a9..00000000 --- a/test/Microsoft.Sbom.Parsers.Spdx30SbomParser.Tests/Parser/JsonStrings/SbomFileJsonStrings.cs +++ /dev/null @@ -1,61 +0,0 @@ -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -namespace Microsoft.Sbom.Parser.JsonStrings; - -public static class SbomFileJsonStrings -{ - [System.Diagnostics.CodeAnalysis.SuppressMessage("Style", "JSON002:Probable JSON string detected", Justification = "Need to use JSON string")] - public const string FileWithLicensesAndHashes = - @"[ - { - ""CopyrightText"": ""sampleCopyright"", - ""creationInfo"": ""_:creationinfo"", - ""name"": ""./sample/path"", - ""spdxId"": ""SPDXRef-software_File-B4A9F99A3A03B9273AE34753D96564CB4F2B0FAD885BBD36B0DD619E9E8AC967"", - ""verifiedUsing"": [ - { - ""algorithm"": ""sha1"", - ""hashValue"": ""sha1value"", - ""creationInfo"": ""_:creationinfo"", - ""spdxId"": ""SPDXRef-PackageVerificationCode-B1565820A5CDAC40E0520D23F9D0B1497F240DDC51D72EAC6423D97D952D444F"", - ""type"": ""PackageVerificationCode"" - }, - { - ""algorithm"": ""sha256"", - ""hashValue"": ""sha256value"", - ""creationInfo"": ""_:creationinfo"", - ""spdxId"": ""SPDXRef-PackageVerificationCode-5D5B09F6DCB2D53A5FFFC60C4AC0D55FABDF556069D6631545F42AA6E3500F2E"", - ""type"": ""PackageVerificationCode"" - } - ], - ""type"": ""software_File"" - }, - { - ""creationInfo"": ""_:creationinfo"", - ""name"": ""sampleLicense1"", - ""spdxId"": ""SPDXRef-AnyLicenseInfo-3BA3FA6D3D66FE2BA75992BB0850D080F1223256368A76C77BEF8E0F6AC71896"", - ""type"": ""AnyLicenseInfo"" - }, - { - ""from"": ""SPDXRef-software_File-B4A9F99A3A03B9273AE34753D96564CB4F2B0FAD885BBD36B0DD619E9E8AC967"", - ""relationshipType"": ""HAS_CONCLUDED_LICENSE"", - ""to"": [ - ""SPDXRef-AnyLicenseInfo-3BA3FA6D3D66FE2BA75992BB0850D080F1223256368A76C77BEF8E0F6AC71896"" - ], - ""creationInfo"": ""_:creationinfo"", - ""spdxId"": ""SPDXRef-Relationship-2A69D50DCB6D763C5C4FFCE6A4F6C3166DD8F6DB3F77BDD4B6129C0B33F238DA"", - ""type"": ""Relationship"" - }, - { - ""from"": ""SPDXRef-software_File-B4A9F99A3A03B9273AE34753D96564CB4F2B0FAD885BBD36B0DD619E9E8AC967"", - ""relationshipType"": ""HAS_DECLARED_LICENSE"", - ""to"": [ - ""SPDXRef-AnyLicenseInfo-3BA3FA6D3D66FE2BA75992BB0850D080F1223256368A76C77BEF8E0F6AC71896"" - ], - ""creationInfo"": ""_:creationinfo"", - ""spdxId"": ""SPDXRef-Relationship-222E099165617B282F2B424519FC133796AA0189D0238FD121CCF3B0340D4301"", - ""type"": ""Relationship"" - } - ]"; -} diff --git a/test/Microsoft.Sbom.Parsers.Spdx30SbomParser.Tests/Parser/JsonStrings/SbomPackageJsonStrings.cs b/test/Microsoft.Sbom.Parsers.Spdx30SbomParser.Tests/Parser/JsonStrings/SbomPackageJsonStrings.cs deleted file mode 100644 index 15f89746..00000000 --- a/test/Microsoft.Sbom.Parsers.Spdx30SbomParser.Tests/Parser/JsonStrings/SbomPackageJsonStrings.cs +++ /dev/null @@ -1,134 +0,0 @@ -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -namespace Microsoft.Sbom.Parser.JsonStrings; - -public static class SbomPackageJsonStrings -{ - public const string PackageWithNoAssertionAndPurlJsonString = - /*lang=json,strict*/ - @"[ - { - ""creationInfo"": ""_:creationinfo"", - ""name"": ""NOASSERTION"", - ""spdxId"": ""SPDXRef-Organization-8560FC6692684D8DF52223FF78E30B9630A1CF5A6FA371AAE24FCA896AE20969"", - ""type"": ""Organization"" - }, - { - ""suppliedBy"": ""SPDXRef-Organization-8560FC6692684D8DF52223FF78E30B9630A1CF5A6FA371AAE24FCA896AE20969"", - ""CopyrightText"": ""NOASSERTION"", - ""software_downloadLocation"": ""NOASSERTION"", - ""creationInfo"": ""_:creationinfo"", - ""externalIdentifier"": [ - ""SPDXRef-ExternalIdentifier-CE6B7E4A59503594D0AF89492494E05071399F36D9085F1E722497D78A9404E1"" - ], - ""name"": ""test"", - ""spdxId"": ""SPDXRef-software_Package-4739C82D88855A138C811B8CE05CC97113BEC7F7C7F66EC7E4C6C176EEA0FECE"", - ""type"": ""software_Package"" - }, - { - ""externalIdentifierType"": ""purl"", - ""identifier"": ""packageUrl"", - ""creationInfo"": ""_:creationinfo"", - ""spdxId"": ""SPDXRef-ExternalIdentifier-CE6B7E4A59503594D0AF89492494E05071399F36D9085F1E722497D78A9404E1"", - ""type"": ""ExternalIdentifier"" - }, - { - ""creationInfo"": ""_:creationinfo"", - ""name"": ""NoAssertion"", - ""spdxId"": ""SPDXRef-Element-D6D57C0C9CC2CAC35C83DE0C8E4C8C37B87C0A58DA49BB31EBEBC6E200F54D4B"", - ""type"": ""Element"" - }, - { - ""from"": ""SPDXRef-software_Package-4739C82D88855A138C811B8CE05CC97113BEC7F7C7F66EC7E4C6C176EEA0FECE"", - ""relationshipType"": ""HAS_CONCLUDED_LICENSE"", - ""to"": [ - ""SPDXRef-Element-D6D57C0C9CC2CAC35C83DE0C8E4C8C37B87C0A58DA49BB31EBEBC6E200F54D4B"" - ], - ""creationInfo"": ""_:creationinfo"", - ""spdxId"": ""SPDXRef-Relationship-2A69D50DCB6D763C5C4FFCE6A4F6C3166DD8F6DB3F77BDD4B6129C0B33F238DA"", - ""type"": ""Relationship"" - }, - { - ""creationInfo"": ""_:creationinfo"", - ""name"": ""NoAssertion"", - ""spdxId"": ""SPDXRef-Element-D6D57C0C9CC2CAC35C83DE0C8E4C8C37B87C0A58DA49BB31EBEBC6E200F54D4B"", - ""type"": ""Element"" - }, - { - ""from"": ""SPDXRef-software_Package-4739C82D88855A138C811B8CE05CC97113BEC7F7C7F66EC7E4C6C176EEA0FECE"", - ""relationshipType"": ""HAS_DECLARED_LICENSE"", - ""to"": [ - ""SPDXRef-Element-D6D57C0C9CC2CAC35C83DE0C8E4C8C37B87C0A58DA49BB31EBEBC6E200F54D4B"" - ], - ""creationInfo"": ""_:creationinfo"", - ""spdxId"": ""SPDXRef-Relationship-222E099165617B282F2B424519FC133796AA0189D0238FD121CCF3B0340D4301"", - ""type"": ""Relationship"" - } - ]"; - - public const string RootPackageJsonString = - /*lang=json,strict*/ - @"[ - { - ""externalIdentifierType"": ""purl"", - ""identifier"": ""pkg:swid/the-package-supplier/sbom.microsoft/the-package-name@the-package-version?tag_id=.*"", - ""creationInfo"": ""_:creationinfo"", - ""spdxId"": ""SPDXRef-ExternalIdentifier-.*"", - ""type"": ""ExternalIdentifier"" - }, - { - ""creationInfo"": ""_:creationinfo"", - ""name"": ""Organization: the-package-supplier"", - ""spdxId"": ""SPDXRef-Organization-D914F48404CB6C27373666F70709BABF08C6603E1303B97758A20190A050CE16"", - ""type"": ""Organization"" - }, - { - ""CopyrightText"": ""NOASSERTION"", - ""software_downloadLocation"": ""NOASSERTION"", - ""software_packageVersion"": ""the-package-version"", - ""creationInfo"": ""_:creationinfo"", - ""externalIdentifier"": [ - ""SPDXRef-ExternalIdentifier-.*"" - ], - ""name"": ""the-package-name"", - ""spdxId"": ""SPDXRef-software_Package-A8C9BE15D102D0AF9D34A9EAA6FE282AB0CE35FF48A83058703A964E512B68B7"", - ""verifiedUsing"": [ - { - ""algorithm"": ""sha1"", - ""hashValue"": ""da39a3ee5e6b4b0d3255bfef95601890afd80709"", - ""creationInfo"": ""_:creationinfo"", - ""spdxId"": ""SPDXRef-PackageVerificationCode-B1565820A5CDAC40E0520D23F9D0B1497F240DDC51D72EAC6423D97D952D444F"", - ""type"": ""PackageVerificationCode"" - } - ], - ""type"": ""software_Package"" - }, - { - ""creationInfo"": ""_:creationinfo"", - ""name"": ""NoAssertion"", - ""spdxId"": ""SPDXRef-Element-D6D57C0C9CC2CAC35C83DE0C8E4C8C37B87C0A58DA49BB31EBEBC6E200F54D4B"", - ""type"": ""Element"" - }, - { - ""from"": ""SPDXRef-RootPackage"", - ""relationshipType"": ""HAS_DECLARED_LICENSE"", - ""to"": [ - ""SPDXRef-Element-D6D57C0C9CC2CAC35C83DE0C8E4C8C37B87C0A58DA49BB31EBEBC6E200F54D4B"" - ], - ""creationInfo"": ""_:creationinfo"", - ""spdxId"": ""SPDXRef-Relationship-222E099165617B282F2B424519FC133796AA0189D0238FD121CCF3B0340D4301"", - ""type"": ""Relationship"" - }, - { - ""from"": ""SPDXRef-RootPackage"", - ""relationshipType"": ""HAS_CONCLUDED_LICENSE"", - ""to"": [ - ""SPDXRef-Element-D6D57C0C9CC2CAC35C83DE0C8E4C8C37B87C0A58DA49BB31EBEBC6E200F54D4B"" - ], - ""creationInfo"": ""_:creationinfo"", - ""spdxId"": ""SPDXRef-Relationship-2A69D50DCB6D763C5C4FFCE6A4F6C3166DD8F6DB3F77BDD4B6129C0B33F238DA"", - ""type"": ""Relationship"" - } - ]"; -} diff --git a/test/Microsoft.Sbom.Parsers.Spdx30SbomParser.Tests/Parser/JsonStrings/SbomRelationshipJsonStrings.cs b/test/Microsoft.Sbom.Parsers.Spdx30SbomParser.Tests/Parser/JsonStrings/SbomRelationshipJsonStrings.cs deleted file mode 100644 index 728d2d37..00000000 --- a/test/Microsoft.Sbom.Parsers.Spdx30SbomParser.Tests/Parser/JsonStrings/SbomRelationshipJsonStrings.cs +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -namespace Microsoft.Sbom.Parser.JsonStrings; - -public static class SbomRelationshipJsonStrings -{ - [System.Diagnostics.CodeAnalysis.SuppressMessage("Style", "JSON002:Probable JSON string detected", Justification = "Need to use JSON string")] - public const string RelationshipJsonString = - @" - { - ""from"": ""source-id"", - ""relationshipType"": ""DESCRIBES"", - ""to"": [ - ""target-id"" - ], - ""creationInfo"": ""_:creationinfo"", - ""spdxId"": ""SPDXRef-Relationship-4A4165C4543F807E438AC18B09585043D3F49095D996BC098C74EC358AD24558"", - ""type"": ""Relationship"" - } - "; -} diff --git a/test/Microsoft.Sbom.Targets.Tests/AbstractGenerateSbomTaskInputTests.cs b/test/Microsoft.Sbom.Targets.Tests/AbstractGenerateSbomTaskInputTests.cs deleted file mode 100644 index 5274dbf5..00000000 --- a/test/Microsoft.Sbom.Targets.Tests/AbstractGenerateSbomTaskInputTests.cs +++ /dev/null @@ -1,375 +0,0 @@ -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Reflection; -using System.Text.RegularExpressions; -using Microsoft.Build.Framework; -using Microsoft.VisualStudio.TestTools.UnitTesting; -using Moq; - -namespace Microsoft.Sbom.Targets.Tests; - -[TestClass] -public abstract class AbstractGenerateSbomTaskInputTests -{ - internal abstract string SbomSpecification { get; } - - internal static readonly string CurrentDirectory = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); - internal static readonly string DefaultManifestDirectory = Path.Combine(CurrentDirectory, "_manifest"); - internal static readonly string TemporaryDirectory = Path.Combine(CurrentDirectory, "_temporary"); - internal static readonly string BuildComponentPath = Path.Combine(CurrentDirectory, "..", "..", ".."); - internal static readonly string ExternalDocumentListFile = Path.GetRandomFileName(); - internal static string SbomToolPath = Path.Combine(Directory.GetCurrentDirectory(), "sbom-tool"); - internal const string PackageSupplier = "Test-Microsoft"; - internal const string PackageName = "CoseSignTool"; - internal const string PackageVersion = "0.0.1"; - internal const string NamespaceBaseUri = "https://base0.uri"; - private Mock buildEngine; - private List errors; - private List messages; - - [TestInitialize] - public void Startup() - { - // Setup the build engine - this.buildEngine = new Mock(); - this.errors = new List(); - this.messages = new List(); - this.buildEngine.Setup(x => x.LogErrorEvent(It.IsAny())).Callback(e => errors.Add(e)); - this.buildEngine.Setup(x => x.LogMessageEvent(It.IsAny())).Callback(msg => messages.Add(msg)); - } - - [TestCleanup] - public void Cleanup() { - // Clean up the manifest directory - if (Directory.Exists(DefaultManifestDirectory)) - { - Directory.Delete(DefaultManifestDirectory, true); - } - - // Clean up the manifest directory - if (Directory.Exists(TemporaryDirectory)) - { - Directory.Delete(TemporaryDirectory, true); - } - } - - /// - /// Test for ensuring the GenerateSbom fails for null or empty inputs for - /// required params, which includes BuildDropPath, PackageSupplier, PackageName, - /// PackageVersion, and NamespaceBaseUri. - /// - [TestMethod] - [DynamicData(nameof(GetNullRequiredParamsData), DynamicDataSourceType.Method)] - [DynamicData(nameof(GetEmptyRequiredParamsData), DynamicDataSourceType.Method)] - [DynamicData(nameof(GetWhiteSpace_Tabs_NewLineParamsData), DynamicDataSourceType.Method)] - public void Sbom_Fails_With_Null_Empty_And_WhiteSpace_Required_Params( - string buildDropPath, - string packageSupplier, - string packageName, - string packageVersion, - string namespaceBaseUri, - string sbomToolPath) - { - // Arrange. - var task = new GenerateSbom - { - BuildDropPath = buildDropPath, - PackageSupplier = packageSupplier, - PackageName = packageName, - PackageVersion = packageVersion, - NamespaceBaseUri = namespaceBaseUri, - ManifestInfo = this.SbomSpecification, - BuildEngine = this.buildEngine.Object, -#if NET472 - SbomToolPath = sbomToolPath, -#endif - }; - - // Act - var result = task.Execute(); - - // Assert - Assert.IsFalse(result); - } - - private static IEnumerable GetNullRequiredParamsData() - { - yield return new object[] { null, PackageSupplier, PackageName, PackageVersion, NamespaceBaseUri, SbomToolPath }; - yield return new object[] { CurrentDirectory, null, PackageName, PackageVersion, NamespaceBaseUri, SbomToolPath }; - yield return new object[] { CurrentDirectory, PackageSupplier, null, PackageVersion, NamespaceBaseUri, SbomToolPath }; - yield return new object[] { CurrentDirectory, PackageSupplier, PackageName, null, NamespaceBaseUri, SbomToolPath }; - yield return new object[] { CurrentDirectory, PackageSupplier, PackageName, PackageVersion, null, SbomToolPath }; -#if NET472 - yield return new object[] { CurrentDirectory, PackageSupplier, PackageName, PackageVersion, NamespaceBaseUri, null }; -#endif - } - - private static IEnumerable GetEmptyRequiredParamsData() - { - yield return new object[] { string.Empty, PackageSupplier, PackageName, PackageVersion, NamespaceBaseUri, SbomToolPath }; - yield return new object[] { CurrentDirectory, string.Empty, PackageName, PackageVersion, NamespaceBaseUri, SbomToolPath }; - yield return new object[] { CurrentDirectory, PackageSupplier, string.Empty, PackageVersion, NamespaceBaseUri, SbomToolPath }; - yield return new object[] { CurrentDirectory, PackageSupplier, PackageName, string.Empty, NamespaceBaseUri, SbomToolPath }; - yield return new object[] { CurrentDirectory, PackageSupplier, PackageName, PackageVersion, string.Empty, SbomToolPath }; -#if NET472 - yield return new object[] { CurrentDirectory, PackageSupplier, PackageName, PackageVersion, NamespaceBaseUri, string.Empty }; -#endif - } - - private static IEnumerable GetWhiteSpace_Tabs_NewLineParamsData() - { - yield return new object[] { " ", PackageSupplier, PackageName, PackageVersion, NamespaceBaseUri, SbomToolPath }; - yield return new object[] { CurrentDirectory, "\n", PackageName, PackageVersion, NamespaceBaseUri, SbomToolPath }; - yield return new object[] { CurrentDirectory, PackageSupplier, "\t", PackageVersion, NamespaceBaseUri, SbomToolPath }; - yield return new object[] { CurrentDirectory, PackageSupplier, PackageName, " \n \t \n \t \n ", NamespaceBaseUri, SbomToolPath }; - yield return new object[] { CurrentDirectory, PackageSupplier, PackageName, PackageVersion, "\t \t \t ", SbomToolPath }; -#if NET472 - yield return new object[] { CurrentDirectory, PackageSupplier, PackageName, PackageVersion, NamespaceBaseUri, "\t \t \t " }; -#endif - } - - /// - /// Test for ensuring the GenerateSbom fails when user provides an - /// invalid URI format. - /// - [TestMethod] - [DataRow("incorrectly_formatted_uri.com")] // Missing protocol - [DataRow("http://invalid.com:70000")] // Invalid port - [DataRow("http://inv\nalid.com")] // Contains new line character - [DataRow("http://invalid.com/path with spaces")] // Contains spaces - [DataRow("http:invalid.com")] // Missing // after protocol - [DataRow("http://")] // Missing domain - public void Sbom_Fails_With_Invalid_NamespaceBaseUri(string namespaceBaseUri) - { - // Arrange - var task = new GenerateSbom - { - BuildDropPath = CurrentDirectory, - PackageSupplier = PackageSupplier, - PackageName = PackageName, - PackageVersion = PackageVersion, - NamespaceBaseUri = namespaceBaseUri, - ManifestInfo = this.SbomSpecification, - BuildEngine = this.buildEngine.Object, -#if NET472 - SbomToolPath = SbomToolPath, -#endif - }; - - // Act - var result = task.Execute(); - - // Assert - Assert.IsFalse(result); - } - - /// - /// Test for ensuring the GenerateSbom fails when user provides - /// an invalid GUID for NamespaceUriUniquePart. - /// - [TestMethod] - [DataRow("-1")] // starts with hyphen - [DataRow("1234567890")] // Too less digits - [DataRow("12345678-1234-1234-1234-123456789abcd")] // Too many digits - [DataRow("12345678-1234-1234-1234-123456789abg")] // invalid character g - [DataRow("12345678-1234-1234-1234-123456789ab!")] // invalid character ! - [DataRow("12345678-1234-1234-1234-123456789ab")] // Too less digits - [DataRow("12345678-1234-1234-1234-123456789ac-")] // Ends with a hyphen - [DataRow("12345678-1234-1234-1234-12345\n6789ac")] // Contains newline - [DataRow("00000000-0000-0000-0000-000000000000")] // Empty guid - public void Sbom_Generation_Fails_For_Invalid_NamespaceUriUniquePart(string namespaceUriUniquePart) - { - // Arrange - var task = new GenerateSbom - { - BuildDropPath = CurrentDirectory, - PackageSupplier = PackageSupplier, - PackageName = PackageName, - PackageVersion = PackageVersion, - NamespaceBaseUri = NamespaceBaseUri, - NamespaceUriUniquePart = namespaceUriUniquePart, - ManifestInfo = this.SbomSpecification, - BuildEngine = this.buildEngine.Object, -#if NET472 - SbomToolPath = SbomToolPath, -#endif - }; - - // Act - var result = task.Execute(); - - // Assert - Assert.IsFalse(result); - } - - /// - /// Test for ensuring GenerateSbom assigns a defualt Verbosity - /// level when null input is provided. - /// - [TestMethod] - public void Sbom_Generation_Succeeds_For_Null_Verbosity() - { - // Arrange - // If Verbosity is null, the default value should be Information and is printed in the - // tool's standard output. - var pattern = new Regex("Verbosity=.*Value=Information"); - var stringWriter = new StringWriter(); - Console.SetOut(stringWriter); - var task = new GenerateSbom - { - BuildDropPath = CurrentDirectory, - PackageSupplier = PackageSupplier, - PackageName = PackageName, - PackageVersion = PackageVersion, - NamespaceBaseUri = NamespaceBaseUri, - ManifestInfo = this.SbomSpecification, - Verbosity = null, - BuildEngine = this.buildEngine.Object, -#if NET472 - SbomToolPath = SbomToolPath, -#endif - }; - - // Act - var result = task.Execute(); - var output = stringWriter.ToString(); - - // Assert - Assert.IsTrue(result); -#if NET472 - Assert.IsTrue(this.messages.Any(msg => pattern.IsMatch(msg.Message))); -#else - Assert.IsTrue(pattern.IsMatch(output)); -#endif - } - - /// - /// Test for ensuring GenerateSbom assigns a default Verbosity for - /// unrecognized input. - /// - [TestMethod] - public void Sbom_Generation_Succeeds_For_Invalid_Verbosity() - { - // Arrange - // If an invalid Verbosity is specified, the default value should be Information. It is also printed in the - // tool's standard output for the MSBuild Core task. - var pattern = new Regex("Verbosity=.*Value=Information"); - var stringWriter = new StringWriter(); - Console.SetOut(stringWriter); - var task = new GenerateSbom - { - BuildDropPath = CurrentDirectory, - PackageSupplier = PackageSupplier, - PackageName = PackageName, - PackageVersion = PackageVersion, - NamespaceBaseUri = NamespaceBaseUri, - Verbosity = "Invalid Verbosity", - ManifestInfo = this.SbomSpecification, - BuildEngine = this.buildEngine.Object, -#if NET472 - SbomToolPath = SbomToolPath, -#endif - }; - - // Act - var result = task.Execute(); - var output = stringWriter.ToString(); - - // Assert - Assert.IsTrue(result); -#if NET472 - Assert.IsTrue(this.messages.Any(msg => pattern.IsMatch(msg.Message))); -#else - Assert.IsTrue(pattern.IsMatch(output)); -#endif - } - -#if !NET472 - /// - /// Test to ensure GenerateSbom correctly parses and provides each EventLevel verbosity - /// values to the SBOM API. - /// - [TestMethod] - [DataRow("FATAL", "Fatal", false)] - [DataRow("information", "Information", true)] - [DataRow("vErBose", "Verbose", true)] - [DataRow("Warning", "Warning", false)] - [DataRow("eRRor", "Error", false)] - [DataRow("DeBug", "Verbose", true)] - public void Sbom_Generation_Assigns_Correct_Verbosity_IgnoreCase(string inputVerbosity, string mappedVerbosity, bool messageShouldBeLogged) - { - if (!messageShouldBeLogged) - { - Assert.Inconclusive("Cases where the input Verbosity is more restrictive than `Information` are failing due to this issue: https://github.com/microsoft/sbom-tool/issues/616"); - } - - // Arrange - var pattern = new Regex($"Verbosity=.*Value={mappedVerbosity}"); - var stringWriter = new StringWriter(); - Console.SetOut(stringWriter); - var task = new GenerateSbom - { - BuildDropPath = CurrentDirectory, - PackageSupplier = PackageSupplier, - PackageName = PackageName, - PackageVersion = PackageVersion, - NamespaceBaseUri = NamespaceBaseUri, - Verbosity = inputVerbosity, - ManifestInfo = this.SbomSpecification, - BuildEngine = this.buildEngine.Object, - }; - - // Act - var result = task.Execute(); - var output = stringWriter.ToString(); - - // Assert - Assert.IsTrue(result, $"result: {result} is not set to true"); - Assert.AreEqual(messageShouldBeLogged, pattern.IsMatch(output)); - } -#else - /// - /// Test to ensure GenerateSbom correctly parses and provides each verbosity option - /// to the SBOM CLI. - /// - [TestMethod] - [DataRow("FATAL", "Fatal", false)] - [DataRow("information", "Information", true)] - [DataRow("vErBose", "Verbose", true)] - [DataRow("Warning", "Warning", false)] - [DataRow("eRRor", "Error", false)] - [DataRow("DeBug", "Debug", true)] - public void Sbom_Generation_Assigns_Correct_Verbosity_IgnoreCase(string inputVerbosity, string mappedVerbosity, bool messageShouldBeLogged) - { - // Arrange - var pattern = new Regex($"Verbosity=.*Value={mappedVerbosity}"); - var stringWriter = new StringWriter(); - Console.SetOut(stringWriter); - var task = new GenerateSbom - { - BuildDropPath = CurrentDirectory, - PackageSupplier = PackageSupplier, - PackageName = PackageName, - PackageVersion = PackageVersion, - NamespaceBaseUri = NamespaceBaseUri, - Verbosity = inputVerbosity, - ManifestInfo = this.SbomSpecification, - BuildEngine = this.buildEngine.Object, - SbomToolPath = SbomToolPath, - }; - - // Act - var result = task.Execute(); - var output = stringWriter.ToString(); - - // Assert - Assert.IsTrue(result, $"result: {result} is not set to true"); - Assert.AreEqual(messageShouldBeLogged, this.messages.Any(msg => pattern.IsMatch(msg.Message))); - } -#endif -} diff --git a/test/Microsoft.Sbom.Targets.Tests/AbstractGenerateSbomTaskTests.cs b/test/Microsoft.Sbom.Targets.Tests/AbstractGenerateSbomTaskTests.cs deleted file mode 100644 index 3c12a8ed..00000000 --- a/test/Microsoft.Sbom.Targets.Tests/AbstractGenerateSbomTaskTests.cs +++ /dev/null @@ -1,452 +0,0 @@ -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -using System.Collections.Generic; -using System.IO; -using System.Reflection; -using Microsoft.Build.Framework; -using Microsoft.Sbom.Targets.Tests.Utility; -using Microsoft.VisualStudio.TestTools.UnitTesting; -using Moq; - -namespace Microsoft.Sbom.Targets.Tests; - -/// -/// Base class for testing SBOM generation through the GenerateSbom. -/// -[TestClass] -public abstract class AbstractGenerateSbomTaskTests -{ - internal abstract string SbomSpecificationName { get; } - - internal abstract string SbomSpecificationVersion { get; } - - internal static readonly string CurrentDirectory = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); - internal static readonly string DefaultManifestDirectory = Path.Combine(CurrentDirectory, "_manifest"); - internal static readonly string TemporaryDirectory = Path.Combine(CurrentDirectory, "_temp"); - internal static readonly string ExternalDocumentListFile = Path.GetRandomFileName(); - internal static string SbomToolPath = Path.Combine(Directory.GetCurrentDirectory(), "sbom-tool"); - - internal const string PackageSupplier = "Test-Microsoft"; - internal const string PackageName = "CoseSignTool"; - internal const string PackageVersion = "0.0.1"; - internal const string NamespaceBaseUri = "https://base0.uri"; - - internal Mock BuildEngine; - internal List Errors; - internal string ManifestPath; - internal GeneratedSbomValidator GeneratedSbomValidator; - - internal string SbomSpecification => $"{this.SbomSpecificationName}:{this.SbomSpecificationVersion}"; - - internal string SbomSpecificationDirectoryName => $"{this.SbomSpecificationName}_{this.SbomSpecificationVersion}".ToLowerInvariant(); - - private void CleanupManifestDirectory() - { - // Clean up the manifest directory - if (Directory.Exists(DefaultManifestDirectory)) - { - Directory.Delete(DefaultManifestDirectory, true); - } - - // Clean up the manifest directory - if (Directory.Exists(TemporaryDirectory)) - { - Directory.Delete(TemporaryDirectory, true); - } - } - - [TestInitialize] - public void Startup() - { - // Setup the build engine - this.BuildEngine = new Mock(); - this.Errors = new List(); - this.BuildEngine.Setup(x => x.LogErrorEvent(It.IsAny())).Callback(e => Errors.Add(e)); - - this.CleanupManifestDirectory(); - - this.ManifestPath = Path.Combine(DefaultManifestDirectory, this.SbomSpecificationDirectoryName, "manifest.spdx.json"); - this.GeneratedSbomValidator = new(this.SbomSpecification); -#if NET472 - Assert.IsTrue(Directory.Exists(SbomToolPath)); -#endif - } - - [TestCleanup] - public void Cleanup() - { - this.CleanupManifestDirectory(); - } - - [TestMethod] - public void Sbom_Is_Successfully_Generated() - { - // Arrange - var task = new GenerateSbom - { - BuildDropPath = CurrentDirectory, - PackageSupplier = PackageSupplier, - PackageName = PackageName, - PackageVersion = PackageVersion, - NamespaceBaseUri = NamespaceBaseUri, - BuildEngine = this.BuildEngine.Object, - ManifestInfo = this.SbomSpecification, -#if NET472 - SbomToolPath = SbomToolPath, -#endif - }; - - // Act - var result = task.Execute(); - - // Assert - Assert.IsTrue(result); - this.GeneratedSbomValidator.AssertSbomIsValid(this.ManifestPath, CurrentDirectory, PackageName, PackageVersion, PackageSupplier, NamespaceBaseUri); - } - - [TestMethod] - [DataRow("http://example.com/hello/world")] // Regular valid URI - [DataRow("http://example.com/hello%20world")] // Valid URI with space encoded - [DataRow("http://ExAmplE.com")] // Mix of cases - [DataRow(" http://example.com ")] // Trailing spaces - [DataRow("http://www.example.com/path/to/resource?param1=value1¶m2=value2¶m3=value3¶m4=value4¶m5=" + - "value5¶m6=value6¶m7=value7¶m8=value8¶m9=value9¶m10=value10¶m11=value11¶m12=value12" + - "¶m13=value13¶m14=value14¶m15=value15¶m16=value16¶m17=value17¶m18=value18¶m19=value19¶m20=value20#section1")] // Super long URI - public void Sbom_Is_Successfully_Generated_Valid_URI(string namespaceBaseUri) - { - // Arrange - var task = new GenerateSbom - { - BuildDropPath = CurrentDirectory, - PackageSupplier = PackageSupplier, - PackageName = PackageName, - PackageVersion = PackageVersion, - NamespaceBaseUri = namespaceBaseUri, - BuildEngine = this.BuildEngine.Object, - ManifestInfo = this.SbomSpecification, -#if NET472 - SbomToolPath = SbomToolPath, -#endif - }; - - // Act - var result = task.Execute(); - - // Assert - Assert.IsTrue(result); - this.GeneratedSbomValidator.AssertSbomIsValid(this.ManifestPath, CurrentDirectory, PackageName, PackageVersion, PackageSupplier, namespaceBaseUri); - } - - [TestMethod] - [DynamicData(nameof(GetPackageSupplierCases), DynamicDataSourceType.Method)] - [DynamicData(nameof(GetPackageNameCases), DynamicDataSourceType.Method)] - [DynamicData(nameof(GetPackageVersionCases), DynamicDataSourceType.Method)] - public void Sbom_Is_Successfully_Generated_Valid_RequiredParams(string packageSupplier, string packageName, string packageVersion) - { - // Arrange - var task = new GenerateSbom - { - BuildDropPath = CurrentDirectory, - PackageSupplier = packageSupplier, - PackageName = packageName, - PackageVersion = packageVersion, - NamespaceBaseUri = NamespaceBaseUri, - BuildEngine = this.BuildEngine.Object, - ManifestInfo = this.SbomSpecification, -#if NET472 - SbomToolPath = SbomToolPath, -#endif - }; - - // Act - var result = task.Execute(); - - // Assert - Assert.IsTrue(result); - this.GeneratedSbomValidator.AssertSbomIsValid(this.ManifestPath, CurrentDirectory, PackageName, PackageVersion, PackageSupplier, NamespaceBaseUri); - } - - private static IEnumerable GetPackageSupplierCases() - { - yield return new object[] { "Test-\nMicrosoft", PackageName, PackageVersion }; - yield return new object[] { "Test\t-Microsoft", PackageName, PackageVersion }; - yield return new object[] { "Test-Mic\tro\nsoft", PackageName, PackageVersion }; - } - - private static IEnumerable GetPackageNameCases() - { - yield return new object[] { PackageSupplier, "CoseSign\nTool", PackageVersion }; - yield return new object[] { PackageSupplier, "Cose\tSign\tTool", PackageVersion }; - yield return new object[] { PackageSupplier, "CoseS\ti\ngn\nToo\tl", PackageVersion }; - } - - private static IEnumerable GetPackageVersionCases() - { - yield return new object[] { PackageSupplier, PackageName, "0.0\n.1" }; - yield return new object[] { PackageSupplier, PackageName, "0.0\t.1" }; - yield return new object[] { PackageSupplier, PackageName, "0. 0. 1" }; - yield return new object[] { PackageSupplier, PackageName, "0 . \t 0 \n .1" }; - } - - [TestMethod] - public void Sbom_Is_Successfully_Generated_In_Specified_Location() - { - var manifestDirPath = Path.Combine(TemporaryDirectory, "sub-directory"); - Directory.CreateDirectory(manifestDirPath); - // Arrange - var task = new GenerateSbom - { - BuildDropPath = CurrentDirectory, - ManifestDirPath = manifestDirPath, - PackageSupplier = PackageSupplier, - PackageName = PackageName, - PackageVersion = PackageVersion, - NamespaceBaseUri = NamespaceBaseUri, - BuildEngine = this.BuildEngine.Object, - ManifestInfo = this.SbomSpecification, -#if NET472 - SbomToolPath = SbomToolPath, -#endif - }; - - // Act - var result = task.Execute(); - - // Assert - Assert.IsTrue(result); - - this.ManifestPath = Path.Combine(manifestDirPath, "_manifest", this.SbomSpecificationDirectoryName, "manifest.spdx.json"); - this.GeneratedSbomValidator.AssertSbomIsValid(this.ManifestPath, CurrentDirectory, PackageName, PackageVersion, PackageSupplier, NamespaceBaseUri); - } - - [TestMethod] - public void Sbom_Generation_Fails_With_NotFound_BuildDropPath() - { - // Arrange - var task = new GenerateSbom - { - BuildDropPath = ".\\non-existent\\path", - PackageSupplier = PackageSupplier, - PackageName = PackageName, - PackageVersion = PackageVersion, - NamespaceBaseUri = NamespaceBaseUri, - BuildEngine = this.BuildEngine.Object, - ManifestInfo = this.SbomSpecification, -#if NET472 - SbomToolPath = SbomToolPath, -#endif - }; - - // Act - var result = task.Execute(); - - // Assert - Assert.IsFalse(result); - } - - [TestMethod] - public void Sbom_Generation_Fails_With_NotFound_BuildComponentPath() - { - // Arrange - var task = new GenerateSbom - { - BuildDropPath = CurrentDirectory, - BuildComponentPath = ".\\non-existent\\path", - PackageSupplier = PackageSupplier, - PackageName = PackageName, - PackageVersion = PackageVersion, - NamespaceBaseUri = NamespaceBaseUri, - BuildEngine = this.BuildEngine.Object, - ManifestInfo = this.SbomSpecification, -#if NET472 - SbomToolPath = SbomToolPath, -#endif - }; - - // Act - var result = task.Execute(); - - // Assert - Assert.IsFalse(result); - Assert.IsFalse(Directory.Exists(DefaultManifestDirectory)); - } - - [TestMethod] - public void Sbom_Generation_Fails_With_NotFound_ExternalDocumentListFile() - { - // Arrange - var task = new GenerateSbom - { - BuildDropPath = CurrentDirectory, - ExternalDocumentListFile = ".\\non-existent\\path", - PackageSupplier = PackageSupplier, - PackageName = PackageName, - PackageVersion = PackageVersion, - NamespaceBaseUri = NamespaceBaseUri, - BuildEngine = this.BuildEngine.Object, - ManifestInfo = this.SbomSpecification, -#if NET472 - SbomToolPath = SbomToolPath, -#endif - }; - - // Act - var result = task.Execute(); - - // Assert - Assert.IsFalse(result); - Assert.IsFalse(Directory.Exists(DefaultManifestDirectory)); - } - - [TestMethod] - public void Sbom_Generation_Fails_With_NotFound_ManifestDirPath() - { - // Arrange - var task = new GenerateSbom - { - BuildDropPath = CurrentDirectory, - ManifestDirPath = ".\\non-existent\\path", - PackageSupplier = PackageSupplier, - PackageName = PackageName, - PackageVersion = PackageVersion, - NamespaceBaseUri = NamespaceBaseUri, - BuildEngine = this.BuildEngine.Object, - ManifestInfo = this.SbomSpecification, -#if NET472 - SbomToolPath = SbomToolPath, -#endif - }; - - // Act - var result = task.Execute(); - - // Assert - Assert.IsFalse(result); - Assert.IsFalse(Directory.Exists(DefaultManifestDirectory)); - } - - [TestMethod] - public void Sbom_Is_Successfully_Generated_With_Component_Path() - { - // Let's generate a SBOM for the current assembly - var sourceDirectory = Path.Combine(CurrentDirectory, "..", "..", ".."); - - // Arrange - var task = new GenerateSbom - { - BuildDropPath = CurrentDirectory, - BuildComponentPath = sourceDirectory, - PackageSupplier = PackageSupplier, - PackageName = PackageName, - PackageVersion = PackageVersion, - NamespaceBaseUri = NamespaceBaseUri, - BuildEngine = this.BuildEngine.Object, - ManifestInfo = this.SbomSpecification, -#if NET472 - SbomToolPath = SbomToolPath, -#endif - }; - - // Act - var result = task.Execute(); - - // Assert - Assert.IsTrue(result); - this.GeneratedSbomValidator.AssertSbomIsValid(this.ManifestPath, CurrentDirectory, PackageName, PackageVersion, PackageSupplier, NamespaceBaseUri, buildComponentPath: sourceDirectory); - } - - [TestMethod] - [DataRow("550e8400-e29b-41d4-a716-446655440000")] // Standard random GUID - [DataRow("3F2504E0-4f89-11D3-9A0C-0305E82c3301")] // Mixed cases - [DataRow("3F2504E04F8911D39A0C0305E82C3301")] // Guids without hyphens - [DataRow(" 3F2504E0-4F89-11D3-9A0C-0305E82C3301 ")] // Guids with trailing spaces - public void Sbom_Is_Successfully_Generated_With_Unique_Namespace_Part_Defined(string uniqueNamespacePart) - { - // Arrange - var task = new GenerateSbom - { - BuildDropPath = CurrentDirectory, - PackageSupplier = PackageSupplier, - PackageName = PackageName, - PackageVersion = PackageVersion, - NamespaceBaseUri = NamespaceBaseUri, - NamespaceUriUniquePart = uniqueNamespacePart, - BuildEngine = this.BuildEngine.Object, - ManifestInfo = this.SbomSpecification, -#if NET472 - SbomToolPath = SbomToolPath, -#endif - }; - - // Act - var result = task.Execute(); - - // Assert - Assert.IsTrue(result, $"{result} is not set to true."); - this.GeneratedSbomValidator.AssertSbomIsValid(this.ManifestPath, CurrentDirectory, PackageName, PackageVersion, PackageSupplier, NamespaceBaseUri, expectedNamespaceUriUniquePart: uniqueNamespacePart); - } - -#if NET472 - [TestMethod] - public void Sbom_Generation_Fails_With_Tool_Path_Not_Found() - { - // Arrange - var task = new GenerateSbom - { - BuildDropPath = CurrentDirectory, - PackageSupplier = PackageSupplier, - PackageName = PackageName, - PackageVersion = PackageVersion, - NamespaceBaseUri = NamespaceBaseUri, - BuildEngine = this.BuildEngine.Object, - ManifestInfo = this.SbomSpecification, - SbomToolPath = "C:\\Not-Found\\Path\\", - }; - - // Act - var result = task.Execute(); - - // Assert - Assert.IsFalse(result); - Assert.IsFalse(Directory.Exists(DefaultManifestDirectory)); - } -#endif - - [TestMethod] - public void Sbom_Fails_To_Generate_Due_To_File_In_Use() - { - var manifestDirPath = Path.Combine(TemporaryDirectory, "sub-directory"); - this.ManifestPath = Path.Combine(manifestDirPath, "_manifest", this.SbomSpecificationDirectoryName, "manifest.spdx.json"); - Directory.CreateDirectory(manifestDirPath); - // Arrange - var task = new GenerateSbom - { - BuildDropPath = CurrentDirectory, - ManifestDirPath = manifestDirPath, - PackageSupplier = PackageSupplier, - PackageName = PackageName, - PackageVersion = PackageVersion, - NamespaceBaseUri = NamespaceBaseUri, - BuildEngine = this.BuildEngine.Object, - ManifestInfo = this.SbomSpecification, -#if NET472 - SbomToolPath = SbomToolPath, -#endif - }; - - // Write JSON content to the manifest file, and create the directory if it doesn't exist - var jsonContent = "{}"; - Directory.CreateDirectory(Path.GetDirectoryName(ManifestPath)); - File.WriteAllText(ManifestPath, jsonContent); - // Open a handle to the manifest file to simulate it being in use - using (var fileStream = File.Open(this.ManifestPath, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.None)) - { - // Act - var result = task.Execute(); - - // Assert - Assert.IsFalse(result); - } - } -} diff --git a/test/Microsoft.Sbom.Targets.Tests/GenerateSbomTaskSPDX_2_2InputTests.cs b/test/Microsoft.Sbom.Targets.Tests/GenerateSbomTaskSPDX_2_2InputTests.cs deleted file mode 100644 index 1efe7e8a..00000000 --- a/test/Microsoft.Sbom.Targets.Tests/GenerateSbomTaskSPDX_2_2InputTests.cs +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -namespace Microsoft.Sbom.Targets.Tests; - -using Microsoft.VisualStudio.TestTools.UnitTesting; - -/// -/// Class to test the generation of SBOM using SPDX 2.2 specification. -/// -[TestClass] -public class GenerateSbomTaskSPDX_2_2InputTests : AbstractGenerateSbomTaskInputTests -{ - internal override string SbomSpecification => "SPDX:2.2"; -} diff --git a/test/Microsoft.Sbom.Targets.Tests/GenerateSbomTaskSPDX_2_2Tests.cs b/test/Microsoft.Sbom.Targets.Tests/GenerateSbomTaskSPDX_2_2Tests.cs deleted file mode 100644 index 63e66701..00000000 --- a/test/Microsoft.Sbom.Targets.Tests/GenerateSbomTaskSPDX_2_2Tests.cs +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -namespace Microsoft.Sbom.Targets.Tests; - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Microsoft.VisualStudio.TestTools.UnitTesting; - -/// -/// Class to test the generation of SBOM using SPDX 2.2 specification. -/// -[TestClass] -public class GenerateSbomTaskSPDX_2_2Tests : AbstractGenerateSbomTaskTests -{ - internal override string SbomSpecificationName => "SPDX"; - - internal override string SbomSpecificationVersion => "2.2"; -} diff --git a/test/Microsoft.Sbom.Targets.Tests/Microsoft.Sbom.Targets.Tests.csproj b/test/Microsoft.Sbom.Targets.Tests/Microsoft.Sbom.Targets.Tests.csproj deleted file mode 100644 index 7f61b315..00000000 --- a/test/Microsoft.Sbom.Targets.Tests/Microsoft.Sbom.Targets.Tests.csproj +++ /dev/null @@ -1,42 +0,0 @@ - - - - net8.0;net472 - net8.0 - false - True - Microsoft.Sbom.Targets.Tests - net8.0 - $(MSBuildThisFileDirectory)..\..\src\Microsoft.Sbom.Tool\ - CA1515;CA1872;NU1903 - - - - TRACE - - - - - - - - - - - - - <_SbomToolFiles Include="$(SBOMCLIToolProjectDir)bin\$(Configuration)\$(SbomCLIToolTargetFramework)\publish\**\*.*"> - false - - - - - - - - - - - - - \ No newline at end of file diff --git a/test/Microsoft.Sbom.Targets.Tests/Utility/GeneratedSbomValidator.cs b/test/Microsoft.Sbom.Targets.Tests/Utility/GeneratedSbomValidator.cs deleted file mode 100644 index 44cb95d1..00000000 --- a/test/Microsoft.Sbom.Targets.Tests/Utility/GeneratedSbomValidator.cs +++ /dev/null @@ -1,138 +0,0 @@ -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -namespace Microsoft.Sbom.Targets.Tests.Utility; - -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Security.Cryptography; -using Microsoft.VisualStudio.TestTools.UnitTesting; -using Newtonsoft.Json; - -/// -/// This class is used to validate that the generated SBOM has valid fields and data. -/// -#pragma warning disable CA5350 // Suppress Do Not Use Weak Cryptographic Algorithms as we use SHA1 intentionally -internal class GeneratedSbomValidator -{ - private const string SPDX22Specification = "SPDX:2.2"; - private readonly string sbomSpecification; - - public GeneratedSbomValidator(string sbomSpecification) - { - this.sbomSpecification = sbomSpecification; - } - - internal void AssertSbomIsValid(string manifestPath, string buildDropPath, string expectedPackageName, string expectedPackageVersion, string expectedPackageSupplier, string expectedNamespaceUriBase, string expectedNamespaceUriUniquePart = null, string buildComponentPath = null) - { - Assert.IsTrue(File.Exists(manifestPath)); - - // Read and parse the manifest - var manifestContent = File.ReadAllText(manifestPath); - var manifest = JsonConvert.DeserializeObject(manifestContent); - - if (this.sbomSpecification.Equals(SPDX22Specification)) - { - // Check the manifest has expected file data - var filesValue = manifest["files"]; - Assert.IsNotNull(filesValue); - - var expectedFilesHashes = this.GetBuildDropFileHashes(buildDropPath); - Assert.AreEqual(expectedFilesHashes.Count, filesValue.Count, $"Manifest {manifestPath} has {filesValue.Count} files instead of {expectedFilesHashes.Count}"); - foreach (var file in filesValue) - { - var filePath = Path.GetFullPath(Path.Combine(buildDropPath, (string)file["fileName"])); - var fileChecksums = file["checksums"]; - Assert.IsNotNull(fileChecksums); - - foreach (var checksum in fileChecksums) - { - var algorithm = (string)checksum["algorithm"]; - var hash = (string)checksum["checksumValue"]; - Assert.IsNotNull(algorithm); - Assert.IsNotNull(hash); - - Assert.IsTrue(expectedFilesHashes.ContainsKey(filePath)); - Assert.IsTrue(expectedFilesHashes[filePath].ContainsKey(algorithm)); - Assert.IsTrue(expectedFilesHashes[filePath][algorithm].Equals(hash, StringComparison.InvariantCultureIgnoreCase)); - } - } - - var packagesValue = manifest["packages"]; - Assert.IsNotNull(packagesValue); - if (string.IsNullOrEmpty(buildComponentPath)) - { - Assert.IsTrue(packagesValue.Count == 1, $"Expected 1 package but actual value was {packagesValue.Count}"); - } - else - { - Assert.IsTrue(packagesValue.Count > 1); - } - - var nameValue = manifest["name"]; - Assert.IsNotNull(nameValue); - Assert.AreEqual($"{expectedPackageName} {expectedPackageVersion}", (string)nameValue); - - var creatorsValue = manifest["creationInfo"]["creators"]; - Assert.IsNotNull(creatorsValue); - Assert.IsTrue(creatorsValue.Count > 0); - Assert.IsTrue(((string)creatorsValue[0]).Contains(expectedPackageSupplier)); - - string namespaceValue = manifest["documentNamespace"]; - Assert.IsNotNull(namespaceValue); - - if (expectedNamespaceUriUniquePart != null) - { - Assert.IsTrue(namespaceValue.Equals($"{expectedNamespaceUriBase.Trim()}/{expectedPackageName}/{expectedPackageVersion}/{expectedNamespaceUriUniquePart.Trim()}", StringComparison.InvariantCultureIgnoreCase)); - } - else - { - Assert.IsTrue(namespaceValue.Contains($"{expectedNamespaceUriBase.Trim()}/{expectedPackageName}/{expectedPackageVersion}")); - } - } else - { - Assert.Fail("An unexpected SBOM specification was used. Please specify SPDX 2.2."); - } - } - - private IDictionary> GetBuildDropFileHashes(string buildDropPath) - { - var filesHashes = new Dictionary>(); - - // Get all files in the buildDropPath and its subfolders - var files = Directory.GetFiles(buildDropPath, "*", SearchOption.AllDirectories) - .Where(f => !f.Contains("manifest.spdx.json")) - .Select(Path.GetFullPath); - - // Compute hashes for each file. - foreach (var filePath in files) - { - var fileHashes = new Dictionary(); - // Compute hashes for the file. - foreach (var hashAlgorithmPair in this.GetListOfHashAlgorithmCreators()) - { - using var stream = File.OpenRead(filePath); - using var hashAlgorithmInstance = hashAlgorithmPair.Item2(); - var hash = hashAlgorithmInstance.ComputeHash(stream); - var hashString = BitConverter.ToString(hash).Replace("-", string.Empty); - fileHashes.Add(hashAlgorithmPair.Item1, hashString); - } - - filesHashes.Add(filePath, fileHashes); - } - - return filesHashes; - } - - private IList<(string, Func)> GetListOfHashAlgorithmCreators() - { - if (this.sbomSpecification.Equals(SPDX22Specification)) - { - return [("SHA1", SHA1.Create), ("SHA256", SHA256.Create)]; - } - - return []; - } -} diff --git a/test/Microsoft.Sbom.Tool.Tests/IntegrationTests.cs b/test/Microsoft.Sbom.Tool.Tests/IntegrationTests.cs deleted file mode 100644 index 4c8f6367..00000000 --- a/test/Microsoft.Sbom.Tool.Tests/IntegrationTests.cs +++ /dev/null @@ -1,234 +0,0 @@ -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -using System; -using System.Diagnostics; -using System.IO; -using System.Reflection; -using System.Runtime.InteropServices; -using Microsoft.VisualStudio.TestTools.UnitTesting; - -namespace Microsoft.Sbom.Tools.Tests; - -[TestClass] -public class IntegrationTests -{ - private const string ManifestRootFolderName = "_manifest"; - private const string ManifestFileName = "manifest.spdx.json"; - - private static readonly bool IsWindows = RuntimeInformation.IsOSPlatform(OSPlatform.Windows); - - public TestContext TestContext { get; set; } - - private static string testRunDirectory; - - [ClassInitialize] - public static void Setup(TestContext context) - { - testRunDirectory = context.TestRunDirectory; - } - - [ClassCleanup(ClassCleanupBehavior.EndOfClass)] - public static void TearDown() - { - // Clean up test directories - if (testRunDirectory is not null) - { - if (Directory.Exists(testRunDirectory)) - { - Directory.Delete(testRunDirectory, true); - } - } - } - - [TestMethod] - public void TargetAppExists() - { - Assert.IsTrue(File.Exists(GetAppName())); - } - - [TestMethod] - public void E2E_NoParameters_DisplaysHelpMessage_ReturnsNonZeroExitCode() - { - if (!IsWindows) - { - Assert.Inconclusive("This test is not (yet) supported on non-Windows platforms."); - return; - } - - var (stdout, stderr, exitCode) = LaunchAndCaptureOutput(null); - - Assert.AreEqual(stderr, string.Empty); - Assert.IsTrue(stdout.Contains("Validate -options")); - Assert.IsTrue(stdout.Contains("Generate -options")); - Assert.IsTrue(stdout.Contains("Redact -options")); - Assert.AreNotEqual(0, exitCode.Value); - } - - [TestMethod] - public void E2E_GenerateManifest_GeneratesManifest_ReturnsZeroExitCode() - { - if (!IsWindows) - { - Assert.Inconclusive("This test is not (yet) supported on non-Windows platforms."); - return; - } - - var testFolderPath = CreateTestFolder(); - GenerateManifestAndValidateSuccess(testFolderPath); - } - - [TestMethod] - public void E2E_GenerateAndValidateManifest_ValidationSucceeds_ReturnsZeroExitCode() - { - if (!IsWindows) - { - Assert.Inconclusive("This test is not (yet) supported on non-Windows platforms."); - return; - } - - var testFolderPath = CreateTestFolder(); - GenerateManifestAndValidateSuccess(testFolderPath); - - var outputFile = Path.Combine(TestContext.TestRunDirectory, TestContext.TestName, "validation.json"); - var manifestRootFolderName = Path.Combine(testFolderPath, ManifestRootFolderName); - var arguments = $"validate -m \"{manifestRootFolderName}\" -b . -o \"{outputFile}\" -mi spdx:2.2"; - - var (stdout, stderr, exitCode) = LaunchAndCaptureOutput(arguments); - - Assert.AreEqual(stderr, string.Empty); - Assert.AreEqual(0, exitCode.Value); - Assert.IsTrue(File.Exists(outputFile), $"{outputFile} should have been created during validation"); - Assert.IsTrue(File.ReadAllText(outputFile).Contains("\"Result\":\"Success\"", StringComparison.OrdinalIgnoreCase)); - } - - [TestMethod] - public void E2E_GenerateAndRedactManifest_RedactedFileIsSmaller_ReturnsZeroExitCode() - { - if (!IsWindows) - { - Assert.Inconclusive("This test is not (yet) supported on non-Windows platforms."); - return; - } - - var testFolderPath = CreateTestFolder(); - GenerateManifestAndValidateSuccess(testFolderPath); - - var outputFolder = Path.Combine(TestContext.TestRunDirectory, TestContext.TestName, "redacted"); - var originalManifestFolderPath = AppendFullManifestFolderPath(testFolderPath); - var originalManifestFilePath = Path.Combine(AppendFullManifestFolderPath(testFolderPath), ManifestFileName); - var arguments = $"redact -sp \"{originalManifestFilePath}\" -o \"{outputFolder}\" -verbosity verbose"; - - var (stdout, stderr, exitCode) = LaunchAndCaptureOutput(arguments); - - Assert.AreEqual(stderr, string.Empty); - Assert.AreEqual(0, exitCode.Value); - Assert.IsTrue(stdout.Contains("Result=Success", StringComparison.OrdinalIgnoreCase)); - var redactedManifestFilePath = Path.Combine(outputFolder, ManifestFileName); - var originalManifestSize = File.ReadAllText(originalManifestFilePath).Length; - var redactedManifestSize = File.ReadAllText(redactedManifestFilePath).Length; - Assert.IsTrue(redactedManifestSize > 0, "Redacted file must not be empty"); - Assert.IsTrue(redactedManifestSize < originalManifestSize, "Redacted file must be smaller than the original"); - } - - private void GenerateManifestAndValidateSuccess(string testFolderPath) - { - var arguments = $"generate -ps IntegrationTests -pn IntegrationTests -pv 1.2.3 -m \"{testFolderPath}\" -b . -bc \"{GetSolutionFolderPath()}\""; - - var (stdout, stderr, exitCode) = LaunchAndCaptureOutput(arguments); - - Assert.AreEqual(stderr, string.Empty); - var manifestFolderPath = AppendFullManifestFolderPath(testFolderPath); - var jsonFilePath = Path.Combine(manifestFolderPath, ManifestFileName); - var shaFilePath = Path.Combine(manifestFolderPath, "manifest.spdx.json.sha256"); - Assert.IsTrue(File.Exists(jsonFilePath)); - Assert.IsTrue(File.Exists(shaFilePath)); - Assert.AreEqual(0, exitCode.Value); - } - - private string CreateTestFolder() - { - var testFolderPath = Path.GetFullPath(Path.Combine(TestContext.TestRunDirectory, TestContext.TestName)); - Directory.CreateDirectory(testFolderPath); - return testFolderPath; - } - - private static string AppendFullManifestFolderPath(string manifestDir) - { - return Path.Combine(manifestDir, ManifestRootFolderName, "spdx_2.2"); - } - - private static string GetSolutionFolderPath() - { - return Path.GetFullPath(Path.Combine(Assembly.GetExecutingAssembly().Location, "..", "..", "..")); - } - - private static string GetAppName() - { - return IsWindows ? "Microsoft.Sbom.Tool.exe" : "Microsoft.Sbom.Tool"; - } - - private static (string stdout, string stderr, int? exitCode) LaunchAndCaptureOutput(string? arguments) - { - var stdout = string.Empty; - var stderr = string.Empty; - int? exitCode = null; - Process process = null; - - try - { - process = new Process - { - StartInfo = new ProcessStartInfo - { - FileName = GetAppName(), - RedirectStandardOutput = true, - RedirectStandardError = true, - UseShellExecute = false, - CreateNoWindow = true, - Arguments = arguments ?? string.Empty, - } - }; - - process.OutputDataReceived += (sender, e) => - { - if (!string.IsNullOrEmpty(e.Data)) - { - stdout += e.Data + Environment.NewLine; - } - }; - - process.ErrorDataReceived += (sender, e) => - { - if (!string.IsNullOrEmpty(e.Data)) - { - stderr += e.Data + Environment.NewLine; - } - }; - - process.Start(); - process.BeginOutputReadLine(); - process.BeginErrorReadLine(); - process.WaitForExit(); - } - catch (Exception e) - { - Assert.Fail($"Caught the following Exception: {e}"); - } - finally - { - if (process is not null) - { - if (!process.HasExited) - { - process.Kill(); - } - - exitCode = process.ExitCode; - process.Dispose(); - } - } - - return (stdout, stderr, exitCode); - } -} diff --git a/test/Microsoft.Sbom.Tool.Tests/Microsoft.Sbom.Tool.Tests.csproj b/test/Microsoft.Sbom.Tool.Tests/Microsoft.Sbom.Tool.Tests.csproj deleted file mode 100644 index 0a21f494..00000000 --- a/test/Microsoft.Sbom.Tool.Tests/Microsoft.Sbom.Tool.Tests.csproj +++ /dev/null @@ -1,18 +0,0 @@ - - - - false - True - Microsoft.Sbom.Tools.Tests - $(StrongNameSigningKeyFilePath) - - - - TRACE - - - - - - -