Skip to content

Commit 1bd6220

Browse files
authored
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
1 parent 49a0633 commit 1bd6220

File tree

6 files changed

+204
-248
lines changed

6 files changed

+204
-248
lines changed

src/installer/tests/Microsoft.NET.HostModel.Tests/AppHost.Bundle.Tests/BundleExtractToSpecificPath.cs

Lines changed: 92 additions & 123 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,18 @@
11
// Licensed to the .NET Foundation under one or more agreements.
22
// The .NET Foundation licenses this file to you under the MIT license.
33

4+
using System;
5+
using System.IO;
6+
using System.Threading;
47
using BundleTests.Helpers;
58
using Microsoft.DotNet.Cli.Build.Framework;
69
using Microsoft.DotNet.CoreSetup.Test;
710
using Microsoft.NET.HostModel.Bundle;
8-
using System;
9-
using System.Collections.Generic;
10-
using System.IO;
11-
using System.Linq;
12-
using System.Runtime.InteropServices;
13-
using System.Threading;
1411
using Xunit;
1512

1613
namespace AppHost.Bundle.Tests
1714
{
18-
public class BundleExtractToSpecificPath : BundleTestBase, IClassFixture<BundleExtractToSpecificPath.SharedTestState>
15+
public class BundleExtractToSpecificPath : IClassFixture<BundleExtractToSpecificPath.SharedTestState>
1916
{
2017
private SharedTestState sharedTestState;
2118

@@ -25,52 +22,48 @@ public BundleExtractToSpecificPath(SharedTestState fixture)
2522
}
2623

2724
[Fact]
28-
private void Bundle_Extraction_To_Specific_Path_Succeeds()
25+
private void AbsolutePath()
2926
{
30-
var fixture = sharedTestState.TestFixture.Copy();
31-
var hostName = BundleHelper.GetHostName(fixture);
32-
33-
// Publish the bundle
34-
BundleOptions options = BundleOptions.BundleNativeBinaries;
35-
Bundler bundler = BundleSelfContainedApp(fixture, out string singleFile, options);
27+
SingleFileTestApp app = sharedTestState.SelfContainedApp;
28+
var bundledApp = sharedTestState.BundledApp;
3629

3730
// Verify expected files in the bundle directory
38-
var bundleDir = BundleHelper.GetBundleDir(fixture);
39-
bundleDir.Should().HaveFile(hostName);
40-
bundleDir.Should().NotHaveFiles(BundleHelper.GetBundledFiles(fixture));
31+
var bundleDir = Directory.GetParent(bundledApp.Path);
32+
bundleDir.Should().OnlyHaveFiles(new[]
33+
{
34+
Binaries.GetExeFileNameForCurrentPlatform(app.Name),
35+
$"{app.Name}.pdb"
36+
});
4137

42-
// Create a directory for extraction.
43-
var extractBaseDir = BundleHelper.GetExtractionRootDir(fixture);
44-
extractBaseDir.Should().NotHaveDirectory(BundleHelper.GetAppBaseName(fixture));
38+
// Directory for extraction.
39+
string extractBaseDir = app.GetNewExtractionRootPath();
4540

4641
// Run the bundled app for the first time, and extract files to
4742
// $DOTNET_BUNDLE_EXTRACT_BASE_DIR/<app>/bundle-id
48-
Command.Create(singleFile)
43+
Command.Create(bundledApp.Path)
4944
.CaptureStdErr()
5045
.CaptureStdOut()
51-
.EnvironmentVariable(BundleHelper.DotnetBundleExtractBaseEnvVariable, extractBaseDir.FullName)
46+
.EnvironmentVariable(BundleHelper.DotnetBundleExtractBaseEnvVariable, extractBaseDir)
5247
.Execute()
53-
.Should()
54-
.Pass()
55-
.And
56-
.HaveStdOutContaining("Hello World");
57-
58-
var extractDir = BundleHelper.GetExtractionDir(fixture, bundler);
59-
extractDir.Should().HaveFiles(BundleHelper.GetExtractedFiles(fixture, BundleOptions.BundleNativeBinaries));
60-
extractDir.Should().NotHaveFiles(BundleHelper.GetFilesNeverExtracted(fixture));
48+
.Should().Pass()
49+
.And.HaveStdOutContaining("Hello World");
50+
51+
var extractDir = app.GetExtractionDir(extractBaseDir, bundledApp.Manifest);
52+
extractDir.Should().OnlyHaveFiles(BundleHelper.GetExtractedFiles(bundledApp.Manifest, bundledApp.Options));
6153
}
6254

6355
[InlineData("./foo", BundleOptions.BundleAllContent)]
6456
[InlineData("../foo", BundleOptions.BundleAllContent)]
6557
[InlineData("foo", BundleOptions.BundleAllContent)]
6658
[InlineData("foo/bar", BundleOptions.BundleAllContent)]
59+
[InlineData("foo\\bar", BundleOptions.BundleAllContent)]
6760
[InlineData("./foo", BundleOptions.BundleNativeBinaries)]
6861
[InlineData("../foo", BundleOptions.BundleNativeBinaries)]
6962
[InlineData("foo", BundleOptions.BundleNativeBinaries)]
7063
[InlineData("foo/bar", BundleOptions.BundleNativeBinaries)]
7164
[InlineData("foo\\bar", BundleOptions.BundleNativeBinaries)]
7265
[Theory]
73-
private void Bundle_Extraction_To_Relative_Path_Succeeds(string relativePath, BundleOptions bundleOptions)
66+
private void RelativePath(string relativePath, BundleOptions bundleOptions)
7467
{
7568
// As we don't modify user defined environment variables, we will not convert
7669
// 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
8477
if (relativePath == "foo\\bar" && !OperatingSystem.IsWindows())
8578
return;
8679

87-
var fixture = sharedTestState.TestFixture.Copy();
88-
var bundler = BundleSelfContainedApp(fixture, out var singleFile, bundleOptions);
80+
Manifest manifest;
81+
string singleFile = sharedTestState.SelfContainedApp.Bundle(bundleOptions, out manifest);
8982

9083
// Run the bundled app (extract files to <path>)
91-
var cmd = Command.Create(singleFile);
92-
cmd.WorkingDirectory(Path.GetDirectoryName(singleFile))
84+
Command.Create(singleFile)
85+
.WorkingDirectory(Path.GetDirectoryName(singleFile))
9386
.CaptureStdErr()
9487
.CaptureStdOut()
9588
.EnvironmentVariable(BundleHelper.DotnetBundleExtractBaseEnvVariable, relativePath)
9689
.Execute()
97-
.Should()
98-
.Pass()
99-
.And
100-
.HaveStdOutContaining("Hello World");
101-
102-
var extractedFiles = BundleHelper.GetExtractedFiles(fixture, bundleOptions);
103-
var extractedDir = new DirectoryInfo(Path.Combine(Path.GetDirectoryName(singleFile),
104-
relativePath,
105-
fixture.TestProject.ProjectName,
106-
bundler.BundleManifest.BundleID));
107-
108-
extractedDir.Should().HaveFiles(extractedFiles);
90+
.Should().Pass()
91+
.And.HaveStdOutContaining("Hello World");
92+
93+
using (TestArtifact extractionRoot = new TestArtifact(Path.Combine(Path.GetDirectoryName(singleFile), relativePath)))
94+
{
95+
var extractedDir = sharedTestState.SelfContainedApp.GetExtractionDir(extractionRoot.Location, manifest);
96+
var extractedFiles = BundleHelper.GetExtractedFiles(manifest, bundleOptions);
97+
extractedDir.Should().OnlyHaveFiles(extractedFiles);
98+
}
10999
}
110100

111101
[Fact]
112-
private void Bundle_extraction_is_reused()
102+
private void ExtractionDirectoryReused()
113103
{
114-
var fixture = sharedTestState.TestFixture.Copy();
115-
116-
// Publish the bundle
117-
BundleOptions options = BundleOptions.BundleNativeBinaries;
118-
Bundler bundler = BundleSelfContainedApp(fixture, out string singleFile, options);
104+
SingleFileTestApp app = sharedTestState.SelfContainedApp;
105+
var bundledApp = sharedTestState.BundledApp;
119106

120-
// Create a directory for extraction.
121-
var extractBaseDir = BundleHelper.GetExtractionRootDir(fixture);
107+
// Directory for extraction.
108+
string extractBaseDir = app.GetNewExtractionRootPath();
122109

123110
// Run the bunded app for the first time, and extract files to
124111
// $DOTNET_BUNDLE_EXTRACT_BASE_DIR/<app>/bundle-id
125-
Command.Create(singleFile)
112+
Command.Create(bundledApp.Path)
126113
.CaptureStdErr()
127114
.CaptureStdOut()
128-
.EnvironmentVariable(BundleHelper.DotnetBundleExtractBaseEnvVariable, extractBaseDir.FullName)
115+
.EnvironmentVariable(BundleHelper.DotnetBundleExtractBaseEnvVariable, extractBaseDir)
129116
.Execute()
130-
.Should()
131-
.Pass()
132-
.And
133-
.HaveStdOutContaining("Hello World");
134-
135-
var extractDir = BundleHelper.GetExtractionDir(fixture, bundler);
117+
.Should().Pass()
118+
.And.HaveStdOutContaining("Hello World");
136119

120+
var extractDir = app.GetExtractionDir(extractBaseDir, bundledApp.Manifest);
137121
extractDir.Refresh();
138122
DateTime firstWriteTime = extractDir.LastWriteTimeUtc;
139123

@@ -143,81 +127,71 @@ private void Bundle_extraction_is_reused()
143127
}
144128

145129
// Run the bundled app again (reuse extracted files)
146-
Command.Create(singleFile)
130+
Command.Create(bundledApp.Path)
147131
.CaptureStdErr()
148132
.CaptureStdOut()
149-
.EnvironmentVariable(BundleHelper.DotnetBundleExtractBaseEnvVariable, extractBaseDir.FullName)
133+
.EnvironmentVariable(BundleHelper.DotnetBundleExtractBaseEnvVariable, extractBaseDir)
150134
.Execute()
151-
.Should()
152-
.Pass()
153-
.And
154-
.HaveStdOutContaining("Hello World");
135+
.Should().Pass()
136+
.And.HaveStdOutContaining("Hello World");
155137

156138
extractDir.Should().NotBeModifiedAfter(firstWriteTime);
157139
}
158140

