#include #include "database/single_node/graph_db.hpp" #include "database/single_node/graph_db_accessor.hpp" #include "storage/common/constraints/unique_constraints.hpp" using storage::constraints::ConstraintEntry; using storage::constraints::UniqueConstraints; class UniqueConstraintsTest : public ::testing::Test { protected: void SetUp() override { auto dba = db_.Access(); label_ = dba.Label("label"); property1_ = dba.Property("property1"); property2_ = dba.Property("property2"); property3_ = dba.Property("property3"); dba.BuildUniqueConstraint(label_, {property1_, property2_, property3_}); dba.Commit(); } database::GraphDb db_; storage::Label label_; storage::Property property1_; storage::Property property2_; storage::Property property3_; PropertyValue value1_{"value1"}; PropertyValue value2_{"value2"}; PropertyValue value3_{"value3"}; UniqueConstraints constraints_; }; // NOLINTNEXTLINE(hicpp-special-member-functions) TEST_F(UniqueConstraintsTest, BuildDrop) { auto constraint = ConstraintEntry{label_, {property1_, property2_, property3_}}; constraints_.AddConstraint(constraint); EXPECT_TRUE( constraints_.Exists(label_, {property2_, property1_, property3_})); EXPECT_TRUE( constraints_.Exists(label_, {property1_, property2_, property3_})); EXPECT_FALSE(constraints_.Exists(label_, {property2_, property3_})); constraints_.RemoveConstraint(constraint); EXPECT_FALSE( constraints_.Exists(label_, {property2_, property1_, property3_})); EXPECT_FALSE( constraints_.Exists(label_, {property1_, property2_, property3_})); } // NOLINTNEXTLINE(hicpp-special-member-functions) TEST_F(UniqueConstraintsTest, BuildWithViolation) { auto dba = db_.Access(); dba.DeleteUniqueConstraint(label_, {property1_, property2_, property3_}); dba.Commit(); auto dba1 = db_.Access(); auto v1 = dba1.InsertVertex(); v1.add_label(label_); v1.PropsSet(property1_, value1_); v1.PropsSet(property2_, value2_); v1.PropsSet(property3_, value3_); auto v2 = dba1.InsertVertex(); v2.add_label(label_); v2.PropsSet(property1_, value1_); v2.PropsSet(property3_, value3_); auto v3 = dba1.InsertVertex(); v3.add_label(label_); v3.PropsSet(property3_, value3_); v3.PropsSet(property1_, value1_); v3.PropsSet(property2_, value2_); dba1.Commit(); auto dba2 = db_.Access(); EXPECT_THROW( dba2.BuildUniqueConstraint(label_, {property1_, property2_, property3_}), database::ConstraintViolationException); dba2.Commit(); } // NOLINTNEXTLINE(hicpp-special-member-functions) TEST_F(UniqueConstraintsTest, InsertInsert) { { auto dba = db_.Access(); auto v = dba.InsertVertex(); v.add_label(label_); v.PropsSet(property2_, value2_); v.PropsSet(property1_, value1_); v.PropsSet(property3_, value3_); dba.Commit(); } { auto dba = db_.Access(); auto v = dba.InsertVertex(); v.add_label(label_); v.PropsSet(property3_, value3_); v.PropsSet(property2_, value2_); EXPECT_THROW(v.PropsSet(property1_, value1_), database::ConstraintViolationException); dba.Commit(); } } // NOLINTNEXTLINE(hicpp-special-member-functions) TEST_F(UniqueConstraintsTest, InsertInsertDiffValues) { { auto dba = db_.Access(); auto v = dba.InsertVertex(); v.add_label(label_); v.PropsSet(property2_, value2_); v.PropsSet(property1_, value1_); v.PropsSet(property3_, value3_); dba.Commit(); } { auto dba = db_.Access(); auto v = dba.InsertVertex(); PropertyValue other3("Some other value 3"); v.PropsSet(property3_, other3); v.add_label(label_); PropertyValue other2("Some other value 2"); v.PropsSet(property2_, other2); PropertyValue other1("Some other value 1"); v.PropsSet(property1_, other1); dba.Commit(); } } // NOLINTNEXTLINE(hicpp-special-member-functions) TEST_F(UniqueConstraintsTest, InsertAbortInsert) { { auto dba = db_.Access(); auto v = dba.InsertVertex(); v.PropsSet(property1_, value1_); v.add_label(label_); v.PropsSet(property2_, value2_); v.PropsSet(property3_, value3_); dba.Abort(); } { auto dba = db_.Access(); auto v = dba.InsertVertex(); v.PropsSet(property2_, value2_); v.PropsSet(property1_, value1_); v.PropsSet(property3_, value3_); v.add_label(label_); dba.Commit(); } } // NOLINTNEXTLINE(hicpp-special-member-functions) TEST_F(UniqueConstraintsTest, InsertRemoveAbortInsert) { auto gid = storage::Gid::FromInt(0); { auto dba = db_.Access(); auto v = dba.InsertVertex(); v.PropsSet(property2_, value2_); v.PropsSet(property1_, value1_); v.PropsSet(property3_, value3_); v.add_label(label_); dba.Commit(); } { auto dba = db_.Access(); auto v = dba.FindVertex(gid, false); v.PropsErase(property2_); dba.Abort(); } { auto dba = db_.Access(); auto v = dba.InsertVertex(); v.PropsSet(property1_, value1_); v.add_label(label_); v.PropsSet(property2_, value2_); EXPECT_THROW(v.PropsSet(property3_, value3_), database::ConstraintViolationException); } } // NOLINTNEXTLINE(hicpp-special-member-functions) TEST_F(UniqueConstraintsTest, InsertInsertSameTransaction) { { auto dba = db_.Access(); auto v1 = dba.InsertVertex(); auto v2 = dba.InsertVertex(); v1.add_label(label_); v2.add_label(label_); v1.PropsSet(property1_, value1_); v1.PropsSet(property2_, value2_); v2.PropsSet(property2_, value2_); v2.PropsSet(property3_, value3_); v2.PropsSet(property1_, value1_); EXPECT_THROW(v1.PropsSet(property3_, value3_), database::ConstraintViolationException); dba.Commit(); } } // NOLINTNEXTLINE(hicpp-special-member-functions) TEST_F(UniqueConstraintsTest, InsertInsertReversed) { auto dba1 = db_.Access(); auto dba2 = db_.Access(); auto v1 = dba1.InsertVertex(); auto v2 = dba2.InsertVertex(); v1.add_label(label_); v2.add_label(label_); v1.PropsSet(property1_, value1_); v1.PropsSet(property2_, value2_); v2.PropsSet(property2_, value2_); v2.PropsSet(property3_, value3_); v2.PropsSet(property1_, value1_); EXPECT_THROW(v1.PropsSet(property3_, value3_), mvcc::SerializationError); } // NOLINTNEXTLINE(hicpp-special-member-functions) TEST_F(UniqueConstraintsTest, InsertRemoveInsert) { auto gid = storage::Gid::FromInt(0); { auto dba = db_.Access(); auto v = dba.InsertVertex(); v.PropsSet(property2_, value2_); v.PropsSet(property1_, value1_); v.PropsSet(property3_, value3_); v.add_label(label_); dba.Commit(); } { auto dba = db_.Access(); auto v = dba.FindVertex(gid, false); v.PropsErase(property2_); dba.Commit(); } { auto dba = db_.Access(); auto v = dba.InsertVertex(); v.PropsSet(property1_, value1_); v.add_label(label_); v.PropsSet(property2_, value2_); v.PropsSet(property3_, value3_); dba.Commit(); } } // NOLINTNEXTLINE(hicpp-special-member-functions) TEST_F(UniqueConstraintsTest, InsertRemoveInsertSameTransaction) { auto dba = db_.Access(); auto v = dba.InsertVertex(); v.PropsSet(property2_, value2_); v.PropsSet(property1_, value1_); v.PropsSet(property3_, value3_); v.add_label(label_); v.PropsErase(property2_); v.PropsSet(property2_, value2_); dba.Commit(); } // NOLINTNEXTLINE(hicpp-special-member-functions) TEST_F(UniqueConstraintsTest, InsertDropInsert) { { auto dba = db_.Access(); auto v = dba.InsertVertex(); v.PropsSet(property1_, value1_); v.add_label(label_); v.PropsSet(property2_, value2_); v.PropsSet(property3_, value3_); dba.Commit(); } { auto dba = db_.Access(); dba.DeleteUniqueConstraint(label_, {property2_, property3_, property1_}); dba.Commit(); } { auto dba = db_.Access(); auto v = dba.InsertVertex(); v.PropsSet(property2_, value2_); v.PropsSet(property1_, value1_); v.add_label(label_); v.PropsSet(property3_, value3_); dba.Commit(); } } int main(int argc, char **argv) { ::testing::InitGoogleTest(&argc, argv); google::InitGoogleLogging(argv[0]); return RUN_ALL_TESTS(); }