Return-Path: X-Original-To: apmail-subversion-commits-archive@minotaur.apache.org Delivered-To: apmail-subversion-commits-archive@minotaur.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 0B87DE985 for ; Wed, 6 Mar 2013 11:11:48 +0000 (UTC) Received: (qmail 31526 invoked by uid 500); 6 Mar 2013 11:11:47 -0000 Delivered-To: apmail-subversion-commits-archive@subversion.apache.org Received: (qmail 31499 invoked by uid 500); 6 Mar 2013 11:11:47 -0000 Mailing-List: contact commits-help@subversion.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@subversion.apache.org Delivered-To: mailing list commits@subversion.apache.org Received: (qmail 31489 invoked by uid 99); 6 Mar 2013 11:11:47 -0000 Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 06 Mar 2013 11:11:47 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=5.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 06 Mar 2013 11:11:25 +0000 Received: from eris.apache.org (localhost [127.0.0.1]) by eris.apache.org (Postfix) with ESMTP id 0B6152388C54; Wed, 6 Mar 2013 11:10:17 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r1453290 [13/15] - in /subversion/branches/fsfs-format7: ./ build/ build/ac-macros/ build/generator/ build/generator/templates/ subversion/bindings/javahl/native/ subversion/bindings/javahl/src/org/apache/subversion/javahl/ subversion/bindi... Date: Wed, 06 Mar 2013 11:10:05 -0000 To: commits@subversion.apache.org From: stefan2@apache.org X-Mailer: svnmailer-1.0.8-patched Message-Id: <20130306111017.0B6152388C54@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Modified: subversion/branches/fsfs-format7/subversion/tests/cmdline/blame_tests.py URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/tests/cmdline/blame_tests.py?rev=1453290&r1=1453289&r2=1453290&view=diff ============================================================================== --- subversion/branches/fsfs-format7/subversion/tests/cmdline/blame_tests.py (original) +++ subversion/branches/fsfs-format7/subversion/tests/cmdline/blame_tests.py Wed Mar 6 11:10:01 2013 @@ -130,23 +130,36 @@ def blame_binary(sbox): svntest.main.file_append(iota, "More new contents for iota\n") svntest.main.run_svn(binary_mime_type_on_text_file_warning, 'propset', 'svn:mime-type', 'image/jpeg', iota) + + # Blame fails when mime-type is locally modified to binary + exit_code, output, errput = svntest.main.run_svn(2, 'blame', iota) + if (len(errput) != 1) or (errput[0].find('Skipping') == -1): + raise svntest.Failure + svntest.main.run_svn(None, 'ci', '-m', '', iota) + # Blame fails when mime-type is binary + exit_code, output, errput = svntest.main.run_svn(2, 'blame', iota) + if (len(errput) != 1) or (errput[0].find('Skipping') == -1): + raise svntest.Failure + # Once more, but now let's remove that mimetype. iota = os.path.join(wc_dir, 'iota') svntest.main.file_append(iota, "Still more new contents for iota\n") svntest.main.run_svn(None, 'propdel', 'svn:mime-type', iota) svntest.main.run_svn(None, 'ci', '-m', '', iota) - - exit_code, output, errput = svntest.main.run_svn(2, 'blame', iota) + + # Blame fails when asking about an old revision where the mime-type is binary + exit_code, output, errput = svntest.main.run_svn(2, 'blame', iota + '@3') if (len(errput) != 1) or (errput[0].find('Skipping') == -1): raise svntest.Failure # But with --force, it should work. - exit_code, output, errput = svntest.main.run_svn(2, 'blame', '--force', iota) - if (len(errput) != 0 or len(output) != 4): + exit_code, output, errput = svntest.main.run_svn(2, 'blame', '--force', + iota + '@3') + if (len(errput) != 0 or len(output) != 3): raise svntest.Failure @@ -602,7 +615,7 @@ def blame_file_not_in_head(sbox): # Check that a correct error message is printed when blaming a target that # doesn't exist (in HEAD). - expected_err = ".*notexisting' (is not a file.*|path not found)" + expected_err = ".*notexisting' (is not a file.*|path not found|does not exist)" svntest.actions.run_and_verify_svn(None, [], expected_err, 'blame', notexisting_url) @@ -805,20 +818,20 @@ def blame_multiple_targets(sbox): sbox.build() + # First, make a new revision of iota. + iota = os.path.join(sbox.wc_dir, 'iota') + svntest.main.file_append(iota, "New contents for iota\n") + svntest.main.run_svn(None, 'ci', '-m', '', iota) + + expected_output = [ + " 1 jrandom This is the file 'iota'.\n", + " 2 jrandom New contents for iota\n", + ] + def multiple_wc_targets(): "multiple wc targets" - # First, make a new revision of iota. - iota = os.path.join(sbox.wc_dir, 'iota') non_existent = os.path.join(sbox.wc_dir, 'non-existent') - svntest.main.file_append(iota, "New contents for iota\n") - svntest.main.run_svn(None, 'ci', - '-m', '', iota) - - expected_output = [ - " 1 jrandom This is the file 'iota'.\n", - " 2 jrandom New contents for iota\n", - ] expected_err = ".*W155010.*\n.*E200009.*" expected_err_re = re.compile(expected_err, re.DOTALL) @@ -830,24 +843,15 @@ def blame_multiple_targets(sbox): if not expected_err_re.match("".join(error)): raise svntest.Failure('blame failed: expected error "%s", but received ' '"%s"' % (expected_err, "".join(error))) + svntest.verify.verify_outputs(None, output, None, expected_output, None) def multiple_url_targets(): "multiple url targets" - # First, make a new revision of iota. - iota = os.path.join(sbox.wc_dir, 'iota') iota_url = sbox.repo_url + '/iota' non_existent = sbox.repo_url + '/non-existent' - svntest.main.file_append(iota, "New contents for iota\n") - svntest.main.run_svn(None, 'ci', - '-m', '', iota) - - expected_output = [ - " 1 jrandom This is the file 'iota'.\n", - " 2 jrandom New contents for iota\n", - ] - expected_err = ".*(W160017|W160013).*\n.*E200009.*" + expected_err = ".*(W160017|W160013|W150000).*\n.*E200009.*" expected_err_re = re.compile(expected_err, re.DOTALL) exit_code, output, error = svntest.main.run_svn(1, 'blame', @@ -857,6 +861,7 @@ def blame_multiple_targets(sbox): if not expected_err_re.match("".join(error)): raise svntest.Failure('blame failed: expected error "%s", but received ' '"%s"' % (expected_err, "".join(error))) + svntest.verify.verify_outputs(None, output, None, expected_output, None) # Test one by one multiple_wc_targets() Modified: subversion/branches/fsfs-format7/subversion/tests/cmdline/copy_tests.py URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/tests/cmdline/copy_tests.py?rev=1453290&r1=1453289&r2=1453290&view=diff ============================================================================== --- subversion/branches/fsfs-format7/subversion/tests/cmdline/copy_tests.py (original) +++ subversion/branches/fsfs-format7/subversion/tests/cmdline/copy_tests.py Wed Mar 6 11:10:01 2013 @@ -2432,20 +2432,11 @@ def move_file_back_and_forth(sbox): # Check expected status before commit expected_status = svntest.actions.get_virginal_state(wc_dir, 1) - expected_status.add({ - 'A/D/G/rho' : Item(status='R ', copied='+', wc_rev='-', - moved_from='A/D/G/rho', moved_to='A/D/G/rho'), - }) svntest.actions.run_and_verify_status(wc_dir, expected_status) - # Commit, and check expected output and status - expected_output = svntest.wc.State(wc_dir, { - 'A/D/G/rho' : Item(verb='Replacing'), - }) + # Try to commit and find out that there is nothing to commit. + expected_output = [] expected_status = svntest.actions.get_virginal_state(wc_dir, 1) - expected_status.add({ - 'A/D/G/rho' : Item(status=' ', wc_rev=2), - }) svntest.actions.run_and_verify_commit(wc_dir, expected_output, expected_status, @@ -2476,19 +2467,6 @@ def move_dir_back_and_forth(sbox): # Verify that the status indicates a replace with history expected_status = svntest.actions.get_virginal_state(wc_dir, 1) - expected_status.add({ - 'A/D' : Item(status='R ', copied='+', wc_rev='-', - moved_from='A/D', moved_to='A/D'), - 'A/D/G' : Item(status=' ', copied='+', wc_rev='-'), - 'A/D/G/pi' : Item(status=' ', copied='+', wc_rev='-'), - 'A/D/G/rho' : Item(status=' ', copied='+', wc_rev='-'), - 'A/D/G/tau' : Item(status=' ', copied='+', wc_rev='-'), - 'A/D/gamma' : Item(status=' ', copied='+', wc_rev='-'), - 'A/D/H' : Item(status=' ', copied='+', wc_rev='-'), - 'A/D/H/chi' : Item(status=' ', copied='+', wc_rev='-'), - 'A/D/H/omega' : Item(status=' ', copied='+', wc_rev='-'), - 'A/D/H/psi' : Item(status=' ', copied='+', wc_rev='-'), - }) svntest.actions.run_and_verify_status(wc_dir, expected_status) def copy_move_added_paths(sbox): @@ -3907,8 +3885,8 @@ def double_parents_with_url(sbox): # Used to cause corruption not fixable by 'svn cleanup'. -def copy_into_absent_dir(sbox): - "copy file into absent dir" +def copy_into_missing_dir(sbox): + "copy file into missing dir" sbox.build(read_only = True) wc_dir = sbox.wc_dir @@ -4755,13 +4733,23 @@ def mixed_rev_copy_del(sbox): svntest.main.run_svn(None, 'up', wc_dir) expected_status.tweak(wc_rev=2) svntest.actions.run_and_verify_status(wc_dir, expected_status) - svntest.main.run_svn(None, 'up', '-r1', - sbox.ospath('A/B/E/alpha'), - sbox.ospath('A/B/E/beta')) + + expected_output = svntest.wc.State(wc_dir, { + 'A/B/E/alpha' : Item(status='A '), + }) + expected_status.add({ 'A/B/E/alpha' : Item(status=' ', wc_rev=1), }) expected_status.tweak('A/B/E/beta', wc_rev=1) + svntest.actions.run_and_verify_update(wc_dir, + expected_output, None, + expected_status, [], + None, None, None, None, None, + '-r1', + sbox.ospath('A/B/E/alpha'), + sbox.ospath('A/B/E/beta')) + svntest.actions.run_and_verify_status(wc_dir, expected_status) # Copy A/B/E to A/B/E_copy @@ -5476,14 +5464,21 @@ def copy_deleted_dir(sbox): sbox.simple_rm('iota') sbox.simple_rm('A') + # E145000 - SVN_ERR_NODE_UNKNOWN_KIND + # E155035 - SVN_ERR_WC_PATH_UNEXPECTED_STATUS + # E155010 - SVN_ERR_WC_PATH_NOT_FOUND + svntest.actions.run_and_verify_svn(None, None, - '(svn: E145000: Path.* does not exist)|' + - "(svn: E155035: Deleted node .* copied)", + 'svn: (E145000|E155035|E155010): ' + + '(Path \'.*iota\' does not exist)|' + + '(Deleted node .*iota\' copied)', 'cp', sbox.ospath('iota'), sbox.ospath('new_iota')) + svntest.actions.run_and_verify_svn(None, None, - '(svn: E145000: Path.* does not exist)|' + - "(svn: E155035: Deleted node .* copied)", + 'svn: (E145000|E155035|E155010): ' + + '(Path \'.*D\' does not exist)|' + + '(Deleted node .*D\' copied)', 'cp', sbox.ospath('A/D'), sbox.ospath('new_D')) @@ -5493,11 +5488,15 @@ def copy_deleted_dir(sbox): # At one time these two invocations raised an assertion. svntest.actions.run_and_verify_svn(None, None, - 'svn: E155035: Deleted node.* can\'t be.*', + 'svn: (E155035|E155010): ' + + '(Path \'.*iota\' does not exist)|' + + '(Deleted node.* .*iota\' can\'t be.*)', 'cp', sbox.ospath('iota'), sbox.ospath('new_iota')) svntest.actions.run_and_verify_svn(None, None, - 'svn: E155035: Deleted node.* can\'t be.*', + 'svn: (E155035|E155010): ' + + '(Path \'.*D\' does not exist)|' + + '(Deleted node.* .*D\' can\'t be.*)', 'cp', sbox.ospath('A/D'), sbox.ospath('new_D')) @@ -5865,7 +5864,7 @@ test_list = [ None, allow_unversioned_parent_for_copy_src, unneeded_parents, double_parents_with_url, - copy_into_absent_dir, + copy_into_missing_dir, find_copyfrom_information_upstairs, path_move_and_copy_between_wcs_2475, path_copy_in_repo_2475, Modified: subversion/branches/fsfs-format7/subversion/tests/cmdline/diff_tests.py URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/tests/cmdline/diff_tests.py?rev=1453290&r1=1453289&r2=1453290&view=diff ============================================================================== --- subversion/branches/fsfs-format7/subversion/tests/cmdline/diff_tests.py (original) +++ subversion/branches/fsfs-format7/subversion/tests/cmdline/diff_tests.py Wed Mar 6 11:10:01 2013 @@ -86,7 +86,8 @@ def make_no_diff_deleted_header(path, ol def make_git_diff_header(target_path, repos_relpath, old_tag, new_tag, add=False, src_label=None, dst_label=None, delete=False, text_changes=True, - cp=False, mv=False, copyfrom_path=None): + cp=False, mv=False, copyfrom_path=None, + copyfrom_rev=None): """ Generate the expected 'git diff' header for file TARGET_PATH. REPOS_RELPATH is the location of the path relative to the repository root. The old and new versions ("revision X", or "working copy") must be @@ -134,9 +135,13 @@ def make_git_diff_header(target_path, re "+++ /dev/null\t(" + new_tag + ")\n" ]) elif cp: + if copyfrom_rev: + copyfrom_rev = '@' + copyfrom_rev + else: + copyfrom_rev = '' output.extend([ "diff --git a/" + copyfrom_path + " b/" + repos_relpath + "\n", - "copy from " + copyfrom_path + "\n", + "copy from " + copyfrom_path + copyfrom_rev + "\n", "copy to " + repos_relpath + "\n", ]) if text_changes: @@ -2209,15 +2214,13 @@ def diff_schedule_delete(sbox): expected_output_r2_base = make_diff_header("foo", "revision 2", "working copy") + [ - "@@ -1 +1,2 @@\n", - " xxx\n", - "+yyy\n" + "@@ -1 +0,0 @@\n", + "-xxx\n", ] - expected_output_base_r2 = make_diff_header("foo", "working copy", + expected_output_base_r2 = make_diff_header("foo", "revision 0", "revision 2") + [ - "@@ -1,2 +1 @@\n", - " xxx\n", - "-yyy\n" + "@@ -0,0 +1 @@\n", + "+xxx\n", ] expected_output_r1_base = make_diff_header("foo", "revision 0", @@ -2427,9 +2430,9 @@ def diff_repos_wc_add_with_props(sbox): ] + make_diff_prop_header("X/bar") + \ make_diff_prop_added("propname", "propvalue") - diff_X_r1_base = make_diff_header("X", "revision 1", + diff_X_r1_base = make_diff_header("X", "revision 0", "working copy") + diff_X - diff_X_base_r3 = make_diff_header("X", "working copy", + diff_X_base_r3 = make_diff_header("X", "revision 0", "revision 3") + diff_X diff_foo_r1_base = make_diff_header("foo", "revision 0", "revision 3") + diff_foo @@ -2528,7 +2531,7 @@ def diff_repos_working_added_dir(sbox): "@@ -0,0 +1 @@\n", "+content\n" ] expected_output_r1_WORKING = make_diff_header("X/bar", "revision 0", - "revision 2") + [ + "working copy") + [ "@@ -0,0 +1,2 @@\n", "+content\n", "+more content\n" ] @@ -3009,7 +3012,7 @@ def diff_with_depth(sbox): make_diff_prop_header("A") + \ make_diff_prop_modified("foo3", "bar3", "baz3") diff_mu = \ - make_diff_header("A/mu", "revision 1", "working copy") + [ + make_diff_header("A/mu", "revision 2", "working copy") + [ "@@ -1 +1,2 @@\n", " This is the file 'mu'.\n", "+new text\n",] @@ -3382,35 +3385,38 @@ def diff_git_format_wc_wc(sbox): ### We're not testing moved paths - expected_output = make_git_diff_header(lambda_copied_path, + expected_output = make_git_diff_header( + alpha_copied_path, "A/B/E/alpha_copied", + "revision 0", "working copy", + copyfrom_path="A/B/E/alpha", + copyfrom_rev='1', cp=True, + text_changes=True) + [ + "@@ -1 +1,2 @@\n", + " This is the file 'alpha'.\n", + "+This is a copy of 'alpha'.\n", + ] + make_git_diff_header(lambda_copied_path, "A/B/lambda_copied", "revision 1", "working copy", - copyfrom_path="A/B/lambda", cp=True, + copyfrom_path="A/B/lambda", + copyfrom_rev='1', cp=True, text_changes=False) \ + make_git_diff_header(mu_path, "A/mu", "revision 1", "working copy", delete=True) + [ "@@ -1 +0,0 @@\n", "-This is the file 'mu'.\n", - ] + make_git_diff_header(alpha_copied_path, "A/B/E/alpha_copied", - "revision 0", "working copy", - copyfrom_path="A/B/E/alpha", cp=True, - text_changes=True) + [ + ] + make_git_diff_header(iota_path, "iota", "revision 1", + "working copy") + [ "@@ -1 +1,2 @@\n", - " This is the file 'alpha'.\n", - "+This is a copy of 'alpha'.\n", + " This is the file 'iota'.\n", + "+Changed 'iota'.\n", ] + make_git_diff_header(new_path, "new", "revision 0", "working copy", add=True) + [ "@@ -0,0 +1 @@\n", "+This is the file 'new'.\n", - ] + make_git_diff_header(iota_path, "iota", "revision 1", - "working copy") + [ - "@@ -1 +1,2 @@\n", - " This is the file 'iota'.\n", - "+Changed 'iota'.\n", ] - expected = svntest.verify.UnorderedOutput(expected_output) + expected = expected_output svntest.actions.run_and_verify_svn(None, expected, [], 'diff', '--git', wc_dir) @@ -3450,13 +3456,13 @@ def diff_git_format_wc_wc_dir_mv(sbox): "@@ -1 +0,0 @@\n", "-This is the file 'tau'.\n" ] + make_git_diff_header(new_pi_path, "A/D/G2/pi", None, None, cp=True, - copyfrom_path="A/D/G/pi", text_changes=False) \ + copyfrom_path="A/D/G/pi", copyfrom_rev='1', text_changes=False) \ + make_git_diff_header(new_rho_path, "A/D/G2/rho", None, None, cp=True, - copyfrom_path="A/D/G/rho", text_changes=False) \ + copyfrom_path="A/D/G/rho", copyfrom_rev='1', text_changes=False) \ + make_git_diff_header(new_tau_path, "A/D/G2/tau", None, None, cp=True, - copyfrom_path="A/D/G/tau", text_changes=False) + copyfrom_path="A/D/G/tau", copyfrom_rev='1', text_changes=False) - expected = svntest.verify.UnorderedOutput(expected_output) + expected = expected_output svntest.actions.run_and_verify_svn(None, expected, [], 'diff', '--git', wc_dir) @@ -3878,7 +3884,6 @@ def no_spurious_conflict(sbox): expected_status.tweak('3449_spurious', status=' ') svntest.actions.run_and_verify_status(wc_dir, expected_status) -@XFail() def diff_two_working_copies(sbox): "diff between two working copies" sbox.build() @@ -3957,7 +3962,10 @@ def diff_two_working_copies(sbox): src_label, dst_label) + [ "@@ -1 +0,0 @@\n", "-This is the file 'pi'.\n", - ] + make_diff_prop_header('A/D/G/pi') + \ + ] + make_diff_header('A/D/G/pi', 'working copy', + 'working copy', + src_label, dst_label) + \ + make_diff_prop_header('A/D/G/pi') + \ make_diff_prop_added("newprop", "propval") + \ make_diff_header('A/D/H/chi', 'working copy', 'working copy', @@ -4298,6 +4306,219 @@ def simple_ancestry(sbox): '--show-copies-as-adds', '--no-diff-added') +def local_tree_replace(sbox): + "diff a replaced tree" + + sbox.build() + wc_dir = sbox.wc_dir + + sbox.simple_add_text('extra', 'A/B/F/extra') + sbox.simple_commit() + + svntest.actions.run_and_verify_svn(None, None, [], + 'rm', '--keep-local', + sbox.ospath('A/B')) + svntest.actions.run_and_verify_svn(None, None, [], + 'add', sbox.ospath('A/B')) + + # And now check with ancestry + + line = '===================================================================\n' + + expected_output = svntest.verify.UnorderedOutput([ + 'Index: %s (deleted)\n' % sbox.path('A/B/lambda'), + line, + 'Index: %s (deleted)\n' % sbox.path('A/B/E/alpha'), + line, + 'Index: %s (deleted)\n' % sbox.path('A/B/E/beta'), + line, + 'Index: %s (deleted)\n' % sbox.path('A/B/F/extra'), + line, + 'Index: %s (added)\n' % sbox.path('A/B/lambda'), + line, + 'Index: %s (added)\n' % sbox.path('A/B/E/alpha'), + line, + 'Index: %s (added)\n' % sbox.path('A/B/E/beta'), + line, + 'Index: %s (added)\n' % sbox.path('A/B/F/extra'), + line, + ]) + + svntest.actions.run_and_verify_svn(None, expected_output, [], + 'diff', wc_dir, + '-r', '2', + '--notice-ancestry', + '--show-copies-as-adds', + '--no-diff-added', + '--no-diff-deleted') + + # Now create patches to verify the tree ordering + patch = os.path.abspath(os.path.join(wc_dir, 'ancestry.patch')) + + cwd = os.getcwd() + os.chdir(wc_dir) + _, out, _ = svntest.actions.run_and_verify_svn(None, None, [], + 'diff', '.', + '-r', '2', + '--notice-ancestry', + '--show-copies-as-adds') + svntest.main.file_append(patch, ''.join(out)) + os.chdir(cwd) + + # And try to apply it + svntest.actions.run_and_verify_svn(None, None, [], 'revert', '-R', wc_dir) + + expected_output = svntest.verify.UnorderedOutput([ + 'D %s\n' % sbox.ospath('A/B/F/extra'), + 'D %s\n' % sbox.ospath('A/B/F'), + 'D %s\n' % sbox.ospath('A/B/E/beta'), + 'D %s\n' % sbox.ospath('A/B/E/alpha'), + 'D %s\n' % sbox.ospath('A/B/E'), + 'D %s\n' % sbox.ospath('A/B/lambda'), + 'D %s\n' % sbox.ospath('A/B'), + 'A %s\n' % sbox.ospath('A/B'), + 'A %s\n' % sbox.ospath('A/B/lambda'), + 'A %s\n' % sbox.ospath('A/B/F'), + 'A %s\n' % sbox.ospath('A/B/F/extra'), + 'A %s\n' % sbox.ospath('A/B/E'), + 'A %s\n' % sbox.ospath('A/B/E/beta'), + 'A %s\n' % sbox.ospath('A/B/E/alpha'), + ]) + # And this currently fails because the ordering is broken, but also + # because it hits an issue in 'svn patch' + svntest.actions.run_and_verify_svn(None, expected_output, [], + 'patch', patch, wc_dir) + +def diff_dir_replaced_by_file(sbox): + "diff a directory replaced by a file" + + sbox.build() + wc_dir = sbox.wc_dir + + sbox.simple_rm('A/B/E') + sbox.simple_add_text('text', 'A/B/E') + + expected_output = [ + 'Index: %s\n' % sbox.path('A/B/E/alpha'), + '===================================================================\n', + '--- %s\t(revision 1)\n' % sbox.path('A/B/E/alpha'), + '+++ %s\t(working copy)\n' % sbox.path('A/B/E/alpha'), + '@@ -1 +0,0 @@\n', + '-This is the file \'alpha\'.\n', + 'Index: %s\n' % sbox.path('A/B/E/beta'), + '===================================================================\n', + '--- %s\t(revision 1)\n' % sbox.path('A/B/E/beta'), + '+++ %s\t(working copy)\n' % sbox.path('A/B/E/beta'), + '@@ -1 +0,0 @@\n', + '-This is the file \'beta\'.\n', + 'Index: %s\n' % sbox.path('A/B/E'), + '===================================================================\n', + '--- %s\t(revision 0)\n' % sbox.path('A/B/E'), + '+++ %s\t(working copy)\n' % sbox.path('A/B/E'), + '@@ -0,0 +1 @@\n', + '+text\n', + '\ No newline at end of file\n', + ] + + svntest.actions.run_and_verify_svn(None, expected_output, [], + 'diff', wc_dir) + +def diff_dir_replaced_by_dir(sbox): + "diff a directory replaced by a directory tree" + + sbox.build() + wc_dir = sbox.wc_dir + + sbox.simple_rm('A/B/E') + sbox.simple_mkdir('A/B/E') + sbox.simple_propset('a', 'b\n', 'A/B/E') + sbox.simple_add_text('New beta\n', 'A/B/E/beta') + + # First check with ancestry (Tree replace) + + expected_output = [ + 'Index: %s\n' % sbox.path('A/B/E/alpha'), + '===================================================================\n', + '--- %s\t(revision 1)\n' % sbox.path('A/B/E/alpha'), + '+++ %s\t(working copy)\n' % sbox.path('A/B/E/alpha'), + '@@ -1 +0,0 @@\n', + '-This is the file \'alpha\'.\n', + 'Index: %s\n' % sbox.path('A/B/E/beta'), + '===================================================================\n', + '--- %s\t(revision 1)\n' % sbox.path('A/B/E/beta'), + '+++ %s\t(working copy)\n' % sbox.path('A/B/E/beta'), + '@@ -1 +0,0 @@\n', + '-This is the file \'beta\'.\n', + 'Index: %s\n' % sbox.path('A/B/E/beta'), + '===================================================================\n', + '--- %s\t(revision 0)\n' % sbox.path('A/B/E/beta'), + '+++ %s\t(working copy)\n' % sbox.path('A/B/E/beta'), + '@@ -0,0 +1 @@\n', + '+New beta\n', + 'Index: %s\n' % sbox.path('A/B/E'), + '===================================================================\n', + '--- %s\t(revision 0)\n' % sbox.path('A/B/E'), + '+++ %s\t(working copy)\n' % sbox.path('A/B/E'), + '\n', + 'Property changes on: %s\n' % sbox.path('A/B/E'), + '___________________________________________________________________\n', + 'Added: a\n', + '## -0,0 +1 ##\n', + '+b\n', + ] + + svntest.actions.run_and_verify_svn(None, expected_output, [], + 'diff', '--notice-ancestry', wc_dir) + + # And summarized. Currently produces directory adds after their children + expected_output = svntest.verify.UnorderedOutput([ + 'D %s\n' % sbox.ospath('A/B/E/alpha'), + 'D %s\n' % sbox.ospath('A/B/E/beta'), + 'D %s\n' % sbox.ospath('A/B/E'), + 'A %s\n' % sbox.ospath('A/B/E'), + 'A %s\n' % sbox.ospath('A/B/E/beta'), + ]) + svntest.actions.run_and_verify_svn(None, expected_output, [], + 'diff', '--summarize', wc_dir, + '--notice-ancestry') + + # And now without (file delete, change + properties) + expected_output = [ + 'Index: %s\n' % sbox.path('A/B/E/alpha'), + '===================================================================\n', + '--- %s\t(revision 1)\n' % sbox.path('A/B/E/alpha'), + '+++ %s\t(working copy)\n' % sbox.path('A/B/E/alpha'), + '@@ -1 +0,0 @@\n', + '-This is the file \'alpha\'.\n', + 'Index: %s\n' % sbox.path('A/B/E/beta'), + '===================================================================\n', + '--- %s\t(revision 1)\n' % sbox.path('A/B/E/beta'), + '+++ %s\t(working copy)\n' % sbox.path('A/B/E/beta'), + '@@ -1 +1 @@\n', + '-This is the file \'beta\'.\n', + '+New beta\n', + 'Index: %s\n' % sbox.path('A/B/E'), + '===================================================================\n', + '--- %s\t(revision 1)\n' % sbox.path('A/B/E'), + '+++ %s\t(working copy)\n' % sbox.path('A/B/E'), + '\n', + 'Property changes on: %s\n' % sbox.path('A/B/E'), + '___________________________________________________________________\n', + 'Added: a\n', + '## -0,0 +1 ##\n', + '+b\n', + ] + + svntest.actions.run_and_verify_svn(None, expected_output, [], + 'diff', wc_dir) + + expected_output = [ + 'D %s\n' % sbox.ospath('A/B/E/alpha'), + 'M %s\n' % sbox.ospath('A/B/E/beta'), + ' M %s\n' % sbox.ospath('A/B/E'), + ] + svntest.actions.run_and_verify_svn(None, expected_output, [], + 'diff', '--summarize', wc_dir) ######################################################################## #Run the tests @@ -4374,6 +4595,9 @@ test_list = [ None, diff_arbitrary_same, diff_git_format_wc_wc_dir_mv, simple_ancestry, + local_tree_replace, + diff_dir_replaced_by_file, + diff_dir_replaced_by_dir, ] if __name__ == '__main__': Modified: subversion/branches/fsfs-format7/subversion/tests/cmdline/externals_tests.py URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/tests/cmdline/externals_tests.py?rev=1453290&r1=1453289&r2=1453290&view=diff ============================================================================== --- subversion/branches/fsfs-format7/subversion/tests/cmdline/externals_tests.py (original) +++ subversion/branches/fsfs-format7/subversion/tests/cmdline/externals_tests.py Wed Mar 6 11:10:01 2013 @@ -3188,6 +3188,44 @@ def pinned_externals(sbox): svntest.actions.verify_disk(wc_dir, expected_disk) +# Test for issue #3741 'externals not removed when working copy is made shallow' +@Issue(3741) +def update_dir_external_shallow(sbox): + "shallow update should remove externals" + + sbox.build() + + # Create an external in r2 + sbox.simple_propset('svn:externals', '^/A/D/H X', 'A/B/E') + sbox.simple_commit() + sbox.simple_update() + + # Now make A/B/E shallow by updating with "--set-depth empty" + expected_output = svntest.wc.State(sbox.wc_dir, { + 'A/B/E/alpha' : Item(status='D '), + 'A/B/E/X' : Item(verb='Removed external'), + 'A/B/E/beta' : Item(status='D '), + }) + svntest.actions.run_and_verify_update(sbox.wc_dir, + expected_output, None, None, + None, None, None, None, None, False, + '--set-depth=empty', + sbox.ospath('A/B/E')) + + # And bring the external back by updating with "--set-depth infinity" + expected_output = svntest.wc.State(sbox.wc_dir, { + 'A/B/E/X/psi' : Item(status='A '), + 'A/B/E/X/chi' : Item(status='A '), + 'A/B/E/X/omega' : Item(status='A '), + 'A/B/E/alpha' : Item(status='A '), + 'A/B/E/beta' : Item(status='A '), + }) + svntest.actions.run_and_verify_update(sbox.wc_dir, + expected_output, None, None, + None, None, None, None, None, False, + '--set-depth=infinity', + sbox.ospath('A/B/E')) + ######################################################################## # Run the tests @@ -3240,6 +3278,7 @@ test_list = [ None, list_include_externals, move_with_file_externals, pinned_externals, + update_dir_external_shallow, ] if __name__ == '__main__': Modified: subversion/branches/fsfs-format7/subversion/tests/cmdline/input_validation_tests.py URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/tests/cmdline/input_validation_tests.py?rev=1453290&r1=1453289&r2=1453290&view=diff ============================================================================== --- subversion/branches/fsfs-format7/subversion/tests/cmdline/input_validation_tests.py (original) +++ subversion/branches/fsfs-format7/subversion/tests/cmdline/input_validation_tests.py Wed Mar 6 11:10:01 2013 @@ -104,7 +104,7 @@ def invalid_copy_target(sbox): sbox.build(read_only=True) mu_path = os.path.join('A', 'mu') C_path = os.path.join('A', 'C') - run_and_verify_svn_in_wc(sbox, "svn: E155007: Path '.*' is not a directory", + run_and_verify_svn_in_wc(sbox, "svn: E155(007|010): Path '.*' is not a directory", 'copy', mu_path, C_path, "iota") def invalid_delete_targets(sbox): @@ -252,7 +252,6 @@ def invalid_update_targets(sbox): run_and_verify_svn_in_wc(sbox, "svn:.*is not a local path", 'update', "^/") -@XFail() def delete_repos_root(sbox): "do stupid things with the repository root" @@ -285,7 +284,7 @@ def delete_repos_root(sbox): # This should produce some error, because we can never commit this expected_error = '.*repository root.*' - svntest.actions.run_and_verify_svn('Move root', [], expected_error, + svntest.actions.run_and_verify_svn('Move root', None, expected_error, 'mv', sbox.ospath('A/D/G'), sbox.ospath('Z')) Modified: subversion/branches/fsfs-format7/subversion/tests/cmdline/lock_tests.py URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/tests/cmdline/lock_tests.py?rev=1453290&r1=1453289&r2=1453290&view=diff ============================================================================== --- subversion/branches/fsfs-format7/subversion/tests/cmdline/lock_tests.py (original) +++ subversion/branches/fsfs-format7/subversion/tests/cmdline/lock_tests.py Wed Mar 6 11:10:01 2013 @@ -1474,10 +1474,13 @@ def lock_path_not_in_head(sbox): # svn: In file '..\..\..\subversion\libsvn_ra_serf\util.c' line 1120: # assertion failed (ctx->status_code) svntest.actions.run_and_verify_svn2(None, None, expected_lock_fail_err_re, - 0, 'lock', D_path) - svntest.actions.run_and_verify_svn2(None, None, expected_lock_fail_err_re, 0, 'lock', lambda_path) + expected_err = 'svn: E155008: The node \'.*D\' is not a file' + svntest.actions.run_and_verify_svn(None, None, expected_err, + 'lock', D_path) + + #---------------------------------------------------------------------- def verify_path_escaping(sbox): "verify escaping of lock paths" Modified: subversion/branches/fsfs-format7/subversion/tests/cmdline/merge_authz_tests.py URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/tests/cmdline/merge_authz_tests.py?rev=1453290&r1=1453289&r2=1453290&view=diff ============================================================================== --- subversion/branches/fsfs-format7/subversion/tests/cmdline/merge_authz_tests.py (original) +++ subversion/branches/fsfs-format7/subversion/tests/cmdline/merge_authz_tests.py Wed Mar 6 11:10:01 2013 @@ -122,7 +122,7 @@ def mergeinfo_and_skipped_paths(sbox): A_COPY_2_H_path = os.path.join(wc_restricted, "A_COPY_2", "D", "H") A_COPY_3_path = os.path.join(wc_restricted, "A_COPY_3") omega_path = os.path.join(wc_restricted, "A_COPY", "D", "H", "omega") - zeta_path = os.path.join(wc_dir, "A", "D", "H", "zeta") + zeta_path = sbox.ospath("A/D/H/zeta") # Merge r4:8 into the restricted WC's A_COPY. # @@ -503,10 +503,10 @@ def merge_fails_if_subtree_is_deleted_on svntest.main.wc_author2 + " = rw")}) # Some paths we'll care about - Acopy_path = os.path.join(wc_dir, 'A_copy') - gamma_path = os.path.join(wc_dir, 'A', 'D', 'gamma') - Acopy_gamma_path = os.path.join(wc_dir, 'A_copy', 'D', 'gamma') - Acopy_D_path = os.path.join(wc_dir, 'A_copy', 'D') + Acopy_path = sbox.ospath('A_copy') + gamma_path = sbox.ospath('A/D/gamma') + Acopy_gamma_path = sbox.ospath('A_copy/D/gamma') + Acopy_D_path = sbox.ospath('A_copy/D') A_url = sbox.repo_url + '/A' Acopy_url = sbox.repo_url + '/A_copy' @@ -624,12 +624,12 @@ def reintegrate_fails_if_no_root_access( # Some paths we'll care about wc_dir = sbox.wc_dir - A_path = os.path.join(wc_dir, 'A') - A_COPY_path = os.path.join(wc_dir, 'A_COPY') - beta_COPY_path = os.path.join(wc_dir, 'A_COPY', 'B', 'E', 'beta') - rho_COPY_path = os.path.join(wc_dir, 'A_COPY', 'D', 'G', 'rho') - omega_COPY_path = os.path.join(wc_dir, 'A_COPY', 'D', 'H', 'omega') - psi_COPY_path = os.path.join(wc_dir, 'A_COPY', 'D', 'H', 'psi') + A_path = sbox.ospath('A') + A_COPY_path = sbox.ospath('A_COPY') + beta_COPY_path = sbox.ospath('A_COPY/B/E/beta') + rho_COPY_path = sbox.ospath('A_COPY/D/G/rho') + omega_COPY_path = sbox.ospath('A_COPY/D/H/omega') + psi_COPY_path = sbox.ospath('A_COPY/D/H/psi') # Copy A@1 to A_COPY in r2, and then make some changes to A in r3-6. sbox.build() @@ -637,7 +637,7 @@ def reintegrate_fails_if_no_root_access( expected_disk, expected_status = set_up_branch(sbox) # Make a change on the branch, to A_COPY/mu, commit in r7. - svntest.main.file_write(os.path.join(wc_dir, "A_COPY", "mu"), + svntest.main.file_write(sbox.ospath("A_COPY/mu"), "Changed on the branch.") expected_output = wc.State(wc_dir, {'A_COPY/mu' : Item(verb='Sending')}) expected_status.tweak('A_COPY/mu', wc_rev=7) @@ -737,6 +737,133 @@ def reintegrate_fails_if_no_root_access( None, True, True, '--reintegrate', A_path) +#---------------------------------------------------------------------- +# Test for issue #4319 'faulty merge notifications when target subtree +# unreadable'. +@SkipUnless(svntest.main.server_has_mergeinfo) +@Skip(svntest.main.is_ra_type_file) +@Issue(4319) +@XFail() +def merge_notifications_and_authz_skips(sbox): + "merge notifications when target subtree unreadable" + + sbox.build() + wc_dir = sbox.wc_dir + + deep_source_tree = sbox.ospath('A/C/J/K/L/M/N/O/P/Q/R/S/T/U/V/W/X/Y/Z') + deep_source_file = sbox.ospath('A/C/J/K/L/M/N/O/P/Q/R/S/T/U/V/W/X/Y/Z/nu') + branch_root = sbox.ospath('branch') + + # r2 - branch ^/A to ^/branch + sbox.simple_copy('A', 'branch') + sbox.simple_commit() + sbox.simple_update() + + # r3 - Add a deep subtree + svntest.actions.run_and_verify_svn(None, None, [], 'mkdir', + deep_source_tree, '--parents') + svntest.main.file_write(deep_source_file, "This is the file 'nu'.\n") + svntest.actions.run_and_verify_svn(None, None, [], 'add', deep_source_file) + sbox.simple_commit() + + # + # Create a restrictive authz where part of the merge source and part + # of the target are inaccesible. + sbox.simple_update(revision=0) + write_restrictive_svnserve_conf(sbox.repo_dir) + write_authz_file(sbox, {"/" : svntest.main.wc_author +"=rw", + # Make a subtree in the merge target inaccessible. + "/branch/C" : svntest.main.wc_author + "=", + }) + sbox.simple_update() + + expected_output = wc.State(branch_root, { + }) + expected_mergeinfo_output = wc.State(branch_root, { + '' : Item(status=' U'), + }) + expected_elision_output = wc.State(branch_root, { + }) + expected_status = wc.State(branch_root, { + '' : Item(status=' M', wc_rev=3), + 'D/H/chi' : Item(status=' ', wc_rev=3), + 'D/H/omega' : Item(status=' ', wc_rev=3), + 'D/H/psi' : Item(status=' ', wc_rev=3), + 'D/H' : Item(status=' ', wc_rev=3), + 'D/gamma' : Item(status=' ', wc_rev=3), + 'D' : Item(status=' ', wc_rev=3), + 'D/G' : Item(status=' ', wc_rev=3), + 'D/G/pi' : Item(status=' ', wc_rev=3), + 'D/G/rho' : Item(status=' ', wc_rev=3), + 'D/G/tau' : Item(status=' ', wc_rev=3), + 'B/lambda' : Item(status=' ', wc_rev=3), + 'B/E' : Item(status=' ', wc_rev=3), + 'B/E/alpha' : Item(status=' ', wc_rev=3), + 'B/E/beta' : Item(status=' ', wc_rev=3), + 'B/F' : Item(status=' ', wc_rev=3), + 'B' : Item(status=' ', wc_rev=3), + 'mu' : Item(status=' ', wc_rev=3), + }) + expected_disk = wc.State('', { + '' : Item(props={SVN_PROP_MERGEINFO : '/A:2-3*'}), + 'D/H/omega' : Item("This is the file 'omega'.\n"), + 'D/H/chi' : Item("This is the file 'chi'.\n"), + 'D/H/psi' : Item("This is the file 'psi'.\n"), + 'D/H' : Item(), + 'D/gamma' : Item("This is the file 'gamma'.\n"), + 'D' : Item(), + 'D/G' : Item(), + 'D/G/pi' : Item("This is the file 'pi'.\n"), + 'D/G/rho' : Item("This is the file 'rho'.\n"), + 'D/G/tau' : Item("This is the file 'tau'.\n"), + 'B/lambda' : Item("This is the file 'lambda'.\n"), + 'B/E' : Item(), + 'B/E/alpha' : Item("This is the file 'alpha'.\n"), + 'B/E/beta' : Item("This is the file 'beta'.\n"), + 'B/F' : Item(), + 'B' : Item(), + 'mu' : Item("This is the file 'mu'.\n"), + }) + expected_skip = wc.State(branch_root, + {'C' : Item(verb='Skipped missing target')}) + # This fails because notifications for all the added subtrees under + # branch/C occur: + # + # >svn merge ^^/A branch -r1:3 + # Skipped missing target: 'branch\C' + # A branch\C\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z\nu + # A branch\C\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z + # A branch\C\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y + # A branch\C\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X + # A branch\C\J\K\L\M\N\O\P\Q\R\S\T\U\V\W + # A branch\C\J\K\L\M\N\O\P\Q\R\S\T\U\V + # A branch\C\J\K\L\M\N\O\P\Q\R\S\T\U + # A branch\C\J\K\L\M\N\O\P\Q\R\S\T + # A branch\C\J\K\L\M\N\O\P\Q\R\S + # A branch\C\J\K\L\M\N\O\P\Q\R + # A branch\C\J\K\L\M\N\O\P\Q + # A branch\C\J\K\L\M\N\O\P + # A branch\C\J\K\L\M\N\O + # A branch\C\J\K\L\M\N + # A branch\C\J\K\L\M + # A branch\C\J\K\L + # A branch\C\J\K + # A branch\C\J + # --- Recording mergeinfo for merge of r2 through r3 into 'branch': + # U branch + # Summary of conflicts: + # Skipped paths: 1 + svntest.actions.run_and_verify_merge(branch_root, None, None, + sbox.repo_url + '/A', None, + expected_output, + expected_mergeinfo_output, + expected_elision_output, + expected_disk, + expected_status, + expected_skip, + None, None, None, None, + None, 1, 0) + ######################################################################## # Run the tests @@ -746,6 +873,7 @@ test_list = [ None, mergeinfo_and_skipped_paths, merge_fails_if_subtree_is_deleted_on_src, reintegrate_fails_if_no_root_access, + merge_notifications_and_authz_skips, ] serial_only = True Modified: subversion/branches/fsfs-format7/subversion/tests/cmdline/merge_automatic_tests.py URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/tests/cmdline/merge_automatic_tests.py?rev=1453290&r1=1453289&r2=1453290&view=diff ============================================================================== --- subversion/branches/fsfs-format7/subversion/tests/cmdline/merge_automatic_tests.py (original) +++ subversion/branches/fsfs-format7/subversion/tests/cmdline/merge_automatic_tests.py Wed Mar 6 11:10:01 2013 @@ -1125,6 +1125,85 @@ def auto_merge_handles_replacements_in_m " G " + branch2_path + "\n"], [], 'merge', sbox.repo_url + '/A', branch2_path) +# Test for issue #4329 'automatic merge uses reintegrate type merge if +# source is fully synced' +@SkipUnless(server_has_mergeinfo) +@Issue(4329) +@XFail() +def effective_sync_results_in_reintegrate(sbox): + "an effectively synced branch gets reintegrated" + + sbox.build() + + iota_path = sbox.ospath('iota') + A_path = sbox.ospath('A') + psi_path = sbox.ospath('A/D/H/psi') + mu_path = sbox.ospath('A/mu') + branch_path = sbox.ospath('branch') + psi_branch_path = sbox.ospath('branch/D/H/psi') + + # r2 - Make a branch. + sbox.simple_copy('A', 'branch') + sbox.simple_commit() + + # r3 - An edit to a file on the trunk. + sbox.simple_append('A/mu', "Trunk edit to 'mu'\n", True) + sbox.simple_commit() + + # r4 - An edit to a file on the branch + sbox.simple_append('branch/D/H/psi', "Branch edit to 'psi'\n", True) + sbox.simple_commit() + + # r5 - Effectively sync all changes on trunk to the branch. We do this + # not via an automatic sync merge, but with a cherry pick that effectively + # merges the same changes (i.e. r3). + sbox.simple_update() + cherry_pick(sbox, 3, A_path, branch_path) + + # r6 - Make another edit to the file on the trunk. + sbox.simple_append('A/mu', "2nd trunk edit to 'mu'\n", True) + sbox.simple_commit() + + # Now try an explicit --reintegrate merge from ^/branch to A. + # This should work because since the resolution of + # http://subversion.tigris.org/issues/show_bug.cgi?id=3577 + # if B is *effectively* synced with A, then B can be reintegrated + # to A. + sbox.simple_update() + expected_output = [ + "--- Merging differences between repository URLs into '" + + A_path + "':\n", + "U " + psi_path + "\n", + "--- Recording mergeinfo for merge between repository URLs into '" + + A_path + "':\n", + " U " + A_path + "\n"] + svntest.actions.run_and_verify_svn(None, expected_output, [], 'merge', + sbox.repo_url + '/branch', A_path, + '--reintegrate') + + # Revert the merge and try it again, this time without the --reintegrate + # option. The merge should still work with the same results. + # + # Currently this fails because the reintegrate code path is not followed, + # rather the automatic merge attempts a sync style merge of the yca (^/A@1) + # through the HEAD of the branch (^/branch@7). This results in a spurious + # conflict on A/mu as the edit made in r3 is reapplied.. + # + # >svn merge ^/branch A + # --- Merging r2 through r6 into 'A': + # C A\mu + # U A\D\H\psi + # --- Recording mergeinfo for merge of r2 through r6 into 'A': + # U A + # Summary of conflicts: + # Text conflicts: 1 + # Conflict discovered in file 'A\mu'. + # Select: (p) postpone, (df) diff-full, (e) edit, (m) merge, + # (mc) mine-conflict, (tc) theirs-conflict, (s) show all options: p + svntest.actions.run_and_verify_svn(None, None, [], 'revert', A_path, '-R') + svntest.actions.run_and_verify_svn(None, expected_output, [], 'merge', + sbox.repo_url + '/branch', A_path) + ######################################################################## # Run the tests @@ -1152,6 +1231,7 @@ test_list = [ None, merge_to_reverse_cherry_subtree_to_merge_to, merge_replacement, auto_merge_handles_replacements_in_merge_source, + effective_sync_results_in_reintegrate, ] if __name__ == '__main__': Modified: subversion/branches/fsfs-format7/subversion/tests/cmdline/merge_reintegrate_tests.py URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/tests/cmdline/merge_reintegrate_tests.py?rev=1453290&r1=1453289&r2=1453290&view=diff ============================================================================== --- subversion/branches/fsfs-format7/subversion/tests/cmdline/merge_reintegrate_tests.py (original) +++ subversion/branches/fsfs-format7/subversion/tests/cmdline/merge_reintegrate_tests.py Wed Mar 6 11:10:01 2013 @@ -1916,7 +1916,7 @@ def reintegrate_with_subtree_merges(sbox 'mu' : Item(status='U '), }) expected_mergeinfo_output = wc.State(A_path, { - '' : Item(status=' G'), + '' : Item(status=' U'), }) expected_elision_output = wc.State(A_path, { }) @@ -1965,14 +1965,14 @@ def reintegrate_with_subtree_merges(sbox }) expected_A_skip = wc.State(A_COPY_path, {}) run_and_verify_reintegrate(A_path, - sbox.repo_url + '/A_COPY', - expected_output, - expected_mergeinfo_output, - expected_elision_output, - expected_A_disk, - expected_A_status, - expected_A_skip, - None, 1, 1) + sbox.repo_url + '/A_COPY', + expected_output, + expected_mergeinfo_output, + expected_elision_output, + expected_A_disk, + expected_A_status, + expected_A_skip, + None, 1, 1) #---------------------------------------------------------------------- # Test for issue #3654 'added subtrees with mergeinfo break reintegrate'. @@ -2774,6 +2774,7 @@ test_list = [ None, reintegrate_with_subtree_mergeinfo, multiple_reintegrates_from_the_same_branch, reintegrate_with_self_referential_mergeinfo, + reintegrate_with_subtree_merges, added_subtrees_with_mergeinfo_break_reintegrate, two_URL_merge_removes_valid_mergeinfo_from_target, reintegrate_creates_bogus_mergeinfo, Modified: subversion/branches/fsfs-format7/subversion/tests/cmdline/merge_tests.py URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/tests/cmdline/merge_tests.py?rev=1453290&r1=1453289&r2=1453290&view=diff ============================================================================== --- subversion/branches/fsfs-format7/subversion/tests/cmdline/merge_tests.py (original) +++ subversion/branches/fsfs-format7/subversion/tests/cmdline/merge_tests.py Wed Mar 6 11:10:01 2013 @@ -1390,6 +1390,13 @@ def merge_in_new_file_and_diff(sbox): # Finally, run diff. expected_output = [ + "Index: " + url_branch_path + "/newfile\n", + "===================================================================\n", + "--- "+ url_branch_path + "/newfile (revision 0)\n", + "+++ "+ url_branch_path + "/newfile (working copy)\n", + "@@ -0,0 +1 @@\n", + "+newfile\n", + "Index: " + url_branch_path + "\n", "===================================================================\n", "--- "+ url_branch_path + "\t(revision 2)\n", @@ -1399,12 +1406,7 @@ def merge_in_new_file_and_diff(sbox): "___________________________________________________________________\n", "Added: " + SVN_PROP_MERGEINFO + "\n", " Merged /A/B/E:r2-3\n", - "Index: " + url_branch_path + "/newfile\n", - "===================================================================\n", - "--- "+ url_branch_path + "/newfile (revision 0)\n", - "+++ "+ url_branch_path + "/newfile (working copy)\n", - "@@ -0,0 +1 @@\n", - "+newfile\n"] + ] svntest.actions.run_and_verify_svn(None, expected_output, [], 'diff', '--show-copies-as-adds', branch_path) @@ -18342,7 +18344,6 @@ def simple_merge(src_path, tgt_ospath, r @Issue(4306) # Test for issue #4306 'multiple editor drive file merges record wrong # mergeinfo during conflicts' -### TODO: Directory merges. We're only testing single-file merges so far. def conflict_aborted_mergeinfo_described_partial_merge(sbox): "conflicted split merge can be repeated" @@ -18623,7 +18624,7 @@ def multiple_editor_drive_merge_notifica @Issue(4317) # Test for issue #4317 "redundant notifications in single editor drive merge". def single_editor_drive_merge_notifications(sbox): - "single editor drive" + "single editor drive merge notifications" sbox.build() wc_dir = sbox.wc_dir @@ -18658,8 +18659,12 @@ def single_editor_drive_merge_notificati # U A_COPY\D # --- Eliding mergeinfo from 'A_COPY\D': # U A_COPY\D - svntest.actions.run_and_verify_svn( - None, + # + # The order of 'beta' and 'omega' can vary, so use UnorderedOutput. This + # raises the possibility that the test could spuriously pass if the 'U'pdate + # notifications aren't grouped with the correct headers, but that's not what + # is being tested here. + expected_output = svntest.verify.UnorderedOutput( ["--- Merging r2 through r3 into '" + A_copy_path + "':\n", "U " + psi_copy_path + "\n", "--- Merging r4 through r7 into '" + A_copy_path + "':\n", @@ -18672,8 +18677,9 @@ def single_editor_drive_merge_notificati D_copy_path + "':\n", " U " + D_copy_path + "\n", "--- Eliding mergeinfo from '" + D_copy_path + "':\n", - " U " + D_copy_path + "\n"], - [], 'merge', sbox.repo_url + '/A', A_copy_path) + " U " + D_copy_path + "\n"]) + svntest.actions.run_and_verify_svn(None, expected_output, [], 'merge', + sbox.repo_url + '/A', A_copy_path) # r8 and r9 - Commit and do reverse subtree merge. sbox.simple_commit() @@ -18685,8 +18691,7 @@ def single_editor_drive_merge_notificati # Now try a reverse merge. There should only be one notification for # r7-5: sbox.simple_update() - svntest.actions.run_and_verify_svn( - None, + expected_output = svntest.verify.UnorderedOutput( ["--- Reverse-merging r7 through r5 into '" + A_copy_path + "':\n", "U " + beta_copy_path + "\n", "U " + omega_copy_path + "\n", @@ -18699,8 +18704,10 @@ def single_editor_drive_merge_notificati D_copy_path + "':\n", " U " + D_copy_path + "\n", "--- Eliding mergeinfo from '" + D_copy_path + "':\n", - " U " + D_copy_path + "\n"], - [], 'merge', '-r9:2', sbox.repo_url + '/A', A_copy_path) + " U " + D_copy_path + "\n"]) + svntest.actions.run_and_verify_svn(None, expected_output, [], 'merge', + '-r9:2', sbox.repo_url + '/A', + A_copy_path) ######################################################################## # Run the tests Modified: subversion/branches/fsfs-format7/subversion/tests/cmdline/patch_tests.py URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/tests/cmdline/patch_tests.py?rev=1453290&r1=1453289&r2=1453290&view=diff ============================================================================== --- subversion/branches/fsfs-format7/subversion/tests/cmdline/patch_tests.py (original) +++ subversion/branches/fsfs-format7/subversion/tests/cmdline/patch_tests.py Wed Mar 6 11:10:01 2013 @@ -970,10 +970,9 @@ def patch_add_new_dir(sbox): C_path = sbox.ospath('A/C') E_path = sbox.ospath('A/B/E') - svntest.actions.run_and_verify_svn("Deleting C failed", None, [], - 'rm', C_path) - svntest.actions.run_and_verify_svn("Deleting E failed", None, [], - 'rm', E_path) + + svntest.main.safe_rmtree(C_path) + svntest.main.safe_rmtree(E_path) svntest.main.file_write(patch_file_path, ''.join(unidiff_patch)) A_B_E_Y_new_path = sbox.ospath('A/B/E/Y/new') @@ -1000,13 +999,13 @@ def patch_add_new_dir(sbox): expected_status = svntest.actions.get_virginal_state(wc_dir, 1) expected_status.add({ - 'X' : Item(status='A ', wc_rev=0), - 'X/Y' : Item(status='A ', wc_rev=0), - 'X/Y/new' : Item(status='A ', wc_rev=0), - 'A/B/E' : Item(status='D ', wc_rev=1), - 'A/B/E/alpha': Item(status='D ', wc_rev=1), - 'A/B/E/beta': Item(status='D ', wc_rev=1), - 'A/C' : Item(status='D ', wc_rev=1), + 'X' : Item(status='A ', wc_rev=0), + 'X/Y' : Item(status='A ', wc_rev=0), + 'X/Y/new' : Item(status='A ', wc_rev=0), + 'A/B/E' : Item(status='! ', wc_rev=1), + 'A/B/E/alpha': Item(status='! ', wc_rev=1), + 'A/B/E/beta' : Item(status='! ', wc_rev=1), + 'A/C' : Item(status='! ', wc_rev=1), }) expected_skip = wc.State( Modified: subversion/branches/fsfs-format7/subversion/tests/cmdline/prop_tests.py URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/tests/cmdline/prop_tests.py?rev=1453290&r1=1453289&r2=1453290&view=diff ============================================================================== --- subversion/branches/fsfs-format7/subversion/tests/cmdline/prop_tests.py (original) +++ subversion/branches/fsfs-format7/subversion/tests/cmdline/prop_tests.py Wed Mar 6 11:10:01 2013 @@ -1785,11 +1785,10 @@ def rm_of_replaced_file(sbox): # which should have no properties. svntest.main.run_svn(None, 'rm', '--force', mu_path) - exit_code, output, errput = svntest.main.run_svn(None, - 'proplist', '-v', mu_path) - if output or errput: - raise svntest.Failure('no output/errors expected') - svntest.verify.verify_exit_code(None, exit_code, 0) + svntest.actions.run_and_verify_svn( + None, [], + 'svn: E200009.*some targets are not versioned.*', + 'proplist', '-v', mu_path) # Run it again, but ask for the pristine properties, which should # be mu's original props. Modified: subversion/branches/fsfs-format7/subversion/tests/cmdline/svndumpfilter_tests.py URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/tests/cmdline/svndumpfilter_tests.py?rev=1453290&r1=1453289&r2=1453290&view=diff ============================================================================== --- subversion/branches/fsfs-format7/subversion/tests/cmdline/svndumpfilter_tests.py (original) +++ subversion/branches/fsfs-format7/subversion/tests/cmdline/svndumpfilter_tests.py Wed Mar 6 11:10:01 2013 @@ -705,6 +705,67 @@ def dumpfilter_targets_expect_leading_sl os.close(fd) os.remove(targets_file) +@Issue(3681) +def drop_all_empty_revisions(sbox): + "drop all empty revisions except revision 0" + + dumpfile_location = os.path.join(os.path.dirname(sys.argv[0]), + 'svndumpfilter_tests_data', + 'empty_revisions.dump') + dump_contents = open(dumpfile_location).read() + + filtered_dumpfile, filtered_err = filter_and_return_output( + dump_contents, + 8192, # Set a sufficiently large bufsize to avoid a deadlock + "include", "branch1", + "--drop-all-empty-revs") + + expected_err = [ + "Including (and dropping empty revisions for) prefixes:\n", + " '/branch1'\n", + "\n", + "Revision 0 committed as 0.\n", + "Revision 1 skipped.\n", + "Revision 2 committed as 2.\n", + "Revision 3 skipped.\n", + "\n", + "Dropped 2 revisions.\n", + "\n"] + + svntest.verify.verify_outputs( + "Actual svndumpfilter stderr does not agree with expected stderr", + None, filtered_err, None, expected_err) + + # Test with --renumber-revs option. + filtered_dumpfile, filtered_err = filter_and_return_output( + dump_contents, + 8192, # Set a sufficiently large bufsize to avoid a deadlock + "include", "branch1", + "--drop-all-empty-revs", + "--renumber-revs") + + expected_err = [ + "Including (and dropping empty revisions for) prefixes:\n", + " '/branch1'\n", + "\n", + "Revision 0 committed as 0.\n", + "Revision 1 skipped.\n", + "Revision 2 committed as 1.\n", + "Revision 3 skipped.\n", + "\n", + "Dropped 2 revisions.\n", + "\n", + "Revisions renumbered as follows:\n", + " 3 => (dropped)\n", + " 2 => 1\n", + " 1 => (dropped)\n", + " 0 => 0\n", + "\n"] + + svntest.verify.verify_outputs( + "Actual svndumpfilter stderr does not agree with expected stderr", + None, filtered_err, None, expected_err) + ######################################################################## # Run the tests @@ -721,6 +782,7 @@ test_list = [ None, match_empty_prefix, accepts_deltas, dumpfilter_targets_expect_leading_slash_prefixes, + drop_all_empty_revisions, ] if __name__ == '__main__': Modified: subversion/branches/fsfs-format7/subversion/tests/cmdline/svntest/actions.py URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/tests/cmdline/svntest/actions.py?rev=1453290&r1=1453289&r2=1453290&view=diff ============================================================================== --- subversion/branches/fsfs-format7/subversion/tests/cmdline/svntest/actions.py (original) +++ subversion/branches/fsfs-format7/subversion/tests/cmdline/svntest/actions.py Wed Mar 6 11:10:01 2013 @@ -1785,7 +1785,7 @@ def run_and_validate_lock(path, username 'info','-R', path) - ### TODO: Leverage RegexOuput([...], match_all=True) here. + ### TODO: Leverage RegexOutput([...], match_all=True) here. # prepare the regexs to compare against token_re = re.compile(".*?Lock Token: opaquelocktoken:.*?", re.DOTALL) author_re = re.compile(".*?Lock Owner: %s\n.*?" % username, re.DOTALL) @@ -1808,9 +1808,17 @@ def _run_and_verify_resolve(cmd, expecte # TODO: verify that the status of PATHS changes accordingly. if len(args) == 0: args = expected_paths - expected_output = verify.UnorderedOutput([ - "Resolved conflicted state of '" + path + "'\n" for path in - expected_paths]) + expected_output = verify.AlternateOutput([ + verify.UnorderedOutput([ + "Resolved conflicted state of '" + path + "'\n" for path in + expected_paths]), + verify.UnorderedOutput([ + "Breaking move with source path '" + path + "'\n" for path in + expected_paths] + [ + "Resolved conflicted state of '" + path + "'\n" for path in + expected_paths]), + ], + match_all=False) run_and_verify_svn(None, expected_output, [], cmd, *args) Modified: subversion/branches/fsfs-format7/subversion/tests/cmdline/svntest/sandbox.py URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/tests/cmdline/svntest/sandbox.py?rev=1453290&r1=1453289&r2=1453290&view=diff ============================================================================== --- subversion/branches/fsfs-format7/subversion/tests/cmdline/svntest/sandbox.py (original) +++ subversion/branches/fsfs-format7/subversion/tests/cmdline/svntest/sandbox.py Wed Mar 6 11:10:01 2013 @@ -37,6 +37,7 @@ class Sandbox: a test to operate within.""" dependents = None + tmp_dir = None def __init__(self, module, idx): self.test_paths = [] @@ -45,10 +46,6 @@ class Sandbox: # This flag is set to True by build() and returned by is_built() self._is_built = False - # Create an empty directory for temporary files - self.tmp_dir = self.add_wc_path('tmp', remove=True) - os.mkdir(self.tmp_dir) - def _set_name(self, name, read_only=False): """A convenience method for renaming a sandbox, useful when working with multiple repositories in the same unit test.""" @@ -159,6 +156,11 @@ class Sandbox: """Get a stable name for a temporary file that will be removed after running the test""" + if not self.tmp_dir: + # Create an empty directory for temporary files + self.tmp_dir = self.add_wc_path('tmp', remove=True) + os.mkdir(self.tmp_dir) + self.tempname_offs = self.tempname_offs + 1 return os.path.join(self.tmp_dir, '%s-%s' % (prefix, self.tempname_offs)) Modified: subversion/branches/fsfs-format7/subversion/tests/cmdline/svntest/verify.py URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/tests/cmdline/svntest/verify.py?rev=1453290&r1=1453289&r2=1453290&view=diff ============================================================================== --- subversion/branches/fsfs-format7/subversion/tests/cmdline/svntest/verify.py (original) +++ subversion/branches/fsfs-format7/subversion/tests/cmdline/svntest/verify.py Wed Mar 6 11:10:01 2013 @@ -315,6 +315,29 @@ class UnorderedRegexListOutput(ExpectedO label + ' (regexp) (unordered)', label) +class AlternateOutput(ExpectedOutput): + """Matches any one of a list of ExpectedOutput instances. + """ + + def __init__(self, expected, match_all=True): + "EXPECTED is a list of ExpectedOutput instances." + assert isinstance(expected, list) and expected != [] + assert all(isinstance(e, ExpectedOutput) for e in expected) + ExpectedOutput.__init__(self, expected) + + def matches(self, actual): + assert actual is not None + for e in self.expected: + if e.matches(actual): + return True + return False + + def display_differences(self, message, label, actual): + # For now, just display differences against the first alternative. + e = self.expected[0] + e.display_differences(message, label, actual) + + ###################################################################### # Displaying expected and actual output @@ -335,6 +358,10 @@ def display_lines_diff(expected, actual, and ACTUAL (labeled with ACTUAL_LABEL). Each of EXPECTED and ACTUAL is a string or a list of strings. """ + if not isinstance(expected, list): + expected = [expected] + if not isinstance(actual, list): + actual = [actual] logger.warn('DIFF ' + expected_label + ':') for x in unified_diff(expected, actual, fromfile='EXPECTED ' + expected_label, Modified: subversion/branches/fsfs-format7/subversion/tests/cmdline/switch_tests.py URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/tests/cmdline/switch_tests.py?rev=1453290&r1=1453289&r2=1453290&view=diff ============================================================================== --- subversion/branches/fsfs-format7/subversion/tests/cmdline/switch_tests.py (original) +++ subversion/branches/fsfs-format7/subversion/tests/cmdline/switch_tests.py Wed Mar 6 11:10:01 2013 @@ -2933,6 +2933,42 @@ def switch_to_spaces(sbox): repo_url + '/A%20with more%20spaces', None, None, expected_status) +def switch_across_replacement(sbox): + "switch across a node replacement" + sbox.build() + os.chdir(sbox.wc_dir) + sbox.wc_dir = '' + + # replacement + sbox.simple_rm('A/mu') + sbox.simple_append('A/mu', "This is the file 'mu'.\n", truncate=True) + sbox.simple_add('A/mu') + sbox.simple_commit() # r2 + + # When 'switch' of a dir brings in a replacement of a child file with no + # textual difference and ignoring ancestry, the switch doesn't report any + # incoming change at all, (and so won't raise a tree conflict if there is + # a local mod). 'update' on the other hand does report the replacement + # as expected. + + # This test FAILs when using a Subversion 1.0-1.7 svnserve. + + expected_output = svntest.wc.State(sbox.wc_dir, { + 'A/mu' : Item(status='A ', prev_status='D '), + }) + svntest.actions.run_and_verify_update(sbox.wc_dir, + expected_output, None, None, + None, None, None, None, None, False, + '-r1') + svntest.actions.run_and_verify_update(sbox.wc_dir, + expected_output, None, None, + None, None, None, None, None, False, + '-r2') + svntest.actions.run_and_verify_switch(sbox.wc_dir, sbox.ospath('A'), '^/A', + expected_output, None, None, + None, None, None, None, None, False, + '-r1') + ######################################################################## # Run the tests @@ -2974,6 +3010,7 @@ test_list = [ None, up_to_old_rev_with_subtree_switched_to_root, different_node_kind, switch_to_spaces, + switch_across_replacement, ] if __name__ == '__main__': Modified: subversion/branches/fsfs-format7/subversion/tests/cmdline/trans_tests.py URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/tests/cmdline/trans_tests.py?rev=1453290&r1=1453289&r2=1453290&view=diff ============================================================================== --- subversion/branches/fsfs-format7/subversion/tests/cmdline/trans_tests.py (original) +++ subversion/branches/fsfs-format7/subversion/tests/cmdline/trans_tests.py Wed Mar 6 11:10:01 2013 @@ -25,7 +25,7 @@ ###################################################################### # General modules -import os, re, logging +import os, re, logging, sys logger = logging.getLogger() @@ -883,6 +883,76 @@ def props_only_file_update(sbox): logger.warn('Temporary files leftover: %s', (', '.join(temps),)) raise svntest.Failure +@XFail() +@Issues(4327) +def autoprops_inconsistent_eol(sbox): + "able to handle inconsistent eols on add" + + sbox.build(read_only = True) + wc_dir = sbox.wc_dir + + text = 'line with NL\n' + \ + 'line with CR\r' + \ + 'line with CRLF\r\n' + \ + 'line with LFCR (or is that not a line? ;-)\n\r' + + # Compensate for python smartness + if sys.platform == 'win32': + expected_text = text.replace('\r\n', '\n') + else: + expected_text = text + + sbox.simple_add_text(text, 'add.c') + sbox.simple_add_text(text, 'add-force.c') + + svntest.actions.run_and_verify_svn(None, None, '.*inconsistent newlines.*', + 'ps', 'svn:eol-style', 'native', + sbox.ospath('add.c')) + + svntest.actions.run_and_verify_svn(None, None, [], + 'ps', 'svn:eol-style', 'native', '--force', + sbox.ospath('add.c')) + + expected_disk = svntest.main.greek_state.copy() + + expected_disk.add({ + 'add-force.c' : Item(contents=expected_text), + 'add.c' : Item(contents=expected_text), + }) + + # Verify that both add and add-force haven't been changed + svntest.actions.verify_disk(wc_dir, expected_disk) + + sbox.simple_propset('svn:auto-props', '*.c = svn:eol-style=native', '') + + + svntest.main.file_write(sbox.ospath('auto.c'), text, mode='wb') + + expected_output = ['A %s\n' % sbox.ospath('auto.c')] + + # Fails with svn: E200009: File '.*auto.c' has inconsistent newlines + svntest.actions.run_and_verify_svn(None, expected_output, + [], 'add', sbox.ospath('auto.c')) + +@XFail() +@Issues(4327) +def autoprops_inconsistent_mime(sbox): + "able to handle inconsistent mime on add" + + sbox.build(read_only = True) + + sbox.simple_propset('svn:auto-props', + '*.c = svn:eol-style=native\n' + 'c.* = svn:mime-type=application/octet-stream', '') + + sbox.simple_append('c.iota.c', '') + + expected_output = ['A %s\n' % sbox.ospath('c.iota.c')] + + # Fails with svn: E200009: File '.*c.iota.c' has binary mime type property + svntest.actions.run_and_verify_svn(None, expected_output, + [], 'add', sbox.ospath('c.iota.c')) + ######################################################################## # Run the tests @@ -902,6 +972,8 @@ test_list = [ None, propset_commit_checkout_nocrash, propset_revert_noerror, props_only_file_update, + autoprops_inconsistent_eol, + autoprops_inconsistent_mime, ] if __name__ == '__main__': Modified: subversion/branches/fsfs-format7/subversion/tests/cmdline/tree_conflict_tests.py URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/tests/cmdline/tree_conflict_tests.py?rev=1453290&r1=1453289&r2=1453290&view=diff ============================================================================== --- subversion/branches/fsfs-format7/subversion/tests/cmdline/tree_conflict_tests.py (original) +++ subversion/branches/fsfs-format7/subversion/tests/cmdline/tree_conflict_tests.py Wed Mar 6 11:10:01 2013 @@ -49,6 +49,10 @@ Issue = svntest.testcase.Issue_deco Wimp = svntest.testcase.Wimp_deco Item = svntest.wc.StateItem AnyOutput = svntest.verify.AnyOutput +RegexOutput = svntest.verify.RegexOutput +RegexListOutput = svntest.verify.RegexListOutput +UnorderedOutput = svntest.verify.UnorderedOutput +AlternateOutput = svntest.verify.AlternateOutput logger = logging.getLogger() @@ -277,12 +281,15 @@ d_moves = [ ] f_rpls = [ - #( create_f, ['fD','fa','fA'] ), # replacement - not yet - #( create_f, ['fM','fa','fC'] ), # don't test all combinations, just because it's slow + # Don't test all possible combinations, just because it's slow + ( create_f, ['fD','fa','fA'] ), + ( create_f, ['fM','fC'] ), ] d_rpls = [ - #( create_d, ['dD','dA'] ), # replacement - not yet - #( create_d, ['dM','dC'] ), # don't test all combinations, just because it's slow + # We're not testing directory replacements yet. + # Don't test all possible combinations, just because it's slow + #( create_d, ['dD','dA'] ), + #( create_d, ['dM','dC'] ), # Note that directory replacement differs from file replacement: the # schedule-delete dir is still on disk and is re-used for the re-addition. ] @@ -373,7 +380,7 @@ def set_up_repos(wc_dir, br_dir, scenari # the target branch before applying the INCOMING_SCENARIOS. def ensure_tree_conflict(sbox, operation, incoming_scenarios, localmod_scenarios, - commit_local_mods): + commit_local_mods=False): sbox.build() wc_dir = sbox.wc_dir @@ -464,7 +471,7 @@ def ensure_tree_conflict(sbox, operation elif operation == 'merge': logger.debug("--- Merging") run_and_verify_svn(None, expected_stdout, [], - 'merge', '--ignore-ancestry', + 'merge', '--allow-mixed-revisions', '-r', str(source_left_rev) + ':' + str(source_right_rev), source_url, target_path) @@ -495,9 +502,17 @@ def ensure_tree_conflict(sbox, operation run_and_verify_commit(".", None, None, ".*conflict.*", victim_path) logger.debug("--- Checking that 'status' reports the conflict") - expected_stdout = svntest.verify.RegexOutput("^......C.* " + - re.escape(victim_path) + "$", - match_all=False) + expected_stdout = AlternateOutput([ + RegexListOutput([ + "^......C.* " + re.escape(victim_path) + "$", + "^ > .* upon " + operation] + + svntest.main.summary_of_conflicts(tree_conflicts=1)), + RegexListOutput([ + "^......C.* " + re.escape(victim_path) + "$", + "^ > moved to .*", + "^ > .* upon " + operation] + + svntest.main.summary_of_conflicts(tree_conflicts=1)) + ]) run_and_verify_svn(None, expected_stdout, [], 'status', victim_path) @@ -534,29 +549,6 @@ def ensure_tree_conflict(sbox, operation #---------------------------------------------------------------------- -# The main entry points for testing a set of scenarios. - -# Test 'update' and/or 'switch' -# See test_wc_merge() for arguments. -def test_tc_up_sw(sbox, incoming_scen, wc_scen): - sbox2 = sbox.clone_dependent() - ensure_tree_conflict(sbox, 'update', incoming_scen, wc_scen, False) - ensure_tree_conflict(sbox2, 'switch', incoming_scen, wc_scen, False) - -# Test 'merge' -# INCOMING_SCEN is a list of scenarios describing the incoming changes to apply. -# BR_SCEN is a list of scenarios describing how the local branch has -# been modified relative to the merge-left source. -# WC_SCEN is a list of scenarios describing the local WC mods. -# One of BR_SCEN or WC_SCEN must be given but not both. -def test_tc_merge(sbox, incoming_scen, br_scen=None, wc_scen=None): - if br_scen: - ensure_tree_conflict(sbox, 'merge', incoming_scen, br_scen, True) - else: - ensure_tree_conflict(sbox, 'merge', incoming_scen, wc_scen, False) - -#---------------------------------------------------------------------- - # Tests for update/switch affecting a file, where the incoming change # conflicts with a scheduled change in the WC. # @@ -564,7 +556,11 @@ def test_tc_merge(sbox, incoming_scen, b def up_sw_file_mod_onto_del(sbox): "up/sw file: modify onto del/rpl" - test_tc_up_sw(sbox, f_mods, f_dels + f_rpls) + sbox2 = sbox.clone_dependent() + ensure_tree_conflict(sbox, 'update', f_mods, + f_dels + f_rpls) + ensure_tree_conflict(sbox2, 'switch', f_mods, + f_dels + f_rpls) # Note: See UC1 in notes/tree-conflicts/use-cases.txt. def up_sw_file_del_onto_mod(sbox): @@ -574,17 +570,27 @@ def up_sw_file_del_onto_mod(sbox): # ### OR (see Nico's email <>): # schedule-delete but leave F on disk (can only apply with # text-mod; prop-mod can't be preserved in this way) - test_tc_up_sw(sbox, f_dels + f_moves + f_rpls, f_mods) + sbox2 = sbox.clone_dependent() + ensure_tree_conflict(sbox, 'update', f_dels + f_moves + f_rpls, + f_mods) + ensure_tree_conflict(sbox2, 'switch', f_dels + f_moves + f_rpls, + f_mods) # Note: See UC2 in notes/tree-conflicts/use-cases.txt. def up_sw_file_del_onto_del(sbox): "up/sw file: del/rpl/mv onto del/rpl/mv" - test_tc_up_sw(sbox, f_dels + f_moves + f_rpls, f_dels + f_rpls) + sbox2 = sbox.clone_dependent() + ensure_tree_conflict(sbox, 'update', f_dels + f_moves + f_rpls, + f_dels + f_rpls) + ensure_tree_conflict(sbox2, 'switch', f_dels + f_moves + f_rpls, + f_dels + f_rpls) # Note: See UC3 in notes/tree-conflicts/use-cases.txt. def up_sw_file_add_onto_add(sbox): "up/sw file: add onto add" - test_tc_up_sw(sbox, f_adds, f_adds) + sbox2 = sbox.clone_dependent() + ensure_tree_conflict(sbox, 'update', f_adds, f_adds) + ensure_tree_conflict(sbox2, 'switch', f_adds, f_adds) #---------------------------------------------------------------------- @@ -594,17 +600,29 @@ def up_sw_file_add_onto_add(sbox): def up_sw_dir_mod_onto_del(sbox): "up/sw dir: modify onto del/rpl/mv" # WC state: any (D necessarily exists; children may have any state) - test_tc_up_sw(sbox, d_mods, d_dels + d_rpls) + sbox2 = sbox.clone_dependent() + ensure_tree_conflict(sbox, 'update', d_mods, + d_dels + d_rpls) + ensure_tree_conflict(sbox2, 'switch', d_mods, + d_dels + d_rpls) def up_sw_dir_del_onto_mod(sbox): "up/sw dir: del/rpl/mv onto modify" # WC state: any (D necessarily exists; children may have any state) - test_tc_up_sw(sbox, d_dels + d_moves + d_rpls, d_mods) + sbox2 = sbox.clone_dependent() + ensure_tree_conflict(sbox, 'update', d_dels + d_moves + d_rpls, + d_mods) + ensure_tree_conflict(sbox2, 'switch', d_dels + d_moves + d_rpls, + d_mods) def up_sw_dir_del_onto_del(sbox): "up/sw dir: del/rpl/mv onto del/rpl/mv" # WC state: any (D necessarily exists; children may have any state) - test_tc_up_sw(sbox, d_dels + d_moves + d_rpls, d_dels + d_rpls) + sbox2 = sbox.clone_dependent() + ensure_tree_conflict(sbox, 'update', d_dels + d_moves + d_rpls, + d_dels + d_rpls) + ensure_tree_conflict(sbox2, 'switch', d_dels + d_moves + d_rpls, + d_dels + d_rpls) # This is currently set as XFail over ra_dav because it hits # issue #3314 'DAV can overwrite directories during copy' @@ -641,7 +659,9 @@ def up_sw_dir_del_onto_del(sbox): def up_sw_dir_add_onto_add(sbox): "up/sw dir: add onto add" # WC state: as scheduled (no obstruction) - test_tc_up_sw(sbox, d_adds, d_adds) + sbox2 = sbox.clone_dependent() + ensure_tree_conflict(sbox, 'update', d_adds, d_adds) + ensure_tree_conflict(sbox2, 'switch', d_adds, d_adds) #---------------------------------------------------------------------- @@ -651,31 +671,38 @@ def up_sw_dir_add_onto_add(sbox): def merge_file_mod_onto_not_file(sbox): "merge file: modify onto not-file" sbox2 = sbox.clone_dependent() - test_tc_merge(sbox, f_mods, br_scen = f_dels + f_moves + f_rpl_d) - test_tc_merge(sbox2, f_mods, wc_scen = f_dels + f_moves) + # Test merges where the "local mods" are committed to the target branch. + ensure_tree_conflict(sbox, 'merge', f_mods, f_dels + f_moves + f_rpl_d, + commit_local_mods=True) + # Test merges where the "local mods" are uncommitted mods in the WC. + ensure_tree_conflict(sbox2, 'merge', f_mods, f_dels + f_moves) # Note: See UC4 in notes/tree-conflicts/use-cases.txt. def merge_file_del_onto_not_same(sbox): "merge file: del/rpl/mv onto not-same" sbox2 = sbox.clone_dependent() - test_tc_merge(sbox, f_dels + f_moves + f_rpls, br_scen = f_mods) - test_tc_merge(sbox2, f_dels + f_moves + f_rpls, wc_scen = f_mods) + ensure_tree_conflict(sbox, 'merge', f_dels + f_moves + f_rpls, f_mods, + commit_local_mods=True) + ensure_tree_conflict(sbox2, 'merge', f_dels + f_moves + f_rpls, f_mods) # Note: See UC5 in notes/tree-conflicts/use-cases.txt. def merge_file_del_onto_not_file(sbox): "merge file: del/rpl/mv onto not-file" sbox2 = sbox.clone_dependent() - test_tc_merge(sbox, f_dels + f_moves + f_rpls, - br_scen = f_dels + f_moves + f_rpl_d) - test_tc_merge(sbox2, f_dels + f_moves + f_rpls, - wc_scen = f_dels + f_moves) + ensure_tree_conflict(sbox, 'merge', f_dels + f_moves + f_rpls, + f_dels + f_moves + f_rpl_d, + commit_local_mods=True) + ensure_tree_conflict(sbox2, 'merge', f_dels + f_moves + f_rpls, + f_dels + f_moves) # Note: See UC6 in notes/tree-conflicts/use-cases.txt. def merge_file_add_onto_not_none(sbox): "merge file: add onto not-none" sbox2 = sbox.clone_dependent() - test_tc_merge(sbox, f_adds, br_scen = f_adds) ### + d_adds (at path "F") - test_tc_merge(sbox2, f_adds, wc_scen = f_adds) ### + d_adds (at path "F") + ensure_tree_conflict(sbox, 'merge', f_adds, f_adds, + commit_local_mods=True) + ensure_tree_conflict(sbox2, 'merge', f_adds, f_adds) + # TODO: Also test directory adds at path "F"? #---------------------------------------------------------------------- @@ -685,28 +712,35 @@ def merge_file_add_onto_not_none(sbox): def merge_dir_mod_onto_not_dir(sbox): "merge dir: modify onto not-dir" sbox2 = sbox.clone_dependent() - test_tc_merge(sbox, d_mods, br_scen = d_dels + d_moves + d_rpl_f) - test_tc_merge(sbox2, d_mods, wc_scen = d_dels + d_moves) + ensure_tree_conflict(sbox, 'merge', d_mods, d_dels + d_moves + d_rpl_f, + commit_local_mods=True) + ensure_tree_conflict(sbox2, 'merge', d_mods, d_dels + d_moves) # Test for issue #3150 'tree conflicts with directories as victims'. @Issue(3150) def merge_dir_del_onto_not_same(sbox): "merge dir: del/rpl/mv onto not-same" sbox2 = sbox.clone_dependent() - test_tc_merge(sbox, d_dels + d_moves + d_rpls, br_scen = d_mods) - test_tc_merge(sbox2, d_dels + d_moves + d_rpls, wc_scen = d_mods) + ensure_tree_conflict(sbox, 'merge', d_dels + d_moves + d_rpls, d_mods, + commit_local_mods=True) + ensure_tree_conflict(sbox2, 'merge', d_dels + d_moves + d_rpls, d_mods) def merge_dir_del_onto_not_dir(sbox): "merge dir: del/rpl/mv onto not-dir" sbox2 = sbox.clone_dependent() - test_tc_merge(sbox, d_dels + d_moves + d_rpls, br_scen = d_dels + d_moves + d_rpl_f) - test_tc_merge(sbox2, d_dels + d_moves + d_rpls, wc_scen = d_dels + d_moves) + ensure_tree_conflict(sbox, 'merge', d_dels + d_moves + d_rpls, + d_dels + d_moves + d_rpl_f, + commit_local_mods=True) + ensure_tree_conflict(sbox2, 'merge', d_dels + d_moves + d_rpls, + d_dels + d_moves) def merge_dir_add_onto_not_none(sbox): "merge dir: add onto not-none" sbox2 = sbox.clone_dependent() - test_tc_merge(sbox, d_adds, br_scen = d_adds) ### + f_adds (at path "D") - test_tc_merge(sbox2, d_adds, wc_scen = d_adds) ### + f_adds (at path "D") + ensure_tree_conflict(sbox, 'merge', d_adds, d_adds, + commit_local_mods=True) + ensure_tree_conflict(sbox2, 'merge', d_adds, d_adds) + # TODO: also try with file adds at path "D"? #----------------------------------------------------------------------