On 01/25/2013 01:47 PM, Ben Reser wrote:

To add some clarity here to what I'm saying above...

There are two options.

1) Build a new class (could be named RegexListOutput) like I mention
above or in an earlier email.  This will likely be a tad easier, since
you don't change the logic existing tests are using and thus you don't
have to do do negative testing against all the tests (which is
probably a lot) that use the existing classes.

2) Adjust RegexOutput so that it can handle more than one Regex.  It's
already expecting a list, it just ignores everything but the first
member.  This is probably the cleaner approach but you need to at a
minimum go through and check every use of RegexOutput to make sure it
isn't passing multiple regexes and consider what the impact is.
You'll also need to be very careful not to change the logic the
existing users of RegexOutput depend on.

Thanks a lot Ben...

I have taken your suggestion (2) and worked on it.
Attaching the updated patch and the log message. Please share your thoughts.


Thanks and regards
Prabhu
Support regex in the expected error list. In addition to directly matching the
entries of the expected error list with the actual error, support regex
in the entries of the expected error list. Set is_regex_list=True in
verify_outputs function to set an EXPECTED list of regexes.

* tests/cmdline/svntest/verify.py
  (ExpectedOutput): If IS_REGEX_LIST is True, the entries in the expected list
  will be treated as regexes.

  (createExpectedOutput): Handle is_regex_list, by default set as FALSE.
  (compare_and_display_lines): Handle is_regex_list, by default set as FALSE.

  Example:
  --------

  Expected err = [".* Verified revision 1.",
                  ".* Error verifying revision 2.",
                  ".*svnadmin: E160004*",
                  ".* Verified revision 3.",
                  ".*svnadmin: E165005*"]

  Actual err = ["* Verified revision 1.",
                "* Error verifying revision 2.",
                "svnadmin: E160004: Invalid change kind in rev file",
                "* Verified revision 3.",
                "svnadmin: E165005: Repository 'svn-test-work/repositories/svnadmin_tests-32' failed to verify"]

The above Expected err and Actual err would match successfully.

Earlier, only *exact* entries in the list were checked for match and hence
the above example wouldnt match successfully.
Index: tests/cmdline/svntest/verify.py
===================================================================
--- tests/cmdline/svntest/verify.py     (revision 1437863)
+++ tests/cmdline/svntest/verify.py     (working copy)
@@ -80,16 +80,20 @@ class SVNDumpParseError(svntest.Failure):
 ######################################################################
 # Comparison of expected vs. actual output
 
-def createExpectedOutput(expected, output_type, match_all=True):
+def createExpectedOutput(expected, output_type, match_all=True,
+                         is_regex_list=False):
   """Return EXPECTED, promoted to an ExpectedOutput instance if not
   None.  Raise SVNIncorrectDatatype if the data type of EXPECTED is
   not handled."""
   if isinstance(expected, list):
-    expected = ExpectedOutput(expected)
+    if is_regex_list:
+      expected = RegexOutput(expected, match_all, is_regex_list)
+    else:
+      expected = ExpectedOutput(expected)
   elif isinstance(expected, str):
-    expected = RegexOutput(expected, match_all)
+    expected = RegexOutput(expected, match_all, False)
   elif isinstance(expected, int):
-    expected = RegexOutput(".*: E%d:.*" % expected, False)
+    expected = RegexOutput(".*: E%d:.*" % expected, False, False)
   elif expected is AnyOutput:
     expected = AnyOutput()
   elif expected is not None and not isinstance(expected, ExpectedOutput):
@@ -102,15 +106,17 @@ class ExpectedOutput:
   is_regex = False
   is_unordered = False
 
-  def __init__(self, output, match_all=True):
+  def __init__(self, output, match_all=True, is_regex_list=False):
     """Initialize the expected output to OUTPUT which is a string, or a list
     of strings, or None meaning an empty list. If MATCH_ALL is True, the
     expected strings will be matched with the actual strings, one-to-one, in
     the same order. If False, they will be matched with a subset of the
     actual strings, one-to-one, in the same order, ignoring any other actual
-    strings among the matching ones."""
+    strings among the matching ones. If IS_REGEX_LIST is True, the entries in
+    the expected list will be treated as regexes."""
     self.output = output
     self.match_all = match_all
+    self.is_regex_list = is_regex_list
 
   def __str__(self):
     return str(self.output)
@@ -164,7 +170,7 @@ class ExpectedOutput:
 
   def is_equivalent_list(self, expected, actual):
     "Return whether EXPECTED and ACTUAL are equivalent."
-    if not self.is_regex:
+    if not self.is_regex and not self.is_regex_list:
       if self.match_all:
         # The EXPECTED lines must match the ACTUAL lines, one-to-one, in
         # the same order.
@@ -181,6 +187,16 @@ class ExpectedOutput:
             return True
       return False
 
+    if self.is_regex_list:
+      # List of regexes.
+      i_expected = 0
+      for actual_line in actual:
+        if re.match(expected[i_expected],actual_line):
+          i_expected += 1
+          if i_expected == len(expected):
+            return True
+      return False
+
     expected_re = expected[0]
     # If we want to check that every line matches the regexp
     # assume they all match and look for any that don't.  If
@@ -369,7 +385,8 @@ def compare_and_display_lines(message, label, expe
     raise raisable
 
 def verify_outputs(message, actual_stdout, actual_stderr,
-                   expected_stdout, expected_stderr, all_stdout=True):
+                   expected_stdout, expected_stderr, all_stdout=True,
+                   is_regex_list=False):
   """Compare and display expected vs. actual stderr and stdout lines:
   if they don't match, print the difference (preceded by MESSAGE iff
   not None) and raise an exception.
@@ -379,8 +396,10 @@ def verify_outputs(message, actual_stdout, actual_
   ACTUAL_STDOUT to match, every line in ACTUAL_STDOUT must match the
   EXPECTED_STDOUT regex, unless ALL_STDOUT is false.  For
   EXPECTED_STDERR regexes only one line in ACTUAL_STDERR need match."""
-  expected_stderr = createExpectedOutput(expected_stderr, 'stderr', False)
-  expected_stdout = createExpectedOutput(expected_stdout, 'stdout', all_stdout)
+  expected_stderr = createExpectedOutput(expected_stderr, 'stderr', False,
+                                         is_regex_list)
+  expected_stdout = createExpectedOutput(expected_stdout, 'stdout',
+                                         all_stdout, False)
 
   for (actual, expected, label, raisable) in (
       (actual_stderr, expected_stderr, 'STDERR', SVNExpectedStderr),

Reply via email to