| 
					
				 | 
			
			
				@@ -43,28 +43,38 @@ sys.path.append(run_tests_root) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 import performance.scenario_config as scenario_config 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-def _scenario_json_string(scenario_json): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+configs_from_yaml = yaml.load(open(os.path.join(os.path.dirname(sys.argv[0]), '../../../build.yaml')))['configs'].keys() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+def mutate_scenario(scenario_json, is_tsan): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   # tweak parameters to get fast test times 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  scenario_json = dict(scenario_json) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   scenario_json['warmup_seconds'] = 0 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   scenario_json['benchmark_seconds'] = 1 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  scenarios_json = {'scenarios': [scenario_config.remove_nonproto_fields(scenario_json)]} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  outstanding_rpcs_divisor = 1 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if is_tsan and ( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      scenario_json['client_config']['client_type'] == 'SYNC_CLIENT' or 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      scenario_json['server_config']['server_type'] == 'SYNC_SERVER'): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    outstanding_rpcs_divisor = 10 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  scenario_json['client_config']['outstanding_rpcs_per_channel'] = max(1, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      int(scenario_json['client_config']['outstanding_rpcs_per_channel'] / outstanding_rpcs_divisor)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  return scenario_json 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+def _scenario_json_string(scenario_json, is_tsan): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  scenarios_json = {'scenarios': [scenario_config.remove_nonproto_fields(mutate_scenario(scenario_json, is_tsan))]} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   return json.dumps(scenarios_json) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-def threads_of_type(scenario_json, path): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  d = scenario_json 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  for el in path.split('/'): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    if el not in d: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      return 0 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    d = d[el] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  return d 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+def threads_required(scenario_json, where, is_tsan): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  scenario_json = mutate_scenario(scenario_json, is_tsan) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if scenario_json['%s_config' % where]['%s_type' % where] == 'ASYNC_%s' % where.upper(): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return scenario_json['%s_config' % where].get('async_%s_threads' % where, 0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  return scenario_json['client_config']['outstanding_rpcs_per_channel'] * scenario_json['client_config']['client_channels'] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-def guess_cpu(scenario_json): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  client = threads_of_type(scenario_json, 'client_config/async_client_threads') 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  server = threads_of_type(scenario_json, 'server_config/async_server_threads') 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+def guess_cpu(scenario_json, is_tsan): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  client = threads_required(scenario_json, 'client', is_tsan) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  server = threads_required(scenario_json, 'server', is_tsan) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   # make an arbitrary guess if set to auto-detect 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   # about the size of the jenkins instances we have for unit tests 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  if client == 0: client = 8 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  if server == 0: server = 8 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if client == 0 or server == 0: return 'capacity' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   return (scenario_json['num_clients'] * client + 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				           scenario_json['num_servers'] * server) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -73,15 +83,32 @@ print yaml.dump({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       'name': 'json_run_localhost', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       'shortname': 'json_run_localhost:%s' % scenario_json['name'], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      'args': ['--scenarios_json', _scenario_json_string(scenario_json)], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      'args': ['--scenarios_json', _scenario_json_string(scenario_json, False)], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      'ci_platforms': ['linux'], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      'platforms': ['linux'], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      'flaky': False, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      'language': 'c++', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      'boringssl': True, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      'defaults': 'boringssl', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      'cpu_cost': guess_cpu(scenario_json, False), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      'exclude_configs': ['tsan'], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      'timeout_seconds': 6*60 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    for scenario_json in scenario_config.CXXLanguage().scenarios() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if 'scalable' in scenario_json.get('CATEGORIES', []) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  ] + [ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      'name': 'json_run_localhost', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      'shortname': 'json_run_localhost:%s' % scenario_json['name'], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      'args': ['--scenarios_json', _scenario_json_string(scenario_json, True)], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       'ci_platforms': ['linux'], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       'platforms': ['linux'], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       'flaky': False, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       'language': 'c++', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       'boringssl': True, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       'defaults': 'boringssl', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      'cpu_cost': guess_cpu(scenario_json), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      'exclude_configs': [], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      'cpu_cost': guess_cpu(scenario_json, True), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      'exclude_configs': sorted(c for c in configs_from_yaml if c != 'tsan'), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       'timeout_seconds': 6*60 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     for scenario_json in scenario_config.CXXLanguage().scenarios() 
			 |