Ejemplo n.º 1
0
    def test_schema_check_fails(self):
        data = {}
        with pytest.raises(mozilla_nimbus_shared.NimbusValidationError) as excinfo:
            mozilla_nimbus_shared.check_schema("normandy/ConsoleLogArguments", data)

        assert "Data does not match schema" in str(excinfo.value)
        errors = list(excinfo.value.errors)
        assert len(errors) == 1
        assert "'message' is a required property" in str(errors[0])
Ejemplo n.º 2
0
    def test_serializer_outputs_empty_targeting(self):
        experiment = NimbusExperimentFactory.create_with_lifecycle(
            NimbusExperimentFactory.Lifecycles.LAUNCH_APPROVE,
            publish_status=NimbusExperiment.PublishStatus.APPROVED,
            targeting_config_slug=NimbusExperiment.TargetingConfig.NO_TARGETING,
            application=NimbusExperiment.Application.FENIX,
        )

        serializer = NimbusExperimentSerializer(experiment)
        self.assertEqual(serializer.data["targeting"], "true")
        check_schema("experiments/NimbusExperiment", serializer.data)
Ejemplo n.º 3
0
 def test_serializer_outputs_targeting(self):
     experiment = NimbusExperimentFactory.create_with_lifecycle(
         NimbusExperimentFactory.Lifecycles.LAUNCH_APPROVE,
         firefox_min_version=NimbusExperiment.Version.FIREFOX_83,
         targeting_config_slug=NimbusExperiment.TargetingConfig.ALL_ENGLISH,
         application=NimbusExperiment.Application.DESKTOP,
         channel=NimbusExperiment.Channel.NO_CHANNEL,
     )
     serializer = NimbusExperimentSerializer(experiment)
     self.assertEqual(serializer.data["targeting"], experiment.targeting)
     check_schema("experiments/NimbusExperiment", serializer.data)
Ejemplo n.º 4
0
 def test_serializers_with_feature_value_None(self):
     experiment = NimbusExperimentFactory.create_with_status(
         NimbusExperiment.Status.ACCEPTED,
         branches=[],
     )
     experiment.reference_branch = NimbusBranchFactory(
         experiment=experiment, feature_value=None)
     experiment.save()
     serializer = NimbusExperimentSerializer(experiment)
     self.assertIsNone(serializer.data["branches"][0]["feature"]["value"])
     check_schema("experiments/NimbusExperiment", serializer.data)
Ejemplo n.º 5
0
 def test_sets_application_channel_for_fenix_experiment(self):
     experiment = NimbusExperimentFactory.create_with_status(
         NimbusExperiment.Status.ACCEPTED,
         application=NimbusExperiment.Application.FENIX,
         channel=NimbusExperiment.Channel.FENIX_NIGHTLY,
     )
     serializer = NimbusExperimentSerializer(experiment)
     self.assertEqual(serializer.data["application"],
                      NimbusExperiment.Channel.FENIX_NIGHTLY)
     self.assertEqual(serializer.data["channel"],
                      NimbusExperiment.Channel.FENIX_NIGHTLY)
     check_schema("experiments/NimbusExperiment", serializer.data)
Ejemplo n.º 6
0
 def test_serializers_with_missing_feature_value(self, application):
     experiment = NimbusExperimentFactory.create_with_lifecycle(
         NimbusExperimentFactory.Lifecycles.LAUNCH_APPROVE,
         application=application,
         branches=[],
     )
     experiment.reference_branch = NimbusBranchFactory(
         experiment=experiment, feature_value=None
     )
     experiment.save()
     serializer = NimbusExperimentSerializer(experiment)
     self.assertEqual(serializer.data["branches"][0]["feature"]["value"], {})
     check_schema("experiments/NimbusExperiment", serializer.data)
Ejemplo n.º 7
0
    def test_serializer_outputs_targeting_for_experiment_without_firefox_min_version(
        self, ):
        experiment = NimbusExperimentFactory.create_with_status(
            NimbusExperiment.Status.ACCEPTED,
            firefox_min_version=None,
            targeting_config_slug=NimbusExperiment.TargetingConfig.ALL_ENGLISH,
            channel=NimbusExperiment.Channel.DESKTOP_NIGHTLY,
        )

        serializer = NimbusExperimentSerializer(experiment)
        self.assertEqual(
            serializer.data["targeting"],
            ('browserSettings.update.channel == "nightly" '
             "&& localeLanguageCode == 'en' "
             "&& 'app.shield.optoutstudies.enabled'|preferenceValue"),
        )
        check_schema("experiments/NimbusExperiment", serializer.data)
