Coverage for basic_library_tests.py: 99%

899 statements  

« prev     ^ index     » next       coverage.py v7.2.7, created at 2024-04-10 15:08 +0100

1#----------------------------------------------------------------------------------- 

2# Library tests to check the basic function of all library object object functions 

3# Calls the library functions directly rather than using the sysytem_test_harness 

4#----------------------------------------------------------------------------------- 

5 

6import time 

7import logging 

8 

9import system_test_harness 

10from model_railway_signals.library import track_sensors 

11from model_railway_signals.library import gpio_sensors 

12from model_railway_signals.library import points 

13from model_railway_signals.library import block_instruments 

14from model_railway_signals.library import dcc_control 

15from model_railway_signals.library import pi_sprog_interface 

16from model_railway_signals.library import signals_common 

17from model_railway_signals.library import mqtt_interface 

18 

19from model_railway_signals.editor import schematic 

20 

21#--------------------------------------------------------------------------------------------------------- 

22# Test Track Sensor Library objects 

23#--------------------------------------------------------------------------------------------------------- 

24 

25def track_sensor_callback(sensor_id, callback_type): 

26 logging_string="Track Sensor Callback from Sensor "+str(sensor_id)+"-"+str(callback_type) 

27 logging.info(logging_string) 

28 

29def run_track_sensor_library_tests(): 

30 # Test all functions - including negative tests for parameter validation 

31 print("Library Tests - Track Sensor Objects") 

32 canvas = schematic.canvas 

33 # create_track_sensor 

34 print("Library Tests - create_track_sensor - will generate 3 errors:") 

35 assert len(track_sensors.track_sensors) == 0 

36 track_sensors.create_track_sensor(canvas, sensor_id=100, x=100, y=100, callback=track_sensor_callback) 

37 track_sensors.create_track_sensor(canvas, sensor_id=0, x=100, y=100, callback=track_sensor_callback) 

38 track_sensors.create_track_sensor(canvas, sensor_id="101", x=100, y=100, callback=track_sensor_callback) 

39 track_sensors.create_track_sensor(canvas, sensor_id=100, x=100, y=100, callback=track_sensor_callback) 

40 assert len(track_sensors.track_sensors) == 1 

41 # track_sensor_exists 

42 print("Library Tests - track_sensor_exists - will generate 1 error:") 

43 assert track_sensors.track_sensor_exists(100) 

44 assert not track_sensors.track_sensor_exists(0) 

45 assert not track_sensors.track_sensor_exists(101) 

46 assert not track_sensors.track_sensor_exists("100") 

47 # track_sensor_triggered (pulse the button and generate callback) 

48 print("Library Tests - track_sensor_triggered - will generate 2 errors:") 

49 track_sensors.track_sensor_triggered("101") 

50 track_sensors.track_sensor_triggered(101) 

51 print("Library Tests - track_sensor_triggered - Triggering 2 track sensor passed events:") 

52 track_sensors.track_sensor_triggered(100) 

53 system_test_harness.sleep(1.5) 

54 # track_sensor_triggered (pulse the button and generate callback) 

55 track_sensors.track_sensor_triggered(100) 

56 # delete_track_sensor - reset_sensor_button function should not generate any exceptions 

57 print("Library Tests - delete_track_sensor - will generate 2 errors:") 

58 track_sensors.delete_track_sensor("101") 

59 track_sensors.delete_track_sensor(101) 

60 track_sensors.delete_track_sensor(100) 

61 assert len(track_sensors.track_sensors) == 0 

62 assert not track_sensors.track_sensor_exists(100) 

63 print("----------------------------------------------------------------------------------------") 

64 print("") 

65 return() 

66 

67#--------------------------------------------------------------------------------------------------------- 

68# Test GPIO Sensor Library objects 

69#--------------------------------------------------------------------------------------------------------- 

70 

71def run_gpio_sensor_library_tests(): 

72 # Test all functions - including negative tests for parameter validation 

73 print("Library Tests - GPIO Sensors") 

74 canvas = schematic.canvas 

75 # gpio_interface_enabled 

76 assert gpio_sensors.gpio_interface_enabled() 

77 # create_gpio_sensor - Sensor ID combinations 

78 assert len(gpio_sensors.gpio_port_mappings) == 0 

79 print ("GPIO Sensors - create_gpio_sensor - will generate 17 errors") 

80 gpio_sensors.create_gpio_sensor(100, 4) # Success - int > 0 with valid port 

81 gpio_sensors.create_gpio_sensor(101, 5) # Success - int > 0 with valid port 

82 gpio_sensors.create_gpio_sensor(102, 6, signal_passed=1) # Success - int > 0 with valid port & valid callback 

83 gpio_sensors.create_gpio_sensor(103, 7, signal_approach=1) # Success - int > 0 with valid port & valid callback 

84 gpio_sensors.create_gpio_sensor(104, 8, sensor_passed=1) # Success - int > 0 with valid port & valid callback 

85 gpio_sensors.create_gpio_sensor(105, 9, sensor_timeout=0.001) # Success - int > 0 with valid port & valid timeout 

86 gpio_sensors.create_gpio_sensor(106, 10, trigger_period=0.001) # success - int > 0 with valid port & valid trigger 

87 gpio_sensors.create_gpio_sensor(107, 11, trigger_period=0.005, sensor_timeout=2.0) # Success - all valid 

88 assert len(gpio_sensors.gpio_port_mappings) == 8 

89 # create_gpio_sensor - Invalid Sensor ID 

90 gpio_sensors.create_gpio_sensor("108", 9) # Fail - Sensor ID not an int 

91 gpio_sensors.create_gpio_sensor(0, 9) # Fail - Sensor ID int not > 0 

92 gpio_sensors.create_gpio_sensor(100, 9) # Fail - Sensor ID duplicate 

93 assert len(gpio_sensors.gpio_port_mappings) == 8 

94 # create_gpio_sensor - Invalid GPIO Port 

95 gpio_sensors.create_gpio_sensor(108, "5") # Fail - Port not an int 

96 gpio_sensors.create_gpio_sensor(108, 14) # Fail - invalid port number 

97 gpio_sensors.create_gpio_sensor(108, 4) # Fail - port already mapped 

98 assert len(gpio_sensors.gpio_port_mappings) == 8 

99 # create_gpio_sensor - Invalid Callback combinations 

100 gpio_sensors.create_gpio_sensor(108, 6, signal_passed="1") # Fail - not an int 

101 gpio_sensors.create_gpio_sensor(108, 6, signal_approach="1") # Fail - not an int 

102 gpio_sensors.create_gpio_sensor(108, 6, sensor_passed="1") # Fail - not an int 

103 gpio_sensors.create_gpio_sensor(108, 6, signal_passed=1, signal_approach=1, sensor_passed=1) # Fail - multiple specified 

104 gpio_sensors.create_gpio_sensor(108, 6, signal_passed=1, signal_approach=1) # Fail - multiple specified 

105 gpio_sensors.create_gpio_sensor(108, 6, signal_approach=1, sensor_passed=1) # Fail - multiple specified 

106 gpio_sensors.create_gpio_sensor(108, 6, signal_passed=1, sensor_passed=1) # Fail - multiple specified 

107 assert len(gpio_sensors.gpio_port_mappings) == 8 

108 # create_gpio_sensor - Invalid Timeout and trigger period  

109 gpio_sensors.create_gpio_sensor(108, 9, sensor_timeout=2) # Fail - not a float 

110 gpio_sensors.create_gpio_sensor(108, 9, trigger_period=1) # Fail - not a float 

111 gpio_sensors.create_gpio_sensor(108, 9, trigger_period=-1.0) # Fail - must be >= 0.0 

112 gpio_sensors.create_gpio_sensor(108, 9, sensor_timeout=-1.0) # Fail - must be >= 0.0 

113 assert len(gpio_sensors.gpio_port_mappings) == 8 

114 # track_sensor_exists (accepts ints and strs) 

115 print ("GPIO Sensors - gpio_sensor_exists - will generate 1 error") 

116 assert gpio_sensors.gpio_sensor_exists(100) # True - int and exists 

117 assert gpio_sensors.gpio_sensor_exists(101) # True - int and exists 

118 assert gpio_sensors.gpio_sensor_exists(102) # True - int and exists 

119 assert gpio_sensors.gpio_sensor_exists(103) # True - int and exists 

120 assert gpio_sensors.gpio_sensor_exists(104) # True - int and exists 

121 assert gpio_sensors.gpio_sensor_exists(105) # True - int and exists 

122 assert gpio_sensors.gpio_sensor_exists(106) # True - int and exists 

123 assert gpio_sensors.gpio_sensor_exists(107) # True - int and exists 

124 assert gpio_sensors.gpio_sensor_exists("100") # True - str and exists 

125 assert gpio_sensors.gpio_sensor_exists("101") # True - str and exists 

126 assert gpio_sensors.gpio_sensor_exists("102") # True - str and exists 

127 assert gpio_sensors.gpio_sensor_exists("103") # True - str and exists 

128 assert gpio_sensors.gpio_sensor_exists("104") # True - str and exists 

129 assert gpio_sensors.gpio_sensor_exists("105") # True - str and exists 

130 assert gpio_sensors.gpio_sensor_exists("106") # True - str and exists 

131 assert gpio_sensors.gpio_sensor_exists("107") # True - str and exists 

132 assert not gpio_sensors.gpio_sensor_exists(108) # False - does not exist 

133 assert not gpio_sensors.gpio_sensor_exists("108") # False - does not exist 

134 assert not gpio_sensors.gpio_sensor_exists(107.0) # False (with Error) - not an int or str 

135 # get_gpio_sensor_callback 

136 print ("GPIO Sensors - get_gpio_sensor_callback - will generate 3 errors") 

137 assert gpio_sensors.get_gpio_sensor_callback(100) == [0,0,0] # Success - ID is int 

