📄 locks-test.c
字号:
"/A/D/H/omega", }; num_expected_paths = sizeof(expected_paths) / sizeof(const char *); get_locks_baton = make_get_locks_baton(pool); SVN_ERR(svn_fs_get_locks(fs, "A/D/H/omega", get_locks_callback, get_locks_baton, pool)); SVN_ERR(verify_matching_lock_paths(get_locks_baton, expected_paths, num_expected_paths, pool)); } /* Verify from "/iota" (which wasn't locked... tricky...). */ { static const char *expected_paths[] = { 0 }; num_expected_paths = 0; get_locks_baton = make_get_locks_baton(pool); SVN_ERR(svn_fs_get_locks(fs, "iota", get_locks_callback, get_locks_baton, pool)); SVN_ERR(verify_matching_lock_paths(get_locks_baton, expected_paths, num_expected_paths, pool)); } return SVN_NO_ERROR;}/* Test that we can create, fetch, and destroy a lock. It exercises each of the five public fs locking functions. */static svn_error_t *basic_lock(const char **msg, svn_boolean_t msg_only, svn_test_opts_t *opts, apr_pool_t *pool){ svn_fs_t *fs; svn_fs_txn_t *txn; svn_fs_root_t *txn_root; const char *conflict; svn_revnum_t newrev; svn_fs_access_t *access; svn_lock_t *mylock, *somelock; *msg = "basic locking"; if (msg_only) return SVN_NO_ERROR; /* Prepare a filesystem and a new txn. */ SVN_ERR(svn_test__create_fs(&fs, "test-repo-basic-lock", opts->fs_type, pool)); SVN_ERR(svn_fs_begin_txn2(&txn, fs, 0, SVN_FS_TXN_CHECK_LOCKS, pool)); SVN_ERR(svn_fs_txn_root(&txn_root, txn, pool)); /* Create the greek tree and commit it. */ SVN_ERR(svn_test__create_greek_tree(txn_root, pool)); SVN_ERR(svn_fs_commit_txn(&conflict, &newrev, txn, pool)); /* We are now 'bubba'. */ SVN_ERR(svn_fs_create_access(&access, "bubba", pool)); SVN_ERR(svn_fs_set_access(fs, access)); /* Lock /A/D/G/rho. */ SVN_ERR(svn_fs_lock(&mylock, fs, "/A/D/G/rho", NULL, "", 0, 0, SVN_INVALID_REVNUM, FALSE, pool)); /* Can we look up the lock by path? */ SVN_ERR(svn_fs_get_lock(&somelock, fs, "/A/D/G/rho", pool)); if ((! somelock) || (strcmp(somelock->token, mylock->token) != 0)) return svn_error_create(SVN_ERR_TEST_FAILED, NULL, "Couldn't look up a lock by pathname."); /* Unlock /A/D/G/rho, and verify that it's gone. */ SVN_ERR(svn_fs_unlock(fs, mylock->path, mylock->token, 0, pool)); SVN_ERR(svn_fs_get_lock(&somelock, fs, "/A/D/G/rho", pool)); if (somelock) return svn_error_create(SVN_ERR_TEST_FAILED, NULL, "Removed a lock, but it's still there."); return SVN_NO_ERROR;}/* Test that locks are enforced -- specifically that both a username and token are required to make use of the lock. */static svn_error_t *lock_credentials(const char **msg, svn_boolean_t msg_only, svn_test_opts_t *opts, apr_pool_t *pool){ svn_fs_t *fs; svn_fs_txn_t *txn; svn_fs_root_t *txn_root; const char *conflict; svn_revnum_t newrev; svn_fs_access_t *access; svn_lock_t *mylock; svn_error_t *err; *msg = "test that locking requires proper credentials"; if (msg_only) return SVN_NO_ERROR; /* Prepare a filesystem and a new txn. */ SVN_ERR(svn_test__create_fs(&fs, "test-repo-lock-credentials", opts->fs_type, pool)); SVN_ERR(svn_fs_begin_txn2(&txn, fs, 0, SVN_FS_TXN_CHECK_LOCKS, pool)); SVN_ERR(svn_fs_txn_root(&txn_root, txn, pool)); /* Create the greek tree and commit it. */ SVN_ERR(svn_test__create_greek_tree(txn_root, pool)); SVN_ERR(svn_fs_commit_txn(&conflict, &newrev, txn, pool)); /* We are now 'bubba'. */ SVN_ERR(svn_fs_create_access(&access, "bubba", pool)); SVN_ERR(svn_fs_set_access(fs, access)); /* Lock /A/D/G/rho. */ SVN_ERR(svn_fs_lock(&mylock, fs, "/A/D/G/rho", NULL, "", 0, 0, SVN_INVALID_REVNUM, FALSE, pool)); /* Push the proper lock-token into the fs access context. */ SVN_ERR(svn_fs_access_add_lock_token(access, mylock->token)); /* Make a new transaction and change rho. */ SVN_ERR(svn_fs_begin_txn2(&txn, fs, newrev, SVN_FS_TXN_CHECK_LOCKS, pool)); SVN_ERR(svn_fs_txn_root(&txn_root, txn, pool)); SVN_ERR(svn_test__set_file_contents(txn_root, "/A/D/G/rho", "new contents", pool)); /* We are no longer 'bubba'. We're nobody. */ SVN_ERR(svn_fs_set_access(fs, NULL)); /* Try to commit the file change. Should fail, because we're nobody. */ err = svn_fs_commit_txn(&conflict, &newrev, txn, pool); if (! err) return svn_error_create (SVN_ERR_TEST_FAILED, NULL, "Uhoh, able to commit locked file without any fs username."); svn_error_clear(err); /* We are now 'hortense'. */ SVN_ERR(svn_fs_create_access(&access, "hortense", pool)); SVN_ERR(svn_fs_set_access(fs, access)); /* Try to commit the file change. Should fail, because we're 'hortense'. */ err = svn_fs_commit_txn(&conflict, &newrev, txn, pool); if (! err) return svn_error_create (SVN_ERR_TEST_FAILED, NULL, "Uhoh, able to commit locked file as non-owner."); svn_error_clear(err); /* Be 'bubba' again. */ SVN_ERR(svn_fs_create_access(&access, "bubba", pool)); SVN_ERR(svn_fs_set_access(fs, access)); /* Try to commit the file change. Should fail, because there's no token. */ err = svn_fs_commit_txn(&conflict, &newrev, txn, pool); if (! err) return svn_error_create (SVN_ERR_TEST_FAILED, NULL, "Uhoh, able to commit locked file with no lock token."); svn_error_clear(err); /* Push the proper lock-token into the fs access context. */ SVN_ERR(svn_fs_access_add_lock_token(access, mylock->token)); /* Commit should now succeed. */ SVN_ERR(svn_fs_commit_txn(&conflict, &newrev, txn, pool)); return SVN_NO_ERROR;}/* Test that locks are enforced at commit time. Somebody might lock something behind your back, right before you run svn_fs_commit_txn(). Also, this test verifies that recursive lock-checks on directories is working properly. */static svn_error_t *final_lock_check(const char **msg, svn_boolean_t msg_only, svn_test_opts_t *opts, apr_pool_t *pool){ svn_fs_t *fs; svn_fs_txn_t *txn; svn_fs_root_t *txn_root; const char *conflict; svn_revnum_t newrev; svn_fs_access_t *access; svn_lock_t *mylock; svn_error_t *err; *msg = "test that locking is enforced in final commit step"; if (msg_only) return SVN_NO_ERROR; /* Prepare a filesystem and a new txn. */ SVN_ERR(svn_test__create_fs(&fs, "test-repo-final-lock-check", opts->fs_type, pool)); SVN_ERR(svn_fs_begin_txn2(&txn, fs, 0, SVN_FS_TXN_CHECK_LOCKS, pool)); SVN_ERR(svn_fs_txn_root(&txn_root, txn, pool)); /* Create the greek tree and commit it. */ SVN_ERR(svn_test__create_greek_tree(txn_root, pool)); SVN_ERR(svn_fs_commit_txn(&conflict, &newrev, txn, pool)); /* Make a new transaction and delete "/A" */ SVN_ERR(svn_fs_begin_txn2(&txn, fs, newrev, SVN_FS_TXN_CHECK_LOCKS, pool)); SVN_ERR(svn_fs_txn_root(&txn_root, txn, pool)); SVN_ERR(svn_fs_delete(txn_root, "/A", pool)); /* Become 'bubba' and lock "/A/D/G/rho". */ SVN_ERR(svn_fs_create_access(&access, "bubba", pool)); SVN_ERR(svn_fs_set_access(fs, access)); SVN_ERR(svn_fs_lock(&mylock, fs, "/A/D/G/rho", NULL, "", 0, 0, SVN_INVALID_REVNUM, FALSE, pool)); /* We are no longer 'bubba'. We're nobody. */ SVN_ERR(svn_fs_set_access(fs, NULL)); /* Try to commit the transaction. Should fail, because a child of the deleted directory is locked by someone else. */ err = svn_fs_commit_txn(&conflict, &newrev, txn, pool); if (! err) return svn_error_create (SVN_ERR_TEST_FAILED, NULL, "Uhoh, able to commit dir deletion when a child is locked."); svn_error_clear(err); /* Supply correct username and token; commit should work. */ SVN_ERR(svn_fs_set_access(fs, access)); SVN_ERR(svn_fs_access_add_lock_token(access, mylock->token)); SVN_ERR(svn_fs_commit_txn(&conflict, &newrev, txn, pool)); return SVN_NO_ERROR;}/* If a directory's child is locked by someone else, we should still be able to commit a propchange on the directory. */static svn_error_t *lock_dir_propchange(const char **msg, svn_boolean_t msg_only, svn_test_opts_t *opts, apr_pool_t *pool){ svn_fs_t *fs; svn_fs_txn_t *txn; svn_fs_root_t *txn_root; const char *conflict; svn_revnum_t newrev; svn_fs_access_t *access; svn_lock_t *mylock; *msg = "dir propchange can be committed with locked child"; if (msg_only) return SVN_NO_ERROR; /* Prepare a filesystem and a new txn. */ SVN_ERR(svn_test__create_fs(&fs, "test-repo-lock-dir-propchange", opts->fs_type, pool)); SVN_ERR(svn_fs_begin_txn2(&txn, fs, 0, SVN_FS_TXN_CHECK_LOCKS, pool)); SVN_ERR(svn_fs_txn_root(&txn_root, txn, pool)); /* Create the greek tree and commit it. */ SVN_ERR(svn_test__create_greek_tree(txn_root, pool)); SVN_ERR(svn_fs_commit_txn(&conflict, &newrev, txn, pool)); /* Become 'bubba' and lock "/A/D/G/rho". */ SVN_ERR(svn_fs_create_access(&access, "bubba", pool)); SVN_ERR(svn_fs_set_access(fs, access)); SVN_ERR(svn_fs_lock(&mylock, fs, "/A/D/G/rho", NULL, "", 0, 0, SVN_INVALID_REVNUM, FALSE, pool)); /* We are no longer 'bubba'. We're nobody. */ SVN_ERR(svn_fs_set_access(fs, NULL)); /* Make a new transaction and make a propchange on "/A" */ SVN_ERR(svn_fs_begin_txn2(&txn, fs, newrev, SVN_FS_TXN_CHECK_LOCKS, pool)); SVN_ERR(svn_fs_txn_root(&txn_root, txn, pool)); SVN_ERR(svn_fs_change_node_prop(txn_root, "/A", "foo", svn_string_create("bar", pool), pool)); /* Commit should succeed; this means we're doing a non-recursive lock-check on directory, rather than a recursive one. */ SVN_ERR(svn_fs_commit_txn(&conflict, &newrev, txn, pool)); return SVN_NO_ERROR;}/* DAV clients sometimes LOCK non-existent paths, as a way of reserving names. Check that this technique works. */static svn_error_t *lock_name_reservation(const char **msg, svn_boolean_t msg_only, svn_test_opts_t *opts, apr_pool_t *pool){ svn_fs_t *fs; svn_fs_txn_t *txn; svn_fs_root_t *txn_root, *rev_root; const char *conflict; svn_revnum_t newrev; svn_fs_access_t *access; svn_lock_t *mylock; svn_error_t *err; *msg = "able to reserve a name (lock non-existent path)"; if (msg_only) return SVN_NO_ERROR; /* Prepare a filesystem and a new txn. */ SVN_ERR(svn_test__create_fs(&fs, "test-repo-lock-name-reservation", opts->fs_type, pool)); SVN_ERR(svn_fs_begin_txn2(&txn, fs, 0, SVN_FS_TXN_CHECK_LOCKS, pool)); SVN_ERR(svn_fs_txn_root(&txn_root, txn, pool)); /* Create the greek tree and commit it. */ SVN_ERR(svn_test__create_greek_tree(txn_root, pool)); SVN_ERR(svn_fs_commit_txn(&conflict, &newrev, txn, pool)); /* Become 'bubba' and lock imaginary path "/A/D/G2/blooga". */ SVN_ERR(svn_fs_create_access(&access, "bubba", pool)); SVN_ERR(svn_fs_set_access(fs, access)); SVN_ERR(svn_fs_lock(&mylock, fs, "/A/D/G2/blooga", NULL, "", 0, 0, SVN_INVALID_REVNUM, FALSE, pool)); /* We are no longer 'bubba'. We're nobody. */ SVN_ERR(svn_fs_set_access(fs, NULL)); /* Make a new transaction. */ SVN_ERR(svn_fs_begin_txn2(&txn, fs, newrev, SVN_FS_TXN_CHECK_LOCKS, pool)); SVN_ERR(svn_fs_txn_root(&txn_root, txn, pool)); /* This copy should fail, because an imaginary path in the target of the copy is reserved by someone else. */ SVN_ERR(svn_fs_revision_root(&rev_root, fs, 1, pool)); err = svn_fs_copy(rev_root, "/A/D/G", txn_root, "/A/D/G2", pool); if (! err) return svn_error_create (SVN_ERR_TEST_FAILED, NULL, "Uhoh, copy succeeded when path within target was locked."); svn_error_clear(err); return SVN_NO_ERROR;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -