Johnny Chen | a1c8337 | 2011-02-01 01:23:34 +0000 | [diff] [blame] | 1 | """ |
| 2 | Test C++ virtual function and virtual inheritance. |
| 3 | """ |
| 4 | |
| 5 | import os, time |
| 6 | import re |
| 7 | import lldb |
| 8 | from lldbtest import * |
| 9 | |
| 10 | def Msg(expr, val): |
| 11 | return "'expression %s' matches the output (from compiled code): %s" % (expr, val) |
| 12 | |
| 13 | class CppVirtualMadness(TestBase): |
| 14 | |
Johnny Chen | 91b6b77 | 2011-06-25 20:19:47 +0000 | [diff] [blame] | 15 | mydir = os.path.join("lang", "cpp", "virtual") |
Johnny Chen | a1c8337 | 2011-02-01 01:23:34 +0000 | [diff] [blame] | 16 | |
| 17 | # This is the pattern by design to match the "my_expr = 'value'" output from |
| 18 | # printf() stmts (see main.cpp). |
| 19 | pattern = re.compile("^([^=]*) = '([^=]*)'$") |
| 20 | |
| 21 | # Assert message. |
| 22 | PRINTF_OUTPUT_GROKKED = "The printf output from compiled code is parsed correctly" |
| 23 | |
| 24 | @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin") |
| 25 | def test_virtual_madness_dsym(self): |
| 26 | """Test that expression works correctly with virtual inheritance as well as virtual function.""" |
| 27 | self.buildDsym() |
| 28 | self.virtual_madness_test() |
| 29 | |
| 30 | def test_virtual_madness_dwarf(self): |
| 31 | """Test that expression works correctly with virtual inheritance as well as virtual function.""" |
| 32 | self.buildDwarf() |
| 33 | self.virtual_madness_test() |
| 34 | |
| 35 | def setUp(self): |
| 36 | # Call super's setUp(). |
| 37 | TestBase.setUp(self) |
| 38 | # Find the line number to break for main.cpp. |
| 39 | self.line = line_number('main.cpp', '// Set first breakpoint here.') |
| 40 | |
| 41 | def virtual_madness_test(self): |
| 42 | """Test that variable expressions with basic types are evaluated correctly.""" |
| 43 | |
| 44 | # First, capture the golden output emitted by the oracle, i.e., the |
| 45 | # series of printf statements. |
Johnny Chen | ac77f3b | 2011-03-23 20:28:59 +0000 | [diff] [blame] | 46 | go = system("./a.out", sender=self)[0] |
Johnny Chen | a1c8337 | 2011-02-01 01:23:34 +0000 | [diff] [blame] | 47 | # This golden list contains a list of "my_expr = 'value' pairs extracted |
| 48 | # from the golden output. |
| 49 | gl = [] |
| 50 | |
| 51 | # Scan the golden output line by line, looking for the pattern: |
| 52 | # |
| 53 | # my_expr = 'value' |
| 54 | # |
| 55 | for line in go.split(os.linesep): |
| 56 | match = self.pattern.search(line) |
| 57 | if match: |
| 58 | my_expr, val = match.group(1), match.group(2) |
| 59 | gl.append((my_expr, val)) |
| 60 | #print "golden list:", gl |
| 61 | |
| 62 | # Bring the program to the point where we can issue a series of |
| 63 | # 'expression' command to compare against the golden output. |
| 64 | self.runCmd("file a.out", CURRENT_EXECUTABLE_SET) |
| 65 | self.runCmd("breakpoint set -f main.cpp -l %d" % self.line) |
| 66 | self.runCmd("run", RUN_SUCCEEDED) |
| 67 | |
| 68 | # Now iterate through the golden list, comparing against the output from |
| 69 | # 'expression var'. |
| 70 | for my_expr, val in gl: |
| 71 | # Don't overwhelm the expression mechanism. |
| 72 | # This slows down the test suite quite a bit, to enable it, define |
| 73 | # the environment variable LLDB_TYPES_EXPR_TIME_WAIT. For example: |
| 74 | # |
| 75 | # export LLDB_TYPES_EXPR_TIME_WAIT=0.5 |
| 76 | # |
| 77 | # causes a 0.5 second delay between 'expression' commands. |
| 78 | if "LLDB_TYPES_EXPR_TIME_WAIT" in os.environ: |
| 79 | time.sleep(float(os.environ["LLDB_TYPES_EXPR_TIME_WAIT"])) |
| 80 | |
| 81 | self.runCmd("expression %s" % my_expr) |
| 82 | output = self.res.GetOutput() |
| 83 | |
| 84 | # The expression output must match the oracle. |
| 85 | self.expect(output, Msg(my_expr, val), exe=False, |
| 86 | substrs = [val]) |