forked from qt-creator/qt-creator
TaskTree: Rewrite tests to use AsyncTask
Instead of using QtcProcess. In this way the tests may be executed much faster, since there is no need to start qtcreator_processlauncher. This should limit the CI failures caused by timeout when executing these tests. Remove testapp, unneeded now. Change-Id: I80775276c2aaec7c2d463b1ac25010efa942b258 Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: <github-actions-qt-creator@cristianadam.eu> Reviewed-by: Marcus Tillmanns <marcus.tillmanns@qt.io>
This commit is contained in:
@@ -1,11 +1,4 @@
|
|||||||
add_subdirectory(testapp)
|
|
||||||
|
|
||||||
file(RELATIVE_PATH RELATIVE_TEST_PATH "${PROJECT_BINARY_DIR}" "${CMAKE_CURRENT_BINARY_DIR}")
|
|
||||||
file(RELATIVE_PATH TEST_RELATIVE_LIBEXEC_PATH "/${RELATIVE_TEST_PATH}" "/${IDE_LIBEXEC_PATH}")
|
|
||||||
|
|
||||||
add_qtc_test(tst_utils_tasktree
|
add_qtc_test(tst_utils_tasktree
|
||||||
DEFINES "TEST_RELATIVE_LIBEXEC_PATH=\"${TEST_RELATIVE_LIBEXEC_PATH}\""
|
DEPENDS Utils
|
||||||
"TESTAPP_PATH=\"${CMAKE_CURRENT_BINARY_DIR}/testapp\""
|
|
||||||
DEPENDS Utils app_version
|
|
||||||
SOURCES tst_tasktree.cpp
|
SOURCES tst_tasktree.cpp
|
||||||
)
|
)
|
||||||
|
@@ -1,12 +0,0 @@
|
|||||||
add_qtc_executable(testapp
|
|
||||||
DEPENDS Utils app_version
|
|
||||||
SOURCES main.cpp
|
|
||||||
SKIP_INSTALL
|
|
||||||
INTERNAL_ONLY
|
|
||||||
)
|
|
||||||
|
|
||||||
set_target_properties(testapp PROPERTIES
|
|
||||||
LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}"
|
|
||||||
ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}"
|
|
||||||
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}"
|
|
||||||
)
|
|
@@ -1,63 +0,0 @@
|
|||||||
// Copyright (C) 2022 The Qt Company Ltd.
|
|
||||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
|
||||||
|
|
||||||
#include <app/app_version.h>
|
|
||||||
|
|
||||||
#include <QString>
|
|
||||||
#include <QThread>
|
|
||||||
|
|
||||||
#ifdef Q_OS_WIN
|
|
||||||
#include <crtdbg.h>
|
|
||||||
#include <cstdlib>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
const char CRASH_OPTION[] = "-crash";
|
|
||||||
const char RETURN_OPTION[] = "-return";
|
|
||||||
const char SLEEP_OPTION[] = "-sleep";
|
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
|
||||||
{
|
|
||||||
#ifdef Q_OS_WIN
|
|
||||||
// avoid crash reporter dialog
|
|
||||||
_set_error_mode(_OUT_TO_STDERR);
|
|
||||||
_CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_DEBUG);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (argc > 1) {
|
|
||||||
const auto arg = QString::fromLocal8Bit(argv[1]);
|
|
||||||
if (arg == CRASH_OPTION) {
|
|
||||||
qFatal("The application has crashed purposefully!");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
if (arg == RETURN_OPTION) {
|
|
||||||
if (argc > 2) {
|
|
||||||
const auto retString = QString::fromLocal8Bit(argv[2]);
|
|
||||||
bool ok = false;
|
|
||||||
const int retVal = retString.toInt(&ok);
|
|
||||||
if (ok)
|
|
||||||
return retVal;
|
|
||||||
// not an int return value
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
// lacking return value
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
if (arg == SLEEP_OPTION) {
|
|
||||||
if (argc > 2) {
|
|
||||||
const auto msecsString = QString::fromLocal8Bit(argv[2]);
|
|
||||||
bool ok = false;
|
|
||||||
const int msecsVal = msecsString.toInt(&ok);
|
|
||||||
if (ok) {
|
|
||||||
QThread::msleep(msecsVal);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
// not an int return value
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
// lacking return value
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// not recognized option
|
|
||||||
return 1;
|
|
||||||
}
|
|
@@ -1,20 +0,0 @@
|
|||||||
import qbs.FileInfo
|
|
||||||
|
|
||||||
QtApplication {
|
|
||||||
name: "testapp"
|
|
||||||
Depends { name: "qtc" }
|
|
||||||
Depends { name: "Utils" }
|
|
||||||
Depends { name: "app_version_header" }
|
|
||||||
|
|
||||||
consoleApplication: true
|
|
||||||
cpp.cxxLanguageVersion: "c++17"
|
|
||||||
cpp.rpaths: project.buildDirectory + '/' + qtc.ide_library_path
|
|
||||||
|
|
||||||
install: false
|
|
||||||
destinationDirectory: project.buildDirectory + '/'
|
|
||||||
+ FileInfo.relativePath(project.ide_source_tree, sourceDirectory)
|
|
||||||
|
|
||||||
files: [
|
|
||||||
"main.cpp",
|
|
||||||
]
|
|
||||||
}
|
|
@@ -1,18 +1,20 @@
|
|||||||
// Copyright (C) 2022 The Qt Company Ltd.
|
// Copyright (C) 2022 The Qt Company Ltd.
|
||||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||||
|
|
||||||
#include <app/app_version.h>
|
#include <utils/asynctask.h>
|
||||||
|
|
||||||
#include <utils/launcherinterface.h>
|
|
||||||
#include <utils/qtcprocess.h>
|
|
||||||
#include <utils/singleton.h>
|
|
||||||
#include <utils/temporarydirectory.h>
|
|
||||||
|
|
||||||
#include <QtTest>
|
#include <QtTest>
|
||||||
|
|
||||||
|
#include <QDeadlineTimer>
|
||||||
|
|
||||||
|
using namespace std::literals::chrono_literals;
|
||||||
|
|
||||||
using namespace Utils;
|
using namespace Utils;
|
||||||
using namespace Utils::Tasking;
|
using namespace Utils::Tasking;
|
||||||
|
|
||||||
|
using TestTask = AsyncTask<void>;
|
||||||
|
using Test = Async<void>;
|
||||||
|
|
||||||
enum class Handler {
|
enum class Handler {
|
||||||
Setup,
|
Setup,
|
||||||
Done,
|
Done,
|
||||||
@@ -37,7 +39,9 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
int CustomStorage::s_count = 0;
|
int CustomStorage::s_count = 0;
|
||||||
static const char s_processIdProperty[] = "__processId";
|
static const char s_taskIdProperty[] = "__taskId";
|
||||||
|
|
||||||
|
static FutureSynchronizer *s_futureSynchronizer = nullptr;
|
||||||
|
|
||||||
enum class OnStart { Running, NotRunning };
|
enum class OnStart { Running, NotRunning };
|
||||||
enum class OnDone { Success, Failure };
|
enum class OnDone { Success, Failure };
|
||||||
@@ -59,66 +63,58 @@ private slots:
|
|||||||
void initTestCase();
|
void initTestCase();
|
||||||
|
|
||||||
void validConstructs(); // compile test
|
void validConstructs(); // compile test
|
||||||
void processTree_data();
|
void testTree_data();
|
||||||
void processTree();
|
void testTree();
|
||||||
void storageOperators();
|
void storageOperators();
|
||||||
void storageDestructor();
|
void storageDestructor();
|
||||||
|
|
||||||
void cleanupTestCase();
|
void cleanupTestCase();
|
||||||
|
|
||||||
private:
|
|
||||||
FilePath m_testAppPath;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
void tst_TaskTree::initTestCase()
|
void tst_TaskTree::initTestCase()
|
||||||
{
|
{
|
||||||
TemporaryDirectory::setMasterTemporaryDirectory(QDir::tempPath() + "/"
|
s_futureSynchronizer = new FutureSynchronizer;
|
||||||
+ Core::Constants::IDE_CASED_ID + "-XXXXXX");
|
|
||||||
const QString libExecPath(qApp->applicationDirPath() + '/'
|
|
||||||
+ QLatin1String(TEST_RELATIVE_LIBEXEC_PATH));
|
|
||||||
LauncherInterface::setPathToLauncher(libExecPath);
|
|
||||||
m_testAppPath = FilePath::fromString(QLatin1String(TESTAPP_PATH)
|
|
||||||
+ QLatin1String("/testapp")).withExecutableSuffix();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void tst_TaskTree::cleanupTestCase()
|
void tst_TaskTree::cleanupTestCase()
|
||||||
{
|
{
|
||||||
Singleton::deleteAll();
|
delete s_futureSynchronizer;
|
||||||
|
s_futureSynchronizer = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void tst_TaskTree::validConstructs()
|
void tst_TaskTree::validConstructs()
|
||||||
{
|
{
|
||||||
const Group process {
|
const Group task {
|
||||||
parallel,
|
parallel,
|
||||||
Process([](QtcProcess &) {}, [](const QtcProcess &) {}),
|
Test([](TestTask &) {}, [](const TestTask &) {}),
|
||||||
Process([](QtcProcess &) {}, [](const QtcProcess &) {}),
|
Test([](TestTask &) {}, [](const TestTask &) {}),
|
||||||
Process([](QtcProcess &) {}, [](const QtcProcess &) {})
|
Test([](TestTask &) {}, [](const TestTask &) {})
|
||||||
};
|
};
|
||||||
|
|
||||||
const Group group1 {
|
const Group group1 {
|
||||||
process
|
task
|
||||||
};
|
};
|
||||||
|
|
||||||
const Group group2 {
|
const Group group2 {
|
||||||
parallel,
|
parallel,
|
||||||
Group {
|
Group {
|
||||||
parallel,
|
parallel,
|
||||||
Process([](QtcProcess &) {}, [](const QtcProcess &) {}),
|
Test([](TestTask &) {}, [](const TestTask &) {}),
|
||||||
Group {
|
Group {
|
||||||
parallel,
|
parallel,
|
||||||
Process([](QtcProcess &) {}, [](const QtcProcess &) {}),
|
Test([](TestTask &) {}, [](const TestTask &) {}),
|
||||||
Group {
|
Group {
|
||||||
parallel,
|
parallel,
|
||||||
Process([](QtcProcess &) {}, [](const QtcProcess &) {})
|
Test([](TestTask &) {}, [](const TestTask &) {})
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
Group {
|
Group {
|
||||||
parallel,
|
parallel,
|
||||||
Process([](QtcProcess &) {}, [](const QtcProcess &) {}),
|
Test([](TestTask &) {}, [](const TestTask &) {}),
|
||||||
OnGroupDone([] {})
|
OnGroupDone([] {})
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
process,
|
task,
|
||||||
OnGroupDone([] {}),
|
OnGroupDone([] {}),
|
||||||
OnGroupError([] {})
|
OnGroupError([] {})
|
||||||
};
|
};
|
||||||
@@ -150,70 +146,75 @@ void tst_TaskTree::validConstructs()
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void tst_TaskTree::processTree_data()
|
static void runTask(QPromise<void> &promise, bool success, std::chrono::milliseconds sleep)
|
||||||
|
{
|
||||||
|
QDeadlineTimer deadline(sleep);
|
||||||
|
while (!deadline.hasExpired()) {
|
||||||
|
QThread::msleep(1);
|
||||||
|
if (promise.isCanceled())
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!success)
|
||||||
|
promise.future().cancel();
|
||||||
|
}
|
||||||
|
|
||||||
|
void tst_TaskTree::testTree_data()
|
||||||
{
|
{
|
||||||
QTest::addColumn<TestData>("testData");
|
QTest::addColumn<TestData>("testData");
|
||||||
|
|
||||||
TreeStorage<CustomStorage> storage;
|
TreeStorage<CustomStorage> storage;
|
||||||
|
|
||||||
const auto setupProcessHelper = [storage, testAppPath = m_testAppPath]
|
const auto setupTaskHelper = [storage](TestTask &task, int taskId, bool success = true,
|
||||||
(QtcProcess &process, const QStringList &args, int processId) {
|
std::chrono::milliseconds sleep = 0ms) {
|
||||||
process.setCommand(CommandLine(testAppPath, args));
|
task.setFutureSynchronizer(s_futureSynchronizer);
|
||||||
process.setProperty(s_processIdProperty, processId);
|
task.setConcurrentCallData(runTask, success, sleep);
|
||||||
storage->m_log.append({processId, Handler::Setup});
|
task.setProperty(s_taskIdProperty, taskId);
|
||||||
|
storage->m_log.append({taskId, Handler::Setup});
|
||||||
};
|
};
|
||||||
const auto setupProcess = [setupProcessHelper](int processId) {
|
const auto setupTask = [setupTaskHelper](int taskId) {
|
||||||
return [=](QtcProcess &process) {
|
return [=](TestTask &task) { setupTaskHelper(task, taskId); };
|
||||||
setupProcessHelper(process, {"-return", "0"}, processId);
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
const auto setupCrashProcess = [setupProcessHelper](int processId) {
|
const auto setupFailingTask = [setupTaskHelper](int taskId) {
|
||||||
return [=](QtcProcess &process) {
|
return [=](TestTask &task) { setupTaskHelper(task, taskId, false); };
|
||||||
setupProcessHelper(process, {"-crash"}, processId);
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
const auto setupSleepProcess = [setupProcessHelper](int processId, int msecs) {
|
const auto setupSleepingTask = [setupTaskHelper](int taskId, std::chrono::milliseconds sleep) {
|
||||||
return [=](QtcProcess &process) {
|
return [=](TestTask &task) { setupTaskHelper(task, taskId, true, sleep); };
|
||||||
setupProcessHelper(process, {"-sleep", QString::number(msecs)}, processId);
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
const auto setupDynamicProcess = [setupProcessHelper](int processId, TaskAction action) {
|
const auto setupDynamicTask = [setupTaskHelper](int taskId, TaskAction action) {
|
||||||
return [=](QtcProcess &process) {
|
return [=](TestTask &task) {
|
||||||
setupProcessHelper(process, {"-return", "0"}, processId);
|
setupTaskHelper(task, taskId);
|
||||||
return action;
|
return action;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
const auto readResult = [storage](const QtcProcess &process) {
|
const auto logDone = [storage](const TestTask &task) {
|
||||||
const int processId = process.property(s_processIdProperty).toInt();
|
storage->m_log.append({task.property(s_taskIdProperty).toInt(), Handler::Done});
|
||||||
storage->m_log.append({processId, Handler::Done});
|
|
||||||
};
|
};
|
||||||
const auto readError = [storage](const QtcProcess &process) {
|
const auto logError = [storage](const TestTask &task) {
|
||||||
const int processId = process.property(s_processIdProperty).toInt();
|
storage->m_log.append({task.property(s_taskIdProperty).toInt(), Handler::Error});
|
||||||
storage->m_log.append({processId, Handler::Error});
|
|
||||||
};
|
};
|
||||||
const auto groupSetup = [storage](int groupId) {
|
const auto groupSetup = [storage](int taskId) {
|
||||||
return [=] { storage->m_log.append({groupId, Handler::GroupSetup}); };
|
return [=] { storage->m_log.append({taskId, Handler::GroupSetup}); };
|
||||||
};
|
};
|
||||||
const auto groupDone = [storage](int groupId) {
|
const auto groupDone = [storage](int taskId) {
|
||||||
return [=] { storage->m_log.append({groupId, Handler::GroupDone}); };
|
return [=] { storage->m_log.append({taskId, Handler::GroupDone}); };
|
||||||
};
|
};
|
||||||
const auto groupError = [storage](int groupId) {
|
const auto groupError = [storage](int taskId) {
|
||||||
return [=] { storage->m_log.append({groupId, Handler::GroupError}); };
|
return [=] { storage->m_log.append({taskId, Handler::GroupError}); };
|
||||||
};
|
};
|
||||||
const auto setupSync = [storage](int syncId) {
|
const auto setupSync = [storage](int taskId) {
|
||||||
return [=] { storage->m_log.append({syncId, Handler::Sync}); };
|
return [=] { storage->m_log.append({taskId, Handler::Sync}); };
|
||||||
};
|
};
|
||||||
const auto setupSyncWithReturn = [storage](int syncId, bool success) {
|
const auto setupSyncWithReturn = [storage](int taskId, bool success) {
|
||||||
return [=] { storage->m_log.append({syncId, Handler::Sync}); return success; };
|
return [=] { storage->m_log.append({taskId, Handler::Sync}); return success; };
|
||||||
};
|
};
|
||||||
|
|
||||||
const auto constructSimpleSequence = [=](const Workflow &policy) {
|
const auto constructSimpleSequence = [=](const Workflow &policy) {
|
||||||
return Group {
|
return Group {
|
||||||
Storage(storage),
|
Storage(storage),
|
||||||
policy,
|
policy,
|
||||||
Process(setupProcess(1), readResult),
|
Test(setupTask(1), logDone),
|
||||||
Process(setupCrashProcess(2), readResult, readError),
|
Test(setupFailingTask(2), logDone, logError),
|
||||||
Process(setupProcess(3), readResult),
|
Test(setupTask(3), logDone),
|
||||||
OnGroupDone(groupDone(0)),
|
OnGroupDone(groupDone(0)),
|
||||||
OnGroupError(groupError(0))
|
OnGroupError(groupError(0))
|
||||||
};
|
};
|
||||||
@@ -222,13 +223,13 @@ void tst_TaskTree::processTree_data()
|
|||||||
return Group {
|
return Group {
|
||||||
Storage(storage),
|
Storage(storage),
|
||||||
Group {
|
Group {
|
||||||
Process(setupProcess(1), readResult)
|
Test(setupTask(1), logDone)
|
||||||
},
|
},
|
||||||
Group {
|
Group {
|
||||||
OnGroupSetup([=] { return taskAction; }),
|
OnGroupSetup([=] { return taskAction; }),
|
||||||
Process(setupProcess(2), readResult),
|
Test(setupTask(2), logDone),
|
||||||
Process(setupProcess(3), readResult),
|
Test(setupTask(3), logDone),
|
||||||
Process(setupProcess(4), readResult)
|
Test(setupTask(4), logDone)
|
||||||
},
|
},
|
||||||
OnGroupDone(groupDone(0)),
|
OnGroupDone(groupDone(0)),
|
||||||
OnGroupError(groupError(0))
|
OnGroupError(groupError(0))
|
||||||
@@ -274,8 +275,8 @@ void tst_TaskTree::processTree_data()
|
|||||||
{
|
{
|
||||||
const Group root {
|
const Group root {
|
||||||
Storage(storage),
|
Storage(storage),
|
||||||
Process(setupDynamicProcess(1, TaskAction::StopWithDone), readResult, readError),
|
Test(setupDynamicTask(1, TaskAction::StopWithDone), logDone, logError),
|
||||||
Process(setupDynamicProcess(2, TaskAction::StopWithDone), readResult, readError)
|
Test(setupDynamicTask(2, TaskAction::StopWithDone), logDone, logError)
|
||||||
};
|
};
|
||||||
const Log log {{1, Handler::Setup}, {2, Handler::Setup}};
|
const Log log {{1, Handler::Setup}, {2, Handler::Setup}};
|
||||||
QTest::newRow("DynamicTaskDone")
|
QTest::newRow("DynamicTaskDone")
|
||||||
@@ -285,8 +286,8 @@ void tst_TaskTree::processTree_data()
|
|||||||
{
|
{
|
||||||
const Group root {
|
const Group root {
|
||||||
Storage(storage),
|
Storage(storage),
|
||||||
Process(setupDynamicProcess(1, TaskAction::StopWithError), readResult, readError),
|
Test(setupDynamicTask(1, TaskAction::StopWithError), logDone, logError),
|
||||||
Process(setupDynamicProcess(2, TaskAction::StopWithError), readResult, readError)
|
Test(setupDynamicTask(2, TaskAction::StopWithError), logDone, logError)
|
||||||
};
|
};
|
||||||
const Log log {{1, Handler::Setup}};
|
const Log log {{1, Handler::Setup}};
|
||||||
QTest::newRow("DynamicTaskError")
|
QTest::newRow("DynamicTaskError")
|
||||||
@@ -296,10 +297,10 @@ void tst_TaskTree::processTree_data()
|
|||||||
{
|
{
|
||||||
const Group root {
|
const Group root {
|
||||||
Storage(storage),
|
Storage(storage),
|
||||||
Process(setupDynamicProcess(1, TaskAction::Continue), readResult, readError),
|
Test(setupDynamicTask(1, TaskAction::Continue), logDone, logError),
|
||||||
Process(setupDynamicProcess(2, TaskAction::Continue), readResult, readError),
|
Test(setupDynamicTask(2, TaskAction::Continue), logDone, logError),
|
||||||
Process(setupDynamicProcess(3, TaskAction::StopWithError), readResult, readError),
|
Test(setupDynamicTask(3, TaskAction::StopWithError), logDone, logError),
|
||||||
Process(setupDynamicProcess(4, TaskAction::Continue), readResult, readError)
|
Test(setupDynamicTask(4, TaskAction::Continue), logDone, logError)
|
||||||
};
|
};
|
||||||
const Log log {
|
const Log log {
|
||||||
{1, Handler::Setup},
|
{1, Handler::Setup},
|
||||||
@@ -316,10 +317,10 @@ void tst_TaskTree::processTree_data()
|
|||||||
const Group root {
|
const Group root {
|
||||||
parallel,
|
parallel,
|
||||||
Storage(storage),
|
Storage(storage),
|
||||||
Process(setupDynamicProcess(1, TaskAction::Continue), readResult, readError),
|
Test(setupDynamicTask(1, TaskAction::Continue), logDone, logError),
|
||||||
Process(setupDynamicProcess(2, TaskAction::Continue), readResult, readError),
|
Test(setupDynamicTask(2, TaskAction::Continue), logDone, logError),
|
||||||
Process(setupDynamicProcess(3, TaskAction::StopWithError), readResult, readError),
|
Test(setupDynamicTask(3, TaskAction::StopWithError), logDone, logError),
|
||||||
Process(setupDynamicProcess(4, TaskAction::Continue), readResult, readError)
|
Test(setupDynamicTask(4, TaskAction::Continue), logDone, logError)
|
||||||
};
|
};
|
||||||
const Log log {
|
const Log log {
|
||||||
{1, Handler::Setup},
|
{1, Handler::Setup},
|
||||||
@@ -336,12 +337,12 @@ void tst_TaskTree::processTree_data()
|
|||||||
const Group root {
|
const Group root {
|
||||||
parallel,
|
parallel,
|
||||||
Storage(storage),
|
Storage(storage),
|
||||||
Process(setupDynamicProcess(1, TaskAction::Continue), readResult, readError),
|
Test(setupDynamicTask(1, TaskAction::Continue), logDone, logError),
|
||||||
Process(setupDynamicProcess(2, TaskAction::Continue), readResult, readError),
|
Test(setupDynamicTask(2, TaskAction::Continue), logDone, logError),
|
||||||
Group {
|
Group {
|
||||||
Process(setupDynamicProcess(3, TaskAction::StopWithError), readResult, readError)
|
Test(setupDynamicTask(3, TaskAction::StopWithError), logDone, logError)
|
||||||
},
|
},
|
||||||
Process(setupDynamicProcess(4, TaskAction::Continue), readResult, readError)
|
Test(setupDynamicTask(4, TaskAction::Continue), logDone, logError)
|
||||||
};
|
};
|
||||||
const Log log {
|
const Log log {
|
||||||
{1, Handler::Setup},
|
{1, Handler::Setup},
|
||||||
@@ -358,16 +359,16 @@ void tst_TaskTree::processTree_data()
|
|||||||
const Group root {
|
const Group root {
|
||||||
parallel,
|
parallel,
|
||||||
Storage(storage),
|
Storage(storage),
|
||||||
Process(setupDynamicProcess(1, TaskAction::Continue), readResult, readError),
|
Test(setupDynamicTask(1, TaskAction::Continue), logDone, logError),
|
||||||
Process(setupDynamicProcess(2, TaskAction::Continue), readResult, readError),
|
Test(setupDynamicTask(2, TaskAction::Continue), logDone, logError),
|
||||||
Group {
|
Group {
|
||||||
OnGroupSetup([storage] {
|
OnGroupSetup([storage] {
|
||||||
storage->m_log.append({0, Handler::GroupSetup});
|
storage->m_log.append({0, Handler::GroupSetup});
|
||||||
return TaskAction::StopWithError;
|
return TaskAction::StopWithError;
|
||||||
}),
|
}),
|
||||||
Process(setupDynamicProcess(3, TaskAction::Continue), readResult, readError)
|
Test(setupDynamicTask(3, TaskAction::Continue), logDone, logError)
|
||||||
},
|
},
|
||||||
Process(setupDynamicProcess(4, TaskAction::Continue), readResult, readError)
|
Test(setupDynamicTask(4, TaskAction::Continue), logDone, logError)
|
||||||
};
|
};
|
||||||
const Log log {
|
const Log log {
|
||||||
{1, Handler::Setup},
|
{1, Handler::Setup},
|
||||||
@@ -388,7 +389,7 @@ void tst_TaskTree::processTree_data()
|
|||||||
Group {
|
Group {
|
||||||
Group {
|
Group {
|
||||||
Group {
|
Group {
|
||||||
Process(setupProcess(5), readResult, readError),
|
Test(setupTask(5), logDone, logError),
|
||||||
OnGroupSetup(groupSetup(5)),
|
OnGroupSetup(groupSetup(5)),
|
||||||
OnGroupDone(groupDone(5))
|
OnGroupDone(groupDone(5))
|
||||||
},
|
},
|
||||||
@@ -426,17 +427,17 @@ void tst_TaskTree::processTree_data()
|
|||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
const auto readResultAnonymous = [=](const QtcProcess &) {
|
const auto logDoneAnonymously = [=](const TestTask &) {
|
||||||
storage->m_log.append({0, Handler::Done});
|
storage->m_log.append({0, Handler::Done});
|
||||||
};
|
};
|
||||||
const Group root {
|
const Group root {
|
||||||
Storage(storage),
|
Storage(storage),
|
||||||
parallel,
|
parallel,
|
||||||
Process(setupProcess(1), readResultAnonymous),
|
Test(setupTask(1), logDoneAnonymously),
|
||||||
Process(setupProcess(2), readResultAnonymous),
|
Test(setupTask(2), logDoneAnonymously),
|
||||||
Process(setupProcess(3), readResultAnonymous),
|
Test(setupTask(3), logDoneAnonymously),
|
||||||
Process(setupProcess(4), readResultAnonymous),
|
Test(setupTask(4), logDoneAnonymously),
|
||||||
Process(setupProcess(5), readResultAnonymous),
|
Test(setupTask(5), logDoneAnonymously),
|
||||||
OnGroupDone(groupDone(0))
|
OnGroupDone(groupDone(0))
|
||||||
};
|
};
|
||||||
const Log log {
|
const Log log {
|
||||||
@@ -460,9 +461,9 @@ void tst_TaskTree::processTree_data()
|
|||||||
auto setupSubTree = [=](TaskTree &taskTree) {
|
auto setupSubTree = [=](TaskTree &taskTree) {
|
||||||
const Group nestedRoot {
|
const Group nestedRoot {
|
||||||
Storage(storage),
|
Storage(storage),
|
||||||
Process(setupProcess(2), readResult),
|
Test(setupTask(2), logDone),
|
||||||
Process(setupProcess(3), readResult),
|
Test(setupTask(3), logDone),
|
||||||
Process(setupProcess(4), readResult)
|
Test(setupTask(4), logDone)
|
||||||
};
|
};
|
||||||
taskTree.setupRoot(nestedRoot);
|
taskTree.setupRoot(nestedRoot);
|
||||||
CustomStorage *activeStorage = storage.activeStorage();
|
CustomStorage *activeStorage = storage.activeStorage();
|
||||||
@@ -473,27 +474,27 @@ void tst_TaskTree::processTree_data()
|
|||||||
};
|
};
|
||||||
const Group root1 {
|
const Group root1 {
|
||||||
Storage(storage),
|
Storage(storage),
|
||||||
Process(setupProcess(1), readResult),
|
Test(setupTask(1), logDone),
|
||||||
Process(setupProcess(2), readResult),
|
Test(setupTask(2), logDone),
|
||||||
Process(setupProcess(3), readResult),
|
Test(setupTask(3), logDone),
|
||||||
Process(setupProcess(4), readResult),
|
Test(setupTask(4), logDone),
|
||||||
Process(setupProcess(5), readResult),
|
Test(setupTask(5), logDone),
|
||||||
OnGroupDone(groupDone(0))
|
OnGroupDone(groupDone(0))
|
||||||
};
|
};
|
||||||
const Group root2 {
|
const Group root2 {
|
||||||
Storage(storage),
|
Storage(storage),
|
||||||
Group { Process(setupProcess(1), readResult) },
|
Group { Test(setupTask(1), logDone) },
|
||||||
Group { Process(setupProcess(2), readResult) },
|
Group { Test(setupTask(2), logDone) },
|
||||||
Group { Process(setupProcess(3), readResult) },
|
Group { Test(setupTask(3), logDone) },
|
||||||
Group { Process(setupProcess(4), readResult) },
|
Group { Test(setupTask(4), logDone) },
|
||||||
Group { Process(setupProcess(5), readResult) },
|
Group { Test(setupTask(5), logDone) },
|
||||||
OnGroupDone(groupDone(0))
|
OnGroupDone(groupDone(0))
|
||||||
};
|
};
|
||||||
const Group root3 {
|
const Group root3 {
|
||||||
Storage(storage),
|
Storage(storage),
|
||||||
Process(setupProcess(1), readResult),
|
Test(setupTask(1), logDone),
|
||||||
Tree(setupSubTree),
|
Tree(setupSubTree),
|
||||||
Process(setupProcess(5), readResult),
|
Test(setupTask(5), logDone),
|
||||||
OnGroupDone(groupDone(0))
|
OnGroupDone(groupDone(0))
|
||||||
};
|
};
|
||||||
const Log log {
|
const Log log {
|
||||||
@@ -521,15 +522,15 @@ void tst_TaskTree::processTree_data()
|
|||||||
const Group root {
|
const Group root {
|
||||||
Storage(storage),
|
Storage(storage),
|
||||||
Group {
|
Group {
|
||||||
Process(setupProcess(1), readResult),
|
Test(setupTask(1), logDone),
|
||||||
Group {
|
Group {
|
||||||
Process(setupProcess(2), readResult),
|
Test(setupTask(2), logDone),
|
||||||
Group {
|
Group {
|
||||||
Process(setupProcess(3), readResult),
|
Test(setupTask(3), logDone),
|
||||||
Group {
|
Group {
|
||||||
Process(setupProcess(4), readResult),
|
Test(setupTask(4), logDone),
|
||||||
Group {
|
Group {
|
||||||
Process(setupProcess(5), readResult),
|
Test(setupTask(5), logDone),
|
||||||
OnGroupDone(groupDone(5))
|
OnGroupDone(groupDone(5))
|
||||||
},
|
},
|
||||||
OnGroupDone(groupDone(4))
|
OnGroupDone(groupDone(4))
|
||||||
@@ -567,11 +568,11 @@ void tst_TaskTree::processTree_data()
|
|||||||
{
|
{
|
||||||
const Group root {
|
const Group root {
|
||||||
Storage(storage),
|
Storage(storage),
|
||||||
Process(setupProcess(1), readResult),
|
Test(setupTask(1), logDone),
|
||||||
Process(setupProcess(2), readResult),
|
Test(setupTask(2), logDone),
|
||||||
Process(setupCrashProcess(3), readResult, readError),
|
Test(setupFailingTask(3), logDone, logError),
|
||||||
Process(setupProcess(4), readResult),
|
Test(setupTask(4), logDone),
|
||||||
Process(setupProcess(5), readResult),
|
Test(setupTask(5), logDone),
|
||||||
OnGroupDone(groupDone(0)),
|
OnGroupDone(groupDone(0)),
|
||||||
OnGroupError(groupError(0))
|
OnGroupError(groupError(0))
|
||||||
};
|
};
|
||||||
@@ -646,8 +647,8 @@ void tst_TaskTree::processTree_data()
|
|||||||
const Group root {
|
const Group root {
|
||||||
Storage(storage),
|
Storage(storage),
|
||||||
optional,
|
optional,
|
||||||
Process(setupCrashProcess(1), readResult, readError),
|
Test(setupFailingTask(1), logDone, logError),
|
||||||
Process(setupCrashProcess(2), readResult, readError),
|
Test(setupFailingTask(2), logDone, logError),
|
||||||
OnGroupDone(groupDone(0)),
|
OnGroupDone(groupDone(0)),
|
||||||
OnGroupError(groupError(0))
|
OnGroupError(groupError(0))
|
||||||
};
|
};
|
||||||
@@ -707,19 +708,19 @@ void tst_TaskTree::processTree_data()
|
|||||||
Storage(storage),
|
Storage(storage),
|
||||||
Group {
|
Group {
|
||||||
OnGroupSetup(groupSetup(1)),
|
OnGroupSetup(groupSetup(1)),
|
||||||
Process(setupProcess(1))
|
Test(setupTask(1))
|
||||||
},
|
},
|
||||||
Group {
|
Group {
|
||||||
OnGroupSetup(groupSetup(2)),
|
OnGroupSetup(groupSetup(2)),
|
||||||
Process(setupProcess(2))
|
Test(setupTask(2))
|
||||||
},
|
},
|
||||||
Group {
|
Group {
|
||||||
OnGroupSetup(groupSetup(3)),
|
OnGroupSetup(groupSetup(3)),
|
||||||
Process(setupProcess(3))
|
Test(setupTask(3))
|
||||||
},
|
},
|
||||||
Group {
|
Group {
|
||||||
OnGroupSetup(groupSetup(4)),
|
OnGroupSetup(groupSetup(4)),
|
||||||
Process(setupProcess(4))
|
Test(setupTask(4))
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
const Log log {
|
const Log log {
|
||||||
@@ -742,23 +743,23 @@ void tst_TaskTree::processTree_data()
|
|||||||
Storage(storage),
|
Storage(storage),
|
||||||
Group {
|
Group {
|
||||||
OnGroupSetup(groupSetup(1)),
|
OnGroupSetup(groupSetup(1)),
|
||||||
Process(setupProcess(1))
|
Test(setupTask(1))
|
||||||
},
|
},
|
||||||
Group {
|
Group {
|
||||||
OnGroupSetup(groupSetup(2)),
|
OnGroupSetup(groupSetup(2)),
|
||||||
Process(setupProcess(2))
|
Test(setupTask(2))
|
||||||
},
|
},
|
||||||
Group {
|
Group {
|
||||||
OnGroupSetup(groupSetup(3)),
|
OnGroupSetup(groupSetup(3)),
|
||||||
Process(setupDynamicProcess(3, TaskAction::StopWithDone))
|
Test(setupDynamicTask(3, TaskAction::StopWithDone))
|
||||||
},
|
},
|
||||||
Group {
|
Group {
|
||||||
OnGroupSetup(groupSetup(4)),
|
OnGroupSetup(groupSetup(4)),
|
||||||
Process(setupProcess(4))
|
Test(setupTask(4))
|
||||||
},
|
},
|
||||||
Group {
|
Group {
|
||||||
OnGroupSetup(groupSetup(5)),
|
OnGroupSetup(groupSetup(5)),
|
||||||
Process(setupProcess(5))
|
Test(setupTask(5))
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
const Log log {
|
const Log log {
|
||||||
@@ -783,63 +784,63 @@ void tst_TaskTree::processTree_data()
|
|||||||
Storage(storage),
|
Storage(storage),
|
||||||
Group {
|
Group {
|
||||||
OnGroupSetup(groupSetup(1)),
|
OnGroupSetup(groupSetup(1)),
|
||||||
Process(setupProcess(1))
|
Test(setupTask(1))
|
||||||
},
|
},
|
||||||
Group {
|
Group {
|
||||||
OnGroupSetup(groupSetup(2)),
|
OnGroupSetup(groupSetup(2)),
|
||||||
Process(setupProcess(2))
|
Test(setupTask(2))
|
||||||
},
|
},
|
||||||
Group {
|
Group {
|
||||||
OnGroupSetup(groupSetup(3)),
|
OnGroupSetup(groupSetup(3)),
|
||||||
Process(setupDynamicProcess(3, TaskAction::StopWithError))
|
Test(setupDynamicTask(3, TaskAction::StopWithError))
|
||||||
},
|
},
|
||||||
Group {
|
Group {
|
||||||
OnGroupSetup(groupSetup(4)),
|
OnGroupSetup(groupSetup(4)),
|
||||||
Process(setupProcess(4))
|
Test(setupTask(4))
|
||||||
},
|
},
|
||||||
Group {
|
Group {
|
||||||
OnGroupSetup(groupSetup(5)),
|
OnGroupSetup(groupSetup(5)),
|
||||||
Process(setupProcess(5))
|
Test(setupTask(5))
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Inside this test the process 2 should finish first, then synchonously:
|
// Inside this test the task 2 should finish first, then synchonously:
|
||||||
// - process 3 should exit setup with error
|
// - task 3 should exit setup with error
|
||||||
// - process 1 should be stopped as a consequence of error inside the group
|
// - task 1 should be stopped as a consequence of error inside the group
|
||||||
// - processes 4 and 5 should be skipped
|
// - tasks 4 and 5 should be skipped
|
||||||
const Group root2 {
|
const Group root2 {
|
||||||
ParallelLimit(2),
|
ParallelLimit(2),
|
||||||
Storage(storage),
|
Storage(storage),
|
||||||
Group {
|
Group {
|
||||||
OnGroupSetup(groupSetup(1)),
|
OnGroupSetup(groupSetup(1)),
|
||||||
Process(setupSleepProcess(1, 100))
|
Test(setupSleepingTask(1, 10ms))
|
||||||
},
|
},
|
||||||
Group {
|
Group {
|
||||||
OnGroupSetup(groupSetup(2)),
|
OnGroupSetup(groupSetup(2)),
|
||||||
Process(setupProcess(2))
|
Test(setupTask(2))
|
||||||
},
|
},
|
||||||
Group {
|
Group {
|
||||||
OnGroupSetup(groupSetup(3)),
|
OnGroupSetup(groupSetup(3)),
|
||||||
Process(setupDynamicProcess(3, TaskAction::StopWithError))
|
Test(setupDynamicTask(3, TaskAction::StopWithError))
|
||||||
},
|
},
|
||||||
Group {
|
Group {
|
||||||
OnGroupSetup(groupSetup(4)),
|
OnGroupSetup(groupSetup(4)),
|
||||||
Process(setupProcess(4))
|
Test(setupTask(4))
|
||||||
},
|
},
|
||||||
Group {
|
Group {
|
||||||
OnGroupSetup(groupSetup(5)),
|
OnGroupSetup(groupSetup(5)),
|
||||||
Process(setupProcess(5))
|
Test(setupTask(5))
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// This test ensures process 1 doesn't invoke its done handler,
|
// This test ensures that the task 1 doesn't invoke its done handler,
|
||||||
// being ready while sleeping in process 2 done handler.
|
// being ready while sleeping in the task's 2 done handler.
|
||||||
// Inside this test the process 2 should finish first, then synchonously:
|
// Inside this test the task 2 should finish first, then synchonously:
|
||||||
// - process 3 should exit setup with error
|
// - task 3 should exit setup with error
|
||||||
// - process 1 should be stopped as a consequence of error inside the group
|
// - task 1 should be stopped as a consequence of error inside the group
|
||||||
// - process 4 should be skipped
|
// - task 4 should be skipped
|
||||||
// - the first child group of root should finish with error
|
// - the first child group of root should finish with error
|
||||||
// - process 5 should be started (because of root's continueOnError policy)
|
// - task 5 should be started (because of root's continueOnError policy)
|
||||||
const Group root3 {
|
const Group root3 {
|
||||||
continueOnError,
|
continueOnError,
|
||||||
Storage(storage),
|
Storage(storage),
|
||||||
@@ -847,24 +848,24 @@ void tst_TaskTree::processTree_data()
|
|||||||
ParallelLimit(2),
|
ParallelLimit(2),
|
||||||
Group {
|
Group {
|
||||||
OnGroupSetup(groupSetup(1)),
|
OnGroupSetup(groupSetup(1)),
|
||||||
Process(setupSleepProcess(1, 100))
|
Test(setupSleepingTask(1, 20ms))
|
||||||
},
|
},
|
||||||
Group {
|
Group {
|
||||||
OnGroupSetup(groupSetup(2)),
|
OnGroupSetup(groupSetup(2)),
|
||||||
Process(setupProcess(2), [](const QtcProcess &) { QThread::msleep(200); })
|
Test(setupTask(2), [](const TestTask &) { QThread::msleep(10); })
|
||||||
},
|
},
|
||||||
Group {
|
Group {
|
||||||
OnGroupSetup(groupSetup(3)),
|
OnGroupSetup(groupSetup(3)),
|
||||||
Process(setupDynamicProcess(3, TaskAction::StopWithError))
|
Test(setupDynamicTask(3, TaskAction::StopWithError))
|
||||||
},
|
},
|
||||||
Group {
|
Group {
|
||||||
OnGroupSetup(groupSetup(4)),
|
OnGroupSetup(groupSetup(4)),
|
||||||
Process(setupProcess(4))
|
Test(setupTask(4))
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
Group {
|
Group {
|
||||||
OnGroupSetup(groupSetup(5)),
|
OnGroupSetup(groupSetup(5)),
|
||||||
Process(setupProcess(5))
|
Test(setupTask(5))
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
const Log shortLog {
|
const Log shortLog {
|
||||||
@@ -893,7 +894,7 @@ void tst_TaskTree::processTree_data()
|
|||||||
OnGroupSetup(groupSetup(1)),
|
OnGroupSetup(groupSetup(1)),
|
||||||
Group {
|
Group {
|
||||||
parallel,
|
parallel,
|
||||||
Process(setupProcess(1))
|
Test(setupTask(1))
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
Group {
|
Group {
|
||||||
@@ -901,7 +902,7 @@ void tst_TaskTree::processTree_data()
|
|||||||
OnGroupSetup(groupSetup(2)),
|
OnGroupSetup(groupSetup(2)),
|
||||||
Group {
|
Group {
|
||||||
parallel,
|
parallel,
|
||||||
Process(setupProcess(2))
|
Test(setupTask(2))
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
Group {
|
Group {
|
||||||
@@ -909,7 +910,7 @@ void tst_TaskTree::processTree_data()
|
|||||||
OnGroupSetup(groupSetup(3)),
|
OnGroupSetup(groupSetup(3)),
|
||||||
Group {
|
Group {
|
||||||
parallel,
|
parallel,
|
||||||
Process(setupProcess(3))
|
Test(setupTask(3))
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
Group {
|
Group {
|
||||||
@@ -917,7 +918,7 @@ void tst_TaskTree::processTree_data()
|
|||||||
OnGroupSetup(groupSetup(4)),
|
OnGroupSetup(groupSetup(4)),
|
||||||
Group {
|
Group {
|
||||||
parallel,
|
parallel,
|
||||||
Process(setupProcess(4))
|
Test(setupTask(4))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -942,27 +943,27 @@ void tst_TaskTree::processTree_data()
|
|||||||
Group {
|
Group {
|
||||||
Storage(TreeStorage<CustomStorage>()),
|
Storage(TreeStorage<CustomStorage>()),
|
||||||
OnGroupSetup(groupSetup(1)),
|
OnGroupSetup(groupSetup(1)),
|
||||||
Group { Process(setupProcess(1)) }
|
Group { Test(setupTask(1)) }
|
||||||
},
|
},
|
||||||
Group {
|
Group {
|
||||||
Storage(TreeStorage<CustomStorage>()),
|
Storage(TreeStorage<CustomStorage>()),
|
||||||
OnGroupSetup(groupSetup(2)),
|
OnGroupSetup(groupSetup(2)),
|
||||||
Group { Process(setupProcess(2)) }
|
Group { Test(setupTask(2)) }
|
||||||
},
|
},
|
||||||
Group {
|
Group {
|
||||||
Storage(TreeStorage<CustomStorage>()),
|
Storage(TreeStorage<CustomStorage>()),
|
||||||
OnGroupSetup(groupSetup(3)),
|
OnGroupSetup(groupSetup(3)),
|
||||||
Group { Process(setupDynamicProcess(3, TaskAction::StopWithDone)) }
|
Group { Test(setupDynamicTask(3, TaskAction::StopWithDone)) }
|
||||||
},
|
},
|
||||||
Group {
|
Group {
|
||||||
Storage(TreeStorage<CustomStorage>()),
|
Storage(TreeStorage<CustomStorage>()),
|
||||||
OnGroupSetup(groupSetup(4)),
|
OnGroupSetup(groupSetup(4)),
|
||||||
Group { Process(setupProcess(4)) }
|
Group { Test(setupTask(4)) }
|
||||||
},
|
},
|
||||||
Group {
|
Group {
|
||||||
Storage(TreeStorage<CustomStorage>()),
|
Storage(TreeStorage<CustomStorage>()),
|
||||||
OnGroupSetup(groupSetup(5)),
|
OnGroupSetup(groupSetup(5)),
|
||||||
Group { Process(setupProcess(5)) }
|
Group { Test(setupTask(5)) }
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
const Log log {
|
const Log log {
|
||||||
@@ -988,27 +989,27 @@ void tst_TaskTree::processTree_data()
|
|||||||
Group {
|
Group {
|
||||||
Storage(TreeStorage<CustomStorage>()),
|
Storage(TreeStorage<CustomStorage>()),
|
||||||
OnGroupSetup(groupSetup(1)),
|
OnGroupSetup(groupSetup(1)),
|
||||||
Group { Process(setupProcess(1)) }
|
Group { Test(setupTask(1)) }
|
||||||
},
|
},
|
||||||
Group {
|
Group {
|
||||||
Storage(TreeStorage<CustomStorage>()),
|
Storage(TreeStorage<CustomStorage>()),
|
||||||
OnGroupSetup(groupSetup(2)),
|
OnGroupSetup(groupSetup(2)),
|
||||||
Group { Process(setupProcess(2)) }
|
Group { Test(setupTask(2)) }
|
||||||
},
|
},
|
||||||
Group {
|
Group {
|
||||||
Storage(TreeStorage<CustomStorage>()),
|
Storage(TreeStorage<CustomStorage>()),
|
||||||
OnGroupSetup(groupSetup(3)),
|
OnGroupSetup(groupSetup(3)),
|
||||||
Group { Process(setupDynamicProcess(3, TaskAction::StopWithError)) }
|
Group { Test(setupDynamicTask(3, TaskAction::StopWithError)) }
|
||||||
},
|
},
|
||||||
Group {
|
Group {
|
||||||
Storage(TreeStorage<CustomStorage>()),
|
Storage(TreeStorage<CustomStorage>()),
|
||||||
OnGroupSetup(groupSetup(4)),
|
OnGroupSetup(groupSetup(4)),
|
||||||
Group { Process(setupProcess(4)) }
|
Group { Test(setupTask(4)) }
|
||||||
},
|
},
|
||||||
Group {
|
Group {
|
||||||
Storage(TreeStorage<CustomStorage>()),
|
Storage(TreeStorage<CustomStorage>()),
|
||||||
OnGroupSetup(groupSetup(5)),
|
OnGroupSetup(groupSetup(5)),
|
||||||
Group { Process(setupProcess(5)) }
|
Group { Test(setupTask(5)) }
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
const Log log {
|
const Log log {
|
||||||
@@ -1107,9 +1108,9 @@ void tst_TaskTree::processTree_data()
|
|||||||
const Group root {
|
const Group root {
|
||||||
Storage(storage),
|
Storage(storage),
|
||||||
Sync(setupSync(1)),
|
Sync(setupSync(1)),
|
||||||
Process(setupProcess(2)),
|
Test(setupTask(2)),
|
||||||
Sync(setupSync(3)),
|
Sync(setupSync(3)),
|
||||||
Process(setupProcess(4)),
|
Test(setupTask(4)),
|
||||||
Sync(setupSync(5)),
|
Sync(setupSync(5)),
|
||||||
OnGroupDone(groupDone(0))
|
OnGroupDone(groupDone(0))
|
||||||
};
|
};
|
||||||
@@ -1129,9 +1130,9 @@ void tst_TaskTree::processTree_data()
|
|||||||
const Group root {
|
const Group root {
|
||||||
Storage(storage),
|
Storage(storage),
|
||||||
Sync(setupSync(1)),
|
Sync(setupSync(1)),
|
||||||
Process(setupProcess(2)),
|
Test(setupTask(2)),
|
||||||
Sync(setupSyncWithReturn(3, false)),
|
Sync(setupSyncWithReturn(3, false)),
|
||||||
Process(setupProcess(4)),
|
Test(setupTask(4)),
|
||||||
Sync(setupSync(5)),
|
Sync(setupSync(5)),
|
||||||
OnGroupError(groupError(0))
|
OnGroupError(groupError(0))
|
||||||
};
|
};
|
||||||
@@ -1148,31 +1149,41 @@ void tst_TaskTree::processTree_data()
|
|||||||
{
|
{
|
||||||
Condition condition;
|
Condition condition;
|
||||||
|
|
||||||
const auto setupProcessWithCondition
|
const auto reportAndSleep = [](QPromise<bool> &promise) {
|
||||||
= [storage, condition, setupProcessHelper](int processId) {
|
promise.addResult(false);
|
||||||
return [storage, condition, setupProcessHelper, processId](QtcProcess &process) {
|
QThread::msleep(10);
|
||||||
setupProcessHelper(process, {"-return", "0"}, processId);
|
};
|
||||||
|
|
||||||
|
const auto setupTaskWithCondition = [storage, condition, reportAndSleep](int taskId) {
|
||||||
|
return [storage, condition, reportAndSleep, taskId](AsyncTask<bool> &async) {
|
||||||
|
async.setFutureSynchronizer(s_futureSynchronizer);
|
||||||
|
async.setConcurrentCallData(reportAndSleep);
|
||||||
|
async.setProperty(s_taskIdProperty, taskId);
|
||||||
|
storage->m_log.append({taskId, Handler::Setup});
|
||||||
|
|
||||||
CustomStorage *currentStorage = storage.activeStorage();
|
CustomStorage *currentStorage = storage.activeStorage();
|
||||||
ConditionActivator *currentActivator = condition.activator();
|
ConditionActivator *currentActivator = condition.activator();
|
||||||
connect(&process, &QtcProcess::started, [currentStorage, currentActivator, processId] {
|
connect(&async, &TestTask::resultReadyAt,
|
||||||
currentStorage->m_log.append({processId, Handler::Activator});
|
[currentStorage, currentActivator, taskId](int index) {
|
||||||
|
Q_UNUSED(index)
|
||||||
|
currentStorage->m_log.append({taskId, Handler::Activator});
|
||||||
currentActivator->activate();
|
currentActivator->activate();
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
// Test that Activator, triggered from inside the process described by
|
// Test that Activator, triggered from inside the task described by
|
||||||
// setupProcessWithCondition, placed BEFORE the group containing the WaitFor element
|
// setupTaskWithCondition, placed BEFORE the group containing the WaitFor element
|
||||||
// in the tree order, works OK in SEQUENTIAL mode.
|
// in the tree order, works OK in SEQUENTIAL mode.
|
||||||
const Group root1 {
|
const Group root1 {
|
||||||
Storage(storage),
|
Storage(storage),
|
||||||
sequential,
|
sequential,
|
||||||
Process(setupProcessWithCondition(1)),
|
Async<bool>(setupTaskWithCondition(1)),
|
||||||
Group {
|
Group {
|
||||||
OnGroupSetup(groupSetup(2)),
|
OnGroupSetup(groupSetup(2)),
|
||||||
WaitFor(condition),
|
WaitFor(condition),
|
||||||
Process(setupProcess(2)),
|
Test(setupTask(2)),
|
||||||
Process(setupProcess(3))
|
Test(setupTask(3))
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
const Log log1 {
|
const Log log1 {
|
||||||
@@ -1183,18 +1194,18 @@ void tst_TaskTree::processTree_data()
|
|||||||
{3, Handler::Setup}
|
{3, Handler::Setup}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Test that Activator, triggered from inside the process described by
|
// Test that Activator, triggered from inside the task described by
|
||||||
// setupProcessWithCondition, placed BEFORE the group containing the WaitFor element
|
// setupTaskWithCondition, placed BEFORE the group containing the WaitFor element
|
||||||
// in the tree order, works OK in PARALLEL mode.
|
// in the tree order, works OK in PARALLEL mode.
|
||||||
const Group root2 {
|
const Group root2 {
|
||||||
Storage(storage),
|
Storage(storage),
|
||||||
parallel,
|
parallel,
|
||||||
Process(setupProcessWithCondition(1)),
|
Async<bool>(setupTaskWithCondition(1)),
|
||||||
Group {
|
Group {
|
||||||
OnGroupSetup(groupSetup(2)),
|
OnGroupSetup(groupSetup(2)),
|
||||||
WaitFor(condition),
|
WaitFor(condition),
|
||||||
Process(setupProcess(2)),
|
Test(setupTask(2)),
|
||||||
Process(setupProcess(3))
|
Test(setupTask(3))
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
const Log log2 {
|
const Log log2 {
|
||||||
@@ -1205,8 +1216,8 @@ void tst_TaskTree::processTree_data()
|
|||||||
{3, Handler::Setup}
|
{3, Handler::Setup}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Test that Activator, triggered from inside the process described by
|
// Test that Activator, triggered from inside the task described by
|
||||||
// setupProcessWithCondition, placed AFTER the group containing the WaitFor element
|
// setupTaskWithCondition, placed AFTER the group containing the WaitFor element
|
||||||
// in the tree order, works OK in PARALLEL mode.
|
// in the tree order, works OK in PARALLEL mode.
|
||||||
//
|
//
|
||||||
// Notice: This won't work in SEQUENTIAL mode, since the Activator placed after the
|
// Notice: This won't work in SEQUENTIAL mode, since the Activator placed after the
|
||||||
@@ -1221,10 +1232,10 @@ void tst_TaskTree::processTree_data()
|
|||||||
Group {
|
Group {
|
||||||
OnGroupSetup(groupSetup(2)),
|
OnGroupSetup(groupSetup(2)),
|
||||||
WaitFor(condition),
|
WaitFor(condition),
|
||||||
Process(setupProcess(2)),
|
Test(setupTask(2)),
|
||||||
Process(setupProcess(3))
|
Test(setupTask(3))
|
||||||
},
|
},
|
||||||
Process(setupProcessWithCondition(1))
|
Async<bool>(setupTaskWithCondition(1))
|
||||||
};
|
};
|
||||||
const Log log3 {
|
const Log log3 {
|
||||||
{2, Handler::GroupSetup},
|
{2, Handler::GroupSetup},
|
||||||
@@ -1244,7 +1255,7 @@ void tst_TaskTree::processTree_data()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void tst_TaskTree::processTree()
|
void tst_TaskTree::testTree()
|
||||||
{
|
{
|
||||||
QFETCH(TestData, testData);
|
QFETCH(TestData, testData);
|
||||||
|
|
||||||
@@ -1324,12 +1335,13 @@ void tst_TaskTree::storageDestructor()
|
|||||||
QCOMPARE(CustomStorage::instanceCount(), 0);
|
QCOMPARE(CustomStorage::instanceCount(), 0);
|
||||||
{
|
{
|
||||||
TreeStorage<CustomStorage> storage;
|
TreeStorage<CustomStorage> storage;
|
||||||
const auto setupProcess = [testAppPath = m_testAppPath](QtcProcess &process) {
|
const auto setupSleepingTask = [](TestTask &task) {
|
||||||
process.setCommand(CommandLine(testAppPath, {"-sleep", "1000"}));
|
task.setFutureSynchronizer(s_futureSynchronizer);
|
||||||
|
task.setConcurrentCallData(runTask, true, 1000ms);
|
||||||
};
|
};
|
||||||
const Group root {
|
const Group root {
|
||||||
Storage(storage),
|
Storage(storage),
|
||||||
Process(setupProcess)
|
Test(setupSleepingTask)
|
||||||
};
|
};
|
||||||
|
|
||||||
TaskTree taskTree(root);
|
TaskTree taskTree(root);
|
||||||
@@ -1338,6 +1350,7 @@ void tst_TaskTree::storageDestructor()
|
|||||||
taskTree.onStorageDone(storage, doneHandler);
|
taskTree.onStorageDone(storage, doneHandler);
|
||||||
taskTree.start();
|
taskTree.start();
|
||||||
QCOMPARE(CustomStorage::instanceCount(), 1);
|
QCOMPARE(CustomStorage::instanceCount(), 1);
|
||||||
|
QThread::msleep(5); // Give the sleeping task a change to start
|
||||||
}
|
}
|
||||||
QCOMPARE(CustomStorage::instanceCount(), 0);
|
QCOMPARE(CustomStorage::instanceCount(), 0);
|
||||||
QVERIFY(setupCalled);
|
QVERIFY(setupCalled);
|
||||||
|
Reference in New Issue
Block a user