159141
[Fact]
160-
private void Bundle_extraction_can_recover_missing_files()
142+
private void RecoverMissingFiles()
161143
{
162-
var fixture = sharedTestState.TestFixture.Copy();
163-
var hostName = BundleHelper.GetHostName(fixture);
164-
var appName = Path.GetFileNameWithoutExtension(hostName);
144+
SingleFileTestApp app = sharedTestState.SelfContainedApp;
145+
var bundledApp = sharedTestState.BundledApp;
165146

166-
// Publish the bundle
167-
BundleOptions options = BundleOptions.BundleNativeBinaries;
168-
Bundler bundler = BundleSelfContainedApp(fixture, out string singleFile, options);
169-
170-
// Create a directory for extraction.
171-
var extractBaseDir = BundleHelper.GetExtractionRootDir(fixture);
147+
// Directory for extraction.
148+
string extractBaseDir = app.GetNewExtractionRootPath();
172149

173150
// Run the bunded app for the first time, and extract files to
174151
// $DOTNET_BUNDLE_EXTRACT_BASE_DIR/<app>/bundle-id
175-
Command.Create(singleFile)
152+
Command.Create(bundledApp.Path)
176153
.CaptureStdErr()
177154
.CaptureStdOut()
178-
.EnvironmentVariable(BundleHelper.DotnetBundleExtractBaseEnvVariable, extractBaseDir.FullName)
155+
.EnvironmentVariable(BundleHelper.DotnetBundleExtractBaseEnvVariable, extractBaseDir)
179156
.Execute()
180-
.Should()
181-
.Pass()
182-
.And
183-
.HaveStdOutContaining("Hello World");
157+
.Should().Pass()
158+
.And.HaveStdOutContaining("Hello World");
184159

185160
// Remove the extracted files, but keep the extraction directory
186-
var extractDir = BundleHelper.GetExtractionDir(fixture, bundler);
187-
var extractedFiles = BundleHelper.GetExtractedFiles(fixture, BundleOptions.BundleNativeBinaries);
161+
var extractDir = app.GetExtractionDir(extractBaseDir, bundledApp.Manifest);
162+
var extractedFiles = BundleHelper.GetExtractedFiles(bundledApp.Manifest, bundledApp.Options);
188163

189-
Array.ForEach(extractedFiles, file => File.Delete(Path.Combine(extractDir.FullName, file)));
164+
foreach (string file in extractedFiles)
165+
File.Delete(Path.Combine(extractDir.FullName, file));
190166

191167
extractDir.Should().Exist();
192168
extractDir.Should().NotHaveFiles(extractedFiles);
193169

194170
// Run the bundled app again (recover deleted files)
195-
Command.Create(singleFile)
171+
Command.Create(bundledApp.Path)
196172
.CaptureStdErr()
197173
.CaptureStdOut()
198-
.EnvironmentVariable(BundleHelper.DotnetBundleExtractBaseEnvVariable, extractBaseDir.FullName)
174+
.EnvironmentVariable(BundleHelper.DotnetBundleExtractBaseEnvVariable, extractBaseDir)
199175
.Execute()
200-
.Should()
201-
.Pass()
202-
.And
203-
.HaveStdOutContaining("Hello World");
176+
.Should().Pass()
177+
.And.HaveStdOutContaining("Hello World");
204178

205-
extractDir.Should().HaveFiles(extractedFiles);
179+
extractDir.Should().OnlyHaveFiles(extractedFiles);
206180
}
207181

