You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by hw...@apache.org on 2010/08/10 22:56:05 UTC

svn commit: r984206 [34/35] - in /subversion/branches/ignore-mergeinfo: ./ build/ build/generator/ build/generator/templates/ build/hudson/ build/hudson/jobs/subversion-1.6.x-solaris/ build/hudson/jobs/subversion-1.6.x-ubuntu/ build/hudson/jobs/subvers...

Modified: subversion/branches/ignore-mergeinfo/subversion/tests/cmdline/special_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/tests/cmdline/special_tests.py?rev=984206&r1=984205&r2=984206&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/tests/cmdline/special_tests.py (original)
+++ subversion/branches/ignore-mergeinfo/subversion/tests/cmdline/special_tests.py Tue Aug 10 20:55:56 2010
@@ -620,15 +620,7 @@ def update_obstructing_symlink(sbox):
 def warn_on_reserved_name(sbox):
   "warn when attempt operation on a reserved name"
   sbox.build()
-  wc_dir = sbox.wc_dir
-  if os.path.exists(os.path.join(wc_dir, ".svn")):
-    reserved_path = os.path.join(wc_dir, ".svn")
-  elif os.path.exists(os.path.join(wc_dir, "_svn")):
-    reserved_path = os.path.join(wc_dir, "_svn")
-  else:
-    # We don't know how to test this, but have no reason to believe
-    # it would fail.  (TODO: any way to return 'Skip', though?)
-    return
+  reserved_path = os.path.join(sbox.wc_dir, svntest.main.get_admin_name())
   svntest.actions.run_and_verify_svn(
     "Locking a file with a reserved name failed to result in an error",
     None,
@@ -636,6 +628,42 @@ def warn_on_reserved_name(sbox):
     'lock', reserved_path)
 
 
+def propvalue_normalized(sbox):
+  "'ps svn:special' should normalize to '*'"
+
+  sbox.build()
+  wc_dir = sbox.wc_dir
+
+  # Add a "symlink"
+  iota2_path = sbox.ospath('iota2')
+  svntest.main.file_write(iota2_path, "This is the file 'iota2'.\n")
+  svntest.main.run_svn(None, 'add', iota2_path)
+  svntest.main.run_svn(None, 'propset', 'svn:special', 'yes', iota2_path)
+
+  # Property value should be SVN_PROP_BOOLEAN_TRUE
+  expected_propval = ['*']
+  svntest.actions.run_and_verify_svn(None, expected_propval, [],
+                                     'propget', '--strict', 'svn:special',
+                                     iota2_path)
+
+  # Commit and check again.
+  expected_output = svntest.wc.State(wc_dir, {
+    'iota2' : Item(verb='Adding'),
+    })
+  expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
+  expected_status.add({
+    'iota2' : Item(status='  ', wc_rev=2),
+    })
+  svntest.actions.run_and_verify_commit(wc_dir, expected_output,
+                                        expected_status, None,
+                                        wc_dir)
+
+  svntest.main.run_svn(None, 'update')
+  svntest.actions.run_and_verify_svn(None, expected_propval, [],
+                                     'propget', '--strict', 'svn:special',
+                                     iota2_path)
+
+
 ########################################################################
 # Run the tests
 
@@ -658,6 +686,7 @@ test_list = [ None,
               replace_symlink_with_dir,
               SkipUnless(update_obstructing_symlink, svntest.main.is_posix_os),
               warn_on_reserved_name,
+              Skip(propvalue_normalized, svntest.main.is_posix_os),
              ]
 
 if __name__ == '__main__':

