diff --git a/eng/Subsets.props b/eng/Subsets.props
index 60c14971d5bdb..ad61be8b48102 100644
--- a/eng/Subsets.props
+++ b/eng/Subsets.props
@@ -489,6 +489,7 @@
+
diff --git a/src/installer/tests/Assets/Projects/HelloWorld/HelloWorld.csproj b/src/installer/tests/Assets/Projects/HelloWorld/HelloWorld.csproj
new file mode 100644
index 0000000000000..e71444bd29bbf
--- /dev/null
+++ b/src/installer/tests/Assets/Projects/HelloWorld/HelloWorld.csproj
@@ -0,0 +1,8 @@
+
+
+
+ $(NetCoreAppCurrent)
+ Exe
+
+
+
diff --git a/src/installer/tests/Assets/Projects/HelloWorld/Program.cs b/src/installer/tests/Assets/Projects/HelloWorld/Program.cs
new file mode 100644
index 0000000000000..b206495c013c9
--- /dev/null
+++ b/src/installer/tests/Assets/Projects/HelloWorld/Program.cs
@@ -0,0 +1,18 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using System;
+using System.Runtime.InteropServices;
+
+namespace HelloWorld
+{
+ public static class Program
+ {
+ public static void Main(string[] args)
+ {
+ Console.WriteLine("Hello World!");
+ Console.WriteLine(string.Join(Environment.NewLine, args));
+ Console.WriteLine(RuntimeInformation.FrameworkDescription);
+ }
+ }
+}
diff --git a/src/installer/tests/Microsoft.NET.HostModel.Tests/Microsoft.NET.HostModel.Bundle.Tests/BundleAndRun.cs b/src/installer/tests/Microsoft.NET.HostModel.Tests/Microsoft.NET.HostModel.Bundle.Tests/BundleAndRun.cs
index fb290084af26c..7e062c658a98a 100644
--- a/src/installer/tests/Microsoft.NET.HostModel.Tests/Microsoft.NET.HostModel.Bundle.Tests/BundleAndRun.cs
+++ b/src/installer/tests/Microsoft.NET.HostModel.Tests/Microsoft.NET.HostModel.Bundle.Tests/BundleAndRun.cs
@@ -8,6 +8,7 @@
using Microsoft.DotNet.CoreSetup.Test;
using BundleTests.Helpers;
using System.Runtime.InteropServices;
+using System.Text;
namespace Microsoft.NET.HostModel.Tests
{
@@ -120,6 +121,27 @@ public void TestWithRelativePathsDirSeparator()
BundleRun(fixture, publishDir);
}
+ [Fact]
+ public void TestWithAdditionalContentAfterBundleMetadata()
+ {
+ var fixture = sharedTestState.TestFixture.Copy();
+ string singleFile = BundleHelper.BundleApp(fixture);
+
+ using (var file = File.OpenWrite(singleFile))
+ {
+ file.Position = file.Length;
+ var blob = Encoding.UTF8.GetBytes("Mock signature at the end of the bundle");
+ file.Write(blob, 0, blob.Length);
+ }
+
+ Command.Create(singleFile)
+ .CaptureStdErr()
+ .CaptureStdOut()
+ .Execute()
+ .Should().Pass()
+ .And.HaveStdOutContaining("Hello World!");
+ }
+
public class SharedTestState : IDisposable
{
public TestProjectFixture TestFixture { get; set; }
diff --git a/src/installer/tests/Microsoft.NET.HostModel.Tests/Microsoft.NET.HostModel.Bundle.Tests/BundlerConsistencyTests.cs b/src/installer/tests/Microsoft.NET.HostModel.Tests/Microsoft.NET.HostModel.Bundle.Tests/BundlerConsistencyTests.cs
index c2df90c84c186..7a9129da2bf08 100644
--- a/src/installer/tests/Microsoft.NET.HostModel.Tests/Microsoft.NET.HostModel.Bundle.Tests/BundlerConsistencyTests.cs
+++ b/src/installer/tests/Microsoft.NET.HostModel.Tests/Microsoft.NET.HostModel.Bundle.Tests/BundlerConsistencyTests.cs
@@ -1,17 +1,14 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
-using BundleTests.Helpers;
-using FluentAssertions;
-using Microsoft.DotNet.Cli.Build.Framework;
-using Microsoft.DotNet.CoreSetup.Test;
-using Microsoft.NET.HostModel.Bundle;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
-using System.Text;
+using FluentAssertions;
+using Microsoft.DotNet.CoreSetup.Test;
+using Microsoft.NET.HostModel.Bundle;
using Xunit;
namespace Microsoft.NET.HostModel.Tests
@@ -25,80 +22,69 @@ public BundlerConsistencyTests(SharedTestState fixture)
sharedTestState = fixture;
}
+ private static string BundlerHostName = Binaries.GetExeFileNameForCurrentPlatform(SharedTestState.AppName);
+ private Bundler CreateBundlerInstance(BundleOptions bundleOptions = BundleOptions.None, Version version = null)
+ => new Bundler(BundlerHostName, SharedFramework.CalculateUniqueTestDirectory($"{sharedTestState.App.Location}-bundle"), bundleOptions, targetFrameworkVersion: version);
+
[Fact]
public void EnableCompression_Before60_Fails()
{
// compression must be off when targeting pre-6.0
Assert.Throws(() =>
- new Bundler("appName", RepoDirectoriesProvider.Default.TestAssetsOutput, BundleOptions.EnableCompression, targetFrameworkVersion: new Version(5, 0)));
+ CreateBundlerInstance(BundleOptions.EnableCompression, new Version(5, 0)));
}
- [Fact]
- public void TestWithEmptySpecFails()
+ [Theory]
+ [InlineData(null)]
+ [InlineData("")]
+ [InlineData(" ")]
+ public void InvalidFileSpec_Fails(string invalidSpecPath)
{
- var fixture = sharedTestState.TestFixture.Copy();
+ FileSpec invalidSourcePath = new FileSpec(invalidSpecPath, BundlerHostName);
+ Assert.False(invalidSourcePath.IsValid());
- var hostName = BundleHelper.GetHostName(fixture);
- var bundleDir = BundleHelper.GetBundleDir(fixture);
- var targetOS = BundleHelper.GetTargetOS(fixture.CurrentRid);
- var targetArch = BundleHelper.GetTargetArch(fixture.CurrentRid);
- Bundler bundler = new Bundler(hostName, bundleDir.FullName, targetOS: targetOS, targetArch: targetArch);
-
- FileSpec[][] invalidSpecs =
- {
- new FileSpec[] {new FileSpec(hostName, null) },
- new FileSpec[] {new FileSpec(hostName, "") },
- new FileSpec[] {new FileSpec(hostName, " ") }
- };
+ FileSpec invalidBundlePath = new FileSpec(BundlerHostName, invalidSpecPath);
+ Assert.False(invalidBundlePath.IsValid());
- foreach (var invalidSpec in invalidSpecs)
- {
- Assert.Throws(() => bundler.GenerateBundle(invalidSpec));
- }
+ Bundler bundler = CreateBundlerInstance();
+ Assert.Throws(() => bundler.GenerateBundle(new[] { invalidSourcePath }));
+ Assert.Throws(() => bundler.GenerateBundle(new[] { invalidBundlePath }));
}
[Fact]
- public void TestWithoutSpecifyingHostFails()
+ public void NoHostInFileSpecs_Fails()
{
- var fixture = sharedTestState.TestFixture.Copy();
+ var appName = Path.GetFileNameWithoutExtension(BundlerHostName);
- var hostName = BundleHelper.GetHostName(fixture);
- var appName = Path.GetFileNameWithoutExtension(hostName);
- var bundleDir = BundleHelper.GetBundleDir(fixture);
- var targetOS = BundleHelper.GetTargetOS(fixture.CurrentRid);
- var targetArch = BundleHelper.GetTargetArch(fixture.CurrentRid);
-
- // Generate a file specification without the apphost
- var fileSpecs = new List();
- string[] files = { $"{appName}.dll", $"{appName}.deps.json", $"{appName}.runtimeconfig.json" };
- Array.ForEach(files, x => fileSpecs.Add(new FileSpec(x, x)));
-
- Bundler bundler = new Bundler(hostName, bundleDir.FullName, targetOS: targetOS, targetArch: targetArch);
+ // File specification without the apphost
+ var fileSpecs = new FileSpec[]
+ {
+ new FileSpec($"{appName}.dll", $"{appName}.dll"),
+ new FileSpec($"{appName}.deps.json", $"{appName}.deps.json"),
+ new FileSpec($"{appName}.runtimeconfig.json", $"{appName}.runtimeconfig.json")
+ };
+ Bundler bundler = CreateBundlerInstance();
Assert.Throws(() => bundler.GenerateBundle(fileSpecs));
}
[Fact]
- public void TestWithExactDuplicateEntriesPasses()
+ public void ExactDuplicateEntries()
{
- var fixture = sharedTestState.TestFixture.Copy();
-
- var hostName = BundleHelper.GetHostName(fixture);
- var bundleDir = BundleHelper.GetBundleDir(fixture);
- var targetOS = BundleHelper.GetTargetOS(fixture.CurrentRid);
- var targetArch = BundleHelper.GetTargetArch(fixture.CurrentRid);
-
- // Generate a file specification with duplicate entries
- var fileSpecs = new List();
- fileSpecs.Add(new FileSpec(BundleHelper.GetHostPath(fixture), BundleHelper.GetHostName(fixture)));
- string appPath = BundleHelper.GetAppPath(fixture);
- fileSpecs.Add(new FileSpec(appPath, "rel/app.repeat.dll"));
- fileSpecs.Add(new FileSpec(appPath, "rel/app.repeat.dll"));
- string systemLibPath = Path.Join(BundleHelper.GetPublishPath(fixture), "System.dll");
- fileSpecs.Add(new FileSpec(systemLibPath, "rel/system.repeat.dll"));
- fileSpecs.Add(new FileSpec(systemLibPath, "rel/system.repeat.dll"));
-
- Bundler bundler = new Bundler(hostName, bundleDir.FullName, targetOS: targetOS, targetArch: targetArch);
+ string appPath = sharedTestState.App.AppDll;
+ string systemLibPath = sharedTestState.SystemDll;
+
+ // File specification with duplicate entries with matching source paths
+ var fileSpecs = new FileSpec[]
+ {
+ new FileSpec(Binaries.AppHost.FilePath, BundlerHostName),
+ new FileSpec(appPath, "rel/app.repeat.dll"),
+ new FileSpec(appPath, "rel/app.repeat.dll"),
+ new FileSpec(systemLibPath, "rel/system.repeat.dll"),
+ new FileSpec(systemLibPath, "rel/system.repeat.dll")
+ };
+
+ Bundler bundler = CreateBundlerInstance();
bundler.GenerateBundle(fileSpecs);
// Exact duplicates are not duplicated in the bundle
@@ -107,45 +93,35 @@ public void TestWithExactDuplicateEntriesPasses()
}
[Fact]
- public void TestWithDuplicateEntriesFails()
+ public void DuplicateBundleRelativePath_Fails()
{
- var fixture = sharedTestState.TestFixture.Copy();
-
- var hostName = BundleHelper.GetHostName(fixture);
- var bundleDir = BundleHelper.GetBundleDir(fixture);
- var targetOS = BundleHelper.GetTargetOS(fixture.CurrentRid);
- var targetArch = BundleHelper.GetTargetArch(fixture.CurrentRid);
-
- // Generate a file specification with duplicate entries
- var fileSpecs = new List();
- fileSpecs.Add(new FileSpec(BundleHelper.GetHostPath(fixture), BundleHelper.GetHostName(fixture)));
- fileSpecs.Add(new FileSpec(BundleHelper.GetAppPath(fixture), "rel/app.repeat"));
- fileSpecs.Add(new FileSpec(Path.Join(BundleHelper.GetPublishPath(fixture), "System.dll"), "rel/app.repeat"));
+ // File specification with duplicate entries with different source paths
+ var fileSpecs = new FileSpec[]
+ {
+ new FileSpec(Binaries.AppHost.FilePath, BundlerHostName),
+ new FileSpec(sharedTestState.App.AppDll, "rel/app.repeat"),
+ new FileSpec(sharedTestState.SystemDll, "rel/app.repeat"),
+ };
- Bundler bundler = new Bundler(hostName, bundleDir.FullName, targetOS: targetOS, targetArch: targetArch);
+ Bundler bundler = CreateBundlerInstance();
Assert.Throws(() => bundler.GenerateBundle(fileSpecs))
.Message
.Should().Contain("rel/app.repeat")
- .And.Contain(BundleHelper.GetAppPath(fixture));
+ .And.Contain(sharedTestState.App.AppDll);
}
[Fact]
- public void TestWithCaseSensitiveDuplicateEntriesPasses()
+ public void CaseSensitiveBundleRelativePath()
{
- var fixture = sharedTestState.TestFixture.Copy();
-
- var hostName = BundleHelper.GetHostName(fixture);
- var bundleDir = BundleHelper.GetBundleDir(fixture);
- var targetOS = BundleHelper.GetTargetOS(fixture.CurrentRid);
- var targetArch = BundleHelper.GetTargetArch(fixture.CurrentRid);
-
- // Generate a file specification with duplicate entries
- var fileSpecs = new List();
- fileSpecs.Add(new FileSpec(BundleHelper.GetHostPath(fixture), BundleHelper.GetHostName(fixture)));
- fileSpecs.Add(new FileSpec(BundleHelper.GetAppPath(fixture), "rel/app.repeat.dll"));
- fileSpecs.Add(new FileSpec(Path.Join(BundleHelper.GetPublishPath(fixture), "System.dll"), "rel/app.Repeat.dll"));
+ // File specification with entries with bundle paths differing only in casing
+ var fileSpecs = new FileSpec[]
+ {
+ new FileSpec(Binaries.AppHost.FilePath, BundlerHostName),
+ new FileSpec(sharedTestState.App.AppDll, "rel/app.repeat.dll"),
+ new FileSpec(sharedTestState.SystemDll, "rel/app.Repeat.dll"),
+ };
- Bundler bundler = new Bundler(hostName, bundleDir.FullName, targetOS: targetOS, targetArch: targetArch);
+ Bundler bundler = CreateBundlerInstance();
bundler.GenerateBundle(fileSpecs);
bundler.BundleManifest.Files.Where(entry => entry.RelativePath.Equals("rel/app.repeat.dll")).Single().Type.Should().Be(FileType.Assembly);
@@ -154,27 +130,21 @@ public void TestWithCaseSensitiveDuplicateEntriesPasses()
private (string bundleFileName, string bundleId) CreateSampleBundle(bool bundleMultipleFiles)
{
- var fixture = sharedTestState.TestFixture.Copy();
-
- var hostName = BundleHelper.GetHostName(fixture);
- var bundleDir = Directory.CreateDirectory(
- Path.Combine(BundleHelper.GetBundleDir(fixture).FullName, Path.GetRandomFileName()));
- var targetOS = BundleHelper.GetTargetOS(fixture.CurrentRid);
- var targetArch = BundleHelper.GetTargetArch(fixture.CurrentRid);
-
- var fileSpecs = new List();
- fileSpecs.Add(new FileSpec(BundleHelper.GetHostPath(fixture), BundleHelper.GetHostName(fixture)));
+ var fileSpecs = new List()
+ {
+ new FileSpec(Binaries.AppHost.FilePath, BundlerHostName)
+ };
if (bundleMultipleFiles)
{
- fileSpecs.Add(new FileSpec(BundleHelper.GetAppPath(fixture), "rel/app.repeat.dll"));
+ fileSpecs.Add(new FileSpec(sharedTestState.App.AppDll, "rel/app.repeat.dll"));
}
- Bundler bundler = new Bundler(hostName, bundleDir.FullName, targetOS: targetOS, targetArch: targetArch);
+ Bundler bundler = CreateBundlerInstance();
return (bundler.GenerateBundle(fileSpecs), bundler.BundleManifest.BundleID);
}
[Fact]
- public void TestWithIdenticalBundlesShouldBeBinaryEqualPasses()
+ public void IdenticalBundles_BinaryEqual()
{
var firstBundle = CreateSampleBundle(true);
byte[] firstBundleContent = File.ReadAllBytes(firstBundle.bundleFileName);
@@ -188,7 +158,7 @@ public void TestWithIdenticalBundlesShouldBeBinaryEqualPasses()
}
[Fact]
- public void TestWithUniqueBundlesShouldHaveUniqueBundleIdsPasses()
+ public void UniqueBundles_UniqueBundleIds()
{
string firstBundle = CreateSampleBundle(true).bundleId;
string secondBundle = CreateSampleBundle(false).bundleId;
@@ -197,26 +167,21 @@ public void TestWithUniqueBundlesShouldHaveUniqueBundleIdsPasses()
}
[Fact]
- public void TestWithMultipleDuplicateEntriesFails()
+ public void MultipleDuplicateBundleRelativePath_Fails()
{
- var fixture = sharedTestState.TestFixture.Copy();
-
- var hostName = BundleHelper.GetHostName(fixture);
- var bundleDir = BundleHelper.GetBundleDir(fixture);
- var targetOS = BundleHelper.GetTargetOS(fixture.CurrentRid);
- var targetArch = BundleHelper.GetTargetArch(fixture.CurrentRid);
-
- // Generate a file specification with duplicate entries
- var fileSpecs = new List();
- fileSpecs.Add(new FileSpec(BundleHelper.GetHostPath(fixture), BundleHelper.GetHostName(fixture)));
- string appPath = BundleHelper.GetAppPath(fixture);
- fileSpecs.Add(new FileSpec(appPath, "rel/app.repeat.dll"));
- fileSpecs.Add(new FileSpec(appPath, "rel/app.repeat.dll"));
- string systemLibPath = Path.Join(BundleHelper.GetPublishPath(fixture), "System.dll");
- fileSpecs.Add(new FileSpec(appPath, "rel/system.repeat.dll"));
- fileSpecs.Add(new FileSpec(systemLibPath, "rel/system.repeat.dll"));
-
- Bundler bundler = new Bundler(hostName, bundleDir.FullName, targetOS: targetOS, targetArch: targetArch);
+ // File specification with a mix of duplicate entries with different/matching source paths
+ string appPath = sharedTestState.App.AppDll;
+ string systemLibPath = sharedTestState.SystemDll;
+ var fileSpecs = new FileSpec[]
+ {
+ new FileSpec(Binaries.AppHost.FilePath, BundlerHostName),
+ new FileSpec(appPath, "rel/app.repeat.dll"),
+ new FileSpec(appPath, "rel/app.repeat.dll"),
+ new FileSpec(appPath, "rel/system.repeat.dll"),
+ new FileSpec(systemLibPath, "rel/system.repeat.dll"),
+ };
+
+ Bundler bundler = CreateBundlerInstance();
Assert.Throws(() => bundler.GenerateBundle(fileSpecs))
.Message
.Should().Contain("rel/system.repeat.dll")
@@ -226,41 +191,36 @@ public void TestWithMultipleDuplicateEntriesFails()
}
[Fact]
- public void TestBaseNameComputation()
+ public void BaseNameComputation()
{
- var fixture = sharedTestState.TestFixture.Copy();
- var publishPath = BundleHelper.GetPublishPath(fixture);
- var bundleDir = BundleHelper.GetBundleDir(fixture);
- var targetOS = BundleHelper.GetTargetOS(fixture.CurrentRid);
- var targetArch = BundleHelper.GetTargetArch(fixture.CurrentRid);
-
- // Rename the host from "StandaloneApp" to "Stand.Alone.App" to check that baseName computation
+ // Create an app with multiple periods in its name to check that baseName computation
// (and consequently deps.json and runtimeconfig.json name computations) in the bundler
// work correctly in the presence of "."s in the hostName.
- var originalBaseName = "StandaloneApp";
- var newBaseName = "Stand.Alone.App";
- var exe = OperatingSystem.IsWindows() ? ".exe" : string.Empty;
-
- void rename(string extension)
+ using (var app = TestApp.CreateEmpty("App.With.Periods"))
{
- File.Move(Path.Combine(publishPath, originalBaseName + extension), Path.Combine(publishPath, newBaseName + extension));
+ app.PopulateFrameworkDependent(Constants.MicrosoftNETCoreApp, RepoDirectoriesProvider.Default.MicrosoftNETCoreAppVersion);
+
+ string hostName = Path.GetFileName(app.AppExe);
+ string depsJsonName = Path.GetFileName(app.DepsJson);
+ string runtimeConfigName = Path.GetFileName(app.RuntimeConfigJson);
+ FileSpec[] fileSpecs = new FileSpec[]
+ {
+ new FileSpec(Binaries.AppHost.FilePath, hostName),
+ new FileSpec(app.AppDll, Path.GetRelativePath(app.Location, app.AppDll)),
+ new FileSpec(app.DepsJson, depsJsonName),
+ new FileSpec(app.RuntimeConfigJson, runtimeConfigName),
+ };
+
+ var bundleDir = Directory.CreateDirectory(SharedFramework.CalculateUniqueTestDirectory(Path.Combine(app.Location, "bundle")));
+ var bundler = new Bundler(hostName, bundleDir.FullName);
+ bundler.GenerateBundle(fileSpecs);
+
+
+ bundler.BundleManifest.Files.Where(entry => entry.RelativePath.Equals(depsJsonName)).Single().Type.Should().Be(FileType.DepsJson);
+ bundler.BundleManifest.Files.Where(entry => entry.RelativePath.Equals(runtimeConfigName)).Single().Type.Should().Be(FileType.RuntimeConfigJson);
+ bundleDir.Should().NotHaveFile(depsJsonName);
+ bundleDir.Should().NotHaveFile(runtimeConfigName);
}
- rename(exe);
- rename(".deps.json");
- rename(".runtimeconfig.json");
-
- var hostName = newBaseName + exe;
- var depsJson = newBaseName + ".deps.json";
- var runtimeconfigJson = newBaseName + ".runtimeconfig.json";
-
- var bundler = new Bundler(hostName, bundleDir.FullName, targetOS: targetOS, targetArch: targetArch);
- BundleHelper.GenerateBundle(bundler, publishPath, bundleDir.FullName);
-
- string[] jsonFiles = { depsJson, runtimeconfigJson };
-
- bundler.BundleManifest.Files.Where(entry => entry.RelativePath.Equals(depsJson)).Single().Type.Should().Be(FileType.DepsJson);
- bundler.BundleManifest.Files.Where(entry => entry.RelativePath.Equals(runtimeconfigJson)).Single().Type.Should().Be(FileType.RuntimeConfigJson);
- bundleDir.Should().NotHaveFiles(jsonFiles);
}
[InlineData(BundleOptions.None)]
@@ -269,126 +229,103 @@ void rename(string extension)
[InlineData(BundleOptions.BundleAllContent)]
[InlineData(BundleOptions.BundleSymbolFiles)]
[Theory]
- public void TestFilesAlwaysBundled(BundleOptions options)
+ public void BundleOptions_IncludedExcludedFiles(BundleOptions options)
{
- var fixture = sharedTestState.TestFixture.Copy();
- var bundler = BundleHelper.Bundle(fixture, options);
- var bundledFiles = BundleHelper.GetBundledFiles(fixture);
-
- Array.ForEach(bundledFiles, file => bundler.BundleManifest.Contains(file).Should().BeTrue());
- }
+ TestApp app = sharedTestState.App;
+ string devJsonName = Path.GetFileName(app.RuntimeDevConfigJson);
+ string appSymbolName = $"{app.Name}.pdb";
+ string otherContentName = "other.txt";
+ FileSpec[] fileSpecs = new FileSpec[]
+ {
+ new FileSpec(Binaries.AppHost.FilePath, BundlerHostName),
+ new FileSpec(app.AppDll, Path.GetRelativePath(app.Location, app.AppDll)),
+ new FileSpec(app.DepsJson, Path.GetRelativePath(app.Location, app.DepsJson)),
+ new FileSpec(app.RuntimeConfigJson, Path.GetRelativePath(app.Location, app.RuntimeConfigJson)),
+ new FileSpec(app.RuntimeConfigJson, devJsonName),
+ new FileSpec(Path.Combine(app.Location, appSymbolName), appSymbolName),
+ new FileSpec(Binaries.CoreClr.FilePath, Binaries.CoreClr.FileName),
+ new FileSpec(app.RuntimeConfigJson, otherContentName),
+ };
- [InlineData(BundleOptions.None)]
- [InlineData(BundleOptions.BundleNativeBinaries)]
- [InlineData(BundleOptions.BundleOtherFiles)]
- [InlineData(BundleOptions.BundleAllContent)]
- [InlineData(BundleOptions.BundleSymbolFiles)]
- [Theory]
- public void TestFilesNeverBundled(BundleOptions options)
- {
- var fixture = sharedTestState.TestFixture.Copy();
- var appBaseName = BundleHelper.GetAppBaseName(fixture);
- string publishPath = BundleHelper.GetPublishPath(fixture);
+ Bundler bundler = CreateBundlerInstance(options);
+ bundler.GenerateBundle(fileSpecs);
- // Make up a app.runtimeconfig.dev.json file in the publish directory.
- File.Copy(Path.Combine(publishPath, $"{appBaseName}.runtimeconfig.json"),
- Path.Combine(publishPath, $"{appBaseName}.runtimeconfig.dev.json"));
+ // App's dll, .deps.json, and .runtimeconfig.json should always be bundled
+ Assert.True(bundler.BundleManifest.Contains(Path.GetFileName(app.AppDll)));
+ Assert.True(bundler.BundleManifest.Contains(Path.GetFileName(app.DepsJson)));
+ Assert.True(bundler.BundleManifest.Contains(Path.GetFileName(app.RuntimeConfigJson)));
- var bundler = BundleHelper.Bundle(fixture, options);
+ // App's .runtimeconfig.dev.json is always excluded
+ Assert.False(bundler.BundleManifest.Contains(devJsonName));
- bundler.BundleManifest.Contains($"{appBaseName}.runtimeconfig.dev.json").Should().BeFalse();
- }
+ // Symbols should only be bundled if option is explicitly set
+ bundler.BundleManifest.Contains(appSymbolName).Should().Be(options.HasFlag(BundleOptions.BundleSymbolFiles));
- [InlineData(BundleOptions.None)]
- [InlineData(BundleOptions.BundleSymbolFiles)]
- [Theory]
- public void TestBundlingSymbols(BundleOptions options)
- {
- var fixture = sharedTestState.TestFixture.Copy();
- var appBaseName = BundleHelper.GetAppBaseName(fixture);
- var bundler = BundleHelper.Bundle(fixture, options);
+ // Native libararies should only be bundled if option is explicitly set
+ bundler.BundleManifest.Contains(Binaries.CoreClr.FileName).Should().Be(options.HasFlag(BundleOptions.BundleNativeBinaries));
- bundler.BundleManifest.Contains($"{appBaseName}.pdb").Should().Be(options.HasFlag(BundleOptions.BundleSymbolFiles));
+ // Other files should only be bundled if option is explicitly set
+ bundler.BundleManifest.Contains(otherContentName).Should().Be(options.HasFlag(BundleOptions.BundleOtherFiles));
}
- [InlineData(BundleOptions.None)]
- [InlineData(BundleOptions.BundleNativeBinaries)]
- [Theory]
- public void TestBundlingNativeBinaries(BundleOptions options)
+ [Fact]
+ public void FileSizes()
{
- var fixture = sharedTestState.TestFixture.Copy();
- var coreclr = Path.GetFileName(fixture.TestProject.CoreClrDll);
- var bundler = BundleHelper.Bundle(fixture, options);
+ var app = sharedTestState.App;
+ List fileSpecs = new List
+ {
+ new FileSpec(Binaries.AppHost.FilePath, BundlerHostName),
+ new FileSpec(app.AppDll, Path.GetRelativePath(app.Location, app.AppDll)),
+ new FileSpec(app.DepsJson, Path.GetRelativePath(app.Location, app.DepsJson)),
+ new FileSpec(app.RuntimeConfigJson, Path.GetRelativePath(app.Location, app.RuntimeConfigJson)),
+ };
+ fileSpecs.AddRange(SingleFileTestApp.GetRuntimeFilesToBundle());
- bundler.BundleManifest.Contains($"{coreclr}").Should().Be(options.HasFlag(BundleOptions.BundleNativeBinaries));
+ Bundler bundler = CreateBundlerInstance();
+ bundler.GenerateBundle(fileSpecs);
+ foreach (FileEntry file in bundler.BundleManifest.Files)
+ {
+ var spec = fileSpecs.Single(f => f.BundleRelativePath == file.RelativePath);
+ Assert.True(file.Size == new FileInfo(spec.SourcePath).Length);
+ }
}
[Fact]
- public void TestFileSizes()
+ public void AssemblyAlignment()
{
- var fixture = sharedTestState.TestFixture.Copy();
- var bundler = BundleHelper.Bundle(fixture);
- var publishPath = BundleHelper.GetPublishPath(fixture);
+ var app = sharedTestState.App;
+ List fileSpecs = new List
+ {
+ new FileSpec(Binaries.AppHost.FilePath, BundlerHostName),
+ new FileSpec(app.AppDll, Path.GetRelativePath(app.Location, app.AppDll)),
+ };
+ fileSpecs.AddRange(SingleFileTestApp.GetRuntimeFilesToBundle());
- bundler.BundleManifest.Files.ForEach(file =>
- Assert.True(file.Size == new FileInfo(Path.Combine(publishPath, file.RelativePath)).Length));
- }
+ Bundler bundler = CreateBundlerInstance();
+ bundler.GenerateBundle(fileSpecs);
- [Fact]
- public void TestAssemblyAlignment()
- {
- var fixture = sharedTestState.TestFixture.Copy();
- var bundler = BundleHelper.Bundle(fixture);
- var targetOS = BundleHelper.GetTargetOS(fixture.CurrentRid);
- var targetArch = BundleHelper.GetTargetArch(fixture.CurrentRid);
- var alignment = (targetOS == OSPlatform.Linux && targetArch == Architecture.Arm64) ? 4096 : 16;
+ var alignment = OperatingSystem.IsLinux() && RuntimeInformation.OSArchitecture == Architecture.Arm64 ? 4096 : 16;
bundler.BundleManifest.Files.ForEach(file =>
Assert.True((file.Type != FileType.Assembly) || (file.Offset % alignment == 0)));
}
- [Fact]
- public void TestWithAdditionalContentAfterBundleMetadata()
- {
- var fixture = sharedTestState.TestFixture.Copy();
- string singleFile = BundleHelper.BundleApp(fixture);
-
- using (var file = File.OpenWrite(singleFile))
- {
- file.Position = file.Length;
- var blob = Encoding.UTF8.GetBytes("Mock signature at the end of the bundle");
- file.Write(blob, 0, blob.Length);
- }
-
- Command.Create(singleFile)
- .CaptureStdErr()
- .CaptureStdOut()
- .Execute()
- .Should()
- .Pass()
- .And
- .HaveStdOutContaining("Hello World!");
- }
-
public class SharedTestState : IDisposable
{
- public TestProjectFixture TestFixture { get; set; }
- public RepoDirectoriesProvider RepoDirectories { get; set; }
+ public const string AppName = "HelloWorld";
+ public TestApp App { get; }
+ public string SystemDll { get; }
public SharedTestState()
{
- RepoDirectories = new RepoDirectoriesProvider();
-
- TestFixture = new TestProjectFixture("StandaloneApp", RepoDirectories);
- TestFixture
- .EnsureRestoredForRid(TestFixture.CurrentRid)
- .PublishProject(runtime: TestFixture.CurrentRid,
- selfContained: true,
- outputDirectory: BundleHelper.GetPublishPath(TestFixture));
+ App = TestApp.CreateFromBuiltAssets(AppName);
+
+ var builtDotNet = new DotNet.Cli.Build.DotNetCli(RepoDirectoriesProvider.Default.BuiltDotnet);
+ SystemDll = Path.Combine(builtDotNet.GreatestVersionSharedFxPath, "System.dll");
}
public void Dispose()
{
- TestFixture.Dispose();
+ App.Dispose();
}
}
}
diff --git a/src/installer/tests/TestUtils/Binaries.cs b/src/installer/tests/TestUtils/Binaries.cs
index dc9d109e7def5..9299a76481bed 100644
--- a/src/installer/tests/TestUtils/Binaries.cs
+++ b/src/installer/tests/TestUtils/Binaries.cs
@@ -42,7 +42,7 @@ public static class AppHost
public static class CoreClr
{
public static string FileName = GetSharedLibraryFileNameForCurrentPlatform("coreclr");
- public static string FilePath = Path.Combine(RepoDirectoriesProvider.Default.HostArtifacts, FileName);
+ public static string FilePath = Path.Combine(new DotNetCli(RepoDirectoriesProvider.Default.BuiltDotnet).GreatestVersionSharedFxPath, FileName);
public static string MockName = GetSharedLibraryFileNameForCurrentPlatform("mockcoreclr");
public static string MockPath = Path.Combine(RepoDirectoriesProvider.Default.HostTestArtifacts, MockName);
diff --git a/src/installer/tests/TestUtils/SingleFileTestApp.cs b/src/installer/tests/TestUtils/SingleFileTestApp.cs
index eeeeb8122fba9..356cdb5d5ccea 100644
--- a/src/installer/tests/TestUtils/SingleFileTestApp.cs
+++ b/src/installer/tests/TestUtils/SingleFileTestApp.cs
@@ -60,6 +60,19 @@ private static SingleFileTestApp Create(string appName, bool selfContained)
};
}
+ public static IReadOnlyList GetRuntimeFilesToBundle()
+ {
+ var runtimeAssemblies = Binaries.GetRuntimeFiles().Assemblies;
+ List fileSpecs = new List();
+ foreach (var asset in runtimeAssemblies)
+ {
+ fileSpecs.Add(new FileSpec(asset, Path.GetFileName(asset)));
+ }
+
+ fileSpecs.Sort((a, b) => string.CompareOrdinal(a.BundleRelativePath, b.BundleRelativePath));
+ return fileSpecs;
+ }
+
public string Bundle(BundleOptions options, Version? bundleVersion = null)
{
string bundleDirectory = SharedFramework.CalculateUniqueTestDirectory(Path.Combine(Location, "bundle"));
@@ -81,11 +94,7 @@ public string Bundle(BundleOptions options, Version? bundleVersion = null)
// If this is a self-contained app, add the runtime assemblies to the bundle
if (selfContained)
{
- var runtimeAssemblies = Binaries.GetRuntimeFiles().Assemblies;
- foreach (var asset in runtimeAssemblies)
- {
- fileSpecs.Add(new FileSpec(asset, Path.GetFileName(asset)));
- }
+ fileSpecs.AddRange(GetRuntimeFilesToBundle());
}
// Sort the file specs to keep the bundle construction deterministic.
diff --git a/src/installer/tests/TestUtils/TestApp.cs b/src/installer/tests/TestUtils/TestApp.cs
index f3df7c9f4514c..487903bf41963 100644
--- a/src/installer/tests/TestUtils/TestApp.cs
+++ b/src/installer/tests/TestUtils/TestApp.cs
@@ -50,6 +50,15 @@ public static TestApp CreateEmpty(string name)
};
}
+ public static TestApp CreateFromBuiltAssets(string appName)
+ {
+ TestApp app = CreateEmpty(appName);
+ TestArtifact.CopyRecursive(
+ Path.Combine(RepoDirectoriesProvider.Default.TestAssetsOutput, appName),
+ app.Location);
+ return app;
+ }
+
public void PopulateFrameworkDependent(string fxName, string fxVersion, Action customizer = null)
{
var builder = NetCoreAppBuilder.PortableForNETCoreApp(this);