summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--store/test/CMakeLists.txt3
-rw-r--r--store/test/storagetest.cpp111
2 files changed, 113 insertions, 1 deletions
diff --git a/store/test/CMakeLists.txt b/store/test/CMakeLists.txt
index 4743cfb..c5c4fcb 100644
--- a/store/test/CMakeLists.txt
+++ b/store/test/CMakeLists.txt
@@ -11,11 +11,12 @@ generate_flatbuffers(calendar)
11macro(manual_tests) 11macro(manual_tests)
12 foreach(_testname ${ARGN}) 12 foreach(_testname ${ARGN})
13 add_executable(${_testname} ${_testname}.cpp ${store_SRCS}) 13 add_executable(${_testname} ${_testname}.cpp ${store_SRCS})
14 qt5_use_modules(${_testname} Core Test) 14 qt5_use_modules(${_testname} Core Test Concurrent)
15 target_link_libraries(${_testname} lmdb) 15 target_link_libraries(${_testname} lmdb)
16 endforeach(_testname) 16 endforeach(_testname)
17endmacro(auto_tests) 17endmacro(auto_tests)
18 18
19manual_tests ( 19manual_tests (
20 storagebenchmark 20 storagebenchmark
21 storagetest
21) 22)
diff --git a/store/test/storagetest.cpp b/store/test/storagetest.cpp
new file mode 100644
index 0000000..1b105af
--- /dev/null
+++ b/store/test/storagetest.cpp
@@ -0,0 +1,111 @@
1#include <QtTest>
2
3#include <iostream>
4
5#include <QDebug>
6#include <QString>
7#include <QtConcurrent/QtConcurrentRun>
8
9#include "store/database.h"
10
11class StorageTest : public QObject
12{
13 Q_OBJECT
14private:
15 //This should point to a directory on disk and not a ramdisk (since we're measuring performance)
16 QString testDataPath;
17 QString dbName;
18 const char *keyPrefix = "key";
19
20 void populate(int count)
21 {
22 Database db(testDataPath, dbName);
23 for (int i = 0; i < count; i++) {
24 //This should perhaps become an implementation detail of the db?
25 if (i % 10000 == 0) {
26 if (i > 0) {
27 db.commitTransaction();
28 }
29 db.startTransaction();
30 }
31 db.write(keyPrefix + std::to_string(i), keyPrefix + std::to_string(i));
32 }
33 db.commitTransaction();
34 }
35
36 bool verify(Database &db, int i)
37 {
38 bool error = false;
39 const auto reference = keyPrefix + std::to_string(i);
40 db.read(keyPrefix + std::to_string(i), [&error, &reference](const std::string &value) {
41 if (value != reference) {
42 qDebug() << "Mismatch while reading";
43 error = true;
44 }
45 });
46 return !error;
47 }
48
49private Q_SLOTS:
50 void initTestCase()
51 {
52 testDataPath = "./testdb";
53 dbName = "test";
54 }
55
56 void cleanupTestCase()
57 {
58 Database db(testDataPath, dbName);
59 db.removeFromDisk();
60 }
61
62
63 void testRead()
64 {
65 const int count = 100;
66
67 populate(count);
68
69 //ensure we can read everything back correctly
70 {
71 Database db(testDataPath, dbName);
72 for (int i = 0; i < count; i++) {
73 QVERIFY(verify(db, i));
74 }
75 }
76
77 Database db(testDataPath, dbName);
78 db.removeFromDisk();
79 }
80
81 void testConcurrentRead()
82 {
83 const int count = 10000;
84
85 populate(count);
86
87 //Try to concurrently read
88 QList<QFuture<void> > futures;
89 const int concurrencyLevel = 4;
90 for (int num = 0; num < concurrencyLevel; num++) {
91 futures << QtConcurrent::run([this, count](){
92 Database db(testDataPath, dbName);
93 for (int i = 0; i < count; i++) {
94 if (!verify(db, i)) {
95 qWarning() << "invalid value";
96 break;
97 }
98 }
99 });
100 }
101 for(auto future : futures) {
102 future.waitForFinished();
103 }
104
105 Database db(testDataPath, dbName);
106 db.removeFromDisk();
107 }
108};
109
110QTEST_MAIN(StorageTest)
111#include "storagetest.moc"