Merge pull request #12463 from yashykt/max_concurrent_streams_fix

Fix for max_concurrent_streams issue - Call mark_stream_closed beforeā€¦
diff --git a/.gitignore b/.gitignore
index 5e38f5f..5ccad2e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -16,7 +16,7 @@
 dist/
 *.egg
 py27/
-py34/
+py3[0-9]*/
 
 # Node installation output
 node_modules
diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.c b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.c
index 0d71f35..2e2b411 100644
--- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.c
+++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.c
@@ -174,7 +174,7 @@
           grpc_lb_addresses_set_address(
               *lb_addresses, i, &addr, addr_len,
               hr->is_balancer /* is_balancer */,
-              hr->is_balancer ? strdup(hr->host) : NULL /* balancer_name */,
+              hr->is_balancer ? hr->host : NULL /* balancer_name */,
               NULL /* user_data */);
           char output[INET6_ADDRSTRLEN];
           ares_inet_ntop(AF_INET6, &addr.sin6_addr, output, INET6_ADDRSTRLEN);
@@ -195,7 +195,7 @@
           grpc_lb_addresses_set_address(
               *lb_addresses, i, &addr, addr_len,
               hr->is_balancer /* is_balancer */,
-              hr->is_balancer ? strdup(hr->host) : NULL /* balancer_name */,
+              hr->is_balancer ? hr->host : NULL /* balancer_name */,
               NULL /* user_data */);
           char output[INET_ADDRSTRLEN];
           ares_inet_ntop(AF_INET, &addr.sin_addr, output, INET_ADDRSTRLEN);
diff --git a/src/core/ext/transport/chttp2/transport/flow_control.c b/src/core/ext/transport/chttp2/transport/flow_control.c
index cec99f6..39aa521 100644
--- a/src/core/ext/transport/chttp2/transport/flow_control.c
+++ b/src/core/ext/transport/chttp2/transport/flow_control.c
@@ -483,7 +483,8 @@
     if (grpc_bdp_estimator_get_bw(&tfc->bdp_estimator, &bw_dbl)) {
       // we target the max of BDP or bandwidth in microseconds.
       int32_t frame_size = (int32_t)GPR_CLAMP(
-          GPR_MAX((int32_t)bw_dbl / 1000, bdp), 16384, 16777215);
+          GPR_MAX((int32_t)GPR_CLAMP(bw_dbl, 0, INT_MAX) / 1000, bdp), 16384,
+          16777215);
       grpc_chttp2_flowctl_urgency frame_size_urgency = delta_is_significant(
           tfc, frame_size, GRPC_CHTTP2_SETTINGS_MAX_FRAME_SIZE);
       if (frame_size_urgency != GRPC_CHTTP2_FLOWCTL_NO_ACTION_NEEDED) {
diff --git a/src/core/lib/debug/stats_data_bq_schema.sql b/src/core/lib/debug/stats_data_bq_schema.sql
new file mode 100644
index 0000000..7291bbf
--- /dev/null
+++ b/src/core/lib/debug/stats_data_bq_schema.sql
@@ -0,0 +1,35 @@
+client_calls_created_per_iteration:INTEGER,
+server_calls_created_per_iteration:INTEGER,
+syscall_poll_per_iteration:INTEGER,
+syscall_wait_per_iteration:INTEGER,
+histogram_slow_lookups_per_iteration:INTEGER,
+syscall_write_per_iteration:INTEGER,
+syscall_read_per_iteration:INTEGER,
+tcp_backup_pollers_created_per_iteration:INTEGER,
+tcp_backup_poller_polls_per_iteration:INTEGER,
+http2_op_batches_per_iteration:INTEGER,
+http2_op_cancel_per_iteration:INTEGER,
+http2_op_send_initial_metadata_per_iteration:INTEGER,
+http2_op_send_message_per_iteration:INTEGER,
+http2_op_send_trailing_metadata_per_iteration:INTEGER,
+http2_op_recv_initial_metadata_per_iteration:INTEGER,
+http2_op_recv_message_per_iteration:INTEGER,
+http2_op_recv_trailing_metadata_per_iteration:INTEGER,
+http2_settings_writes_per_iteration:INTEGER,
+http2_pings_sent_per_iteration:INTEGER,
+http2_writes_begun_per_iteration:INTEGER,
+http2_writes_offloaded_per_iteration:INTEGER,
+http2_writes_continued_per_iteration:INTEGER,
+http2_partial_writes_per_iteration:INTEGER,
+combiner_locks_initiated_per_iteration:INTEGER,
+combiner_locks_scheduled_items_per_iteration:INTEGER,
+combiner_locks_scheduled_final_items_per_iteration:INTEGER,
+combiner_locks_offloaded_per_iteration:INTEGER,
+executor_scheduled_short_items_per_iteration:INTEGER,
+executor_scheduled_long_items_per_iteration:INTEGER,
+executor_scheduled_to_self_per_iteration:INTEGER,
+executor_wakeup_initiated_per_iteration:INTEGER,
+executor_queue_drained_per_iteration:INTEGER,
+executor_push_retries_per_iteration:INTEGER,
+server_requested_calls_per_iteration:INTEGER,
+server_slowpath_requests_queued_per_iteration:INTEGER
diff --git a/tools/buildgen/generate_projects.py b/tools/buildgen/generate_projects.py
index 559ea16..d29cd02 100755
--- a/tools/buildgen/generate_projects.py
+++ b/tools/buildgen/generate_projects.py
@@ -85,7 +85,7 @@
       test[out] = tf[1]
       os.close(tf[0])
       cmd.append(test[out])
-    cmd.append(root + '/' + f)
+    cmd.append(args.base + '/' + root + '/' + f)
     jobs.append(jobset.JobSpec(cmd, shortname=out, timeout_seconds=None))
 
 jobset.run(pre_jobs, maxjobs=args.jobs)
diff --git a/tools/codegen/core/gen_stats_data.py b/tools/codegen/core/gen_stats_data.py
index 8e4ef59..877a5d9 100755
--- a/tools/codegen/core/gen_stats_data.py
+++ b/tools/codegen/core/gen_stats_data.py
@@ -313,3 +313,98 @@
       len(inst_map['Histogram']), ','.join('grpc_stats_table_%d' % x for x in histo_bucket_boundaries))
   print >>C, "void (*const grpc_stats_inc_histogram[%d])(grpc_exec_ctx *exec_ctx, int x) = {%s};" % (
       len(inst_map['Histogram']), ','.join('grpc_stats_inc_%s' % histogram.name.lower() for histogram in inst_map['Histogram']))
