summaryrefslogtreecommitdiffstats
path: root/tests/storagetest.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tests/storagetest.cpp')
-rw-r--r--tests/storagetest.cpp259
1 files changed, 129 insertions, 130 deletions
diff --git a/tests/storagetest.cpp b/tests/storagetest.cpp
index ebd9b8f..31809ce 100644
--- a/tests/storagetest.cpp
+++ b/tests/storagetest.cpp
@@ -24,7 +24,7 @@ private:
24 Sink::Storage storage(testDataPath, dbName, Sink::Storage::ReadWrite); 24 Sink::Storage storage(testDataPath, dbName, Sink::Storage::ReadWrite);
25 auto transaction = storage.createTransaction(Sink::Storage::ReadWrite); 25 auto transaction = storage.createTransaction(Sink::Storage::ReadWrite);
26 for (int i = 0; i < count; i++) { 26 for (int i = 0; i < count; i++) {
27 //This should perhaps become an implementation detail of the db? 27 // This should perhaps become an implementation detail of the db?
28 if (i % 10000 == 0) { 28 if (i % 10000 == 0) {
29 if (i > 0) { 29 if (i > 0) {
30 transaction.commit(); 30 transaction.commit();
@@ -41,19 +41,20 @@ private:
41 bool success = true; 41 bool success = true;
42 bool keyMatch = true; 42 bool keyMatch = true;
43 const auto reference = keyPrefix + QByteArray::number(i); 43 const auto reference = keyPrefix + QByteArray::number(i);
44 storage.createTransaction(Sink::Storage::ReadOnly).openDatabase().scan(keyPrefix + QByteArray::number(i), 44 storage.createTransaction(Sink::Storage::ReadOnly)
45 [&keyMatch, &reference](const QByteArray &key, const QByteArray &value) -> bool { 45 .openDatabase()
46 if (value != reference) { 46 .scan(keyPrefix + QByteArray::number(i),
47 qDebug() << "Mismatch while reading"; 47 [&keyMatch, &reference](const QByteArray &key, const QByteArray &value) -> bool {
48 keyMatch = false; 48 if (value != reference) {
49 } 49 qDebug() << "Mismatch while reading";
50 return keyMatch; 50 keyMatch = false;
51 }, 51 }
52 [&success](const Sink::Storage::Error &error) { 52 return keyMatch;
53 qDebug() << error.message; 53 },
54 success = false; 54 [&success](const Sink::Storage::Error &error) {
55 } 55 qDebug() << error.message;
56 ); 56 success = false;
57 });
57 return success && keyMatch; 58 return success && keyMatch;
58 } 59 }
59 60
@@ -87,7 +88,7 @@ private slots:
87 88
88 populate(count); 89 populate(count);
89 90
90 //ensure we can read everything back correctly 91 // ensure we can read everything back correctly
91 { 92 {
92 Sink::Storage storage(testDataPath, dbName); 93 Sink::Storage storage(testDataPath, dbName);
93 for (int i = 0; i < count; i++) { 94 for (int i = 0; i < count; i++) {
@@ -101,31 +102,35 @@ private slots:
101 const int count = 100; 102 const int count = 100;
102 populate(count); 103 populate(count);
103 104
104 //ensure we can scan for values 105 // ensure we can scan for values
105 { 106 {
106 int hit = 0; 107 int hit = 0;
107 Sink::Storage store(testDataPath, dbName); 108 Sink::Storage store(testDataPath, dbName);
108 store.createTransaction(Sink::Storage::ReadOnly).openDatabase().scan("", [&](const QByteArray &key, const QByteArray &value) -> bool { 109 store.createTransaction(Sink::Storage::ReadOnly)
109 if (key == "key50") { 110 .openDatabase()
110 hit++; 111 .scan("", [&](const QByteArray &key, const QByteArray &value) -> bool {
111 } 112 if (key == "key50") {
112 return true; 113 hit++;
113 }); 114 }
115 return true;
116 });
114 QCOMPARE(hit, 1); 117 QCOMPARE(hit, 1);
115 } 118 }
116 119
117 //ensure we can read a single value 120 // ensure we can read a single value
118 { 121 {
119 int hit = 0; 122 int hit = 0;
120 bool foundInvalidValue = false; 123 bool foundInvalidValue = false;
121 Sink::Storage store(testDataPath, dbName); 124 Sink::Storage store(testDataPath, dbName);
122 store.createTransaction(Sink::Storage::ReadOnly).openDatabase().scan("key50", [&](const QByteArray &key, const QByteArray &value) -> bool { 125 store.createTransaction(Sink::Storage::ReadOnly)
123 if (key != "key50") { 126 .openDatabase()
124 foundInvalidValue = true; 127 .scan("key50", [&](const QByteArray &key, const QByteArray &value) -> bool {
125 } 128 if (key != "key50") {
126 hit++; 129 foundInvalidValue = true;
127 return true; 130 }
128 }); 131 hit++;
132 return true;
133 });
129 QVERIFY(!foundInvalidValue); 134 QVERIFY(!foundInvalidValue);
130 QCOMPARE(hit, 1); 135 QCOMPARE(hit, 1);
131 } 136 }
@@ -137,9 +142,7 @@ private slots:
137 Sink::Storage store(testDataPath, dbName, Sink::Storage::ReadWrite); 142 Sink::Storage store(testDataPath, dbName, Sink::Storage::ReadWrite);
138 auto transaction = store.createTransaction(Sink::Storage::ReadWrite); 143 auto transaction = store.createTransaction(Sink::Storage::ReadWrite);
139 transaction.openDatabase().scan("key1", [&](const QByteArray &key, const QByteArray &value) -> bool { 144 transaction.openDatabase().scan("key1", [&](const QByteArray &key, const QByteArray &value) -> bool {
140 transaction.openDatabase().remove(key, [](const Sink::Storage::Error &) { 145 transaction.openDatabase().remove(key, [](const Sink::Storage::Error &) { QVERIFY(false); });
141 QVERIFY(false);
142 });
143 return false; 146 return false;
144 }); 147 });
145 } 148 }
@@ -148,12 +151,12 @@ private slots:
148 { 151 {
149 populate(3); 152 populate(3);
150 Sink::Storage store(testDataPath, dbName, Sink::Storage::ReadWrite); 153 Sink::Storage store(testDataPath, dbName, Sink::Storage::ReadWrite);
151 store.createTransaction(Sink::Storage::ReadOnly).openDatabase().scan("key1", [&](const QByteArray &key, const QByteArray &value) -> bool { 154 store.createTransaction(Sink::Storage::ReadOnly)
152 store.createTransaction(Sink::Storage::ReadWrite).openDatabase().remove(key, [](const Sink::Storage::Error &) { 155 .openDatabase()
153 QVERIFY(false); 156 .scan("key1", [&](const QByteArray &key, const QByteArray &value) -> bool {
157 store.createTransaction(Sink::Storage::ReadWrite).openDatabase().remove(key, [](const Sink::Storage::Error &) { QVERIFY(false); });
158 return false;
154 }); 159 });
155 return false;
156 });
157 } 160 }
158 161
159 void testReadEmptyDb() 162 void testReadEmptyDb()
@@ -166,14 +169,15 @@ private slots:
166 qDebug() << error.message; 169 qDebug() << error.message;
167 gotError = true; 170 gotError = true;
168 }); 171 });
169 int numValues = db.scan("", [&](const QByteArray &key, const QByteArray &value) -> bool { 172 int numValues = db.scan("",
170 gotResult = true; 173 [&](const QByteArray &key, const QByteArray &value) -> bool {
171 return false; 174 gotResult = true;
172 }, 175 return false;
173 [&](const Sink::Storage::Error &error) { 176 },
174 qDebug() << error.message; 177 [&](const Sink::Storage::Error &error) {
175 gotError = true; 178 qDebug() << error.message;
176 }); 179 gotError = true;
180 });
177 QCOMPARE(numValues, 0); 181 QCOMPARE(numValues, 0);
178 QVERIFY(!gotResult); 182 QVERIFY(!gotResult);
179 QVERIFY(!gotError); 183 QVERIFY(!gotError);
@@ -181,20 +185,20 @@ private slots:
181 185
182 void testConcurrentRead() 186 void testConcurrentRead()
183 { 187 {
184 //With a count of 10000 this test is more likely to expose problems, but also takes some time to execute. 188 // With a count of 10000 this test is more likely to expose problems, but also takes some time to execute.
185 const int count = 1000; 189 const int count = 1000;
186 190
187 populate(count); 191 populate(count);
188 // QTest::qWait(500); 192 // QTest::qWait(500);
189 193
190 //We repeat the test a bunch of times since failing is relatively random 194 // We repeat the test a bunch of times since failing is relatively random
191 for (int tries = 0; tries < 10; tries++) { 195 for (int tries = 0; tries < 10; tries++) {
192 bool error = false; 196 bool error = false;
193 //Try to concurrently read 197 // Try to concurrently read
194 QList<QFuture<void> > futures; 198 QList<QFuture<void>> futures;
195 const int concurrencyLevel = 20; 199 const int concurrencyLevel = 20;
196 for (int num = 0; num < concurrencyLevel; num++) { 200 for (int num = 0; num < concurrencyLevel; num++) {
197 futures << QtConcurrent::run([this, count, &error](){ 201 futures << QtConcurrent::run([this, count, &error]() {
198 Sink::Storage storage(testDataPath, dbName, Sink::Storage::ReadOnly); 202 Sink::Storage storage(testDataPath, dbName, Sink::Storage::ReadOnly);
199 Sink::Storage storage2(testDataPath, dbName + "2", Sink::Storage::ReadOnly); 203 Sink::Storage storage2(testDataPath, dbName + "2", Sink::Storage::ReadOnly);
200 for (int i = 0; i < count; i++) { 204 for (int i = 0; i < count; i++) {
@@ -205,7 +209,7 @@ private slots:
205 } 209 }
206 }); 210 });
207 } 211 }
208 for(auto future : futures) { 212 for (auto future : futures) {
209 future.waitForFinished(); 213 future.waitForFinished();
210 } 214 }
211 QVERIFY(!error); 215 QVERIFY(!error);
@@ -226,17 +230,18 @@ private slots:
226 Sink::Storage store(testDataPath, dbName, Sink::Storage::ReadWrite); 230 Sink::Storage store(testDataPath, dbName, Sink::Storage::ReadWrite);
227 auto transaction = store.createTransaction(Sink::Storage::ReadWrite); 231 auto transaction = store.createTransaction(Sink::Storage::ReadWrite);
228 auto db = transaction.openDatabase("default", nullptr, false); 232 auto db = transaction.openDatabase("default", nullptr, false);
229 db.write("key","value"); 233 db.write("key", "value");
230 db.write("key","value"); 234 db.write("key", "value");
231 235
232 int numValues = db.scan("", [&](const QByteArray &key, const QByteArray &value) -> bool { 236 int numValues = db.scan("",
233 gotResult = true; 237 [&](const QByteArray &key, const QByteArray &value) -> bool {
234 return true; 238 gotResult = true;
235 }, 239 return true;
236 [&](const Sink::Storage::Error &error) { 240 },
237 qDebug() << error.message; 241 [&](const Sink::Storage::Error &error) {
238 gotError = true; 242 qDebug() << error.message;
239 }); 243 gotError = true;
244 });
240 245
241 QCOMPARE(numValues, 1); 246 QCOMPARE(numValues, 1);
242 QVERIFY(!gotError); 247 QVERIFY(!gotError);
@@ -249,16 +254,17 @@ private slots:
249 Sink::Storage store(testDataPath, dbName, Sink::Storage::ReadWrite); 254 Sink::Storage store(testDataPath, dbName, Sink::Storage::ReadWrite);
250 auto transaction = store.createTransaction(Sink::Storage::ReadWrite); 255 auto transaction = store.createTransaction(Sink::Storage::ReadWrite);
251 auto db = transaction.openDatabase("default", nullptr, true); 256 auto db = transaction.openDatabase("default", nullptr, true);
252 db.write("key","value1"); 257 db.write("key", "value1");
253 db.write("key","value2"); 258 db.write("key", "value2");
254 int numValues = db.scan("key", [&](const QByteArray &key, const QByteArray &value) -> bool { 259 int numValues = db.scan("key",
255 gotResult = true; 260 [&](const QByteArray &key, const QByteArray &value) -> bool {
256 return true; 261 gotResult = true;
257 }, 262 return true;
258 [&](const Sink::Storage::Error &error) { 263 },
259 qDebug() << error.message; 264 [&](const Sink::Storage::Error &error) {
260 gotError = true; 265 qDebug() << error.message;
261 }); 266 gotError = true;
267 });
262 268
263 QCOMPARE(numValues, 2); 269 QCOMPARE(numValues, 2);
264 QVERIFY(!gotError); 270 QVERIFY(!gotError);
@@ -269,14 +275,17 @@ private slots:
269 bool gotResult = false; 275 bool gotResult = false;
270 bool gotError = false; 276 bool gotError = false;
271 Sink::Storage store(testDataPath, dbName, Sink::Storage::ReadOnly); 277 Sink::Storage store(testDataPath, dbName, Sink::Storage::ReadOnly);
272 int numValues = store.createTransaction(Sink::Storage::ReadOnly).openDatabase("test").scan("", [&](const QByteArray &key, const QByteArray &value) -> bool { 278 int numValues = store.createTransaction(Sink::Storage::ReadOnly)
273 gotResult = true; 279 .openDatabase("test")
274 return false; 280 .scan("",
275 }, 281 [&](const QByteArray &key, const QByteArray &value) -> bool {
276 [&](const Sink::Storage::Error &error) { 282 gotResult = true;
277 qDebug() << error.message; 283 return false;
278 gotError = true; 284 },
279 }); 285 [&](const Sink::Storage::Error &error) {
286 qDebug() << error.message;
287 gotError = true;
288 });
280 QCOMPARE(numValues, 0); 289 QCOMPARE(numValues, 0);
281 QVERIFY(!gotResult); 290 QVERIFY(!gotResult);
282 QVERIFY(!gotError); 291 QVERIFY(!gotError);
@@ -286,10 +295,12 @@ private slots:
286 { 295 {
287 bool gotError = false; 296 bool gotError = false;
288 Sink::Storage store(testDataPath, dbName, Sink::Storage::ReadWrite); 297 Sink::Storage store(testDataPath, dbName, Sink::Storage::ReadWrite);
289 store.createTransaction(Sink::Storage::ReadWrite).openDatabase("test").write("key1", "value1", [&](const Sink::Storage::Error &error) { 298 store.createTransaction(Sink::Storage::ReadWrite)
290 qDebug() << error.message; 299 .openDatabase("test")
291 gotError = true; 300 .write("key1", "value1", [&](const Sink::Storage::Error &error) {
292 }); 301 qDebug() << error.message;
302 gotError = true;
303 });
293 QVERIFY(!gotError); 304 QVERIFY(!gotError);
294 } 305 }
295 306
@@ -297,24 +308,24 @@ private slots:
297 { 308 {
298 bool gotError = false; 309 bool gotError = false;
299 Sink::Storage store(testDataPath, dbName, Sink::Storage::ReadWrite); 310 Sink::Storage store(testDataPath, dbName, Sink::Storage::ReadWrite);
300 store.createTransaction(Sink::Storage::ReadWrite).openDatabase("test", nullptr, true).write("key1", "value1", [&](const Sink::Storage::Error &error) { 311 store.createTransaction(Sink::Storage::ReadWrite)
301 qDebug() << error.message; 312 .openDatabase("test", nullptr, true)
302 gotError = true; 313 .write("key1", "value1", [&](const Sink::Storage::Error &error) {
303 }); 314 qDebug() << error.message;
315 gotError = true;
316 });
304 QVERIFY(!gotError); 317 QVERIFY(!gotError);
305 } 318 }
306 319
307 //By default we want only exact matches 320 // By default we want only exact matches
308 void testSubstringKeys() 321 void testSubstringKeys()
309 { 322 {
310 Sink::Storage store(testDataPath, dbName, Sink::Storage::ReadWrite); 323 Sink::Storage store(testDataPath, dbName, Sink::Storage::ReadWrite);
311 auto transaction = store.createTransaction(Sink::Storage::ReadWrite); 324 auto transaction = store.createTransaction(Sink::Storage::ReadWrite);
312 auto db = transaction.openDatabase("test", nullptr, true); 325 auto db = transaction.openDatabase("test", nullptr, true);
313 db.write("sub","value1"); 326 db.write("sub", "value1");
314 db.write("subsub","value2"); 327 db.write("subsub", "value2");
315 int numValues = db.scan("sub", [&](const QByteArray &key, const QByteArray &value) -> bool { 328 int numValues = db.scan("sub", [&](const QByteArray &key, const QByteArray &value) -> bool { return true; });
316 return true;
317 });
318 329
319 QCOMPARE(numValues, 1); 330 QCOMPARE(numValues, 1);
320 } 331 }
@@ -324,12 +335,10 @@ private slots:
324 Sink::Storage store(testDataPath, dbName, Sink::Storage::ReadWrite); 335 Sink::Storage store(testDataPath, dbName, Sink::Storage::ReadWrite);
325 auto transaction = store.createTransaction(Sink::Storage::ReadWrite); 336 auto transaction = store.createTransaction(Sink::Storage::ReadWrite);
326 auto db = transaction.openDatabase("test", nullptr, false); 337 auto db = transaction.openDatabase("test", nullptr, false);
327 db.write("sub","value1"); 338 db.write("sub", "value1");
328 db.write("subsub","value2"); 339 db.write("subsub", "value2");
329 db.write("wubsub","value3"); 340 db.write("wubsub", "value3");
330 int numValues = db.scan("sub", [&](const QByteArray &key, const QByteArray &value) -> bool { 341 int numValues = db.scan("sub", [&](const QByteArray &key, const QByteArray &value) -> bool { return true; }, nullptr, true);
331 return true;
332 }, nullptr, true);
333 342
334 QCOMPARE(numValues, 2); 343 QCOMPARE(numValues, 2);
335 } 344 }
@@ -339,12 +348,10 @@ private slots:
339 Sink::Storage store(testDataPath, dbName, Sink::Storage::ReadWrite); 348 Sink::Storage store(testDataPath, dbName, Sink::Storage::ReadWrite);
340 auto transaction = store.createTransaction(Sink::Storage::ReadWrite); 349 auto transaction = store.createTransaction(Sink::Storage::ReadWrite);
341 auto db = transaction.openDatabase("test", nullptr, true); 350 auto db = transaction.openDatabase("test", nullptr, true);
342 db.write("sub","value1"); 351 db.write("sub", "value1");
343 db.write("subsub","value2"); 352 db.write("subsub", "value2");
344 db.write("wubsub","value3"); 353 db.write("wubsub", "value3");
345 int numValues = db.scan("sub", [&](const QByteArray &key, const QByteArray &value) -> bool { 354 int numValues = db.scan("sub", [&](const QByteArray &key, const QByteArray &value) -> bool { return true; }, nullptr, true);
346 return true;
347 }, nullptr, true);
348 355
349 QCOMPARE(numValues, 2); 356 QCOMPARE(numValues, 2);
350 } 357 }
@@ -354,9 +361,9 @@ private slots:
354 Sink::Storage store(testDataPath, dbName, Sink::Storage::ReadWrite); 361 Sink::Storage store(testDataPath, dbName, Sink::Storage::ReadWrite);
355 auto transaction = store.createTransaction(Sink::Storage::ReadWrite); 362 auto transaction = store.createTransaction(Sink::Storage::ReadWrite);
356 auto db = transaction.openDatabase("test", nullptr, false); 363 auto db = transaction.openDatabase("test", nullptr, false);
357 db.write("sub_2","value2"); 364 db.write("sub_2", "value2");
358 db.write("sub_1","value1"); 365 db.write("sub_1", "value1");
359 db.write("sub_3","value3"); 366 db.write("sub_3", "value3");
360 QList<QByteArray> results; 367 QList<QByteArray> results;
361 int numValues = db.scan("sub", [&](const QByteArray &key, const QByteArray &value) -> bool { 368 int numValues = db.scan("sub", [&](const QByteArray &key, const QByteArray &value) -> bool {
362 results << value; 369 results << value;
@@ -369,16 +376,14 @@ private slots:
369 QCOMPARE(results.at(2), QByteArray("value3")); 376 QCOMPARE(results.at(2), QByteArray("value3"));
370 } 377 }
371 378
372 //Ensure we don't retrieve a key that is greater than the current key. We only want equal keys. 379 // Ensure we don't retrieve a key that is greater than the current key. We only want equal keys.
373 void testKeyRange() 380 void testKeyRange()
374 { 381 {
375 Sink::Storage store(testDataPath, dbName, Sink::Storage::ReadWrite); 382 Sink::Storage store(testDataPath, dbName, Sink::Storage::ReadWrite);
376 auto transaction = store.createTransaction(Sink::Storage::ReadWrite); 383 auto transaction = store.createTransaction(Sink::Storage::ReadWrite);
377 auto db = transaction.openDatabase("test", nullptr, true); 384 auto db = transaction.openDatabase("test", nullptr, true);
378 db.write("sub1","value1"); 385 db.write("sub1", "value1");
379 int numValues = db.scan("sub", [&](const QByteArray &key, const QByteArray &value) -> bool { 386 int numValues = db.scan("sub", [&](const QByteArray &key, const QByteArray &value) -> bool { return true; });
380 return true;
381 });
382 387
383 QCOMPARE(numValues, 0); 388 QCOMPARE(numValues, 0);
384 } 389 }
@@ -388,14 +393,12 @@ private slots:
388 Sink::Storage store(testDataPath, dbName, Sink::Storage::ReadWrite); 393 Sink::Storage store(testDataPath, dbName, Sink::Storage::ReadWrite);
389 auto transaction = store.createTransaction(Sink::Storage::ReadWrite); 394 auto transaction = store.createTransaction(Sink::Storage::ReadWrite);
390 auto db = transaction.openDatabase("test", nullptr, false); 395 auto db = transaction.openDatabase("test", nullptr, false);
391 db.write("sub1","value1"); 396 db.write("sub1", "value1");
392 db.write("sub2","value2"); 397 db.write("sub2", "value2");
393 db.write("wub3","value3"); 398 db.write("wub3", "value3");
394 db.write("wub4","value4"); 399 db.write("wub4", "value4");
395 QByteArray result; 400 QByteArray result;
396 db.findLatest("sub", [&](const QByteArray &key, const QByteArray &value) { 401 db.findLatest("sub", [&](const QByteArray &key, const QByteArray &value) { result = value; });
397 result = value;
398 });
399 402
400 QCOMPARE(result, QByteArray("value2")); 403 QCOMPARE(result, QByteArray("value2"));
401 } 404 }
@@ -405,11 +408,9 @@ private slots:
405 Sink::Storage store(testDataPath, dbName, Sink::Storage::ReadWrite); 408 Sink::Storage store(testDataPath, dbName, Sink::Storage::ReadWrite);
406 auto transaction = store.createTransaction(Sink::Storage::ReadWrite); 409 auto transaction = store.createTransaction(Sink::Storage::ReadWrite);
407 auto db = transaction.openDatabase("test", nullptr, false); 410 auto db = transaction.openDatabase("test", nullptr, false);
408 db.write("sub2","value2"); 411 db.write("sub2", "value2");
409 QByteArray result; 412 QByteArray result;
410 db.findLatest("sub", [&](const QByteArray &key, const QByteArray &value) { 413 db.findLatest("sub", [&](const QByteArray &key, const QByteArray &value) { result = value; });
411 result = value;
412 });
413 414
414 QCOMPARE(result, QByteArray("value2")); 415 QCOMPARE(result, QByteArray("value2"));
415 } 416 }
@@ -419,12 +420,10 @@ private slots:
419 Sink::Storage store(testDataPath, dbName, Sink::Storage::ReadWrite); 420 Sink::Storage store(testDataPath, dbName, Sink::Storage::ReadWrite);
420 auto transaction = store.createTransaction(Sink::Storage::ReadWrite); 421 auto transaction = store.createTransaction(Sink::Storage::ReadWrite);
421 auto db = transaction.openDatabase("test", nullptr, false); 422 auto db = transaction.openDatabase("test", nullptr, false);
422 db.write("sub2","value2"); 423 db.write("sub2", "value2");
423 db.write("wub3","value3"); 424 db.write("wub3", "value3");
424 QByteArray result; 425 QByteArray result;
425 db.findLatest("wub", [&](const QByteArray &key, const QByteArray &value) { 426 db.findLatest("wub", [&](const QByteArray &key, const QByteArray &value) { result = value; });
426 result = value;
427 });
428 427
429 QCOMPARE(result, QByteArray("value3")); 428 QCOMPARE(result, QByteArray("value3"));
430 } 429 }