blob: 2a99499843adccc35bf50a33a018eb717fe76c12 [file] [log] [blame]
Jan Tattermusch6d7fa552016-04-14 17:42:54 -07001#!/usr/bin/env python2.7
Jan Tattermuschefd98032016-04-14 16:29:24 -07002# Copyright 2016, Google Inc.
3# All rights reserved.
4#
5# Redistribution and use in source and binary forms, with or without
6# modification, are permitted provided that the following conditions are
7# met:
8#
9# * Redistributions of source code must retain the above copyright
10# notice, this list of conditions and the following disclaimer.
11# * Redistributions in binary form must reproduce the above
12# copyright notice, this list of conditions and the following disclaimer
13# in the documentation and/or other materials provided with the
14# distribution.
15# * Neither the name of Google Inc. nor the names of its
16# contributors may be used to endorse or promote products derived from
17# this software without specific prior written permission.
18#
19# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
Jan Tattermusch6d7fa552016-04-14 17:42:54 -070031# Uploads performance benchmark result file to bigquery.
Jan Tattermuschefd98032016-04-14 16:29:24 -070032
Jan Tattermusch6d7fa552016-04-14 17:42:54 -070033import argparse
Jan Tattermusch4843b512016-04-15 13:43:39 -070034import calendar
Jan Tattermuschefd98032016-04-14 16:29:24 -070035import json
36import os
37import sys
Jan Tattermusch4843b512016-04-15 13:43:39 -070038import time
Jan Tattermuschefd98032016-04-14 16:29:24 -070039import uuid
40
41
42gcp_utils_dir = os.path.abspath(os.path.join(
43 os.path.dirname(__file__), '../../gcp/utils'))
44sys.path.append(gcp_utils_dir)
45import big_query_utils
46
47
48_PROJECT_ID='grpc-testing'
Jan Tattermuschefd98032016-04-14 16:29:24 -070049
50
Jan Tattermusch4de2c322016-05-10 14:33:07 -070051def _upload_netperf_latency_csv_to_bigquery(dataset_id, table_id, result_file):
52 with open(result_file, 'r') as f:
53 (col1, col2, col3) = f.read().split(',')
54 latency50 = float(col1.strip()) * 1000
55 latency90 = float(col2.strip()) * 1000
56 latency99 = float(col3.strip()) * 1000
57
58 scenario_result = {
59 'scenario': {
60 'name': 'netperf_tcp_rr'
61 },
62 'summary': {
63 'latency50': latency50,
64 'latency90': latency90,
65 'latency99': latency99
66 }
67 }
68
Jan Tattermuschefd98032016-04-14 16:29:24 -070069 bq = big_query_utils.create_big_query()
Jan Tattermusch6d7fa552016-04-14 17:42:54 -070070 _create_results_table(bq, dataset_id, table_id)
Jan Tattermuschefd98032016-04-14 16:29:24 -070071
Jan Tattermusch4de2c322016-05-10 14:33:07 -070072 if not _insert_result(bq, dataset_id, table_id, scenario_result, flatten=False):
73 print 'Error uploading result to bigquery.'
74 sys.exit(1)
75
76
77def _upload_scenario_result_to_bigquery(dataset_id, table_id, result_file):
Jan Tattermuschefd98032016-04-14 16:29:24 -070078 with open(result_file, 'r') as f:
79 scenario_result = json.loads(f.read())
Jan Tattermusch6d7fa552016-04-14 17:42:54 -070080
Jan Tattermusch4de2c322016-05-10 14:33:07 -070081 bq = big_query_utils.create_big_query()
82 _create_results_table(bq, dataset_id, table_id)
83
Jan Tattermusch6d7fa552016-04-14 17:42:54 -070084 if not _insert_result(bq, dataset_id, table_id, scenario_result):
85 print 'Error uploading result to bigquery.'
86 sys.exit(1)
Jan Tattermuschefd98032016-04-14 16:29:24 -070087
88
Jan Tattermusch4de2c322016-05-10 14:33:07 -070089def _insert_result(bq, dataset_id, table_id, scenario_result, flatten=True):
90 if flatten:
91 _flatten_result_inplace(scenario_result)
Jan Tattermusch4843b512016-04-15 13:43:39 -070092 _populate_metadata_inplace(scenario_result)
Jan Tattermuschefd98032016-04-14 16:29:24 -070093 row = big_query_utils.make_row(str(uuid.uuid4()), scenario_result)
94 return big_query_utils.insert_rows(bq,
95 _PROJECT_ID,
Jan Tattermusch6d7fa552016-04-14 17:42:54 -070096 dataset_id,
97 table_id,
Jan Tattermuschefd98032016-04-14 16:29:24 -070098 [row])
99
100
Jan Tattermusch6d7fa552016-04-14 17:42:54 -0700101def _create_results_table(bq, dataset_id, table_id):
Jan Tattermuschefd98032016-04-14 16:29:24 -0700102 with open(os.path.dirname(__file__) + '/scenario_result_schema.json', 'r') as f:
103 table_schema = json.loads(f.read())
104 desc = 'Results of performance benchmarks.'
Jan Tattermusch6d7fa552016-04-14 17:42:54 -0700105 return big_query_utils.create_table2(bq, _PROJECT_ID, dataset_id,
106 table_id, table_schema, desc)
Jan Tattermuschefd98032016-04-14 16:29:24 -0700107
108
109def _flatten_result_inplace(scenario_result):
110 """Bigquery is not really great for handling deeply nested data
111 and repeated fields. To maintain values of some fields while keeping
112 the schema relatively simple, we artificially leave some of the fields
113 as JSON strings.
114 """
115 scenario_result['scenario']['clientConfig'] = json.dumps(scenario_result['scenario']['clientConfig'])
116 scenario_result['scenario']['serverConfig'] = json.dumps(scenario_result['scenario']['serverConfig'])
117 scenario_result['latencies'] = json.dumps(scenario_result['latencies'])
118 for stats in scenario_result['clientStats']:
119 stats['latencies'] = json.dumps(stats['latencies'])
Jan Tattermusch88cc4e22016-04-14 16:58:50 -0700120 scenario_result['serverCores'] = json.dumps(scenario_result['serverCores'])
Sree Kuchibhotla6dbfce02016-07-15 11:05:24 -0700121 scenario_result['clientSuccess'] = json.dumps(scenario_result['clientSuccess'])
122 scenario_result['serverSuccess'] = json.dumps(scenario_result['serverSuccess'])
Jan Tattermusch6d7fa552016-04-14 17:42:54 -0700123
124
Jan Tattermusch4843b512016-04-15 13:43:39 -0700125def _populate_metadata_inplace(scenario_result):
126 """Populates metadata based on environment variables set by Jenkins."""
127 # NOTE: Grabbing the Jenkins environment variables will only work if the
128 # driver is running locally on the same machine where Jenkins has started
129 # the job. For our setup, this is currently the case, so just assume that.
130 build_number = os.getenv('BUILD_NUMBER')
131 build_url = os.getenv('BUILD_URL')
132 job_name = os.getenv('JOB_NAME')
133 git_commit = os.getenv('GIT_COMMIT')
134 # actual commit is the actual head of PR that is getting tested
135 git_actual_commit = os.getenv('ghprbActualCommit')
136
137 utc_timestamp = str(calendar.timegm(time.gmtime()))
138 metadata = {'created': utc_timestamp}
139
140 if build_number:
141 metadata['buildNumber'] = build_number
142 if build_url:
143 metadata['buildUrl'] = build_url
144 if job_name:
145 metadata['jobName'] = job_name
146 if git_commit:
147 metadata['gitCommit'] = git_commit
148 if git_actual_commit:
149 metadata['gitActualCommit'] = git_actual_commit
150
151 scenario_result['metadata'] = metadata
152
153
Jan Tattermusch6d7fa552016-04-14 17:42:54 -0700154argp = argparse.ArgumentParser(description='Upload result to big query.')
155argp.add_argument('--bq_result_table', required=True, default=None, type=str,
156 help='Bigquery "dataset.table" to upload results to.')
157argp.add_argument('--file_to_upload', default='scenario_result.json', type=str,
158 help='Report file to upload.')
Jan Tattermusch4de2c322016-05-10 14:33:07 -0700159argp.add_argument('--file_format',
160 choices=['scenario_result','netperf_latency_csv'],
161 default='scenario_result',
162 help='Format of the file to upload.')
Jan Tattermusch6d7fa552016-04-14 17:42:54 -0700163
164args = argp.parse_args()
165
166dataset_id, table_id = args.bq_result_table.split('.', 2)
Jan Tattermusch4de2c322016-05-10 14:33:07 -0700167
168if args.file_format == 'netperf_latency_csv':
169 _upload_netperf_latency_csv_to_bigquery(dataset_id, table_id, args.file_to_upload)
170else:
171 _upload_scenario_result_to_bigquery(dataset_id, table_id, args.file_to_upload)
Jan Tattermusch6d7fa552016-04-14 17:42:54 -0700172print 'Successfully uploaded %s to BigQuery.\n' % args.file_to_upload