Coverage for tests/unit_tests/scons/testing.py: 100%

32 statements  

« prev     ^ index     » next       coverage.py v7.17.2, created at 2026-11-07 05:08 +0000

1# This file is part of the Apio project 

2# (C) 2016-present FPGAwars 

3# Project authors: 

4# * Jesús Arroyo (Jesus89) (2016-2019) 

5# * Juan Gonzalez (obijuan) (2019-2024) 

6# * The Apio Team (2024-present) 

7# License: GPLv2 

8 

9""" 

10Helpers for apio's scons testing.""" 

11 

12import SCons.Script.SConsOptions 

13import SCons.Node.FS 

14import SCons.Environment 

15import SCons.Script.Main 

16from google.protobuf import text_format 

17from apio.scons.apio_env import ApioEnv 

18from apio.common.proto.stubs.apio_scons_pb2 import ( 

19 SconsParams, 

20 TargetParams, 

21 ApioEnvParams, 

22) 

23 

24 

25TEST_PARAMS = """ 

26timestamp: "20123412052" 

27fpga_definition { 

28 arch: ice40 

29 size: "8k" 

30 vendor_part: "ICE40HX4K-TQ144" 

31 ice40_params { 

32 nextpnr_type: "hx8k" 

33 nextpnr_package: "tq144:4k" 

34 } 

35} 

36verbosity { 

37 all: false 

38 synth: false 

39 pnr: false 

40} 

41environment { 

42 platform_id: "darwin-arm64" 

43 yosys_path: "/Users/user/.apio/packages/oss-cad-suite/share/yosys" 

44 trellis_path: "/Users/user/.apio/packages/oss-cad-suite/share/trellis" 

45} 

46apio_env_params { 

47 env_name: "default" 

48 board_id: "alhambra-ii" 

49 top_module: "main" 

50} 

51""" 

52 

53 

54class SconsHacks: 

55 """A collection of static methods that encapsulate scons access outside of 

56 the official scons API. Hopefully this will not be too difficult to adapt 

57 in future versions of SCons.""" 

58 

59 @staticmethod 

60 def reset_scons_state() -> None: 

61 """Reset the relevant SCons global variables. Unfortunately scons 

62 uses a few global variables to hold its state. This works well in 

63 normal operation where an scons process contains a single scons 

64 session but with pytest testing, where multiple independent tests 

65 are running in the same process, we need to reset though variables 

66 before each test.""" 

67 

68 # -- The Cons.Script.Main.OptionsParser variables contains the command 

69 # -- line options of scons. We reset them here and tests can access 

70 # -- them using SetOption() and GetOption(). 

71 

72 parser = SCons.Script.SConsOptions.Parser("my_fake_version") 

73 values = SCons.Script.SConsOptions.SConsValues( 

74 parser.get_default_values() 

75 ) 

76 parser.parse_args(args=[], values=values) 

77 SCons.Script.Main.OptionsParser = parser 

78 

79 # -- Reset the scons target list variable. 

80 SCons.Node.FS.default_fs = None 

81 

82 # -- Clear the SCons targets 

83 SCons.Environment.CleanTargets = {} 

84 

85 

86def make_test_scons_params() -> SconsParams: 

87 """Create a fake scons params for testing.""" 

88 return text_format.Parse(TEST_PARAMS, SconsParams()) 

89 

90 

91def make_test_apio_env( 

92 *, 

93 targets: list[str] | None = None, 

94 platform_id: str | None = None, 

95 apio_env_params: ApioEnvParams | None = None, 

96 target_params: TargetParams | None = None, 

97) -> ApioEnv: 

98 """Creates a fresh apio env for testing. The env is created 

99 with the current directory as the root dir. 

100 """ 

101 

102 # -- Bring scons to a starting state. 

103 SconsHacks.reset_scons_state() 

104 

105 # -- Create default params. 

106 scons_params = make_test_scons_params() 

107 

108 # -- Set debug level 

109 # scons_params.environment.debug_level = debug_level 

110 

111 # -- Apply user overrides. 

112 if platform_id is not None: 

113 scons_params.environment.platform_id = platform_id 

114 if apio_env_params is not None: 

115 scons_params.apio_env_params.MergeFrom(apio_env_params) 

116 if target_params is not None: 

117 scons_params.target.MergeFrom(target_params) 

118 

119 # -- Determine scons target. 

120 if targets is not None: 

121 command_line_targets = targets 

122 else: 

123 command_line_targets = ["build"] 

124 

125 # -- Create and return the apio env. 

126 return ApioEnv( 

127 command_line_targets=command_line_targets, scons_params=scons_params 

128 )