test(pipeline): MP1b - live-vs-pak equivalence suite (dat-gated)
PakEquivalenceTests runs MeshExtractor LIVE and bakes the SAME fixture ids to a temp pak, reads it back via PakReader, and deep-compares every field via the Task 3 ObjectMeshDataEquality comparator. Since the bake tool and the live client drive the identical MeshExtractor code (MP1a), this proves the pak ROUND-TRIP preserves what extraction actually produces on real content — the serializer's job, not a re-verification of the extraction algorithm itself (the existing Conformance suite owns that). Fixture set (>= the plan's minimums): 10 GfxObjs (3 known-tricky ids reused from Issue119UpNullGfxObjDumpTests - 0x010002B4, 0x010008A8, 0x010014C3 - plus 7 more from dat order), 3 Setups reused from door/ tower conformance fixtures (0x020019FF, 0x020005D8, 0x020003F2), 5 EnvCells walked from the Holtburg landblock 0xA9B40000's LandBlockInfo.NumCells range (same idiom as StipplingSurfaceEquivalenceTests). Skips cleanly when dats are absent via ContentConformanceDats. ResolveDatDir(), a deliberate small duplicate of ConformanceDats.ResolveDatDir()'s exact pattern (env var then Documents/Asheron's Call fallback) since Content.Tests cannot reference the AcDream.Core.Tests project. ContentTestDatCollectionAdapter is a third small copy of the IDatReaderWriter dat-access glue (alongside AcDream.App's internal original and AcDream.Bake's copy) for the same layering reason (structure rule 6: tests live in the project matching the layer under test). Ran for real against the dats on this machine (not just CI-skip path): 1 test, all fixture ids extracted live with zero failures, baked, read back, and field-for-field identical. Full solution dotnet test: 4106 tests total (43 Content.Tests + 385 Core.Net.Tests + 425 UI.Abstractions.Tests + 722 App.Tests incl. 2 pre-existing skips + 2531 Core.Tests incl. 2 pre-existing skips) — 0 failures.
This commit is contained in:
parent
50f7dd06cf
commit
55f16a0205
4 changed files with 339 additions and 0 deletions
38
tests/AcDream.Content.Tests/ContentConformanceDats.cs
Normal file
38
tests/AcDream.Content.Tests/ContentConformanceDats.cs
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace AcDream.Content.Tests;
|
||||
|
||||
/// <summary>
|
||||
/// Dat-dir resolution for the Content.Tests dat-gated equivalence suite.
|
||||
/// Mirrors the exact pattern used by
|
||||
/// tests/AcDream.Core.Tests/Conformance/ConformanceDats.ResolveDatDir and
|
||||
/// tests/AcDream.Core.Tests/Conformance/DatConcurrencyStressTests
|
||||
/// ("dats absent (CI) -- skip, matching suite convention"). Content.Tests
|
||||
/// cannot reference AcDream.Core.Tests (a test project, not a library), so
|
||||
/// this is a deliberate small duplication of the resolution logic — not a
|
||||
/// new convention.
|
||||
/// </summary>
|
||||
public static class ContentConformanceDats {
|
||||
public static string? ResolveDatDir() {
|
||||
var fromEnv = Environment.GetEnvironmentVariable("ACDREAM_DAT_DIR");
|
||||
if (!string.IsNullOrWhiteSpace(fromEnv) && Directory.Exists(fromEnv)) return fromEnv;
|
||||
|
||||
var def = Path.Combine(
|
||||
Environment.GetFolderPath(Environment.SpecialFolder.UserProfile),
|
||||
"Documents", "Asheron's Call");
|
||||
return Directory.Exists(def) ? def : null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Minimal ILogger writing to Console — surfaces MeshExtractor failures during the equivalence sweep instead of silently swallowing them (NullLogger would hide the exact failure this suite exists to catch).</summary>
|
||||
internal sealed class TestConsoleLogger : ILogger {
|
||||
public IDisposable? BeginScope<TState>(TState state) where TState : notnull => null;
|
||||
public bool IsEnabled(LogLevel logLevel) => logLevel >= LogLevel.Warning;
|
||||
public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception? exception, Func<TState, Exception?, string> formatter) {
|
||||
if (!IsEnabled(logLevel)) return;
|
||||
Console.WriteLine($"[{logLevel}] MeshExtractor: {formatter(state, exception)}");
|
||||
if (exception is not null) Console.WriteLine(exception);
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue