123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149 |
- #!/usr/bin/env vpython3
- #
- # Copyright 2021 The Chromium Authors. All rights reserved.
- # Use of this source code is governed by a BSD-style license that can be
- # found in the LICENSE file.
- '''Implements Chrome-Fuchsia package binary size differ.'''
- import argparse
- import collections
- import copy
- import json
- import logging
- import math
- import os
- import re
- import shutil
- import subprocess
- import sys
- import tempfile
- import time
- import traceback
- import uuid
- from common import GetHostToolPathFromPlatform, GetHostArchFromPlatform
- from common import SDK_ROOT, DIR_SOURCE_ROOT
- from binary_sizes import ReadPackageSizesJson
- from binary_sizes import PACKAGES_SIZES_FILE
- # Eng is not responsible for changes that cause "reasonable growth" if the
- # uncompressed binary size does not grow.
- # First-warning will fail the test if the uncompressed and compressed size
- # grow, while always-fail will fail the test regardless of uncompressed growth
- # (solely based on compressed growth).
- _FIRST_WARNING_DELTA_BYTES = 12 * 1024 # 12 KiB
- _ALWAYS_FAIL_DELTA_BYTES = 100 * 1024 # 100 KiB
- _TRYBOT_DOC = 'https://chromium.googlesource.com/chromium/src/+/main/docs/speed/binary_size/fuchsia_binary_size_trybot.md'
- def ComputePackageDiffs(before_sizes_file, after_sizes_file):
- '''Computes difference between after and before diff, for each package.'''
- before_sizes = ReadPackageSizesJson(before_sizes_file)
- after_sizes = ReadPackageSizesJson(after_sizes_file)
- assert before_sizes.keys() == after_sizes.keys(), (
- 'Package files cannot'
- ' be compared with different packages: '
- '{} vs {}'.format(before_sizes.keys(), after_sizes.keys()))
- growth = {'compressed': {}, 'uncompressed': {}}
- status_code = 0
- summary = ''
- for package_name in before_sizes:
- growth['compressed'][package_name] = (after_sizes[package_name].compressed -
- before_sizes[package_name].compressed)
- growth['uncompressed'][package_name] = (
- after_sizes[package_name].uncompressed -
- before_sizes[package_name].uncompressed)
- # Developers are only responsible if uncompressed increases.
- if ((growth['compressed'][package_name] >= _FIRST_WARNING_DELTA_BYTES
- and growth['uncompressed'][package_name] > 0)
- # However, if compressed growth is unusually large, fail always.
- or growth['compressed'][package_name] >= _ALWAYS_FAIL_DELTA_BYTES):
- if not summary:
- summary = ('Size check failed! The following package(s) are affected:'
- '<br>')
- status_code = 1
- summary += (('- {} (compressed) grew by {} bytes (uncompressed growth:'
- ' {} bytes).<br>').format(
- package_name, growth['compressed'][package_name],
- growth['uncompressed'][package_name]))
- growth['status_code'] = status_code
- summary += ('<br>See the following document for more information about'
- ' this trybot:<br>{}'.format(_TRYBOT_DOC))
- growth['summary'] = summary
- # TODO(crbug.com/1266085): Investigate using these fields.
- growth['archive_filenames'] = []
- growth['links'] = []
- return growth
- def main():
- parser = argparse.ArgumentParser()
- parser.add_argument(
- '--before-dir',
- type=os.path.realpath,
- required=True,
- help='Location of the build without the patch',
- )
- parser.add_argument(
- '--after-dir',
- type=os.path.realpath,
- required=True,
- help='Location of the build with the patch',
- )
- parser.add_argument(
- '--results-path',
- type=os.path.realpath,
- required=True,
- help='Output path for the trybot result .json file',
- )
- parser.add_argument('--verbose',
- '-v',
- action='store_true',
- help='Enable verbose output')
- args = parser.parse_args()
- if args.verbose:
- print('Fuchsia binary sizes')
- print('Working directory', os.getcwd())
- print('Args:')
- for var in vars(args):
- print(' {}: {}'.format(var, getattr(args, var) or ''))
- if not os.path.isdir(args.before_dir) or not os.path.isdir(args.after_dir):
- raise Exception(
- 'Could not find build output directory "{}" or "{}".'.format(
- args.before_dir, args.after_dir))
- test_name = 'sizes'
- before_sizes_file = os.path.join(args.before_dir, test_name,
- PACKAGES_SIZES_FILE)
- after_sizes_file = os.path.join(args.after_dir, test_name,
- PACKAGES_SIZES_FILE)
- if not os.path.isfile(before_sizes_file):
- raise Exception(
- 'Could not find before sizes file: "{}"'.format(before_sizes_file))
- if not os.path.isfile(after_sizes_file):
- raise Exception(
- 'Could not find after sizes file: "{}"'.format(after_sizes_file))
- test_completed = False
- try:
- growth = ComputePackageDiffs(before_sizes_file, after_sizes_file)
- test_completed = True
- with open(args.results_path, 'wt') as results_file:
- json.dump(growth, results_file)
- except:
- _, value, trace = sys.exc_info()
- traceback.print_tb(trace)
- print(str(value))
- finally:
- return 0 if test_completed else 1
- if __name__ == '__main__':
- sys.exit(main())
|