1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
|
"""Unit tests for memory helpers and session recording."""
from __future__ import annotations
import os
import shutil
import tempfile
import unittest
from greeneye.memory import Memory
from greeneye.record import NullRecorder, Recorder, load_events, load_meta
from greeneye.symbols import Symbol, SymbolDB
class FakeClient:
def __init__(self, size=0x1000):
self.data = bytearray(size)
for i in range(size):
self.data[i] = i & 0xFF
def read_mem(self, addr, size, chunk=0):
return bytes(self.data[addr : addr + size])
def write_mem(self, addr, data, chunk=0):
self.data[addr : addr + len(data)] = data
class MemoryTests(unittest.TestCase):
def setUp(self):
self.mem = Memory(FakeClient())
def test_read_write_hexdump(self):
self.assertEqual(self.mem.read(0x10, 4), bytes(range(0x10, 0x14)))
self.mem.write(0x20, b"AB")
self.assertEqual(self.mem.read(0x20, 2), b"AB")
text = self.mem.hexdump(0, 16)
self.assertIn("00000000", text)
self.assertIn("00 01 02", text)
self.assertIn("|", text)
def test_search(self):
self.assertEqual(self.mem.search(0, 0x40, b"\x10\x11"), [0x10])
self.assertEqual(self.mem.search_string(0, 0x40, "\x20\x21"), [0x20])
masked = self.mem.search(0, 0x100, b"\xa0", mask=b"\xf0")
self.assertEqual(masked[0], 0xA0)
self.mem.write(0x30, b"GREEN")
self.assertEqual(self.mem.search_string(0, 0x100, "GREEN"), [0x30])
def test_snapshot_and_diff(self):
before = self.mem.snapshot(0, 32, "before")
self.mem.write(0x10, b"\xff")
after = self.mem.snapshot(0, 32, "after")
diffs = Memory.diff(before, after, base=0)
self.assertEqual(len(diffs), 1)
self.assertEqual(diffs[0].addr, 0x10)
self.assertEqual(diffs[0].new, b"\xff")
text = Memory.render_diff(diffs)
self.assertIn("00000010", text)
def test_hexdump_annotated(self):
db = SymbolDB()
db.add(Symbol(addr=0, name="block", size=0x100, source="test"))
mem = Memory(FakeClient(), symbols=db)
text = mem.hexdump(0, 16, annotate=True)
self.assertIn("block", text)
class RecorderTests(unittest.TestCase):
def setUp(self):
self.dir = tempfile.mkdtemp(prefix="greeneye-test-")
self.recorder = Recorder(self.dir, name="unit", meta={"note": "test"})
self.recorder.event("alpha", value=1)
self.recorder.event("alpha", value=2)
self.recorder.snapshot("regs", 0x80000000, b"\x00" * 16)
def tearDown(self):
shutil.rmtree(self.dir, ignore_errors=True)
def test_events_and_meta(self):
self.recorder.close()
events = load_events(self.dir)
kinds = [e["type"] for e in events]
self.assertEqual(kinds.count("alpha"), 2)
self.assertIn("snapshot_saved", kinds)
self.assertIn("session_end", kinds)
meta = load_meta(self.dir)
self.assertEqual(meta["name"], "unit")
self.assertEqual(meta["note"], "test")
self.assertTrue(os.path.exists(os.path.join(self.dir, "summary.md")))
summary = open(os.path.join(self.dir, "summary.md")).read()
self.assertIn("unit", summary)
def test_null_recorder(self):
null = NullRecorder()
null.event("x")
null.snapshot("y", 0, b"")
null.close()
self.assertIsNone(null.dir)
if __name__ == "__main__":
unittest.main()
|