Merge pull request #12 from aws-lumberyard-dev/TIF/DynamicDependencyMap
Add dynamic dependency map.
This commit is contained in:
@@ -20,4 +20,4 @@ ly_add_target(
|
||||
BUILD_DEPENDENCIES
|
||||
PRIVATE
|
||||
AZ::TestImpact.Runtime.Static
|
||||
)
|
||||
)
|
||||
+4
-5
@@ -12,9 +12,8 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AzCore/IO/Path/Path.h>
|
||||
#include <AzCore/std/string/string.h>
|
||||
#include <AzCore/std/containers/vector.h>
|
||||
#include <AzCore/std/optional.h>
|
||||
|
||||
namespace TestImpact
|
||||
{
|
||||
@@ -28,14 +27,14 @@ namespace TestImpact
|
||||
//! Coverage information about a particular source file.
|
||||
struct SourceCoverage
|
||||
{
|
||||
AZ::IO::Path m_path; //!< Source file path.
|
||||
AZStd::optional<AZStd::vector<LineCoverage>> m_coverage; //!< Source file line coverage (empty if source level coverage only).
|
||||
AZStd::string m_path; //!< Source file path.
|
||||
AZStd::vector<LineCoverage> m_coverage; //!< Source file line coverage (empty if source level coverage only).
|
||||
};
|
||||
|
||||
//! Coverage information about a particular module (executable, shared library).
|
||||
struct ModuleCoverage
|
||||
{
|
||||
AZ::IO::Path m_path; //!< Module path.
|
||||
AZStd::string m_path; //!< Module path.
|
||||
AZStd::vector<SourceCoverage> m_sources; //!< Sources of this module that are covered.
|
||||
};
|
||||
} // namespace TestImpact
|
||||
|
||||
+3
-10
@@ -97,7 +97,7 @@ namespace TestImpact
|
||||
{
|
||||
// Module
|
||||
ModuleCoverage moduleCoverage;
|
||||
moduleCoverage.m_path = AZ::IO::Path(package_node->first_attribute(Keys[NameKey])->value());
|
||||
moduleCoverage.m_path = package_node->first_attribute(Keys[NameKey])->value();
|
||||
|
||||
const auto classes_node = package_node->first_node(Keys[ClassesKey]);
|
||||
if (classes_node)
|
||||
@@ -107,13 +107,11 @@ namespace TestImpact
|
||||
{
|
||||
// Source
|
||||
SourceCoverage sourceCoverage;
|
||||
sourceCoverage.m_path = AZ::IO::Path(pathRoot + class_node->first_attribute(Keys[FileNameKey])->value());
|
||||
sourceCoverage.m_path = pathRoot + class_node->first_attribute(Keys[FileNameKey])->value();
|
||||
|
||||
const auto lines_node = class_node->first_node(Keys[LinesKey]);
|
||||
if (lines_node)
|
||||
{
|
||||
AZStd::vector<LineCoverage> lineCoverage;
|
||||
|
||||
// Lines
|
||||
for (auto line_node = lines_node->first_node(); line_node; line_node = line_node->next_sibling())
|
||||
{
|
||||
@@ -121,12 +119,7 @@ namespace TestImpact
|
||||
const size_t number =
|
||||
AZStd::stol(AZStd::string(line_node->first_attribute(Keys[NumberKey])->value()));
|
||||
const size_t hits = AZStd::stol(AZStd::string(line_node->first_attribute(Keys[HitsKey])->value()));
|
||||
lineCoverage.emplace_back(LineCoverage{number, hits});
|
||||
}
|
||||
|
||||
if (!lineCoverage.empty())
|
||||
{
|
||||
sourceCoverage.m_coverage.emplace(AZStd::move(lineCoverage));
|
||||
sourceCoverage.m_coverage.emplace_back(LineCoverage{number, hits});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AzCore/std/string/string.h>
|
||||
#include <AzCore/std/containers/vector.h>
|
||||
|
||||
namespace TestImpact
|
||||
{
|
||||
//! Raw representation of the dependency graph for a given build target.
|
||||
struct DependencyGraphData
|
||||
{
|
||||
AZStd::string m_root; //!< The build target this dependency graph is for.
|
||||
AZStd::vector<AZStd::string> m_vertices; //!< The depender/depending built targets in this graph.
|
||||
AZStd::vector<AZStd::pair<AZStd::string, AZStd::string>> m_edges; //!< The dependency connectivity of the build targets in this graph.
|
||||
};
|
||||
} // namespace TestImpact
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <Dependency/TestImpactChangeDependencyList.h>
|
||||
|
||||
namespace TestImpact
|
||||
{
|
||||
ChangeDependencyList::ChangeDependencyList(
|
||||
AZStd::vector<SourceDependency>&& createSourceDependencies,
|
||||
AZStd::vector<SourceDependency>&& updateSourceDependencies,
|
||||
AZStd::vector<SourceDependency>&& deleteSourceDependencies)
|
||||
: m_createSourceDependencies(AZStd::move(createSourceDependencies))
|
||||
, m_updateSourceDependencies(AZStd::move(updateSourceDependencies))
|
||||
, m_deleteSourceDependencies(AZStd::move(deleteSourceDependencies))
|
||||
{
|
||||
}
|
||||
|
||||
const AZStd::vector<SourceDependency>& ChangeDependencyList::GetCreateSourceDependencies() const
|
||||
{
|
||||
return m_createSourceDependencies;
|
||||
}
|
||||
|
||||
const AZStd::vector<SourceDependency>& ChangeDependencyList::GetUpdateSourceDependencies() const
|
||||
{
|
||||
return m_updateSourceDependencies;
|
||||
}
|
||||
|
||||
const AZStd::vector<SourceDependency>& ChangeDependencyList::GetDeleteSourceDependencies() const
|
||||
{
|
||||
return m_deleteSourceDependencies;
|
||||
}
|
||||
} // namespace TestImpact
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <Dependency/TestImpactSourceDependency.h>
|
||||
|
||||
namespace TestImpact
|
||||
{
|
||||
//! Representation of a change list where all CRUD sources have been resolved to source dependencies from the dynamic dependency map.
|
||||
class ChangeDependencyList
|
||||
{
|
||||
public:
|
||||
ChangeDependencyList(
|
||||
AZStd::vector<SourceDependency>&& createSourceDependencies,
|
||||
AZStd::vector<SourceDependency>&& updateSourceDependencies,
|
||||
AZStd::vector<SourceDependency>&& deleteSourceDependencies);
|
||||
|
||||
//! Gets the sources dependencies of the created source files from the change list.
|
||||
const AZStd::vector<SourceDependency>& GetCreateSourceDependencies() const;
|
||||
|
||||
//! Gets the sources dependencies of the updated source files from the change list.
|
||||
const AZStd::vector<SourceDependency>& GetUpdateSourceDependencies() const;
|
||||
|
||||
//! Gets the sources dependencies of the deleted source files from the change list.
|
||||
const AZStd::vector<SourceDependency>& GetDeleteSourceDependencies() const;
|
||||
private:
|
||||
AZStd::vector<SourceDependency> m_createSourceDependencies;
|
||||
AZStd::vector<SourceDependency> m_updateSourceDependencies;
|
||||
AZStd::vector<SourceDependency> m_deleteSourceDependencies;
|
||||
};
|
||||
} // namespace TestImpact
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <TestImpactFramework/TestImpactException.h>
|
||||
|
||||
namespace TestImpact
|
||||
{
|
||||
//! Exception for dependency related operations.
|
||||
class DependencyException
|
||||
: public Exception
|
||||
{
|
||||
public:
|
||||
using Exception::Exception;
|
||||
};
|
||||
} // namespace TestImpact
|
||||
+408
@@ -0,0 +1,408 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <Dependency/TestImpactDynamicDependencyMap.h>
|
||||
#include <Dependency/TestImpactDependencyException.h>
|
||||
|
||||
namespace TestImpact
|
||||
{
|
||||
DynamicDependencyMap::DynamicDependencyMap(
|
||||
AZStd::vector<ProductionTargetDescriptor>&& productionTargetDescriptors,
|
||||
AZStd::vector<TestTargetDescriptor>&& testTargetDescriptors)
|
||||
: m_productionTargets(AZStd::move(productionTargetDescriptors))
|
||||
, m_testTargets(AZStd::move(testTargetDescriptors))
|
||||
{
|
||||
const auto mapBuildTargetSources = [this](const auto* target)
|
||||
{
|
||||
for (const auto& source : target->GetSources().m_staticSources)
|
||||
{
|
||||
if (auto mapping = m_sourceDependencyMap.find(source);
|
||||
mapping != m_sourceDependencyMap.end())
|
||||
{
|
||||
// This is an existing entry in the dependency map so update the parent build targets with this target
|
||||
mapping->second.m_parentTargets.insert(target);
|
||||
}
|
||||
else
|
||||
{
|
||||
// This is a new entry on the dependency map so create an entry with this parent target and no covering targets
|
||||
m_sourceDependencyMap.emplace(source, DependencyData{ {target}, {} });
|
||||
}
|
||||
}
|
||||
|
||||
// Populate the autogen input to output mapping with any autogen sources
|
||||
for (const auto& autogen : target->GetSources().m_autogenSources)
|
||||
{
|
||||
for (const auto& output : autogen.m_outputs)
|
||||
{
|
||||
m_autogenInputToOutputMap[autogen.m_input].push_back(output);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
for (const auto& target : m_productionTargets.GetTargets())
|
||||
{
|
||||
mapBuildTargetSources(&target);
|
||||
}
|
||||
|
||||
for (const auto& target : m_testTargets.GetTargets())
|
||||
{
|
||||
mapBuildTargetSources(&target);
|
||||
}
|
||||
}
|
||||
|
||||
size_t DynamicDependencyMap::GetNumTargets() const
|
||||
{
|
||||
return m_productionTargets.GetNumTargets() + m_testTargets.GetNumTargets();
|
||||
}
|
||||
|
||||
size_t DynamicDependencyMap::GetNumSources() const
|
||||
{
|
||||
return m_sourceDependencyMap.size();
|
||||
}
|
||||
|
||||
const BuildTarget* DynamicDependencyMap::GetBuildTarget(const AZStd::string& name) const
|
||||
{
|
||||
const BuildTarget* buildTarget = nullptr;
|
||||
AZStd::visit([&buildTarget](auto&& target)
|
||||
{
|
||||
if constexpr (IsProductionTarget<decltype(target)> || IsTestTarget<decltype(target)>)
|
||||
{
|
||||
buildTarget = target;
|
||||
}
|
||||
|
||||
}, GetTarget(name));
|
||||
|
||||
return buildTarget;
|
||||
}
|
||||
|
||||
const BuildTarget* DynamicDependencyMap::GetBuildTargetOrThrow(const AZStd::string& name) const
|
||||
{
|
||||
const BuildTarget* buildTarget = nullptr;
|
||||
AZStd::visit([&buildTarget](auto&& target)
|
||||
{
|
||||
if constexpr (IsProductionTarget<decltype(target)> || IsTestTarget<decltype(target)>)
|
||||
{
|
||||
buildTarget = target;
|
||||
}
|
||||
}, GetTargetOrThrow(name));
|
||||
|
||||
return buildTarget;
|
||||
}
|
||||
|
||||
OptionalTarget DynamicDependencyMap::GetTarget(const AZStd::string& name) const
|
||||
{
|
||||
if (const auto testTarget = m_testTargets.GetTarget(name);
|
||||
testTarget != nullptr)
|
||||
{
|
||||
return testTarget;
|
||||
}
|
||||
else if (auto productionTarget = m_productionTargets.GetTarget(name);
|
||||
productionTarget != nullptr)
|
||||
{
|
||||
return productionTarget;
|
||||
}
|
||||
|
||||
return AZStd::monostate{};
|
||||
}
|
||||
|
||||
Target DynamicDependencyMap::GetTargetOrThrow(const AZStd::string& name) const
|
||||
{
|
||||
Target buildTarget;
|
||||
AZStd::visit([&buildTarget, &name](auto&& target)
|
||||
{
|
||||
if constexpr (IsProductionTarget<decltype(target)> || IsTestTarget<decltype(target)>)
|
||||
{
|
||||
buildTarget = target;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw(TargetException(AZStd::string::format("Couldn't find target %s", name.c_str()).c_str()));
|
||||
}
|
||||
}, GetTarget(name));
|
||||
|
||||
return buildTarget;
|
||||
}
|
||||
|
||||
void DynamicDependencyMap::ReplaceSourceCoverage(const SourceCoveringTestsList& sourceCoverageDelta)
|
||||
{
|
||||
for (const auto& sourceCoverage : sourceCoverageDelta.GetCoverage())
|
||||
{
|
||||
// Autogen input files are not compiled sources and thus supplying coverage data for them makes no sense
|
||||
AZ_TestImpact_Eval(
|
||||
m_autogenInputToOutputMap.find(sourceCoverage.GetPath()) == m_autogenInputToOutputMap.end(),
|
||||
DependencyException, AZStd::string::format("Couldn't replace source coverage for %s, source file is an autogen input file",
|
||||
sourceCoverage.GetPath().c_str()).c_str());
|
||||
|
||||
auto [it, inserted] = m_sourceDependencyMap.insert(sourceCoverage.GetPath());
|
||||
auto& [key, sourceDependency] = *it;
|
||||
|
||||
// Clear any existing coverage for the delta
|
||||
sourceDependency.m_coveringTestTargets.clear();
|
||||
|
||||
// Update the dependency with any new coverage data
|
||||
for (const auto& unresolvedTestTarget : sourceCoverage.GetCoveringTestTargets())
|
||||
{
|
||||
if (const TestTarget* testTarget = m_testTargets.GetTarget(unresolvedTestTarget);
|
||||
testTarget)
|
||||
{
|
||||
// Source to covering test target mapping
|
||||
sourceDependency.m_coveringTestTargets.insert(testTarget);
|
||||
|
||||
// Build target to covering test target mapping
|
||||
for (const auto& parentTarget : sourceDependency.m_parentTargets)
|
||||
{
|
||||
m_buildTargetCoverage[parentTarget.GetBuildTarget()].insert(testTarget);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
AZ_Warning("ReplaceSourceCoverage", false, AZStd::string::format("Test target %s exists in the coverage data "
|
||||
"but has since been removed from the build system", unresolvedTestTarget.c_str()).c_str());
|
||||
}
|
||||
}
|
||||
|
||||
// If the new coverage data results in a parentless and coverageless entry, consider it a dead entry and remove accordingly
|
||||
if (sourceDependency.m_coveringTestTargets.empty() && sourceDependency.m_parentTargets.empty())
|
||||
{
|
||||
m_sourceDependencyMap.erase(it);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DynamicDependencyMap::ClearSourceCoverage(const AZStd::vector<AZStd::string>& paths)
|
||||
{
|
||||
for (const auto& path : paths)
|
||||
{
|
||||
if (const auto outputSources = m_autogenInputToOutputMap.find(path);
|
||||
outputSources != m_autogenInputToOutputMap.end())
|
||||
{
|
||||
// Clearing the coverage data of an autogen input source instead clears the coverage data of its output sources
|
||||
for (const auto& outputSource : outputSources->second)
|
||||
{
|
||||
ReplaceSourceCoverage(SourceCoveringTestsList({ SourceCoveringTests(outputSource) }));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ReplaceSourceCoverage(SourceCoveringTestsList({ SourceCoveringTests(path, { }) }));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const ProductionTargetList& DynamicDependencyMap::GetProductionTargetList() const
|
||||
{
|
||||
return m_productionTargets;
|
||||
}
|
||||
|
||||
const TestTargetList& DynamicDependencyMap::GetTestTargetList() const
|
||||
{
|
||||
return m_testTargets;
|
||||
}
|
||||
|
||||
AZStd::vector<const TestTarget*> DynamicDependencyMap::GetCoveringTestTargetsForProductionTarget(const ProductionTarget& productionTarget) const
|
||||
{
|
||||
AZStd::vector<const TestTarget*> coveringTestTargets;
|
||||
if (const auto coverage = m_buildTargetCoverage.find(&productionTarget);
|
||||
coverage != m_buildTargetCoverage.end())
|
||||
{
|
||||
coveringTestTargets.reserve(coverage->second.size());
|
||||
AZStd::copy(coverage->second.begin(), coverage->second.end(), AZStd::back_inserter(coveringTestTargets));
|
||||
}
|
||||
|
||||
return coveringTestTargets;
|
||||
}
|
||||
|
||||
AZStd::optional<SourceDependency> DynamicDependencyMap::GetSourceDependency(const AZStd::string& path) const
|
||||
{
|
||||
AZStd::unordered_set<ParentTarget> parentTargets;
|
||||
AZStd::unordered_set<const TestTarget*> coveringTestTargets;
|
||||
|
||||
const auto getSourceDependency = [&parentTargets, &coveringTestTargets, this](const AZStd::string& path)
|
||||
{
|
||||
const auto sourceDependency = m_sourceDependencyMap.find(path);
|
||||
if (sourceDependency != m_sourceDependencyMap.end())
|
||||
{
|
||||
for (const auto& parentTarget : sourceDependency->second.m_parentTargets)
|
||||
{
|
||||
parentTargets.insert(parentTarget);
|
||||
}
|
||||
|
||||
for (const auto& testTarget : sourceDependency->second.m_coveringTestTargets)
|
||||
{
|
||||
coveringTestTargets.insert(testTarget);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
if (const auto outputSources = m_autogenInputToOutputMap.find(path); outputSources != m_autogenInputToOutputMap.end())
|
||||
{
|
||||
// Consolidate the parentage and coverage of each of the autogen input file's generated output files
|
||||
for (const auto& outputSource : outputSources->second)
|
||||
{
|
||||
getSourceDependency(outputSource);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
getSourceDependency(path);
|
||||
}
|
||||
|
||||
if (!parentTargets.empty() || !coveringTestTargets.empty())
|
||||
{
|
||||
return SourceDependency(path, DependencyData{ AZStd::move(parentTargets), AZStd::move(coveringTestTargets) });
|
||||
}
|
||||
|
||||
return AZStd::nullopt;
|
||||
}
|
||||
|
||||
SourceDependency DynamicDependencyMap::GetSourceDependencyOrThrow(const AZStd::string& path) const
|
||||
{
|
||||
auto sourceDependency = GetSourceDependency(path);
|
||||
AZ_TestImpact_Eval(sourceDependency.has_value(), DependencyException, AZStd::string::format("Couldn't find source %s", path.c_str()).c_str());
|
||||
return sourceDependency.value();
|
||||
}
|
||||
|
||||
SourceCoveringTestsList DynamicDependencyMap::ExportSourceCoverage() const
|
||||
{
|
||||
AZStd::vector<SourceCoveringTests> coverage;
|
||||
for (const auto& [path, dependency] : m_sourceDependencyMap)
|
||||
{
|
||||
AZStd::vector<AZStd::string> souceCoveringTests;
|
||||
for (const auto& testTarget : dependency.m_coveringTestTargets)
|
||||
{
|
||||
souceCoveringTests.push_back(testTarget->GetName());
|
||||
}
|
||||
|
||||
coverage.push_back(SourceCoveringTests(path, AZStd::move(souceCoveringTests)));
|
||||
}
|
||||
|
||||
return SourceCoveringTestsList(AZStd::move(coverage));
|
||||
}
|
||||
|
||||
AZStd::vector<AZStd::string> DynamicDependencyMap::GetOrphanSourceFiles() const
|
||||
{
|
||||
AZStd::vector<AZStd::string> orphans;
|
||||
for (const auto& [source, dependency] : m_sourceDependencyMap)
|
||||
{
|
||||
if (dependency.m_parentTargets.empty())
|
||||
{
|
||||
orphans.push_back(source);
|
||||
}
|
||||
}
|
||||
|
||||
return orphans;
|
||||
}
|
||||
|
||||
ChangeDependencyList DynamicDependencyMap::ApplyAndResoveChangeList(const ChangeList& changeList)
|
||||
{
|
||||
AZStd::vector<SourceDependency> createDependencies;
|
||||
AZStd::vector<SourceDependency> updateDependencies;
|
||||
AZStd::vector<SourceDependency> deleteDependencies;
|
||||
|
||||
// Keep track of the coverage to delete as a post step rather than deleting it in situ so that erroneous change lists
|
||||
// do not corrupt the dynamic dependency map
|
||||
AZStd::vector<AZStd::string> coverageToDelete;
|
||||
|
||||
// Create operations
|
||||
for (const auto& createdFile : changeList.m_createdFiles)
|
||||
{
|
||||
auto sourceDependency = GetSourceDependency(createdFile);
|
||||
if (sourceDependency.has_value())
|
||||
{
|
||||
if (sourceDependency->GetNumCoveringTestTargets())
|
||||
{
|
||||
const AZStd::string msg = AZStd::string::format("The newly-created file %s belongs to a build target yet "
|
||||
"still has coverage data in the source covering test list implying that a delete CRUD operation has been "
|
||||
"missed, thus the integrity of the source covering test list has been compromised", createdFile.c_str());
|
||||
AZ_Error("File Creation", false, msg.c_str());
|
||||
throw DependencyException(msg);
|
||||
}
|
||||
|
||||
if (sourceDependency->GetNumParentTargets())
|
||||
{
|
||||
createDependencies.emplace_back(AZStd::move(*sourceDependency));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Update operations
|
||||
for (const auto& updatedFile : changeList.m_updatedFiles)
|
||||
{
|
||||
auto sourceDependency = GetSourceDependency(updatedFile);
|
||||
if (sourceDependency.has_value())
|
||||
{
|
||||
if (sourceDependency->GetNumParentTargets())
|
||||
{
|
||||
updateDependencies.emplace_back(AZStd::move(*sourceDependency));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (sourceDependency->GetNumCoveringTestTargets())
|
||||
{
|
||||
AZ_Warning(
|
||||
"File Update", false, AZStd::string::format("Source file %s is potentially an orphan (used by build targets "
|
||||
"without explicitly being added to the build system, e.g. an include directive pulling in a header from the "
|
||||
"repository). Running the covering tests for this file with instrumentation will confirm whether or nor this "
|
||||
"is the case", updatedFile.c_str()).c_str());
|
||||
|
||||
updateDependencies.emplace_back(AZStd::move(*sourceDependency));
|
||||
coverageToDelete.push_back(updatedFile);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Delete operations
|
||||
for (const auto& deletedFile : changeList.m_deletedFiles)
|
||||
{
|
||||
auto sourceDependency = GetSourceDependency(deletedFile);
|
||||
if (!sourceDependency.has_value())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (sourceDependency->GetNumParentTargets())
|
||||
{
|
||||
if (sourceDependency->GetNumCoveringTestTargets())
|
||||
{
|
||||
const AZStd::string msg = AZStd::string::format("The deleted file %s still belongs to a build target and still "
|
||||
"has coverage data in the source covering test list, implying that the integrity of both the source to target "
|
||||
"mappings and the source covering test list has been compromised", deletedFile.c_str());
|
||||
AZ_Error("File Delete", false, msg.c_str());
|
||||
throw DependencyException(msg);
|
||||
}
|
||||
else
|
||||
{
|
||||
const AZStd::string msg = AZStd::string::format("The deleted file %s still belongs to a build target implying "
|
||||
"that the integrity of the source to target mappings has been compromised", deletedFile.c_str());
|
||||
AZ_Error("File Delete", false, msg.c_str());
|
||||
throw DependencyException(msg);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (sourceDependency->GetNumCoveringTestTargets())
|
||||
{
|
||||
deleteDependencies.emplace_back(AZStd::move(*sourceDependency));
|
||||
coverageToDelete.push_back(deletedFile);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!coverageToDelete.empty())
|
||||
{
|
||||
ClearSourceCoverage(coverageToDelete);
|
||||
}
|
||||
|
||||
return ChangeDependencyList(AZStd::move(createDependencies), AZStd::move(updateDependencies), AZStd::move(deleteDependencies));
|
||||
}
|
||||
} // namespace TestImpact
|
||||
+119
@@ -0,0 +1,119 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <Artifact/Dynamic/TestImpactChangeList.h>
|
||||
#include <Artifact/Static/TestImpactProductionTargetDescriptor.h>
|
||||
#include <Artifact/Static/TestImpactTestTargetDescriptor.h>
|
||||
#include <Dependency/TestImpactSourceCoveringTestsList.h>
|
||||
#include <Dependency/TestImpactSourceDependency.h>
|
||||
#include <Dependency/TestImpactChangeDependencyList.h>
|
||||
#include <Target/TestImpactProductionTargetList.h>
|
||||
#include <Target/TestImpactTestTargetList.h>
|
||||
|
||||
#include <AzCore/std/containers/unordered_map.h>
|
||||
#include <AzCore/std/containers/unordered_set.h>
|
||||
#include <AzCore/std/containers/vector.h>
|
||||
|
||||
namespace TestImpact
|
||||
{
|
||||
//! Representation of the repository source tree and its relation to the build targets and coverage data.
|
||||
class DynamicDependencyMap
|
||||
{
|
||||
public:
|
||||
//! Constructs the dependency map with entries for each build target's source files with empty test coverage data.
|
||||
DynamicDependencyMap(
|
||||
AZStd::vector<ProductionTargetDescriptor>&& productionTargetDescriptors,
|
||||
AZStd::vector<TestTargetDescriptor>&& testTargetDescriptors);
|
||||
|
||||
//! Gets the total number of production and test targets in the repository.
|
||||
size_t GetNumTargets() const;
|
||||
|
||||
//! Gets the total number of unique source files in the repository.
|
||||
//! @note This includes autogen output sources.
|
||||
size_t GetNumSources() const;
|
||||
|
||||
//! Attempts to get the specified build target.
|
||||
//! @param name The name of the build target to get.
|
||||
//! @returns If found, the pointer to the specified build target, otherwise nullptr.
|
||||
const BuildTarget* GetBuildTarget(const AZStd::string& name) const;
|
||||
|
||||
//! Attempts to get the specified build target or throw TargetException.
|
||||
//! @param name The name of the build target to get.
|
||||
const BuildTarget* GetBuildTargetOrThrow(const AZStd::string& name) const;
|
||||
|
||||
//! Attempts to get the specified target's specialized type.
|
||||
//! @param name The name of the target to get.
|
||||
//! @returns If found, the pointer to the specialized target, otherwise AZStd::monostate.
|
||||
OptionalTarget GetTarget(const AZStd::string& name) const;
|
||||
|
||||
//! Attempts to get the specified target's specialized type or throw TargetException.
|
||||
//! @param name The name of the target to get.
|
||||
Target GetTargetOrThrow(const AZStd::string& name) const;
|
||||
|
||||
//! Get the list of production targets in the repository.
|
||||
const ProductionTargetList& GetProductionTargetList() const;
|
||||
|
||||
//! Get the list of test targets in the repository.
|
||||
const TestTargetList& GetTestTargetList() const;
|
||||
|
||||
//! Gets the test targets covering the specified production target.
|
||||
//! @param productionTarget The production target to retrieve the covering tests for.
|
||||
AZStd::vector<const TestTarget*> GetCoveringTestTargetsForProductionTarget(const ProductionTarget& productionTarget) const;
|
||||
|
||||
//! Gets the source dependency for the specified source file.
|
||||
//! @note Autogen input source dependencies are the consolidated source dependencies of all of their generated output sources.
|
||||
//! @returns If found, the source dependency information for the specified source file, otherwise empty.
|
||||
AZStd::optional<SourceDependency> GetSourceDependency(const AZStd::string& path) const;
|
||||
|
||||
//! Gets the source dependency for the specified source file or throw DependencyException.
|
||||
SourceDependency GetSourceDependencyOrThrow(const AZStd::string& path) const;
|
||||
|
||||
//! Replaces the source coverage of the specified sources with the specified source coverage.
|
||||
//! @note The covering targets for the parent test target(s) will not be pruned if those covering targets are removed.
|
||||
//! @param sourceCoverageDelta The source coverage delta to replace in the dependency map.
|
||||
void ReplaceSourceCoverage(const SourceCoveringTestsList& sourceCoverageDelta);
|
||||
|
||||
//! Exports the coverage of all sources in the dependency map.
|
||||
SourceCoveringTestsList ExportSourceCoverage() const;
|
||||
|
||||
//! Gets the list of orphaned source files in the dependency map that have coverage data but belong to no parent build targets.
|
||||
AZStd::vector<AZStd::string> GetOrphanSourceFiles() const;
|
||||
|
||||
//! Applies the specified change list to the dynamic dependency map and resolves the change list to a change dependency list
|
||||
//! containing the updated source dependencies for each source file in the change list.
|
||||
//! @param changeList The change list to apply and resolve.
|
||||
//! @returns The change list as resolved to the appropriate source dependencies.
|
||||
[[nodiscard]] ChangeDependencyList ApplyAndResoveChangeList(const ChangeList& changeList);
|
||||
|
||||
private:
|
||||
//! Clears the source coverage of the specified sources.
|
||||
//! @note The covering targets for the parent test target(s) will not be pruned if those covering targets are removed.
|
||||
void ClearSourceCoverage(const AZStd::vector<AZStd::string>& paths);
|
||||
|
||||
//! The sorted list of unique production targets in the repository.
|
||||
ProductionTargetList m_productionTargets;
|
||||
|
||||
//! The sorted list of unique test targets in the repository.
|
||||
TestTargetList m_testTargets;
|
||||
|
||||
//! The dependency map of sources to their parent build targets and covering test targets.
|
||||
AZStd::unordered_map<AZStd::string, DependencyData> m_sourceDependencyMap;
|
||||
|
||||
//! The map of build targets and their covering test targets.
|
||||
AZStd::unordered_map<const BuildTarget*, AZStd::unordered_set<const TestTarget*>> m_buildTargetCoverage;
|
||||
|
||||
//! Mapping of autogen input sources to their generated output sources.
|
||||
AZStd::unordered_map<AZStd::string, AZStd::vector<AZStd::string>> m_autogenInputToOutputMap;
|
||||
};
|
||||
} // namespace TestImpact
|
||||
+63
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <Dependency/TestImpactSourceCoveringTestsList.h>
|
||||
|
||||
#include <AzCore/std/sort.h>
|
||||
|
||||
namespace TestImpact
|
||||
{
|
||||
SourceCoveringTests::SourceCoveringTests(const AZStd::string& path)
|
||||
: m_path(path)
|
||||
{
|
||||
}
|
||||
|
||||
SourceCoveringTests::SourceCoveringTests(const AZStd::string& path, AZStd::vector<AZStd::string>&& coveringTestTargets)
|
||||
: m_path(path)
|
||||
, m_coveringTestTargets(AZStd::move(coveringTestTargets))
|
||||
{
|
||||
}
|
||||
|
||||
const AZStd::string& SourceCoveringTests::GetPath() const
|
||||
{
|
||||
return m_path;
|
||||
}
|
||||
|
||||
size_t SourceCoveringTests::GetNumCoveringTestTargets() const
|
||||
{
|
||||
return m_coveringTestTargets.size();
|
||||
}
|
||||
|
||||
const AZStd::vector<AZStd::string>& SourceCoveringTests::GetCoveringTestTargets() const
|
||||
{
|
||||
return m_coveringTestTargets;
|
||||
}
|
||||
|
||||
SourceCoveringTestsList::SourceCoveringTestsList(AZStd::vector<SourceCoveringTests>&& sourceCoveringTests)
|
||||
: m_coverage(AZStd::move(sourceCoveringTests))
|
||||
{
|
||||
AZStd::sort(m_coverage.begin(), m_coverage.end(), [](const SourceCoveringTests& lhs, const SourceCoveringTests& rhs)
|
||||
{
|
||||
return lhs.GetPath() < rhs.GetPath();
|
||||
});
|
||||
}
|
||||
|
||||
size_t SourceCoveringTestsList::GetNumSources() const
|
||||
{
|
||||
return m_coverage.size();
|
||||
}
|
||||
|
||||
const AZStd::vector<SourceCoveringTests>& SourceCoveringTestsList::GetCoverage() const
|
||||
{
|
||||
return m_coverage;
|
||||
}
|
||||
} // namespace TestImpact
|
||||
+54
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AzCore/std/containers/vector.h>
|
||||
#include <AzCore/std/string/string.h>
|
||||
|
||||
namespace TestImpact
|
||||
{
|
||||
//! Represents the unresolved test target coverage for a given source file.
|
||||
class SourceCoveringTests
|
||||
{
|
||||
public:
|
||||
explicit SourceCoveringTests(const AZStd::string& path);
|
||||
SourceCoveringTests(const AZStd::string& path, AZStd::vector<AZStd::string>&& coveringTestTargets);
|
||||
|
||||
//! Returns the path of this source file.
|
||||
const AZStd::string& GetPath() const;
|
||||
|
||||
//! Returns the number of unresolved test targets covering this source file.
|
||||
size_t GetNumCoveringTestTargets() const;
|
||||
|
||||
//! Returns the unresolved test targets covering this source file.
|
||||
const AZStd::vector<AZStd::string>& GetCoveringTestTargets() const;
|
||||
private:
|
||||
AZStd::string m_path; //!< The path of this source file.
|
||||
AZStd::vector<AZStd::string> m_coveringTestTargets; //!< The unresolved test targets that cover this source file.
|
||||
};
|
||||
|
||||
//! Sorted collection of source file test coverage.
|
||||
class SourceCoveringTestsList
|
||||
{
|
||||
public:
|
||||
explicit SourceCoveringTestsList(AZStd::vector<SourceCoveringTests>&& sourceCoveringTests);
|
||||
|
||||
//! Returns the number of source files in the collection.
|
||||
size_t GetNumSources() const;
|
||||
|
||||
//! Returns the source file coverages.
|
||||
const AZStd::vector<SourceCoveringTests>& GetCoverage() const;
|
||||
private:
|
||||
AZStd::vector<SourceCoveringTests> m_coverage; //!< The collection of source file coverages.
|
||||
};
|
||||
} // namespace TestImpact
|
||||
+87
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <Dependency/TestImpactSourceDependency.h>
|
||||
#include <Target/TestImpactBuildTarget.h>
|
||||
#include <Target/TestImpactProductionTarget.h>
|
||||
#include <Target/TestImpactTestTarget.h>
|
||||
|
||||
namespace TestImpact
|
||||
{
|
||||
ParentTarget::ParentTarget(const TestTarget* target)
|
||||
: m_target(target)
|
||||
{
|
||||
}
|
||||
|
||||
ParentTarget::ParentTarget(const ProductionTarget* target)
|
||||
: m_target(target)
|
||||
{
|
||||
}
|
||||
|
||||
bool ParentTarget::operator==(const ParentTarget& other) const
|
||||
{
|
||||
return GetBuildTarget() == other.GetBuildTarget();
|
||||
}
|
||||
|
||||
const BuildTarget* ParentTarget::GetBuildTarget() const
|
||||
{
|
||||
const BuildTarget* buildTarget;
|
||||
AZStd::visit([&buildTarget](auto&& target)
|
||||
{
|
||||
buildTarget = target;
|
||||
|
||||
}, m_target);
|
||||
|
||||
return buildTarget;
|
||||
}
|
||||
|
||||
const Target& ParentTarget::GetTarget() const
|
||||
{
|
||||
return m_target;
|
||||
}
|
||||
|
||||
SourceDependency::SourceDependency(
|
||||
const AZStd::string& path,
|
||||
DependencyData&& dependencyData)
|
||||
: m_path(path)
|
||||
, m_dependencyData(AZStd::move(dependencyData))
|
||||
{
|
||||
}
|
||||
|
||||
const AZStd::string& SourceDependency::GetPath() const
|
||||
{
|
||||
return m_path;
|
||||
}
|
||||
|
||||
size_t SourceDependency::GetNumParentTargets() const
|
||||
{
|
||||
return m_dependencyData.m_parentTargets.size();
|
||||
}
|
||||
|
||||
size_t SourceDependency::GetNumCoveringTestTargets() const
|
||||
{
|
||||
return m_dependencyData.m_coveringTestTargets.size();
|
||||
}
|
||||
|
||||
const AZStd::unordered_set<ParentTarget>& SourceDependency::GetParentTargets() const
|
||||
{
|
||||
return m_dependencyData.m_parentTargets;
|
||||
}
|
||||
|
||||
const AZStd::unordered_set<const TestTarget*>& SourceDependency::GetCoveringTestTargets() const
|
||||
{
|
||||
return m_dependencyData.m_coveringTestTargets;
|
||||
}
|
||||
|
||||
} // namespace TestImpact
|
||||
+95
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <Target/TestImpactBuildTarget.h>
|
||||
|
||||
#include <AzCore/std/string/string.h>
|
||||
#include <AzCore/std/containers/unordered_map.h>
|
||||
#include <AzCore/std/containers/unordered_set.h>
|
||||
#include <AzCore/std/containers/vector.h>
|
||||
|
||||
namespace TestImpact
|
||||
{
|
||||
class ProductionTarget;
|
||||
class TestTarget;
|
||||
|
||||
//! Representation of a source dependency's parent target.
|
||||
class ParentTarget
|
||||
{
|
||||
public:
|
||||
//! Constructor overload for test target types.
|
||||
ParentTarget(const TestTarget* target);
|
||||
|
||||
//! Constructor overload for production target types.
|
||||
ParentTarget(const ProductionTarget* target);
|
||||
|
||||
//! Returns the base build target pointer for this parent.
|
||||
const BuildTarget* GetBuildTarget() const;
|
||||
|
||||
//! Returns the specialized target pointer for this parent.
|
||||
const Target& GetTarget() const;
|
||||
|
||||
bool operator==(const ParentTarget& other) const;
|
||||
private:
|
||||
Target m_target; //! The specialized target pointer for this parent.
|
||||
};
|
||||
}
|
||||
|
||||
namespace AZStd
|
||||
{
|
||||
//! Hash function for ParentTarget types for use in maps and sets
|
||||
template<> struct hash<TestImpact::ParentTarget>
|
||||
{
|
||||
size_t operator()(const TestImpact::ParentTarget& parentTarget) const noexcept
|
||||
{
|
||||
return reinterpret_cast<size_t>(parentTarget.GetBuildTarget());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
namespace TestImpact
|
||||
{
|
||||
struct DependencyData
|
||||
{
|
||||
AZStd::unordered_set<ParentTarget> m_parentTargets;
|
||||
AZStd::unordered_set<const TestTarget*> m_coveringTestTargets;
|
||||
};
|
||||
|
||||
//! Test target coverage and build target dependency information for a given source file in the dynamic dependency map.
|
||||
class SourceDependency
|
||||
{
|
||||
public:
|
||||
SourceDependency(
|
||||
const AZStd::string& path,
|
||||
DependencyData&& dependencyData);
|
||||
|
||||
//! Returns the path of this source file.
|
||||
const AZStd::string& GetPath() const;
|
||||
|
||||
//! Returns the number of parent build targets this source belongs to.
|
||||
size_t GetNumParentTargets() const;
|
||||
|
||||
//! Returns the number of test targets covering this source file.
|
||||
size_t GetNumCoveringTestTargets() const;
|
||||
|
||||
//! Returns the parent targets that this source file belongs to.
|
||||
const AZStd::unordered_set<ParentTarget>& GetParentTargets() const;
|
||||
|
||||
//! Returns the test targets covering this source file.
|
||||
const AZStd::unordered_set<const TestTarget*>& GetCoveringTestTargets() const;
|
||||
private:
|
||||
AZStd::string m_path; //!< The path of this source file.
|
||||
DependencyData m_dependencyData; //!< The dependency data for this source file.
|
||||
};
|
||||
} // namespace TestImpact
|
||||
+226
@@ -0,0 +1,226 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <Dependency/TestImpactDependencyException.h>
|
||||
#include <Dependency/TestImpactDynamicDependencyMap.h>
|
||||
#include <Dependency/TestImpactTestSelectorAndPrioritizer.h>
|
||||
#include <Target/TestImpactTestTarget.h>
|
||||
|
||||
namespace TestImpact
|
||||
{
|
||||
TestSelectorAndPrioritizer::TestSelectorAndPrioritizer(
|
||||
const DynamicDependencyMap* dynamicDependencyMap, DependencyGraphDataMap&& dependencyGraphDataMap)
|
||||
: m_dynamicDependencyMap(dynamicDependencyMap)
|
||||
, m_dependencyGraphDataMap(AZStd::move(dependencyGraphDataMap))
|
||||
{
|
||||
}
|
||||
|
||||
AZStd::vector<const TestTarget*> TestSelectorAndPrioritizer::SelectTestTargets(
|
||||
const ChangeDependencyList& changeDependencyList, TestSelectionStrategy testSelectionStrategy)
|
||||
{
|
||||
const auto selectedTestTargetAndDependerMap = SelectTestTargets(changeDependencyList);
|
||||
const auto prioritizedSelectedTests = PrioritizeSelectedTestTargets(selectedTestTargetAndDependerMap, testSelectionStrategy);
|
||||
return prioritizedSelectedTests;
|
||||
}
|
||||
|
||||
TestSelectorAndPrioritizer::SelectedTestTargetAndDependerMap TestSelectorAndPrioritizer::SelectTestTargets(
|
||||
const ChangeDependencyList& changeDependencyList)
|
||||
{
|
||||
SelectedTestTargetAndDependerMap selectedTestTargetMap;
|
||||
|
||||
// Create operations
|
||||
for (const auto& sourceDependency : changeDependencyList.GetCreateSourceDependencies())
|
||||
{
|
||||
for (const auto& parentTarget : sourceDependency.GetParentTargets())
|
||||
{
|
||||
AZStd::visit([&selectedTestTargetMap, this](auto&& target)
|
||||
{
|
||||
if constexpr (IsProductionTarget<decltype(target)>)
|
||||
{
|
||||
// Parent Targets: Yes
|
||||
// Coverage Data : No
|
||||
// Source Type : Production
|
||||
//
|
||||
// Scenario
|
||||
// 1. The file has been newly created
|
||||
// 2. This file exists in one or more source to production target mapping artifacts
|
||||
// 3. There exists no coverage data for this file in the source covering test list
|
||||
//
|
||||
// Action
|
||||
// 1. Select all test targets covering the parent production targets
|
||||
const auto coverage = m_dynamicDependencyMap->GetCoveringTestTargetsForProductionTarget(*target);
|
||||
for (const auto* testTarget : coverage)
|
||||
{
|
||||
selectedTestTargetMap[testTarget].insert(target);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Parent Targets: Yes
|
||||
// Coverage Data : No
|
||||
// Source Type : Test
|
||||
//
|
||||
// Scenario
|
||||
// 1. The file has been newly created
|
||||
// 2. This file exists in one or more source to test target mapping artifacts
|
||||
// 3. There exists no coverage data for this file in the source covering test list
|
||||
//
|
||||
// Action
|
||||
// 1. Select all parent test targets
|
||||
selectedTestTargetMap.insert(target);
|
||||
}
|
||||
}, parentTarget.GetTarget());
|
||||
}
|
||||
}
|
||||
|
||||
// Update operations
|
||||
for (const auto& sourceDependency : changeDependencyList.GetUpdateSourceDependencies())
|
||||
{
|
||||
if (sourceDependency.GetNumParentTargets())
|
||||
{
|
||||
if (sourceDependency.GetNumCoveringTestTargets())
|
||||
{
|
||||
for (const auto& parentTarget : sourceDependency.GetParentTargets())
|
||||
{
|
||||
AZStd::visit([&selectedTestTargetMap, &sourceDependency, this](auto&& target)
|
||||
{
|
||||
if constexpr (IsProductionTarget<decltype(target)>)
|
||||
{
|
||||
// Parent Targets: Yes
|
||||
// Coverage Data : Yes
|
||||
// Source Type : Production
|
||||
//
|
||||
// Scenario
|
||||
// 1. The existing file has been modified
|
||||
// 2. This file exists in one or more source to production target mapping artifacts
|
||||
// 3. There exists coverage data for this file in the source covering test list
|
||||
//
|
||||
// Action
|
||||
// 1. Select all test targets covering this file
|
||||
for (const auto* testTarget : sourceDependency.GetCoveringTestTargets())
|
||||
{
|
||||
selectedTestTargetMap[testTarget].insert(target);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Parent Targets: Yes
|
||||
// Coverage Data : Yes
|
||||
// Source Type : Test
|
||||
//
|
||||
// Scenario
|
||||
// 1. The existing file has been modified
|
||||
// 2. This file exists in one or more source to test target mapping artifacts
|
||||
// 3. There exists coverage data for this file in the source covering test list
|
||||
//
|
||||
// Action
|
||||
// 1. Select the parent test targets for this file
|
||||
selectedTestTargetMap.insert(target);
|
||||
}
|
||||
}, parentTarget.GetTarget());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (const auto& parentTarget : sourceDependency.GetParentTargets())
|
||||
{
|
||||
AZStd::visit([&selectedTestTargetMap, &sourceDependency, this](auto&& target)
|
||||
{
|
||||
if constexpr (IsTestTarget<decltype(target)>)
|
||||
{
|
||||
// Parent Targets: Yes
|
||||
// Coverage Data : No
|
||||
// Source Type : Test
|
||||
//
|
||||
// Scenario
|
||||
// 1. The existing file has been modified
|
||||
// 2. This file exists in one or more source to test target mapping artifacts
|
||||
// 3. There exists no coverage data for this file in the source covering test list
|
||||
//
|
||||
// Action
|
||||
// 1. Select the parent test targets for this file
|
||||
selectedTestTargetMap.insert(target);
|
||||
}
|
||||
}, parentTarget.GetTarget());
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Parent Targets: No
|
||||
// Coverage Data : Yes
|
||||
// Source Type : Indeterminate
|
||||
//
|
||||
// Scenario
|
||||
// 1. The existing file has been modified
|
||||
// 2. Either:
|
||||
// a) This file previously existed in one or more source to target mapping artifacts
|
||||
// b) This file no longer exists in any source to target mapping artifacts
|
||||
// c) The coverage data for this file was has yet to be deleted from the source covering test list
|
||||
// 3. Or:
|
||||
// a) The file is being used by build targets but has erroneously not been explicitly added to the build
|
||||
// system (e.g. include directive pulling in a header from the repository that has not been added to
|
||||
// any build targets due to an oversight)
|
||||
//
|
||||
// Action
|
||||
// 1. Log potential orphaned source file warning
|
||||
// 2. Select all test targets covering this file
|
||||
// 3. Delete the existing coverage data from the source covering test list
|
||||
|
||||
for (const auto* testTarget : sourceDependency.GetCoveringTestTargets())
|
||||
{
|
||||
selectedTestTargetMap.insert(testTarget);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Delete operations
|
||||
for (const auto& sourceDependency : changeDependencyList.GetDeleteSourceDependencies())
|
||||
{
|
||||
// Parent Targets: No
|
||||
// Coverage Data : Yes
|
||||
// Source Type : Indeterminate
|
||||
//
|
||||
// Scenario
|
||||
// 1. The existing file has been deleted
|
||||
// 2. This file previously existed in one or more source to target mapping artifacts
|
||||
// 2. This file does not exist in any source to target mapping artifacts
|
||||
// 4. The coverage data for this file was has yet to be deleted from the source covering test list
|
||||
//
|
||||
// Action
|
||||
// 1. Select all test targets covering this file
|
||||
// 2. Delete the existing coverage data from the source covering test list
|
||||
for (const auto* testTarget : sourceDependency.GetCoveringTestTargets())
|
||||
{
|
||||
selectedTestTargetMap.insert(testTarget);
|
||||
}
|
||||
}
|
||||
|
||||
return selectedTestTargetMap;
|
||||
}
|
||||
|
||||
AZStd::vector<const TestTarget*> TestSelectorAndPrioritizer::PrioritizeSelectedTestTargets(
|
||||
const SelectedTestTargetAndDependerMap& selectedTestTargetAndDependerMap,
|
||||
[[maybe_unused]]TestSelectionStrategy testSelectionStrategy)
|
||||
{
|
||||
AZStd::vector<const TestTarget*> selectedTestTargets;
|
||||
|
||||
// Prioritization disabled for now
|
||||
// SPEC-6563
|
||||
for (const auto& [testTarget, dependerTargets] : selectedTestTargetAndDependerMap)
|
||||
{
|
||||
selectedTestTargets.push_back(testTarget);
|
||||
}
|
||||
|
||||
return selectedTestTargets;
|
||||
}
|
||||
} // namespace TestImpact
|
||||
+77
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <Artifact/Static/TestImpactDependencyGraphData.h>
|
||||
#include <Dependency/TestImpactChangeDependencyList.h>
|
||||
|
||||
#include <AzCore/std/containers/vector.h>
|
||||
#include <AzCore/std/containers/unordered_map.h>
|
||||
#include <AzCore/std/containers/unordered_set.h>
|
||||
|
||||
namespace TestImpact
|
||||
{
|
||||
class DynamicDependencyMap;
|
||||
class BuildTarget;
|
||||
class TestTarget;
|
||||
|
||||
//! Strategy for selecting tests given a set of source changes.
|
||||
enum class TestSelectionStrategy : bool
|
||||
{
|
||||
SelectOnly, //!< Select tests only, do not attempt prioritization of those selected tests.
|
||||
SelectAndPriotitize //!< Select tests and prioritize according to dependency graph locality of coverer and coveree.
|
||||
};
|
||||
|
||||
//! Map of build targets and their dependency graph data.
|
||||
//! For test targets, the dependency graph data is that of the build targets which the test target depends on.
|
||||
//! For production targets, the dependency graph is that of the build targets that depend on it (dependers).
|
||||
//! @note No dependency graph data is not an error, it simple means that the target cannot be prioritized.
|
||||
using DependencyGraphDataMap = AZStd::unordered_map<const BuildTarget*, DependencyGraphData>;
|
||||
|
||||
//! Selects the test targets that cover a given set of changes based on the CRUD rules and optionally prioritizes the test
|
||||
//! selection according to their locality of their covering production targets in the their dependency graphs.
|
||||
//! @note the CRUD rules for how tests are selected can be found in the MicroRepo header file.
|
||||
class TestSelectorAndPrioritizer
|
||||
{
|
||||
public:
|
||||
//! Constructs the test selector and prioritizer for the given dynamic dependency map.
|
||||
//! @param dynamicDependencyMap The dynamic dependency map representing the repository source tree.
|
||||
//! @param dependencyGraphDataMap The map of build targets and their dependency graph data for use in test prioritization.
|
||||
TestSelectorAndPrioritizer(const DynamicDependencyMap* dynamicDependencyMap, DependencyGraphDataMap&& dependencyGraphDataMap);
|
||||
|
||||
//! Select the covering test targets for the given set of source changes and optionally prioritizes said test selection.
|
||||
//! @param changeDependencyList The resolved list of source dependencies for the CRUD source changes.
|
||||
//! @param testSelectionStrategy The test selection and prioritization strategy to apply to the given CRUD source changes.
|
||||
AZStd::vector<const TestTarget*> SelectTestTargets(const ChangeDependencyList& changeDependencyList, TestSelectionStrategy testSelectionStrategy);
|
||||
|
||||
private:
|
||||
//! Map of selected test targets and the production targets they cover for the given set of source changes.
|
||||
using SelectedTestTargetAndDependerMap = AZStd::unordered_map<const TestTarget*, AZStd::unordered_set<const ProductionTarget*>>;
|
||||
|
||||
//! Selects the test targets covering the set of source changes in the change dependency list.
|
||||
//! @param changeDependencyList The change dependency list containing the CRUD source changes to select tests for.
|
||||
//! @returns The selected tests and their covering production targets for the given set of source changes.
|
||||
SelectedTestTargetAndDependerMap SelectTestTargets(const ChangeDependencyList& changeDependencyList);
|
||||
|
||||
//! Prioritizes the selected tests according to the specified test selection strategy,
|
||||
//! @note If no dependency graph data exists for a given test target then that test target still be selected albeit not prioritized.
|
||||
//! @param selectedTestTargetAndDependerMap The selected tests to prioritize.
|
||||
//! @param testSelectionStrategy The test selection strategy to prioritize the selected tests.
|
||||
//! @returns The selected tests either in either arbitrary order or in prioritized with highest priority first.
|
||||
AZStd::vector<const TestTarget*> PrioritizeSelectedTestTargets(
|
||||
const SelectedTestTargetAndDependerMap& selectedTestTargetAndDependerMap, TestSelectionStrategy testSelectionStrategy);
|
||||
|
||||
const DynamicDependencyMap* m_dynamicDependencyMap;
|
||||
DependencyGraphDataMap m_dependencyGraphDataMap;
|
||||
};
|
||||
} // namespace TestImpact
|
||||
@@ -14,10 +14,20 @@
|
||||
|
||||
#include <Artifact/Static/TestImpactBuildTargetDescriptor.h>
|
||||
|
||||
#include <AzCore/std/containers/variant.h>
|
||||
#include <AzCore/std/string/string.h>
|
||||
|
||||
namespace TestImpact
|
||||
{
|
||||
class TestTarget;
|
||||
class ProductionTarget;
|
||||
|
||||
//! Holder for specializations of BuildTarget.
|
||||
using Target = AZStd::variant<const TestTarget*, const ProductionTarget*>;
|
||||
|
||||
//! Optional holder for specializations of BuildTarget.
|
||||
using OptionalTarget = AZStd::variant<AZStd::monostate, const TestTarget*, const ProductionTarget*>;
|
||||
|
||||
//! Type id for querying specialized derived target types from base pointer/reference.
|
||||
enum class TargetType : bool
|
||||
{
|
||||
|
||||
+2
-2
@@ -25,7 +25,7 @@ namespace TestImpact
|
||||
for (const auto& sourceCovered : moduleCovered.m_sources)
|
||||
{
|
||||
m_sourcesCovered.emplace_back(sourceCovered.m_path);
|
||||
if (sourceCovered.m_coverage.has_value())
|
||||
if (!sourceCovered.m_coverage.empty())
|
||||
{
|
||||
m_coverageLevel = CoverageLevel::Line;
|
||||
}
|
||||
@@ -51,7 +51,7 @@ namespace TestImpact
|
||||
return m_modules.size();
|
||||
}
|
||||
|
||||
const AZStd::vector<AZ::IO::Path>& TestCoverage::GetSourcesCovered() const
|
||||
const AZStd::vector<AZStd::string>& TestCoverage::GetSourcesCovered() const
|
||||
{
|
||||
return m_sourcesCovered;
|
||||
}
|
||||
|
||||
+2
-2
@@ -38,7 +38,7 @@ namespace TestImpact
|
||||
size_t GetNumModulesCovered() const;
|
||||
|
||||
//! Returns the sorted set of unique sources covered (empty if no coverage).
|
||||
const AZStd::vector<AZ::IO::Path>& GetSourcesCovered() const;
|
||||
const AZStd::vector<AZStd::string>& GetSourcesCovered() const;
|
||||
|
||||
//! Returns the modules covered (empty if no coverage).
|
||||
const AZStd::vector<ModuleCoverage>& GetModuleCoverages() const;
|
||||
@@ -48,7 +48,7 @@ namespace TestImpact
|
||||
|
||||
private:
|
||||
AZStd::vector<ModuleCoverage> m_modules;
|
||||
AZStd::vector<AZ::IO::Path> m_sourcesCovered;
|
||||
AZStd::vector<AZStd::string> m_sourcesCovered;
|
||||
AZStd::optional<CoverageLevel> m_coverageLevel;
|
||||
};
|
||||
} // namespace TestImpact
|
||||
|
||||
+6
-6
@@ -19,12 +19,12 @@ namespace UnitTest
|
||||
{
|
||||
namespace
|
||||
{
|
||||
AZ::IO::Path GenerateSourcePath(AZ::u32 index)
|
||||
AZStd::string GenerateSourcePath(AZ::u32 index)
|
||||
{
|
||||
return AZStd::string::format("SourceFile%u", index);
|
||||
}
|
||||
|
||||
AZ::IO::Path GenerateModulePath(AZ::u32 index)
|
||||
AZStd::string GenerateModulePath(AZ::u32 index)
|
||||
{
|
||||
return AZStd::string::format("Module%u", index);
|
||||
}
|
||||
@@ -47,7 +47,7 @@ namespace UnitTest
|
||||
sourceCoverage.m_path = GenerateSourcePath(index);
|
||||
if (coverageLevel == TestImpact::CoverageLevel::Line)
|
||||
{
|
||||
sourceCoverage.m_coverage.emplace(GenerateLineCoverages(index + 1));
|
||||
sourceCoverage.m_coverage = GenerateLineCoverages(index + 1);
|
||||
}
|
||||
|
||||
return sourceCoverage;
|
||||
@@ -152,9 +152,9 @@ namespace UnitTest
|
||||
if (m_coverageLevel == TestImpact::CoverageLevel::Line)
|
||||
{
|
||||
// Expect there to actually be line coverage data if this coverage was procedurally generated with line data
|
||||
EXPECT_TRUE(sourceCoverage.m_coverage.has_value());
|
||||
EXPECT_FALSE(sourceCoverage.m_coverage.empty());
|
||||
|
||||
const AZStd::vector<TestImpact::LineCoverage>& lineCoverages = sourceCoverage.m_coverage.value();
|
||||
const AZStd::vector<TestImpact::LineCoverage>& lineCoverages = sourceCoverage.m_coverage;
|
||||
|
||||
// Expect the source's number of lines to match that of the corresponding procedurally generated source
|
||||
EXPECT_EQ(lineCoverages.size(), sourceIndex + 1);
|
||||
@@ -171,7 +171,7 @@ namespace UnitTest
|
||||
else
|
||||
{
|
||||
// Do not expect there to actually be line coverage data if this coverage was not procedurally generated with line data
|
||||
EXPECT_FALSE(sourceCoverage.m_coverage.has_value());
|
||||
EXPECT_TRUE(sourceCoverage.m_coverage.empty());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+76
-3
@@ -10,11 +10,38 @@
|
||||
#
|
||||
|
||||
set(FILES
|
||||
Include/TestImpactFramework/TestImpactBitwise.h
|
||||
Include/TestImpactFramework/TestImpactCallback.h
|
||||
Include/TestImpactFramework/TestImpactException.h
|
||||
Include/TestImpactFramework/TestImpactFrameworkPath.h
|
||||
Include/TestImpactFramework/TestImpactCallback.h
|
||||
Source/TestImpactException.cpp
|
||||
Source/TestImpactFrameworkPath.cpp
|
||||
Source/Artifact/TestImpactArtifactException.h
|
||||
Source/Artifact/Factory/TestImpactBuildTargetDescriptorFactory.cpp
|
||||
Source/Artifact/Factory/TestImpactBuildTargetDescriptorFactory.h
|
||||
Source/Artifact/Factory/TestImpactChangeListFactory.cpp
|
||||
Source/Artifact/Factory/TestImpactChangeListFactory.h
|
||||
Source/Artifact/Factory/TestImpactTestEnumerationSuiteFactory.cpp
|
||||
Source/Artifact/Factory/TestImpactTestEnumerationSuiteFactory.h
|
||||
Source/Artifact/Factory/TestImpactTestRunSuiteFactory.cpp
|
||||
Source/Artifact/Factory/TestImpactTestRunSuiteFactory.h
|
||||
Source/Artifact/Factory/TestImpactTestTargetMetaMapFactory.cpp
|
||||
Source/Artifact/Factory/TestImpactTestTargetMetaMapFactory.h
|
||||
Source/Artifact/Factory/TestImpactModuleCoverageFactory.cpp
|
||||
Source/Artifact/Factory/TestImpactModuleCoverageFactory.h
|
||||
Source/Artifact/Static/TestImpactBuildTargetDescriptor.cpp
|
||||
Source/Artifact/Static/TestImpactBuildTargetDescriptor.h
|
||||
Source/Artifact/Static/TestImpactTargetDescriptorCompiler.cpp
|
||||
Source/Artifact/Static/TestImpactTargetDescriptorCompiler.h
|
||||
Source/Artifact/Static/TestImpactProductionTargetDescriptor.cpp
|
||||
Source/Artifact/Static/TestImpactProductionTargetDescriptor.h
|
||||
Source/Artifact/Static/TestImpactTestTargetMeta.h
|
||||
Source/Artifact/Static/TestImpactTestTargetDescriptor.cpp
|
||||
Source/Artifact/Static/TestImpactTestTargetDescriptor.h
|
||||
Source/Artifact/Static/TestImpactDependencyGraphData.h
|
||||
Source/Artifact/Dynamic/TestImpactChangelist.h
|
||||
Source/Artifact/Dynamic/TestImpactTestEnumerationSuite.h
|
||||
Source/Artifact/Dynamic/TestImpactTestRunSuite.h
|
||||
Source/Artifact/Dynamic/TestImpactTestSuite.h
|
||||
Source/Artifact/Dynamic/TestImpactCoverage.h
|
||||
Source/Process/TestImpactProcess.cpp
|
||||
Source/Process/TestImpactProcess.h
|
||||
Source/Process/TestImpactProcessException.h
|
||||
@@ -26,4 +53,50 @@ set(FILES
|
||||
Source/Process/JobRunner/TestImpactProcessJobRunner.h
|
||||
Source/Process/Scheduler/TestImpactProcessScheduler.cpp
|
||||
Source/Process/Scheduler/TestImpactProcessScheduler.h
|
||||
Source/Dependency/TestImpactDynamicDependencyMap.cpp
|
||||
Source/Dependency/TestImpactDynamicDependencyMap.h
|
||||
Source/Dependency/TestImpactChangeDependencyList.cpp
|
||||
Source/Dependency/TestImpactChangeDependencyList.h
|
||||
Source/Dependency/TestImpactDependencyException.h
|
||||
Source/Dependency/TestImpactSourceDependency.h
|
||||
Source/Dependency/TestImpactSourceDependency.cpp
|
||||
Source/Dependency/TestImpactTestSelectorAndPrioritizer.h
|
||||
Source/Dependency/TestImpactTestSelectorAndPrioritizer.cpp
|
||||
Source/Dependency/TestImpactSourceCoveringTestsList.h
|
||||
Source/Dependency/TestImpactSourceCoveringTestsList.cpp
|
||||
Source/Target/TestImpactBuildTarget.cpp
|
||||
Source/Target/TestImpactBuildTarget.h
|
||||
Source/Target/TestImpactBuildTargetList.h
|
||||
Source/Target/TestImpactProductionTarget.cpp
|
||||
Source/Target/TestImpactProductionTarget.h
|
||||
Source/Target/TestImpactProductionTargetList.h
|
||||
Source/Target/TestImpactTargetException.h
|
||||
Source/Target/TestImpactTestTarget.cpp
|
||||
Source/Target/TestImpactTestTarget.h
|
||||
Source/Target/TestImpactTestTargetList.h
|
||||
Source/Test/Enumeration/TestImpactTestEnumeration.h
|
||||
Source/Test/Enumeration/TestImpactTestEnumerationException.h
|
||||
Source/Test/Enumeration/TestImpactTestEnumerationSerializer.cpp
|
||||
Source/Test/Enumeration/TestImpactTestEnumerationSerializer.h
|
||||
Source/Test/Enumeration/TestImpactTestEnumerator.cpp
|
||||
Source/Test/Enumeration/TestImpactTestEnumerator.h
|
||||
Source/Test/Run/TestImpactTestRunSerializer.cpp
|
||||
Source/Test/Run/TestImpactTestRunSerializer.h
|
||||
Source/Test/Run/TestImpactTestRunner.cpp
|
||||
Source/Test/Run/TestImpactTestRunner.h
|
||||
Source/Test/Run/TestImpactInstrumentedTestRunner.cpp
|
||||
Source/Test/Run/TestImpactInstrumentedTestRunner.h
|
||||
Source/Test/Run/TestImpactTestRun.cpp
|
||||
Source/Test/Run/TestImpactTestRun.h
|
||||
Source/Test/Run/TestImpactTestRunJobData.cpp
|
||||
Source/Test/Run/TestImpactTestRunJobData.h
|
||||
Source/Test/Run/TestImpactTestCoverage.cpp
|
||||
Source/Test/Run/TestImpactTestCoverage.h
|
||||
Source/Test/Run/TestImpactTestRunException.h
|
||||
Source/Test/Job/TestImpactTestJobRunner.h
|
||||
Source/Test/Job/TestImpactTestJobException.h
|
||||
Source/Test/Job/TestImpactTestJobCommon.h
|
||||
Source/Test/TestImpactTestSuiteContainer.h
|
||||
Source/TestImpactException.cpp
|
||||
Source/TestImpactFrameworkPath.cpp
|
||||
)
|
||||
|
||||
+20
-4
@@ -10,13 +10,29 @@
|
||||
#
|
||||
|
||||
set(FILES
|
||||
Tests/Artifact/TestImpactTargetDescriptorCompilerTest.cpp
|
||||
Tests/Artifact/TestImpactBuildTargetDescriptorFactoryTest.cpp
|
||||
Tests/Artifact/TestImpactModuleCoverageFactoryTest.cpp
|
||||
Tests/Artifact/TestImpactChangeListFactoryTest.cpp
|
||||
Tests/Artifact/TestImpactTestEnumerationSuiteFactoryTest.cpp
|
||||
Tests/Artifact/TestImpactTestRunSuiteFactoryTest.cpp
|
||||
Tests/Artifact/TestImpactTestTargetMetaMapFactoryTest.cpp
|
||||
|
||||
Tests/Process/TestImpactProcessSchedulerTest.cpp
|
||||
|
||||
Tests/Process/TestImpactProcessTest.cpp
|
||||
Tests/Target/TestImpactBuildTargetTest.cpp
|
||||
Tests/TestImpactExceptionTest.cpp
|
||||
Tests/TestImpactFrameworkPathTest.cpp
|
||||
Tests/TestImpactProcessSchedulerTest.cpp
|
||||
Tests/TestImpactProcessTest.cpp
|
||||
Tests/TestImpactProcessTestShared.cpp
|
||||
Tests/TestImpactProcessTestShared.h
|
||||
Tests/Test/TestImpactTestEnumeratorTest.cpp
|
||||
Tests/Test/TestImpactTestEumerationSerializerTest.cpp
|
||||
Tests/Test/TestImpactTestRunSerializerTest.cpp
|
||||
Tests/Test/TestImpactTestRunnerTest.cpp
|
||||
Tests/Test/TestImpactInstrumentedTestRunnerTest.cpp
|
||||
Tests/Test/TestImpactTestCoverageTest.cpp
|
||||
Tests/TestImpactTestJobRunnerCommon.h
|
||||
Tests/TestImpactTestMain.cpp
|
||||
Tests/TestImpactTestUtils.cpp
|
||||
Tests/TestImpactTestUtils.h
|
||||
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user