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 2015/05/13 06:51:28 UTC

svn commit: r1679139 [7/7] - in /subversion/branches/1.10-cache-improvements: ./ build/ build/ac-macros/ build/generator/ build/generator/templates/ subversion/bindings/javahl/ subversion/bindings/javahl/native/ subversion/bindings/javahl/native/jniwra...

Modified: subversion/branches/1.10-cache-improvements/subversion/tests/cmdline/svntest/wc.py
URL: http://svn.apache.org/viewvc/subversion/branches/1.10-cache-improvements/subversion/tests/cmdline/svntest/wc.py?rev=1679139&r1=1679138&r2=1679139&view=diff
==============================================================================
--- subversion/branches/1.10-cache-improvements/subversion/tests/cmdline/svntest/wc.py (original)
+++ subversion/branches/1.10-cache-improvements/subversion/tests/cmdline/svntest/wc.py Wed May 13 04:51:26 2015
@@ -980,6 +980,20 @@ def svn_uri_quote(url):
 
 # ------------
 
+def python_sqlite_can_read_wc():
+  """Check if the Python builtin is capable enough to peek into wc.db"""
+
+  try:
+    db = svntest.sqlite3.connect('')
+
+    c = db.cursor()
+    c.execute('select sqlite_version()')
+    ver = tuple(map(int, c.fetchall()[0][0].split('.')))
+
+    return ver >= (3, 6, 18) # Currently enough (1.7-1.9)
+  except:
+    return False
+
 def open_wc_db(local_path):
   """Open the SQLite DB for the WC path LOCAL_PATH.
      Return (DB object, WC root path, WC relpath of LOCAL_PATH)."""

Modified: subversion/branches/1.10-cache-improvements/subversion/tests/cmdline/switch_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/1.10-cache-improvements/subversion/tests/cmdline/switch_tests.py?rev=1679139&r1=1679138&r2=1679139&view=diff
==============================================================================
--- subversion/branches/1.10-cache-improvements/subversion/tests/cmdline/switch_tests.py (original)
+++ subversion/branches/1.10-cache-improvements/subversion/tests/cmdline/switch_tests.py Wed May 13 04:51:26 2015
@@ -771,7 +771,7 @@ def refresh_read_only_attribute(sbox):
   # behavior, just skip the test.
   if os.name == 'posix':
     if os.geteuid() == 0:
-      raise svntest.Skip
+      raise svntest.Skip('Test doesn\'t work as uid 0')
 
   sbox.build()
   wc_dir = sbox.wc_dir

Modified: subversion/branches/1.10-cache-improvements/subversion/tests/cmdline/update_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/1.10-cache-improvements/subversion/tests/cmdline/update_tests.py?rev=1679139&r1=1679138&r2=1679139&view=diff
==============================================================================
--- subversion/branches/1.10-cache-improvements/subversion/tests/cmdline/update_tests.py (original)
+++ subversion/branches/1.10-cache-improvements/subversion/tests/cmdline/update_tests.py Wed May 13 04:51:26 2015
@@ -2227,6 +2227,7 @@ def forced_update_failures(sbox):
 # Test for issue #2556. The tests maps a virtual drive to a working copy
 # and tries some basic update, commit and status actions on the virtual
 # drive.
+@SkipUnless(svntest.main.is_os_windows)
 def update_wc_on_windows_drive(sbox):
   "update wc on the root of a Windows (virtual) drive"
 
@@ -2253,10 +2254,6 @@ def update_wc_on_windows_drive(sbox):
 
     return None
 
-  # Skip the test if not on Windows
-  if not svntest.main.windows:
-    raise svntest.Skip
-
   # just create an empty folder, we'll checkout later.
   sbox.build(create_wc = False)
   svntest.main.safe_rmtree(sbox.wc_dir)
@@ -2265,7 +2262,7 @@ def update_wc_on_windows_drive(sbox):
   # create a virtual drive to the working copy folder
   drive = find_the_next_available_drive_letter()
   if drive is None:
-    raise svntest.Skip
+    raise svntest.Skip('No drive letter available')
 
   subprocess.call(['subst', drive +':', sbox.wc_dir])
   wc_dir = drive + ':/'
@@ -5137,7 +5134,7 @@ def skip_access_denied(sbox):
   try:
     import msvcrt
   except ImportError:
-    raise svntest.Skip
+    raise svntest.Skip('python msvcrt library not available')
 
   sbox.build()
   wc_dir = sbox.wc_dir

Modified: subversion/branches/1.10-cache-improvements/subversion/tests/cmdline/upgrade_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/1.10-cache-improvements/subversion/tests/cmdline/upgrade_tests.py?rev=1679139&r1=1679138&r2=1679139&view=diff
==============================================================================
--- subversion/branches/1.10-cache-improvements/subversion/tests/cmdline/upgrade_tests.py (original)
+++ subversion/branches/1.10-cache-improvements/subversion/tests/cmdline/upgrade_tests.py Wed May 13 04:51:26 2015
@@ -1438,6 +1438,7 @@ def upgrade_1_7_dir_external(sbox):
   # svn: warning: W200033: sqlite[S5]: database is locked
   svntest.actions.run_and_verify_svn(None, [], 'upgrade', sbox.wc_dir)
 
+@SkipUnless(svntest.wc.python_sqlite_can_read_wc)
 def auto_analyze(sbox):
   """automatic SQLite ANALYZE"""
 

Modified: subversion/branches/1.10-cache-improvements/subversion/tests/libsvn_client/client-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.10-cache-improvements/subversion/tests/libsvn_client/client-test.c?rev=1679139&r1=1679138&r2=1679139&view=diff
==============================================================================
--- subversion/branches/1.10-cache-improvements/subversion/tests/libsvn_client/client-test.c (original)
+++ subversion/branches/1.10-cache-improvements/subversion/tests/libsvn_client/client-test.c Wed May 13 04:51:26 2015
@@ -1287,6 +1287,127 @@ test_copy_pin_externals(const svn_test_o
   return SVN_NO_ERROR;
 }
 
+/* issue #4560 */
+static svn_error_t *
+test_copy_pin_externals_select_subtree(const svn_test_opts_t *opts, apr_pool_t *pool)
+{
+  svn_opt_revision_t rev;
+  svn_opt_revision_t peg_rev;
+  const char *repos_url;
+  const char *A_copy_url;
+  const char *B_url;
+  const char *wc_path;
+  svn_client_ctx_t *ctx;
+  apr_hash_t *externals_to_pin;
+  apr_array_header_t *external_items;
+  apr_array_header_t *copy_sources;
+  svn_wc_external_item2_t item;
+  svn_client_copy_source_t copy_source;
+  apr_hash_t *props;
+  int i;
+  struct test_data {
+    const char *subtree_relpath;
+    const char *src_external_desc;
+    const char *expected_dst_external_desc;
+  } test_data[] = {
+    /* Note: these externals definitions contain extra whitespace on
+       purpose, to test that the pinning logic doesn't make
+       whitespace-only changes to values that aren't pinned. */
+
+    /* External on A/B will be pinned. */
+    { "B", "^/A/D/gamma  gamma-ext", "^/A/D/gamma@3 gamma-ext" },
+
+    /* External on A/D won't be pinned. */
+    { "D", "^/A/B/F  F-ext", "^/A/B/F  F-ext" } ,
+
+    { NULL },
+  };
+
+  /* Create a filesytem and repository containing the Greek tree. */
+  SVN_ERR(create_greek_repos(&repos_url, "pin-externals-select-subtree",
+                             opts, pool));
+
+  wc_path = svn_test_data_path("pin-externals-select-subtree-wc", pool);
+
+  /* Remove old test data from the previous run */
+  SVN_ERR(svn_io_remove_dir2(wc_path, TRUE, NULL, NULL, pool));
+
+  SVN_ERR(svn_io_make_dir_recursively(wc_path, pool));
+  svn_test_add_dir_cleanup(wc_path);
+
+  rev.kind = svn_opt_revision_head;
+  peg_rev.kind = svn_opt_revision_unspecified;
+  SVN_ERR(svn_client_create_context(&ctx, pool));
+
+  /* Configure externals. */
+  i = 0;
+  while (test_data[i].subtree_relpath)
+    {
+      const char *subtree_relpath;
+      const char *url;
+      const svn_string_t *propval;
+
+      subtree_relpath = test_data[i].subtree_relpath;
+      propval = svn_string_create(test_data[i].src_external_desc, pool);
+
+      url = apr_pstrcat(pool, repos_url, "/A/", subtree_relpath, SVN_VA_NULL);
+      SVN_ERR(svn_client_propset_remote(SVN_PROP_EXTERNALS, propval,
+                                        url, TRUE, 1, NULL,
+                                        NULL, NULL, ctx, pool));
+      i++;
+    }
+
+  /* Set up parameters for pinning externals on A/B. */
+  externals_to_pin = apr_hash_make(pool);
+
+  item.url = "^/A/D/gamma";
+  item.target_dir = "gamma-ext";
+
+  external_items = apr_array_make(pool, 2, sizeof(svn_wc_external_item2_t *));
+  APR_ARRAY_PUSH(external_items, svn_wc_external_item2_t *) = &item;
+  B_url = apr_pstrcat(pool, repos_url, "/A/B", SVN_VA_NULL);
+  svn_hash_sets(externals_to_pin, B_url, external_items);
+
+  /* Copy ^/A to ^/A_copy, pinning externals on ^/A/B. */
+  copy_source.path = apr_pstrcat(pool, repos_url, "/A", SVN_VA_NULL);
+  copy_source.revision = &rev;
+  copy_source.peg_revision = &peg_rev;
+  copy_sources = apr_array_make(pool, 1, sizeof(svn_client_copy_source_t *));
+  APR_ARRAY_PUSH(copy_sources, svn_client_copy_source_t *) = &copy_source;
+  A_copy_url = apr_pstrcat(pool, repos_url, "/A_copy", SVN_VA_NULL);
+  SVN_ERR(svn_client_copy7(copy_sources, A_copy_url, FALSE, FALSE,
+                           FALSE, FALSE, TRUE, externals_to_pin,
+                           NULL, NULL, NULL, ctx, pool));
+
+  /* Verify that externals were pinned as expected. */
+  i = 0;
+  while (test_data[i].subtree_relpath)
+    {
+      const char *subtree_relpath;
+      const char *url;
+      const svn_string_t *propval;
+      svn_stringbuf_t *externals_desc;
+      const char *expected_desc;
+
+      subtree_relpath = test_data[i].subtree_relpath;
+      url = apr_pstrcat(pool, A_copy_url, "/", subtree_relpath, SVN_VA_NULL);
+
+      SVN_ERR(svn_client_propget5(&props, NULL, SVN_PROP_EXTERNALS,
+                                  url, &peg_rev, &rev, NULL,
+                                  svn_depth_empty, NULL, ctx, pool, pool));
+      propval = svn_hash_gets(props, url);
+      SVN_TEST_ASSERT(propval);
+      externals_desc = svn_stringbuf_create(propval->data, pool);
+      svn_stringbuf_strip_whitespace(externals_desc);
+      expected_desc = test_data[i].expected_dst_external_desc;
+      SVN_TEST_STRING_ASSERT(externals_desc->data, expected_desc);
+
+      i++;
+    }
+
+  return SVN_NO_ERROR;
+}
+
 /* ========================================================================== */
 
 