138 assert gpio_sensors.get_gpio_sensor_callback(101) == [0,0,0] # Success - ID is int 

139 assert gpio_sensors.get_gpio_sensor_callback(102) == [1,0,0] # Success - ID is int 

140 assert gpio_sensors.get_gpio_sensor_callback(103) == [0,1,0] # Success - ID is int 

141 assert gpio_sensors.get_gpio_sensor_callback(104) == [0,0,1] # Success - ID is int 

142 assert gpio_sensors.get_gpio_sensor_callback("100") == [0,0,0] # Success - ID is str 

143 assert gpio_sensors.get_gpio_sensor_callback("101") == [0,0,0] # Success - ID is str 

144 assert gpio_sensors.get_gpio_sensor_callback("102") == [1,0,0] # Success - ID is str 

145 assert gpio_sensors.get_gpio_sensor_callback("103") == [0,1,0] # Success - ID is str 

146 assert gpio_sensors.get_gpio_sensor_callback("104") == [0,0,1] # Success - ID is str 

147 assert gpio_sensors.get_gpio_sensor_callback(104.0) == [0,0,0] # Error - not int or str 

148 assert gpio_sensors.get_gpio_sensor_callback(108) == [0,0,0] # Error - Does not exist 

149 assert gpio_sensors.get_gpio_sensor_callback("108") == [0,0,0] # Error - Does not exist 

150 # remove_gpio_sensor_callbacks 

151 print ("GPIO Sensors - remove_gpio_sensor_callback - will generate 3 errors") 

152 gpio_sensors.remove_gpio_sensor_callback(102) # Success - int and exists 

153 gpio_sensors.remove_gpio_sensor_callback("103") # success - str and exists 

154 gpio_sensors.remove_gpio_sensor_callback("104") # success - str and exists 

155 gpio_sensors.remove_gpio_sensor_callback(108) # Fail - Does not exist 

156 gpio_sensors.remove_gpio_sensor_callback("108") # Fail - Does not exist 

157 gpio_sensors.remove_gpio_sensor_callback(104.0) # Fail - not int or str 

158 assert gpio_sensors.get_gpio_sensor_callback(102) == [0,0,0] 

159 assert gpio_sensors.get_gpio_sensor_callback(103) == [0,0,0] 

160 assert gpio_sensors.get_gpio_sensor_callback(104) == [0,0,0] 

161 # add_gpio_sensor_callbacks 

162 print ("GPIO Sensors - add_gpio_sensor_callback - will generate 10 errors") 

163 # Set up the test condition for Sensor 105 

164 gpio_sensors.add_gpio_sensor_callback(105, signal_passed=2) 

165 assert gpio_sensors.get_gpio_sensor_callback(105) == [2,0,0] 

166 # Tests start here 

167 gpio_sensors.add_gpio_sensor_callback(102, sensor_passed=1) # Success - int and exists 

168 gpio_sensors.add_gpio_sensor_callback("103", signal_passed=1) # Success - str and exists 

169 gpio_sensors.add_gpio_sensor_callback("104", signal_approach=1) # Success - str and exists 

170 gpio_sensors.add_gpio_sensor_callback(105) # Success - int and exists 

171 gpio_sensors.add_gpio_sensor_callback(108, signal_passed=1) # Fail - Does not exist 

172 gpio_sensors.add_gpio_sensor_callback("108", signal_passed=1) # Fail - Does not exist 

173 gpio_sensors.add_gpio_sensor_callback(102.0, signal_passed=1) # Fail - not an int or str 

174 gpio_sensors.add_gpio_sensor_callback(102, signal_passed="1") # Fail - Item not an int 

175 gpio_sensors.add_gpio_sensor_callback(102, signal_approach="1") # Fail - Item not an int 

176 gpio_sensors.add_gpio_sensor_callback(102, sensor_passed="1") # Fail - Item not an int 

177 gpio_sensors.add_gpio_sensor_callback(102, signal_passed=1, signal_approach=1, sensor_passed=1) # Fail - multiple specified 

178 gpio_sensors.add_gpio_sensor_callback(102, signal_passed=1, signal_approach=1) # Fail - multiple specified 

179 gpio_sensors.add_gpio_sensor_callback(102, signal_approach=1, sensor_passed=1) # Fail - multiple specified 

180 gpio_sensors.add_gpio_sensor_callback(102, signal_passed=1, sensor_passed=1) # Fail - multiple specified 

181 assert gpio_sensors.get_gpio_sensor_callback(102) == [0,0,1] 

182 assert gpio_sensors.get_gpio_sensor_callback(103) == [1,0,0] 

183 assert gpio_sensors.get_gpio_sensor_callback(104) == [0,1,0] 

184 assert gpio_sensors.get_gpio_sensor_callback(105) == [0,0,0] 

185 # set_gpio_sensors_to_publish_state 

186 print ("GPIO Sensors - set_gpio_sensors_to_publish_state - will generate 2 warnings and 2 errors") 

187 assert len(gpio_sensors.list_of_track_sensors_to_publish) == 0 

188 gpio_sensors.set_gpio_sensors_to_publish_state(105, 106) # success - int and exists 

189 gpio_sensors.set_gpio_sensors_to_publish_state(200, 201) # success - int but does not yet exist 

190 gpio_sensors.set_gpio_sensors_to_publish_state(105, 106) # sensors already set to publish - will generate warnings 

191 gpio_sensors.set_gpio_sensors_to_publish_state("107", "108") # Fail - not an int 

192 assert len(gpio_sensors.list_of_track_sensors_to_publish) == 4 

193 # gpio_sensor_triggered - This is an internal function so no need to test invalid inputs 

194 print ("GPIO Sensors - Sensor triggering tests - Triggering Sensors 105, 106, 107") 

195 print ("GPIO Sensors - Will generate 3 Errors (signals / Track Sensors not existing)") 

196 # Set up the initial state for the tests 

197 gpio_sensors.add_gpio_sensor_callback(105, signal_passed=1) 

198 gpio_sensors.add_gpio_sensor_callback(106, signal_approach=2) 

199 gpio_sensors.add_gpio_sensor_callback(107, sensor_passed=3) 

200 # Tests start here 

201 gpio_sensors.gpio_sensor_triggered(9, testing=True) # Port number for GPIO Sensor 105 (timeout=0.0) 

202 gpio_sensors.gpio_sensor_triggered(10, testing=True) # Port number for GPIO Sensor 106 (timeout=3.0) 

203 gpio_sensors.gpio_sensor_triggered(11, testing=True) # Port number for GPIO Sensor 107 (timeout=2.0) 

204 system_test_harness.sleep(1.0) 

205 print ("GPIO Sensors - Re-triggering Sensor 105 (which will have time out) - Sensors 106 and 107 will be extended") 

206 print ("GPIO Sensors - Will generate 1 Error (signal 1 not existing)") 

207 gpio_sensors.gpio_sensor_triggered(9, testing=True) # Port number for GPIO Sensor 105 (timeout=0.0) 

208 gpio_sensors.gpio_sensor_triggered(10, testing=True) # Port number for GPIO Sensor 106 (timeout=3.0) 

209 gpio_sensors.gpio_sensor_triggered(11, testing=True) # Port number for GPIO Sensor 107 (timeout=2.0) 

210 system_test_harness.sleep(2.5) 

211 print ("GPIO Sensors - Re-triggering Sensors 105, 107 (which will have time out) - Sensors 106 will be extended") 

212 print ("GPIO Sensors - Will generate 2 Errors (signal 1 / Track Sensor 3 not existing)") 

213 gpio_sensors.gpio_sensor_triggered(9, testing=True) # Port number for GPIO Sensor 105 (timeout=0.0) 

214 gpio_sensors.gpio_sensor_triggered(10, testing=True) # Port number for GPIO Sensor 106 (timeout=3.0) 

215 gpio_sensors.gpio_sensor_triggered(11, testing=True) # Port number for GPIO Sensor 107 (timeout=2.0) 

216 system_test_harness.sleep(3.5) 

217 print ("GPIO Sensors - End of sensor triggering tests - all sensors should have timed out") 

218 # subscribe_to_remote_gpio_sensor 

219 print ("GPIO Sensors - subscribe_to_remote_gpio_sensor - Will generate 1 warning and 10 Errors") 

220 assert len(gpio_sensors.gpio_port_mappings) == 8 

221 gpio_sensors.subscribe_to_remote_gpio_sensor("box1-200") # Success - valid remote ID 

222 gpio_sensors.subscribe_to_remote_gpio_sensor("box1-201", signal_passed=1) # Success 

223 gpio_sensors.subscribe_to_remote_gpio_sensor("box1-202", signal_approach=1) # Success 

224 gpio_sensors.subscribe_to_remote_gpio_sensor("box1-203", sensor_passed=1) # Success 

225 gpio_sensors.subscribe_to_remote_gpio_sensor("box1-200") # Warning - This is a duplicate 

226 gpio_sensors.subscribe_to_remote_gpio_sensor(120) # Fail - not a string 

227 gpio_sensors.subscribe_to_remote_gpio_sensor("box1") # Fail - not valid remote ID 

228 gpio_sensors.subscribe_to_remote_gpio_sensor("200") # Fail - not valid remote ID 

229 gpio_sensors.subscribe_to_remote_gpio_sensor("box1-201", signal_passed="1") # Fail - not an int 

230 gpio_sensors.subscribe_to_remote_gpio_sensor("box1-201", signal_approach="1") # Fail - not an int 

231 gpio_sensors.subscribe_to_remote_gpio_sensor("box1-201", sensor_passed="1") # Fail - not an int 

232 gpio_sensors.subscribe_to_remote_gpio_sensor("box1-201", signal_passed=1, signal_approach=1, sensor_passed=1) # Fail - multiple specified 

