Commit 603551b3 authored by Weilun Shi's avatar Weilun Shi Committed by Commit Bot

Move OptionalBool out of study.proto

Support class type in json_to_struct and use C++ class base::Optional<bool>
for is_low_end_device instead of OptionalBool.

Bug: 987717
Change-Id: Ica6b475af788bbe9842c8630ef96e2ad6ad7f80c
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1973491Reviewed-by: default avatarBruce Dawson <brucedawson@chromium.org>
Reviewed-by: default avatarAlexei Svitkine <asvitkine@chromium.org>
Reviewed-by: default avatarSteven Holte <holte@chromium.org>
Reviewed-by: default avatarDaniel Cheng <dcheng@chromium.org>
Commit-Queue: Weilun Shi <sweilun@chromium.org>
Auto-Submit: Weilun Shi <sweilun@chromium.org>
Cr-Commit-Position: refs/heads/master@{#729594}
parent e94f1008
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
{ {
"type_name": "FieldTrialTestingConfig", "type_name": "FieldTrialTestingConfig",
"headers": ["components/variations/proto/study.pb.h"], "headers": ["base/optional.h", "components/variations/proto/study.pb.h"],
"schema": [{ "schema": [{
"field": "studies", "field": "studies",
"type": "array", "type": "array",
...@@ -33,9 +33,9 @@ ...@@ -33,9 +33,9 @@
}, },
{ {
"field": "is_low_end_device", "field": "is_low_end_device",
"type": "enum", "type": "class",
"ctype": "Study::OptionalBool", "ctype": "base::Optional<bool>",
"default": "Study::OPTIONAL_BOOL_MISSING", "default": "base::nullopt",
"optional": "True" "optional": "True"
}, },
{ {
......
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
#include "base/feature_list.h" #include "base/feature_list.h"
#include "base/metrics/field_trial.h" #include "base/metrics/field_trial.h"
#include "base/metrics/field_trial_params.h" #include "base/metrics/field_trial_params.h"
#include "base/optional.h"
#include "base/strings/utf_string_conversions.h" #include "base/strings/utf_string_conversions.h"
#include "base/system/sys_info.h" #include "base/system/sys_info.h"
#include "components/variations/field_trial_config/fieldtrial_testing_config.h" #include "components/variations/field_trial_config/fieldtrial_testing_config.h"
...@@ -39,13 +40,11 @@ bool HasPlatform(const FieldTrialTestingExperiment& experiment, ...@@ -39,13 +40,11 @@ bool HasPlatform(const FieldTrialTestingExperiment& experiment,
// is_low_end_device than the current system value does. // is_low_end_device than the current system value does.
// If experiment has is_low_end_device missing, then it is False. // If experiment has is_low_end_device missing, then it is False.
bool HasDeviceLevelMismatch(const FieldTrialTestingExperiment& experiment) { bool HasDeviceLevelMismatch(const FieldTrialTestingExperiment& experiment) {
if (experiment.is_low_end_device == Study::OPTIONAL_BOOL_MISSING) { if (!experiment.is_low_end_device.has_value()) {
return false; return false;
} }
if (base::SysInfo::IsLowEndDevice()) { return experiment.is_low_end_device.value() !=
return experiment.is_low_end_device == Study::OPTIONAL_BOOL_FALSE; base::SysInfo::IsLowEndDevice();
}
return experiment.is_low_end_device == Study::OPTIONAL_BOOL_TRUE;
} }
// Gets current form factor and converts it from enum DeviceFormFactor to enum // Gets current form factor and converts it from enum DeviceFormFactor to enum
......
...@@ -111,7 +111,7 @@ def GenerateFieldContent(element_name, field_info, content, lines, indent, ...@@ -111,7 +111,7 @@ def GenerateFieldContent(element_name, field_info, content, lines, indent,
if content is None: if content is None:
content = field_info.get('default', None) content = field_info.get('default', None)
type = field_info['type'] type = field_info['type']
if type == 'int' or type == 'enum': if type in ('int', 'enum', 'class'):
lines.append('%s%s,' % (indent, content)) lines.append('%s%s,' % (indent, content))
elif type == 'string': elif type == 'string':
_GenerateString(content, lines, indent) _GenerateString(content, lines, indent)
......
...@@ -67,6 +67,19 @@ class ElementGeneratorTest(unittest.TestCase): ...@@ -67,6 +67,19 @@ class ElementGeneratorTest(unittest.TestCase):
GenerateFieldContent('', {'type': 'enum'}, 'BLUE', lines, ' ', {}) GenerateFieldContent('', {'type': 'enum'}, 'BLUE', lines, ' ', {})
self.assertEquals([' BLUE,'], lines) self.assertEquals([' BLUE,'], lines)
def testGenerateClassFieldContent(self):
lines = []
GenerateFieldContent('', {'type': 'class', 'default': 'base::nullopt'},
None, lines, ' ', {})
self.assertEquals([' base::nullopt,'], lines)
lines = []
GenerateFieldContent('', {'type': 'class', 'default': 'base::nullopt'},
'true', lines, ' ', {})
self.assertEquals([' true,'], lines)
lines = []
GenerateFieldContent('', {'type': 'class'}, 'false', lines, ' ', {})
self.assertEquals([' false,'], lines)
def testGenerateArrayFieldContent(self): def testGenerateArrayFieldContent(self):
lines = ['STRUCT BEGINS']; lines = ['STRUCT BEGINS'];
GenerateFieldContent('test', {'type': 'array', 'contents': {'type': 'int'}}, GenerateFieldContent('test', {'type': 'array', 'contents': {'type': 'int'}},
......
...@@ -24,7 +24,7 @@ def GenerateField(field_info): ...@@ -24,7 +24,7 @@ def GenerateField(field_info):
return 'const char* const %s' % field return 'const char* const %s' % field
elif type == 'string16': elif type == 'string16':
return 'const wchar_t* const %s' % field return 'const wchar_t* const %s' % field
elif type == 'enum': elif type == 'enum' or type == 'class':
return 'const %s %s' % (field_info['ctype'], field) return 'const %s %s' % (field_info['ctype'], field)
elif type == 'array': elif type == 'array':
return _GenerateArrayField(field_info) return _GenerateArrayField(field_info)
......
...@@ -33,6 +33,12 @@ class StructGeneratorTest(unittest.TestCase): ...@@ -33,6 +33,12 @@ class StructGeneratorTest(unittest.TestCase):
'field': 'bar_bar', 'field': 'bar_bar',
'contents': {'type': 'int'}})) 'contents': {'type': 'int'}}))
def testGenerateClassField(self):
self.assertEquals('const base::Optional<bool> bar',
GenerateField({'type': 'class',
'field': 'bar',
'ctype': 'base::Optional<bool>'}))
def testGenerateStruct(self): def testGenerateStruct(self):
schema = [ schema = [
{'type': 'int', 'field': 'foo_bar'}, {'type': 'int', 'field': 'foo_bar'},
......
...@@ -58,8 +58,7 @@ def _FormFactorEnumValue(form_factor): ...@@ -58,8 +58,7 @@ def _FormFactorEnumValue(form_factor):
return 'Study::' + form_factor.upper() return 'Study::' + form_factor.upper()
def _Load(filename): def _Load(filename):
"""Loads a JSON file into a Python object and return this object. """Loads a JSON file into a Python object and return this object."""
"""
with open(filename, 'r') as handle: with open(filename, 'r') as handle:
result = json.loads(json_comment_eater.Nom(handle.read())) result = json.loads(json_comment_eater.Nom(handle.read()))
return result return result
...@@ -82,14 +81,29 @@ def _ConvertOverrideUIStrings(override_ui_strings): ...@@ -82,14 +81,29 @@ def _ConvertOverrideUIStrings(override_ui_strings):
def _CreateExperiment(experiment_data, def _CreateExperiment(experiment_data,
platforms, platforms,
is_low_end_device, form_factors,
form_factors): is_low_end_device):
"""Creates an experiment dictionary with all necessary information.
Args:
experiment_data: An experiment json config.
platforms: A list of platforms for this trial. This should be
a subset of |_platforms|.
form_factors: A list of form factors for this trial. This should be
a subset of |_form_factors|.
is_low_end_device: An optional parameter. This can either be True or
False. None if not specified.
Returns:
An experiment dict.
"""
experiment = { experiment = {
'name': experiment_data['name'], 'name': experiment_data['name'],
'platforms': [_PlatformEnumValue(p) for p in platforms], 'platforms': [_PlatformEnumValue(p) for p in platforms],
'is_low_end_device': is_low_end_device,
'form_factors': [_FormFactorEnumValue(f) for f in form_factors], 'form_factors': [_FormFactorEnumValue(f) for f in form_factors],
} }
if is_low_end_device is not None:
experiment['is_low_end_device'] = str(is_low_end_device).lower()
forcing_flags_data = experiment_data.get('forcing_flag') forcing_flags_data = experiment_data.get('forcing_flag')
if forcing_flags_data: if forcing_flags_data:
experiment['forcing_flag'] = forcing_flags_data experiment['forcing_flag'] = forcing_flags_data
...@@ -110,26 +124,22 @@ def _CreateExperiment(experiment_data, ...@@ -110,26 +124,22 @@ def _CreateExperiment(experiment_data,
return experiment return experiment
def _CreateTrial(study_name, experiment_configs, platforms): def _CreateTrial(study_name, experiment_configs, platforms):
"""Returns the applicable experiments for |study_name| and |platforms|. This """Returns the applicable experiments for |study_name| and |platforms|.
iterates through all of the experiment_configs for |study_name| and picks out
the applicable experiments based off of the valid platforms and device This iterates through all of the experiment_configs for |study_name|
type settings if specified. and picks out the applicable experiments based off of the valid platforms
and device type settings if specified.
""" """
experiments = [] experiments = []
for config in experiment_configs: for config in experiment_configs:
platform_intersection = [p for p in platforms if p in config['platforms']] platform_intersection = [p for p in platforms if p in config['platforms']]
is_low_end_device = 'Study::OPTIONAL_BOOL_MISSING'
if 'is_low_end_device' in config:
is_low_end_device = ('Study::OPTIONAL_BOOL_TRUE'
if config['is_low_end_device']
else 'Study::OPTIONAL_BOOL_FALSE')
if platform_intersection: if platform_intersection:
experiments += [_CreateExperiment( experiments += [_CreateExperiment(
e, e,
platform_intersection, platform_intersection,
is_low_end_device, config.get('form_factors', []),
config.get('form_factors', [])) config.get('is_low_end_device'))
for e in config['experiments']] for e in config['experiments']]
return { return {
'name': study_name, 'name': study_name,
......
...@@ -80,7 +80,6 @@ class FieldTrialToStruct(unittest.TestCase): ...@@ -80,7 +80,6 @@ class FieldTrialToStruct(unittest.TestCase):
], ],
'enable_features': ['A', 'B'], 'enable_features': ['A', 'B'],
'disable_features': ['C'], 'disable_features': ['C'],
'is_low_end_device': 'Study::OPTIONAL_BOOL_MISSING',
'form_factors': [], 'form_factors': [],
}, },
{ {
...@@ -92,7 +91,6 @@ class FieldTrialToStruct(unittest.TestCase): ...@@ -92,7 +91,6 @@ class FieldTrialToStruct(unittest.TestCase):
], ],
'enable_features': ['D', 'E'], 'enable_features': ['D', 'E'],
'disable_features': ['F'], 'disable_features': ['F'],
'is_low_end_device': 'Study::OPTIONAL_BOOL_MISSING',
'form_factors': [], 'form_factors': [],
}, },
], ],
...@@ -103,7 +101,6 @@ class FieldTrialToStruct(unittest.TestCase): ...@@ -103,7 +101,6 @@ class FieldTrialToStruct(unittest.TestCase):
{ {
'name': 'OtherGroup', 'name': 'OtherGroup',
'platforms': ['Study::PLATFORM_WINDOWS'], 'platforms': ['Study::PLATFORM_WINDOWS'],
'is_low_end_device': 'Study::OPTIONAL_BOOL_MISSING',
'form_factors': [], 'form_factors': [],
} }
] ]
...@@ -115,7 +112,6 @@ class FieldTrialToStruct(unittest.TestCase): ...@@ -115,7 +112,6 @@ class FieldTrialToStruct(unittest.TestCase):
'name': 'ForcedGroup', 'name': 'ForcedGroup',
'platforms': ['Study::PLATFORM_WINDOWS'], 'platforms': ['Study::PLATFORM_WINDOWS'],
'forcing_flag': "my-forcing-flag", 'forcing_flag': "my-forcing-flag",
'is_low_end_device': 'Study::OPTIONAL_BOOL_MISSING',
'form_factors': [], 'form_factors': [],
} }
] ]
...@@ -131,7 +127,7 @@ class FieldTrialToStruct(unittest.TestCase): ...@@ -131,7 +127,7 @@ class FieldTrialToStruct(unittest.TestCase):
'Trial1': [ 'Trial1': [
{ {
'platforms': ['windows', 'ios'], 'platforms': ['windows', 'ios'],
'is_low_end_device': True, 'is_low_end_device': 'true',
'experiments': [ 'experiments': [
{ {
'name': 'Group1', 'name': 'Group1',
...@@ -189,7 +185,7 @@ class FieldTrialToStruct(unittest.TestCase): ...@@ -189,7 +185,7 @@ class FieldTrialToStruct(unittest.TestCase):
], ],
'enable_features': ['A', 'B'], 'enable_features': ['A', 'B'],
'disable_features': ['C'], 'disable_features': ['C'],
'is_low_end_device': 'Study::OPTIONAL_BOOL_TRUE', 'is_low_end_device': 'true',
'form_factors': [], 'form_factors': [],
}, },
{ {
...@@ -201,13 +197,12 @@ class FieldTrialToStruct(unittest.TestCase): ...@@ -201,13 +197,12 @@ class FieldTrialToStruct(unittest.TestCase):
], ],
'enable_features': ['D', 'E'], 'enable_features': ['D', 'E'],
'disable_features': ['F'], 'disable_features': ['F'],
'is_low_end_device': 'Study::OPTIONAL_BOOL_TRUE', 'is_low_end_device': 'true',
'form_factors': [], 'form_factors': [],
}, },
{ {
'name': 'IOSOnly', 'name': 'IOSOnly',
'platforms': ['Study::PLATFORM_IOS'], 'platforms': ['Study::PLATFORM_IOS'],
'is_low_end_device': 'Study::OPTIONAL_BOOL_MISSING',
'form_factors': [], 'form_factors': [],
}, },
], ],
...@@ -232,7 +227,6 @@ class FieldTrialToStruct(unittest.TestCase): ...@@ -232,7 +227,6 @@ class FieldTrialToStruct(unittest.TestCase):
{ {
'name': 'OtherGroup', 'name': 'OtherGroup',
'platforms': ['Study::PLATFORM_MAC'], 'platforms': ['Study::PLATFORM_MAC'],
'is_low_end_device': 'Study::OPTIONAL_BOOL_MISSING',
'form_factors': [], 'form_factors': [],
}, },
], ],
...@@ -274,7 +268,6 @@ class FieldTrialToStruct(unittest.TestCase): ...@@ -274,7 +268,6 @@ class FieldTrialToStruct(unittest.TestCase):
{ {
'name': 'Group1', 'name': 'Group1',
'platforms': ['Study::PLATFORM_WINDOWS'], 'platforms': ['Study::PLATFORM_WINDOWS'],
'is_low_end_device': 'Study::OPTIONAL_BOOL_MISSING',
'form_factors': ['Study::DESKTOP', 'Study::PHONE'], 'form_factors': ['Study::DESKTOP', 'Study::PHONE'],
}, },
], ],
...@@ -285,7 +278,6 @@ class FieldTrialToStruct(unittest.TestCase): ...@@ -285,7 +278,6 @@ class FieldTrialToStruct(unittest.TestCase):
{ {
'name': 'OtherGroup', 'name': 'OtherGroup',
'platforms': ['Study::PLATFORM_WINDOWS'], 'platforms': ['Study::PLATFORM_WINDOWS'],
'is_low_end_device': 'Study::OPTIONAL_BOOL_MISSING',
'form_factors': ['Study::TABLET'], 'form_factors': ['Study::TABLET'],
}, },
], ],
...@@ -352,7 +344,6 @@ class FieldTrialToStruct(unittest.TestCase): ...@@ -352,7 +344,6 @@ class FieldTrialToStruct(unittest.TestCase):
'value': 'test2' 'value': 'test2'
}, },
], ],
'is_low_end_device': 'Study::OPTIONAL_BOOL_MISSING',
'form_factors': [], 'form_factors': [],
}, },
], ],
...@@ -370,7 +361,6 @@ class FieldTrialToStruct(unittest.TestCase): ...@@ -370,7 +361,6 @@ class FieldTrialToStruct(unittest.TestCase):
'value': 'test3' 'value': 'test3'
}, },
], ],
'is_low_end_device': 'Study::OPTIONAL_BOOL_MISSING',
'form_factors': [], 'form_factors': [],
}, },
], ],
......
specific_include_rules = { specific_include_rules = {
"expected_output.h": ["+components/variations/proto/study.pb.h"] "expected_output.h": [
"+base/optional.h",
"+components/variations/proto/study.pb.h"
]
} }
...@@ -28,7 +28,7 @@ const FieldTrialTestingExperiment array_kFieldTrialConfig_experiments_5[] = { ...@@ -28,7 +28,7 @@ const FieldTrialTestingExperiment array_kFieldTrialConfig_experiments_5[] = {
1, 1,
array_kFieldTrialConfig_form_factors_8, array_kFieldTrialConfig_form_factors_8,
0, 0,
Study::OPTIONAL_BOOL_MISSING, base::nullopt,
NULL, NULL,
0, 0,
NULL, NULL,
...@@ -60,7 +60,7 @@ const FieldTrialTestingExperiment array_kFieldTrialConfig_experiments_4[] = { ...@@ -60,7 +60,7 @@ const FieldTrialTestingExperiment array_kFieldTrialConfig_experiments_4[] = {
1, 1,
array_kFieldTrialConfig_form_factors_6, array_kFieldTrialConfig_form_factors_6,
2, 2,
Study::OPTIONAL_BOOL_MISSING, base::nullopt,
NULL, NULL,
0, 0,
NULL, NULL,
...@@ -77,7 +77,7 @@ const FieldTrialTestingExperiment array_kFieldTrialConfig_experiments_4[] = { ...@@ -77,7 +77,7 @@ const FieldTrialTestingExperiment array_kFieldTrialConfig_experiments_4[] = {
1, 1,
array_kFieldTrialConfig_form_factors_7, array_kFieldTrialConfig_form_factors_7,
1, 1,
Study::OPTIONAL_BOOL_MISSING, base::nullopt,
NULL, NULL,
0, 0,
NULL, NULL,
...@@ -101,7 +101,7 @@ const FieldTrialTestingExperiment array_kFieldTrialConfig_experiments_3[] = { ...@@ -101,7 +101,7 @@ const FieldTrialTestingExperiment array_kFieldTrialConfig_experiments_3[] = {
1, 1,
array_kFieldTrialConfig_form_factors_5, array_kFieldTrialConfig_form_factors_5,
0, 0,
Study::OPTIONAL_BOOL_MISSING, base::nullopt,
NULL, NULL,
0, 0,
NULL, NULL,
...@@ -130,7 +130,7 @@ const FieldTrialTestingExperiment array_kFieldTrialConfig_experiments_2[] = { ...@@ -130,7 +130,7 @@ const FieldTrialTestingExperiment array_kFieldTrialConfig_experiments_2[] = {
1, 1,
array_kFieldTrialConfig_form_factors_3, array_kFieldTrialConfig_form_factors_3,
0, 0,
Study::OPTIONAL_BOOL_TRUE, true,
NULL, NULL,
0, 0,
NULL, NULL,
...@@ -147,7 +147,7 @@ const FieldTrialTestingExperiment array_kFieldTrialConfig_experiments_2[] = { ...@@ -147,7 +147,7 @@ const FieldTrialTestingExperiment array_kFieldTrialConfig_experiments_2[] = {
1, 1,
array_kFieldTrialConfig_form_factors_4, array_kFieldTrialConfig_form_factors_4,
0, 0,
Study::OPTIONAL_BOOL_FALSE, false,
NULL, NULL,
0, 0,
NULL, NULL,
...@@ -174,7 +174,7 @@ const FieldTrialTestingExperiment array_kFieldTrialConfig_experiments_1[] = { ...@@ -174,7 +174,7 @@ const FieldTrialTestingExperiment array_kFieldTrialConfig_experiments_1[] = {
1, 1,
array_kFieldTrialConfig_form_factors_2, array_kFieldTrialConfig_form_factors_2,
0, 0,
Study::OPTIONAL_BOOL_MISSING, base::nullopt,
NULL, NULL,
0, 0,
array_kFieldTrialConfig_enable_features_1, array_kFieldTrialConfig_enable_features_1,
...@@ -237,7 +237,7 @@ const FieldTrialTestingExperiment array_kFieldTrialConfig_experiments_0[] = { ...@@ -237,7 +237,7 @@ const FieldTrialTestingExperiment array_kFieldTrialConfig_experiments_0[] = {
1, 1,
array_kFieldTrialConfig_form_factors_0, array_kFieldTrialConfig_form_factors_0,
0, 0,
Study::OPTIONAL_BOOL_MISSING, base::nullopt,
array_kFieldTrialConfig_params, array_kFieldTrialConfig_params,
2, 2,
array_kFieldTrialConfig_enable_features, array_kFieldTrialConfig_enable_features,
...@@ -254,7 +254,7 @@ const FieldTrialTestingExperiment array_kFieldTrialConfig_experiments_0[] = { ...@@ -254,7 +254,7 @@ const FieldTrialTestingExperiment array_kFieldTrialConfig_experiments_0[] = {
1, 1,
array_kFieldTrialConfig_form_factors_1, array_kFieldTrialConfig_form_factors_1,
0, 0,
Study::OPTIONAL_BOOL_MISSING, base::nullopt,
array_kFieldTrialConfig_params_0, array_kFieldTrialConfig_params_0,
2, 2,
array_kFieldTrialConfig_enable_features_0, array_kFieldTrialConfig_enable_features_0,
...@@ -278,7 +278,7 @@ const FieldTrialTestingExperiment array_kFieldTrialConfig_experiments[] = { ...@@ -278,7 +278,7 @@ const FieldTrialTestingExperiment array_kFieldTrialConfig_experiments[] = {
1, 1,
array_kFieldTrialConfig_form_factors, array_kFieldTrialConfig_form_factors,
0, 0,
Study::OPTIONAL_BOOL_MISSING, base::nullopt,
NULL, NULL,
0, 0,
NULL, NULL,
......
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
#include <cstddef> #include <cstddef>
#include "base/optional.h"
#include "components/variations/proto/study.pb.h" #include "components/variations/proto/study.pb.h"
struct OverrideUIString { struct OverrideUIString {
...@@ -30,7 +31,7 @@ struct FieldTrialTestingExperiment { ...@@ -30,7 +31,7 @@ struct FieldTrialTestingExperiment {
const size_t platforms_size; const size_t platforms_size;
const Study::FormFactor * form_factors; const Study::FormFactor * form_factors;
const size_t form_factors_size; const size_t form_factors_size;
const Study::OptionalBool is_low_end_device; const base::Optional<bool> is_low_end_device;
const FieldTrialTestingExperimentParams * params; const FieldTrialTestingExperimentParams * params;
const size_t params_size; const size_t params_size;
const char* const * enable_features; const char* const * enable_features;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment