| #!/usr/bin/env python3 |
| # Copyright 2023 The ChromiumOS Authors |
| # Use of this source code is governed by a BSD-style license that can be |
| # found in the LICENSE file. |
| |
| import argparse |
| import json |
| import tempfile |
| import os |
| import sys |
| import time |
| import pathlib |
| |
| sys.path.append(os.path.dirname(sys.path[0])) |
| |
| from impl.common import cwd, CROSVM_ROOT, cmd |
| |
| BOT_MASTERS = "crosvm.ci" |
| METRIC_NAME = "file_size" |
| TEST_SUITE_NAME = "crosvm.binary_output" |
| CHROMEPERF_URL = "https://chromeperf.appspot.com" |
| |
| |
| # TODO(zihanchen): upload binary size to db for backup |
| # TODO(zihanchen): Add usage |
| |
| |
| def main(): |
| parser = argparse.ArgumentParser() |
| parser.add_argument( |
| "--base-dir", |
| help="Base dir of cargo target, used to convert target path to shorter relative path, must " |
| "be absolute", |
| ) |
| parser.add_argument( |
| "--target-name", |
| help="Target name of binary", |
| ) |
| parser.add_argument( |
| "--target-path", |
| help="Path to binary, must be absolute if base dir is provided", |
| required=True, |
| ) |
| parser.add_argument("--upload", action="store_true") |
| parser.add_argument( |
| "--catapult-tool-path", |
| help="Path to catapult dashboard upload tool", |
| default="/tools/catapult", |
| ) |
| parser.add_argument( |
| "--builder-name", |
| help="Name of builder generating binaries", |
| ) |
| parser.add_argument("--log-url", help="Url to build execution") |
| parser.add_argument("--build-version", help="Version of crosvm corresponding to the results") |
| |
| args = parser.parse_args() |
| if args.base_dir: |
| if not os.path.isabs(args.base_dir): |
| raise AssertionError("Base dir mush be and absolute path") |
| if not os.path.isabs(args.target_path): |
| raise AssertionError("When base dir is provided, target path must be an absolute path") |
| if not os.path.commonpath([args.base_dir, args.target_path]) == os.path.normpath( |
| args.base_dir |
| ): |
| raise AssertionError("Base dir must be a parent directory of target path") |
| output_path = ( |
| os.path.relpath(args.target_path, start=args.base_dir) |
| if args.base_dir |
| else os.path.normpath(args.target_path) |
| ) |
| |
| # output path can contain duplicated target names, dedup before printing |
| if len(output_path.split("/")) > 2 and output_path.split("/")[0] == output_path.split("/")[1]: |
| output_path = "/".join(output_path.split("/")[1:]) |
| |
| file_size = os.path.getsize(args.target_path) |
| size_dict_for_gerrit = {output_path: file_size} |
| print(json.dumps(size_dict_for_gerrit)) |
| |
| if not args.upload: |
| return |
| |
| fuchiaperf_fd, fuchiaperf_file_path = tempfile.mkstemp(suffix=".fuchisaperf.json", text=True) |
| |
| fuchiaperf_file = os.fdopen(fuchiaperf_fd, "w") |
| |
| fuchsiaperf_data = [ |
| { |
| "test_name": output_path, |
| "test_suite": TEST_SUITE_NAME, |
| "unit": "bytes", |
| "values": [file_size], |
| "metric": METRIC_NAME, |
| } |
| ] |
| |
| json.dump(fuchsiaperf_data, fuchiaperf_file) |
| fuchiaperf_file.close() |
| |
| with open(fuchiaperf_file_path, "r") as f: |
| print(f.read(), file=sys.stderr) |
| |
| _, catapult_file_path = tempfile.mkstemp(suffix=".json", text=True) |
| |
| with cwd(CROSVM_ROOT / "tools" / "impl" / "catapult_converter"): |
| cmd( |
| "cargo", |
| "run", |
| "--", |
| "--input", |
| fuchiaperf_file_path, |
| "--execution-timestamp-ms", |
| str(int(time.time() * 1000)), |
| "--masters", |
| BOT_MASTERS, |
| "--bots", |
| args.builder_name, |
| "--log-url", |
| args.log_url, |
| *( |
| ( |
| "--product-versions", |
| args.build_version, |
| ) |
| if args.build_version |
| else () |
| ) |
| ).write_to(pathlib.Path(catapult_file_path)) |
| |
| # print catapult file to stderr so we retain a copy |
| with open(catapult_file_path, "r") as f: |
| print(f.read(), file=sys.stderr) |
| |
| print( |
| cmd( |
| args.catapult_tool_path, |
| "upload", |
| '--service-account-json=":gce"', |
| "--url", |
| CHROMEPERF_URL, |
| catapult_file_path, |
| ).stdout(), |
| file=sys.stderr, |
| ) |
| |
| |
| if __name__ == "__main__": |
| main() |