Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions optimizely/entities.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@

if TYPE_CHECKING:
# prevent circular dependenacy by skipping import at runtime
from .helpers.types import ExperimentDict, ExperimentType, TrafficAllocation, VariableDict, VariationDict, CmabDict
from .helpers.types import ExperimentDict, TrafficAllocation, VariableDict, VariationDict, CmabDict


class BaseEntity:
Expand Down Expand Up @@ -87,7 +87,7 @@ def __init__(
groupId: Optional[str] = None,
groupPolicy: Optional[str] = None,
cmab: Optional[CmabDict] = None,
type: Optional[ExperimentType] = None,
type: Optional[str] = None,
**kwargs: Any
):
self.id = id
Expand Down
17 changes: 0 additions & 17 deletions optimizely/project_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -189,24 +189,7 @@ def __init__(self, datafile: str | bytes, logger: Logger, error_handler: Any):
self.variation_key_map_by_experiment_id: dict[str, dict[str, Union[entities.Variation, VariationDict]]] = {}
self.flag_variations_map: dict[str, list[entities.Variation]] = {}

valid_experiment_types = {
enums.ExperimentTypes.ab,
enums.ExperimentTypes.mab,
enums.ExperimentTypes.cmab,
enums.ExperimentTypes.td,
enums.ExperimentTypes.fr,
}
for experiment in self.experiment_id_map.values():
if experiment.type is not None and experiment.type not in valid_experiment_types:
self.logger.error(
f'Experiment "{experiment.key}" has invalid type "{experiment.type}". '
f'Valid types: {valid_experiment_types}.'
)
self.error_handler.handle_error(
exceptions.InvalidExperimentException(
f'Invalid experiment type: {experiment.type}'
)
)
self.experiment_key_map[experiment.key] = experiment
self.variation_key_map[experiment.key] = self._generate_key_map(
experiment.variations, 'key', entities.Variation
Expand Down
35 changes: 35 additions & 0 deletions tests/test_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -1651,6 +1651,41 @@ def test_experiment_type_field_none_when_missing(self):
experiment = config.experiment_id_map['exp_ab']
self.assertIsNone(experiment.type)

def test_unknown_experiment_type_accepted(self):
"""Test that experiments with unknown type values are accepted without error."""
datafile = self._build_datafile(
experiments=[
{
'id': 'exp_unknown',
'key': 'unknown_type_exp',
'status': 'Running',
'forcedVariations': {},
'layerId': 'layer_1',
'audienceIds': [],
'trafficAllocation': [{'entityId': 'var_1', 'endOfRange': 5000}],
'variations': [{'key': 'var_1', 'id': 'var_1', 'featureEnabled': True}],
'type': 'new_unknown_type',
},
],
feature_flags=[
{
'id': 'flag_1',
'key': 'test_flag',
'experimentIds': ['exp_unknown'],
'rolloutId': '',
'variables': [],
},
],
)

opt = optimizely.Optimizely(json.dumps(datafile))
config = opt.config_manager.get_config()

self.assertIsNotNone(config)
experiment = config.experiment_id_map['exp_unknown']
self.assertEqual(experiment.type, 'new_unknown_type')
self.assertEqual(experiment.key, 'unknown_type_exp')

def test_feature_rollout_injects_everyone_else_variation(self):
"""Test that feature_rollout experiments get the everyone else variation injected."""
datafile = self._build_datafile(
Expand Down
Loading