You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by st...@apache.org on 2013/02/13 07:37:56 UTC
svn commit: r1445479 [10/11] - in /subversion/branches/fsfs-format7: ./
build/generator/ build/generator/swig/ build/generator/templates/
notes/api-errata/1.7/ packages/ subversion/bindings/swig/include/
subversion/bindings/swig/perl/libsvn_swig_perl/ ...
Modified: subversion/branches/fsfs-format7/subversion/tests/cmdline/merge_tree_conflict_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/tests/cmdline/merge_tree_conflict_tests.py?rev=1445479&r1=1445478&r2=1445479&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/tests/cmdline/merge_tree_conflict_tests.py (original)
+++ subversion/branches/fsfs-format7/subversion/tests/cmdline/merge_tree_conflict_tests.py Wed Feb 13 06:37:54 2013
@@ -30,7 +30,7 @@ import time
# Our testing module
import svntest
-from svntest import main, wc, verify, actions
+from svntest import main, wc, verify, actions, deeptrees
# (abbreviation)
Item = wc.StateItem
@@ -789,21 +789,21 @@ def tree_conflicts_and_obstructions(sbox
# parent directory.
# convenience definitions
-leaf_edit = svntest.actions.deep_trees_leaf_edit
-tree_del = svntest.actions.deep_trees_tree_del
-leaf_del = svntest.actions.deep_trees_leaf_del
-
-disk_after_leaf_edit = svntest.actions.deep_trees_after_leaf_edit
-disk_after_leaf_del = svntest.actions.deep_trees_after_leaf_del
-disk_after_tree_del = svntest.actions.deep_trees_after_tree_del
-disk_after_leaf_del_no_ci = svntest.actions.deep_trees_after_leaf_del_no_ci
-disk_after_tree_del_no_ci = svntest.actions.deep_trees_after_tree_del_no_ci
+leaf_edit = svntest.deeptrees.deep_trees_leaf_edit
+tree_del = svntest.deeptrees.deep_trees_tree_del
+leaf_del = svntest.deeptrees.deep_trees_leaf_del
+
+disk_after_leaf_edit = svntest.deeptrees.deep_trees_after_leaf_edit
+disk_after_leaf_del = svntest.deeptrees.deep_trees_after_leaf_del
+disk_after_tree_del = svntest.deeptrees.deep_trees_after_tree_del
+disk_after_leaf_del_no_ci = svntest.deeptrees.deep_trees_after_leaf_del_no_ci
+disk_after_tree_del_no_ci = svntest.deeptrees.deep_trees_after_tree_del_no_ci
-deep_trees_conflict_output = svntest.actions.deep_trees_conflict_output
+deep_trees_conflict_output = svntest.deeptrees.deep_trees_conflict_output
j = os.path.join
-DeepTreesTestCase = svntest.actions.DeepTreesTestCase
+DeepTreesTestCase = svntest.deeptrees.DeepTreesTestCase
alpha_beta_gamma = svntest.wc.State('', {
'F/alpha' : Item(),
@@ -840,7 +840,7 @@ def tree_conflicts_on_merge_local_ci_4_1
expected_skip = svntest.wc.State('', { })
- svntest.actions.deep_trees_run_tests_scheme_for_merge(sbox,
+ svntest.deeptrees.deep_trees_run_tests_scheme_for_merge(sbox,
[ DeepTreesTestCase("local_tree_del_incoming_leaf_edit",
tree_del,
leaf_edit,
@@ -878,7 +878,7 @@ def tree_conflicts_on_merge_local_ci_4_2
expected_skip = svntest.wc.State('', {
})
- svntest.actions.deep_trees_run_tests_scheme_for_merge(sbox,
+ svntest.deeptrees.deep_trees_run_tests_scheme_for_merge(sbox,
[ DeepTreesTestCase("local_tree_del_incoming_leaf_del",
tree_del,
leaf_del,
@@ -888,7 +888,6 @@ def tree_conflicts_on_merge_local_ci_4_2
expected_skip) ], True)
#----------------------------------------------------------------------
-@XFail()
@Issue(2282)
def tree_conflicts_on_merge_local_ci_5_1(sbox):
"tree conflicts 5.1: leaf edit, tree del"
@@ -906,23 +905,23 @@ def tree_conflicts_on_merge_local_ci_5_1
'' : Item(status=' M', wc_rev='3'),
'D' : Item(status=' ', wc_rev='3'),
'D/D1' : Item(status=' ', treeconflict='C', wc_rev='4'),
- 'D/D1/delta' : Item(status='D ', wc_rev='4'),
+ 'D/D1/delta' : Item(status=' ', wc_rev='4'),
'DD' : Item(status=' ', wc_rev='3'),
- 'DD/D1' : Item(status=' ', treeconflict='C', wc_rev='4'),
- 'DD/D1/D2' : Item(status='D ', wc_rev='3'),
- 'DD/D1/D2/epsilon' : Item(status='D ', wc_rev='4'),
+ 'DD/D1' : Item(status=' ', treeconflict='C', wc_rev='3'),
+ 'DD/D1/D2' : Item(status=' ', wc_rev='4'),
+ 'DD/D1/D2/epsilon' : Item(status=' ', wc_rev='4'),
'DDD' : Item(status=' ', wc_rev='3'),
- 'DDD/D1' : Item(status=' ', treeconflict='C', wc_rev='4'),
- 'DDD/D1/D2' : Item(status='D ', wc_rev='3'),
- 'DDD/D1/D2/D3' : Item(status='D ', wc_rev='3'),
- 'DDD/D1/D2/D3/zeta' : Item(status='D ', wc_rev='4'),
+ 'DDD/D1' : Item(status=' ', treeconflict='C', wc_rev='3'),
+ 'DDD/D1/D2' : Item(status=' ', wc_rev='3'),
+ 'DDD/D1/D2/D3' : Item(status=' ', wc_rev='4'),
+ 'DDD/D1/D2/D3/zeta' : Item(status=' ', wc_rev='4'),
'DDF' : Item(status=' ', wc_rev='3'),
- 'DDF/D1' : Item(status=' ', treeconflict='C', wc_rev='4'),
- 'DDF/D1/D2' : Item(status='D ', wc_rev='3'),
- 'DDF/D1/D2/gamma' : Item(status='D ', wc_rev='4'),
+ 'DDF/D1' : Item(status=' ', treeconflict='C', wc_rev='3'),
+ 'DDF/D1/D2' : Item(status=' ', wc_rev='3'),
+ 'DDF/D1/D2/gamma' : Item(status=' ', wc_rev='4'),
'DF' : Item(status=' ', wc_rev='3'),
- 'DF/D1' : Item(status=' ', treeconflict='C', wc_rev='4'),
- 'DF/D1/beta' : Item(status='D ', wc_rev='4'),
+ 'DF/D1' : Item(status=' ', treeconflict='C', wc_rev='3'),
+ 'DF/D1/beta' : Item(status=' ', wc_rev='4'),
'F' : Item(status=' ', wc_rev='3'),
'F/alpha' : Item(status=' ', treeconflict='C', wc_rev='4'),
@@ -931,7 +930,7 @@ def tree_conflicts_on_merge_local_ci_5_1
expected_skip = svntest.wc.State('', {
})
- svntest.actions.deep_trees_run_tests_scheme_for_merge(sbox,
+ svntest.deeptrees.deep_trees_run_tests_scheme_for_merge(sbox,
[ DeepTreesTestCase("local_leaf_edit_incoming_tree_del",
leaf_edit,
tree_del,
@@ -941,7 +940,6 @@ def tree_conflicts_on_merge_local_ci_5_1
expected_skip) ], True)
#----------------------------------------------------------------------
-@XFail()
@Issue(2282)
def tree_conflicts_on_merge_local_ci_5_2(sbox):
"tree conflicts 5.2: leaf del, tree del"
@@ -957,15 +955,15 @@ def tree_conflicts_on_merge_local_ci_5_2
'D' : Item(status=' ', wc_rev='3'),
'F' : Item(status=' ', wc_rev='3'),
'DD' : Item(status=' ', wc_rev='3'),
- 'DD/D1' : Item(status='! ', treeconflict='C'),
+ 'DD/D1' : Item(status=' ', wc_rev='3', treeconflict='C'),
'DF' : Item(status=' ', wc_rev='3'),
- 'DF/D1' : Item(status='! ', treeconflict='C'),
+ 'DF/D1' : Item(status=' ', wc_rev='3', treeconflict='C'),
'DDD' : Item(status=' ', wc_rev='3'),
- 'DDD/D1' : Item(status='! ', treeconflict='C'),
- 'DDD/D1/D2' : Item(status='D ', wc_rev='3'),
+ 'DDD/D1' : Item(status=' ', wc_rev='3', treeconflict='C'),
+ 'DDD/D1/D2' : Item(status=' ', wc_rev='3'),
'DDF' : Item(status=' ', wc_rev='3'),
- 'DDF/D1' : Item(status='! ', treeconflict='C'),
- 'DDF/D1/D2' : Item(status='D ', wc_rev='3'),
+ 'DDF/D1' : Item(status=' ', wc_rev='3', treeconflict='C'),
+ 'DDF/D1/D2' : Item(status=' ', wc_rev='3'),
'D/D1' : Item(status='! ', treeconflict='C'),
'F/alpha' : Item(status='! ', treeconflict='C'),
})
@@ -973,7 +971,7 @@ def tree_conflicts_on_merge_local_ci_5_2
expected_skip = svntest.wc.State('', {
})
- svntest.actions.deep_trees_run_tests_scheme_for_merge(sbox,
+ svntest.deeptrees.deep_trees_run_tests_scheme_for_merge(sbox,
[ DeepTreesTestCase("local_leaf_del_incoming_tree_del",
leaf_del,
tree_del,
@@ -1012,7 +1010,7 @@ def tree_conflicts_on_merge_local_ci_6(s
expected_skip = svntest.wc.State('', {
})
- svntest.actions.deep_trees_run_tests_scheme_for_merge(sbox,
+ svntest.deeptrees.deep_trees_run_tests_scheme_for_merge(sbox,
[ DeepTreesTestCase("local_tree_del_incoming_tree_del",
tree_del,
tree_del,
@@ -1059,7 +1057,7 @@ def tree_conflicts_on_merge_no_local_ci_
expected_skip = svntest.wc.State('', {
})
- svntest.actions.deep_trees_run_tests_scheme_for_merge(sbox,
+ svntest.deeptrees.deep_trees_run_tests_scheme_for_merge(sbox,
[ DeepTreesTestCase(
"local_tree_del_incoming_leaf_edit",
tree_del,
@@ -1107,7 +1105,7 @@ def tree_conflicts_on_merge_no_local_ci_
expected_skip = svntest.wc.State('', {
})
- svntest.actions.deep_trees_run_tests_scheme_for_merge(sbox,
+ svntest.deeptrees.deep_trees_run_tests_scheme_for_merge(sbox,
[ DeepTreesTestCase(
"local_tree_del_incoming_leaf_del",
tree_del,
@@ -1158,7 +1156,7 @@ def tree_conflicts_on_merge_no_local_ci_
expected_skip = svntest.wc.State('', {
})
- svntest.actions.deep_trees_run_tests_scheme_for_merge(sbox,
+ svntest.deeptrees.deep_trees_run_tests_scheme_for_merge(sbox,
[ DeepTreesTestCase(
"local_leaf_edit_incoming_tree_del",
leaf_edit,
@@ -1170,7 +1168,6 @@ def tree_conflicts_on_merge_no_local_ci_
) ], False)
#----------------------------------------------------------------------
-@XFail()
@Issue(2282)
def tree_conflicts_on_merge_no_local_ci_5_2(sbox):
"tree conflicts 5.2: leaf del (no ci), tree del"
@@ -1188,25 +1185,25 @@ def tree_conflicts_on_merge_no_local_ci_
'F' : Item(status=' ', wc_rev='3'),
'F/alpha' : Item(status='D ', wc_rev='3', treeconflict='C'),
'DD' : Item(status=' ', wc_rev='3'),
- 'DD/D1' : Item(status='D ', wc_rev='3', treeconflict='C'),
+ 'DD/D1' : Item(status=' ', wc_rev='3', treeconflict='C'),
'DD/D1/D2' : Item(status='D ', wc_rev='3'),
'DF' : Item(status=' ', wc_rev='3'),
- 'DF/D1' : Item(status='D ', wc_rev='3', treeconflict='C'),
+ 'DF/D1' : Item(status=' ', wc_rev='3', treeconflict='C'),
'DF/D1/beta' : Item(status='D ', wc_rev='3'),
'DDD' : Item(status=' ', wc_rev='3'),
- 'DDD/D1' : Item(status='D ', wc_rev='3', treeconflict='C'),
- 'DDD/D1/D2' : Item(status='D ', wc_rev='3'),
+ 'DDD/D1' : Item(status=' ', wc_rev='3', treeconflict='C'),
+ 'DDD/D1/D2' : Item(status=' ', wc_rev='3'),
'DDD/D1/D2/D3' : Item(status='D ', wc_rev='3'),
'DDF' : Item(status=' ', wc_rev='3'),
- 'DDF/D1' : Item(status='D ', wc_rev='3', treeconflict='C'),
- 'DDF/D1/D2' : Item(status='D ', wc_rev='3'),
+ 'DDF/D1' : Item(status=' ', wc_rev='3', treeconflict='C'),
+ 'DDF/D1/D2' : Item(status=' ', wc_rev='3'),
'DDF/D1/D2/gamma' : Item(status='D ', wc_rev='3'),
})
expected_skip = svntest.wc.State('', {
})
- svntest.actions.deep_trees_run_tests_scheme_for_merge(sbox,
+ svntest.deeptrees.deep_trees_run_tests_scheme_for_merge(sbox,
[ DeepTreesTestCase(
"local_leaf_del_incoming_tree_del",
leaf_del,
@@ -1255,7 +1252,7 @@ def tree_conflicts_on_merge_no_local_ci_
expected_skip = svntest.wc.State('', {
})
- svntest.actions.deep_trees_run_tests_scheme_for_merge(sbox,
+ svntest.deeptrees.deep_trees_run_tests_scheme_for_merge(sbox,
[ DeepTreesTestCase(
"local_tree_del_incoming_tree_del",
tree_del,
@@ -1333,10 +1330,10 @@ def tree_conflicts_merge_edit_onto_missi
# Currently this test fails because some parts of the merge
# start succeeding.
- svntest.actions.deep_trees_run_tests_scheme_for_merge(sbox,
+ svntest.deeptrees.deep_trees_run_tests_scheme_for_merge(sbox,
[ DeepTreesTestCase(
"local_tree_missing_incoming_leaf_edit",
- svntest.actions.deep_trees_rmtree,
+ svntest.deeptrees.deep_trees_rmtree,
leaf_edit,
expected_output,
expected_disk,
@@ -1405,10 +1402,10 @@ def tree_conflicts_merge_del_onto_missin
'DF/D1' : Item(verb='Skipped missing target'),
})
- svntest.actions.deep_trees_run_tests_scheme_for_merge(sbox,
+ svntest.deeptrees.deep_trees_run_tests_scheme_for_merge(sbox,
[ DeepTreesTestCase(
"local_tree_missing_incoming_leaf_del",
- svntest.actions.deep_trees_rmtree,
+ svntest.deeptrees.deep_trees_rmtree,
leaf_del,
expected_output,
expected_disk,
@@ -1724,7 +1721,6 @@ def merge_replace_causes_tree_conflict(s
actions.run_and_verify_status(wc_dir, expected_status)
#----------------------------------------------------------------------
-@XFail()
@Issue(3806)
def merge_replace_causes_tree_conflict2(sbox):
"replace vs. delete tree-conflicts"
@@ -1785,13 +1781,18 @@ def merge_replace_causes_tree_conflict2(
'A/D/H', 'A/D/H/chi', 'A/D/H/omega', 'A/D/H/psi',
status='D ')
+ # H is now a file. This hides the status of the descendants.
+ expected_status.remove('A/D/H/chi', 'A/D/H/psi', 'A/D/H/omega')
+
# Merge them one by one to see all the errors.
### A file-with-file replacement onto a deleted file.
# svn merge $URL/A/mu $URL/branch/mu A/mu
expected_stdout = expected_merge_output(None, [
' C ' + A_mu + '\n', # merge
+ 'A ' + A_mu + '\n', # merge
" U " + A + "\n", # mergeinfo
+ " U " + A_mu + "\n", # mergeinfo -> 'RM' status
], target=A, two_url=True, tree_conflicts=1)
actions.run_and_verify_svn2('OUTPUT', expected_stdout, [], 0, 'merge',
@@ -1803,13 +1804,14 @@ def merge_replace_causes_tree_conflict2(
#
# D C merge_tree_conflict_tests-23\A\mu
# > local delete, incoming replace upon merge
- expected_status.tweak('A/mu', status='R ', wc_rev='-', copied='+',
+ expected_status.tweak('A/mu', status='RM', wc_rev='-', copied='+',
treeconflict='C')
### A dir-with-dir replacement onto a deleted directory.
# svn merge $URL/A/B $URL/branch/B A/B
expected_stdout = expected_merge_output(None, [
' C ' + A_B_E + '\n', # merge
+ 'A ' + A_B_E + '\n', # merge
" U " + A_B + "\n", # mergeinfo
], target=A_B, two_url=True, tree_conflicts=1)
@@ -1829,8 +1831,8 @@ def merge_replace_causes_tree_conflict2(
# svn merge --depth=immediates $URL/A/D $URL/branch/D A/D
expected_stdout = expected_merge_output(None, [
' C ' + A_D_H + '\n', # merge
+ 'A ' + A_D_H + '\n', # merge
" U " + A_D + "\n", # mergeinfo
- " U " + A_D_G + "\n",
], target=A_D, two_url=True, tree_conflicts=1)
actions.run_and_verify_svn2('OUTPUT', expected_stdout, [], 0, 'merge',
@@ -1849,7 +1851,9 @@ def merge_replace_causes_tree_conflict2(
# svn merge $URL/A/D/G $URL/branch/D/G A/D/G
expected_stdout = expected_merge_output(None, [
' C ' + A_D_G_pi + '\n', # merge
- ], target=A_D_G, elides=[A_D_G_pi, A_D_G], two_url=True, tree_conflicts=1)
+ 'A ' + A_D_G_pi + '\n', # merge
+ " U " + A_D_G + "\n", # mergeinfo
+ ], target=A_D_G, two_url=True, tree_conflicts=1)
actions.run_and_verify_svn2('OUTPUT', expected_stdout, [], 0, 'merge',
url_A_D_G, url_branch_D_G, A_D_G)
@@ -1868,7 +1872,8 @@ def merge_replace_causes_tree_conflict2(
# Check the tree conflict types:
expected_stdout = '(R.*)|(Summary of conflicts.*)|( Tree conflicts.*)' \
- '|(.*local delete, incoming replace upon merge.*)'
+ '|(.*local delete, incoming replace upon merge.*)' \
+ '|( \>.*)'
tree_conflicted_path = [A_B_E, A_mu, A_D_G_pi, A_D_H]
for path in tree_conflicted_path:
actions.run_and_verify_svn2('OUTPUT', expected_stdout, [], 0, 'st',
@@ -1878,7 +1883,6 @@ def merge_replace_causes_tree_conflict2(
# Test for issue #4011 'merge of replacement on local delete fails'
@SkipUnless(server_has_mergeinfo)
@Issue(4011)
-@XFail()
def merge_replace_on_del_fails(sbox):
"merge replace on local delete fails"
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=1445479&r1=1445478&r2=1445479&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/tests/cmdline/patch_tests.py (original)
+++ subversion/branches/fsfs-format7/subversion/tests/cmdline/patch_tests.py Wed Feb 13 06:37:54 2013
@@ -266,9 +266,7 @@ def patch_absolute_paths(sbox):
expected_output = [
'U %s\n' % os.path.join('A', 'B', 'E', 'alpha'),
'Skipped missing target: \'%s\'\n' % lambda_path,
- 'Summary of conflicts:\n',
- ' Skipped paths: 1\n'
- ]
+ ] + svntest.main.summary_of_conflicts(skipped_paths=1)
alpha_contents = "This is the file 'alpha'.\nWhoooo whooooo whoooooooo!\n"
@@ -988,9 +986,7 @@ def patch_add_new_dir(sbox):
'Skipped missing target: \'%s\'\n' % A_B_E_Y_new_path,
'Skipped missing target: \'%s\'\n' % A_C_new_path,
'Skipped missing target: \'%s\'\n' % A_Z_new_path,
- 'Summary of conflicts:\n',
- ' Skipped paths: 3\n',
- ]
+ ] + svntest.main.summary_of_conflicts(skipped_paths=3)
# Create the unversioned obstructing directory
os.mkdir(os.path.dirname(A_Z_new_path))
@@ -1174,9 +1170,7 @@ def patch_reject(sbox):
expected_output = [
'C %s\n' % sbox.ospath('A/D/gamma'),
'> rejected hunk @@ -1,1 +1,1 @@\n',
- 'Summary of conflicts:\n',
- ' Text conflicts: 1\n',
- ]
+ ] + svntest.main.summary_of_conflicts(text_conflicts=1)
expected_disk = svntest.main.greek_state.copy()
expected_disk.tweak('A/D/gamma', contents=gamma_contents)
@@ -2456,9 +2450,7 @@ def patch_same_twice(sbox):
'> hunk @@ -6,6 +6,9 @@ already applied\n',
'> hunk @@ -14,11 +17,8 @@ already applied\n',
'Skipped \'%s\'\n' % beta_path,
- 'Summary of conflicts:\n',
- ' Skipped paths: 1\n',
- ]
+ ] + svntest.main.summary_of_conflicts(skipped_paths=1)
expected_skip = wc.State('', {beta_path : Item(verb='Skipped')})
@@ -2543,9 +2535,7 @@ def patch_dir_properties(sbox):
expected_output = [
' U %s\n' % wc_dir,
' C %s\n' % sbox.ospath('A/B'),
- 'Summary of conflicts:\n',
- ' Property conflicts: 1\n',
- ]
+ ] + svntest.main.summary_of_conflicts(prop_conflicts=1)
expected_disk = svntest.main.greek_state.copy()
expected_disk.add({
@@ -3969,9 +3959,7 @@ def patch_delete_and_skip(sbox):
'D %s\n' % os.path.join('A', 'B', 'E', 'beta'),
'D %s\n' % os.path.join('A', 'B', 'E'),
'Skipped missing target: \'%s\'\n' % skipped_path,
- 'Summary of conflicts:\n',
- ' Skipped paths: 1\n'
- ]
+ ] + svntest.main.summary_of_conflicts(skipped_paths=1)
expected_disk = svntest.main.greek_state.copy()
expected_disk.remove('A/B/E/alpha')
@@ -4402,9 +4390,7 @@ def single_line_mismatch(sbox):
expected_output = [
'C %s\n' % sbox.ospath('test'),
'> rejected hunk @@ -1,1 +1,1 @@\n',
- 'Summary of conflicts:\n',
- ' Text conflicts: 1\n',
- ]
+ ] + svntest.main.summary_of_conflicts(text_conflicts=1)
svntest.actions.run_and_verify_svn(None, expected_output, [],
'patch', patch_file_path, wc_dir)
@@ -4577,6 +4563,61 @@ def patch_apply_no_fuz(sbox):
if not filecmp.cmp(sbox.ospath('test.txt'), sbox.ospath('test_v2.txt')):
raise svntest.Failure("Patch result not identical")
+@XFail()
+def patch_lacking_trailing_eol_on_context(sbox):
+ "patch file lacking trailing eol on context"
+
+ # Apply a patch where a hunk (the only hunk, in this case) ends with a
+ # context line that has no EOL, where this context line is going to
+ # match an existing line that *does* have an EOL.
+ #
+ # Around trunk@1443700, 'svn patch' wrongly removed an EOL from the
+ # target file at that position.
+
+ sbox.build(read_only = True)
+ wc_dir = sbox.wc_dir
+
+ patch_file_path = make_patch_path(sbox)
+
+ # Prepare
+ expected_status = svntest.actions.get_virginal_state(wc_dir, 1)
+ expected_disk = svntest.main.greek_state.copy()
+
+ # Prepare the patch
+ unidiff_patch = [
+ "Index: iota\n",
+ "===================================================================\n",
+ "--- iota\t(revision 1)\n",
+ "+++ iota\t(working copy)\n",
+ # TODO: -1 +1
+ "@@ -1 +1,2 @@\n",
+ "+Some more bytes\n",
+ " This is the file 'iota'.", # No trailing \n on this context line!
+ ]
+ svntest.main.file_write(patch_file_path, ''.join(unidiff_patch))
+
+ iota_contents = "This is the file 'iota'.\n"
+
+ expected_output = [ 'U %s\n' % sbox.ospath('iota') ]
+
+ # Test where the no-EOL context line is the last line in the target.
+ expected_disk.tweak('iota', contents="Some more bytes\n" + iota_contents)
+ expected_status.tweak('iota', 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)
+
+ # Test where the no-EOL context line is a non-last line in the target.
+ sbox.simple_revert('iota')
+ sbox.simple_append('iota', "Another line.\n")
+ expected_disk.tweak('iota', contents="Some more bytes\n" + iota_contents +
+ "Another line.\n")
+ expected_output = [ 'G %s\n' % sbox.ospath('iota') ]
+ 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
@@ -4628,6 +4669,7 @@ test_list = [ None,
single_line_mismatch,
patch_empty_file,
patch_apply_no_fuz,
+ patch_lacking_trailing_eol_on_context,
]
if __name__ == '__main__':
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=1445479&r1=1445478&r2=1445479&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/tests/cmdline/prop_tests.py (original)
+++ subversion/branches/fsfs-format7/subversion/tests/cmdline/prop_tests.py Wed Feb 13 06:37:54 2013
@@ -1796,7 +1796,7 @@ def rm_of_replaced_file(sbox):
exit_code, output, errput = svntest.main.run_svn(None,
'proplist', '-v',
mu_path + '@base')
- expected_output = svntest.verify.UnorderedRegexOutput([
+ expected_output = svntest.verify.UnorderedRegexListOutput([
'Properties on',
' yellow',
' submarine',
@@ -2130,6 +2130,8 @@ def propget_redirection(sbox):
# it refers to non-existent path-revs, but that is not relevant to
# this test. What matters is that it is a realistic 'big' mergeinfo
# value (it is from Subversion's own 1.6.x branch in fact).
+ # Also, the syntax is wrong: every path should start with '/';
+ # Subversion currently silently corrects this.
big_prop_val = "subversion/branches/1.5.x:872364-874936\n" + \
"subversion/branches/1.5.x-34184:874657-874741\n" + \
"subversion/branches/1.5.x-34432:874744-874798\n" + \
@@ -2269,131 +2271,26 @@ def propget_redirection(sbox):
# Check if the redirected output of svn pg -vR on the root of the WC
# is what we expect.
+ expected_mergeinfo_displayed = [
+ ' /' + line for line in big_prop_val.splitlines(True) ]
expected_output = [
"Properties on '" + B_path + "':\n", # Should ocur only once!
+ " svn:mergeinfo\n",
+ ] + expected_mergeinfo_displayed + [
"Properties on '" + C_path + "':\n", # Should ocur only once!
+ " svn:mergeinfo\n",
+ ] + expected_mergeinfo_displayed + [
"Properties on '" + D_path + "':\n", # Should ocur only once!
- # Everything below should appear three times since this same
- # mergeinfo value is set on three paths in the WC.
" svn:mergeinfo\n",
- " /subversion/branches/1.5.x:872364-874936\n",
- " /subversion/branches/1.5.x-34184:874657-874741\n",
- " /subversion/branches/1.5.x-34432:874744-874798\n",
- " /subversion/branches/1.5.x-issue3067:872184-872314\n",
- " /subversion/branches/1.5.x-issue3157:872165-872175\n",
- " /subversion/branches/1.5.x-issue3174:872178-872348\n",
- " /subversion/branches/1.5.x-r30215:870310,870312,870319,870362\n",
- " /subversion/branches/1.5.x-r30756:874853-874870\n",
- " /subversion/branches/1.5.x-r30868:870951-870970\n",
- " /subversion/branches/1.5.x-r31314:874476-874605\n",
- " /subversion/branches/1.5.x-r31516:871592-871649\n",
- " /subversion/branches/1.5.x-r32470:872546-872676\n",
- " /subversion/branches/1.5.x-r32968:873773-873872\n",
- " /subversion/branches/1.5.x-r33447:873527-873547\n",
- " /subversion/branches/1.5.x-r33465:873541-873549\n",
- " /subversion/branches/1.5.x-r33641:873880-873883\n",
- " /subversion/branches/1.5.x-r34050-followups:874639-874686\n",
- " /subversion/branches/1.5.x-r34487:874562-874581\n",
- " /subversion/branches/1.5.x-ra_serf-backports:872354-872626\n",
- " /subversion/branches/1.5.x-rb-test-fix:874916-874919\n",
- " /subversion/branches/1.5.x-reintegrate-improvements:874586-874922\n",
- " /subversion/branches/1.5.x-tests-pass:870925-870973\n",
- " /subversion/branches/dont-save-plaintext-passwords-by-default:"
- "870728-871118\n",
- " /subversion/branches/gnome-keyring:870558-871410\n",
- " /subversion/branches/issue-3220-dev:872210-872226\n",
- " /subversion/branches/kwallet:870785-871314\n",
- " /subversion/branches/log-g-performance:870941-871032\n",
- " /subversion/branches/r30963-1.5.x:871056-871076\n",
- " /subversion/branches/reintegrate-improvements:873853-874164\n",
- " /subversion/branches/svn-mergeinfo-enhancements:870196\n",
- " /subversion/branches/svnpatch-diff:871905\n",
- " /subversion/trunk:869159-869165,869168-869181,869185,869188,869191,"
- "869200-869201,869203-869207,869209-869224,869227-869238,869240-869244,"
- "869248,869250-869260,869262-869263,869265,869267-869268,869272-869280,"
- "869282-869325,869328-869330,869335,869341-869347,869351,869354-869355,"
- "869358,869361-869377,869379-869381,869383-869417,869419-869422,869432-"
- "869453,869455-869466,869471-869473,869475,869483,869486,869488-869489,"
- "869491-869497,869499-869500,869503,869506-869508,869510-869521,869523-"
- "869540,869542-869552,869556,869558,869560-869561,869563,869565,869567,"
- "869570,869572,869582,869601-869602,869605,869607,869613-869614,869616,"
- "869618,869620,869625,869627,869630,869633,869639,869641-869643,869645-"
- "869652,869655,869657,869665,869668,869674,869677,869681,869685,869687-"
- "869688,869693,869697,869699-869700,869704-869708,869716,869719,869722,"
- "869724,869730,869733-869734,869737-869740,869745-869746,869751-869754,"
- "869766,869812-869813,869815-869818,869820,869825,869837,869841,869843-"
- "869844,869858,869860-869861,869871,869875,869889,869895,869898,869902,"
- "869907,869909,869926,869928-869929,869931-869933,869942-869943,869950,"
- "869952,869957-869958,869969,869972,869974,869988,869994,869996,869999,"
- "870004,870013-870014,870016,870024,870032,870036,870039,870041-870043,"
- "870054,870060,870068-870071,870078,870083,870094,870104,870124,870127-"
- "870128,870133,870135-870136,870141,870144,870148,870160,870172,870175,"
- "870191,870198,870203-870204,870211,870219,870225,870233,870235-870236,"
- "870254-870255,870259,870307,870311,870313,870320,870323,870330-870331,"
- "870352-870353,870355,870359-870360,870371,870373,870378,870393-870395,"
- "870402,870409-870410,870414,870416,870421,870436,870442,870447,870449,"
- "870452,870454,870466,870476,870481-870483,870486,870500,870502,870505,"
- "870513-870518,870522-870523,870527,870529,870534,870536-870538,870540-"
- "870541,870543-870548,870554,870556,870561,870563,870584,870590-870592,"
- "870594-870595,870597,870618,870620,870622,870625-870626,870641,870647,"
- "870657,870665,870671,870681,870702-870703,870706-870708,870717-870718,"
- "870727,870730,870737,870740,870742,870752,870758,870800,870809,870815,"
- "870817,870820-870825,870830,870834-870836,870850-870851,870853,870859,"
- "870861,870886,870894,870916-870918,870942,870945,870957,870962,870970,"
- "870979,870981,870989,870996,871003,871005,871009,871011,871023,871033,"
- "871035-871038,871041,871060,871078,871080,871092,871097,871099,871105,"
- "871107,871120,871123-871127,871130,871133-871135,871140,871149,871155-"
- "871156,871160,871162,871164,871181,871191,871199-871200,871205,871211-"
- "871212,871215,871219,871225,871227,871229,871231,871236,871270,871273,"
- "871277,871283,871297,871302,871306,871308,871315-871320,871323-871325,"
- "871333-871335,871345,871347-871350,871354,871357,871361,871363-871366,"
- "871374-871375,871377,871382,871385-871388,871391,871408,871411,871422,"
- "871435,871441,871443-871444,871465,871470,871472-871476,871481,871489,"
- "871499,871501-871502,871505,871508,871520,871523,871525-871527,871538,"
- "871542,871544,871547-871549,871556,871559,871562-871563,871578,871581,"
- "871587,871589-871597,871608,871613,871616-871617,871620,871624,871649,"
- "871668,871675,871677,871693-871694,871696,871704,871732-871733,871744,"
- "871747,871759,871762,871766,871769,871793,871796,871799,871801,871811,"
- "871813,871821-871826,871831,871843,871860,871880,871891,871894,871899,"
- "871907,871911,871926,871928,871933,871935,871941-871942,871947-871949,"
- "871958,871974,872000-872001,872003,872005,872018,872022,872038,872065,"
- "872068,872086,872091,872093,872097,872103,872112,872130,872154,872157,"
- "872206,872216,872218-872219,872227,872234,872238,872243,872253,872255,"
- "872259,872261,872278-872279,872281,872310-872311,872362,872404,872416-"
- "872417,872429,872431,872434,872439,872450-872453,872468,872470,872477-"
- "872478,872483,872490-872491,872495,872515-872516,872518-872519,872537,"
- "872541,872544,872565,872568,872571-872573,872584,872596-872597,872612,"
- "872619,872624,872632,872656,872670,872706,872710,872713,872717,872746-"
- "872748,872777,872780-872782,872791,872804,872813,872845,872864,872870,"
- "872872,872947-872948,872961,872974,872981,872985-872987,873004,873042,"
- "873049,873051,873076,873087,873090,873096,873098,873100,873183,873186,"
- "873192,873195,873210-873211,873247,873252,873256,873259,873275,873286,"
- "873288,873343,873379-873381,873443,873521,873538-873539,873714-873715,"
- "873718,873733,873745,873751,873767,873778,873781,873849,873856,873862,"
- "873914,873940,873947-873948,873975-873976,873987,873998,874026-874027,"
- "874075,874077-874078,874124-874125,874127,874156,874159,874161,874165,"
- "874168,874170,874184,874189,874204,874223-874224,874245,874258,874262,"
- "874270,874292-874297,874300-874301,874303,874305,874316-874318,874330,"
- "874363,874380,874405,874421,874441,874459,874467,874473,874497,874506,"
- "874545-874546,874561,874566,874568,874580,874619,874621,874634,874636,"
- "874659,874673,874681,874727,874730,874743,874765-874767,874806,874816,"
- "874848,874868,874888,874896,874909,874912,874996,875051,875069,875129,"
- "875132,875134,875137,875151-875153,875186-875188,875190,875235-875237,"
- "875242-875243,875249,875388,875393,875406,875411\n"]
+ ] + expected_mergeinfo_displayed
svntest.verify.verify_outputs(
"Redirected pg -vR doesn't match pg -vR stdout",
pg_stdout_redir, None,
svntest.verify.UnorderedOutput(expected_output), None)
- # Because we are using UnorderedOutput above, this test would spuriously
- # pass if the redirected pg output contained duplicates. This hasn't been
- # observed as part of issue #3721, but we might as well be thorough...
- #
- # ...Since we've set the same mergeinfo prop on A/B, A/C, and A/D, this
- # means the number of lines in the redirected output of svn pg -vR should
- # be three times the number of lines in EXPECTED_OUTPUT, adjusted for the
- # fact the "Properties on '[A/B | A/C | A/D]'" headers appear only once.
- if ((len(expected_output) * 3) - 6) != len(pg_stdout_redir):
- raise svntest.Failure("Redirected pg -vR has unexpected duplicates")
+ # (We want this check to fail if the redirected pg output contains
+ # unexpected duplicate lines, although this hasn't been observed as
+ # part of issue #3721. We used to check separately here because the old
+ # UnorderedOutput class ignored duplicates but now it detects them.)
@Issue(3852)
def file_matching_dir_prop_reject(sbox):
Modified: subversion/branches/fsfs-format7/subversion/tests/cmdline/revert_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/tests/cmdline/revert_tests.py?rev=1445479&r1=1445478&r2=1445479&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/tests/cmdline/revert_tests.py (original)
+++ subversion/branches/fsfs-format7/subversion/tests/cmdline/revert_tests.py Wed Feb 13 06:37:54 2013
@@ -1444,7 +1444,7 @@ def revert_tree_conflicts_with_replaceme
# Revert everything (i.e., accept "theirs-full").
svntest.actions.run_and_verify_revert([
wc('A/B/E'),
- wc('A/B/E/alpha'), # incoming
+ wc('A/B/E/alpha'), # incoming & local
wc('A/B/E/beta'),
wc('A/B/E/loc_beta'),
wc('A/B/lambda'),
@@ -1459,7 +1459,6 @@ def revert_tree_conflicts_with_replaceme
wc('A/D/H/loc_psi'),
wc('A/D/gamma'),
wc('A/mu'),
- wc('A/B/E/alpha'),
], '-R', wc_dir)
# Remove a few unversioned files that revert left behind.
Modified: subversion/branches/fsfs-format7/subversion/tests/cmdline/stat_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/tests/cmdline/stat_tests.py?rev=1445479&r1=1445478&r2=1445479&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/tests/cmdline/stat_tests.py (original)
+++ subversion/branches/fsfs-format7/subversion/tests/cmdline/stat_tests.py Wed Feb 13 06:37:54 2013
@@ -1073,9 +1073,7 @@ def status_add_plus_conflict(sbox):
"? " + sbox.ospath('trunk/file.merge-right.r5') + "\n",
"? " + sbox.ospath('trunk/file.working') + "\n",
"C + " + sbox.ospath('trunk/file') + "\n",
- "Summary of conflicts:\n",
- " Text conflicts: 1\n",
- ]
+ ] + svntest.main.summary_of_conflicts(text_conflicts=1)
if svntest.main.server_has_mergeinfo():
lines.append(" M " + sbox.ospath('trunk') + "\n")
@@ -1745,9 +1743,7 @@ def status_with_tree_conflicts(sbox):
" > local file delete, incoming file edit upon update\n",
"! C %s\n" % tau,
" > local file delete, incoming file delete upon update\n",
- "Summary of conflicts:\n",
- " Tree conflicts: 3\n",
- ])
+ ] + svntest.main.summary_of_conflicts(tree_conflicts=3))
svntest.actions.run_and_verify_svn(None,
expected,
@@ -1763,10 +1759,7 @@ def status_with_tree_conflicts(sbox):
" > local file edit, incoming file delete upon update\n",
"! C %s\n" % tau,
" > local file delete, incoming file delete upon update\n",
- "Summary of conflicts:\n",
- " Tree conflicts: 3\n",
- ])
-
+ ] + svntest.main.summary_of_conflicts(tree_conflicts=3))
svntest.actions.run_and_verify_svn(None,
expected,
Modified: subversion/branches/fsfs-format7/subversion/tests/cmdline/svnadmin_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/tests/cmdline/svnadmin_tests.py?rev=1445479&r1=1445478&r2=1445479&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/tests/cmdline/svnadmin_tests.py (original)
+++ subversion/branches/fsfs-format7/subversion/tests/cmdline/svnadmin_tests.py Wed Feb 13 06:37:54 2013
@@ -1499,44 +1499,31 @@ def test_lslocks_and_rmlocks(sbox):
[], "lock", "-m", "Locking files",
iota_url, lambda_url)
- expected_output_list = [
- "Path: /A/B/lambda",
+ def expected_output_list(path):
+ return [
+ "Path: " + path,
"UUID Token: opaquelocktoken",
"Owner: jrandom",
"Created:",
"Expires:",
"Comment \(1 line\):",
"Locking files",
- "Path: /iota",
- "UUID Token: opaquelocktoken.*",
"\n", # empty line
]
# List all locks
exit_code, output, errput = svntest.main.run_svnadmin("lslocks",
sbox.repo_dir)
-
if errput:
raise SVNUnexpectedStderr(errput)
svntest.verify.verify_exit_code(None, exit_code, 0)
- try:
- expected_output = svntest.verify.UnorderedRegexOutput(expected_output_list)
- svntest.verify.compare_and_display_lines('lslocks output mismatch',
- 'output',
- expected_output, output)
- except:
- # Usually both locks have the same timestamp but if the clock
- # ticks between creating the two locks then the timestamps will
- # differ. When the output has two identical "Created" lines
- # UnorderedRegexOutput must have one matching regex, when the
- # output has two different "Created" lines UnorderedRegexOutput
- # must have two regex.
- expected_output_list.append("Created:.*")
- expected_output = svntest.verify.UnorderedRegexOutput(expected_output_list)
- svntest.verify.compare_and_display_lines('lslocks output mismatch',
- 'output',
- expected_output, output)
+ expected_output = svntest.verify.UnorderedRegexListOutput(
+ expected_output_list('/A/B/lambda') +
+ expected_output_list('/iota'))
+ svntest.verify.compare_and_display_lines('lslocks output mismatch',
+ 'output',
+ expected_output, output)
# List lock in path /A
exit_code, output, errput = svntest.main.run_svnadmin("lslocks",
@@ -1545,18 +1532,10 @@ def test_lslocks_and_rmlocks(sbox):
if errput:
raise SVNUnexpectedStderr(errput)
- expected_output = svntest.verify.UnorderedRegexOutput([
- "Path: /A/B/lambda",
- "UUID Token: opaquelocktoken",
- "Owner: jrandom",
- "Created:",
- "Expires:",
- "Comment \(1 line\):",
- "Locking files",
- "\n", # empty line
- ])
-
- svntest.verify.compare_and_display_lines('message', 'label',
+ expected_output = svntest.verify.RegexListOutput(
+ expected_output_list('/A/B/lambda'))
+ svntest.verify.compare_and_display_lines('lslocks output mismatch',
+ 'output',
expected_output, output)
svntest.verify.verify_exit_code(None, exit_code, 0)
Modified: subversion/branches/fsfs-format7/subversion/tests/cmdline/svnrdump_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/tests/cmdline/svnrdump_tests.py?rev=1445479&r1=1445478&r2=1445479&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/tests/cmdline/svnrdump_tests.py (original)
+++ subversion/branches/fsfs-format7/subversion/tests/cmdline/svnrdump_tests.py Wed Feb 13 06:37:54 2013
@@ -138,12 +138,16 @@ def run_dump_test(sbox, dumpfile_name, e
if not l.startswith('Text-delta-base-md5')]
svnrdump_dumpfile = [l for l in svnrdump_dumpfile
if not l.startswith('Text-delta-base-md5')]
+ svnadmin_dumpfile = [l for l in svnadmin_dumpfile
+ if not mismatched_headers_re.match(l)]
+ svnrdump_dumpfile = [l for l in svnrdump_dumpfile
+ if not mismatched_headers_re.match(l)]
svnadmin_dumpfile = svntest.verify.UnorderedOutput(svnadmin_dumpfile)
svntest.verify.compare_and_display_lines(
"Dump files", "DUMP", svnadmin_dumpfile, svnrdump_dumpfile,
- None, mismatched_headers_re)
+ None)
else:
compare_repos_dumps(sbox, svnadmin_dumpfile)
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=1445479&r1=1445478&r2=1445479&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/tests/cmdline/svntest/actions.py (original)
+++ subversion/branches/fsfs-format7/subversion/tests/cmdline/svntest/actions.py Wed Feb 13 06:37:54 2013
@@ -40,6 +40,9 @@ from svntest import Failure
logger = logging.getLogger()
+# (abbreviation)
+Item = svntest.wc.StateItem
+
def _log_tree_state(msg, actual, subtree=""):
if subtree:
subtree += os.sep
@@ -86,16 +89,10 @@ def setup_pristine_greek_repository():
# import the greek tree, using l:foo/p:bar
### todo: svn should not be prompting for auth info when using
### repositories with no auth/auth requirements
- exit_code, output, errput = main.run_svn(None, 'import', '-m',
- 'Log message for revision 1.',
- main.greek_dump_dir,
- main.pristine_greek_repos_url)
-
- # check for any errors from the import
- if len(errput):
- display_lines("Errors during initial 'svn import':",
- 'STDERR', None, errput)
- sys.exit(1)
+ _, output, _ = main.run_svn(None, 'import', '-m',
+ 'Log message for revision 1.',
+ main.greek_dump_dir,
+ main.pristine_greek_repos_url)
# verify the printed output of 'svn import'.
lastline = output.pop().strip()
@@ -1461,47 +1458,50 @@ def run_and_verify_commit(wc_dir_name, o
# This function always passes '-q' to the status command, which
# suppresses the printing of any unversioned or nonexistent items.
-def run_and_verify_status(wc_dir_name, output_tree,
+def run_and_verify_status(wc_dir_name, status_tree,
singleton_handler_a = None,
a_baton = None,
singleton_handler_b = None,
b_baton = None):
"""Run 'status' on WC_DIR_NAME and compare it with the
- expected OUTPUT_TREE. SINGLETON_HANDLER_A and SINGLETON_HANDLER_B will
+ expected STATUS_TREE. SINGLETON_HANDLER_A and SINGLETON_HANDLER_B will
be passed to tree.compare_trees - see that function's doc string for
more details.
Returns on success, raises on failure."""
- if isinstance(output_tree, wc.State):
- output_state = output_tree
- output_tree = output_tree.old_tree()
- else:
- output_state = None
-
exit_code, output, errput = main.run_svn(None, 'status', '-v', '-u', '-q',
wc_dir_name)
- actual = tree.build_tree_from_status(output, wc_dir_name=wc_dir_name)
+ actual_status = svntest.wc.State.from_status(output)
# Verify actual output against expected output.
- try:
- tree.compare_trees("status", actual, output_tree,
- singleton_handler_a, a_baton,
- singleton_handler_b, b_baton)
- except tree.SVNTreeError:
- verify.display_trees(None, 'STATUS OUTPUT TREE', output_tree, actual)
- _log_tree_state("ACTUAL STATUS TREE:", actual, wc_dir_name)
- raise
+ if isinstance(status_tree, wc.State):
+ try:
+ status_tree.compare_and_display('status', actual_status)
+ except tree.SVNTreeError:
+ _log_tree_state("ACTUAL STATUS TREE:", actual_status.old_tree(),
+ wc_dir_name)
+ raise
+ else:
+ actual_status = actual_status.old_tree()
+ try:
+ tree.compare_trees("status", actual_status, status_tree,
+ singleton_handler_a, a_baton,
+ singleton_handler_b, b_baton)
+ except tree.SVNTreeError:
+ verify.display_trees(None, 'STATUS OUTPUT TREE', status_tree, actual_status)
+ _log_tree_state("ACTUAL STATUS TREE:", actual_status, wc_dir_name)
+ raise
# if we have an output State, and we can/are-allowed to create an
# entries-based State, then compare the two.
- if output_state:
- entries_state = wc.State.from_entries(wc_dir_name)
- if entries_state:
- tweaked = output_state.copy()
+ if isinstance(status_tree, wc.State):
+ actual_entries = wc.State.from_entries(wc_dir_name)
+ if actual_entries:
+ tweaked = status_tree.copy()
tweaked.tweak_for_entries_compare()
try:
- tweaked.compare_and_display('entries', entries_state)
+ tweaked.compare_and_display('entries', actual_entries)
except tree.SVNTreeUnequal:
### do something more
raise
@@ -1514,20 +1514,27 @@ def run_and_verify_unquiet_status(wc_dir
expected STATUS_TREE.
Returns on success, raises on failure."""
- if isinstance(status_tree, wc.State):
- status_tree = status_tree.old_tree()
-
exit_code, output, errput = main.run_svn(None, 'status', '-v',
'-u', wc_dir_name)
- actual = tree.build_tree_from_status(output, wc_dir_name=wc_dir_name)
+ actual_status = svntest.wc.State.from_status(output)
# Verify actual output against expected output.
- try:
- tree.compare_trees("UNQUIET STATUS", actual, status_tree)
- except tree.SVNTreeError:
- _log_tree_state("ACTUAL UNQUIET STATUS TREE:", actual, wc_dir_name)
- raise
+ if isinstance(status_tree, wc.State):
+ try:
+ status_tree.compare_and_display('unquiet status', actual_status)
+ except tree.SVNTreeError:
+ _log_tree_state("ACTUAL STATUS TREE:",
+ actual_status.normalize().old_tree(), wc_dir_name)
+ raise
+ else:
+ actual_status = actual_status.old_tree()
+ try:
+ tree.compare_trees("UNQUIET STATUS", actual_status, status_tree)
+ except tree.SVNTreeError:
+ _log_tree_state("ACTUAL UNQUIET STATUS TREE:", actual_status,
+ wc_dir_name)
+ raise
def run_and_verify_status_xml(expected_entries = [],
*args):
@@ -2213,980 +2220,3 @@ def build_greek_tree_conflicts(sbox):
run_and_verify_svn(None, verify.AnyOutput, [], 'update', wc_dir)
-def make_deep_trees(base):
- """Helper function for deep trees conflicts. Create a set of trees,
- each in its own "container" dir. Any conflicts can be tested separately
- in each container.
- """
- j = os.path.join
- # Create the container dirs.
- F = j(base, 'F')
- D = j(base, 'D')
- DF = j(base, 'DF')
- DD = j(base, 'DD')
- DDF = j(base, 'DDF')
- DDD = j(base, 'DDD')
- os.makedirs(F)
- os.makedirs(j(D, 'D1'))
- os.makedirs(j(DF, 'D1'))
- os.makedirs(j(DD, 'D1', 'D2'))
- os.makedirs(j(DDF, 'D1', 'D2'))
- os.makedirs(j(DDD, 'D1', 'D2', 'D3'))
-
- # Create their files.
- alpha = j(F, 'alpha')
- beta = j(DF, 'D1', 'beta')
- gamma = j(DDF, 'D1', 'D2', 'gamma')
- main.file_append(alpha, "This is the file 'alpha'.\n")
- main.file_append(beta, "This is the file 'beta'.\n")
- main.file_append(gamma, "This is the file 'gamma'.\n")
-
-
-def add_deep_trees(sbox, base_dir_name):
- """Prepare a "deep_trees" within a given directory.
-
- The directory <sbox.wc_dir>/<base_dir_name> is created and a deep_tree
- is created within. The items are only added, a commit has to be
- called separately, if needed.
-
- <base_dir_name> will thus be a container for the set of containers
- mentioned in make_deep_trees().
- """
- j = os.path.join
- base = j(sbox.wc_dir, base_dir_name)
- make_deep_trees(base)
- main.run_svn(None, 'add', base)
-
-
-Item = wc.StateItem
-
-# initial deep trees state
-deep_trees_virginal_state = wc.State('', {
- 'F' : Item(),
- 'F/alpha' : Item("This is the file 'alpha'.\n"),
- 'D' : Item(),
- 'D/D1' : Item(),
- 'DF' : Item(),
- 'DF/D1' : Item(),
- 'DF/D1/beta' : Item("This is the file 'beta'.\n"),
- 'DD' : Item(),
- 'DD/D1' : Item(),
- 'DD/D1/D2' : Item(),
- 'DDF' : Item(),
- 'DDF/D1' : Item(),
- 'DDF/D1/D2' : Item(),
- 'DDF/D1/D2/gamma' : Item("This is the file 'gamma'.\n"),
- 'DDD' : Item(),
- 'DDD/D1' : Item(),
- 'DDD/D1/D2' : Item(),
- 'DDD/D1/D2/D3' : Item(),
- })
-
-
-# Many actions on deep trees and their resulting states...
-
-def deep_trees_leaf_edit(base):
- """Helper function for deep trees test cases. Append text to files,
- create new files in empty directories, and change leaf node properties."""
- j = os.path.join
- F = j(base, 'F', 'alpha')
- DF = j(base, 'DF', 'D1', 'beta')
- DDF = j(base, 'DDF', 'D1', 'D2', 'gamma')
- main.file_append(F, "More text for file alpha.\n")
- main.file_append(DF, "More text for file beta.\n")
- main.file_append(DDF, "More text for file gamma.\n")
- run_and_verify_svn(None, verify.AnyOutput, [],
- 'propset', 'prop1', '1', F, DF, DDF)
-
- D = j(base, 'D', 'D1')
- DD = j(base, 'DD', 'D1', 'D2')
- DDD = j(base, 'DDD', 'D1', 'D2', 'D3')
- run_and_verify_svn(None, verify.AnyOutput, [],
- 'propset', 'prop1', '1', D, DD, DDD)
- D = j(base, 'D', 'D1', 'delta')
- DD = j(base, 'DD', 'D1', 'D2', 'epsilon')
- DDD = j(base, 'DDD', 'D1', 'D2', 'D3', 'zeta')
- main.file_append(D, "This is the file 'delta'.\n")
- main.file_append(DD, "This is the file 'epsilon'.\n")
- main.file_append(DDD, "This is the file 'zeta'.\n")
- run_and_verify_svn(None, verify.AnyOutput, [],
- 'add', D, DD, DDD)
-
-# deep trees state after a call to deep_trees_leaf_edit
-deep_trees_after_leaf_edit = wc.State('', {
- 'F' : Item(),
- 'F/alpha' : Item("This is the file 'alpha'.\nMore text for file alpha.\n"),
- 'D' : Item(),
- 'D/D1' : Item(),
- 'D/D1/delta' : Item("This is the file 'delta'.\n"),
- 'DF' : Item(),
- 'DF/D1' : Item(),
- 'DF/D1/beta' : Item("This is the file 'beta'.\nMore text for file beta.\n"),
- 'DD' : Item(),
- 'DD/D1' : Item(),
- 'DD/D1/D2' : Item(),
- 'DD/D1/D2/epsilon' : Item("This is the file 'epsilon'.\n"),
- 'DDF' : Item(),
- 'DDF/D1' : Item(),
- 'DDF/D1/D2' : Item(),
- 'DDF/D1/D2/gamma' : Item("This is the file 'gamma'.\nMore text for file gamma.\n"),
- 'DDD' : Item(),
- 'DDD/D1' : Item(),
- 'DDD/D1/D2' : Item(),
- 'DDD/D1/D2/D3' : Item(),
- 'DDD/D1/D2/D3/zeta' : Item("This is the file 'zeta'.\n"),
- })
-
-
-def deep_trees_leaf_del(base):
- """Helper function for deep trees test cases. Delete files and empty
- dirs."""
- j = os.path.join
- F = j(base, 'F', 'alpha')
- D = j(base, 'D', 'D1')
- DF = j(base, 'DF', 'D1', 'beta')
- DD = j(base, 'DD', 'D1', 'D2')
- DDF = j(base, 'DDF', 'D1', 'D2', 'gamma')
- DDD = j(base, 'DDD', 'D1', 'D2', 'D3')
- main.run_svn(None, 'rm', F, D, DF, DD, DDF, DDD)
-
-# deep trees state after a call to deep_trees_leaf_del
-deep_trees_after_leaf_del = wc.State('', {
- 'F' : Item(),
- 'D' : Item(),
- 'DF' : Item(),
- 'DF/D1' : Item(),
- 'DD' : Item(),
- 'DD/D1' : Item(),
- 'DDF' : Item(),
- 'DDF/D1' : Item(),
- 'DDF/D1/D2' : Item(),
- 'DDD' : Item(),
- 'DDD/D1' : Item(),
- 'DDD/D1/D2' : Item(),
- })
-
-# deep trees state after a call to deep_trees_leaf_del with no commit
-def deep_trees_after_leaf_del_no_ci(wc_dir):
- if svntest.main.wc_is_singledb(wc_dir):
- return deep_trees_after_leaf_del
- else:
- return deep_trees_empty_dirs
-
-
-def deep_trees_tree_del(base):
- """Helper function for deep trees test cases. Delete top-level dirs."""
- j = os.path.join
- F = j(base, 'F', 'alpha')
- D = j(base, 'D', 'D1')
- DF = j(base, 'DF', 'D1')
- DD = j(base, 'DD', 'D1')
- DDF = j(base, 'DDF', 'D1')
- DDD = j(base, 'DDD', 'D1')
- main.run_svn(None, 'rm', F, D, DF, DD, DDF, DDD)
-
-def deep_trees_rmtree(base):
- """Helper function for deep trees test cases. Delete top-level dirs
- with rmtree instead of svn del."""
- j = os.path.join
- F = j(base, 'F', 'alpha')
- D = j(base, 'D', 'D1')
- DF = j(base, 'DF', 'D1')
- DD = j(base, 'DD', 'D1')
- DDF = j(base, 'DDF', 'D1')
- DDD = j(base, 'DDD', 'D1')
- os.unlink(F)
- main.safe_rmtree(D)
- main.safe_rmtree(DF)
- main.safe_rmtree(DD)
- main.safe_rmtree(DDF)
- main.safe_rmtree(DDD)
-
-# deep trees state after a call to deep_trees_tree_del
-deep_trees_after_tree_del = wc.State('', {
- 'F' : Item(),
- 'D' : Item(),
- 'DF' : Item(),
- 'DD' : Item(),
- 'DDF' : Item(),
- 'DDD' : Item(),
- })
-
-# deep trees state without any files
-deep_trees_empty_dirs = wc.State('', {
- 'F' : Item(),
- 'D' : Item(),
- 'D/D1' : Item(),
- 'DF' : Item(),
- 'DF/D1' : Item(),
- 'DD' : Item(),
- 'DD/D1' : Item(),
- 'DD/D1/D2' : Item(),
- 'DDF' : Item(),
- 'DDF/D1' : Item(),
- 'DDF/D1/D2' : Item(),
- 'DDD' : Item(),
- 'DDD/D1' : Item(),
- 'DDD/D1/D2' : Item(),
- 'DDD/D1/D2/D3' : Item(),
- })
-
-# deep trees state after a call to deep_trees_tree_del with no commit
-def deep_trees_after_tree_del_no_ci(wc_dir):
- if svntest.main.wc_is_singledb(wc_dir):
- return deep_trees_after_tree_del
- else:
- return deep_trees_empty_dirs
-
-def deep_trees_tree_del_repos(base):
- """Helper function for deep trees test cases. Delete top-level dirs,
- directly in the repository."""
- j = '/'.join
- F = j([base, 'F', 'alpha'])
- D = j([base, 'D', 'D1'])
- DF = j([base, 'DF', 'D1'])
- DD = j([base, 'DD', 'D1'])
- DDF = j([base, 'DDF', 'D1'])
- DDD = j([base, 'DDD', 'D1'])
- main.run_svn(None, 'mkdir', '-m', '', F, D, DF, DD, DDF, DDD)
-
-# Expected merge/update/switch output.
-
-deep_trees_conflict_output = wc.State('', {
- 'F/alpha' : Item(status=' ', treeconflict='C'),
- 'D/D1' : Item(status=' ', treeconflict='C'),
- 'DF/D1' : Item(status=' ', treeconflict='C'),
- 'DD/D1' : Item(status=' ', treeconflict='C'),
- 'DDF/D1' : Item(status=' ', treeconflict='C'),
- 'DDD/D1' : Item(status=' ', treeconflict='C'),
- })
-
-deep_trees_conflict_output_skipped = wc.State('', {
- 'D/D1' : Item(verb='Skipped'),
- 'F/alpha' : Item(verb='Skipped'),
- 'DD/D1' : Item(verb='Skipped'),
- 'DF/D1' : Item(verb='Skipped'),
- 'DDD/D1' : Item(verb='Skipped'),
- 'DDF/D1' : Item(verb='Skipped'),
- })
-
-# Expected status output after merge/update/switch.
-
-deep_trees_status_local_tree_del = wc.State('', {
- '' : Item(status=' ', wc_rev=3),
- 'D' : Item(status=' ', wc_rev=3),
- 'D/D1' : Item(status='D ', wc_rev=2, treeconflict='C'),
- 'DD' : Item(status=' ', wc_rev=3),
- 'DD/D1' : Item(status='D ', wc_rev=2, treeconflict='C'),
- 'DD/D1/D2' : Item(status='D ', wc_rev=2),
- 'DDD' : Item(status=' ', wc_rev=3),
- 'DDD/D1' : Item(status='D ', wc_rev=2, treeconflict='C'),
- 'DDD/D1/D2' : Item(status='D ', wc_rev=2),
- 'DDD/D1/D2/D3' : Item(status='D ', wc_rev=2),
- 'DDF' : Item(status=' ', wc_rev=3),
- 'DDF/D1' : Item(status='D ', wc_rev=2, treeconflict='C'),
- 'DDF/D1/D2' : Item(status='D ', wc_rev=2),
- 'DDF/D1/D2/gamma' : Item(status='D ', wc_rev=2),
- 'DF' : Item(status=' ', wc_rev=3),
- 'DF/D1' : Item(status='D ', wc_rev=2, treeconflict='C'),
- 'DF/D1/beta' : Item(status='D ', wc_rev=2),
- 'F' : Item(status=' ', wc_rev=3),
- 'F/alpha' : Item(status='D ', wc_rev=2, treeconflict='C'),
- })
-
-deep_trees_status_local_leaf_edit = wc.State('', {
- '' : Item(status=' ', wc_rev=3),
- 'D' : Item(status=' ', wc_rev=3),
- 'D/D1' : Item(status=' M', wc_rev=2, treeconflict='C'),
- 'D/D1/delta' : Item(status='A ', wc_rev=0),
- 'DD' : Item(status=' ', wc_rev=3),
- 'DD/D1' : Item(status=' ', wc_rev=2, treeconflict='C'),
- 'DD/D1/D2' : Item(status=' M', wc_rev=2),
- 'DD/D1/D2/epsilon' : Item(status='A ', wc_rev=0),
- 'DDD' : Item(status=' ', wc_rev=3),
- 'DDD/D1' : Item(status=' ', wc_rev=2, treeconflict='C'),
- 'DDD/D1/D2' : Item(status=' ', wc_rev=2),
- 'DDD/D1/D2/D3' : Item(status=' M', wc_rev=2),
- 'DDD/D1/D2/D3/zeta' : Item(status='A ', wc_rev=0),
- 'DDF' : Item(status=' ', wc_rev=3),
- 'DDF/D1' : Item(status=' ', wc_rev=2, treeconflict='C'),
- 'DDF/D1/D2' : Item(status=' ', wc_rev=2),
- 'DDF/D1/D2/gamma' : Item(status='MM', wc_rev=2),
- 'DF' : Item(status=' ', wc_rev=3),
- 'DF/D1' : Item(status=' ', wc_rev=2, treeconflict='C'),
- 'DF/D1/beta' : Item(status='MM', wc_rev=2),
- 'F' : Item(status=' ', wc_rev=3),
- 'F/alpha' : Item(status='MM', wc_rev=2, treeconflict='C'),
- })
-
-
-class DeepTreesTestCase:
- """Describes one tree-conflicts test case.
- See deep_trees_run_tests_scheme_for_update(), ..._switch(), ..._merge().
-
- The name field is the subdirectory name in which the test should be run.
-
- The local_action and incoming_action are the functions to run
- to construct the local changes and incoming changes, respectively.
- See deep_trees_leaf_edit, deep_trees_tree_del, etc.
-
- The expected_* and error_re_string arguments are described in functions
- run_and_verify_[update|switch|merge]
- except expected_info, which is a dict that has path keys with values
- that are dicts as passed to run_and_verify_info():
- expected_info = {
- 'F/alpha' : {
- 'Revision' : '3',
- 'Tree conflict' :
- '^local delete, incoming edit upon update'
- + ' Source left: .file.*/F/alpha@2'
- + ' Source right: .file.*/F/alpha@3$',
- },
- 'DF/D1' : {
- 'Tree conflict' :
- '^local delete, incoming edit upon update'
- + ' Source left: .dir.*/DF/D1@2'
- + ' Source right: .dir.*/DF/D1@3$',
- },
- ...
- }
-
- Note: expected_skip is only used in merge, i.e. using
- deep_trees_run_tests_scheme_for_merge.
- """
-
- def __init__(self, name, local_action, incoming_action,
- expected_output = None, expected_disk = None,
- expected_status = None, expected_skip = None,
- error_re_string = None,
- commit_block_string = ".*remains in conflict.*",
- expected_info = None):
- self.name = name
- self.local_action = local_action
- self.incoming_action = incoming_action
- self.expected_output = expected_output
- self.expected_disk = expected_disk
- self.expected_status = expected_status
- self.expected_skip = expected_skip
- self.error_re_string = error_re_string
- self.commit_block_string = commit_block_string
- self.expected_info = expected_info
-
-
-
-def deep_trees_run_tests_scheme_for_update(sbox, greater_scheme):
- """
- Runs a given list of tests for conflicts occuring at an update operation.
-
- This function wants to save time and perform a number of different
- test cases using just a single repository and performing just one commit
- for all test cases instead of one for each test case.
-
- 1) Each test case is initialized in a separate subdir. Each subdir
- again contains one set of "deep_trees", being separate container
- dirs for different depths of trees (F, D, DF, DD, DDF, DDD).
-
- 2) A commit is performed across all test cases and depths.
- (our initial state, -r2)
-
- 3) In each test case subdir (e.g. "local_tree_del_incoming_leaf_edit"),
- its *incoming* action is performed (e.g. "deep_trees_leaf_edit"), in
- each of the different depth trees (F, D, DF, ... DDD).
-
- 4) A commit is performed across all test cases and depths:
- our "incoming" state is "stored away in the repository for now",
- -r3.
-
- 5) All test case dirs and contained deep_trees are time-warped
- (updated) back to -r2, the initial state containing deep_trees.
-
- 6) In each test case subdir (e.g. "local_tree_del_incoming_leaf_edit"),
- its *local* action is performed (e.g. "deep_trees_leaf_del"), in
- each of the different depth trees (F, D, DF, ... DDD).
-
- 7) An update to -r3 is performed across all test cases and depths.
- This causes tree-conflicts between the "local" state in the working
- copy and the "incoming" state from the repository, -r3.
-
- 8) A commit is performed in each separate container, to verify
- that each tree-conflict indeed blocks a commit.
-
- The sbox parameter is just the sbox passed to a test function. No need
- to call sbox.build(), since it is called (once) within this function.
-
- The "table" greater_scheme models all of the different test cases
- that should be run using a single repository.
-
- greater_scheme is a list of DeepTreesTestCase items, which define complete
- test setups, so that they can be performed as described above.
- """
-
- j = os.path.join
-
- if not sbox.is_built():
- sbox.build()
- wc_dir = sbox.wc_dir
-
-
- # 1) create directories
-
- for test_case in greater_scheme:
- try:
- add_deep_trees(sbox, test_case.name)
- except:
- logger.warn("ERROR IN: Tests scheme for update: "
- + "while setting up deep trees in '%s'", test_case.name)
- raise
-
-
- # 2) commit initial state
-
- main.run_svn(None, 'commit', '-m', 'initial state', wc_dir)
-
-
- # 3) apply incoming changes
-
- for test_case in greater_scheme:
- try:
- test_case.incoming_action(j(sbox.wc_dir, test_case.name))
- except:
- logger.warn("ERROR IN: Tests scheme for update: "
- + "while performing incoming action in '%s'", test_case.name)
- raise
-
-
- # 4) commit incoming changes
-
- main.run_svn(None, 'commit', '-m', 'incoming changes', wc_dir)
-
-
- # 5) time-warp back to -r2
-
- main.run_svn(None, 'update', '-r2', wc_dir)
-
-
- # 6) apply local changes
-
- for test_case in greater_scheme:
- try:
- test_case.local_action(j(wc_dir, test_case.name))
- except:
- logger.warn("ERROR IN: Tests scheme for update: "
- + "while performing local action in '%s'", test_case.name)
- raise
-
-
- # 7) update to -r3, conflicting with incoming changes.
- # A lot of different things are expected.
- # Do separate update operations for each test case.
-
- for test_case in greater_scheme:
- try:
- base = j(wc_dir, test_case.name)
-
- x_out = test_case.expected_output
- if x_out != None:
- x_out = x_out.copy()
- x_out.wc_dir = base
-
- x_disk = test_case.expected_disk
-
- x_status = test_case.expected_status
- if x_status != None:
- x_status.copy()
- x_status.wc_dir = base
-
- run_and_verify_update(base, x_out, x_disk, None,
- error_re_string = test_case.error_re_string)
- if x_status:
- run_and_verify_unquiet_status(base, x_status)
-
- x_info = test_case.expected_info or {}
- for path in x_info:
- run_and_verify_info([x_info[path]], j(base, path))
-
- except:
- logger.warn("ERROR IN: Tests scheme for update: "
- + "while verifying in '%s'", test_case.name)
- raise
-
-
- # 8) Verify that commit fails.
-
- for test_case in greater_scheme:
- try:
- base = j(wc_dir, test_case.name)
-
- x_status = test_case.expected_status
- if x_status != None:
- x_status.copy()
- x_status.wc_dir = base
-
- run_and_verify_commit(base, None, x_status,
- test_case.commit_block_string,
- base)
- except:
- logger.warn("ERROR IN: Tests scheme for update: "
- + "while checking commit-blocking in '%s'", test_case.name)
- raise
-
-
-
-def deep_trees_skipping_on_update(sbox, test_case, skip_paths,
- chdir_skip_paths):
- """
- Create tree conflicts, then update again, expecting the existing tree
- conflicts to be skipped.
- SKIP_PATHS is a list of paths, relative to the "base dir", for which
- "update" on the "base dir" should report as skipped.
- CHDIR_SKIP_PATHS is a list of (target-path, skipped-path) pairs for which
- an update of "target-path" (relative to the "base dir") should result in
- "skipped-path" (relative to "target-path") being reported as skipped.
- """
-
- """FURTHER_ACTION is a function that will make a further modification to
- each target, this being the modification that we expect to be skipped. The
- function takes the "base dir" (the WC path to the test case directory) as
- its only argument."""
- further_action = deep_trees_tree_del_repos
-
- j = os.path.join
- wc_dir = sbox.wc_dir
- base = j(wc_dir, test_case.name)
-
- # Initialize: generate conflicts. (We do not check anything here.)
- setup_case = DeepTreesTestCase(test_case.name,
- test_case.local_action,
- test_case.incoming_action,
- None,
- None,
- None)
- deep_trees_run_tests_scheme_for_update(sbox, [setup_case])
-
- # Make a further change to each target in the repository so there is a new
- # revision to update to. (This is r4.)
- further_action(sbox.repo_url + '/' + test_case.name)
-
- # Update whole working copy, expecting the nodes still in conflict to be
- # skipped.
-
- x_out = test_case.expected_output
- if x_out != None:
- x_out = x_out.copy()
- x_out.wc_dir = base
-
- x_disk = test_case.expected_disk
-
- x_status = test_case.expected_status
- if x_status != None:
- x_status = x_status.copy()
- x_status.wc_dir = base
- # Account for nodes that were updated by further_action
- x_status.tweak('', 'D', 'F', 'DD', 'DF', 'DDD', 'DDF', wc_rev=4)
-
- run_and_verify_update(base, x_out, x_disk, None,
- error_re_string = test_case.error_re_string)
-
- run_and_verify_unquiet_status(base, x_status)
-
- # Try to update each in-conflict subtree. Expect a 'Skipped' output for
- # each, and the WC status to be unchanged.
- for path in skip_paths:
- run_and_verify_update(j(base, path),
- wc.State(base, {path : Item(verb='Skipped')}),
- None, None)
-
- run_and_verify_unquiet_status(base, x_status)
-
- # Try to update each in-conflict subtree. Expect a 'Skipped' output for
- # each, and the WC status to be unchanged.
- # This time, cd to the subdir before updating it.
- was_cwd = os.getcwd()
- for path, skipped in chdir_skip_paths:
- if isinstance(skipped, list):
- expected_skip = {}
- for p in skipped:
- expected_skip[p] = Item(verb='Skipped')
- else:
- expected_skip = {skipped : Item(verb='Skipped')}
- p = j(base, path)
- run_and_verify_update(p,
- wc.State(p, expected_skip),
- None, None)
- os.chdir(was_cwd)
-
- run_and_verify_unquiet_status(base, x_status)
-
- # Verify that commit still fails.
- for path, skipped in chdir_skip_paths:
-
- run_and_verify_commit(j(base, path), None, None,
- test_case.commit_block_string,
- base)
-
- run_and_verify_unquiet_status(base, x_status)
-
-
-def deep_trees_run_tests_scheme_for_switch(sbox, greater_scheme):
- """
- Runs a given list of tests for conflicts occuring at a switch operation.
-
- This function wants to save time and perform a number of different
- test cases using just a single repository and performing just one commit
- for all test cases instead of one for each test case.
-
- 1) Each test case is initialized in a separate subdir. Each subdir
- again contains two subdirs: one "local" and one "incoming" for
- the switch operation. These contain a set of deep_trees each.
-
- 2) A commit is performed across all test cases and depths.
- (our initial state, -r2)
-
- 3) In each test case subdir's incoming subdir, the
- incoming actions are performed.
-
- 4) A commit is performed across all test cases and depths. (-r3)
-
- 5) In each test case subdir's local subdir, the local actions are
- performed. They remain uncommitted in the working copy.
-
- 6) In each test case subdir's local dir, a switch is performed to its
- corresponding incoming dir.
- This causes conflicts between the "local" state in the working
- copy and the "incoming" state from the incoming subdir (still -r3).
-
- 7) A commit is performed in each separate container, to verify
- that each tree-conflict indeed blocks a commit.
-
- The sbox parameter is just the sbox passed to a test function. No need
- to call sbox.build(), since it is called (once) within this function.
-
- The "table" greater_scheme models all of the different test cases
- that should be run using a single repository.
-
- greater_scheme is a list of DeepTreesTestCase items, which define complete
- test setups, so that they can be performed as described above.
- """
-
- j = os.path.join
-
- if not sbox.is_built():
- sbox.build()
- wc_dir = sbox.wc_dir
-
-
- # 1) Create directories.
-
- for test_case in greater_scheme:
- try:
- base = j(sbox.wc_dir, test_case.name)
- os.makedirs(base)
- make_deep_trees(j(base, "local"))
- make_deep_trees(j(base, "incoming"))
- main.run_svn(None, 'add', base)
- except:
- logger.warn("ERROR IN: Tests scheme for switch: "
- + "while setting up deep trees in '%s'", test_case.name)
- raise
-
-
- # 2) Commit initial state (-r2).
-
- main.run_svn(None, 'commit', '-m', 'initial state', wc_dir)
-
-
- # 3) Apply incoming changes
-
- for test_case in greater_scheme:
- try:
- test_case.incoming_action(j(sbox.wc_dir, test_case.name, "incoming"))
- except:
- logger.warn("ERROR IN: Tests scheme for switch: "
- + "while performing incoming action in '%s'", test_case.name)
- raise
-
-
- # 4) Commit all changes (-r3).
-
- main.run_svn(None, 'commit', '-m', 'incoming changes', wc_dir)
-
-
- # 5) Apply local changes in their according subdirs.
-
- for test_case in greater_scheme:
- try:
- test_case.local_action(j(sbox.wc_dir, test_case.name, "local"))
- except:
- logger.warn("ERROR IN: Tests scheme for switch: "
- + "while performing local action in '%s'", test_case.name)
- raise
-
-
- # 6) switch the local dir to the incoming url, conflicting with incoming
- # changes. A lot of different things are expected.
- # Do separate switch operations for each test case.
-
- for test_case in greater_scheme:
- try:
- local = j(wc_dir, test_case.name, "local")
- incoming = sbox.repo_url + "/" + test_case.name + "/incoming"
-
- x_out = test_case.expected_output
- if x_out != None:
- x_out = x_out.copy()
- x_out.wc_dir = local
-
- x_disk = test_case.expected_disk
-
- x_status = test_case.expected_status
- if x_status != None:
- x_status.copy()
- x_status.wc_dir = local
-
- run_and_verify_switch(local, local, incoming, x_out, x_disk, None,
- test_case.error_re_string, None, None, None,
- None, False, '--ignore-ancestry')
- run_and_verify_unquiet_status(local, x_status)
-
- x_info = test_case.expected_info or {}
- for path in x_info:
- run_and_verify_info([x_info[path]], j(local, path))
- except:
- logger.warn("ERROR IN: Tests scheme for switch: "
- + "while verifying in '%s'", test_case.name)
- raise
-
-
- # 7) Verify that commit fails.
-
- for test_case in greater_scheme:
- try:
- local = j(wc_dir, test_case.name, 'local')
-
- x_status = test_case.expected_status
- if x_status != None:
- x_status.copy()
- x_status.wc_dir = local
-
- run_and_verify_commit(local, None, x_status,
- test_case.commit_block_string,
- local)
- except:
- logger.warn("ERROR IN: Tests scheme for switch: "
- + "while checking commit-blocking in '%s'", test_case.name)
- raise
-
-
-def deep_trees_run_tests_scheme_for_merge(sbox, greater_scheme,
- do_commit_local_changes,
- do_commit_conflicts=True,
- ignore_ancestry=False):
- """
- Runs a given list of tests for conflicts occuring at a merge operation.
-
- This function wants to save time and perform a number of different
- test cases using just a single repository and performing just one commit
- for all test cases instead of one for each test case.
-
- 1) Each test case is initialized in a separate subdir. Each subdir
- initially contains another subdir, called "incoming", which
- contains a set of deep_trees.
-
- 2) A commit is performed across all test cases and depths.
- (a pre-initial state)
-
- 3) In each test case subdir, the "incoming" subdir is copied to "local",
- via the `svn copy' command. Each test case's subdir now has two sub-
- dirs: "local" and "incoming", initial states for the merge operation.
-
- 4) An update is performed across all test cases and depths, so that the
- copies made in 3) are pulled into the wc.
-
- 5) In each test case's "incoming" subdir, the incoming action is
- performed.
-
- 6) A commit is performed across all test cases and depths, to commit
- the incoming changes.
- If do_commit_local_changes is True, this becomes step 7 (swap steps).
-
- 7) In each test case's "local" subdir, the local_action is performed.
- If do_commit_local_changes is True, this becomes step 6 (swap steps).
- Then, in effect, the local changes are committed as well.
-
- 8) In each test case subdir, the "incoming" subdir is merged into the
- "local" subdir. If ignore_ancestry is True, then the merge is done
- with the --ignore-ancestry option, so mergeinfo is neither considered
- nor recorded. This causes conflicts between the "local" state in the
- working copy and the "incoming" state from the incoming subdir.
-
- 9) If do_commit_conflicts is True, then a commit is performed in each
- separate container, to verify that each tree-conflict indeed blocks
- a commit.
-
- The sbox parameter is just the sbox passed to a test function. No need
- to call sbox.build(), since it is called (once) within this function.
-
- The "table" greater_scheme models all of the different test cases
- that should be run using a single repository.
-
- greater_scheme is a list of DeepTreesTestCase items, which define complete
- test setups, so that they can be performed as described above.
- """
-
- j = os.path.join
-
- if not sbox.is_built():
- sbox.build()
- wc_dir = sbox.wc_dir
-
- # 1) Create directories.
- for test_case in greater_scheme:
- try:
- base = j(sbox.wc_dir, test_case.name)
- os.makedirs(base)
- make_deep_trees(j(base, "incoming"))
- main.run_svn(None, 'add', base)
- except:
- logger.warn("ERROR IN: Tests scheme for merge: "
- + "while setting up deep trees in '%s'", test_case.name)
- raise
-
-
- # 2) Commit pre-initial state (-r2).
-
- main.run_svn(None, 'commit', '-m', 'pre-initial state', wc_dir)
-
-
- # 3) Copy "incoming" to "local".
-
- for test_case in greater_scheme:
- try:
- base_url = sbox.repo_url + "/" + test_case.name
- incoming_url = base_url + "/incoming"
- local_url = base_url + "/local"
- main.run_svn(None, 'cp', incoming_url, local_url, '-m',
- 'copy incoming to local')
- except:
- logger.warn("ERROR IN: Tests scheme for merge: "
- + "while copying deep trees in '%s'", test_case.name)
- raise
-
- # 4) Update to load all of the "/local" subdirs into the working copies.
-
- try:
- main.run_svn(None, 'up', sbox.wc_dir)
- except:
- logger.warn("ERROR IN: Tests scheme for merge: "
- + "while updating local subdirs")
- raise
-
-
- # 5) Perform incoming actions
-
- for test_case in greater_scheme:
- try:
- test_case.incoming_action(j(sbox.wc_dir, test_case.name, "incoming"))
- except:
- logger.warn("ERROR IN: Tests scheme for merge: "
- + "while performing incoming action in '%s'", test_case.name)
- raise
-
-
- # 6) or 7) Commit all incoming actions
-
- if not do_commit_local_changes:
- try:
- main.run_svn(None, 'ci', '-m', 'Committing incoming actions',
- sbox.wc_dir)
- except:
- logger.warn("ERROR IN: Tests scheme for merge: "
- + "while committing incoming actions")
- raise
-
-
- # 7) or 6) Perform all local actions.
-
- for test_case in greater_scheme:
- try:
- test_case.local_action(j(sbox.wc_dir, test_case.name, "local"))
- except:
- logger.warn("ERROR IN: Tests scheme for merge: "
- + "while performing local action in '%s'", test_case.name)
- raise
-
-
- # 6) or 7) Commit all incoming actions
-
- if do_commit_local_changes:
- try:
- main.run_svn(None, 'ci', '-m', 'Committing incoming and local actions',
- sbox.wc_dir)
- except:
- logger.warn("ERROR IN: Tests scheme for merge: "
- + "while committing incoming and local actions")
- raise
-
-
- # 8) Merge all "incoming" subdirs to their respective "local" subdirs.
- # This creates conflicts between the local changes in the "local" wc
- # subdirs and the incoming states committed in the "incoming" subdirs.
-
- for test_case in greater_scheme:
- try:
- local = j(sbox.wc_dir, test_case.name, "local")
- incoming = sbox.repo_url + "/" + test_case.name + "/incoming"
-
- x_out = test_case.expected_output
- if x_out != None:
- x_out = x_out.copy()
- x_out.wc_dir = local
-
- x_disk = test_case.expected_disk
-
- x_status = test_case.expected_status
- if x_status != None:
- x_status.copy()
- x_status.wc_dir = local
-
- x_skip = test_case.expected_skip
- if x_skip != None:
- x_skip.copy()
- x_skip.wc_dir = local
-
- varargs = (local,)
- if ignore_ancestry:
- varargs = varargs + ('--ignore-ancestry',)
-
- run_and_verify_merge(local, None, None, incoming, None,
- x_out, None, None, x_disk, None, x_skip,
- test_case.error_re_string,
- None, None, None, None,
- False, False, *varargs)
- run_and_verify_unquiet_status(local, x_status)
- except:
- logger.warn("ERROR IN: Tests scheme for merge: "
- + "while verifying in '%s'", test_case.name)
- raise
-
-
- # 9) Verify that commit fails.
-
- if do_commit_conflicts:
- for test_case in greater_scheme:
- try:
- local = j(wc_dir, test_case.name, 'local')
-
- x_status = test_case.expected_status
- if x_status != None:
- x_status.copy()
- x_status.wc_dir = local
-
- run_and_verify_commit(local, None, x_status,
- test_case.commit_block_string,
- local)
- except:
- logger.warn("ERROR IN: Tests scheme for merge: "
- + "while checking commit-blocking in '%s'", test_case.name)
- raise
-
-
Modified: subversion/branches/fsfs-format7/subversion/tests/cmdline/svntest/main.py
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/tests/cmdline/svntest/main.py?rev=1445479&r1=1445478&r2=1445479&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/tests/cmdline/svntest/main.py (original)
+++ subversion/branches/fsfs-format7/subversion/tests/cmdline/svntest/main.py Wed Feb 13 06:37:54 2013
@@ -1186,6 +1186,26 @@ 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):
+ """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:
+ 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 skipped_paths:
+ lines.append(" Skipped paths: %d\n" % skipped_paths)
+
+ return lines
+
def make_log_msg():
"Conjure up a log message based on the calling test."
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=1445479&r1=1445478&r2=1445479&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/tests/cmdline/svntest/sandbox.py (original)
+++ subversion/branches/fsfs-format7/subversion/tests/cmdline/svntest/sandbox.py Wed Feb 13 06:37:54 2013
@@ -191,6 +191,12 @@ class Sandbox:
path WC_DIR if supplied."""
return [self.ospath(rp, wc_dir) for rp in relpaths]
+ def path(self, relpath, wc_dir=None):
+ """Return RELPATH converted to an path relative to the WC dir
+ of this sbox, or relative to WC_DIR if supplied, but always
+ using '/' as directory separator."""
+ return self.ospath(relpath, wc_dir=wc_dir).replace(os.path.sep, '/')
+
def redirected_root_url(self, temporary=False):
"""If TEMPORARY is set, return the URL which should be configured
to temporarily redirect to the root of this repository;
Modified: subversion/branches/fsfs-format7/subversion/tests/cmdline/svntest/tree.py
URL: http://svn.apache.org/viewvc/subversion/branches/fsfs-format7/subversion/tests/cmdline/svntest/tree.py?rev=1445479&r1=1445478&r2=1445479&view=diff
==============================================================================
--- subversion/branches/fsfs-format7/subversion/tests/cmdline/svntest/tree.py (original)
+++ subversion/branches/fsfs-format7/subversion/tests/cmdline/svntest/tree.py Wed Feb 13 06:37:54 2013
@@ -838,11 +838,10 @@ def build_tree_from_commit(lines):
# IFF columns non-empty.
#
-def build_tree_from_status(lines, wc_dir_name=None):
+def build_tree_from_status(lines):
"Return a tree derived by parsing the output LINES from 'st -vuq'."
- return svntest.wc.State.from_status(lines,
- wc_dir_name=wc_dir_name).old_tree()
+ return svntest.wc.State.from_status(lines).old_tree()
# Parse merge "skipped" output