You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by ph...@apache.org on 2015/05/06 16:22:52 UTC

svn commit: r1678004 [2/3] - in /subversion/trunk: build.conf subversion/tests/libsvn_fs/fs-sequential-test.c subversion/tests/libsvn_fs/fs-test.c

Copied: subversion/trunk/subversion/tests/libsvn_fs/fs-sequential-test.c (from r1677901, subversion/trunk/subversion/tests/libsvn_fs/fs-test.c)
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/libsvn_fs/fs-sequential-test.c?p2=subversion/trunk/subversion/tests/libsvn_fs/fs-sequential-test.c&p1=subversion/trunk/subversion/tests/libsvn_fs/fs-test.c&r1=1677901&r2=1678004&rev=1678004&view=diff
==============================================================================
--- subversion/trunk/subversion/tests/libsvn_fs/fs-test.c (original)
+++ subversion/trunk/subversion/tests/libsvn_fs/fs-sequential-test.c Wed May  6 14:22:51 2015
@@ -1,4 +1,4 @@
-/* fs-test.c --- tests for the filesystem
+/* fs-sequential-test.c --- tests for the filesystem
  *
  * ====================================================================
  *    Licensed to the Apache Software Foundation (ASF) under one
@@ -53,7 +53,7 @@
 
 /*-----------------------------------------------------------------*/
 
