| # Copyright 2015 The Chromium Authors. All rights reserved. |
| # Use of this source code is governed by a BSD-style license that can be |
| # found in the LICENSE file. |
| |
| import json |
| import sys |
| |
| import fieldtrial_to_struct |
| |
| def _hex(ch): |
| hv = hex(ord(ch)).replace('0x', '') |
| hv.zfill(2) |
| return hv.upper() |
| |
| # URL escapes the delimiter characters from the output. urllib.quote is not |
| # used because it cannot escape '.'. |
| def _escape(str): |
| result = str |
| # Must perform replace on '%' first before the others. |
| for c in '%:/.,': |
| result = result.replace(c, '%' + _hex(c)) |
| return result |
| |
| def _FindDuplicates(entries): |
| seen = set() |
| duplicates = set() |
| for entry in entries: |
| if entry in seen: |
| duplicates.add(entry) |
| else: |
| seen.add(entry) |
| return duplicates |
| |
| def _CheckForDuplicateFeatures(enable_features, disable_features): |
| enable_features = [f.split('<')[0] for f in enable_features] |
| enable_features_set = set(enable_features) |
| if len(enable_features_set) != len(enable_features): |
| raise Exception('Duplicate feature(s) in enable_features: ' + |
| ', '.join(_FindDuplicates(enable_features))) |
| |
| disable_features = [f.split('<')[0] for f in disable_features] |
| disable_features_set = set(disable_features) |
| if len(disable_features_set) != len(disable_features): |
| raise Exception('Duplicate feature(s) in disable_features: ' + |
| ', '.join(_FindDuplicates(disable_features))) |
| |
| features_in_both = enable_features_set.intersection(disable_features_set) |
| if len(features_in_both) > 0: |
| raise Exception('Conflicting features set as both enabled and disabled: ' + |
| ', '.join(features_in_both)) |
| |
| # Generate a list of command-line switches to enable field trials for the |
| # provided config_path and platforms. |
| def GenerateArgs(config_path, platforms): |
| try: |
| with open(config_path, 'r') as config_file: |
| config = json.load(config_file) |
| except (IOError, ValueError): |
| return [] |
| |
| platform_studies = fieldtrial_to_struct.ConfigToStudies(config, platforms) |
| |
| studies = [] |
| params = [] |
| enable_features = [] |
| disable_features = [] |
| |
| for study in platform_studies: |
| study_name = study['name'] |
| experiments = study['experiments'] |
| # For now, only take the first experiment. |
| experiment = experiments[0] |
| selected_study = [study_name, experiment['name']] |
| studies.extend(selected_study) |
| param_list = [] |
| if 'params' in experiment: |
| for param in experiment['params']: |
| param_list.append(param['key']) |
| param_list.append(param['value']) |
| if len(param_list): |
| # Escape the variables for the command-line. |
| selected_study = [_escape(x) for x in selected_study] |
| param_list = [_escape(x) for x in param_list] |
| param = '%s:%s' % ('.'.join(selected_study), '/'.join(param_list)) |
| params.append(param) |
| for feature in experiment.get('enable_features', []): |
| enable_features.append(feature + '<' + study_name) |
| for feature in experiment.get('disable_features', []): |
| disable_features.append(feature + '<' + study_name) |
| |
| if not len(studies): |
| return [] |
| _CheckForDuplicateFeatures(enable_features, disable_features) |
| args = ['--force-fieldtrials=%s' % '/'.join(studies)] |
| if len(params): |
| args.append('--force-fieldtrial-params=%s' % ','.join(params)) |
| if len(enable_features): |
| args.append('--enable-features=%s' % ','.join(enable_features)) |
| if len(disable_features): |
| args.append('--disable-features=%s' % ','.join(disable_features)) |
| return args |
| |
| def main(): |
| if len(sys.argv) < 3: |
| print 'Usage: fieldtrial_util.py [config_path] [platform]' |
| print 'Optionally pass \'shell_cmd\' as an extra argument to print' |
| print 'quoted command line arguments.' |
| exit(-1) |
| print_shell_cmd = len(sys.argv) >= 4 and sys.argv[3] == 'shell_cmd' |
| |
| supported_platforms = ['android', 'android_webview', 'chromeos', 'ios', |
| 'linux', 'mac', 'windows'] |
| if sys.argv[2] not in supported_platforms: |
| print ('\'%s\' is an unknown platform. Supported platforms: %s' % |
| (sys.argv[2], supported_platforms)) |
| exit(-1) |
| |
| generated_args = GenerateArgs(sys.argv[1], [sys.argv[2]]) |
| if print_shell_cmd: |
| print " ".join(map((lambda arg: '"{0}"'.format(arg)), generated_args)) |
| else: |
| print generated_args |
| |
| if __name__ == '__main__': |
| main() |