o Added unittest2 which has added the new features in unittest for Python 2.7
  backported to Python 2.3+.  Some of the features desired include better
  verbose reporting in unittest2.TextTestRunner and decorator support for
  skipping tests and expected failures.

  http://pypi.python.org/pypi/unittest2

o Modified the existing .py tests to use unittest2 and decorated
  TestSTL.test_step_into_stl(), which is known to always fail currently, with
  @unittest2.expectedFailure.

llvm-svn: 110397
diff --git a/lldb/test/unittest2/util.py b/lldb/test/unittest2/util.py
new file mode 100644
index 0000000..c45d008
--- /dev/null
+++ b/lldb/test/unittest2/util.py
@@ -0,0 +1,99 @@
+"""Various utility functions."""
+
+__unittest = True
+
+
+_MAX_LENGTH = 80
+def safe_repr(obj, short=False):
+    try:
+        result = repr(obj)
+    except Exception:
+        result = object.__repr__(obj)
+    if not short or len(result) < _MAX_LENGTH:
+        return result
+    return result[:_MAX_LENGTH] + ' [truncated]...'
+
+def safe_str(obj):
+    try:
+        return str(obj)
+    except Exception:
+        return object.__str__(obj)
+
+def strclass(cls):
+    return "%s.%s" % (cls.__module__, cls.__name__)
+
+def sorted_list_difference(expected, actual):
+    """Finds elements in only one or the other of two, sorted input lists.
+
+    Returns a two-element tuple of lists.    The first list contains those
+    elements in the "expected" list but not in the "actual" list, and the
+    second contains those elements in the "actual" list but not in the
+    "expected" list.    Duplicate elements in either input list are ignored.
+    """
+    i = j = 0
+    missing = []
+    unexpected = []
+    while True:
+        try:
+            e = expected[i]
+            a = actual[j]
+            if e < a:
+                missing.append(e)
+                i += 1
+                while expected[i] == e:
+                    i += 1
+            elif e > a:
+                unexpected.append(a)
+                j += 1
+                while actual[j] == a:
+                    j += 1
+            else:
+                i += 1
+                try:
+                    while expected[i] == e:
+                        i += 1
+                finally:
+                    j += 1
+                    while actual[j] == a:
+                        j += 1
+        except IndexError:
+            missing.extend(expected[i:])
+            unexpected.extend(actual[j:])
+            break
+    return missing, unexpected
+
+def unorderable_list_difference(expected, actual, ignore_duplicate=False):
+    """Same behavior as sorted_list_difference but
+    for lists of unorderable items (like dicts).
+
+    As it does a linear search per item (remove) it
+    has O(n*n) performance.
+    """
+    missing = []
+    unexpected = []
+    while expected:
+        item = expected.pop()
+        try:
+            actual.remove(item)
+        except ValueError:
+            missing.append(item)
+        if ignore_duplicate:
+            for lst in expected, actual:
+                try:
+                    while True:
+                        lst.remove(item)
+                except ValueError:
+                    pass
+    if ignore_duplicate:
+        while actual:
+            item = actual.pop()
+            unexpected.append(item)
+            try:
+                while True:
+                    actual.remove(item)
+            except ValueError:
+                pass
+        return missing, unexpected
+
+    # anything left in actual is unexpected
+    return missing, actual