You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by st...@apache.org on 2013/11/27 08:53:35 UTC

svn commit: r1545955 [14/15] - in /subversion/branches/fsfs-improvements: ./ build/ build/ac-macros/ build/generator/ build/generator/templates/ build/win32/ contrib/server-side/ contrib/server-side/svncutter/ notes/ subversion/bindings/javahl/native/ ...

Modified: subversion/branches/fsfs-improvements/subversion/tests/libsvn_subr/translate-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-improvements/subversion/tests/libsvn_subr/translate-test.c?rev=1545955&r1=1545954&r2=1545955&view=diff
==============================================================================
--- subversion/branches/fsfs-improvements/subversion/tests/libsvn_subr/translate-test.c (original)
+++ subversion/branches/fsfs-improvements/subversion/tests/libsvn_subr/translate-test.c Wed Nov 27 07:53:29 2013
@@ -862,7 +862,7 @@ static svn_error_t *
 mixed_to_lf(apr_pool_t *pool)
 {
   return substitute_and_verify
-          ("cr_to_lf", NULL, "\n", 1, NULL, NULL, NULL, NULL, 1, pool);
+          ("mixed_to_lf", NULL, "\n", 1, NULL, NULL, NULL, NULL, 1, pool);
 }
 
 
@@ -1096,10 +1096,10 @@ static svn_error_t *
 unexpand_author(apr_pool_t *pool)
 {
   SVN_ERR(substitute_and_verify
-          ("author", "\n", NULL, 0, NULL, NULL, "jrandom", NULL, 0, pool));
+          ("unexpand_author", "\n", NULL, 0, NULL, NULL, "jrandom", NULL, 0, pool));
 
   SVN_ERR(substitute_and_verify
-          ("author", "\r\n", NULL, 0, NULL, NULL, "jrandom", NULL, 0, pool));
+          ("unexpand_author", "\r\n", NULL, 0, NULL, NULL, "jrandom", NULL, 0, pool));
 
   return SVN_NO_ERROR;
 }
