• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/usr/bin/env python
2# Copyright 2014 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"""Scans build output directory for .isolated files, calculates their SHA1
7hashes and stores final list in JSON document.
8
9Used to figure out what tests were build in isolated mode to trigger these
10tests to run on swarming.
11
12For more info see:
13https://sites.google.com/a/chromium.org/dev/developers/testing/isolated-testing
14"""
15
16import glob
17import hashlib
18import json
19import optparse
20import os
21import re
22import sys
23
24
25def hash_file(filepath):
26  """Calculates the hash of a file without reading it all in memory at once."""
27  digest = hashlib.sha1()
28  with open(filepath, 'rb') as f:
29    while True:
30      chunk = f.read(1024*1024)
31      if not chunk:
32        break
33      digest.update(chunk)
34  return digest.hexdigest()
35
36
37def main():
38  parser = optparse.OptionParser(
39      usage='%prog --build-dir <path> '
40          '[--output-json <path> | --clean-isolated-files]',
41      description=sys.modules[__name__].__doc__)
42  parser.add_option(
43      '--build-dir',
44      help='Path to a directory to search for *.isolated files.')
45  parser.add_option(
46      '--output-json',
47      help='File to dump JSON results into. '
48          'Mutually exclusive with --clean-isolated-files.')
49  parser.add_option(
50      '--clean-isolated-files',
51      action='store_true',
52      help='Whether to clean out all .isolated and .isolated.gen.json files. '
53          'Mutually exclusive with --output-json.')
54
55  options, _ = parser.parse_args()
56  if not options.build_dir:
57    parser.error('--build-dir option is required')
58  if not (options.output_json or options.clean_isolated_files):
59    parser.error('either --output-json or --clean-isolated-files is required')
60  if options.output_json and options.clean_isolated_files:
61    parser.error('only one of --output-json and '
62                 '--clean-isolated-files is allowed')
63
64  result = {}
65
66  # Clean up generated *.isolated.gen.json files, produced by isolate_driver.py
67  # in test_isolation_mode='prepare'.
68  if options.clean_isolated_files:
69    pattern = os.path.join(options.build_dir, '*.isolated.gen.json')
70    for filepath in sorted(glob.glob(pattern)):
71      os.remove(filepath)
72
73  # Get the file hash values and output the pair.
74  pattern = os.path.join(options.build_dir, '*.isolated')
75  for filepath in sorted(glob.glob(pattern)):
76    test_name = os.path.splitext(os.path.basename(filepath))[0]
77    if re.match(r'^.+?\.\d$', test_name):
78      # It's a split .isolated file, e.g. foo.0.isolated. Ignore these.
79      continue
80
81    if options.clean_isolated_files:
82      # TODO(csharp): Remove deletion entirely once the isolate
83      # tracked dependencies are inputs for the isolated files.
84      # http://crbug.com/419031
85      os.remove(filepath)
86    else:
87      sha1_hash = hash_file(filepath)
88      result[test_name] = sha1_hash
89
90  if options.output_json:
91    with open(options.output_json, 'wb') as f:
92      json.dump(result, f)
93
94  return 0
95
96
97if __name__ == '__main__':
98  sys.exit(main())
99