1f7a9b14c2c02d2fa9fad586c19f29d77533fcc09Enrico Granata"""
2f7a9b14c2c02d2fa9fad586c19f29d77533fcc09Enrico GranataTest lldb data formatter subsystem.
3f7a9b14c2c02d2fa9fad586c19f29d77533fcc09Enrico Granata"""
4f7a9b14c2c02d2fa9fad586c19f29d77533fcc09Enrico Granata
5f7a9b14c2c02d2fa9fad586c19f29d77533fcc09Enrico Granataimport os, time
6f7a9b14c2c02d2fa9fad586c19f29d77533fcc09Enrico Granataimport unittest2
7f7a9b14c2c02d2fa9fad586c19f29d77533fcc09Enrico Granataimport lldb
8f7a9b14c2c02d2fa9fad586c19f29d77533fcc09Enrico Granatafrom lldbtest import *
9431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Inghamimport lldbutil
10f7a9b14c2c02d2fa9fad586c19f29d77533fcc09Enrico Granata
1192f75728050db93bfaf3e73d86a4a8a3a75dad8aJohnny Chenclass ScriptDataFormatterTestCase(TestBase):
12f7a9b14c2c02d2fa9fad586c19f29d77533fcc09Enrico Granata
13f7a9b14c2c02d2fa9fad586c19f29d77533fcc09Enrico Granata    mydir = os.path.join("functionalities", "data-formatter", "data-formatter-script")
14f7a9b14c2c02d2fa9fad586c19f29d77533fcc09Enrico Granata
15f7a9b14c2c02d2fa9fad586c19f29d77533fcc09Enrico Granata    @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
16a3ed7d834b0e0c6924ac95629e740682bbcd15baJohnny Chen    @dsym_test
17f7a9b14c2c02d2fa9fad586c19f29d77533fcc09Enrico Granata    def test_with_dsym_and_run_command(self):
18f7a9b14c2c02d2fa9fad586c19f29d77533fcc09Enrico Granata        """Test data formatter commands."""
19f7a9b14c2c02d2fa9fad586c19f29d77533fcc09Enrico Granata        self.buildDsym()
20f7a9b14c2c02d2fa9fad586c19f29d77533fcc09Enrico Granata        self.data_formatter_commands()
21f7a9b14c2c02d2fa9fad586c19f29d77533fcc09Enrico Granata
22a3ed7d834b0e0c6924ac95629e740682bbcd15baJohnny Chen    @dwarf_test
23f7a9b14c2c02d2fa9fad586c19f29d77533fcc09Enrico Granata    def test_with_dwarf_and_run_command(self):
24f7a9b14c2c02d2fa9fad586c19f29d77533fcc09Enrico Granata        """Test data formatter commands."""
25f7a9b14c2c02d2fa9fad586c19f29d77533fcc09Enrico Granata        self.buildDwarf()
26f7a9b14c2c02d2fa9fad586c19f29d77533fcc09Enrico Granata        self.data_formatter_commands()
27f7a9b14c2c02d2fa9fad586c19f29d77533fcc09Enrico Granata
28f7a9b14c2c02d2fa9fad586c19f29d77533fcc09Enrico Granata    def setUp(self):
29f7a9b14c2c02d2fa9fad586c19f29d77533fcc09Enrico Granata        # Call super's setUp().
30f7a9b14c2c02d2fa9fad586c19f29d77533fcc09Enrico Granata        TestBase.setUp(self)
31f7a9b14c2c02d2fa9fad586c19f29d77533fcc09Enrico Granata        # Find the line number to break at.
32f7a9b14c2c02d2fa9fad586c19f29d77533fcc09Enrico Granata        self.line = line_number('main.cpp', '// Set break point at this line.')
33f7a9b14c2c02d2fa9fad586c19f29d77533fcc09Enrico Granata
34f7a9b14c2c02d2fa9fad586c19f29d77533fcc09Enrico Granata    def data_formatter_commands(self):
35f7a9b14c2c02d2fa9fad586c19f29d77533fcc09Enrico Granata        """Test that that file and class static variables display correctly."""
36f7a9b14c2c02d2fa9fad586c19f29d77533fcc09Enrico Granata        self.runCmd("file a.out", CURRENT_EXECUTABLE_SET)
37f7a9b14c2c02d2fa9fad586c19f29d77533fcc09Enrico Granata
38431d839a33e9a274e705f7a268a1c9de2ffc2da2Jim Ingham        lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.line, num_expected_locations=1, loc_exact=True)
39f7a9b14c2c02d2fa9fad586c19f29d77533fcc09Enrico Granata
40f7a9b14c2c02d2fa9fad586c19f29d77533fcc09Enrico Granata        self.runCmd("run", RUN_SUCCEEDED)
41f7a9b14c2c02d2fa9fad586c19f29d77533fcc09Enrico Granata
42f7a9b14c2c02d2fa9fad586c19f29d77533fcc09Enrico Granata        # The stop reason of the thread should be breakpoint.
43f7a9b14c2c02d2fa9fad586c19f29d77533fcc09Enrico Granata        self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
44f7a9b14c2c02d2fa9fad586c19f29d77533fcc09Enrico Granata            substrs = ['stopped',
45f7a9b14c2c02d2fa9fad586c19f29d77533fcc09Enrico Granata                       'stop reason = breakpoint'])
46f7a9b14c2c02d2fa9fad586c19f29d77533fcc09Enrico Granata
47f7a9b14c2c02d2fa9fad586c19f29d77533fcc09Enrico Granata        # This is the function to remove the custom formats in order to have a
48f7a9b14c2c02d2fa9fad586c19f29d77533fcc09Enrico Granata        # clean slate for the next test case.
49f7a9b14c2c02d2fa9fad586c19f29d77533fcc09Enrico Granata        def cleanup():
50f7a9b14c2c02d2fa9fad586c19f29d77533fcc09Enrico Granata            self.runCmd('type format clear', check=False)
51f7a9b14c2c02d2fa9fad586c19f29d77533fcc09Enrico Granata            self.runCmd('type summary clear', check=False)
52f7a9b14c2c02d2fa9fad586c19f29d77533fcc09Enrico Granata
53f7a9b14c2c02d2fa9fad586c19f29d77533fcc09Enrico Granata        # Execute the cleanup function during test case tear down.
54f7a9b14c2c02d2fa9fad586c19f29d77533fcc09Enrico Granata        self.addTearDownHook(cleanup)
55f7a9b14c2c02d2fa9fad586c19f29d77533fcc09Enrico Granata
56f7a9b14c2c02d2fa9fad586c19f29d77533fcc09Enrico Granata        # Set the script here to ease the formatting
57f7a9b14c2c02d2fa9fad586c19f29d77533fcc09Enrico Granata        script = 'a = valobj.GetChildMemberWithName(\'integer\'); a_val = a.GetValue(); str = \'Hello from Python, \' + a_val + \' time\'; return str + (\'!\' if a_val == \'1\' else \'s!\');'
58f7a9b14c2c02d2fa9fad586c19f29d77533fcc09Enrico Granata
592c6a3d80dab3cf50c26fefe037357a4e6e621258Enrico Granata        self.runCmd("type summary add i_am_cool --python-script \"%s\"" % script)
60f7a9b14c2c02d2fa9fad586c19f29d77533fcc09Enrico Granata
61f7a9b14c2c02d2fa9fad586c19f29d77533fcc09Enrico Granata        self.expect("frame variable one",
62f7a9b14c2c02d2fa9fad586c19f29d77533fcc09Enrico Granata            substrs = ['Hello from Python',
63f7a9b14c2c02d2fa9fad586c19f29d77533fcc09Enrico Granata                       '1 time!'])
64f7a9b14c2c02d2fa9fad586c19f29d77533fcc09Enrico Granata
65f7a9b14c2c02d2fa9fad586c19f29d77533fcc09Enrico Granata        self.expect("frame variable two",
66f7a9b14c2c02d2fa9fad586c19f29d77533fcc09Enrico Granata            substrs = ['Hello from Python',
67f7a9b14c2c02d2fa9fad586c19f29d77533fcc09Enrico Granata                       '4 times!'])
68f7a9b14c2c02d2fa9fad586c19f29d77533fcc09Enrico Granata
69f7a9b14c2c02d2fa9fad586c19f29d77533fcc09Enrico Granata        self.runCmd("n"); # skip ahead to make values change
70f7a9b14c2c02d2fa9fad586c19f29d77533fcc09Enrico Granata
71f7a9b14c2c02d2fa9fad586c19f29d77533fcc09Enrico Granata        self.expect("frame variable three",
72f7a9b14c2c02d2fa9fad586c19f29d77533fcc09Enrico Granata            substrs = ['Hello from Python, 10 times!',
73f7a9b14c2c02d2fa9fad586c19f29d77533fcc09Enrico Granata                       'Hello from Python, 4 times!'])
74f7a9b14c2c02d2fa9fad586c19f29d77533fcc09Enrico Granata
75f7a9b14c2c02d2fa9fad586c19f29d77533fcc09Enrico Granata        self.runCmd("n"); # skip ahead to make values change
76f7a9b14c2c02d2fa9fad586c19f29d77533fcc09Enrico Granata
77f7a9b14c2c02d2fa9fad586c19f29d77533fcc09Enrico Granata        self.expect("frame variable two",
78f7a9b14c2c02d2fa9fad586c19f29d77533fcc09Enrico Granata            substrs = ['Hello from Python',
79f7a9b14c2c02d2fa9fad586c19f29d77533fcc09Enrico Granata                       '1 time!'])
80f7a9b14c2c02d2fa9fad586c19f29d77533fcc09Enrico Granata
81f7a9b14c2c02d2fa9fad586c19f29d77533fcc09Enrico Granata        script = 'a = valobj.GetChildMemberWithName(\'integer\'); a_val = a.GetValue(); str = \'int says \' + a_val; return str;'
82f7a9b14c2c02d2fa9fad586c19f29d77533fcc09Enrico Granata
83f7a9b14c2c02d2fa9fad586c19f29d77533fcc09Enrico Granata        # Check that changes in the script are immediately reflected
842c6a3d80dab3cf50c26fefe037357a4e6e621258Enrico Granata        self.runCmd("type summary add i_am_cool --python-script \"%s\"" % script)
85f7a9b14c2c02d2fa9fad586c19f29d77533fcc09Enrico Granata
86f7a9b14c2c02d2fa9fad586c19f29d77533fcc09Enrico Granata        self.expect("frame variable two",
87f7a9b14c2c02d2fa9fad586c19f29d77533fcc09Enrico Granata                    substrs = ['int says 1'])
8890d207ede88604e278f68ee1b02600a35e56dd14Enrico Granata
8990d207ede88604e278f68ee1b02600a35e56dd14Enrico Granata        self.expect("frame variable twoptr",
9090d207ede88604e278f68ee1b02600a35e56dd14Enrico Granata                    substrs = ['int says 1'])
91f7a9b14c2c02d2fa9fad586c19f29d77533fcc09Enrico Granata
92f7a9b14c2c02d2fa9fad586c19f29d77533fcc09Enrico Granata        # Change the summary
93242ffb80dd0c1c650c8a9f05656a3ba2f339993dEnrico Granata        self.runCmd("type summary add --summary-string \"int says ${var.integer}, and float says ${var.floating}\" i_am_cool")
94f7a9b14c2c02d2fa9fad586c19f29d77533fcc09Enrico Granata
95f7a9b14c2c02d2fa9fad586c19f29d77533fcc09Enrico Granata        self.expect("frame variable two",
96f7a9b14c2c02d2fa9fad586c19f29d77533fcc09Enrico Granata                    substrs = ['int says 1',
97f7a9b14c2c02d2fa9fad586c19f29d77533fcc09Enrico Granata                               'and float says 2.71'])
98f7a9b14c2c02d2fa9fad586c19f29d77533fcc09Enrico Granata        # Try it for pointers
99f7a9b14c2c02d2fa9fad586c19f29d77533fcc09Enrico Granata        self.expect("frame variable twoptr",
100f7a9b14c2c02d2fa9fad586c19f29d77533fcc09Enrico Granata                    substrs = ['int says 1',
101f7a9b14c2c02d2fa9fad586c19f29d77533fcc09Enrico Granata                               'and float says 2.71'])
102f7a9b14c2c02d2fa9fad586c19f29d77533fcc09Enrico Granata
103f7a9b14c2c02d2fa9fad586c19f29d77533fcc09Enrico Granata        # Force a failure for pointers
1042c6a3d80dab3cf50c26fefe037357a4e6e621258Enrico Granata        self.runCmd("type summary add i_am_cool -p --python-script \"%s\"" % script)
105f7a9b14c2c02d2fa9fad586c19f29d77533fcc09Enrico Granata
106f7a9b14c2c02d2fa9fad586c19f29d77533fcc09Enrico Granata        self.expect("frame variable twoptr", matching=False,
107f7a9b14c2c02d2fa9fad586c19f29d77533fcc09Enrico Granata                    substrs = ['and float says 2.71'])
108f7a9b14c2c02d2fa9fad586c19f29d77533fcc09Enrico Granata
10990d207ede88604e278f68ee1b02600a35e56dd14Enrico Granata        script = 'return \'Python summary\'';
11090d207ede88604e278f68ee1b02600a35e56dd14Enrico Granata
1112c6a3d80dab3cf50c26fefe037357a4e6e621258Enrico Granata        self.runCmd("type summary add --name test_summary --python-script \"%s\"" % script)
11290d207ede88604e278f68ee1b02600a35e56dd14Enrico Granata
11390d207ede88604e278f68ee1b02600a35e56dd14Enrico Granata        # attach the Python named summary to someone
1143069c62fc7d3c0b857cd1e9269ff22011ed418fbEnrico Granata        self.expect("frame variable one --summary test_summary",
11590d207ede88604e278f68ee1b02600a35e56dd14Enrico Granata                substrs = ['Python summary'])
11690d207ede88604e278f68ee1b02600a35e56dd14Enrico Granata
11790d207ede88604e278f68ee1b02600a35e56dd14Enrico Granata        # should not bind to the type
11890d207ede88604e278f68ee1b02600a35e56dd14Enrico Granata        self.expect("frame variable two", matching=False,
11990d207ede88604e278f68ee1b02600a35e56dd14Enrico Granata                    substrs = ['Python summary'])
12090d207ede88604e278f68ee1b02600a35e56dd14Enrico Granata
1213069c62fc7d3c0b857cd1e9269ff22011ed418fbEnrico Granata        # and should not stick to the variable
1223069c62fc7d3c0b857cd1e9269ff22011ed418fbEnrico Granata        self.expect("frame variable one",matching=False,
1233069c62fc7d3c0b857cd1e9269ff22011ed418fbEnrico Granata                substrs = ['Python summary'])
1243069c62fc7d3c0b857cd1e9269ff22011ed418fbEnrico Granata
125242ffb80dd0c1c650c8a9f05656a3ba2f339993dEnrico Granata        self.runCmd("type summary add i_am_cool --summary-string \"Text summary\"")
12690d207ede88604e278f68ee1b02600a35e56dd14Enrico Granata
1273069c62fc7d3c0b857cd1e9269ff22011ed418fbEnrico Granata        # should be temporary only
1283069c62fc7d3c0b857cd1e9269ff22011ed418fbEnrico Granata        self.expect("frame variable one",matching=False,
12990d207ede88604e278f68ee1b02600a35e56dd14Enrico Granata                    substrs = ['Python summary'])
13090d207ede88604e278f68ee1b02600a35e56dd14Enrico Granata
13190d207ede88604e278f68ee1b02600a35e56dd14Enrico Granata        # use the type summary
13290d207ede88604e278f68ee1b02600a35e56dd14Enrico Granata        self.expect("frame variable two",
13390d207ede88604e278f68ee1b02600a35e56dd14Enrico Granata                    substrs = ['Text summary'])
13490d207ede88604e278f68ee1b02600a35e56dd14Enrico Granata
13590d207ede88604e278f68ee1b02600a35e56dd14Enrico Granata        self.runCmd("n"); # skip ahead to make values change
13690d207ede88604e278f68ee1b02600a35e56dd14Enrico Granata
13790d207ede88604e278f68ee1b02600a35e56dd14Enrico Granata        # both should use the type summary now
13890d207ede88604e278f68ee1b02600a35e56dd14Enrico Granata        self.expect("frame variable one",
13990d207ede88604e278f68ee1b02600a35e56dd14Enrico Granata                    substrs = ['Text summary'])
14090d207ede88604e278f68ee1b02600a35e56dd14Enrico Granata
14190d207ede88604e278f68ee1b02600a35e56dd14Enrico Granata        self.expect("frame variable two",
14290d207ede88604e278f68ee1b02600a35e56dd14Enrico Granata                    substrs = ['Text summary'])
14390d207ede88604e278f68ee1b02600a35e56dd14Enrico Granata
14490d207ede88604e278f68ee1b02600a35e56dd14Enrico Granata        # disable type summary for pointers, and make a Python regex summary
145242ffb80dd0c1c650c8a9f05656a3ba2f339993dEnrico Granata        self.runCmd("type summary add i_am_cool -p --summary-string \"Text summary\"")
1462c6a3d80dab3cf50c26fefe037357a4e6e621258Enrico Granata        self.runCmd("type summary add -x cool --python-script \"%s\"" % script)
14790d207ede88604e278f68ee1b02600a35e56dd14Enrico Granata
14890d207ede88604e278f68ee1b02600a35e56dd14Enrico Granata        # variables should stick to the type summary
14990d207ede88604e278f68ee1b02600a35e56dd14Enrico Granata        self.expect("frame variable one",
15090d207ede88604e278f68ee1b02600a35e56dd14Enrico Granata                    substrs = ['Text summary'])
15190d207ede88604e278f68ee1b02600a35e56dd14Enrico Granata
15290d207ede88604e278f68ee1b02600a35e56dd14Enrico Granata        self.expect("frame variable two",
15390d207ede88604e278f68ee1b02600a35e56dd14Enrico Granata                    substrs = ['Text summary'])
15490d207ede88604e278f68ee1b02600a35e56dd14Enrico Granata
15590d207ede88604e278f68ee1b02600a35e56dd14Enrico Granata        # array and pointer should match the Python one
15690d207ede88604e278f68ee1b02600a35e56dd14Enrico Granata        self.expect("frame variable twoptr",
15790d207ede88604e278f68ee1b02600a35e56dd14Enrico Granata                    substrs = ['Python summary'])
15890d207ede88604e278f68ee1b02600a35e56dd14Enrico Granata
15990d207ede88604e278f68ee1b02600a35e56dd14Enrico Granata        self.expect("frame variable array",
16090d207ede88604e278f68ee1b02600a35e56dd14Enrico Granata                    substrs = ['Python summary'])
16190d207ede88604e278f68ee1b02600a35e56dd14Enrico Granata
16290d207ede88604e278f68ee1b02600a35e56dd14Enrico Granata        # return pointers to the type summary
163242ffb80dd0c1c650c8a9f05656a3ba2f339993dEnrico Granata        self.runCmd("type summary add i_am_cool --summary-string \"Text summary\"")
16490d207ede88604e278f68ee1b02600a35e56dd14Enrico Granata
16590d207ede88604e278f68ee1b02600a35e56dd14Enrico Granata        self.expect("frame variable one",
16690d207ede88604e278f68ee1b02600a35e56dd14Enrico Granata                    substrs = ['Text summary'])
16790d207ede88604e278f68ee1b02600a35e56dd14Enrico Granata
16890d207ede88604e278f68ee1b02600a35e56dd14Enrico Granata        self.expect("frame variable two",
16990d207ede88604e278f68ee1b02600a35e56dd14Enrico Granata                    substrs = ['Text summary'])
17090d207ede88604e278f68ee1b02600a35e56dd14Enrico Granata
17190d207ede88604e278f68ee1b02600a35e56dd14Enrico Granata        self.expect("frame variable twoptr",
17290d207ede88604e278f68ee1b02600a35e56dd14Enrico Granata                    substrs = ['Text summary'])
17390d207ede88604e278f68ee1b02600a35e56dd14Enrico Granata
17490d207ede88604e278f68ee1b02600a35e56dd14Enrico Granata        self.expect("frame variable array",
17590d207ede88604e278f68ee1b02600a35e56dd14Enrico Granata                    substrs = ['Python summary'])
17690d207ede88604e278f68ee1b02600a35e56dd14Enrico Granata
17790d207ede88604e278f68ee1b02600a35e56dd14Enrico Granata
178f7a9b14c2c02d2fa9fad586c19f29d77533fcc09Enrico Granataif __name__ == '__main__':
179f7a9b14c2c02d2fa9fad586c19f29d77533fcc09Enrico Granata    import atexit
180f7a9b14c2c02d2fa9fad586c19f29d77533fcc09Enrico Granata    lldb.SBDebugger.Initialize()
181f7a9b14c2c02d2fa9fad586c19f29d77533fcc09Enrico Granata    atexit.register(lambda: lldb.SBDebugger.Terminate())
182f7a9b14c2c02d2fa9fad586c19f29d77533fcc09Enrico Granata    unittest2.main()
183