#!/usr/bin/env python3 # SPDX-License-Identifier: GPL-3.0-or-later from __future__ import annotations import argparse,hashlib,sqlite3,sys,tempfile,unittest from pathlib import Path P=argparse.ArgumentParser();P.add_argument("--root",type=Path,required=True);ROOT=P.parse_args().root;sys.path.insert(0,str(ROOT/"tools")) from phase10dh_snapshot_query import Outcome,PHASE,SnapshotBinding,SnapshotError,query_snapshot # noqa:E402 def binding(path):data=path.read_bytes();return SnapshotBinding(PHASE,"PPSA01659",len(data),hashlib.sha256(data).hexdigest()) class Phase10DH(unittest.TestCase): def make(self,rows=(),schema=True): temp=tempfile.TemporaryDirectory();path=Path(temp.name)/"snapshot.db";db=sqlite3.connect(path) if schema: db.execute("CREATE TABLE tbl_appinfo (titleId TEXT, key TEXT, val TEXT)");db.executemany("INSERT INTO tbl_appinfo VALUES (?, 'K', 'V')",[(x,) for x in rows]) else:db.execute("CREATE TABLE other (value TEXT)") db.commit();db.close();return temp,path def test_present_and_no_sidecars(self): temp,path=self.make(["PPSA01659"]) with temp:self.assertEqual(query_snapshot(path,binding(path)),Outcome.PRESENT);self.assertEqual([p.name for p in Path(temp.name).iterdir()],["snapshot.db"]) def test_absent(self): temp,path=self.make(["PPSA01650"]) with temp:self.assertEqual(query_snapshot(path,binding(path)),Outcome.ABSENT) def test_schema_mismatch_unknown(self): temp,path=self.make(schema=False) with temp:self.assertEqual(query_snapshot(path,binding(path)),Outcome.UNKNOWN) def test_duplicate_is_unknown(self): temp,path=self.make(["PPSA01659","PPSA01659"]) with temp:self.assertEqual(query_snapshot(path,binding(path)),Outcome.UNKNOWN) def test_hash_mismatch_rejected(self): temp,path=self.make() with temp: bad=binding(path);bad=SnapshotBinding(bad.phase,bad.title_id,bad.size,"0"*64) with self.assertRaises(SnapshotError):query_snapshot(path,bad) def test_non_database_rejected(self): with tempfile.TemporaryDirectory() as name: path=Path(name)/"x";path.write_bytes(b"not sqlite") with self.assertRaises(SnapshotError):query_snapshot(path,binding(path)) if __name__=="__main__":unittest.main(argv=[__file__])