Commit 9e90cff8 authored by Barry Perlman's avatar Barry Perlman Committed by Yoni Fogel

Addresses #2037 refs[t:2037] Add test to verify correct use of directory range locks."


git-svn-id: file:///svn/toku/tokudb.2037b@15681 c7de825b-a66e-492c-adef-691d508d4ae1
parent b7589ac3
......@@ -77,17 +77,17 @@
* create a, b, c
* commit txn
*
* verify_abc() // verify a,b,c exist, c2 and x do not exist
* verify_abcd() // verify a,b,c exist, c2 and x do not exist
*
* begin txn
* perform_ops() // delete b, rename c to c2, create x
* verify_ac2x() // verify a,c2,x exist, b and c do not
* verify_ac2dx() // verify a,c2,x exist, b and c do not
* abort txn
* verify_abc() // verify a,b,c exist, c2 and x do not exist
* verify_abcd() // verify a,b,c exist, c2 and x do not exist
* begin_txn
* perform_ops()
* commit
* verify_ac2x() // verify a,c2,x exist, b and c do not
* verify_ac2dx() // verify a,c2,x exist, b and c do not
*
*
* perform_ops() {
......@@ -97,17 +97,18 @@
* }
*
*
* verify_abc() {
* a,b,c exist, x, c2 do not exist
* verify_abcd() {
* a,b,c,d exist, x, c2 do not exist
* }
*
*
* verify_ac2x() {
* a exists
* verify_ac2dx() {
* a exists
* c2 exists
* x exists
* b does not exist
* c does not exist
* d exists
* x exists
* b does not exist
* c does not exist
* }
*
*
......@@ -147,28 +148,32 @@ test_shutdown(void) {
// create dictionaries a.db, b.db, c.db
static void
create_abc(void) {
create_abcd(void) {
int r;
DB_TXN * txn;
DB * db_a;
DB * db_b;
DB * db_c;
DB * db_d;
r=env->txn_begin(env, 0, &txn, 0); CKERR(r);
r=db_create(&db_a, env, 0); CKERR(r);
r=db_create(&db_b, env, 0); CKERR(r);
r=db_create(&db_c, env, 0); CKERR(r);
r=db_create(&db_d, env, 0); CKERR(r);
r=db_a->open(db_a, txn, "a.db", 0, DB_BTREE, DB_CREATE, S_IRWXU|S_IRWXG|S_IRWXO); CKERR(r);
r=db_b->open(db_b, txn, "b.db", 0, DB_BTREE, DB_CREATE, S_IRWXU|S_IRWXG|S_IRWXO); CKERR(r);
r=db_c->open(db_c, txn, "c.db", 0, DB_BTREE, DB_CREATE, S_IRWXU|S_IRWXG|S_IRWXO); CKERR(r);
r=db_d->open(db_d, txn, "d.db", 0, DB_BTREE, DB_CREATE, S_IRWXU|S_IRWXG|S_IRWXO); CKERR(r);
r=db_a->close(db_a, 0); CKERR(r);
r=db_b->close(db_b, 0); CKERR(r);
r=db_c->close(db_c, 0); CKERR(r);
r=txn->commit(txn, 0); CKERR(r);
r=db_c->close(db_c, 0); CKERR(r); //Should work whether close is before or after commit. Do one after.
r=db_d->close(db_d, 0); CKERR(r); //Should work whether close is before or after commit. Do one after.
}
......@@ -192,15 +197,16 @@ perform_ops(DB_TXN * txn) {
// verify that:
// dictionaries a.db, b.db, c.db exist
// dictionaries a.db, b.db, c.db, d.db exist
// dictionaries x.db and c2.db do not exist
static void
verify_abc(void) {
verify_abcd(void) {
int r;
DB_TXN * txn;
DB * db_a;
DB * db_b;
DB * db_c;
DB * db_d;
DB * db_x;
DB * db_c2;
......@@ -208,6 +214,7 @@ verify_abc(void) {
r=db_create(&db_a, env, 0); CKERR(r);
r=db_create(&db_b, env, 0); CKERR(r);
r=db_create(&db_c, env, 0); CKERR(r);
r=db_create(&db_d, env, 0); CKERR(r);
r=db_create(&db_x, env, 0); CKERR(r);
r=db_create(&db_c2, env, 0); CKERR(r);
......@@ -215,6 +222,7 @@ verify_abc(void) {
r=db_a->open(db_a, txn, "a.db", 0, DB_BTREE, 0, S_IRWXU|S_IRWXG|S_IRWXO); CKERR(r);
r=db_b->open(db_b, txn, "b.db", 0, DB_BTREE, 0, S_IRWXU|S_IRWXG|S_IRWXO); CKERR(r);
r=db_c->open(db_c, txn, "c.db", 0, DB_BTREE, 0, S_IRWXU|S_IRWXG|S_IRWXO); CKERR(r);
r=db_d->open(db_d, txn, "d.db", 0, DB_BTREE, 0, S_IRWXU|S_IRWXG|S_IRWXO); CKERR(r);
// should not exist:
r=db_x->open(db_x, txn, "x.db", 0, DB_BTREE, 0, S_IRWXU|S_IRWXG|S_IRWXO); CKERR2(r, ENOENT);
......@@ -223,6 +231,7 @@ verify_abc(void) {
r=db_a->close(db_a, 0); CKERR(r);
r=db_b->close(db_b, 0); CKERR(r);
r=db_c->close(db_c, 0); CKERR(r);
r=db_d->close(db_d, 0); CKERR(r);
r=db_x->close(db_x, 0); CKERR(r);
r=db_c2->close(db_c2, 0); CKERR(r);
......@@ -234,14 +243,16 @@ verify_abc(void) {
// dictionary a.db exists
// dictionaries b.db, c.db do not exist
// dictionary c2.db exists
// dictionary d.db exists
// dictionary x.db exists
static void
verify_ac2x(DB_TXN * parent_txn) {
verify_ac2dx(DB_TXN * parent_txn) {
int r;
DB_TXN * txn;
DB * db_a;
DB * db_b;
DB * db_c;
DB * db_d;
DB * db_x;
DB * db_c2;
......@@ -249,12 +260,14 @@ verify_ac2x(DB_TXN * parent_txn) {
r=db_create(&db_a, env, 0); CKERR(r);
r=db_create(&db_b, env, 0); CKERR(r);
r=db_create(&db_c, env, 0); CKERR(r);
r=db_create(&db_d, env, 0); CKERR(r);
r=db_create(&db_x, env, 0); CKERR(r);
r=db_create(&db_c2, env, 0); CKERR(r);
// should exist:
r=db_a->open(db_a, txn, "a.db", 0, DB_BTREE, 0, S_IRWXU|S_IRWXG|S_IRWXO); CKERR(r);
r=db_c2->open(db_c2, txn, "c2.db", 0, DB_BTREE, 0, S_IRWXU|S_IRWXG|S_IRWXO); CKERR(r);
r=db_d->open(db_d, txn, "d.db", 0, DB_BTREE, 0, S_IRWXU|S_IRWXG|S_IRWXO); CKERR(r);
r=db_x->open(db_x, txn, "x.db", 0, DB_BTREE, 0, S_IRWXU|S_IRWXG|S_IRWXO); CKERR(r);
// should not exist:
......@@ -264,6 +277,7 @@ verify_ac2x(DB_TXN * parent_txn) {
r=db_a->close(db_a, 0); CKERR(r);
r=db_b->close(db_b, 0); CKERR(r);
r=db_c->close(db_c, 0); CKERR(r);
r=db_d->close(db_d, 0); CKERR(r);
r=db_x->close(db_x, 0); CKERR(r);
r=db_c2->close(db_c2, 0); CKERR(r);
......@@ -272,28 +286,152 @@ verify_ac2x(DB_TXN * parent_txn) {
static void
test_fileops(void) {
test_fileops_1(void) {
int r;
DB_TXN *txn;
create_abc();
verify_abc();
create_abcd();
verify_abcd();
r=env->txn_begin(env, 0, &txn, 0); CKERR(r);
perform_ops(txn);
verify_ac2x(txn); // verify that operations appear effective within this txn
verify_ac2dx(txn); // verify that operations appear effective within this txn
r=txn->abort(txn); CKERR(r);
// verify that aborted transaction changed nothing
verify_abc();
verify_abcd();
r=env->txn_begin(env, 0, &txn, 0); CKERR(r);
perform_ops(txn);
verify_ac2x(txn); // verify that operations appear effective within this txn
verify_ac2dx(txn); // verify that operations appear effective within this txn
r=txn->commit(txn, 0); CKERR(r);
// verify that committed transaction actually changed db
verify_ac2x(NULL);
verify_ac2dx(NULL);
}
static void
verify_locked_open(char * name) {
int r;
DB_TXN * txn;
DB * db;
r=env->txn_begin(env, 0, &txn, 0); CKERR(r);
r=db_create(&db, env, 0); CKERR(r);
r=db->open(db, txn, name, 0, DB_BTREE, DB_CREATE, S_IRWXU|S_IRWXG|S_IRWXO);
CKERR2(r, DB_LOCK_NOTGRANTED);
r=db->close(db, 0); CKERR(r); // always safe to close
r=txn->abort(txn); CKERR(r);
}
static void
verify_locked_remove(char * name) {
int r;
DB_TXN * txn;
r=env->txn_begin(env, 0, &txn, 0); CKERR(r);
r = env->dbremove(env, txn, name, NULL, 0);
CKERR2(r, DB_LOCK_NOTGRANTED);
r=txn->abort(txn); CKERR(r);
}
static void
verify_locked_rename(char * oldname, char * newname) {
int r;
DB_TXN * txn;
r=env->txn_begin(env, 0, &txn, 0); CKERR(r);
r = env->dbrename(env, txn, oldname, NULL, newname, 0);
CKERR2(r, DB_LOCK_NOTGRANTED);
r=txn->abort(txn); CKERR(r);
}
// Purpose of test_fileops_2() is to verify correct operation of
// directory range locks. It should not be possible to open or
// rename or remove a dictionary that is marked for removal or
// rename by another open transaction.
static void
test_fileops_2(void) {
int r;
DB_TXN * txn_a;
verify_ac2dx(NULL); // should still exist
// begin txn_a
// remove a
// create e
// rename x->x2
// rename c2->c3
// open x2, c3, should succeed
// close x2, c3
{
DB * db_e;
DB * db_c3;
DB * db_x2;
r=env->txn_begin(env, 0, &txn_a, 0); CKERR(r);
r=db_create(&db_e, env, 0); CKERR(r);
r=db_create(&db_x2, env, 0); CKERR(r);
r=db_create(&db_c3, env, 0); CKERR(r);
r = env->dbremove(env, txn_a, "a.db", NULL, 0); CKERR(r);
r=db_e->open(db_e, txn_a, "e.db", 0, DB_BTREE, DB_CREATE, S_IRWXU|S_IRWXG|S_IRWXO); CKERR(r);
r = env->dbrename(env, txn_a, "x.db", NULL, "x2.db", 0); CKERR(r);
r = env->dbrename(env, txn_a, "c2.db", NULL, "c3.db", 0); CKERR(r);
r=db_x2->open(db_x2, txn_a, "x2.db", 0, DB_BTREE, 0, S_IRWXU|S_IRWXG|S_IRWXO); CKERR(r);
r=db_c3->open(db_c3, txn_a, "c3.db", 0, DB_BTREE, 0, S_IRWXU|S_IRWXG|S_IRWXO); CKERR(r);
r=db_e->close(db_e, 0); CKERR(r); // abort requires db be closed first
r=db_x2->close(db_x2, 0); CKERR(r); // abort requires db be closed first
r=db_c3->close(db_c3, 0); CKERR(r); // abort requires db be closed first
}
// within another transaction:
// open a, should fail DB_LOCK_NOTGRANTED
// open e, should fail DB_LOCK_NOTGRANTED
// open x, should fail DB_LOCK_NOTGRANTED
// open x2, should fail DB_LOCK_NOTGRANTED
// open c2, should fail DB_LOCK_NOTGRANTED
// open c3, should fail DB_LOCK_NOTGRANTED
// remove a, e, x, x2, c2, c3 DB_LOCK_NOTGRANTED
// rename a, e, x, x2, c2, c3 DB_LOCK_NOTGRANTED
verify_locked_open("a.db");
verify_locked_open("e.db");
verify_locked_open("x.db");
verify_locked_open("x2.db");
verify_locked_open("c2.db");
verify_locked_open("c3.db");
verify_locked_remove("a.db");
verify_locked_remove("e.db");
verify_locked_remove("x.db");
verify_locked_remove("x2.db");
verify_locked_remove("c2.db");
verify_locked_remove("c3.db");
verify_locked_rename("a.db", "z.db");
verify_locked_rename("e.db", "z.db");
verify_locked_rename("x.db", "z.db");
verify_locked_rename("x2.db", "z.db");
verify_locked_rename("c2.db", "z.db");
verify_locked_rename("c3.db", "z.db");
verify_locked_rename("d.db", "a.db");
verify_locked_rename("d.db", "e.db");
verify_locked_rename("d.db", "x.db");
verify_locked_rename("d.db", "x2.db");
verify_locked_rename("d.db", "c2.db");
verify_locked_rename("d.db", "c3.db");
r=txn_a->abort(txn_a); CKERR(r);
}
......@@ -302,7 +440,9 @@ test_main (int argc, char *argv[]) {
parse_args(argc, argv);
setup();
print_engine_status(env);
test_fileops();
test_fileops_1();
print_engine_status(env);
test_fileops_2();
print_engine_status(env);
test_shutdown();
return 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment