| """ |
| Test lldb data formatter subsystem. |
| """ |
| |
| import lldb |
| from lldbsuite.test.decorators import * |
| from lldbsuite.test.lldbtest import * |
| from lldbsuite.test import lldbutil |
| |
| |
| class CategoriesDataFormatterTestCase(TestBase): |
| def setUp(self): |
| # Call super's setUp(). |
| TestBase.setUp(self) |
| # Find the line number to break at. |
| self.line = line_number("main.cpp", "// Set break point at this line.") |
| |
| @expectedFlakeyNetBSD |
| def test_with_run_command(self): |
| """Test that that file and class static variables display correctly.""" |
| self.build() |
| self.runCmd("file " + self.getBuildArtifact("a.out"), CURRENT_EXECUTABLE_SET) |
| |
| lldbutil.run_break_set_by_file_and_line( |
| self, "main.cpp", self.line, num_expected_locations=1, loc_exact=True |
| ) |
| |
| self.runCmd("run", RUN_SUCCEEDED) |
| |
| # The stop reason of the thread should be breakpoint. |
| self.expect( |
| "thread list", |
| STOPPED_DUE_TO_BREAKPOINT, |
| substrs=["stopped", "stop reason = breakpoint"], |
| ) |
| |
| # This is the function to remove the custom formats in order to have a |
| # clean slate for the next test case (most of these categories do not |
| # exist anymore, but we just make sure we delete all of them) |
| def cleanup(): |
| self.runCmd("type format clear", check=False) |
| self.runCmd("type summary clear", check=False) |
| self.runCmd("type category delete Category1", check=False) |
| self.runCmd("type category delete Category2", check=False) |
| self.runCmd("type category delete NewCategory", check=False) |
| self.runCmd("type category delete CircleCategory", check=False) |
| self.runCmd("type category delete RectangleStarCategory", check=False) |
| self.runCmd("type category delete BaseCategory", check=False) |
| |
| # Execute the cleanup function during test case tear down. |
| self.addTearDownHook(cleanup) |
| |
| # Add a summary to a new category and check that it works |
| self.runCmd( |
| 'type summary add Rectangle --summary-string "ARectangle" -w NewCategory' |
| ) |
| |
| self.expect( |
| "frame variable r1 r2 r3", |
| matching=False, |
| substrs=["r1 = ARectangle", "r2 = ARectangle", "r3 = ARectangle"], |
| ) |
| |
| self.runCmd("type category enable NewCategory") |
| |
| self.expect( |
| "frame variable r1 r2 r3", |
| matching=True, |
| substrs=["r1 = ARectangle", "r2 = ARectangle", "r3 = ARectangle"], |
| ) |
| |
| # Disable the category and check that the old stuff is there |
| self.runCmd("type category disable NewCategory") |
| |
| self.expect("frame variable r1 r2 r3", substrs=["r1 = {", "r2 = {", "r3 = {"]) |
| |
| # Re-enable the category and check that it works |
| self.runCmd("type category enable NewCategory") |
| |
| self.expect( |
| "frame variable r1 r2 r3", |
| substrs=["r1 = ARectangle", "r2 = ARectangle", "r3 = ARectangle"], |
| ) |
| |
| # Delete the category and the old stuff should be there |
| self.runCmd("type category delete NewCategory") |
| |
| self.expect("frame variable r1 r2 r3", substrs=["r1 = {", "r2 = {", "r3 = {"]) |
| |
| # Add summaries to two different categories and check that we can |
| # switch |
| self.runCmd( |
| 'type summary add --summary-string "Width = ${var.w}, Height = ${var.h}" Rectangle -w Category1' |
| ) |
| self.runCmd( |
| "type summary add --python-script \"return 'Area = ' + str( int(valobj.GetChildMemberWithName('w').GetValue()) * int(valobj.GetChildMemberWithName('h').GetValue()) );\" Rectangle -w Category2" |
| ) |
| |
| # check that enable A B is the same as enable B enable A |
| self.runCmd("type category enable Category1 Category2") |
| |
| self.expect( |
| "frame variable r1 r2 r3", |
| substrs=["r1 = Width = ", "r2 = Width = ", "r3 = Width = "], |
| ) |
| |
| self.runCmd("type category disable Category1") |
| |
| self.expect( |
| "frame variable r1 r2 r3", |
| substrs=["r1 = Area = ", "r2 = Area = ", "r3 = Area = "], |
| ) |
| |
| # switch again |
| |
| self.runCmd("type category enable Category1") |
| |
| self.expect( |
| "frame variable r1 r2 r3", |
| substrs=["r1 = Width = ", "r2 = Width = ", "r3 = Width = "], |
| ) |
| |
| # Re-enable the category and show that the preference is persisted |
| self.runCmd("type category disable Category2") |
| self.runCmd("type category enable Category2") |
| |
| self.expect( |
| "frame variable r1 r2 r3", |
| substrs=["r1 = Area = ", "r2 = Area = ", "r3 = Area = "], |
| ) |
| |
| # Now delete the favorite summary |
| self.runCmd("type summary delete Rectangle -w Category2") |
| |
| self.expect( |
| "frame variable r1 r2 r3", |
| substrs=["r1 = Width = ", "r2 = Width = ", "r3 = Width = "], |
| ) |
| |
| # Delete the summary from the default category (that does not have it) |
| self.runCmd("type summary delete Rectangle", check=False) |
| |
| self.expect( |
| "frame variable r1 r2 r3", |
| substrs=["r1 = Width = ", "r2 = Width = ", "r3 = Width = "], |
| ) |
| |
| # Now add another summary to another category and switch back and forth |
| self.runCmd("type category delete Category1 Category2") |
| |
| self.runCmd( |
| 'type summary add Rectangle -w Category1 --summary-string "Category1"' |
| ) |
| self.runCmd( |
| 'type summary add Rectangle -w Category2 --summary-string "Category2"' |
| ) |
| |
| self.runCmd("type category enable Category2") |
| self.runCmd("type category enable Category1") |
| |
| self.runCmd("type summary list -w Category1") |
| self.expect( |
| "type summary list -w NoSuchCategoryHere", |
| substrs=["no matching results found"], |
| ) |
| |
| self.expect( |
| "frame variable r1 r2 r3", |
| substrs=["r1 = Category1", "r2 = Category1", "r3 = Category1"], |
| ) |
| |
| self.runCmd("type category disable Category1") |
| |
| self.expect( |
| "frame variable r1 r2 r3", |
| substrs=["r1 = Category2", "r2 = Category2", "r3 = Category2"], |
| ) |
| |
| # Check that re-enabling an enabled category works |
| self.runCmd("type category enable Category1") |
| |
| self.expect( |
| "frame variable r1 r2 r3", |
| substrs=["r1 = Category1", "r2 = Category1", "r3 = Category1"], |
| ) |
| |
| self.runCmd("type category delete Category1") |
| self.runCmd("type category delete Category2") |
| |
| self.expect("frame variable r1 r2 r3", substrs=["r1 = {", "r2 = {", "r3 = {"]) |
| |
| # Check that multiple summaries can go into one category |
| self.runCmd( |
| 'type summary add -w Category1 --summary-string "Width = ${var.w}, Height = ${var.h}" Rectangle' |
| ) |
| self.runCmd( |
| 'type summary add -w Category1 --summary-string "Radius = ${var.r}" Circle' |
| ) |
| |
| self.runCmd("type category enable Category1") |
| |
| self.expect( |
| "frame variable r1 r2 r3", |
| substrs=["r1 = Width = ", "r2 = Width = ", "r3 = Width = "], |
| ) |
| |
| self.expect( |
| "frame variable c1 c2 c3", |
| substrs=["c1 = Radius = ", "c2 = Radius = ", "c3 = Radius = "], |
| ) |
| |
| self.runCmd("type summary delete Circle -w Category1") |
| |
| self.expect("frame variable c1 c2 c3", substrs=["c1 = {", "c2 = {", "c3 = {"]) |
| |
| # Add a regex based summary to a category |
| self.runCmd( |
| 'type summary add -w Category1 --summary-string "Radius = ${var.r}" -x Circle' |
| ) |
| |
| self.expect( |
| "frame variable r1 r2 r3", |
| substrs=["r1 = Width = ", "r2 = Width = ", "r3 = Width = "], |
| ) |
| |
| self.expect( |
| "frame variable c1 c2 c3", |
| substrs=["c1 = Radius = ", "c2 = Radius = ", "c3 = Radius = "], |
| ) |
| |
| # Delete it |
| self.runCmd("type summary delete Circle -w Category1") |
| |
| self.expect("frame variable c1 c2 c3", substrs=["c1 = {", "c2 = {", "c3 = {"]) |
| |
| # Change a summary inside a category and check that the change is |
| # reflected |
| self.runCmd('type summary add Circle -w Category1 --summary-string "summary1"') |
| |
| self.expect( |
| "frame variable c1 c2 c3", |
| substrs=["c1 = summary1", "c2 = summary1", "c3 = summary1"], |
| ) |
| |
| self.runCmd('type summary add Circle -w Category1 --summary-string "summary2"') |
| |
| self.expect( |
| "frame variable c1 c2 c3", |
| substrs=["c1 = summary2", "c2 = summary2", "c3 = summary2"], |
| ) |
| |
| # Check that our order of priority works. Start by clearing categories |
| self.runCmd("type category delete Category1") |
| |
| self.runCmd('type summary add Shape -w BaseCategory --summary-string "AShape"') |
| self.runCmd("type category enable BaseCategory") |
| |
| self.expect("expression (Shape*)&c1", substrs=["AShape"]) |
| self.expect("expression (Shape*)&r1", substrs=["AShape"]) |
| self.expect("expression (Shape*)c_ptr", substrs=["AShape"]) |
| self.expect("expression (Shape*)r_ptr", substrs=["AShape"]) |
| |
| self.runCmd( |
| 'type summary add Circle -w CircleCategory --summary-string "ACircle"' |
| ) |
| self.runCmd( |
| 'type summary add Rectangle -w RectangleCategory --summary-string "ARectangle"' |
| ) |
| self.runCmd("type category enable CircleCategory") |
| |
| self.expect("frame variable c1", substrs=["ACircle"]) |
| self.expect("frame variable c_ptr", substrs=["ACircle"]) |
| |
| self.runCmd( |
| 'type summary add "Rectangle *" -w RectangleStarCategory --summary-string "ARectangleStar"' |
| ) |
| self.runCmd("type category enable RectangleStarCategory") |
| |
| self.expect( |
| "frame variable c1 r1 c_ptr r_ptr", substrs=["ACircle", "ARectangleStar"] |
| ) |
| |
| self.runCmd("type category enable RectangleCategory") |
| |
| self.expect( |
| "frame variable c1 r1 c_ptr r_ptr", |
| substrs=["ACircle", "ACircle", "ARectangle"], |
| ) |
| |
| # Check that abruptly deleting an enabled category does not crash us |
| self.runCmd("type category delete RectangleCategory") |
| |
| self.expect( |
| "frame variable c1 r1 c_ptr r_ptr", |
| substrs=[ |
| "ACircle", |
| "(Rectangle) r1 = ", |
| "w = 5", |
| "h = 6", |
| "ACircle", |
| "ARectangleStar", |
| ], |
| ) |
| |
| # check that list commands work |
| self.expect("type category list", substrs=["RectangleStarCategory (enabled)"]) |
| |
| self.expect("type summary list", substrs=["ARectangleStar"]) |
| |
| # Disable a category and check that it fallsback |
| self.runCmd("type category disable CircleCategory") |
| |
| # check that list commands work |
| self.expect("type category list", substrs=["CircleCategory (disabled"]) |
| |
| self.expect("frame variable c1 r_ptr", substrs=["AShape", "ARectangleStar"]) |
| |
| # check that filters work into categories |
| self.runCmd("type filter add Rectangle --child w --category RectangleCategory") |
| self.runCmd("type category enable RectangleCategory") |
| self.runCmd( |
| 'type summary add Rectangle --category RectangleCategory --summary-string " " -e' |
| ) |
| self.expect("frame variable r2", substrs=["w = 9"]) |
| self.runCmd('type summary add Rectangle --summary-string " " -e') |
| self.expect("frame variable r2", matching=False, substrs=["h = 16"]) |
| |
| # Now delete all categories |
| self.runCmd( |
| "type category delete CircleCategory RectangleStarCategory BaseCategory RectangleCategory" |
| ) |
| |
| # check that a deleted category with filter does not blow us up |
| self.expect("frame variable r2", substrs=["w = 9", "h = 16"]) |
| |
| # and also validate that one can print formatters for a language |
| self.expect( |
| "type summary list -l c++", substrs=["vector", "map", "list", "string"] |
| ) |