[LYN-2470] Integrate resource mapping tool with engine python environment (#17)
1. Add support to use engine python runtime environment. Ideally we should use project executable directory which contains required qt binaries after build. But currently Qt plugins are not put under proper subdirectory which causes huge overhead of loading plugin binaries (see details in this jira https://jira.agscollab.com/browse/LYN-2669 ). The temporary solution is to use AWSCore.Editor target to create a subdirectory for our use case. 2. **Minor Fix** After migrating to engine python environment, see boto3 warning while using debug mode, seems like a existing issue for a long time https://github.com/boto/boto3/issues/454. Register a after call event to close connection 3. **Minor Fix** After migrating to engine python environment, see Qt multithread warning while using debug mode, change direct setter function call to qt signal
This commit is contained in:
+13
-12
@@ -62,7 +62,8 @@ class TestImportResourcesController(TestCase):
|
||||
self._mocked_proxy_model: MagicMock = self._mocked_tree_view.resource_proxy_model
|
||||
|
||||
self._test_import_resources_controller: ImportResourcesController = ImportResourcesController()
|
||||
self._test_import_resources_controller.add_import_resources = MagicMock()
|
||||
self._test_import_resources_controller.add_import_resources_sender = MagicMock()
|
||||
self._test_import_resources_controller.set_notification_frame_text_sender = MagicMock()
|
||||
self._test_import_resources_controller.setup()
|
||||
|
||||
def test_reset_page_resetting_page_with_expected_state(self) -> None:
|
||||
@@ -116,7 +117,7 @@ class TestImportResourcesController(TestCase):
|
||||
self._mocked_import_resources_page.typed_resources_search_button.clicked.connect.call_args[0]
|
||||
|
||||
mocked_call_args[0]() # triggering search_button connected function
|
||||
self._mocked_import_resources_page.set_notification_frame_text.assert_called_once()
|
||||
self._test_import_resources_controller.set_notification_frame_text_sender.emit.assert_called_once()
|
||||
self._mocked_tree_view.reset_view.assert_not_called()
|
||||
self._mocked_import_resources_page.set_current_main_view_index.assert_not_called()
|
||||
|
||||
@@ -170,7 +171,7 @@ class TestImportResourcesController(TestCase):
|
||||
mock_aws_utils.list_cloudformation_stacks.assert_called_once_with(
|
||||
TestImportResourcesController._expected_region)
|
||||
mock_aws_utils.list_cloudformation_stack_resources.assert_not_called()
|
||||
self._mocked_import_resources_page.set_notification_frame_text.assert_called_once()
|
||||
self._test_import_resources_controller.set_notification_frame_text_sender.emit.assert_called_once()
|
||||
self._mocked_proxy_model.load_resource.assert_not_called()
|
||||
self._mocked_proxy_model.emit_source_model_layout_changed.assert_called_once()
|
||||
self._mocked_import_resources_page.set_current_main_view_index.assert_called_with(
|
||||
@@ -195,7 +196,7 @@ class TestImportResourcesController(TestCase):
|
||||
TestImportResourcesController._expected_region)
|
||||
mock_aws_utils.list_cloudformation_stack_resources.assert_called_once_with(
|
||||
TestImportResourcesController._expected_cfn_stack_name, TestImportResourcesController._expected_region)
|
||||
self._mocked_import_resources_page.set_notification_frame_text.assert_called_once()
|
||||
self._test_import_resources_controller.set_notification_frame_text_sender.emit.assert_called_once()
|
||||
self._mocked_proxy_model.load_resource.assert_not_called()
|
||||
self._mocked_proxy_model.emit_source_model_layout_changed.assert_called_once()
|
||||
self._mocked_import_resources_page.set_current_main_view_index.assert_called_with(
|
||||
@@ -258,8 +259,8 @@ class TestImportResourcesController(TestCase):
|
||||
self._mocked_import_resources_page.cfn_stacks_import_button.clicked.connect.call_args[0]
|
||||
|
||||
mocked_call_args[0]() # triggering cfn_stacks_import_button connected function
|
||||
self._test_import_resources_controller.add_import_resources.emit.assert_not_called()
|
||||
self._mocked_import_resources_page.set_notification_frame_text.assert_called_once()
|
||||
self._test_import_resources_controller.add_import_resources_sender.emit.assert_not_called()
|
||||
self._test_import_resources_controller.set_notification_frame_text_sender.emit.assert_called_once()
|
||||
|
||||
def test_page_cfn_stacks_import_button_emit_signal_with_expected_resources_and_switch_to_expected_page(self) -> None:
|
||||
self._mocked_proxy_model.deduplicate_selected_import_resources.return_value = \
|
||||
@@ -268,7 +269,7 @@ class TestImportResourcesController(TestCase):
|
||||
self._mocked_import_resources_page.cfn_stacks_import_button.clicked.connect.call_args[0]
|
||||
|
||||
mocked_call_args[0]() # triggering cfn_stacks_import_button connected function
|
||||
self._test_import_resources_controller.add_import_resources.emit.assert_called_once_with(
|
||||
self._test_import_resources_controller.add_import_resources_sender.emit.assert_called_once_with(
|
||||
[TestImportResourcesController._expected_lambda_resource])
|
||||
self._mocked_view_manager.switch_to_view_edit_page.assert_called_once()
|
||||
self._mocked_tree_view.reset_view.assert_called_once()
|
||||
@@ -329,7 +330,7 @@ class TestImportResourcesController(TestCase):
|
||||
|
||||
mock_aws_utils.list_lambda_functions.assert_called_once_with(
|
||||
TestImportResourcesController._expected_region)
|
||||
self._mocked_import_resources_page.set_notification_frame_text.assert_called_once()
|
||||
self._test_import_resources_controller.set_notification_frame_text_sender.emit.assert_called_once()
|
||||
self._mocked_proxy_model.load_resource.assert_not_called()
|
||||
self._mocked_proxy_model.emit_source_model_layout_changed.assert_called_once()
|
||||
self._mocked_import_resources_page.set_current_main_view_index.assert_called_with(
|
||||
@@ -348,7 +349,7 @@ class TestImportResourcesController(TestCase):
|
||||
mocked_async_call_args: call = mock_thread_manager.get_instance.return_value.start.call_args[0]
|
||||
mocked_async_call_args[0].run() # triggering async function
|
||||
|
||||
self._mocked_import_resources_page.set_notification_frame_text.assert_called_once()
|
||||
self._test_import_resources_controller.set_notification_frame_text_sender.emit.assert_called_once()
|
||||
self._mocked_proxy_model.load_resource.assert_not_called()
|
||||
self._mocked_proxy_model.emit_source_model_layout_changed.assert_called_once()
|
||||
self._mocked_import_resources_page.set_current_main_view_index.assert_called_with(
|
||||
@@ -383,8 +384,8 @@ class TestImportResourcesController(TestCase):
|
||||
self._mocked_import_resources_page.typed_resources_import_button.clicked.connect.call_args[0]
|
||||
|
||||
mocked_call_args[0]() # triggering typed_resources_import_button connected function
|
||||
self._test_import_resources_controller.add_import_resources.emit.assert_not_called()
|
||||
self._mocked_import_resources_page.set_notification_frame_text.assert_called_once()
|
||||
self._test_import_resources_controller.add_import_resources_sender.emit.assert_not_called()
|
||||
self._test_import_resources_controller.set_notification_frame_text_sender.emit.assert_called_once()
|
||||
|
||||
def test_page_typed_resources_import_button_emit_signal_with_expected_resources_and_switch_to_expected_page(self) -> None:
|
||||
self._mocked_proxy_model.deduplicate_selected_import_resources.return_value = \
|
||||
@@ -393,7 +394,7 @@ class TestImportResourcesController(TestCase):
|
||||
self._mocked_import_resources_page.typed_resources_import_button.clicked.connect.call_args[0]
|
||||
|
||||
mocked_call_args[0]() # triggering typed_resources_import_button connected function
|
||||
self._test_import_resources_controller.add_import_resources.emit.assert_called_once_with(
|
||||
self._test_import_resources_controller.add_import_resources_sender.emit.assert_called_once_with(
|
||||
[TestImportResourcesController._expected_lambda_resource])
|
||||
self._mocked_view_manager.switch_to_view_edit_page.assert_called_once()
|
||||
self._mocked_tree_view.reset_view.assert_called_once()
|
||||
|
||||
+14
-12
@@ -62,10 +62,12 @@ class TestViewEditController(TestCase):
|
||||
self._mocked_proxy_model: MagicMock = self._mocked_table_view.resource_proxy_model
|
||||
|
||||
self._test_view_edit_controller: ViewEditController = ViewEditController()
|
||||
self._test_view_edit_controller.set_notification_frame_text_sender = MagicMock()
|
||||
self._test_view_edit_controller.set_notification_page_frame_text_sender = MagicMock()
|
||||
self._test_view_edit_controller.setup()
|
||||
|
||||
def test_add_import_resources_expected_resource_gets_loaded_into_model(self) -> None:
|
||||
self._test_view_edit_controller.add_import_resources([TestViewEditController._expected_resource])
|
||||
self._test_view_edit_controller.add_import_resources_receiver([TestViewEditController._expected_resource])
|
||||
|
||||
self._mocked_proxy_model.add_resource.assert_called_once()
|
||||
mocked_call_args: call = self._mocked_proxy_model.add_resource.call_args[0] # mock call args index is 0
|
||||
@@ -128,7 +130,7 @@ class TestViewEditController(TestCase):
|
||||
self._mocked_proxy_model.emit_source_model_layout_changed.assert_not_called()
|
||||
self._mocked_proxy_model.load_resource.assert_not_called()
|
||||
self._mocked_view_edit_page.set_table_view_page_interactions_enabled.assert_called_with(False)
|
||||
self._mocked_view_edit_page.set_notification_frame_text.assert_called_once()
|
||||
self._test_view_edit_controller.set_notification_frame_text_sender.emit.assert_called_once()
|
||||
self._mocked_view_edit_page.set_current_main_view_index.assert_called_with(
|
||||
ViewEditPageConstants.TABLE_VIEW_PAGE_INDEX)
|
||||
|
||||
@@ -189,7 +191,7 @@ class TestViewEditController(TestCase):
|
||||
mock_json_utils.validate_json_dict_according_to_json_schema.assert_called_once_with({})
|
||||
mock_json_utils.convert_json_dict_to_resources.assert_not_called()
|
||||
self._mocked_proxy_model.load_resource.assert_not_called()
|
||||
self._mocked_view_edit_page.set_notification_frame_text.assert_called_once()
|
||||
self._test_view_edit_controller.set_notification_frame_text_sender.emit.assert_called_once()
|
||||
self._mocked_view_edit_page.set_table_view_page_interactions_enabled.assert_called_with(False)
|
||||
|
||||
@patch("controller.view_edit_controller.file_utils")
|
||||
@@ -239,7 +241,7 @@ class TestViewEditController(TestCase):
|
||||
self._mocked_view_edit_page.config_file_combobox.currentText.assert_called_once()
|
||||
self._mocked_table_view.reset_view.assert_called_once()
|
||||
self._mocked_proxy_model.override_resource_status.assert_called_once()
|
||||
self._mocked_view_edit_page.set_notification_frame_text.assert_called_once()
|
||||
self._test_view_edit_controller.set_notification_frame_text_sender.emit.assert_called_once()
|
||||
self._mocked_proxy_model.emit_source_model_layout_changed.assert_has_calls([call(), call()])
|
||||
self._mocked_view_edit_page.set_current_main_view_index.assert_called_with(
|
||||
ViewEditPageConstants.TABLE_VIEW_PAGE_INDEX)
|
||||
@@ -275,7 +277,7 @@ class TestViewEditController(TestCase):
|
||||
|
||||
mocked_call_args[0]() # triggering config_location_button connected function
|
||||
mock_file_dialog.getExistingDirectory.assert_called_once()
|
||||
self._mocked_view_edit_page.set_notification_page_text.assert_called_with(
|
||||
self._test_view_edit_controller.set_notification_page_frame_text_sender.emit.assert_called_with(
|
||||
notification_label_text.NOTIFICATION_LOADING_MESSAGE)
|
||||
self._mocked_view_edit_page.set_current_main_view_index.assert_called_with(
|
||||
ViewEditPageConstants.NOTIFICATION_PAGE_INDEX)
|
||||
@@ -303,7 +305,7 @@ class TestViewEditController(TestCase):
|
||||
expected_new_config_directory, constants.RESOURCE_MAPPING_CONFIG_FILE_NAME_SUFFIX)
|
||||
assert self._mocked_configuration_manager.configuration.config_files == []
|
||||
self._mocked_view_edit_page.set_config_files.assert_called_with([])
|
||||
self._mocked_view_edit_page.set_notification_page_text.assert_called_once_with(
|
||||
self._test_view_edit_controller.set_notification_page_frame_text_sender.emit.assert_called_once_with(
|
||||
notification_label_text.NOTIFICATION_LOADING_MESSAGE)
|
||||
|
||||
@patch("controller.view_edit_controller.ThreadManager")
|
||||
@@ -325,7 +327,7 @@ class TestViewEditController(TestCase):
|
||||
expected_new_config_directory, constants.RESOURCE_MAPPING_CONFIG_FILE_NAME_SUFFIX)
|
||||
assert self._mocked_configuration_manager.configuration.config_files == []
|
||||
self._mocked_view_edit_page.set_config_files.assert_called_with([])
|
||||
self._mocked_view_edit_page.set_notification_page_text.assert_called_once_with(
|
||||
self._test_view_edit_controller.set_notification_page_frame_text_sender.emit.assert_called_once_with(
|
||||
notification_label_text.NOTIFICATION_LOADING_MESSAGE)
|
||||
|
||||
@patch("controller.view_edit_controller.ThreadManager")
|
||||
@@ -348,7 +350,7 @@ class TestViewEditController(TestCase):
|
||||
expected_new_config_directory, constants.RESOURCE_MAPPING_CONFIG_FILE_NAME_SUFFIX)
|
||||
assert self._mocked_configuration_manager.configuration.config_files == expected_new_config_files
|
||||
self._mocked_view_edit_page.set_config_files.assert_called_with(expected_new_config_files)
|
||||
self._mocked_view_edit_page.set_notification_page_text.assert_called_once_with(
|
||||
self._test_view_edit_controller.set_notification_page_frame_text_sender.emit.assert_called_once_with(
|
||||
notification_label_text.NOTIFICATION_LOADING_MESSAGE)
|
||||
|
||||
def test_page_add_row_button_expected_resource_gets_loaded_into_model(self) -> None:
|
||||
@@ -395,7 +397,7 @@ class TestViewEditController(TestCase):
|
||||
|
||||
mocked_call_args[0]() # triggering save_changes_button connected function
|
||||
self._mocked_proxy_model.override_resource_status.assert_called_once()
|
||||
self._mocked_view_edit_page.set_notification_frame_text.assert_called_once()
|
||||
self._test_view_edit_controller.set_notification_frame_text_sender.emit.assert_called_once()
|
||||
self._mocked_proxy_model.override_all_resources_status.assert_not_called()
|
||||
|
||||
@patch("controller.view_edit_controller.json_utils")
|
||||
@@ -451,7 +453,7 @@ class TestViewEditController(TestCase):
|
||||
mock_json_utils.convert_resources_to_json_dict.assert_called_once()
|
||||
mock_json_utils.write_into_json_file.assert_called_once_with(
|
||||
TestViewEditController._expected_config_file_full_path, expected_json_dict)
|
||||
self._mocked_view_edit_page.set_notification_frame_text.assert_called_once()
|
||||
self._test_view_edit_controller.set_notification_frame_text_sender.emit.assert_called_once()
|
||||
self._mocked_proxy_model.override_all_resources_status.assert_not_called()
|
||||
|
||||
def test_page_search_filter_input_invoke_proxy_model_with_expected_filter_text(self) -> None:
|
||||
@@ -498,7 +500,7 @@ class TestViewEditController(TestCase):
|
||||
mock_file_utils.join_path.assert_called_once()
|
||||
mock_json_utils.create_empty_resource_mapping_file.assert_called_once()
|
||||
mock_file_utils.find_files_with_suffix_under_directory.assert_not_called()
|
||||
self._mocked_view_edit_page.set_notification_frame_text.assert_called_once()
|
||||
self._test_view_edit_controller.set_notification_frame_text_sender.emit.assert_called_once()
|
||||
|
||||
@patch("controller.view_edit_controller.file_utils")
|
||||
def test_page_rescan_button_post_notification_when_find_files_throw_exception(
|
||||
@@ -509,4 +511,4 @@ class TestViewEditController(TestCase):
|
||||
|
||||
mocked_call_args[0]() # triggering rescan_button connected function
|
||||
mock_file_utils.find_files_with_suffix_under_directory.assert_called_once()
|
||||
self._mocked_view_edit_page.set_notification_frame_text.assert_called_once()
|
||||
self._test_view_edit_controller.set_notification_frame_text_sender.emit.assert_called_once()
|
||||
|
||||
+2
-2
@@ -55,5 +55,5 @@ class TestControllerManager(TestCase):
|
||||
TestControllerManager._expected_controller_manager.setup()
|
||||
mocked_view_edit_controller.setup.assert_called_once()
|
||||
mocked_import_resources_controller.setup.assert_called_once()
|
||||
mocked_import_resources_controller.add_import_resources.connect.assert_called_once_with(
|
||||
mocked_view_edit_controller.add_import_resources)
|
||||
mocked_import_resources_controller.add_import_resources_sender.connect.assert_called_once_with(
|
||||
mocked_view_edit_controller.add_import_resources_receiver)
|
||||
|
||||
@@ -18,7 +18,7 @@ from manager.view_manager import (ViewManager, ViewManagerConstants)
|
||||
|
||||
class TestViewManager(TestCase):
|
||||
"""
|
||||
ThreadManager unit test cases
|
||||
ViewManager unit test cases
|
||||
"""
|
||||
_mock_import_resources_page: MagicMock
|
||||
_mock_view_edit_page: MagicMock
|
||||
@@ -36,6 +36,8 @@ class TestViewManager(TestCase):
|
||||
|
||||
main_window_patcher: patch = patch("manager.view_manager.QMainWindow")
|
||||
cls._mock_main_window = main_window_patcher.start()
|
||||
window_icon_patcher: patch = patch("manager.view_manager.QPixmap")
|
||||
window_icon_patcher.start()
|
||||
|
||||
stacked_pages_patcher: patch = patch("manager.view_manager.QStackedWidget")
|
||||
cls._mock_stacked_pages = stacked_pages_patcher.start()
|
||||
|
||||
+44
@@ -0,0 +1,44 @@
|
||||
"""
|
||||
All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
its licensors.
|
||||
|
||||
For complete copyright and license terms please see the LICENSE at the root of this
|
||||
distribution (the "License"). All use of this software is governed by the License,
|
||||
or, if provided, by the license below or the license accompanying this file. Do not
|
||||
remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
"""
|
||||
|
||||
from typing import List
|
||||
from unittest import TestCase
|
||||
from unittest.mock import (ANY, call, MagicMock, patch)
|
||||
|
||||
from model import constants
|
||||
from model.basic_resource_attributes import (BasicResourceAttributes, BasicResourceAttributesBuilder)
|
||||
from utils import environment_utils
|
||||
|
||||
|
||||
class TestEnvironmentUtils(TestCase):
|
||||
"""
|
||||
environment utils unit test cases
|
||||
"""
|
||||
def setUp(self) -> None:
|
||||
os_environ_patcher: patch = patch("os.environ")
|
||||
self.addCleanup(os_environ_patcher.stop)
|
||||
self._mock_os_environ: MagicMock = os_environ_patcher.start()
|
||||
|
||||
os_pathsep_patcher: patch = patch("os.pathsep")
|
||||
self.addCleanup(os_pathsep_patcher.stop)
|
||||
self._mock_os_pathsep: MagicMock = os_pathsep_patcher.start()
|
||||
|
||||
def test_setup_qt_environment_global_flag_is_set(self) -> None:
|
||||
environment_utils.setup_qt_environment("dummy")
|
||||
self._mock_os_environ.copy.assert_called_once()
|
||||
self._mock_os_pathsep.join.assert_called_once()
|
||||
assert environment_utils.is_qt_linked() is True
|
||||
|
||||
def test_cleanup_qt_environment_global_flag_is_set(self) -> None:
|
||||
environment_utils.setup_qt_environment("dummy")
|
||||
assert environment_utils.is_qt_linked() is True
|
||||
environment_utils.cleanup_qt_environment()
|
||||
assert environment_utils.is_qt_linked() is False
|
||||
@@ -30,10 +30,6 @@ class TestFileUtils(TestCase):
|
||||
self.addCleanup(path_patcher.stop)
|
||||
self._mock_path: MagicMock = path_patcher.start()
|
||||
|
||||
windows_path_patcher: patch = patch("pathlib.WindowsPath")
|
||||
self.addCleanup(windows_path_patcher.stop)
|
||||
self._mock_windows_path: MagicMock = windows_path_patcher.start()
|
||||
|
||||
def test_check_path_exists_returns_true(self) -> None:
|
||||
mocked_path: MagicMock = self._mock_path.return_value
|
||||
mocked_path.exists.return_value = True
|
||||
@@ -105,12 +101,35 @@ class TestFileUtils(TestCase):
|
||||
assert not actual_files
|
||||
|
||||
def test_join_path_return_expected_result(self) -> None:
|
||||
mocked_windows_path: MagicMock = self._mock_windows_path.return_value
|
||||
mocked_path: MagicMock = self._mock_path.return_value
|
||||
expected_join_path_name: str = f"{TestFileUtils._expected_path_name}{TestFileUtils._expected_file_name}"
|
||||
mocked_windows_path.joinpath.return_value = expected_join_path_name
|
||||
mocked_path.joinpath.return_value = expected_join_path_name
|
||||
|
||||
actual_join_path_name: str = file_utils.join_path(TestFileUtils._expected_path_name,
|
||||
TestFileUtils._expected_file_name)
|
||||
self._mock_windows_path.assert_called_once_with(TestFileUtils._expected_path_name)
|
||||
mocked_windows_path.joinpath.assert_called_once_with(TestFileUtils._expected_file_name)
|
||||
self._mock_path.assert_called_once_with(TestFileUtils._expected_path_name)
|
||||
mocked_path.joinpath.assert_called_once_with(TestFileUtils._expected_file_name)
|
||||
assert actual_join_path_name == expected_join_path_name
|
||||
|
||||
def test_normalize_file_path_return_empty_when_input_is_empty(self) -> None:
|
||||
actual_normalized_path: str = file_utils.normalize_file_path("")
|
||||
assert actual_normalized_path == ""
|
||||
|
||||
def test_normalize_file_path_return_expected_result(self) -> None:
|
||||
mocked_path: MagicMock = self._mock_path.return_value
|
||||
expected_resolve_path: str = TestFileUtils._expected_path_name
|
||||
mocked_path.resolve.return_value = expected_resolve_path
|
||||
|
||||
actual_resolve_path: str = file_utils.normalize_file_path("dummy")
|
||||
self._mock_path.assert_called_once()
|
||||
mocked_path.resolve.assert_called_once()
|
||||
assert actual_resolve_path == expected_resolve_path
|
||||
|
||||
def test_normalize_file_path_return_empty_when_exception_raised(self) -> None:
|
||||
mocked_path: MagicMock = self._mock_path.return_value
|
||||
mocked_path.resolve.side_effect = RuntimeError()
|
||||
|
||||
actual_resolve_path: str = file_utils.normalize_file_path("dummy")
|
||||
self._mock_path.assert_called_once()
|
||||
mocked_path.resolve.assert_called_once()
|
||||
assert actual_resolve_path == ""
|
||||
|
||||
Reference in New Issue
Block a user