1""" 2Test the lldb command line completion mechanism. 3""" 4 5 6 7import os 8import lldb 9from lldbsuite.test.decorators import * 10from lldbsuite.test.lldbtest import * 11from lldbsuite.test import lldbplatform 12from lldbsuite.test import lldbutil 13 14 15class CommandLineCompletionTestCase(TestBase): 16 17 mydir = TestBase.compute_mydir(__file__) 18 19 NO_DEBUG_INFO_TESTCASE = True 20 21 @classmethod 22 def classCleanup(cls): 23 """Cleanup the test byproducts.""" 24 try: 25 os.remove("child_send.txt") 26 os.remove("child_read.txt") 27 except: 28 pass 29 30 @skipIfFreeBSD # timing out on the FreeBSD buildbot 31 def test_at(self): 32 """Test that 'at' completes to 'attach '.""" 33 self.complete_from_to('at', 'attach ') 34 35 @skipIfFreeBSD # timing out on the FreeBSD buildbot 36 def test_de(self): 37 """Test that 'de' completes to 'detach '.""" 38 self.complete_from_to('de', 'detach ') 39 40 @skipIfFreeBSD # timing out on the FreeBSD buildbot 41 def test_frame_variable(self): 42 self.build() 43 self.main_source = "main.cpp" 44 self.main_source_spec = lldb.SBFileSpec(self.main_source) 45 46 (target, process, thread, bkpt) = lldbutil.run_to_source_breakpoint(self, 47 '// Break here', self.main_source_spec) 48 self.assertEquals(process.GetState(), lldb.eStateStopped) 49 # FIXME: This pulls in the debug information to make the completions work, 50 # but the completions should also work without. 51 self.runCmd("frame variable fooo") 52 53 self.complete_from_to('frame variable fo', 54 'frame variable fooo') 55 self.complete_from_to('frame variable fooo.', 56 'frame variable fooo.') 57 self.complete_from_to('frame variable fooo.dd', 58 'frame variable fooo.dd') 59 60 self.complete_from_to('frame variable ptr_fooo->', 61 'frame variable ptr_fooo->') 62 self.complete_from_to('frame variable ptr_fooo->dd', 63 'frame variable ptr_fooo->dd') 64 65 self.complete_from_to('frame variable cont', 66 'frame variable container') 67 self.complete_from_to('frame variable container.', 68 'frame variable container.MemberVar') 69 self.complete_from_to('frame variable container.Mem', 70 'frame variable container.MemberVar') 71 72 self.complete_from_to('frame variable ptr_cont', 73 'frame variable ptr_container') 74 self.complete_from_to('frame variable ptr_container->', 75 'frame variable ptr_container->MemberVar') 76 self.complete_from_to('frame variable ptr_container->Mem', 77 'frame variable ptr_container->MemberVar') 78 79 @skipIfFreeBSD # timing out on the FreeBSD buildbot 80 def test_process_attach_dash_dash_con(self): 81 """Test that 'process attach --con' completes to 'process attach --continue '.""" 82 self.complete_from_to( 83 'process attach --con', 84 'process attach --continue ') 85 86 @skipIfFreeBSD # timing out on the FreeBSD buildbot 87 def test_process_launch_arch(self): 88 self.complete_from_to('process launch --arch ', 89 ['mips', 90 'arm64']) 91 92 @skipIfFreeBSD # timing out on the FreeBSD buildbot 93 def test_ambiguous_long_opt(self): 94 self.completions_match('breakpoint modify --th', 95 ['--thread-id', 96 '--thread-index', 97 '--thread-name']) 98 99 @skipIfFreeBSD # timing out on the FreeBSD buildbot 100 def test_plugin_load(self): 101 self.complete_from_to('plugin load ', []) 102 103 @skipIfFreeBSD # timing out on the FreeBSD buildbot 104 def test_log_enable(self): 105 self.complete_from_to('log enable ll', ['lldb']) 106 self.complete_from_to('log enable dw', ['dwarf']) 107 self.complete_from_to('log enable lldb al', ['all']) 108 self.complete_from_to('log enable lldb sym', ['symbol']) 109 110 @skipIfFreeBSD # timing out on the FreeBSD buildbot 111 def test_log_enable(self): 112 self.complete_from_to('log disable ll', ['lldb']) 113 self.complete_from_to('log disable dw', ['dwarf']) 114 self.complete_from_to('log disable lldb al', ['all']) 115 self.complete_from_to('log disable lldb sym', ['symbol']) 116 117 @skipIfFreeBSD # timing out on the FreeBSD buildbot 118 def test_log_list(self): 119 self.complete_from_to('log list ll', ['lldb']) 120 self.complete_from_to('log list dw', ['dwarf']) 121 self.complete_from_to('log list ll', ['lldb']) 122 self.complete_from_to('log list lldb dwa', ['dwarf']) 123 124 @skipIfFreeBSD # timing out on the FreeBSD buildbot 125 def test_quoted_command(self): 126 self.complete_from_to('"set', 127 ['"settings" ']) 128 129 @skipIfFreeBSD # timing out on the FreeBSD buildbot 130 def test_quoted_arg_with_quoted_command(self): 131 self.complete_from_to('"settings" "repl', 132 ['"replace" ']) 133 134 @skipIfFreeBSD # timing out on the FreeBSD buildbot 135 def test_quoted_arg_without_quoted_command(self): 136 self.complete_from_to('settings "repl', 137 ['"replace" ']) 138 139 @skipIfFreeBSD # timing out on the FreeBSD buildbot 140 def test_single_quote_command(self): 141 self.complete_from_to("'set", 142 ["'settings' "]) 143 144 @skipIfFreeBSD # timing out on the FreeBSD buildbot 145 def test_terminated_quote_command(self): 146 # This should not crash, but we don't get any 147 # reasonable completions from this. 148 self.complete_from_to("'settings'", []) 149 150 @skipIfFreeBSD # timing out on the FreeBSD buildbot 151 def test_process_launch_arch_arm(self): 152 self.complete_from_to('process launch --arch arm', 153 ['arm64']) 154 155 @skipIfFreeBSD # timing out on the FreeBSD buildbot 156 def test_target_symbols_add_shlib(self): 157 # Doesn't seem to work, but at least it shouldn't crash. 158 self.complete_from_to('target symbols add --shlib ', []) 159 160 @skipIfFreeBSD # timing out on the FreeBSD buildbot 161 def test_log_file(self): 162 # Complete in our source directory which contains a 'main.cpp' file. 163 src_dir = os.path.dirname(os.path.realpath(__file__)) + '/' 164 self.complete_from_to('log enable lldb expr -f ' + src_dir, 165 ['main.cpp']) 166 167 @skipIfFreeBSD # timing out on the FreeBSD buildbot 168 def test_log_dir(self): 169 # Complete our source directory. 170 src_dir = os.path.dirname(os.path.realpath(__file__)) 171 self.complete_from_to('log enable lldb expr -f ' + src_dir, 172 [src_dir + os.sep], turn_off_re_match=True) 173 174 # <rdar://problem/11052829> 175 @skipIfFreeBSD # timing out on the FreeBSD buildbot 176 def test_infinite_loop_while_completing(self): 177 """Test that 'process print hello\' completes to itself and does not infinite loop.""" 178 self.complete_from_to('process print hello\\', 'process print hello\\', 179 turn_off_re_match=True) 180 181 @skipIfFreeBSD # timing out on the FreeBSD buildbot 182 def test_watchpoint_co(self): 183 """Test that 'watchpoint co' completes to 'watchpoint command '.""" 184 self.complete_from_to('watchpoint co', 'watchpoint command ') 185 186 @skipIfFreeBSD # timing out on the FreeBSD buildbot 187 def test_watchpoint_command_space(self): 188 """Test that 'watchpoint command ' completes to ['add', 'delete', 'list'].""" 189 self.complete_from_to( 190 'watchpoint command ', [ 191 'add', 'delete', 'list']) 192 193 @skipIfFreeBSD # timing out on the FreeBSD buildbot 194 def test_watchpoint_command_a(self): 195 """Test that 'watchpoint command a' completes to 'watchpoint command add '.""" 196 self.complete_from_to( 197 'watchpoint command a', 198 'watchpoint command add ') 199 200 @skipIfFreeBSD # timing out on the FreeBSD buildbot 201 def test_watchpoint_set_ex(self): 202 """Test that 'watchpoint set ex' completes to 'watchpoint set expression '.""" 203 self.complete_from_to( 204 'watchpoint set ex', 205 'watchpoint set expression ') 206 207 @skipIfFreeBSD # timing out on the FreeBSD buildbot 208 def test_watchpoint_set_var(self): 209 """Test that 'watchpoint set var' completes to 'watchpoint set variable '.""" 210 self.complete_from_to('watchpoint set var', 'watchpoint set variable ') 211 212 @skipIfFreeBSD # timing out on the FreeBSD buildbot 213 def test_help_fi(self): 214 """Test that 'help fi' completes to ['file', 'finish'].""" 215 self.complete_from_to( 216 'help fi', [ 217 'file', 'finish']) 218 219 @skipIfFreeBSD # timing out on the FreeBSD buildbot 220 def test_help_watchpoint_s(self): 221 """Test that 'help watchpoint s' completes to 'help watchpoint set '.""" 222 self.complete_from_to('help watchpoint s', 'help watchpoint set ') 223 224 @skipIfFreeBSD # timing out on the FreeBSD buildbot 225 def test_settings_append_target_er(self): 226 """Test that 'settings append target.er' completes to 'settings append target.error-path'.""" 227 self.complete_from_to( 228 'settings append target.er', 229 'settings append target.error-path') 230 231 @skipIfFreeBSD # timing out on the FreeBSD buildbot 232 def test_settings_insert_after_target_en(self): 233 """Test that 'settings insert-after target.env' completes to 'settings insert-after target.env-vars'.""" 234 self.complete_from_to( 235 'settings insert-after target.env', 236 'settings insert-after target.env-vars') 237 238 @skipIfFreeBSD # timing out on the FreeBSD buildbot 239 def test_settings_insert_before_target_en(self): 240 """Test that 'settings insert-before target.env' completes to 'settings insert-before target.env-vars'.""" 241 self.complete_from_to( 242 'settings insert-before target.env', 243 'settings insert-before target.env-vars') 244 245 @skipIfFreeBSD # timing out on the FreeBSD buildbot 246 def test_settings_replace_target_ru(self): 247 """Test that 'settings replace target.ru' completes to 'settings replace target.run-args'.""" 248 self.complete_from_to( 249 'settings replace target.ru', 250 'settings replace target.run-args') 251 252 @skipIfFreeBSD # timing out on the FreeBSD buildbot 253 def test_settings_show_term(self): 254 self.complete_from_to( 255 'settings show term-', 256 'settings show term-width') 257 258 @skipIfFreeBSD # timing out on the FreeBSD buildbot 259 def test_settings_list_term(self): 260 self.complete_from_to( 261 'settings list term-', 262 'settings list term-width') 263 264 @skipIfFreeBSD # timing out on the FreeBSD buildbot 265 def test_settings_remove_term(self): 266 self.complete_from_to( 267 'settings remove term-', 268 'settings remove term-width') 269 270 @skipIfFreeBSD # timing out on the FreeBSD buildbot 271 def test_settings_s(self): 272 """Test that 'settings s' completes to ['set', 'show'].""" 273 self.complete_from_to( 274 'settings s', [ 275 'set', 'show']) 276 277 @skipIfFreeBSD # timing out on the FreeBSD buildbot 278 def test_settings_set_th(self): 279 """Test that 'settings set thread-f' completes to 'settings set thread-format'.""" 280 self.complete_from_to('settings set thread-f', 'settings set thread-format') 281 282 @skipIfFreeBSD # timing out on the FreeBSD buildbot 283 def test_settings_s_dash(self): 284 """Test that 'settings set --g' completes to 'settings set --global'.""" 285 self.complete_from_to('settings set --g', 'settings set --global') 286 287 @skipIfFreeBSD # timing out on the FreeBSD buildbot 288 def test_settings_clear_th(self): 289 """Test that 'settings clear thread-f' completes to 'settings clear thread-format'.""" 290 self.complete_from_to( 291 'settings clear thread-f', 292 'settings clear thread-format') 293 294 @skipIfFreeBSD # timing out on the FreeBSD buildbot 295 def test_settings_set_ta(self): 296 """Test that 'settings set ta' completes to 'settings set target.'.""" 297 self.complete_from_to( 298 'settings set target.ma', 299 'settings set target.max-') 300 301 @skipIfFreeBSD # timing out on the FreeBSD buildbot 302 def test_settings_set_target_exec(self): 303 """Test that 'settings set target.exec' completes to 'settings set target.exec-search-paths '.""" 304 self.complete_from_to( 305 'settings set target.exec', 306 'settings set target.exec-search-paths') 307 308 @skipIfFreeBSD # timing out on the FreeBSD buildbot 309 def test_settings_set_target_pr(self): 310 """Test that 'settings set target.pr' completes to [ 311 'target.prefer-dynamic-value', 'target.process.'].""" 312 self.complete_from_to('settings set target.pr', 313 ['target.prefer-dynamic-value', 314 'target.process.']) 315 316 @skipIfFreeBSD # timing out on the FreeBSD buildbot 317 def test_settings_set_target_process(self): 318 """Test that 'settings set target.process' completes to 'settings set target.process.'.""" 319 self.complete_from_to( 320 'settings set target.process', 321 'settings set target.process.') 322 323 @skipIfFreeBSD # timing out on the FreeBSD buildbot 324 def test_settings_set_target_process_dot(self): 325 """Test that 'settings set target.process.t' completes to 'settings set target.process.thread.'.""" 326 self.complete_from_to( 327 'settings set target.process.t', 328 'settings set target.process.thread.') 329 330 @skipIfFreeBSD # timing out on the FreeBSD buildbot 331 def test_settings_set_target_process_thread_dot(self): 332 """Test that 'settings set target.process.thread.' completes to [ 333 'target.process.thread.step-avoid-regexp', 'target.process.thread.trace-thread'].""" 334 self.complete_from_to('settings set target.process.thread.', 335 ['target.process.thread.step-avoid-regexp', 336 'target.process.thread.trace-thread']) 337 338 @skipIfFreeBSD # timing out on the FreeBSD buildbot 339 def test_target_space(self): 340 """Test that 'target ' completes to ['create', 'delete', 'list', 341 'modules', 'select', 'stop-hook', 'variable'].""" 342 self.complete_from_to('target ', 343 ['create', 344 'delete', 345 'list', 346 'modules', 347 'select', 348 'stop-hook', 349 'variable']) 350 351 @skipIfFreeBSD # timing out on the FreeBSD buildbot 352 def test_target_create_dash_co(self): 353 """Test that 'target create --co' completes to 'target variable --core '.""" 354 self.complete_from_to('target create --co', 'target create --core ') 355 356 @skipIfFreeBSD # timing out on the FreeBSD buildbot 357 def test_target_va(self): 358 """Test that 'target va' completes to 'target variable '.""" 359 self.complete_from_to('target va', 'target variable ') 360 361 def test_command_argument_completion(self): 362 """Test completion of command arguments""" 363 self.complete_from_to("watchpoint set variable -", ["-w", "-s"]) 364 self.complete_from_to('watchpoint set variable -w', 'watchpoint set variable -w ') 365 self.complete_from_to("watchpoint set variable --", ["--watch", "--size"]) 366 self.complete_from_to("watchpoint set variable --w", "watchpoint set variable --watch") 367 self.complete_from_to('watchpoint set variable -w ', ['read', 'write', 'read_write']) 368 self.complete_from_to("watchpoint set variable --watch ", ["read", "write", "read_write"]) 369 self.complete_from_to("watchpoint set variable --watch w", "watchpoint set variable --watch write") 370 self.complete_from_to('watchpoint set variable -w read_', 'watchpoint set variable -w read_write') 371 # Now try the same thing with a variable name (non-option argument) to 372 # test that getopts arg reshuffling doesn't confuse us. 373 self.complete_from_to("watchpoint set variable foo -", ["-w", "-s"]) 374 self.complete_from_to('watchpoint set variable foo -w', 'watchpoint set variable foo -w ') 375 self.complete_from_to("watchpoint set variable foo --", ["--watch", "--size"]) 376 self.complete_from_to("watchpoint set variable foo --w", "watchpoint set variable foo --watch") 377 self.complete_from_to('watchpoint set variable foo -w ', ['read', 'write', 'read_write']) 378 self.complete_from_to("watchpoint set variable foo --watch ", ["read", "write", "read_write"]) 379 self.complete_from_to("watchpoint set variable foo --watch w", "watchpoint set variable foo --watch write") 380 self.complete_from_to('watchpoint set variable foo -w read_', 'watchpoint set variable foo -w read_write') 381 382 def test_completion_description_commands(self): 383 """Test descriptions of top-level command completions""" 384 self.check_completion_with_desc("", [ 385 ["command", "Commands for managing custom LLDB commands."], 386 ["breakpoint", "Commands for operating on breakpoints (see 'help b' for shorthand.)"] 387 ]) 388 389 self.check_completion_with_desc("pl", [ 390 ["platform", "Commands to manage and create platforms."], 391 ["plugin", "Commands for managing LLDB plugins."] 392 ]) 393 394 # Just check that this doesn't crash. 395 self.check_completion_with_desc("comman", []) 396 self.check_completion_with_desc("non-existent-command", []) 397 398 def test_completion_description_command_options(self): 399 """Test descriptions of command options""" 400 # Short options 401 self.check_completion_with_desc("breakpoint set -", [ 402 ["-h", "Set the breakpoint on exception catcH."], 403 ["-w", "Set the breakpoint on exception throW."] 404 ]) 405 406 # Long options. 407 self.check_completion_with_desc("breakpoint set --", [ 408 ["--on-catch", "Set the breakpoint on exception catcH."], 409 ["--on-throw", "Set the breakpoint on exception throW."] 410 ]) 411 412 # Ambiguous long options. 413 self.check_completion_with_desc("breakpoint set --on-", [ 414 ["--on-catch", "Set the breakpoint on exception catcH."], 415 ["--on-throw", "Set the breakpoint on exception throW."] 416 ]) 417 418 # Unknown long option. 419 self.check_completion_with_desc("breakpoint set --Z", [ 420 ]) 421 422 @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24489") 423 def test_symbol_name(self): 424 self.build() 425 self.dbg.CreateTarget(self.getBuildArtifact("a.out")) 426 self.complete_from_to('breakpoint set -n Fo', 427 'breakpoint set -n Foo::Bar(int,\\ int)', 428 turn_off_re_match=True) 429 # No completion for Qu because the candidate is 430 # (anonymous namespace)::Quux(). 431 self.complete_from_to('breakpoint set -n Qu', '') 432