From be7c8c8dd33a73c8cedf6fe20e72a1dc0cc9ca26 Mon Sep 17 00:00:00 2001 From: Gene Walters Date: Thu, 4 Nov 2021 09:55:59 -0700 Subject: [PATCH 01/19] Removing flaky multiplayer tests. Will bring back once we can reproduce and correct the flakes Signed-off-by: Gene Walters --- AutomatedTesting/Gem/PythonTests/CMakeLists.txt | 3 --- 1 file changed, 3 deletions(-) diff --git a/AutomatedTesting/Gem/PythonTests/CMakeLists.txt b/AutomatedTesting/Gem/PythonTests/CMakeLists.txt index bec49185bd..fd3222ba83 100644 --- a/AutomatedTesting/Gem/PythonTests/CMakeLists.txt +++ b/AutomatedTesting/Gem/PythonTests/CMakeLists.txt @@ -59,8 +59,5 @@ add_subdirectory(smoke) ## AWS ## add_subdirectory(AWS) -## Multiplayer ## -add_subdirectory(Multiplayer) - ## Integration tests for editor testing framework ## add_subdirectory(editor_test_testing) From bc2b3b12a70d3ef3977e739ca407b6b3f5a8e8c3 Mon Sep 17 00:00:00 2001 From: jromnoa <80134229+jromnoa@users.noreply.github.com> Date: Thu, 4 Nov 2021 11:51:58 -0700 Subject: [PATCH 02/19] remove old main suite, rename optimized main suite to be the new main suite Signed-off-by: jromnoa <80134229+jromnoa@users.noreply.github.com> --- .../Gem/PythonTests/Atom/TestSuite_Main.py | 302 ++++-------------- .../Atom/TestSuite_Main_Optimized.py | 91 ------ 2 files changed, 69 insertions(+), 324 deletions(-) delete mode 100644 AutomatedTesting/Gem/PythonTests/Atom/TestSuite_Main_Optimized.py diff --git a/AutomatedTesting/Gem/PythonTests/Atom/TestSuite_Main.py b/AutomatedTesting/Gem/PythonTests/Atom/TestSuite_Main.py index 6cc48984ab..950bd44199 100644 --- a/AutomatedTesting/Gem/PythonTests/Atom/TestSuite_Main.py +++ b/AutomatedTesting/Gem/PythonTests/Atom/TestSuite_Main.py @@ -4,252 +4,88 @@ For complete copyright and license terms please see the LICENSE at the root of t SPDX-License-Identifier: Apache-2.0 OR MIT """ -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 -from Atom.atom_utils.atom_constants import LIGHT_TYPES - -logger = logging.getLogger(__name__) -TEST_DIRECTORY = os.path.join(os.path.dirname(__file__), "tests") +from ly_test_tools.o3de.editor_test import EditorSharedTest, EditorTestSuite +@pytest.mark.xfail(reason="Optimized tests are experimental, we will enable xfail and monitor them temporarily.") @pytest.mark.parametrize("project", ["AutomatedTesting"]) @pytest.mark.parametrize("launcher_platform", ['windows_editor']) -@pytest.mark.parametrize("level", ["auto_test"]) -class TestAtomEditorComponentsMain(object): - """Holds tests for Atom components.""" +class TestAutomation(EditorTestSuite): - @pytest.mark.test_case_id("C32078118") # Decal - @pytest.mark.test_case_id("C32078119") # DepthOfField - @pytest.mark.test_case_id("C32078120") # Directional Light - @pytest.mark.test_case_id("C32078121") # Exposure Control - @pytest.mark.test_case_id("C32078115") # Global Skylight (IBL) - @pytest.mark.test_case_id("C32078125") # Physical Sky - @pytest.mark.test_case_id("C32078127") # PostFX Layer - @pytest.mark.test_case_id("C32078131") # PostFX Radius Weight Modifier - @pytest.mark.test_case_id("C32078117") # Light - @pytest.mark.test_case_id("C36525660") # Display Mapper - def test_AtomEditorComponents_AddedToEntity(self, request, editor, level, workspace, project, launcher_platform): - """ - Please review the hydra script run by this test for more specific test info. - Tests the Atom components & verifies all "expected_lines" appear in Editor.log - """ - cfg_args = [level] + @pytest.mark.test_case_id("C32078118") + class AtomEditorComponents_DecalAdded(EditorSharedTest): + from Atom.tests import hydra_AtomEditorComponents_DecalAdded as test_module - expected_lines = [ - # 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 Controller|Configuration|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_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", - # 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", - # PostFX Radius Weight Modifier Component - "PostFX Radius Weight Modifier Entity successfully created", - "PostFX Radius Weight Modifier_test: Component added to the entity: True", - "PostFX Radius Weight Modifier_test: Component removed after UNDO: True", - "PostFX Radius Weight Modifier_test: Component added after REDO: True", - "PostFX Radius Weight Modifier_test: Entered game mode: True", - "PostFX Radius Weight Modifier_test: Exit game mode: True", - "PostFX Radius Weight Modifier_test: Entity is hidden: True", - "PostFX Radius Weight Modifier_test: Entity is shown: True", - "PostFX Radius Weight Modifier_test: Entity deleted: True", - "PostFX Radius Weight Modifier_test: UNDO entity deletion works: True", - "PostFX 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", - # Display Mapper Component - "Display Mapper Entity successfully created", - "Display Mapper_test: Component added to the entity: True", - "Display Mapper_test: Component removed after UNDO: True", - "Display Mapper_test: Component added after REDO: True", - "Display Mapper_test: Entered game mode: True", - "Display Mapper_test: Exit game mode: True", - "Display Mapper_test: Entity is hidden: True", - "Display Mapper_test: Entity is shown: True", - "Display Mapper_test: Entity deleted: True", - "Display Mapper_test: UNDO entity deletion works: True", - "Display Mapper_test: REDO entity deletion works: True", - ] + @pytest.mark.test_case_id("C32078119") + class AtomEditorComponents_DepthOfFieldAdded(EditorSharedTest): + from Atom.tests import hydra_AtomEditorComponents_DepthOfFieldAdded as test_module - unexpected_lines = [ - "Trace::Assert", - "Trace::Error", - "Traceback (most recent call last):", - ] + @pytest.mark.test_case_id("C32078120") + class AtomEditorComponents_DirectionalLightAdded(EditorSharedTest): + from Atom.tests import hydra_AtomEditorComponents_DirectionalLightAdded as test_module - hydra.launch_and_validate_results( - request, - TEST_DIRECTORY, - editor, - "hydra_AtomEditorComponents_AddedToEntity.py", - timeout=120, - expected_lines=expected_lines, - unexpected_lines=unexpected_lines, - halt_on_unexpected=True, - null_renderer=True, - cfg_args=cfg_args, - ) + @pytest.mark.test_case_id("C36525660") + class AtomEditorComponents_DisplayMapperAdded(EditorSharedTest): + from Atom.tests import hydra_AtomEditorComponents_DisplayMapperAdded as test_module - @pytest.mark.test_case_id("C34525095") - def test_AtomEditorComponents_LightComponent( - self, request, editor, workspace, project, launcher_platform, level): - """ - Please review the hydra script run by this test for more specific test info. - Tests that the Light component has the expected property options available to it. - """ - cfg_args = [level] + @pytest.mark.test_case_id("C32078121") + class AtomEditorComponents_ExposureControlAdded(EditorSharedTest): + from Atom.tests import hydra_AtomEditorComponents_ExposureControlAdded as test_module - expected_lines = [ - "light_entity Entity successfully created", - "Entity has a Light component", - "light_entity_test: Component added to the entity: True", - f"light_entity_test: Property value is {LIGHT_TYPES['sphere']} which matches {LIGHT_TYPES['sphere']}", - "Controller|Configuration|Shadows|Enable shadow set to True", - "light_entity Controller|Configuration|Shadows|Shadowmap size: SUCCESS", - "Controller|Configuration|Shadows|Shadow filter method set to 1", # PCF - "Controller|Configuration|Shadows|Filtering sample count set to 4", - "Controller|Configuration|Shadows|Filtering sample count set to 64", - "Controller|Configuration|Shadows|Shadow filter method set to 2", # ESM - "Controller|Configuration|Shadows|ESM exponent set to 50.0", - "Controller|Configuration|Shadows|ESM exponent set to 5000.0", - "Controller|Configuration|Shadows|Shadow filter method set to 3", # ESM+PCF - f"light_entity_test: Property value is {LIGHT_TYPES['spot_disk']} which matches {LIGHT_TYPES['spot_disk']}", - f"light_entity_test: Property value is {LIGHT_TYPES['capsule']} which matches {LIGHT_TYPES['capsule']}", - f"light_entity_test: Property value is {LIGHT_TYPES['quad']} which matches {LIGHT_TYPES['quad']}", - "light_entity Controller|Configuration|Fast approximation: SUCCESS", - "light_entity Controller|Configuration|Both directions: SUCCESS", - f"light_entity_test: Property value is {LIGHT_TYPES['polygon']} which matches {LIGHT_TYPES['polygon']}", - f"light_entity_test: Property value is {LIGHT_TYPES['simple_point']} " - f"which matches {LIGHT_TYPES['simple_point']}", - "Controller|Configuration|Attenuation radius|Mode set to 0", - "Controller|Configuration|Attenuation radius|Radius set to 100.0", - f"light_entity_test: Property value is {LIGHT_TYPES['simple_spot']} " - f"which matches {LIGHT_TYPES['simple_spot']}", - "Controller|Configuration|Shutters|Outer angle set to 45.0", - "Controller|Configuration|Shutters|Outer angle set to 90.0", - "light_entity_test: Component added to the entity: True", - "Light component test (non-GPU) completed.", - ] + @pytest.mark.test_case_id("C32078115") + class AtomEditorComponents_GlobalSkylightIBLAdded(EditorSharedTest): + from Atom.tests import hydra_AtomEditorComponents_GlobalSkylightIBLAdded as test_module + + @pytest.mark.test_case_id("C32078122") + class AtomEditorComponents_GridAdded(EditorSharedTest): + from Atom.tests import hydra_AtomEditorComponents_GridAdded as test_module - unexpected_lines = [ - "Trace::Assert", - "Trace::Error", - "Traceback (most recent call last):", - ] + @pytest.mark.test_case_id("C36525671") + class AtomEditorComponents_HDRColorGradingAdded(EditorSharedTest): + from Atom.tests import hydra_AtomEditorComponents_HDRColorGradingAdded as test_module - hydra.launch_and_validate_results( - request, - TEST_DIRECTORY, - editor, - "hydra_AtomEditorComponents_LightComponent.py", - timeout=120, - expected_lines=expected_lines, - unexpected_lines=unexpected_lines, - halt_on_unexpected=True, - null_renderer=True, - cfg_args=cfg_args, - ) + @pytest.mark.test_case_id("C32078117") + class AtomEditorComponents_LightAdded(EditorSharedTest): + from Atom.tests import hydra_AtomEditorComponents_LightAdded as test_module + @pytest.mark.test_case_id("C32078123") + class AtomEditorComponents_MaterialAdded(EditorSharedTest): + from Atom.tests import hydra_AtomEditorComponents_MaterialAdded as test_module + @pytest.mark.test_case_id("C32078124") + class AtomEditorComponents_MeshAdded(EditorSharedTest): + from Atom.tests import hydra_AtomEditorComponents_MeshAdded as test_module + + @pytest.mark.test_case_id("C36525663") + class AtomEditorComponents_OcclusionCullingPlaneAdded(EditorSharedTest): + from Atom.tests import hydra_AtomEditorComponents_OcclusionCullingPlaneAdded as test_module + + @pytest.mark.test_case_id("C32078125") + class AtomEditorComponents_PhysicalSkyAdded(EditorSharedTest): + from Atom.tests import hydra_AtomEditorComponents_PhysicalSkyAdded as test_module + + @pytest.mark.test_case_id("C36525664") + class AtomEditorComponents_PostFXGradientWeightModifierAdded(EditorSharedTest): + from Atom.tests import hydra_AtomEditorComponents_PostFXGradientWeightModifierAdded as test_module + + @pytest.mark.test_case_id("C32078127") + class AtomEditorComponents_PostFXLayerAdded(EditorSharedTest): + from Atom.tests import hydra_AtomEditorComponents_PostFXLayerAdded as test_module + + @pytest.mark.test_case_id("C32078131") + class AtomEditorComponents_PostFXRadiusWeightModifierAdded(EditorSharedTest): + from Atom.tests import ( + hydra_AtomEditorComponents_PostFXRadiusWeightModifierAdded as test_module) + + @pytest.mark.test_case_id("C36525665") + class AtomEditorComponents_PostFXShapeWeightModifierAdded(EditorSharedTest): + from Atom.tests import hydra_AtomEditorComponents_PostFxShapeWeightModifierAdded as test_module + + @pytest.mark.test_case_id("C32078128") + class AtomEditorComponents_ReflectionProbeAdded(EditorSharedTest): + from Atom.tests import hydra_AtomEditorComponents_ReflectionProbeAdded as test_module + + class ShaderAssetBuilder_RecompilesShaderAsChainOfDependenciesChanges(EditorSharedTest): + from Atom.tests import hydra_ShaderAssetBuilder_RecompilesShaderAsChainOfDependenciesChanges as test_module diff --git a/AutomatedTesting/Gem/PythonTests/Atom/TestSuite_Main_Optimized.py b/AutomatedTesting/Gem/PythonTests/Atom/TestSuite_Main_Optimized.py deleted file mode 100644 index 950bd44199..0000000000 --- a/AutomatedTesting/Gem/PythonTests/Atom/TestSuite_Main_Optimized.py +++ /dev/null @@ -1,91 +0,0 @@ -""" -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 pytest - -from ly_test_tools.o3de.editor_test import EditorSharedTest, EditorTestSuite - - -@pytest.mark.xfail(reason="Optimized tests are experimental, we will enable xfail and monitor them temporarily.") -@pytest.mark.parametrize("project", ["AutomatedTesting"]) -@pytest.mark.parametrize("launcher_platform", ['windows_editor']) -class TestAutomation(EditorTestSuite): - - @pytest.mark.test_case_id("C32078118") - class AtomEditorComponents_DecalAdded(EditorSharedTest): - from Atom.tests import hydra_AtomEditorComponents_DecalAdded as test_module - - @pytest.mark.test_case_id("C32078119") - class AtomEditorComponents_DepthOfFieldAdded(EditorSharedTest): - from Atom.tests import hydra_AtomEditorComponents_DepthOfFieldAdded as test_module - - @pytest.mark.test_case_id("C32078120") - class AtomEditorComponents_DirectionalLightAdded(EditorSharedTest): - from Atom.tests import hydra_AtomEditorComponents_DirectionalLightAdded as test_module - - @pytest.mark.test_case_id("C36525660") - class AtomEditorComponents_DisplayMapperAdded(EditorSharedTest): - from Atom.tests import hydra_AtomEditorComponents_DisplayMapperAdded as test_module - - @pytest.mark.test_case_id("C32078121") - class AtomEditorComponents_ExposureControlAdded(EditorSharedTest): - from Atom.tests import hydra_AtomEditorComponents_ExposureControlAdded as test_module - - @pytest.mark.test_case_id("C32078115") - class AtomEditorComponents_GlobalSkylightIBLAdded(EditorSharedTest): - from Atom.tests import hydra_AtomEditorComponents_GlobalSkylightIBLAdded as test_module - - @pytest.mark.test_case_id("C32078122") - class AtomEditorComponents_GridAdded(EditorSharedTest): - from Atom.tests import hydra_AtomEditorComponents_GridAdded as test_module - - @pytest.mark.test_case_id("C36525671") - class AtomEditorComponents_HDRColorGradingAdded(EditorSharedTest): - from Atom.tests import hydra_AtomEditorComponents_HDRColorGradingAdded as test_module - - @pytest.mark.test_case_id("C32078117") - class AtomEditorComponents_LightAdded(EditorSharedTest): - from Atom.tests import hydra_AtomEditorComponents_LightAdded as test_module - - @pytest.mark.test_case_id("C32078123") - class AtomEditorComponents_MaterialAdded(EditorSharedTest): - from Atom.tests import hydra_AtomEditorComponents_MaterialAdded as test_module - - @pytest.mark.test_case_id("C32078124") - class AtomEditorComponents_MeshAdded(EditorSharedTest): - from Atom.tests import hydra_AtomEditorComponents_MeshAdded as test_module - - @pytest.mark.test_case_id("C36525663") - class AtomEditorComponents_OcclusionCullingPlaneAdded(EditorSharedTest): - from Atom.tests import hydra_AtomEditorComponents_OcclusionCullingPlaneAdded as test_module - - @pytest.mark.test_case_id("C32078125") - class AtomEditorComponents_PhysicalSkyAdded(EditorSharedTest): - from Atom.tests import hydra_AtomEditorComponents_PhysicalSkyAdded as test_module - - @pytest.mark.test_case_id("C36525664") - class AtomEditorComponents_PostFXGradientWeightModifierAdded(EditorSharedTest): - from Atom.tests import hydra_AtomEditorComponents_PostFXGradientWeightModifierAdded as test_module - - @pytest.mark.test_case_id("C32078127") - class AtomEditorComponents_PostFXLayerAdded(EditorSharedTest): - from Atom.tests import hydra_AtomEditorComponents_PostFXLayerAdded as test_module - - @pytest.mark.test_case_id("C32078131") - class AtomEditorComponents_PostFXRadiusWeightModifierAdded(EditorSharedTest): - from Atom.tests import ( - hydra_AtomEditorComponents_PostFXRadiusWeightModifierAdded as test_module) - - @pytest.mark.test_case_id("C36525665") - class AtomEditorComponents_PostFXShapeWeightModifierAdded(EditorSharedTest): - from Atom.tests import hydra_AtomEditorComponents_PostFxShapeWeightModifierAdded as test_module - - @pytest.mark.test_case_id("C32078128") - class AtomEditorComponents_ReflectionProbeAdded(EditorSharedTest): - from Atom.tests import hydra_AtomEditorComponents_ReflectionProbeAdded as test_module - - class ShaderAssetBuilder_RecompilesShaderAsChainOfDependenciesChanges(EditorSharedTest): - from Atom.tests import hydra_ShaderAssetBuilder_RecompilesShaderAsChainOfDependenciesChanges as test_module From 16526f58b7f0a4c02a90d3c8ca2ddec84bdc47f7 Mon Sep 17 00:00:00 2001 From: jromnoa <80134229+jromnoa@users.noreply.github.com> Date: Thu, 4 Nov 2021 11:52:28 -0700 Subject: [PATCH 03/19] remove xfail marker Signed-off-by: jromnoa <80134229+jromnoa@users.noreply.github.com> --- AutomatedTesting/Gem/PythonTests/Atom/TestSuite_Main.py | 1 - 1 file changed, 1 deletion(-) diff --git a/AutomatedTesting/Gem/PythonTests/Atom/TestSuite_Main.py b/AutomatedTesting/Gem/PythonTests/Atom/TestSuite_Main.py index 950bd44199..62a402d9c4 100644 --- a/AutomatedTesting/Gem/PythonTests/Atom/TestSuite_Main.py +++ b/AutomatedTesting/Gem/PythonTests/Atom/TestSuite_Main.py @@ -9,7 +9,6 @@ import pytest from ly_test_tools.o3de.editor_test import EditorSharedTest, EditorTestSuite -@pytest.mark.xfail(reason="Optimized tests are experimental, we will enable xfail and monitor them temporarily.") @pytest.mark.parametrize("project", ["AutomatedTesting"]) @pytest.mark.parametrize("launcher_platform", ['windows_editor']) class TestAutomation(EditorTestSuite): From b82ea09a67bec33a19e657d60b834da8e4dcb25c Mon Sep 17 00:00:00 2001 From: jromnoa <80134229+jromnoa@users.noreply.github.com> Date: Thu, 4 Nov 2021 11:54:21 -0700 Subject: [PATCH 04/19] remove redundant sandbox test, remove unsued/old hydra script for old log lines test approach Signed-off-by: jromnoa <80134229+jromnoa@users.noreply.github.com> --- ...ydra_AtomEditorComponents_AddedToEntity.py | 238 ------------------ 1 file changed, 238 deletions(-) delete mode 100644 AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_AddedToEntity.py diff --git a/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_AddedToEntity.py b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_AddedToEntity.py deleted file mode 100644 index bbc8463152..0000000000 --- a/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_AddedToEntity.py +++ /dev/null @@ -1,238 +0,0 @@ -""" -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 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 -import azlmbr.render as render - -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.utils import TestHelper - - -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(), 2.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(), 2.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), 2.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, 2.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), 2.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]), 2.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) - - # Verify cubemap generation - def verify_cubemap_generation(component_name, entity_obj): - # Initially Check if the component has Reflection Probe component - if not hydra.has_components(entity_obj.id, ["Reflection Probe"]): - raise ValueError(f"Given entity {entity_obj.name} has no Reflection Probe component") - render.EditorReflectionProbeBus(azlmbr.bus.Event, "BakeReflectionProbe", entity_obj.id) - - def get_value(): - hydra.get_component_property_value(entity_obj.components[0], "Cubemap|Baked Cubemap Path") - - TestHelper.wait_for_condition(lambda: get_value() != "", 20.0) - general.log(f"{component_name}_test: Cubemap is generated: {get_value() != ''}") - - # Wait for Editor idle loop before executing Python hydra scripts. - TestHelper.init_idle() - - # 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) - - # 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)) - - # Decal Component - material_asset_path = os.path.join("AutomatedTesting", "Materials", "basic_grey.material") - material_asset = asset.AssetCatalogRequestBus( - bus.Broadcast, "GetAssetIdByPath", material_asset_path, math.Uuid(), False) - ComponentTests( - "Decal", lambda entity_obj: verify_set_property( - entity_obj, "Controller|Configuration|Material", material_asset)) - - # 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") - - # PostFX Layer Component - ComponentTests("PostFX Layer") - - # PostFX Radius Weight Modifier Component - ComponentTests("PostFX Radius Weight Modifier") - - # Light Component - ComponentTests("Light") - - # Display Mapper Component - ComponentTests("Display Mapper") - - # Reflection Probe Component - reflection_probe = "Reflection Probe" - ComponentTests( - reflection_probe, - lambda entity_obj: verify_required_component_addition(entity_obj, ["Box Shape"], reflection_probe), - lambda entity_obj: verify_cubemap_generation(reflection_probe, entity_obj),) - -if __name__ == "__main__": - run() From ae72463581d7bcf59ee3f8f9816ab81c3a89b3e6 Mon Sep 17 00:00:00 2001 From: jromnoa <80134229+jromnoa@users.noreply.github.com> Date: Thu, 4 Nov 2021 11:54:49 -0700 Subject: [PATCH 05/19] sandbox portion Signed-off-by: jromnoa <80134229+jromnoa@users.noreply.github.com> --- .../Gem/PythonTests/Atom/TestSuite_Sandbox.py | 50 +------------------ 1 file changed, 2 insertions(+), 48 deletions(-) diff --git a/AutomatedTesting/Gem/PythonTests/Atom/TestSuite_Sandbox.py b/AutomatedTesting/Gem/PythonTests/Atom/TestSuite_Sandbox.py index ad45e51080..55b1540b7e 100644 --- a/AutomatedTesting/Gem/PythonTests/Atom/TestSuite_Sandbox.py +++ b/AutomatedTesting/Gem/PythonTests/Atom/TestSuite_Sandbox.py @@ -9,63 +9,19 @@ 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__) TEST_DIRECTORY = os.path.join(os.path.dirname(__file__), "tests") + class TestAtomEditorComponentsSandbox(object): # It requires at least one test def test_Dummy(self, request, editor, level, workspace, project, launcher_platform): pass - @pytest.mark.parametrize("project", ["AutomatedTesting"]) - @pytest.mark.parametrize("launcher_platform", ['windows_editor']) - @pytest.mark.parametrize("level", ["auto_test"]) - class TestAtomEditorComponentsMain(object): - """Holds tests for Atom components.""" - - @pytest.mark.test_case_id("C32078128") - def test_AtomEditorComponents_ReflectionProbeAddedToEntity( - self, request, editor, level, workspace, project, launcher_platform): - """ - Please review the hydra script run by this test for more specific test info. - Tests the following Atom components and verifies all "expected_lines" appear in Editor.log: - 1. Reflection Probe - """ - cfg_args = [level] - - expected_lines = [ - # Reflection Probe Component - "Reflection Probe Entity successfully created", - "Reflection Probe_test: Component added to the entity: True", - "Reflection Probe_test: Component removed after UNDO: True", - "Reflection Probe_test: Component added after REDO: True", - "Reflection Probe_test: Entered game mode: True", - "Reflection Probe_test: Exit game mode: True", - "Reflection Probe_test: Entity disabled initially: True", - "Reflection Probe_test: Entity enabled after adding required components: True", - "Reflection Probe_test: Cubemap is generated: True", - "Reflection Probe_test: Entity is hidden: True", - "Reflection Probe_test: Entity is shown: True", - "Reflection Probe_test: Entity deleted: True", - "Reflection Probe_test: UNDO entity deletion works: True", - "Reflection Probe_test: REDO entity deletion works: True", - ] - - hydra.launch_and_validate_results( - request, - TEST_DIRECTORY, - editor, - "hydra_AtomEditorComponents_AddedToEntity.py", - timeout=120, - expected_lines=expected_lines, - unexpected_lines=[], - halt_on_unexpected=True, - null_renderer=True, - cfg_args=cfg_args, - ) @pytest.mark.parametrize("project", ["AutomatedTesting"]) @pytest.mark.parametrize("launcher_platform", ['windows_generic']) @@ -119,8 +75,6 @@ class TestMaterialEditorBasicTests(object): "Save All worked as expected: True", ] unexpected_lines = [ - # "Trace::Assert", - # "Trace::Error", "Traceback (most recent call last):" ] From 6f294457da88290ef3a542dfb5c1b8ac943bc82f Mon Sep 17 00:00:00 2001 From: Vishal Das Date: Fri, 5 Nov 2021 00:41:31 +0530 Subject: [PATCH 06/19] fix issue #5172 (#5198) Signed-off-by: Vishal Das --- .../ComponentEntityEditorPlugin/UI/Outliner/EntityOutliner.qss | 1 - .../AzToolsFramework/UI/Outliner/EntityOutliner.qss | 1 - 2 files changed, 2 deletions(-) diff --git a/Code/Editor/Plugins/ComponentEntityEditorPlugin/UI/Outliner/EntityOutliner.qss b/Code/Editor/Plugins/ComponentEntityEditorPlugin/UI/Outliner/EntityOutliner.qss index de35f91678..a7d3949527 100644 --- a/Code/Editor/Plugins/ComponentEntityEditorPlugin/UI/Outliner/EntityOutliner.qss +++ b/Code/Editor/Plugins/ComponentEntityEditorPlugin/UI/Outliner/EntityOutliner.qss @@ -11,7 +11,6 @@ OutlinerWidget #m_display_options { qproperty-icon: url(:/Menu/menu.svg); qproperty-iconSize: 16px 16px; - qproperty-flat: true; } OutlinerWidget QWidget[PulseHighlight="true"] diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/UI/Outliner/EntityOutliner.qss b/Code/Framework/AzToolsFramework/AzToolsFramework/UI/Outliner/EntityOutliner.qss index b3c5882334..93460f8816 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/UI/Outliner/EntityOutliner.qss +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/UI/Outliner/EntityOutliner.qss @@ -10,7 +10,6 @@ AzToolsFramework--EntityOutlinerWidget #m_display_options { qproperty-icon: url(:/stylesheet/img/UI20/menu-centered.svg); qproperty-iconSize: 16px 16px; - qproperty-flat: true; } AzToolsFramework--EntityOutlinerWidget QTreeView From f26e272a8dc39e1e94946f4e8e32367f48963072 Mon Sep 17 00:00:00 2001 From: jromnoa <80134229+jromnoa@users.noreply.github.com> Date: Thu, 4 Nov 2021 12:20:38 -0700 Subject: [PATCH 07/19] move light component non optimized test to sandbox until it gets optimized (ticket cut for this) Signed-off-by: jromnoa <80134229+jromnoa@users.noreply.github.com> --- .../Gem/PythonTests/Atom/TestSuite_Sandbox.py | 65 +++++++++++++++++++ 1 file changed, 65 insertions(+) diff --git a/AutomatedTesting/Gem/PythonTests/Atom/TestSuite_Sandbox.py b/AutomatedTesting/Gem/PythonTests/Atom/TestSuite_Sandbox.py index 55b1540b7e..9ceb3c951f 100644 --- a/AutomatedTesting/Gem/PythonTests/Atom/TestSuite_Sandbox.py +++ b/AutomatedTesting/Gem/PythonTests/Atom/TestSuite_Sandbox.py @@ -12,6 +12,8 @@ import pytest import ly_test_tools.environment.file_system as file_system import editor_python_test_tools.hydra_test_utils as hydra +from Atom.atom_utils.atom_constants import LIGHT_TYPES + logger = logging.getLogger(__name__) TEST_DIRECTORY = os.path.join(os.path.dirname(__file__), "tests") @@ -23,6 +25,69 @@ class TestAtomEditorComponentsSandbox(object): pass +@pytest.mark.parametrize("project", ["AutomatedTesting"]) +@pytest.mark.parametrize("launcher_platform", ['windows_editor']) +@pytest.mark.parametrize("level", ["auto_test"]) +class TestAtomEditorComponentsMain(object): + """Holds tests for Atom components.""" + + @pytest.mark.test_case_id("C34525095") + def test_AtomEditorComponents_LightComponent( + self, request, editor, workspace, project, launcher_platform, level): + """ + Please review the hydra script run by this test for more specific test info. + Tests that the Light component has the expected property options available to it. + """ + cfg_args = [level] + + expected_lines = [ + "light_entity Entity successfully created", + "Entity has a Light component", + "light_entity_test: Component added to the entity: True", + f"light_entity_test: Property value is {LIGHT_TYPES['sphere']} which matches {LIGHT_TYPES['sphere']}", + "Controller|Configuration|Shadows|Enable shadow set to True", + "light_entity Controller|Configuration|Shadows|Shadowmap size: SUCCESS", + "Controller|Configuration|Shadows|Shadow filter method set to 1", # PCF + "Controller|Configuration|Shadows|Filtering sample count set to 4", + "Controller|Configuration|Shadows|Filtering sample count set to 64", + "Controller|Configuration|Shadows|Shadow filter method set to 2", # ESM + "Controller|Configuration|Shadows|ESM exponent set to 50.0", + "Controller|Configuration|Shadows|ESM exponent set to 5000.0", + "Controller|Configuration|Shadows|Shadow filter method set to 3", # ESM+PCF + f"light_entity_test: Property value is {LIGHT_TYPES['spot_disk']} which matches {LIGHT_TYPES['spot_disk']}", + f"light_entity_test: Property value is {LIGHT_TYPES['capsule']} which matches {LIGHT_TYPES['capsule']}", + f"light_entity_test: Property value is {LIGHT_TYPES['quad']} which matches {LIGHT_TYPES['quad']}", + "light_entity Controller|Configuration|Fast approximation: SUCCESS", + "light_entity Controller|Configuration|Both directions: SUCCESS", + f"light_entity_test: Property value is {LIGHT_TYPES['polygon']} which matches {LIGHT_TYPES['polygon']}", + f"light_entity_test: Property value is {LIGHT_TYPES['simple_point']} " + f"which matches {LIGHT_TYPES['simple_point']}", + "Controller|Configuration|Attenuation radius|Mode set to 0", + "Controller|Configuration|Attenuation radius|Radius set to 100.0", + f"light_entity_test: Property value is {LIGHT_TYPES['simple_spot']} " + f"which matches {LIGHT_TYPES['simple_spot']}", + "Controller|Configuration|Shutters|Outer angle set to 45.0", + "Controller|Configuration|Shutters|Outer angle set to 90.0", + "light_entity_test: Component added to the entity: True", + "Light component test (non-GPU) completed.", + ] + + unexpected_lines = ["Traceback (most recent call last):"] + + hydra.launch_and_validate_results( + request, + TEST_DIRECTORY, + editor, + "hydra_AtomEditorComponents_LightComponent.py", + timeout=120, + expected_lines=expected_lines, + unexpected_lines=unexpected_lines, + halt_on_unexpected=True, + null_renderer=True, + cfg_args=cfg_args, + ) + + @pytest.mark.parametrize("project", ["AutomatedTesting"]) @pytest.mark.parametrize("launcher_platform", ['windows_generic']) @pytest.mark.system From 5a3cd96eab655260f494daca914e91e8bc492725 Mon Sep 17 00:00:00 2001 From: Esteban Papp <81431996+amznestebanpapp@users.noreply.github.com> Date: Thu, 4 Nov 2021 12:23:41 -0700 Subject: [PATCH 08/19] Fixes for CMake 3.22rc (#5314) Signed-off-by: Esteban Papp <81431996+amznestebanpapp@users.noreply.github.com> --- .../Platform/Common/MSVC/Configurations_msvc.cmake | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/cmake/Platform/Common/MSVC/Configurations_msvc.cmake b/cmake/Platform/Common/MSVC/Configurations_msvc.cmake index a4d8533626..66a5b7b01f 100644 --- a/cmake/Platform/Common/MSVC/Configurations_msvc.cmake +++ b/cmake/Platform/Common/MSVC/Configurations_msvc.cmake @@ -139,11 +139,20 @@ endif() # Configure system includes ly_set(LY_CXX_SYSTEM_INCLUDE_CONFIGURATION_FLAG - /experimental:external # Turns on "external" headers feature for MSVC compilers + /experimental:external # Turns on "external" headers feature for MSVC compilers, required for MSVC < 16.10 /external:W0 # Set warning level in external headers to 0. This is used to suppress warnings 3rdParty libraries which uses the "system_includes" option in their json configuration ) + +# CMake 3.22rc added a definition for CMAKE_INCLUDE_SYSTEM_FLAG_CXX. However, its defined as "-external:I ", that space causes +# issues when trying to use in TargetIncludeSystemDirectories_unsupported.cmake. +# CMake 3.22rc has also not added support for external directories in MSVC through target_include_directories(... SYSTEM +# So we will just fix the flag that was added by 3.22rc so it works with our TargetIncludeSystemDirectories_unsupported.cmake +# Once target_include_directories(... SYSTEM is supported, we can branch and use TargetIncludeSystemDirectories_supported.cmake +# Reported this here: https://gitlab.kitware.com/cmake/cmake/-/issues/17904#note_1078281 if(NOT CMAKE_INCLUDE_SYSTEM_FLAG_CXX) - ly_set(CMAKE_INCLUDE_SYSTEM_FLAG_CXX /external:I) + ly_set(CMAKE_INCLUDE_SYSTEM_FLAG_CXX "/external:I") +else() + string(STRIP ${CMAKE_INCLUDE_SYSTEM_FLAG_CXX} CMAKE_INCLUDE_SYSTEM_FLAG_CXX) endif() include(cmake/Platform/Common/TargetIncludeSystemDirectories_unsupported.cmake) From 64ab8d5956c7024280826dae7d63a482f60b67ee Mon Sep 17 00:00:00 2001 From: Sean Masterson Date: Thu, 4 Nov 2021 12:13:25 -0700 Subject: [PATCH 09/19] Add P0 Bloom Test Signed-off-by: Sean Masterson --- .../Atom/TestSuite_Main_Optimized.py | 4 + .../Atom/atom_utils/atom_constants.py | 3 + .../hydra_AtomEditorComponents_BloomAdded.py | 188 ++++++++++++++++++ 3 files changed, 195 insertions(+) create mode 100644 AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_BloomAdded.py diff --git a/AutomatedTesting/Gem/PythonTests/Atom/TestSuite_Main_Optimized.py b/AutomatedTesting/Gem/PythonTests/Atom/TestSuite_Main_Optimized.py index 950bd44199..18c77391dc 100644 --- a/AutomatedTesting/Gem/PythonTests/Atom/TestSuite_Main_Optimized.py +++ b/AutomatedTesting/Gem/PythonTests/Atom/TestSuite_Main_Optimized.py @@ -14,6 +14,10 @@ from ly_test_tools.o3de.editor_test import EditorSharedTest, EditorTestSuite @pytest.mark.parametrize("launcher_platform", ['windows_editor']) class TestAutomation(EditorTestSuite): + @pytest.mark.test_case_id("C36525657") + class AtomEditorComponents_BloomAdded(EditorSharedTest): + from Atom.tests import hydra_AtomEditorComponents_BloomAdded as test_module + @pytest.mark.test_case_id("C32078118") class AtomEditorComponents_DecalAdded(EditorSharedTest): from Atom.tests import hydra_AtomEditorComponents_DecalAdded as test_module diff --git a/AutomatedTesting/Gem/PythonTests/Atom/atom_utils/atom_constants.py b/AutomatedTesting/Gem/PythonTests/Atom/atom_utils/atom_constants.py index c365999335..41ffaa0ce1 100644 --- a/AutomatedTesting/Gem/PythonTests/Atom/atom_utils/atom_constants.py +++ b/AutomatedTesting/Gem/PythonTests/Atom/atom_utils/atom_constants.py @@ -42,12 +42,14 @@ class AtomComponentProperties: Bloom component properties. Requires PostFX Layer component. - 'requires' a list of component names as strings required by this component. Use editor_entity_utils EditorEntity.add_components(list) to add this list of requirements.\n + - 'Enable Bloom' Toggle active state of the component True/False :param property: From the last element of the property tree path. Default 'name' for component name string. :return: Full property path OR component name if no property specified. """ properties = { 'name': 'Bloom', 'requires': [AtomComponentProperties.postfx_layer()], + 'Enable Bloom': 'Controller|Configuration|Enable Bloom', } return properties[property] @@ -212,6 +214,7 @@ class AtomComponentProperties: HDR Color Grading component properties. Requires PostFX Layer component. - 'requires' a list of component names as strings required by this component. Use editor_entity_utils EditorEntity.add_components(list) to add this list of requirements.\n + - 'Enable HDR color grading' Toggle active state of the component True/False :param property: From the last element of the property tree path. Default 'name' for component name string. :return: Full property path OR component name if no property specified. """ diff --git a/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_BloomAdded.py b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_BloomAdded.py new file mode 100644 index 0000000000..bce4b86a35 --- /dev/null +++ b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_BloomAdded.py @@ -0,0 +1,188 @@ +""" +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 +""" + +class Tests: + creation_undo = ( + "UNDO Entity creation success", + "UNDO Entity creation failed") + creation_redo = ( + "REDO Entity creation success", + "REDO Entity creation failed") + bloom_creation = ( + "Bloom Entity successfully created", + "Bloom Entity failed to be created") + bloom_component = ( + "Entity has a Bloom component", + "Entity failed to find Bloom component") + bloom_disabled = ( + "Bloom component disabled", + "Bloom component was not disabled") + postfx_layer_component = ( + "Entity has a PostFX Layer component", + "Entity did not have an PostFX Layer component") + bloom_enabled = ( + "Bloom component enabled", + "Bloom component was not enabled") + enable_bloom_parameter_enabled = ( + "Enable Bloom parameter enabled", + "Enable Bloom parameter was not enabled") + enter_game_mode = ( + "Entered game mode", + "Failed to enter game mode") + exit_game_mode = ( + "Exited game mode", + "Couldn't exit game mode") + is_visible = ( + "Entity is visible", + "Entity was not visible") + is_hidden = ( + "Entity is hidden", + "Entity was not hidden") + entity_deleted = ( + "Entity deleted", + "Entity was not deleted") + deletion_undo = ( + "UNDO deletion success", + "UNDO deletion failed") + deletion_redo = ( + "REDO deletion success", + "REDO deletion failed") + + +def AtomEditorComponents_Bloom_AddedToEntity(): + """ + Summary: + Tests the Bloom component can be added to an entity and has the expected functionality. + + Test setup: + - Wait for Editor idle loop. + - Open the "Base" level. + + Expected Behavior: + The component can be added, used in game mode, hidden/shown, deleted, and has accurate required components. + Creation and deletion undo/redo should also work. + + Test Steps: + 1) Create an Bloom entity with no components. + 2) Add Bloom component to Bloom entity. + 3) UNDO the entity creation and component addition. + 4) REDO the entity creation and component addition. + 5) Verify Bloom component not enabled. + 6) Add PostFX Layer component since it is required by the Bloom component. + 7) Verify Bloom component is enabled. + 8) Enable the "Enable Bloom" parameter. + 9) Enter/Exit game mode. + 10) Test IsHidden. + 11) Test IsVisible. + 12) Delete Bloom entity. + 13) UNDO deletion. + 14) REDO deletion. + 15) Look for errors. + + :return: None + """ + + import azlmbr.legacy.general as general + + from editor_python_test_tools.editor_entity_utils import EditorEntity + from editor_python_test_tools.utils import Report, Tracer, TestHelper + from Atom.atom_utils.atom_constants import AtomComponentProperties + + with Tracer() as error_tracer: + # Test setup begins. + # Setup: Wait for Editor idle loop before executing Python hydra scripts then open "Base" level. + TestHelper.init_idle() + TestHelper.open_level("", "Base") + + # Test steps begin. + # 1. Create an Bloom entity with no components. + bloom_entity = EditorEntity.create_editor_entity(AtomComponentProperties.bloom()) + Report.critical_result(Tests.bloom_creation, bloom_entity.exists()) + + # 2. Add Bloom component to Bloom entity. + bloom_component = bloom_entity.add_component(AtomComponentProperties.bloom()) + Report.critical_result(Tests.bloom_component, bloom_entity.has_component(AtomComponentProperties.bloom())) + + # 3. UNDO the entity creation and component addition. + # -> UNDO component addition. + general.undo() + # -> UNDO naming entity. + general.undo() + # -> UNDO selecting entity. + general.undo() + # -> UNDO entity creation. + general.undo() + general.idle_wait_frames(1) + Report.result(Tests.creation_undo, not bloom_entity.exists()) + + # 4. REDO the entity creation and component addition. + # -> REDO entity creation. + general.redo() + # -> REDO selecting entity. + general.redo() + # -> REDO naming entity. + general.redo() + # -> REDO component addition. + general.redo() + general.idle_wait_frames(1) + Report.result(Tests.creation_redo, bloom_entity.exists()) + + # 5. Verify Bloom component not enabled. + Report.result(Tests.bloom_disabled, not bloom_component.is_enabled()) + + # 6. Add PostFX Layer component since it is required by the Bloom component. + bloom_entity.add_component(AtomComponentProperties.postfx_layer()) + Report.result( + Tests.postfx_layer_component, + bloom_entity.has_component(AtomComponentProperties.postfx_layer())) + + # 7. Verify Bloom component is enabled. + Report.result(Tests.bloom_enabled, bloom_component.is_enabled()) + + # 8. Enable the "Enable Bloom" parameter. + bloom_component.set_component_property_value(AtomComponentProperties.bloom('Enable Bloom'), True) + Report.result( + Tests.enable_bloom_parameter_enabled, + bloom_component.get_component_property_value(AtomComponentProperties.bloom('Enable Bloom')) is True) + + # 9. Enter/Exit game mode. + TestHelper.enter_game_mode(Tests.enter_game_mode) + general.idle_wait_frames(1) + TestHelper.exit_game_mode(Tests.exit_game_mode) + + # 10. Test IsHidden. + bloom_entity.set_visibility_state(False) + Report.result(Tests.is_hidden, bloom_entity.is_hidden() is True) + + # 11. Test IsVisible. + bloom_entity.set_visibility_state(True) + general.idle_wait_frames(1) + Report.result(Tests.is_visible, bloom_entity.is_visible() is True) + + # 12. Delete Bloom entity. + bloom_entity.delete() + Report.result(Tests.entity_deleted, not bloom_entity.exists()) + + # 13. UNDO deletion. + general.undo() + Report.result(Tests.deletion_undo, bloom_entity.exists()) + + # 14. REDO deletion. + general.redo() + Report.result(Tests.deletion_redo, not bloom_entity.exists()) + + # 15. Look for errors and asserts. + TestHelper.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}") + + +if __name__ == "__main__": + from editor_python_test_tools.utils import Report + Report.start_test(AtomEditorComponents_Bloom_AddedToEntity) From 1f4cb58c5ebdfa1c1a68e200551737aea358c943 Mon Sep 17 00:00:00 2001 From: Gene Walters Date: Thu, 4 Nov 2021 13:49:33 -0700 Subject: [PATCH 10/19] Moving flaky multiplayer tests into sandbox so they will still be ran nightly, but we can still fix and create new tests Signed-off-by: Gene Walters --- .../Gem/PythonTests/CMakeLists.txt | 3 ++ .../PythonTests/Multiplayer/CMakeLists.txt | 13 +++++++ .../PythonTests/Multiplayer/TestSuite_Main.py | 4 --- .../Multiplayer/TestSuite_Sandbox.py | 35 +++++++++++++++++++ 4 files changed, 51 insertions(+), 4 deletions(-) create mode 100644 AutomatedTesting/Gem/PythonTests/Multiplayer/TestSuite_Sandbox.py diff --git a/AutomatedTesting/Gem/PythonTests/CMakeLists.txt b/AutomatedTesting/Gem/PythonTests/CMakeLists.txt index fd3222ba83..bec49185bd 100644 --- a/AutomatedTesting/Gem/PythonTests/CMakeLists.txt +++ b/AutomatedTesting/Gem/PythonTests/CMakeLists.txt @@ -59,5 +59,8 @@ add_subdirectory(smoke) ## AWS ## add_subdirectory(AWS) +## Multiplayer ## +add_subdirectory(Multiplayer) + ## Integration tests for editor testing framework ## add_subdirectory(editor_test_testing) diff --git a/AutomatedTesting/Gem/PythonTests/Multiplayer/CMakeLists.txt b/AutomatedTesting/Gem/PythonTests/Multiplayer/CMakeLists.txt index 5e74d1e93b..506d15c323 100644 --- a/AutomatedTesting/Gem/PythonTests/Multiplayer/CMakeLists.txt +++ b/AutomatedTesting/Gem/PythonTests/Multiplayer/CMakeLists.txt @@ -20,4 +20,17 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS) COMPONENT Multiplayer ) + ly_add_pytest( + NAME AutomatedTesting::MultiplayerTests_Sandbox + TEST_SUITE sandbox + TEST_SERIAL + PATH ${CMAKE_CURRENT_LIST_DIR}/TestSuite_Sandbox.py + RUNTIME_DEPENDENCIES + Legacy::Editor + AZ::AssetProcessor + AutomatedTesting.Assets + AutomatedTesting.ServerLauncher + COMPONENT + Multiplayer + ) endif() diff --git a/AutomatedTesting/Gem/PythonTests/Multiplayer/TestSuite_Main.py b/AutomatedTesting/Gem/PythonTests/Multiplayer/TestSuite_Main.py index 9cecaa7fe8..df1eb62943 100644 --- a/AutomatedTesting/Gem/PythonTests/Multiplayer/TestSuite_Main.py +++ b/AutomatedTesting/Gem/PythonTests/Multiplayer/TestSuite_Main.py @@ -27,7 +27,3 @@ class TestAutomation(TestAutomationBase): batch_mode=batch_mode, autotest_mode=autotest_mode) - def test_Multiplayer_AutoComponent_NetworkInput(self, request, workspace, editor, launcher_platform): - from .tests import Multiplayer_AutoComponent_NetworkInput as test_module - self._run_prefab_test(request, workspace, editor, test_module) - diff --git a/AutomatedTesting/Gem/PythonTests/Multiplayer/TestSuite_Sandbox.py b/AutomatedTesting/Gem/PythonTests/Multiplayer/TestSuite_Sandbox.py new file mode 100644 index 0000000000..52ac19b26e --- /dev/null +++ b/AutomatedTesting/Gem/PythonTests/Multiplayer/TestSuite_Sandbox.py @@ -0,0 +1,35 @@ +""" +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 + +""" + +# This suite consists of all test cases that are under development and have not been verified yet. +# Once they are verified, please move them to TestSuite_Active.py + +import pytest +import os +import sys + + +sys.path.append(os.path.dirname(os.path.abspath(__file__)) + '/../automatedtesting_shared') + +from base import TestAutomationBase + +@pytest.mark.SUITE_sandbox +@pytest.mark.parametrize("project", ["AutomatedTesting"]) +@pytest.mark.parametrize("launcher_platform", ['windows_editor']) +class TestAutomation(TestAutomationBase): + def _run_prefab_test(self, request, workspace, editor, test_module, batch_mode=True, autotest_mode=True): + self._run_test(request, workspace, editor, test_module, + extra_cmdline_args=["--regset=/Amazon/Preferences/EnablePrefabSystem=true"], + batch_mode=batch_mode, + autotest_mode=autotest_mode) + + ## Seems to be flaky, need to investigate + def test_Multiplayer_AutoComponent_NetworkInput(self, request, workspace, editor, launcher_platform): + from .tests import Multiplayer_AutoComponent_NetworkInput as test_module + self._run_prefab_test(request, workspace, editor, test_module) + From bbeefe43b836a67ccd3eca0ca4775600c9684edd Mon Sep 17 00:00:00 2001 From: Sean Masterson Date: Thu, 4 Nov 2021 13:52:54 -0700 Subject: [PATCH 11/19] Added extra line above class Tests Signed-off-by: Sean Masterson --- .../Atom/tests/hydra_AtomEditorComponents_BloomAdded.py | 1 + 1 file changed, 1 insertion(+) diff --git a/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_BloomAdded.py b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_BloomAdded.py index bce4b86a35..56b22eb20d 100644 --- a/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_BloomAdded.py +++ b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_BloomAdded.py @@ -5,6 +5,7 @@ For complete copyright and license terms please see the LICENSE at the root of t SPDX-License-Identifier: Apache-2.0 OR MIT """ + class Tests: creation_undo = ( "UNDO Entity creation success", From 0c97c879c108073b58ae6e9276212b2796170ef6 Mon Sep 17 00:00:00 2001 From: jromnoa <80134229+jromnoa@users.noreply.github.com> Date: Thu, 4 Nov 2021 13:58:30 -0700 Subject: [PATCH 12/19] remove the main suite optimized jobs from CMakeLists.txt since its causing a false build failure on AR Signed-off-by: jromnoa <80134229+jromnoa@users.noreply.github.com> --- .../Gem/PythonTests/Atom/CMakeLists.txt | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/AutomatedTesting/Gem/PythonTests/Atom/CMakeLists.txt b/AutomatedTesting/Gem/PythonTests/Atom/CMakeLists.txt index ff3cd5c465..87a66c880e 100644 --- a/AutomatedTesting/Gem/PythonTests/Atom/CMakeLists.txt +++ b/AutomatedTesting/Gem/PythonTests/Atom/CMakeLists.txt @@ -20,19 +20,6 @@ if(PAL_TRAIT_BUILD_HOST_TOOLS AND PAL_TRAIT_BUILD_TESTS_SUPPORTED) COMPONENT Atom ) - ly_add_pytest( - NAME AutomatedTesting::Atom_TestSuite_Main_Optimized - TEST_SUITE main - PATH ${CMAKE_CURRENT_LIST_DIR}/TestSuite_Main_Optimized.py - TEST_SERIAL - TIMEOUT 600 - RUNTIME_DEPENDENCIES - AssetProcessor - AutomatedTesting.Assets - Editor - COMPONENT - Atom - ) ly_add_pytest( NAME AutomatedTesting::Atom_TestSuite_Sandbox TEST_SUITE sandbox From 6bae0bca7e5a0947615a1814da4b1c397660e095 Mon Sep 17 00:00:00 2001 From: jromnoa <80134229+jromnoa@users.noreply.github.com> Date: Thu, 4 Nov 2021 15:08:02 -0700 Subject: [PATCH 13/19] add new bloom test to updated Main Suite test file since optimized main suite test file is removed Signed-off-by: jromnoa <80134229+jromnoa@users.noreply.github.com> --- AutomatedTesting/Gem/PythonTests/Atom/TestSuite_Main.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/AutomatedTesting/Gem/PythonTests/Atom/TestSuite_Main.py b/AutomatedTesting/Gem/PythonTests/Atom/TestSuite_Main.py index 62a402d9c4..cce9a27da6 100644 --- a/AutomatedTesting/Gem/PythonTests/Atom/TestSuite_Main.py +++ b/AutomatedTesting/Gem/PythonTests/Atom/TestSuite_Main.py @@ -13,6 +13,10 @@ from ly_test_tools.o3de.editor_test import EditorSharedTest, EditorTestSuite @pytest.mark.parametrize("launcher_platform", ['windows_editor']) class TestAutomation(EditorTestSuite): + @pytest.mark.test_case_id("C36525657") + class AtomEditorComponents_BloomAdded(EditorSharedTest): + from Atom.tests import hydra_AtomEditorComponents_BloomAdded as test_module + @pytest.mark.test_case_id("C32078118") class AtomEditorComponents_DecalAdded(EditorSharedTest): from Atom.tests import hydra_AtomEditorComponents_DecalAdded as test_module From 708582731dc58f99fe71290863878600141ca432 Mon Sep 17 00:00:00 2001 From: Sean Masterson Date: Thu, 4 Nov 2021 16:56:46 -0700 Subject: [PATCH 14/19] Add P0 Deferred Fog Test Signed-off-by: Sean Masterson --- .../Gem/PythonTests/Atom/TestSuite_Main.py | 4 + .../Atom/atom_utils/atom_constants.py | 2 + ...a_AtomEditorComponents_DeferredFogAdded.py | 193 ++++++++++++++++++ 3 files changed, 199 insertions(+) create mode 100644 AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_DeferredFogAdded.py diff --git a/AutomatedTesting/Gem/PythonTests/Atom/TestSuite_Main.py b/AutomatedTesting/Gem/PythonTests/Atom/TestSuite_Main.py index cce9a27da6..52e7ec993e 100644 --- a/AutomatedTesting/Gem/PythonTests/Atom/TestSuite_Main.py +++ b/AutomatedTesting/Gem/PythonTests/Atom/TestSuite_Main.py @@ -21,6 +21,10 @@ class TestAutomation(EditorTestSuite): class AtomEditorComponents_DecalAdded(EditorSharedTest): from Atom.tests import hydra_AtomEditorComponents_DecalAdded as test_module + @pytest.mark.test_case_id("C36525658") + class AtomEditorComponents_DeferredFogAdded(EditorSharedTest): + from Atom.tests import hydra_AtomEditorComponents_DeferredFogAdded as test_module + @pytest.mark.test_case_id("C32078119") class AtomEditorComponents_DepthOfFieldAdded(EditorSharedTest): from Atom.tests import hydra_AtomEditorComponents_DepthOfFieldAdded as test_module diff --git a/AutomatedTesting/Gem/PythonTests/Atom/atom_utils/atom_constants.py b/AutomatedTesting/Gem/PythonTests/Atom/atom_utils/atom_constants.py index 41ffaa0ce1..0c3410ff33 100644 --- a/AutomatedTesting/Gem/PythonTests/Atom/atom_utils/atom_constants.py +++ b/AutomatedTesting/Gem/PythonTests/Atom/atom_utils/atom_constants.py @@ -86,11 +86,13 @@ class AtomComponentProperties: - 'requires' a list of component names as strings required by this component. Use editor_entity_utils EditorEntity.add_components(list) to add this list of requirements.\n :param property: From the last element of the property tree path. Default 'name' for component name string. + - 'Enable Deferred Fog' Toggle active state of the component True/False :return: Full property path OR component name if no property specified. """ properties = { 'name': 'Deferred Fog', 'requires': [AtomComponentProperties.postfx_layer()], + 'Enable Deferred Fog': 'Controller|Configuration|Enable Deferred Fog', } return properties[property] diff --git a/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_DeferredFogAdded.py b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_DeferredFogAdded.py new file mode 100644 index 0000000000..71163ece94 --- /dev/null +++ b/AutomatedTesting/Gem/PythonTests/Atom/tests/hydra_AtomEditorComponents_DeferredFogAdded.py @@ -0,0 +1,193 @@ +""" +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 +""" + + +class Tests: + creation_undo = ( + "UNDO Entity creation success", + "UNDO Entity creation failed") + creation_redo = ( + "REDO Entity creation success", + "REDO Entity creation failed") + deferred_fog_creation = ( + "Deferred Fog Entity successfully created", + "Deferred Fog Entity failed to be created") + deferred_fog_component = ( + "Entity has a Deferred Fog component", + "Entity failed to find Deferred Fog component") + deferred_fog_disabled = ( + "Deferred Fog component disabled", + "Deferred Fog component was not disabled") + postfx_layer_component = ( + "Entity has a PostFX Layer component", + "Entity did not have an PostFX Layer component") + deferred_fog_enabled = ( + "Deferred Fog component enabled", + "Deferred Fog component was not enabled") + enable_deferred_fog_parameter_enabled = ( + "Enable Deferred Fog parameter enabled", + "Enable Deferred Fog parameter was not enabled") + enter_game_mode = ( + "Entered game mode", + "Failed to enter game mode") + exit_game_mode = ( + "Exited game mode", + "Couldn't exit game mode") + is_visible = ( + "Entity is visible", + "Entity was not visible") + is_hidden = ( + "Entity is hidden", + "Entity was not hidden") + entity_deleted = ( + "Entity deleted", + "Entity was not deleted") + deletion_undo = ( + "UNDO deletion success", + "UNDO deletion failed") + deletion_redo = ( + "REDO deletion success", + "REDO deletion failed") + + +def AtomEditorComponents_DeferredFog_AddedToEntity(): + """ + Summary: + Tests the Deferred Fog component can be added to an entity and has the expected functionality. + + Test setup: + - Wait for Editor idle loop. + - Open the "Base" level. + + Expected Behavior: + The component can be added, used in game mode, hidden/shown, deleted, and has accurate required components. + Creation and deletion undo/redo should also work. + + Test Steps: + 1) Create an Deferred Fog entity with no components. + 2) Add Deferred Fog component to Deferred Fog entity. + 3) UNDO the entity creation and component addition. + 4) REDO the entity creation and component addition. + 5) Verify Deferred Fog component not enabled. + 6) Add PostFX Layer component since it is required by the Deferred Fog component. + 7) Verify Deferred Fog component is enabled. + 8) Enable the "Enable Deferred Fog" parameter. + 9) Enter/Exit game mode. + 10) Test IsHidden. + 11) Test IsVisible. + 12) Delete Deferred Fog entity. + 13) UNDO deletion. + 14) REDO deletion. + 15) Look for errors. + + :return: None + """ + + import azlmbr.legacy.general as general + + from editor_python_test_tools.editor_entity_utils import EditorEntity + from editor_python_test_tools.utils import Report, Tracer, TestHelper + from Atom.atom_utils.atom_constants import AtomComponentProperties + + with Tracer() as error_tracer: + # Test setup begins. + # Setup: Wait for Editor idle loop before executing Python hydra scripts then open "Base" level. + TestHelper.init_idle() + TestHelper.open_level("", "Base") + + # Test steps begin. + # 1. Create an Deferred Fog entity with no components. + deferred_fog_entity = EditorEntity.create_editor_entity(AtomComponentProperties.deferred_fog()) + Report.critical_result(Tests.deferred_fog_creation, deferred_fog_entity.exists()) + + # 2. Add Deferred Fog component to Deferred Fog entity. + deferred_fog_component = deferred_fog_entity.add_component( + AtomComponentProperties.deferred_fog()) + Report.critical_result( + Tests.deferred_fog_component, + deferred_fog_entity.has_component(AtomComponentProperties.deferred_fog())) + + # 3. UNDO the entity creation and component addition. + # -> UNDO component addition. + general.undo() + # -> UNDO naming entity. + general.undo() + # -> UNDO selecting entity. + general.undo() + # -> UNDO entity creation. + general.undo() + general.idle_wait_frames(1) + Report.result(Tests.creation_undo, not deferred_fog_entity.exists()) + + # 4. REDO the entity creation and component addition. + # -> REDO entity creation. + general.redo() + # -> REDO selecting entity. + general.redo() + # -> REDO naming entity. + general.redo() + # -> REDO component addition. + general.redo() + general.idle_wait_frames(1) + Report.result(Tests.creation_redo, deferred_fog_entity.exists()) + + # 5. Verify Deferred Fog component not enabled. + Report.result(Tests.deferred_fog_disabled, not deferred_fog_component.is_enabled()) + + # 6. Add PostFX Layer component since it is required by the Deferred Fog component. + deferred_fog_entity.add_component(AtomComponentProperties.postfx_layer()) + Report.result( + Tests.postfx_layer_component, + deferred_fog_entity.has_component(AtomComponentProperties.postfx_layer())) + + # 7. Verify Deferred Fog component is enabled. + Report.result(Tests.deferred_fog_enabled, deferred_fog_component.is_enabled()) + + # 8. Enable the "Enable Deferred Fog" parameter. + deferred_fog_component.set_component_property_value( + AtomComponentProperties.deferred_fog('Enable Deferred Fog'), True) + Report.result(Tests.enable_deferred_fog_parameter_enabled, + deferred_fog_component.get_component_property_value( + AtomComponentProperties.deferred_fog('Enable Deferred Fog')) is True) + + # 9. Enter/Exit game mode. + TestHelper.enter_game_mode(Tests.enter_game_mode) + general.idle_wait_frames(1) + TestHelper.exit_game_mode(Tests.exit_game_mode) + + # 10. Test IsHidden. + deferred_fog_entity.set_visibility_state(False) + Report.result(Tests.is_hidden, deferred_fog_entity.is_hidden() is True) + + # 11. Test IsVisible. + deferred_fog_entity.set_visibility_state(True) + general.idle_wait_frames(1) + Report.result(Tests.is_visible, deferred_fog_entity.is_visible() is True) + + # 12. Delete Deferred Fog entity. + deferred_fog_entity.delete() + Report.result(Tests.entity_deleted, not deferred_fog_entity.exists()) + + # 13. UNDO deletion. + general.undo() + Report.result(Tests.deletion_undo, deferred_fog_entity.exists()) + + # 14. REDO deletion. + general.redo() + Report.result(Tests.deletion_redo, not deferred_fog_entity.exists()) + + # 15. Look for errors and asserts. + TestHelper.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}") + + +if __name__ == "__main__": + from editor_python_test_tools.utils import Report + Report.start_test(AtomEditorComponents_DeferredFog_AddedToEntity) From 84d38a4f9cc613972513639fa7b5158738cc87e6 Mon Sep 17 00:00:00 2001 From: Gene Walters Date: Thu, 4 Nov 2021 22:23:00 -0700 Subject: [PATCH 15/19] Removing Multiplayer MainSuite tests, because AR considers no-test to be a failure Signed-off-by: Gene Walters --- .../Gem/PythonTests/Multiplayer/CMakeLists.txt | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/AutomatedTesting/Gem/PythonTests/Multiplayer/CMakeLists.txt b/AutomatedTesting/Gem/PythonTests/Multiplayer/CMakeLists.txt index 506d15c323..367de4da9a 100644 --- a/AutomatedTesting/Gem/PythonTests/Multiplayer/CMakeLists.txt +++ b/AutomatedTesting/Gem/PythonTests/Multiplayer/CMakeLists.txt @@ -7,19 +7,6 @@ # if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS) - ly_add_pytest( - NAME AutomatedTesting::MultiplayerTests_Main - TEST_SUITE main - TEST_SERIAL - PATH ${CMAKE_CURRENT_LIST_DIR}/TestSuite_Main.py - RUNTIME_DEPENDENCIES - Legacy::Editor - AZ::AssetProcessor - AutomatedTesting.Assets - AutomatedTesting.ServerLauncher - COMPONENT - Multiplayer - ) ly_add_pytest( NAME AutomatedTesting::MultiplayerTests_Sandbox TEST_SUITE sandbox From c0ece7d32d8e7ba68e3efadcd47a2f3024a01c78 Mon Sep 17 00:00:00 2001 From: Sean Masterson Date: Fri, 5 Nov 2021 09:49:59 -0700 Subject: [PATCH 16/19] Update to atom_constants.py docstring Signed-off-by: Sean Masterson --- .../Gem/PythonTests/Atom/atom_utils/atom_constants.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/AutomatedTesting/Gem/PythonTests/Atom/atom_utils/atom_constants.py b/AutomatedTesting/Gem/PythonTests/Atom/atom_utils/atom_constants.py index 0c3410ff33..70156b9375 100644 --- a/AutomatedTesting/Gem/PythonTests/Atom/atom_utils/atom_constants.py +++ b/AutomatedTesting/Gem/PythonTests/Atom/atom_utils/atom_constants.py @@ -85,8 +85,8 @@ class AtomComponentProperties: Deferred Fog component properties. Requires PostFX Layer component. - 'requires' a list of component names as strings required by this component. Use editor_entity_utils EditorEntity.add_components(list) to add this list of requirements.\n + - 'Enable Deferred Fog' Toggle active state of the component True/False :param property: From the last element of the property tree path. Default 'name' for component name string. - - 'Enable Deferred Fog' Toggle active state of the component True/False :return: Full property path OR component name if no property specified. """ properties = { From 08115fc41fe8ae94933ac73c2fbb33a15eef1836 Mon Sep 17 00:00:00 2001 From: Shirang Jia Date: Fri, 5 Nov 2021 10:36:14 -0700 Subject: [PATCH 17/19] Add platform name to AP log path on S3 (#5316) * Add platform name to AP log path on S3 Signed-off-by: shiranj * Add platform name to AP log path on S3 Signed-off-by: shiranj --- scripts/build/Jenkins/Jenkinsfile | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/scripts/build/Jenkins/Jenkinsfile b/scripts/build/Jenkins/Jenkinsfile index ff04902861..6c3d697d2a 100644 --- a/scripts/build/Jenkins/Jenkinsfile +++ b/scripts/build/Jenkins/Jenkinsfile @@ -271,7 +271,7 @@ def CheckoutRepo(boolean disableSubmodules = false) { palRm('commitdate') } -def HandleDriveMount(String snapshot, String repositoryName, String projectName, String pipeline, String branchName, String platform, String buildType, String workspace, boolean recreateVolume = false) { +def HandleDriveMount(String snapshot, String repositoryName, String projectName, String pipeline, String branchName, String platform, String buildType, String workspace, boolean recreateVolume = false) { unstash name: 'incremental_build_script' def pythonCmd = '' @@ -435,7 +435,7 @@ def ExportTestScreenshots(Map options, String branchName, String platformName, S } } -def UploadAPLogs(Map options, String branchName, String jobName, String workspace, Map params) { +def UploadAPLogs(Map options, String branchName, String platformName, String jobName, String workspace, Map params) { dir("${workspace}/${ENGINE_REPOSITORY_NAME}") { projects = params.CMAKE_LY_PROJECTS.split(",") projects.each{ project -> @@ -449,7 +449,7 @@ def UploadAPLogs(Map options, String branchName, String jobName, String workspac } def command = "${pythonPath} -u ${s3UploadScriptPath} --base_dir ${apLogsPath} " + "--file_regex \".*\" --bucket ${env.AP_LOGS_S3_BUCKET} " + - "--search_subdirectories True --key_prefix ${env.JENKINS_JOB_NAME}/${branchName}/${env.BUILD_NUMBER}/${jobName} " + + "--search_subdirectories True --key_prefix ${env.JENKINS_JOB_NAME}/${branchName}/${env.BUILD_NUMBER}/${platformName}/${jobName} " + '--extra_args {\\"ACL\\":\\"bucket-owner-full-control\\"}' palSh(command, "Uploading AP logs for job ${jobName} for branch ${branchName}", false) } @@ -519,10 +519,10 @@ def CreateExportTestScreenshotsStage(Map pipelineConfig, String branchName, Stri } } -def CreateUploadAPLogsStage(Map pipelineConfig, String branchName, String jobName, String workspace, Map params) { +def CreateUploadAPLogsStage(Map pipelineConfig, String branchName, String platformName, String jobName, String workspace, Map params) { return { stage("${jobName}_upload_ap_logs") { - UploadAPLogs(pipelineConfig, branchName, jobName, workspace, params) + UploadAPLogs(pipelineConfig, branchName, platformName, jobName, workspace, params) } } } @@ -577,7 +577,7 @@ def CreateSingleNode(Map pipelineConfig, def platform, def build_job, Map envVar } } if (IsAPLogUpload(branchName, build_job_name)) { - CreateUploadAPLogsStage(pipelineConfig, branchName, build_job_name, envVars['WORKSPACE'], platform.value.build_types[build_job_name].PARAMETERS).call() + CreateUploadAPLogsStage(pipelineConfig, branchName, platform.key, build_job_name, envVars['WORKSPACE'], platform.value.build_types[build_job_name].PARAMETERS).call() } // All other errors will be raised outside the retry block currentResult = envVars['ON_FAILURE_MARK'] ?: 'FAILURE' From eecf6ab920ea3688e2430e7ac885380685610492 Mon Sep 17 00:00:00 2001 From: Esteban Papp <81431996+amznestebanpapp@users.noreply.github.com> Date: Fri, 5 Nov 2021 12:30:19 -0700 Subject: [PATCH 18/19] Create a nightly job that validates project-centric/engine-prebuilt (#5287) * adds a test_install_profile_vs2019_pipe job to validate a project can build from the SDK Signed-off-by: Esteban Papp <81431996+amznestebanpapp@users.noreply.github.com> * missed escaping these variables and breaks runtime dependencines in the install layout Signed-off-by: Esteban Papp <81431996+amznestebanpapp@users.noreply.github.com> * Changes to PIPELINE_ENV_OVERRIDE Signed-off-by: Esteban Papp <81431996+amznestebanpapp@users.noreply.github.com> * Tries to propagate ENV variables from pipeline jobs to jobs under it Signed-off-by: Esteban Papp <81431996+amznestebanpapp@users.noreply.github.com> * Fixes typo Signed-off-by: Esteban Papp <81431996+amznestebanpapp@users.noreply.github.com> * echoing a var to understand why is not going to the right path Signed-off-by: Esteban Papp <81431996+amznestebanpapp@users.noreply.github.com> * put the COMMAND_CWD in the wrong job Signed-off-by: Esteban Papp <81431996+amznestebanpapp@users.noreply.github.com> * adding similar jobs for linux/mac Signed-off-by: Esteban Papp <81431996+amznestebanpapp@users.noreply.github.com> * dont pass an empty LY_PROJECTS Signed-off-by: Esteban Papp <81431996+amznestebanpapp@users.noreply.github.com> * cmd -> sh, copy-paste mistake Signed-off-by: Esteban Papp <81431996+amznestebanpapp@users.noreply.github.com> * inverting check in linux/mac Signed-off-by: Esteban Papp <81431996+amznestebanpapp@users.noreply.github.com> * more fixes for linux/mac Signed-off-by: Esteban Papp <81431996+amznestebanpapp@users.noreply.github.com> * fixing script paths for macos Signed-off-by: Esteban Papp <81431996+amznestebanpapp@users.noreply.github.com> * more fixes for linux/mac Signed-off-by: Esteban Papp <81431996+amznestebanpapp@users.noreply.github.com> * Test use of %% instead of !! for windows builds Signed-off-by: Esteban Papp <81431996+amznestebanpapp@users.noreply.github.com> * fixes typo Signed-off-by: Esteban Papp <81431996+amznestebanpapp@users.noreply.github.com> --- scripts/build/Jenkins/Jenkinsfile | 4 +- .../build/Platform/Linux/build_config.json | 43 +++++++++++++++++ scripts/build/Platform/Linux/build_linux.sh | 5 +- scripts/build/Platform/Linux/env_linux.sh | 5 ++ scripts/build/Platform/Mac/build_config.json | 45 +++++++++++++++++ scripts/build/Platform/Mac/build_mac.sh | 5 +- scripts/build/Platform/Mac/env_mac.sh | 5 ++ .../build/Platform/Windows/build_config.json | 48 ++++++++++++------- .../build/Platform/Windows/build_windows.cmd | 19 ++++---- .../build/Platform/Windows/env_windows.cmd | 5 ++ 10 files changed, 157 insertions(+), 27 deletions(-) diff --git a/scripts/build/Jenkins/Jenkinsfile b/scripts/build/Jenkins/Jenkinsfile index 6c3d697d2a..8eddb61c33 100644 --- a/scripts/build/Jenkins/Jenkinsfile +++ b/scripts/build/Jenkins/Jenkinsfile @@ -551,9 +551,11 @@ def CreateSingleNode(Map pipelineConfig, def platform, def build_job, Map envVar CreateSetupStage(pipelineConfig, snapshot, repositoryName, projectName, pipelineName, branchName, platform.key, build_job.key, envVars, onlyMountEBSVolume).call() if(build_job.value.steps) { //this is a pipe with many steps so create all the build stages + pipelineEnvVars = GetBuildEnvVars(platform.value.PIPELINE_ENV ?: EMPTY_JSON, build_job.value.PIPELINE_ENV ?: EMPTY_JSON, pipelineName) build_job.value.steps.each { build_step -> build_job_name = build_step - envVars = GetBuildEnvVars(platform.value.PIPELINE_ENV ?: EMPTY_JSON, platform.value.build_types[build_step].PIPELINE_ENV ?: EMPTY_JSON, pipelineName) + // This addition of maps makes it that the right operand will override entries if they overlap with the left operand + envVars = pipelineEnvVars + GetBuildEnvVars(platform.value.PIPELINE_ENV ?: EMPTY_JSON, platform.value.build_types[build_step].PIPELINE_ENV ?: EMPTY_JSON, pipelineName) try { CreateBuildStage(pipelineConfig, platform.key, build_step, envVars).call() } diff --git a/scripts/build/Platform/Linux/build_config.json b/scripts/build/Platform/Linux/build_config.json index c0307de23d..8551c3dcb3 100644 --- a/scripts/build/Platform/Linux/build_config.json +++ b/scripts/build/Platform/Linux/build_config.json @@ -214,5 +214,48 @@ "CMAKE_LY_PROJECTS": "AutomatedTesting", "CMAKE_TARGET": "all" } + }, + "install_profile": { + "TAGS": [], + "COMMAND": "build_linux.sh", + "PARAMETERS": { + "CONFIGURATION": "profile", + "OUTPUT_DIRECTORY": "build/linux", + "CMAKE_OPTIONS": "-G 'Ninja Multi-Config' -DCMAKE_C_COMPILER=clang-6.0 -DCMAKE_CXX_COMPILER=clang++-6.0 -DLY_PARALLEL_LINK_JOBS=4 -DLY_DISABLE_TEST_MODULES=TRUE", + "CMAKE_TARGET": "install" + } + }, + "install_profile_pipe": { + "TAGS": [ + "nightly-incremental", + "nightly-clean" + ], + "PIPELINE_ENV": { + "PROJECT_REPOSITORY_NAME": "TestProject" + }, + "steps": [ + "install_profile", + "project_generate", + "project_engineinstall_profile" + ] + }, + "project_generate": { + "TAGS": [], + "COMMAND": "python_linux.sh", + "PARAMETERS": { + "SCRIPT_PATH": "install/scripts/o3de.py", + "SCRIPT_PARAMETERS": "create-project -pp ${WORKSPACE}/${PROJECT_REPOSITORY_NAME} --force" + } + }, + "project_engineinstall_profile": { + "TAGS": [], + "COMMAND": "build_linux.sh", + "PARAMETERS": { + "COMMAND_CWD": "${WORKSPACE}/${PROJECT_REPOSITORY_NAME}", + "CONFIGURATION": "profile", + "OUTPUT_DIRECTORY": "build/linux", + "CMAKE_OPTIONS": "-G 'Ninja Multi-Config' -DCMAKE_C_COMPILER=clang-6.0 -DCMAKE_CXX_COMPILER=clang++-6.0 -DLY_PARALLEL_LINK_JOBS=4 -DCMAKE_MODULE_PATH=${WORKSPACE}/o3de/install/cmake", + "CMAKE_TARGET": "all" + } } } diff --git a/scripts/build/Platform/Linux/build_linux.sh b/scripts/build/Platform/Linux/build_linux.sh index fd73e17a12..ab51913550 100755 --- a/scripts/build/Platform/Linux/build_linux.sh +++ b/scripts/build/Platform/Linux/build_linux.sh @@ -17,7 +17,10 @@ SOURCE_DIRECTORY=${PWD} pushd $OUTPUT_DIRECTORY LAST_CONFIGURE_CMD_FILE=ci_last_configure_cmd.txt -CONFIGURE_CMD="cmake ${SOURCE_DIRECTORY} ${CMAKE_OPTIONS} ${EXTRA_CMAKE_OPTIONS} -DLY_3RDPARTY_PATH=${LY_3RDPARTY_PATH} -DLY_PROJECTS='${CMAKE_LY_PROJECTS}'" +CONFIGURE_CMD="cmake ${SOURCE_DIRECTORY} ${CMAKE_OPTIONS} ${EXTRA_CMAKE_OPTIONS} -DLY_3RDPARTY_PATH=${LY_3RDPARTY_PATH}" +if [[ -n "$CMAKE_LY_PROJECTS" ]]; then + CONFIGURE_CMD="${CONFIGURE_CMD} -DLY_PROJECTS='${CMAKE_LY_PROJECTS}'" +fi if [[ ! -e "CMakeCache.txt" ]]; then echo [ci_build] First run, generating RUN_CONFIGURE=1 diff --git a/scripts/build/Platform/Linux/env_linux.sh b/scripts/build/Platform/Linux/env_linux.sh index a03b9642fb..059bb119ff 100755 --- a/scripts/build/Platform/Linux/env_linux.sh +++ b/scripts/build/Platform/Linux/env_linux.sh @@ -18,3 +18,8 @@ if ! command -v ninja &> /dev/null; then echo "[ci_build] Ninja not found" exit 1 fi + +if [[ -n "${COMMAND_CWD}" ]]; then + echo $(eval echo [ci_build] Changing CWD to $COMMAND_CWD) + cd $(eval echo ${COMMAND_CWD}) +fi diff --git a/scripts/build/Platform/Mac/build_config.json b/scripts/build/Platform/Mac/build_config.json index b57cc522bc..34b02a1aec 100644 --- a/scripts/build/Platform/Mac/build_config.json +++ b/scripts/build/Platform/Mac/build_config.json @@ -162,5 +162,50 @@ "SCRIPT_PATH": "scripts/build/package/package.py", "SCRIPT_PARAMETERS": "--platform Mac --type all" } + }, + "install_profile": { + "TAGS": [], + "COMMAND": "build_mac.sh", + "PARAMETERS": { + "CONFIGURATION": "profile", + "OUTPUT_DIRECTORY": "build/mac", + "CMAKE_OPTIONS": "-G Xcode -DLY_DISABLE_TEST_MODULES=TRUE", + "CMAKE_LY_PROJECTS": "", + "CMAKE_TARGET": "install" + } + }, + "install_profile_pipe": { + "TAGS": [ + "nightly-incremental", + "nightly-clean" + ], + "PIPELINE_ENV": { + "PROJECT_REPOSITORY_NAME": "TestProject" + }, + "steps": [ + "install_profile", + "project_generate", + "project_engineinstall_profile" + ] + }, + "project_generate": { + "TAGS": [], + "COMMAND": "python_mac.sh", + "PARAMETERS": { + "SCRIPT_PATH": "install/O3DE_SDK.app/Contents/Engine/scripts/o3de.py", + "SCRIPT_PARAMETERS": "create-project -pp ${WORKSPACE}/${PROJECT_REPOSITORY_NAME} --force" + } + }, + "project_engineinstall_profile": { + "TAGS": [], + "COMMAND": "build_mac.sh", + "PARAMETERS": { + "COMMAND_CWD": "${WORKSPACE}/${PROJECT_REPOSITORY_NAME}", + "CONFIGURATION": "profile", + "OUTPUT_DIRECTORY": "build/mac", + "CMAKE_OPTIONS": "-G Xcode -DCMAKE_MODULE_PATH=${WORKSPACE}/o3de/install/O3DE_SDK.app/Contents/Engine/cmake", + "CMAKE_LY_PROJECTS": "", + "CMAKE_TARGET": "ALL_BUILD" + } } } diff --git a/scripts/build/Platform/Mac/build_mac.sh b/scripts/build/Platform/Mac/build_mac.sh index cb271212d6..169e91c24f 100755 --- a/scripts/build/Platform/Mac/build_mac.sh +++ b/scripts/build/Platform/Mac/build_mac.sh @@ -17,7 +17,10 @@ SOURCE_DIRECTORY=${PWD} pushd $OUTPUT_DIRECTORY LAST_CONFIGURE_CMD_FILE=ci_last_configure_cmd.txt -CONFIGURE_CMD="cmake ${SOURCE_DIRECTORY} ${CMAKE_OPTIONS} ${EXTRA_CMAKE_OPTIONS} -DLY_3RDPARTY_PATH=${LY_3RDPARTY_PATH} -DLY_PROJECTS='${CMAKE_LY_PROJECTS}'" +CONFIGURE_CMD="cmake ${SOURCE_DIRECTORY} ${CMAKE_OPTIONS} ${EXTRA_CMAKE_OPTIONS} -DLY_3RDPARTY_PATH=${LY_3RDPARTY_PATH}" +if [[ -n "$CMAKE_LY_PROJECTS" ]]; then + CONFIGURE_CMD="${CONFIGURE_CMD} -DLY_PROJECTS='${CMAKE_LY_PROJECTS}'" +fi if [[ ! -e "CMakeCache.txt" ]]; then echo [ci_build] First run, generating RUN_CONFIGURE=1 diff --git a/scripts/build/Platform/Mac/env_mac.sh b/scripts/build/Platform/Mac/env_mac.sh index 2c974a1efe..f5fd9f5773 100755 --- a/scripts/build/Platform/Mac/env_mac.sh +++ b/scripts/build/Platform/Mac/env_mac.sh @@ -13,3 +13,8 @@ if ! command -v cmake &> /dev/null; then echo "[ci_build] CMake not found" exit 1 fi + +if [[ -n "${COMMAND_CWD}" ]]; then + echo $(eval echo [ci_build] Changing CWD to $COMMAND_CWD) + cd $(eval echo ${COMMAND_CWD}) +fi diff --git a/scripts/build/Platform/Windows/build_config.json b/scripts/build/Platform/Windows/build_config.json index b185a845ec..b0bb79b5dd 100644 --- a/scripts/build/Platform/Windows/build_config.json +++ b/scripts/build/Platform/Windows/build_config.json @@ -56,7 +56,7 @@ "COMMAND": "python_windows.cmd", "PARAMETERS": { "SCRIPT_PATH": "scripts/build/ci_build_metrics.py", - "SCRIPT_PARAMETERS": "--platform=Windows --repository=!REPOSITORY_NAME! --jobname=!JOB_NAME! --jobnumber=!BUILD_NUMBER! --jobnode=!NODE_LABEL! --changelist=!CHANGE_ID!" + "SCRIPT_PARAMETERS": "--platform=Windows --repository=%REPOSITORY_NAME% --jobname=%JOB_NAME% --jobnumber=%BUILD_NUMBER% --jobnode=%NODE_LABEL% --changelist=%CHANGE_ID%" } }, "windows_packaging_all": { @@ -88,7 +88,7 @@ "CONFIGURATION": "profile", "SCRIPT_PATH": "scripts/build/TestImpactAnalysis/tiaf_driver.py", "SCRIPT_PARAMETERS": - "--config=\"!OUTPUT_DIRECTORY!/bin/TestImpactFramework/profile/Persistent/tiaf.json\" --src-branch=!BRANCH_NAME! --dst-branch=!CHANGE_TARGET! --commit=!CHANGE_ID! --s3-bucket=!TEST_IMPACT_S3_BUCKET! --mars-index-prefix=jonawals --s3-top-level-dir=!REPOSITORY_NAME! --build-number=!BUILD_NUMBER! --suite=main --test-failure-policy=continue" + "--config=\"%OUTPUT_DIRECTORY%/bin/TestImpactFramework/profile/Persistent/tiaf.json\" --src-branch=%BRANCH_NAME% --dst-branch=%CHANGE_TARGET% --commit=%CHANGE_ID% --s3-bucket=%TEST_IMPACT_S3_BUCKET% --mars-index-prefix=jonawals --s3-top-level-dir=%REPOSITORY_NAME% --build-number=%BUILD_NUMBER% --suite=main --test-failure-policy=continue" } }, "debug_vs2019": { @@ -131,7 +131,7 @@ "PARAMETERS": { "CONFIGURATION": "profile", "OUTPUT_DIRECTORY": "build\\windows_vs2019", - "CMAKE_OPTIONS": "-G \"Visual Studio 16 2019\" -DCMAKE_SYSTEM_VERSION=10.0 -DLY_TEST_IMPACT_INSTRUMENTATION_BIN=!TEST_IMPACT_WIN_BINARY!", + "CMAKE_OPTIONS": "-G \"Visual Studio 16 2019\" -DCMAKE_SYSTEM_VERSION=10.0 -DLY_TEST_IMPACT_INSTRUMENTATION_BIN=%TEST_IMPACT_WIN_BINARY%", "CMAKE_LY_PROJECTS": "AutomatedTesting", "CMAKE_TARGET": "ALL_BUILD", "CMAKE_NATIVE_BUILD_ARGS": "/m /nologo" @@ -337,16 +337,12 @@ } }, "install_profile_vs2019": { - "TAGS": [ - "nightly-incremental", - "nightly-clean" - ], + "TAGS": [], "COMMAND": "build_windows.cmd", "PARAMETERS": { "CONFIGURATION": "profile", "OUTPUT_DIRECTORY": "build\\windows_vs2019", "CMAKE_OPTIONS": "-G \"Visual Studio 16 2019\" -DCMAKE_SYSTEM_VERSION=10.0 -DLY_DISABLE_TEST_MODULES=TRUE", - "CMAKE_LY_PROJECTS": "", "CMAKE_TARGET": "INSTALL", "CMAKE_NATIVE_BUILD_ARGS": "/m /nologo" } @@ -363,14 +359,35 @@ "PARAMETERS": { "CONFIGURATION": "profile", "OUTPUT_DIRECTORY": "build\\windows_vs2019", - "CMAKE_OPTIONS": "-G \"Visual Studio 16 2019\" -DCMAKE_SYSTEM_VERSION=10.0 -DLY_DISABLE_TEST_MODULES=TRUE -DLY_VERSION_ENGINE_NAME=o3de-sdk -DLY_INSTALLER_WIX_ROOT=\"!WIX! \"", - "EXTRA_CMAKE_OPTIONS": "-DLY_INSTALLER_AUTO_GEN_TAG=ON -DLY_INSTALLER_DOWNLOAD_URL=!INSTALLER_DOWNLOAD_URL! -DLY_INSTALLER_LICENSE_URL=!INSTALLER_DOWNLOAD_URL!/license", - "CPACK_BUCKET": "!INSTALLER_BUCKET!", - "CMAKE_LY_PROJECTS": "", + "CMAKE_OPTIONS": "-G \"Visual Studio 16 2019\" -DCMAKE_SYSTEM_VERSION=10.0 -DLY_DISABLE_TEST_MODULES=TRUE -DLY_VERSION_ENGINE_NAME=o3de-sdk -DLY_INSTALLER_WIX_ROOT=\"%WIX% \"", + "EXTRA_CMAKE_OPTIONS": "-DLY_INSTALLER_AUTO_GEN_TAG=ON -DLY_INSTALLER_DOWNLOAD_URL=%INSTALLER_DOWNLOAD_URL% -DLY_INSTALLER_LICENSE_URL=%INSTALLER_DOWNLOAD_URL%/license", + "CPACK_BUCKET": "%INSTALLER_BUCKET%", "CMAKE_TARGET": "ALL_BUILD", "CMAKE_NATIVE_BUILD_ARGS": "/m /nologo" } }, + "install_profile_vs2019_pipe": { + "TAGS": [ + "nightly-incremental", + "nightly-clean" + ], + "PIPELINE_ENV": { + "PROJECT_REPOSITORY_NAME": "TestProject" + }, + "steps": [ + "install_profile_vs2019", + "project_generate", + "project_engineinstall_profile_vs2019" + ] + }, + "project_generate": { + "TAGS": [], + "COMMAND": "python_windows.cmd", + "PARAMETERS": { + "SCRIPT_PATH": "install\\scripts\\o3de.py", + "SCRIPT_PARAMETERS": "create-project -pp %WORKSPACE%\\%PROJECT_REPOSITORY_NAME% --force" + } + }, "project_enginesource_profile_vs2019": { "TAGS": [ "project" @@ -382,8 +399,7 @@ "PARAMETERS": { "CONFIGURATION": "profile", "OUTPUT_DIRECTORY": "build\\windows_vs2019", - "CMAKE_OPTIONS": "-G \"Visual Studio 16 2019\" -DCMAKE_SYSTEM_VERSION=10.0 -DCMAKE_MODULE_PATH=!WORKSPACE!/o3de/cmake", - "CMAKE_LY_PROJECTS": "", + "CMAKE_OPTIONS": "-G \"Visual Studio 16 2019\" -DCMAKE_SYSTEM_VERSION=10.0 -DCMAKE_MODULE_PATH=%WORKSPACE%/o3de/cmake", "CMAKE_TARGET": "ALL_BUILD", "CMAKE_NATIVE_BUILD_ARGS": "/m /nologo" } @@ -395,10 +411,10 @@ }, "COMMAND": "build_windows.cmd", "PARAMETERS": { + "COMMAND_CWD": "%WORKSPACE%\\%PROJECT_REPOSITORY_NAME%", "CONFIGURATION": "profile", "OUTPUT_DIRECTORY": "build\\windows_vs2019", - "CMAKE_OPTIONS": "-G \"Visual Studio 16 2019\" -DCMAKE_SYSTEM_VERSION=10.0 -DCMAKE_MODULE_PATH=!WORKSPACE!/o3de/install/cmake", - "CMAKE_LY_PROJECTS": "", + "CMAKE_OPTIONS": "-G \"Visual Studio 16 2019\" -DCMAKE_SYSTEM_VERSION=10.0 -DCMAKE_MODULE_PATH=%WORKSPACE%/o3de/install/cmake", "CMAKE_TARGET": "ALL_BUILD", "CMAKE_NATIVE_BUILD_ARGS": "/m /nologo" } diff --git a/scripts/build/Platform/Windows/build_windows.cmd b/scripts/build/Platform/Windows/build_windows.cmd index b5a0245d1a..b9e862e04f 100644 --- a/scripts/build/Platform/Windows/build_windows.cmd +++ b/scripts/build/Platform/Windows/build_windows.cmd @@ -9,6 +9,13 @@ REM SETLOCAL EnableDelayedExpansion +REM Jenkins reports MSB8029 when TMP/TEMP is not defined, define a dummy folder +SET TMP=%cd%/temp +SET TEMP=%cd%/temp +IF NOT EXIST %TMP% ( + MKDIR temp +) + CALL %~dp0env_windows.cmd IF NOT EXIST "%OUTPUT_DIRECTORY%" ( @@ -25,18 +32,14 @@ IF ERRORLEVEL 1 ( exit /b 1 ) -REM Jenkins reports MSB8029 when TMP/TEMP is not defined, define a dummy folder -SET TMP=%cd%/temp -SET TEMP=%cd%/temp -IF NOT EXIST %TMP% ( - MKDIR temp -) - REM Compute half the amount of processors so some jobs can run SET /a HALF_PROCESSORS = NUMBER_OF_PROCESSORS / 2 SET LAST_CONFIGURE_CMD_FILE=ci_last_configure_cmd.txt -SET CONFIGURE_CMD=cmake %SOURCE_DIRECTORY% %CMAKE_OPTIONS% %EXTRA_CMAKE_OPTIONS% -DLY_3RDPARTY_PATH="%LY_3RDPARTY_PATH%" -DLY_PROJECTS=%CMAKE_LY_PROJECTS% +SET CONFIGURE_CMD=cmake %SOURCE_DIRECTORY% %CMAKE_OPTIONS% %EXTRA_CMAKE_OPTIONS% -DLY_3RDPARTY_PATH="%LY_3RDPARTY_PATH%" +IF NOT "%CMAKE_LY_PROJECTS%"=="" ( + SET CONFIGURE_CMD=!CONFIGURE_CMD! -DLY_PROJECTS="%CMAKE_LY_PROJECTS%" +) IF NOT EXIST CMakeCache.txt ( ECHO [ci_build] First run, generating SET RUN_CONFIGURE=1 diff --git a/scripts/build/Platform/Windows/env_windows.cmd b/scripts/build/Platform/Windows/env_windows.cmd index 1c54e36bfc..f11d394519 100644 --- a/scripts/build/Platform/Windows/env_windows.cmd +++ b/scripts/build/Platform/Windows/env_windows.cmd @@ -13,6 +13,11 @@ IF NOT %ERRORLEVEL%==0 ( GOTO :error ) +IF NOT "%COMMAND_CWD%"=="" ( + ECHO [ci_build] Changing CWD to %COMMAND_CWD% + CD %COMMAND_CWD% +) + EXIT /b 0 :error From 46f4935ee44693b17e884237810d0428bb4825a6 Mon Sep 17 00:00:00 2001 From: Mike Chang Date: Fri, 5 Nov 2021 14:04:05 -0700 Subject: [PATCH 19/19] Update to licenses/notices script (#5214) This updates the licenses script to pull in all PackageInfo.json files with a specific argument, then follows each license file defined and writes the contents to a file. In this mode, if a packageinfo file is found, it will only grab the license file path defined within. Also has the following features: * Generalizes the function and variable names for non-license specific references * Sorts os.walk to maintain consistent ordering * Uses an ordered dict for the output, also to maintain ordering if using Python below 3.7 * Adds an additional json config file to have specific exclusion rules for 3p packages * Adds a package creation function and config file entry * Allow multipath scans, optional use of gitignore, merged license file scan Signed-off-by: Mike Chang --- scripts/license_scanner/license_scanner.py | 140 ++++++++++++++------ scripts/license_scanner/scanner_config.json | 3 + 2 files changed, 103 insertions(+), 40 deletions(-) diff --git a/scripts/license_scanner/license_scanner.py b/scripts/license_scanner/license_scanner.py index c0e3c1f1ba..2936e343f9 100644 --- a/scripts/license_scanner/license_scanner.py +++ b/scripts/license_scanner/license_scanner.py @@ -6,6 +6,7 @@ # import argparse +from collections import OrderedDict import fnmatch import json import os @@ -24,15 +25,19 @@ class LicenseScanner: """ DEFAULT_CONFIG_FILE = 'scanner_config.json' + DEFAULT_EXCLUDE_FILE = '.gitignore' + DEFAULT_PACKAGE_INFO_FILE = 'PackageInfo.json' def __init__(self, config_file=None): self.config_file = config_file self.config_data = self._load_config() - self.license_regex = self._load_license_regex() + self.file_regex = self._load_file_regex(self.config_data['license_patterns']) + self.package_info = self._load_file_regex(self.config_data['package_patterns']) + self.excluded_directories = self._load_file_regex(self.config_data['excluded_directories']) def _load_config(self): """Load config from the provided file. Sets default file if one is not provided.""" - if self.config_file is None: + if not self.config_file: script_directory = os.path.dirname(os.path.abspath(__file__)) # Default file expected in same dir as script self.config_file = os.path.join(script_directory, self.DEFAULT_CONFIG_FILE) @@ -43,45 +48,68 @@ class LicenseScanner: print('Config file cannot be found') raise - def _load_license_regex(self): + def _load_file_regex(self, patterns): """Returns regex object with case-insensitive matching from the list of filename patterns.""" regex_patterns = [] - for pattern in self.config_data['license_patterns']: + for pattern in patterns: regex_patterns.append(fnmatch.translate(pattern)) + + if not regex_patterns: + print(f'Warning: No patterns from {patterns} found') + return None + return re.compile('|'.join(regex_patterns), re.IGNORECASE) - def scan(self, path=os.curdir): - """Scan directory tree for filenames matching license_regex. + def scan(self, paths=os.curdir): + """Scan directory tree for filenames matching file_regex, package info, and exclusion files. - :param path: Path of the directory to run scanner - :return: Package paths and their corresponding license file contents - :rtype: dict + :param paths: Paths of the directory to run scanner + :return: Package paths and their corresponding file contents + :rtype: Ordered dict """ - licenses = 0 - license_files = {} + files = 0 + matching_files = OrderedDict() + excluded_directories = None - for dirpath, dirnames, filenames in os.walk(path): - for file in filenames: - if self.license_regex.match(file): - license_file_content = self._get_license_file_contents(os.path.join(dirpath, file)) - rel_dirpath = os.path.relpath(dirpath, path) # Limit path inside scanned directory - license_files[rel_dirpath] = license_file_content - licenses += 1 - print(f'License file: {os.path.join(dirpath, file)}') + if not self.package_info: + self.package_info = self.DEFAULT_PACKAGE_INFO_FILE - # Remove directories that should not be scanned - for dir in self.config_data['excluded_directories']: - if dir in dirnames: - dirnames.remove(dir) - print(f'{licenses} license files found.') - return license_files + if not self.excluded_directories: + print(f'No excluded directory in config, looking for {self.DEFAULT_EXCLUDE_FILE} instead') - def _get_license_file_contents(self, filepath): + for path in paths: + for dirpath, dirnames, filenames in os.walk(path, topdown=True): + dirnames.sort(key=str.casefold) # Ensure that results are sorted + for file in filenames: + if self.file_regex.match(file) or self.package_info.match(file): + file_path = os.path.join(dirpath, file) + matching_file_content = self._get_file_contents(file_path) + matching_files[file_path] = matching_file_content + files += 1 + print(f'Matching file: {file_path}') + if self.package_info.match(file): + dirnames[:] = [] # Stop scanning subdirectories if package info file found + if self.DEFAULT_EXCLUDE_FILE in file and not self.excluded_directories: + ignore_list = self._get_file_contents(os.path.join(dirpath, file)).splitlines() + ignore_list.append('.git') # .gitignore doesn't usually have .git in its exclusions + excluded_directories = self._load_file_regex(ignore_list) + + # Remove directories that should not be scanned + if self.excluded_directories: + excluded_directories = self.excluded_directories + for dir in dirnames: + if excluded_directories.match(dir): + dirnames.remove(dir) + + print(f'{files} files found.') + return matching_files + + def _get_file_contents(self, filepath): try: with open(filepath, encoding='utf8') as f: return f.read() except UnicodeDecodeError: - print(f'Unable to read license file: {filepath}') + print(f'Unable to read file: {filepath}') pass def create_license_file(self, licenses, filepath='NOTICES.txt'): @@ -89,18 +117,44 @@ class LicenseScanner: :param licenses: Dict with package paths and their corresponding license file contents :param filepath: Path to write the file - """ - package_separator = '------------------------------------' - with open(filepath, 'w', encoding='utf8') as f: + """ + license_separator = '------------------------------------' + with open(filepath, 'w', encoding='utf8') as lf: for directory, license in licenses.items(): - license_output = '\n\n'.join([ - f'{package_separator}', - f'Package path: {directory}', - 'License:', - f'{license}\n' - ]) - f.write(license_output) + if not self.package_info.match(os.path.basename(directory)): + license_output = '\n\n'.join([ + f'{license_separator}', + f'Package path: {os.path.relpath(directory)}', + 'License:', + f'{license}\n' + ]) + lf.write(license_output) return None + + def create_package_file(self, packages, filepath='SPDX-Licenses.json', get_contents=False): + """Creates file with all the provided SPDX package info summaries in json. + Optional dirpath parameter will follow the license file path in the package info and return its contents in a dictionary + + :param licenses: Dict with package info paths and their corresponding file contents + :param filepath: Path to write the file + :param dirpath: Root path for packages + :rtype: Ordered dict + """ + licenses = OrderedDict() + package_json = [] + + with open(filepath, 'w', encoding='utf8') as pf: + for directory, package in packages.items(): + if self.package_info.match(os.path.basename(directory)): + package_obj = json.loads(package) + package_json.append(package_obj) + if get_contents: + license_path = os.path.join(os.path.dirname(directory), pathlib.Path(package_obj['LicenseFile'])) + licenses[license_path] = self._get_file_contents(license_path) + else: + licenses[directory] = package + pf.write(json.dumps(package_json, indent=4)) + return licenses def parse_args(): @@ -108,7 +162,8 @@ def parse_args(): description='Script to run LicenseScanner and generate license file') parser.add_argument('--config-file', '-c', type=pathlib.Path, help='Config file for LicenseScanner') parser.add_argument('--license-file-path', '-l', type=pathlib.Path, help='Create license file in the provided path') - parser.add_argument('--scan-path', '-s', default=os.curdir, type=pathlib.Path, help='Path to scan') + parser.add_argument('--package-file-path', '-p', type=pathlib.Path, help='Create package summary file in the provided path') + parser.add_argument('--scan-path', '-s', default=os.curdir, type=pathlib.Path, nargs='+', help='Path to scan, multiple space separated paths can be used') return parser.parse_args() @@ -116,10 +171,15 @@ def main(): try: args = parse_args() ls = LicenseScanner(args.config_file) - licenses = ls.scan(args.scan_path) + scanned_path_data = ls.scan(args.scan_path) if args.license_file_path: - ls.create_license_file(licenses, args.license_file_path) + ls.create_license_file(scanned_path_data, args.license_file_path) + if args.package_file_path: + ls.create_package_file(scanned_path_data, args.package_file_path) + if args.license_file_path and args.package_file_path: + license_files = ls.create_package_file(scanned_path_data, args.package_file_path, True) + ls.create_license_file(license_files, args.license_file_path) except FileNotFoundError as e: print(f'Type: {type(e).__name__}, Error: {e}') return 1 diff --git a/scripts/license_scanner/scanner_config.json b/scripts/license_scanner/scanner_config.json index b5863a7d31..2e8f5206db 100644 --- a/scripts/license_scanner/scanner_config.json +++ b/scripts/license_scanner/scanner_config.json @@ -8,5 +8,8 @@ "license_patterns": [ "LICENSE*", "COPYING*" + ], + "package_patterns": [ + "PackageInfo.json" ] }