233 gpio_sensors.subscribe_to_remote_gpio_sensor("box1-201", signal_passed=1, signal_approach=1) # Fail - multiple specified 

234 gpio_sensors.subscribe_to_remote_gpio_sensor("box1-201", signal_approach=1, sensor_passed=1) # Fail - multiple specified 

235 gpio_sensors.subscribe_to_remote_gpio_sensor("box1-101", signal_passed=1, sensor_passed=1) # Fail - multiple specified 

236 assert gpio_sensors.gpio_sensor_exists("box1-200") 

237 assert gpio_sensors.gpio_sensor_exists("box1-201") 

238 assert gpio_sensors.gpio_sensor_exists("box1-202") 

239 assert gpio_sensors.gpio_sensor_exists("box1-203") 

240 assert len(gpio_sensors.gpio_port_mappings) == 12 

241 # Check the callbacks have been setup correctly 

242 assert gpio_sensors.get_gpio_sensor_callback("box1-200") == [0,0,0] 

243 assert gpio_sensors.get_gpio_sensor_callback("box1-201") == [1,0,0] 

244 assert gpio_sensors.get_gpio_sensor_callback("box1-202") == [0,1,0] 

245 assert gpio_sensors.get_gpio_sensor_callback("box1-203") == [0,0,1] 

246 # Test the triggering of remote sensors: 

247 print ("GPIO Sensors - handle_mqtt_gpio_sensor_triggered_event - will generate 3 errors and 2 warnings") 

248 gpio_sensors.handle_mqtt_gpio_sensor_triggered_event({"sourceidentifier": "box1-200"}) 

249 gpio_sensors.handle_mqtt_gpio_sensor_triggered_event({"sourceidentifier": "box1-201"}) 

250 gpio_sensors.handle_mqtt_gpio_sensor_triggered_event({"sourceidentifier": "box1-202"}) 

251 gpio_sensors.handle_mqtt_gpio_sensor_triggered_event({"sourceidentifier": "box1-203"}) 

252 gpio_sensors.handle_mqtt_gpio_sensor_triggered_event({"wrongkey": "box1-200"}) # Fail - spurious message 

253 gpio_sensors.handle_mqtt_gpio_sensor_triggered_event({"sourceidentifier": "box1-150"}) # Fail - not subscribed 

254 system_test_harness.sleep (1.0) 

255 # reset_mqtt_configuration (all remote sensors will be deleted) 

256 print ("GPIO Sensors - reset_mqtt_configuration") 

257 gpio_sensors.reset_mqtt_configuration() 

258 assert len(gpio_sensors.gpio_port_mappings) == 8 

259 assert not gpio_sensors.gpio_sensor_exists("box1-200") 

260 assert not gpio_sensors.gpio_sensor_exists("box1-201") 

261 assert not gpio_sensors.gpio_sensor_exists("box1-202") 

262 assert not gpio_sensors.gpio_sensor_exists("box1-203") 

263 assert gpio_sensors.gpio_sensor_exists(100) 

264 assert gpio_sensors.gpio_sensor_exists(101) 

265 assert gpio_sensors.gpio_sensor_exists(102) 

266 assert gpio_sensors.gpio_sensor_exists(103) 

267 assert gpio_sensors.gpio_sensor_exists(104) 

268 assert gpio_sensors.gpio_sensor_exists(105) 

269 assert gpio_sensors.gpio_sensor_exists(106) 

270 assert gpio_sensors.gpio_sensor_exists(107) 

271 print ("GPIO Sensors - delete_all_local_gpio_sensors") 

272 # Subscribe to remote sensors to test delete of local sensors 

273 gpio_sensors.subscribe_to_remote_gpio_sensor("box1-200") 

274 gpio_sensors.subscribe_to_remote_gpio_sensor("box1-201") 

275 assert len(gpio_sensors.gpio_port_mappings) == 10 

276 # delete_all_local_gpio_sensors 

277 gpio_sensors.delete_all_local_gpio_sensors() 

278 assert not gpio_sensors.gpio_sensor_exists(100) 

279 assert not gpio_sensors.gpio_sensor_exists(101) 

280 assert not gpio_sensors.gpio_sensor_exists(102) 

281 assert not gpio_sensors.gpio_sensor_exists(103) 

282 assert not gpio_sensors.gpio_sensor_exists(104) 

283 assert not gpio_sensors.gpio_sensor_exists(105) 

284 assert not gpio_sensors.gpio_sensor_exists(106) 

285 assert not gpio_sensors.gpio_sensor_exists(107) 

286 assert gpio_sensors.gpio_sensor_exists("box1-200") 

287 assert gpio_sensors.gpio_sensor_exists("box1-201") 

288 assert len(gpio_sensors.gpio_port_mappings) == 2 

289 gpio_sensors.reset_mqtt_configuration() 

290 assert len(gpio_sensors.gpio_port_mappings) == 0 

291 # gpio_shutdown 

292 print ("GPIO Sensors - gpio_shutdown immediately after a trigger event") 

293 gpio_sensors.create_gpio_sensor(100, 4) 

294 gpio_sensors.gpio_sensor_triggered(4, testing=True) 

295 gpio_sensors.gpio_shutdown() 

296 gpio_sensors.gpio_sensor_triggered(4, testing=True) 

297 print("----------------------------------------------------------------------------------------") 

298 print("") 

299 return() 

300 

301#--------------------------------------------------------------------------------------------------------- 

302# Test Point Library objects 

303#--------------------------------------------------------------------------------------------------------- 

304 

305def point_callback(point_id, callback_type): 

306 logging_string="Point Callback from Point "+str(point_id)+"-"+str(callback_type) 

307 logging.info(logging_string) 

308 

309def run_point_library_tests(): 

310 # Test all functions - including negative tests for parameter validation 

311 print("Library Tests - Point Objects") 

312 canvas = schematic.canvas 

313 # create_point 

314 assert len(points.points) == 0 

315 # Point ID and point_type combinations 

316 print("Library Tests - create_point - will generate 7 errors:") 

317 points.create_point(canvas, 100, points.point_type.RH, 100, 100, point_callback) # Valid 

318 points.create_point(canvas, 101, points.point_type.LH, 200, 100, point_callback, auto=True) # Valid 

319 points.create_point(canvas, 102, points.point_type.RH, 300, 100, point_callback, also_switch=101) # Valid 

320 points.create_point(canvas, 103, points.point_type.LH, 400, 100, point_callback, auto=True) # Valid 

321 points.create_point(canvas, 104, points.point_type.LH, 500, 100, point_callback, fpl=True) # Valid 

322 points.create_point(canvas, 0, points.point_type.RH, 100, 100, point_callback) 

323 points.create_point(canvas, "100", points.point_type.RH,100, 100, point_callback) 

324 points.create_point(canvas, 100, points.point_type.RH, 100, 100, point_callback) 

325 points.create_point(canvas, 105, "random-type", 100, 100, point_callback) 

326 # Alsoswitch combinations 

327 points.create_point(canvas, 106, points.point_type.LH, 100, 100, point_callback, also_switch="100") 

328 points.create_point(canvas, 107, points.point_type.LH, 100, 100, point_callback, also_switch=107) 

329 # Automatic and FPL combinations 

330 points.create_point(canvas, 108, points.point_type.LH, 100, 100, point_callback, auto=True, fpl=True) 

331 assert len(points.points) == 5 

332 # point_exists 

333 print("Library Tests - point_exists - will generate 1 error:") 

334 assert points.point_exists(100) 

335 assert points.point_exists(101) 

336 assert points.point_exists(102) 

337 assert points.point_exists(103) 

338 assert points.point_exists(104) 

339 assert not points.point_exists(105) 

340 assert not points.point_exists(106) 

341 assert not points.point_exists(107) 

342 assert not points.point_exists(108) 

343 assert not points.point_exists("100") # Invalid 

344 # toggle_point and point/fpl state 

345 print("Library Tests - point_switched - will generate 2 errors:") 

346 assert not points.point_switched(100) 

347 assert not points.point_switched(101) 

348 assert not points.point_switched(102) 

349 assert not points.point_switched(103) 

350 assert not points.point_switched(104) 

351 assert not points.point_switched("100") # Invalid 

352 assert not points.point_switched(105) # Does not exist 

353 print("Library Tests - fpl_active - will generate 2 errors:") 

354 assert points.fpl_active(100) 

355 assert points.fpl_active(101) 

356 assert points.fpl_active(102) 

357 assert points.fpl_active(103) 

358 assert points.fpl_active(104) 

359 assert not points.fpl_active("100") # Invalid 

360 assert not points.fpl_active(105) # Does not exist 

361 print("Library Tests - toggle_point to 'switched' - will generate 3 errors and 1 warning:") 

362 points.toggle_point(100) 

363 points.toggle_point(102) # 102 will autoswitch 101 

364 points.toggle_point(104) # 104 has FPL so will generate warning 

365 points.toggle_point(103) # 103 is auto so will generate error 

366 points.toggle_point("100") # Invalid 

367 points.toggle_point(105) # Does not exist 

368 print("Library Tests - toggle_point to 'normal' - will generate 1 error and 1 warning:") 

369 assert points.point_switched(100) 

370 assert points.point_switched(101) 

371 assert points.point_switched(102) 

372 assert not points.point_switched(103) 

373 assert points.point_switched(104) 

374 points.lock_point(104) 

375 points.toggle_point(100) 

376 points.toggle_point(102) # 102 will autoswitch 101 

377 points.toggle_point(103) # 103 is auto so will generate error 

378 points.toggle_point(104) # 104 has FPL so will generate warning 

379 points.unlock_point(104) 

380 assert not points.point_switched(100) 

381 assert not points.point_switched(101) 

382 assert not points.point_switched(102) 

383 assert not points.point_switched(103) 

384 assert not points.point_switched(104) 

