def RunTest(test):
  command = [test_runner, test] + test_runner_runtime_options
  if test_runner_under_valgrind:
    command = ['valgrind'] + command

  p = subprocess.Popen(command,
                       stdout=subprocess.PIPE,
                       stderr=subprocess.STDOUT)
  p_out, p_err = p.communicate()
  rc = p.poll()

  if rc == 0:
    with n_tests_passed.get_lock(): n_tests_passed.value += 1
  else:
    with n_tests_failed.get_lock(): n_tests_failed.value += 1

  printer.__print_lock__.acquire()

  printer.UpdateProgress(start_time,
                         n_tests_passed.value,
                         n_tests_failed.value,
                         n_tests,
                         test,
                         prevent_next_overwrite = (rc != 0),
                         has_lock = True,
                         prefix = progress_prefix)

  if rc != 0:
    printer.Print('FAILED: ' + test, has_lock = True)
    printer.Print(printer.COLOUR_RED + ' '.join(command) + printer.NO_COLOUR,
                  has_lock = True)
    printer.Print(p_out, has_lock = True)

  printer.__print_lock__.release()
Example #2
0
    def Run(self, jobs, verbose, run_function):
        def InitGlobals():
            # Initialisation.
            self.start_time = time.time()
            self.n_tests = len(self.queue)
            if self.n_tests == 0:
                printer.Print('No tests to run.')
                return False
            Test.n_tests_passed.value = 0
            Test.n_tests_failed.value = 0
            Test.n_tests_skipped.value = 0
            self.tests_skipped.clear()
            return True

        thread_pool.Multithread(run_function, self.queue, jobs, InitGlobals)

        printer.UpdateProgress(self.start_time,
                               Test.n_tests_passed.value,
                               Test.n_tests_failed.value,
                               self.n_tests,
                               Test.n_tests_skipped.value,
                               self.n_known_failures,
                               '== Done ==',
                               prevent_next_overwrite=True,
                               prefix=self.progress_prefix)
        n_tests_features = 0
        features = set()
        for reason, n_tests in list(self.tests_skipped.items()):
            m = re.match(REGEXP_MISSING_FEATURES, reason)
            if m:
                if verbose:
                    printer.Print(
                        "%d tests skipped because the following features are not "
                        "available '%s'" % (n_tests, m.group(1)))
                else:
                    n_tests_features += n_tests
                    features.update(m.group(1).split(', '))
            else:
                printer.Print("%d tests skipped because '%s'" %
                              (n_tests, reason))

        n_tests_other = 0
        if n_tests_features > 0:
            printer.Print("%d tests skipped because the CPU does not support "
                          "the following features: '%s'" %
                          (n_tests_features, ", ".join(features)))

        for reason, n_tests in list(self.known_failures.items()):
            printer.Print("%d tests skipped because '%s'" % (n_tests, reason))

        # Empty the queue now that the tests have been run.
        self.queue = []
        # `0` indicates success
        return Test.n_tests_failed.value
Example #3
0
def RunTest(test):
    command = test.args['command']
    p = subprocess.Popen(command,
                         stdout=subprocess.PIPE,
                         stderr=subprocess.STDOUT)
    p_out, p_err = p.communicate()
    rc = p.poll()

    if rc == 0:
        skipped = False
        lines = p_out.split('\n')
        skipped_id = "SKIPPED: "
        for i in range(len(lines)):
            if lines[i].startswith(skipped_id):
                skipped = True
                reason = lines[i][len(skipped_id):]
                with Test.n_tests_skipped.get_lock():
                    Test.n_tests_skipped.value += 1
                    test.shared.tests_skipped.setdefault(reason, 0)
                    test.shared.tests_skipped[reason] += 1
                break
        if not skipped:
            with Test.n_tests_passed.get_lock():
                Test.n_tests_passed.value += 1
    else:
        with Test.n_tests_failed.get_lock():
            Test.n_tests_failed.value += 1

    printer.__print_lock__.acquire()

    printer.UpdateProgress(test.shared.start_time,
                           Test.n_tests_passed.value,
                           Test.n_tests_failed.value,
                           test.shared.n_tests,
                           Test.n_tests_skipped.value,
                           test.shared.n_known_failures,
                           test.name,
                           prevent_next_overwrite=(rc != 0),
                           has_lock=True,
                           prefix=test.shared.progress_prefix)

    if rc != 0:
        printer.Print('FAILED: ' + test.name, has_lock=True)
        printer.Print(printer.COLOUR_RED + ' '.join(command) +
                      printer.NO_COLOUR,
                      has_lock=True)
        printer.Print(p_out, has_lock=True)

    printer.__print_lock__.release()