Ejemplo n.º 8
0
    def test_serializer_outputs_targeting_for_experiment_without_channels(
            self):
        experiment = NimbusExperimentFactory.create_with_status(
            NimbusExperiment.Status.ACCEPTED,
            firefox_min_version=NimbusExperiment.Version.FIREFOX_80,
            targeting_config_slug=NimbusExperiment.TargetingConfig.ALL_ENGLISH,
            application=NimbusExperiment.Application.DESKTOP,
            channel=None,
        )

        serializer = NimbusExperimentSerializer(experiment)
        self.assertEqual(
            serializer.data["targeting"],
            ("version|versionCompare('80.!') >= 0 "
             "&& localeLanguageCode == 'en' "
             "&& 'app.shield.optoutstudies.enabled'|preferenceValue"),
        )
        check_schema("experiments/NimbusExperiment", serializer.data)
Ejemplo n.º 9
0
    def test_serializer_outputs_expected_schema_without_feature(self):
        experiment = NimbusExperimentFactory.create_with_status(
            NimbusExperiment.Status.ACCEPTED,
            feature_config=None,
        )
        serializer = NimbusExperimentSerializer(experiment)
        experiment_data = serializer.data.copy()
        branches_data = [dict(b) for b in experiment_data.pop("branches")]
        self.assertEqual(len(branches_data), 2)
        for branch in experiment.branches.all():
            self.assertIn(
                {
                    "slug": branch.slug,
                    "ratio": branch.ratio
                },
                branches_data,
            )

        check_schema("experiments/NimbusExperiment", serializer.data)
Ejemplo n.º 10
0
    def test_sets_app_id_name_channel_for_application(
        self,
        application,
        channel,
        expected_application,
        expected_appId,
        expected_appName,
    ):
        experiment = NimbusExperimentFactory.create_with_lifecycle(
            NimbusExperimentFactory.Lifecycles.LAUNCH_APPROVE,
            application=application,
            channel=channel,
        )

        serializer = NimbusExperimentSerializer(experiment)
        self.assertEqual(serializer.data["application"], expected_application)
        self.assertEqual(serializer.data["channel"], channel)
        self.assertEqual(serializer.data["appName"], expected_appName)
        self.assertEqual(serializer.data["appId"], expected_appId)
        check_schema("experiments/NimbusExperiment", serializer.data)
Ejemplo n.º 11
0
    def test_serializer_outputs_expected_schema_with_feature(self):
        experiment = NimbusExperimentFactory.create_with_lifecycle(
            NimbusExperimentFactory.Lifecycles.ENDING_APPROVE_APPROVE,
            application=NimbusExperiment.Application.DESKTOP,
            firefox_min_version=NimbusExperiment.Version.FIREFOX_83,
            targeting_config_slug=NimbusExperiment.TargetingConfig.ALL_ENGLISH,
            channel=NimbusExperiment.Channel.NIGHTLY,
            primary_outcomes=["foo", "bar", "baz"],
            secondary_outcomes=["quux", "xyzzy"],
        )

        serializer = NimbusExperimentSerializer(experiment)
        experiment_data = serializer.data.copy()
        bucket_data = dict(experiment_data.pop("bucketConfig"))
        branches_data = [dict(b) for b in experiment_data.pop("branches")]

        self.assertDictEqual(
            experiment_data,
            {
                "arguments": {},
                "application": "firefox-desktop",
                "appName": "firefox_desktop",
                "appId": "firefox-desktop",
                "channel": "nightly",
                # DRF manually replaces the isoformat suffix so we have to do the same
                "endDate": experiment.end_date.isoformat().replace("+00:00", "Z"),
                "id": experiment.slug,
                "isEnrollmentPaused": True,
                "proposedDuration": experiment.proposed_duration,
                "proposedEnrollment": experiment.proposed_enrollment,
                "referenceBranch": experiment.reference_branch.slug,
                "schemaVersion": settings.NIMBUS_SCHEMA_VERSION,
                "slug": experiment.slug,
                # DRF manually replaces the isoformat suffix so we have to do the same
                "startDate": experiment.start_date.isoformat().replace("+00:00", "Z"),
                "targeting": (
                    'browserSettings.update.channel == "nightly" '
                    "&& version|versionCompare('83.!') >= 0 "
                    "&& 'app.shield.optoutstudies.enabled'|preferenceValue "
                    "&& localeLanguageCode == 'en'"
                ),
                "userFacingDescription": experiment.public_description,
                "userFacingName": experiment.name,
                "probeSets": [],
                "outcomes": [
                    {"priority": "primary", "slug": "foo"},
                    {"priority": "primary", "slug": "bar"},
                    {"priority": "primary", "slug": "baz"},
                    {"priority": "secondary", "slug": "quux"},
                    {"priority": "secondary", "slug": "xyzzy"},
                ],
                "featureIds": [experiment.feature_config.slug],
            },
        )
        self.assertEqual(
            bucket_data,
            {
                "randomizationUnit": (
                    experiment.bucket_range.isolation_group.randomization_unit
                ),
                "namespace": experiment.bucket_range.isolation_group.namespace,
                "start": experiment.bucket_range.start,
                "count": experiment.bucket_range.count,
                "total": experiment.bucket_range.isolation_group.total,
            },
        )
        self.assertEqual(len(branches_data), 2)
        for branch in experiment.branches.all():
            self.assertIn(
                {
                    "slug": branch.slug,
                    "ratio": branch.ratio,
                    "feature": {
                        "featureId": experiment.feature_config.slug,
                        "enabled": branch.feature_enabled,
                        "value": json.loads(branch.feature_value),
                    },
                },
                branches_data,
            )

        check_schema("experiments/NimbusExperiment", serializer.data)