385 # FPL specific tests 

386 print("Library Tests - toggle_fpl - will generate 3 errors and 2 warnings:") 

387 points.toggle_fpl("100") # Invalid 

388 points.toggle_fpl(100) # No FPL 

389 points.toggle_fpl(105) # Does not exist 

390 assert points.fpl_active(104) 

391 points.toggle_fpl(104) # Has FPL - toggle off FPL 

392 assert not points.fpl_active(104) 

393 points.toggle_point(104) # Has FPL - switch point 

394 assert points.point_switched(104) 

395 points.toggle_point(104) # Has FPL - switch pointback to 'normal' 

396 assert not points.point_switched(104) 

397 points.lock_point(104) # Will activate FPL with a warning 

398 points.toggle_fpl(104) # Toggle FPL to OFF with point locked - will generate warning 

399 assert not points.fpl_active(104) 

400 points.unlock_point(104) 

401 # Test the button callback functions 

402 print("Library Tests - Point button callback functions:") 

403 assert not points.fpl_active(104) 

404 points.change_button_event(104) # Has FPL - switch point 

405 assert points.point_switched(104) 

406 points.change_button_event(104) # Has FPL - switch pointback to 'normal' 

407 assert not points.point_switched(104) 

408 points.fpl_button_event(104) # Has FPL - toggle on FPL 

409 assert points.fpl_active(104) 

410 # Note we leave the FPL off for the next tests to generate warnings 

411 points.fpl_button_event(104) # Has FPL - toggle off FPL 

412 # Lock Point 

413 print("Library Tests - lock_point - will generate 2 errors and 1 warning:") 

414 assert points.points[str(100)]['locked']==False 

415 assert points.points[str(104)]['locked']==False 

416 points.lock_point("100") # Invalid 

417 points.lock_point(105) # Does not exist 

418 points.lock_point(100) 

419 points.lock_point(104) 

420 points.lock_point(104) 

421 assert points.points[str(100)]['locked']==True 

422 assert points.points[str(104)]['locked']==True 

423 print("Library Tests - unlock_point - will generate 2 errors:") 

424 points.unlock_point("100") # Invalid 

425 points.unlock_point(105) # Does not exist 

426 points.unlock_point(100) 

427 points.unlock_point(104) 

428 points.unlock_point(104) 

429 assert points.points[str(100)]['locked']==False 

430 assert points.points[str(104)]['locked']==False 

431 # Update autoswitch 

432 print("Library Tests - update_autoswitch - will generate 4 errors:") 

433 points.update_autoswitch("100", 103) 

434 points.update_autoswitch(105, 103) # Point 105 does not exist 

435 points.update_autoswitch(102, "109") 

436 points.update_autoswitch(102, 105) 

437 points.toggle_point(102) # 102 was autoswitching 101 

438 assert points.point_switched(102) 

439 assert not points.point_switched(103) 

440 points.update_autoswitch(102, 103) 

441 assert points.point_switched(102) 

442 assert points.point_switched(103) 

443 points.toggle_point(102) 

444 assert not points.point_switched(102) 

445 assert not points.point_switched(103) 

446 print("Library Tests - update_autoswitch to a non-auto point - will generate 2 errors:") 

447 points.update_autoswitch(102, 100) 

448 points.toggle_point(102) 

449 assert points.point_switched(102) 

450 assert not points.point_switched(100) 

451 # delete point  

452 print("Library Tests - delete_point - will generate 2 errors:") 

453 assert len(points.points) == 5 

454 points.delete_point("100") 

455 points.delete_point(105) # Point 105 does not exist 

456 points.delete_point(100) 

457 points.delete_point(101) 

458 points.delete_point(103) 

459 points.delete_point(104) 

460 assert not points.point_exists(100) 

461 assert not points.point_exists(101) 

462 assert not points.point_exists(103) 

463 assert not points.point_exists(104) 

464 assert len(points.points) == 1 

465 print("Library Tests - autoswitch a deleted point - will generate 1 error:") 

466 points.toggle_point(102) 

467 points.delete_point(102) 

468 assert not points.point_exists(102) 

469 assert len(points.points) == 0 

470 print("Library Tests - create autoswitched point - will generate 1 warning:") 

471 points.create_point(canvas, 100, points.point_type.LH, 100, 100, point_callback, also_switch=101) # Valid 

472 points.toggle_point_state(100) 

473 points.create_point(canvas, 101, points.point_type.LH, 200, 100, point_callback, auto=True) # Valid 

474 assert len(points.points) == 2 

475 assert points.point_switched(100) 

476 assert points.point_switched(101) 

477 points.create_point(canvas, 102, points.point_type.LH, 300, 100, point_callback, also_switch=101) # Valid 

478 assert points.point_switched(100) 

479 assert not points.point_switched(101) 

480 assert not points.point_switched(101) 

481 print("Library Tests - clean up by deleting all points") 

482 points.delete_point(100) 

483 points.delete_point(101) 

484 points.delete_point(102) 

485 assert len(points.points) == 0 

486 print("----------------------------------------------------------------------------------------") 

487 print("") 

488 return() 

489 

490#--------------------------------------------------------------------------------------------------------- 

491# Test Block Instrument Library objects 

492#--------------------------------------------------------------------------------------------------------- 

493 

494def instrument_callback(instrument_id, callback_type): 

495 logging_string="Instrument Callback from Instrument "+str(instrument_id)+"-"+str(callback_type) 

496 logging.info(logging_string) 

497 

498def run_instrument_library_tests(): 

499 # Test all functions - including negative tests for parameter validation 

500 print("Library Tests - Instrument Objects") 

501 canvas = schematic.canvas 

502 # create_instrument 

503 print("Library Tests - create_instrument - 6 Errors and 4 warnings will be generated") 

504 assert len(block_instruments.instruments) == 0 

505 # Sunny day tests 

506 block_instruments.create_instrument(canvas, 1, block_instruments.instrument_type.single_line, 100, 100, instrument_callback, linked_to="2") 

507 block_instruments.create_instrument(canvas, 2, block_instruments.instrument_type.single_line, 200, 100, instrument_callback, linked_to="1") 

508 block_instruments.create_instrument(canvas, 3, block_instruments.instrument_type.double_line, 300, 100, instrument_callback, linked_to="4") 

509 block_instruments.create_instrument(canvas, 4, block_instruments.instrument_type.double_line, 400, 100, instrument_callback, linked_to="3") 

510 block_instruments.create_instrument(canvas, 5, block_instruments.instrument_type.double_line, 500, 100, instrument_callback, linked_to="box1-5") 

511 block_instruments.create_instrument(canvas, 6, block_instruments.instrument_type.single_line, 600, 100, instrument_callback, linked_to="9") 

512 # Raise a warning because Instrument 6 is already linked to instrument 9 

513 block_instruments.create_instrument(canvas, 7, block_instruments.instrument_type.single_line, 700, 100, instrument_callback, linked_to="9") # warning 

514 # Raise a warning because Instrument 5 is linked back to a completely different instrument (instrument "box1-5") 

515 block_instruments.create_instrument(canvas, 8, block_instruments.instrument_type.single_line, 800, 100, instrument_callback, linked_to="5") # Warning 

516 # Raise a warning because we are linking to instrument 8 but Instruments 6 and 7 are already linked to back to 'our' instrument 

517 block_instruments.create_instrument(canvas, 9, block_instruments.instrument_type.single_line, 900, 100, instrument_callback, linked_to="10") # Warning 

518 # Rainy day tests: 

519 block_instruments.create_instrument(canvas, 0, block_instruments.instrument_type.single_line, 100, 100, instrument_callback, linked_to="10") # Fail (int <1) 

520 block_instruments.create_instrument(canvas, 4, block_instruments.instrument_type.single_line, 100, 100, instrument_callback, linked_to="10") # Fail (Exists) 

521 block_instruments.create_instrument(canvas, "10", block_instruments.instrument_type.single_line, 100, 100, instrument_callback, linked_to="10") # Fail (str) 

522 block_instruments.create_instrument(canvas, 10, "random_type", 100, 100, instrument_callback, linked_to="2") # Fail 

523 block_instruments.create_instrument(canvas, 11, block_instruments.instrument_type.single_line, 100, 100, instrument_callback, linked_to=10) # Fail 

524 block_instruments.create_instrument(canvas, 12, block_instruments.instrument_type.single_line, 100, 100, instrument_callback, linked_to="box1") # Fail 

525 assert len(block_instruments.instruments) == 9 

526 print("Library Tests - instrument_exists - 1 Error will be generated") 

527 assert block_instruments.instrument_exists("1") 

528 assert block_instruments.instrument_exists("2") 

529 assert block_instruments.instrument_exists("3") 

530 assert block_instruments.instrument_exists("4") 

531 assert block_instruments.instrument_exists(5) 

532 assert block_instruments.instrument_exists(6) 

533 assert block_instruments.instrument_exists(7) 

534 assert block_instruments.instrument_exists(8) 

535 assert block_instruments.instrument_exists(9) 

536 assert not block_instruments.instrument_exists("10") 

537 assert not block_instruments.instrument_exists(10) 

538 assert not block_instruments.instrument_exists(10.1) 

539 print("Library Tests - block_section_ahead_clear - Part 1 - 2 Errors will be generated") 

540 assert not block_instruments.block_section_ahead_clear(1) 

541 assert not block_instruments.block_section_ahead_clear(2) 

542 assert not block_instruments.block_section_ahead_clear(3) 

543 assert not block_instruments.block_section_ahead_clear(4) 

544 assert not block_instruments.block_section_ahead_clear("5") 

545 assert not block_instruments.block_section_ahead_clear(10) 

546 print("Library Tests - block_section_ahead_clear - Part 2 - Testing instrument states (no errors or warnings)") 

547 block_instruments.clear_button_event(1) 

