Home | History | Annotate | Download | only in completion
      1 """
      2 Test the lldb command line completion mechanism.
      3 """
      4 
      5 import os
      6 import unittest2
      7 import lldb
      8 import pexpect
      9 from lldbtest import *
     10 
     11 class CommandLineCompletionTestCase(TestBase):
     12 
     13     mydir = os.path.join("functionalities", "completion")
     14 
     15     @classmethod
     16     def classCleanup(cls):
     17         """Cleanup the test byproducts."""
     18         try:
     19             os.remove("child_send.txt")
     20             os.remove("child_read.txt")
     21         except:
     22             pass
     23 
     24     def test_at(self):
     25         """Test that 'at' completes to 'attach '."""
     26         self.complete_from_to('at', 'attach ')
     27 
     28     def test_de(self):
     29         """Test that 'de' completes to 'detach '."""
     30         self.complete_from_to('de', 'detach ')
     31 
     32     def test_process_attach_dash_dash_con(self):
     33         """Test that 'process attach --con' completes to 'process attach --continue '."""
     34         self.complete_from_to('process attach --con', 'process attach --continue ')
     35 
     36     # <rdar://problem/11052829>
     37     @skipIfLinux # llvm.org/pr14637: this test case fails (with GCC 4.6 but not clang) because the input prompt "(lldb)" is missing
     38     def test_infinite_loop_while_completing(self):
     39         """Test that 'process print hello\' completes to itself and does not infinite loop."""
     40         self.complete_from_to('process print hello\\', 'process print hello\\',
     41                               turn_off_re_match=True)
     42 
     43     def test_watchpoint_command_dash_w_space(self):
     44         """Test that 'watchpoint command' completes to ['Available completions:', 'add', 'delete', 'list']."""
     45         self.complete_from_to('watchpoint command', ['Available completions:', 'add', 'delete', 'list'])
     46 
     47     def test_watchpoint_set_variable_dash_w(self):
     48         """Test that 'watchpoint set variable -w' completes to 'watchpoint set variable -w '."""
     49         self.complete_from_to('watchpoint set variable -w', 'watchpoint set variable -w ')
     50 
     51     def test_watchpoint_set_variable_dash_w_space(self):
     52         """Test that 'watchpoint set variable -w ' completes to ['Available completions:', 'read', 'write', 'read_write']."""
     53         self.complete_from_to('watchpoint set variable -w ', ['Available completions:', 'read', 'write', 'read_write'])
     54 
     55     def test_watchpoint_set_ex(self):
     56         """Test that 'watchpoint set ex' completes to 'watchpoint set expression '."""
     57         self.complete_from_to('watchpoint set ex', 'watchpoint set expression ')
     58 
     59     def test_watchpoint_set_var(self):
     60         """Test that 'watchpoint set var' completes to 'watchpoint set variable '."""
     61         self.complete_from_to('watchpoint set var', 'watchpoint set variable ')
     62 
     63     def test_watchpoint_set_variable_dash_w_read_underbar(self):
     64         """Test that 'watchpoint set variable -w read_' completes to 'watchpoint set variable -w read_write'."""
     65         self.complete_from_to('watchpoint set variable -w read_', 'watchpoint set variable -w read_write')
     66 
     67     def test_help_fi(self):
     68         """Test that 'help fi' completes to ['Available completions:', 'file', 'finish']."""
     69         self.complete_from_to('help fi', ['Available completions:', 'file', 'finish'])
     70 
     71     def test_help_watchpoint_s(self):
     72         """Test that 'help watchpoint s' completes to 'help watchpoint set '."""
     73         self.complete_from_to('help watchpoint s', 'help watchpoint set ')
     74 
     75     def test_settings_append_target_er(self):
     76         """Test that 'settings append target.er' completes to 'settings append target.error-path'."""
     77         self.complete_from_to('settings append target.er', 'settings append target.error-path')
     78 
     79     def test_settings_insert_after_target_en(self):
     80         """Test that 'settings insert-after target.env' completes to 'settings insert-after target.env-vars'."""
     81         self.complete_from_to('settings insert-after target.env', 'settings insert-after target.env-vars')
     82 
     83     def test_settings_insert_before_target_en(self):
     84         """Test that 'settings insert-before target.env' completes to 'settings insert-before target.env-vars'."""
     85         self.complete_from_to('settings insert-before target.env', 'settings insert-before target.env-vars')
     86 
     87     def test_settings_replace_target_ru(self):
     88         """Test that 'settings replace target.ru' completes to 'settings replace target.run-args'."""
     89         self.complete_from_to('settings replace target.ru', 'settings replace target.run-args')
     90 
     91     def test_settings_s(self):
     92         """Test that 'settings s' completes to ['Available completions:', 'set', 'show']."""
     93         self.complete_from_to('settings s', ['Available completions:', 'set', 'show'])
     94 
     95     def test_settings_set_th(self):
     96         """Test that 'settings set th' completes to 'settings set thread-format'."""
     97         self.complete_from_to('settings set th', 'settings set thread-format')
     98 
     99     def test_settings_s_dash(self):
    100         """Test that 'settings set -' completes to 'settings set -g'."""
    101         self.complete_from_to('settings set -', 'settings set -g')
    102 
    103     def test_settings_clear_th(self):
    104         """Test that 'settings clear th' completes to 'settings clear thread-format'."""
    105         self.complete_from_to('settings clear th', 'settings clear thread-format')
    106 
    107     def test_settings_set_ta(self):
    108         """Test that 'settings set ta' completes to 'settings set target.'."""
    109         self.complete_from_to('settings set ta', 'settings set target.')
    110 
    111     def test_settings_set_target_exec(self):
    112         """Test that 'settings set target.exec' completes to 'settings set target.exec-search-paths '."""
    113         self.complete_from_to('settings set target.exec', 'settings set target.exec-search-paths')
    114 
    115     def test_settings_set_target_pr(self):
    116         """Test that 'settings set target.pr' completes to ['Available completions:',
    117         'target.prefer-dynamic-value', 'target.process.']."""
    118         self.complete_from_to('settings set target.pr',
    119                               ['Available completions:',
    120                                'target.prefer-dynamic-value',
    121                                'target.process.'])
    122 
    123     def test_settings_set_target_process(self):
    124         """Test that 'settings set target.process' completes to 'settings set target.process.'."""
    125         self.complete_from_to('settings set target.process', 'settings set target.process.')
    126 
    127     def test_settings_set_target_process_dot(self):
    128         """Test that 'settings set target.process.t' completes to 'settings set target.process.thread.'."""
    129         self.complete_from_to('settings set target.process.t', 'settings set target.process.thread.')
    130 
    131     def test_settings_set_target_process_thread_dot(self):
    132         """Test that 'settings set target.process.thread.' completes to ['Available completions:',
    133         'target.process.thread.step-avoid-regexp', 'target.process.thread.trace-thread']."""
    134         self.complete_from_to('settings set target.process.thread.',
    135                               ['Available completions:',
    136                                'target.process.thread.step-avoid-regexp',
    137                                'target.process.thread.trace-thread'])
    138 
    139     def test_target_space(self):
    140         """Test that 'target ' completes to ['Available completions:', 'create', 'delete', 'list',
    141         'modules', 'select', 'stop-hook', 'variable']."""
    142         self.complete_from_to('target ',
    143                               ['Available completions:', 'create', 'delete', 'list',
    144                                'modules', 'select', 'stop-hook', 'variable'])
    145 
    146     def test_target_create_dash_co(self):
    147         """Test that 'target create --co' completes to 'target variable --core '."""
    148         self.complete_from_to('target create --co', 'target create --core ')
    149 
    150     def test_target_va(self):
    151         """Test that 'target va' completes to 'target variable '."""
    152         self.complete_from_to('target va', 'target variable ')
    153 
    154     def complete_from_to(self, str_input, patterns, turn_off_re_match=False):
    155         """Test that the completion mechanism completes str_input to patterns,
    156         where patterns could be a pattern-string or a list of pattern-strings"""
    157         # Patterns should not be None in order to proceed.
    158         self.assertFalse(patterns is None)
    159         # And should be either a string or list of strings.  Check for list type
    160         # below, if not, make a list out of the singleton string.  If patterns
    161         # is not a string or not a list of strings, there'll be runtime errors
    162         # later on.
    163         if not isinstance(patterns, list):
    164             patterns = [patterns]
    165         
    166         # The default lldb prompt.
    167         prompt = "(lldb) "
    168 
    169         # So that the child gets torn down after the test.
    170         self.child = pexpect.spawn('%s %s' % (self.lldbHere, self.lldbOption))
    171         child = self.child
    172         # Turn on logging for input/output to/from the child.
    173         with open('child_send.txt', 'w') as f_send:
    174             with open('child_read.txt', 'w') as f_read:
    175                 child.logfile_send = f_send
    176                 child.logfile_read = f_read
    177 
    178                 child.expect_exact(prompt)
    179                 child.setecho(True)
    180                 # Sends str_input and a Tab to invoke the completion machinery.
    181                 child.send("%s\t" % str_input)
    182                 child.sendline('')
    183                 child.expect_exact(prompt)
    184 
    185         # Now that the necessary logging is done, restore logfile to None to
    186         # stop further logging.
    187         child.logfile_send = None
    188         child.logfile_read = None
    189         
    190         with open('child_send.txt', 'r') as fs:
    191             if self.TraceOn():
    192                 print "\n\nContents of child_send.txt:"
    193                 print fs.read()
    194         with open('child_read.txt', 'r') as fr:
    195             from_child = fr.read()
    196             if self.TraceOn():
    197                 print "\n\nContents of child_read.txt:"
    198                 print from_child
    199 
    200             # The matching could be verbatim or using generic re pattern.
    201             for p in patterns:
    202                 # Test that str_input completes to our patterns or substrings.
    203                 # If each pattern/substring matches from_child, the completion mechanism works!
    204                 if turn_off_re_match:
    205                     self.expect(from_child, msg=COMPLETION_MSG(str_input, p), exe=False,
    206                         substrs = [p])
    207                 else:
    208                     self.expect(from_child, msg=COMPLETION_MSG(str_input, p), exe=False,
    209                         patterns = [p])
    210 
    211 
    212 if __name__ == '__main__':
    213     import atexit
    214     lldb.SBDebugger.Initialize()
    215     atexit.register(lambda: lldb.SBDebugger.Terminate())
    216     unittest2.main()
    217