Example #4
0
def Lint(filename, progress_prefix = ''):
  command = ['cpplint.py', filename]
  process = subprocess.Popen(command,
                             stdout=subprocess.PIPE,
                             stderr=subprocess.STDOUT)

  outerr, _ = process.communicate()

  if process.returncode == 0:
    printer.PrintOverwritableLine(
      progress_prefix + "Done processing %s" % filename,
      type = printer.LINE_TYPE_LINTER)
    return (filename, 0)

  if progress_prefix:
    outerr = re.sub('^', progress_prefix, outerr, flags=re.MULTILINE)
  printer.Print(outerr)

  # Find the number of errors in this file.
  res = re.search('Total errors found: (\d+)', outerr)
  if res:
    n_errors_str = res.string[res.start(1):res.end(1)]
    n_errors = int(n_errors_str)
  else:
    print("Couldn't parse cpplint.py output.")
    n_errors = -1

  return (filename, n_errors)
Example #5
0
def ClangTidyFiles(files, clang_tidy, jobs=1, progress_prefix=''):
    if not ClangTidyIsAvailable(clang_tidy):
        error_message = "`{}` version {}.{} not found. Please ensure it " \
                        "is installed, in your PATH and the correct version." \
                        .format(clang_tidy,
                                CLANG_TIDY_VERSION_MAJOR,
                                CLANG_TIDY_VERSION_MINOR)
        print(printer.COLOUR_RED + error_message + printer.NO_COLOUR)
        return -1

    opts = [
        '--', '-DVIXL_INCLUDE_TARGET_AARCH64', '-DVIXL_CODE_BUFFER_MALLOC',
        '-DVIXL_DEBUG', '-DVIXL_INCLUDE_SIMLUATOR_AARCH64',
        '-DVIXL_INCLUDE_TARGET_A32', '-DVIXL_INCLUDE_TARGET_T32',
        '-DVIXL_INCLUDE_TARGET_A64'
    ]
    opts += ['-I%s' % config.dir_src_vixl]
    opts += ['-I%s' % config.dir_tests]
    opts += ['-I%s' % config.dir_aarch64_examples]
    opts += ['-I%s' % config.dir_aarch32_examples]

    to_check = FilterFiles(files)
    printer.Print("clang-tidy: %d files to check" % len(to_check))

    queue = TestQueue(prefix=progress_prefix)

    for file in to_check:
        for cpp_version in config.tested_cpp_standards:
            command = [clang_tidy, file] + opts + ['-std=%s' % cpp_version]
            queue.AddTest(file, command=command)

    return queue.Run(jobs, True, RunTest)
Example #6
0
def LintFiles(files,
              jobs = 1,
              progress_prefix = '',
              cached_results = None):
  if not IsCppLintAvailable():
    print(
      printer.COLOUR_RED + \
      ("cpplint.py not found. Please ensure the depot"
       " tools are installed and in your PATH. See"
       " http://dev.chromium.org/developers/how-tos/install-depot-tools for"
       " details.") + \
      printer.NO_COLOUR)
    return -1

  # Filter out directories.
  files = filter(os.path.isfile, files)

  # Filter out files for which we have a cached correct result.
  if cached_results is not None and len(cached_results) != 0:
    n_input_files = len(files)
    files = filter(lambda f: ShouldLint(f, cached_results), files)
    n_skipped_files = n_input_files - len(files)
    if n_skipped_files != 0:
      printer.Print(
        progress_prefix +
        'Skipping %d correct files that were already processed.' %
        n_skipped_files)

  pool = multiprocessing.Pool(jobs)
  # The '.get(9999999)' is workaround to allow killing the test script with
  # ctrl+C from the shell. This bug is documented at
  # http://bugs.python.org/issue8296.
  tasks = [(f, progress_prefix) for f in files]
  # Run under a try-catch  to avoid flooding the output when the script is
  # interrupted from the keyboard with ctrl+C.
  try:
    results = pool.map_async(LintWrapper, tasks).get(9999999)
    pool.close()
    pool.join()
  except KeyboardInterrupt:
    pool.terminate()
    sys.exit(1)

  n_errors = sum(map(lambda (filename, errors): errors, results))

  if cached_results is not None:
    for filename, errors in results:
      if errors == 0:
        with open(filename, 'rb') as f:
          filename = os.path.realpath(filename)
          file_hash = hashlib.md5(f.read()).hexdigest()
          cached_results[filename] = file_hash


  printer.PrintOverwritableLine(
      progress_prefix + 'Total errors found: %d' % n_errors)
  printer.EnsureNewLine()
  return n_errors
