forked from qt-creator/qt-creator
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:
@@ -242,19 +242,21 @@ private:
|
|||||||
It instructs the running task tree on how to proceed after the setup handler's execution
|
It instructs the running task tree on how to proceed after the setup handler's execution
|
||||||
finished.
|
finished.
|
||||||
\value Continue
|
\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
|
When a group's or task's setup handler returns void, it's assumed that
|
||||||
it returned Continue.
|
it returned Continue.
|
||||||
\value StopWithDone
|
\value StopWithDone
|
||||||
The group's or task's execution stops immediately with success.
|
The group's or task's execution stops immediately with success.
|
||||||
When returned from the group's setup handler, all child tasks are skipped,
|
When returned from the group's setup handler, all child tasks are skipped,
|
||||||
and the group's onGroupDone() handler is invoked (if provided).
|
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,
|
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.
|
its done handler isn't invoked, and the task reports success to its parent.
|
||||||
\value StopWithError
|
\value StopWithError
|
||||||
The group's or task's execution stops immediately with an error.
|
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,
|
When returned from the group's setup handler, all child tasks are skipped,
|
||||||
and the group's onGroupError() handler is invoked (if provided).
|
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,
|
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.
|
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;
|
TaskAction startAction = TaskAction::Continue;
|
||||||
if (m_constData.m_groupHandler.m_setupHandler) {
|
if (m_constData.m_groupHandler.m_setupHandler) {
|
||||||
startAction = invokeHandler(this, 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);
|
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 (startAction == TaskAction::Continue) {
|
||||||
if (m_constData.m_children.isEmpty())
|
if (m_constData.m_children.isEmpty())
|
||||||
|
|||||||
@@ -318,14 +318,53 @@ void tst_Tasking::testTree_data()
|
|||||||
groupDone(0),
|
groupDone(0),
|
||||||
groupError(0)
|
groupError(0)
|
||||||
};
|
};
|
||||||
|
|
||||||
const Log logDone {{0, Handler::GroupDone}};
|
const Log logDone {{0, Handler::GroupDone}};
|
||||||
const Log logError {{0, Handler::GroupError}};
|
const Log logError {{0, Handler::GroupError}};
|
||||||
|
|
||||||
QTest::newRow("Empty") << TestData{storage, root1, logDone, 0, OnDone::Success};
|
QTest::newRow("Empty") << TestData{storage, root1, logDone, 0, OnDone::Success};
|
||||||
QTest::newRow("EmptyContinue") << TestData{storage, root2, 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("EmptyDone") << TestData{storage, root3, logDone, 0, OnDone::Success};
|
||||||
QTest::newRow("EmptyError") << TestData{storage, root4, logError, 0, OnDone::Failure};
|
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 {
|
const Group root {
|
||||||
Storage(storage),
|
Storage(storage),
|
||||||
|
|||||||
Reference in New Issue
Block a user