+
+# patch qps_test bigquery schema
+RECORD_EXPLICIT_PERCENTILES = [50, 95, 99]
+
+with open('tools/run_tests/performance/scenario_result_schema.json', 'r') as f:
+  qps_schema = json.loads(f.read())
+
+def FindNamed(js, name):
+  for el in js:
+    if el['name'] == name:
+      return el
+
+def RemoveCoreFields(js):
+  new_fields = []
+  for field in js['fields']:
+    if not field['name'].startswith('core_'):
+      new_fields.append(field)
+  js['fields'] = new_fields
+
+RemoveCoreFields(FindNamed(qps_schema, 'clientStats'))
+RemoveCoreFields(FindNamed(qps_schema, 'serverStats'))
+
+def AddCoreFields(js):
+  for counter in inst_map['Counter']:
+    js['fields'].append({
+      'name': 'core_%s' % counter.name,
+      'type': 'INTEGER',
+      'mode': 'NULLABLE'
+    })
+  for histogram in inst_map['Histogram']:
+    js['fields'].append({
+      'name': 'core_%s' % histogram.name,
+      'type': 'STRING',
+      'mode': 'NULLABLE'
+    })
+    js['fields'].append({
+      'name': 'core_%s_bkts' % histogram.name,
+      'type': 'STRING',
+      'mode': 'NULLABLE'
+    })
+    for pctl in RECORD_EXPLICIT_PERCENTILES:
+      js['fields'].append({
+        'name': 'core_%s_%dp' % (histogram.name, pctl),
+        'type': 'FLOAT',
+        'mode': 'NULLABLE'
+      })
+
+AddCoreFields(FindNamed(qps_schema, 'clientStats'))
+AddCoreFields(FindNamed(qps_schema, 'serverStats'))
+
+with open('tools/run_tests/performance/scenario_result_schema.json', 'w') as f:
+  f.write(json.dumps(qps_schema, indent=2, sort_keys=True))
+
+# and generate a helper script to massage scenario results into the format we'd
+# like to query
+with open('tools/run_tests/performance/massage_qps_stats.py', 'w') as P:
+  with open(sys.argv[0]) as my_source:
+    for line in my_source:
+      if line[0] != '#': break
+    for line in my_source:
+      if line[0] == '#':
+        print >>P, line.rstrip()
+        break
+    for line in my_source:
+      if line[0] != '#':
+        break
+      print >>P, line.rstrip()
+
+  print >>P
+  print >>P, '# Autogenerated by tools/codegen/core/gen_stats_data.py'
+  print >>P
+
+  print >>P, 'import massage_qps_stats_helpers'
+
+  print >>P, 'def massage_qps_stats(scenario_result):'
+  print >>P, '  for stats in scenario_result["serverStats"] + scenario_result["clientStats"]:'
+  print >>P, '    if "coreStats" not in stats: return'
+  print >>P, '    core_stats = stats["coreStats"]'
+  print >>P, '    del stats["coreStats"]'
+  for counter in inst_map['Counter']:
+    print >>P, '    stats["core_%s"] = massage_qps_stats_helpers.counter(core_stats, "%s")' % (counter.name, counter.name)
+  for i, histogram in enumerate(inst_map['Histogram']):
+    print >>P, '    h = massage_qps_stats_helpers.histogram(core_stats, "%s")' % histogram.name
+    print >>P, '    stats["core_%s"] = ",".join("%%f" %% x for x in h.buckets)' % histogram.name
+    print >>P, '    stats["core_%s_bkts"] = ",".join("%%f" %% x for x in h.boundaries)' % histogram.name
+    for pctl in RECORD_EXPLICIT_PERCENTILES:
+      print >>P, '    stats["core_%s_%dp"] = massage_qps_stats_helpers.percentile(h.buckets, %d, h.boundaries)' % (
+          histogram.name, pctl, pctl)
+
+with open('src/core/lib/debug/stats_data_bq_schema.sql', 'w') as S:
+  columns = []
+  for counter in inst_map['Counter']:
+    columns.append(('%s_per_iteration' % counter.name, 'INTEGER'))
+  print >>S, ',\n'.join('%s:%s' % x for x in columns)
+
diff --git a/tools/run_tests/performance/bq_upload_result.py b/tools/run_tests/performance/bq_upload_result.py
index 630ac23..31819d6 100755
--- a/tools/run_tests/performance/bq_upload_result.py
+++ b/tools/run_tests/performance/bq_upload_result.py
@@ -24,6 +24,7 @@
 import sys
 import time
 import uuid
