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
@@ -1041,20 +1042,56 @@ def _assert_applying_conf_test_command(mocked_exec):
10411042 @mock .patch .object (DeviceConnection , "update_config" )
10421043 @mock .patch .object (DeviceConnection , "get_working_connection" )
10431044 def test_device_update_config_in_progress (
1044- self , mocked_get_working_connection , update_config , mocked_sleep
1045+ self , mocked_get_working_connection , mocked_update_config , mocked_sleep
10451046 ):
10461047 conf = self ._prepare_conf_object ()
10471048
1048- with mock .patch ("celery.app.control.Inspect.active" ) as mocked_active :
1049- mocked_active .return_value = {
1050- "task" : [{"name" : _TASK_NAME , "args" : [str (conf .device .pk )]}]
1051- }
1052- conf .config = {"general" : {"timezone" : "UTC" }}
1053- conf .full_clean ()
1054- conf .save ()
1055- mocked_active .assert_called_once ()
1056- mocked_get_working_connection .assert_not_called ()
1057- update_config .assert_not_called ()
1049+ with self .subTest ("More than one update_config task active for the device" ):
1050+ with mock .patch ("celery.app.control.Inspect.active" ) as mocked_active :
1051+ mocked_active .return_value = {
1052+ "task" : [
1053+ {
1054+ "name" : _TASK_NAME ,
1055+ "args" : [str (conf .device .pk )],
1056+ "id" : str (uuid4 ()),
1057+ }
1058+ ]
1059+ }
1060+ conf .config = {"general" : {"timezone" : "UTC" }}
1061+ conf .full_clean ()
1062+ conf .save ()
1063+ mocked_active .assert_called_once ()
1064+ mocked_get_working_connection .assert_not_called ()
1065+ mocked_update_config .assert_not_called ()
1066+
1067+ Config .objects .update (status = "applied" )
1068+ mocked_get_working_connection .return_value = (
1069+ conf .device .deviceconnection_set .first ()
1070+ )
1071+ with self .subTest ("Only one task is active for the device" ):
1072+ task_id = str (uuid4 ())
1073+ with mock .patch (
1074+ "celery.app.control.Inspect.active"
1075+ ) as mocked_active , mock .patch (
1076+ "celery.app.task.Context.id" ,
1077+ new_callable = mock .PropertyMock ,
1078+ return_value = task_id ,
1079+ ):
1080+ mocked_active .return_value = {
1081+ "task" : [
1082+ {
1083+ "name" : _TASK_NAME ,
1084+ "args" : [str (conf .device .pk )],
1085+ "id" : task_id ,
1086+ }
1087+ ]
1088+ }
1089+ conf .config = {"general" : {"timezone" : "Asia/Kolkata" }}
1090+ conf .full_clean ()
1091+ conf .save ()
1092+ mocked_active .assert_called_once ()
1093+ mocked_get_working_connection .assert_called_once ()
1094+ mocked_update_config .assert_called_once ()
10581095
10591096 @mock .patch ("time.sleep" )
10601097 @mock .patch .object (DeviceConnection , "update_config" )
@@ -1068,8 +1105,15 @@ def test_device_update_config_not_in_progress(
10681105 )
10691106
10701107 with mock .patch ("celery.app.control.Inspect.active" ) as mocked_active :
1108+ # Mock a task running for a different device (args is different)
10711109 mocked_active .return_value = {
1072- "task" : [{"name" : _TASK_NAME , "args" : ["..." ]}]
1110+ "task" : [
1111+ {
1112+ "name" : _TASK_NAME ,
1113+ "args" : ["another-device-id" ], # Different device
1114+ "id" : "different-task-id" ,
1115+ }
1116+ ]
10731117 }
10741118 conf .config = {"general" : {"timezone" : "UTC" }}
10751119 conf .full_clean ()
0 commit comments