Example #7
0
def GetDefaultTrackedFiles():
    if git.is_git_repository_root(config.dir_root):
        default_tracked_files = git.get_tracked_files().split()
        default_tracked_files = filter(is_linter_input, default_tracked_files)
        return 0, default_tracked_files
    else:
        printer.Print(printer.COLOUR_ORANGE + 'WARNING: This script is not run ' \
                      'from its Git repository. The linter will not run.' + \
                      printer.NO_COLOUR)
        return 1, []
Example #8
0
def GetDefaultFilesToLint():
  if git.is_git_repository_root(config.dir_root):
    files = git.get_tracked_files().split()
    files = filter(IsLinterInput, files)
    files = FilterOutTestTraceHeaders(files)
    return 0, files
  else:
    printer.Print(printer.COLOUR_ORANGE + 'WARNING: This script is not run ' \
                  'from its Git repository. The linter will not run.' + \
                  printer.NO_COLOUR)
    return 1, []
Example #9
0
 def InitGlobals():
     # Initialisation.
     self.start_time = time.time()
     self.n_tests = len(self.queue)
     if self.n_tests == 0:
         printer.Print('No tests to run.')
         return False
     Test.n_tests_passed.value = 0
     Test.n_tests_failed.value = 0
     Test.n_tests_skipped.value = 0
     self.tests_skipped.clear()
     return True
Example #10
0
def RunTest(test):
    cmd = " ".join(test.args['command'])
    rc, p_out = util.getstatusoutput(cmd)
    if rc != 0:
        # This usually happens when the compiler hits a '#error' because of
        # a missing define.
        printer.Print("%sFATAL ERROR: failed to run command '%s': %s%s" %
                      (printer.COLOUR_RED, cmd, p_out, printer.NO_COLOUR))
    p_out = FilterClangTidyLines(p_out.split('\n'))

    failed = (len(p_out) > 0) or (rc != 0)

    if failed:
        with Test.n_tests_failed.get_lock():
            Test.n_tests_failed.value += 1
    else:
        with Test.n_tests_passed.get_lock():
            Test.n_tests_passed.value += 1

    printer.__print_lock__.acquire()

    printer.UpdateProgress(test.shared.start_time,
                           Test.n_tests_passed.value,
                           Test.n_tests_failed.value,
                           test.shared.n_tests,
                           Test.n_tests_skipped.value,
                           test.shared.n_known_failures,
                           test.name,
                           prevent_next_overwrite=failed,
                           has_lock=True,
                           prefix=test.shared.progress_prefix)

    if failed:
        printer.Print(printer.COLOUR_RED + 'FAILED: ' + cmd +
                      printer.NO_COLOUR,
                      has_lock=True)
        printer.Print(p_out, has_lock=True)

    printer.__print_lock__.release()
Example #11
0
def RunTests(test_runner_command,
             filters,
             runtime_options,
             under_valgrind=False,
             jobs=1,
             prefix=''):
    global test_runner
    global test_runner_runtime_options
    global test_runner_under_valgrind
    global n_tests
    global start_time
    global progress_prefix

    tests = GetTests(test_runner_command, filters)
    tests = FilterKnownTestFailures(tests, under_valgrind=under_valgrind)

    if n_tests == 0:
        printer.Print('No tests to run.')
        return 0

    with __run_tests_lock__:

        # Initialisation.
        start_time = time.time()
        test_runner = test_runner_command
        test_runner_runtime_options = runtime_options
        test_runner_under_valgrind = under_valgrind
        n_tests = len(tests)
        n_tests_passed.value = 0
        n_tests_failed.value = 0
        progress_prefix = prefix

        pool = multiprocessing.Pool(jobs)
        # The '.get(9999999)' is a workaround to allow killing the test script with
        # ctrl+C from the shell. This bug is documented at
        # http://bugs.python.org/issue8296.
        work = pool.map_async(RunTest, tests).get(9999999)
        pool.close()
        pool.join()

        printer.UpdateProgress(start_time,
                               n_tests_passed.value,
                               n_tests_failed.value,
                               n_tests,
                               '== Done ==',
                               prevent_next_overwrite=True,
                               prefix=progress_prefix)

    # `0` indicates success
    return n_tests_failed.value
