mirror of
https://github.com/clementine-player/Clementine
synced 2024-12-23 00:09:14 +01:00
320a1b81c9
To avoid a race condition, it is important to call setFuture() after doing the connections. See: https://doc.qt.io/qt-6/qfuturewatcher.html
158 lines
3.8 KiB
C++
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.)
|