18
18
from click .testing import CliRunner
19
19
20
20
from sonic_py_common import device_info , multi_asic
21
+ from utilities_common import flock
21
22
from utilities_common .db import Db
22
23
from utilities_common .general import load_module_from_source
23
24
from mock import call , patch , mock_open , MagicMock
45
46
load_minigraph_platform_false_path = os .path .join (load_minigraph_input_path , "platform_false" )
46
47
47
48
load_minigraph_command_output = """\
49
+ Acquired lock on {0}
50
+ Stopping SONiC target ...
51
+ Running command: /usr/local/bin/sonic-cfggen -H -m --write-to-db
52
+ Running command: config qos reload --no-dynamic-buffer --no-delay
53
+ Running command: pfcwd start_default
54
+ Restarting SONiC target ...
55
+ Reloading Monit configuration ...
56
+ Please note setting loaded from minigraph will be lost after system reboot. To preserve setting, run `config save`.
57
+ Released lock on {0}
58
+ """
59
+
60
+ load_minigraph_lock_failure_output = """\
61
+ Failed to acquire lock on {0}
62
+ """
63
+
64
+ load_minigraph_command_bypass_lock_output = """\
65
+ Bypass lock on {}
48
66
Stopping SONiC target ...
49
67
Running command: /usr/local/bin/sonic-cfggen -H -m --write-to-db
50
68
Running command: config qos reload --no-dynamic-buffer --no-delay
55
73
"""
56
74
57
75
load_minigraph_platform_plugin_command_output = """\
76
+ Acquired lock on {0}
58
77
Stopping SONiC target ...
59
78
Running command: /usr/local/bin/sonic-cfggen -H -m --write-to-db
60
79
Running command: config qos reload --no-dynamic-buffer --no-delay
63
82
Restarting SONiC target ...
64
83
Reloading Monit configuration ...
65
84
Please note setting loaded from minigraph will be lost after system reboot. To preserve setting, run `config save`.
85
+ Released lock on {0}
66
86
"""
67
87
68
88
load_mgmt_config_command_ipv4_only_output = """\
137
157
"""
138
158
139
159
RELOAD_CONFIG_DB_OUTPUT = """\
160
+ Acquired lock on {0}
161
+ Stopping SONiC target ...
162
+ Running command: /usr/local/bin/sonic-cfggen -j /tmp/config.json --write-to-db
163
+ Restarting SONiC target ...
164
+ Reloading Monit configuration ...
165
+ Released lock on {0}
166
+ """
167
+
168
+ RELOAD_CONFIG_DB_LOCK_FAILURE_OUTPUT = """\
169
+ Failed to acquire lock on {0}
170
+ """
171
+
172
+ RELOAD_CONFIG_DB_BYPASS_LOCK_OUTPUT = """\
173
+ Bypass lock on {0}
140
174
Stopping SONiC target ...
141
175
Running command: /usr/local/bin/sonic-cfggen -j /tmp/config.json --write-to-db
142
176
Restarting SONiC target ...
143
177
Reloading Monit configuration ...
144
178
"""
145
179
146
180
RELOAD_YANG_CFG_OUTPUT = """\
181
+ Acquired lock on {0}
147
182
Stopping SONiC target ...
148
183
Running command: /usr/local/bin/sonic-cfggen -Y /tmp/config.json --write-to-db
149
184
Restarting SONiC target ...
150
185
Reloading Monit configuration ...
186
+ Released lock on {0}
151
187
"""
152
188
153
189
RELOAD_MASIC_CONFIG_DB_OUTPUT = """\
190
+ Acquired lock on {0}
154
191
Stopping SONiC target ...
155
192
Running command: /usr/local/bin/sonic-cfggen -j /tmp/config.json --write-to-db
156
193
Running command: /usr/local/bin/sonic-cfggen -j /tmp/config.json -n asic0 --write-to-db
157
194
Running command: /usr/local/bin/sonic-cfggen -j /tmp/config.json -n asic1 --write-to-db
158
195
Restarting SONiC target ...
159
196
Reloading Monit configuration ...
197
+ Released lock on {0}
160
198
"""
161
199
162
200
reload_config_with_sys_info_command_output = """\
201
+ Acquired lock on {0}
163
202
Running command: /usr/local/bin/sonic-cfggen -H -k Seastone-DX010-25-50 --write-to-db"""
164
203
165
204
reload_config_with_disabled_service_output = """\
205
+ Acquired lock on {0}
166
206
Stopping SONiC target ...
167
207
Running command: /usr/local/bin/sonic-cfggen -j /tmp/config.json --write-to-db
168
208
Restarting SONiC target ...
169
209
Reloading Monit configuration ...
210
+ Released lock on {0}
170
211
"""
171
212
172
213
reload_config_masic_onefile_output = """\
214
+ Acquired lock on {0}
173
215
Stopping SONiC target ...
174
216
Restarting SONiC target ...
175
217
Reloading Monit configuration ...
218
+ Released lock on {0}
176
219
"""
177
220
178
221
reload_config_masic_onefile_gen_sysinfo_output = """\
222
+ Acquired lock on {0}
179
223
Stopping SONiC target ...
180
224
Running command: /usr/local/bin/sonic-cfggen -H -k Mellanox-SN3800-D112C8 --write-to-db
181
225
Running command: /usr/local/bin/sonic-cfggen -H -k multi_asic -n asic0 --write-to-db
182
226
Running command: /usr/local/bin/sonic-cfggen -H -k multi_asic -n asic1 --write-to-db
183
227
Restarting SONiC target ...
184
228
Reloading Monit configuration ...
229
+ Released lock on {0}
185
230
"""
186
231
187
232
save_config_output = """\
@@ -601,7 +646,8 @@ def test_config_reload(self, get_cmd_module, setup_single_broadcom_asic):
601
646
602
647
assert result .exit_code == 0
603
648
604
- assert "\n " .join ([l .rstrip () for l in result .output .split ('\n ' )][:1 ]) == reload_config_with_sys_info_command_output
649
+ assert "\n " .join ([line .rstrip () for line in result .output .split ('\n ' )][:2 ]) == \
650
+ reload_config_with_sys_info_command_output .format (config .SYSTEM_RELOAD_LOCK )
605
651
606
652
def test_config_reload_stdin (self , get_cmd_module , setup_single_broadcom_asic ):
607
653
def mock_json_load (f ):
@@ -641,7 +687,8 @@ def mock_json_load(f):
641
687
642
688
assert result .exit_code == 0
643
689
644
- assert "\n " .join ([l .rstrip () for l in result .output .split ('\n ' )][:1 ]) == reload_config_with_sys_info_command_output
690
+ assert "\n " .join ([line .rstrip () for line in result .output .split ('\n ' )][:2 ]) == \
691
+ reload_config_with_sys_info_command_output .format (config .SYSTEM_RELOAD_LOCK )
645
692
646
693
@classmethod
647
694
def teardown_class (cls ):
@@ -747,7 +794,8 @@ def read_json_file_side_effect(filename):
747
794
traceback .print_tb (result .exc_info [2 ])
748
795
749
796
assert result .exit_code == 0
750
- assert "\n " .join ([li .rstrip () for li in result .output .split ('\n ' )]) == reload_config_masic_onefile_output
797
+ assert "\n " .join ([li .rstrip () for li in result .output .split ('\n ' )]) == \
798
+ reload_config_masic_onefile_output .format (config .SYSTEM_RELOAD_LOCK )
751
799
752
800
def test_config_reload_onefile_gen_sysinfo_masic (self ):
753
801
def read_json_file_side_effect (filename ):
@@ -823,7 +871,7 @@ def read_json_file_side_effect(filename):
823
871
assert result .exit_code == 0
824
872
assert "\n " .join (
825
873
[li .rstrip () for li in result .output .split ('\n ' )]
826
- ) == reload_config_masic_onefile_gen_sysinfo_output
874
+ ) == reload_config_masic_onefile_gen_sysinfo_output . format ( config . SYSTEM_RELOAD_LOCK )
827
875
828
876
def test_config_reload_onefile_bad_format_masic (self ):
829
877
def read_json_file_side_effect (filename ):
@@ -878,11 +926,58 @@ def test_load_minigraph(self, get_cmd_module, setup_single_broadcom_asic):
878
926
print (result .output )
879
927
traceback .print_tb (result .exc_info [2 ])
880
928
assert result .exit_code == 0
881
- assert "\n " .join ([l .rstrip () for l in result .output .split ('\n ' )]) == load_minigraph_command_output
929
+ assert "\n " .join ([line .rstrip () for line in result .output .split ('\n ' )]) == \
930
+ (load_minigraph_command_output .format (config .SYSTEM_RELOAD_LOCK ))
882
931
# Verify "systemctl reset-failed" is called for services under sonic.target
883
932
mock_run_command .assert_any_call (['systemctl' , 'reset-failed' , 'swss' ])
884
933
assert mock_run_command .call_count == 12
885
934
935
+ @mock .patch ('sonic_py_common.device_info.get_paths_to_platform_and_hwsku_dirs' ,
936
+ mock .MagicMock (return_value = ("dummy_path" , None )))
937
+ def test_load_minigraph_lock_failure (self , get_cmd_module , setup_single_broadcom_asic ):
938
+ with mock .patch ("utilities_common.cli.run_command" ,
939
+ mock .MagicMock (side_effect = mock_run_command_side_effect )) as mock_run_command :
940
+ (config , _ ) = get_cmd_module
941
+
942
+ fd = open (config .SYSTEM_RELOAD_LOCK , 'r' )
943
+ assert flock .acquire_flock (fd , 0 )
944
+
945
+ try :
946
+ runner = CliRunner ()
947
+ result = runner .invoke (config .config .commands ["load_minigraph" ], ["-y" ])
948
+ print (result .exit_code )
949
+ print (result .output )
950
+ traceback .print_tb (result .exc_info [2 ])
951
+ assert result .exit_code != 0
952
+ assert result .output == \
953
+ (load_minigraph_lock_failure_output .format (config .SYSTEM_RELOAD_LOCK ))
954
+ assert mock_run_command .call_count == 0
955
+ finally :
956
+ flock .release_flock (fd )
957
+
958
+ @mock .patch ('sonic_py_common.device_info.get_paths_to_platform_and_hwsku_dirs' ,
959
+ mock .MagicMock (return_value = ("dummy_path" , None )))
960
+ def test_load_minigraph_bypass_lock (self , get_cmd_module , setup_single_broadcom_asic ):
961
+ with mock .patch ("utilities_common.cli.run_command" ,
962
+ mock .MagicMock (side_effect = mock_run_command_side_effect )) as mock_run_command :
963
+ (config , _ ) = get_cmd_module
964
+
965
+ fd = open (config .SYSTEM_RELOAD_LOCK , 'r' )
966
+ assert flock .acquire_flock (fd , 0 )
967
+
968
+ try :
969
+ runner = CliRunner ()
970
+ result = runner .invoke (config .config .commands ["load_minigraph" ], ["-y" , "-b" ])
971
+ print (result .exit_code )
972
+ print (result .output )
973
+ traceback .print_tb (result .exc_info [2 ])
974
+ assert result .exit_code == 0
975
+ assert result .output == \
976
+ load_minigraph_command_bypass_lock_output .format (config .SYSTEM_RELOAD_LOCK )
977
+ assert mock_run_command .call_count == 12
978
+ finally :
979
+ flock .release_flock (fd )
980
+
886
981
@mock .patch ('sonic_py_common.device_info.get_paths_to_platform_and_hwsku_dirs' , mock .MagicMock (return_value = (load_minigraph_platform_path , None )))
887
982
def test_load_minigraph_platform_plugin (self , get_cmd_module , setup_single_broadcom_asic ):
888
983
with mock .patch ("utilities_common.cli.run_command" , mock .MagicMock (side_effect = mock_run_command_side_effect )) as mock_run_command :
@@ -893,7 +988,8 @@ def test_load_minigraph_platform_plugin(self, get_cmd_module, setup_single_broad
893
988
print (result .output )
894
989
traceback .print_tb (result .exc_info [2 ])
895
990
assert result .exit_code == 0
896
- assert "\n " .join ([l .rstrip () for l in result .output .split ('\n ' )]) == load_minigraph_platform_plugin_command_output
991
+ assert "\n " .join ([line .rstrip () for line in result .output .split ('\n ' )]) == \
992
+ (load_minigraph_platform_plugin_command_output .format (config .SYSTEM_RELOAD_LOCK ))
897
993
# Verify "systemctl reset-failed" is called for services under sonic.target
898
994
mock_run_command .assert_any_call (['systemctl' , 'reset-failed' , 'swss' ])
899
995
assert mock_run_command .call_count == 12
@@ -1171,7 +1267,59 @@ def test_reload_config(self, get_cmd_module, setup_single_broadcom_asic):
1171
1267
traceback .print_tb (result .exc_info [2 ])
1172
1268
assert result .exit_code == 0
1173
1269
assert "\n " .join ([l .rstrip () for l in result .output .split ('\n ' )]) \
1174
- == RELOAD_CONFIG_DB_OUTPUT
1270
+ == RELOAD_CONFIG_DB_OUTPUT .format (config .SYSTEM_RELOAD_LOCK )
1271
+
1272
+ def test_reload_config_lock_failure (self , get_cmd_module , setup_single_broadcom_asic ):
1273
+ self .add_sysinfo_to_cfg_file ()
1274
+ with mock .patch (
1275
+ "utilities_common.cli.run_command" ,
1276
+ mock .MagicMock (side_effect = mock_run_command_side_effect )
1277
+ ):
1278
+ (config , show ) = get_cmd_module
1279
+ runner = CliRunner ()
1280
+
1281
+ fd = open (config .SYSTEM_RELOAD_LOCK , 'r' )
1282
+ assert flock .acquire_flock (fd , 0 )
1283
+
1284
+ try :
1285
+ result = runner .invoke (
1286
+ config .config .commands ["reload" ],
1287
+ [self .dummy_cfg_file , '-y' , '-f' ])
1288
+
1289
+ print (result .exit_code )
1290
+ print (result .output )
1291
+ traceback .print_tb (result .exc_info [2 ])
1292
+ assert result .exit_code != 0
1293
+ assert "\n " .join ([line .rstrip () for line in result .output .split ('\n ' )]) \
1294
+ == RELOAD_CONFIG_DB_LOCK_FAILURE_OUTPUT .format (config .SYSTEM_RELOAD_LOCK )
1295
+ finally :
1296
+ flock .release_flock (fd )
1297
+
1298
+ def test_reload_config_bypass_lock (self , get_cmd_module , setup_single_broadcom_asic ):
1299
+ self .add_sysinfo_to_cfg_file ()
1300
+ with mock .patch (
1301
+ "utilities_common.cli.run_command" ,
1302
+ mock .MagicMock (side_effect = mock_run_command_side_effect )
1303
+ ):
1304
+ (config , show ) = get_cmd_module
1305
+ runner = CliRunner ()
1306
+
1307
+ fd = open (config .SYSTEM_RELOAD_LOCK , 'r' )
1308
+ assert flock .acquire_flock (fd , 0 )
1309
+
1310
+ try :
1311
+ result = runner .invoke (
1312
+ config .config .commands ["reload" ],
1313
+ [self .dummy_cfg_file , '-y' , '-f' , '-b' ])
1314
+
1315
+ print (result .exit_code )
1316
+ print (result .output )
1317
+ traceback .print_tb (result .exc_info [2 ])
1318
+ assert result .exit_code == 0
1319
+ assert "\n " .join ([line .rstrip () for line in result .output .split ('\n ' )]) \
1320
+ == RELOAD_CONFIG_DB_BYPASS_LOCK_OUTPUT .format (config .SYSTEM_RELOAD_LOCK )
1321
+ finally :
1322
+ flock .release_flock (fd )
1175
1323
1176
1324
def test_config_reload_disabled_service (self , get_cmd_module , setup_single_broadcom_asic ):
1177
1325
self .add_sysinfo_to_cfg_file ()
@@ -1191,7 +1339,8 @@ def test_config_reload_disabled_service(self, get_cmd_module, setup_single_broad
1191
1339
1192
1340
assert result .exit_code == 0
1193
1341
1194
- assert "\n " .join ([l .rstrip () for l in result .output .split ('\n ' )]) == reload_config_with_disabled_service_output
1342
+ assert "\n " .join ([line .rstrip () for line in result .output .split ('\n ' )]) == \
1343
+ reload_config_with_disabled_service_output .format (config .SYSTEM_RELOAD_LOCK )
1195
1344
1196
1345
def test_reload_config_masic (self , get_cmd_module , setup_multi_broadcom_masic ):
1197
1346
self .add_sysinfo_to_cfg_file ()
@@ -1215,7 +1364,7 @@ def test_reload_config_masic(self, get_cmd_module, setup_multi_broadcom_masic):
1215
1364
traceback .print_tb (result .exc_info [2 ])
1216
1365
assert result .exit_code == 0
1217
1366
assert "\n " .join ([l .rstrip () for l in result .output .split ('\n ' )]) \
1218
- == RELOAD_MASIC_CONFIG_DB_OUTPUT
1367
+ == RELOAD_MASIC_CONFIG_DB_OUTPUT . format ( config . SYSTEM_RELOAD_LOCK )
1219
1368
1220
1369
def test_reload_yang_config (self , get_cmd_module ,
1221
1370
setup_single_broadcom_asic ):
@@ -1234,7 +1383,7 @@ def test_reload_yang_config(self, get_cmd_module,
1234
1383
traceback .print_tb (result .exc_info [2 ])
1235
1384
assert result .exit_code == 0
1236
1385
assert "\n " .join ([l .rstrip () for l in result .output .split ('\n ' )]) \
1237
- == RELOAD_YANG_CFG_OUTPUT
1386
+ == RELOAD_YANG_CFG_OUTPUT . format ( config . SYSTEM_RELOAD_LOCK )
1238
1387
1239
1388
@classmethod
1240
1389
def teardown_class (cls ):
0 commit comments