11import socket
22from unittest import mock
33from unittest .mock import PropertyMock
4+ from uuid import uuid4
45
56import paramiko
67from django .contrib .auth .models import ContentType
@@ -1026,20 +1027,56 @@ def _assert_applying_conf_test_command(mocked_exec):
10261027 @mock .patch .object (DeviceConnection , "update_config" )
10271028 @mock .patch .object (DeviceConnection , "get_working_connection" )
10281029 def test_device_update_config_in_progress (
1029- self , mocked_get_working_connection , update_config , mocked_sleep
1030+ self , mocked_get_working_connection , mocked_update_config , mocked_sleep
10301031 ):
10311032 conf = self ._prepare_conf_object ()
10321033
1033- with mock .patch ("celery.app.control.Inspect.active" ) as mocked_active :
1034- mocked_active .return_value = {
1035- "task" : [{"name" : _TASK_NAME , "args" : [str (conf .device .pk )]}]
1036- }
1037- conf .config = {"general" : {"timezone" : "UTC" }}
1038- conf .full_clean ()
1039- conf .save ()
1040- mocked_active .assert_called_once ()
1041- mocked_get_working_connection .assert_not_called ()
1042- update_config .assert_not_called ()
1034+ with self .subTest ("More than one update_config task active for the device" ):
1035+ with mock .patch ("celery.app.control.Inspect.active" ) as mocked_active :
1036+ mocked_active .return_value = {
1037+ "task" : [
1038+ {
1039+ "name" : _TASK_NAME ,
1040+ "args" : [str (conf .device .pk )],
1041+ "id" : str (uuid4 ()),
1042+ }
1043+ ]
1044+ }
1045+ conf .config = {"general" : {"timezone" : "UTC" }}
1046+ conf .full_clean ()
1047+ conf .save ()
1048+ mocked_active .assert_called_once ()
1049+ mocked_get_working_connection .assert_not_called ()
1050+ mocked_update_config .assert_not_called ()
1051+
1052+ Config .objects .update (status = "applied" )
1053+ mocked_get_working_connection .return_value = (
1054+ conf .device .deviceconnection_set .first ()
1055+ )
1056+ with self .subTest ("Only one task is active for the device" ):
1057+ task_id = str (uuid4 ())
1058+ with mock .patch (
1059+ "celery.app.control.Inspect.active"
1060+ ) as mocked_active , mock .patch (
1061+ "celery.app.task.Context.id" ,
1062+ new_callable = mock .PropertyMock ,
1063+ return_value = task_id ,
1064+ ):
1065+ mocked_active .return_value = {
1066+ "task" : [
1067+ {
1068+ "name" : _TASK_NAME ,
1069+ "args" : [str (conf .device .pk )],
1070+ "id" : task_id ,
1071+ }
1072+ ]
1073+ }
1074+ conf .config = {"general" : {"timezone" : "Asia/Kolkata" }}
1075+ conf .full_clean ()
1076+ conf .save ()
1077+ mocked_active .assert_called_once ()
1078+ mocked_get_working_connection .assert_called_once ()
1079+ mocked_update_config .assert_called_once ()
10431080
10441081 @mock .patch ("time.sleep" )
10451082 @mock .patch .object (DeviceConnection , "update_config" )
@@ -1053,8 +1090,15 @@ def test_device_update_config_not_in_progress(
10531090 )
10541091
10551092 with mock .patch ("celery.app.control.Inspect.active" ) as mocked_active :
1093+ # Mock a task running for a different device (args is different)
10561094 mocked_active .return_value = {
1057- "task" : [{"name" : _TASK_NAME , "args" : ["..." ]}]
1095+ "task" : [
1096+ {
1097+ "name" : _TASK_NAME ,
1098+ "args" : ["another-device-id" ], # Different device
1099+ "id" : "different-task-id" ,
1100+ }
1101+ ]
10581102 }
10591103 conf .config = {"general" : {"timezone" : "UTC" }}
10601104 conf .full_clean ()
0 commit comments