Browse Source

Lyn 17149: Move Asset Bundler Batch Tests to the Temp Workspace. (#14063)

* Updating Asset Bundler tests to the temp workspace.
Moved the temp project cache location within the temp project folder.
Updated tests that would fail due to updated temp project cache location.

Signed-off-by: Rosario Cox <[email protected]>

* Adding skip reason and linking GHI issue.

Signed-off-by: Rosario Cox <[email protected]>

* Fixing typos and adding missing doc strings.

Signed-off-by: Rosario Cox <[email protected]>

* Added missing cache fix to pythonassetbuildertests

Signed-off-by: Rosario Cox <[email protected]>

Signed-off-by: Rosario Cox <[email protected]>
LesaelR 2 years ago
parent
commit
cd245b9af5
42 changed files with 1597 additions and 331 deletions
  1. 3 0
      AutomatedTesting/Gem/AssetProcessorGemConfig.setreg
  2. 1 1
      AutomatedTesting/Gem/PythonTests/assetpipeline/ap_fixtures/ap_config_backup_fixture.py
  3. 143 100
      AutomatedTesting/Gem/PythonTests/assetpipeline/ap_fixtures/bundler_batch_setup_fixture.py
  4. 43 0
      AutomatedTesting/Gem/PythonTests/assetpipeline/asset_bundler_tests/CMakeLists.txt
  5. 7 0
      AutomatedTesting/Gem/PythonTests/assetpipeline/asset_bundler_tests/__init__.py
  6. 213 190
      AutomatedTesting/Gem/PythonTests/assetpipeline/asset_bundler_tests/asset_bundler_batch_tests.py
  7. 547 0
      AutomatedTesting/Gem/PythonTests/assetpipeline/asset_bundler_tests/assets/Levels/TestDependenciesLevel/TestDependenciesLevel.prefab
  8. 12 0
      AutomatedTesting/Gem/PythonTests/assetpipeline/asset_bundler_tests/assets/Levels/TestDependenciesLevel/tags.txt
  9. 3 0
      AutomatedTesting/Gem/PythonTests/assetpipeline/asset_bundler_tests/assets/SeedWithDependencies/AMA_Green_01.tif
  10. 3 0
      AutomatedTesting/Gem/PythonTests/assetpipeline/asset_bundler_tests/assets/SeedWithDependencies/AMA_Grey_01.tif
  11. 3 0
      AutomatedTesting/Gem/PythonTests/assetpipeline/asset_bundler_tests/assets/SeedWithDependencies/AMA_White_01.tif
  12. 564 0
      AutomatedTesting/Gem/PythonTests/assetpipeline/asset_bundler_tests/assets/SeedWithDependencies/Canvas1.uicanvas
  13. 3 0
      AutomatedTesting/Gem/PythonTests/assetpipeline/asset_bundler_tests/assets/SeedWithDependencies/default1024.font
  14. 3 0
      AutomatedTesting/Gem/PythonTests/assetpipeline/asset_bundler_tests/assets/SeedWithDependencies/default2048.font
  15. 1 0
      AutomatedTesting/Gem/PythonTests/assetpipeline/asset_bundler_tests/assets/TestAssets/multiple_corrupted_prefab/corrupted_prefab1.prefab
  16. 1 0
      AutomatedTesting/Gem/PythonTests/assetpipeline/asset_bundler_tests/assets/TestAssets/multiple_corrupted_prefab/corrupted_prefab2.prefab
  17. 1 0
      AutomatedTesting/Gem/PythonTests/assetpipeline/asset_bundler_tests/assets/TestAssets/multiple_working_prefab/working_prefab1.prefab
  18. 1 0
      AutomatedTesting/Gem/PythonTests/assetpipeline/asset_bundler_tests/assets/TestAssets/multiple_working_prefab/working_prefab2.prefab
  19. 1 0
      AutomatedTesting/Gem/PythonTests/assetpipeline/asset_bundler_tests/assets/TestAssets/single_corrupted_prefab/corrupted_prefab.prefab
  20. 1 0
      AutomatedTesting/Gem/PythonTests/assetpipeline/asset_bundler_tests/assets/TestAssets/single_working_prefab/working_prefab.prefab
  21. 1 0
      AutomatedTesting/Gem/PythonTests/assetpipeline/asset_bundler_tests/assets/TestAssets/single_working_prefab_override/working_prefab.prefab
  22. 3 0
      AutomatedTesting/Gem/PythonTests/assetpipeline/asset_bundler_tests/assets/asset_bundler_test_assets/datfile_0.dat
  23. 3 0
      AutomatedTesting/Gem/PythonTests/assetpipeline/asset_bundler_tests/assets/asset_bundler_test_assets/datfile_1.dat
  24. 3 0
      AutomatedTesting/Gem/PythonTests/assetpipeline/asset_bundler_tests/assets/asset_bundler_test_assets/datfile_2.dat
  25. 3 0
      AutomatedTesting/Gem/PythonTests/assetpipeline/asset_bundler_tests/assets/asset_bundler_test_assets/datfile_3.dat
  26. 3 0
      AutomatedTesting/Gem/PythonTests/assetpipeline/asset_bundler_tests/assets/asset_bundler_test_assets/datfile_4.dat
  27. 3 0
      AutomatedTesting/Gem/PythonTests/assetpipeline/asset_bundler_tests/assets/asset_bundler_test_assets/datfile_5.dat
  28. 1 0
      AutomatedTesting/Gem/PythonTests/assetpipeline/asset_bundler_tests/assets/asset_bundler_test_assets/txtfile_0.txt
  29. 1 0
      AutomatedTesting/Gem/PythonTests/assetpipeline/asset_bundler_tests/assets/asset_bundler_test_assets/txtfile_1.txt
  30. 1 0
      AutomatedTesting/Gem/PythonTests/assetpipeline/asset_bundler_tests/assets/asset_bundler_test_assets/txtfile_2.txt
  31. 1 0
      AutomatedTesting/Gem/PythonTests/assetpipeline/asset_bundler_tests/assets/asset_bundler_test_assets/txtfile_3.txt
  32. 1 0
      AutomatedTesting/Gem/PythonTests/assetpipeline/asset_bundler_tests/assets/asset_bundler_test_assets/txtfile_4.txt
  33. 1 0
      AutomatedTesting/Gem/PythonTests/assetpipeline/asset_bundler_tests/assets/asset_bundler_test_assets/txtfile_5.txt
  34. 0 0
      AutomatedTesting/Gem/PythonTests/assetpipeline/asset_bundler_tests/bundle_mode_in_editor_tests.py
  35. 4 0
      AutomatedTesting/Gem/PythonTests/assetpipeline/asset_bundler_tests/bundle_mode_tests.py
  36. 0 0
      AutomatedTesting/Gem/PythonTests/assetpipeline/asset_bundler_tests/conftest.py
  37. 0 22
      AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/CMakeLists.txt
  38. 1 1
      AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/asset_processor_gui_tests_2.py
  39. 1 1
      AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/missing_dependency_tests.py
  40. 2 2
      AutomatedTesting/Gem/PythonTests/assetpipeline/fbx_tests/fbx_tests.py
  41. 7 11
      AutomatedTesting/Gem/PythonTests/assetpipeline/fbx_tests/pythonassetbuildertests.py
  42. 3 3
      Tools/LyTestTools/ly_test_tools/o3de/asset_processor.py

+ 3 - 0
AutomatedTesting/Gem/AssetProcessorGemConfig.setreg

@@ -17,6 +17,9 @@
                 "Exclude Restricted AssetProcessorTestAssets": {
                     "glob": "*/asset_processor_tests/restricted/*"
                 },
+                "Exclude AssetBundlerTestAssets": {
+                    "glob": "*/asset_bundler_tests/assets/*"
+                },
                 "Exclude Scene Tests": {
                     "glob": "*/scene_tests/assets/*"
                 }

+ 1 - 1
AutomatedTesting/Gem/PythonTests/assetpipeline/ap_fixtures/ap_config_backup_fixture.py

@@ -4,7 +4,7 @@ For complete copyright and license terms please see the LICENSE at the root of t
 
 SPDX-License-Identifier: Apache-2.0 OR MIT
 
-Fixture for backing up and restoring dev/AssetProcessorPlatformConfig.ini
+Fixture for backing up and restoring <EngineRoot>\Registry\AssetProcessorPlatformConfig.setreg
 
 """
 

+ 143 - 100
AutomatedTesting/Gem/PythonTests/assetpipeline/ap_fixtures/bundler_batch_setup_fixture.py

@@ -17,9 +17,10 @@ import logging
 import zipfile
 from typing import Any, Dict, List
 
-from . import asset_processor_fixture as asset_processor
-from . import timeout_option_fixture as timeout
-from . import ap_config_backup_fixture as config_backup
+from assetpipeline.ap_fixtures.asset_processor_fixture import asset_processor
+from assetpipeline.ap_fixtures.timeout_option_fixture import timeout_option_fixture as timeout
+from assetpipeline.ap_fixtures.ap_config_backup_fixture import ap_config_backup_fixture as config_backup
+from assetpipeline.ap_fixtures.ap_setup_fixture import ap_setup_fixture
 
 import ly_test_tools.environment.file_system as fs
 import ly_test_tools.o3de.pipeline_utils as utils
@@ -30,67 +31,102 @@ logger = logging.getLogger(__name__)
 
 @pytest.fixture
 @pytest.mark.usefixtures("config_backup")
-def bundler_batch_setup_fixture(request, workspace, asset_processor, timeout) -> Any:
-
-    ALL_PLATFORMS = []
-    for _, value in ASSET_PROCESSOR_PLATFORM_MAP.items():
-        ALL_PLATFORMS.append(value)
-
-    # Set up temporary directory to use for tests
-    tempDir = os.path.join(TF.gettempdir(), "AssetBundlerTempDirectory")
-    if os.path.exists(tempDir):
-        fs.delete([tempDir], True, True)
-    if not os.path.exists(tempDir):
-        os.mkdir(tempDir)
-
-    # Get platforms to build for bundle tests
-    platforms = request.config.getoption("--bundle_platforms")
-    if platforms is not None:
-        # Remove whitespace and split at commas if platforms provided
-        platforms = [platform.strip() for platform in platforms.split(",")]
-    else:
-        # No commandline argument provided, default to mac and pc
-        platforms = ["pc", "mac"]
-
-    class BundlerBatchFixture:
[email protected]("asset_processor")
[email protected]("ap_setup_fixture")
+def bundler_batch_setup_fixture(request, workspace, ap_setup_fixture, asset_processor, timeout) -> Any:
+
+    def get_all_platforms() -> list[str]:
+        """Helper: This function generates a list of all platforms to be built for testing Asset Bundler."""
+        ALL_PLATFORMS = []
+        for _, value in ASSET_PROCESSOR_PLATFORM_MAP.items():
+            ALL_PLATFORMS.append(value)
+        return ALL_PLATFORMS
+
+    def platforms_to_build() -> list | list[str]:
+        """Helper: Gets the platforms to build for bundle tests."""
+        platforms = request.config.getoption("--bundle_platforms")
+        if platforms is not None:
+            # Remove whitespace and split at commas if platforms provided
+            platforms = [platform.strip() for platform in platforms.split(",")]
+        else:
+            # No commandline argument provided, default to mac and pc
+            platforms = ["pc", "mac"]
+        return platforms
+
+    def setup_temp_workspace() -> None:
+        """Helper: Sets up the temp workspace for asset bundling tests."""
+        asset_processor.create_temp_asset_root()
+
+    def setup_temp_dir() -> Any:
+        """Helper: Sets up a temp directory for use in bundling tests that can't use the temp workspace."""
+        tempDir = os.path.join(TF.gettempdir(), "AssetBundlerTempDirectory")
+        if os.path.exists(tempDir):
+            fs.delete([tempDir], True, True)
+        if not os.path.exists(tempDir):
+            os.mkdir(tempDir)
+        return tempDir
+
+    class WorkSpaceBundlerBatchFixture:
         """
         Houses useful variables and functions for running Asset Bundler Batch Tests
         """
-
         def __init__(self):
             self.bin_dir = workspace.paths.build_directory()
             self.bundler_batch = os.path.join(self.bin_dir, "AssetBundlerBatch")
-            self.test_dir = tempDir
-            self.asset_alias = workspace.paths.platform_cache()
-            self.tools_dir = os.path.join(workspace.paths.engine_root(), "Tools")
             self.seed_list_file_name = "testSeedListFile.seed"
-            self.seed_list_file = os.path.join(self.test_dir, self.seed_list_file_name)
             self.asset_info_file_name = "assetFileInfo.assetlist"
-            self.asset_info_file_request = os.path.join(self.test_dir, self.asset_info_file_name)
-            self.bundle_settings_file_request = os.path.join(self.test_dir, "bundleSettingsFile.bundlesettings")
             self.bundle_file_name = "bundle.pak"
-            self.bundle_file = os.path.join(self.test_dir, self.bundle_file_name)
-            self.asset_info_file_result = os.path.join(
-                self.test_dir, self.platform_file_name(self.asset_info_file_name,
-                                                       workspace.asset_processor_platform)
-            )
-            self.bundle_settings_file_result = os.path.join(
-                self.test_dir, self.platform_file_name("bundleSettingsFile.bundlesettings",
-                                                       workspace.asset_processor_platform)
-            )
+            self.bundle_settings_file_name = "bundleSettingsFile.bundlesettings"
+            self.workspace = workspace
+            self.platforms = platforms_to_build()
+            self.platforms_as_string = ",".join(self.platforms)
+
             # Useful sizes
             self.max_bundle_size_in_mib = 35
             self.number_of_bytes_in_mib = 1024 * 1024
-            self.workspace = workspace
-            self.platforms = platforms
-            self.platforms_as_string = ",".join(platforms)
-
-        # *** Bundler-batch-calling helpers ***
 
-        def call_asset_bundler(self, arg_list):                 
-            # Print out the call to asset bundler, so if an error occurs, the commands that were run can be repeated.
-            # Split out the list to something that can be easily copy and pasted. Printing a list by default will put it in,
-            # [comma, separated, braces], this join will instead print each arg in the list with only a space between them.
+            # Checks whether or not the fixture was parametrized to use the temp workspace. Defaults to True.
+            self.use_temp_workspace = request.param if hasattr(request, "param") else True
+
+            if self.use_temp_workspace:
+                setup_temp_workspace()
+                self.project_path = os.path.join(asset_processor.temp_asset_root(), workspace.project)
+                self.cache = asset_processor.temp_project_cache_path()
+                self.seed_list_file = os.path.join(self.project_path, self.seed_list_file_name)
+                self.asset_info_file_request = os.path.join(self.project_path, self.asset_info_file_name)
+                self.bundle_settings_file_request = os.path.join(self.project_path, self.bundle_settings_file_name)
+                self.bundle_file = os.path.join(self.project_path, self.bundle_file_name)
+                self.asset_info_file_result = os.path.join(
+                    self.project_path, self.platform_file_name(self.asset_info_file_name,
+                                                               workspace.asset_processor_platform)
+                )
+                self.bundle_settings_file_result = os.path.join(
+                    self.project_path, self.platform_file_name(self.bundle_settings_file_name,
+                                                               workspace.asset_processor_platform)
+                )
+
+            else:
+                self.project_path = workspace.paths.project()
+                self.cache = workspace.paths.project_cache()
+                self.test_dir = setup_temp_dir()
+                self.seed_list_file = os.path.join(self.test_dir, self.seed_list_file_name)
+                self.asset_info_file_request = os.path.join(self.test_dir, self.asset_info_file_name)
+                self.bundle_settings_file_request = os.path.join(self.test_dir, self.bundle_settings_file_name)
+                self.bundle_file = os.path.join(self.test_dir, self.bundle_file_name)
+                self.asset_info_file_result = os.path.join(
+                    self.test_dir, self.platform_file_name(self.asset_info_file_name,
+                                                           workspace.asset_processor_platform)
+                )
+                self.bundle_settings_file_result = os.path.join(
+                    self.test_dir, self.platform_file_name(self.bundle_settings_file_name,
+                                                           workspace.asset_processor_platform)
+                )
+
+        @staticmethod
+        def call_asset_bundler(arg_list):
+            """
+            Prints out the call to asset bundler, so if an error occurs, the commands that were run can be repeated.
+            """
             logger.info(f"{' '.join(f'arg_list{x}' for x in arg_list)}")
             try:
                 output = subprocess.check_output(arg_list).decode()
@@ -103,48 +139,48 @@ def bundler_batch_setup_fixture(request, workspace, asset_processor, timeout) ->
                 logger.error(f"File Not Found - Failed to call AssetBundlerBatch with args {arg_list} with error {e}")
                 raise e
 
-        def call_bundlerbatch(self, **kwargs: Dict[str, str]):
+        def call_bundlerbatch(self, **kwargs: Dict[str, str]) -> tuple[bool, str] | tuple[bool, Any]:
             """Helper function for calling assetbundlerbatch with no sub-command"""
             cmd = [self.bundler_batch]
             return self.call_asset_bundler(self._append_arguments(cmd, kwargs))
 
-        def call_seeds(self, **kwargs: Dict[str, str]) -> None:
+        def call_seeds(self, **kwargs: Dict[str, str]) -> tuple[bool, str] | tuple[bool, Any]:
             """Helper function for calling assetbundlerbatch with 'seeds' sub-command"""
 
             cmd = [self.bundler_batch, "seeds"]
             return self.call_asset_bundler(self._append_arguments(cmd, kwargs))
 
-        def call_assetLists(self, **kwargs: Dict) -> None:
+        def call_assetLists(self, **kwargs: Dict) -> tuple[bool, str] | tuple[bool, Any]:
             """Helper function for calling assetbundlerbatch with 'assetLists' sub-command"""
 
             cmd = [self.bundler_batch, "assetLists"]
             return self.call_asset_bundler(self._append_arguments(cmd, kwargs))
 
-        def call_comparisonRules(self, **kwargs: Dict) -> None:
+        def call_comparisonRules(self, **kwargs: Dict) -> tuple[bool, str] | tuple[bool, Any]:
             """Helper function for calling assetbundlerbatch with 'comparisonRules' sub-command"""
 
             cmd = [self.bundler_batch, "comparisonRules"]
             return self.call_asset_bundler(self._append_arguments(cmd, kwargs))
 
-        def call_compare(self, **kwargs: Dict) -> None:
+        def call_compare(self, **kwargs: Dict) -> tuple[bool, str] | tuple[bool, Any]:
             """Helper function for calling assetbundlerbatch with 'compare' sub-command"""
 
             cmd = [self.bundler_batch, "compare"]
             return self.call_asset_bundler(self._append_arguments(cmd, kwargs))
 
-        def call_bundleSettings(self, **kwargs: Dict) -> None:
+        def call_bundleSettings(self, **kwargs: Dict) -> tuple[bool, str] | tuple[bool, Any]:
             """Helper function for calling assetbundlerbatch with 'bundleSettings' sub-command"""
 
             cmd = [self.bundler_batch, "bundleSettings"]
             return self.call_asset_bundler(self._append_arguments(cmd, kwargs))
 
-        def call_bundles(self, **kwargs: Dict) -> None:
+        def call_bundles(self, **kwargs: Dict) -> tuple[bool, str] | tuple[bool, Any]:
             """Helper function for calling assetbundlerbatch with 'bundles' sub-command"""
 
             cmd = [self.bundler_batch, "bundles"]
             return self.call_asset_bundler(self._append_arguments(cmd, kwargs))
 
-        def call_bundleSeed(self, **kwargs: Dict) -> None:
+        def call_bundleSeed(self, **kwargs: Dict) -> tuple[bool, str] | tuple[bool, Any]:
             """Helper function for calling assetbundlerbatch with 'bundleSeed' sub-command"""
 
             cmd = [self.bundler_batch, "bundleSeed"]
@@ -153,17 +189,22 @@ def bundler_batch_setup_fixture(request, workspace, asset_processor, timeout) ->
         def _append_arguments(self, cmd: List[str], kwargs: Dict, append_defaults: bool = True) -> List[str]:
             """Appends and returns all keyword arguments to the list of string [cmd]"""
             for key, value in kwargs.items():
-                if value:
-                    cmd.append(f"--{key}={value}")
-                else:
+                if not value:
                     cmd.append(f"--{key}")
+
+                else:
+                    if type(value) != list:
+                        cmd.append(f"--{key}={value}")
+                    else:
+                        for item in value:
+                            cmd.append(f"--{key}={item}")
+
             if append_defaults:
-                cmd.append(f"--project-path={workspace.paths.project()}")
+                cmd.append(f"--project-path={self.project_path}")
             return cmd
 
-        # ******
-
-        def get_seed_relative_paths(self, seed_file: str) -> str:
+        @staticmethod
+        def get_seed_relative_paths(seed_file: str) -> str:
             """Iterates all asset relative paths in the [seed_file]."""
             assert seed_file.endswith(".seed"), f"file {seed_file} is not a seed file"
             # Get value from all XML nodes who are grandchildren of all Class tags and have
@@ -171,7 +212,8 @@ def bundler_batch_setup_fixture(request, workspace, asset_processor, timeout) ->
             for node in ET.parse(seed_file).getroot().findall(r"./Class/Class/*[@field='pathHint']"):
                 yield node.attrib["value"]
 
-        def get_seed_relative_paths_for_platform(self, seed_file: str, platform_flags : int) -> str:
+        @staticmethod
+        def get_seed_relative_paths_for_platform(seed_file: str, platform_flags: int) -> list[str]:
             """Iterates all asset relative paths in the [seed_file] which match the platform flags"""
             assert seed_file.endswith(".seed"), f"file {seed_file} is not a seed file"
             # Get value from all XML nodes who are grandchildren of all Class tags and have
@@ -182,30 +224,32 @@ def bundler_batch_setup_fixture(request, workspace, asset_processor, timeout) ->
             root = data.getroot()
             seedFileRootNode = root.find("Class")
             for seedFileInfoNode in seedFileRootNode.findall("*"):
-                if (int(seedFileInfoNode.find('./Class[@field="platformFlags"]').attrib["value"]) & platform_flags ):
+                if (int(seedFileInfoNode.find('./Class[@field="platformFlags"]').attrib["value"]) & platform_flags):
                     pathHint = seedFileInfoNode.find('./Class[@field="pathHint"]').attrib["value"]
                     seedFileListContents.append(pathHint)
             return seedFileListContents
 
-        def get_asset_relative_paths(self, asset_list_file: str) -> str:
+        @staticmethod
+        def get_asset_relative_paths(asset_list_file: str) -> str:
             """Iterates all asset relative paths in the [asset_list_file]."""
             assert asset_list_file.endswith(".assetlist"), f"file {asset_list_file} is not an assetlist file"
             # Get value from all XML nodes who are great-grandchildren of all Class tags and have
             # a field attr. equal to "assetRelativePath"
-            # fmt:off
+
             for node in (ET.parse(asset_list_file).getroot().findall(
                     r"./Class/Class/Class/*[@field='assetRelativePath']")):
                 yield node.attrib["value"]
-            # fmt:on
 
-        def get_dependent_bundle_names(self, manifest_file: str) -> str:
+        @staticmethod
+        def get_dependent_bundle_names(manifest_file: str) -> str:
             """Iterates all dependent bundle names in the [manifest_file]"""
             assert manifest_file.endswith(".xml"), f"File {manifest_file} does not have an XML extension"
             # Get value from all XML nodes whose parent field attr. is "DependentBundleNames" and whose tag is Class
             for node in ET.parse(manifest_file).getroot().findall(r".//*[@field='DependentBundleNames']/Class"):
                 yield node.attrib["value"]
 
-        def platform_file_name(self, file_name: str, platform: str) -> str:
+        @staticmethod
+        def platform_file_name(file_name: str, platform: str) -> str:
             """Converts the standard [file_name] to a platform specific file name"""
             split = file_name.split(".", 1)
             platform_name = ASSET_PROCESSOR_PLATFORM_MAP.get(platform)
@@ -214,14 +258,16 @@ def bundler_batch_setup_fixture(request, workspace, asset_processor, timeout) ->
                 return file_name
             return f'{split[0]}_{platform_name}.{split[1]}'
 
-        def extract_file_content(self, bundle_file: str, file_name_to_extract: str) -> str:
-            """Extract the contents of a single file from a bundle"""
+        @staticmethod
+        def extract_file_content(bundle_file: str, file_name_to_extract: str) -> bytes:
+            """Extract the contents of a single file from a bundle as a ByteString."""
 
             with zipfile.ZipFile(bundle_file) as bundle_zip:
                 with bundle_zip.open(file_name_to_extract, "r") as extracted_file:
                     return extracted_file.read()
 
-        def get_crc_of_files_in_archive(self, archive_name: str) -> Dict[str, int]:
+        @staticmethod
+        def get_crc_of_files_in_archive(archive_name: str) -> Dict[str, int]:
             """
             Extracts the CRC-32 'checksum' for all files in the archive as dictionary.
             The returned dictionary will have:
@@ -234,17 +280,20 @@ def bundler_batch_setup_fixture(request, workspace, asset_processor, timeout) ->
                 file_crcs[info.filename] = info.CRC
             return file_crcs
 
-        def get_platform_flag(self, platform_name: str) -> int:
-            if (platform_name == "pc"):
-                return 1
-            elif (platform_name == "android"):
-                return 2
-            elif (platform_name == "ios"):
-                return 4
-            elif (platform_name == "mac"):
-                return 8
-            elif (platform_name == "server"):
-                return 128
+        @staticmethod
+        def get_platform_flag(platform_name: str) -> int:
+            """ Helper to fetch the platform flag from a provided platform name. """
+            platform_flags = {
+                "pc": 1,
+                "android": 2,
+                "ios": 4,
+                "mac": 8,
+                "server": 128
+            }
+            if platform_name in platform_flags:
+                return platform_flags.get(platform_name)
+            raise ValueError(f"{platform_name} not found within expected platform flags. "
+                             f"Expected: {platform_flags.keys()}")
 
         def extract_and_check(self, extract_dir: str, bundle_file: str) -> None:
             """
@@ -287,7 +336,8 @@ def bundler_batch_setup_fixture(request, workspace, asset_processor, timeout) ->
             # Ensure that all assets were present in the bundles
             assert sorted(assets_from_file) == sorted(assets_in_disk)
 
-        def _get_platform_flags(self) -> Dict[str, int]:
+        @staticmethod
+        def _get_platform_flags() -> Dict[str, int]:
             """
             Extract platform numeric values from the file that declares them (PlatformDefaults.h):
             Platform Flags are defined in the C header file, where ORDER MATTERS.
@@ -324,7 +374,10 @@ def bundler_batch_setup_fixture(request, workspace, asset_processor, timeout) ->
 
         def teardown(self) -> None:
             """Destroys the temporary directory used in this test"""
-            fs.delete([self.test_dir], True, True)
+            if self.use_temp_workspace:
+                fs.delete([asset_processor.temp_asset_root()], True, True)
+            else:
+                fs.delete([self.test_dir], True, True)
 
         def __getitem__(self, item: str) -> str:
             """Get Item overload to use the object like a dictionary.
@@ -333,19 +386,9 @@ def bundler_batch_setup_fixture(request, workspace, asset_processor, timeout) ->
 
     # End class BundlerBatchFixture
 
-    bundler_batch_fixture = BundlerBatchFixture()
+    bundler_batch_fixture = WorkSpaceBundlerBatchFixture()
     request.addfinalizer(bundler_batch_fixture.teardown)
 
     bundler_batch_fixture.platform_values = bundler_batch_fixture._get_platform_flags()
 
-    # Enable platforms accepted from command line
-    platforms_list = [platform for platform in platforms if platform in ALL_PLATFORMS]
-
-    # Run a full scan to ENSURE that both caches (pc and osx) are COMPLETELY POPULATED
-    # Needed for asset bundling
-    # fmt:off
-    assert asset_processor.batch_process(fastscan=True, timeout=timeout * len(platforms), platforms=platforms_list), \
-        "AP Batch failed to process in bundler_batch_fixture"
-    # fmt:on
-
     return bundler_batch_fixture  # Return the fixture

+ 43 - 0
AutomatedTesting/Gem/PythonTests/assetpipeline/asset_bundler_tests/CMakeLists.txt

@@ -0,0 +1,43 @@
+#
+# 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
+#
+#
+
+if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS)
+## AP Python Tests ##
+
+## Non-Linux Tests ##
+
+    set(SUPPORTED_PLATFORMS "Windows" "Mac")
+    if (NOT "${PAL_PLATFORM_NAME}" IN_LIST SUPPORTED_PLATFORMS)
+        return()
+    endif()
+
+## Periodic Tests ##
+
+    ly_add_pytest(
+        NAME APTests.AssetBundler
+        PATH ${CMAKE_CURRENT_LIST_DIR}/asset_bundler_batch_tests.py
+        TEST_SERIAL 
+        TEST_SUITE periodic
+        RUNTIME_DEPENDENCIES
+            AZ::AssetProcessor
+            AZ::AssetBundlerBatch
+    )
+
+    ly_add_pytest(
+        NAME APTests.BundleMode
+        PATH ${CMAKE_CURRENT_LIST_DIR}/bundle_mode_tests.py
+        TEST_SERIAL
+        TEST_SUITE periodic
+        RUNTIME_DEPENDENCIES
+            AZ::AssetProcessor
+            AZ::AssetBundlerBatch
+            Legacy::Editor
+            AutomatedTesting.Assets
+    )
+
+endif()

