From e421f3f074dff74f60b1f47a4d82baf5c2d3f917 Mon Sep 17 00:00:00 2001 From: shantyk Date: Wed, 24 Sep 2025 02:25:15 -0600 Subject: [PATCH 01/34] Skeleton for parameterized test framework --- .../shantys-tests/KickOffTests.cs | 40 ++++++ .../shantys-tests/NITestRunner.cs | 120 ++++++++++++++++++ .../shantys-tests/TestEnvironmentManager.cs | 59 +++++++++ .../shantys-tests/TestProjectBuilder.cs | 101 +++++++++++++++ 4 files changed, 320 insertions(+) create mode 100644 detect-nuget-inspector/detect-nuget-inspector-tests/shantys-tests/KickOffTests.cs create mode 100644 detect-nuget-inspector/detect-nuget-inspector-tests/shantys-tests/NITestRunner.cs create mode 100644 detect-nuget-inspector/detect-nuget-inspector-tests/shantys-tests/TestEnvironmentManager.cs create mode 100644 detect-nuget-inspector/detect-nuget-inspector-tests/shantys-tests/TestProjectBuilder.cs diff --git a/detect-nuget-inspector/detect-nuget-inspector-tests/shantys-tests/KickOffTests.cs b/detect-nuget-inspector/detect-nuget-inspector-tests/shantys-tests/KickOffTests.cs new file mode 100644 index 0000000..efba40b --- /dev/null +++ b/detect-nuget-inspector/detect-nuget-inspector-tests/shantys-tests/KickOffTests.cs @@ -0,0 +1,40 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; + +namespace DetectNugetInspectorTests.ShantysTests +{ + [TestClass] + public class KickOffTests + { + [TestMethod] + public void TestBasicSetup() + { + var runner = new NITestRunner(); + var result = runner.RunBasicSetupTest("6.0.100", "MyTestSolution"); + + Assert.IsTrue(result.Success, result.Message); + Console.WriteLine(result.Message); + } + + [TestMethod] + public void TestBasicSetup_WithDifferentVersion() + { + var runner = new NITestRunner(); + var result = runner.RunBasicSetupTest("6.0.136", "AnotherTestSolution"); + + Assert.IsTrue(result.Success, result.Message); + Console.WriteLine(result.Message); + } + + [TestMethod] + public void TestBasicSetup_InvalidDotNetVersion() + { + var runner = new NITestRunner(); + + Assert.ThrowsException(() => + { + runner.RunBasicSetupTest("99.0.999", "FailureSolution"); + }); + } + } +} \ No newline at end of file diff --git a/detect-nuget-inspector/detect-nuget-inspector-tests/shantys-tests/NITestRunner.cs b/detect-nuget-inspector/detect-nuget-inspector-tests/shantys-tests/NITestRunner.cs new file mode 100644 index 0000000..15a5692 --- /dev/null +++ b/detect-nuget-inspector/detect-nuget-inspector-tests/shantys-tests/NITestRunner.cs @@ -0,0 +1,120 @@ +using System; +using System.Collections.Generic; +using System.IO; + +namespace DetectNugetInspectorTests.ShantysTests +{ + public class NITestRunner + { + private List _executedBranches = new List(); + + public NIResult RunBasicSetupTest(string dotnetVersion = "6.0.136", string solutionName = "TestSolution") + { + Console.WriteLine($"Starting basic setup test with .NET version: {dotnetVersion}"); + + // 1. Setup environment + var env = new TestEnvironmentManager(); + try + { + env.SetupEnvironment(dotnetVersion); + Console.WriteLine($"✓ Environment setup successful - Working directory: {env.WorkingDirectory}"); + } + catch (Exception ex) + { + Console.WriteLine($"✗ Environment setup failed: {ex.Message}"); + throw; + } + + // 2. Create simple solution + var projectBuilder = new TestProjectBuilder(env); + string solutionPath; + try + { + solutionPath = projectBuilder + .CreateSimpleSolution(solutionName) + .Build(); + Console.WriteLine($"✓ Solution created successfully at: {solutionPath}"); + } + catch (Exception ex) + { + Console.WriteLine($"✗ Solution creation failed: {ex.Message}"); + env.Cleanup(); + throw; + } + + // 3. Verify what was created + try + { + VerifyCreatedStructure(solutionPath, solutionName); + Console.WriteLine("✓ Solution structure verification passed"); + } + catch (Exception ex) + { + Console.WriteLine($"✗ Solution structure verification failed: {ex.Message}"); + env.Cleanup(); + throw; + } + + // 4. Cleanup + try + { + env.Cleanup(); + Console.WriteLine("✓ Cleanup completed successfully"); + } + catch (Exception ex) + { + Console.WriteLine($"⚠ Cleanup warning: {ex.Message}"); + } + + return new NIResult + { + Success = true, + Message = $"Basic setup test completed successfully for .NET {dotnetVersion}", + SolutionPath = solutionPath + }; + } + + private void VerifyCreatedStructure(string solutionPath, string solutionName) + { + // Check solution file exists + var solutionFile = Path.Combine(solutionPath, $"{solutionName}.sln"); + if (!File.Exists(solutionFile)) + throw new InvalidOperationException($"Solution file not found: {solutionFile}"); + + // Check Project1 directory exists + var project1Dir = Path.Combine(solutionPath, "Project1"); + if (!Directory.Exists(project1Dir)) + throw new InvalidOperationException($"Project1 directory not found: {project1Dir}"); + + // Check Project1.csproj exists + var project1File = Path.Combine(project1Dir, "Project1.csproj"); + if (!File.Exists(project1File)) + throw new InvalidOperationException($"Project1.csproj not found: {project1File}"); + + Console.WriteLine($" - Solution file: {solutionFile}"); + Console.WriteLine($" - Project1 directory: {project1Dir}"); + Console.WriteLine($" - Project1.csproj: {project1File}"); + } + + public List GetExecutedBranches() + { + return new List(_executedBranches); + } + } + + public class NIResult + { + public bool Success { get; set; } + public string Message { get; set; } + public string SolutionPath { get; set; } + // Keep the old properties for when we add back NI inspection + public object Container { get; set; } + public object Dependencies { get; set; } + public object Packages { get; set; } + } + + public class AssertionException : Exception + { + public AssertionException(string message) : base(message) { } + } +} \ No newline at end of file diff --git a/detect-nuget-inspector/detect-nuget-inspector-tests/shantys-tests/TestEnvironmentManager.cs b/detect-nuget-inspector/detect-nuget-inspector-tests/shantys-tests/TestEnvironmentManager.cs new file mode 100644 index 0000000..5659678 --- /dev/null +++ b/detect-nuget-inspector/detect-nuget-inspector-tests/shantys-tests/TestEnvironmentManager.cs @@ -0,0 +1,59 @@ +using System; +using System.IO; +using System.Diagnostics; + +namespace DetectNugetInspectorTests.ShantysTests +{ + public class TestEnvironmentManager + { + public string DotNetVersion { get; private set; } + public string DotNetCommand { get; private set; } // New property + public string WorkingDirectory { get; private set; } + + public TestEnvironmentManager SetupEnvironment(string dotnetVersion, string dotnetCommand = "dotnet") + { + DotNetVersion = dotnetVersion; + DotNetCommand = dotnetCommand; // Store the command to use + WorkingDirectory = Path.Combine(Path.GetTempPath(), "NI-Tests", Guid.NewGuid().ToString()); + + Directory.CreateDirectory(WorkingDirectory); + + // Verify dotnet version is available with the specified command + ValidateDotNetVersion(dotnetVersion, dotnetCommand); + + return this; + } + + private void ValidateDotNetVersion(string version, string command) + { + var process = new Process + { + StartInfo = new ProcessStartInfo + { + FileName = command, // Use the specified command + Arguments = "--list-sdks", + UseShellExecute = false, + RedirectStandardOutput = true, + CreateNoWindow = true + } + }; + + process.Start(); + string output = process.StandardOutput.ReadToEnd(); + process.WaitForExit(); + + if (!output.Contains(version)) + { + throw new InvalidOperationException($"Required .NET SDK version {version} is not available with command '{command}'."); + } + } + + public void Cleanup() + { + if (Directory.Exists(WorkingDirectory)) + { + Directory.Delete(WorkingDirectory, recursive: true); + } + } + } +} \ No newline at end of file diff --git a/detect-nuget-inspector/detect-nuget-inspector-tests/shantys-tests/TestProjectBuilder.cs b/detect-nuget-inspector/detect-nuget-inspector-tests/shantys-tests/TestProjectBuilder.cs new file mode 100644 index 0000000..c467f48 --- /dev/null +++ b/detect-nuget-inspector/detect-nuget-inspector-tests/shantys-tests/TestProjectBuilder.cs @@ -0,0 +1,101 @@ +using System; +using System.Diagnostics; +using System.IO; + +namespace DetectNugetInspectorTests.ShantysTests +{ + public class TestProjectBuilder + { + private readonly TestEnvironmentManager _environment; + private string _solutionDirectory; + private string _solutionName; + + public TestProjectBuilder(TestEnvironmentManager environment) + { + _environment = environment; + } + + public TestProjectBuilder CreateSimpleSolution(string solutionName = "TestSolution") + { + _solutionName = solutionName; + _solutionDirectory = Path.Combine(_environment.WorkingDirectory, solutionName); + Directory.CreateDirectory(_solutionDirectory); + + // Create solution + var createSolutionProcess = new Process + { + StartInfo = new ProcessStartInfo + { + FileName = "dotnet", + Arguments = $"new sln -n {solutionName}", + WorkingDirectory = _solutionDirectory, + UseShellExecute = false, + RedirectStandardOutput = true, + RedirectStandardError = true, + CreateNoWindow = true + } + }; + + createSolutionProcess.Start(); + createSolutionProcess.WaitForExit(); + + if (createSolutionProcess.ExitCode != 0) + { + throw new InvalidOperationException($"Failed to create solution: {createSolutionProcess.StandardError.ReadToEnd()}"); + } + + // Create Project1 + var createProjectProcess = new Process + { + StartInfo = new ProcessStartInfo + { + FileName = "dotnet", + Arguments = "new console -n Project1", + WorkingDirectory = _solutionDirectory, + UseShellExecute = false, + RedirectStandardOutput = true, + RedirectStandardError = true, + CreateNoWindow = true + } + }; + + createProjectProcess.Start(); + createProjectProcess.WaitForExit(); + + if (createProjectProcess.ExitCode != 0) + { + throw new InvalidOperationException($"Failed to create Project1: {createProjectProcess.StandardError.ReadToEnd()}"); + } + + // Add Project1 to solution + var addProjectProcess = new Process + { + StartInfo = new ProcessStartInfo + { + FileName = "dotnet", + Arguments = "sln add Project1/Project1.csproj", + WorkingDirectory = _solutionDirectory, + UseShellExecute = false, + RedirectStandardOutput = true, + RedirectStandardError = true, + CreateNoWindow = true + } + }; + + addProjectProcess.Start(); + addProjectProcess.WaitForExit(); + + if (addProjectProcess.ExitCode != 0) + { + throw new InvalidOperationException($"Failed to add Project1 to solution: {addProjectProcess.StandardError.ReadToEnd()}"); + } + + return this; + } + + public string Build() + { + return _solutionDirectory; + } + } +} \ No newline at end of file From 3753a69721aa01a5dad8eb15996c8e379cf90d5b Mon Sep 17 00:00:00 2001 From: shantyk Date: Wed, 24 Sep 2025 05:27:14 -0600 Subject: [PATCH 02/34] Parameterize dotnet version for test project creation --- .../shantys-tests/KickOffTests.cs | 25 +++--- .../shantys-tests/NITestRunner.cs | 8 +- .../shantys-tests/TestEnvironmentManager.cs | 80 ++++++++++++++++--- .../shantys-tests/TestProjectBuilder.cs | 6 +- 4 files changed, 86 insertions(+), 33 deletions(-) diff --git a/detect-nuget-inspector/detect-nuget-inspector-tests/shantys-tests/KickOffTests.cs b/detect-nuget-inspector/detect-nuget-inspector-tests/shantys-tests/KickOffTests.cs index efba40b..19aa951 100644 --- a/detect-nuget-inspector/detect-nuget-inspector-tests/shantys-tests/KickOffTests.cs +++ b/detect-nuget-inspector/detect-nuget-inspector-tests/shantys-tests/KickOffTests.cs @@ -6,35 +6,34 @@ namespace DetectNugetInspectorTests.ShantysTests [TestClass] public class KickOffTests { + [TestMethod] - public void TestBasicSetup() + public void TestBasicSetup_InvalidDotNetVersion() { var runner = new NITestRunner(); - var result = runner.RunBasicSetupTest("6.0.100", "MyTestSolution"); - Assert.IsTrue(result.Success, result.Message); - Console.WriteLine(result.Message); + Assert.ThrowsException(() => + { + runner.RunBasicSetupTest("99.0.999", "FailureSolution"); + }); } [TestMethod] - public void TestBasicSetup_WithDifferentVersion() + public void TestBasicSetup_DotNet6() { var runner = new NITestRunner(); - var result = runner.RunBasicSetupTest("6.0.136", "AnotherTestSolution"); + var result = runner.RunBasicSetupTest("6.0.428", "MyTestSolution", "dotnet6"); Assert.IsTrue(result.Success, result.Message); - Console.WriteLine(result.Message); } - [TestMethod] - public void TestBasicSetup_InvalidDotNetVersion() + [TestMethod] + public void TestBasicSetup_DotNet7() { var runner = new NITestRunner(); + var result = runner.RunBasicSetupTest("7.0.410", "MyTestSolution", "dotnet7"); - Assert.ThrowsException(() => - { - runner.RunBasicSetupTest("99.0.999", "FailureSolution"); - }); + Assert.IsTrue(result.Success, result.Message); } } } \ No newline at end of file diff --git a/detect-nuget-inspector/detect-nuget-inspector-tests/shantys-tests/NITestRunner.cs b/detect-nuget-inspector/detect-nuget-inspector-tests/shantys-tests/NITestRunner.cs index 15a5692..cd8ee36 100644 --- a/detect-nuget-inspector/detect-nuget-inspector-tests/shantys-tests/NITestRunner.cs +++ b/detect-nuget-inspector/detect-nuget-inspector-tests/shantys-tests/NITestRunner.cs @@ -8,15 +8,15 @@ public class NITestRunner { private List _executedBranches = new List(); - public NIResult RunBasicSetupTest(string dotnetVersion = "6.0.136", string solutionName = "TestSolution") + public NIResult RunBasicSetupTest(string dotnetVersion = "6.0.428", string solutionName = "TestSolution", string dotnetCommand = "dotnet") { - Console.WriteLine($"Starting basic setup test with .NET version: {dotnetVersion}"); + Console.WriteLine($"Starting basic setup test with .NET version: {dotnetVersion} using command: {dotnetCommand}"); // 1. Setup environment var env = new TestEnvironmentManager(); try { - env.SetupEnvironment(dotnetVersion); + env.SetupEnvironment(dotnetVersion, dotnetCommand); Console.WriteLine($"✓ Environment setup successful - Working directory: {env.WorkingDirectory}"); } catch (Exception ex) @@ -69,7 +69,7 @@ public NIResult RunBasicSetupTest(string dotnetVersion = "6.0.136", string solut return new NIResult { Success = true, - Message = $"Basic setup test completed successfully for .NET {dotnetVersion}", + Message = $"Basic setup test completed successfully for .NET {dotnetVersion} using {dotnetCommand}", SolutionPath = solutionPath }; } diff --git a/detect-nuget-inspector/detect-nuget-inspector-tests/shantys-tests/TestEnvironmentManager.cs b/detect-nuget-inspector/detect-nuget-inspector-tests/shantys-tests/TestEnvironmentManager.cs index 5659678..93783a3 100644 --- a/detect-nuget-inspector/detect-nuget-inspector-tests/shantys-tests/TestEnvironmentManager.cs +++ b/detect-nuget-inspector/detect-nuget-inspector-tests/shantys-tests/TestEnvironmentManager.cs @@ -1,59 +1,113 @@ using System; -using System.IO; using System.Diagnostics; +using System.IO; namespace DetectNugetInspectorTests.ShantysTests { public class TestEnvironmentManager { public string DotNetVersion { get; private set; } - public string DotNetCommand { get; private set; } // New property + public string NuGetVersion { get; private set; } + public string DotNetCommand { get; private set; } public string WorkingDirectory { get; private set; } public TestEnvironmentManager SetupEnvironment(string dotnetVersion, string dotnetCommand = "dotnet") { DotNetVersion = dotnetVersion; - DotNetCommand = dotnetCommand; // Store the command to use + DotNetCommand = ResolveDotNetCommand(dotnetCommand); // Resolve to actual executable path, will need to be changed/generalized so this works in jenkins WorkingDirectory = Path.Combine(Path.GetTempPath(), "NI-Tests", Guid.NewGuid().ToString()); Directory.CreateDirectory(WorkingDirectory); - // Verify dotnet version is available with the specified command - ValidateDotNetVersion(dotnetVersion, dotnetCommand); + // Validate and log .NET version + ValidateAndLogVersions(dotnetVersion, DotNetCommand); return this; } - private void ValidateDotNetVersion(string version, string command) + private string ResolveDotNetCommand(string command) + { + // The build machine has aliases for dotnet 3,5 and 6 + switch (command) + { + case "dotnet6": + return "~/.dotnet/dotnet".Replace("~", Environment.GetFolderPath(Environment.SpecialFolder.UserProfile)); + case "dotnet7": + return "~/.dotnet7/dotnet".Replace("~", Environment.GetFolderPath(Environment.SpecialFolder.UserProfile)); + default: + return command; // Default dotnet (6) + } + } + + private void ValidateAndLogVersions(string expectedVersion, string command) + { + Console.WriteLine($"🔍 Validating environment with command: {command}"); + + // Check .NET version + var dotnetVersionResult = RunCommand(command, "--version"); + if (dotnetVersionResult.ExitCode != 0) + { + throw new InvalidOperationException($"Failed to get .NET version using command '{command}': {dotnetVersionResult.Error}"); + } + + var actualDotNetVersion = dotnetVersionResult.Output.Trim(); + Console.WriteLine($"📋 .NET Version: {actualDotNetVersion}"); + + // Throw exception if the requested version doesn't match what's available + if (!actualDotNetVersion.StartsWith(expectedVersion)) + { + Console.WriteLine($"❌ Version mismatch: Expected {expectedVersion}, but got {actualDotNetVersion}"); + throw new InvalidOperationException($"Requested .NET version {expectedVersion} is not available. System returned version {actualDotNetVersion}. Please install the required .NET SDK version or update your test."); + } + + // Check NuGet version + var nugetVersionResult = RunCommand(command, "nuget --version"); + if (nugetVersionResult.ExitCode == 0) + { + NuGetVersion = nugetVersionResult.Output.Trim(); + Console.WriteLine($"📦 NuGet Version: {NuGetVersion}"); + } + else + { + Console.WriteLine($"⚠️ Could not determine NuGet version: {nugetVersionResult.Error}"); + NuGetVersion = "Unknown"; + } + + Console.WriteLine($"📁 Working Directory: {WorkingDirectory}"); + Console.WriteLine("✅ Environment validation complete"); + } + + private (int ExitCode, string Output, string Error) RunCommand(string command, string arguments) { var process = new Process { StartInfo = new ProcessStartInfo { - FileName = command, // Use the specified command - Arguments = "--list-sdks", + FileName = command, + Arguments = arguments, UseShellExecute = false, RedirectStandardOutput = true, + RedirectStandardError = true, CreateNoWindow = true } }; process.Start(); string output = process.StandardOutput.ReadToEnd(); + string error = process.StandardError.ReadToEnd(); process.WaitForExit(); - if (!output.Contains(version)) - { - throw new InvalidOperationException($"Required .NET SDK version {version} is not available with command '{command}'."); - } + return (process.ExitCode, output, error); } public void Cleanup() { if (Directory.Exists(WorkingDirectory)) { - Directory.Delete(WorkingDirectory, recursive: true); + Directory.Delete(WorkingDirectory, true); + Console.WriteLine($"🧹 Cleaned up working directory: {WorkingDirectory}"); } + } } } \ No newline at end of file diff --git a/detect-nuget-inspector/detect-nuget-inspector-tests/shantys-tests/TestProjectBuilder.cs b/detect-nuget-inspector/detect-nuget-inspector-tests/shantys-tests/TestProjectBuilder.cs index c467f48..ccf8fc5 100644 --- a/detect-nuget-inspector/detect-nuget-inspector-tests/shantys-tests/TestProjectBuilder.cs +++ b/detect-nuget-inspector/detect-nuget-inspector-tests/shantys-tests/TestProjectBuilder.cs @@ -26,7 +26,7 @@ public TestProjectBuilder CreateSimpleSolution(string solutionName = "TestSoluti { StartInfo = new ProcessStartInfo { - FileName = "dotnet", + FileName = _environment.DotNetCommand, // Use the environment's command Arguments = $"new sln -n {solutionName}", WorkingDirectory = _solutionDirectory, UseShellExecute = false, @@ -49,7 +49,7 @@ public TestProjectBuilder CreateSimpleSolution(string solutionName = "TestSoluti { StartInfo = new ProcessStartInfo { - FileName = "dotnet", + FileName = _environment.DotNetCommand, // Use the environment's command Arguments = "new console -n Project1", WorkingDirectory = _solutionDirectory, UseShellExecute = false, @@ -72,7 +72,7 @@ public TestProjectBuilder CreateSimpleSolution(string solutionName = "TestSoluti { StartInfo = new ProcessStartInfo { - FileName = "dotnet", + FileName = _environment.DotNetCommand, // Use the environment's command Arguments = "sln add Project1/Project1.csproj", WorkingDirectory = _solutionDirectory, UseShellExecute = false, From 9d42be9e13faa6af599d5b94a3fa463272717550 Mon Sep 17 00:00:00 2001 From: shantyk Date: Thu, 25 Sep 2025 15:31:49 -0600 Subject: [PATCH 03/34] Fix build error for test project --- .../detect-nuget-inspector-tests.csproj | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/detect-nuget-inspector/detect-nuget-inspector-tests/detect-nuget-inspector-tests.csproj b/detect-nuget-inspector/detect-nuget-inspector-tests/detect-nuget-inspector-tests.csproj index c26790f..0086c64 100644 --- a/detect-nuget-inspector/detect-nuget-inspector-tests/detect-nuget-inspector-tests.csproj +++ b/detect-nuget-inspector/detect-nuget-inspector-tests/detect-nuget-inspector-tests.csproj @@ -7,6 +7,11 @@ enable false + + false + false From c9fec8227a376311741e3193fdf2b82b3b62355a Mon Sep 17 00:00:00 2001 From: shantyk Date: Thu, 25 Sep 2025 16:58:37 -0600 Subject: [PATCH 04/34] Add test for when the desired dotnet is not installed --- .../shantys-tests/KickOffTests.cs | 19 +++++++++++++++---- .../shantys-tests/TestEnvironmentManager.cs | 10 +++++----- 2 files changed, 20 insertions(+), 9 deletions(-) diff --git a/detect-nuget-inspector/detect-nuget-inspector-tests/shantys-tests/KickOffTests.cs b/detect-nuget-inspector/detect-nuget-inspector-tests/shantys-tests/KickOffTests.cs index 19aa951..109b902 100644 --- a/detect-nuget-inspector/detect-nuget-inspector-tests/shantys-tests/KickOffTests.cs +++ b/detect-nuget-inspector/detect-nuget-inspector-tests/shantys-tests/KickOffTests.cs @@ -11,7 +11,7 @@ public class KickOffTests public void TestBasicSetup_InvalidDotNetVersion() { var runner = new NITestRunner(); - + Assert.ThrowsException(() => { runner.RunBasicSetupTest("99.0.999", "FailureSolution"); @@ -23,17 +23,28 @@ public void TestBasicSetup_DotNet6() { var runner = new NITestRunner(); var result = runner.RunBasicSetupTest("6.0.428", "MyTestSolution", "dotnet6"); - + Assert.IsTrue(result.Success, result.Message); } - [TestMethod] + [TestMethod] public void TestBasicSetup_DotNet7() { var runner = new NITestRunner(); var result = runner.RunBasicSetupTest("7.0.410", "MyTestSolution", "dotnet7"); - + Assert.IsTrue(result.Success, result.Message); } + + [TestMethod] + public void TestBasicSetup_DotNet8() + { + var runner = new NITestRunner(); + + Assert.ThrowsException(() => + { + runner.RunBasicSetupTest("8.0.0", "MyTestSolution", "dotnet8"); + }); + } } } \ No newline at end of file diff --git a/detect-nuget-inspector/detect-nuget-inspector-tests/shantys-tests/TestEnvironmentManager.cs b/detect-nuget-inspector/detect-nuget-inspector-tests/shantys-tests/TestEnvironmentManager.cs index 93783a3..63942a2 100644 --- a/detect-nuget-inspector/detect-nuget-inspector-tests/shantys-tests/TestEnvironmentManager.cs +++ b/detect-nuget-inspector/detect-nuget-inspector-tests/shantys-tests/TestEnvironmentManager.cs @@ -11,10 +11,10 @@ public class TestEnvironmentManager public string DotNetCommand { get; private set; } public string WorkingDirectory { get; private set; } - public TestEnvironmentManager SetupEnvironment(string dotnetVersion, string dotnetCommand = "dotnet") + public TestEnvironmentManager SetupEnvironment(string dotnetVersion, string desiredDotnetCommand = "dotnet") { DotNetVersion = dotnetVersion; - DotNetCommand = ResolveDotNetCommand(dotnetCommand); // Resolve to actual executable path, will need to be changed/generalized so this works in jenkins + DotNetCommand = ResolveDotNetCommand(desiredDotnetCommand); // Resolve to actual executable path, will need to be changed/generalized so this works in jenkins WorkingDirectory = Path.Combine(Path.GetTempPath(), "NI-Tests", Guid.NewGuid().ToString()); Directory.CreateDirectory(WorkingDirectory); @@ -27,7 +27,7 @@ public TestEnvironmentManager SetupEnvironment(string dotnetVersion, string dotn private string ResolveDotNetCommand(string command) { - // The build machine has aliases for dotnet 3,5 and 6 + // The build machine has symlinks for dotnet3,5 and 6. This method will need to be made more robust before being added to jenkins pipeline to just find the desired version on the system if it exists. And maybe not expect installations to be in certain directories. switch (command) { case "dotnet6": @@ -35,7 +35,7 @@ private string ResolveDotNetCommand(string command) case "dotnet7": return "~/.dotnet7/dotnet".Replace("~", Environment.GetFolderPath(Environment.SpecialFolder.UserProfile)); default: - return command; // Default dotnet (6) + return "dotnet"; // Default dotnet with no alias (6) } } @@ -57,7 +57,7 @@ private void ValidateAndLogVersions(string expectedVersion, string command) if (!actualDotNetVersion.StartsWith(expectedVersion)) { Console.WriteLine($"❌ Version mismatch: Expected {expectedVersion}, but got {actualDotNetVersion}"); - throw new InvalidOperationException($"Requested .NET version {expectedVersion} is not available. System returned version {actualDotNetVersion}. Please install the required .NET SDK version or update your test."); + throw new InvalidOperationException($"Requested .NET version {expectedVersion} is not available. System returned version {actualDotNetVersion}. Please install the required .NET SDK version and create appropriate alias."); } // Check NuGet version From b699f1ed0e1ecbbe1fde4b6512a550dcffd3f5f3 Mon Sep 17 00:00:00 2001 From: shantyk Date: Mon, 6 Oct 2025 16:15:23 -0600 Subject: [PATCH 05/34] Update tests for build machine --- .../shantys-tests/KickOffTests.cs | 4 ++++ .../shantys-tests/TestEnvironmentManager.cs | 7 ++++--- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/detect-nuget-inspector/detect-nuget-inspector-tests/shantys-tests/KickOffTests.cs b/detect-nuget-inspector/detect-nuget-inspector-tests/shantys-tests/KickOffTests.cs index 109b902..1784a3d 100644 --- a/detect-nuget-inspector/detect-nuget-inspector-tests/shantys-tests/KickOffTests.cs +++ b/detect-nuget-inspector/detect-nuget-inspector-tests/shantys-tests/KickOffTests.cs @@ -18,6 +18,8 @@ public void TestBasicSetup_InvalidDotNetVersion() }); } + + // dotnet 6 tests (nuget v6.3.4.2) [TestMethod] public void TestBasicSetup_DotNet6() { @@ -27,6 +29,7 @@ public void TestBasicSetup_DotNet6() Assert.IsTrue(result.Success, result.Message); } + // dotnet 7 tests (nuget v6.7.1.1) [TestMethod] public void TestBasicSetup_DotNet7() { @@ -36,6 +39,7 @@ public void TestBasicSetup_DotNet7() Assert.IsTrue(result.Success, result.Message); } + // dotnet 8 tests (nuget v...) [TestMethod] public void TestBasicSetup_DotNet8() { diff --git a/detect-nuget-inspector/detect-nuget-inspector-tests/shantys-tests/TestEnvironmentManager.cs b/detect-nuget-inspector/detect-nuget-inspector-tests/shantys-tests/TestEnvironmentManager.cs index 63942a2..f23a580 100644 --- a/detect-nuget-inspector/detect-nuget-inspector-tests/shantys-tests/TestEnvironmentManager.cs +++ b/detect-nuget-inspector/detect-nuget-inspector-tests/shantys-tests/TestEnvironmentManager.cs @@ -27,11 +27,12 @@ public TestEnvironmentManager SetupEnvironment(string dotnetVersion, string desi private string ResolveDotNetCommand(string command) { - // The build machine has symlinks for dotnet3,5 and 6. This method will need to be made more robust before being added to jenkins pipeline to just find the desired version on the system if it exists. And maybe not expect installations to be in certain directories. + // The build machine has symlinks for dotnet3, 5 and 6. This method will need to be made more robust before being added to jenkins pipeline to just find the desired version on the system if it exists. And maybe not expect installations to be in certain directories. switch (command) { case "dotnet6": - return "~/.dotnet/dotnet".Replace("~", Environment.GetFolderPath(Environment.SpecialFolder.UserProfile)); + return "dotnet6"; + //return "~/.dotnet/dotnet".Replace("~", Environment.GetFolderPath(Environment.SpecialFolder.UserProfile)); case "dotnet7": return "~/.dotnet7/dotnet".Replace("~", Environment.GetFolderPath(Environment.SpecialFolder.UserProfile)); default: @@ -44,7 +45,7 @@ private void ValidateAndLogVersions(string expectedVersion, string command) Console.WriteLine($"🔍 Validating environment with command: {command}"); // Check .NET version - var dotnetVersionResult = RunCommand(command, "--version"); + var dotnetVersionResult = RunCommand(command, " --version"); if (dotnetVersionResult.ExitCode != 0) { throw new InvalidOperationException($"Failed to get .NET version using command '{command}': {dotnetVersionResult.Error}"); From d7bec03dedc5fab5c170af5167bde9393cd36c58 Mon Sep 17 00:00:00 2001 From: shantyk Date: Mon, 6 Oct 2025 16:38:57 -0600 Subject: [PATCH 06/34] Tweaking to make tests work in jenkins --- .../detect-nuget-inspector-tests/shantys-tests/KickOffTests.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/detect-nuget-inspector/detect-nuget-inspector-tests/shantys-tests/KickOffTests.cs b/detect-nuget-inspector/detect-nuget-inspector-tests/shantys-tests/KickOffTests.cs index 1784a3d..6d63180 100644 --- a/detect-nuget-inspector/detect-nuget-inspector-tests/shantys-tests/KickOffTests.cs +++ b/detect-nuget-inspector/detect-nuget-inspector-tests/shantys-tests/KickOffTests.cs @@ -24,7 +24,7 @@ public void TestBasicSetup_InvalidDotNetVersion() public void TestBasicSetup_DotNet6() { var runner = new NITestRunner(); - var result = runner.RunBasicSetupTest("6.0.428", "MyTestSolution", "dotnet6"); + var result = runner.RunBasicSetupTest("6.0.201", "MyTestSolution", "dotnet6"); Assert.IsTrue(result.Success, result.Message); } From 76905e958be24d7688198e193839efc292557547 Mon Sep 17 00:00:00 2001 From: shantyk Date: Mon, 6 Oct 2025 20:33:44 -0600 Subject: [PATCH 07/34] Update fail scenrios with better error msgs --- .../shantys-tests/KickOffTests.cs | 2 +- .../shantys-tests/NITestRunner.cs | 2 +- .../shantys-tests/TestEnvironmentManager.cs | 57 ++++++++----------- 3 files changed, 27 insertions(+), 34 deletions(-) diff --git a/detect-nuget-inspector/detect-nuget-inspector-tests/shantys-tests/KickOffTests.cs b/detect-nuget-inspector/detect-nuget-inspector-tests/shantys-tests/KickOffTests.cs index 6d63180..20a3a4e 100644 --- a/detect-nuget-inspector/detect-nuget-inspector-tests/shantys-tests/KickOffTests.cs +++ b/detect-nuget-inspector/detect-nuget-inspector-tests/shantys-tests/KickOffTests.cs @@ -14,7 +14,7 @@ public void TestBasicSetup_InvalidDotNetVersion() Assert.ThrowsException(() => { - runner.RunBasicSetupTest("99.0.999", "FailureSolution"); + runner.RunBasicSetupTest("99.0.999", "FailureSolution", "nonExistentDotnetVersion"); }); } diff --git a/detect-nuget-inspector/detect-nuget-inspector-tests/shantys-tests/NITestRunner.cs b/detect-nuget-inspector/detect-nuget-inspector-tests/shantys-tests/NITestRunner.cs index cd8ee36..ac6c12a 100644 --- a/detect-nuget-inspector/detect-nuget-inspector-tests/shantys-tests/NITestRunner.cs +++ b/detect-nuget-inspector/detect-nuget-inspector-tests/shantys-tests/NITestRunner.cs @@ -8,7 +8,7 @@ public class NITestRunner { private List _executedBranches = new List(); - public NIResult RunBasicSetupTest(string dotnetVersion = "6.0.428", string solutionName = "TestSolution", string dotnetCommand = "dotnet") + public NIResult RunBasicSetupTest(string dotnetVersion, string solutionName, string dotnetCommand) { Console.WriteLine($"Starting basic setup test with .NET version: {dotnetVersion} using command: {dotnetCommand}"); diff --git a/detect-nuget-inspector/detect-nuget-inspector-tests/shantys-tests/TestEnvironmentManager.cs b/detect-nuget-inspector/detect-nuget-inspector-tests/shantys-tests/TestEnvironmentManager.cs index f23a580..4c8d017 100644 --- a/detect-nuget-inspector/detect-nuget-inspector-tests/shantys-tests/TestEnvironmentManager.cs +++ b/detect-nuget-inspector/detect-nuget-inspector-tests/shantys-tests/TestEnvironmentManager.cs @@ -14,32 +14,17 @@ public class TestEnvironmentManager public TestEnvironmentManager SetupEnvironment(string dotnetVersion, string desiredDotnetCommand = "dotnet") { DotNetVersion = dotnetVersion; - DotNetCommand = ResolveDotNetCommand(desiredDotnetCommand); // Resolve to actual executable path, will need to be changed/generalized so this works in jenkins + DotNetCommand = desiredDotnetCommand; WorkingDirectory = Path.Combine(Path.GetTempPath(), "NI-Tests", Guid.NewGuid().ToString()); Directory.CreateDirectory(WorkingDirectory); - // Validate and log .NET version + // Validate and log .NET and NuGet versions ValidateAndLogVersions(dotnetVersion, DotNetCommand); return this; } - private string ResolveDotNetCommand(string command) - { - // The build machine has symlinks for dotnet3, 5 and 6. This method will need to be made more robust before being added to jenkins pipeline to just find the desired version on the system if it exists. And maybe not expect installations to be in certain directories. - switch (command) - { - case "dotnet6": - return "dotnet6"; - //return "~/.dotnet/dotnet".Replace("~", Environment.GetFolderPath(Environment.SpecialFolder.UserProfile)); - case "dotnet7": - return "~/.dotnet7/dotnet".Replace("~", Environment.GetFolderPath(Environment.SpecialFolder.UserProfile)); - default: - return "dotnet"; // Default dotnet with no alias (6) - } - } - private void ValidateAndLogVersions(string expectedVersion, string command) { Console.WriteLine($"🔍 Validating environment with command: {command}"); @@ -80,25 +65,33 @@ private void ValidateAndLogVersions(string expectedVersion, string command) private (int ExitCode, string Output, string Error) RunCommand(string command, string arguments) { - var process = new Process + try { - StartInfo = new ProcessStartInfo + var process = new Process { - FileName = command, - Arguments = arguments, - UseShellExecute = false, - RedirectStandardOutput = true, - RedirectStandardError = true, - CreateNoWindow = true - } - }; + StartInfo = new ProcessStartInfo + { + FileName = command, + Arguments = arguments, + UseShellExecute = false, + RedirectStandardOutput = true, + RedirectStandardError = true, + CreateNoWindow = true + } + }; - process.Start(); - string output = process.StandardOutput.ReadToEnd(); - string error = process.StandardError.ReadToEnd(); - process.WaitForExit(); + process.Start(); + string output = process.StandardOutput.ReadToEnd(); + string error = process.StandardError.ReadToEnd(); + process.WaitForExit(); - return (process.ExitCode, output, error); + return (process.ExitCode, output, error); + } + catch (Exception ex) + { + //Console.Error.WriteLine($"❌ Error running command '{command} {arguments}': {ex.Message}"); + return (-1, string.Empty, ex.Message); + } } public void Cleanup() From a861c1d45aa8b4eaebcd6fc9fa2ef978aba2ce6a Mon Sep 17 00:00:00 2001 From: shantyk Date: Mon, 6 Oct 2025 23:11:47 -0600 Subject: [PATCH 08/34] Refactor/clean up test framewokr --- .../shantys-tests/KickOffTests.cs | 20 ++++++++++++++-- .../shantys-tests/NITestRunner.cs | 14 ++--------- .../shantys-tests/TestEnvironmentManager.cs | 24 ++++++++++++------- ...ojectBuilder.cs => TestSolutionBuilder.cs} | 17 +++++++++---- 4 files changed, 49 insertions(+), 26 deletions(-) rename detect-nuget-inspector/detect-nuget-inspector-tests/shantys-tests/{TestProjectBuilder.cs => TestSolutionBuilder.cs} (87%) diff --git a/detect-nuget-inspector/detect-nuget-inspector-tests/shantys-tests/KickOffTests.cs b/detect-nuget-inspector/detect-nuget-inspector-tests/shantys-tests/KickOffTests.cs index 20a3a4e..9107b35 100644 --- a/detect-nuget-inspector/detect-nuget-inspector-tests/shantys-tests/KickOffTests.cs +++ b/detect-nuget-inspector/detect-nuget-inspector-tests/shantys-tests/KickOffTests.cs @@ -19,7 +19,7 @@ public void TestBasicSetup_InvalidDotNetVersion() } - // dotnet 6 tests (nuget v6.3.4.2) + // dotnet 6 (nuget v6.3.4.2) [TestMethod] public void TestBasicSetup_DotNet6() { @@ -29,7 +29,7 @@ public void TestBasicSetup_DotNet6() Assert.IsTrue(result.Success, result.Message); } - // dotnet 7 tests (nuget v6.7.1.1) + // dotnet 7 (nuget v6.7.1.1) [TestMethod] public void TestBasicSetup_DotNet7() { @@ -50,5 +50,21 @@ public void TestBasicSetup_DotNet8() runner.RunBasicSetupTest("8.0.0", "MyTestSolution", "dotnet8"); }); } + + [TestMethod] + public void TestBasicSetup_DotNet6_NoCPM() + { + // 1. Set up environment with .NET 6 + var dotnetVersion = "6.0.428"; // todo change me to match what is on jenkins + var env = new TestEnvironmentManager().SetupEnvironment(dotnetVersion, "dotnet6"); + + // 2. Build a .NET 6 project without CPM + var builder = new TestSolutionBuilder(env).CreateSimpleSolution("MySimpleDotnet6Solution").Build(); + + + // 3. Run inspector and assert output + + // Make assertions on the result json + } } } \ No newline at end of file diff --git a/detect-nuget-inspector/detect-nuget-inspector-tests/shantys-tests/NITestRunner.cs b/detect-nuget-inspector/detect-nuget-inspector-tests/shantys-tests/NITestRunner.cs index ac6c12a..953e2be 100644 --- a/detect-nuget-inspector/detect-nuget-inspector-tests/shantys-tests/NITestRunner.cs +++ b/detect-nuget-inspector/detect-nuget-inspector-tests/shantys-tests/NITestRunner.cs @@ -13,20 +13,10 @@ public NIResult RunBasicSetupTest(string dotnetVersion, string solutionName, str Console.WriteLine($"Starting basic setup test with .NET version: {dotnetVersion} using command: {dotnetCommand}"); // 1. Setup environment - var env = new TestEnvironmentManager(); - try - { - env.SetupEnvironment(dotnetVersion, dotnetCommand); - Console.WriteLine($"✓ Environment setup successful - Working directory: {env.WorkingDirectory}"); - } - catch (Exception ex) - { - Console.WriteLine($"✗ Environment setup failed: {ex.Message}"); - throw; - } + var env = new TestEnvironmentManager().SetupEnvironment(dotnetVersion, dotnetCommand); // 2. Create simple solution - var projectBuilder = new TestProjectBuilder(env); + var projectBuilder = new TestSolutionBuilder(env); string solutionPath; try { diff --git a/detect-nuget-inspector/detect-nuget-inspector-tests/shantys-tests/TestEnvironmentManager.cs b/detect-nuget-inspector/detect-nuget-inspector-tests/shantys-tests/TestEnvironmentManager.cs index 4c8d017..a8851e8 100644 --- a/detect-nuget-inspector/detect-nuget-inspector-tests/shantys-tests/TestEnvironmentManager.cs +++ b/detect-nuget-inspector/detect-nuget-inspector-tests/shantys-tests/TestEnvironmentManager.cs @@ -13,16 +13,24 @@ public class TestEnvironmentManager public TestEnvironmentManager SetupEnvironment(string dotnetVersion, string desiredDotnetCommand = "dotnet") { - DotNetVersion = dotnetVersion; - DotNetCommand = desiredDotnetCommand; - WorkingDirectory = Path.Combine(Path.GetTempPath(), "NI-Tests", Guid.NewGuid().ToString()); - - Directory.CreateDirectory(WorkingDirectory); + try + { + DotNetVersion = dotnetVersion; + DotNetCommand = desiredDotnetCommand; + WorkingDirectory = Path.Combine(Path.GetTempPath(), "NI-Tests", Guid.NewGuid().ToString()); - // Validate and log .NET and NuGet versions - ValidateAndLogVersions(dotnetVersion, DotNetCommand); + Directory.CreateDirectory(WorkingDirectory); - return this; + // Validate and log .NET and NuGet versions + ValidateAndLogVersions(dotnetVersion, DotNetCommand); + + Console.WriteLine($"✓ Environment setup successful - Working directory: {this.WorkingDirectory}"); + return this; + } catch (Exception ex) + { + Console.WriteLine($"✗ Environment setup failed: {ex.Message}"); + throw; + } } private void ValidateAndLogVersions(string expectedVersion, string command) diff --git a/detect-nuget-inspector/detect-nuget-inspector-tests/shantys-tests/TestProjectBuilder.cs b/detect-nuget-inspector/detect-nuget-inspector-tests/shantys-tests/TestSolutionBuilder.cs similarity index 87% rename from detect-nuget-inspector/detect-nuget-inspector-tests/shantys-tests/TestProjectBuilder.cs rename to detect-nuget-inspector/detect-nuget-inspector-tests/shantys-tests/TestSolutionBuilder.cs index ccf8fc5..83f540f 100644 --- a/detect-nuget-inspector/detect-nuget-inspector-tests/shantys-tests/TestProjectBuilder.cs +++ b/detect-nuget-inspector/detect-nuget-inspector-tests/shantys-tests/TestSolutionBuilder.cs @@ -4,20 +4,22 @@ namespace DetectNugetInspectorTests.ShantysTests { - public class TestProjectBuilder + public class TestSolutionBuilder { private readonly TestEnvironmentManager _environment; private string _solutionDirectory; private string _solutionName; - public TestProjectBuilder(TestEnvironmentManager environment) + public TestSolutionBuilder(TestEnvironmentManager environment) { _environment = environment; } - public TestProjectBuilder CreateSimpleSolution(string solutionName = "TestSolution") + public TestSolutionBuilder CreateSimpleSolution(string solutionName) { - _solutionName = solutionName; + try + { + _solutionName = solutionName; _solutionDirectory = Path.Combine(_environment.WorkingDirectory, solutionName); Directory.CreateDirectory(_solutionDirectory); @@ -91,6 +93,13 @@ public TestProjectBuilder CreateSimpleSolution(string solutionName = "TestSoluti } return this; + } catch (Exception ex) + { + Console.WriteLine($"✗ Solution creation failed: {ex.Message}"); + _environment.Cleanup(); + throw; + } + } public string Build() From e7b0970b79a7d0e5d1c5109fa5da74618005f40b Mon Sep 17 00:00:00 2001 From: shantyk Date: Tue, 7 Oct 2025 21:11:15 -0600 Subject: [PATCH 09/34] Refactor to make test solution builder more readable --- .../shantys-tests/KickOffTests.cs | 17 ++- .../shantys-tests/NITestRunner.cs | 4 +- .../shantys-tests/TestSolutionBuilder.cs | 105 +++++++----------- 3 files changed, 56 insertions(+), 70 deletions(-) diff --git a/detect-nuget-inspector/detect-nuget-inspector-tests/shantys-tests/KickOffTests.cs b/detect-nuget-inspector/detect-nuget-inspector-tests/shantys-tests/KickOffTests.cs index 9107b35..c5ebf3c 100644 --- a/detect-nuget-inspector/detect-nuget-inspector-tests/shantys-tests/KickOffTests.cs +++ b/detect-nuget-inspector/detect-nuget-inspector-tests/shantys-tests/KickOffTests.cs @@ -52,19 +52,24 @@ public void TestBasicSetup_DotNet8() } [TestMethod] - public void TestBasicSetup_DotNet6_NoCPM() + public void TestBasicSolution_DotNet6_NoCPM() { - // 1. Set up environment with .NET 6 + // 1. Set up environment with .NET 6 (nuget v6.3.4.2) var dotnetVersion = "6.0.428"; // todo change me to match what is on jenkins var env = new TestEnvironmentManager().SetupEnvironment(dotnetVersion, "dotnet6"); - // 2. Build a .NET 6 project without CPM - var builder = new TestSolutionBuilder(env).CreateSimpleSolution("MySimpleDotnet6Solution").Build(); - - + // 2. Create .NET 6 solution + var builder = new TestSolutionBuilder(env) + .CreateSolution("MySimpleDotnet6Solution") + .CreateAndAddProject("ProjectA") + .AddDependencyToProject("ProjectA", "Newtonsoft.Json", "13.0.3") + .Build(); + // 3. Run inspector and assert output // Make assertions on the result json + + // Clean up everything. start at state 0. } } } \ No newline at end of file diff --git a/detect-nuget-inspector/detect-nuget-inspector-tests/shantys-tests/NITestRunner.cs b/detect-nuget-inspector/detect-nuget-inspector-tests/shantys-tests/NITestRunner.cs index 953e2be..500e1e6 100644 --- a/detect-nuget-inspector/detect-nuget-inspector-tests/shantys-tests/NITestRunner.cs +++ b/detect-nuget-inspector/detect-nuget-inspector-tests/shantys-tests/NITestRunner.cs @@ -10,7 +10,7 @@ public class NITestRunner public NIResult RunBasicSetupTest(string dotnetVersion, string solutionName, string dotnetCommand) { - Console.WriteLine($"Starting basic setup test with .NET version: {dotnetVersion} using command: {dotnetCommand}"); + Console.WriteLine($"Starting basic test with .NET version: {dotnetVersion} using command: {dotnetCommand}"); // 1. Setup environment var env = new TestEnvironmentManager().SetupEnvironment(dotnetVersion, dotnetCommand); @@ -21,7 +21,7 @@ public NIResult RunBasicSetupTest(string dotnetVersion, string solutionName, str try { solutionPath = projectBuilder - .CreateSimpleSolution(solutionName) + .CreateSolution(solutionName) .Build(); Console.WriteLine($"✓ Solution created successfully at: {solutionPath}"); } diff --git a/detect-nuget-inspector/detect-nuget-inspector-tests/shantys-tests/TestSolutionBuilder.cs b/detect-nuget-inspector/detect-nuget-inspector-tests/shantys-tests/TestSolutionBuilder.cs index 83f540f..4ee8d88 100644 --- a/detect-nuget-inspector/detect-nuget-inspector-tests/shantys-tests/TestSolutionBuilder.cs +++ b/detect-nuget-inspector/detect-nuget-inspector-tests/shantys-tests/TestSolutionBuilder.cs @@ -15,68 +15,58 @@ public TestSolutionBuilder(TestEnvironmentManager environment) _environment = environment; } - public TestSolutionBuilder CreateSimpleSolution(string solutionName) + public TestSolutionBuilder CreateSolution(string solutionName) { try { - _solutionName = solutionName; - _solutionDirectory = Path.Combine(_environment.WorkingDirectory, solutionName); - Directory.CreateDirectory(_solutionDirectory); + _solutionName = solutionName; + _solutionDirectory = Path.Combine(_environment.WorkingDirectory, solutionName); + Directory.CreateDirectory(_solutionDirectory); - // Create solution - var createSolutionProcess = new Process - { - StartInfo = new ProcessStartInfo - { - FileName = _environment.DotNetCommand, // Use the environment's command - Arguments = $"new sln -n {solutionName}", - WorkingDirectory = _solutionDirectory, - UseShellExecute = false, - RedirectStandardOutput = true, - RedirectStandardError = true, - CreateNoWindow = true - } - }; + // Create solution + RunDotNetCommand($"new sln -n {solutionName}", _solutionDirectory); - createSolutionProcess.Start(); - createSolutionProcess.WaitForExit(); - - if (createSolutionProcess.ExitCode != 0) + return this; + } catch (Exception ex) { - throw new InvalidOperationException($"Failed to create solution: {createSolutionProcess.StandardError.ReadToEnd()}"); + Console.WriteLine($"✗ Test Solution creation failed: {ex.Message}"); + _environment.Cleanup(); + throw; } - // Create Project1 - var createProjectProcess = new Process - { - StartInfo = new ProcessStartInfo - { - FileName = _environment.DotNetCommand, // Use the environment's command - Arguments = "new console -n Project1", - WorkingDirectory = _solutionDirectory, - UseShellExecute = false, - RedirectStandardOutput = true, - RedirectStandardError = true, - CreateNoWindow = true - } - }; - - createProjectProcess.Start(); - createProjectProcess.WaitForExit(); + } - if (createProjectProcess.ExitCode != 0) - { - throw new InvalidOperationException($"Failed to create Project1: {createProjectProcess.StandardError.ReadToEnd()}"); - } + public TestSolutionBuilder CreateAndAddProject(string projectName) + { + // Create ProjectA + RunDotNetCommand($"new console -n {projectName}", _solutionDirectory); - // Add Project1 to solution - var addProjectProcess = new Process + // Add ProjectA to solution + RunDotNetCommand("sln add ProjectA/ProjectA.csproj", _solutionDirectory); + return this; + } + + public TestSolutionBuilder AddDependencyToProject(string projectName, string packageName, string version) + { + var projectDir = Path.Combine(_solutionDirectory, projectName); + var args = $"add package {packageName} --version {version}"; + RunDotNetCommand(args, projectDir); + return this; + } + + + private void RunDotNetCommand(string arguments, string workingDirectory) + { + var command = $"{_environment.DotNetCommand} {arguments}"; + Console.WriteLine($"> {command}"); + + var process = new Process { StartInfo = new ProcessStartInfo { - FileName = _environment.DotNetCommand, // Use the environment's command - Arguments = "sln add Project1/Project1.csproj", - WorkingDirectory = _solutionDirectory, + FileName = _environment.DotNetCommand, + Arguments = arguments, + WorkingDirectory = workingDirectory, UseShellExecute = false, RedirectStandardOutput = true, RedirectStandardError = true, @@ -84,22 +74,13 @@ public TestSolutionBuilder CreateSimpleSolution(string solutionName) } }; - addProjectProcess.Start(); - addProjectProcess.WaitForExit(); - - if (addProjectProcess.ExitCode != 0) - { - throw new InvalidOperationException($"Failed to add Project1 to solution: {addProjectProcess.StandardError.ReadToEnd()}"); - } + process.Start(); + process.WaitForExit(); - return this; - } catch (Exception ex) + if (process.ExitCode != 0) { - Console.WriteLine($"✗ Solution creation failed: {ex.Message}"); - _environment.Cleanup(); - throw; + throw new InvalidOperationException($"dotnet {arguments} failed: {process.StandardError.ReadToEnd()}"); } - } public string Build() From ec4766e91406e504b83197c84e2e4fac50ba2d87 Mon Sep 17 00:00:00 2001 From: shantyk Date: Tue, 7 Oct 2025 22:35:28 -0600 Subject: [PATCH 10/34] dotnet6 project.assets.json case --- .../shantys-tests/KickOffTests.cs | 62 +++++++++++++++++-- .../shantys-tests/TestEnvironmentManager.cs | 2 +- .../shantys-tests/TestSolutionBuilder.cs | 34 +++++++--- .../Inspection/InspectionResult.cs | 2 +- .../Inspection/InspectorExecutionResult.cs | 8 ++- .../Inspection/InspectorExecutor.cs | 5 +- 6 files changed, 92 insertions(+), 21 deletions(-) diff --git a/detect-nuget-inspector/detect-nuget-inspector-tests/shantys-tests/KickOffTests.cs b/detect-nuget-inspector/detect-nuget-inspector-tests/shantys-tests/KickOffTests.cs index c5ebf3c..37d3117 100644 --- a/detect-nuget-inspector/detect-nuget-inspector-tests/shantys-tests/KickOffTests.cs +++ b/detect-nuget-inspector/detect-nuget-inspector-tests/shantys-tests/KickOffTests.cs @@ -1,5 +1,7 @@ using System; +using Blackduck.Detect.Nuget.Inspector.Inspection; using Microsoft.VisualStudio.TestTools.UnitTesting; +using NuGet.ProjectModel; namespace DetectNugetInspectorTests.ShantysTests { @@ -52,7 +54,7 @@ public void TestBasicSetup_DotNet8() } [TestMethod] - public void TestBasicSolution_DotNet6_NoCPM() + public void TestBasicSolution_DotNet6_ProjectAssetsJsonFile() { // 1. Set up environment with .NET 6 (nuget v6.3.4.2) var dotnetVersion = "6.0.428"; // todo change me to match what is on jenkins @@ -65,11 +67,61 @@ public void TestBasicSolution_DotNet6_NoCPM() .AddDependencyToProject("ProjectA", "Newtonsoft.Json", "13.0.3") .Build(); - // 3. Run inspector and assert output - - // Make assertions on the result json + // 3. Run inspector + // Redirect console output for assertions later + var stringWriter = new StringWriter(); + var originalOut = Console.Out; + Console.SetOut(stringWriter); - // Clean up everything. start at state 0. + var options = new InspectionOptions() + { + TargetPath = builder, + Verbose = true, + PackagesRepoUrl = "https://api.nuget.org/v3/index.json", + OutputDirectory = env.WorkingDirectory, + IgnoreFailure = false + }; + + try + { + var inspection = InspectorExecutor.ExecuteInspectors(options); + + // 4. Assert inspection results + Assert.IsTrue(inspection.Success); + var inspectionResults = inspection.Results; + Assert.IsNotNull(inspectionResults); + Assert.AreEqual(1, inspectionResults.Count); + var result = inspectionResults[0]; + Assert.AreEqual(InspectionResult.ResultStatus.Success, result.Status); + Assert.IsNotNull(result.Containers); + Assert.AreEqual(1, result.Containers.Count); + var solutionContainer = result.Containers[0]; + Assert.AreEqual(solutionContainer.Type, "Solution"); + Assert.AreEqual("MySimpleDotnet6Solution", solutionContainer.Name); + + var projectContainer = solutionContainer.Children[0]; + Assert.AreEqual(projectContainer.Type, "Project"); + Assert.AreEqual("ProjectA", projectContainer.Name); + + Assert.IsNotNull(projectContainer.Dependencies); + Assert.AreEqual(1, projectContainer.Dependencies.Count); + var dependencies = projectContainer.Dependencies; + Assert.AreEqual(1, dependencies.Count); + var dependency = dependencies.Single(); + Assert.AreEqual("Newtonsoft.Json", dependency.Name); + Assert.AreEqual("13.0.3", dependency.Version); + + // Assert console output + string output = stringWriter.ToString(); + Assert.IsTrue(output.Contains("Using assets json file:")); + originalOut.Write(stringWriter.ToString()); + } + finally + { + // Undo redirect, go back to writing to standard out + Console.SetOut(originalOut); + env.Cleanup(); + } } } } \ No newline at end of file diff --git a/detect-nuget-inspector/detect-nuget-inspector-tests/shantys-tests/TestEnvironmentManager.cs b/detect-nuget-inspector/detect-nuget-inspector-tests/shantys-tests/TestEnvironmentManager.cs index a8851e8..9ab7e6c 100644 --- a/detect-nuget-inspector/detect-nuget-inspector-tests/shantys-tests/TestEnvironmentManager.cs +++ b/detect-nuget-inspector/detect-nuget-inspector-tests/shantys-tests/TestEnvironmentManager.cs @@ -71,7 +71,7 @@ private void ValidateAndLogVersions(string expectedVersion, string command) Console.WriteLine("✅ Environment validation complete"); } - private (int ExitCode, string Output, string Error) RunCommand(string command, string arguments) + private (int ExitCode, string Output, string Error) RunCommand(string command, string arguments) // TODO only need one dotnet command runner { try { diff --git a/detect-nuget-inspector/detect-nuget-inspector-tests/shantys-tests/TestSolutionBuilder.cs b/detect-nuget-inspector/detect-nuget-inspector-tests/shantys-tests/TestSolutionBuilder.cs index 4ee8d88..0daff37 100644 --- a/detect-nuget-inspector/detect-nuget-inspector-tests/shantys-tests/TestSolutionBuilder.cs +++ b/detect-nuget-inspector/detect-nuget-inspector-tests/shantys-tests/TestSolutionBuilder.cs @@ -29,7 +29,7 @@ public TestSolutionBuilder CreateSolution(string solutionName) return this; } catch (Exception ex) { - Console.WriteLine($"✗ Test Solution creation failed: {ex.Message}"); + Console.WriteLine($"✗ Test solution creation failed: {ex.Message}"); _environment.Cleanup(); throw; } @@ -38,20 +38,34 @@ public TestSolutionBuilder CreateSolution(string solutionName) public TestSolutionBuilder CreateAndAddProject(string projectName) { - // Create ProjectA - RunDotNetCommand($"new console -n {projectName}", _solutionDirectory); + try { + // Create ProjectA + RunDotNetCommand($"new console -n {projectName}", _solutionDirectory); - // Add ProjectA to solution - RunDotNetCommand("sln add ProjectA/ProjectA.csproj", _solutionDirectory); - return this; + // Add ProjectA to solution + RunDotNetCommand("sln add ProjectA/ProjectA.csproj", _solutionDirectory); + return this; + } catch (Exception ex) + { + Console.WriteLine($"✗ Test subproject creation failed: {ex.Message}"); + _environment.Cleanup(); + throw; + } } public TestSolutionBuilder AddDependencyToProject(string projectName, string packageName, string version) { - var projectDir = Path.Combine(_solutionDirectory, projectName); - var args = $"add package {packageName} --version {version}"; - RunDotNetCommand(args, projectDir); - return this; + try { + var projectDir = Path.Combine(_solutionDirectory, projectName); + var args = $"add package {packageName} --version {version}"; + RunDotNetCommand(args, projectDir); + return this; + } catch (Exception ex) + { + Console.WriteLine($"✗ Adding dependency to subproject failed: {ex.Message}"); + _environment.Cleanup(); + throw; + } } diff --git a/detect-nuget-inspector/detect-nuget-inspector/Inspection/InspectionResult.cs b/detect-nuget-inspector/detect-nuget-inspector/Inspection/InspectionResult.cs index 2278e83..d5f79dd 100644 --- a/detect-nuget-inspector/detect-nuget-inspector/Inspection/InspectionResult.cs +++ b/detect-nuget-inspector/detect-nuget-inspector/Inspection/InspectionResult.cs @@ -7,7 +7,7 @@ namespace Blackduck.Detect.Nuget.Inspector.Inspection { - class InspectionResult + public class InspectionResult { public enum ResultStatus { diff --git a/detect-nuget-inspector/detect-nuget-inspector/Inspection/InspectorExecutionResult.cs b/detect-nuget-inspector/detect-nuget-inspector/Inspection/InspectorExecutionResult.cs index 370d320..fe03bbc 100644 --- a/detect-nuget-inspector/detect-nuget-inspector/Inspection/InspectorExecutionResult.cs +++ b/detect-nuget-inspector/detect-nuget-inspector/Inspection/InspectorExecutionResult.cs @@ -3,6 +3,7 @@ using System.Linq; using System.Text; using System.Threading.Tasks; +using Blackduck.Detect.Nuget.Inspector.Inspection; namespace Blackduck.Detect.Nuget.Inspector.Result { @@ -10,6 +11,7 @@ public class InspectorExecutionResult { public bool Success; public int ExitCode = 0; + public List? Results { get; set; } public static InspectorExecutionResult Failed(int exitCode = -1) { @@ -20,12 +22,14 @@ public static InspectorExecutionResult Failed(int exitCode = -1) }; } - public static InspectorExecutionResult Succeeded() + public static InspectorExecutionResult Succeeded(List? results) { - return new InspectorExecutionResult + var something = new InspectorExecutionResult { Success = true }; + something.Results = results; + return something; } } } diff --git a/detect-nuget-inspector/detect-nuget-inspector/Inspection/InspectorExecutor.cs b/detect-nuget-inspector/detect-nuget-inspector/Inspection/InspectorExecutor.cs index c203223..7c39a7a 100644 --- a/detect-nuget-inspector/detect-nuget-inspector/Inspection/InspectorExecutor.cs +++ b/detect-nuget-inspector/detect-nuget-inspector/Inspection/InspectorExecutor.cs @@ -14,12 +14,13 @@ public class InspectorExecutor public static InspectorExecutionResult ExecuteInspectors(InspectionOptions options) { bool anyFailed = false; + List? inspectionResults = null; try { var dispatch = new InspectorDispatch(); var searchService = new NugetSearchService(options.PackagesRepoUrl, options.NugetConfigPath); - var inspectionResults = dispatch.Inspect(options, searchService); + inspectionResults = dispatch.Inspect(options, searchService); if (inspectionResults != null) { foreach (var result in inspectionResults) @@ -72,7 +73,7 @@ public static InspectorExecutionResult ExecuteInspectors(InspectionOptions optio } else { - return InspectorExecutionResult.Succeeded(); + return InspectorExecutionResult.Succeeded(inspectionResults); } } } From 4c4b3dc95af451632f8c44261b56c0a470df4144 Mon Sep 17 00:00:00 2001 From: shantyk Date: Tue, 7 Oct 2025 23:40:26 -0600 Subject: [PATCH 11/34] Add projectReferenceResolver and ProjectXMLResolver for duplicate pkg reference tests --- .../shantys-tests/KickOffTests.cs | 184 ++++++++++++++++-- .../shantys-tests/TestSolutionBuilder.cs | 44 ++++- 2 files changed, 210 insertions(+), 18 deletions(-) diff --git a/detect-nuget-inspector/detect-nuget-inspector-tests/shantys-tests/KickOffTests.cs b/detect-nuget-inspector/detect-nuget-inspector-tests/shantys-tests/KickOffTests.cs index 37d3117..dca9803 100644 --- a/detect-nuget-inspector/detect-nuget-inspector-tests/shantys-tests/KickOffTests.cs +++ b/detect-nuget-inspector/detect-nuget-inspector-tests/shantys-tests/KickOffTests.cs @@ -1,14 +1,11 @@ -using System; using Blackduck.Detect.Nuget.Inspector.Inspection; -using Microsoft.VisualStudio.TestTools.UnitTesting; -using NuGet.ProjectModel; +using Microsoft.Build.Locator; namespace DetectNugetInspectorTests.ShantysTests { [TestClass] public class KickOffTests { - [TestMethod] public void TestBasicSetup_InvalidDotNetVersion() { @@ -20,7 +17,7 @@ public void TestBasicSetup_InvalidDotNetVersion() }); } - + // dotnet 6 (nuget v6.3.4.2) [TestMethod] public void TestBasicSetup_DotNet6() @@ -40,13 +37,13 @@ public void TestBasicSetup_DotNet7() Assert.IsTrue(result.Success, result.Message); } - + // dotnet 8 tests (nuget v...) [TestMethod] public void TestBasicSetup_DotNet8() { var runner = new NITestRunner(); - + Assert.ThrowsException(() => { runner.RunBasicSetupTest("8.0.0", "MyTestSolution", "dotnet8"); @@ -66,13 +63,13 @@ public void TestBasicSolution_DotNet6_ProjectAssetsJsonFile() .CreateAndAddProject("ProjectA") .AddDependencyToProject("ProjectA", "Newtonsoft.Json", "13.0.3") .Build(); - + // 3. Run inspector // Redirect console output for assertions later var stringWriter = new StringWriter(); var originalOut = Console.Out; Console.SetOut(stringWriter); - + var options = new InspectionOptions() { TargetPath = builder, @@ -91,26 +88,25 @@ public void TestBasicSolution_DotNet6_ProjectAssetsJsonFile() var inspectionResults = inspection.Results; Assert.IsNotNull(inspectionResults); Assert.AreEqual(1, inspectionResults.Count); - var result = inspectionResults[0]; + var result = inspectionResults[0]; Assert.AreEqual(InspectionResult.ResultStatus.Success, result.Status); Assert.IsNotNull(result.Containers); Assert.AreEqual(1, result.Containers.Count); var solutionContainer = result.Containers[0]; Assert.AreEqual(solutionContainer.Type, "Solution"); Assert.AreEqual("MySimpleDotnet6Solution", solutionContainer.Name); - + var projectContainer = solutionContainer.Children[0]; Assert.AreEqual(projectContainer.Type, "Project"); Assert.AreEqual("ProjectA", projectContainer.Name); - + Assert.IsNotNull(projectContainer.Dependencies); - Assert.AreEqual(1, projectContainer.Dependencies.Count); var dependencies = projectContainer.Dependencies; Assert.AreEqual(1, dependencies.Count); var dependency = dependencies.Single(); Assert.AreEqual("Newtonsoft.Json", dependency.Name); Assert.AreEqual("13.0.3", dependency.Version); - + // Assert console output string output = stringWriter.ToString(); Assert.IsTrue(output.Contains("Using assets json file:")); @@ -123,5 +119,165 @@ public void TestBasicSolution_DotNet6_ProjectAssetsJsonFile() env.Cleanup(); } } + + [TestMethod] + public void TestBasicSolution_DotNet6_DuplicatePackageReference_ProjectReferenceResolver() + { + // 1. Set up environment with .NET 6 (nuget v6.3.4.2) + var dotnetVersion = "6.0.201"; // todo change me to match what is on jenkins + var env = new TestEnvironmentManager().SetupEnvironment(dotnetVersion, "dotnet6"); + + // 2. Create .NET 6 solution + var builder = new TestSolutionBuilder(env) + .CreateSolution("MySimpleDotnet6Solution") + .CreateAndAddProject("ProjectA") + .AddDependencyToProject("ProjectA", "Newtonsoft.Json", "13.0.3") + .AddPackageReferenceToCsprojManually("ProjectA", "Newtonsoft.Json", "12.0.1") + .NoBuildArtifacts() // So we can force using ProjectReferenceResolver instead of assets file + .Build(); + + + // 3. Run inspector + // Redirect console output for assertions later + var stringWriter = new StringWriter(); + var originalOut = Console.Out; + Console.SetOut(stringWriter); + + var options = new InspectionOptions() + { + TargetPath = builder, + Verbose = true, + PackagesRepoUrl = "https://api.nuget.org/v3/index.json", + OutputDirectory = env.WorkingDirectory, + IgnoreFailure = false + }; + + try + { + // Register MSBuild so ProjectReferenceResolver succeeds and does not cascade to XML resolver + var instance = MSBuildLocator.RegisterDefaults(); + Console.WriteLine($"MSBuild registered: {instance.Name} {instance.Version} at {instance.MSBuildPath}"); + + var inspection = InspectorExecutor.ExecuteInspectors(options); + + // 4. Assert inspection results + Assert.IsTrue(inspection.Success); + var inspectionResults = inspection.Results; + Assert.IsNotNull(inspectionResults); + Assert.AreEqual(1, inspectionResults.Count); + var result = inspectionResults[0]; + Assert.AreEqual(InspectionResult.ResultStatus.Success, result.Status); + Assert.IsNotNull(result.Containers); + Assert.AreEqual(1, result.Containers.Count); + var solutionContainer = result.Containers[0]; + Assert.AreEqual(solutionContainer.Type, "Solution"); + Assert.AreEqual("MySimpleDotnet6Solution", solutionContainer.Name); + + var projectContainer = solutionContainer.Children[0]; + Assert.AreEqual(projectContainer.Type, "Project"); + Assert.AreEqual("ProjectA", projectContainer.Name); + + Assert.IsNotNull(projectContainer.Dependencies); + var dependencies = projectContainer.Dependencies; + Assert.AreEqual(2, dependencies.Count); + // Confirm duplicates are captured + Assert.IsTrue(dependencies.Any(d => d.Name == "Newtonsoft.Json" && d.Version == "13.0.3")); + Assert.IsTrue(dependencies.Any(d => d.Name == "Newtonsoft.Json" && d.Version == "12.0.1")); + + // Assert console output + string output = stringWriter.ToString(); + Assert.IsTrue(output.Contains("Reference resolver succeeded.")); + originalOut.Write(stringWriter.ToString()); + } + finally + { + // Undo redirect, go back to writing to standard out + Console.SetOut(originalOut); + env.Cleanup(); + } + } + + [TestMethod] + public void TestBasicSolution_DotNet6_DuplicatePackageReference_XMLResolver() + { + // 1. Set up environment with .NET 6 (nuget v6.3.4.2) + var dotnetVersion = "6.0.201"; // todo change me to match what is on jenkins + var env = new TestEnvironmentManager().SetupEnvironment(dotnetVersion, "dotnet6"); + + // 2. Create .NET 6 solution + var builder = new TestSolutionBuilder(env) + .CreateSolution("MySimpleDotnet6Solution") + .CreateAndAddProject("ProjectA") + .AddDependencyToProject("ProjectA", "Newtonsoft.Json", "13.0.3") + .AddPackageReferenceToCsprojManually("ProjectA", "Newtonsoft.Json", "12.0.1") + .NoBuildArtifacts() // So we can bypass assets file during cascading + .Build(); + + + // 3. Run inspector + // Redirect console output for assertions later + var stringWriter = new StringWriter(); + var originalOut = Console.Out; + Console.SetOut(stringWriter); + + var options = new InspectionOptions() + { + TargetPath = builder, + Verbose = true, + PackagesRepoUrl = "https://api.nuget.org/v3/index.json", + OutputDirectory = env.WorkingDirectory, + IgnoreFailure = false + }; + + try + { + // Since we do not register MSBuild, we will cascade to ProjectXMLResolver + var inspection = InspectorExecutor.ExecuteInspectors(options); + + // 4. Assert inspection results + Assert.IsTrue(inspection.Success); + var inspectionResults = inspection.Results; + Assert.IsNotNull(inspectionResults); + Assert.AreEqual(1, inspectionResults.Count); + var result = inspectionResults[0]; + Assert.AreEqual(InspectionResult.ResultStatus.Success, result.Status); + Assert.IsNotNull(result.Containers); + Assert.AreEqual(1, result.Containers.Count); + var solutionContainer = result.Containers[0]; + Assert.AreEqual(solutionContainer.Type, "Solution"); + Assert.AreEqual("MySimpleDotnet6Solution", solutionContainer.Name); + + var projectContainer = solutionContainer.Children[0]; + Assert.AreEqual(projectContainer.Type, "Project"); + Assert.AreEqual("ProjectA", projectContainer.Name); + + Assert.IsNotNull(projectContainer.Dependencies); + var dependencies = projectContainer.Dependencies; + Assert.AreEqual(2, dependencies.Count); + // Confirm duplicates are captured + Assert.IsTrue(dependencies.Any(d => d.Name == "Newtonsoft.Json" && d.Version == "13.0.3")); + Assert.IsTrue(dependencies.Any(d => d.Name == "Newtonsoft.Json" && d.Version == "12.0.1")); + + // Assert console output + string output = stringWriter.ToString(); + Assert.IsTrue(output.Contains("Using backup XML resolver.")); + originalOut.Write(stringWriter.ToString()); + } + finally + { + // Undo redirect, go back to writing to standard out + Console.SetOut(originalOut); + env.Cleanup(); + } + } + + // for dotnet6, we could add .csproj branch, raw xml parser branch ... etc. + // So what tests is REQUIRED so you can close your tickets: + // 1. for validating nuget up to 6.3.4: + // duplicate PackageReference in .csproj file. Confirm both are captured. + // Duplicate PackageVersion in Directory.Packages.props. Confirm both are captured. + + // 2. for validating nuget up to 6.7.1: + // Central Package Management. Create solution with that very complicated set up. Confirm all captured. } } \ No newline at end of file diff --git a/detect-nuget-inspector/detect-nuget-inspector-tests/shantys-tests/TestSolutionBuilder.cs b/detect-nuget-inspector/detect-nuget-inspector-tests/shantys-tests/TestSolutionBuilder.cs index 0daff37..2fc75e6 100644 --- a/detect-nuget-inspector/detect-nuget-inspector-tests/shantys-tests/TestSolutionBuilder.cs +++ b/detect-nuget-inspector/detect-nuget-inspector-tests/shantys-tests/TestSolutionBuilder.cs @@ -39,8 +39,8 @@ public TestSolutionBuilder CreateSolution(string solutionName) public TestSolutionBuilder CreateAndAddProject(string projectName) { try { - // Create ProjectA - RunDotNetCommand($"new console -n {projectName}", _solutionDirectory); + // Create a minimal project with a class + RunDotNetCommand($"new classlib -n {projectName}", _solutionDirectory); // Add ProjectA to solution RunDotNetCommand("sln add ProjectA/ProjectA.csproj", _solutionDirectory); @@ -67,8 +67,44 @@ public TestSolutionBuilder AddDependencyToProject(string projectName, string pac throw; } } - - + + public TestSolutionBuilder AddPackageReferenceToCsprojManually(string projectName, string packageName, string version) + { + // Adding the same package with a different version will cause the dotnet add package command to update the + // existing reference to the new version, not add a duplicate. So we need to manually update the project file. + var projectDir = Path.Combine(_solutionDirectory, projectName); + var csprojPath = Path.Combine(projectDir, $"{projectName}.csproj"); + var csprojContent = File.ReadAllText(csprojPath); + var packageReference = $" "; + csprojContent = csprojContent.Replace("", $"{packageReference}\n "); + File.WriteAllText(csprojPath, csprojContent); + + return this; + } + + public TestSolutionBuilder NoBuildArtifacts() + { + try + { + // Remove bin and obj directories + foreach (var dir in Directory.GetDirectories(_solutionDirectory, "*", SearchOption.AllDirectories)) + { + if (dir.EndsWith("bin") || dir.EndsWith("obj")) + { + Directory.Delete(dir, true); + } + } + + return this; + } catch (Exception ex) + { + Console.WriteLine($"✗ Removing build artifacts failed: {ex.Message}"); + _environment.Cleanup(); + throw; + } + } + + private void RunDotNetCommand(string arguments, string workingDirectory) { var command = $"{_environment.DotNetCommand} {arguments}"; From 6750173659eccdd345916499ed3c5b0a3a85a43d Mon Sep 17 00:00:00 2001 From: shantyk Date: Wed, 8 Oct 2025 00:07:35 -0600 Subject: [PATCH 12/34] Isolate tests that register MSBuild defaults --- .../shantys-tests/KickOffTests.cs | 97 +------------------ .../TestsWithMsBuildRegistration.cs | 86 ++++++++++++++++ 2 files changed, 91 insertions(+), 92 deletions(-) create mode 100644 detect-nuget-inspector/detect-nuget-inspector-tests/shantys-tests/TestsWithMsBuildRegistration.cs diff --git a/detect-nuget-inspector/detect-nuget-inspector-tests/shantys-tests/KickOffTests.cs b/detect-nuget-inspector/detect-nuget-inspector-tests/shantys-tests/KickOffTests.cs index dca9803..c8c2872 100644 --- a/detect-nuget-inspector/detect-nuget-inspector-tests/shantys-tests/KickOffTests.cs +++ b/detect-nuget-inspector/detect-nuget-inspector-tests/shantys-tests/KickOffTests.cs @@ -16,27 +16,17 @@ public void TestBasicSetup_InvalidDotNetVersion() runner.RunBasicSetupTest("99.0.999", "FailureSolution", "nonExistentDotnetVersion"); }); } + - - // dotnet 6 (nuget v6.3.4.2) - [TestMethod] - public void TestBasicSetup_DotNet6() - { - var runner = new NITestRunner(); - var result = runner.RunBasicSetupTest("6.0.201", "MyTestSolution", "dotnet6"); - - Assert.IsTrue(result.Success, result.Message); - } - - // dotnet 7 (nuget v6.7.1.1) - [TestMethod] + // dotnet 7.0.410 (nuget v6.7.1.1) + /*[TestMethod] public void TestBasicSetup_DotNet7() { var runner = new NITestRunner(); var result = runner.RunBasicSetupTest("7.0.410", "MyTestSolution", "dotnet7"); Assert.IsTrue(result.Success, result.Message); - } + }*/ // dotnet 8 tests (nuget v...) [TestMethod] @@ -119,89 +109,12 @@ public void TestBasicSolution_DotNet6_ProjectAssetsJsonFile() env.Cleanup(); } } - - [TestMethod] - public void TestBasicSolution_DotNet6_DuplicatePackageReference_ProjectReferenceResolver() - { - // 1. Set up environment with .NET 6 (nuget v6.3.4.2) - var dotnetVersion = "6.0.201"; // todo change me to match what is on jenkins - var env = new TestEnvironmentManager().SetupEnvironment(dotnetVersion, "dotnet6"); - - // 2. Create .NET 6 solution - var builder = new TestSolutionBuilder(env) - .CreateSolution("MySimpleDotnet6Solution") - .CreateAndAddProject("ProjectA") - .AddDependencyToProject("ProjectA", "Newtonsoft.Json", "13.0.3") - .AddPackageReferenceToCsprojManually("ProjectA", "Newtonsoft.Json", "12.0.1") - .NoBuildArtifacts() // So we can force using ProjectReferenceResolver instead of assets file - .Build(); - - - // 3. Run inspector - // Redirect console output for assertions later - var stringWriter = new StringWriter(); - var originalOut = Console.Out; - Console.SetOut(stringWriter); - - var options = new InspectionOptions() - { - TargetPath = builder, - Verbose = true, - PackagesRepoUrl = "https://api.nuget.org/v3/index.json", - OutputDirectory = env.WorkingDirectory, - IgnoreFailure = false - }; - - try - { - // Register MSBuild so ProjectReferenceResolver succeeds and does not cascade to XML resolver - var instance = MSBuildLocator.RegisterDefaults(); - Console.WriteLine($"MSBuild registered: {instance.Name} {instance.Version} at {instance.MSBuildPath}"); - - var inspection = InspectorExecutor.ExecuteInspectors(options); - - // 4. Assert inspection results - Assert.IsTrue(inspection.Success); - var inspectionResults = inspection.Results; - Assert.IsNotNull(inspectionResults); - Assert.AreEqual(1, inspectionResults.Count); - var result = inspectionResults[0]; - Assert.AreEqual(InspectionResult.ResultStatus.Success, result.Status); - Assert.IsNotNull(result.Containers); - Assert.AreEqual(1, result.Containers.Count); - var solutionContainer = result.Containers[0]; - Assert.AreEqual(solutionContainer.Type, "Solution"); - Assert.AreEqual("MySimpleDotnet6Solution", solutionContainer.Name); - - var projectContainer = solutionContainer.Children[0]; - Assert.AreEqual(projectContainer.Type, "Project"); - Assert.AreEqual("ProjectA", projectContainer.Name); - - Assert.IsNotNull(projectContainer.Dependencies); - var dependencies = projectContainer.Dependencies; - Assert.AreEqual(2, dependencies.Count); - // Confirm duplicates are captured - Assert.IsTrue(dependencies.Any(d => d.Name == "Newtonsoft.Json" && d.Version == "13.0.3")); - Assert.IsTrue(dependencies.Any(d => d.Name == "Newtonsoft.Json" && d.Version == "12.0.1")); - - // Assert console output - string output = stringWriter.ToString(); - Assert.IsTrue(output.Contains("Reference resolver succeeded.")); - originalOut.Write(stringWriter.ToString()); - } - finally - { - // Undo redirect, go back to writing to standard out - Console.SetOut(originalOut); - env.Cleanup(); - } - } [TestMethod] public void TestBasicSolution_DotNet6_DuplicatePackageReference_XMLResolver() { // 1. Set up environment with .NET 6 (nuget v6.3.4.2) - var dotnetVersion = "6.0.201"; // todo change me to match what is on jenkins + var dotnetVersion = "6.0.428"; var env = new TestEnvironmentManager().SetupEnvironment(dotnetVersion, "dotnet6"); // 2. Create .NET 6 solution diff --git a/detect-nuget-inspector/detect-nuget-inspector-tests/shantys-tests/TestsWithMsBuildRegistration.cs b/detect-nuget-inspector/detect-nuget-inspector-tests/shantys-tests/TestsWithMsBuildRegistration.cs new file mode 100644 index 0000000..6674eff --- /dev/null +++ b/detect-nuget-inspector/detect-nuget-inspector-tests/shantys-tests/TestsWithMsBuildRegistration.cs @@ -0,0 +1,86 @@ +using Blackduck.Detect.Nuget.Inspector.Inspection; +using Microsoft.Build.Locator; + +namespace DetectNugetInspectorTests.ShantysTests; + +// Tests cases for scenarios where MSBuild is registered via MSBuildLocator need to be in their own class to avoid +// conflicts with other tests (MSBuild registration is process-wide and can only be done once per process.) +public class TestsWithMsBuildRegistration +{ + [TestMethod] + public void TestBasicSolution_DotNet6_DuplicatePackageReference_ProjectReferenceResolver() + { + // 1. Set up environment with .NET 6 (nuget v6.3.4.2) + var dotnetVersion = "6.0.428"; + var env = new TestEnvironmentManager().SetupEnvironment(dotnetVersion, "dotnet6"); + + // 2. Create .NET 6 solution + var builder = new TestSolutionBuilder(env) + .CreateSolution("MySimpleDotnet6Solution") + .CreateAndAddProject("ProjectA") + .AddDependencyToProject("ProjectA", "Newtonsoft.Json", "13.0.3") + .AddPackageReferenceToCsprojManually("ProjectA", "Newtonsoft.Json", "12.0.1") + .NoBuildArtifacts() // So we can force using ProjectReferenceResolver instead of assets file + .Build(); + + + // 3. Run inspector + // Redirect console output for assertions later + var stringWriter = new StringWriter(); + var originalOut = Console.Out; + Console.SetOut(stringWriter); + + var options = new InspectionOptions() + { + TargetPath = builder, + Verbose = true, + PackagesRepoUrl = "https://api.nuget.org/v3/index.json", + OutputDirectory = env.WorkingDirectory, + IgnoreFailure = false + }; + + try + { + // Register MSBuild so ProjectReferenceResolver succeeds and does not cascade to XML resolver + var instance = MSBuildLocator.RegisterDefaults(); + Console.WriteLine($"MSBuild registered: {instance.Name} {instance.Version} at {instance.MSBuildPath}"); + + var inspection = InspectorExecutor.ExecuteInspectors(options); + + // 4. Assert inspection results + Assert.IsTrue(inspection.Success); + var inspectionResults = inspection.Results; + Assert.IsNotNull(inspectionResults); + Assert.AreEqual(1, inspectionResults.Count); + var result = inspectionResults[0]; + Assert.AreEqual(InspectionResult.ResultStatus.Success, result.Status); + Assert.IsNotNull(result.Containers); + Assert.AreEqual(1, result.Containers.Count); + var solutionContainer = result.Containers[0]; + Assert.AreEqual(solutionContainer.Type, "Solution"); + Assert.AreEqual("MySimpleDotnet6Solution", solutionContainer.Name); + + var projectContainer = solutionContainer.Children[0]; + Assert.AreEqual(projectContainer.Type, "Project"); + Assert.AreEqual("ProjectA", projectContainer.Name); + + Assert.IsNotNull(projectContainer.Dependencies); + var dependencies = projectContainer.Dependencies; + Assert.AreEqual(2, dependencies.Count); + // Confirm duplicates are captured + Assert.IsTrue(dependencies.Any(d => d.Name == "Newtonsoft.Json" && d.Version == "13.0.3")); + Assert.IsTrue(dependencies.Any(d => d.Name == "Newtonsoft.Json" && d.Version == "12.0.1")); + + // Assert console output + string output = stringWriter.ToString(); + Assert.IsTrue(output.Contains("Reference resolver succeeded.")); + originalOut.Write(stringWriter.ToString()); + } + finally + { + // Undo redirect, go back to writing to standard out + Console.SetOut(originalOut); + env.Cleanup(); + } + } +} \ No newline at end of file From 78f4707b117062952c28e9f517482a217351ae0e Mon Sep 17 00:00:00 2001 From: shantyk Date: Wed, 8 Oct 2025 05:29:56 -0600 Subject: [PATCH 13/34] Clean up tests --- .../shantys-tests/KickOffTests.cs | 78 ++++++++++++------- .../shantys-tests/TestSolutionBuilder.cs | 52 +++++++++++++ ...=> TestsWithMsBuildRegistrationDotnet6.cs} | 2 +- 3 files changed, 102 insertions(+), 30 deletions(-) rename detect-nuget-inspector/detect-nuget-inspector-tests/shantys-tests/{TestsWithMsBuildRegistration.cs => TestsWithMsBuildRegistrationDotnet6.cs} (98%) diff --git a/detect-nuget-inspector/detect-nuget-inspector-tests/shantys-tests/KickOffTests.cs b/detect-nuget-inspector/detect-nuget-inspector-tests/shantys-tests/KickOffTests.cs index c8c2872..01ff2f3 100644 --- a/detect-nuget-inspector/detect-nuget-inspector-tests/shantys-tests/KickOffTests.cs +++ b/detect-nuget-inspector/detect-nuget-inspector-tests/shantys-tests/KickOffTests.cs @@ -9,34 +9,9 @@ public class KickOffTests [TestMethod] public void TestBasicSetup_InvalidDotNetVersion() { - var runner = new NITestRunner(); - Assert.ThrowsException(() => { - runner.RunBasicSetupTest("99.0.999", "FailureSolution", "nonExistentDotnetVersion"); - }); - } - - - // dotnet 7.0.410 (nuget v6.7.1.1) - /*[TestMethod] - public void TestBasicSetup_DotNet7() - { - var runner = new NITestRunner(); - var result = runner.RunBasicSetupTest("7.0.410", "MyTestSolution", "dotnet7"); - - Assert.IsTrue(result.Success, result.Message); - }*/ - - // dotnet 8 tests (nuget v...) - [TestMethod] - public void TestBasicSetup_DotNet8() - { - var runner = new NITestRunner(); - - Assert.ThrowsException(() => - { - runner.RunBasicSetupTest("8.0.0", "MyTestSolution", "dotnet8"); + var env = new TestEnvironmentManager().SetupEnvironment("99.0.999", "nonExistentDotnetVersion"); }); } @@ -184,13 +159,58 @@ public void TestBasicSolution_DotNet6_DuplicatePackageReference_XMLResolver() } } - // for dotnet6, we could add .csproj branch, raw xml parser branch ... etc. // So what tests is REQUIRED so you can close your tickets: // 1. for validating nuget up to 6.3.4: - // duplicate PackageReference in .csproj file. Confirm both are captured. - // Duplicate PackageVersion in Directory.Packages.props. Confirm both are captured. + // duplicate PackageReference in .csproj file. Confirm both are captured. (done) + // Duplicate PackageVersion in Directory.Packages.props. Confirm both are captured.(stretch goal.... well no it has to be a CPM test haha) // 2. for validating nuget up to 6.7.1: // Central Package Management. Create solution with that very complicated set up. Confirm all captured. + + [TestMethod] + public void TestCPMSolution_DotNet7() // TODO finish me. + { + // 1. Set up environment with .NET 7 (nuget v6.7.1.1) + var dotnetVersion = "7.0.410"; + var env = new TestEnvironmentManager().SetupEnvironment(dotnetVersion, "dotnet7"); + + // 2. Create solution and projects with CPM enabled + var builder = new TestSolutionBuilder(env) + .CreateSolution("MyCPMDotnet7Solution") + .CreateAndAddProject("ProjectA") + .CreateAndAddProject("ProjectB") + .EnableCentralPackageManagementWithDesiredStructure() + .AddCentrallyManagedPackage("Newtonsoft.Json", "13.0.3") + .Build(); + + // 3. Run inspector + var options = new InspectionOptions + { + TargetPath = builder, + Verbose = true, + PackagesRepoUrl = "https://api.nuget.org/v3/index.json", + OutputDirectory = env.WorkingDirectory, + IgnoreFailure = false + }; + + try + { + var inspection = InspectorExecutor.ExecuteInspectors(options); + + // 4. Assert results + Assert.IsTrue(inspection.Success); + // ... further assertions for CPM dependencies ... + } + finally + { + env.Cleanup(); + } + } + + + // 3. Validates until nuget 6.11 (.NET 8.0.414) + [TestMethod] + public void TestSolution_DotNet8() // TODO + {} } } \ No newline at end of file diff --git a/detect-nuget-inspector/detect-nuget-inspector-tests/shantys-tests/TestSolutionBuilder.cs b/detect-nuget-inspector/detect-nuget-inspector-tests/shantys-tests/TestSolutionBuilder.cs index 2fc75e6..f4e96af 100644 --- a/detect-nuget-inspector/detect-nuget-inspector-tests/shantys-tests/TestSolutionBuilder.cs +++ b/detect-nuget-inspector/detect-nuget-inspector-tests/shantys-tests/TestSolutionBuilder.cs @@ -103,6 +103,58 @@ public TestSolutionBuilder NoBuildArtifacts() throw; } } + + public TestSolutionBuilder EnableCentralPackageManagementWithDesiredStructure() + { + // 1. Create Directory.Packages.props at solution root directory + // Create Directory.Packages.props manually for .NET 7 + var propsPath = Path.Combine(_solutionDirectory, "Directory.Packages.props"); + var propsContent = @" + + + +"; + File.WriteAllText(propsPath, propsContent); + + // 2. For each project, add true + var projectDirs = Directory.GetDirectories(_solutionDirectory) + .Where(d => File.Exists(Path.Combine(d, $"{Path.GetFileName(d)}.csproj"))); + foreach (var projectDir in projectDirs) + { + var projectName = Path.GetFileName(projectDir); + var csprojPath = Path.Combine(projectDir, $"{projectName}.csproj"); + var csprojXml = System.Xml.Linq.XDocument.Load(csprojPath); + var propertyGroup = csprojXml.Root.Elements("PropertyGroup").FirstOrDefault(); + if (propertyGroup == null) + { + propertyGroup = new System.Xml.Linq.XElement("PropertyGroup"); + csprojXml.Root.AddFirst(propertyGroup); + } + propertyGroup.Add(new System.Xml.Linq.XElement("ManagePackageVersionsCentrally", "true")); + csprojXml.Save(csprojPath); + } + + // Optionally, update Directory.Packages.props manually here if needed + + return this; + } + + public TestSolutionBuilder AddCentrallyManagedPackage(string packageName, string version) + { // TODO handle error where Directory.Packages.props does not exist + var propsPath = Path.Combine(_solutionDirectory, "Directory.Packages.props"); + var propsXml = System.Xml.Linq.XDocument.Load(propsPath); + var itemGroup = propsXml.Root.Elements("ItemGroup").FirstOrDefault(); + if (itemGroup == null) + { + itemGroup = new System.Xml.Linq.XElement("ItemGroup"); + propsXml.Root.Add(itemGroup); + } + itemGroup.Add(new System.Xml.Linq.XElement("PackageVersion", + new System.Xml.Linq.XAttribute("Include", packageName), + new System.Xml.Linq.XAttribute("Version", version))); + propsXml.Save(propsPath); + return this; + } private void RunDotNetCommand(string arguments, string workingDirectory) diff --git a/detect-nuget-inspector/detect-nuget-inspector-tests/shantys-tests/TestsWithMsBuildRegistration.cs b/detect-nuget-inspector/detect-nuget-inspector-tests/shantys-tests/TestsWithMsBuildRegistrationDotnet6.cs similarity index 98% rename from detect-nuget-inspector/detect-nuget-inspector-tests/shantys-tests/TestsWithMsBuildRegistration.cs rename to detect-nuget-inspector/detect-nuget-inspector-tests/shantys-tests/TestsWithMsBuildRegistrationDotnet6.cs index 6674eff..7a97f93 100644 --- a/detect-nuget-inspector/detect-nuget-inspector-tests/shantys-tests/TestsWithMsBuildRegistration.cs +++ b/detect-nuget-inspector/detect-nuget-inspector-tests/shantys-tests/TestsWithMsBuildRegistrationDotnet6.cs @@ -5,7 +5,7 @@ namespace DetectNugetInspectorTests.ShantysTests; // Tests cases for scenarios where MSBuild is registered via MSBuildLocator need to be in their own class to avoid // conflicts with other tests (MSBuild registration is process-wide and can only be done once per process.) -public class TestsWithMsBuildRegistration +public class TestsWithMsBuildRegistrationDotnet6 { [TestMethod] public void TestBasicSolution_DotNet6_DuplicatePackageReference_ProjectReferenceResolver() From 5d135d5c411c2a0b617da7cbca0ab16eacba4e92 Mon Sep 17 00:00:00 2001 From: shantyk Date: Wed, 8 Oct 2025 05:30:45 -0600 Subject: [PATCH 14/34] Rename some folders --- .../{shantys-tests => versioned-dotnet-tests}/KickOffTests.cs | 0 .../{shantys-tests => versioned-dotnet-tests}/NITestRunner.cs | 0 .../TestEnvironmentManager.cs | 0 .../TestSolutionBuilder.cs | 0 .../TestsWithMsBuildRegistrationDotnet6.cs | 0 5 files changed, 0 insertions(+), 0 deletions(-) rename detect-nuget-inspector/detect-nuget-inspector-tests/{shantys-tests => versioned-dotnet-tests}/KickOffTests.cs (100%) rename detect-nuget-inspector/detect-nuget-inspector-tests/{shantys-tests => versioned-dotnet-tests}/NITestRunner.cs (100%) rename detect-nuget-inspector/detect-nuget-inspector-tests/{shantys-tests => versioned-dotnet-tests}/TestEnvironmentManager.cs (100%) rename detect-nuget-inspector/detect-nuget-inspector-tests/{shantys-tests => versioned-dotnet-tests}/TestSolutionBuilder.cs (100%) rename detect-nuget-inspector/detect-nuget-inspector-tests/{shantys-tests => versioned-dotnet-tests}/TestsWithMsBuildRegistrationDotnet6.cs (100%) diff --git a/detect-nuget-inspector/detect-nuget-inspector-tests/shantys-tests/KickOffTests.cs b/detect-nuget-inspector/detect-nuget-inspector-tests/versioned-dotnet-tests/KickOffTests.cs similarity index 100% rename from detect-nuget-inspector/detect-nuget-inspector-tests/shantys-tests/KickOffTests.cs rename to detect-nuget-inspector/detect-nuget-inspector-tests/versioned-dotnet-tests/KickOffTests.cs diff --git a/detect-nuget-inspector/detect-nuget-inspector-tests/shantys-tests/NITestRunner.cs b/detect-nuget-inspector/detect-nuget-inspector-tests/versioned-dotnet-tests/NITestRunner.cs similarity index 100% rename from detect-nuget-inspector/detect-nuget-inspector-tests/shantys-tests/NITestRunner.cs rename to detect-nuget-inspector/detect-nuget-inspector-tests/versioned-dotnet-tests/NITestRunner.cs diff --git a/detect-nuget-inspector/detect-nuget-inspector-tests/shantys-tests/TestEnvironmentManager.cs b/detect-nuget-inspector/detect-nuget-inspector-tests/versioned-dotnet-tests/TestEnvironmentManager.cs similarity index 100% rename from detect-nuget-inspector/detect-nuget-inspector-tests/shantys-tests/TestEnvironmentManager.cs rename to detect-nuget-inspector/detect-nuget-inspector-tests/versioned-dotnet-tests/TestEnvironmentManager.cs diff --git a/detect-nuget-inspector/detect-nuget-inspector-tests/shantys-tests/TestSolutionBuilder.cs b/detect-nuget-inspector/detect-nuget-inspector-tests/versioned-dotnet-tests/TestSolutionBuilder.cs similarity index 100% rename from detect-nuget-inspector/detect-nuget-inspector-tests/shantys-tests/TestSolutionBuilder.cs rename to detect-nuget-inspector/detect-nuget-inspector-tests/versioned-dotnet-tests/TestSolutionBuilder.cs diff --git a/detect-nuget-inspector/detect-nuget-inspector-tests/shantys-tests/TestsWithMsBuildRegistrationDotnet6.cs b/detect-nuget-inspector/detect-nuget-inspector-tests/versioned-dotnet-tests/TestsWithMsBuildRegistrationDotnet6.cs similarity index 100% rename from detect-nuget-inspector/detect-nuget-inspector-tests/shantys-tests/TestsWithMsBuildRegistrationDotnet6.cs rename to detect-nuget-inspector/detect-nuget-inspector-tests/versioned-dotnet-tests/TestsWithMsBuildRegistrationDotnet6.cs From cf6cac3cc2fb808e91d496bc143e40b8ca480f31 Mon Sep 17 00:00:00 2001 From: shantyk Date: Wed, 8 Oct 2025 05:31:39 -0600 Subject: [PATCH 15/34] More clean up: remove unused class --- .../versioned-dotnet-tests/NITestRunner.cs | 110 ------------------ 1 file changed, 110 deletions(-) delete mode 100644 detect-nuget-inspector/detect-nuget-inspector-tests/versioned-dotnet-tests/NITestRunner.cs diff --git a/detect-nuget-inspector/detect-nuget-inspector-tests/versioned-dotnet-tests/NITestRunner.cs b/detect-nuget-inspector/detect-nuget-inspector-tests/versioned-dotnet-tests/NITestRunner.cs deleted file mode 100644 index 500e1e6..0000000 --- a/detect-nuget-inspector/detect-nuget-inspector-tests/versioned-dotnet-tests/NITestRunner.cs +++ /dev/null @@ -1,110 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; - -namespace DetectNugetInspectorTests.ShantysTests -{ - public class NITestRunner - { - private List _executedBranches = new List(); - - public NIResult RunBasicSetupTest(string dotnetVersion, string solutionName, string dotnetCommand) - { - Console.WriteLine($"Starting basic test with .NET version: {dotnetVersion} using command: {dotnetCommand}"); - - // 1. Setup environment - var env = new TestEnvironmentManager().SetupEnvironment(dotnetVersion, dotnetCommand); - - // 2. Create simple solution - var projectBuilder = new TestSolutionBuilder(env); - string solutionPath; - try - { - solutionPath = projectBuilder - .CreateSolution(solutionName) - .Build(); - Console.WriteLine($"✓ Solution created successfully at: {solutionPath}"); - } - catch (Exception ex) - { - Console.WriteLine($"✗ Solution creation failed: {ex.Message}"); - env.Cleanup(); - throw; - } - - // 3. Verify what was created - try - { - VerifyCreatedStructure(solutionPath, solutionName); - Console.WriteLine("✓ Solution structure verification passed"); - } - catch (Exception ex) - { - Console.WriteLine($"✗ Solution structure verification failed: {ex.Message}"); - env.Cleanup(); - throw; - } - - // 4. Cleanup - try - { - env.Cleanup(); - Console.WriteLine("✓ Cleanup completed successfully"); - } - catch (Exception ex) - { - Console.WriteLine($"⚠ Cleanup warning: {ex.Message}"); - } - - return new NIResult - { - Success = true, - Message = $"Basic setup test completed successfully for .NET {dotnetVersion} using {dotnetCommand}", - SolutionPath = solutionPath - }; - } - - private void VerifyCreatedStructure(string solutionPath, string solutionName) - { - // Check solution file exists - var solutionFile = Path.Combine(solutionPath, $"{solutionName}.sln"); - if (!File.Exists(solutionFile)) - throw new InvalidOperationException($"Solution file not found: {solutionFile}"); - - // Check Project1 directory exists - var project1Dir = Path.Combine(solutionPath, "Project1"); - if (!Directory.Exists(project1Dir)) - throw new InvalidOperationException($"Project1 directory not found: {project1Dir}"); - - // Check Project1.csproj exists - var project1File = Path.Combine(project1Dir, "Project1.csproj"); - if (!File.Exists(project1File)) - throw new InvalidOperationException($"Project1.csproj not found: {project1File}"); - - Console.WriteLine($" - Solution file: {solutionFile}"); - Console.WriteLine($" - Project1 directory: {project1Dir}"); - Console.WriteLine($" - Project1.csproj: {project1File}"); - } - - public List GetExecutedBranches() - { - return new List(_executedBranches); - } - } - - public class NIResult - { - public bool Success { get; set; } - public string Message { get; set; } - public string SolutionPath { get; set; } - // Keep the old properties for when we add back NI inspection - public object Container { get; set; } - public object Dependencies { get; set; } - public object Packages { get; set; } - } - - public class AssertionException : Exception - { - public AssertionException(string message) : base(message) { } - } -} \ No newline at end of file From f01ed9256d511c6f7f21c585c2939bdf76004536 Mon Sep 17 00:00:00 2001 From: shantyk Date: Wed, 8 Oct 2025 06:12:16 -0600 Subject: [PATCH 16/34] Add test case for dotnet 8 that uses MSBuild libraries --- .../TestsWithMsBuildRegistrationDotnet6.cs | 1 + .../TestsWithMsBuildRegistrationDotnet8.cs | 85 +++++++++++++++++++ .../Inspection/InspectorExecutionResult.cs | 6 +- 3 files changed, 89 insertions(+), 3 deletions(-) create mode 100644 detect-nuget-inspector/detect-nuget-inspector-tests/versioned-dotnet-tests/TestsWithMsBuildRegistrationDotnet8.cs diff --git a/detect-nuget-inspector/detect-nuget-inspector-tests/versioned-dotnet-tests/TestsWithMsBuildRegistrationDotnet6.cs b/detect-nuget-inspector/detect-nuget-inspector-tests/versioned-dotnet-tests/TestsWithMsBuildRegistrationDotnet6.cs index 7a97f93..d3eef38 100644 --- a/detect-nuget-inspector/detect-nuget-inspector-tests/versioned-dotnet-tests/TestsWithMsBuildRegistrationDotnet6.cs +++ b/detect-nuget-inspector/detect-nuget-inspector-tests/versioned-dotnet-tests/TestsWithMsBuildRegistrationDotnet6.cs @@ -5,6 +5,7 @@ namespace DetectNugetInspectorTests.ShantysTests; // Tests cases for scenarios where MSBuild is registered via MSBuildLocator need to be in their own class to avoid // conflicts with other tests (MSBuild registration is process-wide and can only be done once per process.) +[TestClass] public class TestsWithMsBuildRegistrationDotnet6 { [TestMethod] diff --git a/detect-nuget-inspector/detect-nuget-inspector-tests/versioned-dotnet-tests/TestsWithMsBuildRegistrationDotnet8.cs b/detect-nuget-inspector/detect-nuget-inspector-tests/versioned-dotnet-tests/TestsWithMsBuildRegistrationDotnet8.cs new file mode 100644 index 0000000..bef0c3d --- /dev/null +++ b/detect-nuget-inspector/detect-nuget-inspector-tests/versioned-dotnet-tests/TestsWithMsBuildRegistrationDotnet8.cs @@ -0,0 +1,85 @@ +using Blackduck.Detect.Nuget.Inspector.Inspection; +using Microsoft.Build.Locator; + +namespace DetectNugetInspectorTests.ShantysTests; + +[TestClass] +public class TestsWithMsBuildRegistrationDotnet8 +{ + [TestMethod] + public void TestBasicSolution_DotNet8_DuplicatePackageReference_ProjectReferenceResolver() + { + // 1. Set up environment with .NET 8 (nuget v6.11.1.2) + var dotnetVersion = "8.0.414"; + var env = new TestEnvironmentManager().SetupEnvironment(dotnetVersion, "dotnet8"); + + // 2. Create .NET 8 solution + var builder = new TestSolutionBuilder(env) + .CreateSolution("MySimpleDotnet8Solution") + .CreateAndAddProject("ProjectA") + .AddDependencyToProject("ProjectA", "Newtonsoft.Json", "13.0.3") + .AddPackageReferenceToCsprojManually("ProjectA", "Newtonsoft.Json", "12.0.1") + .NoBuildArtifacts() // So we can force using ProjectReferenceResolver instead of assets file + .Build(); + + + // 3. Run inspector + // Redirect console output for assertions later + var stringWriter = new StringWriter(); + var originalOut = Console.Out; + Console.SetOut(stringWriter); + + var options = new InspectionOptions() + { + TargetPath = builder, + Verbose = true, + PackagesRepoUrl = "https://api.nuget.org/v3/index.json", + OutputDirectory = env.WorkingDirectory, + IgnoreFailure = false + }; + + try + { + // Register MSBuild so ProjectReferenceResolver succeeds and does not cascade to XML resolver + var instance = MSBuildLocator.RegisterDefaults(); + Console.WriteLine($"MSBuild registered: {instance.Name} {instance.Version} at {instance.MSBuildPath}"); + + var inspection = InspectorExecutor.ExecuteInspectors(options); + + // 4. Assert inspection results + Assert.IsTrue(inspection.Success); + var inspectionResults = inspection.Results; + Assert.IsNotNull(inspectionResults); + Assert.AreEqual(1, inspectionResults.Count); + var result = inspectionResults[0]; + Assert.AreEqual(InspectionResult.ResultStatus.Success, result.Status); + Assert.IsNotNull(result.Containers); + Assert.AreEqual(1, result.Containers.Count); + var solutionContainer = result.Containers[0]; + Assert.AreEqual(solutionContainer.Type, "Solution"); + Assert.AreEqual("MySimpleDotnet8Solution", solutionContainer.Name); + + var projectContainer = solutionContainer.Children[0]; + Assert.AreEqual(projectContainer.Type, "Project"); + Assert.AreEqual("ProjectA", projectContainer.Name); + + Assert.IsNotNull(projectContainer.Dependencies); + var dependencies = projectContainer.Dependencies; + Assert.AreEqual(2, dependencies.Count); + // Confirm duplicates are captured + Assert.IsTrue(dependencies.Any(d => d.Name == "Newtonsoft.Json" && d.Version == "13.0.3")); + Assert.IsTrue(dependencies.Any(d => d.Name == "Newtonsoft.Json" && d.Version == "12.0.1")); + + // Assert console output + string output = stringWriter.ToString(); + Assert.IsTrue(output.Contains("Reference resolver succeeded.")); + originalOut.Write(stringWriter.ToString()); + } + finally + { + // Undo redirect, go back to writing to standard out + Console.SetOut(originalOut); + env.Cleanup(); + } + } +} \ No newline at end of file diff --git a/detect-nuget-inspector/detect-nuget-inspector/Inspection/InspectorExecutionResult.cs b/detect-nuget-inspector/detect-nuget-inspector/Inspection/InspectorExecutionResult.cs index fe03bbc..01e0642 100644 --- a/detect-nuget-inspector/detect-nuget-inspector/Inspection/InspectorExecutionResult.cs +++ b/detect-nuget-inspector/detect-nuget-inspector/Inspection/InspectorExecutionResult.cs @@ -24,12 +24,12 @@ public static InspectorExecutionResult Failed(int exitCode = -1) public static InspectorExecutionResult Succeeded(List? results) { - var something = new InspectorExecutionResult + var inspectionResults = new InspectorExecutionResult { Success = true }; - something.Results = results; - return something; + inspectionResults.Results = results; + return inspectionResults; } } } From 35beb2952f415c7ba75d74e44d8b643c38d19090 Mon Sep 17 00:00:00 2001 From: shantyk Date: Wed, 8 Oct 2025 06:34:20 -0600 Subject: [PATCH 17/34] update dotnet 6 version to match build machine --- .../versioned-dotnet-tests/KickOffTests.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/detect-nuget-inspector/detect-nuget-inspector-tests/versioned-dotnet-tests/KickOffTests.cs b/detect-nuget-inspector/detect-nuget-inspector-tests/versioned-dotnet-tests/KickOffTests.cs index 01ff2f3..e50631d 100644 --- a/detect-nuget-inspector/detect-nuget-inspector-tests/versioned-dotnet-tests/KickOffTests.cs +++ b/detect-nuget-inspector/detect-nuget-inspector-tests/versioned-dotnet-tests/KickOffTests.cs @@ -19,7 +19,7 @@ public void TestBasicSetup_InvalidDotNetVersion() public void TestBasicSolution_DotNet6_ProjectAssetsJsonFile() { // 1. Set up environment with .NET 6 (nuget v6.3.4.2) - var dotnetVersion = "6.0.428"; // todo change me to match what is on jenkins + var dotnetVersion = "6.0.201"; var env = new TestEnvironmentManager().SetupEnvironment(dotnetVersion, "dotnet6"); // 2. Create .NET 6 solution @@ -89,7 +89,7 @@ public void TestBasicSolution_DotNet6_ProjectAssetsJsonFile() public void TestBasicSolution_DotNet6_DuplicatePackageReference_XMLResolver() { // 1. Set up environment with .NET 6 (nuget v6.3.4.2) - var dotnetVersion = "6.0.428"; + var dotnetVersion = "6.0.201"; var env = new TestEnvironmentManager().SetupEnvironment(dotnetVersion, "dotnet6"); // 2. Create .NET 6 solution From d4f9fe602b92a7996fd7021dd72a6fa210c93ad4 Mon Sep 17 00:00:00 2001 From: shantyk Date: Wed, 8 Oct 2025 06:48:09 -0600 Subject: [PATCH 18/34] Restore test project on dotnet8 before adding packages --- .../versioned-dotnet-tests/TestSolutionBuilder.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/detect-nuget-inspector/detect-nuget-inspector-tests/versioned-dotnet-tests/TestSolutionBuilder.cs b/detect-nuget-inspector/detect-nuget-inspector-tests/versioned-dotnet-tests/TestSolutionBuilder.cs index f4e96af..c78aed6 100644 --- a/detect-nuget-inspector/detect-nuget-inspector-tests/versioned-dotnet-tests/TestSolutionBuilder.cs +++ b/detect-nuget-inspector/detect-nuget-inspector-tests/versioned-dotnet-tests/TestSolutionBuilder.cs @@ -57,6 +57,11 @@ public TestSolutionBuilder AddDependencyToProject(string projectName, string pac { try { var projectDir = Path.Combine(_solutionDirectory, projectName); + + // First, restore the project to ensure it's in a proper state + RunDotNetCommand("restore", projectDir); + + // Then add the package var args = $"add package {packageName} --version {version}"; RunDotNetCommand(args, projectDir); return this; From 54b5bfcc1f6d7efc3a5321cf7fc6c946ac352e34 Mon Sep 17 00:00:00 2001 From: shantyk Date: Wed, 8 Oct 2025 06:54:51 -0600 Subject: [PATCH 19/34] Match jenkins --- .../TestsWithMsBuildRegistrationDotnet6.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/detect-nuget-inspector/detect-nuget-inspector-tests/versioned-dotnet-tests/TestsWithMsBuildRegistrationDotnet6.cs b/detect-nuget-inspector/detect-nuget-inspector-tests/versioned-dotnet-tests/TestsWithMsBuildRegistrationDotnet6.cs index d3eef38..6e64d94 100644 --- a/detect-nuget-inspector/detect-nuget-inspector-tests/versioned-dotnet-tests/TestsWithMsBuildRegistrationDotnet6.cs +++ b/detect-nuget-inspector/detect-nuget-inspector-tests/versioned-dotnet-tests/TestsWithMsBuildRegistrationDotnet6.cs @@ -12,7 +12,7 @@ public class TestsWithMsBuildRegistrationDotnet6 public void TestBasicSolution_DotNet6_DuplicatePackageReference_ProjectReferenceResolver() { // 1. Set up environment with .NET 6 (nuget v6.3.4.2) - var dotnetVersion = "6.0.428"; + var dotnetVersion = "6.0.201"; var env = new TestEnvironmentManager().SetupEnvironment(dotnetVersion, "dotnet6"); // 2. Create .NET 6 solution From 99aae55f8fedb3a38e4017e1b0c76f9a0d97df35 Mon Sep 17 00:00:00 2001 From: shantyk Date: Wed, 8 Oct 2025 07:00:27 -0600 Subject: [PATCH 20/34] Fix failing dotnet8 test --- .../TestsWithMsBuildRegistrationDotnet8.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/detect-nuget-inspector/detect-nuget-inspector-tests/versioned-dotnet-tests/TestsWithMsBuildRegistrationDotnet8.cs b/detect-nuget-inspector/detect-nuget-inspector-tests/versioned-dotnet-tests/TestsWithMsBuildRegistrationDotnet8.cs index bef0c3d..d800898 100644 --- a/detect-nuget-inspector/detect-nuget-inspector-tests/versioned-dotnet-tests/TestsWithMsBuildRegistrationDotnet8.cs +++ b/detect-nuget-inspector/detect-nuget-inspector-tests/versioned-dotnet-tests/TestsWithMsBuildRegistrationDotnet8.cs @@ -17,7 +17,8 @@ public void TestBasicSolution_DotNet8_DuplicatePackageReference_ProjectReference var builder = new TestSolutionBuilder(env) .CreateSolution("MySimpleDotnet8Solution") .CreateAndAddProject("ProjectA") - .AddDependencyToProject("ProjectA", "Newtonsoft.Json", "13.0.3") + // Add them manually because dotnet8 doesn't allow adding duplicate PackageReference via CLI + .AddPackageReferenceToCsprojManually("ProjectA", "Newtonsoft.Json", "13.0.3") .AddPackageReferenceToCsprojManually("ProjectA", "Newtonsoft.Json", "12.0.1") .NoBuildArtifacts() // So we can force using ProjectReferenceResolver instead of assets file .Build(); From e375ca714213322a44975e268775916855f9cd21 Mon Sep 17 00:00:00 2001 From: shantyk Date: Wed, 8 Oct 2025 07:14:14 -0600 Subject: [PATCH 21/34] Isolate runs so we can register new msbuild each time --- detect-nuget-inspector-tests/Isolated.runsettings | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 detect-nuget-inspector-tests/Isolated.runsettings diff --git a/detect-nuget-inspector-tests/Isolated.runsettings b/detect-nuget-inspector-tests/Isolated.runsettings new file mode 100644 index 0000000..6663f2a --- /dev/null +++ b/detect-nuget-inspector-tests/Isolated.runsettings @@ -0,0 +1,13 @@ + + + + + + + true + + + + + + From 30cee61d92b2b91fa12332f7b5c70508eab64329 Mon Sep 17 00:00:00 2001 From: shantyk Date: Wed, 8 Oct 2025 09:01:15 -0600 Subject: [PATCH 22/34] Clean up --- .../versioned-dotnet-tests/KickOffTests.cs | 84 +++++++++++++++--- .../TestsWithMsBuildRegistrationDotnet6.cs | 87 ------------------- 2 files changed, 74 insertions(+), 97 deletions(-) delete mode 100644 detect-nuget-inspector/detect-nuget-inspector-tests/versioned-dotnet-tests/TestsWithMsBuildRegistrationDotnet6.cs diff --git a/detect-nuget-inspector/detect-nuget-inspector-tests/versioned-dotnet-tests/KickOffTests.cs b/detect-nuget-inspector/detect-nuget-inspector-tests/versioned-dotnet-tests/KickOffTests.cs index e50631d..cb1f6b7 100644 --- a/detect-nuget-inspector/detect-nuget-inspector-tests/versioned-dotnet-tests/KickOffTests.cs +++ b/detect-nuget-inspector/detect-nuget-inspector-tests/versioned-dotnet-tests/KickOffTests.cs @@ -159,14 +159,6 @@ public void TestBasicSolution_DotNet6_DuplicatePackageReference_XMLResolver() } } - // So what tests is REQUIRED so you can close your tickets: - // 1. for validating nuget up to 6.3.4: - // duplicate PackageReference in .csproj file. Confirm both are captured. (done) - // Duplicate PackageVersion in Directory.Packages.props. Confirm both are captured.(stretch goal.... well no it has to be a CPM test haha) - - // 2. for validating nuget up to 6.7.1: - // Central Package Management. Create solution with that very complicated set up. Confirm all captured. - [TestMethod] public void TestCPMSolution_DotNet7() // TODO finish me. { @@ -210,7 +202,79 @@ public void TestCPMSolution_DotNet7() // TODO finish me. // 3. Validates until nuget 6.11 (.NET 8.0.414) [TestMethod] - public void TestSolution_DotNet8() // TODO - {} + public void TestSolution_DotNet8() + { + { + // 1. Set up environment with .NET 8 (nuget v6.11.1.2) + var dotnetVersion = "8.0.414"; + var env = new TestEnvironmentManager().SetupEnvironment(dotnetVersion, "dotnet8"); + + // 2. Create .NET 8 solution + var builder = new TestSolutionBuilder(env) + .CreateSolution("MySimpleDotnet8Solution") + .CreateAndAddProject("ProjectA") + // Add them manually because dotnet8 doesn't allow adding duplicate PackageReference via CLI + .AddPackageReferenceToCsprojManually("ProjectA", "Newtonsoft.Json", "13.0.3") + .AddPackageReferenceToCsprojManually("ProjectA", "Newtonsoft.Json", "12.0.1") + .NoBuildArtifacts() // So we can force using ProjectReferenceResolver instead of assets file + .Build(); + + + // 3. Run inspector + // Redirect console output for assertions later + var stringWriter = new StringWriter(); + var originalOut = Console.Out; + Console.SetOut(stringWriter); + + var options = new InspectionOptions() + { + TargetPath = builder, + Verbose = true, + PackagesRepoUrl = "https://api.nuget.org/v3/index.json", + OutputDirectory = env.WorkingDirectory, + IgnoreFailure = false + }; + + try + { + var inspection = InspectorExecutor.ExecuteInspectors(options); + + // 4. Assert inspection results + Assert.IsTrue(inspection.Success); + var inspectionResults = inspection.Results; + Assert.IsNotNull(inspectionResults); + Assert.AreEqual(1, inspectionResults.Count); + var result = inspectionResults[0]; + Assert.AreEqual(InspectionResult.ResultStatus.Success, result.Status); + Assert.IsNotNull(result.Containers); + Assert.AreEqual(1, result.Containers.Count); + var solutionContainer = result.Containers[0]; + Assert.AreEqual(solutionContainer.Type, "Solution"); + Assert.AreEqual("MySimpleDotnet8Solution", solutionContainer.Name); + + var projectContainer = solutionContainer.Children[0]; + Assert.AreEqual(projectContainer.Type, "Project"); + Assert.AreEqual("ProjectA", projectContainer.Name); + + Assert.IsNotNull(projectContainer.Dependencies); + var dependencies = projectContainer.Dependencies; + Assert.AreEqual(2, dependencies.Count); + // Confirm duplicates are captured + Assert.IsTrue(dependencies.Any(d => d.Name == "Newtonsoft.Json" && d.Version == "13.0.3")); + Assert.IsTrue(dependencies.Any(d => d.Name == "Newtonsoft.Json" && d.Version == "12.0.1")); + + // Assert console output + string output = stringWriter.ToString(); + Assert.IsTrue(output.Contains("Reference resolver succeeded.")); + originalOut.Write(stringWriter.ToString()); + } + finally + { + // Undo redirect, go back to writing to standard out + Console.SetOut(originalOut); + env.Cleanup(); + } + } + } } } \ No newline at end of file diff --git a/detect-nuget-inspector/detect-nuget-inspector-tests/versioned-dotnet-tests/TestsWithMsBuildRegistrationDotnet6.cs b/detect-nuget-inspector/detect-nuget-inspector-tests/versioned-dotnet-tests/TestsWithMsBuildRegistrationDotnet6.cs deleted file mode 100644 index 6e64d94..0000000 --- a/detect-nuget-inspector/detect-nuget-inspector-tests/versioned-dotnet-tests/TestsWithMsBuildRegistrationDotnet6.cs +++ /dev/null @@ -1,87 +0,0 @@ -using Blackduck.Detect.Nuget.Inspector.Inspection; -using Microsoft.Build.Locator; - -namespace DetectNugetInspectorTests.ShantysTests; - -// Tests cases for scenarios where MSBuild is registered via MSBuildLocator need to be in their own class to avoid -// conflicts with other tests (MSBuild registration is process-wide and can only be done once per process.) -[TestClass] -public class TestsWithMsBuildRegistrationDotnet6 -{ - [TestMethod] - public void TestBasicSolution_DotNet6_DuplicatePackageReference_ProjectReferenceResolver() - { - // 1. Set up environment with .NET 6 (nuget v6.3.4.2) - var dotnetVersion = "6.0.201"; - var env = new TestEnvironmentManager().SetupEnvironment(dotnetVersion, "dotnet6"); - - // 2. Create .NET 6 solution - var builder = new TestSolutionBuilder(env) - .CreateSolution("MySimpleDotnet6Solution") - .CreateAndAddProject("ProjectA") - .AddDependencyToProject("ProjectA", "Newtonsoft.Json", "13.0.3") - .AddPackageReferenceToCsprojManually("ProjectA", "Newtonsoft.Json", "12.0.1") - .NoBuildArtifacts() // So we can force using ProjectReferenceResolver instead of assets file - .Build(); - - - // 3. Run inspector - // Redirect console output for assertions later - var stringWriter = new StringWriter(); - var originalOut = Console.Out; - Console.SetOut(stringWriter); - - var options = new InspectionOptions() - { - TargetPath = builder, - Verbose = true, - PackagesRepoUrl = "https://api.nuget.org/v3/index.json", - OutputDirectory = env.WorkingDirectory, - IgnoreFailure = false - }; - - try - { - // Register MSBuild so ProjectReferenceResolver succeeds and does not cascade to XML resolver - var instance = MSBuildLocator.RegisterDefaults(); - Console.WriteLine($"MSBuild registered: {instance.Name} {instance.Version} at {instance.MSBuildPath}"); - - var inspection = InspectorExecutor.ExecuteInspectors(options); - - // 4. Assert inspection results - Assert.IsTrue(inspection.Success); - var inspectionResults = inspection.Results; - Assert.IsNotNull(inspectionResults); - Assert.AreEqual(1, inspectionResults.Count); - var result = inspectionResults[0]; - Assert.AreEqual(InspectionResult.ResultStatus.Success, result.Status); - Assert.IsNotNull(result.Containers); - Assert.AreEqual(1, result.Containers.Count); - var solutionContainer = result.Containers[0]; - Assert.AreEqual(solutionContainer.Type, "Solution"); - Assert.AreEqual("MySimpleDotnet6Solution", solutionContainer.Name); - - var projectContainer = solutionContainer.Children[0]; - Assert.AreEqual(projectContainer.Type, "Project"); - Assert.AreEqual("ProjectA", projectContainer.Name); - - Assert.IsNotNull(projectContainer.Dependencies); - var dependencies = projectContainer.Dependencies; - Assert.AreEqual(2, dependencies.Count); - // Confirm duplicates are captured - Assert.IsTrue(dependencies.Any(d => d.Name == "Newtonsoft.Json" && d.Version == "13.0.3")); - Assert.IsTrue(dependencies.Any(d => d.Name == "Newtonsoft.Json" && d.Version == "12.0.1")); - - // Assert console output - string output = stringWriter.ToString(); - Assert.IsTrue(output.Contains("Reference resolver succeeded.")); - originalOut.Write(stringWriter.ToString()); - } - finally - { - // Undo redirect, go back to writing to standard out - Console.SetOut(originalOut); - env.Cleanup(); - } - } -} \ No newline at end of file From 6ba3b801137f5764691c0182317d2ab235ee177d Mon Sep 17 00:00:00 2001 From: shantyk Date: Tue, 14 Oct 2025 04:26:32 -0600 Subject: [PATCH 23/34] Update namespaces --- .../versioned-dotnet-tests/KickOffTests.cs | 3 +-- .../versioned-dotnet-tests/TestEnvironmentManager.cs | 4 +--- .../versioned-dotnet-tests/TestSolutionBuilder.cs | 4 +--- .../TestsWithMsBuildRegistrationDotnet8.cs | 2 +- 4 files changed, 4 insertions(+), 9 deletions(-) diff --git a/detect-nuget-inspector/detect-nuget-inspector-tests/versioned-dotnet-tests/KickOffTests.cs b/detect-nuget-inspector/detect-nuget-inspector-tests/versioned-dotnet-tests/KickOffTests.cs index cb1f6b7..5418605 100644 --- a/detect-nuget-inspector/detect-nuget-inspector-tests/versioned-dotnet-tests/KickOffTests.cs +++ b/detect-nuget-inspector/detect-nuget-inspector-tests/versioned-dotnet-tests/KickOffTests.cs @@ -1,7 +1,6 @@ using Blackduck.Detect.Nuget.Inspector.Inspection; -using Microsoft.Build.Locator; -namespace DetectNugetInspectorTests.ShantysTests +namespace detect_nuget_inspector_tests.versioned_dotnet_tests { [TestClass] public class KickOffTests diff --git a/detect-nuget-inspector/detect-nuget-inspector-tests/versioned-dotnet-tests/TestEnvironmentManager.cs b/detect-nuget-inspector/detect-nuget-inspector-tests/versioned-dotnet-tests/TestEnvironmentManager.cs index 9ab7e6c..353a3c8 100644 --- a/detect-nuget-inspector/detect-nuget-inspector-tests/versioned-dotnet-tests/TestEnvironmentManager.cs +++ b/detect-nuget-inspector/detect-nuget-inspector-tests/versioned-dotnet-tests/TestEnvironmentManager.cs @@ -1,8 +1,6 @@ -using System; using System.Diagnostics; -using System.IO; -namespace DetectNugetInspectorTests.ShantysTests +namespace detect_nuget_inspector_tests.versioned_dotnet_tests { public class TestEnvironmentManager { diff --git a/detect-nuget-inspector/detect-nuget-inspector-tests/versioned-dotnet-tests/TestSolutionBuilder.cs b/detect-nuget-inspector/detect-nuget-inspector-tests/versioned-dotnet-tests/TestSolutionBuilder.cs index c78aed6..207f421 100644 --- a/detect-nuget-inspector/detect-nuget-inspector-tests/versioned-dotnet-tests/TestSolutionBuilder.cs +++ b/detect-nuget-inspector/detect-nuget-inspector-tests/versioned-dotnet-tests/TestSolutionBuilder.cs @@ -1,8 +1,6 @@ -using System; using System.Diagnostics; -using System.IO; -namespace DetectNugetInspectorTests.ShantysTests +namespace detect_nuget_inspector_tests.versioned_dotnet_tests { public class TestSolutionBuilder { diff --git a/detect-nuget-inspector/detect-nuget-inspector-tests/versioned-dotnet-tests/TestsWithMsBuildRegistrationDotnet8.cs b/detect-nuget-inspector/detect-nuget-inspector-tests/versioned-dotnet-tests/TestsWithMsBuildRegistrationDotnet8.cs index d800898..25b71e0 100644 --- a/detect-nuget-inspector/detect-nuget-inspector-tests/versioned-dotnet-tests/TestsWithMsBuildRegistrationDotnet8.cs +++ b/detect-nuget-inspector/detect-nuget-inspector-tests/versioned-dotnet-tests/TestsWithMsBuildRegistrationDotnet8.cs @@ -1,7 +1,7 @@ using Blackduck.Detect.Nuget.Inspector.Inspection; using Microsoft.Build.Locator; -namespace DetectNugetInspectorTests.ShantysTests; +namespace detect_nuget_inspector_tests.versioned_dotnet_tests; [TestClass] public class TestsWithMsBuildRegistrationDotnet8 From 7e9d1f7b5318104210e17e893e6c3c643055e71f Mon Sep 17 00:00:00 2001 From: shantyk Date: Tue, 14 Oct 2025 04:40:30 -0600 Subject: [PATCH 24/34] Clean up log msgs --- .../versioned-dotnet-tests/KickOffTests.cs | 5 ++--- .../TestEnvironmentManager.cs | 18 +++++++++--------- 2 files changed, 11 insertions(+), 12 deletions(-) diff --git a/detect-nuget-inspector/detect-nuget-inspector-tests/versioned-dotnet-tests/KickOffTests.cs b/detect-nuget-inspector/detect-nuget-inspector-tests/versioned-dotnet-tests/KickOffTests.cs index 5418605..59a14bd 100644 --- a/detect-nuget-inspector/detect-nuget-inspector-tests/versioned-dotnet-tests/KickOffTests.cs +++ b/detect-nuget-inspector/detect-nuget-inspector-tests/versioned-dotnet-tests/KickOffTests.cs @@ -85,7 +85,7 @@ public void TestBasicSolution_DotNet6_ProjectAssetsJsonFile() } [TestMethod] - public void TestBasicSolution_DotNet6_DuplicatePackageReference_XMLResolver() + public void TestSolution_DotNet6_DuplicatePackageReference_XMLResolver() { // 1. Set up environment with .NET 6 (nuget v6.3.4.2) var dotnetVersion = "6.0.201"; @@ -159,7 +159,7 @@ public void TestBasicSolution_DotNet6_DuplicatePackageReference_XMLResolver() } [TestMethod] - public void TestCPMSolution_DotNet7() // TODO finish me. + public void TestCPMSolution_DotNet7() { // 1. Set up environment with .NET 7 (nuget v6.7.1.1) var dotnetVersion = "7.0.410"; @@ -199,7 +199,6 @@ public void TestCPMSolution_DotNet7() // TODO finish me. } - // 3. Validates until nuget 6.11 (.NET 8.0.414) [TestMethod] public void TestSolution_DotNet8() { diff --git a/detect-nuget-inspector/detect-nuget-inspector-tests/versioned-dotnet-tests/TestEnvironmentManager.cs b/detect-nuget-inspector/detect-nuget-inspector-tests/versioned-dotnet-tests/TestEnvironmentManager.cs index 353a3c8..1c2351f 100644 --- a/detect-nuget-inspector/detect-nuget-inspector-tests/versioned-dotnet-tests/TestEnvironmentManager.cs +++ b/detect-nuget-inspector/detect-nuget-inspector-tests/versioned-dotnet-tests/TestEnvironmentManager.cs @@ -33,7 +33,7 @@ public TestEnvironmentManager SetupEnvironment(string dotnetVersion, string desi private void ValidateAndLogVersions(string expectedVersion, string command) { - Console.WriteLine($"🔍 Validating environment with command: {command}"); + Console.WriteLine($"Validating environment with command: {command}"); // Check .NET version var dotnetVersionResult = RunCommand(command, " --version"); @@ -43,12 +43,12 @@ private void ValidateAndLogVersions(string expectedVersion, string command) } var actualDotNetVersion = dotnetVersionResult.Output.Trim(); - Console.WriteLine($"📋 .NET Version: {actualDotNetVersion}"); + Console.WriteLine($".NET Version: {actualDotNetVersion}"); // Throw exception if the requested version doesn't match what's available if (!actualDotNetVersion.StartsWith(expectedVersion)) { - Console.WriteLine($"❌ Version mismatch: Expected {expectedVersion}, but got {actualDotNetVersion}"); + Console.WriteLine($"✗ Version mismatch: Expected {expectedVersion}, but got {actualDotNetVersion}"); throw new InvalidOperationException($"Requested .NET version {expectedVersion} is not available. System returned version {actualDotNetVersion}. Please install the required .NET SDK version and create appropriate alias."); } @@ -57,16 +57,16 @@ private void ValidateAndLogVersions(string expectedVersion, string command) if (nugetVersionResult.ExitCode == 0) { NuGetVersion = nugetVersionResult.Output.Trim(); - Console.WriteLine($"📦 NuGet Version: {NuGetVersion}"); + Console.WriteLine($"NuGet Version: {NuGetVersion}"); } else { - Console.WriteLine($"⚠️ Could not determine NuGet version: {nugetVersionResult.Error}"); + Console.WriteLine($"Could not determine NuGet version: {nugetVersionResult.Error}"); NuGetVersion = "Unknown"; } - Console.WriteLine($"📁 Working Directory: {WorkingDirectory}"); - Console.WriteLine("✅ Environment validation complete"); + Console.WriteLine($"Working Directory: {WorkingDirectory}"); + Console.WriteLine("✓ Environment validation complete"); } private (int ExitCode, string Output, string Error) RunCommand(string command, string arguments) // TODO only need one dotnet command runner @@ -95,7 +95,7 @@ private void ValidateAndLogVersions(string expectedVersion, string command) } catch (Exception ex) { - //Console.Error.WriteLine($"❌ Error running command '{command} {arguments}': {ex.Message}"); + Console.Error.WriteLine($"✗ Error running command '{command} {arguments}': {ex.Message}"); return (-1, string.Empty, ex.Message); } } @@ -105,7 +105,7 @@ public void Cleanup() if (Directory.Exists(WorkingDirectory)) { Directory.Delete(WorkingDirectory, true); - Console.WriteLine($"🧹 Cleaned up working directory: {WorkingDirectory}"); + Console.WriteLine($"Cleaned up working directory: {WorkingDirectory}"); } } From ef68e5b7af15eb0dd5c1272d9b7432f3125bc480 Mon Sep 17 00:00:00 2001 From: shantyk Date: Tue, 14 Oct 2025 04:58:07 -0600 Subject: [PATCH 25/34] Make test failures more readable --- .../versioned-dotnet-tests/KickOffTests.cs | 68 +++++++++++++++---- 1 file changed, 56 insertions(+), 12 deletions(-) diff --git a/detect-nuget-inspector/detect-nuget-inspector-tests/versioned-dotnet-tests/KickOffTests.cs b/detect-nuget-inspector/detect-nuget-inspector-tests/versioned-dotnet-tests/KickOffTests.cs index 59a14bd..bb8ba3d 100644 --- a/detect-nuget-inspector/detect-nuget-inspector-tests/versioned-dotnet-tests/KickOffTests.cs +++ b/detect-nuget-inspector/detect-nuget-inspector-tests/versioned-dotnet-tests/KickOffTests.cs @@ -5,13 +5,39 @@ namespace detect_nuget_inspector_tests.versioned_dotnet_tests [TestClass] public class KickOffTests { + public TestContext TestContext { get; set; } + private bool _testFailed; + + [TestInitialize] + public void PrintTestName() + { + Console.WriteLine($"Starting test: {TestContext.TestName}"); + } + + [TestCleanup] + public void PrintTestResult() + { + Console.WriteLine(_testFailed + ? $"❌ Test {TestContext.TestName} FAILED" + : $"✅ Test {TestContext.TestName} PASSED"); + } + + [TestMethod] public void TestBasicSetup_InvalidDotNetVersion() { - Assert.ThrowsException(() => + try + { + Assert.ThrowsException(() => + { + var env = new TestEnvironmentManager().SetupEnvironment("99.0.999", "nonExistentDotnetVersion"); + }); + } + catch { - var env = new TestEnvironmentManager().SetupEnvironment("99.0.999", "nonExistentDotnetVersion"); - }); + _testFailed = true; + throw; + } } [TestMethod] @@ -76,6 +102,11 @@ public void TestBasicSolution_DotNet6_ProjectAssetsJsonFile() Assert.IsTrue(output.Contains("Using assets json file:")); originalOut.Write(stringWriter.ToString()); } + catch + { + _testFailed = true; + throw; + } finally { // Undo redirect, go back to writing to standard out @@ -83,8 +114,8 @@ public void TestBasicSolution_DotNet6_ProjectAssetsJsonFile() env.Cleanup(); } } - - [TestMethod] + + [TestMethod] public void TestSolution_DotNet6_DuplicatePackageReference_XMLResolver() { // 1. Set up environment with .NET 6 (nuget v6.3.4.2) @@ -150,6 +181,11 @@ public void TestSolution_DotNet6_DuplicatePackageReference_XMLResolver() Assert.IsTrue(output.Contains("Using backup XML resolver.")); originalOut.Write(stringWriter.ToString()); } + catch + { + _testFailed = true; + throw; + } finally { // Undo redirect, go back to writing to standard out @@ -164,7 +200,7 @@ public void TestCPMSolution_DotNet7() // 1. Set up environment with .NET 7 (nuget v6.7.1.1) var dotnetVersion = "7.0.410"; var env = new TestEnvironmentManager().SetupEnvironment(dotnetVersion, "dotnet7"); - + // 2. Create solution and projects with CPM enabled var builder = new TestSolutionBuilder(env) .CreateSolution("MyCPMDotnet7Solution") @@ -173,7 +209,7 @@ public void TestCPMSolution_DotNet7() .EnableCentralPackageManagementWithDesiredStructure() .AddCentrallyManagedPackage("Newtonsoft.Json", "13.0.3") .Build(); - + // 3. Run inspector var options = new InspectionOptions { @@ -183,7 +219,7 @@ public void TestCPMSolution_DotNet7() OutputDirectory = env.WorkingDirectory, IgnoreFailure = false }; - + try { var inspection = InspectorExecutor.ExecuteInspectors(options); @@ -192,17 +228,21 @@ public void TestCPMSolution_DotNet7() Assert.IsTrue(inspection.Success); // ... further assertions for CPM dependencies ... } + catch + { + _testFailed = true; + throw; + } finally { env.Cleanup(); } } - - + + [TestMethod] public void TestSolution_DotNet8() { - { // 1. Set up environment with .NET 8 (nuget v6.11.1.2) var dotnetVersion = "8.0.414"; var env = new TestEnvironmentManager().SetupEnvironment(dotnetVersion, "dotnet8"); @@ -266,6 +306,11 @@ public void TestSolution_DotNet8() Assert.IsTrue(output.Contains("Reference resolver succeeded.")); originalOut.Write(stringWriter.ToString()); } + catch + { + _testFailed = true; + throw; + } finally { // Undo redirect, go back to writing to standard out @@ -273,6 +318,5 @@ public void TestSolution_DotNet8() env.Cleanup(); } } - } } } \ No newline at end of file From 23d845095dcb7911ca9e4e385d0d42148d0033c4 Mon Sep 17 00:00:00 2001 From: shantyk Date: Tue, 14 Oct 2025 07:00:56 -0600 Subject: [PATCH 26/34] Some tests that would've been useful if they could be fixed, perhaps in the future: nested solution files with parent CPM. And Tests with MSBuild registration if tests could be truly isolated. --- .../versioned-dotnet-tests/KickOffTests.cs | 12 +- .../TestSolutionBuilder.cs | 160 +++++++++++++++--- .../TestsWithMsBuildRegistrationDotnet8.cs | 2 +- 3 files changed, 139 insertions(+), 35 deletions(-) diff --git a/detect-nuget-inspector/detect-nuget-inspector-tests/versioned-dotnet-tests/KickOffTests.cs b/detect-nuget-inspector/detect-nuget-inspector-tests/versioned-dotnet-tests/KickOffTests.cs index bb8ba3d..1ed6034 100644 --- a/detect-nuget-inspector/detect-nuget-inspector-tests/versioned-dotnet-tests/KickOffTests.cs +++ b/detect-nuget-inspector/detect-nuget-inspector-tests/versioned-dotnet-tests/KickOffTests.cs @@ -128,7 +128,7 @@ public void TestSolution_DotNet6_DuplicatePackageReference_XMLResolver() .CreateAndAddProject("ProjectA") .AddDependencyToProject("ProjectA", "Newtonsoft.Json", "13.0.3") .AddPackageReferenceToCsprojManually("ProjectA", "Newtonsoft.Json", "12.0.1") - .NoBuildArtifacts() // So we can bypass assets file during cascading + .RemoveBuildArtifacts() // So we can bypass assets file during cascading .Build(); @@ -204,10 +204,7 @@ public void TestCPMSolution_DotNet7() // 2. Create solution and projects with CPM enabled var builder = new TestSolutionBuilder(env) .CreateSolution("MyCPMDotnet7Solution") - .CreateAndAddProject("ProjectA") - .CreateAndAddProject("ProjectB") .EnableCentralPackageManagementWithDesiredStructure() - .AddCentrallyManagedPackage("Newtonsoft.Json", "13.0.3") .Build(); // 3. Run inspector @@ -222,6 +219,9 @@ public void TestCPMSolution_DotNet7() try { + // run dotnet7 restore + // run dotnet7 list package + // pause here ans ask me what to do with the output. var inspection = InspectorExecutor.ExecuteInspectors(options); // 4. Assert results @@ -241,7 +241,7 @@ public void TestCPMSolution_DotNet7() [TestMethod] - public void TestSolution_DotNet8() + public void TestSolution_DotNet8() // TODO: This test and TestSolution_DotNet6_DuplicatePackageReference_XMLResolver are duplicates, parameterize them { // 1. Set up environment with .NET 8 (nuget v6.11.1.2) var dotnetVersion = "8.0.414"; @@ -254,7 +254,7 @@ public void TestSolution_DotNet8() // Add them manually because dotnet8 doesn't allow adding duplicate PackageReference via CLI .AddPackageReferenceToCsprojManually("ProjectA", "Newtonsoft.Json", "13.0.3") .AddPackageReferenceToCsprojManually("ProjectA", "Newtonsoft.Json", "12.0.1") - .NoBuildArtifacts() // So we can force using ProjectReferenceResolver instead of assets file + .RemoveBuildArtifacts() // So we can force using ProjectReferenceResolver instead of assets file .Build(); diff --git a/detect-nuget-inspector/detect-nuget-inspector-tests/versioned-dotnet-tests/TestSolutionBuilder.cs b/detect-nuget-inspector/detect-nuget-inspector-tests/versioned-dotnet-tests/TestSolutionBuilder.cs index 207f421..ebe714a 100644 --- a/detect-nuget-inspector/detect-nuget-inspector-tests/versioned-dotnet-tests/TestSolutionBuilder.cs +++ b/detect-nuget-inspector/detect-nuget-inspector-tests/versioned-dotnet-tests/TestSolutionBuilder.cs @@ -33,6 +33,29 @@ public TestSolutionBuilder CreateSolution(string solutionName) } } + + public TestSolutionBuilder CreateNestedSolution(string parentDirectory, string solutionName) + { + try + { + var nestedSolutionDir = Path.Combine(parentDirectory, solutionName); + Directory.CreateDirectory(nestedSolutionDir); + + RunDotNetCommand($"new sln -n {solutionName}", nestedSolutionDir); + + // Optionally update _solutionDirectory/_solutionName if you want to work with this nested solution next + _solutionDirectory = nestedSolutionDir; + _solutionName = solutionName; + + return this; + } + catch (Exception ex) + { + Console.WriteLine($"✗ Nested solution creation failed: {ex.Message}"); + _environment.Cleanup(); + throw; + } + } public TestSolutionBuilder CreateAndAddProject(string projectName) { @@ -40,8 +63,8 @@ public TestSolutionBuilder CreateAndAddProject(string projectName) // Create a minimal project with a class RunDotNetCommand($"new classlib -n {projectName}", _solutionDirectory); - // Add ProjectA to solution - RunDotNetCommand("sln add ProjectA/ProjectA.csproj", _solutionDirectory); + // Add project to solution + RunDotNetCommand($"sln add {projectName}/{projectName}.csproj", _solutionDirectory); return this; } catch (Exception ex) { @@ -85,7 +108,7 @@ public TestSolutionBuilder AddPackageReferenceToCsprojManually(string projectNam return this; } - public TestSolutionBuilder NoBuildArtifacts() + public TestSolutionBuilder RemoveBuildArtifacts() { try { @@ -109,41 +132,71 @@ public TestSolutionBuilder NoBuildArtifacts() public TestSolutionBuilder EnableCentralPackageManagementWithDesiredStructure() { + // This method creates a CPM enabled project with the following structure: + // (root) + // ├─Directory.Packages.props (13.0.3) + // | + // ├─Solution1 + // | ├─Directory.Packages.props (12.0.3) + // | | + // | └─ProjectA + // | └─ProjectA.csproj + // | + // └─Solution2 + // └─ProjectB + // └─ProjectB.csproj + // 1. Create Directory.Packages.props at solution root directory - // Create Directory.Packages.props manually for .NET 7 - var propsPath = Path.Combine(_solutionDirectory, "Directory.Packages.props"); + // Each time we create a new solution, the builder switches context to that solution. So here we will keep + // track of our root solution: + var rootSolutionDir = _solutionDirectory; + var rootSolutionName = _solutionName; + CreateBlankDirectoryPackagesPropsFile(_solutionDirectory); + AddCentrallyManagedPackageToPropsFile("Newtonsoft.Json", "13.0.3"); + + // 2. Create Solution1 + CreateNestedSolution(rootSolutionDir, "Solution1"); + var nestedSolution1Dir = _solutionDirectory; + var nestedSolution1Name = _solutionName; + // 2a. Inside Solution1, create its own Directory.Packages.props + CreateBlankDirectoryPackagesPropsFile(_solutionDirectory); + AddCentrallyManagedPackageToPropsFile("Newtonsoft.Json", "12.0.3"); + // 2b. Inside Solution1, create ProjectA + CreateAndAddProject("ProjectA"); + EnableCentralPackageManagementForProject("ProjectA"); + AddCentrallyManagedPackageReferenceToProject("ProjectA", "Newtonsoft.Json"); + + // 3. Create Solution2 + CreateNestedSolution(rootSolutionDir, "Solution2"); + var nestedSolution2Dir = _solutionDirectory; + var nestedSolution2Name = _solutionName; + // 3a. Inside Solution2, create ProjectB + CreateAndAddProject("ProjectB"); + EnableCentralPackageManagementForProject("ProjectB"); + AddCentrallyManagedPackageReferenceToProject("ProjectB", "Newtonsoft.Json"); + + // Switch context back to root solution + _solutionDirectory = rootSolutionDir; + _solutionName = rootSolutionName; + + return this; + } + + public TestSolutionBuilder CreateBlankDirectoryPackagesPropsFile(string directory) + { + // Create Directory.Packages.props manually + var propsPath = Path.Combine(directory, "Directory.Packages.props"); var propsContent = @" "; File.WriteAllText(propsPath, propsContent); - - // 2. For each project, add true - var projectDirs = Directory.GetDirectories(_solutionDirectory) - .Where(d => File.Exists(Path.Combine(d, $"{Path.GetFileName(d)}.csproj"))); - foreach (var projectDir in projectDirs) - { - var projectName = Path.GetFileName(projectDir); - var csprojPath = Path.Combine(projectDir, $"{projectName}.csproj"); - var csprojXml = System.Xml.Linq.XDocument.Load(csprojPath); - var propertyGroup = csprojXml.Root.Elements("PropertyGroup").FirstOrDefault(); - if (propertyGroup == null) - { - propertyGroup = new System.Xml.Linq.XElement("PropertyGroup"); - csprojXml.Root.AddFirst(propertyGroup); - } - propertyGroup.Add(new System.Xml.Linq.XElement("ManagePackageVersionsCentrally", "true")); - csprojXml.Save(csprojPath); - } - - // Optionally, update Directory.Packages.props manually here if needed - return this; } - public TestSolutionBuilder AddCentrallyManagedPackage(string packageName, string version) - { // TODO handle error where Directory.Packages.props does not exist + public TestSolutionBuilder AddCentrallyManagedPackageToPropsFile(string packageName, string version) + { var propsPath = Path.Combine(_solutionDirectory, "Directory.Packages.props"); var propsXml = System.Xml.Linq.XDocument.Load(propsPath); var itemGroup = propsXml.Root.Elements("ItemGroup").FirstOrDefault(); @@ -158,8 +211,59 @@ public TestSolutionBuilder AddCentrallyManagedPackage(string packageName, string propsXml.Save(propsPath); return this; } + + public TestSolutionBuilder AddCentrallyManagedPackageReferenceToProject(string projectName, string packageName) + { + var projectDir = Path.Combine(_solutionDirectory, projectName); + var csprojPath = Path.Combine(projectDir, $"{projectName}.csproj"); + var csprojContent = File.ReadAllText(csprojPath); + var packageReference = $" "; + + if (csprojContent.Contains("")) + { + // So we can reuse this method for a test tht adds more than one dependency + csprojContent = csprojContent.Replace("", $"{packageReference}\n "); + } + else + { + // Add a new ItemGroup before + csprojContent = csprojContent.Replace("", $" \n{packageReference}\n \n"); + } + + File.WriteAllText(csprojPath, csprojContent); + + return this; + } + + public TestSolutionBuilder EnableCentralPackageManagementForProject(string projectName) + { + var projectDir = Path.Combine(_solutionDirectory, projectName); + var csprojPath = Path.Combine(projectDir, $"{projectName}.csproj"); + var csprojContent = File.ReadAllText(csprojPath); + var propertyToAdd = " true\n"; + if (csprojContent.Contains("")) + { + csprojContent = csprojContent.Replace( + "", + "\n" + propertyToAdd + ); + } + else + { + // If no PropertyGroup exists, add one at the top after + var projectTagEnd = csprojContent.IndexOf('>') + 1; + csprojContent = csprojContent.Insert( + projectTagEnd, + "\n \n" + propertyToAdd + " \n" + ); + } + File.WriteAllText(csprojPath, csprojContent); + return this; + } + + private void RunDotNetCommand(string arguments, string workingDirectory) { var command = $"{_environment.DotNetCommand} {arguments}"; diff --git a/detect-nuget-inspector/detect-nuget-inspector-tests/versioned-dotnet-tests/TestsWithMsBuildRegistrationDotnet8.cs b/detect-nuget-inspector/detect-nuget-inspector-tests/versioned-dotnet-tests/TestsWithMsBuildRegistrationDotnet8.cs index 25b71e0..3cbd756 100644 --- a/detect-nuget-inspector/detect-nuget-inspector-tests/versioned-dotnet-tests/TestsWithMsBuildRegistrationDotnet8.cs +++ b/detect-nuget-inspector/detect-nuget-inspector-tests/versioned-dotnet-tests/TestsWithMsBuildRegistrationDotnet8.cs @@ -20,7 +20,7 @@ public void TestBasicSolution_DotNet8_DuplicatePackageReference_ProjectReference // Add them manually because dotnet8 doesn't allow adding duplicate PackageReference via CLI .AddPackageReferenceToCsprojManually("ProjectA", "Newtonsoft.Json", "13.0.3") .AddPackageReferenceToCsprojManually("ProjectA", "Newtonsoft.Json", "12.0.1") - .NoBuildArtifacts() // So we can force using ProjectReferenceResolver instead of assets file + .RemoveBuildArtifacts() // So we can force using ProjectReferenceResolver instead of assets file .Build(); From c1aa24a9a8a473a77480d2f9c51ed74e56ec1b39 Mon Sep 17 00:00:00 2001 From: shantyk Date: Tue, 14 Oct 2025 07:43:12 -0600 Subject: [PATCH 27/34] Working tests --- .../TestSolutionBuilder.cs | 37 +++---------------- 1 file changed, 5 insertions(+), 32 deletions(-) diff --git a/detect-nuget-inspector/detect-nuget-inspector-tests/versioned-dotnet-tests/TestSolutionBuilder.cs b/detect-nuget-inspector/detect-nuget-inspector-tests/versioned-dotnet-tests/TestSolutionBuilder.cs index ebe714a..e16d076 100644 --- a/detect-nuget-inspector/detect-nuget-inspector-tests/versioned-dotnet-tests/TestSolutionBuilder.cs +++ b/detect-nuget-inspector/detect-nuget-inspector-tests/versioned-dotnet-tests/TestSolutionBuilder.cs @@ -133,51 +133,24 @@ public TestSolutionBuilder RemoveBuildArtifacts() public TestSolutionBuilder EnableCentralPackageManagementWithDesiredStructure() { // This method creates a CPM enabled project with the following structure: - // (root) - // ├─Directory.Packages.props (13.0.3) - // | // ├─Solution1 // | ├─Directory.Packages.props (12.0.3) // | | // | └─ProjectA - // | └─ProjectA.csproj - // | - // └─Solution2 + // | └─ProjectA.csproj (CPM enabled) // └─ProjectB - // └─ProjectB.csproj + // └─ProjectB.csproj (CPM not enabled, direct reference to version 13.0.3) // 1. Create Directory.Packages.props at solution root directory - // Each time we create a new solution, the builder switches context to that solution. So here we will keep - // track of our root solution: - var rootSolutionDir = _solutionDirectory; - var rootSolutionName = _solutionName; - CreateBlankDirectoryPackagesPropsFile(_solutionDirectory); - AddCentrallyManagedPackageToPropsFile("Newtonsoft.Json", "13.0.3"); - - // 2. Create Solution1 - CreateNestedSolution(rootSolutionDir, "Solution1"); - var nestedSolution1Dir = _solutionDirectory; - var nestedSolution1Name = _solutionName; - // 2a. Inside Solution1, create its own Directory.Packages.props CreateBlankDirectoryPackagesPropsFile(_solutionDirectory); AddCentrallyManagedPackageToPropsFile("Newtonsoft.Json", "12.0.3"); - // 2b. Inside Solution1, create ProjectA + // 2b. Create ProjectA CreateAndAddProject("ProjectA"); EnableCentralPackageManagementForProject("ProjectA"); AddCentrallyManagedPackageReferenceToProject("ProjectA", "Newtonsoft.Json"); - - // 3. Create Solution2 - CreateNestedSolution(rootSolutionDir, "Solution2"); - var nestedSolution2Dir = _solutionDirectory; - var nestedSolution2Name = _solutionName; - // 3a. Inside Solution2, create ProjectB + CreateAndAddProject("ProjectB"); - EnableCentralPackageManagementForProject("ProjectB"); - AddCentrallyManagedPackageReferenceToProject("ProjectB", "Newtonsoft.Json"); - - // Switch context back to root solution - _solutionDirectory = rootSolutionDir; - _solutionName = rootSolutionName; + AddDependencyToProject("ProjectB", "Newtonsoft.Json", "13.0.3"); return this; } From e9fee6aa661343f719207920d9446de86dcb8ab7 Mon Sep 17 00:00:00 2001 From: shantyk Date: Tue, 14 Oct 2025 07:43:39 -0600 Subject: [PATCH 28/34] Working tests --- .../versioned-dotnet-tests/KickOffTests.cs | 37 ++++++++++++++++--- .../TestSolutionBuilder.cs | 6 +-- 2 files changed, 33 insertions(+), 10 deletions(-) diff --git a/detect-nuget-inspector/detect-nuget-inspector-tests/versioned-dotnet-tests/KickOffTests.cs b/detect-nuget-inspector/detect-nuget-inspector-tests/versioned-dotnet-tests/KickOffTests.cs index 1ed6034..fa9166d 100644 --- a/detect-nuget-inspector/detect-nuget-inspector-tests/versioned-dotnet-tests/KickOffTests.cs +++ b/detect-nuget-inspector/detect-nuget-inspector-tests/versioned-dotnet-tests/KickOffTests.cs @@ -195,7 +195,7 @@ public void TestSolution_DotNet6_DuplicatePackageReference_XMLResolver() } [TestMethod] - public void TestCPMSolution_DotNet7() + public void TestCPMSolution_DotNet7_ProjectAssetsJsonFile() { // 1. Set up environment with .NET 7 (nuget v6.7.1.1) var dotnetVersion = "7.0.410"; @@ -208,6 +208,11 @@ public void TestCPMSolution_DotNet7() .Build(); // 3. Run inspector + // Redirect console output for assertions later + var stringWriter = new StringWriter(); + var originalOut = Console.Out; + Console.SetOut(stringWriter); + var options = new InspectionOptions { TargetPath = builder, @@ -219,14 +224,36 @@ public void TestCPMSolution_DotNet7() try { - // run dotnet7 restore - // run dotnet7 list package - // pause here ans ask me what to do with the output. var inspection = InspectorExecutor.ExecuteInspectors(options); // 4. Assert results Assert.IsTrue(inspection.Success); - // ... further assertions for CPM dependencies ... + var inspectionResults = inspection.Results; + Assert.IsNotNull(inspectionResults); + Assert.AreEqual(1, inspectionResults.Count); + var result = inspectionResults[0]; + Assert.AreEqual(InspectionResult.ResultStatus.Success, result.Status); + Assert.IsNotNull(result.Containers); + Assert.AreEqual(1, result.Containers.Count); + var solutionContainer = result.Containers[0]; + Assert.AreEqual(solutionContainer.Type, "Solution"); + Assert.AreEqual("MyCPMDotnet7Solution", solutionContainer.Name); + + var projectContainer = solutionContainer.Children[0]; + Assert.AreEqual(projectContainer.Type, "Project"); + Assert.AreEqual("ProjectA", projectContainer.Name); + + Assert.IsNotNull(projectContainer.Dependencies); + var dependencies = projectContainer.Dependencies; + Assert.AreEqual(1, dependencies.Count); + var dependency = dependencies.Single(); + Assert.AreEqual("Newtonsoft.Json", dependency.Name); + Assert.AreEqual("12.0.3", dependency.Version); + + // Assert console output + string output = stringWriter.ToString(); + Assert.IsTrue(output.Contains("Using assets json file:")); + originalOut.Write(stringWriter.ToString()); } catch { diff --git a/detect-nuget-inspector/detect-nuget-inspector-tests/versioned-dotnet-tests/TestSolutionBuilder.cs b/detect-nuget-inspector/detect-nuget-inspector-tests/versioned-dotnet-tests/TestSolutionBuilder.cs index e16d076..bfb1477 100644 --- a/detect-nuget-inspector/detect-nuget-inspector-tests/versioned-dotnet-tests/TestSolutionBuilder.cs +++ b/detect-nuget-inspector/detect-nuget-inspector-tests/versioned-dotnet-tests/TestSolutionBuilder.cs @@ -138,8 +138,7 @@ public TestSolutionBuilder EnableCentralPackageManagementWithDesiredStructure() // | | // | └─ProjectA // | └─ProjectA.csproj (CPM enabled) - // └─ProjectB - // └─ProjectB.csproj (CPM not enabled, direct reference to version 13.0.3) + // 1. Create Directory.Packages.props at solution root directory CreateBlankDirectoryPackagesPropsFile(_solutionDirectory); @@ -148,9 +147,6 @@ public TestSolutionBuilder EnableCentralPackageManagementWithDesiredStructure() CreateAndAddProject("ProjectA"); EnableCentralPackageManagementForProject("ProjectA"); AddCentrallyManagedPackageReferenceToProject("ProjectA", "Newtonsoft.Json"); - - CreateAndAddProject("ProjectB"); - AddDependencyToProject("ProjectB", "Newtonsoft.Json", "13.0.3"); return this; } From e5bd3cc5c1a6ece0e6ea8d22d66fbc12aa759ee5 Mon Sep 17 00:00:00 2001 From: shantyk Date: Tue, 14 Oct 2025 07:45:41 -0600 Subject: [PATCH 29/34] Clean up comments --- .../versioned-dotnet-tests/KickOffTests.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/detect-nuget-inspector/detect-nuget-inspector-tests/versioned-dotnet-tests/KickOffTests.cs b/detect-nuget-inspector/detect-nuget-inspector-tests/versioned-dotnet-tests/KickOffTests.cs index fa9166d..23cf486 100644 --- a/detect-nuget-inspector/detect-nuget-inspector-tests/versioned-dotnet-tests/KickOffTests.cs +++ b/detect-nuget-inspector/detect-nuget-inspector-tests/versioned-dotnet-tests/KickOffTests.cs @@ -268,7 +268,7 @@ public void TestCPMSolution_DotNet7_ProjectAssetsJsonFile() [TestMethod] - public void TestSolution_DotNet8() // TODO: This test and TestSolution_DotNet6_DuplicatePackageReference_XMLResolver are duplicates, parameterize them + public void TestSolution_DotNet8() { // 1. Set up environment with .NET 8 (nuget v6.11.1.2) var dotnetVersion = "8.0.414"; From c9097791a101590dbbebd64c45cb2f2e17821cbd Mon Sep 17 00:00:00 2001 From: shantyk Date: Tue, 14 Oct 2025 08:04:40 -0600 Subject: [PATCH 30/34] Remove attempt at isolating tests --- detect-nuget-inspector-tests/Isolated.runsettings | 13 ------------- .../versioned-dotnet-tests/TestSolutionBuilder.cs | 2 ++ 2 files changed, 2 insertions(+), 13 deletions(-) delete mode 100644 detect-nuget-inspector-tests/Isolated.runsettings diff --git a/detect-nuget-inspector-tests/Isolated.runsettings b/detect-nuget-inspector-tests/Isolated.runsettings deleted file mode 100644 index 6663f2a..0000000 --- a/detect-nuget-inspector-tests/Isolated.runsettings +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - true - - - - - - diff --git a/detect-nuget-inspector/detect-nuget-inspector-tests/versioned-dotnet-tests/TestSolutionBuilder.cs b/detect-nuget-inspector/detect-nuget-inspector-tests/versioned-dotnet-tests/TestSolutionBuilder.cs index bfb1477..026bd19 100644 --- a/detect-nuget-inspector/detect-nuget-inspector-tests/versioned-dotnet-tests/TestSolutionBuilder.cs +++ b/detect-nuget-inspector/detect-nuget-inspector-tests/versioned-dotnet-tests/TestSolutionBuilder.cs @@ -147,6 +147,8 @@ public TestSolutionBuilder EnableCentralPackageManagementWithDesiredStructure() CreateAndAddProject("ProjectA"); EnableCentralPackageManagementForProject("ProjectA"); AddCentrallyManagedPackageReferenceToProject("ProjectA", "Newtonsoft.Json"); + + RunDotNetCommand("restore", _solutionDirectory); return this; } From 16832d5aa43a96875814fa52593af8e99fa00714 Mon Sep 17 00:00:00 2001 From: shantyk Date: Wed, 15 Oct 2025 09:09:25 -0600 Subject: [PATCH 31/34] Add script --- .../set-up-versioned-dotnet-tests-env.sh | 45 +++++++++++++++++++ .../versioned-dotnet-tests/KickOffTests.cs | 15 ++++--- .../TestEnvironmentManager.cs | 2 +- 3 files changed, 54 insertions(+), 8 deletions(-) create mode 100644 detect-nuget-inspector/detect-nuget-inspector-tests/set-up-versioned-dotnet-tests-env.sh diff --git a/detect-nuget-inspector/detect-nuget-inspector-tests/set-up-versioned-dotnet-tests-env.sh b/detect-nuget-inspector/detect-nuget-inspector-tests/set-up-versioned-dotnet-tests-env.sh new file mode 100644 index 0000000..e741ea0 --- /dev/null +++ b/detect-nuget-inspector/detect-nuget-inspector-tests/set-up-versioned-dotnet-tests-env.sh @@ -0,0 +1,45 @@ +#!/bin/bash + +set -e + +DOTNET6_URL="https://download.visualstudio.microsoft.com/download/pr/2e2e2e2e-2e2e-2e2e-2e2e-2e2e2e2e2e2e/abcdef1234567890abcdef1234567890/dotnet-sdk-6.0.420-osx-arm64.tar.gz" +DOTNET7_URL="https://download.visualstudio.microsoft.com/download/pr/3f3f3f3f-3f3f-3f3f-3f3f-3f3f3f3f3f3f/abcdef1234567890abcdef1234567890/dotnet-sdk-7.0.408-osx-arm64.tar.gz" +DOTNET8_URL="https://download.visualstudio.microsoft.com/download/pr/4a4a4a4a-4a4a-4a4a-4a4a-4a4a4a4a4a4a/abcdef1234567890abcdef1234567890/dotnet-sdk-8.0.204-osx-arm64.tar.gz" + +install_dotnet() { + VERSION=$1 + URL=$2 + DEST="$HOME/.dotnet$VERSION" + BIN="/usr/local/bin/dotnet$VERSION" + + echo "Downloading .NET $VERSION..." + rm -rf "$DEST" + mkdir -p "$DEST" + if curl -L "$URL" | tar -xz -C "$DEST"; then + echo "Downloaded and extracted .NET $VERSION." + else + echo "Failed to download or extract .NET $VERSION." + exit 1 + fi + + echo "Setting up symlink for dotnet$VERSION..." + if sudo rm -f "$BIN" && sudo ln -s "$DEST/dotnet" "$BIN"; then + echo "Symlink for dotnet$VERSION set up." + else + echo "Failed to set up symlink for dotnet$VERSION." + exit 1 + fi + + if "$BIN" --version; then + echo ".NET $VERSION installed successfully." + else + echo "Failed to verify .NET $VERSION installation." + exit 1 + fi +} + +install_dotnet 6 "$DOTNET6_URL" +install_dotnet 7 "$DOTNET7_URL" +install_dotnet 8 "$DOTNET8_URL" + +echo "All .NET SDKs installed and symlinked as dotnet6, dotnet7, dotnet8." diff --git a/detect-nuget-inspector/detect-nuget-inspector-tests/versioned-dotnet-tests/KickOffTests.cs b/detect-nuget-inspector/detect-nuget-inspector-tests/versioned-dotnet-tests/KickOffTests.cs index 23cf486..32288da 100644 --- a/detect-nuget-inspector/detect-nuget-inspector-tests/versioned-dotnet-tests/KickOffTests.cs +++ b/detect-nuget-inspector/detect-nuget-inspector-tests/versioned-dotnet-tests/KickOffTests.cs @@ -2,6 +2,7 @@ namespace detect_nuget_inspector_tests.versioned_dotnet_tests { + // To set up your environment for these tests, see set-up-versioned-dotnet-tests-env.sh [TestClass] public class KickOffTests { @@ -262,6 +263,7 @@ public void TestCPMSolution_DotNet7_ProjectAssetsJsonFile() } finally { + Console.SetOut(originalOut); env.Cleanup(); } } @@ -279,8 +281,7 @@ public void TestSolution_DotNet8() .CreateSolution("MySimpleDotnet8Solution") .CreateAndAddProject("ProjectA") // Add them manually because dotnet8 doesn't allow adding duplicate PackageReference via CLI - .AddPackageReferenceToCsprojManually("ProjectA", "Newtonsoft.Json", "13.0.3") - .AddPackageReferenceToCsprojManually("ProjectA", "Newtonsoft.Json", "12.0.1") + .AddDependencyToProject("ProjectA", "Newtonsoft.Json", "13.0.3") .RemoveBuildArtifacts() // So we can force using ProjectReferenceResolver instead of assets file .Build(); @@ -323,14 +324,14 @@ public void TestSolution_DotNet8() Assert.IsNotNull(projectContainer.Dependencies); var dependencies = projectContainer.Dependencies; - Assert.AreEqual(2, dependencies.Count); - // Confirm duplicates are captured - Assert.IsTrue(dependencies.Any(d => d.Name == "Newtonsoft.Json" && d.Version == "13.0.3")); - Assert.IsTrue(dependencies.Any(d => d.Name == "Newtonsoft.Json" && d.Version == "12.0.1")); + Assert.AreEqual(1, dependencies.Count); + var dependency = dependencies.Single(); + Assert.AreEqual("Newtonsoft.Json", dependency.Name); + Assert.AreEqual("13.0.3", dependency.Version); // Assert console output string output = stringWriter.ToString(); - Assert.IsTrue(output.Contains("Reference resolver succeeded.")); + Assert.IsTrue(output.Contains("Using backup XML resolver.")); originalOut.Write(stringWriter.ToString()); } catch diff --git a/detect-nuget-inspector/detect-nuget-inspector-tests/versioned-dotnet-tests/TestEnvironmentManager.cs b/detect-nuget-inspector/detect-nuget-inspector-tests/versioned-dotnet-tests/TestEnvironmentManager.cs index 1c2351f..5ac942d 100644 --- a/detect-nuget-inspector/detect-nuget-inspector-tests/versioned-dotnet-tests/TestEnvironmentManager.cs +++ b/detect-nuget-inspector/detect-nuget-inspector-tests/versioned-dotnet-tests/TestEnvironmentManager.cs @@ -69,7 +69,7 @@ private void ValidateAndLogVersions(string expectedVersion, string command) Console.WriteLine("✓ Environment validation complete"); } - private (int ExitCode, string Output, string Error) RunCommand(string command, string arguments) // TODO only need one dotnet command runner + private (int ExitCode, string Output, string Error) RunCommand(string command, string arguments) { try { From 2d8767c50b089737a210dbad9afb0ec3b004d981 Mon Sep 17 00:00:00 2001 From: shantyk Date: Wed, 15 Oct 2025 09:10:20 -0600 Subject: [PATCH 32/34] Rename test --- .../versioned-dotnet-tests/KickOffTests.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/detect-nuget-inspector/detect-nuget-inspector-tests/versioned-dotnet-tests/KickOffTests.cs b/detect-nuget-inspector/detect-nuget-inspector-tests/versioned-dotnet-tests/KickOffTests.cs index 32288da..72b1c07 100644 --- a/detect-nuget-inspector/detect-nuget-inspector-tests/versioned-dotnet-tests/KickOffTests.cs +++ b/detect-nuget-inspector/detect-nuget-inspector-tests/versioned-dotnet-tests/KickOffTests.cs @@ -270,7 +270,7 @@ public void TestCPMSolution_DotNet7_ProjectAssetsJsonFile() [TestMethod] - public void TestSolution_DotNet8() + public void TestSolution_DotNet8_XMLResolver() { // 1. Set up environment with .NET 8 (nuget v6.11.1.2) var dotnetVersion = "8.0.414"; From 7f64208be9ec384840351a169dc77852407f86d2 Mon Sep 17 00:00:00 2001 From: shantyk Date: Wed, 15 Oct 2025 09:37:55 -0600 Subject: [PATCH 33/34] Add log that will be useful when testing --- detect-nuget-inspector/detect-nuget-inspector/Program.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/detect-nuget-inspector/detect-nuget-inspector/Program.cs b/detect-nuget-inspector/detect-nuget-inspector/Program.cs index f549a6e..7978da3 100644 --- a/detect-nuget-inspector/detect-nuget-inspector/Program.cs +++ b/detect-nuget-inspector/detect-nuget-inspector/Program.cs @@ -10,7 +10,8 @@ public static void Main(string[] args) try { Console.WriteLine("Registering MSBuild defaults."); - MSBuildLocator.RegisterDefaults(); + VisualStudioInstance registeredInstance = MSBuildLocator.RegisterDefaults(); + Console.WriteLine("MSBuild registered: " + registeredInstance.MSBuildPath + " (Version: " + registeredInstance.Version + ")"); } catch (Exception e) { From 2ea9ccc4032997e73bfbb9134b01542aafea82fd Mon Sep 17 00:00:00 2001 From: shantyk Date: Wed, 15 Oct 2025 09:49:46 -0600 Subject: [PATCH 34/34] correct urLs in download script --- .../set-up-versioned-dotnet-tests-env.sh | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/detect-nuget-inspector/detect-nuget-inspector-tests/set-up-versioned-dotnet-tests-env.sh b/detect-nuget-inspector/detect-nuget-inspector-tests/set-up-versioned-dotnet-tests-env.sh index e741ea0..9df7449 100644 --- a/detect-nuget-inspector/detect-nuget-inspector-tests/set-up-versioned-dotnet-tests-env.sh +++ b/detect-nuget-inspector/detect-nuget-inspector-tests/set-up-versioned-dotnet-tests-env.sh @@ -1,10 +1,11 @@ #!/bin/bash set -e - -DOTNET6_URL="https://download.visualstudio.microsoft.com/download/pr/2e2e2e2e-2e2e-2e2e-2e2e-2e2e2e2e2e2e/abcdef1234567890abcdef1234567890/dotnet-sdk-6.0.420-osx-arm64.tar.gz" -DOTNET7_URL="https://download.visualstudio.microsoft.com/download/pr/3f3f3f3f-3f3f-3f3f-3f3f-3f3f3f3f3f3f/abcdef1234567890abcdef1234567890/dotnet-sdk-7.0.408-osx-arm64.tar.gz" -DOTNET8_URL="https://download.visualstudio.microsoft.com/download/pr/4a4a4a4a-4a4a-4a4a-4a4a-4a4a4a4a4a4a/abcdef1234567890abcdef1234567890/dotnet-sdk-8.0.204-osx-arm64.tar.gz" +# Your version of the following may differ in minor version numbers. The test are written to align with the Jenkins +# build machine (ubuntu 20.04 at time of writing. Adjust as needed. +DOTNET6_URL="https://builds.dotnet.microsoft.com/dotnet/Sdk/6.0.428/dotnet-sdk-6.0.428-osx-arm64.pkg" +DOTNET7_URL="https://builds.dotnet.microsoft.com/dotnet/Sdk/7.0.410/dotnet-sdk-7.0.410-osx-arm64.pkg" +DOTNET8_URL="https://builds.dotnet.microsoft.com/dotnet/Sdk/8.0.121/dotnet-sdk-8.0.121-osx-arm64.pkg" install_dotnet() { VERSION=$1