+import massage_qps_stats
 
 
 gcp_utils_dir = os.path.abspath(os.path.join(
@@ -117,6 +118,7 @@
   scenario_result['serverCpuUsage'] = scenario_result['summary'].pop('serverCpuUsage', None)
   scenario_result['summary'].pop('successfulRequestsPerSecond', None)
   scenario_result['summary'].pop('failedRequestsPerSecond', None)
+  massage_qps_stats.massage_qps_stats(scenario_result)
 
 
 def _populate_metadata_inplace(scenario_result):
diff --git a/tools/run_tests/performance/massage_qps_stats.py b/tools/run_tests/performance/massage_qps_stats.py
new file mode 100644
index 0000000..30a94ca
--- /dev/null
+++ b/tools/run_tests/performance/massage_qps_stats.py
@@ -0,0 +1,123 @@
+# 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.
+
+# Autogenerated by tools/codegen/core/gen_stats_data.py
+
+import massage_qps_stats_helpers
+def massage_qps_stats(scenario_result):
+  for stats in scenario_result["serverStats"] + scenario_result["clientStats"]:
+    if "coreStats" not in stats: return
+    core_stats = stats["coreStats"]
+    del stats["coreStats"]
+    stats["core_client_calls_created"] = massage_qps_stats_helpers.counter(core_stats, "client_calls_created")
+    stats["core_server_calls_created"] = massage_qps_stats_helpers.counter(core_stats, "server_calls_created")
+    stats["core_syscall_poll"] = massage_qps_stats_helpers.counter(core_stats, "syscall_poll")
+    stats["core_syscall_wait"] = massage_qps_stats_helpers.counter(core_stats, "syscall_wait")
+    stats["core_histogram_slow_lookups"] = massage_qps_stats_helpers.counter(core_stats, "histogram_slow_lookups")
+    stats["core_syscall_write"] = massage_qps_stats_helpers.counter(core_stats, "syscall_write")
+    stats["core_syscall_read"] = massage_qps_stats_helpers.counter(core_stats, "syscall_read")
+    stats["core_tcp_backup_pollers_created"] = massage_qps_stats_helpers.counter(core_stats, "tcp_backup_pollers_created")
+    stats["core_tcp_backup_poller_polls"] = massage_qps_stats_helpers.counter(core_stats, "tcp_backup_poller_polls")
+    stats["core_http2_op_batches"] = massage_qps_stats_helpers.counter(core_stats, "http2_op_batches")
+    stats["core_http2_op_cancel"] = massage_qps_stats_helpers.counter(core_stats, "http2_op_cancel")
+    stats["core_http2_op_send_initial_metadata"] = massage_qps_stats_helpers.counter(core_stats, "http2_op_send_initial_metadata")
+    stats["core_http2_op_send_message"] = massage_qps_stats_helpers.counter(core_stats, "http2_op_send_message")
+    stats["core_http2_op_send_trailing_metadata"] = massage_qps_stats_helpers.counter(core_stats, "http2_op_send_trailing_metadata")
+    stats["core_http2_op_recv_initial_metadata"] = massage_qps_stats_helpers.counter(core_stats, "http2_op_recv_initial_metadata")
+    stats["core_http2_op_recv_message"] = massage_qps_stats_helpers.counter(core_stats, "http2_op_recv_message")
+    stats["core_http2_op_recv_trailing_metadata"] = massage_qps_stats_helpers.counter(core_stats, "http2_op_recv_trailing_metadata")
+    stats["core_http2_settings_writes"] = massage_qps_stats_helpers.counter(core_stats, "http2_settings_writes")
+    stats["core_http2_pings_sent"] = massage_qps_stats_helpers.counter(core_stats, "http2_pings_sent")
+    stats["core_http2_writes_begun"] = massage_qps_stats_helpers.counter(core_stats, "http2_writes_begun")
+    stats["core_http2_writes_offloaded"] = massage_qps_stats_helpers.counter(core_stats, "http2_writes_offloaded")
+    stats["core_http2_writes_continued"] = massage_qps_stats_helpers.counter(core_stats, "http2_writes_continued")
+    stats["core_http2_partial_writes"] = massage_qps_stats_helpers.counter(core_stats, "http2_partial_writes")
+    stats["core_combiner_locks_initiated"] = massage_qps_stats_helpers.counter(core_stats, "combiner_locks_initiated")
+    stats["core_combiner_locks_scheduled_items"] = massage_qps_stats_helpers.counter(core_stats, "combiner_locks_scheduled_items")
+    stats["core_combiner_locks_scheduled_final_items"] = massage_qps_stats_helpers.counter(core_stats, "combiner_locks_scheduled_final_items")
+    stats["core_combiner_locks_offloaded"] = massage_qps_stats_helpers.counter(core_stats, "combiner_locks_offloaded")
+    stats["core_executor_scheduled_short_items"] = massage_qps_stats_helpers.counter(core_stats, "executor_scheduled_short_items")
+    stats["core_executor_scheduled_long_items"] = massage_qps_stats_helpers.counter(core_stats, "executor_scheduled_long_items")
+    stats["core_executor_scheduled_to_self"] = massage_qps_stats_helpers.counter(core_stats, "executor_scheduled_to_self")
+    stats["core_executor_wakeup_initiated"] = massage_qps_stats_helpers.counter(core_stats, "executor_wakeup_initiated")
+    stats["core_executor_queue_drained"] = massage_qps_stats_helpers.counter(core_stats, "executor_queue_drained")
+    stats["core_executor_push_retries"] = massage_qps_stats_helpers.counter(core_stats, "executor_push_retries")
+    stats["core_server_requested_calls"] = massage_qps_stats_helpers.counter(core_stats, "server_requested_calls")
+    stats["core_server_slowpath_requests_queued"] = massage_qps_stats_helpers.counter(core_stats, "server_slowpath_requests_queued")
+    h = massage_qps_stats_helpers.histogram(core_stats, "tcp_write_size")
+    stats["core_tcp_write_size"] = ",".join("%f" % x for x in h.buckets)
+    stats["core_tcp_write_size_bkts"] = ",".join("%f" % x for x in h.boundaries)
+    stats["core_tcp_write_size_50p"] = massage_qps_stats_helpers.percentile(h.buckets, 50, h.boundaries)
+    stats["core_tcp_write_size_95p"] = massage_qps_stats_helpers.percentile(h.buckets, 95, h.boundaries)
+    stats["core_tcp_write_size_99p"] = massage_qps_stats_helpers.percentile(h.buckets, 99, h.boundaries)
+    h = massage_qps_stats_helpers.histogram(core_stats, "tcp_write_iov_size")
+    stats["core_tcp_write_iov_size"] = ",".join("%f" % x for x in h.buckets)
+    stats["core_tcp_write_iov_size_bkts"] = ",".join("%f" % x for x in h.boundaries)
+    stats["core_tcp_write_iov_size_50p"] = massage_qps_stats_helpers.percentile(h.buckets, 50, h.boundaries)
+    stats["core_tcp_write_iov_size_95p"] = massage_qps_stats_helpers.percentile(h.buckets, 95, h.boundaries)
+    stats["core_tcp_write_iov_size_99p"] = massage_qps_stats_helpers.percentile(h.buckets, 99, h.boundaries)
+    h = massage_qps_stats_helpers.histogram(core_stats, "tcp_read_size")
+    stats["core_tcp_read_size"] = ",".join("%f" % x for x in h.buckets)
+    stats["core_tcp_read_size_bkts"] = ",".join("%f" % x for x in h.boundaries)
+    stats["core_tcp_read_size_50p"] = massage_qps_stats_helpers.percentile(h.buckets, 50, h.boundaries)
+    stats["core_tcp_read_size_95p"] = massage_qps_stats_helpers.percentile(h.buckets, 95, h.boundaries)
+    stats["core_tcp_read_size_99p"] = massage_qps_stats_helpers.percentile(h.buckets, 99, h.boundaries)
+    h = massage_qps_stats_helpers.histogram(core_stats, "tcp_read_offer")
+    stats["core_tcp_read_offer"] = ",".join("%f" % x for x in h.buckets)
+    stats["core_tcp_read_offer_bkts"] = ",".join("%f" % x for x in h.boundaries)
+    stats["core_tcp_read_offer_50p"] = massage_qps_stats_helpers.percentile(h.buckets, 50, h.boundaries)
+    stats["core_tcp_read_offer_95p"] = massage_qps_stats_helpers.percentile(h.buckets, 95, h.boundaries)
+    stats["core_tcp_read_offer_99p"] = massage_qps_stats_helpers.percentile(h.buckets, 99, h.boundaries)
+    h = massage_qps_stats_helpers.histogram(core_stats, "tcp_read_offer_iov_size")
+    stats["core_tcp_read_offer_iov_size"] = ",".join("%f" % x for x in h.buckets)
+    stats["core_tcp_read_offer_iov_size_bkts"] = ",".join("%f" % x for x in h.boundaries)
+    stats["core_tcp_read_offer_iov_size_50p"] = massage_qps_stats_helpers.percentile(h.buckets, 50, h.boundaries)
+    stats["core_tcp_read_offer_iov_size_95p"] = massage_qps_stats_helpers.percentile(h.buckets, 95, h.boundaries)
+    stats["core_tcp_read_offer_iov_size_99p"] = massage_qps_stats_helpers.percentile(h.buckets, 99, h.boundaries)
+    h = massage_qps_stats_helpers.histogram(core_stats, "http2_send_message_size")
+    stats["core_http2_send_message_size"] = ",".join("%f" % x for x in h.buckets)
+    stats["core_http2_send_message_size_bkts"] = ",".join("%f" % x for x in h.boundaries)
+    stats["core_http2_send_message_size_50p"] = massage_qps_stats_helpers.percentile(h.buckets, 50, h.boundaries)
+    stats["core_http2_send_message_size_95p"] = massage_qps_stats_helpers.percentile(h.buckets, 95, h.boundaries)
+    stats["core_http2_send_message_size_99p"] = massage_qps_stats_helpers.percentile(h.buckets, 99, h.boundaries)
+    h = massage_qps_stats_helpers.histogram(core_stats, "http2_send_initial_metadata_per_write")
+    stats["core_http2_send_initial_metadata_per_write"] = ",".join("%f" % x for x in h.buckets)
+    stats["core_http2_send_initial_metadata_per_write_bkts"] = ",".join("%f" % x for x in h.boundaries)
+    stats["core_http2_send_initial_metadata_per_write_50p"] = massage_qps_stats_helpers.percentile(h.buckets, 50, h.boundaries)
+    stats["core_http2_send_initial_metadata_per_write_95p"] = massage_qps_stats_helpers.percentile(h.buckets, 95, h.boundaries)
+    stats["core_http2_send_initial_metadata_per_write_99p"] = massage_qps_stats_helpers.percentile(h.buckets, 99, h.boundaries)
+    h = massage_qps_stats_helpers.histogram(core_stats, "http2_send_message_per_write")
+    stats["core_http2_send_message_per_write"] = ",".join("%f" % x for x in h.buckets)
+    stats["core_http2_send_message_per_write_bkts"] = ",".join("%f" % x for x in h.boundaries)
+    stats["core_http2_send_message_per_write_50p"] = massage_qps_stats_helpers.percentile(h.buckets, 50, h.boundaries)
+    stats["core_http2_send_message_per_write_95p"] = massage_qps_stats_helpers.percentile(h.buckets, 95, h.boundaries)
+    stats["core_http2_send_message_per_write_99p"] = massage_qps_stats_helpers.percentile(h.buckets, 99, h.boundaries)
+    h = massage_qps_stats_helpers.histogram(core_stats, "http2_send_trailing_metadata_per_write")
+    stats["core_http2_send_trailing_metadata_per_write"] = ",".join("%f" % x for x in h.buckets)
+    stats["core_http2_send_trailing_metadata_per_write_bkts"] = ",".join("%f" % x for x in h.boundaries)
+    stats["core_http2_send_trailing_metadata_per_write_50p"] = massage_qps_stats_helpers.percentile(h.buckets, 50, h.boundaries)
+    stats["core_http2_send_trailing_metadata_per_write_95p"] = massage_qps_stats_helpers.percentile(h.buckets, 95, h.boundaries)
+    stats["core_http2_send_trailing_metadata_per_write_99p"] = massage_qps_stats_helpers.percentile(h.buckets, 99, h.boundaries)
+    h = massage_qps_stats_helpers.histogram(core_stats, "http2_send_flowctl_per_write")
+    stats["core_http2_send_flowctl_per_write"] = ",".join("%f" % x for x in h.buckets)
+    stats["core_http2_send_flowctl_per_write_bkts"] = ",".join("%f" % x for x in h.boundaries)
+    stats["core_http2_send_flowctl_per_write_50p"] = massage_qps_stats_helpers.percentile(h.buckets, 50, h.boundaries)
+    stats["core_http2_send_flowctl_per_write_95p"] = massage_qps_stats_helpers.percentile(h.buckets, 95, h.boundaries)
+    stats["core_http2_send_flowctl_per_write_99p"] = massage_qps_stats_helpers.percentile(h.buckets, 99, h.boundaries)
+    h = massage_qps_stats_helpers.histogram(core_stats, "server_cqs_checked")
+    stats["core_server_cqs_checked"] = ",".join("%f" % x for x in h.buckets)
+    stats["core_server_cqs_checked_bkts"] = ",".join("%f" % x for x in h.boundaries)
+    stats["core_server_cqs_checked_50p"] = massage_qps_stats_helpers.percentile(h.buckets, 50, h.boundaries)
+    stats["core_server_cqs_checked_95p"] = massage_qps_stats_helpers.percentile(h.buckets, 95, h.boundaries)
+    stats["core_server_cqs_checked_99p"] = massage_qps_stats_helpers.percentile(h.buckets, 99, h.boundaries)
diff --git a/tools/run_tests/performance/massage_qps_stats_helpers.py b/tools/run_tests/performance/massage_qps_stats_helpers.py
new file mode 100644
index 0000000..400a0c8
--- /dev/null
+++ b/tools/run_tests/performance/massage_qps_stats_helpers.py
@@ -0,0 +1,57 @@
+# 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.
+
+import collections
+
+def _threshold_for_count_below(buckets, boundaries, count_below):
+  count_so_far = 0
+  for lower_idx in range(0, len(buckets)):
+    count_so_far += buckets[lower_idx]
+    if count_so_far >= count_below:
+      break
+  if count_so_far == count_below:
+    # this bucket hits the threshold exactly... we should be midway through
+    # any run of zero values following the bucket
+    for upper_idx in range(lower_idx + 1, num_buckets):
+      if buckets[upper_idx] != 0:
+        break
+    return (boundaries[lower_idx] + boundaries[upper_idx]) / 2.0
+  else:
+    # treat values as uniform throughout the bucket, and find where this value
+    # should lie
+    lower_bound = boundaries[lower_idx]
+    upper_bound = boundaries[lower_idx + 1]
+    return (upper_bound -
+           (upper_bound - lower_bound) * (count_so_far - count_below) /
+               float(buckets[lower_idx]))
+
+def percentile(buckets, pctl, boundaries):
+  return _threshold_for_count_below(
+      buckets, boundaries, sum(buckets) * pctl / 100.0)
+
+def counter(core_stats, name):
+  for stat in core_stats['metrics']:
+    if stat['name'] == name:
+      return int(stat.get('count', 0))
+
+Histogram = collections.namedtuple('Histogram', 'buckets boundaries')
+def histogram(core_stats, name):
+  for stat in core_stats['metrics']:
+    if stat['name'] == name:
+      buckets = []
+      boundaries = []
+      for b in stat['histogram']['buckets']:
+        buckets.append(int(b.get('count', 0)))
+        boundaries.append(int(b.get('start', 0)))
+  return Histogram(buckets=buckets, boundaries=boundaries)
diff --git a/tools/run_tests/performance/scenario_result_schema.json b/tools/run_tests/performance/scenario_result_schema.json
index d7e2e29..84b3cb7 100644
--- a/tools/run_tests/performance/scenario_result_schema.json
+++ b/tools/run_tests/performance/scenario_result_schema.json
@@ -1,269 +1,1169 @@
 [
   {
-    "name": "metadata",
-    "type": "RECORD",
-    "mode": "NULLABLE",
     "fields": [
       {
-        "name": "buildNumber",
-        "type": "INTEGER",
-        "mode": "NULLABLE"
-      },
+        "mode": "NULLABLE", 
+        "name": "buildNumber", 
+        "type": "INTEGER"
+      }, 
       {
-        "name": "buildUrl",
-        "type": "STRING",
-        "mode": "NULLABLE"
-      },
+        "mode": "NULLABLE", 
+        "name": "buildUrl", 
+        "type": "STRING"
+      }, 
       {
-        "name": "jobName",
-        "type": "STRING",
-        "mode": "NULLABLE"
-      },
+        "mode": "NULLABLE", 
+        "name": "jobName", 
+        "type": "STRING"
+      }, 
       {
-        "name": "gitCommit",
-        "type": "STRING",
-        "mode": "NULLABLE"
-      },
+        "mode": "NULLABLE", 
+        "name": "gitCommit", 
+        "type": "STRING"
+      }, 
       {
-        "name": "gitActualCommit",
-        "type": "STRING",
-        "mode": "NULLABLE"
-      },
+        "mode": "NULLABLE", 
+        "name": "gitActualCommit", 
+        "type": "STRING"
+      }, 
       {
-        "name": "created",
-        "type": "TIMESTAMP",
-        "mode": "NULLABLE"
+        "mode": "NULLABLE", 
+        "name": "created", 
+        "type": "TIMESTAMP"
       }