@@ -1109,11 +1109,11 @@ static svn_error_t *
 unexpand_date(apr_pool_t *pool)
 {
   SVN_ERR(substitute_and_verify
-          ("date", "\n", NULL, 0,
+          ("unexpand_date", "\n", NULL, 0,
            NULL, "Wed Jan  9 07:49:05 2002", NULL, NULL, 0, pool));
 
   SVN_ERR(substitute_and_verify
-          ("date", "\r\n", NULL, 0,
+          ("unexpand_date", "\r\n", NULL, 0,
            NULL, "Wed Jan  9 07:49:05 2002", NULL, NULL, 0, pool));
 
   return SVN_NO_ERROR;
@@ -1124,11 +1124,11 @@ static svn_error_t *
 unexpand_author_date(apr_pool_t *pool)
 {
   SVN_ERR(substitute_and_verify
-          ("author_date", "\n", NULL, 0,
+          ("unexpand_author_date", "\n", NULL, 0,
            NULL, "Wed Jan  9 07:49:05 2002", "jrandom", NULL, 0, pool));
 
   SVN_ERR(substitute_and_verify
-          ("author_date", "\r\n", NULL, 0,
+          ("unexpand_author_date", "\r\n", NULL, 0,
            NULL, "Wed Jan  9 07:49:05 2002", "jrandom", NULL, 0, pool));
 
   return SVN_NO_ERROR;
@@ -1139,11 +1139,11 @@ static svn_error_t *
 unexpand_author_rev(apr_pool_t *pool)
 {
   SVN_ERR(substitute_and_verify
-          ("author_rev", "\n", NULL, 0,
+          ("unexpand_author_rev", "\n", NULL, 0,
            "1729", NULL, "jrandom", NULL, 0, pool));
 
   SVN_ERR(substitute_and_verify
-          ("author_rev", "\r\n", NULL, 0,
+          ("unexpand_author_rev", "\r\n", NULL, 0,
            "1729", NULL, "jrandom", NULL, 0, pool));
 
   return SVN_NO_ERROR;
@@ -1154,11 +1154,11 @@ static svn_error_t *
 unexpand_rev(apr_pool_t *pool)
 {
   SVN_ERR(substitute_and_verify
-          ("rev", "\n", NULL, 0,
+          ("unexpand_rev", "\n", NULL, 0,
            "1729", NULL, NULL, NULL, 0, pool));
 
   SVN_ERR(substitute_and_verify
-          ("rev", "\r\n", NULL, 0,
+          ("unexpand_rev", "\r\n", NULL, 0,
            "1729", NULL, NULL, NULL, 0, pool));
 
   return SVN_NO_ERROR;
@@ -1169,11 +1169,11 @@ static svn_error_t *
 unexpand_rev_url(apr_pool_t *pool)
 {
   SVN_ERR(substitute_and_verify
-          ("rev_url", "\n", NULL, 0,
+          ("unexpand_rev_url", "\n", NULL, 0,
            "1729", NULL, NULL, "http://subversion.tigris.org", 0, pool));
 
   SVN_ERR(substitute_and_verify
-          ("rev_url", "\r\n", NULL, 0,
+          ("unexpand_rev_url", "\r\n", NULL, 0,
            "1729", NULL, NULL, "http://subversion.tigris.org", 0, pool));
 
   return SVN_NO_ERROR;
@@ -1184,7 +1184,7 @@ static svn_error_t *
 unexpand_author_date_rev_url(apr_pool_t *pool)
 {
   SVN_ERR(substitute_and_verify
-          ("author_date_rev_url", "\n", NULL, 0,
+          ("unexpand_author_date_rev_url", "\n", NULL, 0,
            "1729",
            "Wed Jan  9 07:49:05 2002",
            "jrandom",
@@ -1192,7 +1192,7 @@ unexpand_author_date_rev_url(apr_pool_t 
            1, pool));
 
   SVN_ERR(substitute_and_verify
-          ("author_date_rev_url", "\r\n", NULL, 0,
+          ("unexpand_author_date_rev_url", "\r\n", NULL, 0,
            "1729",
            "Wed Jan  9 07:49:05 2002",
            "jrandom",
@@ -1210,7 +1210,7 @@ static svn_error_t *
 lf_to_crlf_unexpand_author(apr_pool_t *pool)
 {
   return substitute_and_verify
-          ("lf_to_crlf_author", "\n", "\r\n", 0,
+          ("lf_to_crlf_unexpand_author", "\n", "\r\n", 0,
            NULL, NULL, "jrandom", NULL, 0, pool);
 }
 
@@ -1219,7 +1219,7 @@ static svn_error_t *
 mixed_to_lf_unexpand_author_date(apr_pool_t *pool)
 {
   return substitute_and_verify
-          ("mixed_to_lf_author_date", NULL, "\n", 1,
+          ("mixed_to_lf_unexpand_author_date", NULL, "\n", 1,
            NULL, "Wed Jan  9 07:49:05 2002", "jrandom", NULL, 0, pool);
 }
 
@@ -1228,7 +1228,7 @@ static svn_error_t *
 crlf_to_cr_unexpand_author_rev(apr_pool_t *pool)
 {
   return substitute_and_verify
-          ("crlf_to_cr_author_rev", "\r\n", "\r", 0,
+          ("crlf_to_cr_unexpand_author_rev", "\r\n", "\r", 0,
            "1729", NULL, "jrandom", NULL, 0, pool);
 }
 
@@ -1237,7 +1237,7 @@ static svn_error_t *
 cr_to_crlf_unexpand_rev(apr_pool_t *pool)
 {
   return substitute_and_verify
-          ("cr_to_crlf_rev", "\r", "\r\n", 0,
+          ("cr_to_crlf_unexpand_rev", "\r", "\r\n", 0,
            "1729", NULL, NULL, NULL, 0, pool);
 }
 
@@ -1246,7 +1246,7 @@ static svn_error_t *
 cr_to_crlf_unexpand_rev_url(apr_pool_t *pool)
 {
   return substitute_and_verify
-          ("cr_to_crlf_rev_url", "\r", "\r\n", 0,
+          ("cr_to_crlf_unexpand_rev_url", "\r", "\r\n", 0,
            "1729", NULL, NULL, "http://subversion.tigris.org", 0, pool);
 }
 
@@ -1255,7 +1255,7 @@ static svn_error_t *
 mixed_to_crlf_unexpand_author_date_rev_url(apr_pool_t *pool)
 {
   return substitute_and_verify
-          ("mixed_to_crlf_author_date_rev_url", NULL, "\r\n", 1,
+          ("mixed_to_crlf_unexpand_author_date_rev_url", NULL, "\r\n", 1,
            "1729",
            "Wed Jan  9 07:49:05 2002",
            "jrandom",
@@ -1268,6 +1268,8 @@ mixed_to_crlf_unexpand_author_date_rev_u
 
 /* The test table.  */
 
+int svn_test_max_threads = 7;
+
 struct svn_test_descriptor_t test_funcs[] =
   {
     SVN_TEST_NULL,

Modified: subversion/branches/fsfs-improvements/subversion/tests/libsvn_subr/utf-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-improvements/subversion/tests/libsvn_subr/utf-test.c?rev=1545955&r1=1545954&r2=1545955&view=diff
==============================================================================
--- subversion/branches/fsfs-improvements/subversion/tests/libsvn_subr/utf-test.c (original)
+++ subversion/branches/fsfs-improvements/subversion/tests/libsvn_subr/utf-test.c Wed Nov 27 07:53:29 2013
@@ -740,6 +740,8 @@ test_utf_is_normalized(apr_pool_t *pool)
 
 /* The test table.  */
 
+int svn_test_max_threads = 1;
+
 struct svn_test_descriptor_t test_funcs[] =
   {
     SVN_TEST_NULL,

Modified: subversion/branches/fsfs-improvements/subversion/tests/libsvn_wc/conflict-data-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-improvements/subversion/tests/libsvn_wc/conflict-data-test.c?rev=1545955&r1=1545954&r2=1545955&view=diff
==============================================================================
--- subversion/branches/fsfs-improvements/subversion/tests/libsvn_wc/conflict-data-test.c (original)
+++ subversion/branches/fsfs-improvements/subversion/tests/libsvn_wc/conflict-data-test.c Wed Nov 27 07:53:29 2013
@@ -810,6 +810,8 @@ test_prop_conflicts(const svn_test_opts_
 
 /* The test table.  */
 
+int svn_test_max_threads = 1;
+
 struct svn_test_descriptor_t test_funcs[] =
   {
     SVN_TEST_NULL,

Modified: subversion/branches/fsfs-improvements/subversion/tests/libsvn_wc/db-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-improvements/subversion/tests/libsvn_wc/db-test.c?rev=1545955&r1=1545954&r2=1545955&view=diff
==============================================================================
--- subversion/branches/fsfs-improvements/subversion/tests/libsvn_wc/db-test.c (original)
+++ subversion/branches/fsfs-improvements/subversion/tests/libsvn_wc/db-test.c Wed Nov 27 07:53:29 2013
@@ -1521,6 +1521,8 @@ test_externals_store(apr_pool_t *pool)
   return SVN_NO_ERROR;
 }
 
+int svn_test_max_threads = 2;
+
 struct svn_test_descriptor_t test_funcs[] =
   {
     SVN_TEST_NULL,

Modified: subversion/branches/fsfs-improvements/subversion/tests/libsvn_wc/entries-compat.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-improvements/subversion/tests/libsvn_wc/entries-compat.c?rev=1545955&r1=1545954&r2=1545955&view=diff
==============================================================================
--- subversion/branches/fsfs-improvements/subversion/tests/libsvn_wc/entries-compat.c (original)
+++ subversion/branches/fsfs-improvements/subversion/tests/libsvn_wc/entries-compat.c Wed Nov 27 07:53:29 2013
@@ -638,6 +638,8 @@ test_access_baton_like_locking(apr_pool_
 }
 
 
+int svn_test_max_threads = -1;
+
 struct svn_test_descriptor_t test_funcs[] =
   {
     SVN_TEST_NULL,

Modified: subversion/branches/fsfs-improvements/subversion/tests/libsvn_wc/op-depth-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-improvements/subversion/tests/libsvn_wc/op-depth-test.c?rev=1545955&r1=1545954&r2=1545955&view=diff
==============================================================================
--- subversion/branches/fsfs-improvements/subversion/tests/libsvn_wc/op-depth-test.c (original)
+++ subversion/branches/fsfs-improvements/subversion/tests/libsvn_wc/op-depth-test.c Wed Nov 27 07:53:29 2013
@@ -29,6 +29,7 @@
 
 #include "svn_private_config.h"
 #include "svn_types.h"
+#include "svn_hash.h"
 #include "svn_io.h"
 #include "svn_dirent_uri.h"
 #include "svn_pools.h"
@@ -52,10 +53,6 @@
 
 #include "../svn_test.h"
 
-#ifdef _MSC_VER
-#pragma warning(disable: 4221) /* nonstandard extension used */
-#endif
-
 /* Compare strings, like strcmp but either or both may be NULL which
  * compares equal to NULL and not equal to any non-NULL string. */
 static int
@@ -104,6 +101,14 @@ typedef struct nodes_row_t {
     const char *props;  /* comma-separated list of prop names */
 } nodes_row_t;
 
+/* What conflicts are on a path. */
+typedef struct conflict_info_t {
+    const char *local_relpath;
+    svn_boolean_t text_conflicted;
+    svn_boolean_t prop_conflicted;
+    svn_boolean_t tree_conflicted;
+} conflict_info_t;
+
 /* Macro for filling in the REPO_* fields of a non-base NODES_ROW_T
  * that has no copy-from info. */
 #define NO_COPY_FROM SVN_INVALID_REVNUM, NULL, FALSE
@@ -332,6 +337,146 @@ check_db_rows(svn_test__sandbox_t *b,
 }
 
 
+static const char *
+print_conflict(const conflict_info_t *row,
+               apr_pool_t *result_pool)
+{
+  return apr_psprintf(result_pool, "\"%s\", %s, %s, %s",
+                      row->local_relpath,
+                      row->text_conflicted ? "TRUE" : "FALSE",
+                      row->prop_conflicted ? "TRUE" : "FALSE",
+                      row->tree_conflicted ? "TRUE" : "FALSE");
+}
+
+static svn_error_t *
+compare_conflict_info(const void *key, apr_ssize_t klen,
+                      enum svn_hash_diff_key_status status,
+                      void *baton)
+{
+  comparison_baton_t *b = baton;
+  conflict_info_t *expected = apr_hash_get(b->expected_hash, key, klen);
+  conflict_info_t *found = apr_hash_get(b->found_hash, key, klen);
+
+  if (! expected)
+    {
+      b->errors = svn_error_createf(
+                    SVN_ERR_TEST_FAILED, b->errors,
+                    "found   {%s}",
+                    print_conflict(found, b->scratch_pool));
+    }
+  else if (! found)
+    {
+      b->errors = svn_error_createf(
+                    SVN_ERR_TEST_FAILED, b->errors,
+                    "expected {%s}",
+                    print_conflict(expected, b->scratch_pool));
+    }
+  else if (expected->text_conflicted != found->text_conflicted
+           || expected->prop_conflicted != found->prop_conflicted
+           || expected->tree_conflicted != found->tree_conflicted)
+    {
+      b->errors = svn_error_createf(
+                    SVN_ERR_TEST_FAILED, b->errors,
+                    "expected {%s}; found {%s}",
+                    print_conflict(expected, b->scratch_pool),
+                    print_conflict(found, b->scratch_pool));
+    }
+
+  /* Don't terminate the comparison: accumulate all differences. */
+  return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+check_db_conflicts(svn_test__sandbox_t *b,
+                   const char *root_path,
+                   const conflict_info_t *expected_conflicts)
+{
+  const char *base_relpath = root_path;
+  svn_sqlite__db_t *sdb;
+  int i;
+  svn_sqlite__stmt_t *stmt;
+  static const char *const statements[] = {
+    "SELECT local_relpath"
+    " FROM actual_node "
+    " WHERE conflict_data is NOT NULL "
+    "   AND local_relpath = ?1 OR local_relpath LIKE ?2",
+    NULL };
+#define STMT_SELECT_ACTUAL_INFO 0
+
+  svn_boolean_t have_row;
+  apr_hash_t *found_hash = apr_hash_make(b->pool);
+  apr_hash_t *expected_hash = apr_hash_make(b->pool);
+  apr_pool_t *iterpool = svn_pool_create(b->pool);
+  apr_hash_index_t *hi;
+  comparison_baton_t comparison_baton;
+
+  comparison_baton.expected_hash = expected_hash;
+  comparison_baton.found_hash = found_hash;
+  comparison_baton.scratch_pool = b->pool;
+  comparison_baton.errors = NULL;
+
+  /* Fill ACTUAL_HASH with data from the WC DB. */
+  SVN_ERR(open_wc_db(&sdb, b->wc_abspath, statements, b->pool, b->pool));
+  SVN_ERR(svn_sqlite__get_statement(&stmt, sdb, STMT_SELECT_ACTUAL_INFO));
+  SVN_ERR(svn_sqlite__bindf(stmt, "ss", base_relpath,
+                            (base_relpath[0]
+                             ? apr_psprintf(b->pool, "%s/%%", base_relpath)
+                             : "_%")));
+  SVN_ERR(svn_sqlite__step(&have_row, stmt));
+  while (have_row)
+    {
+      conflict_info_t *row = apr_palloc(b->pool, sizeof(*row));
+
+      row->local_relpath = svn_sqlite__column_text(stmt, 0, b->pool);
+
+      svn_hash_sets(found_hash, row->local_relpath, row);
+
+      SVN_ERR(svn_sqlite__step(&have_row, stmt));
+    }
+  SVN_ERR(svn_sqlite__reset(stmt));
+  SVN_ERR(svn_sqlite__close(sdb));
+
+  for (hi = apr_hash_first(b->pool, found_hash); hi; hi = apr_hash_next(hi))
+    {
+      svn_skel_t *conflict;
+      conflict_info_t *info = svn__apr_hash_index_val(hi);
+      const char *local_abspath;
+
+      svn_pool_clear(iterpool);
+
+      local_abspath = svn_dirent_join(b->wc_abspath, info->local_relpath,
+                                      iterpool);
+
+      SVN_ERR(svn_wc__db_read_conflict(&conflict, b->wc_ctx->db, local_abspath,
+                                       iterpool, iterpool));
+
+      SVN_TEST_ASSERT(conflict != NULL);
+
+      SVN_ERR(svn_wc__conflict_read_info(NULL, NULL,
+                                         &info->text_conflicted,
+                                         &info->prop_conflicted,
+                                         &info->tree_conflicted,
+                                         b->wc_ctx->db, local_abspath,
+                                         conflict,
+                                         iterpool, iterpool));
+    }
+
+  /* Fill EXPECTED_HASH with data from EXPECTED_ROWS. */
+  if (expected_conflicts)
+    for (i = 0; expected_conflicts[i].local_relpath != NULL; i++)
+      {
+        const conflict_info_t *row = &expected_conflicts[i];
+
+        svn_hash_sets(expected_hash, row->local_relpath, row);
+      }
+
+  /* Compare EXPECTED_HASH with ACTUAL_HASH and return any errors. */
+  SVN_ERR(svn_hash_diff(expected_hash, found_hash,
+                        compare_conflict_info, &comparison_baton, b->pool));
+  return comparison_baton.errors;
+}
+
+
 /* ---------------------------------------------------------------------- */
 /* The test functions */
 
@@ -759,7 +904,7 @@ test_adds_change_kind(const svn_test_opt
 {
   svn_test__sandbox_t b;
 
-  SVN_ERR(svn_test__sandbox_create(&b, "adds", opts, pool));
+  SVN_ERR(svn_test__sandbox_create(&b, "test_adds_change_kind", opts, pool));
   SVN_ERR(sbox_add_and_commit_greek_tree(&b));
 
   /* replace dir with file */
@@ -5215,9 +5360,21 @@ update_prop_mod_into_moved(const svn_tes
     SVN_ERR(check_db_rows(&b, "", nodes));
   }
 
+  {
+    conflict_info_t conflicts[] = {
+      { "A", FALSE, FALSE, TRUE },
+      {0}
+    };
+
+    SVN_ERR(check_db_conflicts(&b, "", conflicts));
+  }
+
   /* Resolve should update the move. */
   SVN_ERR(sbox_wc_resolve(&b, "A", svn_depth_empty,
                           svn_wc_conflict_choose_mine_conflict));
+
+  SVN_ERR(check_db_conflicts(&b, "", NULL));
+
   {
     nodes_row_t nodes[] = {
       {0, "",         "normal",       2, ""},
@@ -5300,6 +5457,7 @@ nested_move_update(const svn_test_opts_t
                           svn_wc_conflict_choose_mine_conflict));
   SVN_ERR(sbox_wc_resolve(&b, "A2/B/C", svn_depth_empty,
                           svn_wc_conflict_choose_mine_conflict));
+  SVN_ERR(check_db_conflicts(&b, "", NULL /* no conflicts */));
   {
     nodes_row_t nodes[] = {
       {0, "",          "normal",       2, ""},
@@ -5326,6 +5484,8 @@ nested_move_update(const svn_test_opts_t
 
   /* Update A to r3 brings no changes but updates the revisions. */
   SVN_ERR(sbox_wc_update(&b, "A", 3));
+  SVN_ERR(check_db_conflicts(&b, "", NULL /* no conflicts */));
+
   {
     nodes_row_t nodes[] = {
       {0, "",          "normal",       2, ""},
@@ -5625,7 +5785,9 @@ check_tree_conflict_repos_path(svn_test_
       svn_wc_conflict_version_t *version
         = APR_ARRAY_IDX(locations, 0, svn_wc_conflict_version_t *);
 
-      SVN_ERR_ASSERT(!strcmp(version->path_in_repos, repos_path1));
+      SVN_TEST_ASSERT(version != NULL);
+
+      SVN_TEST_ASSERT(!strcmp(version->path_in_repos, repos_path1));
     }
 
   if (repos_path2)
@@ -5633,7 +5795,9 @@ check_tree_conflict_repos_path(svn_test_
       svn_wc_conflict_version_t *version
         = APR_ARRAY_IDX(locations, 1, svn_wc_conflict_version_t *);
 
-      SVN_ERR_ASSERT(!strcmp(version->path_in_repos, repos_path2));
+      SVN_TEST_ASSERT(version != NULL);
+
+      SVN_TEST_ASSERT(!strcmp(version->path_in_repos, repos_path2));
     }
 
   return SVN_NO_ERROR;
@@ -7085,7 +7249,7 @@ movedto_opdepth(const svn_test_opts_t *o
 {
   svn_test__sandbox_t b;
 
-  SVN_ERR(svn_test__sandbox_create(&b, "moved_to_op_depth",
+  SVN_ERR(svn_test__sandbox_create(&b, "movedto_opdepth",
                                    opts, pool));
 
   SVN_ERR(sbox_wc_mkdir(&b, "A"));
@@ -8753,9 +8917,546 @@ move_twice_within_delete(const svn_test_
     return SVN_NO_ERROR;
 }
 
+/* Helper function for 4 move4 tests */
+static svn_error_t *
+init_move4(svn_test__sandbox_t *sandbox,
+           const char *test_name,
+           const svn_test_opts_t *opts,
+           svn_boolean_t move_away,
+           apr_pool_t *pool)
+{
+  SVN_ERR(svn_test__sandbox_create(sandbox, test_name, opts, pool));
+
+  SVN_ERR(sbox_wc_mkdir(sandbox, "A"));
+  SVN_ERR(sbox_wc_mkdir(sandbox, "A/A"));
+  SVN_ERR(sbox_wc_mkdir(sandbox, "A/A/A"));
+  SVN_ERR(sbox_wc_mkdir(sandbox, "A/A/A/A"));
+
+  SVN_ERR(sbox_wc_mkdir(sandbox, "B"));
+  SVN_ERR(sbox_wc_mkdir(sandbox, "B/A"));
+  SVN_ERR(sbox_wc_mkdir(sandbox, "B/A/A"));
+  SVN_ERR(sbox_wc_mkdir(sandbox, "B/A/A/A"));
+
+  SVN_ERR(sbox_wc_mkdir(sandbox, "C"));
+  SVN_ERR(sbox_wc_mkdir(sandbox, "C/A"));
+  SVN_ERR(sbox_wc_mkdir(sandbox, "C/A/A"));
+  SVN_ERR(sbox_wc_mkdir(sandbox, "C/A/A/A"));
+
+  SVN_ERR(sbox_wc_mkdir(sandbox, "D"));
+  SVN_ERR(sbox_wc_mkdir(sandbox, "D/A"));
+  SVN_ERR(sbox_wc_mkdir(sandbox, "D/A/A"));
+  SVN_ERR(sbox_wc_mkdir(sandbox, "D/A/A/A"));
+
+  SVN_ERR(sbox_wc_commit(sandbox, "")); /* r1 */
+
+  if (strstr(test_name, "_edit_"))
+    {
+      SVN_ERR(sbox_wc_propset(sandbox, "key", "value", "A/A/A"));
+      SVN_ERR(sbox_wc_propset(sandbox, "key", "value", "B/A/A"));
+      SVN_ERR(sbox_wc_propset(sandbox, "key", "value", "C/A/A"));
+      SVN_ERR(sbox_wc_propset(sandbox, "key", "value", "D/A/A"));
+      SVN_ERR(sbox_wc_propset(sandbox, "key", "value", "A/A/A/A"));
+      SVN_ERR(sbox_wc_propset(sandbox, "key", "value", "B/A/A/A"));
+      SVN_ERR(sbox_wc_propset(sandbox, "key", "value", "C/A/A/A"));
+      SVN_ERR(sbox_wc_propset(sandbox, "key", "value", "D/A/A/A"));
+    }
+  else if (strstr(test_name, "_delete_"))
+    {
+      SVN_ERR(sbox_wc_delete(sandbox, "A/A/A/A"));
+      SVN_ERR(sbox_wc_delete(sandbox, "B/A/A/A"));
+      SVN_ERR(sbox_wc_delete(sandbox, "C/A/A/A"));
+      SVN_ERR(sbox_wc_delete(sandbox, "D/A/A/A"));
+    }
+  else if (strstr(test_name, "_add_"))
+    {
+      SVN_ERR(sbox_wc_mkdir(sandbox, "A/A/A/NEW"));
+      SVN_ERR(sbox_wc_mkdir(sandbox, "B/A/A/NEW"));
+      SVN_ERR(sbox_wc_mkdir(sandbox, "C/A/A/NEW"));
+      SVN_ERR(sbox_wc_mkdir(sandbox, "D/A/A/NEW"));
+    }
+  else if (strstr(test_name, "_delself_"))
+    {
+      SVN_ERR(sbox_wc_delete(sandbox, "A/A/A"));
+      SVN_ERR(sbox_wc_delete(sandbox, "B/A/A"));
+      SVN_ERR(sbox_wc_delete(sandbox, "C/A/A"));
+      SVN_ERR(sbox_wc_delete(sandbox, "D/A/A"));
+    }
+
+  SVN_ERR(sbox_wc_commit(sandbox, ""));
+  SVN_ERR(sbox_wc_update(sandbox, "", 1));
+
+  SVN_ERR(sbox_wc_move(sandbox, "A/A/A", "AAA_1"));
+
+  if (move_away)
+    SVN_ERR(sbox_wc_move(sandbox, "A", "A_moved"));
+  else
+    SVN_ERR(sbox_wc_delete(sandbox, "A"));
+
+  SVN_ERR(sbox_wc_move(sandbox, "B", "A"));
+
+  SVN_ERR(sbox_wc_move(sandbox, "A/A/A", "AAA_2"));
+
+  if (move_away)
+    SVN_ERR(sbox_wc_move(sandbox, "A/A", "BA_moved"));
+  else
+    SVN_ERR(sbox_wc_delete(sandbox, "A/A"));
+
+  SVN_ERR(sbox_wc_move(sandbox, "C/A", "A/A"));
+
+  SVN_ERR(sbox_wc_move(sandbox, "A/A/A", "AAA_3"));
+
+  SVN_ERR(sbox_wc_move(sandbox, "D/A/A", "A/A/A"));
+
+  return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+del4_update_edit_AAA(const svn_test_opts_t *opts, apr_pool_t *pool)
+{
+  svn_test__sandbox_t b;
+
+  SVN_ERR(init_move4(&b, "del4_update_edit_AAA", opts, FALSE, pool));
+
+  /* Update and resolve via mine strategy */
+  SVN_ERR(sbox_wc_update(&b, "", 2));
+  SVN_ERR(sbox_wc_resolve(&b, "", svn_depth_infinity, svn_wc_conflict_choose_mine_conflict));
+  /* Go back to start position */
+  SVN_ERR(sbox_wc_update(&b, "", 1));
+  SVN_ERR(sbox_wc_resolve(&b, "", svn_depth_infinity, svn_wc_conflict_choose_mine_conflict));
+  /* Update and resolve via their strategy */
+  SVN_ERR(sbox_wc_update(&b, "", 2));
+  SVN_ERR(sbox_wc_resolve(&b, "", svn_depth_infinity, svn_wc_conflict_choose_merged));
+
+  return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+del4_update_delete_AAA(const svn_test_opts_t *opts, apr_pool_t *pool)
+{
+  svn_test__sandbox_t b;
+
+  SVN_ERR(init_move4(&b, "del4_update_delete_AAA", opts, FALSE, pool));
+
+  /* Update and resolve via mine strategy */
+  SVN_ERR(sbox_wc_update(&b, "", 2));
+  SVN_ERR(sbox_wc_resolve(&b, "", svn_depth_infinity, svn_wc_conflict_choose_mine_conflict));
+  /* Go back to start position */
+  SVN_ERR(sbox_wc_update(&b, "", 1));
+  SVN_ERR(sbox_wc_resolve(&b, "", svn_depth_infinity, svn_wc_conflict_choose_mine_conflict));
+  /* Update and resolve via their strategy */
+  SVN_ERR(sbox_wc_update(&b, "", 2));
+  SVN_ERR(sbox_wc_resolve(&b, "", svn_depth_infinity, svn_wc_conflict_choose_merged));
+
+  return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+del4_update_add_AAA(const svn_test_opts_t *opts, apr_pool_t *pool)
+{
+  svn_test__sandbox_t b;
+
+  SVN_ERR(init_move4(&b, "del4_update_add_AAA", opts, FALSE, pool));
+
+  /* Update and resolve via mine strategy */
+  SVN_ERR(sbox_wc_update(&b, "", 2));
+  SVN_ERR(sbox_wc_resolve(&b, "", svn_depth_infinity, svn_wc_conflict_choose_mine_conflict));
+  /* Go back to start position */
+  SVN_ERR(sbox_wc_update(&b, "", 1));
+  SVN_ERR(sbox_wc_resolve(&b, "", svn_depth_infinity, svn_wc_conflict_choose_mine_conflict));
+  /* Update and resolve via their strategy */
+  SVN_ERR(sbox_wc_update(&b, "", 2));
+  SVN_ERR(sbox_wc_resolve(&b, "", svn_depth_infinity, svn_wc_conflict_choose_merged));
+
+  return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+del4_update_delself_AAA(const svn_test_opts_t *opts, apr_pool_t *pool)
+{
+  svn_test__sandbox_t b;
+
+  SVN_ERR(init_move4(&b, "del4_update_delself_AAA", opts, FALSE, pool));
+
+  /* Update and resolve via mine strategy */
+  SVN_ERR(sbox_wc_update(&b, "", 2));
+
+  /* Resolve a few conflicts manually */
+  SVN_ERR(sbox_wc_resolve(&b, "A", svn_depth_empty,
+                          svn_wc_conflict_choose_mine_conflict));
+  SVN_ERR(sbox_wc_resolve(&b, "B", svn_depth_empty,
+                          svn_wc_conflict_choose_mine_conflict));
+  SVN_ERR(sbox_wc_resolve(&b, "C/A", svn_depth_empty,
+                          svn_wc_conflict_choose_mine_conflict));
+
+  /* ### These can currently only be resolved to merged ???? */
+  SVN_ERR(sbox_wc_resolve(&b, "D/A/A", svn_depth_empty,
+                          svn_wc_conflict_choose_merged));
+  SVN_ERR(sbox_wc_resolve(&b, "A/A/A", svn_depth_empty,
+                          svn_wc_conflict_choose_merged));
+
+  SVN_ERR(sbox_wc_resolve(&b, "", svn_depth_infinity, svn_wc_conflict_choose_mine_conflict));
+  /* Go back to start position */
+  SVN_ERR(sbox_wc_update(&b, "", 1));
+  SVN_ERR(sbox_wc_resolve(&b, "", svn_depth_infinity, svn_wc_conflict_choose_mine_conflict));
+  /* Update and resolve via their strategy */
+  SVN_ERR(sbox_wc_update(&b, "", 2));
+  SVN_ERR(sbox_wc_resolve(&b, "", svn_depth_infinity, svn_wc_conflict_choose_merged));
+
+  return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+move4_update_edit_AAA(const svn_test_opts_t *opts, apr_pool_t *pool)
+{
+    svn_test__sandbox_t b;
+
+    SVN_ERR(init_move4(&b, "move4_update_edit_AAA", opts, TRUE, pool));
+
+    /* Update and resolve via mine strategy */
+    SVN_ERR(sbox_wc_update(&b, "", 2));
+    SVN_ERR(sbox_wc_resolve(&b, "", svn_depth_infinity, svn_wc_conflict_choose_mine_conflict));
+    /* Go back to start position */
+    SVN_ERR(sbox_wc_update(&b, "", 1));
+    SVN_ERR(sbox_wc_resolve(&b, "", svn_depth_infinity, svn_wc_conflict_choose_mine_conflict));
+    /* Update and resolve via their strategy */
+    SVN_ERR(sbox_wc_update(&b, "", 2));
+    SVN_ERR(sbox_wc_resolve(&b, "", svn_depth_infinity, svn_wc_conflict_choose_merged));
+
+    return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+move4_update_delete_AAA(const svn_test_opts_t *opts, apr_pool_t *pool)
+{
+    svn_test__sandbox_t b;
+
+    SVN_ERR(init_move4(&b, "move4_update_delete_AAA", opts, TRUE, pool));
+
+    /* Update and resolve via mine strategy */
+    SVN_ERR(sbox_wc_update(&b, "", 2));
+    SVN_ERR(sbox_wc_resolve(&b, "", svn_depth_infinity, svn_wc_conflict_choose_mine_conflict));
+    /* Go back to start position */
+    SVN_ERR(sbox_wc_update(&b, "", 1));
+    SVN_ERR(sbox_wc_resolve(&b, "", svn_depth_infinity, svn_wc_conflict_choose_mine_conflict));
+    /* Update and resolve via their strategy */
+    SVN_ERR(sbox_wc_update(&b, "", 2));
+    SVN_ERR(sbox_wc_resolve(&b, "", svn_depth_infinity, svn_wc_conflict_choose_merged));
+
+    return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+move4_update_add_AAA(const svn_test_opts_t *opts, apr_pool_t *pool)
+{
+    svn_test__sandbox_t b;
+
+    SVN_ERR(init_move4(&b, "move4_update_add_AAA", opts, TRUE, pool));
+
+    /* Update and resolve via mine strategy */
+    SVN_ERR(sbox_wc_update(&b, "", 2));
+    SVN_ERR(sbox_wc_resolve(&b, "", svn_depth_infinity, svn_wc_conflict_choose_mine_conflict));
+    /* Go back to start position */
+    SVN_ERR(sbox_wc_update(&b, "", 1));
+    SVN_ERR(sbox_wc_resolve(&b, "", svn_depth_infinity, svn_wc_conflict_choose_mine_conflict));
+    /* Update and resolve via their strategy */
+    SVN_ERR(sbox_wc_update(&b, "", 2));
+    SVN_ERR(sbox_wc_resolve(&b, "", svn_depth_infinity, svn_wc_conflict_choose_merged));
+
+    return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+move4_update_delself_AAA(const svn_test_opts_t *opts, apr_pool_t *pool)
+{
+    svn_test__sandbox_t b;
+
+    SVN_ERR(init_move4(&b, "move4_update_delself_AAA", opts, TRUE, pool));
+
+    /* Update and resolve via mine strategy */
+    SVN_ERR(sbox_wc_update(&b, "", 2));
+
+    /* Resolve a few conflicts manually */
+    SVN_ERR(sbox_wc_resolve(&b, "A", svn_depth_empty,
+        svn_wc_conflict_choose_mine_conflict));
+    SVN_ERR(sbox_wc_resolve(&b, "B", svn_depth_empty,
+        svn_wc_conflict_choose_mine_conflict));
+    SVN_ERR(sbox_wc_resolve(&b, "C/A", svn_depth_empty,
+        svn_wc_conflict_choose_mine_conflict));
+
+    /* ### These can currently only be resolved to merged ???? */
+    SVN_ERR(sbox_wc_resolve(&b, "D/A/A", svn_depth_empty,
+                            svn_wc_conflict_choose_merged));
+    SVN_ERR(sbox_wc_resolve(&b, "A/A/A", svn_depth_empty,
+                            svn_wc_conflict_choose_merged));
+    SVN_ERR(sbox_wc_resolve(&b, "A_moved/A/A", svn_depth_empty,
+                            svn_wc_conflict_choose_merged));
+    /*SVN_ERR(check_db_conflicts(&b, "", NULL));*/
+    SVN_ERR(sbox_wc_resolve(&b, "A/A", svn_depth_empty,
+                            svn_wc_conflict_choose_mine_conflict));
+    SVN_ERR(sbox_wc_resolve(&b, "BA_moved/A", svn_depth_empty,
+                            svn_wc_conflict_choose_merged));
+    SVN_ERR(sbox_wc_resolve(&b, "", svn_depth_infinity, svn_wc_conflict_choose_mine_conflict));
+    /* Go back to start position */
+    SVN_ERR(sbox_wc_update(&b, "", 1));
+    SVN_ERR(sbox_wc_resolve(&b, "", svn_depth_infinity, svn_wc_conflict_choose_mine_conflict));
+    /* Update and resolve via their strategy */
+    SVN_ERR(sbox_wc_update(&b, "", 2));
+    SVN_ERR(sbox_wc_resolve(&b, "", svn_depth_infinity, svn_wc_conflict_choose_merged));
+
+    return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+simple_move_bump(const svn_test_opts_t *opts, apr_pool_t *pool)
+{
+  svn_test__sandbox_t b;
+
+  SVN_ERR(svn_test__sandbox_create(&b, "simple_move_bump", opts, pool));
+
+  SVN_ERR(sbox_wc_mkdir(&b, "A"));
+  SVN_ERR(sbox_wc_mkdir(&b, "A/B"));
+
+  SVN_ERR(sbox_wc_propset(&b, "old_A", "val", "A"));
+  SVN_ERR(sbox_wc_propset(&b, "old_B", "val", "A/B"));
+
+  SVN_ERR(sbox_wc_commit(&b, ""));
+
+  SVN_ERR(sbox_wc_propset(&b, "new_A", "val", "A"));
+  SVN_ERR(sbox_wc_propset(&b, "new_B", "val", "A/B"));
+
+  SVN_ERR(sbox_wc_commit(&b, ""));
+
+  SVN_ERR(sbox_wc_update(&b, "", 1));
+
+  SVN_ERR(sbox_wc_move(&b, "A/B", "A/B_mv"));
+  SVN_ERR(sbox_wc_move(&b, "A", "A_mv"));
+
+  {
+    nodes_row_t nodes[] = {
+
+      { 0, "",          "normal",       1, ""},
+      { 0, "A",         "normal",       1, "A", NOT_MOVED, "old_A"},
+      { 0, "A/B",       "normal",       1, "A/B", NOT_MOVED, "old_B"},
+
+      { 1, "A",         "base-deleted", NO_COPY_FROM, "A_mv"},
+      { 1, "A/B",       "base-deleted", NO_COPY_FROM},
+
+      { 1, "A_mv",      "normal",       1, "A", MOVED_HERE, "old_A" },
+      { 1, "A_mv/B",    "normal",       1, "A/B", MOVED_HERE, "old_B" },
+
+      { 2, "A_mv/B",    "base-deleted", NO_COPY_FROM, "A_mv/B_mv" },
+      { 2, "A_mv/B_mv", "normal",       1, "A/B", FALSE, NULL, TRUE, "old_B" },
+
+      { 0 },
+    };
+    SVN_ERR(check_db_rows(&b, "", nodes));
+  }
+
+  SVN_ERR(sbox_wc_update(&b, "", 2));
+
+  /* Expect the A tree to be updated */
+  {
+    nodes_row_t nodes[] = {
+
+      { 0, "",          "normal",       2, ""},
+      { 0, "A",         "normal",       2, "A", NOT_MOVED, "new_A,old_A"},
+      { 0, "A/B",       "normal",       2, "A/B", NOT_MOVED, "new_B,old_B"},
+
+      { 1, "A",         "base-deleted", NO_COPY_FROM, "A_mv"},
+      { 1, "A/B",       "base-deleted", NO_COPY_FROM},
+
+      { 1, "A_mv",      "normal",       1, "A", MOVED_HERE, "old_A" },
+      { 1, "A_mv/B",    "normal",       1, "A/B", MOVED_HERE, "old_B" },
+
+      { 2, "A_mv/B",    "base-deleted", NO_COPY_FROM, "A_mv/B_mv" },
+      { 2, "A_mv/B_mv", "normal",       1, "A/B", FALSE, NULL, TRUE, "old_B" },
+
+      { 0 },
+    };
+    SVN_ERR(check_db_rows(&b, "", nodes));
+  }
+
+  SVN_ERR(sbox_wc_resolve(&b, "A", svn_depth_empty,
+                          svn_wc_conflict_choose_mine_conflict));
+
+  {
+    nodes_row_t nodes[] = {
+
+      { 0, "",          "normal",       2, ""},
+      { 0, "A",         "normal",       2, "A", NOT_MOVED, "new_A,old_A"},
+      { 0, "A/B",       "normal",       2, "A/B", NOT_MOVED, "new_B,old_B"},
+
+      { 1, "A",         "base-deleted", NO_COPY_FROM, "A_mv"},
+      { 1, "A/B",       "base-deleted", NO_COPY_FROM},
+
+      { 1, "A_mv",      "normal",       2, "A", MOVED_HERE, "new_A,old_A" },
+      { 1, "A_mv/B",    "normal",       2, "A/B", MOVED_HERE, "new_B,old_B" },
+
+      { 2, "A_mv/B",    "base-deleted", NO_COPY_FROM, "A_mv/B_mv" },
+      { 2, "A_mv/B_mv", "normal",       1, "A/B", FALSE, NULL, TRUE, "old_B" },
+
+      { 0 },
+    };
+    SVN_ERR(check_db_rows(&b, "", nodes));
+  }
+
+  SVN_ERR(sbox_wc_resolve(&b, "A_mv/B", svn_depth_empty,
+                          svn_wc_conflict_choose_mine_conflict));
+
+  {
+    nodes_row_t nodes[] = {
+
+      { 0, "",          "normal",       2, ""},
+      { 0, "A",         "normal",       2, "A", NOT_MOVED, "new_A,old_A"},
+      { 0, "A/B",       "normal",       2, "A/B", NOT_MOVED, "new_B,old_B"},
+
+      { 1, "A",         "base-deleted", NO_COPY_FROM, "A_mv"},
+      { 1, "A/B",       "base-deleted", NO_COPY_FROM},
+
+      { 1, "A_mv",      "normal",       2, "A", MOVED_HERE, "new_A,old_A" },
+      { 1, "A_mv/B",    "normal",       2, "A/B", MOVED_HERE, "new_B,old_B" },
+
+      { 2, "A_mv/B",    "base-deleted", NO_COPY_FROM, "A_mv/B_mv" },
+      { 2, "A_mv/B_mv", "normal",       2, "A/B", FALSE, NULL, TRUE, "new_B,old_B" },
+
+      { 0 },
+    };
+    SVN_ERR(check_db_rows(&b, "", nodes));
+  }
+
+  return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+movedhere_extract_retract(const svn_test_opts_t *opts, apr_pool_t *pool)
+{
+  svn_test__sandbox_t b;
+
+  SVN_ERR(svn_test__sandbox_create(&b, "movedhere_extract_retract",
+                                   opts, pool));
+
+  SVN_ERR(sbox_wc_mkdir(&b, "A"));
+  SVN_ERR(sbox_wc_mkdir(&b, "A/B1"));
+  SVN_ERR(sbox_wc_mkdir(&b, "A/B2"));
+  SVN_ERR(sbox_wc_mkdir(&b, "A/B3"));
+  SVN_ERR(sbox_wc_mkdir(&b, "A/C1"));
+  SVN_ERR(sbox_wc_mkdir(&b, "A/C2"));
+  SVN_ERR(sbox_wc_mkdir(&b, "A/C3"));
+  SVN_ERR(sbox_wc_mkdir(&b, "A/D1"));
+  SVN_ERR(sbox_wc_mkdir(&b, "A/D2"));
+  SVN_ERR(sbox_wc_mkdir(&b, "A/D3"));
+
+  SVN_ERR(sbox_wc_commit(&b, ""));
+
+  SVN_ERR(sbox_wc_propset(&b, "k", "v", "A/B1"));
+  SVN_ERR(sbox_wc_propset(&b, "k", "v", "A/B2"));
+  SVN_ERR(sbox_wc_propset(&b, "k", "v", "A/B3"));
+  SVN_ERR(sbox_wc_delete(&b, "A/C1"));
+  SVN_ERR(sbox_wc_delete(&b, "A/C2"));
+  SVN_ERR(sbox_wc_delete(&b, "A/C3"));
+  SVN_ERR(sbox_wc_mkdir(&b, "A/E1"));
+  SVN_ERR(sbox_wc_mkdir(&b, "A/E2"));
+  SVN_ERR(sbox_wc_mkdir(&b, "A/E3"));
+
+  SVN_ERR(sbox_wc_commit(&b, ""));
+
+  SVN_ERR(sbox_wc_update(&b, "", 1));
+
+  SVN_ERR(sbox_wc_move(&b, "A", "Z"));
+
+  SVN_ERR(sbox_wc_delete(&b, "Z/B1"));
+  SVN_ERR(sbox_wc_delete(&b, "Z/C1"));
+  SVN_ERR(sbox_wc_delete(&b, "Z/D1"));
+
+  SVN_ERR(sbox_wc_move(&b, "Z/B2", "B2"));
+  SVN_ERR(sbox_wc_move(&b, "Z/C2", "C2"));
+  SVN_ERR(sbox_wc_move(&b, "Z/D2", "D2"));
+
+  SVN_ERR(sbox_wc_mkdir(&b, "Z/B2"));
+  SVN_ERR(sbox_wc_mkdir(&b, "Z/C2"));
+  SVN_ERR(sbox_wc_mkdir(&b, "Z/D2"));
+  SVN_ERR(sbox_wc_mkdir(&b, "Z/E2"));
+
+  SVN_ERR(sbox_wc_update(&b, "", 2));
+  SVN_ERR(sbox_wc_resolve(&b, "A", svn_depth_empty,
+                          svn_wc_conflict_choose_mine_conflict));
+  SVN_ERR(sbox_wc_resolve(&b, "Z/B1", svn_depth_empty,
+                          svn_wc_conflict_choose_mine_conflict));
+  SVN_ERR(sbox_wc_resolve(&b, "Z/B2", svn_depth_empty,
+                          svn_wc_conflict_choose_mine_conflict));
+
+  SVN_ERR(sbox_wc_resolve(&b, "Z/C1", svn_depth_empty,
+                          svn_wc_conflict_choose_merged));
+  SVN_ERR(sbox_wc_resolve(&b, "Z/C2", svn_depth_empty,
+                          svn_wc_conflict_choose_merged));
+
+  SVN_ERR(sbox_wc_resolve(&b, "", svn_depth_infinity,
+                          svn_wc_conflict_choose_mine_conflict));
+  {
+    nodes_row_t nodes[] = {
+
+      {0, "",       "normal",       2, ""},
+      {0, "A",      "normal",       2, "A"},
+      {0, "A/B1",   "normal",       2, "A/B1", FALSE, NULL, FALSE, "k"},
+      {0, "A/B2",   "normal",       2, "A/B2", FALSE, NULL, FALSE, "k"},
+      {0, "A/B3",   "normal",       2, "A/B3", FALSE, NULL, FALSE, "k"},
+      {0, "A/D1",   "normal",       2, "A/D1"},
+      {0, "A/D2",   "normal",       2, "A/D2"},
+      {0, "A/D3",   "normal",       2, "A/D3"},
+      {0, "A/E1",   "normal",       2, "A/E1"},
+      {0, "A/E2",   "normal",       2, "A/E2"},
+      {0, "A/E3",   "normal",       2, "A/E3"},
+
+      {1, "A",      "base-deleted", NO_COPY_FROM, "Z"},
+      {1, "A/B1",   "base-deleted", NO_COPY_FROM},
+      {1, "A/B2",   "base-deleted", NO_COPY_FROM},
+      {1, "A/B3",   "base-deleted", NO_COPY_FROM},
+
+      {1, "A/D1",   "base-deleted", NO_COPY_FROM},
+      {1, "A/D2",   "base-deleted", NO_COPY_FROM},
+      {1, "A/D3",   "base-deleted", NO_COPY_FROM},
+
+      {1, "A/E1",   "base-deleted", NO_COPY_FROM},
+      {1, "A/E2",   "base-deleted", NO_COPY_FROM},
+      {1, "A/E3",   "base-deleted", NO_COPY_FROM},
+
+      {1, "B2",     "normal",       2, "A/B2", MOVED_HERE, "k"},
+      {1, "C2",     "normal",       1, "A/C2"},
+      {1, "D2",     "normal",       1, "A/D2", MOVED_HERE},
+
+      {1, "Z",      "normal",       2, "A", MOVED_HERE},
+      {1, "Z/B1",   "normal",       2, "A/B1", MOVED_HERE, "k"},
+      {1, "Z/B2",   "normal",       2, "A/B2", MOVED_HERE, "k"},
+      {1, "Z/B3",   "normal",       2, "A/B3", MOVED_HERE, "k"},
+      {1, "Z/D1",   "normal",       2, "A/D1", MOVED_HERE},
+      {1, "Z/D2",   "normal",       2, "A/D2", MOVED_HERE},
+      {1, "Z/D3",   "normal",       2, "A/D3", MOVED_HERE},
+      {1, "Z/E1",   "normal",       2, "A/E1", MOVED_HERE},
+      {1, "Z/E2",   "normal",       2, "A/E2", MOVED_HERE},
+      {1, "Z/E3",   "normal",       2, "A/E3", MOVED_HERE},
+
+      {2, "Z/B2",   "normal",       NO_COPY_FROM, "B2"},
+      {2, "Z/C2",   "normal",       NO_COPY_FROM},
+      {2, "Z/D2",   "normal",       NO_COPY_FROM, "D2"},
+      {2, "Z/E2",   "normal",       NO_COPY_FROM},
+
+      {2, "Z/B1",   "base-deleted", NO_COPY_FROM},
+      {2, "Z/D1",   "base-deleted", NO_COPY_FROM},
+
+      { 0 },
+    };
+    SVN_ERR(check_db_rows(&b, "", nodes));
+  }
+
+  return SVN_NO_ERROR;
+}
+
+
 /* ---------------------------------------------------------------------- */
 /* The list of test functions */
 
+int svn_test_max_threads = 2;
+
 struct svn_test_descriptor_t test_funcs[] =
   {
     SVN_TEST_NULL,
@@ -8920,5 +9621,25 @@ struct svn_test_descriptor_t test_funcs[
                        "move replace ancestor with child"),
     SVN_TEST_OPTS_PASS(move_twice_within_delete,
                        "move twice and then delete"),
+    SVN_TEST_OPTS_PASS(del4_update_edit_AAA,
+                       "del4: edit AAA"),
+    SVN_TEST_OPTS_PASS(del4_update_delete_AAA,
+                       "del4: delete AAA"),
+    SVN_TEST_OPTS_PASS(del4_update_add_AAA,
+                       "del4: add AAA"),
+    SVN_TEST_OPTS_PASS(del4_update_delself_AAA,
+                       "del4: delete self AAA"),
+    SVN_TEST_OPTS_PASS(move4_update_edit_AAA,
+                       "move4: edit AAA"),
+    SVN_TEST_OPTS_PASS(move4_update_delete_AAA,
+                       "move4: delete AAA"),
+    SVN_TEST_OPTS_PASS(move4_update_add_AAA,
+                       "move4: add AAA"),
+    SVN_TEST_OPTS_XFAIL(move4_update_delself_AAA,
+                       "move4: delete self AAA"),
+    SVN_TEST_OPTS_PASS(simple_move_bump,
+                       "simple move bump"),
+    SVN_TEST_OPTS_PASS(movedhere_extract_retract,
+                       "movedhere extract retract"),
     SVN_TEST_NULL
   };

Modified: subversion/branches/fsfs-improvements/subversion/tests/libsvn_wc/pristine-store-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-improvements/subversion/tests/libsvn_wc/pristine-store-test.c?rev=1545955&r1=1545954&r2=1545955&view=diff
==============================================================================
--- subversion/branches/fsfs-improvements/subversion/tests/libsvn_wc/pristine-store-test.c (original)
+++ subversion/branches/fsfs-improvements/subversion/tests/libsvn_wc/pristine-store-test.c Wed Nov 27 07:53:29 2013
@@ -319,6 +319,8 @@ reject_mismatching_text(const svn_test_o
 }
 
 
+int svn_test_max_threads = -1;
+
 struct svn_test_descriptor_t test_funcs[] =
   {
     SVN_TEST_NULL,

Modified: subversion/branches/fsfs-improvements/subversion/tests/libsvn_wc/utils.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-improvements/subversion/tests/libsvn_wc/utils.c?rev=1545955&r1=1545954&r2=1545955&view=diff
==============================================================================
--- subversion/branches/fsfs-improvements/subversion/tests/libsvn_wc/utils.c (original)
+++ subversion/branches/fsfs-improvements/subversion/tests/libsvn_wc/utils.c Wed Nov 27 07:53:29 2013
@@ -326,8 +326,15 @@ sbox_wc_update_depth(svn_test__sandbox_t
                                              sizeof(const char *));
   svn_opt_revision_t revision;
 
-  revision.kind = svn_opt_revision_number;
-  revision.value.number = revnum;
+  if (SVN_IS_VALID_REVNUM(revnum))
+    {
+      revision.kind = svn_opt_revision_number;
+      revision.value.number = revnum;
+    }
+  else
+    {
+      revision.kind = svn_opt_revision_head;
+    }
 
   APR_ARRAY_PUSH(paths, const char *) = sbox_wc_path(b, path);
   SVN_ERR(svn_client_create_context2(&ctx, NULL, b->pool));

Modified: subversion/branches/fsfs-improvements/subversion/tests/libsvn_wc/wc-queries-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-improvements/subversion/tests/libsvn_wc/wc-queries-test.c?rev=1545955&r1=1545954&r2=1545955&view=diff
==============================================================================
--- subversion/branches/fsfs-improvements/subversion/tests/libsvn_wc/wc-queries-test.c (original)
+++ subversion/branches/fsfs-improvements/subversion/tests/libsvn_wc/wc-queries-test.c Wed Nov 27 07:53:29 2013
@@ -22,6 +22,7 @@
  */
 
 #include "svn_pools.h"
+#include "svn_hash.h"
 #include "svn_ctype.h"
 #include "private/svn_dep_compat.h"
 
@@ -72,6 +73,7 @@ static const int schema_statements[] =
   STMT_CREATE_NODES,
   STMT_CREATE_NODES_TRIGGERS,
   STMT_CREATE_EXTERNALS,
+  STMT_INSTALL_SCHEMA_STATISTICS,
   /* Memory tables */
   STMT_CREATE_TARGETS_LIST,
   STMT_CREATE_CHANGELIST_LIST,
@@ -90,8 +92,8 @@ static const int slow_statements[] =
   /* Operate on the entire WC */
   STMT_SELECT_ALL_NODES,                /* schema validation code */
 
-  /* Is there a record? ### Can we somehow check for LIMIT 1? */
-  STMT_LOOK_FOR_WORK,
+  /* Updates all records for a repository (designed slow) */
+  STMT_UPDATE_LOCK_REPOS_ID,
 
   /* Full temporary table read */
   STMT_INSERT_ACTUAL_EMPTIES,
@@ -109,6 +111,19 @@ static const int slow_statements[] =
   -1 /* final marker */
 };
 
+/* Statements that just read the first record from a table,
+   using the primary key. Specialized as different sqlite
+   versions produce different results */
+static const int primary_key_statements[] =
+{
+  /* Is there a record? ### Can we somehow check for LIMIT 1,
+     and primary key instead of adding a list? */
+  STMT_LOOK_FOR_WORK,
+  STMT_SELECT_WORK_ITEM,
+
+  -1 /* final marker */
+};
+
 /* Helper function to determine if a statement is in a list */
 static svn_boolean_t
 in_list(const int list[], int stmt_idx)
@@ -524,6 +539,7 @@ is_node_table(const char *table_name)
   return (apr_strnatcasecmp(table_name, "nodes") == 0
           || apr_strnatcasecmp(table_name, "actual_node") == 0
           || apr_strnatcasecmp(table_name, "externals") == 0
+          || apr_strnatcasecmp(table_name, "lock") == 0
           || apr_strnatcasecmp(table_name, "wc_lock") == 0
           || FALSE);
 }
@@ -585,7 +601,7 @@ test_query_expectations(apr_pool_t *scra
                              apr_pstrcat(iterpool,
                                          "EXPLAIN QUERY PLAN ",
                                          wc_queries[i],
-                                         NULL),
+                                         SVN_VA_NULL),
                              -1, &stmt, &tail);
 
       if (r != SQLITE_OK)
@@ -646,14 +662,24 @@ test_query_expectations(apr_pool_t *scra
                        || (item->expression_vars < 1))
                    && !is_result_table(item->table))
             {
-              warned = TRUE;
-              if (!is_slow_statement(i))
-                warnings = svn_error_createf(SVN_ERR_TEST_FAILED, warnings,
+              if (in_list(primary_key_statements, i))
+                {
+                  /* Reported as primary key index usage in Sqlite 3.7,
+                     as table scan in 3.8+, while the execution plan is
+                     identical: read first record from table */
+                }
+              else if (!is_slow_statement(i))
+                {
+                  warned = TRUE;
+                  warnings = svn_error_createf(SVN_ERR_TEST_FAILED, warnings,
                                 "%s: "
                                 "Uses %s with only %d index component: (%s)\n%s",
                                 wc_query_info[i][0], item->table,
                                 item->expression_vars, item->expressions,
                                 wc_queries[i]);
+                }
+              else
+                warned = TRUE;
             }
           else if (item->search && !item->index)
             {
@@ -713,6 +739,245 @@ test_query_expectations(apr_pool_t *scra
   return warnings;
 }
 
+static svn_error_t *
+test_query_duplicates(apr_pool_t *scratch_pool)
+{
+  sqlite3 *sdb;
+  int i;
+  apr_pool_t *iterpool = svn_pool_create(scratch_pool);
+  svn_error_t *warnings = NULL;
+  svn_boolean_t supports_query_info;
+  apr_hash_t *sha_to_query = apr_hash_make(scratch_pool);
+
+  SVN_ERR(create_memory_db(&sdb, scratch_pool));
+
+  SVN_ERR(supported_explain_query_plan(&supports_query_info, sdb,
+      scratch_pool));
+  if (!supports_query_info)
+    {
+      SQLITE_ERR(sqlite3_close(sdb));
+      return svn_error_create(SVN_ERR_TEST_SKIPPED, NULL,
+          "Sqlite doesn't support EXPLAIN QUERY PLAN");
+    }
+
+  for (i = 0; i < STMT_SCHEMA_FIRST; i++)
+    {
+      sqlite3_stmt *stmt;
+      const char *tail;
+      int r;
+      svn_stringbuf_t *result;
+      svn_checksum_t *checksum;
+
+      if (is_schema_statement(i))
+        continue;
+
+      /* Prepare statement to find if it is a single statement. */
+      r = sqlite3_prepare_v2(sdb, wc_queries[i], -1, &stmt, &tail);
+
+      if (r != SQLITE_OK)
+        continue; /* Parse failure is already reported by 'test_parable' */
+
+      SQLITE_ERR(sqlite3_finalize(stmt));
+      if (tail[0] != '\0')
+        continue; /* Multi-queries are currently not testable */
+
+      svn_pool_clear(iterpool);
+
+      r = sqlite3_prepare_v2(sdb,
+                             apr_pstrcat(iterpool,
+                             "EXPLAIN ",
+                             wc_queries[i],
+                             SVN_VA_NULL),
+                             -1, &stmt, &tail);
+
+      if (r != SQLITE_OK)
+          continue; /* EXPLAIN not enabled or doesn't support this query */
+
+      result = svn_stringbuf_create_empty(iterpool);
+
+      while (SQLITE_ROW == (r = sqlite3_step(stmt)))
+        {
+          int col;
+
+          for (col = 0; col < sqlite3_column_count(stmt); col++)
+            {
+              const char *txt = (const char*)sqlite3_column_text(stmt, col);
+              if (txt)
+                  svn_stringbuf_appendcstr(result, txt);
+
+              svn_stringbuf_appendcstr(result, "|");
+            }
+
+          svn_stringbuf_appendcstr(result, "\n");
+        }
+
+      SQLITE_ERR(sqlite3_reset(stmt));
+      SQLITE_ERR(sqlite3_finalize(stmt));
+
+      SVN_ERR(svn_checksum(&checksum, svn_checksum_sha1,
+                           result->data, result->len,
+                           iterpool));
+
+      {
+        const char *hex = svn_checksum_to_cstring(checksum, scratch_pool);
+        const char *other;
+
+        other = svn_hash_gets(sha_to_query, hex);
+        if (other)
+          {
+            warnings = svn_error_createf(SVN_ERR_TEST_FAILED, warnings,
+                              "Query %s has an identical execution plan as %s",
+                              wc_query_info[i][0], other);
+          }
+        else
+          svn_hash_sets(sha_to_query, hex, wc_query_info[i][0]);
+      }
+    }
+  SQLITE_ERR(sqlite3_close(sdb)); /* Close the DB if ok; otherwise leaked */
+
+  return warnings;
+}
+
+/* Helper to verify a bit of data in the sqlite3 statistics */
+static int
+parse_stat_data(const char *stat)
+{
+  int n = 0;
+  apr_int64_t last = APR_INT64_MAX;
+  while (*stat)
+    {
+      apr_int64_t v;
+      char *next;
+
+      if (*stat < '0' || *stat > '9')
+        return -2;
+
+      errno = 0;
+      v = apr_strtoi64(stat, &next, 10);
+
+      /* All numbers specify the average number of rows
+         with the same values in all columns left of it,
+         so the value must be >= 1 and lower than or equal
+         to all previous seen numbers */
+      if (v <= 0 || (v > last) || (errno != 0))
+        return -1;
+
+      last = v;
+
+      n++;
+      stat = next;
+
+      if (*stat == ' ')
+        stat++;
+    }
+
+  return n;
+}
+
+static svn_error_t *
+test_schema_statistics(apr_pool_t *scratch_pool)
+{
+  sqlite3 *sdb;
+  sqlite3_stmt *stmt;
+
+  SVN_ERR(create_memory_db(&sdb, scratch_pool));
+
+  SQLITE_ERR(
+      sqlite3_exec(sdb,
+                   "CREATE TABLE shadow_stat1(tbl TEXT, idx TEXT, stat TEXT)",
+                   NULL, NULL, NULL));
+
+  SQLITE_ERR(
+      sqlite3_exec(sdb,
+                   "INSERT INTO shadow_stat1 (tbl, idx, stat) "
+                   "SELECT tbl, idx, stat FROM sqlite_stat1",
+                   NULL, NULL, NULL));
+
+  SQLITE_ERR(
+      sqlite3_exec(sdb,
+                   "DROP TABLE sqlite_stat1",
+                   NULL, NULL, NULL));
+
+  /* Insert statement to give index at least 1 record */
+  SQLITE_ERR(
+      sqlite3_exec(sdb,
+                   "INSERT INTO nodes (wc_id, local_relpath, op_depth,"
+                   "                   presence, kind) "
+                   "VALUES (1, '', 0, 'normal', 'dir')",
+                   NULL, NULL, NULL));
+
+  SQLITE_ERR(
+      sqlite3_exec(sdb,
+                   "INSERT INTO actual_node (wc_id, local_relpath) "
+                   "VALUES (1, '')",
+                   NULL, NULL, NULL));
+
+  SQLITE_ERR(
+      sqlite3_exec(sdb,
+                   "INSERT INTO lock (repos_id, repos_relpath, lock_token) "
+                   "VALUES (1, '', '')",
+                   NULL, NULL, NULL));
+
+  /* These are currently not necessary for query optimization, but it's better
+     to tell Sqlite how we intend to use this table anyway */
+  SQLITE_ERR(
+      sqlite3_exec(sdb,
+                   "INSERT INTO wc_lock (wc_id, local_dir_relpath) "
+                   "VALUES (1, '')",
+                   NULL, NULL, NULL));
+
+  SQLITE_ERR(
+      sqlite3_exec(sdb,
+                   "INSERT INTO WORK_QUEUE (work) "
+                   "VALUES ('')",
+                   NULL, NULL, NULL));
+
+  SQLITE_ERR(
+      sqlite3_exec(sdb,
+                   "ANALYZE",
+                   NULL, NULL, NULL));
+
+  SQLITE_ERR(
+      sqlite3_prepare(sdb, "SELECT s.tbl, s.idx, s.stat, r.stat "
+                           "FROM shadow_stat1 s "
+                           "LEFT JOIN sqlite_stat1 r ON "
+                                "s.tbl=r.tbl and s.idx=r.idx",
+                      -1, &stmt, NULL));
+
+  while (sqlite3_step(stmt) == SQLITE_ROW)
+    {
+      const char *wc_stat       = (const char*)sqlite3_column_text(stmt, 2);
+      const char *sqlite_stat   = (const char*)sqlite3_column_text(stmt, 3);
+
+      if (! sqlite_stat)
+        {
+          return svn_error_createf(SVN_ERR_TEST_FAILED, NULL,
+                                   "Schema statistic failure:"
+                                   " Refering to unknown index '%s' on '%s'",
+                                   sqlite3_column_text(stmt, 1),
+                                   sqlite3_column_text(stmt, 0));
+        }
+
+      if (parse_stat_data(wc_stat) != parse_stat_data(sqlite_stat))
+        {
+          return svn_error_createf(SVN_ERR_TEST_FAILED, NULL,
+                                   "Schema statistic failure:"
+                                   " Column mismatch for '%s' on '%s'",
+                                   sqlite3_column_text(stmt, 1),
+                                   sqlite3_column_text(stmt, 0));
+        }
+    }
+
+  SQLITE_ERR(sqlite3_reset(stmt));
+  SQLITE_ERR(sqlite3_finalize(stmt));
+
+  SQLITE_ERR(sqlite3_close(sdb)); /* Close the DB if ok; otherwise leaked */
+
+  return SVN_NO_ERROR;
+}
+
+int svn_test_max_threads = 1;
+
 struct svn_test_descriptor_t test_funcs[] =
   {
     SVN_TEST_NULL,
@@ -722,5 +987,9 @@ struct svn_test_descriptor_t test_funcs[
                    "queries are parsable"),
     SVN_TEST_PASS2(test_query_expectations,
                    "test query expectations"),
+    SVN_TEST_PASS2(test_query_duplicates,
+                   "test query duplicates"),
+    SVN_TEST_PASS2(test_schema_statistics,
+                   "test schema statistics"),
     SVN_TEST_NULL
   };

Modified: subversion/branches/fsfs-improvements/subversion/tests/libsvn_wc/wc-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-improvements/subversion/tests/libsvn_wc/wc-test.c?rev=1545955&r1=1545954&r2=1545955&view=diff
==============================================================================
--- subversion/branches/fsfs-improvements/subversion/tests/libsvn_wc/wc-test.c (original)
+++ subversion/branches/fsfs-improvements/subversion/tests/libsvn_wc/wc-test.c Wed Nov 27 07:53:29 2013
@@ -309,6 +309,8 @@ test_externals_parse_erratic(apr_pool_t 
 /* ---------------------------------------------------------------------- */
 /* The list of test functions */
 
+int svn_test_max_threads = 2;
+
 struct svn_test_descriptor_t test_funcs[] =
   {
     SVN_TEST_NULL,

Modified: subversion/branches/fsfs-improvements/subversion/tests/svn_test.h
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-improvements/subversion/tests/svn_test.h?rev=1545955&r1=1545954&r2=1545955&view=diff
==============================================================================
--- subversion/branches/fsfs-improvements/subversion/tests/svn_test.h (original)
+++ subversion/branches/fsfs-improvements/subversion/tests/svn_test.h Wed Nov 27 07:53:29 2013
@@ -104,6 +104,8 @@ typedef struct svn_test_opts_t
   const char *fs_type;
   /* Config file. */
   const char *config_file;
+  /* Source dir. */
+  const char *srcdir;
   /* Minor version to use for servers and FS backends, or zero to use
      the current latest version. */
   int server_minor_version;
@@ -187,6 +189,9 @@ extern struct svn_test_descriptor_t test
 #define SVN_TEST_OPTS_WIMP_COND(func, p, msg, wip) \
   {(p) ? svn_test_xfail : svn_test_pass, NULL, func, msg, wip}
 
+/* Maximum number of concurrent test threads.  Set to 1 if all tests must
+   be executed serially.  Numbers less than 1 mean "unbounded" */
+extern int svn_test_max_threads;
 
 
 /* Return a pseudo-random number based on SEED, and modify SEED.

Modified: subversion/branches/fsfs-improvements/subversion/tests/svn_test_main.c
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-improvements/subversion/tests/svn_test_main.c?rev=1545955&r1=1545954&r2=1545955&view=diff
==============================================================================
--- subversion/branches/fsfs-improvements/subversion/tests/svn_test_main.c (original)
+++ subversion/branches/fsfs-improvements/subversion/tests/svn_test_main.c Wed Nov 27 07:53:29 2013
@@ -47,9 +47,18 @@
 #include "svn_utf.h"
 
 #include "private/svn_cmdline_private.h"
+#include "private/svn_atomic.h"
+#include "private/svn_mutex.h"
 
 #include "svn_private_config.h"
 
+#if APR_HAS_THREADS && APR_VERSION_AT_LEAST(1,3,0)
+#  include <apr_thread_pool.h>
+#  define HAVE_THREADPOOLS 1
+#else
+#  define HAVE_THREADPOOLS 0
+#endif
+
 /* Some Subversion test programs may want to parse options in the
    argument list, so we remember it here. */
 int test_argc;
@@ -76,6 +85,9 @@ static svn_boolean_t allow_segfaults = F
    Pass, All). */
 enum svn_test_mode_t mode_filter = svn_test_all;
 
+/* Test option: Allow concurrent execution of tests */
+static svn_boolean_t parallel = FALSE;
+
 /* Option parsing enums and structures */
 enum {
   help_opt = SVN_OPT_FIRST_LONGOPT_ID,
@@ -88,7 +100,8 @@ enum {
   server_minor_version_opt,
   allow_segfault_opt,
   srcdir_opt,
-  mode_filter_opt
+  mode_filter_opt,
+  parallel_opt
 };
 
 static const apr_getopt_option_t cl_options[] =
@@ -117,6 +130,8 @@ static const apr_getopt_option_t cl_opti
                     N_("don't trap seg faults (useful for debugging)")},
   {"srcdir",        srcdir_opt, 1,
                     N_("source directory")},
+  {"parallel",      parallel_opt, 0,
+                    N_("allow concurrent execution of tests")},
   {0,               0, 0, 0}
 };
 
@@ -130,6 +145,9 @@ static svn_boolean_t skip_cleanup = FALS
 /* All cleanup actions are registered as cleanups on this pool. */
 static apr_pool_t *cleanup_pool = NULL;
 
+/* Used by test_thread to serialize access to stdout. */
+static svn_mutex__t *log_mutex = NULL;
+
 static apr_status_t
 cleanup_rmtree(void *data)
 {
@@ -160,13 +178,34 @@ svn_test_add_dir_cleanup(const char *pat
   if (cleanup_mode)
     {
       const char *abspath;
-      svn_error_t *err = svn_path_get_absolute(&abspath, path, cleanup_pool);
+      svn_error_t *err;
+
+      /* All cleanup functions use the *same* pool (not subpools of it).
+         Thus, we need to synchronize. */
+      err = svn_mutex__lock(log_mutex);
+      if (err)
+        {
+          if (verbose_mode) 
+            printf("FAILED svn_mutex__lock in svn_test_add_dir_cleanup.\n");
+          svn_error_clear(err);
+          return;
+        }
+
+      err = svn_path_get_absolute(&abspath, path, cleanup_pool);
       svn_error_clear(err);
       if (!err)
         apr_pool_cleanup_register(cleanup_pool, abspath, cleanup_rmtree,
                                   apr_pool_cleanup_null);
       else if (verbose_mode)
         printf("FAILED ABSPATH: %s\n", path);
+
+      err = svn_mutex__unlock(log_mutex, NULL);
+      if (err)
+        {
+          if (verbose_mode) 
+            printf("FAILED svn_mutex__unlock in svn_test_add_dir_cleanup.\n");
+          svn_error_clear(err);
+        }
     }
 }
 
@@ -209,6 +248,86 @@ crash_handler(int signum)
   longjmp(jump_buffer, 1);
 }
 
+/* Write the result of test number TEST_NUM to stdout.  Pretty-print test
+   name and dots according to our test-suite spec, and return TRUE if there
+   has been a test failure.
+
+   The parameters are basically the internal state of do_test_num() and
+   test_thread(). */
+/*  */
+static svn_boolean_t
+log_results(const char *progname,
+            int test_num,
+            svn_boolean_t msg_only,
+            svn_boolean_t run_this_test,
+            svn_boolean_t skip,
+            svn_boolean_t xfail,
+            svn_boolean_t wimp,
+            svn_error_t *err,
+            const char *msg,
+            const struct svn_test_descriptor_t *desc)
+{
+  svn_boolean_t test_failed;
+
+  if (err && err->apr_err == SVN_ERR_TEST_SKIPPED)
+    {
+      svn_error_clear(err);
+      err = SVN_NO_ERROR;
+      skip = TRUE;
+    }
+
+  /* Failure means unexpected results -- FAIL or XPASS. */
+  test_failed = (!wimp && ((err != SVN_NO_ERROR) != (xfail != 0)));
+
+  /* If we got an error, print it out.  */
+  if (err)
+    {
+      svn_handle_error2(err, stdout, FALSE, "svn_tests: ");
+      svn_error_clear(err);
+    }
+
+  if (msg_only)
+    {
+      if (run_this_test)
+        printf(" %3d    %-5s  %s%s%s%s\n",
+               test_num,
+               (xfail ? "XFAIL" : (skip ? "SKIP" : "")),
+               msg ? msg : "(test did not provide name)",
+               (wimp && verbose_mode) ? " [[" : "",
+               (wimp && verbose_mode) ? desc->wip : "",
+               (wimp && verbose_mode) ? "]]" : "");
+    }
+  else if (run_this_test && ((! quiet_mode) || test_failed))
+    {
+      printf("%s %s %d: %s%s%s%s\n",
+             (err
+              ? (xfail ? "XFAIL:" : "FAIL: ")
+              : (xfail ? "XPASS:" : (skip ? "SKIP: " : "PASS: "))),
+             progname,
+             test_num,
+             msg ? msg : "(test did not provide name)",
+             wimp ? " [[WIMP: " : "",
+             wimp ? desc->wip : "",
+             wimp ? "]]" : "");
+    }
+
+  if (msg)
+    {
+      size_t len = strlen(msg);
+      if (len > 50)
+        printf("WARNING: Test docstring exceeds 50 characters\n");
+      if (msg[len - 1] == '.')
+        printf("WARNING: Test docstring ends in a period (.)\n");
+      if (svn_ctype_isupper(msg[0]))
+        printf("WARNING: Test docstring is capitalized\n");
+    }
+  if (desc->msg == NULL)
+    printf("WARNING: New-style test descriptor is missing a docstring.\n");
+
+  fflush(stdout);
+
+  return test_failed;
+}
 
 /* Execute a test number TEST_NUM.  Pretty-print test name and dots
    according to our test-suite spec, and return the result code.
@@ -224,7 +343,6 @@ do_test_num(const char *progname,
 {
   svn_boolean_t skip, xfail, wimp;
   svn_error_t *err = NULL;
-  svn_boolean_t test_failed;
   const char *msg = NULL;  /* the message this individual test prints out */
   const struct svn_test_descriptor_t *desc;
   const int array_size = get_array_size();
@@ -296,60 +414,147 @@ do_test_num(const char *progname,
     }
 
   /* Failure means unexpected results -- FAIL or XPASS. */
-  test_failed = (!wimp && ((err != SVN_NO_ERROR) != (xfail != 0)));
+  skip_cleanup = log_results(progname, test_num, msg_only, run_this_test,
+                             skip, xfail, wimp, err, msg, desc);
 
-  /* If we got an error, print it out.  */
-  if (err)
-    {
-      svn_handle_error2(err, stdout, FALSE, "svn_tests: ");
-      svn_error_clear(err);
-    }
+  return skip_cleanup;
+}
 
-  if (msg_only)
-    {
-      if (run_this_test)
-        printf(" %3d    %-5s  %s%s%s%s\n",
-               test_num,
-               (xfail ? "XFAIL" : (skip ? "SKIP" : "")),
-               msg ? msg : "(test did not provide name)",
-               (wimp && verbose_mode) ? " [[" : "",
-               (wimp && verbose_mode) ? desc->wip : "",
-               (wimp && verbose_mode) ? "]]" : "");
-    }
-  else if (run_this_test && ((! quiet_mode) || test_failed))
+#if HAVE_THREADPOOLS
+
+/* Per-test parameters used by test_thread */
+typedef struct test_params_t
+{
+  /* Name of the application */
+  const char *progname;
+
+  /* Number / index of the test to execute */
+  int test_num;
+
+  /* Global test options as provided by main() */
+  svn_test_opts_t *opts;
+
+  /* Thread-safe parent pool for the test-specific pool.  We expect the
+     test thread to create a sub-pool and destroy it after test completion. */
+  apr_pool_t *pool;
+
+  /* Reference to the global failure flag.  Set this if any test failed. */
+  svn_atomic_t *got_error;
+
+  /* Reference to the global completed test counter. */
+  svn_atomic_t *run_count;
+} test_params_t;
+
+/* Thread function similar to do_test_num() but with fewer options.  We do
+   catch segfaults.  All parameters are given as a test_params_t in DATA.
+ */
+static void * APR_THREAD_FUNC
+test_thread(apr_thread_t *tid, void *data)
+{
+  svn_boolean_t skip, xfail, wimp;
+  svn_error_t *err = NULL;
+  const struct svn_test_descriptor_t *desc;
+  svn_boolean_t run_this_test; /* This test's mode matches DESC->MODE. */
+  test_params_t *params = data;
+
+  apr_pool_t *test_pool = svn_pool_create(params->pool);
+
+  desc = &test_funcs[params->test_num];
+  skip = desc->mode == svn_test_skip;
+  xfail = desc->mode == svn_test_xfail;
+  wimp = xfail && desc->wip;
+  run_this_test = mode_filter == svn_test_all || mode_filter == desc->mode;
+
+  /* Do test */
+  if (skip || !run_this_test)
+    ; /* pass */
+  else if (desc->func2)
+    err = (*desc->func2)(test_pool);
+  else
+    err = (*desc->func_opts)(params->opts, test_pool);
+
+  /* Write results to console */
+  svn_error_clear(svn_mutex__lock(log_mutex));
+  if (log_results(params->progname, params->test_num, FALSE, run_this_test,
+                  skip, xfail, wimp, err, desc->msg, desc))
+    svn_atomic_set(params->got_error, TRUE);
+  svn_error_clear(svn_mutex__unlock(log_mutex, NULL));
+
+  /* release all test memory */
+  svn_pool_destroy(test_pool);
+
+  /* one more test completed */
+  svn_atomic_inc(params->run_count);
+    
+  return NULL;
+}
+
+/* Execute all ARRAY_SIZE tests concurrently using MAX_THREADS threads.
+   Pass PROGNAME and OPTS to the individual tests.  Return TRUE if at least
+   one of the tests failed.  Allocate all data in POOL.
+
+   Note that cleanups are delayed until all tests have been completed.
+ */
+static svn_boolean_t
+do_tests_concurrently(const char *progname,
+                      int array_size,
+                      int max_threads,
+                      svn_test_opts_t *opts,
+                      apr_pool_t *pool)
+{
+  apr_thread_pool_t *threads;
+  apr_status_t status;
+  svn_atomic_t got_error = FALSE;
+  int i;
+  svn_atomic_t run_count = 0;
+
+  /* Create the thread pool. */
+  status = apr_thread_pool_create(&threads, max_threads, max_threads, pool);
+  if (status)
     {
-      printf("%s %s %d: %s%s%s%s\n",
-             (err
-              ? (xfail ? "XFAIL:" : "FAIL: ")
-              : (xfail ? "XPASS:" : (skip ? "SKIP: " : "PASS: "))),
-             progname,
-             test_num,
-             msg ? msg : "(test did not provide name)",
-             wimp ? " [[WIMP: " : "",
-             wimp ? desc->wip : "",
-             wimp ? "]]" : "");
+      printf("apr_thread_pool_create() failed.\n");
+      return TRUE;
     }
 
-  if (msg)
+  /* Don't queue requests unless we reached the worker thread limit. */
+  apr_thread_pool_threshold_set(threads, 0);
+
+  /* Generate one task per test and queue them in the thread pool. */
+  for (i = 1; i <= array_size; i++)
     {
-      size_t len = strlen(msg);
-      if (len > 50)
-        printf("WARNING: Test docstring exceeds 50 characters\n");
-      if (msg[len - 1] == '.')
-        printf("WARNING: Test docstring ends in a period (.)\n");
-      if (svn_ctype_isupper(msg[0]))
-        printf("WARNING: Test docstring is capitalized\n");
+      test_params_t *params = apr_pcalloc(pool, sizeof(*params));
+      params->got_error = &got_error;
+      params->opts = opts;
+      params->pool = pool;
+      params->progname = progname;
+      params->test_num = i;
+      params->run_count = &run_count;
+
+      apr_thread_pool_push(threads, test_thread, params, 0, NULL);
     }
-  if (desc->msg == NULL)
-    printf("WARNING: New-style test descriptor is missing a docstring.\n");
 
-  fflush(stdout);
+  /* Wait for all tasks (tests) to complete.  As it turns out, this is the
+     variant with the least run-time overhead to the test threads. */
+  while (   apr_thread_pool_tasks_count(threads)
+         || apr_thread_pool_busy_count(threads))
+    apr_thread_yield();
+  
+  /* For some unknown reason, cleaning POOL (TEST_POOL in main()) does not
+     call the following reliably for all users. */
+  apr_thread_pool_destroy(threads);
 
-  skip_cleanup = test_failed;
+  /* Verify that we didn't skip any tasks. */
+  if (run_count != array_size)
+    {
+      printf("Parallel test failure: only %d of %d tests executed.\n",
+             (int)run_count, array_size);
+      return TRUE;
+    }
 
-  return test_failed;
+  return got_error != FALSE;
 }
 
+#endif
 
 static void help(const char *progname, apr_pool_t *pool)
 {
@@ -410,9 +615,9 @@ static svn_error_t *init_test_data(const
 }
 
 const char *
-svn_test_data_path(const char *basename, apr_pool_t *result_pool)
+svn_test_data_path(const char *base_name, apr_pool_t *result_pool)
 {
-  return svn_dirent_join(data_path, basename, result_pool);
+  return svn_dirent_join(data_path, base_name, result_pool);
 }
 
 
@@ -449,6 +654,12 @@ main(int argc, const char *argv[])
    * usage but make it thread-safe to allow for multi-threaded tests.
    */
   pool = apr_allocator_owner_get(svn_pool_create_allocator(TRUE));
+  err = svn_mutex__init(&log_mutex, TRUE, pool);
+  if (err)
+    {
+      svn_handle_error2(err, stderr, TRUE, "svn_tests: ");
+      svn_error_clear(err);
+    }
 
   /* Remember the command line */
   test_argc = argc;
@@ -538,6 +749,10 @@ main(int argc, const char *argv[])
         case fstype_opt:
           opts.fs_type = apr_pstrdup(pool, opt_arg);
           break;
+        case srcdir_opt:
+          SVN_INT_ERR(svn_utf_cstring_to_utf8(&opts.srcdir, opt_arg, pool));
+          opts.srcdir = svn_dirent_internal_style(opts.srcdir, pool);
+          break;
         case list_opt:
           list_mode = TRUE;
           break;
@@ -581,7 +796,13 @@ main(int argc, const char *argv[])
                 fprintf(stderr, "FAIL: Invalid minor version given\n");
                 exit(1);
               }
+            break;
           }
+#if HAVE_THREADPOOLS
+        case parallel_opt:
+          parallel = TRUE;
+          break;
+#endif
       }
     }
 
@@ -652,15 +873,33 @@ main(int argc, const char *argv[])
   if (! ran_a_test)
     {
       /* just run all tests */
-      for (i = 1; i <= array_size; i++)
+      if (svn_test_max_threads < 1)
+        svn_test_max_threads = array_size;
+
+      if (svn_test_max_threads == 1 || !parallel)
         {
-          if (do_test_num(prog_name, i, FALSE, &opts, NULL, test_pool))
-            got_error = TRUE;
+          for (i = 1; i <= array_size; i++)
+            {
+              if (do_test_num(prog_name, i, FALSE, &opts, NULL, test_pool))
+                got_error = TRUE;
+
+              /* Clear the per-function pool */
+              svn_pool_clear(test_pool);
+              svn_pool_clear(cleanup_pool);
+            }
+        }
+#if HAVE_THREADPOOLS
+      else
+        {
+          got_error = do_tests_concurrently(prog_name, array_size,
+                                            svn_test_max_threads,
+                                            &opts, test_pool);
 
-          /* Clear the per-function pool */
+          /* Execute all cleanups */
           svn_pool_clear(test_pool);
           svn_pool_clear(cleanup_pool);
         }
+#endif
     }
 
   /* Clean up APR */

Modified: subversion/branches/fsfs-improvements/tools/buildbot/slaves/win32-SharpSvn/svntest-bindings.cmd
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-improvements/tools/buildbot/slaves/win32-SharpSvn/svntest-bindings.cmd?rev=1545955&r1=1545954&r2=1545955&view=diff
==============================================================================
--- subversion/branches/fsfs-improvements/tools/buildbot/slaves/win32-SharpSvn/svntest-bindings.cmd (original)
+++ subversion/branches/fsfs-improvements/tools/buildbot/slaves/win32-SharpSvn/svntest-bindings.cmd Wed Nov 27 07:53:29 2013
@@ -22,29 +22,30 @@ SETLOCAL ENABLEEXTENSIONS ENABLEDELAYEDE
 
 CALL ..\svn-config.cmd
 IF ERRORLEVEL 1 EXIT /B 1
-ECHO ON
 
 IF "%SVN_BRANCH%" LEQ "1.6.x" (
-  ECHO --- Building 1.6.x or older: Skipping bindings ---
-  EXIT /B 0
+    ECHO --- Building 1.6.x or older: Skipping bindings ---
+    EXIT /B 0
 )
 
-PATH %PATH%;%TESTDIR%\bin
-SET result=0
+IF "%SVN_BRANCH%" LSS "1.9." (
+    IF NOT EXIST "%TESTDIR%\bin" MKDIR "%TESTDIR%\bin"
+    xcopy /y /i ..\deps\release\bin\*.dll "%TESTDIR%\bin"
 
-python win-tests.py -d -f fsfs --javahl "%TESTDIR%\tests"
-IF ERRORLEVEL 1 (
-  echo [python reported error !ERRORLEVEL!]
-  SET result=1
+    PATH %TESTDIR%\bin;!PATH!
 )
 
+SET result=0
+
 if "%SVN_BRANCH%" GTR "1.9." (
 
     python win-tests.py -r -f fsfs --swig=python "%TESTDIR%\tests"
 
     IF ERRORLEVEL 1 (
-        echo [Python tests exited with error !ERRORLEVEL!]
+        echo [Python tests reported error !ERRORLEVEL!] 1>&2
         SET result=1
+    ) ELSE (
+        echo Done.
     )
 
 ) ELSE (
@@ -61,8 +62,10 @@ if "%SVN_BRANCH%" GTR "1.9." (
 
     python subversion\bindings\swig\python\tests\run_all.py
     IF ERRORLEVEL 1 (
-        echo [Python tests exited with error !ERRORLEVEL!]
+        echo [Python tests reported error !ERRORLEVEL!] 1>&2
         SET result=1
+    ) ELSE (
+        echo Done.
     )
 )
 
@@ -71,8 +74,10 @@ if "%SVN_BRANCH%" GTR "1.9." (
     python win-tests.py -d -f fsfs --swig=perl "%TESTDIR%\tests"
 
     IF ERRORLEVEL 1 (
-        echo [Perl tests exited with error !ERRORLEVEL!]
-        SET result=1
+        echo [Perl tests reported error !ERRORLEVEL!] 1>&2
+        REM SET result=1
+    ) ELSE (
+        echo Done.
     )
 
 ) ELSE IF "%SVN_BRANCH%" GTR "1.8." (
@@ -94,19 +99,23 @@ if "%SVN_BRANCH%" GTR "1.9." (
     pushd subversion\bindings\swig\perl\native
     perl -MExtUtils::Command::MM -e "test_harness()" t\*.t
     IF ERRORLEVEL 1 (
-        echo [Perl reported error !ERRORLEVEL!]
+        echo [Test runner reported error !ERRORLEVEL!]
         SET result=1
     )
     popd
 )
 
 if "%SVN_BRANCH%" GTR "1.9." (
-  python win-tests.py -d -f fsfs --swig=ruby "%TESTDIR%\tests"
+    python win-tests.py -d -f fsfs --swig=ruby "%TESTDIR%\tests"
+
+    IF ERRORLEVEL 1 (
+        echo [Ruby tests reported error !ERRORLEVEL!] 1>&2
+        REM SET result=1
+    ) ELSE (
+        echo Done.
+    )
 
-  IF ERRORLEVEL 1 (
-    echo [Ruby tests reported error !ERRORLEVEL!] (not fatal)
-    REM SET result=1
-  )
+  taskkill /im svnserve.exe /f
 )
 
 exit /b %result%

Modified: subversion/branches/fsfs-improvements/tools/buildbot/slaves/win32-SharpSvn/svntest-build-bindings.cmd
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-improvements/tools/buildbot/slaves/win32-SharpSvn/svntest-build-bindings.cmd?rev=1545955&r1=1545954&r2=1545955&view=diff
==============================================================================
--- subversion/branches/fsfs-improvements/tools/buildbot/slaves/win32-SharpSvn/svntest-build-bindings.cmd (original)
+++ subversion/branches/fsfs-improvements/tools/buildbot/slaves/win32-SharpSvn/svntest-build-bindings.cmd Wed Nov 27 07:53:29 2013
@@ -28,7 +28,7 @@ IF "%SVN_BRANCH%" LEQ "1.6.x" (
   EXIT /B 0
 )
 
-SET DEBUG_TARGETS=/t:__JAVAHL__ /t:__JAVAHL_TESTS__
+SET DEBUG_TARGETS=/t:__ALL_TESTS__
 SET RELEASE_TARGETS=/t:__SWIG_PYTHON__
 
 if "%SVN_BRANCH%" GTR "1.8." (
@@ -39,10 +39,10 @@ if "%SVN_BRANCH%" GTR "1.9." (
   SET DEBUG_TARGETS=%DEBUG_TARGETS% /t:__SWIG_RUBY__
 )
 
-msbuild subversion_vcnet.sln /m /p:Configuration=Debug /p:Platform=win32 %DEBUG_TARGETS%
+msbuild subversion_vcnet.sln /m /v:m /p:Configuration=Debug /p:Platform=Win32 %DEBUG_TARGETS%
 IF ERRORLEVEL 1 EXIT /B 1
 
-msbuild subversion_vcnet.sln /p:Configuration=Release /p:Platform=win32 %RELEASE_TARGETS%
+msbuild subversion_vcnet.sln /m /v:m /p:Configuration=Release /p:Platform=Win32 %RELEASE_TARGETS%
 IF ERRORLEVEL 1 EXIT /B 1
 
-EXIT /B 0
\ No newline at end of file
+EXIT /B 0

Modified: subversion/branches/fsfs-improvements/tools/buildbot/slaves/win32-SharpSvn/svntest-build.cmd
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-improvements/tools/buildbot/slaves/win32-SharpSvn/svntest-build.cmd?rev=1545955&r1=1545954&r2=1545955&view=diff
==============================================================================
--- subversion/branches/fsfs-improvements/tools/buildbot/slaves/win32-SharpSvn/svntest-build.cmd (original)
+++ subversion/branches/fsfs-improvements/tools/buildbot/slaves/win32-SharpSvn/svntest-build.cmd Wed Nov 27 07:53:29 2013
@@ -25,10 +25,12 @@ IF ERRORLEVEL 1 EXIT /B 1
 
 PUSHD ..\deps
 
-nant gen-dev -D:wc=..\build -D:impBase=../deps/build/win32 -D:botBuild=true %NANTARGS%
+nant gen-dev -D:wc=..\build -D:impBase=../deps/build/win32 -D:botBuild=true %SVN_NANT_ARGS%
 IF ERRORLEVEL 1 EXIT /B 1
 
 POPD
 
-msbuild subversion_vcnet.sln /p:Configuration=Debug /p:Platform=win32 /t:__ALL_TESTS__
+msbuild subversion_vcnet.sln /m /v:m /p:Configuration=Debug /p:Platform=Win32 /t:__ALL_TESTS__ %SVN_MSBUILD_ARGS%
 IF ERRORLEVEL 1 EXIT /B 1
+
+EXIT /B 0

Modified: subversion/branches/fsfs-improvements/tools/buildbot/slaves/win32-SharpSvn/svntest-cleanup.cmd
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-improvements/tools/buildbot/slaves/win32-SharpSvn/svntest-cleanup.cmd?rev=1545955&r1=1545954&r2=1545955&view=diff
==============================================================================
--- subversion/branches/fsfs-improvements/tools/buildbot/slaves/win32-SharpSvn/svntest-cleanup.cmd (original)
+++ subversion/branches/fsfs-improvements/tools/buildbot/slaves/win32-SharpSvn/svntest-cleanup.cmd Wed Nov 27 07:53:29 2013
@@ -28,17 +28,17 @@ PUSHD ..\deps
 ECHO Checking dependencies in %CD%
 
 IF NOT EXIST "imports\" (
-  svn co --username guest --password "" http://sharpsvn.open.collab.net/svn/sharpsvn/trunk/imports imports
+    svn co --username guest --password "" http://sharpsvn.open.collab.net/svn/sharpsvn/trunk/imports imports
 )
 IF NOT EXIST build\imports.done (
-  svn up imports
-  copy /y imports\dev-default.build default.build
-  nant prep-dev %NANTARGS%
-  IF ERRORLEVEL 1 (
-    exit /B 1
-  )
-  del release\bin\*svn* release\bin\_*.* 2>nul:
-  echo. > build\imports.done
+    svn up imports
+    copy /y imports\dev-default.build default.build
+    nant prep-dev %NANTARGS%
+    IF ERRORLEVEL 1 (
+        EXIT /B 1
+    )
+    del release\bin\*svn* release\bin\_*.* 2>nul:
+    ECHO. > build\imports.done
 )
 
 POPD
@@ -50,6 +50,7 @@ IF NOT ERRORLEVEL 1 (
 POPD
 
 
+taskkill /im msbuild.exe /f 2> nul:
 taskkill /im svn.exe /f 2> nul:
 taskkill /im svnlook.exe /f 2> nul:
 taskkill /im svnadmin.exe /f 2> nul:
@@ -57,20 +58,23 @@ taskkill /im svnserve.exe /f 2> nul:
 taskkill /im svnrdump.exe /f 2> nul:
 taskkill /im svnsync.exe /f 2> nul:
 taskkill /im httpd.exe /f 2> nul:
+taskkill /im client-test.exe /f 2> nul:
 taskkill /im fs-test.exe /f 2> nul:
 taskkill /im op-depth-test.exe /f 2> nul:
 taskkill /im atomic-ra-revprop-change.exe /f 2> nul:
 taskkill /im java.exe /f 2> nul:
 taskkill /im perl.exe /f 2> nul:
+taskkill /im ruby.exe /f 2> nul:
 taskkill /im mspdbsrv.exe /f 2> nul:
-IF EXIST "%TESTDIR%\tests\subversion\tests\cmdline\httpd\" (
-  rmdir /s /q  "%TESTDIR%\tests\subversion\tests\cmdline\httpd"
-)
+
 IF EXIST "%TESTDIR%\swig\" (
-  rmdir /s /q  "%TESTDIR%\swig"
+    rmdir /s /q "%TESTDIR%\swig"
 )
 
-del "%TESTDIR%\tests\*.log" 2> nul:
-
+IF EXIST "%TESTDIR%\tests\" (
+    PUSHD "%TESTDIR%\tests\"
+    rmdir /s /q "%TESTDIR%\tests\" 2> nul:
+    POPD
+)
 
 exit /B 0

Modified: subversion/branches/fsfs-improvements/tools/buildbot/slaves/win32-SharpSvn/svntest-test.cmd
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-improvements/tools/buildbot/slaves/win32-SharpSvn/svntest-test.cmd?rev=1545955&r1=1545954&r2=1545955&view=diff
==============================================================================
--- subversion/branches/fsfs-improvements/tools/buildbot/slaves/win32-SharpSvn/svntest-test.cmd (original)
+++ subversion/branches/fsfs-improvements/tools/buildbot/slaves/win32-SharpSvn/svntest-test.cmd Wed Nov 27 07:53:29 2013
@@ -65,10 +65,12 @@ IF NOT "%1" == "" GOTO next
 
 taskkill /im svnserve.exe httpd.exe /f 2> nul:
 
-IF NOT EXIST "%TESTDIR%\bin" MKDIR "%TESTDIR%\bin"
-xcopy /y /i ..\deps\release\bin\*.dll "%TESTDIR%\bin"
+IF "%SVN_BRANCH%" LSS "1.9." (
+  IF NOT EXIST "%TESTDIR%\bin" MKDIR "%TESTDIR%\bin"
+  xcopy /y /i ..\deps\release\bin\*.dll "%TESTDIR%\bin"
 
-PATH %TESTDIR%\bin;%PATH%
+  PATH %TESTDIR%\bin;!PATH!
+)
 
 IF "%LOCAL%+%FSFS%" == "1+1" (
   echo win-tests.py -c %PARALLEL% %MODE% -f fsfs %ARGS% "%TESTDIR%\tests"

Modified: subversion/branches/fsfs-improvements/tools/client-side/svn-bench/cl.h
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-improvements/tools/client-side/svn-bench/cl.h?rev=1545955&r1=1545954&r2=1545955&view=diff
==============================================================================
--- subversion/branches/fsfs-improvements/tools/client-side/svn-bench/cl.h (original)
+++ subversion/branches/fsfs-improvements/tools/client-side/svn-bench/cl.h Wed Nov 27 07:53:29 2013
@@ -137,7 +137,7 @@ extern const apr_getopt_option_t svn_cl_
  *
  * Typically, error codes like SVN_ERR_UNVERSIONED_RESOURCE,
  * SVN_ERR_ENTRY_NOT_FOUND, etc, are supplied in varargs.  Don't
- * forget to terminate the argument list with SVN_NO_ERROR.
+ * forget to terminate the argument list with 0 (or APR_SUCCESS).
  */
 svn_error_t *
 svn_cl__try(svn_error_t *err,