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 9825ffb..3f7f4c9 100644 --- a/global.json +++ b/global.json @@ -1,6 +1,9 @@ { "msbuild-sdks": { "Microsoft.Build.NoTargets": "3.7.56", - "MSTest.Sdk": "3.6.0" + "MSTest.Sdk": "3.11.1" + }, + "test": { + "runner": "Microsoft.Testing.Platform" } -} \ No newline at end of file +} 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 {