blob: 5f71570116c3d86761a019355b54860fd48eef15 [file] [log] [blame]
bsheedy20e696b2017-09-13 20:31:051# Copyright 2017 The Chromium Authors. All rights reserved.
2# Use of this source code is governed by a BSD-style license that can be
3# found in the LICENSE file.
4
5"""Runs resource_sizes.py on two apks and outputs the diff."""
6
7import argparse
8import json
9import os
10import subprocess
11import sys
12
13from pylib.constants import host_paths
14from pylib.utils import shared_preference_utils
15
16with host_paths.SysPath(host_paths.BUILD_COMMON_PATH):
17 import perf_tests_results_helper # pylint: disable=import-error
18
19_ANDROID_DIR = os.path.dirname(os.path.abspath(__file__))
20with host_paths.SysPath(os.path.join(_ANDROID_DIR, 'gyp', 'util')):
21 import build_utils # pylint: disable=import-error
22
23
24_BASE_CHART = {
25 'format_version': '0.1',
26 'benchmark_name': 'resource_sizes_diff',
27 'benchmark_description': 'APK resource size diff information',
28 'trace_rerun_options': [],
29 'charts': {},
30}
31
32_RESULTS_FILENAME = 'results-chart.json'
33
34
35def DiffResults(chartjson, base_results, diff_results):
36 """Reports the diff between the two given results.
37
38 Args:
39 chartjson: A dictionary that chartjson results will be placed in, or None
40 to only print results.
41 base_results: The chartjson-formatted size results of the base APK.
42 diff_results: The chartjson-formatted size results of the diff APK.
43 """
44 for graph_title, graph in base_results['charts'].iteritems():
45 for trace_title, trace in graph.iteritems():
46 perf_tests_results_helper.ReportPerfResult(
47 chartjson, graph_title, trace_title,
48 diff_results['charts'][graph_title][trace_title]['value']
49 - trace['value'],
50 trace['units'], trace['improvement_direction'],
51 trace['important'])
52
53
54def AddIntermediateResults(chartjson, base_results, diff_results):
55 """Copies the intermediate size results into the output chartjson.
56
57 Args:
58 chartjson: A dictionary that chartjson results will be placed in.
59 base_results: The chartjson-formatted size results of the base APK.
60 diff_results: The chartjson-formatted size results of the diff APK.
61 """
62 for graph_title, graph in base_results['charts'].iteritems():
63 for trace_title, trace in graph.iteritems():
64 perf_tests_results_helper.ReportPerfResult(
65 chartjson, graph_title + '_base_apk', trace_title,
66 trace['value'], trace['units'], trace['improvement_direction'],
67 trace['important'])
68
69 # Both base_results and diff_results should have the same charts/traces, but
70 # loop over them separately in case they don't
71 for graph_title, graph in diff_results['charts'].iteritems():
72 for trace_title, trace in graph.iteritems():
73 perf_tests_results_helper.ReportPerfResult(
74 chartjson, graph_title + '_diff_apk', trace_title,
75 trace['value'], trace['units'], trace['improvement_direction'],
76 trace['important'])
77
78
79def _CreateArgparser():
80 argparser = argparse.ArgumentParser(
81 description='Diff resource sizes of two APKs. Arguments not listed here '
82 'will be passed on to both invocations of resource_sizes.py.')
83 argparser.add_argument('--chromium-output-directory-base',
84 dest='out_dir_base',
85 help='Location of the build artifacts for the base '
86 'APK, i.e. what the size increase/decrease will '
87 'be measured from.')
88 argparser.add_argument('--chromium-output-directory-diff',
89 dest='out_dir_diff',
90 help='Location of the build artifacts for the diff '
91 'APK.')
92 argparser.add_argument('--chartjson',
93 action='store_true',
94 help='Sets output mode to chartjson.')
95 argparser.add_argument('--include-intermediate-results',
96 action='store_true',
97 help='Include the results from the resource_sizes.py '
98 'runs in the chartjson output.')
99 argparser.add_argument('--output-dir',
100 default='.',
101 help='Directory to save chartjson to.')
102 argparser.add_argument('--base-apk',
103 required=True,
104 help='Path to the base APK, i.e. what the size '
105 'increase/decrease will be measured from.')
106 argparser.add_argument('--diff-apk',
107 required=True,
108 help='Path to the diff APK, i.e. the APK whose size '
109 'increase/decrease will be measured against the '
110 'base APK.')
111 return argparser
112
113
114def main():
115 args, unknown_args = _CreateArgparser().parse_known_args()
116 chartjson = _BASE_CHART.copy() if args.chartjson else None
117
118 with build_utils.TempDir() as base_dir, build_utils.TempDir() as diff_dir:
119 # Run resource_sizes.py on the two APKs
120 resource_sizes_path = os.path.join(_ANDROID_DIR, 'resource_sizes.py')
121 shared_args = (['python', resource_sizes_path, '--chartjson']
122 + unknown_args)
123
124 base_args = shared_args + ['--output-dir', base_dir, args.base_apk]
125 if args.out_dir_base:
126 base_args += ['--chromium-output-directory', args.out_dir_base]
127 subprocess.check_output(base_args, stderr=subprocess.STDOUT)
128
129 diff_args = shared_args + ['--output-dir', diff_dir, args.diff_apk]
130 if args.out_dir_diff:
131 base_args += ['--chromium-output-directory', args.out_dir_diff]
132 subprocess.check_output(diff_args, stderr=subprocess.STDOUT)
133
134 # Combine the separate results
135 base_file = os.path.join(base_dir, _RESULTS_FILENAME)
136 diff_file = os.path.join(diff_dir, _RESULTS_FILENAME)
137 base_results = shared_preference_utils.ExtractSettingsFromJson(base_file)
138 diff_results = shared_preference_utils.ExtractSettingsFromJson(diff_file)
139 DiffResults(chartjson, base_results, diff_results)
140 if args.include_intermediate_results:
141 AddIntermediateResults(chartjson, base_results, diff_results)
142
143 if args.chartjson:
144 with open(os.path.join(os.path.abspath(args.output_dir),
145 _RESULTS_FILENAME), 'w') as outfile:
146 json.dump(chartjson, outfile)
147
148if __name__ == '__main__':
149 sys.exit(main())