https://github.com/rupprecht created https://github.com/llvm/llvm-project/pull/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-abi` on Linux. There's a good chance non-Linux tests have similar quirks, but I'm not able to uncover those. >From fa34f52771a31a424503c2a4b33c1a31b4ecb597 Mon Sep 17 00:00:00 2001 From: Jordan Rupprecht <ruppre...@google.com> Date: Mon, 29 Jan 2024 19:07:36 -0800 Subject: [PATCH 1/5] Blanket unittest2 -> unittest replacement (excluding docs) --- .../Python/lldbsuite/test/configuration.py | 4 +-- .../Python/lldbsuite/test/decorators.py | 34 +++++++++---------- lldb/packages/Python/lldbsuite/test/dotest.py | 12 +++---- .../Python/lldbsuite/test/lldbtest.py | 8 ++--- .../Python/lldbsuite/test/test_result.py | 4 +-- .../API/commands/expression/test/TestExprs.py | 4 +-- .../TestThreadPlanUserBreakpoint.py | 2 +- .../jitloader_gdb/TestJITLoaderGDB.py | 4 +-- .../thread/state/TestThreadStates.py | 6 ++-- .../API/functionalities/tty/TestTerminal.py | 6 ++-- .../API/lang/c/shared_lib/TestSharedLib.py | 4 +-- .../TestSharedLibStrippedSymbols.py | 4 +-- .../lang/cpp/namespace/TestNamespaceLookup.py | 10 +++--- .../TestCppReferenceToOuterClass.py | 4 +-- .../lang/objc/hidden-ivars/TestHiddenIvars.py | 4 +-- .../API/macosx/universal/TestUniversal.py | 8 ++--- .../test/test_lldbgdbserverutils.py | 4 +-- 17 files changed, 61 insertions(+), 61 deletions(-) diff --git a/lldb/packages/Python/lldbsuite/test/configuration.py b/lldb/packages/Python/lldbsuite/test/configuration.py index 2a4b9b3c070c7..685f491c85fe1 100644 --- a/lldb/packages/Python/lldbsuite/test/configuration.py +++ b/lldb/packages/Python/lldbsuite/test/configuration.py @@ -12,14 +12,14 @@ # Third-party modules -import unittest2 +import unittest # LLDB Modules import lldbsuite # The test suite. -suite = unittest2.TestSuite() +suite = unittest.TestSuite() # The list of categories we said we care about categories_list = None diff --git a/lldb/packages/Python/lldbsuite/test/decorators.py b/lldb/packages/Python/lldbsuite/test/decorators.py index 0fb146913388e..a5e1fa51cf6e6 100644 --- a/lldb/packages/Python/lldbsuite/test/decorators.py +++ b/lldb/packages/Python/lldbsuite/test/decorators.py @@ -11,7 +11,7 @@ import subprocess # Third-party modules -import unittest2 +import unittest # LLDB modules import lldb @@ -115,11 +115,11 @@ def _compiler_supports( def expectedFailureIf(condition, bugnumber=None): def expectedFailure_impl(func): - if isinstance(func, type) and issubclass(func, unittest2.TestCase): + if isinstance(func, type) and issubclass(func, unittest.TestCase): raise Exception("Decorator can only be used to decorate a test method") if condition: - return unittest2.expectedFailure(func) + return unittest.expectedFailure(func) return func if callable(bugnumber): @@ -130,14 +130,14 @@ def expectedFailure_impl(func): def expectedFailureIfFn(expected_fn, bugnumber=None): def expectedFailure_impl(func): - if isinstance(func, type) and issubclass(func, unittest2.TestCase): + if isinstance(func, type) and issubclass(func, unittest.TestCase): raise Exception("Decorator can only be used to decorate a test method") @wraps(func) def wrapper(*args, **kwargs): xfail_reason = expected_fn(*args, **kwargs) if xfail_reason is not None: - xfail_func = unittest2.expectedFailure(func) + xfail_func = unittest.expectedFailure(func) xfail_func(*args, **kwargs) else: func(*args, **kwargs) @@ -157,11 +157,11 @@ def wrapper(*args, **kwargs): def skipTestIfFn(expected_fn, bugnumber=None): def skipTestIfFn_impl(func): - if isinstance(func, type) and issubclass(func, unittest2.TestCase): + if isinstance(func, type) and issubclass(func, unittest.TestCase): reason = expected_fn() # The return value is the reason (or None if we don't skip), so # reason is used for both args. - return unittest2.skipIf(condition=reason, reason=reason)(func) + return unittest.skipIf(condition=reason, reason=reason)(func) @wraps(func) def wrapper(*args, **kwargs): @@ -191,7 +191,7 @@ def wrapper(*args, **kwargs): def _xfailForDebugInfo(expected_fn, bugnumber=None): def expectedFailure_impl(func): - if isinstance(func, type) and issubclass(func, unittest2.TestCase): + if isinstance(func, type) and issubclass(func, unittest.TestCase): raise Exception("Decorator can only be used to decorate a test method") func.__xfail_for_debug_info_cat_fn__ = expected_fn @@ -205,7 +205,7 @@ def expectedFailure_impl(func): def _skipForDebugInfo(expected_fn, bugnumber=None): def skipImpl(func): - if isinstance(func, type) and issubclass(func, unittest2.TestCase): + if isinstance(func, type) and issubclass(func, unittest.TestCase): raise Exception("Decorator can only be used to decorate a test method") func.__skip_for_debug_info_cat_fn__ = expected_fn @@ -434,7 +434,7 @@ def add_test_categories(cat): cat = test_categories.validate(cat, True) def impl(func): - if isinstance(func, type) and issubclass(func, unittest2.TestCase): + if isinstance(func, type) and issubclass(func, unittest.TestCase): raise Exception( "@add_test_categories can only be used to decorate a test method" ) @@ -465,7 +465,7 @@ def should_skip_benchmarks_test(): def no_debug_info_test(func): """Decorate the item as a test what don't use any debug info. If this annotation is specified then the test runner won't generate a separate test for each debug info format.""" - if isinstance(func, type) and issubclass(func, unittest2.TestCase): + if isinstance(func, type) and issubclass(func, unittest.TestCase): raise Exception( "@no_debug_info_test can only be used to decorate a test method" ) @@ -631,7 +631,7 @@ def is_out_of_tree_debugserver(): def skipIfRemote(func): """Decorate the item to skip tests if testing remotely.""" - return unittest2.skipIf(lldb.remote_platform, "skip on remote platform")(func) + return unittest.skipIf(lldb.remote_platform, "skip on remote platform")(func) def skipIfNoSBHeaders(func): @@ -768,7 +768,7 @@ def skipUnlessDarwin(func): def skipUnlessTargetAndroid(func): - return unittest2.skipUnless( + return unittest.skipUnless( lldbplatformutil.target_is_android(), "requires target to be Android" )(func) @@ -809,7 +809,7 @@ def skipIfPlatform(oslist): """Decorate the item to skip tests if running on one of the listed platforms.""" # This decorator cannot be ported to `skipIf` yet because it is used on entire # classes, which `skipIf` explicitly forbids. - return unittest2.skipIf( + return unittest.skipIf( lldbplatformutil.getPlatform() in oslist, "skip on %s" % (", ".join(oslist)) ) @@ -818,7 +818,7 @@ def skipUnlessPlatform(oslist): """Decorate the item to skip tests unless running on one of the listed platforms.""" # This decorator cannot be ported to `skipIf` yet because it is used on entire # classes, which `skipIf` explicitly forbids. - return unittest2.skipUnless( + return unittest.skipUnless( lldbplatformutil.getPlatform() in oslist, "requires one of %s" % (", ".join(oslist)), ) @@ -1078,7 +1078,7 @@ def _get_bool_config(key, fail_value=True): def _get_bool_config_skip_if_decorator(key): have = _get_bool_config(key) - return unittest2.skipIf(not have, "requires " + key) + return unittest.skipIf(not have, "requires " + key) def skipIfCursesSupportMissing(func): @@ -1110,7 +1110,7 @@ def skipIfLLVMTargetMissing(target): found = True break - return unittest2.skipIf(not found, "requires " + target) + return unittest.skipIf(not found, "requires " + target) # Call sysctl on darwin to see if a specified hardware feature is available on this machine. diff --git a/lldb/packages/Python/lldbsuite/test/dotest.py b/lldb/packages/Python/lldbsuite/test/dotest.py index 4393e0caacaab..e6d9a2efb3159 100644 --- a/lldb/packages/Python/lldbsuite/test/dotest.py +++ b/lldb/packages/Python/lldbsuite/test/dotest.py @@ -33,7 +33,7 @@ import tempfile # Third-party modules -import unittest2 +import unittest # LLDB Modules import lldbsuite @@ -658,7 +658,7 @@ def iter_filters(): for filterspec in iter_filters(): filtered = True print("adding filter spec %s to module %s" % (filterspec, repr(module))) - tests = unittest2.defaultTestLoader.loadTestsFromName(filterspec, module) + tests = unittest.defaultTestLoader.loadTestsFromName(filterspec, module) configuration.suite.addTests(tests) # Forgo this module if the (base, filterspec) combo is invalid @@ -670,7 +670,7 @@ def iter_filters(): # Also the fail-over case when the filterspec branch # (base, filterspec) combo doesn't make sense. configuration.suite.addTests( - unittest2.defaultTestLoader.loadTestsFromName(base) + unittest.defaultTestLoader.loadTestsFromName(base) ) @@ -1032,7 +1032,7 @@ def run_suite(): # # Install the control-c handler. - unittest2.signals.installHandler() + unittest.signals.installHandler() # # Invoke the default TextTestRunner to run the test suite @@ -1066,7 +1066,7 @@ def run_suite(): # Invoke the test runner. if configuration.count == 1: - result = unittest2.TextTestRunner( + result = unittest.TextTestRunner( stream=sys.stderr, verbosity=configuration.verbose, resultclass=test_result.LLDBTestResult, @@ -1077,7 +1077,7 @@ def run_suite(): # not enforced. test_result.LLDBTestResult.__ignore_singleton__ = True for i in range(configuration.count): - result = unittest2.TextTestRunner( + result = unittest.TextTestRunner( stream=sys.stderr, verbosity=configuration.verbose, resultclass=test_result.LLDBTestResult, diff --git a/lldb/packages/Python/lldbsuite/test/lldbtest.py b/lldb/packages/Python/lldbsuite/test/lldbtest.py index d944b09cbcc47..2c4446d8aebc5 100644 --- a/lldb/packages/Python/lldbsuite/test/lldbtest.py +++ b/lldb/packages/Python/lldbsuite/test/lldbtest.py @@ -44,7 +44,7 @@ import traceback # Third-party modules -import unittest2 +import unittest # LLDB modules import lldb @@ -517,7 +517,7 @@ def builder_module(): return lldbplatformutil.builder_module() -class Base(unittest2.TestCase): +class Base(unittest.TestCase): """ Abstract base for performing lldb (see TestBase) or other generic tests (see BenchBase for one example). lldbtest.Base works with the test driver to @@ -1704,13 +1704,13 @@ def test_method(self, attrvalue=attrvalue): xfail_reason = xfail_for_debug_info_cat_fn(cat) if xfail_reason: - test_method = unittest2.expectedFailure(xfail_reason)( + test_method = unittest.expectedFailure(xfail_reason)( test_method ) skip_reason = skip_for_debug_info_cat_fn(cat) if skip_reason: - test_method = unittest2.skip(skip_reason)(test_method) + test_method = unittest.skip(skip_reason)(test_method) newattrs[method_name] = test_method diff --git a/lldb/packages/Python/lldbsuite/test/test_result.py b/lldb/packages/Python/lldbsuite/test/test_result.py index cb84c909c4196..2690906232b97 100644 --- a/lldb/packages/Python/lldbsuite/test/test_result.py +++ b/lldb/packages/Python/lldbsuite/test/test_result.py @@ -12,14 +12,14 @@ import traceback # Third-party modules -import unittest2 +import unittest # LLDB Modules from . import configuration from lldbsuite.test_event import build_exception -class LLDBTestResult(unittest2.TextTestResult): +class LLDBTestResult(unittest.TextTestResult): """ Enforce a singleton pattern to allow introspection of test progress. diff --git a/lldb/test/API/commands/expression/test/TestExprs.py b/lldb/test/API/commands/expression/test/TestExprs.py index e95c76b7104c2..0e3d2e6cf41ff 100644 --- a/lldb/test/API/commands/expression/test/TestExprs.py +++ b/lldb/test/API/commands/expression/test/TestExprs.py @@ -12,7 +12,7 @@ """ -import unittest2 +import unittest import lldb from lldbsuite.test.decorators import * from lldbsuite.test.lldbtest import * @@ -46,7 +46,7 @@ def build_and_run(self): # llvm.org/pr17135 <rdar://problem/14874559> # APFloat::toString does not identify the correct (i.e. least) precision. - @unittest2.expectedFailure + @unittest.expectedFailure def test_floating_point_expr_commands(self): self.build_and_run() diff --git a/lldb/test/API/functionalities/breakpoint/thread_plan_user_breakpoint/TestThreadPlanUserBreakpoint.py b/lldb/test/API/functionalities/breakpoint/thread_plan_user_breakpoint/TestThreadPlanUserBreakpoint.py index d9b7426b14844..ee597ad2b148c 100644 --- a/lldb/test/API/functionalities/breakpoint/thread_plan_user_breakpoint/TestThreadPlanUserBreakpoint.py +++ b/lldb/test/API/functionalities/breakpoint/thread_plan_user_breakpoint/TestThreadPlanUserBreakpoint.py @@ -8,7 +8,7 @@ """ -import unittest2 +import unittest import lldb from lldbsuite.test.decorators import * from lldbsuite.test.lldbtest import * diff --git a/lldb/test/API/functionalities/jitloader_gdb/TestJITLoaderGDB.py b/lldb/test/API/functionalities/jitloader_gdb/TestJITLoaderGDB.py index a074215244787..98c0b149003df 100644 --- a/lldb/test/API/functionalities/jitloader_gdb/TestJITLoaderGDB.py +++ b/lldb/test/API/functionalities/jitloader_gdb/TestJITLoaderGDB.py @@ -1,7 +1,7 @@ """Test for the JITLoaderGDB interface""" -import unittest2 +import unittest import os import lldb from lldbsuite.test import lldbutil @@ -14,7 +14,7 @@ class JITLoaderGDBTestCase(TestBase): lambda: "Skipped because the test crashes the test runner", bugnumber="llvm.org/pr24702", ) - @unittest2.expectedFailure # llvm.org/pr24702 + @unittest.expectedFailure # llvm.org/pr24702 def test_bogus_values(self): """Test that we handle inferior misusing the GDB JIT interface""" self.build() diff --git a/lldb/test/API/functionalities/thread/state/TestThreadStates.py b/lldb/test/API/functionalities/thread/state/TestThreadStates.py index e128ca84977b4..56954c9f34c7e 100644 --- a/lldb/test/API/functionalities/thread/state/TestThreadStates.py +++ b/lldb/test/API/functionalities/thread/state/TestThreadStates.py @@ -3,7 +3,7 @@ """ -import unittest2 +import unittest import lldb from lldbsuite.test.decorators import * from lldbsuite.test.lldbtest import * @@ -41,14 +41,14 @@ def test_state_after_continue(self): @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24660") @expectedFailureNetBSD # thread states not properly maintained - @unittest2.expectedFailure # llvm.org/pr16712 + @unittest.expectedFailure # llvm.org/pr16712 def test_state_after_expression(self): """Test thread state after expression.""" self.build() self.thread_state_after_expression_test() # thread states not properly maintained - @unittest2.expectedFailure # llvm.org/pr15824 and <rdar://problem/28557237> + @unittest.expectedFailure # llvm.org/pr15824 and <rdar://problem/28557237> @expectedFailureAll( oslist=["windows"], bugnumber="llvm.org/pr24668: Breakpoints not resolved correctly", diff --git a/lldb/test/API/functionalities/tty/TestTerminal.py b/lldb/test/API/functionalities/tty/TestTerminal.py index 457abd7b4a89d..750cdb3fc8361 100644 --- a/lldb/test/API/functionalities/tty/TestTerminal.py +++ b/lldb/test/API/functionalities/tty/TestTerminal.py @@ -2,7 +2,7 @@ Test lldb command aliases. """ -import unittest2 +import unittest import os import lldb from lldbsuite.test.decorators import * @@ -17,13 +17,13 @@ class LaunchInTerminalTestCase(TestBase): @skipUnlessDarwin # If the test is being run under sudo, the spawned terminal won't retain that elevated # privilege so it can't open the socket to talk back to the test case - @unittest2.skipIf( + @unittest.skipIf( hasattr(os, "geteuid") and os.geteuid() == 0, "test cannot be run as root" ) # Do we need to disable this test if the testsuite is being run on a remote system? # This env var is only defined when the shell is running in a local mac # terminal window - @unittest2.skipUnless( + @unittest.skipUnless( "TERM_PROGRAM" in os.environ, "test must be run on local system" ) @no_debug_info_test diff --git a/lldb/test/API/lang/c/shared_lib/TestSharedLib.py b/lldb/test/API/lang/c/shared_lib/TestSharedLib.py index 235b9b4ce3442..e0994aae76169 100644 --- a/lldb/test/API/lang/c/shared_lib/TestSharedLib.py +++ b/lldb/test/API/lang/c/shared_lib/TestSharedLib.py @@ -1,7 +1,7 @@ """Test that types defined in shared libraries work correctly.""" -import unittest2 +import unittest import lldb from lldbsuite.test.decorators import * from lldbsuite.test.lldbtest import * @@ -35,7 +35,7 @@ def test_expr_no_preload(self): """Test that types work when defined in a shared library and forward-declared in the main executable, but with preloading disabled""" self.common_test_expr(False) - @unittest2.expectedFailure # llvm.org/PR36712 + @unittest.expectedFailure # llvm.org/PR36712 def test_frame_variable(self): """Test that types work when defined in a shared library and forward-declared in the main executable""" self.build() diff --git a/lldb/test/API/lang/c/shared_lib_stripped_symbols/TestSharedLibStrippedSymbols.py b/lldb/test/API/lang/c/shared_lib_stripped_symbols/TestSharedLibStrippedSymbols.py index 070bd88d8db94..6971fc0fbc3fd 100644 --- a/lldb/test/API/lang/c/shared_lib_stripped_symbols/TestSharedLibStrippedSymbols.py +++ b/lldb/test/API/lang/c/shared_lib_stripped_symbols/TestSharedLibStrippedSymbols.py @@ -1,7 +1,7 @@ """Test that types defined in shared libraries with stripped symbols work correctly.""" -import unittest2 +import unittest import lldb from lldbsuite.test.decorators import * from lldbsuite.test.lldbtest import * @@ -28,7 +28,7 @@ def test_expr(self): ) @expectedFailureAll(oslist=["windows"]) - @unittest2.expectedFailure # llvm.org/PR36712 + @unittest.expectedFailure # llvm.org/PR36712 def test_frame_variable(self): """Test that types work when defined in a shared library and forward-declared in the main executable""" self.build() diff --git a/lldb/test/API/lang/cpp/namespace/TestNamespaceLookup.py b/lldb/test/API/lang/cpp/namespace/TestNamespaceLookup.py index 44cfbd2df5f34..b5e8115160d20 100644 --- a/lldb/test/API/lang/cpp/namespace/TestNamespaceLookup.py +++ b/lldb/test/API/lang/cpp/namespace/TestNamespaceLookup.py @@ -3,7 +3,7 @@ """ -import unittest2 +import unittest import lldb from lldbsuite.test.decorators import * from lldbsuite.test.lldbtest import * @@ -41,7 +41,7 @@ def runToBkpt(self, command): ) @skipIfWindows # This is flakey on Windows: llvm.org/pr38373 - @unittest2.expectedFailure # CU-local objects incorrectly scoped + @unittest.expectedFailure # CU-local objects incorrectly scoped def test_scope_lookup_with_run_command_globals(self): """Test scope lookup of functions in lldb.""" self.build() @@ -211,7 +211,7 @@ def test_scope_lookup_with_run_command(self): # Evaluate B::func() - should call B::func() self.expect_expr("B::func()", result_type="int", result_value="4") - @unittest2.expectedFailure # lldb scope lookup of functions bugs + @unittest.expectedFailure # lldb scope lookup of functions bugs def test_function_scope_lookup_with_run_command(self): """Test scope lookup of functions in lldb.""" self.build() @@ -272,7 +272,7 @@ def test_scope_after_using_directive_lookup_with_run_command(self): # Evaluate func2() - should call A::func2() self.expect_expr("func2()", result_type="int", result_value="3") - @unittest2.expectedFailure # lldb scope lookup after using declaration bugs + @unittest.expectedFailure # lldb scope lookup after using declaration bugs # NOTE: this test may fail on older systems that don't emit import # emtries in DWARF - may need to add checks for compiler versions here. def test_scope_after_using_declaration_lookup_with_run_command(self): @@ -294,7 +294,7 @@ def test_scope_after_using_declaration_lookup_with_run_command(self): # Evaluate func() - should call A::func() self.expect_expr("func()", result_type="int", result_value="3") - @unittest2.expectedFailure # lldb scope lookup ambiguity after using bugs + @unittest.expectedFailure # lldb scope lookup ambiguity after using bugs def test_scope_ambiguity_after_using_lookup_with_run_command(self): """Test scope lookup ambiguity after using in lldb.""" self.build() diff --git a/lldb/test/API/lang/cpp/reference-to-outer-type/TestCppReferenceToOuterClass.py b/lldb/test/API/lang/cpp/reference-to-outer-type/TestCppReferenceToOuterClass.py index 3172b5f2fe384..a6e419b7fcdfa 100644 --- a/lldb/test/API/lang/cpp/reference-to-outer-type/TestCppReferenceToOuterClass.py +++ b/lldb/test/API/lang/cpp/reference-to-outer-type/TestCppReferenceToOuterClass.py @@ -1,4 +1,4 @@ -import unittest2 +import unittest import lldb from lldbsuite.test.decorators import * from lldbsuite.test.lldbtest import * @@ -6,7 +6,7 @@ class TestCase(TestBase): - @unittest2.expectedFailure # The fix for this was reverted due to llvm.org/PR52257 + @unittest.expectedFailure # The fix for this was reverted due to llvm.org/PR52257 def test(self): self.build() self.dbg.CreateTarget(self.getBuildArtifact("a.out")) diff --git a/lldb/test/API/lang/objc/hidden-ivars/TestHiddenIvars.py b/lldb/test/API/lang/objc/hidden-ivars/TestHiddenIvars.py index 479f4379a5302..f5e4eb1404ac8 100644 --- a/lldb/test/API/lang/objc/hidden-ivars/TestHiddenIvars.py +++ b/lldb/test/API/lang/objc/hidden-ivars/TestHiddenIvars.py @@ -3,7 +3,7 @@ import subprocess -import unittest2 +import unittest import lldb from lldbsuite.test.decorators import * from lldbsuite.test.lldbtest import * @@ -58,7 +58,7 @@ def test_frame_variable(self): self.build() self.frame_var(False) - @unittest2.expectedFailure # rdar://18683637 + @unittest.expectedFailure # rdar://18683637 def test_frame_variable_across_modules(self): if self.getArchitecture() == "i386": self.skipTest("requires modern objc runtime") diff --git a/lldb/test/API/macosx/universal/TestUniversal.py b/lldb/test/API/macosx/universal/TestUniversal.py index 6e8c112efa096..d988cc0923b27 100644 --- a/lldb/test/API/macosx/universal/TestUniversal.py +++ b/lldb/test/API/macosx/universal/TestUniversal.py @@ -1,4 +1,4 @@ -import unittest2 +import unittest import os import lldb from lldbsuite.test.decorators import * @@ -24,7 +24,7 @@ def setUp(self): @add_test_categories(["pyapi"]) @skipUnlessDarwin - @unittest2.skipUnless( + @unittest.skipUnless( hasattr(os, "uname") and os.uname()[4] in ["x86_64"], "requires x86_64" ) @skipIfDarwinEmbedded # this test file assumes we're targetting an x86 system @@ -50,7 +50,7 @@ def test_sbdebugger_create_target_with_file_and_target_triple(self): self.assertTrue(process, PROCESS_IS_VALID) @skipUnlessDarwin - @unittest2.skipUnless( + @unittest.skipUnless( hasattr(os, "uname") and os.uname()[4] in ["x86_64"], "requires x86_64" ) @skipIfDarwinEmbedded # this test file assumes we're targetting an x86 system @@ -115,7 +115,7 @@ def test_process_launch_for_universal(self): self.runCmd("continue") @skipUnlessDarwin - @unittest2.skipUnless( + @unittest.skipUnless( hasattr(os, "uname") and os.uname()[4] in ["x86_64"], "requires x86_64" ) @skipIfDarwinEmbedded # this test file assumes we're targetting an x86 system diff --git a/lldb/test/API/tools/lldb-server/test/test_lldbgdbserverutils.py b/lldb/test/API/tools/lldb-server/test/test_lldbgdbserverutils.py index 6a6fd020de450..9c9a73cb4e64e 100644 --- a/lldb/test/API/tools/lldb-server/test/test_lldbgdbserverutils.py +++ b/lldb/test/API/tools/lldb-server/test/test_lldbgdbserverutils.py @@ -1,10 +1,10 @@ -import unittest2 +import unittest import re from lldbgdbserverutils import * -class TestLldbGdbServerUtils(unittest2.TestCase): +class TestLldbGdbServerUtils(unittest.TestCase): def test_entry_exact_payload_match(self): entry = GdbRemoteEntry(is_send_to_remote=False, exact_payload="$OK#9a") entry.assert_match(self, "$OK#9a") >From 11eaf8f1fa3d268bb4fd51b09b4c348a9638fff7 Mon Sep 17 00:00:00 2001 From: Jordan Rupprecht <ruppre...@google.com> Date: Mon, 29 Jan 2024 19:19:32 -0800 Subject: [PATCH 2/5] Remove bugnumber refs from xfail, update assertItemsEqual->assertCountEqual --- .../packages/Python/lldbsuite/test/lldbtest.py | 18 +++++------------- .../Python/lldbsuite/test/test_result.py | 14 +++++++------- .../TestGdbRemoteLibrariesSvr4Support.py | 2 +- 3 files changed, 13 insertions(+), 21 deletions(-) diff --git a/lldb/packages/Python/lldbsuite/test/lldbtest.py b/lldb/packages/Python/lldbsuite/test/lldbtest.py index 2c4446d8aebc5..afe0ce237bd4a 100644 --- a/lldb/packages/Python/lldbsuite/test/lldbtest.py +++ b/lldb/packages/Python/lldbsuite/test/lldbtest.py @@ -1090,17 +1090,14 @@ def markFailure(self): # Once by the Python unittest framework, and a second time by us. print("FAIL", file=sbuf) - def markExpectedFailure(self, err, bugnumber): + def markExpectedFailure(self, err): """Callback invoked when an expected failure/error occurred.""" self.__expected__ = True with recording(self, False) as sbuf: # False because there's no need to write "expected failure" to the # stderr twice. # Once by the Python unittest framework, and a second time by us. - if bugnumber is None: - print("expected failure", file=sbuf) - else: - print("expected failure (problem id:" + str(bugnumber) + ")", file=sbuf) + print("expected failure", file=sbuf) def markSkippedTest(self): """Callback invoked when a test is skipped.""" @@ -1111,19 +1108,14 @@ def markSkippedTest(self): # Once by the Python unittest framework, and a second time by us. print("skipped test", file=sbuf) - def markUnexpectedSuccess(self, bugnumber): + def markUnexpectedSuccess(self): """Callback invoked when an unexpected success occurred.""" self.__unexpected__ = True with recording(self, False) as sbuf: # False because there's no need to write "unexpected success" to the # stderr twice. # Once by the Python unittest framework, and a second time by us. - if bugnumber is None: - print("unexpected success", file=sbuf) - else: - print( - "unexpected success (problem id:" + str(bugnumber) + ")", file=sbuf - ) + print("unexpected success", file=sbuf) def getRerunArgs(self): return " -f %s.%s" % (self.__class__.__name__, self._testMethodName) @@ -2226,7 +2218,7 @@ def completions_match(self, command, completions): match_strings = lldb.SBStringList() interp.HandleCompletion(command, len(command), 0, -1, match_strings) # match_strings is a 1-indexed list, so we have to slice... - self.assertItemsEqual( + self.assertCountEqual( completions, list(match_strings)[1:], "List of returned completion is wrong" ) diff --git a/lldb/packages/Python/lldbsuite/test/test_result.py b/lldb/packages/Python/lldbsuite/test/test_result.py index 2690906232b97..20365f53a6754 100644 --- a/lldb/packages/Python/lldbsuite/test/test_result.py +++ b/lldb/packages/Python/lldbsuite/test/test_result.py @@ -243,7 +243,7 @@ def addFailure(self, test, err): if self.checkExclusion( configuration.xfail_tests, test.id() ) or self.checkCategoryExclusion(configuration.xfail_categories, test): - self.addExpectedFailure(test, err, None) + self.addExpectedFailure(test, err) return configuration.sdir_has_content = True @@ -264,12 +264,12 @@ def addFailure(self, test, err): else: configuration.failures_per_category[category] = 1 - def addExpectedFailure(self, test, err, bugnumber): + def addExpectedFailure(self, test, err): configuration.sdir_has_content = True - super(LLDBTestResult, self).addExpectedFailure(test, err, bugnumber) + super(LLDBTestResult, self).addExpectedFailure(test, err) method = getattr(test, "markExpectedFailure", None) if method: - method(err, bugnumber) + method(err) self.stream.write( "XFAIL: LLDB (%s) :: %s\n" % (self._config_string(test), str(test)) ) @@ -285,12 +285,12 @@ def addSkip(self, test, reason): % (self._config_string(test), str(test), reason) ) - def addUnexpectedSuccess(self, test, bugnumber): + def addUnexpectedSuccess(self, test): configuration.sdir_has_content = True - super(LLDBTestResult, self).addUnexpectedSuccess(test, bugnumber) + super(LLDBTestResult, self).addUnexpectedSuccess(test) method = getattr(test, "markUnexpectedSuccess", None) if method: - method(bugnumber) + method() self.stream.write( "XPASS: LLDB (%s) :: %s\n" % (self._config_string(test), str(test)) ) diff --git a/lldb/test/API/tools/lldb-server/libraries-svr4/TestGdbRemoteLibrariesSvr4Support.py b/lldb/test/API/tools/lldb-server/libraries-svr4/TestGdbRemoteLibrariesSvr4Support.py index ac65d2d4c660f..846adade34402 100644 --- a/lldb/test/API/tools/lldb-server/libraries-svr4/TestGdbRemoteLibrariesSvr4Support.py +++ b/lldb/test/API/tools/lldb-server/libraries-svr4/TestGdbRemoteLibrariesSvr4Support.py @@ -72,7 +72,7 @@ def libraries_svr4_well_formed(self): self.assertEqual(xml_root.tag, "library-list-svr4") for child in xml_root: self.assertEqual(child.tag, "library") - self.assertItemsEqual(child.attrib.keys(), ["name", "lm", "l_addr", "l_ld"]) + self.assertCountEqual(child.attrib.keys(), ["name", "lm", "l_addr", "l_ld"]) def libraries_svr4_has_correct_load_addr(self): xml_root = self.get_libraries_svr4_xml() >From 5354a57e2dc8d8f79bfbd6d97c462ad334f175ac Mon Sep 17 00:00:00 2001 From: Jordan Rupprecht <ruppre...@google.com> Date: Mon, 29 Jan 2024 20:26:26 -0800 Subject: [PATCH 3/5] Parse test runner output for lit integration --- lldb/test/API/lldbtest.py | 43 +++++++++++++++++++++++++++++++-------- 1 file changed, 34 insertions(+), 9 deletions(-) diff --git a/lldb/test/API/lldbtest.py b/lldb/test/API/lldbtest.py index 2b44bb7f6f9f4..3b8f2a61822c8 100644 --- a/lldb/test/API/lldbtest.py +++ b/lldb/test/API/lldbtest.py @@ -86,20 +86,45 @@ def execute(self, test, litConfig): if timeoutInfo: return lit.Test.TIMEOUT, output - # Parse the dotest output from stderr. - result_regex = r"\((\d+) passes, (\d+) failures, (\d+) errors, (\d+) skipped, (\d+) expected failures, (\d+) unexpected successes\)" - results = re.search(result_regex, err) + # Parse the dotest output from stderr. First get the # of total tests, in order to infer the # of passes. + # Example: "Ran 5 tests in 0.042s" + num_ran_regex = r"^Ran (\d+) tests? in " + num_ran_results = re.search(num_ran_regex, err, re.MULTILINE) + + # If parsing fails mark this test as unresolved. + if not num_ran_results: + return lit.Test.UNRESOLVED, output + num_ran = int(num_ran_results.group(1)) + + # Then look for a detailed summary, which is OK or FAILED followed by optional details. + # Example: "OK (skipped=1, expected failures=1)" + # Example: "FAILED (failures=3)" + # Example: "OK" + result_regex = r"^(?:OK|FAILED)(?: \((.*)\))?$" + results = re.search(result_regex, err, re.MULTILINE) # If parsing fails mark this test as unresolved. if not results: return lit.Test.UNRESOLVED, output - passes = int(results.group(1)) - failures = int(results.group(2)) - errors = int(results.group(3)) - skipped = int(results.group(4)) - expected_failures = int(results.group(5)) - unexpected_successes = int(results.group(6)) + details = results.group(1) + parsed_details = {} + if details: + for detail in details.split(", "): + detail_parts = detail.split("=") + if len(detail_parts) != 2: + return lit.Test.UNRESOLVED, output + parsed_details[detail_parts[0]] = int(detail_parts[1]) + + failures = parsed_details.get("failures", 0) + errors = parsed_details.get("errors", 0) + skipped = parsed_details.get("skipped", 0) + expected_failures = parsed_details.get("expected failures", 0) + unexpected_successes = parsed_details.get("unexpected successes", 0) + non_pass = ( + failures + errors + skipped + expected_failures + unexpected_successes + ) + passes = num_ran - non_pass if exitCode: # Mark this test as FAIL if at least one test failed. >From ca32f6a9eebace25f0b5d2ba22fb3823e023f452 Mon Sep 17 00:00:00 2001 From: Jordan Rupprecht <ruppre...@google.com> Date: Mon, 29 Jan 2024 20:31:24 -0800 Subject: [PATCH 4/5] Remove one more xfail reason usage --- lldb/packages/Python/lldbsuite/test/lldbtest.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/lldb/packages/Python/lldbsuite/test/lldbtest.py b/lldb/packages/Python/lldbsuite/test/lldbtest.py index afe0ce237bd4a..018f2a06980a8 100644 --- a/lldb/packages/Python/lldbsuite/test/lldbtest.py +++ b/lldb/packages/Python/lldbsuite/test/lldbtest.py @@ -1696,9 +1696,7 @@ def test_method(self, attrvalue=attrvalue): xfail_reason = xfail_for_debug_info_cat_fn(cat) if xfail_reason: - test_method = unittest.expectedFailure(xfail_reason)( - test_method - ) + test_method = unittest.expectedFailure(test_method) skip_reason = skip_for_debug_info_cat_fn(cat) if skip_reason: >From edd3cfa6559acb37331945e45887d2d5069d5179 Mon Sep 17 00:00:00 2001 From: Jordan Rupprecht <ruppre...@google.com> Date: Mon, 29 Jan 2024 20:38:06 -0800 Subject: [PATCH 5/5] Clear module in TestThreadLocal to prevent failure during teardown --- lldb/test/API/lang/cpp/thread_local/TestThreadLocal.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/lldb/test/API/lang/cpp/thread_local/TestThreadLocal.py b/lldb/test/API/lang/cpp/thread_local/TestThreadLocal.py index 9b128ba6097ac..0b63e15e876d6 100644 --- a/lldb/test/API/lang/cpp/thread_local/TestThreadLocal.py +++ b/lldb/test/API/lang/cpp/thread_local/TestThreadLocal.py @@ -39,6 +39,11 @@ def test_thread_local(self): process.Kill() lldbutil.run_to_breakpoint_do_run(self, target, main_bkpt) + # The test fails during tear down because the module isn't cleared. + # Even though this test case is marked as xfail, a failure during + # tear down still counts as an error. + main_module.Clear() + self.expect( "expr tl_local_int", error=True, _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits