Files
TeslaSuite/Console/tests/TeslaConsole.DiffTests
CydandClaude Opus 5 2a5a387381 Console: remember Enable Custom Bitmaps, ship the art; bump suite to 4.11.4.5
Settings -> Enable Custom Bitmaps was a static bool with no backing store:
it defaulted to off on every launch, so an operator had to re-tick it each
session and any custom plasma art was silently ignored until they did. New
ConsoleSettings persists machine-level menu toggles as XML in
%ProgramData%\Tesla Console\console.settings, alongside RPDefaults.rpd /
BTDefaults.btd / local.siteconfig. It is loaded once from Main and never
from a static initializer: the differential suite drives PlasmaBitmaps
directly and must keep seeing the original defaults rather than whatever
this machine has saved. A missing file is the first-run case; a corrupt one
is ignored and rewritten by the next toggle, because losing a menu setting
must never stop the console starting.

Custom art is now version-controlled and rolls with the release. New
Console\Plasma Images\ is copied into the package, and the lookup searches
%ProgramData%\Tesla Console\Plasma Images first and the exe-relative folder
second, so a release can never clobber a site's own name bitmaps.
install.bat creates the data-dir folder before the icacls grant so an
unelevated operator can write it. Ships with three 128x32 name bitmaps
(Deadmeat, Muerte, Phrogg); Muerte arrived as "Muerte_128x32-2.bmp", a name
the lookup can never build, so it is renamed to match its pilot.

Two fixes fell out of making the flag sticky. Path.Combine ran on the raw
participant name outside the try block, so with the option on a pilot named
"A:B" threw ArgumentException straight out of egg generation; names that
cannot be a Windows file name now just render procedurally. And the art was
loaded with Image.FromFile, which keeps the bitmap backed by the file and
locked for its whole lifetime — it is copied out through a stream now, so
art can be swapped between missions without restarting the console.

Verified against the built net40 exe: all three shipped bitmaps resolve by
pilot name, ProgramData wins over the shipped copy, a wrong-size file is
ignored, an illegal-character name does not throw, the file is not left
locked, and the settings round-trip and corrupt-file tolerance both hold.
Diff suite 106/106.

Version bumped 4.11.4.4 -> 4.11.4.5 across Console, Launcher, vPOD, the
install/build banners, the diff-suite version assertion and the README's
latest-release pointer.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-28 13:16:11 -05:00
..

TeslaConsole.DiffTests — differential equivalence suite

Verifies that the reconstructed TeslaConsole.exe (built from the decompiled source in this repo) behaves identically to the original reference binary in original/TeslaConsole.exe.

How it works

The suite loads each assembly into its own child AppDomain (DifferentialFixture) and drives it through a MarshalByRefObject proxy (Invoker). This is why the project targets net48 — AppDomains are a .NET Framework feature. The original is the 4.11.3.37076 baseline; the recovered build is the modernized 4.11.4.x line (same TeslaConsole assembly name, an intentionally newer version). Because the two versions differ, the public-member comparison strips Version= stamps before diffing — it compares type/member names, not assembly versions.

Each child domain is given a probe directory (the recovered build's output, which ships every dependency DLL) so the original — which is distributed without its proprietary dependencies — still resolves its references for metadata inspection.

What is compared

  1. Public API surface (PublicApiSurfaceTests) Every public type and public member (signature-for-signature) exposed by the original must also be exposed by the recovered build. Compiler-generated members and property/event accessor methods are excluded — the README at the repo root notes those legitimately differ between a decompilation and the lost sources.

  2. Recovered-only characterization (CatalogTests, BTGoldenEggTests) Features that were added in the reconstruction have no counterpart in the original exe, so these run against the recovered build only:

    • CatalogTests — the data-driven product catalog reproduces the exact LaunchData the old hardcoded code emitted.
    • BTGoldenEggTests — the new TeslaConsole.BattleTech mission builder is diffed field-by-field against two golden eggs captured from the original consoles (BattleTech/cavern.egg, BattleTech/TESTARN.EGG). The comparison is per-section and order-independent (the pod parses eggs INI-style; the two golden eggs themselves disagree on field order). Font-rendered name-bitmap pixel rows are excluded, but TESTARN's ordinal art — identical to the RP-inherited rows — is compared byte-exactly. Also covers the EggFileMessage wire framing (NUL-delimited ASCII, 1000-byte chunks, byte-exact reassembly), role-block de-duplication, the No Return mode (same scenario=freeforall, different role), and the shipped BattleTech\BTConfig.xml catalog contents.
  3. Behavioral output (BehavioralEquivalenceTests) The same deterministic, dependency-free methods are invoked in both assemblies over a battery of inputs and the results must match byte-for-byte:

    • RPStrings.GetTimeString (mm:ss formatting + 0.5 s rounding)
    • HostTypeHelper.Parse(...).ToString() (incl. invalid-input exceptions)
    • PlasmaBitmaps.ConvertBitmap (1-bpp packing of a known pixel pattern)
    • PlasmaBitmaps.GenerateString (full GDI text → 1-bpp plasma pipeline)
    • RPMap / RPVehicle XML parsing
    • SiteManagement well-known application GUID constants
    • Tuple.Create<,> generic factory

    A negative-control test (Harness_Distinguishes_Different_Outputs) proves the harness can actually see a difference, so a green run is never vacuous.

The project also carries two byte-compatibility guards — not original-vs-recovered comparisons, but checks that the modernized protocol/crypto stays compatible with the original binaries:

  • PodRpcProtocolTests — round-trips the framed-JSON RPC (Contract/PodRpcProtocol.cs) in-process: every request/response shape encodes and decodes back to the same values.
  • SecureConfigCompatTests — asserts the source-built OFBCryptoStream produces byte-identical ciphertext to the original TeslaSecureConfiguration.dll, so the pod provisioning handshake stays wire-compatible.

Running

dotnet test tests/TeslaConsole.DiffTests/TeslaConsole.DiffTests.csproj

A project reference builds the reconstruction first, and the suite always tests the most recently built bin/{Debug,Release}/net40/TeslaConsole.exe (net40 since the XP11 port; the net48 test host loads it fine — both are CLR4, so the whole process runs the net40/Newtonsoft stack that ships).

Scope / limitations

This compares deterministic logic. It deliberately does not drive the WinForms UI, the pod networking, secure-configuration, or hardware-facing code — those require the live console, its pods, and the proprietary services, and are not reproducible in a unit test. The API-surface test still asserts those types exist with matching signatures even though their behavior isn't exercised.