Skip to content

Commit 5b38615

Browse files
authored
[lldb][test] Switch LLDB API tests from vendored unittest2 to unittest (#79945)
This removes the dependency LLDB API tests have on lldb/third_party/Python/module/unittest2, and instead uses the standard one provided by Python. This does not actually remove the vendored dep yet, nor update the docs. I'll do both those once this sticks. Non-trivial changes to call out: - expected failures (i.e. "bugnumber") don't have a reason anymore, so those params were removed - `assertItemsEqual` is now called `assertCountEqual` - When a test is marked xfail, our copy of unittest2 considers failures during teardown to be OK, but modern unittest does not. See TestThreadLocal.py. (Very likely could be a real bug/leak). - Our copy of unittest2 was patched to print all test results, even ones that don't happen, e.g. `(5 passes, 0 failures, 1 errors, 0 skipped, ...)`, but standard unittest prints a terser message that omits test result types that didn't happen, e.g. `OK (skipped=1)`. Our lit integration parses this stderr and needs to be updated w/ that expectation. I tested this w/ `ninja check-lldb-api` on Linux. There's a good chance non-Linux tests have similar quirks, but I'm not able to uncover those.
1 parent c92bf6b commit 5b38615

File tree

20 files changed

+115
-95
lines changed

20 files changed

+115
-95
lines changed

lldb/packages/Python/lldbsuite/test/configuration.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,14 @@
1212

1313

1414
# Third-party modules
15-
import unittest2
15+
import unittest
1616

1717
# LLDB Modules
1818
import lldbsuite
1919

2020

2121
# The test suite.
22-
suite = unittest2.TestSuite()
22+
suite = unittest.TestSuite()
2323

2424
# The list of categories we said we care about
2525
categories_list = None

lldb/packages/Python/lldbsuite/test/decorators.py

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
import subprocess
1212

1313
# Third-party modules
14-
import unittest2
14+
import unittest
1515

1616
# LLDB modules
1717
import lldb
@@ -115,11 +115,11 @@ def _compiler_supports(
115115

116116
def expectedFailureIf(condition, bugnumber=None):
117117
def expectedFailure_impl(func):
118-
if isinstance(func, type) and issubclass(func, unittest2.TestCase):
118+
if isinstance(func, type) and issubclass(func, unittest.TestCase):
119119
raise Exception("Decorator can only be used to decorate a test method")
120120

121121
if condition:
122-
return unittest2.expectedFailure(func)
122+
return unittest.expectedFailure(func)
123123
return func
124124

125125
if callable(bugnumber):
@@ -130,14 +130,14 @@ def expectedFailure_impl(func):
130130

131131
def expectedFailureIfFn(expected_fn, bugnumber=None):
132132
def expectedFailure_impl(func):
133-
if isinstance(func, type) and issubclass(func, unittest2.TestCase):
133+
if isinstance(func, type) and issubclass(func, unittest.TestCase):
134134
raise Exception("Decorator can only be used to decorate a test method")
135135

136136
@wraps(func)
137137
def wrapper(*args, **kwargs):
138138
xfail_reason = expected_fn(*args, **kwargs)
139139
if xfail_reason is not None:
140-
xfail_func = unittest2.expectedFailure(func)
140+
xfail_func = unittest.expectedFailure(func)
141141
xfail_func(*args, **kwargs)
142142
else:
143143
func(*args, **kwargs)
@@ -157,11 +157,11 @@ def wrapper(*args, **kwargs):
157157

158158
def skipTestIfFn(expected_fn, bugnumber=None):
159159
def skipTestIfFn_impl(func):
160-
if isinstance(func, type) and issubclass(func, unittest2.TestCase):
160+
if isinstance(func, type) and issubclass(func, unittest.TestCase):
161161
reason = expected_fn()
162162
# The return value is the reason (or None if we don't skip), so
163163
# reason is used for both args.
164-
return unittest2.skipIf(condition=reason, reason=reason)(func)
164+
return unittest.skipIf(condition=reason, reason=reason)(func)
165165

166166
@wraps(func)
167167
def wrapper(*args, **kwargs):
@@ -191,7 +191,7 @@ def wrapper(*args, **kwargs):
191191

192192
def _xfailForDebugInfo(expected_fn, bugnumber=None):
193193
def expectedFailure_impl(func):
194-
if isinstance(func, type) and issubclass(func, unittest2.TestCase):
194+
if isinstance(func, type) and issubclass(func, unittest.TestCase):
195195
raise Exception("Decorator can only be used to decorate a test method")
196196

197197
func.__xfail_for_debug_info_cat_fn__ = expected_fn
@@ -205,7 +205,7 @@ def expectedFailure_impl(func):
205205

206206
def _skipForDebugInfo(expected_fn, bugnumber=None):
207207
def skipImpl(func):
208-
if isinstance(func, type) and issubclass(func, unittest2.TestCase):
208+
if isinstance(func, type) and issubclass(func, unittest.TestCase):
209209
raise Exception("Decorator can only be used to decorate a test method")
210210

211211
func.__skip_for_debug_info_cat_fn__ = expected_fn
@@ -434,7 +434,7 @@ def add_test_categories(cat):
434434
cat = test_categories.validate(cat, True)
435435

436436
def impl(func):
437-
if isinstance(func, type) and issubclass(func, unittest2.TestCase):
437+
if isinstance(func, type) and issubclass(func, unittest.TestCase):
438438
raise Exception(
439439
"@add_test_categories can only be used to decorate a test method"
440440
)
@@ -465,7 +465,7 @@ def should_skip_benchmarks_test():
465465
def no_debug_info_test(func):
466466
"""Decorate the item as a test what don't use any debug info. If this annotation is specified
467467
then the test runner won't generate a separate test for each debug info format."""
468-
if isinstance(func, type) and issubclass(func, unittest2.TestCase):
468+
if isinstance(func, type) and issubclass(func, unittest.TestCase):
469469
raise Exception(
470470
"@no_debug_info_test can only be used to decorate a test method"
471471
)
@@ -631,7 +631,7 @@ def is_out_of_tree_debugserver():
631631

632632
def skipIfRemote(func):
633633
"""Decorate the item to skip tests if testing remotely."""
634-
return unittest2.skipIf(lldb.remote_platform, "skip on remote platform")(func)
634+
return unittest.skipIf(lldb.remote_platform, "skip on remote platform")(func)
635635

636636

637637
def skipIfNoSBHeaders(func):
@@ -768,7 +768,7 @@ def skipUnlessDarwin(func):
768768

769769

770770
def skipUnlessTargetAndroid(func):
771-
return unittest2.skipUnless(
771+
return unittest.skipUnless(
772772
lldbplatformutil.target_is_android(), "requires target to be Android"
773773
)(func)
774774

@@ -809,7 +809,7 @@ def skipIfPlatform(oslist):
809809
"""Decorate the item to skip tests if running on one of the listed platforms."""
810810
# This decorator cannot be ported to `skipIf` yet because it is used on entire
811811
# classes, which `skipIf` explicitly forbids.
812-
return unittest2.skipIf(
812+
return unittest.skipIf(
813813
lldbplatformutil.getPlatform() in oslist, "skip on %s" % (", ".join(oslist))
814814
)
815815

@@ -818,7 +818,7 @@ def skipUnlessPlatform(oslist):
818818
"""Decorate the item to skip tests unless running on one of the listed platforms."""
819819
# This decorator cannot be ported to `skipIf` yet because it is used on entire
820820
# classes, which `skipIf` explicitly forbids.
821-
return unittest2.skipUnless(
821+
return unittest.skipUnless(
822822
lldbplatformutil.getPlatform() in oslist,
823823
"requires one of %s" % (", ".join(oslist)),
824824
)
@@ -1078,7 +1078,7 @@ def _get_bool_config(key, fail_value=True):
10781078

10791079
def _get_bool_config_skip_if_decorator(key):
10801080
have = _get_bool_config(key)
1081-
return unittest2.skipIf(not have, "requires " + key)
1081+
return unittest.skipIf(not have, "requires " + key)
10821082

10831083

10841084
def skipIfCursesSupportMissing(func):
@@ -1110,7 +1110,7 @@ def skipIfLLVMTargetMissing(target):
11101110
found = True
11111111
break
11121112

1113-
return unittest2.skipIf(not found, "requires " + target)
1113+
return unittest.skipIf(not found, "requires " + target)
11141114

11151115

11161116
# Call sysctl on darwin to see if a specified hardware feature is available on this machine.

lldb/packages/Python/lldbsuite/test/dotest.py

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333
import tempfile
3434

3535
# Third-party modules
36-
import unittest2
36+
import unittest
3737

3838
# LLDB Modules
3939
import lldbsuite
@@ -658,7 +658,7 @@ def iter_filters():
658658
for filterspec in iter_filters():
659659
filtered = True
660660
print("adding filter spec %s to module %s" % (filterspec, repr(module)))
661-
tests = unittest2.defaultTestLoader.loadTestsFromName(filterspec, module)
661+
tests = unittest.defaultTestLoader.loadTestsFromName(filterspec, module)
662662
configuration.suite.addTests(tests)
663663

664664
# Forgo this module if the (base, filterspec) combo is invalid
@@ -669,9 +669,7 @@ def iter_filters():
669669
# Add the entire file's worth of tests since we're not filtered.
670670
# Also the fail-over case when the filterspec branch
671671
# (base, filterspec) combo doesn't make sense.
672-
configuration.suite.addTests(
673-
unittest2.defaultTestLoader.loadTestsFromName(base)
674-
)
672+
configuration.suite.addTests(unittest.defaultTestLoader.loadTestsFromName(base))
675673

676674

677675
def visit(prefix, dir, names):
@@ -1032,7 +1030,7 @@ def run_suite():
10321030
#
10331031

10341032
# Install the control-c handler.
1035-
unittest2.signals.installHandler()
1033+
unittest.signals.installHandler()
10361034

10371035
#
10381036
# Invoke the default TextTestRunner to run the test suite
@@ -1066,7 +1064,7 @@ def run_suite():
10661064

10671065
# Invoke the test runner.
10681066
if configuration.count == 1:
1069-
result = unittest2.TextTestRunner(
1067+
result = unittest.TextTestRunner(
10701068
stream=sys.stderr,
10711069
verbosity=configuration.verbose,
10721070
resultclass=test_result.LLDBTestResult,
@@ -1077,7 +1075,7 @@ def run_suite():
10771075
# not enforced.
10781076
test_result.LLDBTestResult.__ignore_singleton__ = True
10791077
for i in range(configuration.count):
1080-
result = unittest2.TextTestRunner(
1078+
result = unittest.TextTestRunner(
10811079
stream=sys.stderr,
10821080
verbosity=configuration.verbose,
10831081
resultclass=test_result.LLDBTestResult,

lldb/packages/Python/lldbsuite/test/lldbtest.py

Lines changed: 9 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@
4444
import traceback
4545

4646
# Third-party modules
47-
import unittest2
47+
import unittest
4848

4949
# LLDB modules
5050
import lldb
@@ -517,7 +517,7 @@ def builder_module():
517517
return lldbplatformutil.builder_module()
518518

519519

520-
class Base(unittest2.TestCase):
520+
class Base(unittest.TestCase):
521521
"""
522522
Abstract base for performing lldb (see TestBase) or other generic tests (see
523523
BenchBase for one example). lldbtest.Base works with the test driver to
@@ -1090,17 +1090,14 @@ def markFailure(self):
10901090
# Once by the Python unittest framework, and a second time by us.
10911091
print("FAIL", file=sbuf)
10921092

1093-
def markExpectedFailure(self, err, bugnumber):
1093+
def markExpectedFailure(self, err):
10941094
"""Callback invoked when an expected failure/error occurred."""
10951095
self.__expected__ = True
10961096
with recording(self, False) as sbuf:
10971097
# False because there's no need to write "expected failure" to the
10981098
# stderr twice.
10991099
# Once by the Python unittest framework, and a second time by us.
1100-
if bugnumber is None:
1101-
print("expected failure", file=sbuf)
1102-
else:
1103-
print("expected failure (problem id:" + str(bugnumber) + ")", file=sbuf)
1100+
print("expected failure", file=sbuf)
11041101

11051102
def markSkippedTest(self):
11061103
"""Callback invoked when a test is skipped."""
@@ -1111,19 +1108,14 @@ def markSkippedTest(self):
11111108
# Once by the Python unittest framework, and a second time by us.
11121109
print("skipped test", file=sbuf)
11131110

1114-
def markUnexpectedSuccess(self, bugnumber):
1111+
def markUnexpectedSuccess(self):
11151112
"""Callback invoked when an unexpected success occurred."""
11161113
self.__unexpected__ = True
11171114
with recording(self, False) as sbuf:
11181115
# False because there's no need to write "unexpected success" to the
11191116
# stderr twice.
11201117
# Once by the Python unittest framework, and a second time by us.
1121-
if bugnumber is None:
1122-
print("unexpected success", file=sbuf)
1123-
else:
1124-
print(
1125-
"unexpected success (problem id:" + str(bugnumber) + ")", file=sbuf
1126-
)
1118+
print("unexpected success", file=sbuf)
11271119

11281120
def getRerunArgs(self):
11291121
return " -f %s.%s" % (self.__class__.__name__, self._testMethodName)
@@ -1704,13 +1696,11 @@ def test_method(self, attrvalue=attrvalue):
17041696

17051697
xfail_reason = xfail_for_debug_info_cat_fn(cat)
17061698
if xfail_reason:
1707-
test_method = unittest2.expectedFailure(xfail_reason)(
1708-
test_method
1709-
)
1699+
test_method = unittest.expectedFailure(test_method)
17101700

17111701
skip_reason = skip_for_debug_info_cat_fn(cat)
17121702
if skip_reason:
1713-
test_method = unittest2.skip(skip_reason)(test_method)
1703+
test_method = unittest.skip(skip_reason)(test_method)
17141704

17151705
newattrs[method_name] = test_method
17161706

@@ -2226,7 +2216,7 @@ def completions_match(self, command, completions):
22262216
match_strings = lldb.SBStringList()
22272217
interp.HandleCompletion(command, len(command), 0, -1, match_strings)
22282218
# match_strings is a 1-indexed list, so we have to slice...
2229-
self.assertItemsEqual(
2219+
self.assertCountEqual(
22302220
completions, list(match_strings)[1:], "List of returned completion is wrong"
22312221
)
22322222

lldb/packages/Python/lldbsuite/test/test_result.py

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,14 @@
1212
import traceback
1313

1414
# Third-party modules
15-
import unittest2
15+
import unittest
1616

1717
# LLDB Modules
1818
from . import configuration
1919
from lldbsuite.test_event import build_exception
2020

2121

22-
class LLDBTestResult(unittest2.TextTestResult):
22+
class LLDBTestResult(unittest.TextTestResult):
2323
"""
2424
Enforce a singleton pattern to allow introspection of test progress.
2525
@@ -243,7 +243,7 @@ def addFailure(self, test, err):
243243
if self.checkExclusion(
244244
configuration.xfail_tests, test.id()
245245
) or self.checkCategoryExclusion(configuration.xfail_categories, test):
246-
self.addExpectedFailure(test, err, None)
246+
self.addExpectedFailure(test, err)
247247
return
248248

249249
configuration.sdir_has_content = True
@@ -264,12 +264,12 @@ def addFailure(self, test, err):
264264
else:
265265
configuration.failures_per_category[category] = 1
266266

267-
def addExpectedFailure(self, test, err, bugnumber):
267+
def addExpectedFailure(self, test, err):
268268
configuration.sdir_has_content = True
269-
super(LLDBTestResult, self).addExpectedFailure(test, err, bugnumber)
269+
super(LLDBTestResult, self).addExpectedFailure(test, err)
270270
method = getattr(test, "markExpectedFailure", None)
271271
if method:
272-
method(err, bugnumber)
272+
method(err)
273273
self.stream.write(
274274
"XFAIL: LLDB (%s) :: %s\n" % (self._config_string(test), str(test))
275275
)
@@ -285,12 +285,12 @@ def addSkip(self, test, reason):
285285
% (self._config_string(test), str(test), reason)
286286
)
287287

288-
def addUnexpectedSuccess(self, test, bugnumber):
288+
def addUnexpectedSuccess(self, test):
289289
configuration.sdir_has_content = True
290-
super(LLDBTestResult, self).addUnexpectedSuccess(test, bugnumber)
290+
super(LLDBTestResult, self).addUnexpectedSuccess(test)
291291
method = getattr(test, "markUnexpectedSuccess", None)
292292
if method:
293-
method(bugnumber)
293+
method()
294294
self.stream.write(
295295
"XPASS: LLDB (%s) :: %s\n" % (self._config_string(test), str(test))
296296
)

lldb/test/API/commands/expression/test/TestExprs.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
"""
1313

1414

15-
import unittest2
15+
import unittest
1616
import lldb
1717
from lldbsuite.test.decorators import *
1818
from lldbsuite.test.lldbtest import *
@@ -46,7 +46,7 @@ def build_and_run(self):
4646

4747
# llvm.org/pr17135 <rdar://problem/14874559>
4848
# APFloat::toString does not identify the correct (i.e. least) precision.
49-
@unittest2.expectedFailure
49+
@unittest.expectedFailure
5050
def test_floating_point_expr_commands(self):
5151
self.build_and_run()
5252

lldb/test/API/functionalities/breakpoint/thread_plan_user_breakpoint/TestThreadPlanUserBreakpoint.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
"""
99

1010

11-
import unittest2
11+
import unittest
1212
import lldb
1313
from lldbsuite.test.decorators import *
1414
from lldbsuite.test.lldbtest import *

0 commit comments

Comments
 (0)