1#!/usr/bin/env python 2# 3# Copyright 2016 Google Inc. 4# 5# Use of this source code is governed by a BSD-style license that can be 6# found in the LICENSE file. 7 8 9import default_flavor 10import os 11import subprocess 12import time 13 14 15"""Utils for running coverage tests.""" 16 17 18class CoverageFlavorUtils(default_flavor.DefaultFlavorUtils): 19 def compile(self, target): 20 """Build the given target.""" 21 cmd = [os.path.join(self._bot_info.skia_dir, 'tools', 22 'llvm_coverage_build'), 23 target] 24 self._bot_info.run(cmd) 25 26 def step(self, cmd, **kwargs): 27 """Run the given step through coverage.""" 28 # Slice out the 'key' and 'properties' arguments to be reused. 29 key = [] 30 properties = [] 31 current = None 32 for i in xrange(0, len(cmd)): 33 if isinstance(cmd[i], basestring) and cmd[i] == '--key': 34 current = key 35 elif isinstance(cmd[i], basestring) and cmd[i] == '--properties': 36 current = properties 37 elif isinstance(cmd[i], basestring) and cmd[i].startswith('--'): 38 current = None 39 if current is not None: 40 current.append(cmd[i]) 41 42 results_dir = self._bot_info.out_dir.join('coverage_results') 43 self.create_clean_host_dir(results_dir) 44 45 # Run DM under coverage. 46 report_file_basename = '%s.cov' % self._bot_info.got_revision 47 report_file = os.path.join(results_dir, report_file_basename) 48 args = [ 49 'python', 50 os.path.join(self._bot_info.skia_dir, 'tools', 'llvm_coverage_run.py'), 51 ] + cmd + ['--outResultsFile', report_file] 52 self._bot_info.run(args, **kwargs) 53 54 # Generate nanobench-style JSON output from the coverage report. 55 git_timestamp = subprocess.check_output(['git', 'log', '-n1', 56 self._bot_info.got_revision, '--format=%%ci']).rstrip() 57 nanobench_json = results_dir.join('nanobench_%s_%s.json' % ( 58 self._bot_info.got_revision, git_timestamp)) 59 line_by_line_basename = ('coverage_by_line_%s_%s.json' % ( 60 self._bot_info.got_revision, git_timestamp)) 61 line_by_line = results_dir.join(line_by_line_basename) 62 args = [ 63 'python', 64 os.path.join(self._bot_info.skia_dir, 'tools', 65 'parse_llvm_coverage.py'), 66 '--report', report_file, '--nanobench', nanobench_json, 67 '--linebyline', line_by_line] 68 args.extend(key) 69 args.extend(properties) 70 self._bot_info.run(args) 71 72 # Upload raw coverage data. 73 now = time.utcnow() 74 gs_json_path = '/'.join(( 75 str(now.year).zfill(4), str(now.month).zfill(2), 76 str(now.day).zfill(2), str(now.hour).zfill(2), 77 self._bot_info.name, 78 str(self._bot_info.build_number))) 79 if self._bot_info.is_trybot: 80 gs_json_path = '/'.join(('trybot', gs_json_path, 81 str(self._bot_info.issue))) 82 83 self._bot_info.gsutil_upload( 84 'upload raw coverage data', 85 source=report_file, 86 bucket='skia-infra', 87 dest='/'.join(('coverage-raw-v1', gs_json_path, report_file_basename))) 88 89 # Upload nanobench JSON data. 90 gsutil_path = self._bot_info.m.path['depot_tools'].join( 91 'third_party', 'gsutil', 'gsutil') 92 upload_args = [self._bot_info.name, 93 self._bot_info.m.properties['buildnumber'], 94 results_dir, 95 self._bot_info.got_revision, gsutil_path] 96 if self._bot_info.is_trybot: 97 upload_args.append(self._bot_info.m.properties['issue']) 98 self._bot_info.run( 99 self._bot_info.m.python, 100 'upload nanobench coverage results', 101 script=self._bot_info.resource('upload_bench_results.py'), 102 args=upload_args, 103 cwd=self._bot_info.m.path['checkout'], 104 abort_on_failure=False, 105 infra_step=True) 106 107 # Upload line-by-line coverage data. 108 self._bot_info.gsutil_upload( 109 'upload line-by-line coverage data', 110 source=line_by_line, 111 bucket='skia-infra', 112 dest='/'.join(('coverage-json-v1', gs_json_path, 113 line_by_line_basename))) 114 115