diff --git a/scripts/conversion_script.py b/scripts/conversion_script.py index b1c4cfc..345cdbe 100644 --- a/scripts/conversion_script.py +++ b/scripts/conversion_script.py @@ -1,4 +1,3 @@ -import hashlib import json import os import subprocess @@ -26,11 +25,10 @@ class RequiredFile(object): """Holds data about files needed to download convert2rhel""" - def __init__(self, path="", host=""): + def __init__(self, path="", host="", keep=False): self.path = path self.host = host - self.sha512_on_system = None - self.is_file_present = False + self.keep = keep class ProcessError(Exception): @@ -151,13 +149,14 @@ def gather_textual_report(): return data -def generate_report_message(highest_status): +def generate_report_message(highest_status, gpg_key_file): """Generate a report message based on the status severity.""" message = "" alert = False if STATUS_CODE[highest_status] <= STATUS_CODE["WARNING"]: message = "No problems found. The system was converted successfully." + gpg_key_file.keep = True if STATUS_CODE[highest_status] > STATUS_CODE["WARNING"]: message = "The conversion cannot proceed. You must resolve existing issues to perform the conversion." @@ -170,34 +169,19 @@ def setup_convert2rhel(required_files): """Setup convert2rhel tool by downloading the required files.""" print("Downloading required files.") for required_file in required_files: + _create_or_restore_backup_file(required_file) response = urlopen(required_file.host) data = response.read() - downloaded_file_sha512 = hashlib.sha512(data) - if os.path.exists(required_file.path): - print( - "File '%s' is already present on the system. Downloading a copy in order to check if they are the same." - % required_file.path - ) - if ( - downloaded_file_sha512.hexdigest() - != required_file.sha512_on_system.hexdigest() - ): - raise ProcessError( - message="Hash mismatch between the downloaded file and the one present on the system.", - report="File '%s' present on the system does not match the one downloaded. Stopping the execution." - % required_file.path, - ) - else: - directory = os.path.dirname(required_file.path) - if not os.path.exists(directory): - print("Creating directory at '%s'" % directory) - os.makedirs(directory, mode=0o755) - - print("Writing file to destination: '%s'" % required_file.path) - with open(required_file.path, mode="w") as handler: - handler.write(data) - os.chmod(required_file.path, 0o644) + directory = os.path.dirname(required_file.path) + if not os.path.exists(directory): + print("Creating directory at '%s'" % directory) + os.makedirs(directory, mode=0o755) + + print("Writing file to destination: '%s'" % required_file.path) + with open(required_file.path, mode="w") as handler: + handler.write(data) + os.chmod(required_file.path, 0o644) # Code taken from @@ -295,32 +279,32 @@ def cleanup(required_files): not something that was downloaded by the script. """ for required_file in required_files: - if not required_file.is_file_present and os.path.exists(required_file.path): + if required_file.keep: + continue + if os.path.exists(required_file.path): print( "Removing the file '%s' as it was previously downloaded." % required_file.path ) os.remove(required_file.path) - continue + _create_or_restore_backup_file(required_file) + +def _create_or_restore_backup_file(required_file): + """ + Either creates or restores backup files (rename in both cases). + """ + suffix = ".backup" + if os.path.exists(required_file.path + suffix): + print("Restoring backed up file %s." % (required_file.path)) + os.rename(required_file.path + suffix, required_file.path) + return + if os.path.exists(required_file.path): print( - "File '%s' was present on the system before the execution. Skipping the removal." - % required_file.path + "File %s already present on system, backing up to %s." + % (required_file.path, required_file.path + suffix) ) - - -def verify_required_files_are_present(required_files): - """Verify if the required files are already present on the system.""" - print("Checking if required files are present on the system.") - for required_file in required_files: - # Avoid race conditions - try: - print("Checking for file %s" % required_file.path) - with open(required_file.path, mode="r") as handler: - required_file.sha512_on_system = hashlib.sha512(handler.read()) - required_file.is_file_present = True - except (IOError, OSError): - required_file.is_file_present = False + os.rename(required_file.path, required_file.path + ".backup") def _generate_message_key(message, action_id): @@ -432,11 +416,13 @@ def update_insights_inventory(): def main(): """Main entrypoint for the script.""" output = OutputCollector() + gpg_key_file = RequiredFile( + path="/etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release", + host="https://www.redhat.com/security/data/fd431d51.txt", + ) + required_files = [ - RequiredFile( - path="/etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release", - host="https://www.redhat.com/security/data/fd431d51.txt", - ), + gpg_key_file, RequiredFile( path="/etc/yum.repos.d/convert2rhel.repo", host="https://ftp.redhat.com/redhat/convert2rhel/7/convert2rhel.repo", @@ -445,7 +431,6 @@ def main(): try: # Setup Convert2RHEL to be executed. - verify_required_files_are_present(required_files) setup_convert2rhel(required_files) install_convert2rhel() run_convert2rhel() @@ -462,7 +447,9 @@ def main(): # Generate report message and transform the raw data into entries for # Insights. - output.message, output.alert = generate_report_message(highest_level) + output.message, output.alert = generate_report_message( + highest_level, gpg_key_file + ) output.entries = transform_raw_data(data) update_insights_inventory() print("Conversion script finish successfully!") diff --git a/scripts/preconversion_assessment_script.py b/scripts/preconversion_assessment_script.py index 38b278a..d42e78e 100644 --- a/scripts/preconversion_assessment_script.py +++ b/scripts/preconversion_assessment_script.py @@ -1,4 +1,3 @@ -import hashlib import json import os import subprocess @@ -29,8 +28,6 @@ class RequiredFile(object): def __init__(self, path="", host=""): self.path = path self.host = host - self.sha512_on_system = None - self.is_file_present = False class ProcessError(Exception): @@ -167,34 +164,19 @@ def setup_convert2rhel(required_files): """Setup convert2rhel tool by downloading the required files.""" print("Downloading required files.") for required_file in required_files: + _create_or_restore_backup_file(required_file) response = urlopen(required_file.host) data = response.read() - downloaded_file_sha512 = hashlib.sha512(data) - if os.path.exists(required_file.path): - print( - "File '%s' is already present on the system. Downloading a copy in order to check if they are the same." - % required_file.path - ) - if ( - downloaded_file_sha512.hexdigest() - != required_file.sha512_on_system.hexdigest() - ): - raise ProcessError( - message="Hash mismatch between the downloaded file and the one present on the system.", - report="File '%s' present on the system does not match the one downloaded. Stopping the execution." - % required_file.path, - ) - else: - directory = os.path.dirname(required_file.path) - if not os.path.exists(directory): - print("Creating directory at '%s'" % directory) - os.makedirs(directory, mode=0o755) - - print("Writing file to destination: '%s'" % required_file.path) - with open(required_file.path, mode="w") as handler: - handler.write(data) - os.chmod(required_file.path, 0o644) + directory = os.path.dirname(required_file.path) + if not os.path.exists(directory): + print("Creating directory at '%s'" % directory) + os.makedirs(directory, mode=0o755) + + print("Writing file to destination: '%s'" % required_file.path) + with open(required_file.path, mode="w") as handler: + handler.write(data) + os.chmod(required_file.path, 0o644) # Code taken from @@ -294,32 +276,30 @@ def cleanup(required_files): not something that was downloaded by the script. """ for required_file in required_files: - if not required_file.is_file_present and os.path.exists(required_file.path): + if os.path.exists(required_file.path): print( "Removing the file '%s' as it was previously downloaded." % required_file.path ) os.remove(required_file.path) - continue + _create_or_restore_backup_file(required_file) + +def _create_or_restore_backup_file(required_file): + """ + Either creates or restores backup files (rename in both cases). + """ + suffix = ".backup" + if os.path.exists(required_file.path + suffix): + print("Restoring backed up file %s." % (required_file.path)) + os.rename(required_file.path + suffix, required_file.path) + return + if os.path.exists(required_file.path): print( - "File '%s' was present on the system before the execution. Skipping the removal." - % required_file.path + "File %s already present on system, backing up to %s." + % (required_file.path, required_file.path + suffix) ) - - -def verify_required_files_are_present(required_files): - """Verify if the required files are already present on the system.""" - print("Checking if required files are present on the system.") - for required_file in required_files: - # Avoid race conditions - try: - print("Checking for file %s" % required_file.path) - with open(required_file.path, mode="r") as handler: - required_file.sha512_on_system = hashlib.sha512(handler.read()) - required_file.is_file_present = True - except (IOError, OSError): - required_file.is_file_present = False + os.rename(required_file.path, required_file.path + ".backup") def _generate_message_key(message, action_id): @@ -429,7 +409,6 @@ def main(): try: # Setup Convert2RHEL to be executed. - verify_required_files_are_present(required_files) setup_convert2rhel(required_files) install_convert2rhel() run_convert2rhel() diff --git a/tests/conversion_script/test_backup_restore_files.py b/tests/conversion_script/test_backup_restore_files.py new file mode 100644 index 0000000..067c00a --- /dev/null +++ b/tests/conversion_script/test_backup_restore_files.py @@ -0,0 +1,41 @@ +import pytest +from mock import patch + +from scripts.conversion_script import ( + RequiredFile, + _create_or_restore_backup_file, +) + + +@patch("scripts.conversion_script.os") +def test_backup_existing_file(mock_os): + filepath = "/path/to/file" + required_file = RequiredFile(path=filepath) + mock_os.path.exists.side_effect = [False, True] + + _create_or_restore_backup_file(required_file) + + mock_os.path.exists.assert_called_with(filepath) + mock_os.rename.assert_called_once_with(filepath, filepath + ".backup") + + +@patch("scripts.conversion_script.os") +def test_restore_existing_file(mock_os): + filepath = "/path/to/file" + required_file = RequiredFile(path=filepath) + mock_os.path.exists.side_effect = [True] + + _create_or_restore_backup_file(required_file) + + mock_os.path.exists.assert_called_with(filepath + ".backup") + mock_os.rename.assert_called_once_with(filepath + ".backup", filepath) + + +@patch("scripts.conversion_script.os") +def test_ioerror_restore_or_backup(mock_os): + filepath = "/path/to/file" + required_file = RequiredFile(path=filepath) + mock_os.path.exists.side_effect = IOError + + with pytest.raises(IOError): + _create_or_restore_backup_file(required_file) diff --git a/tests/conversion_script/test_cleanup.py b/tests/conversion_script/test_cleanup.py index 5e7458d..69473f2 100644 --- a/tests/conversion_script/test_cleanup.py +++ b/tests/conversion_script/test_cleanup.py @@ -5,15 +5,33 @@ @patch("os.path.exists", side_effect=Mock()) @patch("os.remove", side_effect=Mock()) -def test_cleanup_with_file_to_remove(mock_remove, mock_exists): +@patch("scripts.conversion_script._create_or_restore_backup_file") +def test_cleanup_with_file_to_remove(mock_restore, mock_remove, mock_exists): """Only downloaded files are removed.""" present_file = RequiredFile("/already/present") - present_file.is_file_present = True - downloaded_file = RequiredFile("/downloaded") - required_files = [present_file, downloaded_file] + required_files = [present_file] cleanup(required_files) + # For removal of file, then two checks in backup function assert mock_exists.call_count == 1 assert mock_remove.call_count == 1 + assert mock_restore.call_count == 1 + + +@patch("os.path.exists", side_effect=Mock()) +@patch("os.remove", side_effect=Mock()) +@patch("scripts.conversion_script._create_or_restore_backup_file") +def test_cleanup_with_file_to_keep(mock_restore, mock_remove, mock_exists): + """Only downloaded files are removed.""" + + keep_downloaded_file = RequiredFile("/download/keep", keep=True) + required_files = [keep_downloaded_file] + + cleanup(required_files) + + # For removal of file, then two checks in backup function + assert mock_exists.call_count == 0 + assert mock_remove.call_count == 0 + assert mock_restore.call_count == 0 diff --git a/tests/conversion_script/test_generate_report_message.py b/tests/conversion_script/test_generate_report_message.py index a53127b..4f2748e 100644 --- a/tests/conversion_script/test_generate_report_message.py +++ b/tests/conversion_script/test_generate_report_message.py @@ -1,19 +1,42 @@ import pytest -from scripts.conversion_script import generate_report_message +from scripts.conversion_script import RequiredFile, generate_report_message @pytest.mark.parametrize( - ("highest_status", "expected_message", "has_alert"), + ("highest_status", "expected_message", "has_alert", "file_should_be_kept"), [ - ("SUCCESS", "No problems found. The system was converted successfully.", False), - ("INFO", "No problems found. The system was converted successfully.", False), - ("WARNING", "No problems found. The system was converted successfully.", False), + ( + "SUCCESS", + "No problems found. The system was converted successfully.", + False, + True, + ), + ( + "INFO", + "No problems found. The system was converted successfully.", + False, + True, + ), + ( + "WARNING", + "No problems found. The system was converted successfully.", + False, + True, + ), ( "ERROR", "The conversion cannot proceed. You must resolve existing issues to perform the conversion.", True, + False, ), ], ) -def test_generate_report_message(highest_status, expected_message, has_alert): - assert generate_report_message(highest_status) == (expected_message, has_alert) +def test_generate_report_message( + highest_status, expected_message, has_alert, file_should_be_kept +): + file = RequiredFile("/foo/bar") + assert generate_report_message(highest_status, file) == ( + expected_message, + has_alert, + ) + assert file.keep is file_should_be_kept diff --git a/tests/conversion_script/test_main.py b/tests/conversion_script/test_main.py index d9a010b..79019ae 100644 --- a/tests/conversion_script/test_main.py +++ b/tests/conversion_script/test_main.py @@ -8,7 +8,6 @@ # fmt: off @patch("scripts.conversion_script.gather_json_report", side_effect=[{"actions": []}]) @patch("scripts.conversion_script.update_insights_inventory", side_effect=Mock()) -@patch("scripts.conversion_script.verify_required_files_are_present", side_effect=Mock()) @patch("scripts.conversion_script.setup_convert2rhel", side_effect=Mock()) @patch("scripts.conversion_script.install_convert2rhel", side_effect=Mock()) @patch("scripts.conversion_script.run_convert2rhel", side_effect=Mock()) @@ -27,13 +26,11 @@ def test_main_success( mock_run_convert2rhel, mock_install_convert2rhel, mock_setup_convert2rhel, - mock_verify_required_files_are_present, mock_update_insights_inventory, mock_gather_json_report, ): main() - assert mock_verify_required_files_are_present.call_count == 1 assert mock_setup_convert2rhel.call_count == 1 assert mock_install_convert2rhel.call_count == 1 assert mock_run_convert2rhel.call_count == 1 @@ -49,7 +46,6 @@ def test_main_success( # fmt: off @patch("__builtin__.open", new_callable=mock_open()) @patch("scripts.conversion_script.gather_json_report", side_effect=[{"actions": []}]) -@patch("scripts.conversion_script.verify_required_files_are_present", side_effect=Mock()) @patch("scripts.conversion_script.setup_convert2rhel", side_effect=Mock()) @patch("scripts.conversion_script.install_convert2rhel", side_effect=Mock()) @patch("scripts.conversion_script.run_convert2rhel", side_effect=ProcessError("test", "Process error")) @@ -66,13 +62,11 @@ def test_main_process_error( mock_run_convert2rhel, mock_install_convert2rhel, mock_setup_convert2rhel, - mock_verify_required_files_are_present, mock_gather_json_report, mock_open_func, ): main() - assert mock_verify_required_files_are_present.call_count == 1 assert mock_setup_convert2rhel.call_count == 1 assert mock_install_convert2rhel.call_count == 1 assert mock_run_convert2rhel.call_count == 1 @@ -86,7 +80,6 @@ def test_main_process_error( # fmt: off @patch("__builtin__.open", mock_open(read_data="not json serializable")) -@patch("scripts.conversion_script.verify_required_files_are_present", side_effect=Mock()) @patch("scripts.conversion_script.setup_convert2rhel", side_effect=Mock()) @patch("scripts.conversion_script.install_convert2rhel", side_effect=Mock()) @patch("scripts.conversion_script.run_convert2rhel", side_effect=Mock()) @@ -103,11 +96,9 @@ def test_main_general_exception( mock_run_convert2rhel, mock_install_convert2rhel, mock_setup_convert2rhel, - mock_verify_required_files_are_present, ): main() - assert mock_verify_required_files_are_present.call_count == 1 assert mock_setup_convert2rhel.call_count == 1 assert mock_install_convert2rhel.call_count == 1 assert mock_run_convert2rhel.call_count == 1 diff --git a/tests/conversion_script/test_setup.py b/tests/conversion_script/test_setup.py index 6e0b4d5..6373e4f 100644 --- a/tests/conversion_script/test_setup.py +++ b/tests/conversion_script/test_setup.py @@ -1,9 +1,6 @@ -import hashlib -import pytest -from mock import Mock, mock_open, patch +from mock import Mock, patch from scripts.conversion_script import ( - ProcessError, RequiredFile, setup_convert2rhel, ) @@ -23,62 +20,56 @@ def read(self): ) @patch("os.path.exists", return_value=True) @patch("os.makedirs", side_effect=Mock()) -@patch("__builtin__.open", side_effect=mock_open) -def test_setup_convert2rhel_file_exist_not_match( - mock_open_fn, mock_makedirs, mock_exist, mock_urlopen +@patch("scripts.conversion_script._create_or_restore_backup_file") +@patch("__builtin__.open") +@patch("os.chmod") +def test_setup_file_exist_backup_called( + mock_chmod, + mock_open_fn, + mock_backup, + mock_makedirs, + mock_exist, + mock_urlopen, ): + # pylint: disable=too-many-arguments test_file = RequiredFile("/mock/path/file.txt", "exist_not_match") - test_file.sha512_on_system = hashlib.sha512(b"foo") - required_files = [test_file] - - with pytest.raises(ProcessError): - setup_convert2rhel(required_files) - - assert mock_exist.call_count == 1 - assert mock_urlopen.call_count == 1 - assert mock_makedirs.call_count == 0 - assert mock_open_fn.call_count == 0 - - -@patch( - "scripts.conversion_script.urlopen", - return_value=MockResponse("exist_match"), -) -@patch("os.path.exists", return_value=True) -@patch("os.makedirs", side_effect=Mock()) -@patch("__builtin__.open", side_effect=mock_open) -def test_setup_convert2rhel_file_exist_match( - mock_open_fn, mock_makedirs, mock_exist, mock_urlopen -): - test_file = RequiredFile("/mock/path/file.txt", "exist_match") - test_file.sha512_on_system = hashlib.sha512(b"exist_match") required_files = [test_file] setup_convert2rhel(required_files) + assert mock_backup.call_count == 1 assert mock_exist.call_count == 1 assert mock_urlopen.call_count == 1 assert mock_makedirs.call_count == 0 - assert mock_open_fn.call_count == 0 + assert mock_open_fn.call_count == 1 + assert mock_chmod.call_count == 1 @patch( "scripts.conversion_script.urlopen", - return_value=MockResponse("not_exist"), + return_value=MockResponse("exist_not_match"), ) @patch("os.path.exists", return_value=False) @patch("os.makedirs", side_effect=Mock()) -@patch("__builtin__.open", new_callable=mock_open) -@patch("os.chmod", side_effect=Mock()) -def test_setup_convert2rhel_file_not_exist( - mock_chmod, mock_open_fn, mock_makedirs, mock_exist, mock_urlopen +@patch("scripts.conversion_script._create_or_restore_backup_file") +@patch("__builtin__.open") +@patch("os.chmod") +def test_setup_file_does_not_exists_backup_called( + mock_chmod, + mock_open_fn, + mock_backup, + mock_makedirs, + mock_exist, + mock_urlopen, ): - test_file = RequiredFile("/mock/path/file.txt", "not_exist") + # pylint: disable=too-many-arguments + test_file = RequiredFile("/mock/path/file.txt", "exist_not_match") required_files = [test_file] setup_convert2rhel(required_files) - assert mock_exist.call_count == 2 + assert mock_backup.call_count == 1 + assert mock_exist.call_count == 1 assert mock_urlopen.call_count == 1 assert mock_makedirs.call_count == 1 assert mock_open_fn.call_count == 1 diff --git a/tests/conversion_script/test_verify_files_present.py b/tests/conversion_script/test_verify_files_present.py deleted file mode 100644 index 4a8c27e..0000000 --- a/tests/conversion_script/test_verify_files_present.py +++ /dev/null @@ -1,41 +0,0 @@ -from mock import patch, mock_open - -from scripts.conversion_script import ( - verify_required_files_are_present, - RequiredFile, -) - - -def test_verify_required_files_are_present_exist(): - """Attribute is_file_present set to True and sha512 generated""" - required_files = [ - RequiredFile("/mock/path/file1.txt"), - RequiredFile("/mock/path/file2.txt"), - ] - mock_open_func = mock_open(read_data="dummy content") - - with patch("__builtin__.open", mock_open_func): - verify_required_files_are_present(required_files) - - assert mock_open_func.call_count == len(required_files) - - for required_file in required_files: - assert required_file.is_file_present - assert required_file.sha512_on_system is not None - - -def test_verify_required_files_are_present_not_found(): - """If files do not exist on system then default attributes should be set""" - required_files = [ - RequiredFile("/mock/path/file1.txt"), - RequiredFile("/mock/path/file2.txt"), - ] - with patch("__builtin__.open", new_callable=mock_open) as mock_file: - mock_file.side_effect = IOError() - verify_required_files_are_present(required_files) - - assert mock_file.call_count == len(required_files) - - for required_file in required_files: - assert not required_file.is_file_present - assert required_file.sha512_on_system is None diff --git a/tests/preconversion_assessment/test_backup_restore_files.py b/tests/preconversion_assessment/test_backup_restore_files.py new file mode 100644 index 0000000..4cc4fa3 --- /dev/null +++ b/tests/preconversion_assessment/test_backup_restore_files.py @@ -0,0 +1,41 @@ +import pytest +from mock import patch + +from scripts.preconversion_assessment_script import ( + RequiredFile, + _create_or_restore_backup_file, +) + + +@patch("scripts.preconversion_assessment_script.os") +def test_backup_existing_file(mock_os): + filepath = "/path/to/file" + required_file = RequiredFile(path=filepath) + mock_os.path.exists.side_effect = [False, True] + + _create_or_restore_backup_file(required_file) + + mock_os.path.exists.assert_called_with(filepath) + mock_os.rename.assert_called_once_with(filepath, filepath + ".backup") + + +@patch("scripts.preconversion_assessment_script.os") +def test_restore_existing_file(mock_os): + filepath = "/path/to/file" + required_file = RequiredFile(path=filepath) + mock_os.path.exists.side_effect = [True] + + _create_or_restore_backup_file(required_file) + + mock_os.path.exists.assert_called_with(filepath + ".backup") + mock_os.rename.assert_called_once_with(filepath + ".backup", filepath) + + +@patch("scripts.preconversion_assessment_script.os") +def test_ioerror_restore_or_backup(mock_os): + filepath = "/path/to/file" + required_file = RequiredFile(path=filepath) + mock_os.path.exists.side_effect = IOError + + with pytest.raises(IOError): + _create_or_restore_backup_file(required_file) diff --git a/tests/preconversion_assessment/test_cleanup.py b/tests/preconversion_assessment/test_cleanup.py index bf016b2..40e6e96 100644 --- a/tests/preconversion_assessment/test_cleanup.py +++ b/tests/preconversion_assessment/test_cleanup.py @@ -5,15 +5,16 @@ @patch("os.path.exists", side_effect=Mock()) @patch("os.remove", side_effect=Mock()) -def test_cleanup_with_file_to_remove(mock_remove, mock_exists): +@patch("scripts.preconversion_assessment_script._create_or_restore_backup_file") +def test_cleanup_with_file_to_remove(mock_restore, mock_remove, mock_exists): """Only downloaded files are removed.""" present_file = RequiredFile("/already/present") - present_file.is_file_present = True - downloaded_file = RequiredFile("/downloaded") - required_files = [present_file, downloaded_file] + required_files = [present_file] cleanup(required_files) + # For removal of file, then two checks in backup function assert mock_exists.call_count == 1 assert mock_remove.call_count == 1 + assert mock_restore.call_count == 1 diff --git a/tests/preconversion_assessment/test_main.py b/tests/preconversion_assessment/test_main.py index 55089bb..f2648a4 100644 --- a/tests/preconversion_assessment/test_main.py +++ b/tests/preconversion_assessment/test_main.py @@ -7,7 +7,6 @@ # fmt: off @patch("scripts.preconversion_assessment_script.gather_json_report", side_effect=[{"actions": []}]) -@patch("scripts.preconversion_assessment_script.verify_required_files_are_present", side_effect=Mock()) @patch("scripts.preconversion_assessment_script.setup_convert2rhel", side_effect=Mock()) @patch("scripts.preconversion_assessment_script.install_convert2rhel", side_effect=Mock()) @patch("scripts.preconversion_assessment_script.run_convert2rhel", side_effect=Mock()) @@ -26,12 +25,10 @@ def test_main_success( mock_run_convert2rhel, mock_install_convert2rhel, mock_setup_convert2rhel, - mock_verify_required_files_are_present, mock_gather_json_report, ): main() - assert mock_verify_required_files_are_present.call_count == 1 assert mock_setup_convert2rhel.call_count == 1 assert mock_install_convert2rhel.call_count == 1 assert mock_run_convert2rhel.call_count == 1 @@ -46,7 +43,6 @@ def test_main_success( # fmt: off @patch("__builtin__.open", new_callable=mock_open()) @patch("scripts.preconversion_assessment_script.gather_json_report", side_effect=[{"actions": []}]) -@patch("scripts.preconversion_assessment_script.verify_required_files_are_present", side_effect=Mock()) @patch("scripts.preconversion_assessment_script.setup_convert2rhel", side_effect=Mock()) @patch("scripts.preconversion_assessment_script.install_convert2rhel", side_effect=Mock()) @patch("scripts.preconversion_assessment_script.run_convert2rhel", side_effect=ProcessError("test", "Process error")) @@ -63,13 +59,11 @@ def test_main_process_error( mock_run_convert2rhel, mock_install_convert2rhel, mock_setup_convert2rhel, - mock_verify_required_files_are_present, mock_gather_json_report, mock_open_func, ): main() - assert mock_verify_required_files_are_present.call_count == 1 assert mock_setup_convert2rhel.call_count == 1 assert mock_install_convert2rhel.call_count == 1 assert mock_run_convert2rhel.call_count == 1 @@ -83,7 +77,6 @@ def test_main_process_error( # fmt: off @patch("__builtin__.open", mock_open(read_data="not json serializable")) -@patch("scripts.preconversion_assessment_script.verify_required_files_are_present", side_effect=Mock()) @patch("scripts.preconversion_assessment_script.setup_convert2rhel", side_effect=Mock()) @patch("scripts.preconversion_assessment_script.install_convert2rhel", side_effect=Mock()) @patch("scripts.preconversion_assessment_script.run_convert2rhel", side_effect=Mock()) @@ -100,11 +93,9 @@ def test_main_general_exception( mock_run_convert2rhel, mock_install_convert2rhel, mock_setup_convert2rhel, - mock_verify_required_files_are_present, ): main() - assert mock_verify_required_files_are_present.call_count == 1 assert mock_setup_convert2rhel.call_count == 1 assert mock_install_convert2rhel.call_count == 1 assert mock_run_convert2rhel.call_count == 1 diff --git a/tests/preconversion_assessment/test_setup.py b/tests/preconversion_assessment/test_setup.py index 91b3011..1e86d0e 100644 --- a/tests/preconversion_assessment/test_setup.py +++ b/tests/preconversion_assessment/test_setup.py @@ -1,9 +1,6 @@ -import hashlib -import pytest -from mock import Mock, mock_open, patch +from mock import Mock, patch from scripts.preconversion_assessment_script import ( - ProcessError, RequiredFile, setup_convert2rhel, ) @@ -23,62 +20,56 @@ def read(self): ) @patch("os.path.exists", return_value=True) @patch("os.makedirs", side_effect=Mock()) -@patch("__builtin__.open", side_effect=mock_open) -def test_setup_convert2rhel_file_exist_not_match( - mock_open_fn, mock_makedirs, mock_exist, mock_urlopen +@patch("scripts.preconversion_assessment_script._create_or_restore_backup_file") +@patch("__builtin__.open") +@patch("os.chmod") +def test_setup_file_exist_backup_called( + mock_chmod, + mock_open_fn, + mock_backup, + mock_makedirs, + mock_exist, + mock_urlopen, ): + # pylint: disable=too-many-arguments test_file = RequiredFile("/mock/path/file.txt", "exist_not_match") - test_file.sha512_on_system = hashlib.sha512(b"foo") - required_files = [test_file] - - with pytest.raises(ProcessError): - setup_convert2rhel(required_files) - - assert mock_exist.call_count == 1 - assert mock_urlopen.call_count == 1 - assert mock_makedirs.call_count == 0 - assert mock_open_fn.call_count == 0 - - -@patch( - "scripts.preconversion_assessment_script.urlopen", - return_value=MockResponse("exist_match"), -) -@patch("os.path.exists", return_value=True) -@patch("os.makedirs", side_effect=Mock()) -@patch("__builtin__.open", side_effect=mock_open) -def test_setup_convert2rhel_file_exist_match( - mock_open_fn, mock_makedirs, mock_exist, mock_urlopen -): - test_file = RequiredFile("/mock/path/file.txt", "exist_match") - test_file.sha512_on_system = hashlib.sha512(b"exist_match") required_files = [test_file] setup_convert2rhel(required_files) + assert mock_backup.call_count == 1 assert mock_exist.call_count == 1 assert mock_urlopen.call_count == 1 assert mock_makedirs.call_count == 0 - assert mock_open_fn.call_count == 0 + assert mock_open_fn.call_count == 1 + assert mock_chmod.call_count == 1 @patch( "scripts.preconversion_assessment_script.urlopen", - return_value=MockResponse("not_exist"), + return_value=MockResponse("exist_not_match"), ) @patch("os.path.exists", return_value=False) @patch("os.makedirs", side_effect=Mock()) -@patch("__builtin__.open", new_callable=mock_open) -@patch("os.chmod", side_effect=Mock()) -def test_setup_convert2rhel_file_not_exist( - mock_chmod, mock_open_fn, mock_makedirs, mock_exist, mock_urlopen +@patch("scripts.preconversion_assessment_script._create_or_restore_backup_file") +@patch("__builtin__.open") +@patch("os.chmod") +def test_setup_file_does_not_exists_backup_called( + mock_chmod, + mock_open_fn, + mock_backup, + mock_makedirs, + mock_exist, + mock_urlopen, ): - test_file = RequiredFile("/mock/path/file.txt", "not_exist") + # pylint: disable=too-many-arguments + test_file = RequiredFile("/mock/path/file.txt", "exist_not_match") required_files = [test_file] setup_convert2rhel(required_files) - assert mock_exist.call_count == 2 + assert mock_backup.call_count == 1 + assert mock_exist.call_count == 1 assert mock_urlopen.call_count == 1 assert mock_makedirs.call_count == 1 assert mock_open_fn.call_count == 1 diff --git a/tests/preconversion_assessment/test_verify_files_present.py b/tests/preconversion_assessment/test_verify_files_present.py deleted file mode 100644 index c7ebc51..0000000 --- a/tests/preconversion_assessment/test_verify_files_present.py +++ /dev/null @@ -1,41 +0,0 @@ -from mock import patch, mock_open - -from scripts.preconversion_assessment_script import ( - verify_required_files_are_present, - RequiredFile, -) - - -def test_verify_required_files_are_present_exist(): - """Attribute is_file_present set to True and sha512 generated""" - required_files = [ - RequiredFile("/mock/path/file1.txt"), - RequiredFile("/mock/path/file2.txt"), - ] - mock_open_func = mock_open(read_data="dummy content") - - with patch("__builtin__.open", mock_open_func): - verify_required_files_are_present(required_files) - - assert mock_open_func.call_count == len(required_files) - - for required_file in required_files: - assert required_file.is_file_present - assert required_file.sha512_on_system is not None - - -def test_verify_required_files_are_present_not_found(): - """If files do not exist on system then default attributes should be set""" - required_files = [ - RequiredFile("/mock/path/file1.txt"), - RequiredFile("/mock/path/file2.txt"), - ] - with patch("__builtin__.open", new_callable=mock_open) as mock_file: - mock_file.side_effect = IOError() - verify_required_files_are_present(required_files) - - assert mock_file.call_count == len(required_files) - - for required_file in required_files: - assert not required_file.is_file_present - assert required_file.sha512_on_system is None