@@ -1313,6 +1434,8 @@ static struct svn_test_descriptor_t test
                        "test svn_client_status6 with ignore_local_mods"),
     SVN_TEST_OPTS_PASS(test_copy_pin_externals,
                        "test svn_client_copy7 with externals_to_pin"),
+    SVN_TEST_OPTS_PASS(test_copy_pin_externals_select_subtree,
+                       "pin externals on selected subtrees only"),
     SVN_TEST_NULL
   };
 

Modified: subversion/branches/1.10-cache-improvements/subversion/tests/libsvn_fs/fs-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.10-cache-improvements/subversion/tests/libsvn_fs/fs-test.c?rev=1679139&r1=1679138&r2=1679139&view=diff
==============================================================================
--- subversion/branches/1.10-cache-improvements/subversion/tests/libsvn_fs/fs-test.c (original)
+++ subversion/branches/1.10-cache-improvements/subversion/tests/libsvn_fs/fs-test.c Wed May 13 04:51:26 2015
@@ -4268,7 +4268,7 @@ check_related(const svn_test_opts_t *opt
             if (i == j)
               {
                 /* Identical note. */
-                if (!related || relation != svn_fs_node_same)
+                if (!related || relation != svn_fs_node_unchanged)
                   {
                     return svn_error_createf
                       (SVN_ERR_TEST_FAILED, NULL,
@@ -4319,7 +4319,7 @@ check_related(const svn_test_opts_t *opt
                                          rev_root, path, subpool));
 
             /* They shall use the same noderevs */
-            if (relation != svn_fs_node_same)
+            if (relation != svn_fs_node_unchanged)
               {
                 return svn_error_createf
                   (SVN_ERR_TEST_FAILED, NULL,
@@ -4486,7 +4486,7 @@ check_txn_related(const svn_test_opts_t
             if (i == j)
               {
                 /* Identical noderev. */
-                if (!related || relation != svn_fs_node_same)
+                if (!related || relation != svn_fs_node_unchanged)
                   {
                     return svn_error_createf
                       (SVN_ERR_TEST_FAILED, NULL,
@@ -4525,7 +4525,7 @@ check_txn_related(const svn_test_opts_t
                                      root[0], "D", subpool));
 
         /* They shall use the same noderevs */
-        if (relation != svn_fs_node_same)
+        if (relation != svn_fs_node_unchanged)
           {
             return svn_error_createf
               (SVN_ERR_TEST_FAILED, NULL,
@@ -5610,100 +5610,6 @@ dir_prop_merge(const svn_test_opts_t *op
   return SVN_NO_ERROR;
 }
 
-#if APR_HAS_THREADS
-struct reopen_modify_baton_t {
-  const char *fs_path;
-  const char *txn_name;
-  apr_pool_t *pool;
-  svn_error_t *err;
-};
-
-static void * APR_THREAD_FUNC
-reopen_modify_child(apr_thread_t *tid, void *data)
-{
-  struct reopen_modify_baton_t *baton = data;
-  svn_fs_t *fs;
-  svn_fs_txn_t *txn;
-  svn_fs_root_t *root;
-
-  baton->err = svn_fs_open(&fs, baton->fs_path, NULL, baton->pool);
-  if (!baton->err)
-    baton->err = svn_fs_open_txn(&txn, fs, baton->txn_name, baton->pool);
-  if (!baton->err)
-    baton->err = svn_fs_txn_root(&root, txn, baton->pool);
-  if (!baton->err)
-    baton->err = svn_fs_change_node_prop(root, "A", "name",
-                                         svn_string_create("value",
-                                                           baton->pool),
-                                         baton->pool);
-  svn_pool_destroy(baton->pool);
-  apr_thread_exit(tid, 0);
-  return NULL;
-}
-#endif
-
-static svn_error_t *
-reopen_modify(const svn_test_opts_t *opts,
-              apr_pool_t *pool)
-{
-#if APR_HAS_THREADS
-  svn_fs_t *fs;
-  svn_revnum_t head_rev = 0;
-  svn_fs_root_t *root;
-  svn_fs_txn_t *txn;
-  const char *fs_path, *txn_name;
-  svn_string_t *value;
-  struct reopen_modify_baton_t baton;
-  apr_status_t status, child_status;
-  apr_threadattr_t *tattr;
-  apr_thread_t *tid;
-
-  /* Create test repository with greek tree. */
-  fs_path = "test-reopen-modify";
-  SVN_ERR(svn_test__create_fs(&fs, fs_path, opts, pool));
-  SVN_ERR(svn_fs_begin_txn(&txn, fs, head_rev, pool));
-  SVN_ERR(svn_fs_txn_root(&root, txn, pool));
-  SVN_ERR(svn_test__create_greek_tree(root, pool));
-  SVN_ERR(test_commit_txn(&head_rev, txn, NULL, pool));
-
-  /* Create txn with changes. */
-  SVN_ERR(svn_fs_begin_txn(&txn, fs, head_rev, pool));
-  SVN_ERR(svn_fs_txn_name(&txn_name, txn, pool));
-  SVN_ERR(svn_fs_txn_root(&root, txn, pool));
-  SVN_ERR(svn_fs_make_dir(root, "X", pool));
-
-  /* In another thread: reopen fs and txn, and add more changes.  This
-     works in BDB and FSX but in FSFS the txn_dir_cache becomes
-     out-of-date and the thread's changes don't reach the revision. */
-  baton.fs_path = fs_path;
-  baton.txn_name = txn_name;
-  baton.pool = svn_pool_create(pool);
-  status = apr_threadattr_create(&tattr, pool);
-  if (status)
-    return svn_error_wrap_apr(status, _("Can't create threadattr"));
-  status = apr_thread_create(&tid, tattr, reopen_modify_child, &baton, pool);
-  if (status)
-    return svn_error_wrap_apr(status, _("Can't create thread"));
-  status = apr_thread_join(&child_status, tid);
-  if (status)
-    return svn_error_wrap_apr(status, _("Can't join thread"));
-  if (baton.err)
-    return svn_error_trace(baton.err);
-
-  /* Commit */
-  SVN_ERR(test_commit_txn(&head_rev, txn, NULL, pool));
-
-  /* Check for change made by thread. */
-  SVN_ERR(svn_fs_revision_root(&root, fs, head_rev, pool));
-  SVN_ERR(svn_fs_node_prop(&value, root, "A", "name", pool));
-  SVN_TEST_ASSERT(value && !strcmp(value->data, "value"));
-
-  return SVN_NO_ERROR;
-#else
-  return svn_error_create(SVN_ERR_TEST_SKIPPED, NULL, "no thread support");
-#endif
-}
-
 static svn_error_t *
 upgrade_while_committing(const svn_test_opts_t *opts,
                          apr_pool_t *pool)
@@ -6524,7 +6430,7 @@ test_dir_optimal_order(const svn_test_op
 
   /* Call the API function we are interested in. */
   SVN_ERR(svn_fs_dir_entries(&unordered, root, "A", pool));
-  SVN_ERR(svn_fs_dir_optimal_order(&ordered, root, unordered, pool));
+  SVN_ERR(svn_fs_dir_optimal_order(&ordered, root, unordered, pool, pool));
 
   /* Verify that all entries are returned. */
   SVN_TEST_ASSERT(ordered->nelts == apr_hash_count(unordered));
@@ -7079,9 +6985,6 @@ static struct svn_test_descriptor_t test
                        "test svn_fs__compatible_version"),
     SVN_TEST_OPTS_PASS(dir_prop_merge,
                        "test merge directory properties"),
-    SVN_TEST_OPTS_XFAIL_OTOH(reopen_modify,
-                             "test reopen and modify txn",
-                             SVN_TEST_PASS_IF_FS_TYPE_IS_NOT("fsfs")),
     SVN_TEST_OPTS_PASS(upgrade_while_committing,
                        "upgrade while committing"),
     SVN_TEST_OPTS_PASS(test_paths_changed,

Modified: subversion/branches/1.10-cache-improvements/subversion/tests/libsvn_fs_fs/fs-fs-pack-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.10-cache-improvements/subversion/tests/libsvn_fs_fs/fs-fs-pack-test.c?rev=1679139&r1=1679138&r2=1679139&view=diff
==============================================================================
--- subversion/branches/1.10-cache-improvements/subversion/tests/libsvn_fs_fs/fs-fs-pack-test.c (original)
+++ subversion/branches/1.10-cache-improvements/subversion/tests/libsvn_fs_fs/fs-fs-pack-test.c Wed May 13 04:51:26 2015
@@ -1372,6 +1372,281 @@ plain_0_length(const svn_test_opts_t *op
 
 #undef REPO_NAME
 
+/* ------------------------------------------------------------------------ */
+
+#define REPO_NAME "test-repo-rep_sharing_effectiveness"
+
+static int
+count_substring(svn_stringbuf_t *string,
+                const char *needle)
+{
+  int count = 0;
+  apr_size_t len = strlen(needle);
+  apr_size_t pos;
+
+  for (pos = 0; pos + len <= string->len; ++pos)
+    if (memcmp(string->data + pos, needle, len) == 0)
+      ++count;
+
+  return count;
+}
+
+static svn_error_t *
+count_representations(int *count,
+                      svn_fs_t *fs,
+                      svn_revnum_t revision,
+                      apr_pool_t *pool)
+{
+  svn_stringbuf_t *rev_contents;
+  const char *rev_path = svn_fs_fs__path_rev_absolute(fs, revision, pool);
+  SVN_ERR(svn_stringbuf_from_file2(&rev_contents, rev_path, pool));
+
+  *count = count_substring(rev_contents, "PLAIN")
+         + count_substring(rev_contents, "DELTA");
+
+  return SVN_NO_ERROR;
+}
+
+/* Repeat string S many times to make it big enough for deltification etc.
+   to kick in. */
+static const char*
+multiply_string(const char *s,
+                apr_pool_t *pool)
+{
+  svn_stringbuf_t *temp = svn_stringbuf_create(s, pool);
+
+  int i;
+  for (i = 0; i < 7; ++i)
+    svn_stringbuf_insert(temp, temp->len, temp->data, temp->len);
+
+  return temp->data;
+}
+
+static svn_error_t *
+rep_sharing_effectiveness(const svn_test_opts_t *opts,
+                          apr_pool_t *pool)
+{
+  svn_fs_t *fs;
+  fs_fs_data_t *ffd;
+  svn_fs_txn_t *txn;
+  svn_fs_root_t *root;
+  svn_revnum_t rev;
+  const char *hello_str = multiply_string("Hello, ", pool);
+  const char *world_str = multiply_string("World!", pool);
+  const char *goodbye_str = multiply_string("Goodbye!", pool);
+
+  if (strcmp(opts->fs_type, "fsfs") != 0)
+    return svn_error_create(SVN_ERR_TEST_SKIPPED, NULL, NULL);
+
+  /* Create a repo that and explicitly enable rep sharing. */
+  SVN_ERR(svn_test__create_fs(&fs, REPO_NAME, opts, pool));
+
+  ffd = fs->fsap_data;
+  if (ffd->format < SVN_FS_FS__MIN_REP_SHARING_FORMAT)
+    return svn_error_create(SVN_ERR_TEST_SKIPPED, NULL, NULL);
+
+  ffd->rep_sharing_allowed = TRUE;
+
+  /* Revision 1: create 2 files with different content. */
+  SVN_ERR(svn_fs_begin_txn(&txn, fs, 0, pool));
+  SVN_ERR(svn_fs_txn_root(&root, txn, pool));
+  SVN_ERR(svn_fs_make_file(root, "foo", pool));
+  SVN_ERR(svn_test__set_file_contents(root, "foo", hello_str, pool));
+  SVN_ERR(svn_fs_make_file(root, "bar", pool));
+  SVN_ERR(svn_test__set_file_contents(root, "bar", world_str, pool));
+  SVN_ERR(svn_fs_commit_txn(NULL, &rev, txn, pool));
+
+  /* Revision 2: modify a file to match another file's r1 content and
+                 add another with the same content.
+                 (classic rep-sharing). */
+  SVN_ERR(svn_fs_begin_txn(&txn, fs, rev, pool));
+  SVN_ERR(svn_fs_txn_root(&root, txn, pool));
+  SVN_ERR(svn_test__set_file_contents(root, "foo", world_str, pool));
+  SVN_ERR(svn_fs_make_file(root, "baz", pool));
+  SVN_ERR(svn_test__set_file_contents(root, "baz", hello_str, pool));
+  SVN_ERR(svn_fs_commit_txn(NULL, &rev, txn, pool));
+
+  /* Revision 3: modify all files to some new, identical content and add
+                 another with the same content.
+                 (in-revision rep-sharing). */
+  SVN_ERR(svn_fs_begin_txn(&txn, fs, rev, pool));
+  SVN_ERR(svn_fs_txn_root(&root, txn, pool));
+  SVN_ERR(svn_test__set_file_contents(root, "foo", goodbye_str, pool));
+  SVN_ERR(svn_test__set_file_contents(root, "bar", goodbye_str, pool));
+  SVN_ERR(svn_test__set_file_contents(root, "baz", goodbye_str, pool));
+  SVN_ERR(svn_fs_make_file(root, "qux", pool));
+  SVN_ERR(svn_test__set_file_contents(root, "qux", goodbye_str, pool));
+  SVN_ERR(svn_fs_commit_txn(NULL, &rev, txn, pool));
+
+  /* Verify revision contents. */
+  {
+    const struct {
+      svn_revnum_t revision;
+      const char *file;
+      const char *contents;
+    } expected[] = {
+      { 1, "foo", "Hello, " },
+      { 1, "bar", "World!" },
+      { 2, "foo", "World!" },
+      { 2, "bar", "World!" },
+      { 2, "baz", "Hello, " },
+      { 3, "foo", "Goodbye!" },
+      { 3, "bar", "Goodbye!" },
+      { 3, "baz", "Goodbye!" },
+      { 3, "qux", "Goodbye!" },
+      { SVN_INVALID_REVNUM, NULL, NULL }
+    };
+
+    int i;
+    apr_pool_t *iterpool = svn_pool_create(pool);
+    for (i = 0; SVN_IS_VALID_REVNUM(expected[i].revision); ++i)
+      {
+        svn_stringbuf_t *str;
+
+        SVN_ERR(svn_fs_revision_root(&root, fs, expected[i].revision,
+                                     iterpool));
+        SVN_ERR(svn_test__get_file_contents(root, expected[i].file, &str,
+                                            iterpool));
+
+        SVN_TEST_STRING_ASSERT(str->data,
+                               multiply_string(expected[i].contents,
+                                               iterpool));
+      }
+
+    svn_pool_destroy(iterpool);
+  }
+
+  /* Verify that rep sharing eliminated most reps. */
+  {
+    /* Number of expected representations (including the root directory). */
+    const int expected[] = { 1, 3, 1, 2 } ;
+
+    svn_revnum_t i;
+    apr_pool_t *iterpool = svn_pool_create(pool);
+    for (i = 0; i <= rev; ++i)
+      {
+        int count;
+        SVN_ERR(count_representations(&count, fs, i, iterpool));
+        SVN_TEST_ASSERT(count == expected[i]);
+      }
+
+    svn_pool_destroy(iterpool);
+  }
+
+  return SVN_NO_ERROR;
+}
+
+#undef REPO_NAME
+
+/* ------------------------------------------------------------------------ */
+
+#define REPO_NAME "test-repo-delta_chain_with_plain"
+
+static svn_error_t *
+delta_chain_with_plain(const svn_test_opts_t *opts,
+                       apr_pool_t *pool)
+{
+  svn_fs_t *fs;
+  fs_fs_data_t *ffd;
+  svn_fs_txn_t *txn;
+  svn_fs_root_t *root;
+  svn_revnum_t rev;
+  svn_stringbuf_t *prop_value, *contents, *contents2, *hash_rep;
+  int i;
+  apr_hash_t *fs_config, *props;
+
+  if (strcmp(opts->fs_type, "fsfs") != 0)
+    return svn_error_create(SVN_ERR_TEST_SKIPPED, NULL, NULL);
+
+  /* Reproducing issue #4577 without the r1676667 fix is much harder in 1.9+
+   * than it was in 1.8.  The reason is that 1.9+ won't deltify small reps
+   * nor against small reps.  So, we must construct relatively large PLAIN
+   * and DELTA reps.
+   *
+   * The idea is to construct a PLAIN prop rep, make a file share that as
+   * its text rep, grow the file considerably (to make the PLAIN rep later
+   * read beyond EOF) and then replace it entirely with another longish
+   * contents.
+   */
+
+  /* Create a repo that and explicitly enable rep sharing. */
+  SVN_ERR(svn_test__create_fs(&fs, REPO_NAME, opts, pool));
+
+  ffd = fs->fsap_data;
+  if (ffd->format < SVN_FS_FS__MIN_REP_SHARING_FORMAT)
+    return svn_error_create(SVN_ERR_TEST_SKIPPED, NULL, NULL);
+
+  ffd->rep_sharing_allowed = TRUE;
+
+  /* Make sure all props are stored as PLAIN reps. */
+  ffd->deltify_properties = FALSE;
+
+  /* Construct various content strings.
+   * Note that props need to be shorter than the file contents. */
+  prop_value = svn_stringbuf_create("prop", pool);
+  for (i = 0; i < 10; ++i)
+    svn_stringbuf_appendstr(prop_value, prop_value);
+
+  contents = svn_stringbuf_create("Some text.", pool);
+  for (i = 0; i < 10; ++i)
+    svn_stringbuf_appendstr(contents, contents);
+
+  contents2 = svn_stringbuf_create("Totally new!", pool);
+  for (i = 0; i < 10; ++i)
+    svn_stringbuf_appendstr(contents2, contents2);
+
+  /* Revision 1: create a property rep. */
+  SVN_ERR(svn_fs_begin_txn(&txn, fs, 0, pool));
+  SVN_ERR(svn_fs_txn_root(&root, txn, pool));
+  SVN_ERR(svn_fs_change_node_prop(root, "/", "p",
+                                  svn_string_create(prop_value->data, pool),
+                                  pool));
+  SVN_ERR(svn_fs_commit_txn(NULL, &rev, txn, pool));
+
+  /* Revision 2: create a file that shares the text rep with the PLAIN
+   * property rep from r1. */
+  props = apr_hash_make(pool);
+  svn_hash_sets(props, "p", svn_string_create(prop_value->data, pool));
+
+  hash_rep = svn_stringbuf_create_empty(pool);
+  svn_hash_write2(props, svn_stream_from_stringbuf(hash_rep, pool), "END",
+                  pool);
+
+  SVN_ERR(svn_fs_begin_txn(&txn, fs, rev, pool));
+  SVN_ERR(svn_fs_txn_root(&root, txn, pool));
+  SVN_ERR(svn_fs_make_file(root, "foo", pool));
+  SVN_ERR(svn_test__set_file_contents(root, "foo", hash_rep->data, pool));
+  SVN_ERR(svn_fs_commit_txn(NULL, &rev, txn, pool));
+
+  /* Revision 3: modify the file contents to a long-ish full text
+   * (~10kByte, longer than the r1 revision file). */
+  SVN_ERR(svn_fs_begin_txn(&txn, fs, rev, pool));
+  SVN_ERR(svn_fs_txn_root(&root, txn, pool));
+  SVN_ERR(svn_test__set_file_contents(root, "foo", contents->data, pool));
+  SVN_ERR(svn_fs_commit_txn(NULL, &rev, txn, pool));
+
+  /* Revision 4: replace file contents to something disjoint from r3. */
+  SVN_ERR(svn_fs_begin_txn(&txn, fs, rev, pool));
+  SVN_ERR(svn_fs_txn_root(&root, txn, pool));
+  SVN_ERR(svn_test__set_file_contents(root, "foo", contents2->data, pool));
+  SVN_ERR(svn_fs_commit_txn(NULL, &rev, txn, pool));
+
+  /* Getting foo@4 must work.  To make sure we actually read from disk,
+   * use a new FS instance with disjoint caches. */
+  fs_config = apr_hash_make(pool);
+  svn_hash_sets(fs_config, SVN_FS_CONFIG_FSFS_CACHE_NS,
+                           svn_uuid_generate(pool));
+  SVN_ERR(svn_fs_open2(&fs, REPO_NAME, fs_config, pool, pool));
+
+  SVN_ERR(svn_fs_revision_root(&root, fs, rev, pool));
+  SVN_ERR(svn_test__get_file_contents(root, "foo", &contents, pool));
+  SVN_TEST_STRING_ASSERT(contents->data, contents2->data);
+
+  return SVN_NO_ERROR;
+}
+
+#undef REPO_NAME
+
 
 /* The test table.  */
 
@@ -1416,6 +1691,10 @@ static struct svn_test_descriptor_t test
                        "id parser test"),
     SVN_TEST_OPTS_PASS(plain_0_length,
                        "file with 0 expanded-length, issue #4554"),
+    SVN_TEST_OPTS_PASS(rep_sharing_effectiveness,
+                       "rep-sharing effectiveness"),
+    SVN_TEST_OPTS_PASS(delta_chain_with_plain,
+                       "delta chains starting with PLAIN, issue #4577"),
     SVN_TEST_NULL
   };
 

Modified: subversion/branches/1.10-cache-improvements/subversion/tests/libsvn_ra/ra-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.10-cache-improvements/subversion/tests/libsvn_ra/ra-test.c?rev=1679139&r1=1679138&r2=1679139&view=diff
==============================================================================
--- subversion/branches/1.10-cache-improvements/subversion/tests/libsvn_ra/ra-test.c (original)
+++ subversion/branches/1.10-cache-improvements/subversion/tests/libsvn_ra/ra-test.c Wed May 13 04:51:26 2015
@@ -1440,6 +1440,83 @@ errors_from_callbacks(const svn_test_opt
   return SVN_NO_ERROR;
 }
 
+static svn_error_t *
+ra_list_has_props(const svn_test_opts_t *opts,
+                  apr_pool_t *pool)
+{
+  svn_ra_session_t *ra_session;
+  const svn_delta_editor_t *editor;
+  apr_pool_t *iterpool = svn_pool_create(pool);
+  int i;
+  void *edit_baton;
+  const char *trunk_url;
+
+  SVN_ERR(make_and_open_repos(&ra_session, "ra_list_has_props",
+                              opts, pool));
+
+  SVN_ERR(svn_ra_get_commit_editor3(ra_session, &editor, &edit_baton,
+                                    apr_hash_make(pool), NULL,
+                                    NULL, NULL, FALSE, iterpool));
+
+  /* Create initial layout*/
+  {
+    void *root_baton;
+    void *dir_baton;
+
+    SVN_ERR(editor->open_root(edit_baton, 0, pool, &root_baton));
+    SVN_ERR(editor->add_directory("trunk", root_baton, NULL, SVN_INVALID_REVNUM,
+                                  iterpool, &dir_baton));
+    SVN_ERR(editor->close_directory(dir_baton, iterpool));
+    SVN_ERR(editor->add_directory("tags", root_baton, NULL, SVN_INVALID_REVNUM,
+                                  iterpool, &dir_baton));
+    SVN_ERR(editor->close_directory(dir_baton, iterpool));
+    SVN_ERR(editor->close_directory(root_baton, iterpool));
+    SVN_ERR(editor->close_edit(edit_baton, iterpool));
+  }
+
+  SVN_ERR(svn_ra_get_repos_root2(ra_session, &trunk_url, pool));
+  trunk_url = svn_path_url_add_component2(trunk_url, "trunk", pool);
+
+  /* Create a few tags. Using a value like 8000 will take too long for a normal
+     testrun, but produces more realistic problems */
+  for (i = 0; i < 50; i++)
+    {
+      void *root_baton;
+      void *tags_baton;
+      void *dir_baton;
+
+      svn_pool_clear(iterpool);
+
+      SVN_ERR(svn_ra_get_commit_editor3(ra_session, &editor, &edit_baton,
+                                        apr_hash_make(pool), NULL,
+                                        NULL, NULL, FALSE, iterpool));
+
+      SVN_ERR(editor->open_root(edit_baton, i+1, pool, &root_baton));
+      SVN_ERR(editor->open_directory("tags", root_baton, i+1, iterpool,
+                                     &tags_baton));
+      SVN_ERR(editor->add_directory(apr_psprintf(iterpool, "tags/T%05d", i+1),
+                                    tags_baton, trunk_url, 1, iterpool,
+                                    &dir_baton));
+
+      SVN_ERR(editor->close_directory(dir_baton, iterpool));
+      SVN_ERR(editor->close_directory(tags_baton, iterpool));
+      SVN_ERR(editor->close_directory(root_baton, iterpool));
+      SVN_ERR(editor->close_edit(edit_baton, iterpool));
+    }
+
+  {
+    apr_hash_t *dirents;
+    svn_revnum_t fetched_rev;
+    apr_hash_t *props;
+
+    SVN_ERR(svn_ra_get_dir2(ra_session, &dirents, &fetched_rev, &props,
+                            "tags", SVN_INVALID_REVNUM,
+                            SVN_DIRENT_ALL, pool));
+  }
+
+  return SVN_NO_ERROR;
+}
+
 
 /* The test table.  */
 
@@ -1468,6 +1545,8 @@ static struct svn_test_descriptor_t test
                        "check how ra functions handle bad revisions"),
     SVN_TEST_OPTS_PASS(errors_from_callbacks,
                        "check how ra layers handle errors from callbacks"),
+    SVN_TEST_OPTS_PASS(ra_list_has_props,
+                       "check list has_props performance"),
     SVN_TEST_NULL
   };
 

Modified: subversion/branches/1.10-cache-improvements/subversion/tests/libsvn_subr/cache-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.10-cache-improvements/subversion/tests/libsvn_subr/cache-test.c?rev=1679139&r1=1679138&r2=1679139&view=diff
==============================================================================
--- subversion/branches/1.10-cache-improvements/subversion/tests/libsvn_subr/cache-test.c (original)
+++ subversion/branches/1.10-cache-improvements/subversion/tests/libsvn_subr/cache-test.c Wed May 13 04:51:26 2015
@@ -34,6 +34,39 @@
 
 #include "../svn_test.h"
 
+/* Create memcached cache if configured */
+static svn_error_t *
+create_memcache(svn_memcache_t **memcache,
+                const svn_test_opts_t *opts,
+                apr_pool_t *result_pool,
+                apr_pool_t *scratch_pool)
+{
+  svn_config_t *config = NULL;
+  if (opts->config_file)
+    {
+      SVN_ERR(svn_config_read3(&config, opts->config_file,
+                               TRUE, FALSE, FALSE, scratch_pool));
+    }
+  else if (opts->memcached_server)
+    {
+      SVN_ERR(svn_config_create2(&config, FALSE, FALSE, scratch_pool));
+
+      svn_config_set(config, SVN_CACHE_CONFIG_CATEGORY_MEMCACHED_SERVERS,
+                     "key" /* some value; ignored*/,
+                     opts->memcached_server);
+    }
+
+  if (config)
+    {
+      SVN_ERR(svn_cache__make_memcache_from_config(memcache, config,
+                                                   result_pool, scratch_pool));
+    }
+  else
+    *memcache = NULL;
+
+  return SVN_NO_ERROR;
+}
+
 /* Implements svn_cache__serialize_func_t */
 static svn_error_t *
 serialize_revnum(void **data,
@@ -147,20 +180,12 @@ test_memcache_basic(const svn_test_opts_
                     apr_pool_t *pool)
 {
   svn_cache__t *cache;
-  svn_config_t *config;
   svn_memcache_t *memcache = NULL;
   const char *prefix = apr_psprintf(pool,
                                     "test_memcache_basic-%" APR_TIME_T_FMT,
                                     apr_time_now());
 
-  if (opts->config_file)
-    {
-      SVN_ERR(svn_config_read3(&config, opts->config_file,
-                               TRUE, FALSE, FALSE, pool));
-      SVN_ERR(svn_cache__make_memcache_from_config(&memcache, config,
-                                                   pool, pool));
-    }
-
+  SVN_ERR(create_memcache(&memcache, opts, pool, pool));
   if (! memcache)
     return svn_error_create(SVN_ERR_TEST_SKIPPED, NULL,
                             "not configured to use memcached");
@@ -306,7 +331,6 @@ test_memcache_long_key(const svn_test_op
                        apr_pool_t *pool)
 {
   svn_cache__t *cache;
-  svn_config_t *config;
   svn_memcache_t *memcache = NULL;
   svn_revnum_t fifty = 50, *answer;
   svn_boolean_t found = FALSE;
@@ -322,13 +346,7 @@ test_memcache_long_key(const svn_test_op
     "0123456789" "0123456789" "0123456789" "0123456789" "0123456789" /* 300 */
     ;
 
-  if (opts->config_file)
-    {
-      SVN_ERR(svn_config_read3(&config, opts->config_file,
-                               TRUE, FALSE, FALSE, pool));
-      SVN_ERR(svn_cache__make_memcache_from_config(&memcache, config,
-                                                   pool, pool));
-    }
+  SVN_ERR(create_memcache(&memcache, opts, pool, pool));
 
   if (! memcache)
     return svn_error_create(SVN_ERR_TEST_SKIPPED, NULL,
@@ -471,6 +489,107 @@ test_null_cache(apr_pool_t *pool)
   return SVN_NO_ERROR;
 }
 
+static svn_error_t *
+test_membuffer_unaligned_string_keys(apr_pool_t *pool)
+{
+  svn_cache__t *cache;
+  svn_membuffer_t *membuffer;
+  svn_revnum_t fifty = 50;
+  svn_revnum_t *answer;
+  svn_boolean_t found = FALSE;
+
+  /* Allocate explicitly to have aligned string and this add one
+   * to have unaligned string.*/
+  const char *aligned_key = apr_pstrdup(pool, "fifty");
+  const char *unaligned_key = apr_pstrdup(pool, "_fifty") + 1;
+  const char *unaligned_prefix = apr_pstrdup(pool, "_cache:") + 1;
+
+  SVN_ERR(svn_cache__membuffer_cache_create(&membuffer, 10*1024, 1, 0,
+                                            TRUE, TRUE, pool));
+
+  /* Create a cache with just one entry. */
+  SVN_ERR(svn_cache__create_membuffer_cache(
+            &cache, membuffer, serialize_revnum, deserialize_revnum,
+            APR_HASH_KEY_STRING, unaligned_prefix,
+            SVN_CACHE__MEMBUFFER_DEFAULT_PRIORITY, FALSE, FALSE,
+            pool, pool));
+
+  SVN_ERR(svn_cache__set(cache, unaligned_key, &fifty, pool));
+  SVN_ERR(svn_cache__get((void **) &answer, &found, cache, unaligned_key,
+                         pool));
+
+  if (! found)
+    return svn_error_create(SVN_ERR_TEST_FAILED, NULL,
+                            "cache failed to find entry for 'fifty'");
+  if (*answer != 50)
+    return svn_error_createf(SVN_ERR_TEST_FAILED, NULL,
+                             "expected 50 but found '%ld'", *answer);
+
+  /* Make sure that we get proper result when providing aligned key*/
+  SVN_ERR(svn_cache__get((void **) &answer, &found, cache, aligned_key,
+                         pool));
+
+  if (! found)
+    return svn_error_create(SVN_ERR_TEST_FAILED, NULL,
+                            "cache failed to find entry for 'fifty'");
+  if (*answer != 50)
+    return svn_error_createf(SVN_ERR_TEST_FAILED, NULL,
+                             "expected 50 but found '%ld'", *answer);
+
+  return SVN_NO_ERROR;
+}
+
+static svn_error_t *
+test_membuffer_unaligned_fixed_keys(apr_pool_t *pool)
+{
+  svn_cache__t *cache;
+  svn_membuffer_t *membuffer;
+  svn_revnum_t fifty = 50;
+  svn_revnum_t *answer;
+  svn_boolean_t found = FALSE;
+
+  /* Allocate explicitly to have aligned string and this add one
+   * to have unaligned key.*/
+  const char *aligned_key = apr_pstrdup(pool, "12345678");
+  const char *unaligned_key = apr_pstrdup(pool, "_12345678") + 1;
+  const char *unaligned_prefix = apr_pstrdup(pool, "_cache:") + 1;
+
+  SVN_ERR(svn_cache__membuffer_cache_create(&membuffer, 10*1024, 1, 0,
+                                            TRUE, TRUE, pool));
+
+  /* Create a cache with just one entry. */
+  SVN_ERR(svn_cache__create_membuffer_cache(
+            &cache, membuffer, serialize_revnum, deserialize_revnum,
+            8 /* klen*/,
+            unaligned_prefix,
+            SVN_CACHE__MEMBUFFER_DEFAULT_PRIORITY, FALSE, FALSE,
+            pool, pool));
+
+  SVN_ERR(svn_cache__set(cache, unaligned_key, &fifty, pool));
+  SVN_ERR(svn_cache__get((void **) &answer, &found, cache, unaligned_key,
+                         pool));
+
+  if (! found)
+    return svn_error_create(SVN_ERR_TEST_FAILED, NULL,
+                            "cache failed to find entry for '12345678' (unaligned)");
+  if (*answer != 50)
+    return svn_error_createf(SVN_ERR_TEST_FAILED, NULL,
+                             "expected 50 but found '%ld'", *answer);
+
+  /* Make sure that we get proper result when providing aligned key*/
+  SVN_ERR(svn_cache__get((void **) &answer, &found, cache, aligned_key,
+                         pool));
+
+  if (! found)
+    return svn_error_create(SVN_ERR_TEST_FAILED, NULL,
+                            "cache failed to find entry for '12345678' (aligned)");
+  if (*answer != 50)
+    return svn_error_createf(SVN_ERR_TEST_FAILED, NULL,
+                             "expected 50 but found '%ld'", *answer);
+
+  return SVN_NO_ERROR;
+}
+
 
 /* The test table.  */
 
@@ -493,6 +612,10 @@ static struct svn_test_descriptor_t test
                    "test clearing a membuffer svn_cache"),
     SVN_TEST_PASS2(test_null_cache,
                    "basic null svn_cache test"),
+    SVN_TEST_PASS2(test_membuffer_unaligned_string_keys,
+                   "test membuffer cache with unaligned string keys"),
+    SVN_TEST_PASS2(test_membuffer_unaligned_fixed_keys,
+                   "test membuffer cache with unaligned fixed keys"),
     SVN_TEST_NULL
   };
 

Modified: subversion/branches/1.10-cache-improvements/subversion/tests/libsvn_subr/checksum-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.10-cache-improvements/subversion/tests/libsvn_subr/checksum-test.c?rev=1679139&r1=1679138&r2=1679139&view=diff
==============================================================================
--- subversion/branches/1.10-cache-improvements/subversion/tests/libsvn_subr/checksum-test.c (original)
+++ subversion/branches/1.10-cache-improvements/subversion/tests/libsvn_subr/checksum-test.c Wed May 13 04:51:26 2015
@@ -254,6 +254,26 @@ zlib_expansion_test(const svn_test_opts_
   return SVN_NO_ERROR;
 }
 
+static svn_error_t *
+test_serialization(apr_pool_t *pool)
+{
+  svn_checksum_kind_t kind;
+  for (kind = svn_checksum_md5; kind <= svn_checksum_fnv1a_32x4; ++kind)
+    {
+      const svn_checksum_t *parsed_checksum;
+      svn_checksum_t *checksum = svn_checksum_empty_checksum(kind, pool);
+      const char *serialized = svn_checksum_serialize(checksum, pool, pool);
+
+      SVN_ERR(svn_checksum_deserialize(&parsed_checksum, serialized, pool,
+                                       pool));
+
+      SVN_TEST_ASSERT(parsed_checksum->kind == kind);
+      SVN_TEST_ASSERT(svn_checksum_match(checksum, parsed_checksum));
+    }
+
+  return SVN_NO_ERROR;
+}
+
 /* An array of all test functions */
 
 static int max_threads = 1;
@@ -271,6 +291,8 @@ static struct svn_test_descriptor_t test
                        "zlib expansion test (zlib regression)"),
     SVN_TEST_PASS2(zero_cross_match,
                    "zero checksum cross-type matching"),
+    SVN_TEST_PASS2(test_serialization,
+                   "checksum (de-)serialization"),
     SVN_TEST_NULL
   };
 

Modified: subversion/branches/1.10-cache-improvements/subversion/tests/libsvn_subr/io-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.10-cache-improvements/subversion/tests/libsvn_subr/io-test.c?rev=1679139&r1=1679138&r2=1679139&view=diff
==============================================================================
--- subversion/branches/1.10-cache-improvements/subversion/tests/libsvn_subr/io-test.c (original)
+++ subversion/branches/1.10-cache-improvements/subversion/tests/libsvn_subr/io-test.c Wed May 13 04:51:26 2015
@@ -30,8 +30,10 @@
 
 #include "svn_pools.h"
 #include "svn_string.h"
+#include "svn_io.h"
 #include "private/svn_skel.h"
 #include "private/svn_dep_compat.h"
+#include "private/svn_io_private.h"
 
 #include "../svn_test.h"
 #include "../svn_test_fs.h"
@@ -737,6 +739,49 @@ ignore_enoent(apr_pool_t *pool)
   return SVN_NO_ERROR;
 }
 
+static svn_error_t *
+test_install_stream_to_longpath(apr_pool_t *pool)
+{
+  const char *tmp_dir;
+  const char *final_abspath;
+  const char *deep_dir;
+  svn_stream_t *stream;
+  svn_stringbuf_t *actual_content;
+  int i;
+
+  /* Create an empty directory. */
+  SVN_ERR(svn_dirent_get_absolute(&tmp_dir, "test_install_stream_to_longpath",
+                                  pool));
+  SVN_ERR(svn_io_remove_dir2(tmp_dir, TRUE, NULL, NULL, pool));
+  SVN_ERR(svn_io_make_dir_recursively(tmp_dir, pool));
+  svn_test_add_dir_cleanup(tmp_dir);
+
+  deep_dir = tmp_dir;
+
+  /* Generate very long path (> 260 symbols) */
+  for (i = 0; i < 26; i++)
+    {
+      deep_dir = svn_dirent_join(deep_dir, "1234567890", pool);
+      SVN_ERR(svn_io_make_dir_recursively(deep_dir, pool));
+    }
+
+  final_abspath = svn_dirent_join(deep_dir, "stream1", pool);
+  SVN_ERR(svn_stream__create_for_install(&stream, deep_dir, pool, pool));
+  SVN_ERR(svn_stream_puts(stream, "stream1 content"));
+  SVN_ERR(svn_stream_close(stream));
+  SVN_ERR(svn_stream__install_stream(stream,
+                                     final_abspath,
+                                     TRUE,
+                                     pool));
+
+  SVN_ERR(svn_stringbuf_from_file2(&actual_content,
+                                   final_abspath,
+                                   pool));
+
+  SVN_TEST_STRING_ASSERT(actual_content->data, "stream1 content");
+
+  return SVN_NO_ERROR;
+}
 
 /* The test table.  */
 
@@ -759,6 +804,8 @@ static struct svn_test_descriptor_t test
                    "test aligned seek"),
     SVN_TEST_PASS2(ignore_enoent,
                    "test ignore-enoent"),
+    SVN_TEST_PASS2(test_install_stream_to_longpath,
+                   "test svn_stream__install_stream to long path"),
     SVN_TEST_NULL
   };
 

Modified: subversion/branches/1.10-cache-improvements/subversion/tests/libsvn_wc/op-depth-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.10-cache-improvements/subversion/tests/libsvn_wc/op-depth-test.c?rev=1679139&r1=1679138&r2=1679139&view=diff
==============================================================================
--- subversion/branches/1.10-cache-improvements/subversion/tests/libsvn_wc/op-depth-test.c (original)
+++ subversion/branches/1.10-cache-improvements/subversion/tests/libsvn_wc/op-depth-test.c Wed May 13 04:51:26 2015
@@ -3622,6 +3622,17 @@ revert_file_externals(const svn_test_opt
     SVN_ERR(check_db_rows(&b, "", rows));
   }
 
+  SVN_ERR(sbox_wc_update(&b, "", 1));
+  {
+    nodes_row_t rows[] = {
+      { 0, "",    "normal",      1, "" },
+      { 0, "f",   "normal",      1, "f" },
+      { 0, "g",   "normal",      1, "f", TRUE },
+      { 0 }
+    };
+    SVN_ERR(check_db_rows(&b, "", rows));
+  }
+
   return SVN_NO_ERROR;
 }
 
@@ -12086,7 +12097,7 @@ static struct svn_test_descriptor_t test
     SVN_TEST_OPTS_PASS(test_global_commit,
                        "test global commit"),
     SVN_TEST_OPTS_PASS(test_global_commit_switched,
-                       "test global commit"),
+                       "test global commit switched"),
     SVN_TEST_NULL
   };
 

Modified: subversion/branches/1.10-cache-improvements/subversion/tests/libsvn_wc/wc-queries-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.10-cache-improvements/subversion/tests/libsvn_wc/wc-queries-test.c?rev=1679139&r1=1679138&r2=1679139&view=diff
==============================================================================
--- subversion/branches/1.10-cache-improvements/subversion/tests/libsvn_wc/wc-queries-test.c (original)
+++ subversion/branches/1.10-cache-improvements/subversion/tests/libsvn_wc/wc-queries-test.c Wed May 13 04:51:26 2015
@@ -927,6 +927,15 @@ test_schema_statistics(apr_pool_t *scrat
                    "VALUES (1, '', '')",
                    NULL, NULL, NULL));
 
+  SQLITE_ERR(
+      sqlite3_exec(sdb,
+                   "INSERT INTO EXTERNALS (wc_id, local_relpath,"
+                   "                       parent_relpath, repos_id,"
+                   "                       presence, kind, def_local_relpath,"
+                   "                       def_repos_relpath) "
+                   "VALUES (1, 'subdir', '', 1, 'normal', 'dir', '', '')",
+                   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(

Modified: subversion/branches/1.10-cache-improvements/subversion/tests/svn_test.h
URL: http://svn.apache.org/viewvc/subversion/branches/1.10-cache-improvements/subversion/tests/svn_test.h?rev=1679139&r1=1679138&r2=1679139&view=diff
==============================================================================
--- subversion/branches/1.10-cache-improvements/subversion/tests/svn_test.h (original)
+++ subversion/branches/1.10-cache-improvements/subversion/tests/svn_test.h Wed May 13 04:51:26 2015
@@ -149,6 +149,8 @@ typedef struct svn_test_opts_t
   const char *repos_dir;
   /* Repository url: The url to access REPOS_DIR as */
   const char *repos_url;
+  /* Memcached server. */
+  const char *memcached_server;
   /* Repository template: pre-created repository to copy for tests */
   const char *repos_template;
   /* Minor version to use for servers and FS backends, or zero to use

Modified: subversion/branches/1.10-cache-improvements/subversion/tests/svn_test_main.c
URL: http://svn.apache.org/viewvc/subversion/branches/1.10-cache-improvements/subversion/tests/svn_test_main.c?rev=1679139&r1=1679138&r2=1679139&view=diff
==============================================================================
--- subversion/branches/1.10-cache-improvements/subversion/tests/svn_test_main.c (original)
+++ subversion/branches/1.10-cache-improvements/subversion/tests/svn_test_main.c Wed May 13 04:51:26 2015
@@ -104,6 +104,7 @@ enum test_options_e {
   reposdir_opt,
   reposurl_opt,
   repostemplate_opt,
+  memcached_server_opt,
   mode_filter_opt,
   sqlite_log_opt,
   parallel_opt,
@@ -144,6 +145,8 @@ static const apr_getopt_option_t cl_opti
                     N_("the url to access reposdir as")},
   {"repos-template",repostemplate_opt, 1,
                     N_("the repository to use as template")},
+  {"memcached-server", memcached_server_opt, 1,
+                    N_("the memcached server to use")},
   {"sqlite-logging", sqlite_log_opt, 0,
                     N_("enable SQLite logging")},
   {"parallel",      parallel_opt, 0,
@@ -751,7 +754,7 @@ svn_test__init_auth_baton(svn_auth_baton
                                          "jrandom", "rayjandom",
                                          NULL,
                                          TRUE  /* no_auth_cache */,
-                                         FALSE /* trust_server_cert */,
+                                         TRUE /* trust_server_cert_unkown_ca */,
                                          FALSE, FALSE, FALSE, FALSE,
                                          cfg_config, NULL, NULL, result_pool));
 
@@ -915,6 +918,10 @@ svn_test_main(int argc, const char *argv
           opts.repos_template = svn_dirent_internal_style(opts.repos_template,
                                                           pool);
           break;
+        case memcached_server_opt:
+          SVN_INT_ERR(svn_utf_cstring_to_utf8(&opts.memcached_server, opt_arg,
+                                              pool));
+          break;
         case list_opt:
           list_mode = TRUE;
           break;

Modified: subversion/branches/1.10-cache-improvements/tools/buildbot/slaves/svn-x64-macosx/mkramdisk.sh
URL: http://svn.apache.org/viewvc/subversion/branches/1.10-cache-improvements/tools/buildbot/slaves/svn-x64-macosx/mkramdisk.sh?rev=1679139&r1=1679138&r2=1679139&view=diff
==============================================================================
--- subversion/branches/1.10-cache-improvements/tools/buildbot/slaves/svn-x64-macosx/mkramdisk.sh (original)
+++ subversion/branches/1.10-cache-improvements/tools/buildbot/slaves/svn-x64-macosx/mkramdisk.sh Wed May 13 04:51:26 2015
@@ -53,7 +53,7 @@ mount | grep "^/dev/disk[0-9][0-9]* on $
 
     # Make sure we strip trailing spaces from the result of older
     # versions of hduitil.
-    device=$(echo $(hdiutil attach -nomount ram://900000))
+    device=$(echo $(hdiutil attach -nomount ram://1000000))
     newfs_hfs -M 0700 -v "$1" "${device}"
     hdiutil mountvol "${device}"
 

Modified: subversion/branches/1.10-cache-improvements/tools/buildbot/slaves/svn-x64-macosx/setenv.sh
URL: http://svn.apache.org/viewvc/subversion/branches/1.10-cache-improvements/tools/buildbot/slaves/svn-x64-macosx/setenv.sh?rev=1679139&r1=1679138&r2=1679139&view=diff
==============================================================================
--- subversion/branches/1.10-cache-improvements/tools/buildbot/slaves/svn-x64-macosx/setenv.sh (original)
+++ subversion/branches/1.10-cache-improvements/tools/buildbot/slaves/svn-x64-macosx/setenv.sh Wed May 13 04:51:26 2015
@@ -50,7 +50,6 @@ export SVNBB_APR_15
 export SVNBB_APR_20_DEV
 export SVNBB_JUNIT
 export SVNBB_PARALLEL
-export LIBTOOL_CONFIG
 
 
 # Set the absolute source path

Modified: subversion/branches/1.10-cache-improvements/tools/buildbot/slaves/svn-x64-macosx/svncheck-bindings.sh
URL: http://svn.apache.org/viewvc/subversion/branches/1.10-cache-improvements/tools/buildbot/slaves/svn-x64-macosx/svncheck-bindings.sh?rev=1679139&r1=1679138&r2=1679139&view=diff
==============================================================================
--- subversion/branches/1.10-cache-improvements/tools/buildbot/slaves/svn-x64-macosx/svncheck-bindings.sh (original)
+++ subversion/branches/1.10-cache-improvements/tools/buildbot/slaves/svn-x64-macosx/svncheck-bindings.sh Wed May 13 04:51:26 2015
@@ -20,10 +20,11 @@
 
 run_tests() {
     check="$1"
+    cleanup="$2"
 
     echo "============ make check-${check}"
     cd ${absbld}
-    make check-${check} || exit 1
+    make check-${check} ${cleanup} || exit 1
 }
 
 
@@ -53,6 +54,6 @@ done
 ${check_swig_py} && run_tests swig-py
 ${check_swig_pl} && run_tests swig-pl
 ${check_swig_rb} && run_tests swig-rb
-${check_javahl} && run_tests javahl
+${check_javahl} && run_tests javahl JAVAHL_CLEANUP=1
 
 exit 0

Modified: subversion/branches/1.10-cache-improvements/tools/client-side/bash_completion
URL: http://svn.apache.org/viewvc/subversion/branches/1.10-cache-improvements/tools/client-side/bash_completion?rev=1679139&r1=1679138&r2=1679139&view=diff
==============================================================================
--- subversion/branches/1.10-cache-improvements/tools/client-side/bash_completion (original)
+++ subversion/branches/1.10-cache-improvements/tools/client-side/bash_completion Wed May 13 04:51:26 2015
@@ -781,8 +781,7 @@ _svn()
 
 	# otherwise build possible options for the command
 	pOpts="--username --password --no-auth-cache --non-interactive \
-	       --trust-unknown-ca --trust-cn-mismatch \
-	       --trust-expired --trust-not-yet-valid --trust-other-failure \
+	       --trust-server-cert-failures \
 	       --force-interactive"
 	mOpts="-m --message -F --file --encoding --force-log --with-revprop"
 	rOpts="-r --revision"
@@ -938,7 +937,7 @@ _svn()
 	status|stat|st)
 		cmdOpts="-u --show-updates -v --verbose $nOpts $qOpts $pOpts \
 		         --no-ignore --ignore-externals --incremental --xml \
-                         $cOpts"
+                         $rOpts $cOpts"
 		;;
 	switch|sw)
 		cmdOpts="--relocate $rOpts $nOpts $qOpts $pOpts --diff3-cmd \

Modified: subversion/branches/1.10-cache-improvements/tools/dist/backport.pl
URL: http://svn.apache.org/viewvc/subversion/branches/1.10-cache-improvements/tools/dist/backport.pl?rev=1679139&r1=1679138&r2=1679139&view=diff
==============================================================================
--- subversion/branches/1.10-cache-improvements/tools/dist/backport.pl (original)
+++ subversion/branches/1.10-cache-improvements/tools/dist/backport.pl Wed May 13 04:51:26 2015
@@ -431,7 +431,7 @@ fi
 $SVNq up
 $SVNq merge @mergeargs
 if [ "`$SVN status -q | wc -l`" -eq 1 ]; then
-  if [ -n "`$SVN diff | perl -lne 'print if s/^(Added|Deleted|Modified): //' | grep -vx svn:mergeinfo`" ]; then
+  if [ -z "`$SVN diff | perl -lne 'print if s/^(Added|Deleted|Modified): //' | grep -vx svn:mergeinfo`" ]; then
     # This check detects STATUS entries that name non-^/subversion/ revnums.
     # ### Q: What if we actually commit a mergeinfo fix to trunk and then want
     # ###    to backport it?
@@ -578,7 +578,7 @@ sub parse_entry {
   # summary
   do {
     push @logsummary, shift
-  } until $_[0] =~ /^\s*[][\w]+:/ or not defined $_[0];
+  } until $_[0] =~ /^\s*[A-Z][][\w]*:/ or not defined $_[0];
 
   # votes
   unshift @votes, pop until $_[-1] =~ /^\s*Votes:/ or not defined $_[-1];
@@ -765,7 +765,7 @@ sub vote {
         "Approve $_->{entry}->{header}."
       } @votesarray;
     (@sentences == 1)
-    ? $sentences[0]
+    ? "* STATUS: $sentences[0]"
     : "* STATUS:\n" . join "", map "  $_\n", @sentences;
   };
 
@@ -1287,7 +1287,7 @@ sub nominate_main {
   # Done!
   system "$SVN diff -- $STATUS";
   if (prompt "Commit this nomination? ") {
-    system "$SVN commit -m 'Nominate r$revnums[0].' -- $STATUS";
+    system "$SVN commit -m '* STATUS: Nominate r$revnums[0].' -- $STATUS";
     exit $?;
   }
   elsif (!$had_local_mods or prompt "Revert STATUS (destroying local mods)? ") {

Modified: subversion/branches/1.10-cache-improvements/tools/dist/backport_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/1.10-cache-improvements/tools/dist/backport_tests.py?rev=1679139&r1=1679138&r2=1679139&view=diff
==============================================================================
--- subversion/branches/1.10-cache-improvements/tools/dist/backport_tests.py (original)
+++ subversion/branches/1.10-cache-improvements/tools/dist/backport_tests.py Wed May 13 04:51:26 2015
@@ -1,7 +1,7 @@
 #!/usr/bin/env python
 # py:encoding=utf-8
 #
-#  backport_tests.py:  Test backport.pl
+#  backport_tests.py:  Test backport.pl or backport.py
 #
 #  Subversion is a tool for revision control.
 #  See http://subversion.apache.org for more information.
@@ -25,6 +25,25 @@
 #    under the License.
 ######################################################################
 
+# We'd like to test backport.pl and backport.py the same way, and to reuse
+# the svntest Python harness.  Since the latter standardizes argv parsing,
+# we can't use argv to determine whether .py or .pl should be tested.  Thus,
+# we implement the tests themselves in this file, while two driver files
+# (backport_tests_pl.py and backport_tests_py.py) invoke this file set
+# to run either backport-suite implementation.
+#
+# ### Note: the two driver scripts use the same repository names in
+# ### svn-test-work.  This is not ideal, but hopefully acceptable
+# ### temporarily until we switch over to backport.py and remove backport.pl.
+# ###
+# ### See svntest.testcase.FunctionTestCase.get_sandbox_name().
+try:
+  run_backport, run_conflicter
+except NameError:
+  raise Exception("Failure: %s should not be run directly, or the wrapper "
+                  "does not define both run_backport() and run_conflicter()"
+                  % __file__)
+
 # General modules
 import contextlib
 import functools
@@ -58,8 +77,6 @@ Wimp = svntest.testcase.Wimp_deco
 ######################################################################
 # Helper functions
 
-BACKPORT_PL = os.path.abspath(os.path.join(os.path.dirname(__file__),
-                                           'backport.pl'))
 STATUS = 'branch/STATUS'
 
 class BackportTest(object):
@@ -159,12 +176,15 @@ def serialize_entry(entry):
   ])
 
 def serialize_STATUS(approveds,
+                     candidates=[],
                      serialize_entry=serialize_entry):
   """Construct and return the contents of a STATUS file.
 
   APPROVEDS is an iterable of ENTRY dicts.  The dicts are defined
   to have the following keys: 'revisions', a list of revision numbers (ints);
   'logsummary'; and 'votes', a dict mapping ±1/±0 (int) to list of voters.
+
+  CANDIDATES is like APPROVEDS, except added to a different section of the file.
   """
 
   strings = []
@@ -173,6 +193,8 @@ def serialize_STATUS(approveds,
   strings.append("Candidate changes:\n")
   strings.append("==================\n\n")
 
+  strings.extend(map(serialize_entry, candidates))
+
   strings.append("Random new subheading:\n")
   strings.append("======================\n\n")
 
@@ -186,22 +208,6 @@ def serialize_STATUS(approveds,
 
   return "".join(strings)
 
-def run_backport(sbox, error_expected=False, extra_env=[]):
-  """Run backport.pl.  EXTRA_ENV is a list of key=value pairs (str) to set in
-  the child's environment.  ERROR_EXPECTED is propagated to run_command()."""
-  # TODO: if the test is run in verbose mode, pass DEBUG=1 in the environment,
-  #       and pass error_expected=True to run_command() to not croak on
-  #       stderr output from the child (because it uses 'sh -x').
-  args = [
-    '/usr/bin/env',
-    'SVN=' + svntest.main.svn_binary,
-    'YES=1', 'MAY_COMMIT=1', 'AVAILID=jrandom',
-  ] + list(extra_env) + [
-    'perl', BACKPORT_PL,
-  ]
-  with chdir(sbox.ospath('branch')):
-    return svntest.main.run_command(args[0], error_expected, False, *(args[1:]))
-
 def verify_backport(sbox, expected_dump_file, uuid):
   """Compare the contents of the SBOX repository with EXPECTED_DUMP_FILE.
   Set the UUID of SBOX to UUID beforehand.
@@ -225,7 +231,7 @@ def verify_backport(sbox, expected_dump_
   src_dump = svntest.actions.run_and_verify_dump(sbox.repo_dir)
 
   svntest.verify.compare_dump_files(
-    "Dump files", "DUMP", src_dump, dest_dump)
+    "Dump files", "DUMP", dest_dump, src_dump)
 
 ######################################################################
 # Tests
@@ -376,16 +382,14 @@ def backport_conflicts_detection(sbox):
   sbox.simple_commit(message="Conflicting change on iota")
 
   # r7: nominate r4, but without the requisite --accept
-  approved_entries = [
+  candidate_entries = [
     make_entry([4], notes="This will conflict."),
   ]
-  sbox.simple_append(STATUS, serialize_STATUS(approved_entries))
+  sbox.simple_append(STATUS, serialize_STATUS([], candidate_entries))
   sbox.simple_commit(message='Nominate r4')
 
   # Run it.
-  exit_code, output, errput = run_backport(sbox, True,
-                                           # Choose conflicts mode:
-                                           ["MAY_COMMIT=0"])
+  exit_code, output, errput = run_conflicter(sbox, True)
 
   # Verify the conflict is detected.
   expected_output = svntest.verify.RegexOutput(
@@ -418,9 +422,9 @@ def backport_conflicts_detection(sbox):
   sbox.simple_commit(message='Re-nominate r4')
 
   # Detect conflicts.
-  exit_code, output, errput = run_backport(sbox, extra_env=["MAY_COMMIT=0"])
+  exit_code, output, errput = run_conflicter(sbox)
 
-  # Verify stdout.  (exit_code and errput were verified by run_backport().)
+  # Verify stdout.  (exit_code and errput were verified by run_conflicter().)
   svntest.verify.verify_outputs(None, output, errput,
                                 "Conflicts found.*, as expected.", [])
 
@@ -501,7 +505,7 @@ def backport_double_conflict(sbox):
   sbox.simple_commit(message='Nominate the r4 group')
 
   # Run it, in conflicts mode.
-  exit_code, output, errput = run_backport(sbox, True, ["MAY_COMMIT=0"])
+  exit_code, output, errput = run_conflicter(sbox, True)
 
   # Verify the failure mode: "merge conflict" error on stderr, but backport.pl
   # itself exits with code 0, since conflicts were confined to Depends:-ed
@@ -541,13 +545,16 @@ def backport_double_conflict(sbox):
   sbox.simple_append(STATUS, serialize_STATUS(approved_entries), truncate=True)
   sbox.simple_commit(message='Re-nominate the r4 group')
 
-  exit_code, output, errput = run_backport(sbox, True, ["MAY_COMMIT=0"])
+  exit_code, output, errput = run_conflicter(sbox, True)
 
+  ## An unexpected non-zero exit code is treated as a fatal error.
   # [1-9]\d+ matches non-zero exit codes
-  expected_errput = r'r4 .*: subshell exited with code (?:[1-9]\d+)'
+  expected_stdout = None
+  expected_errput = r'r4 .*: subshell exited with code (?:[1-9]\d+)' \
+                   r"|.*subprocess.CalledProcessError.*'merge'.*exit status 1"
   svntest.verify.verify_exit_code(None, exit_code, 1)
   svntest.verify.verify_outputs(None, output, errput,
-                                svntest.verify.AnyOutput, expected_errput)
+                                expected_stdout, expected_errput)
 
 
 
@@ -590,6 +597,55 @@ def backport_branch_with_original_revisi
 
 
 #----------------------------------------------------------------------
+@BackportTest(None)
+def backport_otherproject_change(sbox):
+  "inoperative revision"
+
+  # r6: a change outside ^/subversion
+  sbox.simple_mkdir('elsewhere')
+  sbox.simple_commit()
+
+  # r7: Nominate r6 by mistake
+  approved_entries = [
+    make_entry([6])
+  ]
+  sbox.simple_append(STATUS, serialize_STATUS(approved_entries))
+  sbox.simple_commit(message='Nominate r6 by mistake')
+
+  # Run it.
+  exit_code, output, errput = run_backport(sbox, error_expected=True)
+
+  # Verify no commit occurred.
+  svntest.actions.run_and_verify_svnlook(["7\n"], [],
+                                         'youngest', sbox.repo_dir)
+
+  # Verify the failure mode.
+  expected_stdout = None
+  expected_stderr = ".*only svn:mergeinfo changes.*"
+  if exit_code == 0:
+    # Can't use verify_exit_code() since the exact code used varies.
+    raise svntest.Failure("exit_code should be non-zero")
+  svntest.verify.verify_outputs(None, output, errput,
+                                expected_stdout, expected_stderr)
+
+#----------------------------------------------------------------------
+@BackportTest(None)
+def backport_STATUS_mods(sbox):
+  "local mods to STATUS"
+
+  # Introduce a local mod.
+  sbox.simple_append(STATUS, "\n")
+
+  exit_code, output, errput = run_backport(sbox, error_expected=True)
+  expected_stdout = None
+  expected_stderr = ".*Local mods.*STATUS.*"
+  if exit_code == 0:
+    # Can't use verify_exit_code() since the exact code used varies.
+    raise svntest.Failure("exit_code should be non-zero")
+  svntest.verify.verify_outputs(None, output, errput,
+                                expected_stdout, expected_stderr)
+
+#----------------------------------------------------------------------
 
 ########################################################################
 # Run the tests
@@ -605,6 +661,8 @@ test_list = [ None,
               backport_branch_contains,
               backport_double_conflict,
               backport_branch_with_original_revision,
+              backport_otherproject_change,
+              backport_STATUS_mods,
               # When adding a new test, include the test number in the last
               # 6 bytes of the UUID.
              ]

Propchange: subversion/branches/1.10-cache-improvements/tools/dist/backport_tests.py
            ('svn:executable' removed)

Modified: subversion/branches/1.10-cache-improvements/tools/dist/release.py
URL: http://svn.apache.org/viewvc/subversion/branches/1.10-cache-improvements/tools/dist/release.py?rev=1679139&r1=1679138&r2=1679139&view=diff
==============================================================================
--- subversion/branches/1.10-cache-improvements/tools/dist/release.py (original)
+++ subversion/branches/1.10-cache-improvements/tools/dist/release.py Wed May 13 04:51:26 2015
@@ -87,12 +87,12 @@ tool_versions = {
   'trunk' : {
             'autoconf' : '2.69',
             'libtool'  : '2.4.3',
-            'swig'     : '3.0.0',
+            'swig'     : '2.0.12',
   },
   '1.9' : {
             'autoconf' : '2.69',
             'libtool'  : '2.4.3',
-            'swig'     : '3.0.0'
+            'swig'     : '2.0.12'
   },
   '1.8' : {
             'autoconf' : '2.69',

Modified: subversion/branches/1.10-cache-improvements/win-tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/1.10-cache-improvements/win-tests.py?rev=1679139&r1=1679138&r2=1679139&view=diff
==============================================================================
--- subversion/branches/1.10-cache-improvements/win-tests.py (original)
+++ subversion/branches/1.10-cache-improvements/win-tests.py Wed May 13 04:51:26 2015
@@ -83,6 +83,13 @@ def _usage_exit():
   print("  --disable-http-v2      : Do not advertise support for HTTPv2 on server")
   print("  --disable-bulk-updates : Disable bulk updates on HTTP server")
   print("  --ssl-cert             : Path to SSL server certificate to trust.")
+  print("  --exclusive-wc-locks   : Enable exclusive working copy locks")
+  print("  --memcached-dir=DIR    : Run memcached from dir")
+  print("  --memcached-server=    : Enable usage of the specified memcached server")
+  print("              <url:port>")
+  print("  --skip-c-tests         : Skip all C tests")
+  print("  --dump-load-cross-check: Run the dump load cross check after every test")
+
   print("  --javahl               : Run the javahl tests instead of the normal tests")
   print("  --swig=language        : Run the swig perl/python/ruby tests instead of")
   print("                           the normal tests")
@@ -127,7 +134,9 @@ opts, args = my_getopt(sys.argv[1:], 'hr
                         'list', 'enable-sasl', 'bin=', 'parallel',
                         'config-file=', 'server-minor-version=', 'log-level=',
                         'log-to-stdout', 'mode-filter=', 'milestone-filter=',
-                        'ssl-cert='])
+                        'ssl-cert=', 'exclusive-wc-locks', 'memcached-server=',
+                        'skip-c-tests', 'dump-load-cross-check', 'memcached-dir=',
+                        ])
 if len(args) > 1:
   print('Warning: non-option arguments after the first one will be ignored')
 
@@ -162,6 +171,12 @@ mode_filter=None
 tests_to_run = []
 log_level = None
 ssl_cert = None
+exclusive_wc_locks = None
+run_memcached = None
+memcached_server = None
+memcached_dir = None
+skip_c_tests = None
+dump_load_cross_check = None
 
 for opt, val in opts:
   if opt in ('-h', '--help'):
@@ -238,6 +253,17 @@ for opt, val in opts:
     log_level = val
   elif opt == '--ssl-cert':
     ssl_cert = val
+  elif opt == '--exclusive-wc-locks':
+    exclusive_wc_locks = 1
+  elif opt == '--memcached-server':
+    memcached_server = val
+  elif opt == '--skip-c-tests':
+    skip_c_tests = 1
+  elif opt == '--dump-load-cross-check':
+    dump_load_cross_check = 1
+  elif opt == '--memcached-dir':
+    memcached_dir = val
+    run_memcached = 1
 
 # Calculate the source and test directory names
 abs_srcdir = os.path.abspath("")
@@ -569,6 +595,8 @@ class Httpd:
                                     'jrandom', 'rayjandom'])
     os.spawnv(os.P_WAIT, htpasswd, ['htpasswd.exe', '-bp',  self.httpd_users,
                                     'jconstant', 'rayjandom'])
+    os.spawnv(os.P_WAIT, htpasswd, ['htpasswd.exe', '-bp',  self.httpd_users,
+                                    '__dumpster__', '__loadster__'])
 
   def _create_mime_types_file(self):
     "Create empty mime.types file"
@@ -635,6 +663,10 @@ class Httpd:
     else:
       self._start_daemon()
 
+    # Avoid output from starting and preparing between test results
+    sys.stderr.flush()
+    sys.stdout.flush()
+
   def stop(self):
     if self.service:
       self._stop_service()
@@ -672,6 +704,45 @@ class Httpd:
         pass
     print('Httpd.stop_daemon not implemented')
 
+class Memcached:
+  "Run memcached for tests"
+  def __init__(self, abs_memcached_dir, memcached_server):
+    self.name = 'memcached.exe'
+
+    self.memcached_host, self.memcached_port = memcached_server.split(':')
+    self.memcached_dir = abs_memcached_dir
+
+    self.proc = None
+    self.path = os.path.join(self.memcached_dir, self.name)
+
+    self.memcached_args = [
+                            self.name,
+                            '-p', self.memcached_port,
+                            '-l', self.memcached_host
+                          ]
+
+  def __del__(self):
+    "Stop memcached when the object is deleted"
+    self.stop()
+
+  def start(self):
+    "Start memcached as daemon"
+    print('Starting %s as daemon' % self.name)
+    print(self.memcached_args)
+    self.proc = subprocess.Popen([self.path] + self.memcached_args)
+
+  def stop(self):
+    "Stop memcached"
+    if self.proc is not None:
+      try:
+        print('Stopping %s' % self.name)
+        self.proc.poll();
+        if self.proc.returncode is None:
+          self.proc.kill();
+        return
+      except AttributeError:
+        pass
+
 # Move the binaries to the test directory
 create_target_dir(abs_builddir)
 locate_libs()
@@ -692,10 +763,15 @@ create_target_dir(CMDLINE_TEST_SCRIPT_NA
 abs_builddir = fix_case(abs_builddir)
 
 daemon = None
+memcached = None
 # Run the tests
 
 # No need to start any servers if we are only listing the tests.
 if not list_tests:
+  if run_memcached:
+    memcached = Memcached(memcached_dir, memcached_server)
+    memcached.start()
+
   if run_svnserve:
     daemon = Svnserve(svnserve_args, objdir, abs_objdir, abs_builddir)
 
@@ -759,7 +835,11 @@ if not test_javahl and not test_swig:
                              fsfs_sharding, fsfs_packing,
                              list_tests, svn_bin, mode_filter,
                              milestone_filter,
-                             set_log_level=log_level, ssl_cert=ssl_cert)
+                             set_log_level=log_level, ssl_cert=ssl_cert,
+                             exclusive_wc_locks=exclusive_wc_locks,
+                             memcached_server=memcached_server,
+                             skip_c_tests=skip_c_tests,
+                             dump_load_cross_check=dump_load_cross_check)
   old_cwd = os.getcwd()
   try:
     os.chdir(abs_builddir)
@@ -792,6 +872,9 @@ elif test_javahl:
     if (objdir == 'Debug'):
       args = args + ('-Xcheck:jni',)
 
+    if cleanup:
+      args = args + ('-Dtest.cleanup=1',)
+
     args = args + (
             '-Dtest.rootdir=' + os.path.join(abs_builddir, 'javahl'),
             '-Dtest.srcdir=' + os.path.join(abs_srcdir,
@@ -976,6 +1059,9 @@ elif test_swig == 'ruby':
 if daemon:
   del daemon
 
+if memcached:
+  del memcached
+
 # Remove the execs again
 for tgt in copied_execs:
   try: