From a51be7c1904f2accb41e5c04cbaa428f2e487a0c Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Thu, 23 Sep 2021 06:58:56 -0700 Subject: [PATCH] Remove broken tool (#27449) --- tools/github/pr_latency.py | 211 ------------------------------------- 1 file changed, 211 deletions(-) delete mode 100644 tools/github/pr_latency.py diff --git a/tools/github/pr_latency.py b/tools/github/pr_latency.py deleted file mode 100644 index afc6b9f88c8..00000000000 --- a/tools/github/pr_latency.py +++ /dev/null @@ -1,211 +0,0 @@ -#!/usr/bin/env python -# Copyright 2017 gRPC authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -"""Measure the time between PR creation and completion of all tests. - -You'll need a github API token to avoid being rate-limited. See -https://help.github.com/articles/creating-a-personal-access-token-for-the-command-line/ - -This script goes over the most recent 100 pull requests. For PRs with a single -commit, it uses the PR's creation as the initial time; otherwise, it uses the -date of the last commit. This is somewhat fragile, and imposed by the fact that -GitHub reports a PR's updated timestamp for any event that modifies the PR (e.g. -comments), not just the addition of new commits. - -In addition, it ignores latencies greater than five hours, as that's likely due -to a manual re-run of tests. -""" - -from __future__ import absolute_import -from __future__ import division -from __future__ import print_function - -from datetime import datetime -from datetime import timedelta -import json -import logging -import pprint - -import urllib2 - -logging.basicConfig(format='%(asctime)s %(message)s') - -PRS = 'https://api.github.com/repos/grpc/grpc/pulls?state=open&per_page=100' -COMMITS = 'https://api.github.com/repos/grpc/grpc/pulls/{pr_number}/commits' - - -def gh(url): - request = urllib2.Request(url) - if TOKEN: - request.add_header('Authorization', 'token {}'.format(TOKEN)) - response = urllib2.urlopen(request) - return response.read() - - -def print_csv_header(): - print('pr,base_time,test_time,latency_seconds,successes,failures,errors') - - -def output(pr, - base_time, - test_time, - diff_time, - successes, - failures, - errors, - mode='human'): - if mode == 'human': - print( - "PR #{} base time: {} UTC, Tests completed at: {} UTC. Latency: {}." - "\n\tSuccesses: {}, Failures: {}, Errors: {}".format( - pr, base_time, test_time, diff_time, successes, failures, - errors)) - elif mode == 'csv': - print(','.join([ - str(pr), - str(base_time), - str(test_time), - str(int((test_time - base_time).total_seconds())), - str(successes), - str(failures), - str(errors) - ])) - - -def parse_timestamp(datetime_str): - return datetime.strptime(datetime_str, '%Y-%m-%dT%H:%M:%SZ') - - -def to_posix_timestamp(dt): - return str((dt - datetime(1970, 1, 1)).total_seconds()) - - -def get_pr_data(): - latest_prs = json.loads(gh(PRS)) - res = [{ - 'number': pr['number'], - 'created_at': parse_timestamp(pr['created_at']), - 'updated_at': parse_timestamp(pr['updated_at']), - 'statuses_url': pr['statuses_url'] - } for pr in latest_prs] - return res - - -def get_commits_data(pr_number): - commits = json.loads(gh(COMMITS.format(pr_number=pr_number))) - return { - 'num_commits': - len(commits), - 'most_recent_date': - parse_timestamp(commits[-1]['commit']['author']['date']) - } - - -def get_status_data(statuses_url, system): - status_url = statuses_url.replace('statuses', 'status') - statuses = json.loads(gh(status_url + '?per_page=100')) - successes = 0 - failures = 0 - errors = 0 - latest_datetime = None - if not statuses: - return None - if system == 'kokoro': - string_in_target_url = 'kokoro' - elif system == 'jenkins': - string_in_target_url = 'grpc-testing' - for status in statuses['statuses']: - if not status['target_url'] or string_in_target_url not in status[ - 'target_url']: - continue # Ignore jenkins - if status['state'] == 'pending': - return None - elif status['state'] == 'success': - successes += 1 - elif status['state'] == 'failure': - failures += 1 - elif status['state'] == 'error': - errors += 1 - if not latest_datetime: - latest_datetime = parse_timestamp(status['updated_at']) - else: - latest_datetime = max(latest_datetime, - parse_timestamp(status['updated_at'])) - # First status is the most recent one. - if any([successes, failures, errors - ]) and sum([successes, failures, errors]) > 15: - return { - 'latest_datetime': latest_datetime, - 'successes': successes, - 'failures': failures, - 'errors': errors - } - else: - return None - - -def build_args_parser(): - import argparse - parser = argparse.ArgumentParser() - parser.add_argument('--format', - type=str, - choices=['human', 'csv'], - default='human', - help='Output format: are you a human or a machine?') - parser.add_argument('--system', - type=str, - choices=['jenkins', 'kokoro'], - required=True, - help='Consider only the given CI system') - parser.add_argument( - '--token', - type=str, - default='', - help='GitHub token to use its API with a higher rate limit') - return parser - - -def main(): - import sys - global TOKEN - args_parser = build_args_parser() - args = args_parser.parse_args() - TOKEN = args.token - if args.format == 'csv': - print_csv_header() - for pr_data in get_pr_data(): - commit_data = get_commits_data(pr_data['number']) - # PR with a single commit -> use the PRs creation time. - # else -> use the latest commit's date. - base_timestamp = pr_data['updated_at'] - if commit_data['num_commits'] > 1: - base_timestamp = commit_data['most_recent_date'] - else: - base_timestamp = pr_data['created_at'] - last_status = get_status_data(pr_data['statuses_url'], args.system) - if last_status: - diff = last_status['latest_datetime'] - base_timestamp - if diff < timedelta(hours=5): - output(pr_data['number'], - base_timestamp, - last_status['latest_datetime'], - diff, - last_status['successes'], - last_status['failures'], - last_status['errors'], - mode=args.format) - - -if __name__ == '__main__': - main()