@@ -1036,7 +1036,7 @@ def test_device_update_config_in_progress(
10361036
10371037 with mock .patch (
10381038 "openwisp_controller.connection.tasks._acquire_update_config_lock" ,
1039- return_value = False ,
1039+ return_value = None ,
10401040 ):
10411041 conf .config = {"general" : {"timezone" : "UTC" }}
10421042 conf .full_clean ()
@@ -1057,28 +1057,43 @@ def test_device_update_config_not_in_progress(
10571057
10581058 with mock .patch (
10591059 "openwisp_controller.connection.tasks._acquire_update_config_lock" ,
1060- return_value = True ,
1060+ return_value = "fake-lock-token" ,
10611061 ), mock .patch (
10621062 "openwisp_controller.connection.tasks._release_update_config_lock" ,
1063- ):
1063+ ) as mocked_release :
10641064 conf .config = {"general" : {"timezone" : "UTC" }}
10651065 conf .full_clean ()
10661066 conf .save ()
10671067 mocked_get_working_connection .assert_called_once ()
10681068 mocked_update_config .assert_called_once ()
1069+ mocked_release .assert_called_once ()
10691070
10701071 def test_acquire_update_config_lock (self ):
10711072 """Test that the lock can be acquired and prevents duplicate acquisition."""
10721073 device_id = "test-device-id"
1073- # First acquisition should succeed
1074- self .assertTrue (_acquire_update_config_lock (device_id ))
1074+ # First acquisition should succeed and return a token
1075+ token = _acquire_update_config_lock (device_id )
1076+ self .assertIsNotNone (token )
10751077 # Second acquisition should fail (lock already held)
1076- self .assertFalse (_acquire_update_config_lock (device_id ))
1077- # After releasing, acquisition should succeed again
1078- _release_update_config_lock (device_id )
1079- self .assertTrue (_acquire_update_config_lock (device_id ))
1078+ self .assertIsNone (_acquire_update_config_lock (device_id ))
1079+ # After releasing with correct token, acquisition should succeed again
1080+ _release_update_config_lock (device_id , token )
1081+ token2 = _acquire_update_config_lock (device_id )
1082+ self .assertIsNotNone (token2 )
10801083 # Cleanup
1081- _release_update_config_lock (device_id )
1084+ _release_update_config_lock (device_id , token2 )
1085+
1086+ def test_release_update_config_lock_wrong_token (self ):
1087+ """Only the lock owner can release the lock."""
1088+ device_id = "test-device-id"
1089+ token = _acquire_update_config_lock (device_id )
1090+ self .assertIsNotNone (token )
1091+ # Releasing with wrong token should not delete the lock
1092+ _release_update_config_lock (device_id , "wrong-token" )
1093+ # Lock should still be held
1094+ self .assertIsNone (_acquire_update_config_lock (device_id ))
1095+ # Releasing with correct token should work
1096+ _release_update_config_lock (device_id , token )
10821097
10831098 @mock .patch (_connect_path )
10841099 def test_schedule_command_called (self , connect_mocked ):
0 commit comments