#include <ShlObj.h>
#include <ctime>
+#if !defined(RRF_SUBKEY_WOW6432KEY)
+#define RRF_SUBKEY_WOW6432KEY 0x00020000
+#endif
bool GetModuleFileNameWrapper(HMODULE hModule, pal::string_t* recv)
{
return true;
}
-bool pal::get_global_dotnet_dirs(std::vector<pal::string_t>* dirs)
-{
- pal::string_t dir;
- if (!get_default_installation_dir(&dir))
- {
- return false;
- }
-
- dirs->push_back(dir);
- return true;
-}
-
bool pal::get_default_installation_dir(pal::string_t* recv)
{
pal::char_t* program_files_dir;
}
append_path(recv, _X("dotnet"));
+
+ return true;
+}
+
+bool get_sdk_self_registered_dir(pal::string_t* recv)
+{
+#if !defined(_TARGET_AMD64_) && !defined(_TARGET_X86_)
+ // Self-registered SDK installation directory is only supported for x64 and x86 architectures.
+ return false;
+#else
+ recv->clear();
+
+ // ***Used only for testing***
+ pal::string_t environmentOverride;
+ if (pal::getenv(_X("_DOTNET_TEST_SDK_SELF_REGISTERED_DIR"), &environmentOverride))
+ {
+ recv->assign(environmentOverride);
+ return true;
+ }
+ // ***************************
+
+ DWORD size = 0;
+ const HKEY hkey = HKEY_LOCAL_MACHINE;
+ // The registry search occurs in the 32-bit registry in all cases.
+ const DWORD flags = RRF_RT_REG_SZ | RRF_SUBKEY_WOW6432KEY;
+ pal::string_t sub_key = pal::string_t(_X("SOFTWARE\\dotnet\\Setup\\InstalledVersions\\")) + get_arch() + pal::string_t(_X("\\sdk"));
+ pal::char_t* value = _X("InstallLocation");
+
+ // Determine the size of the buffer
+ LONG result = ::RegGetValueW(hkey, sub_key.c_str(), value, flags, nullptr, nullptr, &size);
+ if (result != ERROR_SUCCESS || size == 0)
+ {
+ return false;
+ }
+
+ // Get the key's value
+ std::vector<pal::char_t> buffer(size/sizeof(pal::char_t));
+ result = ::RegGetValueW(hkey, sub_key.c_str(), value, flags, nullptr, &buffer[0], &size);
+ if (result != ERROR_SUCCESS)
+ {
+ return false;
+ }
+
+ recv->assign(buffer.data());
+
return true;
+#endif
+}
+
+bool pal::get_global_dotnet_dirs(std::vector<pal::string_t>* dirs)
+{
+ pal::string_t default_dir;
+ pal::string_t custom_dir;
+ bool dir_found = false;
+ if (get_sdk_self_registered_dir(&custom_dir))
+ {
+ dirs->push_back(custom_dir);
+ dir_found = true;
+ }
+ if (get_default_installation_dir(&default_dir))
+ {
+ // Avoid duplicate global dirs.
+ if (!dir_found || !are_paths_equal_with_normalized_casing(custom_dir, default_dir))
+ {
+ dirs->push_back(default_dir);
+ dir_found = true;
+ }
+ }
+ return dir_found;
}
// To determine the OS version, we are going to use RtlGetVersion API
// Enable tracing so that test assertion failures are easier to diagnose.
Environment.SetEnvironmentVariable("COREHOST_TRACE", "1");
- // If requested, test multilevel lookup using fake ProgramFiles location.
+ // If requested, test multilevel lookup using fake Global SDK directories:
+ // 1. using a fake ProgramFiles location
+ // 2. using a fake SDK Self-Registered location
// Note that this has to be set here and not in the calling test process because
// %ProgramFiles% gets reset on process creation.
- string testMultilevelLookupProgramFiles = Environment.GetEnvironmentVariable(
- "TEST_MULTILEVEL_LOOKUP_PROGRAM_FILES");
+ string testMultilevelLookupProgramFiles = Environment.GetEnvironmentVariable("TEST_MULTILEVEL_LOOKUP_PROGRAM_FILES");
+ string testMultilevelLookupSelfRegistered = Environment.GetEnvironmentVariable("TEST_MULTILEVEL_LOOKUP_SELF_REGISTERED");
- if (testMultilevelLookupProgramFiles != null)
+ if (testMultilevelLookupProgramFiles != null && testMultilevelLookupSelfRegistered != null)
{
+ Environment.SetEnvironmentVariable("_DOTNET_TEST_SDK_SELF_REGISTERED_DIR", testMultilevelLookupSelfRegistered);
Environment.SetEnvironmentVariable("ProgramFiles", testMultilevelLookupProgramFiles);
Environment.SetEnvironmentVariable("ProgramFiles(x86)", testMultilevelLookupProgramFiles);
Environment.SetEnvironmentVariable("DOTNET_MULTILEVEL_LOOKUP", "1");
using System.Collections.Generic;
using System.IO;
using System.Linq;
+using System.Runtime.InteropServices;
using Microsoft.DotNet.InternalAbstractions;
using Xunit;
private string _currentWorkingDir;
private string _userDir;
- private string _executableDir;
+ private string _exeDir;
+ private string _regDir;
private string _cwdSdkBaseDir;
private string _userSdkBaseDir;
private string _exeSdkBaseDir;
+ private string _regSdkBaseDir;
private string _cwdSelectedMessage;
private string _userSelectedMessage;
private string _exeSelectedMessage;
+ private string _regSelectedMessage;
private string _sdkDir;
private string _multilevelDir;
_currentWorkingDir = Path.Combine(_multilevelDir, "cwd");
_userDir = Path.Combine(_multilevelDir, "user");
- _executableDir = Path.Combine(_multilevelDir, "exe");
+ _exeDir = Path.Combine(_multilevelDir, "exe");
+ _regDir = Path.Combine(_multilevelDir, "reg");
// It's necessary to copy the entire publish folder to the exe dir because
// we'll need to build from it. The CopyDirectory method automatically creates the dest dir
- SharedFramework.CopyDirectory(builtDotnet, _executableDir);
+ SharedFramework.CopyDirectory(builtDotnet, _exeDir);
- RepoDirectories = new RepoDirectoriesProvider(builtDotnet: _executableDir);
+ RepoDirectories = new RepoDirectoriesProvider(builtDotnet: _exeDir);
// SdkBaseDirs contain all available version folders
_cwdSdkBaseDir = Path.Combine(_currentWorkingDir, "sdk");
_userSdkBaseDir = Path.Combine(_userDir, ".dotnet", RepoDirectories.BuildArchitecture, "sdk");
- _exeSdkBaseDir = Path.Combine(_executableDir, "sdk");
+ _exeSdkBaseDir = Path.Combine(_exeDir, "sdk");
+ _regSdkBaseDir = Path.Combine(_regDir, "sdk");
// Create directories
Directory.CreateDirectory(_cwdSdkBaseDir);
Directory.CreateDirectory(_userSdkBaseDir);
Directory.CreateDirectory(_exeSdkBaseDir);
+ Directory.CreateDirectory(_regSdkBaseDir);
// Restore and build PortableApp from exe dir
PreviouslyBuiltAndRestoredPortableTestProjectFixture = new TestProjectFixture("PortableApp", RepoDirectories)
// Set a dummy framework version (9999.0.0) in the exe sharedFx location. We will
// always pick the framework from this to avoid interference with the sharedFxLookup
- string exeDirDummyFxVersion = Path.Combine(_executableDir, "shared", "Microsoft.NETCore.App", "9999.0.0");
+ string exeDirDummyFxVersion = Path.Combine(_exeDir, "shared", "Microsoft.NETCore.App", "9999.0.0");
string builtSharedFxDir = fixture.BuiltDotnet.GreatestVersionSharedFxPath;
SharedFramework.CopyDirectory(builtSharedFxDir, exeDirDummyFxVersion);
_cwdSelectedMessage = $"Using dotnet SDK dll=[{_cwdSdkBaseDir}";
_userSelectedMessage = $"Using dotnet SDK dll=[{_userSdkBaseDir}";
_exeSelectedMessage = $"Using dotnet SDK dll=[{_exeSdkBaseDir}";
+ _regSelectedMessage = $"Using dotnet SDK dll=[{_regSdkBaseDir}";
}
public void Dispose()
}
[Fact]
- public void SdkLookup_Global_Json_Single_Digit_Patch_Rollup()
+ public void SdkMultilevelLookup_Global_Json_Single_Digit_Patch_Rollup()
{
+ if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
+ {
+ // Multi-level lookup is only supported on Windows.
+ return;
+ }
+
var fixture = PreviouslyBuiltAndRestoredPortableTestProjectFixture
.Copy();
var dotnet = fixture.BuiltDotnet;
- // Set specified CLI version = 9999.3.4-global-dummy
+ // Set specified SDK version = 9999.3.4-global-dummy
SetGlobalJsonVersion("SingleDigit-global.json");
- // Specified CLI version: 9999.3.4-global-dummy
- // CWD: empty
+ // Specified SDK version: 9999.3.4-global-dummy
+ // Cwd: empty
// User: empty
// Exe: empty
+ // Reg: empty
// Expected: no compatible version and a specific error messages
dotnet.Exec("help")
.WorkingDirectory(_currentWorkingDir)
.WithUserProfile(_userDir)
.Environment(s_DefaultEnvironment)
- .EnvironmentVariable("DOTNET_MULTILEVEL_LOOKUP", "0")
+ .EnvironmentVariable("DOTNET_MULTILEVEL_LOOKUP", "1")
+ .EnvironmentVariable("_DOTNET_TEST_SDK_SELF_REGISTERED_DIR", _regDir)
.CaptureStdOut()
.CaptureStdErr()
.Execute(fExpectedToFail: true)
.Should()
.Fail()
.And
- .HaveStdErrContaining("A compatible installed dotnet SDK for global.json version")
- .And
- .HaveStdErrContaining("It was not possible to find any installed dotnet SDKs")
- .And
- .NotHaveStdErrContaining("Checking if resolved SDK dir");
+ .HaveStdErrContaining("A compatible installed dotnet SDK for global.json version");
- // Add some dummy versions
+ // Add SDK versions
AddAvailableSdkVersions(_exeSdkBaseDir, "9999.4.1", "9999.3.4-dummy");
- // Specified CLI version: 9999.3.4-global-dummy
- // CWD: empty
+ // Specified SDK version: 9999.3.4-global-dummy
+ // Cwd: empty
// User: empty
// Exe: 9999.4.1, 9999.3.4-dummy
+ // Reg: empty
// Expected: no compatible version and a specific error message
dotnet.Exec("help")
.WorkingDirectory(_currentWorkingDir)
.WithUserProfile(_userDir)
.Environment(s_DefaultEnvironment)
- .EnvironmentVariable("DOTNET_MULTILEVEL_LOOKUP", "0")
+ .EnvironmentVariable("DOTNET_MULTILEVEL_LOOKUP", "1")
+ .EnvironmentVariable("_DOTNET_TEST_SDK_SELF_REGISTERED_DIR", _regDir)
.CaptureStdOut()
.CaptureStdErr()
.Execute(fExpectedToFail: true)
.Should()
.Fail()
.And
- .HaveStdErrContaining("A compatible installed dotnet SDK for global.json version")
- .And
- .NotHaveStdErrContaining("It was not possible to find any installed dotnet SDKs");
+ .HaveStdErrContaining("A compatible installed dotnet SDK for global.json version");
- // Add specified CLI version
- AddAvailableSdkVersions(_exeSdkBaseDir, "9999.3.3");
+ // Add SDK versions
+ AddAvailableSdkVersions(_regSdkBaseDir, "9999.3.3");
- // Specified CLI version: 9999.3.4-global-dummy
- // CWD: empty
+ // Specified SDK version: 9999.3.4-global-dummy
+ // Cwd: empty
// User: empty
- // Exe: 9999.4.1, 9999.3.4-dummy, 9999.3.3
+ // Exe: 9999.4.1, 9999.3.4-dummy
+ // Reg: 9999.3.3
// Expected: no compatible version and a specific error message
dotnet.Exec("help")
.WorkingDirectory(_currentWorkingDir)
.WithUserProfile(_userDir)
.Environment(s_DefaultEnvironment)
- .EnvironmentVariable("DOTNET_MULTILEVEL_LOOKUP", "0")
+ .EnvironmentVariable("DOTNET_MULTILEVEL_LOOKUP", "1")
+ .EnvironmentVariable("_DOTNET_TEST_SDK_SELF_REGISTERED_DIR", _regDir)
.CaptureStdOut()
.CaptureStdErr()
.Execute(fExpectedToFail: true)
.Should()
.Fail()
.And
- .HaveStdErrContaining("A compatible installed dotnet SDK for global.json version")
- .And
- .NotHaveStdErrContaining("It was not possible to find any installed dotnet SDKs");
+ .HaveStdErrContaining("A compatible installed dotnet SDK for global.json version");
- // Add specified CLI version
+ // Add SDK versions
AddAvailableSdkVersions(_exeSdkBaseDir, "9999.3.4");
- // Specified CLI version: 9999.3.4-global-dummy
- // CWD: empty
+ // Specified SDK version: 9999.3.4-global-dummy
+ // Cwd: empty
// User: empty
- // Exe: 9999.4.1, 9999.3.4-dummy, 9999.3.3, 9999.3.4
+ // Exe: 9999.4.1, 9999.3.4-dummy, 9999.3.4
+ // Reg: 9999.3.3
// Expected: 9999.3.4 from exe dir
dotnet.Exec("help")
.WorkingDirectory(_currentWorkingDir)
.WithUserProfile(_userDir)
.Environment(s_DefaultEnvironment)
- .EnvironmentVariable("DOTNET_MULTILEVEL_LOOKUP", "0")
+ .EnvironmentVariable("DOTNET_MULTILEVEL_LOOKUP", "1")
+ .EnvironmentVariable("_DOTNET_TEST_SDK_SELF_REGISTERED_DIR", _regDir)
.CaptureStdOut()
.CaptureStdErr()
.Execute()
.And
.HaveStdErrContaining(Path.Combine(_exeSelectedMessage, "9999.3.4", _dotnetSdkDllMessageTerminator));
- // Add specified CLI version
- AddAvailableSdkVersions(_exeSdkBaseDir, "9999.3.5-dummy");
+ // Add SDK versions
+ AddAvailableSdkVersions(_regSdkBaseDir, "9999.3.5-dummy");
- // Specified CLI version: 9999.3.4-global-dummy
- // CWD: empty
+ // Specified SDK version: 9999.3.4-global-dummy
+ // Cwd: empty
// User: empty
- // Exe: 9999.4.1, 9999.3.4-dummy, 9999.3.3, 9999.3.4, 9999.3.5-dummy
- // Expected: 9999.3.5-dummy from exe dir
+ // Exe: 9999.4.1, 9999.3.4-dummy, 9999.3.4
+ // Reg: 9999.3.3, 9999.3.5-dummy
+ // Expected: 9999.3.5-dummy from reg dir
dotnet.Exec("help")
.WorkingDirectory(_currentWorkingDir)
.WithUserProfile(_userDir)
.Environment(s_DefaultEnvironment)
- .EnvironmentVariable("DOTNET_MULTILEVEL_LOOKUP", "0")
+ .EnvironmentVariable("DOTNET_MULTILEVEL_LOOKUP", "1")
+ .EnvironmentVariable("_DOTNET_TEST_SDK_SELF_REGISTERED_DIR", _regDir)
.CaptureStdOut()
.CaptureStdErr()
.Execute()
.Should()
.Pass()
.And
- .HaveStdErrContaining(Path.Combine(_exeSelectedMessage, "9999.3.5-dummy", _dotnetSdkDllMessageTerminator));
+ .HaveStdErrContaining(Path.Combine(_regSelectedMessage, "9999.3.5-dummy", _dotnetSdkDllMessageTerminator));
- // Add specified CLI version
+ // Add SDK versions
AddAvailableSdkVersions(_exeSdkBaseDir, "9999.3.600");
- // Specified CLI version: 9999.3.4-global-dummy
- // CWD: empty
+ // Specified SDK version: 9999.3.4-global-dummy
+ // Cwd: empty
// User: empty
- // Exe: 9999.4.1, 9999.3.4-dummy, 9999.3.3, 9999.3.4, 9999.3.5-dummy, 9999.3.600
- // Expected: 9999.3.5-dummy from exe dir
+ // Exe: 9999.4.1, 9999.3.4-dummy, 9999.3.4, 9999.3.600
+ // Reg: 9999.3.3, 9999.3.5-dummy
+ // Expected: 9999.3.5-dummy from reg dir
dotnet.Exec("help")
.WorkingDirectory(_currentWorkingDir)
.WithUserProfile(_userDir)
.Environment(s_DefaultEnvironment)
- .EnvironmentVariable("DOTNET_MULTILEVEL_LOOKUP", "0")
+ .EnvironmentVariable("DOTNET_MULTILEVEL_LOOKUP", "1")
+ .EnvironmentVariable("_DOTNET_TEST_SDK_SELF_REGISTERED_DIR", _regDir)
.CaptureStdOut()
.CaptureStdErr()
.Execute()
.Should()
.Pass()
.And
- .HaveStdErrContaining(Path.Combine(_exeSelectedMessage, "9999.3.5-dummy", _dotnetSdkDllMessageTerminator));
+ .HaveStdErrContaining(Path.Combine(_regSelectedMessage, "9999.3.5-dummy", _dotnetSdkDllMessageTerminator));
- // Add specified CLI version
+ // Add SDK versions
AddAvailableSdkVersions(_exeSdkBaseDir, "9999.3.4-global-dummy");
- // Specified CLI version: 9999.3.4-global-dummy
- // CWD: empty
+ // Specified SDK version: 9999.3.4-global-dummy
+ // Cwd: empty
// User: empty
- // Exe: 9999.4.1, 9999.3.4-dummy, 9999.3.3, 9999.3.4, 9999.3.5-dummy, 9999.3.600, 9999.3.4-global-dummy
+ // Exe: 9999.4.1, 9999.3.4-dummy, 9999.3.4, 9999.3.600, 9999.3.4-global-dummy
+ // Reg: 9999.3.3, 9999.3.5-dummy
// Expected: 9999.3.4-global-dummy from exe dir
dotnet.Exec("help")
.WorkingDirectory(_currentWorkingDir)
.WithUserProfile(_userDir)
.Environment(s_DefaultEnvironment)
- .EnvironmentVariable("DOTNET_MULTILEVEL_LOOKUP", "0")
+ .EnvironmentVariable("DOTNET_MULTILEVEL_LOOKUP", "1")
+ .EnvironmentVariable("_DOTNET_TEST_SDK_SELF_REGISTERED_DIR", _regDir)
.CaptureStdOut()
.CaptureStdErr()
.Execute()
.And
.HaveStdErrContaining(Path.Combine(_exeSelectedMessage, "9999.3.4-global-dummy", _dotnetSdkDllMessageTerminator));
- // Verify we have the expected sdk versions
+ // Verify we have the expected SDK versions
dotnet.Exec("--list-sdks")
.WorkingDirectory(_currentWorkingDir)
.WithUserProfile(_userDir)
.Environment(s_DefaultEnvironment)
+ .EnvironmentVariable("DOTNET_MULTILEVEL_LOOKUP", "1")
+ .EnvironmentVariable("_DOTNET_TEST_SDK_SELF_REGISTERED_DIR", _regDir)
.CaptureStdOut()
.Execute()
.Should()
}
[Fact]
- public void SdkLookup_Global_Json_Two_Part_Patch_Rollup()
+ public void SdkMultilevelLookup_Global_Json_Two_Part_Patch_Rollup()
{
+ if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
+ {
+ // Multi-level lookup is only supported on Windows.
+ return;
+ }
+
var fixture = PreviouslyBuiltAndRestoredPortableTestProjectFixture
.Copy();
var dotnet = fixture.BuiltDotnet;
- // Set specified CLI version = 9999.3.304-global-dummy
+ // Set specified SDK version = 9999.3.304-global-dummy
SetGlobalJsonVersion("TwoPart-global.json");
- // Specified CLI version: 9999.3.304-global-dummy
- // CWD: empty
+ // Specified SDK version: 9999.3.304-global-dummy
+ // Cwd: empty
// User: empty
// Exe: empty
+ // Reg: empty
// Expected: no compatible version and a specific error messages
dotnet.Exec("help")
.WorkingDirectory(_currentWorkingDir)
.WithUserProfile(_userDir)
.Environment(s_DefaultEnvironment)
- .EnvironmentVariable("DOTNET_MULTILEVEL_LOOKUP", "0")
+ .EnvironmentVariable("DOTNET_MULTILEVEL_LOOKUP", "1")
+ .EnvironmentVariable("_DOTNET_TEST_SDK_SELF_REGISTERED_DIR", _regDir)
.CaptureStdOut()
.CaptureStdErr()
.Execute(fExpectedToFail: true)
.Should()
.Fail()
.And
- .HaveStdErrContaining("A compatible installed dotnet SDK for global.json version")
- .And
- .HaveStdErrContaining("It was not possible to find any installed dotnet SDKs");
+ .HaveStdErrContaining("A compatible installed dotnet SDK for global.json version");
- // Add some dummy versions
- AddAvailableSdkVersions(_exeSdkBaseDir, "9999.3.57", "9999.3.4-dummy");
+ // Add SDK versions
+ AddAvailableSdkVersions(_regSdkBaseDir, "9999.3.57", "9999.3.4-dummy");
- // Specified CLI version: 9999.3.304-global-dummy
- // CWD: empty
+ // Specified SDK version: 9999.3.304-global-dummy
+ // Cwd: empty
// User: empty
- // Exe: 9999.3.57, 9999.3.4-dummy
+ // Exe: empty
+ // Reg: 9999.3.57, 9999.3.4-dummy
// Expected: no compatible version and a specific error message
dotnet.Exec("help")
.WorkingDirectory(_currentWorkingDir)
.WithUserProfile(_userDir)
.Environment(s_DefaultEnvironment)
- .EnvironmentVariable("DOTNET_MULTILEVEL_LOOKUP", "0")
+ .EnvironmentVariable("DOTNET_MULTILEVEL_LOOKUP", "1")
+ .EnvironmentVariable("_DOTNET_TEST_SDK_SELF_REGISTERED_DIR", _regDir)
.CaptureStdOut()
.CaptureStdErr()
.Execute(fExpectedToFail: true)
.Should()
.Fail()
.And
- .HaveStdErrContaining("A compatible installed dotnet SDK for global.json version")
- .And
- .NotHaveStdErrContaining("It was not possible to find any installed dotnet SDKs");
+ .HaveStdErrContaining("A compatible installed dotnet SDK for global.json version");
- // Add specified CLI version
+ // Add SDK versions
AddAvailableSdkVersions(_exeSdkBaseDir, "9999.3.300", "9999.7.304-global-dummy");
- // Specified CLI version: 9999.3.304-global-dummy
- // CWD: empty
+ // Specified SDK version: 9999.3.304-global-dummy
+ // Cwd: empty
// User: empty
- // Exe: 9999.3.57, 9999.3.4-dummy, 9999.3.300, 9999.7.304-global-dummy
+ // Exe: 9999.3.300, 9999.7.304-global-dummy
+ // Reg: 9999.3.57, 9999.3.4-dummy
// Expected: no compatible version and a specific error message
dotnet.Exec("help")
.WorkingDirectory(_currentWorkingDir)
.WithUserProfile(_userDir)
.Environment(s_DefaultEnvironment)
- .EnvironmentVariable("DOTNET_MULTILEVEL_LOOKUP", "0")
+ .EnvironmentVariable("DOTNET_MULTILEVEL_LOOKUP", "1")
+ .EnvironmentVariable("_DOTNET_TEST_SDK_SELF_REGISTERED_DIR", _regDir)
.CaptureStdOut()
.CaptureStdErr()
.Execute(fExpectedToFail: true)
.Should()
.Fail()
.And
- .HaveStdErrContaining("A compatible installed dotnet SDK for global.json version")
- .And
- .NotHaveStdErrContaining("It was not possible to find any installed dotnet SDKs");
+ .HaveStdErrContaining("A compatible installed dotnet SDK for global.json version");
- // Add specified CLI version
- AddAvailableSdkVersions(_exeSdkBaseDir, "9999.3.304");
+ // Add SDK versions
+ AddAvailableSdkVersions(_regSdkBaseDir, "9999.3.304");
- // Specified CLI version: 9999.3.304-global-dummy
- // CWD: empty
+ // Specified SDK version: 9999.3.304-global-dummy
+ // Cwd: empty
// User: empty
- // Exe: 99999.3.57, 9999.3.4-dummy, 9999.3.300, 9999.7.304-global-dummy, 9999.3.304
- // Expected: 9999.3.304 from exe dir
+ // Exe: 9999.3.300, 9999.7.304-global-dummy
+ // Reg: 9999.3.57, 9999.3.4-dummy, 9999.3.304
+ // Expected: 9999.3.304 from reg dir
dotnet.Exec("help")
.WorkingDirectory(_currentWorkingDir)
.WithUserProfile(_userDir)
.Environment(s_DefaultEnvironment)
- .EnvironmentVariable("DOTNET_MULTILEVEL_LOOKUP", "0")
+ .EnvironmentVariable("DOTNET_MULTILEVEL_LOOKUP", "1")
+ .EnvironmentVariable("_DOTNET_TEST_SDK_SELF_REGISTERED_DIR", _regDir)
.CaptureStdOut()
.CaptureStdErr()
.Execute()
.Should()
.Pass()
.And
- .HaveStdErrContaining(Path.Combine(_exeSelectedMessage, "9999.3.304", _dotnetSdkDllMessageTerminator));
+ .HaveStdErrContaining(Path.Combine(_regSelectedMessage, "9999.3.304", _dotnetSdkDllMessageTerminator));
- // Add specified CLI version
+ // Add SDK versions
AddAvailableSdkVersions(_exeSdkBaseDir, "9999.3.399", "9999.3.399-dummy", "9999.3.400");
- // Specified CLI version: 9999.3.304-global-dummy
- // CWD: empty
+ // Specified SDK version: 9999.3.304-global-dummy
+ // Cwd: empty
// User: empty
- // Exe: 9999.3.57, 9999.3.4-dummy, 9999.3.300, 9999.7.304-global-dummy, 9999.3.304, 9999.3.399, 9999.3.399-dummy, 9999.3.400
+ // Exe: 9999.3.300, 9999.7.304-global-dummy, 9999.3.399, 9999.3.399-dummy, 9999.3.400
+ // Reg: 9999.3.57, 9999.3.4-dummy, 9999.3.304
// Expected: 9999.3.399 from exe dir
dotnet.Exec("help")
.WorkingDirectory(_currentWorkingDir)
.WithUserProfile(_userDir)
.Environment(s_DefaultEnvironment)
- .EnvironmentVariable("DOTNET_MULTILEVEL_LOOKUP", "0")
+ .EnvironmentVariable("DOTNET_MULTILEVEL_LOOKUP", "1")
+ .EnvironmentVariable("_DOTNET_TEST_SDK_SELF_REGISTERED_DIR", _regDir)
.CaptureStdOut()
.CaptureStdErr()
.Execute()
.And
.HaveStdErrContaining(Path.Combine(_exeSelectedMessage, "9999.3.399", _dotnetSdkDllMessageTerminator));
- // Add specified CLI version
+ // Add SDK versions
AddAvailableSdkVersions(_exeSdkBaseDir, "9999.3.2400, 9999.3.3004");
+ AddAvailableSdkVersions(_regSdkBaseDir, "9999.3.2400, 9999.3.3004");
- // Specified CLI version: 9999.3.304-global-dummy
- // CWD: empty
+ // Specified SDK version: 9999.3.304-global-dummy
+ // Cwd: empty
// User: empty
- // Exe: 9999.3.57, 9999.3.4-dummy, 9999.3.300, 9999.7.304-global-dummy, 9999.3.304, 9999.3.399, 9999.3.399-dummy, 9999.3.400, 9999.3.2400, 9999.3.3004
+ // Exe: 9999.3.300, 9999.7.304-global-dummy, 9999.3.399, 9999.3.399-dummy, 9999.3.400, 9999.3.2400, 9999.3.3004
+ // Reg: 9999.3.57, 9999.3.4-dummy, 9999.3.304, 9999.3.2400, 9999.3.3004
// Expected: 9999.3.399 from exe dir
dotnet.Exec("help")
.WorkingDirectory(_currentWorkingDir)
.WithUserProfile(_userDir)
.Environment(s_DefaultEnvironment)
- .EnvironmentVariable("DOTNET_MULTILEVEL_LOOKUP", "0")
+ .EnvironmentVariable("DOTNET_MULTILEVEL_LOOKUP", "1")
+ .EnvironmentVariable("_DOTNET_TEST_SDK_SELF_REGISTERED_DIR", _regDir)
.CaptureStdOut()
.CaptureStdErr()
.Execute()
.And
.HaveStdErrContaining(Path.Combine(_exeSelectedMessage, "9999.3.399", _dotnetSdkDllMessageTerminator));
- // Add specified CLI version
- AddAvailableSdkVersions(_exeSdkBaseDir, "9999.3.304-global-dummy");
+ // Add SDK versions
+ AddAvailableSdkVersions(_regSdkBaseDir, "9999.3.304-global-dummy");
- // Specified CLI version: 9999.3.304-global-dummy
- // CWD: empty
+ // Specified SDK version: 9999.3.304-global-dummy
+ // Cwd: empty
// User: empty
- // Exe: 9999.3.57, 9999.3.4-dummy, 9999.3.300, 9999.7.304-global-dummy, 9999.3.304, 9999.3.399, 9999.3.399-dummy, 9999.3.400, 9999.3.2400, 9999.3.3004, 9999.3.304-global-dummy
- // Expected: 9999.3.304-global-dummy from exe dir
+ // Exe: 9999.3.300, 9999.7.304-global-dummy, 9999.3.399, 9999.3.399-dummy, 9999.3.400, 9999.3.2400, 9999.3.3004
+ // Reg: 9999.3.57, 9999.3.4-dummy, 9999.3.304, 9999.3.2400, 9999.3.3004, 9999.3.304-global-dummy
+ // Expected: 9999.3.304-global-dummy from reg dir
dotnet.Exec("help")
.WorkingDirectory(_currentWorkingDir)
.WithUserProfile(_userDir)
.Environment(s_DefaultEnvironment)
- .EnvironmentVariable("DOTNET_MULTILEVEL_LOOKUP", "0")
+ .EnvironmentVariable("DOTNET_MULTILEVEL_LOOKUP", "1")
+ .EnvironmentVariable("_DOTNET_TEST_SDK_SELF_REGISTERED_DIR", _regDir)
.CaptureStdOut()
.CaptureStdErr()
.Execute()
.Should()
.Pass()
.And
- .HaveStdErrContaining(Path.Combine(_exeSelectedMessage, "9999.3.304-global-dummy", _dotnetSdkDllMessageTerminator));
+ .HaveStdErrContaining(Path.Combine(_regSelectedMessage, "9999.3.304-global-dummy", _dotnetSdkDllMessageTerminator));
- // Verify we have the expected sdk versions
+ // Verify we have the expected SDK versions
dotnet.Exec("--list-sdks")
.WorkingDirectory(_currentWorkingDir)
.WithUserProfile(_userDir)
.Environment(s_DefaultEnvironment)
+ .EnvironmentVariable("DOTNET_MULTILEVEL_LOOKUP", "1")
+ .EnvironmentVariable("_DOTNET_TEST_SDK_SELF_REGISTERED_DIR", _regDir)
.CaptureStdOut()
.Execute()
.Should()
}
[Fact]
- public void SdkLookup_Negative_Version()
+ public void SdkMultilevelLookup_Precedential_Order()
{
+ if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
+ {
+ // Multi-level lookup is only supported on Windows.
+ return;
+ }
+
var fixture = PreviouslyBuiltAndRestoredPortableTestProjectFixture
.Copy();
var dotnet = fixture.BuiltDotnet;
- // Add a negative CLI version
- AddAvailableSdkVersions(_exeSdkBaseDir, "-1.-1.-1");
+ // Add SDK versions
+ AddAvailableSdkVersions(_regSdkBaseDir, "9999.0.4");
- // Specified CLI version: none
- // CWD: empty
+ // Specified SDK version: none
+ // Cwd: empty
// User: empty
- // Exe: -1.-1.-1
- // Expected: no compatible version and a specific error messages
+ // Exe: empty
+ // Reg: 9999.0.4
+ // Expected: 9999.0.4 from reg dir
dotnet.Exec("help")
.WorkingDirectory(_currentWorkingDir)
.WithUserProfile(_userDir)
.Environment(s_DefaultEnvironment)
- .EnvironmentVariable("DOTNET_MULTILEVEL_LOOKUP", "0")
+ .EnvironmentVariable("DOTNET_MULTILEVEL_LOOKUP", "1")
+ .EnvironmentVariable("_DOTNET_TEST_SDK_SELF_REGISTERED_DIR", _regDir)
.CaptureStdOut()
.CaptureStdErr()
- .Execute(fExpectedToFail: true)
+ .Execute()
.Should()
- .Fail()
- .And
- .HaveStdErrContaining("It was not possible to find any installed dotnet SDKs")
+ .Pass()
.And
- .HaveStdErrContaining("Did you mean to run dotnet SDK commands? Please install dotnet SDK from");
+ .HaveStdErrContaining(Path.Combine(_regSelectedMessage, "9999.0.4", _dotnetSdkDllMessageTerminator));
- // Add specified CLI version
+ // Add SDK versions
AddAvailableSdkVersions(_exeSdkBaseDir, "9999.0.4");
- // Specified CLI version: none
- // CWD: empty
+ // Specified SDK version: none
+ // Cwd: empty
// User: empty
- // Exe: -1.-1.-1, 9999.0.4
+ // Exe: 9999.0.4
+ // Reg: 9999.0.4
// Expected: 9999.0.4 from exe dir
dotnet.Exec("help")
.WorkingDirectory(_currentWorkingDir)
.WithUserProfile(_userDir)
.Environment(s_DefaultEnvironment)
- .EnvironmentVariable("DOTNET_MULTILEVEL_LOOKUP", "0")
+ .EnvironmentVariable("DOTNET_MULTILEVEL_LOOKUP", "1")
+ .EnvironmentVariable("_DOTNET_TEST_SDK_SELF_REGISTERED_DIR", _regDir)
.CaptureStdOut()
.CaptureStdErr()
.Execute()
.Pass()
.And
.HaveStdErrContaining(Path.Combine(_exeSelectedMessage, "9999.0.4", _dotnetSdkDllMessageTerminator));
-
- // Verify we have the expected sdk versions
- dotnet.Exec("--list-sdks")
- .WorkingDirectory(_currentWorkingDir)
- .WithUserProfile(_userDir)
- .Environment(s_DefaultEnvironment)
- .EnvironmentVariable("DOTNET_MULTILEVEL_LOOKUP", "0")
- .CaptureStdOut()
- .Execute()
- .Should()
- .Pass()
- .And
- .HaveStdOutContaining("9999.0.4");
}
-
+
[Fact]
- public void SdkLookup_Must_Pick_The_Highest_Semantic_Version()
+ public void SdkMultilevelLookup_Must_Pick_The_Highest_Semantic_Version()
{
+ if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
+ {
+ // Multi-level lookup is only supported on Windows.
+ return;
+ }
+
var fixture = PreviouslyBuiltAndRestoredPortableTestProjectFixture
.Copy();
var dotnet = fixture.BuiltDotnet;
- // Add dummy versions in the exe dir
- AddAvailableSdkVersions(_exeSdkBaseDir, "9999.0.0", "9999.0.3-dummy");
+ // Add SDK versions
+ AddAvailableSdkVersions(_regSdkBaseDir, "9999.0.0", "9999.0.3-dummy");
- // Specified CLI version: none
- // CWD: empty
+ // Specified SDK version: none
+ // Cwd: empty
// User: empty
- // Exe: 9999.0.0, 9999.0.3-dummy
- // Expected: 9999.0.3-dummy from exe dir
+ // Exe: empty
+ // Reg: 9999.0.0, 9999.0.3-dummy
+ // Expected: 9999.0.3-dummy from reg dir
dotnet.Exec("help")
.WorkingDirectory(_currentWorkingDir)
.WithUserProfile(_userDir)
.Environment(s_DefaultEnvironment)
+ .EnvironmentVariable("DOTNET_MULTILEVEL_LOOKUP", "1")
+ .EnvironmentVariable("_DOTNET_TEST_SDK_SELF_REGISTERED_DIR", _regDir)
.CaptureStdOut()
.CaptureStdErr()
.Execute()
.Should()
.Pass()
.And
- .HaveStdErrContaining(Path.Combine(_exeSelectedMessage, "9999.0.3-dummy", _dotnetSdkDllMessageTerminator));
+ .HaveStdErrContaining(Path.Combine(_regSelectedMessage, "9999.0.3-dummy", _dotnetSdkDllMessageTerminator));
- // Add dummy versions in the exe dir
+ // Add SDK versions
AddAvailableSdkVersions(_exeSdkBaseDir, "9999.0.3");
- // Specified CLI version: none
- // CWD: empty
+ // Specified SDK version: none
+ // Cwd: empty
// User: empty
- // Exe: 9999.0.0, 9999.0.3-dummy, 9999.0.3
+ // Exe: 9999.0.3
+ // Reg: 9999.0.0, 9999.0.3-dummy
// Expected: 9999.0.3 from exe dir
dotnet.Exec("help")
.WorkingDirectory(_currentWorkingDir)
.WithUserProfile(_userDir)
.Environment(s_DefaultEnvironment)
+ .EnvironmentVariable("DOTNET_MULTILEVEL_LOOKUP", "1")
+ .EnvironmentVariable("_DOTNET_TEST_SDK_SELF_REGISTERED_DIR", _regDir)
.CaptureStdOut()
.CaptureStdErr()
.Execute()
.And
.HaveStdErrContaining(Path.Combine(_exeSelectedMessage, "9999.0.3", _dotnetSdkDllMessageTerminator));
- // Add dummy versions
+ // Add SDK versions
AddAvailableSdkVersions(_userSdkBaseDir, "9999.0.200");
AddAvailableSdkVersions(_cwdSdkBaseDir, "10000.0.0");
- AddAvailableSdkVersions(_exeSdkBaseDir, "9999.0.100");
+ AddAvailableSdkVersions(_regSdkBaseDir, "9999.0.100");
- // Specified CLI version: none
- // CWD: 10000.0.0 --> should not be picked
+ // Specified SDK version: none
+ // Cwd: 10000.0.0 --> should not be picked
// User: 9999.0.200 --> should not be picked
- // Exe: 9999.0.0, 9999.0.3-dummy, 9999.0.3, 9999.0.100
- // Expected: 9999.0.100 from exe dir
+ // Exe: 9999.0.3
+ // Reg: 9999.0.0, 9999.0.3-dummy, 9999.0.100
+ // Expected: 9999.0.100 from reg dir
dotnet.Exec("help")
.WorkingDirectory(_currentWorkingDir)
.WithUserProfile(_userDir)
.Environment(s_DefaultEnvironment)
+ .EnvironmentVariable("DOTNET_MULTILEVEL_LOOKUP", "1")
+ .EnvironmentVariable("_DOTNET_TEST_SDK_SELF_REGISTERED_DIR", _regDir)
.CaptureStdOut()
.CaptureStdErr()
.Execute()
.Should()
.Pass()
.And
- .HaveStdErrContaining(Path.Combine(_exeSelectedMessage, "9999.0.100", _dotnetSdkDllMessageTerminator));
+ .HaveStdErrContaining(Path.Combine(_regSelectedMessage, "9999.0.100", _dotnetSdkDllMessageTerminator));
- // Add a dummy version in the exe dir
+ // Add SDK versions
AddAvailableSdkVersions(_exeSdkBaseDir, "9999.0.80");
- // Specified CLI version: none
- // CWD: 10000.0.0 --> should not be picked
+ // Specified SDK version: none
+ // Cwd: 10000.0.0 --> should not be picked
// User: 9999.0.200 --> should not be picked
- // Exe: 9999.0.0, 9999.0.3-dummy, 9999.0.3, 9999.0.100, 9999.0.80
- // Expected: 9999.0.100 from exe dir
+ // Exe: 9999.0.3, 9999.0.80
+ // Reg: 9999.0.0, 9999.0.3-dummy, 9999.0.100
+ // Expected: 9999.0.100 from reg dir
dotnet.Exec("help")
.WorkingDirectory(_currentWorkingDir)
.WithUserProfile(_userDir)
.Environment(s_DefaultEnvironment)
+ .EnvironmentVariable("DOTNET_MULTILEVEL_LOOKUP", "1")
+ .EnvironmentVariable("_DOTNET_TEST_SDK_SELF_REGISTERED_DIR", _regDir)
.CaptureStdOut()
.CaptureStdErr()
.Execute()
.Should()
.Pass()
.And
- .HaveStdErrContaining(Path.Combine(_exeSelectedMessage, "9999.0.100", _dotnetSdkDllMessageTerminator));
+ .HaveStdErrContaining(Path.Combine(_regSelectedMessage, "9999.0.100", _dotnetSdkDllMessageTerminator));
- // Add a dummy version in the user dir
+ // Add SDK versions
AddAvailableSdkVersions(_exeSdkBaseDir, "9999.0.5500000");
- // Specified CLI version: none
- // CWD: 10000.0.0 --> should not be picked
+ // Specified SDK version: none
+ // Cwd: 10000.0.0 --> should not be picked
// User: 9999.0.200 --> should not be picked
- // Exe: 9999.0.0, 9999.0.3-dummy, 9999.0.3, 9999.0.100, 9999.0.80, 9999.0.5500000
+ // Exe: 9999.0.3, 9999.0.80, 9999.0.5500000
+ // Reg: 9999.0.0, 9999.0.3-dummy, 9999.0.100
// Expected: 9999.0.5500000 from exe dir
dotnet.Exec("help")
.WorkingDirectory(_currentWorkingDir)
.WithUserProfile(_userDir)
.Environment(s_DefaultEnvironment)
+ .EnvironmentVariable("DOTNET_MULTILEVEL_LOOKUP", "1")
+ .EnvironmentVariable("_DOTNET_TEST_SDK_SELF_REGISTERED_DIR", _regDir)
.CaptureStdOut()
.CaptureStdErr()
.Execute()
.And
.HaveStdErrContaining(Path.Combine(_exeSelectedMessage, "9999.0.5500000", _dotnetSdkDllMessageTerminator));
- // Add a dummy version in the user dir
- AddAvailableSdkVersions(_exeSdkBaseDir, "9999.0.52000000");
+ // Add SDK versions
+ AddAvailableSdkVersions(_regSdkBaseDir, "9999.0.52000000");
- // Specified CLI version: none
- // CWD: 10000.0.0 --> should not be picked
+ // Specified SDK version: none
+ // Cwd: 10000.0.0 --> should not be picked
// User: 9999.0.200 --> should not be picked
- // Exe: 9999.0.0, 9999.0.3-dummy, 9999.0.3, 9999.0.100, 9999.0.80, 9999.0.5500000, 9999.0.52000000
- // Expected: 9999.0.52000000 from exe dir
+ // Exe: 9999.0.3, 9999.0.80, 9999.0.5500000
+ // Reg: 9999.0.0, 9999.0.3-dummy, 9999.0.100, 9999.0.52000000
+ // Expected: 9999.0.52000000 from reg dir
dotnet.Exec("help")
.WorkingDirectory(_currentWorkingDir)
.WithUserProfile(_userDir)
.Environment(s_DefaultEnvironment)
+ .EnvironmentVariable("DOTNET_MULTILEVEL_LOOKUP", "1")
+ .EnvironmentVariable("_DOTNET_TEST_SDK_SELF_REGISTERED_DIR", _regDir)
.CaptureStdOut()
.CaptureStdErr()
.Execute()
.Should()
.Pass()
.And
- .HaveStdErrContaining(Path.Combine(_exeSelectedMessage, "9999.0.52000000", _dotnetSdkDllMessageTerminator));
+ .HaveStdErrContaining(Path.Combine(_regSelectedMessage, "9999.0.52000000", _dotnetSdkDllMessageTerminator));
- // Verify we have the expected sdk versions
+ // Verify we have the expected SDK versions
dotnet.Exec("--list-sdks")
.WorkingDirectory(_currentWorkingDir)
.WithUserProfile(_userDir)
.Environment(s_DefaultEnvironment)
+ .EnvironmentVariable("DOTNET_MULTILEVEL_LOOKUP", "1")
+ .EnvironmentVariable("_DOTNET_TEST_SDK_SELF_REGISTERED_DIR", _regDir)
.CaptureStdOut()
.Execute()
.Should()
using Newtonsoft.Json.Linq;
using System;
using System.IO;
+using System.Runtime.InteropServices;
using Xunit;
namespace Microsoft.DotNet.CoreSetup.Test.HostActivation.MultilevelSharedFxLookup
private string _currentWorkingDir;
private string _userDir;
- private string _executableDir;
- private string _globalDir;
+ private string _exeDir;
+ private string _regDir;
private string _cwdSharedFxBaseDir;
private string _cwdSharedUberFxBaseDir;
private string _userSharedFxBaseDir;
private string _userSharedUberFxBaseDir;
private string _exeSharedFxBaseDir;
private string _exeSharedUberFxBaseDir;
- private string _globalSharedFxBaseDir;
- private string _globalSharedUberFxBaseDir;
+ private string _regSharedFxBaseDir;
+ private string _regSharedUberFxBaseDir;
private string _builtSharedFxDir;
private string _builtSharedUberFxDir;
private string _cwdSelectedMessage;
private string _userSelectedMessage;
private string _exeSelectedMessage;
- private string _globalSelectedMessage;
+ private string _regSelectedMessage;
private string _cwdFoundUberFxMessage;
private string _userFoundUberFxMessage;
private string _exeFoundUberFxMessage;
- private string _globalFoundUberFxMessage;
+ private string _regFoundUberFxMessage;
private string _sharedFxVersion;
private string _multilevelDir;
// be used during tests
_currentWorkingDir = Path.Combine(_multilevelDir, "cwd");
_userDir = Path.Combine(_multilevelDir, "user");
- _executableDir = Path.Combine(_multilevelDir, "exe");
- _globalDir = Path.Combine(_multilevelDir, "global");
+ _exeDir = Path.Combine(_multilevelDir, "exe");
+ _regDir = Path.Combine(_multilevelDir, "reg");
- RepoDirectories = new RepoDirectoriesProvider(builtDotnet: _executableDir);
+ RepoDirectories = new RepoDirectoriesProvider(builtDotnet: _exeDir);
// SharedFxBaseDirs contain all available version folders
_cwdSharedFxBaseDir = Path.Combine(_currentWorkingDir, "shared", "Microsoft.NETCore.App");
_userSharedFxBaseDir = Path.Combine(_userDir, ".dotnet", RepoDirectories.BuildArchitecture, "shared", "Microsoft.NETCore.App");
- _exeSharedFxBaseDir = Path.Combine(_executableDir, "shared", "Microsoft.NETCore.App");
- _globalSharedFxBaseDir = Path.Combine(_globalDir, "shared", "Microsoft.NETCore.App");
+ _exeSharedFxBaseDir = Path.Combine(_exeDir, "shared", "Microsoft.NETCore.App");
+ _regSharedFxBaseDir = Path.Combine(_regDir, "shared", "Microsoft.NETCore.App");
_cwdSharedUberFxBaseDir = Path.Combine(_currentWorkingDir, "shared", "Microsoft.UberFramework");
_userSharedUberFxBaseDir = Path.Combine(_userDir, ".dotnet", RepoDirectories.BuildArchitecture, "shared", "Microsoft.UberFramework");
- _exeSharedUberFxBaseDir = Path.Combine(_executableDir, "shared", "Microsoft.UberFramework");
- _globalSharedUberFxBaseDir = Path.Combine(_globalDir, "shared", "Microsoft.UberFramework");
+ _exeSharedUberFxBaseDir = Path.Combine(_exeDir, "shared", "Microsoft.UberFramework");
+ _regSharedUberFxBaseDir = Path.Combine(_regDir, "shared", "Microsoft.UberFramework");
// Create directories. It's necessary to copy the entire publish folder to the exe dir because
// we'll need to build from it. The CopyDirectory method automatically creates the dest dir
Directory.CreateDirectory(_cwdSharedFxBaseDir);
Directory.CreateDirectory(_userSharedFxBaseDir);
- Directory.CreateDirectory(_globalSharedFxBaseDir);
+ Directory.CreateDirectory(_regSharedFxBaseDir);
Directory.CreateDirectory(_cwdSharedUberFxBaseDir);
Directory.CreateDirectory(_userSharedUberFxBaseDir);
- Directory.CreateDirectory(_globalSharedUberFxBaseDir);
- SharedFramework.CopyDirectory(_builtDotnet, _executableDir);
+ Directory.CreateDirectory(_regSharedUberFxBaseDir);
+ SharedFramework.CopyDirectory(_builtDotnet, _exeDir);
- //Copy dotnet to global directory
- File.Copy(Path.Combine(_builtDotnet, $"dotnet{Constants.ExeSuffix}"), Path.Combine(_globalDir, $"dotnet{Constants.ExeSuffix}"), true);
+ //Copy dotnet to self-registered directory
+ File.Copy(Path.Combine(_builtDotnet, $"dotnet{Constants.ExeSuffix}"), Path.Combine(_regDir, $"dotnet{Constants.ExeSuffix}"), true);
// Restore and build SharedFxLookupPortableApp from exe dir
PreviouslyBuiltAndRestoredPortableTestProjectFixture = new TestProjectFixture("SharedFxLookupPortableApp", RepoDirectories)
_cwdSelectedMessage = $"The expected {_hostPolicyDllName} directory is [{_cwdSharedFxBaseDir}";
_userSelectedMessage = $"The expected {_hostPolicyDllName} directory is [{_userSharedFxBaseDir}";
_exeSelectedMessage = $"The expected {_hostPolicyDllName} directory is [{_exeSharedFxBaseDir}";
- _globalSelectedMessage = $"The expected {_hostPolicyDllName} directory is [{_globalSharedFxBaseDir}";
+ _regSelectedMessage = $"The expected {_hostPolicyDllName} directory is [{_regSharedFxBaseDir}";
_cwdFoundUberFxMessage = $"Chose FX version [{_cwdSharedUberFxBaseDir}";
_userFoundUberFxMessage = $"Chose FX version [{_userSharedUberFxBaseDir}";
_exeFoundUberFxMessage = $"Chose FX version [{_exeSharedUberFxBaseDir}";
- _globalFoundUberFxMessage = $"Chose FX version [{_globalSharedUberFxBaseDir}";
+ _regFoundUberFxMessage = $"Chose FX version [{_regSharedUberFxBaseDir}";
}
public void Dispose()
}
[Fact]
- public void SharedFxLookup_Must_Verify_Folders_in_the_Correct_Order()
+ public void SharedMultilevelFxLookup_Must_Verify_Folders_in_the_Correct_Order()
{
+ if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
+ {
+ // Multi-level lookup is only supported on Windows.
+ return;
+ }
+
var fixture = PreviouslyBuiltAndRestoredPortableTestProjectFixture
.Copy();
string runtimeConfig = Path.Combine(fixture.TestProject.OutputDirectory, "SharedFxLookupPortableApp.runtimeconfig.json");
SharedFramework.SetRuntimeConfigJson(runtimeConfig, "9999.0.0");
- // Add version in the exe dir
- SharedFramework.AddAvailableSharedFxVersions(_builtSharedFxDir, _exeSharedFxBaseDir, "9999.0.0");
+ // Add version in the reg dir
+ SharedFramework.AddAvailableSharedFxVersions(_builtSharedFxDir, _regSharedFxBaseDir, "9999.0.0");
// Version: 9999.0.0
+ // Cwd: empty
// User: empty
- // Exe: 9999.0.0
- // Expected: 9999.0.0 from exe dir
+ // Exe: empty
+ // Reg: 9999.0.0
+ // Expected: 9999.0.0 from reg dir
dotnet.Exec(appDll)
.WorkingDirectory(_currentWorkingDir)
- .EnvironmentVariable("COREHOST_TRACE", "1")
.WithUserProfile(_userDir)
+ .EnvironmentVariable("COREHOST_TRACE", "1")
+ .EnvironmentVariable("DOTNET_MULTILEVEL_LOOKUP", "1")
+ .EnvironmentVariable("_DOTNET_TEST_SDK_SELF_REGISTERED_DIR", _regDir)
.CaptureStdOut()
.CaptureStdErr()
.Execute()
.Should()
.Pass()
.And
- .HaveStdErrContaining(_exeSelectedMessage);
+ .HaveStdErrContaining(Path.Combine(_regSelectedMessage, "9999.0.0"));
// Add a dummy version in the user dir
SharedFramework.AddAvailableSharedFxVersions(_builtSharedFxDir, _userSharedFxBaseDir, "9999.0.0");
// Version: 9999.0.0
+ // Cwd: empty
// User: 9999.0.0 --> should not be picked
- // Exe: 9999.0.0
- // Expected: 9999.0.0 from user dir
+ // Exe: empty
+ // Reg: 9999.0.0
+ // Expected: 9999.0.0 from reg dir
dotnet.Exec(appDll)
.WorkingDirectory(_currentWorkingDir)
- .EnvironmentVariable("COREHOST_TRACE", "1")
.WithUserProfile(_userDir)
+ .EnvironmentVariable("COREHOST_TRACE", "1")
+ .EnvironmentVariable("DOTNET_MULTILEVEL_LOOKUP", "1")
+ .EnvironmentVariable("_DOTNET_TEST_SDK_SELF_REGISTERED_DIR", _regDir)
.CaptureStdOut()
.CaptureStdErr()
.Execute()
.Should()
.Pass()
.And
- .HaveStdErrContaining(_exeSelectedMessage);
+ .HaveStdErrContaining(Path.Combine(_regSelectedMessage, "9999.0.0"));
- // Add a dummy version in the cwd
+ // Add a dummy version in the cwd dir
SharedFramework.AddAvailableSharedFxVersions(_builtSharedFxDir, _cwdSharedFxBaseDir, "9999.0.0");
// Version: 9999.0.0
- // CWD: 9999.0.0 --> should not be picked
- // User: 9999.0.0
- // Exe: 9999.0.0
- // Expected: 9999.0.0 from user Exe
+ // Cwd: 9999.0.0 --> should not be picked
+ // User: 9999.0.0 --> should not be picked
+ // Exe: empty
+ // Reg: 9999.0.0
+ // Expected: 9999.0.0 from reg dir
dotnet.Exec(appDll)
.WorkingDirectory(_currentWorkingDir)
- .EnvironmentVariable("COREHOST_TRACE", "1")
.WithUserProfile(_userDir)
+ .EnvironmentVariable("COREHOST_TRACE", "1")
+ .EnvironmentVariable("DOTNET_MULTILEVEL_LOOKUP", "1")
+ .EnvironmentVariable("_DOTNET_TEST_SDK_SELF_REGISTERED_DIR", _regDir)
.CaptureStdOut()
.CaptureStdErr()
.Execute()
.Should()
.Pass()
.And
- .HaveStdErrContaining(_exeSelectedMessage);
-
- // Verify we have the expected runtime versions
- dotnet.Exec("--list-runtimes")
- .WorkingDirectory(_currentWorkingDir)
- .WithUserProfile(_userDir)
- .CaptureStdOut()
- .Execute()
- .Should()
- .Pass()
- .And
- .HaveStdOutContaining("Microsoft.NETCore.App 9999.0.0");
- }
-
- [Fact]
- public void SharedFxLookup_Must_Not_Roll_Forward_If_Framework_Version_Is_Specified_Through_Argument()
- {
- var fixture = PreviouslyBuiltAndRestoredPortableTestProjectFixture
- .Copy();
+ .HaveStdErrContaining(Path.Combine(_regSelectedMessage, "9999.0.0"));
- var dotnet = fixture.BuiltDotnet;
- var appDll = fixture.TestProject.AppDll;
-
- // Add some dummy versions
- SharedFramework.AddAvailableSharedFxVersions(_builtSharedFxDir, _exeSharedFxBaseDir, "9999.0.0", "9999.0.2", "9999.0.0-dummy2", "9999.0.3", "9999.0.0-dummy3");
+ // Add version in the exe dir
+ SharedFramework.AddAvailableSharedFxVersions(_builtSharedFxDir, _exeSharedFxBaseDir, "9999.0.0");
- // Version: 9999.0.0 (through --fx-version arg)
- // Exe: 9999.0.2, 9999.0.0-dummy2, 9999.0.0, 9999.0.3, 9999.0.0-dummy3
- // global: empty
+ // Version: 9999.0.0
+ // Cwd: 9999.0.0 --> should not be picked
+ // User: 9999.0.0 --> should not be picked
+ // Exe: 9999.0.0
+ // Reg: 9999.0.0
// Expected: 9999.0.0 from exe dir
- dotnet.Exec("--fx-version", "9999.0.0", appDll)
+ dotnet.Exec(appDll)
.WorkingDirectory(_currentWorkingDir)
+ .WithUserProfile(_userDir)
.EnvironmentVariable("COREHOST_TRACE", "1")
+ .EnvironmentVariable("DOTNET_MULTILEVEL_LOOKUP", "1")
+ .EnvironmentVariable("_DOTNET_TEST_SDK_SELF_REGISTERED_DIR", _regDir)
.CaptureStdOut()
.CaptureStdErr()
.Execute()
.And
.HaveStdErrContaining(Path.Combine(_exeSelectedMessage, "9999.0.0"));
- // Version: 9999.0.0-dummy1 (through --fx-version arg)
- // Exe: 9999.0.2, 9999.0.0-dummy2,9999.0.0, 9999.0.3, 9999.0.0-dummy3
- // global: empty
- // Expected: no compatible version
- dotnet.Exec("--fx-version", "9999.0.0-dummy1", appDll)
- .WorkingDirectory(_currentWorkingDir)
- .EnvironmentVariable("COREHOST_TRACE", "1")
- .CaptureStdOut()
- .CaptureStdErr()
- .Execute(fExpectedToFail: true)
- .Should()
- .Fail()
- .And
- .HaveStdErrContaining("It was not possible to find any compatible framework version");
-
// Verify we have the expected runtime versions
dotnet.Exec("--list-runtimes")
.WorkingDirectory(_currentWorkingDir)
- .CaptureStdOut()
- .Execute()
- .Should()
- .Pass()
- .And
- .HaveStdOutContaining("Microsoft.NETCore.App 9999.0.0")
- .And
- .HaveStdOutContaining("Microsoft.NETCore.App 9999.0.0-dummy2")
- .And
- .HaveStdOutContaining("Microsoft.NETCore.App 9999.0.2")
- .And
- .HaveStdOutContaining("Microsoft.NETCore.App 9999.0.3")
- .And
- .HaveStdOutContaining("Microsoft.NETCore.App 9999.0.0-dummy3");
- }
-
- [Fact]
- public void Roll_Forward_On_No_Candidate_Fx_Must_Happen_If_Compatible_Patch_Version_Is_Not_Available()
- {
- var fixture = PreviouslyBuiltAndRestoredPortableTestProjectFixture
- .Copy();
-
- var dotnet = fixture.BuiltDotnet;
- var appDll = fixture.TestProject.AppDll;
-
- // Set desired version = 9999.0.0
- string runtimeConfig = Path.Combine(fixture.TestProject.OutputDirectory, "SharedFxLookupPortableApp.runtimeconfig.json");
- SharedFramework.SetRuntimeConfigJson(runtimeConfig, "9999.0.0");
-
- // Add some dummy versions in the exe
- SharedFramework.AddAvailableSharedFxVersions(_builtSharedFxDir, _exeSharedFxBaseDir, "10000.1.1", "10000.1.3");
-
- // Version: 9999.0.0
- // 'Roll forward on no candidate fx' enabled with value 2 (major+minor) through env var
- // exe: 10000.1.1, 10000.1.3
- // Expected: 10000.1.3 from exe
- dotnet.Exec(appDll)
- .WorkingDirectory(_currentWorkingDir)
- .EnvironmentVariable("DOTNET_ROLL_FORWARD_ON_NO_CANDIDATE_FX", "2")
- .EnvironmentVariable("COREHOST_TRACE", "1")
- .CaptureStdOut()
- .CaptureStdErr()
- .Execute()
- .Should()
- .Pass()
- .And
- .HaveStdErrContaining(Path.Combine(_exeSelectedMessage, "10000.1.3"));
-
- // Add a dummy version in the exe dir
- SharedFramework.AddAvailableSharedFxVersions(_builtSharedFxDir, _exeSharedFxBaseDir, "9999.1.1");
-
- // Version: 9999.0.0
- // 'Roll forward on no candidate fx' enabled with value 2 (major+minor) through env var
- // exe: 9999.1.1, 10000.1.1, 10000.1.3
- // Expected: 9999.1.1 from exe
- dotnet.Exec(appDll)
- .WorkingDirectory(_currentWorkingDir)
- .EnvironmentVariable("DOTNET_ROLL_FORWARD_ON_NO_CANDIDATE_FX", "2")
+ .WithUserProfile(_userDir)
.EnvironmentVariable("COREHOST_TRACE", "1")
+ .EnvironmentVariable("DOTNET_MULTILEVEL_LOOKUP", "1")
+ .EnvironmentVariable("_DOTNET_TEST_SDK_SELF_REGISTERED_DIR", _regDir)
.CaptureStdOut()
.CaptureStdErr()
.Execute()
.Should()
.Pass()
.And
- .HaveStdErrContaining(Path.Combine(_exeSelectedMessage, "9999.1.1"))
- .And
- .HaveStdOutContaining("Framework Version:9999.1.1");
-
- // Verify we have the expected runtime versions
- dotnet.Exec("--list-runtimes")
- .WorkingDirectory(_currentWorkingDir)
- .CaptureStdOut()
- .Execute()
- .Should()
- .Pass()
- .And
- .HaveStdOutContaining("Microsoft.NETCore.App 9999.1.1")
- .And
- .HaveStdOutContaining("Microsoft.NETCore.App 10000.1.1")
- .And
- .HaveStdOutContaining("Microsoft.NETCore.App 10000.1.3");
+ .HaveStdOutContaining("Microsoft.NETCore.App 9999.0.0");
}
[Fact]
- public void Roll_Forward_On_No_Candidate_Fx_Minor_And_Disabled()
+ public void SharedMultilevelFxLookup_Must_Not_Roll_Forward_If_Framework_Version_Is_Specified_Through_Argument()
{
+ if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
+ {
+ // Multi-level lookup is only supported on Windows.
+ return;
+ }
+
var fixture = PreviouslyBuiltAndRestoredPortableTestProjectFixture
.Copy();
var dotnet = fixture.BuiltDotnet;
var appDll = fixture.TestProject.AppDll;
- // Set desired version = 9999.0.0
- string runtimeConfig = Path.Combine(fixture.TestProject.OutputDirectory, "SharedFxLookupPortableApp.runtimeconfig.json");
- SharedFramework.SetRuntimeConfigJson(runtimeConfig, "9999.0.0");
-
- // Add some dummy versions in the exe
- SharedFramework.AddAvailableSharedFxVersions(_builtSharedFxDir, _exeSharedFxBaseDir, "10000.1.1");
-
- // Version: 9999.0.0
- // 'Roll forward on no candidate fx' default value of 1 (minor)
- // exe: 10000.1.1
- // Expected: fail with no framework
- dotnet.Exec(appDll)
- .WorkingDirectory(_currentWorkingDir)
- .EnvironmentVariable("COREHOST_TRACE", "1")
- .CaptureStdOut()
- .CaptureStdErr()
- .Execute(fExpectedToFail: true)
- .Should()
- .Fail()
- .And
- .HaveStdErrContaining("It was not possible to find any compatible framework version");
-
- // Add a dummy version in the exe dir
- SharedFramework.AddAvailableSharedFxVersions(_builtSharedFxDir, _exeSharedFxBaseDir, "9999.1.1");
+ // Add some dummy versions
+ SharedFramework.AddAvailableSharedFxVersions(_builtSharedFxDir, _exeSharedFxBaseDir, "9999.0.0", "9999.0.1", "9999.0.0-dummy2", "9999.0.4");
+ SharedFramework.AddAvailableSharedFxVersions(_builtSharedFxDir, _regSharedFxBaseDir, "9999.0.0", "9999.0.2", "9999.0.3", "9999.0.0-dummy3");
- // Version: 9999.0.0
- // 'Roll forward on no candidate fx' default value of 1 (minor)
- // exe: 9999.1.1, 10000.1.1
- // Expected: 9999.1.1 from exe
- dotnet.Exec(appDll)
+ // Version: 9999.0.0 (through --fx-version arg)
+ // Cwd: empty
+ // User: empty
+ // Exe: 9999.0.0, 9999.0.1, 9999.0.4, 9999.0.0-dummy2
+ // Reg: 9999.0.0, 9999.0.2, 9999.0.3, 9999.0.0-dummy3
+ // Expected: 9999.0.1 from exe dir
+ dotnet.Exec("--fx-version", "9999.0.1", appDll)
.WorkingDirectory(_currentWorkingDir)
+ .WithUserProfile(_userDir)
.EnvironmentVariable("COREHOST_TRACE", "1")
+ .EnvironmentVariable("DOTNET_MULTILEVEL_LOOKUP", "1")
+ .EnvironmentVariable("_DOTNET_TEST_SDK_SELF_REGISTERED_DIR", _regDir)
.CaptureStdOut()
.CaptureStdErr()
.Execute()
.Should()
.Pass()
.And
- .HaveStdErrContaining(Path.Combine(_exeSelectedMessage, "9999.1.1"))
- .And
- .HaveStdOutContaining("Framework Version:9999.1.1");
+ .HaveStdErrContaining(Path.Combine(_exeSelectedMessage, "9999.0.1"));
- // Version: 9999.0.0
- // 'Roll forward on no candidate fx' disabled through env var
- // exe: 9999.1.1, 10000.1.1
- // Expected: fail with no framework
- dotnet.Exec(appDll)
+ // Version: 9999.0.0-dummy1 (through --fx-version arg)
+ // Cwd: empty
+ // User: empty
+ // Exe: 9999.0.0, 9999.0.1, 9999.0.4, 9999.0.0-dummy2
+ // Reg: 9999.0.0, 9999.0.2, 9999.0.3, 9999.0.0-dummy3
+ // Expected: no compatible version
+ dotnet.Exec("--fx-version", "9999.0.0-dummy1", appDll)
.WorkingDirectory(_currentWorkingDir)
+ .WithUserProfile(_userDir)
.EnvironmentVariable("COREHOST_TRACE", "1")
- .EnvironmentVariable("DOTNET_ROLL_FORWARD_ON_NO_CANDIDATE_FX", "0")
+ .EnvironmentVariable("DOTNET_MULTILEVEL_LOOKUP", "1")
+ .EnvironmentVariable("_DOTNET_TEST_SDK_SELF_REGISTERED_DIR", _regDir)
.CaptureStdOut()
.CaptureStdErr()
.Execute(fExpectedToFail: true)
.And
.HaveStdErrContaining("It was not possible to find any compatible framework version");
- // Verify we have the expected runtime versions
- dotnet.Exec("--list-runtimes")
- .WorkingDirectory(_currentWorkingDir)
- .CaptureStdOut()
- .Execute()
- .Should()
- .Pass()
- .And
- .HaveStdOutContaining("Microsoft.NETCore.App 9999.1.1")
- .And
- .HaveStdOutContaining("Microsoft.NETCore.App 10000.1.1");
- }
-
- [Fact]
- public void Roll_Forward_On_No_Candidate_Fx_Production_To_Preview()
- {
- var fixture = PreviouslyBuiltAndRestoredPortableTestProjectFixture
- .Copy();
-
- var dotnet = fixture.BuiltDotnet;
- var appDll = fixture.TestProject.AppDll;
-
- // Set desired version = 9999.0.0
- string runtimeConfig = Path.Combine(fixture.TestProject.OutputDirectory, "SharedFxLookupPortableApp.runtimeconfig.json");
- SharedFramework.SetRuntimeConfigJson(runtimeConfig, "9999.0.0");
-
- // Add preview version in the exe
- SharedFramework.AddAvailableSharedFxVersions(_builtSharedFxDir, _exeSharedFxBaseDir, "9999.1.1-dummy1");
-
- // Version: 9999.0.0
- // 'Roll forward on no candidate fx' default value of 1 (minor)
- // exe: 9999.1.1-dummy1
- // Expected: 9999.1.1-dummy1 since there is no production version
- dotnet.Exec(appDll)
- .WorkingDirectory(_currentWorkingDir)
- .EnvironmentVariable("COREHOST_TRACE", "1")
- .CaptureStdOut()
- .CaptureStdErr()
- .Execute()
- .Should()
- .Pass()
- .And
- .HaveStdErrContaining(Path.Combine(_exeSelectedMessage, "9999.1.1-dummy1"));
-
- // Add a production version with higher value
- SharedFramework.AddAvailableSharedFxVersions(_builtSharedFxDir, _exeSharedFxBaseDir, "9999.2.1");
-
- // Version: 9999.0.0
- // 'Roll forward on no candidate fx' default value of 1 (minor)
- // exe: 9999.1.1-dummy1, 9999.2.1
- // Expected: 9999.2.1 since we favor production over preview
- dotnet.Exec(appDll)
- .WorkingDirectory(_currentWorkingDir)
- .EnvironmentVariable("COREHOST_TRACE", "1")
- .CaptureStdOut()
- .CaptureStdErr()
- .Execute()
- .Should()
- .Pass()
- .And
- .HaveStdErrContaining(Path.Combine(_exeSelectedMessage, "9999.2.1"));
-
- // Add a preview version with same major.minor as production
- SharedFramework.AddAvailableSharedFxVersions(_builtSharedFxDir, _exeSharedFxBaseDir, "9999.2.1-dummy1");
-
- // Version: 9999.0.0
- // 'Roll forward on no candidate fx' default value of 1 (minor)
- // exe: 9999.1.1-dummy1, 9999.2.1, 9999.2.1-dummy1
- // Expected: 9999.2.1 since we favor production over preview
- dotnet.Exec(appDll)
+ // Version: 9999.0.0 (through --fx-version arg)
+ // Cwd: empty
+ // User: empty
+ // Exe: 9999.0.0, 9999.0.1, 9999.0.4, 9999.0.0-dummy2
+ // Reg: 9999.0.0, 9999.0.2, 9999.0.3, 9999.0.0-dummy3
+ // Expected: 9999.0.2 from reg dir
+ dotnet.Exec("--fx-version", "9999.0.2", appDll)
.WorkingDirectory(_currentWorkingDir)
+ .WithUserProfile(_userDir)
.EnvironmentVariable("COREHOST_TRACE", "1")
+ .EnvironmentVariable("DOTNET_MULTILEVEL_LOOKUP", "1")
+ .EnvironmentVariable("_DOTNET_TEST_SDK_SELF_REGISTERED_DIR", _regDir)
.CaptureStdOut()
.CaptureStdErr()
.Execute()
.Should()
.Pass()
.And
- .HaveStdErrContaining(Path.Combine(_exeSelectedMessage, "9999.2.1"));
+ .HaveStdErrContaining(Path.Combine(_regSelectedMessage, "9999.0.2"));
- // Add a preview version with same major.minor as production but higher patch version
- SharedFramework.AddAvailableSharedFxVersions(_builtSharedFxDir, _exeSharedFxBaseDir, "9999.2.2-dummy1");
-
- // Version: 9999.0.0
- // 'Roll forward on no candidate fx' default value of 1 (minor)
- // exe: 9999.1.1-dummy1, 9999.2.1, 9999.2.1-dummy1, 9999.2.2-dummy1
- // Expected: 9999.2.1 since we favor production over preview
- dotnet.Exec(appDll)
+ // Version: 9999.0.0 (through --fx-version arg)
+ // Cwd: empty
+ // User: empty
+ // Exe: 9999.0.0, 9999.0.1, 9999.0.4, 9999.0.0-dummy2
+ // Reg: 9999.0.0, 9999.0.2, 9999.0.3, 9999.0.0-dummy3
+ // Expected: 9999.0.0 from exe dir
+ dotnet.Exec("--fx-version", "9999.0.0", appDll)
.WorkingDirectory(_currentWorkingDir)
+ .WithUserProfile(_userDir)
.EnvironmentVariable("COREHOST_TRACE", "1")
+ .EnvironmentVariable("DOTNET_MULTILEVEL_LOOKUP", "1")
+ .EnvironmentVariable("_DOTNET_TEST_SDK_SELF_REGISTERED_DIR", _regDir)
.CaptureStdOut()
.CaptureStdErr()
.Execute()
.Should()
.Pass()
.And
- .HaveStdErrContaining(Path.Combine(_exeSelectedMessage, "9999.2.1"));
+ .HaveStdErrContaining(Path.Combine(_exeSelectedMessage, "9999.0.0"));
// Verify we have the expected runtime versions
dotnet.Exec("--list-runtimes")
.WorkingDirectory(_currentWorkingDir)
+ .WithUserProfile(_userDir)
+ .EnvironmentVariable("COREHOST_TRACE", "1")
+ .EnvironmentVariable("DOTNET_MULTILEVEL_LOOKUP", "1")
+ .EnvironmentVariable("_DOTNET_TEST_SDK_SELF_REGISTERED_DIR", _regDir)
.CaptureStdOut()
+ .CaptureStdErr()
.Execute()
.Should()
.Pass()
.And
- .HaveStdOutContaining("Microsoft.NETCore.App 9999.1.1-dummy1")
- .And
- .HaveStdOutContaining("Microsoft.NETCore.App 9999.2.1")
- .And
- .HaveStdOutContaining("Microsoft.NETCore.App 9999.2.1-dummy1")
+ .HaveStdOutContaining("Microsoft.NETCore.App 9999.0.0")
.And
- .HaveStdOutContaining("Microsoft.NETCore.App 9999.2.2-dummy1");
- }
-
- [Fact]
- public void Roll_Forward_On_No_Candidate_Fx_Preview_To_Production()
- {
- var fixture = PreviouslyBuiltAndRestoredPortableTestProjectFixture
- .Copy();
-
- var dotnet = fixture.BuiltDotnet;
- var appDll = fixture.TestProject.AppDll;
-
- // Set desired version = 9999.0.0-dummy1
- string runtimeConfig = Path.Combine(fixture.TestProject.OutputDirectory, "SharedFxLookupPortableApp.runtimeconfig.json");
- SharedFramework.SetRuntimeConfigJson(runtimeConfig, "9999.0.0-dummy1");
-
- // Add dummy versions in the exe
- SharedFramework.AddAvailableSharedFxVersions(_builtSharedFxDir, _exeSharedFxBaseDir, "9999.0.0", "9999.0.1-dummy1");
-
- // Version: 9999.0.0-dummy1
- // exe: 9999.0.0, 9999.0.1-dummy1
- // Expected: fail since we don't roll forward unless match on major.minor.patch and never roll forward to production
- dotnet.Exec(appDll)
- .WorkingDirectory(_currentWorkingDir)
- .EnvironmentVariable("COREHOST_TRACE", "1")
- .CaptureStdOut()
- .CaptureStdErr()
- .Execute(fExpectedToFail: true)
- .Should()
- .Fail()
+ .HaveStdOutContaining("Microsoft.NETCore.App 9999.0.0-dummy2")
.And
- .HaveStdErrContaining("It was not possible to find any compatible framework version");
-
- // Add preview versions in the exe with name major.minor.patch
- SharedFramework.AddAvailableSharedFxVersions(_builtSharedFxDir, _exeSharedFxBaseDir, "9999.0.0-dummy2", "9999.0.0-dummy3");
-
- // Version: 9999.0.0-dummy1
- // exe: 9999.0.0-dummy2, 9999.0.0-dummy3, 9999.0.0, 9999.0.1-dummy1
- // Expected: 9999.0.0-dummy2
- dotnet.Exec(appDll)
- .WorkingDirectory(_currentWorkingDir)
- .EnvironmentVariable("COREHOST_TRACE", "1")
- .CaptureStdOut()
- .CaptureStdErr()
- .Execute()
- .Should()
- .Pass()
+ .HaveStdOutContaining("Microsoft.NETCore.App 9999.0.2")
.And
- .HaveStdErrContaining(Path.Combine(_exeSelectedMessage, "9999.0.0-dummy2"))
+ .HaveStdOutContaining("Microsoft.NETCore.App 9999.0.3")
.And
- .HaveStdOutContaining("Framework Version:9999.0.0-dummy2");
-
- // Verify we have the expected runtime versions
- dotnet.Exec("--list-runtimes")
- .WorkingDirectory(_currentWorkingDir)
- .CaptureStdOut()
- .Execute()
- .Should()
- .Pass()
- .And
- .HaveStdOutContaining("9999.0.0-dummy2")
- .And
- .HaveStdOutContaining("9999.0.0-dummy3")
- .And
- .HaveStdOutContaining("9999.0.0")
- .And
- .HaveStdOutContaining("9999.0.1-dummy1");
- }
-
- [Fact]
- public void Roll_Forward_On_No_Candidate_Fx_Fails_If_No_Higher_Version_Is_Available()
- {
- var fixture = PreviouslyBuiltAndRestoredPortableTestProjectFixture
- .Copy();
-
- var dotnet = fixture.BuiltDotnet;
- var appDll = fixture.TestProject.AppDll;
-
- // Set desired version = 9999.1.1
- string runtimeConfig = Path.Combine(fixture.TestProject.OutputDirectory, "SharedFxLookupPortableApp.runtimeconfig.json");
- SharedFramework.SetRuntimeConfigJson(runtimeConfig, "9999.1.1");
-
- // Add some dummy versions in the exe
- SharedFramework.AddAvailableSharedFxVersions(_builtSharedFxDir, _exeSharedFxBaseDir, "9998.0.1", "9998.1.0", "9999.0.0", "9999.0.1", "9999.1.0");
-
- // Version: 9999.1.1
- // exe: 9998.0.1, 9998.1.0, 9999.0.0, 9999.0.1, 9999.1.0
- // Expected: no compatible version
- dotnet.Exec(appDll)
- .WorkingDirectory(_currentWorkingDir)
- .EnvironmentVariable("COREHOST_TRACE", "1")
- .CaptureStdOut()
- .CaptureStdErr()
- .Execute(fExpectedToFail: true)
- .Should()
- .Fail()
- .And
- .HaveStdErrContaining("It was not possible to find any compatible framework version");
-
- // Verify we have the expected runtime versions
- dotnet.Exec("--list-runtimes")
- .WorkingDirectory(_currentWorkingDir)
- .CaptureStdOut()
- .Execute()
- .Should()
- .Pass()
- .And
- .HaveStdOutContaining("Microsoft.NETCore.App 9998.0.1")
- .And
- .HaveStdOutContaining("Microsoft.NETCore.App 9998.1.0")
- .And
- .HaveStdOutContaining("Microsoft.NETCore.App 9999.0.0")
- .And
- .HaveStdOutContaining("Microsoft.NETCore.App 9999.0.1")
- .And
- .HaveStdOutContaining("Microsoft.NETCore.App 9999.1.0");
- }
-
- [Fact]
- public void Multiple_SharedFxLookup_Independent_Roll_Forward()
- {
- var fixture = PreviouslyBuiltAndRestoredPortableTestProjectFixture
- .Copy();
-
- var dotnet = fixture.BuiltDotnet;
- var appDll = fixture.TestProject.AppDll;
-
- string runtimeConfig = Path.Combine(fixture.TestProject.OutputDirectory, "SharedFxLookupPortableApp.runtimeconfig.json");
- SharedFramework.SetRuntimeConfigJson(runtimeConfig, "7777.0.0", null, useUberFramework: true);
-
- // Add versions in the exe folders
- SharedFramework.AddAvailableSharedFxVersions(_builtSharedFxDir, _exeSharedFxBaseDir, "9999.0.0");
- SharedFramework.AddAvailableSharedUberFxVersions(_builtSharedUberFxDir, _exeSharedUberFxBaseDir, "9999.0.0", "7777.0.0");
-
- // Version: NetCoreApp 9999.0.0
- // UberFramework 7777.0.0
- // Exe: NetCoreApp 9999.0.0
- // UberFramework 7777.0.0
- // Expected: 9999.0.0
- // 7777.0.0
- dotnet.Exec(appDll)
- .WorkingDirectory(_currentWorkingDir)
- .EnvironmentVariable("COREHOST_TRACE", "1")
- .CaptureStdOut()
- .CaptureStdErr()
- .Execute()
- .Should()
- .Pass()
- .And
- .HaveStdErrContaining(Path.Combine(_exeSelectedMessage, "9999.0.0"))
- .And
- .HaveStdOutContaining("Framework Version:9999.0.0")
- .And
- .HaveStdErrContaining(Path.Combine(_exeFoundUberFxMessage, "7777.0.0"));
-
- // Add a newer version to verify roll-forward
- SharedFramework.AddAvailableSharedFxVersions(_builtSharedFxDir, _exeSharedFxBaseDir, "9999.0.1");
- SharedFramework.AddAvailableSharedUberFxVersions(_builtSharedUberFxDir, _exeSharedUberFxBaseDir, "9999.0.0", "7777.0.1");
-
- // Version: NetCoreApp 9999.0.0
- // UberFramework 7777.0.0
- // Exe: NetCoreApp 9999.0.0, 9999.0.1
- // UberFramework 7777.0.0, 7777.0.1
- // Expected: 9999.0.1
- // 7777.0.1
- dotnet.Exec(appDll)
- .WorkingDirectory(_currentWorkingDir)
- .EnvironmentVariable("COREHOST_TRACE", "1")
- .CaptureStdOut()
- .CaptureStdErr()
- .Execute()
- .Should()
- .Pass()
- .And
- .HaveStdErrContaining(Path.Combine(_exeSelectedMessage, "9999.0.1"))
- .And
- .HaveStdErrContaining(Path.Combine(_exeFoundUberFxMessage, "7777.0.1"));
-
- // Verify we have the expected runtime versions
- dotnet.Exec("--list-runtimes")
- .WorkingDirectory(_currentWorkingDir)
- .WithUserProfile(_userDir)
- .CaptureStdOut()
- .Execute()
- .Should()
- .Pass()
- .And
- .HaveStdOutContaining("Microsoft.NETCore.App 9999.0.0")
- .And
- .HaveStdOutContaining("Microsoft.NETCore.App 9999.0.1")
- .And
- .HaveStdOutContaining("Microsoft.UberFramework 7777.0.0")
- .And
- .HaveStdOutContaining("Microsoft.UberFramework 7777.0.1");
- }
-
- [Fact]
- public void Multiple_SharedFxLookup_Do_Not_Propagate()
- {
- var fixture = PreviouslyBuiltAndRestoredPortableTestProjectFixture
- .Copy();
-
- var dotnet = fixture.BuiltDotnet;
- var appDll = fixture.TestProject.AppDll;
-
- string runtimeConfig = Path.Combine(fixture.TestProject.OutputDirectory, "SharedFxLookupPortableApp.runtimeconfig.json");
- SharedFramework.SetRuntimeConfigJson(runtimeConfig, "7777.0.0", null, useUberFramework: true);
-
- // Add versions in the exe folders
- SharedFramework.AddAvailableSharedFxVersions(_builtSharedFxDir, _exeSharedFxBaseDir, "9999.1.0");
- SharedFramework.AddAvailableSharedUberFxVersions(_builtSharedUberFxDir, _exeSharedUberFxBaseDir, "9999.0.0", "7777.0.0");
-
- // Version: NetCoreApp 9999.0.0
- // UberFramework 7777.0.0
- // 'Roll forward on no candidate fx' disabled through env var
- // Exe: NetCoreApp 9999.1.0
- // UberFramework 7777.0.0
- // Expected: no compatible version
- dotnet.Exec(appDll)
- .WorkingDirectory(_currentWorkingDir)
- .EnvironmentVariable("COREHOST_TRACE", "1")
- .EnvironmentVariable("DOTNET_ROLL_FORWARD_ON_NO_CANDIDATE_FX", "0")
- .CaptureStdOut()
- .CaptureStdErr()
- .Execute(fExpectedToFail: true)
- .Should()
- .Fail()
- .And
- .HaveStdErrContaining("It was not possible to find any compatible framework version");
-
- // Enable rollForwardOnNoCandidateFx on app's config, which will not be used as the default for Uber's config
- SharedFramework.SetRuntimeConfigJson(runtimeConfig, "7777.0.0", rollFwdOnNoCandidateFx: 1, useUberFramework: true);
-
- // Version: NetCoreApp 9999.0.0
- // UberFramework 7777.0.0
- // 'Roll forward on no candidate fx' enabled through config
- // Exe: NetCoreApp 9999.1.0
- // UberFramework 7777.0.0
- // Expected: no compatible version
- dotnet.Exec(appDll)
- .WorkingDirectory(_currentWorkingDir)
- .EnvironmentVariable("COREHOST_TRACE", "1")
- .EnvironmentVariable("DOTNET_ROLL_FORWARD_ON_NO_CANDIDATE_FX", "0")
- .CaptureStdOut()
- .CaptureStdErr()
- .Execute(fExpectedToFail: true)
- .Should()
- .Fail()
- .And
- .HaveStdErrContaining("It was not possible to find any compatible framework version");
- }
-
- [Fact]
- public void Multiple_Fx_References_Cant_Roll_Forward_Because_Incompatible_Config()
- {
- var fixture = PreviouslyBuiltAndRestoredPortableTestProjectFixture
- .Copy();
-
- var dotnet = fixture.BuiltDotnet;
- var appDll = fixture.TestProject.AppDll;
-
- string runtimeConfig = Path.Combine(fixture.TestProject.OutputDirectory, "SharedFxLookupPortableApp.runtimeconfig.json");
-
- var additionalfxs = new JArray();
- additionalfxs.Add(GetAdditionalFramework("Microsoft.NETCore.App", "9999.1.0", applyPatches: false, rollForwardOnNoCandidateFx: 0));
- SharedFramework.SetRuntimeConfigJson(runtimeConfig, "7777.0.0", null, useUberFramework: true, frameworks: additionalfxs);
-
- // Add versions in the exe folders
- SharedFramework.AddAvailableSharedFxVersions(_builtSharedFxDir, _exeSharedFxBaseDir, "9999.1.0", "9999.5.5");
- SharedFramework.AddAvailableSharedUberFxVersions(_builtSharedUberFxDir, _exeSharedUberFxBaseDir, "9999.5.5", "7777.0.0");
-
- // Verify that both 9999.1.0 and 9999.5.5 can't be selected with roll-forward disabled
- // Version: NetCoreApp 9999.5.5 (in framework section)
- // NetCoreApp 9999.1.0 (in frameworks section)
- // UberFramework 7777.0.0
- // Exe: NetCoreApp 9999.1.0 rollForwardOnNoCandidateFx:0 applyPatches:false
- // NetCoreApp 9999.5.5
- // UberFramework 7777.0.0
- // Expected: no compatible version
- dotnet.Exec(appDll)
- .WorkingDirectory(_currentWorkingDir)
- .EnvironmentVariable("COREHOST_TRACE", "1")
- .CaptureStdOut()
- .CaptureStdErr()
- .Execute(fExpectedToFail: true)
- .Should()
- .Fail()
- .And
- .HaveStdErrContaining("cannot roll-forward to the previously referenced version '9999.5.5");
- }
-
- [Fact]
- public void Multiple_Fx_References_Can_Roll_Forward_Without_Retry()
- {
- var fixture = PreviouslyBuiltAndRestoredPortableTestProjectFixture
- .Copy();
-
- var dotnet = fixture.BuiltDotnet;
- var appDll = fixture.TestProject.AppDll;
-
- string runtimeConfig = Path.Combine(fixture.TestProject.OutputDirectory, "SharedFxLookupPortableApp.runtimeconfig.json");
-
- var additionalfxs = new JArray();
- additionalfxs.Add(GetAdditionalFramework("Microsoft.NETCore.App", "9999.1.1", applyPatches: false, rollForwardOnNoCandidateFx: 1));
- SharedFramework.SetRuntimeConfigJson(runtimeConfig, "7777.0.0", null, useUberFramework: true, frameworks: additionalfxs);
-
- // Add versions in the exe folders
- SharedFramework.AddAvailableSharedFxVersions(_builtSharedFxDir, _exeSharedFxBaseDir, "9999.1.0", "9999.5.5");
- SharedFramework.AddAvailableSharedUberFxVersions(_builtSharedUberFxDir, _exeSharedUberFxBaseDir, "9999.5.5", "7777.0.0");
-
- // Version: NetCoreApp 9999.5.5 (in framework section)
- // NetCoreApp 9999.1.0 (in frameworks section)
- // UberFramework 7777.0.0
- // Exe: NetCoreApp 9999.1.0 rollForwardOnNoCandidateFx:1 applyPatches:false
- // NetCoreApp 9999.5.5
- // UberFramework 7777.0.0
- // Expected: 9999.5.5
- // 7777.0.0
- dotnet.Exec(appDll)
- .WorkingDirectory(_currentWorkingDir)
- .EnvironmentVariable("COREHOST_TRACE", "1")
- .CaptureStdOut()
- .CaptureStdErr()
- .Execute()
- .Should()
- .Pass()
- .And
- .HaveStdErrContaining(Path.Combine(_exeSelectedMessage, "9999.5.5"))
- .And
- .HaveStdOutContaining("Framework Version:9999.5.5")
- .And
- .HaveStdErrContaining(Path.Combine(_exeFoundUberFxMessage, "7777.0.0"))
- .And
- .NotHaveStdErrContaining("Restarting all framework resolution");
- }
-
- [Fact]
- public void Multiple_Fx_References_Can_Roll_Forward_With_Retry()
- {
- var fixture = PreviouslyBuiltAndRestoredPortableTestProjectFixture
- .Copy();
-
- var dotnet = fixture.BuiltDotnet;
- var appDll = fixture.TestProject.AppDll;
-
- string runtimeConfig = Path.Combine(fixture.TestProject.OutputDirectory, "SharedFxLookupPortableApp.runtimeconfig.json");
-
- var additionalfxs = new JArray();
- additionalfxs.Add(GetAdditionalFramework("Microsoft.UberFramework", "7777.0.0", null, null));
- // Specify Uber as additional fx so we find NetCoreApp 9999.1.1 and then need to do a re-try for 9999.5.5
- SharedFramework.SetRuntimeConfigJson(runtimeConfig, "9999.1.1", null, null, frameworks: additionalfxs);
-
- // Add versions in the exe folders
- SharedFramework.AddAvailableSharedFxVersions(_builtSharedFxDir, _exeSharedFxBaseDir, "9999.1.1", "9999.5.5");
- SharedFramework.AddAvailableSharedUberFxVersions(_builtSharedUberFxDir, _exeSharedUberFxBaseDir, "9999.5.5", "7777.0.0");
-
- // Version: NetCoreApp 9999.1.1 (in framework section)
- // UberFramework 7777.0.0 (in frameworks section)
- // NetCoreApp 9999.5.5 (in uber's config)
- // Exe: NetCoreApp 9999.1.1
- // NetCoreApp 9999.5.5
- // UberFramework 7777.0.0
- // Expected: 9999.5.5
- // 7777.0.0
- dotnet.Exec(appDll)
- .WorkingDirectory(_currentWorkingDir)
- .EnvironmentVariable("COREHOST_TRACE", "1")
- .CaptureStdOut()
- .CaptureStdErr()
- .Execute()
- .Should()
- .Pass()
- .And
- .HaveStdErrContaining(Path.Combine(_exeSelectedMessage, "9999.5.5"))
- .And
- .HaveStdOutContaining("Framework Version:9999.5.5")
- .And
- .HaveStdErrContaining(Path.Combine(_exeFoundUberFxMessage, "7777.0.0"))
- .And
- .HaveStdErrContaining("Restarting all framework resolution because the previously resolved framework 'Microsoft.NETCore.App', version '9999.1.1' must be re-resolved with the new version '9999.5.5'");
- }
-
- [Fact]
- public void Multiple_Fx_References_Cant_Roll_Forward_Because_Disabled_Through_CommandLine()
- {
- var fixture = PreviouslyBuiltAndRestoredPortableTestProjectFixture
- .Copy();
-
- var dotnet = fixture.BuiltDotnet;
- var appDll = fixture.TestProject.AppDll;
-
- string runtimeConfig = Path.Combine(fixture.TestProject.OutputDirectory, "SharedFxLookupPortableApp.runtimeconfig.json");
-
- var additionalfxs = new JArray();
- additionalfxs.Add(GetAdditionalFramework("Microsoft.NETCore.App", "9999.1.1", applyPatches: false, rollForwardOnNoCandidateFx: 1));
- SharedFramework.SetRuntimeConfigJson(runtimeConfig, "7777.0.0", null, useUberFramework: true, frameworks: additionalfxs);
-
- // Add versions in the exe folders
- SharedFramework.AddAvailableSharedFxVersions(_builtSharedFxDir, _exeSharedFxBaseDir, "9999.1.0", "9999.5.5");
- SharedFramework.AddAvailableSharedUberFxVersions(_builtSharedUberFxDir, _exeSharedUberFxBaseDir, "9999.5.5", "7777.0.0");
-
- // Version: NetCoreApp 9999.5.5 (in framework section)
- // NetCoreApp 9999.1.0 (in frameworks section)
- // UberFramework 7777.0.0
- // Exe: NetCoreApp 9999.1.0 rollForwardOnNoCandidateFx:1 applyPatches:false
- // NetCoreApp 9999.5.5
- // UberFramework 7777.0.0
- // --roll-forward-on-no-candidate-fx=0 should override config settings
- // Expected: 9999.5.5
- // 7777.0.0
-
- dotnet.Exec(
- "exec",
- "--roll-forward-on-no-candidate-fx", "0",
- appDll)
- .WorkingDirectory(_currentWorkingDir)
- .EnvironmentVariable("COREHOST_TRACE", "1")
- .CaptureStdOut()
- .CaptureStdErr()
- .Execute(fExpectedToFail: true)
- .Should()
- .Fail()
- .And
- .HaveStdErrContaining("cannot roll-forward to the previously referenced version '9999.5.5");
- }
-
- [Fact]
- public void Multiple_SharedFxLookup_NetCoreApp_MinorRollForward_Wins_Over_UberFx()
- {
- var fixture = PreviouslyBuiltAndRestoredPortableTestProjectFixture
- .Copy();
-
- var dotnet = fixture.BuiltDotnet;
- var appDll = fixture.TestProject.AppDll;
-
- string runtimeConfig = Path.Combine(fixture.TestProject.OutputDirectory, "SharedFxLookupPortableApp.runtimeconfig.json");
- SharedFramework.SetRuntimeConfigJson(runtimeConfig, "7777.0.0", null, useUberFramework: true);
-
- // Modify the Uber values
- SharedFramework.CreateUberFrameworkArtifacts(_builtSharedFxDir, _builtSharedUberFxDir, "0.0.0.1", "0.0.0.2");
-
- // Add versions in the exe folders
- SharedFramework.AddAvailableSharedFxVersions(_builtSharedFxDir, _exeSharedFxBaseDir, "9999.1.0");
- SharedFramework.AddAvailableSharedUberFxVersions(_builtSharedUberFxDir, _exeSharedUberFxBaseDir, "9999.0.0", "7777.0.0");
-
- string uberFile = Path.Combine(_exeSharedUberFxBaseDir, "7777.0.0", "System.Collections.Immutable.dll");
- string netCoreAppFile = Path.Combine(_exeSharedFxBaseDir, "9999.1.0", "System.Collections.Immutable.dll");
- // The System.Collections.Immutable.dll is located in the UberFramework and NetCoreApp
- // Version: NetCoreApp 9999.0.0
- // UberFramework 7777.0.0
- // 'Roll forward on no candidate fx' enabled through config
- // Exe: NetCoreApp 9999.1.0
- // UberFramework 7777.0.0
- // Expected: 9999.1.0
- // 7777.0.0
- dotnet.Exec(appDll)
- .WorkingDirectory(_currentWorkingDir)
- .EnvironmentVariable("COREHOST_TRACE", "1")
- .CaptureStdOut()
- .CaptureStdErr()
- .Execute()
- .Should()
- .Pass()
- .And
- .HaveStdErrContaining($"Replacing deps entry [{uberFile}, AssemblyVersion:0.0.0.1, FileVersion:0.0.0.2] with [{netCoreAppFile}");
- }
-
- [Fact]
- public void Multiple_SharedFxLookup_Uber_Wins_Over_NetCoreApp_On_PatchRollForward()
- {
- var fixture = PreviouslyBuiltAndRestoredPortableTestProjectFixture
- .Copy();
-
- var dotnet = fixture.BuiltDotnet;
- var appDll = fixture.TestProject.AppDll;
-
- string runtimeConfig = Path.Combine(fixture.TestProject.OutputDirectory, "SharedFxLookupPortableApp.runtimeconfig.json");
- SharedFramework.SetRuntimeConfigJson(runtimeConfig, "7777.0.0", null, useUberFramework: true);
-
- // Add versions in the exe folders
- SharedFramework.AddAvailableSharedFxVersions(_builtSharedFxDir, _exeSharedFxBaseDir, "9999.0.1");
- SharedFramework.AddAvailableSharedUberFxVersions(_builtSharedUberFxDir, _exeSharedUberFxBaseDir, "9999.0.0", "7777.0.0");
-
- // The System.Collections.Immutable.dll is located in the UberFramework and NetCoreApp
- // Version: NetCoreApp 9999.0.0
- // UberFramework 7777.0.0
- // 'Roll forward on no candidate fx' enabled through config
- // Exe: NetCoreApp 9999.0.1
- // UberFramework 7777.0.0
- // Expected: 9999.0.1
- // 7777.0.0
- dotnet.Exec(appDll)
- .WorkingDirectory(_currentWorkingDir)
- .EnvironmentVariable("COREHOST_TRACE", "1")
- .CaptureStdOut()
- .CaptureStdErr()
- .Execute()
- .Should()
- .Pass()
- .And
- .HaveStdErrContaining(Path.Combine("7777.0.0", "System.Collections.Immutable.dll"))
- .And
- .NotHaveStdErrContaining(Path.Combine("9999.1.0", "System.Collections.Immutable.dll"));
+ .HaveStdOutContaining("Microsoft.NETCore.App 9999.0.0-dummy3");
}
static private JObject GetAdditionalFramework(string fxName, string fxVersion, bool? applyPatches, int? rollForwardOnNoCandidateFx)
public string AppDll => _fixture.TestProject.AppDll;
public string ExeDir => Path.Combine(_fixture.TestProject.ProjectDirectory, "ed");
public string ProgramFiles => Path.Combine(ExeDir, "pf");
+ public string SelfRegistered => Path.Combine(ExeDir, "sr");
public string WorkingDir => Path.Combine(_fixture.TestProject.ProjectDirectory, "wd");
- public string GlobalSdkDir => Path.Combine(ProgramFiles, "dotnet", "sdk");
+ public string ProgramFilesGlobalSdkDir => Path.Combine(ProgramFiles, "dotnet", "sdk");
+ public string SelfRegisteredGlobalSdkDir => Path.Combine(SelfRegistered, "sdk");
public string LocalSdkDir => Path.Combine(ExeDir, "sdk");
public string GlobalJson => Path.Combine(WorkingDir, "global.json");
- public string[] GlobalSdks = new[] { "4.5.6", "1.2.3", "2.3.4-preview" };
+ public string[] ProgramFilesGlobalSdks = new[] { "4.5.6", "1.2.3", "2.3.4-preview" };
+ public string[] SelfRegisteredGlobalSdks = new[] { "3.0.0", "15.1.4-preview", "5.6.7" };
public string[] LocalSdks = new[] { "0.1.2", "5.6.7-preview", "1.2.3" };
public SdkResolutionFixture(SharedTestState state)
// on a given machine from impacting the test.
File.WriteAllText(GlobalJson, "{}");
- foreach (string sdk in GlobalSdks)
+ foreach (string sdk in ProgramFilesGlobalSdks)
{
- Directory.CreateDirectory(Path.Combine(GlobalSdkDir, sdk));
+ Directory.CreateDirectory(Path.Combine(ProgramFilesGlobalSdkDir, sdk));
+ }
+ foreach (string sdk in SelfRegisteredGlobalSdks)
+ {
+ Directory.CreateDirectory(Path.Combine(SelfRegisteredGlobalSdkDir, sdk));
}
-
foreach (string sdk in LocalSdks)
{
Directory.CreateDirectory(Path.Combine(LocalSdkDir, sdk));
string expectedList = string.Join(';', new[]
{
Path.Combine(f.LocalSdkDir, "0.1.2"),
- Path.Combine(f.GlobalSdkDir, "1.2.3"),
+ Path.Combine(f.ProgramFilesGlobalSdkDir, "1.2.3"),
Path.Combine(f.LocalSdkDir, "1.2.3"),
- Path.Combine(f.GlobalSdkDir, "2.3.4-preview"),
- Path.Combine(f.GlobalSdkDir, "4.5.6"),
+ Path.Combine(f.ProgramFilesGlobalSdkDir, "2.3.4-preview"),
+ Path.Combine(f.SelfRegisteredGlobalSdkDir, "3.0.0"),
+ Path.Combine(f.ProgramFilesGlobalSdkDir, "4.5.6"),
Path.Combine(f.LocalSdkDir, "5.6.7-preview"),
+ Path.Combine(f.SelfRegisteredGlobalSdkDir, "5.6.7"),
+ Path.Combine(f.SelfRegisteredGlobalSdkDir, "15.1.4-preview"),
});
f.Dotnet.Exec(f.AppDll, new[] { "hostfxr_get_available_sdks", f.ExeDir })
.EnvironmentVariable("TEST_MULTILEVEL_LOOKUP_PROGRAM_FILES", f.ProgramFiles)
+ .EnvironmentVariable("TEST_MULTILEVEL_LOOKUP_SELF_REGISTERED", f.SelfRegistered)
.CaptureStdOut()
.CaptureStdErr()
.Execute()
--- /dev/null
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using Microsoft.DotNet.InternalAbstractions;
+using Xunit;
+
+namespace Microsoft.DotNet.CoreSetup.Test.HostActivation.SDKLookup
+{
+ public class GivenThatICareAboutSDKLookup : IDisposable
+ {
+ private static IDictionary<string, string> s_DefaultEnvironment = new Dictionary<string, string>()
+ {
+ {"COREHOST_TRACE", "1" },
+ // The SDK being used may be crossgen'd for a different architecture than we are building for.
+ // Turn off ready to run, so an x64 crossgen'd SDK can be loaded in an x86 process.
+ {"COMPlus_ReadyToRun", "0" },
+ };
+
+ private RepoDirectoriesProvider RepoDirectories;
+ private TestProjectFixture PreviouslyBuiltAndRestoredPortableTestProjectFixture;
+
+ private string _currentWorkingDir;
+ private string _userDir;
+ private string _executableDir;
+ private string _cwdSdkBaseDir;
+ private string _userSdkBaseDir;
+ private string _exeSdkBaseDir;
+ private string _cwdSelectedMessage;
+ private string _userSelectedMessage;
+ private string _exeSelectedMessage;
+ private string _sdkDir;
+ private string _baseDir;
+
+ private const string _dotnetSdkDllMessageTerminator = "dotnet.dll]";
+
+ public GivenThatICareAboutSDKLookup()
+ {
+ // From the artifacts dir, it's possible to find where the sharedFrameworkPublish folder is. We need
+ // to locate it because we'll copy its contents into other folders
+ string artifactsDir = Environment.GetEnvironmentVariable("TEST_ARTIFACTS");
+ string builtDotnet = Path.Combine(artifactsDir, "sharedFrameworkPublish");
+
+ // The dotnetSDKLookup dir will contain some folders and files that will be
+ // necessary to perform the tests
+ string baseDir = Path.Combine(artifactsDir, "dotnetSDKLookup");
+ _baseDir = SharedFramework.CalculateUniqueTestDirectory(baseDir);
+
+ // The three tested locations will be the cwd, the user folder and the exe dir. cwd and user are no longer supported.
+ // All dirs will be placed inside the base folder
+
+ _currentWorkingDir = Path.Combine(_baseDir, "cwd");
+ _userDir = Path.Combine(_baseDir, "user");
+ _executableDir = Path.Combine(_baseDir, "exe");
+
+ // It's necessary to copy the entire publish folder to the exe dir because
+ // we'll need to build from it. The CopyDirectory method automatically creates the dest dir
+ SharedFramework.CopyDirectory(builtDotnet, _executableDir);
+
+ RepoDirectories = new RepoDirectoriesProvider(builtDotnet: _executableDir);
+
+ // SdkBaseDirs contain all available version folders
+ _cwdSdkBaseDir = Path.Combine(_currentWorkingDir, "sdk");
+ _userSdkBaseDir = Path.Combine(_userDir, ".dotnet", RepoDirectories.BuildArchitecture, "sdk");
+ _exeSdkBaseDir = Path.Combine(_executableDir, "sdk");
+
+ // Create directories
+ Directory.CreateDirectory(_cwdSdkBaseDir);
+ Directory.CreateDirectory(_userSdkBaseDir);
+ Directory.CreateDirectory(_exeSdkBaseDir);
+
+ // Restore and build PortableApp from exe dir
+ PreviouslyBuiltAndRestoredPortableTestProjectFixture = new TestProjectFixture("PortableApp", RepoDirectories)
+ .EnsureRestored(RepoDirectories.CorehostPackages)
+ .BuildProject();
+ var fixture = PreviouslyBuiltAndRestoredPortableTestProjectFixture;
+
+ // Set a dummy framework version (9999.0.0) in the exe sharedFx location. We will
+ // always pick the framework from this to avoid interference with the sharedFxLookup
+ string exeDirDummyFxVersion = Path.Combine(_executableDir, "shared", "Microsoft.NETCore.App", "9999.0.0");
+ string builtSharedFxDir = fixture.BuiltDotnet.GreatestVersionSharedFxPath;
+ SharedFramework.CopyDirectory(builtSharedFxDir, exeDirDummyFxVersion);
+
+ // The actual SDK version can be obtained from the built fixture. We'll use it to
+ // locate the sdkDir from which we can get the files contained in the version folder
+ string sdkBaseDir = Path.Combine(fixture.SdkDotnet.BinPath, "sdk");
+
+ var sdkVersionDirs = Directory.EnumerateDirectories(sdkBaseDir)
+ .Select(p => Path.GetFileName(p));
+
+ string greatestVersionSdk = sdkVersionDirs
+ .Where(p => !string.Equals(p, "NuGetFallbackFolder", StringComparison.OrdinalIgnoreCase))
+ .OrderByDescending(p => p.ToLower())
+ .First();
+
+ _sdkDir = Path.Combine(sdkBaseDir, greatestVersionSdk);
+
+ // Trace messages used to identify from which folder the SDK was picked
+ _cwdSelectedMessage = $"Using dotnet SDK dll=[{_cwdSdkBaseDir}";
+ _userSelectedMessage = $"Using dotnet SDK dll=[{_userSdkBaseDir}";
+ _exeSelectedMessage = $"Using dotnet SDK dll=[{_exeSdkBaseDir}";
+ }
+
+ public void Dispose()
+ {
+ PreviouslyBuiltAndRestoredPortableTestProjectFixture.Dispose();
+
+ if (!TestProject.PreserveTestRuns())
+ {
+ Directory.Delete(_baseDir, true);
+ }
+ }
+
+ [Fact]
+ public void SdkLookup_Global_Json_Single_Digit_Patch_Rollup()
+ {
+ var fixture = PreviouslyBuiltAndRestoredPortableTestProjectFixture
+ .Copy();
+
+ var dotnet = fixture.BuiltDotnet;
+
+ // Set specified SDK version = 9999.3.4-global-dummy
+ SetGlobalJsonVersion("SingleDigit-global.json");
+
+ // Specified SDK version: 9999.3.4-global-dummy
+ // Exe: empty
+ // Expected: no compatible version and a specific error messages
+ dotnet.Exec("help")
+ .WorkingDirectory(_currentWorkingDir)
+ .WithUserProfile(_userDir)
+ .Environment(s_DefaultEnvironment)
+ .EnvironmentVariable("DOTNET_MULTILEVEL_LOOKUP", "0")
+ .CaptureStdOut()
+ .CaptureStdErr()
+ .Execute(fExpectedToFail: true)
+ .Should()
+ .Fail()
+ .And
+ .HaveStdErrContaining("A compatible installed dotnet SDK for global.json version")
+ .And
+ .HaveStdErrContaining("It was not possible to find any installed dotnet SDKs")
+ .And
+ .NotHaveStdErrContaining("Checking if resolved SDK dir");
+
+ // Add SDK versions
+ AddAvailableSdkVersions(_exeSdkBaseDir, "9999.4.1", "9999.3.4-dummy");
+
+ // Specified SDK version: 9999.3.4-global-dummy
+ // Exe: 9999.4.1, 9999.3.4-dummy
+ // Expected: no compatible version and a specific error message
+ dotnet.Exec("help")
+ .WorkingDirectory(_currentWorkingDir)
+ .WithUserProfile(_userDir)
+ .Environment(s_DefaultEnvironment)
+ .EnvironmentVariable("DOTNET_MULTILEVEL_LOOKUP", "0")
+ .CaptureStdOut()
+ .CaptureStdErr()
+ .Execute(fExpectedToFail: true)
+ .Should()
+ .Fail()
+ .And
+ .HaveStdErrContaining("A compatible installed dotnet SDK for global.json version")
+ .And
+ .NotHaveStdErrContaining("It was not possible to find any installed dotnet SDKs");
+
+ // Add SDK versions
+ AddAvailableSdkVersions(_exeSdkBaseDir, "9999.3.3");
+
+ // Specified SDK version: 9999.3.4-global-dummy
+ // Exe: 9999.4.1, 9999.3.4-dummy, 9999.3.3
+ // Expected: no compatible version and a specific error message
+ dotnet.Exec("help")
+ .WorkingDirectory(_currentWorkingDir)
+ .WithUserProfile(_userDir)
+ .Environment(s_DefaultEnvironment)
+ .EnvironmentVariable("DOTNET_MULTILEVEL_LOOKUP", "0")
+ .CaptureStdOut()
+ .CaptureStdErr()
+ .Execute(fExpectedToFail: true)
+ .Should()
+ .Fail()
+ .And
+ .HaveStdErrContaining("A compatible installed dotnet SDK for global.json version")
+ .And
+ .NotHaveStdErrContaining("It was not possible to find any installed dotnet SDKs");
+
+ // Add SDK versions
+ AddAvailableSdkVersions(_exeSdkBaseDir, "9999.3.4");
+
+ // Specified SDK version: 9999.3.4-global-dummy
+ // Exe: 9999.4.1, 9999.3.4-dummy, 9999.3.3, 9999.3.4
+ // Expected: 9999.3.4 from exe dir
+ dotnet.Exec("help")
+ .WorkingDirectory(_currentWorkingDir)
+ .WithUserProfile(_userDir)
+ .Environment(s_DefaultEnvironment)
+ .EnvironmentVariable("DOTNET_MULTILEVEL_LOOKUP", "0")
+ .CaptureStdOut()
+ .CaptureStdErr()
+ .Execute()
+ .Should()
+ .Pass()
+ .And
+ .HaveStdErrContaining(Path.Combine(_exeSelectedMessage, "9999.3.4", _dotnetSdkDllMessageTerminator));
+
+ // Add SDK versions
+ AddAvailableSdkVersions(_exeSdkBaseDir, "9999.3.5-dummy");
+
+ // Specified SDK version: 9999.3.4-global-dummy
+ // Exe: 9999.4.1, 9999.3.4-dummy, 9999.3.3, 9999.3.4, 9999.3.5-dummy
+ // Expected: 9999.3.5-dummy from exe dir
+ dotnet.Exec("help")
+ .WorkingDirectory(_currentWorkingDir)
+ .WithUserProfile(_userDir)
+ .Environment(s_DefaultEnvironment)
+ .EnvironmentVariable("DOTNET_MULTILEVEL_LOOKUP", "0")
+ .CaptureStdOut()
+ .CaptureStdErr()
+ .Execute()
+ .Should()
+ .Pass()
+ .And
+ .HaveStdErrContaining(Path.Combine(_exeSelectedMessage, "9999.3.5-dummy", _dotnetSdkDllMessageTerminator));
+
+ // Add SDK versions
+ AddAvailableSdkVersions(_exeSdkBaseDir, "9999.3.600");
+
+ // Specified SDK version: 9999.3.4-global-dummy
+ // Exe: 9999.4.1, 9999.3.4-dummy, 9999.3.3, 9999.3.4, 9999.3.5-dummy, 9999.3.600
+ // Expected: 9999.3.5-dummy from exe dir
+ dotnet.Exec("help")
+ .WorkingDirectory(_currentWorkingDir)
+ .WithUserProfile(_userDir)
+ .Environment(s_DefaultEnvironment)
+ .EnvironmentVariable("DOTNET_MULTILEVEL_LOOKUP", "0")
+ .CaptureStdOut()
+ .CaptureStdErr()
+ .Execute()
+ .Should()
+ .Pass()
+ .And
+ .HaveStdErrContaining(Path.Combine(_exeSelectedMessage, "9999.3.5-dummy", _dotnetSdkDllMessageTerminator));
+
+ // Add SDK versions
+ AddAvailableSdkVersions(_exeSdkBaseDir, "9999.3.4-global-dummy");
+
+ // Specified SDK version: 9999.3.4-global-dummy
+ // Exe: 9999.4.1, 9999.3.4-dummy, 9999.3.3, 9999.3.4, 9999.3.5-dummy, 9999.3.600, 9999.3.4-global-dummy
+ // Expected: 9999.3.4-global-dummy from exe dir
+ dotnet.Exec("help")
+ .WorkingDirectory(_currentWorkingDir)
+ .WithUserProfile(_userDir)
+ .Environment(s_DefaultEnvironment)
+ .EnvironmentVariable("DOTNET_MULTILEVEL_LOOKUP", "0")
+ .CaptureStdOut()
+ .CaptureStdErr()
+ .Execute()
+ .Should()
+ .Pass()
+ .And
+ .HaveStdErrContaining(Path.Combine(_exeSelectedMessage, "9999.3.4-global-dummy", _dotnetSdkDllMessageTerminator));
+
+ // Verify we have the expected SDK versions
+ dotnet.Exec("--list-sdks")
+ .WorkingDirectory(_currentWorkingDir)
+ .WithUserProfile(_userDir)
+ .Environment(s_DefaultEnvironment)
+ .EnvironmentVariable("DOTNET_MULTILEVEL_LOOKUP", "0")
+ .CaptureStdOut()
+ .Execute()
+ .Should()
+ .Pass()
+ .And
+ .HaveStdOutContaining("9999.3.4-dummy")
+ .And
+ .HaveStdOutContaining("9999.3.4-global-dummy")
+ .And
+ .HaveStdOutContaining("9999.4.1")
+ .And
+ .HaveStdOutContaining("9999.3.3")
+ .And
+ .HaveStdOutContaining("9999.3.4")
+ .And
+ .HaveStdOutContaining("9999.3.600")
+ .And
+ .HaveStdOutContaining("9999.3.5-dummy");
+ }
+
+ [Fact]
+ public void SdkLookup_Global_Json_Two_Part_Patch_Rollup()
+ {
+ var fixture = PreviouslyBuiltAndRestoredPortableTestProjectFixture
+ .Copy();
+
+ var dotnet = fixture.BuiltDotnet;
+
+ // Set specified SDK version = 9999.3.304-global-dummy
+ SetGlobalJsonVersion("TwoPart-global.json");
+
+ // Specified SDK version: 9999.3.304-global-dummy
+ // Exe: empty
+ // Expected: no compatible version and a specific error messages
+ dotnet.Exec("help")
+ .WorkingDirectory(_currentWorkingDir)
+ .WithUserProfile(_userDir)
+ .Environment(s_DefaultEnvironment)
+ .EnvironmentVariable("DOTNET_MULTILEVEL_LOOKUP", "0")
+ .CaptureStdOut()
+ .CaptureStdErr()
+ .Execute(fExpectedToFail: true)
+ .Should()
+ .Fail()
+ .And
+ .HaveStdErrContaining("A compatible installed dotnet SDK for global.json version")
+ .And
+ .HaveStdErrContaining("It was not possible to find any installed dotnet SDKs");
+
+ // Add SDK versions
+ AddAvailableSdkVersions(_exeSdkBaseDir, "9999.3.57", "9999.3.4-dummy");
+
+ // Specified SDK version: 9999.3.304-global-dummy
+ // Exe: 9999.3.57, 9999.3.4-dummy
+ // Expected: no compatible version and a specific error message
+ dotnet.Exec("help")
+ .WorkingDirectory(_currentWorkingDir)
+ .WithUserProfile(_userDir)
+ .Environment(s_DefaultEnvironment)
+ .EnvironmentVariable("DOTNET_MULTILEVEL_LOOKUP", "0")
+ .CaptureStdOut()
+ .CaptureStdErr()
+ .Execute(fExpectedToFail: true)
+ .Should()
+ .Fail()
+ .And
+ .HaveStdErrContaining("A compatible installed dotnet SDK for global.json version")
+ .And
+ .NotHaveStdErrContaining("It was not possible to find any installed dotnet SDKs");
+
+ // Add SDK versions
+ AddAvailableSdkVersions(_exeSdkBaseDir, "9999.3.300", "9999.7.304-global-dummy");
+
+ // Specified SDK version: 9999.3.304-global-dummy
+ // Exe: 9999.3.57, 9999.3.4-dummy, 9999.3.300, 9999.7.304-global-dummy
+ // Expected: no compatible version and a specific error message
+ dotnet.Exec("help")
+ .WorkingDirectory(_currentWorkingDir)
+ .WithUserProfile(_userDir)
+ .Environment(s_DefaultEnvironment)
+ .EnvironmentVariable("DOTNET_MULTILEVEL_LOOKUP", "0")
+ .CaptureStdOut()
+ .CaptureStdErr()
+ .Execute(fExpectedToFail: true)
+ .Should()
+ .Fail()
+ .And
+ .HaveStdErrContaining("A compatible installed dotnet SDK for global.json version")
+ .And
+ .NotHaveStdErrContaining("It was not possible to find any installed dotnet SDKs");
+
+ // Add SDK versions
+ AddAvailableSdkVersions(_exeSdkBaseDir, "9999.3.304");
+
+ // Specified SDK version: 9999.3.304-global-dummy
+ // Exe: 99999.3.57, 9999.3.4-dummy, 9999.3.300, 9999.7.304-global-dummy, 9999.3.304
+ // Expected: 9999.3.304 from exe dir
+ dotnet.Exec("help")
+ .WorkingDirectory(_currentWorkingDir)
+ .WithUserProfile(_userDir)
+ .Environment(s_DefaultEnvironment)
+ .EnvironmentVariable("DOTNET_MULTILEVEL_LOOKUP", "0")
+ .CaptureStdOut()
+ .CaptureStdErr()
+ .Execute()
+ .Should()
+ .Pass()
+ .And
+ .HaveStdErrContaining(Path.Combine(_exeSelectedMessage, "9999.3.304", _dotnetSdkDllMessageTerminator));
+
+ // Add SDK versions
+ AddAvailableSdkVersions(_exeSdkBaseDir, "9999.3.399", "9999.3.399-dummy", "9999.3.400");
+
+ // Specified SDK version: 9999.3.304-global-dummy
+ // Exe: 9999.3.57, 9999.3.4-dummy, 9999.3.300, 9999.7.304-global-dummy, 9999.3.304, 9999.3.399, 9999.3.399-dummy, 9999.3.400
+ // Expected: 9999.3.399 from exe dir
+ dotnet.Exec("help")
+ .WorkingDirectory(_currentWorkingDir)
+ .WithUserProfile(_userDir)
+ .Environment(s_DefaultEnvironment)
+ .EnvironmentVariable("DOTNET_MULTILEVEL_LOOKUP", "0")
+ .CaptureStdOut()
+ .CaptureStdErr()
+ .Execute()
+ .Should()
+ .Pass()
+ .And
+ .HaveStdErrContaining(Path.Combine(_exeSelectedMessage, "9999.3.399", _dotnetSdkDllMessageTerminator));
+
+ // Add SDK versions
+ AddAvailableSdkVersions(_exeSdkBaseDir, "9999.3.2400, 9999.3.3004");
+
+ // Specified SDK version: 9999.3.304-global-dummy
+ // Exe: 9999.3.57, 9999.3.4-dummy, 9999.3.300, 9999.7.304-global-dummy, 9999.3.304, 9999.3.399, 9999.3.399-dummy, 9999.3.400, 9999.3.2400, 9999.3.3004
+ // Expected: 9999.3.399 from exe dir
+ dotnet.Exec("help")
+ .WorkingDirectory(_currentWorkingDir)
+ .WithUserProfile(_userDir)
+ .Environment(s_DefaultEnvironment)
+ .EnvironmentVariable("DOTNET_MULTILEVEL_LOOKUP", "0")
+ .CaptureStdOut()
+ .CaptureStdErr()
+ .Execute()
+ .Should()
+ .Pass()
+ .And
+ .HaveStdErrContaining(Path.Combine(_exeSelectedMessage, "9999.3.399", _dotnetSdkDllMessageTerminator));
+
+ // Add SDK versions
+ AddAvailableSdkVersions(_exeSdkBaseDir, "9999.3.304-global-dummy");
+
+ // Specified SDK version: 9999.3.304-global-dummy
+ // Exe: 9999.3.57, 9999.3.4-dummy, 9999.3.300, 9999.7.304-global-dummy, 9999.3.304, 9999.3.399, 9999.3.399-dummy, 9999.3.400, 9999.3.2400, 9999.3.3004, 9999.3.304-global-dummy
+ // Expected: 9999.3.304-global-dummy from exe dir
+ dotnet.Exec("help")
+ .WorkingDirectory(_currentWorkingDir)
+ .WithUserProfile(_userDir)
+ .Environment(s_DefaultEnvironment)
+ .EnvironmentVariable("DOTNET_MULTILEVEL_LOOKUP", "0")
+ .CaptureStdOut()
+ .CaptureStdErr()
+ .Execute()
+ .Should()
+ .Pass()
+ .And
+ .HaveStdErrContaining(Path.Combine(_exeSelectedMessage, "9999.3.304-global-dummy", _dotnetSdkDllMessageTerminator));
+
+ // Verify we have the expected SDK versions
+ dotnet.Exec("--list-sdks")
+ .WorkingDirectory(_currentWorkingDir)
+ .WithUserProfile(_userDir)
+ .Environment(s_DefaultEnvironment)
+ .EnvironmentVariable("DOTNET_MULTILEVEL_LOOKUP", "0")
+ .CaptureStdOut()
+ .Execute()
+ .Should()
+ .Pass()
+ .And
+ .HaveStdOutContaining("9999.3.57")
+ .And
+ .HaveStdOutContaining("9999.3.4-dummy")
+ .And
+ .HaveStdOutContaining("9999.3.300")
+ .And
+ .HaveStdOutContaining("9999.7.304-global-dummy")
+ .And
+ .HaveStdOutContaining("9999.3.399")
+ .And
+ .HaveStdOutContaining("9999.3.399-dummy")
+ .And
+ .HaveStdOutContaining("9999.3.400")
+ .And
+ .HaveStdOutContaining("9999.3.2400")
+ .And
+ .HaveStdOutContaining("9999.3.3004")
+ .And
+ .HaveStdOutContaining("9999.3.304")
+ .And
+ .HaveStdOutContaining("9999.3.304-global-dummy");
+ }
+
+ [Fact]
+ public void SdkLookup_Negative_Version()
+ {
+ var fixture = PreviouslyBuiltAndRestoredPortableTestProjectFixture
+ .Copy();
+
+ var dotnet = fixture.BuiltDotnet;
+
+ // Add a negative SDK version
+ AddAvailableSdkVersions(_exeSdkBaseDir, "-1.-1.-1");
+
+ // Specified SDK version: none
+ // Exe: -1.-1.-1
+ // Expected: no compatible version and a specific error messages
+ dotnet.Exec("help")
+ .WorkingDirectory(_currentWorkingDir)
+ .WithUserProfile(_userDir)
+ .Environment(s_DefaultEnvironment)
+ .EnvironmentVariable("DOTNET_MULTILEVEL_LOOKUP", "0")
+ .CaptureStdOut()
+ .CaptureStdErr()
+ .Execute(fExpectedToFail: true)
+ .Should()
+ .Fail()
+ .And
+ .HaveStdErrContaining("It was not possible to find any installed dotnet SDKs")
+ .And
+ .HaveStdErrContaining("Did you mean to run dotnet SDK commands? Please install dotnet SDK from");
+
+ // Add SDK versions
+ AddAvailableSdkVersions(_exeSdkBaseDir, "9999.0.4");
+
+ // Specified SDK version: none
+ // Exe: -1.-1.-1, 9999.0.4
+ // Expected: 9999.0.4 from exe dir
+ dotnet.Exec("help")
+ .WorkingDirectory(_currentWorkingDir)
+ .WithUserProfile(_userDir)
+ .Environment(s_DefaultEnvironment)
+ .EnvironmentVariable("DOTNET_MULTILEVEL_LOOKUP", "0")
+ .CaptureStdOut()
+ .CaptureStdErr()
+ .Execute()
+ .Should()
+ .Pass()
+ .And
+ .HaveStdErrContaining(Path.Combine(_exeSelectedMessage, "9999.0.4", _dotnetSdkDllMessageTerminator));
+
+ // Verify we have the expected SDK versions
+ dotnet.Exec("--list-sdks")
+ .WorkingDirectory(_currentWorkingDir)
+ .WithUserProfile(_userDir)
+ .Environment(s_DefaultEnvironment)
+ .EnvironmentVariable("DOTNET_MULTILEVEL_LOOKUP", "0")
+ .CaptureStdOut()
+ .Execute()
+ .Should()
+ .Pass()
+ .And
+ .HaveStdOutContaining("9999.0.4");
+ }
+
+ [Fact]
+ public void SdkLookup_Must_Pick_The_Highest_Semantic_Version()
+ {
+ var fixture = PreviouslyBuiltAndRestoredPortableTestProjectFixture
+ .Copy();
+
+ var dotnet = fixture.BuiltDotnet;
+
+ // Add SDK versions
+ AddAvailableSdkVersions(_exeSdkBaseDir, "9999.0.0", "9999.0.3-dummy");
+
+ // Specified SDK version: none
+ // Cwd: empty
+ // User: empty
+ // Exe: 9999.0.0, 9999.0.3-dummy
+ // Expected: 9999.0.3-dummy from exe dir
+ dotnet.Exec("help")
+ .WorkingDirectory(_currentWorkingDir)
+ .WithUserProfile(_userDir)
+ .Environment(s_DefaultEnvironment)
+ .EnvironmentVariable("DOTNET_MULTILEVEL_LOOKUP", "0")
+ .CaptureStdOut()
+ .CaptureStdErr()
+ .Execute()
+ .Should()
+ .Pass()
+ .And
+ .HaveStdErrContaining(Path.Combine(_exeSelectedMessage, "9999.0.3-dummy", _dotnetSdkDllMessageTerminator));
+
+ // Add SDK versions
+ AddAvailableSdkVersions(_exeSdkBaseDir, "9999.0.3");
+
+ // Specified SDK version: none
+ // Cwd: empty
+ // User: empty
+ // Exe: 9999.0.0, 9999.0.3-dummy, 9999.0.3
+ // Expected: 9999.0.3 from exe dir
+ dotnet.Exec("help")
+ .WorkingDirectory(_currentWorkingDir)
+ .WithUserProfile(_userDir)
+ .Environment(s_DefaultEnvironment)
+ .EnvironmentVariable("DOTNET_MULTILEVEL_LOOKUP", "0")
+ .CaptureStdOut()
+ .CaptureStdErr()
+ .Execute()
+ .Should()
+ .Pass()
+ .And
+ .HaveStdErrContaining(Path.Combine(_exeSelectedMessage, "9999.0.3", _dotnetSdkDllMessageTerminator));
+
+ // Add SDK versions
+ AddAvailableSdkVersions(_userSdkBaseDir, "9999.0.200");
+ AddAvailableSdkVersions(_cwdSdkBaseDir, "10000.0.0");
+ AddAvailableSdkVersions(_exeSdkBaseDir, "9999.0.100");
+
+ // Specified SDK version: none
+ // Cwd: 10000.0.0 --> should not be picked
+ // User: 9999.0.200 --> should not be picked
+ // Exe: 9999.0.0, 9999.0.3-dummy, 9999.0.3, 9999.0.100
+ // Expected: 9999.0.100 from exe dir
+ dotnet.Exec("help")
+ .WorkingDirectory(_currentWorkingDir)
+ .WithUserProfile(_userDir)
+ .Environment(s_DefaultEnvironment)
+ .EnvironmentVariable("DOTNET_MULTILEVEL_LOOKUP", "0")
+ .CaptureStdOut()
+ .CaptureStdErr()
+ .Execute()
+ .Should()
+ .Pass()
+ .And
+ .HaveStdErrContaining(Path.Combine(_exeSelectedMessage, "9999.0.100", _dotnetSdkDllMessageTerminator));
+
+ // Add SDK versions
+ AddAvailableSdkVersions(_exeSdkBaseDir, "9999.0.80");
+
+ // Specified SDK version: none
+ // Cwd: 10000.0.0 --> should not be picked
+ // User: 9999.0.200 --> should not be picked
+ // Exe: 9999.0.0, 9999.0.3-dummy, 9999.0.3, 9999.0.100, 9999.0.80
+ // Expected: 9999.0.100 from exe dir
+ dotnet.Exec("help")
+ .WorkingDirectory(_currentWorkingDir)
+ .WithUserProfile(_userDir)
+ .Environment(s_DefaultEnvironment)
+ .EnvironmentVariable("DOTNET_MULTILEVEL_LOOKUP", "0")
+ .CaptureStdOut()
+ .CaptureStdErr()
+ .Execute()
+ .Should()
+ .Pass()
+ .And
+ .HaveStdErrContaining(Path.Combine(_exeSelectedMessage, "9999.0.100", _dotnetSdkDllMessageTerminator));
+
+ // Add SDK versions
+ AddAvailableSdkVersions(_exeSdkBaseDir, "9999.0.5500000");
+
+ // Specified SDK version: none
+ // Cwd: 10000.0.0 --> should not be picked
+ // User: 9999.0.200 --> should not be picked
+ // Exe: 9999.0.0, 9999.0.3-dummy, 9999.0.3, 9999.0.100, 9999.0.80, 9999.0.5500000
+ // Expected: 9999.0.5500000 from exe dir
+ dotnet.Exec("help")
+ .WorkingDirectory(_currentWorkingDir)
+ .WithUserProfile(_userDir)
+ .Environment(s_DefaultEnvironment)
+ .EnvironmentVariable("DOTNET_MULTILEVEL_LOOKUP", "0")
+ .CaptureStdOut()
+ .CaptureStdErr()
+ .Execute()
+ .Should()
+ .Pass()
+ .And
+ .HaveStdErrContaining(Path.Combine(_exeSelectedMessage, "9999.0.5500000", _dotnetSdkDllMessageTerminator));
+
+ // Add SDK versions
+ AddAvailableSdkVersions(_exeSdkBaseDir, "9999.0.52000000");
+
+ // Specified SDK version: none
+ // Cwd: 10000.0.0 --> should not be picked
+ // User: 9999.0.200 --> should not be picked
+ // Exe: 9999.0.0, 9999.0.3-dummy, 9999.0.3, 9999.0.100, 9999.0.80, 9999.0.5500000, 9999.0.52000000
+ // Expected: 9999.0.52000000 from exe dir
+ dotnet.Exec("help")
+ .WorkingDirectory(_currentWorkingDir)
+ .WithUserProfile(_userDir)
+ .Environment(s_DefaultEnvironment)
+ .EnvironmentVariable("DOTNET_MULTILEVEL_LOOKUP", "0")
+ .CaptureStdOut()
+ .CaptureStdErr()
+ .Execute()
+ .Should()
+ .Pass()
+ .And
+ .HaveStdErrContaining(Path.Combine(_exeSelectedMessage, "9999.0.52000000", _dotnetSdkDllMessageTerminator));
+
+ // Verify we have the expected SDK versions
+ dotnet.Exec("--list-sdks")
+ .WorkingDirectory(_currentWorkingDir)
+ .WithUserProfile(_userDir)
+ .Environment(s_DefaultEnvironment)
+ .EnvironmentVariable("DOTNET_MULTILEVEL_LOOKUP", "0")
+ .CaptureStdOut()
+ .Execute()
+ .Should()
+ .Pass()
+ .And
+ .HaveStdOutContaining("9999.0.0")
+ .And
+ .HaveStdOutContaining("9999.0.3-dummy")
+ .And
+ .HaveStdOutContaining("9999.0.3")
+ .And
+ .HaveStdOutContaining("9999.0.100")
+ .And
+ .HaveStdOutContaining("9999.0.80")
+ .And
+ .HaveStdOutContaining("9999.0.5500000")
+ .And
+ .HaveStdOutContaining("9999.0.52000000");
+ }
+
+ // This method adds a list of new sdk version folders in the specified
+ // sdkBaseDir. The files are copied from the _sdkDir. Also, the dotnet.runtimeconfig.json
+ // file is overwritten in order to use a dummy framework version (9999.0.0)
+ // Remarks:
+ // - If the sdkBaseDir does not exist, then a DirectoryNotFoundException
+ // is thrown.
+ // - If a specified version folder already exists, then it is deleted and replaced
+ // with the contents of the _builtSharedFxDir.
+ private void AddAvailableSdkVersions(string sdkBaseDir, params string[] availableVersions)
+ {
+ DirectoryInfo sdkBaseDirInfo = new DirectoryInfo(sdkBaseDir);
+
+ if (!sdkBaseDirInfo.Exists)
+ {
+ throw new DirectoryNotFoundException();
+ }
+
+ string dummyRuntimeConfig = Path.Combine(RepoDirectories.RepoRoot, "src", "test", "Assets", "TestUtils",
+ "SDKLookup", "dotnet.runtimeconfig.json");
+
+ foreach (string version in availableVersions)
+ {
+ string newSdkDir = Path.Combine(sdkBaseDir, version);
+ SharedFramework.CopyDirectory(_sdkDir, newSdkDir);
+
+ string runtimeConfig = Path.Combine(newSdkDir, "dotnet.runtimeconfig.json");
+ File.Copy(dummyRuntimeConfig, runtimeConfig, true);
+ }
+ }
+
+ // Put a global.json file in the cwd in order to specify a CLI
+ public void SetGlobalJsonVersion(string globalJsonFileName)
+ {
+ string destFile = Path.Combine(_currentWorkingDir, "global.json");
+ string srcFile = Path.Combine(RepoDirectories.RepoRoot, "src", "test", "Assets", "TestUtils",
+ "SDKLookup", globalJsonFileName);
+
+ File.Copy(srcFile, destFile, true);
+ }
+ }
+}
--- /dev/null
+using Microsoft.DotNet.InternalAbstractions;
+using Microsoft.DotNet.Cli.Build.Framework;
+using Newtonsoft.Json.Linq;
+using System;
+using System.IO;
+using Xunit;
+
+namespace Microsoft.DotNet.CoreSetup.Test.HostActivation.SharedFxLookup
+{
+ public partial class GivenThatICareAboutSharedFxLookup : IDisposable
+ {
+ private const string SystemCollectionsImmutableFileVersion = "88.2.3.4";
+ private const string SystemCollectionsImmutableAssemblyVersion = "88.0.1.2";
+
+ private RepoDirectoriesProvider RepoDirectories;
+ private TestProjectFixture PreviouslyBuiltAndRestoredPortableTestProjectFixture;
+
+ private string _currentWorkingDir;
+ private string _userDir;
+ private string _executableDir;
+ private string _globalDir;
+ private string _cwdSharedFxBaseDir;
+ private string _cwdSharedUberFxBaseDir;
+ private string _userSharedFxBaseDir;
+ private string _userSharedUberFxBaseDir;
+ private string _exeSharedFxBaseDir;
+ private string _exeSharedUberFxBaseDir;
+ private string _globalSharedFxBaseDir;
+ private string _globalSharedUberFxBaseDir;
+ private string _builtSharedFxDir;
+ private string _builtSharedUberFxDir;
+
+ private string _cwdSelectedMessage;
+ private string _userSelectedMessage;
+ private string _exeSelectedMessage;
+ private string _globalSelectedMessage;
+
+ private string _cwdFoundUberFxMessage;
+ private string _userFoundUberFxMessage;
+ private string _exeFoundUberFxMessage;
+ private string _globalFoundUberFxMessage;
+
+ private string _sharedFxVersion;
+ private string _baseDir;
+ private string _builtDotnet;
+ private string _hostPolicyDllName;
+
+ public GivenThatICareAboutSharedFxLookup()
+ {
+ // From the artifacts dir, it's possible to find where the sharedFrameworkPublish folder is. We need
+ // to locate it because we'll copy its contents into other folders
+ string artifactsDir = Environment.GetEnvironmentVariable("TEST_ARTIFACTS");
+ _builtDotnet = Path.Combine(artifactsDir, "sharedFrameworkPublish");
+
+ // The dotnetSharedFxLookup dir will contain some folders and files that will be
+ // necessary to perform the tests
+ string baseDir = Path.Combine(artifactsDir, "dotnetSharedFxLookup");
+ _baseDir = SharedFramework.CalculateUniqueTestDirectory(baseDir);
+
+ // The three tested locations will be the cwd, the user folder and the exe dir. Both cwd and exe dir
+ // are easily overwritten, so they will be placed inside the multilevel folder. The actual user location will
+ // be used during tests
+ _currentWorkingDir = Path.Combine(_baseDir, "cwd");
+ _userDir = Path.Combine(_baseDir, "user");
+ _executableDir = Path.Combine(_baseDir, "exe");
+ _globalDir = Path.Combine(_baseDir, "global");
+
+ RepoDirectories = new RepoDirectoriesProvider(builtDotnet: _executableDir);
+
+ // SharedFxBaseDirs contain all available version folders
+ _cwdSharedFxBaseDir = Path.Combine(_currentWorkingDir, "shared", "Microsoft.NETCore.App");
+ _userSharedFxBaseDir = Path.Combine(_userDir, ".dotnet", RepoDirectories.BuildArchitecture, "shared", "Microsoft.NETCore.App");
+ _exeSharedFxBaseDir = Path.Combine(_executableDir, "shared", "Microsoft.NETCore.App");
+ _globalSharedFxBaseDir = Path.Combine(_globalDir, "shared", "Microsoft.NETCore.App");
+
+ _cwdSharedUberFxBaseDir = Path.Combine(_currentWorkingDir, "shared", "Microsoft.UberFramework");
+ _userSharedUberFxBaseDir = Path.Combine(_userDir, ".dotnet", RepoDirectories.BuildArchitecture, "shared", "Microsoft.UberFramework");
+ _exeSharedUberFxBaseDir = Path.Combine(_executableDir, "shared", "Microsoft.UberFramework");
+ _globalSharedUberFxBaseDir = Path.Combine(_globalDir, "shared", "Microsoft.UberFramework");
+
+ // Create directories. It's necessary to copy the entire publish folder to the exe dir because
+ // we'll need to build from it. The CopyDirectory method automatically creates the dest dir
+ Directory.CreateDirectory(_cwdSharedFxBaseDir);
+ Directory.CreateDirectory(_userSharedFxBaseDir);
+ Directory.CreateDirectory(_globalSharedFxBaseDir);
+ Directory.CreateDirectory(_cwdSharedUberFxBaseDir);
+ Directory.CreateDirectory(_userSharedUberFxBaseDir);
+ Directory.CreateDirectory(_globalSharedUberFxBaseDir);
+ SharedFramework.CopyDirectory(_builtDotnet, _executableDir);
+
+ //Copy dotnet to global directory
+ File.Copy(Path.Combine(_builtDotnet, $"dotnet{Constants.ExeSuffix}"), Path.Combine(_globalDir, $"dotnet{Constants.ExeSuffix}"), true);
+
+ // Restore and build SharedFxLookupPortableApp from exe dir
+ PreviouslyBuiltAndRestoredPortableTestProjectFixture = new TestProjectFixture("SharedFxLookupPortableApp", RepoDirectories)
+ .EnsureRestored(RepoDirectories.CorehostPackages)
+ .BuildProject();
+ var fixture = PreviouslyBuiltAndRestoredPortableTestProjectFixture;
+
+ // The actual framework version can be obtained from the built fixture. We'll use it to
+ // locate the builtSharedFxDir from which we can get the files contained in the version folder
+ string greatestVersionSharedFxPath = fixture.BuiltDotnet.GreatestVersionSharedFxPath;
+ _sharedFxVersion = (new DirectoryInfo(greatestVersionSharedFxPath)).Name;
+ _builtSharedFxDir = Path.Combine(_builtDotnet, "shared", "Microsoft.NETCore.App", _sharedFxVersion);
+ _builtSharedUberFxDir = Path.Combine(_builtDotnet, "shared", "Microsoft.UberFramework", _sharedFxVersion);
+ SharedFramework.CreateUberFrameworkArtifacts(_builtSharedFxDir, _builtSharedUberFxDir, SystemCollectionsImmutableAssemblyVersion, SystemCollectionsImmutableFileVersion);
+
+ // Trace messages used to identify from which folder the framework was picked
+ _hostPolicyDllName = Path.GetFileName(fixture.TestProject.HostPolicyDll);
+ _cwdSelectedMessage = $"The expected {_hostPolicyDllName} directory is [{_cwdSharedFxBaseDir}";
+ _userSelectedMessage = $"The expected {_hostPolicyDllName} directory is [{_userSharedFxBaseDir}";
+ _exeSelectedMessage = $"The expected {_hostPolicyDllName} directory is [{_exeSharedFxBaseDir}";
+ _globalSelectedMessage = $"The expected {_hostPolicyDllName} directory is [{_globalSharedFxBaseDir}";
+
+ _cwdFoundUberFxMessage = $"Chose FX version [{_cwdSharedUberFxBaseDir}";
+ _userFoundUberFxMessage = $"Chose FX version [{_userSharedUberFxBaseDir}";
+ _exeFoundUberFxMessage = $"Chose FX version [{_exeSharedUberFxBaseDir}";
+ _globalFoundUberFxMessage = $"Chose FX version [{_globalSharedUberFxBaseDir}";
+ }
+
+ public void Dispose()
+ {
+ PreviouslyBuiltAndRestoredPortableTestProjectFixture.Dispose();
+
+ if (!TestProject.PreserveTestRuns())
+ {
+ Directory.Delete(_baseDir, true);
+ }
+ }
+
+ [Fact]
+ public void SharedFxLookup_Must_Verify_Folders_in_the_Correct_Order()
+ {
+ var fixture = PreviouslyBuiltAndRestoredPortableTestProjectFixture
+ .Copy();
+
+ var dotnet = fixture.BuiltDotnet;
+ var appDll = fixture.TestProject.AppDll;
+
+ // Set desired version = 9999.0.0
+ string runtimeConfig = Path.Combine(fixture.TestProject.OutputDirectory, "SharedFxLookupPortableApp.runtimeconfig.json");
+ SharedFramework.SetRuntimeConfigJson(runtimeConfig, "9999.0.0");
+
+ // Add version in the exe dir
+ SharedFramework.AddAvailableSharedFxVersions(_builtSharedFxDir, _exeSharedFxBaseDir, "9999.0.0");
+
+ // Version: 9999.0.0
+ // User: empty
+ // Exe: 9999.0.0
+ // Expected: 9999.0.0 from exe dir
+ dotnet.Exec(appDll)
+ .WorkingDirectory(_currentWorkingDir)
+ .EnvironmentVariable("COREHOST_TRACE", "1")
+ .WithUserProfile(_userDir)
+ .CaptureStdOut()
+ .CaptureStdErr()
+ .Execute()
+ .Should()
+ .Pass()
+ .And
+ .HaveStdErrContaining(_exeSelectedMessage);
+
+ // Add a dummy version in the user dir
+ SharedFramework.AddAvailableSharedFxVersions(_builtSharedFxDir, _userSharedFxBaseDir, "9999.0.0");
+
+ // Version: 9999.0.0
+ // User: 9999.0.0 --> should not be picked
+ // Exe: 9999.0.0
+ // Expected: 9999.0.0 from user dir
+ dotnet.Exec(appDll)
+ .WorkingDirectory(_currentWorkingDir)
+ .EnvironmentVariable("COREHOST_TRACE", "1")
+ .WithUserProfile(_userDir)
+ .CaptureStdOut()
+ .CaptureStdErr()
+ .Execute()
+ .Should()
+ .Pass()
+ .And
+ .HaveStdErrContaining(_exeSelectedMessage);
+
+ // Add a dummy version in the cwd
+ SharedFramework.AddAvailableSharedFxVersions(_builtSharedFxDir, _cwdSharedFxBaseDir, "9999.0.0");
+
+ // Version: 9999.0.0
+ // CWD: 9999.0.0 --> should not be picked
+ // User: 9999.0.0
+ // Exe: 9999.0.0
+ // Expected: 9999.0.0 from user Exe
+ dotnet.Exec(appDll)
+ .WorkingDirectory(_currentWorkingDir)
+ .EnvironmentVariable("COREHOST_TRACE", "1")
+ .WithUserProfile(_userDir)
+ .CaptureStdOut()
+ .CaptureStdErr()
+ .Execute()
+ .Should()
+ .Pass()
+ .And
+ .HaveStdErrContaining(_exeSelectedMessage);
+
+ // Verify we have the expected runtime versions
+ dotnet.Exec("--list-runtimes")
+ .WorkingDirectory(_currentWorkingDir)
+ .WithUserProfile(_userDir)
+ .CaptureStdOut()
+ .Execute()
+ .Should()
+ .Pass()
+ .And
+ .HaveStdOutContaining("Microsoft.NETCore.App 9999.0.0");
+ }
+
+ [Fact]
+ public void SharedFxLookup_Must_Not_Roll_Forward_If_Framework_Version_Is_Specified_Through_Argument()
+ {
+ var fixture = PreviouslyBuiltAndRestoredPortableTestProjectFixture
+ .Copy();
+
+ var dotnet = fixture.BuiltDotnet;
+ var appDll = fixture.TestProject.AppDll;
+
+ // Add some dummy versions
+ SharedFramework.AddAvailableSharedFxVersions(_builtSharedFxDir, _exeSharedFxBaseDir, "9999.0.0", "9999.0.2", "9999.0.0-dummy2", "9999.0.3", "9999.0.0-dummy3");
+
+ // Version: 9999.0.0 (through --fx-version arg)
+ // Exe: 9999.0.2, 9999.0.0-dummy2, 9999.0.0, 9999.0.3, 9999.0.0-dummy3
+ // global: empty
+ // Expected: 9999.0.0 from exe dir
+ dotnet.Exec("--fx-version", "9999.0.0", appDll)
+ .WorkingDirectory(_currentWorkingDir)
+ .EnvironmentVariable("COREHOST_TRACE", "1")
+ .CaptureStdOut()
+ .CaptureStdErr()
+ .Execute()
+ .Should()
+ .Pass()
+ .And
+ .HaveStdErrContaining(Path.Combine(_exeSelectedMessage, "9999.0.0"));
+
+ // Version: 9999.0.0-dummy1 (through --fx-version arg)
+ // Exe: 9999.0.2, 9999.0.0-dummy2,9999.0.0, 9999.0.3, 9999.0.0-dummy3
+ // global: empty
+ // Expected: no compatible version
+ dotnet.Exec("--fx-version", "9999.0.0-dummy1", appDll)
+ .WorkingDirectory(_currentWorkingDir)
+ .EnvironmentVariable("COREHOST_TRACE", "1")
+ .CaptureStdOut()
+ .CaptureStdErr()
+ .Execute(fExpectedToFail: true)
+ .Should()
+ .Fail()
+ .And
+ .HaveStdErrContaining("It was not possible to find any compatible framework version");
+
+ // Verify we have the expected runtime versions
+ dotnet.Exec("--list-runtimes")
+ .WorkingDirectory(_currentWorkingDir)
+ .CaptureStdOut()
+ .Execute()
+ .Should()
+ .Pass()
+ .And
+ .HaveStdOutContaining("Microsoft.NETCore.App 9999.0.0")
+ .And
+ .HaveStdOutContaining("Microsoft.NETCore.App 9999.0.0-dummy2")
+ .And
+ .HaveStdOutContaining("Microsoft.NETCore.App 9999.0.2")
+ .And
+ .HaveStdOutContaining("Microsoft.NETCore.App 9999.0.3")
+ .And
+ .HaveStdOutContaining("Microsoft.NETCore.App 9999.0.0-dummy3");
+ }
+
+ [Fact]
+ public void Roll_Forward_On_No_Candidate_Fx_Must_Happen_If_Compatible_Patch_Version_Is_Not_Available()
+ {
+ var fixture = PreviouslyBuiltAndRestoredPortableTestProjectFixture
+ .Copy();
+
+ var dotnet = fixture.BuiltDotnet;
+ var appDll = fixture.TestProject.AppDll;
+
+ // Set desired version = 9999.0.0
+ string runtimeConfig = Path.Combine(fixture.TestProject.OutputDirectory, "SharedFxLookupPortableApp.runtimeconfig.json");
+ SharedFramework.SetRuntimeConfigJson(runtimeConfig, "9999.0.0");
+
+ // Add some dummy versions in the exe
+ SharedFramework.AddAvailableSharedFxVersions(_builtSharedFxDir, _exeSharedFxBaseDir, "10000.1.1", "10000.1.3");
+
+ // Version: 9999.0.0
+ // 'Roll forward on no candidate fx' enabled with value 2 (major+minor) through env var
+ // exe: 10000.1.1, 10000.1.3
+ // Expected: 10000.1.3 from exe
+ dotnet.Exec(appDll)
+ .WorkingDirectory(_currentWorkingDir)
+ .EnvironmentVariable("DOTNET_ROLL_FORWARD_ON_NO_CANDIDATE_FX", "2")
+ .EnvironmentVariable("COREHOST_TRACE", "1")
+ .CaptureStdOut()
+ .CaptureStdErr()
+ .Execute()
+ .Should()
+ .Pass()
+ .And
+ .HaveStdErrContaining(Path.Combine(_exeSelectedMessage, "10000.1.3"));
+
+ // Add a dummy version in the exe dir
+ SharedFramework.AddAvailableSharedFxVersions(_builtSharedFxDir, _exeSharedFxBaseDir, "9999.1.1");
+
+ // Version: 9999.0.0
+ // 'Roll forward on no candidate fx' enabled with value 2 (major+minor) through env var
+ // exe: 9999.1.1, 10000.1.1, 10000.1.3
+ // Expected: 9999.1.1 from exe
+ dotnet.Exec(appDll)
+ .WorkingDirectory(_currentWorkingDir)
+ .EnvironmentVariable("DOTNET_ROLL_FORWARD_ON_NO_CANDIDATE_FX", "2")
+ .EnvironmentVariable("COREHOST_TRACE", "1")
+ .CaptureStdOut()
+ .CaptureStdErr()
+ .Execute()
+ .Should()
+ .Pass()
+ .And
+ .HaveStdErrContaining(Path.Combine(_exeSelectedMessage, "9999.1.1"))
+ .And
+ .HaveStdOutContaining("Framework Version:9999.1.1");
+
+ // Verify we have the expected runtime versions
+ dotnet.Exec("--list-runtimes")
+ .WorkingDirectory(_currentWorkingDir)
+ .CaptureStdOut()
+ .Execute()
+ .Should()
+ .Pass()
+ .And
+ .HaveStdOutContaining("Microsoft.NETCore.App 9999.1.1")
+ .And
+ .HaveStdOutContaining("Microsoft.NETCore.App 10000.1.1")
+ .And
+ .HaveStdOutContaining("Microsoft.NETCore.App 10000.1.3");
+ }
+
+ [Fact]
+ public void Roll_Forward_On_No_Candidate_Fx_Minor_And_Disabled()
+ {
+ var fixture = PreviouslyBuiltAndRestoredPortableTestProjectFixture
+ .Copy();
+
+ var dotnet = fixture.BuiltDotnet;
+ var appDll = fixture.TestProject.AppDll;
+
+ // Set desired version = 9999.0.0
+ string runtimeConfig = Path.Combine(fixture.TestProject.OutputDirectory, "SharedFxLookupPortableApp.runtimeconfig.json");
+ SharedFramework.SetRuntimeConfigJson(runtimeConfig, "9999.0.0");
+
+ // Add some dummy versions in the exe
+ SharedFramework.AddAvailableSharedFxVersions(_builtSharedFxDir, _exeSharedFxBaseDir, "10000.1.1");
+
+ // Version: 9999.0.0
+ // 'Roll forward on no candidate fx' default value of 1 (minor)
+ // exe: 10000.1.1
+ // Expected: fail with no framework
+ dotnet.Exec(appDll)
+ .WorkingDirectory(_currentWorkingDir)
+ .EnvironmentVariable("COREHOST_TRACE", "1")
+ .CaptureStdOut()
+ .CaptureStdErr()
+ .Execute(fExpectedToFail: true)
+ .Should()
+ .Fail()
+ .And
+ .HaveStdErrContaining("It was not possible to find any compatible framework version");
+
+ // Add a dummy version in the exe dir
+ SharedFramework.AddAvailableSharedFxVersions(_builtSharedFxDir, _exeSharedFxBaseDir, "9999.1.1");
+
+ // Version: 9999.0.0
+ // 'Roll forward on no candidate fx' default value of 1 (minor)
+ // exe: 9999.1.1, 10000.1.1
+ // Expected: 9999.1.1 from exe
+ dotnet.Exec(appDll)
+ .WorkingDirectory(_currentWorkingDir)
+ .EnvironmentVariable("COREHOST_TRACE", "1")
+ .CaptureStdOut()
+ .CaptureStdErr()
+ .Execute()
+ .Should()
+ .Pass()
+ .And
+ .HaveStdErrContaining(Path.Combine(_exeSelectedMessage, "9999.1.1"))
+ .And
+ .HaveStdOutContaining("Framework Version:9999.1.1");
+
+ // Version: 9999.0.0
+ // 'Roll forward on no candidate fx' disabled through env var
+ // exe: 9999.1.1, 10000.1.1
+ // Expected: fail with no framework
+ dotnet.Exec(appDll)
+ .WorkingDirectory(_currentWorkingDir)
+ .EnvironmentVariable("COREHOST_TRACE", "1")
+ .EnvironmentVariable("DOTNET_ROLL_FORWARD_ON_NO_CANDIDATE_FX", "0")
+ .CaptureStdOut()
+ .CaptureStdErr()
+ .Execute(fExpectedToFail: true)
+ .Should()
+ .Fail()
+ .And
+ .HaveStdErrContaining("It was not possible to find any compatible framework version");
+
+ // Verify we have the expected runtime versions
+ dotnet.Exec("--list-runtimes")
+ .WorkingDirectory(_currentWorkingDir)
+ .CaptureStdOut()
+ .Execute()
+ .Should()
+ .Pass()
+ .And
+ .HaveStdOutContaining("Microsoft.NETCore.App 9999.1.1")
+ .And
+ .HaveStdOutContaining("Microsoft.NETCore.App 10000.1.1");
+ }
+
+ [Fact]
+ public void Roll_Forward_On_No_Candidate_Fx_Production_To_Preview()
+ {
+ var fixture = PreviouslyBuiltAndRestoredPortableTestProjectFixture
+ .Copy();
+
+ var dotnet = fixture.BuiltDotnet;
+ var appDll = fixture.TestProject.AppDll;
+
+ // Set desired version = 9999.0.0
+ string runtimeConfig = Path.Combine(fixture.TestProject.OutputDirectory, "SharedFxLookupPortableApp.runtimeconfig.json");
+ SharedFramework.SetRuntimeConfigJson(runtimeConfig, "9999.0.0");
+
+ // Add preview version in the exe
+ SharedFramework.AddAvailableSharedFxVersions(_builtSharedFxDir, _exeSharedFxBaseDir, "9999.1.1-dummy1");
+
+ // Version: 9999.0.0
+ // 'Roll forward on no candidate fx' default value of 1 (minor)
+ // exe: 9999.1.1-dummy1
+ // Expected: 9999.1.1-dummy1 since there is no production version
+ dotnet.Exec(appDll)
+ .WorkingDirectory(_currentWorkingDir)
+ .EnvironmentVariable("COREHOST_TRACE", "1")
+ .CaptureStdOut()
+ .CaptureStdErr()
+ .Execute()
+ .Should()
+ .Pass()
+ .And
+ .HaveStdErrContaining(Path.Combine(_exeSelectedMessage, "9999.1.1-dummy1"));
+
+ // Add a production version with higher value
+ SharedFramework.AddAvailableSharedFxVersions(_builtSharedFxDir, _exeSharedFxBaseDir, "9999.2.1");
+
+ // Version: 9999.0.0
+ // 'Roll forward on no candidate fx' default value of 1 (minor)
+ // exe: 9999.1.1-dummy1, 9999.2.1
+ // Expected: 9999.2.1 since we favor production over preview
+ dotnet.Exec(appDll)
+ .WorkingDirectory(_currentWorkingDir)
+ .EnvironmentVariable("COREHOST_TRACE", "1")
+ .CaptureStdOut()
+ .CaptureStdErr()
+ .Execute()
+ .Should()
+ .Pass()
+ .And
+ .HaveStdErrContaining(Path.Combine(_exeSelectedMessage, "9999.2.1"));
+
+ // Add a preview version with same major.minor as production
+ SharedFramework.AddAvailableSharedFxVersions(_builtSharedFxDir, _exeSharedFxBaseDir, "9999.2.1-dummy1");
+
+ // Version: 9999.0.0
+ // 'Roll forward on no candidate fx' default value of 1 (minor)
+ // exe: 9999.1.1-dummy1, 9999.2.1, 9999.2.1-dummy1
+ // Expected: 9999.2.1 since we favor production over preview
+ dotnet.Exec(appDll)
+ .WorkingDirectory(_currentWorkingDir)
+ .EnvironmentVariable("COREHOST_TRACE", "1")
+ .CaptureStdOut()
+ .CaptureStdErr()
+ .Execute()
+ .Should()
+ .Pass()
+ .And
+ .HaveStdErrContaining(Path.Combine(_exeSelectedMessage, "9999.2.1"));
+
+ // Add a preview version with same major.minor as production but higher patch version
+ SharedFramework.AddAvailableSharedFxVersions(_builtSharedFxDir, _exeSharedFxBaseDir, "9999.2.2-dummy1");
+
+ // Version: 9999.0.0
+ // 'Roll forward on no candidate fx' default value of 1 (minor)
+ // exe: 9999.1.1-dummy1, 9999.2.1, 9999.2.1-dummy1, 9999.2.2-dummy1
+ // Expected: 9999.2.1 since we favor production over preview
+ dotnet.Exec(appDll)
+ .WorkingDirectory(_currentWorkingDir)
+ .EnvironmentVariable("COREHOST_TRACE", "1")
+ .CaptureStdOut()
+ .CaptureStdErr()
+ .Execute()
+ .Should()
+ .Pass()
+ .And
+ .HaveStdErrContaining(Path.Combine(_exeSelectedMessage, "9999.2.1"));
+
+ // Verify we have the expected runtime versions
+ dotnet.Exec("--list-runtimes")
+ .WorkingDirectory(_currentWorkingDir)
+ .CaptureStdOut()
+ .Execute()
+ .Should()
+ .Pass()
+ .And
+ .HaveStdOutContaining("Microsoft.NETCore.App 9999.1.1-dummy1")
+ .And
+ .HaveStdOutContaining("Microsoft.NETCore.App 9999.2.1")
+ .And
+ .HaveStdOutContaining("Microsoft.NETCore.App 9999.2.1-dummy1")
+ .And
+ .HaveStdOutContaining("Microsoft.NETCore.App 9999.2.2-dummy1");
+ }
+
+ [Fact]
+ public void Roll_Forward_On_No_Candidate_Fx_Preview_To_Production()
+ {
+ var fixture = PreviouslyBuiltAndRestoredPortableTestProjectFixture
+ .Copy();
+
+ var dotnet = fixture.BuiltDotnet;
+ var appDll = fixture.TestProject.AppDll;
+
+ // Set desired version = 9999.0.0-dummy1
+ string runtimeConfig = Path.Combine(fixture.TestProject.OutputDirectory, "SharedFxLookupPortableApp.runtimeconfig.json");
+ SharedFramework.SetRuntimeConfigJson(runtimeConfig, "9999.0.0-dummy1");
+
+ // Add dummy versions in the exe
+ SharedFramework.AddAvailableSharedFxVersions(_builtSharedFxDir, _exeSharedFxBaseDir, "9999.0.0", "9999.0.1-dummy1");
+
+ // Version: 9999.0.0-dummy1
+ // exe: 9999.0.0, 9999.0.1-dummy1
+ // Expected: fail since we don't roll forward unless match on major.minor.patch and never roll forward to production
+ dotnet.Exec(appDll)
+ .WorkingDirectory(_currentWorkingDir)
+ .EnvironmentVariable("COREHOST_TRACE", "1")
+ .CaptureStdOut()
+ .CaptureStdErr()
+ .Execute(fExpectedToFail: true)
+ .Should()
+ .Fail()
+ .And
+ .HaveStdErrContaining("It was not possible to find any compatible framework version");
+
+ // Add preview versions in the exe with name major.minor.patch
+ SharedFramework.AddAvailableSharedFxVersions(_builtSharedFxDir, _exeSharedFxBaseDir, "9999.0.0-dummy2", "9999.0.0-dummy3");
+
+ // Version: 9999.0.0-dummy1
+ // exe: 9999.0.0-dummy2, 9999.0.0-dummy3, 9999.0.0, 9999.0.1-dummy1
+ // Expected: 9999.0.0-dummy2
+ dotnet.Exec(appDll)
+ .WorkingDirectory(_currentWorkingDir)
+ .EnvironmentVariable("COREHOST_TRACE", "1")
+ .CaptureStdOut()
+ .CaptureStdErr()
+ .Execute()
+ .Should()
+ .Pass()
+ .And
+ .HaveStdErrContaining(Path.Combine(_exeSelectedMessage, "9999.0.0-dummy2"))
+ .And
+ .HaveStdOutContaining("Framework Version:9999.0.0-dummy2");
+
+ // Verify we have the expected runtime versions
+ dotnet.Exec("--list-runtimes")
+ .WorkingDirectory(_currentWorkingDir)
+ .CaptureStdOut()
+ .Execute()
+ .Should()
+ .Pass()
+ .And
+ .HaveStdOutContaining("9999.0.0-dummy2")
+ .And
+ .HaveStdOutContaining("9999.0.0-dummy3")
+ .And
+ .HaveStdOutContaining("9999.0.0")
+ .And
+ .HaveStdOutContaining("9999.0.1-dummy1");
+ }
+
+ [Fact]
+ public void Roll_Forward_On_No_Candidate_Fx_Fails_If_No_Higher_Version_Is_Available()
+ {
+ var fixture = PreviouslyBuiltAndRestoredPortableTestProjectFixture
+ .Copy();
+
+ var dotnet = fixture.BuiltDotnet;
+ var appDll = fixture.TestProject.AppDll;
+
+ // Set desired version = 9999.1.1
+ string runtimeConfig = Path.Combine(fixture.TestProject.OutputDirectory, "SharedFxLookupPortableApp.runtimeconfig.json");
+ SharedFramework.SetRuntimeConfigJson(runtimeConfig, "9999.1.1");
+
+ // Add some dummy versions in the exe
+ SharedFramework.AddAvailableSharedFxVersions(_builtSharedFxDir, _exeSharedFxBaseDir, "9998.0.1", "9998.1.0", "9999.0.0", "9999.0.1", "9999.1.0");
+
+ // Version: 9999.1.1
+ // exe: 9998.0.1, 9998.1.0, 9999.0.0, 9999.0.1, 9999.1.0
+ // Expected: no compatible version
+ dotnet.Exec(appDll)
+ .WorkingDirectory(_currentWorkingDir)
+ .EnvironmentVariable("COREHOST_TRACE", "1")
+ .CaptureStdOut()
+ .CaptureStdErr()
+ .Execute(fExpectedToFail: true)
+ .Should()
+ .Fail()
+ .And
+ .HaveStdErrContaining("It was not possible to find any compatible framework version");
+
+ // Verify we have the expected runtime versions
+ dotnet.Exec("--list-runtimes")
+ .WorkingDirectory(_currentWorkingDir)
+ .CaptureStdOut()
+ .Execute()
+ .Should()
+ .Pass()
+ .And
+ .HaveStdOutContaining("Microsoft.NETCore.App 9998.0.1")
+ .And
+ .HaveStdOutContaining("Microsoft.NETCore.App 9998.1.0")
+ .And
+ .HaveStdOutContaining("Microsoft.NETCore.App 9999.0.0")
+ .And
+ .HaveStdOutContaining("Microsoft.NETCore.App 9999.0.1")
+ .And
+ .HaveStdOutContaining("Microsoft.NETCore.App 9999.1.0");
+ }
+
+ [Fact]
+ public void Multiple_SharedFxLookup_Independent_Roll_Forward()
+ {
+ var fixture = PreviouslyBuiltAndRestoredPortableTestProjectFixture
+ .Copy();
+
+ var dotnet = fixture.BuiltDotnet;
+ var appDll = fixture.TestProject.AppDll;
+
+ string runtimeConfig = Path.Combine(fixture.TestProject.OutputDirectory, "SharedFxLookupPortableApp.runtimeconfig.json");
+ SharedFramework.SetRuntimeConfigJson(runtimeConfig, "7777.0.0", null, useUberFramework: true);
+
+ // Add versions in the exe folders
+ SharedFramework.AddAvailableSharedFxVersions(_builtSharedFxDir, _exeSharedFxBaseDir, "9999.0.0");
+ SharedFramework.AddAvailableSharedUberFxVersions(_builtSharedUberFxDir, _exeSharedUberFxBaseDir, "9999.0.0", "7777.0.0");
+
+ // Version: NetCoreApp 9999.0.0
+ // UberFramework 7777.0.0
+ // Exe: NetCoreApp 9999.0.0
+ // UberFramework 7777.0.0
+ // Expected: 9999.0.0
+ // 7777.0.0
+ dotnet.Exec(appDll)
+ .WorkingDirectory(_currentWorkingDir)
+ .EnvironmentVariable("COREHOST_TRACE", "1")
+ .CaptureStdOut()
+ .CaptureStdErr()
+ .Execute()
+ .Should()
+ .Pass()
+ .And
+ .HaveStdErrContaining(Path.Combine(_exeSelectedMessage, "9999.0.0"))
+ .And
+ .HaveStdOutContaining("Framework Version:9999.0.0")
+ .And
+ .HaveStdErrContaining(Path.Combine(_exeFoundUberFxMessage, "7777.0.0"));
+
+ // Add a newer version to verify roll-forward
+ SharedFramework.AddAvailableSharedFxVersions(_builtSharedFxDir, _exeSharedFxBaseDir, "9999.0.1");
+ SharedFramework.AddAvailableSharedUberFxVersions(_builtSharedUberFxDir, _exeSharedUberFxBaseDir, "9999.0.0", "7777.0.1");
+
+ // Version: NetCoreApp 9999.0.0
+ // UberFramework 7777.0.0
+ // Exe: NetCoreApp 9999.0.0, 9999.0.1
+ // UberFramework 7777.0.0, 7777.0.1
+ // Expected: 9999.0.1
+ // 7777.0.1
+ dotnet.Exec(appDll)
+ .WorkingDirectory(_currentWorkingDir)
+ .EnvironmentVariable("COREHOST_TRACE", "1")
+ .CaptureStdOut()
+ .CaptureStdErr()
+ .Execute()
+ .Should()
+ .Pass()
+ .And
+ .HaveStdErrContaining(Path.Combine(_exeSelectedMessage, "9999.0.1"))
+ .And
+ .HaveStdErrContaining(Path.Combine(_exeFoundUberFxMessage, "7777.0.1"));
+
+ // Verify we have the expected runtime versions
+ dotnet.Exec("--list-runtimes")
+ .WorkingDirectory(_currentWorkingDir)
+ .WithUserProfile(_userDir)
+ .CaptureStdOut()
+ .Execute()
+ .Should()
+ .Pass()
+ .And
+ .HaveStdOutContaining("Microsoft.NETCore.App 9999.0.0")
+ .And
+ .HaveStdOutContaining("Microsoft.NETCore.App 9999.0.1")
+ .And
+ .HaveStdOutContaining("Microsoft.UberFramework 7777.0.0")
+ .And
+ .HaveStdOutContaining("Microsoft.UberFramework 7777.0.1");
+ }
+
+ [Fact]
+ public void Multiple_SharedFxLookup_Do_Not_Propagate()
+ {
+ var fixture = PreviouslyBuiltAndRestoredPortableTestProjectFixture
+ .Copy();
+
+ var dotnet = fixture.BuiltDotnet;
+ var appDll = fixture.TestProject.AppDll;
+
+ string runtimeConfig = Path.Combine(fixture.TestProject.OutputDirectory, "SharedFxLookupPortableApp.runtimeconfig.json");
+ SharedFramework.SetRuntimeConfigJson(runtimeConfig, "7777.0.0", null, useUberFramework: true);
+
+ // Add versions in the exe folders
+ SharedFramework.AddAvailableSharedFxVersions(_builtSharedFxDir, _exeSharedFxBaseDir, "9999.1.0");
+ SharedFramework.AddAvailableSharedUberFxVersions(_builtSharedUberFxDir, _exeSharedUberFxBaseDir, "9999.0.0", "7777.0.0");
+
+ // Version: NetCoreApp 9999.0.0
+ // UberFramework 7777.0.0
+ // 'Roll forward on no candidate fx' disabled through env var
+ // Exe: NetCoreApp 9999.1.0
+ // UberFramework 7777.0.0
+ // Expected: no compatible version
+ dotnet.Exec(appDll)
+ .WorkingDirectory(_currentWorkingDir)
+ .EnvironmentVariable("COREHOST_TRACE", "1")
+ .EnvironmentVariable("DOTNET_ROLL_FORWARD_ON_NO_CANDIDATE_FX", "0")
+ .CaptureStdOut()
+ .CaptureStdErr()
+ .Execute(fExpectedToFail: true)
+ .Should()
+ .Fail()
+ .And
+ .HaveStdErrContaining("It was not possible to find any compatible framework version");
+
+ // Enable rollForwardOnNoCandidateFx on app's config, which will not be used as the default for Uber's config
+ SharedFramework.SetRuntimeConfigJson(runtimeConfig, "7777.0.0", rollFwdOnNoCandidateFx: 1, useUberFramework: true);
+
+ // Version: NetCoreApp 9999.0.0
+ // UberFramework 7777.0.0
+ // 'Roll forward on no candidate fx' enabled through config
+ // Exe: NetCoreApp 9999.1.0
+ // UberFramework 7777.0.0
+ // Expected: no compatible version
+ dotnet.Exec(appDll)
+ .WorkingDirectory(_currentWorkingDir)
+ .EnvironmentVariable("COREHOST_TRACE", "1")
+ .EnvironmentVariable("DOTNET_ROLL_FORWARD_ON_NO_CANDIDATE_FX", "0")
+ .CaptureStdOut()
+ .CaptureStdErr()
+ .Execute(fExpectedToFail: true)
+ .Should()
+ .Fail()
+ .And
+ .HaveStdErrContaining("It was not possible to find any compatible framework version");
+ }
+
+ [Fact]
+ public void Multiple_Fx_References_Cant_Roll_Forward_Because_Incompatible_Config()
+ {
+ var fixture = PreviouslyBuiltAndRestoredPortableTestProjectFixture
+ .Copy();
+
+ var dotnet = fixture.BuiltDotnet;
+ var appDll = fixture.TestProject.AppDll;
+
+ string runtimeConfig = Path.Combine(fixture.TestProject.OutputDirectory, "SharedFxLookupPortableApp.runtimeconfig.json");
+
+ var additionalfxs = new JArray();
+ additionalfxs.Add(GetAdditionalFramework("Microsoft.NETCore.App", "9999.1.0", applyPatches: false, rollForwardOnNoCandidateFx: 0));
+ SharedFramework.SetRuntimeConfigJson(runtimeConfig, "7777.0.0", null, useUberFramework: true, frameworks: additionalfxs);
+
+ // Add versions in the exe folders
+ SharedFramework.AddAvailableSharedFxVersions(_builtSharedFxDir, _exeSharedFxBaseDir, "9999.1.0", "9999.5.5");
+ SharedFramework.AddAvailableSharedUberFxVersions(_builtSharedUberFxDir, _exeSharedUberFxBaseDir, "9999.5.5", "7777.0.0");
+
+ // Verify that both 9999.1.0 and 9999.5.5 can't be selected with roll-forward disabled
+ // Version: NetCoreApp 9999.5.5 (in framework section)
+ // NetCoreApp 9999.1.0 (in frameworks section)
+ // UberFramework 7777.0.0
+ // Exe: NetCoreApp 9999.1.0 rollForwardOnNoCandidateFx:0 applyPatches:false
+ // NetCoreApp 9999.5.5
+ // UberFramework 7777.0.0
+ // Expected: no compatible version
+ dotnet.Exec(appDll)
+ .WorkingDirectory(_currentWorkingDir)
+ .EnvironmentVariable("COREHOST_TRACE", "1")
+ .CaptureStdOut()
+ .CaptureStdErr()
+ .Execute(fExpectedToFail: true)
+ .Should()
+ .Fail()
+ .And
+ .HaveStdErrContaining("cannot roll-forward to the previously referenced version '9999.5.5");
+ }
+
+ [Fact]
+ public void Multiple_Fx_References_Can_Roll_Forward_Without_Retry()
+ {
+ var fixture = PreviouslyBuiltAndRestoredPortableTestProjectFixture
+ .Copy();
+
+ var dotnet = fixture.BuiltDotnet;
+ var appDll = fixture.TestProject.AppDll;
+
+ string runtimeConfig = Path.Combine(fixture.TestProject.OutputDirectory, "SharedFxLookupPortableApp.runtimeconfig.json");
+
+ var additionalfxs = new JArray();
+ additionalfxs.Add(GetAdditionalFramework("Microsoft.NETCore.App", "9999.1.1", applyPatches: false, rollForwardOnNoCandidateFx: 1));
+ SharedFramework.SetRuntimeConfigJson(runtimeConfig, "7777.0.0", null, useUberFramework: true, frameworks: additionalfxs);
+
+ // Add versions in the exe folders
+ SharedFramework.AddAvailableSharedFxVersions(_builtSharedFxDir, _exeSharedFxBaseDir, "9999.1.0", "9999.5.5");
+ SharedFramework.AddAvailableSharedUberFxVersions(_builtSharedUberFxDir, _exeSharedUberFxBaseDir, "9999.5.5", "7777.0.0");
+
+ // Version: NetCoreApp 9999.5.5 (in framework section)
+ // NetCoreApp 9999.1.0 (in frameworks section)
+ // UberFramework 7777.0.0
+ // Exe: NetCoreApp 9999.1.0 rollForwardOnNoCandidateFx:1 applyPatches:false
+ // NetCoreApp 9999.5.5
+ // UberFramework 7777.0.0
+ // Expected: 9999.5.5
+ // 7777.0.0
+ dotnet.Exec(appDll)
+ .WorkingDirectory(_currentWorkingDir)
+ .EnvironmentVariable("COREHOST_TRACE", "1")
+ .CaptureStdOut()
+ .CaptureStdErr()
+ .Execute()
+ .Should()
+ .Pass()
+ .And
+ .HaveStdErrContaining(Path.Combine(_exeSelectedMessage, "9999.5.5"))
+ .And
+ .HaveStdOutContaining("Framework Version:9999.5.5")
+ .And
+ .HaveStdErrContaining(Path.Combine(_exeFoundUberFxMessage, "7777.0.0"))
+ .And
+ .NotHaveStdErrContaining("Restarting all framework resolution");
+ }
+
+ [Fact]
+ public void Multiple_Fx_References_Can_Roll_Forward_With_Retry()
+ {
+ var fixture = PreviouslyBuiltAndRestoredPortableTestProjectFixture
+ .Copy();
+
+ var dotnet = fixture.BuiltDotnet;
+ var appDll = fixture.TestProject.AppDll;
+
+ string runtimeConfig = Path.Combine(fixture.TestProject.OutputDirectory, "SharedFxLookupPortableApp.runtimeconfig.json");
+
+ var additionalfxs = new JArray();
+ additionalfxs.Add(GetAdditionalFramework("Microsoft.UberFramework", "7777.0.0", null, null));
+ // Specify Uber as additional fx so we find NetCoreApp 9999.1.1 and then need to do a re-try for 9999.5.5
+ SharedFramework.SetRuntimeConfigJson(runtimeConfig, "9999.1.1", null, null, frameworks: additionalfxs);
+
+ // Add versions in the exe folders
+ SharedFramework.AddAvailableSharedFxVersions(_builtSharedFxDir, _exeSharedFxBaseDir, "9999.1.1", "9999.5.5");
+ SharedFramework.AddAvailableSharedUberFxVersions(_builtSharedUberFxDir, _exeSharedUberFxBaseDir, "9999.5.5", "7777.0.0");
+
+ // Version: NetCoreApp 9999.1.1 (in framework section)
+ // UberFramework 7777.0.0 (in frameworks section)
+ // NetCoreApp 9999.5.5 (in uber's config)
+ // Exe: NetCoreApp 9999.1.1
+ // NetCoreApp 9999.5.5
+ // UberFramework 7777.0.0
+ // Expected: 9999.5.5
+ // 7777.0.0
+ dotnet.Exec(appDll)
+ .WorkingDirectory(_currentWorkingDir)
+ .EnvironmentVariable("COREHOST_TRACE", "1")
+ .CaptureStdOut()
+ .CaptureStdErr()
+ .Execute()
+ .Should()
+ .Pass()
+ .And
+ .HaveStdErrContaining(Path.Combine(_exeSelectedMessage, "9999.5.5"))
+ .And
+ .HaveStdOutContaining("Framework Version:9999.5.5")
+ .And
+ .HaveStdErrContaining(Path.Combine(_exeFoundUberFxMessage, "7777.0.0"))
+ .And
+ .HaveStdErrContaining("Restarting all framework resolution because the previously resolved framework 'Microsoft.NETCore.App', version '9999.1.1' must be re-resolved with the new version '9999.5.5'");
+ }
+
+ [Fact]
+ public void Multiple_Fx_References_Cant_Roll_Forward_Because_Disabled_Through_CommandLine()
+ {
+ var fixture = PreviouslyBuiltAndRestoredPortableTestProjectFixture
+ .Copy();
+
+ var dotnet = fixture.BuiltDotnet;
+ var appDll = fixture.TestProject.AppDll;
+
+ string runtimeConfig = Path.Combine(fixture.TestProject.OutputDirectory, "SharedFxLookupPortableApp.runtimeconfig.json");
+
+ var additionalfxs = new JArray();
+ additionalfxs.Add(GetAdditionalFramework("Microsoft.NETCore.App", "9999.1.1", applyPatches: false, rollForwardOnNoCandidateFx: 1));
+ SharedFramework.SetRuntimeConfigJson(runtimeConfig, "7777.0.0", null, useUberFramework: true, frameworks: additionalfxs);
+
+ // Add versions in the exe folders
+ SharedFramework.AddAvailableSharedFxVersions(_builtSharedFxDir, _exeSharedFxBaseDir, "9999.1.0", "9999.5.5");
+ SharedFramework.AddAvailableSharedUberFxVersions(_builtSharedUberFxDir, _exeSharedUberFxBaseDir, "9999.5.5", "7777.0.0");
+
+ // Version: NetCoreApp 9999.5.5 (in framework section)
+ // NetCoreApp 9999.1.0 (in frameworks section)
+ // UberFramework 7777.0.0
+ // Exe: NetCoreApp 9999.1.0 rollForwardOnNoCandidateFx:1 applyPatches:false
+ // NetCoreApp 9999.5.5
+ // UberFramework 7777.0.0
+ // --roll-forward-on-no-candidate-fx=0 should override config settings
+ // Expected: 9999.5.5
+ // 7777.0.0
+
+ dotnet.Exec(
+ "exec",
+ "--roll-forward-on-no-candidate-fx", "0",
+ appDll)
+ .WorkingDirectory(_currentWorkingDir)
+ .EnvironmentVariable("COREHOST_TRACE", "1")
+ .CaptureStdOut()
+ .CaptureStdErr()
+ .Execute(fExpectedToFail: true)
+ .Should()
+ .Fail()
+ .And
+ .HaveStdErrContaining("cannot roll-forward to the previously referenced version '9999.5.5");
+ }
+
+ [Fact]
+ public void Multiple_SharedFxLookup_NetCoreApp_MinorRollForward_Wins_Over_UberFx()
+ {
+ var fixture = PreviouslyBuiltAndRestoredPortableTestProjectFixture
+ .Copy();
+
+ var dotnet = fixture.BuiltDotnet;
+ var appDll = fixture.TestProject.AppDll;
+
+ string runtimeConfig = Path.Combine(fixture.TestProject.OutputDirectory, "SharedFxLookupPortableApp.runtimeconfig.json");
+ SharedFramework.SetRuntimeConfigJson(runtimeConfig, "7777.0.0", null, useUberFramework: true);
+
+ // Modify the Uber values
+ SharedFramework.CreateUberFrameworkArtifacts(_builtSharedFxDir, _builtSharedUberFxDir, "0.0.0.1", "0.0.0.2");
+
+ // Add versions in the exe folders
+ SharedFramework.AddAvailableSharedFxVersions(_builtSharedFxDir, _exeSharedFxBaseDir, "9999.1.0");
+ SharedFramework.AddAvailableSharedUberFxVersions(_builtSharedUberFxDir, _exeSharedUberFxBaseDir, "9999.0.0", "7777.0.0");
+
+ string uberFile = Path.Combine(_exeSharedUberFxBaseDir, "7777.0.0", "System.Collections.Immutable.dll");
+ string netCoreAppFile = Path.Combine(_exeSharedFxBaseDir, "9999.1.0", "System.Collections.Immutable.dll");
+ // The System.Collections.Immutable.dll is located in the UberFramework and NetCoreApp
+ // Version: NetCoreApp 9999.0.0
+ // UberFramework 7777.0.0
+ // 'Roll forward on no candidate fx' enabled through config
+ // Exe: NetCoreApp 9999.1.0
+ // UberFramework 7777.0.0
+ // Expected: 9999.1.0
+ // 7777.0.0
+ dotnet.Exec(appDll)
+ .WorkingDirectory(_currentWorkingDir)
+ .EnvironmentVariable("COREHOST_TRACE", "1")
+ .CaptureStdOut()
+ .CaptureStdErr()
+ .Execute()
+ .Should()
+ .Pass()
+ .And
+ .HaveStdErrContaining($"Replacing deps entry [{uberFile}, AssemblyVersion:0.0.0.1, FileVersion:0.0.0.2] with [{netCoreAppFile}");
+ }
+
+ [Fact]
+ public void Multiple_SharedFxLookup_Uber_Wins_Over_NetCoreApp_On_PatchRollForward()
+ {
+ var fixture = PreviouslyBuiltAndRestoredPortableTestProjectFixture
+ .Copy();
+
+ var dotnet = fixture.BuiltDotnet;
+ var appDll = fixture.TestProject.AppDll;
+
+ string runtimeConfig = Path.Combine(fixture.TestProject.OutputDirectory, "SharedFxLookupPortableApp.runtimeconfig.json");
+ SharedFramework.SetRuntimeConfigJson(runtimeConfig, "7777.0.0", null, useUberFramework: true);
+
+ // Add versions in the exe folders
+ SharedFramework.AddAvailableSharedFxVersions(_builtSharedFxDir, _exeSharedFxBaseDir, "9999.0.1");
+ SharedFramework.AddAvailableSharedUberFxVersions(_builtSharedUberFxDir, _exeSharedUberFxBaseDir, "9999.0.0", "7777.0.0");
+
+ // The System.Collections.Immutable.dll is located in the UberFramework and NetCoreApp
+ // Version: NetCoreApp 9999.0.0
+ // UberFramework 7777.0.0
+ // 'Roll forward on no candidate fx' enabled through config
+ // Exe: NetCoreApp 9999.0.1
+ // UberFramework 7777.0.0
+ // Expected: 9999.0.1
+ // 7777.0.0
+ dotnet.Exec(appDll)
+ .WorkingDirectory(_currentWorkingDir)
+ .EnvironmentVariable("COREHOST_TRACE", "1")
+ .CaptureStdOut()
+ .CaptureStdErr()
+ .Execute()
+ .Should()
+ .Pass()
+ .And
+ .HaveStdErrContaining(Path.Combine("7777.0.0", "System.Collections.Immutable.dll"))
+ .And
+ .NotHaveStdErrContaining(Path.Combine("9999.1.0", "System.Collections.Immutable.dll"));
+ }
+
+ static private JObject GetAdditionalFramework(string fxName, string fxVersion, bool? applyPatches, int? rollForwardOnNoCandidateFx)
+ {
+ var jobject = new JObject(new JProperty("name", fxName));
+
+ if (fxVersion != null)
+ {
+ jobject.Add(new JProperty("version", fxVersion));
+ }
+
+ if (applyPatches.HasValue)
+ {
+ jobject.Add(new JProperty("applyPatches", applyPatches.Value));
+ }
+
+ if (rollForwardOnNoCandidateFx.HasValue)
+ {
+ jobject.Add(new JProperty("rollForwardOnNoCandidateFx", rollForwardOnNoCandidateFx));
+ }
+
+ return jobject;
+ }
+
+ static private string CreateAStore(TestProjectFixture testProjectFixture)
+ {
+ var storeoutputDirectory = Path.Combine(testProjectFixture.TestProject.ProjectDirectory, "store");
+ if (!Directory.Exists(storeoutputDirectory))
+ {
+ Directory.CreateDirectory(storeoutputDirectory);
+ }
+
+ testProjectFixture.StoreProject(outputDirectory: storeoutputDirectory);
+
+ return storeoutputDirectory;
+ }
+ }
+}