1
0
mirror of https://github.com/clementine-player/Clementine synced 2024-12-22 15:58:45 +01:00
Clementine-audio-player-Mac.../tests/concurrentrun_test.cpp
Jonas Kvinge 320a1b81c9 Fix incorrect use of QFutureWatcher
To avoid a race condition, it is important to call setFuture() after doing the connections.

See: https://doc.qt.io/qt-6/qfuturewatcher.html
2021-07-14 10:18:15 +01:00

158 lines
3.8 KiB
C++

#include "gtest/gtest.h"
#include <functional>
#include <QEventLoop>
#include <QFutureWatcher>
#include <QThreadPool>
#include "core/concurrentrun.h"
#include "test_utils.h"
int f() {
return 1337;
}
TEST(ConcurrentRunTest, ConcurrentRun0StartAndWait) {
QThreadPool threadpool;
QFuture<int> future = ConcurrentRun::Run<int>(&threadpool, &f);
QFutureWatcher<int> watcher;
QEventLoop loop;
QObject::connect(&watcher, SIGNAL(finished()), &loop, SLOT(quit()));
watcher.setFuture(future);
loop.exec();
EXPECT_EQ(1337, watcher.result());
}
int g(int i) {
return ++i;
}
TEST(ConcurrentRunTest, ConcurrentRun1StartAndWait) {
QThreadPool threadpool;
int i = 1336;
QFuture<int> future = ConcurrentRun::Run<int, int>(&threadpool, &g, i);
QFutureWatcher<int> watcher;
QEventLoop loop;
QObject::connect(&watcher, SIGNAL(finished()), &loop, SLOT(quit()));
watcher.setFuture(future);
loop.exec();
EXPECT_EQ(1337, watcher.result());
}
int max(int i, int j) {
return (i > j ? i : j);
}
TEST(ConcurrentRunTest, ConcurrentRun2StartAndWait) {
int i = 10;
int j = 42;
QThreadPool threadpool;
QFuture<int> future = ConcurrentRun::Run<int, int, int>(&threadpool, &max, i, j);
QFutureWatcher<int> watcher;
QEventLoop loop;
QObject::connect(&watcher, SIGNAL(finished()), &loop, SLOT(quit()));
watcher.setFuture(future);
loop.exec();
EXPECT_EQ(42, watcher.result());
}
int sum(int a, int b, int c) {
return a + b + c;
}
TEST(ConcurrentRunTest, ConcurrentRun3StartAndWait) {
int i = 10;
int j = 42;
int k = 50;
QThreadPool threadpool;
QFuture<int> future = ConcurrentRun::Run<int, int, int, int>(&threadpool, &sum, i, j, k);
QFutureWatcher<int> watcher;
QEventLoop loop;
QObject::connect(&watcher, SIGNAL(finished()), &loop, SLOT(quit()));
watcher.setFuture(future);
loop.exec();
EXPECT_EQ(102, watcher.result());
}
void aFunction(int* n) {
*n = 1337;
}
void bFunction(int* n, int *m) {
aFunction(n);
*m = 1338;
}
void cFunction(int* n, int *m, int *o) {
bFunction(n, m);
*o = 1339;
}
TEST(ConcurrentRunTest, ConcurrentRunVoidFunction1Start) {
QThreadPool threadpool;
int n = 10;
QFuture<void> future = ConcurrentRun::Run<void, int*>(&threadpool, &aFunction, &n);
QFutureWatcher<void> watcher;
QEventLoop loop;
QObject::connect(&watcher, SIGNAL(finished()), &loop, SLOT(quit()));
watcher.setFuture(future);
loop.exec();
EXPECT_EQ(1337, n);
}
TEST(ConcurrentRunTest, ConcurrentRunVoidFunction2Start) {
QThreadPool threadpool;
int n = 10, m = 11;
QFuture<void> future = ConcurrentRun::Run<void, int*, int*>(&threadpool, &bFunction, &n, &m);
QFutureWatcher<void> watcher;
QEventLoop loop;
QObject::connect(&watcher, SIGNAL(finished()), &loop, SLOT(quit()));
watcher.setFuture(future);
loop.exec();
EXPECT_EQ(1337, n);
EXPECT_EQ(1338, m);
}
TEST(ConcurrentRunTest, ConcurrentRunVoidFunction3Start) {
QThreadPool threadpool;
int n = 10, m = 11, o = 12;
QFuture<void> future = ConcurrentRun::Run<void, int*, int*, int*>(&threadpool, &cFunction, &n, &m, &o);
QFutureWatcher<void> watcher;
QEventLoop loop;
QObject::connect(&watcher, SIGNAL(finished()), &loop, SLOT(quit()));
watcher.setFuture(future);
loop.exec();
EXPECT_EQ(1337, n);
EXPECT_EQ(1338, m);
EXPECT_EQ(1339, o);
}
class A {
public:
void f(int* i) {
*i = *i + 1;
}
};
TEST(ConcurrentRunTest, ConcurrentRunVoidBindFunctionStart) {
QThreadPool threadpool;
A a;
int nb = 10;
QFuture<void> future = ConcurrentRun::Run<void>(&threadpool, std::bind(&A::f, &a, &nb));
QFutureWatcher<void> watcher;
QEventLoop loop;
QObject::connect(&watcher, SIGNAL(finished()), &loop, SLOT(quit()));
watcher.setFuture(future);
loop.exec();
EXPECT_EQ(11, nb);
}
// TODO: add some more complex test cases? (e.g. with several CPU-consuming
// tasks launched in parallel, with/without threadpool's threads numbers
// decreased, etc.)