TaskTree: Introduce finishAllAndError workflow policy

It's going to be used in timeout task.

Change-Id: I2abd65b461cab445ada7a0ad5e1bbe07d1b6323b
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Marcus Tillmanns <marcus.tillmanns@qt.io>
Reviewed-by: <github-actions-qt-creator@cristianadam.eu>
This commit is contained in:
Jarek Kobus
2023-05-28 22:07:17 +02:00
parent b9e5f4b5c0
commit 5e9eadfc58
3 changed files with 110 additions and 58 deletions

View File

@@ -404,12 +404,14 @@ TaskItem workflowPolicy(WorkflowPolicy policy)
const TaskItem sequential = parallelLimit(1); const TaskItem sequential = parallelLimit(1);
const TaskItem parallel = parallelLimit(0); const TaskItem parallel = parallelLimit(0);
const TaskItem stopOnError = workflowPolicy(WorkflowPolicy::StopOnError); const TaskItem stopOnError = workflowPolicy(WorkflowPolicy::StopOnError);
const TaskItem continueOnError = workflowPolicy(WorkflowPolicy::ContinueOnError); const TaskItem continueOnError = workflowPolicy(WorkflowPolicy::ContinueOnError);
const TaskItem stopOnDone = workflowPolicy(WorkflowPolicy::StopOnDone); const TaskItem stopOnDone = workflowPolicy(WorkflowPolicy::StopOnDone);
const TaskItem continueOnDone = workflowPolicy(WorkflowPolicy::ContinueOnDone); const TaskItem continueOnDone = workflowPolicy(WorkflowPolicy::ContinueOnDone);
const TaskItem stopOnFinished = workflowPolicy(WorkflowPolicy::StopOnFinished); const TaskItem stopOnFinished = workflowPolicy(WorkflowPolicy::StopOnFinished);
const TaskItem finishAllAndDone = workflowPolicy(WorkflowPolicy::FinishAllAndDone); const TaskItem finishAllAndDone = workflowPolicy(WorkflowPolicy::FinishAllAndDone);
const TaskItem finishAllAndError = workflowPolicy(WorkflowPolicy::FinishAllAndError);
static TaskAction toTaskAction(bool success) static TaskAction toTaskAction(bool success)
{ {
@@ -859,7 +861,8 @@ TaskContainer::RuntimeData::RuntimeData(const ConstData &constData)
, m_storageIdList(createStorages(constData)) , m_storageIdList(createStorages(constData))
{ {
m_successBit = m_constData.m_workflowPolicy != WorkflowPolicy::StopOnDone m_successBit = m_constData.m_workflowPolicy != WorkflowPolicy::StopOnDone
&& m_constData.m_workflowPolicy != WorkflowPolicy::ContinueOnDone; && m_constData.m_workflowPolicy != WorkflowPolicy::ContinueOnDone
&& m_constData.m_workflowPolicy != WorkflowPolicy::FinishAllAndError;
} }
TaskContainer::RuntimeData::~RuntimeData() TaskContainer::RuntimeData::~RuntimeData()
@@ -873,7 +876,8 @@ TaskContainer::RuntimeData::~RuntimeData()
bool TaskContainer::RuntimeData::updateSuccessBit(bool success) bool TaskContainer::RuntimeData::updateSuccessBit(bool success)
{ {
if (m_constData.m_workflowPolicy == WorkflowPolicy::FinishAllAndDone) if (m_constData.m_workflowPolicy == WorkflowPolicy::FinishAllAndDone
|| m_constData.m_workflowPolicy == WorkflowPolicy::FinishAllAndError)
return m_successBit; return m_successBit;
if (m_constData.m_workflowPolicy == WorkflowPolicy::StopOnFinished) { if (m_constData.m_workflowPolicy == WorkflowPolicy::StopOnFinished) {
m_successBit = success; m_successBit = success;

View File

@@ -102,6 +102,7 @@ private:
// 3. Stops on first finished child. In sequential mode it will never run other children then the first one. // 3. Stops on first finished child. In sequential mode it will never run other children then the first one.
// Useful only in parallel mode. // Useful only in parallel mode.
// 4. Always run all children, let them finish, ignore their results and report done afterwards. // 4. Always run all children, let them finish, ignore their results and report done afterwards.
// 5. Always run all children, let them finish, ignore their results and report error afterwards.
enum class WorkflowPolicy { enum class WorkflowPolicy {
StopOnError, // 1a - Reports error on first child error, otherwise done (if all children were done). StopOnError, // 1a - Reports error on first child error, otherwise done (if all children were done).
@@ -109,7 +110,8 @@ enum class WorkflowPolicy {
StopOnDone, // 2a - Reports done on first child done, otherwise error (if all children were error). StopOnDone, // 2a - Reports done on first child done, otherwise error (if all children were error).
ContinueOnDone, // 2b - The same, but children execution continues. Reports error when no children. ContinueOnDone, // 2b - The same, but children execution continues. Reports error when no children.
StopOnFinished, // 3 - Stops on first finished child and report its result. StopOnFinished, // 3 - Stops on first finished child and report its result.
FinishAllAndDone // 4 - Reports done after all children finished. FinishAllAndDone, // 4 - Reports done after all children finished.
FinishAllAndError // 5 - Reports error after all children finished.
}; };
Q_ENUM_NS(WorkflowPolicy); Q_ENUM_NS(WorkflowPolicy);
@@ -247,12 +249,14 @@ TASKING_EXPORT TaskItem workflowPolicy(WorkflowPolicy policy);
TASKING_EXPORT extern const TaskItem sequential; TASKING_EXPORT extern const TaskItem sequential;
TASKING_EXPORT extern const TaskItem parallel; TASKING_EXPORT extern const TaskItem parallel;
TASKING_EXPORT extern const TaskItem stopOnError; TASKING_EXPORT extern const TaskItem stopOnError;
TASKING_EXPORT extern const TaskItem continueOnError; TASKING_EXPORT extern const TaskItem continueOnError;
TASKING_EXPORT extern const TaskItem stopOnDone; TASKING_EXPORT extern const TaskItem stopOnDone;
TASKING_EXPORT extern const TaskItem continueOnDone; TASKING_EXPORT extern const TaskItem continueOnDone;
TASKING_EXPORT extern const TaskItem stopOnFinished; TASKING_EXPORT extern const TaskItem stopOnFinished;
TASKING_EXPORT extern const TaskItem finishAllAndDone; TASKING_EXPORT extern const TaskItem finishAllAndDone;
TASKING_EXPORT extern const TaskItem finishAllAndError;
class TASKING_EXPORT Storage : public TaskItem class TASKING_EXPORT Storage : public TaskItem
{ {

View File

@@ -637,25 +637,36 @@ void tst_Tasking::testTree_data()
}; };
}; };
const Log log = {{0, Handler::GroupDone}}; const Log doneLog = {{0, Handler::GroupDone}};
const Log errorLog = {{0, Handler::GroupError}};
const Group root1 = createRoot(WorkflowPolicy::StopOnError); const Group root1 = createRoot(WorkflowPolicy::StopOnError);
QTest::newRow("EmptyStopOnError") << TestData{storage, root1, log, 0, OnDone::Success}; QTest::newRow("EmptyStopOnError") << TestData{storage, root1, doneLog, 0,
OnDone::Success};
const Group root2 = createRoot(WorkflowPolicy::ContinueOnError); const Group root2 = createRoot(WorkflowPolicy::ContinueOnError);
QTest::newRow("EmptyContinueOnError") << TestData{storage, root2, log, 0, OnDone::Success}; QTest::newRow("EmptyContinueOnError") << TestData{storage, root2, doneLog, 0,
OnDone::Success};
const Group root3 = createRoot(WorkflowPolicy::StopOnDone); const Group root3 = createRoot(WorkflowPolicy::StopOnDone);
QTest::newRow("EmptyStopOnDone") << TestData{storage, root3, log, 0, OnDone::Success}; QTest::newRow("EmptyStopOnDone") << TestData{storage, root3, doneLog, 0,
OnDone::Success};
const Group root4 = createRoot(WorkflowPolicy::ContinueOnDone); const Group root4 = createRoot(WorkflowPolicy::ContinueOnDone);
QTest::newRow("EmptyContinueOnDone") << TestData{storage, root4, log, 0, OnDone::Success}; QTest::newRow("EmptyContinueOnDone") << TestData{storage, root4, doneLog, 0,
OnDone::Success};
const Group root5 = createRoot(WorkflowPolicy::StopOnFinished); const Group root5 = createRoot(WorkflowPolicy::StopOnFinished);
QTest::newRow("EmptyStopOnFinished") << TestData{storage, root5, log, 0, OnDone::Success}; QTest::newRow("EmptyStopOnFinished") << TestData{storage, root5, doneLog, 0,
OnDone::Success};
const Group root6 = createRoot(WorkflowPolicy::FinishAllAndDone); const Group root6 = createRoot(WorkflowPolicy::FinishAllAndDone);
QTest::newRow("EmptyOptional") << TestData{storage, root6, log, 0, OnDone::Success}; QTest::newRow("EmptyFinishAllAndDone") << TestData{storage, root6, doneLog, 0,
OnDone::Success};
const Group root7 = createRoot(WorkflowPolicy::FinishAllAndError);
QTest::newRow("EmptyFinishAllAndError") << TestData{storage, root7, errorLog, 0,
OnDone::Failure};
} }
{ {
@@ -670,29 +681,45 @@ void tst_Tasking::testTree_data()
}; };
}; };
const Log log = { const Log doneLog = {
{1, Handler::Setup}, {1, Handler::Setup},
{1, Handler::Done}, {1, Handler::Done},
{0, Handler::GroupDone} {0, Handler::GroupDone}
}; };
const Log errorLog = {
{1, Handler::Setup},
{1, Handler::Done},
{0, Handler::GroupError}
};
const Group root1 = createRoot(WorkflowPolicy::StopOnError); const Group root1 = createRoot(WorkflowPolicy::StopOnError);
QTest::newRow("DoneStopOnError") << TestData{storage, root1, log, 1, OnDone::Success}; QTest::newRow("DoneStopOnError") << TestData{storage, root1, doneLog, 1,
OnDone::Success};
const Group root2 = createRoot(WorkflowPolicy::ContinueOnError); const Group root2 = createRoot(WorkflowPolicy::ContinueOnError);
QTest::newRow("DoneContinueOnError") << TestData{storage, root2, log, 1, OnDone::Success}; QTest::newRow("DoneContinueOnError") << TestData{storage, root2, doneLog, 1,
OnDone::Success};
const Group root3 = createRoot(WorkflowPolicy::StopOnDone); const Group root3 = createRoot(WorkflowPolicy::StopOnDone);
QTest::newRow("DoneStopOnDone") << TestData{storage, root3, log, 1, OnDone::Success}; QTest::newRow("DoneStopOnDone") << TestData{storage, root3, doneLog, 1,
OnDone::Success};
const Group root4 = createRoot(WorkflowPolicy::ContinueOnDone); const Group root4 = createRoot(WorkflowPolicy::ContinueOnDone);
QTest::newRow("DoneContinueOnDone") << TestData{storage, root4, log, 1, OnDone::Success}; QTest::newRow("DoneContinueOnDone") << TestData{storage, root4, doneLog, 1,
OnDone::Success};
const Group root5 = createRoot(WorkflowPolicy::StopOnFinished); const Group root5 = createRoot(WorkflowPolicy::StopOnFinished);
QTest::newRow("DoneStopOnFinished") << TestData{storage, root5, log, 1, OnDone::Success}; QTest::newRow("DoneStopOnFinished") << TestData{storage, root5, doneLog, 1,
OnDone::Success};
const Group root6 = createRoot(WorkflowPolicy::FinishAllAndDone); const Group root6 = createRoot(WorkflowPolicy::FinishAllAndDone);
QTest::newRow("DoneOptional") << TestData{storage, root6, log, 1, OnDone::Success}; QTest::newRow("DoneFinishAllAndDone") << TestData{storage, root6, doneLog, 1,
OnDone::Success};
const Group root7 = createRoot(WorkflowPolicy::FinishAllAndError);
QTest::newRow("DoneFinishAllAndError") << TestData{storage, root7, errorLog, 1,
OnDone::Failure};
} }
{ {
@@ -707,35 +734,45 @@ void tst_Tasking::testTree_data()
}; };
}; };
const Log log = { const Log doneLog = {
{1, Handler::Setup},
{1, Handler::Error},
{0, Handler::GroupError}
};
const Log optionalLog = {
{1, Handler::Setup}, {1, Handler::Setup},
{1, Handler::Error}, {1, Handler::Error},
{0, Handler::GroupDone} {0, Handler::GroupDone}
}; };
const Log errorLog = {
{1, Handler::Setup},
{1, Handler::Error},
{0, Handler::GroupError}
};
const Group root1 = createRoot(WorkflowPolicy::StopOnError); const Group root1 = createRoot(WorkflowPolicy::StopOnError);
QTest::newRow("ErrorStopOnError") << TestData{storage, root1, log, 1, OnDone::Failure}; QTest::newRow("ErrorStopOnError") << TestData{storage, root1, errorLog, 1,
OnDone::Failure};
const Group root2 = createRoot(WorkflowPolicy::ContinueOnError); const Group root2 = createRoot(WorkflowPolicy::ContinueOnError);
QTest::newRow("ErrorContinueOnError") << TestData{storage, root2, log, 1, OnDone::Failure}; QTest::newRow("ErrorContinueOnError") << TestData{storage, root2, errorLog, 1,
OnDone::Failure};
const Group root3 = createRoot(WorkflowPolicy::StopOnDone); const Group root3 = createRoot(WorkflowPolicy::StopOnDone);
QTest::newRow("ErrorStopOnDone") << TestData{storage, root3, log, 1, OnDone::Failure}; QTest::newRow("ErrorStopOnDone") << TestData{storage, root3, errorLog, 1,
OnDone::Failure};
const Group root4 = createRoot(WorkflowPolicy::ContinueOnDone); const Group root4 = createRoot(WorkflowPolicy::ContinueOnDone);
QTest::newRow("ErrorContinueOnDone") << TestData{storage, root4, log, 1, OnDone::Failure}; QTest::newRow("ErrorContinueOnDone") << TestData{storage, root4, errorLog, 1,
OnDone::Failure};
const Group root5 = createRoot(WorkflowPolicy::StopOnFinished); const Group root5 = createRoot(WorkflowPolicy::StopOnFinished);
QTest::newRow("ErrorStopOnFinished") << TestData{storage, root5, log, 1, OnDone::Failure}; QTest::newRow("ErrorStopOnFinished") << TestData{storage, root5, errorLog, 1,
OnDone::Failure};
const Group root6 = createRoot(WorkflowPolicy::FinishAllAndDone); const Group root6 = createRoot(WorkflowPolicy::FinishAllAndDone);
QTest::newRow("ErrorOptional") << TestData{storage, root6, optionalLog, 1, OnDone::Success}; QTest::newRow("ErrorFinishAllAndDone") << TestData{storage, root6, doneLog, 1,
OnDone::Success};
const Group root7 = createRoot(WorkflowPolicy::FinishAllAndError);
QTest::newRow("ErrorFinishAllAndError") << TestData{storage, root7, errorLog, 1,
OnDone::Failure};
} }
{ {
@@ -800,8 +837,12 @@ void tst_Tasking::testTree_data()
<< TestData{storage, root5, errorErrorLog, 2, OnDone::Failure}; << TestData{storage, root5, errorErrorLog, 2, OnDone::Failure};
const Group root6 = createRoot(WorkflowPolicy::FinishAllAndDone); const Group root6 = createRoot(WorkflowPolicy::FinishAllAndDone);
QTest::newRow("StopRootWithOptional") QTest::newRow("StopRootWithFinishAllAndDone")
<< TestData{storage, root6, doneLog, 2, OnDone::Success}; << TestData{storage, root6, doneLog, 2, OnDone::Success};
const Group root7 = createRoot(WorkflowPolicy::FinishAllAndError);
QTest::newRow("StopRootWithFinishAllAndError")
<< TestData{storage, root7, errorDoneLog, 2, OnDone::Failure};
} }
{ {
@@ -884,8 +925,12 @@ void tst_Tasking::testTree_data()
<< TestData{storage, root5, doneErrorLog, 3, OnDone::Success}; << TestData{storage, root5, doneErrorLog, 3, OnDone::Success};
const Group root6 = createRoot(WorkflowPolicy::FinishAllAndDone); const Group root6 = createRoot(WorkflowPolicy::FinishAllAndDone);
QTest::newRow("StopRootAfterDoneWithOptional") QTest::newRow("StopRootAfterDoneWithFinishAllAndDone")
<< TestData{storage, root6, doneDoneLog, 3, OnDone::Success}; << TestData{storage, root6, doneDoneLog, 3, OnDone::Success};
const Group root7 = createRoot(WorkflowPolicy::FinishAllAndError);
QTest::newRow("StopRootAfterDoneWithFinishAllAndError")
<< TestData{storage, root7, errorDoneLog, 3, OnDone::Failure};
} }
{ {
@@ -948,8 +993,12 @@ void tst_Tasking::testTree_data()
<< TestData{storage, root5, errorLog, 2, OnDone::Failure}; << TestData{storage, root5, errorLog, 2, OnDone::Failure};
const Group root6 = createRoot(WorkflowPolicy::FinishAllAndDone); const Group root6 = createRoot(WorkflowPolicy::FinishAllAndDone);
QTest::newRow("StopGroupWithOptional") QTest::newRow("StopGroupWithFinishAllAndDone")
<< TestData{storage, root6, doneLog, 2, OnDone::Failure}; << TestData{storage, root6, doneLog, 2, OnDone::Failure};
const Group root7 = createRoot(WorkflowPolicy::FinishAllAndError);
QTest::newRow("StopGroupWithFinishAllAndError")
<< TestData{storage, root7, errorLog, 2, OnDone::Failure};
} }
{ {
@@ -1026,8 +1075,12 @@ void tst_Tasking::testTree_data()
<< TestData{storage, root5, shortDoneLog, 3, OnDone::Failure}; << TestData{storage, root5, shortDoneLog, 3, OnDone::Failure};
const Group root6 = createRoot(WorkflowPolicy::FinishAllAndDone); const Group root6 = createRoot(WorkflowPolicy::FinishAllAndDone);
QTest::newRow("StopGroupAfterDoneWithOptional") QTest::newRow("StopGroupAfterDoneWithFinishAllAndDone")
<< TestData{storage, root6, longDoneLog, 3, OnDone::Failure}; << TestData{storage, root6, longDoneLog, 3, OnDone::Failure};
const Group root7 = createRoot(WorkflowPolicy::FinishAllAndError);
QTest::newRow("StopGroupAfterDoneWithFinishAllAndError")
<< TestData{storage, root7, errorLog, 3, OnDone::Failure};
} }
{ {
@@ -1104,8 +1157,12 @@ void tst_Tasking::testTree_data()
<< TestData{storage, root5, shortErrorLog, 3, OnDone::Failure}; << TestData{storage, root5, shortErrorLog, 3, OnDone::Failure};
const Group root6 = createRoot(WorkflowPolicy::FinishAllAndDone); const Group root6 = createRoot(WorkflowPolicy::FinishAllAndDone);
QTest::newRow("StopGroupAfterErrorWithOptional") QTest::newRow("StopGroupAfterErrorWithFinishAllAndDone")
<< TestData{storage, root6, doneLog, 3, OnDone::Failure}; << TestData{storage, root6, doneLog, 3, OnDone::Failure};
const Group root7 = createRoot(WorkflowPolicy::FinishAllAndError);
QTest::newRow("StopGroupAfterErrorWithFinishAllAndError")
<< TestData{storage, root7, longErrorLog, 3, OnDone::Failure};
} }
{ {
@@ -1133,7 +1190,7 @@ void tst_Tasking::testTree_data()
QTest::newRow("StopOnError") << TestData{storage, root1, log1, 3, OnDone::Failure}; QTest::newRow("StopOnError") << TestData{storage, root1, log1, 3, OnDone::Failure};
const Group root2 = createRoot(WorkflowPolicy::ContinueOnError); const Group root2 = createRoot(WorkflowPolicy::ContinueOnError);
const Log log2 { const Log errorLog {
{1, Handler::Setup}, {1, Handler::Setup},
{1, Handler::Done}, {1, Handler::Done},
{2, Handler::Setup}, {2, Handler::Setup},
@@ -1142,7 +1199,7 @@ void tst_Tasking::testTree_data()
{3, Handler::Done}, {3, Handler::Done},
{0, Handler::GroupError} {0, Handler::GroupError}
}; };
QTest::newRow("ContinueOnError") << TestData{storage, root2, log2, 3, OnDone::Failure}; QTest::newRow("ContinueOnError") << TestData{storage, root2, errorLog, 3, OnDone::Failure};
const Group root3 = createRoot(WorkflowPolicy::StopOnDone); const Group root3 = createRoot(WorkflowPolicy::StopOnDone);
const Log log3 { const Log log3 {
@@ -1153,7 +1210,7 @@ void tst_Tasking::testTree_data()
QTest::newRow("StopOnDone") << TestData{storage, root3, log3, 3, OnDone::Success}; QTest::newRow("StopOnDone") << TestData{storage, root3, log3, 3, OnDone::Success};
const Group root4 = createRoot(WorkflowPolicy::ContinueOnDone); const Group root4 = createRoot(WorkflowPolicy::ContinueOnDone);
const Log log4 { const Log doneLog {
{1, Handler::Setup}, {1, Handler::Setup},
{1, Handler::Done}, {1, Handler::Done},
{2, Handler::Setup}, {2, Handler::Setup},
@@ -1162,7 +1219,7 @@ void tst_Tasking::testTree_data()
{3, Handler::Done}, {3, Handler::Done},
{0, Handler::GroupDone} {0, Handler::GroupDone}
}; };
QTest::newRow("ContinueOnDone") << TestData{storage, root4, log4, 3, OnDone::Success}; QTest::newRow("ContinueOnDone") << TestData{storage, root4, doneLog, 3, OnDone::Success};
const Group root5 = createRoot(WorkflowPolicy::StopOnFinished); const Group root5 = createRoot(WorkflowPolicy::StopOnFinished);
const Log log5 { const Log log5 {
@@ -1171,6 +1228,12 @@ void tst_Tasking::testTree_data()
{0, Handler::GroupDone} {0, Handler::GroupDone}
}; };
QTest::newRow("StopOnFinished") << TestData{storage, root5, log5, 3, OnDone::Success}; QTest::newRow("StopOnFinished") << TestData{storage, root5, log5, 3, OnDone::Success};
const Group root6 = createRoot(WorkflowPolicy::FinishAllAndDone);
QTest::newRow("FinishAllAndDone") << TestData{storage, root6, doneLog, 3, OnDone::Success};
const Group root7 = createRoot(WorkflowPolicy::FinishAllAndError);
QTest::newRow("FinishAllAndError") << TestData{storage, root7, errorLog, 3, OnDone::Failure};
} }
{ {
@@ -1213,25 +1276,6 @@ void tst_Tasking::testTree_data()
QTest::newRow("StopOnFinished4") << TestData{storage, root4, failure, 2, OnDone::Failure}; QTest::newRow("StopOnFinished4") << TestData{storage, root4, failure, 2, OnDone::Failure};
} }
{
const Group root {
Storage(storage),
finishAllAndDone,
createFailingTask(1),
createFailingTask(2),
groupDone(0),
groupError(0)
};
const Log log {
{1, Handler::Setup},
{1, Handler::Error},
{2, Handler::Setup},
{2, Handler::Error},
{0, Handler::GroupDone}
};
QTest::newRow("Optional") << TestData{storage, root, log, 2, OnDone::Success};
}
{ {
const auto createRoot = [storage, createSuccessTask, groupDone, groupError]( const auto createRoot = [storage, createSuccessTask, groupDone, groupError](
TaskAction taskAction) { TaskAction taskAction) {