-/** The actual fs-tests called by `make check` **/
+/** The actual fs-sequential-tests called by `make check` **/
 
 /* Helper:  commit TXN, expecting either success or failure:
  *
@@ -148,6978 +148,112 @@ test_commit_txn(svn_revnum_t *new_rev,
   return SVN_NO_ERROR;
 }
 
+#if APR_HAS_THREADS
+struct reopen_modify_baton_t {
+  const char *fs_path;
+  const char *txn_name;
+  apr_pool_t *pool;
+  svn_error_t *err;
+};
 
-
-/* Begin a txn, check its name, then close it */
-static svn_error_t *
-trivial_transaction(const svn_test_opts_t *opts,
-                    apr_pool_t *pool)
-{
-  svn_fs_t *fs;
-  svn_fs_txn_t *txn;
-  const char *txn_name;
-  int is_invalid_char[256];
-  int i;
-  const char *p;
-
-  SVN_ERR(svn_test__create_fs(&fs, "test-repo-trivial-txn",
-                              opts, 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.");
-
-  /* Test that the txn name contains only valid characters.  See
-     svn_fs.h for the list of valid characters. */
-  for (i = 0; i < sizeof(is_invalid_char)/sizeof(*is_invalid_char); ++i)
-    is_invalid_char[i] = 1;
-  for (i = '0'; i <= '9'; ++i)
-    is_invalid_char[i] = 0;
-  for (i = 'a'; i <= 'z'; ++i)
-    is_invalid_char[i] = 0;
-  for (i = 'A'; i <= 'Z'; ++i)
-    is_invalid_char[i] = 0;
-  for (p = "-."; *p; ++p)
-    is_invalid_char[(unsigned char) *p] = 0;
-
-  for (p = txn_name; *p; ++p)
-    {
-      if (is_invalid_char[(unsigned char) *p])
-        return svn_error_createf(SVN_ERR_FS_GENERAL, NULL,
-                                 "The txn name '%s' contains an illegal '%c' "
-                                 "character", txn_name, *p);
-    }
-
-  return SVN_NO_ERROR;
-}
-
-
-
-/* Open an existing transaction by name. */
-static svn_error_t *
-reopen_trivial_transaction(const svn_test_opts_t *opts,
-                           apr_pool_t *pool)
-{
-  svn_fs_t *fs;
-  svn_fs_txn_t *txn;
-  svn_fs_root_t *root;
-  const char *txn_name;
-  apr_pool_t *subpool = svn_pool_create(pool);
-
-  SVN_ERR(svn_test__create_fs(&fs, "test-repo-reopen-trivial-txn",
-                              opts, pool));
-
-  /* Create a first transaction - we don't want that one to reopen. */
-  SVN_ERR(svn_fs_begin_txn(&txn, fs, 0, subpool));
-
-  /* Begin a second 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));
-
-  /* Create a third transaction - we don't want that one to reopen. */
-  SVN_ERR(svn_fs_begin_txn(&txn, fs, 0, subpool));
-
-  /* Close the transaction. */
-  svn_pool_clear(subpool);
-
-  /* Reopen the transaction by name */
-  SVN_ERR(svn_fs_open_txn(&txn, fs, txn_name, subpool));
-
-  /* Does it have the same name? */
-  SVN_ERR(svn_fs_txn_root(&root, txn, subpool));
-  SVN_TEST_STRING_ASSERT(svn_fs_txn_root_name(root, subpool), txn_name);
-
-  /* Close the transaction ... again. */
-  svn_pool_destroy(subpool);
-
-  return SVN_NO_ERROR;
-}
-
-
-
-/* Create a file! */
-static svn_error_t *
-create_file_transaction(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;
-
-  SVN_ERR(svn_test__create_fs(&fs, "test-repo-create-file-txn",
-                              opts, 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 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;
-
-  SVN_ERR(svn_test__create_fs(&fs, "test-repo-verify-txn-list",
-                              opts, 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;
-}
-
-
-/* Generate N consecutive transactions, then abort them all.  Return
-   the list of transaction names. */
-static svn_error_t *
-txn_names_are_not_reused_helper1(apr_hash_t **txn_names,
-                                 svn_fs_t *fs,
-                                 apr_pool_t *pool)
-{
-  apr_hash_index_t *hi;
-  const int N = 10;
-  int i;
-
-  *txn_names = apr_hash_make(pool);
-
-  /* Create the transactions and store in a hash table the transaction
-     name as the key and the svn_fs_txn_t * as the value. */
-  for (i = 0; i < N; ++i)
-    {
-      svn_fs_txn_t *txn;
-      const char *name;
-      SVN_ERR(svn_fs_begin_txn(&txn, fs, 0, pool));
-      SVN_ERR(svn_fs_txn_name(&name, txn, pool));
-      if (apr_hash_get(*txn_names, name, APR_HASH_KEY_STRING) != NULL)
-        return svn_error_createf(SVN_ERR_FS_GENERAL, NULL,
-                                 "beginning a new transaction used an "
-                                 "existing transaction name '%s'",
-                                 name);
-      apr_hash_set(*txn_names, name, APR_HASH_KEY_STRING, txn);
-    }
-
-  i = 0;
-  for (hi = apr_hash_first(pool, *txn_names); hi; hi = apr_hash_next(hi))
-    {
-      void *val;
-      apr_hash_this(hi, NULL, NULL, &val);
-      SVN_ERR(svn_fs_abort_txn((svn_fs_txn_t *)val, pool));
-      ++i;
-    }
-
-  if (i != N)
-    return svn_error_createf(SVN_ERR_FS_GENERAL, NULL,
-                             "created %d transactions, but only aborted %d",
-                             N, i);
-
-  return SVN_NO_ERROR;
-}
-
-/* Compare two hash tables and ensure that no keys in the first hash
-   table appear in the second hash table. */
-static svn_error_t *
-txn_names_are_not_reused_helper2(apr_hash_t *ht1,
-                                 apr_hash_t *ht2,
-                                 apr_pool_t *pool)
-{
-  apr_hash_index_t *hi;
-
-  for (hi = apr_hash_first(pool, ht1); hi; hi = apr_hash_next(hi))
-    {
-      const void *key;
-      const char *key_string;
-      apr_hash_this(hi, &key, NULL, NULL);
-      key_string = key;
-      if (apr_hash_get(ht2, key, APR_HASH_KEY_STRING) != NULL)
-        return svn_error_createf(SVN_ERR_FS_GENERAL, NULL,
-                                 "the transaction name '%s' was reused",
-                                 key_string);
-    }
-
-  return SVN_NO_ERROR;
-}
-
-/* Make sure that transaction names are not reused. */
-static svn_error_t *
-txn_names_are_not_reused(const svn_test_opts_t *opts,
-                         apr_pool_t *pool)
-{
-  svn_fs_t *fs;
-  apr_pool_t *subpool;
-  apr_hash_t *txn_names1, *txn_names2;
-
-  /* Bail (with success) on known-untestable scenarios */
-  if ((strcmp(opts->fs_type, "fsfs") == 0)
-      && (opts->server_minor_version && (opts->server_minor_version < 5)))
-    return SVN_NO_ERROR;
-
-  SVN_ERR(svn_test__create_fs(&fs, "test-repo-txn-names-are-not-reused",
-                              opts, pool));
-
-  subpool = svn_pool_create(pool);
-
-  /* Create N transactions, abort them all, and collect the generated
-     transaction names.  Do this twice. */
-  SVN_ERR(txn_names_are_not_reused_helper1(&txn_names1, fs, subpool));
-  SVN_ERR(txn_names_are_not_reused_helper1(&txn_names2, fs, subpool));
-
-  /* Check that no transaction names appear in both hash tables. */
-  SVN_ERR(txn_names_are_not_reused_helper2(txn_names1, txn_names2, subpool));
-  SVN_ERR(txn_names_are_not_reused_helper2(txn_names2, txn_names1, subpool));
-
-  svn_pool_destroy(subpool);
-
-  return SVN_NO_ERROR;
-}
-
-
-
-/* Test writing & reading a file's contents. */
-static svn_error_t *
-write_and_read_file(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;
-  svn_stream_t *rstream;
-  svn_stringbuf_t *rstring;
-  svn_stringbuf_t *wstring;
-
-  wstring = svn_stringbuf_create("Wicki wild, wicki wicki wild.", pool);
-  SVN_ERR(svn_test__create_fs(&fs, "test-repo-read-and-write-file",
-                              opts, 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 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_ERR(svn_test__create_fs(&fs, "test-repo-create-mini-tree-txn",
-                              opts, 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;
-}
-
-
-/* Create a file, a directory, and a file in that directory! */
-static svn_error_t *
-create_greek_tree_transaction(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;
-
-  /* Prepare a txn to receive the greek tree. */
-  SVN_ERR(svn_test__create_fs(&fs, "test-repo-create-greek-tree-txn",
-                              opts, pool));
-  SVN_ERR(svn_fs_begin_txn(&txn, fs, 0, pool));
-  SVN_ERR(svn_fs_txn_root(&txn_root, txn, pool));
-
-  /* Create and verify the greek tree. */
-  SVN_ERR(svn_test__create_greek_tree(txn_root, pool));
-
-  return SVN_NO_ERROR;
-}
-
-
-/* Verify that entry KEY is present in ENTRIES, and that its value is
-   an svn_fs_dirent_t whose name and id are not null. */
-static svn_error_t *
-verify_entry(apr_hash_t *entries, const char *key)
-{
-  svn_fs_dirent_t *ent = apr_hash_get(entries, key,
-                                      APR_HASH_KEY_STRING);
-
-  if (ent == NULL)
-    return svn_error_createf
-      (SVN_ERR_FS_GENERAL, NULL,
-       "didn't find dir entry for \"%s\"", key);
-
-  if ((ent->name == NULL) && (ent->id == NULL))
-    return svn_error_createf
-      (SVN_ERR_FS_GENERAL, NULL,
-       "dir entry for \"%s\" has null name and null id", key);
-
-  if (ent->name == NULL)
-    return svn_error_createf
-      (SVN_ERR_FS_GENERAL, NULL,
-       "dir entry for \"%s\" has null name", key);
-
-  if (ent->id == NULL)
-    return svn_error_createf
-      (SVN_ERR_FS_GENERAL, NULL,
-       "dir entry for \"%s\" has null id", key);
-
-  if (strcmp(ent->name, key) != 0)
-     return svn_error_createf
-     (SVN_ERR_FS_GENERAL, NULL,
-      "dir entry for \"%s\" contains wrong name (\"%s\")", key, ent->name);
-
-  return SVN_NO_ERROR;
-}
-
-
-static svn_error_t *
-list_directory(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;
-  apr_hash_t *entries;
-
-  SVN_ERR(svn_test__create_fs(&fs, "test-repo-list-dir",
-                              opts, pool));
-  SVN_ERR(svn_fs_begin_txn(&txn, fs, 0, pool));
-  SVN_ERR(svn_fs_txn_root(&txn_root, txn, pool));
-
-  /* We create this tree
-   *
-   *         /q
-   *         /A/x
-   *         /A/y
-   *         /A/z
-   *         /B/m
-   *         /B/n
-   *         /B/o
-   *
-   * then list dir A.  It should have 3 files: "x", "y", and "z", no
-   * more, no less.
-   */
-
-  /* Create the tree. */
-  SVN_ERR(svn_fs_make_file(txn_root, "q", pool));
-  SVN_ERR(svn_fs_make_dir(txn_root, "A", pool));
-  SVN_ERR(svn_fs_make_file(txn_root, "A/x", pool));
-  SVN_ERR(svn_fs_make_file(txn_root, "A/y", pool));
-  SVN_ERR(svn_fs_make_file(txn_root, "A/z", pool));
-  SVN_ERR(svn_fs_make_dir(txn_root, "B", pool));
-  SVN_ERR(svn_fs_make_file(txn_root, "B/m", pool));
-  SVN_ERR(svn_fs_make_file(txn_root, "B/n", pool));
-  SVN_ERR(svn_fs_make_file(txn_root, "B/o", pool));
-
-  /* Get A's entries. */
-  SVN_ERR(svn_fs_dir_entries(&entries, txn_root, "A", pool));
-
-  /* Make sure exactly the right set of entries is present. */
-  if (apr_hash_count(entries) != 3)
-    {
-      return svn_error_create(SVN_ERR_FS_GENERAL, NULL,
-                              "unexpected number of entries in dir");
-    }
-  else
-    {
-      SVN_ERR(verify_entry(entries, "x"));
-      SVN_ERR(verify_entry(entries, "y"));
-      SVN_ERR(verify_entry(entries, "z"));
-    }
-
-  return SVN_NO_ERROR;
-}
-
-
-/* If EXPR raises SVN_ERR_FS_PROP_BASEVALUE_MISMATCH, continue; else, fail
- * the test. */
-#define FAILS_WITH_BOV(expr) \
-  do { \
-      svn_error_t *__err = (expr); \
-      if (!__err || __err->apr_err != SVN_ERR_FS_PROP_BASEVALUE_MISMATCH) \
-        return svn_error_create(SVN_ERR_TEST_FAILED, __err, \
-                                "svn_fs_change_rev_prop2() failed to " \
-                                "detect unexpected old value"); \
-      else \
-        svn_error_clear(__err); \
-  } while (0)
-
-static svn_error_t *
-revision_props(const svn_test_opts_t *opts,
-               apr_pool_t *pool)
-{
-  svn_fs_t *fs;
-  apr_hash_t *proplist;
-  svn_string_t *value;
-  int i;
-  svn_string_t s1;
-
-  const char *initial_props[4][2] = {
-    { "color", "red" },
-    { "size", "XXL" },
-    { "favorite saturday morning cartoon", "looney tunes" },
-    { "auto", "Green 1997 Saturn SL1" }
-    };
-
-  const char *final_props[4][2] = {
-    { "color", "violet" },
-    { "flower", "violet" },
-    { "favorite saturday morning cartoon", "looney tunes" },
-    { "auto", "Red 2000 Chevrolet Blazer" }
-    };
-
-  /* Open the fs */
-  SVN_ERR(svn_test__create_fs(&fs, "test-repo-rev-props",
-                              opts, pool));
-
-  /* Set some properties on the revision. */
-  for (i = 0; i < 4; i++)
-    {
-      SET_STR(&s1, initial_props[i][1]);
-      SVN_ERR(svn_fs_change_rev_prop(fs, 0, initial_props[i][0], &s1, pool));
-    }
-
-  /* Change some of the above properties. */
-  SET_STR(&s1, "violet");
-  SVN_ERR(svn_fs_change_rev_prop(fs, 0, "color", &s1, pool));
-
-  SET_STR(&s1, "Red 2000 Chevrolet Blazer");
-  SVN_ERR(svn_fs_change_rev_prop(fs, 0, "auto", &s1, pool));
-
-  /* Remove a property altogether */
-  SVN_ERR(svn_fs_change_rev_prop(fs, 0, "size", NULL, pool));
-
-  /* Copy a property's value into a new property. */
-  SVN_ERR(svn_fs_revision_prop(&value, fs, 0, "color", pool));
-  SVN_TEST_ASSERT(value);
-
-  s1.data = value->data;
-  s1.len = value->len;
-  SVN_ERR(svn_fs_change_rev_prop(fs, 0, "flower", &s1, pool));
-
-  /* Test svn_fs_change_rev_prop2().  If the whole block goes through, then
-   * it is a no-op (it undoes all changes it makes). */
-    {
-      const svn_string_t s2 = { "wrong value", 11 };
-      const svn_string_t *s2_p = &s2;
-      const svn_string_t *s1_p = &s1;
-      const svn_string_t *unset = NULL;
-      const svn_string_t *s1_dup;
-
-      /* Value of "flower" is 's1'. */
-
-      FAILS_WITH_BOV(svn_fs_change_rev_prop2(fs, 0, "flower", &s2_p, s1_p, pool));
-      s1_dup = svn_string_dup(&s1, pool);
-      SVN_ERR(svn_fs_change_rev_prop2(fs, 0, "flower", &s1_dup, s2_p, pool));
-
-      /* Value of "flower" is 's2'. */
-
-      FAILS_WITH_BOV(svn_fs_change_rev_prop2(fs, 0, "flower", &s1_p, NULL, pool));
-      SVN_ERR(svn_fs_change_rev_prop2(fs, 0, "flower", &s2_p, NULL, pool));
-
-      /* Value of "flower" is <not set>. */
-
-      FAILS_WITH_BOV(svn_fs_change_rev_prop2(fs, 0, "flower", &s2_p, s1_p, pool));
-      SVN_ERR(svn_fs_change_rev_prop2(fs, 0, "flower", &unset, s1_p, pool));
-
-      /* Value of "flower" is 's1'. */
-    }
-
-  /* Obtain a list of all current properties, and make sure it matches
-     the expected values. */
-  SVN_ERR(svn_fs_revision_proplist(&proplist, fs, 0, pool));
-  SVN_TEST_ASSERT(proplist);
-  {
-    svn_string_t *prop_value;
-
-    if (apr_hash_count(proplist) < 4 )
-      return svn_error_createf
-        (SVN_ERR_FS_GENERAL, NULL,
-         "too few revision properties found");
-
-    /* Loop through our list of expected revision property name/value
-       pairs. */
-    for (i = 0; i < 4; i++)
-      {
-        /* For each expected property: */
-
-        /* Step 1.  Find it by name in the hash of all rev. props
-           returned to us by svn_fs_revision_proplist.  If it can't be
-           found, return an error. */
-        prop_value = apr_hash_get(proplist,
-                                  final_props[i][0],
-                                  APR_HASH_KEY_STRING);
-        if (! prop_value)
-          return svn_error_createf
-            (SVN_ERR_FS_GENERAL, NULL,
-             "unable to find expected revision property");
-
-        /* Step 2.  Make sure the value associated with it is the same
-           as what was expected, else return an error. */
-        if (strcmp(prop_value->data, final_props[i][1]))
-          return svn_error_createf
-            (SVN_ERR_FS_GENERAL, NULL,
-             "revision property had an unexpected value");
-      }
-  }
-
-  return SVN_NO_ERROR;
-}
-
-
-static svn_error_t *
-transaction_props(const svn_test_opts_t *opts,
-                  apr_pool_t *pool)
-{
-  svn_fs_t *fs;
-  svn_fs_txn_t *txn;
-  apr_hash_t *proplist;
-  svn_string_t *value;
-  svn_revnum_t after_rev;
-  int i;
-  svn_string_t s1;
-
-  const char *initial_props[4][2] = {
-    { "color", "red" },
-    { "size", "XXL" },
-    { "favorite saturday morning cartoon", "looney tunes" },
-    { "auto", "Green 1997 Saturn SL1" }
-    };
-
-  const char *final_props[5][2] = {
-    { "color", "violet" },
-    { "flower", "violet" },
-    { "favorite saturday morning cartoon", "looney tunes" },
-    { "auto", "Red 2000 Chevrolet Blazer" },
-    { SVN_PROP_REVISION_DATE, "<some datestamp value>" }
-    };
-
-  /* Open the fs */
-  SVN_ERR(svn_test__create_fs(&fs, "test-repo-txn-props",
-                              opts, pool));
-  SVN_ERR(svn_fs_begin_txn(&txn, fs, 0, pool));
-
-  /* Set some properties on the revision. */
-  for (i = 0; i < 4; i++)
-    {
-      SET_STR(&s1, initial_props[i][1]);
-      SVN_ERR(svn_fs_change_txn_prop(txn, initial_props[i][0], &s1, pool));
-    }
-
-  /* Change some of the above properties. */
-  SET_STR(&s1, "violet");
-  SVN_ERR(svn_fs_change_txn_prop(txn, "color", &s1, pool));
-
-  SET_STR(&s1, "Red 2000 Chevrolet Blazer");
-  SVN_ERR(svn_fs_change_txn_prop(txn, "auto", &s1, pool));
-
-  /* Remove a property altogether */
-  SVN_ERR(svn_fs_change_txn_prop(txn, "size", NULL, pool));
-
-  /* Copy a property's value into a new property. */
-  SVN_ERR(svn_fs_txn_prop(&value, txn, "color", pool));
-
-  s1.data = value->data;
-  s1.len = value->len;
-  SVN_ERR(svn_fs_change_txn_prop(txn, "flower", &s1, pool));
-
-  /* Obtain a list of all current properties, and make sure it matches
-     the expected values. */
-  SVN_ERR(svn_fs_txn_proplist(&proplist, txn, pool));
-  {
-    svn_string_t *prop_value;
-
-    /* All transactions get a datestamp property at their inception,
-       so we expect *5*, not 4 properties. */
-    if (apr_hash_count(proplist) != 5 )
-      return svn_error_createf
-        (SVN_ERR_FS_GENERAL, NULL,
-         "unexpected number of transaction properties were found");
-
-    /* Loop through our list of expected revision property name/value
-       pairs. */
-    for (i = 0; i < 5; i++)
-      {
-        /* For each expected property: */
-
-        /* Step 1.  Find it by name in the hash of all rev. props
-           returned to us by svn_fs_revision_proplist.  If it can't be
-           found, return an error. */
-        prop_value = apr_hash_get(proplist,
-                                  final_props[i][0],
-                                  APR_HASH_KEY_STRING);
-        if (! prop_value)
-          return svn_error_createf
-            (SVN_ERR_FS_GENERAL, NULL,
-             "unable to find expected transaction property");
-
-        /* Step 2.  Make sure the value associated with it is the same
-           as what was expected, else return an error. */
-        if (strcmp(final_props[i][0], SVN_PROP_REVISION_DATE))
-          if (strcmp(prop_value->data, final_props[i][1]))
-            return svn_error_createf
-              (SVN_ERR_FS_GENERAL, NULL,
-               "transaction property had an unexpected value");
-      }
-  }
-
-  /* Commit the transaction. */
-  SVN_ERR(test_commit_txn(&after_rev, txn, NULL, pool));
-  if (after_rev != 1)
-    return svn_error_createf
-      (SVN_ERR_FS_GENERAL, NULL,
-       "committed transaction got wrong revision number");
-
-  /* Obtain a list of all properties on the new revision, and make
-     sure it matches the expected values.  If you're wondering, the
-     expected values should be the exact same set of properties that
-     existed on the transaction just prior to its being committed. */
-  SVN_ERR(svn_fs_revision_proplist(&proplist, fs, after_rev, pool));
-  {
-    svn_string_t *prop_value;
-
-    if (apr_hash_count(proplist) < 5 )
-      return svn_error_createf
-        (SVN_ERR_FS_GENERAL, NULL,
-         "unexpected number of revision properties were found");
-
-    /* Loop through our list of expected revision property name/value
-       pairs. */
-    for (i = 0; i < 5; i++)
-      {
-        /* For each expected property: */
-
-        /* Step 1.  Find it by name in the hash of all rev. props
-           returned to us by svn_fs_revision_proplist.  If it can't be
-           found, return an error. */
-        prop_value = apr_hash_get(proplist,
-                                  final_props[i][0],
-                                  APR_HASH_KEY_STRING);
-        if (! prop_value)
-          return svn_error_createf
-            (SVN_ERR_FS_GENERAL, NULL,
-             "unable to find expected revision property");
-
-        /* Step 2.  Make sure the value associated with it is the same
-           as what was expected, else return an error. */
-        if (strcmp(final_props[i][0], SVN_PROP_REVISION_DATE))
-          if (strcmp(prop_value->data, final_props[i][1]))
-            return svn_error_createf
-              (SVN_ERR_FS_GENERAL, NULL,
-               "revision property had an unexpected value");
-      }
-  }
-
-  return SVN_NO_ERROR;
-}
-
-
-static svn_error_t *
-node_props(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;
-  apr_hash_t *proplist;
-  svn_string_t *value;
-  int i;
-  svn_string_t s1;
-
-  const char *initial_props[4][2] = {
-    { "Best Rock Artist", "Creed" },
-    { "Best Rap Artist", "Eminem" },
-    { "Best Country Artist", "(null)" },
-    { "Best Sound Designer", "Pluessman" }
-    };
-
-  const char *final_props[4][2] = {
-    { "Best Rock Artist", "P.O.D." },
-    { "Best Rap Artist", "Busta Rhymes" },
-    { "Best Sound Designer", "Pluessman" },
-    { "Biggest Cakewalk Fanatic", "Pluessman" }
-    };
-
-  /* Open the fs and transaction */
-  SVN_ERR(svn_test__create_fs(&fs, "test-repo-node-props",
-                              opts, pool));
-  SVN_ERR(svn_fs_begin_txn(&txn, fs, 0, pool));
-  SVN_ERR(svn_fs_txn_root(&txn_root, txn, pool));
-
-  /* Make a node to put some properties into */
-  SVN_ERR(svn_fs_make_file(txn_root, "music.txt", pool));
-
-  /* Set some properties on the nodes. */
-  for (i = 0; i < 4; i++)
-    {
-      SET_STR(&s1, initial_props[i][1]);
-      SVN_ERR(svn_fs_change_node_prop
-              (txn_root, "music.txt", initial_props[i][0], &s1, pool));
-    }
-
-  /* Change some of the above properties. */
-  SET_STR(&s1, "P.O.D.");
-  SVN_ERR(svn_fs_change_node_prop(txn_root, "music.txt", "Best Rock Artist",
-                                  &s1, pool));
-
-  SET_STR(&s1, "Busta Rhymes");
-  SVN_ERR(svn_fs_change_node_prop(txn_root, "music.txt", "Best Rap Artist",
-                                  &s1, pool));
-
-  /* Remove a property altogether */
-  SVN_ERR(svn_fs_change_node_prop(txn_root, "music.txt",
-                                  "Best Country Artist", NULL, pool));
-
-  /* Copy a property's value into a new property. */
-  SVN_ERR(svn_fs_node_prop(&value, txn_root, "music.txt",
-                           "Best Sound Designer", pool));
-
-  s1.data = value->data;
-  s1.len = value->len;
-  SVN_ERR(svn_fs_change_node_prop(txn_root, "music.txt",
-                                  "Biggest Cakewalk Fanatic", &s1, pool));
-
-  /* Obtain a list of all current properties, and make sure it matches
-     the expected values. */
-  SVN_ERR(svn_fs_node_proplist(&proplist, txn_root, "music.txt", pool));
-  {
-    svn_string_t *prop_value;
-
-    if (apr_hash_count(proplist) != 4 )
-      return svn_error_createf
-        (SVN_ERR_FS_GENERAL, NULL,
-         "unexpected number of node properties were found");
-
-    /* Loop through our list of expected node property name/value
-       pairs. */
-    for (i = 0; i < 4; i++)
-      {
-        /* For each expected property: */
-
-        /* Step 1.  Find it by name in the hash of all node props
-           returned to us by svn_fs_node_proplist.  If it can't be
-           found, return an error. */
-        prop_value = apr_hash_get(proplist,
-                                  final_props[i][0],
-                                  APR_HASH_KEY_STRING);
-        if (! prop_value)
-          return svn_error_createf
-            (SVN_ERR_FS_GENERAL, NULL,
-             "unable to find expected node property");
-
-        /* Step 2.  Make sure the value associated with it is the same
-           as what was expected, else return an error. */
-        if (strcmp(prop_value->data, final_props[i][1]))
-          return svn_error_createf
-            (SVN_ERR_FS_GENERAL, NULL,
-             "node property had an unexpected value");
-      }
-  }
-
-  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 = FALSE;
-  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 = TRUE;
-  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;
-}
-
-
-/* Fetch the youngest revision from a repos. */
-static svn_error_t *
-fetch_youngest_rev(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;
-  svn_revnum_t new_rev;
-  svn_revnum_t youngest_rev, new_youngest_rev;
-
-  SVN_ERR(svn_test__create_fs(&fs, "test-repo-youngest-rev",
-                              opts, pool));
-
-  /* Get youngest revision of brand spankin' new filesystem. */
-  SVN_ERR(svn_fs_youngest_rev(&youngest_rev, fs, pool));
-
-  /* Prepare a txn to receive the greek tree. */
-  SVN_ERR(svn_fs_begin_txn(&txn, fs, 0, pool));
-  SVN_ERR(svn_fs_txn_root(&txn_root, txn, pool));
-
-  /* Create the greek tree. */
-  SVN_ERR(svn_test__create_greek_tree(txn_root, pool));
-
-  /* Commit it. */
-  SVN_ERR(test_commit_txn(&new_rev, txn, NULL, pool));
-
-  /* Get the new youngest revision. */
-  SVN_ERR(svn_fs_youngest_rev(&new_youngest_rev, fs, pool));
-
-  if (youngest_rev == new_rev)
-    return svn_error_create(SVN_ERR_FS_GENERAL, NULL,
-                            "commit didn't bump up revision number");
-
-  if (new_youngest_rev != new_rev)
-    return svn_error_create(SVN_ERR_FS_GENERAL, NULL,
-                            "couldn't fetch youngest revision");
-
-  return SVN_NO_ERROR;
-}
-
-
-/* Test committing against an empty repository.
-   todo: also test committing against youngest? */
-static svn_error_t *
-basic_commit(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, *revision_root;
-  svn_revnum_t before_rev, after_rev;
-  const char *conflict;
-
-  /* Prepare a filesystem. */
-  SVN_ERR(svn_test__create_fs(&fs, "test-repo-basic-commit",
-                              opts, pool));
-
-  /* Save the current youngest revision. */
-  SVN_ERR(svn_fs_youngest_rev(&before_rev, fs, pool));
-
-  /* Prepare a txn to receive the greek tree. */
-  SVN_ERR(svn_fs_begin_txn(&txn, fs, 0, pool));
-  SVN_ERR(svn_fs_txn_root(&txn_root, txn, pool));
-
-  /* Paranoidly check that the current youngest rev is unchanged. */
-  SVN_ERR(svn_fs_youngest_rev(&after_rev, fs, pool));
-  if (after_rev != before_rev)
-    return svn_error_create
-      (SVN_ERR_FS_GENERAL, NULL,
-       "youngest revision changed unexpectedly");
-
-  /* Create the greek tree. */
-  SVN_ERR(svn_test__create_greek_tree(txn_root, pool));
-  SVN_TEST_ASSERT(svn_fs_is_txn_root(txn_root));
-  SVN_TEST_ASSERT(!svn_fs_is_revision_root(txn_root));
-
-  /* Commit it. */
-  SVN_ERR(svn_fs_commit_txn(&conflict, &after_rev, txn, pool));
-  SVN_TEST_ASSERT(SVN_IS_VALID_REVNUM(after_rev));
-
-  /* Make sure it's a different revision than before. */
-  if (after_rev == before_rev)
-    return svn_error_create
-      (SVN_ERR_FS_GENERAL, NULL,
-       "youngest revision failed to change");
-
-  /* Get root of the revision */
-  SVN_ERR(svn_fs_revision_root(&revision_root, fs, after_rev, pool));
-  SVN_TEST_ASSERT(!svn_fs_is_txn_root(revision_root));
-  SVN_TEST_ASSERT(svn_fs_is_revision_root(revision_root));
-
-  /* Check the tree. */
-  SVN_ERR(svn_test__check_greek_tree(revision_root, pool));
-
-  return SVN_NO_ERROR;
-}
-
-
-
-static svn_error_t *
-test_tree_node_validation(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, *revision_root;
-  svn_revnum_t after_rev;
-  const char *conflict;
-  apr_pool_t *subpool;
-
-  /* Prepare a filesystem. */
-  SVN_ERR(svn_test__create_fs(&fs, "test-repo-validate-tree-entries",
-                              opts, pool));
-
-  /* In a txn, create the greek tree. */
-  subpool = svn_pool_create(pool);
-  {
-    static svn_test__tree_entry_t expected_entries[] = {
-      /* path, contents (0 = dir) */
-      { "iota",        "This is the file 'iota'.\n" },
-      { "A",           0 },
-      { "A/mu",        "This is the file 'mu'.\n" },
-      { "A/B",         0 },
-      { "A/B/lambda",  "This is the file 'lambda'.\n" },
-      { "A/B/E",       0 },
-      { "A/B/E/alpha", "This is the file 'alpha'.\n" },
-      { "A/B/E/beta",  "This is the file 'beta'.\n" },
-      { "A/B/F",       0 },
-      { "A/C",         0 },
-      { "A/D",         0 },
-      { "A/D/gamma",   "This is the file 'gamma'.\n" },
-      { "A/D/G",       0 },
-      { "A/D/G/pi",    "This is the file 'pi'.\n" },
-      { "A/D/G/rho",   "This is the file 'rho'.\n" },
-      { "A/D/G/tau",   "This is the file 'tau'.\n" },
-      { "A/D/H",       0 },
-      { "A/D/H/chi",   "This is the file 'chi'.\n" },
-      { "A/D/H/psi",   "This is the file 'psi'.\n" },
-      { "A/D/H/omega", "This is the file 'omega'.\n" }
-    };
-    SVN_ERR(svn_fs_begin_txn(&txn, fs, 0, subpool));
-    SVN_ERR(svn_fs_txn_root(&txn_root, txn, subpool));
-    SVN_ERR(svn_test__create_greek_tree(txn_root, subpool));
-
-    /* Carefully validate that tree in the transaction. */
-    SVN_ERR(svn_test__validate_tree(txn_root, expected_entries, 20,
-                                    subpool));
-
-    /* Go ahead and commit the tree, and destroy the txn object.  */
-    SVN_ERR(svn_fs_commit_txn(&conflict, &after_rev, txn, subpool));
-    SVN_TEST_ASSERT(SVN_IS_VALID_REVNUM(after_rev));
-
-    /* Carefully validate that tree in the new revision, now. */
-    SVN_ERR(svn_fs_revision_root(&revision_root, fs, after_rev, subpool));
-    SVN_ERR(svn_test__validate_tree(revision_root, expected_entries, 20,
-                                    subpool));
-  }
-  svn_pool_destroy(subpool);
-
-  /* In a new txn, modify the greek tree. */
-  subpool = svn_pool_create(pool);
-  {
-    static svn_test__tree_entry_t expected_entries[] = {
-      /* path, contents (0 = dir) */
-      { "iota",          "This is a new version of 'iota'.\n" },
-      { "A",             0 },
-      { "A/B",           0 },
-      { "A/B/lambda",    "This is the file 'lambda'.\n" },
-      { "A/B/E",         0 },
-      { "A/B/E/alpha",   "This is the file 'alpha'.\n" },
-      { "A/B/E/beta",    "This is the file 'beta'.\n" },
-      { "A/B/F",         0 },
-      { "A/C",           0 },
-      { "A/C/kappa",     "This is the file 'kappa'.\n" },
-      { "A/D",           0 },
-      { "A/D/gamma",     "This is the file 'gamma'.\n" },
-      { "A/D/H",         0 },
-      { "A/D/H/chi",     "This is the file 'chi'.\n" },
-      { "A/D/H/psi",     "This is the file 'psi'.\n" },
-      { "A/D/H/omega",   "This is the file 'omega'.\n" },
-      { "A/D/I",         0 },
-      { "A/D/I/delta",   "This is the file 'delta'.\n" },
-      { "A/D/I/epsilon", "This is the file 'epsilon'.\n" }
-    };
-
-    SVN_ERR(svn_fs_begin_txn(&txn, fs, after_rev, subpool));
-    SVN_ERR(svn_fs_txn_root(&txn_root, txn, subpool));
-    SVN_ERR(svn_test__set_file_contents
-            (txn_root, "iota", "This is a new version of 'iota'.\n",
-             subpool));
-    SVN_ERR(svn_fs_delete(txn_root, "A/mu", subpool));
-    SVN_ERR(svn_fs_delete(txn_root, "A/D/G", subpool));
-    SVN_ERR(svn_fs_make_dir(txn_root, "A/D/I", subpool));
-    SVN_ERR(svn_fs_make_file(txn_root, "A/D/I/delta", subpool));
-    SVN_ERR(svn_test__set_file_contents
-            (txn_root, "A/D/I/delta", "This is the file 'delta'.\n",
-             subpool));
-    SVN_ERR(svn_fs_make_file(txn_root, "A/D/I/epsilon", subpool));
-    SVN_ERR(svn_test__set_file_contents
-            (txn_root, "A/D/I/epsilon", "This is the file 'epsilon'.\n",
-             subpool));
-    SVN_ERR(svn_fs_make_file(txn_root, "A/C/kappa", subpool));
-    SVN_ERR(svn_test__set_file_contents
-            (txn_root, "A/C/kappa", "This is the file 'kappa'.\n",
-             subpool));
-
-    /* Carefully validate that tree in the transaction. */
-    SVN_ERR(svn_test__validate_tree(txn_root, expected_entries, 19,
-                                    subpool));
-
-    /* Go ahead and commit the tree, and destroy the txn object.  */
-    SVN_ERR(svn_fs_commit_txn(&conflict, &after_rev, txn, subpool));
-    SVN_TEST_ASSERT(SVN_IS_VALID_REVNUM(after_rev));
-
-    /* Carefully validate that tree in the new revision, now. */
-    SVN_ERR(svn_fs_revision_root(&revision_root, fs, after_rev, subpool));
-    SVN_ERR(svn_test__validate_tree(revision_root, expected_entries,
-                                    19, subpool));
-  }
-  svn_pool_destroy(subpool);
-
-  return SVN_NO_ERROR;
-}
-
-
-/* Commit with merging (committing against non-youngest). */
-static svn_error_t *
-merging_commit(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, *revision_root;
-  svn_revnum_t after_rev;
-  svn_revnum_t revisions[24];
-  apr_size_t i;
-  svn_revnum_t revision_count;
-
-  /* Prepare a filesystem. */
-  SVN_ERR(svn_test__create_fs(&fs, "test-repo-merging-commit",
-                              opts, pool));
-
-  /* Initialize our revision number stuffs. */
-  for (i = 0;
-       i < ((sizeof(revisions)) / (sizeof(svn_revnum_t)));
-       i++)
-    revisions[i] = SVN_INVALID_REVNUM;
-  revision_count = 0;
-  revisions[revision_count++] = 0; /* the brand spankin' new revision */
-
-  /***********************************************************************/
-  /* REVISION 0 */
-  /***********************************************************************/
-
-  /* In one txn, create and commit the greek tree. */
-  SVN_ERR(svn_fs_begin_txn(&txn, fs, 0, pool));
-  SVN_ERR(svn_fs_txn_root(&txn_root, txn, pool));
-  SVN_ERR(svn_test__create_greek_tree(txn_root, pool));
-  SVN_ERR(test_commit_txn(&after_rev, txn, NULL, pool));
-
-  /***********************************************************************/
-  /* REVISION 1 */
-  /***********************************************************************/
-  {
-    static svn_test__tree_entry_t expected_entries[] = {
-      /* path, contents (0 = dir) */
-      { "iota",        "This is the file 'iota'.\n" },
-      { "A",           0 },
-      { "A/mu",        "This is the file 'mu'.\n" },
-      { "A/B",         0 },
-      { "A/B/lambda",  "This is the file 'lambda'.\n" },
-      { "A/B/E",       0 },
-      { "A/B/E/alpha", "This is the file 'alpha'.\n" },
-      { "A/B/E/beta",  "This is the file 'beta'.\n" },
-      { "A/B/F",       0 },
-      { "A/C",         0 },
-      { "A/D",         0 },
-      { "A/D/gamma",   "This is the file 'gamma'.\n" },
-      { "A/D/G",       0 },
-      { "A/D/G/pi",    "This is the file 'pi'.\n" },
-      { "A/D/G/rho",   "This is the file 'rho'.\n" },
-      { "A/D/G/tau",   "This is the file 'tau'.\n" },
-      { "A/D/H",       0 },
-      { "A/D/H/chi",   "This is the file 'chi'.\n" },
-      { "A/D/H/psi",   "This is the file 'psi'.\n" },
-      { "A/D/H/omega", "This is the file 'omega'.\n" }
-    };
-    SVN_ERR(svn_fs_revision_root(&revision_root, fs, after_rev, pool));
-    SVN_ERR(svn_test__validate_tree(revision_root, expected_entries,
-                                    20, pool));
-  }
-  revisions[revision_count++] = after_rev;
-
-  /* Let's add a directory and some files to the tree, and delete
-     'iota' */
-  SVN_ERR(svn_fs_begin_txn(&txn, fs, revisions[revision_count-1], pool));
-  SVN_ERR(svn_fs_txn_root(&txn_root, txn, pool));
-  SVN_ERR(svn_fs_make_dir(txn_root, "A/D/I", pool));
-  SVN_ERR(svn_fs_make_file(txn_root, "A/D/I/delta", pool));
-  SVN_ERR(svn_test__set_file_contents
-          (txn_root, "A/D/I/delta", "This is the file 'delta'.\n", pool));
-  SVN_ERR(svn_fs_make_file(txn_root, "A/D/I/epsilon", pool));
-  SVN_ERR(svn_test__set_file_contents
-          (txn_root, "A/D/I/epsilon", "This is the file 'epsilon'.\n", pool));
-  SVN_ERR(svn_fs_make_file(txn_root, "A/C/kappa", pool));
-  SVN_ERR(svn_test__set_file_contents
-          (txn_root, "A/C/kappa", "This is the file 'kappa'.\n", pool));
-  SVN_ERR(svn_fs_delete(txn_root, "iota", pool));
-  SVN_ERR(test_commit_txn(&after_rev, txn, NULL, pool));
-
-  /***********************************************************************/
-  /* REVISION 2 */
-  /***********************************************************************/
-  {
-    static svn_test__tree_entry_t expected_entries[] = {
-      /* path, contents (0 = dir) */
-      { "A",             0 },
-      { "A/mu",          "This is the file 'mu'.\n" },
-      { "A/B",           0 },
-      { "A/B/lambda",    "This is the file 'lambda'.\n" },
-      { "A/B/E",         0 },
-      { "A/B/E/alpha",   "This is the file 'alpha'.\n" },
-      { "A/B/E/beta",    "This is the file 'beta'.\n" },
-      { "A/B/F",         0 },
-      { "A/C",           0 },
-      { "A/C/kappa",     "This is the file 'kappa'.\n" },
-      { "A/D",           0 },
-      { "A/D/gamma",     "This is the file 'gamma'.\n" },
-      { "A/D/G",         0 },
-      { "A/D/G/pi",      "This is the file 'pi'.\n" },
-      { "A/D/G/rho",     "This is the file 'rho'.\n" },
-      { "A/D/G/tau",     "This is the file 'tau'.\n" },
-      { "A/D/H",         0 },
-      { "A/D/H/chi",     "This is the file 'chi'.\n" },
-      { "A/D/H/psi",     "This is the file 'psi'.\n" },
-      { "A/D/H/omega",   "This is the file 'omega'.\n" },
-      { "A/D/I",         0 },
-      { "A/D/I/delta",   "This is the file 'delta'.\n" },
-      { "A/D/I/epsilon", "This is the file 'epsilon'.\n" }
-    };
-    SVN_ERR(svn_fs_revision_root(&revision_root, fs, after_rev, pool));
-    SVN_ERR(svn_test__validate_tree(revision_root, expected_entries,
-                                    23, pool));
-  }
-  revisions[revision_count++] = after_rev;
-
-  /* We don't think the A/D/H directory is pulling its weight...let's
-     knock it off.  Oh, and let's re-add iota, too. */
-  SVN_ERR(svn_fs_begin_txn(&txn, fs, revisions[revision_count-1], pool));
-  SVN_ERR(svn_fs_txn_root(&txn_root, txn, pool));
-  SVN_ERR(svn_fs_delete(txn_root, "A/D/H", pool));
-  SVN_ERR(svn_fs_make_file(txn_root, "iota", pool));
-  SVN_ERR(svn_test__set_file_contents
-          (txn_root, "iota", "This is the new file 'iota'.\n", pool));
-  SVN_ERR(test_commit_txn(&after_rev, txn, NULL, pool));
-
-  /***********************************************************************/
-  /* REVISION 3 */
-  /***********************************************************************/
-  {
-    static svn_test__tree_entry_t expected_entries[] = {
-      /* path, contents (0 = dir) */
-      { "iota",          "This is the new file 'iota'.\n" },
-      { "A",             0 },
-      { "A/mu",          "This is the file 'mu'.\n" },
-      { "A/B",           0 },
-      { "A/B/lambda",    "This is the file 'lambda'.\n" },
-      { "A/B/E",         0 },
-      { "A/B/E/alpha",   "This is the file 'alpha'.\n" },
-      { "A/B/E/beta",    "This is the file 'beta'.\n" },
-      { "A/B/F",         0 },
-      { "A/C",           0 },
-      { "A/C/kappa",     "This is the file 'kappa'.\n" },
-      { "A/D",           0 },
-      { "A/D/gamma",     "This is the file 'gamma'.\n" },
-      { "A/D/G",         0 },
-      { "A/D/G/pi",      "This is the file 'pi'.\n" },
-      { "A/D/G/rho",     "This is the file 'rho'.\n" },
-      { "A/D/G/tau",     "This is the file 'tau'.\n" },
-      { "A/D/I",         0 },
-      { "A/D/I/delta",   "This is the file 'delta'.\n" },
-      { "A/D/I/epsilon", "This is the file 'epsilon'.\n" }
-    };
-    SVN_ERR(svn_fs_revision_root(&revision_root, fs, after_rev, pool));
-    SVN_ERR(svn_test__validate_tree(revision_root, expected_entries,
-                                    20, pool));
-  }
-  revisions[revision_count++] = after_rev;
-
-  /* Delete iota (yet again). */
-  SVN_ERR(svn_fs_begin_txn(&txn, fs, revisions[revision_count-1], pool));
-  SVN_ERR(svn_fs_txn_root(&txn_root, txn, pool));
-  SVN_ERR(svn_fs_delete(txn_root, "iota", pool));
-  SVN_ERR(test_commit_txn(&after_rev, txn, NULL, pool));
-
-  /***********************************************************************/
-  /* REVISION 4 */
-  /***********************************************************************/
-  {
-    static svn_test__tree_entry_t expected_entries[] = {
-      /* path, contents (0 = dir) */
-      { "A",             0 },
-      { "A/mu",          "This is the file 'mu'.\n" },
-      { "A/B",           0 },
-      { "A/B/lambda",    "This is the file 'lambda'.\n" },
-      { "A/B/E",         0 },
-      { "A/B/E/alpha",   "This is the file 'alpha'.\n" },
-      { "A/B/E/beta",    "This is the file 'beta'.\n" },
-      { "A/B/F",         0 },
-      { "A/C",           0 },
-      { "A/C/kappa",     "This is the file 'kappa'.\n" },
-      { "A/D",           0 },
-      { "A/D/gamma",     "This is the file 'gamma'.\n" },
-      { "A/D/G",         0 },
-      { "A/D/G/pi",      "This is the file 'pi'.\n" },
-      { "A/D/G/rho",     "This is the file 'rho'.\n" },
-      { "A/D/G/tau",     "This is the file 'tau'.\n" },
-      { "A/D/I",         0 },
-      { "A/D/I/delta",   "This is the file 'delta'.\n" },
-      { "A/D/I/epsilon", "This is the file 'epsilon'.\n" }
-    };
-    SVN_ERR(svn_fs_revision_root(&revision_root, fs, after_rev, pool));
-    SVN_ERR(svn_test__validate_tree(revision_root, expected_entries,
-                                    19, pool));
-  }
-  revisions[revision_count++] = after_rev;
-
-  /***********************************************************************/
-  /* GIVEN:  A and B, with common ancestor ANCESTOR, where A and B
-     directories, and E, an entry in either A, B, or ANCESTOR.
-
-     For every E, the following cases exist:
-      - E exists in neither ANCESTOR nor A.
-      - E doesn't exist in ANCESTOR, and has been added to A.
-      - E exists in ANCESTOR, but has been deleted from A.
-      - E exists in both ANCESTOR and A ...
-        - but refers to different node revisions.
-        - and refers to the same node revision.
-
-     The same set of possible relationships with ANCESTOR holds for B,
-     so there are thirty-six combinations.  The matrix is symmetrical
-     with A and B reversed, so we only have to describe one triangular
-     half, including the diagonal --- 21 combinations.
-
-     Our goal here is to test all the possible scenarios that can
-     occur given the above boolean logic table, and to make sure that
-     the results we get are as expected.
-
-     The test cases below have the following features:
-
-     - They run straight through the scenarios as described in the
-       `structure' document at this time.
-
-     - In each case, a txn is begun based on some revision (ANCESTOR),
-       is modified into a new tree (B), and then is attempted to be
-       committed (which happens against the head of the tree, A).
-
-     - If the commit is successful (and is *expected* to be such),
-       that new revision (which exists now as a result of the
-       successful commit) is thoroughly tested for accuracy of tree
-       entries, and in the case of files, for their contents.  It is
-       important to realize that these successful commits are
-       advancing the head of the tree, and each one effective becomes
-       the new `A' described in further test cases.
-  */
-  /***********************************************************************/
-
-  /* (6) E exists in neither ANCESTOR nor A. */
-  {
-    /* (1) E exists in neither ANCESTOR nor B.  Can't occur, by
-       assumption that E exists in either A, B, or ancestor. */
-
-    /* (1) E has been added to B.  Add E in the merged result. */
-    SVN_ERR(svn_fs_begin_txn(&txn, fs, revisions[0], pool));
-    SVN_ERR(svn_fs_txn_root(&txn_root, txn, pool));
-    SVN_ERR(svn_fs_make_file(txn_root, "theta", pool));
-    SVN_ERR(svn_test__set_file_contents
-            (txn_root, "theta", "This is the file 'theta'.\n", pool));
-    SVN_ERR(test_commit_txn(&after_rev, txn, NULL, pool));
-
-    /*********************************************************************/
-    /* REVISION 5 */
-    /*********************************************************************/
-    {
-      static svn_test__tree_entry_t expected_entries[] = {
-        /* path, contents (0 = dir) */
-        { "theta",         "This is the file 'theta'.\n" },
-        { "A",             0 },
-        { "A/mu",          "This is the file 'mu'.\n" },
-        { "A/B",           0 },
-        { "A/B/lambda",    "This is the file 'lambda'.\n" },
-        { "A/B/E",         0 },
-        { "A/B/E/alpha",   "This is the file 'alpha'.\n" },
-        { "A/B/E/beta",    "This is the file 'beta'.\n" },
-        { "A/B/F",         0 },
-        { "A/C",           0 },
-        { "A/C/kappa",     "This is the file 'kappa'.\n" },
-        { "A/D",           0 },
-        { "A/D/gamma",     "This is the file 'gamma'.\n" },
-        { "A/D/G",         0 },
-        { "A/D/G/pi",      "This is the file 'pi'.\n" },
-        { "A/D/G/rho",     "This is the file 'rho'.\n" },
-        { "A/D/G/tau",     "This is the file 'tau'.\n" },
-        { "A/D/I",         0 },
-        { "A/D/I/delta",   "This is the file 'delta'.\n" },
-        { "A/D/I/epsilon", "This is the file 'epsilon'.\n" }
-      };
-      SVN_ERR(svn_fs_revision_root(&revision_root, fs, after_rev, pool));
-      SVN_ERR(svn_test__validate_tree(revision_root,
-                                      expected_entries,
-                                      20, pool));
-    }
-    revisions[revision_count++] = after_rev;
-
-    /* (1) E has been deleted from B.  Can't occur, by assumption that
-       E doesn't exist in ANCESTOR. */
-
-    /* (3) E exists in both ANCESTOR and B.  Can't occur, by
-       assumption that E doesn't exist in ancestor. */
-  }
-
-  /* (5) E doesn't exist in ANCESTOR, and has been added to A. */
-  {
-    svn_revnum_t failed_rev;
-    /* (1) E doesn't exist in ANCESTOR, and has been added to B.
-       Conflict. */
-    SVN_ERR(svn_fs_begin_txn(&txn, fs, revisions[4], pool));
-    SVN_ERR(svn_fs_txn_root(&txn_root, txn, pool));
-    SVN_ERR(svn_fs_make_file(txn_root, "theta", pool));
-    SVN_ERR(svn_test__set_file_contents
-            (txn_root, "theta", "This is another file 'theta'.\n", pool));
-
-    /* TXN must actually be based upon revisions[4] (instead of HEAD). */
-    SVN_TEST_ASSERT(svn_fs_txn_base_revision(txn) == revisions[4]);
-
-    SVN_ERR(test_commit_txn(&failed_rev, txn, "/theta", pool));
-    SVN_ERR(svn_fs_abort_txn(txn, pool));
-
-    /* (1) E exists in ANCESTOR, but has been deleted from B.  Can't
-       occur, by assumption that E doesn't exist in ANCESTOR. */
-
-    /* (3) E exists in both ANCESTOR and B.  Can't occur, by assumption
-       that E doesn't exist in ANCESTOR. */
-
-    SVN_TEST_ASSERT(failed_rev == SVN_INVALID_REVNUM);
-  }
-
-  /* (4) E exists in ANCESTOR, but has been deleted from A */
-  {
-    /* (1) E exists in ANCESTOR, but has been deleted from B.  If
-       neither delete was a result of a rename, then omit E from the
-       merged tree.  Otherwise, conflict. */
-    /* ### cmpilato todo: the rename case isn't actually handled by
-       merge yet, so we know we won't get a conflict here. */
-    SVN_ERR(svn_fs_begin_txn(&txn, fs, revisions[1], pool));
-    SVN_ERR(svn_fs_txn_root(&txn_root, txn, pool));
-    SVN_ERR(svn_fs_delete(txn_root, "A/D/H", pool));
-
-    /* TXN must actually be based upon revisions[1] (instead of HEAD). */
-    SVN_TEST_ASSERT(svn_fs_txn_base_revision(txn) == revisions[1]);
-
-    /* We used to create the revision like this before fixing issue
-       #2751 -- Directory prop mods reverted in overlapping commits scenario.
-
-       But we now expect that to fail as out of date */
-    {
-      svn_revnum_t failed_rev;
-      SVN_ERR(test_commit_txn(&failed_rev, txn, "/A/D/H", pool));
-
-      SVN_TEST_ASSERT(failed_rev == SVN_INVALID_REVNUM);
-    }
-    /*********************************************************************/
-    /* REVISION 6 */
-    /*********************************************************************/
-    {
-      static svn_test__tree_entry_t expected_entries[] = {
-        /* path, contents (0 = dir) */
-        { "theta",         "This is the file 'theta'.\n" },
-        { "A",             0 },
-        { "A/mu",          "This is the file 'mu'.\n" },
-        { "A/B",           0 },
-        { "A/B/lambda",    "This is the file 'lambda'.\n" },
-        { "A/B/E",         0 },
-        { "A/B/E/alpha",   "This is the file 'alpha'.\n" },
-        { "A/B/E/beta",    "This is the file 'beta'.\n" },
-        { "A/B/F",         0 },
-        { "A/C",           0 },
-        { "A/C/kappa",     "This is the file 'kappa'.\n" },
-        { "A/D",           0 },
-        { "A/D/gamma",     "This is the file 'gamma'.\n" },
-        { "A/D/G",         0 },
-        { "A/D/G/pi",      "This is the file 'pi'.\n" },
-        { "A/D/G/rho",     "This is the file 'rho'.\n" },
-        { "A/D/G/tau",     "This is the file 'tau'.\n" },
-        { "A/D/I",         0 },
-        { "A/D/I/delta",   "This is the file 'delta'.\n" },
-        { "A/D/I/epsilon", "This is the file 'epsilon'.\n" }
-      };
-      SVN_ERR(svn_fs_revision_root(&revision_root, fs, after_rev, pool));
-      SVN_ERR(svn_test__validate_tree(revision_root,
-                                      expected_entries,
-                                      20, pool));
-    }
-    revisions[revision_count++] = after_rev;
-
-    /* Try deleting a file F inside a subtree S where S does not exist
-       in the most recent revision, but does exist in the ancestor
-       tree.  This should conflict. */
-    {
-      svn_revnum_t failed_rev;
-      SVN_ERR(svn_fs_begin_txn(&txn, fs, revisions[1], pool));
-      SVN_ERR(svn_fs_txn_root(&txn_root, txn, pool));
-      SVN_ERR(svn_fs_delete(txn_root, "A/D/H/omega", pool));
-      SVN_ERR(test_commit_txn(&failed_rev, txn, "/A/D/H", pool));
-      SVN_ERR(svn_fs_abort_txn(txn, pool));
-
-      SVN_TEST_ASSERT(failed_rev == SVN_INVALID_REVNUM);
-    }
-
-    /* E exists in both ANCESTOR and B ... */
-    {
-      /* (1) but refers to different nodes.  Conflict. */
-      SVN_ERR(svn_fs_begin_txn(&txn, fs, after_rev, pool));
-      SVN_ERR(svn_fs_txn_root(&txn_root, txn, pool));
-      SVN_ERR(svn_fs_make_dir(txn_root, "A/D/H", pool));
-      SVN_ERR(test_commit_txn(&after_rev, txn, NULL, pool));
-      revisions[revision_count++] = after_rev;
-
-      /*********************************************************************/
-      /* REVISION 7 */
-      /*********************************************************************/
-
-      /* Re-remove A/D/H because future tests expect it to be absent. */
-      {
-        SVN_ERR(svn_fs_begin_txn
-                (&txn, fs, revisions[revision_count - 1], pool));
-        SVN_ERR(svn_fs_txn_root(&txn_root, txn, pool));
-        SVN_ERR(svn_fs_delete(txn_root, "A/D/H", pool));
-        SVN_ERR(test_commit_txn(&after_rev, txn, NULL, pool));
-        revisions[revision_count++] = after_rev;
-      }
-
-      /*********************************************************************/
-      /* REVISION 8 (looks exactly like revision 6, we hope) */
-      /*********************************************************************/
-
-      /* (1) but refers to different revisions of the same node.
-         Conflict. */
-      SVN_ERR(svn_fs_begin_txn(&txn, fs, revisions[1], pool));
-      SVN_ERR(svn_fs_txn_root(&txn_root, txn, pool));
-      SVN_ERR(svn_fs_make_file(txn_root, "A/D/H/zeta", pool));
-      SVN_ERR(test_commit_txn(&after_rev, txn, "/A/D/H", pool));
-      SVN_ERR(svn_fs_abort_txn(txn, pool));
-
-      /* (1) and refers to the same node revision.  Omit E from the
-         merged tree.  This is already tested in Merge-Test 3
-         (A/D/H/chi, A/D/H/psi, e.g.), but we'll test it here again
-         anyway.  A little paranoia never hurt anyone.  */
-      SVN_ERR(svn_fs_begin_txn(&txn, fs, revisions[1], pool));
-      SVN_ERR(svn_fs_txn_root(&txn_root, txn, pool));
-      SVN_ERR(svn_fs_delete(txn_root, "A/mu", pool)); /* unrelated change */
-      SVN_ERR(test_commit_txn(&after_rev, txn, NULL, pool));
-
-      /*********************************************************************/
-      /* REVISION 9 */
-      /*********************************************************************/
-      {
-        static svn_test__tree_entry_t expected_entries[] = {
-          /* path, contents (0 = dir) */
-          { "theta",         "This is the file 'theta'.\n" },
-          { "A",             0 },
-          { "A/B",           0 },
-          { "A/B/lambda",    "This is the file 'lambda'.\n" },
-          { "A/B/E",         0 },
-          { "A/B/E/alpha",   "This is the file 'alpha'.\n" },
-          { "A/B/E/beta",    "This is the file 'beta'.\n" },
-          { "A/B/F",         0 },
-          { "A/C",           0 },
-          { "A/C/kappa",     "This is the file 'kappa'.\n" },
-          { "A/D",           0 },
-          { "A/D/gamma",     "This is the file 'gamma'.\n" },
-          { "A/D/G",         0 },
-          { "A/D/G/pi",      "This is the file 'pi'.\n" },
-          { "A/D/G/rho",     "This is the file 'rho'.\n" },
-          { "A/D/G/tau",     "This is the file 'tau'.\n" },
-          { "A/D/I",         0 },
-          { "A/D/I/delta",   "This is the file 'delta'.\n" },
-          { "A/D/I/epsilon", "This is the file 'epsilon'.\n" }
-        };
-        SVN_ERR(svn_fs_revision_root(&revision_root, fs, after_rev, pool));
-        SVN_ERR(svn_test__validate_tree(revision_root,
-                                        expected_entries,
-                                        19, pool));
-      }
-      revisions[revision_count++] = after_rev;
-    }
-  }
-
-  /* Preparation for upcoming tests.
-     We make a new head revision, with A/mu restored, but containing
-     slightly different contents than its first incarnation. */
-  SVN_ERR(svn_fs_begin_txn(&txn, fs, revisions[revision_count-1], pool));
-  SVN_ERR(svn_fs_txn_root(&txn_root, txn, pool));
-  SVN_ERR(svn_fs_make_file(txn_root, "A/mu", pool));
-  SVN_ERR(svn_test__set_file_contents
-          (txn_root, "A/mu", "A new file 'mu'.\n", pool));
-  SVN_ERR(svn_fs_make_file(txn_root, "A/D/G/xi", pool));
-  SVN_ERR(svn_test__set_file_contents
-          (txn_root, "A/D/G/xi", "This is the file 'xi'.\n", pool));
-  SVN_ERR(test_commit_txn(&after_rev, txn, NULL, pool));
-  /*********************************************************************/
-  /* REVISION 10 */
-  /*********************************************************************/
-  {
-    static svn_test__tree_entry_t expected_entries[] = {
-      /* path, contents (0 = dir) */
-      { "theta",         "This is the file 'theta'.\n" },
-      { "A",             0 },
-      { "A/mu",          "A new file 'mu'.\n" },
-      { "A/B",           0 },
-      { "A/B/lambda",    "This is the file 'lambda'.\n" },
-      { "A/B/E",         0 },
-      { "A/B/E/alpha",   "This is the file 'alpha'.\n" },
-      { "A/B/E/beta",    "This is the file 'beta'.\n" },
-      { "A/B/F",         0 },
-      { "A/C",           0 },
-      { "A/C/kappa",     "This is the file 'kappa'.\n" },
-      { "A/D",           0 },
-      { "A/D/gamma",     "This is the file 'gamma'.\n" },
-      { "A/D/G",         0 },
-      { "A/D/G/pi",      "This is the file 'pi'.\n" },
-      { "A/D/G/rho",     "This is the file 'rho'.\n" },
-      { "A/D/G/tau",     "This is the file 'tau'.\n" },
-      { "A/D/G/xi",      "This is the file 'xi'.\n" },
-      { "A/D/I",         0 },
-      { "A/D/I/delta",   "This is the file 'delta'.\n" },
-      { "A/D/I/epsilon", "This is the file 'epsilon'.\n" }
-    };
-    SVN_ERR(svn_fs_revision_root(&revision_root, fs, after_rev, pool));
-    SVN_ERR(svn_test__validate_tree(revision_root, expected_entries,
-                                    21, pool));
-  }
-  revisions[revision_count++] = after_rev;
-
-  /* (3) E exists in both ANCESTOR and A, but refers to different
-     nodes. */
-  {
-    /* (1) E exists in both ANCESTOR and B, but refers to different
-       nodes, and not all nodes are directories.  Conflict. */
-
-    /* ### kff todo: A/mu's contents will be exactly the same.
-       If the fs ever starts optimizing this case, these tests may
-       start to fail. */
-    SVN_ERR(svn_fs_begin_txn(&txn, fs, revisions[1], pool));
-    SVN_ERR(svn_fs_txn_root(&txn_root, txn, pool));
-    SVN_ERR(svn_fs_delete(txn_root, "A/mu", pool));
-    SVN_ERR(svn_fs_make_file(txn_root, "A/mu", pool));
-    SVN_ERR(svn_test__set_file_contents
-            (txn_root, "A/mu", "This is the file 'mu'.\n", pool));
-    SVN_ERR(test_commit_txn(&after_rev, txn, "/A/mu", pool));
-    SVN_ERR(svn_fs_abort_txn(txn, pool));
-
-    /* (1) E exists in both ANCESTOR and B, but refers to different
-       revisions of the same node.  Conflict. */
-    SVN_ERR(svn_fs_begin_txn(&txn, fs, revisions[1], pool));
-    SVN_ERR(svn_fs_txn_root(&txn_root, txn, pool));
-    SVN_ERR(svn_test__set_file_contents
-            (txn_root, "A/mu", "A change to file 'mu'.\n", pool));
-    SVN_ERR(test_commit_txn(&after_rev, txn, "/A/mu", pool));
-    SVN_ERR(svn_fs_abort_txn(txn, pool));
-
-    /* (1) E exists in both ANCESTOR and B, and refers to the same
-       node revision.  Replace E with A's node revision.  */
-    {
-      svn_stringbuf_t *old_mu_contents;
-      SVN_ERR(svn_fs_begin_txn(&txn, fs, revisions[1], pool));
-      SVN_ERR(svn_fs_txn_root(&txn_root, txn, pool));
-      SVN_ERR(svn_test__get_file_contents
-              (txn_root, "A/mu", &old_mu_contents, pool));
-      if ((! old_mu_contents) || (strcmp(old_mu_contents->data,
-                                         "This is the file 'mu'.\n") != 0))
-        {
-          return svn_error_create
-            (SVN_ERR_FS_GENERAL, NULL,
-             "got wrong contents from an old revision tree");
-        }
-      SVN_ERR(svn_fs_make_file(txn_root, "A/sigma", pool));
-      SVN_ERR(svn_test__set_file_contents  /* unrelated change */
-              (txn_root, "A/sigma", "This is the file 'sigma'.\n", pool));
-      SVN_ERR(test_commit_txn(&after_rev, txn, NULL, pool));
-      /*********************************************************************/
-      /* REVISION 11 */
-      /*********************************************************************/
-      {
-        static svn_test__tree_entry_t expected_entries[] = {
-          /* path, contents (0 = dir) */
-          { "theta",         "This is the file 'theta'.\n" },
-          { "A",             0 },
-          { "A/mu",          "A new file 'mu'.\n" },
-          { "A/sigma",       "This is the file 'sigma'.\n" },
-          { "A/B",           0 },
-          { "A/B/lambda",    "This is the file 'lambda'.\n" },
-          { "A/B/E",         0 },
-          { "A/B/E/alpha",   "This is the file 'alpha'.\n" },
-          { "A/B/E/beta",    "This is the file 'beta'.\n" },
-          { "A/B/F",         0 },
-          { "A/C",           0 },
-          { "A/C/kappa",     "This is the file 'kappa'.\n" },
-          { "A/D",           0 },
-          { "A/D/gamma",     "This is the file 'gamma'.\n" },
-          { "A/D/G",         0 },
-          { "A/D/G/pi",      "This is the file 'pi'.\n" },
-          { "A/D/G/rho",     "This is the file 'rho'.\n" },
-          { "A/D/G/tau",     "This is the file 'tau'.\n" },
-          { "A/D/G/xi",      "This is the file 'xi'.\n" },
-          { "A/D/I",         0 },
-          { "A/D/I/delta",   "This is the file 'delta'.\n" },
-          { "A/D/I/epsilon", "This is the file 'epsilon'.\n" }
-        };
-        SVN_ERR(svn_fs_revision_root(&revision_root, fs, after_rev, pool));
-        SVN_ERR(svn_test__validate_tree(revision_root,
-                                        expected_entries,
-                                        22, pool));
-      }
-      revisions[revision_count++] = after_rev;
-    }
-  }
-
-  /* Preparation for upcoming tests.
-     We make a new head revision.  There are two changes in the new
-     revision: A/B/lambda has been modified.  We will also use the
-     recent addition of A/D/G/xi, treated as a modification to
-     A/D/G. */
-  SVN_ERR(svn_fs_begin_txn(&txn, fs, revisions[revision_count-1], pool));
-  SVN_ERR(svn_fs_txn_root(&txn_root, txn, pool));
-  SVN_ERR(svn_test__set_file_contents
-          (txn_root, "A/B/lambda", "Change to file 'lambda'.\n", pool));
-  SVN_ERR(test_commit_txn(&after_rev, txn, NULL, pool));
-  /*********************************************************************/
-  /* REVISION 12 */
-  /*********************************************************************/
-  {
-    static svn_test__tree_entry_t expected_entries[] = {
-      /* path, contents (0 = dir) */
-      { "theta",         "This is the file 'theta'.\n" },
-      { "A",             0 },
-      { "A/mu",          "A new file 'mu'.\n" },
-      { "A/sigma",       "This is the file 'sigma'.\n" },
-      { "A/B",           0 },
-      { "A/B/lambda",    "Change to file 'lambda'.\n" },
-      { "A/B/E",         0 },
-      { "A/B/E/alpha",   "This is the file 'alpha'.\n" },
-      { "A/B/E/beta",    "This is the file 'beta'.\n" },
-      { "A/B/F",         0 },
-      { "A/C",           0 },
-      { "A/C/kappa",     "This is the file 'kappa'.\n" },
-      { "A/D",           0 },
-      { "A/D/gamma",     "This is the file 'gamma'.\n" },
-      { "A/D/G",         0 },
-      { "A/D/G/pi",      "This is the file 'pi'.\n" },
-      { "A/D/G/rho",     "This is the file 'rho'.\n" },
-      { "A/D/G/tau",     "This is the file 'tau'.\n" },
-      { "A/D/G/xi",      "This is the file 'xi'.\n" },
-      { "A/D/I",         0 },
-      { "A/D/I/delta",   "This is the file 'delta'.\n" },
-      { "A/D/I/epsilon", "This is the file 'epsilon'.\n" }
-    };
-    SVN_ERR(svn_fs_revision_root(&revision_root, fs, after_rev, pool));
-    SVN_ERR(svn_test__validate_tree(revision_root, expected_entries,
-                                    22, pool));
-  }
-  revisions[revision_count++] = after_rev;
-
-  /* (2) E exists in both ANCESTOR and A, but refers to different
-     revisions of the same node. */
-  {
-    /* (1a) E exists in both ANCESTOR and B, but refers to different
-       revisions of the same file node.  Conflict. */
-    SVN_ERR(svn_fs_begin_txn(&txn, fs, revisions[1], pool));
-    SVN_ERR(svn_fs_txn_root(&txn_root, txn, pool));
-    SVN_ERR(svn_test__set_file_contents
-            (txn_root, "A/B/lambda", "A different change to 'lambda'.\n",
-             pool));
-    SVN_ERR(test_commit_txn(&after_rev, txn, "/A/B/lambda", pool));
-    SVN_ERR(svn_fs_abort_txn(txn, pool));
-
-    /* (1b) E exists in both ANCESTOR and B, but refers to different
-       revisions of the same directory node.  Merge A/E and B/E,
-       recursively.  Succeed, because no conflict beneath E. */
-    SVN_ERR(svn_fs_begin_txn(&txn, fs, revisions[1], pool));
-    SVN_ERR(svn_fs_txn_root(&txn_root, txn, pool));
-    SVN_ERR(svn_fs_make_file(txn_root, "A/D/G/nu", pool));
-    SVN_ERR(svn_test__set_file_contents
-            (txn_root, "A/D/G/nu", "This is the file 'nu'.\n", pool));
-    SVN_ERR(test_commit_txn(&after_rev, txn, NULL, pool));
-    /*********************************************************************/
-    /* REVISION 13 */
-    /*********************************************************************/
-    {
-      static svn_test__tree_entry_t expected_entries[] = {
-        /* path, contents (0 = dir) */
-        { "theta",         "This is the file 'theta'.\n" },
-        { "A",             0 },
-        { "A/mu",          "A new file 'mu'.\n" },
-        { "A/sigma",       "This is the file 'sigma'.\n" },
-        { "A/B",           0 },
-        { "A/B/lambda",    "Change to file 'lambda'.\n" },
-        { "A/B/E",         0 },
-        { "A/B/E/alpha",   "This is the file 'alpha'.\n" },
-        { "A/B/E/beta",    "This is the file 'beta'.\n" },
-        { "A/B/F",         0 },
-        { "A/C",           0 },
-        { "A/C/kappa",     "This is the file 'kappa'.\n" },
-        { "A/D",           0 },
-        { "A/D/gamma",     "This is the file 'gamma'.\n" },
-        { "A/D/G",         0 },
-        { "A/D/G/pi",      "This is the file 'pi'.\n" },
-        { "A/D/G/rho",     "This is the file 'rho'.\n" },
-        { "A/D/G/tau",     "This is the file 'tau'.\n" },
-        { "A/D/G/xi",      "This is the file 'xi'.\n" },
-        { "A/D/G/nu",      "This is the file 'nu'.\n" },
-        { "A/D/I",         0 },
-        { "A/D/I/delta",   "This is the file 'delta'.\n" },
-        { "A/D/I/epsilon", "This is the file 'epsilon'.\n" }
-      };
-      SVN_ERR(svn_fs_revision_root(&revision_root, fs, after_rev, pool));
-      SVN_ERR(svn_test__validate_tree(revision_root,
-                                      expected_entries,
-                                      23, pool));
-    }
-    revisions[revision_count++] = after_rev;
-
-    /* (1c) E exists in both ANCESTOR and B, but refers to different
-       revisions of the same directory node.  Merge A/E and B/E,
-       recursively.  Fail, because conflict beneath E. */
-    SVN_ERR(svn_fs_begin_txn(&txn, fs, revisions[1], pool));
-    SVN_ERR(svn_fs_txn_root(&txn_root, txn, pool));
-    SVN_ERR(svn_fs_make_file(txn_root, "A/D/G/xi", pool));
-    SVN_ERR(svn_test__set_file_contents
-            (txn_root, "A/D/G/xi", "This is a different file 'xi'.\n", pool));
-    SVN_ERR(test_commit_txn(&after_rev, txn, "/A/D/G/xi", pool));
-    SVN_ERR(svn_fs_abort_txn(txn, pool));
-
-    /* (1) E exists in both ANCESTOR and B, and refers to the same node
-       revision.  Replace E with A's node revision.  */
-    {
-      svn_stringbuf_t *old_lambda_ctnts;
-      SVN_ERR(svn_fs_begin_txn(&txn, fs, revisions[1], pool));
-      SVN_ERR(svn_fs_txn_root(&txn_root, txn, pool));
-      SVN_ERR(svn_test__get_file_contents
-              (txn_root, "A/B/lambda", &old_lambda_ctnts, pool));
-      if ((! old_lambda_ctnts)
-          || (strcmp(old_lambda_ctnts->data,
-                     "This is the file 'lambda'.\n") != 0))
-        {
-          return svn_error_create
-            (SVN_ERR_FS_GENERAL, NULL,
-             "got wrong contents from an old revision tree");
-        }
-      SVN_ERR(svn_test__set_file_contents
-              (txn_root, "A/D/G/rho",
-               "This is an irrelevant change to 'rho'.\n", pool));
-      SVN_ERR(test_commit_txn(&after_rev, txn, NULL, pool));
-      /*********************************************************************/
-      /* REVISION 14 */
-      /*********************************************************************/
-      {
-        static svn_test__tree_entry_t expected_entries[] = {
-          /* path, contents (0 = dir) */
-          { "theta",         "This is the file 'theta'.\n" },
-          { "A",             0 },
-          { "A/mu",          "A new file 'mu'.\n" },
-          { "A/sigma",       "This is the file 'sigma'.\n" },
-          { "A/B",           0 },
-          { "A/B/lambda",    "Change to file 'lambda'.\n" },
-          { "A/B/E",         0 },
-          { "A/B/E/alpha",   "This is the file 'alpha'.\n" },
-          { "A/B/E/beta",    "This is the file 'beta'.\n" },
-          { "A/B/F",         0 },
-          { "A/C",           0 },
-          { "A/C/kappa",     "This is the file 'kappa'.\n" },
-          { "A/D",           0 },
-          { "A/D/gamma",     "This is the file 'gamma'.\n" },
-          { "A/D/G",         0 },
-          { "A/D/G/pi",      "This is the file 'pi'.\n" },
-          { "A/D/G/rho",     "This is an irrelevant change to 'rho'.\n" },
-          { "A/D/G/tau",     "This is the file 'tau'.\n" },
-          { "A/D/G/xi",      "This is the file 'xi'.\n" },
-          { "A/D/G/nu",      "This is the file 'nu'.\n"},
-          { "A/D/I",         0 },
-          { "A/D/I/delta",   "This is the file 'delta'.\n" },
-          { "A/D/I/epsilon", "This is the file 'epsilon'.\n" }
-        };
-        SVN_ERR(svn_fs_revision_root(&revision_root, fs, after_rev, pool));
-        SVN_ERR(svn_test__validate_tree(revision_root,
-                                        expected_entries,
-                                        23, pool));
-      }
-      revisions[revision_count++] = after_rev;
-    }
-  }
-
-  /* (1) E exists in both ANCESTOR and A, and refers to the same node
-     revision. */
-  {
-    /* (1) E exists in both ANCESTOR and B, and refers to the same
-       node revision.  Nothing has happened to ANCESTOR/E, so no
-       change is necessary. */
-
-    /* This has now been tested about fifty-four trillion times.  We
-       don't need to test it again here. */
-  }
-
-  /* E exists in ANCESTOR, but has been deleted from A.  E exists in
-     both ANCESTOR and B but refers to different revisions of the same
-     node.  Conflict.  */
-  SVN_ERR(svn_fs_begin_txn(&txn, fs, revisions[1], pool));
-  SVN_ERR(svn_fs_txn_root(&txn_root, txn, pool));
-  SVN_ERR(svn_test__set_file_contents
-          (txn_root, "iota", "New contents for 'iota'.\n", pool));
-  SVN_ERR(test_commit_txn(&after_rev, txn, "/iota", pool));
-  SVN_ERR(svn_fs_abort_txn(txn, pool));
-
-  return SVN_NO_ERROR;
-}
-
-
-static svn_error_t *
-copy_test(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, *rev_root;
-  svn_revnum_t after_rev;
-
-  /* Prepare a filesystem. */
-  SVN_ERR(svn_test__create_fs(&fs, "test-repo-copy",
-                              opts, pool));
-
-  /* In first txn, create and commit the greek tree. */
-  SVN_ERR(svn_fs_begin_txn(&txn, fs, 0, pool));
-  SVN_ERR(svn_fs_txn_root(&txn_root, txn, pool));
-  SVN_ERR(svn_test__create_greek_tree(txn_root, pool));
-  SVN_ERR(test_commit_txn(&after_rev, txn, NULL, pool));
-
-  /* In second txn, copy the file A/D/G/pi into the subtree A/D/H as
-     pi2.  Change that file's contents to state its new name.  Along
-     the way, test that the copy history was preserved both during the
-     transaction and after the commit. */
-
-  SVN_ERR(svn_fs_revision_root(&rev_root, fs, after_rev, pool));
-  SVN_ERR(svn_fs_begin_txn(&txn, fs, after_rev, pool));
-  SVN_ERR(svn_fs_txn_root(&txn_root, txn, pool));
-  SVN_ERR(svn_fs_copy(rev_root, "A/D/G/pi",
-                      txn_root, "A/D/H/pi2",
-                      pool));
-  { /* Check that copy history was preserved. */
-    svn_revnum_t rev;
-    const char *path;
-
-    SVN_ERR(svn_fs_copied_from(&rev, &path, txn_root,
-                               "A/D/H/pi2", pool));
-
-    if (rev != after_rev)
-      return svn_error_create
-        (SVN_ERR_FS_GENERAL, NULL,
-         "pre-commit copy history not preserved (rev lost) for A/D/H/pi2");
-
-    if (strcmp(path, "/A/D/G/pi") != 0)
-      return svn_error_create
-        (SVN_ERR_FS_GENERAL, NULL,
-         "pre-commit copy history not preserved (path lost) for A/D/H/pi2");
-  }
-  SVN_ERR(svn_test__set_file_contents
-          (txn_root, "A/D/H/pi2", "This is the file 'pi2'.\n", pool));
-  SVN_ERR(test_commit_txn(&after_rev, txn, NULL, pool));
-
-  { /* Check that copy history is still preserved _after_ the commit. */
-    svn_fs_root_t *root;
-    svn_revnum_t rev;
-    const char *path;
-
-    SVN_ERR(svn_fs_revision_root(&root, fs, after_rev, pool));
-    SVN_ERR(svn_fs_copied_from(&rev, &path, root, "A/D/H/pi2", pool));
-
-    if (rev != (after_rev - 1))
-      return svn_error_create
-        (SVN_ERR_FS_GENERAL, NULL,
-         "post-commit copy history wrong (rev) for A/D/H/pi2");
-
-    if (strcmp(path, "/A/D/G/pi") != 0)
-      return svn_error_create
-        (SVN_ERR_FS_GENERAL, NULL,
-         "post-commit copy history wrong (path) for A/D/H/pi2");
-  }
-
-  /* Let's copy the copy we just made, to make sure copy history gets
-     chained correctly. */
-  SVN_ERR(svn_fs_revision_root(&rev_root, fs, after_rev, pool));
-  SVN_ERR(svn_fs_begin_txn(&txn, fs, after_rev, pool));
-  SVN_ERR(svn_fs_txn_root(&txn_root, txn, pool));
-  SVN_ERR(svn_fs_copy(rev_root, "A/D/H/pi2", txn_root, "A/D/H/pi3", pool));
-  SVN_ERR(test_commit_txn(&after_rev, txn, NULL, pool));
-  { /* Check the copy history. */
-    svn_fs_root_t *root;
-    svn_revnum_t rev;
-    const char *path;
-
-    /* Check that the original copy still has its old history. */
-    SVN_ERR(svn_fs_revision_root(&root, fs, (after_rev - 1), pool));
-    SVN_ERR(svn_fs_copied_from(&rev, &path, root, "A/D/H/pi2", pool));
-
-    if (rev != (after_rev - 2))
-      return svn_error_create
-        (SVN_ERR_FS_GENERAL, NULL,
-         "first copy history wrong (rev) for A/D/H/pi2");
-
-    if (strcmp(path, "/A/D/G/pi") != 0)
-      return svn_error_create
-        (SVN_ERR_FS_GENERAL, NULL,
-         "first copy history wrong (path) for A/D/H/pi2");
-
-    /* Check that the copy of the copy has the right history. */
-    SVN_ERR(svn_fs_revision_root(&root, fs, after_rev, pool));
-    SVN_ERR(svn_fs_copied_from(&rev, &path, root, "A/D/H/pi3", pool));
-
-    if (rev != (after_rev - 1))
-      return svn_error_create
-        (SVN_ERR_FS_GENERAL, NULL,
-         "second copy history wrong (rev) for A/D/H/pi3");
-
-    if (strcmp(path, "/A/D/H/pi2") != 0)
-      return svn_error_create
-        (SVN_ERR_FS_GENERAL, NULL,
-         "second copy history wrong (path) for A/D/H/pi3");
-  }
-
-  /* Commit a regular change to a copy, make sure the copy history
-     isn't inherited. */
-  SVN_ERR(svn_fs_revision_root(&rev_root, fs, after_rev, pool));
-  SVN_ERR(svn_fs_begin_txn(&txn, fs, after_rev, pool));
-  SVN_ERR(svn_fs_txn_root(&txn_root, txn, pool));
-  SVN_ERR(svn_test__set_file_contents
-          (txn_root, "A/D/H/pi3", "This is the file 'pi3'.\n", pool));
-  SVN_ERR(test_commit_txn(&after_rev, txn, NULL, pool));
-  { /* Check the copy history. */
-    svn_fs_root_t *root;
-    svn_revnum_t rev;
-    const char *path;
-
-    /* Check that the copy still has its history. */
-    SVN_ERR(svn_fs_revision_root(&root, fs, (after_rev - 1), pool));
-    SVN_ERR(svn_fs_copied_from(&rev, &path, root, "A/D/H/pi3", pool));
-
-    if (rev != (after_rev - 2))
-      return svn_error_create
-        (SVN_ERR_FS_GENERAL, NULL,
-         "copy history wrong (rev) for A/D/H/pi3");
-
-    if (strcmp(path, "/A/D/H/pi2") != 0)
-      return svn_error_create
-        (SVN_ERR_FS_GENERAL, NULL,
-         "copy history wrong (path) for A/D/H/pi3");
-
-    /* Check that the next revision after the copy has no copy history. */
-    SVN_ERR(svn_fs_revision_root(&root, fs, after_rev, pool));
-    SVN_ERR(svn_fs_copied_from(&rev, &path, root, "A/D/H/pi3", pool));
-
-    if (rev != SVN_INVALID_REVNUM)
-      return svn_error_create
-        (SVN_ERR_FS_GENERAL, NULL,
-         "copy history wrong (rev) for A/D/H/pi3");
-
-    if (path != NULL)
-      return svn_error_create
-        (SVN_ERR_FS_GENERAL, NULL,
-         "copy history wrong (path) for A/D/H/pi3");
-  }
-
-  /* Then, as if that wasn't fun enough, copy the whole subtree A/D/H
-     into the root directory as H2! */
-  SVN_ERR(svn_fs_revision_root(&rev_root, fs, after_rev, pool));
-  SVN_ERR(svn_fs_begin_txn(&txn, fs, after_rev, pool));
-  SVN_ERR(svn_fs_txn_root(&txn_root, txn, pool));
-  SVN_ERR(svn_fs_copy(rev_root, "A/D/H", txn_root, "H2", pool));
-  SVN_ERR(test_commit_txn(&after_rev, txn, NULL, pool));
-  { /* Check the copy history. */
-    svn_fs_root_t *root;
-    svn_revnum_t rev;
-    const char *path;
-
-    /* Check that the top of the copy has history. */
-    SVN_ERR(svn_fs_revision_root(&root, fs, after_rev, pool));
-    SVN_ERR(svn_fs_copied_from(&rev, &path, root, "H2", pool));
-
-    if (rev != (after_rev - 1))
-      return svn_error_create
-        (SVN_ERR_FS_GENERAL, NULL,
-         "copy history wrong (rev) for H2");
-
-    if (strcmp(path, "/A/D/H") != 0)
-      return svn_error_create
-        (SVN_ERR_FS_GENERAL, NULL,
-         "copy history wrong (path) for H2");
-
-    /* Check that a random file under H2 reports no copy history. */
-    SVN_ERR(svn_fs_copied_from(&rev, &path, root, "H2/omega", pool));
-
-    if (rev != SVN_INVALID_REVNUM)
-      return svn_error_create
-        (SVN_ERR_FS_GENERAL, NULL,
-         "copy history wrong (rev) for H2/omega");
-
-    if (path != NULL)
-      return svn_error_create
-        (SVN_ERR_FS_GENERAL, NULL,
-         "copy history wrong (path) for H2/omega");
-
-    /* Note that H2/pi2 still has copy history, though.  See the doc
-       string for svn_fs_copied_from() for more on this. */
-  }
-
-  /* Let's live dangerously.  What happens if we copy a path into one
-     of its own children.  Looping filesystem?  Cyclic ancestry?
-     Another West Virginia family tree with no branches?  We certainly
-     hope that's not the case. */
-  SVN_ERR(svn_fs_revision_root(&rev_root, fs, after_rev, pool));
-  SVN_ERR(svn_fs_begin_txn(&txn, fs, after_rev, pool));
-  SVN_ERR(svn_fs_txn_root(&txn_root, txn, pool));
-  SVN_ERR(svn_fs_copy(rev_root, "A/B", txn_root, "A/B/E/B", pool));
-  SVN_ERR(test_commit_txn(&after_rev, txn, NULL, pool));
-  { /* Check the copy history. */
-    svn_fs_root_t *root;
-    svn_revnum_t rev;
-    const char *path;
-
-    /* Check that the copy has history. */
-    SVN_ERR(svn_fs_revision_root(&root, fs, after_rev, pool));
-    SVN_ERR(svn_fs_copied_from(&rev, &path, root, "A/B/E/B", pool));
-
-    if (rev != (after_rev - 1))
-      return svn_error_create
-        (SVN_ERR_FS_GENERAL, NULL,
-         "copy history wrong (rev) for A/B/E/B");
-
-    if (strcmp(path, "/A/B") != 0)
-      return svn_error_create
-        (SVN_ERR_FS_GENERAL, NULL,
-         "copy history wrong (path) for A/B/E/B");
-
-    /* Check that the original does not have copy history. */
-    SVN_ERR(svn_fs_revision_root(&root, fs, after_rev, pool));
-    SVN_ERR(svn_fs_copied_from(&rev, &path, root, "A/B", pool));
-
-    if (rev != SVN_INVALID_REVNUM)
-      return svn_error_create
-        (SVN_ERR_FS_GENERAL, NULL,
-         "copy history wrong (rev) for A/B");
-
-    if (path != NULL)
-      return svn_error_create
-        (SVN_ERR_FS_GENERAL, NULL,
-         "copy history wrong (path) for A/B");
-  }
-
-  /* After all these changes, let's see if the filesystem looks as we
-     would expect it to. */
-  {
-    static svn_test__tree_entry_t expected_entries[] = {
-      /* path, contents (0 = dir) */
-      { "iota",        "This is the file 'iota'.\n" },
-      { "H2",          0 },
-      { "H2/chi",      "This is the file 'chi'.\n" },
-      { "H2/pi2",      "This is the file 'pi2'.\n" },
-      { "H2/pi3",      "This is the file 'pi3'.\n" },
-      { "H2/psi",      "This is the file 'psi'.\n" },
-      { "H2/omega",    "This is the file 'omega'.\n" },
-      { "A",           0 },
-      { "A/mu",        "This is the file 'mu'.\n" },
-      { "A/B",         0 },
-      { "A/B/lambda",  "This is the file 'lambda'.\n" },
-      { "A/B/E",       0 },
-      { "A/B/E/alpha", "This is the file 'alpha'.\n" },
-      { "A/B/E/beta",  "This is the file 'beta'.\n" },
-      { "A/B/E/B",         0 },
-      { "A/B/E/B/lambda",  "This is the file 'lambda'.\n" },
-      { "A/B/E/B/E",       0 },
-      { "A/B/E/B/E/alpha", "This is the file 'alpha'.\n" },
-      { "A/B/E/B/E/beta",  "This is the file 'beta'.\n" },
-      { "A/B/E/B/F",       0 },
-      { "A/B/F",       0 },
-      { "A/C",         0 },
-      { "A/D",         0 },
-      { "A/D/gamma",   "This is the file 'gamma'.\n" },
-      { "A/D/G",       0 },
-      { "A/D/G/pi",    "This is the file 'pi'.\n" },
-      { "A/D/G/rho",   "This is the file 'rho'.\n" },
-      { "A/D/G/tau",   "This is the file 'tau'.\n" },
-      { "A/D/H",       0 },
-      { "A/D/H/chi",   "This is the file 'chi'.\n" },
-      { "A/D/H/pi2",   "This is the file 'pi2'.\n" },
-      { "A/D/H/pi3",   "This is the file 'pi3'.\n" },
-      { "A/D/H/psi",   "This is the file 'psi'.\n" },
-      { "A/D/H/omega", "This is the file 'omega'.\n" }
-    };
-    SVN_ERR(svn_fs_revision_root(&rev_root, fs, after_rev, pool));
-    SVN_ERR(svn_test__validate_tree(rev_root, expected_entries,
-                                    34, pool));
-  }
-
-  return SVN_NO_ERROR;
-}
-
-
-/* This tests deleting of mutable nodes.  We build a tree in a
- * transaction, then try to delete various items in the tree.  We
- * never commit the tree, so every entry being deleted points to a
- * mutable node.
- *
- * ### todo: this test was written before commits worked.  It might
- * now be worthwhile to combine it with delete().
- */
-static svn_error_t *
-delete_mutables(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;
-  svn_error_t *err;
-
-  /* Prepare a txn to receive the greek tree. */
-  SVN_ERR(svn_test__create_fs(&fs, "test-repo-del-from-dir",
-                              opts, pool));
-  SVN_ERR(svn_fs_begin_txn(&txn, fs, 0, pool));
-  SVN_ERR(svn_fs_txn_root(&txn_root, txn, pool));
-
-  /* Create the greek tree. */
-  SVN_ERR(svn_test__create_greek_tree(txn_root, pool));
-
-  /* Baby, it's time to test like you've never tested before.  We do
-   * the following, in this order:
-   *
-   *    1. Delete a single file somewhere, succeed.
-   *    2. Delete two files of three, then make sure the third remains.
-   *    3. Delete the third and last file.
-   *    4. Try again to delete the dir, succeed.
-   *    5. Delete one of the natively empty dirs, succeed.
-   *    6. Try to delete root, fail.
-   *    7. Try to delete a top-level file, succeed.
-   *
-   * Specifically, that's:
-   *
-   *    1. Delete A/D/gamma.
-   *    2. Delete A/D/G/pi, A/D/G/rho.
-   *    3. Delete A/D/G/tau.
-   *    4. Try again to delete A/D/G, succeed.
-   *    5. Delete A/C.
-   *    6. Try to delete /, fail.
-   *    7. Try to delete iota, succeed.
-   *
-   * Before and after each deletion or attempted deletion, we probe
-   * the affected directory, to make sure everything is as it should
-   * be.
-   */
-
-  /* 1 */
-  {
-    const svn_fs_id_t *gamma_id;
-    SVN_ERR(svn_fs_node_id(&gamma_id, txn_root, "A/D/gamma", pool));
-    SVN_ERR(check_entry_present(txn_root, "A/D", "gamma", pool));
-    SVN_ERR(svn_fs_delete(txn_root, "A/D/gamma", pool));
-    SVN_ERR(check_entry_absent(txn_root, "A/D", "gamma", pool));
-  }
-
-  /* 2 */
-  {
-    const svn_fs_id_t *pi_id, *rho_id, *tau_id;
-    SVN_ERR(svn_fs_node_id(&pi_id, txn_root, "A/D/G/pi", pool));
-    SVN_ERR(svn_fs_node_id(&rho_id, txn_root, "A/D/G/rho", pool));
-    SVN_ERR(svn_fs_node_id(&tau_id, txn_root, "A/D/G/tau", pool));
-    SVN_ERR(check_entry_present(txn_root, "A/D/G", "pi", pool));
-    SVN_ERR(check_entry_present(txn_root, "A/D/G", "rho", pool));
-    SVN_ERR(check_entry_present(txn_root, "A/D/G", "tau", pool));
-    SVN_ERR(svn_fs_delete(txn_root, "A/D/G/pi", pool));
-    SVN_ERR(check_entry_absent(txn_root, "A/D/G", "pi", pool));
-    SVN_ERR(check_entry_present(txn_root, "A/D/G", "rho", pool));
-    SVN_ERR(check_entry_present(txn_root, "A/D/G", "tau", pool));
-    SVN_ERR(svn_fs_delete(txn_root, "A/D/G/rho", pool));

[... 4735 lines stripped ...]