1"""
2Test the lldb command line completion mechanism.
3"""
4
5
6
7import os
8from multiprocessing import Process
9import psutil
10import lldb
11from lldbsuite.test.decorators import *
12from lldbsuite.test.lldbtest import *
13from lldbsuite.test import lldbplatform
14from lldbsuite.test import lldbutil
15
16
17class CommandLineCompletionTestCase(TestBase):
18
19    mydir = TestBase.compute_mydir(__file__)
20
21    NO_DEBUG_INFO_TESTCASE = True
22
23    @classmethod
24    def classCleanup(cls):
25        """Cleanup the test byproducts."""
26        try:
27            os.remove("child_send.txt")
28            os.remove("child_read.txt")
29        except:
30            pass
31
32    def test_at(self):
33        """Test that 'at' completes to 'attach '."""
34        self.complete_from_to('at', 'attach ')
35
36    def test_de(self):
37        """Test that 'de' completes to 'detach '."""
38        self.complete_from_to('de', 'detach ')
39
40    def test_frame_variable(self):
41        self.build()
42        self.main_source = "main.cpp"
43        self.main_source_spec = lldb.SBFileSpec(self.main_source)
44
45        (target, process, thread, bkpt) = lldbutil.run_to_source_breakpoint(self,
46                                          '// Break here', self.main_source_spec)
47        self.assertEquals(process.GetState(), lldb.eStateStopped)
48
49        # Since CommandInterpreter has been corrected to update the current execution
50        # context at the beginning of HandleCompletion, we're here explicitly testing
51        # the scenario where "frame var" is completed without any preceding commands.
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    def test_process_attach_dash_dash_con(self):
80        """Test that 'process attach --con' completes to 'process attach --continue '."""
81        self.complete_from_to(
82            'process attach --con',
83            'process attach --continue ')
84
85    def test_process_launch_arch(self):
86        self.complete_from_to('process launch --arch ',
87                              ['mips',
88                               'arm64'])
89
90    def test_process_load(self):
91        self.build()
92        lldbutil.run_to_source_breakpoint(self, '// Break here', lldb.SBFileSpec("main.cpp"))
93        self.complete_from_to('process load Makef', 'process load Makefile')
94
95    @skipUnlessPlatform(["linux"])
96    def test_process_unload(self):
97        """Test the completion for "process unload <index>" """
98        # This tab completion should not work without a running process.
99        self.complete_from_to('process unload ',
100                              'process unload ')
101
102        self.build()
103        lldbutil.run_to_source_breakpoint(self, '// Break here', lldb.SBFileSpec("main.cpp"))
104        err = lldb.SBError()
105        self.process().LoadImage(lldb.SBFileSpec(self.getBuildArtifact("libshared.so")), err)
106        self.assertSuccess(err)
107
108        self.complete_from_to('process unload ',
109                              'process unload 0')
110
111        self.process().UnloadImage(0)
112        self.complete_from_to('process unload ',
113                              'process unload ')
114
115    def test_process_plugin_completion(self):
116        subcommands = ['attach -P', 'connect -p', 'launch -p']
117
118        for subcommand in subcommands:
119            self.complete_from_to('process ' + subcommand + ' mac',
120                                  'process ' + subcommand + ' mach-o-core')
121
122    @skipIfRemote
123    def test_common_completion_process_pid_and_name(self):
124        # The LLDB process itself and the process already attached to are both
125        # ignored by the process discovery mechanism, thus we need a process known
126        # to us here.
127        self.build()
128        server = self.spawnSubprocess(
129            self.getBuildArtifact("a.out"),
130            ["-x"], # Arg "-x" makes the subprocess wait for input thus it won't be terminated too early
131            install_remote=False)
132        self.assertIsNotNone(server)
133        pid = server.pid
134
135        self.complete_from_to('process attach -p ', [str(pid)])
136        self.complete_from_to('platform process attach -p ', [str(pid)])
137        self.complete_from_to('platform process info ', [str(pid)])
138
139        pname = psutil.Process(pid).name()  # FIXME: psutil doesn't work for remote
140        self.complete_from_to('process attach -n ', [str(pname)])
141        self.complete_from_to('platform process attach -n ', [str(pname)])
142
143    def test_process_signal(self):
144        # The tab completion for "process signal"  won't work without a running process.
145        self.complete_from_to('process signal ',
146                              'process signal ')
147
148        # Test with a running process.
149        self.build()
150        self.main_source = "main.cpp"
151        self.main_source_spec = lldb.SBFileSpec(self.main_source)
152        lldbutil.run_to_source_breakpoint(self, '// Break here', self.main_source_spec)
153
154        self.complete_from_to('process signal ',
155                              'process signal SIG')
156        self.complete_from_to('process signal SIGA',
157                              ['SIGABRT',
158                               'SIGALRM'])
159
160    def test_ambiguous_long_opt(self):
161        self.completions_match('breakpoint modify --th',
162                               ['--thread-id',
163                                '--thread-index',
164                                '--thread-name'])
165
166    def test_disassemble_dash_f(self):
167        self.completions_match('disassemble -F ',
168                               ['default',
169                                'intel',
170                                'att'])
171
172    def test_plugin_load(self):
173        self.complete_from_to('plugin load ', [])
174
175    def test_log_enable(self):
176        self.complete_from_to('log enable ll', ['lldb'])
177        self.complete_from_to('log enable dw', ['dwarf'])
178        self.complete_from_to('log enable lldb al', ['all'])
179        self.complete_from_to('log enable lldb sym', ['symbol'])
180
181    def test_log_enable(self):
182        self.complete_from_to('log disable ll', ['lldb'])
183        self.complete_from_to('log disable dw', ['dwarf'])
184        self.complete_from_to('log disable lldb al', ['all'])
185        self.complete_from_to('log disable lldb sym', ['symbol'])
186
187    def test_log_list(self):
188        self.complete_from_to('log list ll', ['lldb'])
189        self.complete_from_to('log list dw', ['dwarf'])
190        self.complete_from_to('log list ll', ['lldb'])
191        self.complete_from_to('log list lldb dwa', ['dwarf'])
192
193    def test_quoted_command(self):
194        self.complete_from_to('"set',
195                              ['"settings" '])
196
197    def test_quoted_arg_with_quoted_command(self):
198        self.complete_from_to('"settings" "repl',
199                              ['"replace" '])
200
201    def test_quoted_arg_without_quoted_command(self):
202        self.complete_from_to('settings "repl',
203                              ['"replace" '])
204
205    def test_single_quote_command(self):
206        self.complete_from_to("'set",
207                              ["'settings' "])
208
209    def test_terminated_quote_command(self):
210        # This should not crash, but we don't get any
211        # reasonable completions from this.
212        self.complete_from_to("'settings'", [])
213
214    def test_process_launch_arch_arm(self):
215        self.complete_from_to('process launch --arch arm',
216                              ['arm64'])
217
218    def test_target_symbols_add_shlib(self):
219        # Doesn't seem to work, but at least it shouldn't crash.
220        self.complete_from_to('target symbols add --shlib ', [])
221
222    def test_log_file(self):
223        # Complete in our source directory which contains a 'main.cpp' file.
224        src_dir =  os.path.dirname(os.path.realpath(__file__)) + '/'
225        self.complete_from_to('log enable lldb expr -f ' + src_dir,
226                              ['main.cpp'])
227
228    def test_log_dir(self):
229        # Complete our source directory.
230        src_dir =  os.path.dirname(os.path.realpath(__file__))
231        self.complete_from_to('log enable lldb expr -f ' + src_dir,
232                              [src_dir + os.sep], turn_off_re_match=True)
233
234    # <rdar://problem/11052829>
235    def test_infinite_loop_while_completing(self):
236        """Test that 'process print hello\' completes to itself and does not infinite loop."""
237        self.complete_from_to('process print hello\\', 'process print hello\\',
238                              turn_off_re_match=True)
239
240    def test_watchpoint_co(self):
241        """Test that 'watchpoint co' completes to 'watchpoint command '."""
242        self.complete_from_to('watchpoint co', 'watchpoint command ')
243
244    def test_watchpoint_command_space(self):
245        """Test that 'watchpoint command ' completes to ['add', 'delete', 'list']."""
246        self.complete_from_to(
247            'watchpoint command ', [
248                'add', 'delete', 'list'])
249
250    def test_watchpoint_command_a(self):
251        """Test that 'watchpoint command a' completes to 'watchpoint command add '."""
252        self.complete_from_to(
253            'watchpoint command a',
254            'watchpoint command add ')
255
256    def test_watchpoint_set_ex(self):
257        """Test that 'watchpoint set ex' completes to 'watchpoint set expression '."""
258        self.complete_from_to(
259            'watchpoint set ex',
260            'watchpoint set expression ')
261
262    def test_watchpoint_set_var(self):
263        """Test that 'watchpoint set var' completes to 'watchpoint set variable '."""
264        self.complete_from_to('watchpoint set var', 'watchpoint set variable ')
265
266    def test_watchpoint_set_variable_foo(self):
267        self.build()
268        lldbutil.run_to_source_breakpoint(self, '// Break here', lldb.SBFileSpec("main.cpp"))
269        self.complete_from_to('watchpoint set variable fo', 'watchpoint set variable fooo')
270        # Only complete the first argument.
271        self.complete_from_to('watchpoint set variable fooo ', 'watchpoint set variable fooo ')
272
273    def test_help_fi(self):
274        """Test that 'help fi' completes to ['file', 'finish']."""
275        self.complete_from_to(
276            'help fi', [
277                'file', 'finish'])
278
279    def test_help_watchpoint_s(self):
280        """Test that 'help watchpoint s' completes to 'help watchpoint set '."""
281        self.complete_from_to('help watchpoint s', 'help watchpoint set ')
282
283    def test_common_complete_watchpoint_ids(self):
284        subcommands = ['enable', 'disable', 'delete', 'modify', 'ignore']
285
286        # Completion should not work without a target.
287        for subcommand in subcommands:
288            self.complete_from_to('watchpoint ' + subcommand + ' ',
289                                  'watchpoint ' + subcommand + ' ')
290
291        # Create a process to provide a target and enable watchpoint setting.
292        self.build()
293        lldbutil.run_to_source_breakpoint(self, '// Break here', lldb.SBFileSpec("main.cpp"))
294
295        self.runCmd('watchpoint set variable ptr_fooo')
296        for subcommand in subcommands:
297            self.complete_from_to('watchpoint ' + subcommand + ' ', ['1'])
298
299    def test_settings_append_target_er(self):
300        """Test that 'settings append target.er' completes to 'settings append target.error-path'."""
301        self.complete_from_to(
302            'settings append target.er',
303            'settings append target.error-path')
304
305    def test_settings_insert_after_target_en(self):
306        """Test that 'settings insert-after target.env' completes to 'settings insert-after target.env-vars'."""
307        self.complete_from_to(
308            'settings insert-after target.env',
309            'settings insert-after target.env-vars')
310
311    def test_settings_insert_before_target_en(self):
312        """Test that 'settings insert-before target.env' completes to 'settings insert-before target.env-vars'."""
313        self.complete_from_to(
314            'settings insert-before target.env',
315            'settings insert-before target.env-vars')
316
317    def test_settings_replace_target_ru(self):
318        """Test that 'settings replace target.ru' completes to 'settings replace target.run-args'."""
319        self.complete_from_to(
320            'settings replace target.ru',
321            'settings replace target.run-args')
322
323    def test_settings_show_term(self):
324        self.complete_from_to(
325            'settings show term-',
326            'settings show term-width')
327
328    def test_settings_list_term(self):
329        self.complete_from_to(
330            'settings list term-',
331            'settings list term-width')
332
333    def test_settings_remove_term(self):
334        self.complete_from_to(
335            'settings remove term-',
336            'settings remove term-width')
337
338    def test_settings_s(self):
339        """Test that 'settings s' completes to ['set', 'show']."""
340        self.complete_from_to(
341            'settings s', [
342                'set', 'show'])
343
344    def test_settings_set_th(self):
345        """Test that 'settings set thread-f' completes to 'settings set thread-format'."""
346        self.complete_from_to('settings set thread-f', 'settings set thread-format')
347
348    def test_settings_s_dash(self):
349        """Test that 'settings set --g' completes to 'settings set --global'."""
350        self.complete_from_to('settings set --g', 'settings set --global')
351
352    def test_settings_clear_th(self):
353        """Test that 'settings clear thread-f' completes to 'settings clear thread-format'."""
354        self.complete_from_to(
355            'settings clear thread-f',
356            'settings clear thread-format')
357
358    def test_settings_set_ta(self):
359        """Test that 'settings set ta' completes to 'settings set target.'."""
360        self.complete_from_to(
361            'settings set target.ma',
362            'settings set target.max-')
363
364    def test_settings_set_target_exec(self):
365        """Test that 'settings set target.exec' completes to 'settings set target.exec-search-paths '."""
366        self.complete_from_to(
367            'settings set target.exec',
368            'settings set target.exec-search-paths')
369
370    def test_settings_set_target_pr(self):
371        """Test that 'settings set target.pr' completes to [
372        'target.prefer-dynamic-value', 'target.process.']."""
373        self.complete_from_to('settings set target.pr',
374                              ['target.prefer-dynamic-value',
375                               'target.process.'])
376
377    def test_settings_set_target_process(self):
378        """Test that 'settings set target.process' completes to 'settings set target.process.'."""
379        self.complete_from_to(
380            'settings set target.process',
381            'settings set target.process.')
382
383    def test_settings_set_target_process_dot(self):
384        """Test that 'settings set target.process.t' completes to 'settings set target.process.thread.'."""
385        self.complete_from_to(
386            'settings set target.process.t',
387            'settings set target.process.thread.')
388
389    def test_settings_set_target_process_thread_dot(self):
390        """Test that 'settings set target.process.thread.' completes to [
391        'target.process.thread.step-avoid-regexp', 'target.process.thread.trace-thread']."""
392        self.complete_from_to('settings set target.process.thread.',
393                              ['target.process.thread.step-avoid-regexp',
394                               'target.process.thread.trace-thread'])
395
396    def test_thread_plan_discard(self):
397        self.build()
398        (_, _, thread, _) = lldbutil.run_to_source_breakpoint(self,
399                                          'ptr_foo', lldb.SBFileSpec("main.cpp"))
400        self.assertTrue(thread)
401        self.complete_from_to('thread plan discard ', 'thread plan discard ')
402
403        source_path = os.path.join(self.getSourceDir(), "thread_plan_script.py")
404        self.runCmd("command script import '%s'"%(source_path))
405        self.runCmd("thread step-scripted -C thread_plan_script.PushPlanStack")
406        self.complete_from_to('thread plan discard ', 'thread plan discard 1')
407        self.runCmd('thread plan discard 1')
408
409    def test_target_space(self):
410        """Test that 'target ' completes to ['create', 'delete', 'list',
411        'modules', 'select', 'stop-hook', 'variable']."""
412        self.complete_from_to('target ',
413                              ['create',
414                               'delete',
415                               'list',
416                               'modules',
417                               'select',
418                               'stop-hook',
419                               'variable'])
420
421    def test_target_modules_dump_line_table(self):
422        """Tests source file completion by completing the line-table argument."""
423        self.build()
424        self.dbg.CreateTarget(self.getBuildArtifact("a.out"))
425        self.complete_from_to('target modules dump line-table main.cp',
426                              ['main.cpp'])
427
428    def test_target_modules_load_aout(self):
429        """Tests modules completion by completing the target modules load argument."""
430        self.build()
431        self.dbg.CreateTarget(self.getBuildArtifact("a.out"))
432        self.complete_from_to('target modules load a.ou',
433                              ['a.out'])
434
435    def test_target_modules_search_paths_insert(self):
436        # Completion won't work without a valid target.
437        self.complete_from_to("target modules search-paths insert ", "target modules search-paths insert ")
438        self.build()
439        target = self.dbg.CreateTarget(self.getBuildArtifact('a.out'))
440        self.assertTrue(target, VALID_TARGET)
441        self.complete_from_to("target modules search-paths insert ", "target modules search-paths insert ")
442        self.runCmd("target modules search-paths add a b")
443        self.complete_from_to("target modules search-paths insert ", "target modules search-paths insert 0")
444        # Completion only works for the first arg.
445        self.complete_from_to("target modules search-paths insert 0 ", "target modules search-paths insert 0 ")
446
447    def test_target_create_dash_co(self):
448        """Test that 'target create --co' completes to 'target variable --core '."""
449        self.complete_from_to('target create --co', 'target create --core ')
450
451    def test_target_va(self):
452        """Test that 'target va' completes to 'target variable '."""
453        self.complete_from_to('target va', 'target variable ')
454
455    def test_common_completion_thread_index(self):
456        subcommands = ['continue', 'info', 'exception', 'select',
457                       'step-in', 'step-inst', 'step-inst-over', 'step-out', 'step-over', 'step-script']
458
459        # Completion should do nothing without threads.
460        for subcommand in subcommands:
461            self.complete_from_to('thread ' + subcommand + ' ',
462                                  'thread ' + subcommand + ' ')
463
464        self.build()
465        lldbutil.run_to_source_breakpoint(self, '// Break here', lldb.SBFileSpec("main.cpp"))
466
467        # At least we have the thread at the index of 1 now.
468        for subcommand in subcommands:
469            self.complete_from_to('thread ' + subcommand + ' ', ['1'])
470
471    def test_common_completion_type_category_name(self):
472        subcommands = ['delete', 'list', 'enable', 'disable', 'define']
473        for subcommand in subcommands:
474            self.complete_from_to('type category ' + subcommand + ' ', ['default'])
475        self.complete_from_to('type filter add -w ', ['default'])
476
477    def test_command_argument_completion(self):
478        """Test completion of command arguments"""
479        self.complete_from_to("watchpoint set variable -", ["-w", "-s"])
480        self.complete_from_to('watchpoint set variable -w', 'watchpoint set variable -w ')
481        self.complete_from_to("watchpoint set variable --", ["--watch", "--size"])
482        self.complete_from_to("watchpoint set variable --w", "watchpoint set variable --watch")
483        self.complete_from_to('watchpoint set variable -w ', ['read', 'write', 'read_write'])
484        self.complete_from_to("watchpoint set variable --watch ", ["read", "write", "read_write"])
485        self.complete_from_to("watchpoint set variable --watch w", "watchpoint set variable --watch write")
486        self.complete_from_to('watchpoint set variable -w read_', 'watchpoint set variable -w read_write')
487        # Now try the same thing with a variable name (non-option argument) to
488        # test that getopts arg reshuffling doesn't confuse us.
489        self.complete_from_to("watchpoint set variable foo -", ["-w", "-s"])
490        self.complete_from_to('watchpoint set variable foo -w', 'watchpoint set variable foo -w ')
491        self.complete_from_to("watchpoint set variable foo --", ["--watch", "--size"])
492        self.complete_from_to("watchpoint set variable foo --w", "watchpoint set variable foo --watch")
493        self.complete_from_to('watchpoint set variable foo -w ', ['read', 'write', 'read_write'])
494        self.complete_from_to("watchpoint set variable foo --watch ", ["read", "write", "read_write"])
495        self.complete_from_to("watchpoint set variable foo --watch w", "watchpoint set variable foo --watch write")
496        self.complete_from_to('watchpoint set variable foo -w read_', 'watchpoint set variable foo -w read_write')
497
498    def test_command_script_delete(self):
499        self.runCmd("command script add -h test_desc -f none -s current usercmd1")
500        self.check_completion_with_desc('command script delete ', [['usercmd1', 'test_desc']])
501
502    def test_command_delete(self):
503        self.runCmd(r"command regex test_command s/^$/finish/ 's/([0-9]+)/frame select %1/'")
504        self.complete_from_to('command delete test_c', 'command delete test_command')
505
506    def test_command_unalias(self):
507        self.complete_from_to('command unalias ima', 'command unalias image')
508
509    def test_completion_description_commands(self):
510        """Test descriptions of top-level command completions"""
511        self.check_completion_with_desc("", [
512            ["command", "Commands for managing custom LLDB commands."],
513            ["breakpoint", "Commands for operating on breakpoints (see 'help b' for shorthand.)"]
514        ])
515
516        self.check_completion_with_desc("pl", [
517            ["platform", "Commands to manage and create platforms."],
518            ["plugin", "Commands for managing LLDB plugins."]
519        ])
520
521        # Just check that this doesn't crash.
522        self.check_completion_with_desc("comman", [])
523        self.check_completion_with_desc("non-existent-command", [])
524
525    def test_completion_description_command_options(self):
526        """Test descriptions of command options"""
527        # Short options
528        self.check_completion_with_desc("breakpoint set -", [
529            ["-h", "Set the breakpoint on exception catcH."],
530            ["-w", "Set the breakpoint on exception throW."]
531        ])
532
533        # Long options.
534        self.check_completion_with_desc("breakpoint set --", [
535            ["--on-catch", "Set the breakpoint on exception catcH."],
536            ["--on-throw", "Set the breakpoint on exception throW."]
537        ])
538
539        # Ambiguous long options.
540        self.check_completion_with_desc("breakpoint set --on-", [
541            ["--on-catch", "Set the breakpoint on exception catcH."],
542            ["--on-throw", "Set the breakpoint on exception throW."]
543        ])
544
545        # Unknown long option.
546        self.check_completion_with_desc("breakpoint set --Z", [
547        ])
548
549    def test_common_completion_frame_index(self):
550        self.build()
551        lldbutil.run_to_source_breakpoint(self, '// Break here', lldb.SBFileSpec("main.cpp"))
552
553        self.complete_from_to('frame select ', ['0'])
554        self.complete_from_to('thread backtrace -s ', ['0'])
555
556    def test_frame_recognizer_delete(self):
557        self.runCmd("frame recognizer add -l py_class -s module_name -n recognizer_name")
558        self.check_completion_with_desc('frame recognizer delete ', [['0', 'py_class, module module_name, symbol recognizer_name']])
559
560    def test_platform_install_local_file(self):
561        self.complete_from_to('platform target-install main.cp', 'platform target-install main.cpp')
562
563    @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24489")
564    def test_symbol_name(self):
565        self.build()
566        self.dbg.CreateTarget(self.getBuildArtifact("a.out"))
567        self.complete_from_to('breakpoint set -n Fo',
568                              'breakpoint set -n Foo::Bar(int,\\ int)',
569                              turn_off_re_match=True)
570        # No completion for Qu because the candidate is
571        # (anonymous namespace)::Quux().
572        self.complete_from_to('breakpoint set -n Qu', '')
573
574    @skipIf(archs=no_match(['x86_64']))
575    def test_register_read_and_write_on_x86(self):
576        """Test the completion of the commands register read and write on x86"""
577
578        # The tab completion for "register read/write"  won't work without a running process.
579        self.complete_from_to('register read ',
580                              'register read ')
581        self.complete_from_to('register write ',
582                              'register write ')
583
584        self.build()
585        self.main_source_spec = lldb.SBFileSpec("main.cpp")
586        lldbutil.run_to_source_breakpoint(self, '// Break here', self.main_source_spec)
587
588        # test cases for register read
589        self.complete_from_to('register read ',
590                              ['rax',
591                               'rbx',
592                               'rcx'])
593        self.complete_from_to('register read r',
594                              ['rax',
595                               'rbx',
596                               'rcx'])
597        self.complete_from_to('register read ra',
598                              'register read rax')
599        # register read can take multiple register names as arguments
600        self.complete_from_to('register read rax ',
601                              ['rax',
602                               'rbx',
603                               'rcx'])
604        # complete with prefix '$'
605        self.completions_match('register read $rb',
606                              ['$rbx',
607                               '$rbp'])
608        self.completions_match('register read $ra',
609                              ['$rax'])
610        self.complete_from_to('register read rax $',
611                              ['\$rax',
612                               '\$rbx',
613                               '\$rcx'])
614        self.complete_from_to('register read $rax ',
615                              ['rax',
616                               'rbx',
617                               'rcx'])
618
619        # test cases for register write
620        self.complete_from_to('register write ',
621                              ['rax',
622                               'rbx',
623                               'rcx'])
624        self.complete_from_to('register write r',
625                              ['rax',
626                               'rbx',
627                               'rcx'])
628        self.complete_from_to('register write ra',
629                              'register write rax')
630        self.complete_from_to('register write rb',
631                              ['rbx',
632                               'rbp'])
633        # register write can only take exact one register name as argument
634        self.complete_from_to('register write rbx ',
635                              [])
636
637    def test_common_completion_target_stophook_ids(self):
638        subcommands = ['delete', 'enable', 'disable']
639
640        for subcommand in subcommands:
641            self.complete_from_to('target stop-hook ' + subcommand + ' ',
642                                  'target stop-hook ' + subcommand + ' ')
643
644        self.build()
645        self.dbg.CreateTarget(self.getBuildArtifact("a.out"))
646        self.runCmd('target stop-hook add test DONE')
647
648        for subcommand in subcommands:
649            self.complete_from_to('target stop-hook ' + subcommand + ' ',
650                                  'target stop-hook ' + subcommand + ' 1')
651
652        # Completion should work only on the first argument.
653        for subcommand in subcommands:
654            self.complete_from_to('target stop-hook ' + subcommand + ' 1 ',
655                                  'target stop-hook ' + subcommand + ' 1 ')
656
657    def test_common_completion_type_language(self):
658        self.complete_from_to('type category -l ', ['c'])
659
660    def test_target_modules_load_dash_u(self):
661        self.build()
662        target = self.dbg.CreateTarget(self.getBuildArtifact("a.out"))
663        self.complete_from_to('target modules load -u ', [target.GetModuleAtIndex(0).GetUUIDString()])
664
665    def test_complete_breakpoint_with_ids(self):
666        """These breakpoint subcommands should be completed with a list of breakpoint ids"""
667
668        subcommands = ['enable', 'disable', 'delete', 'modify', 'name add', 'name delete', 'write']
669
670        # The tab completion here is unavailable without a target
671        for subcommand in subcommands:
672            self.complete_from_to('breakpoint ' + subcommand + ' ',
673                                  'breakpoint ' + subcommand + ' ')
674
675        self.build()
676        target = self.dbg.CreateTarget(self.getBuildArtifact('a.out'))
677        self.assertTrue(target, VALID_TARGET)
678
679        bp = target.BreakpointCreateByName('main', 'a.out')
680        self.assertTrue(bp)
681        self.assertEqual(bp.GetNumLocations(), 1)
682
683        for subcommand in subcommands:
684            self.complete_from_to('breakpoint ' + subcommand + ' ',
685                                  ['1'])
686
687        bp2 = target.BreakpointCreateByName('Bar', 'a.out')
688        self.assertTrue(bp2)
689        self.assertEqual(bp2.GetNumLocations(), 1)
690
691        for subcommand in subcommands:
692            self.complete_from_to('breakpoint ' + subcommand + ' ',
693                                  ['1',
694                                   '2'])
695
696        for subcommand in subcommands:
697            self.complete_from_to('breakpoint ' + subcommand + ' 1 ',
698                                  ['1',
699                                   '2'])
700
701    def test_complete_breakpoint_with_names(self):
702        self.build()
703        target = self.dbg.CreateTarget(self.getBuildArtifact('a.out'))
704        self.assertTrue(target, VALID_TARGET)
705
706        # test breakpoint read dedicated
707        self.complete_from_to('breakpoint read -N ', 'breakpoint read -N ')
708        self.complete_from_to('breakpoint read -f breakpoints.json -N ', ['mm'])
709        self.complete_from_to('breakpoint read -f breakpoints.json -N n', 'breakpoint read -f breakpoints.json -N n')
710        self.complete_from_to('breakpoint read -f breakpoints_invalid.json -N ', 'breakpoint read -f breakpoints_invalid.json -N ')
711
712        # test common breapoint name completion
713        bp1 = target.BreakpointCreateByName('main', 'a.out')
714        self.assertTrue(bp1)
715        self.assertEqual(bp1.GetNumLocations(), 1)
716        self.complete_from_to('breakpoint set -N n', 'breakpoint set -N n')
717        self.assertTrue(bp1.AddNameWithErrorHandling("nn"))
718        self.complete_from_to('breakpoint set -N ', 'breakpoint set -N nn')
719