blob: ebd28f75918c480816a66f9e938aa3fb072b41f7 [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 Tattermusch6d7fa552016-04-14 17:42:54 -070051def _upload_scenario_result_to_bigquery(dataset_id, table_id, result_file):
Jan Tattermuschefd98032016-04-14 16:29:24 -070052 bq = big_query_utils.create_big_query()
Jan Tattermusch6d7fa552016-04-14 17:42:54 -070053 _create_results_table(bq, dataset_id, table_id)
Jan Tattermuschefd98032016-04-14 16:29:24 -070054
55 with open(result_file, 'r') as f:
56 scenario_result = json.loads(f.read())
Jan Tattermusch6d7fa552016-04-14 17:42:54 -070057
58 if not _insert_result(bq, dataset_id, table_id, scenario_result):
59 print 'Error uploading result to bigquery.'
60 sys.exit(1)
Jan Tattermuschefd98032016-04-14 16:29:24 -070061
62
Jan Tattermusch6d7fa552016-04-14 17:42:54 -070063def _insert_result(bq, dataset_id, table_id, scenario_result):
Jan Tattermuschefd98032016-04-14 16:29:24 -070064 _flatten_result_inplace(scenario_result)
Jan Tattermusch4843b512016-04-15 13:43:39 -070065 _populate_metadata_inplace(scenario_result)
Jan Tattermuschefd98032016-04-14 16:29:24 -070066 row = big_query_utils.make_row(str(uuid.uuid4()), scenario_result)
67 return big_query_utils.insert_rows(bq,
68 _PROJECT_ID,
Jan Tattermusch6d7fa552016-04-14 17:42:54 -070069 dataset_id,
70 table_id,
Jan Tattermuschefd98032016-04-14 16:29:24 -070071 [row])
72
73
Jan Tattermusch6d7fa552016-04-14 17:42:54 -070074def _create_results_table(bq, dataset_id, table_id):
Jan Tattermuschefd98032016-04-14 16:29:24 -070075 with open(os.path.dirname(__file__) + '/scenario_result_schema.json', 'r') as f:
76 table_schema = json.loads(f.read())
77 desc = 'Results of performance benchmarks.'
Jan Tattermusch6d7fa552016-04-14 17:42:54 -070078 return big_query_utils.create_table2(bq, _PROJECT_ID, dataset_id,
79 table_id, table_schema, desc)
Jan Tattermuschefd98032016-04-14 16:29:24 -070080
81
82def _flatten_result_inplace(scenario_result):
83 """Bigquery is not really great for handling deeply nested data
84 and repeated fields. To maintain values of some fields while keeping
85 the schema relatively simple, we artificially leave some of the fields
86 as JSON strings.
87 """
88 scenario_result['scenario']['clientConfig'] = json.dumps(scenario_result['scenario']['clientConfig'])
89 scenario_result['scenario']['serverConfig'] = json.dumps(scenario_result['scenario']['serverConfig'])
90 scenario_result['latencies'] = json.dumps(scenario_result['latencies'])
91 for stats in scenario_result['clientStats']:
92 stats['latencies'] = json.dumps(stats['latencies'])
Jan Tattermusch88cc4e22016-04-14 16:58:50 -070093 scenario_result['serverCores'] = json.dumps(scenario_result['serverCores'])
Jan Tattermusch6d7fa552016-04-14 17:42:54 -070094
95
Jan Tattermusch4843b512016-04-15 13:43:39 -070096def _populate_metadata_inplace(scenario_result):
97 """Populates metadata based on environment variables set by Jenkins."""
98 # NOTE: Grabbing the Jenkins environment variables will only work if the
99 # driver is running locally on the same machine where Jenkins has started
100 # the job. For our setup, this is currently the case, so just assume that.
101 build_number = os.getenv('BUILD_NUMBER')
102 build_url = os.getenv('BUILD_URL')
103 job_name = os.getenv('JOB_NAME')
104 git_commit = os.getenv('GIT_COMMIT')
105 # actual commit is the actual head of PR that is getting tested
106 git_actual_commit = os.getenv('ghprbActualCommit')
107
108 utc_timestamp = str(calendar.timegm(time.gmtime()))
109 metadata = {'created': utc_timestamp}
110
111 if build_number:
112 metadata['buildNumber'] = build_number
113 if build_url:
114 metadata['buildUrl'] = build_url
115 if job_name:
116 metadata['jobName'] = job_name
117 if git_commit:
118 metadata['gitCommit'] = git_commit
119 if git_actual_commit:
120 metadata['gitActualCommit'] = git_actual_commit
121
122 scenario_result['metadata'] = metadata
123
124
Jan Tattermusch6d7fa552016-04-14 17:42:54 -0700125argp = argparse.ArgumentParser(description='Upload result to big query.')
126argp.add_argument('--bq_result_table', required=True, default=None, type=str,
127 help='Bigquery "dataset.table" to upload results to.')
128argp.add_argument('--file_to_upload', default='scenario_result.json', type=str,
129 help='Report file to upload.')
130
131args = argp.parse_args()
132
133dataset_id, table_id = args.bq_result_table.split('.', 2)
134_upload_scenario_result_to_bigquery(dataset_id, table_id, args.file_to_upload)
135print 'Successfully uploaded %s to BigQuery.\n' % args.file_to_upload