-    ]
-  },
+    ], 
+    "mode": "NULLABLE", 
+    "name": "metadata", 
+    "type": "RECORD"
+  }, 
   {
-    "name": "scenario",
-    "type": "RECORD",
-    "mode": "NULLABLE",
     "fields": [
       {
-        "name": "name",
-        "type": "STRING",
-        "mode": "NULLABLE"
-      },
+        "mode": "NULLABLE", 
+        "name": "name", 
+        "type": "STRING"
+      }, 
       {
-        "name": "clientConfig",
-        "type": "STRING",
-        "mode": "NULLABLE"
-      },
+        "mode": "NULLABLE", 
+        "name": "clientConfig", 
+        "type": "STRING"
+      }, 
       {
-        "name": "numClients",
-        "type": "INTEGER",
-        "mode": "NULLABLE"
-      },
+        "mode": "NULLABLE", 
+        "name": "numClients", 
+        "type": "INTEGER"
+      }, 
       {
-        "name": "serverConfig",
-        "type": "STRING",
-        "mode": "NULLABLE"
-      },
+        "mode": "NULLABLE", 
+        "name": "serverConfig", 
+        "type": "STRING"
+      }, 
       {
-        "name": "numServers",
-        "type": "INTEGER",
-        "mode": "NULLABLE"
-      },
+        "mode": "NULLABLE", 
+        "name": "numServers", 
+        "type": "INTEGER"
+      }, 
       {
-        "name": "warmupSeconds",
-        "type": "INTEGER",
-        "mode": "NULLABLE"
-      },
+        "mode": "NULLABLE", 
+        "name": "warmupSeconds", 
+        "type": "INTEGER"
+      }, 
       {
-        "name": "benchmarkSeconds",
-        "type": "INTEGER",
-        "mode": "NULLABLE"
+        "mode": "NULLABLE", 
+        "name": "benchmarkSeconds", 
+        "type": "INTEGER"
       }
