#!/usr/bin/python
# Copyright 2018 the V8 project authors. All rights reserved.
'''
C S u i t e                                         because who can remember?
-----------------------------------------------------------------------------
python csuite.py [options] <benchmark> <mode> <d8 path>

Arguments
  benchmark: one of octane, sunspider or kraken.
  mode: baseline or compare.
  d8 path: a valid path to the d8 executable you want to use.

CSuite is a wrapper around benchmark.py and compare-baseline.py, old
friends in the d8 benchmarking world. Unlike those tools, it can be
run in any directory. It's also opinionated about which benchmarks it
will run, currently SunSpider, Octane and Kraken. Furthermore, it
runs the versions we pull into ./test/benchmarks/data.

Examples:

Say you want to see how much optimization buys you:
  ./csuite.py kraken baseline ~/src/v8/out/d8 -x="--noopt"
  ./csuite.py kraken compare ~/src/v8/out/d8

Suppose you are comparing two binaries, quick n' dirty style:
  ./csuite.py -r 3 octane baseline ~/src/v8/out-master/d8
  ./csuite.py -r 3 octane compare ~/src/v8/out-mine/d8

You can run from any place:
  ../../somewhere-strange/csuite.py sunspider baseline ./d8
  ../../somewhere-strange/csuite.py sunspider compare ./d8-better
'''

# for py2/py3 compatibility
from __future__ import print_function

import os
from optparse import OptionParser
import subprocess
import sys

if __name__ == '__main__':
  parser = OptionParser(usage=__doc__)
  parser.add_option("-r", "--runs", dest="runs",
      help="Override the default number of runs for the benchmark.")
  parser.add_option("-x", "--extra-arguments", dest="extra_args",
      help="Pass these extra arguments to d8.")
  parser.add_option("-v", "--verbose", action="store_true", dest="verbose",
      help="See more output about what magic csuite is doing.")
  (opts, args) = parser.parse_args()

  if len(args) < 3:
    print('not enough arguments')
    sys.exit(1)

  suite = args[0]
  mode = args[1]

  if suite not in ['octane', 'sunspider', 'kraken']:
    print('Suite must be octane, sunspider or kraken. Aborting.')
    sys.exit(1)

  if mode != 'baseline' and mode != 'compare':
    print('mode must be baseline or compare. Aborting.')
    sys.exit(1)

  # Set up paths.
  d8_path = os.path.abspath(args[2])
  if not os.path.exists(d8_path):
    print(d8_path + " is not valid.")
    sys.exit(1)

  csuite_path = os.path.dirname(os.path.abspath(__file__))
  if not os.path.exists(csuite_path):
    print("The csuite directory is invalid.")
    sys.exit(1)

  benchmark_py_path = os.path.join(csuite_path, "benchmark.py")
  if not os.path.exists(benchmark_py_path):
    print("Unable to find benchmark.py in " + csuite_path \
        + ". Aborting.")
    sys.exit(1)

  compare_baseline_py_path = os.path.join(csuite_path,
      "compare-baseline.py")

  if not os.path.exists(compare_baseline_py_path):
    print("Unable to find compare-baseline.py in " + csuite_path \
        + ". Aborting.")
    sys.exit(1)

  benchmark_path = os.path.abspath(os.path.join(csuite_path, "../data"))
  if not os.path.exists(benchmark_path):
    print("I can't find the benchmark data directory. Aborting.")
    sys.exit(1)

  # Gather the remaining arguments into a string of extra args for d8.
  extra_args = ""
  if opts.extra_args:
    extra_args = opts.extra_args

  if suite == "octane":
    runs = 10
    suite_path = os.path.join(benchmark_path, "octane")
    cmd = "run.js"
  elif suite == "kraken":
    runs = 80
    suite_path = os.path.join(benchmark_path, "kraken")
    cmd = os.path.join(csuite_path, "run-kraken.js")
  else:
    runs = 100
    suite_path = os.path.join(benchmark_path, "sunspider")
    cmd = os.path.join(csuite_path, "sunspider-standalone-driver.js")

  if opts.runs:
    if (float(opts.runs) / runs) < 0.6:
      print("Normally, %s requires %d runs to get stable results." \
          % (suite, runs))
    runs = int(opts.runs)

  if opts.verbose:
    print("Running and averaging %s %d times." % (suite, runs))

  # Ensure output directory is setup
  output_path_base = os.path.abspath(os.getcwd())
  output_path = os.path.join(output_path_base, "_results")
  output_file = os.path.join(output_path, "master")
  if not os.path.exists(output_path):
    if opts.verbose:
      print("Creating directory %s." % output_path)
    os.mkdir(output_path)

  if opts.verbose:
    print("Working directory for runs is %s." % suite_path)

  inner_command = " -c \"%s --expose-gc %s %s \"" \
      % (d8_path, extra_args, cmd)
  if opts.verbose:
    print("calling d8 like so: %s." % inner_command)

  cmdline_base = "python %s %s -fv -r %d -d %s" \
      % (benchmark_py_path, inner_command, runs, output_path_base)

  if mode == "baseline":
    cmdline = "%s > %s" % (cmdline_base, output_file)
  else:
    cmdline = "%s | %s %s" \
        % (cmdline_base, compare_baseline_py_path, output_file)

  if opts.verbose:
    print("Spawning subprocess: %s." % cmdline)
  return_code = subprocess.call(cmdline, shell=True, cwd=suite_path)
  if return_code < 0:
    print("Error return code: %d." % return_code)
  if mode == "baseline":
    print("Wrote %s." % output_file)
    print("Run %s again with compare mode to see results." % suite)
