From ea54ee58c2a56f6abf71e3a69eb67f5afdf6638a Mon Sep 17 00:00:00 2001 From: john feng Date: Mon, 10 Jul 2023 09:31:20 -0700 Subject: [PATCH 1/7] raise excetion if min is < 2.7 --- src/core/src/bootstrap/Bootstrapper.py | 7 +++++++ src/core/tests/Test_CoreMain.py | 21 +++++++++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/src/core/src/bootstrap/Bootstrapper.py b/src/core/src/bootstrap/Bootstrapper.py index 4e349f26..42bc4eef 100644 --- a/src/core/src/bootstrap/Bootstrapper.py +++ b/src/core/src/bootstrap/Bootstrapper.py @@ -141,6 +141,9 @@ def basic_environment_health_check(self): self.composite_logger.log("Linux distribution: " + str(self.env_layer.platform.linux_distribution()) + "\n") self.composite_logger.log("Process id: " + str(os.getpid())) + # check machine min python version is met + self.check_min_python_version() + # Ensure sudo works in the environment sudo_check_result = self.check_sudo_status() self.composite_logger.log_debug("Sudo status check: " + str(sudo_check_result) + "\n") @@ -175,3 +178,7 @@ def check_sudo_status(self, raise_if_not_sudo=True): if raise_if_not_sudo: raise + def check_min_python_version(self): + if sys.version_info < (2, 7): + self.composite_logger.log_debug("Python version is below 2.7") + raise Exception("Error: minimum python version is not met - Python version is below 2.7") diff --git a/src/core/tests/Test_CoreMain.py b/src/core/tests/Test_CoreMain.py index 6395e6c2..538b2dde 100644 --- a/src/core/tests/Test_CoreMain.py +++ b/src/core/tests/Test_CoreMain.py @@ -19,6 +19,7 @@ import os import re import shutil +import sys import time import unittest import uuid @@ -1135,6 +1136,26 @@ def __check_telemetry_events(self, runtime): self.assertTrue('Core' in events[0]['TaskName']) f.close() + # def test_python_version_below_2_7(self): + # sys.version_info = (2, 6) + # argument_composer = ArgumentComposer() + # argument_composer.operation = Constants.ASSESSMENT + # runtime = RuntimeCompositor(argument_composer.get_composed_arguments(), True, Constants.ZYPPER) + # runtime.set_legacy_test_type('HappyPath') + # CoreMain(argument_composer.get_composed_arguments()) + # + # # check telemetry events + # self.__check_telemetry_events(runtime) + # + # # check status file + # with runtime.env_layer.file_system.open(runtime.execution_config.status_file_path, 'r') as file_handle: + # substatus_file_data = json.load(file_handle)[0]["status"]["substatus"] + # self.assertEqual(len(substatus_file_data), 2) + # self.assertTrue(substatus_file_data[0]["name"] == Constants.PATCH_ASSESSMENT_SUMMARY) + # self.assertTrue(substatus_file_data[0]["status"].lower() == Constants.STATUS_SUCCESS.lower()) + # self.assertTrue(substatus_file_data[1]["name"] == Constants.CONFIGURE_PATCHING_SUMMARY) + # self.assertTrue(substatus_file_data[1]["status"].lower() == Constants.STATUS_SUCCESS.lower()) + # runtime.stop() if __name__ == '__main__': unittest.main() \ No newline at end of file From 65975e06f85dfc78a5dc1f692157048867e75186 Mon Sep 17 00:00:00 2001 From: john feng Date: Mon, 10 Jul 2023 10:05:13 -0700 Subject: [PATCH 2/7] change log_debug to log_error --- src/core/src/bootstrap/Bootstrapper.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/src/bootstrap/Bootstrapper.py b/src/core/src/bootstrap/Bootstrapper.py index 42bc4eef..c113eb92 100644 --- a/src/core/src/bootstrap/Bootstrapper.py +++ b/src/core/src/bootstrap/Bootstrapper.py @@ -180,5 +180,5 @@ def check_sudo_status(self, raise_if_not_sudo=True): def check_min_python_version(self): if sys.version_info < (2, 7): - self.composite_logger.log_debug("Python version is below 2.7") + self.composite_logger.log_error("Python version is below 2.7") raise Exception("Error: minimum python version is not met - Python version is below 2.7") From 25b10c469959a7a5be485afab2e6e308bcff2bfd Mon Sep 17 00:00:00 2001 From: john feng Date: Mon, 17 Jul 2023 10:38:00 -0700 Subject: [PATCH 3/7] add min_python_version exception to start_assessment() --- src/core/src/bootstrap/Bootstrapper.py | 8 -------- src/core/src/bootstrap/Constants.py | 3 +++ src/core/src/core_logic/PatchAssessor.py | 10 ++++++++++ src/core/tests/Test_CoreMain.py | 20 -------------------- src/core/tests/Test_PatchAssessor.py | 8 ++++++++ 5 files changed, 21 insertions(+), 28 deletions(-) diff --git a/src/core/src/bootstrap/Bootstrapper.py b/src/core/src/bootstrap/Bootstrapper.py index c113eb92..562357c4 100644 --- a/src/core/src/bootstrap/Bootstrapper.py +++ b/src/core/src/bootstrap/Bootstrapper.py @@ -141,9 +141,6 @@ def basic_environment_health_check(self): self.composite_logger.log("Linux distribution: " + str(self.env_layer.platform.linux_distribution()) + "\n") self.composite_logger.log("Process id: " + str(os.getpid())) - # check machine min python version is met - self.check_min_python_version() - # Ensure sudo works in the environment sudo_check_result = self.check_sudo_status() self.composite_logger.log_debug("Sudo status check: " + str(sudo_check_result) + "\n") @@ -177,8 +174,3 @@ def check_sudo_status(self, raise_if_not_sudo=True): "Exception details: " + str(exception)) if raise_if_not_sudo: raise - - def check_min_python_version(self): - if sys.version_info < (2, 7): - self.composite_logger.log_error("Python version is below 2.7") - raise Exception("Error: minimum python version is not met - Python version is below 2.7") diff --git a/src/core/src/bootstrap/Constants.py b/src/core/src/bootstrap/Constants.py index 7348541c..8547e8ab 100644 --- a/src/core/src/bootstrap/Constants.py +++ b/src/core/src/bootstrap/Constants.py @@ -335,3 +335,6 @@ class UbuntuProClientSettings(EnumBackport): MAX_OS_MAJOR_VERSION_SUPPORTED = 18 MINIMUM_CLIENT_VERSION = "27.14.4" + class PythonVersionMsg(EnumBackport): + PYTHON_NOT_COMPATIBLE_ERROR_MSG = "Unsupported older Python version. Python version is below 2.7. To resolve: https://www.pythoncentral.io/how-to-update-python/" + PYTHON_COMPATIBLE_MSG = "Minimum Python version (2.7) prerequisite met" diff --git a/src/core/src/core_logic/PatchAssessor.py b/src/core/src/core_logic/PatchAssessor.py index 3ee0c991..1e162217 100644 --- a/src/core/src/core_logic/PatchAssessor.py +++ b/src/core/src/core_logic/PatchAssessor.py @@ -19,6 +19,7 @@ import json import os import shutil +import sys import time from core.src.bootstrap.Constants import Constants from core.src.core_logic.Stopwatch import Stopwatch @@ -43,6 +44,7 @@ def start_assessment(self): """ Start a patch assessment """ self.status_handler.set_current_operation(Constants.ASSESSMENT) self.raise_if_telemetry_unsupported() + self.raise_if_min_python_version_not_met() if self.execution_config.exec_auto_assess_only and not self.should_auto_assessment_run(): self.composite_logger.log("\nSkipping automatic patch assessment... [ShouldAutoAssessmentRun=False]\n") @@ -129,6 +131,14 @@ def raise_if_telemetry_unsupported(self): self.composite_logger.log("{0}".format(Constants.TELEMETRY_COMPATIBLE_MSG)) + def raise_if_min_python_version_not_met(self): + if sys.version_info < (2, 7): + error_msg = "{0}".format(Constants.PythonVersionMsg.PYTHON_NOT_COMPATIBLE_ERROR_MSG) + self.composite_logger.log_error(error_msg) + self.status_handler.set_assessment_substatus_json(status=Constants.STATUS_ERROR) + raise Exception(error_msg) + self.composite_logger.log("{0}".format(Constants.PythonVersionMsg.PYTHON_COMPATIBLE_MSG)) + # region - Auto-assessment extensions def should_auto_assessment_run(self): # get last start time diff --git a/src/core/tests/Test_CoreMain.py b/src/core/tests/Test_CoreMain.py index 538b2dde..4aa638fd 100644 --- a/src/core/tests/Test_CoreMain.py +++ b/src/core/tests/Test_CoreMain.py @@ -1136,26 +1136,6 @@ def __check_telemetry_events(self, runtime): self.assertTrue('Core' in events[0]['TaskName']) f.close() - # def test_python_version_below_2_7(self): - # sys.version_info = (2, 6) - # argument_composer = ArgumentComposer() - # argument_composer.operation = Constants.ASSESSMENT - # runtime = RuntimeCompositor(argument_composer.get_composed_arguments(), True, Constants.ZYPPER) - # runtime.set_legacy_test_type('HappyPath') - # CoreMain(argument_composer.get_composed_arguments()) - # - # # check telemetry events - # self.__check_telemetry_events(runtime) - # - # # check status file - # with runtime.env_layer.file_system.open(runtime.execution_config.status_file_path, 'r') as file_handle: - # substatus_file_data = json.load(file_handle)[0]["status"]["substatus"] - # self.assertEqual(len(substatus_file_data), 2) - # self.assertTrue(substatus_file_data[0]["name"] == Constants.PATCH_ASSESSMENT_SUMMARY) - # self.assertTrue(substatus_file_data[0]["status"].lower() == Constants.STATUS_SUCCESS.lower()) - # self.assertTrue(substatus_file_data[1]["name"] == Constants.CONFIGURE_PATCHING_SUMMARY) - # self.assertTrue(substatus_file_data[1]["status"].lower() == Constants.STATUS_SUCCESS.lower()) - # runtime.stop() if __name__ == '__main__': unittest.main() \ No newline at end of file diff --git a/src/core/tests/Test_PatchAssessor.py b/src/core/tests/Test_PatchAssessor.py index 96c0684c..65b27c3d 100644 --- a/src/core/tests/Test_PatchAssessor.py +++ b/src/core/tests/Test_PatchAssessor.py @@ -16,6 +16,7 @@ import datetime import json import os +import sys import unittest from core.src.bootstrap.Constants import Constants @@ -171,6 +172,13 @@ def test_stopwatch_properties_assessment_fail(self): self.assertTrue(self.runtime.patch_assessor.stopwatch.time_taken_in_secs is not None) self.assertTrue(self.runtime.patch_assessor.stopwatch.task_details is not None) + def test_raise_if_min_python_version_not_met(self): + sys.version_info = (2, 6) + # Assert that an exception is raised + with self.assertRaises(Exception) as context: + self.runtime.patch_assessor.start_assessment() + self.assertEqual(str(context.exception), "Unsupported older Python version. Python version is below 2.7. To resolve: https://www.pythoncentral.io/how-to-update-python/") + def raise_ex(self): raise Exception() From ad8977c02558b530b0d5f70353ef1c751ba334c1 Mon Sep 17 00:00:00 2001 From: john feng Date: Mon, 17 Jul 2023 11:02:34 -0700 Subject: [PATCH 4/7] reset python version after unit test is completed --- src/core/tests/Test_CoreMain.py | 4 +--- src/core/tests/Test_PatchAssessor.py | 2 ++ 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/core/tests/Test_CoreMain.py b/src/core/tests/Test_CoreMain.py index 4aa638fd..612d6bc6 100644 --- a/src/core/tests/Test_CoreMain.py +++ b/src/core/tests/Test_CoreMain.py @@ -19,8 +19,6 @@ import os import re import shutil -import sys -import time import unittest import uuid @@ -1138,4 +1136,4 @@ def __check_telemetry_events(self, runtime): if __name__ == '__main__': - unittest.main() \ No newline at end of file + unittest.main() diff --git a/src/core/tests/Test_PatchAssessor.py b/src/core/tests/Test_PatchAssessor.py index 65b27c3d..fb10e084 100644 --- a/src/core/tests/Test_PatchAssessor.py +++ b/src/core/tests/Test_PatchAssessor.py @@ -29,8 +29,10 @@ class TestPatchAssessor(unittest.TestCase): def setUp(self): self.runtime = RuntimeCompositor(ArgumentComposer().get_composed_arguments(), legacy_mode=True) self.container = self.runtime.container + self.original_version_info = sys.version_info def tearDown(self): + sys.version_info = self.original_version_info self.runtime.stop() def test_assessment_success(self): From 72e80d5b3fd916d34c2d77e7173d65b8c3471fa9 Mon Sep 17 00:00:00 2001 From: john feng Date: Mon, 17 Jul 2023 13:38:20 -0700 Subject: [PATCH 5/7] changing python version description and revert changes in bootstrapper.py --- src/core/src/bootstrap/Bootstrapper.py | 1 + src/core/src/bootstrap/Constants.py | 5 +---- src/core/src/core_logic/PatchAssessor.py | 3 +-- src/core/tests/Test_PatchAssessor.py | 2 +- 4 files changed, 4 insertions(+), 7 deletions(-) diff --git a/src/core/src/bootstrap/Bootstrapper.py b/src/core/src/bootstrap/Bootstrapper.py index 562357c4..4e349f26 100644 --- a/src/core/src/bootstrap/Bootstrapper.py +++ b/src/core/src/bootstrap/Bootstrapper.py @@ -174,3 +174,4 @@ def check_sudo_status(self, raise_if_not_sudo=True): "Exception details: " + str(exception)) if raise_if_not_sudo: raise + diff --git a/src/core/src/bootstrap/Constants.py b/src/core/src/bootstrap/Constants.py index 8547e8ab..a59fb58d 100644 --- a/src/core/src/bootstrap/Constants.py +++ b/src/core/src/bootstrap/Constants.py @@ -300,7 +300,7 @@ class TelemetryTaskName(EnumBackport): TELEMETRY_NOT_COMPATIBLE_ERROR_MSG = "Unsupported older Azure Linux Agent version. To resolve: http://aka.ms/UpdateLinuxAgent" TELEMETRY_COMPATIBLE_MSG = "Minimum Azure Linux Agent version prerequisite met" - + PYTHON_NOT_COMPATIBLE_ERROR_MSG = "Unsupported older Python version. Minimum Python version required is 2.7. [DetectedPythonVersion={0}]" UTC_DATETIME_FORMAT = "%Y-%m-%dT%H:%M:%SZ" # EnvLayer Constants @@ -335,6 +335,3 @@ class UbuntuProClientSettings(EnumBackport): MAX_OS_MAJOR_VERSION_SUPPORTED = 18 MINIMUM_CLIENT_VERSION = "27.14.4" - class PythonVersionMsg(EnumBackport): - PYTHON_NOT_COMPATIBLE_ERROR_MSG = "Unsupported older Python version. Python version is below 2.7. To resolve: https://www.pythoncentral.io/how-to-update-python/" - PYTHON_COMPATIBLE_MSG = "Minimum Python version (2.7) prerequisite met" diff --git a/src/core/src/core_logic/PatchAssessor.py b/src/core/src/core_logic/PatchAssessor.py index 1e162217..50d49584 100644 --- a/src/core/src/core_logic/PatchAssessor.py +++ b/src/core/src/core_logic/PatchAssessor.py @@ -133,11 +133,10 @@ def raise_if_telemetry_unsupported(self): def raise_if_min_python_version_not_met(self): if sys.version_info < (2, 7): - error_msg = "{0}".format(Constants.PythonVersionMsg.PYTHON_NOT_COMPATIBLE_ERROR_MSG) + error_msg = Constants.PYTHON_NOT_COMPATIBLE_ERROR_MSG.format(sys.version_info) self.composite_logger.log_error(error_msg) self.status_handler.set_assessment_substatus_json(status=Constants.STATUS_ERROR) raise Exception(error_msg) - self.composite_logger.log("{0}".format(Constants.PythonVersionMsg.PYTHON_COMPATIBLE_MSG)) # region - Auto-assessment extensions def should_auto_assessment_run(self): diff --git a/src/core/tests/Test_PatchAssessor.py b/src/core/tests/Test_PatchAssessor.py index fb10e084..40f1c22d 100644 --- a/src/core/tests/Test_PatchAssessor.py +++ b/src/core/tests/Test_PatchAssessor.py @@ -179,7 +179,7 @@ def test_raise_if_min_python_version_not_met(self): # Assert that an exception is raised with self.assertRaises(Exception) as context: self.runtime.patch_assessor.start_assessment() - self.assertEqual(str(context.exception), "Unsupported older Python version. Python version is below 2.7. To resolve: https://www.pythoncentral.io/how-to-update-python/") + self.assertEqual(str(context.exception), Constants.PYTHON_NOT_COMPATIBLE_ERROR_MSG.format(sys.version_info)) def raise_ex(self): raise Exception() From 4d0b62a10a42681c07ae2e73f4767118de7b3743 Mon Sep 17 00:00:00 2001 From: john feng Date: Mon, 17 Jul 2023 14:12:29 -0700 Subject: [PATCH 6/7] add conditio for python version is not met in installation logic --- src/core/src/core_logic/PatchInstaller.py | 10 +++++++++- src/core/tests/Test_CoreMain.py | 1 - src/core/tests/Test_PatchInstaller.py | 13 +++++++++++++ 3 files changed, 22 insertions(+), 2 deletions(-) diff --git a/src/core/src/core_logic/PatchInstaller.py b/src/core/src/core_logic/PatchInstaller.py index a97523ca..a80c1436 100644 --- a/src/core/src/core_logic/PatchInstaller.py +++ b/src/core/src/core_logic/PatchInstaller.py @@ -17,7 +17,7 @@ """ The patch install orchestrator """ import datetime import math -import os +import sys import time from core.src.bootstrap.Constants import Constants from core.src.core_logic.Stopwatch import Stopwatch @@ -56,6 +56,7 @@ def start_installation(self, simulate=False): """ Kick off a patch installation run """ self.status_handler.set_current_operation(Constants.INSTALLATION) self.raise_if_telemetry_unsupported() + self.raise_if_min_python_version_not_met() self.composite_logger.log('\nStarting patch installation...') @@ -140,6 +141,13 @@ def raise_if_telemetry_unsupported(self): self.composite_logger.log("{0}".format(Constants.TELEMETRY_COMPATIBLE_MSG)) + def raise_if_min_python_version_not_met(self): + if sys.version_info < (2, 7): + error_msg = Constants.PYTHON_NOT_COMPATIBLE_ERROR_MSG.format(sys.version_info) + self.composite_logger.log_error(error_msg) + self.status_handler.set_installation_substatus_json(status=Constants.STATUS_ERROR) + raise Exception(error_msg) + def install_updates(self, maintenance_window, package_manager, simulate=False): """wrapper function of installing updates""" self.composite_logger.log("\n\nGetting available updates...") diff --git a/src/core/tests/Test_CoreMain.py b/src/core/tests/Test_CoreMain.py index 612d6bc6..d79f96b4 100644 --- a/src/core/tests/Test_CoreMain.py +++ b/src/core/tests/Test_CoreMain.py @@ -1134,6 +1134,5 @@ def __check_telemetry_events(self, runtime): self.assertTrue('Core' in events[0]['TaskName']) f.close() - if __name__ == '__main__': unittest.main() diff --git a/src/core/tests/Test_PatchInstaller.py b/src/core/tests/Test_PatchInstaller.py index 12068df6..6d6a81e7 100644 --- a/src/core/tests/Test_PatchInstaller.py +++ b/src/core/tests/Test_PatchInstaller.py @@ -16,6 +16,7 @@ import datetime import json +import sys import unittest from core.src.bootstrap.Constants import Constants from core.tests.Test_UbuntuProClient import MockUpdatesResult, MockVersionResult @@ -651,6 +652,18 @@ def test_write_installer_perf_logs_runs_successfully_if_exception_in_get_percent self.assertTrue(runtime.patch_installer.write_installer_perf_logs(True, 1, 1, runtime.maintenance_window, False, Constants.TaskStatus.SUCCEEDED, "")) runtime.stop() + def test_raise_if_min_python_version_not_met(self): + runtime = RuntimeCompositor(ArgumentComposer().get_composed_arguments(), legacy_mode=True) + original_version = sys.version_info + sys.version_info = (2, 6) + # Assert that an exception is raised + with self.assertRaises(Exception) as context: + runtime.patch_installer.start_installation() + self.assertEqual(str(context.exception), Constants.PYTHON_NOT_COMPATIBLE_ERROR_MSG.format(sys.version_info)) + + # reset sys.version to original + sys.version_info = original_version + runtime.stop() if __name__ == '__main__': unittest.main() From aada10baf44c5109d1df15ea73f4cd00eb193dc6 Mon Sep 17 00:00:00 2001 From: john feng Date: Mon, 17 Jul 2023 14:19:47 -0700 Subject: [PATCH 7/7] revert changes in test_coremain.py --- src/core/tests/Test_CoreMain.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/core/tests/Test_CoreMain.py b/src/core/tests/Test_CoreMain.py index d79f96b4..922fa900 100644 --- a/src/core/tests/Test_CoreMain.py +++ b/src/core/tests/Test_CoreMain.py @@ -1134,5 +1134,6 @@ def __check_telemetry_events(self, runtime): self.assertTrue('Core' in events[0]['TaskName']) f.close() + if __name__ == '__main__': - unittest.main() + unittest.main() \ No newline at end of file