From 7ab09d6299f6391e243ed9541a77e6a90fe574d6 Mon Sep 17 00:00:00 2001 From: anish-mudaraddi Date: Thu, 13 Feb 2025 16:13:50 +0000 Subject: [PATCH] fixes for extract uptime refactor function to handle all cases for uptime string: - days=x HH:MM - HH:MM - minutes=x --- openstackquery/time_utils.py | 44 +++++++++++++++-------- tests/test_time_utils.py | 67 +++++++++++------------------------- 2 files changed, 51 insertions(+), 60 deletions(-) diff --git a/openstackquery/time_utils.py b/openstackquery/time_utils.py index dfc0c7b..f5d8a4b 100644 --- a/openstackquery/time_utils.py +++ b/openstackquery/time_utils.py @@ -54,29 +54,45 @@ def convert_to_timestamp( def extract_uptime(uptime_string: str) -> Optional[float]: """ Extracts number of days uptime from the string returned by the uptime - command + command. Handles formats: + - "X days, HH:MM" + - "HH:MM" + - "X min" :param uptime_string: String returned by the uptime command :type uptime_string: str :return: Number of days uptime if found in string :rtype: float | None """ - uptime_pattern = re.compile(r"up\s+((\d+ days?,\s*)?(\d+:\d+))") + # Pattern matches both "X days, HH:MM" and "HH:MM" and "X min" formats + uptime_pattern = re.compile( + r"up\s+(?:(\d+)\s*days?,\s*)?(?:(\d+):(\d+)|(\d+)\s*min)" + ) + try: match = uptime_pattern.search(uptime_string) except TypeError: + # datetime string is not what we expect + return None + + if not match: return None - if match: - uptime_string = match.group(1) - days = 0 - time_part = uptime_string - if "day" in uptime_string: - days_part, time_part = uptime_string.split( - " day" + ("s" if "days" in uptime_string else "") + ", " - ) - days += int(days_part) - hours, minutes = map(int, time_part.split(":")) + days = 0 + + # Check if we matched days + if match.group(1): + days = int(match.group(1)) + + # Check if we matched HH:MM format + if match.group(2) and match.group(3): + hours = int(match.group(2)) + minutes = int(match.group(3)) days += hours / 24 + minutes / 1440 - return round(days, 2) - return None + + # Check if we matched minutes format + elif match.group(4): + minutes = int(match.group(4)) + days += minutes / 1440 + + return round(days, 2) diff --git a/tests/test_time_utils.py b/tests/test_time_utils.py index 53f6f52..9c4bd29 100644 --- a/tests/test_time_utils.py +++ b/tests/test_time_utils.py @@ -69,56 +69,31 @@ def test_convert_to_timestamp(): assert out == "timestamp-out" -def test_extract_uptime(): - """ - Test successful extraction of number of days uptime - """ - mock_string = ( - "17:13:49 up 394 days, 7:03, 0 users, load average: 1.90, 1.70, 1.95" - ) - - res = TimeUtils.extract_uptime(mock_string) - - assert res == 394.29 - - def test_extract_uptime_not_string(): """ Test extraction returns None when not a string """ - mock_not_string = None - - res = TimeUtils.extract_uptime(mock_not_string) - - assert res is None - - -def test_extract_uptime_empty_string(): + assert TimeUtils.extract_uptime(None) is None + + +@pytest.mark.parametrize( + "mock_string,expected_result", + [ + # Test extraction when greater than a day + ( + "17:13:49 up 394 days, 7:03, 0 users, load average: 1.90, 1.70, 1.95", + 394.29, + ), + # Test extraction when HH:MM uptime format (less than a day) + ("17:13:49 up 5:57, 0 users, load average: 0.00, 0.01, 0.00", 0.25), + # Test extraction when HH:MM uptime format (less than a day) + ("17:13:49 up 1 day, 7:03, 0 users, load average: 0.00, 0.01, 0.00", 1.29), + # Test extraction when less than a hour uptime + ("15:48:54 up 30 min, 1 user, load average: 0.06, 0.39, 0.25", 0.02), + ], +) +def test_extract_uptime(mock_string, expected_result): """ Test extraction from empty string returns None """ - mock_string = " " - - res = TimeUtils.extract_uptime(mock_string) - - assert res is None - - -def test_extract_uptime_less_than_day(): - """ - Test extraction when less than a day uptime - """ - mock_string = "17:13:49 up 5:57, 0 users, load average: 0.00, 0.01, 0.00" - res = TimeUtils.extract_uptime(mock_string) - - assert res == 0.25 - - -def test_extract_uptime_is_one_day(): - """ - Test extraction when less than a day uptime - """ - mock_string = "17:13:49 up 1 day, 7:03, 0 users, load average: 0.00, 0.01, 0.00" - res = TimeUtils.extract_uptime(mock_string) - - assert res == 1.29 + assert TimeUtils.extract_uptime(mock_string) == expected_result