@@ -39,7 +39,7 @@ internal sealed class SdkAndFrameworkFixture : IDisposable
3939 // Versions are assumed to be in ascending order. We use these properties to check against the
4040 // expected values passed to hostfxr API callbacks in the expected order.
4141 public string ExeDir => Path . Combine ( _artifact . Location , "ed" ) ;
42- public string LocalSdkDir => Path . Combine ( ExeDir , "sdk" ) ;
42+ public string LocalSdkDir { get ; }
4343 public string LocalFrameworksDir => Path . Combine ( ExeDir , "shared" ) ;
4444 public string [ ] LocalSdks = new [ ] { "0.1.200" , "1.2.300" , "5.6.701-preview" } ;
4545 public IEnumerable < string > LocalSdkPaths => LocalSdks . Select ( sdk => Path . Combine ( LocalSdkDir , sdk ) ) ;
@@ -50,46 +50,15 @@ internal sealed class SdkAndFrameworkFixture : IDisposable
5050 ( "HostFxr.Test.C" , new [ ] { "3.0.0" } )
5151 } ;
5252
53- public string ProgramFiles => Path . Combine ( _artifact . Location , "pf" ) ;
54- public string ProgramFilesGlobalSdkDir => Path . Combine ( ProgramFiles , "dotnet" , "sdk" ) ;
55- public string ProgramFilesGlobalFrameworksDir => Path . Combine ( ProgramFiles , "dotnet" , "shared" ) ;
56- public string [ ] ProgramFilesGlobalSdks = new [ ] { "1.2.300" , "2.3.400-preview" , "4.5.600" } ;
57- public List < ( string fwName , string [ ] fwVersions ) > ProgramFilesGlobalFrameworks =
58- new List < ( string fwName , string [ ] fwVersions ) > ( )
59- {
60- ( "HostFxr.Test.A" , new [ ] { "1.2.3" , "3.0.0" } ) ,
61- ( "HostFxr.Test.B" , new [ ] { "5.6.7-A" } )
62- } ;
63-
64- public string SelfRegistered => Path . Combine ( _artifact . Location , "sr" ) ;
65- public string SelfRegisteredGlobalSdkDir => Path . Combine ( SelfRegistered , "sdk" ) ;
66- public string [ ] SelfRegisteredGlobalSdks = new [ ] { "3.0.100" , "5.6.700" , "15.1.400-preview" } ;
67-
6853 public SdkAndFrameworkFixture ( )
6954 {
7055 _artifact = TestArtifact . Create ( nameof ( SdkAndFrameworkFixture ) ) ;
7156
72- foreach ( string sdk in ProgramFilesGlobalSdks )
73- {
74- AddSdkDirectory ( ProgramFilesGlobalSdkDir , sdk ) ;
75- }
76- foreach ( string sdk in SelfRegisteredGlobalSdks )
77- {
78- AddSdkDirectory ( SelfRegisteredGlobalSdkDir , sdk ) ;
79- }
80- foreach ( string sdk in LocalSdks )
81- {
82- AddSdkDirectory ( LocalSdkDir , sdk ) ;
83- }
57+ LocalSdkDir = CreateSdkDirectories ( ExeDir , LocalSdks ) ;
8458
8559 // Empty SDK directory - this should not be recognized as a valid SDK directory
8660 Directory . CreateDirectory ( Path . Combine ( LocalSdkDir , "9.9.9" ) ) ;
8761
88- foreach ( ( string fwName , string [ ] fwVersions ) in ProgramFilesGlobalFrameworks )
89- {
90- foreach ( string fwVersion in fwVersions )
91- AddFrameworkDirectory ( ProgramFilesGlobalFrameworksDir , fwName , fwVersion ) ;
92- }
9362 foreach ( ( string fwName , string [ ] fwVersions ) in LocalFrameworks )
9463 {
9564 foreach ( string fwVersion in fwVersions )
@@ -99,18 +68,29 @@ public SdkAndFrameworkFixture()
9968 Directory . CreateDirectory ( Path . Combine ( LocalFrameworksDir , fwName , "9.9.9" ) ) ;
10069 }
10170
102- static void AddSdkDirectory ( string sdkDir , string version )
71+ static void AddFrameworkDirectory ( string frameworkDir , string name , string version )
10372 {
104- string versionDir = Path . Combine ( sdkDir , version ) ;
73+ string versionDir = Path . Combine ( frameworkDir , name , version ) ;
10574 Directory . CreateDirectory ( versionDir ) ;
106- File . WriteAllText ( Path . Combine ( versionDir , "dotnet.dll ") , string . Empty ) ;
75+ File . WriteAllText ( Path . Combine ( versionDir , $ " { name } .deps.json ") , string . Empty ) ;
10776 }
77+ }
10878
109- static void AddFrameworkDirectory ( string frameworkDir , string name , string version )
79+ public static string CreateSdkDirectories ( string root , string [ ] versions )
80+ {
81+ string sdkDirectory = Path . Combine ( root , "sdk" ) ;
82+ foreach ( string sdk in versions )
11083 {
111- string versionDir = Path . Combine ( frameworkDir , name , version ) ;
84+ AddSdkDirectory ( sdkDirectory , sdk ) ;
85+ }
86+
87+ return sdkDirectory ;
88+
89+ static void AddSdkDirectory ( string sdkDir , string version )
90+ {
91+ string versionDir = Path . Combine ( sdkDir , version ) ;
11292 Directory . CreateDirectory ( versionDir ) ;
113- File . WriteAllText ( Path . Combine ( versionDir , $ " { name } .deps.json ") , string . Empty ) ;
93+ File . WriteAllText ( Path . Combine ( versionDir , "dotnet.dll ") , string . Empty ) ;
11494 }
11595 }
11696
@@ -120,26 +100,6 @@ public void Dispose()
120100 }
121101 }
122102
123- [ Fact ]
124- [ PlatformSpecific ( TestPlatforms . Windows ) ] // The test setup only works on Windows (and MLL was Windows-only anyway)
125- public void Hostfxr_get_available_sdks_with_multilevel_lookup ( )
126- {
127- // Starting with .NET 7, multi-level lookup is completely disabled for hostfxr API calls.
128- // This test is still valuable to validate that it is in fact disabled
129- var f = sharedTestState . SdkAndFrameworkFixture ;
130- string expectedList = string . Join ( ';' , f . LocalSdkPaths ) ;
131-
132- string api = ApiNames . hostfxr_get_available_sdks ;
133- sharedTestState . TestBehaviorEnabledDotNet . Exec ( sharedTestState . HostApiInvokerApp . AppDll , api , f . ExeDir )
134- . EnvironmentVariable ( "TEST_MULTILEVEL_LOOKUP_PROGRAM_FILES" , f . ProgramFiles )
135- . EnvironmentVariable ( "TEST_MULTILEVEL_LOOKUP_SELF_REGISTERED" , f . SelfRegistered )
136- . EnableTracingAndCaptureOutputs ( )
137- . Execute ( )
138- . Should ( ) . Pass ( )
139- . And . ReturnStatusCode ( api , Constants . ErrorCode . Success )
140- . And . HaveStdOutContaining ( $ "{ api } sdks:[{ expectedList } ]") ;
141- }
142-
143103 [ Fact ]
144104 public void Hostfxr_get_available_sdks ( )
145105 {
@@ -165,7 +125,7 @@ public void Hostfxr_resolve_sdk2_NoGlobalJson()
165125 var f = sharedTestState . SdkAndFrameworkFixture ;
166126 string expectedData = string . Join ( ';' , new [ ]
167127 {
168- ( "resolved_sdk_dir" , Path . Combine ( f . LocalSdkDir , "5.6.701-preview" ) ) ,
128+ ( "resolved_sdk_dir" , Path . Combine ( f . LocalSdkDir , f . LocalSdks [ ^ 1 ] ) ) ,
169129 ( "global_json_state" , "not_found" ) ,
170130 } ) ;
171131
@@ -238,10 +198,14 @@ public void Hostfxr_resolve_sdk2_GlobalJson_Paths()
238198 var f = sharedTestState . SdkAndFrameworkFixture ;
239199 using ( TestArtifact workingDir = TestArtifact . Create ( nameof ( workingDir ) ) )
240200 {
241- string globalJson = GlobalJson . Write ( workingDir . Location , new GlobalJson . Sdk ( ) { Paths = [ f . SelfRegistered , f . LocalSdkDir ] } ) ;
201+ string customSdkRoot = workingDir . GetUniqueSubdirectory ( "custom_paths" ) ;
202+ string [ ] versions = [ "3.0.100" , "5.6.700" , "15.1.400-preview" ] ;
203+ string customSdkDirectory = SdkAndFrameworkFixture . CreateSdkDirectories ( customSdkRoot , versions ) ;
204+
205+ string globalJson = GlobalJson . Write ( workingDir . Location , new GlobalJson . Sdk ( ) { Paths = [ customSdkRoot , f . LocalSdkDir ] } ) ;
242206 string expectedData = string . Join ( ';' , new [ ]
243207 {
244- ( "resolved_sdk_dir" , Path . Combine ( f . SelfRegisteredGlobalSdkDir , "15.1.400-preview" ) ) ,
208+ ( "resolved_sdk_dir" , Path . Combine ( customSdkDirectory , versions [ ^ 1 ] ) ) ,
245209 ( "global_json_path" , globalJson ) ,
246210 ( "global_json_state" , "valid" ) ,
247211 } ) ;
@@ -387,73 +351,6 @@ public void Hostfxr_get_dotnet_environment_info_dotnet_root_only()
387351 . And . HaveStdOutContaining ( $ "{ api } framework paths:[{ expectedFrameworkPaths } ]") ;
388352 }
389353
390- [ Fact ]
391- [ PlatformSpecific ( TestPlatforms . Windows ) ] // The test setup only works on Windows (and MLL was Windows-only anyway)
392- public void Hostfxr_get_dotnet_environment_info_with_multilevel_lookup_with_dotnet_root ( )
393- {
394- var f = sharedTestState . SdkAndFrameworkFixture ;
395- string expectedSdkVersions = string . Join ( ';' , f . LocalSdks ) ;
396- string expectedSdkPaths = string . Join ( ';' , f . LocalSdkPaths ) ;
397-
398- string expectedFrameworkNames = string . Join ( ';' , new [ ]
399- {
400- "HostFxr.Test.B" ,
401- "HostFxr.Test.B" ,
402- "HostFxr.Test.C"
403- } ) ;
404-
405- string expectedFrameworkVersions = string . Join ( ';' , new [ ]
406- {
407- "4.0.0" ,
408- "5.6.7-A" ,
409- "3.0.0"
410- } ) ;
411-
412- string expectedFrameworkPaths = string . Join ( ';' , new [ ]
413- {
414- Path . Combine ( f . LocalFrameworksDir , "HostFxr.Test.B" ) ,
415- Path . Combine ( f . LocalFrameworksDir , "HostFxr.Test.B" ) ,
416- Path . Combine ( f . LocalFrameworksDir , "HostFxr.Test.C" )
417- } ) ;
418-
419- string api = ApiNames . hostfxr_get_dotnet_environment_info ;
420- sharedTestState . TestBehaviorEnabledDotNet . Exec ( sharedTestState . HostApiInvokerApp . AppDll , new [ ] { api , f . ExeDir } )
421- . EnvironmentVariable ( "TEST_MULTILEVEL_LOOKUP_PROGRAM_FILES" , f . ProgramFiles )
422- . EnvironmentVariable ( "TEST_MULTILEVEL_LOOKUP_SELF_REGISTERED" , f . SelfRegistered )
423- . EnableTracingAndCaptureOutputs ( )
424- . Execute ( )
425- . Should ( ) . Pass ( )
426- . And . ReturnStatusCode ( api , Constants . ErrorCode . Success )
427- . And . HaveStdOutContaining ( $ "{ api } sdk versions:[{ expectedSdkVersions } ]")
428- . And . HaveStdOutContaining ( $ "{ api } sdk paths:[{ expectedSdkPaths } ]")
429- . And . HaveStdOutContaining ( $ "{ api } framework names:[{ expectedFrameworkNames } ]")
430- . And . HaveStdOutContaining ( $ "{ api } framework versions:[{ expectedFrameworkVersions } ]")
431- . And . HaveStdOutContaining ( $ "{ api } framework paths:[{ expectedFrameworkPaths } ]") ;
432- }
433-
434- [ Fact ]
435- [ PlatformSpecific ( TestPlatforms . Windows ) ] // The test setup only works on Windows (and MLL was Windows-only anyway)
436- public void Hostfxr_get_dotnet_environment_info_with_multilevel_lookup_only ( )
437- {
438- var f = sharedTestState . SdkAndFrameworkFixture ;
439-
440- // Multi-level lookup is completely disabled on 7+
441- // The test runs the API with the dotnet root directory set to a location which doesn't have any SDKs or frameworks
442- string api = ApiNames . hostfxr_get_dotnet_environment_info ;
443- sharedTestState . TestBehaviorEnabledDotNet . Exec ( sharedTestState . HostApiInvokerApp . AppDll , api , sharedTestState . HostApiInvokerApp . Location )
444- . EnvironmentVariable ( "TEST_MULTILEVEL_LOOKUP_PROGRAM_FILES" , f . ProgramFiles )
445- . EnvironmentVariable ( "TEST_MULTILEVEL_LOOKUP_SELF_REGISTERED" , f . SelfRegistered )
446- . EnableTracingAndCaptureOutputs ( )
447- . Execute ( )
448- . Should ( ) . Pass ( )
449- . And . ReturnStatusCode ( api , Constants . ErrorCode . Success )
450- . And . HaveStdOutContaining ( $ "{ api } sdk versions:[]")
451- . And . HaveStdOutContaining ( $ "{ api } sdk paths:[]")
452- . And . HaveStdOutContaining ( $ "{ api } framework names:[]")
453- . And . HaveStdOutContaining ( $ "{ api } framework versions:[]")
454- . And . HaveStdOutContaining ( $ "{ api } framework paths:[]") ;
455- }
456-
457354 [ Fact ]
458355 public void Hostfxr_get_dotnet_environment_info_global_install_path ( )
459356 {
@@ -873,28 +770,16 @@ public class SharedTestState : IDisposable
873770 {
874771 public TestApp HostApiInvokerApp { get ; }
875772
876- public DotNetCli TestBehaviorEnabledDotNet { get ; }
877- private readonly TestArtifact copiedDotnet ;
878-
879773 internal SdkAndFrameworkFixture SdkAndFrameworkFixture { get ; }
880774
881775 public SharedTestState ( )
882776 {
883- // Make a copy of the built .NET, as we will enable test-only behaviour
884- copiedDotnet = TestArtifact . CreateFromCopy ( nameof ( NativeHostApis ) , TestContext . BuiltDotNet . BinPath ) ;
885- TestBehaviorEnabledDotNet = new DotNetCli ( copiedDotnet . Location ) ;
886-
887- // Enable test-only behavior for the copied .NET. We don't bother disabling the behaviour later,
888- // as we just delete the entire copy after the tests run.
889- _ = TestOnlyProductBehavior . Enable ( TestBehaviorEnabledDotNet . GreatestVersionHostFxrFilePath ) ;
890-
891777 HostApiInvokerApp = TestApp . CreateFromBuiltAssets ( "HostApiInvokerApp" ) ;
892778
893779 // On non-Windows, we can't just P/Invoke to already loaded hostfxr, so provide the app with
894780 // paths to hostfxr so that it can handle resolving the library.
895781 RuntimeConfig . FromFile ( HostApiInvokerApp . RuntimeConfigJson )
896782 . WithProperty ( "HOSTFXR_PATH" , TestContext . BuiltDotNet . GreatestVersionHostFxrFilePath )
897- . WithProperty ( "HOSTFXR_PATH_TEST_BEHAVIOR" , TestBehaviorEnabledDotNet . GreatestVersionHostFxrFilePath )
898783 . Save ( ) ;
899784
900785 SdkAndFrameworkFixture = new SdkAndFrameworkFixture ( ) ;
@@ -903,7 +788,6 @@ public SharedTestState()
903788 public void Dispose ( )
904789 {
905790 HostApiInvokerApp ? . Dispose ( ) ;
906- copiedDotnet . Dispose ( ) ;
907791 SdkAndFrameworkFixture . Dispose ( ) ;
908792 }
909793 }
0 commit comments