Merging main and resolving conflicts

This commit is contained in:
jckand
2021-04-26 09:54:32 -05:00
109 changed files with 4710 additions and 5981 deletions
+53 -39
View File
@@ -16,39 +16,53 @@
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
#if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS)
# ly_add_pytest(
# NAME AutomatedTesting::PhysicsTests
# TEST_SUITE main
# TEST_SERIAL
# PATH ${CMAKE_CURRENT_LIST_DIR}/physics/TestSuite_Active.py
# TIMEOUT 3600
# RUNTIME_DEPENDENCIES
# Legacy::Editor
# Legacy::CryRenderNULL
# AZ::AssetProcessor
# AutomatedTesting.Assets
# COMPONENT
# Physics
# )
# ly_add_pytest(
# NAME AutomatedTesting::PhysicsTests_Sandbox
# TEST_SUITE sandbox
# TEST_SERIAL
# PATH ${CMAKE_CURRENT_LIST_DIR}/physics/TestSuite_Sandbox.py
# TIMEOUT 3600
# RUNTIME_DEPENDENCIES
# Legacy::Editor
# Legacy::CryRenderNULL
# AZ::AssetProcessor
# AutomatedTesting.Assets
# COMPONENT
# Physics
# )
#endif()
if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS)
ly_add_pytest(
NAME AutomatedTesting::PhysicsTests_Main
TEST_SUITE main
TEST_SERIAL
PATH ${CMAKE_CURRENT_LIST_DIR}/physics/TestSuite_Main.py
TIMEOUT 3600
RUNTIME_DEPENDENCIES
Legacy::Editor
Legacy::CryRenderNULL
AZ::AssetProcessor
AutomatedTesting.Assets
COMPONENT
Physics
)
ly_add_pytest(
NAME AutomatedTesting::PhysicsTests_Periodic
TEST_SUITE periodic
TEST_SERIAL
PATH ${CMAKE_CURRENT_LIST_DIR}/physics/TestSuite_Periodic.py
TIMEOUT 3600
RUNTIME_DEPENDENCIES
Legacy::Editor
Legacy::CryRenderNULL
AZ::AssetProcessor
AutomatedTesting.Assets
COMPONENT
Physics
)
ly_add_pytest(
NAME AutomatedTesting::PhysicsTests_Sandbox
TEST_SUITE sandbox
TEST_SERIAL
PATH ${CMAKE_CURRENT_LIST_DIR}/physics/TestSuite_Sandbox.py
TIMEOUT 3600
RUNTIME_DEPENDENCIES
Legacy::Editor
Legacy::CryRenderNULL
AZ::AssetProcessor
AutomatedTesting.Assets
COMPONENT
Physics
)
endif()
## ScriptCanvas ##
if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS)
@@ -177,7 +191,7 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS AND PAL_TRAIT_
## DynVeg ##
ly_add_pytest(
NAME DynamicVegetationTests_Main
NAME AutomatedTesting::DynamicVegetationTests_Main
TEST_SERIAL
TEST_SUITE main
PATH ${CMAKE_CURRENT_LIST_DIR}/largeworlds/dyn_veg
@@ -193,7 +207,7 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS AND PAL_TRAIT_
)
ly_add_pytest(
NAME DynamicVegetationTests_Sandbox
NAME AutomatedTesting::DynamicVegetationTests_Sandbox
TEST_SERIAL
TEST_SUITE sandbox
PATH ${CMAKE_CURRENT_LIST_DIR}/largeworlds/dyn_veg
@@ -209,7 +223,7 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS AND PAL_TRAIT_
)
ly_add_pytest(
NAME DynamicVegetationTests_Periodic
NAME AutomatedTesting::DynamicVegetationTests_Periodic
TEST_SERIAL
TEST_SUITE periodic
PATH ${CMAKE_CURRENT_LIST_DIR}/largeworlds/dyn_veg
@@ -225,7 +239,7 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS AND PAL_TRAIT_
## LandscapeCanvas ##
ly_add_pytest(
NAME LandscapeCanvasTests_Main
NAME AutomatedTesting::LandscapeCanvasTests_Main
TEST_SERIAL
TEST_SUITE main
PATH ${CMAKE_CURRENT_LIST_DIR}/largeworlds/landscape_canvas
@@ -240,7 +254,7 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS AND PAL_TRAIT_
)
ly_add_pytest(
NAME LandscapeCanvasTests_Periodic
NAME AutomatedTesting::LandscapeCanvasTests_Periodic
TEST_SERIAL
TEST_SUITE periodic
PATH ${CMAKE_CURRENT_LIST_DIR}/largeworlds/landscape_canvas
@@ -256,7 +270,7 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS AND PAL_TRAIT_
## GradientSignal ##
ly_add_pytest(
NAME GradientSignalTests_Periodic
NAME AutomatedTesting::GradientSignalTests_Periodic
TEST_SERIAL
TEST_SUITE periodic
PATH ${CMAKE_CURRENT_LIST_DIR}/largeworlds/gradient_signal
@@ -274,7 +288,7 @@ endif()
## Editor ##
if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS AND PAL_TRAIT_FOUNDATION_TEST_SUPPORTED)
ly_add_pytest(
NAME EditorTests_Periodic
NAME AutomatedTesting::EditorTests_Periodic
TEST_SUITE periodic
TEST_SERIAL
PATH ${CMAKE_CURRENT_LIST_DIR}/editor
@@ -292,7 +306,7 @@ endif()
if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS)
# Unstable, SPEC-3838 will restore
#ly_add_pytest(
# NAME asset_load_benchmark_test
# NAME AutomatedTesting::asset_load_benchmark_test
# TEST_SERIAL
# TEST_SUITE benchmark
# PATH ${CMAKE_CURRENT_LIST_DIR}/streaming/benchmark/asset_load_benchmark_test.py
@@ -278,6 +278,12 @@ class Tracer:
self.function = args[3]
self.message = args[4]
def __str__(self):
return f"Warning: [{self.filename}:{self.function}:{self.line}]: [{self.window}] {self.message}"
def __repr__(self):
return f"[Warning: {self.message}]"
class ErrorInfo:
def __init__(self, args):
self.window = args[0]
@@ -285,6 +291,12 @@ class Tracer:
self.line = args[2]
self.function = args[3]
self.message = args[4]
def __str__(self):
return f"Error: [{self.filename}:{self.function}:{self.line}]: [{self.window}] {self.message}"
def __repr__(self):
return f"[Error: {self.message}]"
class AssertInfo:
def __init__(self, args):
@@ -292,6 +304,12 @@ class Tracer:
self.line = args[1]
self.function = args[2]
self.message = args[3]
def __str__(self):
return f"Assert: [{self.filename}:{self.function}:{self.line}]: {self.message}"
def __repr__(self):
return f"[Assert: {self.message}]"
def _on_warning(self, args):
warningInfo = Tracer.WarningInfo(args)
@@ -0,0 +1,40 @@
#
# 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 AutomatedTesting::AtomRenderer_HydraTests_Main
TEST_SUITE main
PATH ${CMAKE_CURRENT_LIST_DIR}/test_Atom_MainSuite.py
TEST_SERIAL
TIMEOUT 300
RUNTIME_DEPENDENCIES
AssetProcessor
AutomatedTesting.Assets
Editor
)
ly_add_pytest(
NAME AutomatedTesting::AtomRenderer_HydraTests_Sandbox
TEST_SUITE sandbox
PATH ${CMAKE_CURRENT_LIST_DIR}/test_Atom_SandboxSuite.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,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.
"""
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)
# It requires at least one test
def test_Dummy(self, request, editor, level, workspace, project, launcher_platform):
pass
@@ -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,
)
@@ -94,13 +94,13 @@ class TestAutomationBase:
editor_starttime = time.time()
self.logger.debug("Running automated test")
testcase_module_filepath = self._get_testcase_module_filepath(testcase_module)
pycmd = ["--runpythontest", testcase_module_filepath, "-BatchMode", "-autotest_mode", "-NullRenderer"] + extra_cmdline_args
pycmd = ["--runpythontest", testcase_module_filepath, "-BatchMode", "-autotest_mode", "-rhi=null"] + extra_cmdline_args
editor.args.extend(pycmd) # args are added to the WinLauncher start command
editor.start(backupFiles = False, launch_ap = False)
try:
editor.wait(TestAutomationBase.MAX_TIMEOUT)
except WaitTimeoutError:
errors.append(TestRunError("TIMEOUT", "Editor did not close after {TestAutomationBase.MAX_TIMEOUT} seconds, verify the test is ending and the application didn't freeze"))
errors.append(TestRunError("TIMEOUT", f"Editor did not close after {TestAutomationBase.MAX_TIMEOUT} seconds, verify the test is ending and the application didn't freeze"))
editor.kill()
output = editor.get_output()
@@ -118,16 +118,16 @@ class TestAutomationBase:
else:
error_str = "Test failed, no output available..\n"
errors.append(TestRunError("FAILED TEST", error_str))
if return_code != TestAutomationBase.TEST_FAIL_RETCODE: # Crashed
if return_code and return_code != TestAutomationBase.TEST_FAIL_RETCODE: # Crashed
crash_info = "-- No crash log available --"
error_log = os.path.join(workspace.paths.project_log(), 'error.log')
crash_log = os.path.join(workspace.paths.project_log(), 'error.log')
try:
waiter.wait_for(lambda: os.path.exists(error_log), timeout=TestAutomationBase.WAIT_FOR_CRASH_LOG)
waiter.wait_for(lambda: os.path.exists(crash_log), timeout=TestAutomationBase.WAIT_FOR_CRASH_LOG)
except AssertionError:
pass
try:
with open(error_log) as f:
with open(crash_log) as f:
crash_info = f.read()
except Exception as ex:
crash_info += f"\n{str(ex)}"
@@ -24,7 +24,7 @@ class Tests():
# fmt: on
def run():
def C14861501_PhysXCollider_RenderMeshAutoAssigned():
"""
Summary:
Create entity with Mesh component and assign a render mesh to the Mesh component. Add Physics Collider component
@@ -61,7 +61,7 @@ def run():
from asset_utils import Asset
# Asset paths
STATIC_MESH = os.path.join("assets", "c14861501_physxcollider_rendermeshautoassigned", "spherebot", "r0-b_body.cgf")
STATIC_MESH = os.path.join("assets", "c14861501_physxcollider_rendermeshautoassigned", "spherebot", "r0-b_body.azmodel")
PHYSX_MESH = os.path.join(
"assets", "c14861501_physxcollider_rendermeshautoassigned", "spherebot", "r0-b_body.pxmesh"
)
@@ -80,8 +80,8 @@ def run():
# 4) Assign a render mesh asset to Mesh component (the fbx mesh having both Static mesh and PhysX collision Mesh)
mesh_asset = Asset.find_asset_by_path(STATIC_MESH)
mesh_component.set_component_property_value("MeshComponentRenderNode|Mesh asset", mesh_asset.id)
mesh_asset.id = mesh_component.get_component_property_value("MeshComponentRenderNode|Mesh asset")
mesh_component.set_component_property_value("Controller|Configuration|Mesh Asset", mesh_asset.id)
mesh_asset.id = mesh_component.get_component_property_value("Controller|Configuration|Mesh Asset")
Report.result(Tests.assign_mesh_asset, mesh_asset.get_path() == STATIC_MESH.replace(os.sep, "/"))
# 5) Add PhysX Collider component
@@ -95,4 +95,8 @@ def run():
if __name__ == "__main__":
run()
import ImportPathHelper as imports
imports.init()
from utils import Report
Report.start_test(C14861501_PhysXCollider_RenderMeshAutoAssigned)
@@ -62,8 +62,8 @@ def C14861502_PhysXCollider_AssetAutoAssigned():
# Open 3D Engine Imports
import azlmbr.legacy.general as general
MESH_ASSET_PATH = os.path.join("Objects", "SphereBot", "r0-b_body.cgf")
MESH_PROPERTY_PATH = "MeshComponentRenderNode|Mesh asset"
MESH_ASSET_PATH = os.path.join("Objects", "SphereBot", "r0-b_body.azmodel")
MESH_PROPERTY_PATH = "Controller|Configuration|Mesh Asset"
TESTED_PROPERTY_PATH = "Shape Configuration|Asset|PhysX Mesh"
helper.init_idle()
@@ -69,7 +69,7 @@ def run():
import azlmbr.asset as azasset
# Asset paths
STATIC_MESH = os.path.join("assets", "c14861504_rendermeshasset_withnopxasset", "test_asset.cgf")
STATIC_MESH = os.path.join("assets", "c14861504_rendermeshasset_withnopxasset", "test_asset.azmodel")
helper.init_idle()
# 1) Load the empty level
@@ -85,8 +85,8 @@ def run():
# 4) Assign a render mesh asset to Mesh component (the fbx mesh having both Static mesh and PhysX collision Mesh)
mesh_asset = Asset.find_asset_by_path(STATIC_MESH)
mesh_component.set_component_property_value("MeshComponentRenderNode|Mesh asset", mesh_asset.id)
mesh_asset.id = mesh_component.get_component_property_value("MeshComponentRenderNode|Mesh asset")
mesh_component.set_component_property_value("Controller|Configuration|Mesh Asset", mesh_asset.id)
mesh_asset.id = mesh_component.get_component_property_value("Controller|Configuration|Mesh Asset")
Report.result(Tests.assign_mesh_asset, mesh_asset.get_path() == STATIC_MESH.replace(os.sep, "/"))
# 5) Add PhysX Collider component
@@ -27,7 +27,7 @@ class Tests():
# fmt: on
def run():
def C4044695_PhysXCollider_AddMultipleSurfaceFbx():
"""
Summary:
Create entity with Mesh and PhysX Collider components and assign a fbx file in both the components.
@@ -45,12 +45,7 @@ def run():
4) Select the PhysicsAsset shape in the PhysX Collider component
5) Assign the fbx file in PhysX Mesh and Mesh component
6) Check if multiple material slots show up under Materials section in the PhysX Collider component
Note:
- This test file must be called from the Open 3D Engine Editor command terminal
- Any passed and failed tests are written to the Editor.log file.
Parsing the file or running a log_monitor are required to observe the test results.
:return: None
"""
# Builtins
@@ -70,7 +65,7 @@ def run():
SURFACE_TAG_COUNT = 4 # Number of surface tags included in used asset
# Asset paths
STATIC_MESH = os.path.join("assets", "c4044695_physxcollider_addmultiplesurfacefbx", "test.cgf")
STATIC_MESH = os.path.join("assets", "c4044695_physxcollider_addmultiplesurfacefbx", "test.azmodel")
PHYSX_MESH = os.path.join("assets", "c4044695_physxcollider_addmultiplesurfacefbx", "test.pxmesh")
helper.init_idle()
@@ -100,8 +95,8 @@ def run():
Report.result(Tests.assign_px_mesh_asset, px_asset.get_path() == PHYSX_MESH.replace(os.sep, "/"))
mesh_asset = Asset.find_asset_by_path(STATIC_MESH)
mesh_component.set_component_property_value("MeshComponentRenderNode|Mesh asset", mesh_asset.id)
mesh_asset.id = mesh_component.get_component_property_value("MeshComponentRenderNode|Mesh asset")
mesh_component.set_component_property_value("Controller|Configuration|Mesh Asset", mesh_asset.id)
mesh_asset.id = mesh_component.get_component_property_value("Controller|Configuration|Mesh Asset")
Report.result(Tests.assign_mesh_asset, mesh_asset.get_path() == STATIC_MESH.replace(os.sep, "/"))
# 6) Check if multiple material slots show up under Materials section in the PhysX Collider component
@@ -116,4 +111,8 @@ def run():
if __name__ == "__main__":
run()
import ImportPathHelper as imports
imports.init()
from utils import Report
Report.start_test(C4044695_PhysXCollider_AddMultipleSurfaceFbx)
@@ -27,7 +27,7 @@ class Tests():
def C4976236_AddPhysxColliderComponent():
"""
Summary:
Load level with Entity having PhysX Collider component. Verify that editor remains stable in Game mode.
Opens an empty level and creates an Entity with PhysX Collider. Verify that editor remains stable in Game mode.
Expected Behavior:
The Editor is stable there are no warnings or errors.
@@ -37,16 +37,10 @@ def C4976236_AddPhysxColliderComponent():
2) Create test entity
3) Start the Tracer to catch any errors and warnings
4) Add the PhysX Collider component and change shape to box
5) Add Mesh component and an asset
6) Enter game mode
7) Verify there are no errors and warnings in the logs
8) Exit game mode
9) Close the editor
Note:
- This test file must be called from the Open 3D Engine Editor command terminal
- Any passed and failed tests are written to the Editor.log file.
Parsing the file or running a log_monitor are required to observe the test results.
5) Enter game mode
6) Verify there are no errors and warnings in the logs
7) Exit game mode
8) Close the editor
:return: None
"""
@@ -60,7 +54,7 @@ def C4976236_AddPhysxColliderComponent():
from editor_python_test_tools.utils import TestHelper as helper
from editor_python_test_tools.utils import Tracer
from asset_utils import Asset
helper.init_idle()
# 1) Load the level
helper.open_level("Physics", "Base")
@@ -74,17 +68,12 @@ def C4976236_AddPhysxColliderComponent():
# 4) Add the PhysX Collider component and change shape to box
collider_component = test_entity.add_component("PhysX Collider")
Report.result(Tests.add_physx_collider, test_entity.has_component("PhysX Collider"))
collider_component.set_component_property_value('Shape Configuration|Shape', 1)
collider_component.set_component_property_value('Shape Configuration|Shape', azlmbr.physics.ShapeType_Box)
# 5) Add Mesh component and an asset
mesh_component = test_entity.add_component("Mesh")
asset = Asset.find_asset_by_path(r"Objects\default\primitive_cube.cgf")
mesh_component.set_component_property_value('MeshComponentRenderNode|Mesh asset', asset.id)
# 6) Enter game mode
# 5) Enter game mode
helper.enter_game_mode(Tests.enter_game_mode)
# 7) Verify there are no errors and warnings in the logs
# 6) Verify there are no errors and warnings in the logs
success_condition = not (section_tracer.has_errors or section_tracer.has_warnings)
Report.result(Tests.no_errors_and_warnings_found, success_condition)
if not success_condition:
@@ -92,9 +81,8 @@ def C4976236_AddPhysxColliderComponent():
Report.info(f"Warnings found: {section_tracer.warnings}")
if section_tracer.has_errors:
Report.info(f"Errors found: {section_tracer.errors}")
Report.failure(Tests.no_errors_and_warnings_found)
# 8) Exit game mode
# 7) Exit game mode
helper.exit_game_mode(Tests.exit_game_mode)
@@ -0,0 +1,37 @@
"""
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 suite consists of all test cases that are passing and have been verified.
import pytest
import os
import sys
from .FileManagement import FileManagement as fm
from ly_test_tools import LAUNCHERS
sys.path.append(os.path.dirname(os.path.abspath(__file__)) + '/../automatedtesting_shared')
from base import TestAutomationBase
revert_physics_config = fm.file_revert_list(['physxdebugconfiguration.setreg', 'physxdefaultsceneconfiguration.setreg', 'physxsystemconfiguration.setreg'], 'AutomatedTesting/Registry')
@pytest.mark.SUITE_main
@pytest.mark.parametrize("launcher_platform", ['windows_editor'])
@pytest.mark.parametrize("project", ["AutomatedTesting"])
class TestAutomation(TestAutomationBase):
def test_C111111_RigidBody_EnablingGravityWorksUsingNotificationsPoC(self, request, workspace, editor, launcher_platform):
from . import C111111_RigidBody_EnablingGravityWorksUsingNotificationsPoC as test_module
self._run_test(request, workspace, editor, test_module)
@@ -27,26 +27,16 @@ from base import TestAutomationBase
revert_physics_config = fm.file_revert_list(['physxdebugconfiguration.setreg', 'physxdefaultsceneconfiguration.setreg', 'physxsystemconfiguration.setreg'], 'AutomatedTesting/Registry')
@pytest.mark.SUITE_main
@pytest.mark.SUITE_periodic
@pytest.mark.parametrize("launcher_platform", ['windows_editor'])
@pytest.mark.parametrize("project", ["AutomatedTesting"])
class TestAutomation(TestAutomationBase):
# Marking the test as an expected failure due to sporadic failure on Automated Review: SPEC-3146
# The test still runs, but a failure of the test doesn't result in the test run failing
@pytest.mark.xfail(
reason="This test seems to fail sometimes due to it being the first test in the testsuite, we'll duplicate it temporarly."
"Need to figure out the reason why this is the case")
@revert_physics_config
def test_C000000_RigidBody_EnablingGravityWorksPoC_DUPLICATE(self, request, workspace, editor, launcher_platform):
from . import C100000_RigidBody_EnablingGravityWorksPoC as test_module
self._run_test(request, workspace, editor, test_module)
@revert_physics_config
def test_C3510642_Terrain_NotCollideWithTerrain(self, request, workspace, editor, launcher_platform):
from . import C3510642_Terrain_NotCollideWithTerrain as test_module
self._run_test(request, workspace, editor, test_module)
@revert_physics_config
def test_C4976195_RigidBodies_InitialLinearVelocity(self, request, workspace, editor, launcher_platform):
from . import C4976195_RigidBodies_InitialLinearVelocity as test_module
@@ -530,8 +520,4 @@ class TestAutomation(TestAutomationBase):
def test_C100000_RigidBody_EnablingGravityWorksPoC(self, request, workspace, editor, launcher_platform):
from . import C100000_RigidBody_EnablingGravityWorksPoC as test_module
self._run_test(request, workspace, editor, test_module)
def test_C111111_RigidBody_EnablingGravityWorksUsingNotificationsPoC(self, request, workspace, editor, launcher_platform):
from . import C111111_RigidBody_EnablingGravityWorksUsingNotificationsPoC as test_module
self._run_test(request, workspace, editor, test_module)
self._run_test(request, workspace, editor, test_module)