1#!/usr/bin/env python3 2# Copyright 2023 The ChromiumOS Authors 3# Use of this source code is governed by a BSD-style license that can be 4# found in the LICENSE file. 5 6import argparse 7import json 8import tempfile 9import os 10import sys 11import time 12import pathlib 13 14sys.path.append(os.path.dirname(sys.path[0])) 15 16from impl.common import cwd, CROSVM_ROOT, cmd 17 18BOT_MASTERS = "crosvm.ci" 19METRIC_NAME = "file_size" 20TEST_SUITE_NAME = "crosvm.binary_output" 21CHROMEPERF_URL = "https://chromeperf.appspot.com" 22 23 24# TODO(zihanchen): upload binary size to db for backup 25# TODO(zihanchen): Add usage 26 27 28def main(): 29 parser = argparse.ArgumentParser() 30 parser.add_argument( 31 "--base-dir", 32 help="Base dir of cargo target, used to convert target path to shorter relative path, must " 33 "be absolute", 34 ) 35 parser.add_argument( 36 "--target-name", 37 help="Target name of binary", 38 ) 39 parser.add_argument( 40 "--target-path", 41 help="Path to binary, must be absolute if base dir is provided", 42 required=True, 43 ) 44 parser.add_argument("--upload", action="store_true") 45 parser.add_argument( 46 "--catapult-tool-path", 47 help="Path to catapult dashboard upload tool", 48 default="/tools/catapult", 49 ) 50 parser.add_argument( 51 "--builder-name", 52 help="Name of builder generating binaries", 53 ) 54 parser.add_argument("--log-url", help="Url to build execution") 55 parser.add_argument("--build-version", help="Version of crosvm corresponding to the results") 56 57 args = parser.parse_args() 58 if args.base_dir: 59 if not os.path.isabs(args.base_dir): 60 raise AssertionError("Base dir mush be and absolute path") 61 if not os.path.isabs(args.target_path): 62 raise AssertionError("When base dir is provided, target path must be an absolute path") 63 if not os.path.commonpath([args.base_dir, args.target_path]) == os.path.normpath( 64 args.base_dir 65 ): 66 raise AssertionError("Base dir must be a parent directory of target path") 67 output_path = ( 68 os.path.relpath(args.target_path, start=args.base_dir) 69 if args.base_dir 70 else os.path.normpath(args.target_path) 71 ) 72 73 # output path can contain duplicated target names, dedup before printing 74 if len(output_path.split("/")) > 2 and output_path.split("/")[0] == output_path.split("/")[1]: 75 output_path = "/".join(output_path.split("/")[1:]) 76 77 file_size = os.path.getsize(args.target_path) 78 size_dict_for_gerrit = {output_path: file_size} 79 print(json.dumps(size_dict_for_gerrit)) 80 81 if not args.upload: 82 return 83 84 fuchiaperf_fd, fuchiaperf_file_path = tempfile.mkstemp(suffix=".fuchisaperf.json", text=True) 85 86 fuchiaperf_file = os.fdopen(fuchiaperf_fd, "w") 87 88 fuchsiaperf_data = [ 89 { 90 "test_name": output_path, 91 "test_suite": TEST_SUITE_NAME, 92 "unit": "bytes", 93 "values": [file_size], 94 "metric": METRIC_NAME, 95 } 96 ] 97 98 json.dump(fuchsiaperf_data, fuchiaperf_file) 99 fuchiaperf_file.close() 100 101 with open(fuchiaperf_file_path, "r") as f: 102 print(f.read(), file=sys.stderr) 103 104 _, catapult_file_path = tempfile.mkstemp(suffix=".json", text=True) 105 106 with cwd(CROSVM_ROOT / "tools" / "impl" / "catapult_converter"): 107 cmd( 108 "cargo", 109 "run", 110 "--", 111 "--input", 112 fuchiaperf_file_path, 113 "--execution-timestamp-ms", 114 str(int(time.time() * 1000)), 115 "--masters", 116 BOT_MASTERS, 117 "--bots", 118 args.builder_name, 119 "--log-url", 120 args.log_url, 121 *( 122 ( 123 "--product-versions", 124 args.build_version, 125 ) 126 if args.build_version 127 else () 128 ) 129 ).write_to(pathlib.Path(catapult_file_path)) 130 131 # print catapult file to stderr so we retain a copy 132 with open(catapult_file_path, "r") as f: 133 print(f.read(), file=sys.stderr) 134 135 print( 136 cmd( 137 args.catapult_tool_path, 138 "upload", 139 '--service-account-json=":gce"', 140 "--url", 141 CHROMEPERF_URL, 142 catapult_file_path, 143 ).stdout(), 144 file=sys.stderr, 145 ) 146 147 148if __name__ == "__main__": 149 main() 150