You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
164 lines
7.6 KiB
Python
164 lines
7.6 KiB
Python
"""
|
|
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.
|
|
|
|
Sample tests to demonstrate typical functionality of PythonTestTools and how to integrate into the BAT.
|
|
"""
|
|
# Workaround for tests which depend on old tools, before they are updated to ly_test_tools and Python 3
|
|
import pytest
|
|
pytest.importorskip('test_tools')
|
|
|
|
# System level imports
|
|
import os
|
|
import subprocess
|
|
|
|
# Basic PythonTestTools imports, in most cases you should always import these
|
|
import test_tools.builtin.fixtures as fixtures
|
|
from test_tools import HOST_PLATFORM, WINDOWS_LAUNCHER
|
|
|
|
# test_tools and shared are modules with a lot of useful utility functions already written, use them!
|
|
# Pick and choose the ones below that you need, don't just blindly copy/paste
|
|
import test_tools.launchers.phase
|
|
import test_tools.shared.process_utils as process_utils
|
|
from test_tools.shared.file_utils import gather_error_logs, clear_out_config_file, delete_screenshot_folder, move_file
|
|
from shared.network_utils import check_for_listening_port
|
|
from test_tools.shared.remote_console_commands import RemoteConsole
|
|
from test_tools.shared.waiter import wait_for
|
|
|
|
|
|
# This is where you should access lumberyard - building, asset processing, finding paths/logs, etc. Do NOT change or
|
|
# remove this unless you know what you're doing.
|
|
# See the documentation for PythonTestTools for more information.
|
|
workspace = fixtures.use_fixture(fixtures.builtin_empty_workspace_fixture, scope='function')
|
|
|
|
# What are fixtures?
|
|
# Fixtures set up a testing process (or test) by running all necessary code to satisfy its preconditions.
|
|
# More reading here: https://docs.pytest.org/en/latest/fixture.html
|
|
|
|
# This is a shared instance of the remote console that be used across multiple tests. It must have the @pytest.fixture!
|
|
# You should remove this if you aren't going to use the remote console.
|
|
@pytest.fixture
|
|
def remote_console_instance(request):
|
|
"""
|
|
Creates a remote console instance to send console commands.
|
|
"""
|
|
console = RemoteConsole()
|
|
|
|
def teardown():
|
|
try:
|
|
console.stop()
|
|
except:
|
|
pass
|
|
|
|
request.addfinalizer(teardown)
|
|
|
|
return console
|
|
|
|
|
|
# This is a shared instance of the launcher that can be used across multiple tests within this file and any that it
|
|
# includes. It must have the @pytest.fixture for pytest to automatically pass it around!
|
|
# You should remove this if you aren't going to use the level-specific launchers.
|
|
@pytest.fixture
|
|
def launcher_instance(request, workspace, level):
|
|
"""
|
|
Creates a launcher fixture instance with an extra teardown for error log grabbing.
|
|
"""
|
|
def teardown_launcher_copy_logs():
|
|
"""
|
|
Tries to grab any error logs before moving on to the next test.
|
|
"""
|
|
|
|
for file_name in os.listdir(launcher.workspace.release.paths.project_log()):
|
|
move_file(launcher.workspace.release.paths.project_log(),
|
|
launcher.workspace.artifact_manager.get_save_artifact_path(),
|
|
file_name)
|
|
|
|
logs_exist = lambda: gather_error_logs(
|
|
launcher.workspace.release.paths.dev(),
|
|
launcher.workspace.artifact_manager.get_save_artifact_path())
|
|
try:
|
|
test_tools.shared.waiter.wait_for(logs_exist)
|
|
except AssertionError:
|
|
print("No error logs found. Completing test...")
|
|
|
|
request.addfinalizer(teardown_launcher_copy_logs)
|
|
|
|
launcher = fixtures.launcher(request, workspace, level)
|
|
return launcher
|
|
|
|
# For the rest of the file, these are sample tests that you should remove entirely, or cannibalize them to help your
|
|
# own test-writing process.
|
|
class TestSamplesAPBatch:
|
|
|
|
# This is a shared instance of test teardown that will be used across all tests in this class.
|
|
# It must have the @pytest.fixture(autouse=True)!
|
|
@pytest.fixture(autouse=True)
|
|
def setup_teardown(self, request):
|
|
|
|
# This is the teardown function that will be run after *each* test finishes
|
|
def teardown():
|
|
pass
|
|
|
|
# This is the setup section that will be run before *each* test starts
|
|
request.addfinalizer(teardown)
|
|
|
|
# mark.BAT adds this test to the BAT.
|
|
# mark.test_case is used to link to your testrail id.
|
|
# mark.parameterize allows you to run the same test multiple times but with different parameters, such as platform,
|
|
# configuration, project, level, and more. See more on parameters here: https://docs.pytest.org/en/latest/parametrize.html
|
|
@pytest.mark.BAT
|
|
@pytest.mark.test_case(testrail_id='Foo')
|
|
@pytest.mark.parametrize('platform,configuration,project,spec', (
|
|
pytest.param('win_x64_vs2017', 'profile', 'StarterGame', 'all',
|
|
marks=pytest.mark.skipif(HOST_PLATFORM != 'win_x64', reason='Only supported on Windows hosts')),
|
|
pytest.param('darwin_x64', 'profile', 'StarterGame', 'all',
|
|
marks=pytest.mark.skipif(HOST_PLATFORM != 'darwin_x64', reason='Only supported on Mac hosts')),
|
|
))
|
|
def test_RunAPBatch_WorkspacePreconfigured_NoLeftoverProcessesExist(self, workspace):
|
|
"""
|
|
Tests that the Asset Processor Batch and run and doesn't leave leftover processes.
|
|
"""
|
|
# Your function docstrings (the above text) will be part of the test catalog!
|
|
|
|
subprocess.check_call([os.path.join(workspace.release.paths.bin(), 'AssetProcessorBatch')])
|
|
|
|
# This is how you should do timeouts
|
|
wait_for(lambda: not process_utils.process_exists('AssetProcessorBatch', True), timeout=10)
|
|
|
|
# Make sure to include an informative assert message to make debugging easier
|
|
assert not process_utils.process_exists('rc', True), 'rc process still exists'
|
|
assert not process_utils.process_exists('AssetBuilder', True), 'AssetBuilder process still exists'
|
|
|
|
|
|
# Notice that you can put the marks both on the class and on the individual methods (seen above).
|
|
@pytest.mark.BAT
|
|
@pytest.mark.parametrize("platform,configuration,project,spec,level", [
|
|
pytest.param("win_x64_vs2017", "profile", "StarterGame", "all", "StarterGame",
|
|
marks=pytest.mark.skipif(not WINDOWS_LAUNCHER, reason="Only supported on Windows hosts")),
|
|
pytest.param("win_x64_vs2019", "profile", "StarterGame", "all", "StarterGame",
|
|
marks=pytest.mark.skipif(not WINDOWS_LAUNCHER, reason="Only supported on Windows hosts"))
|
|
])
|
|
class TestSamplesRemoteConsole(object):
|
|
|
|
# Notice here that both the launcher_instance and remote_console_instance fixtures are being reused from above
|
|
def test_LaunchRemoteConsoleAndLauncher_CanLaunch(self, launcher_instance, platform, configuration, project, spec,
|
|
level, remote_console_instance):
|
|
"""
|
|
Verifies launcher & remote console can successfully launch. Notice that there are no asserts here, and that is
|
|
because the called functions will raise exceptions if there is unexpected behavior.
|
|
"""
|
|
launcher_instance.launch()
|
|
|
|
launcher_instance.run(test_tools.launchers.phase.TimePhase(120, 120))
|
|
|
|
test_tools.shared.waiter.wait_for(lambda: check_for_listening_port(4600), timeout=300,
|
|
exc=AssertionError('Port 4600 not listening.'))
|
|
|
|
remote_console_instance.start()
|