Modified: subversion/branches/ignore-mergeinfo/subversion/tests/cmdline/svnadmin_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/tests/cmdline/svnadmin_tests.py?rev=984206&r1=984205&r2=984206&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/tests/cmdline/svnadmin_tests.py (original)
+++ subversion/branches/ignore-mergeinfo/subversion/tests/cmdline/svnadmin_tests.py Tue Aug 10 20:55:56 2010
@@ -96,7 +96,7 @@ def load_and_verify_dumpstream(sbox, exp
     dump = [ dump ]
 
   exit_code, output, errput = svntest.main.run_command_stdin(
-    svntest.main.svnadmin_binary, expected_stderr, 1, dump,
+    svntest.main.svnadmin_binary, expected_stderr, 0, 1, dump,
     'load', '--quiet', sbox.repo_dir, *varargs)
 
   if expected_stdout:
@@ -625,7 +625,7 @@ def recover_fsfs(sbox):
   svntest.main.run_svn(None, 'ci', sbox.wc_dir, '--quiet', '-m', 'log msg')
 
   # Remember the contents of the db/current file.
-  expected_current_contents = svntest.main.file_read(current_path)
+  expected_current_contents = open(current_path).read()
 
   # Move aside the current file for r3.
   os.rename(os.path.join(sbox.repo_dir, 'db','current'),
@@ -637,7 +637,7 @@ def recover_fsfs(sbox):
   if errput:
     raise SVNUnexpectedStderr(errput)
 
-  actual_current_contents = svntest.main.file_read(current_path)
+  actual_current_contents = open(current_path).read()
   svntest.verify.compare_and_display_lines(
     "Contents of db/current is unexpected.",
     'db/current', expected_current_contents, actual_current_contents)
@@ -651,7 +651,7 @@ def recover_fsfs(sbox):
   if errput:
     raise SVNUnexpectedStderr(errput)
 
-  actual_current_contents = svntest.main.file_read(current_path)
+  actual_current_contents = open(current_path).read()
   svntest.verify.compare_and_display_lines(
     "Contents of db/current is unexpected.",
     'db/current', expected_current_contents, actual_current_contents)
@@ -665,7 +665,7 @@ def recover_fsfs(sbox):
   if errput:
     raise SVNUnexpectedStderr(errput)
 
-  actual_current_contents = svntest.main.file_read(current_path)
+  actual_current_contents = open(current_path).read()
   svntest.verify.compare_and_display_lines(
     "Contents of db/current is unexpected.",
     'db/current', expected_current_contents, actual_current_contents)
@@ -684,7 +684,7 @@ def recover_fsfs(sbox):
   if errput:
     raise SVNUnexpectedStderr(errput)
 
-  actual_current_contents = svntest.main.file_read(current_path)
+  actual_current_contents = open(current_path).read()
   svntest.verify.compare_and_display_lines(
     "Contents of db/current is unexpected.",
     'db/current', expected_current_contents, actual_current_contents)
@@ -700,7 +700,7 @@ def load_with_parent_dir(sbox):
   dumpfile_location = os.path.join(os.path.dirname(sys.argv[0]),
                                    'svnadmin_tests_data',
                                    'mergeinfo_included.dump')
-  dumpfile = svntest.main.file_read(dumpfile_location)
+  dumpfile = open(dumpfile_location).read()
 
   # Create 'sample' dir in sbox.repo_url, and load the dump stream there.
   svntest.actions.run_and_verify_svn(None,
@@ -798,7 +798,7 @@ def reflect_dropped_renumbered_revs(sbox
   dumpfile_location = os.path.join(os.path.dirname(sys.argv[0]),
                                    'svndumpfilter_tests_data',
                                    'with_merges.dump')
-  dumpfile = svntest.main.file_read(dumpfile_location)
+  dumpfile = open(dumpfile_location).read()
 
   # Create 'toplevel' dir in sbox.repo_url
   svntest.actions.run_and_verify_svn(None, ['\n', 'Committed revision 1.\n'],
@@ -813,24 +813,14 @@ def reflect_dropped_renumbered_revs(sbox
                              '/toplevel')
 
   # Verify the svn:mergeinfo properties
-  svntest.actions.run_and_verify_svn(None, ["/trunk:2-4\n"],
-                                     [], 'propget', 'svn:mergeinfo',
-                                     sbox.repo_url + '/branch2')
-  svntest.actions.run_and_verify_svn(None, ["/branch1:5-9\n"],
-                                     [], 'propget', 'svn:mergeinfo',
-                                     sbox.repo_url + '/trunk')
-  svntest.actions.run_and_verify_svn(None, ["/toplevel/trunk:11-13\n"],
-                                     [], 'propget', 'svn:mergeinfo',
-                                     sbox.repo_url + '/toplevel/branch2')
-  svntest.actions.run_and_verify_svn(None, ["/toplevel/branch1:14-18\n"],
-                                     [], 'propget', 'svn:mergeinfo',
-                                     sbox.repo_url + '/toplevel/trunk')
-  svntest.actions.run_and_verify_svn(None, ["/toplevel/trunk:11-12\n"],
-                                     [], 'propget', 'svn:mergeinfo',
-                                     sbox.repo_url + '/toplevel/branch1')
-  svntest.actions.run_and_verify_svn(None, ["/trunk:2-3\n"],
-                                     [], 'propget', 'svn:mergeinfo',
-                                     sbox.repo_url + '/branch1')
+  url = sbox.repo_url
+  expected_output = svntest.verify.UnorderedOutput([
+    url + "/trunk - /branch1:5-9\n",
+    url + "/toplevel/trunk - /toplevel/branch1:14-18\n",
+    ])
+  svntest.actions.run_and_verify_svn(None, expected_output, [],
+                                     'propget', 'svn:mergeinfo', '-R',
+                                     sbox.repo_url)
 
 #----------------------------------------------------------------------
 
@@ -960,34 +950,34 @@ def verify_with_invalid_revprops(sbox):
     raise svntest.Failure
 
 #----------------------------------------------------------------------
-# More testing for issue #3020 'Reflect dropped/renumbered revisions in
-# svn:mergeinfo data during svnadmin load'
+# Even *more* testing for issue #3020 'Reflect dropped/renumbered
+# revisions in svn:mergeinfo data during svnadmin load'
 #
-# Specifically, test that loading a partial dump file filters out
-# mergeinfo that refers to revisions that are older than the oldest
-# loaded revisions -- See
-# http://subversion.tigris.org/issues/show_bug.cgi?id=3020#desc10.
-def drop_mergeinfo_outside_of_dump_stream(sbox):
-  "filter mergeinfo revs outside of dump stream"
+# Full or incremental dump-load cycles should result in the same
+# mergeinfo in the loaded repository.
+#
+# Given a repository 'SOURCE-REPOS' with mergeinfo, and a repository
+# 'TARGET-REPOS' (which may or may not be empty), either of the following
+# methods to move 'SOURCE-REPOS' to 'TARGET-REPOS' should result in
+# the same mergeinfo on 'TARGET-REPOS':
+#
+#   1) Dump -r1:HEAD from 'SOURCE-REPOS' and load it in one shot to
+#      'TARGET-REPOS'.
+#
+#   2) Dump 'SOURCE-REPOS' in a series of incremental dumps and load
+#      each of them to 'TARGET-REPOS'.
+#
+# See http://subversion.tigris.org/issues/show_bug.cgi?id=3020#desc13
+def dont_drop_valid_mergeinfo_during_incremental_loads(sbox):
+  "don't filter mergeinfo revs from incremental dump"
 
+  # Create an empty repos.
   test_create(sbox)
 
-  # Load a partial dump into an existing repository.
-  #
-  # Picture == 1k words:
-  #
-  # The existing repos loaded from skeleton_repos.dump looks like this:
+  # PART 1: Load a full dump to an empty repository.
   #
-  # Projects/       (Added r1)
-  #   README        (Added r2)
-  #   Project-X     (Added r3)
-  #   Project-Y     (Added r4)
-  #   Project-Z     (Added r5)
-  #   docs/         (Added r6)
-  #     README      (Added r6)
-  #
-  # The dump file 'mergeinfo_included_partial.dump' is a dump of r6:HEAD of
-  # the following repos:
+  # The test repository used here, 'mergeinfo_included_full.dump', is
+  # this repos:
   #                       __________________________________________
   #                      |                                         |
   #                      |             ____________________________|_____
@@ -1016,7 +1006,7 @@ def drop_mergeinfo_outside_of_dump_strea
   #                  branches/B1/B/E------------------------------r14---r15->
   #                  
   #
-  # The mergeinfo on the complete repos in the preceeding repos looks like:
+  # The mergeinfo on this repos@15 is:
   #
   #   Properties on 'branches/B1':
   #     svn:mergeinfo
@@ -1029,113 +1019,10 @@ def drop_mergeinfo_outside_of_dump_strea
   #   Properties on 'branches/B2':
   #     svn:mergeinfo
   #       /trunk:9
-  #
-  # If we were to load the dump of r6:HEAD into an empty repository, we'd
-  # expect any references to revisions <r6 to be removed entirely (since
-  # that history no longer exists) and the the remaining mergeinfo should
-  # have its revisions offset by -5.  The resulting mergeinfo should look
-  # like this:
-  #
-  #   Properties on 'branches/B1':
-  #     svn:mergeinfo
-  #       /branches/B2:6-7
-  #       /trunk:1,4
-  #   Properties on 'branches/B1/B/E':
-  #     svn:mergeinfo
-  #       /branches/B2/B/E:6-7
-  #       /trunk/B/E:1,3-4
-  #   Properties on 'branches/B2':
-  #     svn:mergeinfo
-  #       /trunk:4
-  #
-  # But here we will load it into the existing skeleton repository in the
-  # Projects/Project-X directory.  Since we are loading the dump into a
-  # subtree, all the merge sources should be prefixed with the path to
-  # that subtree, i.e. 'Projects/Project-X', compared to the mergeinfo above.
-  # In addition, since the skeleton repos already has 6 revisions, we expect
-  # all the remaining revisions to be offset +6 from the above.  That should
-  # result in this mergeinfo:
-  #
-  #   Properties on 'Projects/Project-X/branches/B1':
-  #     svn:mergeinfo
-  #       /Projects/Project-X/branches/B2:12-13
-  #       /Projects/Project-X/trunk:7,10
-  #   Properties on 'Projects/Project-X/branches/B1/B/E':
-  #     svn:mergeinfo
-  #       /Projects/Project-X/branches/B2/B/E:12-13
-  #       /Projects/Project-X/trunk/B/E:7,9-10
-  #   Properties on 'Projects/Project-X/branches/B2':
-  #     svn:mergeinfo
-  #       /Projects/Project-X/trunk:10
-
-  # Load the skeleton dump:
-  dumpfile1 = svntest.main.file_read(
-    os.path.join(os.path.dirname(sys.argv[0]),
-                 'svnadmin_tests_data',
-                 'skeleton_repos.dump'))
-  load_and_verify_dumpstream(sbox, [], [], None, dumpfile1, '--ignore-uuid')
-
-  # Load the partial repository with mergeinfo dump:
-  dumpfile2 = svntest.main.file_read(
-    os.path.join(os.path.dirname(sys.argv[0]),
-                 'svnadmin_tests_data',
-                 'mergeinfo_included_partial.dump'))
-  load_and_verify_dumpstream(sbox, [], [], None, dumpfile2, '--ignore-uuid',
-                             '--parent-dir', '/Projects/Project-X')
-
-  # Check the resulting mergeinfo.
-  #
-  # TODO: Use pg -vR, which would make the expected output easier on the eyes.
-  #       Not using it because pg -vR on windows is outputting <CR><CR><LF>
-  #       after the first line of multiline mergeinfo, which breaks the
-  #       comparison, e.g.:
-  #
-  #   Properties on 'Projects/Project-X/branches/B1/B/E':<CR><LF>
-  #     svn:mergeinfo<CR><LF>
-  #       /Projects/Project-X/branches/B2:12-13<CR><CR><LF>
-  #                                            ^^^
-  #       /Projects/Project-X/trunk:7,10<CR><LF>
-  url = sbox.repo_url + '/Projects/Project-X/branches/'
-  expected_output = svntest.verify.UnorderedOutput([
-    url + "B1 - /Projects/Project-X/branches/B2:12-13\n",
-    "/Projects/Project-X/trunk:7,10\n",
-    url + "B2 - /Projects/Project-X/trunk:10\n",
-    url + "B1/B/E - /Projects/Project-X/branches/B2/B/E:12-13\n",
-    "/Projects/Project-X/trunk/B/E:7,9-10\n"])
-  svntest.actions.run_and_verify_svn(None, expected_output, [],
-                                     'propget', 'svn:mergeinfo', '-R',
-                                     sbox.repo_url)
-
-#----------------------------------------------------------------------
-# Even *more* testing for issue #3020 'Reflect dropped/renumbered
-# revisions in svn:mergeinfo data during svnadmin load'
-#
-# Filtering revsions from mergeinfo in a load stream that refers to
-# history outside of the stream is all well and good if the load
-# is a partial dump loaded in one shot...but if a repository's full
-# history is dumped incrementally and each incremental dump is loaded,
-# well then, *any* filtering done then is removing valid mergeinfo...
-#
-# ...and currently we do exactly that, as this test demonstrates.
-#
-# Note: If a repository is *partially* dumped in a sequence of incremental
-# dumps then possibly some mergeinfo should be filtered on the load, but
-# not *all* mergeinfo, which is what we are doing in that case too.
-def dont_drop_valid_mergeinfo_during_incremental_loads(sbox):
-  "don't filter mergeinfo revs from incremental dump"
-
-  # Create an empty repos.
-  test_create(sbox)
-
-  # Load the test repository to the first repos in a single load.
-  #
-  # Note: The test repository 'mergeinfo_included_full.dump' is the full
-  # repos diagramed in the test drop_mergeinfo_outside_of_dump_stream.
-  dumpfile1 = svntest.main.file_read(
-    os.path.join(os.path.dirname(sys.argv[0]),
-                 'svnadmin_tests_data',
-                 'mergeinfo_included_full.dump'))
-  load_and_verify_dumpstream(sbox, [], [], None, dumpfile1, '--ignore-uuid')
+  dumpfile_full = open(os.path.join(os.path.dirname(sys.argv[0]),
+                                    'svnadmin_tests_data',
+                                    'mergeinfo_included_full.dump')).read()
+  load_and_verify_dumpstream(sbox, [], [], None, dumpfile_full, '--ignore-uuid')
 
   # Check that the mergeinfo is as expected.
   url = sbox.repo_url + '/branches/'
@@ -1149,7 +1036,9 @@ def dont_drop_valid_mergeinfo_during_inc
                                      'propget', 'svn:mergeinfo', '-R',
                                      sbox.repo_url)  
 
-  # Now incrementally dump that repository into three dump files:
+  # PART 2: Load a a series of incremental dumps to an empty repository.
+  #
+  # Incrementally dump the repository into three dump files:
   dump_file_r1_10 = svntest.main.temp_dir + "-r1-10.dump"
   exit_code, output, errput = svntest.main.run_svnadmin(
     'dump', sbox.repo_dir, '-r1:10')
@@ -1176,21 +1065,125 @@ def dont_drop_valid_mergeinfo_during_inc
 
   # Load the three incremental dump files in sequence.
   load_and_verify_dumpstream(sbox, [], [], None,
-                             svntest.main.file_read(dump_file_r1_10),
+                             open(dump_file_r1_10).read(),
                              '--ignore-uuid')
   load_and_verify_dumpstream(sbox, [], [], None,
-                             svntest.main.file_read(dump_file_r11_13),
+                             open(dump_file_r11_13).read(),
                              '--ignore-uuid')
   load_and_verify_dumpstream(sbox, [], [], None,
-                             svntest.main.file_read(dump_file_r14_15),
+                             open(dump_file_r14_15).read(),
                              '--ignore-uuid')
 
   # Check the mergeinfo, we use the same expected output as before,
   # as it (duh!) should be exactly the same as when we loaded the
   # repos in one shot.
+  svntest.actions.run_and_verify_svn(None, expected_output, [],
+                                     'propget', 'svn:mergeinfo', '-R',
+                                     sbox.repo_url)
+
+  # Now repeat the above two scenarios, but with an initially non-empty target
+  # repository.  First, try the full dump-load in one shot.
+  #
+  # PART 3: Load a full dump to an non-empty repository.
+  #  
+  # Reset our sandbox.
+  test_create(sbox)
+
+  # Load this skeleton repos into the empty target:
+  #
+  #   Projects/       (Added r1)
+  #     README        (Added r2)
+  #     Project-X     (Added r3)
+  #     Project-Y     (Added r4)
+  #     Project-Z     (Added r5)
+  #     docs/         (Added r6)
+  #       README      (Added r6)
+  dumpfile_skeleton = open(os.path.join(os.path.dirname(sys.argv[0]),
+                                        'svnadmin_tests_data',
+                                        'skeleton_repos.dump')).read()
+  load_and_verify_dumpstream(sbox, [], [], None, dumpfile_skeleton,
+                             '--ignore-uuid')
+
+  # Load 'svnadmin_tests_data/mergeinfo_included_full.dump' in one shot:
+  load_and_verify_dumpstream(sbox, [], [], None, dumpfile_full,
+                             '--parent-dir', 'Projects/Project-X',
+                             '--ignore-uuid')
+
+  # Check that the mergeinfo is as expected.  This is exactly the
+  # same expected mergeinfo we previously checked, except that the
+  # revisions are all offset +6 to reflect the revions already in
+  # the skeleton target before we began loading and the leading source
+  # paths are adjusted by the --parent-dir:
+  #
+  #   Properties on 'branches/B1':
+  #     svn:mergeinfo
+  #       /Projects/Project-X/branches/B2:17-18
+  #       /Projects/Project-X/trunk:12,15
+  #   Properties on 'branches/B1/B/E':
+  #     svn:mergeinfo
+  #       /Projects/Project-X/branches/B2/B/E:17-18
+  #       /Projects/Project-X/trunk/B/E:11-12,14-15
+  #   Properties on 'branches/B2':
+  #     svn:mergeinfo
+  #       /Projects/Project-X/trunk:15
+  url = sbox.repo_url + '/Projects/Project-X/branches/'
+  expected_output = svntest.verify.UnorderedOutput([
+    url + "B1 - /Projects/Project-X/branches/B2:17-18\n",
+    "/Projects/Project-X/trunk:12,15\n",
+    url + "B2 - /Projects/Project-X/trunk:15\n",
+    url + "B1/B/E - /Projects/Project-X/branches/B2/B/E:17-18\n",
+    "/Projects/Project-X/trunk/B/E:11-12,14-15\n"])
+  svntest.actions.run_and_verify_svn(None, expected_output, [],
+                                     'propget', 'svn:mergeinfo', '-R',
+                                     sbox.repo_url)
+
+  # PART 4: Load a a series of incremental dumps to an non-empty repository.
+  #
+  # Reset our sandbox.
+  test_create(sbox)
+
+  # Load this skeleton repos into the empty target:
+  load_and_verify_dumpstream(sbox, [], [], None, dumpfile_skeleton,
+                             '--ignore-uuid')
+  
+  # Load the three incremental dump files in sequence.
+  load_and_verify_dumpstream(sbox, [], [], None,
+                             open(dump_file_r1_10).read(),
+                             '--parent-dir', 'Projects/Project-X',
+                             '--ignore-uuid')
+  load_and_verify_dumpstream(sbox, [], [], None,
+                             open(dump_file_r11_13).read(),
+                             '--parent-dir', 'Projects/Project-X',
+                             '--ignore-uuid')
+  load_and_verify_dumpstream(sbox, [], [], None,
+                             open(dump_file_r14_15).read(),
+                             '--parent-dir', 'Projects/Project-X',
+                             '--ignore-uuid')
+
+  # Check the resulting mergeinfo.  We expect the exact same results
+  # as Part 3.
+  #
+  # Currently this fails because our current logic mapping mergeinfo revs
+  # in the load stream to their new values based on the offset of the
+  # target repository is quite flawed.  Right now this is the resulting
+  # mergeinfo:
+  #
+  #    Properties on 'svnadmin_tests-21\Projects\Project-X\branches\B1\B
+  #      svn:mergeinfo
+  #        /Projects/Project-X/branches/B2/B/E:11-12
+  #        /Projects/Project-X/trunk/B/E:5-6,8-9
+  #    Properties on 'svnadmin_tests-21\Projects\Project-X\branches\B1':
+  #      svn:mergeinfo
+  #        /Projects/Project-X/branches/B2:11-18
+  #                                           ^^
+  #                                 The *only* correct rev here!
+  #        /Projects/Project-X/trunk:6,9
+  #    Properties on 'svnadmin_tests-21\Projects\Project-X\branches\B2':
+  #      svn:mergeinfo
+  #        /Projects/Project-X/trunk:9
   #
-  # Currently this test is set as XFail, because the mergeinfo filtering
-  # logic in load is removing valid mergeinfo.
+  # See http://subversion.tigris.org/issues/show_bug.cgi?id=3020#desc16 for
+  # more info.
   svntest.actions.run_and_verify_svn(None, expected_output, [],
                                      'propget', 'svn:mergeinfo', '-R',
                                      sbox.repo_url)
@@ -1222,7 +1215,6 @@ test_list = [ None,
               create_in_repo_subdir,
               SkipUnless(verify_with_invalid_revprops,
                          svntest.main.is_fs_type_fsfs),
-              drop_mergeinfo_outside_of_dump_stream,
               XFail(dont_drop_valid_mergeinfo_during_incremental_loads),
              ]
 

Modified: subversion/branches/ignore-mergeinfo/subversion/tests/cmdline/svndumpfilter_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/tests/cmdline/svndumpfilter_tests.py?rev=984206&r1=984205&r2=984206&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/tests/cmdline/svndumpfilter_tests.py (original)
+++ subversion/branches/ignore-mergeinfo/subversion/tests/cmdline/svndumpfilter_tests.py Tue Aug 10 20:55:56 2010
@@ -47,17 +47,34 @@ Item = svntest.wc.StateItem
 # Helper routines
 
 
-def filter_and_return_output(dump, *varargs):
-  """Filter the array of lines passed in 'dump' and return the output"""
+def filter_and_return_output(dump, bufsize=0, *varargs):
+  """Filter the array of lines passed in 'dump' and return the output
+  and errput"""
 
   if isinstance(dump, str):
     dump = [ dump ]
 
-  ## TODO: Should we need to handle errput and exit_code?
+  # Does the caller want the stderr?
+  try:
+      varargs.index('-q')
+      expected_errput = None # Stderr with -q or --quiet is a real error!
+  except:
+      try:
+          varargs.index('--quiet')
+          expected_errput = None
+      except:
+          expected_errput = svntest.verify.AnyOutput
+  ## TODO: Should we handle exit_code?
   exit_code, output, errput = svntest.main.run_command_stdin(
-    svntest.main.svndumpfilter_binary, None, 1, dump, *varargs)
+    svntest.main.svndumpfilter_binary, expected_errput, bufsize, 1,
+    dump, *varargs)
 
-  return output
+  # Since we call svntest.main.run_command_stdin() in binary mode,
+  # normalize the stderr line endings on Windows ourselves.
+  if sys.platform == 'win32':
+      errput = map(lambda x : x.replace('\r\n', '\n'), errput)
+      
+  return output, errput
 
 
 ######################################################################
@@ -74,45 +91,46 @@ def reflect_dropped_renumbered_revs(sbox
   dumpfile_location = os.path.join(os.path.dirname(sys.argv[0]),
                                    'svndumpfilter_tests_data',
                                    'with_merges.dump')
-  dumpfile = svntest.main.file_read(dumpfile_location)
+  dumpfile = open(dumpfile_location).read()
+
+  filtered_out, filtered_err = filter_and_return_output(
+      dumpfile, 0, "include",
+      "trunk", "branch1",
+      "--skip-missing-merge-sources",
+      "--drop-empty-revs",
+      "--renumber-revs", "--quiet")
 
-  filtered_out = filter_and_return_output(dumpfile, "include",
-                                          "trunk", "branch1",
-                                          "--skip-missing-merge-sources",
-                                          "--drop-empty-revs",
-                                          "--renumber-revs", "--quiet")
   load_and_verify_dumpstream(sbox, [], [], None, filtered_out,
                              "--ignore-uuid")
 
   # Verify the svn:mergeinfo properties
-  svntest.actions.run_and_verify_svn(None,
-                                     [sbox.repo_url+"/trunk - /branch1:4-5\n"],
-                                     [], 'propget', 'svn:mergeinfo', '-R',
-                                     sbox.repo_url + '/trunk')
-  svntest.actions.run_and_verify_svn(None,
-                                     [sbox.repo_url+"/branch1 - /trunk:1-2\n"],
-                                     [], 'propget', 'svn:mergeinfo', '-R',
-                                     sbox.repo_url + '/branch1')
+  url = sbox.repo_url
+  expected_output = svntest.verify.UnorderedOutput([
+    url + "/trunk - /branch1:4-5\n",
+    ])
+  svntest.actions.run_and_verify_svn(None, expected_output, [],
+                                     'propget', 'svn:mergeinfo', '-R',
+                                     sbox.repo_url)
+  
 
   # Test svndumpfilter with exclude option
   test_create(sbox)
-  filtered_out = filter_and_return_output(dumpfile, "exclude",
-                                          "branch1",
-                                          "--skip-missing-merge-sources",
-                                          "--drop-empty-revs",
-                                          "--renumber-revs", "--quiet")
+  filtered_out, filtered_err = filter_and_return_output(
+      dumpfile, 0, "exclude", "branch1",
+      "--skip-missing-merge-sources",
+      "--drop-empty-revs",
+      "--renumber-revs", "--quiet")
+
   load_and_verify_dumpstream(sbox, [], [], None, filtered_out,
                              "--ignore-uuid")
 
   # Verify the svn:mergeinfo properties
-  svntest.actions.run_and_verify_svn(None,
-                                     [sbox.repo_url+"/trunk - \n"],
-                                     [], 'propget', 'svn:mergeinfo', '-R',
-                                     sbox.repo_url + '/trunk')
-  svntest.actions.run_and_verify_svn(None,
-                                     [sbox.repo_url+"/branch2 - /trunk:1-2\n"],
-                                     [], 'propget', 'svn:mergeinfo', '-R',
-                                     sbox.repo_url + '/branch2')
+  expected_output = svntest.verify.UnorderedOutput([
+    url + "/trunk - \n",
+    ])
+  svntest.actions.run_and_verify_svn(None, expected_output, [],
+                                     'propget', 'svn:mergeinfo', '-R',
+                                     sbox.repo_url)
 
 def svndumpfilter_loses_mergeinfo(sbox):
   "svndumpfilter loses mergeinfo"
@@ -124,27 +142,29 @@ def svndumpfilter_loses_mergeinfo(sbox):
   dumpfile_location = os.path.join(os.path.dirname(sys.argv[0]),
                                    'svndumpfilter_tests_data',
                                    'with_merges.dump')
-  dumpfile = svntest.main.file_read(dumpfile_location)
+  dumpfile = open(dumpfile_location).read()
 
-  filtered_out = filter_and_return_output(dumpfile, "include",
-                                          "trunk", "branch1", "--quiet")
+  filtered_out, filtered_err = filter_and_return_output(dumpfile, 0, "include",
+                                                        "trunk", "branch1",
+                                                        "--quiet")
   load_and_verify_dumpstream(sbox, [], [], None, filtered_out)
 
   # Verify the svn:mergeinfo properties
-  svntest.actions.run_and_verify_svn(None,
-                                     [sbox.repo_url+"/trunk - /branch1:4-8\n"],
-                                     [], 'propget', 'svn:mergeinfo', '-R',
-                                     sbox.repo_url + '/trunk')
-  svntest.actions.run_and_verify_svn(None,
-                                     [sbox.repo_url+"/branch1 - /trunk:1-2\n"],
-                                     [], 'propget', 'svn:mergeinfo', '-R',
-                                     sbox.repo_url + '/branch1')
+  url = sbox.repo_url
+  expected_output = svntest.verify.UnorderedOutput([
+    url + "/trunk - /branch1:4-8\n",
+    ])
+  svntest.actions.run_and_verify_svn(None, expected_output, [],
+                                     'propget', 'svn:mergeinfo', '-R',
+                                     sbox.repo_url)
 
 
 def _simple_dumpfilter_test(sbox, dumpfile, *dumpargs):
   wc_dir = sbox.wc_dir
 
-  filtered_output = filter_and_return_output(dumpfile, '--quiet', *dumpargs)
+  filtered_output, filtered_err = filter_and_return_output(dumpfile, 0,
+                                                           '--quiet',
+                                                           *dumpargs)
 
   # Setup our expectations
   load_and_verify_dumpstream(sbox, [], [], None, filtered_output,
@@ -203,7 +223,7 @@ def dumpfilter_with_targets(sbox):
   dumpfile_location = os.path.join(os.path.dirname(sys.argv[0]),
                                    'svndumpfilter_tests_data',
                                    'greek_tree.dump')
-  dumpfile = svntest.main.file_read(dumpfile_location)
+  dumpfile = open(dumpfile_location).read()
 
   (fd, targets_file) = tempfile.mkstemp(dir=svntest.main.temp_dir)
   try:
@@ -226,10 +246,348 @@ def dumpfilter_with_patterns(sbox):
   dumpfile_location = os.path.join(os.path.dirname(sys.argv[0]),
                                    'svndumpfilter_tests_data',
                                    'greek_tree.dump')
-  dumpfile = svntest.main.file_read(dumpfile_location)
+  dumpfile = open(dumpfile_location).read()
   _simple_dumpfilter_test(sbox, dumpfile,
                           'exclude', '--pattern', '/A/D/[GH]*', '/A/[B]/E*')
 
+#----------------------------------------------------------------------
+# More testing for issue #3020 'Reflect dropped/renumbered revisions in
+# svn:mergeinfo data during svnadmin load'
+#
+# Specifically, test that svndumpfilter, when used with the
+# --skip-missing-merge-sources option, removes mergeinfo that refers to
+# revisions that are older than the oldest revision in the dump stream.
+def filter_mergeinfo_revs_outside_of_dump_stream(sbox):
+  "filter mergeinfo revs outside of dump stream"
+
+  test_create(sbox)
+
+  # Load a partial dump into an existing repository.
+  #
+  # Picture == 1k words:
+  #
+  # The dump file we filter in this test, 'mergeinfo_included_partial.dump', is
+  # a dump of r6:HEAD of the following repos:
+  #
+  #                       __________________________________________
+  #                      |                                         |
+  #                      |             ____________________________|_____
+  #                      |            |                            |     |
+  # trunk---r2---r3-----r5---r6-------r8---r9--------------->      |     |
+  #   r1             |        |     |       |                      |     |
+  # intial           |        |     |       |______                |     |
+  # import         copy       |   copy             |            merge   merge
+  #                  |        |     |            merge           (r5)   (r8)
+  #                  |        |     |            (r9)              |     |
+  #                  |        |     |              |               |     |
+  #                  |        |     V              V               |     |
+  #                  |        | branches/B2-------r11---r12---->   |     |
+  #                  |        |     r7              |____|         |     |
+  #                  |        |                        |           |     |
+  #                  |      merge                      |___        |     |
+  #                  |      (r6)                           |       |     |
+  #                  |        |_________________           |       |     |
+  #                  |                          |        merge     |     |
+  #                  |                          |      (r11-12)    |     |
+  #                  |                          |          |       |     |
+  #                  V                          V          V       |     |
+  #              branches/B1-------------------r10--------r13-->   |     |
+  #                  r4                                            |     |
+  #                   |                                            V     V
+  #                  branches/B1/B/E------------------------------r14---r15->
+  #                  
+  #
+  # The mergeinfo on the complete repos would look like this:
+  #
+  #   Properties on 'branches/B1':
+  #     svn:mergeinfo
+  #       /branches/B2:11-12
+  #       /trunk:6,9
+  #   Properties on 'branches/B1/B/E':
+  #     svn:mergeinfo
+  #       /branches/B2/B/E:11-12
+  #       /trunk/B/E:5-6,8-9
+  #   Properties on 'branches/B2':
+  #     svn:mergeinfo
+  #       /trunk:9
+  #
+  # We will run the partial dump through svndumpfilter using the the
+  # --skip-missing-merge-soruces which should strip out any revisions < 6.
+  # Then we'll load the filtered result into an empty repository.  This
+  # should offset the incoming mergeinfo by -5.  In addition, any mergeinfo
+  # revisions that are adjusted to r1 should be removed because that implies
+  # a merge of -r0:1, which is impossible.  The resulting mergeinfo should
+  # look like this:
+  #
+  #   Properties on 'branches/B1':
+  #     svn:mergeinfo
+  #       /branches/B2:6-7
+  #       /trunk:4
+  #   Properties on 'branches/B1/B/E':
+  #     svn:mergeinfo
+  #       /branches/B2/B/E:6-7
+  #       /trunk/B/E:3-4
+  #   Properties on 'branches/B2':
+  #     svn:mergeinfo
+  #       /trunk:4
+  partial_dump = os.path.join(os.path.dirname(sys.argv[0]),
+                                   'svndumpfilter_tests_data',
+                                   'mergeinfo_included_partial.dump')
+  partial_dump_contents = open(partial_dump).read()
+  filtered_dumpfile2, filtered_out = filter_and_return_output(
+      partial_dump_contents,
+      8192, # Set a sufficiently large bufsize to avoid a deadlock
+      "include", "trunk", "branches",
+      "--skip-missing-merge-sources",
+      "--quiet")
+  load_and_verify_dumpstream(sbox, [], [], None, filtered_dumpfile2,
+                             '--ignore-uuid')
+  # Check the resulting mergeinfo.
+  url = sbox.repo_url + "/branches"
+  expected_output = svntest.verify.UnorderedOutput([
+    url + "/B1 - /branches/B2:6-7\n",
+    "/trunk:4\n",
+    url + "/B2 - /trunk:4\n",
+    url + "/B1/B/E - /branches/B2/B/E:6-7\n",
+    "/trunk/B/E:3-4\n"])
+  svntest.actions.run_and_verify_svn(None, expected_output, [],
+                                     'propget', 'svn:mergeinfo', '-R',
+                                     sbox.repo_url)
+
+  # Blow away the current repos, create an empty one in its place, and
+  # then load this skeleton repos into the empty target:
+  #
+  #   Projects/       (Added r1)
+  #     README        (Added r2)
+  #     Project-X     (Added r3)
+  #     Project-Y     (Added r4)
+  #     Project-Z     (Added r5)
+  #     docs/         (Added r6)
+  #       README      (Added r6).
+  test_create(sbox)
+  skeleton_dumpfile = open(os.path.join(os.path.dirname(sys.argv[0]),
+                                        'svnadmin_tests_data',
+                                        'skeleton_repos.dump')).read()
+  load_and_verify_dumpstream(sbox, [], [], None, skeleton_dumpfile,
+                             '--ignore-uuid')
+  partial_dump2 = os.path.join(os.path.dirname(sys.argv[0]),
+                                   'svndumpfilter_tests_data',
+                                   'mergeinfo_included_partial.dump')
+  partial_dump_contents2 = open(partial_dump2).read()
+  # Now use the partial dump file we used above, but this time exclude
+  # the B2 branch.  Load the filtered dump into the /Projects/Project-X
+  # subtree of the skeleton repos.
+  filtered_dumpfile2, filtered_err = filter_and_return_output(
+      partial_dump_contents2,
+      8192, # Set a sufficiently large bufsize to avoid a deadlock
+      "exclude", "branches/B2",
+      "--skip-missing-merge-sources",
+      "--drop-empty-revs",
+      "--renumber-revs")
+
+  # Starting with the same expectation we had when loading into an empty
+  # repository, adjust each revision by +6 to account for the six revision
+  # already present in the target repos, that gives:
+  #
+  #   Properties on 'branches/B1':
+  #     svn:mergeinfo
+  #       /branches/B2:12-13
+  #       /trunk:10
+  #   Properties on 'branches/B1/B/E':
+  #     svn:mergeinfo
+  #       /branches/B2/B/E:12-13
+  #       /trunk/B/E:9-10
+  #   Properties on 'branches/B2':
+  #     svn:mergeinfo
+  #       /trunk:10
+  #
+  # ...But /branches/B2 has been filtered out, so all references to
+  # that branch should be gone, leaving:
+  # 
+  #   Properties on 'branches/B1':
+  #     svn:mergeinfo
+  #       /trunk:10
+  #   Properties on 'branches/B1/B/E':
+  #     svn:mergeinfo
+  #       /trunk/B/E:9-10
+  #
+  # ...But wait, there's more!  Because we use the '--drop-empty-revs'
+  # option, when filtering out 'branches/B2' all the revisions that effect
+  # only that branch should be dropped (i.e. original revs r7, r11, and r12).
+  # In and of itself that has no effect, but we also specifiy the
+  # '--renumber-revs' option, so when r7 is dropped, r8 should map to r7,
+  # r9 to r8, and r10 to r9 (and so on).  That should finally leave us with:
+  #
+  #   Properties on 'branches/B1':
+  #     svn:mergeinfo
+  #       /trunk:9
+  #   Properties on 'branches/B1/B/E':
+  #     svn:mergeinfo
+  #       /trunk/B/E:8-9
+  #
+  # This test currently fails with this mergeinfo:
+  #
+  # 
+  #
+  #
+  # Check that all the blather above really happens.  First does
+  # svndumpfilter report what we expect to stderr?
+  expected_err = [
+      "Excluding (and dropping empty revisions for) prefix patterns:\n",
+      "   '/branches/B2'\n",
+      "\n",
+      "Revision 6 committed as 6.\n",
+      "Revision 7 skipped.\n",        # <-- DROP!
+      "Revision 8 committed as 7.\n",
+      "Revision 9 committed as 8.\n",
+      "Revision 10 committed as 9.\n",
+      "Revision 11 skipped.\n",       # <-- DROP!
+      "Revision 12 skipped.\n",       # <-- DROP!
+      "Revision 13 committed as 10.\n",
+      "Revision 14 committed as 11.\n",
+      "Revision 15 committed as 12.\n",
+      "\n",
+      "Dropped 3 revisions.\n",
+      "\n",
+      "Revisions renumbered as follows:\n",
+      "   15 => 12\n",
+      "   14 => 11\n",
+      "   13 => 10\n",
+      "   12 => (dropped)\n", # <-- DROP!
+      "   11 => (dropped)\n", # <-- DROP!
+      "   10 => 9\n",
+      "   9 => 8\n",
+      "   8 => 7\n",
+      "   7 => (dropped)\n",  # <-- DROP!
+      "   6 => 6\n",
+      "\n",
+      "Dropped 2 nodes:\n",
+      "   '/branches/B2'\n",
+      "   '/branches/B2/D/H/chi'\n",
+      "\n"]
+  svntest.verify.verify_outputs(
+      "Actual svndumpfilter stderr does not agree with expected stderr",
+      None, filtered_err, None, expected_err)
+
+  # Now actually load the filtered dump into the skeleton repository
+  # and then check the resulting mergeinfo.
+  load_and_verify_dumpstream(sbox, [], [], None, filtered_dumpfile2,
+                             '--parent-dir', '/Projects/Project-X',
+                             '--ignore-uuid')
+
+  url = sbox.repo_url + "/Projects/Project-X/branches"
+  expected_output = svntest.verify.UnorderedOutput([
+    url + "/B1 - /Projects/Project-X/trunk:9\n",
+    url + "/B1/B/E - /Projects/Project-X/trunk/B/E:8-9\n"])
+  svntest.actions.run_and_verify_svn(None, expected_output, [],
+                                     'propget', 'svn:mergeinfo', '-R',
+                                     sbox.repo_url)
+
+#----------------------------------------------------------------------
+# More testing for issue #3020 'Reflect dropped/renumbered revisions in
+# svn:mergeinfo data during svnadmin load'
+#
+# Using svndumpfilter with the --drop-empty-revs option, but without the
+# --renumber-revs option, can create a dump with non-contiguous revisions.
+# Such dumps should not interfere with the correct remapping of mergeinfo
+# source revisions.
+def dropped_but_not_renumbered_empty_revs(sbox):
+  "mergeinfo maps correctly when dropping revs"
+
+  test_create(sbox)
+
+  # The dump file mergeinfo_included_full.dump represents this repository:
+  # 
+  #
+  #                       __________________________________________
+  #                      |                                         |
+  #                      |             ____________________________|_____
+  #                      |            |                            |     |
+  # trunk---r2---r3-----r5---r6-------r8---r9--------------->      |     |
+  #   r1             |        |     |       |                      |     |
+  # intial           |        |     |       |______                |     |
+  # import         copy       |   copy             |            merge   merge
+  #                  |        |     |            merge           (r5)   (r8)
+  #                  |        |     |            (r9)              |     |
+  #                  |        |     |              |               |     |
+  #                  |        |     V              V               |     |
+  #                  |        | branches/B2-------r11---r12---->   |     |
+  #                  |        |     r7              |____|         |     |
+  #                  |        |                        |           |     |
+  #                  |      merge                      |___        |     |
+  #                  |      (r6)                           |       |     |
+  #                  |        |_________________           |       |     |
+  #                  |                          |        merge     |     |
+  #                  |                          |      (r11-12)    |     |
+  #                  |                          |          |       |     |
+  #                  V                          V          V       |     |
+  #              branches/B1-------------------r10--------r13-->   |     |
+  #                  r4                                            |     |
+  #                   |                                            V     V
+  #                  branches/B1/B/E------------------------------r14---r15->
+  #                  
+  #
+  # The mergeinfo on mergeinfo_included_full.dump is:
+  #
+  #   Properties on 'branches/B1':
+  #     svn:mergeinfo
+  #       /branches/B2:11-12
+  #       /trunk:6,9
+  #   Properties on 'branches/B1/B/E':
+  #     svn:mergeinfo
+  #       /branches/B2/B/E:11-12
+  #       /trunk/B/E:5-6,8-9
+  #   Properties on 'branches/B2':
+  #     svn:mergeinfo
+  #       /trunk:9
+  #
+  # Use svndumpfilter to filter mergeinfo_included_full.dump, excluding
+  # branches/B2, while dropping, but not renumbering, empty revisions.
+  #
+  # Load the filtered dump into an empty repository.  Since we are excluding
+  # /branches/B2 and dropping empty revs, revisions 7, 11, and 12 won't be
+  # included in the filtered dump.
+  full_dump = os.path.join(os.path.dirname(sys.argv[0]),
+                                   'svnadmin_tests_data',
+                                   'mergeinfo_included_full.dump')
+  full_dump_contents = open(full_dump).read()
+  filtered_dumpfile, filtered_out = filter_and_return_output(
+      full_dump_contents,
+      8192, # Set a sufficiently large bufsize to avoid a deadlock
+      "exclude", "branches/B2",
+      "--skip-missing-merge-sources", "--drop-empty-revs")
+
+  # Now load the filtered dump into an empty repository.
+  load_and_verify_dumpstream(sbox, [], [], None, filtered_dumpfile,
+                             '--ignore-uuid')
+
+  # The mergeinfo in the newly loaded repos should have no references to the
+  # dropped branch and the remaining merge source revs should be remapped to
+  # reflect the fact that the loaded repository no longer has any empty
+  # revisions:
+  #
+  #   Properties on 'branches/B1':
+  #     svn:mergeinfo
+  #       /trunk:6,8
+  #                ^
+  #       With r7 dropped, r9 in the incoming
+  #       dump becomes r8 in the loaded repos.
+  #
+  #   Properties on 'branches/B1/B/E':
+  #     svn:mergeinfo
+  #       /trunk/B/E:5-8
+  #                    ^
+  #       With r7 dropped, r8 and r9 in the incoming
+  #       dump becomes r7 and r8 in the loaded repos.
+ 
+  # Check the resulting mergeinfo.
+  url = sbox.repo_url + "/branches"
+  expected_output = svntest.verify.UnorderedOutput([
+    url + "/B1 - /trunk:6,8\n",
+    url + "/B1/B/E - /trunk/B/E:5-8\n"])
+  svntest.actions.run_and_verify_svn(None, expected_output, [],
+                                     'propget', 'svn:mergeinfo', '-R',
+                                     sbox.repo_url)
 
 ########################################################################
 # Run the tests
@@ -241,6 +599,8 @@ test_list = [ None,
               svndumpfilter_loses_mergeinfo,
               dumpfilter_with_targets,
               dumpfilter_with_patterns,
+              filter_mergeinfo_revs_outside_of_dump_stream,
+              dropped_but_not_renumbered_empty_revs,
               ]
 
 if __name__ == '__main__':

Modified: subversion/branches/ignore-mergeinfo/subversion/tests/cmdline/svndumpfilter_tests_data/with_merges.dump
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/tests/cmdline/svndumpfilter_tests_data/with_merges.dump?rev=984206&r1=984205&r2=984206&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/tests/cmdline/svndumpfilter_tests_data/with_merges.dump (original)
+++ subversion/branches/ignore-mergeinfo/subversion/tests/cmdline/svndumpfilter_tests_data/with_merges.dump Tue Aug 10 20:55:56 2010
@@ -140,13 +140,9 @@ Node-kind: dir
 Node-action: add
 Node-copyfrom-rev: 2
 Node-copyfrom-path: trunk
-Prop-content-length: 45
-Content-length: 45
+Prop-content-length: 10
+Content-length: 10
 
-K 13
-svn:mergeinfo
-V 10
-/trunk:1-2
 PROPS-END
 
 
@@ -173,13 +169,9 @@ Node-kind: dir
 Node-action: add
 Node-copyfrom-rev: 3
 Node-copyfrom-path: trunk
-Prop-content-length: 45
-Content-length: 45
+Prop-content-length: 10
+Content-length: 10
 
-K 13
-svn:mergeinfo
-V 10
-/trunk:1-3
 PROPS-END
 
 

Modified: subversion/branches/ignore-mergeinfo/subversion/tests/cmdline/svnlook_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/tests/cmdline/svnlook_tests.py?rev=984206&r1=984205&r2=984206&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/tests/cmdline/svnlook_tests.py (original)
+++ subversion/branches/ignore-mergeinfo/subversion/tests/cmdline/svnlook_tests.py Tue Aug 10 20:55:56 2010
@@ -92,7 +92,7 @@ def test_misc(sbox):
 
   # give the repo a new UUID
   uuid = "01234567-89ab-cdef-89ab-cdef01234567"
-  svntest.main.run_command_stdin(svntest.main.svnadmin_binary, None, 1,
+  svntest.main.run_command_stdin(svntest.main.svnadmin_binary, None, 0, 1,
                            ["SVN-fs-dump-format-version: 2\n",
                             "\n",
                             "UUID: ", uuid, "\n",

Modified: subversion/branches/ignore-mergeinfo/subversion/tests/cmdline/svnsync_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/tests/cmdline/svnsync_tests.py?rev=984206&r1=984205&r2=984206&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/tests/cmdline/svnsync_tests.py (original)
+++ subversion/branches/ignore-mergeinfo/subversion/tests/cmdline/svnsync_tests.py Tue Aug 10 20:55:56 2010
@@ -39,7 +39,7 @@ Skip = svntest.testcase.Skip
 SkipUnless = svntest.testcase.SkipUnless
 XFail = svntest.testcase.XFail
 Item = svntest.wc.StateItem
-
+Wimp = svntest.testcase.Wimp
 
 ######################################################################
 # Helper routines
@@ -55,12 +55,18 @@ def build_repos(sbox):
   svntest.main.create_repos(sbox.repo_dir)
 
 
-def run_sync(url, expected_error=None):
+def run_sync(url, source_url=None, expected_error=None):
   "Synchronize the mirror repository with the master"
-  exit_code, output, errput = svntest.main.run_svnsync(
-    "synchronize", url,
-    "--username", svntest.main.wc_author,
-    "--password", svntest.main.wc_passwd)
+  if source_url is not None:
+    exit_code, output, errput = svntest.main.run_svnsync(
+      "synchronize", url, source_url,
+      "--username", svntest.main.wc_author,
+      "--password", svntest.main.wc_passwd)
+  else: # Allow testing of old source-URL-less syntax
+    exit_code, output, errput = svntest.main.run_svnsync(
+      "synchronize", url,
+      "--username", svntest.main.wc_author,
+      "--password", svntest.main.wc_passwd)
   if errput:
     if expected_error is None:
       raise SVNUnexpectedStderr(errput)
@@ -75,10 +81,10 @@ def run_sync(url, expected_error=None):
     # should be: ['Committed revision 1.\n', 'Committed revision 2.\n']
     raise SVNUnexpectedStdout("Missing stdout")
 
-def run_copy_revprops(url, expected_error=None):
+def run_copy_revprops(url, source_url, expected_error=None):
   "Copy revprops to the mirror repository from the master"
   exit_code, output, errput = svntest.main.run_svnsync(
-    "copy-revprops", url,
+    "copy-revprops", url, source_url,
     "--username", svntest.main.wc_author,
     "--password", svntest.main.wc_passwd)
   if errput:
@@ -164,8 +170,8 @@ or another dump file."""
     repo_url = repo_url + subdir
   run_init(dest_sbox.repo_url, repo_url)
 
-  run_sync(dest_sbox.repo_url)
-  run_copy_revprops(dest_sbox.repo_url)
+  run_sync(dest_sbox.repo_url, repo_url)
+  run_copy_revprops(dest_sbox.repo_url, repo_url)
 
   # Remove some SVNSync-specific housekeeping properties from the
   # mirror repository in preparation for the comparison dump.
@@ -308,7 +314,7 @@ def detect_meddling(sbox):
                                      '-m', 'msg',
                                      dest_sbox.wc_dir)
 
-  run_sync(dest_sbox.repo_url,
+  run_sync(dest_sbox.repo_url, None,
            ".*Destination HEAD \\(2\\) is not the last merged revision \\(1\\).*")
 
 #----------------------------------------------------------------------
@@ -791,8 +797,9 @@ test_list = [ None,
               detect_meddling,
               Skip(basic_authz, svntest.main.is_ra_type_file),
               Skip(copy_from_unreadable_dir, svntest.main.is_ra_type_file),
-              Skip(copy_with_mod_from_unreadable_dir,
-                   svntest.main.is_ra_type_file),
+              Wimp("Needs local add below copy support in WC-NG",
+                   Skip(copy_with_mod_from_unreadable_dir,
+                        svntest.main.is_ra_type_file)),
               Skip(copy_with_mod_from_unreadable_dir_and_copy,
                    svntest.main.is_ra_type_file),
               url_encoding,

Modified: subversion/branches/ignore-mergeinfo/subversion/tests/cmdline/svntest/actions.py
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/tests/cmdline/svntest/actions.py?rev=984206&r1=984205&r2=984206&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/tests/cmdline/svntest/actions.py (original)
+++ subversion/branches/ignore-mergeinfo/subversion/tests/cmdline/svntest/actions.py Tue Aug 10 20:55:56 2010
@@ -269,7 +269,7 @@ def run_and_verify_load(repo_dir, dump_f
     raise TypeError("dump_file_content argument should have list type")
   expected_stderr = []
   exit_code, output, errput = main.run_command_stdin(
-    main.svnadmin_binary, expected_stderr, 1, dump_file_content,
+    main.svnadmin_binary, expected_stderr, 0, 1, dump_file_content,
     'load', '--force-uuid', '--quiet', repo_dir)
 
   verify.verify_outputs("Unexpected stderr output", None, errput,
@@ -287,7 +287,7 @@ def run_and_verify_dump(repo_dir):
 def load_repo(sbox, dumpfile_path = None, dump_str = None):
   "Loads the dumpfile into sbox"
   if not dump_str:
-    dump_str = main.file_read(dumpfile_path, "rb")
+    dump_str = open(dumpfile_path, "rb").read()
 
   # Create a virgin repos and working copy
   main.safe_rmtree(sbox.repo_dir, 1)

Modified: subversion/branches/ignore-mergeinfo/subversion/tests/cmdline/svntest/factory.py
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/tests/cmdline/svntest/factory.py?rev=984206&r1=984205&r2=984206&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/tests/cmdline/svntest/factory.py (original)
+++ subversion/branches/ignore-mergeinfo/subversion/tests/cmdline/svntest/factory.py Tue Aug 10 20:55:56 2010
@@ -531,10 +531,16 @@ class TestFactory:
         py += '# SKIPPING NON-WC ' + target.runarg + '\n'
         continue
 
-      pystatus = self.get_current_status(target.wc)
-      py += (pystatus +
-             "actions.run_and_verify_status(" + target.wc.py +
-             ", expected_status)\n")
+      if '-q' in status_args:
+        pystatus = self.get_current_status(target.wc, True)
+        py += (pystatus +
+               "actions.run_and_verify_status(" + target.wc.py +
+               ", expected_status)\n")
+      else:
+        pystatus = self.get_current_status(target.wc, False)
+        py += (pystatus +
+               "actions.run_and_verify_unquiet_status(" + target.wc.py +
+               ", expected_status)\n")
     return py
 
 
@@ -933,10 +939,14 @@ class TestFactory:
     self.prev_disk = [wc.realpath, actual]
 
 
-  def get_current_status(self, wc):
+  def get_current_status(self, wc, quiet=True):
     "Probes the given working copy and writes an expected_status for it."
-    code, output, err = main.run_svn(None, 'status', '-v', '-u', '-q',
-                                     wc.realpath)
+    if quiet:
+      code, output, err = main.run_svn(None, 'status', '-v', '-u', '-q',
+                                       wc.realpath)
+    else:
+      code, output, err = main.run_svn(None, 'status', '-v', '-u',
+                                       wc.realpath)
     if code != 0 or len(err) > 0:
       raise Failure("Hmm. `svn status' failed. What now.")
 

Modified: subversion/branches/ignore-mergeinfo/subversion/tests/cmdline/svntest/main.py
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/tests/cmdline/svntest/main.py?rev=984206&r1=984205&r2=984206&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/tests/cmdline/svntest/main.py (original)
+++ subversion/branches/ignore-mergeinfo/subversion/tests/cmdline/svntest/main.py Tue Aug 10 20:55:56 2010
@@ -137,7 +137,10 @@ def pathname2url(path):
   """Convert the pathname PATH from the local syntax for a path to the form
   used in the path component of a URL. This does not produce a complete URL.
   The return value will already be quoted using the quote() function."""
-  return urllib_parse_quote(path.replace('\\', '/'))
+
+  # Don't leave ':' in file://C%3A/ escaped as our canonicalization
+  # rules will replace this with a ':' on input.
+  return urllib_parse_quote(path.replace('\\', '/')).replace('%3A', ':')
 
 # This function mimics the Python 2.3 urllib function of the same name.
 def url2pathname(path):
@@ -184,9 +187,8 @@ enable_sasl = False
 use_jsvn = False
 
 # Global variable indicating which DAV library to use if both are available
-# ('neon', 'serf'). The default is neon for backward compatibility of the
-# test suite.
-preferred_http_library = 'neon'
+# ('neon', 'serf').
+preferred_http_library = 'serf'
 
 # Global variable: Number of shards to use in FSFS
 # 'None' means "use FSFS's default"
@@ -362,7 +364,7 @@ def run_command(command, error_expected,
   as lists of lines (including line terminators).  See run_command_stdin()
   for details.  If ERROR_EXPECTED is None, any stderr also will be printed."""
 
-  return run_command_stdin(command, error_expected, binary_mode,
+  return run_command_stdin(command, error_expected, 0, binary_mode,
                            None, *varargs)
 
 # A regular expression that matches arguments that are trivially safe
@@ -391,9 +393,10 @@ def _quote_arg(arg):
       arg = arg.replace('$', '\$')
     return '"%s"' % (arg,)
 
-def open_pipe(command, stdin=None, stdout=None, stderr=None):
+def open_pipe(command, bufsize=0, stdin=None, stdout=None, stderr=None):
   """Opens a subprocess.Popen pipe to COMMAND using STDIN,
-  STDOUT, and STDERR.
+  STDOUT, and STDERR.  BUFSIZE is passed to subprocess.Popen's
+  argument of the same name.
 
   Returns (infile, outfile, errfile, waiter); waiter
   should be passed to wait_on_pipe."""
@@ -422,6 +425,7 @@ def open_pipe(command, stdin=None, stdou
     stderr = subprocess.PIPE
 
   p = subprocess.Popen(command,
+                       bufsize,
                        stdin=stdin,
                        stdout=stdout,
                        stderr=stderr,
@@ -475,8 +479,14 @@ def wait_on_pipe(waiter, binary_mode, st
                        % (command_string, exit_code))
     return stdout_lines, stderr_lines, exit_code
 
-def spawn_process(command, binary_mode=0, stdin_lines=None, *varargs):
+def spawn_process(command, bufsize=0, binary_mode=0, stdin_lines=None,
+                  *varargs):
   """Run any binary, supplying input text, logging the command line.
+  BUFSIZE dictates the pipe buffer size used in communication with the
+  subprocess: 0 means unbuffered, 1 means line buffered, any other
+  positive value means use a buffer of (approximately) that size.
+  A negative bufsize means to use the system default, which usually
+  means fully buffered. The default value for bufsize is 0 (unbuffered).
   Normalize Windows line endings of stdout and stderr if not BINARY_MODE.
   Return exit code as int; stdout, stderr as lists of lines (including
   line terminators)."""
@@ -489,7 +499,7 @@ def spawn_process(command, binary_mode=0
                                       ' '.join([_quote_arg(x) for x in varargs])))
     sys.stdout.flush()
 
-  infile, outfile, errfile, kid = open_pipe([command] + list(varargs))
+  infile, outfile, errfile, kid = open_pipe([command] + list(varargs), bufsize)
 
   if stdin_lines:
     for x in stdin_lines:
@@ -503,13 +513,15 @@ def spawn_process(command, binary_mode=0
 
   return exit_code, stdout_lines, stderr_lines
 
-def run_command_stdin(command, error_expected, binary_mode=0,
+def run_command_stdin(command, error_expected, bufsize=0, binary_mode=0,
                       stdin_lines=None, *varargs):
   """Run COMMAND with VARARGS; input STDIN_LINES (a list of strings
   which should include newline characters) to program via stdin - this
   should not be very large, as if the program outputs more than the OS
   is willing to buffer, this will deadlock, with both Python and
-  COMMAND waiting to write to each other for ever.
+  COMMAND waiting to write to each other for ever.  For tests where this
+  is a problem, setting BUFSIZE to a sufficiently large value will prevent
+  the deadlock, see spawn_process().
   Normalize Windows line endings of stdout and stderr if not BINARY_MODE.
   Return exit code as int; stdout, stderr as lists of lines (including
   line terminators).
@@ -519,6 +531,7 @@ def run_command_stdin(command, error_exp
     start = time.time()
 
   exit_code, stdout_lines, stderr_lines = spawn_process(command,
+                                                        bufsize,
                                                         binary_mode,
                                                         stdin_lines,
                                                         *varargs)
@@ -631,7 +644,7 @@ def run_entriesdump(path):
   # use spawn_process rather than run_command to avoid copying all the data
   # to stdout in verbose mode.
   exit_code, stdout_lines, stderr_lines = spawn_process(entriesdump_binary,
-                                                        0, None, path)
+                                                        0, 0, None, path)
   if verbose_mode:
     ### finish the CMD output
     print
@@ -693,25 +706,11 @@ def file_write(path, contents, mode='w')
   which is (w)rite by default."""
   open(path, mode).write(contents)
 
-# For reading the contents of a file
-def file_read(path, mode = 'r'):
-  """Return the contents of the file at PATH, opening file using MODE,
-  which is (r)ead by default."""
-  fp = open(path, mode)
-  contents = fp.read()
-  fp.close()
-  return contents
-
 # For replacing parts of contents in an existing file, with new content.
 def file_substitute(path, contents, new_contents):
   """Replace the CONTENTS in the file at PATH using the NEW_CONTENTS"""
-  fp = open(path, 'r')
-  fcontent = fp.read()
-  fp.close()
-  fcontent = fcontent.replace(contents, new_contents)
-  fp = open(path, 'w')
-  fp.write(fcontent)
-  fp.close()
+  fcontent = open(path, 'r').read().replace(contents, new_contents)
+  open(path, 'w').write(fcontent)
 
 # For creating blank new repositories
 def create_repos(path):
@@ -726,6 +725,8 @@ def create_repos(path):
     opts += ("--pre-1.5-compatible",)
   elif server_minor_version < 6:
     opts += ("--pre-1.6-compatible",)
+  elif server_minor_version < 7:
+    opts += ("--pre-1.7-compatible",)
   if fs_type is not None:
     opts += ("--fs-type=" + fs_type,)
   exit_code, stdout, stderr = run_command(svnadmin_binary, 1, 0, "create",
@@ -768,7 +769,7 @@ def create_repos(path):
 
       # read it
       format_file_path = get_fsfs_format_file_path(path)
-      contents = file_read(format_file_path, 'rb')
+      contents = open(format_file_path, 'rb').read()
 
       # tweak it
       new_contents = "".join([transform_line(line) + "\n"
@@ -801,9 +802,12 @@ def create_repos(path):
 def copy_repos(src_path, dst_path, head_revision, ignore_uuid = 1):
   "Copy the repository SRC_PATH, with head revision HEAD_REVISION, to DST_PATH"
 
+  # Save any previous value of SVN_DBG_QUIET
+  saved_quiet = os.environ.get('SVN_DBG_QUIET')
+  os.environ['SVN_DBG_QUIET'] = 'y'
+
   # Do an svnadmin dump|svnadmin load cycle. Print a fake pipe command so that
   # the displayed CMDs can be run by hand
-  os.environ['SVN_DBG_QUIET'] = 'y'
   create_repos(dst_path)
   dump_args = ['dump', src_path]
   load_args = ['load', dst_path]
@@ -837,7 +841,10 @@ def copy_repos(src_path, dst_path, head_
   load_out.close()
   load_err.close()
 
-  del os.environ['SVN_DBG_QUIET']
+  if saved_quiet is None:
+    del os.environ['SVN_DBG_QUIET']
+  else:
+    os.environ['SVN_DBG_QUIET'] = saved_quiet
 
   dump_re = re.compile(r'^\* Dumped revision (\d+)\.\r?$')
   expect_revision = 0
@@ -876,7 +883,7 @@ def canonicalize_url(input):
     return input
 
 
-def create_python_hook_script (hook_path, hook_script_code):
+def create_python_hook_script(hook_path, hook_script_code):
   """Create a Python hook script at HOOK_PATH with the specified
      HOOK_SCRIPT_CODE."""
 
@@ -884,14 +891,14 @@ def create_python_hook_script (hook_path
     # Use an absolute path since the working directory is not guaranteed
     hook_path = os.path.abspath(hook_path)
     # Fill the python file.
-    file_write ("%s.py" % hook_path, hook_script_code)
+    file_write("%s.py" % hook_path, hook_script_code)
     # Fill the batch wrapper file.
-    file_append ("%s.bat" % hook_path,
-                 "@\"%s\" %s.py %%*\n" % (sys.executable, hook_path))
+    file_append("%s.bat" % hook_path,
+                "@\"%s\" %s.py %%*\n" % (sys.executable, hook_path))
   else:
     # For all other platforms
-    file_write (hook_path, "#!%s\n%s" % (sys.executable, hook_script_code))
-    os.chmod (hook_path, 0755)
+    file_write(hook_path, "#!%s\n%s" % (sys.executable, hook_script_code))
+    os.chmod(hook_path, 0755)
 
 def write_restrictive_svnserve_conf(repo_dir, anon_access="none"):
   "Create a restrictive authz file ( no anynomous access )."
@@ -993,6 +1000,34 @@ def merge_notify_line(revstart=None, rev
              % (from_foreign_phrase, revstart, revend)
 
 
+def make_log_msg():
+  "Conjure up a log message based on the calling test."
+
+  for idx in range(1, 100):
+    frame = sys._getframe(idx)
+
+    # If this frame isn't from a function in *_tests.py, then skip it.
+    filename = frame.f_code.co_filename
+    if not filename.endswith('_tests.py'):
+      continue
+
+    # There should be a test_list in this module.
+    test_list = frame.f_globals.get('test_list')
+    if test_list is None:
+      continue
+
+    # If the function is not in the test_list, then skip it.
+    func_name = frame.f_code.co_name
+    func_ob = frame.f_globals.get(func_name)
+    if func_ob not in test_list:
+      continue
+
+    # Make the log message look like a line from a traceback.
+    # Well...close. We use single quotes to avoid interfering with the
+    # double-quote quoting performed on Windows
+    return "File '%s', line %d, in %s" % (filename, frame.f_lineno, func_name)
+
+
 ######################################################################
 # Functions which check the test configuration
 # (useful for conditional XFails)
@@ -1118,7 +1153,8 @@ class TestSpawningThread(threading.Threa
     if server_minor_version:
       args.append('--server-minor-version=' + str(server_minor_version))
 
-    result, stdout_lines, stderr_lines = spawn_process(command, 0, None, *args)
+    result, stdout_lines, stderr_lines = spawn_process(command, 0, 0, None,
+                                                       *args)
     self.results.append((index, result, stdout_lines, stderr_lines))
 
     if result != 1:
@@ -1345,8 +1381,8 @@ def usage():
         "                 output and ignores all exceptions in the \n"
         "                 run_and_verify* functions. This option is only \n"
         "                 useful during test development!")
-  print(" --server-minor-version  Set the minor version for the server.\n"
-        "                 Supports version 4 or 5.")
+  print(" --server-minor-version  Set the minor version for the server ('4',\n"
+        "                 '5', or '6').")
   print(" --fsfs-sharding Default shard size (for fsfs)\n"
         " --fsfs-packing  Run 'svnadmin pack' automatically")
   print(" --config-file   Configuration file for tests.")
@@ -1584,11 +1620,12 @@ def run_tests(test_list, serial_only = F
   if serial_only or len(testnums) < 2:
     parallel = 0
 
-  # Build out the default configuration directory
-  create_config_dir(default_config_dir)
+  if not is_child_process:
+    # Build out the default configuration directory
+    create_config_dir(default_config_dir)
 
-  # Setup the pristine repository
-  svntest.actions.setup_pristine_repository()
+    # Setup the pristine repository
+    svntest.actions.setup_pristine_repository()
 
   # Run the tests.
   exit_code = _internal_run_tests(test_list, testnums, parallel)

Modified: subversion/branches/ignore-mergeinfo/subversion/tests/cmdline/svntest/objects.py
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/tests/cmdline/svntest/objects.py?rev=984206&r1=984205&r2=984206&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/tests/cmdline/svntest/objects.py (original)
+++ subversion/branches/ignore-mergeinfo/subversion/tests/cmdline/svntest/objects.py Tue Aug 10 20:55:56 2010
@@ -149,7 +149,6 @@ class SvnRepository:
     """Dump the repository into the directory OUTPUT_DIR"""
     ldir = local_path(output_dir)
     os.mkdir(ldir)
-    print "## SvnRepository::dump(rep_dir=" + self.repo_absdir + ")"
 
     """Run a BDB dump on the repository"""
     if self.db_dump_name != 'none':
@@ -322,7 +321,6 @@ class SvnWC:
                                'commit', '-m', log, lpath)
     actions.run_and_verify_update(lpath, None, None, None)
     self.repo.head_rev += 1
-    print "## head-rev == " + str(self.repo.head_rev)
     return self.repo.head_rev
 
   def svn_update(self, rpath='', rev='HEAD'):

Modified: subversion/branches/ignore-mergeinfo/subversion/tests/cmdline/svntest/sandbox.py
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/tests/cmdline/svntest/sandbox.py?rev=984206&r1=984205&r2=984206&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/tests/cmdline/svntest/sandbox.py (original)
+++ subversion/branches/ignore-mergeinfo/subversion/tests/cmdline/svntest/sandbox.py Tue Aug 10 20:55:56 2010
@@ -147,6 +147,58 @@ class Sandbox:
     "Returns True when build() has been called on this instance."
     return self._is_built
 
+  def ospath(self, relpath, wc_dir=None):
+    if wc_dir is None:
+      wc_dir = self.wc_dir
+    return os.path.join(wc_dir, svntest.wc.to_ospath(relpath))
+
+  def simple_commit(self, target=None):
+    assert not self.read_only
+    if target is None:
+      target = self.wc_dir
+    svntest.main.run_svn(False, 'commit',
+                         '-m', svntest.main.make_log_msg(),
+                         target)
+
+  def simple_rm(self, *targets):
+    assert len(targets) > 0
+    if len(targets) == 1 and is_url(targets[0]):
+      assert not self.read_only
+      targets = ('-m', svntests.main.make_log_msg(), targets[0])
+    svntest.main.run_svn(False, 'rm', *targets)
+
+  def simple_mkdir(self, *targets):
+    assert len(targets) > 0
+    if len(targets) == 1 and is_url(targets[0]):
+      assert not self.read_only
+      targets = ('-m', svntests.main.make_log_msg(), targets[0])
+    svntest.main.run_svn(False, 'mkdir', *targets)
+
+  def simple_add(self, *targets):
+    assert len(targets) > 0
+    svntest.main.run_svn(False, 'add', *targets)
+
+  def simple_revert(self, *targets):
+    assert len(targets) > 0
+    svntest.main.run_svn(False, 'revert', *targets)
+
+  def simple_propset(self, name, value, *targets):
+    assert len(targets) > 0
+    svntest.main.run_svn(False, 'propset', name, value, *targets)
+
+  def simple_propdel(self, name, *targets):
+    assert len(targets) > 0
+    svntest.main.run_svn(False, 'propdel', name, *targets)
+
+
+def is_url(target):
+  return (target.startswith('^/')
+          or target.startswith('file://')
+          or target.startswith('http://')
+          or target.startswith('https://')
+          or target.startswith('svn://')
+          or target.startswith('svn+ssh://'))
+
 
 _deferred_test_paths = []
 

Modified: subversion/branches/ignore-mergeinfo/subversion/tests/cmdline/svntest/wc.py
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/tests/cmdline/svntest/wc.py?rev=984206&r1=984205&r2=984206&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/tests/cmdline/svntest/wc.py (original)
+++ subversion/branches/ignore-mergeinfo/subversion/tests/cmdline/svntest/wc.py Tue Aug 10 20:55:56 2010
@@ -73,7 +73,7 @@ import svntest
 # Working revision, last-changed revision, and last author are whitespace
 # only if the item is missing.
 #
-_re_parse_status = re.compile('^([?!MACDRUG_ ][MACDRUG_ ])'
+_re_parse_status = re.compile('^([?!MACDRUGI_~ ][MACDRUG_ ])'
                               '([L ])'
                               '([+ ])'
                               '([SX ])'
@@ -272,7 +272,7 @@ class State:
     between the two states. LABEL will be used in the display. SELF is the
     "expected" state, and OTHER is the "actual" state.
 
-    If any changes are detected/diplayed, then SVNTreeUnequal is raised.
+    If any changes are detected/displayed, then SVNTreeUnequal is raised.
     """
     norm_self = self.normalize()
     norm_other = other.normalize()
@@ -312,11 +312,17 @@ class State:
         else:
           # when reading the entry structures, we don't examine for text or
           # property mods, so clear those flags. we also do not examine the
-          # filesystem, so we cannot detect missing files.
-          if item.status[0] in 'M!':
+          # filesystem, so we cannot detect missing or obstructed files.
+          if item.status[0] in 'M!~':
             item.status = ' ' + item.status[1]
           if item.status[1] == 'M':
             item.status = item.status[0] + ' '
+          # under wc-ng terms, we may report a different revision than the
+          # backwards-compatible code should report. if there is a special
+          # value for compatibility, then use it.
+          if item.entry_rev is not None:
+            item.wc_rev = item.entry_rev
+            item.entry_rev = None
       if item.writelocked:
         # we don't contact the repository, so our only information is what
         # is in the working copy. 'K' means we have one and it matches the
@@ -615,7 +621,7 @@ class StateItem:
   """
 
   def __init__(self, contents=None, props=None,
-               status=None, verb=None, wc_rev=None,
+               status=None, verb=None, wc_rev=None, entry_rev=None,
                locked=None, copied=None, switched=None, writelocked=None,
                treeconflict=None):
     # provide an empty prop dict if it wasn't provided
@@ -638,6 +644,9 @@ class StateItem:
     self.verb = verb
     # The base revision number of the node in the WC, as a string.
     self.wc_rev = wc_rev
+    # This one will be set when we expect the wc_rev to differ from the one
+    # found ni the entries code.
+    self.entry_rev = entry_rev
     # For the following attributes, the value is the status character of that
     # field from 'svn status', except using value None instead of status ' '.
     self.locked = locked
@@ -806,6 +815,16 @@ def svn_url_quote(url):
 
 
 # ------------
+
+def text_base_path(file_path):
+  """Return the path to the text-base file for the versioned file
+     FILE_PATH."""
+  dot_svn = svntest.main.get_admin_name()
+  return os.path.join(os.path.dirname(file_path), dot_svn, 'text-base',
+                      os.path.basename(file_path) + '.svn-base')
+
+
+# ------------
 ### probably toss these at some point. or major rework. or something.
 ### just bootstrapping some changes for now.
 #

Modified: subversion/branches/ignore-mergeinfo/subversion/tests/cmdline/svnversion_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/tests/cmdline/svnversion_tests.py?rev=984206&r1=984205&r2=984206&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/tests/cmdline/svnversion_tests.py (original)
+++ subversion/branches/ignore-mergeinfo/subversion/tests/cmdline/svnversion_tests.py Tue Aug 10 20:55:56 2010
@@ -237,6 +237,36 @@ def svnversion_with_excluded_subtrees(sb
                                             D_path, repo_url + '/A/D',
                                             [ "1P\n" ], [])
 
+def svnversion_with_structural_changes(sbox):
+  "test 'svnversion' with structural changes"
+  sbox.build()
+  wc_dir = sbox.wc_dir
+  repo_url = sbox.repo_url
+
+  iota_path = os.path.join(wc_dir, 'iota')
+  iota_copy_path = os.path.join(wc_dir, 'iota_copy')
+
+  svntest.actions.run_and_verify_svn(None, None, [],
+                                     'cp', iota_path, iota_copy_path)
+
+  svntest.actions.run_and_verify_svnversion("Copied file",
+                                            iota_copy_path, repo_url +
+                                            '/iota_copy',
+                                            [ "Uncommitted local addition, "
+                                            "copy or move\n" ], 
+                                            [])
+  C_path = os.path.join(wc_dir, 'A', 'C')
+  C_copy_path = os.path.join(wc_dir, 'C_copy')
+  svntest.actions.run_and_verify_svn(None, None, [],
+                                     'cp', C_path, C_copy_path)
+
+  svntest.actions.run_and_verify_svnversion("Copied dir",
+                                            C_copy_path, repo_url +
+                                            '/C_copy',
+                                            [ "Uncommitted local addition, "
+                                            "copy or move\n" ], 
+                                            [])
+
 ########################################################################
 # Run the tests
 
@@ -246,6 +276,7 @@ test_list = [ None,
               svnversion_test,
               ignore_externals,
               svnversion_with_excluded_subtrees,
+              svnversion_with_structural_changes,
              ]
 
 if __name__ == '__main__':

Modified: subversion/branches/ignore-mergeinfo/subversion/tests/cmdline/switch_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/tests/cmdline/switch_tests.py?rev=984206&r1=984205&r2=984206&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/tests/cmdline/switch_tests.py (original)
+++ subversion/branches/ignore-mergeinfo/subversion/tests/cmdline/switch_tests.py Tue Aug 10 20:55:56 2010
@@ -2545,6 +2545,11 @@ def tree_conflicts_on_switch_2_1(sbox):
     },
   }
 
+  ### D/D1/delta is locally-added during leaf_edit. when tree_del executes,
+  ### it will delete D/D1, and the switch reschedules local D/D1 for
+  ### local-copy from its original revision. however, right now, we cannot
+  ### denote that delta is a local-add rather than a child of that D/D1 copy.
+  ### thus, it appears in the status output as a (M)odified child.
   svntest.actions.deep_trees_run_tests_scheme_for_switch(sbox,
     [ DeepTreesTestCase("local_leaf_edit_incoming_tree_del",
                         leaf_edit,
@@ -2939,7 +2944,7 @@ test_list = [ None,
               tolerate_local_mods,
               tree_conflicts_on_switch_1_1,
               tree_conflicts_on_switch_1_2,
-              tree_conflicts_on_switch_2_1,
+              XFail(tree_conflicts_on_switch_2_1),
               tree_conflicts_on_switch_2_2,
               tree_conflicts_on_switch_3,
               single_file_relocate,

Modified: subversion/branches/ignore-mergeinfo/subversion/tests/cmdline/trans_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/tests/cmdline/trans_tests.py?rev=984206&r1=984205&r2=984206&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/tests/cmdline/trans_tests.py (original)
+++ subversion/branches/ignore-mergeinfo/subversion/tests/cmdline/trans_tests.py Tue Aug 10 20:55:56 2010
@@ -387,8 +387,7 @@ def keywords_from_birth(sbox):
     '$URL::x%sx$\n' % (' ' * len(url_expand_test_data))
     ]
 
-  fp = open(os.path.join(wc_dir, svntest.main.get_admin_name(),
-                         'text-base', 'fixed_length_keywords.svn-base'), 'r')
+  fp = open(svntest.wc.text_base_path(fixed_length_keywords_path), 'r')
   actual_textbase_kw = fp.readlines()
   fp.close()
   check_keywords(actual_textbase_kw, kw_textbase, "text base")
@@ -573,7 +572,7 @@ def eol_change_is_text_mod(sbox):
                                      'ci', '-m', 'log msg', foo_path)
 
   # check 2: do the files have the right contents now?
-  contents = svntest.main.file_read(foo_path, 'rb')
+  contents = open(foo_path, 'rb').read()
   if svntest.main.windows:
     if contents != "1\n2\n3\n4\n5\n6\n7\n8\n9\n":
       raise svntest.Failure
@@ -581,9 +580,8 @@ def eol_change_is_text_mod(sbox):
     if contents != "1\r\n2\r\n3\r\n4\r\n5\r\n6\r\n7\r\n8\r\n9\r\n":
       raise svntest.Failure
 
-  foo_base_path = os.path.join(wc_dir, svntest.main.get_admin_name(),
-                               'text-base', 'foo.svn-base')
-  base_contents = svntest.main.file_read(foo_base_path, 'rb')
+  foo_base_path = svntest.wc.text_base_path(foo_path)
+  base_contents = open(foo_base_path, 'rb').read()
   if contents != base_contents:
     raise svntest.Failure
 
@@ -759,7 +757,7 @@ def propset_commit_checkout_nocrash(sbox
                                      sbox.repo_url,
                                      other_wc_dir)
 
-  mu_other_contents = svntest.main.file_read(mu_other_path)
+  mu_other_contents = open(mu_other_path).read()
   if mu_other_contents != "This is the file 'mu'.\n$Rev: 3 $":
     print("'%s' does not have the expected contents" % mu_other_path)
     raise svntest.Failure
@@ -790,6 +788,94 @@ def propset_revert_noerror(sbox):
   svntest.actions.run_and_verify_status(wc_dir, expected_status)
 
 
+def props_only_file_update(sbox):
+  "retranslation occurs on a props-only update"
+
+  sbox.build()
+  wc_dir = sbox.wc_dir
+
+  iota_path = os.path.join(wc_dir, 'iota')
+  content = ["This is the file 'iota'.\n",
+             "$Author$\n",
+             ]
+  content_expanded = ["This is the file 'iota'.\n",
+                      "$Author: jrandom $\n",
+                      ]
+
+  # Create r2 with iota's contents and svn:keywords modified
+  open(iota_path, 'w').writelines(content)
+  svntest.main.run_svn(None, 'propset', 'svn:keywords', 'Author', iota_path)
+
+  expected_output = wc.State(wc_dir, {
+    'iota' : Item(verb='Sending'),
+    })
+
+  expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
+  expected_status.tweak('iota', wc_rev=2)
+
+  svntest.actions.run_and_verify_commit(wc_dir,
+                                        expected_output,
+                                        expected_status,
+                                        None,
+                                        wc_dir)
+
+  # Create r3 that drops svn:keywords
+
+  # put the content back to its untranslated form
+  open(iota_path, 'w').writelines(content)
+
+  svntest.main.run_svn(None, 'propdel', 'svn:keywords', iota_path)
+
+  expected_status.tweak('iota', wc_rev=3)
+
+  svntest.actions.run_and_verify_commit(wc_dir,
+                                        expected_output,
+                                        expected_status,
+                                        None,
+                                        wc_dir)
+
+  # Now, go back to r2. iota should have the Author keyword expanded.
+  expected_disk = svntest.main.greek_state.copy()
+  expected_disk.tweak('iota', contents=''.join(content_expanded))
+
+  expected_status = svntest.actions.get_virginal_state(wc_dir, 2)
+
+  svntest.actions.run_and_verify_update(wc_dir,
+                                        None, None, expected_status,
+                                        None,
+                                        None, None, None, None,
+                                        False,
+                                        wc_dir, '-r', '2')
+
+  if open(iota_path).read() != ''.join(content_expanded):
+    raise svntest.Failure("$Author$ is not expanded in 'iota'")
+
+  # Update to r3. this should retranslate iota, dropping the keyword expansion
+  expected_disk = svntest.main.greek_state.copy()
+  expected_disk.tweak('iota', contents=''.join(content))
+
+  expected_status = svntest.actions.get_virginal_state(wc_dir, 3)
+
+  svntest.actions.run_and_verify_update(wc_dir,
+                                        None, expected_disk, expected_status,
+                                        None,
+                                        None, None, None, None,
+                                        False,
+                                        wc_dir)
+
+  if open(iota_path).read() != ''.join(content):
+    raise svntest.Failure("$Author$ is not contracted in 'iota'")
+
+  # We used to leave some temporary files around. Make sure that we don't.
+  temps = os.listdir(os.path.join(wc_dir, svntest.main.get_admin_name(), 'tmp'))
+  temps.remove('prop-base')
+  temps.remove('props')
+  temps.remove('text-base')
+  if temps:
+    print('Temporary files leftover: %s' % (', '.join(temps),))
+    raise svntest.Failure
+
+
 ########################################################################
 # Run the tests
 
@@ -807,6 +893,7 @@ test_list = [ None,
               copy_propset_commit,
               propset_commit_checkout_nocrash,
               propset_revert_noerror,
+              props_only_file_update,
              ]
 
 if __name__ == '__main__':

Modified: subversion/branches/ignore-mergeinfo/subversion/tests/cmdline/tree_conflict_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/ignore-mergeinfo/subversion/tests/cmdline/tree_conflict_tests.py?rev=984206&r1=984205&r2=984206&view=diff
==============================================================================
--- subversion/branches/ignore-mergeinfo/subversion/tests/cmdline/tree_conflict_tests.py (original)
+++ subversion/branches/ignore-mergeinfo/subversion/tests/cmdline/tree_conflict_tests.py Tue Aug 10 20:55:56 2010
@@ -862,8 +862,8 @@ def force_del_tc_inside(sbox):
   # Verify deletion status
   # Note: the tree conflicts are still in the status.
   expected_status.tweak('A/C', status='D ')
-  expected_status.tweak('A/C/dir', status='! ', copied=None, wc_rev=None)
-  expected_status.tweak('A/C/file', status='! ', copied=None, wc_rev=None)
+  expected_status.tweak('A/C/dir', 'A/C/file', status='! ', copied=None,
+                        wc_rev=None)
 
   run_and_verify_status(wc_dir, expected_status)