📄 fs-base-test.c
字号:
/* fs-test.c --- tests for the filesystem * * ==================================================================== * Copyright (c) 2000-2004 CollabNet. All rights reserved. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms * are also available at http://subversion.tigris.org/license-1.html. * If newer versions of this license are posted there, you may use a * newer version instead, at your option. * * This software consists of voluntary contributions made by many * individuals. For exact contribution history, see the revision * history and logs, available at http://subversion.tigris.org/. * ==================================================================== */#include <stdlib.h>#include <string.h>#include <apr_pools.h>#include "svn_pools.h"#include "svn_time.h"#include "svn_string.h"#include "svn_fs.h"#include "svn_md5.h"#include "../svn_test.h"#include "../svn_test_fs.h"#include "../../libsvn_fs_base/id.h"#include "../../libsvn_fs_base/trail.h"#include "../../libsvn_fs_base/bdb/txn-table.h"#include "../../libsvn_fs_base/bdb/nodes-table.h"#include "../../libsvn_delta/delta.h"#define SET_STR(ps, s) ((ps)->data = (s), (ps)->len = strlen(s))/*-----------------------------------------------------------------*//** The actual fs-tests called by `make check` **//* Create a filesystem. */static svn_error_t *create_berkeley_filesystem(const char **msg, svn_boolean_t msg_only, svn_test_opts_t *opts, apr_pool_t *pool){ svn_fs_t *fs; *msg = "svn_fs_create_berkeley"; if (msg_only) return SVN_NO_ERROR; /* Create and close a repository. */ SVN_ERR(svn_test__create_fs(&fs, "test-repo-create-berkeley", "bdb", pool)); return SVN_NO_ERROR;}/* Generic Berkeley DB error handler function. */static voidberkeley_error_handler(const char *errpfx, char *msg){ fprintf(stderr, "%s%s\n", errpfx ? errpfx : "", msg);}/* Open an existing filesystem. */static svn_error_t *open_berkeley_filesystem(const char **msg, svn_boolean_t msg_only, svn_test_opts_t *opts, apr_pool_t *pool){ svn_fs_t *fs, *fs2; *msg = "open an existing Berkeley DB filesystem"; if (msg_only) return SVN_NO_ERROR; /* Create and close a repository (using fs). */ SVN_ERR(svn_test__create_fs(&fs, "test-repo-open-berkeley", "bdb", pool)); /* Create a different fs object, and use it to re-open the repository again. */ SVN_ERR(svn_test__fs_new(&fs2, pool)); SVN_ERR(svn_fs_open_berkeley(fs2, "test-repo-open-berkeley")); /* Provide a handler for Berkeley DB error messages. */ SVN_ERR(svn_fs_set_berkeley_errcall(fs2, berkeley_error_handler)); return SVN_NO_ERROR;}/* Set *PRESENT to true if entry NAME is present in directory PATH under ROOT, else set *PRESENT to false. */static svn_error_t *check_entry(svn_fs_root_t *root, const char *path, const char *name, svn_boolean_t *present, apr_pool_t *pool){ apr_hash_t *entries; svn_fs_dirent_t *ent; SVN_ERR(svn_fs_dir_entries(&entries, root, path, pool)); ent = apr_hash_get(entries, name, APR_HASH_KEY_STRING); if (ent) *present = TRUE; else *present = FALSE; return SVN_NO_ERROR;}/* Return an error if entry NAME is absent in directory PATH under ROOT. */static svn_error_t *check_entry_present(svn_fs_root_t *root, const char *path, const char *name, apr_pool_t *pool){ svn_boolean_t present; SVN_ERR(check_entry(root, path, name, &present, pool)); if (! present) return svn_error_createf (SVN_ERR_FS_GENERAL, NULL, "entry \"%s\" absent when it should be present", name); return SVN_NO_ERROR;}/* Return an error if entry NAME is present in directory PATH under ROOT. */static svn_error_t *check_entry_absent(svn_fs_root_t *root, const char *path, const char *name, apr_pool_t *pool){ svn_boolean_t present; SVN_ERR(check_entry(root, path, name, &present, pool)); if (present) return svn_error_createf (SVN_ERR_FS_GENERAL, NULL, "entry \"%s\" present when it should be absent", name); return SVN_NO_ERROR;}struct check_id_args{ svn_fs_t *fs; const svn_fs_id_t *id; svn_boolean_t present;};static svn_error_t *txn_body_check_id(void *baton, trail_t *trail){ struct check_id_args *args = baton; node_revision_t *noderev; svn_error_t *err; err = svn_fs_bdb__get_node_revision(&noderev, args->fs, args->id, trail, trail->pool); if (err && (err->apr_err == SVN_ERR_FS_ID_NOT_FOUND)) args->present = FALSE; else if (! err) args->present = TRUE; else { svn_string_t *id_str = svn_fs_unparse_id(args->id, trail->pool); return svn_error_createf (SVN_ERR_FS_GENERAL, err, "error looking for node revision id \"%s\"", id_str->data); } svn_error_clear(err); return SVN_NO_ERROR;}/* Set *PRESENT to true if node revision ID is present in filesystem FS, else set *PRESENT to false. */static svn_error_t *check_id(svn_fs_t *fs, const svn_fs_id_t *id, svn_boolean_t *present, apr_pool_t *pool){ struct check_id_args args; args.id = id; args.fs = fs; SVN_ERR(svn_fs_base__retry_txn(fs, txn_body_check_id, &args, pool)); if (args.present) *present = TRUE; else *present = FALSE; return SVN_NO_ERROR;}/* Return error if node revision ID is not present in FS. */static svn_error_t *check_id_present(svn_fs_t *fs, const svn_fs_id_t *id, apr_pool_t *pool){ svn_boolean_t present; SVN_ERR(check_id(fs, id, &present, pool)); if (! present) { svn_string_t *id_str = svn_fs_unparse_id(id, pool); return svn_error_createf (SVN_ERR_FS_GENERAL, NULL, "node revision id \"%s\" absent when should be present", id_str->data); } return SVN_NO_ERROR;}/* Return error if node revision ID is present in FS. */static svn_error_t *check_id_absent(svn_fs_t *fs, const svn_fs_id_t *id, apr_pool_t *pool){ svn_boolean_t present; SVN_ERR(check_id(fs, id, &present, pool)); if (present) { svn_string_t *id_str = svn_fs_unparse_id(id, pool); return svn_error_createf (SVN_ERR_FS_GENERAL, NULL, "node revision id \"%s\" present when should be absent", id_str->data); } return SVN_NO_ERROR;}/* Test that aborting a Subversion transaction works. NOTE: This function tests internal filesystem interfaces, not just the public filesystem interface. */static svn_error_t *abort_txn(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 *txn1, *txn2; svn_fs_root_t *txn1_root, *txn2_root; const char *txn1_name, *txn2_name; *msg = "abort a transaction"; if (msg_only) return SVN_NO_ERROR; /* Prepare two txns to receive the Greek tree. */ SVN_ERR(svn_test__create_fs(&fs, "test-repo-abort-txn", "bdb", pool)); SVN_ERR(svn_fs_begin_txn(&txn1, fs, 0, pool)); SVN_ERR(svn_fs_begin_txn(&txn2, fs, 0, pool)); SVN_ERR(svn_fs_txn_root(&txn1_root, txn1, pool)); SVN_ERR(svn_fs_txn_root(&txn2_root, txn2, pool)); /* Save their names for later. */ SVN_ERR(svn_fs_txn_name(&txn1_name, txn1, pool)); SVN_ERR(svn_fs_txn_name(&txn2_name, txn2, pool)); /* Create greek trees in them. */ SVN_ERR(svn_test__create_greek_tree(txn1_root, pool)); SVN_ERR(svn_test__create_greek_tree(txn2_root, pool)); /* The test is to abort txn2, while leaving txn1. * * After we abort txn2, we make sure that a) all of its nodes * disappeared from the database, and b) none of txn1's nodes * disappeared. * * Finally, we create a third txn, and check that the name it got is * different from the names of txn1 and txn2. */ { /* Yes, I really am this paranoid. */ /* IDs for every file in the standard Greek Tree. */ const svn_fs_id_t *t1_root_id, *t2_root_id, *t1_iota_id, *t2_iota_id, *t1_A_id, *t2_A_id, *t1_mu_id, *t2_mu_id, *t1_B_id, *t2_B_id, *t1_lambda_id, *t2_lambda_id, *t1_E_id, *t2_E_id, *t1_alpha_id, *t2_alpha_id, *t1_beta_id, *t2_beta_id, *t1_F_id, *t2_F_id, *t1_C_id, *t2_C_id, *t1_D_id, *t2_D_id, *t1_gamma_id, *t2_gamma_id, *t1_H_id, *t2_H_id, *t1_chi_id, *t2_chi_id, *t1_psi_id, *t2_psi_id, *t1_omega_id, *t2_omega_id, *t1_G_id, *t2_G_id, *t1_pi_id, *t2_pi_id, *t1_rho_id, *t2_rho_id, *t1_tau_id, *t2_tau_id; SVN_ERR(svn_fs_node_id(&t1_root_id, txn1_root, "", pool)); SVN_ERR(svn_fs_node_id(&t2_root_id, txn2_root, "", pool)); SVN_ERR(svn_fs_node_id(&t1_iota_id, txn1_root, "iota", pool)); SVN_ERR(svn_fs_node_id(&t2_iota_id, txn2_root, "iota", pool)); SVN_ERR(svn_fs_node_id(&t1_A_id, txn1_root, "/A", pool)); SVN_ERR(svn_fs_node_id(&t2_A_id, txn2_root, "/A", pool)); SVN_ERR(svn_fs_node_id(&t1_mu_id, txn1_root, "/A/mu", pool)); SVN_ERR(svn_fs_node_id(&t2_mu_id, txn2_root, "/A/mu", pool)); SVN_ERR(svn_fs_node_id(&t1_B_id, txn1_root, "/A/B", pool)); SVN_ERR(svn_fs_node_id(&t2_B_id, txn2_root, "/A/B", pool)); SVN_ERR(svn_fs_node_id(&t1_lambda_id, txn1_root, "/A/B/lambda", pool)); SVN_ERR(svn_fs_node_id(&t2_lambda_id, txn2_root, "/A/B/lambda", pool)); SVN_ERR(svn_fs_node_id(&t1_E_id, txn1_root, "/A/B/E", pool)); SVN_ERR(svn_fs_node_id(&t2_E_id, txn2_root, "/A/B/E", pool)); SVN_ERR(svn_fs_node_id(&t1_alpha_id, txn1_root, "/A/B/E/alpha", pool)); SVN_ERR(svn_fs_node_id(&t2_alpha_id, txn2_root, "/A/B/E/alpha", pool)); SVN_ERR(svn_fs_node_id(&t1_beta_id, txn1_root, "/A/B/E/beta", pool)); SVN_ERR(svn_fs_node_id(&t2_beta_id, txn2_root, "/A/B/E/beta", pool)); SVN_ERR(svn_fs_node_id(&t1_F_id, txn1_root, "/A/B/F", pool)); SVN_ERR(svn_fs_node_id(&t2_F_id, txn2_root, "/A/B/F", pool)); SVN_ERR(svn_fs_node_id(&t1_C_id, txn1_root, "/A/C", pool)); SVN_ERR(svn_fs_node_id(&t2_C_id, txn2_root, "/A/C", pool)); SVN_ERR(svn_fs_node_id(&t1_D_id, txn1_root, "/A/D", pool)); SVN_ERR(svn_fs_node_id(&t2_D_id, txn2_root, "/A/D", pool)); SVN_ERR(svn_fs_node_id(&t1_gamma_id, txn1_root, "/A/D/gamma", pool)); SVN_ERR(svn_fs_node_id(&t2_gamma_id, txn2_root, "/A/D/gamma", pool)); SVN_ERR(svn_fs_node_id(&t1_H_id, txn1_root, "/A/D/H", pool)); SVN_ERR(svn_fs_node_id(&t2_H_id, txn2_root, "/A/D/H", pool)); SVN_ERR(svn_fs_node_id(&t1_chi_id, txn1_root, "/A/D/H/chi", pool)); SVN_ERR(svn_fs_node_id(&t2_chi_id, txn2_root, "/A/D/H/chi", pool)); SVN_ERR(svn_fs_node_id(&t1_psi_id, txn1_root, "/A/D/H/psi", pool)); SVN_ERR(svn_fs_node_id(&t2_psi_id, txn2_root, "/A/D/H/psi", pool)); SVN_ERR(svn_fs_node_id(&t1_omega_id, txn1_root, "/A/D/H/omega", pool)); SVN_ERR(svn_fs_node_id(&t2_omega_id, txn2_root, "/A/D/H/omega", pool)); SVN_ERR(svn_fs_node_id(&t1_G_id, txn1_root, "/A/D/G", pool)); SVN_ERR(svn_fs_node_id(&t2_G_id, txn2_root, "/A/D/G", pool)); SVN_ERR(svn_fs_node_id(&t1_pi_id, txn1_root, "/A/D/G/pi", pool)); SVN_ERR(svn_fs_node_id(&t2_pi_id, txn2_root, "/A/D/G/pi", pool)); SVN_ERR(svn_fs_node_id(&t1_rho_id, txn1_root, "/A/D/G/rho", pool)); SVN_ERR(svn_fs_node_id(&t2_rho_id, txn2_root, "/A/D/G/rho", pool));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -