• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/usr/bin/env/python
2# Copyright 2020 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"""Merges .profraw files generated by unit tests into .profdata files
6to be processed by the chromium code_coverage module.
7
8This script based on the following chromium script. It performs the
9same merging steps, but code related to json parsing has been removed,
10as openscreen does not generate these json files as chromium does:
11https://source.chromium.org/chromium/chromium/src/+/master:testing/merge_scripts/code_coverage/merge_steps.py
12"""
13
14import argparse
15import json
16import logging
17import os
18import subprocess
19import sys
20
21import merge_lib as coverage_merger
22
23
24def _MergeAPIArgumentParser(*args, **kwargs):
25  parser = argparse.ArgumentParser(*args, **kwargs)
26  parser.add_argument(
27      '--task-output-dir', required=True, help=argparse.SUPPRESS)
28  parser.add_argument(
29      '--profdata-dir', required=True, help='where to store the merged data')
30  parser.add_argument(
31      '--llvm-profdata',
32      required=True,
33      help='path to llvm-profdata executable')
34  parser.add_argument(
35      '--per-cl-coverage',
36      action='store_true',
37      help='set to indicate that this is a per-CL coverage build')
38  # TODO(crbug.com/1077304) - migrate this to sparse=False as default, and have
39  # --sparse to set sparse
40  parser.add_argument(
41      '--no-sparse',
42      action='store_false',
43      dest='sparse',
44      help='run llvm-profdata without the sparse flag.')
45  # TODO(crbug.com/1077304) - The intended behaviour is to default sparse to
46  # false. --no-sparse above was added as a workaround, and will be removed.
47  # This is being introduced now in support of the migration to intended
48  # behavior. Ordering of args matters here, as the default is set by the former
49  # (sparse defaults to False because of ordering. See unit tests for details)
50  parser.add_argument(
51      '--sparse',
52      action='store_true',
53      dest='sparse',
54      help='run llvm-profdata with the sparse flag.')
55  # (crbug.com/1091310) - IR PGO is incompatible with the initial conversion
56  # of .profraw -> .profdata that's run to detect validation errors.
57  # Introducing a bypass flag that'll merge all .profraw directly to .profdata
58  parser.add_argument(
59      '--skip-validation',
60      action='store_true',
61      help='skip validation for good raw profile data. this will pass all '
62           'raw profiles found to llvm-profdata to be merged. only applicable '
63           'when input extension is .profraw.')
64  return parser
65
66
67def main():
68  desc = "Merge profraw files in <--task-output-dir> into a single profdata."
69  parser = _MergeAPIArgumentParser(description=desc)
70  params = parser.parse_args()
71
72  output_prodata_filename = 'default.profdata'
73  invalid_profiles, counter_overflows = coverage_merger.merge_profiles(
74      params.task_output_dir,
75      os.path.join(params.profdata_dir, output_prodata_filename), '.profraw',
76      params.llvm_profdata,
77      sparse=params.sparse,
78      skip_validation=params.skip_validation)
79
80  # At the moment counter overflows overlap with invalid profiles, but this is
81  # not guaranteed to remain the case indefinitely. To avoid future conflicts
82  # treat these separately.
83  if counter_overflows:
84    with open(
85        os.path.join(params.profdata_dir, 'profiles_with_overflows.json'),
86        'w') as f:
87      json.dump(counter_overflows, f)
88
89  if invalid_profiles:
90    with open(os.path.join(params.profdata_dir, 'invalid_profiles.json'),
91              'w') as f:
92      json.dump(invalid_profiles, f)
93
94  return 1 if bool(invalid_profiles) else 0
95
96
97if __name__ == '__main__':
98  logging.basicConfig(
99      format='[%(asctime)s %(levelname)s] %(message)s', level=logging.INFO)
100  sys.exit(main())
101