Bläddra i källkod

Mote file moves.

Signed-off-by: John <[email protected]>
John 3 år sedan
förälder
incheckning
e60a76af28
20 ändrade filer med 552 tillägg och 268 borttagningar
  1. 9 0
      Code/Tools/TestImpactFramework/Runtime/Native/CMakeLists.txt
  2. 87 0
      Code/Tools/TestImpactFramework/Runtime/Native/Code/CMakeLists.txt
  3. 13 13
      Code/Tools/TestImpactFramework/Runtime/Native/Code/Source/Artifact/Factory/TestImpactNativeTargetDescriptorFactory.cpp
  4. 2 2
      Code/Tools/TestImpactFramework/Runtime/Native/Code/Source/Artifact/Factory/TestImpactNativeTargetDescriptorFactory.h
  5. 7 9
      Code/Tools/TestImpactFramework/Runtime/Native/Code/Source/Artifact/Factory/TestImpactNativeTestTargetMetaMapFactory.cpp
  6. 2 4
      Code/Tools/TestImpactFramework/Runtime/Native/Code/Source/Artifact/Factory/TestImpactNativeTestTargetMetaMapFactory.h
  7. 3 3
      Code/Tools/TestImpactFramework/Runtime/Native/Code/Source/Artifact/Static/TestImpactNativeProductionTargetDescriptor.cpp
  8. 5 4
      Code/Tools/TestImpactFramework/Runtime/Native/Code/Source/Artifact/Static/TestImpactNativeProductionTargetDescriptor.h
  9. 18 0
      Code/Tools/TestImpactFramework/Runtime/Native/Code/Source/Artifact/Static/TestImpactNativeTargetDescriptor.cpp
  10. 24 0
      Code/Tools/TestImpactFramework/Runtime/Native/Code/Source/Artifact/Static/TestImpactNativeTargetDescriptor.h
  11. 42 0
      Code/Tools/TestImpactFramework/Runtime/Native/Code/Source/Artifact/Static/TestImpactNativeTargetDescriptorCompiler.cpp
  12. 8 6
      Code/Tools/TestImpactFramework/Runtime/Native/Code/Source/Artifact/Static/TestImpactNativeTargetDescriptorCompiler.h
  13. 3 3
      Code/Tools/TestImpactFramework/Runtime/Native/Code/Source/Artifact/Static/TestImpactNativeTestTargetDescriptor.cpp
  14. 6 6
      Code/Tools/TestImpactFramework/Runtime/Native/Code/Source/Artifact/Static/TestImpactNativeTestTargetDescriptor.h
  15. 5 6
      Code/Tools/TestImpactFramework/Runtime/Native/Code/Source/Artifact/Static/TestImpactNativeTestTargetMeta.h
  16. 0 41
      Code/Tools/TestImpactFramework/Runtime/Native/Code/Source/Artifact/Static/TestImpactTargetDescriptorCompiler.cpp
  17. 177 140
      Code/Tools/TestImpactFramework/Runtime/Native/Code/Source/TestImpactRuntime.cpp
  18. 70 31
      Code/Tools/TestImpactFramework/Runtime/Native/Code/Source/TestImpactRuntimeUtils.cpp
  19. 45 0
      Code/Tools/TestImpactFramework/Runtime/Native/Code/testimpactframework_runtime_native_files.cmake
  20. 26 0
      Code/Tools/TestImpactFramework/Runtime/Native/Code/testimpactframework_runtime_native_tests_files.cmake

+ 9 - 0
Code/Tools/TestImpactFramework/Runtime/Native/CMakeLists.txt

@@ -0,0 +1,9 @@
+#
+# 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
+#
+#
+
+add_subdirectory(Code)

+ 87 - 0
Code/Tools/TestImpactFramework/Runtime/Native/Code/CMakeLists.txt

@@ -0,0 +1,87 @@
+#
+# 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
+#
+#
+
+o3de_pal_dir(pal_dir ${CMAKE_CURRENT_LIST_DIR}/Source/Platform/${PAL_PLATFORM_NAME} ${O3DE_ENGINE_RESTRICTED_PATH} ${LY_ROOT_FOLDER})
+set(common_dir ${CMAKE_CURRENT_LIST_DIR}/Source/Platform/Common)
+
+ly_add_target(
+    NAME TestImpact.Runtime.Native.Static STATIC
+    NAMESPACE AZ
+    FILES_CMAKE
+        testimpactframework_runtime_native_files.cmake
+        ${pal_dir}/platform_${PAL_PLATFORM_NAME_LOWERCASE}_files.cmake
+    PLATFORM_INCLUDE_FILES
+        ${common_dir}/${PAL_TRAIT_COMPILER_ID}/testimpactframework_${PAL_TRAIT_COMPILER_ID_LOWERCASE}.cmake
+    INCLUDE_DIRECTORIES
+        PRIVATE
+            Source
+    BUILD_DEPENDENCIES
+        PRIVATE
+            AZ::TestImpact.Runtime.Common.Static
+        PUBLIC
+            AZ::AzCore
+            AZ::TestImpact.Runtime.Common.Headers
+)
+
+################################################################################
+# Tests
+################################################################################
+
+# Disabled: SPEC-7246
+#add_subdirectory(Tests/TestProcess)
+#add_subdirectory(Tests/TestTargetA)
+#add_subdirectory(Tests/TestTargetB)
+#add_subdirectory(Tests/TestTargetC)
+#add_subdirectory(Tests/TestTargetD)
+#
+#ly_add_target(
+#    NAME TestImpact.Runtime.Native.Tests ${PAL_TRAIT_TEST_TARGET_TYPE}
+#    NAMESPACE AZ
+#    FILES_CMAKE
+#        testimpactframework_runtime_native_tests_files.cmake
+#    INCLUDE_DIRECTORIES
+#        PRIVATE
+#            Include
+#            Source
+#            Tests
+#    BUILD_DEPENDENCIES
+#        PRIVATE
+#            AZ::AzTestShared
+#            AZ::AzTest
+#            AZ::TestImpact.Runtime.Native.Static
+#    RUNTIME_DEPENDENCIES
+#        AZ::AzTestRunner
+#        AZ::TestImpact.TestProcess.Console
+#        AZ::TestImpact.TestTargetA.Tests
+#        AZ::TestImpact.TestTargetB.Tests
+#        AZ::TestImpact.TestTargetC.Tests
+#        AZ::TestImpact.TestTargetD.Tests
+#    COMPILE_DEFINITIONS
+#        PRIVATE
+#            LY_TEST_IMPACT_AZ_TESTRUNNER_BIN="$<TARGET_FILE:AzTestRunner>"
+#            LY_TEST_IMPACT_TEST_PROCESS_BIN="$<TARGET_FILE:TestImpact.TestProcess.Console>"
+#            LY_TEST_IMPACT_TEST_TARGET_A_BIN="$<TARGET_FILE:TestImpact.TestTargetA.Tests>"
+#            LY_TEST_IMPACT_TEST_TARGET_B_BIN="$<TARGET_FILE:TestImpact.TestTargetB.Tests>"
+#            LY_TEST_IMPACT_TEST_TARGET_C_BIN="$<TARGET_FILE:TestImpact.TestTargetC.Tests>"
+#            LY_TEST_IMPACT_TEST_TARGET_D_BIN="$<TARGET_FILE:TestImpact.TestTargetD.Tests>"
+#            LY_TEST_IMPACT_TEST_TARGET_A_BASE_NAME="$<TARGET_FILE_BASE_NAME:TestImpact.TestTargetA.Tests>"
+#            LY_TEST_IMPACT_TEST_TARGET_B_BASE_NAME="$<TARGET_FILE_BASE_NAME:TestImpact.TestTargetB.Tests>"
+#            LY_TEST_IMPACT_TEST_TARGET_C_BASE_NAME="$<TARGET_FILE_BASE_NAME:TestImpact.TestTargetC.Tests>"
+#            LY_TEST_IMPACT_TEST_TARGET_D_BASE_NAME="$<TARGET_FILE_BASE_NAME:TestImpact.TestTargetD.Tests>"
+#            LY_TEST_IMPACT_TEST_TARGET_ENUMERATION_DIR="${GTEST_XML_OUTPUT_DIR}/TestImpact/Temp/Exclusive/Enum"
+#            LY_TEST_IMPACT_TEST_TARGET_RESULTS_DIR="${GTEST_XML_OUTPUT_DIR}/TestImpact/Temp/Exclusive/Result"
+#            LY_TEST_IMPACT_TEST_TARGET_COVERAGE_DIR="${GTEST_XML_OUTPUT_DIR}/TestImpact/Temp/Exclusive/Coverage"
+#            LY_TEST_IMPACT_INSTRUMENTATION_BIN="${LY_TEST_IMPACT_INSTRUMENTATION_BIN}"
+#            LY_TEST_IMPACT_MODULES_DIR="${CMAKE_BINARY_DIR}"
+#            LY_TEST_IMPACT_COVERAGE_SOURCES_DIR="${CMAKE_CURRENT_SOURCE_DIR}"
+#            LY_TEST_IMPACT_REPO_DIR="${CMAKE_SOURCE_DIR}"
+#)
+#
+#ly_add_googletest(
+#    NAME AZ::TestImpact.Runtime.Native.Tests
+#)

+ 13 - 13
Code/Tools/TestImpactFramework/Runtime/Native/Code/Source/Artifact/Factory/TestImpactNativeBuildTargetDescriptorFactory.cpp → Code/Tools/TestImpactFramework/Runtime/Native/Code/Source/Artifact/Factory/TestImpactNativeTargetDescriptorFactory.cpp

@@ -8,7 +8,7 @@
 
 #include <TestImpactFramework/TestImpactRuntime.h>
 
-#include <Artifact/Factory/TestImpactBuildTargetDescriptorFactory.h>
+#include <Artifact/Factory/TestImpactNativeTargetDescriptorFactory.h>
 #include <Artifact/TestImpactArtifactException.h>
 
 #include <AzCore/JSON/document.h>
@@ -60,7 +60,7 @@ namespace TestImpact
         return autogenSources;
     }
 
