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 ;
47using BundleTests . Helpers ;
58using Microsoft . DotNet . Cli . Build . Framework ;
69using Microsoft . DotNet . CoreSetup . Test ;
710using 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 ;
1411using Xunit ;
1512
1613namespace 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