#!/usr/bin/env python2
# Copyright 2013 Google Inc. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import cPickle
import errno
import gzip
import multiprocessing
import optparse
import os
import signal
import subprocess
import sys
import tempfile
import thread
import threading
import time
import zlib

# An object that catches SIGINT sent to the Python process and notices
# if processes passed to wait() die by SIGINT (we need to look for
# both of those cases, because pressing Ctrl+C can result in either
# the main process or one of the subprocesses getting the signal).
#
# Before a SIGINT is seen, wait(p) will simply call p.wait() and
# return the result. Once a SIGINT has been seen (in the main process
# or a subprocess, including the one the current call is waiting for),
# wait(p) will call p.terminate() and raise ProcessWasInterrupted.
class SigintHandler(object):
  class ProcessWasInterrupted(Exception): pass
  sigint_returncodes = {-signal.SIGINT,  # Unix
                        -1073741510,     # Windows
                        }
  def __init__(self):
    self.__lock = threading.Lock()
    self.__processes = set()
    self.__got_sigint = False
    signal.signal(signal.SIGINT, self.__sigint_handler)
  def __on_sigint(self):
    self.__got_sigint = True
    while self.__processes:
      try:
        self.__processes.pop().terminate()
      except OSError:
        pass
  def __sigint_handler(self, signal_num, frame):
    with self.__lock:
      self.__on_sigint()
  def got_sigint(self):
    with self.__lock:
      return self.__got_sigint
  def wait(self, p):
    with self.__lock:
      if self.__got_sigint:
        p.terminate()
      self.__processes.add(p)
    code = p.wait()
    with self.__lock:
      self.__processes.discard(p)
      if code in self.sigint_returncodes:
        self.__on_sigint()
      if self.__got_sigint:
        raise self.ProcessWasInterrupted
    return code
sigint_handler = SigintHandler()

