You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by lg...@apache.org on 2010/02/18 10:35:35 UTC

svn commit: r911296 - in /subversion/trunk/subversion/tests: libsvn_ra_local/ra-local-test.c libsvn_repos/repos-test.c svn_test_fs.c svn_test_fs.h

Author: lgo
Date: Thu Feb 18 09:35:35 2010
New Revision: 911296

URL: http://svn.apache.org/viewvc?rev=911296&view=rev
Log:
Add a (partial) test for issue #3243, and move some common code to the
test framework for later reuse.

* subversion/tests/libsvn_repos/repos-test.c
  (test_get_file_revs): New test svn_repos_get_file_revs2.
  (file_rev_handler): Helper function.
  (test_funcs): Run the new test.

* subversion/tests/libsvn_ra_local/ra-local-test.c
  (global): Remove now unneeded includes.
  (make_and_open_local_repos): Update function call.
  (current_directory_url): Move function from here ...

* subversion/tests/svn_test_fs.c
  (svn_test__current_directory_url): ... to here.
  (svn_test__create_greek_tree_at): New test function, create greek
   tree at a path (doesn't have to be '/') in the repository.
  (svn_test__create_greek_tree): Wrap svn_test__create_greek_tree_at.
  (svn_test__create_blame_repository): Set up a new repo, similar to
   the one used to reproduce issue #3243.

* subversion/tests/svn_test_fs.h
  (svn_test__create_greek_tree_at,
   svn_test__create_blame_repository,
   svn_test__current_directory_url): New function declarations.

Modified:
    subversion/trunk/subversion/tests/libsvn_ra_local/ra-local-test.c
    subversion/trunk/subversion/tests/libsvn_repos/repos-test.c
    subversion/trunk/subversion/tests/svn_test_fs.c
    subversion/trunk/subversion/tests/svn_test_fs.h

Modified: subversion/trunk/subversion/tests/libsvn_ra_local/ra-local-test.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/libsvn_ra_local/ra-local-test.c?rev=911296&r1=911295&r2=911296&view=diff
==============================================================================
--- subversion/trunk/subversion/tests/libsvn_ra_local/ra-local-test.c (original)
+++ subversion/trunk/subversion/tests/libsvn_ra_local/ra-local-test.c Thu Feb 18 09:35:35 2010
@@ -26,15 +26,6 @@
 #include <apr_general.h>
 #include <apr_pools.h>
 
-#ifdef _MSC_VER
-#include <direct.h>
-#define getcwd _getcwd
-#else
-#include <unistd.h> /* for getcwd() */
-#endif
-
-#include "svn_string.h"
-#include "svn_utf.h"
 #include "svn_error.h"
 #include "svn_delta.h"
 #include "svn_ra.h"
@@ -49,36 +40,6 @@
 /** Helper routines. **/
 
 
-/* Helper function.  Set URL to a "file://" url for the current directory,
-   suffixed by the forward-slash-style relative path SUFFIX, performing all
-   allocation in POOL. */
-static svn_error_t *
-current_directory_url(const char **url,
-                      const char *suffix,
-                      apr_pool_t *pool)
-{
-  /* 8KB is a lot, but it almost guarantees that any path will fit. */
-  char curdir[8192];
-  const char *utf8_ls_curdir, *utf8_is_curdir, *unencoded_url;
-
-  if (! getcwd(curdir, sizeof(curdir)))
-    return svn_error_create(SVN_ERR_BASE, NULL, "getcwd() failed");
-
-  SVN_ERR(svn_utf_cstring_to_utf8(&utf8_ls_curdir, curdir, pool));
-  utf8_is_curdir = svn_path_internal_style(utf8_ls_curdir, pool);
-
-  unencoded_url = apr_psprintf(pool, "file://%s%s%s%s",
-                               (utf8_is_curdir[0] != '/') ? "/" : "",
-                               utf8_is_curdir,
-                               (suffix[0] && suffix[0] != '/') ? "/" : "",
-                               suffix);
-
-  *url = svn_path_uri_encode(unencoded_url, pool);
-
-  return SVN_NO_ERROR;
-}
-
-
 static svn_error_t *
 make_and_open_local_repos(svn_ra_session_t **session,
                           const char *repos_name,
@@ -94,7 +55,7 @@
   SVN_ERR(svn_test__create_repos(&repos, repos_name, opts, pool));
   SVN_ERR(svn_ra_initialize(pool));
 
-  SVN_ERR(current_directory_url(&url, repos_name, pool));
+  SVN_ERR(svn_test__current_directory_url(&url, repos_name, pool));
 
   SVN_ERR(svn_ra_open3(session,
                        url,
@@ -262,7 +223,7 @@
   /* Create a filesystem and repository */
   SVN_ERR(svn_test__create_repos(&repos, repos_path, opts, pool));
 
-  SVN_ERR(current_directory_url(&root_url, repos_path, pool));
+  SVN_ERR(svn_test__current_directory_url(&root_url, repos_path, pool));
   if (in_repos_path)
     url = apr_pstrcat(pool, root_url, in_repos_path, NULL);
   else

Modified: subversion/trunk/subversion/tests/libsvn_repos/repos-test.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/libsvn_repos/repos-test.c?rev=911296&r1=911295&r2=911296&view=diff
==============================================================================
--- subversion/trunk/subversion/tests/libsvn_repos/repos-test.c (original)
+++ subversion/trunk/subversion/tests/libsvn_repos/repos-test.c Thu Feb 18 09:35:35 2010
@@ -2340,6 +2340,118 @@
   return SVN_NO_ERROR;
 }
 
+
+/* Tests for svn_repos_get_file_revsN() */
+
+typedef struct {
+    svn_revnum_t rev;
+    const char *path;
+    svn_boolean_t result_of_merge;
+    const char *author;
+} file_revs_t;
+
+/* Finds the revision REV in the hash table passed in in BATON, and checks
+   if the PATH and RESULT_OF_MERGE match are as expected. */
+static svn_error_t *
+file_rev_handler(void *baton, const char *path, svn_revnum_t rev,
+                 apr_hash_t *rev_props, svn_boolean_t result_of_merge,
+                 svn_txdelta_window_handler_t *delta_handler,
+                 void **delta_baton, apr_array_header_t *prop_diffs,
+                 apr_pool_t *pool)
+{
+  apr_hash_t *ht = baton;
+  const char *author;
+  file_revs_t *file_rev = apr_hash_get(ht, &rev, sizeof(svn_revnum_t));
+
+  if (!file_rev)
+    return svn_error_createf(SVN_ERR_TEST_FAILED, NULL,
+                             "Revision rev info not expected for rev %ld "
+                             "from path %s",
+                             rev, path);
+
+  author = svn_prop_get_value(rev_props,
+                              SVN_PROP_REVISION_AUTHOR);
+
+  SVN_TEST_STRING_ASSERT(author, file_rev->author);
+  SVN_TEST_STRING_ASSERT(path, file_rev->path);
+  SVN_TEST_ASSERT(rev == file_rev->rev);
+  SVN_TEST_ASSERT(result_of_merge == file_rev->result_of_merge);
+
+  /* Remove this revision from this list so we'll be able to verify that we
+     have seen all expected revisions. */
+  apr_hash_set(ht, &rev, sizeof(svn_revnum_t), NULL);
+
+  return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+test_get_file_revs(const svn_test_opts_t *opts,
+                   apr_pool_t *pool)
+{
+  svn_repos_t *repos = NULL;
+  svn_fs_t *fs;
+  svn_revnum_t youngest_rev = 0;
+  apr_pool_t *subpool = svn_pool_create(pool);
+  int i;
+
+  file_revs_t trunk_results[] = {
+    { 2, "/trunk/A/mu", FALSE, "initial" },
+    { 3, "/trunk/A/mu", FALSE, "user-trunk" },
+    { 4, "/branches/1.0.x/A/mu", TRUE, "copy" },
+    { 5, "/trunk/A/mu", FALSE, "user-trunk" },
+    { 6, "/branches/1.0.x/A/mu", TRUE, "user-branch" },
+    { 7, "/branches/1.0.x/A/mu", TRUE, "user-merge1" },
+    { 8, "/trunk/A/mu", FALSE, "user-merge2" },
+  };
+  file_revs_t branch_results[] = {
+    { 2, "/trunk/A/mu", FALSE, "initial" },
+    { 3, "/trunk/A/mu", FALSE, "user-trunk" },
+    { 4, "/branches/1.0.x/A/mu", FALSE, "copy" },
+    { 5, "/trunk/A/mu", TRUE, "user-trunk" },
+    { 6, "/branches/1.0.x/A/mu", FALSE, "user-branch" },
+    { 7, "/branches/1.0.x/A/mu", FALSE, "user-merge1" },
+  };
+  apr_hash_t *ht_trunk_results = apr_hash_make(subpool);
+  apr_hash_t *ht_branch_results = apr_hash_make(subpool);
+
+  for (i = 0; i < sizeof(trunk_results) / sizeof(trunk_results[0]); i++)
+    apr_hash_set(ht_trunk_results, &trunk_results[i].rev,
+                 sizeof(svn_revnum_t), &trunk_results[i]);
+
+  for (i = 0; i < sizeof(branch_results) / sizeof(branch_results[0]); i++)
+    apr_hash_set(ht_branch_results, &branch_results[i].rev,
+                 sizeof(svn_revnum_t), &branch_results[i]);
+
+  /* Create the repository and verify blame results. */
+  SVN_ERR(svn_test__create_blame_repository(&repos, "test-repo-get-filerevs",
+                                            opts, subpool));
+  fs = svn_repos_fs(repos);
+
+  SVN_ERR(svn_fs_youngest_rev(&youngest_rev, fs, subpool));
+
+  /* Verify blame of /trunk/A/mu */
+  SVN_ERR(svn_repos_get_file_revs2(repos, "/trunk/A/mu", 0, youngest_rev,
+                                   1, NULL, NULL,
+                                   file_rev_handler,
+                                   ht_trunk_results,
+                                   subpool));
+  SVN_TEST_ASSERT(apr_hash_count(ht_trunk_results) == 0);
+
+  /* Verify blame of /branches/1.0.x/A/mu */
+  SVN_ERR(svn_repos_get_file_revs2(repos, "/branches/1.0.x/A/mu", 0,
+                                   youngest_rev,
+                                   1, NULL, NULL,
+                                   file_rev_handler,
+                                   ht_branch_results,
+                                   subpool));
+  SVN_TEST_ASSERT(apr_hash_count(ht_branch_results) == 0);
+
+  /* ### TODO: Verify blame of /branches/1.0.x/A/mu in range 6-7 */
+
+  svn_pool_destroy(subpool);
+
+  return SVN_NO_ERROR;
+}
 
 
 /* The test table.  */
@@ -2373,5 +2485,7 @@
                        "test if revprops are validated by repos"),
     SVN_TEST_OPTS_PASS(get_logs,
                        "test svn_repos_get_logs ranges and limits"),
+    SVN_TEST_OPTS_PASS(test_get_file_revs,
+                       "test svn_repos_get_file_revsN"),
     SVN_TEST_NULL
   };

Modified: subversion/trunk/subversion/tests/svn_test_fs.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/svn_test_fs.c?rev=911296&r1=911295&r2=911296&view=diff
==============================================================================
--- subversion/trunk/subversion/tests/svn_test_fs.c (original)
+++ subversion/trunk/subversion/tests/svn_test_fs.c Thu Feb 18 09:35:35 2010
@@ -24,8 +24,17 @@
 #include <string.h>
 #include <apr_pools.h>
 
+#ifdef _MSC_VER
+#include <direct.h>
+#define getcwd _getcwd
+#else
+#include <unistd.h> /* for getcwd() */
+#endif
+
 #include "svn_test.h"
 
+#include "svn_string.h"
+#include "svn_utf.h"
 #include "svn_pools.h"
 #include "svn_error.h"
 #include "svn_fs.h"
@@ -227,6 +236,36 @@
 }
 
 
+/* Helper function.  Set URL to a "file://" url for the current directory,
+   suffixed by the forward-slash-style relative path SUFFIX, performing all
+   allocation in POOL. */
+svn_error_t *
+svn_test__current_directory_url(const char **url,
+                                const char *suffix,
+                                apr_pool_t *pool)
+{
+  /* 8KB is a lot, but it almost guarantees that any path will fit. */
+  char curdir[8192];
+  const char *utf8_ls_curdir, *utf8_is_curdir, *unencoded_url;
+
+  if (! getcwd(curdir, sizeof(curdir)))
+    return svn_error_create(SVN_ERR_BASE, NULL, "getcwd() failed");
+
+  SVN_ERR(svn_utf_cstring_to_utf8(&utf8_ls_curdir, curdir, pool));
+  utf8_is_curdir = svn_path_internal_style(utf8_ls_curdir, pool);
+
+  unencoded_url = apr_psprintf(pool, "file://%s%s%s%s",
+                               (utf8_is_curdir[0] != '/') ? "/" : "",
+                               utf8_is_curdir,
+                               (suffix[0] && suffix[0] != '/') ? "/" : "",
+                               suffix);
+
+  *url = svn_path_uri_encode(unencoded_url, pool);
+
+  return SVN_NO_ERROR;
+}
+
+
 svn_error_t *
 svn_test__stream_to_string(svn_stringbuf_t **string,
                            svn_stream_t *stream,
@@ -606,55 +645,186 @@
   return SVN_NO_ERROR;
 }
 
-
+/**
+ * Loads the greek tree in a directory at ROOT_DIR under transaction TXN_ROOT.
+ * ROOT_DIR should be created by the caller.
+ *
+ * Note: this function will not commit the transaction.
+ */
+svn_error_t *
+svn_test__create_greek_tree_at(svn_fs_root_t *txn_root,
+                               const char *root_dir,
+                               apr_pool_t *pool)
+{
+  char *iota =     svn_relpath_join(root_dir, "iota", pool);
+  char *A =        svn_relpath_join(root_dir, "A", pool);
+  char *Amu =      svn_relpath_join(root_dir, "A/mu", pool);
+  char *AB =       svn_relpath_join(root_dir, "A/B", pool);
+  char *ABlambda = svn_relpath_join(root_dir, "A/B/lambda", pool);
+  char *ABE =      svn_relpath_join(root_dir, "A/B/E", pool);
+  char *ABEalpha = svn_relpath_join(root_dir, "A/B/E/alpha", pool);
+  char *ABEbeta =  svn_relpath_join(root_dir, "A/B/E/beta", pool);
+  char *ABF =      svn_relpath_join(root_dir, "A/B/F", pool);
+  char *AC =       svn_relpath_join(root_dir, "A/C", pool);
+  char *AD =       svn_relpath_join(root_dir, "A/D", pool);
+  char *ADgamma =  svn_relpath_join(root_dir, "A/D/gamma", pool);
+  char *ADG =      svn_relpath_join(root_dir, "A/D/G", pool);
+  char *ADGpi =    svn_relpath_join(root_dir, "A/D/G/pi", pool);
+  char *ADGrho =   svn_relpath_join(root_dir, "A/D/G/rho", pool);
+  char *ADGtau =   svn_relpath_join(root_dir, "A/D/G/tau", pool);
+  char *ADH =      svn_relpath_join(root_dir, "A/D/H", pool);
+  char *ADHchi =   svn_relpath_join(root_dir, "A/D/H/chi", pool);
+  char *ADHpsi =   svn_relpath_join(root_dir, "A/D/H/psi", pool);
+  char *ADHomega = svn_relpath_join(root_dir, "A/D/H/omega", pool);
+
+  SVN_ERR(svn_fs_make_file(txn_root, iota, pool));
+  SVN_ERR(svn_test__set_file_contents
+          (txn_root, iota, "This is the file 'iota'.\n", pool));
+  SVN_ERR(svn_fs_make_dir  (txn_root, A, pool));
+  SVN_ERR(svn_fs_make_file(txn_root, Amu, pool));
+  SVN_ERR(svn_test__set_file_contents
+          (txn_root, Amu, "This is the file 'mu'.\n", pool));
+  SVN_ERR(svn_fs_make_dir  (txn_root, AB, pool));
+  SVN_ERR(svn_fs_make_file(txn_root, ABlambda, pool));
+  SVN_ERR(svn_test__set_file_contents
+          (txn_root, ABlambda, "This is the file 'lambda'.\n", pool));
+  SVN_ERR(svn_fs_make_dir  (txn_root, ABE, pool));
+  SVN_ERR(svn_fs_make_file(txn_root, ABEalpha, pool));
+  SVN_ERR(svn_test__set_file_contents
+          (txn_root, ABEalpha, "This is the file 'alpha'.\n", pool));
+  SVN_ERR(svn_fs_make_file(txn_root, ABEbeta, pool));
+  SVN_ERR(svn_test__set_file_contents
+          (txn_root, ABEbeta, "This is the file 'beta'.\n", pool));
+  SVN_ERR(svn_fs_make_dir  (txn_root, ABF, pool));
+  SVN_ERR(svn_fs_make_dir  (txn_root, AC, pool));
+  SVN_ERR(svn_fs_make_dir  (txn_root, AD, pool));
+  SVN_ERR(svn_fs_make_file(txn_root, ADgamma, pool));
+  SVN_ERR(svn_test__set_file_contents
+          (txn_root, ADgamma, "This is the file 'gamma'.\n", pool));
+  SVN_ERR(svn_fs_make_dir  (txn_root, ADG, pool));
+  SVN_ERR(svn_fs_make_file(txn_root, ADGpi, pool));
+  SVN_ERR(svn_test__set_file_contents
+          (txn_root, ADGpi, "This is the file 'pi'.\n", pool));
+  SVN_ERR(svn_fs_make_file(txn_root, ADGrho, pool));
+  SVN_ERR(svn_test__set_file_contents
+          (txn_root, ADGrho, "This is the file 'rho'.\n", pool));
+  SVN_ERR(svn_fs_make_file(txn_root, ADGtau, pool));
+  SVN_ERR(svn_test__set_file_contents
+          (txn_root, ADGtau, "This is the file 'tau'.\n", pool));
+  SVN_ERR(svn_fs_make_dir  (txn_root, ADH, pool));
+  SVN_ERR(svn_fs_make_file(txn_root, ADHchi, pool));
+  SVN_ERR(svn_test__set_file_contents
+          (txn_root, ADHchi, "This is the file 'chi'.\n", pool));
+  SVN_ERR(svn_fs_make_file(txn_root, ADHpsi, pool));
+  SVN_ERR(svn_test__set_file_contents
+          (txn_root, ADHpsi, "This is the file 'psi'.\n", pool));
+  SVN_ERR(svn_fs_make_file(txn_root, ADHomega, pool));
+  SVN_ERR(svn_test__set_file_contents
+          (txn_root, ADHomega, "This is the file 'omega'.\n", pool));
+  return SVN_NO_ERROR;
+}
 
 svn_error_t *
 svn_test__create_greek_tree(svn_fs_root_t *txn_root,
                             apr_pool_t *pool)
 {
-  SVN_ERR(svn_fs_make_file(txn_root, "iota", pool));
-  SVN_ERR(svn_test__set_file_contents
-          (txn_root, "iota", "This is the file 'iota'.\n", pool));
-  SVN_ERR(svn_fs_make_dir  (txn_root, "A", 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(svn_fs_make_dir  (txn_root, "A/B", pool));
-  SVN_ERR(svn_fs_make_file(txn_root, "A/B/lambda", pool));
-  SVN_ERR(svn_test__set_file_contents
-          (txn_root, "A/B/lambda", "This is the file 'lambda'.\n", pool));
-  SVN_ERR(svn_fs_make_dir  (txn_root, "A/B/E", pool));
-  SVN_ERR(svn_fs_make_file(txn_root, "A/B/E/alpha", pool));
-  SVN_ERR(svn_test__set_file_contents
-          (txn_root, "A/B/E/alpha", "This is the file 'alpha'.\n", pool));
-  SVN_ERR(svn_fs_make_file(txn_root, "A/B/E/beta", pool));
-  SVN_ERR(svn_test__set_file_contents
-          (txn_root, "A/B/E/beta", "This is the file 'beta'.\n", pool));
-  SVN_ERR(svn_fs_make_dir  (txn_root, "A/B/F", pool));
-  SVN_ERR(svn_fs_make_dir  (txn_root, "A/C", pool));
-  SVN_ERR(svn_fs_make_dir  (txn_root, "A/D", pool));
-  SVN_ERR(svn_fs_make_file(txn_root, "A/D/gamma", pool));
-  SVN_ERR(svn_test__set_file_contents
-          (txn_root, "A/D/gamma", "This is the file 'gamma'.\n", pool));
-  SVN_ERR(svn_fs_make_dir  (txn_root, "A/D/G", pool));
-  SVN_ERR(svn_fs_make_file(txn_root, "A/D/G/pi", pool));
-  SVN_ERR(svn_test__set_file_contents
-          (txn_root, "A/D/G/pi", "This is the file 'pi'.\n", pool));
-  SVN_ERR(svn_fs_make_file(txn_root, "A/D/G/rho", pool));
-  SVN_ERR(svn_test__set_file_contents
-          (txn_root, "A/D/G/rho", "This is the file 'rho'.\n", pool));
-  SVN_ERR(svn_fs_make_file(txn_root, "A/D/G/tau", pool));
-  SVN_ERR(svn_test__set_file_contents
-          (txn_root, "A/D/G/tau", "This is the file 'tau'.\n", pool));
-  SVN_ERR(svn_fs_make_dir  (txn_root, "A/D/H", pool));
-  SVN_ERR(svn_fs_make_file(txn_root, "A/D/H/chi", pool));
-  SVN_ERR(svn_test__set_file_contents
-          (txn_root, "A/D/H/chi", "This is the file 'chi'.\n", pool));
-  SVN_ERR(svn_fs_make_file(txn_root, "A/D/H/psi", pool));
-  SVN_ERR(svn_test__set_file_contents
-          (txn_root, "A/D/H/psi", "This is the file 'psi'.\n", pool));
-  SVN_ERR(svn_fs_make_file(txn_root, "A/D/H/omega", pool));
-  SVN_ERR(svn_test__set_file_contents
-          (txn_root, "A/D/H/omega", "This is the file 'omega'.\n", pool));
+  return svn_test__create_greek_tree_at(txn_root, "", pool);
+}
+
+svn_error_t *
+svn_test__create_blame_repository(svn_repos_t **out_repos,
+                                  const char *test_name,
+                                  const svn_test_opts_t *opts,
+                                  apr_pool_t *pool)
+{
+  svn_repos_t *repos;
+  svn_fs_t *fs;
+  svn_fs_txn_t *txn;
+  svn_fs_root_t *txn_root, *revision_root;
+  svn_revnum_t youngest_rev = 0;
+
+  /* Create a filesystem and repository. */
+  SVN_ERR(svn_test__create_repos(&repos, test_name,
+                                 opts, pool));
+  *out_repos = repos;
+
+  fs = svn_repos_fs(repos);
+
+  /* Revision 1:  Add trunk, tags, branches. */
+  SVN_ERR(svn_repos_fs_begin_txn_for_commit(&txn, repos, youngest_rev,
+                                            "initial", "log msg", pool));
+  SVN_ERR(svn_fs_txn_root(&txn_root, txn, pool));
+  SVN_ERR(svn_fs_make_dir(txn_root, "trunk", pool));
+  SVN_ERR(svn_fs_make_dir(txn_root, "tags", pool));
+  SVN_ERR(svn_fs_make_dir(txn_root, "branches", pool));
+  SVN_ERR(svn_repos_fs_commit_txn(NULL, repos, &youngest_rev, txn, pool));
+
+  /* Revision 2:  Add the Greek tree on the trunk. */
+  SVN_ERR(svn_repos_fs_begin_txn_for_commit(&txn, repos, youngest_rev,
+                                            "initial", "log msg", pool));
+  SVN_ERR(svn_fs_txn_root(&txn_root, txn, pool));
+  SVN_ERR(svn_test__create_greek_tree_at(txn_root, "trunk", pool));
+  SVN_ERR(svn_repos_fs_commit_txn(NULL, repos, &youngest_rev, txn, pool));
+
+  /* Revision 3:  Tweak trunk/A/mu. */
+  SVN_ERR(svn_repos_fs_begin_txn_for_commit(&txn, repos, youngest_rev,
+                                            "user-trunk", "log msg", pool));
+  SVN_ERR(svn_fs_txn_root(&txn_root, txn, pool));
+  SVN_ERR(svn_test__set_file_contents(txn_root, "trunk/A/mu",
+                                      "A\nB\nC\nD\nE\nF\nG\nH\nI", pool));
+  SVN_ERR(svn_repos_fs_commit_txn(NULL, repos, &youngest_rev, txn, pool));
+
+  /* Revision 4:  Copy trunk to branches/1.0.x. */
+  SVN_ERR(svn_repos_fs_begin_txn_for_commit(&txn, repos, youngest_rev,
+                                            "copy", "log msg", pool));
+  SVN_ERR(svn_fs_txn_root(&txn_root, txn, pool));
+  SVN_ERR(svn_fs_revision_root(&revision_root, fs, youngest_rev, pool));
+  SVN_ERR(svn_fs_copy(revision_root, "trunk",
+                      txn_root, "branches/1.0.x",
+                      pool));
+  SVN_ERR(svn_repos_fs_commit_txn(NULL, repos, &youngest_rev, txn, pool));
+
+  /* Revision 5:  Tweak trunk/A/mu. */
+  SVN_ERR(svn_repos_fs_begin_txn_for_commit(&txn, repos, youngest_rev,
+                                            "user-trunk", "log msg", pool));
+  SVN_ERR(svn_fs_txn_root(&txn_root, txn, pool));
+  SVN_ERR(svn_test__set_file_contents(txn_root, "trunk/A/mu",
+                                      "A\nB\nC -- trunk edit\nD\nE\nF\nG\nH\nI",
+                                      pool));
+  SVN_ERR(svn_repos_fs_commit_txn(NULL, repos, &youngest_rev, txn, pool));
+
+  /* Revision 6:  Tweak branches/1.0.x/A/mu. */
+  SVN_ERR(svn_repos_fs_begin_txn_for_commit(&txn, repos, youngest_rev,
+                                            "user-branch", "log msg", pool));
+  SVN_ERR(svn_fs_txn_root(&txn_root, txn, pool));
+  SVN_ERR(svn_test__set_file_contents(txn_root, "branches/1.0.x/A/mu",
+                                      "A\nB\nC\nD -- branch edit\nE\nF\nG\nH\nI",
+                                      pool));
+  SVN_ERR(svn_repos_fs_commit_txn(NULL, repos, &youngest_rev, txn, pool));
+
+  /* Revision 7:  Merge trunk to branch. */
+  SVN_ERR(svn_repos_fs_begin_txn_for_commit(&txn, repos, youngest_rev,
+                                            "user-merge1", "log msg", pool));
+  SVN_ERR(svn_fs_txn_root(&txn_root, txn, pool));
+  SVN_ERR(svn_test__set_file_contents(txn_root, "branches/1.0.x/A/mu",
+                                      "A\nB\nC -- trunk edit\nD -- branch edit"
+                                      "\nE\nF\nG\nH\nI", pool));
+  SVN_ERR(svn_fs_change_node_prop(txn_root, "/branches/1.0.x", "svn:mergeinfo",
+                                  svn_string_create("/trunk:4-6", pool),
+                                  pool));
+  SVN_ERR(svn_repos_fs_commit_txn(NULL, repos, &youngest_rev, txn, pool));
+
+  /* Revision 8:  Merge branch to trunk. */
+  SVN_ERR(svn_repos_fs_begin_txn_for_commit(&txn, repos, youngest_rev,
+                                            "user-merge2", "log msg", pool));
+  SVN_ERR(svn_fs_txn_root(&txn_root, txn, pool));
+  SVN_ERR(svn_test__set_file_contents(txn_root, "trunk/A/mu",
+                                      "A\nB\nC -- trunk edit\nD -- branch edit\n"
+                                      "E\nF\nG\nH\nI", pool));
+  SVN_ERR(svn_fs_change_node_prop(txn_root, "/trunk", "svn:mergeinfo",
+                                  svn_string_create("/branches/1.0.x:4-7", pool),
+                                  pool));
+  SVN_ERR(svn_repos_fs_commit_txn(NULL, repos, &youngest_rev, txn, pool));
+
   return SVN_NO_ERROR;
 }

Modified: subversion/trunk/subversion/tests/svn_test_fs.h
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/svn_test_fs.h?rev=911296&r1=911295&r2=911296&view=diff
==============================================================================
--- subversion/trunk/subversion/tests/svn_test_fs.h (original)
+++ subversion/trunk/subversion/tests/svn_test_fs.h Thu Feb 18 09:35:35 2010
@@ -73,6 +73,13 @@
                        const svn_test_opts_t *opts,
                        apr_pool_t *pool);
 
+/* Set URL to a "file://" url for the current directory, suffixed by the
+   forward-slash-style relative path SUFFIX, performing all allocation
+   in POOL. */
+svn_error_t *
+svn_test__current_directory_url(const char **url,
+                                const char *suffix,
+                                apr_pool_t *pool);
 
 /* Read all data from a generic read STREAM, and return it in STRING.
    Allocate the svn_stringbuf_t in APRPOOL.  (All data in STRING will be
@@ -169,6 +176,19 @@
 svn_test__create_greek_tree(svn_fs_root_t *txn_root,
                             apr_pool_t *pool);
 
+/* Create the Greek Tree under TXN_ROOT at dir ROOT_DIR.  */
+svn_error_t *
+svn_test__create_greek_tree_at(svn_fs_root_t *txn_root,
+                               const char *root_dir,
+                               apr_pool_t *pool);
+
+/* Create a new repository with a greek tree, trunk, branch and some
+   merges between them. */
+svn_error_t *
+svn_test__create_blame_repository(svn_repos_t **out_repos,
+                                  const char *test_name,
+                                  const svn_test_opts_t *opts,
+                                  apr_pool_t *pool);
 
 #ifdef __cplusplus
 }