Ejemplo n.º 12
0
def test_schema_check_fails():
    data = {}
    with pytest.raises(jsonschema.exceptions.ValidationError):
        mozilla_nimbus_shared.check_schema("normandy/ConsoleLogArguments",
                                           data)
Ejemplo n.º 13
0
def test_schema_check_passes():
    data = {"message": "test"}
    assert mozilla_nimbus_shared.check_schema("normandy/ConsoleLogArguments",
                                              data)
Ejemplo n.º 14
0
 def test_missing_schema_throws_the_right_error(self):
     with pytest.raises(mozilla_nimbus_shared.NimbusSchemaNotFoundError):
         mozilla_nimbus_shared.check_schema("Bogus/Schema", {})
Ejemplo n.º 15
0
    def test_serializer_outputs_expected_schema_with_feature(self):
        probe_set = NimbusProbeSetFactory.create()
        experiment = NimbusExperimentFactory.create_with_status(
            NimbusExperiment.Status.COMPLETE,
            application=NimbusExperiment.Application.DESKTOP,
            firefox_min_version=NimbusExperiment.Version.FIREFOX_80,
            targeting_config_slug=NimbusExperiment.TargetingConfig.ALL_ENGLISH,
            channel=NimbusExperiment.Channel.DESKTOP_NIGHTLY,
            probe_sets=[probe_set],
        )

        serializer = NimbusExperimentSerializer(experiment)
        all_experiment_data = serializer.data.copy()
        arguments_data = all_experiment_data.pop("arguments")
        for experiment_data in arguments_data, all_experiment_data:
            branches_data = [dict(b) for b in experiment_data.pop("branches")]

            self.assertEqual(
                experiment_data,
                {
                    "application":
                    experiment.application,
                    "channel":
                    experiment.channel,
                    "bucketConfig": {
                        "randomizationUnit":
                        (experiment.bucket_range.isolation_group.
                         randomization_unit),
                        "namespace":
                        experiment.bucket_range.isolation_group.namespace,
                        "start":
                        experiment.bucket_range.start,
                        "count":
                        experiment.bucket_range.count,
                        "total":
                        experiment.bucket_range.isolation_group.total,
                    },
                    # DRF manually replaces the isoformat suffix so we have to do the same
                    "endDate":
                    experiment.end_date.isoformat().replace("+00:00", "Z"),
                    "id":
                    experiment.slug,
                    "isEnrollmentPaused":
                    False,
                    "proposedDuration":
                    experiment.proposed_duration,
                    "proposedEnrollment":
                    experiment.proposed_enrollment,
                    "referenceBranch":
                    experiment.reference_branch.slug,
                    "schemaVersion":
                    settings.NIMBUS_SCHEMA_VERSION,
                    "slug":
                    experiment.slug,
                    # DRF manually replaces the isoformat suffix so we have to do the same
                    "startDate":
                    experiment.start_date.isoformat().replace("+00:00", "Z"),
                    "targeting":
                    ('browserSettings.update.channel == "nightly" '
                     "&& version|versionCompare('80.!') >= 0 "
                     "&& localeLanguageCode == 'en' "
                     "&& 'app.shield.optoutstudies.enabled'|preferenceValue"),
                    "userFacingDescription":
                    experiment.public_description,
                    "userFacingName":
                    experiment.name,
                    "probeSets": [probe_set.slug],
                },
            )
            self.assertEqual(len(branches_data), 2)
            for branch in experiment.branches.all():
                self.assertIn(
                    {
                        "slug": branch.slug,
                        "ratio": branch.ratio,
                        "feature": {
                            "featureId": experiment.feature_config.slug,
                            "enabled": branch.feature_enabled,
                            "value": json.loads(branch.feature_value),
                        },
                    },
                    branches_data,
                )

        check_schema("experiments/NimbusExperiment", serializer.data)