Example #12
0
def ClangFormat(filename, in_place=False, progress_prefix=''):
    rc = 0
    printer.PrintOverwritableLine('Processing %s' % filename,
                                  type=printer.LINE_TYPE_LINTER)

    cmd_format = ['clang-format-3.6', filename]
    temp_file, temp_file_name = tempfile.mkstemp(prefix='clang_format_')
    cmd_format_string = '$ ' + ' '.join(cmd_format) + ' > %s' % temp_file_name
    p_format = subprocess.Popen(cmd_format,
                                stdout=temp_file,
                                stderr=subprocess.STDOUT)

    rc += p_format.wait()

    cmd_diff = ['diff', '--unified', filename, temp_file_name]
    cmd_diff_string = '$ ' + ' '.join(cmd_diff)
    p_diff = subprocess.Popen(cmd_diff,
                              stdout=subprocess.PIPE,
                              stderr=subprocess.STDOUT)

    if util.IsCommandAvailable('colordiff') and not is_output_redirected:
        p_colordiff = subprocess.Popen(['colordiff', '--unified'],
                                       stdin=p_diff.stdout,
                                       stdout=subprocess.PIPE,
                                       stderr=subprocess.STDOUT)
        out, unused = p_colordiff.communicate()
    else:
        out, unused = p_diff.communicate()

    rc += p_diff.wait()

    if in_place:
        cmd_format = ['clang-format-3.6', '-i', filename]
        p_format = subprocess.Popen(cmd_format,
                                    stdout=temp_file,
                                    stderr=subprocess.STDOUT)

    if rc != 0:
        printer.Print('Incorrectly formatted file: ' + filename + '\n' + \
                      cmd_format_string + '\n' + \
                      cmd_diff_string + '\n' + \
                      out)

    os.remove(temp_file_name)

    return 0 if rc == 0 else 1
Example #13
0
  def AddTests(self, test_runner_command, filters, runtime_options, under_valgrind):
    tests = GetTests(test_runner_command, filters)
    n_tests_total = len(tests)
    tests, skipped  = FilterKnownTestFailures(tests, under_valgrind = under_valgrind)
    for n_tests, reason in skipped:
      if n_tests > 0:
          self.AddKnownFailures(reason, n_tests)

    if len(tests) == 0:
      printer.Print('No tests to run.')
      return

    base_command = []
    if under_valgrind:
      base_command += ['valgrind']
    base_command += [test_runner_command]
    for test in tests:
      command = base_command + [test] + runtime_options
      self.AddTest(test, command = command)
Example #14
0
def PrintStatus(success):
    printer.Print('\n$ ' + ' '.join(sys.argv))
    if success:
        printer.Print('SUCCESS')
    else:
        printer.Print('FAILURE')
Example #15
0
def RunCommand(command, environment_options=None):
    # Create a copy of the environment. We do not want to pollute the environment
    # of future commands run.
    environment = os.environ
    # Configure the environment.
    # TODO: We currently pass the options as strings, so we need to parse them. We
    # should instead pass them as a data structure and build the string option
    # later. `environment_options` looks like `['CXX=compiler', 'OPT=val']`.
    if environment_options:
        for option in environment_options:
            opt, val = option.split('=')
            environment[opt] = val

    printable_command = ''
    if environment_options:
        printable_command += ' '.join(environment_options) + ' '
    printable_command += ' '.join(command)

    printable_command_orange = \
      printer.COLOUR_ORANGE + printable_command + printer.NO_COLOUR
    printer.PrintOverwritableLine(printable_command_orange)
    sys.stdout.flush()

    # Start a process for the command.
    # Interleave `stderr` and `stdout`.
    p = subprocess.Popen(command,
                         stdout=subprocess.PIPE,
                         stderr=subprocess.STDOUT,
                         env=environment)

    # We want to be able to display a continuously updated 'work indicator' while
    # the process is running. Since the process can hang if the `stdout` pipe is
    # full, we need to pull from it regularly. We cannot do so via the
    # `readline()` function because it is blocking, and would thus cause the
    # indicator to not be updated properly. So use file control mechanisms
    # instead.
    indicator = ' (still working: %d seconds elapsed)'

    # Mark the process output as non-blocking.
    flags = fcntl.fcntl(p.stdout, fcntl.F_GETFL)
    fcntl.fcntl(p.stdout, fcntl.F_SETFL, flags | os.O_NONBLOCK)

    t_start = time.time()
    t_last_indication = t_start
    process_output = ''

    # Keep looping as long as the process is running.
    while p.poll() is None:
        # Avoid polling too often.
        time.sleep(0.1)
        # Update the progress indicator.
        t_current = time.time()
        if (t_current - t_start >= 2) and (t_current - t_last_indication >= 1):
            printer.PrintOverwritableLine(printable_command_orange +
                                          indicator % int(t_current - t_start))
            sys.stdout.flush()
            t_last_indication = t_current
        # Pull from the process output.
        while True:
            try:
                line = os.read(p.stdout.fileno(), 1024)
            except OSError:
                line = ''
                break
            if line == '': break
            process_output += line

    # The process has exited. Don't forget to retrieve the rest of its output.
    out, err = p.communicate()
    rc = p.poll()
    process_output += out

    if rc == 0:
        printer.Print(printer.COLOUR_GREEN + printable_command +
                      printer.NO_COLOUR)
    else:
        printer.Print(printer.COLOUR_RED + printable_command +
                      printer.NO_COLOUR)
        printer.Print(process_output)
    return rc
