TaskTree: Fix calling the right group end handler

Make non-Continue TaskAction returned by group's start
handler take precedence over group's workflow policy.

Call the group's done handler when group's setup returns
StopWithDone and the workflow policy is FinishAddAndError.

Call the group's error handler when group's setup returns
StopWithError and the workflow policy is FinishAddAndDone.

Add tests for these cases.

Change-Id: I98210a5d522daabc0986200e65b25986a8c0c440
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: hjk <hjk@qt.io>
Reviewed-by: <github-actions-qt-creator@cristianadam.eu>
This commit is contained in:
Jarek Kobus
2023-06-16 16:37:50 +02:00
parent a41577f8bd
commit 52badc2fa6
2 changed files with 46 additions and 2 deletions

View File

@@ -242,19 +242,21 @@ private:
It instructs the running task tree on how to proceed after the setup handler's execution
finished.
\value Continue
Default. The group's or task's execution continues nomally.
Default. The group's or task's execution continues normally.
When a group's or task's setup handler returns void, it's assumed that
it returned Continue.
\value StopWithDone
The group's or task's execution stops immediately with success.
When returned from the group's setup handler, all child tasks are skipped,
and the group's onGroupDone() handler is invoked (if provided).
The group reports success to its parent. The group's workflow policy is ignored.
When returned from the task's setup handler, the task isn't started,
its done handler isn't invoked, and the task reports success to its parent.
\value StopWithError
The group's or task's execution stops immediately with an error.
When returned from the group's setup handler, all child tasks are skipped,
and the group's onGroupError() handler is invoked (if provided).
The group reports an error to its parent. The group's workflow policy is ignored.
When returned from the task's setup handler, the task isn't started,
its error handler isn't invoked, and the task reports an error to its parent.
*/
@@ -953,8 +955,11 @@ TaskAction TaskContainer::start()
TaskAction startAction = TaskAction::Continue;
if (m_constData.m_groupHandler.m_setupHandler) {
startAction = invokeHandler(this, m_constData.m_groupHandler.m_setupHandler);
if (startAction != TaskAction::Continue)
if (startAction != TaskAction::Continue) {
m_constData.m_taskTreePrivate->advanceProgress(m_constData.m_taskCount);
// Non-Continue TaskAction takes precedence over the workflow policy.
m_runtimeData->m_successBit = startAction == TaskAction::StopWithDone;
}
}
if (startAction == TaskAction::Continue) {
if (m_constData.m_children.isEmpty())

View File

@@ -318,14 +318,53 @@ void tst_Tasking::testTree_data()
groupDone(0),
groupError(0)
};
const Log logDone {{0, Handler::GroupDone}};
const Log logError {{0, Handler::GroupError}};
QTest::newRow("Empty") << TestData{storage, root1, logDone, 0, OnDone::Success};
QTest::newRow("EmptyContinue") << TestData{storage, root2, logDone, 0, OnDone::Success};
QTest::newRow("EmptyDone") << TestData{storage, root3, logDone, 0, OnDone::Success};
QTest::newRow("EmptyError") << TestData{storage, root4, logError, 0, OnDone::Failure};
}
{
const auto setupGroup = [=](TaskAction taskAction, WorkflowPolicy policy) {
return Group {
Storage(storage),
workflowPolicy(policy),
onGroupSetup([taskAction] { return taskAction; }),
groupDone(0),
groupError(0)
};
};
const auto doneData = [storage, setupGroup](WorkflowPolicy policy) {
return TestData{storage, setupGroup(TaskAction::StopWithDone, policy),
Log{{0, Handler::GroupDone}}, 0, OnDone::Success};
};
const auto errorData = [storage, setupGroup](WorkflowPolicy policy) {
return TestData{storage, setupGroup(TaskAction::StopWithError, policy),
Log{{0, Handler::GroupError}}, 0, OnDone::Failure};
};
QTest::newRow("DoneAndStopOnError") << doneData(WorkflowPolicy::StopOnError);
QTest::newRow("DoneAndContinueOnError") << doneData(WorkflowPolicy::ContinueOnError);
QTest::newRow("DoneAndStopOnDone") << doneData(WorkflowPolicy::StopOnDone);
QTest::newRow("DoneAndContinueOnDone") << doneData(WorkflowPolicy::ContinueOnDone);
QTest::newRow("DoneAndStopOnFinished") << doneData(WorkflowPolicy::StopOnFinished);
QTest::newRow("DoneAndFinishAllAndDone") << doneData(WorkflowPolicy::FinishAllAndDone);
QTest::newRow("DoneAndFinishAllAndError") << doneData(WorkflowPolicy::FinishAllAndError);
QTest::newRow("ErrorAndStopOnError") << errorData(WorkflowPolicy::StopOnError);
QTest::newRow("ErrorAndContinueOnError") << errorData(WorkflowPolicy::ContinueOnError);
QTest::newRow("ErrorAndStopOnDone") << errorData(WorkflowPolicy::StopOnDone);
QTest::newRow("ErrorAndContinueOnDone") << errorData(WorkflowPolicy::ContinueOnDone);
QTest::newRow("ErrorAndStopOnFinished") << errorData(WorkflowPolicy::StopOnFinished);
QTest::newRow("ErrorAndFinishAllAndDone") << errorData(WorkflowPolicy::FinishAllAndDone);
QTest::newRow("ErrorAndFinishAllAndError") << errorData(WorkflowPolicy::FinishAllAndError);
}
{
const Group root {
Storage(storage),