📄 fs-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 <assert.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_delta/delta.h"#define SET_STR(ps, s) ((ps)->data = (s), (ps)->len = strlen(s))/*-----------------------------------------------------------------*//** The actual fs-tests called by `make check` **//* Helper: commit TXN, expecting either success or failure: * * If EXPECTED_CONFLICT is null, then the commit is expected to * succeed. If it does succeed, set *NEW_REV to the new revision; * else return error. * * If EXPECTED_CONFLICT is non-null, it is either the empty string or * the expected path of the conflict. If it is the empty string, any * conflict is acceptable. If it is a non-empty string, the commit * must fail due to conflict, and the conflict path must match * EXPECTED_CONFLICT. If they don't match, return error. * * If a conflict is expected but the commit succeeds anyway, return * error. */static svn_error_t *test_commit_txn(svn_revnum_t *new_rev, svn_fs_txn_t *txn, const char *expected_conflict, apr_pool_t *pool){ const char *conflict; svn_error_t *err; err = svn_fs_commit_txn(&conflict, new_rev, txn, pool); if (err && (err->apr_err == SVN_ERR_FS_CONFLICT)) { svn_error_clear(err); if (! expected_conflict) { return svn_error_createf (SVN_ERR_FS_CONFLICT, NULL, "commit conflicted at '%s', but no conflict expected", conflict ? conflict : "(missing conflict info!)"); } else if (conflict == NULL) { return svn_error_createf (SVN_ERR_FS_CONFLICT, NULL, "commit conflicted as expected, " "but no conflict path was returned ('%s' expected)", expected_conflict); } else if ((strcmp(expected_conflict, "") != 0) && (strcmp(conflict, expected_conflict) != 0)) { return svn_error_createf (SVN_ERR_FS_CONFLICT, NULL, "commit conflicted at '%s', but expected conflict at '%s')", conflict, expected_conflict); } } else if (err) /* commit failed, but not due to conflict */ { return svn_error_quick_wrap (err, "commit failed due to something other than a conflict"); } else /* err == NULL, so commit succeeded */ { if (expected_conflict) { return svn_error_createf (SVN_ERR_FS_GENERAL, NULL, "commit succeeded that was expected to fail at '%s'", expected_conflict); } } return SVN_NO_ERROR;}/* Begin a txn, check its name, then close it */static svn_error_t *trivial_transaction(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; const char *txn_name; *msg = "begin a txn, check its name, then close it"; if (msg_only) return SVN_NO_ERROR; SVN_ERR(svn_test__create_fs(&fs, "test-repo-trivial-txn", opts->fs_type, pool)); /* Begin a new transaction that is based on revision 0. */ SVN_ERR(svn_fs_begin_txn(&txn, fs, 0, pool)); /* Test that the txn name is non-null. */ SVN_ERR(svn_fs_txn_name(&txn_name, txn, pool)); if (! txn_name) return svn_error_create(SVN_ERR_FS_GENERAL, NULL, "Got a NULL txn name."); return SVN_NO_ERROR;}/* Open an existing transaction by name. */static svn_error_t *reopen_trivial_transaction(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; const char *txn_name; apr_pool_t *subpool = svn_pool_create(pool); *msg = "open an existing transaction by name"; if (msg_only) return SVN_NO_ERROR; SVN_ERR(svn_test__create_fs(&fs, "test-repo-reopen-trivial-txn", opts->fs_type, pool)); /* Begin a new transaction that is based on revision 0. */ SVN_ERR(svn_fs_begin_txn(&txn, fs, 0, subpool)); /* Don't use the subpool, txn_name must persist beyond the current txn */ SVN_ERR(svn_fs_txn_name(&txn_name, txn, pool)); /* Close the transaction. */ svn_pool_clear(subpool); /* Reopen the transaction by name */ SVN_ERR(svn_fs_open_txn(&txn, fs, txn_name, subpool)); /* Close the transaction ... again. */ svn_pool_destroy(subpool); return SVN_NO_ERROR;}/* Create a file! */static svn_error_t *create_file_transaction(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; *msg = "begin a txn, get the txn root, and add a file"; if (msg_only) return SVN_NO_ERROR; SVN_ERR(svn_test__create_fs(&fs, "test-repo-create-file-txn", opts->fs_type, pool)); /* Begin a new transaction that is based on revision 0. */ SVN_ERR(svn_fs_begin_txn(&txn, fs, 0, pool)); /* Get the txn root */ SVN_ERR(svn_fs_txn_root(&txn_root, txn, pool)); /* Create a new file in the root directory. */ SVN_ERR(svn_fs_make_file(txn_root, "beer.txt", pool)); return SVN_NO_ERROR;}/* Make sure we get txn lists correctly. */static svn_error_t *verify_txn_list(const char **msg, svn_boolean_t msg_only, svn_test_opts_t *opts, apr_pool_t *pool){ svn_fs_t *fs; apr_pool_t *subpool; svn_fs_txn_t *txn1, *txn2; const char *name1, *name2; apr_array_header_t *txn_list; *msg = "create 2 txns, list them, and verify the list"; if (msg_only) return SVN_NO_ERROR; SVN_ERR(svn_test__create_fs(&fs, "test-repo-verify-txn-list", opts->fs_type, pool)); /* Begin a new transaction, get its name (in the top pool), close it. */ subpool = svn_pool_create(pool); SVN_ERR(svn_fs_begin_txn(&txn1, fs, 0, subpool)); SVN_ERR(svn_fs_txn_name(&name1, txn1, pool)); svn_pool_destroy(subpool); /* Begin *another* transaction, get its name (in the top pool), close it. */ subpool = svn_pool_create(pool); SVN_ERR(svn_fs_begin_txn(&txn2, fs, 0, subpool)); SVN_ERR(svn_fs_txn_name(&name2, txn2, pool)); svn_pool_destroy(subpool); /* Get the list of active transactions from the fs. */ SVN_ERR(svn_fs_list_transactions(&txn_list, fs, pool)); /* Check the list. It should have *exactly* two entries. */ if (txn_list->nelts != 2) goto all_bad; /* We should be able to find our 2 txn names in the list, in some order. */ if ((! strcmp(name1, APR_ARRAY_IDX(txn_list, 0, const char *))) && (! strcmp(name2, APR_ARRAY_IDX(txn_list, 1, const char *)))) goto all_good; else if ((! strcmp(name2, APR_ARRAY_IDX(txn_list, 0, const char *))) && (! strcmp(name1, APR_ARRAY_IDX(txn_list, 1, const char *)))) goto all_good; all_bad: return svn_error_create(SVN_ERR_FS_GENERAL, NULL, "Got a bogus txn list."); all_good: return SVN_NO_ERROR;}/* Test writing & reading a file's contents. */static svn_error_t *write_and_read_file(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_stream_t *rstream; svn_stringbuf_t *rstring; svn_stringbuf_t *wstring; *msg = "write and read a file's contents"; if (msg_only) return SVN_NO_ERROR; wstring = svn_stringbuf_create("Wicki wild, wicki wicki wild.", pool); SVN_ERR(svn_test__create_fs(&fs, "test-repo-read-and-write-file", opts->fs_type, pool)); SVN_ERR(svn_fs_begin_txn(&txn, fs, 0, pool)); SVN_ERR(svn_fs_txn_root(&txn_root, txn, pool)); /* Add an empty file. */ SVN_ERR(svn_fs_make_file(txn_root, "beer.txt", pool)); /* And write some data into this file. */ SVN_ERR(svn_test__set_file_contents(txn_root, "beer.txt", wstring->data, pool)); /* Now let's read the data back from the file. */ SVN_ERR(svn_fs_file_contents(&rstream, txn_root, "beer.txt", pool)); SVN_ERR(svn_test__stream_to_string(&rstring, rstream, pool)); /* Compare what was read to what was written. */ if (! svn_stringbuf_compare(rstring, wstring)) return svn_error_create(SVN_ERR_FS_GENERAL, NULL, "data read != data written."); return SVN_NO_ERROR;}/* Create a file, a directory, and a file in that directory! */static svn_error_t *create_mini_tree_transaction(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; *msg = "test basic file and subdirectory creation"; if (msg_only) return SVN_NO_ERROR; SVN_ERR(svn_test__create_fs(&fs, "test-repo-create-mini-tree-txn", opts->fs_type, pool)); /* Begin a new transaction that is based on revision 0. */ SVN_ERR(svn_fs_begin_txn(&txn, fs, 0, pool)); /* Get the txn root */ SVN_ERR(svn_fs_txn_root(&txn_root, txn, pool)); /* Create a new file in the root directory. */ SVN_ERR(svn_fs_make_file(txn_root, "wine.txt", pool)); /* Create a new directory in the root directory. */ SVN_ERR(svn_fs_make_dir(txn_root, "keg", pool)); /* Now, create a file in our new directory. */ SVN_ERR(svn_fs_make_file(txn_root, "keg/beer.txt", pool)); return SVN_NO_ERROR;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -