#include "mvcc_find_update_common.hpp" #undef T4_FIND #define T4_FIND version_list.find(*t4) #undef T3_FIND #define T3_FIND version_list.find(*t3) // IMPORTANT: look definiton of EXPECT_CRE and EXPECT_EXP macros in // tests/mvcc_find_update_common.hpp. Numbers in those macros represent // transaction ids when transactions where created. // **************************************************************** // * CASE 1: T3 starts after T2 ends. // * // * T2: START---OP---END // * // * T3: START---OP---END // * // * T4: START---FIND---END // **************************************************************** TEST_F(Mvcc, UpdCmtUpdCmt1) { T2_UPDATE; T2_COMMIT; T3_BEGIN; T3_UPDATE; T3_COMMIT; EXPECT_EXP(v1, 2); EXPECT_CRE(v2, 2); EXPECT_EXP(v2, 3); EXPECT_CRE(v3, 3); EXPECT_EXP(v3, 0); EXPECT_NXT(v3, v2); EXPECT_NXT(v2, v1); EXPECT_SIZE(3); T4_BEGIN; EXPECT_EQ(T4_FIND, v3); } TEST_F(Mvcc, UpdCmtRemCmt1) { T2_UPDATE; T2_COMMIT; T3_BEGIN; T3_REMOVE; T3_COMMIT; EXPECT_EXP(v1, 2); EXPECT_CRE(v2, 2); EXPECT_EXP(v2, 3); EXPECT_NXT(v2, v1); EXPECT_SIZE(2); T4_BEGIN; EXPECT_EQ(T4_FIND, nullptr); } TEST_F(Mvcc, RemCmtUpdCmt1) { T2_REMOVE; T2_COMMIT; T3_BEGIN; EXPECT_DEATH(T3_UPDATE, ".*nullptr.*"); } TEST_F(Mvcc, RemCmtRemCmt1) { T2_REMOVE; T2_COMMIT; T3_BEGIN; EXPECT_FALSE(T3_FIND); } TEST_F(Mvcc, UpdCmtUpdAbt1) { T2_UPDATE; T2_COMMIT; T3_BEGIN; T3_UPDATE; T3_ABORT; EXPECT_EXP(v1, 2); EXPECT_CRE(v2, 2); EXPECT_EXP(v2, 3); EXPECT_CRE(v3, 3); EXPECT_EXP(v3, 0); EXPECT_NXT(v2, v1); EXPECT_NXT(v3, v2); EXPECT_SIZE(3); T4_BEGIN; EXPECT_EQ(T4_FIND, v2); } TEST_F(Mvcc, UpdCmtRemAbt1) { T2_UPDATE; T2_COMMIT; T3_BEGIN; T3_REMOVE; T3_ABORT; EXPECT_EXP(v1, 2); EXPECT_CRE(v2, 2); EXPECT_EXP(v2, 3); EXPECT_NXT(v2, v1); EXPECT_SIZE(2); T4_BEGIN; EXPECT_EQ(T4_FIND, v2); } TEST_F(Mvcc, RemCmtUpdAbt1) { T2_REMOVE; T2_COMMIT; T3_BEGIN; EXPECT_DEATH(T3_UPDATE, ".*nullptr.*"); } TEST_F(Mvcc, RemCmtRemAbt1) { T2_REMOVE; T2_COMMIT; T3_BEGIN; EXPECT_FALSE(T3_FIND); } TEST_F(Mvcc, UpdAbtUpdCmt1) { T2_UPDATE; T2_ABORT; T3_BEGIN; T3_UPDATE; T3_COMMIT; EXPECT_EXP(v1, 3); EXPECT_CRE(v2, 2); EXPECT_EXP(v2, 0); EXPECT_CRE(v3, 3); EXPECT_EXP(v3, 0); EXPECT_NXT(v3, v2); EXPECT_NXT(v2, v1); EXPECT_SIZE(3); T4_BEGIN; EXPECT_EQ(T4_FIND, v3); } TEST_F(Mvcc, UpdAbtRemCmt1) { T2_UPDATE; T2_ABORT; T3_BEGIN; T3_REMOVE; T3_COMMIT; EXPECT_NXT(v2, v1); EXPECT_EXP(v1, 3); EXPECT_CRE(v2, 2); EXPECT_EXP(v2, 0); EXPECT_SIZE(2); T4_BEGIN; EXPECT_EQ(T4_FIND, nullptr); } TEST_F(Mvcc, RemAbtUpdCmt1) { T2_REMOVE; T2_ABORT; T3_BEGIN; T3_UPDATE; T3_COMMIT; EXPECT_EXP(v1, 3); EXPECT_CRE(v3, 3); EXPECT_EXP(v3, 0); EXPECT_NXT(v3, v1); EXPECT_SIZE(2); T4_BEGIN; EXPECT_EQ(T4_FIND, v3); } TEST_F(Mvcc, RemAbtRemCmt1) { T2_REMOVE; T2_ABORT; T3_BEGIN; T3_REMOVE; T3_COMMIT; EXPECT_EXP(v1, 3); EXPECT_SIZE(1); T4_BEGIN; EXPECT_EQ(T4_FIND, nullptr); } TEST_F(Mvcc, UpdAbtUpdAbt1) { T2_UPDATE; T2_ABORT; T3_BEGIN; T3_UPDATE; T3_ABORT; EXPECT_EXP(v1, 3); EXPECT_CRE(v2, 2); EXPECT_EXP(v2, 0); EXPECT_CRE(v3, 3); EXPECT_EXP(v3, 0); EXPECT_NXT(v2, v1); EXPECT_NXT(v3, v2); EXPECT_SIZE(3); T4_BEGIN; EXPECT_EQ(T4_FIND, v1); } TEST_F(Mvcc, UpdAbtRemAbt1) { T2_UPDATE; T2_ABORT; T3_BEGIN; T3_REMOVE; T3_ABORT; EXPECT_NXT(v2, v1); EXPECT_EXP(v1, 3); EXPECT_CRE(v2, 2); EXPECT_EXP(v2, 0); EXPECT_SIZE(2); T4_BEGIN; EXPECT_EQ(T4_FIND, v1); } TEST_F(Mvcc, RemAbtUpdAbt1) { T2_REMOVE; T2_ABORT; T3_BEGIN; T3_UPDATE; T3_ABORT; EXPECT_EXP(v1, 3); EXPECT_CRE(v3, 3); EXPECT_EXP(v3, 0); EXPECT_NXT(v3, v1); EXPECT_SIZE(2); T4_BEGIN; EXPECT_EQ(T4_FIND, v1); } TEST_F(Mvcc, RemAbtRemAbt1) { T2_REMOVE; T2_ABORT; T3_BEGIN; T3_REMOVE; T3_ABORT; EXPECT_EXP(v1, 3); EXPECT_SIZE(1); T4_BEGIN; EXPECT_EQ(T4_FIND, v1); } // **************************************************************** // * CASE 2: T3 starts before T2 ends. // * // * T2: START---OP---END // * // * T3: START---------OP---END // * // * T4: START---FIND---END // * // **************************************************************** // **************************** // COVERS 8 cases! TEST_F(Mvcc, UpdCmtUpd2) { T2_UPDATE; T3_BEGIN; T2_COMMIT; EXPECT_THROW(T3_UPDATE, mvcc::SerializationError); } TEST_F(Mvcc, UpdCmtRem2) { T2_UPDATE; T3_BEGIN; T2_COMMIT; EXPECT_THROW(T3_REMOVE, mvcc::SerializationError); } TEST_F(Mvcc, RemCmtUpd2) { T2_REMOVE; T3_BEGIN; T2_COMMIT; EXPECT_THROW(T3_UPDATE, mvcc::SerializationError); } TEST_F(Mvcc, RemCmtRem2) { T2_REMOVE; T3_BEGIN; T2_COMMIT; EXPECT_THROW(T3_REMOVE, mvcc::SerializationError); } // ************************** TEST_F(Mvcc, UpdAbtUpdCmt2) { T2_UPDATE; T3_BEGIN; T2_ABORT; T3_UPDATE; T3_COMMIT; EXPECT_EXP(v1, 3); EXPECT_CRE(v2, 2); EXPECT_EXP(v2, 0); EXPECT_CRE(v3, 3); EXPECT_EXP(v3, 0); EXPECT_NXT(v3, v2); EXPECT_NXT(v2, v1); EXPECT_SIZE(3); T4_BEGIN; EXPECT_EQ(T4_FIND, v3); } TEST_F(Mvcc, UpdAbtRemCmt2) { T2_UPDATE; T3_BEGIN; T2_ABORT; T3_REMOVE; T3_COMMIT; EXPECT_NXT(v2, v1); EXPECT_EXP(v1, 3); EXPECT_CRE(v2, 2); EXPECT_EXP(v2, 0); EXPECT_SIZE(2); T4_BEGIN; EXPECT_EQ(T4_FIND, nullptr); } TEST_F(Mvcc, RemAbtUpdCmt2) { T2_REMOVE; T3_BEGIN; T2_ABORT; T3_UPDATE; T3_COMMIT; EXPECT_EXP(v1, 3); EXPECT_CRE(v3, 3); EXPECT_EXP(v3, 0); EXPECT_NXT(v3, v1); EXPECT_SIZE(2); T4_BEGIN; EXPECT_EQ(T4_FIND, v3); } TEST_F(Mvcc, RemAbtRemCmt2) { T2_REMOVE; T3_BEGIN; T2_ABORT; T3_REMOVE; T3_COMMIT; EXPECT_EXP(v1, 3); EXPECT_SIZE(1); T4_BEGIN; EXPECT_EQ(T4_FIND, nullptr); } TEST_F(Mvcc, UpdAbtUpdAbt2) { T2_UPDATE; T3_BEGIN; T2_ABORT; T3_UPDATE; T3_ABORT; EXPECT_EXP(v1, 3); EXPECT_CRE(v2, 2); EXPECT_EXP(v2, 0); EXPECT_CRE(v3, 3); EXPECT_EXP(v2, 0); EXPECT_NXT(v2, v1); EXPECT_NXT(v3, v2); EXPECT_SIZE(3); T4_BEGIN; EXPECT_EQ(T4_FIND, v1); } TEST_F(Mvcc, UpdAbtRemAbt2) { T2_UPDATE; T3_BEGIN; T2_ABORT; T3_REMOVE; T3_ABORT; EXPECT_NXT(v2, v1); EXPECT_EXP(v1, 3); EXPECT_CRE(v2, 2); EXPECT_EXP(v2, 0); EXPECT_SIZE(2); T4_BEGIN; EXPECT_EQ(T4_FIND, v1); } TEST_F(Mvcc, RemAbtUpdAbt2) { T2_REMOVE; T3_BEGIN; T2_ABORT; T3_UPDATE; T3_ABORT; EXPECT_EXP(v1, 3); EXPECT_CRE(v3, 3); EXPECT_EXP(v3, 0); EXPECT_NXT(v3, v1); EXPECT_SIZE(2); T4_BEGIN; EXPECT_EQ(T4_FIND, v1); } TEST_F(Mvcc, RemAbtRemAbt2) { T2_REMOVE; T3_BEGIN; T2_ABORT; T3_REMOVE; T3_ABORT; EXPECT_EXP(v1, 3); EXPECT_SIZE(1); T4_BEGIN; EXPECT_EQ(T4_FIND, v1); } // **************************************************************** // * CASE 3: T3 ends before T2 starts executing operations. // * // * T2: START--------------------OP---END // * // * T3: START---OP---END // * // * T4: START---FIND---END // * // **************************************************************** // **************************** // COVERS 8 cases! TEST_F(Mvcc, UpdUpdCmt3) { T3_BEGIN; T3_UPDATE; T3_COMMIT; EXPECT_THROW(T2_UPDATE, mvcc::SerializationError); } TEST_F(Mvcc, UpdRemCmt3) { T3_BEGIN; T3_REMOVE; T3_COMMIT; EXPECT_THROW(T2_UPDATE, mvcc::SerializationError); } TEST_F(Mvcc, RemUpdCmt3) { T3_BEGIN; T3_UPDATE; T3_COMMIT; EXPECT_THROW(T2_REMOVE, mvcc::SerializationError); } TEST_F(Mvcc, RemRemCmt3) { T3_BEGIN; T3_REMOVE; T3_COMMIT; EXPECT_THROW(T2_REMOVE, mvcc::SerializationError); } // ************************** TEST_F(Mvcc, UpdCmtUpdAbt3) { T3_BEGIN; T3_UPDATE; T3_ABORT; T2_UPDATE; T2_COMMIT; EXPECT_EXP(v1, 2); EXPECT_CRE(v2, 2); EXPECT_EXP(v2, 0); EXPECT_CRE(v3, 3); EXPECT_EXP(v3, 0); EXPECT_NXT(v3, v1); EXPECT_NXT(v2, v3); EXPECT_SIZE(3); T4_BEGIN; EXPECT_EQ(T4_FIND, v2); } TEST_F(Mvcc, UpdCmtRemAbt3) { T3_BEGIN; T3_REMOVE; T3_ABORT; T2_UPDATE; T2_COMMIT; EXPECT_EXP(v1, 2); EXPECT_CRE(v2, 2); EXPECT_EXP(v2, 0); EXPECT_NXT(v2, v1); EXPECT_SIZE(2); T4_BEGIN; EXPECT_EQ(T4_FIND, v2); } TEST_F(Mvcc, RemCmtUpdAbt3) { T3_BEGIN; T3_UPDATE; T3_ABORT; T2_REMOVE; T2_COMMIT; EXPECT_EXP(v1, 2); EXPECT_CRE(v3, 3); EXPECT_EXP(v3, 0); EXPECT_NXT(v3, v1); EXPECT_SIZE(2); T4_BEGIN; EXPECT_EQ(T4_FIND, nullptr); } TEST_F(Mvcc, RemCmtRemAbt3) { T3_BEGIN; T3_REMOVE; T3_ABORT; T2_REMOVE; T2_COMMIT; EXPECT_EXP(v1, 2); EXPECT_SIZE(1); T4_BEGIN; EXPECT_EQ(T4_FIND, nullptr); } TEST_F(Mvcc, UpdAbtUpdAbt3) { T3_BEGIN; T3_UPDATE; T3_ABORT; T2_UPDATE; T2_ABORT; EXPECT_EXP(v1, 2); EXPECT_CRE(v2, 2); EXPECT_EXP(v2, 0); EXPECT_CRE(v3, 3); EXPECT_EXP(v3, 0); EXPECT_NXT(v3, v1); EXPECT_NXT(v2, v3); EXPECT_SIZE(3); T4_BEGIN; EXPECT_EQ(T4_FIND, v1); } TEST_F(Mvcc, UpdAbtRemAbt3) { T3_BEGIN; T3_REMOVE; T3_ABORT; T2_UPDATE; T2_ABORT; EXPECT_NXT(v2, v1); EXPECT_EXP(v1, 2); EXPECT_CRE(v2, 2); EXPECT_EXP(v2, 0); EXPECT_SIZE(2); T4_BEGIN; EXPECT_EQ(T4_FIND, v1); } TEST_F(Mvcc, RemAbtUpdAbt3) { T3_BEGIN; T3_UPDATE; T3_ABORT; T2_REMOVE; T2_ABORT; EXPECT_EXP(v1, 2); EXPECT_CRE(v3, 3); EXPECT_EXP(v3, 0); EXPECT_NXT(v3, v1); EXPECT_SIZE(2); T4_BEGIN; EXPECT_EQ(T4_FIND, v1); } TEST_F(Mvcc, RemAbtRemAbt3) { T3_BEGIN; T3_REMOVE; T3_ABORT; T2_REMOVE; T2_ABORT; EXPECT_EXP(v1, 2); EXPECT_SIZE(1); T4_BEGIN; EXPECT_EQ(T4_FIND, v1); } int main(int argc, char **argv) { ::testing::InitGoogleTest(&argc, argv); ::testing::FLAGS_gtest_death_test_style = "threadsafe"; return RUN_ALL_TESTS(); }