-
Notifications
You must be signed in to change notification settings - Fork 21
Testing
STO has a testing framework that let users test their datatype implementations before putting them under the stree of actual concurrent transactions. The test framework let users manually create interesting interleaving situations to test the correctness of transactional datatypes.
The test framework consists of two main classes: TransactionGuard and TestTransaction. Both of them are defined in sto-core/Transaction.hh.
TransactionGuard is a lock-guard-like object that helps you start a transaction automatically, and try to commit the transaction once it's out-of-scope. If the commit is unsuccessful, a Transaction::Abort exception will be thrown.
{
TransactionGuard t;
// transactional code here
}TestTransaction simulates concurrent transactions on a single thread, and gives programmer some level of control to the interleaving of the transactions.
Once a TestTransaction object is created, the thread switches to executing the newly created (test) transaction. The TestTransaction::use() method let you switch to another transaction during the test, simulating transaction interleaving. At the end of the test, TestTransaction::try_commit() should be called to test/verify whether the test transaction can commit.
If exceptions are thrown, which may be necessary in tests where opacity is being tested, the test may end without try_commit() being called. In this case, the exception should be caught and the TestTransaction::hard_reset() static method should be used to restore the testing framework to a consistent state. This clean-up step is mandatory before executing additional tests using TestTransaction and/or TransactionGuard objects.
try {
TestTransaction t1(1);
// now executing transaction t1
TestTransaction t2(2);
// now switching to transaction t2
t1.use();
// switch back to transaction t1
assert(t1.try_commit()); // verify that t1 can commit
t2.use();
// switch back to t2
// perform some operation that may violate opacity
// and throw an exception
assert(false, "code not reachable");
} catch (Transaction::Abort e) {
TestTransaction::hard_reset(); // clean up
}