+ 7 - 0
AutomatedTesting/Gem/PythonTests/assetpipeline/asset_bundler_tests/__init__.py

@@ -0,0 +1,7 @@
+#
+# 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
+#
+#

+ 213 - 190
AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/asset_bundler_batch_tests.py → AutomatedTesting/Gem/PythonTests/assetpipeline/asset_bundler_tests/asset_bundler_batch_tests.py

@@ -4,7 +4,7 @@ For complete copyright and license terms please see the LICENSE at the root of t
 
 SPDX-License-Identifier: Apache-2.0 OR MIT
 
-General Asset Bundler Batch Tests
+Asset Bundler Batch Tests that can be run in the temp workspace.
 """
 
 # Import builtin libraries
@@ -25,10 +25,10 @@ from ..ap_fixtures.ap_setup_fixture import ap_setup_fixture as ap_setup_fixture
 from ..ap_fixtures.asset_processor_fixture import asset_processor
 from ..ap_fixtures.timeout_option_fixture import timeout_option_fixture as timeout
 
-# fmt:off
+
 from ..ap_fixtures.bundler_batch_setup_fixture \
     import bundler_batch_setup_fixture as bundler_batch_helper
-# fmt:on
+
 from ..ap_fixtures.ap_config_backup_fixture import ap_config_backup_fixture as config_backup
 
 # Import LyShared
@@ -54,7 +54,7 @@ targetProjects = ["AutomatedTesting"]
 
 @pytest.fixture
 def local_resources(request, workspace, ap_setup_fixture):
-    # Test-level asset folder. Directory contains a subfolder for each test (i.e. C1234567)
+    """ Test-level asset folder. Directory contains a sub-folder for each test (i.e. C1234567) """
     ap_setup_fixture["tests_dir"] = os.path.dirname(os.path.realpath(__file__))
 
 
@@ -67,6 +67,13 @@ class TestsAssetBundlerBatch(object):
     Asset Bundler Batch Tests for all platforms
     """
 
+    @staticmethod
+    def ap_prepare_test_environment(test_folder_name, asset_processor, ap_setup_fixture):
+        """Helper: Prepares the test environment; copies test files to the project in the current root, then runs AP."""
+        asset_processor.prepare_test_environment(ap_setup_fixture["tests_dir"], test_folder_name, use_current_root=True)
+        ap_result, _ = asset_processor.batch_process(platforms="pc,mac")
+        assert ap_result, "Asset Processor failed to process test assets."
+
     @pytest.mark.BAT
     @pytest.mark.assetpipeline
     @pytest.mark.test_case_id("C16877174")
@@ -92,7 +99,7 @@ class TestsAssetBundlerBatch(object):
     @pytest.mark.BAT
     @pytest.mark.assetpipeline
     @pytest.mark.test_case_id("C16877175")
-    def test_GenerateDebugInfo_DoesNotEffectOutputFile(self, workspace, bundler_batch_helper):
+    def test_GenerateDebugInfo_DoesNotEffectOutputFile(self, workspace, asset_processor, ap_setup_fixture, bundler_batch_helper):
         """
         Validates destructive overwriting for asset lists and
         that generating debug information does not affect asset list creation
@@ -106,17 +113,28 @@ class TestsAssetBundlerBatch(object):
         7. Attempt to create a new asset list without debug while allowing overwrites
         8. Verify that file contents of the originally created asset list changed from what was stored in memory
         """
+        # Test Setup:
+        test_folder_name = "asset_bundler_test_assets"
         helper = bundler_batch_helper
-        seed_list = os.path.join(workspace.paths.engine_root(), "Assets", "Engine", "SeedAssetList.seed")  # Engine seed list
-        asset = r"levels\testdependencieslevel\testdependencieslevel.spawnable"
+        self.ap_prepare_test_environment(test_folder_name, asset_processor, ap_setup_fixture)
+        seed_asset = os.path.join(asset_processor.project_test_cache_folder(), "txtfile_0.txt")
+        additional_seed_asset = os.path.join(asset_processor.project_test_cache_folder(), "txtfile_1.txt")
+        # Test Setup Ends
 
-        # Create Asset list
+        #Create a seedlist file to use in the test.
+        helper.call_seeds(
+            seedListFile=helper["seed_list_file"],
+            addSeed=seed_asset,
+            platform="pc"
+        )
+
+        #Create an assetlist using the previously created seedlist
         helper.call_assetLists(
-            seedListFile=seed_list,
-            assetListFile=helper['asset_info_file_request'],
+            seedListFile=helper["seed_list_file"],
+            assetListFile=helper["asset_info_file_request"]
         )
 
-        # Validate file was created
+        # Validate the assetlist file was created
         assert os.path.isfile(helper["asset_info_file_result"])
 
         # Read asset list contents to compare before and after destructive overwrite
@@ -125,30 +143,29 @@ class TestsAssetBundlerBatch(object):
 
         # Make sure destructive overwrite will fail without --allowOverwrites
         # Try overwriting the existing file without --allowOverwrites (should fail)
-        result, _ = helper.call_assetLists(seedListFile=seed_list, addSeed=asset,
-                                           assetListFile=helper["asset_info_file_request"])
+        result, _ = helper.call_assetLists(
+            seedListFile=helper["seed_list_file"],
+            addSeed=additional_seed_asset,
+            assetListFile=helper["asset_info_file_request"]
+        )
         assert result is False, "Destructive overwrite without override DID NOT fail"
 
         # Make sure file contents DID NOT change
-        # fmt:off
         with open(helper["asset_info_file_result"], "r") as asset_list_file:
             assert file_contents == asset_list_file.read(), \
                 "File was changed even though the Destructive overwrite failed without override."
-        # fmt:on
 
         # Create the asset list file without generating debug info (and overwriting existing file)
         helper.call_assetLists(
-            addSeed=asset,
+            addSeed=additional_seed_asset,
             assetListFile=helper["asset_info_file_request"],
             allowOverwrites=""
         )
 
         # Make sure file contents DID change
-        # fmt:off
         with open(helper["asset_info_file_result"], "r") as asset_list_file:
             assert file_contents != asset_list_file.read(), \
                 "File was NOT changed even though the Destructive overwrite was allowed."
-        # fmt:on
 
         # Get list of all files (relative paths) in generated asset list (no debug file created)
         assets_generated_without_debug_info = []
@@ -157,7 +174,7 @@ class TestsAssetBundlerBatch(object):
 
         # Create the asset list file while also generating debug info
         helper.call_assetLists(
-            addSeed=asset,
+            addSeed=additional_seed_asset,
             allowOverwrites="",
             generateDebugFile="",
             assetListFile=helper["asset_info_file_request"]
@@ -176,7 +193,7 @@ class TestsAssetBundlerBatch(object):
     @pytest.mark.assetpipeline
     @pytest.mark.test_case_id("C16877175")
     @pytest.mark.test_case_id("C16877177")
-    def test_BundlesAndBundleSettings_EquivalentOutput(self, workspace, bundler_batch_helper):
+    def test_BundlesAndBundleSettings_EquivalentOutput(self, workspace, asset_processor, ap_setup_fixture, bundler_batch_helper):
         """
         Validates bundle creation both through the 'bundles' and 'bundlesettings'
         subcommands.
@@ -186,31 +203,31 @@ class TestsAssetBundlerBatch(object):
         2. Create a bundle with the asset list and without a bundle settings file
         3. Create a bundle with the asset list and a bundle settings file
         4. Validate calling bundle doesn't perform destructive overwrite without --allowOverwrites
-        5. Calling bundle again with --alowOverwrites performs destructive overwrite
+        5. Calling bundle again with --allowOverwrites performs destructive overwrite
         6. Validate contents of original bundle and overwritten bundle
         """
+        test_folder_name = "asset_bundler_test_assets"
         helper = bundler_batch_helper
+        self.ap_prepare_test_environment(test_folder_name, asset_processor, ap_setup_fixture)
+        seed_asset = os.path.join(asset_processor.project_test_cache_folder(), "txtfile_0.txt")
         seed_list = os.path.join(workspace.paths.engine_root(), "Assets", "Engine", "SeedAssetList.seed")  # Engine seed list
-        asset = r"levels\testdependencieslevel\testdependencieslevel.spawnable"
 
         # Useful bundle locations / names (2 for comparing contents)
-        # fmt:off
         platform_bundle_file_1 = os.path.join(
-            helper["test_dir"],
+            helper["project_path"],
             helper.platform_file_name(helper["bundle_file_name"], workspace.asset_processor_platform))
 
-        second_bundle_file_request = os.path.join(helper["test_dir"], "bundle_2.pak")
+        second_bundle_file_request = os.path.join(helper["project_path"], "bundle_2.pak")
         platform_bundle_file_2 = os.path.join(
-            helper["test_dir"], helper.platform_file_name("bundle_2.pak", workspace.asset_processor_platform))
-        # fmt:on
+            helper["project_path"], helper.platform_file_name("bundle_2.pak", workspace.asset_processor_platform))
 
         # Extraction directories
-        extract_dir_1 = os.path.join(helper["test_dir"], "ExtractDir1")
-        extract_dir_2 = os.path.join(helper["test_dir"], "ExtractDir2")
+        extract_dir_1 = os.path.join(helper["project_path"], "ExtractDir1")
+        extract_dir_2 = os.path.join(helper["project_path"], "ExtractDir2")
 
         # Create asset list to test bundles on
         helper.call_assetLists(
-            addSeed=asset,
+            addSeed=seed_asset,
             seedListFile=seed_list,
             assetListFile=helper["asset_info_file_request"],
         )
@@ -266,8 +283,11 @@ class TestsAssetBundlerBatch(object):
     @pytest.mark.assetpipeline
     @pytest.mark.test_case_id("C16877175")
     @pytest.mark.test_case_id("C16877177")
-    def test_CreateMultiPlatformBundles_ValidContents(self, workspace, bundler_batch_helper):
+    @pytest.mark.skip(reason="https://github.com/o3de/o3de/issues/14062")
+    def test_CreateMultiPlatformBundles_ValidContents(self, workspace, bundler_batch_helper, asset_processor, ap_setup_fixture):
         """
+        Skip reason: O3DE/O3DE#14062 and O3DE/O3DE#14060
+
         Creates bundles using the same asset list and compares that they are created equally. Also
         validates that platform bundles exclude/include an expected file. (excluded for WIN, included for MAC)
 
@@ -281,45 +301,57 @@ class TestsAssetBundlerBatch(object):
         7. Verify that files were generated
         8. Verify original bundle checksums are equal to new bundle checksums
         """
+        # Test Setup Start
+        test_folder_name = "asset_bundler_test_assets"
         helper = bundler_batch_helper
