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 CB8EEFC28 for ; Fri, 10 May 2013 15:00:52 +0000 (UTC) Received: (qmail 68788 invoked by uid 500); 10 May 2013 15:00:52 -0000 Delivered-To: apmail-subversion-commits-archive@subversion.apache.org Received: (qmail 68769 invoked by uid 500); 10 May 2013 15:00:52 -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 68752 invoked by uid 99); 10 May 2013 15:00:52 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 10 May 2013 15:00:52 +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; Fri, 10 May 2013 15:00:49 +0000 Received: from eris.apache.org (localhost [127.0.0.1]) by eris.apache.org (Postfix) with ESMTP id BE0232388C6A; Fri, 10 May 2013 14:59:27 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r1481041 [35/38] - in /subversion/branches/master-passphrase: ./ build/ build/ac-macros/ build/generator/ build/generator/templates/ contrib/client-side/svncopy/ contrib/hook-scripts/ contrib/server-side/fsfsfixer/ contrib/server-side/fsfsf... Date: Fri, 10 May 2013 14:58:56 -0000 To: commits@subversion.apache.org From: cmpilato@apache.org X-Mailer: svnmailer-1.0.8-patched Message-Id: <20130510145927.BE0232388C6A@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Modified: subversion/branches/master-passphrase/subversion/tests/cmdline/move_tests.py URL: http://svn.apache.org/viewvc/subversion/branches/master-passphrase/subversion/tests/cmdline/move_tests.py?rev=1481041&r1=1481040&r2=1481041&view=diff ============================================================================== --- subversion/branches/master-passphrase/subversion/tests/cmdline/move_tests.py (original) +++ subversion/branches/master-passphrase/subversion/tests/cmdline/move_tests.py Fri May 10 14:58:47 2013 @@ -95,14 +95,14 @@ def build_incoming_changes_file(sbox, so sbox.simple_propdel("foo", dest) sbox.simple_commit(message="Delete property on destination of moved file") - # r13 = Remove destination again (not needed for any test just cleanup). + # r13 = Remove destination again (not needed for any test just cleanup). sbox.simple_rm(dest) sbox.simple_commit(message="Remove destination (cleanup)") # r14 = Add property on source of moved file. sbox.simple_propset("foo", "bar", source) sbox.simple_commit(message="Add property on source of moved file") - + # r15 = Modify property on source of moved file. sbox.simple_propset("foo", "baz", source) sbox.simple_commit(message="Modify property on source of moved file") @@ -141,11 +141,11 @@ def move_file_test(sbox, source, dest, m source_path = sbox.ospath(source) dest_path = sbox.ospath(dest) - # Deal with if there's no resolves key, as in we're not going to + # Deal with if there's no resolves key, as in we're not going to # do a resolve. if not 'resolves' in test or not test['resolves']: test['resolves'] = {None: None} - + # Do the test for every type of resolve provided. for resolve_accept in test['resolves'].keys(): @@ -157,7 +157,7 @@ def move_file_test(sbox, source, dest, m # execute the move move_func(test['start_rev']) - # update to end_rev, which will create a conflict + # update to end_rev, which will create a conflict # TODO: Limit the property checks to only when we're doing something with # properties. svntest.actions.run_and_verify_update(wc_dir, test['up_output'], @@ -177,7 +177,7 @@ def move_file_test(sbox, source, dest, m if not 'output' in resolve: resolve['output'] = None if not 'error' in resolve: - resolve['error'] = [] + resolve['error'] = [] if not 'disk' in resolve: resolve['disk'] = None if 'revert_paths' in resolve: @@ -197,7 +197,7 @@ def move_file_test(sbox, source, dest, m if resolve['disk']: svntest.actions.verify_disk(wc_dir, resolve['disk'], True) - # revert to preprare for the next test + # revert to preprare for the next test svntest.actions.run_and_verify_revert(revert_paths, '-R', wc_dir) # tests is an array of test dictionaries that move_file_test above will take @@ -240,11 +240,11 @@ def build_simple_file_move_tests(sbox, s mc['output'] = svntest.verify.ExpectedOutput( "Resolved conflicted state of '%s'\n" % source_path, match_all=False ) - mc['status'] = svntest.actions.get_virginal_state(wc_dir, test['end_rev']) + mc['status'] = svntest.actions.get_virginal_state(wc_dir, test['end_rev']) mc['status'].tweak(source, status='D ', moved_to=dest) mc['status'].add({dest: Item(status='A ', moved_from=source, copied='+', wc_rev='-')}) - mc['disk'] = test['up_disk'].copy() + mc['disk'] = test['up_disk'].copy() mc['disk'].tweak(dest, contents="This is the file 'lambda'.\nmodified\n") # theirs-conflict doesn't work tc = {} @@ -259,10 +259,10 @@ def build_simple_file_move_tests(sbox, s "Resolved conflicted state of '%s'\n" % source_path, ] ) - working['status'] = svntest.actions.get_virginal_state(wc_dir, test['end_rev']) + working['status'] = svntest.actions.get_virginal_state(wc_dir, test['end_rev']) working['status'].tweak(source, status='D ') working['status'].add({dest: Item(status='A ', copied='+', wc_rev='-')}) - working['disk'] = test['up_disk'] + working['disk'] = test['up_disk'] test['resolves'] = {'mine-conflict': mc, 'theirs-conflict': tc, 'working': working} test['revert_paths'] = [source_path, dest_path] @@ -301,7 +301,7 @@ def build_simple_file_move_tests(sbox, s "Resolved conflicted state of '%s'\n" % source_path, match_all=False ) # move is broken now - working['status'] = svntest.actions.get_virginal_state(wc_dir, test['end_rev']) + working['status'] = svntest.actions.get_virginal_state(wc_dir, test['end_rev']) working['status'].add({dest: Item(status='A ', copied='+', wc_rev='-')}) working['status'].remove(source) working['disk'] = test['up_disk'] @@ -346,7 +346,7 @@ def build_simple_file_move_tests(sbox, s "Resolved conflicted state of '%s'\n" % source_path, match_all=False ) # XXX: Not sure this status is really correct here - working['status'] = svntest.actions.get_virginal_state(wc_dir, test['end_rev']) + working['status'] = svntest.actions.get_virginal_state(wc_dir, test['end_rev']) working['status'].tweak(source, status='! ') working['status'].add({dest: Item(status='A ', copied='+', wc_rev='-')}) working['disk'] = test['up_disk'] @@ -389,7 +389,7 @@ def build_simple_file_move_tests(sbox, s "Resolved conflicted state of '%s'\n" % dest_path, match_all=False ) # working converts the move into a replacement - working['status'] = svntest.actions.get_virginal_state(wc_dir, test['end_rev']) + working['status'] = svntest.actions.get_virginal_state(wc_dir, test['end_rev']) working['status'].tweak(source, status='D ', moved_to=dest) working['status'].add({dest: Item(status='R ', moved_from=source, copied='+', wc_rev='-')}) @@ -435,7 +435,7 @@ def build_simple_file_move_tests(sbox, s "Resolved conflicted state of '%s'\n" % dest_path, match_all=False ) # working converts the move into a replacement - working['status'] = svntest.actions.get_virginal_state(wc_dir, test['end_rev']) + working['status'] = svntest.actions.get_virginal_state(wc_dir, test['end_rev']) working['status'].tweak(source, status='D ', moved_to=dest) working['status'].add({dest: Item(status='R ', moved_from=source, copied='+', wc_rev='-')}) @@ -503,7 +503,7 @@ def build_simple_file_move_tests(sbox, s "Resolved conflicted state of '%s'\n" % dest_path, match_all=False ) # working converts the move into a replacement - working['status'] = svntest.actions.get_virginal_state(wc_dir, test['end_rev']) + working['status'] = svntest.actions.get_virginal_state(wc_dir, test['end_rev']) working['status'].tweak(source, status='D ', moved_to=dest) working['status'].add({dest: Item(status='R ', moved_from=source, copied='+', wc_rev='-')}) @@ -547,7 +547,7 @@ def build_simple_file_move_tests(sbox, s "Resolved conflicted state of '%s'\n" % dest_path, match_all=False ) # working converts the move into a replacement - working['status'] = svntest.actions.get_virginal_state(wc_dir, test['end_rev']) + working['status'] = svntest.actions.get_virginal_state(wc_dir, test['end_rev']) working['status'].tweak(source, status='D ', moved_to=dest) working['status'].add({dest: Item(status='R ', moved_from=source, copied='+', wc_rev='-')}) @@ -560,7 +560,7 @@ def build_simple_file_move_tests(sbox, s # move and update with incoming property addition to dest (r7-10) test = {} test['start_rev'] = 7 - test['end_rev'] = 10 + test['end_rev'] = 10 test['start_output'] = None test['start_disk'] = None test['start_status'] = None @@ -591,7 +591,7 @@ def build_simple_file_move_tests(sbox, s "Resolved conflicted state of '%s'\n" % dest_path, match_all=False ) # working converts the move into a replacement - working['status'] = svntest.actions.get_virginal_state(wc_dir, test['end_rev']) + working['status'] = svntest.actions.get_virginal_state(wc_dir, test['end_rev']) working['status'].tweak(source, status='D ', moved_to=dest) working['status'].add({dest: Item(status='R ', moved_from=source, copied='+', wc_rev='-')}) @@ -604,7 +604,7 @@ def build_simple_file_move_tests(sbox, s # move and update with incoming property modification to dest (r7-11) test = {} test['start_rev'] = 7 - test['end_rev'] = 11 + test['end_rev'] = 11 test['start_output'] = None test['start_disk'] = None test['start_status'] = None @@ -635,7 +635,7 @@ def build_simple_file_move_tests(sbox, s "Resolved conflicted state of '%s'\n" % dest_path, match_all=False ) # working converts the move into a replacement - working['status'] = svntest.actions.get_virginal_state(wc_dir, test['end_rev']) + working['status'] = svntest.actions.get_virginal_state(wc_dir, test['end_rev']) working['status'].tweak(source, status='D ', moved_to=dest) working['status'].add({dest: Item(status='R ', moved_from=source, copied='+', wc_rev='-')}) @@ -648,7 +648,7 @@ def build_simple_file_move_tests(sbox, s # move and update with incoming property deletion to dest (r7-12) test = {} test['start_rev'] = 7 - test['end_rev'] = 12 + test['end_rev'] = 12 test['start_output'] = None test['start_disk'] = None test['start_status'] = None @@ -679,7 +679,7 @@ def build_simple_file_move_tests(sbox, s "Resolved conflicted state of '%s'\n" % dest_path, match_all=False ) # working converts the move into a replacement - working['status'] = svntest.actions.get_virginal_state(wc_dir, test['end_rev']) + working['status'] = svntest.actions.get_virginal_state(wc_dir, test['end_rev']) working['status'].tweak(source, status='D ', moved_to=dest) working['status'].add({dest: Item(status='R ', moved_from=source, copied='+', wc_rev='-')}) @@ -692,7 +692,7 @@ def build_simple_file_move_tests(sbox, s # move and update with incoming property addition to source (r13-14) test = {} test['start_rev'] = 13 - test['end_rev'] = 14 + test['end_rev'] = 14 test['start_output'] = None test['start_disk'] = None test['start_status'] = None @@ -714,7 +714,7 @@ def build_simple_file_move_tests(sbox, s mc['output'] = svntest.verify.ExpectedOutput( "Resolved conflicted state of '%s'\n" % source_path, match_all=False ) - mc['status'] = svntest.actions.get_virginal_state(wc_dir, test['end_rev']) + mc['status'] = svntest.actions.get_virginal_state(wc_dir, test['end_rev']) mc['status'].tweak(source, status='D ', moved_to=dest) mc['status'].add({dest: Item(status='A ', moved_from=source, copied='+', wc_rev='-')}) @@ -733,7 +733,7 @@ def build_simple_file_move_tests(sbox, s ] ) # XXX: working breaks the move? Is that right? - working['status'] = svntest.actions.get_virginal_state(wc_dir, test['end_rev']) + working['status'] = svntest.actions.get_virginal_state(wc_dir, test['end_rev']) working['status'].tweak(source, status='D ') working['status'].add({dest: Item(status='A ', copied='+', wc_rev='-')}) working['disk'] = test['up_disk'] @@ -745,7 +745,7 @@ def build_simple_file_move_tests(sbox, s # move and update with incoming property modification to source (r14-15) test = {} test['start_rev'] = 14 - test['end_rev'] = 15 + test['end_rev'] = 15 test['start_output'] = None test['start_disk'] = None test['start_status'] = None @@ -767,7 +767,7 @@ def build_simple_file_move_tests(sbox, s mc['output'] = svntest.verify.ExpectedOutput( "Resolved conflicted state of '%s'\n" % source_path, match_all=False ) - mc['status'] = svntest.actions.get_virginal_state(wc_dir, test['end_rev']) + mc['status'] = svntest.actions.get_virginal_state(wc_dir, test['end_rev']) mc['status'].tweak(source, status='D ', moved_to=dest) mc['status'].add({dest: Item(status='A ', moved_from=source, copied='+', wc_rev='-')}) @@ -786,7 +786,7 @@ def build_simple_file_move_tests(sbox, s ] ) # XXX: working breaks the move? Is that right? - working['status'] = svntest.actions.get_virginal_state(wc_dir, test['end_rev']) + working['status'] = svntest.actions.get_virginal_state(wc_dir, test['end_rev']) working['status'].tweak(source, status='D ') working['status'].add({dest: Item(status='A ', copied='+', wc_rev='-')}) working['disk'] = test['up_disk'] @@ -798,7 +798,7 @@ def build_simple_file_move_tests(sbox, s # move and update with incoming property deletion to source (r15-16) test = {} test['start_rev'] = 15 - test['end_rev'] = 16 + test['end_rev'] = 16 test['start_output'] = None test['start_disk'] = None test['start_status'] = None @@ -820,7 +820,7 @@ def build_simple_file_move_tests(sbox, s mc['output'] = svntest.verify.ExpectedOutput( "Resolved conflicted state of '%s'\n" % source_path, match_all=False ) - mc['status'] = svntest.actions.get_virginal_state(wc_dir, test['end_rev']) + mc['status'] = svntest.actions.get_virginal_state(wc_dir, test['end_rev']) mc['status'].tweak(source, status='D ', moved_to=dest) mc['status'].add({dest: Item(status='A ', moved_from=source, copied='+', wc_rev='-')}) @@ -839,7 +839,7 @@ def build_simple_file_move_tests(sbox, s ] ) # XXX: working breaks the move? Is that right? - working['status'] = svntest.actions.get_virginal_state(wc_dir, test['end_rev']) + working['status'] = svntest.actions.get_virginal_state(wc_dir, test['end_rev']) working['status'].tweak(source, status='D ') working['status'].add({dest: Item(status='A ', copied='+', wc_rev='-')}) working['disk'] = test['up_disk'] @@ -853,7 +853,7 @@ def build_simple_file_move_tests(sbox, s # showed no conflict at all on udpate. test = {} test['start_rev'] = 16 - test['end_rev'] = 17 + test['end_rev'] = 17 test['start_output'] = None test['start_disk'] = None test['start_status'] = None @@ -905,9 +905,9 @@ def build_simple_file_move_func(sbox, so def move_func(rev): # execute the move svntest.actions.run_and_verify_svn(None, None, [], "move", - source_path, dest_path) + source_path, dest_path) if move_func.extra_mv_tests: - mv_status = svntest.actions.get_virginal_state(wc_dir, rev) + mv_status = svntest.actions.get_virginal_state(wc_dir, rev) mv_status.tweak(source, status='D ', moved_to=dest) mv_status.add({dest: Item(status='A ', moved_from=source, copied='+', wc_rev='-')}) @@ -1027,6 +1027,212 @@ def deeper_move_file_test(sbox): move_file_tests(sbox, source, dest, move_func, tests) +def property_merge(sbox): + "test property merging on move-update" + + # pristine local incoming outcome revert + # 1 p1 v2 p2 v2 p1 v2, p2 v2 p2 v2 + # 2 p1 v1 p1 v2 p2 v2 p1 v2, p2 v2 p1 v1 p2 v2 + # 3 p1 v1 p1 v2 p1 v2 p1 v2 p1 v2 + # 4 p1 v2 p1 v3 p1 v2 conflict p1 v3 + # 5 p1 v1 p1 v2 p1 v3 p1 v2 conflict p1 v3 + + sbox.build() + wc_dir = sbox.wc_dir + + sbox.simple_mkdir('A/C/D1') + sbox.simple_mkdir('A/C/D2') + sbox.simple_mkdir('A/C/D3') + sbox.simple_mkdir('A/C/D4') + sbox.simple_mkdir('A/C/D5') + sbox.simple_add_text('content of f1', 'A/C/f1') + sbox.simple_add_text('content of f2', 'A/C/f2') + sbox.simple_add_text('content of f3', 'A/C/f3') + sbox.simple_add_text('content of f4', 'A/C/f4') + sbox.simple_add_text('content of f5', 'A/C/f5') + sbox.simple_propset('key1', 'value1', + 'A/C/D2', 'A/C/D3', 'A/C/D5', + 'A/C/f2', 'A/C/f3', 'A/C/f5') + sbox.simple_commit() + sbox.simple_propset('key2', 'value2', + 'A/C/D1', 'A/C/D2', + 'A/C/f1', 'A/C/f2') + sbox.simple_propset('key1', 'value2', + 'A/C/D3', + 'A/C/f3') + sbox.simple_propset('key1', 'value3', + 'A/C/D4', 'A/C/D5', + 'A/C/f4', 'A/C/f5') + sbox.simple_commit() + sbox.simple_update('', 2) + sbox.simple_propset('key1', 'value2', + 'A/C/D1', 'A/C/D2', 'A/C/D3', 'A/C/D4', 'A/C/D5', + 'A/C/f1', 'A/C/f2', 'A/C/f3', 'A/C/f4', 'A/C/f5') + sbox.simple_move('A/C', 'A/C2') + + expected_status = svntest.actions.get_virginal_state(wc_dir, 2) + expected_status.tweak('A/C', status='D ', moved_to='A/C2') + expected_status.add({ + 'A/C/D1' : Item(status='D ', wc_rev=2), + 'A/C/D2' : Item(status='D ', wc_rev=2), + 'A/C/D3' : Item(status='D ', wc_rev=2), + 'A/C/D4' : Item(status='D ', wc_rev=2), + 'A/C/D5' : Item(status='D ', wc_rev=2), + 'A/C/f1' : Item(status='D ', wc_rev=2), + 'A/C/f2' : Item(status='D ', wc_rev=2), + 'A/C/f3' : Item(status='D ', wc_rev=2), + 'A/C/f4' : Item(status='D ', wc_rev=2), + 'A/C/f5' : Item(status='D ', wc_rev=2), + 'A/C2' : Item(status='A ', copied='+', wc_rev='-', moved_from='A/C'), + 'A/C2/D1' : Item(status=' M', copied='+', wc_rev='-'), + 'A/C2/D2' : Item(status=' M', copied='+', wc_rev='-'), + 'A/C2/D3' : Item(status=' M', copied='+', wc_rev='-'), + 'A/C2/D4' : Item(status=' M', copied='+', wc_rev='-'), + 'A/C2/D5' : Item(status=' M', copied='+', wc_rev='-'), + 'A/C2/f1' : Item(status=' M', copied='+', wc_rev='-'), + 'A/C2/f2' : Item(status=' M', copied='+', wc_rev='-'), + 'A/C2/f3' : Item(status=' M', copied='+', wc_rev='-'), + 'A/C2/f4' : Item(status=' M', copied='+', wc_rev='-'), + 'A/C2/f5' : Item(status=' M', copied='+', wc_rev='-'), + }) + svntest.actions.run_and_verify_status(wc_dir, expected_status) + + sbox.simple_update() + svntest.actions.run_and_verify_svn("resolve failed", None, [], + 'resolve', + '--accept=mine-conflict', + sbox.ospath('A/C')) + + expected_status.tweak(wc_rev=3) + expected_status.tweak('A/C2', + 'A/C2/D1', 'A/C2/D2', 'A/C2/D3', 'A/C2/D4', 'A/C2/D5', + 'A/C2/f1', 'A/C2/f2', 'A/C2/f3', 'A/C2/f4', 'A/C2/f5', + wc_rev='-') + expected_status.tweak('A/C2/D3', + 'A/C2/f3', + status=' ') + expected_status.tweak('A/C2/D4', 'A/C2/D5', + 'A/C2/f4', 'A/C2/f5', + status=' C') + + svntest.actions.run_and_verify_status(wc_dir, expected_status) + + expected_disk = svntest.main.greek_state.copy() + expected_disk.remove('A/C') + expected_disk.add({ + 'A/C2' : Item(), + 'A/C2/D1' : Item(props={'key1' : 'value2', 'key2' : 'value2'}), + 'A/C2/D2' : Item(props={'key1' : 'value2', 'key2' : 'value2'}), + 'A/C2/D3' : Item(props={'key1' : 'value2'}), + 'A/C2/D4' : Item(props={'key1' : 'value2'}), + 'A/C2/D5' : Item(props={'key1' : 'value2'}), + 'A/C2/f1' : Item(contents='content of f1', + props={'key1' : 'value2', 'key2' : 'value2'}), + 'A/C2/f2' : Item(contents='content of f2', + props={'key1' : 'value2', 'key2' : 'value2'}), + 'A/C2/f3' : Item(contents='content of f3', + props={'key1' : 'value2'}), + 'A/C2/f4' : Item(contents='content of f4', + props={'key1' : 'value2'}), + 'A/C2/f5' : Item(contents='content of f5', + props={'key1' : 'value2'}), + 'A/C2/D4/dir_conflicts.prej' : Item(contents= +"""Trying to add new property 'key1' +but the property already exists. +<<<<<<< (local property value) +value2======= +value3>>>>>>> (incoming property value) +"""), + 'A/C2/D5/dir_conflicts.prej' : Item(contents= +"""Trying to change property 'key1' +but the property has already been locally changed to a different value. +<<<<<<< (local property value) +value2======= +value3>>>>>>> (incoming property value) +"""), + 'A/C2/f4.prej' : Item(contents= +"""Trying to add new property 'key1' +but the property already exists. +<<<<<<< (local property value) +value2======= +value3>>>>>>> (incoming property value) +"""), + 'A/C2/f5.prej' : Item(contents= +"""Trying to change property 'key1' +but the property has already been locally changed to a different value. +<<<<<<< (local property value) +value2======= +value3>>>>>>> (incoming property value) +"""), + }) + + svntest.actions.verify_disk(wc_dir, expected_disk, True) + + sbox.simple_revert('A/C2/D1', 'A/C2/D2', 'A/C2/D4', 'A/C2/D5', + 'A/C2/f1', 'A/C2/f2', 'A/C2/f4', 'A/C2/f5') + + expected_status.tweak('A/C2/D1', 'A/C2/D2', 'A/C2/D4', 'A/C2/D5', + 'A/C2/f1', 'A/C2/f2', 'A/C2/f4', 'A/C2/f5', + status=' ') + svntest.actions.run_and_verify_status(wc_dir, expected_status) + + expected_disk.remove('A/C2/D4/dir_conflicts.prej', + 'A/C2/D5/dir_conflicts.prej', + 'A/C2/f4.prej', + 'A/C2/f5.prej') + expected_disk.tweak('A/C2/D1', + 'A/C2/f1', + props={'key2' : 'value2'}) + expected_disk.tweak('A/C2/D2', + 'A/C2/f2', + props={'key1' : 'value1', 'key2' : 'value2'}) + expected_disk.tweak('A/C2/D4', 'A/C2/D5', + 'A/C2/f4', 'A/C2/f5', + props={'key1' : 'value3'}) + svntest.actions.verify_disk(wc_dir, expected_disk, True) + + +@Issue(4356) +def move_missing(sbox): + "move a missing directory" + + sbox.build(read_only=True) + wc_dir = sbox.wc_dir + + svntest.main.safe_rmtree(sbox.ospath('A/D/G')) + + expected_err = '.*Can\'t move \'.*G\' to \'.*R\':.*' + + # This move currently fails halfway between adding the dest and + # deleting the source + svntest.actions.run_and_verify_svn(None, None, expected_err, + 'mv', sbox.ospath('A/D/G'), + sbox.ospath('R')) + + expected_status = svntest.actions.get_virginal_state(wc_dir, 1) + expected_status.tweak('A/D/G', 'A/D/G/tau', 'A/D/G/pi', 'A/D/G/rho', + status='! ', entry_status=' ') + + expected_status.add({ + 'R' : Item(status='! ', wc_rev='-', + entry_status='A ', entry_copied='+'), + 'R/pi' : Item(status='! ', wc_rev='-', + entry_status=' ', entry_copied='+'), + 'R/tau' : Item(status='! ', wc_rev='-', + entry_status=' ', entry_copied='+'), + 'R/rho' : Item(status='! ', wc_rev='-', + entry_status=' ', entry_copied='+'), + }) + + # Verify that the status processing doesn't crash + svntest.actions.run_and_verify_status(wc_dir, expected_status) + + # The issue is a crash when the destination is present + os.mkdir(sbox.ospath('R')) + expected_status.tweak('R', status='A ', copied='+') + + svntest.actions.run_and_verify_status(wc_dir, expected_status) + ####################################################################### # Run the tests @@ -1037,6 +1243,8 @@ test_list = [ None, sibling_move_file_test, shallower_move_file_test, deeper_move_file_test, + property_merge, + move_missing, ] if __name__ == '__main__': Modified: subversion/branches/master-passphrase/subversion/tests/cmdline/patch_tests.py URL: http://svn.apache.org/viewvc/subversion/branches/master-passphrase/subversion/tests/cmdline/patch_tests.py?rev=1481041&r1=1481040&r2=1481041&view=diff ============================================================================== --- subversion/branches/master-passphrase/subversion/tests/cmdline/patch_tests.py (original) +++ subversion/branches/master-passphrase/subversion/tests/cmdline/patch_tests.py Fri May 10 14:58:47 2013 @@ -4617,6 +4617,46 @@ def patch_lacking_trailing_eol_on_contex expected_output, expected_disk, expected_status, expected_skip) +def patch_with_custom_keywords(sbox): + """patch with custom keywords""" + + sbox.build() + wc_dir = sbox.wc_dir + + sbox.simple_append('A/mu', '$Qq$\nAB\nZZ\n', truncate=True) + sbox.simple_propset('svn:keywords', 'Qq=%R', 'A/mu') + sbox.simple_commit() + expected_disk = svntest.main.greek_state.copy() + expected_disk.tweak('A/mu', + contents='$Qq: %s $\nAB\nZZ\n' % sbox.repo_url) + svntest.actions.verify_disk(sbox.wc_dir, expected_disk) + + unidiff_patch = [ + "Index: A/mu\n", + "===================================================================\n", + "--- A/mu\t(revision 2)\n", + "+++ A/mu\t(working copy)\n", + "@@ -1,3 +1,3 @@\n", + " $Qq$\n", + "-AB\n", + "+ABAB\n", + " ZZ\n" + ] + + patch_file_path = make_patch_path(sbox) + svntest.main.file_write(patch_file_path, ''.join(unidiff_patch)) + + expected_output = [ 'U %s\n' % sbox.ospath('A/mu') ] + expected_disk.tweak('A/mu', + contents='$Qq: %s $\nABAB\nZZ\n' % sbox.repo_url) + expected_status = svntest.actions.get_virginal_state(wc_dir, 1) + expected_status.tweak('A/mu', wc_rev=2) + expected_status.tweak('A/mu', status='M ') + expected_skip = wc.State('', { }) + svntest.actions.run_and_verify_patch(wc_dir, os.path.abspath(patch_file_path), + expected_output, expected_disk, + expected_status, expected_skip) + ######################################################################## #Run the tests @@ -4669,6 +4709,7 @@ test_list = [ None, patch_empty_file, patch_apply_no_fuz, patch_lacking_trailing_eol_on_context, + patch_with_custom_keywords, ] if __name__ == '__main__': Modified: subversion/branches/master-passphrase/subversion/tests/cmdline/prop_tests.py URL: http://svn.apache.org/viewvc/subversion/branches/master-passphrase/subversion/tests/cmdline/prop_tests.py?rev=1481041&r1=1481040&r2=1481041&view=diff ============================================================================== --- subversion/branches/master-passphrase/subversion/tests/cmdline/prop_tests.py (original) +++ subversion/branches/master-passphrase/subversion/tests/cmdline/prop_tests.py Fri May 10 14:58:47 2013 @@ -2597,6 +2597,21 @@ def almost_known_prop_names(sbox): " is not a valid svn: property name;" " re-run with '--force' to set it") +@Issue(3231) +def peg_rev_base_working(sbox): + """peg rev @BASE, peg rev @WORKING""" + + sbox.build() + wc_dir = sbox.wc_dir + + # set up a local prop mod + svntest.actions.set_prop('ordinal', 'ninth\n', sbox.ospath('iota')) + sbox.simple_commit(message='r2') + svntest.actions.set_prop('cardinal', 'nine\n', sbox.ospath('iota')) + svntest.actions.run_and_verify_svn(None, ['ninth\n'], [], + 'propget', '--strict', 'ordinal', + sbox.ospath('iota') + '@BASE') + ######################################################################## # Run the tests @@ -2641,6 +2656,7 @@ test_list = [ None, pristine_props_listed, inheritable_ignores, almost_known_prop_names, + peg_rev_base_working, ] if __name__ == '__main__': Modified: subversion/branches/master-passphrase/subversion/tests/cmdline/revert_tests.py URL: http://svn.apache.org/viewvc/subversion/branches/master-passphrase/subversion/tests/cmdline/revert_tests.py?rev=1481041&r1=1481040&r2=1481041&view=diff ============================================================================== --- subversion/branches/master-passphrase/subversion/tests/cmdline/revert_tests.py (original) +++ subversion/branches/master-passphrase/subversion/tests/cmdline/revert_tests.py Fri May 10 14:58:47 2013 @@ -792,7 +792,7 @@ def status_of_missing_dir_after_revert(s svntest.main.safe_rmtree(A_D_G_path) expected_status.tweak('A/D/G', status='! ') - + svntest.actions.run_and_verify_status(wc_dir, expected_status) # When using single-db, we can get back to the virginal state. @@ -1599,13 +1599,13 @@ def revert_nonexistent(sbox): @Issue(4168) def revert_obstructing_wc(sbox): "revert with an obstructing working copy" - + sbox.build(create_wc=False, read_only=True) wc_dir = sbox.wc_dir - + expected_output = svntest.wc.State(wc_dir, {}) - expected_disk = svntest.wc.State(wc_dir, {}) - + expected_disk = svntest.wc.State(wc_dir, {}) + # Checkout wc as depth empty svntest.actions.run_and_verify_checkout(sbox.repo_url, wc_dir, expected_output, expected_disk, Modified: subversion/branches/master-passphrase/subversion/tests/cmdline/stat_tests.py URL: http://svn.apache.org/viewvc/subversion/branches/master-passphrase/subversion/tests/cmdline/stat_tests.py?rev=1481041&r1=1481040&r2=1481041&view=diff ============================================================================== --- subversion/branches/master-passphrase/subversion/tests/cmdline/stat_tests.py (original) +++ subversion/branches/master-passphrase/subversion/tests/cmdline/stat_tests.py Fri May 10 14:58:47 2013 @@ -630,7 +630,16 @@ def get_text_timestamp(path): if re.match("^Text Last Updated", line): return line logger.warn("Didn't find text-time for %s", path) - raise svntest.Failure + raise svntest.Failure("didn't find text-time") + +def no_text_timestamp(path): + "ensure no text-time for path using svn info" + exit_code, out, err = svntest.actions.run_and_verify_svn(None, None, [], + 'info', path) + for line in out: + if re.match("^Text Last Updated", line): + logger.warn("Found text-time for %s", path) + raise svntest.Failure("found text-time") # Helper for timestamp_behaviour test def text_time_behaviour(wc_dir, wc_path, status_path, expected_status, cmd): @@ -1519,7 +1528,7 @@ def status_depth_update(sbox): #---------------------------------------------------------------------- def status_depth_update_local_modifications(sbox): "run 'status --depth=X -u' with local changes" - + sbox.build() wc_dir = sbox.wc_dir A_path = sbox.ospath('A') @@ -1969,7 +1978,7 @@ def status_not_present(sbox): sbox.ospath('no-file')) # Skip this test is a .svn dir exists in the root directory -@Skip(lambda: os.path.exists("/%s" % svntest.main.get_admin_name())) +@Skip(lambda: os.path.exists("/%s" % svntest.main.get_admin_name())) def status_unversioned_dir(sbox): "status on unversioned dir" sbox.build(read_only = True, create_wc = False) @@ -2015,6 +2024,74 @@ def status_case_changed(sbox): expected_status) +def move_update_timestamps(sbox): + "timestamp behaviour for move-update" + + sbox.build() + wc_dir = sbox.wc_dir + + sbox.simple_append('A/B/E/beta', 'X\nY\nZ\n', truncate=True) + sbox.simple_commit() + sbox.simple_append('A/B/E/alpha', 'modified alpha') + sbox.simple_append('A/B/E/beta', 'XX\nY\nZ\n', truncate=True) + sbox.simple_commit() + sbox.simple_update('', 2) + + sbox.simple_append('A/B/E/beta', 'local beta') + src_time = get_text_timestamp(sbox.ospath('A/B/E/alpha')) + sbox.simple_move("A/B/E", "A/B/E2") + alpha_dst_time = get_text_timestamp(sbox.ospath('A/B/E2/alpha')) + beta_dst_time = get_text_timestamp(sbox.ospath('A/B/E2/beta')) + if src_time != alpha_dst_time: + raise svntest.Failure("move failed to copy timestamp") + + expected_output = svntest.wc.State(wc_dir, { + 'A/B/E' : Item(status=' ', treeconflict='C'), + 'A/B/E/alpha' : Item(status=' ', treeconflict='U'), + 'A/B/E/beta' : Item(status=' ', treeconflict='U'), + }) + expected_status = svntest.actions.get_virginal_state(wc_dir, 3) + expected_status.tweak('A/B/E', + status='D ', treeconflict='C', moved_to='A/B/E2') + expected_status.tweak('A/B/E/alpha', 'A/B/E/beta', status='D ') + expected_status.add({ + 'A/B/E2' : Item(status='A ', wc_rev='-', copied='+', + moved_from='A/B/E'), + 'A/B/E2/alpha' : Item(status=' ', wc_rev='-', copied='+'), + 'A/B/E2/beta' : Item(status='M ', wc_rev='-', copied='+'), + }) + expected_disk = svntest.main.greek_state.copy() + expected_disk.remove('A/B/E', 'A/B/E/alpha', 'A/B/E/beta') + expected_disk.add({ + 'A/B/E2' : Item(), + 'A/B/E2/alpha' : Item("This is the file 'alpha'.\n"), + 'A/B/E2/beta' : Item("X\nY\nZ\nlocal beta"), + }) + svntest.actions.run_and_verify_update(wc_dir, + expected_output, + expected_disk, + expected_status) + + time.sleep(1.1) + svntest.actions.run_and_verify_svn("resolve failed", None, [], + 'resolve', + '--accept=mine-conflict', + sbox.ospath('A/B/E')) + expected_status.tweak('A/B/E', treeconflict=None) + expected_status.tweak('A/B/E2/beta', status='M ') + svntest.actions.run_and_verify_status(wc_dir, expected_status) + expected_disk.tweak('A/B/E2/beta', contents="XX\nY\nZ\nlocal beta") + expected_disk.tweak('A/B/E2/alpha', contents="This is the file 'alpha'.\nmodified alpha") + svntest.actions.verify_disk(wc_dir, expected_disk) + + # alpha is pristine so gets a new timestamp + new_time = get_text_timestamp(sbox.ospath('A/B/E2/alpha')) + if new_time == alpha_dst_time: + raise svntest.Failure("move failed to update timestamp") + + # beta is modified so timestamp is removed + no_text_timestamp(sbox.ospath('A/B/E2/beta')) + ######################################################################## # Run the tests @@ -2061,6 +2138,7 @@ test_list = [ None, status_not_present, status_unversioned_dir, status_case_changed, + move_update_timestamps, ] if __name__ == '__main__': Modified: subversion/branches/master-passphrase/subversion/tests/cmdline/svnadmin_tests.py URL: http://svn.apache.org/viewvc/subversion/branches/master-passphrase/subversion/tests/cmdline/svnadmin_tests.py?rev=1481041&r1=1481040&r2=1481041&view=diff ============================================================================== --- subversion/branches/master-passphrase/subversion/tests/cmdline/svnadmin_tests.py (original) +++ subversion/branches/master-passphrase/subversion/tests/cmdline/svnadmin_tests.py Fri May 10 14:58:47 2013 @@ -548,6 +548,8 @@ def verify_windows_paths_in_repos(sbox): exit_code, output, errput = svntest.main.run_svnadmin("verify", sbox.repo_dir) + if errput: + raise SVNUnexpectedStderr(errput) # unfortunately, FSFS needs to do more checks than BDB resulting in # different progress output @@ -557,13 +559,13 @@ def verify_windows_paths_in_repos(sbox): 'STDERR', ["* Verifying repository metadata ...\n", "* Verified revision 0.\n", "* Verified revision 1.\n", - "* Verified revision 2.\n"], errput) + "* Verified revision 2.\n"], output) else: svntest.verify.compare_and_display_lines( "Error while running 'svnadmin verify'.", 'STDERR', ["* Verified revision 0.\n", "* Verified revision 1.\n", - "* Verified revision 2.\n"], errput) + "* Verified revision 2.\n"], output) #---------------------------------------------------------------------- @@ -1062,8 +1064,10 @@ def verify_with_invalid_revprops(sbox): exit_code, output, errput = svntest.main.run_svnadmin("verify", sbox.repo_dir) + if errput: + raise SVNUnexpectedStderr(errput) if svntest.verify.verify_outputs( - "Output of 'svnadmin verify' is unexpected.", None, errput, None, + "Output of 'svnadmin verify' is unexpected.", None, output, None, ".*Verified revision 0*"): raise svntest.Failure @@ -1621,7 +1625,8 @@ def hotcopy_incremental_packed(sbox): # Pack revisions 0 and 1. svntest.actions.run_and_verify_svnadmin( - None, None, [], "pack", os.path.join(cwd, sbox.repo_dir)) + None, ['Packing revisions in shard 0...done.\n'], [], "pack", + os.path.join(cwd, sbox.repo_dir)) # Commit 5 more revs, hotcopy and pack after each commit. for i in [1, 2, 3, 4, 5]: @@ -1637,8 +1642,12 @@ def hotcopy_incremental_packed(sbox): if i < 5: sbox.simple_mkdir("newdir-%i" % i) sbox.simple_commit() + if not i % 2: + expected_output = ['Packing revisions in shard %d...done.\n' % (i/2)] + else: + expected_output = [] svntest.actions.run_and_verify_svnadmin( - None, None, [], "pack", os.path.join(cwd, sbox.repo_dir)) + None, expected_output, [], "pack", os.path.join(cwd, sbox.repo_dir)) def locking(sbox): Modified: subversion/branches/master-passphrase/subversion/tests/cmdline/svnauthz_tests.py URL: http://svn.apache.org/viewvc/subversion/branches/master-passphrase/subversion/tests/cmdline/svnauthz_tests.py?rev=1481041&r1=1481040&r2=1481041&view=diff ============================================================================== --- subversion/branches/master-passphrase/subversion/tests/cmdline/svnauthz_tests.py (original) +++ subversion/branches/master-passphrase/subversion/tests/cmdline/svnauthz_tests.py Fri May 10 14:58:47 2013 @@ -90,7 +90,7 @@ def svnauthz_validate_file_test(sbox): (authz_fd, authz_path) = tempfile.mkstemp() authz_content = "[/]\n* = rw\n" svntest.main.file_write(authz_path, authz_content) - + # Valid authz file svntest.actions.run_and_verify_svnauthz("Valid authz file", None, None, 0, False, "validate", authz_path) @@ -162,7 +162,7 @@ def svnauthz_validate_txn_test(sbox): repr([('validate', 'A/authz')])) svntest.main.create_python_hook_script(pre_commit_hook, hook_instance) - # Create an authz file + # Create an authz file authz_content = "[/]\n* = rw\n" authz_path = os.path.join(wc_dir, 'A/authz') svntest.main.file_write(authz_path, authz_content) @@ -249,7 +249,7 @@ def svnauthz_accessof_file_test(sbox): "--path", "/jokes", "--username", "groucho") - # User groucho specified on /jokes with the repo comedy will be rw + # User groucho specified on /jokes with the repo comedy will be rw svntest.actions.run_and_verify_svnauthz("User access on path with repo", ["rw\n"], None, 0, False, "accessof", authz_path, "--path", "/jokes", @@ -318,13 +318,13 @@ def svnauthz_accessof_repo_test(sbox): "--path", "/jokes", "--username", "groucho") - # User groucho specified on /jokes with the repo comedy will be rw + # User groucho specified on /jokes with the repo comedy will be rw svntest.actions.run_and_verify_svnauthz("User access on path with repo", ["rw\n"], None, 0, False, "accessof", authz_url, "--path", "/jokes", "--username", "groucho", "--repository", "comedy") - + def svnauthz_accessof_groups_file_test(sbox): "test 'svnauthz accessof --groups-file' on files" @@ -359,7 +359,7 @@ def svnauthz_accessof_groups_file_test(s ["no\n"], None, 0, False, "accessof", authz_path, "--groups-file", groups_path, - "--username", "groucho") + "--username", "groucho") # Anonymous access specified on /jokes with the repo comedy will be no. svntest.actions.run_and_verify_svnauthz("Anonymous access on path with repo", @@ -449,7 +449,7 @@ def svnauthz_accessof_groups_repo_test(s ["no\n"], None, 0, False, "accessof", authz_url, "--groups-file", groups_url, - "--username", "groucho") + "--username", "groucho") # Anonymous access specified on /jokes with the repo comedy will be no. svntest.actions.run_and_verify_svnauthz("Anonymous access on path with repo", @@ -592,7 +592,7 @@ def svnauthz_accessof_is_file_test(sbox) "--username", "groucho", "--is", "no") - # User groucho specified on /jokes with the repo comedy will be rw + # User groucho specified on /jokes with the repo comedy will be rw # Test --is rw returns 0. svntest.actions.run_and_verify_svnauthz("User access on path w/ repo --is rw", None, None, 0, False, "accessof", @@ -623,7 +623,7 @@ def svnauthz_accessof_is_file_test(sbox) match_all=False ) svntest.actions.run_and_verify_svnauthz("--is with invalid authz file", - None, expected_out, 1, False, + None, expected_out, 1, False, "accessof", authz_path, "--path", "/jokes", "--username", "groucho", "--repository", "comedy", "--is", @@ -761,7 +761,7 @@ def svnauthz_accessof_is_repo_test(sbox) "--username", "groucho", "--is", "no") - # User groucho specified on /jokes with the repo comedy will be rw + # User groucho specified on /jokes with the repo comedy will be rw # Test --is rw returns 0. svntest.actions.run_and_verify_svnauthz("User access on path w/ repo --is rw", None, None, 0, False, "accessof", @@ -818,7 +818,7 @@ def svnauthz_accessof_txn_test(sbox): '--is rw A/authz')])) svntest.main.create_python_hook_script(pre_commit_hook, hook_instance) - # Create an authz file + # Create an authz file authz_content = "[/]\n* = rw\n" authz_path = os.path.join(wc_dir, 'A/authz') svntest.main.file_write(authz_path, authz_content) @@ -875,9 +875,9 @@ def svnauthz_accessof_txn_test(sbox): def svnauthz_compat_mode_file_test(sbox): "test 'svnauthz-validate' compatability mode file" - - # Create an authz file + + # Create an authz file (authz_fd, authz_path) = tempfile.mkstemp() authz_content = "[/]\n* = rw\n" svntest.main.file_write(authz_path, authz_content) @@ -912,7 +912,7 @@ def svnauthz_compat_mode_repo_test(sbox) wc_dir = sbox.wc_dir repo_url = sbox.repo_url - # Create an authz file + # Create an authz file authz_content = "[/]\n* = rw\n" authz_path = os.path.join(wc_dir, 'A/authz') svntest.main.file_write(authz_path, authz_content) @@ -944,7 +944,7 @@ def svnauthz_compat_mode_repo_test(sbox) authz_path) # Check a non-existant url. - # Exit code really should be 2 since this is an operational error. + # Exit code really should be 2 since this is an operational error. svntest.actions.run_and_verify_svnauthz( "svnauthz-validate on non-existant file", None, None, 2, True, repo_url + "/zilch" Modified: subversion/branches/master-passphrase/subversion/tests/cmdline/svndumpfilter_tests.py URL: http://svn.apache.org/viewvc/subversion/branches/master-passphrase/subversion/tests/cmdline/svndumpfilter_tests.py?rev=1481041&r1=1481040&r2=1481041&view=diff ============================================================================== --- subversion/branches/master-passphrase/subversion/tests/cmdline/svndumpfilter_tests.py (original) +++ subversion/branches/master-passphrase/subversion/tests/cmdline/svndumpfilter_tests.py Fri May 10 14:58:47 2013 @@ -677,7 +677,7 @@ def accepts_deltas(sbox): load_and_verify_dumpstream(sbox, [], [], expected_revs, True, dump_out, '--ignore-uuid') - + @Issue(4234) def dumpfilter_targets_expect_leading_slash_prefixes(sbox): Modified: subversion/branches/master-passphrase/subversion/tests/cmdline/svneditor.bat URL: http://svn.apache.org/viewvc/subversion/branches/master-passphrase/subversion/tests/cmdline/svneditor.bat?rev=1481041&r1=1481040&r2=1481041&view=diff ============================================================================== --- subversion/branches/master-passphrase/subversion/tests/cmdline/svneditor.bat (original) +++ subversion/branches/master-passphrase/subversion/tests/cmdline/svneditor.bat Fri May 10 14:58:47 2013 @@ -19,7 +19,7 @@ rem specific language governing permissi rem under the License. rem rem -rem the svneditor.py script is expected to be in the same directory as the +rem the svneditor.py script is expected to be in the same directory as the rem .bat file rem SVN_TEST_PYTHON set by svntest/main.py "%SVN_TEST_PYTHON%" "%~dp0\svneditor.py" %* Modified: subversion/branches/master-passphrase/subversion/tests/cmdline/svnmucc_tests.py URL: http://svn.apache.org/viewvc/subversion/branches/master-passphrase/subversion/tests/cmdline/svnmucc_tests.py?rev=1481041&r1=1481040&r2=1481041&view=diff ============================================================================== --- subversion/branches/master-passphrase/subversion/tests/cmdline/svnmucc_tests.py (original) +++ subversion/branches/master-passphrase/subversion/tests/cmdline/svnmucc_tests.py Fri May 10 14:58:47 2013 @@ -375,7 +375,7 @@ def too_many_log_messages(sbox): svntest.main.file_append(msg_file, 'some log message') err_msg = ["svnmucc: E205000: --message (-m), --file (-F), and " "--with-revprop=svn:log are mutually exclusive"] - + xtest_svnmucc(sbox.repo_url, err_msg, '--non-interactive', '-m', 'log msg', @@ -397,11 +397,11 @@ def too_many_log_messages(sbox): '-F', msg_file, '--with-revprop', 'svn:log=proppy log message', 'mkdir', 'A/subdir') - + @Issues(3418) def no_log_msg_non_interactive(sbox): "test non-interactive without a log message" - + sbox.build(create_wc=False) xtest_svnmucc(sbox.repo_url, ["svnmucc: E205001: Cannot invoke editor to get log message " @@ -409,7 +409,7 @@ def no_log_msg_non_interactive(sbox): ], #--------- '--non-interactive', 'mkdir', 'A/subdir') - + ###################################################################### Modified: subversion/branches/master-passphrase/subversion/tests/cmdline/svnrdump_tests.py URL: http://svn.apache.org/viewvc/subversion/branches/master-passphrase/subversion/tests/cmdline/svnrdump_tests.py?rev=1481041&r1=1481040&r2=1481041&view=diff ============================================================================== --- subversion/branches/master-passphrase/subversion/tests/cmdline/svnrdump_tests.py (original) +++ subversion/branches/master-passphrase/subversion/tests/cmdline/svnrdump_tests.py Fri May 10 14:58:47 2013 @@ -367,7 +367,7 @@ def copy_bad_line_endings_load(sbox): "load: inconsistent line endings in svn:* props" run_load_test(sbox, "copy-bad-line-endings.dump", expected_dumpfile_name="copy-bad-line-endings.expected.dump") - + def copy_bad_line_endings2_dump(sbox): "dump: non-LF line endings in svn:* props" run_dump_test(sbox, "copy-bad-line-endings2.dump", Modified: subversion/branches/master-passphrase/subversion/tests/cmdline/svntest/actions.py URL: http://svn.apache.org/viewvc/subversion/branches/master-passphrase/subversion/tests/cmdline/svntest/actions.py?rev=1481041&r1=1481040&r2=1481041&view=diff ============================================================================== --- subversion/branches/master-passphrase/subversion/tests/cmdline/svntest/actions.py (original) +++ subversion/branches/master-passphrase/subversion/tests/cmdline/svntest/actions.py Fri May 10 14:58:47 2013 @@ -1288,7 +1288,6 @@ def run_and_verify_mergeinfo(error_re_st return out = [_f for _f in [x.rstrip()[1:] for x in out] if _f] - expected_output.sort() extra_out = [] if out != expected_output: exp_hash = dict.fromkeys(expected_output) @@ -1629,7 +1628,7 @@ def run_and_verify_inherited_prop_xml(pa expected_iprops = {} for x in expected_inherited_props: if sandbox.is_url(x): - expected_iprops[x] = expected_inherited_props[x] + expected_iprops[x] = expected_inherited_props[x] else: expected_iprops[os.path.abspath(x)] = expected_inherited_props[x] Modified: subversion/branches/master-passphrase/subversion/tests/cmdline/svntest/deeptrees.py URL: http://svn.apache.org/viewvc/subversion/branches/master-passphrase/subversion/tests/cmdline/svntest/deeptrees.py?rev=1481041&r1=1481040&r2=1481041&view=diff ============================================================================== --- subversion/branches/master-passphrase/subversion/tests/cmdline/svntest/deeptrees.py (original) +++ subversion/branches/master-passphrase/subversion/tests/cmdline/svntest/deeptrees.py Fri May 10 14:58:47 2013 @@ -985,7 +985,7 @@ def deep_trees_run_tests_scheme_for_merg if ignore_ancestry: varargs = varargs + ('--ignore-ancestry',) - run_and_verify_merge(local, None, None, incoming, None, + run_and_verify_merge(local, '0', 'HEAD', incoming, None, x_out, None, None, x_disk, None, x_skip, test_case.error_re_string, None, None, None, None, Modified: subversion/branches/master-passphrase/subversion/tests/cmdline/svntest/main.py URL: http://svn.apache.org/viewvc/subversion/branches/master-passphrase/subversion/tests/cmdline/svntest/main.py?rev=1481041&r1=1481040&r2=1481041&view=diff ============================================================================== --- subversion/branches/master-passphrase/subversion/tests/cmdline/svntest/main.py (original) +++ subversion/branches/master-passphrase/subversion/tests/cmdline/svntest/main.py Fri May 10 14:58:47 2013 @@ -53,7 +53,7 @@ import svntest from svntest import Failure from svntest import Skip -SVN_VER_MINOR = 8 +SVN_VER_MINOR = 9 ###################################################################### # @@ -135,6 +135,8 @@ wc_passwd = 'rayjandom' # scenarios wc_author2 = 'jconstant' # use the same password as wc_author +stack_trace_regexp = r'(?:.*subversion[\\//].*\.c:[0-9]*,$|.*apr_err=.*)' + # Set C locale for command line programs os.environ['LC_ALL'] = 'C' @@ -520,13 +522,13 @@ def run_command_stdin(command, error_exp *varargs) def _line_contains_repos_diskpath(line): - # ### Note: this assumes that either svn-test-work isn't a symlink, + # ### Note: this assumes that either svn-test-work isn't a symlink, # ### or the diskpath isn't realpath()'d somewhere on the way from # ### the server's configuration and the client's stderr. We could # ### check for both the symlinked path and the realpath. return \ os.path.join('cmdline', 'svn-test-work', 'repositories') in line \ - or os.path.join('cmdline', 'svn-test-work', 'local_tmp', 'repos') in line + or os.path.join('cmdline', 'svn-test-work', 'local_tmp', 'repos') in line for lines, name in [[stdout_lines, "stdout"], [stderr_lines, "stderr"]]: if is_ra_type_file() or 'svnadmin' in command or 'svnlook' in command: @@ -547,7 +549,12 @@ def run_command_stdin(command, error_exp if (not error_expected) and ((stderr_lines) or (exit_code != 0)): for x in stderr_lines: logger.warning(x.rstrip()) - raise Failure + if len(varargs) <= 5: + brief_command = ' '.join((command,) + varargs) + else: + brief_command = ' '.join(((command,) + varargs)[:4]) + ' ...' + raise Failure('Command failed: "' + brief_command + + '"; exit code ' + str(exit_code)) return exit_code, \ filter_dbg(stdout_lines), \ @@ -876,12 +883,28 @@ def create_repos(path, minor_version = N # Skip tests if we can't create the repository. if stderr: + stderr_lines = 0 + not_using_fsfs_backend = (options.fs_type != "fsfs") + backend_deprecation_warning = False for line in stderr: + stderr_lines += 1 if line.find('Unknown FS type') != -1: raise Skip - # If the FS type is known, assume the repos couldn't be created - # (e.g. due to a missing 'svnadmin' binary). - raise SVNRepositoryCreateFailure("".join(stderr).rstrip()) + if not_using_fsfs_backend: + if 0 < line.find('repository back-end is deprecated, consider using'): + backend_deprecation_warning = True + + # Creating BDB repositories will cause svnadmin to print a warning + # which should be ignored. + if (stderr_lines == 1 + and not_using_fsfs_backend + and backend_deprecation_warning): + pass + else: + # If the FS type is known and we noticed more than just the + # BDB-specific warning, assume the repos couldn't be created + # (e.g. due to a missing 'svnadmin' binary). + raise SVNRepositoryCreateFailure("".join(stderr).rstrip()) # Require authentication to write to the repos, for ra_svn testing. file_write(get_svnserve_conf_file_path(path), @@ -1186,24 +1209,46 @@ def merge_notify_line(revstart=None, rev return "--- Merging %sr%ld through r%ld into '%s':\n" \ % (from_foreign_phrase, revstart, revend, target_re) -def summary_of_conflicts(text_conflicts=0, prop_conflicts=0, - tree_conflicts=0, skipped_paths=0): +def summary_of_conflicts(text_conflicts=0, + prop_conflicts=0, + tree_conflicts=0, + text_resolved=0, + prop_resolved=0, + tree_resolved=0, + skipped_paths=0, + as_regex=False): """Return a list of lines corresponding to the summary of conflicts and skipped paths that is printed by merge and update and switch. If all parameters are zero, return an empty list. """ lines = [] - if text_conflicts or prop_conflicts or tree_conflicts or skipped_paths: + if (text_conflicts or prop_conflicts or tree_conflicts + or text_resolved or prop_resolved or tree_resolved + or skipped_paths): lines.append("Summary of conflicts:\n") - if text_conflicts: - lines.append(" Text conflicts: %d\n" % text_conflicts) - if prop_conflicts: - lines.append(" Property conflicts: %d\n" % prop_conflicts) - if tree_conflicts: - lines.append(" Tree conflicts: %d\n" % tree_conflicts) + if text_conflicts or text_resolved: + if text_resolved == 0: + lines.append(" Text conflicts: %d\n" % text_conflicts) + else: + lines.append(" Text conflicts: %d remaining (and %d already resolved)\n" + % (text_conflicts, text_resolved)) + if prop_conflicts or prop_resolved: + if prop_resolved == 0: + lines.append(" Property conflicts: %d\n" % prop_conflicts) + else: + lines.append(" Property conflicts: %d remaining (and %d already resolved)\n" + % (prop_conflicts, prop_resolved)) + if tree_conflicts or tree_resolved: + if tree_resolved == 0: + lines.append(" Tree conflicts: %d\n" % tree_conflicts) + else: + lines.append(" Tree conflicts: %d remaining (and %d already resolved)\n" + % (tree_conflicts, tree_resolved)) if skipped_paths: lines.append(" Skipped paths: %d\n" % skipped_paths) + if as_regex: + lines = map(re.escape, lines) return lines Modified: subversion/branches/master-passphrase/subversion/tests/cmdline/tree_conflict_tests.py URL: http://svn.apache.org/viewvc/subversion/branches/master-passphrase/subversion/tests/cmdline/tree_conflict_tests.py?rev=1481041&r1=1481040&r2=1481041&view=diff ============================================================================== --- subversion/branches/master-passphrase/subversion/tests/cmdline/tree_conflict_tests.py (original) +++ subversion/branches/master-passphrase/subversion/tests/cmdline/tree_conflict_tests.py Fri May 10 14:58:47 2013 @@ -1407,9 +1407,11 @@ def actual_only_node_behaviour(sbox): "unlock", foo_path) # update (up) + # This doesn't skip because the update is anchored at the parent of A, + # the parent of A is not in conflict, and the update doesn't attempt to + # change foo itself. expected_stdout = [ - "Skipped '%s' -- Node remains in conflict\n" % sbox.ospath('A/foo'), - ] + svntest.main.summary_of_conflicts(skipped_paths=1) + "Updating '" + foo_path + "':\n", "At revision 4.\n"] expected_stderr = [] run_and_verify_svn(None, expected_stdout, expected_stderr, "update", foo_path) Modified: subversion/branches/master-passphrase/subversion/tests/cmdline/update_tests.py URL: http://svn.apache.org/viewvc/subversion/branches/master-passphrase/subversion/tests/cmdline/update_tests.py?rev=1481041&r1=1481040&r2=1481041&view=diff ============================================================================== --- subversion/branches/master-passphrase/subversion/tests/cmdline/update_tests.py (original) +++ subversion/branches/master-passphrase/subversion/tests/cmdline/update_tests.py Fri May 10 14:58:47 2013 @@ -3694,7 +3694,7 @@ def update_copied_and_deleted_prop(sbox) #---------------------------------------------------------------------- -def update_output_with_conflicts(rev, target, paths=None): +def update_output_with_conflicts(rev, target, paths=None, resolved=False): """Return the expected output for an update of TARGET to revision REV, in which all of the PATHS are updated and conflicting. @@ -3707,19 +3707,19 @@ def update_output_with_conflicts(rev, ta for path in paths: lines += ['C %s\n' % path] lines += ['Updated to revision %d.\n' % rev] - lines += svntest.main.summary_of_conflicts(text_conflicts=len(paths)) + if resolved: + for path in paths: + lines += ["Resolved conflicted state of '%s'\n" % path] + lines += svntest.main.summary_of_conflicts(text_resolved=len(paths)) + else: + lines += svntest.main.summary_of_conflicts(text_conflicts=len(paths)) return lines def update_output_with_conflicts_resolved(rev, target, paths=None): """Like update_output_with_conflicts(), but where all of the conflicts are resolved within the update. """ - if paths is None: - paths = [target] - - lines = update_output_with_conflicts(rev, target, paths) - for path in paths: - lines += ["Resolved conflicted state of '%s'\n" % path] + lines = update_output_with_conflicts(rev, target, paths, resolved=True) return lines #---------------------------------------------------------------------- @@ -6015,7 +6015,7 @@ def update_edit_delete_obstruction(sbox) 'A/D/H' : Item(status=' ', treeconflict='U'), 'A/D/H/chi' : Item(status=' ', treeconflict='D'), 'A/B' : Item(prev_status=' ', prev_treeconflict='D', # Replacement - status=' ', treeconflict='A'), + status=' ', treeconflict='A'), 'iota' : Item(status='A ', prev_status='D '), # Replacement }) @@ -6128,7 +6128,6 @@ def break_moved_dir_edited_leaf_del(sbox expected_status.tweak('A/B/E2', moved_from=None) svntest.actions.run_and_verify_status(wc_dir, expected_status) -@XFail() @Issue(3144,3630) def break_moved_replaced_dir(sbox): "break local move of dir plus replace" @@ -6182,13 +6181,14 @@ def break_moved_replaced_dir(sbox): None, None, None, None, None, 1) - # Now resolve the conflict, using --accept=theirs-conflict. + # Now resolve the conflict, using --accept=working # This should break the move of A/B/E to A/B/E2, leaving A/B/E2 # as a copy. A/B/E is not reverted. svntest.actions.run_and_verify_svn("resolve failed", None, [], 'resolve', '--recursive', - '--accept=theirs-conflict', wc_dir) + '--accept=working', wc_dir) expected_status.tweak('A/B/E2', moved_from=None) + expected_status.tweak('A/B/E', treeconflict=None, moved_to=None) svntest.actions.run_and_verify_status(wc_dir, expected_status) @Issue(4295) @@ -6277,7 +6277,7 @@ def update_removes_switched(sbox): 'C' : Item(status=' ', wc_rev='3'), 'mu' : Item(status=' ', wc_rev='3'), }) - + # And this final update brings back the node, as it was before switching. svntest.actions.run_and_verify_update(wc_dir, expected_output, Modified: subversion/branches/master-passphrase/subversion/tests/cmdline/upgrade_tests.py URL: http://svn.apache.org/viewvc/subversion/branches/master-passphrase/subversion/tests/cmdline/upgrade_tests.py?rev=1481041&r1=1481040&r2=1481041&view=diff ============================================================================== --- subversion/branches/master-passphrase/subversion/tests/cmdline/upgrade_tests.py (original) +++ subversion/branches/master-passphrase/subversion/tests/cmdline/upgrade_tests.py Fri May 10 14:58:47 2013 @@ -1278,6 +1278,136 @@ def upgrade_from_1_7_conflict(sbox): # a working copy used to cause a pointless 'upgrade required' error. svntest.actions.run_and_verify_svn(None, None, [], 'upgrade', sbox.wc_dir) +def do_iprops_upgrade(nonrootfile, rootfile, sbox): + + wc_dir = sbox.wc_dir + + replace_sbox_with_tarfile(sbox, nonrootfile) + svntest.actions.run_and_verify_svn(None, None, [], 'upgrade', sbox.wc_dir) + svntest.actions.run_and_verify_svn(None, None, [], 'relocate', + 'file:///tmp/repo', sbox.repo_url, wc_dir) + + expected_output = [] + expected_disk = svntest.wc.State('', { + 'E' : Item(), + 'E/alpha' : Item(contents="This is the file 'alpha'.\n"), + 'E/beta' : Item(contents="This is the file 'beta'.\n"), + 'F' : Item(), + 'lambda' : Item(contents="This is the file 'lambda'.\n"), + }) + expected_status = svntest.wc.State(sbox.wc_dir, { + '' : Item(), + 'E' : Item(switched='S'), + 'E/alpha' : Item(), + 'E/beta' : Item(), + 'F' : Item(), + 'lambda' : Item(), + }) + expected_status.tweak(status=' ', wc_rev=2) + + # No inherited props after upgrade until an update + expected_iprops = {} + expected_explicit_props = {} + svntest.actions.run_and_verify_inherited_prop_xml( + wc_dir, expected_iprops, expected_explicit_props) + svntest.actions.run_and_verify_inherited_prop_xml( + sbox.ospath('E'), expected_iprops, expected_explicit_props) + + # Update populates the inherited props + svntest.actions.run_and_verify_update(wc_dir, + expected_output, + expected_disk, + expected_status) + + expected_iprops = {sbox.repo_url : {'p' : 'v'}, + sbox.repo_url + '/A' : {'pA' : 'vA'}} + svntest.actions.run_and_verify_inherited_prop_xml( + wc_dir, expected_iprops, expected_explicit_props) + + expected_iprops = {sbox.repo_url : {'p' : 'v'}, + sbox.repo_url + '/X' : {'pX' : 'vX'}} + svntest.actions.run_and_verify_inherited_prop_xml( + sbox.ospath('E'), expected_iprops, expected_explicit_props) + + # Now try with a repository root working copy + replace_sbox_with_tarfile(sbox, rootfile) + svntest.actions.run_and_verify_svn(None, None, [], 'upgrade', sbox.wc_dir) + svntest.actions.run_and_verify_svn(None, None, [], 'relocate', + 'file:///tmp/repo', sbox.repo_url, wc_dir) + + # Unswitched inherited props available after upgrade + expected_iprops = {wc_dir : {'p' : 'v'}, + sbox.ospath('A') : {'pA' : 'vA'}} + svntest.actions.run_and_verify_inherited_prop_xml( + sbox.ospath('A/B'), expected_iprops, expected_explicit_props) + + # Switched inherited props not populated until update after upgrade + expected_iprops = {} + svntest.actions.run_and_verify_inherited_prop_xml( + sbox.ospath('A/B/E'), expected_iprops, expected_explicit_props) + + expected_disk = svntest.wc.State('', { + 'A' : Item(), + 'A/B' : Item(), + 'A/B/E' : Item(), + }) + expected_status = svntest.wc.State(sbox.wc_dir, { + '' : Item(), + 'A' : Item(), + 'A/B' : Item(), + 'A/B/E' : Item(switched='S'), + }) + expected_status.tweak(status=' ', wc_rev=2) + svntest.actions.run_and_verify_update(wc_dir, + expected_output, + expected_disk, + expected_status) + + expected_iprops = {wc_dir : {'p' : 'v'}, + sbox.ospath('A') : {'pA' : 'vA'}} + svntest.actions.run_and_verify_inherited_prop_xml( + sbox.ospath('A/B'), expected_iprops, expected_explicit_props) + + expected_iprops = {sbox.repo_url : {'p' : 'v'}, + sbox.repo_url + '/X' : {'pX' : 'vX'}} + expected_explicit_props = {} + svntest.actions.run_and_verify_inherited_prop_xml( + sbox.ospath('A/B/E'), expected_iprops, expected_explicit_props) + +def iprops_upgrade(sbox): + "inherited properties after upgrade from 1.7" + + sbox.build() + + sbox.simple_copy('A', 'X') + sbox.simple_propset('p', 'v', '') + sbox.simple_propset('pA', 'vA', 'A') + sbox.simple_propset('pX', 'vX', 'X') + sbox.simple_commit() + svntest.main.run_svnadmin('setuuid', sbox.repo_dir, + '8f4d0ebe-2ebf-4f62-ad11-804fd88c2382') + + do_iprops_upgrade('iprops_upgrade_nonroot.tar.bz2', + 'iprops_upgrade_root.tar.bz2', + sbox) + +def iprops_upgrade1_6(sbox): + "inherited properties after upgrade from 1.6" + + sbox.build() + + sbox.simple_copy('A', 'X') + sbox.simple_propset('p', 'v', '') + sbox.simple_propset('pA', 'vA', 'A') + sbox.simple_propset('pX', 'vX', 'X') + sbox.simple_commit() + svntest.main.run_svnadmin('setuuid', sbox.repo_dir, + '8f4d0ebe-2ebf-4f62-ad11-804fd88c2382') + + do_iprops_upgrade('iprops_upgrade_nonroot1_6.tar.bz2', + 'iprops_upgrade_root1_6.tar.bz2', + sbox) + ######################################################################## # Run the tests @@ -1330,6 +1460,8 @@ test_list = [ None, upgrade_missing_replaced, upgrade_not_present_replaced, upgrade_from_1_7_conflict, + iprops_upgrade, + iprops_upgrade1_6, ] Modified: subversion/branches/master-passphrase/subversion/tests/libsvn_delta/random-test.c URL: http://svn.apache.org/viewvc/subversion/branches/master-passphrase/subversion/tests/libsvn_delta/random-test.c?rev=1481041&r1=1481040&r2=1481041&view=diff ============================================================================== --- subversion/branches/master-passphrase/subversion/tests/libsvn_delta/random-test.c (original) +++ subversion/branches/master-passphrase/subversion/tests/libsvn_delta/random-test.c Fri May 10 14:58:47 2013 @@ -500,6 +500,8 @@ random_combine_test(apr_pool_t *pool) { apr_uint32_t seed; svn_error_t *err = do_random_combine_test(pool, &seed); + if (err) + fprintf(stderr, "SEED: %lu\n", (unsigned long)seed); return err; } Modified: subversion/branches/master-passphrase/subversion/tests/libsvn_delta/range-index-test.h URL: http://svn.apache.org/viewvc/subversion/branches/master-passphrase/subversion/tests/libsvn_delta/range-index-test.h?rev=1481041&r1=1481040&r2=1481041&view=diff ============================================================================== --- subversion/branches/master-passphrase/subversion/tests/libsvn_delta/range-index-test.h (original) +++ subversion/branches/master-passphrase/subversion/tests/libsvn_delta/range-index-test.h Fri May 10 14:58:47 2013 @@ -27,7 +27,7 @@ #include "../../libsvn_delta/compose_delta.c" static range_index_node_t *prev_node, *prev_prev_node; -static apr_off_t +static apr_size_t walk_range_index(range_index_node_t *node, const char **msg) { apr_off_t ret; @@ -70,19 +70,18 @@ print_node_data(range_index_node_t *node { if (-node->target_offset == ndx) { - printf(" * Node: [%3"APR_OFF_T_FMT - ",%3"APR_OFF_T_FMT - ") = %-5"APR_OFF_T_FMT"%s\n", + printf(" * Node: [%3"APR_SIZE_T_FMT + ",%3"APR_SIZE_T_FMT + ") = %-5"APR_SIZE_T_FMT"%s\n", node->offset, node->limit, -node->target_offset, msg); } else { - printf(" Node: [%3"APR_OFF_T_FMT - ",%3"APR_OFF_T_FMT - ") = %"APR_OFF_T_FMT"\n", + printf(" Node: [%3"APR_SIZE_T_FMT + ",%3"APR_SIZE_T_FMT + ") = %"APR_SIZE_T_FMT"\n", node->offset, node->limit, - (node->target_offset < 0 - ? -node->target_offset : node->target_offset)); + node->target_offset); } } @@ -154,13 +153,13 @@ random_range_index_test(apr_pool_t *pool ndx = create_range_index(pool); for (i = 1; i <= iterations; ++i) { - apr_off_t offset = svn_test_rand(&seed) % 47; - apr_off_t limit = offset + svn_test_rand(&seed) % 16 + 1; + apr_size_t offset = svn_test_rand(&seed) % 47; + apr_size_t limit = offset + svn_test_rand(&seed) % 16 + 1; range_list_node_t *list, *r; - apr_off_t ret; + apr_size_t ret; const char *msg2; - printf("%3d: Inserting [%3"APR_OFF_T_FMT",%3"APR_OFF_T_FMT") ...", + printf("%3d: Inserting [%3"APR_SIZE_T_FMT",%3"APR_SIZE_T_FMT") ...", i, offset, limit); splay_range_index(offset, ndx); list = build_range_list(offset, limit, ndx); @@ -170,7 +169,7 @@ random_range_index_test(apr_pool_t *pool if (ret == 0) { for (r = list; r; r = r->next) - printf(" %s[%3"APR_OFF_T_FMT",%3"APR_OFF_T_FMT")", + printf(" %s[%3"APR_SIZE_T_FMT",%3"APR_SIZE_T_FMT")", (r->kind == range_from_source ? (++src_cp, "S") : (++tgt_cp, "T")), r->offset, r->limit); Modified: subversion/branches/master-passphrase/subversion/tests/libsvn_diff/diff-diff3-test.c URL: http://svn.apache.org/viewvc/subversion/branches/master-passphrase/subversion/tests/libsvn_diff/diff-diff3-test.c?rev=1481041&r1=1481040&r2=1481041&view=diff ============================================================================== --- subversion/branches/master-passphrase/subversion/tests/libsvn_diff/diff-diff3-test.c (original) +++ subversion/branches/master-passphrase/subversion/tests/libsvn_diff/diff-diff3-test.c Fri May 10 14:58:47 2013 @@ -241,6 +241,12 @@ two_way_diff(const char *filename1, svn_stringbuf_t *actual; char *diff_name = apr_psprintf(pool, "diff-%s-%s", filename1, filename2); + /* Some of the tests have lots of lines, although not much data as + the lines are short, and the in-memory diffs allocate a lot of + memory. Since we are doing multiple diff in a single test we use + a subpool to reuse that memory. */ + apr_pool_t *subpool = svn_pool_create(pool); + /* We have an EXPECTED string we can match, because we don't support any other combinations (yet) than the ones above. */ svn_string_t *original = svn_string_create(contents1, pool); @@ -248,7 +254,8 @@ two_way_diff(const char *filename1, options = options ? options : svn_diff_file_options_create(pool); - SVN_ERR(svn_diff_mem_string_diff(&diff, original, modified, options, pool)); + SVN_ERR(svn_diff_mem_string_diff(&diff, original, modified, options, + subpool)); actual = svn_stringbuf_create_empty(pool); ostream = svn_stream_from_stringbuf(actual, pool); @@ -256,7 +263,8 @@ two_way_diff(const char *filename1, SVN_ERR(svn_diff_mem_string_output_unified(ostream, diff, filename1, filename2, SVN_APR_LOCALE_CHARSET, - original, modified, pool)); + original, modified, subpool)); + svn_pool_clear(subpool); SVN_ERR(svn_stream_close(ostream)); if (strcmp(actual->data, expected) != 0) return svn_error_createf(SVN_ERR_TEST_FAILED, NULL, @@ -311,11 +319,13 @@ two_way_diff(const char *filename1, SVN_ERR(three_way_merge(filename1, filename2, filename1, contents1, contents2, contents1, contents2, NULL, svn_diff_conflict_display_modified_latest, - pool)); + subpool)); + svn_pool_clear(subpool); SVN_ERR(three_way_merge(filename2, filename1, filename2, contents2, contents1, contents2, contents1, NULL, svn_diff_conflict_display_modified_latest, - pool)); + subpool)); + svn_pool_destroy(subpool); SVN_ERR(svn_io_remove_file2(diff_name, TRUE, pool)); @@ -2565,20 +2575,22 @@ static svn_error_t * test_token_compare(apr_pool_t *pool) { apr_size_t chunk_size = 1 << 17; - const char *pattern = "\n\n\n\n\n\n\n\n"; + const char *pattern = "ABCDEFG\n"; svn_stringbuf_t *original, *modified; svn_diff_file_options_t *diff_opts = svn_diff_file_options_create(pool); diff_opts->ignore_space = svn_diff_file_ignore_space_all; - original = svn_stringbuf_create_ensure(chunk_size, pool); + original = svn_stringbuf_create_ensure(chunk_size * 2 + 8, pool); + /* CHUNK_SIZE bytes */ while (original->len < chunk_size - 8) { svn_stringbuf_appendcstr(original, pattern); } svn_stringbuf_appendcstr(original, " @@@\n"); - modified = svn_stringbuf_create_ensure(chunk_size, pool); + modified = svn_stringbuf_create_ensure(chunk_size * 2 + 9, pool); + /* CHUNK_SIZE+1 bytes, one ' ' more than original */ while (modified->len < chunk_size - 8) { svn_stringbuf_appendcstr(modified, pattern); @@ -2600,13 +2612,43 @@ test_token_compare(apr_pool_t *pool) "--- token-compare-original2" NL "+++ token-compare-modified2" NL "@@ -%u,4 +%u,4 @@" NL - " \n" - " \n" + " ABCDEFG\n" + " ABCDEFG\n" " @@@\n" "-aaaaaaa\n" "+bbbbbbb\n", - 1 +(unsigned int)chunk_size - 8 + 1 - 3, - 1 +(unsigned int)chunk_size - 8 + 1 - 3), + (unsigned int)chunk_size/8 - 2, + (unsigned int)chunk_size/8 - 2), + diff_opts, pool)); + + /* CHUNK_SIZE*2 bytes */ + while (original->len <= chunk_size * 2 - 8) + { + svn_stringbuf_appendcstr(original, pattern); + } + + /* CHUNK_SIZE*2+1 bytes, one ' ' more than original */ + while (modified->len <= chunk_size * 2 - 7) + { + svn_stringbuf_appendcstr(modified, pattern); + } + + SVN_ERR(two_way_diff("token-compare-original2", "token-compare-modified2", + original->data, modified->data, + apr_psprintf(pool, + "--- token-compare-original2" NL + "+++ token-compare-modified2" NL + "@@ -%u,7 +%u,7 @@" NL + " ABCDEFG\n" + " ABCDEFG\n" + " @@@\n" + "-aaaaaaa\n" + "+bbbbbbb\n" + " ABCDEFG\n" + " ABCDEFG\n" + " ABCDEFG\n", + (unsigned int)chunk_size/8 - 2, + (unsigned int)chunk_size/8 - 2), diff_opts, pool)); return SVN_NO_ERROR; Modified: subversion/branches/master-passphrase/subversion/tests/libsvn_fs/fs-test.c URL: http://svn.apache.org/viewvc/subversion/branches/master-passphrase/subversion/tests/libsvn_fs/fs-test.c?rev=1481041&r1=1481040&r2=1481041&view=diff ============================================================================== --- subversion/branches/master-passphrase/subversion/tests/libsvn_fs/fs-test.c (original) +++ subversion/branches/master-passphrase/subversion/tests/libsvn_fs/fs-test.c Fri May 10 14:58:47 2013 @@ -34,6 +34,7 @@ #include "svn_checksum.h" #include "svn_mergeinfo.h" #include "svn_props.h" +#include "svn_version.h" #include "private/svn_fs_private.h" @@ -2073,7 +2074,7 @@ copy_test(const svn_test_opts_t *opts, svn_revnum_t after_rev; /* Prepare a filesystem. */ - SVN_ERR(svn_test__create_fs(&fs, "test-repo-copy-test", + SVN_ERR(svn_test__create_fs(&fs, "test-repo-copy", opts, pool)); /* In first txn, create and commit the greek tree. */ @@ -4236,7 +4237,7 @@ branch_test(const svn_test_opts_t *opts, svn_revnum_t youngest_rev = 0; /* Create a filesystem and repository. */ - SVN_ERR(svn_test__create_fs(&fs, "test-repo-branch-test", + SVN_ERR(svn_test__create_fs(&fs, "test-repo-branch", opts, pool)); /*** Revision 1: Create the greek tree in revision. ***/ @@ -4934,7 +4935,75 @@ delete_fs(const svn_test_opts_t *opts, return SVN_NO_ERROR; } +/* Issue 4340, "filenames containing \n corrupt FSFS repositories" */ +static svn_error_t * +filename_trailing_newline(const svn_test_opts_t *opts, + apr_pool_t *pool) +{ + apr_pool_t *subpool = svn_pool_create(pool); + svn_fs_t *fs; + svn_fs_txn_t *txn; + svn_fs_root_t *txn_root, *root; + svn_revnum_t youngest_rev = 0; + svn_error_t *err; + svn_boolean_t allow_newlines; + + /* Some filesystem implementations can handle newlines in filenames + * and can be white-listed here. + * Currently, only BDB supports \n in filenames. */ + allow_newlines = (strcmp(opts->fs_type, "bdb") == 0); + + SVN_ERR(svn_test__create_fs(&fs, "test-repo-filename-trailing-newline", + opts, pool)); + + /* Revision 1: Add a directory /foo */ + SVN_ERR(svn_fs_begin_txn(&txn, fs, youngest_rev, subpool)); + SVN_ERR(svn_fs_txn_root(&txn_root, txn, subpool)); + SVN_ERR(svn_fs_make_dir(txn_root, "/foo", subpool)); + SVN_ERR(svn_fs_commit_txn(NULL, &youngest_rev, txn, subpool)); + SVN_TEST_ASSERT(SVN_IS_VALID_REVNUM(youngest_rev)); + svn_pool_clear(subpool); + /* Attempt to copy /foo to "/bar\n". This should fail on FSFS. */ + SVN_ERR(svn_fs_begin_txn(&txn, fs, youngest_rev, subpool)); + SVN_ERR(svn_fs_txn_root(&txn_root, txn, subpool)); + SVN_ERR(svn_fs_revision_root(&root, fs, youngest_rev, subpool)); + err = svn_fs_copy(root, "/foo", txn_root, "/bar\n", subpool); + if (allow_newlines) + SVN_TEST_ASSERT(err == SVN_NO_ERROR); + else + SVN_TEST_ASSERT_ERROR(err, SVN_ERR_FS_PATH_SYNTAX); + + /* Attempt to create a file /foo/baz\n. This should fail on FSFS. */ + err = svn_fs_make_file(txn_root, "/foo/baz\n", subpool); + if (allow_newlines) + SVN_TEST_ASSERT(err == SVN_NO_ERROR); + else + SVN_TEST_ASSERT_ERROR(err, SVN_ERR_FS_PATH_SYNTAX); + + return SVN_NO_ERROR; +} + +static svn_error_t * +test_fs_info_format(const svn_test_opts_t *opts, + apr_pool_t *pool) +{ + svn_fs_t *fs; + int fs_format; + svn_version_t *supports_version; + svn_version_t v1_5_0 = {1, 5, 0, ""}; + svn_test_opts_t opts2; + + opts2 = *opts; + opts2.server_minor_version = 5; + + SVN_ERR(svn_test__create_fs(&fs, "test-fs-format-info", &opts2, pool)); + SVN_ERR(svn_fs_info_format(&fs_format, &supports_version, fs, pool, pool)); + SVN_TEST_ASSERT(fs_format == 3); /* happens to be the same for FSFS and BDB */ + SVN_TEST_ASSERT(svn_ver_equal(supports_version, &v1_5_0)); + + return SVN_NO_ERROR; +} /* ------------------------------------------------------------------------ */ @@ -5016,5 +5085,9 @@ struct svn_test_descriptor_t test_funcs[ "test svn_fs_node_history"), SVN_TEST_OPTS_PASS(delete_fs, "test svn_fs_delete_fs"), + SVN_TEST_OPTS_PASS(filename_trailing_newline, + "filenames with trailing \\n might be rejected"), + SVN_TEST_OPTS_PASS(test_fs_info_format, + "test svn_fs_info_format"), SVN_TEST_NULL }; Modified: subversion/branches/master-passphrase/subversion/tests/libsvn_fs_fs/fs-pack-test.c URL: http://svn.apache.org/viewvc/subversion/branches/master-passphrase/subversion/tests/libsvn_fs_fs/fs-pack-test.c?rev=1481041&r1=1481040&r2=1481041&view=diff ============================================================================== --- subversion/branches/master-passphrase/subversion/tests/libsvn_fs_fs/fs-pack-test.c (original) +++ subversion/branches/master-passphrase/subversion/tests/libsvn_fs_fs/fs-pack-test.c Fri May 10 14:58:47 2013 @@ -256,7 +256,7 @@ large_log(svn_revnum_t rev, apr_size_t l svn_stringbuf_appendcstr(temp, "A "); for (i = 0; i < count; ++i) svn_stringbuf_appendcstr(temp, "very, "); - + svn_stringbuf_appendcstr(temp, apr_psprintf(pool, "very long message for rev %ld, indeed", rev)); @@ -762,7 +762,7 @@ file_hint_at_shard_boundary(const svn_te subpool = svn_pool_create(pool); SVN_ERR(svn_fs_open(&fs, REPO_NAME, NULL, subpool)); - /* Revision = SHARD_SIZE */ + /* Revision = SHARD_SIZE */ file_contents = get_rev_contents(SHARD_SIZE, subpool); SVN_ERR(svn_fs_begin_txn(&txn, fs, MAX_REV, subpool)); SVN_ERR(svn_fs_txn_root(&txn_root, txn, subpool)); @@ -781,13 +781,57 @@ file_hint_at_shard_boundary(const svn_te /* Close the repo. */ svn_pool_destroy(subpool); - return err; + return err; } #undef REPO_NAME #undef MAX_REV #undef SHARD_SIZE /* ------------------------------------------------------------------------ */ +#define REPO_NAME "test-repo-fsfs-info" +#define SHARD_SIZE 3 +#define MAX_REV 5 +static svn_error_t * +test_info(const svn_test_opts_t *opts, + apr_pool_t *pool) +{ + svn_fs_t *fs; + const svn_fs_fsfs_info_t *fsfs_info; + const svn_fs_info_placeholder_t *info; + + SVN_ERR(create_packed_filesystem(REPO_NAME, opts, MAX_REV, SHARD_SIZE, + pool)); + + SVN_ERR(svn_fs_open(&fs, REPO_NAME, NULL, pool)); + SVN_ERR(svn_fs_info(&info, fs, pool, pool)); + info = svn_fs_info_dup(info, pool, pool); + + SVN_TEST_STRING_ASSERT(opts->fs_type, info->fs_type); + + /* Bail (with success) on known-untestable scenarios */ + if (strcmp(opts->fs_type, "fsfs") != 0) + return SVN_NO_ERROR; + + fsfs_info = (const void *)info; + if (opts->server_minor_version && (opts->server_minor_version < 6)) + { + SVN_TEST_ASSERT(fsfs_info->shard_size == 0); + SVN_TEST_ASSERT(fsfs_info->min_unpacked_rev == 0); + } + else + { + SVN_TEST_ASSERT(fsfs_info->shard_size == SHARD_SIZE); + SVN_TEST_ASSERT(fsfs_info->min_unpacked_rev + == (MAX_REV + 1) / SHARD_SIZE * SHARD_SIZE); + } + + return SVN_NO_ERROR; +} +#undef REPO_NAME +#undef SHARD_SIZE +#undef MAX_REV + +/* ------------------------------------------------------------------------ */ /* The test table. */ @@ -812,5 +856,7 @@ struct svn_test_descriptor_t test_funcs[ "recover a fully packed filesystem"), SVN_TEST_OPTS_PASS(file_hint_at_shard_boundary, "test file hint at shard boundary"), + SVN_TEST_OPTS_PASS(test_info, + "test svn_fs_info"), SVN_TEST_NULL };