Merge branch 'development' into cmake/SPEC-7484

Signed-off-by: Esteban Papp <81431996+amznestebanpapp@users.noreply.github.com>

# Conflicts:
#	Code/Editor/ConfigGroup.cpp
#	Code/Editor/ControlMRU.cpp
#	Code/Editor/CryEdit.cpp
#	Code/Editor/CryEdit.h
#	Code/Editor/IEditorImpl.cpp
#	Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/Plugins/StandardPlugins/Source/AnimGraph/GameController.cpp
This commit is contained in:
Esteban Papp
2021-08-10 09:23:34 -07:00
1040 changed files with 29662 additions and 44251 deletions
@@ -262,7 +262,7 @@ namespace TestImpact
Policy::TestFailure testFailurePolicy,
AZStd::optional<AZStd::chrono::milliseconds> testTargetTimeout,
AZStd::optional<AZStd::chrono::milliseconds> globalTimeout,
AZStd::optional<TestEngineJobCompleteCallback> callback)
AZStd::optional<TestEngineJobCompleteCallback> callback) const
{
TestEngineJobMap<TestEnumerator::JobInfo::IdType> engineJobs;
const auto jobInfos = m_testJobInfoGenerator->GenerateTestEnumerationJobInfos(testTargets, TestEnumerator::JobInfo::CachePolicy::Write);
@@ -285,7 +285,7 @@ namespace TestImpact
[[maybe_unused]]Policy::TargetOutputCapture targetOutputCapture,
AZStd::optional<AZStd::chrono::milliseconds> testTargetTimeout,
AZStd::optional<AZStd::chrono::milliseconds> globalTimeout,
AZStd::optional<TestEngineJobCompleteCallback> callback)
AZStd::optional<TestEngineJobCompleteCallback> callback) const
{
DeleteArtifactXmls();
@@ -312,7 +312,7 @@ namespace TestImpact
[[maybe_unused]]Policy::TargetOutputCapture targetOutputCapture,
AZStd::optional<AZStd::chrono::milliseconds> testTargetTimeout,
AZStd::optional<AZStd::chrono::milliseconds> globalTimeout,
AZStd::optional<TestEngineJobCompleteCallback> callback)
AZStd::optional<TestEngineJobCompleteCallback> callback) const
{
DeleteArtifactXmls();
@@ -69,7 +69,7 @@ namespace TestImpact
Policy::TestFailure testFailurePolicy,
AZStd::optional<AZStd::chrono::milliseconds> testTargetTimeout,
AZStd::optional<AZStd::chrono::milliseconds> globalTimeout,
AZStd::optional<TestEngineJobCompleteCallback> callback);
AZStd::optional<TestEngineJobCompleteCallback> callback) const;
//! Performs a test run without any instrumentation and, for each test target, returns the test run results and metrics about the run.
//! @param testTargets The test targets to run.
@@ -89,7 +89,7 @@ namespace TestImpact
Policy::TargetOutputCapture targetOutputCapture,
AZStd::optional<AZStd::chrono::milliseconds> testTargetTimeout,
AZStd::optional<AZStd::chrono::milliseconds> globalTimeout,
AZStd::optional<TestEngineJobCompleteCallback> callback);
AZStd::optional<TestEngineJobCompleteCallback> callback) const;
//! Performs a test run with instrumentation and, for each test target, returns the test run results, coverage data and metrics about the run.
//! @param testTargets The test targets to run.
@@ -111,7 +111,7 @@ namespace TestImpact
Policy::TargetOutputCapture targetOutputCapture,
AZStd::optional<AZStd::chrono::milliseconds> testTargetTimeout,
AZStd::optional<AZStd::chrono::milliseconds> globalTimeout,
AZStd::optional<TestEngineJobCompleteCallback> callback);
AZStd::optional<TestEngineJobCompleteCallback> callback) const;
private:
//! Cleans up the artifacts directory of any artifacts from previous runs.
@@ -1,120 +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 <TestImpactFramework/TestImpactClientFailureReport.h>
namespace TestImpact
{
namespace Client
{
TargetFailure::TargetFailure(const AZStd::string& targetName)
: m_targetName(targetName)
{
}
const AZStd::string& TargetFailure::GetTargetName() const
{
return m_targetName;
}
ExecutionFailure::ExecutionFailure(const AZStd::string& targetName, const AZStd::string& command)
: TargetFailure(targetName)
, m_commandString(command)
{
}
const AZStd::string& ExecutionFailure::GetCommandString() const
{
return m_commandString;
}
TestFailure::TestFailure(const AZStd::string& testName, const AZStd::string& errorMessage)
: m_name(testName)
, m_errorMessage(errorMessage)
{
}
const AZStd::string& TestFailure::GetName() const
{
return m_name;
}
const AZStd::string& TestFailure::GetErrorMessage() const
{
return m_errorMessage;
}
TestCaseFailure::TestCaseFailure(const AZStd::string& testCaseName, AZStd::vector<TestFailure>&& testFailures)
: m_name(testCaseName)
, m_testFailures(AZStd::move(testFailures))
{
}
const AZStd::string& TestCaseFailure::GetName() const
{
return m_name;
}
const AZStd::vector<TestFailure>& TestCaseFailure::GetTestFailures() const
{
return m_testFailures;
}
TestRunFailure::TestRunFailure(const AZStd::string& targetName, AZStd::vector<TestCaseFailure>&& testFailures)
: TargetFailure(targetName)
, m_testCaseFailures(AZStd::move(testFailures))
{
for (const auto& testCase : m_testCaseFailures)
{
m_numTestFailures += testCase.GetTestFailures().size();
}
}
size_t TestRunFailure::GetNumTestFailures() const
{
return m_numTestFailures;
}
const AZStd::vector<TestCaseFailure>& TestRunFailure::GetTestCaseFailures() const
{
return m_testCaseFailures;
}
SequenceFailure::SequenceFailure(
AZStd::vector<ExecutionFailure>&& executionFailures,
AZStd::vector<TestRunFailure>&& testRunFailures,
AZStd::vector<TargetFailure>&& timedOutTests,
AZStd::vector<TargetFailure>&& unexecutionTests)
: m_executionFailures(AZStd::move(executionFailures))
, m_testRunFailures(testRunFailures)
, m_timedOutTests(AZStd::move(timedOutTests))
, m_unexecutedTests(AZStd::move(unexecutionTests))
{
}
const AZStd::vector<ExecutionFailure>& SequenceFailure::GetExecutionFailures() const
{
return m_executionFailures;
}
const AZStd::vector<TestRunFailure>& SequenceFailure::GetTestRunFailures() const
{
return m_testRunFailures;
}
const AZStd::vector<TargetFailure>& SequenceFailure::GetTimedOutTests() const
{
return m_timedOutTests;
}
const AZStd::vector<TargetFailure>& SequenceFailure::GetUnexecutedTests() const
{
return m_unexecutedTests;
}
} // namespace Client
} // namespace TestImpact
@@ -0,0 +1,312 @@
/*
* 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 <TestImpactFramework/TestImpactClientSequenceReport.h>
namespace TestImpact
{
namespace Client
{
//! Calculates the final sequence result for a composite of multiple sequences.
TestSequenceResult CalculateMultiTestSequenceResult(const AZStd::vector<TestSequenceResult>& results)
{
// Order of precedence:
// 1. TestSequenceResult::Failure
// 2. TestSequenceResult::Timeout
// 3. TestSequenceResult::Success
if (const auto it = AZStd::find(results.begin(), results.end(), TestSequenceResult::Failure);
it != results.end())
{
return TestSequenceResult::Failure;
}
if (const auto it = AZStd::find(results.begin(), results.end(), TestSequenceResult::Timeout);
it != results.end())
{
return TestSequenceResult::Timeout;
}
return TestSequenceResult::Success;
}
TestRunReport::TestRunReport(
TestSequenceResult result,
AZStd::chrono::high_resolution_clock::time_point startTime,
AZStd::chrono::milliseconds duration,
AZStd::vector<TestRun>&& passingTests,
AZStd::vector<TestRunWithTestFailures>&& failingTests,
AZStd::vector<TestRun>&& executionFailureTests,
AZStd::vector<TestRun>&& timedOutTests,
AZStd::vector<TestRun>&& unexecutedTests)
: m_startTime(startTime)
, m_result(result)
, m_duration(duration)
, m_passingTests(AZStd::move(passingTests))
, m_failingTests(AZStd::move(failingTests))
, m_executionFailureTests(AZStd::move(executionFailureTests))
, m_timedOutTests(AZStd::move(timedOutTests))
, m_unexecutedTests(AZStd::move(unexecutedTests))
{
}
TestSequenceResult TestRunReport::GetResult() const
{
return m_result;
}
AZStd::chrono::high_resolution_clock::time_point TestRunReport::GetStartTime() const
{
return m_startTime;
}
AZStd::chrono::high_resolution_clock::time_point TestRunReport::GetEndTime() const
{
return m_startTime + m_duration;
}
AZStd::chrono::milliseconds TestRunReport::GetDuration() const
{
return m_duration;
}
size_t TestRunReport::GetNumPassingTests() const
{
return m_passingTests.size();
}
size_t TestRunReport::GetNumFailingTests() const
{
return m_failingTests.size();
}
size_t TestRunReport::GetNumTimedOutTests() const
{
return m_timedOutTests.size();
}
size_t TestRunReport::GetNumUnexecutedTests() const
{
return m_unexecutedTests.size();
}
const AZStd::vector<TestRun>& TestRunReport::GetPassingTests() const
{
return m_passingTests;
}
const AZStd::vector<TestRunWithTestFailures>& TestRunReport::GetFailingTests() const
{
return m_failingTests;
}
const AZStd::vector<TestRun>& TestRunReport::GetExecutionFailureTests() const
{
return m_executionFailureTests;
}
const AZStd::vector<TestRun>& TestRunReport::GetTimedOutTests() const
{
return m_timedOutTests;
}
const AZStd::vector<TestRun>& TestRunReport::GetUnexecutedTests() const
{
return m_unexecutedTests;
}
SequenceReport::SequenceReport(SuiteType suiteType, const TestRunSelection& selectedTests, TestRunReport&& selectedTestRunReport)
: m_suite(suiteType)
, m_selectedTests(selectedTests)
, m_selectedTestRunReport(AZStd::move(selectedTestRunReport))
{
}
TestSequenceResult SequenceReport::GetResult() const
{
return m_selectedTestRunReport.GetResult();
}
AZStd::chrono::high_resolution_clock::time_point SequenceReport::GetStartTime() const
{
return m_selectedTestRunReport.GetStartTime();
}
AZStd::chrono::high_resolution_clock::time_point SequenceReport::GetEndTime() const
{
return GetStartTime() + GetDuration();
}
AZStd::chrono::milliseconds SequenceReport::GetDuration() const
{
return m_selectedTestRunReport.GetDuration();
}
TestRunSelection SequenceReport::GetSelectedTests() const
{
return m_selectedTests;
}
TestRunReport SequenceReport::GetSelectedTestRunReport() const
{
return m_selectedTestRunReport;
}
size_t SequenceReport::GetTotalNumPassingTests() const
{
return m_selectedTestRunReport.GetNumPassingTests();
}
size_t SequenceReport::GetTotalNumFailingTests() const
{
return m_selectedTestRunReport.GetNumFailingTests();
}
size_t SequenceReport::GetTotalNumTimedOutTests() const
{
return m_selectedTestRunReport.GetNumTimedOutTests();
}
size_t SequenceReport::GetTotalNumUnexecutedTests() const
{
return m_selectedTestRunReport.GetNumUnexecutedTests();
}
DraftingSequenceReport::DraftingSequenceReport(
SuiteType suiteType,
const TestRunSelection& selectedTests,
const AZStd::vector<AZStd::string>& draftedTests,
TestRunReport&& selectedTestRunReport,
TestRunReport&& draftedTestRunReport)
: SequenceReport(suiteType, selectedTests, AZStd::move(selectedTestRunReport))
, m_draftedTests(draftedTests)
, m_draftedTestRunReport(AZStd::move(draftedTestRunReport))
{
}
TestSequenceResult DraftingSequenceReport::GetResult() const
{
return CalculateMultiTestSequenceResult({SequenceReport::GetResult(), m_draftedTestRunReport.GetResult()});
}
AZStd::chrono::milliseconds DraftingSequenceReport::GetDuration() const
{
return SequenceReport::GetDuration() + m_draftedTestRunReport.GetDuration();
}
size_t DraftingSequenceReport::GetTotalNumPassingTests() const
{
return SequenceReport::GetTotalNumPassingTests() + m_draftedTestRunReport.GetNumPassingTests();
}
size_t DraftingSequenceReport::GetTotalNumFailingTests() const
{
return SequenceReport::GetTotalNumFailingTests() + m_draftedTestRunReport.GetNumFailingTests();
}
size_t DraftingSequenceReport::GetTotalNumTimedOutTests() const
{
return SequenceReport::GetTotalNumTimedOutTests() + m_draftedTestRunReport.GetNumTimedOutTests();
}
size_t DraftingSequenceReport::GetTotalNumUnexecutedTests() const
{
return SequenceReport::GetTotalNumUnexecutedTests() + m_draftedTestRunReport.GetNumUnexecutedTests();
}
const AZStd::vector<AZStd::string>& DraftingSequenceReport::GetDraftedTests() const
{
return m_draftedTests;
}
TestRunReport DraftingSequenceReport::GetDraftedTestRunReport() const
{
return m_draftedTestRunReport;
}
ImpactAnalysisSequenceReport::ImpactAnalysisSequenceReport(
SuiteType suiteType,
const TestRunSelection& selectedTests,
const AZStd::vector<AZStd::string>& discardedTests,
const AZStd::vector<AZStd::string>& draftedTests,
TestRunReport&& selectedTestRunReport,
TestRunReport&& draftedTestRunReport)
: DraftingSequenceReport(
suiteType,
selectedTests,
draftedTests,
AZStd::move(selectedTestRunReport),
AZStd::move(draftedTestRunReport))
, m_discardedTests(discardedTests)
{
}
const AZStd::vector<AZStd::string>& ImpactAnalysisSequenceReport::GetDiscardedTests() const
{
return m_discardedTests;
}
SafeImpactAnalysisSequenceReport::SafeImpactAnalysisSequenceReport(
SuiteType suiteType,
const TestRunSelection& selectedTests,
const TestRunSelection& discardedTests,
const AZStd::vector<AZStd::string>& draftedTests,
TestRunReport&& selectedTestRunReport,
TestRunReport&& discardedTestRunReport,
TestRunReport&& draftedTestRunReport)
: DraftingSequenceReport(
suiteType,
selectedTests,
draftedTests,
AZStd::move(selectedTestRunReport),
AZStd::move(draftedTestRunReport))
, m_discardedTests(discardedTests)
, m_discardedTestRunReport(AZStd::move(discardedTestRunReport))
{
}
TestSequenceResult SafeImpactAnalysisSequenceReport::GetResult() const
{
return CalculateMultiTestSequenceResult({ DraftingSequenceReport::GetResult(), m_discardedTestRunReport.GetResult() });
}
AZStd::chrono::milliseconds SafeImpactAnalysisSequenceReport::GetDuration() const
{
return DraftingSequenceReport::GetDuration() + m_discardedTestRunReport.GetDuration();
}
size_t SafeImpactAnalysisSequenceReport::GetTotalNumPassingTests() const
{
return DraftingSequenceReport::GetTotalNumPassingTests() + m_discardedTestRunReport.GetNumPassingTests();
}
size_t SafeImpactAnalysisSequenceReport::GetTotalNumFailingTests() const
{
return DraftingSequenceReport::GetTotalNumFailingTests() + m_discardedTestRunReport.GetNumFailingTests();
}
size_t SafeImpactAnalysisSequenceReport::GetTotalNumTimedOutTests() const
{
return DraftingSequenceReport::GetTotalNumTimedOutTests() + m_discardedTestRunReport.GetNumTimedOutTests();
}
size_t SafeImpactAnalysisSequenceReport::GetTotalNumUnexecutedTests() const
{
return DraftingSequenceReport::GetTotalNumUnexecutedTests() + m_discardedTestRunReport.GetNumUnexecutedTests();
}
const TestRunSelection SafeImpactAnalysisSequenceReport::GetDiscardedTests() const
{
return m_discardedTests;
}
TestRunReport SafeImpactAnalysisSequenceReport::GetDiscardedTestRunReport() const
{
return m_discardedTestRunReport;
}
} // namespace Client
} // namespace TestImpact
@@ -7,14 +7,22 @@
*/
#include <TestImpactFramework/TestImpactClientTestRun.h>
namespace TestImpact
{
namespace Client
{
TestRun::TestRun(const AZStd::string& name, TestRunResult result, AZStd::chrono::milliseconds duration)
TestRun::TestRun(
const AZStd::string& name,
const AZStd::string& commandString,
AZStd::chrono::high_resolution_clock::time_point startTime,
AZStd::chrono::milliseconds duration,
TestRunResult result)
: m_targetName(name)
, m_result(result)
, m_commandString(commandString)
, m_startTime(startTime)
, m_duration(duration)
, m_result(result)
{
}
@@ -23,6 +31,21 @@ namespace TestImpact
return m_targetName;
}
const AZStd::string& TestRun::GetCommandString() const
{
return m_commandString;
}
AZStd::chrono::high_resolution_clock::time_point TestRun::GetStartTime() const
{
return m_startTime;
}
AZStd::chrono::high_resolution_clock::time_point TestRun::GetEndTime() const
{
return m_startTime + m_duration;
}
AZStd::chrono::milliseconds TestRun::GetDuration() const
{
return m_duration;
@@ -32,5 +55,78 @@ namespace TestImpact
{
return m_result;
}
TestFailure::TestFailure(const AZStd::string& testName, const AZStd::string& errorMessage)
: m_name(testName)
, m_errorMessage(errorMessage)
{
}
const AZStd::string& TestFailure::GetName() const
{
return m_name;
}
const AZStd::string& TestFailure::GetErrorMessage() const
{
return m_errorMessage;
}
TestCaseFailure::TestCaseFailure(const AZStd::string& testCaseName, AZStd::vector<TestFailure>&& testFailures)
: m_name(testCaseName)
, m_testFailures(AZStd::move(testFailures))
{
}
const AZStd::string& TestCaseFailure::GetName() const
{
return m_name;
}
const AZStd::vector<TestFailure>& TestCaseFailure::GetTestFailures() const
{
return m_testFailures;
}
static size_t CalculateNumTestRunFailures(const AZStd::vector<TestCaseFailure>& testFailures)
{
size_t numTestFailures = 0;
for (const auto& testCase : testFailures)
{
numTestFailures += testCase.GetTestFailures().size();
}
return numTestFailures;
}
TestRunWithTestFailures::TestRunWithTestFailures(
const AZStd::string& name,
const AZStd::string& commandString,
AZStd::chrono::high_resolution_clock::time_point startTime,
AZStd::chrono::milliseconds duration,
TestRunResult result,
AZStd::vector<TestCaseFailure>&& testFailures)
: TestRun(name, commandString, startTime, duration, result)
, m_testCaseFailures(AZStd::move(testFailures))
{
m_numTestFailures = CalculateNumTestRunFailures(m_testCaseFailures);
}
TestRunWithTestFailures::TestRunWithTestFailures(TestRun&& testRun, AZStd::vector<TestCaseFailure>&& testFailures)
: TestRun(AZStd::move(testRun))
, m_testCaseFailures(AZStd::move(testFailures))
{
m_numTestFailures = CalculateNumTestRunFailures(m_testCaseFailures);
}
size_t TestRunWithTestFailures::GetNumTestFailures() const
{
return m_numTestFailures;
}
const AZStd::vector<TestCaseFailure>& TestRunWithTestFailures::GetTestCaseFailures() const
{
return m_testCaseFailures;
}
} // namespace Client
} // namespace TestImpact
@@ -34,13 +34,33 @@ namespace TestImpact
{
}
//! Returns the time elapsed (in milliseconds) since the timer was instantiated
AZStd::chrono::milliseconds Elapsed()
//! Returns the time point that the timer was instantiated.
AZStd::chrono::high_resolution_clock::time_point GetStartTimePoint() const
{
return m_startTime;
}
//! Returns the time point that the timer was instantiated relative to the specified starting time point.
AZStd::chrono::high_resolution_clock::time_point GetStartTimePointRelative(const Timer& start) const
{
return AZStd::chrono::high_resolution_clock::time_point() +
AZStd::chrono::duration_cast<AZStd::chrono::milliseconds>(m_startTime - start.GetStartTimePoint());
}
//! Returns the time elapsed (in milliseconds) since the timer was instantiated.
AZStd::chrono::milliseconds GetElapsedMs() const
{
const auto endTime = AZStd::chrono::high_resolution_clock::now();
return AZStd::chrono::duration_cast<AZStd::chrono::milliseconds>(endTime - m_startTime);
}
//! Returns the current time point relative to the time point the timer was instantiated.
AZStd::chrono::high_resolution_clock::time_point GetElapsedTimepoint() const
{
const auto endTime = AZStd::chrono::high_resolution_clock::now();
return m_startTime + AZStd::chrono::duration_cast<AZStd::chrono::milliseconds>(endTime - m_startTime);
}
private:
AZStd::chrono::high_resolution_clock::time_point m_startTime;
};
@@ -49,8 +69,11 @@ namespace TestImpact
class TestRunCompleteCallbackHandler
{
public:
TestRunCompleteCallbackHandler(AZStd::optional<TestRunCompleteCallback> testCompleteCallback)
: m_testCompleteCallback(testCompleteCallback)
TestRunCompleteCallbackHandler(
size_t totalTests,
AZStd::optional<TestRunCompleteCallback> testCompleteCallback)
: m_totalTests(totalTests)
, m_testCompleteCallback(testCompleteCallback)
{
}
@@ -58,19 +81,27 @@ namespace TestImpact
{
if (m_testCompleteCallback.has_value())
{
(*m_testCompleteCallback)
(Client::TestRun(testJob.GetTestTarget()->GetName(), testJob.GetTestResult(), testJob.GetDuration()));
Client::TestRun testRun(
testJob.GetTestTarget()->GetName(),
testJob.GetCommandString(),
testJob.GetStartTime(),
testJob.GetDuration(),
testJob.GetTestResult());
(*m_testCompleteCallback)(testRun, ++m_numTestsCompleted, m_totalTests);
}
}
private:
const size_t m_totalTests; //!< The total number of tests to run for the entire sequence.
size_t m_numTestsCompleted = 0; //!< The running total of tests that have completed.
AZStd::optional<TestRunCompleteCallback> m_testCompleteCallback;
};
}
//! Utility for concatenating two vectors.
template<typename T>
AZStd::vector<T> ConcatenateVectors(const AZStd::vector<T>& v1, const AZStd::vector<T>& v2)
static AZStd::vector<T> ConcatenateVectors(const AZStd::vector<T>& v1, const AZStd::vector<T>& v2)
{
AZStd::vector<T> result;
result.reserve(v1.size() + v2.size());
@@ -298,6 +329,7 @@ namespace TestImpact
continue;
}
// Add the sources covered by this test target to the coverage map
for (const auto& source : job.GetTestCoverge().value().GetSourcesCovered())
{
coverage[source.String()].insert(job.GetTestTarget()->GetName());
@@ -309,6 +341,7 @@ namespace TestImpact
sourceCoveringTests.reserve(coverage.size());
for (auto&& [source, testTargets] : coverage)
{
// 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))
{
@@ -353,17 +386,17 @@ namespace TestImpact
}
}
TestSequenceResult Runtime::RegularTestSequence(
Client::SequenceReport Runtime::RegularTestSequence(
AZStd::optional<AZStd::chrono::milliseconds> testTargetTimeout,
AZStd::optional<AZStd::chrono::milliseconds> globalTimeout,
AZStd::optional<TestSequenceStartCallback> testSequenceStartCallback,
AZStd::optional<TestSequenceCompleteCallback> testSequenceEndCallback,
AZStd::optional<TestSequenceCompleteCallback<Client::SequenceReport>> testSequenceEndCallback,
AZStd::optional<TestRunCompleteCallback> testCompleteCallback)
{
Timer timer;
const Timer sequenceTimer;
AZStd::vector<const TestTarget*> includedTestTargets;
AZStd::vector<const TestTarget*> 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())
{
@@ -378,12 +411,17 @@ namespace TestImpact
}
}
// Sequence start callback
// Extract the client facing representation of selected test targets
const Client::TestRunSelection selectedTests(ExtractTestTargetNames(includedTestTargets), ExtractTestTargetNames(excludedTestTargets));
// Inform the client that the sequence is about to start
if (testSequenceStartCallback.has_value())
{
(*testSequenceStartCallback)(Client::TestRunSelection(ExtractTestTargetNames(includedTestTargets), ExtractTestTargetNames(excludedTestTargets)));
(*testSequenceStartCallback)(m_suiteFilter, selectedTests);
}
// Run the test targets and collect the test run results
const Timer testRunTimer;
const auto [result, testJobs] = m_testEngine->RegularRun(
includedTestTargets,
m_testShardingPolicy,
@@ -392,27 +430,124 @@ namespace TestImpact
m_targetOutputCapture,
testTargetTimeout,
globalTimeout,
TestRunCompleteCallbackHandler(testCompleteCallback));
TestRunCompleteCallbackHandler(includedTestTargets.size(), testCompleteCallback));
const auto testRunDuration = testRunTimer.GetElapsedMs();
// Generate the sequence report for the client
const auto sequenceReport = Client::SequenceReport(
m_suiteFilter,
selectedTests,
GenerateTestRunReport(result, testRunTimer.GetStartTimePointRelative(sequenceTimer), testRunDuration, testJobs));
// Inform the client that the sequence has ended
if (testSequenceEndCallback.has_value())
{
(*testSequenceEndCallback)(GenerateSequenceFailureReport(testJobs), timer.Elapsed());
(*testSequenceEndCallback)(sequenceReport);
}
return result;
return sequenceReport;
}
TestSequenceResult Runtime::ImpactAnalysisTestSequence(
//! Wrapper for the impact analysis test sequence to handle both the updating and non-updating policies through a common pathway.
//! @tparam TestRunnerFunctor The functor for running the specified tests.
//! @tparam TestJob The test engine job type returned by the functor.
//! @param suiteType The suite type used for this sequence.
//! @param timer The timer to use for the test run timings.
//! @param testRunner The test runner functor to use for each of the test runs.
//! @param includedSelectedTestTargets The subset of test targets that were selected to run and not also fully excluded from running.
//! @param excludedSelectedTestTargets The subset of test targets that were selected to run but were fully excluded running.
//! @param discardedTestTargets The subset of test targets that were discarded from the test selection and will not be run.
//! @param globalTimeout The maximum duration the entire test sequence may run for (infinite if empty).
//! @param testSequenceStartCallback The client function to be called after the test targets have been selected but prior to running the tests.
//! @param testSequenceCompleteCallback The client function to be called after the test sequence has completed.
//! @param testRunCompleteCallback The client function to be called after an individual test run has completed.
//! @param updateCoverage The function to call to update the dynamic dependency map with test coverage (if any).
template<typename TestRunnerFunctor, typename TestJob>
Client::ImpactAnalysisSequenceReport ImpactAnalysisTestSequenceWrapper(
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::optional<AZStd::chrono::milliseconds> globalTimeout,
AZStd::optional<ImpactAnalysisTestSequenceStartCallback> testSequenceStartCallback,
AZStd::optional<TestSequenceCompleteCallback<Client::ImpactAnalysisSequenceReport>> testSequenceEndCallback,
AZStd::optional<TestRunCompleteCallback> testCompleteCallback,
AZStd::optional<AZStd::function<void(const AZStd::vector<TestJob>& jobs)>> updateCoverage)
{
AZStd::optional<AZStd::chrono::milliseconds> sequenceTimeout = globalTimeout;
// Extract the client facing representation of selected, discarded and drafted test targets
const Client::TestRunSelection selectedTests(
ExtractTestTargetNames(includedSelectedTestTargets), ExtractTestTargetNames(excludedSelectedTestTargets));
const auto discardedTests = ExtractTestTargetNames(discardedTestTargets);
const auto draftedTests = ExtractTestTargetNames(draftedTestTargets);
// Inform the client that the sequence is about to start
if (testSequenceStartCallback.has_value())
{
(*testSequenceStartCallback)(suiteType, selectedTests, discardedTests, draftedTests);
}
// We share the test run complete handler between the selected and drafted test runs as to present them together as one
// continuous test sequence to the client rather than two discrete test runs
const size_t totalNumTestRuns = includedSelectedTestTargets.size() + draftedTestTargets.size();
TestRunCompleteCallbackHandler testRunCompleteHandler(totalNumTestRuns, testCompleteCallback);
// Run the selected test targets and collect the test run results
const Timer selectedTestRunTimer;
const auto [selectedResult, selectedTestJobs] = testRunner(includedSelectedTestTargets, testRunCompleteHandler, globalTimeout);
const auto selectedTestRunDuration = selectedTestRunTimer.GetElapsedMs();
// Carry the remaining global sequence time over to the drafted test run
if (globalTimeout.has_value())
{
const auto elapsed = selectedTestRunDuration;
sequenceTimeout = elapsed < globalTimeout.value() ? globalTimeout.value() - elapsed : AZStd::chrono::milliseconds(0);
}
// Run the drafted test targets and collect the test run results
Timer draftedTestRunTimer;
const auto [draftedResult, draftedTestJobs] = testRunner(draftedTestTargets, testRunCompleteHandler, globalTimeout);
const auto draftedTestRunDuration = draftedTestRunTimer.GetElapsedMs();
// Generate the sequence report for the client
const auto sequenceReport = Client::ImpactAnalysisSequenceReport(
suiteType,
selectedTests,
discardedTests,
draftedTests,
GenerateTestRunReport(selectedResult, selectedTestRunTimer.GetStartTimePointRelative(sequenceTimer), selectedTestRunDuration, selectedTestJobs),
GenerateTestRunReport(draftedResult, draftedTestRunTimer.GetStartTimePointRelative(sequenceTimer), draftedTestRunDuration, draftedTestJobs));
// Inform the client that the sequence has ended
if (testSequenceEndCallback.has_value())
{
(*testSequenceEndCallback)(sequenceReport);
}
// Update the dynamic dependency map with the latest coverage data (if any)
if (updateCoverage.has_value())
{
(*updateCoverage)(ConcatenateVectors(selectedTestJobs, draftedTestJobs));
}
return sequenceReport;
}
Client::ImpactAnalysisSequenceReport Runtime::ImpactAnalysisTestSequence(
const ChangeList& changeList,
Policy::TestPrioritization testPrioritizationPolicy,
Policy::DynamicDependencyMap dynamicDependencyMapPolicy,
AZStd::optional<AZStd::chrono::milliseconds> testTargetTimeout,
AZStd::optional<AZStd::chrono::milliseconds> globalTimeout,
AZStd::optional<ImpactAnalysisTestSequenceStartCallback> testSequenceStartCallback,
AZStd::optional<TestSequenceCompleteCallback> testSequenceEndCallback,
AZStd::optional<TestSequenceCompleteCallback<Client::ImpactAnalysisSequenceReport>> testSequenceEndCallback,
AZStd::optional<TestRunCompleteCallback> testCompleteCallback)
{
Timer timer;
const Timer sequenceTimer;
// Draft in the test targets that have no coverage entries in the dynamic dependency map
AZStd::vector<const TestTarget*> draftedTestTargets = m_dynamicDependencyMap->GetNotCoveringTests();
@@ -423,71 +558,94 @@ namespace TestImpact
// The subset of selected test targets that are not on the configuration's exclude list and those that are
auto [includedSelectedTestTargets, excludedSelectedTestTargets] = SelectTestTargetsByExcludeList(selectedTestTargets);
// We present to the client the included selected test targets and the drafted test targets as distinct sets but internally
// we consider the concatenated set of the two the actual set of tests to run
AZStd::vector<const TestTarget*> testTargetsToRun = ConcatenateVectors(includedSelectedTestTargets, draftedTestTargets);
if (testSequenceStartCallback.has_value())
// Functor for running instrumented test targets
const auto instrumentedTestRun =
[this, &testTargetTimeout](
const AZStd::vector<const TestTarget*>& testsTargets,
TestRunCompleteCallbackHandler& testRunCompleteHandler,
AZStd::optional<AZStd::chrono::milliseconds> globalTimeout)
{
(*testSequenceStartCallback)(
Client::TestRunSelection(ExtractTestTargetNames(includedSelectedTestTargets), ExtractTestTargetNames(excludedSelectedTestTargets)),
ExtractTestTargetNames(discardedTestTargets),
ExtractTestTargetNames(draftedTestTargets));
}
return m_testEngine->InstrumentedRun(
testsTargets,
m_testShardingPolicy,
m_executionFailurePolicy,
m_integrationFailurePolicy,
m_testFailurePolicy,
m_targetOutputCapture,
testTargetTimeout,
globalTimeout,
AZStd::ref(testRunCompleteHandler));
};
// Functor for running uninstrumented test targets
const auto regularTestRun =
[this, &testTargetTimeout](
const AZStd::vector<const TestTarget*>& testsTargets,
TestRunCompleteCallbackHandler& testRunCompleteHandler,
AZStd::optional<AZStd::chrono::milliseconds> globalTimeout)
{
return m_testEngine->RegularRun(
testsTargets,
m_testShardingPolicy,
m_executionFailurePolicy,
m_testFailurePolicy,
m_targetOutputCapture,
testTargetTimeout,
globalTimeout,
AZStd::ref(testRunCompleteHandler));
};
if (dynamicDependencyMapPolicy == Policy::DynamicDependencyMap::Update)
{
const auto [result, testJobs] = m_testEngine->InstrumentedRun(
testTargetsToRun,
m_testShardingPolicy,
m_executionFailurePolicy,
Policy::IntegrityFailure::Continue,
m_testFailurePolicy,
m_targetOutputCapture,
testTargetTimeout,
globalTimeout,
TestRunCompleteCallbackHandler(testCompleteCallback));
UpdateAndSerializeDynamicDependencyMap(testJobs);
if (testSequenceEndCallback.has_value())
AZStd::optional<AZStd::function<void(const AZStd::vector<TestEngineInstrumentedRun>& jobs)>> updateCoverage =
[this](const AZStd::vector<TestEngineInstrumentedRun>& jobs)
{
(*testSequenceEndCallback)(GenerateSequenceFailureReport(testJobs), timer.Elapsed());
}
UpdateAndSerializeDynamicDependencyMap(jobs);
};
return result;
return ImpactAnalysisTestSequenceWrapper(
m_suiteFilter,
sequenceTimer,
instrumentedTestRun,
includedSelectedTestTargets,
excludedSelectedTestTargets,
discardedTestTargets,
draftedTestTargets,
globalTimeout,
testSequenceStartCallback,
testSequenceEndCallback,
testCompleteCallback,
updateCoverage);
}
else
{
const auto [result, testJobs] = m_testEngine->RegularRun(
testTargetsToRun,
m_testShardingPolicy,
m_executionFailurePolicy,
m_testFailurePolicy,
m_targetOutputCapture,
testTargetTimeout,
return ImpactAnalysisTestSequenceWrapper(
m_suiteFilter,
sequenceTimer,
regularTestRun,
includedSelectedTestTargets,
excludedSelectedTestTargets,
discardedTestTargets,
draftedTestTargets,
globalTimeout,
TestRunCompleteCallbackHandler(testCompleteCallback));
if (testSequenceEndCallback.has_value())
{
(*testSequenceEndCallback)(GenerateSequenceFailureReport(testJobs), timer.Elapsed());
}
return result;
testSequenceStartCallback,
testSequenceEndCallback,
testCompleteCallback,
AZStd::optional<AZStd::function<void(const AZStd::vector<TestEngineRegularRun>& jobs)>>{ AZStd::nullopt });
}
}
AZStd::pair<TestSequenceResult, TestSequenceResult> Runtime::SafeImpactAnalysisTestSequence(
Client::SafeImpactAnalysisSequenceReport Runtime::SafeImpactAnalysisTestSequence(
const ChangeList& changeList,
Policy::TestPrioritization testPrioritizationPolicy,
AZStd::optional<AZStd::chrono::milliseconds> testTargetTimeout,
AZStd::optional<AZStd::chrono::milliseconds> globalTimeout,
AZStd::optional<SafeImpactAnalysisTestSequenceStartCallback> testSequenceStartCallback,
AZStd::optional<SafeTestSequenceCompleteCallback> testSequenceEndCallback,
AZStd::optional<TestSequenceCompleteCallback<Client::SafeImpactAnalysisSequenceReport>> testSequenceEndCallback,
AZStd::optional<TestRunCompleteCallback> testCompleteCallback)
{
Timer timer;
const Timer sequenceTimer;
auto 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();
@@ -501,40 +659,46 @@ namespace TestImpact
// The subset of discarded test targets that are not on the configuration's exclude list and those that are
auto [includedDiscardedTestTargets, excludedDiscardedTestTargets] = SelectTestTargetsByExcludeList(discardedTestTargets);
// We present to the client the included selected test targets and the drafted test targets as distinct sets but internally
// we consider the concatenated set of the two the actual set of tests to run
AZStd::vector<const TestTarget*> testTargetsToRun = ConcatenateVectors(includedSelectedTestTargets, draftedTestTargets);
// Extract the client facing representation of selected, discarded and drafted test targets
const Client::TestRunSelection selectedTests(
ExtractTestTargetNames(includedSelectedTestTargets), ExtractTestTargetNames(excludedSelectedTestTargets));
const Client::TestRunSelection discardedTests(ExtractTestTargetNames(includedDiscardedTestTargets), ExtractTestTargetNames(excludedDiscardedTestTargets));
const auto draftedTests = ExtractTestTargetNames(draftedTestTargets);
// Inform the client that the sequence is about to start
if (testSequenceStartCallback.has_value())
{
(*testSequenceStartCallback)(
Client::TestRunSelection(ExtractTestTargetNames(includedSelectedTestTargets), ExtractTestTargetNames(excludedSelectedTestTargets)),
Client::TestRunSelection(ExtractTestTargetNames(includedDiscardedTestTargets), ExtractTestTargetNames(excludedDiscardedTestTargets)),
ExtractTestTargetNames(draftedTestTargets));
(*testSequenceStartCallback)(m_suiteFilter, selectedTests, discardedTests, draftedTests);
}
// Impact analysis run of the selected test targets
// We share the test run complete handler between the selected, discarded and drafted test runs as to present them together as one
// continuous test sequence to the client rather than three discrete test runs
const size_t totalNumTestRuns = includedSelectedTestTargets.size() + draftedTestTargets.size() + includedDiscardedTestTargets.size();
TestRunCompleteCallbackHandler testRunCompleteHandler(totalNumTestRuns, testCompleteCallback);
// Run the selected test targets and collect the test run results
const Timer selectedTestRunTimer;
const auto [selectedResult, selectedTestJobs] = m_testEngine->InstrumentedRun(
testTargetsToRun,
includedSelectedTestTargets,
m_testShardingPolicy,
m_executionFailurePolicy,
Policy::IntegrityFailure::Continue,
m_integrationFailurePolicy,
m_testFailurePolicy,
m_targetOutputCapture,
testTargetTimeout,
globalTimeout,
TestRunCompleteCallbackHandler(testCompleteCallback));
const auto selectedDuraton = timer.Elapsed();
sequenceTimeout,
AZStd::ref(testRunCompleteHandler));
const auto selectedTestRunDuration = selectedTestRunTimer.GetElapsedMs();
// Carry the remaining global sequence time over to the discarded test run
if (globalTimeout.has_value())
{
const auto elapsed = timer.Elapsed();
globalTimeout = elapsed < globalTimeout.value() ? globalTimeout.value() - elapsed : AZStd::chrono::milliseconds(0);
const auto elapsed = selectedTestRunDuration;
sequenceTimeout = elapsed < globalTimeout.value() ? globalTimeout.value() - elapsed : AZStd::chrono::milliseconds(0);
}
// Regular run of the discarded test targets
// Run the discarded test targets and collect the test run results
const Timer discardedTestRunTimer;
const auto [discardedResult, discardedTestJobs] = m_testEngine->RegularRun(
includedDiscardedTestTargets,
m_testShardingPolicy,
@@ -542,35 +706,63 @@ namespace TestImpact
m_testFailurePolicy,
m_targetOutputCapture,
testTargetTimeout,
globalTimeout,
TestRunCompleteCallbackHandler(testCompleteCallback));
sequenceTimeout,
AZStd::ref(testRunCompleteHandler));
const auto discardedTestRunDuration = discardedTestRunTimer.GetElapsedMs();
const auto discardedDuraton = timer.Elapsed();
if (testSequenceEndCallback.has_value())
// Carry the remaining global sequence time over to the drafted test run
if (globalTimeout.has_value())
{
(*testSequenceEndCallback)(
GenerateSequenceFailureReport(selectedTestJobs),
GenerateSequenceFailureReport(discardedTestJobs),
selectedDuraton,
discardedDuraton);
const auto elapsed = selectedTestRunDuration + discardedTestRunDuration;
sequenceTimeout = elapsed < globalTimeout.value() ? globalTimeout.value() - elapsed : AZStd::chrono::milliseconds(0);
}
UpdateAndSerializeDynamicDependencyMap(selectedTestJobs);
return { selectedResult, discardedResult };
// Run the drafted test targets and collect the test run results
const Timer draftedTestRunTimer;
const auto [draftedResult, draftedTestJobs] = m_testEngine->InstrumentedRun(
draftedTestTargets,
m_testShardingPolicy,
m_executionFailurePolicy,
m_integrationFailurePolicy,
m_testFailurePolicy,
m_targetOutputCapture,
testTargetTimeout,
sequenceTimeout,
AZStd::ref(testRunCompleteHandler));
const auto draftedTestRunDuration = draftedTestRunTimer.GetElapsedMs();
// Generate the sequence report for the client
const auto sequenceReport = Client::SafeImpactAnalysisSequenceReport(
m_suiteFilter,
selectedTests,
discardedTests,
draftedTests,
GenerateTestRunReport(selectedResult, selectedTestRunTimer.GetStartTimePointRelative(sequenceTimer), selectedTestRunDuration, selectedTestJobs),
GenerateTestRunReport(discardedResult, discardedTestRunTimer.GetStartTimePointRelative(sequenceTimer), discardedTestRunDuration, discardedTestJobs),
GenerateTestRunReport(draftedResult, draftedTestRunTimer.GetStartTimePointRelative(sequenceTimer), draftedTestRunDuration, draftedTestJobs));
// Inform the client that the sequence has ended
if (testSequenceEndCallback.has_value())
{
(*testSequenceEndCallback)(sequenceReport);
}
UpdateAndSerializeDynamicDependencyMap(ConcatenateVectors(selectedTestJobs, draftedTestJobs));
return sequenceReport;
}
TestSequenceResult Runtime::SeededTestSequence(
Client::SequenceReport Runtime::SeededTestSequence(
AZStd::optional<AZStd::chrono::milliseconds> testTargetTimeout,
AZStd::optional<AZStd::chrono::milliseconds> globalTimeout,
AZStd::optional<TestSequenceStartCallback> testSequenceStartCallback,
AZStd::optional<TestSequenceCompleteCallback> testSequenceEndCallback,
AZStd::optional<TestSequenceCompleteCallback<Client::SequenceReport>> testSequenceEndCallback,
AZStd::optional<TestRunCompleteCallback> testCompleteCallback)
{
Timer timer;
const Timer sequenceTimer;
AZStd::vector<const TestTarget*> includedTestTargets;
AZStd::vector<const TestTarget*> 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())
{
if (!m_testTargetExcludeList.contains(&testTarget))
@@ -583,31 +775,44 @@ namespace TestImpact
}
}
// Extract the client facing representation of selected test targets
Client::TestRunSelection selectedTests(ExtractTestTargetNames(includedTestTargets), ExtractTestTargetNames(excludedTestTargets));
// Inform the client that the sequence is about to start
if (testSequenceStartCallback.has_value())
{
(*testSequenceStartCallback)(Client::TestRunSelection(ExtractTestTargetNames(includedTestTargets), ExtractTestTargetNames(excludedTestTargets)));
(*testSequenceStartCallback)(m_suiteFilter, selectedTests);
}
// Run the test targets and collect the test run results
const Timer testRunTimer;
const auto [result, testJobs] = m_testEngine->InstrumentedRun(
includedTestTargets,
m_testShardingPolicy,
m_executionFailurePolicy,
Policy::IntegrityFailure::Continue,
m_integrationFailurePolicy,
m_testFailurePolicy,
m_targetOutputCapture,
testTargetTimeout,
globalTimeout,
TestRunCompleteCallbackHandler(testCompleteCallback));
TestRunCompleteCallbackHandler(includedTestTargets.size(), testCompleteCallback));
const auto testRunDuration = testRunTimer.GetElapsedMs();
// Generate the sequence report for the client
const auto sequenceReport = Client::SequenceReport(
m_suiteFilter,
selectedTests,
GenerateTestRunReport(result, testRunTimer.GetStartTimePointRelative(sequenceTimer), testRunDuration, testJobs));
// Inform the client that the sequence has ended
if (testSequenceEndCallback.has_value())
{
(*testSequenceEndCallback)(GenerateSequenceFailureReport(testJobs), timer.Elapsed());
(*testSequenceEndCallback)(sequenceReport);
}
ClearDynamicDependencyMapAndRemoveExistingFile();
UpdateAndSerializeDynamicDependencyMap(testJobs);
return result;
return sequenceReport;
}
bool Runtime::HasImpactAnalysisData() const
@@ -24,13 +24,13 @@ namespace TestImpact
return TestTargetMetaMapFactory(masterTestListData, suiteFilter);
}
AZStd::vector<TestImpact::BuildTargetDescriptor> ReadBuildTargetDescriptorFiles(const BuildTargetDescriptorConfig& buildTargetDescriptorConfig)
AZStd::vector<BuildTargetDescriptor> ReadBuildTargetDescriptorFiles(const BuildTargetDescriptorConfig& buildTargetDescriptorConfig)
{
AZStd::vector<TestImpact::BuildTargetDescriptor> buildTargetDescriptors;
AZStd::vector<BuildTargetDescriptor> buildTargetDescriptors;
for (const auto& buildTargetDescriptorFile : std::filesystem::directory_iterator(buildTargetDescriptorConfig.m_mappingDirectory.c_str()))
{
const auto buildTargetDescriptorContents = ReadFileContents<RuntimeException>(buildTargetDescriptorFile.path().string().c_str());
auto buildTargetDescriptor = TestImpact::BuildTargetDescriptorFactory(
auto buildTargetDescriptor = BuildTargetDescriptorFactory(
buildTargetDescriptorContents,
buildTargetDescriptorConfig.m_staticInclusionFilters,
buildTargetDescriptorConfig.m_inputInclusionFilters,
@@ -41,7 +41,7 @@ namespace TestImpact
return buildTargetDescriptors;
}
AZStd::unique_ptr<TestImpact::DynamicDependencyMap> ConstructDynamicDependencyMap(
AZStd::unique_ptr<DynamicDependencyMap> ConstructDynamicDependencyMap(
SuiteType suiteFilter,
const BuildTargetDescriptorConfig& buildTargetDescriptorConfig,
const TestTargetMetaConfig& testTargetMetaConfig)
@@ -50,7 +50,7 @@ namespace TestImpact
auto buildTargetDescriptors = ReadBuildTargetDescriptorFiles(buildTargetDescriptorConfig);
auto buildTargets = CompileTargetDescriptors(AZStd::move(buildTargetDescriptors), AZStd::move(testTargetmetaMap));
auto&& [productionTargets, testTargets] = buildTargets;
return AZStd::make_unique<TestImpact::DynamicDependencyMap>(AZStd::move(productionTargets), AZStd::move(testTargets));
return AZStd::make_unique<DynamicDependencyMap>(AZStd::move(productionTargets), AZStd::move(testTargets));
}
AZStd::unordered_set<const TestTarget*> ConstructTestTargetExcludeList(
@@ -68,7 +68,7 @@ namespace TestImpact
return testTargetExcludeList;
}
AZStd::vector<AZStd::string> ExtractTestTargetNames(const AZStd::vector<const TestTarget*> testTargets)
AZStd::vector<AZStd::string> ExtractTestTargetNames(const AZStd::vector<const TestTarget*>& testTargets)
{
AZStd::vector<AZStd::string> testNames;
AZStd::transform(testTargets.begin(), testTargets.end(), AZStd::back_inserter(testNames), [](const TestTarget* testTarget)
@@ -10,7 +10,7 @@
#include <TestImpactFramework/TestImpactConfiguration.h>
#include <TestImpactFramework/TestImpactClientTestSelection.h>
#include <TestImpactFramework/TestImpactClientFailureReport.h>
#include <TestImpactFramework/TestImpactClientSequenceReport.h>
#include <Artifact/Static/TestImpactTestTargetMeta.h>
#include <Artifact/Static/TestImpactBuildTargetDescriptor.h>
@@ -25,7 +25,7 @@
namespace TestImpact
{
//! Construct a dynamic dependency map from the build target descriptors and test target metas.
AZStd::unique_ptr<TestImpact::DynamicDependencyMap> ConstructDynamicDependencyMap(
AZStd::unique_ptr<DynamicDependencyMap> ConstructDynamicDependencyMap(
SuiteType suiteFilter,
const BuildTargetDescriptorConfig& buildTargetDescriptorConfig,
const TestTargetMetaConfig& testTargetMetaConfig);
@@ -36,16 +36,17 @@ namespace TestImpact
const AZStd::vector<AZStd::string>& excludedTestTargets);
//! Extracts the name information from the specified test targets.
AZStd::vector<AZStd::string> ExtractTestTargetNames(const AZStd::vector<const TestTarget*> testTargets);
AZStd::vector<AZStd::string> ExtractTestTargetNames(const AZStd::vector<const TestTarget*>& testTargets);
//! Generates a test run failure report from the specified test engine job information.
//! @tparam TestJob The test engine job type.
template<typename TestJob>
Client::TestRunFailure GenerateTestRunFailure(const TestJob& testJob)
AZStd::vector<Client::TestCaseFailure> GenerateTestCaseFailures(const TestJob& testJob)
{
AZStd::vector<Client::TestCaseFailure> testCaseFailures;
if (testJob.GetTestRun().has_value())
{
AZStd::vector<Client::TestCaseFailure> testCaseFailures;
for (const auto& testSuite : testJob.GetTestRun()->GetTestSuites())
{
AZStd::vector<Client::TestFailure> testFailures;
@@ -56,57 +57,66 @@ namespace TestImpact
testFailures.push_back(Client::TestFailure(testCase.m_name, "No error message retrieved"));
}
}
if (!testFailures.empty())
{
testCaseFailures.push_back(Client::TestCaseFailure(testSuite.m_name, AZStd::move(testFailures)));
}
}
}
return Client::TestRunFailure(Client::TestRunFailure(testJob.GetTestTarget()->GetName(), AZStd::move(testCaseFailures)));
}
else
{
return Client::TestRunFailure(testJob.GetTestTarget()->GetName(), { });
}
return testCaseFailures;
}
//! Generates a sequence failure report from the specified list of test engine jobs.
//! @tparam TestJob The test engine job type.
template<typename TestJob>
Client::SequenceFailure GenerateSequenceFailureReport(const AZStd::vector<TestJob>& testJobs)
Client::TestRunReport GenerateTestRunReport(
TestSequenceResult result,
AZStd::chrono::high_resolution_clock::time_point startTime,
AZStd::chrono::milliseconds duration,
const AZStd::vector<TestJob>& testJobs)
{
AZStd::vector<Client::ExecutionFailure> executionFailures;
AZStd::vector<Client::TestRunFailure> testRunFailures;
AZStd::vector<Client::TargetFailure> timedOutTestRuns;
AZStd::vector<Client::TargetFailure> unexecutedTestRuns;
AZStd::vector<Client::TestRun> passingTests;
AZStd::vector<Client::TestRunWithTestFailures> failingTests;
AZStd::vector<Client::TestRun> executionFailureTests;
AZStd::vector<Client::TestRun> timedOutTests;
AZStd::vector<Client::TestRun> unexecutedTests;
for (const auto& testJob : testJobs)
{
// Test job start time relative to start time
const auto relativeStartTime =
AZStd::chrono::high_resolution_clock::time_point() +
AZStd::chrono::duration_cast<AZStd::chrono::milliseconds>(testJob.GetStartTime() - startTime);
Client::TestRun clientTestRun(
testJob.GetTestTarget()->GetName(), testJob.GetCommandString(), relativeStartTime, testJob.GetDuration(),
testJob.GetTestResult());
switch (testJob.GetTestResult())
{
case Client::TestRunResult::FailedToExecute:
{
executionFailures.push_back(Client::ExecutionFailure(testJob.GetTestTarget()->GetName(), testJob.GetCommandString()));
executionFailureTests.push_back(clientTestRun);
break;
}
case Client::TestRunResult::NotRun:
{
unexecutedTestRuns.push_back(testJob.GetTestTarget()->GetName());
unexecutedTests.push_back(clientTestRun);
break;
}
case Client::TestRunResult::Timeout:
{
timedOutTestRuns.push_back(testJob.GetTestTarget()->GetName());
timedOutTests.push_back(clientTestRun);
break;
}
case Client::TestRunResult::AllTestsPass:
{
passingTests.push_back(clientTestRun);
break;
}
case Client::TestRunResult::TestFailures:
{
testRunFailures.push_back(GenerateTestRunFailure(testJob));
failingTests.emplace_back(AZStd::move(clientTestRun), GenerateTestCaseFailures(testJob));
break;
}
default:
@@ -116,11 +126,15 @@ namespace TestImpact
}
}
}
return Client::SequenceFailure(
AZStd::move(executionFailures),
AZStd::move(testRunFailures),
AZStd::move(timedOutTestRuns),
AZStd::move(unexecutedTestRuns));
return Client::TestRunReport(
result,
startTime,
duration,
AZStd::move(passingTests),
AZStd::move(failingTests),
AZStd::move(executionFailureTests),
AZStd::move(timedOutTests),
AZStd::move(unexecutedTests));
}
}
} // namespace TestImpact