Merge pull request #272 from aws-lumberyard-dev/Atom/jromnoa/add-atomtest-epb-tests-to-automatedtesting

ATOM-15219: Add the Atom component test to the AutomatedTesting project.
This commit is contained in:
jromnoa
2021-04-23 16:55:26 -07:00
committed by GitHub
7 changed files with 541 additions and 1 deletions
@@ -16,6 +16,7 @@
ly_get_list_relative_pal_filename(pal_dir ${CMAKE_CURRENT_LIST_DIR}/Platform/${PAL_PLATFORM_NAME})
add_subdirectory(assetpipeline)
add_subdirectory(atom_renderer)
## Physics ##
# DISABLED - see LYN-2536
@@ -58,7 +58,7 @@ def launch_and_validate_results(request, test_directory, editor, editor_script,
if auto_test_mode:
editor.args.extend(["--autotest_mode"])
if null_renderer:
editor.args.extend(["-NullRenderer"])
editor.args.extend(["-rhi=null"])
with editor.start():
@@ -0,0 +1,29 @@
#
# 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.
#
################################################################################
# Atom Renderer: Automated Tests
# Runs EditorPythonBindings (hydra) scripts inside the Editor to verify test results for the Atom renderer.
################################################################################
if(PAL_TRAIT_BUILD_HOST_TOOLS AND PAL_TRAIT_BUILD_TESTS_SUPPORTED AND AutomatedTesting IN_LIST LY_PROJECTS)
ly_add_pytest(
NAME AtomRenderer::HydraTestsMain
TEST_SUITE main
PATH ${CMAKE_CURRENT_LIST_DIR}/test_Atom_MainSuite.py
TEST_SERIAL
TIMEOUT 300
RUNTIME_DEPENDENCIES
AssetProcessor
AutomatedTesting.Assets
Editor
)
endif()
@@ -0,0 +1,10 @@
"""
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.
"""
@@ -0,0 +1,10 @@
"""
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.
"""
@@ -0,0 +1,271 @@
"""
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.
"""
# This module does a bulk test and update of many components at once.
# Each test case is listed below in the format:
# "Test Case ID: Test Case Title (URL)"
# C32078130: Tone Mapper (https://testrail.agscollab.com/index.php?/cases/view/32078130)
# C32078129: Light (https://testrail.agscollab.com/index.php?/cases/view/32078129)
# C32078131: Radius Weight Modifier (https://testrail.agscollab.com/index.php?/cases/view/32078131)
# C32078127: PostFX Layer (https://testrail.agscollab.com/index.php?/cases/view/32078127)
# C32078126: Point Light (https://testrail.agscollab.com/index.php?/cases/view/32078126)
# C32078125: Physical Sky (https://testrail.agscollab.com/index.php?/cases/view/32078125)
# C32078115: Global Skylight (IBL) (https://testrail.agscollab.com/index.php?/cases/view/32078115)
# C32078121: Exposure Control (https://testrail.agscollab.com/index.php?/cases/view/32078121)
# C32078120: Directional Light (https://testrail.agscollab.com/index.php?/cases/view/32078120)
# C32078119: DepthOfField (https://testrail.agscollab.com/index.php?/cases/view/32078119)
# C32078118: Decal (https://testrail.agscollab.com/index.php?/cases/view/32078118)
# C32078117: Area Light (https://testrail.agscollab.com/index.php?/cases/view/32078117)
import os
import sys
import azlmbr.math as math
import azlmbr.bus as bus
import azlmbr.paths
import azlmbr.asset as asset
import azlmbr.entity as entity
import azlmbr.legacy.general as general
import azlmbr.editor as editor
sys.path.append(os.path.join(azlmbr.paths.devroot, "AutomatedTesting", "Gem", "PythonTests"))
import editor_python_test_tools.hydra_editor_utils as hydra
from editor_python_test_tools.utils import TestHelper
from editor_python_test_tools.editor_test_helper import EditorTestHelper
EditorTestHelper = EditorTestHelper(log_prefix="AtomEditorComponents")
def run():
"""
Summary:
The below common tests are done for each of the components.
1) Addition of component to the entity
2) UNDO/REDO of addition of component
3) Enter/Exit game mode
4) Hide/Show entity containing component
5) Deletion of component
6) UNDO/REDO of deletion of component
Some additional tests for specific components include
1) Assigning value to some properties of each component
2) Verifying if the component is activated only when the required components are added
Expected Result:
1) Component can be added to an entity.
2) The addition of component can be undone and redone.
3) Game mode can be entered/exited without issue.
4) Entity with component can be hidden/shown.
5) Component can be deleted.
6) The deletion of component can be undone and redone.
7) Component is activated only when the required components are added
8) Values can be assigned to the properties of the component
:return: None
"""
def create_entity_undo_redo_component_addition(component_name):
new_entity = hydra.Entity(f"{component_name}")
new_entity.create_entity(math.Vector3(512.0, 512.0, 34.0), [component_name])
general.log(f"{component_name}_test: Component added to the entity: "
f"{hydra.has_components(new_entity.id, [component_name])}")
# undo component addition
general.undo()
TestHelper.wait_for_condition(lambda: not hydra.has_components(new_entity.id, [component_name]), 2.0)
general.log(f"{component_name}_test: Component removed after UNDO: "
f"{not hydra.has_components(new_entity.id, [component_name])}")
# redo component addition
general.redo()
TestHelper.wait_for_condition(lambda: hydra.has_components(new_entity.id, [component_name]), 2.0)
general.log(f"{component_name}_test: Component added after REDO: "
f"{hydra.has_components(new_entity.id, [component_name])}")
return new_entity
def verify_enter_exit_game_mode(component_name):
general.enter_game_mode()
TestHelper.wait_for_condition(lambda: general.is_in_game_mode(), 1.0)
general.log(f"{component_name}_test: Entered game mode: {general.is_in_game_mode()}")
general.exit_game_mode()
TestHelper.wait_for_condition(lambda: not general.is_in_game_mode(), 1.0)
general.log(f"{component_name}_test: Exit game mode: {not general.is_in_game_mode()}")
def verify_hide_unhide_entity(component_name, entity_obj):
def is_entity_hidden(entity_id):
return editor.EditorEntityInfoRequestBus(bus.Event, "IsHidden", entity_id)
editor.EditorEntityAPIBus(bus.Event, "SetVisibilityState", entity_obj.id, False)
general.idle_wait_frames(1)
general.log(f"{component_name}_test: Entity is hidden: {is_entity_hidden(entity_obj.id)}")
editor.EditorEntityAPIBus(bus.Event, "SetVisibilityState", entity_obj.id, True)
general.idle_wait_frames(1)
general.log(f"{component_name}_test: Entity is shown: {not is_entity_hidden(entity_obj.id)}")
def verify_deletion_undo_redo(component_name, entity_obj):
editor.ToolsApplicationRequestBus(bus.Broadcast, "DeleteEntityById", entity_obj.id)
TestHelper.wait_for_condition(lambda: not hydra.find_entity_by_name(entity_obj.name), 1.0)
general.log(f"{component_name}_test: Entity deleted: {not hydra.find_entity_by_name(entity_obj.name)}")
general.undo()
TestHelper.wait_for_condition(lambda: hydra.find_entity_by_name(entity_obj.name) is not None, 1.0)
general.log(f"{component_name}_test: UNDO entity deletion works: "
f"{hydra.find_entity_by_name(entity_obj.name) is not None}")
general.redo()
TestHelper.wait_for_condition(lambda: not hydra.find_entity_by_name(entity_obj.name), 1.0)
general.log(f"{component_name}_test: REDO entity deletion works: "
f"{not hydra.find_entity_by_name(entity_obj.name)}")
def verify_required_component_addition(entity_obj, components_to_add, component_name):
def is_component_enabled(entity_componentid_pair):
return editor.EditorComponentAPIBus(bus.Broadcast, "IsComponentEnabled", entity_componentid_pair)
general.log(
f"{component_name}_test: Entity disabled initially: "
f"{not is_component_enabled(entity_obj.components[0])}")
for component in components_to_add:
entity_obj.add_component(component)
TestHelper.wait_for_condition(lambda: is_component_enabled(entity_obj.components[0]), 1.0)
general.log(
f"{component_name}_test: Entity enabled after adding "
f"required components: {is_component_enabled(entity_obj.components[0])}"
)
def verify_set_property(entity_obj, path, value):
entity_obj.get_set_test(0, path, value)
# Wait for Editor idle loop before executing Python hydra scripts.
TestHelper.init_idle()
# Create a new level.
new_level_name = "tmp_level" # Specified in TestAllComponentsBasicTests.py
heightmap_resolution = 512
heightmap_meters_per_pixel = 1
terrain_texture_resolution = 412
use_terrain = False
# Return codes are ECreateLevelResult defined in CryEdit.h
return_code = general.create_level_no_prompt(
new_level_name, heightmap_resolution, heightmap_meters_per_pixel, terrain_texture_resolution, use_terrain)
if return_code == 1:
general.log(f"{new_level_name} level already exists")
elif return_code == 2:
general.log("Failed to create directory")
elif return_code == 3:
general.log("Directory length is too long")
elif return_code != 0:
general.log("Unknown error, failed to create level")
else:
general.log(f"{new_level_name} level created successfully")
EditorTestHelper.after_level_load(bypass_viewport_resize=True)
# Delete all existing entities initially
search_filter = azlmbr.entity.SearchFilter()
all_entities = entity.SearchBus(azlmbr.bus.Broadcast, "SearchEntities", search_filter)
editor.ToolsApplicationRequestBus(bus.Broadcast, "DeleteEntities", all_entities)
class ComponentTests:
"""Test launcher for each component."""
def __init__(self, component_name, *additional_tests):
self.component_name = component_name
self.additional_tests = additional_tests
self.run_component_tests()
def run_component_tests(self):
# Run common and additional tests
entity_obj = create_entity_undo_redo_component_addition(self.component_name)
# Enter/Exit game mode test
verify_enter_exit_game_mode(self.component_name)
# Any additional tests are executed here
for test in self.additional_tests:
test(entity_obj)
# Hide/Unhide entity test
verify_hide_unhide_entity(self.component_name, entity_obj)
# Deletion/Undo/Redo test
verify_deletion_undo_redo(self.component_name, entity_obj)
# Area Light Component
area_light = "Area Light"
ComponentTests(
area_light, lambda entity_obj: verify_required_component_addition(
entity_obj, ["Capsule Shape"], area_light))
# Decal Component
material_asset_path = os.path.join("Materials", "decal", "aiirship_nose_number_decal.material")
material_asset = asset.AssetCatalogRequestBus(
bus.Broadcast, "GetAssetIdByPath", material_asset_path, math.Uuid(), False)
ComponentTests(
"Decal", lambda entity_obj: verify_set_property(
entity_obj, "Settings|Decal Settings|Material", material_asset))
# DepthOfField Component
camera_entity = hydra.Entity("camera_entity")
camera_entity.create_entity(math.Vector3(512.0, 512.0, 34.0), ["Camera"])
depth_of_field = "DepthOfField"
ComponentTests(
depth_of_field,
lambda entity_obj: verify_required_component_addition(entity_obj, ["PostFX Layer"], depth_of_field),
lambda entity_obj: verify_set_property(
entity_obj, "Controller|Configuration|Camera Entity", camera_entity.id))
# Directional Light Component
ComponentTests(
"Directional Light",
lambda entity_obj: verify_set_property(
entity_obj, "Controller|Configuration|Shadow|Camera", camera_entity.id))
# Exposure Control Component
ComponentTests(
"Exposure Control", lambda entity_obj: verify_required_component_addition(
entity_obj, ["PostFX Layer"], "Exposure Control"))
# Global Skylight (IBL) Component
diffuse_image_path = os.path.join("LightingPresets", "greenwich_park_02_4k_iblskyboxcm.exr.streamingimage")
diffuse_image_asset = asset.AssetCatalogRequestBus(
bus.Broadcast, "GetAssetIdByPath", diffuse_image_path, math.Uuid(), False)
specular_image_path = os.path.join("LightingPresets", "greenwich_park_02_4k_iblskyboxcm.exr.streamingimage")
specular_image_asset = asset.AssetCatalogRequestBus(
bus.Broadcast, "GetAssetIdByPath", specular_image_path, math.Uuid(), False)
ComponentTests(
"Global Skylight (IBL)",
lambda entity_obj: verify_set_property(
entity_obj, "Controller|Configuration|Diffuse Image", diffuse_image_asset),
lambda entity_obj: verify_set_property(
entity_obj, "Controller|Configuration|Specular Image", specular_image_asset))
# Physical Sky Component
ComponentTests("Physical Sky")
# Point Light Component
ComponentTests("Point Light")
# PostFX Layer Component
ComponentTests("PostFX Layer")
# Radius Weight Modifier Component
ComponentTests("Radius Weight Modifier")
# Spot Light Component
ComponentTests("Light")
if __name__ == "__main__":
run()
@@ -0,0 +1,219 @@
"""
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.
"""
import logging
import os
import pytest
import ly_test_tools.environment.file_system as file_system
import editor_python_test_tools.hydra_test_utils as hydra
logger = logging.getLogger(__name__)
EDITOR_TIMEOUT = 60
TEST_DIRECTORY = os.path.join(os.path.dirname(__file__), "atom_hydra_scripts")
@pytest.mark.parametrize("project", ["AutomatedTesting"])
@pytest.mark.parametrize("launcher_platform", ['windows_editor'])
@pytest.mark.parametrize("level", ["tmp_level"])
class TestAtomEditorComponents(object):
@pytest.fixture(autouse=True)
def setup_teardown(self, request, workspace, project, level):
# Cleanup our temp level
file_system.delete(
[os.path.join(workspace.paths.engine_root(), project, "Levels", "AtomLevels", level)], True, True)
def teardown():
# Cleanup our temp level
file_system.delete(
[os.path.join(workspace.paths.engine_root(), project, "Levels", "AtomLevels", level)], True, True)
request.addfinalizer(teardown)
@pytest.mark.test_case_id(
"C32078130", # Tone Mapper
"C32078129", # Light
"C32078131", # Radius Weight Modifier
"C32078127", # PostFX Layer
"C32078126", # Point Light
"C32078125", # Physical Sky
"C32078115", # Global Skylight (IBL)
"C32078121", # Exposure Control
"C32078120", # Directional Light
"C32078119", # DepthOfField
"C32078118") # Decal
def test_AtomEditorComponents_AddedToEntity(self, request, editor, level, workspace, project, launcher_platform):
cfg_args = [level]
expected_lines = [
# Area Light Component
"Area Light Entity successfully created",
"Area Light_test: Component added to the entity: True",
"Area Light_test: Component removed after UNDO: True",
"Area Light_test: Component added after REDO: True",
"Area Light_test: Entered game mode: True",
"Area Light_test: Entity enabled after adding required components: True",
"Area Light_test: Entity is hidden: True",
"Area Light_test: Entity is shown: True",
"Area Light_test: Entity deleted: True",
"Area Light_test: UNDO entity deletion works: True",
"Area Light_test: REDO entity deletion works: True",
# Decal Component
"Decal Entity successfully created",
"Decal_test: Component added to the entity: True",
"Decal_test: Component removed after UNDO: True",
"Decal_test: Component added after REDO: True",
"Decal_test: Entered game mode: True",
"Decal_test: Exit game mode: True",
"Decal Settings|Decal Settings|Material: SUCCESS",
"Decal_test: Entity is hidden: True",
"Decal_test: Entity is shown: True",
"Decal_test: Entity deleted: True",
"Decal_test: UNDO entity deletion works: True",
"Decal_test: REDO entity deletion works: True",
# DepthOfField Component
"DepthOfField Entity successfully created",
"DepthOfField_test: Component added to the entity: True",
"DepthOfField_test: Component removed after UNDO: True",
"DepthOfField_test: Component added after REDO: True",
"DepthOfField_test: Entered game mode: True",
"DepthOfField_test: Exit game mode: True",
"DepthOfField_test: Entity disabled initially: True",
"DepthOfField_test: Entity enabled after adding required components: True",
"DepthOfField Controller|Configuration|Camera Entity: SUCCESS",
"DepthOfField_test: Entity is hidden: True",
"DepthOfField_test: Entity is shown: True",
"DepthOfField_test: Entity deleted: True",
"DepthOfField_test: UNDO entity deletion works: True",
"DepthOfField_test: REDO entity deletion works: True",
# Directional Light Component
"Directional Light Entity successfully created",
"Directional Light_test: Component added to the entity: True",
"Directional Light_test: Component removed after UNDO: True",
"Directional Light_test: Component added after REDO: True",
"Directional Light_test: Entered game mode: True",
"Directional Light_test: Exit game mode: True",
"Directional Light Controller|Configuration|Shadow|Camera: SUCCESS",
"Directional Light_test: Entity is hidden: True",
"Directional Light_test: Entity is shown: True",
"Directional Light_test: Entity deleted: True",
"Directional Light_test: UNDO entity deletion works: True",
"Directional Light_test: REDO entity deletion works: True",
# Exposure Control Component
"Exposure Control Entity successfully created",
"Exposure Control_test: Component added to the entity: True",
"Exposure Control_test: Component removed after UNDO: True",
"Exposure Control_test: Component added after REDO: True",
"Exposure Control_test: Entered game mode: True",
"Exposure Control_test: Exit game mode: True",
"Exposure Control_test: Entity disabled initially: True",
"Exposure Control_test: Entity enabled after adding required components: True",
"Exposure Control_test: Entity is hidden: True",
"Exposure Control_test: Entity is shown: True",
"Exposure Control_test: Entity deleted: True",
"Exposure Control_test: UNDO entity deletion works: True",
"Exposure Control_test: REDO entity deletion works: True",
# Global Skylight (IBL) Component
"Global Skylight (IBL) Entity successfully created",
"Global Skylight (IBL)_test: Component added to the entity: True",
"Global Skylight (IBL)_test: Component removed after UNDO: True",
"Global Skylight (IBL)_test: Component added after REDO: True",
"Global Skylight (IBL)_test: Entered game mode: True",
"Global Skylight (IBL)_test: Exit game mode: True",
"Global Skylight (IBL) Controller|Configuration|Diffuse Image: SUCCESS",
"Global Skylight (IBL) Controller|Configuration|Specular Image: SUCCESS",
"Global Skylight (IBL)_test: Entity is hidden: True",
"Global Skylight (IBL)_test: Entity is shown: True",
"Global Skylight (IBL)_test: Entity deleted: True",
"Global Skylight (IBL)_test: UNDO entity deletion works: True",
"Global Skylight (IBL)_test: REDO entity deletion works: True",
# Physical Sky Component
"Physical Sky Entity successfully created",
"Physical Sky component was added to entity",
"Entity has a Physical Sky component",
"Physical Sky_test: Component added to the entity: True",
"Physical Sky_test: Component removed after UNDO: True",
"Physical Sky_test: Component added after REDO: True",
"Physical Sky_test: Entered game mode: True",
"Physical Sky_test: Exit game mode: True",
"Physical Sky_test: Entity is hidden: True",
"Physical Sky_test: Entity is shown: True",
"Physical Sky_test: Entity deleted: True",
"Physical Sky_test: UNDO entity deletion works: True",
"Physical Sky_test: REDO entity deletion works: True",
# Point Light Component
"Point Light Entity successfully created",
"Point Light_test: Component added to the entity: True",
"Point Light_test: Component removed after UNDO: True",
"Point Light_test: Component added after REDO: True",
"Point Light_test: Entered game mode: True",
"Point Light_test: Exit game mode: True",
"Point Light_test: Entity is hidden: True",
"Point Light_test: Entity is shown: True",
"Point Light_test: Entity deleted: True",
"Point Light_test: UNDO entity deletion works: True",
"Point Light_test: REDO entity deletion works: True",
# PostFX Layer Component
"PostFX Layer Entity successfully created",
"PostFX Layer_test: Component added to the entity: True",
"PostFX Layer_test: Component removed after UNDO: True",
"PostFX Layer_test: Component added after REDO: True",
"PostFX Layer_test: Entered game mode: True",
"PostFX Layer_test: Exit game mode: True",
"PostFX Layer_test: Entity is hidden: True",
"PostFX Layer_test: Entity is shown: True",
"PostFX Layer_test: Entity deleted: True",
"PostFX Layer_test: UNDO entity deletion works: True",
"PostFX Layer_test: REDO entity deletion works: True",
# Radius Weight Modifier Component
"Radius Weight Modifier Entity successfully created",
"Radius Weight Modifier_test: Component added to the entity: True",
"Radius Weight Modifier_test: Component removed after UNDO: True",
"Radius Weight Modifier_test: Component added after REDO: True",
"Radius Weight Modifier_test: Entered game mode: True",
"Radius Weight Modifier_test: Exit game mode: True",
"Radius Weight Modifier_test: Entity is hidden: True",
"Radius Weight Modifier_test: Entity is shown: True",
"Radius Weight Modifier_test: Entity deleted: True",
"Radius Weight Modifier_test: UNDO entity deletion works: True",
"Radius Weight Modifier_test: REDO entity deletion works: True",
# Light Component
"Light Entity successfully created",
"Light_test: Component added to the entity: True",
"Light_test: Component removed after UNDO: True",
"Light_test: Component added after REDO: True",
"Light_test: Entered game mode: True",
"Light_test: Exit game mode: True",
"Light_test: Entity is hidden: True",
"Light_test: Entity is shown: True",
"Light_test: Entity deleted: True",
"Light_test: UNDO entity deletion works: True",
"Light_test: REDO entity deletion works: True",
]
unexpected_lines = [
"failed to open",
"Traceback (most recent call last):",
]
hydra.launch_and_validate_results(
request,
TEST_DIRECTORY,
editor,
"hydra_AtomEditorComponents_AddedToEntity.py",
timeout=EDITOR_TIMEOUT,
expected_lines=expected_lines,
unexpected_lines=unexpected_lines,
halt_on_unexpected=True,
null_renderer=True,
cfg_args=cfg_args,
)