| """ | |
| Test user added container commands | |
| """ | |
| import sys | |
| import lldb | |
| from lldbsuite.test.decorators import * | |
| from lldbsuite.test.lldbtest import * | |
| class TestCmdContainer(TestBase): | |
| NO_DEBUG_INFO_TESTCASE = True | |
| def test_container_add(self): | |
| self.container_add() | |
| def check_command_tree_exists(self): | |
| """This makes sure we can still run the command tree we added.""" | |
| self.runCmd("test-multi") | |
| self.runCmd("test-multi test-multi-sub") | |
| self.runCmd("test-multi test-multi-sub welcome") | |
| def container_add(self): | |
| # Make sure we can't overwrite built-in commands: | |
| self.expect( | |
| "command container add process", | |
| "Can't replace builtin container command", | |
| substrs=["can't replace builtin command"], | |
| error=True, | |
| ) | |
| self.expect( | |
| "command container add process non_such_subcommand", | |
| "Can't add to built-in subcommand", | |
| substrs=["Path component: 'process' is not a user command"], | |
| error=True, | |
| ) | |
| self.expect( | |
| "command container add process launch", | |
| "Can't replace builtin subcommand", | |
| substrs=["Path component: 'process' is not a user command"], | |
| error=True, | |
| ) | |
| # Now lets make a container command: | |
| self.runCmd("command container add -h 'A test container command' test-multi") | |
| # Make sure the help works: | |
| self.expect( | |
| "help test-multi", | |
| "Help works for top-level multi", | |
| substrs=["A test container command"], | |
| ) | |
| # Add a subcommand: | |
| self.runCmd( | |
| "command container add -h 'A test container sub-command' test-multi test-multi-sub" | |
| ) | |
| # Make sure the help works: | |
| self.expect( | |
| "help test-multi", | |
| "Help shows sub-multi", | |
| substrs=[ | |
| "A test container command", | |
| "test-multi-sub -- A test container sub-command", | |
| ], | |
| ) | |
| self.expect( | |
| "help test-multi test-multi-sub", | |
| "Help shows sub-multi", | |
| substrs=["A test container sub-command"], | |
| ) | |
| # Now add a script based command to the container command: | |
| self.runCmd("command script import welcome.py") | |
| self.runCmd( | |
| "command script add -c welcome.WelcomeCommand test-multi test-multi-sub welcome" | |
| ) | |
| # Make sure the help still works: | |
| self.expect( | |
| "help test-multi test-multi-sub", | |
| "Listing subcommands works", | |
| substrs=[ | |
| "A test container sub-command", | |
| "welcome -- Just a docstring for Welcome", | |
| ], | |
| ) | |
| self.expect( | |
| "help test-multi test-multi-sub welcome", | |
| "Subcommand help works", | |
| substrs=["Just a docstring for Welcome"], | |
| ) | |
| # And make sure it actually works: | |
| self.expect( | |
| "test-multi test-multi-sub welcome friend", | |
| "Test command works", | |
| substrs=["Hello friend, welcome to LLDB"], | |
| ) | |
| # Make sure we can make an alias to this: | |
| self.runCmd( | |
| "command alias my-welcome test-multi test-multi-sub welcome", | |
| "We can make an alias to multi-word", | |
| ) | |
| self.expect( | |
| "my-welcome friend", | |
| "Test command works", | |
| substrs=["Hello friend, welcome to LLDB"], | |
| ) | |
| self.runCmd("command unalias my-welcome") | |
| # Make sure overwriting works on the leaf command. First using the | |
| # explicit option so we should not be able to remove extant commands by default: | |
| self.expect( | |
| "command script add -c welcome.WelcomeCommand2 test-multi test-multi-sub welcome", | |
| "overwrite command w/o -o", | |
| substrs=["cannot add command: sub-command already exists"], | |
| error=True, | |
| ) | |
| # But we can with the -o option: | |
| self.runCmd( | |
| "command script add -c welcome.WelcomeCommand2 -o test-multi test-multi-sub welcome" | |
| ) | |
| # Make sure we really did overwrite: | |
| self.expect( | |
| "test-multi test-multi-sub welcome friend", | |
| "Used the new command class", | |
| substrs=["Hello friend, welcome again to LLDB"], | |
| ) | |
| self.expect( | |
| "apropos welcome", | |
| "welcome should show up in apropos", | |
| substrs=["A docstring for the second Welcome"], | |
| ) | |
| self.expect( | |
| "help test-multi test-multi-sub welcome", | |
| "welcome should show up in help", | |
| substrs=["A docstring for the second Welcome"], | |
| ) | |
| self.expect("help", "test-multi should show up in help", substrs=["test-multi"]) | |
| # Now switch the default and make sure we can now delete w/o the overwrite option: | |
| self.runCmd("settings set interpreter.require-overwrite 0") | |
| self.runCmd( | |
| "command script add -c welcome.WelcomeCommand test-multi test-multi-sub welcome" | |
| ) | |
| # Make sure we really did overwrite: | |
| self.expect( | |
| "test-multi test-multi-sub welcome friend", | |
| "Used the new command class", | |
| substrs=["Hello friend, welcome to LLDB"], | |
| ) | |
| # Make sure we give good errors when the input is wrong: | |
| self.expect( | |
| "command script delete test-mult test-multi-sub welcome", | |
| "Delete script command - wrong first path component", | |
| substrs=["'test-mult' not found"], | |
| error=True, | |
| ) | |
| self.expect( | |
| "command script delete test-multi test-multi-su welcome", | |
| "Delete script command - wrong second path component", | |
| substrs=["'test-multi-su' not found"], | |
| error=True, | |
| ) | |
| self.check_command_tree_exists() | |
| self.expect( | |
| "command script delete test-multi test-multi-sub welcom", | |
| "Delete script command - wrong leaf component", | |
| substrs=["'welcom' not found"], | |
| error=True, | |
| ) | |
| self.check_command_tree_exists() | |
| self.expect( | |
| "command script delete test-multi test-multi-sub", | |
| "Delete script command - no leaf component", | |
| substrs=["subcommand 'test-multi-sub' is not a user command"], | |
| error=True, | |
| ) | |
| self.check_command_tree_exists() | |
| # You can't use command script delete to delete container commands: | |
| self.expect( | |
| "command script delete test-multi", | |
| "Delete script - can't delete container", | |
| substrs=["command 'test-multi' is a multi-word command."], | |
| error=True, | |
| ) | |
| self.expect( | |
| "command script delete test-multi test-multi-sub", | |
| "Delete script - can't delete container", | |
| substrs=["subcommand 'test-multi-sub' is not a user command"], | |
| error=True, | |
| ) | |
| # You can't use command container delete to delete scripted commands: | |
| self.expect( | |
| "command container delete test-multi test-multi-sub welcome", | |
| "command container can't delete user commands", | |
| substrs=["subcommand 'welcome' is not a container command"], | |
| error=True, | |
| ) | |
| # Also make sure you can't alias on top of container commands: | |
| self.expect( | |
| "command alias test-multi process launch", | |
| "Tried to alias on top of a container command", | |
| substrs=[ | |
| "'test-multi' is a user container command and cannot be overwritten." | |
| ], | |
| error=True, | |
| ) | |
| self.check_command_tree_exists() | |
| # Also assert that we can't delete builtin commands: | |
| self.expect( | |
| "command script delete process launch", | |
| "Delete builtin command fails", | |
| substrs=["command 'process' is not a user command"], | |
| error=True, | |
| ) | |
| # Now let's do the version that works | |
| self.expect( | |
| "command script delete test-multi test-multi-sub welcome", | |
| "Delete script command by path", | |
| substrs=["Deleted command: test-multi test-multi-sub welcome"], | |
| ) | |
| # Now overwrite the sub-command, it should end up empty: | |
| self.runCmd( | |
| "command container add -h 'A different help string' -o test-multi test-multi-sub" | |
| ) | |
| # welcome should be gone: | |
| self.expect( | |
| "test-multi test-multi-sub welcome friend", | |
| "did remove subcommand", | |
| substrs=["'test-multi-sub' does not have any subcommands"], | |
| error=True, | |
| ) | |
| # We should have the new help: | |
| self.expect( | |
| "help test-multi test-multi-sub", | |
| "help changed", | |
| substrs=["A different help string"], | |
| ) | |
| # Now try deleting commands. | |
| self.runCmd("command container delete test-multi test-multi-sub") | |
| self.expect( | |
| "test-multi test-multi-sub", | |
| "Command is not active", | |
| error=True, | |
| substrs=["'test-multi' does not have any subcommands"], | |
| ) | |
| self.expect("help test-multi", matching=False, substrs=["test-multi-sub"]) | |
| # Next the root command: | |
| self.runCmd("command container delete test-multi") | |
| self.expect( | |
| "test-multi", | |
| "Root command gone", | |
| substrs=["'test-multi' is not a valid command"], | |
| error=True, | |
| ) |