Merge pull request #1306 from Ryex/ci/address-sanitiser_on_debug_builds
This commit is contained in:
parent
7926170073
commit
27f6debdaf
@ -85,6 +85,38 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DTOML_ENABLE_FLOAT16=0")
|
|||||||
# set CXXFLAGS for build targets
|
# set CXXFLAGS for build targets
|
||||||
set(CMAKE_CXX_FLAGS_RELEASE "-O2 -D_FORTIFY_SOURCE=2 ${CMAKE_CXX_FLAGS_RELEASE}")
|
set(CMAKE_CXX_FLAGS_RELEASE "-O2 -D_FORTIFY_SOURCE=2 ${CMAKE_CXX_FLAGS_RELEASE}")
|
||||||
|
|
||||||
|
option(DEBUG_ADDRESS_SANITIZER "Enable Address Sanitizer in Debug builds" on)
|
||||||
|
|
||||||
|
# If this is a Debug build turn on address sanitiser
|
||||||
|
if (CMAKE_BUILD_TYPE STREQUAL "Debug" AND DEBUG_ADDRESS_SANITIZER)
|
||||||
|
message(STATUS "Address Sanitizer enabled for Debug builds, Turn it off with -DDEBUG_ADDRESS_SANITIZER=off")
|
||||||
|
if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")
|
||||||
|
if (CMAKE_CXX_COMPILER_FRONTEND_VARIANT STREQUAL "MSVC")
|
||||||
|
# using clang with clang-cl front end
|
||||||
|
message(STATUS "Address Sanitizer available on Clang MSVC frontend")
|
||||||
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /fsanitize=address /O1 /Oy-")
|
||||||
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /fsanitize=address /O1 /Oy-")
|
||||||
|
else()
|
||||||
|
# AppleClang and Clang
|
||||||
|
message(STATUS "Address Sanitizer available on Clang")
|
||||||
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address -O1 -fno-omit-frame-pointer")
|
||||||
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=address -O1 -fno-omit-frame-pointer")
|
||||||
|
endif()
|
||||||
|
elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
|
||||||
|
# GCC
|
||||||
|
message(STATUS "Address Sanitizer available on GCC")
|
||||||
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address -O1 -fno-omit-frame-pointer")
|
||||||
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=address -O1 -fno-omit-frame-pointer")
|
||||||
|
link_libraries("asan")
|
||||||
|
elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
|
||||||
|
message(STATUS "Address Sanitizer available on MSVC")
|
||||||
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /fsanitize=address /O1 /Oy-")
|
||||||
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /fsanitize=address /O1 /Oy-")
|
||||||
|
else()
|
||||||
|
message(STATUS "Address Sanitizer not available on compiler ${CMAKE_CXX_COMPILER_ID}")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
option(ENABLE_LTO "Enable Link Time Optimization" off)
|
option(ENABLE_LTO "Enable Link Time Optimization" off)
|
||||||
|
|
||||||
if(ENABLE_LTO)
|
if(ENABLE_LTO)
|
||||||
|
@ -42,6 +42,10 @@ class LinkTask : public Task {
|
|||||||
m_lnk->debug(true);
|
m_lnk->debug(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
~LinkTask() {
|
||||||
|
delete m_lnk;
|
||||||
|
}
|
||||||
|
|
||||||
void matcher(const IPathMatcher *filter)
|
void matcher(const IPathMatcher *filter)
|
||||||
{
|
{
|
||||||
m_lnk->matcher(filter);
|
m_lnk->matcher(filter);
|
||||||
@ -219,7 +223,8 @@ slots:
|
|||||||
qDebug() << tempDir.path();
|
qDebug() << tempDir.path();
|
||||||
qDebug() << target_dir.path();
|
qDebug() << target_dir.path();
|
||||||
FS::copy c(folder, target_dir.path());
|
FS::copy c(folder, target_dir.path());
|
||||||
c.matcher(new RegexpMatcher("[.]?mcmeta"));
|
RegexpMatcher re("[.]?mcmeta");
|
||||||
|
c.matcher(&re);
|
||||||
c();
|
c();
|
||||||
|
|
||||||
for(auto entry: target_dir.entryList())
|
for(auto entry: target_dir.entryList())
|
||||||
@ -253,7 +258,8 @@ slots:
|
|||||||
qDebug() << tempDir.path();
|
qDebug() << tempDir.path();
|
||||||
qDebug() << target_dir.path();
|
qDebug() << target_dir.path();
|
||||||
FS::copy c(folder, target_dir.path());
|
FS::copy c(folder, target_dir.path());
|
||||||
c.matcher(new RegexpMatcher("[.]?mcmeta"));
|
RegexpMatcher re("[.]?mcmeta");
|
||||||
|
c.matcher(&re);
|
||||||
c.whitelist(true);
|
c.whitelist(true);
|
||||||
c();
|
c();
|
||||||
|
|
||||||
@ -460,7 +466,8 @@ slots:
|
|||||||
qDebug() << target_dir.path();
|
qDebug() << target_dir.path();
|
||||||
|
|
||||||
LinkTask lnk_tsk(folder, target_dir.path());
|
LinkTask lnk_tsk(folder, target_dir.path());
|
||||||
lnk_tsk.matcher(new RegexpMatcher("[.]?mcmeta"));
|
RegexpMatcher re("[.]?mcmeta");
|
||||||
|
lnk_tsk.matcher(&re);
|
||||||
lnk_tsk.linkRecursively(true);
|
lnk_tsk.linkRecursively(true);
|
||||||
QObject::connect(&lnk_tsk, &Task::finished, [&]{
|
QObject::connect(&lnk_tsk, &Task::finished, [&]{
|
||||||
QVERIFY2(lnk_tsk.wasSuccessful(), "Task finished but was not successful when it should have been.");
|
QVERIFY2(lnk_tsk.wasSuccessful(), "Task finished but was not successful when it should have been.");
|
||||||
@ -511,7 +518,8 @@ slots:
|
|||||||
qDebug() << target_dir.path();
|
qDebug() << target_dir.path();
|
||||||
|
|
||||||
LinkTask lnk_tsk(folder, target_dir.path());
|
LinkTask lnk_tsk(folder, target_dir.path());
|
||||||
lnk_tsk.matcher(new RegexpMatcher("[.]?mcmeta"));
|
RegexpMatcher re("[.]?mcmeta");
|
||||||
|
lnk_tsk.matcher(&re);
|
||||||
lnk_tsk.linkRecursively(true);
|
lnk_tsk.linkRecursively(true);
|
||||||
lnk_tsk.whitelist(true);
|
lnk_tsk.whitelist(true);
|
||||||
QObject::connect(&lnk_tsk, &Task::finished, [&]{
|
QObject::connect(&lnk_tsk, &Task::finished, [&]{
|
||||||
|
@ -38,6 +38,7 @@ class DummyResourceModel : public ResourceModel {
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
DummyResourceModel() : ResourceModel(new DummyResourceAPI) {}
|
DummyResourceModel() : ResourceModel(new DummyResourceAPI) {}
|
||||||
|
~DummyResourceModel() {}
|
||||||
|
|
||||||
[[nodiscard]] auto metaEntryBase() const -> QString override { return ""; };
|
[[nodiscard]] auto metaEntryBase() const -> QString override { return ""; };
|
||||||
|
|
||||||
@ -58,7 +59,10 @@ class DummyResourceModel : public ResourceModel {
|
|||||||
class ResourceModelTest : public QObject {
|
class ResourceModelTest : public QObject {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
private slots:
|
private slots:
|
||||||
void test_abstract_item_model() { [[maybe_unused]] auto tester = new QAbstractItemModelTester(new DummyResourceModel); }
|
void test_abstract_item_model() {
|
||||||
|
auto dummy = DummyResourceModel();
|
||||||
|
auto tester = QAbstractItemModelTester(&dummy);
|
||||||
|
}
|
||||||
|
|
||||||
void test_search()
|
void test_search()
|
||||||
{
|
{
|
||||||
@ -78,6 +82,8 @@ class ResourceModelTest : public QObject {
|
|||||||
QVERIFY(processed_pack->addonId.toString() == Json::requireString(processed_response, "project_id"));
|
QVERIFY(processed_pack->addonId.toString() == Json::requireString(processed_response, "project_id"));
|
||||||
QVERIFY(processed_pack->description == Json::requireString(processed_response, "description"));
|
QVERIFY(processed_pack->description == Json::requireString(processed_response, "description"));
|
||||||
QVERIFY(processed_pack->authors.first().name == Json::requireString(processed_response, "author"));
|
QVERIFY(processed_pack->authors.first().name == Json::requireString(processed_response, "author"));
|
||||||
|
|
||||||
|
delete model;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
#include <QTest>
|
#include <QTest>
|
||||||
#include <QTimer>
|
|
||||||
#include <QThread>
|
#include <QThread>
|
||||||
|
#include <QTimer>
|
||||||
|
|
||||||
#include <tasks/ConcurrentTask.h>
|
#include <tasks/ConcurrentTask.h>
|
||||||
#include <tasks/MultipleOptionsTask.h>
|
#include <tasks/MultipleOptionsTask.h>
|
||||||
@ -19,10 +19,7 @@ class BasicTask : public Task {
|
|||||||
BasicTask(bool show_debug_log = true) : Task(nullptr, show_debug_log) {}
|
BasicTask(bool show_debug_log = true) : Task(nullptr, show_debug_log) {}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void executeTask() override
|
void executeTask() override { emitSucceeded(); };
|
||||||
{
|
|
||||||
emitSucceeded();
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Does nothing. Only used for testing. */
|
/* Does nothing. Only used for testing. */
|
||||||
@ -34,7 +31,7 @@ class BasicTask_MultiStep : public Task {
|
|||||||
private:
|
private:
|
||||||
auto isMultiStep() const -> bool override { return true; }
|
auto isMultiStep() const -> bool override { return true; }
|
||||||
|
|
||||||
void executeTask() override {};
|
void executeTask() override{};
|
||||||
};
|
};
|
||||||
|
|
||||||
class BigConcurrentTask : public ConcurrentTask {
|
class BigConcurrentTask : public ConcurrentTask {
|
||||||
@ -44,7 +41,7 @@ class BigConcurrentTask : public ConcurrentTask {
|
|||||||
{
|
{
|
||||||
// This is here only to help fill the stack a bit more quickly (if there's an issue, of course :^))
|
// This is here only to help fill the stack a bit more quickly (if there's an issue, of course :^))
|
||||||
// Each tasks thus adds 1024 * 4 bytes to the stack, at the very least.
|
// Each tasks thus adds 1024 * 4 bytes to the stack, at the very least.
|
||||||
[[maybe_unused]] volatile std::array<uint32_t, 1024> some_data_on_the_stack {};
|
[[maybe_unused]] volatile std::array<uint32_t, 1024> some_data_on_the_stack{};
|
||||||
|
|
||||||
ConcurrentTask::startNext();
|
ConcurrentTask::startNext();
|
||||||
}
|
}
|
||||||
@ -53,49 +50,42 @@ class BigConcurrentTask : public ConcurrentTask {
|
|||||||
class BigConcurrentTaskThread : public QThread {
|
class BigConcurrentTaskThread : public QThread {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
BigConcurrentTask big_task;
|
QTimer m_deadline;
|
||||||
|
|
||||||
void run() override
|
void run() override
|
||||||
{
|
{
|
||||||
QTimer deadline;
|
BigConcurrentTask big_task;
|
||||||
deadline.setInterval(10000);
|
m_deadline.setInterval(10000);
|
||||||
connect(&deadline, &QTimer::timeout, this, [this]{ passed_the_deadline = true; });
|
|
||||||
deadline.start();
|
|
||||||
|
|
||||||
// NOTE: Arbitrary value that manages to trigger a problem when there is one.
|
// NOTE: Arbitrary value that manages to trigger a problem when there is one.
|
||||||
// Considering each tasks, in a problematic state, adds 1024 * 4 bytes to the stack,
|
// Considering each tasks, in a problematic state, adds 1024 * 4 bytes to the stack,
|
||||||
// this number is enough to fill up 16 MiB of stack, more than enough to cause a problem.
|
// this number is enough to fill up 16 MiB of stack, more than enough to cause a problem.
|
||||||
static const unsigned s_num_tasks = 1 << 12;
|
static const unsigned s_num_tasks = 1 << 12;
|
||||||
auto sub_tasks = new BasicTask::Ptr[s_num_tasks];
|
|
||||||
|
|
||||||
for (unsigned i = 0; i < s_num_tasks; i++) {
|
for (unsigned i = 0; i < s_num_tasks; i++) {
|
||||||
auto sub_task = makeShared<BasicTask>(false);
|
auto sub_task = makeShared<BasicTask>(false);
|
||||||
sub_tasks[i] = sub_task;
|
|
||||||
big_task.addTask(sub_task);
|
big_task.addTask(sub_task);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
connect(&big_task, &Task::finished, this, &QThread::quit);
|
||||||
|
connect(&m_deadline, &QTimer::timeout, this, [&] { passed_the_deadline = true; quit(); });
|
||||||
|
|
||||||
|
m_deadline.start();
|
||||||
big_task.run();
|
big_task.run();
|
||||||
|
|
||||||
while (!big_task.isFinished() && !passed_the_deadline)
|
exec();
|
||||||
QCoreApplication::processEvents();
|
|
||||||
|
|
||||||
emit finished();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
bool passed_the_deadline = false;
|
bool passed_the_deadline = false;
|
||||||
|
|
||||||
signals:
|
|
||||||
void finished();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class TaskTest : public QObject {
|
class TaskTest : public QObject {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void test_SetStatus_NoMultiStep(){
|
void test_SetStatus_NoMultiStep()
|
||||||
|
{
|
||||||
BasicTask t;
|
BasicTask t;
|
||||||
QString status {"test status"};
|
QString status{ "test status" };
|
||||||
|
|
||||||
t.setStatus(status);
|
t.setStatus(status);
|
||||||
|
|
||||||
@ -103,9 +93,10 @@ class TaskTest : public QObject {
|
|||||||
QCOMPARE(t.getStepProgress().isEmpty(), TaskStepProgressList{}.isEmpty());
|
QCOMPARE(t.getStepProgress().isEmpty(), TaskStepProgressList{}.isEmpty());
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_SetStatus_MultiStep(){
|
void test_SetStatus_MultiStep()
|
||||||
|
{
|
||||||
BasicTask_MultiStep t;
|
BasicTask_MultiStep t;
|
||||||
QString status {"test status"};
|
QString status{ "test status" };
|
||||||
|
|
||||||
t.setStatus(status);
|
t.setStatus(status);
|
||||||
|
|
||||||
@ -115,7 +106,8 @@ class TaskTest : public QObject {
|
|||||||
QCOMPARE(t.getStepProgress().isEmpty(), TaskStepProgressList{}.isEmpty());
|
QCOMPARE(t.getStepProgress().isEmpty(), TaskStepProgressList{}.isEmpty());
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_SetProgress(){
|
void test_SetProgress()
|
||||||
|
{
|
||||||
BasicTask t;
|
BasicTask t;
|
||||||
int current = 42;
|
int current = 42;
|
||||||
int total = 207;
|
int total = 207;
|
||||||
@ -126,17 +118,18 @@ class TaskTest : public QObject {
|
|||||||
QCOMPARE(t.getTotalProgress(), total);
|
QCOMPARE(t.getTotalProgress(), total);
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_basicRun(){
|
void test_basicRun()
|
||||||
|
{
|
||||||
BasicTask t;
|
BasicTask t;
|
||||||
QObject::connect(&t, &Task::finished, [&]{ QVERIFY2(t.wasSuccessful(), "Task finished but was not successful when it should have been."); });
|
QObject::connect(&t, &Task::finished,
|
||||||
|
[&] { QVERIFY2(t.wasSuccessful(), "Task finished but was not successful when it should have been."); });
|
||||||
t.start();
|
t.start();
|
||||||
|
|
||||||
QVERIFY2(QTest::qWaitFor([&]() {
|
QVERIFY2(QTest::qWaitFor([&]() { return t.isFinished(); }, 1000), "Task didn't finish as it should.");
|
||||||
return t.isFinished();
|
|
||||||
}, 1000), "Task didn't finish as it should.");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_basicConcurrentRun(){
|
void test_basicConcurrentRun()
|
||||||
|
{
|
||||||
auto t1 = makeShared<BasicTask>();
|
auto t1 = makeShared<BasicTask>();
|
||||||
auto t2 = makeShared<BasicTask>();
|
auto t2 = makeShared<BasicTask>();
|
||||||
auto t3 = makeShared<BasicTask>();
|
auto t3 = makeShared<BasicTask>();
|
||||||
@ -147,21 +140,20 @@ class TaskTest : public QObject {
|
|||||||
t.addTask(t2);
|
t.addTask(t2);
|
||||||
t.addTask(t3);
|
t.addTask(t3);
|
||||||
|
|
||||||
QObject::connect(&t, &Task::finished, [&]{
|
QObject::connect(&t, &Task::finished, [&t, &t1, &t2, &t3] {
|
||||||
QVERIFY2(t.wasSuccessful(), "Task finished but was not successful when it should have been.");
|
QVERIFY2(t.wasSuccessful(), "Task finished but was not successful when it should have been.");
|
||||||
QVERIFY(t1->wasSuccessful());
|
QVERIFY(t1->wasSuccessful());
|
||||||
QVERIFY(t2->wasSuccessful());
|
QVERIFY(t2->wasSuccessful());
|
||||||
QVERIFY(t3->wasSuccessful());
|
QVERIFY(t3->wasSuccessful());
|
||||||
});
|
});
|
||||||
|
|
||||||
t.start();
|
t.start();
|
||||||
QVERIFY2(QTest::qWaitFor([&]() {
|
QVERIFY2(QTest::qWaitFor([&]() { return t.isFinished(); }, 1000), "Task didn't finish as it should.");
|
||||||
return t.isFinished();
|
|
||||||
}, 1000), "Task didn't finish as it should.");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tests if starting new tasks after the 6 initial ones is working
|
// Tests if starting new tasks after the 6 initial ones is working
|
||||||
void test_moreConcurrentRun(){
|
void test_moreConcurrentRun()
|
||||||
|
{
|
||||||
auto t1 = makeShared<BasicTask>();
|
auto t1 = makeShared<BasicTask>();
|
||||||
auto t2 = makeShared<BasicTask>();
|
auto t2 = makeShared<BasicTask>();
|
||||||
auto t3 = makeShared<BasicTask>();
|
auto t3 = makeShared<BasicTask>();
|
||||||
@ -184,26 +176,25 @@ class TaskTest : public QObject {
|
|||||||
t.addTask(t8);
|
t.addTask(t8);
|
||||||
t.addTask(t9);
|
t.addTask(t9);
|
||||||
|
|
||||||
QObject::connect(&t, &Task::finished, [&]{
|
QObject::connect(&t, &Task::finished, [&t, &t1, &t2, &t3, &t4, &t5, &t6, &t7, &t8, &t9] {
|
||||||
QVERIFY2(t.wasSuccessful(), "Task finished but was not successful when it should have been.");
|
QVERIFY2(t.wasSuccessful(), "Task finished but was not successful when it should have been.");
|
||||||
QVERIFY(t1->wasSuccessful());
|
QVERIFY(t1->wasSuccessful());
|
||||||
QVERIFY(t2->wasSuccessful());
|
QVERIFY(t2->wasSuccessful());
|
||||||
QVERIFY(t3->wasSuccessful());
|
QVERIFY(t3->wasSuccessful());
|
||||||
QVERIFY(t4->wasSuccessful());
|
QVERIFY(t4->wasSuccessful());
|
||||||
QVERIFY(t5->wasSuccessful());
|
QVERIFY(t5->wasSuccessful());
|
||||||
QVERIFY(t6->wasSuccessful());
|
QVERIFY(t6->wasSuccessful());
|
||||||
QVERIFY(t7->wasSuccessful());
|
QVERIFY(t7->wasSuccessful());
|
||||||
QVERIFY(t8->wasSuccessful());
|
QVERIFY(t8->wasSuccessful());
|
||||||
QVERIFY(t9->wasSuccessful());
|
QVERIFY(t9->wasSuccessful());
|
||||||
});
|
});
|
||||||
|
|
||||||
t.start();
|
t.start();
|
||||||
QVERIFY2(QTest::qWaitFor([&]() {
|
QVERIFY2(QTest::qWaitFor([&]() { return t.isFinished(); }, 1000), "Task didn't finish as it should.");
|
||||||
return t.isFinished();
|
|
||||||
}, 1000), "Task didn't finish as it should.");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_basicSequentialRun(){
|
void test_basicSequentialRun()
|
||||||
|
{
|
||||||
auto t1 = makeShared<BasicTask>();
|
auto t1 = makeShared<BasicTask>();
|
||||||
auto t2 = makeShared<BasicTask>();
|
auto t2 = makeShared<BasicTask>();
|
||||||
auto t3 = makeShared<BasicTask>();
|
auto t3 = makeShared<BasicTask>();
|
||||||
@ -214,20 +205,19 @@ class TaskTest : public QObject {
|
|||||||
t.addTask(t2);
|
t.addTask(t2);
|
||||||
t.addTask(t3);
|
t.addTask(t3);
|
||||||
|
|
||||||
QObject::connect(&t, &Task::finished, [&]{
|
QObject::connect(&t, &Task::finished, [&t, &t1, &t2, &t3] {
|
||||||
QVERIFY2(t.wasSuccessful(), "Task finished but was not successful when it should have been.");
|
QVERIFY2(t.wasSuccessful(), "Task finished but was not successful when it should have been.");
|
||||||
QVERIFY(t1->wasSuccessful());
|
QVERIFY(t1->wasSuccessful());
|
||||||
QVERIFY(t2->wasSuccessful());
|
QVERIFY(t2->wasSuccessful());
|
||||||
QVERIFY(t3->wasSuccessful());
|
QVERIFY(t3->wasSuccessful());
|
||||||
});
|
});
|
||||||
|
|
||||||
t.start();
|
t.start();
|
||||||
QVERIFY2(QTest::qWaitFor([&]() {
|
QVERIFY2(QTest::qWaitFor([&]() { return t.isFinished(); }, 1000), "Task didn't finish as it should.");
|
||||||
return t.isFinished();
|
|
||||||
}, 1000), "Task didn't finish as it should.");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_basicMultipleOptionsRun(){
|
void test_basicMultipleOptionsRun()
|
||||||
|
{
|
||||||
auto t1 = makeShared<BasicTask>();
|
auto t1 = makeShared<BasicTask>();
|
||||||
auto t2 = makeShared<BasicTask>();
|
auto t2 = makeShared<BasicTask>();
|
||||||
auto t3 = makeShared<BasicTask>();
|
auto t3 = makeShared<BasicTask>();
|
||||||
@ -238,33 +228,30 @@ class TaskTest : public QObject {
|
|||||||
t.addTask(t2);
|
t.addTask(t2);
|
||||||
t.addTask(t3);
|
t.addTask(t3);
|
||||||
|
|
||||||
QObject::connect(&t, &Task::finished, [&]{
|
QObject::connect(&t, &Task::finished, [&t, &t1, &t2, &t3] {
|
||||||
QVERIFY2(t.wasSuccessful(), "Task finished but was not successful when it should have been.");
|
QVERIFY2(t.wasSuccessful(), "Task finished but was not successful when it should have been.");
|
||||||
QVERIFY(t1->wasSuccessful());
|
QVERIFY(t1->wasSuccessful());
|
||||||
QVERIFY(!t2->wasSuccessful());
|
QVERIFY(!t2->wasSuccessful());
|
||||||
QVERIFY(!t3->wasSuccessful());
|
QVERIFY(!t3->wasSuccessful());
|
||||||
});
|
});
|
||||||
|
|
||||||
t.start();
|
t.start();
|
||||||
QVERIFY2(QTest::qWaitFor([&]() {
|
QVERIFY2(QTest::qWaitFor([&]() { return t.isFinished(); }, 1000), "Task didn't finish as it should.");
|
||||||
return t.isFinished();
|
|
||||||
}, 1000), "Task didn't finish as it should.");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_stackOverflowInConcurrentTask()
|
void test_stackOverflowInConcurrentTask()
|
||||||
{
|
{
|
||||||
QEventLoop loop;
|
QEventLoop loop;
|
||||||
|
|
||||||
auto thread = new BigConcurrentTaskThread;
|
BigConcurrentTaskThread thread;
|
||||||
|
|
||||||
connect(thread, &BigConcurrentTaskThread::finished, &loop, &QEventLoop::quit);
|
connect(&thread, &BigConcurrentTaskThread::finished, &loop, &QEventLoop::quit);
|
||||||
|
|
||||||
thread->start();
|
thread.start();
|
||||||
|
|
||||||
loop.exec();
|
loop.exec();
|
||||||
|
|
||||||
QVERIFY(!thread->passed_the_deadline);
|
QVERIFY(!thread.passed_the_deadline);
|
||||||
thread->deleteLater();
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -20,6 +20,8 @@
|
|||||||
class VersionTest : public QObject {
|
class VersionTest : public QObject {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
|
QStringList m_flex_test_names = {};
|
||||||
|
|
||||||
void addDataColumns()
|
void addDataColumns()
|
||||||
{
|
{
|
||||||
QTest::addColumn<QString>("first");
|
QTest::addColumn<QString>("first");
|
||||||
@ -101,8 +103,9 @@ class VersionTest : public QObject {
|
|||||||
QString first{split_line.first().simplified()};
|
QString first{split_line.first().simplified()};
|
||||||
QString second{split_line.last().simplified()};
|
QString second{split_line.last().simplified()};
|
||||||
|
|
||||||
auto new_test_name = test_name_template.arg(QString::number(test_number), "lessThan").toLatin1().data();
|
auto new_test_name = test_name_template.arg(QString::number(test_number), "lessThan");
|
||||||
QTest::newRow(new_test_name) << first << second << true << false;
|
m_flex_test_names.append(new_test_name);
|
||||||
|
QTest::newRow(m_flex_test_names.last().toLatin1().data()) << first << second << true << false;
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -112,8 +115,9 @@ class VersionTest : public QObject {
|
|||||||
QString first{split_line.first().simplified()};
|
QString first{split_line.first().simplified()};
|
||||||
QString second{split_line.last().simplified()};
|
QString second{split_line.last().simplified()};
|
||||||
|
|
||||||
auto new_test_name = test_name_template.arg(QString::number(test_number), "equals").toLatin1().data();
|
auto new_test_name = test_name_template.arg(QString::number(test_number), "equals");
|
||||||
QTest::newRow(new_test_name) << first << second << false << true;
|
m_flex_test_names.append(new_test_name);
|
||||||
|
QTest::newRow(m_flex_test_names.last().toLatin1().data()) << first << second << false << true;
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -123,8 +127,9 @@ class VersionTest : public QObject {
|
|||||||
QString first{split_line.first().simplified()};
|
QString first{split_line.first().simplified()};
|
||||||
QString second{split_line.last().simplified()};
|
QString second{split_line.last().simplified()};
|
||||||
|
|
||||||
auto new_test_name = test_name_template.arg(QString::number(test_number), "greaterThan").toLatin1().data();
|
auto new_test_name = test_name_template.arg(QString::number(test_number), "greaterThan");
|
||||||
QTest::newRow(new_test_name) << first << second << false << false;
|
m_flex_test_names.append(new_test_name);
|
||||||
|
QTest::newRow(m_flex_test_names.last().toLatin1().data()) << first << second << false << false;
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user