# Return the width of the terminal, or None if it couldn't be
# determined (e.g. because we're not being run interactively).
def term_width(out):
  if not out.isatty():
    return None
  try:
    p = subprocess.Popen(["stty", "size"],
                         stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    (out, err) = p.communicate()
    if p.returncode != 0 or err:
      return None
    return int(out.split()[1])
  except (IndexError, OSError, ValueError):
    return None

# Output transient and permanent lines of text. If several transient
# lines are written in sequence, the new will overwrite the old. We
# use this to ensure that lots of unimportant info (tests passing)
# won't drown out important info (tests failing).
class Outputter(object):
  def __init__(self, out_file):
    self.__out_file = out_file
    self.__previous_line_was_transient = False
    self.__width = term_width(out_file)  # Line width, or None if not a tty.
  def transient_line(self, msg):
    if self.__width is None:
      self.__out_file.write(msg + "\n")
    else:
      self.__out_file.write("\r" + msg[:self.__width].ljust(self.__width))
      self.__previous_line_was_transient = True
  def flush_transient_output(self):
    if self.__previous_line_was_transient:
      self.__out_file.write("\n")
      self.__previous_line_was_transient = False
  def permanent_line(self, msg):
    self.flush_transient_output()
    self.__out_file.write(msg + "\n")

stdout_lock = threading.Lock()

class FilterFormat:
  if sys.stdout.isatty():
    # stdout needs to be unbuffered since the output is interactive.
    sys.stdout = os.fdopen(sys.stdout.fileno(), 'w', 0)

  out = Outputter(sys.stdout)
  total_tests = 0
  finished_tests = 0

  tests = {}
  outputs = {}
  failures = []

  def print_test_status(self, last_finished_test, time_ms):
    self.out.transient_line("[%d/%d] %s (%d ms)"
                            % (self.finished_tests, self.total_tests,
                               last_finished_test, time_ms))

  def handle_meta(self, job_id, args):
    (command, arg) = args.split(' ', 1)
    if command == "TEST":
      (binary, test) = arg.split(' ', 1)
      self.tests[job_id] = (binary, test.strip())
    elif command == "EXIT":
      (exit_code, time_ms) = [int(x) for x in arg.split(' ', 1)]
      self.finished_tests += 1
      (binary, test) = self.tests[job_id]
      self.print_test_status(test, time_ms)
      if exit_code != 0:
        self.failures.append(self.tests[job_id])
        with open(self.outputs[job_id]) as f:
          for line in f.readlines():
            self.out.permanent_line(line.rstrip())
        self.out.permanent_line(
          "[%d/%d] %s returned/aborted with exit code %d (%d ms)"
          % (self.finished_tests, self.total_tests, test, exit_code, time_ms))
    elif command == "TESTCNT":
      self.total_tests = int(arg.split(' ', 1)[1])
      self.out.transient_line("[0/%d] Running tests..." % self.total_tests)

  def logfile(self, job_id, name):
    self.outputs[job_id] = name

  def log(self, line):
    stdout_lock.acquire()
    (prefix, output) = line.split(' ', 1)

    assert prefix[-1] == ':'
    self.handle_meta(int(prefix[:-1]), output)
    stdout_lock.release()

  def end(self):
    if self.failures:
      self.out.permanent_line("FAILED TESTS (%d/%d):"
                              % (len(self.failures), self.total_tests))
      for (binary, test) in self.failures:
        self.out.permanent_line(" " + binary + ": " + test)
    self.out.flush_transient_output()

class RawFormat:
  def log(self, line):
    stdout_lock.acquire()
    sys.stdout.write(line + "\n")
    sys.stdout.flush()
    stdout_lock.release()
  def logfile(self, job_id, name):
    with open(name) as f:
      for line in f.readlines():
        self.log(str(job_id) + '> ' + line.rstrip())
  def end(self):
    pass

# Record of test runtimes. Has built-in locking.
class TestTimes(object):
  def __init__(self, save_file):
    "Create new object seeded with saved test times from the given file."
    self.__times = {}  # (test binary, test name) -> runtime in ms

    # Protects calls to record_test_time(); other calls are not
    # expected to be made concurrently.
    self.__lock = threading.Lock()

    try:
      with gzip.GzipFile(save_file, "rb") as f:
        times = cPickle.load(f)
    except (EOFError, IOError, cPickle.UnpicklingError, zlib.error):
      # File doesn't exist, isn't readable, is malformed---whatever.
      # Just ignore it.
      return

    # Discard saved times if the format isn't right.
    if type(times) is not dict:
      return
    for ((test_binary, test_name), runtime) in times.items():
      if (type(test_binary) is not str or type(test_name) is not str
          or type(runtime) not in {int, long, type(None)}):
        return

    self.__times = times

  def get_test_time(self, binary, testname):
    """Return the last duration for the given test as an integer number of
    milliseconds, or None if the test failed or if there's no record for it."""
    return self.__times.get((binary, testname), None)

  def record_test_time(self, binary, testname, runtime_ms):
    """Record that the given test ran in the specified number of
    milliseconds. If the test failed, runtime_ms should be None."""
    with self.__lock:
      self.__times[(binary, testname)] = runtime_ms

  def write_to_file(self, save_file):
    "Write all the times to file."
    try:
      with open(save_file, "wb") as f:
        with gzip.GzipFile("", "wb", 9, f) as gzf:
          cPickle.dump(self.__times, gzf, cPickle.HIGHEST_PROTOCOL)
    except IOError:
      pass  # ignore errors---saving the times isn't that important

# Remove additional arguments (anything after --).
additional_args = []

for i in range(len(sys.argv)):
  if sys.argv[i] == '--':
    additional_args = sys.argv[i+1:]
    sys.argv = sys.argv[:i]
    break

parser = optparse.OptionParser(
    usage = 'usage: %prog [options] binary [binary ...] -- [additional args]')

parser.add_option('-d', '--output_dir', type='string',
                  default=os.path.join(tempfile.gettempdir(), "gtest-parallel"),
                  help='output directory for test logs')
parser.add_option('-r', '--repeat', type='int', default=1,
                  help='repeat tests')
parser.add_option('--failed', action='store_true', default=False,
                  help='run only failed and new tests')
parser.add_option('-w', '--workers', type='int',
                  default=multiprocessing.cpu_count(),
                  help='number of workers to spawn')
parser.add_option('--gtest_color', type='string', default='yes',
                  help='color output')
parser.add_option('--gtest_filter', type='string', default='',
                  help='test filter')
parser.add_option('--gtest_also_run_disabled_tests', action='store_true',
                  default=False, help='run disabled tests too')
parser.add_option('--format', type='string', default='filter',
                  help='output format (raw,filter)')
parser.add_option('--print_test_times', action='store_true', default=False,
                  help='When done, list the run time of each test')

(options, binaries) = parser.parse_args()

if binaries == []:
  parser.print_usage()
  sys.exit(1)

logger = RawFormat()
if options.format == 'raw':
  pass
elif options.format == 'filter':
  logger = FilterFormat()
else:
  sys.exit("Unknown output format: " + options.format)

# Find tests.
save_file = os.path.join(os.path.expanduser("~"), ".gtest-parallel-times")
times = TestTimes(save_file)
tests = []
for test_binary in binaries:
  command = [test_binary]
  if options.gtest_also_run_disabled_tests:
    command += ['--gtest_also_run_disabled_tests']

  list_command = list(command)
  if options.gtest_filter != '':
    list_command += ['--gtest_filter=' + options.gtest_filter]

  try:
    test_list = subprocess.Popen(list_command + ['--gtest_list_tests'],
                                 stdout=subprocess.PIPE).communicate()[0]
  except OSError as e:
    sys.exit("%s: %s" % (test_binary, str(e)))

  command += additional_args

  test_group = ''
  for line in test_list.split('\n'):
    if not line.strip():
      continue
    if line[0] != " ":
      # Remove comments for typed tests and strip whitespace.
      test_group = line.split('#')[0].strip()
      continue
    # Remove comments for parameterized tests and strip whitespace.
    line = line.split('#')[0].strip()
    if not line:
      continue

    test = test_group + line
    if not options.gtest_also_run_disabled_tests and 'DISABLED_' in test:
      continue
    tests.append((times.get_test_time(test_binary, test),
                  test_binary, test, command))

if options.failed:
  # The first element of each entry is the runtime of the most recent
  # run if it was successful, or None if the test is new or the most
  # recent run failed.
  tests = [x for x in tests if x[0] is None]

# Sort tests by falling runtime (with None, which is what we get for
# new and failing tests, being considered larger than any real
# runtime).
tests.sort(reverse=True, key=lambda x: ((1 if x[0] is None else 0), x))

# Repeat tests (-r flag).
tests *= options.repeat
test_lock = threading.Lock()
job_id = 0
logger.log(str(-1) + ': TESTCNT ' + ' ' + str(len(tests)))

exit_code = 0

# Create directory for test log output.
try:
  os.makedirs(options.output_dir)
except OSError as e:
  # Ignore errors if this directory already exists.
  if e.errno != errno.EEXIST or not os.path.isdir(options.output_dir):
    raise e
# Remove files from old test runs.
for logfile in os.listdir(options.output_dir):
  os.remove(os.path.join(options.output_dir, logfile))

# Run the specified job. Return the elapsed time in milliseconds if
# the job succeeds, or None if the job fails. (This ensures that
# failing tests will run first the next time.)
def run_job((command, job_id, test)):
  begin = time.time()

  with tempfile.NamedTemporaryFile(dir=options.output_dir, delete=False) as log:
    sub = subprocess.Popen(command + ['--gtest_filter=' + test] +
                             ['--gtest_color=' + options.gtest_color],
                           stdout=log.file,
                           stderr=log.file)
    try:
      code = sigint_handler.wait(sub)
    except sigint_handler.ProcessWasInterrupted:
      thread.exit()
    runtime_ms = int(1000 * (time.time() - begin))
    logger.logfile(job_id, log.name)

  logger.log("%s: EXIT %s %d" % (job_id, code, runtime_ms))
  if code == 0:
    return runtime_ms
  global exit_code
  exit_code = code
  return None

def worker():
  global job_id
  while True:
    job = None
    test_lock.acquire()
    if job_id < len(tests):
      (_, test_binary, test, command) = tests[job_id]
      logger.log(str(job_id) + ': TEST ' + test_binary + ' ' + test)
      job = (command, job_id, test)
    job_id += 1
    test_lock.release()
    if job is None:
      return
    times.record_test_time(test_binary, test, run_job(job))

def start_daemon(func):
  t = threading.Thread(target=func)
  t.daemon = True
  t.start()
  return t

workers = [start_daemon(worker) for i in range(options.workers)]

[t.join() for t in workers]
logger.end()
times.write_to_file(save_file)
if options.print_test_times:
  ts = sorted((times.get_test_time(test_binary, test), test_binary, test)
              for (_, test_binary, test, _) in tests
              if times.get_test_time(test_binary, test) is not None)
  for (time_ms, test_binary, test) in ts:
    print "%8s %s" % ("%dms" % time_ms, test)
sys.exit(-signal.SIGINT if sigint_handler.got_sigint() else exit_code)
