/* * 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 #include #include #include #include #include #include namespace TestImpact { namespace { namespace SequenceReportFields { // Keys for pertinent Json node and attribute names constexpr const char* Keys[] = { "name", "command_args", "start_time", "end_time", "duration", "result", "num_passing_tests", "num_failing_tests", "num_disabled_tests", "tests", "num_passing_test_runs", "num_failing_test_runs", "num_execution_failure_test_runs", "num_timed_out_test_runs", "num_unexecuted_test_runs", "passing_test_runs", "failing_test_runs", "execution_failure_test_runs", "timed_out_test_runs", "unexecuted_test_runs", "total_num_passing_tests", "total_num_failing_tests", "total_num_disabled_tests", "total_num_test_runs", "num_included_test_runs", "num_excluded_test_runs", "included_test_runs", "excluded_test_runs", "execution_failure", "coverage_failure", "test_failure", "integrity_failure", "test_sharding", "target_output_capture", "test_prioritization", "dynamic_dependency_map", "type", "test_target_timeout", "global_timeout", "max_concurrency", "policy", "suite", "selected_test_runs", "selected_test_run_report", "total_num_passing_test_runs", "total_num_failing_test_runs", "total_num_execution_failure_test_runs", "total_num_timed_out_test_runs", "total_num_unexecuted_test_runs", "drafted_test_runs", "drafted_test_run_report", "discarded_test_runs", "discarded_test_run_report" }; enum { Name, CommandArgs, StartTime, EndTime, Duration, Result, NumPassingTests, NumFailingTests, NumDisabledTests, Tests, NumPassingTestRuns, NumFailingTestRuns, NumExecutionFailureTestRuns, NumTimedOutTestRuns, NumUnexecutedTestRuns, PassingTestRuns, FailingTestRuns, ExecutionFailureTestRuns, TimedOutTestRuns, UnexecutedTestRuns, TotalNumPassingTests, TotalNumFailingTests, TotalNumDisabledTests, TotalNumTestRuns, NumIncludedTestRuns, NumExcludedTestRuns, IncludedTestRuns, ExcludedTestRuns, ExecutionFailure, CoverageFailure, TestFailure, IntegrityFailure, TestSharding, TargetOutputCapture, TestPrioritization, DynamicDependencyMap, Type, TestTargetTimeout, GlobalTimeout, MaxConcurrency, Policy, Suite, SelectedTestRuns, SelectedTestRunReport, TotalNumPassingTestRuns, TotalNumFailingTestRuns, TotalNumExecutionFailureTestRuns, TotalNumTimedOutTestRuns, TotalNumUnexecutedTestRuns, DraftedTestRuns, DraftedTestRunReport, DiscardedTestRuns, DiscardedTestRunReport }; } // namespace SequenceReportFields AZ::u64 TimePointInMsAsInt64(AZStd::chrono::high_resolution_clock::time_point timePoint) { return AZStd::chrono::duration_cast(timePoint.time_since_epoch()).count(); } void SerializeTestRunMembers(const Client::TestRunBase& testRun, rapidjson::PrettyWriter& writer) { // Name writer.Key(SequenceReportFields::Keys[SequenceReportFields::Name]); writer.String(testRun.GetTargetName().c_str()); // Command string writer.Key(SequenceReportFields::Keys[SequenceReportFields::CommandArgs]); writer.String(testRun.GetCommandString().c_str()); // Start time writer.Key(SequenceReportFields::Keys[SequenceReportFields::StartTime]); writer.Int64(TimePointInMsAsInt64(testRun.GetStartTime())); // End time writer.Key(SequenceReportFields::Keys[SequenceReportFields::EndTime]); writer.Int64(TimePointInMsAsInt64(testRun.GetEndTime())); // Duration writer.Key(SequenceReportFields::Keys[SequenceReportFields::Duration]); writer.Uint64(testRun.GetDuration().count()); // Result writer.Key(SequenceReportFields::Keys[SequenceReportFields::Result]); writer.String(TestRunResultAsString(testRun.GetResult()).c_str()); } void SerializeTestRun(const Client::TestRunBase& testRun, rapidjson::PrettyWriter& writer) { writer.StartObject(); { SerializeTestRunMembers(testRun, writer); } writer.EndObject(); } void SerializeCompletedTestRun(const Client::CompletedTestRun& testRun, rapidjson::PrettyWriter& writer) { writer.StartObject(); { SerializeTestRunMembers(testRun, writer); // Number of passing test cases writer.Key(SequenceReportFields::Keys[SequenceReportFields::NumPassingTests]); writer.Uint64(testRun.GetTotalNumPassingTests()); // Number of failing test cases writer.Key(SequenceReportFields::Keys[SequenceReportFields::NumFailingTests]); writer.Uint64(testRun.GetTotalNumFailingTests()); // Number of disabled test cases writer.Key(SequenceReportFields::Keys[SequenceReportFields::NumDisabledTests]); writer.Uint64(testRun.GetTotalNumDisabledTests()); // Tests writer.Key(SequenceReportFields::Keys[SequenceReportFields::Tests]); writer.StartArray(); for (const auto& test : testRun.GetTests()) { // Test writer.StartObject(); // Name writer.Key(SequenceReportFields::Keys[SequenceReportFields::Name]); writer.String(test.GetName().c_str()); // Result writer.Key(SequenceReportFields::Keys[SequenceReportFields::Result]); writer.String(ClientTestResultAsString(test.GetResult()).c_str()); writer.EndObject(); // Test } writer.EndArray(); // Tests } writer.EndObject(); } void SerializeTestRunReport( const Client::TestRunReport& testRunReport, rapidjson::PrettyWriter& writer) { writer.StartObject(); { // Result writer.Key(SequenceReportFields::Keys[SequenceReportFields::Result]); writer.String(TestSequenceResultAsString(testRunReport.GetResult()).c_str()); // Start time writer.Key(SequenceReportFields::Keys[SequenceReportFields::StartTime]); writer.Int64(TimePointInMsAsInt64(testRunReport.GetStartTime())); // End time writer.Key(SequenceReportFields::Keys[SequenceReportFields::EndTime]); writer.Int64(TimePointInMsAsInt64(testRunReport.GetEndTime())); // Duration writer.Key(SequenceReportFields::Keys[SequenceReportFields::Duration]); writer.Uint64(testRunReport.GetDuration().count()); // Number of passing test runs writer.Key(SequenceReportFields::Keys[SequenceReportFields::NumPassingTestRuns]); writer.Uint64(testRunReport.GetNumPassingTestRuns()); // Number of failing test runs writer.Key(SequenceReportFields::Keys[SequenceReportFields::NumFailingTestRuns]); writer.Uint64(testRunReport.GetNumFailingTestRuns()); // Number of test runs that failed to execute writer.Key(SequenceReportFields::Keys[SequenceReportFields::NumExecutionFailureTestRuns]); writer.Uint64(testRunReport.GetNumExecutionFailureTestRuns()); // Number of timed out test runs writer.Key(SequenceReportFields::Keys[SequenceReportFields::NumTimedOutTestRuns]); writer.Uint64(testRunReport.GetNumTimedOutTestRuns()); // Number of unexecuted test runs writer.Key(SequenceReportFields::Keys[SequenceReportFields::NumUnexecutedTestRuns]); writer.Uint64(testRunReport.GetNumUnexecutedTestRuns()); // Passing test runs writer.Key(SequenceReportFields::Keys[SequenceReportFields::PassingTestRuns]); writer.StartArray(); for (const auto& testRun : testRunReport.GetPassingTestRuns()) { SerializeCompletedTestRun(testRun, writer); } writer.EndArray(); // Passing test runs // Failing test runs writer.Key(SequenceReportFields::Keys[SequenceReportFields::FailingTestRuns]); writer.StartArray(); for (const auto& testRun : testRunReport.GetFailingTestRuns()) { SerializeCompletedTestRun(testRun, writer); } writer.EndArray(); // Failing test runs // Execution failures writer.Key(SequenceReportFields::Keys[SequenceReportFields::ExecutionFailureTestRuns]); writer.StartArray(); for (const auto& testRun : testRunReport.GetExecutionFailureTestRuns()) { SerializeTestRun(testRun, writer); } writer.EndArray(); // Execution failures // Timed out test runs writer.Key(SequenceReportFields::Keys[SequenceReportFields::TimedOutTestRuns]); writer.StartArray(); for (const auto& testRun : testRunReport.GetTimedOutTestRuns()) { SerializeTestRun(testRun, writer); } writer.EndArray(); // Timed out test runs // Unexecuted test runs writer.Key(SequenceReportFields::Keys[SequenceReportFields::UnexecutedTestRuns]); writer.StartArray(); for (const auto& testRun : testRunReport.GetUnexecutedTestRuns()) { SerializeTestRun(testRun, writer); } writer.EndArray(); // Unexecuted test runs // Number of passing tests writer.Key(SequenceReportFields::Keys[SequenceReportFields::TotalNumPassingTests]); writer.Uint64(testRunReport.GetTotalNumPassingTests()); // Number of failing tests writer.Key(SequenceReportFields::Keys[SequenceReportFields::TotalNumFailingTests]); writer.Uint64(testRunReport.GetTotalNumFailingTests()); // Number of disabled tests writer.Key(SequenceReportFields::Keys[SequenceReportFields::TotalNumDisabledTests]); writer.Uint64(testRunReport.GetTotalNumDisabledTests()); } writer.EndObject(); } void SerializeTestSelection( const Client::TestRunSelection& testSelection, rapidjson::PrettyWriter& writer) { writer.StartObject(); { // Total number of test runs writer.Key(SequenceReportFields::Keys[SequenceReportFields::TotalNumTestRuns]); writer.Uint64(testSelection.GetTotalNumTests()); // Number of included test runs writer.Key(SequenceReportFields::Keys[SequenceReportFields::NumIncludedTestRuns]); writer.Uint64(testSelection.GetNumIncludedTestRuns()); // Number of excluded test runs writer.Key(SequenceReportFields::Keys[SequenceReportFields::NumExcludedTestRuns]); writer.Uint64(testSelection.GetNumExcludedTestRuns()); // Included test runs writer.Key(SequenceReportFields::Keys[SequenceReportFields::IncludedTestRuns]); writer.StartArray(); for (const auto& testRun : testSelection.GetIncludededTestRuns()) { writer.String(testRun.c_str()); } writer.EndArray(); // Included test runs // Excluded test runs writer.Key(SequenceReportFields::Keys[SequenceReportFields::ExcludedTestRuns]); writer.StartArray(); for (const auto& testRun : testSelection.GetExcludedTestRuns()) { writer.String(testRun.c_str()); } writer.EndArray(); // Excluded test runs } writer.EndObject(); } void SerializePolicyStateBaseMembers(const PolicyStateBase& policyState, rapidjson::PrettyWriter& writer) { // Execution failure writer.Key(SequenceReportFields::Keys[SequenceReportFields::ExecutionFailure]); writer.String(ExecutionFailurePolicyAsString(policyState.m_executionFailurePolicy).c_str()); // Failed test coverage writer.Key(SequenceReportFields::Keys[SequenceReportFields::CoverageFailure]); writer.String(FailedTestCoveragePolicyAsString(policyState.m_failedTestCoveragePolicy).c_str()); // Test failure writer.Key(SequenceReportFields::Keys[SequenceReportFields::TestFailure]); writer.String(TestFailurePolicyAsString(policyState.m_testFailurePolicy).c_str()); // Integrity failure writer.Key(SequenceReportFields::Keys[SequenceReportFields::IntegrityFailure]); writer.String(IntegrityFailurePolicyAsString(policyState.m_integrityFailurePolicy).c_str()); // Test sharding writer.Key(SequenceReportFields::Keys[SequenceReportFields::TestSharding]); writer.String(TestShardingPolicyAsString(policyState.m_testShardingPolicy).c_str()); // Target output capture writer.Key(SequenceReportFields::Keys[SequenceReportFields::TargetOutputCapture]); writer.String(TargetOutputCapturePolicyAsString(policyState.m_targetOutputCapture).c_str()); } void SerializePolicyStateMembers( const SequencePolicyState& policyState, rapidjson::PrettyWriter& writer) { SerializePolicyStateBaseMembers(policyState.m_basePolicies, writer); } void SerializePolicyStateMembers( const SafeImpactAnalysisSequencePolicyState& policyState, rapidjson::PrettyWriter& writer) { SerializePolicyStateBaseMembers(policyState.m_basePolicies, writer); // Test prioritization writer.Key(SequenceReportFields::Keys[SequenceReportFields::TestPrioritization]); writer.String(TestPrioritizationPolicyAsString(policyState.m_testPrioritizationPolicy).c_str()); } void SerializePolicyStateMembers( const ImpactAnalysisSequencePolicyState& policyState, rapidjson::PrettyWriter& writer) { SerializePolicyStateBaseMembers(policyState.m_basePolicies, writer); // Test prioritization writer.Key(SequenceReportFields::Keys[SequenceReportFields::TestPrioritization]); writer.String(TestPrioritizationPolicyAsString(policyState.m_testPrioritizationPolicy).c_str()); // Dynamic dependency map writer.Key(SequenceReportFields::Keys[SequenceReportFields::DynamicDependencyMap]); writer.String(DynamicDependencyMapPolicyAsString(policyState.m_dynamicDependencyMap).c_str()); } template void SerializeSequenceReportBaseMembers( const SequenceReportBaseType& sequenceReport, rapidjson::PrettyWriter& writer) { // Type writer.Key(SequenceReportFields::Keys[SequenceReportFields::Type]); writer.String(SequenceReportTypeAsString(sequenceReport.ReportType).c_str()); // Test target timeout writer.Key(SequenceReportFields::Keys[SequenceReportFields::TestTargetTimeout]); writer.Uint64(sequenceReport.GetTestTargetTimeout().value_or(AZStd::chrono::milliseconds{0}).count()); // Global timeout writer.Key(SequenceReportFields::Keys[SequenceReportFields::GlobalTimeout]); writer.Uint64(sequenceReport.GetGlobalTimeout().value_or(AZStd::chrono::milliseconds{ 0 }).count()); // Maximum concurrency writer.Key(SequenceReportFields::Keys[SequenceReportFields::MaxConcurrency]); writer.Uint64(sequenceReport.GetMaxConcurrency()); // Policies writer.Key(SequenceReportFields::Keys[SequenceReportFields::Policy]); writer.StartObject(); { SerializePolicyStateMembers(sequenceReport.GetPolicyState(), writer); } writer.EndObject(); // Policies // Suite writer.Key(SequenceReportFields::Keys[SequenceReportFields::Suite]); writer.String(SuiteTypeAsString(sequenceReport.GetSuite()).c_str()); // Selected test runs writer.Key(SequenceReportFields::Keys[SequenceReportFields::SelectedTestRuns]); SerializeTestSelection(sequenceReport.GetSelectedTestRuns(), writer); // Selected test run report writer.Key(SequenceReportFields::Keys[SequenceReportFields::SelectedTestRunReport]); SerializeTestRunReport(sequenceReport.GetSelectedTestRunReport(), writer); // Start time writer.Key(SequenceReportFields::Keys[SequenceReportFields::StartTime]); writer.Int64(TimePointInMsAsInt64(sequenceReport.GetStartTime())); // End time writer.Key(SequenceReportFields::Keys[SequenceReportFields::EndTime]); writer.Int64(TimePointInMsAsInt64(sequenceReport.GetEndTime())); // Duration writer.Key(SequenceReportFields::Keys[SequenceReportFields::Duration]); writer.Uint64(sequenceReport.GetDuration().count()); // Result writer.Key(SequenceReportFields::Keys[SequenceReportFields::Result]); writer.String(TestSequenceResultAsString(sequenceReport.GetResult()).c_str()); // Total number of test runs writer.Key(SequenceReportFields::Keys[SequenceReportFields::TotalNumTestRuns]); writer.Uint64(sequenceReport.GetTotalNumTestRuns()); // Total number of passing test runs writer.Key(SequenceReportFields::Keys[SequenceReportFields::TotalNumPassingTestRuns]); writer.Uint64(sequenceReport.GetTotalNumPassingTestRuns()); // Total number of failing test runs writer.Key(SequenceReportFields::Keys[SequenceReportFields::TotalNumFailingTestRuns]); writer.Uint64(sequenceReport.GetTotalNumFailingTestRuns()); // Total number of test runs that failed to execute writer.Key(SequenceReportFields::Keys[SequenceReportFields::TotalNumExecutionFailureTestRuns]); writer.Uint64(sequenceReport.GetTotalNumExecutionFailureTestRuns()); // Total number of timed out test runs writer.Key(SequenceReportFields::Keys[SequenceReportFields::TotalNumTimedOutTestRuns]); writer.Uint64(sequenceReport.GetTotalNumTimedOutTestRuns()); // Total number of unexecuted test runs writer.Key(SequenceReportFields::Keys[SequenceReportFields::TotalNumUnexecutedTestRuns]); writer.Uint64(sequenceReport.GetTotalNumUnexecutedTestRuns()); // Total number of passing tests writer.Key(SequenceReportFields::Keys[SequenceReportFields::TotalNumPassingTests]); writer.Uint64(sequenceReport.GetTotalNumPassingTests()); // Total number of failing tests writer.Key(SequenceReportFields::Keys[SequenceReportFields::TotalNumFailingTests]); writer.Uint64(sequenceReport.GetTotalNumFailingTests()); // Total number of disabled tests writer.Key(SequenceReportFields::Keys[SequenceReportFields::TotalNumDisabledTests]); writer.Uint64(sequenceReport.GetTotalNumDisabledTests()); } template void SerializeDraftingSequenceReportMembers( const DraftingSequenceReportBaseType& sequenceReport, rapidjson::PrettyWriter& writer) { SerializeSequenceReportBaseMembers(sequenceReport, writer); // Drafted test runs writer.Key(SequenceReportFields::Keys[SequenceReportFields::DraftedTestRuns]); writer.StartArray(); for (const auto& testRun : sequenceReport.GetDraftedTestRuns()) { writer.String(testRun.c_str()); } writer.EndArray(); // Drafted test runs // Drafted test run report writer.Key(SequenceReportFields::Keys[SequenceReportFields::DraftedTestRunReport]); SerializeTestRunReport(sequenceReport.GetDraftedTestRunReport(), writer); } } // namespace AZStd::string SerializeSequenceReport(const Client::RegularSequenceReport& sequenceReport) { rapidjson::StringBuffer stringBuffer; rapidjson::PrettyWriter writer(stringBuffer); writer.StartObject(); { SerializeSequenceReportBaseMembers(sequenceReport, writer); } writer.EndObject(); return stringBuffer.GetString(); } AZStd::string SerializeSequenceReport(const Client::SeedSequenceReport& sequenceReport) { rapidjson::StringBuffer stringBuffer; rapidjson::PrettyWriter writer(stringBuffer); writer.StartObject(); { SerializeSequenceReportBaseMembers(sequenceReport, writer); } writer.EndObject(); return stringBuffer.GetString(); } AZStd::string SerializeSequenceReport(const Client::ImpactAnalysisSequenceReport& sequenceReport) { rapidjson::StringBuffer stringBuffer; rapidjson::PrettyWriter writer(stringBuffer); writer.StartObject(); { SerializeDraftingSequenceReportMembers(sequenceReport, writer); // Discarded test runs writer.Key(SequenceReportFields::Keys[SequenceReportFields::DiscardedTestRuns]); writer.StartArray(); for (const auto& testRun : sequenceReport.GetDiscardedTestRuns()) { writer.String(testRun.c_str()); } writer.EndArray(); // Discarded test runs } writer.EndObject(); return stringBuffer.GetString(); } AZStd::string SerializeSequenceReport(const Client::SafeImpactAnalysisSequenceReport& sequenceReport) { rapidjson::StringBuffer stringBuffer; rapidjson::PrettyWriter writer(stringBuffer); writer.StartObject(); { SerializeDraftingSequenceReportMembers(sequenceReport, writer); // Discarded test runs writer.Key(SequenceReportFields::Keys[SequenceReportFields::DiscardedTestRuns]); SerializeTestSelection(sequenceReport.GetDiscardedTestRuns(), writer); // Discarded test run report writer.Key(SequenceReportFields::Keys[SequenceReportFields::DiscardedTestRunReport]); SerializeTestRunReport(sequenceReport.GetDiscardedTestRunReport(), writer); } writer.EndObject(); return stringBuffer.GetString(); } AZStd::chrono::high_resolution_clock::time_point TimePointFromMsInt64(AZ::s64 ms) { return AZStd::chrono::high_resolution_clock::time_point(AZStd::chrono::milliseconds(ms)); } AZStd::vector DeserializeTests(const rapidjson::Value& serialTests) { AZStd::vector tests; tests.reserve(serialTests[SequenceReportFields::Keys[SequenceReportFields::Tests]].GetArray().Size()); for (const auto& test : serialTests[SequenceReportFields::Keys[SequenceReportFields::Tests]].GetArray()) { const AZStd::string name = test[SequenceReportFields::Keys[SequenceReportFields::Name]].GetString(); const auto result = TestResultFromString(test[SequenceReportFields::Keys[SequenceReportFields::Result]].GetString()); tests.emplace_back(name, result); } return tests; } Client::TestRunBase DeserializeTestRunBase(const rapidjson::Value& serialTestRun) { return Client::TestRunBase( serialTestRun[SequenceReportFields::Keys[SequenceReportFields::Name]].GetString(), serialTestRun[SequenceReportFields::Keys[SequenceReportFields::CommandArgs]].GetString(), TimePointFromMsInt64(serialTestRun[SequenceReportFields::Keys[SequenceReportFields::StartTime]].GetInt64()), AZStd::chrono::milliseconds(serialTestRun[SequenceReportFields::Keys[SequenceReportFields::Duration]].GetInt64()), TestRunResultFromString(serialTestRun[SequenceReportFields::Keys[SequenceReportFields::Result]].GetString())); } template AZStd::vector DeserializeTestRuns(const rapidjson::Value& serialTestRuns) { AZStd::vector testRuns; testRuns.reserve(serialTestRuns.GetArray().Size()); for (const auto& testRun : serialTestRuns.GetArray()) { testRuns.emplace_back(DeserializeTestRunBase(testRun)); } return testRuns; } template AZStd::vector DeserializeCompletedTestRuns(const rapidjson::Value& serialCompletedTestRuns) { AZStd::vector testRuns; testRuns.reserve(serialCompletedTestRuns.GetArray().Size()); for (const auto& testRun : serialCompletedTestRuns.GetArray()) { testRuns.emplace_back( DeserializeTestRunBase(testRun), DeserializeTests(testRun[SequenceReportFields::Keys[SequenceReportFields::Tests]])); } return testRuns; } Client::TestRunReport DeserializeTestRunReport(const rapidjson::Value& serialTestRunReport) { return Client::TestRunReport( TestSequenceResultFromString(serialTestRunReport[SequenceReportFields::Keys[SequenceReportFields::Result]].GetString()), TimePointFromMsInt64(serialTestRunReport[SequenceReportFields::Keys[SequenceReportFields::StartTime]].GetInt64()), AZStd::chrono::milliseconds(serialTestRunReport[SequenceReportFields::Keys[SequenceReportFields::Duration]].GetInt64()), DeserializeCompletedTestRuns( serialTestRunReport[SequenceReportFields::Keys[SequenceReportFields::PassingTestRuns]]), DeserializeCompletedTestRuns( serialTestRunReport[SequenceReportFields::Keys[SequenceReportFields::FailingTestRuns]]), DeserializeTestRuns( serialTestRunReport[SequenceReportFields::Keys[SequenceReportFields::ExecutionFailureTestRuns]]), DeserializeTestRuns( serialTestRunReport[SequenceReportFields::Keys[SequenceReportFields::TimedOutTestRuns]]), DeserializeTestRuns( serialTestRunReport[SequenceReportFields::Keys[SequenceReportFields::UnexecutedTestRuns]])); } Client::TestRunSelection DeserializeTestSelection(const rapidjson::Value& serialTestRunSelection) { const auto extractTestTargetNames = [](const rapidjson::Value& serialTestTargets) { AZStd::vector testTargets; testTargets.reserve(serialTestTargets.GetArray().Size()); for (const auto& testTarget : serialTestTargets.GetArray()) { testTargets.emplace_back(testTarget.GetString()); } return testTargets; }; return Client::TestRunSelection( extractTestTargetNames(serialTestRunSelection[SequenceReportFields::Keys[SequenceReportFields::IncludedTestRuns]]), extractTestTargetNames(serialTestRunSelection[SequenceReportFields::Keys[SequenceReportFields::ExcludedTestRuns]])); } PolicyStateBase DeserializePolicyStateBaseMembers(const rapidjson::Value& serialPolicyState) { return { ExecutionFailurePolicyFromString(serialPolicyState[SequenceReportFields::Keys[SequenceReportFields::ExecutionFailure]].GetString()), FailedTestCoveragePolicyFromString(serialPolicyState[SequenceReportFields::Keys[SequenceReportFields::CoverageFailure]].GetString()), TestFailurePolicyFromString(serialPolicyState[SequenceReportFields::Keys[SequenceReportFields::TestFailure]].GetString()), IntegrityFailurePolicyFromString(serialPolicyState[SequenceReportFields::Keys[SequenceReportFields::IntegrityFailure]].GetString()), TestShardingPolicyFromString(serialPolicyState[SequenceReportFields::Keys[SequenceReportFields::TestSharding]].GetString()), TargetOutputCapturePolicyFromString(serialPolicyState[SequenceReportFields::Keys[SequenceReportFields::TargetOutputCapture]].GetString()) }; } SequencePolicyState DeserializePolicyStateMembers(const rapidjson::Value& serialPolicyState) { return { DeserializePolicyStateBaseMembers(serialPolicyState) }; } SafeImpactAnalysisSequencePolicyState DeserializeSafeImpactAnalysisPolicyStateMembers(const rapidjson::Value& serialPolicyState) { return { DeserializePolicyStateBaseMembers(serialPolicyState), TestPrioritizationPolicyFromString(serialPolicyState[SequenceReportFields::Keys[SequenceReportFields::TestPrioritization]].GetString()) }; } ImpactAnalysisSequencePolicyState DeserializeImpactAnalysisSequencePolicyStateMembers(const rapidjson::Value& serialPolicyState) { return { DeserializePolicyStateBaseMembers(serialPolicyState), TestPrioritizationPolicyFromString(serialPolicyState[SequenceReportFields::Keys[SequenceReportFields::TestPrioritization]].GetString()), DynamicDependencyMapPolicyFromString( serialPolicyState[SequenceReportFields::Keys[SequenceReportFields::DynamicDependencyMap]].GetString()) }; } template PolicyStateType DeserializePolicyStateType(const rapidjson::Value& serialPolicyStateType) { if constexpr (AZStd::is_same_v) { return DeserializePolicyStateMembers(serialPolicyStateType); } else if constexpr (AZStd::is_same_v) { return DeserializeSafeImpactAnalysisPolicyStateMembers(serialPolicyStateType); } else if constexpr (AZStd::is_same_v) { return DeserializeImpactAnalysisSequencePolicyStateMembers(serialPolicyStateType); } else { static_assert(false, "Template paramater must be a valid policy state type"); } } template SequenceReportBaseType DeserialiseSequenceReportBase(const rapidjson::Value& serialSequenceReportBase) { const auto type = SequenceReportTypeFromString(serialSequenceReportBase[SequenceReportFields::Keys[SequenceReportFields::Type]].GetString()); AZ_TestImpact_Eval( type == SequenceReportBaseType::ReportType, SequenceReportException, AZStd::string::format( "The JSON sequence report type '%s' does not match the constructed report type", serialSequenceReportBase[SequenceReportFields::Keys[SequenceReportFields::Type]].GetString())); const auto testTargetTimeout = serialSequenceReportBase[SequenceReportFields::Keys[SequenceReportFields::TestTargetTimeout]].GetUint64(); const auto globalTimeout = serialSequenceReportBase[SequenceReportFields::Keys[SequenceReportFields::GlobalTimeout]].GetUint64(); return SequenceReportBaseType( serialSequenceReportBase[SequenceReportFields::Keys[SequenceReportFields::MaxConcurrency]].GetUint64(), testTargetTimeout ? AZStd::optional{ testTargetTimeout } : AZStd::nullopt, globalTimeout ? AZStd::optional{ globalTimeout } : AZStd::nullopt, DeserializePolicyStateType(serialSequenceReportBase), SuiteTypeFromString(serialSequenceReportBase[SequenceReportFields::Keys[SequenceReportFields::Suite]].GetString()), DeserializeTestSelection(serialSequenceReportBase[SequenceReportFields::Keys[SequenceReportFields::SelectedTestRuns]]), DeserializeTestRunReport(serialSequenceReportBase[SequenceReportFields::Keys[SequenceReportFields::SelectedTestRunReport]])); } template Client::DraftingSequenceReportBase DeserializeDraftingSequenceReportBase(const rapidjson::Value& serialDraftingSequenceReportBase) { AZStd::vector draftingTestRuns; draftingTestRuns.reserve( serialDraftingSequenceReportBase[SequenceReportFields::Keys[SequenceReportFields::DraftedTestRuns]].GetArray().Size()); for (const auto& testRun : serialDraftingSequenceReportBase[SequenceReportFields::Keys[SequenceReportFields::DraftedTestRuns]].GetArray()) { draftingTestRuns.emplace_back(testRun.GetString()); } using SequenceBase = Client::SequenceReportBase; using DraftingSequenceBase = Client::DraftingSequenceReportBase; return DraftingSequenceBase( DeserialiseSequenceReportBase(serialDraftingSequenceReportBase), AZStd::move(draftingTestRuns), DeserializeTestRunReport(serialDraftingSequenceReportBase[SequenceReportFields::Keys[SequenceReportFields::DraftedTestRunReport]])); } rapidjson::Document OpenSequenceReportJson(const AZStd::string& sequenceReportJson) { rapidjson::Document doc; if (doc.Parse<0>(sequenceReportJson.c_str()).HasParseError()) { throw SequenceReportException("Could not parse sequence report data"); } return doc; } Client::RegularSequenceReport DeserializeRegularSequenceReport(const AZStd::string& sequenceReportJson) { const auto doc = OpenSequenceReportJson(sequenceReportJson); return DeserialiseSequenceReportBase(doc); } Client::SeedSequenceReport DeserializeSeedSequenceReport(const AZStd::string& sequenceReportJson) { const auto doc = OpenSequenceReportJson(sequenceReportJson); return DeserialiseSequenceReportBase(doc); } Client::ImpactAnalysisSequenceReport DeserializeImpactAnalysisSequenceReport(const AZStd::string& sequenceReportJson) { const auto doc = OpenSequenceReportJson(sequenceReportJson); AZStd::vector discardedTestRuns; discardedTestRuns.reserve(doc[SequenceReportFields::Keys[SequenceReportFields::DiscardedTestRuns]].GetArray().Size()); for (const auto& testRun : doc[SequenceReportFields::Keys[SequenceReportFields::DiscardedTestRuns]].GetArray()) { discardedTestRuns.emplace_back(testRun.GetString()); } return Client::ImpactAnalysisSequenceReport( DeserializeDraftingSequenceReportBase(doc), AZStd::move(discardedTestRuns)); } Client::SafeImpactAnalysisSequenceReport DeserializeSafeImpactAnalysisSequenceReport(const AZStd::string& sequenceReportJson) { const auto doc = OpenSequenceReportJson(sequenceReportJson); return Client::SafeImpactAnalysisSequenceReport( DeserializeDraftingSequenceReportBase(doc), DeserializeTestSelection(doc[SequenceReportFields::Keys[SequenceReportFields::DiscardedTestRuns]]), DeserializeTestRunReport(doc[SequenceReportFields::Keys[SequenceReportFields::DiscardedTestRunReport]])); } } // namespace TestImpact