Pin and prove lazy provider asset delivery
This commit is contained in:
parent
3da246aba8
commit
6e19396f7f
5 changed files with 52 additions and 37 deletions
|
|
@ -305,9 +305,8 @@ namespace GameCult.EveUnity.GenericClient.PlayModeTests
|
|||
Assert.That(provider.Selection.VerseId, Is.Not.Empty);
|
||||
Assert.That(provider.Selection.ProviderId, Is.Not.Empty);
|
||||
Assert.That(provider.Selection.SurfaceId, Is.Not.Empty);
|
||||
Assert.That(provider.CurrentAssetBodyTransportKind,
|
||||
Is.EqualTo(CultMeshBodyTransportKind.SharedFileMapping),
|
||||
"The generic client did not negotiate its verified provider bundle as a mapped body.");
|
||||
Assert.That(provider.CurrentAssetBodyTransportKind, Is.Null,
|
||||
"Publishing the provider catalog eagerly transferred an asset bundle.");
|
||||
host = root.AddComponent<EveUnityPlayableWorldClientHost>();
|
||||
host.Configure(
|
||||
root.transform,
|
||||
|
|
@ -376,6 +375,9 @@ namespace GameCult.EveUnity.GenericClient.PlayModeTests
|
|||
"provider-asset-ref"));
|
||||
Assert.That(playerPrefab, Is.Not.Null,
|
||||
$"Provider asset catalog did not resolve player AssetRef '{playerFact.AssetRef}'.");
|
||||
Assert.That(provider.CurrentAssetBodyTransportKind,
|
||||
Is.EqualTo(CultMeshBodyTransportKind.SharedFileMapping),
|
||||
"The first requested provider bundle was not negotiated as a mapped body.");
|
||||
var marker = FindMarker(root, playerId);
|
||||
Assert.That(
|
||||
marker.GetComponentsInChildren<Transform>(includeInactive: true).Length,
|
||||
|
|
|
|||
|
|
@ -6,10 +6,10 @@
|
|||
"com.unity.modules.physics": "1.0.0",
|
||||
"com.unity.modules.uielements": "1.0.0",
|
||||
"com.unity.render-pipelines.universal": "17.4.0",
|
||||
"org.gamecult.cultlib": "https://github.com/GameCult/CultLib.git?path=/unity/org.gamecult.cultlib#cultlib-unity-v1.0.34",
|
||||
"org.gamecult.cultlib": "https://github.com/GameCult/CultLib.git?path=/unity/org.gamecult.cultlib#cultlib-unity-v1.0.35",
|
||||
"org.gamecult.eve.plugin-fields": "https://github.com/GameCult/EvePlugins.git?path=/plugins/eve-plugin-fields/unity/org.gamecult.eve.plugin-fields#eve-plugin-fields-unity-v0.2.3",
|
||||
"org.gamecult.eve.surface": "https://github.com/GameCult/EveUnity.git?path=/packages/org.gamecult.eve.surface#eveunity-surface-v0.2.4",
|
||||
"org.gamecult.eve.unity-scene": "https://github.com/GameCult/EveUnity.git?path=/packages/org.gamecult.eve.unity-scene#eveunity-scene-v0.3.94",
|
||||
"org.gamecult.eve.unity-scene": "https://github.com/GameCult/EveUnity.git?path=/packages/org.gamecult.eve.unity-scene#eveunity-scene-v0.3.96",
|
||||
"org.gamecult.eve.unity-uitoolkit": "https://github.com/GameCult/EveUnity.git?path=/packages/org.gamecult.eve.unity-uitoolkit#eveunity-uitoolkit-v0.1.1"
|
||||
},
|
||||
"testables": [
|
||||
|
|
|
|||
|
|
@ -119,11 +119,11 @@
|
|||
}
|
||||
},
|
||||
"org.gamecult.cultlib": {
|
||||
"version": "https://github.com/GameCult/CultLib.git?path=/unity/org.gamecult.cultlib#cultlib-unity-v1.0.34",
|
||||
"version": "https://github.com/GameCult/CultLib.git?path=/unity/org.gamecult.cultlib#cultlib-unity-v1.0.35",
|
||||
"depth": 0,
|
||||
"source": "git",
|
||||
"dependencies": {},
|
||||
"hash": "c148d891c1d8713285ae15b2f17b59c106fb9426"
|
||||
"hash": "36a822d91416d7fecd4f3e67259186e45cf7cdaa"
|
||||
},
|
||||
"org.gamecult.eve.plugin-fields": {
|
||||
"version": "https://github.com/GameCult/EvePlugins.git?path=/plugins/eve-plugin-fields/unity/org.gamecult.eve.plugin-fields#eve-plugin-fields-unity-v0.2.3",
|
||||
|
|
@ -144,18 +144,18 @@
|
|||
"hash": "e08fa08335f99e9edddeb706912eecfad07cb281"
|
||||
},
|
||||
"org.gamecult.eve.unity-scene": {
|
||||
"version": "https://github.com/GameCult/EveUnity.git?path=/packages/org.gamecult.eve.unity-scene#eveunity-scene-v0.3.94",
|
||||
"version": "https://github.com/GameCult/EveUnity.git?path=/packages/org.gamecult.eve.unity-scene#eveunity-scene-v0.3.96",
|
||||
"depth": 0,
|
||||
"source": "git",
|
||||
"dependencies": {
|
||||
"org.gamecult.cultlib": "1.0.34",
|
||||
"org.gamecult.cultlib": "1.0.35",
|
||||
"org.gamecult.eve.plugin-fields": "0.2.3",
|
||||
"org.gamecult.eve.surface": "0.2.4",
|
||||
"com.unity.mathematics": "1.3.2",
|
||||
"com.unity.render-pipelines.universal": "17.4.0",
|
||||
"com.unity.modules.particlesystem": "1.0.0"
|
||||
},
|
||||
"hash": "0463ddff4e39c9cca14e632b7e46b6b0081c67cc"
|
||||
"hash": "3da246aba8ee24af1c2528fe1c81b41a51a41c64"
|
||||
},
|
||||
"org.gamecult.eve.unity-uitoolkit": {
|
||||
"version": "https://github.com/GameCult/EveUnity.git?path=/packages/org.gamecult.eve.unity-uitoolkit#eveunity-uitoolkit-v0.1.1",
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ using UnityEngine.Rendering;
|
|||
using UnityEngine.Rendering.Universal;
|
||||
using UnityEngine.TestTools;
|
||||
using UnityEngine.UIElements;
|
||||
using Stopwatch = System.Diagnostics.Stopwatch;
|
||||
|
||||
namespace GameCult.EveUnity.GenericClient.PlayModeTests
|
||||
{
|
||||
|
|
@ -304,9 +305,8 @@ namespace GameCult.EveUnity.GenericClient.PlayModeTests
|
|||
Assert.That(provider.Selection.VerseId, Is.Not.Empty);
|
||||
Assert.That(provider.Selection.ProviderId, Is.Not.Empty);
|
||||
Assert.That(provider.Selection.SurfaceId, Is.Not.Empty);
|
||||
Assert.That(provider.CurrentAssetBodyTransportKind,
|
||||
Is.EqualTo(CultMeshBodyTransportKind.SharedFileMapping),
|
||||
"The generic client did not negotiate its verified provider bundle as a mapped body.");
|
||||
Assert.That(provider.CurrentAssetBodyTransportKind, Is.Null,
|
||||
"Publishing the provider catalog eagerly transferred an asset bundle.");
|
||||
host = root.AddComponent<EveUnityPlayableWorldClientHost>();
|
||||
host.Configure(
|
||||
root.transform,
|
||||
|
|
@ -375,6 +375,9 @@ namespace GameCult.EveUnity.GenericClient.PlayModeTests
|
|||
"provider-asset-ref"));
|
||||
Assert.That(playerPrefab, Is.Not.Null,
|
||||
$"Provider asset catalog did not resolve player AssetRef '{playerFact.AssetRef}'.");
|
||||
Assert.That(provider.CurrentAssetBodyTransportKind,
|
||||
Is.EqualTo(CultMeshBodyTransportKind.SharedFileMapping),
|
||||
"The first requested provider bundle was not negotiated as a mapped body.");
|
||||
var marker = FindMarker(root, playerId);
|
||||
Assert.That(
|
||||
marker.GetComponentsInChildren<Transform>(includeInactive: true).Length,
|
||||
|
|
@ -912,6 +915,7 @@ namespace GameCult.EveUnity.GenericClient.PlayModeTests
|
|||
Assert.That(captureFieldVolume, Is.Not.Null,
|
||||
"The generic client did not install its Fields volume lowerer before temporal settling.");
|
||||
const int temporalSettlingFrames = 128;
|
||||
var temporalSettlingElapsed = Stopwatch.StartNew();
|
||||
var initialCompositeCount = captureFieldVolume.CompositeCount;
|
||||
var temporalSettlingDeadline = Time.realtimeSinceStartup + 20f;
|
||||
while (captureFieldVolume.CompositeCount - initialCompositeCount < temporalSettlingFrames &&
|
||||
|
|
@ -923,6 +927,8 @@ namespace GameCult.EveUnity.GenericClient.PlayModeTests
|
|||
Assert.That(captureFieldVolume.CompositeCount - initialCompositeCount,
|
||||
Is.GreaterThanOrEqualTo(temporalSettlingFrames),
|
||||
"The pilot capture ran before the advertised temporal reconstruction had settled.");
|
||||
Debug.Log($"EveUnity witness phase temporal-settling-128-frames took {temporalSettlingElapsed.Elapsed.TotalMilliseconds:0.###}ms.");
|
||||
var pilotCaptureElapsed = Stopwatch.StartNew();
|
||||
yield return null;
|
||||
RenderTexture.active = target;
|
||||
pixels = new Texture2D(captureWidth, captureHeight, TextureFormat.RGB24, false);
|
||||
|
|
@ -950,7 +956,9 @@ namespace GameCult.EveUnity.GenericClient.PlayModeTests
|
|||
"The provider-authored player prefab has no renderer on its advertised map channel.");
|
||||
Assert.That(playerMapRendererFacts.Sum(fact => fact.renderedPixelCount), Is.Zero,
|
||||
"A provider-prefab map-channel renderer leaked into the pilot camera.");
|
||||
Debug.Log($"EveUnity witness phase pilot-capture-and-renderer-probes took {pilotCaptureElapsed.Elapsed.TotalMilliseconds:0.###}ms.");
|
||||
|
||||
var mapCaptureElapsed = Stopwatch.StartNew();
|
||||
mapRenderers = mapRenderers.Where(renderer => renderer != null).ToList();
|
||||
Assert.That(mapRenderers, Is.Not.Empty,
|
||||
"All advertised map-channel renderers were destroyed before map capture.");
|
||||
|
|
@ -981,6 +989,7 @@ namespace GameCult.EveUnity.GenericClient.PlayModeTests
|
|||
Directory.CreateDirectory(Path.GetDirectoryName(Path.GetFullPath(mapCapturePath)));
|
||||
File.WriteAllBytes(mapCapturePath, pixels.EncodeToPNG());
|
||||
Assert.That(new FileInfo(mapCapturePath).Length, Is.GreaterThan(1024));
|
||||
Debug.Log($"EveUnity witness phase map-capture took {mapCaptureElapsed.Elapsed.TotalMilliseconds:0.###}ms.");
|
||||
var tractorReleaseVersion = runtime.ActiveVersion;
|
||||
var tractorRelease = host.SubmitAdvertisedActionValueIntent(
|
||||
playerId,
|
||||
|
|
|
|||
|
|
@ -17,10 +17,10 @@ param(
|
|||
)
|
||||
|
||||
$ErrorActionPreference = "Stop"
|
||||
$expectedEveUnityCommit = "0463ddff4e39c9cca14e632b7e46b6b0081c67cc"
|
||||
$expectedEveUnityCommit = "3da246aba8ee24af1c2528fe1c81b41a51a41c64"
|
||||
$expectedEveFieldsCommit = "c5a4a75c1b727499b16c2dae1895f29e2a9f72f0"
|
||||
$expectedEveUnityUiToolkitCommit = "4d0cbe0185bdc4fc65eb63503a7c5cb578539669"
|
||||
$expectedCultLibCommit = "c148d891c1d8713285ae15b2f17b59c106fb9426"
|
||||
$expectedCultLibCommit = "36a822d91416d7fecd4f3e67259186e45cf7cdaa"
|
||||
$repoRoot = Split-Path -Parent $PSScriptRoot
|
||||
$projectRoot = $ClientProject
|
||||
$outputRoot = if ([IO.Path]::IsPathRooted($OutputDirectory)) { $OutputDirectory } else { Join-Path $repoRoot $OutputDirectory }
|
||||
|
|
@ -42,7 +42,7 @@ $providerReadyPath = Join-Path $outputRoot "provider-ready.txt"
|
|||
$witnessPath = Join-Path $outputRoot "runtime-witness.json"
|
||||
$replicaPath = Join-Path $outputRoot "eve-unity-replica.cc"
|
||||
$statePath = Join-Path $outputRoot "aetheria-witness-state.cc"
|
||||
$providerBundlePath = Join-Path $AetheriaRoot "Build\EveAssets\StandaloneWindows64\aetheria-world"
|
||||
$providerBundleDirectory = Join-Path $AetheriaRoot "Build\EveAssets\StandaloneWindows64"
|
||||
$daemonProject = Join-Path $AetheriaRoot "Aetheria.State.Daemon\Aetheria.State.Daemon.csproj"
|
||||
$importProject = Join-Path $AetheriaRoot "Aetheria.State.Import\Aetheria.State.Import.csproj"
|
||||
|
||||
|
|
@ -144,32 +144,36 @@ if ($PrimeWarmCacheFromProviderBundle) {
|
|||
if ($CacheState -ne "warm") {
|
||||
throw "Local provider-bundle priming is only valid for an explicitly warm witness."
|
||||
}
|
||||
if (-not (Test-Path -LiteralPath $providerBundlePath)) {
|
||||
throw "Provider-owned Aetheria bundle is missing: $providerBundlePath"
|
||||
}
|
||||
$providerBundlePaths = @(Get-ChildItem -LiteralPath $providerBundleDirectory -Filter "aetheria-*" -File -ErrorAction SilentlyContinue |
|
||||
Where-Object { $_.Extension -ne ".manifest" } | Select-Object -ExpandProperty FullName)
|
||||
if ($providerBundlePaths.Count -eq 0) { throw "Provider-owned Aetheria bundles are missing: $providerBundleDirectory" }
|
||||
New-Item -ItemType Directory -Force -Path $assetCachePath | Out-Null
|
||||
$primeHash = (Get-FileHash -LiteralPath $providerBundlePath -Algorithm SHA256).Hash.ToLowerInvariant()
|
||||
$primeTarget = Join-Path $assetCachePath "$primeHash.body"
|
||||
if (-not (Test-Path -LiteralPath $primeTarget)) {
|
||||
$primePartial = Join-Path $assetCachePath "$primeHash.partial.local-prime"
|
||||
Copy-Item -LiteralPath $providerBundlePath -Destination $primePartial -Force
|
||||
if ((Get-FileHash -LiteralPath $primePartial -Algorithm SHA256).Hash.ToLowerInvariant() -ne $primeHash) {
|
||||
Remove-Item -LiteralPath $primePartial -Force -ErrorAction SilentlyContinue
|
||||
throw "Locally primed provider bundle failed its content-hash check."
|
||||
foreach ($providerBundlePath in $providerBundlePaths) {
|
||||
$primeHash = (Get-FileHash -LiteralPath $providerBundlePath -Algorithm SHA256).Hash.ToLowerInvariant()
|
||||
$primeTarget = Join-Path $assetCachePath "$primeHash.body"
|
||||
if (-not (Test-Path -LiteralPath $primeTarget)) {
|
||||
$primePartial = Join-Path $assetCachePath "$primeHash.partial.local-prime"
|
||||
Copy-Item -LiteralPath $providerBundlePath -Destination $primePartial -Force
|
||||
if ((Get-FileHash -LiteralPath $primePartial -Algorithm SHA256).Hash.ToLowerInvariant() -ne $primeHash) {
|
||||
Remove-Item -LiteralPath $primePartial -Force -ErrorAction SilentlyContinue
|
||||
throw "Locally primed provider bundle failed its content-hash check."
|
||||
}
|
||||
Move-Item -LiteralPath $primePartial -Destination $primeTarget -Force
|
||||
}
|
||||
Move-Item -LiteralPath $primePartial -Destination $primeTarget -Force
|
||||
}
|
||||
Write-Host "Warm cache primed locally from the provider bundle; this is not CDN-transfer evidence: $primeTarget"
|
||||
Write-Host "Warm cache primed locally from $($providerBundlePaths.Count) provider bundles; this is not CDN-transfer evidence: $assetCachePath"
|
||||
}
|
||||
if ($CacheState -eq "warm") {
|
||||
if (-not (Test-Path -LiteralPath $providerBundlePath)) {
|
||||
throw "Provider-owned Aetheria bundle is missing: $providerBundlePath"
|
||||
}
|
||||
$currentBundleHash = (Get-FileHash -LiteralPath $providerBundlePath -Algorithm SHA256).Hash.ToLowerInvariant()
|
||||
$currentWarmBody = Get-ChildItem -LiteralPath $assetCachePath -Filter "$currentBundleHash.body" -File -Recurse -ErrorAction SilentlyContinue |
|
||||
Select-Object -First 1
|
||||
if ($null -eq $currentWarmBody) {
|
||||
throw "Warm witness cache does not contain the current provider bundle. expected=$currentBundleHash cache=$assetCachePath"
|
||||
$providerBundlePaths = @(Get-ChildItem -LiteralPath $providerBundleDirectory -Filter "aetheria-*" -File -ErrorAction SilentlyContinue |
|
||||
Where-Object { $_.Extension -ne ".manifest" } | Select-Object -ExpandProperty FullName)
|
||||
if ($providerBundlePaths.Count -eq 0) { throw "Provider-owned Aetheria bundles are missing: $providerBundleDirectory" }
|
||||
foreach ($providerBundlePath in $providerBundlePaths) {
|
||||
$currentBundleHash = (Get-FileHash -LiteralPath $providerBundlePath -Algorithm SHA256).Hash.ToLowerInvariant()
|
||||
$currentWarmBody = Get-ChildItem -LiteralPath $assetCachePath -Filter "$currentBundleHash.body" -File -Recurse -ErrorAction SilentlyContinue |
|
||||
Select-Object -First 1
|
||||
if ($null -eq $currentWarmBody) {
|
||||
throw "Warm witness cache does not contain current provider bundle '$providerBundlePath'. expected=$currentBundleHash cache=$assetCachePath"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Reference in a new issue