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

1"""Tests for the openxc7 parts-index reader.""" 

2 

3import json 

4import os 

5 

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) 

19 

20_PART = "xc7a35tcsg324-1" 

21 

22 

23def _write_index(sb: ApioSandbox, document: dict) -> None: 

24 """Write a parts index under the sandbox home. 

25 

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)) 

34 

35 

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 ) 

43 

44 

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 } 

54 

55 

56def _document(parts: dict, schema: int = 6) -> dict: 

57 """A minimal parts index.""" 

58 return {"schema": schema, "parts": parts} 

59 

60 

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] 

70 

71 

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 

82 

83 

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 

95 

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