• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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