Coverage for tests/unit_tests/commands/test_apio_build.py: 100%

47 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"""Test for the "apio build" command.""" 

10 

11from pathlib import Path 

12from tests.conftest import ApioRunner 

13from apio.commands.apio import apio_top_cli as apio 

14 

15 

16def test_build_without_apio_ini(apio_runner: ApioRunner): 

17 """Tests build command with no apio.ini.""" 

18 

19 with apio_runner.in_sandbox() as sb: 

20 

21 # -- Run "apio build" without apio.ini 

22 result = sb.invoke_apio_cmd(apio, ["build"]) 

23 assert result.exit_code != 0, result.output 

24 assert "Error: Missing project file apio.ini" in result.output 

25 

26 

27def test_build_with_apio_ini(apio_runner: ApioRunner): 

28 """Test build command with apio.ini.""" 

29 

30 with apio_runner.in_sandbox() as sb: 

31 

32 # -- Run "apio build" with a missing board var. 

33 sb.write_apio_ini({"[env:default]": {"top-module": "main"}}) 

34 result = sb.invoke_apio_cmd(apio, ["build"]) 

35 assert result.exit_code == 1, result.output 

36 assert ( 

37 "Error: Missing required option 'board' for env 'default'" 

38 in result.output 

39 ) 

40 

41 # -- Run "apio build" with an invalid board 

42 sb.write_apio_ini( 

43 { 

44 "[env:default]": { 

45 "board": "no-such-board", 

46 "top-module": "main", 

47 } 

48 } 

49 ) 

50 result = sb.invoke_apio_cmd(apio, ["build"]) 

51 assert result.exit_code == 1, result.output 

52 assert ( 

53 "Error: Unknown board id 'no-such-board' in apio.ini" 

54 in result.output 

55 ) 

56 

57 # -- Run "apio build" with an unknown option. 

58 sb.write_apio_ini( 

59 { 

60 "[env:default]": { 

61 "board": "alhambra-ii", 

62 "top-module": "main", 

63 "unknown": "xyz", 

64 } 

65 } 

66 ) 

67 result = sb.invoke_apio_cmd(apio, ["build"]) 

68 assert result.exit_code == 1, result.output 

69 assert ( 

70 "Error: Unknown option 'unknown' in [env:default] section " 

71 "of apio.ini" in result.output 

72 ) 

73 

74 

75def test_build_with_env_arg_error(apio_runner: ApioRunner): 

76 """Tests the command with an invalid --env value. This error message 

77 confirms that the --env arg was propagated to the apio.ini loading 

78 logic.""" 

79 

80 with apio_runner.in_sandbox() as sb: 

81 

82 # -- Run "apio build --env no-such-env" 

83 sb.write_apio_ini({"[env:default]": {"top-module": "main"}}) 

84 result = sb.invoke_apio_cmd(apio, ["build", "--env", "no-such-env"]) 

85 assert result.exit_code == 1, result.output 

86 assert ( 

87 "Error: Env 'no-such-env' not found in apio.ini" in result.output 

88 ) 

89 

90 

91def test_files_order(apio_runner: ApioRunner): 

92 """Tests that source files are sorted by the apio build command.""" 

93 

94 with apio_runner.in_sandbox() as sb: 

95 

96 # -- Fetch a working example. 

97 result = sb.invoke_apio_cmd( 

98 apio, 

99 ["examples", "fetch", "alhambra-ii/ledon"], 

100 terminal_mode=False, 

101 ) 

102 sb.assert_result_ok(result) 

103 print(result.output) 

104 

105 # -- Add dummy source files 

106 Path("aa").mkdir(parents=True) 

107 Path("bb").mkdir(parents=True) 

108 Path("aa/bb.v").touch() 

109 Path("aa/cc.v").touch() 

110 Path("bb/aa.v").touch() 

111 

112 # -- Add a fake source files in _build directory. It should not be 

113 # -- picked up. 

114 Path("_build").mkdir() 

115 Path("_build/zzz.v").touch() 

116 

117 # -- 'apio build' 

118 result = sb.invoke_apio_cmd(apio, ["build"]) 

119 sb.assert_result_ok(result) 

120 assert "SUCCESS" in result.output 

121 

122 # -- Check that the source file from the _build directory was not 

123 # -- picked up. 

124 assert "zzz.v" not in result.output 

125 

126 # -- Check that the files in the build command are sorted. 

127 # -- We adjust for the "/" vs "\" difference between Windows and Linux. 

128 expected_order = ["main.v", "aa/bb.v", "aa/cc.v", "bb/aa.v"] 

129 expected_text = " ".join([str(Path(f)) for f in expected_order]) 

130 assert expected_text in result.output