Coverage for jumpstarter_driver_flashers/driver_test.py: 100%

90 statements  

« prev     ^ index     » next       coverage.py v7.9.1, created at 2025-06-30 18:45 +0200

1import os 

2import tempfile 

3 

4import pytest 

5from jumpstarter_driver_power.driver import MockPower 

6from jumpstarter_driver_pyserial.driver import PySerial 

7 

8from .driver import BaseFlasher 

9from jumpstarter.client.core import DriverInvalidArgument 

10from jumpstarter.common.exceptions import ConfigurationError 

11from jumpstarter.common.utils import serve 

12 

13 

14@pytest.fixture(scope="session") 

15def temp_dirs(): 

16 with tempfile.TemporaryDirectory() as temp_dir: 

17 cache = os.path.join(temp_dir, "cache") 

18 http = os.path.join(temp_dir, "http") 

19 tftp = os.path.join(temp_dir, "tftp") 

20 os.mkdir(cache) 

21 os.mkdir(http) 

22 os.mkdir(tftp) 

23 yield cache, http, tftp 

24 

25 

26@pytest.fixture(scope="session") # session to retain cache over time 

27def complete_flasher(temp_dirs): 

28 cache, http, tftp = temp_dirs 

29 yield BaseFlasher( 

30 flasher_bundle="quay.io/jumpstarter-dev/jumpstarter-flasher-test:new", 

31 cache_dir=cache, 

32 http_dir=http, 

33 tftp_dir=tftp, 

34 children={ 

35 "serial": PySerial(url="loop://"), 

36 "power": MockPower(), 

37 }, 

38 ) 

39 

40def test_missing_serial(temp_dirs): 

41 cache, http, tftp = temp_dirs 

42 with pytest.raises(ConfigurationError): 

43 BaseFlasher(cache_dir=cache, http_dir=http, tftp_dir=tftp, children={"power": MockPower()}) 

44 

45 

46def test_missing_power(temp_dirs): 

47 cache, http, tftp = temp_dirs 

48 with pytest.raises(ConfigurationError): 

49 BaseFlasher(cache_dir=cache, http_dir=http, tftp_dir=tftp, children={"serial": PySerial(url="loop://")}) 

50 

51 

52def test_drivers_flashers_setup_flasher_bundle(complete_flasher): 

53 with serve(complete_flasher) as client: 

54 client.call("setup_flasher_bundle") 

55 dtb = client.call("get_dtb_filename") 

56 kernel = client.call("get_kernel_filename") 

57 initram = client.call("get_initram_filename") 

58 assert client.tftp.storage.read_bytes(kernel) == b"\x00" * 1024 

59 assert client.tftp.storage.read_bytes(initram) == b"\x00" * 1024 * 2 

60 assert client.tftp.storage.read_bytes(dtb) == b"\x00" * 1024 * 3 

61 

62 

63def test_drivers_flashers_manifest(complete_flasher): 

64 with serve(complete_flasher) as client: 

65 assert client.manifest.spec.kernel.file == "data/kernel" 

66 

67 

68def test_drivers_flashers_dtb_switching(complete_flasher): 

69 with serve(complete_flasher) as client: 

70 assert client.call("get_dtb_filename") == "test-dtb.dtb" 

71 client.call("use_dtb_variant", "alternate") 

72 assert client.call("get_dtb_filename") == "alternate.dtb" 

73 client.call("use_dtb_variant", "test-dtb") 

74 assert client.call("get_dtb_filename") == "test-dtb.dtb" 

75 # verify dtb variant switching to nonexisting 

76 with pytest.raises(ValueError): 

77 client.call("use_dtb_variant", "noexists") 

78 

79 

80def test_drivers_flashers_filenames(complete_flasher): 

81 with serve(complete_flasher) as client: 

82 assert client.call("get_dtb_filename") == "test-dtb.dtb" 

83 assert client.call("get_kernel_filename") == "kernel" 

84 assert client.call("get_initram_filename") == "initramfs" 

85 

86 

87def test_drivers_flashers_addresses(complete_flasher): 

88 with serve(complete_flasher) as client: 

89 assert client.call("get_kernel_address") == "0x82000000" 

90 assert client.call("get_initram_address") == "0x83000000" 

91 assert client.call("get_dtb_address") == "0x84000000" 

92 

93 

94def test_drivers_flashers_get_bootcmd_default(complete_flasher): 

95 """Test getting the default boot command""" 

96 with serve(complete_flasher) as client: 

97 bootcmd = client.call("get_bootcmd") 

98 assert bootcmd == "booti 0x82000000 - 0x84000000" 

99 

100 

101def test_drivers_flashers_get_bootcmd_with_dtb_variant(complete_flasher): 

102 """Test getting boot command with DTB variant that has custom bootcmd""" 

103 with serve(complete_flasher) as client: 

104 # Switch to variant with custom boot command 

105 client.call("use_dtb_variant", "othercmd") 

106 bootcmd = client.call("get_bootcmd") 

107 assert bootcmd == "bootm" 

108 

109 

110def test_drivers_flashers_get_bootcmd_with_dtb_variant_no_custom_cmd(complete_flasher): 

111 """Test getting boot command with DTB variant that has no custom bootcmd (should use default)""" 

112 with serve(complete_flasher) as client: 

113 # Switch to variant without custom boot command 

114 client.call("use_dtb_variant", "alternate") 

115 bootcmd = client.call("get_bootcmd") 

116 assert bootcmd == "booti 0x82000000 - 0x84000000" 

117 

118 

119def test_drivers_flashers_get_bootcmd_variant_switching(complete_flasher): 

120 """Test that boot command changes when switching between DTB variants""" 

121 with serve(complete_flasher) as client: 

122 # Start with default variant 

123 bootcmd = client.call("get_bootcmd") 

124 assert bootcmd == "booti 0x82000000 - 0x84000000" 

125 

126 # Switch to variant with custom boot command 

127 client.call("use_dtb_variant", "othercmd") 

128 bootcmd = client.call("get_bootcmd") 

129 assert bootcmd == "bootm" 

130 

131 # Switch back to default variant 

132 client.call("use_dtb_variant", "test-dtb") 

133 bootcmd = client.call("get_bootcmd") 

134 assert bootcmd == "booti 0x82000000 - 0x84000000" 

135 

136 

137def test_drivers_flashers_get_bootcmd_invalid_variant(complete_flasher): 

138 """Test that get_bootcmd raises DriverInvalidArgument for invalid DTB variant""" 

139 with serve(complete_flasher) as client: 

140 # Set an invalid variant 

141 with pytest.raises(DriverInvalidArgument): 

142 client.call("use_dtb_variant", "noexists") 

143