-    BuildTargetDescriptor BuildTargetDescriptorFactory(
+    NativeTargetDescriptor NativeTargetDescriptorFactory(
         const AZStd::string& buildTargetData,
         const AZStd::vector<AZStd::string>& staticSourceExtensionIncludes,
         const AZStd::vector<AZStd::string>& autogenInputExtensionIncludes,
@@ -93,7 +93,7 @@ namespace TestImpact
 
         AZ_TestImpact_Eval(!autogenMatcher.empty(), ArtifactException, "Autogen matcher cannot be empty");
 
-        BuildTargetDescriptor buildTargetDescriptor;
+        NativeTargetDescriptor NativeTargetDescriptor;
         rapidjson::Document buildTarget;
 
         if (buildTarget.Parse(buildTargetData.c_str()).HasParseError())
@@ -102,20 +102,20 @@ namespace TestImpact
         }
 
         const auto& target = buildTarget[Keys[TargetKey]];
-        buildTargetDescriptor.m_buildMetaData.m_name = target[Keys[NameKey]].GetString();
-        buildTargetDescriptor.m_buildMetaData.m_outputName = target[Keys[OutputNameKey]].GetString();
-        buildTargetDescriptor.m_buildMetaData.m_path = target["path"].GetString();
+        NativeTargetDescriptor.m_name = target[Keys[NameKey]].GetString();
+        NativeTargetDescriptor.m_outputName = target[Keys[OutputNameKey]].GetString();
+        NativeTargetDescriptor.m_path = target["path"].GetString();
 
-        AZ_TestImpact_Eval(!buildTargetDescriptor.m_buildMetaData.m_name.empty(), ArtifactException, "Target name cannot be empty");
+        AZ_TestImpact_Eval(!NativeTargetDescriptor.m_name.empty(), ArtifactException, "Target name cannot be empty");
         AZ_TestImpact_Eval(
-            !buildTargetDescriptor.m_buildMetaData.m_outputName.empty(), ArtifactException, "Target output name cannot be empty");
-        AZ_TestImpact_Eval(!buildTargetDescriptor.m_buildMetaData.m_path.empty(), ArtifactException, "Target path cannot be empty");
+            !NativeTargetDescriptor.m_outputName.empty(), ArtifactException, "Target output name cannot be empty");
+        AZ_TestImpact_Eval(!NativeTargetDescriptor.m_path.empty(), ArtifactException, "Target path cannot be empty");
 
         const auto& sources = buildTarget[Keys[SourcesKey]];
         const auto& staticSources = sources[Keys[StaticKey]].GetArray();
         if (!staticSources.Empty())
         {
-            buildTargetDescriptor.m_sources.m_staticSources = AZStd::vector<RepoPath>();
+            NativeTargetDescriptor.m_sources.m_staticSources = AZStd::vector<RepoPath>();
 
             for (const auto& source : staticSources)
             {
@@ -124,7 +124,7 @@ namespace TestImpact
                         staticSourceExtensionIncludes.begin(), staticSourceExtensionIncludes.end(), sourcePath.Extension().Native()) !=
                     staticSourceExtensionIncludes.end())
                 {
-                    buildTargetDescriptor.m_sources.m_staticSources.emplace_back(AZStd::move(sourcePath));
+                    NativeTargetDescriptor.m_sources.m_staticSources.emplace_back(AZStd::move(sourcePath));
                 }
             }
         }
@@ -157,9 +157,9 @@ namespace TestImpact
                 outputPaths.emplace_back(AZStd::move(RepoPath(source.GetString())));
             }
 
-            buildTargetDescriptor.m_sources.m_autogenSources = PairAutogenSources(inputPaths, outputPaths, autogenMatcher);
+            NativeTargetDescriptor.m_sources.m_autogenSources = PairAutogenSources(inputPaths, outputPaths, autogenMatcher);
         }
 
-        return buildTargetDescriptor;
+        return NativeTargetDescriptor;
     }
 } // namespace TestImpact

+ 2 - 2
Code/Tools/TestImpactFramework/Runtime/Native/Code/Source/Artifact/Factory/TestImpactNativeTargetDescriptorFactory.h

@@ -8,7 +8,7 @@
 
 #pragma once
 
-#include <Artifact/Static/TestImpactBuildTargetDescriptor.h>
+#include <Artifact/Static/TestImpactNativeTargetDescriptor.h>
 
 #include <AzCore/std/containers/vector.h>
 #include <AzCore/std/string/string.h>
@@ -21,7 +21,7 @@ namespace TestImpact
     //! @param autogenInputExtentsionIncludes The list of file extensions to include for autogen input sources.
     //! @param autogenMatcher The regex pattern used to match autogen input filenames with output filenames.
     //! @return The constructed build target artifact.
