summaryrefslogtreecommitdiffstats
path: root/tools/parallel_launcher/parallel_launcher.py
blob: a29e05be0304e7a94cdfda631d199b2caff08d60 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
#!/usr/bin/python
# Copyright (c) 2010 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""
This tool launches several shards of a gtest-based binary
in parallel on a local machine.

Example usage:

parallel_launcher.py path/to/base_unittests
"""

import optparse
import os
import subprocess
import sys
import tempfile

class TestLauncher(object):
  def __init__(self, args, executable, num_shards, shard):
    self._args = args
    self._executable = executable
    self._num_shards = num_shards
    self._shard = shard
    self._test = None
    self._tempfile = tempfile.TemporaryFile()

  def launch(self):
    env = os.environ.copy()
    env['GTEST_TOTAL_SHARDS'] = str(self._num_shards)
    env['GTEST_SHARD_INDEX'] = str(self._shard)
    self._test = subprocess.Popen(args=self._args,
                                  executable=self._executable,
                                  stdout=self._tempfile,
                                  stderr=subprocess.STDOUT,
                                  env=env)

  def wait(self):
    code = self._test.wait()
    self._tempfile.seek(0)
    print self._tempfile.read()
    self._tempfile.close()
    return code

def main(argv):
  parser = optparse.OptionParser()
  parser.add_option("--shards", type="int", dest="shards", default=10)

  options, args = parser.parse_args(argv)

  if len(args) != 1:
    print 'You must provide only one argument: path to the test binary'
    return 1

  launchers = []

  for shard in range(options.shards):
    launcher = TestLauncher(args[0], args[0], options.shards, shard)
    launcher.launch()
    launchers.append(launcher)

  return_code = 0
  for launcher in launchers:
    if launcher.wait() != 0:
      return_code = 1

  return return_code

if __name__ == "__main__":
  sys.exit(main(sys.argv[1:]))