subversion-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From br...@apache.org
Subject svn commit: r1658128 [5/6] - in /subversion/branches/pin-externals: ./ build/ notes/ subversion/bindings/cxxhl/include/svncxxhl/ subversion/bindings/javahl/native/ subversion/bindings/javahl/native/jniwrapper/ subversion/include/ subversion/include/pri...
Date Sun, 08 Feb 2015 03:10:27 GMT
Modified: subversion/branches/pin-externals/subversion/svnsync/sync.c
URL: http://svn.apache.org/viewvc/subversion/branches/pin-externals/subversion/svnsync/sync.c?rev=1658128&r1=1658127&r2=1658128&view=diff
==============================================================================
--- subversion/branches/pin-externals/subversion/svnsync/sync.c (original)
+++ subversion/branches/pin-externals/subversion/svnsync/sync.c Sun Feb  8 03:10:25 2015
@@ -115,6 +115,7 @@ remove_r0_mergeinfo(const svn_string_t *
     {
       char *line = APR_ARRAY_IDX(lines, i, char *);
       char *colon;
+      char *rangelist;
 
       /* split at the last colon */
       colon = strrchr(line, ':');
@@ -124,13 +125,11 @@ remove_r0_mergeinfo(const svn_string_t *
                                  _("Missing colon in svn:mergeinfo "
                                    "property"));
 
+      rangelist = colon + 1;
+
       /* remove r0 */
       if (colon[1] == '0')
         {
-          char *rangelist;
-
-          rangelist = colon + 1;
-
           if (strncmp(rangelist, "0*,", 3) == 0)
             {
               rangelist += 3;
@@ -151,19 +150,16 @@ remove_r0_mergeinfo(const svn_string_t *
             {
               rangelist[0] = '1';
             }
+        }
 
-          /* reassemble */
+      /* reassemble */
+      if (rangelist[0])
+        {
           if (new_str->len)
             svn_stringbuf_appendbyte(new_str, '\n');
           svn_stringbuf_appendbytes(new_str, line, colon + 1 - line);
           svn_stringbuf_appendcstr(new_str, rangelist);
         }
-      else
-        {
-          if (new_str->len)
-            svn_stringbuf_appendbyte(new_str, '\n');
-          svn_stringbuf_appendcstr(new_str, line);
-        }
     }
 
   if (strcmp((*str)->data, new_str->data) != 0)
@@ -513,7 +509,7 @@ change_file_prop(void *file_baton,
       SVN_ERR(normalize_string(&value, &was_normalized,
                                eb->source_prop_encoding, pool, pool));
       /* Correct malformed mergeinfo. */
-      if (strcmp(name, SVN_PROP_MERGEINFO) == 0)
+      if (value && strcmp(name, SVN_PROP_MERGEINFO) == 0)
         {
           SVN_ERR(remove_r0_mergeinfo(&value, &mergeinfo_tweaked,
                                       pool, pool));
@@ -623,7 +619,7 @@ change_dir_prop(void *dir_baton,
       SVN_ERR(normalize_string(&value, &was_normalized, eb->source_prop_encoding,
                                pool, pool));
       /* Maybe adjust svn:mergeinfo. */
-      if (strcmp(name, SVN_PROP_MERGEINFO) == 0)
+      if (value && strcmp(name, SVN_PROP_MERGEINFO) == 0)
         {
           SVN_ERR(remove_r0_mergeinfo(&value, &mergeinfo_tweaked,
                                       pool, pool));

Modified: subversion/branches/pin-externals/subversion/tests/cmdline/authz_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/pin-externals/subversion/tests/cmdline/authz_tests.py?rev=1658128&r1=1658127&r2=1658128&view=diff
==============================================================================
--- subversion/branches/pin-externals/subversion/tests/cmdline/authz_tests.py (original)
+++ subversion/branches/pin-externals/subversion/tests/cmdline/authz_tests.py Sun Feb  8 03:10:25 2015
@@ -45,6 +45,7 @@ XFail = svntest.testcase.XFail_deco
 Issues = svntest.testcase.Issues_deco
 Issue = svntest.testcase.Issue_deco
 Wimp = svntest.testcase.Wimp_deco
+SkipDumpLoadCrossCheck = svntest.testcase.SkipDumpLoadCrossCheck_deco
 
 ######################################################################
 # Tests
@@ -123,6 +124,7 @@ def authz_open_directory(sbox):
                                         wc_dir)
 
 @Skip(svntest.main.is_ra_type_file)
+@SkipDumpLoadCrossCheck()
 def broken_authz_file(sbox):
   "broken authz files cause errors"
 

Modified: subversion/branches/pin-externals/subversion/tests/cmdline/davautocheck.sh
URL: http://svn.apache.org/viewvc/subversion/branches/pin-externals/subversion/tests/cmdline/davautocheck.sh?rev=1658128&r1=1658127&r2=1658128&view=diff
==============================================================================
--- subversion/branches/pin-externals/subversion/tests/cmdline/davautocheck.sh (original)
+++ subversion/branches/pin-externals/subversion/tests/cmdline/davautocheck.sh Sun Feb  8 03:10:25 2015
@@ -401,6 +401,7 @@ fi
 say "Adding users for lock authentication"
 $HTPASSWD -bc $HTTPD_USERS jrandom   rayjandom
 $HTPASSWD -b  $HTTPD_USERS jconstant rayjandom
+$HTPASSWD -b  $HTTPD_USERS __dumpster__ __loadster__
 
 touch $HTTPD_MIME_TYPES
 

Modified: subversion/branches/pin-externals/subversion/tests/cmdline/externals_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/pin-externals/subversion/tests/cmdline/externals_tests.py?rev=1658128&r1=1658127&r2=1658128&view=diff
==============================================================================
--- subversion/branches/pin-externals/subversion/tests/cmdline/externals_tests.py (original)
+++ subversion/branches/pin-externals/subversion/tests/cmdline/externals_tests.py Sun Feb  8 03:10:25 2015
@@ -3806,6 +3806,43 @@ def copy_pin_externals(sbox):
                                      '--pin-externals')
 
 
+def nested_notification(sbox):
+  "notification for nested externals"
+
+  sbox.build()
+  wc_dir = sbox.wc_dir
+  repo_dir = sbox.repo_dir
+
+  sbox.simple_mkdir('D1')
+  sbox.simple_mkdir('D2')
+  sbox.simple_mkdir('D3')
+  sbox.simple_mkdir('D4')
+  sbox.simple_propset('svn:externals', '^/D2 X', 'D1')
+  sbox.simple_propset('svn:externals', '^/D3 X', 'D2')
+  sbox.simple_propset('svn:externals', '^/D4 X', 'D3')
+  sbox.simple_commit()
+  expected_output = [
+    'Updating \'' + sbox.ospath('D1') + '\':\n',
+    '\n',
+    'Fetching external item into \'' + sbox.ospath('D1/X') + '\':\n',
+    ' U   ' + sbox.ospath('D1/X') + '\n',
+    '\n',
+    'Fetching external item into \'' + sbox.ospath('D1/X/X') + '\':\n',
+    ' U   ' + sbox.ospath('D1/X/X') + '\n',
+    '\n',
+    'Fetching external item into \'' + sbox.ospath('D1/X/X/X') + '\':\n',
+    'Updated external to revision 2.\n',
+    '\n',
+    'External at revision 2.\n',
+    '\n',
+    'External at revision 2.\n',
+    '\n',
+    'At revision 2.\n'
+    ]
+  svntest.actions.run_and_verify_svn(None, expected_output, [],
+                                     'update', sbox.ospath('D1'))
+
+
 ########################################################################
 # Run the tests
 
@@ -3867,6 +3904,7 @@ test_list = [ None,
               copy_file_external_to_repo,
               replace_tree_with_foreign_external,
               copy_pin_externals,
+              nested_notification,
              ]
 
 if __name__ == '__main__':

Modified: subversion/branches/pin-externals/subversion/tests/cmdline/info_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/pin-externals/subversion/tests/cmdline/info_tests.py?rev=1658128&r1=1658127&r2=1658128&view=diff
==============================================================================
--- subversion/branches/pin-externals/subversion/tests/cmdline/info_tests.py (original)
+++ subversion/branches/pin-externals/subversion/tests/cmdline/info_tests.py Sun Feb  8 03:10:25 2015
@@ -208,7 +208,7 @@ def info_with_tree_conflicts(sbox):
 def info_on_added_file(sbox):
   """info on added file"""
 
-  svntest.actions.make_repo_and_wc(sbox)
+  sbox.build()
   wc_dir = sbox.wc_dir
 
   # create new file
@@ -251,7 +251,7 @@ def info_on_added_file(sbox):
 
 def info_on_mkdir(sbox):
   """info on new dir with mkdir"""
-  svntest.actions.make_repo_and_wc(sbox)
+  sbox.build()
   wc_dir = sbox.wc_dir
 
   # create a new directory using svn mkdir

Modified: subversion/branches/pin-externals/subversion/tests/cmdline/log_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/pin-externals/subversion/tests/cmdline/log_tests.py?rev=1658128&r1=1658127&r2=1658128&view=diff
==============================================================================
--- subversion/branches/pin-externals/subversion/tests/cmdline/log_tests.py (original)
+++ subversion/branches/pin-externals/subversion/tests/cmdline/log_tests.py Sun Feb  8 03:10:25 2015
@@ -227,12 +227,7 @@ def merge_history_repos(sbox):
   branch_c = os.path.join('branches', 'c')
 
   # Create an empty repository - r0
-  svntest.main.safe_rmtree(sbox.repo_dir, 1)
-  svntest.main.safe_rmtree(sbox.wc_dir, 1)
-  svntest.main.create_repos(sbox.repo_dir)
-
-  svntest.actions.run_and_verify_svn(None, None, [], "co", sbox.repo_url,
-                                     sbox.wc_dir)
+  sbox.build(empty=True)
   was_cwd = os.getcwd()
   os.chdir(sbox.wc_dir)
 
@@ -751,8 +746,7 @@ def log_with_empty_repos(sbox):
   "'svn log' on an empty repository"
 
   # Create virgin repos
-  svntest.main.safe_rmtree(sbox.repo_dir, 1)
-  svntest.main.create_repos(sbox.repo_dir)
+  sbox.build(create_wc=False, empty=True)
 
   svntest.actions.run_and_verify_svn(None, None, [],
                                      'log',

Modified: subversion/branches/pin-externals/subversion/tests/cmdline/move_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/pin-externals/subversion/tests/cmdline/move_tests.py?rev=1658128&r1=1658127&r2=1658128&view=diff
==============================================================================
--- subversion/branches/pin-externals/subversion/tests/cmdline/move_tests.py (original)
+++ subversion/branches/pin-externals/subversion/tests/cmdline/move_tests.py Sun Feb  8 03:10:25 2015
@@ -1241,10 +1241,10 @@ def move_missing(sbox):
 def nested_replaces(sbox):
   "nested replaces"
 
-  repo_dir, repo_url = sbox.add_repo_path('blank')
-  wc_dir = sbox.add_wc_path('blank')
-  svntest.main.create_repos(repo_dir)
-  ospath = lambda dirent: sbox.ospath(dirent, wc_dir)
+  sbox.build(create_wc=False, empty=True)
+  repo_url = sbox.repo_url
+  wc_dir = sbox.wc_dir
+  ospath = sbox.ospath
 
   ## r1: setup
   svntest.actions.run_and_verify_svnmucc(None, None, [],

Modified: subversion/branches/pin-externals/subversion/tests/cmdline/schedule_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/pin-externals/subversion/tests/cmdline/schedule_tests.py?rev=1658128&r1=1658127&r2=1658128&view=diff
==============================================================================
--- subversion/branches/pin-externals/subversion/tests/cmdline/schedule_tests.py (original)
+++ subversion/branches/pin-externals/subversion/tests/cmdline/schedule_tests.py Sun Feb  8 03:10:25 2015
@@ -569,10 +569,9 @@ def status_add_deleted_directory(sbox):
 def add_recursive_already_versioned(sbox):
   "'svn add' should traverse already-versioned dirs"
 
+  sbox.build()
   wc_dir = sbox.wc_dir
 
-  svntest.actions.make_repo_and_wc(sbox)
-
   # Create some files, then schedule them for addition
   delta_path = sbox.ospath('delta')
   zeta_path = sbox.ospath('A/B/zeta')

Modified: subversion/branches/pin-externals/subversion/tests/cmdline/svnadmin_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/pin-externals/subversion/tests/cmdline/svnadmin_tests.py?rev=1658128&r1=1658127&r2=1658128&view=diff
==============================================================================
--- subversion/branches/pin-externals/subversion/tests/cmdline/svnadmin_tests.py (original)
+++ subversion/branches/pin-externals/subversion/tests/cmdline/svnadmin_tests.py Sun Feb  8 03:10:25 2015
@@ -50,6 +50,7 @@ XFail = svntest.testcase.XFail_deco
 Issues = svntest.testcase.Issues_deco
 Issue = svntest.testcase.Issue_deco
 Wimp = svntest.testcase.Wimp_deco
+SkipDumpLoadCrossCheck = svntest.testcase.SkipDumpLoadCrossCheck_deco
 Item = svntest.wc.StateItem
 
 def check_hotcopy_bdb(src, dst):
@@ -424,37 +425,6 @@ def set_changed_path_list(sbox, revision
 
 #----------------------------------------------------------------------
 
-def test_create(sbox, minor_version=None):
-  "'svnadmin create'"
-
-
-  repo_dir = sbox.repo_dir
-  wc_dir = sbox.wc_dir
-
-  svntest.main.safe_rmtree(repo_dir, 1)
-  svntest.main.safe_rmtree(wc_dir)
-
-  svntest.main.create_repos(repo_dir, minor_version)
-
-  svntest.actions.run_and_verify_svn("Creating rev 0 checkout",
-                                     ["Checked out revision 0.\n"], [],
-                                     "checkout",
-                                     sbox.repo_url, wc_dir)
-
-
-  svntest.actions.run_and_verify_svn(
-    "Running status",
-    [], [],
-    "status", wc_dir)
-
-  svntest.actions.run_and_verify_svn(
-    "Running verbose status",
-    ["                 0        0  ?           %s\n" % wc_dir], [],
-    "status", "--verbose", wc_dir)
-
-  # success
-
-
 # dump stream tests need a dump file
 
 def clean_dumpfile():
@@ -486,7 +456,7 @@ dumpfile_revisions = \
 def extra_headers(sbox):
   "loading of dumpstream with extra headers"
 
-  test_create(sbox)
+  sbox.build(empty=True)
 
   dumpfile = clean_dumpfile()
 
@@ -501,7 +471,7 @@ def extra_headers(sbox):
 def extra_blockcontent(sbox):
   "load success on oversized Content-length"
 
-  test_create(sbox)
+  sbox.build(empty=True)
 
   dumpfile = clean_dumpfile()
 
@@ -519,7 +489,7 @@ def extra_blockcontent(sbox):
 def inconsistent_headers(sbox):
   "load failure on undersized Content-length"
 
-  test_create(sbox)
+  sbox.build(empty=True)
 
   dumpfile = clean_dumpfile()
 
@@ -535,7 +505,7 @@ def inconsistent_headers(sbox):
 def empty_date(sbox):
   "preserve date-less revisions in load"
 
-  test_create(sbox)
+  sbox.build(empty=True)
 
   dumpfile = clean_dumpfile()
 
@@ -1040,7 +1010,7 @@ def load_with_parent_dir(sbox):
   "'svnadmin load --parent-dir' reparents mergeinfo"
 
   ## See http://subversion.tigris.org/issues/show_bug.cgi?id=2983. ##
-  test_create(sbox)
+  sbox.build(empty=True)
 
   dumpfile_location = os.path.join(os.path.dirname(sys.argv[0]),
                                    'svnadmin_tests_data',
@@ -1138,7 +1108,7 @@ def reflect_dropped_renumbered_revs(sbox
 
   ## See http://subversion.tigris.org/issues/show_bug.cgi?id=3020. ##
 
-  test_create(sbox)
+  sbox.build(empty=True)
 
   dumpfile_location = os.path.join(os.path.dirname(sys.argv[0]),
                                    'svndumpfilter_tests_data',
@@ -1238,6 +1208,10 @@ def fsfs_recover_handle_missing_revs_or_
     ".*Revision 3 has a non-file where its revprops file should be.*"):
     raise svntest.Failure
 
+  # Restore the r3 revprops file, thus repairing the repository.
+  os.rmdir(revprop_3)
+  os.rename(revprop_was_3, revprop_3)
+
 
 #----------------------------------------------------------------------
 
@@ -1245,14 +1219,8 @@ def fsfs_recover_handle_missing_revs_or_
 def create_in_repo_subdir(sbox):
   "'svnadmin create /path/to/repo/subdir'"
 
+  sbox.build(create_wc=False, empty=True)
   repo_dir = sbox.repo_dir
-  wc_dir = sbox.wc_dir
-
-  svntest.main.safe_rmtree(repo_dir, 1)
-  svntest.main.safe_rmtree(wc_dir)
-
-  # This should succeed
-  svntest.main.create_repos(repo_dir)
 
   success = False
   try:
@@ -1280,16 +1248,13 @@ def create_in_repo_subdir(sbox):
 
 
 @SkipUnless(svntest.main.is_fs_type_fsfs)
+@SkipDumpLoadCrossCheck()
 def verify_with_invalid_revprops(sbox):
   "svnadmin verify detects invalid revprops file"
 
+  sbox.build(create_wc=False, empty=True)
   repo_dir = sbox.repo_dir
 
-  svntest.main.safe_rmtree(repo_dir, 1)
-
-  # This should succeed
-  svntest.main.create_repos(repo_dir)
-
   # Run a test verify
   exit_code, output, errput = svntest.main.run_svnadmin("verify",
                                                         sbox.repo_dir)
@@ -1339,7 +1304,7 @@ def dont_drop_valid_mergeinfo_during_inc
   "don't filter mergeinfo revs from incremental dump"
 
   # Create an empty repos.
-  test_create(sbox)
+  sbox.build(empty=True)
 
   # PART 1: Load a full dump to an empty repository.
   #
@@ -1428,7 +1393,7 @@ def dont_drop_valid_mergeinfo_during_inc
   dump_fp.close()
 
   # Blow away the current repos and create an empty one in its place.
-  test_create(sbox)
+  sbox.build(empty=True)
 
   # Load the three incremental dump files in sequence.
   load_dumpstream(sbox, open(dump_file_r1_10).read(), '--ignore-uuid')
@@ -1448,7 +1413,7 @@ def dont_drop_valid_mergeinfo_during_inc
   # PART 3: Load a full dump to an non-empty repository.
   #
   # Reset our sandbox.
-  test_create(sbox)
+  sbox.build(empty=True)
 
   # Load this skeleton repos into the empty target:
   #
@@ -1499,7 +1464,7 @@ def dont_drop_valid_mergeinfo_during_inc
   # PART 4: Load a a series of incremental dumps to an non-empty repository.
   #
   # Reset our sandbox.
-  test_create(sbox)
+  sbox.build(empty=True)
 
   # Load this skeleton repos into the empty target:
   load_dumpstream(sbox, dumpfile_skeleton, '--ignore-uuid')
@@ -1527,14 +1492,12 @@ def hotcopy_symlink(sbox):
 
   ## See http://subversion.tigris.org/issues/show_bug.cgi?id=2591. ##
 
+  # Create a repository.
+  sbox.build(create_wc=False, empty=True)
   original_repo = sbox.repo_dir
 
   hotcopy_repo, hotcopy_url = sbox.add_repo_path('hotcopy')
 
-  # Create a repository.
-  svntest.main.safe_rmtree(original_repo, 1)
-  svntest.main.create_repos(original_repo)
-
   # Create a file, a dir and a missing path outside the repoitory.
   svntest.main.safe_rmtree(sbox.wc_dir, 1)
   os.mkdir(sbox.wc_dir)
@@ -1630,7 +1593,7 @@ text
 
 
 """
-  test_create(sbox)
+  sbox.build(empty=True)
 
   # Try to load the dumpstream, expecting a failure (because of mixed EOLs).
   load_and_verify_dumpstream(sbox, [], svntest.verify.AnyOutput,
@@ -1655,8 +1618,8 @@ def verify_non_utf8_paths(sbox):
 
   # Corruption only possible in physically addressed revisions created
   # with pre-1.6 servers.
-  test_create(sbox,
-              minor_version = min(svntest.main.options.server_minor_version,8))
+  sbox.build(empty=True,
+             minor_version=min(svntest.main.options.server_minor_version,8))
 
   # Load the dumpstream
   load_and_verify_dumpstream(sbox, [], [], dumpfile_revisions, False,
@@ -1798,7 +1761,7 @@ def load_ranges(sbox):
   "'svnadmin load --revision X:Y'"
 
   ## See http://subversion.tigris.org/issues/show_bug.cgi?id=3734. ##
-  test_create(sbox)
+  sbox.build(empty=True)
 
   dumpfile_location = os.path.join(os.path.dirname(sys.argv[0]),
                                    'svnadmin_tests_data',
@@ -2074,8 +2037,7 @@ def mergeinfo_race(sbox):
 @Skip(svntest.main.is_fs_type_fsx)
 def recover_old_empty(sbox):
   "recover empty --compatible-version=1.3"
-  svntest.main.safe_rmtree(sbox.repo_dir, 1)
-  svntest.main.create_repos(sbox.repo_dir, minor_version=3)
+  sbox.build(create_wc=False, empty=True, minor_version=3)
   svntest.actions.run_and_verify_svnadmin(None, None, [],
                                           "recover", sbox.repo_dir)
 
@@ -2151,6 +2113,9 @@ def verify_keep_going(sbox):
                                    None, errput, None, "svnadmin: E165011:.*"):
     raise svntest.Failure
 
+  # Don't leave a corrupt repository
+  svntest.main.safe_rmtree(sbox.repo_dir, True)
+
 @SkipUnless(svntest.main.is_fs_type_fsfs)
 def verify_invalid_path_changes(sbox):
   "detect invalid changed path list entries"
@@ -2290,13 +2255,14 @@ def verify_invalid_path_changes(sbox):
                                    None, errput, None, "svnadmin: E165011:.*"):
     raise svntest.Failure
 
+  # Don't leave a corrupt repository
+  svntest.main.safe_rmtree(sbox.repo_dir, True)
+
 
 def verify_denormalized_names(sbox):
   "detect denormalized names and name collisions"
 
-  sbox.build(create_wc = False)
-  svntest.main.safe_rmtree(sbox.repo_dir, True)
-  svntest.main.create_repos(sbox.repo_dir)
+  sbox.build(create_wc=False, empty=True)
 
   dumpfile_location = os.path.join(os.path.dirname(sys.argv[0]),
                                    'svnadmin_tests_data',
@@ -2372,10 +2338,8 @@ def load_ignore_dates(sbox):
   # All revisions in the loaded repository should come after this time.
   start_time = time.localtime()
   time.sleep(1)
-  
-  sbox.build(create_wc=False)
-  svntest.main.safe_rmtree(sbox.repo_dir, True)
-  svntest.main.create_repos(sbox.repo_dir)
+
+  sbox.build(create_wc=False, empty=True)
 
   dumpfile_skeleton = open(os.path.join(os.path.dirname(sys.argv[0]),
                                         'svnadmin_tests_data',
@@ -2669,6 +2633,9 @@ def verify_quickly(sbox):
                                    output, errput, exp_out, exp_err):
     raise svntest.Failure
 
+  # Don't leave a corrupt repository
+  svntest.main.safe_rmtree(sbox.repo_dir, True)
+
 
 @SkipUnless(svntest.main.is_fs_type_fsfs)
 @SkipUnless(svntest.main.fs_has_pack)
@@ -2682,9 +2649,7 @@ def fsfs_hotcopy_progress(sbox):
     raise svntest.Skip
 
   # Create an empty repository, configure three files per shard.
-  sbox.build(create_wc=False)
-  svntest.main.safe_rmtree(sbox.repo_dir, True)
-  svntest.main.create_repos(sbox.repo_dir)
+  sbox.build(create_wc=False, empty=True)
   patch_format(sbox.repo_dir, shard_size=3)
 
   inc_backup_dir, inc_backup_url = sbox.add_repo_path('incremental-backup')
@@ -2798,9 +2763,7 @@ def fsfs_hotcopy_progress_with_revprop_c
     raise svntest.Skip
 
   # Create an empty repository, commit several revisions and hotcopy it.
-  sbox.build(create_wc=False)
-  svntest.main.safe_rmtree(sbox.repo_dir, True)
-  svntest.main.create_repos(sbox.repo_dir)
+  sbox.build(create_wc=False, empty=True)
 
   for i in range(6):
     svntest.actions.run_and_verify_svn(None, None, [], 'mkdir',
@@ -2845,9 +2808,7 @@ def fsfs_hotcopy_progress_with_revprop_c
 def fsfs_hotcopy_progress_old(sbox):
   "hotcopy --compatible-version=1.3 progress"
 
-  sbox.build(create_wc=False)
-  svntest.main.safe_rmtree(sbox.repo_dir, True)
-  svntest.main.create_repos(sbox.repo_dir, minor_version=3)
+  sbox.build(create_wc=False, empty=True, minor_version=3)
 
   inc_backup_dir, inc_backup_url = sbox.add_repo_path('incremental-backup')
 
@@ -2942,7 +2903,7 @@ def upgrade(sbox):
 def load_txdelta(sbox):
   "exercising svn_txdelta_target on BDB"
 
-  test_create(sbox)
+  sbox.build(empty=True)
 
   # This dumpfile produced a BDB repository that generated cheksum
   # mismatches on read caused by the improper handling of

Modified: subversion/branches/pin-externals/subversion/tests/cmdline/svndumpfilter_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/pin-externals/subversion/tests/cmdline/svndumpfilter_tests.py?rev=1658128&r1=1658127&r2=1658128&view=diff
==============================================================================
--- subversion/branches/pin-externals/subversion/tests/cmdline/svndumpfilter_tests.py (original)
+++ subversion/branches/pin-externals/subversion/tests/cmdline/svndumpfilter_tests.py Sun Feb  8 03:10:25 2015
@@ -34,8 +34,7 @@ import svntest
 from svntest.verify import SVNExpectedStdout, SVNExpectedStderr
 
 # Get some helper routines
-from svnadmin_tests import (load_and_verify_dumpstream, load_dumpstream,
-                            test_create)
+from svnadmin_tests import load_and_verify_dumpstream, load_dumpstream
 from svntest.main import run_svn, run_svnadmin
 
 # (abbreviation)
@@ -87,7 +86,7 @@ def reflect_dropped_renumbered_revs(sbox
   ## See http://subversion.tigris.org/issues/show_bug.cgi?id=2982. ##
 
   # Test svndumpfilter with include option
-  test_create(sbox)
+  sbox.build(empty=True)
   dumpfile_location = os.path.join(os.path.dirname(sys.argv[0]),
                                    'svndumpfilter_tests_data',
                                    'with_merges.dump')
@@ -113,7 +112,7 @@ def reflect_dropped_renumbered_revs(sbox
 
 
   # Test svndumpfilter with exclude option
-  test_create(sbox)
+  sbox.build(empty=True)
   filtered_out, filtered_err = filter_and_return_output(
       dumpfile, 0, "exclude", "branch1",
       "--skip-missing-merge-sources",
@@ -137,7 +136,7 @@ def svndumpfilter_loses_mergeinfo(sbox):
 
   ## See http://subversion.tigris.org/issues/show_bug.cgi?id=3181. ##
 
-  test_create(sbox)
+  sbox.build(empty=True)
   dumpfile_location = os.path.join(os.path.dirname(sys.argv[0]),
                                    'svndumpfilter_tests_data',
                                    'with_merges.dump')
@@ -220,7 +219,7 @@ def dumpfilter_with_targets(sbox):
   "svndumpfilter --targets blah"
   ## See http://subversion.tigris.org/issues/show_bug.cgi?id=2697. ##
 
-  test_create(sbox)
+  sbox.build(empty=True)
 
   dumpfile_location = os.path.join(os.path.dirname(sys.argv[0]),
                                    'svndumpfilter_tests_data',
@@ -243,7 +242,7 @@ def dumpfilter_with_targets(sbox):
 def dumpfilter_with_patterns(sbox):
   "svndumpfilter --pattern PATH_PREFIX"
 
-  test_create(sbox)
+  sbox.build(empty=True)
 
   dumpfile_location = os.path.join(os.path.dirname(sys.argv[0]),
                                    'svndumpfilter_tests_data',
@@ -263,7 +262,7 @@ def dumpfilter_with_patterns(sbox):
 def filter_mergeinfo_revs_outside_of_dump_stream(sbox):
   "filter mergeinfo revs outside of dump stream"
 
-  test_create(sbox)
+  sbox.build(empty=True)
 
   # Load a partial dump into an existing repository.
   #
@@ -366,7 +365,7 @@ def filter_mergeinfo_revs_outside_of_dum
   #     Project-Z     (Added r5)
   #     docs/         (Added r6)
   #       README      (Added r6).
-  test_create(sbox)
+  sbox.build(empty=True)
   skeleton_dumpfile = open(os.path.join(os.path.dirname(sys.argv[0]),
                                         'svnadmin_tests_data',
                                         'skeleton_repos.dump')).read()
@@ -495,7 +494,7 @@ def filter_mergeinfo_revs_outside_of_dum
 def dropped_but_not_renumbered_empty_revs(sbox):
   "mergeinfo maps correctly when dropping revs"
 
-  test_create(sbox)
+  sbox.build(empty=True)
 
   # The dump file mergeinfo_included_full.dump represents this repository:
   #
@@ -611,7 +610,7 @@ def match_empty_prefix(sbox):
       raise verify.UnexpectedStderr(filtered_err)
 
     # Load the filtered dump into a repo and check the result
-    test_create(sbox)
+    sbox.build(empty=True)
     load_dumpstream(sbox, filtered_output, '--ignore-uuid')
     svntest.actions.run_and_verify_update(sbox.wc_dir,
                                           expected_output,
@@ -645,7 +644,7 @@ def accepts_deltas(sbox):
   "accepts deltas in the input"
   # Accept format v3 (as created by 'svnadmin --deltas' or svnrdump).
 
-  test_create(sbox)
+  sbox.build(empty=True)
   dumpfile_location = os.path.join(os.path.dirname(sys.argv[0]),
                                    'svndumpfilter_tests_data',
                                    'simple_v3.dump')
@@ -679,7 +678,7 @@ def dumpfilter_targets_expect_leading_sl
   "dumpfilter targets expect leading '/' in prefixes"
   ## See http://subversion.tigris.org/issues/show_bug.cgi?id=4234. ##
 
-  test_create(sbox)
+  sbox.build(empty=True)
 
   dumpfile_location = os.path.join(os.path.dirname(sys.argv[0]),
                                    'svndumpfilter_tests_data',

Modified: subversion/branches/pin-externals/subversion/tests/cmdline/svnrdump_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/pin-externals/subversion/tests/cmdline/svnrdump_tests.py?rev=1658128&r1=1658127&r2=1658128&view=diff
==============================================================================
--- subversion/branches/pin-externals/subversion/tests/cmdline/svnrdump_tests.py (original)
+++ subversion/branches/pin-externals/subversion/tests/cmdline/svnrdump_tests.py Sun Feb  8 03:10:25 2015
@@ -34,7 +34,6 @@ from svntest.verify import SVNUnexpected
 from svntest.verify import SVNExpectedStderr
 from svntest.main import write_restrictive_svnserve_conf
 from svntest.main import server_has_partial_replay
-from svnadmin_tests import test_create
 
 # (abbreviation)
 Skip = svntest.testcase.Skip_deco
@@ -61,15 +60,6 @@ mismatched_headers_re = re.compile(
 ######################################################################
 # Helper routines
 
-def build_repos(sbox):
-  """Build an empty sandbox repository"""
-
-  # Cleanup after the last run by removing any left-over repository.
-  svntest.main.safe_rmtree(sbox.repo_dir)
-
-  # Create an empty repository.
-  svntest.main.create_repos(sbox.repo_dir)
-
 def compare_repos_dumps(sbox, other_dumpfile,
                         bypass_prop_validation=False):
   """Compare two dumpfiles, one created from SBOX, and other given
@@ -83,8 +73,7 @@ def compare_repos_dumps(sbox, other_dump
 
   # Load and dump the other dumpfile (using svnadmin)
   other_sbox = sbox.clone_dependent()
-  svntest.main.safe_rmtree(other_sbox.repo_dir)
-  svntest.main.create_repos(other_sbox.repo_dir)
+  other_sbox.build(create_wc=False, empty=True)
   svntest.actions.run_and_verify_load(other_sbox.repo_dir, other_dumpfile,
                                       bypass_prop_validation)
   other_dumpfile = svntest.actions.run_and_verify_dump(other_sbox.repo_dir)
@@ -104,7 +93,7 @@ def run_dump_test(sbox, dumpfile_name, e
   array of optional additional options to pass to 'svnrdump dump'."""
 
   # Create an empty sandbox repository
-  build_repos(sbox)
+  sbox.build(create_wc=False, empty=True)
 
   # This directory contains all the dump files
   svnrdump_tests_dir = os.path.join(os.path.dirname(sys.argv[0]),
@@ -159,7 +148,7 @@ def run_load_test(sbox, dumpfile_name, e
   dump' and check that the same dumpfile is produced"""
 
   # Create an empty sandbox repository
-  build_repos(sbox)
+  sbox.build(create_wc=False, empty=True)
 
   # Create the revprop-change hook for this test
   svntest.actions.enable_revprop_changes(sbox.repo_dir)
@@ -412,7 +401,7 @@ def reflect_dropped_renumbered_revs(sbox
   "svnrdump renumbers dropped revs in mergeinfo"
 
   # Create an empty sandbox repository
-  build_repos(sbox)
+  sbox.build(create_wc=False, empty=True)
 
   # Create the revprop-change hook for this test
   svntest.actions.enable_revprop_changes(sbox.repo_dir)
@@ -476,7 +465,7 @@ def dont_drop_valid_mergeinfo_during_inc
   "don't drop mergeinfo revs in incremental svnrdump"
 
   # Create an empty repos.
-  test_create(sbox)
+  sbox.build(empty=True)
 
   # Create the revprop-change hook for this test
   svntest.actions.enable_revprop_changes(sbox.repo_dir)
@@ -582,7 +571,7 @@ def dont_drop_valid_mergeinfo_during_inc
   dump_fp.close()
 
   # Blow away the current repos and create an empty one in its place.
-  test_create(sbox)
+  sbox.build(empty=True)
 
   # Create the revprop-change hook for this test
   svntest.actions.enable_revprop_changes(sbox.repo_dir)
@@ -617,7 +606,7 @@ def dont_drop_valid_mergeinfo_during_inc
   # PART 3: Load a full dump to an non-empty repository.
   #
   # Reset our sandbox.
-  test_create(sbox)
+  sbox.build(empty=True)
 
   # Create the revprop-change hook for this test
   svntest.actions.enable_revprop_changes(sbox.repo_dir)
@@ -678,7 +667,7 @@ def dont_drop_valid_mergeinfo_during_inc
   # PART 4: Load a a series of incremental dumps to an non-empty repository.
   #
   # Reset our sandbox.
-  test_create(sbox)
+  sbox.build(empty=True)
 
   # Create the revprop-change hook for this test
   svntest.actions.enable_revprop_changes(sbox.repo_dir)
@@ -723,7 +712,7 @@ def svnrdump_load_partial_incremental_du
   "svnrdump load partial incremental dump"
 
   # Create an empty sandbox repository
-  build_repos(sbox)
+  sbox.build(create_wc=False, empty=True)
 
   # Create the revprop-change hook for this test
   svntest.actions.enable_revprop_changes(sbox.repo_dir)
@@ -795,7 +784,7 @@ def load_prop_change_in_non_deltas_dump(
   dump = svntest.actions.run_and_verify_dump(sbox.repo_dir, deltas=False)
 
   # Try to load that dump.
-  build_repos(sbox)
+  sbox.build(create_wc=False, empty=True)
   svntest.actions.enable_revprop_changes(sbox.repo_dir)
   svntest.actions.run_and_verify_svnrdump(dump,
                                           [], [], 0,

Modified: subversion/branches/pin-externals/subversion/tests/cmdline/svnsync_authz_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/pin-externals/subversion/tests/cmdline/svnsync_authz_tests.py?rev=1658128&r1=1658127&r2=1658128&view=diff
==============================================================================
--- subversion/branches/pin-externals/subversion/tests/cmdline/svnsync_authz_tests.py (original)
+++ subversion/branches/pin-externals/subversion/tests/cmdline/svnsync_authz_tests.py Sun Feb  8 03:10:25 2015
@@ -37,10 +37,11 @@ import svntest
 from svntest.verify import SVNUnexpectedStdout, SVNUnexpectedStderr
 from svntest.verify import SVNExpectedStderr
 from svntest.main import write_restrictive_svnserve_conf
+from svntest.main import write_authz_file
 from svntest.main import server_has_partial_replay
 
 # Shared helpers
-from svnsync_tests import build_repos, run_init, run_sync, run_test
+from svnsync_tests import run_init, run_sync, run_test
 
 # (abbreviation)
 Skip = svntest.testcase.Skip_deco
@@ -61,22 +62,20 @@ def basic_authz(sbox):
   write_restrictive_svnserve_conf(sbox.repo_dir)
 
   dest_sbox = sbox.clone_dependent()
-  build_repos(dest_sbox)
+  dest_sbox.build(create_wc=False, empty=True)
 
   svntest.actions.enable_revprop_changes(dest_sbox.repo_dir)
 
   run_init(dest_sbox.repo_url, sbox.repo_url)
 
-  args = tuple(s.authz_name() for s in [sbox, sbox, dest_sbox])
-  svntest.main.file_write(sbox.authz_file,
-                          "[%s:/]\n"
-                          "* = r\n"
-                          "\n"
-                          "[%s:/A/B]\n"
-                          "* = \n"
-                          "\n"
-                          "[%s:/]\n"
-                          "* = rw\n" % args)
+  src_authz = sbox.authz_name()
+  dst_authz = dest_sbox.authz_name()
+  write_authz_file(sbox, None,
+                   prefixed_rules = {
+                       src_authz + ':/':    '* = r',
+                       src_authz + ':/A/B': '* =',
+                       dst_authz + ':/':    '* = rw',
+                       })
 
   run_sync(dest_sbox.repo_url)
 
@@ -141,21 +140,18 @@ def copy_from_unreadable_dir(sbox):
   write_restrictive_svnserve_conf(sbox.repo_dir)
 
   dest_sbox = sbox.clone_dependent()
-  build_repos(dest_sbox)
+  dest_sbox.build(create_wc=False, empty=True)
 
   svntest.actions.enable_revprop_changes(dest_sbox.repo_dir)
 
-  args = tuple(s.authz_name() for s in [sbox, sbox, dest_sbox])
-  open(sbox.authz_file, 'w').write(
-             "[%s:/]\n"
-             "* = r\n"
-             "\n"
-             "[%s:/A/B]\n"
-             "* = \n"
-             "\n"
-             "[%s:/]\n"
-             "* = rw"
-             % args)
+  src_authz = sbox.authz_name()
+  dst_authz = dest_sbox.authz_name()
+  write_authz_file(sbox, None,
+                   prefixed_rules = {
+                       src_authz + ':/':    '* = r',
+                       src_authz + ':/A/B': '* =',
+                       dst_authz + ':/':    '* = rw',
+                       })
 
   run_init(dest_sbox.repo_url, sbox.repo_url)
 
@@ -255,21 +251,18 @@ def copy_with_mod_from_unreadable_dir(sb
   write_restrictive_svnserve_conf(sbox.repo_dir)
 
   dest_sbox = sbox.clone_dependent()
-  build_repos(dest_sbox)
+  dest_sbox.build(create_wc=False, empty=True)
 
   svntest.actions.enable_revprop_changes(dest_sbox.repo_dir)
 
-  args = tuple(s.authz_name() for s in [sbox, sbox, dest_sbox])
-  open(sbox.authz_file, 'w').write(
-             "[%s:/]\n"
-             "* = r\n"
-             "\n"
-             "[%s:/A/B]\n"
-             "* = \n"
-             "\n"
-             "[%s:/]\n"
-             "* = rw"
-             % args)
+  src_authz = sbox.authz_name()
+  dst_authz = dest_sbox.authz_name()
+  write_authz_file(sbox, None,
+                   prefixed_rules = {
+                       src_authz + ':/':    '* = r',
+                       src_authz + ':/A/B': '* =',
+                       dst_authz + ':/':    '* = rw',
+                       })
 
   run_init(dest_sbox.repo_url, sbox.repo_url)
 
@@ -347,21 +340,18 @@ def copy_with_mod_from_unreadable_dir_an
   write_restrictive_svnserve_conf(sbox.repo_dir)
 
   dest_sbox = sbox.clone_dependent()
-  build_repos(dest_sbox)
+  dest_sbox.build(create_wc=False, empty=True)
 
   svntest.actions.enable_revprop_changes(dest_sbox.repo_dir)
 
-  args = tuple(s.authz_name() for s in [sbox, sbox, dest_sbox])
-  open(sbox.authz_file, 'w').write(
-             "[%s:/]\n"
-             "* = r\n"
-             "\n"
-             "[%s:/A/B]\n"
-             "* = \n"
-             "\n"
-             "[%s:/]\n"
-             "* = rw"
-             % args)
+  src_authz = sbox.authz_name()
+  dst_authz = dest_sbox.authz_name()
+  write_authz_file(sbox, None,
+                   prefixed_rules = {
+                       src_authz + ':/':    '* = r',
+                       src_authz + ':/A/B': '* =',
+                       dst_authz + ':/':    '* = rw',
+                       })
 
   run_init(dest_sbox.repo_url, sbox.repo_url)
 
@@ -426,7 +416,7 @@ def specific_deny_authz(sbox):
   sbox.build()
 
   dest_sbox = sbox.clone_dependent()
-  build_repos(dest_sbox)
+  dest_sbox.build(create_wc=False, empty=True)
 
   svntest.actions.enable_revprop_changes(dest_sbox.repo_dir)
 
@@ -443,31 +433,24 @@ def specific_deny_authz(sbox):
   # For mod_dav_svn's parent path setup we need per-repos permissions in
   # the authz file...
   if sbox.repo_url.startswith('http'):
-    args = tuple(s.authz_name() for s in [sbox, sbox, sbox, dest_sbox])
-    svntest.main.file_write(sbox.authz_file,
-                            "[%s:/]\n"
-                            "* = r\n"
-                            "\n"
-                            "[%s:/A]\n"
-                            "* = \n"
-                            "\n"
-                            "[%s:/A_COPY/B/lambda]\n"
-                            "* = \n"
-                            "\n"
-                            "[%s:/]\n"
-                            "* = rw\n" % args)
+    src_authz = sbox.authz_name()
+    dst_authz = dest_sbox.authz_name()
+    write_authz_file(sbox, None,
+                   prefixed_rules = {
+                       src_authz + ':/':                '* = r',
+                       src_authz + ':/A':               '* =',
+                       src_authz + ':/A_COPY/B/lambda': '* =',
+                       dst_authz + ':/':                '* = rw',
+                       })
   # Otherwise we can just go with the permissions needed for the source
   # repository.
   else:
-    svntest.main.file_write(sbox.authz_file,
-                            "[/]\n"
-                            "* = r\n"
-                            "\n"
-                            "[/A]\n"
-                            "* = \n"
-                            "\n"
-                            "[/A_COPY/B/lambda]\n"
-                            "* = \n")
+    write_authz_file(sbox, None,
+                   prefixed_rules = {
+                       '/':                '* = r',
+                       '/A':               '* =',
+                       '/A_COPY/B/lambda': '* =',
+                       })
 
   run_sync(dest_sbox.repo_url)
 
@@ -494,18 +477,17 @@ def copy_delete_unreadable_child(sbox):
 
   # Create the destination.
   dest_sbox = sbox.clone_dependent()
-  build_repos(dest_sbox)
+  dest_sbox.build(create_wc=False, empty=True)
   svntest.actions.enable_revprop_changes(dest_sbox.repo_dir)
 
   # Lock down the source.
-  authz = sbox.authz_name()
   write_restrictive_svnserve_conf(sbox.repo_dir, anon_access='read')
-  svntest.main.file_write(sbox.authz_file,
-      "[%s:/]\n"
-      "* = r\n"
-      "[%s:/A]\n"
-      "* =  \n"
-      % (authz, authz))
+  src_authz = sbox.authz_name()
+  write_authz_file(sbox, None,
+                   prefixed_rules = {
+                       src_authz + ':/':  '* = r',
+                       src_authz + ':/A': '* =',
+                       })
 
   dest_url = svntest.main.file_scheme_prefix \
                     + urllib.pathname2url(os.path.abspath(dest_sbox.repo_dir))

Modified: subversion/branches/pin-externals/subversion/tests/cmdline/svnsync_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/pin-externals/subversion/tests/cmdline/svnsync_tests.py?rev=1658128&r1=1658127&r2=1658128&view=diff
==============================================================================
--- subversion/branches/pin-externals/subversion/tests/cmdline/svnsync_tests.py (original)
+++ subversion/branches/pin-externals/subversion/tests/cmdline/svnsync_tests.py Sun Feb  8 03:10:25 2015
@@ -34,6 +34,7 @@ import re, urllib
 import svntest
 from svntest.verify import SVNUnexpectedStdout, SVNUnexpectedStderr
 from svntest.verify import SVNExpectedStderr
+from svntest.verify import AnyOutput
 from svntest.main import server_has_partial_replay
 
 # (abbreviation)
@@ -49,117 +50,57 @@ Item = svntest.wc.StateItem
 # Helper routines
 
 
-def build_repos(sbox):
-  """Avoid the use sbox.build() because we're working with a repos
-  other than the Greek tree."""
-  # Cleanup after the last run by removing any left-over repository.
-  svntest.main.safe_rmtree(sbox.repo_dir)
-
-  # Create an empty repository.
-  svntest.main.create_repos(sbox.repo_dir)
-
-
-def run_sync(url, source_url=None, expected_error=None,
-             source_prop_encoding=None):
+def run_sync(url, source_url=None,
+             source_prop_encoding=None,
+             expected_output=AnyOutput, expected_error=[]):
   "Synchronize the mirror repository with the master"
   if source_url is not None:
-    args = ["synchronize", url, source_url,
-      "--username", svntest.main.wc_author,
-      "--password", svntest.main.wc_passwd]
+    args = ["synchronize", url, source_url]
   else: # Allow testing of old source-URL-less syntax
-    args = ["synchronize", url,
-      "--username", svntest.main.wc_author,
-      "--password", svntest.main.wc_passwd]
+    args = ["synchronize", url]
   if source_prop_encoding:
     args.append("--source-prop-encoding")
     args.append(source_prop_encoding)
 
-  exit_code, output, errput = svntest.main.run_svnsync(*args)
-  for index, line in enumerate(errput[:]):
-    if re.search("warning: W200007", line):
-      del errput[index]
-  if errput:
-    if expected_error is None:
-      raise SVNUnexpectedStderr(errput)
-    else:
-      expected_error = svntest.verify.RegexOutput(expected_error,
-                                                  match_all=False)
-      svntest.verify.compare_and_display_lines(None, "STDERR",
-                                               expected_error, errput)
-  elif expected_error is not None:
-    raise SVNExpectedStderr
-  if not output and not expected_error:
-    # should be: ['Committed revision 1.\n', 'Committed revision 2.\n']
-    raise SVNUnexpectedStdout("Missing stdout")
-
-def run_copy_revprops(url, source_url, expected_error=None,
-                      source_prop_encoding=None):
+  # Normal expected output is of the form:
+  #            ['Transmitting file data .......\n',  # optional
+  #             'Committed revision 1.\n',
+  #             'Copied properties for revision 1.\n', ...]
+  svntest.actions.run_and_verify_svnsync(expected_output, expected_error,
+                                         *args)
+
+def run_copy_revprops(url, source_url,
+                      source_prop_encoding=None,
+                      expected_output=AnyOutput, expected_error=[]):
   "Copy revprops to the mirror repository from the master"
-  args = ["copy-revprops", url, source_url,
-    "--username", svntest.main.wc_author,
-    "--password", svntest.main.wc_passwd]
+  args = ["copy-revprops", url, source_url]
   if source_prop_encoding:
     args.append("--source-prop-encoding")
     args.append(source_prop_encoding)
 
-  exit_code, output, errput = svntest.main.run_svnsync(*args)
-  for index, line in enumerate(errput[:]):
-    if re.search("warning: W200007", line):
-      del errput[index]
-  if errput:
-    if expected_error is None:
-      raise SVNUnexpectedStderr(errput)
-    else:
-      expected_error = svntest.verify.RegexOutput(expected_error,
-                                                  match_all=False)
-      svntest.verify.compare_and_display_lines(None, "STDERR",
-                                               expected_error, errput)
-  elif expected_error is not None:
-    raise SVNExpectedStderr
-  if not output and not expected_error:
-    # should be: ['Copied properties for revision 1.\n',
-    #             'Copied properties for revision 2.\n']
-    raise SVNUnexpectedStdout("Missing stdout")
+  # Normal expected output is of the form:
+  #            ['Copied properties for revision 1.\n', ...]
+  svntest.actions.run_and_verify_svnsync(expected_output, expected_error,
+                                         *args)
 
 def run_init(dst_url, src_url, source_prop_encoding=None):
   "Initialize the mirror repository from the master"
-  args = ["initialize", dst_url, src_url,
-    "--username", svntest.main.wc_author,
-    "--password", svntest.main.wc_passwd]
+  args = ["initialize", dst_url, src_url]
   if source_prop_encoding:
     args.append("--source-prop-encoding")
     args.append(source_prop_encoding)
 
-  exit_code, output, errput = svntest.main.run_svnsync(*args)
-  for index, line in enumerate(errput[:]):
-    if re.search("warning: W200007", line):
-      del errput[index]
-  if errput:
-    raise SVNUnexpectedStderr(errput)
-  if output != ['Copied properties for revision 0.\n']:
-    raise SVNUnexpectedStdout(output)
+  expected_output = ['Copied properties for revision 0.\n']
+  svntest.actions.run_and_verify_svnsync(expected_output, [], *args)
 
-def run_info(url, expected_error=None):
+def run_info(url, expected_output=AnyOutput, expected_error=[]):
   "Print synchronization information of the repository"
-  exit_code, output, errput = svntest.main.run_svnsync(
-    "info", url,
-    "--username", svntest.main.wc_author,
-    "--password", svntest.main.wc_passwd)
-  if errput:
-    if expected_error is None:
-      raise SVNUnexpectedStderr(errput)
-    else:
-      expected_error = svntest.verify.RegexOutput(expected_error,
-                                                  match_all=False)
-      svntest.verify.compare_and_display_lines(None, "STDERR",
-                                               expected_error, errput)
-  elif expected_error is not None:
-    raise SVNExpectedStderr
-  if not output and not expected_error:
-    # should be: ['From URL: http://....\n',
-    #             'From UUID: XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX\n',
-    #             'Last Merged Revision: XXX\n']
-    raise SVNUnexpectedStdout("Missing stdout")
+  # Normal expected output is of the form:
+  #            ['From URL: http://....\n',
+  #             'From UUID: XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX\n',
+  #             'Last Merged Revision: XXX\n']
+  svntest.actions.run_and_verify_svnsync(expected_output, expected_error,
+                                         "info", url)
 
 
 def setup_and_sync(sbox, dump_file_contents, subdir=None,
@@ -168,7 +109,7 @@ def setup_and_sync(sbox, dump_file_conte
   """Create a repository for SBOX, load it with DUMP_FILE_CONTENTS, then create a mirror repository and sync it with SBOX. If is_src_ra_local or is_dest_ra_local is True, then run_init, run_sync, and run_copy_revprops will use the file:// scheme for the source and destination URLs.  Return the mirror sandbox."""
 
   # Create the empty master repository.
-  build_repos(sbox)
+  sbox.build(create_wc=False, empty=True)
 
   # Load the repository from DUMP_FILE_PATH.
   svntest.actions.run_and_verify_load(sbox.repo_dir, dump_file_contents,
@@ -176,7 +117,7 @@ def setup_and_sync(sbox, dump_file_conte
 
   # Create the empty destination repository.
   dest_sbox = sbox.clone_dependent()
-  build_repos(dest_sbox)
+  dest_sbox.build(create_wc=False, empty=True)
 
   # Setup the mirror repository.  Feed it the UUID of the source repository.
   exit_code, output, errput = svntest.main.run_svnlook("uuid", sbox.repo_dir)
@@ -346,7 +287,7 @@ def detect_meddling(sbox):
   sbox.build("svnsync-meddling")
 
   dest_sbox = sbox.clone_dependent()
-  build_repos(dest_sbox)
+  dest_sbox.build(create_wc=False, empty=True)
 
   # Make our own destination checkout (have to do it ourself because
   # it is not greek).
@@ -380,8 +321,9 @@ def detect_meddling(sbox):
                                      '-m', 'msg',
                                      dest_sbox.wc_dir)
 
+  expected_error = r".*Destination HEAD \(2\) is not the last merged revision \(1\).*"
   run_sync(dest_sbox.repo_url, None,
-           ".*Destination HEAD \\(2\\) is not the last merged revision \\(1\\).*")
+           expected_output=[], expected_error=expected_error)
 
 def url_encoding(sbox):
   "test url encoding issues"
@@ -427,28 +369,18 @@ def info_synchronized(sbox):
   src_uuid = output[0].strip()
 
   dest_sbox = sbox.clone_dependent()
-  build_repos(dest_sbox)
+  dest_sbox.build(create_wc=False, empty=True)
 
   svntest.actions.enable_revprop_changes(dest_sbox.repo_dir)
   run_init(dest_sbox.repo_url, sbox.repo_url)
   run_sync(dest_sbox.repo_url)
 
-  exit_code, output, errput = svntest.main.run_svnsync(
-    "info", dest_sbox.repo_url,
-    "--username", svntest.main.wc_author,
-    "--password", svntest.main.wc_passwd)
-  if errput:
-      raise SVNUnexpectedStderr(errput)
-
   expected_out = ['Source URL: %s\n' % sbox.repo_url,
                   'Source Repository UUID: %s\n' % src_uuid,
                   'Last Merged Revision: 1\n',
                   ]
-
-  svntest.verify.compare_and_display_lines(None,
-                                           'INFO',
-                                           expected_out,
-                                           output)
+  svntest.actions.run_and_verify_svnsync(expected_out, [],
+                                         "info", dest_sbox.repo_url)
 
 def info_not_synchronized(sbox):
   "test info cmd on an un-synchronized repo"
@@ -456,7 +388,7 @@ def info_not_synchronized(sbox):
   sbox.build("svnsync-info-not-syncd", False)
 
   run_info(sbox.repo_url,
-           ".*Repository '%s' is not initialized.*" % sbox.repo_url)
+           [], ".*Repository '%s' is not initialized.*" % sbox.repo_url)
 
 #----------------------------------------------------------------------
 
@@ -578,9 +510,72 @@ def fd_leak_sync_from_serf_to_local(sbox
 @Issue(4476)
 def mergeinfo_contains_r0(sbox):
   "mergeinfo contains r0"
-  run_test(sbox, "mergeinfo-contains-r0.dump",
-           exp_dump_file_name="mergeinfo-contains-r0.expected.dump",
-           bypass_prop_validation=True)
+
+  def make_node_record(node_name, mi):
+    """Return a dumpfile node-record for adding a (directory) node named
+       NODE_NAME with mergeinfo MI. Return it as a list of newline-terminated
+       lines.
+    """
+    headers_tmpl = """\
+Node-path: %s
+Node-kind: dir
+Node-action: add
+Prop-content-length: %d
+Content-length: %d
+"""
+    content_tmpl = """\
+K 13
+svn:mergeinfo
+V %d
+%s
+PROPS-END
+"""
+    content = content_tmpl % (len(mi), mi)
+    headers = headers_tmpl % (node_name, len(content), len(content))
+    record = headers + '\n' + content + '\n\n'
+    return record.splitlines(True)
+
+  # The test case mergeinfo (before, after) syncing, separated here with
+  # spaces instead of newlines
+  test_mi = [
+    ("",            ""),  # unchanged
+    ("/a:1",        "/a:1"),
+    ("/a:1 /b:1*,2","/a:1 /b:1*,2"),
+    ("/:0:1",       "/:0:1"),  # unchanged; colon-zero in filename
+    ("/a:0",        ""),  # dropped entirely
+    ("/a:0*",       ""),
+    ("/a:0 /b:0*",  ""),
+    ("/a:1 /b:0",   "/a:1"),  # one kept, one dropped
+    ("/a:0 /b:1",   "/b:1"),
+    ("/a:0,1 /b:1", "/a:1 /b:1"),  # one kept, one changed
+    ("/a:1 /b:0,1", "/a:1 /b:1"),
+    ("/a:0,1 /b:0*,1 /c:0,2 /d:0-1 /e:0-1,3 /f:0-2 /g:0-3",
+     "/a:1 /b:1 /c:2 /d:1 /e:1,3 /f:1-2 /g:1-3"),  # all changed
+    ("/a:0:0-1",    "/a:0:1"),  # changed; colon-zero in filename
+    ]
+
+  # Get the constant prefix for each dumpfile
+  dump_file_name = "mergeinfo-contains-r0.dump"
+  svnsync_tests_dir = os.path.join(os.path.dirname(sys.argv[0]),
+                                   'svnsync_tests_data')
+  dump_in = open(os.path.join(svnsync_tests_dir, dump_file_name),
+                 'rb').readlines()
+  dump_out = list(dump_in)  # duplicate the list
+
+  # Add dumpfile node records containing the test mergeinfo
+  for n, mi in enumerate(test_mi):
+    node_name = "D" + str(n)
+
+    mi_in = mi[0].replace(' ', '\n')
+    mi_out = mi[1].replace(' ', '\n')
+    dump_in.extend(make_node_record(node_name, mi_in))
+    dump_out.extend(make_node_record(node_name, mi_out))
+
+  # Run the sync
+  dest_sbox = setup_and_sync(sbox, dump_in, bypass_prop_validation=True)
+
+  # Compare the dump produced by the mirror repository with expected
+  verify_mirror(dest_sbox, dump_out)
 
 
 ########################################################################

Modified: subversion/branches/pin-externals/subversion/tests/cmdline/svnsync_tests_data/mergeinfo-contains-r0.dump
URL: http://svn.apache.org/viewvc/subversion/branches/pin-externals/subversion/tests/cmdline/svnsync_tests_data/mergeinfo-contains-r0.dump?rev=1658128&r1=1658127&r2=1658128&view=diff
==============================================================================
--- subversion/branches/pin-externals/subversion/tests/cmdline/svnsync_tests_data/mergeinfo-contains-r0.dump (original)
+++ subversion/branches/pin-externals/subversion/tests/cmdline/svnsync_tests_data/mergeinfo-contains-r0.dump Sun Feb  8 03:10:25 2015
@@ -13,8 +13,8 @@ V 27
 PROPS-END
 
 Revision-number: 1
-Prop-content-length: 101
-Content-length: 101
+Prop-content-length: 84
+Content-length: 84
 
 K 10
 svn:author
@@ -24,113 +24,5 @@ K 8
 svn:date
 V 27
 2000-01-01T00:00:00.000000Z
-K 7
-svn:log
-V 0
-
-PROPS-END
-
-Node-path: 
-Node-kind: dir
-Node-action: change
-Prop-content-length: 22
-Content-length: 22
-
-K 1
-p
-V 1
-v
-PROPS-END
-
-
-Revision-number: 2
-Prop-content-length: 113
-Content-length: 113
-
-K 10
-svn:author
-V 7
-jrandom
-K 8
-svn:date
-V 27
-2005-11-07T23:37:17.705159Z
-K 7
-svn:log
-V 11
-add foo.txt
-PROPS-END
-
-Node-path: foo.txt
-Node-kind: file
-Node-action: add
-Text-content-md5: d41d8cd98f00b204e9800998ecf8427e
-Text-content-sha1: da39a3ee5e6b4b0d3255bfef95601890afd80709
-Prop-content-length: 86
-Text-content-length: 0
-Content-length: 86
-
-K 13
-svn:mergeinfo
-V 51
-/a:0,1
-/b:0*,1
-/c:0,2
-/d:0-1
-/e:0-1,3
-/f:0-2
-/g:0-3
 PROPS-END
 
-
-Revision-number: 3
-Prop-content-length: 97
-Content-length: 97
-
-K 10
-svn:author
-V 2
-pm
-K 8
-svn:date
-V 27
-2015-02-03T18:38:47.017031Z
-K 7
-svn:log
-V 1
-m
-PROPS-END
-
-Node-path: zag
-Node-kind: dir
-Node-action: add
-Prop-content-length: 76
-Content-length: 76
-
-K 13
-svn:mergeinfo
-V 45
-/a:1,4
-/b:0,4
-/c:2-3
-/d:0-3
-/e:2,5-6
-/f:0,5-6
-PROPS-END
-
-
-Node-path: zig
-Node-kind: dir
-Node-action: add
-Prop-content-length: 55
-Content-length: 55
-
-K 13
-svn:mergeinfo
-V 20
-/a:1
-/b:2-3
-/c:4,7-8
-PROPS-END
-
-

Modified: subversion/branches/pin-externals/subversion/tests/cmdline/svntest/actions.py
URL: http://svn.apache.org/viewvc/subversion/branches/pin-externals/subversion/tests/cmdline/svntest/actions.py?rev=1658128&r1=1658127&r2=1658128&view=diff
==============================================================================
--- subversion/branches/pin-externals/subversion/tests/cmdline/svntest/actions.py (original)
+++ subversion/branches/pin-externals/subversion/tests/cmdline/svntest/actions.py Sun Feb  8 03:10:25 2015
@@ -129,7 +129,7 @@ def setup_pristine_greek_repository():
 
 ######################################################################
 
-def guarantee_empty_repository(path):
+def guarantee_empty_repository(path, minor_version):
   """Guarantee that a local svn repository exists at PATH, containing
   nothing."""
 
@@ -139,7 +139,7 @@ def guarantee_empty_repository(path):
 
   # create an empty repository at PATH.
   main.safe_rmtree(path)
-  main.create_repos(path)
+  main.create_repos(path, minor_version)
 
 # Used by every test, so that they can run independently of  one
 # another. Every time this routine is called, it recursively copies
@@ -338,28 +338,22 @@ def run_and_verify_load(repo_dir, dump_f
   if not isinstance(dump_file_content, list):
     raise TypeError("dump_file_content argument should have list type")
   expected_stderr = []
+  args = ()
   if bypass_prop_validation:
-    exit_code, output, errput = main.run_command_stdin(
-      main.svnadmin_binary, expected_stderr, 0, True, dump_file_content,
-      'load', '--force-uuid', '--quiet', '--bypass-prop-validation', repo_dir)
-  else:
-    exit_code, output, errput = main.run_command_stdin(
-      main.svnadmin_binary, expected_stderr, 0, True, dump_file_content,
-      'load', '--force-uuid', '--quiet', repo_dir)
-
-  verify.verify_outputs("Unexpected stderr output", None, errput,
-                        None, expected_stderr)
+    args += ('--bypass-prop-validation',)
+  main.run_command_stdin(
+    main.svnadmin_binary, expected_stderr, 0, True, dump_file_content,
+    'load', '--force-uuid', '--quiet', repo_dir, *args)
 
 
 def run_and_verify_dump(repo_dir, deltas=False):
   "Runs 'svnadmin dump' and reports any errors, returning the dump content."
+  args = ()
   if deltas:
-    exit_code, output, errput = main.run_svnadmin('dump', '--deltas',
-                                                  repo_dir)
-  else:
-    exit_code, output, errput = main.run_svnadmin('dump', repo_dir)
-  verify.verify_outputs("Missing expected output(s)", output, errput,
-                        verify.AnyOutput, verify.AnyOutput)
+    args += ('--deltas',)
+  exit_code, output, errput = run_and_verify_svnadmin(
+                                None, verify.AnyOutput, [],
+                                'dump', '--quiet', repo_dir, *args)
   return output
 
 
@@ -374,6 +368,8 @@ def run_and_verify_svnrdump(dumpfile_con
   if sys.platform == 'win32':
     err = map(lambda x : x.replace('\r\n', '\n'), err)
 
+  # Ignore "consider upgrade" warnings to allow regression tests to pass
+  # when run against a 1.6 mod_dav_svn.
   for index, line in enumerate(err[:]):
     if re.search("warning: W200007", line):
       del err[index]
@@ -405,6 +401,34 @@ def run_and_verify_svnmucc2(message, exp
   return exit_code, out, err
 
 
+def run_and_verify_svnsync(expected_stdout, expected_stderr,
+                           *varargs):
+  """Run svnsync command and check its output"""
+
+  expected_exit = 0
+  if expected_stderr is not None and expected_stderr != []:
+    expected_exit = 1
+  return run_and_verify_svnsync2(expected_stdout, expected_stderr,
+                                 expected_exit, *varargs)
+
+def run_and_verify_svnsync2(expected_stdout, expected_stderr,
+                            expected_exit, *varargs):
+  """Run svnmucc command and check its output and exit code."""
+
+  exit_code, out, err = main.run_svnsync(*varargs)
+
+  # Ignore "consider upgrade" warnings to allow regression tests to pass
+  # when run against a 1.6 mod_dav_svn.
+  for index, line in enumerate(err[:]):
+    if re.search("warning: W200007", line):
+      del err[index]
+
+  verify.verify_outputs("Unexpected output", out, err,
+                        expected_stdout, expected_stderr)
+  verify.verify_exit_code("Unexpected return code", exit_code, expected_exit)
+  return exit_code, out, err
+
+
 def load_repo(sbox, dumpfile_path = None, dump_str = None,
               bypass_prop_validation = False):
   "Loads the dumpfile into sbox"
@@ -1882,32 +1906,44 @@ def run_and_verify_revert(expected_paths
 
 
 # This allows a test to *quickly* bootstrap itself.
-def make_repo_and_wc(sbox, create_wc = True, read_only = False,
-                     minor_version = None):
-  """Create a fresh 'Greek Tree' repository and check out a WC from it.
+def make_repo_and_wc(sbox, create_wc=True, read_only=False, empty=False,
+                     minor_version=None):
+  """Create a fresh repository and check out a WC from it.  If EMPTY is
+  True, the repository and WC will be empty and at revision 0,
+  otherwise they will contain the 'Greek Tree' at revision 1.
 
   If READ_ONLY is False, a dedicated repository will be created, at the path
-  SBOX.repo_dir.  If READ_ONLY is True, the pristine repository will be used.
+  SBOX.repo_dir.  If READ_ONLY is True, a shared pristine repository may be
+  used or a dedicated repository may be created.  (Currently we use a shared
+  pristine 'Greek tree' repo but we create a dedicated empty repo.)
   In either case, SBOX.repo_url is assumed to point to the repository that
   will be used.
 
-  If create_wc is True, a dedicated working copy will be checked out from
+  If CREATE_WC is True, a dedicated working copy will be checked out from
   the repository, at the path SBOX.wc_dir.
 
   Returns on success, raises on failure."""
 
-  # Create (or copy afresh) a new repos with a greek tree in it.
-  if not read_only:
-    guarantee_greek_repository(sbox.repo_dir, minor_version)
+  # Create or copy or reference the appropriate kind of repository:
+  # if we want a non-empty, Greek repo, refer to the shared one; else
+  # if we want an empty repo or a writable Greek repo, create one.
+  # (We could have a shared empty repo for read-only use, but we don't.)
+  if empty:
+    guarantee_empty_repository(sbox.repo_dir, minor_version)
+    expected_state = svntest.wc.State('', {})
+  else:
+    if not read_only:
+      guarantee_greek_repository(sbox.repo_dir, minor_version)
+    expected_state = main.greek_state
 
   if create_wc:
     # Generate the expected output tree.
-    expected_output = main.greek_state.copy()
+    expected_output = expected_state.copy()
     expected_output.wc_dir = sbox.wc_dir
     expected_output.tweak(status='A ', contents=None)
 
     # Generate an expected wc tree.
-    expected_wc = main.greek_state
+    expected_wc = expected_state
 
     # Do a checkout, and verify the resulting output and disk contents.
     run_and_verify_checkout(sbox.repo_url,

Modified: subversion/branches/pin-externals/subversion/tests/cmdline/svntest/main.py
URL: http://svn.apache.org/viewvc/subversion/branches/pin-externals/subversion/tests/cmdline/svntest/main.py?rev=1658128&r1=1658127&r2=1658128&view=diff
==============================================================================
--- subversion/branches/pin-externals/subversion/tests/cmdline/svntest/main.py (original)
+++ subversion/branches/pin-externals/subversion/tests/cmdline/svntest/main.py Sun Feb  8 03:10:25 2015
@@ -132,6 +132,10 @@ else:
 wc_author = 'jrandom'
 wc_passwd = 'rayjandom'
 
+# Username and password used by svnrdump in dump/load cross-checks
+crosscheck_username = '__dumpster__'
+crosscheck_password = '__loadster__'
+
 # Username and password used by the working copies for "second user"
 # scenarios
 wc_author2 = 'jconstant' # use the same password as wc_author
@@ -693,14 +697,25 @@ def _with_config_dir(args):
   else:
     return args + ('--config-dir', default_config_dir)
 
+class svnrdump_crosscheck_authentication:
+  pass
+
 def _with_auth(args):
   assert '--password' not in args
-  args = args + ('--password', wc_passwd,
+  if svnrdump_crosscheck_authentication in args:
+    args = filter(lambda x: x is not svnrdump_crosscheck_authentication, args)
+    auth_username = crosscheck_username
+    auth_password = crosscheck_password
+  else:
+    auth_username = wc_author
+    auth_password = wc_passwd
+
+  args = args + ('--password', auth_password,
                  '--no-auth-cache' )
   if '--username' in args:
     return args
   else:
-    return args + ('--username', wc_author )
+    return args + ('--username', auth_username )
 
 # For running subversion and returning the output
 def run_svn(error_expected, *varargs):
@@ -748,7 +763,8 @@ def run_svnrdump(stdin_input, *varargs):
 def run_svnsync(*varargs):
   """Run svnsync with VARARGS, returns exit code as int; stdout, stderr as
   list of lines (including line terminators)."""
-  return run_command(svnsync_binary, 1, False, *(_with_config_dir(varargs)))
+  return run_command(svnsync_binary, 1, False,
+                     *(_with_auth(_with_config_dir(varargs))))
 
 def run_svnversion(*varargs):
   """Run svnversion with VARARGS, returns exit code as int; stdout, stderr
@@ -934,8 +950,13 @@ def _post_create_repos(path, minor_versi
     # This actually creates TWO [users] sections in the file (one of them is
     # uncommented in `svnadmin create`'s template), so we exercise the .ini
     # files reading code's handling of duplicates, too. :-)
-    file_append(os.path.join(path, "conf", "passwd"),
-                "[users]\njrandom = rayjandom\njconstant = rayjandom\n");
+    users = ("[users]\n"
+             "jrandom = rayjandom\n"
+             "jconstant = rayjandom\n")
+    if tests_verify_dump_load_cross_check():
+      # Insert a user for the dump/load cross-check.
+      users += (crosscheck_username + " = " + crosscheck_password + "\n")
+    file_append(os.path.join(path, "conf", "passwd"), users)
 
   if options.fs_type is None or options.fs_type == 'fsfs':
     # fsfs.conf file
@@ -1201,7 +1222,7 @@ def write_restrictive_svnserve_conf_with
 # parallel execution at the bottom like so
 #   if __name__ == '__main__':
 #     svntest.main.run_tests(test_list, serial_only = True)
-def write_authz_file(sbox, rules, sections=None):
+def write_authz_file(sbox, rules, sections=None, prefixed_rules=None):
   """Write an authz file to SBOX, appropriate for the RA method used,
 with authorizations rules RULES mapping paths to strings containing
 the rules. You can add sections SECTIONS (ex. groups, aliases...) with
@@ -1209,23 +1230,37 @@ an appropriate list of mappings.
 """
   fp = open(sbox.authz_file, 'w')
 
-  # When the sandbox repository is read only it's name will be different from
+  # When the sandbox repository is read only its name will be different from
   # the repository name.
-  repo_name = sbox.repo_dir
-  while repo_name[-1] == '/':
-    repo_name = repo_name[:-1]
-  repo_name = os.path.basename(repo_name)
+  repo_name = os.path.basename(sbox.repo_dir.rstrip('/'))
 
   if sbox.repo_url.startswith("http"):
-    prefix = repo_name + ":"
+    default_prefix = repo_name + ":"
   else:
-    prefix = ""
+    default_prefix = ""
+
   if sections:
     for p, r in sections.items():
       fp.write("[%s]\n%s\n" % (p, r))
 
-  for p, r in rules.items():
-    fp.write("[%s%s]\n%s\n" % (prefix, p, r))
+  if not prefixed_rules:
+    prefixed_rules = dict()
+
+  if rules:
+    for p, r in rules.items():
+      prefixed_rules[default_prefix + p] = r
+
+  for p, r in prefixed_rules.items():
+    fp.write("[%s]\n%s\n" % (p, r))
+    if tests_verify_dump_load_cross_check():
+      # Insert an ACE that lets the dump/load cross-check bypass
+      # authz restrictions.
+      fp.write(crosscheck_username + " = rw\n")
+
+  if tests_verify_dump_load_cross_check() and '/' not in prefixed_rules:
+    # We need a repository-root ACE for the dump/load cross-check
+    fp.write("[/]\n" + crosscheck_username + " = rw\n")
+
   fp.close()
 
 # See the warning about parallel test execution in write_authz_file
@@ -1379,6 +1414,9 @@ def make_log_msg():
 def tests_use_prepacakaged_repository():
   return options.fsfs_version is not None
 
+def tests_verify_dump_load_cross_check():
+  return options.dump_load_cross_check
+
 def is_ra_type_dav():
   return options.test_area_url.startswith('http')
 
@@ -1568,6 +1606,8 @@ class TestSpawningThread(threading.Threa
       args.append('--fsfs-packing')
     if options.fsfs_version:
       args.append('--fsfs-version=' + str(options.fsfs_version))
+    if options.dump_load_cross_check:
+      args.append('--dump-load-cross-check')
 
     result, stdout_lines, stderr_lines = spawn_process(command, 0, False, None,
                                                        *args)
@@ -1892,6 +1932,11 @@ def _create_parser():
                     help='Default shard size (for fsfs)')
   parser.add_option('--fsfs-version', type='int', action='store',
                     help='FSFS version (fsfs)')
+  parser.add_option('--dump-load-cross-check', action='store_true',
+                    help="After every test, run a series of dump and load " +
+                         "tests with svnadmin, svnrdump and svndumpfilter " +
+                         " on the testcase repositories to cross-check " +
+                         " dump file compatibility.")
   parser.add_option('--config-file', action='store',
                     help="Configuration file for tests.")
   parser.add_option('--set-log-level', action='callback', type='str',

Modified: subversion/branches/pin-externals/subversion/tests/cmdline/svntest/sandbox.py
URL: http://svn.apache.org/viewvc/subversion/branches/pin-externals/subversion/tests/cmdline/svntest/sandbox.py?rev=1658128&r1=1658127&r2=1658128&view=diff
==============================================================================
--- subversion/branches/pin-externals/subversion/tests/cmdline/svntest/sandbox.py (original)
+++ subversion/branches/pin-externals/subversion/tests/cmdline/svntest/sandbox.py Sun Feb  8 03:10:25 2015
@@ -26,12 +26,67 @@ import shutil
 import copy
 import urllib
 import logging
+import re
 
 import svntest
 
 logger = logging.getLogger()
 
 
+def make_mirror(sbox, source_prop_encoding=None):
+  """Make a mirror of the repository in SBOX.
+  """
+  # Set up the mirror repository.
+  dest_sbox = sbox.clone_dependent()
+  dest_sbox.build(create_wc=False, empty=True)
+  exit_code, output, errput = svntest.main.run_svnlook("uuid", sbox.repo_dir)
+  svntest.actions.run_and_verify_svnadmin2("Setting UUID", None, None, 0,
+                                           'setuuid', dest_sbox.repo_dir,
+                                           output[0][:-1])
+  svntest.actions.enable_revprop_changes(dest_sbox.repo_dir)
+
+  repo_url = sbox.repo_url
+  dest_repo_url = dest_sbox.repo_url
+
+  # Synchronize it.
+  args = (svntest.main.svnrdump_crosscheck_authentication,)
+  if source_prop_encoding:
+    args = args + ("--source-prop-encoding=" + source_prop_encoding,)
+  svntest.actions.run_and_verify_svnsync(svntest.verify.AnyOutput, [],
+                                         "initialize",
+                                         dest_repo_url, repo_url, *args)
+  svntest.actions.run_and_verify_svnsync(None, [],
+                                         "synchronize",
+                                         dest_repo_url, repo_url, *args)
+
+  return dest_sbox
+
+def verify_mirror(repo_url, repo_dir, expected_dumpfile):
+  """Compare the repository content at REPO_URL/REPO_DIR with that in
+     EXPECTED_DUMPFILE (which is a non-delta dump).
+  """
+  # Remove some SVNSync-specific housekeeping properties from the
+  # mirror repository in preparation for the comparison dump.
+  for prop_name in ("svn:sync-from-url", "svn:sync-from-uuid",
+                    "svn:sync-last-merged-rev"):
+    svntest.actions.run_and_verify_svn(
+      None, None, [], "propdel", "--revprop", "-r", "0",
+      prop_name, repo_url)
+  # Create a dump file from the mirror repository.
+  dumpfile_s_n = svntest.actions.run_and_verify_dump(repo_dir)
+  # Compare the mirror's dumpfile, ignoring any expected differences:
+  # The original dumpfile in some cases lacks 'Text-content-sha1' headers;
+  # the mirror dump always has them -- ### Why?
+  svnsync_headers_always = re.compile("Text-content-sha1: ")
+  dumpfile_a_n_cmp = [l for l in expected_dumpfile
+                      if not svnsync_headers_always.match(l)]
+  dumpfile_s_n_cmp = [l for l in dumpfile_s_n
+                      if not svnsync_headers_always.match(l)]
+  svntest.verify.compare_dump_files(None, None,
+                                    dumpfile_a_n_cmp,
+                                    dumpfile_s_n_cmp)
+
+
 class Sandbox:
   """Manages a sandbox (one or more repository/working copy pairs) for
   a test to operate within."""
@@ -46,7 +101,9 @@ class Sandbox:
     # This flag is set to True by build() and returned by is_built()
     self._is_built = False
 
-  def _set_name(self, name, read_only=False):
+    self.was_cwd = os.getcwd()
+
+  def _set_name(self, name, read_only=False, empty=False):
     """A convenience method for renaming a sandbox, useful when
     working with multiple repositories in the same unit test."""
     if not name is None:
@@ -54,7 +111,7 @@ class Sandbox:
     self.read_only = read_only
     self.wc_dir = os.path.join(svntest.main.general_wc_dir, self.name)
     self.add_test_path(self.wc_dir)
-    if not read_only:
+    if empty or not read_only:  # use a local repo
       self.repo_dir = os.path.join(svntest.main.general_repo_dir, self.name)
       self.repo_url = (svntest.main.options.test_area_url + '/'
                        + urllib.pathname2url(self.repo_dir))
@@ -88,14 +145,16 @@ class Sandbox:
       shutil.copytree(self.wc_dir, clone.wc_dir, symlinks=True)
     return clone
 
-  def build(self, name=None, create_wc=True, read_only=False,
+  def build(self, name=None, create_wc=True, read_only=False, empty=False,
             minor_version=None):
     """Make a 'Greek Tree' repo (or refer to the central one if READ_ONLY),
+       or make an empty repo if EMPTY is true,
        and check out a WC from it (unless CREATE_WC is false). Change the
        sandbox's name to NAME. See actions.make_repo_and_wc() for details."""
-    self._set_name(name, read_only)
+    self._set_name(name, read_only, empty)
     self._ensure_authz()
-    svntest.actions.make_repo_and_wc(self, create_wc, read_only, minor_version)
+    svntest.actions.make_repo_and_wc(self, create_wc, read_only, empty,
+                                     minor_version)
     self._is_built = True
 
   def _ensure_authz(self):
@@ -381,6 +440,123 @@ class Sandbox:
     youngest = int(output[0])
     return youngest
 
+  def verify_repo(self):
+    """
+    """
+    svnrdump_headers_missing = re.compile(
+        "Text-content-sha1: .*|Text-copy-source-md5: .*|"
+        "Text-copy-source-sha1: .*|Text-delta-base-sha1: .*"
+    )
+    svnrdump_headers_always = re.compile(
+        "Prop-delta: .*"
+    )
+
+    dumpfile_a_n = svntest.actions.run_and_verify_dump(self.repo_dir,
+                                                       deltas=False)
+    dumpfile_a_d = svntest.actions.run_and_verify_dump(self.repo_dir,
+                                                       deltas=True)
+    dumpfile_r_d = svntest.actions.run_and_verify_svnrdump(
+      None, svntest.verify.AnyOutput, [], 0, 'dump', '-q', self.repo_url,
+      svntest.main.svnrdump_crosscheck_authentication)
+
+    # Compare the two deltas dumpfiles, ignoring expected differences
+    dumpfile_a_d_cmp = [l for l in dumpfile_a_d
+                       if not svnrdump_headers_missing.match(l)
+                                and not svnrdump_headers_always.match(l)]
+    dumpfile_r_d_cmp = [l for l in dumpfile_r_d
+                       if not svnrdump_headers_always.match(l)]
+    # Ignore differences in number of blank lines between node records,
+    # as svnrdump puts 3 whereas svnadmin puts 2 after a replace-with-copy.
+    svntest.verify.compare_dump_files(None, None,
+                                      dumpfile_a_d_cmp,
+                                      dumpfile_r_d_cmp,
+                                      ignore_number_of_blank_lines=True)
+
+    # Try loading the dump files.
+    # For extra points, load each with the other tool:
+    #   svnadmin dump | svnrdump load
+    #   svnrdump dump | svnadmin load
+    repo_dir_a_n, repo_url_a_n = self.add_repo_path('load_a_n')
+    svntest.main.create_repos(repo_dir_a_n)
+    svntest.actions.enable_revprop_changes(repo_dir_a_n)
+    svntest.actions.run_and_verify_svnrdump(
+      dumpfile_a_n, svntest.verify.AnyOutput, [], 0, 'load', repo_url_a_n,
+      svntest.main.svnrdump_crosscheck_authentication)
+
+    repo_dir_a_d, repo_url_a_d = self.add_repo_path('load_a_d')
+    svntest.main.create_repos(repo_dir_a_d)
+    svntest.actions.enable_revprop_changes(repo_dir_a_d)
+    svntest.actions.run_and_verify_svnrdump(
+      dumpfile_a_d, svntest.verify.AnyOutput, [], 0, 'load', repo_url_a_d,
+      svntest.main.svnrdump_crosscheck_authentication)
+
+    repo_dir_r_d, repo_url_r_d = self.add_repo_path('load_r_d')
+    svntest.main.create_repos(repo_dir_r_d)
+    svntest.actions.run_and_verify_load(repo_dir_r_d, dumpfile_r_d)
+
+    # Dump the loaded repositories in the same way; expect exact equality
+    reloaded_dumpfile_a_n = svntest.actions.run_and_verify_dump(repo_dir_a_n)
+    reloaded_dumpfile_a_d = svntest.actions.run_and_verify_dump(repo_dir_a_d)
+    reloaded_dumpfile_r_d = svntest.actions.run_and_verify_dump(repo_dir_r_d)
+    svntest.verify.compare_dump_files(None, None,
+                                      reloaded_dumpfile_a_n,
+                                      reloaded_dumpfile_a_d,
+                                      ignore_uuid=True)
+    svntest.verify.compare_dump_files(None, None,
+                                      reloaded_dumpfile_a_d,
+                                      reloaded_dumpfile_r_d,
+                                      ignore_uuid=True)
+
+    # Run each dump through svndumpfilter and check for no further change.
+    for dumpfile in [dumpfile_a_n,
+                     dumpfile_a_d,
+                     dumpfile_r_d
+                     ]:
+      ### No buffer size seems to work for update_tests-2. So skip that test?
+      ### (Its dumpfile size is ~360 KB non-delta, ~180 KB delta.)
+      if len(''.join(dumpfile)) > 100000:
+        continue
+
+      exit_code, dumpfile2, errput = svntest.main.run_command_stdin(
+        svntest.main.svndumpfilter_binary, None, -1, True,
+        dumpfile, '--quiet', 'include', '/')
+      assert not exit_code and not errput
+      # Ignore empty prop sections in the input file during comparison, as
+      # svndumpfilter strips them.
+      # Ignore differences in number of blank lines between node records,
+      # as svndumpfilter puts 3 instead of 2 after an add or delete record.
+      svntest.verify.compare_dump_files(None, None, dumpfile, dumpfile2,
+                                        expect_content_length_always=True,
+                                        ignore_empty_prop_sections=True,
+                                        ignore_number_of_blank_lines=True)
+
+    # Run the repository through 'svnsync' and check that this does not
+    # change the repository content. (Don't bother if it's already been
+    # created by svnsync.)
+    if "svn:sync-from-url\n" not in dumpfile_a_n:
+      dest_sbox = make_mirror(self)
+      verify_mirror(dest_sbox.repo_url, dest_sbox.repo_dir, dumpfile_a_n)
+
+  def verify(self, skip_cross_check=False):
+    """Do additional testing that should hold for any sandbox, such as
+       verifying that the repository can be dumped.
+    """
+    if (not skip_cross_check
+        and svntest.main.tests_verify_dump_load_cross_check()):
+      if self.is_built() and not self.read_only:
+        # verify that we can in fact dump the repo
+        # (except for the few tests that deliberately corrupt the repo)
+        os.chdir(self.was_cwd)
+        if os.path.exists(self.repo_dir):
+          logger.info("VERIFY: running dump/load cross-check")
+          self.verify_repo()
+      else:
+        logger.info("VERIFY: WARNING: skipping dump/load cross-check:"
+                    " is-built=%s, read-only=%s"
+                    % (self.is_built() and "true" or "false",
+                       self.read_only and "true" or "false"))
+    pass
+
 def is_url(target):
   return (target.startswith('^/')
           or target.startswith('file://')

Modified: subversion/branches/pin-externals/subversion/tests/cmdline/svntest/testcase.py
URL: http://svn.apache.org/viewvc/subversion/branches/pin-externals/subversion/tests/cmdline/svntest/testcase.py?rev=1658128&r1=1658127&r2=1658128&view=diff
==============================================================================
--- subversion/branches/pin-externals/subversion/tests/cmdline/svntest/testcase.py (original)
+++ subversion/branches/pin-externals/subversion/tests/cmdline/svntest/testcase.py Sun Feb  8 03:10:25 2015
@@ -28,7 +28,8 @@ import os, types, sys
 import svntest
 
 # if somebody does a "from testcase import *", they only get these names
-__all__ = ['_XFail', '_Wimp', '_Skip', '_SkipUnless']
+__all__ = ['_XFail', '_Wimp', '_Skip', '_SkipUnless',
+           '_SkipDumpLoadCrossCheck']
 
 RESULT_OK = 'ok'
 RESULT_FAIL = 'fail'
@@ -135,7 +136,7 @@ class FunctionTestCase(TestCase):
   is derived from the file name in which FUNC was defined)
   """
 
-  def __init__(self, func, issues=None):
+  def __init__(self, func, issues=None, skip_cross_check=False):
     # it better be a function that accepts an sbox parameter and has a
     # docstring on it.
     assert isinstance(func, types.FunctionType)
@@ -161,6 +162,7 @@ class FunctionTestCase(TestCase):
 
     TestCase.__init__(self, doc=doc, issues=issues)
     self.func = func
+    self.skip_cross_check = skip_cross_check
 
   def get_function_name(self):
     return self.func.func_name
@@ -173,7 +175,9 @@ class FunctionTestCase(TestCase):
     return os.path.splitext(os.path.basename(filename))[0]
 
   def run(self, sandbox):
-    return self.func(sandbox)
+    result = self.func(sandbox)
+    sandbox.verify(skip_cross_check = self.skip_cross_check)
+    return result
 
 
 class _XFail(TestCase):
@@ -261,11 +265,22 @@ class _SkipUnless(_Skip):
     _Skip.__init__(self, test_case, lambda c=cond_func: not c())
 
 
-def create_test_case(func, issues=None):
+class _SkipDumpLoadCrossCheck(TestCase):
+  """A test that will skip the post-test dump/load cross-check."""
+
+  def __init__(self, test_case, cond_func=lambda: True, wip=None,
+               issues=None):
+    TestCase.__init__(self,
+                      create_test_case(test_case, skip_cross_check=True),
+                      cond_func, wip=wip, issues=issues)
+
+
+def create_test_case(func, issues=None, skip_cross_check=False):
   if isinstance(func, TestCase):
     return func
   else:
-    return FunctionTestCase(func, issues=issues)
+    return FunctionTestCase(func, issues=issues,
+                            skip_cross_check=skip_cross_check)
 
 
 # Various decorators to make declaring tests as such simpler
@@ -322,5 +337,15 @@ def Issues_deco(*issues):
 
   return _second
 
+def SkipDumpLoadCrossCheck_deco(cond_func = lambda: True):
+  def _second(func):
+    if isinstance(func, TestCase):
+      return _SkipDumpLoadCrossCheck(func, cond_func, issues=func.issues)
+    else:
+      return _SkipDumpLoadCrossCheck(func, cond_func)
+
+  return _second
+
+
 # Create a singular alias, for linguistic correctness
 Issue_deco = Issues_deco

Modified: subversion/branches/pin-externals/subversion/tests/cmdline/svntest/verify.py
URL: http://svn.apache.org/viewvc/subversion/branches/pin-externals/subversion/tests/cmdline/svntest/verify.py?rev=1658128&r1=1658127&r2=1658128&view=diff
==============================================================================
--- subversion/branches/pin-externals/subversion/tests/cmdline/svntest/verify.py (original)
+++ subversion/branches/pin-externals/subversion/tests/cmdline/svntest/verify.py Sun Feb  8 03:10:25 2015
@@ -474,8 +474,10 @@ class DumpParser:
     if not m:
       if required:
         raise SVNDumpParseError("expected '%s' at line %d\n%s"
+                                "\nPrevious lines:\n%s"
                                 % (regex, self.current,
-                                   self.lines[self.current]))
+                                   self.lines[self.current],
+                                   ''.join(self.lines[max(0,self.current - 10):self.current])))
       else:
         return None
     self.current += 1
@@ -507,6 +509,10 @@ class DumpParser:
       headers.append((key, val))
     return headers
 
+
+  def parse_boolean(self, header, required):
+    return self.parse_line(header + ': (false|true)$', required)
+
   def parse_format(self):
     return self.parse_line('SVN-fs-dump-format-version: ([0-9]+)$')
 
@@ -516,6 +522,9 @@ class DumpParser:
   def parse_revision(self):
     return self.parse_line('Revision-number: ([0-9]+)$')
 
+  def parse_prop_delta(self):
+    return self.parse_line('Prop-delta: (false|true)$', required=False)
+
   def parse_prop_length(self, required=True):
     return self.parse_line('Prop-content-length: ([0-9]+)$', required)
 
@@ -523,10 +532,7 @@ class DumpParser:
     return self.parse_line('Content-length: ([0-9]+)$', required)
 
   def parse_path(self):
-    path = self.parse_line('Node-path: (.+)$', required=False)
-    if not path and self.lines[self.current] == 'Node-path: \n':
-      self.current += 1
-      path = ''
+    path = self.parse_line('Node-path: (.*)$', required=False)
     return path
 
   def parse_kind(self):
@@ -557,6 +563,15 @@ class DumpParser:
   def parse_text_sha1(self):
     return self.parse_line('Text-content-sha1: ([0-9a-z]+)$', required=False)
 
+  def parse_text_delta(self):
+    return self.parse_line('Text-delta: (false|true)$', required=False)
+
+  def parse_text_delta_base_md5(self):
+    return self.parse_line('Text-delta-base-md5: ([0-9a-f]+)$', required=False)
+
+  def parse_text_delta_base_sha1(self):
+    return self.parse_line('Text-delta-base-sha1: ([0-9a-f]+)$', required=False)
+
   def parse_text_length(self):
     return self.parse_line('Text-content-length: ([0-9]+)$', required=False)
 
@@ -586,8 +601,14 @@ class DumpParser:
 
         return key
 
-      key = read_key_or_value(curprop)
-      value = read_key_or_value(curprop)
+      if props[curprop[0]].startswith('K'):
+        key = read_key_or_value(curprop)
+        value = read_key_or_value(curprop)
+      elif props[curprop[0]].startswith('D'):
+        key = read_key_or_value(curprop)
+        value = None
+      else:
+        raise
       prophash[key] = value
 
     return prophash
@@ -664,7 +685,7 @@ class DumpParser:
       if self.current >= len(self.lines):
         break
       path = self.parse_path()
-      if not path and not path is '':
+      if path is None:
         break
       if not nodes.get(path):
         nodes[path] = {}
@@ -702,7 +723,11 @@ class DumpParser:
     self.parse_all_revisions()
     return self.parsed
 
-def compare_dump_files(message, label, expected, actual):
+def compare_dump_files(message, label, expected, actual,
+                       ignore_uuid=False,
+                       expect_content_length_always=False,
+                       ignore_empty_prop_sections=False,
+                       ignore_number_of_blank_lines=False):
   """Parse two dump files EXPECTED and ACTUAL, both of which are lists
   of lines as returned by run_and_verify_dump, and check that the same
   revisions, nodes, properties, etc. are present in both dumps.
@@ -711,8 +736,39 @@ def compare_dump_files(message, label, e
   parsed_expected = DumpParser(expected).parse()
   parsed_actual = DumpParser(actual).parse()
 
+  if ignore_uuid:
+    parsed_expected['uuid'] = '<ignored>'
+    parsed_actual['uuid'] = '<ignored>'
+
+  for parsed in [parsed_expected, parsed_actual]:
+    for rev_name, rev_record in parsed.items():
+      #print "Found %s" % (rev_name,)
+      if 'nodes' in rev_record:
+        #print "Found %s.%s" % (rev_name, 'nodes')
+        for path_name, path_record in rev_record['nodes'].items():
+          #print "Found %s.%s.%s" % (rev_name, 'nodes', path_name)
+          for action_name, action_record in path_record.items():
+            #print "Found %s.%s.%s.%s" % (rev_name, 'nodes', path_name, action_name)
+
+            if expect_content_length_always:
+              if action_record.get('content_length') == None:
+                #print 'Adding: %s.%s.%s.%s.%s' % (rev_name, 'nodes', path_name, action_name, 'content_length=0')
+                action_record['content_length'] = '0'
+            if ignore_empty_prop_sections:
+              if action_record.get('prop_length') == '10':
+                #print 'Removing: %s.%s.%s.%s.%s' % (rev_name, 'nodes', path_name, action_name, 'prop_length')
+                action_record['prop_length'] = None
+                del action_record['props']
+                old_content_length = int(action_record['content_length'])
+                action_record['content_length'] = str(old_content_length - 10)
+            if ignore_number_of_blank_lines:
+              action_record['blanks'] = 0
+
   if parsed_expected != parsed_actual:
-    raise svntest.Failure('\n' + '\n'.join(ndiff(
+    print 'DIFF of raw dumpfiles (including expected differences)'
+    print ''.join(ndiff(expected, actual))
+    raise svntest.Failure('DIFF of parsed dumpfiles (ignoring expected differences)\n'
+                          + '\n'.join(ndiff(
           pprint.pformat(parsed_expected).splitlines(),
           pprint.pformat(parsed_actual).splitlines())))
 



Mime
View raw message