-        # fmt:off
-        assert "pc" in helper["platforms"] and "mac" in helper["platforms"], \
-            "This test requires both PC and MAC platforms to be enabled. " \
-            "Please rerun with commandline option: '--bundle_platforms=pc,mac'"
-        # fmt:on
-
-        # Engine seed list
-        seed_list = os.path.join(workspace.paths.engine_root(), "Assets", "Engine", "SeedAssetList.seed")
-
-        # Useful bundle / asset list locations
+        self.ap_prepare_test_environment(test_folder_name, asset_processor, ap_setup_fixture)
+        seed_assets = [os.path.join(asset_processor.project_test_cache_folder(), seed_file) for seed_file in
+                       os.listdir(asset_processor.project_test_cache_folder())]
+        asset_list = helper["asset_info_file_request"]
+        seed_list = helper["seed_list_file"]
         bundle_dir = os.path.dirname(helper["bundle_file"])
         bundle_files = {}
         duplicate_bundle_files = {}
         for platform in helper["platforms"]:
             bundle_files[platform] = os.path.join(
-                bundle_dir,
-                helper.platform_file_name("bundle.pak", platforms[platform])
-            )
+                bundle_dir, helper.platform_file_name("bundle.pak", platforms[platform]))
             duplicate_bundle_files[platform] = os.path.join(
-                bundle_dir,
-                helper.platform_file_name("duplicateBundle.pak", platforms[platform])
-            )
+                bundle_dir, helper.platform_file_name("duplicateBundle.pak", platforms[platform]))
 
-        duplicate_asset_info_file_request = os.path.join(helper["test_dir"], "duplicateAssetFileInfo.assetlist")
-        duplicate_bundle_file = os.path.join(helper["test_dir"], "duplicateBundle.pak")
+        duplicate_asset_info_file_request = os.path.join(
+            helper["project_path"], "duplicateAssetFileInfo.assetlist")
+        duplicate_bundle_file = os.path.join(
+            helper["project_path"], "duplicateBundle.pak")
+        # Test Setup Ends
+
+        assert "pc" in helper["platforms"] and "mac" in helper["platforms"], \
+            "This test requires both PC and MAC platforms to be enabled. " \
+            "Please rerun with commandline option: '--bundle_platforms=pc,mac'"
 
-        # Create an asset list to work with
+        helper.call_seeds(
+            seedListFile=seed_list,
+            addSeed=seed_assets,
+            platform="pc,mac"
+        )
         helper.call_assetLists(
             seedListFile=seed_list,
-            assetListFile=helper["asset_info_file_request"],
-            platform=helper["platforms_as_string"],
+            assetListFile=asset_list,
+            platform="pc",
+        )
+        helper.call_assetLists(
+            seedListFile=seed_list,
+            assetListFile=asset_list,
+            platform="mac",
         )
-
-        # Create bundles for both pc and mac
         helper.call_bundles(
-            assetListFile=helper["asset_info_file_request"],
+            assetListFile=asset_list,
             outputBundlePath=helper["bundle_file"],
-            platform=helper["platforms_as_string"],
+            platform="pc",
+        )
+        helper.call_bundles(
+            assetListFile=asset_list,
+            outputBundlePath=helper["bundle_file"],
+            platform="mac",
         )
 
         # Ensure that the bundles were created
@@ -327,21 +359,21 @@ class TestsAssetBundlerBatch(object):
             assert os.path.isfile(bundle_file)
 
         # This asset is created both on mac and windows platform
-        file_to_check = b"engineassets/textures/Cubemap/default_level_cubemap.tif"  # [use byte str because file is in binary]
+        file_to_check = b"asset_bundler_test_assets/txtfile_0.txt"  # [use byte str because file is in binary]
 
         # Extract the delta catalog file from pc archive. {file_to_check} SHOULD NOT be present for PC
         file_contents = helper.extract_file_content(bundle_files["pc"], "DeltaCatalog.xml")
-        # fmt:off
+
         assert file_contents.find(file_to_check), \
             f"{file_to_check} was found in DeltaCatalog.xml in pc bundle file {bundle_files['pc']}"
-        # fmt:on
+
 
         # Extract the delta catalog file from mac archive. {file_to_check} SHOULD be present for MAC
         file_contents = helper.extract_file_content(bundle_files["mac"], "DeltaCatalog.xml")
-        # fmt:off
+
         assert file_contents.find(file_to_check), \
             f"{file_to_check} was not found in DeltaCatalog.xml in darwin bundle file {bundle_files['mac']}"
-        # fmt:on
+
 
         # Gather checksums for first set of bundles
         check_sums_before = {}
@@ -367,10 +399,9 @@ class TestsAssetBundlerBatch(object):
         # Make sure all files were created as expected
         for platform in helper["platforms"]:
             assert os.path.isfile(bundle_files[platform]), f"File: {bundle_files[platform]} was not created"
-            # fmt:off
+
             assert os.path.isfile(duplicate_bundle_files[platform]), \
                 f"File: {duplicate_bundle_files[platform]} was not created"
-            # fmt:on
 
         # Get original bundles' contents again
         check_sums_after = {}
@@ -381,17 +412,17 @@ class TestsAssetBundlerBatch(object):
 
         # Make sure original bundles' contents did not change during operation
         for platform in helper["platforms"]:
-            # fmt:off
+
             assert check_sums_before[platform] == check_sums_after[platform], \
                 f"Before and after check sum for {platform} did not match"
             assert check_sums_before[platform] == check_sums_duplicates[platform], \
                 f"Before and duplicated check sum for {platform} did not match"
-            # fmt:on
+
 
     @pytest.mark.BAT
     @pytest.mark.assetpipeline
     @pytest.mark.test_case_id("C16877174")
-    def test_AddAndRemoveSeedPlatform_Success(self, workspace, bundler_batch_helper):
+    def test_AddAndRemoveSeedPlatform_Success(self, workspace, bundler_batch_helper, asset_processor, ap_setup_fixture):
         """
         Validates that the 'seeds' subcommand can add and remove seeds and seed platforms properly.
         Also checks that destructive overwrites require the --allowOverwrites flag
@@ -414,13 +445,15 @@ class TestsAssetBundlerBatch(object):
         14. Remove seed
         15. Validate that seed was removed from the seed list
         """
+        test_folder_name = "asset_bundler_test_assets"
         helper = bundler_batch_helper
+        self.ap_prepare_test_environment(test_folder_name, asset_processor, ap_setup_fixture)
+        seed_asset = os.path.join(asset_processor.project_test_cache_folder(), "txtfile_0.txt")
 
         # Make sure asset list file does not exist entering the test
         if os.path.exists(helper["asset_info_file_request"]):
             fs.delete([helper["asset_info_file_request"]], True, True)
 
-        test_asset = r"fonts/open_sans/license.txt"
         re_pattern = re.compile(r"""field="platformFlags" value="(\d+)" """)
         all_lines = ""
 
@@ -432,10 +465,10 @@ class TestsAssetBundlerBatch(object):
             re_match = re_pattern.search(lines)
             assert re_match, f"PlatformFlags were not found in seed file {seed_file}"
             platform_flag = int(re_match.group(1))
-            # fmt:off
+
             assert platform_flag == expected_platform_flag, \
                 f"Expected platform flag to be {expected_platform_flag}. Actual {platform_flag}"
-            # fmt:on
+
             return lines
 
         # End check_seed_platform()
@@ -443,26 +476,25 @@ class TestsAssetBundlerBatch(object):
         # Create seed list file
         helper.call_seeds(
             seedListFile=helper["seed_list_file"],
-            addSeed=test_asset,
+            addSeed=seed_asset,
             platform="pc",
         )
 
         # Validate file exists and has proper platform flag
         assert os.path.exists(helper["seed_list_file"]), f"seed list file was not created at {helper['seed_list_file']}"
-        check_seed_platform(helper["seed_list_file"], test_asset, helper["platform_values"]["pc"])
+        check_seed_platform(helper["seed_list_file"], seed_asset, helper["platform_values"]["pc"])
 
         # Add Mac and pc as platform for seed
         helper.call_seeds(
             seedListFile=helper["seed_list_file"],
-            addSeed=test_asset,
+            addSeed=seed_asset,
             platform="pc,mac",
         )
 
         # Validate both mac and pc are activated for seed
