- added unit-tests for linked transactions
@@ -307,5 +307,128 @@ | ||
307 | 307 | } |
308 | 308 | printf( "ok.\n" ); |
309 | 309 | |
310 | + printf( "testing ArrayDatabase linking transactions and writing..." ); | |
311 | + { | |
312 | + filePtr memFile = fileSys->CreateMemoryFile(); | |
313 | + | |
314 | + ArrayDatabase::db_construction_params cparams; | |
315 | + cparams.item_block_size = 512; | |
316 | + cparams.journal_size = 200; | |
317 | + cparams.user_ident = 0x74926487; | |
318 | + | |
319 | + ArrayDatabase::CreateDatabase( memFile, cparams ); | |
320 | + | |
321 | + ArrayDatabase db( execMan, std::move( memFile ) ); | |
322 | + | |
323 | + std::uint32_t tid1 = db.BeginTransaction( 0 ); | |
324 | + std::uint32_t tid2 = db.BeginTransaction( 1 ); | |
325 | + | |
326 | + db.LinkTransactions( tid1, tid2 ); | |
327 | + | |
328 | + db.WriteStruct <std::uint32_t> ( tid1, 0, 42 ); | |
329 | + db.WriteStruct <std::uint32_t> ( tid2, 0, 21 ); | |
330 | + | |
331 | + db.EndTransaction( tid1 ); | |
332 | + db.EndTransaction( tid2 ); | |
333 | + } | |
334 | + printf( "ok.\n" ); | |
335 | + | |
336 | + printf( "testing ArrayDatabase aborting linked transactions..." ); | |
337 | + { | |
338 | + filePtr memFile = fileSys->CreateMemoryFile(); | |
339 | + | |
340 | + ArrayDatabase::db_construction_params cparams; | |
341 | + cparams.item_block_size = 512; | |
342 | + cparams.journal_size = 200; | |
343 | + cparams.user_ident = 0x74926487; | |
344 | + | |
345 | + ArrayDatabase::CreateDatabase( memFile, cparams ); | |
346 | + | |
347 | + ArrayDatabase db( execMan, std::move( memFile ) ); | |
348 | + | |
349 | + std::uint32_t tid1 = db.BeginTransaction( 0 ); | |
350 | + | |
351 | + db.WriteStruct <std::uint32_t> ( tid1, 0, 100 ); | |
352 | + | |
353 | + std::uint32_t tid2 = db.BeginTransaction( 1 ); | |
354 | + | |
355 | + db.LinkTransactions( tid1, tid2 ); | |
356 | + | |
357 | + db.EndTransaction( tid1 ); | |
358 | + | |
359 | + db.WriteStruct <std::uint32_t> ( tid2, 0, 230 ); | |
360 | + | |
361 | + db.AbortTransaction( tid2 ); | |
362 | + | |
363 | + assert( db.ReadStruct_EX <std::uint32_t> ( 0, 0 ) == 0 ); | |
364 | + assert( db.ReadStruct_EX <std::uint32_t> ( 1, 0 ) == 0 ); | |
365 | + } | |
366 | + printf( "ok.\n" ); | |
367 | + | |
368 | + printf( "testing ArrayDatabase parsing journal with linked transactions..." ); | |
369 | + { | |
370 | + filePtr memFile = fileSys->CreateMemoryFile(); | |
371 | + | |
372 | + ArrayDatabase::db_construction_params cparams; | |
373 | + cparams.item_block_size = 512; | |
374 | + cparams.journal_size = 200; | |
375 | + cparams.user_ident = 0x74926487; | |
376 | + | |
377 | + ArrayDatabase::CreateDatabase( memFile, cparams ); | |
378 | + | |
379 | + // First create a recovery-required scenario. | |
380 | + { | |
381 | + ArrayDatabase write_db( execMan, filePtr( memFile, false ) ); | |
382 | + | |
383 | + std::uint32_t tid1 = write_db.BeginTransaction( 0 ); | |
384 | + std::uint32_t tid2 = write_db.BeginTransaction( 1 ); | |
385 | + | |
386 | + write_db.LinkTransactions( tid1, tid2 ); | |
387 | + write_db.WriteStruct <std::uint32_t> ( tid1, 0, 11 ); | |
388 | + write_db.WriteStruct <std::uint32_t> ( tid2, 0, 22 ); | |
389 | + | |
390 | + write_db.EndTransaction( tid1 ); | |
391 | + | |
392 | + // Boom. tid2 is not closed thus the database is in an invalid state. | |
393 | + } | |
394 | + | |
395 | + // Parse it with recovery. | |
396 | + { | |
397 | + ArrayDatabase read_db( execMan, std::move( memFile ) ); | |
398 | + | |
399 | + assert( read_db.ReadStruct_EX <std::uint32_t> ( 0, 0 ) == 0 ); | |
400 | + assert( read_db.ReadStruct_EX <std::uint32_t> ( 1, 0 ) == 0 ); | |
401 | + } | |
402 | + } | |
403 | + printf( "ok.\n" ); | |
404 | + | |
405 | + printf( "testing ArrayDatabase linked-transactions no reuse ID if previously linked..." ); | |
406 | + { | |
407 | + filePtr memFile = fileSys->CreateMemoryFile(); | |
408 | + | |
409 | + ArrayDatabase::db_construction_params cparams; | |
410 | + cparams.item_block_size = 512; | |
411 | + cparams.journal_size = 200; | |
412 | + cparams.user_ident = 0x74926487; | |
413 | + | |
414 | + ArrayDatabase::CreateDatabase( memFile, cparams ); | |
415 | + | |
416 | + ArrayDatabase db( execMan, std::move( memFile ) ); | |
417 | + | |
418 | + std::uint32_t tid1 = db.BeginTransaction( 0 ); | |
419 | + std::uint32_t tid2 = db.BeginTransaction( 1 ); | |
420 | + | |
421 | + db.LinkTransactions( tid1, tid2 ); | |
422 | + db.EndTransaction( tid2 ); | |
423 | + | |
424 | + std::uint32_t tid3 = db.BeginTransaction( 1 ); | |
425 | + | |
426 | + assert( tid2 != tid3 ); | |
427 | + | |
428 | + // While the re-usage of IDs is valid in the serialized format it is totally invalid in this API | |
429 | + // because BeginTransaction explicitly states that the returned ID was free in any way. | |
430 | + } | |
431 | + printf( "ok.\n" ); | |
432 | + | |
310 | 433 | // TODO: more tests. |
311 | 434 | } |
\ No newline at end of file |