未验证 提交 1bd62206 编写于 作者: E Elinor Fung 提交者: GitHub

Switch `BundleExtractToSpecificPath` and `BundleAndRun` to using built test assets (#92024)

- Make `BundleExtractToSpecificPath` and `BundleAndRun` tests use built test asset project (`HelloWorld`)
  - The `BundleExtractToSpecificPath` tests explicitly include `mockcoreclr` so that it will have native binaries to bundle
- Remove redundant `BundleAndRun.TestWith*Paths*` tests
  - These were running a self-contained (not bundled) application by invoking it using relative / absolute paths, which does not seem particularly useful. There was no difference in how they bundled the application or ran the bundled application.
- Move codesign check to `BundlerConsistencyTests` - trying to separate tests targeting the `Bundler` API from tests targeting single-file activation
上级 49a0633f
// 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.IO;
using System.Threading;
using BundleTests.Helpers;
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.Threading;
using Xunit;
namespace AppHost.Bundle.Tests
{
public class BundleExtractToSpecificPath : BundleTestBase, IClassFixture<BundleExtractToSpecificPath.SharedTestState>
public class BundleExtractToSpecificPath : IClassFixture<BundleExtractToSpecificPath.SharedTestState>
{
private SharedTestState sharedTestState;
......@@ -25,52 +22,48 @@ public BundleExtractToSpecificPath(SharedTestState fixture)
}
[Fact]
private void Bundle_Extraction_To_Specific_Path_Succeeds()
private void AbsolutePath()
{
var fixture = sharedTestState.TestFixture.Copy();
var hostName = BundleHelper.GetHostName(fixture);
// Publish the bundle
BundleOptions options = BundleOptions.BundleNativeBinaries;
Bundler bundler = BundleSelfContainedApp(fixture, out string singleFile, options);
SingleFileTestApp app = sharedTestState.SelfContainedApp;
var bundledApp = sharedTestState.BundledApp;
// Verify expected files in the bundle directory
var bundleDir = BundleHelper.GetBundleDir(fixture);
bundleDir.Should().HaveFile(hostName);
bundleDir.Should().NotHaveFiles(BundleHelper.GetBundledFiles(fixture));
var bundleDir = Directory.GetParent(bundledApp.Path);
bundleDir.Should().OnlyHaveFiles(new[]
{
Binaries.GetExeFileNameForCurrentPlatform(app.Name),
$"{app.Name}.pdb"
});
// Create a directory for extraction.
var extractBaseDir = BundleHelper.GetExtractionRootDir(fixture);
extractBaseDir.Should().NotHaveDirectory(BundleHelper.GetAppBaseName(fixture));
// Directory for extraction.
string extractBaseDir = app.GetNewExtractionRootPath();
// Run the bundled app for the first time, and extract files to
// $DOTNET_BUNDLE_EXTRACT_BASE_DIR/<app>/bundle-id
Command.Create(singleFile)
Command.Create(bundledApp.Path)
.CaptureStdErr()
.CaptureStdOut()
.EnvironmentVariable(BundleHelper.DotnetBundleExtractBaseEnvVariable, extractBaseDir.FullName)
.EnvironmentVariable(BundleHelper.DotnetBundleExtractBaseEnvVariable, extractBaseDir)
.Execute()
.Should()
.Pass()
.And
.HaveStdOutContaining("Hello World");
var extractDir = BundleHelper.GetExtractionDir(fixture, bundler);
extractDir.Should().HaveFiles(BundleHelper.GetExtractedFiles(fixture, BundleOptions.BundleNativeBinaries));
extractDir.Should().NotHaveFiles(BundleHelper.GetFilesNeverExtracted(fixture));
.Should().Pass()
.And.HaveStdOutContaining("Hello World");
var extractDir = app.GetExtractionDir(extractBaseDir, bundledApp.Manifest);
extractDir.Should().OnlyHaveFiles(BundleHelper.GetExtractedFiles(bundledApp.Manifest, bundledApp.Options));
}
[InlineData("./foo", BundleOptions.BundleAllContent)]
[InlineData("../foo", BundleOptions.BundleAllContent)]
[InlineData("foo", BundleOptions.BundleAllContent)]
[InlineData("foo/bar", BundleOptions.BundleAllContent)]
[InlineData("foo\\bar", BundleOptions.BundleAllContent)]
[InlineData("./foo", BundleOptions.BundleNativeBinaries)]
[InlineData("../foo", BundleOptions.BundleNativeBinaries)]
[InlineData("foo", BundleOptions.BundleNativeBinaries)]
[InlineData("foo/bar", BundleOptions.BundleNativeBinaries)]
[InlineData("foo\\bar", BundleOptions.BundleNativeBinaries)]
[Theory]
private void Bundle_Extraction_To_Relative_Path_Succeeds(string relativePath, BundleOptions bundleOptions)
private void RelativePath(string relativePath, BundleOptions bundleOptions)
{
// As we don't modify user defined environment variables, we will not convert
// any forward slashes to the standard Windows dir separator ('\'), thus
......@@ -84,56 +77,47 @@ private void Bundle_Extraction_To_Relative_Path_Succeeds(string relativePath, Bu
if (relativePath == "foo\\bar" && !OperatingSystem.IsWindows())
return;
var fixture = sharedTestState.TestFixture.Copy();
var bundler = BundleSelfContainedApp(fixture, out var singleFile, bundleOptions);
Manifest manifest;
string singleFile = sharedTestState.SelfContainedApp.Bundle(bundleOptions, out manifest);
// Run the bundled app (extract files to <path>)
var cmd = Command.Create(singleFile);
cmd.WorkingDirectory(Path.GetDirectoryName(singleFile))
Command.Create(singleFile)
.WorkingDirectory(Path.GetDirectoryName(singleFile))
.CaptureStdErr()
.CaptureStdOut()
.EnvironmentVariable(BundleHelper.DotnetBundleExtractBaseEnvVariable, relativePath)
.Execute()
.Should()
.Pass()
.And
.HaveStdOutContaining("Hello World");
var extractedFiles = BundleHelper.GetExtractedFiles(fixture, bundleOptions);
var extractedDir = new DirectoryInfo(Path.Combine(Path.GetDirectoryName(singleFile),
relativePath,
fixture.TestProject.ProjectName,
bundler.BundleManifest.BundleID));
extractedDir.Should().HaveFiles(extractedFiles);
.Should().Pass()
.And.HaveStdOutContaining("Hello World");
using (TestArtifact extractionRoot = new TestArtifact(Path.Combine(Path.GetDirectoryName(singleFile), relativePath)))
{
var extractedDir = sharedTestState.SelfContainedApp.GetExtractionDir(extractionRoot.Location, manifest);
var extractedFiles = BundleHelper.GetExtractedFiles(manifest, bundleOptions);
extractedDir.Should().OnlyHaveFiles(extractedFiles);
}
}
[Fact]
private void Bundle_extraction_is_reused()
private void ExtractionDirectoryReused()
{
var fixture = sharedTestState.TestFixture.Copy();
// Publish the bundle
BundleOptions options = BundleOptions.BundleNativeBinaries;
Bundler bundler = BundleSelfContainedApp(fixture, out string singleFile, options);
SingleFileTestApp app = sharedTestState.SelfContainedApp;
var bundledApp = sharedTestState.BundledApp;
// Create a directory for extraction.
var extractBaseDir = BundleHelper.GetExtractionRootDir(fixture);
// Directory for extraction.
string extractBaseDir = app.GetNewExtractionRootPath();
// Run the bunded app for the first time, and extract files to
// $DOTNET_BUNDLE_EXTRACT_BASE_DIR/<app>/bundle-id
Command.Create(singleFile)
Command.Create(bundledApp.Path)
.CaptureStdErr()
.CaptureStdOut()
.EnvironmentVariable(BundleHelper.DotnetBundleExtractBaseEnvVariable, extractBaseDir.FullName)
.EnvironmentVariable(BundleHelper.DotnetBundleExtractBaseEnvVariable, extractBaseDir)
.Execute()
.Should()
.Pass()
.And
.HaveStdOutContaining("Hello World");
var extractDir = BundleHelper.GetExtractionDir(fixture, bundler);
.Should().Pass()
.And.HaveStdOutContaining("Hello World");
var extractDir = app.GetExtractionDir(extractBaseDir, bundledApp.Manifest);
extractDir.Refresh();
DateTime firstWriteTime = extractDir.LastWriteTimeUtc;
......@@ -143,73 +127,63 @@ private void Bundle_extraction_is_reused()
}
// Run the bundled app again (reuse extracted files)
Command.Create(singleFile)
Command.Create(bundledApp.Path)
.CaptureStdErr()
.CaptureStdOut()
.EnvironmentVariable(BundleHelper.DotnetBundleExtractBaseEnvVariable, extractBaseDir.FullName)
.EnvironmentVariable(BundleHelper.DotnetBundleExtractBaseEnvVariable, extractBaseDir)
.Execute()
.Should()
.Pass()
.And
.HaveStdOutContaining("Hello World");
.Should().Pass()
.And.HaveStdOutContaining("Hello World");
extractDir.Should().NotBeModifiedAfter(firstWriteTime);
}
[Fact]
private void Bundle_extraction_can_recover_missing_files()
private void RecoverMissingFiles()
{
var fixture = sharedTestState.TestFixture.Copy();
var hostName = BundleHelper.GetHostName(fixture);
var appName = Path.GetFileNameWithoutExtension(hostName);
SingleFileTestApp app = sharedTestState.SelfContainedApp;
var bundledApp = sharedTestState.BundledApp;
// Publish the bundle
BundleOptions options = BundleOptions.BundleNativeBinaries;
Bundler bundler = BundleSelfContainedApp(fixture, out string singleFile, options);
// Create a directory for extraction.
var extractBaseDir = BundleHelper.GetExtractionRootDir(fixture);
// Directory for extraction.
string extractBaseDir = app.GetNewExtractionRootPath();
// Run the bunded app for the first time, and extract files to
// $DOTNET_BUNDLE_EXTRACT_BASE_DIR/<app>/bundle-id
Command.Create(singleFile)
Command.Create(bundledApp.Path)
.CaptureStdErr()
.CaptureStdOut()
.EnvironmentVariable(BundleHelper.DotnetBundleExtractBaseEnvVariable, extractBaseDir.FullName)
.EnvironmentVariable(BundleHelper.DotnetBundleExtractBaseEnvVariable, extractBaseDir)
.Execute()
.Should()
.Pass()
.And
.HaveStdOutContaining("Hello World");
.Should().Pass()
.And.HaveStdOutContaining("Hello World");
// Remove the extracted files, but keep the extraction directory
var extractDir = BundleHelper.GetExtractionDir(fixture, bundler);
var extractedFiles = BundleHelper.GetExtractedFiles(fixture, BundleOptions.BundleNativeBinaries);
var extractDir = app.GetExtractionDir(extractBaseDir, bundledApp.Manifest);
var extractedFiles = BundleHelper.GetExtractedFiles(bundledApp.Manifest, bundledApp.Options);
Array.ForEach(extractedFiles, file => File.Delete(Path.Combine(extractDir.FullName, file)));
foreach (string file in extractedFiles)
File.Delete(Path.Combine(extractDir.FullName, file));
extractDir.Should().Exist();
extractDir.Should().NotHaveFiles(extractedFiles);
// Run the bundled app again (recover deleted files)
Command.Create(singleFile)
Command.Create(bundledApp.Path)
.CaptureStdErr()
.CaptureStdOut()
.EnvironmentVariable(BundleHelper.DotnetBundleExtractBaseEnvVariable, extractBaseDir.FullName)
.EnvironmentVariable(BundleHelper.DotnetBundleExtractBaseEnvVariable, extractBaseDir)
.Execute()
.Should()
.Pass()
.And
.HaveStdOutContaining("Hello World");
.Should().Pass()
.And.HaveStdOutContaining("Hello World");
extractDir.Should().HaveFiles(extractedFiles);
extractDir.Should().OnlyHaveFiles(extractedFiles);
}
[Fact]
private void Bundle_extraction_to_nonexisting_default()
private void NonexistentDefault_Fails()
{
string nonExistentPath = Path.Combine(
sharedTestState.DefaultBundledAppFixture.TestProject.OutputDirectory,
Path.GetDirectoryName(sharedTestState.BundledApp.Path),
"nonexistent");
string defaultExpansionEnvVariable = OperatingSystem.IsWindows() ? "TMP" : "HOME";
......@@ -217,7 +191,7 @@ private void Bundle_extraction_to_nonexisting_default()
$"Failed to determine default extraction location. Check if 'TMP'" :
$"Default extraction directory [{nonExistentPath}] either doesn't exist or is not accessible for read/write.";
Command.Create(sharedTestState.DefaultBundledAppExecutablePath)
Command.Create(sharedTestState.BundledApp.Path)
.CaptureStdErr()
.CaptureStdOut()
.EnvironmentVariable(defaultExpansionEnvVariable, nonExistentPath)
......@@ -227,56 +201,51 @@ private void Bundle_extraction_to_nonexisting_default()
[Fact]
[SkipOnPlatform(TestPlatforms.Windows, "On Windows the default extraction path is determined by calling GetTempPath which looks at multiple places and can't really be undefined.")]
private void Bundle_extraction_fallsback_to_getpwuid_when_HOME_env_var_is_undefined()
private void UndefinedHOME_getpwuidFallback()
{
string home = Environment.GetEnvironmentVariable("HOME");
// suppose we are testing on a system where HOME is not set, use System.Environment (which also fallsback to getpwuid)
if (string.IsNullOrEmpty(home))
{
// HOME is not set. Use System.Environment (which also fallsback to getpwuid)
home = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile);
}
DirectoryInfo sharedExtractDirInfo = BundleHelper.GetExtractionDir(sharedTestState.TestFixture, sharedTestState.DefaultBundledAppBundler);
string sharedExtractDir = sharedExtractDirInfo.FullName;
string extractDirSubPath = sharedExtractDir.Substring(sharedExtractDir.LastIndexOf("extract/") + "extract/".Length);
string realExtractDir = Path.Combine(home, ".net", extractDirSubPath);
var expectedExtractDir = new DirectoryInfo(realExtractDir);
Command.Create(sharedTestState.DefaultBundledAppExecutablePath)
var bundledApp = sharedTestState.BundledApp;
Command.Create(bundledApp.Path)
.CaptureStdErr()
.CaptureStdOut()
.EnvironmentVariable("HOME", null)
.Execute()
.Should()
.Pass()
.And
.HaveStdOutContaining("Hello World");
.Should().Pass()
.And.HaveStdOutContaining("Hello World");
var extractedFiles = BundleHelper.GetExtractedFiles(sharedTestState.TestFixture, BundleOptions.BundleNativeBinaries);
DirectoryInfo expectedExtractDir = sharedTestState.SelfContainedApp.GetExtractionDir(Path.Combine(home, ".net"), bundledApp.Manifest);
var extractedFiles = BundleHelper.GetExtractedFiles(bundledApp.Manifest, bundledApp.Options);
expectedExtractDir.Should().HaveFiles(extractedFiles);
}
public class SharedTestState : SharedTestStateBase, IDisposable
public class SharedTestState : IDisposable
{
public TestProjectFixture TestFixture { get; }
public (string Path, Manifest Manifest, BundleOptions Options) BundledApp{ get; }
public TestProjectFixture DefaultBundledAppFixture { get; }
public string DefaultBundledAppExecutablePath { get; }
public Bundler DefaultBundledAppBundler { get; }
public SingleFileTestApp SelfContainedApp { get; }
public SharedTestState()
{
TestFixture = PreparePublishedSelfContainedTestProject("StandaloneApp");
SelfContainedApp = SingleFileTestApp.CreateSelfContained("HelloWorld");
// Copy over mockcoreclr so that the app will have a native binary
File.Copy(Binaries.CoreClr.MockPath, Path.Combine(SelfContainedApp.NonBundledLocation, Binaries.CoreClr.MockName));
DefaultBundledAppFixture = TestFixture.Copy();
DefaultBundledAppBundler = BundleSelfContainedApp(DefaultBundledAppFixture, out var singleFile, BundleOptions.BundleNativeBinaries);
DefaultBundledAppExecutablePath = singleFile;
// Create a bundled app that can be used by multiple tests
BundleOptions options = BundleOptions.BundleNativeBinaries;
string bundlePath = SelfContainedApp.Bundle(options, out Manifest manifest);
BundledApp = (bundlePath, manifest, options);
}
public void Dispose()
{
DefaultBundledAppFixture.Dispose();
TestFixture.Dispose();
SelfContainedApp.Dispose();
}
}
}
......
......@@ -52,46 +52,39 @@ public static string GetAppBaseName(TestProjectFixture fixture)
return Path.GetFileNameWithoutExtension(GetAppName(fixture));
}
public static string[] GetBundledFiles(TestProjectFixture fixture)
public static List<string> GetExtractedFiles(Manifest manifest, BundleOptions bundleOptions)
{
string appBaseName = GetAppBaseName(fixture);
return new string[] { $"{appBaseName}.dll", $"{appBaseName}.deps.json", $"{appBaseName}.runtimeconfig.json" };
}
public static string[] GetExtractedFiles(TestProjectFixture fixture, BundleOptions bundleOptions)
{
switch (bundleOptions & ~BundleOptions.EnableCompression)
List<string> expected = new List<string>();
foreach (FileEntry file in manifest.Files)
{
case BundleOptions.None:
case BundleOptions.BundleOtherFiles:
case BundleOptions.BundleSymbolFiles:
throw new ArgumentException($"Bundle option {bundleOptions} doesn't extract any files to disk.");
if (!ShouldBeExtracted(file.Type, bundleOptions))
continue;
case BundleOptions.BundleAllContent:
return Directory.GetFiles(GetPublishPath(fixture))
.Select(f => Path.GetFileName(f))
.Except(GetFilesNeverExtracted(fixture)).ToArray();
expected.Add(file.RelativePath);
}
case BundleOptions.BundleNativeBinaries:
return new string[] { Path.GetFileName(fixture.TestProject.CoreClrDll) };
return expected;
default:
throw new ArgumentException("Unsupported bundle option.");
static bool ShouldBeExtracted(FileType type, BundleOptions options)
{
switch (type)
{
case FileType.Assembly:
case FileType.DepsJson:
case FileType.RuntimeConfigJson:
return options.HasFlag(BundleOptions.BundleAllContent);
case FileType.NativeBinary:
return options.HasFlag(BundleOptions.BundleNativeBinaries);
case FileType.Symbols:
return options.HasFlag(BundleOptions.BundleSymbolFiles);
case FileType.Unknown:
return options.HasFlag(BundleOptions.BundleOtherFiles);
default:
return false;
}
}
}
public static string[] GetFilesNeverExtracted(TestProjectFixture fixture)
{
string appBaseName = GetAppBaseName(fixture);
return new string[] { $"{appBaseName}",
$"{appBaseName}.dll",
$"{appBaseName}.exe",
$"{appBaseName}.pdb",
$"{appBaseName}.runtimeconfig.dev.json",
Path.GetFileName(fixture.TestProject.HostFxrDll),
Path.GetFileName(fixture.TestProject.HostPolicyDll) };
}
public static string GetPublishPath(TestProjectFixture fixture)
{
return Path.Combine(fixture.TestProject.ProjectDirectory, "publish");
......
......@@ -21,33 +21,21 @@ public BundleAndRun(BundleAndRun.SharedTestState fixture)
sharedTestState = fixture;
}
private void RunTheApp(string path)
private void RunTheApp(string path, bool selfContained)
{
Command.Create(path)
.CaptureStdErr()
.CaptureStdOut()
.DotNetRoot(selfContained ? null : RepoDirectoriesProvider.Default.BuiltDotnet)
.Execute()
.Should()
.Pass()
.And
.HaveStdOutContaining("Hello World!");
}
private void CheckFileSigned(string path)
{
// Check if the file is signed (it should have been signed by the bundler)
Command.Create("codesign", $"-v {path}")
.CaptureStdErr()
.CaptureStdOut()
.Execute()
.Should()
.Pass();
.Should().Pass()
.And.HaveStdOutContaining("Hello World!");
}
private string MakeUniversalBinary(string path, string rid)
private string MakeUniversalBinary(string path, Architecture architecture)
{
string fatApp = path + ".fat";
string arch = BundleHelper.GetTargetArch(rid) == Architecture.Arm64 ? "arm64" : "x86_64";
string arch = architecture == Architecture.Arm64 ? "arm64" : "x86_64";
// We will create a universal binary with just one arch slice and run it.
// It is enough for testing purposes. The code that finds the releavant slice
......@@ -62,70 +50,36 @@ private string MakeUniversalBinary(string path, string rid)
return fatApp;
}
private void BundleRun(TestProjectFixture fixture, string publishPath)
[Theory]
[InlineData(true)]
[InlineData(false)]
private void RunApp(bool selfContained)
{
var hostName = BundleHelper.GetHostName(fixture);
// Run the App normally
RunTheApp(Path.Combine(publishPath, hostName));
// Bundle to a single-file
string singleFile = BundleHelper.BundleApp(fixture);
string singleFile = selfContained
? sharedTestState.SelfContainedApp.Bundle()
: sharedTestState.FrameworkDependentApp.Bundle();
// check that the file structure is understood by codesign
var targetOS = BundleHelper.GetTargetOS(fixture.CurrentRid);
if (targetOS == OSPlatform.OSX)
{
CheckFileSigned(singleFile);
}
// Run the bundled app
RunTheApp(singleFile, selfContained);
// Run the extracted app
RunTheApp(singleFile);
if (targetOS == OSPlatform.OSX)
if (OperatingSystem.IsMacOS())
{
string fatApp = MakeUniversalBinary(singleFile, fixture.CurrentRid);
string fatApp = MakeUniversalBinary(singleFile, RuntimeInformation.OSArchitecture);
// Run the fat app
RunTheApp(fatApp);
RunTheApp(fatApp, selfContained);
}
}
private string RelativePath(string path)
[Theory]
[InlineData(true)]
[InlineData(false)]
public void AdditionalContentAfterBundleMetadata(bool selfContained)
{
return Path.GetRelativePath(Directory.GetCurrentDirectory(), path)
.TrimEnd(Path.DirectorySeparatorChar);
}
[Fact]
public void TestWithAbsolutePaths()
{
var fixture = sharedTestState.TestFixture.Copy();
string publishDir = BundleHelper.GetPublishPath(fixture);
BundleRun(fixture, publishDir);
}
[Fact]
public void TestWithRelativePaths()
{
var fixture = sharedTestState.TestFixture.Copy();
string publishDir = RelativePath(BundleHelper.GetPublishPath(fixture));
BundleRun(fixture, publishDir);
}
[Fact]
public void TestWithRelativePathsDirSeparator()
{
var fixture = sharedTestState.TestFixture.Copy();
string publishDir = RelativePath(BundleHelper.GetPublishPath(fixture)) + Path.DirectorySeparatorChar;
BundleRun(fixture, publishDir);
}
[Fact]
public void TestWithAdditionalContentAfterBundleMetadata()
{
var fixture = sharedTestState.TestFixture.Copy();
string singleFile = BundleHelper.BundleApp(fixture);
string singleFile = selfContained
? sharedTestState.SelfContainedApp.Bundle()
: sharedTestState.FrameworkDependentApp.Bundle();
using (var file = File.OpenWrite(singleFile))
{
......@@ -134,35 +88,24 @@ public void TestWithAdditionalContentAfterBundleMetadata()
file.Write(blob, 0, blob.Length);
}
Command.Create(singleFile)
.CaptureStdErr()
.CaptureStdOut()
.Execute()
.Should().Pass()
.And.HaveStdOutContaining("Hello World!");
RunTheApp(singleFile, selfContained);
}
public class SharedTestState : IDisposable
{
public TestProjectFixture TestFixture { get; set; }
public TestProjectFixture LegacyFixture { get; set; }
public RepoDirectoriesProvider RepoDirectories { get; set; }
public SingleFileTestApp FrameworkDependentApp { get; }
public SingleFileTestApp SelfContainedApp { 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));
FrameworkDependentApp = SingleFileTestApp.CreateFrameworkDependent("HelloWorld");
SelfContainedApp = SingleFileTestApp.CreateSelfContained("HelloWorld");
}
public void Dispose()
{
TestFixture.Dispose();
FrameworkDependentApp.Dispose();
SelfContainedApp.Dispose();
}
}
}
......
......@@ -7,6 +7,7 @@
using System.Linq;
using System.Runtime.InteropServices;
using FluentAssertions;
using Microsoft.DotNet.Cli.Build.Framework;
using Microsoft.DotNet.CoreSetup.Test;
using Microsoft.NET.HostModel.Bundle;
using Xunit;
......@@ -23,8 +24,8 @@ public BundlerConsistencyTests(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);
private Bundler CreateBundlerInstance(BundleOptions bundleOptions = BundleOptions.None, Version version = null, bool macosCodesign = true)
=> new Bundler(BundlerHostName, SharedFramework.CalculateUniqueTestDirectory($"{sharedTestState.App.Location}-bundle"), bundleOptions, targetFrameworkVersion: version, macosCodesign: macosCodesign);
[Fact]
public void EnableCompression_Before60_Fails()
......@@ -309,6 +310,40 @@ public void AssemblyAlignment()
Assert.True((file.Type != FileType.Assembly) || (file.Offset % alignment == 0)));
}
[Theory]
[InlineData(true)]
[InlineData(false)]
[PlatformSpecific(TestPlatforms.OSX)]
public void Codesign(bool shouldCodesign)
{
TestApp app = sharedTestState.App;
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)),
};
Bundler bundler = CreateBundlerInstance(macosCodesign: shouldCodesign);
string bundledApp = bundler.GenerateBundle(fileSpecs);
// Check if the file is signed
CommandResult result = Command.Create("codesign", $"-v {bundledApp}")
.CaptureStdErr()
.CaptureStdOut()
.Execute(expectedToFail: !shouldCodesign);
if (shouldCodesign)
{
result.Should().Pass();
}
else
{
result.Should().Fail();
}
}
public class SharedTestState : IDisposable
{
public const string AppName = "HelloWorld";
......
......@@ -73,7 +73,12 @@ public static IReadOnlyList<FileSpec> GetRuntimeFilesToBundle()
return fileSpecs;
}
public string Bundle(BundleOptions options, Version? bundleVersion = null)
public string Bundle(BundleOptions options = BundleOptions.None, Version? bundleVersion = null)
{
return Bundle(options, out _, bundleVersion);
}
public string Bundle(BundleOptions options, out Manifest manifest, Version? bundleVersion = null)
{
string bundleDirectory = SharedFramework.CalculateUniqueTestDirectory(Path.Combine(Location, "bundle"));
var bundler = new Bundler(
......@@ -113,9 +118,20 @@ public string Bundle(BundleOptions options, Version? bundleVersion = null)
File.Copy(spec.SourcePath, outputFilePath, true);
}
manifest = bundler.BundleManifest;
return singleFile;
}
public string GetNewExtractionRootPath()
{
return SharedFramework.CalculateUniqueTestDirectory(Path.Combine(Location, "extract"));
}
public DirectoryInfo GetExtractionDir(string root, Manifest manifest)
{
return new DirectoryInfo(Path.Combine(root, Name, manifest.BundleID));
}
private void PopulateBuiltAppDirectory()
{
// Copy the compiled app output - the app is expected to have been built as framework-dependent
......
......@@ -63,7 +63,7 @@ pal::string_t& extractor_t::extraction_dir()
append_path(&m_extraction_dir, host_name.c_str());
append_path(&m_extraction_dir, m_bundle_id.c_str());
trace::info(_X("Files embedded within the bundled will be extracted to [%s] directory."), m_extraction_dir.c_str());
trace::info(_X("Files embedded within the bundle will be extracted to [%s] directory."), m_extraction_dir.c_str());
}
return m_extraction_dir;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册