@@ -493,3 +493,53 @@ def test_portinit_timeout(self, mock_syslog, get_runtime):
493493 call (['sudo' , 'systemctl' , 'enable' , 'telemetry.service' ], capture_output = True , check = True , text = True ),
494494 call (['sudo' , 'systemctl' , 'start' , 'telemetry.service' ], capture_output = True , check = True , text = True )]
495495 mocked_subprocess .run .assert_has_calls (expected , any_order = True )
496+
497+ def test_systemctl_command_failure (self , mock_syslog , get_runtime ):
498+ """Test that when systemctl commands fail:
499+ 1. The feature state is not cached
500+ 2. The feature state is set to FAILED
501+ 3. The update_feature_state returns False
502+ """
503+ mock_db = mock .MagicMock ()
504+ mock_feature_state_table = mock .MagicMock ()
505+
506+ feature_handler = featured .FeatureHandler (mock_db , mock_feature_state_table , {}, False )
507+ feature_handler .is_delayed_enabled = True
508+
509+ # Create a feature that should be enabled
510+ feature_name = 'test_feature'
511+ feature_cfg = {
512+ 'state' : 'enabled' ,
513+ 'auto_restart' : 'enabled' ,
514+ 'delayed' : 'False' ,
515+ 'has_global_scope' : 'True' ,
516+ 'has_per_asic_scope' : 'False'
517+ }
518+
519+ # Initialize the feature in cached_config using the same pattern as in featured
520+ feature = featured .Feature (feature_name , feature_cfg )
521+ feature_handler ._cached_config .setdefault (feature_name , featured .Feature (feature_name , {}))
522+
523+ # Mock subprocess.run and Popen to simulate command failure
524+ with mock .patch ('featured.subprocess' ) as mocked_subprocess :
525+ # Mock Popen for get_systemd_unit_state
526+ popen_mock = mock .Mock ()
527+ popen_mock .communicate .return_value = ('enabled' , '' )
528+ popen_mock .returncode = 1
529+ mocked_subprocess .Popen .return_value = popen_mock
530+
531+ # Mock run_cmd to raise an exception
532+ with mock .patch ('featured.run_cmd' ) as mocked_run_cmd :
533+ mocked_run_cmd .side_effect = Exception ("Command failed" )
534+
535+ # Try to update feature state
536+ result = feature_handler .update_feature_state (feature )
537+
538+ # Verify the result is False
539+ assert result is False
540+
541+ # Verify the feature state was set to FAILED
542+ mock_feature_state_table .set .assert_called_with ('test_feature' , [('state' , 'failed' )])
543+
544+ # Verify the feature state was not enabled in the cache
545+ assert feature_handler ._cached_config [feature .name ].state != 'enabled'
0 commit comments