1#!/usr/bin/env python
2# Copyright 2015 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
6import argparse
7import os
8import subprocess
9import sys
10
11script_dir = os.path.dirname(os.path.realpath(__file__))
12tool_dir = os.path.abspath(os.path.join(script_dir, '../../pylib'))
13sys.path.insert(0, tool_dir)
14
15from clang import plugin_testing
16
17
18class BlinkGcPluginTest(plugin_testing.ClangPluginTest):
19  """Test harness for the Blink GC plugin."""
20
21  def __init__(self, use_cppgc, *args, **kwargs):
22    super(BlinkGcPluginTest, self).__init__(*args, **kwargs)
23    self.use_cppgc = use_cppgc
24
25  def AdjustClangArguments(self, clang_cmd):
26    clang_cmd.append('-Wno-inaccessible-base')
27    if self.use_cppgc:
28      clang_cmd.append('-DUSE_V8_OILPAN')
29
30  def ProcessOneResult(self, test_name, actual):
31    # Some Blink GC plugins dump a JSON representation of the object graph, and
32    # use the processed results as the actual results of the test.
33    if os.path.exists('%s.graph.json' % test_name):
34      try:
35        actual = subprocess.check_output([
36            'python', '../process-graph.py', '-c',
37            '%s.graph.json' % test_name
38        ],
39                                         stderr=subprocess.STDOUT,
40                                         universal_newlines=True)
41      except subprocess.CalledProcessError as e:
42        # The graph processing script returns a failure exit code if the graph
43        # is bad (e.g. it has a cycle). The output still needs to be captured in
44        # that case, since the expected results capture the errors.
45        actual = e.output
46      finally:
47        # Clean up the .graph.json file to prevent false passes from stale
48        # results from a previous run.
49        os.remove('%s.graph.json' % test_name)
50    if self.use_cppgc:
51      if os.path.exists('%s.cppgc.txt' % test_name):
52        # Some tests include namespace names in the output and thus require a
53        # different output file for comparison.
54        test_name = '%s.cppgc' % test_name
55    return super(BlinkGcPluginTest, self).ProcessOneResult(test_name, actual)
56
57
58def main():
59  parser = argparse.ArgumentParser()
60  parser.add_argument(
61      '--reset-results',
62      action='store_true',
63      help='If specified, overwrites the expected results in place.')
64  parser.add_argument('clang_path', help='The path to the clang binary.')
65  args = parser.parse_args()
66
67  dir_name = os.path.dirname(os.path.realpath(__file__))
68
69  num_faliures_blink = BlinkGcPluginTest(
70      False,  # USE_V8_OILPAN
71      dir_name,
72      args.clang_path,
73      'blink-gc-plugin',
74      args.reset_results).Run()
75
76  num_faliures_cppgc = BlinkGcPluginTest(
77      True,  # USE_V8_OILPAN
78      dir_name,
79      args.clang_path,
80      'blink-gc-plugin',
81      args.reset_results).Run()
82
83  print "\nBlink GC Plugin Summary: %d tests failed without USE_V8_OILPAN, " \
84   "%d tests failed with USE_V8_OILPAN" % (
85      num_faliures_blink, num_faliures_cppgc)
86  return num_faliures_blink + num_faliures_cppgc
87
88
89if __name__ == '__main__':
90  sys.exit(main())
91