From 5ccbccfce0209eed8154236cf673416ee8d7ea9b Mon Sep 17 00:00:00 2001 From: Johnny Chen Date: Sat, 30 Jul 2011 01:39:58 +0000 Subject: [PATCH] Add a @benchmarks_test decorator for test method we want to categorize as benchmarks test. The test driver now takes an option "+b" which enables to run just the benchmarks tests. By default, tests decorated with the @benchmarks_test decorator do not get run. Add an example benchmarks test directory which contains nothing for the time being, just to demonstrate the @benchmarks_test concept. For example, $ ./dotest.py -v benchmarks ... ---------------------------------------------------------------------- Collected 2 tests 1: test_with_gdb (TestRepeatedExprs.RepeatedExprssCase) Test repeated expressions with gdb. ... skipped 'benchmarks tests' 2: test_with_lldb (TestRepeatedExprs.RepeatedExprssCase) Test repeated expressions with lldb. ... skipped 'benchmarks tests' ---------------------------------------------------------------------- Ran 2 tests in 0.047s OK (skipped=2) $ ./dotest.py -v +b benchmarks ... ---------------------------------------------------------------------- Collected 2 tests 1: test_with_gdb (TestRepeatedExprs.RepeatedExprssCase) Test repeated expressions with gdb. ... running test_with_gdb benchmarks result for test_with_gdb ok 2: test_with_lldb (TestRepeatedExprs.RepeatedExprssCase) Test repeated expressions with lldb. ... running test_with_lldb benchmarks result for test_with_lldb ok ---------------------------------------------------------------------- Ran 2 tests in 0.270s OK Also mark some Python API tests which are missing the @python_api_test decorator. llvm-svn: 136553 --- lldb/test/benchmarks/example/Makefile | 5 +++ .../benchmarks/example/TestRepeatedExprs.py | 37 +++++++++++++++++++ lldb/test/benchmarks/example/main.c | 6 +++ lldb/test/dotest.py | 10 +++++ lldb/test/lldbtest.py | 35 +++++++++++++++++- .../lldbutil/frame/TestFrameUtils.py | 1 + .../lldbutil/iter/TestLLDBIterator.py | 3 ++ .../lldbutil/iter/TestRegistersIterator.py | 1 + .../lldbutil/process/TestPrintStackTraces.py | 1 + 9 files changed, 97 insertions(+), 2 deletions(-) create mode 100644 lldb/test/benchmarks/example/Makefile create mode 100644 lldb/test/benchmarks/example/TestRepeatedExprs.py create mode 100644 lldb/test/benchmarks/example/main.c diff --git a/lldb/test/benchmarks/example/Makefile b/lldb/test/benchmarks/example/Makefile new file mode 100644 index 000000000000..0d70f2595019 --- /dev/null +++ b/lldb/test/benchmarks/example/Makefile @@ -0,0 +1,5 @@ +LEVEL = ../../make + +C_SOURCES := main.c + +include $(LEVEL)/Makefile.rules diff --git a/lldb/test/benchmarks/example/TestRepeatedExprs.py b/lldb/test/benchmarks/example/TestRepeatedExprs.py new file mode 100644 index 000000000000..719efb93617d --- /dev/null +++ b/lldb/test/benchmarks/example/TestRepeatedExprs.py @@ -0,0 +1,37 @@ +"""Test evaluating expressions repeatedly comparing lldb against gdb.""" + +import os +import unittest2 +import lldb +import pexpect +from lldbtest import * + +class RepeatedExprssCase(TestBase): + + mydir = os.path.join("benchmarks", "example") + + @benchmarks_test + def test_with_lldb(self): + """Test repeated expressions with lldb.""" + self.buildDefault() + self.run_lldb_repeated_exprs() + + @benchmarks_test + def test_with_gdb(self): + """Test repeated expressions with gdb.""" + self.buildDefault() + self.run_gdb_repeated_exprs() + + def run_lldb_repeated_exprs(self): + print "running "+self.testMethodName + print "benchmarks result for "+self.testMethodName + + def run_gdb_repeated_exprs(self): + print "running "+self.testMethodName + print "benchmarks result for "+self.testMethodName + +if __name__ == '__main__': + import atexit + lldb.SBDebugger.Initialize() + atexit.register(lambda: lldb.SBDebugger.Terminate()) + unittest2.main() diff --git a/lldb/test/benchmarks/example/main.c b/lldb/test/benchmarks/example/main.c new file mode 100644 index 000000000000..277aa54a4eea --- /dev/null +++ b/lldb/test/benchmarks/example/main.c @@ -0,0 +1,6 @@ +#include + +int main(int argc, char const *argv[]) { + printf("Hello world.\n"); + return 0; +} diff --git a/lldb/test/dotest.py b/lldb/test/dotest.py index 68cca8c6ec17..f422bc50d4e6 100755 --- a/lldb/test/dotest.py +++ b/lldb/test/dotest.py @@ -70,6 +70,9 @@ dont_do_python_api_test = False # By default, both command line and Python API tests are performed. just_do_python_api_test = False +# By default, benchmarks tests are not run. +just_do_benchmarks_test = False + # The blacklist is optional (-b blacklistFile) and allows a central place to skip # testclass's and/or testclass.testmethod's. blacklist = None @@ -162,6 +165,8 @@ where options: use @python_api_test to decorate a test case as lldb Python API test +a : just do lldb Python API tests do not specify both '-a' and '+a' at the same time ++b : just do benchmark tests + use @benchmark_test to decorate a test case as such -b : read a blacklist file specified after this option -c : read a config file specified after this option the architectures and compilers (note the plurals) specified via '-A' and '-C' @@ -287,6 +292,7 @@ def parseOptionsAndInitTestdirs(): global dont_do_python_api_test global just_do_python_api_test + global just_do_benchmarks_test global blacklist global blacklistConfig global configFile @@ -347,6 +353,9 @@ def parseOptionsAndInitTestdirs(): elif sys.argv[index].startswith('+a'): just_do_python_api_test = True index += 1 + elif sys.argv[index].startswith('+b'): + just_do_benchmarks_test = True + index += 1 elif sys.argv[index].startswith('-b'): # Increment by 1 to fetch the blacklist file name option argument. index += 1 @@ -815,6 +824,7 @@ lldb.blacklist = blacklist # Put dont/just_do_python_api_test in the lldb namespace, too. lldb.dont_do_python_api_test = dont_do_python_api_test lldb.just_do_python_api_test = just_do_python_api_test +lldb.just_do_benchmarks_test = just_do_benchmarks_test # Turn on lldb loggings if necessary. lldbLoggings() diff --git a/lldb/test/lldbtest.py b/lldb/test/lldbtest.py index bdcdc17cd741..777459f76e53 100644 --- a/lldb/test/lldbtest.py +++ b/lldb/test/lldbtest.py @@ -240,7 +240,7 @@ def python_api_test(func): def wrapper(self, *args, **kwargs): try: if lldb.dont_do_python_api_test: - self.skipTest("Skip Python API tests") + self.skipTest("python api tests") except AttributeError: pass return func(self, *args, **kwargs) @@ -249,6 +249,24 @@ def python_api_test(func): wrapper.__python_api_test__ = True return wrapper +from functools import wraps +def benchmarks_test(func): + """Decorate the item as a benchmarks test.""" + if isinstance(func, type) and issubclass(func, unittest2.TestCase): + raise Exception("@benchmarks_test can only be used to decorate a test method") + @wraps(func) + def wrapper(self, *args, **kwargs): + try: + if not lldb.just_do_benchmarks_test: + self.skipTest("benchmarks tests") + except AttributeError: + pass + return func(self, *args, **kwargs) + + # Mark this function as such to separate them from the regular tests. + wrapper.__benchmarks_test__ = True + return wrapper + class recording(StringIO.StringIO): """ A nice little context manager for recording the debugger interactions into @@ -514,7 +532,20 @@ class TestBase(unittest2.TestCase): if getattr(testMethod, "__python_api_test__", False): pass else: - self.skipTest("Skip lldb command line test") + self.skipTest("non python api test") + except AttributeError: + pass + + # Benchmarks test is decorated with @benchmarks_test, + # which also sets the "__benchmarks_test__" attribute of the + # function object to True. + try: + if lldb.just_do_benchmarks_test: + testMethod = getattr(self, self._testMethodName) + if getattr(testMethod, "__benchmarks_test__", False): + pass + else: + self.skipTest("non benchmarks test") except AttributeError: pass diff --git a/lldb/test/python_api/lldbutil/frame/TestFrameUtils.py b/lldb/test/python_api/lldbutil/frame/TestFrameUtils.py index d980aba020c3..068077b5494f 100644 --- a/lldb/test/python_api/lldbutil/frame/TestFrameUtils.py +++ b/lldb/test/python_api/lldbutil/frame/TestFrameUtils.py @@ -18,6 +18,7 @@ class FrameUtilsTestCase(TestBase): self.line = line_number('main.c', "// Find the line number here.") + @python_api_test def test_frame_utils(self): """Test utility functions for the frame object.""" self.buildDefault() diff --git a/lldb/test/python_api/lldbutil/iter/TestLLDBIterator.py b/lldb/test/python_api/lldbutil/iter/TestLLDBIterator.py index 1ec5c4b1a5db..e0022a0aaac5 100644 --- a/lldb/test/python_api/lldbutil/iter/TestLLDBIterator.py +++ b/lldb/test/python_api/lldbutil/iter/TestLLDBIterator.py @@ -19,16 +19,19 @@ class LLDBIteratorTestCase(TestBase): self.line1 = line_number('main.cpp', '// Set break point at this line.') self.line2 = line_number('main.cpp', '// And that line.') + @python_api_test def test_lldb_iter_module(self): """Test module_iter works correctly for SBTarget -> SBModule.""" self.buildDefault() self.lldb_iter_module() + @python_api_test def test_lldb_iter_breakpoint(self): """Test breakpoint_iter works correctly for SBTarget -> SBBreakpoint.""" self.buildDefault() self.lldb_iter_breakpoint() + @python_api_test def test_lldb_iter_frame(self): """Test iterator works correctly for SBProcess->SBThread->SBFrame.""" self.buildDefault() diff --git a/lldb/test/python_api/lldbutil/iter/TestRegistersIterator.py b/lldb/test/python_api/lldbutil/iter/TestRegistersIterator.py index f706365f1d91..a869d5bcc7ec 100644 --- a/lldb/test/python_api/lldbutil/iter/TestRegistersIterator.py +++ b/lldb/test/python_api/lldbutil/iter/TestRegistersIterator.py @@ -18,6 +18,7 @@ class RegistersIteratorTestCase(TestBase): # Find the line number to break inside main(). self.line1 = line_number('main.cpp', '// Set break point at this line.') + @python_api_test def test_iter_registers(self): """Test iterator works correctly for lldbutil.iter_registers().""" self.buildDefault() diff --git a/lldb/test/python_api/lldbutil/process/TestPrintStackTraces.py b/lldb/test/python_api/lldbutil/process/TestPrintStackTraces.py index a84fa690a9be..e67436a4666b 100644 --- a/lldb/test/python_api/lldbutil/process/TestPrintStackTraces.py +++ b/lldb/test/python_api/lldbutil/process/TestPrintStackTraces.py @@ -18,6 +18,7 @@ class ThreadsStackTracesTestCase(TestBase): # Find the line number to break inside main(). self.line = line_number('main.cpp', '// Set break point at this line.') + @python_api_test def test_stack_traces(self): """Test SBprocess and SBThread APIs with printing of the stack traces.""" self.buildDefault()