summaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/CMakeLists.txt17
-rw-r--r--tests/calendar.fbs12
-rw-r--r--tests/storagebenchmark.cpp161
-rw-r--r--tests/storagetest.cpp112
4 files changed, 302 insertions, 0 deletions
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
new file mode 100644
index 0000000..1629acb
--- /dev/null
+++ b/tests/CMakeLists.txt
@@ -0,0 +1,17 @@
1set(CMAKE_AUTOMOC ON)
2include_directories(${CMAKE_CURRENT_BINARY_DIR})
3
4generate_flatbuffers(calendar)
5
6macro(manual_tests)
7 foreach(_testname ${ARGN})
8 add_executable(${_testname} ${_testname}.cpp)
9 qt5_use_modules(${_testname} Core Test Concurrent)
10 target_link_libraries(${_testname} akonadinextcommon)
11 endforeach(_testname)
12endmacro(manual_tests)
13
14manual_tests (
15 storagebenchmark
16 storagetest
17)
diff --git a/tests/calendar.fbs b/tests/calendar.fbs
new file mode 100644
index 0000000..203ee43
--- /dev/null
+++ b/tests/calendar.fbs
@@ -0,0 +1,12 @@
1// example IDL file
2
3namespace Calendar;
4
5table Event {
6 summary:string;
7 description:string;
8 attachment:[byte];
9}
10
11root_type Event;
12file_identifier "AKFB";
diff --git a/tests/storagebenchmark.cpp b/tests/storagebenchmark.cpp
new file mode 100644
index 0000000..f9fea7c
--- /dev/null
+++ b/tests/storagebenchmark.cpp
@@ -0,0 +1,161 @@
1#include <QtTest>
2
3#include "calendar_generated.h"
4
5#include <iostream>
6#include <fstream>
7
8#include <QDebug>
9#include <QString>
10#include <QTime>
11
12#include "common/storage.h"
13
14using namespace Calendar;
15using namespace flatbuffers;
16
17static std::string createEvent()
18{
19 FlatBufferBuilder fbb;
20 {
21 auto summary = fbb.CreateString("summary");
22
23 const int attachmentSize = 1024*2; // 2KB
24 int8_t rawData[attachmentSize];
25 auto data = fbb.CreateVector(rawData, attachmentSize);
26
27 Calendar::EventBuilder eventBuilder(fbb);
28 eventBuilder.add_summary(summary);
29 eventBuilder.add_attachment(data);
30 auto eventLocation = eventBuilder.Finish();
31 FinishEventBuffer(fbb, eventLocation);
32 }
33 return std::string(reinterpret_cast<const char *>(fbb.GetBufferPointer()), fbb.GetSize());
34}
35
36// static void readEvent(const std::string &data)
37// {
38// auto readEvent = GetEvent(data.c_str());
39// std::cout << readEvent->summary()->c_str() << std::endl;
40// }
41
42class StorageBenchmark : public QObject
43{
44 Q_OBJECT
45private:
46 //This should point to a directory on disk and not a ramdisk (since we're measuring performance)
47 QString testDataPath;
48 QString dbName;
49 QString filePath;
50 const int count = 50000;
51
52private Q_SLOTS:
53 void initTestCase()
54 {
55 testDataPath = "./testdb";
56 dbName = "test";
57 filePath = testDataPath + "buffer.fb";
58 }
59
60 void cleanupTestCase()
61 {
62 Storage store(testDataPath, dbName);
63 store.removeFromDisk();
64 }
65
66 void testWriteRead_data()
67 {
68 QTest::addColumn<bool>("useDb");
69 QTest::addColumn<int>("count");
70
71 QTest::newRow("db, 50k") << true << count;
72 QTest::newRow("file, 50k") << false << count;
73 }
74
75 void testWriteRead()
76 {
77 QFETCH(bool, useDb);
78 QFETCH(int, count);
79
80 Storage *store = 0;
81 if (useDb) {
82 store = new Storage(testDataPath, dbName);
83 }
84
85 std::ofstream myfile;
86 myfile.open(filePath.toStdString());
87 const char *keyPrefix = "key";
88
89 QTime time;
90
91 time.start();
92 {
93 auto event = createEvent();
94 for (int i = 0; i < count; i++) {
95 if (store) {
96 if (i % 10000 == 0) {
97 if (i > 0) {
98 store->commitTransaction();
99 }
100 store->startTransaction();
101 }
102
103 store->write(keyPrefix + std::to_string(i), event);
104 } else {
105 myfile << event;
106 }
107 }
108
109 if (store) {
110 store->commitTransaction();
111 } else {
112 myfile.close();
113 }
114 }
115 const int writeDuration = time.restart();
116 qDebug() << "Writing took[ms]: " << writeDuration;
117
118 {
119 for (int i = 0; i < count; i++) {
120 if (store) {
121 store->read(keyPrefix + std::to_string(i), [](std::string value){});
122 }
123 }
124 }
125 const int readDuration = time.restart();
126
127 if (store) {
128 qDebug() << "Reading took[ms]: " << readDuration;
129 } else {
130 qDebug() << "File reading is not implemented.";
131 }
132
133 delete store;
134 }
135
136 void testBufferCreation()
137 {
138 QTime time;
139
140 time.start();
141 {
142 for (int i = 0; i < count; i++) {
143 auto event = createEvent();
144 }
145 }
146 const int bufferDuration = time.elapsed();
147 qDebug() << "Creating buffers took[ms]: " << bufferDuration;
148 }
149
150 void testSizes()
151 {
152 Storage store(testDataPath, dbName);
153 qDebug() << "Database size [kb]: " << store.diskUsage()/1024;
154
155 QFileInfo fileInfo(filePath);
156 qDebug() << "File size [kb]: " << fileInfo.size()/1024;
157 }
158};
159
160QTEST_MAIN(StorageBenchmark)
161#include "storagebenchmark.moc"
diff --git a/tests/storagetest.cpp b/tests/storagetest.cpp
new file mode 100644
index 0000000..2b2805d
--- /dev/null
+++ b/tests/storagetest.cpp
@@ -0,0 +1,112 @@
1#include <QtTest>
2
3#include <iostream>
4
5#include <QDebug>
6#include <QString>
7#include <QtConcurrent/QtConcurrentRun>
8
9#include "common/storage.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 Storage storage(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 storage.commitTransaction();
28 }
29 storage.startTransaction();
30 }
31 storage.write(keyPrefix + std::to_string(i), keyPrefix + std::to_string(i));
32 }
33 storage.commitTransaction();
34 }
35
36 bool verify(Storage &storage, int i)
37 {
38 bool success = true;
39 bool keyMatch = true;
40 const auto reference = keyPrefix + std::to_string(i);
41 success = storage.read(keyPrefix + std::to_string(i), [&error, &reference](const std::string &value) {
42 if (value != reference) {
43 qDebug() << "Mismatch while reading";
44 keyMatch = false;
45 }
46 });
47 return succes && keyMatch;
48 }
49
50private Q_SLOTS:
51 void initTestCase()
52 {
53 testDataPath = "./testdb";
54 dbName = "test";
55 }
56
57 void cleanupTestCase()
58 {
59 Database db(testDataPath, dbName);
60 db.removeFromDisk();
61 }
62
63
64 void testRead()
65 {
66 const int count = 100;
67
68 populate(count);
69
70 //ensure we can read everything back correctly
71 {
72 Database db(testDataPath, dbName);
73 for (int i = 0; i < count; i++) {
74 QVERIFY(verify(db, i));
75 }
76 }
77
78 Database db(testDataPath, dbName);
79 db.removeFromDisk();
80 }
81
82 void testConcurrentRead()
83 {
84 const int count = 10000;
85
86 populate(count);
87
88 //Try to concurrently read
89 QList<QFuture<void> > futures;
90 const int concurrencyLevel = 4;
91 for (int num = 0; num < concurrencyLevel; num++) {
92 futures << QtConcurrent::run([this, count](){
93 Database db(testDataPath, dbName);
94 for (int i = 0; i < count; i++) {
95 if (!verify(db, i)) {
96 qWarning() << "invalid value";
97 break;
98 }
99 }
100 });
101 }
102 for(auto future : futures) {
103 future.waitForFinished();
104 }
105
106 Database db(testDataPath, dbName);
107 db.removeFromDisk();
108 }
109};
110
111QTEST_MAIN(StorageTest)
112#include "storagetest.moc"