subversion-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From julianf...@apache.org
Subject svn commit: r1332174 - /subversion/trunk/subversion/tests/cmdline/merge_symmetric_tests.py
Date Mon, 30 Apr 2012 12:35:38 GMT
Author: julianfoad
Date: Mon Apr 30 12:35:38 2012
New Revision: 1332174

URL: http://svn.apache.org/viewvc?rev=1332174&view=rev
Log:
Continue implementing testing for symmetric-merge.

* subversion/tests/cmdline/merge_symmetric_tests.py
  (assert_equal, get_3ways_from_output,
   expected_symmetric_merge_output, three_way_merge,
   three_way_merge_no_op, no_op_commit): New functions.
  (symmetric_merge): Rework checking for expected output, and remove
    the 'lines' parameter. Add an 'expect_changes' parameter with skeleton
    code.
  (merge_once_1, merge_once_2, merge_once_3, merge_once_4,
   cherry2_fwd): Specify the expected results in a compact, testable form.
  (merge_twice_same_direction_1, merge_twice_same_direction_2): New
    tests.
  (test_list): Add the new tests.

Modified:
    subversion/trunk/subversion/tests/cmdline/merge_symmetric_tests.py

Modified: subversion/trunk/subversion/tests/cmdline/merge_symmetric_tests.py
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/cmdline/merge_symmetric_tests.py?rev=1332174&r1=1332173&r2=1332174&view=diff
==============================================================================
--- subversion/trunk/subversion/tests/cmdline/merge_symmetric_tests.py (original)
+++ subversion/trunk/subversion/tests/cmdline/merge_symmetric_tests.py Mon Apr 30 12:35:38
2012
@@ -149,6 +149,14 @@ from merge_tests import svn_merge
 
 ########################################################################
 
+def assert_equal(a, b):
+  """Assert that two generic Python objects are equal.  If not, raise an
+     exception giving their values.  Rationale:  During debugging, it's
+     easier to see what's wrong if we see the values rather than just
+     an indication that the assertion failed."""
+  if a != b:
+    raise Exception("assert_equal failed: a = (%s), b = (%s)" % (a, b))
+
 def get_mergeinfo_change(sbox, target):
   """Return a list of revision numbers representing the mergeinfo change
   on TARGET (working version against base).  Non-recursive."""
@@ -167,6 +175,29 @@ def get_mergeinfo_change(sbox, target):
         merged_revs += range(int(r_start), int(r_end) + 1)
   return merged_revs
 
+def get_3ways_from_output(output):
+  """Scan the list of lines OUTPUT for indications of 3-way merges.
+     Return a list of (base, source-right) tuples."""
+  ### Problem: test suite strips debugging output within run_and_verify_...()
+  ### so we don't see it here.  And relying on debug output is a temporary
+  ### measure only.  Better to access svn_client_find_symmetric_merge()
+  ### directly, via bindings?
+
+  merges = []
+  for line in output:
+    print "## " + line,
+    # Extract "A1" from a line like "DBG: merge.c:11336: base  svn://.../A@1"
+    match = re.search(r'merge\.c:.* base .* /(\w+)@([0-9-]+)', line)
+    if match:
+      base = match.group(1) + match.group(2)
+    match = re.search(r'merge\.c:.* right.* /(\w+)@([0-9-]+)', line)
+    if match:
+      right = match.group(1) + match.group(2)
+      assert base is not None
+      merges.append((base, right))
+      base = None
+  return merges
+
 def make_branches(sbox):
   """Make branches A and B."""
   sbox.build()
