feat: 发布固件底层开发 Skill 套件
This commit is contained in:
commit
c7ae3b4ce1
72 files changed
+10212
No files matched your search
@@ -0,0 +1,325 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Behavioral tests for validate_psp.py."""
|
||||
|
||||
import hashlib
|
||||
import json
|
||||
import tempfile
|
||||
from pathlib import Path
|
||||
|
||||
import validate_psp
|
||||
|
||||
|
||||
def main() -> int:
|
||||
with tempfile.TemporaryDirectory() as tmp:
|
||||
root = Path(tmp)
|
||||
psp = root / "psp"
|
||||
(psp / "configs").mkdir(parents=True)
|
||||
(psp / "scripts").mkdir()
|
||||
(psp / "AiPlugin").mkdir()
|
||||
artifact_root = root / "imgs" / "20260902_1"
|
||||
artifact_root.mkdir(parents=True)
|
||||
artifact = artifact_root / "boot.bin"
|
||||
artifact.write_bytes(b"boot")
|
||||
digest = hashlib.sha256(artifact.read_bytes()).hexdigest()
|
||||
kernel = artifact_root / "kernel.bin"
|
||||
kernel.write_bytes(b"kernel")
|
||||
rootfs = artifact_root / "rootfs.bin"
|
||||
rootfs.write_bytes(b"rootfs")
|
||||
(psp / "psp.json").write_text(
|
||||
json.dumps(
|
||||
{
|
||||
"EmxMediaVersion": "EmxMedia-1",
|
||||
"EmxAiPluginVersion": "EmxAiPlugin-1",
|
||||
"EmxResToProduct": [{"src": str(artifact), "dst": "imgs/boot.bin"}],
|
||||
}
|
||||
),
|
||||
encoding="utf-8",
|
||||
)
|
||||
(psp / "AiPlugin" / "profile.json").write_text(
|
||||
json.dumps({"EmxSdkVersion": "EmxSdk-1"}), encoding="utf-8"
|
||||
)
|
||||
(psp / "configs" / "same.json").write_text(
|
||||
json.dumps(
|
||||
{
|
||||
"source": "psp",
|
||||
"tool_cache": "/var/tmp/psp-tool-only",
|
||||
"endpoint": "https://git.example/psp",
|
||||
}
|
||||
),
|
||||
encoding="utf-8",
|
||||
)
|
||||
sensor_dir = psp / "configs" / "media" / "sensor"
|
||||
sensor_dir.mkdir(parents=True)
|
||||
(sensor_dir / "sensor_cfg.ini").write_text(
|
||||
"[sensor]\nname = 0X201C3B40\n", encoding="utf-8"
|
||||
)
|
||||
expected_sensors = [("sensor", "SMS_SC4336P_MIPI_4M_30FPS_10BIT")]
|
||||
(psp / "scripts" / "start.sh").write_text("#!/bin/sh\ntrue\n", encoding="utf-8")
|
||||
|
||||
app = root / "orgConfigs"
|
||||
app.mkdir()
|
||||
(app / "same.json").write_text('{"source":"app"}', encoding="utf-8")
|
||||
(psp / "metadata").mkdir()
|
||||
(psp / "metadata" / "allowed-overrides.json").write_text(
|
||||
json.dumps(
|
||||
{
|
||||
"schema_version": 1,
|
||||
"overrides": [
|
||||
{
|
||||
"psp_path": "configs/same.json",
|
||||
"application_path": "orgConfigs/same.json",
|
||||
"winner": "psp",
|
||||
"reason": "board config",
|
||||
"confirmed_by": "PSP owner",
|
||||
"confirmed_at": "2026-09-02T00:00:00+00:00",
|
||||
}
|
||||
],
|
||||
}
|
||||
),
|
||||
encoding="utf-8",
|
||||
)
|
||||
|
||||
handoff = root / "psp_handoff.json"
|
||||
bsp_project = root / "CV1841CP-NEW_dualos"
|
||||
partition = bsp_project / "configs" / "board" / "partition" / "partition_spinand.xml"
|
||||
partition.parent.mkdir(parents=True)
|
||||
partition.write_text(
|
||||
"""<physical_partition type="spinand">
|
||||
<partition label="BOOT" alias="kernel.A" size_in_kb="1024" file="kernel.bin"/>
|
||||
<partition label="ROOTFS" alias="rootfs.A" size_in_kb="1024" file="rootfs.bin"/>
|
||||
</physical_partition>
|
||||
""",
|
||||
encoding="utf-8",
|
||||
)
|
||||
margin_checks = []
|
||||
for image in (kernel, rootfs):
|
||||
size = image.stat().st_size
|
||||
margin_checks.append(
|
||||
{
|
||||
"image": image.name,
|
||||
"image_path": str(image),
|
||||
"image_size_bytes": size,
|
||||
"partitions": [
|
||||
{
|
||||
"label": "BOOT" if image.name == "kernel.bin" else "ROOTFS",
|
||||
"alias": "kernel.A" if image.name == "kernel.bin" else "rootfs.A",
|
||||
"file": image.name,
|
||||
"size_in_kb": 1024,
|
||||
"size_bytes": 1024 * 1024,
|
||||
}
|
||||
],
|
||||
"effective_partition_size_bytes": 1024 * 1024,
|
||||
"required_margin_bytes": 512 * 1024,
|
||||
"actual_margin_bytes": 1024 * 1024 - size,
|
||||
"passed": True,
|
||||
}
|
||||
)
|
||||
margin = {
|
||||
"schema_version": 1,
|
||||
"passed": True,
|
||||
"checked_at": "2026-09-02T00:00:00+00:00",
|
||||
"partition_table": str(partition),
|
||||
"partition_table_sha256": hashlib.sha256(partition.read_bytes()).hexdigest(),
|
||||
"required_margin_bytes": 512 * 1024,
|
||||
"checks": margin_checks,
|
||||
}
|
||||
margin_path = bsp_project / "doc" / "bsp_adaptation" / "validation" / "image_partition_margin_20260902_1.json"
|
||||
margin_path.parent.mkdir(parents=True)
|
||||
margin_path.write_text(json.dumps(margin), encoding="utf-8")
|
||||
handoff.write_text(
|
||||
json.dumps(
|
||||
{
|
||||
"schema_version": 1,
|
||||
"handoff_type": "bsp-to-psp",
|
||||
"producer": {
|
||||
"project": "CV1841CP-NEW_dualos",
|
||||
"project_path": str(bsp_project),
|
||||
},
|
||||
"baseline": {
|
||||
"chip": "CV1841CP",
|
||||
"sdk": "cv184x-v1",
|
||||
"board_build_type": "cv1841cp_wevb_0015a_spinand",
|
||||
"system_form": "dual-os",
|
||||
},
|
||||
"build": {
|
||||
"version": "20260902_1",
|
||||
"status": "build_passed",
|
||||
"exit_code": 0,
|
||||
"completion_marker_seen": True,
|
||||
"imgs_version_path": str(artifact_root),
|
||||
"image_partition_margin_path": str(margin_path),
|
||||
},
|
||||
"artifacts": [
|
||||
{
|
||||
"relative_path": item.name,
|
||||
"absolute_path": str(item),
|
||||
"size": item.stat().st_size,
|
||||
"sha256": hashlib.sha256(item.read_bytes()).hexdigest(),
|
||||
}
|
||||
for item in (artifact, kernel, rootfs)
|
||||
],
|
||||
"validation": {
|
||||
"image_partition_margin": margin,
|
||||
"hardware": "pending",
|
||||
"owner_acceptance": "pending",
|
||||
"release": "not-authorized",
|
||||
},
|
||||
}
|
||||
),
|
||||
encoding="utf-8",
|
||||
)
|
||||
lock = psp / "metadata" / "bsp.lock.json"
|
||||
result = validate_psp.validate_psp(
|
||||
psp,
|
||||
"NEW",
|
||||
"EmxSdk-1",
|
||||
"EmxMedia-1",
|
||||
"EmxAiPlugin-1",
|
||||
handoff,
|
||||
lock,
|
||||
"CV1841CP-NEW_dualos",
|
||||
"CV1841CP",
|
||||
"cv184x-v1",
|
||||
"cv1841cp_wevb_0015a_spinand",
|
||||
"dual-os",
|
||||
[],
|
||||
[(app, "configs")],
|
||||
formal=False,
|
||||
expected_sensors=expected_sensors,
|
||||
)
|
||||
assert result["passed"] is True, result
|
||||
assert lock.is_file()
|
||||
lock_payload = json.loads(lock.read_text(encoding="utf-8"))
|
||||
assert lock_payload["image_partition_margin"]["required_margin_bytes"] == 512 * 1024
|
||||
assert result["checks"]["configuration_overrides"][0]["allowed"] is True
|
||||
assert any("个人或临时目录" in warning for warning in result["warnings"])
|
||||
assert any(
|
||||
item["source"] == "configs/same.json"
|
||||
for item in result["checks"]["absolute_paths"]
|
||||
)
|
||||
assert all(
|
||||
"git.example" not in item["path"]
|
||||
for item in result["checks"]["absolute_paths"]
|
||||
)
|
||||
assert result["checks"]["sensor_baseline"]["sensors"][0]["matched"] is True
|
||||
assert result["checks"]["sensor_baseline"]["enum_header"]["source"] == "bundled"
|
||||
assert result["checks"]["sensor_baseline"]["enum_header"]["path"] == str(
|
||||
validate_psp.bundled_sensor_header("cv184x")
|
||||
)
|
||||
cv184_items = validate_psp.parse_sensor_enum(
|
||||
validate_psp.bundled_sensor_header("cv184x"), "_SNS_TYPE_E"
|
||||
)
|
||||
assert len(cv184_items) == 244
|
||||
assert cv184_items["SMS_SC4336P_MIPI_4M_30FPS_10BIT"] == 0X201C3B40
|
||||
assert cv184_items["IMGDS_MIS40C1_MIPI_4M_20FPS_1L_10BIT"] == 0X00003A00
|
||||
assert "BYD_BF2253L_MIPI_1200P_30FPS_10BIT" not in cv184_items
|
||||
|
||||
formal = validate_psp.validate_psp(
|
||||
psp,
|
||||
"NEW",
|
||||
"EmxSdk-1",
|
||||
"EmxMedia-1",
|
||||
"EmxAiPlugin-1",
|
||||
handoff,
|
||||
None,
|
||||
"CV1841CP-NEW_dualos",
|
||||
"CV1841CP",
|
||||
"cv184x-v1",
|
||||
"cv1841cp_wevb_0015a_spinand",
|
||||
"dual-os",
|
||||
[artifact_root, handoff],
|
||||
[(app, "configs")],
|
||||
formal=True,
|
||||
expected_sensors=expected_sensors,
|
||||
)
|
||||
assert formal["passed"] is False
|
||||
assert any(
|
||||
"configs/same.json" in error and "个人或临时目录" in error
|
||||
for error in formal["errors"]
|
||||
)
|
||||
|
||||
artifact.write_bytes(b"tampered")
|
||||
tampered = validate_psp.validate_psp(
|
||||
psp,
|
||||
"NEW",
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
handoff,
|
||||
None,
|
||||
"CV1841CP-NEW_dualos",
|
||||
"CV1841CP",
|
||||
"cv184x-v1",
|
||||
"cv1841cp_wevb_0015a_spinand",
|
||||
"dual-os",
|
||||
[],
|
||||
[],
|
||||
formal=False,
|
||||
expected_sensors=expected_sensors,
|
||||
)
|
||||
assert tampered["passed"] is False
|
||||
assert any("BSP handoff" in error for error in tampered["errors"])
|
||||
|
||||
missing_identity = validate_psp.validate_psp(
|
||||
psp,
|
||||
"NEW",
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
handoff,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
[],
|
||||
[],
|
||||
formal=False,
|
||||
expected_sensors=expected_sensors,
|
||||
)
|
||||
assert missing_identity["passed"] is False
|
||||
assert any("必需身份字段" in error for error in missing_identity["errors"])
|
||||
|
||||
(sensor_dir / "sensor_cfg.ini").write_text(
|
||||
"[sensor]\nname = SMS_SC4336P_MIPI_4M_30FPS_10BIT\n", encoding="utf-8"
|
||||
)
|
||||
sensor_errors: list[str] = []
|
||||
validate_psp.validate_sensor_baseline(
|
||||
psp,
|
||||
"CV1841CP",
|
||||
None,
|
||||
expected_sensors,
|
||||
sensor_errors,
|
||||
)
|
||||
assert any("必须填写" in error and "枚举值" in error for error in sensor_errors)
|
||||
|
||||
cv181_psp = root / "cv181-psp"
|
||||
cv181_sensor_dir = cv181_psp / "configs" / "media" / "isp"
|
||||
cv181_sensor_dir.mkdir(parents=True)
|
||||
(cv181_sensor_dir / "sensor_cfg.ini").write_text(
|
||||
"[sensor]\nname = SMS_SC4336P_MIPI_4M_30FPS_10BIT\n", encoding="utf-8"
|
||||
)
|
||||
cv181_errors: list[str] = []
|
||||
cv181_result = validate_psp.validate_sensor_baseline(
|
||||
cv181_psp,
|
||||
"CV1815J",
|
||||
None,
|
||||
expected_sensors,
|
||||
cv181_errors,
|
||||
)
|
||||
assert cv181_errors == [], cv181_errors
|
||||
assert cv181_result["sensors"][0]["matched"] is True
|
||||
assert cv181_result["enum_header"]["source"] == "bundled"
|
||||
cv181_items = validate_psp.parse_sensor_enum(
|
||||
validate_psp.bundled_sensor_header("cv181x"), "_SAMPLE_SNS_TYPE_E"
|
||||
)
|
||||
assert len(cv181_items) == 213
|
||||
assert "SMS_SC4336P_MIPI_4M_30FPS_10BIT" in cv181_items
|
||||
|
||||
print("PSP validator tests passed")
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
raise SystemExit(main())
|
||||
Reference in new issue
Block a user