Files
m2pack-secure/docs/testing.md
2026-04-14 17:25:17 +02:00

4.1 KiB

Testing

Linux headless

m2pack-secure can be validated headless on a Linux VPS without GUI support.

This covers the archive toolchain and release artifacts, not the full Windows client runtime.

Run:

cmake -S . -B build
cmake --build build -j
python3 scripts/headless_e2e.py

Or through npm:

npm run headless:e2e

The headless E2E test covers:

  • keygen
  • build
  • list
  • verify
  • diff
  • export-client-config
  • export-runtime-key in json
  • export-runtime-key in blob
  • extract
  • byte-for-byte comparison of extracted files

What it does not cover

  • Windows SDK compilation of the client
  • Direct3D startup
  • shared-memory launcher bootstrap on Windows
  • in-game runtime behavior of the client loader

Full client runtime

To test the actual client runtime you still need one of these:

  • a Windows build machine
  • a Windows VM
  • or a Linux host with wine plus the required runtime dependencies

The Linux VPS path is now validated as well.

Confirmed runtime path on this host:

  • Linux-hosted Windows build of m2dev-client-src
  • headless execution through xvfb-run + wine
  • runtime key delivery through:
    • M2PACK_MASTER_KEY_HEX
    • M2PACK_KEY_ID

Confirmed .m2p smoke tests:

  • root.m2p only, with root.pck removed
  • root.m2p + patch1.m2p, with both legacy .pck files removed
  • root.m2p + patch1.m2p + season3_eu.m2p, with all three legacy .pck files removed
  • root.m2p + patch1.m2p + patch2.m2p + season3_eu.m2p, with all four legacy .pck files removed
  • root.m2p + patch1.m2p + patch2.m2p + season3_eu.m2p + metin2_patch_snow.m2p + metin2_patch_snow_dungeon.m2p + metin2_patch_etc_costume1.m2p + metin2_patch_pet1.m2p, with all eight matching legacy .pck files removed
  • root.m2p + patch1.m2p + patch2.m2p + season3_eu.m2p + metin2_patch_snow.m2p + metin2_patch_snow_dungeon.m2p + metin2_patch_etc_costume1.m2p + metin2_patch_pet1.m2p + metin2_patch_pet2.m2p + metin2_patch_ramadan_costume.m2p + metin2_patch_flame.m2p + metin2_patch_flame_dungeon.m2p, with all twelve matching legacy .pck files removed
  • the same twelve-pack startup set plus:
    • locale.m2p
    • uiscript.m2p
    • uiloading.m2p
    • ETC.m2p with all sixteen matching legacy .pck files removed
  • the same sixteen-pack startup and UI bootstrap set plus:
    • item.m2p
    • effect.m2p
    • icon.m2p
    • property.m2p with all twenty matching legacy .pck files removed

In every confirmed case the client reached the login bootstrap path under Wine and completed:

  • PackInitialize
  • Python bootstrap through prototype.py
  • app.Create(...)
  • app.SetCamera(...)
  • MainStream.SetLoginPhase()

This is now enough to treat the .m2p path as validated for the current core startup, UI bootstrap, and shared login-adjacent content pack set used by the client runtime.

At this point the login-phase smoke test stops being a strong validator for additional packs such as world, NPC, monster, and late-load gameplay content. Those should be validated with map loads or in-game scenario coverage rather than startup-only checks.

Current non-fatal runtime issues on the VPS:

  • missing Tahoma font mapping in the client runtime
  • headless ALSA / audio decoder warnings

Those do not currently block .m2p loading or the login-phase smoke test.

Example runtime command:

M2PACK_MASTER_KEY_HEX="$(cat /home/mt2.jakubkadlec.dev/.secrets/m2pack-secure/2026-04-14/master.key)" \
M2PACK_KEY_ID=1 \
M2_TIMEOUT=20 \
WINEDEBUG=-all \
/home/mt2.jakubkadlec.dev/metin/repos/m2dev-client-src/scripts/run-wine-headless.sh \
  /home/mt2.jakubkadlec.dev/metin/repos/m2dev-client-src/build-mingw64-lld/bin

Automated smoke runner for selected packs:

python3 scripts/runtime_smoke_wine.py \
  --runtime-root /tmp/m2dev-client-runtime-http \
  --client-repo /home/mt2.jakubkadlec.dev/metin/repos/m2dev-client-src \
  --master-key /home/mt2.jakubkadlec.dev/.secrets/m2pack-secure/2026-04-14/master.key \
  --key-id 1 \
  --pack root \
  --pack patch1 \
  --pack patch2 \
  --pack season3_eu \
  --pack locale \
  --pack uiscript \
  --pack uiloading \
  --pack ETC \
  --json