static svn_error_t * commit_packed_fs(const 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 after_rev; /* Bail (with success) on known-untestable scenarios */ if ((strcmp(opts->fs_type, "fsfs") != 0) || (opts->server_minor_version && (opts->server_minor_version < 6))) return SVN_NO_ERROR; /* Create the packed FS and open it. */ SVN_ERR(create_packed_filesystem(REPO_NAME, opts, MAX_REV, 5, pool)); SVN_ERR(svn_fs_open(&fs, REPO_NAME, NULL, pool)); /* Now do a commit. */ SVN_ERR(svn_fs_begin_txn(&txn, fs, MAX_REV, pool)); SVN_ERR(svn_fs_txn_root(&txn_root, txn, pool)); SVN_ERR(svn_test__set_file_contents(txn_root, "iota", "How much better is it to get wisdom than gold! and to get " "understanding rather to be chosen than silver!", pool)); SVN_ERR(svn_fs_commit_txn(&conflict, &after_rev, txn, pool)); SVN_TEST_ASSERT(SVN_IS_VALID_REVNUM(after_rev)); return SVN_NO_ERROR; }
static svn_error_t * pack_even_filesystem(const char **msg, svn_boolean_t msg_only, svn_test_opts_t *opts, apr_pool_t *pool) { svn_node_kind_t kind; const char *path; *msg = "pack FSFS where revs % shard = 0"; if (msg_only) return SVN_NO_ERROR; /* Bail (with success) on known-untestable scenarios */ if ((strcmp(opts->fs_type, "fsfs") != 0) || (opts->server_minor_version && (opts->server_minor_version < 6))) return SVN_NO_ERROR; SVN_ERR(create_packed_filesystem(REPO_NAME, opts, MAX_REV, SHARD_SIZE, pool)); path = svn_path_join_many(pool, REPO_NAME, "revs", "2.pack", NULL); SVN_ERR(svn_io_check_path(path, &kind, pool)); if (kind != svn_node_dir) return svn_error_createf(SVN_ERR_FS_GENERAL, NULL, "Packing did not complete as expected"); return SVN_NO_ERROR; }
static svn_error_t * recover_fully_packed(const svn_test_opts_t *opts, apr_pool_t *pool) { apr_pool_t *subpool; svn_fs_t *fs; svn_fs_txn_t *txn; svn_fs_root_t *txn_root; const char *conflict; svn_revnum_t after_rev; svn_error_t *err; /* Bail (with success) on known-untestable scenarios */ if ((strcmp(opts->fs_type, "fsfs") != 0) || (opts->server_minor_version && (opts->server_minor_version < 7))) return SVN_NO_ERROR; /* Create a packed FS for which every revision will live in a pack digest file, and then recover it. */ SVN_ERR(create_packed_filesystem(REPO_NAME, opts, MAX_REV, SHARD_SIZE, pool)); SVN_ERR(svn_fs_recover(REPO_NAME, NULL, NULL, pool)); /* Add another revision, re-pack, re-recover. */ subpool = svn_pool_create(pool); SVN_ERR(svn_fs_open(&fs, REPO_NAME, NULL, subpool)); SVN_ERR(svn_fs_begin_txn(&txn, fs, MAX_REV, subpool)); SVN_ERR(svn_fs_txn_root(&txn_root, txn, subpool)); SVN_ERR(svn_test__set_file_contents(txn_root, "A/mu", "new-mu", subpool)); SVN_ERR(svn_fs_commit_txn(&conflict, &after_rev, txn, subpool)); SVN_TEST_ASSERT(SVN_IS_VALID_REVNUM(after_rev)); svn_pool_destroy(subpool); SVN_ERR(svn_fs_pack(REPO_NAME, NULL, NULL, NULL, NULL, pool)); SVN_ERR(svn_fs_recover(REPO_NAME, NULL, NULL, pool)); /* Now, delete the youngest revprop file, and recover again. This time we want to see an error! */ SVN_ERR(svn_io_remove_file2( svn_dirent_join_many(pool, REPO_NAME, PATH_REVPROPS_DIR, apr_psprintf(pool, "%ld/%ld", after_rev / SHARD_SIZE, after_rev), NULL), FALSE, pool)); err = svn_fs_recover(REPO_NAME, NULL, NULL, pool); if (! err) return svn_error_create(SVN_ERR_TEST_FAILED, NULL, "Expected SVN_ERR_FS_CORRUPT error; got none"); if (err->apr_err != SVN_ERR_FS_CORRUPT) return svn_error_create(SVN_ERR_TEST_FAILED, err, "Expected SVN_ERR_FS_CORRUPT error; got:"); svn_error_clear(err); return SVN_NO_ERROR; }
static svn_error_t * read_packed_fs(const char **msg, svn_boolean_t msg_only, svn_test_opts_t *opts, apr_pool_t *pool) { svn_fs_t *fs; svn_stream_t *rstream; svn_stringbuf_t *rstring; svn_revnum_t i; *msg = "read from a packed FSFS filesystem"; if (msg_only) return SVN_NO_ERROR; /* Bail (with success) on known-untestable scenarios */ if ((strcmp(opts->fs_type, "fsfs") != 0) || (opts->server_minor_version && (opts->server_minor_version < 6))) return SVN_NO_ERROR; SVN_ERR(create_packed_filesystem(REPO_NAME, opts, 11, 5, pool)); SVN_ERR(svn_fs_open(&fs, REPO_NAME, NULL, pool)); for (i = 1; i < 12; i++) { svn_fs_root_t *rev_root; svn_stringbuf_t *sb; SVN_ERR(svn_fs_revision_root(&rev_root, fs, i, pool)); SVN_ERR(svn_fs_file_contents(&rstream, rev_root, "iota", pool)); SVN_ERR(svn_test__stream_to_string(&rstring, rstream, pool)); if (i == 1) sb = svn_stringbuf_create("This is the file 'iota'.\n", pool); else sb = svn_stringbuf_create(get_rev_contents(i, pool), pool); if (! svn_stringbuf_compare(rstring, sb)) return svn_error_createf(SVN_ERR_FS_GENERAL, NULL, "Bad data in revision %ld.", i); } return SVN_NO_ERROR; }
static svn_error_t * get_set_revprop_packed_fs(const 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 after_rev; svn_string_t *prop_value; apr_pool_t *subpool; /* Bail (with success) on known-untestable scenarios */ if ((strcmp(opts->fs_type, "fsfs") != 0) || (opts->server_minor_version && (opts->server_minor_version < 7))) return SVN_NO_ERROR; /* Create the packed FS and open it. */ SVN_ERR(create_packed_filesystem(REPO_NAME, opts, MAX_REV, SHARD_SIZE, pool)); SVN_ERR(svn_fs_open(&fs, REPO_NAME, NULL, pool)); subpool = svn_pool_create(pool); /* Do a commit to trigger packing. */ SVN_ERR(svn_fs_begin_txn(&txn, fs, MAX_REV, subpool)); SVN_ERR(svn_fs_txn_root(&txn_root, txn, subpool)); SVN_ERR(svn_test__set_file_contents(txn_root, "iota", "new-iota", subpool)); SVN_ERR(svn_fs_commit_txn(&conflict, &after_rev, txn, subpool)); SVN_TEST_ASSERT(SVN_IS_VALID_REVNUM(after_rev)); svn_pool_clear(subpool); /* Pack the repository. */ SVN_ERR(svn_fs_pack(REPO_NAME, NULL, NULL, NULL, NULL, pool)); /* Try to get revprop for revision 0. */ SVN_ERR(svn_fs_revision_prop(&prop_value, fs, 0, SVN_PROP_REVISION_AUTHOR, pool)); /* Try to change revprop for revision 0. */ SVN_ERR(svn_fs_change_rev_prop(fs, 0, SVN_PROP_REVISION_AUTHOR, svn_string_create("tweaked-author", pool), pool)); return SVN_NO_ERROR; }
static svn_error_t * pack_filesystem(const svn_test_opts_t *opts, apr_pool_t *pool) { int i; svn_node_kind_t kind; const char *path; char buf[80]; apr_file_t *file; apr_size_t len; /* Bail (with success) on known-untestable scenarios */ if ((strcmp(opts->fs_type, "fsfs") != 0) || (opts->server_minor_version && (opts->server_minor_version < 6))) return SVN_NO_ERROR; SVN_ERR(create_packed_filesystem(REPO_NAME, opts, MAX_REV, SHARD_SIZE, pool)); /* Check to see that the pack files exist, and that the rev directories don't. */ for (i = 0; i < (MAX_REV + 1) / SHARD_SIZE; i++) { path = svn_dirent_join_many(pool, REPO_NAME, "revs", apr_psprintf(pool, "%d.pack", i / SHARD_SIZE), "pack", NULL); /* These files should exist. */ SVN_ERR(svn_io_check_path(path, &kind, pool)); if (kind != svn_node_file) return svn_error_createf(SVN_ERR_FS_GENERAL, NULL, "Expected pack file '%s' not found", path); path = svn_dirent_join_many(pool, REPO_NAME, "revs", apr_psprintf(pool, "%d.pack", i / SHARD_SIZE), "manifest", NULL); SVN_ERR(svn_io_check_path(path, &kind, pool)); if (kind != svn_node_file) return svn_error_createf(SVN_ERR_FS_GENERAL, NULL, "Expected manifest file '%s' not found", path); /* This directory should not exist. */ path = svn_dirent_join_many(pool, REPO_NAME, "revs", apr_psprintf(pool, "%d", i / SHARD_SIZE), NULL); SVN_ERR(svn_io_check_path(path, &kind, pool)); if (kind != svn_node_none) return svn_error_createf(SVN_ERR_FS_GENERAL, NULL, "Unexpected directory '%s' found", path); } /* Ensure the min-unpacked-rev jives with the above operations. */ SVN_ERR(svn_io_file_open(&file, svn_dirent_join(REPO_NAME, PATH_MIN_UNPACKED_REV, pool), APR_READ | APR_BUFFERED, APR_OS_DEFAULT, pool)); len = sizeof(buf); SVN_ERR(svn_io_read_length_line(file, buf, &len, pool)); SVN_ERR(svn_io_file_close(file, pool)); if (SVN_STR_TO_REV(buf) != (MAX_REV / SHARD_SIZE) * SHARD_SIZE) return svn_error_createf(SVN_ERR_FS_GENERAL, NULL, "Bad '%s' contents", PATH_MIN_UNPACKED_REV); /* Finally, make sure the final revision directory does exist. */ path = svn_dirent_join_many(pool, REPO_NAME, "revs", apr_psprintf(pool, "%d", (i / SHARD_SIZE) + 1), NULL); SVN_ERR(svn_io_check_path(path, &kind, pool)); if (kind != svn_node_none) return svn_error_createf(SVN_ERR_FS_GENERAL, NULL, "Expected directory '%s' not found", path); return SVN_NO_ERROR; }