#!/usr/bin/env python3.8

# Copyright 2019 The Fuchsia Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

#### CATEGORY=Other

import argparse
import json
import os
import subprocess
import sys
import textwrap

# Colors and helpers for terminal pretty-printing.
BOLD_BLACK = '\033[1;30m'
BOLD_RED = '\033[1;31m'
NO_COLOR = '\033[0m'
def info_print(s):
  print('\n%s%s%s' % (BOLD_BLACK, s, NO_COLOR))
def error_print(s):
  print('\n%s%s%s' % (BOLD_RED, s, NO_COLOR))

def main():
    parser = argparse.ArgumentParser(
        description=(textwrap.dedent('''\
            Executes a test in the GN graph.

            Note that the name of the test is just the name of a binary in the
            output folder.
            For example, if you have this binary:

                out/default/host_x64/my_test

            You just specify "my_test" as the test name.

            Also note that the binary need to be part of your GN build graph,
            even if you are not interested in delivering this binary as part of
            the image.  This means that, if your test is generated by the

                //system/src/my_package/my_test

            target, you might need to add this target to your GN build graph by
            adjusting your "fx set" arguments like this:

                fx set ... --with //system/src/my_package/my_test
        ''')),
        formatter_class=argparse.RawDescriptionHelpFormatter,
    )
    parser.add_argument('--manifest',
                        help='The path to the manifest of tests',
                        required=True)
    parser.add_argument('--names',
                        help='The names of the tests to execute',
                        nargs='*',
                        required=True)
    parser.add_argument('test_args',
                        help='Arguments to pass to the tests on execution',
                        nargs='*')
    parser.add_argument('--build-dir',
                        help='The path to the root build directory',
                        required=True)
    parser.add_argument('--ninja',
                        help='The path to the ninja binary',
                        required=True)
    args = parser.parse_args()

    if not args.names:
      error_print('no tests provided')
      return 1

    with open(args.manifest, 'r') as f:
      entries = json.load(f)

    tests = []
    unmatched = set(args.names)
    for entry in entries:
      test = entry['test']
      if test['os'] == 'fuchsia':
        continue
      # some tests have no "path" property
      if 'path' not in test:
        continue
      path = test['path']
      name = os.path.basename(path)
      if name not in args.names:
        continue
      tests.append(test)
      unmatched.remove(name)

    if unmatched:
      error_print(
          'could not find tests with the following names:\n' +
          '\n'.join(unmatched))
      return 1

    # test['path'] gives the path to the test relative build directory,
    # which is a valid ninja target.
    ret = subprocess.call(
        [args.ninja, '-C', args.build_dir] +
        [test['path'] for test in tests])
    if ret:
      error_print('failed to compile tests')
      return 1

    failed = []
    for test in tests:
      target = test['name']
      info_print('<< running %s >>' % target)
      if 'command' in test and len(test['command']) > 1:
        location, extra_args = test['command'][0], test['command'][1:]
      else:
        location, extra_args = test['path'], []
      ret = subprocess.call(
          [os.path.join(args.build_dir, location)] + extra_args + args.test_args)
      if ret != 0:
        failed.append(target)

    num_tests = len(tests)
    if not num_tests:
      error_print('no tests found with names %s' % ', '.join(args.names))
      return 1

    if failed:
      error_print(
          '%d of %d test%s failed:' % (
              len(failed), num_tests, 's' if num_tests > 1 else ''
          ) +
          '\n'.join(failed))
      return 1
    else:
      info_print('%d of %d test%s passed' % (
          num_tests, num_tests, 's' if num_tests > 1 else ''))

if __name__ == '__main__':
    sys.exit(main())
