1""" 2Test user added container commands 3""" 4 5 6import sys 7import lldb 8from lldbsuite.test.decorators import * 9from lldbsuite.test.lldbtest import * 10 11 12class TestCmdContainer(TestBase): 13 NO_DEBUG_INFO_TESTCASE = True 14 15 def test_container_add(self): 16 self.container_add() 17 18 def check_command_tree_exists(self): 19 """This makes sure we can still run the command tree we added.""" 20 self.runCmd("test-multi") 21 self.runCmd("test-multi test-multi-sub") 22 self.runCmd("test-multi test-multi-sub welcome") 23 24 def container_add(self): 25 # Make sure we can't overwrite built-in commands: 26 self.expect("command container add process", "Can't replace builtin container command", 27 substrs=["can't replace builtin command"], error=True) 28 self.expect("command container add process non_such_subcommand", "Can't add to built-in subcommand", 29 substrs=["Path component: 'process' is not a user command"], error=True) 30 self.expect("command container add process launch", "Can't replace builtin subcommand", 31 substrs=["Path component: 'process' is not a user command"], error=True) 32 33 # Now lets make a container command: 34 self.runCmd("command container add -h 'A test container command' test-multi") 35 # Make sure the help works: 36 self.expect("help test-multi", "Help works for top-level multi", 37 substrs=["A test container command"]) 38 # Add a subcommand: 39 self.runCmd("command container add -h 'A test container sub-command' test-multi test-multi-sub") 40 # Make sure the help works: 41 self.expect("help test-multi", "Help shows sub-multi", 42 substrs=["A test container command", "test-multi-sub -- A test container sub-command"]) 43 self.expect("help test-multi test-multi-sub", "Help shows sub-multi", 44 substrs=["A test container sub-command"]) 45 46 # Now add a script based command to the container command: 47 self.runCmd("command script import welcome.py") 48 self.runCmd("command script add -c welcome.WelcomeCommand test-multi test-multi-sub welcome") 49 # Make sure the help still works: 50 self.expect("help test-multi test-multi-sub", "Listing subcommands works", 51 substrs=["A test container sub-command", "welcome -- Just a docstring for Welcome"]) 52 self.expect("help test-multi test-multi-sub welcome", "Subcommand help works", 53 substrs=["Just a docstring for Welcome"]) 54 # And make sure it actually works: 55 self.expect("test-multi test-multi-sub welcome friend", "Test command works", 56 substrs=["Hello friend, welcome to LLDB"]) 57 58 # Make sure we can make an alias to this: 59 self.runCmd("command alias my-welcome test-multi test-multi-sub welcome", "We can make an alias to multi-word") 60 self.expect("my-welcome friend", "Test command works", 61 substrs=["Hello friend, welcome to LLDB"]) 62 self.runCmd("command unalias my-welcome") 63 64 # Make sure overwriting works on the leaf command. First using the 65 # explicit option so we should not be able to remove extant commands by default: 66 67 self.expect("command script add -c welcome.WelcomeCommand2 test-multi test-multi-sub welcome", 68 "overwrite command w/o -o", 69 substrs=["cannot add command: sub-command already exists"], error=True) 70 # But we can with the -o option: 71 self.runCmd("command script add -c welcome.WelcomeCommand2 -o test-multi test-multi-sub welcome") 72 # Make sure we really did overwrite: 73 self.expect("test-multi test-multi-sub welcome friend", "Used the new command class", 74 substrs=["Hello friend, welcome again to LLDB"]) 75 self.expect("apropos welcome", "welcome should show up in apropos", substrs=["A docstring for the second Welcome"]) 76 self.expect("help test-multi test-multi-sub welcome", "welcome should show up in help", substrs=["A docstring for the second Welcome"]) 77 self.expect("help", "test-multi should show up in help", substrs=["test-multi"]) 78 79 # Now switch the default and make sure we can now delete w/o the overwrite option: 80 self.runCmd("settings set interpreter.require-overwrite 0") 81 self.runCmd("command script add -c welcome.WelcomeCommand test-multi test-multi-sub welcome") 82 # Make sure we really did overwrite: 83 self.expect("test-multi test-multi-sub welcome friend", "Used the new command class", 84 substrs=["Hello friend, welcome to LLDB"]) 85 86 # Make sure we give good errors when the input is wrong: 87 self.expect("command script delete test-mult test-multi-sub welcome", "Delete script command - wrong first path component", 88 substrs=["'test-mult' not found"], error=True) 89 90 self.expect("command script delete test-multi test-multi-su welcome", "Delete script command - wrong second path component", 91 substrs=["'test-multi-su' not found"], error=True) 92 self.check_command_tree_exists() 93 94 self.expect("command script delete test-multi test-multi-sub welcom", "Delete script command - wrong leaf component", 95 substrs=["'welcom' not found"], error=True) 96 self.check_command_tree_exists() 97 98 self.expect("command script delete test-multi test-multi-sub", "Delete script command - no leaf component", 99 substrs=["subcommand 'test-multi-sub' is not a user command"], error=True) 100 self.check_command_tree_exists() 101 102 # You can't use command script delete to delete container commands: 103 self.expect("command script delete test-multi", "Delete script - can't delete container", 104 substrs=["command 'test-multi' is a multi-word command."], error=True) 105 self.expect("command script delete test-multi test-multi-sub", "Delete script - can't delete container", 106 substrs=["subcommand 'test-multi-sub' is not a user command"], error = True) 107 108 # You can't use command container delete to delete scripted commands: 109 self.expect("command container delete test-multi test-multi-sub welcome", "command container can't delete user commands", 110 substrs=["subcommand 'welcome' is not a container command"], error = True) 111 112 # Also make sure you can't alias on top of container commands: 113 self.expect("command alias test-multi process launch", "Tried to alias on top of a container command", 114 substrs=["'test-multi' is a user container command and cannot be overwritten."], error=True) 115 self.check_command_tree_exists() 116 117 # Also assert that we can't delete builtin commands: 118 self.expect("command script delete process launch", "Delete builtin command fails", substrs=["command 'process' is not a user command"], error=True) 119 # Now let's do the version that works 120 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"]) 121 122 # Now overwrite the sub-command, it should end up empty: 123 self.runCmd("command container add -h 'A different help string' -o test-multi test-multi-sub") 124 # welcome should be gone: 125 self.expect("test-multi test-multi-sub welcome friend", "did remove subcommand", 126 substrs=["'test-multi-sub' does not have any subcommands."], error=True) 127 # We should have the new help: 128 self.expect("help test-multi test-multi-sub", "help changed", 129 substrs=["A different help string"]) 130 131 # Now try deleting commands. 132 self.runCmd("command container delete test-multi test-multi-sub") 133 self.expect("test-multi test-multi-sub", "Command is not active", error=True, 134 substrs = ["'test-multi' does not have any subcommands"]) 135 self.expect("help test-multi", matching=False, substrs=["test-multi-sub"]) 136 137 138 # Next the root command: 139 self.runCmd("command container delete test-multi") 140 self.expect("test-multi", "Root command gone", substrs=["'test-multi' is not a valid command."], error=True) 141