-        # fmt:off
-        check_seed_platform(helper["seed_list_file"], test_asset,
+
+        check_seed_platform(helper["seed_list_file"], seed_asset,
                             helper["platform_values"]["pc"] + helper["platform_values"]["mac"])
-        # fmt:on
 
         # Remove MAC platform
         helper.call_seeds(
@@ -471,18 +503,17 @@ class TestsAssetBundlerBatch(object):
             platform="mac",
         )
         # Validate only pc platform for seed. Save file contents to variable
-        all_lines = check_seed_platform(helper["seed_list_file"], test_asset, helper["platform_values"]["pc"])
+        all_lines = check_seed_platform(helper["seed_list_file"], seed_asset, helper["platform_values"]["pc"])
 
         result, _ = helper.call_seeds(seedListFile=helper["seed_list_file"], addPlatformToSeeds="", )
 
         assert result is False, "Calling --addPlatformToSeeds did not fail when not specifying the --platform argument"
 
         # Make sure the file contents did not change
-        # fmt:off
+
         with open(helper["seed_list_file"], "r") as asset_list_file:
             assert all_lines == asset_list_file.read(), \
                 "Calling --addPlatformToSeeds without --platform failed but changed the seed file"
-        # fmt:on
 
         # Add MAC platform via --addPlatformToSeeds
         helper.call_seeds(
@@ -491,10 +522,9 @@ class TestsAssetBundlerBatch(object):
             platform="mac",
         )
         # Validate Mac platform was added back on. Save file contents
-        # fmt:off
-        all_lines = check_seed_platform(helper["seed_list_file"], test_asset,
+
+        all_lines = check_seed_platform(helper["seed_list_file"], seed_asset,
                                         helper["platform_values"]["pc"] + helper["platform_values"]["mac"])
-        # fmt:on
 
         # Try to remove platform without specifying a platform to remove (should fail)
         result, _ = helper.call_seeds(seedListFile=helper["seed_list_file"], removePlatformFromSeeds="", )
@@ -502,25 +532,24 @@ class TestsAssetBundlerBatch(object):
         assert result is False, "Calling --removePlatformFromSeeds did not fail when not specifying the --platform argument"
 
         # Make sure file contents did not change
-        # fmt:off
+
         with open(helper["seed_list_file"], "r") as asset_list_file:
             assert all_lines == asset_list_file.read(), \
                 "Calling --removePlatformFromSeeds without --platform failed but changed the seed file"
-        # fmt:on
 
         # Remove the seed
         helper.call_seeds(
             seedListFile=helper["seed_list_file"],
-            removeSeed=test_asset,
+            removeSeed=seed_asset,
             platform="pc,mac",
         )
 
         # Validate seed was removed from file
-        # fmt:off
+
         with open(helper["seed_list_file"], "r") as seed_list_file:
-            assert test_asset not in seed_list_file.read(), \
+            assert seed_asset not in seed_list_file.read(), \
                 f"Seed was not removed from asset list file {helper['seed_list_file']}"
-        # fmt:on
+
 
     @pytest.mark.BAT
     @pytest.mark.assetpipeline
@@ -528,10 +557,10 @@ class TestsAssetBundlerBatch(object):
     @pytest.mark.test_case_id("C16877174")
     @pytest.mark.test_case_id("C16877175")
     @pytest.mark.test_case_id("C16877178")
-    # fmt:off
+
     def test_ComparisonOperations_Success(self, workspace, bundler_batch_helper, ap_setup_fixture,
                                                         asset_processor, timeout):
-        # fmt:on
+
         """
         Tests asset list comparison, both by file and by comparison type. Uses a set
         of controlled test assets to compare resulting output asset lists
@@ -542,14 +571,14 @@ class TestsAssetBundlerBatch(object):
         4. Validate assetlists were created properly
         5. Compare using comparison rules files and just command line arguments
         """
+        test_folder_name = "asset_bundler_test_assets"
         helper = bundler_batch_helper
-        env = ap_setup_fixture
+        self.ap_prepare_test_environment(test_folder_name, asset_processor, ap_setup_fixture)
 
-        # fmt:off
         assert "pc" in helper["platforms"] and "mac" in helper["platforms"], \
             "This test requires both PC and MAC platforms to be enabled. " \
             "Please rerun with commandline option: '--bundle_platforms=pc,mac'"
-        # fmt:on
+
 
         # Test assets arranged in common lists: six (0-5) .txt files and .dat files
         even_txt = ["txtfile_0.txt", "txtfile_2.txt", "txtfile_4.txt"]
@@ -588,26 +617,20 @@ class TestsAssetBundlerBatch(object):
             ("combined.rules", "2,0"),
         ]
 
-        # Get our test assets ready and processed
-        utils.prepare_test_assets(env["tests_dir"], "C16877178", env["project_test_assets_dir"])
-        asset_processor.batch_process(timeout=timeout, fastscan=False, platforms="pc,mac")
-
-        # *** Some helper functions *** #
-
         def create_seed_file(asset_names: List[str], seed_file_name: str) -> None:
-            """Adds the [asset_names] to the seed file [seed_file_name] with their specific platform"""
+            """Helper: Adds the [asset_names] to the seed file [seed_file_name] with their specific platform"""
             for asset_file_name in asset_names:
                 helper.call_seeds(
-                    seedListFile=os.path.join(helper["test_dir"], seed_file_name),
-                    addSeed=os.path.join(env["test_asset_dir_name"], asset_file_name),
+                    seedListFile=os.path.join(helper["project_path"], seed_file_name),
+                    addSeed=os.path.join(asset_processor.project_test_cache_folder(), asset_file_name),
                     platform=file_platforms[asset_file_name],
                 )
 
         def create_asset_list_file(seed_file_name: str, asset_list_file_name: str) -> None:
-            """Simple wrapper for calling the Bundler Batch for a [seed_file_name] and [asset_list_file_name]"""
+            """Helper: Simple wrapper for calling the Bundler Batch for a [seed_file_name] and [asset_list_file_name]"""
             helper.call_assetLists(
-                assetListFile=os.path.join(helper["test_dir"], asset_list_file_name),
-                seedListFile=os.path.join(helper["test_dir"], seed_file_name),
+                assetListFile=os.path.join(helper["project_path"], asset_list_file_name),
+                seedListFile=os.path.join(helper["project_path"], seed_file_name),
                 platform="pc,mac",
             )
 
@@ -625,7 +648,7 @@ class TestsAssetBundlerBatch(object):
         def validate_asset_list(asset_list_file: str, asset_list: List[str]) -> None:
             """Validates that the [asset_list_file] contains exactly the assets in [asset_list]"""
             assets_to_find = list(asset_list)  # Make copy of list. We will be removing elements as we go
-            for rel_path in helper.get_asset_relative_paths(os.path.join(helper["test_dir"], asset_list_file)):
+            for rel_path in helper.get_asset_relative_paths(os.path.join(helper["project_path"], asset_list_file)):
                 asset = os.path.split(rel_path)[1]  # Get just the asset's file name
                 try:
                     assets_to_find.remove(asset)  # Attempt to remove
@@ -684,7 +707,7 @@ class TestsAssetBundlerBatch(object):
                         out += asset_list + ","
                     else:
                         # Get absolute file path
-                        out += os.path.join(helper["test_dir"], asset_list) + ","
+                        out += os.path.join(helper["project_path"], asset_list) + ","
                 return out[:-1]  # Trim off extra comma
 
             # End asset_lists_to_string()
@@ -703,7 +726,7 @@ class TestsAssetBundlerBatch(object):
                 if second_input_arg is not None:
                     cmd.append(f"--secondAssetFile={second_input_arg}")
                 if use_file:
-                    file_name = os.path.join(helper["test_dir"], rule + ".rules")
+                    file_name = os.path.join(helper["project_path"], rule + ".rules")
                     cmd.append("--comparisonRulesFile=" + file_name)
                 else:
                     comp_type = [i for r, i in comparison_files if r.startswith(rule)][0]  # Get comparisonType flag
@@ -717,21 +740,21 @@ class TestsAssetBundlerBatch(object):
             # End generate_compare_command()
 
             def verify_asset_list_contents(expected: str, output_asset_list: str) -> None:
-                # Compare relative paths from inside 'expected' and 'output_asset_list' (last output file from cmd)
+                """Helper: Compare relative paths from inside 'expected' and 'output_asset_list' (last output file from cmd)"""
                 expected_paths = []
                 actual_paths = []
                 for rel_path in helper.get_asset_relative_paths(expected):
                     expected_paths.append(rel_path)
                 for rel_path in helper.get_asset_relative_paths(output_asset_list):
                     actual_paths.append(rel_path)
-                # fmt:off
+
                 assert sorted(expected_paths) == sorted(actual_paths), \
                     "Asset list comparison did not yield expected results"
-                # fmt:on
+
             # End verify_asset_list_contents()
 
             def run_compare_command_and_verify(platform_arg: str, expect_pc_output: bool, expect_mac_output: bool) -> None:
-
+                """Helper: Adds the platform suffixes to each expected output, builds and runs the compare commands. """
                 # Expected asset list to equal result of comparison
                 expected_pc_asset_list = None
                 expected_mac_asset_list = None
@@ -744,12 +767,12 @@ class TestsAssetBundlerBatch(object):
                 last_output_arg = output_arg.split(",")[-1]
                 if expect_pc_output:
                     platform = platforms["pc"]
-                    expected_pc_asset_list = os.path.join(helper["test_dir"], helper.platform_file_name(expected_asset_list, platform))
+                    expected_pc_asset_list = os.path.join(helper["project_path"], helper.platform_file_name(expected_asset_list, platform))
                     output_pc_asset_list = helper.platform_file_name(last_output_arg, platform)
 
                 if expect_mac_output:
                     platform = platforms["mac"]
-                    expected_mac_asset_list = os.path.join(helper["test_dir"], helper.platform_file_name(expected_asset_list, platform))
+                    expected_mac_asset_list = os.path.join(helper["project_path"], helper.platform_file_name(expected_asset_list, platform))
                     output_mac_asset_list = helper.platform_file_name(last_output_arg, platform)
 
                 # Build execution command
@@ -780,7 +803,7 @@ class TestsAssetBundlerBatch(object):
 
         # Create comparison (.rules) files
         for args in comparison_files:
-            rule_file = os.path.join(helper["test_dir"], args[0])
+            rule_file = os.path.join(helper["project_path"], args[0])
             logger.info(f"Creating rule file: {rule_file}")
             cmd = [
                 helper["bundler_batch"],
@@ -871,7 +894,7 @@ class TestsAssetBundlerBatch(object):
     @pytest.mark.assetpipeline
     @pytest.mark.test_case_id("C16877174")
     @pytest.mark.test_case_id("C16877175")
-    def test_AssetListCreation_OutputMatchesResult(self, workspace, bundler_batch_helper):
+    def test_AssetListCreation_OutputMatchesResult(self, workspace, bundler_batch_helper, asset_processor, ap_setup_fixture):
         """
         Tests that assetlists are created equivalent to the output while being created, and
         makes sure overwriting an existing file without the --allowOverwrites fails
@@ -886,17 +909,18 @@ class TestsAssetBundlerBatch(object):
         7. Specifying platform but not "add" or "remove" should fail
         8. Verify file Has changed
         """
+        test_folder_name = "asset_bundler_test_assets"
         helper = bundler_batch_helper
+        self.ap_prepare_test_environment(test_folder_name, asset_processor, ap_setup_fixture)
+        seed_asset = os.path.join(asset_processor.project_test_cache_folder(), "txtfile_0.txt")
 
-        # fmt:off
         assert "pc" in helper["platforms"], \
             "This test requires the PC platform to be enabled. " \
             "Please rerun with commandline option: '--bundle_platforms=pc'"
-        # fmt:on
 
         # Assetlist result file (pc platform)
         al_file_path = os.path.join(
-            helper["test_dir"],
+            helper["project_path"],
             helper.platform_file_name(helper["asset_info_file_name"], platforms["pc"])
         )
         seed_files_pattern = re.compile("Loading Seed List file ( ([^)]*) )")
@@ -925,7 +949,7 @@ class TestsAssetBundlerBatch(object):
         # Create a seed file
         helper.call_seeds(
             seedListFile=helper["seed_list_file"],
-            addSeed=r"levels\testdependencieslevel\testdependencieslevel.spawnable",
+            addSeed=seed_asset,
             platform="pc",
         )
 
@@ -962,10 +986,8 @@ class TestsAssetBundlerBatch(object):
     @pytest.mark.assetpipeline
     @pytest.mark.test_case_id("C16877175")
     @pytest.mark.test_case_id("C16877177")
-    # fmt:off
-    def test_AP_BundleProcessing_BundleProcessedAtRuntime(self, workspace, bundler_batch_helper,
-                                                                        asset_processor, request):
-        # fmt:on
+    def test_AP_BundleProcessing_BundleProcessedAtRuntime(self, workspace, bundler_batch_helper, asset_processor,
+                                                          ap_setup_fixture, request):
         """
         Test to make sure the AP GUI will process a newly created bundle file
 
@@ -977,18 +999,20 @@ class TestsAssetBundlerBatch(object):
         5. Make sure bundle now exists in cache
         """
         # Set up helpers and variables
+        test_folder_name = "asset_bundler_test_assets"
         helper = bundler_batch_helper
+        self.ap_prepare_test_environment(test_folder_name, asset_processor, ap_setup_fixture)
+        seed_asset = os.path.join(asset_processor.project_test_cache_folder(), "txtfile_0.txt")
 
         # Make sure file gets deleted on teardown
         request.addfinalizer(lambda: fs.delete([bundle_result_path], True, False))
 
-        bundles_folder = os.path.join(workspace.paths.project(), "Bundles")
-        level_pak = r"levels\testdependencieslevel\testdependencieslevel.spawnable"
+        bundles_folder = os.path.join(bundler_batch_helper["project_path"], "Bundles")
         bundle_request_path = os.path.join(bundles_folder, "bundle.pak")
         bundle_result_path = os.path.join(bundles_folder,
                                           helper.platform_file_name("bundle.pak", workspace.asset_processor_platform))
 
-        bundle_cache_path = os.path.join(workspace.paths.platform_cache(),
+        bundle_cache_path = os.path.join(asset_processor.temp_project_cache(asset_platform="pc"),
                                          "Bundles",
                                          helper.platform_file_name("bundle.pak", workspace.asset_processor_platform))
 
@@ -1001,7 +1025,7 @@ class TestsAssetBundlerBatch(object):
 
         # Make asset list file (used for bundle creation)
         helper.call_assetLists(
-            addSeed=level_pak,
+            addSeed=seed_asset,
             assetListFile=helper["asset_info_file_request"],
         )
 
@@ -1009,7 +1033,7 @@ class TestsAssetBundlerBatch(object):
         result, _ = asset_processor.gui_process()
         assert result, "AP GUI failed"
 
-        time.sleep(5)
+        asset_processor.wait_for_idle(timeout=5)
 
         # Make bundle in <project_folder>/Bundles
         helper.call_bundles(
@@ -1028,35 +1052,29 @@ class TestsAssetBundlerBatch(object):
 
     @pytest.mark.BAT
     @pytest.mark.assetpipeline
-    # fmt:off
-    def test_FilesMarkedSkip_FilesAreSkipped(self, workspace, bundler_batch_helper):
+    def test_FilesMarkedSkip_FilesAreSkipped(self, workspace, asset_processor, ap_setup_fixture, bundler_batch_helper):
         """
         Test Steps:
         1. Create an asset list with a file marked as skip
         2. Verify file was created
         3. Verify that only the expected assets are present in the created asset list
         """
+        test_folder_name = "SeedWithDependencies"
+        self.ap_prepare_test_environment(test_folder_name, asset_processor, ap_setup_fixture)
+        seed_asset = os.path.join(asset_processor.project_test_cache_folder(), "canvas1.uicanvas")
+
         expected_assets = sorted([
-            "ui/canvases/lyshineexamples/animation/multiplesequences.uicanvas",
-            "ui/textures/prefab/button_disabled.tif.streamingimage",
-            "ui/textures/prefab/tooltip_sliced.tif.streamingimage",
-            "ui/textures/prefab/button_normal.tif.streamingimage"
+            "seedwithdependencies/ama_green_01.tif.streamingimage",
+            "seedwithdependencies/ama_grey_01.tif.streamingimage",
+            "seedwithdependencies/ama_white_01.tif.streamingimage",
+            "seedwithdependencies/canvas1.uicanvas"
         ])
         # Printing these lists out can save a step in debugging if this test fails on Jenkins.
         logger.info(f"expected_assets: {expected_assets}")
 
         skip_assets = sorted([
-            "ui/scripts/lyshineexamples/animation/multiplesequences.luac",
-            "ui/scripts/lyshineexamples/unloadthiscanvasbutton.luac",
-            "fonts/vera.fontfamily",
-            "fonts/vera-italic.font",
-            "fonts/vera.font",
-            "fonts/vera-bold.font",
-            "fonts/vera-bold-italic.font",
-            "fonts/vera-italic.ttf",
-            "fonts/vera.ttf",
-            "fonts/vera-bold.ttf",
-            "fonts/vera-bold-italic.ttf"
+            "seedwithdependencies/default1024.font",
+            "seedwithdependencies/default2048.font"
         ])
         logger.info(f"skip_assets: {skip_assets}")
 
@@ -1068,7 +1086,7 @@ class TestsAssetBundlerBatch(object):
         # the files were actually skipped, and not just missing.
         bundler_batch_helper.call_assetLists(
             assetListFile=bundler_batch_helper['asset_info_file_request'],
-            addSeed="ui/canvases/lyshineexamples/animation/multiplesequences.uicanvas"
+            addSeed=seed_asset
         )
         assert os.path.isfile(bundler_batch_helper["asset_info_file_result"])
         assets_in_no_skip_list = []
@@ -1081,7 +1099,7 @@ class TestsAssetBundlerBatch(object):
         # Now generate an asset info file using the skip command, and verify the skip files are not in the list.
         bundler_batch_helper.call_assetLists(
             assetListFile=bundler_batch_helper['asset_info_file_request'],
-            addSeed="ui/canvases/lyshineexamples/animation/multiplesequences.uicanvas",
+            addSeed=seed_asset,
             allowOverwrites="",
             skip=','.join(skip_assets)
         )
@@ -1094,48 +1112,9 @@ class TestsAssetBundlerBatch(object):
         logger.info(f"assets_in_list: {assets_in_list}")
         assert assets_in_list == expected_assets
 
-
     @pytest.mark.BAT
     @pytest.mark.assetpipeline
-    # fmt:off
-    def test_AssetListSkipOneOfTwoParents_SharedDependencyIsIncluded(self, workspace,
-                                                                                   bundler_batch_helper):
-        """
-        Test Steps:
-        1. Create Asset List with multiple parent assets that are skipped
-        2. Verify that Asset List was created
-        3. Verify that only the expected assets are present in the asset list
-        """
-        expected_assets = [
-            "objects/cube_lod0.azlod",
-            "objects/cube_lod0_index.azbuffer",
-            "resourcepools/defaultvertexbufferpool.pool"
-        ]
-        # Test Asset Structure:
-        #          Grandparent
-        #      /        |        \
-        #   ParentA  ParentB  ParentC
-        #      \        |        /
-        #          CommonChild
-
-        # Even if we exclude all parents besides "ParentA", we should still have "CommonChild" since it is a product dependency of "ParentA"
-        bundler_batch_helper.call_assetLists(
-            assetListFile=bundler_batch_helper['asset_info_file_request'],
-            addSeed="objects/cube_lod0.azlod",
-            skip="objects/cube_lod0_position0.azbuffer, objects/cube_lod0_tangent0.azbuffer,"
-                 "objects/cube_lod0_normal0.azbuffer, objects/cube_lod0_bitangent0.azbuffer,"
-                 "objects/cube_lod0_uv0.azbuffer"
-        )
-        assert os.path.isfile(bundler_batch_helper["asset_info_file_result"])
-        assets_in_list = []
-        for rel_path in bundler_batch_helper.get_asset_relative_paths(bundler_batch_helper["asset_info_file_result"]):
-            assets_in_list.append(rel_path)
-        assert sorted(assets_in_list) == sorted(expected_assets)
-
-    @pytest.mark.BAT
-    @pytest.mark.assetpipeline
-    # fmt:off
-    def test_AssetLists_SkipRoot_ExcludesAll(self, workspace, bundler_batch_helper):
+    def test_AssetLists_SkipRoot_ExcludesAll(self, workspace, asset_processor, ap_setup_fixture, bundler_batch_helper):
         """
         Negative scenario test that skips the same file being used as the parent seed.
 
@@ -1143,6 +1122,9 @@ class TestsAssetBundlerBatch(object):
         1. Create an asset list that skips the root asset
         2. Verify that asset list was not generated
         """
+        test_folder_name = os.path.join(workspace.project, "libs\\particles")
+        asset_processor.add_source_folder_assets(test_folder_name)
+        asset_processor.batch_process()
 
         result, _ = bundler_batch_helper.call_assetLists(
             assetListFile=bundler_batch_helper['asset_info_file_request'],
@@ -1157,8 +1139,8 @@ class TestsAssetBundlerBatch(object):
 
     @pytest.mark.BAT
     @pytest.mark.assetpipeline
-    # fmt:off
-    def test_AssetLists_SkipUniversalWildcard_ExcludesAll(self, workspace, bundler_batch_helper):
+
+    def test_AssetLists_SkipUniversalWildcard_ExcludesAll(self, workspace, asset_processor, ap_setup_fixture, bundler_batch_helper):
         """
         Negative scenario test that uses the all wildcard when generating an asset list.
 
@@ -1166,6 +1148,9 @@ class TestsAssetBundlerBatch(object):
         1. Create an Asset List while using the universal all wildcard "*"
         2. Verify that asset list was not generated
         """
+        test_folder_name = os.path.join(workspace.project, "libs\\particles")
+        asset_processor.add_source_folder_assets(test_folder_name)
+        asset_processor.batch_process()
 
         result, _ = bundler_batch_helper.call_assetLists(
             assetListFile=bundler_batch_helper['asset_info_file_request'],
@@ -1180,7 +1165,6 @@ class TestsAssetBundlerBatch(object):
 
     @pytest.mark.BAT
     @pytest.mark.assetpipeline
-    # fmt:off
     def test_Bundles_InvalidAssetList_ReportsError(self, workspace, bundler_batch_helper):
         """
         Verifies that when the bundles command is used, with an invalid asset list, the command fails and prints a useful error message.
@@ -1201,3 +1185,42 @@ class TestsAssetBundlerBatch(object):
             return
         logger.error("AssetBundlerBatch was expected to fail when given an invalid asset list to bundle, but did not.")
         assert False
+
+    @pytest.mark.BAT
+    @pytest.mark.assetpipeline
+    @pytest.mark.parametrize("bundler_batch_helper", [False], indirect=True)
+    def test_AssetListSkipOneOfTwoParents_SharedDependencyIsIncluded(self, workspace, asset_processor, bundler_batch_helper):
+        """
+        Test Steps:
+        1. Create Asset List with multiple parent assets that are skipped
+        2. Verify that Asset List was created
+        3. Verify that only the expected assets are present in the asset list
+        """
+
+        asset_processor.batch_process()
+        expected_assets = [
+            "objects/cube_lod0.azlod",
+            "objects/cube_lod0_index.azbuffer",
+            "resourcepools/defaultvertexbufferpool.pool"
+        ]
+        # Test Asset Structure:
+        #          Grandparent
+        #      /        |        \
+        #   ParentA  ParentB  ParentC
+        #      \        |        /
+        #          CommonChild
+
+        # Even if we exclude all parents besides "ParentA", we should still have "CommonChild" since it is a product dependency of "ParentA"
+        bundler_batch_helper.call_assetLists(
+            assetListFile=bundler_batch_helper['asset_info_file_request'],
+            addSeed="objects/cube_lod0.azlod",
+            skip="objects/cube_lod0_position0.azbuffer, objects/cube_lod0_tangent0.azbuffer,"
+                 "objects/cube_lod0_normal0.azbuffer, objects/cube_lod0_bitangent0.azbuffer,"
+                 "objects/cube_lod0_uv0.azbuffer"
+        )
+        assert os.path.isfile(bundler_batch_helper["asset_info_file_result"])
+        assets_in_list = []
+        for rel_path in bundler_batch_helper.get_asset_relative_paths(
+                bundler_batch_helper["asset_info_file_result"]):
+            assets_in_list.append(rel_path)
+        assert sorted(assets_in_list) == sorted(expected_assets)

+ 547 - 0
AutomatedTesting/Gem/PythonTests/assetpipeline/asset_bundler_tests/assets/Levels/TestDependenciesLevel/TestDependenciesLevel.prefab

@@ -0,0 +1,547 @@
+{
+    "ContainerEntity": {
+        "Id": "Entity_[1146574390643]",
+        "Name": "Level",
+        "Components": {
+            "Component_[10641544592923449938]": {
+                "$type": "EditorInspectorComponent",
+                "Id": 10641544592923449938
+            },
+            "Component_[12039882709170782873]": {
+                "$type": "EditorOnlyEntityComponent",
+                "Id": 12039882709170782873
+            },
+            "Component_[12265484671603697631]": {
+                "$type": "EditorPendingCompositionComponent",
+                "Id": 12265484671603697631
+            },
+            "Component_[14126657869720434043]": {
+                "$type": "EditorEntitySortComponent",
+                "Id": 14126657869720434043
+            },
+            "Component_[15230859088967841193]": {
+                "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
+                "Id": 15230859088967841193,
+                "Parent Entity": ""
+            },
+            "Component_[16239496886950819870]": {
+                "$type": "EditorDisabledCompositionComponent",
+                "Id": 16239496886950819870
+            },
+            "Component_[5688118765544765547]": {
+                "$type": "EditorEntityIconComponent",
+                "Id": 5688118765544765547
+            },
+            "Component_[6545738857812235305]": {
+                "$type": "SelectionComponent",
+                "Id": 6545738857812235305
+            },
+            "Component_[7247035804068349658]": {
+                "$type": "EditorPrefabComponent",
+                "Id": 7247035804068349658
+            },
+            "Component_[9307224322037797205]": {
+                "$type": "EditorLockComponent",
+                "Id": 9307224322037797205
+            },
+            "Component_[9562516168917670048]": {
+                "$type": "EditorVisibilityComponent",
+                "Id": 9562516168917670048
+            }
+        }
+    },
+    "Entities": {
+        "Entity_[1155164325235]": {
+            "Id": "Entity_[1155164325235]",
+            "Name": "Sun",
+            "Components": {
+                "Component_[10440557478882592717]": {
+                    "$type": "SelectionComponent",
+                    "Id": 10440557478882592717
+                },
+                "Component_[13620450453324765907]": {
+                    "$type": "EditorLockComponent",
+                    "Id": 13620450453324765907
+                },
+                "Component_[2134313378593666258]": {
+                    "$type": "EditorInspectorComponent",
+                    "Id": 2134313378593666258
+                },
+                "Component_[234010807770404186]": {
+                    "$type": "EditorVisibilityComponent",
+                    "Id": 234010807770404186
+                },
+                "Component_[2970359110423865725]": {
+                    "$type": "EditorEntityIconComponent",
+                    "Id": 2970359110423865725
+                },
+                "Component_[3722854130373041803]": {
+                    "$type": "EditorOnlyEntityComponent",
+                    "Id": 3722854130373041803
+                },
+                "Component_[5992533738676323195]": {
+                    "$type": "EditorDisabledCompositionComponent",
+                    "Id": 5992533738676323195
+                },
+                "Component_[7378860763541895402]": {
+                    "$type": "AZ::Render::EditorDirectionalLightComponent",
+                    "Id": 7378860763541895402,
+                    "Controller": {
+                        "Configuration": {
+                            "Intensity": 1.0,
+                            "CameraEntityId": "",
+                            "ShadowFilterMethod": 1
+                        }
+                    }
+                },
+                "Component_[7892834440890947578]": {
+                    "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
+                    "Id": 7892834440890947578,
+                    "Parent Entity": "Entity_[1176639161715]",
+                    "Transform Data": {
+                        "Translate": [
+                            0.0,
+                            0.0,
+                            13.487043380737305
+                        ],
+                        "Rotate": [
+                            -76.13099670410156,
+                            -0.847000002861023,
+                            -15.8100004196167
+                        ]
+                    }
+                },
+                "Component_[8599729549570828259]": {
+                    "$type": "EditorEntitySortComponent",
+                    "Id": 8599729549570828259
+                },
+                "Component_[952797371922080273]": {
+                    "$type": "EditorPendingCompositionComponent",
+                    "Id": 952797371922080273
+                }
+            }
+        },
+        "Entity_[1159459292531]": {
+            "Id": "Entity_[1159459292531]",
+            "Name": "Ground",
+            "Components": {
+                "Component_[11701138785793981042]": {
+                    "$type": "SelectionComponent",
+                    "Id": 11701138785793981042
+                },
+                "Component_[12260880513256986252]": {
+                    "$type": "EditorEntityIconComponent",
+                    "Id": 12260880513256986252
+                },
+                "Component_[13711420870643673468]": {
+                    "$type": "EditorDisabledCompositionComponent",
+                    "Id": 13711420870643673468
+                },
+                "Component_[138002849734991713]": {
+                    "$type": "EditorOnlyEntityComponent",
+                    "Id": 138002849734991713
+                },
+                "Component_[16578565737331764849]": {
+                    "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
+                    "Id": 16578565737331764849,
+                    "Parent Entity": "Entity_[1176639161715]"
+                },
+                "Component_[16919232076966545697]": {
+                    "$type": "EditorInspectorComponent",
+                    "Id": 16919232076966545697
+                },
+                "Component_[5182430712893438093]": {
+                    "$type": "EditorMaterialComponent",
+                    "Id": 5182430712893438093
+                },
+                "Component_[5675108321710651991]": {
+                    "$type": "AZ::Render::EditorMeshComponent",
+                    "Id": 5675108321710651991,
+                    "Controller": {
+                        "Configuration": {
+                            "ModelAsset": {
+                                "assetId": {
+                                    "guid": "{0CD745C0-6AA8-569A-A68A-73A3270986C4}",
+                                    "subId": 277889906
+                                },
+                                "assetHint": "objects/groudplane/groundplane_512x512m.azmodel"
+                            }
+                        }
+                    }
+                },
+                "Component_[5681893399601237518]": {
+                    "$type": "EditorEntitySortComponent",
+                    "Id": 5681893399601237518
+                },
+                "Component_[592692962543397545]": {
+                    "$type": "EditorPendingCompositionComponent",
+                    "Id": 592692962543397545
+                },
+                "Component_[7090012899106946164]": {
+                    "$type": "EditorLockComponent",
+                    "Id": 7090012899106946164
+                },
+                "Component_[9410832619875640998]": {
+                    "$type": "EditorVisibilityComponent",
+                    "Id": 9410832619875640998
+                }
+            }
+        },
+        "Entity_[1163754259827]": {
+            "Id": "Entity_[1163754259827]",
+            "Name": "Camera",
+            "Components": {
+                "Component_[11895140916889160460]": {
+                    "$type": "EditorEntityIconComponent",
+                    "Id": 11895140916889160460
+                },
+                "Component_[16880285896855930892]": {
+                    "$type": "{CA11DA46-29FF-4083-B5F6-E02C3A8C3A3D} EditorCameraComponent",
+                    "Id": 16880285896855930892,
+                    "Controller": {
+                        "Configuration": {
+                            "Field of View": 55.0,
+                            "EditorEntityId": 8929576024571800510
+                        }
+                    }
+                },
+                "Component_[17187464423780271193]": {
+                    "$type": "EditorLockComponent",
+                    "Id": 17187464423780271193
+                },
+                "Component_[17495696818315413311]": {
+                    "$type": "EditorEntitySortComponent",
+                    "Id": 17495696818315413311
+                },
+                "Component_[18086214374043522055]": {
+                    "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
+                    "Id": 18086214374043522055,
+                    "Parent Entity": "Entity_[1176639161715]",
+                    "Transform Data": {
+                        "Translate": [
+                            -2.3000001907348633,
+                            -3.9368600845336914,
+                            1.0
+                        ],
+                        "Rotate": [
+                            -2.050307512283325,
+                            1.9552897214889526,
+                            -43.623355865478516
+                        ]
+                    }
+                },
+                "Component_[18387556550380114975]": {
+                    "$type": "SelectionComponent",
+                    "Id": 18387556550380114975
+                },
+                "Component_[2654521436129313160]": {
+                    "$type": "EditorVisibilityComponent",
+                    "Id": 2654521436129313160
+                },
+                "Component_[5265045084611556958]": {
+                    "$type": "EditorDisabledCompositionComponent",
+                    "Id": 5265045084611556958
+                },
+                "Component_[7169798125182238623]": {
+                    "$type": "EditorPendingCompositionComponent",
+                    "Id": 7169798125182238623
+                },
+                "Component_[7255796294953281766]": {
+                    "$type": "GenericComponentWrapper",
+                    "Id": 7255796294953281766,
+                    "m_template": {
+                        "$type": "FlyCameraInputComponent"
+                    }
+                },
+                "Component_[8866210352157164042]": {
+                    "$type": "EditorInspectorComponent",
+                    "Id": 8866210352157164042
+                },
+                "Component_[9129253381063760879]": {
+                    "$type": "EditorOnlyEntityComponent",
+                    "Id": 9129253381063760879
+                }
+            }
+        },
+        "Entity_[1168049227123]": {
+            "Id": "Entity_[1168049227123]",
+            "Name": "Grid",
+            "Components": {
+                "Component_[11443347433215807130]": {
+                    "$type": "EditorEntityIconComponent",
+                    "Id": 11443347433215807130
+                },
+                "Component_[11779275529534764488]": {
+                    "$type": "SelectionComponent",
+                    "Id": 11779275529534764488
+                },
+                "Component_[14249419413039427459]": {
+                    "$type": "EditorInspectorComponent",
+                    "Id": 14249419413039427459
+                },
+                "Component_[15448581635946161318]": {
+                    "$type": "AZ::Render::EditorGridComponent",
+                    "Id": 15448581635946161318,
+                    "Controller": {
+                        "Configuration": {
+                            "primarySpacing": 4.0,
+                            "primaryColor": [
+                                0.501960813999176,
+                                0.501960813999176,
+                                0.501960813999176
+                            ],
+                            "secondarySpacing": 0.5,
+                            "secondaryColor": [
+                                0.250980406999588,
+                                0.250980406999588,
+                                0.250980406999588
+                            ]
+                        }
+                    }
+                },
+                "Component_[1843303322527297409]": {
+                    "$type": "EditorDisabledCompositionComponent",
+                    "Id": 1843303322527297409
+                },
+                "Component_[380249072065273654]": {
+                    "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
+                    "Id": 380249072065273654,
+                    "Parent Entity": "Entity_[1176639161715]"
+                },
+                "Component_[7476660583684339787]": {
+                    "$type": "EditorPendingCompositionComponent",
+                    "Id": 7476660583684339787
+                },
+                "Component_[7557626501215118375]": {
+                    "$type": "EditorEntitySortComponent",
+                    "Id": 7557626501215118375
+                },
+                "Component_[7984048488947365511]": {
+                    "$type": "EditorVisibilityComponent",
+                    "Id": 7984048488947365511
+                },
+                "Component_[8118181039276487398]": {
+                    "$type": "EditorOnlyEntityComponent",
+                    "Id": 8118181039276487398
+                },
+                "Component_[9189909764215270515]": {
+                    "$type": "EditorLockComponent",
+                    "Id": 9189909764215270515
+                }
+            }
+        },
+        "Entity_[1172344194419]": {
+            "Id": "Entity_[1172344194419]",
+            "Name": "Shader Ball",
+            "Components": {
+                "Component_[10789351944715265527]": {
+                    "$type": "EditorOnlyEntityComponent",
+                    "Id": 10789351944715265527
+                },
+                "Component_[12037033284781049225]": {
+                    "$type": "EditorEntitySortComponent",
+                    "Id": 12037033284781049225
+                },
+                "Component_[13759153306105970079]": {
+                    "$type": "EditorPendingCompositionComponent",
+                    "Id": 13759153306105970079
+                },
+                "Component_[14135560884830586279]": {
+                    "$type": "EditorInspectorComponent",
+                    "Id": 14135560884830586279
+                },
+                "Component_[16247165675903986673]": {
+                    "$type": "EditorVisibilityComponent",
+                    "Id": 16247165675903986673
+                },
+                "Component_[18082433625958885247]": {
+                    "$type": "EditorDisabledCompositionComponent",
+                    "Id": 18082433625958885247
+                },
+                "Component_[6472623349872972660]": {
+                    "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
+                    "Id": 6472623349872972660,
+                    "Parent Entity": "Entity_[1176639161715]",
+                    "Transform Data": {
+                        "Rotate": [
+                            0.0,
+                            0.10000000149011612,
+                            180.0
+                        ]
+                    }
+                },
+                "Component_[6495255223970673916]": {
+                    "$type": "AZ::Render::EditorMeshComponent",
+                    "Id": 6495255223970673916,
+                    "Controller": {
+                        "Configuration": {
+                            "ModelAsset": {
+                                "assetId": {
+                                    "guid": "{FD340C30-755C-5911-92A3-19A3F7A77931}",
+                                    "subId": 281415304
+                                },
+                                "assetHint": "objects/shaderball/shaderball_default_1m.azmodel"
+                            }
+                        }
+                    }
+                },
+                "Component_[8056625192494070973]": {
+                    "$type": "SelectionComponent",
+                    "Id": 8056625192494070973
+                },
+                "Component_[8550141614185782969]": {
+                    "$type": "EditorEntityIconComponent",
+                    "Id": 8550141614185782969
+                },
+                "Component_[9439770997198325425]": {
+                    "$type": "EditorLockComponent",
+                    "Id": 9439770997198325425
+                }
+            }
+        },
+        "Entity_[1176639161715]": {
+            "Id": "Entity_[1176639161715]",
+            "Name": "Atom Default Environment",
+            "Components": {
+                "Component_[10757302973393310045]": {
+                    "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
+                    "Id": 10757302973393310045,
+                    "Parent Entity": "Entity_[1146574390643]"
+                },
+                "Component_[14505817420424255464]": {
+                    "$type": "EditorInspectorComponent",
+                    "Id": 14505817420424255464,
+                    "ComponentOrderEntryArray": [
+                        {
+                            "ComponentId": 10757302973393310045
+                        }
+                    ]
+                },
+                "Component_[14988041764659020032]": {
+                    "$type": "EditorLockComponent",
+                    "Id": 14988041764659020032
+                },
+                "Component_[15808690248755038124]": {
+                    "$type": "SelectionComponent",
+                    "Id": 15808690248755038124
+                },
+                "Component_[15900837685796817138]": {
+                    "$type": "EditorVisibilityComponent",
+                    "Id": 15900837685796817138
+                },
+                "Component_[3298767348226484884]": {
+                    "$type": "EditorOnlyEntityComponent",
+                    "Id": 3298767348226484884
+                },
+                "Component_[4076975109609220594]": {
+                    "$type": "EditorPendingCompositionComponent",
+                    "Id": 4076975109609220594
+                },
+                "Component_[5679760548946028854]": {
+                    "$type": "EditorDisabledCompositionComponent",
+                    "Id": 5679760548946028854
+                },
+                "Component_[5855590796136709437]": {
+                    "$type": "EditorEntitySortComponent",
+                    "Id": 5855590796136709437,
+                    "Child Entity Order": [
+                        "Entity_[1155164325235]",
+                        "Entity_[1180934129011]",
+                        "Entity_[1172344194419]",
+                        "Entity_[1168049227123]",
+                        "Entity_[1163754259827]",
+                        "Entity_[1159459292531]"
+                    ]
+                },
+                "Component_[9277695270015777859]": {
+                    "$type": "EditorEntityIconComponent",
+                    "Id": 9277695270015777859
+                }
+            }
+        },
+        "Entity_[1180934129011]": {
+            "Id": "Entity_[1180934129011]",
+            "Name": "Global Sky",
+            "Components": {
+                "Component_[11231930600558681245]": {
+                    "$type": "AZ::Render::EditorHDRiSkyboxComponent",
+                    "Id": 11231930600558681245,
+                    "Controller": {
+                        "Configuration": {
+                            "CubemapAsset": {
+                                "assetId": {
+                                    "guid": "{215E47FD-D181-5832-B1AB-91673ABF6399}",
+                                    "subId": 1000
+                                },
+                                "assetHint": "lightingpresets/highcontrast/goegap_4k_skyboxcm.exr.streamingimage"
+                            }
+                        }
+                    }
+                },
+                "Component_[11980494120202836095]": {
+                    "$type": "SelectionComponent",
+                    "Id": 11980494120202836095
+                },
+                "Component_[1428633914413949476]": {
+                    "$type": "EditorLockComponent",
+                    "Id": 1428633914413949476
+                },
+                "Component_[14936200426671614999]": {
+                    "$type": "AZ::Render::EditorImageBasedLightComponent",
+                    "Id": 14936200426671614999,
+                    "Controller": {
+                        "Configuration": {
+                            "diffuseImageAsset": {
+                                "assetId": {
+                                    "guid": "{3FD09945-D0F2-55C8-B9AF-B2FD421FE3BE}",
+                                    "subId": 3000
+                                },
+                                "assetHint": "lightingpresets/highcontrast/goegap_4k_iblglobalcm_ibldiffuse.exr.streamingimage"
+                            },
+                            "specularImageAsset": {
+                                "assetId": {
+                                    "guid": "{3FD09945-D0F2-55C8-B9AF-B2FD421FE3BE}",
+                                    "subId": 2000
+                                },
+                                "assetHint": "lightingpresets/highcontrast/goegap_4k_iblglobalcm_iblspecular.exr.streamingimage"
+                            }
+                        }
+                    }
+                },
+                "Component_[14994774102579326069]": {
+                    "$type": "EditorDisabledCompositionComponent",
+                    "Id": 14994774102579326069
+                },
+                "Component_[15417479889044493340]": {
+                    "$type": "EditorPendingCompositionComponent",
+                    "Id": 15417479889044493340
+                },
+                "Component_[15826613364991382688]": {
+                    "$type": "EditorEntitySortComponent",
+                    "Id": 15826613364991382688
+                },
+                "Component_[1665003113283562343]": {
+                    "$type": "EditorOnlyEntityComponent",
+                    "Id": 1665003113283562343
+                },
+                "Component_[3704934735944502280]": {
+                    "$type": "EditorEntityIconComponent",
+                    "Id": 3704934735944502280
+                },
+                "Component_[5698542331457326479]": {
+                    "$type": "EditorVisibilityComponent",
+                    "Id": 5698542331457326479
+                },
+                "Component_[6644513399057217122]": {
+                    "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
+                    "Id": 6644513399057217122,
+                    "Parent Entity": "Entity_[1176639161715]"
+                },
+                "Component_[931091830724002070]": {
+                    "$type": "EditorInspectorComponent",
+                    "Id": 931091830724002070
+                }
+            }
+        }
+    }
+}

+ 12 - 0
AutomatedTesting/Gem/PythonTests/assetpipeline/asset_bundler_tests/assets/Levels/TestDependenciesLevel/tags.txt

@@ -0,0 +1,12 @@
+0,0,0,0,0,0
+0,0,0,0,0,0
+0,0,0,0,0,0
+0,0,0,0,0,0
+0,0,0,0,0,0
+0,0,0,0,0,0
+0,0,0,0,0,0
+0,0,0,0,0,0
+0,0,0,0,0,0
+0,0,0,0,0,0
+0,0,0,0,0,0
+0,0,0,0,0,0

+ 3 - 0
AutomatedTesting/Gem/PythonTests/assetpipeline/asset_bundler_tests/assets/SeedWithDependencies/AMA_Green_01.tif

@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:6b857d0dd0d349ce5366612372290a1b9b4085ffc2e235e245739a7a6c76ea11
+size 21752

+ 3 - 0
AutomatedTesting/Gem/PythonTests/assetpipeline/asset_bundler_tests/assets/SeedWithDependencies/AMA_Grey_01.tif

@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:418ed2ae210922737306d653cd18ae970ba72c192bbcf4e8bc9dff005f53ea0a
+size 5020

+ 3 - 0
AutomatedTesting/Gem/PythonTests/assetpipeline/asset_bundler_tests/assets/SeedWithDependencies/AMA_White_01.tif

@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:cd91032afab1a93327de4a4b00146340efafd1dda5a2a0b35399427bd511f127
+size 6660

+ 564 - 0
AutomatedTesting/Gem/PythonTests/assetpipeline/asset_bundler_tests/assets/SeedWithDependencies/Canvas1.uicanvas

@@ -0,0 +1,564 @@
+<ObjectStream version="3">
+	<Class name="UiCanvasFileObject" version="2" type="{1F02632F-F113-49B1-85AD-8CD0FA78B8AA}">
+		<Class name="AZ::Entity" field="CanvasEntity" version="2" type="{75651658-8663-478D-9090-2432DFCAFA44}">
+			<Class name="EntityId" field="Id" version="1" type="{6383F1D3-BB27-4E6B-A49A-6409B2059EAA}">
+				<Class name="AZ::u64" field="id" value="474928432572" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}"/>
+			</Class>
+			<Class name="AZStd::string" field="Name" value="UiCanvasEntity" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
+			<Class name="AZStd::vector&lt;AZ::Component*, allocator&gt;" field="Components" type="{13D58FF9-1088-5C69-9A1F-C2A144B57B78}">
+				<Class name="UiCanvasComponent" field="element" version="4" type="{50B8CF6C-B19A-4D86-AFE9-96EFB820D422}">
+					<Class name="AZ::Component" field="BaseClass1" type="{EDFCB2CF-F75D-43BE-B26B-F35821B29247}">
+						<Class name="AZ::u64" field="Id" value="15467960535682957009" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}"/>
+					</Class>
+					<Class name="AZ::u64" field="UniqueId" value="11774790100548863531" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}"/>
+					<Class name="EntityId" field="RootElement" version="1" type="{6383F1D3-BB27-4E6B-A49A-6409B2059EAA}">
+						<Class name="AZ::u64" field="id" value="487813334460" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}"/>
+					</Class>
+					<Class name="unsigned int" field="LastElement" value="9" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
+					<Class name="Vector2" field="CanvasSize" value="1280.0000000 720.0000000" type="{3D80F623-C85C-4741-90D0-E4E66164E6BF}"/>
+					<Class name="bool" field="IsSnapEnabled" value="false" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
+					<Class name="int" field="DrawOrder" value="0" type="{72039442-EB38-4D42-A1AD-CB68F7E0EEF6}"/>
+					<Class name="bool" field="IsPixelAligned" value="true" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
+					<Class name="bool" field="IsTextPixelAligned" value="true" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
+					<Class name="bool" field="RenderToTexture" value="false" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
+					<Class name="Asset&lt;AttachmentImageAsset&gt;" field="AttachmentImageAsset" value="id={00000000-0000-0000-0000-000000000000}:0,type={82CEA86B-E891-4969-8F35-D8017E8902C8},hint={},loadBehavior=1" version="3" type="{61538C1C-2EDA-593B-AA53-701FF7D854E7}"/>
+					<Class name="bool" field="IsPosInputSupported" value="true" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
+					<Class name="bool" field="IsConsumingAllInput" value="false" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
+					<Class name="bool" field="IsMultiTouchSupported" value="true" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
+					<Class name="bool" field="IsNavigationSupported" value="true" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
+					<Class name="float" field="NavigationThreshold" value="0.4000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
+					<Class name="AZ::u64" field="NavigationRepeatDelay" value="300" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}"/>
+					<Class name="AZ::u64" field="NavigationRepeatPeriod" value="150" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}"/>
+					<Class name="EntityId" field="FirstHoverElement" version="1" type="{6383F1D3-BB27-4E6B-A49A-6409B2059EAA}">
+						<Class name="AZ::u64" field="id" value="4294967295" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}"/>
+					</Class>
+					<Class name="UiAnimationSystem" field="AnimSystem" version="1" type="{2592269B-EF74-4409-B29F-682DC0B45DAF}">
+						<Class name="AZStd::vector&lt;AZStd::intrusive_ptr&lt;IUiAnimSequence&gt;, allocator&gt;" field="Sequences" type="{9F8D44A9-9731-5314-885E-B958D4216073}"/>
+					</Class>
+					<Class name="AnimationData" field="AnimationData" version="1" type="{FDC58CF7-8109-48F2-8D5D-BCBAF774ABB7}">
+						<Class name="AZStd::string" field="SerializeString" value="" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
+					</Class>
+					<Class name="EntityId" field="TooltipDisplayElement" version="1" type="{6383F1D3-BB27-4E6B-A49A-6409B2059EAA}">
+						<Class name="AZ::u64" field="id" value="4294967295" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}"/>
+					</Class>
+					<Class name="float" field="SnapDistance" value="10.0000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
+					<Class name="float" field="SnapRotationDegrees" value="10.0000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
+					<Class name="AZStd::vector&lt;float, allocator&gt;" field="HorizontalGuides" type="{6106BF95-5ACD-5071-8D0E-4F846C2138AD}"/>
+					<Class name="AZStd::vector&lt;float, allocator&gt;" field="VerticalGuides" type="{6106BF95-5ACD-5071-8D0E-4F846C2138AD}"/>
+					<Class name="Color" field="GuideColor" value="0.2500000 1.0000000 0.2500000 1.0000000" type="{7894072A-9050-4F0F-901B-34B1A0D29417}"/>
+					<Class name="bool" field="GuidesLocked" value="false" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
+					<Class name="AZStd::vector&lt;SimpleAssetReference&lt;TextureAtlasAsset&gt;, allocator&gt;" field="TextureAtlases" type="{73F8CC7B-8504-5F80-BD45-1620CD7EF9AB}"/>
+				</Class>
+			</Class>
+			<Class name="bool" field="IsDependencyReady" value="true" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
+			<Class name="bool" field="IsRuntimeActive" value="true" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
+		</Class>
+		<Class name="AZ::Entity" field="RootSliceEntity" version="2" type="{75651658-8663-478D-9090-2432DFCAFA44}">
+			<Class name="EntityId" field="Id" version="1" type="{6383F1D3-BB27-4E6B-A49A-6409B2059EAA}">
+				<Class name="AZ::u64" field="id" value="479223399868" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}"/>
+			</Class>
+			<Class name="AZStd::string" field="Name" value="479223399868" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
+			<Class name="AZStd::vector&lt;AZ::Component*, allocator&gt;" field="Components" type="{13D58FF9-1088-5C69-9A1F-C2A144B57B78}">
+				<Class name="SliceComponent" field="element" version="3" type="{AFD304E4-1773-47C8-855A-8B622398934F}">
+					<Class name="AZ::Component" field="BaseClass1" type="{EDFCB2CF-F75D-43BE-B26B-F35821B29247}">
+						<Class name="AZ::u64" field="Id" value="2590986407960043829" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}"/>
+					</Class>
+					<Class name="AZStd::vector&lt;AZ::Entity*, allocator&gt;" field="Entities" type="{21786AF0-2606-5B9A-86EB-0892E2820E6C}">
+						<Class name="AZ::Entity" field="element" version="2" type="{75651658-8663-478D-9090-2432DFCAFA44}">
+							<Class name="EntityId" field="Id" version="1" type="{6383F1D3-BB27-4E6B-A49A-6409B2059EAA}">
+								<Class name="AZ::u64" field="id" value="487813334460" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}"/>
+							</Class>
+							<Class name="AZStd::string" field="Name" value="_root" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
+							<Class name="AZStd::vector&lt;AZ::Component*, allocator&gt;" field="Components" type="{13D58FF9-1088-5C69-9A1F-C2A144B57B78}">
+								<Class name="EditorOnlyEntityComponent" field="element" type="{22A16F1D-6D49-422D-AAE9-91AE45B5D3E7}">
+									<Class name="EditorComponentBase" field="BaseClass1" version="1" type="{D5346BD4-7F20-444E-B370-327ACD03D4A0}">
+										<Class name="AZ::Component" field="BaseClass1" type="{EDFCB2CF-F75D-43BE-B26B-F35821B29247}">
+											<Class name="AZ::u64" field="Id" value="8296342203764853668" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}"/>
+										</Class>
+									</Class>
+									<Class name="bool" field="IsEditorOnly" value="false" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
+								</Class>
+								<Class name="UiTransform2dComponent" field="element" version="3" type="{2751A5A5-3291-4A4D-9FC0-9CB0EB8D1DE6}">
+									<Class name="AZ::Component" field="BaseClass1" type="{EDFCB2CF-F75D-43BE-B26B-F35821B29247}">
+										<Class name="AZ::u64" field="Id" value="1417335033688256310" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}"/>
+									</Class>
+									<Class name="Anchors" field="Anchors" type="{65D4346C-FB16-4CB0-9BDC-1185B122C4A9}">
+										<Class name="float" field="left" value="0.5000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
+										<Class name="float" field="top" value="0.5000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
+										<Class name="float" field="right" value="0.5000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
+										<Class name="float" field="bottom" value="0.5000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
+									</Class>
+									<Class name="Offsets" field="Offsets" type="{F681BA9D-245C-4630-B20E-05DD752FAD57}">
+										<Class name="float" field="left" value="-50.0000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
+										<Class name="float" field="top" value="-50.0000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
+										<Class name="float" field="right" value="50.0000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
+										<Class name="float" field="bottom" value="50.0000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
+									</Class>
+									<Class name="Vector2" field="Pivot" value="0.5000000 0.5000000" type="{3D80F623-C85C-4741-90D0-E4E66164E6BF}"/>
+									<Class name="float" field="Rotation" value="0.0000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
+									<Class name="Vector2" field="Scale" value="1.0000000 1.0000000" type="{3D80F623-C85C-4741-90D0-E4E66164E6BF}"/>
+									<Class name="int" field="ScaleToDevice" value="0" type="{72039442-EB38-4D42-A1AD-CB68F7E0EEF6}"/>
+								</Class>
+								<Class name="UiElementComponent" field="element" version="3" type="{4A97D63E-CE7A-45B6-AAE4-102DB4334688}">
+									<Class name="AZ::Component" field="BaseClass1" type="{EDFCB2CF-F75D-43BE-B26B-F35821B29247}">
+										<Class name="AZ::u64" field="Id" value="2955930260092508917" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}"/>
+									</Class>
+									<Class name="unsigned int" field="Id" value="1" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
+									<Class name="bool" field="IsEnabled" value="true" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
+									<Class name="bool" field="IsVisibleInEditor" value="true" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
+									<Class name="bool" field="IsSelectableInEditor" value="true" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
+									<Class name="bool" field="IsSelectedInEditor" value="false" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
+									<Class name="bool" field="IsExpandedInEditor" value="true" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
+									<Class name="AZStd::vector&lt;ChildEntityIdOrderEntry, allocator&gt;" field="ChildEntityIdOrder" type="{0DE523D9-AEAE-5FC4-9D40-967A2E2B8A62}">
+										<Class name="ChildEntityIdOrderEntry" field="element" version="1" type="{D6F3CC55-6C7C-4D64-818F-FA3378EC8DA2}">
+											<Class name="EntityId" field="ChildEntityId" version="1" type="{6383F1D3-BB27-4E6B-A49A-6409B2059EAA}">
+												<Class name="AZ::u64" field="id" value="492108301756" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}"/>
+											</Class>
+											<Class name="AZ::u64" field="SortIndex" value="0" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}"/>
+										</Class>
+										<Class name="ChildEntityIdOrderEntry" field="element" version="1" type="{D6F3CC55-6C7C-4D64-818F-FA3378EC8DA2}">
+											<Class name="EntityId" field="ChildEntityId" version="1" type="{6383F1D3-BB27-4E6B-A49A-6409B2059EAA}">
+												<Class name="AZ::u64" field="id" value="496403269052" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}"/>
+											</Class>
+											<Class name="AZ::u64" field="SortIndex" value="1" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}"/>
+										</Class>
+										<Class name="ChildEntityIdOrderEntry" field="element" version="1" type="{D6F3CC55-6C7C-4D64-818F-FA3378EC8DA2}">
+											<Class name="EntityId" field="ChildEntityId" version="1" type="{6383F1D3-BB27-4E6B-A49A-6409B2059EAA}">
+												<Class name="AZ::u64" field="id" value="500698236348" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}"/>
+											</Class>
+											<Class name="AZ::u64" field="SortIndex" value="2" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}"/>
+										</Class>
+										<Class name="ChildEntityIdOrderEntry" field="element" version="1" type="{D6F3CC55-6C7C-4D64-818F-FA3378EC8DA2}">
+											<Class name="EntityId" field="ChildEntityId" version="1" type="{6383F1D3-BB27-4E6B-A49A-6409B2059EAA}">
+												<Class name="AZ::u64" field="id" value="504993203644" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}"/>
+											</Class>
+											<Class name="AZ::u64" field="SortIndex" value="3" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}"/>
+										</Class>
+										<Class name="ChildEntityIdOrderEntry" field="element" version="1" type="{D6F3CC55-6C7C-4D64-818F-FA3378EC8DA2}">
+											<Class name="EntityId" field="ChildEntityId" version="1" type="{6383F1D3-BB27-4E6B-A49A-6409B2059EAA}">
+												<Class name="AZ::u64" field="id" value="509288170940" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}"/>
+											</Class>
+											<Class name="AZ::u64" field="SortIndex" value="4" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}"/>
+										</Class>
+									</Class>
+								</Class>
+							</Class>
+							<Class name="bool" field="IsDependencyReady" value="true" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
+							<Class name="bool" field="IsRuntimeActive" value="true" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
+						</Class>
+						<Class name="AZ::Entity" field="element" version="2" type="{75651658-8663-478D-9090-2432DFCAFA44}">
+							<Class name="EntityId" field="Id" version="1" type="{6383F1D3-BB27-4E6B-A49A-6409B2059EAA}">
+								<Class name="AZ::u64" field="id" value="496403269052" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}"/>
+							</Class>
+							<Class name="AZStd::string" field="Name" value="Image2" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
+							<Class name="AZStd::vector&lt;AZ::Component*, allocator&gt;" field="Components" type="{13D58FF9-1088-5C69-9A1F-C2A144B57B78}">
+								<Class name="EditorOnlyEntityComponent" field="element" type="{22A16F1D-6D49-422D-AAE9-91AE45B5D3E7}">
+									<Class name="EditorComponentBase" field="BaseClass1" version="1" type="{D5346BD4-7F20-444E-B370-327ACD03D4A0}">
+										<Class name="AZ::Component" field="BaseClass1" type="{EDFCB2CF-F75D-43BE-B26B-F35821B29247}">
+											<Class name="AZ::u64" field="Id" value="6090667790069324941" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}"/>
+										</Class>
+									</Class>
+									<Class name="bool" field="IsEditorOnly" value="false" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
+								</Class>
+								<Class name="UiTransform2dComponent" field="element" version="3" type="{2751A5A5-3291-4A4D-9FC0-9CB0EB8D1DE6}">
+									<Class name="AZ::Component" field="BaseClass1" type="{EDFCB2CF-F75D-43BE-B26B-F35821B29247}">
+										<Class name="AZ::u64" field="Id" value="8387065614562102859" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}"/>
+									</Class>
+									<Class name="Anchors" field="Anchors" type="{65D4346C-FB16-4CB0-9BDC-1185B122C4A9}">
+										<Class name="float" field="left" value="0.5000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
+										<Class name="float" field="top" value="0.5000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
+										<Class name="float" field="right" value="0.5000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
+										<Class name="float" field="bottom" value="0.5000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
+									</Class>
+									<Class name="Offsets" field="Offsets" type="{F681BA9D-245C-4630-B20E-05DD752FAD57}">
+										<Class name="float" field="left" value="-158.4188843" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
+										<Class name="float" field="top" value="-50.0000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
+										<Class name="float" field="right" value="-58.4188919" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
+										<Class name="float" field="bottom" value="50.0000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
+									</Class>
+									<Class name="Vector2" field="Pivot" value="0.5000000 0.5000000" type="{3D80F623-C85C-4741-90D0-E4E66164E6BF}"/>
+									<Class name="float" field="Rotation" value="0.0000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
+									<Class name="Vector2" field="Scale" value="1.0000000 1.0000000" type="{3D80F623-C85C-4741-90D0-E4E66164E6BF}"/>
+									<Class name="int" field="ScaleToDevice" value="0" type="{72039442-EB38-4D42-A1AD-CB68F7E0EEF6}"/>
+								</Class>
+								<Class name="UiElementComponent" field="element" version="3" type="{4A97D63E-CE7A-45B6-AAE4-102DB4334688}">
+									<Class name="AZ::Component" field="BaseClass1" type="{EDFCB2CF-F75D-43BE-B26B-F35821B29247}">
+										<Class name="AZ::u64" field="Id" value="16657781940265029894" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}"/>
+									</Class>
+									<Class name="unsigned int" field="Id" value="3" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
+									<Class name="bool" field="IsEnabled" value="true" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
+									<Class name="bool" field="IsVisibleInEditor" value="true" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
+									<Class name="bool" field="IsSelectableInEditor" value="true" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
+									<Class name="bool" field="IsSelectedInEditor" value="false" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
+									<Class name="bool" field="IsExpandedInEditor" value="true" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
+									<Class name="AZStd::vector&lt;ChildEntityIdOrderEntry, allocator&gt;" field="ChildEntityIdOrder" type="{0DE523D9-AEAE-5FC4-9D40-967A2E2B8A62}"/>
+								</Class>
+								<Class name="UiImageComponent" field="element" version="8" type="{BDBEFD23-DBB4-4726-A32D-4FEAC24E51F6}">
+									<Class name="AZ::Component" field="BaseClass1" type="{EDFCB2CF-F75D-43BE-B26B-F35821B29247}">
+										<Class name="AZ::u64" field="Id" value="8899143841318558907" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}"/>
+									</Class>
+									<Class name="int" field="SpriteType" value="0" type="{72039442-EB38-4D42-A1AD-CB68F7E0EEF6}"/>
+									<Class name="SimpleAssetReference&lt;TextureAsset&gt;" field="SpritePath" version="1" type="{6E0B1C86-F66A-5D30-BCBB-0F9EA199E4AF}">
+										<Class name="SimpleAssetReferenceBase" field="BaseClass1" version="1" type="{E16CA6C5-5C78-4AD9-8E9B-F8C1FB4D1DB8}">
+											<Class name="AZStd::string" field="AssetPath" value="ama_grey_01.tif" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
+										</Class>
+									</Class>
+									<Class name="unsigned int" field="Index" value="0" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
+									<Class name="Asset&lt;AttachmentImageAsset&gt;" field="AttachmentImageAsset" value="id={00000000-0000-0000-0000-000000000000}:0,type={82CEA86B-E891-4969-8F35-D8017E8902C8},hint={},loadBehavior=1" version="3" type="{61538C1C-2EDA-593B-AA53-701FF7D854E7}"/>
+									<Class name="bool" field="IsRenderTargetSRGB" value="false" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
+									<Class name="Color" field="Color" value="1.0000000 1.0000000 1.0000000 1.0000000" type="{7894072A-9050-4F0F-901B-34B1A0D29417}"/>
+									<Class name="float" field="Alpha" value="1.0000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
+									<Class name="int" field="ImageType" value="0" type="{72039442-EB38-4D42-A1AD-CB68F7E0EEF6}"/>
+									<Class name="bool" field="FillCenter" value="true" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
+									<Class name="bool" field="StretchSliced" value="true" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
+									<Class name="int" field="BlendMode" value="0" type="{72039442-EB38-4D42-A1AD-CB68F7E0EEF6}"/>
+									<Class name="int" field="FillType" value="0" type="{72039442-EB38-4D42-A1AD-CB68F7E0EEF6}"/>
+									<Class name="float" field="FillAmount" value="1.0000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
+									<Class name="float" field="FillStartAngle" value="0.0000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
+									<Class name="int" field="FillCornerOrigin" value="0" type="{72039442-EB38-4D42-A1AD-CB68F7E0EEF6}"/>
+									<Class name="int" field="FillEdgeOrigin" value="0" type="{72039442-EB38-4D42-A1AD-CB68F7E0EEF6}"/>
+									<Class name="bool" field="FillClockwise" value="true" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
+								</Class>
+							</Class>
+							<Class name="bool" field="IsDependencyReady" value="true" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
+							<Class name="bool" field="IsRuntimeActive" value="true" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
+						</Class>
+						<Class name="AZ::Entity" field="element" version="2" type="{75651658-8663-478D-9090-2432DFCAFA44}">
+							<Class name="EntityId" field="Id" version="1" type="{6383F1D3-BB27-4E6B-A49A-6409B2059EAA}">
+								<Class name="AZ::u64" field="id" value="500698236348" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}"/>
+							</Class>
+							<Class name="AZStd::string" field="Name" value="Image3" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
+							<Class name="AZStd::vector&lt;AZ::Component*, allocator&gt;" field="Components" type="{13D58FF9-1088-5C69-9A1F-C2A144B57B78}">
+								<Class name="EditorOnlyEntityComponent" field="element" type="{22A16F1D-6D49-422D-AAE9-91AE45B5D3E7}">
+									<Class name="EditorComponentBase" field="BaseClass1" version="1" type="{D5346BD4-7F20-444E-B370-327ACD03D4A0}">
+										<Class name="AZ::Component" field="BaseClass1" type="{EDFCB2CF-F75D-43BE-B26B-F35821B29247}">
+											<Class name="AZ::u64" field="Id" value="4225407189794244608" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}"/>
+										</Class>
+									</Class>
+									<Class name="bool" field="IsEditorOnly" value="false" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
+								</Class>
+								<Class name="UiTransform2dComponent" field="element" version="3" type="{2751A5A5-3291-4A4D-9FC0-9CB0EB8D1DE6}">
+									<Class name="AZ::Component" field="BaseClass1" type="{EDFCB2CF-F75D-43BE-B26B-F35821B29247}">
+										<Class name="AZ::u64" field="Id" value="10653913905093048091" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}"/>
+									</Class>
+									<Class name="Anchors" field="Anchors" type="{65D4346C-FB16-4CB0-9BDC-1185B122C4A9}">
+										<Class name="float" field="left" value="0.5000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
+										<Class name="float" field="top" value="0.5000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
+										<Class name="float" field="right" value="0.5000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
+										<Class name="float" field="bottom" value="0.5000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
+									</Class>
+									<Class name="Offsets" field="Offsets" type="{F681BA9D-245C-4630-B20E-05DD752FAD57}">
+										<Class name="float" field="left" value="60.8829575" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
+										<Class name="float" field="top" value="-50.0000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
+										<Class name="float" field="right" value="160.8829651" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
+										<Class name="float" field="bottom" value="50.0000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
+									</Class>
+									<Class name="Vector2" field="Pivot" value="0.5000000 0.5000000" type="{3D80F623-C85C-4741-90D0-E4E66164E6BF}"/>
+									<Class name="float" field="Rotation" value="0.0000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
+									<Class name="Vector2" field="Scale" value="1.0000000 1.0000000" type="{3D80F623-C85C-4741-90D0-E4E66164E6BF}"/>
+									<Class name="int" field="ScaleToDevice" value="0" type="{72039442-EB38-4D42-A1AD-CB68F7E0EEF6}"/>
+								</Class>
+								<Class name="UiElementComponent" field="element" version="3" type="{4A97D63E-CE7A-45B6-AAE4-102DB4334688}">
+									<Class name="AZ::Component" field="BaseClass1" type="{EDFCB2CF-F75D-43BE-B26B-F35821B29247}">
+										<Class name="AZ::u64" field="Id" value="14510703990579393410" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}"/>
+									</Class>
+									<Class name="unsigned int" field="Id" value="4" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
+									<Class name="bool" field="IsEnabled" value="true" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
+									<Class name="bool" field="IsVisibleInEditor" value="true" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
+									<Class name="bool" field="IsSelectableInEditor" value="true" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
+									<Class name="bool" field="IsSelectedInEditor" value="false" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
+									<Class name="bool" field="IsExpandedInEditor" value="true" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
+									<Class name="AZStd::vector&lt;ChildEntityIdOrderEntry, allocator&gt;" field="ChildEntityIdOrder" type="{0DE523D9-AEAE-5FC4-9D40-967A2E2B8A62}"/>
+								</Class>
+								<Class name="UiImageComponent" field="element" version="8" type="{BDBEFD23-DBB4-4726-A32D-4FEAC24E51F6}">
+									<Class name="AZ::Component" field="BaseClass1" type="{EDFCB2CF-F75D-43BE-B26B-F35821B29247}">
+										<Class name="AZ::u64" field="Id" value="3027781663307535247" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}"/>
+									</Class>
+									<Class name="int" field="SpriteType" value="0" type="{72039442-EB38-4D42-A1AD-CB68F7E0EEF6}"/>
+									<Class name="SimpleAssetReference&lt;TextureAsset&gt;" field="SpritePath" version="1" type="{6E0B1C86-F66A-5D30-BCBB-0F9EA199E4AF}">
+										<Class name="SimpleAssetReferenceBase" field="BaseClass1" version="1" type="{E16CA6C5-5C78-4AD9-8E9B-F8C1FB4D1DB8}">
+											<Class name="AZStd::string" field="AssetPath" value="ama_white_01.tif" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
+										</Class>
+									</Class>
+									<Class name="unsigned int" field="Index" value="0" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
+									<Class name="Asset&lt;AttachmentImageAsset&gt;" field="AttachmentImageAsset" value="id={00000000-0000-0000-0000-000000000000}:0,type={82CEA86B-E891-4969-8F35-D8017E8902C8},hint={},loadBehavior=1" version="3" type="{61538C1C-2EDA-593B-AA53-701FF7D854E7}"/>
+									<Class name="bool" field="IsRenderTargetSRGB" value="false" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
+									<Class name="Color" field="Color" value="1.0000000 1.0000000 1.0000000 1.0000000" type="{7894072A-9050-4F0F-901B-34B1A0D29417}"/>
+									<Class name="float" field="Alpha" value="1.0000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
+									<Class name="int" field="ImageType" value="0" type="{72039442-EB38-4D42-A1AD-CB68F7E0EEF6}"/>
+									<Class name="bool" field="FillCenter" value="true" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
+									<Class name="bool" field="StretchSliced" value="true" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
+									<Class name="int" field="BlendMode" value="0" type="{72039442-EB38-4D42-A1AD-CB68F7E0EEF6}"/>
+									<Class name="int" field="FillType" value="0" type="{72039442-EB38-4D42-A1AD-CB68F7E0EEF6}"/>
+									<Class name="float" field="FillAmount" value="1.0000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
+									<Class name="float" field="FillStartAngle" value="0.0000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
+									<Class name="int" field="FillCornerOrigin" value="0" type="{72039442-EB38-4D42-A1AD-CB68F7E0EEF6}"/>
+									<Class name="int" field="FillEdgeOrigin" value="0" type="{72039442-EB38-4D42-A1AD-CB68F7E0EEF6}"/>
+									<Class name="bool" field="FillClockwise" value="true" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
+								</Class>
+							</Class>
+							<Class name="bool" field="IsDependencyReady" value="true" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
+							<Class name="bool" field="IsRuntimeActive" value="true" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
+						</Class>
+						<Class name="AZ::Entity" field="element" version="2" type="{75651658-8663-478D-9090-2432DFCAFA44}">
+							<Class name="EntityId" field="Id" version="1" type="{6383F1D3-BB27-4E6B-A49A-6409B2059EAA}">
+								<Class name="AZ::u64" field="id" value="492108301756" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}"/>
+							</Class>
+							<Class name="AZStd::string" field="Name" value="Image1" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
+							<Class name="AZStd::vector&lt;AZ::Component*, allocator&gt;" field="Components" type="{13D58FF9-1088-5C69-9A1F-C2A144B57B78}">
+								<Class name="EditorOnlyEntityComponent" field="element" type="{22A16F1D-6D49-422D-AAE9-91AE45B5D3E7}">
+									<Class name="EditorComponentBase" field="BaseClass1" version="1" type="{D5346BD4-7F20-444E-B370-327ACD03D4A0}">
+										<Class name="AZ::Component" field="BaseClass1" type="{EDFCB2CF-F75D-43BE-B26B-F35821B29247}">
+											<Class name="AZ::u64" field="Id" value="14527494804262531044" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}"/>
+										</Class>
+									</Class>
+									<Class name="bool" field="IsEditorOnly" value="false" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
+								</Class>
+								<Class name="UiTransform2dComponent" field="element" version="3" type="{2751A5A5-3291-4A4D-9FC0-9CB0EB8D1DE6}">
+									<Class name="AZ::Component" field="BaseClass1" type="{EDFCB2CF-F75D-43BE-B26B-F35821B29247}">
+										<Class name="AZ::u64" field="Id" value="1653241725306964827" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}"/>
+									</Class>
+									<Class name="Anchors" field="Anchors" type="{65D4346C-FB16-4CB0-9BDC-1185B122C4A9}">
+										<Class name="float" field="left" value="0.5000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
+										<Class name="float" field="top" value="0.5000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
+										<Class name="float" field="right" value="0.5000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
+										<Class name="float" field="bottom" value="0.5000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
+									</Class>
+									<Class name="Offsets" field="Offsets" type="{F681BA9D-245C-4630-B20E-05DD752FAD57}">
+										<Class name="float" field="left" value="-50.0000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
+										<Class name="float" field="top" value="-50.0000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
+										<Class name="float" field="right" value="50.0000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
+										<Class name="float" field="bottom" value="50.0000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
+									</Class>
+									<Class name="Vector2" field="Pivot" value="0.5000000 0.5000000" type="{3D80F623-C85C-4741-90D0-E4E66164E6BF}"/>
+									<Class name="float" field="Rotation" value="0.0000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
+									<Class name="Vector2" field="Scale" value="1.0000000 1.0000000" type="{3D80F623-C85C-4741-90D0-E4E66164E6BF}"/>
+									<Class name="int" field="ScaleToDevice" value="0" type="{72039442-EB38-4D42-A1AD-CB68F7E0EEF6}"/>
+								</Class>
+								<Class name="UiElementComponent" field="element" version="3" type="{4A97D63E-CE7A-45B6-AAE4-102DB4334688}">
+									<Class name="AZ::Component" field="BaseClass1" type="{EDFCB2CF-F75D-43BE-B26B-F35821B29247}">
+										<Class name="AZ::u64" field="Id" value="16329198947015742888" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}"/>
+									</Class>
+									<Class name="unsigned int" field="Id" value="2" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
+									<Class name="bool" field="IsEnabled" value="true" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
+									<Class name="bool" field="IsVisibleInEditor" value="true" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
+									<Class name="bool" field="IsSelectableInEditor" value="true" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
+									<Class name="bool" field="IsSelectedInEditor" value="false" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
+									<Class name="bool" field="IsExpandedInEditor" value="true" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
+									<Class name="AZStd::vector&lt;ChildEntityIdOrderEntry, allocator&gt;" field="ChildEntityIdOrder" type="{0DE523D9-AEAE-5FC4-9D40-967A2E2B8A62}"/>
+								</Class>
+								<Class name="UiImageComponent" field="element" version="8" type="{BDBEFD23-DBB4-4726-A32D-4FEAC24E51F6}">
+									<Class name="AZ::Component" field="BaseClass1" type="{EDFCB2CF-F75D-43BE-B26B-F35821B29247}">
+										<Class name="AZ::u64" field="Id" value="7841180896507436090" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}"/>
+									</Class>
+									<Class name="int" field="SpriteType" value="0" type="{72039442-EB38-4D42-A1AD-CB68F7E0EEF6}"/>
+									<Class name="SimpleAssetReference&lt;TextureAsset&gt;" field="SpritePath" version="1" type="{6E0B1C86-F66A-5D30-BCBB-0F9EA199E4AF}">
+										<Class name="SimpleAssetReferenceBase" field="BaseClass1" version="1" type="{E16CA6C5-5C78-4AD9-8E9B-F8C1FB4D1DB8}">
+											<Class name="AZStd::string" field="AssetPath" value="ama_green_01.tif" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
+										</Class>
+									</Class>
+									<Class name="unsigned int" field="Index" value="0" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
+									<Class name="Asset&lt;AttachmentImageAsset&gt;" field="AttachmentImageAsset" value="id={00000000-0000-0000-0000-000000000000}:0,type={82CEA86B-E891-4969-8F35-D8017E8902C8},hint={},loadBehavior=1" version="3" type="{61538C1C-2EDA-593B-AA53-701FF7D854E7}"/>
+									<Class name="bool" field="IsRenderTargetSRGB" value="false" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
+									<Class name="Color" field="Color" value="1.0000000 1.0000000 1.0000000 1.0000000" type="{7894072A-9050-4F0F-901B-34B1A0D29417}"/>
+									<Class name="float" field="Alpha" value="1.0000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
+									<Class name="int" field="ImageType" value="0" type="{72039442-EB38-4D42-A1AD-CB68F7E0EEF6}"/>
+									<Class name="bool" field="FillCenter" value="true" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
+									<Class name="bool" field="StretchSliced" value="true" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
+									<Class name="int" field="BlendMode" value="0" type="{72039442-EB38-4D42-A1AD-CB68F7E0EEF6}"/>
+									<Class name="int" field="FillType" value="0" type="{72039442-EB38-4D42-A1AD-CB68F7E0EEF6}"/>
+									<Class name="float" field="FillAmount" value="1.0000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
+									<Class name="float" field="FillStartAngle" value="0.0000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
+									<Class name="int" field="FillCornerOrigin" value="0" type="{72039442-EB38-4D42-A1AD-CB68F7E0EEF6}"/>
+									<Class name="int" field="FillEdgeOrigin" value="0" type="{72039442-EB38-4D42-A1AD-CB68F7E0EEF6}"/>
+									<Class name="bool" field="FillClockwise" value="true" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
+								</Class>
+							</Class>
+							<Class name="bool" field="IsDependencyReady" value="true" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
+							<Class name="bool" field="IsRuntimeActive" value="true" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
+						</Class>
+						<Class name="AZ::Entity" field="element" version="2" type="{75651658-8663-478D-9090-2432DFCAFA44}">
+							<Class name="EntityId" field="Id" version="1" type="{6383F1D3-BB27-4E6B-A49A-6409B2059EAA}">
+								<Class name="AZ::u64" field="id" value="509288170940" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}"/>
+							</Class>
+							<Class name="AZStd::string" field="Name" value="StringB" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
+							<Class name="AZStd::vector&lt;AZ::Component*, allocator&gt;" field="Components" type="{13D58FF9-1088-5C69-9A1F-C2A144B57B78}">
+								<Class name="EditorOnlyEntityComponent" field="element" type="{22A16F1D-6D49-422D-AAE9-91AE45B5D3E7}">
+									<Class name="EditorComponentBase" field="BaseClass1" version="1" type="{D5346BD4-7F20-444E-B370-327ACD03D4A0}">
+										<Class name="AZ::Component" field="BaseClass1" type="{EDFCB2CF-F75D-43BE-B26B-F35821B29247}">
+											<Class name="AZ::u64" field="Id" value="11423924478304368427" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}"/>
+										</Class>
+									</Class>
+									<Class name="bool" field="IsEditorOnly" value="false" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
+								</Class>
+								<Class name="UiTransform2dComponent" field="element" version="3" type="{2751A5A5-3291-4A4D-9FC0-9CB0EB8D1DE6}">
+									<Class name="AZ::Component" field="BaseClass1" type="{EDFCB2CF-F75D-43BE-B26B-F35821B29247}">
+										<Class name="AZ::u64" field="Id" value="3389394107544437620" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}"/>
+									</Class>
+									<Class name="Anchors" field="Anchors" type="{65D4346C-FB16-4CB0-9BDC-1185B122C4A9}">
+										<Class name="float" field="left" value="0.5000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
+										<Class name="float" field="top" value="0.5000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
+										<Class name="float" field="right" value="0.5000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
+										<Class name="float" field="bottom" value="0.5000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
+									</Class>
+									<Class name="Offsets" field="Offsets" type="{F681BA9D-245C-4630-B20E-05DD752FAD57}">
+										<Class name="float" field="left" value="-50.0000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
+										<Class name="float" field="top" value="-32.7515411" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
+										<Class name="float" field="right" value="50.0000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
+										<Class name="float" field="bottom" value="67.2484589" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
+									</Class>
+									<Class name="Vector2" field="Pivot" value="0.5000000 0.5000000" type="{3D80F623-C85C-4741-90D0-E4E66164E6BF}"/>
+									<Class name="float" field="Rotation" value="0.0000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
+									<Class name="Vector2" field="Scale" value="1.0000000 1.0000000" type="{3D80F623-C85C-4741-90D0-E4E66164E6BF}"/>
+									<Class name="int" field="ScaleToDevice" value="0" type="{72039442-EB38-4D42-A1AD-CB68F7E0EEF6}"/>
+								</Class>
+								<Class name="UiElementComponent" field="element" version="3" type="{4A97D63E-CE7A-45B6-AAE4-102DB4334688}">
+									<Class name="AZ::Component" field="BaseClass1" type="{EDFCB2CF-F75D-43BE-B26B-F35821B29247}">
+										<Class name="AZ::u64" field="Id" value="304592595352478546" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}"/>
+									</Class>
+									<Class name="unsigned int" field="Id" value="6" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
+									<Class name="bool" field="IsEnabled" value="true" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
+									<Class name="bool" field="IsVisibleInEditor" value="true" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
+									<Class name="bool" field="IsSelectableInEditor" value="true" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
+									<Class name="bool" field="IsSelectedInEditor" value="false" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
+									<Class name="bool" field="IsExpandedInEditor" value="true" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
+									<Class name="AZStd::vector&lt;ChildEntityIdOrderEntry, allocator&gt;" field="ChildEntityIdOrder" type="{0DE523D9-AEAE-5FC4-9D40-967A2E2B8A62}"/>
+								</Class>
+								<Class name="UiTextComponent" field="element" version="9" type="{5B3FB2A7-5DC4-4033-A970-001CEC85B6C4}">
+									<Class name="AZ::Component" field="BaseClass1" type="{EDFCB2CF-F75D-43BE-B26B-F35821B29247}">
+										<Class name="AZ::u64" field="Id" value="1428988889681071293" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}"/>
+									</Class>
+									<Class name="AZStd::string" field="Text" value="String 2" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
+									<Class name="bool" field="MarkupEnabled" value="false" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
+									<Class name="Color" field="Color" value="1.0000000 1.0000000 1.0000000 1.0000000" type="{7894072A-9050-4F0F-901B-34B1A0D29417}"/>
+									<Class name="float" field="Alpha" value="1.0000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
+									<Class name="SimpleAssetReference&lt;FontAsset&gt;" field="FontFileName" version="1" type="{4953F80A-F59C-5F38-9E84-AFEB8F438CC4}">
+										<Class name="SimpleAssetReferenceBase" field="BaseClass1" version="1" type="{E16CA6C5-5C78-4AD9-8E9B-F8C1FB4D1DB8}">
+											<Class name="AZStd::string" field="AssetPath" value="default2048.font" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
+										</Class>
+									</Class>
+									<Class name="float" field="FontSize" value="32.0000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
+									<Class name="unsigned int" field="EffectIndex" value="0" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
+									<Class name="int" field="TextHAlignment" value="1" type="{72039442-EB38-4D42-A1AD-CB68F7E0EEF6}"/>
+									<Class name="int" field="TextVAlignment" value="1" type="{72039442-EB38-4D42-A1AD-CB68F7E0EEF6}"/>
+									<Class name="float" field="CharacterSpacing" value="0.0000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
+									<Class name="float" field="LineSpacing" value="0.0000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
+									<Class name="int" field="OverflowMode" value="0" type="{72039442-EB38-4D42-A1AD-CB68F7E0EEF6}"/>
+									<Class name="int" field="WrapTextSetting" value="0" type="{72039442-EB38-4D42-A1AD-CB68F7E0EEF6}"/>
+									<Class name="int" field="ShrinkToFit" value="0" type="{72039442-EB38-4D42-A1AD-CB68F7E0EEF6}"/>
+									<Class name="float" field="MinShrinkScale" value="0.0000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
+								</Class>
+							</Class>
+							<Class name="bool" field="IsDependencyReady" value="true" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
+							<Class name="bool" field="IsRuntimeActive" value="true" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
+						</Class>
+						<Class name="AZ::Entity" field="element" version="2" type="{75651658-8663-478D-9090-2432DFCAFA44}">
+							<Class name="EntityId" field="Id" version="1" type="{6383F1D3-BB27-4E6B-A49A-6409B2059EAA}">
+								<Class name="AZ::u64" field="id" value="504993203644" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}"/>
+							</Class>
+							<Class name="AZStd::string" field="Name" value="StringA" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
+							<Class name="AZStd::vector&lt;AZ::Component*, allocator&gt;" field="Components" type="{13D58FF9-1088-5C69-9A1F-C2A144B57B78}">
+								<Class name="EditorOnlyEntityComponent" field="element" type="{22A16F1D-6D49-422D-AAE9-91AE45B5D3E7}">
+									<Class name="EditorComponentBase" field="BaseClass1" version="1" type="{D5346BD4-7F20-444E-B370-327ACD03D4A0}">
+										<Class name="AZ::Component" field="BaseClass1" type="{EDFCB2CF-F75D-43BE-B26B-F35821B29247}">
+											<Class name="AZ::u64" field="Id" value="14981437203688256870" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}"/>
+										</Class>
+									</Class>
+									<Class name="bool" field="IsEditorOnly" value="false" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
+								</Class>
+								<Class name="UiTransform2dComponent" field="element" version="3" type="{2751A5A5-3291-4A4D-9FC0-9CB0EB8D1DE6}">
+									<Class name="AZ::Component" field="BaseClass1" type="{EDFCB2CF-F75D-43BE-B26B-F35821B29247}">
+										<Class name="AZ::u64" field="Id" value="13998432843499002612" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}"/>
+									</Class>
+									<Class name="Anchors" field="Anchors" type="{65D4346C-FB16-4CB0-9BDC-1185B122C4A9}">
+										<Class name="float" field="left" value="0.5000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
+										<Class name="float" field="top" value="0.5000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
+										<Class name="float" field="right" value="0.5000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
+										<Class name="float" field="bottom" value="0.5000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
+									</Class>
+									<Class name="Offsets" field="Offsets" type="{F681BA9D-245C-4630-B20E-05DD752FAD57}">
+										<Class name="float" field="left" value="-50.0000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
+										<Class name="float" field="top" value="-77.1047211" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
+										<Class name="float" field="right" value="50.0000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
+										<Class name="float" field="bottom" value="22.8952770" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
+									</Class>
+									<Class name="Vector2" field="Pivot" value="0.5000000 0.5000000" type="{3D80F623-C85C-4741-90D0-E4E66164E6BF}"/>
+									<Class name="float" field="Rotation" value="0.0000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
+									<Class name="Vector2" field="Scale" value="1.0000000 1.0000000" type="{3D80F623-C85C-4741-90D0-E4E66164E6BF}"/>
+									<Class name="int" field="ScaleToDevice" value="0" type="{72039442-EB38-4D42-A1AD-CB68F7E0EEF6}"/>
+								</Class>
+								<Class name="UiElementComponent" field="element" version="3" type="{4A97D63E-CE7A-45B6-AAE4-102DB4334688}">
+									<Class name="AZ::Component" field="BaseClass1" type="{EDFCB2CF-F75D-43BE-B26B-F35821B29247}">
+										<Class name="AZ::u64" field="Id" value="14496178371394383110" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}"/>
+									</Class>
+									<Class name="unsigned int" field="Id" value="5" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
+									<Class name="bool" field="IsEnabled" value="true" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
+									<Class name="bool" field="IsVisibleInEditor" value="true" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
+									<Class name="bool" field="IsSelectableInEditor" value="true" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
+									<Class name="bool" field="IsSelectedInEditor" value="false" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
+									<Class name="bool" field="IsExpandedInEditor" value="true" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
+									<Class name="AZStd::vector&lt;ChildEntityIdOrderEntry, allocator&gt;" field="ChildEntityIdOrder" type="{0DE523D9-AEAE-5FC4-9D40-967A2E2B8A62}"/>
+								</Class>
+								<Class name="UiTextComponent" field="element" version="9" type="{5B3FB2A7-5DC4-4033-A970-001CEC85B6C4}">
+									<Class name="AZ::Component" field="BaseClass1" type="{EDFCB2CF-F75D-43BE-B26B-F35821B29247}">
+										<Class name="AZ::u64" field="Id" value="6443965789941675950" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}"/>
+									</Class>
+									<Class name="AZStd::string" field="Text" value="String A" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
+									<Class name="bool" field="MarkupEnabled" value="false" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
+									<Class name="Color" field="Color" value="1.0000000 1.0000000 1.0000000 1.0000000" type="{7894072A-9050-4F0F-901B-34B1A0D29417}"/>
+									<Class name="float" field="Alpha" value="1.0000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
+									<Class name="SimpleAssetReference&lt;FontAsset&gt;" field="FontFileName" version="1" type="{4953F80A-F59C-5F38-9E84-AFEB8F438CC4}">
+										<Class name="SimpleAssetReferenceBase" field="BaseClass1" version="1" type="{E16CA6C5-5C78-4AD9-8E9B-F8C1FB4D1DB8}">
+											<Class name="AZStd::string" field="AssetPath" value="default1024.font" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
+										</Class>
+									</Class>
+									<Class name="float" field="FontSize" value="32.0000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
+									<Class name="unsigned int" field="EffectIndex" value="0" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
+									<Class name="int" field="TextHAlignment" value="1" type="{72039442-EB38-4D42-A1AD-CB68F7E0EEF6}"/>
+									<Class name="int" field="TextVAlignment" value="1" type="{72039442-EB38-4D42-A1AD-CB68F7E0EEF6}"/>
+									<Class name="float" field="CharacterSpacing" value="0.0000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
+									<Class name="float" field="LineSpacing" value="0.0000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
+									<Class name="int" field="OverflowMode" value="0" type="{72039442-EB38-4D42-A1AD-CB68F7E0EEF6}"/>
+									<Class name="int" field="WrapTextSetting" value="0" type="{72039442-EB38-4D42-A1AD-CB68F7E0EEF6}"/>
+									<Class name="int" field="ShrinkToFit" value="0" type="{72039442-EB38-4D42-A1AD-CB68F7E0EEF6}"/>
+									<Class name="float" field="MinShrinkScale" value="0.0000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
+								</Class>
+							</Class>
+							<Class name="bool" field="IsDependencyReady" value="true" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
+							<Class name="bool" field="IsRuntimeActive" value="true" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
+						</Class>
+					</Class>
+					<Class name="AZStd::list&lt;SliceReference, allocator&gt;" field="Prefabs" type="{DAD45EB6-5853-5645-B762-3A37F8775E12}"/>
+					<Class name="bool" field="IsDynamic" value="true" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
+					<Class name="AZ::Entity" field="MetadataEntity" version="2" type="{75651658-8663-478D-9090-2432DFCAFA44}">
+						<Class name="EntityId" field="Id" version="1" type="{6383F1D3-BB27-4E6B-A49A-6409B2059EAA}">
+							<Class name="AZ::u64" field="id" value="483518367164" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}"/>
+						</Class>
+						<Class name="AZStd::string" field="Name" value="" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
+						<Class name="AZStd::vector&lt;AZ::Component*, allocator&gt;" field="Components" type="{13D58FF9-1088-5C69-9A1F-C2A144B57B78}">
+							<Class name="SliceMetadataInfoComponent" field="element" version="2" type="{25EE4D75-8A17-4449-81F4-E561005BAABD}">
+								<Class name="AZ::Component" field="BaseClass1" type="{EDFCB2CF-F75D-43BE-B26B-F35821B29247}">
+									<Class name="AZ::u64" field="Id" value="6119851056583331912" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}"/>
+								</Class>
+								<Class name="AZStd::set&lt;EntityId, AZStd::less&lt;EntityId&gt;, allocator&gt;" field="AssociatedIds" type="{78E024C3-0143-53FC-B393-0675227839AF}"/>
+								<Class name="EntityId" field="ParentId" version="1" type="{6383F1D3-BB27-4E6B-A49A-6409B2059EAA}">
+									<Class name="AZ::u64" field="id" value="4294967295" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}"/>
+								</Class>
+								<Class name="AZStd::unordered_set&lt;EntityId, AZStd::hash&lt;EntityId&gt;, AZStd::equal_to&lt;EntityId&gt;, allocator&gt;" field="ChildrenIds" type="{6C8F8E52-AB4A-5C1F-8E56-9AC390290B94}"/>
+								<Class name="bool" field="PersistenceFlag" value="true" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
+							</Class>
+						</Class>
+						<Class name="bool" field="IsDependencyReady" value="false" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
+						<Class name="bool" field="IsRuntimeActive" value="true" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
+					</Class>
+					<Class name="DataFlagsPerEntity" field="DataFlagsForNewEntities" version="1" type="{57FE7B9E-B2AF-4F6F-9F8D-87F671E91C99}">
+						<Class name="AZStd::unordered_map&lt;EntityId, AZStd::unordered_map&lt;AddressType, unsigned char, AZStd::hash&lt;AddressType&gt;, AZStd::equal_to&lt;AddressType&gt;, allocator&gt;, AZStd::hash&lt;EntityId&gt;, AZStd::equal_to&lt;EntityId&gt;, allocator&gt;" field="EntityToDataFlags" type="{CAB9E1F5-761E-54B8-916E-E7FB597E5EDE}"/>
+					</Class>
+				</Class>
+			</Class>
+			<Class name="bool" field="IsDependencyReady" value="false" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
+			<Class name="bool" field="IsRuntimeActive" value="true" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
+		</Class>
+	</Class>
+</ObjectStream>
+

+ 3 - 0
AutomatedTesting/Gem/PythonTests/assetpipeline/asset_bundler_tests/assets/SeedWithDependencies/default1024.font

@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:ebb0258eb7bdd50e4687d589d8cd7cca0af47ddfdb26d63f53b7e930556b2864
+size 261

+ 3 - 0
AutomatedTesting/Gem/PythonTests/assetpipeline/asset_bundler_tests/assets/SeedWithDependencies/default2048.font

@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:922a3fd98211deab4ba49bf9eacbe1e0d09e1bea435ab2a97b8240b9d78d87c5
+size 262

+ 1 - 0
AutomatedTesting/Gem/PythonTests/assetpipeline/asset_bundler_tests/assets/TestAssets/multiple_corrupted_prefab/corrupted_prefab1.prefab

@@ -0,0 +1 @@
+This is a file created to act as a purposely corrupted prefab for use in test.

+ 1 - 0
AutomatedTesting/Gem/PythonTests/assetpipeline/asset_bundler_tests/assets/TestAssets/multiple_corrupted_prefab/corrupted_prefab2.prefab

@@ -0,0 +1 @@
+This is a file created to act as a purposely corrupted prefab for use in test.

+ 1 - 0
AutomatedTesting/Gem/PythonTests/assetpipeline/asset_bundler_tests/assets/TestAssets/multiple_working_prefab/working_prefab1.prefab

@@ -0,0 +1 @@
+{}

+ 1 - 0
AutomatedTesting/Gem/PythonTests/assetpipeline/asset_bundler_tests/assets/TestAssets/multiple_working_prefab/working_prefab2.prefab

@@ -0,0 +1 @@
+{}

+ 1 - 0
AutomatedTesting/Gem/PythonTests/assetpipeline/asset_bundler_tests/assets/TestAssets/single_corrupted_prefab/corrupted_prefab.prefab

@@ -0,0 +1 @@
+This is a file created to act as a purposely corrupted prefab for use in test.

+ 1 - 0
AutomatedTesting/Gem/PythonTests/assetpipeline/asset_bundler_tests/assets/TestAssets/single_working_prefab/working_prefab.prefab

@@ -0,0 +1 @@
+{}

+ 1 - 0
AutomatedTesting/Gem/PythonTests/assetpipeline/asset_bundler_tests/assets/TestAssets/single_working_prefab_override/working_prefab.prefab

@@ -0,0 +1 @@
+{ }

+ 3 - 0
AutomatedTesting/Gem/PythonTests/assetpipeline/asset_bundler_tests/assets/asset_bundler_test_assets/datfile_0.dat

@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:310e481a3de7fdce8565017090acde92f32734e5d0d79945d418ee55af163acf
+size 148

+ 3 - 0
AutomatedTesting/Gem/PythonTests/assetpipeline/asset_bundler_tests/assets/asset_bundler_test_assets/datfile_1.dat

@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:310e481a3de7fdce8565017090acde92f32734e5d0d79945d418ee55af163acf
+size 148

+ 3 - 0
AutomatedTesting/Gem/PythonTests/assetpipeline/asset_bundler_tests/assets/asset_bundler_test_assets/datfile_2.dat

@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:310e481a3de7fdce8565017090acde92f32734e5d0d79945d418ee55af163acf
+size 148

+ 3 - 0
AutomatedTesting/Gem/PythonTests/assetpipeline/asset_bundler_tests/assets/asset_bundler_test_assets/datfile_3.dat

@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:310e481a3de7fdce8565017090acde92f32734e5d0d79945d418ee55af163acf
+size 148

+ 3 - 0
AutomatedTesting/Gem/PythonTests/assetpipeline/asset_bundler_tests/assets/asset_bundler_test_assets/datfile_4.dat

@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:310e481a3de7fdce8565017090acde92f32734e5d0d79945d418ee55af163acf
+size 148

+ 3 - 0
AutomatedTesting/Gem/PythonTests/assetpipeline/asset_bundler_tests/assets/asset_bundler_test_assets/datfile_5.dat

@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:310e481a3de7fdce8565017090acde92f32734e5d0d79945d418ee55af163acf
+size 148

+ 1 - 0
AutomatedTesting/Gem/PythonTests/assetpipeline/asset_bundler_tests/assets/asset_bundler_test_assets/txtfile_0.txt

@@ -0,0 +1 @@
+I am a text file! this is my contents. I should be filter-able (if that's a word) by my ".txt" extension.

+ 1 - 0
AutomatedTesting/Gem/PythonTests/assetpipeline/asset_bundler_tests/assets/asset_bundler_test_assets/txtfile_1.txt

@@ -0,0 +1 @@
+I am a text file! this is my contents. I should be filter-able (if that's a word) by my ".txt" extension.

+ 1 - 0
AutomatedTesting/Gem/PythonTests/assetpipeline/asset_bundler_tests/assets/asset_bundler_test_assets/txtfile_2.txt

@@ -0,0 +1 @@
+I am a text file! this is my contents. I should be filter-able (if that's a word) by my ".txt" extension.

+ 1 - 0
AutomatedTesting/Gem/PythonTests/assetpipeline/asset_bundler_tests/assets/asset_bundler_test_assets/txtfile_3.txt

@@ -0,0 +1 @@
+I am a text file! this is my contents. I should be filter-able (if that's a word) by my ".txt" extension.

+ 1 - 0
AutomatedTesting/Gem/PythonTests/assetpipeline/asset_bundler_tests/assets/asset_bundler_test_assets/txtfile_4.txt

@@ -0,0 +1 @@
+I am a text file! this is my contents. I should be filter-able (if that's a word) by my ".txt" extension.

+ 1 - 0
AutomatedTesting/Gem/PythonTests/assetpipeline/asset_bundler_tests/assets/asset_bundler_test_assets/txtfile_5.txt

@@ -0,0 +1 @@
+I am a text file! this is my contents. I should be filter-able (if that's a word) by my ".txt" extension.

+ 0 - 0
AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/bundle_mode_in_editor_tests.py → AutomatedTesting/Gem/PythonTests/assetpipeline/asset_bundler_tests/bundle_mode_in_editor_tests.py


+ 4 - 0
AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/bundle_mode_tests.py → AutomatedTesting/Gem/PythonTests/assetpipeline/asset_bundler_tests/bundle_mode_tests.py

@@ -18,10 +18,12 @@ import ly_test_tools.log.log_monitor
 
 from ly_test_tools.o3de.editor_test_utils import compile_test_case_name_from_request
 
+from ..ap_fixtures.ap_setup_fixture import ap_setup_fixture
 from ..ap_fixtures.asset_processor_fixture import asset_processor as asset_processor
 from ..ap_fixtures.bundler_batch_setup_fixture import bundler_batch_setup_fixture as bundler_batch_helper
 from ..ap_fixtures.timeout_option_fixture import timeout_option_fixture as timeout
 
+
 @pytest.mark.SUITE_periodic
 @pytest.mark.parametrize('launcher_platform', ['windows_editor'])
 @pytest.mark.parametrize('project', ['AutomatedTesting'])
@@ -30,6 +32,8 @@ from ..ap_fixtures.timeout_option_fixture import timeout_option_fixture as timeo
 class TestBundleMode(object):
     def test_bundle_mode_with_levels_mounts_bundles_correctly(self, request, editor, level, launcher_platform,
                                                               asset_processor, workspace, bundler_batch_helper):
+        asset_processor.add_source_folder_assets("AutomatedTesting\\Levels\\TestDependenciesLevel")
+        asset_processor.batch_process()
         level_pak = os.path.join("levels", level, "TestDependenciesLevel.spawnable")
         bundles_folder = os.path.join(workspace.paths.project(), "Bundles")
         bundle_request_path = os.path.join(bundles_folder, "bundle.pak")

+ 0 - 0
AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/conftest.py → AutomatedTesting/Gem/PythonTests/assetpipeline/asset_bundler_tests/conftest.py


+ 0 - 22
AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/CMakeLists.txt

@@ -244,16 +244,6 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS)
 
 ## Periodic Tests ##
 
-    ly_add_pytest(
-        NAME APTests.AssetBundler
-        PATH ${CMAKE_CURRENT_LIST_DIR}/asset_bundler_batch_tests.py
-        TEST_SERIAL 
-        TEST_SUITE periodic
-        RUNTIME_DEPENDENCIES
-            AZ::AssetProcessor
-            AZ::AssetBundlerBatch
-    )
-
     ly_add_pytest(
         NAME APTests.MissingDependency
         PATH ${CMAKE_CURRENT_LIST_DIR}/missing_dependency_tests.py
@@ -263,16 +253,4 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS)
             AZ::AssetProcessorBatch
     )
 
-    ly_add_pytest(
-        NAME APTests.BundleMode
-        PATH ${CMAKE_CURRENT_LIST_DIR}/bundle_mode_tests.py
-        TEST_SERIAL
-        TEST_SUITE periodic
-        RUNTIME_DEPENDENCIES
-            AZ::AssetProcessor
-            AZ::AssetBundlerBatch
-            Legacy::Editor
-            AutomatedTesting.Assets
-    )
-
 endif()

+ 1 - 1
AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/asset_processor_gui_tests_2.py

@@ -319,7 +319,7 @@ class TestsAssetProcessorGUI_AllPlatforms(object):
         # Expected test asset sources and products
         # *.assetinfo and *.fbx files are not produced in cache, and file.fbx produces file.actor in cache
         expected_test_assets = ["Jack.fbx", "Jack.fbx.assetinfo"]
-        expected_cache_assets = ["jack.actor"]
+        expected_cache_assets = ["jack.actor", "jack.assetinfo.dbg", "jack.dbgsg", "jack.dbgsg.xml", "jack.dbgsg.json"]
 
         # Copy test assets to project folder and verify test assets folder exists
         test_assets_folder, cache_folder = asset_processor.prepare_test_environment(env["tests_dir"], "C24168802")

+ 1 - 1
AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/missing_dependency_tests.py

@@ -60,7 +60,7 @@ class TestsMissingDependencies_WindowsAndMac(object):
         self._missing_dep_helper = missing_dep_helper
         self._asset_processor.create_temp_asset_root()
         self._asset_processor.add_source_folder_assets(f"AutomatedTesting\\TestAssets")
-        missing_dep_helper.asset_db = os.path.join(asset_processor.temp_asset_root(), "Cache",
+        missing_dep_helper.asset_db = os.path.join(asset_processor.temp_asset_root(), self._workspace.project, "Cache",
                                                    "assetdb.sqlite")
         self._asset_processor.add_source_folder_assets(f"{self._workspace.project}\\Prefabs")
         self._asset_processor.add_source_folder_assets(f"{self._workspace.project}\\Materials")

+ 2 - 2
AutomatedTesting/Gem/PythonTests/assetpipeline/fbx_tests/fbx_tests.py

@@ -1090,9 +1090,9 @@ class TestsFBX_AllPlatforms(object):
             f'The following assets were expected to be in, but not found in cache: {str(missing_assets)}'
 
         # Load the asset database.
-        db_path = os.path.join(asset_processor.temp_asset_root(), "Cache",
+        db_path = os.path.join(asset_processor.temp_asset_root(), workspace.project, "Cache",
                                "assetdb.sqlite")
-        cache_root = os.path.dirname(os.path.join(asset_processor.temp_asset_root(), "Cache",
+        cache_root = os.path.dirname(os.path.join(asset_processor.temp_asset_root(), workspace.project, "Cache",
                                                   ASSET_PROCESSOR_PLATFORM_MAP[workspace.asset_processor_platform]))
 
         if blackbox_params.scene_debug_file:

+ 7 - 11
AutomatedTesting/Gem/PythonTests/assetpipeline/fbx_tests/pythonassetbuildertests.py

@@ -103,11 +103,7 @@ class TestsPythonAssetProcessing_APBatch(object):
         assert result, "AP Batch failed"
 
         # compute the cache path
-        platform = workspace.asset_processor_platform
-        cache_folder = asset_processor.temp_asset_root()
-        if platform == 'windows':
-            platform = 'pc'
-        cache_folder = os.path.join(cache_folder, 'Cache', platform)
+        cache_folder = asset_processor.project_test_cache_folder()
 
         # compute the file name to the debug file
         asset_debug_filename = os.path.join(cache_folder, debug_filename)
@@ -119,7 +115,7 @@ class TestsPythonAssetProcessing_APBatch(object):
     def test_ProcessSceneWithMetadata_SupportedMayaDataTypes_Work(self, workspace, ap_setup_fixture, asset_processor):
         # This test loads the debug output file for an FBX exported by Maya that has a few user defined properties
 
-        asset_dbgsg = 'userdefinedproperties/maya_with_attributes.dbgsg'
+        asset_dbgsg = 'maya_with_attributes.dbgsg'
         dbgsg_file = self.compute_udp_asset_debug_file(workspace, asset_processor, asset_dbgsg, ap_setup_fixture)
         assert self.find_user_defined_property(dbgsg_file, 'o3de_atom_lod: false'), "Malformed o3de_atom_lod value"
         assert self.find_user_defined_property(dbgsg_file, 'o3de_atom_material: 0'), "Malformed o3de_atom_material value"
@@ -129,7 +125,7 @@ class TestsPythonAssetProcessing_APBatch(object):
     def test_ProcessSceneWithMetadata_SupportedMaxDataTypes_Work(self, workspace, ap_setup_fixture, asset_processor):
         # This test loads the debug output file for an FBX exported by Max that has a few user defined properties
 
-        asset_dbgsg = 'userdefinedproperties/max_with_attributes.dbgsg'
+        asset_dbgsg = 'max_with_attributes.dbgsg'
         dbgsg_file = self.compute_udp_asset_debug_file(workspace, asset_processor, asset_dbgsg, ap_setup_fixture)
         assert self.find_user_defined_property(dbgsg_file, 'o3de_atom_material: 0'), "Malformed o3de_atom_material value"
         assert self.find_user_defined_property(dbgsg_file, 'o3de_phyx_lodY: 0.000000'), "Malformed o3de_phyx_lodY value"
@@ -140,7 +136,7 @@ class TestsPythonAssetProcessing_APBatch(object):
     def test_ProcessSceneWithMetadata_SupportedBlenderDataTypes_Work(self, workspace, ap_setup_fixture, asset_processor):
         # This test loads the debug output file for an FBX exported by Blender that has a few user defined properties
 
-        asset_dbgsg = 'userdefinedproperties/blender_with_attributes.dbgsg'
+        asset_dbgsg = 'blender_with_attributes.dbgsg'
         dbgsg_file = self.compute_udp_asset_debug_file(workspace, asset_processor, asset_dbgsg, ap_setup_fixture)
         assert self.find_user_defined_property(dbgsg_file, 'o3de_atom_material: 0'), "Malformed o3de_atom_material value"
         assert self.find_user_defined_property(dbgsg_file, 'o3de_default_lod: 0.000000'), "Malformed o3de_default_lod value"
@@ -150,7 +146,7 @@ class TestsPythonAssetProcessing_APBatch(object):
     def test_ProcessSceneWithMetadata_DebugSceneManifest_Work(self, workspace, ap_setup_fixture, asset_processor):
         # This test detects the debug .assetinfo file in the cahce folder
 
-        assetinfo_dbg = 'userdefinedproperties/blender_with_attributes.assetinfo.dbg'
+        assetinfo_dbg = 'blender_with_attributes.assetinfo.dbg'
         assetinfo_dbg_file = self.compute_udp_asset_debug_file(workspace, asset_processor, assetinfo_dbg, ap_setup_fixture)
         assert assetinfo_dbg_file, "The debug assetinfo file is missing"
 
@@ -159,8 +155,8 @@ class TestsPythonAssetProcessing_APBatch(object):
         # of a scene containing mesh nodes that have a common parent transform node
 
         assetinfo_dbg_list = {
-            "meshgroups/blender_with_common_parent.assetinfo.dbg",
-            "meshgroups/maya_with_common_parent.assetinfo.dbg"
+            "blender_with_common_parent.assetinfo.dbg",
+            "maya_with_common_parent.assetinfo.dbg"
         }
 
         expected_mesh_nodes = {

+ 3 - 3
Tools/LyTestTools/ly_test_tools/o3de/asset_processor.py

@@ -854,7 +854,7 @@ class AssetProcessor(object):
         self._function_name = function_name
         self._assets_source_folder = utils.prepare_test_assets(assets_path, function_name, test_folder)
         self._test_assets_source_folder = test_folder
-        self._cache_folder = os.path.join(self._temp_asset_root, 'Cache', cache_platform or
+        self._cache_folder = os.path.join(self._temp_asset_root, self._workspace.project,'Cache', cache_platform or
                                           ASSET_PROCESSOR_PLATFORM_MAP[self._workspace.asset_processor_platform],
                                           function_name.lower() if existing_function_name is None
                                           else existing_function_name)
@@ -958,7 +958,7 @@ class AssetProcessor(object):
         :return: path to project cache
         """
         asset_platform = asset_platform or ASSET_PROCESSOR_PLATFORM_MAP[self._workspace.asset_processor_platform]
-        return os.path.join(self._temp_asset_root, 'Cache', asset_platform.lower())
+        return os.path.join(self._temp_asset_root, self._workspace.project, 'Cache', asset_platform.lower())
 
     def temp_project_cache_path(self, project_name=None):
         """
@@ -969,7 +969,7 @@ class AssetProcessor(object):
 
         :return: path to project cache root folder
         """
-        return os.path.join(self._temp_asset_root, 'Cache')
+        return os.path.join(self._temp_asset_root, self._workspace.project, 'Cache')
 
     def clear_readonly(self, relative_dest):
         """