Example #16
0
            # Avoid going through the build stage if we are not using the build
            # result.
            if not (args.notest and args.nobench):
                build_rc = BuildAll(build_options, args.jobs)
                # Don't run the tests for this configuration if the build failed.
                if build_rc != 0:
                    rc |= build_rc
                    continue

            # Use the realpath of the test executable so that the commands printed
            # can be copy-pasted and run.
            test_executable = os.path.realpath(
                join(config.dir_build_latest, 'test', 'test-runner'))

            if not args.notest:
                printer.Print(test_executable)

            for runtime_options in test_runtime_combinations:
                if not args.notest:
                    runtime_options = [
                        x for x in runtime_options if x is not None
                    ]
                    prefix = '  ' + ' '.join(runtime_options) + '  '
                    rc |= threaded_tests.RunTests(test_executable,
                                                  args.filters,
                                                  list(runtime_options),
                                                  args.under_valgrind,
                                                  jobs=args.jobs,
                                                  prefix=prefix)

            if not args.nobench:
Example #17
0
def RunTest(test):
    filename = test.args['filename']
    clang_format = test.args['clang_format']
    in_place = test.args['in_place']

    rc = 0

    cmd_format = [clang_format, filename]
    temp_file, temp_file_name = tempfile.mkstemp(prefix='clang_format_')
    cmd_format_string = '$ ' + ' '.join(cmd_format) + ' > %s' % temp_file_name
    p_format = subprocess.Popen(cmd_format,
                                stdout=temp_file,
                                stderr=subprocess.STDOUT)

    rc += p_format.wait()

    cmd_diff = ['diff', '--unified', filename, temp_file_name]
    cmd_diff_string = '$ ' + ' '.join(cmd_diff)
    p_diff = subprocess.Popen(cmd_diff,
                              stdout=subprocess.PIPE,
                              stderr=subprocess.STDOUT)

    if util.IsCommandAvailable('colordiff') and not is_output_redirected:
        p_colordiff = subprocess.Popen(['colordiff', '--unified'],
                                       stdin=p_diff.stdout,
                                       stdout=subprocess.PIPE,
                                       stderr=subprocess.STDOUT)
        out, unused = p_colordiff.communicate()
    else:
        out, unused = p_diff.communicate()

    rc += p_diff.wait()

    if in_place:
        cmd_format = [clang_format, '-i', filename]
        p_format = subprocess.Popen(cmd_format,
                                    stdout=temp_file,
                                    stderr=subprocess.STDOUT)

    if rc != 0:
        with Test.n_tests_failed.get_lock():
            Test.n_tests_failed.value += 1
    else:
        with Test.n_tests_passed.get_lock():
            Test.n_tests_passed.value += 1

    printer.__print_lock__.acquire()

    printer.UpdateProgress(test.shared.start_time,
                           Test.n_tests_passed.value,
                           Test.n_tests_failed.value,
                           test.shared.n_tests,
                           Test.n_tests_skipped.value,
                           test.shared.n_known_failures,
                           test.name,
                           prevent_next_overwrite=rc != 0,
                           has_lock=True,
                           prefix=test.shared.progress_prefix)

    if rc != 0:
        printer.Print('Incorrectly formatted file: ' + filename + '\n' + \
                      cmd_format_string + '\n' + \
                      cmd_diff_string + '\n' + \
                      out, has_lock = True)
    printer.__print_lock__.release()

    os.remove(temp_file_name)