548 block_instruments.clear_button_event(3) 

549 block_instruments.clear_button_event(3) 

550 assert block_instruments.block_section_ahead_clear(2) 

551 assert block_instruments.block_section_ahead_clear(4) 

552 assert not block_instruments.block_section_ahead_clear(1) 

553 assert not block_instruments.block_section_ahead_clear(3) 

554 block_instruments.occup_button_event(1) 

555 block_instruments.occup_button_event(3) 

556 block_instruments.occup_button_event(3) 

557 assert not block_instruments.block_section_ahead_clear(1) 

558 assert not block_instruments.block_section_ahead_clear(2) 

559 assert not block_instruments.block_section_ahead_clear(3) 

560 assert not block_instruments.block_section_ahead_clear(4) 

561 block_instruments.blocked_button_event(1) 

562 block_instruments.blocked_button_event(3) 

563 block_instruments.blocked_button_event(3) 

564 assert not block_instruments.block_section_ahead_clear(1) 

565 assert not block_instruments.block_section_ahead_clear(2) 

566 assert not block_instruments.block_section_ahead_clear(3) 

567 assert not block_instruments.block_section_ahead_clear(4) 

568 block_instruments.clear_button_event(2) 

569 block_instruments.clear_button_event(4) 

570 assert block_instruments.block_section_ahead_clear(1) 

571 assert block_instruments.block_section_ahead_clear(3) 

572 assert not block_instruments.block_section_ahead_clear(2) 

573 assert not block_instruments.block_section_ahead_clear(4) 

574 block_instruments.blocked_button_event(2) 

575 block_instruments.blocked_button_event(4) 

576 print("Library Tests - update_linked_instrument - 5 Errors and 5 warnings will be generated") 

577 # Clear down the spurious linkings 

578 block_instruments.update_linked_instrument(5,"") 

579 block_instruments.update_linked_instrument(6,"") 

580 block_instruments.update_linked_instrument(7,"") 

581 block_instruments.update_linked_instrument(8,"") 

582 block_instruments.update_linked_instrument(9,"") 

583 # Make the new linkings 

584 block_instruments.update_linked_instrument(5,"4") 

585 block_instruments.update_linked_instrument(4,"5") 

586 block_instruments.update_linked_instrument(1,"6") 

587 block_instruments.update_linked_instrument(6,"1") 

588 block_instruments.update_linked_instrument(4,"4") # Fail - same ID 

589 block_instruments.update_linked_instrument(10,"7") # Fail -Inst ID does not exist 

590 block_instruments.update_linked_instrument("1","2") # Fail - Inst ID not an int 

591 block_instruments.update_linked_instrument(1,2) # Fail - Linked ID not a str 

592 block_instruments.update_linked_instrument(1,"box1") # Fail - linked ID npot valid remote ID 

593 print("Library Tests - set_instruments_to_publish_state - 3 Errors and 4 warnings will be generated") 

594 assert len(block_instruments.list_of_instruments_to_publish) == 0 

595 block_instruments.set_instruments_to_publish_state(1,2,5,20) 

596 block_instruments.set_instruments_to_publish_state(1,2,5,20) # Already set to publish - 4 warnings 

597 block_instruments.set_instruments_to_publish_state("1,","2") # Not integers - 2 Errors 

598 block_instruments.set_instruments_to_publish_state(0) # Integer but < 1 - 1 Error 

599 assert len(block_instruments.list_of_instruments_to_publish) == 4 

600 print("Library Tests - set_instruments_to_publish_state - Exercise Publishing of Events code") 

601 # Clear down the existing linked instruments first 

602 block_instruments.update_linked_instrument(4,"") 

603 block_instruments.update_linked_instrument(1,"") 

604 block_instruments.update_linked_instrument(5,"Box2-150") 

605 block_instruments.update_linked_instrument(6,"Box2-160") 

606 block_instruments.clear_button_event(5) 

607 block_instruments.blocked_button_event(5) 

608 block_instruments.telegraph_key_button(5) 

609 block_instruments.clear_button_event(6) 

610 block_instruments.blocked_button_event(6) 

611 block_instruments.telegraph_key_button(6) 

612 print("Library Tests - subscribe_to_remote_instrument - 3 Errors and 1 Warning will be generated") 

613 block_instruments.subscribe_to_remote_instrument("box2-200") 

614 block_instruments.subscribe_to_remote_instrument("box2-200") # Warning - This is a duplicate 

615 block_instruments.subscribe_to_remote_instrument(120) # Fail - not a string 

616 block_instruments.subscribe_to_remote_instrument("box2") # Fail - not valid remote ID 

617 block_instruments.subscribe_to_remote_instrument("200") # Fail - not valid remote ID 

618 assert len(block_instruments.instruments) == 10 

619 assert block_instruments.instrument_exists("box2-200") 

620 print("Library Tests - handle_mqtt_instrument_updated_event - 5 Warnings will be generated") 

621 assert not block_instruments.block_section_ahead_clear(1) 

622 block_instruments.handle_mqtt_instrument_updated_event({"sourceidentifier": "box2-200", "sectionstate": True, "instrumentid":"box1-1" }) 

623 assert block_instruments.block_section_ahead_clear(1) 

624 block_instruments.handle_mqtt_instrument_updated_event({"sourceidentifier": "box2-200", "sectionstate": False, "instrumentid":"box1-1" }) 

625 assert not block_instruments.block_section_ahead_clear(1) 

626 block_instruments.handle_mqtt_instrument_updated_event({"sourceidentifier": "box2-200", "sectionstate": None, "instrumentid":"box1-1" }) 

627 assert not block_instruments.block_section_ahead_clear(1) 

628 block_instruments.handle_mqtt_instrument_updated_event({"sourceidentifier":"box2-200","sectionstate":None,"instrumentid":"random" }) # Invalid ID 

629 block_instruments.handle_mqtt_instrument_updated_event({"sourceidentifier":"box2-150","sectionstate":False,"instrumentid":"box1-1"}) # Not subscribed 

630 block_instruments.handle_mqtt_instrument_updated_event({"sourceidentifier":"box2-150","instrumentid":"box1-1"}) # Fail - spurious message 

631 block_instruments.handle_mqtt_instrument_updated_event({"sectionstate": False, "instrumentid":"box1-1"}) # Fail - spurious message 

632 block_instruments.handle_mqtt_instrument_updated_event({"sourceidentifier":"box2-150","sectionstate": False}) # Fail - spurious message 

633 print("Library Tests - handle_mqtt_ring_section_bell_event - 4 Warnings will be generated") 

634 block_instruments.handle_mqtt_ring_section_bell_event({"sourceidentifier": "box2-200", "instrumentid":"box1-1" }) 

635 block_instruments.handle_mqtt_ring_section_bell_event({"sourceidentifier": "box2-200", "instrumentid":"box1-1" }) 

636 block_instruments.handle_mqtt_ring_section_bell_event({"sourceidentifier": "box2-200", "instrumentid":"box1-1" }) 

637 block_instruments.handle_mqtt_ring_section_bell_event({"sourceidentifier": "box2-200", "instrumentid":"random" }) # Invalid ID 

638 block_instruments.handle_mqtt_ring_section_bell_event({"sourceidentifier": "box2-150", "sectionstate": False}) # Not subscribed 

639 block_instruments.handle_mqtt_ring_section_bell_event({"instrumentid": "box2-1"}) # Fail - spurious message 

640 block_instruments.handle_mqtt_ring_section_bell_event({"sourceidentifier": "box2-200"}) # Fail - spurious message 

641 print("Library Tests - reset_mqtt_configuration (all subscribed instruments will be deleted)") 

642 block_instruments.reset_mqtt_configuration() 

643 assert len(block_instruments.list_of_instruments_to_publish) == 0 

644 assert len(block_instruments.instruments) == 9 

645 assert not block_instruments.instrument_exists("box1-200") 

646 print("Library Tests - delete_instrument - 2 Errors will be generated") 

647 block_instruments.delete_instrument(1) 

648 block_instruments.delete_instrument(2) 

649 block_instruments.delete_instrument(3) 

650 block_instruments.delete_instrument(4) 

651 block_instruments.delete_instrument(5) 

652 block_instruments.delete_instrument(6) 

653 block_instruments.delete_instrument(7) 

654 block_instruments.delete_instrument(8) 

655 block_instruments.delete_instrument(9) 

656 assert len(block_instruments.instruments) == 0 

657 assert not block_instruments.instrument_exists(1) 

658 assert not block_instruments.instrument_exists(2) 

659 assert not block_instruments.instrument_exists(3) 

660 assert not block_instruments.instrument_exists(4) 

661 assert not block_instruments.instrument_exists(5) 

662 assert not block_instruments.instrument_exists(6) 

663 assert not block_instruments.instrument_exists(7) 

664 assert not block_instruments.instrument_exists(8) 

665 assert not block_instruments.instrument_exists(9) 

666 block_instruments.delete_instrument(10) # Fail 

667 block_instruments.delete_instrument("10") # Fail 

668 print("----------------------------------------------------------------------------------------") 

669 print("") 

670 return() 

671 

672#--------------------------------------------------------------------------------------------------------- 

673# Test Pi-Sprog interface - Requires Harman SC1 to be connected for CV read/write tests (set to address 1) 

674#--------------------------------------------------------------------------------------------------------- 

675 

676def run_pi_sprog_interface_tests(baud_rate): 

677 # Test all functions - including negative tests for parameter validation 

678 print("Library Tests - Pi Sprog Interface Tests") 

679 print("Library Tests - sprog_connect - 3 Errors will be generated") 

680 assert not pi_sprog_interface.sprog_connect (0, 115200) # Fail - Port name not a str 

681 assert not pi_sprog_interface.sprog_connect ("/dev/serial0", "115200") # Fail - Baud Rate not an int 

