Coverage for tests/unit_tests/managers/test_xilinx_chipdb.py: 100%
49 statements
« prev ^ index » next coverage.py v7.16.1, created at 2026-09-23 03:53 +0000
« prev ^ index » next coverage.py v7.16.1, created at 2026-09-23 03:53 +0000
1"""Tests for the openxc7 parts-index reader."""
3import json
4import os
6import pytest
7from tests.conftest import ApioRunner, ApioSandbox
8from apio.apio_context import (
9 ApioContext,
10 PackagesPolicy,
11 ProjectPolicy,
12 RemoteConfigPolicy,
13)
14from apio.managers.xilinx_chipdb import (
15 PARTS_INDEX_FILE_NAME,
16 chipdb_file_on_demand,
17 read_xilinx_parts_index,
18)
20_PART = "xc7a35tcsg324-1"
23def _write_index(sb: ApioSandbox, document: dict) -> None:
24 """Write a parts index under the sandbox home.
26 The sandbox points APIO_PACKAGES at a shared cache. This test points
27 it at the sandbox home instead, so the fixture does not touch that
28 cache.
29 """
30 packages = sb.home_dir / "packages"
31 os.environ["APIO_PACKAGES"] = str(packages)
32 index_path = packages / "openxc7" / PARTS_INDEX_FILE_NAME
33 sb.write_file(index_path, json.dumps(document))
36def _context() -> ApioContext:
37 """An apio context that does not install packages."""
38 return ApioContext(
39 project_policy=ProjectPolicy.NO_PROJECT,
40 remote_config_policy=RemoteConfigPolicy.CACHED_OK,
41 packages_policy=PackagesPolicy.IGNORE_PACKAGES,
42 )
45def _entry() -> dict:
46 """One generated part. Schema 6 has no pnr field."""
47 return {
48 "family": "artix7",
49 "base-part": "xc7a35tcsg324",
50 "speed": "1",
51 "generated": True,
52 "chipdb": "chipdb-xc7a35tcsg324.bin",
53 }
56def _document(parts: dict, schema: int = 6) -> dict:
57 """A minimal parts index."""
58 return {"schema": schema, "parts": parts}
61def test_schema_6_is_accepted(apio_runner: ApioRunner):
62 """A schema 6 index with no pnr field is accepted."""
63 with apio_runner.in_sandbox() as sb:
64 _write_index(sb, _document({_PART: _entry()}))
65 apio_ctx = _context()
66 document = read_xilinx_parts_index(apio_ctx)
67 assert document["schema"] == 6
68 assert _PART in document["parts"]
69 assert "pnr" not in document["parts"][_PART]
72def test_absent_part_is_fatal(apio_runner: ApioRunner):
73 """A part that is not in the index is a fatal error naming it."""
74 with apio_runner.in_sandbox() as sb:
75 _write_index(sb, _document({"xc7a100tcsg324-1": _entry()}))
76 apio_ctx = _context()
77 with apio_runner.with_logger() as log:
78 with pytest.raises(SystemExit) as e:
79 chipdb_file_on_demand(apio_ctx, _PART)
80 assert e.value.code == 1
81 assert _PART in log.out
84def test_schema_5_is_rejected(apio_runner: ApioRunner):
85 """A schema 5 index is rejected by the shared reader, including when
86 the chipdb fetch is what opens it."""
87 with apio_runner.in_sandbox() as sb:
88 _write_index(sb, _document({_PART: _entry()}, schema=5))
89 apio_ctx = _context()
90 with apio_runner.with_logger() as log:
91 with pytest.raises(SystemExit) as e:
92 read_xilinx_parts_index(apio_ctx)
93 assert e.value.code == 1
94 assert "expected 6" in log.out
96 with apio_runner.with_logger() as log:
97 with pytest.raises(SystemExit) as e:
98 chipdb_file_on_demand(apio_ctx, _PART)
99 assert e.value.code == 1
100 assert "expected 6" in log.out