-    ]
-  },
+    ], 
+    "mode": "NULLABLE", 
+    "name": "scenario", 
+    "type": "RECORD"
+  }, 
   {
-    "name": "latencies",
-    "type": "STRING",
-    "mode": "NULLABLE"
-  },
+    "mode": "NULLABLE", 
+    "name": "latencies", 
+    "type": "STRING"
+  }, 
   {
-    "name": "clientStats",
-    "type": "RECORD",
-    "mode": "REPEATED",
     "fields": [
       {
-        "name": "latencies",
-        "type": "STRING",
-        "mode": "NULLABLE"
-      },
+        "mode": "NULLABLE", 
+        "name": "latencies", 
+        "type": "STRING"
+      }, 
       {
-        "name": "timeElapsed",
-        "type": "FLOAT",
-        "mode": "NULLABLE"
-      },
+        "mode": "NULLABLE", 
+        "name": "timeElapsed", 
+        "type": "FLOAT"
+      }, 
       {
-        "name": "timeUser",
-        "type": "FLOAT",
-        "mode": "NULLABLE"
-      },
+        "mode": "NULLABLE", 
+        "name": "timeUser", 
+        "type": "FLOAT"
+      }, 
       {
-        "name": "timeSystem",
-        "type": "FLOAT",
-        "mode": "NULLABLE"
-      },
+        "mode": "NULLABLE", 
+        "name": "timeSystem", 
+        "type": "FLOAT"
+      }, 
       {
-        "name": "cqPollCount",
-        "type": "INTEGER",
-        "mode": "NULLABLE"
+        "mode": "NULLABLE", 
+        "name": "cqPollCount", 
+        "type": "INTEGER"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_client_calls_created", 
+        "type": "INTEGER"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_server_calls_created", 
+        "type": "INTEGER"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_syscall_poll", 
+        "type": "INTEGER"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_syscall_wait", 
+        "type": "INTEGER"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_histogram_slow_lookups", 
+        "type": "INTEGER"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_syscall_write", 
+        "type": "INTEGER"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_syscall_read", 
+        "type": "INTEGER"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_tcp_backup_pollers_created", 
+        "type": "INTEGER"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_tcp_backup_poller_polls", 
+        "type": "INTEGER"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_http2_op_batches", 
+        "type": "INTEGER"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_http2_op_cancel", 
+        "type": "INTEGER"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_http2_op_send_initial_metadata", 
+        "type": "INTEGER"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_http2_op_send_message", 
+        "type": "INTEGER"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_http2_op_send_trailing_metadata", 
+        "type": "INTEGER"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_http2_op_recv_initial_metadata", 
+        "type": "INTEGER"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_http2_op_recv_message", 
+        "type": "INTEGER"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_http2_op_recv_trailing_metadata", 
+        "type": "INTEGER"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_http2_settings_writes", 
+        "type": "INTEGER"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_http2_pings_sent", 
+        "type": "INTEGER"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_http2_writes_begun", 
+        "type": "INTEGER"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_http2_writes_offloaded", 
+        "type": "INTEGER"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_http2_writes_continued", 
+        "type": "INTEGER"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_http2_partial_writes", 
+        "type": "INTEGER"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_combiner_locks_initiated", 
+        "type": "INTEGER"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_combiner_locks_scheduled_items", 
+        "type": "INTEGER"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_combiner_locks_scheduled_final_items", 
+        "type": "INTEGER"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_combiner_locks_offloaded", 
+        "type": "INTEGER"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_executor_scheduled_short_items", 
+        "type": "INTEGER"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_executor_scheduled_long_items", 
+        "type": "INTEGER"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_executor_scheduled_to_self", 
+        "type": "INTEGER"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_executor_wakeup_initiated", 
+        "type": "INTEGER"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_executor_queue_drained", 
+        "type": "INTEGER"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_executor_push_retries", 
+        "type": "INTEGER"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_server_requested_calls", 
+        "type": "INTEGER"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_server_slowpath_requests_queued", 
+        "type": "INTEGER"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_tcp_write_size", 
+        "type": "STRING"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_tcp_write_size_bkts", 
+        "type": "STRING"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_tcp_write_size_50p", 
+        "type": "FLOAT"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_tcp_write_size_95p", 
+        "type": "FLOAT"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_tcp_write_size_99p", 
+        "type": "FLOAT"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_tcp_write_iov_size", 
+        "type": "STRING"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_tcp_write_iov_size_bkts", 
+        "type": "STRING"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_tcp_write_iov_size_50p", 
+        "type": "FLOAT"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_tcp_write_iov_size_95p", 
+        "type": "FLOAT"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_tcp_write_iov_size_99p", 
+        "type": "FLOAT"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_tcp_read_size", 
+        "type": "STRING"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_tcp_read_size_bkts", 
+        "type": "STRING"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_tcp_read_size_50p", 
+        "type": "FLOAT"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_tcp_read_size_95p", 
+        "type": "FLOAT"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_tcp_read_size_99p", 
+        "type": "FLOAT"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_tcp_read_offer", 
+        "type": "STRING"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_tcp_read_offer_bkts", 
+        "type": "STRING"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_tcp_read_offer_50p", 
+        "type": "FLOAT"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_tcp_read_offer_95p", 
+        "type": "FLOAT"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_tcp_read_offer_99p", 
+        "type": "FLOAT"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_tcp_read_offer_iov_size", 
+        "type": "STRING"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_tcp_read_offer_iov_size_bkts", 
+        "type": "STRING"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_tcp_read_offer_iov_size_50p", 
+        "type": "FLOAT"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_tcp_read_offer_iov_size_95p", 
+        "type": "FLOAT"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_tcp_read_offer_iov_size_99p", 
+        "type": "FLOAT"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_http2_send_message_size", 
+        "type": "STRING"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_http2_send_message_size_bkts", 
+        "type": "STRING"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_http2_send_message_size_50p", 
+        "type": "FLOAT"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_http2_send_message_size_95p", 
+        "type": "FLOAT"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_http2_send_message_size_99p", 
+        "type": "FLOAT"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_http2_send_initial_metadata_per_write", 
+        "type": "STRING"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_http2_send_initial_metadata_per_write_bkts", 
+        "type": "STRING"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_http2_send_initial_metadata_per_write_50p", 
+        "type": "FLOAT"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_http2_send_initial_metadata_per_write_95p", 
+        "type": "FLOAT"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_http2_send_initial_metadata_per_write_99p", 
+        "type": "FLOAT"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_http2_send_message_per_write", 
+        "type": "STRING"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_http2_send_message_per_write_bkts", 
+        "type": "STRING"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_http2_send_message_per_write_50p", 
+        "type": "FLOAT"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_http2_send_message_per_write_95p", 
+        "type": "FLOAT"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_http2_send_message_per_write_99p", 
+        "type": "FLOAT"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_http2_send_trailing_metadata_per_write", 
+        "type": "STRING"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_http2_send_trailing_metadata_per_write_bkts", 
+        "type": "STRING"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_http2_send_trailing_metadata_per_write_50p", 
+        "type": "FLOAT"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_http2_send_trailing_metadata_per_write_95p", 
+        "type": "FLOAT"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_http2_send_trailing_metadata_per_write_99p", 
+        "type": "FLOAT"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_http2_send_flowctl_per_write", 
+        "type": "STRING"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_http2_send_flowctl_per_write_bkts", 
+        "type": "STRING"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_http2_send_flowctl_per_write_50p", 
+        "type": "FLOAT"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_http2_send_flowctl_per_write_95p", 
+        "type": "FLOAT"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_http2_send_flowctl_per_write_99p", 
+        "type": "FLOAT"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_server_cqs_checked", 
+        "type": "STRING"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_server_cqs_checked_bkts", 
+        "type": "STRING"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_server_cqs_checked_50p", 
+        "type": "FLOAT"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_server_cqs_checked_95p", 
+        "type": "FLOAT"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_server_cqs_checked_99p", 
+        "type": "FLOAT"
       }