208182
[Fact]
209-
private void Bundle_extraction_to_nonexisting_default()
183+
private void NonexistentDefault_Fails()
210184
{
211185
string nonExistentPath = Path.Combine(
212-
sharedTestState.DefaultBundledAppFixture.TestProject.OutputDirectory,
186+
Path.GetDirectoryName(sharedTestState.BundledApp.Path),
213187
"nonexistent");
214188

215189
string defaultExpansionEnvVariable = OperatingSystem.IsWindows() ? "TMP" : "HOME";
216190
string expectedErrorMessagePart = OperatingSystem.IsWindows() ?
217191
$"Failed to determine default extraction location. Check if 'TMP'" :
218192
$"Default extraction directory [{nonExistentPath}] either doesn't exist or is not accessible for read/write.";
219193

220-
Command.Create(sharedTestState.DefaultBundledAppExecutablePath)
194+
Command.Create(sharedTestState.BundledApp.Path)
221195
.CaptureStdErr()
222196
.CaptureStdOut()
223197
.EnvironmentVariable(defaultExpansionEnvVariable, nonExistentPath)
@@ -227,56 +201,51 @@ private void Bundle_extraction_to_nonexisting_default()
227201

228202
[Fact]
229203
[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.")]
230-
private void Bundle_extraction_fallsback_to_getpwuid_when_HOME_env_var_is_undefined()
204+
private void UndefinedHOME_getpwuidFallback()
231205
{
232206
string home = Environment.GetEnvironmentVariable("HOME");
233-
// suppose we are testing on a system where HOME is not set, use System.Environment (which also fallsback to getpwuid)
234207
if (string.IsNullOrEmpty(home))
235208
{
209+
// HOME is not set. Use System.Environment (which also fallsback to getpwuid)
236210
home = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile);
237211
}
238212

239-
DirectoryInfo sharedExtractDirInfo = BundleHelper.GetExtractionDir(sharedTestState.TestFixture, sharedTestState.DefaultBundledAppBundler);
240-
string sharedExtractDir = sharedExtractDirInfo.FullName;
241-
string extractDirSubPath = sharedExtractDir.Substring(sharedExtractDir.LastIndexOf("extract/") + "extract/".Length);
242-
string realExtractDir = Path.Combine(home, ".net", extractDirSubPath);
243-
var expectedExtractDir = new DirectoryInfo(realExtractDir);
244-
245-
Command.Create(sharedTestState.DefaultBundledAppExecutablePath)
213+
var bundledApp = sharedTestState.BundledApp;
214+
Command.Create(bundledApp.Path)
246215
.CaptureStdErr()
247216
.CaptureStdOut()
248217
.EnvironmentVariable("HOME", null)
249218
.Execute()
250-
.Should()
251-
.Pass()
252-
.And
253-
.HaveStdOutContaining("Hello World");
219+
.Should().Pass()
220+
.And.HaveStdOutContaining("Hello World");
254221

255-
var extractedFiles = BundleHelper.GetExtractedFiles(sharedTestState.TestFixture, BundleOptions.BundleNativeBinaries);
222+
DirectoryInfo expectedExtractDir = sharedTestState.SelfContainedApp.GetExtractionDir(Path.Combine(home, ".net"), bundledApp.Manifest);
223+
var extractedFiles = BundleHelper.GetExtractedFiles(bundledApp.Manifest, bundledApp.Options);
256224
expectedExtractDir.Should().HaveFiles(extractedFiles);
257225
}
258226

259-
public class SharedTestState : SharedTestStateBase, IDisposable
227+
public class SharedTestState : IDisposable
260228
{
261-
public TestProjectFixture TestFixture { get; }
229+
public (string Path, Manifest Manifest, BundleOptions Options) BundledApp{ get; }
262230

263-
public TestProjectFixture DefaultBundledAppFixture { get; }
264-
public string DefaultBundledAppExecutablePath { get; }
265-
public Bundler DefaultBundledAppBundler { get; }
231+
public SingleFileTestApp SelfContainedApp { get; }
266232

267233
public SharedTestState()
268234
{
269-
TestFixture = PreparePublishedSelfContainedTestProject("StandaloneApp");
235+
SelfContainedApp = SingleFileTestApp.CreateSelfContained("HelloWorld");
236+
237+
// Copy over mockcoreclr so that the app will have a native binary
238+
File.Copy(Binaries.CoreClr.MockPath, Path.Combine(SelfContainedApp.NonBundledLocation, Binaries.CoreClr.MockName));
270239

271-
DefaultBundledAppFixture = TestFixture.Copy();
272-
DefaultBundledAppBundler = BundleSelfContainedApp(DefaultBundledAppFixture, out var singleFile, BundleOptions.BundleNativeBinaries);
273-
DefaultBundledAppExecutablePath = singleFile;
240+
// Create a bundled app that can be used by multiple tests
241+
BundleOptions options = BundleOptions.BundleNativeBinaries;
242+
string bundlePath = SelfContainedApp.Bundle(options, out Manifest manifest);
243+
BundledApp = (bundlePath, manifest, options);
274244
}
275245

276246
public void Dispose()
277247
{
278-
DefaultBundledAppFixture.Dispose();
279-
TestFixture.Dispose();
248+
SelfContainedApp.Dispose();
280249
}
281250
}
282251
}

0 commit comments

Comments
 (0)