-    BuildTargetDescriptor BuildTargetDescriptorFactory(
+    NativeTargetDescriptor NativeTargetDescriptorFactory(
         const AZStd::string& buildTargetData,
         const AZStd::vector<AZStd::string>& staticSourceExtentsionIncludes,
         const AZStd::vector<AZStd::string>& autogenInputExtentsionIncludes,

+ 7 - 9
Code/Tools/TestImpactFramework/Runtime/Native/Code/Source/Artifact/Factory/TestImpactNativeTestTargetMetaMapFactory.cpp

@@ -8,16 +8,14 @@
 
 #include <TestImpactFramework/TestImpactUtils.h>
 
-#include <Artifact/Factory/TestImpactTestTargetMetaMapFactory.h>
+#include <Artifact/Factory/TestImpactNativeTestTargetMetaMapFactory.h>
 #include <Artifact/TestImpactArtifactException.h>
 
 #include <AzCore/JSON/document.h>
 
-#include <cstring>
-
 namespace TestImpact
 {
-    TestTargetMetaMap TestTargetMetaMapFactory(const AZStd::string& masterTestListData, SuiteType suiteType)
+    NativeTestTargetMetaMap NativeTestTargetMetaMapFactory(const AZStd::string& masterTestListData, SuiteType suiteType)
     {
         // Keys for pertinent JSON node and attribute names
         constexpr const char* Keys[] =
@@ -50,9 +48,9 @@ namespace TestImpact
             TimeoutKey
         };
 
-        AZ_TestImpact_Eval(!masterTestListData.empty(), ArtifactException, "test meta-data cannot be empty");
+        AZ_TestImpact_Eval(!masterTestListData.empty(), ArtifactException, "Test meta-data cannot be empty");
 
-        TestTargetMetaMap testMetas;
+        NativeTestTargetMetaMap testMetas;
         rapidjson::Document masterTestList;
 
         if (masterTestList.Parse(masterTestListData.c_str()).HasParseError())
@@ -63,7 +61,7 @@ namespace TestImpact
         const auto tests = masterTestList[Keys[GoogleKey]][Keys[TestKey]][Keys[TestsKey]].GetArray();
         for (const auto& test : tests)
         {
-            TestTargetMeta testMeta;
+            NativeTestTargetMeta testMeta;
             const auto testSuites = test[Keys[TestSuitesKey]].GetArray();
             for (const auto& suite : testSuites)
             {
@@ -71,9 +69,9 @@ namespace TestImpact
                 if (const auto suiteName = suite[Keys[SuiteKey]].GetString();
                     strcmp(SuiteTypeAsString(suiteType).c_str(), suiteName) == 0)
                 {
-                    testMeta.m_suite = suiteName;
+                    testMeta.m_suiteMeta.m_name = suiteName;
+                    testMeta.m_suiteMeta.m_timeout = AZStd::chrono::seconds{ suite[Keys[TimeoutKey]].GetUint() };
                     testMeta.m_customArgs = suite[Keys[CommandKey]].GetString();
-                    testMeta.m_timeout = AZStd::chrono::seconds{ suite[Keys[TimeoutKey]].GetUint() };
                     if (const auto buildTypeString = test[Keys[LaunchMethodKey]].GetString(); strcmp(buildTypeString, Keys[TestRunnerKey]) == 0)
                     {
                         testMeta.m_launchMethod = LaunchMethod::TestRunner;

+ 2 - 4
Code/Tools/TestImpactFramework/Runtime/Native/Code/Source/Artifact/Factory/TestImpactNativeTestTargetMetaMapFactory.h

@@ -9,9 +9,7 @@
 #pragma once
 
 #include <TestImpactFramework/TestImpactTestSequence.h>
-#include <Artifact/Static/TestImpactTestTargetMeta.h>
-
-#include <AzCore/std/containers/vector.h>
+#include <Artifact/Static/TestImpactNativeTestTargetMeta.h>
 
 namespace TestImpact
 {
@@ -19,5 +17,5 @@ namespace TestImpact
     //! @param masterTestListData The raw master test list data in JSON format.
     //! @param suiteType The suite type to select the target meta-data artifacts from.
     //! @return The constructed list of test target meta-data artifacts.
-    TestTargetMetaMap TestTargetMetaMapFactory(const AZStd::string& masterTestListData, SuiteType suiteType);
+    NativeTestTargetMetaMap NativeTestTargetMetaMapFactory(const AZStd::string& masterTestListData, SuiteType suiteType);
 } // namespace TestImpact

+ 3 - 3
Code/Tools/TestImpactFramework/Runtime/Native/Code/Source/Artifact/Static/TestImpactProductionTargetDescriptor.cpp → Code/Tools/TestImpactFramework/Runtime/Native/Code/Source/Artifact/Static/TestImpactNativeProductionTargetDescriptor.cpp

@@ -6,12 +6,12 @@
  *
  */
 
-#include <Artifact/Static/TestImpactProductionTargetDescriptor.h>
+#include <Artifact/Static/TestImpactNativeProductionTargetDescriptor.h>
 
 namespace TestImpact
 {
-    ProductionTargetDescriptor::ProductionTargetDescriptor(BuildTargetDescriptor&& buildTargetDescriptor)
-        : BuildTargetDescriptor(AZStd::move(buildTargetDescriptor))
+    NativeProductionTargetDescriptor::NativeProductionTargetDescriptor(NativeTargetDescriptor&& NativeTargetDescriptor)
+        : NativeTargetDescriptor(AZStd::move(NativeTargetDescriptor))
     {
     }
 } // namespace TestImpact

+ 5 - 4
Code/Tools/TestImpactFramework/Runtime/Native/Code/Source/Artifact/Static/TestImpactProductionTargetDescriptor.h → Code/Tools/TestImpactFramework/Runtime/Native/Code/Source/Artifact/Static/TestImpactNativeProductionTargetDescriptor.h

@@ -8,14 +8,15 @@
 
 #pragma once
 
-#include <Artifact/Static/TestImpactBuildTargetDescriptor.h>
+#include <Artifact/Static/TestImpactNativeTargetDescriptor.h>
 
 namespace TestImpact
 {
     //! Artifact produced by the target artifact compiler that represents a production build target in the repository.
-    struct ProductionTargetDescriptor
-        : public BuildTargetDescriptor
+    struct NativeProductionTargetDescriptor
+        : public NativeTargetDescriptor
     {
-        ProductionTargetDescriptor(BuildTargetDescriptor&& buildTarget);
+        NativeProductionTargetDescriptor() = default;
+        NativeProductionTargetDescriptor(NativeTargetDescriptor&& buildTarget);
     };
 } // namespace TestImpact

+ 18 - 0
Code/Tools/TestImpactFramework/Runtime/Native/Code/Source/Artifact/Static/TestImpactNativeTargetDescriptor.cpp

@@ -0,0 +1,18 @@
+/*
+ * 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
+ *
+ */
+
+#include <Artifact/Static/TestImpactNativeTargetDescriptor.h>
+
+namespace TestImpact
+{
+    NativeTargetDescriptor::NativeTargetDescriptor(TargetDescriptor&& targetDescriptor, const AZStd::string& outputName)
+        : TargetDescriptor(AZStd::move(targetDescriptor))
+        , m_outputName(outputName)
+    {
+    }
+} // namespace TestImpact

+ 24 - 0
Code/Tools/TestImpactFramework/Runtime/Native/Code/Source/Artifact/Static/TestImpactNativeTargetDescriptor.h

@@ -0,0 +1,24 @@
+/*
+ * 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
+ *
+ */
+
+#pragma once
+
+#include <Artifact/Static/TestImpactTargetDescriptor.h>
+
+namespace TestImpact
+{
+    //! Artifact produced by the build system for each build target. Contains source and output information about said targets.
+    struct NativeTargetDescriptor
+        : public TargetDescriptor
+    {
+        NativeTargetDescriptor() = default;
+        NativeTargetDescriptor(TargetDescriptor&& targetDescriptor, const AZStd::string& outputName);
+
+        AZStd::string m_outputName; //!< Output name (sans extension) of build target binary.
+    };
+} // namespace TestImpact

+ 42 - 0
Code/Tools/TestImpactFramework/Runtime/Native/Code/Source/Artifact/Static/TestImpactNativeTargetDescriptorCompiler.cpp

@@ -0,0 +1,42 @@
+/*
+ * 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
+ *
+ */
+
+#include <Artifact/Static/TestImpactNativeTargetDescriptorCompiler.h>
+#include <Artifact/TestImpactArtifactException.h>
+
+#include <AzCore/std/containers/unordered_map.h>
+
+namespace TestImpact
+{
+    AZStd::tuple<AZStd::vector<AZStd::unique_ptr<NativeProductionTargetDescriptor>>, AZStd::vector<AZStd::unique_ptr<NativeTestTargetDescriptor>>> CompileTargetDescriptors(
+        AZStd::vector<NativeTargetDescriptor>&& buildTargets, NativeTestTargetMetaMap&& NativeTestTargetMetaMap)
+    {
+        AZ_TestImpact_Eval(!buildTargets.empty(), ArtifactException, "Build target descriptor list cannot be null");
+        AZ_TestImpact_Eval(!NativeTestTargetMetaMap.empty(), ArtifactException, "Test target meta map cannot be null");
+
+        AZStd::tuple<AZStd::vector<AZStd::unique_ptr<NativeProductionTargetDescriptor>>, AZStd::vector<AZStd::unique_ptr<NativeTestTargetDescriptor>>>
+            outputTargets;
+        auto& [productionTargets, testTargets] = outputTargets;
+
+        for (auto&& buildTarget : buildTargets)
+        {
+            // If this build target has an associated test artifact then it is a test target, otherwise it is a production target
+            if (auto&& testTargetMeta = NativeTestTargetMetaMap.find(buildTarget.m_name);
+                testTargetMeta != NativeTestTargetMetaMap.end())
+            {
+                testTargets.emplace_back(AZStd::make_unique<NativeTestTargetDescriptor>(AZStd::move(buildTarget), AZStd::move(testTargetMeta->second)));
+            }
+            else
+            {
+                productionTargets.emplace_back(AZStd::make_unique<NativeProductionTargetDescriptor>(AZStd::move(buildTarget)));
+            }
+        }
+
+        return outputTargets;
+    }
+} // namespace TestImpact

+ 8 - 6
Code/Tools/TestImpactFramework/Runtime/Native/Code/Source/Artifact/Static/TestImpactTargetDescriptorCompiler.h → Code/Tools/TestImpactFramework/Runtime/Native/Code/Source/Artifact/Static/TestImpactNativeTargetDescriptorCompiler.h

@@ -8,11 +8,12 @@
 
 #pragma once
 
-#include <Artifact/Static/TestImpactProductionTargetDescriptor.h>
-#include <Artifact/Static/TestImpactTestTargetDescriptor.h>
-#include <Artifact/Static/TestImpactTestTargetMeta.h>
+#include <Artifact/Static/TestImpactNativeProductionTargetDescriptor.h>
+#include <Artifact/Static/TestImpactNativeTestTargetDescriptor.h>
+#include <Artifact/Static/TestImpactNativeTestTargetMeta.h>
 
 #include <AzCore/std/containers/vector.h>
+#include <AzCore/std/smart_ptr/unique_ptr.h>
 #include <AzCore/std/tuple.h>
 
 namespace TestImpact
@@ -20,8 +21,9 @@ namespace TestImpact
     //! Compiles the production target artifacts and test target artifactss from the supplied build target artifacts and test target meta
     //! map artifact.
     //! @param buildTargets The list of build target artifacts to be sorted into production and test artifact types.
-    //! @param testTargetMetaMap The map of test target meta artifacts containing the additional meta-data about each test target.
+    //! @param NativeTestTargetMetaMap The map of test target meta artifacts containing the additional meta-data about each test target.
     //! @return A tuple containing the production artifacts and test artifacts.
-    AZStd::tuple<AZStd::vector<ProductionTargetDescriptor>, AZStd::vector<TestTargetDescriptor>> CompileTargetDescriptors(
-        AZStd::vector<BuildTargetDescriptor>&& buildTargets, TestTargetMetaMap&& testTargetMetaMap);
+    AZStd::tuple<AZStd::vector<AZStd::unique_ptr<NativeProductionTargetDescriptor>>, AZStd::vector<AZStd::unique_ptr<NativeTestTargetDescriptor>>>
+    CompileTargetDescriptors(
+        AZStd::vector<NativeTargetDescriptor>&& buildTargets, NativeTestTargetMetaMap&& NativeTestTargetMetaMap);
 } // namespace TestImpact

+ 3 - 3
Code/Tools/TestImpactFramework/Runtime/Native/Code/Source/Artifact/Static/TestImpactTestTargetDescriptor.cpp → Code/Tools/TestImpactFramework/Runtime/Native/Code/Source/Artifact/Static/TestImpactNativeTestTargetDescriptor.cpp

@@ -6,12 +6,12 @@
  *
  */
 
-#include <Artifact/Static/TestImpactTestTargetDescriptor.h>
+#include <Artifact/Static/TestImpactNativeTestTargetDescriptor.h>
 
 namespace TestImpact
 {
-    TestTargetDescriptor::TestTargetDescriptor(BuildTargetDescriptor&& buildTarget, TestTargetMeta&& testTargetMeta)
-        : BuildTargetDescriptor(AZStd::move(buildTarget))
+    NativeTestTargetDescriptor::NativeTestTargetDescriptor(NativeTargetDescriptor&& buildTarget, NativeTestTargetMeta&& testTargetMeta)
+        : NativeTargetDescriptor(AZStd::move(buildTarget))
         , m_testMetaData(AZStd::move(testTargetMeta))
     {
     }

+ 6 - 6
Code/Tools/TestImpactFramework/Runtime/Native/Code/Source/Artifact/Static/TestImpactTestTargetDescriptor.h → Code/Tools/TestImpactFramework/Runtime/Native/Code/Source/Artifact/Static/TestImpactNativeTestTargetDescriptor.h

@@ -8,17 +8,17 @@
 
 #pragma once
 
-#include <Artifact/Static/TestImpactBuildTargetDescriptor.h>
-#include <Artifact/Static/TestImpactTestTargetMeta.h>
+#include <Artifact/Static/TestImpactNativeTargetDescriptor.h>
+#include <Artifact/Static/TestImpactNativeTestTargetMeta.h>
 
 namespace TestImpact
 {
     //! Artifact produced by the target artifact compiler that represents a test build target in the repository.
-    struct TestTargetDescriptor
-        : public BuildTargetDescriptor
+    struct NativeTestTargetDescriptor
+        : public NativeTargetDescriptor
     {
-        TestTargetDescriptor(BuildTargetDescriptor&& buildTarget, TestTargetMeta&& testTargetMeta);
+        NativeTestTargetDescriptor(NativeTargetDescriptor&& buildTarget, NativeTestTargetMeta&& testTargetMeta);
 
-        TestTargetMeta m_testMetaData;
+        NativeTestTargetMeta m_testMetaData;
     };
 } // namespace TestImpact

+ 5 - 6
Code/Tools/TestImpactFramework/Runtime/Native/Code/Source/Artifact/Static/TestImpactTestTargetMeta.h → Code/Tools/TestImpactFramework/Runtime/Native/Code/Source/Artifact/Static/TestImpactNativeTestTargetMeta.h

@@ -8,9 +8,9 @@
 
 #pragma once
 
+#include <Artifact/Static/TestImpactTestSuiteMeta.h>
+
 #include <AzCore/std/containers/unordered_map.h>
-#include <AzCore/std/string/string.h>
-#include <AzCore/std/chrono/chrono.h>
 
 namespace TestImpact
 {
@@ -22,14 +22,13 @@ namespace TestImpact
     };
 
     //! Artifact produced by the build system for each test target containing the additional meta-data about the test.
-    struct TestTargetMeta
+    struct NativeTestTargetMeta
     {
-        AZStd::string m_suite;
+        TestSuiteMeta m_suiteMeta;
         AZStd::string m_customArgs;
-        AZStd::chrono::milliseconds m_timeout = AZStd::chrono::milliseconds{ 0 };
         LaunchMethod m_launchMethod = LaunchMethod::TestRunner;
     };
 
     //! Map between test target name and test target meta-data.
-    using TestTargetMetaMap = AZStd::unordered_map<AZStd::string, TestTargetMeta>;
+    using NativeTestTargetMetaMap = AZStd::unordered_map<AZStd::string, NativeTestTargetMeta>;
 } // namespace TestImpact

+ 0 - 41
Code/Tools/TestImpactFramework/Runtime/Native/Code/Source/Artifact/Static/TestImpactTargetDescriptorCompiler.cpp

@@ -1,41 +0,0 @@
-/*
- * Copyright (c) Contributors to the Open 3D Engine Project.
- * For complete copyright and license terms please see the LICENSE at the root of this distribution.
- *
- * SPDX-License-Identifier: Apache-2.0 OR MIT
- *
- */
-
-#include <Artifact/Static/TestImpactTargetDescriptorCompiler.h>
-#include <Artifact/TestImpactArtifactException.h>
-
-#include <AzCore/std/containers/unordered_map.h>
-
-namespace TestImpact
-{
-    AZStd::tuple<AZStd::vector<ProductionTargetDescriptor>, AZStd::vector<TestTargetDescriptor>> CompileTargetDescriptors(
-        AZStd::vector<BuildTargetDescriptor>&& buildTargets, TestTargetMetaMap&& testTargetMetaMap)
-    {
-        AZ_TestImpact_Eval(!buildTargets.empty(), ArtifactException, "Build target descriptor list cannot be null");
-        AZ_TestImpact_Eval(!testTargetMetaMap.empty(), ArtifactException, "Test target meta map cannot be null");
-
-        AZStd::tuple<AZStd::vector<ProductionTargetDescriptor>, AZStd::vector<TestTargetDescriptor>> outputTargets;
-        auto& [productionTargets, testTargets] = outputTargets;
-
-        for (auto&& buildTarget : buildTargets)
-        {
-            // If this build target has an associated test artifact then it is a test target, otherwise it is a production target
-            if (auto&& testTargetMeta = testTargetMetaMap.find(buildTarget.m_buildMetaData.m_name);
-                testTargetMeta != testTargetMetaMap.end())
-            {
-                testTargets.emplace_back(TestTargetDescriptor(AZStd::move(buildTarget), AZStd::move(testTargetMeta->second)));
-            }
-            else
-            {
-                productionTargets.emplace_back(ProductionTargetDescriptor(AZStd::move(buildTarget)));
-            }
-        }
-
-        return outputTargets;
-    }
-} // namespace TestImpact

+ 177 - 140
Code/Tools/TestImpactFramework/Runtime/Native/Code/Source/TestImpactRuntime.cpp

@@ -11,11 +11,14 @@
 #include <TestImpactFramework/TestImpactRuntimeException.h>
 
 #include <TestImpactRuntimeUtils.h>
+#include <BuildTarget/Common/TestImpactBuildTarget.h>
 #include <Dependency/TestImpactDependencyException.h>
 #include <Dependency/TestImpactDynamicDependencyMap.h>
 #include <Dependency/TestImpactSourceCoveringTestsSerializer.h>
 #include <Dependency/TestImpactTestSelectorAndPrioritizer.h>
-#include <TestEngine/TestImpactTestEngine.h>
+#include <Target/Native/TestImpactNativeTestTarget.h>
+#include <Target/Native/TestImpactNativeProductionTarget.h>
+#include <TestEngine/Native/TestImpactNativeTestEngine.h>
 
 #include <AzCore/IO/SystemFile.h>
 
@@ -77,7 +80,7 @@ namespace TestImpact
             {
             }
 
-            void operator()(const TestEngineJob& testJob)
+            void operator()(const TestEngineJob<NativeTestTarget>& testJob)
             {
                 if (m_testCompleteCallback.has_value())
                 {
@@ -144,10 +147,10 @@ namespace TestImpact
         SuiteType suiteType,
         const Timer& sequenceTimer,
         const TestRunnerFunctor& testRunner,
-        const AZStd::vector<const TestTarget*>& includedSelectedTestTargets,
-        const AZStd::vector<const TestTarget*>& excludedSelectedTestTargets,
-        const AZStd::vector<const TestTarget*>& discardedTestTargets,
-        const AZStd::vector<const TestTarget*>& draftedTestTargets,
+        const AZStd::vector<const NativeTestTarget*>& includedSelectedTestTargets,
+        const AZStd::vector<const NativeTestTarget*>& excludedSelectedTestTargets,
+        const AZStd::vector<const NativeTestTarget*>& discardedTestTargets,
+        const AZStd::vector<const NativeTestTarget*>& draftedTestTargets,
         const AZStd::optional<AZStd::chrono::milliseconds>& testTargetTimeout,
         const AZStd::optional<AZStd::chrono::milliseconds>& globalTimeout,
         AZStd::optional<ImpactAnalysisTestSequenceStartCallback> testSequenceStartCallback,
@@ -176,7 +179,7 @@ namespace TestImpact
         TestRunCompleteCallbackHandler testRunCompleteHandler(totalNumTestRuns, testCompleteCallback);
 
         const auto gatherTestRunData = [&sequenceTimer, &testRunner, &testRunCompleteHandler, &globalTimeout]
-        (const AZStd::vector<const TestTarget*>& testsTargets, TestRunData<TestJob>& testRunData)
+        (const AZStd::vector<const NativeTestTarget*>& testsTargets, TestRunData<TestJob>& testRunData)
         {
             const Timer testRunTimer;
             testRunData.m_relativeStartTime = testRunTimer.GetStartTimePointRelative(sequenceTimer);
@@ -243,8 +246,9 @@ namespace TestImpact
 
     Runtime::Runtime(
         RuntimeConfig&& config,
-        AZStd::optional<RepoPath> dataFile,
-        AZStd::vector<AZStd::string> testsToExclude,
+        const AZStd::optional<RepoPath>& dataFile,
+        [[maybe_unused]] const AZStd::optional<RepoPath>& previousRunDataFile,
+        const AZStd::vector<TargetConfig::ExcludedTarget>& testsToExclude,
         SuiteType suiteFilter,
         Policy::ExecutionFailure executionFailurePolicy,
         Policy::FailedTestCoverage failedTestCoveragePolicy,
@@ -263,28 +267,36 @@ namespace TestImpact
         , m_targetOutputCapture(targetOutputCapture)
         , m_maxConcurrency(maxConcurrency.value_or(AZStd::thread::hardware_concurrency()))
     {
-        // Construct the dynamic dependency map from the build target descriptors
-        m_dynamicDependencyMap = ConstructDynamicDependencyMap(suiteFilter, m_config.m_buildTargetDescriptor, m_config.m_testTargetMeta);
+        // Construct the build targets from the build target descriptors
+        m_buildTargets = ConstructNativeBuildTargetList(suiteFilter, m_config.m_NativeTargetDescriptor, m_config.m_testTargetMeta);
+
+        // Construct the dynamic dependency map from the build targets
+        m_dynamicDependencyMap = AZStd::make_unique<DynamicDependencyMap<NativeTestTarget, NativeProductionTarget>>(m_buildTargets.get());
 
         // Construct the test selector and prioritizer from the dependency graph data (NOTE: currently not implemented)
-        m_testSelectorAndPrioritizer = AZStd::make_unique<TestSelectorAndPrioritizer>(m_dynamicDependencyMap.get(), DependencyGraphDataMap{});
+        m_testSelectorAndPrioritizer =
+            AZStd::make_unique<TestSelectorAndPrioritizer<NativeTestTarget, NativeProductionTarget>>(m_dynamicDependencyMap.get(), DependencyGraphDataMap{});
 
         // Construct the target exclude list from the exclude file if provided, otherwise use target configuration data
         if (!testsToExclude.empty())
         {
             // Construct using data from excludeTestFile
-            m_testTargetExcludeList = ConstructTestTargetExcludeList(
-                m_dynamicDependencyMap->GetTestTargetList(), testsToExclude);
+            m_regularTestTargetExcludeList =
+                ConstructTestTargetExcludeList(m_dynamicDependencyMap->GetBuildTargets()->GetTestTargetList(), testsToExclude);
+            m_instrumentedTestTargetExcludeList =
+                ConstructTestTargetExcludeList(m_dynamicDependencyMap->GetBuildTargets()->GetTestTargetList(), testsToExclude);
         }
         else
         {
             // Construct using data from config file.
-            m_testTargetExcludeList =
-                ConstructTestTargetExcludeList(m_dynamicDependencyMap->GetTestTargetList(), m_config.m_target.m_excludedTestTargets);
+            m_regularTestTargetExcludeList = ConstructTestTargetExcludeList(
+                m_dynamicDependencyMap->GetBuildTargets()->GetTestTargetList(), m_config.m_target.m_excludedRegularTestTargets);
+            m_instrumentedTestTargetExcludeList = ConstructTestTargetExcludeList(
+                m_dynamicDependencyMap->GetBuildTargets()->GetTestTargetList(), m_config.m_target.m_excludedInstrumentedTestTargets);
         }
 
         // Construct the test engine with the workspace path and launcher binaries
-        m_testEngine = AZStd::make_unique<TestEngine>(
+        m_testEngine = AZStd::make_unique<NativeTestEngine>(
             m_config.m_repo.m_root,
             m_config.m_target.m_outputDirectory,
             m_config.m_workspace.m_temp.m_enumerationCacheDirectory,
@@ -312,6 +324,19 @@ namespace TestImpact
             {
                 m_dynamicDependencyMap->ReplaceSourceCoverage(tiaData);
                 m_hasImpactAnalysisData = true;
+
+                // Enumerate new test targets
+                //const auto testTargetsWithNoEnumeration = m_dynamicDependencyMap->GetNotCoveringTests();
+                //if (!testTargetsWithNoEnumeration.empty())
+                //{
+                //    m_testEngine->UpdateEnumerationCache(
+                //        testTargetsWithNoEnumeration,
+                //        Policy::ExecutionFailure::Ignore,
+                //        Policy::TestFailure::Continue,
+                //        AZStd::nullopt,
+                //        AZStd::nullopt,
+                //        AZStd::nullopt);
+                //}
             }
         }
         catch (const DependencyException& e)
@@ -332,59 +357,62 @@ namespace TestImpact
 
     Runtime::~Runtime() = default;
 
-    void Runtime::EnumerateMutatedTestTargets(const ChangeDependencyList& changeDependencyList)
-    {
-        AZStd::vector<const TestTarget*> testTargets;
-        const auto addMutatedTestTargetsToEnumerationList = [&testTargets](const AZStd::vector<SourceDependency>& sourceDependencies)
-        {
-            for (const auto& sourceDependency : sourceDependencies)
-            {
-                for (const auto& parentTarget : sourceDependency.GetParentTargets())
-                {
-                    AZStd::visit([&testTargets]([[maybe_unused]] auto&& target)
-                    {
-                        if constexpr (IsTestTarget<decltype(target)>)
-                        {
-                            testTargets.push_back(target);
-                        }
-                    }, parentTarget.GetTarget());
-                }
-            }
-        };
-
-        // Gather all of the test targets that have had any of their sources modified
-        addMutatedTestTargetsToEnumerationList(changeDependencyList.GetCreateSourceDependencies());
-        addMutatedTestTargetsToEnumerationList(changeDependencyList.GetUpdateSourceDependencies());
-        addMutatedTestTargetsToEnumerationList(changeDependencyList.GetDeleteSourceDependencies());
-
-        // Enumerate the mutated test targets to ensure their enumeration caches are up to date
-        if (!testTargets.empty())
-        {
-            m_testEngine->UpdateEnumerationCache(
-                testTargets,
-                Policy::ExecutionFailure::Ignore,
-                Policy::TestFailure::Continue,
-                AZStd::nullopt,
-                AZStd::nullopt,
-                AZStd::nullopt);
-        }
-    }
-
-    AZStd::pair<AZStd::vector<const TestTarget*>, AZStd::vector<const TestTarget*>> Runtime::SelectCoveringTestTargets(
+    //void Runtime::EnumerateMutatedTestTargets(const ChangeDependencyList& changeDependencyList)
+    //{
+    //    AZStd::vector<const NativeTestTarget*> testTargets;
+    //    const auto addMutatedTestTargetsToEnumerationList = [this, &testTargets](const AZStd::vector<SourceDependency>& sourceDependencies)
+    //    {
+    //        for (const auto& sourceDependency : sourceDependencies)
+    //        {
+    //            for (const auto& parentTarget : sourceDependency.GetParentTargets())
+    //            {
+    //                AZStd::visit([&testTargets]([[maybe_unused]] auto&& target)
+    //                {
+    //                    if constexpr (IsTestTarget<decltype(target)>)
+    //                    {
+    //                        testTargets.push_back(target);
+    //                    }
+    //                }, parentTarget.GetBuildTarget());
+    //            }
+    //        }
+    //    };
+    //
+    //    // Gather all of the test targets that have had any of their sources modified
+    //    addMutatedTestTargetsToEnumerationList(changeDependencyList.GetCreateSourceDependencies());
+    //    addMutatedTestTargetsToEnumerationList(changeDependencyList.GetUpdateSourceDependencies());
+    //    addMutatedTestTargetsToEnumerationList(changeDependencyList.GetDeleteSourceDependencies());
+    //
+    //    // Enumerate the mutated test targets to ensure their enumeration caches are up to date
+    //    if (!testTargets.empty())
+    //    {
+    //        m_testEngine->UpdateEnumerationCache(
+    //            testTargets,
+    //            Policy::ExecutionFailure::Ignore,
+    //            Policy::TestFailure::Continue,
+    //            AZStd::nullopt,
+    //            AZStd::nullopt,
+    //            AZStd::nullopt);
+    //    }
+    //}
+
+    AZStd::pair<AZStd::vector<const NativeTestTarget*>, AZStd::vector<const NativeTestTarget*>> Runtime::SelectCoveringTestTargets(
         const ChangeList& changeList,
         Policy::TestPrioritization testPrioritizationPolicy)
     {
-        AZStd::vector<const TestTarget*> discardedTestTargets;
+        AZStd::vector<const NativeTestTarget*> discardedTestTargets;
 
         // Select and prioritize the test targets pertinent to this change list
         const auto changeDependencyList = m_dynamicDependencyMap->ApplyAndResoveChangeList(changeList, m_integrationFailurePolicy);
         const auto selectedTestTargets = m_testSelectorAndPrioritizer->SelectTestTargets(changeDependencyList, testPrioritizationPolicy);
 
         // Populate a set with the selected test targets so that we can infer the discarded test target not selected for this change list
-        const AZStd::unordered_set<const TestTarget*> selectedTestTargetSet(selectedTestTargets.begin(), selectedTestTargets.end());
+        const AZStd::unordered_set<const NativeTestTarget*> selectedTestTargetSet(selectedTestTargets.begin(), selectedTestTargets.end());
+
+        // Update the enumeration caches of mutated targets regardless of the current sharding policy
+        //EnumerateMutatedTestTargets(changeDependencyList);
 
         // The test targets in the main list not in the selected test target set are the test targets not selected for this change list
-        for (const auto& testTarget : m_dynamicDependencyMap->GetTestTargetList().GetTargets())
+        for (const auto& testTarget : m_dynamicDependencyMap->GetBuildTargets()->GetTestTargetList().GetTargets())
         {
             if (!selectedTestTargetSet.contains(&testTarget))
             {
@@ -395,52 +423,32 @@ namespace TestImpact
         return { selectedTestTargets, discardedTestTargets };
     }
 
-    AZStd::pair<AZStd::vector<const TestTarget*>, AZStd::vector<const TestTarget*>> Runtime::SelectTestTargetsByExcludeList(
-        AZStd::vector<const TestTarget*> testTargets) const
-    {
-        AZStd::vector<const TestTarget*> includedTestTargets;
-        AZStd::vector<const TestTarget*> excludedTestTargets;
-
-        if (m_testTargetExcludeList.empty())
-        {
-            return { testTargets, {} };
-        }
-
-        for (const auto& testTarget : testTargets)
-        {
-            if (!m_testTargetExcludeList.contains(testTarget))
-            {
-                includedTestTargets.push_back(testTarget);
-            }
-            else
-            {
-                excludedTestTargets.push_back(testTarget);
-            }
-        }
-
-        return { includedTestTargets, excludedTestTargets };
-    }
-
     void Runtime::ClearDynamicDependencyMapAndRemoveExistingFile()
     {
         m_dynamicDependencyMap->ClearAllSourceCoverage();
         DeleteFile(m_sparTiaFile);
     }
 
-    SourceCoveringTestsList Runtime::CreateSourceCoveringTestFromTestCoverages(const AZStd::vector<TestEngineInstrumentedRun>& jobs)
+    //! Prunes the existing coverage for the specified jobs and creates the consolidated source covering tests list from the
+    //! test engine instrumented run jobs.
+    SourceCoveringTestsList CreateSourceCoveringTestFromTestCoverages(
+        DynamicDependencyMap<NativeTestTarget, NativeProductionTarget>* dynamicDependencyMap,
+        const AZStd::vector<TestEngineInstrumentedRun<NativeTestTarget, TestCoverage>>& jobs,
+        Policy::FailedTestCoverage failedTestCoveragePolicy,
+        const RepoPath& repoRoot)
     {
         AZStd::unordered_map<AZStd::string, AZStd::unordered_set<AZStd::string>> coverage;
         for (const auto& job : jobs)
         {
             // First we must remove any existing coverage for the test target so as to not end up with source remnants from previous
             // coverage that is no longer covered by this revision of the test target
-            m_dynamicDependencyMap->RemoveTestTargetFromSourceCoverage(job.GetTestTarget());
+            dynamicDependencyMap->RemoveTestTargetFromSourceCoverage(job.GetTestTarget());
 
             // Next we will update the coverage of test targets that completed (with or without failures), unless the failed test coverage
             // policy dictates we should instead discard the coverage of test targets with failing tests
             const auto testResult = job.GetTestResult();
 
-            if (m_failedTestCoveragePolicy == Policy::FailedTestCoverage::Discard && testResult == Client::TestRunResult::TestFailures)
+            if (failedTestCoveragePolicy == Policy::FailedTestCoverage::Discard && testResult == Client::TestRunResult::TestFailures)
             {
                 // Discard the coverage for this job
                 continue;
@@ -452,14 +460,14 @@ namespace TestImpact
                 {
                     // Passing tests should have coverage data, otherwise something is very wrong
                     AZ_TestImpact_Eval(
-                        job.GetTestCoverge().has_value(),
+                        job.GetCoverge().has_value(),
                         RuntimeException,
                         AZStd::string::format(
                             "Test target '%s' completed its test run successfully but produced no coverage data. Command string: '%s'",
                             job.GetTestTarget()->GetName().c_str(), job.GetCommandString().c_str()));
                 }
 
-                if (!job.GetTestCoverge().has_value())
+                if (!job.GetCoverge().has_value())
                 {
                     // When a test run completes with failing tests but produces no coverage artifact that's typically a sign of the
                     // test aborting due to an unhandled exception, in which case ignore it and let it be picked up in the failure report
@@ -467,7 +475,7 @@ namespace TestImpact
                 }
 
                 // Add the sources covered by this test target to the coverage map
-                for (const auto& source : job.GetTestCoverge().value().GetSourcesCovered())
+                for (const auto& source : job.GetCoverge().value().GetSourcesCovered())
                 {
                     coverage[source.String()].insert(job.GetTestTarget()->GetName());
                 }
@@ -480,10 +488,10 @@ namespace TestImpact
         {
             // Check to see whether this source is inside the repo or not (not a perfect check but weeds out the obvious non-repo sources)
             if (const auto sourcePath = RepoPath(source);
-                sourcePath.IsRelativeTo(m_config.m_repo.m_root))
+                sourcePath.IsRelativeTo(repoRoot))
             {
                 sourceCoveringTests.push_back(
-                    SourceCoveringTests(RepoPath(sourcePath.LexicallyRelative(m_config.m_repo.m_root)), AZStd::move(testTargets)));
+                    SourceCoveringTests(RepoPath(sourcePath.LexicallyRelative(repoRoot)), AZStd::move(testTargets)));
             }
             else
             {
@@ -494,25 +502,34 @@ namespace TestImpact
         return SourceCoveringTestsList(AZStd::move(sourceCoveringTests));
     }
 
-    void Runtime::UpdateAndSerializeDynamicDependencyMap(const AZStd::vector<TestEngineInstrumentedRun>& jobs)
+    //! Updates the dynamic dependency map and serializes the entire map to disk.
+    [[nodiscard]] AZStd::optional<bool> UpdateAndSerializeDynamicDependencyMap(
+        DynamicDependencyMap<NativeTestTarget, NativeProductionTarget>* dynamicDependencyMap,
+        const AZStd::vector<TestEngineInstrumentedRun<NativeTestTarget, TestCoverage>>& jobs,
+        Policy::FailedTestCoverage failedTestCoveragePolicy,
+        Policy::IntegrityFailure integrationFailurePolicy,
+        const RepoPath& repoRoot,
+        const RepoPath& sparTiaFile)
     {
         try
         {
-            const auto sourceCoverageTestsList = CreateSourceCoveringTestFromTestCoverages(jobs);
+            const auto sourceCoverageTestsList =
+                CreateSourceCoveringTestFromTestCoverages(dynamicDependencyMap, jobs, failedTestCoveragePolicy, repoRoot);
+
             if (sourceCoverageTestsList.GetNumSources() == 0)
             {
-                return;
+                return AZStd::nullopt;
             }
 
-            m_dynamicDependencyMap->ReplaceSourceCoverage(sourceCoverageTestsList);
-            const auto sparTia = m_dynamicDependencyMap->ExportSourceCoverage();
+            dynamicDependencyMap->ReplaceSourceCoverage(sourceCoverageTestsList);
+            const auto sparTia = dynamicDependencyMap->ExportSourceCoverage();
             const auto sparTiaData = SerializeSourceCoveringTestsList(sparTia);
-            WriteFileContents<RuntimeException>(sparTiaData, m_sparTiaFile);
-            m_hasImpactAnalysisData = true;
+            WriteFileContents<RuntimeException>(sparTiaData, sparTiaFile);
+            return true;
         }
         catch(const RuntimeException& e)
         {
-            if (m_integrationFailurePolicy == Policy::IntegrityFailure::Abort)
+            if (integrationFailurePolicy == Policy::IntegrityFailure::Abort)
             {
                 throw e;
             }
@@ -521,6 +538,8 @@ namespace TestImpact
                 AZ_Error(LogCallSite, false, e.what());
             }
         }
+
+        return AZStd::nullopt;
     }
 
     PolicyStateBase Runtime::GeneratePolicyStateBase() const
@@ -562,20 +581,19 @@ namespace TestImpact
         AZStd::optional<TestRunCompleteCallback> testCompleteCallback)
     {
         const Timer sequenceTimer;
-        AZStd::vector<const TestTarget*> includedTestTargets;
-        AZStd::vector<const TestTarget*> excludedTestTargets;
+        AZStd::vector<const NativeTestTarget*> includedTestTargets;
+        AZStd::vector<const NativeTestTarget*> excludedTestTargets;
         
         // Separate the test targets into those that are excluded by either the test filter or exclusion list and those that are not
-        for (const auto& testTarget : m_dynamicDependencyMap->GetTestTargetList().GetTargets())
+        for (const auto& testTarget : m_dynamicDependencyMap->GetBuildTargets()->GetTestTargetList().GetTargets())
         {
-            if (!m_testTargetExcludeList.contains(&testTarget))
+            if (m_regularTestTargetExcludeList->IsTestTargetFullyExcluded(&testTarget))
             {
-                includedTestTargets.push_back(&testTarget);
+                excludedTestTargets.push_back(&testTarget);
             }
             else
             {
-                // Test targets on the exclude list are excluded
-                excludedTestTargets.push_back(&testTarget);
+                includedTestTargets.push_back(&testTarget);
             }
         }
 
@@ -592,7 +610,6 @@ namespace TestImpact
         const Timer testRunTimer;
         const auto [result, testJobs] = m_testEngine->RegularRun(
             includedTestTargets,
-            m_testShardingPolicy,
             m_executionFailurePolicy,
             m_testFailurePolicy,
             m_targetOutputCapture,
@@ -633,7 +650,7 @@ namespace TestImpact
         const Timer sequenceTimer;
 
         // Draft in the test targets that have no coverage entries in the dynamic dependency map
-        const AZStd::vector<const TestTarget*> draftedTestTargets = m_dynamicDependencyMap->GetNotCoveringTests();
+        const AZStd::vector<const NativeTestTarget*> draftedTestTargets = m_dynamicDependencyMap->GetNotCoveringTests();
 
         const auto selectCoveringTestTargetsAndPruneDraftedFromDiscarded =
             [this, &draftedTestTargets, &changeList, testPrioritizationPolicy]()
@@ -642,9 +659,9 @@ namespace TestImpact
             const auto [selectedTestTargets, discardedTestTargets] =
                 SelectCoveringTestTargets(changeList, testPrioritizationPolicy);
 
-            const AZStd::unordered_set<const TestTarget*> draftedTestTargetsSet(draftedTestTargets.begin(), draftedTestTargets.end());
+            const AZStd::unordered_set<const NativeTestTarget*> draftedTestTargetsSet(draftedTestTargets.begin(), draftedTestTargets.end());
 
-            AZStd::vector<const TestTarget*> discardedNotDraftedTestTargets;
+            AZStd::vector<const NativeTestTarget*> discardedNotDraftedTestTargets;
             for (const auto* testTarget : discardedTestTargets)
             {
                 if (!draftedTestTargetsSet.count(testTarget))
@@ -659,18 +676,18 @@ namespace TestImpact
         const auto [selectedTestTargets, discardedTestTargets] = selectCoveringTestTargetsAndPruneDraftedFromDiscarded();
 
         // The subset of selected test targets that are not on the configuration's exclude list and those that are
-        auto [includedSelectedTestTargets, excludedSelectedTestTargets] = SelectTestTargetsByExcludeList(selectedTestTargets);
+        const auto [includedSelectedTestTargets, excludedSelectedTestTargets] =
+            SelectTestTargetsByExcludeList(*m_instrumentedTestTargetExcludeList, selectedTestTargets);
 
         // Functor for running instrumented test targets
         const auto instrumentedTestRun =
             [this, &testTargetTimeout](
-                const AZStd::vector<const TestTarget*>& testsTargets,
+                const AZStd::vector<const NativeTestTarget*>& testsTargets,
                 TestRunCompleteCallbackHandler& testRunCompleteHandler,
                 AZStd::optional<AZStd::chrono::milliseconds> globalTimeout)
         {
             return m_testEngine->InstrumentedRun(
                 testsTargets,
-                m_testShardingPolicy,
                 m_executionFailurePolicy,
                 m_integrationFailurePolicy,
                 m_testFailurePolicy,
@@ -683,13 +700,12 @@ namespace TestImpact
         // Functor for running uninstrumented test targets
         const auto regularTestRun =
             [this, &testTargetTimeout](
-                const AZStd::vector<const TestTarget*>& testsTargets,
+                const AZStd::vector<const NativeTestTarget*>& testsTargets,
                  TestRunCompleteCallbackHandler& testRunCompleteHandler,
                 AZStd::optional<AZStd::chrono::milliseconds> globalTimeout)
         {
             return m_testEngine->RegularRun(
                 testsTargets,
-                m_testShardingPolicy,
                 m_executionFailurePolicy,
                 m_testFailurePolicy,
                 m_targetOutputCapture,
@@ -700,10 +716,16 @@ namespace TestImpact
 
         if (dynamicDependencyMapPolicy == Policy::DynamicDependencyMap::Update)
         {
-            AZStd::optional<AZStd::function<void(const AZStd::vector<TestEngineInstrumentedRun>& jobs)>> updateCoverage =
-                [this](const AZStd::vector<TestEngineInstrumentedRun>& jobs)
+            AZStd::optional<AZStd::function<void(const AZStd::vector<TestEngineInstrumentedRun<NativeTestTarget, TestCoverage>>& jobs)>>
+                updateCoverage = [this](const AZStd::vector<TestEngineInstrumentedRun<NativeTestTarget, TestCoverage>>& jobs)
             {
-                UpdateAndSerializeDynamicDependencyMap(jobs);
+                m_hasImpactAnalysisData = UpdateAndSerializeDynamicDependencyMap(
+                    m_dynamicDependencyMap.get(),
+                    jobs,
+                    m_failedTestCoveragePolicy,
+                    m_integrationFailurePolicy,
+                    m_config.m_repo.m_root,
+                    m_sparTiaFile).value_or(m_hasImpactAnalysisData);
             };
 
             return ImpactAnalysisTestSequenceWrapper(
@@ -740,7 +762,8 @@ namespace TestImpact
                 testSequenceStartCallback,
                 testSequenceEndCallback,
                 testCompleteCallback,
-                AZStd::optional<AZStd::function<void(const AZStd::vector<TestEngineRegularRun>& jobs)>>{ AZStd::nullopt });
+                AZStd::optional<AZStd::function<void(const AZStd::vector<TestEngineRegularRun<NativeTestTarget>>& jobs)>>{
+                    AZStd::nullopt });
         }
     }
 
@@ -754,21 +777,23 @@ namespace TestImpact
         AZStd::optional<TestRunCompleteCallback> testCompleteCallback)
     {
         const Timer sequenceTimer;
-        TestRunData<TestEngineInstrumentedRun> selectedTestRunData, draftedTestRunData;
-        TestRunData<TestEngineRegularRun> discardedTestRunData;
+        TestRunData<TestEngineInstrumentedRun<NativeTestTarget, TestCoverage>> selectedTestRunData, draftedTestRunData;
+        TestRunData<TestEngineRegularRun<NativeTestTarget>> discardedTestRunData;
         AZStd::optional<AZStd::chrono::milliseconds> sequenceTimeout = globalTimeout;
 
         // Draft in the test targets that have no coverage entries in the dynamic dependency map
-        AZStd::vector<const TestTarget*> draftedTestTargets = m_dynamicDependencyMap->GetNotCoveringTests();
+        AZStd::vector<const NativeTestTarget*> draftedTestTargets = m_dynamicDependencyMap->GetNotCoveringTests();
 
         // The test targets that were selected for the change list by the dynamic dependency map and the test targets that were not
         const auto [selectedTestTargets, discardedTestTargets] = SelectCoveringTestTargets(changeList, testPrioritizationPolicy);
 
         // The subset of selected test targets that are not on the configuration's exclude list and those that are
-        auto [includedSelectedTestTargets, excludedSelectedTestTargets] = SelectTestTargetsByExcludeList(selectedTestTargets);
+        const auto [includedSelectedTestTargets, excludedSelectedTestTargets] =
+            SelectTestTargetsByExcludeList(*m_instrumentedTestTargetExcludeList, selectedTestTargets);
 
         // The subset of discarded test targets that are not on the configuration's exclude list and those that are
-        auto [includedDiscardedTestTargets, excludedDiscardedTestTargets] = SelectTestTargetsByExcludeList(discardedTestTargets);
+        const auto [includedDiscardedTestTargets, excludedDiscardedTestTargets] =
+            SelectTestTargetsByExcludeList(*m_regularTestTargetExcludeList, discardedTestTargets);
 
         // Extract the client facing representation of selected, discarded and drafted test targets
         const Client::TestRunSelection selectedTests(
@@ -789,11 +814,10 @@ namespace TestImpact
         
         // Functor for running instrumented test targets
         const auto instrumentedTestRun =
-            [this, &testTargetTimeout, &sequenceTimeout, &testRunCompleteHandler](const AZStd::vector<const TestTarget*>& testsTargets)
+            [this, &testTargetTimeout, &sequenceTimeout, &testRunCompleteHandler](const AZStd::vector<const NativeTestTarget*>& testsTargets)
         {
             return m_testEngine->InstrumentedRun(
                 testsTargets,
-                m_testShardingPolicy,
                 m_executionFailurePolicy,
                 m_integrationFailurePolicy,
                 m_testFailurePolicy,
@@ -805,11 +829,10 @@ namespace TestImpact
 
         // Functor for running uninstrumented test targets
         const auto regularTestRun =
-            [this, &testTargetTimeout, &sequenceTimeout, &testRunCompleteHandler](const AZStd::vector<const TestTarget*>& testsTargets)
+            [this, &testTargetTimeout, &sequenceTimeout, &testRunCompleteHandler](const AZStd::vector<const NativeTestTarget*>& testsTargets)
         {
             return m_testEngine->RegularRun(
                 testsTargets,
-                m_testShardingPolicy,
                 m_executionFailurePolicy,
                 m_testFailurePolicy,
                 m_targetOutputCapture,
@@ -820,7 +843,7 @@ namespace TestImpact
 
         // Functor for running instrumented test targets
         const auto gatherTestRunData = [&sequenceTimer]
-        (const AZStd::vector<const TestTarget*>& testsTargets, const auto& testRunner, auto& testRunData)
+        (const AZStd::vector<const NativeTestTarget*>& testsTargets, const auto& testRunner, auto& testRunData)
         {
             const Timer testRunTimer;
             testRunData.m_relativeStartTime = testRunTimer.GetStartTimePointRelative(sequenceTimer);
@@ -894,7 +917,14 @@ namespace TestImpact
             (*testSequenceEndCallback)(sequenceReport);
         }
 
-        UpdateAndSerializeDynamicDependencyMap(ConcatenateVectors(selectedTestRunData.m_jobs, draftedTestRunData.m_jobs));
+        m_hasImpactAnalysisData = UpdateAndSerializeDynamicDependencyMap(
+                    m_dynamicDependencyMap.get(),
+                    ConcatenateVectors(selectedTestRunData.m_jobs, draftedTestRunData.m_jobs),
+                    m_failedTestCoveragePolicy,
+                    m_integrationFailurePolicy,
+                    m_config.m_repo.m_root,
+                    m_sparTiaFile).value_or(m_hasImpactAnalysisData);
+
         return sequenceReport;
     }
 
@@ -906,19 +936,19 @@ namespace TestImpact
         AZStd::optional<TestRunCompleteCallback> testCompleteCallback)
     {
         const Timer sequenceTimer;
-        AZStd::vector<const TestTarget*> includedTestTargets;
-        AZStd::vector<const TestTarget*> excludedTestTargets;
+        AZStd::vector<const NativeTestTarget*> includedTestTargets;
+        AZStd::vector<const NativeTestTarget*> excludedTestTargets;
 
         // Separate the test targets into those that are excluded by either the test filter or exclusion list and those that are not
-        for (const auto& testTarget : m_dynamicDependencyMap->GetTestTargetList().GetTargets())
+        for (const auto& testTarget : m_dynamicDependencyMap->GetBuildTargets()->GetTestTargetList().GetTargets())
         {
-            if (!m_testTargetExcludeList.contains(&testTarget))
+            if (m_instrumentedTestTargetExcludeList->IsTestTargetFullyExcluded(&testTarget))
             {
-                includedTestTargets.push_back(&testTarget);
+                excludedTestTargets.push_back(&testTarget);
             }
             else
             {
-                excludedTestTargets.push_back(&testTarget);
+                includedTestTargets.push_back(&testTarget);
             }
         }
 
@@ -935,7 +965,6 @@ namespace TestImpact
         const Timer testRunTimer;
         const auto [result, testJobs] = m_testEngine->InstrumentedRun(
             includedTestTargets,
-            m_testShardingPolicy,
             m_executionFailurePolicy,
             m_integrationFailurePolicy,
             m_testFailurePolicy,
@@ -962,7 +991,15 @@ namespace TestImpact
         }
 
         ClearDynamicDependencyMapAndRemoveExistingFile();
-        UpdateAndSerializeDynamicDependencyMap(testJobs);
+
+         m_hasImpactAnalysisData = UpdateAndSerializeDynamicDependencyMap(
+                    m_dynamicDependencyMap.get(),
+                    testJobs,
+                    m_failedTestCoveragePolicy,
+                    m_integrationFailurePolicy,
+                    m_config.m_repo.m_root,
+                    m_sparTiaFile).value_or(m_hasImpactAnalysisData);
+
         return sequenceReport;
     }
 

+ 70 - 31
Code/Tools/TestImpactFramework/Runtime/Native/Code/Source/TestImpactRuntimeUtils.cpp

@@ -10,68 +10,107 @@
 #include <TestImpactFramework/TestImpactRuntimeException.h>
 
 #include <TestImpactRuntimeUtils.h>
-#include <Artifact/Factory/TestImpactTestTargetMetaMapFactory.h>
-#include <Artifact/Factory/TestImpactBuildTargetDescriptorFactory.h>
-#include <Artifact/Static/TestImpactTargetDescriptorCompiler.h>
+#include <Artifact/Factory/TestImpactNativeTestTargetMetaMapFactory.h>
+#include <Artifact/Factory/TestImpactNativeTargetDescriptorFactory.h>
+#include <Artifact/Static/TestImpactNativeTargetDescriptorCompiler.h>
+#include <Target/Native/TestImpactNativeTestTarget.h>
+#include <Target/Native/TestImpactNativeProductionTarget.h>
 
 #include <filesystem>
 
 namespace TestImpact
 {
-    TestTargetMetaMap ReadTestTargetMetaMapFile(SuiteType suiteFilter, const RepoPath& testTargetMetaConfigFile)
+    NativeTestTargetMetaMap ReadNativeTestTargetMetaMapFile(SuiteType suiteFilter, const RepoPath& testTargetMetaConfigFile)
     {
         const auto masterTestListData = ReadFileContents<RuntimeException>(testTargetMetaConfigFile);
-        return TestTargetMetaMapFactory(masterTestListData, suiteFilter);
+        return NativeTestTargetMetaMapFactory(masterTestListData, suiteFilter);
     }
 
-    AZStd::vector<BuildTargetDescriptor> ReadBuildTargetDescriptorFiles(const BuildTargetDescriptorConfig& buildTargetDescriptorConfig)
+    AZStd::vector<NativeTargetDescriptor> ReadNativeTargetDescriptorFiles(const NativeTargetDescriptorConfig& NativeTargetDescriptorConfig)
     {
-        AZStd::vector<BuildTargetDescriptor> buildTargetDescriptors;
-        for (const auto& buildTargetDescriptorFile : std::filesystem::directory_iterator(buildTargetDescriptorConfig.m_mappingDirectory.c_str()))
+        AZStd::vector<NativeTargetDescriptor> NativeTargetDescriptors;
+        for (const auto& NativeTargetDescriptorFile : std::filesystem::directory_iterator(NativeTargetDescriptorConfig.m_mappingDirectory.c_str()))
         {
-            const auto buildTargetDescriptorContents = ReadFileContents<RuntimeException>(buildTargetDescriptorFile.path().string().c_str());
-            auto buildTargetDescriptor = BuildTargetDescriptorFactory(
-                buildTargetDescriptorContents,
-                buildTargetDescriptorConfig.m_staticInclusionFilters,
-                buildTargetDescriptorConfig.m_inputInclusionFilters,
-                buildTargetDescriptorConfig.m_inputOutputPairer);
-            buildTargetDescriptors.emplace_back(AZStd::move(buildTargetDescriptor));
+            const auto NativeTargetDescriptorContents = ReadFileContents<RuntimeException>(NativeTargetDescriptorFile.path().string().c_str());
+            auto NativeTargetDescriptor = NativeTargetDescriptorFactory(
+                NativeTargetDescriptorContents,
+                NativeTargetDescriptorConfig.m_staticInclusionFilters,
+                NativeTargetDescriptorConfig.m_inputInclusionFilters,
+                NativeTargetDescriptorConfig.m_inputOutputPairer);
+            NativeTargetDescriptors.emplace_back(AZStd::move(NativeTargetDescriptor));
         }
 
-        return buildTargetDescriptors;
+        return NativeTargetDescriptors;
     }
 
-    AZStd::unique_ptr<DynamicDependencyMap> ConstructDynamicDependencyMap(
+     AZStd::unique_ptr<BuildTargetList<NativeTestTarget, NativeProductionTarget>> ConstructNativeBuildTargetList(
         SuiteType suiteFilter,
-        const BuildTargetDescriptorConfig& buildTargetDescriptorConfig,
+        const NativeTargetDescriptorConfig& NativeTargetDescriptorConfig,
         const TestTargetMetaConfig& testTargetMetaConfig)
     {
-        auto testTargetmetaMap = ReadTestTargetMetaMapFile(suiteFilter, testTargetMetaConfig.m_metaFile);
-        auto buildTargetDescriptors = ReadBuildTargetDescriptorFiles(buildTargetDescriptorConfig);
-        auto buildTargets = CompileTargetDescriptors(AZStd::move(buildTargetDescriptors), AZStd::move(testTargetmetaMap));
+        auto NativeTestTargetMetaMap = ReadNativeTestTargetMetaMapFile(suiteFilter, testTargetMetaConfig.m_metaFile);
+        auto NativeTargetDescriptors = ReadNativeTargetDescriptorFiles(NativeTargetDescriptorConfig);
+        auto buildTargets = CompileTargetDescriptors(AZStd::move(NativeTargetDescriptors), AZStd::move(NativeTestTargetMetaMap));
         auto&& [productionTargets, testTargets] = buildTargets;
-        return AZStd::make_unique<DynamicDependencyMap>(AZStd::move(productionTargets), AZStd::move(testTargets));
+        return AZStd::make_unique<BuildTargetList<NativeTestTarget, NativeProductionTarget>>(
+            AZStd::move(testTargets), AZStd::move(productionTargets));
     }
 
-    AZStd::unordered_set<const TestTarget*> ConstructTestTargetExcludeList(
-        const TestTargetList& testTargets, const AZStd::vector<AZStd::string>& excludedTestTargets)
+    AZStd::unique_ptr<TestTargetExclusionList> ConstructTestTargetExcludeList(
+        const TargetList<NativeTestTarget>& testTargets, const AZStd::vector<TargetConfig::ExcludedTarget>& excludedTestTargets)
     {
-        AZStd::unordered_set<const TestTarget*> testTargetExcludeList;
-        for (const auto& testTargetName : excludedTestTargets)
+        AZStd::unordered_map<const NativeTestTarget*, AZStd::vector<AZStd::string>> testTargetExcludeList;
+        for (const auto& excludedTestTarget : excludedTestTargets)
         {
-            if (const auto* testTarget = testTargets.GetTarget(testTargetName); testTarget != nullptr)
+            if (const auto* testTarget = testTargets.GetTarget(excludedTestTarget.m_name);
+                testTarget != nullptr)
             {
-                testTargetExcludeList.insert(testTarget);
+                testTargetExcludeList[testTarget] = excludedTestTarget.m_excludedTests;
             }
         }
 
-        return testTargetExcludeList;
+        return AZStd::make_unique<TestTargetExclusionList>(AZStd::move(testTargetExcludeList));
     }
 
-    AZStd::vector<AZStd::string> ExtractTestTargetNames(const AZStd::vector<const TestTarget*>& testTargets)
+    AZStd::pair<
+        AZStd::vector<const NativeTestTarget*>,
+        AZStd::vector<const NativeTestTarget*>>
+    SelectTestTargetsByExcludeList(
+        const TestTargetExclusionList& testTargetExcludeList,
+        const AZStd::vector<const NativeTestTarget*>& testTargets)
+    {
+        AZStd::vector<const NativeTestTarget*> includedTestTargets;
+        AZStd::vector<const NativeTestTarget*> excludedTestTargets;
+
+        if (testTargetExcludeList.IsEmpty())
+        {
+            return { testTargets, {} };
+        }
+
+        for (const auto& testTarget : testTargets)
+        {
+            if (const auto* excludedTests = testTargetExcludeList.GetExcludedTestsForTarget(testTarget);
+                excludedTests != nullptr && excludedTests->empty())
+            {
+                // If the test filter is empty, the entire suite is excluded
+                excludedTestTargets.push_back(testTarget);
+            }
+            else
+            {
+                includedTestTargets.push_back(testTarget);
+            }
+        }
+
+        return { includedTestTargets, excludedTestTargets };
+    }
+
+    AZStd::vector<AZStd::string> ExtractTestTargetNames(
+        const AZStd::vector<const NativeTestTarget*>& testTargets)
     {
         AZStd::vector<AZStd::string> testNames;
-        AZStd::transform(testTargets.begin(), testTargets.end(), AZStd::back_inserter(testNames), [](const TestTarget* testTarget)
+        AZStd::transform(
+            testTargets.begin(), testTargets.end(), AZStd::back_inserter(testNames),
+            [](const NativeTestTarget* testTarget)
         {
             return testTarget->GetName();
         });

+ 45 - 0
Code/Tools/TestImpactFramework/Runtime/Native/Code/testimpactframework_runtime_native_files.cmake

@@ -0,0 +1,45 @@
+#
+# 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
+#
+#
+
+set(FILES
+    Source/Artifact/Factory/TestImpactNativeTargetDescriptorFactory.cpp
+    Source/Artifact/Factory/TestImpactNativeTargetDescriptorFactory.h
+    Source/Artifact/Factory/TestImpactNativeTestTargetMetaMapFactory.cpp
+    Source/Artifact/Factory/TestImpactNativeTestTargetMetaMapFactory.h
+    Source/Artifact/Static/TestImpactNativeTargetDescriptor.cpp
+    Source/Artifact/Static/TestImpactNativeTargetDescriptor.h
+    Source/Artifact/Static/TestImpactNativeTargetDescriptorCompiler.cpp
+    Source/Artifact/Static/TestImpactNativeTargetDescriptorCompiler.h
+    Source/Artifact/Static/TestImpactNativeProductionTargetDescriptor.cpp
+    Source/Artifact/Static/TestImpactNativeProductionTargetDescriptor.h
+    Source/Artifact/Static/TestImpactNativeTestTargetMeta.h
+    Source/Artifact/Static/TestImpactNativeTestTargetDescriptor.cpp
+    Source/Artifact/Static/TestImpactNativeTestTargetDescriptor.h
+    Source/Target/Native/TestImpactNativeTarget.cpp
+    Source/Target/Native/TestImpactNativeTarget.h
+    Source/Target/Native/TestImpactNativeProductionTarget.cpp
+    Source/Target/Native/TestImpactNativeProductionTarget.h
+    Source/Target/Native/TestImpactNativeTestTarget.cpp
+    Source/Target/Native/TestImpactNativeTestTarget.h
+    Source/TestRunner/Native/TestImpactNativeInstrumentedTestRunner.h
+    Source/TestRunner/Native/TestImpactNativeRegularTestRunner.h
+    Source/TestRunner/Native/TestImpactNativeTestEnumerator.h
+    Source/TestRunner/Native/Job/TestImpactNativeTestRunJobData.h
+    Source/TestEngine/Native/TestImpactNativeTestEngine.cpp
+    Source/TestEngine/Native/TestImpactNativeTestEngine.h
+    Source/TestEngine/Native/TestImpactNativeErrorCodeChecker.cpp
+    Source/TestEngine/Native/TestImpactNativeErrorCodeChecker.h
+    Source/TestEngine/Native/TestImpactNativeTestTargetExtension.h
+    Source/TestEngine/Native/Job/TestImpactNativeTestJobInfoUtils.cpp
+    Source/TestEngine/Native/Job/TestImpactNativeTestJobInfoUtils.h
+    Source/TestEngine/Native/Job/TestImpactNativeTestJobInfoGenerator.cpp
+    Source/TestEngine/Native/Job/TestImpactNativeTestJobInfoGenerator.h
+    Source/TestImpactRuntime.cpp
+    Source/TestImpactRuntimeUtils.cpp
+    Source/TestImpactTestTargetExclusionList.cpp
+)

+ 26 - 0
Code/Tools/TestImpactFramework/Runtime/Native/Code/testimpactframework_runtime_native_tests_files.cmake

@@ -0,0 +1,26 @@
+#
+# 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
+#
+#
+
+set(FILES
+Tests/Artifact/TestImpactNativeTargetDescriptorCompilerTest.cpp
+Tests/Artifact/TestImpactNativeTargetDescriptorFactoryTest.cpp
+Tests/Artifact/TestImpactNativeTestTargetMetaMapFactoryTest.cpp
+Tests/Process/TestImpactProcessSchedulerTest.cpp
+Tests/Dependency/TestImpactNativeDynamicDependencyMapTest.cpp
+Tests/TestRunner/TestImpactTestNativeEnumeratorTest.cpp
+Tests/TestRunner/TestImpactTestNativeRunnerTest.cpp
+Tests/TestRunner/TestImpactNativeInstrumentedTestRunnerTest.cpp
+Tests/TestEngine/TestImpactNativeTestEngineTest.cpp
+Tests/TestEngine/TestImpactNativeTestJobInfoGeneratorTest.cpp
+Tests/TestImpactNativeRuntimeTestMain.cpp
+Tests/TestImpactNativeMicroRepo.cpp
+Tests/TestImpactNativeMicroRepo.h
+Tests/TestImpactNativeRuntimeTest.cpp
+Tests/TestImpactNativeTestUtils.cpp
+Tests/TestImpactNativeTestUtils.h
+)