📄 locks-test.c
字号:
}/* Test that we can set and get locks in and under a directory. We'll use non-existent FS paths for this test, though, as the FS API currently disallows directory locking. */static svn_error_t *directory_locks_kinda(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; svn_fs_access_t *access; svn_lock_t *mylock; apr_size_t num_expected_paths, i; struct get_locks_baton_t *get_locks_baton; *msg = "directory locks (kinda)"; if (msg_only) return SVN_NO_ERROR; /* Prepare a filesystem and a new txn. */ SVN_ERR(svn_test__create_fs(&fs, "test-repo-directory-locks-kinda", 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)); /* We are now 'bubba'. */ SVN_ERR(svn_fs_create_access(&access, "bubba", pool)); SVN_ERR(svn_fs_set_access(fs, access)); /*** Lock some various, non-existent, yet dir-name-spacily overlapping paths; verify. ***/ { static const char *expected_paths[] = { "/Program Files/Tigris.org/Subversion", "/Program Files/Tigris.org", "/Stuff/Junk/Fluff", "/Program Files", }; num_expected_paths = sizeof(expected_paths) / sizeof(const char *); /* Lock all paths under /A/D/G. */ for (i = 0; i < num_expected_paths; i++) { SVN_ERR(svn_fs_lock(&mylock, fs, expected_paths[i], NULL, "", 0, 0, SVN_INVALID_REVNUM, FALSE, pool)); } get_locks_baton = make_get_locks_baton(pool); SVN_ERR(svn_fs_get_locks(fs, "/", get_locks_callback, get_locks_baton, pool)); SVN_ERR(verify_matching_lock_paths(get_locks_baton, expected_paths, num_expected_paths, pool)); } /*** Now unlock a "middle directory" ***/ { static const char *expected_paths[] = { "/Program Files/Tigris.org/Subversion", "/Stuff/Junk/Fluff", "/Program Files", }; num_expected_paths = sizeof(expected_paths) / sizeof(const char *); SVN_ERR(svn_fs_unlock(fs, "/Program Files/Tigris.org", NULL, TRUE, pool)); get_locks_baton = make_get_locks_baton(pool); SVN_ERR(svn_fs_get_locks(fs, "/", 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 locks auto-expire correctly. */static svn_error_t *lock_expiration(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; struct get_locks_baton_t *get_locks_baton; *msg = "test that locks can expire"; if (msg_only) return SVN_NO_ERROR; /* Prepare a filesystem and a new txn. */ SVN_ERR(svn_test__create_fs(&fs, "test-repo-lock-expiration", 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 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 now 'bubba'. */ SVN_ERR(svn_fs_create_access(&access, "bubba", pool)); SVN_ERR(svn_fs_set_access(fs, access)); /* Lock /A/D/G/rho, with an expiration 3 seconds from now. */ SVN_ERR(svn_fs_lock(&mylock, fs, "/A/D/G/rho", NULL, "", 0, apr_time_now() + apr_time_from_sec(3), SVN_INVALID_REVNUM, FALSE, pool)); /* Become nobody. */ SVN_ERR(svn_fs_set_access(fs, NULL)); /* Try to commit. Should fail because we're 'nobody', and the lock hasn't expired yet. */ err = svn_fs_commit_txn(&conflict, &newrev, txn, pool); if (! err) return svn_error_create (SVN_ERR_TEST_FAILED, NULL, "Uhoh, able to commit a file that has a non-expired lock."); svn_error_clear(err); /* Check that the lock is there, by getting it via the paths parent. */ { static const char *expected_paths [] = { "/A/D/G/rho" }; apr_size_t num_expected_paths = (sizeof(expected_paths) / sizeof(expected_paths[0])); get_locks_baton = make_get_locks_baton(pool); SVN_ERR(svn_fs_get_locks(fs, "/A/D/G", get_locks_callback, get_locks_baton, pool)); SVN_ERR(verify_matching_lock_paths(get_locks_baton, expected_paths, num_expected_paths, pool)); } /* Sleep 5 seconds, so the lock auto-expires. Anonymous commit should then succeed. */ apr_sleep(apr_time_from_sec(5)); /* Verify that the lock auto-expired even in the recursive case. */ { static const char *expected_paths [] = { 0 }; apr_size_t num_expected_paths = 0; get_locks_baton = make_get_locks_baton(pool); SVN_ERR(svn_fs_get_locks(fs, "/A/D/G", get_locks_callback, get_locks_baton, pool)); SVN_ERR(verify_matching_lock_paths(get_locks_baton, expected_paths, num_expected_paths, pool)); } SVN_ERR(svn_fs_commit_txn(&conflict, &newrev, txn, pool)); return SVN_NO_ERROR;}/* Test that a lock can be broken, stolen, or refreshed */static svn_error_t *lock_break_steal_refresh(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 = "breaking, stealing, refreshing a lock"; if (msg_only) return SVN_NO_ERROR; /* Prepare a filesystem and a new txn. */ SVN_ERR(svn_test__create_fs(&fs, "test-repo-steal-refresh", 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)); /* Become 'hortense' and break bubba's lock, then verify it's gone. */ SVN_ERR(svn_fs_create_access(&access, "hortense", pool)); SVN_ERR(svn_fs_set_access(fs, access)); SVN_ERR(svn_fs_unlock(fs, mylock->path, mylock->token, 1 /* FORCE BREAK */, 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, "Tried to break a lock, but it's still there."); /* As hortense, create a new lock, and verify that we own it. */ SVN_ERR(svn_fs_lock(&mylock, fs, "/A/D/G/rho", NULL, "", 0, 0, SVN_INVALID_REVNUM, FALSE, pool)); SVN_ERR(svn_fs_get_lock(&somelock, fs, "/A/D/G/rho", pool)); if (strcmp(somelock->owner, mylock->owner) != 0) return svn_error_create(SVN_ERR_TEST_FAILED, NULL, "Made a lock, but we don't seem to own it."); /* As bubba, steal hortense's lock, creating a new one that expires. */ 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, apr_time_now() + apr_time_from_sec(300), /* 5 min. */ SVN_INVALID_REVNUM, TRUE /* FORCE STEAL */, pool)); SVN_ERR(svn_fs_get_lock(&somelock, fs, "/A/D/G/rho", pool)); if (strcmp(somelock->owner, mylock->owner) != 0) return svn_error_create(SVN_ERR_TEST_FAILED, NULL, "Made a lock, but we don't seem to own it."); if (! somelock->expiration_date) return svn_error_create(SVN_ERR_TEST_FAILED, NULL, "Made expiring lock, but seems not to expire."); /* Refresh the lock, so that it never expires. */ SVN_ERR(svn_fs_lock(&somelock, fs, somelock->path, somelock->token, somelock->comment, 0, 0, SVN_INVALID_REVNUM, TRUE /* FORCE STEAL */, pool)); SVN_ERR(svn_fs_get_lock(&somelock, fs, "/A/D/G/rho", pool)); if (somelock->expiration_date) return svn_error_create(SVN_ERR_TEST_FAILED, NULL, "Made non-expirirng lock, but it expires."); return SVN_NO_ERROR;}/* Test that svn_fs_lock() and svn_fs_attach_lock() can do out-of-dateness checks.. */static svn_error_t *lock_out_of_date(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 = "check out-of-dateness before locking"; if (msg_only) return SVN_NO_ERROR; /* Prepare a filesystem and a new txn. */ SVN_ERR(svn_test__create_fs(&fs, "test-repo-lock-out-of-date", 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)); /* Commit a small change to /A/D/G/rho, creating revision 2. */ 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)); 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)); /* Try to lock /A/D/G/rho, but claim that we still have r1 of the file. */ err = svn_fs_lock(&mylock, fs, "/A/D/G/rho", NULL, "", 0, 0, 1, FALSE, pool); if (! err) return svn_error_create (SVN_ERR_TEST_FAILED, NULL, "Uhoh, able to lock an out-of-date file."); svn_error_clear(err); /* Attempt lock again, this time claiming to have r2. */ SVN_ERR(svn_fs_lock(&mylock, fs, "/A/D/G/rho", NULL, "", 0, 0, 2, FALSE, pool)); /* 'Refresh' the lock, claiming to have r1... should fail. */ err = svn_fs_lock(&mylock, fs, mylock->path, mylock->token, mylock->comment, 0, apr_time_now() + apr_time_from_sec(50), 1, TRUE /* FORCE STEAL */, pool); if (! err) return svn_error_create (SVN_ERR_TEST_FAILED, NULL, "Uhoh, able to refresh a lock on an out-of-date file."); svn_error_clear(err); return SVN_NO_ERROR;}/* ------------------------------------------------------------------------ *//* The test table. */struct svn_test_descriptor_t test_funcs[] = { SVN_TEST_NULL, SVN_TEST_PASS(lock_only), SVN_TEST_PASS(lookup_lock_by_path), SVN_TEST_PASS(attach_lock), SVN_TEST_PASS(get_locks), SVN_TEST_PASS(basic_lock), SVN_TEST_PASS(lock_credentials), SVN_TEST_PASS(final_lock_check), SVN_TEST_PASS(lock_dir_propchange), SVN_TEST_XFAIL(lock_name_reservation), SVN_TEST_XFAIL(directory_locks_kinda), SVN_TEST_PASS(lock_expiration), SVN_TEST_PASS(lock_break_steal_refresh), SVN_TEST_PASS(lock_out_of_date), SVN_TEST_NULL };
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -