2
2
// The .NET Foundation licenses this file to you under the MIT license.
3
3
4
4
using System ;
5
+ using System . Collections . Generic ;
5
6
using System . IO ;
6
7
using System . Linq ;
8
+ using System . Runtime . InteropServices ;
7
9
8
10
using FluentAssertions ;
9
11
using Microsoft . DotNet . Cli . Build . Framework ;
@@ -21,6 +23,165 @@ public SymbolicLinks(SymbolicLinks.SharedTestState fixture)
21
23
sharedTestState = fixture ;
22
24
}
23
25
26
+ [ Theory ]
27
+ [ InlineData ( "a/b/SymlinkToFrameworkDependentApp" ) ]
28
+ [ InlineData ( "a/SymlinkToFrameworkDependentApp" ) ]
29
+ public void Symlink_all_files_fx ( string symlinkRelativePath )
30
+ {
31
+ using var testDir = TestArtifact . Create ( "symlink" ) ;
32
+ Directory . CreateDirectory ( Path . Combine ( testDir . Location , Path . GetDirectoryName ( symlinkRelativePath ) ) ) ;
33
+
34
+ // Symlink every file in the app directory
35
+ var symlinks = new List < SymLink > ( ) ;
36
+ try
37
+ {
38
+ foreach ( var file in Directory . EnumerateFiles ( sharedTestState . FrameworkDependentApp . Location ) )
39
+ {
40
+ var fileName = Path . GetFileName ( file ) ;
41
+ var symlinkPath = Path . Combine ( testDir . Location , symlinkRelativePath , fileName ) ;
42
+ Directory . CreateDirectory ( Path . GetDirectoryName ( symlinkPath ) ) ;
43
+ symlinks . Add ( new SymLink ( symlinkPath , file ) ) ;
44
+ }
45
+
46
+ var result = Command . Create ( Path . Combine ( testDir . Location , symlinkRelativePath , Path . GetFileName ( sharedTestState . FrameworkDependentApp . AppExe ) ) )
47
+ . CaptureStdErr ( )
48
+ . CaptureStdOut ( )
49
+ . DotNetRoot ( TestContext . BuiltDotNet . BinPath )
50
+ . Execute ( ) ;
51
+
52
+ // This should succeed on all platforms, but for different reasons:
53
+ // * Windows: The apphost will look next to the symlink for the app dll and find the symlinked dll
54
+ // * Unix: The apphost will look next to the resolved apphost for the app dll and find the real thing
55
+ result
56
+ . Should ( ) . Pass ( )
57
+ . And . HaveStdOutContaining ( "Hello World" ) ;
58
+ }
59
+ finally
60
+ {
61
+ foreach ( var symlink in symlinks )
62
+ {
63
+ symlink . Dispose ( ) ;
64
+ }
65
+ }
66
+ }
67
+
68
+ [ Theory ]
69
+ [ InlineData ( "a/b/SymlinkToFrameworkDependentApp" ) ]
70
+ [ InlineData ( "a/SymlinkToFrameworkDependentApp" ) ]
71
+ public void Symlink_split_files_fx ( string symlinkRelativePath )
72
+ {
73
+ using var testDir = TestArtifact . Create ( "symlink" ) ;
74
+
75
+ // Split the app into two directories, one for the apphost and one for the rest of the files
76
+ var appHostDir = Path . Combine ( testDir . Location , "apphost" ) ;
77
+ var appFilesDir = Path . Combine ( testDir . Location , "appfiles" ) ;
78
+ Directory . CreateDirectory ( appHostDir ) ;
79
+ Directory . CreateDirectory ( appFilesDir ) ;
80
+
81
+ var appHostName = Path . GetFileName ( sharedTestState . FrameworkDependentApp . AppExe ) ;
82
+
83
+ File . Copy (
84
+ sharedTestState . FrameworkDependentApp . AppExe ,
85
+ Path . Combine ( appHostDir , appHostName ) ) ;
86
+
87
+ foreach ( var file in Directory . EnumerateFiles ( sharedTestState . FrameworkDependentApp . Location ) )
88
+ {
89
+ var fileName = Path . GetFileName ( file ) ;
90
+ if ( fileName != appHostName )
91
+ {
92
+ File . Copy ( file , Path . Combine ( appFilesDir , fileName ) ) ;
93
+ }
94
+ }
95
+
96
+ // Symlink all of the above into a single directory
97
+ var targetPath = Path . Combine ( testDir . Location , symlinkRelativePath ) ;
98
+ Directory . CreateDirectory ( targetPath ) ;
99
+ var symlinks = new List < SymLink > ( ) ;
100
+ try
101
+ {
102
+ foreach ( var file in Directory . EnumerateFiles ( appFilesDir ) )
103
+ {
104
+ var fileName = Path . GetFileName ( file ) ;
105
+ var symlinkPath = Path . Combine ( targetPath , fileName ) ;
106
+ Directory . CreateDirectory ( Path . GetDirectoryName ( symlinkPath ) ) ;
107
+ symlinks . Add ( new SymLink ( symlinkPath , file ) ) ;
108
+ }
109
+ symlinks . Add ( new SymLink (
110
+ Path . Combine ( targetPath , appHostName ) ,
111
+ Path . Combine ( appHostDir , appHostName ) ) ) ;
112
+
113
+ var result = Command . Create ( Path . Combine ( targetPath , appHostName ) )
114
+ . CaptureStdErr ( )
115
+ . CaptureStdOut ( )
116
+ . DotNetRoot ( TestContext . BuiltDotNet . BinPath )
117
+ . Execute ( ) ;
118
+
119
+ if ( RuntimeInformation . IsOSPlatform ( OSPlatform . Windows ) )
120
+ {
121
+ // On Windows, the apphost will look next to the symlink for the app dll and find the symlinks
122
+ result
123
+ . Should ( ) . Pass ( )
124
+ . And . HaveStdOutContaining ( "Hello World" ) ;
125
+ }
126
+ else
127
+ {
128
+ // On Unix, the apphost will not find the app files next to the symlink
129
+ result
130
+ . Should ( ) . Fail ( )
131
+ . And . HaveStdErrContaining ( "The application to execute does not exist" ) ;
132
+ }
133
+ }
134
+ finally
135
+ {
136
+ foreach ( var symlink in symlinks )
137
+ {
138
+ symlink . Dispose ( ) ;
139
+ }
140
+ }
141
+ }
142
+
143
+ [ Theory ]
144
+ [ InlineData ( "a/b/SymlinkToFrameworkDependentApp" ) ]
145
+ [ InlineData ( "a/SymlinkToFrameworkDependentApp" ) ]
146
+ public void Symlink_all_files_self_contained ( string symlinkRelativePath )
147
+ {
148
+ using var testDir = TestArtifact . Create ( "symlink" ) ;
149
+ Directory . CreateDirectory ( Path . Combine ( testDir . Location , Path . GetDirectoryName ( symlinkRelativePath ) ) ) ;
150
+
151
+ // Symlink every file in the app directory
152
+ var symlinks = new List < SymLink > ( ) ;
153
+ try
154
+ {
155
+ foreach ( var file in Directory . EnumerateFiles ( sharedTestState . SelfContainedApp . Location ) )
156
+ {
157
+ var fileName = Path . GetFileName ( file ) ;
158
+ var symlinkPath = Path . Combine ( testDir . Location , symlinkRelativePath , fileName ) ;
159
+ Directory . CreateDirectory ( Path . GetDirectoryName ( symlinkPath ) ) ;
160
+ symlinks . Add ( new SymLink ( symlinkPath , file ) ) ;
161
+ }
162
+
163
+ var result = Command . Create ( Path . Combine ( testDir . Location , symlinkRelativePath , Path . GetFileName ( sharedTestState . FrameworkDependentApp . AppExe ) ) )
164
+ . CaptureStdErr ( )
165
+ . CaptureStdOut ( )
166
+ . DotNetRoot ( TestContext . BuiltDotNet . BinPath )
167
+ . Execute ( ) ;
168
+
169
+ // This should succeed on all platforms, but for different reasons:
170
+ // * Windows: The apphost will look next to the symlink for the files and find the symlinks
171
+ // * Unix: The apphost will look next to the resolved apphost for the files and find the real thing
172
+ result
173
+ . Should ( ) . Pass ( )
174
+ . And . HaveStdOutContaining ( "Hello World" ) ;
175
+ }
176
+ finally
177
+ {
178
+ foreach ( var symlink in symlinks )
179
+ {
180
+ symlink . Dispose ( ) ;
181
+ }
182
+ }
183
+ }
184
+
24
185
[ Theory ]
25
186
[ InlineData ( "a/b/SymlinkToApphost" ) ]
26
187
[ InlineData ( "a/SymlinkToApphost" ) ]
@@ -33,12 +194,23 @@ public void Run_apphost_behind_symlink(string symlinkRelativePath)
33
194
var symlinkFullPath = Path . Combine ( testDir . Location , symlinkRelativePath ) ;
34
195
35
196
using var symlink = new SymLink ( symlinkFullPath , sharedTestState . SelfContainedApp . AppExe ) ;
36
- Command . Create ( symlinkFullPath )
197
+ var result = Command . Create ( symlinkFullPath )
37
198
. CaptureStdErr ( )
38
199
. CaptureStdOut ( )
39
- . Execute ( )
40
- . Should ( ) . Pass ( )
41
- . And . HaveStdOutContaining ( "Hello World" ) ;
200
+ . Execute ( ) ;
201
+
202
+ if ( RuntimeInformation . IsOSPlatform ( OSPlatform . Windows ) )
203
+ {
204
+ result
205
+ . Should ( ) . Fail ( )
206
+ . And . HaveStdErrContaining ( "The application to execute does not exist" ) ;
207
+ }
208
+ else
209
+ {
210
+ result
211
+ . Should ( ) . Pass ( )
212
+ . And . HaveStdOutContaining ( "Hello World" ) ;
213
+ }
42
214
}
43
215
}
44
216
@@ -63,12 +235,23 @@ public void Run_apphost_behind_transitive_symlinks(string firstSymlinkRelativePa
63
235
Directory . CreateDirectory ( Path . GetDirectoryName ( symlink1Path ) ) ;
64
236
using var symlink1 = new SymLink ( symlink1Path , symlink2Path ) ;
65
237
66
- Command . Create ( symlink1 . SrcPath )
238
+ var result = Command . Create ( symlink1 . SrcPath )
67
239
. CaptureStdErr ( )
68
240
. CaptureStdOut ( )
69
- . Execute ( )
70
- . Should ( ) . Pass ( )
71
- . And . HaveStdOutContaining ( "Hello World" ) ;
241
+ . Execute ( ) ;
242
+
243
+ if ( RuntimeInformation . IsOSPlatform ( OSPlatform . Windows ) )
244
+ {
245
+ result
246
+ . Should ( ) . Fail ( )
247
+ . And . HaveStdErrContaining ( "The application to execute does not exist" ) ;
248
+ }
249
+ else
250
+ {
251
+ result
252
+ . Should ( ) . Pass ( )
253
+ . And . HaveStdOutContaining ( "Hello World" ) ;
254
+ }
72
255
}
73
256
}
74
257
@@ -86,13 +269,24 @@ public void Run_framework_dependent_app_behind_symlink(string symlinkRelativePat
86
269
Directory . CreateDirectory ( Path . Combine ( testDir . Location , Path . GetDirectoryName ( symlinkRelativePath ) ) ) ;
87
270
88
271
using var symlink = new SymLink ( Path . Combine ( testDir . Location , symlinkRelativePath ) , sharedTestState . FrameworkDependentApp . AppExe ) ;
89
- Command . Create ( symlink . SrcPath )
272
+ var result = Command . Create ( symlink . SrcPath )
90
273
. CaptureStdErr ( )
91
274
. CaptureStdOut ( )
92
275
. DotNetRoot ( TestContext . BuiltDotNet . BinPath )
93
- . Execute ( )
94
- . Should ( ) . Pass ( )
95
- . And . HaveStdOutContaining ( "Hello World" ) ;
276
+ . Execute ( ) ;
277
+
278
+ if ( RuntimeInformation . IsOSPlatform ( OSPlatform . Windows ) )
279
+ {
280
+ result
281
+ . Should ( ) . Fail ( )
282
+ . And . HaveStdErrContaining ( "The application to execute does not exist" ) ;
283
+ }
284
+ else
285
+ {
286
+ result
287
+ . Should ( ) . Pass ( )
288
+ . And . HaveStdOutContaining ( "Hello World" ) ;
289
+ }
96
290
}
97
291
}
98
292
@@ -144,12 +338,23 @@ public void Put_dotnet_behind_symlink()
144
338
var dotnetSymlink = Path . Combine ( testDir . Location , Binaries . DotNet . FileName ) ;
145
339
146
340
using var symlink = new SymLink ( dotnetSymlink , TestContext . BuiltDotNet . DotnetExecutablePath ) ;
147
- Command . Create ( symlink . SrcPath , sharedTestState . SelfContainedApp . AppDll )
341
+ var result = Command . Create ( symlink . SrcPath , sharedTestState . SelfContainedApp . AppDll )
148
342
. CaptureStdErr ( )
149
343
. CaptureStdOut ( )
150
- . Execute ( )
151
- . Should ( ) . Pass ( )
152
- . And . HaveStdOutContaining ( "Hello World" ) ;
344
+ . Execute ( ) ;
345
+
346
+ if ( RuntimeInformation . IsOSPlatform ( OSPlatform . Windows ) )
347
+ {
348
+ result
349
+ . Should ( ) . Fail ( )
350
+ . And . HaveStdErrContaining ( $ "[{ Path . Combine ( testDir . Location , "host" , "fxr" ) } ] does not exist") ;
351
+ }
352
+ else
353
+ {
354
+ result
355
+ . Should ( ) . Pass ( )
356
+ . And . HaveStdOutContaining ( "Hello World" ) ;
357
+ }
153
358
}
154
359
}
155
360
0 commit comments