From 6ec84e4444f496e6db7cbc65187336a039b8ec75 Mon Sep 17 00:00:00 2001 From: stan-sz <37585349+stan-sz@users.noreply.github.com> Date: Thu, 2 Oct 2025 08:34:47 +0200 Subject: [PATCH 1/4] MSTest upgrade https://github.com/microsoft/testfx/releases/tag/v3.11.0 --- global.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/global.json b/global.json index 9825ffb..04e8d4a 100644 --- a/global.json +++ b/global.json @@ -1,6 +1,6 @@ { "msbuild-sdks": { "Microsoft.Build.NoTargets": "3.7.56", - "MSTest.Sdk": "3.6.0" + "MSTest.Sdk": "3.11.0" } -} \ No newline at end of file +} From 012aa578eaa45ec845609f278d7e8adccfbc0e28 Mon Sep 17 00:00:00 2001 From: stan-sz <37585349+stan-sz@users.noreply.github.com> Date: Tue, 18 Nov 2025 14:12:02 +0100 Subject: [PATCH 2/4] Update global.json --- global.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/global.json b/global.json index 04e8d4a..68dda42 100644 --- a/global.json +++ b/global.json @@ -1,6 +1,6 @@ { "msbuild-sdks": { "Microsoft.Build.NoTargets": "3.7.56", - "MSTest.Sdk": "3.11.0" + "MSTest.Sdk": "3.11.1" } } From eb8a26296b0b7b77f96541b3fc3c4075b86c4372 Mon Sep 17 00:00:00 2001 From: Stanislaw Szczepanowski <37585349+stan-sz@users.noreply.github.com> Date: Thu, 27 Nov 2025 09:49:46 +0100 Subject: [PATCH 3/4] Fix --- .github/workflows/ci.yml | 2 +- .github/workflows/pr.yml | 2 +- global.json | 3 +++ 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 89c2de7..55b0831 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -31,7 +31,7 @@ jobs: run: dotnet build --configuration Release --no-restore -bl:logs/build.binlog - name: Test - run: dotnet test --configuration Release --no-build --logger trx --results-directory TestResults --collect:"Code Coverage;Format=Cobertura" + run: dotnet test --configuration Release --no-build --report-trx --results-directory TestResults --coverage # - name: Upload coverage to Codecov # uses: codecov/codecov-action@v4 diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml index 47b84c7..cf765fd 100644 --- a/.github/workflows/pr.yml +++ b/.github/workflows/pr.yml @@ -29,7 +29,7 @@ jobs: run: dotnet build --configuration Release --no-restore -bl:logs/build.binlog - name: Test - run: dotnet test --configuration Release --no-build --logger trx --results-directory TestResults --collect:"Code Coverage;Format=Cobertura" + run: dotnet test --configuration Release --no-build --report-trx --results-directory TestResults --coverage # - name: Upload coverage to Codecov # uses: codecov/codecov-action@v4 diff --git a/global.json b/global.json index 68dda42..3f7f4c9 100644 --- a/global.json +++ b/global.json @@ -2,5 +2,8 @@ "msbuild-sdks": { "Microsoft.Build.NoTargets": "3.7.56", "MSTest.Sdk": "3.11.1" + }, + "test": { + "runner": "Microsoft.Testing.Platform" } } From ca75f7c0f70db9e61dd62be69e1b9435c2f8b012 Mon Sep 17 00:00:00 2001 From: Stanislaw Szczepanowski <37585349+stan-sz@users.noreply.github.com> Date: Fri, 28 Nov 2025 08:03:54 +0100 Subject: [PATCH 4/4] API fixes --- src/Tests/E2ETests.cs | 46 +++++++----------------------------- src/Tests/MsvcLoggerTests.cs | 44 +++++++++++++++++----------------- 2 files changed, 31 insertions(+), 59 deletions(-) diff --git a/src/Tests/E2ETests.cs b/src/Tests/E2ETests.cs index 4f66a2b..63a3124 100644 --- a/src/Tests/E2ETests.cs +++ b/src/Tests/E2ETests.cs @@ -3,6 +3,8 @@ using System.Text.RegularExpressions; using ReferenceTrimmer.Loggers.MSVC; +[assembly: Parallelize(Workers = 1, Scope = ExecutionScope.MethodLevel)] + namespace ReferenceTrimmer.Tests; [TestClass] @@ -257,14 +259,9 @@ await RunMSBuildAsync( } [TestMethod] + [OSCondition(OperatingSystems.Windows, IgnoreMessage = "The GAC is Windows-specific")] public async Task UnusedReferenceFromGac() { - // The GAC is Windows-specific - if (!OperatingSystem.IsWindows()) - { - Assert.Inconclusive(); - } - await RunMSBuildAsync( projectFile: "Library.csproj", expectedWarnings: new[] @@ -274,14 +271,9 @@ await RunMSBuildAsync( } [TestMethod] + [OSCondition(OperatingSystems.Windows, IgnoreMessage = "The GAC is Windows-specific")] public async Task UsedReferenceFromGac() { - // The GAC is Windows-specific - if (!OperatingSystem.IsWindows()) - { - Assert.Inconclusive(); - } - await RunMSBuildAsync( projectFile: "Library.csproj", expectedWarnings: []); @@ -418,28 +410,18 @@ public Task ReferenceTrimmerDisabled() } [TestMethod] + [OSCondition(OperatingSystems.Windows, IgnoreMessage = "This test only applies to Windows")] public async Task LegacyStyleProject() { - if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) - { - Assert.Inconclusive("This test only applies to Windows"); - return; - } - await RunMSBuildAsync( projectFile: "Library/Library.csproj", expectedWarnings: []); } [TestMethod] + [OSCondition(OperatingSystems.Windows, IgnoreMessage = "This test only applies to Windows")] public async Task UnusedWinSdkImportLibrary() { - if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) - { - Assert.Inconclusive("This test only applies to Windows"); - return; - } - await RunMSBuildAsync( projectFile: "App/App.vcxproj", expectedWarnings: [], @@ -456,14 +438,9 @@ await RunMSBuildAsync( } [TestMethod] + [OSCondition(OperatingSystems.Windows, IgnoreMessage = "This test only applies to Windows")] public async Task UnusedCppLibrary() { - if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) - { - Assert.Inconclusive("This test only applies to Windows"); - return; - } - await RunMSBuildAsync( projectFile: "App/App.vcxproj", expectedWarnings: [], @@ -478,14 +455,9 @@ await RunMSBuildAsync( } [TestMethod] + [OSCondition(OperatingSystems.Windows, IgnoreMessage = "This test only applies to Windows")] public async Task UnusedCppDelayLoadLibrary() { - if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) - { - Assert.Inconclusive("This test only applies to Windows"); - return; - } - await RunMSBuildAsync( projectFile: "App/App.vcxproj", expectedWarnings: [], @@ -600,7 +572,7 @@ private async Task RunMSBuildAsync(string projectFile, Warning[] expectedWarning Assert.AreEqual(File.Exists(unusedLibraryLogPath), expectUnusedMsvcLibrariesLog); string errors = await File.ReadAllTextAsync(errorsFilePath); - Assert.IsTrue(errors.Length == 0, $"Build of {projectFile} was not successful.{Environment.NewLine}Error log: {errors}"); + Assert.AreEqual(0, errors.Length, $"Build of {projectFile} was not successful.{Environment.NewLine}Error log: {errors}"); List actualWarnings = new(); foreach (string line in await File.ReadAllLinesAsync(warningsFilePath)) diff --git a/src/Tests/MsvcLoggerTests.cs b/src/Tests/MsvcLoggerTests.cs index e8ac3fd..4577fc1 100644 --- a/src/Tests/MsvcLoggerTests.cs +++ b/src/Tests/MsvcLoggerTests.cs @@ -100,11 +100,11 @@ public void ForwardingLogger_ForwardsNothingIfLinkTaskNotStarted() { eventSource.AssertExpectedForwardingEventSubscriptions(); eventSource.SendTaskStarted(new TaskStartedEventArgs(message: "Not Link!", helpKeyword: "NotLink", projectFile: "a.proj", taskFile: "a.proj", taskName: "NotLink")); - Assert.AreEqual(0, eventRedirector.Events.Count); + Assert.IsEmpty(eventRedirector.Events); eventSource.SendMessageRaised(new BuildMessageEventArgs(message: "a non-link message", helpKeyword: "NotLink", senderName: "NotLink", MessageImportance.High, DateTime.Now) { ProjectFile = "a.proj" }); - Assert.AreEqual(0, eventRedirector.Events.Count); + Assert.IsEmpty(eventRedirector.Events); eventSource.SendTaskFinished(new TaskFinishedEventArgs(message: "Not Link!", helpKeyword: "NotLink", projectFile: "a.proj", taskFile: "a.proj", taskName: "NotLink", succeeded: true)); - Assert.AreEqual(0, eventRedirector.Events.Count); + Assert.IsEmpty(eventRedirector.Events); } finally { @@ -123,11 +123,11 @@ public void ForwardingLogger_ForwardsNothingIfLinkTaskGetsNoUnusedLibMessages() { eventSource.AssertExpectedForwardingEventSubscriptions(); eventSource.SendTaskStarted(new TaskStartedEventArgs(message: "Link starting", helpKeyword: "Link", projectFile: "a.proj", taskFile: "a.proj", taskName: "Link")); - Assert.AreEqual(0, eventRedirector.Events.Count); + Assert.IsEmpty(eventRedirector.Events); eventSource.SendMessageRaised(new BuildMessageEventArgs(message: "Generic link message", helpKeyword: "Link", senderName: "Link", MessageImportance.High, DateTime.Now) { ProjectFile = "a.proj" }); - Assert.AreEqual(0, eventRedirector.Events.Count); + Assert.IsEmpty(eventRedirector.Events); eventSource.SendTaskFinished(new TaskFinishedEventArgs(message: "Link finished", helpKeyword: "Link", projectFile: "a.proj", taskFile: "a.proj", taskName: "Link", succeeded: true)); - Assert.AreEqual(0, eventRedirector.Events.Count); + Assert.IsEmpty(eventRedirector.Events); } finally { @@ -146,11 +146,11 @@ public void ForwardingLogger_ForwardsNothingIfLinkTaskGetsUnusedLibHeaderOnly() { eventSource.AssertExpectedForwardingEventSubscriptions(); eventSource.SendTaskStarted(new TaskStartedEventArgs(message: "Link starting", helpKeyword: "Link", projectFile: "a.proj", taskFile: "a.proj", taskName: "Link")); - Assert.AreEqual(0, eventRedirector.Events.Count); + Assert.IsEmpty(eventRedirector.Events); eventSource.SendMessageRaised(new BuildMessageEventArgs(message: "Unused libraries:", helpKeyword: "Link", senderName: "Link", MessageImportance.High, DateTime.Now) { ProjectFile = "a.proj" }); - Assert.AreEqual(0, eventRedirector.Events.Count); + Assert.IsEmpty(eventRedirector.Events); eventSource.SendTaskFinished(new TaskFinishedEventArgs(message: "Link finished", helpKeyword: "Link", projectFile: "a.proj", taskFile: "a.proj", taskName: "Link", succeeded: true)); - Assert.AreEqual(0, eventRedirector.Events.Count); + Assert.IsEmpty(eventRedirector.Events); } finally { @@ -169,23 +169,23 @@ public void ForwardingLogger_ForwardsUnusedLibs() { eventSource.AssertExpectedForwardingEventSubscriptions(); eventSource.SendTaskStarted(new TaskStartedEventArgs(message: "Link starting", helpKeyword: "Link", projectFile: "a.proj", taskFile: "a.proj", taskName: "Link")); - Assert.AreEqual(0, eventRedirector.Events.Count); + Assert.IsEmpty(eventRedirector.Events); eventSource.SendMessageRaised(new BuildMessageEventArgs(message: "Unused libraries:", helpKeyword: "Link", senderName: "Link", MessageImportance.High, DateTime.Now) { ProjectFile = "a.proj" }); - Assert.AreEqual(0, eventRedirector.Events.Count); + Assert.IsEmpty(eventRedirector.Events); eventSource.SendMessageRaised(new BuildMessageEventArgs(message: " user32.lib", helpKeyword: "Link", senderName: "Link", MessageImportance.High, DateTime.Now) { ProjectFile = "a.proj" }); - Assert.AreEqual(0, eventRedirector.Events.Count); + Assert.IsEmpty(eventRedirector.Events); eventSource.SendMessageRaised(new BuildMessageEventArgs(message: " bar.lib", helpKeyword: "Link", senderName: "Link", MessageImportance.High, DateTime.Now) { ProjectFile = "a.proj" }); - Assert.AreEqual(0, eventRedirector.Events.Count); + Assert.IsEmpty(eventRedirector.Events); eventSource.SendMessageRaised(new BuildMessageEventArgs(message: string.Empty, helpKeyword: "Link", senderName: "Link", MessageImportance.High, DateTime.Now) { ProjectFile = "a.proj" }); - Assert.AreEqual(0, eventRedirector.Events.Count); + Assert.IsEmpty(eventRedirector.Events); eventSource.SendTaskFinished(new TaskFinishedEventArgs(message: "Link finished", helpKeyword: "Link", projectFile: "a.proj", taskFile: "a.proj", taskName: "Link", succeeded: true)); - Assert.AreEqual(1, eventRedirector.Events.Count); + Assert.HasCount(1, eventRedirector.Events); var unusedLibArgs = eventRedirector.Events[0] as UnusedLibsCustomBuildEventArgs; Assert.IsNotNull(unusedLibArgs); Assert.AreEqual("a.proj", unusedLibArgs.ProjectPath); Assert.IsTrue(unusedLibArgs.Message!.Contains("user32.lib", StringComparison.Ordinal), unusedLibArgs.Message); Assert.IsTrue(unusedLibArgs.Message.Contains("bar.lib", StringComparison.Ordinal), unusedLibArgs.Message); - Assert.IsTrue(unusedLibArgs.UnusedLibraryPathsJson.Length > 0); + Assert.IsGreaterThan(0, unusedLibArgs.UnusedLibraryPathsJson.Length); } finally { @@ -204,17 +204,17 @@ public void ForwardingLogger_ForwardsNothingIfLinkTaskFails() { eventSource.AssertExpectedForwardingEventSubscriptions(); eventSource.SendTaskStarted(new TaskStartedEventArgs(message: "Link starting", helpKeyword: "Link", projectFile: "a.proj", taskFile: "a.proj", taskName: "Link")); - Assert.AreEqual(0, eventRedirector.Events.Count); + Assert.IsEmpty(eventRedirector.Events); eventSource.SendMessageRaised(new BuildMessageEventArgs(message: "Unused libraries:", helpKeyword: "Link", senderName: "Link", MessageImportance.High, DateTime.Now) { ProjectFile = "a.proj" }); - Assert.AreEqual(0, eventRedirector.Events.Count); + Assert.IsEmpty(eventRedirector.Events); eventSource.SendMessageRaised(new BuildMessageEventArgs(message: " kernel32.lib", helpKeyword: "Link", senderName: "Link", MessageImportance.High, DateTime.Now) { ProjectFile = "a.proj" }); - Assert.AreEqual(0, eventRedirector.Events.Count); + Assert.IsEmpty(eventRedirector.Events); eventSource.SendMessageRaised(new BuildMessageEventArgs(message: " foo.lib", helpKeyword: "Link", senderName: "Link", MessageImportance.High, DateTime.Now) { ProjectFile = "a.proj" }); - Assert.AreEqual(0, eventRedirector.Events.Count); + Assert.IsEmpty(eventRedirector.Events); eventSource.SendMessageRaised(new BuildMessageEventArgs(message: string.Empty, helpKeyword: "Link", senderName: "Link", MessageImportance.High, DateTime.Now) { ProjectFile = "a.proj" }); - Assert.AreEqual(0, eventRedirector.Events.Count); + Assert.IsEmpty(eventRedirector.Events); eventSource.SendTaskFinished(new TaskFinishedEventArgs(message: "Link finished", helpKeyword: "Link", projectFile: "a.proj", taskFile: "a.proj", taskName: "Link", succeeded: false)); - Assert.AreEqual(0, eventRedirector.Events.Count); + Assert.IsEmpty(eventRedirector.Events); } finally {