diff options
Diffstat (limited to 'packages/Python/lldbsuite/test/lldbtest.py')
| -rw-r--r-- | packages/Python/lldbsuite/test/lldbtest.py | 188 | 
1 files changed, 152 insertions, 36 deletions
diff --git a/packages/Python/lldbsuite/test/lldbtest.py b/packages/Python/lldbsuite/test/lldbtest.py index 1b6302ae96a6..161e8c61349d 100644 --- a/packages/Python/lldbsuite/test/lldbtest.py +++ b/packages/Python/lldbsuite/test/lldbtest.py @@ -72,8 +72,7 @@ from lldbsuite.support import encoded_file  from lldbsuite.support import funcutils  # See also dotest.parseOptionsAndInitTestdirs(), where the environment variables -# LLDB_COMMAND_TRACE and LLDB_DO_CLEANUP are set from '-t' and '-r dir' -# options. +# LLDB_COMMAND_TRACE is set from '-t' option.  # By default, traceAlways is False.  if "LLDB_COMMAND_TRACE" in os.environ and os.environ[ @@ -740,6 +739,11 @@ class Base(unittest2.TestCase):          else:              self.lldbMiExec = None +        if "LLDBVSCODE_EXEC" in os.environ: +            self.lldbVSCodeExec = os.environ["LLDBVSCODE_EXEC"] +        else: +            self.lldbVSCodeExec = None +          # If we spawn an lldb process for test (via pexpect), do not load the          # init file unless told otherwise.          if "NO_LLDBINIT" in os.environ and "NO" == os.environ["NO_LLDBINIT"]: @@ -1215,12 +1219,15 @@ class Base(unittest2.TestCase):                  if os.path.isfile(src):                      dst = src.replace(self.log_basename, dst_log_basename)                      if os.name == "nt" and os.path.isfile(dst): -                        # On Windows, renaming a -> b will throw an exception if b exists.  On non-Windows platforms -                        # it silently replaces the destination.  Ultimately this means that atomic renames are not -                        # guaranteed to be possible on Windows, but we need this to work anyway, so just remove the -                        # destination first if it already exists. +                        # On Windows, renaming a -> b will throw an exception if +                        # b exists.  On non-Windows platforms it silently +                        # replaces the destination.  Ultimately this means that +                        # atomic renames are not guaranteed to be possible on +                        # Windows, but we need this to work anyway, so just +                        # remove the destination first if it already exists.                          remove_file(dst) +                    lldbutil.mkdir_p(os.path.dirname(dst))                      os.rename(src, dst)          else:              # success!  (and we don't want log files) delete log files @@ -1302,18 +1309,6 @@ class Base(unittest2.TestCase):                  version = m.group(1)          return version -    def getGoCompilerVersion(self): -        """ Returns a string that represents the go compiler version, or None if go is not found. -        """ -        compiler = which("go") -        if compiler: -            version_output = system([[compiler, "version"]])[0] -            for line in version_output.split(os.linesep): -                m = re.search('go version (devel|go\\S+)', line) -                if m: -                    return m.group(1) -        return None -      def platformIsDarwin(self):          """Returns true if the OS triple for the selected platform is any valid apple OS"""          return lldbplatformutil.platformIsDarwin() @@ -1582,12 +1577,6 @@ class Base(unittest2.TestCase):                                      dictionary, testdir, testname):              raise Exception("Don't know how to build binary with gmodules") -    def buildGo(self): -        """Build the default go binary. -        """ -        exe = self.getBuildArtifact("a.out") -        system([[which('go'), 'build -gcflags "-N -l" -o %s main.go' % exe]]) -      def signBinary(self, binary_path):          if sys.platform.startswith("darwin"):              codesign_cmd = "codesign --force --sign \"%s\" %s" % ( @@ -1875,18 +1864,16 @@ class TestBase(Base):          # decorators.          Base.setUp(self) -        if self.child: -            # Set the clang modules cache path. -            assert(self.getDebugInfo() == 'default') -            mod_cache = os.path.join(self.getBuildDir(), "module-cache") -            self.runCmd('settings set symbols.clang-modules-cache-path "%s"' -                        % mod_cache) - -            # Disable Spotlight lookup. The testsuite creates -            # different binaries with the same UUID, because they only -            # differ in the debug info, which is not being hashed. -            self.runCmd('settings set symbols.enable-external-lookup false') +        # Set the clang modules cache path used by LLDB. +        mod_cache = os.path.join(os.path.join(os.environ["LLDB_BUILD"], +                                              "module-cache-lldb")) +        self.runCmd('settings set symbols.clang-modules-cache-path "%s"' +                    % mod_cache) +        # Disable Spotlight lookup. The testsuite creates +        # different binaries with the same UUID, because they only +        # differ in the debug info, which is not being hashed. +        self.runCmd('settings set symbols.enable-external-lookup false')          if "LLDB_MAX_LAUNCH_COUNT" in os.environ:              self.maxLaunchCount = int(os.environ["LLDB_MAX_LAUNCH_COUNT"]) @@ -2074,8 +2061,17 @@ class TestBase(Base):                      print("Command '" + cmd + "' failed!", file=sbuf)          if check: +            output = "" +            if self.res.GetOutput(): +              output += "\nCommand output:\n" + self.res.GetOutput() +            if self.res.GetError(): +              output += "\nError output:\n" + self.res.GetError() +            if msg: +              msg += output +            if cmd: +              cmd += output              self.assertTrue(self.res.Succeeded(), -                            msg if msg else CMD_MSG(cmd)) +                            msg if (msg) else CMD_MSG(cmd))      def match(              self, @@ -2134,6 +2130,126 @@ class TestBase(Base):          return match_object +    def check_completion_with_desc(self, str_input, match_desc_pairs): +        interp = self.dbg.GetCommandInterpreter() +        match_strings = lldb.SBStringList() +        description_strings = lldb.SBStringList() +        num_matches = interp.HandleCompletionWithDescriptions(str_input, len(str_input), 0, -1, match_strings, description_strings) +        self.assertEqual(len(description_strings), len(match_strings)) + +        missing_pairs = [] +        for pair in match_desc_pairs: +            found_pair = False +            for i in range(num_matches + 1): +                match_candidate = match_strings.GetStringAtIndex(i) +                description_candidate = description_strings.GetStringAtIndex(i) +                if match_candidate == pair[0] and description_candidate == pair[1]: +                    found_pair = True +                    break +            if not found_pair: +                missing_pairs.append(pair) + +        if len(missing_pairs): +            error_msg = "Missing pairs:\n" +            for pair in missing_pairs: +                error_msg += " [" + pair[0] + ":" + pair[1] + "]\n" +            error_msg += "Got the following " + str(num_matches) + " completions back:\n" +            for i in range(num_matches + 1): +                match_candidate = match_strings.GetStringAtIndex(i) +                description_candidate = description_strings.GetStringAtIndex(i) +                error_msg += "[" + match_candidate + ":" + description_candidate + "]\n" +            self.assertEqual(0, len(missing_pairs), error_msg) + +    def complete_exactly(self, str_input, patterns): +        self.complete_from_to(str_input, patterns, True) + +    def complete_from_to(self, str_input, patterns, turn_off_re_match=False): +        """Test that the completion mechanism completes str_input to patterns, +        where patterns could be a pattern-string or a list of pattern-strings""" +        # Patterns should not be None in order to proceed. +        self.assertFalse(patterns is None) +        # And should be either a string or list of strings.  Check for list type +        # below, if not, make a list out of the singleton string.  If patterns +        # is not a string or not a list of strings, there'll be runtime errors +        # later on. +        if not isinstance(patterns, list): +            patterns = [patterns] + +        interp = self.dbg.GetCommandInterpreter() +        match_strings = lldb.SBStringList() +        num_matches = interp.HandleCompletion(str_input, len(str_input), 0, -1, match_strings) +        common_match = match_strings.GetStringAtIndex(0) +        if num_matches == 0: +            compare_string = str_input +        else: +            if common_match != None and len(common_match) > 0: +                compare_string = str_input + common_match +            else: +                compare_string = "" +                for idx in range(1, num_matches+1): +                    compare_string += match_strings.GetStringAtIndex(idx) + "\n" + +        for p in patterns: +            if turn_off_re_match: +                self.expect( +                    compare_string, msg=COMPLETION_MSG( +                        str_input, p, match_strings), exe=False, substrs=[p]) +            else: +                self.expect( +                    compare_string, msg=COMPLETION_MSG( +                        str_input, p, match_strings), exe=False, patterns=[p]) + +    def filecheck( +            self, +            command, +            check_file, +            filecheck_options = ''): +        # Run the command. +        self.runCmd( +                command, +                msg="FileCheck'ing result of `{0}`".format(command)) + +        # Get the error text if there was an error, and the regular text if not. +        output = self.res.GetOutput() if self.res.Succeeded() \ +                else self.res.GetError() + +        # Assemble the absolute path to the check file. As a convenience for +        # LLDB inline tests, assume that the check file is a relative path to +        # a file within the inline test directory. +        if check_file.endswith('.pyc'): +            check_file = check_file[:-1] +        check_file_abs = os.path.abspath(check_file) + +        # Run FileCheck. +        filecheck_bin = configuration.get_filecheck_path() +        if not filecheck_bin: +            self.assertTrue(False, "No valid FileCheck executable specified") +        filecheck_args = [filecheck_bin, check_file_abs] +        if filecheck_options: +            filecheck_args.append(filecheck_options) +        subproc = Popen(filecheck_args, stdin=PIPE, stdout=PIPE, stderr=PIPE, universal_newlines = True) +        cmd_stdout, cmd_stderr = subproc.communicate(input=output) +        cmd_status = subproc.returncode + +        filecheck_cmd = " ".join(filecheck_args) +        filecheck_trace = """ +--- FileCheck trace (code={0}) --- +{1} + +FileCheck input: +{2} + +FileCheck output: +{3} +{4} +""".format(cmd_status, filecheck_cmd, output, cmd_stdout, cmd_stderr) + +        trace = cmd_status != 0 or traceAlways +        with recording(self, trace) as sbuf: +            print(filecheck_trace, file=sbuf) + +        self.assertTrue(cmd_status == 0) +      def expect(              self,              str,  | 
