@@ -1175,137 +1175,3 @@ def test_orchestrator_stops_on_event(self, mock_web, mock_load):
11751175
11761176 polling_loop (config_mgr , storage , stop )
11771177 # If we get here without hanging, the test passes
1178-
1179- @patch ("app.drivers.driver_registry.load_driver" )
1180- @patch ("app.main.web" )
1181- def test_driver_hot_swap_on_modem_type_change (self , mock_web , mock_load ):
1182- """Polling loop should hot-swap the modem driver when modem_type changes."""
1183- import threading
1184- from app .main import polling_loop
1185-
1186- mock_driver = MagicMock ()
1187- mock_driver .get_device_info .return_value = {"model" : "Test" , "sw_version" : "1.0" }
1188- mock_driver .get_connection_info .return_value = {}
1189- mock_driver .get_docsis_data .return_value = {}
1190- mock_load .return_value = mock_driver
1191-
1192- config_mgr = self ._make_config_mgr ()
1193- storage = MagicMock ()
1194- stop = threading .Event ()
1195-
1196- call_count = [0 ]
1197- original_wait = stop .wait
1198-
1199- def change_modem_after_first_tick (timeout = None ):
1200- call_count [0 ] += 1
1201- if call_count [0 ] == 1 :
1202- # After first tick, change modem_type in config
1203- config_mgr .get_all .return_value ["modem_type" ] = "tc4400"
1204- config_mgr .get .side_effect = lambda k , d = None : {
1205- "modem_type" : "tc4400" ,
1206- "modem_url" : "http://fritz.box" ,
1207- "modem_user" : "admin" ,
1208- "modem_password" : "pass" ,
1209- "poll_interval" : 900 ,
1210- }.get (k , d )
1211- return original_wait (0 )
1212- elif call_count [0 ] >= 3 :
1213- stop .set ()
1214- return True
1215- return original_wait (0 )
1216-
1217- stop .wait = change_modem_after_first_tick
1218-
1219- polling_loop (config_mgr , storage , stop )
1220-
1221- # load_driver should have been called at least twice:
1222- # once for initial setup, once for hot-swap
1223- assert mock_load .call_count >= 2
1224- # Second call should use the new modem type
1225- second_call = mock_load .call_args_list [1 ]
1226- assert second_call [0 ][0 ] == "tc4400"
1227- # Web state should have been reset for the swap
1228- mock_web .reset_modem_state .assert_called ()
1229- mock_web .init_collector .assert_called ()
1230-
1231- @patch ("app.drivers.driver_registry.load_driver" )
1232- @patch ("app.main.web" )
1233- def test_driver_hot_swap_on_url_change (self , mock_web , mock_load ):
1234- """Hot-swap should trigger when modem URL changes, not just type."""
1235- import threading
1236- from app .main import polling_loop
1237-
1238- mock_driver = MagicMock ()
1239- mock_driver .get_device_info .return_value = {"model" : "Test" , "sw_version" : "1.0" }
1240- mock_driver .get_connection_info .return_value = {}
1241- mock_driver .get_docsis_data .return_value = {}
1242- mock_load .return_value = mock_driver
1243-
1244- config_mgr = self ._make_config_mgr ()
1245- storage = MagicMock ()
1246- stop = threading .Event ()
1247-
1248- call_count = [0 ]
1249- original_wait = stop .wait
1250-
1251- def change_url_after_first_tick (timeout = None ):
1252- call_count [0 ] += 1
1253- if call_count [0 ] == 1 :
1254- # Change URL but keep same modem_type
1255- config_mgr .get .side_effect = lambda k , d = None : {
1256- "modem_type" : "fritzbox" ,
1257- "modem_url" : "http://192.168.100.1" ,
1258- "modem_user" : "admin" ,
1259- "modem_password" : "pass" ,
1260- "poll_interval" : 900 ,
1261- }.get (k , d )
1262- return original_wait (0 )
1263- elif call_count [0 ] >= 3 :
1264- stop .set ()
1265- return True
1266- return original_wait (0 )
1267-
1268- stop .wait = change_url_after_first_tick
1269-
1270- polling_loop (config_mgr , storage , stop )
1271-
1272- # load_driver called twice: initial + hot-swap for URL change
1273- assert mock_load .call_count >= 2
1274- second_call = mock_load .call_args_list [1 ]
1275- assert second_call [0 ][1 ] == "http://192.168.100.1"
1276-
1277- @patch ("app.drivers.driver_registry.load_driver" )
1278- @patch ("app.main.web" )
1279- def test_no_hot_swap_when_config_unchanged (self , mock_web , mock_load ):
1280- """No hot-swap should occur when modem config hasn't changed."""
1281- import threading
1282- from app .main import polling_loop
1283-
1284- mock_driver = MagicMock ()
1285- mock_driver .get_device_info .return_value = {"model" : "Test" , "sw_version" : "1.0" }
1286- mock_driver .get_connection_info .return_value = {}
1287- mock_driver .get_docsis_data .return_value = {}
1288- mock_load .return_value = mock_driver
1289-
1290- config_mgr = self ._make_config_mgr ()
1291- storage = MagicMock ()
1292- stop = threading .Event ()
1293-
1294- call_count = [0 ]
1295- original_wait = stop .wait
1296-
1297- def stop_after_ticks (timeout = None ):
1298- call_count [0 ] += 1
1299- if call_count [0 ] >= 3 :
1300- stop .set ()
1301- return True
1302- return original_wait (0 )
1303-
1304- stop .wait = stop_after_ticks
1305-
1306- polling_loop (config_mgr , storage , stop )
1307-
1308- # load_driver should only be called once (initial setup)
1309- assert mock_load .call_count == 1
1310- # reset_modem_state should NOT have been called (no swap)
1311- mock_web .reset_modem_state .assert_not_called ()
0 commit comments