-    ]
-  },
+    ], 
+    "mode": "REPEATED", 
+    "name": "clientStats", 
+    "type": "RECORD"
+  }, 
   {
-    "name": "serverStats",
-    "type": "RECORD",
-    "mode": "REPEATED",
     "fields": [
       {
-        "name": "timeElapsed",
-        "type": "FLOAT",
-        "mode": "NULLABLE"
-      },
+        "mode": "NULLABLE", 
+        "name": "timeElapsed", 
+        "type": "FLOAT"
+      }, 
       {
-        "name": "timeUser",
-        "type": "FLOAT",
-        "mode": "NULLABLE"
-      },
+        "mode": "NULLABLE", 
+        "name": "timeUser", 
+        "type": "FLOAT"
+      }, 
       {
-        "name": "timeSystem",
-        "type": "FLOAT",
-        "mode": "NULLABLE"
-      },
+        "mode": "NULLABLE", 
+        "name": "timeSystem", 
+        "type": "FLOAT"
+      }, 
       {
-        "name": "cqPollCount",
-        "type": "INTEGER",
-        "mode": "NULLABLE"
+        "mode": "NULLABLE", 
+        "name": "cqPollCount", 
+        "type": "INTEGER"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_client_calls_created", 
+        "type": "INTEGER"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_server_calls_created", 
+        "type": "INTEGER"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_syscall_poll", 
+        "type": "INTEGER"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_syscall_wait", 
+        "type": "INTEGER"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_histogram_slow_lookups", 
+        "type": "INTEGER"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_syscall_write", 
+        "type": "INTEGER"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_syscall_read", 
+        "type": "INTEGER"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_tcp_backup_pollers_created", 
+        "type": "INTEGER"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_tcp_backup_poller_polls", 
+        "type": "INTEGER"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_http2_op_batches", 
+        "type": "INTEGER"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_http2_op_cancel", 
+        "type": "INTEGER"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_http2_op_send_initial_metadata", 
+        "type": "INTEGER"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_http2_op_send_message", 
+        "type": "INTEGER"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_http2_op_send_trailing_metadata", 
+        "type": "INTEGER"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_http2_op_recv_initial_metadata", 
+        "type": "INTEGER"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_http2_op_recv_message", 
+        "type": "INTEGER"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_http2_op_recv_trailing_metadata", 
+        "type": "INTEGER"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_http2_settings_writes", 
+        "type": "INTEGER"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_http2_pings_sent", 
+        "type": "INTEGER"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_http2_writes_begun", 
+        "type": "INTEGER"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_http2_writes_offloaded", 
+        "type": "INTEGER"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_http2_writes_continued", 
+        "type": "INTEGER"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_http2_partial_writes", 
+        "type": "INTEGER"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_combiner_locks_initiated", 
+        "type": "INTEGER"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_combiner_locks_scheduled_items", 
+        "type": "INTEGER"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_combiner_locks_scheduled_final_items", 
+        "type": "INTEGER"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_combiner_locks_offloaded", 
+        "type": "INTEGER"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_executor_scheduled_short_items", 
+        "type": "INTEGER"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_executor_scheduled_long_items", 
+        "type": "INTEGER"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_executor_scheduled_to_self", 
+        "type": "INTEGER"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_executor_wakeup_initiated", 
+        "type": "INTEGER"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_executor_queue_drained", 
+        "type": "INTEGER"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_executor_push_retries", 
+        "type": "INTEGER"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_server_requested_calls", 
+        "type": "INTEGER"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_server_slowpath_requests_queued", 
+        "type": "INTEGER"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_tcp_write_size", 
+        "type": "STRING"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_tcp_write_size_bkts", 
+        "type": "STRING"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_tcp_write_size_50p", 
+        "type": "FLOAT"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_tcp_write_size_95p", 
+        "type": "FLOAT"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_tcp_write_size_99p", 
+        "type": "FLOAT"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_tcp_write_iov_size", 
+        "type": "STRING"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_tcp_write_iov_size_bkts", 
+        "type": "STRING"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_tcp_write_iov_size_50p", 
+        "type": "FLOAT"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_tcp_write_iov_size_95p", 
+        "type": "FLOAT"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_tcp_write_iov_size_99p", 
+        "type": "FLOAT"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_tcp_read_size", 
+        "type": "STRING"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_tcp_read_size_bkts", 
+        "type": "STRING"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_tcp_read_size_50p", 
+        "type": "FLOAT"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_tcp_read_size_95p", 
+        "type": "FLOAT"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_tcp_read_size_99p", 
+        "type": "FLOAT"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_tcp_read_offer", 
+        "type": "STRING"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_tcp_read_offer_bkts", 
+        "type": "STRING"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_tcp_read_offer_50p", 
+        "type": "FLOAT"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_tcp_read_offer_95p", 
+        "type": "FLOAT"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_tcp_read_offer_99p", 
+        "type": "FLOAT"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_tcp_read_offer_iov_size", 
+        "type": "STRING"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_tcp_read_offer_iov_size_bkts", 
+        "type": "STRING"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_tcp_read_offer_iov_size_50p", 
+        "type": "FLOAT"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_tcp_read_offer_iov_size_95p", 
+        "type": "FLOAT"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_tcp_read_offer_iov_size_99p", 
+        "type": "FLOAT"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_http2_send_message_size", 
+        "type": "STRING"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_http2_send_message_size_bkts", 
+        "type": "STRING"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_http2_send_message_size_50p", 
+        "type": "FLOAT"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_http2_send_message_size_95p", 
+        "type": "FLOAT"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_http2_send_message_size_99p", 
+        "type": "FLOAT"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_http2_send_initial_metadata_per_write", 
+        "type": "STRING"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_http2_send_initial_metadata_per_write_bkts", 
+        "type": "STRING"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_http2_send_initial_metadata_per_write_50p", 
+        "type": "FLOAT"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_http2_send_initial_metadata_per_write_95p", 
+        "type": "FLOAT"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_http2_send_initial_metadata_per_write_99p", 
+        "type": "FLOAT"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_http2_send_message_per_write", 
+        "type": "STRING"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_http2_send_message_per_write_bkts", 
+        "type": "STRING"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_http2_send_message_per_write_50p", 
+        "type": "FLOAT"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_http2_send_message_per_write_95p", 
+        "type": "FLOAT"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_http2_send_message_per_write_99p", 
+        "type": "FLOAT"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_http2_send_trailing_metadata_per_write", 
+        "type": "STRING"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_http2_send_trailing_metadata_per_write_bkts", 
+        "type": "STRING"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_http2_send_trailing_metadata_per_write_50p", 
+        "type": "FLOAT"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_http2_send_trailing_metadata_per_write_95p", 
+        "type": "FLOAT"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_http2_send_trailing_metadata_per_write_99p", 
+        "type": "FLOAT"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_http2_send_flowctl_per_write", 
+        "type": "STRING"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_http2_send_flowctl_per_write_bkts", 
+        "type": "STRING"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_http2_send_flowctl_per_write_50p", 
+        "type": "FLOAT"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_http2_send_flowctl_per_write_95p", 
+        "type": "FLOAT"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_http2_send_flowctl_per_write_99p", 
+        "type": "FLOAT"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_server_cqs_checked", 
+        "type": "STRING"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_server_cqs_checked_bkts", 
+        "type": "STRING"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_server_cqs_checked_50p", 
+        "type": "FLOAT"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_server_cqs_checked_95p", 
+        "type": "FLOAT"
+      }, 
+      {
+        "mode": "NULLABLE", 
+        "name": "core_server_cqs_checked_99p", 
+        "type": "FLOAT"
       }