@@ -188,8 +219,40 @@ def modify_branch(sbox, branch, number, 
     sbox.simple_propset('prop-' + uniq, uniq, branch + '/D')
   sbox.simple_commit()
 
-def symmetric_merge(sbox, source, target, lines=None, args=[],
-                    expect_mi=None, expect_3ways=None):
+def expected_symmetric_merge_output(target, expect_3ways):
+  """Calculate the expected output."""
+
+  # (This is rather specific to the current implementation.)
+
+  # Match a notification for each rev-range.
+  if expect_3ways:
+    rev_ranges = []
+    for base, right in expect_3ways:
+      if base[0] == right[0]:
+        base_rev = int(base[1:])
+        right_rev = int(right[1:])
+        rev_ranges += [(base_rev + 1, right_rev)];
+  else:
+    rev_ranges = None
+
+  # Match any content modifications; but not of the root of the branch
+  # because we don't intentionally modify the branch root node in most
+  # tests and we don't want to accidentally overlook a mergeinfo change.
+  lines = ["(A |D |[UG] | [UG]|[UG][UG])   " + target + "/.*\n"]
+
+  # Match mergeinfo changes.  (### Subtrees are not yet supported here.)
+  lines += [" [UG]   " + target + "\n"]
+
+  # At the moment, the symmetric merge code sometimes gives 'Merging
+  # differences between repository URLs' notifications when it need not
+  # or should not; so expect that.
+  lines += ["--- Merging differences between repository URLs into '%s':\n" % (target,),
+            "--- Recording mergeinfo for merge between repository URLs into '%s':\n" % (target,)]
+
+  return expected_merge_output(rev_ranges, lines, target=target)
+
+def symmetric_merge(sbox, source, target, args=[],
+                    expect_changes=None, expect_mi=None, expect_3ways=None):
   """Do a complete, automatic merge from path SOURCE to path TARGET, and
   commit.  Verify the output and that there is no error.
   ### TODO: Verify the changes made.)
@@ -205,28 +268,34 @@ def symmetric_merge(sbox, source, target
   # First, update the WC target because mixed-rev is not fully supported.
   sbox.simple_update(target)
 
-  if lines is None:
-    lines = ["--- Recording mergeinfo for .*\n",
-             "(A |D |[UG] | [UG]|[UG][UG])   " + target + ".*\n"]
-  else:
-    # Expect mergeinfo on the target; caller must supply matches for any
-    # subtree mergeinfo paths.
-    lines.append(" [UG]   " + target + "\n")
-  exp_out = expected_merge_output(None, lines, target=target)
-  svntest.actions.run_and_verify_svn(None, exp_out, [],
+  exp_out = expected_symmetric_merge_output(target, expect_3ways)
+  exit, out, err = svntest.actions.run_and_verify_svn(None, exp_out, [],
                                      'merge', '--symmetric',
                                      '^/' + source, target,
                                      *args)
+
+  if expect_changes is not None:
+    ### actual_changes = get_changes(sbox, target)
+    ### assert_equal(actual_changes, expect_changes)
+    pass
+
   if expect_mi is not None:
     actual_mi_change = get_mergeinfo_change(sbox, target)
-    assert actual_mi_change == expect_mi
+    assert_equal(actual_mi_change, expect_mi)
+
   if expect_3ways is not None:
-    ### actual_3ways = ...
-    ### assert actual_3ways == expect_3ways
+    ### actual_3ways = get_3ways_from_output(out)
+    ### assert_equal(actual_3ways, expect_3ways)
     pass
 
   sbox.simple_commit()
 
+def three_way_merge(base_node, source_right_node):
+  return (base_node, source_right_node)
+
+def three_way_merge_no_op(base_node, source_right_node):
+  return (base_node, source_right_node)
+
 def cherry_pick(sbox, rev, source, target):
   """Cherry-pick merge revision REV from branch SOURCE to branch TARGET
   (both WC-relative paths), and commit."""
@@ -234,58 +303,161 @@ def cherry_pick(sbox, rev, source, targe
   svn_merge(rev, source, target)
   sbox.simple_commit()
 
+no_op_commit__n = 0
+def no_op_commit(sbox):
+  """Commit a new revision that does not affect the branches under test."""
+
+  global no_op_commit__n
+  sbox.simple_propset('foo', str(no_op_commit__n), 'iota')
+  no_op_commit__n += 1
+  sbox.simple_commit('iota')
+
 
 #----------------------------------------------------------------------
 
 # Merge once
-#
-#     A (--?---
-#       (    \
-#     B (--?--x
 
 @SkipUnless(server_has_mergeinfo)
 def merge_once_1(sbox):
   """merge_once_1"""
+
+  #   A (------
+  #     (    \
+  #   B (-----x
+  #     2 34  5
+
   make_branches(sbox)
-  symmetric_merge(sbox, 'A', 'B')
+  no_op_commit(sbox)  # r3
+  no_op_commit(sbox)  # r4
+
+  symmetric_merge(sbox, 'A', 'B',
+                  expect_changes=[],
+                  expect_mi=[2, 3, 4],
+                  expect_3ways=[three_way_merge_no_op('A1', 'A4')])
 
 @SkipUnless(server_has_mergeinfo)
 def merge_once_2(sbox):
   """merge_once_2"""
+
+  #   A (-o----
+  #     (    \
+  #   B (-----x
+  #     2 34  5
+
   make_branches(sbox)
-  modify_branch(sbox, 'A', 1)
-  symmetric_merge(sbox, 'A', 'B')
+  modify_branch(sbox, 'A', 3)
+  no_op_commit(sbox)  # r4
+
+  symmetric_merge(sbox, 'A', 'B',
+                  expect_changes=['A3'],
+                  expect_mi=[2, 3, 4],
+                  expect_3ways=[three_way_merge('A1', 'A4')])
 
 @SkipUnless(server_has_mergeinfo)
 def merge_once_3(sbox):
   """merge_once_3"""
+
+  #   A (------
+  #     (    \
+  #   B (--o--x
+  #     2 34  5
+
   make_branches(sbox)
-  modify_branch(sbox, 'B', 1)
-  symmetric_merge(sbox, 'A', 'B')
+  no_op_commit(sbox)  # r3
+  modify_branch(sbox, 'B', 4)
+
+  symmetric_merge(sbox, 'A', 'B',
+                  expect_changes=[],
+                  expect_mi=[2, 3, 4],
+                  expect_3ways=[three_way_merge_no_op('A1', 'A4')])
 
 @SkipUnless(server_has_mergeinfo)
 def merge_once_4(sbox):
   """merge_once_4"""
+
+  #   A (-o----
+  #     (    \
+  #   B (--o--x
+  #     2 34  5
+
+  make_branches(sbox)
+  modify_branch(sbox, 'A', 3)
+  modify_branch(sbox, 'B', 4)
+
+  symmetric_merge(sbox, 'A', 'B',
+                  expect_changes=['A3'],
+                  expect_mi=[2, 3, 4],
+                  expect_3ways=[three_way_merge('A1', 'A4')])
+
+#----------------------------------------------------------------------
+
+# Merge twice in same direction
+
+@SkipUnless(server_has_mergeinfo)
+def merge_twice_same_direction_1(sbox):
+  """merge_twice_same_direction_1"""
+
+  #   A (--o-----------
+  #     (     \      \
+  #   B (---o--x------x
+  #     2  34  5  67  8
+
+  make_branches(sbox)
+  modify_branch(sbox, 'A', 3)
+  modify_branch(sbox, 'B', 4)
+
+  symmetric_merge(sbox, 'A', 'B',
+                  expect_changes=['A3'],
+                  expect_mi=[2, 3, 4],
+                  expect_3ways=[three_way_merge('A1', 'A4')])
+
+  no_op_commit(sbox)  # r6
+  no_op_commit(sbox)  # r7
+
+  symmetric_merge(sbox, 'A', 'B',
+                  expect_changes=[],
+                  expect_mi=[5, 6, 7],
+                  expect_3ways=[three_way_merge_no_op('A4', 'A7')])
+
+@SkipUnless(server_has_mergeinfo)
+def merge_twice_same_direction_2(sbox):
+  """merge_twice_same_direction_2"""
+
+  #   A (--o------o----
+  #     (     \      \
+  #   B (---o--x---o--x
+  #     2  34  5  67  8
+
   make_branches(sbox)
   modify_branch(sbox, 'A', 3)
   modify_branch(sbox, 'B', 4)
 
-  expect_mi = [2, 3, 4]
   symmetric_merge(sbox, 'A', 'B',
-                  expect_mi=expect_mi)
+                  expect_changes=['A3'],
+                  expect_mi=[2, 3, 4],
+                  expect_3ways=[three_way_merge('A1', 'A4')])
+
+  modify_branch(sbox, 'A', 6)
+  modify_branch(sbox, 'B', 7)
+
+  symmetric_merge(sbox, 'A', 'B',
+                  expect_changes=['A6'],
+                  expect_mi=[5, 6, 7],
+                  expect_3ways=[three_way_merge('A4', 'A7')])
 
 #----------------------------------------------------------------------
 
 # Cherry2, fwd
-#
-#     A (--o-----?-----c--o---
-#       (    \        /     \
-#     B (--o--x--o-[o]-------x
-#       2 34  5  6  7  8  9
-#
+
 @SkipUnless(server_has_mergeinfo)
 def cherry2_fwd(sbox):
   """cherry2-fwd"""
+
+  #   A (--o-----?-----c--o---
+  #     (    \        /     \
+  #   B (--o--x--o-[o]-------x
+  #     2 34  5  6  7  8  9
+
   make_branches(sbox)
   modify_branch(sbox, 'A', 3)
   modify_branch(sbox, 'B', 4)
@@ -295,14 +467,10 @@ def cherry2_fwd(sbox):
   cherry_pick(sbox, 7, 'B', 'A')
   modify_branch(sbox, 'A', 9)
 
-  # Expected merge:
-  #   Logical changes = A9 (and NOT A8)
-  #   Mergeinfo += A5-9
-  #   3-way merges: (Base=A8, Source-right=A9)
-  expect_mi = [5, 6, 7, 8, 9]
-  expect_3ways = [('A8', 'A9')]
   symmetric_merge(sbox, 'A', 'B',
-                  expect_mi=expect_mi, expect_3ways=expect_3ways)
+                  expect_changes=['A9'],  # and NOT A8
+                  expect_mi=[5, 6, 7, 8, 9],
+                  expect_3ways=[three_way_merge('A8', 'A9')])
 
 
 ########################################################################
@@ -315,6 +483,8 @@ test_list = [ None,
               merge_once_2,
               merge_once_3,
               merge_once_4,
+              merge_twice_same_direction_1,
+              merge_twice_same_direction_2,
               cherry2_fwd,
              ]
 



Mime
View raw message