1#!/usr/bin/env python
2# Copyright (c) 2012 The Chromium Authors. All rights reserved.
3# Use of this source code is governed by a BSD-style license that can be
4# found in the LICENSE file.
5
6"""Launch a local server on an ephemeral port, then launch a executable that
7points to that server.
8"""
9
10import copy
11import getos
12import optparse
13import os
14import subprocess
15import sys
16import httpd
17
18
19if sys.version_info < (2, 6, 0):
20  sys.stderr.write("python 2.6 or later is required run this script\n")
21  sys.exit(1)
22
23
24def main(args):
25  usage = """usage: %prog [options] -- executable args...
26
27  This command creates a local server on an ephemeral port, then runs:
28    <executable> <args..> http://localhost:<port>/<page>.
29
30  Where <page> can be set by -P, or uses index.html by default."""
31  parser = optparse.OptionParser(usage)
32  parser.add_option('-C', '--serve-dir',
33      help='Serve files out of this directory.',
34      dest='serve_dir', default=os.path.abspath('.'))
35  parser.add_option('-P', '--path', help='Path to load from local server.',
36      dest='path', default='index.html')
37  parser.add_option('-D',
38      help='Add debug command-line when launching the chrome debug.',
39      dest='debug', action='append', default=[])
40  parser.add_option('-E',
41      help='Add environment variables when launching the executable.',
42      dest='environ', action='append', default=[])
43  parser.add_option('--test-mode',
44      help='Listen for posts to /ok or /fail and shut down the server with '
45          ' errorcodes 0 and 1 respectively.',
46      dest='test_mode', action='store_true')
47  parser.add_option('-p', '--port',
48      help='Port to run server on. Default is 5103, ephemeral is 0.',
49      default=5103)
50  options, args = parser.parse_args(args)
51  if not args:
52    parser.error('No executable given.')
53
54  # 0 means use an ephemeral port.
55  server = httpd.LocalHTTPServer(options.serve_dir, options.port,
56                                 options.test_mode)
57  print 'Serving %s on %s...' % (options.serve_dir, server.GetURL(''))
58
59  env = copy.copy(os.environ)
60  for e in options.environ:
61    key, value = map(str.strip, e.split('='))
62    env[key] = value
63
64  cmd = args + [server.GetURL(options.path)]
65  print 'Running: %s...' % (' '.join(cmd),)
66  process = subprocess.Popen(cmd, env=env)
67
68  # If any debug args are passed in, assume we want to debug
69  if options.debug:
70    if getos.GetPlatform() != 'win':
71      cmd = ['xterm', '-title', 'NaCl Debugger', '-e']
72    else:
73      cmd = []
74    cmd += options.debug
75    print 'Starting debugger: ' + ' '.join(cmd)
76    debug_process = subprocess.Popen(cmd, env=env)
77  else:
78    debug_process = False
79
80  try:
81    return server.ServeUntilSubprocessDies(process)
82  finally:
83    if process.returncode is None:
84      process.kill()
85    if debug_process and debug_process.returncode is None:
86      debug_process.kill()
87
88if __name__ == '__main__':
89  sys.exit(main(sys.argv[1:]))
90