From 8543ddf2072a5a9b4f7707d01b1d9103ad3d5020 Mon Sep 17 00:00:00 2001 From: sujinmkang Date: Wed, 17 Aug 2022 16:42:57 -0700 Subject: [PATCH] update the reboot cause logic and update the unit test --- scripts/determine-reboot-cause | 31 +++++++++--------- tests/determine-reboot-cause_test.py | 47 ++++++++++++++++++++-------- 2 files changed, 50 insertions(+), 28 deletions(-) diff --git a/scripts/determine-reboot-cause b/scripts/determine-reboot-cause index 6252947663e1..b4d01d0ffc1f 100755 --- a/scripts/determine-reboot-cause +++ b/scripts/determine-reboot-cause @@ -175,28 +175,29 @@ def determine_reboot_cause(): software_reboot_cause = find_software_reboot_cause() # The main decision logic of the reboot cause: - # If there is a reboot cause indicated by /proc/cmdline, it should be warmreboot/fastreboot + # If there is a valid hardware reboot cause indicated by platform API, + # check the software reboot cause to add additional rebot cause. + # If there is a reboot cause indicated by /proc/cmdline, and/or warmreboot/fastreboot/softreboot # the software_reboot_cause which is the content of /hosts/reboot-cause/reboot-cause.txt - # will be treated as the reboot cause - # Elif there is a reboot cause indicated by platform API, - # the hardware_reboot_cause will be treated as the reboot cause + # will be treated as the additional reboot cause + # Elif there is a cmdline reboot cause, + # the software_reboot_cause will be treated as the reboot cause if it's not unknown + # otherwise, the cmdline_reboot_cause will be treated as the reboot cause if it's not none # Else the software_reboot_cause will be treated as the reboot cause - if proc_cmdline_reboot_cause is not None: - if not hardware_reboot_cause.startswith(REBOOT_CAUSE_NON_HARDWARE): - # Add the hardware_reboot_cause as actual reboot cause - previous_reboot_cause = hardware_reboot_cause - additional_reboot_info = software_reboot_cause - else: - previous_reboot_cause = software_reboot_cause - elif hardware_reboot_cause is not None: + if not hardware_reboot_cause.startswith(REBOOT_CAUSE_NON_HARDWARE): + previous_reboot_cause = hardware_reboot_cause # Check if any software reboot was issued before this hardware reboot happened if software_reboot_cause is not REBOOT_CAUSE_UNKNOWN: - previous_reboot_cause = hardware_reboot_cause additional_reboot_info = software_reboot_cause + elif proc_cmdline_reboot_cause is not None: + additional_reboot_info = proc_cmdline_reboot_cause + elif proc_cmdline_reboot_cause is not None: + if software_reboot_cause is not REBOOT_CAUSE_UNKNOWN: + # Get the reboot cause from REBOOT_CAUSE_FILE + previous_reboot_cause = software_reboot_cause else: - previous_reboot_cause = hardware_reboot_cause + previous_reboot_cause = proc_cmdline_reboot_cause else: - # Get the reboot cause from REBOOT_CAUSE_FILE previous_reboot_cause = software_reboot_cause return previous_reboot_cause, additional_reboot_info diff --git a/tests/determine-reboot-cause_test.py b/tests/determine-reboot-cause_test.py index 509c32337e6c..a2ddea3f38b9 100644 --- a/tests/determine-reboot-cause_test.py +++ b/tests/determine-reboot-cause_test.py @@ -54,11 +54,16 @@ GEN_TIME_KERNEL_PANIC = "2021_3_28_13_48_49" +REBOOT_CAUSE_UNKNOWN = "Unknown" +REBOOT_CAUSE_NON_HARDWARE = "Non-Hardware" +EXPECTED_NON_HARDWARE_REBOOT_CAUSE = {REBOOT_CAUSE_NON_HARDWARE, "N/A"} +REBOOT_CAUSE_HARDWARE_OTHER = "Hardware - Other" +EXPECTED_HARDWARE_REBOOT_CAUSE = {REBOOT_CAUSE_HARDWARE_OTHER, ""} + EXPECTED_PARSE_WARMFAST_REBOOT_FROM_PROC_CMDLINE = "warm-reboot" EXPECTED_FIND_SOFTWARE_REBOOT_CAUSE_USER = "User issued 'warm-reboot' command [User: admin, Time: Mon Nov 2 22:37:45 UTC 2020]" EXPECTED_FIND_FIRSTBOOT_VERSION = " (First boot of SONiC version 20191130.52)" EXPECTED_FIND_SOFTWARE_REBOOT_CAUSE_FIRSTBOOT = "Unknown (First boot of SONiC version 20191130.52)" -EXPECTED_HARDWARE_REBOOT_CAUSE = {"warm-reboot", ""} EXPECTED_WATCHDOG_REBOOT_CAUSE_DICT = {'comment': '', 'gen_time': '2020_10_22_03_15_08', 'cause': 'Watchdog', 'user': 'N/A', 'time': 'N/A'} EXPECTED_USER_REBOOT_CAUSE_DICT = {'comment': '', 'gen_time': '2020_10_22_03_14_07', 'cause': 'reboot', 'user': 'admin', 'time': 'Thu Oct 22 03:11:08 UTC 2020'} @@ -119,33 +124,49 @@ def test_get_reboot_cause_dict_kernel_panic(self): assert reboot_cause_dict == EXPECTED_KERNEL_PANIC_REBOOT_CAUSE_DICT def test_determine_reboot_cause_hardware(self): - with mock.patch("determine_reboot_cause.determine_reboot_cause.find_proc_cmdline_reboot_cause", return_value="Unknown"): - with mock.patch("determine_reboot_cause.determine_reboot_cause.find_software_reboot_cause", return_value="Power Cycle"): - with mock.patch("determine_reboot_cause.determine_reboot_cause.find_hardware_reboot_cause", return_value="Unknown"): - previous_reboot_cause, additional_info = determine_reboot_cause.determine_reboot_cause() - assert previous_reboot_cause == "Power Cycle" - assert additional_info == "N/A" + with mock.patch("determine_reboot_cause.find_proc_cmdline_reboot_cause", return_value=None): + with mock.patch("determine_reboot_cause.find_software_reboot_cause", return_value=REBOOT_CAUSE_UNKNOWN): + with mock.patch("determine_reboot_cause.find_hardware_reboot_cause", return_value=EXPECTED_HARDWARE_REBOOT_CAUSE): + previous_reboot_cause, additional_reboot_info = determine_reboot_cause.determine_reboot_cause() + assert previous_reboot_cause == EXPECTED_HARDWARE_REBOOT_CAUSE + assert additional_reboot_info == "N/A" def test_determine_reboot_cause_software(self): - with mock.patch("determine_reboot_cause.determine_reboot_cause.find_proc_cmdline_reboot_cause", return_value="Unknown"): + with mock.patch("determine_reboot_cause.determine_reboot_cause.find_proc_cmdline_reboot_cause", return_value=None): with mock.patch("determine_reboot_cause.determine_reboot_cause.find_software_reboot_cause", return_value=EXPECTED_FIND_SOFTWARE_REBOOT_CAUSE_USER): - with mock.patch("determine_reboot_cause.determine_reboot_cause.find_hardware_reboot_cause", return_value="Unknown"): + with mock.patch("determine_reboot_cause.determine_reboot_cause.find_hardware_reboot_cause", return_value=EXPECTED_NON_HARDWARE_REBOOT_CAUSE): previous_reboot_cause, additional_info = determine_reboot_cause.determine_reboot_cause() assert previous_reboot_cause == EXPECTED_FIND_SOFTWARE_REBOOT_CAUSE_USER assert additional_info == "N/A" - def test_determine_reboot_cause_cmdline(self): + def test_determine_reboot_cause_cmdline_software(self): with mock.patch("determine_reboot_cause.determine_reboot_cause.find_proc_cmdline_reboot_cause", return_value=EXPECTED_PARSE_WARMFAST_REBOOT_FROM_PROC_CMDLINE): with mock.patch("determine_reboot_cause.determine_reboot_cause.find_software_reboot_cause", return_value=EXPECTED_FIND_SOFTWARE_REBOOT_CAUSE_USER): - with mock.patch("determine_reboot_cause.determine_reboot_cause.find_hardware_reboot_cause", return_value="Unknown"): + with mock.patch("determine_reboot_cause.determine_reboot_cause.find_hardware_reboot_cause", return_value=EXPECTED_NON_HARDWARE_REBOOT_CAUSE): previous_reboot_cause, additional_info = determine_reboot_cause.determine_reboot_cause() assert previous_reboot_cause == EXPECTED_FIND_SOFTWARE_REBOOT_CAUSE_USER assert additional_info == "N/A" + def test_determine_reboot_cause_cmdline_no_software(self): + with mock.patch("determine_reboot_cause.determine_reboot_cause.find_proc_cmdline_reboot_cause", return_value=EXPECTED_PARSE_WARMFAST_REBOOT_FROM_PROC_CMDLINE): + with mock.patch("determine_reboot_cause.determine_reboot_cause.find_software_reboot_cause", return_value=REBOOT_CAUSE_UNKNOWN): + with mock.patch("determine_reboot_cause.determine_reboot_cause.find_hardware_reboot_cause", return_value=EXPECTED_NON_HARDWARE_REBOOT_CAUSE): + previous_reboot_cause, additional_info = determine_reboot_cause.determine_reboot_cause() + assert previous_reboot_cause == EXPECTED_PARSE_WARMFAST_REBOOT_FROM_PROC_CMDLINE + assert additional_info == "N/A" + def test_determine_reboot_cause_cmdline_hardware(self): with mock.patch("determine_reboot_cause.determine_reboot_cause.find_proc_cmdline_reboot_cause", return_value=EXPECTED_PARSE_WARMFAST_REBOOT_FROM_PROC_CMDLINE): - with mock.patch("determine_reboot_cause.determine_reboot_cause.find_software_reboot_cause", return_value=EXPECTED_FIND_SOFTWARE_REBOOT_CAUSE_USER): - with mock.patch("determine_reboot_cause.determine_reboot_cause.find_hardware_reboot_cause", return_value=REBOOT_CAUSE_WATCHDOG): + with mock.patch("determine_reboot_cause.determine_reboot_cause.find_software_reboot_cause", return_value=REBOOT_CAUSE_UNKNOWN): + with mock.patch("determine_reboot_cause.determine_reboot_cause.find_hardware_reboot_cause", return_value=EXPECTED_HARDWARE_REBOOT_CAUSE): + previous_reboot_cause, additional_info = determine_reboot_cause.determine_reboot_cause() + assert previous_reboot_cause == EXPECTED_HARDWARE_REBOOT_CAUSE + assert additional_info == EXPECTED_PARSE_WARMFAST_REBOOT_FROM_PROC_CMDLINE + + def test_determine_reboot_cause_software_hardware(self): + with mock.patch("determine_reboot_cause.find_proc_cmdline_reboot_cause", return_value=EXPECTED_PARSE_WARMFAST_REBOOT_FROM_PROC_CMDLINE): + with mock.patch("determine_reboot_cause.find_software_reboot_cause", return_value=EXPECTED_FIND_SOFTWARE_REBOOT_CAUSE_USER): + with mock.patch("determine_reboot_cause.find_hardware_reboot_cause", return_value=EXPECTED_HARDWARE_REBOOT_CAUSE): previous_reboot_cause, additional_info = determine_reboot_cause.determine_reboot_cause() assert previous_reboot_cause == REBOOT_CAUSE_WATCHDOG assert additional_info == EXPECTED_FIND_SOFTWARE_REBOOT_CAUSE_USER