From 29a5db626b467a40086be25fa4f9886224b8f85f Mon Sep 17 00:00:00 2001 From: Caelan Sayler Date: Thu, 25 Jan 2024 15:17:37 +0000 Subject: [PATCH] Add tests for VelopackApp verifier --- .../Commands/WindowsPackCommandRunner.cs | 2 +- src/Velopack.Packaging.Windows/DotnetUtil.cs | 13 ++- test/PathHelper.cs | 6 + test/TestApp/Program.cs | 2 + test/TestApp/TestApp.csproj | 4 + .../DotnetUtilTests.cs | 108 ++++++++++++++++++ 6 files changed, 129 insertions(+), 6 deletions(-) create mode 100644 test/Velopack.Packaging.Tests/DotnetUtilTests.cs diff --git a/src/Velopack.Packaging.Windows/Commands/WindowsPackCommandRunner.cs b/src/Velopack.Packaging.Windows/Commands/WindowsPackCommandRunner.cs index c36f7d97..53de9578 100644 --- a/src/Velopack.Packaging.Windows/Commands/WindowsPackCommandRunner.cs +++ b/src/Velopack.Packaging.Windows/Commands/WindowsPackCommandRunner.cs @@ -38,7 +38,7 @@ public class WindowsPackCommandRunner : PackageBuilder "Please publish your application to a folder without ClickOnce."); } - DotnetUtil.VerifyVelopackAppBuilder(MainExePath, Log); + DotnetUtil.VerifyVelopackApp(MainExePath, Log); // copy files to temp dir, so we can modify them var dir = TempDir.CreateSubdirectory("PreprocessPackDirWin"); diff --git a/src/Velopack.Packaging.Windows/DotnetUtil.cs b/src/Velopack.Packaging.Windows/DotnetUtil.cs index f9e3e28a..129e7f82 100644 --- a/src/Velopack.Packaging.Windows/DotnetUtil.cs +++ b/src/Velopack.Packaging.Windows/DotnetUtil.cs @@ -1,6 +1,4 @@ -using System.Diagnostics; -using System.IO; -using AsmResolver.DotNet; +using AsmResolver.DotNet; using AsmResolver.DotNet.Bundles; using AsmResolver.DotNet.Serialized; using AsmResolver.PE; @@ -14,7 +12,7 @@ namespace Velopack.Packaging.Windows { public class DotnetUtil { - public static void VerifyVelopackAppBuilder(string exeFile, ILogger log) + public static NuGetVersion VerifyVelopackApp(string exeFile, ILogger log) { try { NuGetVersion velopackVersion = null; @@ -25,7 +23,7 @@ namespace Velopack.Packaging.Windows if (mainAssy == null) { // not a dotnet binary - return; + return null; } if (velopackDll != null) { @@ -57,8 +55,10 @@ namespace Velopack.Packaging.Windows $"This may cause compatibility issues. Expected {VelopackRuntimeInfo.VelopackProductVersion}, " + $"but found {velopackVersion}."); } + return velopackVersion; } else { log.Warn("VelopackApp verified at entry point, but ProductVersion could not be checked."); + return null; } } } @@ -68,9 +68,12 @@ namespace Velopack.Packaging.Windows // if we've iterated the whole main method and not found the call, then the velopack builder is missing throw new UserInfoException($"Unable to verify VelopackApp, in application main method '{entryPoint.FullName}'. " + "Please ensure that 'VelopackApp.Build().Run()' is present in your Program.Main()."); + } catch (Exception ex) when (ex is not UserInfoException) { log.Error("Unable to verify VelopackApp: " + ex.Message); } + + return null; } private static AssemblyDefinition LoadFullFramework(string exeFile, ref IPEImage velopackDll) diff --git a/test/PathHelper.cs b/test/PathHelper.cs index e70e8bf9..9f782124 100644 --- a/test/PathHelper.cs +++ b/test/PathHelper.cs @@ -9,6 +9,12 @@ public static class PathHelper public static string GetProjectDir() => Path.Combine(GetTestRoot(), ".."); + public static string GetAvaloniaSample() + => Path.Combine(GetProjectDir(), "examples", "AvaloniaCrossPlat"); + + public static string GetWpfSample() + => Path.Combine(GetProjectDir(), "examples", "VeloWpfSample"); + public static string GetVendorLibDir() => Path.Combine(GetProjectDir(), "vendor"); diff --git a/test/TestApp/Program.cs b/test/TestApp/Program.cs index 46648b84..430c5648 100644 --- a/test/TestApp/Program.cs +++ b/test/TestApp/Program.cs @@ -7,6 +7,7 @@ try { bool shouldExit = false; bool shouldAutoUpdate = args.Any(a => a.Equals("--autoupdate", StringComparison.OrdinalIgnoreCase)); +#if !NO_VELO_BUILDER VelopackApp.Build() .SetAutoApplyOnStartup(shouldAutoUpdate) .WithFirstRun((v) => { @@ -33,6 +34,7 @@ try { if (shouldExit) { return 0; } +#endif if (args.Length == 1 && args[0] == "version") { var locator = VelopackLocator.GetDefault(new ConsoleLogger()); diff --git a/test/TestApp/TestApp.csproj b/test/TestApp/TestApp.csproj index fb7f17ee..14a96a09 100644 --- a/test/TestApp/TestApp.csproj +++ b/test/TestApp/TestApp.csproj @@ -6,6 +6,10 @@ enable + + NO_VELO_BUILDER + + diff --git a/test/Velopack.Packaging.Tests/DotnetUtilTests.cs b/test/Velopack.Packaging.Tests/DotnetUtilTests.cs new file mode 100644 index 00000000..edc17980 --- /dev/null +++ b/test/Velopack.Packaging.Tests/DotnetUtilTests.cs @@ -0,0 +1,108 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Velopack.Packaging.Exceptions; +using Velopack.Packaging.Windows; +using Velopack.Packaging.Windows.Commands; + +namespace Velopack.Packaging.Tests +{ + public class DotnetUtilTests + { + private readonly ITestOutputHelper _output; + + public DotnetUtilTests(ITestOutputHelper output) + { + _output = output; + } + + [SkippableFact] + public void NonDotnetBinaryPasses() + { + Skip.IfNot(VelopackRuntimeInfo.IsWindows); + using var logger = _output.BuildLoggerFor(); + Assert.Null(DotnetUtil.VerifyVelopackApp(PathHelper.GetRustAsset("testapp.exe"), logger)); + } + + [SkippableFact] + public void PublishSingleFilePasses() + { + Skip.IfNot(VelopackRuntimeInfo.IsWindows); + using var logger = _output.BuildLoggerFor(); + using var _1 = Utility.GetTempDirectory(out var dir); + var sample = PathHelper.GetAvaloniaSample(); + Exe.InvokeAndThrowIfNonZero( + "dotnet", + new string[] { "publish", "--no-self-contained", "-r", "win-x64", "-o", dir, + "-p:UseLocalVelopack=true", "-p:PublishSingleFile=true" }, + sample); + + var path = Path.Combine(dir, "AvaloniaCrossPlat.exe"); + Assert.Equal(VelopackRuntimeInfo.VelopackProductVersion, DotnetUtil.VerifyVelopackApp(path, logger)); + + var newPath = Path.Combine(dir, "AvaloniaCrossPlat-asd2.exe"); + File.Move(path, newPath); + Assert.Equal(VelopackRuntimeInfo.VelopackProductVersion, DotnetUtil.VerifyVelopackApp(newPath, logger)); + } + + [SkippableFact] + public void PublishDotnet6Passes() + { + Skip.IfNot(VelopackRuntimeInfo.IsWindows); + using var logger = _output.BuildLoggerFor(); + using var _1 = Utility.GetTempDirectory(out var dir); + var sample = PathHelper.GetAvaloniaSample(); + Exe.InvokeAndThrowIfNonZero( + "dotnet", + new string[] { "publish", "--no-self-contained", "-r", "win-x64", "-o", dir, + "-p:UseLocalVelopack=true" }, + sample); + + var path = Path.Combine(dir, "AvaloniaCrossPlat.exe"); + Assert.Equal(VelopackRuntimeInfo.VelopackProductVersion, DotnetUtil.VerifyVelopackApp(path, logger)); + + var newPath = Path.Combine(dir, "AvaloniaCrossPlat-asd2.exe"); + File.Move(path, newPath); + Assert.Equal(VelopackRuntimeInfo.VelopackProductVersion, DotnetUtil.VerifyVelopackApp(newPath, logger)); + } + + [SkippableFact] + public void PublishNet48Passes() + { + Skip.IfNot(VelopackRuntimeInfo.IsWindows); + using var logger = _output.BuildLoggerFor(); + using var _1 = Utility.GetTempDirectory(out var dir); + var sample = PathHelper.GetWpfSample(); + Exe.InvokeAndThrowIfNonZero( + "dotnet", + new string[] { "publish", "-o", dir }, + sample); + + var path = Path.Combine(dir, "VeloWpfSample.exe"); + Assert.NotNull(DotnetUtil.VerifyVelopackApp(path, logger)); + + var newPath = Path.Combine(dir, "VeloWpfSample-asd2.exe"); + File.Move(path, newPath); + Assert.NotNull(DotnetUtil.VerifyVelopackApp(newPath, logger)); + } + + [SkippableFact] + public void UnawareDotnetAppFails() + { + Skip.IfNot(VelopackRuntimeInfo.IsWindows); + using var logger = _output.BuildLoggerFor(); + using var _1 = Utility.GetTempDirectory(out var dir); + var sample = PathHelper.GetTestRootPath("TestApp"); + Exe.InvokeAndThrowIfNonZero( + "dotnet", + new string[] { "publish", "--no-self-contained", "-r", "win-x64", "-o", dir, + "-p:NoVelopackApp=true" }, + sample); + + var path = Path.Combine(dir, "TestApp.exe"); + Assert.Throws(() => DotnetUtil.VerifyVelopackApp(path, logger)); + } + } +}