public async Task Publish_WithLinkerAndCompression_IsIncremental() { // Arrange using var project = ProjectDirectory.Create("blazorhosted", additionalProjects: new[] { "blazorwasm", "razorclasslibrary" }); var result = await MSBuildProcessManager.DotnetMSBuild(project, target : "publish"); Assert.BuildPassed(result); var buildOutputDirectory = project.BuildOutputDirectory; // Act var compressedFilesFolder = Path.Combine("..", "blazorwasm", project.IntermediateOutputDirectory, "brotli"); var thumbPrint = FileThumbPrint.CreateFolderThumbprint(project, compressedFilesFolder); // Assert for (var i = 0; i < 3; i++) { result = await MSBuildProcessManager.DotnetMSBuild(project); Assert.BuildPassed(result); var newThumbPrint = FileThumbPrint.CreateFolderThumbprint(project, compressedFilesFolder); Assert.Equal(thumbPrint.Count, newThumbPrint.Count); for (var j = 0; j < thumbPrint.Count; j++) { Assert.Equal(thumbPrint[j], newThumbPrint[j]); } } }
public async Task Publish_WithoutLinkerAndCompression_UpdatesFilesWhenSourcesChange() { // Arrange using var project = ProjectDirectory.Create("blazorhosted", additionalProjects: new[] { "blazorwasm", "razorclasslibrary" }); var result = await MSBuildProcessManager.DotnetMSBuild(project, target : "publish", args : "/p:BlazorWebAssemblyEnableLinking=false"); Assert.BuildPassed(result); // Act var mainAppDll = Path.Combine(project.DirectoryPath, project.PublishOutputDirectory, "wwwroot", "_framework", "blazorwasm.dll"); var mainAppDllThumbPrint = FileThumbPrint.Create(mainAppDll); var mainAppCompressedDll = Path.Combine(project.DirectoryPath, project.PublishOutputDirectory, "wwwroot", "_framework", "blazorwasm.dll.br"); var mainAppCompressedDllThumbPrint = FileThumbPrint.Create(mainAppCompressedDll); var programFile = Path.Combine(project.DirectoryPath, "..", "blazorwasm", "Program.cs"); var programFileContents = File.ReadAllText(programFile); File.WriteAllText(programFile, programFileContents.Replace("args", "arguments")); // Assert result = await MSBuildProcessManager.DotnetMSBuild(project, target : "publish", args : "/p:BlazorWebAssemblyEnableLinking=false"); Assert.BuildPassed(result); var newMainAppDllThumbPrint = FileThumbPrint.Create(mainAppDll); var newMainAppCompressedDllThumbPrint = FileThumbPrint.Create(mainAppCompressedDll); Assert.NotEqual(mainAppDllThumbPrint, newMainAppDllThumbPrint); Assert.NotEqual(mainAppCompressedDllThumbPrint, newMainAppCompressedDllThumbPrint); }
public async Task Build_InRelease_Works() { // Arrange using var project = ProjectDirectory.Create("blazorwasm", additionalProjects: new[] { "razorclasslibrary" }); project.Configuration = "Release"; var result = await MSBuildProcessManager.DotnetMSBuild(project); Assert.BuildPassed(result); var buildOutputDirectory = project.BuildOutputDirectory; Assert.FileExists(result, buildOutputDirectory, "wwwroot", "_framework", "blazor.boot.json"); Assert.FileExists(result, buildOutputDirectory, "wwwroot", "_framework", "blazor.webassembly.js"); Assert.FileExists(result, buildOutputDirectory, "wwwroot", "_framework", "dotnet.wasm"); Assert.FileExists(result, buildOutputDirectory, "wwwroot", "_framework", DotNetJsFileName); Assert.FileExists(result, buildOutputDirectory, "wwwroot", "_framework", "blazorwasm.dll"); Assert.FileExists(result, buildOutputDirectory, "wwwroot", "_framework", "RazorClassLibrary.dll"); Assert.FileExists(result, buildOutputDirectory, "wwwroot", "_framework", "System.Text.Json.dll"); // Verify dependencies are part of the output. Assert.FileExists(result, buildOutputDirectory, "wwwroot", "_framework", "blazorwasm.pdb"); Assert.FileExists(result, buildOutputDirectory, "wwwroot", "_framework", "RazorClassLibrary.pdb"); var staticWebAssets = Assert.FileExists(result, buildOutputDirectory, "blazorwasm.StaticWebAssets.xml"); Assert.FileContains(result, staticWebAssets, Path.Combine(project.TargetFramework, "wwwroot")); Assert.FileContains(result, staticWebAssets, Path.GetFullPath(Path.Combine(project.SolutionPath, "razorclasslibrary", "wwwroot"))); }
public async Task Build_SatelliteAssembliesAreCopiedToBuildOutput() { // Arrange using var project = ProjectDirectory.Create("blazorwasm", additionalProjects: new[] { "razorclasslibrary", "classlibrarywithsatelliteassemblies" }); project.AddProjectFileContent( @" <PropertyGroup> <DefineConstants>$(DefineConstants);REFERENCE_classlibrarywithsatelliteassemblies</DefineConstants> </PropertyGroup> <ItemGroup> <ProjectReference Include=""..\classlibrarywithsatelliteassemblies\classlibrarywithsatelliteassemblies.csproj"" /> </ItemGroup>"); var resxfileInProject = Path.Combine(project.DirectoryPath, "Resources.ja.resx.txt"); File.Move(resxfileInProject, Path.Combine(project.DirectoryPath, "Resource.ja.resx")); var result = await MSBuildProcessManager.DotnetMSBuild(project, args : "/restore"); Assert.BuildPassed(result); var buildOutputDirectory = project.BuildOutputDirectory; Assert.FileExists(result, buildOutputDirectory, "wwwroot", "_framework", "blazorwasm.dll"); Assert.FileExists(result, buildOutputDirectory, "wwwroot", "_framework", "classlibrarywithsatelliteassemblies.dll"); Assert.FileExists(result, buildOutputDirectory, "wwwroot", "_framework", "Microsoft.CodeAnalysis.CSharp.dll"); Assert.FileExists(result, buildOutputDirectory, "wwwroot", "_framework", "fr", "Microsoft.CodeAnalysis.CSharp.resources.dll"); // Verify satellite assemblies are present in the build output. var bootJsonPath = Path.Combine(buildOutputDirectory, "wwwroot", "_framework", "blazor.boot.json"); Assert.FileContains(result, bootJsonPath, "\"Microsoft.CodeAnalysis.CSharp.dll\""); Assert.FileContains(result, bootJsonPath, "\"fr\\/Microsoft.CodeAnalysis.CSharp.resources.dll\""); }
public async Task Build_WithBlazorEnableTimeZoneSupportDisabled_DoesNotCopyTimeZoneInfo() { // Arrange using var project = ProjectDirectory.Create("blazorwasm", additionalProjects: new[] { "razorclasslibrary" }); project.Configuration = "Release"; project.AddProjectFileContent( @" <PropertyGroup> <BlazorEnableTimeZoneSupport>false</BlazorEnableTimeZoneSupport> </PropertyGroup>"); var result = await MSBuildProcessManager.DotnetMSBuild(project); Assert.BuildPassed(result); var buildOutputDirectory = project.BuildOutputDirectory; var bootJsonPath = Path.Combine(buildOutputDirectory, "wwwroot", "_framework", "blazor.boot.json"); var bootJsonData = ReadBootJsonData(result, bootJsonPath); var runtime = bootJsonData.resources.runtime.Keys; Assert.Contains("dotnet.wasm", runtime); Assert.DoesNotContain("dotnet.timezones.dat", runtime); Assert.FileExists(result, buildOutputDirectory, "wwwroot", "_framework", "wasm", "dotnet.wasm"); Assert.FileDoesNotExist(result, buildOutputDirectory, "wwwroot", "_framework", "wasm", "dotnet.timezones.dat"); }
public async Task Build_InRelease_ProducesBootJsonDataWithExpectedContent() { // Arrange using var project = ProjectDirectory.Create("blazorwasm", additionalProjects: new[] { "razorclasslibrary" }); project.Configuration = "Release"; var result = await MSBuildProcessManager.DotnetMSBuild(project); Assert.BuildPassed(result); var buildOutputDirectory = project.BuildOutputDirectory; var bootJsonPath = Path.Combine(buildOutputDirectory, "wwwroot", "_framework", "blazor.boot.json"); var bootJsonData = ReadBootJsonData(result, bootJsonPath); var runtime = bootJsonData.resources.runtime.Keys; Assert.Contains(DotNetJsFileName, runtime); Assert.Contains("dotnet.wasm", runtime); var assemblies = bootJsonData.resources.assembly.Keys; Assert.Contains("blazorwasm.dll", assemblies); Assert.Contains("RazorClassLibrary.dll", assemblies); Assert.Contains("System.Text.Json.dll", assemblies); var pdb = bootJsonData.resources.pdb.Keys; Assert.Contains("blazorwasm.pdb", pdb); Assert.Contains("RazorClassLibrary.pdb", pdb); Assert.Null(bootJsonData.resources.satelliteResources); }
public async Task Build_WithAspNetCoreFrameworkReference_Fails() { // Arrange using var project = ProjectDirectory.Create("blazorwasm-fxref"); var result = await MSBuildProcessManager.DotnetMSBuild(project); Assert.BuildError(result, "BLAZORSDK1001"); }
public async Task Publish_HostedApp_WithRid_Works() { // Arrange using var project = ProjectDirectory.Create("blazorhosted-rid", additionalProjects: new[] { "blazorwasm", "razorclasslibrary", }); project.RuntimeIdentifier = "linux-x64"; var result = await MSBuildProcessManager.DotnetMSBuild(project, "Publish"); AssertRIDPublishOuput(project, result); }
public async Task Publish_HostedApp_DefaultSettings_Works() { // Arrange using var project = ProjectDirectory.Create("blazorhosted", additionalProjects: new[] { "blazorwasm", "razorclasslibrary", }); var result = await MSBuildProcessManager.DotnetMSBuild(project, "Publish"); Assert.BuildPassed(result); var publishDirectory = project.PublishOutputDirectory; // Make sure the main project exists Assert.FileExists(result, publishDirectory, "blazorhosted.dll"); // Verification for https://github.com/dotnet/aspnetcore/issues/19926. Verify binaries for projects // referenced by the Hosted project appear in the publish directory Assert.FileExists(result, publishDirectory, "RazorClassLibrary.dll"); Assert.FileExists(result, publishDirectory, "blazorwasm.dll"); var blazorPublishDirectory = Path.Combine(publishDirectory, "wwwroot"); Assert.FileExists(result, blazorPublishDirectory, "_framework", "blazor.boot.json"); Assert.FileExists(result, blazorPublishDirectory, "_framework", "blazor.webassembly.js"); Assert.FileExists(result, blazorPublishDirectory, "_framework", "dotnet.wasm"); Assert.FileExists(result, blazorPublishDirectory, "_framework", DotNetJsFileName); Assert.FileExists(result, blazorPublishDirectory, "_framework", "blazorwasm.dll"); Assert.FileExists(result, blazorPublishDirectory, "_framework", "System.Text.Json.dll"); // Verify dependencies are part of the output. // Verify project references appear as static web assets Assert.FileExists(result, blazorPublishDirectory, "_framework", "RazorClassLibrary.dll"); // Also verify project references to the server project appear in the publish output Assert.FileExists(result, publishDirectory, "RazorClassLibrary.dll"); // Verify static assets are in the publish directory Assert.FileExists(result, blazorPublishDirectory, "index.html"); // Verify static web assets from referenced projects are copied. Assert.FileExists(result, publishDirectory, "wwwroot", "_content", "RazorClassLibrary", "wwwroot", "exampleJsInterop.js"); Assert.FileExists(result, publishDirectory, "wwwroot", "_content", "RazorClassLibrary", "styles.css"); // Verify web.config Assert.FileExists(result, publishDirectory, "web.config"); VerifyBootManifestHashes(result, blazorPublishDirectory); // Verify compression works Assert.FileExists(result, blazorPublishDirectory, "_framework", "dotnet.wasm.br"); Assert.FileExists(result, blazorPublishDirectory, "_framework", "blazorwasm.dll.br"); Assert.FileExists(result, blazorPublishDirectory, "_framework", "RazorClassLibrary.dll.br"); Assert.FileExists(result, blazorPublishDirectory, "_framework", "System.Text.Json.dll.br"); VerifyServiceWorkerFiles(result, blazorPublishDirectory, serviceWorkerPath: Path.Combine("serviceworkers", "my-service-worker.js"), serviceWorkerContent: "// This is the production service worker", assetsManifestPath: "custom-service-worker-assets.js"); VerifyTypeGranularTrimming(result, blazorPublishDirectory); }
public async Task Publish_HostedApp_WithRid_Works() { // Arrange using var project = ProjectDirectory.Create("blazorhosted-rid", additionalProjects: new[] { "blazorwasm", "razorclasslibrary", }); project.RuntimeIdentifier = "linux-x64"; var result = await MSBuildProcessManager.DotnetMSBuild(project, "Publish"); Assert.BuildPassed(result); var publishDirectory = project.PublishOutputDirectory; // Make sure the main project exists Assert.FileExists(result, publishDirectory, "blazorhosted-rid.dll"); Assert.FileExists(result, publishDirectory, "libhostfxr.so"); // Verify that we're doing a self-contained deployment Assert.FileExists(result, publishDirectory, "RazorClassLibrary.dll"); Assert.FileExists(result, publishDirectory, "blazorwasm.dll"); var blazorPublishDirectory = Path.Combine(publishDirectory, "wwwroot"); Assert.FileExists(result, blazorPublishDirectory, "_framework", "blazor.boot.json"); Assert.FileExists(result, blazorPublishDirectory, "_framework", "blazor.webassembly.js"); Assert.FileExists(result, blazorPublishDirectory, "_framework", "dotnet.wasm"); Assert.FileExists(result, blazorPublishDirectory, "_framework", DotNetJsFileName); Assert.FileExists(result, blazorPublishDirectory, "_framework", "blazorwasm.dll"); Assert.FileExists(result, blazorPublishDirectory, "_framework", "System.Text.Json.dll"); // Verify dependencies are part of the output. // Verify project references appear as static web assets Assert.FileExists(result, blazorPublishDirectory, "_framework", "RazorClassLibrary.dll"); // Also verify project references to the server project appear in the publish output Assert.FileExists(result, publishDirectory, "RazorClassLibrary.dll"); // Verify static assets are in the publish directory Assert.FileExists(result, blazorPublishDirectory, "index.html"); // Verify static web assets from referenced projects are copied. Assert.FileExists(result, publishDirectory, "wwwroot", "_content", "RazorClassLibrary", "wwwroot", "exampleJsInterop.js"); Assert.FileExists(result, publishDirectory, "wwwroot", "_content", "RazorClassLibrary", "styles.css"); // Verify web.config Assert.FileExists(result, publishDirectory, "web.config"); VerifyBootManifestHashes(result, blazorPublishDirectory); // Verify compression works Assert.FileExists(result, blazorPublishDirectory, "_framework", "dotnet.wasm.br"); Assert.FileExists(result, blazorPublishDirectory, "_framework", "blazorwasm.dll.br"); Assert.FileExists(result, blazorPublishDirectory, "_framework", "RazorClassLibrary.dll.br"); Assert.FileExists(result, blazorPublishDirectory, "_framework", "System.Text.Json.dll.br"); VerifyServiceWorkerFiles(result, blazorPublishDirectory, serviceWorkerPath: Path.Combine("serviceworkers", "my-service-worker.js"), serviceWorkerContent: "// This is the production service worker", assetsManifestPath: "custom-service-worker-assets.js"); }
public async Task ManualServerShutdown_NoPipeName_ShutsDownServer() { // We are trying to test whether the correct pipe name is generated (from the location of rzc tool) // when we don't explicitly specify a pipe name. // Publish rzc tool to a temporary path. This is the location based on which the pipe name is generated. var repositoryRoot = ProjectDirectory.SearchUp(AppContext.BaseDirectory, "global.json"); var solutionRoot = Path.Combine(repositoryRoot, "src", "Razor"); var toolAssemblyDirectory = Path.Combine(solutionRoot, "src", "Microsoft.AspNetCore.Razor.Tools"); var toolAssemblyPath = Path.Combine(toolAssemblyDirectory, "Microsoft.AspNetCore.Razor.Tools.csproj"); var projectDirectory = new TestProjectDirectory(solutionRoot, toolAssemblyDirectory, toolAssemblyPath); var publishDir = Path.Combine(Path.GetTempPath(), "Razor", Path.GetRandomFileName(), "RzcPublish"); var publishResult = await MSBuildProcessManager.RunProcessAsync(projectDirectory, $"/t:Publish /p:PublishDir=\"{publishDir}\""); try { // Make sure publish succeeded. Assert.BuildPassed(publishResult); // Run the build using the published tool var toolAssembly = Path.Combine(publishDir, "rzc.dll"); var result = await DotnetMSBuild( "Build", $"/p:_RazorForceBuildServer=true /p:_RazorToolAssembly={toolAssembly}", suppressBuildServer : true); // We don't want to specify a pipe name Assert.BuildPassed(result); // Manually shutdown the server var processStartInfo = new ProcessStartInfo() { WorkingDirectory = publishDir, UseShellExecute = false, RedirectStandardError = true, RedirectStandardOutput = true, FileName = "dotnet", Arguments = $"{toolAssembly} shutdown -w" }; var logFilePath = Path.Combine(publishDir, "out.log"); processStartInfo.Environment.Add("RAZORBUILDSERVER_LOG", logFilePath); var shutdownResult = await MSBuildProcessManager.RunProcessCoreAsync(processStartInfo); Assert.Equal(0, shutdownResult.ExitCode); var output = await File.ReadAllTextAsync(logFilePath); Assert.Contains("shut down completed", output); } finally { // Finally delete the temporary publish directory ProjectDirectory.CleanupDirectory(publishDir); } }
internal Task <MSBuildResult> DotnetMSBuild( string target, string args = null, bool suppressTimeout = false, bool suppressBuildServer = false, string buildServerPipeName = null, MSBuildProcessKind msBuildProcessKind = MSBuildProcessKind.Dotnet) { var timeout = suppressTimeout ? (TimeSpan?)Timeout.InfiniteTimeSpan : null; var buildArgumentList = new List <string> { // Disable node-reuse. We don't want msbuild processes to stick around // once the test is completed. "/nr:false", // Always generate a bin log for debugging purposes "/bl", // Let the test app know it is running as part of a test. "/p:RunningAsTest=true", $"/p:MicrosoftNETCoreAppRuntimeVersion={BuildVariables.MicrosoftNETCoreAppRuntimeVersion}", $"/p:MicrosoftNetCompilersToolsetPackageVersion={BuildVariables.MicrosoftNetCompilersToolsetPackageVersion}", $"/p:RazorSdkDirectoryRoot={BuildVariables.RazorSdkDirectoryRoot}", $"/p:RepoRoot={BuildVariables.RepoRoot}", }; if (!suppressBuildServer) { buildArgumentList.Add($@"/p:_RazorBuildServerPipeName=""{buildServerPipeName ?? BuildServer.PipeName}"""); } if (!string.IsNullOrEmpty(target)) { buildArgumentList.Add($"/t:{target}"); } else { buildArgumentList.Add($"/t:Build"); } buildArgumentList.Add($"/p:Configuration={Configuration} {args}"); var buildArguments = string.Join(" ", buildArgumentList); return(MSBuildProcessManager.RunProcessAsync( Project, buildArguments, timeout, msBuildProcessKind)); }
internal async Task PackAsync(ITestOutputHelper output) { if (_packed) { return; } var projectsToPack = GetProjectsToPack(); foreach (var project in projectsToPack) { output.WriteLine(project); } foreach (var project in projectsToPack) { var psi = new ProcessStartInfo { FileName = DotNetMuxer.MuxerPathOrDefault(), #if DEBUG Arguments = "msbuild /t:Restore;Pack /p:Configuration=Debug", #else Arguments = "msbuild /t:Restore;Pack /p:Configuration=Release", #endif WorkingDirectory = project, RedirectStandardOutput = true, RedirectStandardError = true }; for (int i = 0; i < MaxPackRetries; i++) { try { var result = await MSBuildProcessManager.RunProcessCoreAsync( psi, TimeSpan.FromMinutes(MaxPackTimeoutInMinutes)); output.WriteLine(result.Output); Assert.Equal(0, result.ExitCode); break; } catch { await Task.Delay(1000); } } } _packed = true; }
public async Task Build_WithCustomOutputPath_Works() { // Arrange using var project = ProjectDirectory.Create("blazorwasm", additionalProjects: new[] { "razorclasslibrary" }); project.AddDirectoryBuildContent( @"<PropertyGroup> <BaseOutputPath>$(MSBuildThisFileDirectory)build\bin\</BaseOutputPath> <BaseIntermediateOutputPath>$(MSBuildThisFileDirectory)build\obj\</BaseIntermediateOutputPath> </PropertyGroup>"); var result = await MSBuildProcessManager.DotnetMSBuild(project, args : "/restore"); Assert.BuildPassed(result); }
public async Task Build_SatelliteAssembliesFileIsPreserved() { // Arrange using var project = ProjectDirectory.Create("blazorwasm", additionalProjects: new[] { "razorclasslibrary" }); File.Move(Path.Combine(project.DirectoryPath, "Resources.ja.resx.txt"), Path.Combine(project.DirectoryPath, "Resource.ja.resx")); var result = await MSBuildProcessManager.DotnetMSBuild(project); Assert.BuildPassed(result); var satelliteAssemblyCacheFile = Path.Combine(project.IntermediateOutputDirectory, "blazor.satelliteasm.props"); var satelliteAssemblyFile = Path.Combine(project.BuildOutputDirectory, "wwwroot", "_framework", "ja", "blazorwasm.resources.dll"); var bootJson = Path.Combine(project.DirectoryPath, project.BuildOutputDirectory, "wwwroot", "_framework", "blazor.boot.json"); // Assert for (var i = 0; i < 3; i++) { result = await MSBuildProcessManager.DotnetMSBuild(project); Assert.BuildPassed(result); Verify(); } // Assert - incremental builds with BuildingProject=false for (var i = 0; i < 3; i++) { result = await MSBuildProcessManager.DotnetMSBuild(project, args : "/p:BuildingProject=false"); Assert.BuildPassed(result); Verify(); } void Verify() { Assert.FileExists(result, satelliteAssemblyCacheFile); Assert.FileExists(result, satelliteAssemblyFile); var bootJsonFile = JsonSerializer.Deserialize <BootJsonData>(File.ReadAllText(bootJson), new JsonSerializerOptions { PropertyNameCaseInsensitive = true }); var satelliteResources = bootJsonFile.resources.satelliteResources; var kvp = Assert.Single(satelliteResources); Assert.Equal("ja", kvp.Key); Assert.Equal("ja/blazorwasm.resources.dll", Assert.Single(kvp.Value).Key); } }
public async Task Publish_WithTrimmingdDisabled_Works() { // Arrange using var project = ProjectDirectory.Create("blazorwasm", additionalProjects: new[] { "razorclasslibrary" }); project.AddProjectFileContent( @"<PropertyGroup> <PublishTrimmed>false</PublishTrimmed> </PropertyGroup>"); var result = await MSBuildProcessManager.DotnetMSBuild(project, "Publish"); Assert.BuildPassed(result); var publishDirectory = project.PublishOutputDirectory; var blazorPublishDirectory = Path.Combine(publishDirectory, "wwwroot"); Assert.FileExists(result, blazorPublishDirectory, "_framework", "blazor.boot.json"); Assert.FileExists(result, blazorPublishDirectory, "_framework", "blazor.webassembly.js"); Assert.FileExists(result, blazorPublishDirectory, "_framework", "dotnet.wasm"); Assert.FileExists(result, blazorPublishDirectory, "_framework", DotNetJsFileName); Assert.FileExists(result, blazorPublishDirectory, "_framework", "blazorwasm.dll"); Assert.FileExists(result, blazorPublishDirectory, "_framework", "System.Text.Json.dll"); // Verify dependencies are part of the output. // Verify compression works Assert.FileExists(result, blazorPublishDirectory, "_framework", "dotnet.wasm.br"); Assert.FileExists(result, blazorPublishDirectory, "_framework", "System.Text.Json.dll.br"); // // Verify static assets are in the publish directory Assert.FileExists(result, blazorPublishDirectory, "index.html"); // Verify referenced static web assets Assert.FileExists(result, blazorPublishDirectory, "_content", "RazorClassLibrary", "wwwroot", "exampleJsInterop.js"); Assert.FileExists(result, blazorPublishDirectory, "_content", "RazorClassLibrary", "styles.css"); // Verify web.config Assert.FileExists(result, publishDirectory, "web.config"); VerifyBootManifestHashes(result, blazorPublishDirectory); VerifyServiceWorkerFiles(result, blazorPublishDirectory, serviceWorkerPath: Path.Combine("serviceworkers", "my-service-worker.js"), serviceWorkerContent: "// This is the production service worker", assetsManifestPath: "custom-service-worker-assets.js"); // Verify assemblies are not trimmed var loggingAssemblyPath = Path.Combine(blazorPublishDirectory, "_framework", "Microsoft.Extensions.Logging.Abstractions.dll"); Assert.AssemblyContainsType(result, loggingAssemblyPath, "Microsoft.Extensions.Logging.Abstractions.NullLogger"); }
internal Task <MSBuildResult> DotnetMSBuild( string target, string args = null, bool suppressRestore = false, bool suppressTimeout = false, MSBuildProcessKind msBuildProcessKind = MSBuildProcessKind.Dotnet) { var timeout = suppressTimeout ? (TimeSpan?)Timeout.InfiniteTimeSpan : null; var restoreArgument = suppressRestore ? "" : "/restore"; return(MSBuildProcessManager.RunProcessAsync( Project, $"{restoreArgument} /t:{target} /p:Configuration={Configuration} {args}", timeout, msBuildProcessKind)); }
public async Task Publish_HostedApp_VisualStudio() { // Simulates publishing the same way VS does by setting BuildProjectReferences=false. // Arrange using var project = ProjectDirectory.Create("blazorhosted", additionalProjects: new[] { "blazorwasm", "razorclasslibrary", }); project.Configuration = "Release"; var result = await MSBuildProcessManager.DotnetMSBuild(project, "Build", "/p:BuildInsideVisualStudio=true"); Assert.BuildPassed(result); result = await MSBuildProcessManager.DotnetMSBuild(project, "Publish", "/p:BuildProjectReferences=false /p:BuildInsideVisualStudio=true"); var publishDirectory = project.PublishOutputDirectory; // Make sure the main project exists Assert.FileExists(result, publishDirectory, "blazorhosted.dll"); var blazorPublishDirectory = Path.Combine(publishDirectory, "wwwroot"); Assert.FileExists(result, blazorPublishDirectory, "_framework", "blazor.boot.json"); Assert.FileExists(result, blazorPublishDirectory, "_framework", "dotnet.wasm"); Assert.FileExists(result, blazorPublishDirectory, "_framework", DotNetJsFileName); Assert.FileExists(result, blazorPublishDirectory, "_framework", "blazorwasm.dll"); Assert.FileExists(result, blazorPublishDirectory, "_framework", "System.Text.Json.dll"); // Verify dependencies are part of the output. // Verify static assets are in the publish directory Assert.FileExists(result, blazorPublishDirectory, "index.html"); // Verify static web assets from referenced projects are copied. Assert.FileExists(result, publishDirectory, "wwwroot", "_content", "RazorClassLibrary", "wwwroot", "exampleJsInterop.js"); Assert.FileExists(result, publishDirectory, "wwwroot", "_content", "RazorClassLibrary", "styles.css"); // Verify compression works Assert.FileExists(result, blazorPublishDirectory, "_framework", "dotnet.wasm.br"); Assert.FileExists(result, blazorPublishDirectory, "_framework", "blazorwasm.dll.br"); Assert.FileExists(result, blazorPublishDirectory, "_framework", "RazorClassLibrary.dll.br"); Assert.FileExists(result, blazorPublishDirectory, "_framework", "System.Text.Json.dll.br"); // Verify web.config Assert.FileExists(result, publishDirectory, "web.config"); VerifyBootManifestHashes(result, blazorPublishDirectory); VerifyServiceWorkerFiles(result, blazorPublishDirectory, serviceWorkerPath: Path.Combine("serviceworkers", "my-service-worker.js"), serviceWorkerContent: "// This is the production service worker", assetsManifestPath: "custom-service-worker-assets.js"); }
public async Task Publish_WithDefaultSettings_Works() { // Arrange using var project = ProjectDirectory.Create("blazorwasm", additionalProjects: new[] { "razorclasslibrary", "LinkBaseToWebRoot" }); project.Configuration = "Debug"; var result = await MSBuildProcessManager.DotnetMSBuild(project, "Publish"); Assert.BuildPassed(result); var publishDirectory = project.PublishOutputDirectory; var blazorPublishDirectory = Path.Combine(publishDirectory, "wwwroot"); Assert.FileExists(result, blazorPublishDirectory, "_framework", "blazor.boot.json"); Assert.FileExists(result, blazorPublishDirectory, "_framework", "blazor.webassembly.js"); Assert.FileExists(result, blazorPublishDirectory, "_framework", "dotnet.wasm"); Assert.FileExists(result, blazorPublishDirectory, "_framework", DotNetJsFileName); Assert.FileExists(result, blazorPublishDirectory, "_framework", "blazorwasm.dll"); Assert.FileExists(result, blazorPublishDirectory, "_framework", "System.Text.Json.dll"); // Verify dependencies are part of the output. // Verify referenced static web assets Assert.FileExists(result, blazorPublishDirectory, "_content", "RazorClassLibrary", "wwwroot", "exampleJsInterop.js"); Assert.FileExists(result, blazorPublishDirectory, "_content", "RazorClassLibrary", "styles.css"); // Verify static assets are in the publish directory Assert.FileExists(result, blazorPublishDirectory, "index.html"); // Verify link item assets are in the publish directory Assert.FileExists(result, blazorPublishDirectory, "js", "LinkedScript.js"); var cssFile = Assert.FileExists(result, blazorPublishDirectory, "css", "app.css"); Assert.FileContains(result, cssFile, ".publish"); Assert.FileDoesNotExist(result, "dist", "Fake-License.txt"); // Verify web.config Assert.FileExists(result, publishDirectory, "web.config"); Assert.FileCountEquals(result, 1, publishDirectory, "*", SearchOption.TopDirectoryOnly); VerifyBootManifestHashes(result, blazorPublishDirectory); VerifyServiceWorkerFiles(result, blazorPublishDirectory, serviceWorkerPath: Path.Combine("serviceworkers", "my-service-worker.js"), serviceWorkerContent: "// This is the production service worker", assetsManifestPath: "custom-service-worker-assets.js"); VerifyTypeGranularTrimming(result, blazorPublishDirectory); }
public async Task Build_Hosted_Works() { // Arrange using var project = ProjectDirectory.Create("blazorhosted", additionalProjects: new[] { "blazorwasm", "razorclasslibrary", }); var result = await MSBuildProcessManager.DotnetMSBuild(project); Assert.BuildPassed(result); var buildOutputDirectory = project.BuildOutputDirectory; Assert.FileDoesNotExist(result, buildOutputDirectory, "wwwroot", "_framework", "_bin", "blazorwasm.dll"); var staticWebAssets = Assert.FileExists(result, buildOutputDirectory, "blazorhosted.StaticWebAssets.xml"); Assert.FileContains(result, staticWebAssets, Path.Combine("net6.0", "wwwroot")); Assert.FileContains(result, staticWebAssets, Path.Combine("razorclasslibrary", "wwwroot")); Assert.FileContains(result, staticWebAssets, Path.Combine("blazorwasm", "wwwroot")); }
public async Task Publish_LazyLoadExplicitAssembly_InvalidAssembly() { // Arrange using var project = ProjectDirectory.Create("blazorwasm", additionalProjects: new[] { "razorclasslibrary" }); project.Configuration = "Release"; project.AddProjectFileContent( @" <ItemGroup> <BlazorWebAssemblyLazyLoad Include='RazorClassLibraryInvalid.dll' /> </ItemGroup> "); // Act var result = await MSBuildProcessManager.DotnetMSBuild(project, "Publish"); // Assert Assert.BuildError(result, "BLAZORSDK1001"); Assert.BuildFailed(result); }
public async Task Publish_WithNoBuild_Works() { // Arrange using var project = ProjectDirectory.Create("blazorwasm", additionalProjects: new[] { "razorclasslibrary" }); var result = await MSBuildProcessManager.DotnetMSBuild(project, "Build"); Assert.BuildPassed(result); result = await MSBuildProcessManager.DotnetMSBuild(project, "Publish", "/p:NoBuild=true"); Assert.BuildPassed(result); var publishDirectory = project.PublishOutputDirectory; var blazorPublishDirectory = Path.Combine(publishDirectory, "wwwroot"); Assert.FileExists(result, blazorPublishDirectory, "_framework", "blazor.boot.json"); Assert.FileExists(result, blazorPublishDirectory, "_framework", "blazor.webassembly.js"); Assert.FileExists(result, blazorPublishDirectory, "_framework", "dotnet.wasm"); Assert.FileExists(result, blazorPublishDirectory, "_framework", DotNetJsFileName); Assert.FileExists(result, blazorPublishDirectory, "_framework", "blazorwasm.dll"); Assert.FileExists(result, blazorPublishDirectory, "_framework", "System.Text.Json.dll"); // Verify dependencies are part of the output. // Verify static assets are in the publish directory Assert.FileExists(result, blazorPublishDirectory, "index.html"); // Verify static web assets from referenced projects are copied. Assert.FileExists(result, blazorPublishDirectory, "_content", "RazorClassLibrary", "wwwroot", "exampleJsInterop.js"); Assert.FileExists(result, blazorPublishDirectory, "_content", "RazorClassLibrary", "styles.css"); // Verify static assets are in the publish directory Assert.FileExists(result, blazorPublishDirectory, "index.html"); // Verify web.config Assert.FileExists(result, publishDirectory, "web.config"); VerifyBootManifestHashes(result, blazorPublishDirectory); VerifyServiceWorkerFiles(result, blazorPublishDirectory, serviceWorkerPath: Path.Combine("serviceworkers", "my-service-worker.js"), serviceWorkerContent: "// This is the production service worker", assetsManifestPath: "custom-service-worker-assets.js"); VerifyCompression(result, blazorPublishDirectory); }
public async Task Build_SatelliteAssembliesFileIsDeleted_IfAllSatelliteFilesAreRemoved() { // Arrange using var project = ProjectDirectory.Create("blazorwasm", additionalProjects: new[] { "razorclasslibrary" }); File.Move(Path.Combine(project.DirectoryPath, "Resources.ja.resx.txt"), Path.Combine(project.DirectoryPath, "Resource.ja.resx")); var result = await MSBuildProcessManager.DotnetMSBuild(project); Assert.BuildPassed(result); var satelliteAssemblyCacheFile = Path.Combine(project.IntermediateOutputDirectory, "blazor.satelliteasm.props"); var satelliteAssemblyFile = Path.Combine(project.BuildOutputDirectory, "wwwroot", "_framework", "ja", "blazorwasm.resources.dll"); var bootJson = Path.Combine(project.DirectoryPath, project.BuildOutputDirectory, "wwwroot", "_framework", "blazor.boot.json"); result = await MSBuildProcessManager.DotnetMSBuild(project); Assert.BuildPassed(result); Assert.FileExists(result, satelliteAssemblyCacheFile); Assert.FileExists(result, satelliteAssemblyFile); var bootJsonFile = JsonSerializer.Deserialize <BootJsonData>(File.ReadAllText(bootJson), new JsonSerializerOptions { PropertyNameCaseInsensitive = true }); var satelliteResources = bootJsonFile.resources.satelliteResources; var kvp = Assert.Single(satelliteResources); Assert.Equal("ja", kvp.Key); Assert.Equal("ja/blazorwasm.resources.dll", Assert.Single(kvp.Value).Key); File.Delete(Path.Combine(project.DirectoryPath, "Resource.ja.resx")); result = await MSBuildProcessManager.DotnetMSBuild(project); Assert.BuildPassed(result); Assert.FileDoesNotExist(result, satelliteAssemblyCacheFile); bootJsonFile = JsonSerializer.Deserialize <BootJsonData>(File.ReadAllText(bootJson), new JsonSerializerOptions { PropertyNameCaseInsensitive = true }); satelliteResources = bootJsonFile.resources.satelliteResources; Assert.Null(satelliteResources); }
public async Task Publish_WithExistingWebConfig_Works() { // Arrange using var project = ProjectDirectory.Create("blazorwasm", additionalProjects: new[] { "razorclasslibrary", "LinkBaseToWebRoot" }); project.Configuration = "Release"; var webConfigContents = "test webconfig contents"; AddFileToProject(project, "web.config", webConfigContents); var result = await MSBuildProcessManager.DotnetMSBuild(project, "Publish"); Assert.BuildPassed(result); var publishDirectory = project.PublishOutputDirectory; // Verify web.config Assert.FileExists(result, publishDirectory, "web.config"); Assert.FileContains(result, Path.Combine(publishDirectory, "web.config"), webConfigContents); }
public async Task Build_ServiceWorkerAssetsManifest_Works() { // Arrange var expectedExtensions = new[] { ".dll", ".pdb", ".js", ".wasm" }; using var project = ProjectDirectory.Create("blazorwasm", additionalProjects: new[] { "razorclasslibrary" }); var result = await MSBuildProcessManager.DotnetMSBuild(project, args : "/p:ServiceWorkerAssetsManifest=service-worker-assets.js"); Assert.BuildPassed(result); var buildOutputDirectory = project.BuildOutputDirectory; Assert.FileExists(result, buildOutputDirectory, "wwwroot", "_framework", "blazor.boot.json"); Assert.FileExists(result, buildOutputDirectory, "wwwroot", "_framework", "dotnet.wasm"); Assert.FileExists(result, buildOutputDirectory, "wwwroot", "_framework", DotNetJsFileName); Assert.FileExists(result, buildOutputDirectory, "wwwroot", "_framework", "blazorwasm.dll"); var staticWebAssets = Assert.FileExists(result, buildOutputDirectory, "blazorwasm.StaticWebAssets.xml"); Assert.FileContains(result, staticWebAssets, Path.Combine(project.TargetFramework, "wwwroot")); var serviceWorkerAssetsManifest = Assert.FileExists(result, buildOutputDirectory, "wwwroot", "service-worker-assets.js"); // Trim prefix 'self.assetsManifest = ' and suffix ';' var manifestContents = File.ReadAllText(serviceWorkerAssetsManifest).TrimEnd()[22..^ 1]; var manifestContentsJson = JsonDocument.Parse(manifestContents); Assert.True(manifestContentsJson.RootElement.TryGetProperty("assets", out var assets)); Assert.Equal(JsonValueKind.Array, assets.ValueKind); var entries = assets.EnumerateArray().Select(e => e.GetProperty("url").GetString()).OrderBy(e => e).ToArray(); Assert.All(entries, e => expectedExtensions.Contains(Path.GetExtension(e))); VerifyServiceWorkerFiles(result, Path.Combine(buildOutputDirectory, "wwwroot"), serviceWorkerPath: Path.Combine("serviceworkers", "my-service-worker.js"), serviceWorkerContent: "// This is the development service worker", assetsManifestPath: "service-worker-assets.js"); }
public async Task Publish_UpdatesServiceWorkerVersionHash_WhenSourcesChange() { // Arrange using var project = ProjectDirectory.Create("blazorwasm", additionalProjects: new[] { "razorclasslibrary" }); var result = await MSBuildProcessManager.DotnetMSBuild(project, "Publish", args : "/bl:initial.binlog /p:ServiceWorkerAssetsManifest=service-worker-assets.js"); Assert.BuildPassed(result); var publishOutputDirectory = project.PublishOutputDirectory; var serviceWorkerFile = Assert.FileExists(result, publishOutputDirectory, "wwwroot", "serviceworkers", "my-service-worker.js"); var version = File.ReadAllLines(serviceWorkerFile).Last(); var match = Regex.Match(version, "\\/\\* Manifest version: (.{8}) \\*\\/"); Assert.True(match.Success); Assert.Equal(2, match.Groups.Count); Assert.NotNull(match.Groups[1].Value); var capture = match.Groups[1].Value; // Act var cssFile = Path.Combine(project.DirectoryPath, "LinkToWebRoot", "css", "app.css"); File.WriteAllText(cssFile, ".updated { }"); // Assert result = await MSBuildProcessManager.DotnetMSBuild(project, "Publish", args : "/bl:updated.binlog /p:ServiceWorkerAssetsManifest=service-worker-assets.js"); Assert.BuildPassed(result); var updatedVersion = File.ReadAllLines(serviceWorkerFile).Last(); var updatedMatch = Regex.Match(updatedVersion, "\\/\\* Manifest version: (.{8}) \\*\\/"); Assert.True(updatedMatch.Success); Assert.Equal(2, updatedMatch.Groups.Count); Assert.NotNull(updatedMatch.Groups[1].Value); var updatedCapture = updatedMatch.Groups[1].Value; Assert.NotEqual(capture, updatedCapture); }
public async Task Publish_InRelease_Works() { // Arrange using var project = ProjectDirectory.Create("blazorwasm", additionalProjects: new[] { "razorclasslibrary", "LinkBaseToWebRoot" }); project.Configuration = "Release"; var result = await MSBuildProcessManager.DotnetMSBuild(project, "Publish", ""); Assert.BuildPassed(result); var publishDirectory = project.PublishOutputDirectory; var blazorPublishDirectory = Path.Combine(publishDirectory, "wwwroot"); Assert.FileExists(result, blazorPublishDirectory, "_framework", "blazor.boot.json"); Assert.FileExists(result, blazorPublishDirectory, "_framework", "blazor.webassembly.js"); Assert.FileExists(result, blazorPublishDirectory, "_framework", "dotnet.wasm"); Assert.FileExists(result, blazorPublishDirectory, "_framework", DotNetJsFileName); Assert.FileExists(result, blazorPublishDirectory, "_framework", "blazorwasm.dll"); Assert.FileExists(result, blazorPublishDirectory, "_framework", "System.Text.Json.dll"); // Verify dependencies are part of the output. // Verify referenced static web assets Assert.FileExists(result, blazorPublishDirectory, "_content", "RazorClassLibrary", "wwwroot", "exampleJsInterop.js"); Assert.FileExists(result, blazorPublishDirectory, "_content", "RazorClassLibrary", "styles.css"); // Verify static assets are in the publish directory Assert.FileExists(result, blazorPublishDirectory, "index.html"); // Verify link item assets are in the publish directory Assert.FileExists(result, blazorPublishDirectory, "js", "LinkedScript.js"); var cssFile = Assert.FileExists(result, blazorPublishDirectory, "css", "app.css"); Assert.FileContains(result, cssFile, ".publish"); Assert.FileDoesNotExist(result, "dist", "Fake-License.txt"); // Verify web.config Assert.FileExists(result, publishDirectory, "web.config"); Assert.FileCountEquals(result, 1, publishDirectory, "*", SearchOption.TopDirectoryOnly); }
public async Task BuildMinimal_Works() { // Arrange // Minimal has no project references, service worker etc. This is pretty close to the project template. using var project = ProjectDirectory.Create("blazorwasm-minimal"); var result = await MSBuildProcessManager.DotnetMSBuild(project); Assert.BuildPassed(result); var buildOutputDirectory = project.BuildOutputDirectory; Assert.FileExists(result, buildOutputDirectory, "wwwroot", "_framework", "blazor.boot.json"); Assert.FileExists(result, buildOutputDirectory, "wwwroot", "_framework", "blazor.webassembly.js"); Assert.FileExists(result, buildOutputDirectory, "wwwroot", "_framework", "dotnet.wasm"); Assert.FileExists(result, buildOutputDirectory, "wwwroot", "_framework", "dotnet.wasm.gz"); Assert.FileExists(result, buildOutputDirectory, "wwwroot", "_framework", DotNetJsFileName); Assert.FileExists(result, buildOutputDirectory, "wwwroot", "_framework", "blazorwasm-minimal.dll"); var staticWebAssets = Assert.FileExists(result, buildOutputDirectory, "blazorwasm-minimal.StaticWebAssets.xml"); Assert.FileContains(result, staticWebAssets, Path.Combine(project.TargetFramework, "wwwroot")); }
public async Task Publish_CompressesAllFrameworkFiles() { // Arrange using var project = ProjectDirectory.Create("blazorwasm", additionalProjects: new[] { "razorclasslibrary" }); var result = await MSBuildProcessManager.DotnetMSBuild(project, target : "publish"); Assert.BuildPassed(result); var extensions = new[] { ".dll", ".js", ".pdb", ".wasm", ".map", ".json", ".dat" }; // Act var frameworkFilesPath = Path.Combine(project.DirectoryPath, project.PublishOutputDirectory, "wwwroot", "_framework"); foreach (var file in Directory.EnumerateFiles(frameworkFilesPath, "*", new EnumerationOptions { RecurseSubdirectories = true, })) { var extension = Path.GetExtension(file); if (extension != ".br" && extension != ".gz") { Assert.FileExists(result, file + ".br"); } } }
public async Task Publish_LazyLoadExplicitAssembly_Debug_Works() { // Arrange using var project = ProjectDirectory.Create("blazorwasm", additionalProjects: new[] { "razorclasslibrary" }); project.Configuration = "Debug"; project.AddProjectFileContent( @" <ItemGroup> <BlazorWebAssemblyLazyLoad Include='RazorClassLibrary.dll' /> </ItemGroup> "); var result = await MSBuildProcessManager.DotnetMSBuild(project, "Publish"); var publishDirectory = project.PublishOutputDirectory; // Verify that a blazor.boot.json file has been created Assert.FileExists(result, publishDirectory, "wwwroot", "_framework", "blazor.boot.json"); // And that the assembly is in the output Assert.FileExists(result, publishDirectory, "wwwroot", "_framework", "RazorClassLibrary.dll"); var bootJson = ReadBootJsonData(result, Path.Combine(publishDirectory, "wwwroot", "_framework", "blazor.boot.json")); // And that it has been labelled as a dynamic assembly in the boot.json var lazyAssemblies = bootJson.resources.lazyAssembly; var assemblies = bootJson.resources.assembly; Assert.NotNull(lazyAssemblies); Assert.Contains("RazorClassLibrary.dll", lazyAssemblies.Keys); Assert.DoesNotContain("RazorClassLibrary.dll", assemblies.Keys); // App assembly should not be lazy loaded Assert.DoesNotContain("blazorwasm.dll", lazyAssemblies.Keys); Assert.Contains("blazorwasm.dll", assemblies.Keys); }