fix: initialize selected runtime for live playout
This commit is contained in:
@@ -179,7 +179,7 @@ public sealed class LegacyIniDatabaseOptionsLoaderTests
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Runtime_DevelopmentLiveUsesOnlyExactLocalAppDataIni()
|
||||
public void Runtime_DevelopmentLiveUsesProtectedLocalAppDataIniWhenNoOperatorResIsSelected()
|
||||
{
|
||||
using var localApplicationData = TemporaryDirectory.Create();
|
||||
var resourceDirectory = Path.Combine(
|
||||
@@ -200,7 +200,8 @@ public sealed class LegacyIniDatabaseOptionsLoaderTests
|
||||
environmentName,
|
||||
"stale-environment.invalid");
|
||||
runtime = DatabaseRuntime.CreateDevelopmentLiveLocalOverride(
|
||||
localApplicationData.Path);
|
||||
localApplicationData.Path,
|
||||
operatorResourceDirectory: null);
|
||||
}
|
||||
finally
|
||||
{
|
||||
@@ -213,6 +214,170 @@ public sealed class LegacyIniDatabaseOptionsLoaderTests
|
||||
Assert.Equal("maria.dev.invalid", runtime.Options.MariaDb.Host);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Runtime_DevelopmentLiveSelectedResIniIsAuthoritativeAndIgnoresEnvironment()
|
||||
{
|
||||
using var localApplicationData = TemporaryDirectory.Create();
|
||||
var protectedResourceDirectory = Path.Combine(
|
||||
localApplicationData.Path,
|
||||
"MBN_STOCK_WEBVIEW",
|
||||
"Res");
|
||||
Directory.CreateDirectory(protectedResourceDirectory);
|
||||
File.WriteAllBytes(
|
||||
Path.Combine(protectedResourceDirectory, "MmoneyCoder.ini"),
|
||||
TemporaryLegacyIni.ValidUtf8Bytes());
|
||||
using var selected = TemporaryLegacyIni.Create(Encoding.UTF8.GetBytes(
|
||||
"""
|
||||
[Oracle]
|
||||
ConnectionName=selected.oracle.invalid:1523/SELECTED
|
||||
ID=selected-oracle-user
|
||||
Pass=selected-oracle-password
|
||||
[Maria]
|
||||
ConnectionName=selected.maria.invalid:3308/selected_stock
|
||||
ID=selected-maria-user
|
||||
Pass=selected-maria-password
|
||||
"""));
|
||||
|
||||
var environmentOverrides = new Dictionary<string, string>
|
||||
{
|
||||
["MBN_STOCK_ORACLE_HOST"] = "stale-environment.invalid",
|
||||
["MBN_STOCK_ORACLE_PORT"] = "not-an-integer",
|
||||
["MBN_STOCK_MARIADB_TLS_MODE"] = "Required"
|
||||
};
|
||||
var originalEnvironment = environmentOverrides.Keys.ToDictionary(
|
||||
static name => name,
|
||||
Environment.GetEnvironmentVariable,
|
||||
StringComparer.Ordinal);
|
||||
DatabaseRuntime runtime;
|
||||
try
|
||||
{
|
||||
foreach (var pair in environmentOverrides)
|
||||
{
|
||||
Environment.SetEnvironmentVariable(pair.Key, pair.Value);
|
||||
}
|
||||
|
||||
runtime = DatabaseRuntime.CreateDevelopmentLiveLocalOverride(
|
||||
localApplicationData.Path,
|
||||
selected.Directory);
|
||||
}
|
||||
finally
|
||||
{
|
||||
foreach (var pair in originalEnvironment)
|
||||
{
|
||||
Environment.SetEnvironmentVariable(pair.Key, pair.Value);
|
||||
}
|
||||
}
|
||||
|
||||
Assert.Equal("selected.oracle.invalid", runtime.Options.Oracle.Host);
|
||||
Assert.Equal(1523, runtime.Options.Oracle.Port);
|
||||
Assert.Equal("SELECTED", runtime.Options.Oracle.Sid);
|
||||
Assert.Equal("selected.maria.invalid", runtime.Options.MariaDb.Host);
|
||||
Assert.Equal(3308, runtime.Options.MariaDb.Port);
|
||||
Assert.Equal("selected_stock", runtime.Options.MariaDb.Database);
|
||||
Assert.Equal(MariaDbTlsMode.Disabled, runtime.Options.MariaDb.TlsMode);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Runtime_DevelopmentLiveReadsSelectedIniOnEveryCreation()
|
||||
{
|
||||
using var selected = TemporaryLegacyIni.Create(Encoding.UTF8.GetBytes(
|
||||
"""
|
||||
[Oracle]
|
||||
ConnectionName=first.oracle.invalid:1521/FIRST
|
||||
ID=oracle-user
|
||||
Pass=oracle-password
|
||||
[Maria]
|
||||
ConnectionName=first.maria.invalid:3306/first_stock
|
||||
ID=maria-user
|
||||
Pass=maria-password
|
||||
"""));
|
||||
|
||||
var first = DatabaseRuntime.CreateDevelopmentLiveLocalOverride(selected.Directory);
|
||||
File.WriteAllBytes(selected.Path, Encoding.UTF8.GetBytes(
|
||||
"""
|
||||
[Oracle]
|
||||
ConnectionName=second.oracle.invalid:1521/SECOND
|
||||
ID=oracle-user
|
||||
Pass=oracle-password
|
||||
[Maria]
|
||||
ConnectionName=second.maria.invalid:3306/second_stock
|
||||
ID=maria-user
|
||||
Pass=maria-password
|
||||
"""));
|
||||
var second = DatabaseRuntime.CreateDevelopmentLiveLocalOverride(selected.Directory);
|
||||
|
||||
Assert.Equal("first.oracle.invalid", first.Options.Oracle.Host);
|
||||
Assert.Equal("first.maria.invalid", first.Options.MariaDb.Host);
|
||||
Assert.Equal("second.oracle.invalid", second.Options.Oracle.Host);
|
||||
Assert.Equal("second.maria.invalid", second.Options.MariaDb.Host);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Runtime_DevelopmentLiveSelectedResDoesNotDependOnLocalAppDataRoot()
|
||||
{
|
||||
using var selected = TemporaryLegacyIni.CreateValidUtf8();
|
||||
|
||||
var runtime = DatabaseRuntime.CreateDevelopmentLiveLocalOverride(
|
||||
localApplicationData: string.Empty,
|
||||
operatorResourceDirectory: selected.Directory);
|
||||
|
||||
Assert.Equal("oracle.dev.invalid", runtime.Options.Oracle.Host);
|
||||
Assert.Equal("maria.dev.invalid", runtime.Options.MariaDb.Host);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Runtime_DevelopmentLiveSelectedResDoesNotFallBackWhenExactIniIsMissing()
|
||||
{
|
||||
using var localApplicationData = TemporaryDirectory.Create();
|
||||
var protectedResourceDirectory = Path.Combine(
|
||||
localApplicationData.Path,
|
||||
"MBN_STOCK_WEBVIEW",
|
||||
"Res");
|
||||
Directory.CreateDirectory(protectedResourceDirectory);
|
||||
File.WriteAllBytes(
|
||||
Path.Combine(protectedResourceDirectory, "MmoneyCoder.ini"),
|
||||
TemporaryLegacyIni.ValidUtf8Bytes());
|
||||
using var selectedResourceDirectory = TemporaryDirectory.Create();
|
||||
File.WriteAllBytes(
|
||||
Path.Combine(selectedResourceDirectory.Path, "MmoneyCoder.ini.bak"),
|
||||
TemporaryLegacyIni.ValidUtf8Bytes());
|
||||
|
||||
Assert.Throws<DatabaseConfigurationException>(
|
||||
() => DatabaseRuntime.CreateDevelopmentLiveLocalOverride(
|
||||
localApplicationData.Path,
|
||||
selectedResourceDirectory.Path));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Runtime_DevelopmentLiveSelectedResDoesNotFallBackWhenIniIsInvalid()
|
||||
{
|
||||
const string secret = "selected-secret-sentinel";
|
||||
using var localApplicationData = TemporaryDirectory.Create();
|
||||
var protectedResourceDirectory = Path.Combine(
|
||||
localApplicationData.Path,
|
||||
"MBN_STOCK_WEBVIEW",
|
||||
"Res");
|
||||
Directory.CreateDirectory(protectedResourceDirectory);
|
||||
File.WriteAllBytes(
|
||||
Path.Combine(protectedResourceDirectory, "MmoneyCoder.ini"),
|
||||
TemporaryLegacyIni.ValidUtf8Bytes());
|
||||
using var selected = TemporaryLegacyIni.Create(Encoding.UTF8.GetBytes(
|
||||
"""
|
||||
[Oracle]
|
||||
ConnectionName=invalid
|
||||
ID=oracle-user
|
||||
Pass=selected-secret-sentinel
|
||||
"""));
|
||||
|
||||
var exception = Assert.Throws<DatabaseConfigurationException>(
|
||||
() => DatabaseRuntime.CreateDevelopmentLiveLocalOverride(
|
||||
localApplicationData.Path,
|
||||
selected.Directory));
|
||||
|
||||
Assert.DoesNotContain(secret, exception.ToString(), StringComparison.Ordinal);
|
||||
Assert.DoesNotContain(selected.Path, exception.ToString(), StringComparison.Ordinal);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Runtime_DevelopmentLiveFailsClosedWhenBothProtectedProfilesAreMissing()
|
||||
{
|
||||
@@ -224,7 +389,8 @@ public sealed class LegacyIniDatabaseOptionsLoaderTests
|
||||
|
||||
Assert.Throws<DatabaseConfigurationException>(
|
||||
() => DatabaseRuntime.CreateDevelopmentLiveLocalOverride(
|
||||
localApplicationData.Path));
|
||||
localApplicationData.Path,
|
||||
operatorResourceDirectory: null));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -260,7 +426,8 @@ public sealed class LegacyIniDatabaseOptionsLoaderTests
|
||||
""");
|
||||
|
||||
var runtime = DatabaseRuntime.CreateDevelopmentLiveLocalOverride(
|
||||
localApplicationData.Path);
|
||||
localApplicationData.Path,
|
||||
operatorResourceDirectory: null);
|
||||
|
||||
Assert.Equal("json.oracle.invalid", runtime.Options.Oracle.Host);
|
||||
Assert.Equal("json.maria.invalid", runtime.Options.MariaDb.Host);
|
||||
@@ -280,7 +447,8 @@ public sealed class LegacyIniDatabaseOptionsLoaderTests
|
||||
|
||||
Assert.Throws<DatabaseConfigurationException>(
|
||||
() => DatabaseRuntime.CreateDevelopmentLiveLocalOverride(
|
||||
localApplicationData.Path));
|
||||
localApplicationData.Path,
|
||||
operatorResourceDirectory: null));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -296,7 +464,8 @@ public sealed class LegacyIniDatabaseOptionsLoaderTests
|
||||
|
||||
Assert.Throws<DatabaseConfigurationException>(
|
||||
() => DatabaseRuntime.CreateDevelopmentLiveLocalOverride(
|
||||
localApplicationData.Path));
|
||||
localApplicationData.Path,
|
||||
operatorResourceDirectory: null));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
||||
@@ -117,7 +117,7 @@ public sealed class LegacyDevelopmentLiveStartupContractTests
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void AppliedDevelopmentLiveUsesSelectedRuntimePathsAndProtectedDatabaseInputs()
|
||||
public void AppliedDevelopmentLiveUsesSelectedRuntimePathsAndSelectedResDatabaseAuthority()
|
||||
{
|
||||
var window = File.ReadAllText(Path.Combine(ParityRoot, "MainWindow.xaml.cs"));
|
||||
var playout = File.ReadAllText(Path.Combine(
|
||||
@@ -142,14 +142,15 @@ public sealed class LegacyDevelopmentLiveStartupContractTests
|
||||
window,
|
||||
StringComparison.Ordinal);
|
||||
Assert.Contains(
|
||||
"_isDevelopmentLiveLaunch ||\n" +
|
||||
"var selectedLegacyDatabaseIni =\n" +
|
||||
" selectedResourceDirectory is null\n" +
|
||||
" ? null",
|
||||
window.ReplaceLineEndings("\n"),
|
||||
StringComparison.Ordinal);
|
||||
Assert.Contains(
|
||||
"DatabaseRuntime.CreateDevelopmentLiveLocalOverride()",
|
||||
window,
|
||||
"? DatabaseRuntime.CreateDevelopmentLiveLocalOverride(\n" +
|
||||
" selectedResourceDirectory)",
|
||||
window.ReplaceLineEndings("\n"),
|
||||
StringComparison.Ordinal);
|
||||
Assert.Contains(
|
||||
"? PlayoutOptionsLoader.LoadDevelopmentLive(",
|
||||
@@ -168,7 +169,7 @@ public sealed class LegacyDevelopmentLiveStartupContractTests
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void DatabaseFailureDoesNotDowngradeOrBlockValidatedLiveEngine()
|
||||
public void InvalidDevelopmentLiveDatabaseConfigurationBlocksEngineAndAutomaticConnect()
|
||||
{
|
||||
var window = File.ReadAllText(Path.Combine(ParityRoot, "MainWindow.xaml.cs"))
|
||||
.ReplaceLineEndings("\n");
|
||||
@@ -177,44 +178,50 @@ public sealed class LegacyDevelopmentLiveStartupContractTests
|
||||
"MainWindow.Playout.cs"))
|
||||
.ReplaceLineEndings("\n");
|
||||
|
||||
var runtimeReset = window.IndexOf(
|
||||
"_databaseRuntime = null;",
|
||||
var databaseFailureCondition = window.IndexOf(
|
||||
"_isDevelopmentLiveLaunch &&\n" +
|
||||
" exception is DatabaseConfigurationException;",
|
||||
StringComparison.Ordinal);
|
||||
var pagePlanReset = window.IndexOf(
|
||||
"fixedPagePlanProvider = null;",
|
||||
runtimeReset,
|
||||
var startupBlock = window.IndexOf(
|
||||
"_developmentLiveStartupBlocked = true;",
|
||||
databaseFailureCondition,
|
||||
StringComparison.Ordinal);
|
||||
var databaseFailureEnd = window.IndexOf(
|
||||
"_industryWorkflow = new LegacyIndustrySelectionWorkflow(",
|
||||
pagePlanReset,
|
||||
var safeMessage = window.IndexOf(
|
||||
"\"Development Live 데이터베이스 설정을 확인할 수 없습니다.\"",
|
||||
startupBlock,
|
||||
StringComparison.Ordinal);
|
||||
var playoutInitialization = window.IndexOf(
|
||||
"InitializePlayoutRuntime();",
|
||||
safeMessage,
|
||||
StringComparison.Ordinal);
|
||||
var automaticConnectGuard = window.IndexOf(
|
||||
"if (!_developmentLiveStartupBlocked)",
|
||||
playoutInitialization,
|
||||
StringComparison.Ordinal);
|
||||
var automaticConnect = window.IndexOf(
|
||||
"await ConnectPlayoutAsync(_lifetimeCancellation.Token);",
|
||||
automaticConnectGuard,
|
||||
StringComparison.Ordinal);
|
||||
var earlyBlock = playout.IndexOf(
|
||||
"if (_developmentLiveStartupBlocked)",
|
||||
StringComparison.Ordinal);
|
||||
var earlyReturn = playout.IndexOf(
|
||||
"return;",
|
||||
earlyBlock,
|
||||
StringComparison.Ordinal);
|
||||
var createEngine = playout.IndexOf(
|
||||
"_playoutEngine = PlayoutEngineFactory.Create(",
|
||||
StringComparison.Ordinal);
|
||||
|
||||
Assert.True(runtimeReset >= 0);
|
||||
Assert.True(pagePlanReset > runtimeReset);
|
||||
Assert.True(databaseFailureEnd > pagePlanReset);
|
||||
Assert.True(playoutInitialization > databaseFailureEnd);
|
||||
Assert.DoesNotContain(
|
||||
"_developmentLiveStartupBlocked = true;",
|
||||
window[runtimeReset..databaseFailureEnd],
|
||||
StringComparison.Ordinal);
|
||||
Assert.DoesNotContain("databaseInitializationSucceeded", window,
|
||||
StringComparison.Ordinal);
|
||||
Assert.Contains(
|
||||
"_isDevelopmentLiveLaunch\n" +
|
||||
" ? PlayoutOptionsLoader.LoadDevelopmentLive(",
|
||||
playout,
|
||||
StringComparison.Ordinal);
|
||||
Assert.Contains(
|
||||
"if (_playoutOptions.Mode != PlayoutMode.Live)",
|
||||
playout,
|
||||
StringComparison.Ordinal);
|
||||
Assert.Contains(
|
||||
"_playoutEngine = PlayoutEngineFactory.Create(",
|
||||
playout,
|
||||
StringComparison.Ordinal);
|
||||
Assert.True(databaseFailureCondition >= 0);
|
||||
Assert.True(startupBlock > databaseFailureCondition);
|
||||
Assert.True(safeMessage > startupBlock);
|
||||
Assert.True(playoutInitialization > safeMessage);
|
||||
Assert.True(automaticConnectGuard > playoutInitialization);
|
||||
Assert.True(automaticConnect > automaticConnectGuard);
|
||||
Assert.True(earlyBlock >= 0);
|
||||
Assert.True(earlyReturn > earlyBlock);
|
||||
Assert.True(createEngine > earlyReturn);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
||||
@@ -70,7 +70,7 @@ public sealed class LegacyFirstRunSetupNativeContractTests
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void BothFolderSelectionsValidateOnlyCanonicalPaths()
|
||||
public void BothFolderSelectionsValidateCanonicalPathsAndTheSelectedDatabaseIni()
|
||||
{
|
||||
var setup = File.ReadAllText(Path.Combine(
|
||||
AppRoot,
|
||||
@@ -84,8 +84,11 @@ public sealed class LegacyFirstRunSetupNativeContractTests
|
||||
"LegacyOperatorSettingsFolderKind.Resource",
|
||||
setup,
|
||||
StringComparison.Ordinal);
|
||||
Assert.DoesNotContain("MmoneyCoder.ini", setup, StringComparison.Ordinal);
|
||||
Assert.DoesNotContain("LegacyIniDatabaseOptionsLoader", setup,
|
||||
Assert.Contains(
|
||||
"Path.Combine(resource, \"MmoneyCoder.ini\")",
|
||||
setup,
|
||||
StringComparison.Ordinal);
|
||||
Assert.Contains("LegacyIniDatabaseOptionsLoader", setup,
|
||||
StringComparison.Ordinal);
|
||||
var clearCuts = setup.IndexOf(
|
||||
"_cutsDirectory = null;",
|
||||
@@ -116,29 +119,78 @@ public sealed class LegacyFirstRunSetupNativeContractTests
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void SetupPersistsOnlyTheSelectedPathsWithoutStartingAChildProcess()
|
||||
public void SetupRunsTheVerifiedInitializerAndVerifiesEveryDurableOutput()
|
||||
{
|
||||
var setup = File.ReadAllText(Path.Combine(
|
||||
AppRoot,
|
||||
"FirstRunSetupWindow.xaml.cs"));
|
||||
|
||||
var saveSettings = RequiredIndex(
|
||||
setup,
|
||||
"var saved = store.Save(current with");
|
||||
var saveBinding = RequiredIndex(
|
||||
setup,
|
||||
"SaveRuntimeBinding(repositoryRoot, runtimeRoot);");
|
||||
Assert.True(saveSettings < saveBinding);
|
||||
Assert.Contains(
|
||||
"var store = new LegacyOperatorSettingsStore();",
|
||||
"await RunVerifiedSetupAsync(",
|
||||
setup,
|
||||
StringComparison.Ordinal);
|
||||
Assert.Contains(
|
||||
"SceneDirectory = cutsDirectory",
|
||||
"new ProcessStartInfo",
|
||||
setup,
|
||||
StringComparison.Ordinal);
|
||||
Assert.Contains(
|
||||
"ResourceDirectory = resourceDirectory",
|
||||
"UseShellExecute = false",
|
||||
setup,
|
||||
StringComparison.Ordinal);
|
||||
Assert.Contains(
|
||||
"CreateNoWindow = true",
|
||||
setup,
|
||||
StringComparison.Ordinal);
|
||||
Assert.Contains(
|
||||
"RedirectStandardOutput = true",
|
||||
setup,
|
||||
StringComparison.Ordinal);
|
||||
Assert.Contains(
|
||||
"RedirectStandardError = true",
|
||||
setup,
|
||||
StringComparison.Ordinal);
|
||||
Assert.Contains(
|
||||
"startInfo.ArgumentList.Add(value)",
|
||||
setup,
|
||||
StringComparison.Ordinal);
|
||||
Assert.Contains(
|
||||
"Initialize-ExistingDevelopmentPc.ps1",
|
||||
setup,
|
||||
StringComparison.Ordinal);
|
||||
Assert.Contains(
|
||||
"AddArgument(\"-SkipDatabaseProfile\")",
|
||||
setup,
|
||||
StringComparison.Ordinal);
|
||||
Assert.Contains(
|
||||
"AddArgument(\"-ConfigureDevelopmentLive\")",
|
||||
setup,
|
||||
StringComparison.Ordinal);
|
||||
Assert.Contains(
|
||||
"AddArgument(\"127.0.0.1\")",
|
||||
setup,
|
||||
StringComparison.Ordinal);
|
||||
Assert.Contains(
|
||||
"AddArgument(\"30001\")",
|
||||
setup,
|
||||
StringComparison.Ordinal);
|
||||
Assert.Contains(
|
||||
"AddArgument(\"-PinRegisteredK3D\")",
|
||||
setup,
|
||||
StringComparison.Ordinal);
|
||||
Assert.Contains(
|
||||
"DrainOutputAsync(process.StandardOutput)",
|
||||
setup,
|
||||
StringComparison.Ordinal);
|
||||
Assert.Contains(
|
||||
"DrainOutputAsync(process.StandardError)",
|
||||
setup,
|
||||
StringComparison.Ordinal);
|
||||
Assert.Contains(
|
||||
"loaded.Settings.SceneDirectory",
|
||||
setup,
|
||||
StringComparison.Ordinal);
|
||||
Assert.Contains(
|
||||
"loaded.Settings.ResourceDirectory",
|
||||
setup,
|
||||
StringComparison.Ordinal);
|
||||
Assert.Contains(
|
||||
@@ -146,18 +198,21 @@ public sealed class LegacyFirstRunSetupNativeContractTests
|
||||
setup,
|
||||
StringComparison.Ordinal);
|
||||
Assert.Contains(
|
||||
"File.Move(temporary, destination, overwrite: true);",
|
||||
"\"k3d-pins.local.json\"",
|
||||
setup,
|
||||
StringComparison.Ordinal);
|
||||
Assert.DoesNotContain("ProcessStartInfo", setup, StringComparison.Ordinal);
|
||||
Assert.DoesNotContain("Process.Start", setup, StringComparison.Ordinal);
|
||||
Assert.DoesNotContain("RunSetupAsync", setup, StringComparison.Ordinal);
|
||||
Assert.DoesNotContain("powershell.exe", setup, StringComparison.OrdinalIgnoreCase);
|
||||
Assert.DoesNotContain("dotnet", setup, StringComparison.OrdinalIgnoreCase);
|
||||
Assert.DoesNotContain("ConfigureDevelopmentLive", setup,
|
||||
Assert.Contains(
|
||||
"\"playout.local.json\"",
|
||||
setup,
|
||||
StringComparison.Ordinal);
|
||||
Assert.Contains(
|
||||
"\"playout.development-live.local.json\"",
|
||||
setup,
|
||||
StringComparison.Ordinal);
|
||||
Assert.DoesNotContain(
|
||||
"Environment.SetEnvironmentVariable",
|
||||
setup,
|
||||
StringComparison.Ordinal);
|
||||
Assert.DoesNotContain("PinRegisteredK3D", setup, StringComparison.Ordinal);
|
||||
Assert.DoesNotContain("DatabaseIniPath", setup, StringComparison.Ordinal);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -180,6 +235,19 @@ public sealed class LegacyFirstRunSetupNativeContractTests
|
||||
StringComparison.Ordinal);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void SolutionDeclaresTheVisualStudioWinUiWorkload()
|
||||
{
|
||||
var configuration = File.ReadAllText(Path.Combine(
|
||||
RepositoryRoot,
|
||||
".vsconfig"));
|
||||
|
||||
Assert.Contains(
|
||||
"\"Microsoft.VisualStudio.Workload.Universal\"",
|
||||
configuration,
|
||||
StringComparison.Ordinal);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void AutomaticK3dPinningIsPersistentAndCannotApproveAChangedDll()
|
||||
{
|
||||
@@ -277,11 +345,4 @@ public sealed class LegacyFirstRunSetupNativeContractTests
|
||||
|
||||
throw new DirectoryNotFoundException("Repository root was not found.");
|
||||
}
|
||||
|
||||
private static int RequiredIndex(string value, string marker)
|
||||
{
|
||||
var index = value.IndexOf(marker, StringComparison.Ordinal);
|
||||
Assert.True(index >= 0, $"Required marker was not found: {marker}");
|
||||
return index;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -97,6 +97,11 @@ public sealed class LegacyOperatorSettingsNativeContractTests
|
||||
Assert.Contains("_appliedOperatorSettings = operatorSettingsLoad.Settings", Window,
|
||||
StringComparison.Ordinal);
|
||||
Assert.Contains("ResolveFromResourceDirectory(", Window, StringComparison.Ordinal);
|
||||
Assert.Contains(
|
||||
"DatabaseRuntime.CreateDevelopmentLiveLocalOverride(\n" +
|
||||
" selectedResourceDirectory)",
|
||||
Window.ReplaceLineEndings("\n"),
|
||||
StringComparison.Ordinal);
|
||||
Assert.Contains("preferLegacyOverride: selectedLegacyDatabaseIni is not null", Window,
|
||||
StringComparison.Ordinal);
|
||||
Assert.Contains(
|
||||
@@ -128,13 +133,18 @@ public sealed class LegacyOperatorSettingsNativeContractTests
|
||||
databaseComposition,
|
||||
"DatabaseRuntime.CreateDefault()",
|
||||
gateA);
|
||||
var selectedDevelopmentLiveIni = RequiredIndex(
|
||||
databaseComposition,
|
||||
"DatabaseRuntime.CreateDevelopmentLiveLocalOverride(",
|
||||
pinnedJson);
|
||||
var legacyIni = RequiredIndex(
|
||||
databaseComposition,
|
||||
"DatabaseRuntime.CreateLegacyExecutableDefault(",
|
||||
pinnedJson);
|
||||
selectedDevelopmentLiveIni);
|
||||
|
||||
Assert.True(gateA < pinnedJson);
|
||||
Assert.True(pinnedJson < legacyIni);
|
||||
Assert.True(pinnedJson < selectedDevelopmentLiveIni);
|
||||
Assert.True(selectedDevelopmentLiveIni < legacyIni);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
||||
@@ -373,7 +373,11 @@ public sealed class LegacyRuntimeAssetDeploymentContractTests
|
||||
"External legacy runtime paths are enabled",
|
||||
StringComparison.Ordinal));
|
||||
Assert.Contains(
|
||||
"Cuts files remain in the selected folder",
|
||||
@"Cuts and the credential-bearing Res\MmoneyCoder.ini remain",
|
||||
fullRuntimeMessage.Attribute("Text")?.Value,
|
||||
StringComparison.Ordinal);
|
||||
Assert.Contains(
|
||||
"in the selected external folders",
|
||||
fullRuntimeMessage.Attribute("Text")?.Value,
|
||||
StringComparison.Ordinal);
|
||||
|
||||
@@ -654,6 +658,10 @@ public sealed class LegacyRuntimeAssetDeploymentContractTests
|
||||
RepositoryRoot,
|
||||
"scripts",
|
||||
"Initialize-ExistingDevelopmentPc.ps1"));
|
||||
var registrationInspector = File.ReadAllText(Path.Combine(
|
||||
RepositoryRoot,
|
||||
"scripts",
|
||||
"Inspect-K3DRegistration.ps1"));
|
||||
|
||||
Assert.Contains("[string] $LegacyRuntimeSourceRoot", initializer,
|
||||
StringComparison.Ordinal);
|
||||
@@ -784,6 +792,34 @@ public sealed class LegacyRuntimeAssetDeploymentContractTests
|
||||
"[string] $classReport.ThreadingModel -cne 'Apartment'",
|
||||
initializer,
|
||||
StringComparison.Ordinal);
|
||||
Assert.Contains(
|
||||
"$standardK3dRoot = 'C:\\K3DAsyncEngine'",
|
||||
initializer,
|
||||
StringComparison.Ordinal);
|
||||
Assert.Contains(
|
||||
"DLL\\x64\\Release\\K3DAsyncEngine.dll",
|
||||
initializer,
|
||||
StringComparison.Ordinal);
|
||||
Assert.Contains(
|
||||
"Bin\\x64\\C#\\Interop.K3DAsyncEngineLib.dll",
|
||||
initializer,
|
||||
StringComparison.Ordinal);
|
||||
Assert.Contains(
|
||||
"-Right $standardK3dNativePath",
|
||||
initializer,
|
||||
StringComparison.Ordinal);
|
||||
Assert.Contains(
|
||||
"$expectedVendorRoot = 'C:\\K3DAsyncEngine'",
|
||||
registrationInspector,
|
||||
StringComparison.Ordinal);
|
||||
Assert.Contains(
|
||||
"-Expected $expectedNativePath",
|
||||
registrationInspector,
|
||||
StringComparison.Ordinal);
|
||||
Assert.Contains(
|
||||
"Assert-Amd64File -Path $interopPath",
|
||||
registrationInspector,
|
||||
StringComparison.Ordinal);
|
||||
Assert.DoesNotContain("Activator.CreateInstance", initializer,
|
||||
StringComparison.Ordinal);
|
||||
Assert.DoesNotContain("Connect(", initializer, StringComparison.Ordinal);
|
||||
|
||||
@@ -78,22 +78,22 @@ public sealed class InstalledK3dInteropMetadataTests
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void RegisteredPaths_MapOnlyExactX64VendorLayout()
|
||||
public void RegisteredPaths_MapOnlyCompanyStandardInstallation()
|
||||
{
|
||||
const string native = @"C:\Vendor\K3DAsyncEngine\DLL\x64\Release\K3DAsyncEngine.dll";
|
||||
const string native = K3dComConstants.StandardNativeBinaryPath;
|
||||
var paths = InstalledK3dInteropMetadata.ResolveRegisteredPaths(ReadySnapshot(native));
|
||||
|
||||
Assert.Equal(Path.GetFullPath(native), paths.NativeBinaryPath);
|
||||
Assert.Equal(
|
||||
Path.GetFullPath(
|
||||
@"C:\Vendor\K3DAsyncEngine\Bin\x64\C#\Interop.K3DAsyncEngineLib.dll"),
|
||||
Path.GetFullPath(K3dComConstants.StandardInteropAssemblyPath),
|
||||
paths.InteropAssemblyPath);
|
||||
Assert.Equal(@"C:\K3DAsyncEngine", K3dComConstants.StandardInstallationRoot);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void RegisteredPaths_RejectDivergentClassBinary()
|
||||
{
|
||||
const string native = @"C:\Vendor\K3DAsyncEngine\DLL\x64\Release\K3DAsyncEngine.dll";
|
||||
const string native = K3dComConstants.StandardNativeBinaryPath;
|
||||
var snapshot = ReadySnapshot(native) with
|
||||
{
|
||||
EventHandler = ReadySnapshot(native).EventHandler with
|
||||
@@ -116,6 +116,16 @@ public sealed class InstalledK3dInteropMetadataTests
|
||||
() => InstalledK3dInteropMetadata.ResolveRegisteredPaths(ReadySnapshot(native)));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void RegisteredPaths_RejectAlternateRootWithMatchingX64Layout()
|
||||
{
|
||||
const string native =
|
||||
@"D:\K3DAsyncEngine\DLL\x64\Release\K3DAsyncEngine.dll";
|
||||
|
||||
Assert.Throws<InstalledK3dInteropMetadataUnavailableException>(
|
||||
() => InstalledK3dInteropMetadata.ResolveRegisteredPaths(ReadySnapshot(native)));
|
||||
}
|
||||
|
||||
private static K3dRegistrySnapshot ReadySnapshot(string nativePath) => new(
|
||||
true,
|
||||
nativePath,
|
||||
|
||||
@@ -5,9 +5,9 @@ namespace MBN_STOCK_WEBVIEW.Playout.Tests;
|
||||
|
||||
public sealed class K3dRegistrationProbeTests
|
||||
{
|
||||
private const string TypeLibraryPath = "C:\\vendor-secret\\typelib-x64.dll";
|
||||
private const string EnginePath = "C:\\vendor-secret\\engine-x64.dll";
|
||||
private const string EventHandlerPath = "C:\\vendor-secret\\events-x64.dll";
|
||||
private const string TypeLibraryPath = K3dComConstants.StandardNativeBinaryPath;
|
||||
private const string EnginePath = K3dComConstants.StandardNativeBinaryPath;
|
||||
private const string EventHandlerPath = K3dComConstants.StandardNativeBinaryPath;
|
||||
|
||||
[Fact]
|
||||
public void Probe_WithReciprocalAmd64MachineRegistration_IsReady()
|
||||
@@ -72,6 +72,32 @@ public sealed class K3dRegistrationProbeTests
|
||||
AssertSafe(report);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Probe_WhenRegistryUsesAlternateRoot_FailsClosed()
|
||||
{
|
||||
const string alternate =
|
||||
@"D:\K3DAsyncEngine\DLL\x64\Release\K3DAsyncEngine.dll";
|
||||
var snapshot = ReadySnapshot() with
|
||||
{
|
||||
Win64TypeLibraryPath = alternate,
|
||||
Engine = ReadySnapshot().Engine with { InprocServerPath = alternate },
|
||||
EventHandler = ReadySnapshot().EventHandler with { InprocServerPath = alternate }
|
||||
};
|
||||
var binaries = new FakeBinaryInspector()
|
||||
.Set(alternate, exists: true, isAmd64: true);
|
||||
var probe = CreateProbe(snapshot, binaries);
|
||||
|
||||
var report = probe.Probe();
|
||||
|
||||
Assert.False(report.IsReady);
|
||||
Assert.True(report.Issues.HasFlag(K3dRegistrationIssue.TypeLibraryPathMismatch));
|
||||
Assert.True(report.Issues.HasFlag(K3dRegistrationIssue.EngineServerPathMismatch));
|
||||
Assert.True(report.Issues.HasFlag(K3dRegistrationIssue.EventHandlerServerPathMismatch));
|
||||
Assert.False(report.IsEngineClassReady);
|
||||
Assert.False(report.IsEventHandlerClassReady);
|
||||
AssertSafe(report);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Probe_WhenCurrentUserOverrideExists_FailsClosedWithoutDetails()
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user