123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321 |
- """
- Copyright (c) Contributors to the Open 3D Engine Project.
- For complete copyright and license terms please see the LICENSE at the root of this distribution.
- SPDX-License-Identifier: Apache-2.0 OR MIT
- Unit tests for ly_test_tools._internal.pytest_plugin.test_tools_fixtures
- """
- import datetime
- import os
- import unittest.mock as mock
- import pytest
- import ly_test_tools._internal.pytest_plugin.test_tools_fixtures as test_tools_fixtures
- pytestmark = pytest.mark.SUITE_smoke
- class TestFixtures(object):
- def test_AddOptionForLogs_MockParser_OptionAdded(self):
- mock_parser = mock.MagicMock()
- test_tools_fixtures.pytest_addoption(mock_parser)
- mock_call = mock_parser.addoption.mock_calls[0]
- """
- mock_call is the same as: call('--output_path', help='Set the folder name for the output logs.')
- which results in a 3-tuple with (name, args, kwargs), so --output_path is in the list of args
- """
- assert mock_call[1][0] == '--output-path'
- def test_RecordSuiteProperty_MockRequestWithEmptyXml_PropertyAdded(self):
- mock_request = mock.MagicMock()
- mock_xml = mock.MagicMock()
- mock_request.config._xml = mock_xml
- func = test_tools_fixtures._record_suite_property(mock_request)
- func('NewProperty', 'value')
- mock_xml.add_global_property.assert_called_once_with('NewProperty', 'value')
- def test_RecordSuiteProperty_MockRequestWithPropertyXml_PropertyUpdated(self):
- mock_request = mock.MagicMock()
- mock_xml = mock.MagicMock()
- mock_xml.global_properties = [('ExistingProperty', 'old value')]
- mock_request.config._xml = mock_xml
- func = test_tools_fixtures._record_suite_property(mock_request)
- func('ExistingProperty', 'new value')
- assert mock_xml.global_properties[0] == ('ExistingProperty', 'new value')
- mock_xml.add_global_property.assert_not_called()
- @mock.patch('ly_test_tools._internal.pytest_plugin.test_tools_fixtures.logger')
- def test_RecordSuiteProperty_MockRequestWithoutXml_NoOpReturned(self, mock_logger):
- mock_request = mock.MagicMock()
- mock_request.config._xml = None
- func = test_tools_fixtures._record_suite_property(mock_request)
- mock_logger.debug.assert_not_called()
- func('SomeProperty', 'some value')
- mock_logger.debug.assert_called_once()
- @mock.patch('os.makedirs')
- def test_LogsPath_CustomPathOption_CustomPathCreated(self, mock_makedirs):
- expected = 'SomePath'
- mock_config = mock.MagicMock()
- mock_config.getoption.return_value = expected
- actual = test_tools_fixtures._get_output_path(mock_config)
- assert actual == expected
- mock_makedirs.assert_called_once_with('SomePath', exist_ok=True)
- @mock.patch('ly_test_tools._internal.pytest_plugin.test_tools_fixtures.datetime',
- mock.Mock(now=lambda: datetime.datetime(2019, 10, 11)))
- @mock.patch('os.getcwd')
- @mock.patch('os.makedirs')
- def test_LogsPath_NoPathOption_DefaultPathCreated(self, mock_makedirs, mock_getcwd):
- mock_config = mock.MagicMock()
- mock_cwd = 'C:/foo'
- mock_getcwd.return_value = mock_cwd
- mock_config.getoption.return_value = None
- expected = os.path.join(mock_cwd,
- 'pytest_results',
- '2019-10-11T00-00-00-000000')
- actual = test_tools_fixtures._get_output_path(mock_config)
- assert actual == expected
- mock_makedirs.assert_called_once_with(expected, exist_ok=True)
- def test_RecordBuildName_MockRecordFunction_MockFunctionCalled(self):
- mock_fn = mock.MagicMock()
- func = test_tools_fixtures._record_build_name(mock_fn)
- func('MyBuild')
- mock_fn.assert_called_once_with('build', 'MyBuild')
- @mock.patch('ly_test_tools._internal.pytest_plugin.test_tools_fixtures.datetime',
- mock.Mock(now=lambda: datetime.datetime(2019, 10, 11)))
- def test_RecordTimeStamp_MockRecordFunction_MockFunctionCalled(self):
- mock_fn = mock.MagicMock()
- test_tools_fixtures._record_test_timestamp(mock_fn)
- mock_fn.assert_called_once_with('timestamp', '2019-10-11T00-00-00-000000')
- @mock.patch('ly_test_tools._internal.pytest_plugin.test_tools_fixtures.datetime',
- mock.Mock(now=lambda: datetime.datetime(2019, 10, 11)))
- @mock.patch('socket.gethostname')
- @mock.patch('getpass.getuser')
- def test_RecordSuiteData_MockRecordFunction_MockFunctionCalled(self, mock_getuser, mock_gethostname):
- mock_getuser.return_value = 'foo@bar.baz'
- mock_gethostname.return_value = 'bar.baz'
- mock_fn = mock.MagicMock()
- test_tools_fixtures._record_suite_data(mock_fn)
- expected_calls = [mock.call('timestamp', '2019-10-11T00-00-00-000000'),
- mock.call('hostname', 'bar.baz'),
- mock.call('username', 'foo@bar.baz')]
- mock_fn.assert_has_calls(expected_calls)
- @mock.patch("ly_test_tools._internal.log.py_logging_util.initialize_logging", mock.MagicMock())
- @mock.patch("ly_test_tools.builtin.helpers.setup_builtin_workspace")
- @mock.patch("ly_test_tools.builtin.helpers.create_builtin_workspace")
- def test_Workspace_MockFixturesAndExecTeardown_ReturnWorkspaceRegisterTeardown(self, mock_create, mock_setup):
- test_module = 'example.tests.test_system_example'
- test_class = ('TestSystemExample.test_SystemTestExample_AllSupportedPlatforms_LaunchAutomatedTesting'
- '[120-simple_jacklocomotion-AutomatedTesting-all-profile-win_x64_vs2017]')
- test_method = 'test_SystemTestExample_AllSupportedPlatforms_LaunchAutomatedTesting'
- artifact_folder_name = 'TheArtifactFolder'
- artifact_path = "PathToArtifacts"
- mock_request = mock.MagicMock()
- mock_request.addfinalizer = mock.MagicMock()
- mock_request.node.module.__name__ = test_module
- mock_request.node.getmodpath.return_value = test_class
- mock_request.node.originalname = test_method
- mock_workspace = mock.MagicMock()
- mock_workspace.artifact_manager.generate_folder_name.return_value = artifact_folder_name
- mock_workspace.artifact_manager.artifact_path = artifact_path
- mock_workspace.artifact_manager.gather_artifacts.return_value = os.path.join(artifact_path, 'foo.zip')
- mock_create.return_value = mock_workspace
- mock_property = mock.MagicMock()
- mock_build_name = mock.MagicMock()
- mock_logs = "foo"
- under_test = test_tools_fixtures._workspace(
- request=mock_request,
- build_directory='foo',
- project="",
- record_property=mock_property,
- record_build_name=mock_build_name,
- output_path=mock_logs,
- asset_processor_platform='ap_platform'
- )
- assert under_test is mock_workspace
- # verify additional commands are called
- mock_create.assert_called_once()
- mock_setup.assert_called_once_with(under_test, artifact_folder_name, mock_request.session.testscollected)
- # verify teardown was hooked but not called
- mock_request.addfinalizer.assert_called_once()
- mock_workspace.teardown.assert_not_called()
- # execute teardown hook from recorded call, and verify called
- mock_request.addfinalizer.call_args[0][0]()
- mock_workspace.teardown.assert_called_once()
- mock_workspace.artifact_manager.generate_folder_name.assert_called_with(
- test_module.split('.')[-1], # 'example.tests.test_system_example' -> 'test_system_example'
- test_class.split('.')[0], # 'TestSystemExample.test_SystemTestExample_...' -> 'TestSystemExample'
- test_method # 'test_SystemTestExample_AllSupportedPlatforms_LaunchAutomatedTesting'
- )
- @mock.patch('os.path.exists', mock.MagicMock(return_value=True))
- @mock.patch("ly_test_tools.launchers.launcher_helper.create_game_launcher")
- def test_Launcher_MockHelper_Passthrough(self, mock_create):
- retval = mock.MagicMock()
- mock_create.return_value = retval
- mock_workspace = mock.MagicMock()
- under_test = test_tools_fixtures._launcher(mock.MagicMock(), mock_workspace, 'windows', 'level')
- mock_create.assert_called_once()
- assert retval is under_test
- @mock.patch('os.path.exists', mock.MagicMock(return_value=True))
- @mock.patch("ly_test_tools.launchers.launcher_helper.create_game_launcher")
- def test_Launcher_MockHelper_TeardownCalled(self, mock_create):
- retval = mock.MagicMock()
- retval.stop = mock.MagicMock()
- mock_create.return_value = retval
- mock_request = mock.MagicMock()
- mock_workspace = mock.MagicMock()
- def _fail_finalizer():
- assert False, "teardown should have been added to finalizer"
- def _capture_finalizer(func):
- nonlocal _finalizer
- _finalizer = func
- _finalizer = _fail_finalizer
- mock_request.addfinalizer = _capture_finalizer
- under_test = test_tools_fixtures._launcher(mock_request, mock_workspace, 'windows', 'level')
- assert retval is under_test
- assert _finalizer is not None
- _finalizer()
- retval.stop.assert_called_once()
- @mock.patch("ly_test_tools.launchers.launcher_helper.create_editor")
- def test_Editor_MockHelper_Passthrough(self, mock_create):
- retval = mock.MagicMock()
- mock_create.return_value = retval
- under_test = test_tools_fixtures._editor(mock.MagicMock(), mock.MagicMock(), 'windows_editor')
- mock_create.assert_called_once()
- assert retval is under_test
- @mock.patch("ly_test_tools.launchers.launcher_helper.create_editor")
- def test_Editor_MockHelper_TeardownCalled(self, mock_create):
- retval = mock.MagicMock()
- retval.stop = mock.MagicMock()
- mock_request = mock.MagicMock()
- mock_create.return_value = retval
- def _fail_finalizer():
- assert False, "teardown should have been added to finalizer"
- def _capture_finalizer(func):
- nonlocal _finalizer
- _finalizer = func
- _finalizer = _fail_finalizer
- mock_request.addfinalizer = _capture_finalizer
- under_test = test_tools_fixtures._editor(mock_request, mock.MagicMock(), 'windows_editor')
- mock_create.assert_called_once()
- assert retval is under_test
- assert _finalizer is not None
- _finalizer()
- retval.stop.assert_called_once()
- @mock.patch('ly_test_tools._internal.pytest_plugin.test_tools_fixtures.get_fixture_argument')
- @mock.patch('ly_test_tools._internal.managers.ly_process_killer.detect_lumberyard_processes')
- @mock.patch('ly_test_tools._internal.managers.ly_process_killer.kill_processes', mock.MagicMock())
- def test_AutomaticProcessKiller_ProcessKillList_KillsDetectedProcesses(self, mock_detect_processes,
- mock_get_fixture_argument):
- mock_processes_list = ['foo', 'bar', 'foobar']
- mock_detected_processes = ['foo', 'bar']
- mock_detect_processes.return_value = mock_detected_processes
- mock_get_fixture_argument.return_value = mock_processes_list
- under_test = test_tools_fixtures._automatic_process_killer(mock_processes_list)
- under_test.detect_lumberyard_processes.assert_called_with(processes_list=mock_processes_list)
- under_test.kill_processes.assert_called_with(processes_list=mock_detected_processes)
- @mock.patch('ly_test_tools.environment.watchdog.CrashLogWatchdog.start', mock.MagicMock())
- @mock.patch('ly_test_tools.environment.watchdog.CrashLogWatchdog')
- def test_CrashLogWatchdog_Instantiates_CreatesWatchdog(self, under_test):
- mock_workspace = mock.MagicMock()
- mock_workspace.paths.crash_log.return_value = mock.MagicMock()
- mock_request = mock.MagicMock()
- mock_request.addfinalizer = mock.MagicMock()
- mock_raise_on_crash = mock.MagicMock()
- mock_watchdog = test_tools_fixtures._crash_log_watchdog(mock_request, mock_workspace, mock_raise_on_crash)
- under_test.assert_called_once_with(mock_workspace.paths.crash_log.return_value, raise_on_condition=mock_raise_on_crash)
- @mock.patch('ly_test_tools.environment.watchdog.CrashLogWatchdog.start')
- def test_CrashLogWatchdog_Instantiates_StartsThread(self, under_test):
- mock_workspace = mock.MagicMock()
- mock_path = 'C:/foo'
- mock_workspace.paths.crash_log.return_value = mock_path
- mock_request = mock.MagicMock()
- mock_request.addfinalizer = mock.MagicMock()
- mock_raise_on_crash = mock.MagicMock()
- test_tools_fixtures._crash_log_watchdog(mock_request, mock_workspace, mock_raise_on_crash)
- under_test.assert_called_once()
- @mock.patch('ly_test_tools.environment.watchdog.CrashLogWatchdog.start', mock.MagicMock())
- def test_CrashLogWatchdog_Instantiates_AddsTeardown(self):
- mock_workspace = mock.MagicMock()
- mock_path = 'C:/foo'
- mock_workspace.paths.crash_log.return_value = mock_path
- mock_request = mock.MagicMock()
- mock_request.addfinalizer = mock.MagicMock()
- mock_raise_on_crash = mock.MagicMock()
- mock_watchdog = test_tools_fixtures._crash_log_watchdog(mock_request, mock_workspace, mock_raise_on_crash)
- mock_request.addfinalizer.assert_called_once()
- @mock.patch('ly_test_tools.environment.watchdog.CrashLogWatchdog.start', mock.MagicMock())
- @mock.patch('ly_test_tools.environment.watchdog.CrashLogWatchdog.stop')
- def test_CrashLogWatchdog_Teardown_CallsStop(self, mock_stop):
- mock_workspace = mock.MagicMock()
- mock_path = 'C:/foo'
- mock_workspace.paths.crash_log.return_value = mock_path
- mock_request = mock.MagicMock()
- mock_request.addfinalizer = mock.MagicMock()
- mock_raise_condition = mock.MagicMock()
- mock_watchdog = test_tools_fixtures._crash_log_watchdog(mock_request, mock_workspace, mock_raise_condition)
- mock_request.addfinalizer.call_args[0][0]()
- mock_stop.assert_called_once()
|