初始化奇妙小屏幕控制器项目
This commit is contained in:
@@ -0,0 +1,106 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import copy
|
||||
import importlib.util
|
||||
from pathlib import Path
|
||||
import sys
|
||||
import unittest
|
||||
|
||||
SOURCE_ROOT = Path(__file__).resolve().parents[1]
|
||||
sys.path.insert(0, str(SOURCE_ROOT / "src"))
|
||||
|
||||
from matrix_image_editor.config import ( # noqa: E402
|
||||
HEADER_BYTES,
|
||||
SLOT_BYTES,
|
||||
ImageConfigError,
|
||||
create_config_file,
|
||||
read_config_file,
|
||||
update_config_file,
|
||||
validate_config,
|
||||
)
|
||||
|
||||
|
||||
def sample_config() -> dict:
|
||||
return {
|
||||
"schema_version": 1,
|
||||
"product": "matrix-screen-controller-walnutpi",
|
||||
"software_version": "1.0.3",
|
||||
"account": {"username": "matrix", "password": "password123"},
|
||||
"wifi": {"ssid": "测试 WiFi", "password": "wifi-pass-123"},
|
||||
"ipv4": {"mode": "dhcp", "address": "", "prefix": 0, "gateway": "", "dns": []},
|
||||
}
|
||||
|
||||
|
||||
class ConfigTests(unittest.TestCase):
|
||||
def test_round_trip_and_update_inactive_slot(self) -> None:
|
||||
original = create_config_file(sample_config())
|
||||
config, generation, slot = read_config_file(original)
|
||||
self.assertEqual((generation, slot), (1, 0))
|
||||
config["wifi"]["ssid"] = "新网络"
|
||||
updated = update_config_file(original, config)
|
||||
verified, generation, slot = read_config_file(updated)
|
||||
self.assertEqual((generation, slot, verified["wifi"]["ssid"]), (2, 1, "新网络"))
|
||||
self.assertEqual(updated[HEADER_BYTES : HEADER_BYTES + SLOT_BYTES], original[HEADER_BYTES : HEADER_BYTES + SLOT_BYTES])
|
||||
|
||||
def test_corrupt_active_slot_falls_back_and_both_corrupt_fail(self) -> None:
|
||||
original = create_config_file(sample_config())
|
||||
updated = bytearray(update_config_file(original, sample_config()))
|
||||
updated[HEADER_BYTES + SLOT_BYTES + 60] ^= 0x01
|
||||
_config, generation, slot = read_config_file(bytes(updated))
|
||||
self.assertEqual((generation, slot), (1, 0))
|
||||
updated[HEADER_BYTES + 60] ^= 0x01
|
||||
with self.assertRaises(ImageConfigError):
|
||||
read_config_file(bytes(updated))
|
||||
|
||||
def test_rejects_unknown_product_schema_and_fields(self) -> None:
|
||||
for field, value in (("product", "wrong"), ("schema_version", 2)):
|
||||
config = sample_config()
|
||||
config[field] = value
|
||||
with self.assertRaises(ImageConfigError):
|
||||
validate_config(config)
|
||||
config = sample_config()
|
||||
config["unexpected"] = True
|
||||
with self.assertRaises(ImageConfigError):
|
||||
validate_config(config)
|
||||
|
||||
def test_utf8_ssid_and_utf16_secret_lengths_match_contract(self) -> None:
|
||||
config = sample_config()
|
||||
config["wifi"]["ssid"] = "中" * 10
|
||||
validate_config(config)
|
||||
config["wifi"]["ssid"] = "中" * 11
|
||||
with self.assertRaises(ImageConfigError):
|
||||
validate_config(config)
|
||||
config = sample_config()
|
||||
config["account"]["password"] = "😀" * 4
|
||||
validate_config(config)
|
||||
|
||||
def test_static_ipv4_requires_same_subnet_and_valid_dns(self) -> None:
|
||||
config = sample_config()
|
||||
config["ipv4"] = {
|
||||
"mode": "static",
|
||||
"address": "192.168.10.20",
|
||||
"prefix": 24,
|
||||
"gateway": "192.168.10.1",
|
||||
"dns": ["1.1.1.1", "8.8.8.8"],
|
||||
}
|
||||
validate_config(config)
|
||||
config["ipv4"]["gateway"] = "192.168.11.1"
|
||||
with self.assertRaises(ImageConfigError):
|
||||
validate_config(config)
|
||||
|
||||
def test_project_codec_cross_compatibility_when_repository_is_present(self) -> None:
|
||||
project_codec = SOURCE_ROOT.parents[2] / "核桃派软件源代码" / "scripts" / "image_config.py"
|
||||
if not project_codec.is_file():
|
||||
self.skipTest("独立源码副本中没有主工程交叉校验器")
|
||||
spec = importlib.util.spec_from_file_location("project_image_config", project_codec)
|
||||
assert spec is not None and spec.loader is not None
|
||||
module = importlib.util.module_from_spec(spec)
|
||||
spec.loader.exec_module(module)
|
||||
ours = create_config_file(copy.deepcopy(sample_config()))
|
||||
theirs = module.create_config_file(copy.deepcopy(sample_config()))
|
||||
self.assertEqual(module.read_config_file(ours)[0], read_config_file(theirs)[0])
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
|
||||
Reference in New Issue
Block a user