diff --git a/sonic_platform_base/module_base.py b/sonic_platform_base/module_base.py index a474000b3..53f862725 100644 --- a/sonic_platform_base/module_base.py +++ b/sonic_platform_base/module_base.py @@ -488,7 +488,8 @@ def set_admin_state_gracefully(self, up): "startup": 300, # 5 mins "shutdown": 180, # 3 mins "reboot": 240, # 4 mins - "halt_services": 60 # 1 min + "halt_services": 60, # 1 min + "recovery": 600 # 10 mins } _TRANSITION_TIMEOUTS_CACHE = None diff --git a/tests/module_base_test.py b/tests/module_base_test.py index 17ec65da5..a57d4b90a 100644 --- a/tests/module_base_test.py +++ b/tests/module_base_test.py @@ -447,6 +447,7 @@ def test_load_transition_timeouts_defaults_host(self): with patch("sonic_py_common.device_info.get_platform", return_value="test_platform"), \ patch("os.path.exists", return_value=False): assert self.module._load_transition_timeouts() == { + "recovery": 600, "startup": 300, "shutdown": 180, "reboot": 240, @@ -459,6 +460,7 @@ def test_load_transition_timeouts_defaults_container(self): self.module.is_host = False with patch("os.path.exists", return_value=False): assert self.module._load_transition_timeouts() == { + "recovery": 600, "startup": 300, "shutdown": 180, "reboot": 240, @@ -480,6 +482,7 @@ def test_load_transition_timeouts_custom_host(self): patch("os.path.exists", return_value=True), \ patch("builtins.open", return_value=mf): assert self.module._load_transition_timeouts() == { + "recovery": 600, "startup": 600, "shutdown": 360, "reboot": 480, @@ -500,6 +503,7 @@ def test_load_transition_timeouts_custom_container(self): with patch("os.path.exists", return_value=True), \ patch("builtins.open", return_value=mf): assert self.module._load_transition_timeouts() == { + "recovery": 600, "startup": 600, "shutdown": 360, "reboot": 480, @@ -514,6 +518,7 @@ def test_load_transition_timeouts_partial(self): with patch("os.path.exists", return_value=True), \ patch("builtins.open", return_value=mf): assert self.module._load_transition_timeouts() == { + "recovery": 600, "startup": 500, "shutdown": 180, "reboot": 240, @@ -528,6 +533,7 @@ def test_load_transition_timeouts_error_host(self, capsys): patch("os.path.exists", return_value=True), \ patch("builtins.open", side_effect=Exception("read error")): assert self.module._load_transition_timeouts() == { + "recovery": 600, "startup": 300, "shutdown": 180, "reboot": 240, @@ -542,6 +548,7 @@ def test_load_transition_timeouts_error_container(self, capsys): with patch("os.path.exists", return_value=True), \ patch("builtins.open", side_effect=Exception("read error")): assert self.module._load_transition_timeouts() == { + "recovery": 600, "startup": 300, "shutdown": 180, "reboot": 240, @@ -832,6 +839,21 @@ def test_set_module_state_transition_happy(self): call(self._key("DPU0"), "transition_start_time", "1000"), ]) + def test_set_module_state_transition_recovery(self): + """The 'recovery' transition type must be accepted (added to defaults).""" + db = MagicMock() + self.module.state_db = db + db.hget.return_value = None + with patch.object(self.module, "get_name", return_value="DPU0"), \ + patch.object(self.module, "_transition_operation_lock"), \ + patch("time.time", return_value=1000): + assert self.module.set_module_state_transition("dpu0", "recovery") is True + db.hset.assert_has_calls([ + call(self._key("DPU0"), "transition_in_progress", "True"), + call(self._key("DPU0"), "transition_type", "recovery"), + call(self._key("DPU0"), "transition_start_time", "1000"), + ]) + def test_set_module_state_transition_within_timeout(self, capsys): db = MagicMock() self.module.state_db = db