38 lines
2.1 KiB
Python
38 lines
2.1 KiB
Python
#!/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__])
|