From 11c219701e4cb547fa5c466796e33ff84a57efb2 Mon Sep 17 00:00:00 2001 From: jckand-amzn Date: Fri, 12 Nov 2021 15:47:18 -0600 Subject: [PATCH 1/8] Initial check-in of in-memory prefab creation helpers for Dynamic Vegetation tests Signed-off-by: jckand-amzn --- .../editor_entity_utils.py | 4 +- .../DynVegUtils_TempPrefabCreationWorks.py | 90 +++++++++++++++++++ .../dyn_veg/TestSuite_Periodic_Optimized.py | 22 +++++ .../editor_dynveg_test_helper.py | 55 +++++++++++- 4 files changed, 169 insertions(+), 2 deletions(-) create mode 100644 AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/DynVegUtils_TempPrefabCreationWorks.py create mode 100644 AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/TestSuite_Periodic_Optimized.py diff --git a/AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/editor_python_test_tools/editor_entity_utils.py b/AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/editor_python_test_tools/editor_entity_utils.py index 9e857ed8bc..aee8846afe 100644 --- a/AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/editor_python_test_tools/editor_entity_utils.py +++ b/AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/editor_python_test_tools/editor_entity_utils.py @@ -132,6 +132,7 @@ class EditorEntity: def __init__(self, id: azlmbr.entity.EntityId): self.id: azlmbr.entity.EntityId = id + self.components: List[EditorComponent] = [] # Creation functions @classmethod @@ -258,6 +259,7 @@ class EditorEntity: :return: Component object of newly added component. """ component = self.add_components([component_name])[0] + self.components.append(component) return component def add_components(self, component_names: list) -> List[EditorComponent]: @@ -279,7 +281,7 @@ class EditorEntity: ), f"Failure: Could not add component: '{new_comp.get_component_name()}' to entity: '{self.get_name()}'" new_comp.id = add_component_outcome.GetValue()[0] components.append(new_comp) - + self.components.append(new_comp) return components def get_components_of_type(self, component_names: list) -> List[EditorComponent]: diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/DynVegUtils_TempPrefabCreationWorks.py b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/DynVegUtils_TempPrefabCreationWorks.py new file mode 100644 index 0000000000..d684d7eb02 --- /dev/null +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/DynVegUtils_TempPrefabCreationWorks.py @@ -0,0 +1,90 @@ +""" +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 +""" + + +def DynVegUtils_TempPrefabCreationWorks(): + """ + Summary: + An existing level is opened. Each Prefab setup to be spawned by Dynamic Vegetation tests is created in memory and + validated against existing components/mesh assignments. A spawner is then created with the temporary prefabs to ensure + proper functionality with Dynamic Vegetation components. + + Expected Behavior: + Temporary prefabs contain the expected components/assets. Instances plant as expected in the assigned area. + + Test Steps: + 1) Open an existing level + 2) Create each of the necessary temporary prefabs, and validate the component/mesh setups + 3) Create a Vegetation Layer Spawner setup using the temporary prefabs as Prefab Instance Spawner types + 4) Create a surface to plant on and validate instance counts + 5) Verify expected instance counts + + 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 + """ + + import os + + import azlmbr.editor as editor + import azlmbr.legacy.general as general + import azlmbr.bus as bus + import azlmbr.math as math + + import editor_python_test_tools.hydra_editor_utils as hydra + from largeworlds.large_worlds_utils import editor_dynveg_test_helper as dynveg + from editor_python_test_tools.utils import Report, Tracer + from editor_python_test_tools.utils import TestHelper as helper + from editor_python_test_tools.prefab_utils import Prefab, PrefabInstance, get_prefab_file_path + + with Tracer() as error_tracer: + # Create dictionary for prefab filenames and paths to create using helper function + mesh_prefabs = { + "PinkFlower": os.path.join("assets", "objects", "foliage", "grass_flower_pink.azmodel"), + "PurpleFlower": os.path.join("assets", "objects", "foliage", "grass_flower_purple.azmodel"), + "1m_Cube": os.path.join("objects", "_primitives", "_box_1x1.azmodel"), + "CedarTree": os.path.join("assets", "objects", "foliage", "cedar.azmodel"), + "Bush": os.path.join("assets", "objects", "foliage", "bush_privet_01.azmodel"), + } + + # 1) Open an existing simple level + helper.init_idle() + helper.open_level("Prefab", "Base") + + # 2) Create a Dynamic Vegetation surface in preparation of prefab creation + center_point = math.Vector3(0.0, 0.0, 0.0) + dynveg.create_surface_entity("Planting Surface", center_point, 128.0, 128.0, 1.0) + + # 3) Create each of the Mesh asset prefabs and validate that the prefab created successfully + for prefab_filename, asset_path in mesh_prefabs.items(): + prefab_created = ( + f"Temporary {prefab_filename} prefab created successfully", + f"Failed to create temporary {prefab_filename} prefab" + ) + prefab = dynveg.create_temp_mesh_prefab(asset_path, prefab_filename) + Report.result(prefab_created, helper.wait_for_condition(lambda: PrefabInstance.is_valid(prefab[1]), 3.0)) + + # 4) Assign the temp prefab to the prefab instance spawner, and validate the instance count + #for prefab_filename in mesh_prefabs: + spawner_entity = dynveg.create_prefab_spawner("PrefabSpawner", center_point, 16.0, 16.0, 16.0, + get_prefab_file_path("Sphere")) + + # 5) Report errors/asserts + helper.wait_for_condition(lambda: error_tracer.has_errors or error_tracer.has_asserts, 1.0) + for error_info in error_tracer.errors: + Report.info(f"Error: {error_info.filename} {error_info.function} | {error_info.message}") + for assert_info in error_tracer.asserts: + Report.info(f"Assert: {assert_info.filename} {assert_info.function} | {assert_info.message}") + + general.idle_wait(20.0) +if __name__ == "__main__": + + from editor_python_test_tools.utils import Report + Report.start_test(DynVegUtils_TempPrefabCreationWorks) diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/TestSuite_Periodic_Optimized.py b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/TestSuite_Periodic_Optimized.py new file mode 100644 index 0000000000..764d2dec75 --- /dev/null +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/TestSuite_Periodic_Optimized.py @@ -0,0 +1,22 @@ +""" +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 +""" + +import os +import pytest + +import ly_test_tools.environment.file_system as file_system +from ly_test_tools.o3de.editor_test import EditorSingleTest, EditorSharedTest, EditorParallelTest, EditorTestSuite + + +@pytest.mark.SUITE_main +@pytest.mark.parametrize("launcher_platform", ['windows_editor']) +@pytest.mark.parametrize("project", ["AutomatedTesting"]) +class TestAutomation(EditorTestSuite): + global_extra_cmdline_args = [] + + class test_DynVegUtils_TempPrefabCreationWorks(EditorSharedTest): + from .EditorScripts import DynVegUtils_TempPrefabCreationWorks as test_module diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/large_worlds_utils/editor_dynveg_test_helper.py b/AutomatedTesting/Gem/PythonTests/largeworlds/large_worlds_utils/editor_dynveg_test_helper.py index 957536fffb..3004038b7f 100755 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/large_worlds_utils/editor_dynveg_test_helper.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/large_worlds_utils/editor_dynveg_test_helper.py @@ -19,6 +19,25 @@ import azlmbr.paths sys.path.append(os.path.join(azlmbr.paths.projectroot, 'Gem', 'PythonTests')) import editor_python_test_tools.hydra_editor_utils as hydra +from editor_python_test_tools.editor_entity_utils import EditorEntity, EditorComponent +from editor_python_test_tools.prefab_utils import Prefab + + +def create_temp_mesh_prefab(mesh_asset_path, prefab_filename): + # Create initial entity + root = EditorEntity.create_editor_entity(name=prefab_filename) + assert root.exists(), "Failed to create entity" + # Add mesh component + mesh_component = root.add_component("Mesh") + assert root.has_component("Mesh") and mesh_component.is_enabled(), "Failed to add/activate Mesh component" + # Assign the specified mesh asset + mesh_asset = asset.AssetCatalogRequestBus(bus.Broadcast, "GetAssetIdByPath", mesh_asset_path, math.Uuid(), False) + mesh_component.set_component_property_value("Controller|Configuration|Mesh Asset", mesh_asset) + assert mesh_component.get_component_property_value("Controller|Configuration|Mesh Asset"), \ + "Failed to set Mesh asset" + # Create and return the temporary/in-memory prefab + temp_prefab = Prefab.create_prefab([root], prefab_filename) + return temp_prefab def create_surface_entity(name, center_point, box_size_x, box_size_y, box_size_z): @@ -52,6 +71,40 @@ def create_mesh_surface_entity_with_slopes(name, center_point, uniform_scale): return surface_entity +def create_prefab_spawner(name, center_point, box_size_x, box_size_y, box_size_z, prefab_asset_path): + # Create a vegetation area entity to use as our test vegetation spawner + spawner_entity = EditorEntity.create_editor_entity_at(center_point, name=name) + spawner_entity.add_components(["Vegetation Layer Spawner", "Box Shape", "Vegetation Asset List"]) + if spawner_entity.id.IsValid(): + print(f"'{spawner_entity.get_name()}' created") + spawner_entity.components[1].set_component_property_value("Box Shape|Box Configuration|Dimensions", + math.Vector3(box_size_x, box_size_y, box_size_z)) + + # Set the vegetation area to a Prefab spawner with a specific prefab asset selected + prefab_spawner = vegetation.PrefabInstanceSpawner() + prefab_spawner.SetPrefabAssetPath(prefab_asset_path) + descriptor = spawner_entity.components[2].get_component_property_value("Configuration|Embedded Assets|[0]") + descriptor.spawner = prefab_spawner + spawner_entity.components[2].set_component_property_value("Configuration|Embedded Assets|[0]", descriptor) + return spawner_entity + +def create_empty_spawner(name, center_point, box_size_x, box_size_y, box_size_z): + # Create a vegetation area entity to use as our test vegetation spawner + spawner_entity = EditorEntity.create_editor_entity_at(center_point, name=name) + spawner_entity.add_components(["Vegetation Layer Spawner", "Box Shape", "Vegetation Asset List"]) + if spawner_entity.id.IsValid(): + print(f"'{spawner_entity.get_name()}' created") + spawner_entity.components[1].set_component_property_value("Box Shape|Box Configuration|Dimensions", + math.Vector3(box_size_x, box_size_y, box_size_z)) + + # Set the vegetation area to an empty spawner + empty_spawner = vegetation.EmptyInstanceSpawner() + descriptor = spawner_entity.components[2].get_component_property_value("Configuration|Embedded Assets|[0]") + descriptor.spawner = empty_spawner + spawner_entity.components[2].set_component_property_value("Configuration|Embedded Assets|[0]", descriptor) + return spawner_entity + + def create_vegetation_area(name, center_point, box_size_x, box_size_y, box_size_z, dynamic_slice_asset_path): # Create a vegetation area entity to use as our test vegetation spawner spawner_entity = hydra.Entity(name) @@ -67,7 +120,7 @@ def create_vegetation_area(name, center_point, box_size_x, box_size_y, box_size_ # Set the vegetation area to a Dynamic Slice spawner with a specific slice asset selected dynamic_slice_spawner = vegetation.DynamicSliceInstanceSpawner() dynamic_slice_spawner.SetSliceAssetPath(dynamic_slice_asset_path) - descriptor = hydra.get_component_property_value(spawner_entity.components[2], 'Configuration|Embedded Assets|[0]') + descriptor = vegetation.Descriptor() descriptor.spawner = dynamic_slice_spawner spawner_entity.get_set_test(2, "Configuration|Embedded Assets|[0]", descriptor) return spawner_entity From 0d3ab12d4221596d163a37b60badc6ef41b55687 Mon Sep 17 00:00:00 2001 From: jckand-amzn Date: Fri, 12 Nov 2021 16:34:57 -0600 Subject: [PATCH 2/8] Removing unused imports and debug waits Signed-off-by: jckand-amzn --- .../DynVegUtils_TempPrefabCreationWorks.py | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/DynVegUtils_TempPrefabCreationWorks.py b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/DynVegUtils_TempPrefabCreationWorks.py index d684d7eb02..6f0aace162 100644 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/DynVegUtils_TempPrefabCreationWorks.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/DynVegUtils_TempPrefabCreationWorks.py @@ -33,12 +33,8 @@ def DynVegUtils_TempPrefabCreationWorks(): import os - import azlmbr.editor as editor - import azlmbr.legacy.general as general - import azlmbr.bus as bus import azlmbr.math as math - import editor_python_test_tools.hydra_editor_utils as hydra from largeworlds.large_worlds_utils import editor_dynveg_test_helper as dynveg from editor_python_test_tools.utils import Report, Tracer from editor_python_test_tools.utils import TestHelper as helper @@ -72,9 +68,9 @@ def DynVegUtils_TempPrefabCreationWorks(): Report.result(prefab_created, helper.wait_for_condition(lambda: PrefabInstance.is_valid(prefab[1]), 3.0)) # 4) Assign the temp prefab to the prefab instance spawner, and validate the instance count - #for prefab_filename in mesh_prefabs: - spawner_entity = dynveg.create_prefab_spawner("PrefabSpawner", center_point, 16.0, 16.0, 16.0, - get_prefab_file_path("Sphere")) + for prefab_filename in mesh_prefabs: + spawner_entity = dynveg.create_prefab_spawner("PrefabSpawner", center_point, 16.0, 16.0, 16.0, + get_prefab_file_path(get_prefab_file_path(prefab_filename))) # 5) Report errors/asserts helper.wait_for_condition(lambda: error_tracer.has_errors or error_tracer.has_asserts, 1.0) @@ -83,7 +79,7 @@ def DynVegUtils_TempPrefabCreationWorks(): for assert_info in error_tracer.asserts: Report.info(f"Assert: {assert_info.filename} {assert_info.function} | {assert_info.message}") - general.idle_wait(20.0) + if __name__ == "__main__": from editor_python_test_tools.utils import Report From 0a801ffd783e91b550c48f6f218e69baef6785e7 Mon Sep 17 00:00:00 2001 From: jckand-amzn Date: Mon, 15 Nov 2021 15:33:46 -0600 Subject: [PATCH 3/8] Finalizing temporary prefab helpers and test Signed-off-by: jckand-amzn --- .../DynVegUtils_TempPrefabCreationWorks.py | 49 ++++++++++--------- .../editor_dynveg_test_helper.py | 41 +++++++++------- 2 files changed, 49 insertions(+), 41 deletions(-) diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/DynVegUtils_TempPrefabCreationWorks.py b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/DynVegUtils_TempPrefabCreationWorks.py index 6f0aace162..3aac745149 100644 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/DynVegUtils_TempPrefabCreationWorks.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/DynVegUtils_TempPrefabCreationWorks.py @@ -10,18 +10,16 @@ def DynVegUtils_TempPrefabCreationWorks(): """ Summary: An existing level is opened. Each Prefab setup to be spawned by Dynamic Vegetation tests is created in memory and - validated against existing components/mesh assignments. A spawner is then created with the temporary prefabs to ensure - proper functionality with Dynamic Vegetation components. + validated against existing test slice components/mesh assignments. Expected Behavior: - Temporary prefabs contain the expected components/assets. Instances plant as expected in the assigned area. + Temporary prefabs contain the expected components/assets. Test Steps: 1) Open an existing level - 2) Create each of the necessary temporary prefabs, and validate the component/mesh setups - 3) Create a Vegetation Layer Spawner setup using the temporary prefabs as Prefab Instance Spawner types - 4) Create a surface to plant on and validate instance counts - 5) Verify expected instance counts + 2) Create each of the necessary temporary Mesh prefabs, and validate the component/mesh setups + 3) Create the necessary temporary PhysX Collider, and validate the component setup + 4) Report errors/asserts Note: - This test file must be called from the Open 3D Engine Editor command terminal @@ -33,12 +31,15 @@ def DynVegUtils_TempPrefabCreationWorks(): import os + import azlmbr.asset as asset + import azlmbr.bus as bus + import azlmbr.legacy.general as general import azlmbr.math as math from largeworlds.large_worlds_utils import editor_dynveg_test_helper as dynveg from editor_python_test_tools.utils import Report, Tracer from editor_python_test_tools.utils import TestHelper as helper - from editor_python_test_tools.prefab_utils import Prefab, PrefabInstance, get_prefab_file_path + from editor_python_test_tools.prefab_utils import PrefabInstance with Tracer() as error_tracer: # Create dictionary for prefab filenames and paths to create using helper function @@ -54,25 +55,29 @@ def DynVegUtils_TempPrefabCreationWorks(): helper.init_idle() helper.open_level("Prefab", "Base") - # 2) Create a Dynamic Vegetation surface in preparation of prefab creation - center_point = math.Vector3(0.0, 0.0, 0.0) - dynveg.create_surface_entity("Planting Surface", center_point, 128.0, 128.0, 1.0) - - # 3) Create each of the Mesh asset prefabs and validate that the prefab created successfully + # 2) Create each of the Mesh asset prefabs and validate that the prefab created successfully for prefab_filename, asset_path in mesh_prefabs.items(): - prefab_created = ( - f"Temporary {prefab_filename} prefab created successfully", - f"Failed to create temporary {prefab_filename} prefab" + mesh_prefab_created = ( + f"Temporary mesh prefab: {prefab_filename} created successfully", + f"Failed to create temporary mesh prefab: {prefab_filename}" ) prefab = dynveg.create_temp_mesh_prefab(asset_path, prefab_filename) - Report.result(prefab_created, helper.wait_for_condition(lambda: PrefabInstance.is_valid(prefab[1]), 3.0)) + Report.result(mesh_prefab_created, helper.wait_for_condition(lambda: + PrefabInstance.is_valid(prefab[1]), 3.0)) - # 4) Assign the temp prefab to the prefab instance spawner, and validate the instance count - for prefab_filename in mesh_prefabs: - spawner_entity = dynveg.create_prefab_spawner("PrefabSpawner", center_point, 16.0, 16.0, 16.0, - get_prefab_file_path(get_prefab_file_path(prefab_filename))) + # 3) Create temp PhysX Collider prefab and validate that the prefab created successfully + physx_prefab_filename = "CedarTree_Collision" + physx_collider_prefab_created = ( + f"Temporary mesh prefab: {physx_prefab_filename} created successfully", + f"Failed to create temporary mesh prefab: {physx_prefab_filename}" + ) + test_physx_mesh_asset_id = asset.AssetCatalogRequestBus(bus.Broadcast, "GetAssetIdByPath", os.path.join( + "assets", "objects", "foliage", "cedar.pxmesh"), math.Uuid(), False) + dynveg.create_temp_physx_mesh_collider(test_physx_mesh_asset_id, "CedarTree_Collision") + Report.result(physx_collider_prefab_created, helper.wait_for_condition(lambda: + PrefabInstance.is_valid(prefab[1]), 3.0)) - # 5) Report errors/asserts + # 4) Report errors/asserts helper.wait_for_condition(lambda: error_tracer.has_errors or error_tracer.has_asserts, 1.0) for error_info in error_tracer.errors: Report.info(f"Error: {error_info.filename} {error_info.function} | {error_info.message}") diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/large_worlds_utils/editor_dynveg_test_helper.py b/AutomatedTesting/Gem/PythonTests/largeworlds/large_worlds_utils/editor_dynveg_test_helper.py index 3004038b7f..9840a4c5fd 100755 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/large_worlds_utils/editor_dynveg_test_helper.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/large_worlds_utils/editor_dynveg_test_helper.py @@ -19,7 +19,7 @@ import azlmbr.paths sys.path.append(os.path.join(azlmbr.paths.projectroot, 'Gem', 'PythonTests')) import editor_python_test_tools.hydra_editor_utils as hydra -from editor_python_test_tools.editor_entity_utils import EditorEntity, EditorComponent +from editor_python_test_tools.editor_entity_utils import EditorEntity from editor_python_test_tools.prefab_utils import Prefab @@ -33,13 +33,33 @@ def create_temp_mesh_prefab(mesh_asset_path, prefab_filename): # Assign the specified mesh asset mesh_asset = asset.AssetCatalogRequestBus(bus.Broadcast, "GetAssetIdByPath", mesh_asset_path, math.Uuid(), False) mesh_component.set_component_property_value("Controller|Configuration|Mesh Asset", mesh_asset) - assert mesh_component.get_component_property_value("Controller|Configuration|Mesh Asset"), \ + assert mesh_component.get_component_property_value("Controller|Configuration|Mesh Asset") == mesh_asset, \ "Failed to set Mesh asset" # Create and return the temporary/in-memory prefab temp_prefab = Prefab.create_prefab([root], prefab_filename) return temp_prefab +def create_temp_physx_mesh_collider(physx_mesh_id, prefab_filename): + # Create initial entity + root = EditorEntity.create_editor_entity(name=prefab_filename) + assert root.exists(), "Failed to create entity" + # Add PhysX Collider component + collider_component = root.add_component("PhysX Collider") + assert root.has_component("PhysX Collider") and collider_component.is_enabled(), \ + "Failed to add/activate PhysX Collider component" + # Set the Collider's Shape Configuration field to PhysicsAsset, and assign the specified PhysX Mesh asset + collider_component.set_component_property_value("Shape Configuration|Shape", 7) + assert collider_component.get_component_property_value("Shape Configuration|Shape") == 7, \ + "Failed to set Collider Shape to PhysicsAsset" + collider_component.set_component_property_value("Shape Configuration|Asset|PhysX Mesh", physx_mesh_id) + assert collider_component.get_component_property_value("Shape Configuration|Asset|PhysX Mesh") == physx_mesh_id, \ + "Failed to assign PhysX Mesh asset" + # Create and return the temporary/in-memory prefab + temp_prefab = Prefab.create_prefab([root], prefab_filename) + return temp_prefab + + def create_surface_entity(name, center_point, box_size_x, box_size_y, box_size_z): # Create a "flat surface" entity to use as a plantable vegetation surface surface_entity = hydra.Entity(name) @@ -71,23 +91,6 @@ def create_mesh_surface_entity_with_slopes(name, center_point, uniform_scale): return surface_entity -def create_prefab_spawner(name, center_point, box_size_x, box_size_y, box_size_z, prefab_asset_path): - # Create a vegetation area entity to use as our test vegetation spawner - spawner_entity = EditorEntity.create_editor_entity_at(center_point, name=name) - spawner_entity.add_components(["Vegetation Layer Spawner", "Box Shape", "Vegetation Asset List"]) - if spawner_entity.id.IsValid(): - print(f"'{spawner_entity.get_name()}' created") - spawner_entity.components[1].set_component_property_value("Box Shape|Box Configuration|Dimensions", - math.Vector3(box_size_x, box_size_y, box_size_z)) - - # Set the vegetation area to a Prefab spawner with a specific prefab asset selected - prefab_spawner = vegetation.PrefabInstanceSpawner() - prefab_spawner.SetPrefabAssetPath(prefab_asset_path) - descriptor = spawner_entity.components[2].get_component_property_value("Configuration|Embedded Assets|[0]") - descriptor.spawner = prefab_spawner - spawner_entity.components[2].set_component_property_value("Configuration|Embedded Assets|[0]", descriptor) - return spawner_entity - def create_empty_spawner(name, center_point, box_size_x, box_size_y, box_size_z): # Create a vegetation area entity to use as our test vegetation spawner spawner_entity = EditorEntity.create_editor_entity_at(center_point, name=name) From 327d4192f8943b3fcdd427257177df6f8d516222 Mon Sep 17 00:00:00 2001 From: jckand-amzn Date: Mon, 15 Nov 2021 15:48:44 -0600 Subject: [PATCH 4/8] Enabling new optimized periodic test runner for DynamicVegetation tests Signed-off-by: jckand-amzn --- .../Gem/PythonTests/largeworlds/CMakeLists.txt | 15 ++++++++++++++- .../dyn_veg/TestSuite_Periodic_Optimized.py | 3 ++- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/CMakeLists.txt b/AutomatedTesting/Gem/PythonTests/largeworlds/CMakeLists.txt index c2123d683c..98801b49d6 100644 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/CMakeLists.txt +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/CMakeLists.txt @@ -24,7 +24,6 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS AND PAL_TRAIT_ LargeWorlds ) - ly_add_pytest( NAME AutomatedTesting::DynamicVegetationTests_Periodic TEST_SERIAL @@ -39,6 +38,20 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS AND PAL_TRAIT_ LargeWorlds ) + ly_add_pytest( + NAME AutomatedTesting::DynamicVegetationTests_Periodic_Optimized + TEST_SERIAL + TEST_SUITE periodic + PATH ${CMAKE_CURRENT_LIST_DIR}/dyn_veg/TestSuite_Periodic_Optimized.py + RUNTIME_DEPENDENCIES + AZ::AssetProcessor + Legacy::Editor + AutomatedTesting.Assets + AutomatedTesting.GameLauncher + COMPONENT + LargeWorlds + ) + ly_add_pytest( NAME AutomatedTesting::DynamicVegetationTests_Main_Optimized TEST_SERIAL diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/TestSuite_Periodic_Optimized.py b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/TestSuite_Periodic_Optimized.py index 764d2dec75..8d298e970b 100644 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/TestSuite_Periodic_Optimized.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/TestSuite_Periodic_Optimized.py @@ -16,7 +16,8 @@ from ly_test_tools.o3de.editor_test import EditorSingleTest, EditorSharedTest, E @pytest.mark.parametrize("launcher_platform", ['windows_editor']) @pytest.mark.parametrize("project", ["AutomatedTesting"]) class TestAutomation(EditorTestSuite): - global_extra_cmdline_args = [] + + global_extra_cmdline_args = ["-BatchMode", "-autotest_mode", "--regset=/Amazon/Preferences/EnablePrefabSystem=true"] class test_DynVegUtils_TempPrefabCreationWorks(EditorSharedTest): from .EditorScripts import DynVegUtils_TempPrefabCreationWorks as test_module From 60f7ea54aa3eaadc4a709ecf331b30e7fda05e6b Mon Sep 17 00:00:00 2001 From: jckand-amzn Date: Mon, 15 Nov 2021 17:45:52 -0600 Subject: [PATCH 5/8] Reverting unintentional change to create_vegetation_area() helper Signed-off-by: jckand-amzn --- .../EditorScripts/DynVegUtils_TempPrefabCreationWorks.py | 3 +-- .../large_worlds_utils/editor_dynveg_test_helper.py | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/DynVegUtils_TempPrefabCreationWorks.py b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/DynVegUtils_TempPrefabCreationWorks.py index 3aac745149..16a6c2eda6 100644 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/DynVegUtils_TempPrefabCreationWorks.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/DynVegUtils_TempPrefabCreationWorks.py @@ -33,7 +33,6 @@ def DynVegUtils_TempPrefabCreationWorks(): import azlmbr.asset as asset import azlmbr.bus as bus - import azlmbr.legacy.general as general import azlmbr.math as math from largeworlds.large_worlds_utils import editor_dynveg_test_helper as dynveg @@ -73,7 +72,7 @@ def DynVegUtils_TempPrefabCreationWorks(): ) test_physx_mesh_asset_id = asset.AssetCatalogRequestBus(bus.Broadcast, "GetAssetIdByPath", os.path.join( "assets", "objects", "foliage", "cedar.pxmesh"), math.Uuid(), False) - dynveg.create_temp_physx_mesh_collider(test_physx_mesh_asset_id, "CedarTree_Collision") + dynveg.create_temp_physx_mesh_collider(test_physx_mesh_asset_id, physx_prefab_filename) Report.result(physx_collider_prefab_created, helper.wait_for_condition(lambda: PrefabInstance.is_valid(prefab[1]), 3.0)) diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/large_worlds_utils/editor_dynveg_test_helper.py b/AutomatedTesting/Gem/PythonTests/largeworlds/large_worlds_utils/editor_dynveg_test_helper.py index 9840a4c5fd..d840628abc 100755 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/large_worlds_utils/editor_dynveg_test_helper.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/large_worlds_utils/editor_dynveg_test_helper.py @@ -123,7 +123,7 @@ def create_vegetation_area(name, center_point, box_size_x, box_size_y, box_size_ # Set the vegetation area to a Dynamic Slice spawner with a specific slice asset selected dynamic_slice_spawner = vegetation.DynamicSliceInstanceSpawner() dynamic_slice_spawner.SetSliceAssetPath(dynamic_slice_asset_path) - descriptor = vegetation.Descriptor() + descriptor = hydra.get_component_property_value(spawner_entity.components[2], 'Configuration|Embedded Assets|[0]') descriptor.spawner = dynamic_slice_spawner spawner_entity.get_set_test(2, "Configuration|Embedded Assets|[0]", descriptor) return spawner_entity From 05caf1b29da517f188704337d5ec9fa452c242b0 Mon Sep 17 00:00:00 2001 From: jckand-amzn Date: Mon, 15 Nov 2021 17:50:42 -0600 Subject: [PATCH 6/8] Removed redundant append to components list from add_component() Signed-off-by: jckand-amzn --- .../editor_python_test_tools/editor_entity_utils.py | 1 - 1 file changed, 1 deletion(-) diff --git a/AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/editor_python_test_tools/editor_entity_utils.py b/AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/editor_python_test_tools/editor_entity_utils.py index aee8846afe..59e454479c 100644 --- a/AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/editor_python_test_tools/editor_entity_utils.py +++ b/AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/editor_python_test_tools/editor_entity_utils.py @@ -259,7 +259,6 @@ class EditorEntity: :return: Component object of newly added component. """ component = self.add_components([component_name])[0] - self.components.append(component) return component def add_components(self, component_names: list) -> List[EditorComponent]: From e5ebdaebcf2452d1c10806a7c4cfb31f543ecd60 Mon Sep 17 00:00:00 2001 From: jckand-amzn Date: Mon, 15 Nov 2021 18:27:52 -0600 Subject: [PATCH 7/8] Removing unused helper for now and utilizing helper function for opening base level Signed-off-by: jckand-amzn --- .../DynVegUtils_TempPrefabCreationWorks.py | 4 ++-- .../editor_dynveg_test_helper.py | 17 ----------------- 2 files changed, 2 insertions(+), 19 deletions(-) diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/DynVegUtils_TempPrefabCreationWorks.py b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/DynVegUtils_TempPrefabCreationWorks.py index 16a6c2eda6..8d7f02425d 100644 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/DynVegUtils_TempPrefabCreationWorks.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/DynVegUtils_TempPrefabCreationWorks.py @@ -35,6 +35,7 @@ def DynVegUtils_TempPrefabCreationWorks(): import azlmbr.bus as bus import azlmbr.math as math + from Prefab.tests import PrefabTestUtils as prefab_test_utils from largeworlds.large_worlds_utils import editor_dynveg_test_helper as dynveg from editor_python_test_tools.utils import Report, Tracer from editor_python_test_tools.utils import TestHelper as helper @@ -51,8 +52,7 @@ def DynVegUtils_TempPrefabCreationWorks(): } # 1) Open an existing simple level - helper.init_idle() - helper.open_level("Prefab", "Base") + prefab_test_utils.open_base_tests_level() # 2) Create each of the Mesh asset prefabs and validate that the prefab created successfully for prefab_filename, asset_path in mesh_prefabs.items(): diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/large_worlds_utils/editor_dynveg_test_helper.py b/AutomatedTesting/Gem/PythonTests/largeworlds/large_worlds_utils/editor_dynveg_test_helper.py index d840628abc..d7d5842518 100755 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/large_worlds_utils/editor_dynveg_test_helper.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/large_worlds_utils/editor_dynveg_test_helper.py @@ -91,23 +91,6 @@ def create_mesh_surface_entity_with_slopes(name, center_point, uniform_scale): return surface_entity -def create_empty_spawner(name, center_point, box_size_x, box_size_y, box_size_z): - # Create a vegetation area entity to use as our test vegetation spawner - spawner_entity = EditorEntity.create_editor_entity_at(center_point, name=name) - spawner_entity.add_components(["Vegetation Layer Spawner", "Box Shape", "Vegetation Asset List"]) - if spawner_entity.id.IsValid(): - print(f"'{spawner_entity.get_name()}' created") - spawner_entity.components[1].set_component_property_value("Box Shape|Box Configuration|Dimensions", - math.Vector3(box_size_x, box_size_y, box_size_z)) - - # Set the vegetation area to an empty spawner - empty_spawner = vegetation.EmptyInstanceSpawner() - descriptor = spawner_entity.components[2].get_component_property_value("Configuration|Embedded Assets|[0]") - descriptor.spawner = empty_spawner - spawner_entity.components[2].set_component_property_value("Configuration|Embedded Assets|[0]", descriptor) - return spawner_entity - - def create_vegetation_area(name, center_point, box_size_x, box_size_y, box_size_z, dynamic_slice_asset_path): # Create a vegetation area entity to use as our test vegetation spawner spawner_entity = hydra.Entity(name) From d2d83079eb36d3620fcf67e383bdfb95f03e1339 Mon Sep 17 00:00:00 2001 From: jckand-amzn Date: Mon, 15 Nov 2021 18:30:06 -0600 Subject: [PATCH 8/8] Cleaning up test docstring Signed-off-by: jckand-amzn --- .../EditorScripts/DynVegUtils_TempPrefabCreationWorks.py | 5 ----- 1 file changed, 5 deletions(-) diff --git a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/DynVegUtils_TempPrefabCreationWorks.py b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/DynVegUtils_TempPrefabCreationWorks.py index 8d7f02425d..d016473d5e 100644 --- a/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/DynVegUtils_TempPrefabCreationWorks.py +++ b/AutomatedTesting/Gem/PythonTests/largeworlds/dyn_veg/EditorScripts/DynVegUtils_TempPrefabCreationWorks.py @@ -21,11 +21,6 @@ def DynVegUtils_TempPrefabCreationWorks(): 3) Create the necessary temporary PhysX Collider, and validate the component setup 4) Report errors/asserts - 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 """