Home | History | Annotate | Download | only in build
      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
      7 hashes, stores final list in JSON document and then removes *.isolated files
      8 found (to ensure no stale *.isolated stay around on the next build).
      9 
     10 Used to figure out what tests were build in isolated mode to trigger these
     11 tests to run on swarming.
     12 
     13 For more info see:
     14 https://sites.google.com/a/chromium.org/dev/developers/testing/isolated-testing
     15 """
     16 
     17 import glob
     18 import hashlib
     19 import json
     20 import optparse
     21 import os
     22 import re
     23 import sys
     24 
     25 
     26 def hash_file(filepath):
     27   """Calculates the hash of a file without reading it all in memory at once."""
     28   digest = hashlib.sha1()
     29   with open(filepath, 'rb') as f:
     30     while True:
     31       chunk = f.read(1024*1024)
     32       if not chunk:
     33         break
     34       digest.update(chunk)
     35   return digest.hexdigest()
     36 
     37 
     38 def main():
     39   parser = optparse.OptionParser(
     40       usage='%prog --build-dir <path> --output-json <path>',
     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 
     49   options, _ = parser.parse_args()
     50   if not options.build_dir:
     51     parser.error('--build-dir option is required')
     52   if not options.output_json:
     53     parser.error('--output-json option is required')
     54 
     55   result = {}
     56 
     57   # Get the file hash values and output the pair.
     58   pattern = os.path.join(options.build_dir, '*.isolated')
     59   for filepath in sorted(glob.glob(pattern)):
     60     test_name = os.path.splitext(os.path.basename(filepath))[0]
     61     if re.match(r'^.+?\.\d$', test_name):
     62       # It's a split .isolated file, e.g. foo.0.isolated. Ignore these.
     63       continue
     64 
     65     # TODO(csharp): Remove deletion once the isolate tracked dependencies are
     66     # inputs for the isolated files.
     67     sha1_hash = hash_file(filepath)
     68     os.remove(filepath)
     69     result[test_name] = sha1_hash
     70 
     71   with open(options.output_json, 'wb') as f:
     72     json.dump(result, f)
     73 
     74   return 0
     75 
     76 
     77 if __name__ == '__main__':
     78   sys.exit(main())
     79