diff --git a/Microsoft.Sbom.sln b/Microsoft.Sbom.sln index cd1421e7a..1c5c1b0af 100644 --- a/Microsoft.Sbom.sln +++ b/Microsoft.Sbom.sln @@ -54,6 +54,9 @@ 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}" + ProjectSection(ProjectDependencies) = postProject + {6C27560E-B0B0-44E3-B4AE-6FB92CE9FE4A} = {6C27560E-B0B0-44E3-B4AE-6FB92CE9FE4A} + EndProjectSection 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 diff --git a/test/Microsoft.Sbom.Targets.Tests/AbstractGenerateSbomTaskInputTests.cs b/test/Microsoft.Sbom.Targets.Tests/AbstractGenerateSbomTaskInputTests.cs index 83569ff4f..3834c75a3 100644 --- a/test/Microsoft.Sbom.Targets.Tests/AbstractGenerateSbomTaskInputTests.cs +++ b/test/Microsoft.Sbom.Targets.Tests/AbstractGenerateSbomTaskInputTests.cs @@ -18,22 +18,40 @@ 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 virtual string SbomSpecification { get; } + + internal static string TestBuildDropPath; + internal static string DefaultManifestDirectory; + internal static string TemporaryDirectory; + internal static string ExternalDocumentListFile; + internal static string SbomToolPath; + 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"; + +#if NET472 + private const string TargetFramework = "net472"; +#else + private const string TargetFramework = "net80"; +#endif + private Mock buildEngine; private List errors; private List messages; + protected static void ClassSetup(string testDirectoryName) + { + var executingDirectory = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); + TestBuildDropPath = Path.GetFullPath(Path.Combine(executingDirectory, "..", $"{testDirectoryName}_{TargetFramework}")); + DefaultManifestDirectory = Path.Combine(TestBuildDropPath, "_manifest"); + TemporaryDirectory = Path.Combine(TestBuildDropPath, "_temp"); + ExternalDocumentListFile = Path.GetRandomFileName(); + SbomToolPath = Path.Combine(TestBuildDropPath, "sbom-tool"); + Xcopy(executingDirectory, TestBuildDropPath); + } + [TestInitialize] public void Startup() { @@ -46,7 +64,8 @@ public void Startup() } [TestCleanup] - public void Cleanup() { + public void Cleanup() + { // Clean up the manifest directory if (Directory.Exists(DefaultManifestDirectory)) { @@ -60,6 +79,18 @@ public void Cleanup() { } } + protected static void ClassTearDown() + { + // Clean up the TestBuildDropPath directory + if (TestBuildDropPath is not null) + { + if (Directory.Exists(TestBuildDropPath)) + { + Directory.Delete(TestBuildDropPath, true); + } + } + } + /// /// Test for ensuring the GenerateSbom fails for null or empty inputs for /// required params, which includes BuildDropPath, PackageSupplier, PackageName, @@ -102,36 +133,36 @@ public void Sbom_Fails_With_Null_Empty_And_WhiteSpace_Required_Params( 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 }; + yield return new object[] { TestBuildDropPath, null, PackageName, PackageVersion, NamespaceBaseUri, SbomToolPath }; + yield return new object[] { TestBuildDropPath, PackageSupplier, null, PackageVersion, NamespaceBaseUri, SbomToolPath }; + yield return new object[] { TestBuildDropPath, PackageSupplier, PackageName, null, NamespaceBaseUri, SbomToolPath }; + yield return new object[] { TestBuildDropPath, PackageSupplier, PackageName, PackageVersion, null, SbomToolPath }; #if NET472 - yield return new object[] { CurrentDirectory, PackageSupplier, PackageName, PackageVersion, NamespaceBaseUri, null }; + yield return new object[] { TestBuildDropPath, 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 }; + yield return new object[] { TestBuildDropPath, string.Empty, PackageName, PackageVersion, NamespaceBaseUri, SbomToolPath }; + yield return new object[] { TestBuildDropPath, PackageSupplier, string.Empty, PackageVersion, NamespaceBaseUri, SbomToolPath }; + yield return new object[] { TestBuildDropPath, PackageSupplier, PackageName, string.Empty, NamespaceBaseUri, SbomToolPath }; + yield return new object[] { TestBuildDropPath, PackageSupplier, PackageName, PackageVersion, string.Empty, SbomToolPath }; #if NET472 - yield return new object[] { CurrentDirectory, PackageSupplier, PackageName, PackageVersion, NamespaceBaseUri, string.Empty }; + yield return new object[] { TestBuildDropPath, 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 }; + yield return new object[] { TestBuildDropPath, "\n", PackageName, PackageVersion, NamespaceBaseUri, SbomToolPath }; + yield return new object[] { TestBuildDropPath, PackageSupplier, "\t", PackageVersion, NamespaceBaseUri, SbomToolPath }; + yield return new object[] { TestBuildDropPath, PackageSupplier, PackageName, " \n \t \n \t \n ", NamespaceBaseUri, SbomToolPath }; + yield return new object[] { TestBuildDropPath, PackageSupplier, PackageName, PackageVersion, "\t \t \t ", SbomToolPath }; #if NET472 - yield return new object[] { CurrentDirectory, PackageSupplier, PackageName, PackageVersion, NamespaceBaseUri, "\t \t \t " }; + yield return new object[] { TestBuildDropPath, PackageSupplier, PackageName, PackageVersion, NamespaceBaseUri, "\t \t \t " }; #endif } @@ -151,7 +182,7 @@ public void Sbom_Fails_With_Invalid_NamespaceBaseUri(string namespaceBaseUri) // Arrange var task = new GenerateSbom { - BuildDropPath = CurrentDirectory, + BuildDropPath = TestBuildDropPath, PackageSupplier = PackageSupplier, PackageName = PackageName, PackageVersion = PackageVersion, @@ -189,7 +220,7 @@ public void Sbom_Generation_Fails_For_Invalid_NamespaceUriUniquePart(string name // Arrange var task = new GenerateSbom { - BuildDropPath = CurrentDirectory, + BuildDropPath = TestBuildDropPath, PackageSupplier = PackageSupplier, PackageName = PackageName, PackageVersion = PackageVersion, @@ -224,7 +255,7 @@ public void Sbom_Generation_Succeeds_For_Null_Verbosity() Console.SetOut(stringWriter); var task = new GenerateSbom { - BuildDropPath = CurrentDirectory, + BuildDropPath = TestBuildDropPath, PackageSupplier = PackageSupplier, PackageName = PackageName, PackageVersion = PackageVersion, @@ -265,7 +296,7 @@ public void Sbom_Generation_Succeeds_For_Invalid_Verbosity() Console.SetOut(stringWriter); var task = new GenerateSbom { - BuildDropPath = CurrentDirectory, + BuildDropPath = TestBuildDropPath, PackageSupplier = PackageSupplier, PackageName = PackageName, PackageVersion = PackageVersion, @@ -316,7 +347,7 @@ public void Sbom_Generation_Assigns_Correct_Verbosity_IgnoreCase(string inputVer Console.SetOut(stringWriter); var task = new GenerateSbom { - BuildDropPath = CurrentDirectory, + BuildDropPath = TestBuildDropPath, PackageSupplier = PackageSupplier, PackageName = PackageName, PackageVersion = PackageVersion, @@ -354,7 +385,7 @@ public void Sbom_Generation_Assigns_Correct_Verbosity_IgnoreCase(string inputVer Console.SetOut(stringWriter); var task = new GenerateSbom { - BuildDropPath = CurrentDirectory, + BuildDropPath = TestBuildDropPath, PackageSupplier = PackageSupplier, PackageName = PackageName, PackageVersion = PackageVersion, @@ -374,4 +405,17 @@ public void Sbom_Generation_Assigns_Correct_Verbosity_IgnoreCase(string inputVer Assert.AreEqual(messageShouldBeLogged, this.messages.Any(msg => pattern.IsMatch(msg.Message))); } #endif + + private static void Xcopy(string sourceDir, string targetDir) + { + foreach (var dirPath in Directory.GetDirectories(sourceDir, "*.*", SearchOption.AllDirectories)) + { + Directory.CreateDirectory(dirPath.Replace(sourceDir, targetDir)); + } + + foreach (var newPath in Directory.GetFiles(sourceDir, "*.*", SearchOption.AllDirectories)) + { + File.Copy(newPath, newPath.Replace(sourceDir, targetDir), true); + } + } } diff --git a/test/Microsoft.Sbom.Targets.Tests/AbstractGenerateSbomTaskTests.cs b/test/Microsoft.Sbom.Targets.Tests/AbstractGenerateSbomTaskTests.cs index 3c12a8ed1..7fbbc1964 100644 --- a/test/Microsoft.Sbom.Targets.Tests/AbstractGenerateSbomTaskTests.cs +++ b/test/Microsoft.Sbom.Targets.Tests/AbstractGenerateSbomTaskTests.cs @@ -21,17 +21,23 @@ public abstract class AbstractGenerateSbomTaskTests 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 static string TestBuildDropPath; + internal static string DefaultManifestDirectory; + internal static string TemporaryDirectory; + internal static string SbomToolPath; + internal static string ExternalDocumentListFile; 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"; +#if NET472 + private const string TargetFramework = "net472"; +#else + private const string TargetFramework = "net80"; +#endif + internal Mock BuildEngine; internal List Errors; internal string ManifestPath; @@ -56,6 +62,17 @@ private void CleanupManifestDirectory() } } + protected static void ClassSetup(string testDirectoryName) + { + var executingDirectory = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); + TestBuildDropPath = Path.GetFullPath(Path.Combine(executingDirectory, "..", $"{testDirectoryName}_{TargetFramework}")); + DefaultManifestDirectory = Path.Combine(TestBuildDropPath, "_manifest"); + TemporaryDirectory = Path.Combine(TestBuildDropPath, "_temp"); + ExternalDocumentListFile = Path.GetRandomFileName(); + SbomToolPath = Path.Combine(TestBuildDropPath, "sbom-tool"); + Xcopy(executingDirectory, TestBuildDropPath); + } + [TestInitialize] public void Startup() { @@ -79,13 +96,25 @@ public void Cleanup() this.CleanupManifestDirectory(); } + protected static void ClassTearDown() + { + // Clean up the TestBuildDropPath directory + if (TestBuildDropPath is not null) + { + if (Directory.Exists(TestBuildDropPath)) + { + Directory.Delete(TestBuildDropPath, true); + } + } + } + [TestMethod] public void Sbom_Is_Successfully_Generated() { // Arrange var task = new GenerateSbom { - BuildDropPath = CurrentDirectory, + BuildDropPath = TestBuildDropPath, PackageSupplier = PackageSupplier, PackageName = PackageName, PackageVersion = PackageVersion, @@ -102,7 +131,7 @@ public void Sbom_Is_Successfully_Generated() // Assert Assert.IsTrue(result); - this.GeneratedSbomValidator.AssertSbomIsValid(this.ManifestPath, CurrentDirectory, PackageName, PackageVersion, PackageSupplier, NamespaceBaseUri); + this.GeneratedSbomValidator.AssertSbomIsValid(this.ManifestPath, TestBuildDropPath, PackageName, PackageVersion, PackageSupplier, NamespaceBaseUri); } [TestMethod] @@ -118,7 +147,7 @@ public void Sbom_Is_Successfully_Generated_Valid_URI(string namespaceBaseUri) // Arrange var task = new GenerateSbom { - BuildDropPath = CurrentDirectory, + BuildDropPath = TestBuildDropPath, PackageSupplier = PackageSupplier, PackageName = PackageName, PackageVersion = PackageVersion, @@ -135,7 +164,7 @@ public void Sbom_Is_Successfully_Generated_Valid_URI(string namespaceBaseUri) // Assert Assert.IsTrue(result); - this.GeneratedSbomValidator.AssertSbomIsValid(this.ManifestPath, CurrentDirectory, PackageName, PackageVersion, PackageSupplier, namespaceBaseUri); + this.GeneratedSbomValidator.AssertSbomIsValid(this.ManifestPath, TestBuildDropPath, PackageName, PackageVersion, PackageSupplier, namespaceBaseUri); } [TestMethod] @@ -147,7 +176,7 @@ public void Sbom_Is_Successfully_Generated_Valid_RequiredParams(string packageSu // Arrange var task = new GenerateSbom { - BuildDropPath = CurrentDirectory, + BuildDropPath = TestBuildDropPath, PackageSupplier = packageSupplier, PackageName = packageName, PackageVersion = packageVersion, @@ -164,7 +193,7 @@ public void Sbom_Is_Successfully_Generated_Valid_RequiredParams(string packageSu // Assert Assert.IsTrue(result); - this.GeneratedSbomValidator.AssertSbomIsValid(this.ManifestPath, CurrentDirectory, PackageName, PackageVersion, PackageSupplier, NamespaceBaseUri); + this.GeneratedSbomValidator.AssertSbomIsValid(this.ManifestPath, TestBuildDropPath, PackageName, PackageVersion, PackageSupplier, NamespaceBaseUri); } private static IEnumerable GetPackageSupplierCases() @@ -197,7 +226,7 @@ public void Sbom_Is_Successfully_Generated_In_Specified_Location() // Arrange var task = new GenerateSbom { - BuildDropPath = CurrentDirectory, + BuildDropPath = TestBuildDropPath, ManifestDirPath = manifestDirPath, PackageSupplier = PackageSupplier, PackageName = PackageName, @@ -217,7 +246,7 @@ public void Sbom_Is_Successfully_Generated_In_Specified_Location() Assert.IsTrue(result); this.ManifestPath = Path.Combine(manifestDirPath, "_manifest", this.SbomSpecificationDirectoryName, "manifest.spdx.json"); - this.GeneratedSbomValidator.AssertSbomIsValid(this.ManifestPath, CurrentDirectory, PackageName, PackageVersion, PackageSupplier, NamespaceBaseUri); + this.GeneratedSbomValidator.AssertSbomIsValid(this.ManifestPath, TestBuildDropPath, PackageName, PackageVersion, PackageSupplier, NamespaceBaseUri); } [TestMethod] @@ -251,7 +280,7 @@ public void Sbom_Generation_Fails_With_NotFound_BuildComponentPath() // Arrange var task = new GenerateSbom { - BuildDropPath = CurrentDirectory, + BuildDropPath = TestBuildDropPath, BuildComponentPath = ".\\non-existent\\path", PackageSupplier = PackageSupplier, PackageName = PackageName, @@ -278,7 +307,7 @@ public void Sbom_Generation_Fails_With_NotFound_ExternalDocumentListFile() // Arrange var task = new GenerateSbom { - BuildDropPath = CurrentDirectory, + BuildDropPath = TestBuildDropPath, ExternalDocumentListFile = ".\\non-existent\\path", PackageSupplier = PackageSupplier, PackageName = PackageName, @@ -305,7 +334,7 @@ public void Sbom_Generation_Fails_With_NotFound_ManifestDirPath() // Arrange var task = new GenerateSbom { - BuildDropPath = CurrentDirectory, + BuildDropPath = TestBuildDropPath, ManifestDirPath = ".\\non-existent\\path", PackageSupplier = PackageSupplier, PackageName = PackageName, @@ -330,12 +359,12 @@ public void Sbom_Generation_Fails_With_NotFound_ManifestDirPath() public void Sbom_Is_Successfully_Generated_With_Component_Path() { // Let's generate a SBOM for the current assembly - var sourceDirectory = Path.Combine(CurrentDirectory, "..", "..", ".."); + var sourceDirectory = Path.Combine(TestBuildDropPath, "..", "..", ".."); // Arrange var task = new GenerateSbom { - BuildDropPath = CurrentDirectory, + BuildDropPath = TestBuildDropPath, BuildComponentPath = sourceDirectory, PackageSupplier = PackageSupplier, PackageName = PackageName, @@ -353,7 +382,7 @@ public void Sbom_Is_Successfully_Generated_With_Component_Path() // Assert Assert.IsTrue(result); - this.GeneratedSbomValidator.AssertSbomIsValid(this.ManifestPath, CurrentDirectory, PackageName, PackageVersion, PackageSupplier, NamespaceBaseUri, buildComponentPath: sourceDirectory); + this.GeneratedSbomValidator.AssertSbomIsValid(this.ManifestPath, TestBuildDropPath, PackageName, PackageVersion, PackageSupplier, NamespaceBaseUri, buildComponentPath: sourceDirectory); } [TestMethod] @@ -366,7 +395,7 @@ public void Sbom_Is_Successfully_Generated_With_Unique_Namespace_Part_Defined(st // Arrange var task = new GenerateSbom { - BuildDropPath = CurrentDirectory, + BuildDropPath = TestBuildDropPath, PackageSupplier = PackageSupplier, PackageName = PackageName, PackageVersion = PackageVersion, @@ -384,7 +413,7 @@ public void Sbom_Is_Successfully_Generated_With_Unique_Namespace_Part_Defined(st // Assert Assert.IsTrue(result, $"{result} is not set to true."); - this.GeneratedSbomValidator.AssertSbomIsValid(this.ManifestPath, CurrentDirectory, PackageName, PackageVersion, PackageSupplier, NamespaceBaseUri, expectedNamespaceUriUniquePart: uniqueNamespacePart); + this.GeneratedSbomValidator.AssertSbomIsValid(this.ManifestPath, TestBuildDropPath, PackageName, PackageVersion, PackageSupplier, NamespaceBaseUri, expectedNamespaceUriUniquePart: uniqueNamespacePart); } #if NET472 @@ -394,7 +423,7 @@ public void Sbom_Generation_Fails_With_Tool_Path_Not_Found() // Arrange var task = new GenerateSbom { - BuildDropPath = CurrentDirectory, + BuildDropPath = TestBuildDropPath, PackageSupplier = PackageSupplier, PackageName = PackageName, PackageVersion = PackageVersion, @@ -422,7 +451,7 @@ public void Sbom_Fails_To_Generate_Due_To_File_In_Use() // Arrange var task = new GenerateSbom { - BuildDropPath = CurrentDirectory, + BuildDropPath = TestBuildDropPath, ManifestDirPath = manifestDirPath, PackageSupplier = PackageSupplier, PackageName = PackageName, @@ -449,4 +478,17 @@ public void Sbom_Fails_To_Generate_Due_To_File_In_Use() Assert.IsFalse(result); } } + + private static void Xcopy(string sourceDir, string targetDir) + { + foreach (var dirPath in Directory.GetDirectories(sourceDir, "*.*", SearchOption.AllDirectories)) + { + Directory.CreateDirectory(dirPath.Replace(sourceDir, targetDir)); + } + + foreach (var newPath in Directory.GetFiles(sourceDir, "*.*", SearchOption.AllDirectories)) + { + File.Copy(newPath, newPath.Replace(sourceDir, targetDir), true); + } + } } diff --git a/test/Microsoft.Sbom.Targets.Tests/GenerateSbomTaskSPDX_2_2InputTests.cs b/test/Microsoft.Sbom.Targets.Tests/GenerateSbomTaskSPDX_2_2InputTests.cs index 1efe7e8a3..364aa7165 100644 --- a/test/Microsoft.Sbom.Targets.Tests/GenerateSbomTaskSPDX_2_2InputTests.cs +++ b/test/Microsoft.Sbom.Targets.Tests/GenerateSbomTaskSPDX_2_2InputTests.cs @@ -12,4 +12,10 @@ namespace Microsoft.Sbom.Targets.Tests; public class GenerateSbomTaskSPDX_2_2InputTests : AbstractGenerateSbomTaskInputTests { internal override string SbomSpecification => "SPDX:2.2"; + + [ClassInitialize] + public static void Setup(TestContext testContext) => ClassSetup(nameof(GenerateSbomTaskSPDX_2_2InputTests)); + + [ClassCleanup(ClassCleanupBehavior.EndOfClass)] + public static void TearDown() => ClassTearDown(); } diff --git a/test/Microsoft.Sbom.Targets.Tests/GenerateSbomTaskSPDX_2_2Tests.cs b/test/Microsoft.Sbom.Targets.Tests/GenerateSbomTaskSPDX_2_2Tests.cs index ad60e1e9c..59750300d 100644 --- a/test/Microsoft.Sbom.Targets.Tests/GenerateSbomTaskSPDX_2_2Tests.cs +++ b/test/Microsoft.Sbom.Targets.Tests/GenerateSbomTaskSPDX_2_2Tests.cs @@ -14,4 +14,10 @@ public class GenerateSbomTaskSPDX_2_2Tests : AbstractGenerateSbomTaskTests internal override string SbomSpecificationName => "SPDX"; internal override string SbomSpecificationVersion => "2.2"; + + [ClassInitialize] + public static void Setup(TestContext testContext) => ClassSetup(nameof(GenerateSbomTaskSPDX_2_2Tests)); + + [ClassCleanup(ClassCleanupBehavior.EndOfClass)] + public static void TearDown() => ClassTearDown(); } diff --git a/test/Microsoft.Sbom.Tool.Tests/IntegrationTests.cs b/test/Microsoft.Sbom.Tool.Tests/IntegrationTests.cs index 874a4b558..c94baa867 100644 --- a/test/Microsoft.Sbom.Tool.Tests/IntegrationTests.cs +++ b/test/Microsoft.Sbom.Tool.Tests/IntegrationTests.cs @@ -4,6 +4,7 @@ using System; using System.Diagnostics; using System.IO; +using System.Linq; using System.Reflection; using System.Runtime.InteropServices; using Microsoft.VisualStudio.TestTools.UnitTesting; @@ -21,11 +22,15 @@ public class IntegrationTests public TestContext TestContext { get; set; } private static string testRunDirectory; + private static string testDropDirectory; [ClassInitialize] public static void Setup(TestContext context) { testRunDirectory = context.TestRunDirectory; + var executingDirectory = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); + testDropDirectory = Path.GetFullPath(Path.Combine(executingDirectory, "..", nameof(IntegrationTests))); + Xcopy(executingDirectory, testDropDirectory); } [ClassCleanup(ClassCleanupBehavior.EndOfClass)] @@ -39,6 +44,14 @@ public static void TearDown() Directory.Delete(testRunDirectory, true); } } + + if (testDropDirectory is not null) + { + if (Directory.Exists(testDropDirectory)) + { + Directory.Delete(testDropDirectory, true); + } + } } [TestMethod] @@ -95,7 +108,7 @@ public void E2E_GenerateAndValidateManifest_ValidationSucceeds_ReturnsZeroExitCo var (stdout, stderr, exitCode) = LaunchAndCaptureOutput(arguments); Assert.AreEqual(stderr, string.Empty); - Assert.AreEqual(0, exitCode.Value); + Assert.AreEqual(0, exitCode.Value, $"Unexpected failure: stdout = {stdout}"); Assert.IsTrue(File.Exists(outputFile), $"{outputFile} should have been created during validation"); Assert.IsTrue(File.ReadAllText(outputFile).Contains("\"Result\":\"Success\"", StringComparison.OrdinalIgnoreCase)); } @@ -162,7 +175,7 @@ public void E2E_Generate_WithBadManifestInfo_ReturnsNonZeroExitCode() } var testFolderPath = CreateTestFolder(); - var arguments = $"generate -ps IntegrationTests -pn IntegrationTests -pv 1.2.3 -m \"{testFolderPath}\" -b . -bc \"{GetSolutionFolderPath()}\" -mi randomName:randomVersion"; + var arguments = $"generate -ps IntegrationTests -pn IntegrationTests -pv 1.2.3 -m \"{testFolderPath}\" -b \"{testDropDirectory}\" -bc \"{GetSolutionFolderPath()}\" -mi randomName:randomVersion"; var (stdout, stderr, exitCode) = LaunchAndCaptureOutput(arguments); Assert.AreEqual("Please provide a valid value for the ManifestInfo (-mi) parameter. Supported values include: SPDX:2.2, SPDX:3.0. The values are case-insensitive.\r\n", stderr); Assert.AreNotEqual(0, exitCode.Value); @@ -215,7 +228,7 @@ public void E2E_Redact_WithManifestInfo_ReturnsNonZeroExitCode(string manifestIn private void GenerateManifestAndValidateSuccess(string testFolderPath, string manifestInfoValue = null) { - var arguments = $"generate -ps IntegrationTests -pn IntegrationTests -pv 1.2.3 -m \"{testFolderPath}\" -b . -bc \"{GetSolutionFolderPath()}\""; + var arguments = $"generate -ps IntegrationTests -pn IntegrationTests -pv 1.2.3 -m \"{testFolderPath}\" -b \"{testDropDirectory}\" -bc \"{GetSolutionFolderPath()}\""; if (!string.IsNullOrEmpty(manifestInfoValue)) { arguments += $" -mi SPDX:{manifestInfoValue}"; @@ -235,14 +248,14 @@ private void GenerateManifestAndValidateSuccess(string testFolderPath, string ma Assert.AreEqual(1, directories.Length, "There should be only one folder in the test directory."); Assert.AreEqual(manifestFolderPath, directories[0], "The only folder in the test directory should be a folder with the correct SBOM version name."); - Assert.AreEqual(0, exitCode.Value); + Assert.AreEqual(0, exitCode.Value, $"Unexpected failure. stdout = {stdout}"); } private (string arguments, string outputFile) GetValidateManifestArguments(string testFolderPath, string manifestInfoValue = "SPDX:2.2") { var outputFile = Path.Combine(TestContext.TestRunDirectory, TestContext.TestName, "validation.json"); var manifestRootFolderName = Path.Combine(testFolderPath, ManifestRootFolderName); - var arguments = $"validate -m \"{manifestRootFolderName}\" -b . -o \"{outputFile}\""; + var arguments = $"validate -m \"{manifestRootFolderName}\" -b \"{testDropDirectory}\" -o \"{outputFile}\""; arguments += $" -mi {manifestInfoValue}"; return (arguments, outputFile); } @@ -259,9 +272,20 @@ private static string AppendFullManifestFolderPath(string manifestDir, string sp return Path.Combine(manifestDir, ManifestRootFolderName, $"spdx_{spdxVersion ?? "2.2"}"); } + /// + /// Consistently return the path that contains our solution file. Starts from the location of the executing + /// assembly, then walks up the tree until is finds a solution file + /// + /// The path to the folder that contains the solution file private static string GetSolutionFolderPath() { - return Path.GetFullPath(Path.Combine(Assembly.GetExecutingAssembly().Location, "..", "..", "..")); + var pathToCheck = Path.GetFullPath(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)); + while (!Directory.EnumerateFiles(pathToCheck, "*.sln").Any()) + { + pathToCheck = Path.GetFullPath(Path.Combine(pathToCheck, "..")); + } + + return pathToCheck; } private static string GetAppName() @@ -332,4 +356,17 @@ private static (string stdout, string stderr, int? exitCode) LaunchAndCaptureOut return (stdout, stderr, exitCode); } + + private static void Xcopy(string sourceDir, string targetDir) + { + foreach (var dirPath in Directory.GetDirectories(sourceDir, "*.*", SearchOption.AllDirectories)) + { + Directory.CreateDirectory(dirPath.Replace(sourceDir, targetDir)); + } + + foreach (var newPath in Directory.GetFiles(sourceDir, "*.*", SearchOption.AllDirectories)) + { + File.Copy(newPath, newPath.Replace(sourceDir, targetDir), true); + } + } }