ksjsb/tests/test_h5_kww.py
2026-07-30 20:25:56 +08:00

93 lines
3.6 KiB
Python

import shutil
import json
import os
import subprocess
import unittest
from core.h5_kww import H5KwwGenerator, PureH5KwwGenerator
@unittest.skipIf(shutil.which("node") is None, "node is required for KWF VM bridge")
class H5KwwTests(unittest.TestCase):
def test_pure_generator_matches_deterministic_bridge_sequence(self):
generator = PureH5KwwGenerator(start_collect_count=1, now_ms=1780000000123)
first = generator.get()
second = generator.get()
self.assertEqual(first.kwfcv1, "2")
self.assertEqual(second.kwfcv1, "3")
self.assertEqual(first.kwfv1, first.kww)
self.assertEqual(second.kwfv1, second.kww)
self.assertEqual(first.kww[:87], second.kww[:87])
self.assertTrue(first.kww.startswith("PnGU+9+Y8008S+nH"))
def test_generator_returns_pngu_kww_and_preserves_counter(self):
generator = H5KwwGenerator(timeout=10)
try:
first = generator.get(
url="https://nebula.kuaishou.com/rest/wd/encourage/unionTask/signIn/resource?sigCatVer=1",
method="GET",
cookie="kpn=NEBULA; kpf=ANDROID_PHONE",
)
second = generator.get(
url="https://nebula.kuaishou.com/rest/n/nebula/activity/earn/overview/tasks",
method="GET",
cookie="kpn=NEBULA; kpf=ANDROID_PHONE",
)
finally:
generator.close()
self.assertEqual(len(first.kww), 174)
self.assertEqual(len(second.kww), 174)
self.assertTrue(first.kww.startswith("PnGU+9+Y8008S+nH"))
self.assertTrue(second.kww.startswith("PnGU+9+Y8008S+nH"))
self.assertEqual(first.kwfv1, first.kww)
self.assertEqual(second.kwfv1, second.kww)
self.assertGreater(int(second.kwfcv1), int(first.kwfcv1))
def test_server_deterministic_trace_dependency_surface(self):
env = os.environ.copy()
env["KS_H5_KWW_SEED"] = "20260712"
env["KS_H5_KWW_NOW"] = "1780000000123"
request = {
"id": 1,
"url": "https://nebula.kuaishou.com/rest/n/nebula/activity/earn/overview/tasks",
"method": "GET",
"cookie": "kpn=NEBULA",
"trace": True,
}
proc = subprocess.run(
["node", "core/h5_kww_server.mjs"],
input=json.dumps(request, separators=(",", ":")) + "\n",
text=True,
capture_output=True,
encoding="utf-8",
timeout=10,
env=env,
check=False,
)
self.assertEqual(proc.returncode, 0, proc.stderr)
data = json.loads(proc.stdout)
event_types = [item["type"] for item in data["trace"]]
self.assertEqual(len(data["kww"]), 174)
self.assertEqual(data["kwfcv1"], "2")
self.assertEqual(event_types.count("random"), 2)
self.assertEqual(event_types.count("String.fromCharCode"), 1)
self.assertEqual(event_types.count("localStorage.getItem"), 1)
self.assertEqual(event_types.count("localStorage.setItem"), 2)
self.assertIn("Object.assign", event_types)
self.assertGreaterEqual(event_types.count("now"), 2)
self.assertGreater(data["traceSummary"]["Math.floor"], event_types.count("Math.floor"))
storage_events = [
item for item in data["trace"]
if item["type"].startswith("localStorage.")
]
self.assertEqual(storage_events[0]["key"], "kwfcv1")
self.assertEqual(storage_events[1]["key"], "kwfcv1")
self.assertEqual(storage_events[2]["key"], "kwfv1")
if __name__ == "__main__":
unittest.main()