682 assert not pi_sprog_interface.sprog_connect ("/dev/serial0", baud_rate, "True") # Fail - Debug mode not a bool 

683 assert pi_sprog_interface.sprog_connect ("/dev/serial0", baud_rate, False) # Success 

684 print("Library Tests - sprog_disconnect and reconnect (no errors or warnings)") 

685 assert pi_sprog_interface.sprog_disconnect() 

686 assert pi_sprog_interface.sprog_connect ("/dev/serial0", baud_rate, True) 

687 print("Library Tests - dcc_power_on and dcc_power_off (no errors or warnings)") 

688 assert pi_sprog_interface.request_dcc_power_on() 

689 assert pi_sprog_interface.request_dcc_power_off() 

690 print("Library Tests - service_mode_read_cv - 2 Errors should be generated") 

691 assert pi_sprog_interface.request_dcc_power_on() 

692 assert pi_sprog_interface.service_mode_read_cv("1") is None # Fail 

693 assert pi_sprog_interface.service_mode_read_cv(1024) is None # Fail 

694 cv1_value = pi_sprog_interface.service_mode_read_cv(1) # Success 

695 cv9_value = pi_sprog_interface.service_mode_read_cv(9) # Success 

696 assert cv1_value is not None 

697 assert cv9_value is not None 

698 print("Library Tests - service_mode_write_cv - 4 Errors should be generated") 

699 assert not pi_sprog_interface.service_mode_write_cv("1", 123) # Fail - CV not an int 

700 assert not pi_sprog_interface.service_mode_write_cv(1024, 123) # Fail - CV out of range 

701 assert not pi_sprog_interface.service_mode_write_cv(1, "123") # Fail - Value not an int 

702 assert not pi_sprog_interface.service_mode_write_cv(1, 256) # Fail - Value out of range 

703 print("Library Tests - service_mode_write_cv - Set new values for CV1 and CV9 (no errors or warnings)") 

704 assert pi_sprog_interface.service_mode_write_cv(1, 123) # Success 

705 assert pi_sprog_interface.service_mode_write_cv(9, 255) # Success 

706 print("Library Tests - service_mode_write_cv - Read back the values to confirm (no errors or warnings)") 

707 assert pi_sprog_interface.service_mode_read_cv(1) == 123 # Success 

708 assert pi_sprog_interface.service_mode_read_cv(9) == 255 # Success 

709 print("Library Tests - service_mode_write_cv - Set the values back to what they were (no errors or warnings)") 

710 assert pi_sprog_interface.service_mode_write_cv(1, cv1_value) # Success 

711 assert pi_sprog_interface.service_mode_write_cv(9, cv9_value) # Success 

712 print("Library Tests - service_mode_write_cv - Confirm the values have been set back (no errors or warnings)") 

713 assert pi_sprog_interface.service_mode_read_cv(1) == cv1_value # Success 

714 assert pi_sprog_interface.service_mode_read_cv(9) == cv9_value # Success 

715 assert pi_sprog_interface.request_dcc_power_off() 

716 print("Library Tests - send_accessory_short_event - 3 Errors should be generated") 

717 assert pi_sprog_interface.request_dcc_power_on() 

718 pi_sprog_interface.send_accessory_short_event("1", True) # Fail - address not int 

719 pi_sprog_interface.send_accessory_short_event(2048, True) # Fail - address invalid 

720 pi_sprog_interface.send_accessory_short_event(1, "True") # Fail - state invalid 

721 pi_sprog_interface.send_accessory_short_event(1, True) 

722 pi_sprog_interface.send_accessory_short_event(2, True) 

723 pi_sprog_interface.send_accessory_short_event(3, True) 

724 pi_sprog_interface.send_accessory_short_event(4, True) 

725 pi_sprog_interface.send_accessory_short_event(5, True) 

726 pi_sprog_interface.send_accessory_short_event(6, True) 

727 pi_sprog_interface.send_accessory_short_event(7, True) 

728 pi_sprog_interface.send_accessory_short_event(8, True) 

729 system_test_harness.sleep(0.5) 

730 pi_sprog_interface.send_accessory_short_event(1, False) 

731 system_test_harness.sleep(0.5) 

732 pi_sprog_interface.send_accessory_short_event(2, False) 

733 system_test_harness.sleep(0.5) 

734 pi_sprog_interface.send_accessory_short_event(3, False) 

735 system_test_harness.sleep(0.5) 

736 pi_sprog_interface.send_accessory_short_event(4, False) 

737 system_test_harness.sleep(0.5) 

738 pi_sprog_interface.send_accessory_short_event(5, False) 

739 system_test_harness.sleep(0.5) 

740 pi_sprog_interface.send_accessory_short_event(6, False) 

741 system_test_harness.sleep(0.5) 

742 pi_sprog_interface.send_accessory_short_event(7, False) 

743 system_test_harness.sleep(0.5) 

744 pi_sprog_interface.send_accessory_short_event(8, False) 

745 system_test_harness.sleep(1.0) 

746 print("Library Tests - negative tests - sending commands when DCC power is OFF - 2 Warnings will be generated") 

747 assert pi_sprog_interface.request_dcc_power_off() 

748 pi_sprog_interface.send_accessory_short_event(8, True) 

749 pi_sprog_interface.send_accessory_short_event(8, False) 

750 assert pi_sprog_interface.service_mode_read_cv(1) is None 

751 assert not pi_sprog_interface.service_mode_write_cv(1,255) 

752 print("Library Tests - negative tests - sending commands when port is closed - 4 Warnings will be generated") 

753 assert pi_sprog_interface.sprog_disconnect() 

754 assert not pi_sprog_interface.request_dcc_power_on() 

755 pi_sprog_interface.send_accessory_short_event(8, True) 

756 pi_sprog_interface.send_accessory_short_event(8, False) 

757 assert pi_sprog_interface.service_mode_read_cv(1) is None 

758 assert not pi_sprog_interface.service_mode_write_cv(1,255) 

759 assert not pi_sprog_interface.request_dcc_power_off() 

760 print("Library Tests - Sprog Shutdown (no errors or warnings)") 

761 pi_sprog_interface.sprog_shutdown() 

762 pi_sprog_interface.sprog_shutdown() 

763 print("----------------------------------------------------------------------------------------") 

764 print("") 

765 return() 

766 

767#--------------------------------------------------------------------------------------------------------- 

768# Test DCC Control interface 

769#--------------------------------------------------------------------------------------------------------- 

770 

771def run_dcc_control_tests(baud_rate): 

772 # Test all functions - including negative tests for parameter validation 

773 print("Library Tests - DCC control Tests - connecting to SPROG first") 

774 assert pi_sprog_interface.sprog_connect ("/dev/serial0", baud_rate) 

775 assert pi_sprog_interface.request_dcc_power_on() 

776 print("Library Tests - map_dcc_signal - one Debug message - rest are Errors") 

777 assert len(dcc_control.dcc_signal_mappings) == 0 

778 assert len(dcc_control.dcc_address_mappings) == 0 

779 dcc_control.map_dcc_signal(1, auto_route_inhibit=False, 

780 danger = [[1,True], [2,True], [3,False]], 

781 proceed = [[1,True], [2,False], [3,False] ], 

782 caution = [[1,True], [2,False], [3,False] ], 

783 prelim_caution = [[1,False], [2,True], [3,True] ], 

784 flash_caution = [[1,False], [2,True], [3,False] ], 

785 flash_prelim_caution = [[1,False], [2,False], [3,True] ], 

786 MAIN = [[4,True], [5,True], [6,False]], 

787 LH1 = [[4,True], [5,False], [6,False] ], 

788 LH2 = [[4,True], [5,False], [6,False] ], 

789 RH1 = [[4,False], [5,True], [6,True] ], 

790 RH2 = [[4,False], [5,True], [6,False] ], 

791 NONE = [[4,False], [5,False], [6,True] ], 

792 THEATRE = [ ['#', [[4,True], [5,True], [6,False]]], 

793 ['1', [[4,True], [5,False], [6,False]] ], 

794 ['2', [[4,True], [5,False], [6,False]] ], 

795 ['3', [[4,False], [5,True], [6,True]] ], 

796 ['4', [[4,False], [5,True], [6,False]] ], 

797 ['5', [[4,False], [5,False], [6,True]] ] ], 

798 subsidary = 7 ) 

799 # Negative tests - all will fail with errors 

800 dcc_control.map_dcc_signal(0) # Fail - out of range 

801 dcc_control.map_dcc_signal(1) # Fail - already exists 

802 dcc_control.map_dcc_signal("2") # Fail - not an int  

803 dcc_control.map_dcc_signal(3, danger = [[1,True], ["abc",True], [11,"random"], [2048, True]] ) 

804 dcc_control.map_dcc_signal(4, proceed = [[1,True], ["abc",True], [11,"random"], [2048, True]] ) 

805 dcc_control.map_dcc_signal(5, caution = [[1,True], ["abc",True], [11,"random"], [2048, True]] ) 

806 dcc_control.map_dcc_signal(6, prelim_caution = [[1,True], ["abc",True], [11,"random"], [2048, True]] ) 

807 dcc_control.map_dcc_signal(7, flash_prelim_caution = [[1,True], ["abc",True], [11,"random"], [2048, True]] ) 

808 dcc_control.map_dcc_signal(8, MAIN = [[1,True], ["abc",True], [11,"random"], [2048, True]] ) 

809 dcc_control.map_dcc_signal(9, LH1 = [[1,True], ["abc",True], [11,"random"], [2048, True]] ) 

810 dcc_control.map_dcc_signal(10, RH1 = [[1,True], ["abc",True], [11,"random"], [2048, True]] ) 

811 dcc_control.map_dcc_signal(11, RH2 = [[1,True], ["abc",True], [11,"random"], [2048, True]] ) 

