Prepare uploader to be used as a 'merge script'.
* Don't exit by throwing exceptions. * Rely on a dataclass instead of argument list. * Prepare to remove arg wait_upload because it's always true. * Remove unused args wait_timeout_sec and wait_timeout_secwait_polling_period_sec. Bug: webrtc:13806 Change-Id: I0879fa7fd22c72f5b174f8823bdd51d49f1f140b Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/255320 Reviewed-by: Mirko Bonadei <mbonadei@webrtc.org> Commit-Queue: Jeremy Leconte <jleconte@google.com> Reviewed-by: Andrey Logvin <landrey@webrtc.org> Cr-Commit-Position: refs/heads/main@{#36193}
This commit is contained in:
committed by
WebRTC LUCI CQ
parent
8ca06137dc
commit
2c4a4472a5
@ -14,6 +14,7 @@ import subprocess
|
||||
import time
|
||||
import zlib
|
||||
|
||||
import dataclasses
|
||||
import httplib2
|
||||
|
||||
from tracing.value import histogram
|
||||
@ -22,6 +23,41 @@ from tracing.value.diagnostics import generic_set
|
||||
from tracing.value.diagnostics import reserved_infos
|
||||
|
||||
|
||||
@dataclasses.dataclass
|
||||
class UploaderOptions():
|
||||
"""Required information to upload perf metrics.
|
||||
|
||||
Attributes:
|
||||
perf_dashboard_machine_group: The "master" the bots are grouped under.
|
||||
This string is the group in the the perf dashboard path
|
||||
group/bot/perf_id/metric/subtest.
|
||||
bot: The bot running the test (e.g. webrtc-win-large-tests).
|
||||
test_suite: The key for the test in the dashboard (i.e. what you select
|
||||
in the top-level test suite selector in the dashboard
|
||||
webrtc_git_hash: webrtc.googlesource.com commit hash.
|
||||
commit_position: Commit pos corresponding to the git hash.
|
||||
build_page_url: URL to the build page for this build.
|
||||
dashboard_url: Which dashboard to use.
|
||||
input_results_file: A HistogramSet proto file coming from WebRTC tests.
|
||||
output_json_file: Where to write the output (for debugging).
|
||||
wait_timeout_sec: Maximum amount of time in seconds that the script will
|
||||
wait for the confirmation.
|
||||
wait_polling_period_sec: Status will be requested from the Dashboard
|
||||
every wait_polling_period_sec seconds.
|
||||
"""
|
||||
perf_dashboard_machine_group: str
|
||||
bot: str
|
||||
test_suite: str
|
||||
webrtc_git_hash: str
|
||||
commit_position: int
|
||||
build_page_url: str
|
||||
dashboard_url: str
|
||||
input_results_file: str
|
||||
output_json_file: str
|
||||
wait_timeout_sec: datetime.timedelta = datetime.timedelta(seconds=1200)
|
||||
wait_polling_period_sec: datetime.timedelta = datetime.timedelta(seconds=120)
|
||||
|
||||
|
||||
def _GenerateOauthToken():
|
||||
args = ['luci-auth', 'token']
|
||||
p = subprocess.Popen(args,
|
||||
@ -195,7 +231,7 @@ def _ApplyHacks(dicts):
|
||||
|
||||
def _LoadHistogramSetFromProto(options):
|
||||
hs = histogram_set.HistogramSet()
|
||||
with options.input_results_file as f:
|
||||
with open(options.input_results_file, 'rb') as f:
|
||||
hs.ImportProto(f.read())
|
||||
|
||||
return hs
|
||||
@ -217,11 +253,11 @@ def _AddBuildInfo(histograms, options):
|
||||
|
||||
|
||||
def _DumpOutput(histograms, output_file):
|
||||
with output_file:
|
||||
json.dump(_ApplyHacks(histograms.AsDicts()), output_file, indent=4)
|
||||
with open(output_file, 'wb') as f:
|
||||
json.dump(_ApplyHacks(histograms.AsDicts()), f, indent=4)
|
||||
|
||||
|
||||
def UploadToDashboard(options):
|
||||
def UploadToDashboardImpl(options):
|
||||
histograms = _LoadHistogramSetFromProto(options)
|
||||
_AddBuildInfo(histograms, options)
|
||||
|
||||
@ -236,15 +272,14 @@ def UploadToDashboard(options):
|
||||
return 1
|
||||
|
||||
upload_token = json.loads(content).get('token')
|
||||
if not options.wait_for_upload or not upload_token:
|
||||
if not upload_token:
|
||||
print(('Received 200 from dashboard. ',
|
||||
'Not waiting for the upload status confirmation.'))
|
||||
return 0
|
||||
|
||||
response, resp_json = _WaitForUploadConfirmation(
|
||||
options.dashboard_url, upload_token,
|
||||
datetime.timedelta(seconds=options.wait_timeout_sec),
|
||||
datetime.timedelta(seconds=options.wait_polling_period_sec))
|
||||
options.dashboard_url, upload_token, options.wait_timeout_sec,
|
||||
options.wait_polling_period_sec)
|
||||
|
||||
if ((resp_json and resp_json['state'] == 'COMPLETED')
|
||||
or _CheckFullUploadInfo(options.dashboard_url, upload_token)):
|
||||
@ -260,6 +295,15 @@ def UploadToDashboard(options):
|
||||
print('Upload failed.')
|
||||
return 1
|
||||
|
||||
print(('Upload wasn\'t completed in a given time: %d seconds.' %
|
||||
print(('Upload wasn\'t completed in a given time: %s seconds.' %
|
||||
options.wait_timeout_sec))
|
||||
return 1
|
||||
|
||||
|
||||
def UploadToDashboard(options):
|
||||
try:
|
||||
exit_code = UploadToDashboardImpl(options)
|
||||
except RuntimeError as e:
|
||||
print(e)
|
||||
return 2
|
||||
return exit_code
|
||||
|
||||
@ -32,9 +32,9 @@ def _CreateParser():
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument('--perf-dashboard-machine-group',
|
||||
required=True,
|
||||
help='The "master" the bots are grouped under. This '
|
||||
'string is the group in the the perf dashboard path '
|
||||
'group/bot/perf_id/metric/subtest.')
|
||||
help='The "machine_group" the bots are grouped under.'
|
||||
'This string is the group in the the perf dashboard '
|
||||
'path group/bot/perf_id/metric/subtest.')
|
||||
parser.add_argument('--bot',
|
||||
required=True,
|
||||
help='The bot running the test (e.g. '
|
||||
@ -68,27 +68,14 @@ def _CreateParser():
|
||||
parser.add_argument('--outdir',
|
||||
required=True,
|
||||
help='Path to the local out/ dir (usually out/Default)')
|
||||
# TODO(crbug.com/webrtc/13806): Remove this argument.
|
||||
parser.add_argument('--wait-for-upload',
|
||||
action='store_true',
|
||||
help='If specified, script will wait untill Chrome '
|
||||
'perf dashboard confirms that the data was succesfully '
|
||||
'proccessed and uploaded')
|
||||
parser.add_argument('--wait-timeout-sec',
|
||||
type=int,
|
||||
default=1200,
|
||||
help='Used only if wait-for-upload is True. Maximum '
|
||||
'amount of time in seconds that the script will wait '
|
||||
'for the confirmation.')
|
||||
parser.add_argument('--wait-polling-period-sec',
|
||||
type=int,
|
||||
default=120,
|
||||
help='Used only if wait-for-upload is True. Status '
|
||||
'will be requested from the Dashboard every '
|
||||
'wait-polling-period-sec seconds.')
|
||||
help='DEPRECATED: this option will soon be removed')
|
||||
return parser
|
||||
|
||||
|
||||
def _ConfigurePythonPath(options):
|
||||
def _ConfigurePythonPath(outdir):
|
||||
# We just yank the python scripts we require into the PYTHONPATH. You could
|
||||
# also imagine a solution where we use for instance
|
||||
# protobuf:py_proto_runtime to copy catapult and protobuf code to out/.
|
||||
@ -110,8 +97,8 @@ def _ConfigurePythonPath(options):
|
||||
# The webrtc_dashboard_upload gn rule will build the protobuf stub for
|
||||
# python, so put it in the path for this script before we attempt to import
|
||||
# it.
|
||||
histogram_proto_path = os.path.join(options.outdir, 'pyproto', 'tracing',
|
||||
'tracing', 'proto')
|
||||
histogram_proto_path = os.path.join(outdir, 'pyproto', 'tracing', 'tracing',
|
||||
'proto')
|
||||
sys.path.insert(0, histogram_proto_path)
|
||||
|
||||
# Fail early in case the proto hasn't been built.
|
||||
@ -127,11 +114,23 @@ def main(args):
|
||||
parser = _CreateParser()
|
||||
options = parser.parse_args(args)
|
||||
|
||||
_ConfigurePythonPath(options)
|
||||
_ConfigurePythonPath(options.outdir)
|
||||
|
||||
import catapult_uploader
|
||||
|
||||
return catapult_uploader.UploadToDashboard(options)
|
||||
uploader_options = catapult_uploader.UploaderOptions(
|
||||
perf_dashboard_machine_group=options.perf_dashboard_machine_group,
|
||||
bot=options.bot,
|
||||
test_suite=options.test_suite,
|
||||
webrtc_git_hash=options.webrtc_git_hash,
|
||||
commit_position=options.commit_position,
|
||||
build_page_url=options.build_page_url,
|
||||
dashboard_url=options.dashboard_url,
|
||||
input_results_file=options.input_results_file,
|
||||
output_json_file=options.output_json_file,
|
||||
)
|
||||
|
||||
return catapult_uploader.UploadToDashboard(uploader_options)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
Reference in New Issue
Block a user