22// The .NET Foundation licenses this file to you under the MIT license.
33
44using System ;
5- using System . Collections . Generic ;
65using System . IO ;
76using System . Linq ;
7+ using System . Text ;
88using Microsoft . DotNet . Cli . Build ;
9- using Microsoft . DotNet . Cli . Build . Framework ;
109using Microsoft . DotNet . CoreSetup . Test ;
1110using Microsoft . DotNet . CoreSetup . Test . HostActivation ;
12- using Microsoft . DotNet . TestUtils ;
1311using Xunit ;
1412
1513namespace HostActivation . Tests
@@ -24,14 +22,79 @@ public HostCommands(SharedTestState sharedState)
2422 }
2523
2624 [ Fact ]
27- public void ListRuntimes_OtherArchitectures ( )
25+ public void Info ( )
26+ {
27+ string expectedSdksOutput =
28+ $ """
29+ .NET SDKs installed:
30+ { GetListSdksOutput ( SharedState . DotNet . BinPath , SharedState . InstalledVersions , " " ) }
31+ """ ;
32+ string expectedRuntimesOutput =
33+ $ """
34+ .NET runtimes installed:
35+ { GetListRuntimesOutput ( SharedState . DotNet . BinPath , SharedState . InstalledVersions , " " ) }
36+ """ ;
37+ SharedState . DotNet . Exec ( "--info" )
38+ . CaptureStdOut ( )
39+ . Execute ( )
40+ . Should ( ) . Pass ( )
41+ . And . HaveStdOutContaining ( expectedSdksOutput )
42+ . And . HaveStdOutContaining ( expectedRuntimesOutput )
43+ . And . HaveStdOutMatching ( $@ "Architecture:\s*{ TestContext . BuildArchitecture } ")
44+ // If an SDK exists, we rely on it to print the RID. The host should not print it again.
45+ . And . NotHaveStdOutMatching ( $@ "RID:\s*{ TestContext . BuildRID } ") ;
46+ }
47+
48+ [ Fact ]
49+ public void Info_NoSDK ( )
50+ {
51+ TestContext . BuiltDotNet . Exec ( "--info" )
52+ . CaptureStdOut ( )
53+ . Execute ( )
54+ . Should ( ) . Pass ( )
55+ . And . HaveStdOutMatching ( $@ "Architecture:\s*{ TestContext . BuildArchitecture } ")
56+ . And . HaveStdOutMatching ( $@ "RID:\s*{ TestContext . BuildRID } ")
57+ . And . HaveStdOutContaining ( "No SDKs were found" ) ;
58+ }
59+
60+
61+ [ Fact ]
62+ public void Info_Utf8Path ( )
63+ {
64+ string installLocation = Encoding . UTF8 . GetString ( "utf8-龯蝌灋齅ㄥ䶱"u8 ) ;
65+ DotNetCli dotnet = new DotNetBuilder ( SharedState . Artifact . Location , TestContext . BuiltDotNet . BinPath , installLocation )
66+ . Build ( ) ;
67+
68+ dotnet . Exec ( "--info" )
69+ . DotNetRoot ( Path . Combine ( SharedState . Artifact . Location , installLocation ) )
70+ . CaptureStdOut ( Encoding . UTF8 )
71+ . Execute ( )
72+ . Should ( ) . Pass ( )
73+ . And . HaveStdOutMatching ( $@ "DOTNET_ROOT.*{ installLocation } ") ;
74+ }
75+
76+ [ Fact ]
77+ public void ListRuntimes ( )
78+ {
79+ // Verify exact match of command output. The output of --list-runtimes is intended to be machine-readable
80+ // and must not change in a way that breaks existing parsing.
81+ string expectedOutput = GetListRuntimesOutput ( SharedState . DotNet . BinPath , SharedState . InstalledVersions ) ;
82+ SharedState . DotNet . Exec ( "--list-runtimes" )
83+ . CaptureStdOut ( )
84+ . Execute ( )
85+ . Should ( ) . Pass ( )
86+ . And . HaveStdOut ( expectedOutput ) ;
87+ }
88+
89+ [ Fact ]
90+ public void ListRuntimes_OtherArchitecture ( )
2891 {
2992 using ( var registeredInstallLocationOverride = new RegisteredInstallLocationOverride ( SharedState . DotNet . GreatestVersionHostFxrFilePath ) )
3093 {
3194 registeredInstallLocationOverride . SetInstallLocation ( SharedState . OtherArchInstallLocations ) ;
3295 foreach ( ( string arch , string installLocation ) in SharedState . OtherArchInstallLocations )
3396 {
34- // Verifiy exact match of command output. The output of --list-runtimes is intended to be machine-readable
97+ // Verify exact match of command output. The output of --list-runtimes is intended to be machine-readable
3598 // and must not change in a way that breaks existing parsing.
3699 string expectedOutput = GetListRuntimesOutput ( installLocation , SharedState . InstalledVersions ) ;
37100 SharedState . DotNet . Exec ( "--list-runtimes" , "--arch" , arch )
@@ -45,14 +108,45 @@ public void ListRuntimes_OtherArchitectures()
45108 }
46109
47110 [ Fact ]
48- public void ListSdks_OtherArchitectures ( )
111+ public void ListRuntimes_OtherArchitecture_NoInstalls ( )
112+ {
113+ // Non-host architecture - arm64 if current architecture is x64, otherwise x64
114+ string arch = TestContext . BuildArchitecture == "x64" ? "arm64" : "x64" ;
115+ using ( var registeredInstallLocationOverride = new RegisteredInstallLocationOverride ( SharedState . DotNet . GreatestVersionHostFxrFilePath ) )
116+ {
117+ // Register a location that should have no runtimes installed
118+ registeredInstallLocationOverride . SetInstallLocation ( ( arch , SharedState . Artifact . Location ) ) ;
119+ SharedState . DotNet . Exec ( "--list-runtimes" , "--arch" , arch )
120+ . ApplyRegisteredInstallLocationOverride ( registeredInstallLocationOverride )
121+ . CaptureStdOut ( )
122+ . Execute ( )
123+ . Should ( ) . Pass ( )
124+ . And . HaveStdOut ( string . Empty ) ;
125+ }
126+ }
127+
128+ [ Fact ]
129+ public void ListSdks ( )
130+ {
131+ // Verify exact match of command output. The output of --list-sdks is intended to be machine-readable
132+ // and must not change in a way that breaks existing parsing.
133+ string expectedOutput = GetListSdksOutput ( SharedState . DotNet . BinPath , SharedState . InstalledVersions ) ;
134+ SharedState . DotNet . Exec ( "--list-sdks" )
135+ . CaptureStdOut ( )
136+ . Execute ( )
137+ . Should ( ) . Pass ( )
138+ . And . HaveStdOut ( expectedOutput ) ;
139+ }
140+
141+ [ Fact ]
142+ public void ListSdks_OtherArchitecture ( )
49143 {
50144 using ( var registeredInstallLocationOverride = new RegisteredInstallLocationOverride ( SharedState . DotNet . GreatestVersionHostFxrFilePath ) )
51145 {
52146 registeredInstallLocationOverride . SetInstallLocation ( SharedState . OtherArchInstallLocations ) ;
53147 foreach ( ( string arch , string installLocation ) in SharedState . OtherArchInstallLocations )
54148 {
55- // Verifiy exact match of command output. The output of --list-sdks is intended to be machine-readable
149+ // Verify exact match of command output. The output of --list-sdks is intended to be machine-readable
56150 // and must not change in a way that breaks existing parsing.
57151 string expectedOutput = GetListSdksOutput ( installLocation , SharedState . InstalledVersions ) ;
58152 SharedState . DotNet . Exec ( "--list-sdks" , "--arch" , arch )
@@ -65,20 +159,39 @@ public void ListSdks_OtherArchitectures()
65159 }
66160 }
67161
68- private static string GetListRuntimesOutput ( string installLocation , string [ ] versions )
162+ [ Fact ]
163+ public void ListSdks_OtherArchitecture_NoInstalls ( )
164+ {
165+ // Non-host architecture - arm64 if current architecture is x64, otherwise x64
166+ string arch = TestContext . BuildArchitecture == "x64" ? "arm64" : "x64" ;
167+ using ( var registeredInstallLocationOverride = new RegisteredInstallLocationOverride ( SharedState . DotNet . GreatestVersionHostFxrFilePath ) )
168+ {
169+ // Register a location that should have no SDKs installed
170+ registeredInstallLocationOverride . SetInstallLocation ( ( arch , SharedState . Artifact . Location ) ) ;
171+ SharedState . DotNet . Exec ( "--list-sdks" , "--arch" , arch )
172+ . ApplyRegisteredInstallLocationOverride ( registeredInstallLocationOverride )
173+ . CaptureStdOut ( )
174+ . Execute ( )
175+ . Should ( ) . Pass ( )
176+ . And . HaveStdOut ( string . Empty ) ;
177+ }
178+ }
179+
180+ private static string GetListRuntimesOutput ( string installLocation , string [ ] versions , string prefix = "" )
69181 {
70182 string runtimePath = Path . Combine ( installLocation , "shared" , Constants . MicrosoftNETCoreApp ) ;
71- return string . Join ( string . Empty , versions . Select ( v => $ "{ Constants . MicrosoftNETCoreApp } { v } [{ runtimePath } ]{ Environment . NewLine } ") ) ;
183+ return string . Join ( string . Empty , versions . Select ( v => $ "{ prefix } { Constants . MicrosoftNETCoreApp } { v } [{ runtimePath } ]{ Environment . NewLine } ") ) ;
72184 }
73185
74- private static string GetListSdksOutput ( string installLocation , string [ ] versions )
186+ private static string GetListSdksOutput ( string installLocation , string [ ] versions , string prefix = "" )
75187 {
76188 string sdkPath = Path . Combine ( installLocation , "sdk" ) ;
77- return string . Join ( string . Empty , versions . Select ( v => $ "{ v } [{ sdkPath } ]{ Environment . NewLine } ") ) ;
189+ return string . Join ( string . Empty , versions . Select ( v => $ "{ prefix } { v } [{ sdkPath } ]{ Environment . NewLine } ") ) ;
78190 }
79191
80192 public sealed class SharedTestState : IDisposable
81193 {
194+ public TestArtifact Artifact { get ; }
82195 public DotNetCli DotNet { get ; }
83196
84197 // Versions are assumed to be in ascending order. We use this property to check against the
@@ -87,13 +200,11 @@ public sealed class SharedTestState : IDisposable
87200
88201 public ( string , string ) [ ] OtherArchInstallLocations { get ; }
89202
90- private TestArtifact _artifact ;
91-
92203 public SharedTestState ( )
93204 {
94- _artifact = TestArtifact . Create ( nameof ( HostCommands ) ) ;
205+ Artifact = TestArtifact . Create ( nameof ( HostCommands ) ) ;
95206
96- var builder = new DotNetBuilder ( _artifact . Location , TestContext . BuiltDotNet . BinPath , "exe" ) ;
207+ var builder = new DotNetBuilder ( Artifact . Location , TestContext . BuiltDotNet . BinPath , "exe" ) ;
97208 foreach ( string version in InstalledVersions )
98209 {
99210 builder . AddMicrosoftNETCoreAppFrameworkMockHostPolicy ( version ) ;
@@ -103,12 +214,12 @@ public SharedTestState()
103214 DotNet = builder . Build ( ) ;
104215
105216 // Add runtimes and SDKs for other architectures
106- string [ ] otherArchs = new [ ] { "arm" , " arm64", "x64" , "x86" } . Where ( a => a != TestContext . BuildArchitecture ) . ToArray ( ) ;
217+ string [ ] otherArchs = new [ ] { "arm64" , "x64" , "x86" } . Where ( a => a != TestContext . BuildArchitecture ) . ToArray ( ) ;
107218 OtherArchInstallLocations = new ( string , string ) [ otherArchs . Length ] ;
108219 for ( int i = 0 ; i < otherArchs . Length ; i ++ )
109220 {
110221 string arch = otherArchs [ i ] ;
111- string installLocation = Directory . CreateDirectory ( Path . Combine ( _artifact . Location , arch ) ) . FullName ;
222+ string installLocation = Directory . CreateDirectory ( Path . Combine ( Artifact . Location , arch ) ) . FullName ;
112223 foreach ( string version in InstalledVersions )
113224 {
114225 DotNetBuilder . AddMicrosoftNETCoreAppFrameworkMockHostPolicy ( installLocation , version ) ;
@@ -127,7 +238,7 @@ public SharedTestState()
127238
128239 public void Dispose ( )
129240 {
130- _artifact . Dispose ( ) ;
241+ Artifact . Dispose ( ) ;
131242 }
132243 }
133244 }
0 commit comments