-    ]
-  },
+    ], 
+    "mode": "REPEATED", 
+    "name": "serverStats", 
+    "type": "RECORD"
+  }, 
   {
-    "name": "serverCores",
-    "type": "STRING",
-    "mode": "NULLABLE"
-  },
+    "mode": "NULLABLE", 
+    "name": "serverCores", 
+    "type": "STRING"
+  }, 
   {
-    "name": "summary",
-    "type": "RECORD",
-    "mode": "NULLABLE",
     "fields": [
       {
-        "name": "qps",
-        "type": "FLOAT",
-        "mode": "NULLABLE"
-      },
+        "mode": "NULLABLE", 
+        "name": "qps", 
+        "type": "FLOAT"
+      }, 
       {
-        "name": "qpsPerServerCore",
-        "type": "FLOAT",
-        "mode": "NULLABLE"
-      },
+        "mode": "NULLABLE", 
+        "name": "qpsPerServerCore", 
+        "type": "FLOAT"
+      }, 
       {
-        "name": "serverSystemTime",
-        "type": "FLOAT",
-        "mode": "NULLABLE"
-      },
+        "mode": "NULLABLE", 
+        "name": "serverSystemTime", 
+        "type": "FLOAT"
+      }, 
       {
-        "name": "serverUserTime",
-        "type": "FLOAT",
-        "mode": "NULLABLE"
-      },
+        "mode": "NULLABLE", 
+        "name": "serverUserTime", 
+        "type": "FLOAT"
+      }, 
       {
-        "name": "clientSystemTime",
-        "type": "FLOAT",
-        "mode": "NULLABLE"
-      },
+        "mode": "NULLABLE", 
+        "name": "clientSystemTime", 
+        "type": "FLOAT"
+      }, 
       {
-        "name": "clientUserTime",
-        "type": "FLOAT",
-        "mode": "NULLABLE"
-      },
+        "mode": "NULLABLE", 
+        "name": "clientUserTime", 
+        "type": "FLOAT"
+      }, 
       {
-        "name": "latency50",
-        "type": "FLOAT",
-        "mode": "NULLABLE"
-      },
+        "mode": "NULLABLE", 
+        "name": "latency50", 
+        "type": "FLOAT"
+      }, 
       {
-        "name": "latency90",
-        "type": "FLOAT",
-        "mode": "NULLABLE"
-      },
+        "mode": "NULLABLE", 
+        "name": "latency90", 
+        "type": "FLOAT"
+      }, 
       {
-        "name": "latency95",
-        "type": "FLOAT",
-        "mode": "NULLABLE"
-      },
+        "mode": "NULLABLE", 
+        "name": "latency95", 
+        "type": "FLOAT"
+      }, 
       {
-        "name": "latency99",
-        "type": "FLOAT",
-        "mode": "NULLABLE"
-      },
+        "mode": "NULLABLE", 
+        "name": "latency99", 
+        "type": "FLOAT"
+      }, 
       {
-        "name": "latency999",
-        "type": "FLOAT",
-        "mode": "NULLABLE"
-      },
+        "mode": "NULLABLE", 
+        "name": "latency999", 
+        "type": "FLOAT"
+      }, 
       {
-        "name": "clientPollsPerRequest",
-        "type": "FLOAT",
-        "mode": "NULLABLE"
-      },
+        "mode": "NULLABLE", 
+        "name": "clientPollsPerRequest", 
+        "type": "FLOAT"
+      }, 
       {
-        "name": "serverPollsPerRequest",
-        "type": "FLOAT",
-        "mode": "NULLABLE"
-      },
+        "mode": "NULLABLE", 
+        "name": "serverPollsPerRequest", 
+        "type": "FLOAT"
+      }, 
       {
-        "name": "serverQueriesPerCpuSec",
-        "type": "FLOAT",
-        "mode": "NULLABLE"
-      },
+        "mode": "NULLABLE", 
+        "name": "serverQueriesPerCpuSec", 
+        "type": "FLOAT"
+      }, 
       {
-        "name": "clientQueriesPerCpuSec",
-        "type": "FLOAT",
-        "mode": "NULLABLE"
+        "mode": "NULLABLE", 
+        "name": "clientQueriesPerCpuSec", 
+        "type": "FLOAT"
       }
