TaskTree: Add taskCount() getter

Will be helpful when implementing progressMaximum.

Change-Id: I9204b53425054a01c96f3b926b595f7888f81e3a
Reviewed-by: <github-actions-qt-creator@cristianadam.eu>
Reviewed-by: hjk <hjk@qt.io>
This commit is contained in:
Jarek Kobus
2022-11-10 14:31:25 +01:00
parent 234b3d1e6f
commit e38db06203
3 changed files with 64 additions and 30 deletions

View File

@@ -87,6 +87,7 @@ public:
void selectChildren(); void selectChildren();
void stop(); void stop();
bool isRunning() const; bool isRunning() const;
int taskCount() const;
void childDone(bool success); void childDone(bool success);
void invokeEndHandler(bool success); void invokeEndHandler(bool success);
void resetSuccessBit(); void resetSuccessBit();
@@ -97,6 +98,7 @@ public:
const TaskItem::ExecuteMode m_executeMode = TaskItem::ExecuteMode::Parallel; const TaskItem::ExecuteMode m_executeMode = TaskItem::ExecuteMode::Parallel;
TaskItem::WorkflowPolicy m_workflowPolicy = TaskItem::WorkflowPolicy::StopOnError; TaskItem::WorkflowPolicy m_workflowPolicy = TaskItem::WorkflowPolicy::StopOnError;
const TaskItem::GroupHandler m_groupHandler; const TaskItem::GroupHandler m_groupHandler;
int m_taskCount = 0;
GroupConfig m_groupConfig; GroupConfig m_groupConfig;
QList<TaskNode *> m_children; QList<TaskNode *> m_children;
QList<TaskNode *> m_selectedChildren; QList<TaskNode *> m_selectedChildren;
@@ -116,7 +118,9 @@ public:
bool start(); bool start();
void stop(); void stop();
bool isRunning(); bool isRunning() const;
bool isTask() const;
int taskCount() const;
private: private:
const TaskItem::TaskHandler m_taskHandler; const TaskItem::TaskHandler m_taskHandler;
@@ -154,8 +158,11 @@ TaskContainer::TaskContainer(TaskTreePrivate *taskTreePrivate, TaskContainer *pa
, m_groupHandler(task.groupHandler()) , m_groupHandler(task.groupHandler())
{ {
const QList<TaskItem> &children = task.children(); const QList<TaskItem> &children = task.children();
for (const TaskItem &child : children) for (const TaskItem &child : children) {
m_children.append(new TaskNode(m_taskTreePrivate, this, child)); TaskNode *node = new TaskNode(m_taskTreePrivate, this, child);
m_children.append(node);
m_taskCount += node->taskCount();
}
} }
TaskContainer::~TaskContainer() TaskContainer::~TaskContainer()
@@ -231,6 +238,11 @@ bool TaskContainer::isRunning() const
return m_currentIndex >= 0; return m_currentIndex >= 0;
} }
int TaskContainer::taskCount() const
{
return m_taskCount;
}
void TaskContainer::childDone(bool success) void TaskContainer::childDone(bool success)
{ {
if ((m_workflowPolicy == TaskItem::WorkflowPolicy::StopOnDone && success) if ((m_workflowPolicy == TaskItem::WorkflowPolicy::StopOnDone && success)
@@ -300,7 +312,7 @@ void TaskContainer::updateSuccessBit(bool success)
bool TaskNode::start() bool TaskNode::start()
{ {
if (!m_taskHandler.m_createHandler || !m_taskHandler.m_setupHandler) { if (!isTask()) {
m_container.start(); m_container.start();
return true; return true;
} }
@@ -334,11 +346,21 @@ void TaskNode::stop()
m_container.stop(); m_container.stop();
} }
bool TaskNode::isRunning() bool TaskNode::isRunning() const
{ {
return m_task || m_container.isRunning(); return m_task || m_container.isRunning();
} }
bool TaskNode::isTask() const
{
return m_taskHandler.m_createHandler && m_taskHandler.m_setupHandler;
}
int TaskNode::taskCount() const
{
return isTask() ? 1 : m_container.taskCount();
}
/*! /*!
\class Utils::TaskTree \class Utils::TaskTree
@@ -415,4 +437,9 @@ bool TaskTree::isRunning() const
return d->m_root.isRunning(); return d->m_root.isRunning();
} }
int TaskTree::taskCount() const
{
return d->m_root.taskCount();
}
} // namespace Utils } // namespace Utils

View File

@@ -245,6 +245,7 @@ public:
void start(); void start();
void stop(); void stop();
bool isRunning() const; bool isRunning() const;
int taskCount() const;
signals: signals:
void done(); void done();

View File

@@ -113,6 +113,7 @@ void tst_TaskTree::processTree_data()
QTest::addColumn<Log>("expectedLog"); QTest::addColumn<Log>("expectedLog");
QTest::addColumn<bool>("runningAfterStart"); QTest::addColumn<bool>("runningAfterStart");
QTest::addColumn<bool>("success"); QTest::addColumn<bool>("success");
QTest::addColumn<int>("taskCount");
const auto setupProcessHelper = [this](QtcProcess &process, const QStringList &args, int processId) { const auto setupProcessHelper = [this](QtcProcess &process, const QStringList &args, int processId) {
process.setCommand(CommandLine(m_testAppPath, args)); process.setCommand(CommandLine(m_testAppPath, args));
@@ -156,6 +157,7 @@ void tst_TaskTree::processTree_data()
OnGroupDone(rootDone) OnGroupDone(rootDone)
}; };
const Log emptyLog{{-1, Handler::GroupDone}}; const Log emptyLog{{-1, Handler::GroupDone}};
QTest::newRow("Empty") << emptyRoot << emptyLog << false << true << 0;
const Group nestedRoot { const Group nestedRoot {
Group { Group {
@@ -194,6 +196,7 @@ void tst_TaskTree::processTree_data()
{2, Handler::GroupDone}, {2, Handler::GroupDone},
{1, Handler::GroupDone}, {1, Handler::GroupDone},
{-1, Handler::GroupDone}}; {-1, Handler::GroupDone}};
QTest::newRow("Nested") << nestedRoot << nestedLog << true << true << 1;
const Group parallelRoot { const Group parallelRoot {
parallel, parallel,
@@ -215,6 +218,7 @@ void tst_TaskTree::processTree_data()
{-1, Handler::Done}, {-1, Handler::Done},
{-1, Handler::Done}, {-1, Handler::Done},
{-1, Handler::GroupDone}}; // Done handlers may come in different order {-1, Handler::GroupDone}}; // Done handlers may come in different order
QTest::newRow("Parallel") << parallelRoot << parallelLog << true << true << 5;
const Group sequentialRoot { const Group sequentialRoot {
Process(std::bind(setupProcess, _1, 1), readResult), Process(std::bind(setupProcess, _1, 1), readResult),
@@ -253,6 +257,9 @@ void tst_TaskTree::processTree_data()
{5, Handler::Setup}, {5, Handler::Setup},
{5, Handler::Done}, {5, Handler::Done},
{-1, Handler::GroupDone}}; {-1, Handler::GroupDone}};
QTest::newRow("Sequential") << sequentialRoot << sequentialLog << true << true << 5;
QTest::newRow("SequentialEncapsulated") << sequentialEncapsulatedRoot << sequentialLog
<< true << true << 5;
const Group sequentialNestedRoot { const Group sequentialNestedRoot {
Group { Group {
@@ -293,6 +300,8 @@ void tst_TaskTree::processTree_data()
{2, Handler::GroupDone}, {2, Handler::GroupDone},
{1, Handler::GroupDone}, {1, Handler::GroupDone},
{-1, Handler::GroupDone}}; {-1, Handler::GroupDone}};
QTest::newRow("SequentialNested") << sequentialNestedRoot << sequentialNestedLog
<< true << true << 5;
const Group sequentialErrorRoot { const Group sequentialErrorRoot {
Process(std::bind(setupProcess, _1, 1), readResult), Process(std::bind(setupProcess, _1, 1), readResult),
@@ -310,14 +319,8 @@ void tst_TaskTree::processTree_data()
{3, Handler::Setup}, {3, Handler::Setup},
{3, Handler::Error}, {3, Handler::Error},
{-1, Handler::GroupError}}; {-1, Handler::GroupError}};
QTest::newRow("SequentialError") << sequentialErrorRoot << sequentialErrorLog
const QList<TaskItem> simpleSequence { << true << false << 5;
Process(std::bind(setupProcess, _1, 1), readResult),
Process(std::bind(setupCrashProcess, _1, 2), readResult, readError),
Process(std::bind(setupProcess, _1, 3), readResult),
OnGroupDone(rootDone),
OnGroupError(rootError)
};
const auto constructSimpleSequence = [=](const WorkflowPolicy &policy) { const auto constructSimpleSequence = [=](const WorkflowPolicy &policy) {
return Group { return Group {
@@ -336,6 +339,7 @@ void tst_TaskTree::processTree_data()
{2, Handler::Setup}, {2, Handler::Setup},
{2, Handler::Error}, {2, Handler::Error},
{-1, Handler::GroupError}}; {-1, Handler::GroupError}};
QTest::newRow("StopOnError") << stopOnErrorRoot << stopOnErrorLog << true << false << 3;
const Group continueOnErrorRoot = constructSimpleSequence(continueOnError); const Group continueOnErrorRoot = constructSimpleSequence(continueOnError);
const Log continueOnErrorLog{{1, Handler::Setup}, const Log continueOnErrorLog{{1, Handler::Setup},
@@ -345,11 +349,15 @@ void tst_TaskTree::processTree_data()
{3, Handler::Setup}, {3, Handler::Setup},
{3, Handler::Done}, {3, Handler::Done},
{-1, Handler::GroupError}}; {-1, Handler::GroupError}};
QTest::newRow("ContinueOnError") << continueOnErrorRoot << continueOnErrorLog
<< true << false << 3;
const Group stopOnDoneRoot = constructSimpleSequence(stopOnDone); const Group stopOnDoneRoot = constructSimpleSequence(stopOnDone);
const Log stopOnDoneLog{{1, Handler::Setup}, const Log stopOnDoneLog{{1, Handler::Setup},
{1, Handler::Done}, {1, Handler::Done},
{-1, Handler::GroupDone}}; {-1, Handler::GroupDone}};
QTest::newRow("StopOnDone") << stopOnDoneRoot << stopOnDoneLog
<< true << true << 3;
const Group continueOnDoneRoot = constructSimpleSequence(continueOnDone); const Group continueOnDoneRoot = constructSimpleSequence(continueOnDone);
const Log continueOnDoneLog{{1, Handler::Setup}, const Log continueOnDoneLog{{1, Handler::Setup},
@@ -359,6 +367,7 @@ void tst_TaskTree::processTree_data()
{3, Handler::Setup}, {3, Handler::Setup},
{3, Handler::Done}, {3, Handler::Done},
{-1, Handler::GroupDone}}; {-1, Handler::GroupDone}};
QTest::newRow("ContinueOnDone") << continueOnDoneRoot << continueOnDoneLog << true << true << 3;
const Group optionalRoot { const Group optionalRoot {
optional, optional,
@@ -372,6 +381,7 @@ void tst_TaskTree::processTree_data()
{2, Handler::Setup}, {2, Handler::Setup},
{2, Handler::Error}, {2, Handler::Error},
{-1, Handler::GroupDone}}; {-1, Handler::GroupDone}};
QTest::newRow("Optional") << optionalRoot << optionalLog << true << true << 2;
const auto stopWithDoneSetup = [] { return GroupConfig{GroupAction::StopWithDone}; }; const auto stopWithDoneSetup = [] { return GroupConfig{GroupAction::StopWithDone}; };
const auto stopWithErrorSetup = [] { return GroupConfig{GroupAction::StopWithError}; }; const auto stopWithErrorSetup = [] { return GroupConfig{GroupAction::StopWithError}; };
@@ -396,10 +406,16 @@ void tst_TaskTree::processTree_data()
const Log dynamicSetupDoneLog{{1, Handler::Setup}, const Log dynamicSetupDoneLog{{1, Handler::Setup},
{1, Handler::Done}, {1, Handler::Done},
{-1, Handler::GroupDone}}; {-1, Handler::GroupDone}};
QTest::newRow("DynamicSetupDone") << dynamicSetupDoneRoot << dynamicSetupDoneLog
<< true << true << 4;
const Group dynamicSetupErrorRoot = constructDynamicSetup({stopWithErrorSetup}); const Group dynamicSetupErrorRoot = constructDynamicSetup({stopWithErrorSetup});
const Log dynamicSetupErrorLog{{1, Handler::Setup}, const Log dynamicSetupErrorLog{{1, Handler::Setup},
{1, Handler::Done}, {1, Handler::Done},
{-1, Handler::GroupError}}; {-1, Handler::GroupError}};
QTest::newRow("DynamicSetupError") << dynamicSetupErrorRoot << dynamicSetupErrorLog
<< true << false << 4;
const Group dynamicSetupAllRoot = constructDynamicSetup({continueAllSetup}); const Group dynamicSetupAllRoot = constructDynamicSetup({continueAllSetup});
const Log dynamicSetupAllLog{{1, Handler::Setup}, const Log dynamicSetupAllLog{{1, Handler::Setup},
{1, Handler::Done}, {1, Handler::Done},
@@ -410,6 +426,9 @@ void tst_TaskTree::processTree_data()
{4, Handler::Setup}, {4, Handler::Setup},
{4, Handler::Done}, {4, Handler::Done},
{-1, Handler::GroupDone}}; {-1, Handler::GroupDone}};
QTest::newRow("DynamicSetupAll") << dynamicSetupAllRoot << dynamicSetupAllLog
<< true << true << 4;
const Group dynamicSetupSelRoot = constructDynamicSetup({continueSelSetup}); const Group dynamicSetupSelRoot = constructDynamicSetup({continueSelSetup});
const Log dynamicSetupSelLog{{1, Handler::Setup}, const Log dynamicSetupSelLog{{1, Handler::Setup},
{1, Handler::Done}, {1, Handler::Done},
@@ -418,23 +437,8 @@ void tst_TaskTree::processTree_data()
{4, Handler::Setup}, {4, Handler::Setup},
{4, Handler::Done}, {4, Handler::Done},
{-1, Handler::GroupDone}}; {-1, Handler::GroupDone}};
QTest::newRow("DynamicSetupSelected") << dynamicSetupSelRoot << dynamicSetupSelLog
QTest::newRow("Empty") << emptyRoot << emptyLog << false << true; << true << true << 4;
QTest::newRow("Nested") << nestedRoot << nestedLog << true << true;
QTest::newRow("Parallel") << parallelRoot << parallelLog << true << true;
QTest::newRow("Sequential") << sequentialRoot << sequentialLog << true << true;
QTest::newRow("SequentialEncapsulated") << sequentialEncapsulatedRoot << sequentialLog << true << true;
QTest::newRow("SequentialNested") << sequentialNestedRoot << sequentialNestedLog << true << true;
QTest::newRow("SequentialError") << sequentialErrorRoot << sequentialErrorLog << true << false;
QTest::newRow("StopOnError") << stopOnErrorRoot << stopOnErrorLog << true << false;
QTest::newRow("ContinueOnError") << continueOnErrorRoot << continueOnErrorLog << true << false;
QTest::newRow("StopOnDone") << stopOnDoneRoot << stopOnDoneLog << true << true;
QTest::newRow("ContinueOnDone") << continueOnDoneRoot << continueOnDoneLog << true << true;
QTest::newRow("Optional") << optionalRoot << optionalLog << true << true;
QTest::newRow("DynamicSetupDone") << dynamicSetupDoneRoot << dynamicSetupDoneLog << true << true;
QTest::newRow("DynamicSetupError") << dynamicSetupErrorRoot << dynamicSetupErrorLog << true << false;
QTest::newRow("DynamicSetupAll") << dynamicSetupAllRoot << dynamicSetupAllLog << true << true;
QTest::newRow("DynamicSetupSelected") << dynamicSetupSelRoot << dynamicSetupSelLog << true << true;
} }
void tst_TaskTree::processTree() void tst_TaskTree::processTree()
@@ -446,9 +450,11 @@ void tst_TaskTree::processTree()
QFETCH(Log, expectedLog); QFETCH(Log, expectedLog);
QFETCH(bool, runningAfterStart); QFETCH(bool, runningAfterStart);
QFETCH(bool, success); QFETCH(bool, success);
QFETCH(int, taskCount);
QEventLoop eventLoop; QEventLoop eventLoop;
TaskTree processTree(root); TaskTree processTree(root);
QCOMPARE(processTree.taskCount(), taskCount);
int doneCount = 0; int doneCount = 0;
int errorCount = 0; int errorCount = 0;
connect(&processTree, &TaskTree::done, this, [&doneCount, &eventLoop] { ++doneCount; eventLoop.quit(); }); connect(&processTree, &TaskTree::done, this, [&doneCount, &eventLoop] { ++doneCount; eventLoop.quit(); });