812 dcc_control.map_dcc_signal(12, NONE = [[1,True], ["abc",True], [11,"random"], [2048, True]] ) 

813 dcc_control.map_dcc_signal(13, MAIN = [[1,True], ["abc",True], [11,"random"], [2048, True]] ) 

814 dcc_control.map_dcc_signal(14, subsidary = 1) 

815 dcc_control.map_dcc_signal(15, subsidary = "abc") 

816 dcc_control.map_dcc_signal(16, subsidary = 2048) 

817 dcc_control.map_dcc_signal(17, THEATRE = [ ['#', [[1,True], ["abc",True], [11,"random"], [2048, True], 2047,[1,2,3]]], 

818 ['2', [[1,True], ["abc",True], [11,"random"], [2048, True], 2047,[1,2,3]]] ] ) 

819 assert len(dcc_control.dcc_signal_mappings) == 1 

820 assert len(dcc_control.dcc_address_mappings) == 7 

821 print("Library Tests - map_semaphore_signal - one Debug message - rest are Errors") 

822 dcc_control.map_semaphore_signal(2, main_signal=10, lh1_signal=11, lh2_signal=12, rh1_signal=13, rh2_signal=14, 

823 main_subsidary=15, lh1_subsidary=16, lh2_subsidary=17, rh1_subsidary=18, rh2_subsidary=19, 

824 THEATRE = [ ['#', [[20,True], [21,True], [22,False]]], 

825 ['1', [[20,True], [21,False], [22,False]] ], 

826 ['2', [[20,True], [21,False], [22,False]] ], 

827 ['3', [[20,False], [21,True], [22,True]] ], 

828 ['4', [[20,False], [21,True], [22,False]] ], 

829 ['5', [[20,False], [21,False], [22,True]] ] ]) 

830 # Negative tests - all will fail with errors 

831 dcc_control.map_semaphore_signal(0) # Fail - out of range 

832 dcc_control.map_semaphore_signal(2) # Fail - already exists 

833 dcc_control.map_semaphore_signal("3") # Fail - not an int  

834 dcc_control.map_semaphore_signal(4, main_signal=1, lh1_signal=2, lh2_signal=3, rh1_signal=4, rh2_signal=5) 

835 dcc_control.map_semaphore_signal(5, main_signal="ab", lh1_signal="cd", lh2_signal="ef", rh1_signal="gh", rh2_signal="jk") 

836 dcc_control.map_semaphore_signal(6, main_signal=2048, lh1_signal=2049, lh2_signal=2050, rh1_signal=2051, rh2_signal=2052) 

837 dcc_control.map_semaphore_signal(7, main_subsidary=2048, lh1_subsidary=2049, lh2_subsidary=2050, rh1_subsidary=2051, rh2_subsidary=2052) 

838 dcc_control.map_semaphore_signal(8, main_subsidary="ab", lh1_subsidary="cd", lh2_subsidary="ef", rh1_subsidary="gh", rh2_subsidary="jk") 

839 dcc_control.map_semaphore_signal(9, main_subsidary=10, lh1_subsidary=11, lh2_subsidary=12, rh1_subsidary=13, rh2_subsidary=14) 

840 dcc_control.map_semaphore_signal(10, THEATRE = [ ['#', [[1,True], ["abc",True], [11,"random"], [2048, True], 2047,[1,2,3]]], 

841 ['2', [[1,True], ["abc",True], [11,"random"], [2048, True], 2047,[1,2,3]]] ] ) 

842 assert len(dcc_control.dcc_signal_mappings) == 2 

843 assert len(dcc_control.dcc_address_mappings) == 20 

844 print("Library Tests - map_dcc_point - Two Debug messages - rest are Errors") 

845 assert len(dcc_control.dcc_point_mappings) == 0 

846 dcc_control.map_dcc_point(1, 30, False) 

847 dcc_control.map_dcc_point(2, 31, True) 

848 dcc_control.map_dcc_point(0, 32, False) # Fail - Invalid ID 

849 dcc_control.map_dcc_point(1, 32, False) # Fail - Duplicate ID 

850 dcc_control.map_dcc_point("3", 32, False) # Fail - ID not an int  

851 dcc_control.map_dcc_point(4, 30, False) # Fail - address already in use  

852 dcc_control.map_dcc_point(5, 10, False) # Fail - address already in use  

853 dcc_control.map_dcc_point(6, "abc", False) # Fail - address not a str  

854 dcc_control.map_dcc_point(6, 2048, False) # Fail - Invalid address  

855 dcc_control.map_dcc_point(7, 33, "True") # Fail - Invalid reversed flag  

856 assert len(dcc_control.dcc_point_mappings) == 2 

857 assert len(dcc_control.dcc_address_mappings) == 22 

858 print("Library Tests - get_dcc_address_mappings (no errors or warnings should be generated)") 

859 mappings = dcc_control.get_dcc_address_mappings() 

860 assert mappings == {1: ['Signal', 1], 2: ['Signal', 1], 3: ['Signal', 1], 4: ['Signal', 1], 

861 5: ['Signal', 1], 6: ['Signal', 1], 7: ['Signal', 1], 10: ['Signal', 2], 

862 15: ['Signal', 2], 11: ['Signal', 2], 16: ['Signal', 2], 13: ['Signal', 2], 

863 18: ['Signal', 2], 12: ['Signal', 2], 17: ['Signal', 2], 14: ['Signal', 2], 

864 19: ['Signal', 2], 20: ['Signal', 2], 21: ['Signal', 2], 22: ['Signal', 2], 

865 30: ['Point', 1], 31: ['Point', 2]} 

866 print("Library Tests - dcc_address_mapping - 2 Errors should be generated)") 

867 assert dcc_control.dcc_address_mapping(1) == ['Signal', 1] 

868 assert dcc_control.dcc_address_mapping(10) == ['Signal', 2] 

869 assert dcc_control.dcc_address_mapping(30) == ['Point', 1] 

870 assert dcc_control.dcc_address_mapping(31) == ['Point', 2] 

871 assert dcc_control.dcc_address_mapping(40) is None 

872 assert dcc_control.dcc_address_mapping("40") is None # Error - not an int 

873 assert dcc_control.dcc_address_mapping(2048) is None # Error - out of range 

874 print("Library Tests - update_dcc_point (no errors or warnings - but DCC commands should be sent)") 

875 dcc_control.update_dcc_point(1, True) 

876 dcc_control.update_dcc_point(1, False) 

877 dcc_control.update_dcc_point(2, True) 

878 dcc_control.update_dcc_point(2, False) 

879 print("Library Tests - update_dcc_signal_aspects - 1 Error - DCC commands should be sent") 

880 dcc_control.update_dcc_signal_aspects(2, signals_common.signal_state_type.DANGER) # Error - wrong type 

881 dcc_control.update_dcc_signal_aspects(1, signals_common.signal_state_type.DANGER) 

882 dcc_control.update_dcc_signal_aspects(1, signals_common.signal_state_type.PROCEED) 

883 dcc_control.update_dcc_signal_aspects(1, signals_common.signal_state_type.CAUTION) 

884 dcc_control.update_dcc_signal_aspects(1, signals_common.signal_state_type.PRELIM_CAUTION) 

885 dcc_control.update_dcc_signal_aspects(1, signals_common.signal_state_type.FLASH_CAUTION) 

886 dcc_control.update_dcc_signal_aspects(1, signals_common.signal_state_type.FLASH_PRELIM_CAUTION) 

887 dcc_control.update_dcc_signal_element(1, True, element="main_subsidary") 

888 dcc_control.update_dcc_signal_aspects(3, signals_common.signal_state_type.DANGER) 

889 print("Library Tests - update_dcc_signal_element - 1 Error - DCC commands should be sent") 

890 dcc_control.update_dcc_signal_element(1, True, element="main_signal") 

891 dcc_control.update_dcc_signal_element(1, True, element="main_subsidary") 

892 dcc_control.update_dcc_signal_element(2, True, element="main_signal") 

893 dcc_control.update_dcc_signal_element(2, True, element="main_subsidary") 

894 dcc_control.update_dcc_signal_element(2, True, element="lh1_signal") 

895 dcc_control.update_dcc_signal_element(2, True, element="lh1_subsidary") 

896 dcc_control.update_dcc_signal_element(2, True, element="lh2_signal") 

897 dcc_control.update_dcc_signal_element(2, True, element="lh2_subsidary") 

898 dcc_control.update_dcc_signal_element(2, True, element="rh1_signal") 

899 dcc_control.update_dcc_signal_element(2, True, element="rh1_subsidary") 

900 dcc_control.update_dcc_signal_element(2, True, element="rh2_signal") 

901 dcc_control.update_dcc_signal_element(2, True, element="rh2_subsidary") 

902 print("Library Tests - update_dcc_signal_route - 1 Error - DCC commands should be sent)") 

903 dcc_control.update_dcc_signal_route(2,signals_common.route_type.MAIN, True, False) 

904 dcc_control.update_dcc_signal_route(1,signals_common.route_type.MAIN, True, False) 

905 dcc_control.update_dcc_signal_route(1,signals_common.route_type.LH1, True, False) 

906 dcc_control.update_dcc_signal_route(1,signals_common.route_type.LH2, True, False) 

907 dcc_control.update_dcc_signal_route(1,signals_common.route_type.RH1, True, False) 

908 dcc_control.update_dcc_signal_route(1,signals_common.route_type.RH2, True, False) 

909 dcc_control.update_dcc_signal_route(1,signals_common.route_type.MAIN, True, True) 

910 dcc_control.update_dcc_signal_route(1,signals_common.route_type.MAIN, False, True) 

911 dcc_control.update_dcc_signal_route(1,signals_common.route_type.MAIN, False, False) 

912 print("Library Tests - update_dcc_signal_theatre (no errors or warnings - DCC commands should be sent)") 