-    ]
-  },
+    ], 
+    "mode": "NULLABLE", 
+    "name": "summary", 
+    "type": "RECORD"
+  }, 
   {
-    "name": "clientSuccess",
-    "type": "STRING",
-    "mode": "NULLABLE"
-  },
+    "mode": "NULLABLE", 
+    "name": "clientSuccess", 
+    "type": "STRING"
+  }, 
   {
-    "name": "serverSuccess",
-    "type": "STRING",
-    "mode": "NULLABLE"
-  },
+    "mode": "NULLABLE", 
+    "name": "serverSuccess", 
+    "type": "STRING"
+  }, 
   {
-    "name": "requestResults",
-    "type": "STRING",
-    "mode": "NULLABLE"
-  },
+    "mode": "NULLABLE", 
+    "name": "requestResults", 
+    "type": "STRING"
+  }, 
   {
-    "name": "serverCpuStats",
-    "type": "RECORD",
-    "mode": "REPEATED",
     "fields": [
       {
-        "name": "totalCpuTime",
-        "type": "INTEGER",
-        "mode": "NULLABLE"
-      },
+        "mode": "NULLABLE", 
+        "name": "totalCpuTime", 
+        "type": "INTEGER"
+      }, 
       {
-        "name": "idleCpuTime",
-        "type": "INTEGER",
-        "mode": "NULLABLE"
+        "mode": "NULLABLE", 
+        "name": "idleCpuTime", 
+        "type": "INTEGER"
       }
-    ]
-  },
+    ], 
+    "mode": "REPEATED", 
+    "name": "serverCpuStats", 
+    "type": "RECORD"
+  }, 
   {
-    "name": "serverCpuUsage",
-    "type": "FLOAT",
-    "mode": "NULLABLE"
+    "mode": "NULLABLE", 
+    "name": "serverCpuUsage", 
+    "type": "FLOAT"
   }
-]
+]
\ No newline at end of file
diff --git a/tools/run_tests/python_utils/jobset.py b/tools/run_tests/python_utils/jobset.py
index 08d652a..80e7944 100755
--- a/tools/run_tests/python_utils/jobset.py
+++ b/tools/run_tests/python_utils/jobset.py
@@ -224,7 +224,7 @@
     self.retries = 0
     self.message = ''
     self.cpu_estimated = 1
-    self.cpu_measured = 0
+    self.cpu_measured = 1
 
 
 def read_from_start(f):