11import os
22import sys
33import swsscommon as swsscommon_package
4+ from sonic_py_common import device_info
45from swsscommon import swsscommon
56
67from parameterized import parameterized
@@ -46,7 +47,7 @@ def checks_config_table(self, feature_table, expected_table):
4647
4748 return True if not ddiff else False
4849
49- def checks_systemd_config_file (self , feature_table ):
50+ def checks_systemd_config_file (self , feature_table , feature_systemd_name_map = None ):
5051 """Checks whether the systemd configuration file of each feature was created or not
5152 and whether the `Restart=` field in the file is set correctly or not.
5253
@@ -69,13 +70,16 @@ def checks_systemd_config_file(self, feature_table):
6970 elif "disabled" in auto_restart_status :
7071 auto_restart_status = "disabled"
7172
72- feature_systemd_config_file_path = systemd_config_file_path .format (feature_name )
73- is_config_file_existing = os .path .exists (feature_systemd_config_file_path )
74- assert is_config_file_existing , "Systemd configuration file of feature '{}' does not exist!" .format (feature_name )
73+ feature_systemd_list = feature_systemd_name_map [feature_name ] if feature_systemd_name_map else [feature_name ]
7574
76- with open (feature_systemd_config_file_path ) as systemd_config_file :
77- status = systemd_config_file .read ().strip ()
78- assert status == '[Service]\n Restart={}' .format (truth_table [auto_restart_status ])
75+ for feature_systemd in feature_systemd_list :
76+ feature_systemd_config_file_path = systemd_config_file_path .format (feature_systemd )
77+ is_config_file_existing = os .path .exists (feature_systemd_config_file_path )
78+ assert is_config_file_existing , "Systemd configuration file of feature '{}' does not exist!" .format (feature_systemd )
79+
80+ with open (feature_systemd_config_file_path ) as systemd_config_file :
81+ status = systemd_config_file .read ().strip ()
82+ assert status == '[Service]\n Restart={}' .format (truth_table [auto_restart_status ])
7983
8084 def get_state_db_set_calls (self , feature_table ):
8185 """Returns a Mock call objects which recorded the `set` calls to `FEATURE` table in `STATE_DB`.
@@ -120,31 +124,42 @@ def test_sync_state_field(self, test_scenario_name, config_data, fs):
120124 MockConfigDb .set_config_db (config_data ['config_db' ])
121125 feature_state_table_mock = mock .Mock ()
122126 with mock .patch ('hostcfgd.subprocess' ) as mocked_subprocess :
123- popen_mock = mock .Mock ()
124- attrs = config_data ['popen_attributes' ]
125- popen_mock .configure_mock (** attrs )
126- mocked_subprocess .Popen .return_value = popen_mock
127-
128- device_config = {}
129- device_config ['DEVICE_METADATA' ] = MockConfigDb .CONFIG_DB ['DEVICE_METADATA' ]
130- feature_handler = hostcfgd .FeatureHandler (MockConfigDb (), feature_state_table_mock , device_config )
131-
132- feature_table = MockConfigDb .CONFIG_DB ['FEATURE' ]
133- feature_handler .sync_state_field (feature_table )
134-
135- is_any_difference = self .checks_config_table (MockConfigDb .get_config_db ()['FEATURE' ],
136- config_data ['expected_config_db' ]['FEATURE' ])
137- assert is_any_difference , "'FEATURE' table in 'CONFIG_DB' is modified unexpectedly!"
138-
139- feature_table_state_db_calls = self .get_state_db_set_calls (feature_table )
140-
141- self .checks_systemd_config_file (config_data ['config_db' ]['FEATURE' ])
142- mocked_subprocess .check_call .assert_has_calls (config_data ['enable_feature_subprocess_calls' ],
143- any_order = True )
144- mocked_subprocess .check_call .assert_has_calls (config_data ['daemon_reload_subprocess_call' ],
145- any_order = True )
146- feature_state_table_mock .set .assert_has_calls (feature_table_state_db_calls )
147- self .checks_systemd_config_file (config_data ['config_db' ]['FEATURE' ])
127+ with mock .patch ("sonic_py_common.device_info.get_device_runtime_metadata" , return_value = config_data ['device_runtime_metadata' ]):
128+ with mock .patch ("sonic_py_common.device_info.is_multi_npu" , return_value = True if 'num_npu' in config_data else False ):
129+ with mock .patch ("sonic_py_common.device_info.get_num_npus" , return_value = config_data ['num_npu' ] if 'num_npu' in config_data else 1 ):
130+ popen_mock = mock .Mock ()
131+ attrs = config_data ['popen_attributes' ]
132+ popen_mock .configure_mock (** attrs )
133+ mocked_subprocess .Popen .return_value = popen_mock
134+
135+ device_config = {}
136+ device_config ['DEVICE_METADATA' ] = MockConfigDb .CONFIG_DB ['DEVICE_METADATA' ]
137+ device_config .update (config_data ['device_runtime_metadata' ])
138+
139+ feature_handler = hostcfgd .FeatureHandler (MockConfigDb (), feature_state_table_mock , device_config )
140+
141+ feature_table = MockConfigDb .CONFIG_DB ['FEATURE' ]
142+ feature_handler .sync_state_field (feature_table )
143+
144+ feature_systemd_name_map = {}
145+ for feature_name in feature_table .keys ():
146+ feature = hostcfgd .Feature (feature_name , feature_table [feature_name ], device_config )
147+ feature_names , _ = feature_handler .get_multiasic_feature_instances (feature )
148+ feature_systemd_name_map [feature_name ] = feature_names
149+
150+ is_any_difference = self .checks_config_table (MockConfigDb .get_config_db ()['FEATURE' ],
151+ config_data ['expected_config_db' ]['FEATURE' ])
152+ assert is_any_difference , "'FEATURE' table in 'CONFIG_DB' is modified unexpectedly!"
153+
154+ feature_table_state_db_calls = self .get_state_db_set_calls (feature_table )
155+
156+ self .checks_systemd_config_file (config_data ['config_db' ]['FEATURE' ], feature_systemd_name_map )
157+ mocked_subprocess .check_call .assert_has_calls (config_data ['enable_feature_subprocess_calls' ],
158+ any_order = True )
159+ mocked_subprocess .check_call .assert_has_calls (config_data ['daemon_reload_subprocess_call' ],
160+ any_order = True )
161+ feature_state_table_mock .set .assert_has_calls (feature_table_state_db_calls )
162+ self .checks_systemd_config_file (config_data ['config_db' ]['FEATURE' ], feature_systemd_name_map )
148163
149164 @parameterized .expand (HOSTCFGD_TEST_VECTOR )
150165 @patchfs
@@ -165,25 +180,33 @@ def test_handler(self, test_scenario_name, config_data, fs):
165180 MockConfigDb .set_config_db (config_data ['config_db' ])
166181 feature_state_table_mock = mock .Mock ()
167182 with mock .patch ('hostcfgd.subprocess' ) as mocked_subprocess :
168- popen_mock = mock .Mock ()
169- attrs = config_data ['popen_attributes' ]
170- popen_mock .configure_mock (** attrs )
171- mocked_subprocess .Popen .return_value = popen_mock
172-
173- device_config = {}
174- device_config ['DEVICE_METADATA' ] = MockConfigDb .CONFIG_DB ['DEVICE_METADATA' ]
175- feature_handler = hostcfgd .FeatureHandler (MockConfigDb (), feature_state_table_mock , device_config )
176-
177- feature_table = MockConfigDb .CONFIG_DB ['FEATURE' ]
178-
179- for feature_name , feature_config in feature_table .items ():
180- feature_handler .handler (feature_name , 'SET' , feature_config )
181-
182- self .checks_systemd_config_file (config_data ['config_db' ]['FEATURE' ])
183- mocked_subprocess .check_call .assert_has_calls (config_data ['enable_feature_subprocess_calls' ],
184- any_order = True )
185- mocked_subprocess .check_call .assert_has_calls (config_data ['daemon_reload_subprocess_call' ],
186- any_order = True )
183+ with mock .patch ("sonic_py_common.device_info.get_device_runtime_metadata" , return_value = config_data ['device_runtime_metadata' ]):
184+ with mock .patch ("sonic_py_common.device_info.is_multi_npu" , return_value = True if 'num_npu' in config_data else False ):
185+ with mock .patch ("sonic_py_common.device_info.get_num_npus" , return_value = config_data ['num_npu' ] if 'num_npu' in config_data else 1 ):
186+ popen_mock = mock .Mock ()
187+ attrs = config_data ['popen_attributes' ]
188+ popen_mock .configure_mock (** attrs )
189+ mocked_subprocess .Popen .return_value = popen_mock
190+
191+ device_config = {}
192+ device_config ['DEVICE_METADATA' ] = MockConfigDb .CONFIG_DB ['DEVICE_METADATA' ]
193+ device_config .update (config_data ['device_runtime_metadata' ])
194+ feature_handler = hostcfgd .FeatureHandler (MockConfigDb (), feature_state_table_mock , device_config )
195+
196+ feature_table = MockConfigDb .CONFIG_DB ['FEATURE' ]
197+
198+ feature_systemd_name_map = {}
199+ for feature_name , feature_config in feature_table .items ():
200+ feature_handler .handler (feature_name , 'SET' , feature_config )
201+ feature = hostcfgd .Feature (feature_name , feature_table [feature_name ], device_config )
202+ feature_names , _ = feature_handler .get_multiasic_feature_instances (feature )
203+ feature_systemd_name_map [feature_name ] = feature_names
204+
205+ self .checks_systemd_config_file (config_data ['config_db' ]['FEATURE' ], feature_systemd_name_map )
206+ mocked_subprocess .check_call .assert_has_calls (config_data ['enable_feature_subprocess_calls' ],
207+ any_order = True )
208+ mocked_subprocess .check_call .assert_has_calls (config_data ['daemon_reload_subprocess_call' ],
209+ any_order = True )
187210
188211 def test_feature_config_parsing (self ):
189212 swss_feature = hostcfgd .Feature ('swss' , {
0 commit comments