913 dcc_control.update_dcc_signal_theatre(1,"#", True, False) 

914 dcc_control.update_dcc_signal_theatre(1,"1", True, False) 

915 dcc_control.update_dcc_signal_theatre(1,"2", True, False) 

916 dcc_control.update_dcc_signal_theatre(1,"3", True, False) 

917 dcc_control.update_dcc_signal_theatre(1,"4", True, False) 

918 dcc_control.update_dcc_signal_theatre(1,"5", True, False) 

919 dcc_control.update_dcc_signal_theatre(1,"1", True, True) 

920 dcc_control.update_dcc_signal_theatre(1,"1", False, True) 

921 dcc_control.update_dcc_signal_theatre(1,"1", False, False) 

922 print("Library Tests - set_node_to_publish_dcc_commands - 1 Error will be generated ") 

923 dcc_control.set_node_to_publish_dcc_commands("True") # Error 

924 dcc_control.set_node_to_publish_dcc_commands(True) 

925 print("Library Tests - subscribe_to_dcc_command_feed - 1 Error will be generated") 

926 dcc_control.subscribe_to_dcc_command_feed(100) # Error 

927 dcc_control.subscribe_to_dcc_command_feed("Box1") 

928 print("Library Tests - reset_mqtt_configuration - No warnings or errors") 

929 dcc_control.reset_mqtt_configuration() 

930 print("Library Tests - handle_mqtt_dcc_accessory_short_event - 3 Errors - DCC Commands should be sent out") 

931 dcc_control.handle_mqtt_dcc_accessory_short_event({"sourceidentifier": "box1-200", "dccaddress": 1000}) # Error 

932 dcc_control.handle_mqtt_dcc_accessory_short_event({"sourceidentifier": "box1-200", "dccstate": True}) # Error 

933 dcc_control.handle_mqtt_dcc_accessory_short_event({"dccaddress": 1000, "dccstate": True}) # Error 

934 dcc_control.handle_mqtt_dcc_accessory_short_event({"sourceidentifier": "box1-200", "dccaddress": 1000, "dccstate": True}) # Valid 

935 dcc_control.handle_mqtt_dcc_accessory_short_event({"sourceidentifier": "box1-200", "dccaddress": 1000, "dccstate": False}) # Valid 

936 print("Library Tests - delete_point_mapping - 2 Errors shoould be generated") 

937 assert len(dcc_control.dcc_point_mappings) == 2 

938 assert len(dcc_control.dcc_address_mappings) == 22 

939 dcc_control.delete_point_mapping("100") # Error 

940 dcc_control.delete_point_mapping(5) # Error (does not exist) 

941 dcc_control.delete_point_mapping(1) 

942 assert len(dcc_control.dcc_point_mappings) == 1 

943 assert len(dcc_control.dcc_address_mappings) == 21 

944 dcc_control.delete_point_mapping(2) 

945 assert len(dcc_control.dcc_point_mappings) == 0 

946 assert len(dcc_control.dcc_address_mappings) == 20 

947 print("Library Tests - delete_signal_mapping - 2 Errors shoould be generated") 

948 assert len(dcc_control.dcc_signal_mappings) == 2 

949 dcc_control.delete_signal_mapping("100") # Error 

950 dcc_control.delete_signal_mapping(5) # Error (does not exist) 

951 dcc_control.delete_signal_mapping(2) 

952 assert len(dcc_control.dcc_signal_mappings) == 1 

953 assert len(dcc_control.dcc_address_mappings) == 7 

954 dcc_control.delete_signal_mapping(1) 

955 assert len(dcc_control.dcc_signal_mappings) == 0 

956 assert len(dcc_control.dcc_address_mappings) == 0 

957 print("Library Tests - DCC control Tests - disconnecting from SPROG") 

958 system_test_harness.sleep(1.0) # Give the SPROG a chance to send all DCC commands 

959 assert pi_sprog_interface.request_dcc_power_off() 

960 assert pi_sprog_interface.sprog_disconnect() 

961 print("----------------------------------------------------------------------------------------") 

962 print("") 

963 return() 

964 

965#--------------------------------------------------------------------------------------------------------- 

966# Test MQTT interface 

967#--------------------------------------------------------------------------------------------------------- 

968 

969def shutdown_callback(): 

970 print("Library Tests - MQTT shutdown callback received") 

971 

972def message_callback(message): 

973 print("Library Tests - MQTT message received: "+str(message)) 

974 

975def run_mqtt_interface_tests(): 

976 # Test all functions - including negative tests for parameter validation 

977 print("Library Tests - MQTT Interface Tests") 

978 print("Library Tests - split_remote_item_identifier") 

979 assert mqtt_interface.split_remote_item_identifier(123) is None 

980 assert mqtt_interface.split_remote_item_identifier("box111") is None 

981 assert mqtt_interface.split_remote_item_identifier("box1-abc") is None 

982 assert mqtt_interface.split_remote_item_identifier("box1-0") is None 

983 assert mqtt_interface.split_remote_item_identifier("box1-999") is None 

984 assert mqtt_interface.split_remote_item_identifier("box1-99") == ["box1", 99] 

985 print("Library Tests - configure_mqtt_client - 5 Errors should be generated") 

986 mqtt_interface.configure_mqtt_client(100,"node1", False, False, False, shutdown_callback) # error 

987 mqtt_interface.configure_mqtt_client("network1",100, False, False, False, shutdown_callback) # error 

988 mqtt_interface.configure_mqtt_client("network1","node1", "False", False, False, shutdown_callback) # error 

989 mqtt_interface.configure_mqtt_client("network1","node1", False, "False", False, shutdown_callback) # error 

990 mqtt_interface.configure_mqtt_client("network1","node1", False, False, "False", shutdown_callback) # error 

991 mqtt_interface.configure_mqtt_client("network1","node1", True, True, True, shutdown_callback) # Success 

992 print("Library Tests - mqtt_broker_connect - 4 Errors should be generated") 

993 assert not mqtt_interface.mqtt_broker_connect(127,1883) # Fail 

994 assert not mqtt_interface.mqtt_broker_connect("127.0.0.1","1883") # Fail 

995 assert not mqtt_interface.mqtt_broker_connect("127.0.0.1",1883, 100, "password1") # Fail 

996 assert not mqtt_interface.mqtt_broker_connect("127.0.0.1",1883, "user1", 100) # Fail 

997 assert mqtt_interface.mqtt_broker_connect("127.0.0.1",1883, "user1", "password1") # success 

998 system_test_harness.sleep(0.2) 

999 print("Library Tests - mqtt_broker_disconnect (and then re-connect") 

1000 assert mqtt_interface.mqtt_broker_disconnect() 

1001 assert mqtt_interface.mqtt_broker_connect("127.0.0.1",1883, "user1", "password1") # success 

1002 system_test_harness.sleep(0.2) 

1003 print("Library Tests - subscribe_to_mqtt_messages") 

1004 mqtt_interface.subscribe_to_mqtt_messages("test_messages_1", "node1", 1, message_callback) 

1005 mqtt_interface.subscribe_to_mqtt_messages("test_messages_2", "node1", 1, message_callback, subtopics=True) 

1006 system_test_harness.sleep(0.2) 

1007 print("Library Tests - send_mqtt_message") 

1008 mqtt_interface.send_mqtt_message("test_messages_1", 1, {"data1":123, "data2":"abc"}, log_message="LOG MESSAGE 1") 

1009 mqtt_interface.send_mqtt_message("test_messages_1", 1, {"data1":456, "data2":"def"}, log_message="LOG MESSAGE 2") 

1010 mqtt_interface.send_mqtt_message("test_messages_2", 1, {"data1":123, "data2":"abc"}, log_message="LOG MESSAGE 3", subtopic="sub1") 

1011 mqtt_interface.send_mqtt_message("test_messages_2", 1, {"data1":456, "data2":"def"}, log_message="LOG MESSAGE 4", subtopic="sub2") 

1012 system_test_harness.sleep(0.2) 

1013 print("Library Tests - unsubscribe_from_message_type") 

1014 mqtt_interface.unsubscribe_from_message_type("test_messages_1") 

1015 system_test_harness.sleep(0.2) 

1016 mqtt_interface.send_mqtt_message("test_messages_1", 1, {"data1":123, "data2":"abc"}, log_message="LOG MESSAGE 1") 

1017 mqtt_interface.send_mqtt_message("test_messages_1", 1, {"data1":456, "data2":"def"}, log_message="LOG MESSAGE 2") 

1018 print("Library Tests - mqtt_shutdown") 

1019 mqtt_interface.mqtt_shutdown() 

1020 system_test_harness.sleep(0.2) 

1021 print("----------------------------------------------------------------------------------------") 

1022 print("") 

1023 return() 

1024 

1025#--------------------------------------------------------------------------------------------------------- 

1026# Run all library Tests 

1027#--------------------------------------------------------------------------------------------------------- 

1028 

1029def run_all_basic_library_tests(shutdown:bool=False): 

1030 baud_rate = 115200 # change to 460800 for Pi Sprog V2 

1031 logging.getLogger().setLevel(logging.DEBUG) 

1032 run_track_sensor_library_tests() 

1033 run_gpio_sensor_library_tests() 

1034 run_point_library_tests() 

1035 run_instrument_library_tests() 

1036 run_pi_sprog_interface_tests(baud_rate) 

1037 run_dcc_control_tests(baud_rate) 

1038 run_mqtt_interface_tests() 

1039 logging.getLogger().setLevel(logging.WARNING) 

1040 if shutdown: system_test_harness.report_results() 

1041 

1042if __name__ == "__main__": 1042 ↛ 1043line 1042 didn't jump to line 1043, because the condition on line 1042 was never true

1043 system_test_harness.start_application(lambda:run_all_basic_library_tests(shutdown=True)) 

1044 

1045###############################################################################################################################