• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/usr/bin/env python3
2#
3# Copyright 2023 The Chromium Authors
4# Use of this source code is governed by a BSD-style license that can be
5# found in the LICENSE file.
6
7import argparse
8import difflib
9import pathlib
10import os
11import sys
12
13REPOSITORY_ROOT = os.path.abspath(
14    os.path.join(os.path.dirname(__file__), os.pardir, os.pardir, os.pardir))
15
16sys.path.insert(0, os.path.join(REPOSITORY_ROOT, 'build/android/gyp'))
17from util import build_utils  # pylint: disable=wrong-import-position
18
19# Set this environment variable in order to regenerate the golden text
20# files.
21_REBASELINE_CRONET_PROGUARD = os.environ.get('REBASELINE_CRONET_PROGUARD',
22                                             '0') != '0'
23
24
25def _ReadFile(path):
26  """Reads a file as a string"""
27  return pathlib.Path(path).read_text()
28
29
30def _CompareText(generated_text, golden_text, golden_file_path):
31  """
32  Compares the generated text with the golden text.
33
34  returns a diff that can be applied with `patch` if exists.
35  """
36  golden_lines = [line.rstrip() for line in golden_text.splitlines()]
37  generated_lines = [line.rstrip() for line in generated_text.splitlines()]
38  if golden_lines == generated_lines:
39    return None
40
41  expected_path = os.path.relpath(
42      golden_file_path, build_utils.DIR_SOURCE_ROOT)
43
44  diff = difflib.unified_diff(
45      golden_lines,
46      generated_lines,
47      fromfile=os.path.join('before', expected_path),
48      tofile=os.path.join('after', expected_path),
49      n=0,
50      lineterm='',
51  )
52
53  return '\n'.join(diff)
54
55
56def CompareGeneratedWithGolden(generated_file_path, golden_file_path):
57  golden_text = _ReadFile(golden_file_path)
58  generated_text = _ReadFile(generated_file_path)
59  if _REBASELINE_CRONET_PROGUARD:
60    if golden_text != generated_text:
61      print('Updated', golden_file_path)
62      with open(golden_file_path, 'w') as f:
63        f.write(generated_text)
64    return None
65
66  if golden_text is None:
67    print(f'Golden file does not exist: {golden_file_path}')
68
69  return _CompareText(generated_text, golden_text, golden_file_path)
70
71
72def main():
73  parser = argparse.ArgumentParser()
74  parser.add_argument('--input_generated_file',
75                      type=str,
76                      help="Path to the generated file.")
77  parser.add_argument('--input_golden_file',
78                      type=str,
79                      help='Path to the input golden file.')
80  parser.add_argument('--stamp', type=str, help='Path to touch on success')
81  args = parser.parse_args()
82  text_diff = CompareGeneratedWithGolden(args.input_generated_file,
83                                         args.input_golden_file)
84  if text_diff:
85
86    print(f"""
87Cronet Proguard golden test failed. To generate it:
88#######################################################
89#                                                     #
90#      Run the command below to generate the file     #
91#                                                     #
92#######################################################
93
94########### START ###########
95patch -p1 << 'END_DIFF'
96{text_diff}
97END_DIFF
98############ END ############
99
100If you wish to build the action locally in generation mode, See the instructions below:
101#####################################################################
102#                                                                   #
103# Run the command below to re-run the action in generation mode     #
104#                                                                   #
105#####################################################################
106./components/cronet/tools/cr_cronet.py -d out/proguard_config gn && \
107REBASELINE_CRONET_PROGUARD=1 autoninja -C out/proguard_config \
108cronet_combined_proguard_flags_golden_test
109
110This will generate a GN output directory with the appropriate GN\
111flags to run the golden_test in generation mode rather than verification mode.
112""")
113    sys.exit(-1)
114  else:
115    build_utils.Touch(args.stamp)
116
117if __name__ == '__main__':
118  sys.exit(main())
119