Example #1
0
def update_recipe_ids_to_experiments():
    metrics.incr("update_ready_to_ship_experiments.started")
    logger.info("Update Recipes to Experiments")

    ready_to_ship_experiments = Experiment.objects.filter(
        status__in=[Experiment.STATUS_SHIP, Experiment.STATUS_ACCEPTED])
    for experiment in ready_to_ship_experiments:
        try:
            logger.info("Updating Experiment: {}".format(experiment))
            recipe_data = normandy.get_recipe_list(experiment.slug)

            if len(recipe_data):
                recipe_ids = [r["id"] for r in recipe_data]
                # sort to get oldest id to be primary
                recipe_ids.sort()
                changed_data = {
                    "normandy_id": recipe_ids[0],
                    "other_normandy_ids": recipe_ids[1:],
                    "status": Experiment.STATUS_ACCEPTED,
                }
                update_experiment_with_change_log(experiment, changed_data)

        except (IntegrityError, KeyError, normandy.NormandyError) as e:
            logger.info(f"Failed to update Experiment {experiment}: {e}")
            metrics.incr("update_ready_to_experiments.failed")
    metrics.incr("update_ready_to_experiments.completed")
Example #2
0
def check_experiment_is_complete():
    metrics.incr("check_experiment_is_complete.started")

    live_experiments = Experiment.objects.filter(
        type=Experiment.TYPE_RAPID, status=Experiment.STATUS_LIVE
    )

    records = client.get_main_records()
    record_ids = [r.get("id") for r in records]

    for experiment in live_experiments:
        if experiment.recipe_slug not in record_ids:
            logger.info(
                "{experiment} status is being updated to complete".format(
                    experiment=experiment
                )
            )
            update_experiment_with_change_log(
                experiment,
                {"status": Experiment.STATUS_COMPLETE},
                settings.KINTO_DEFAULT_CHANGELOG_USER,
            )

            logger.info("Experiment Status is set to complete")

    metrics.incr("check_experiment_is_complete.completed")
Example #3
0
def update_recipe_ids_to_experiments():
    metrics.incr("update_ready_to_ship_experiments.started")
    logger.info("Update Recipes to Experiments")

    ready_to_ship_experiments = Experiment.objects.filter(
        status__in=[Experiment.STATUS_SHIP, Experiment.STATUS_ACCEPTED])

    for experiment in ready_to_ship_experiments:
        try:
            logger.info("Updating Experiment: {}".format(experiment))
            recipe_data = normandy.get_recipe_list(experiment.slug)

            if len(recipe_data):
                sorted_recipe_data = sorted(recipe_data,
                                            key=lambda x: x.get("id"))
                recipe_ids = [r["id"] for r in sorted_recipe_data]
                changed_data = {
                    "normandy_id": recipe_ids[0],
                    "other_normandy_ids": recipe_ids[1:],
                    "status": Experiment.STATUS_ACCEPTED,
                }
                user_email = (sorted_recipe_data[0].get(
                    "latest_revision", {}).get("creator", {}).get(
                        "email",
                        "")) or settings.NORMANDY_DEFAULT_CHANGELOG_USER

                update_experiment_with_change_log(experiment, changed_data,
                                                  user_email)

        except (IntegrityError, KeyError, normandy.NormandyError) as e:
            logger.info(f"Failed to update Experiment {experiment}: {e}")
            metrics.incr("update_ready_to_experiments.failed")
    metrics.incr("update_ready_to_experiments.completed")
Example #4
0
def update_rejected_record(record_id, rejected_data):
    experiment = Experiment.objects.get(recipe_slug=record_id)
    update_experiment_with_change_log(
        experiment,
        {"status": Experiment.STATUS_REJECTED},
        settings.KINTO_DEFAULT_CHANGELOG_USER,
        message=rejected_data["last_reviewer_comment"],
    )
    client.delete_rejected_record(record_id)
Example #5
0
def update_firefox_versions(experiment, recipe_data, filter_objects):
    changed_data = {}

    if versions := filter_objects.get("version"):

        min_version = str(float(min(versions["versions"])))
        max_version = str(float(max(versions["versions"])))
        if experiment.firefox_min_version != min_version:
            changed_data["firefox_min_version"] = min_version
        if experiment.firefox_max_version != max_version:
            changed_data["firefox_max_version"] = max_version

        if changed_data:
            user_email = (recipe_data.get("creator", {}).get(
                "email", "")) or settings.NORMANDY_DEFAULT_CHANGELOG_USER
            update_experiment_with_change_log(experiment,
                                              changed_data,
                                              user_email,
                                              message="Added Version(s)")
Example #6
0
    def create_with_status(cls, target_status, **kwargs):
        from experimenter.experiments.changelog_utils import (
            update_experiment_with_change_log, )

        experiment = cls.create(**kwargs)

        ExperimentControlFactory.create(experiment=experiment,
                                        name="Control",
                                        slug="control")
        ExperimentVariantFactory.create(experiment=experiment,
                                        name="Treatment",
                                        slug="treatment")

        for status, _ in Experiment.STATUS_CHOICES:
            if status == Experiment.STATUS_REVIEW:
                experiment.proposed_duration = 28
                experiment.bugzilla_id = "12345"
                experiment.recipe_slug = experiment.generate_recipe_slug()
                experiment.save()

                ExperimentBucketNamespace.request_namespace_buckets(
                    experiment.recipe_slug,
                    experiment,
                    100,
                )

            update_experiment_with_change_log(
                experiment,
                {"status": status},
                experiment.owner,
            )

            if status == target_status:
                break

        return Experiment.objects.get(id=experiment.id)
Example #7
0
        reject_recipe_id := client.get_rejected_record()
    ):

        update_rejected_record(reject_recipe_id[0], rejected_collection_data)

    if queued_experiments.exists():
        if client.has_pending_review():
            metrics.incr("check_kinto_push_queue.pending_review")
            return

        next_experiment = queued_experiments.first()

        update_experiment_with_change_log(
            next_experiment,
            {
                "status": Experiment.STATUS_ACCEPTED,
                "recipe_slug": next_experiment.generate_recipe_slug(),
            },
            settings.KINTO_DEFAULT_CHANGELOG_USER,
        )

        push_experiment_to_kinto.delay(next_experiment.id)
        metrics.incr("check_kinto_push_queue.queued_experiment_selected")
    else:
        metrics.incr("check_kinto_push_queue.no_experiments_queued")

    metrics.incr("check_kinto_push_queue.completed")


@app.task
@metrics.timer_decorator("check_experiment_is_live")
def check_experiment_is_live():
Example #8
0
            "bucketSample") or filter_objects.get("namespaceSample"):

        decimal.getcontext().prec = 5
        bucket_total = bucket_sample.get("total", experiment.BUCKET_TOTAL)
        percent_decimal = (decimal.Decimal(bucket_sample["count"]) /
                           decimal.Decimal(bucket_total) *
                           decimal.Decimal(100))

        if experiment.population_percent != percent_decimal:
            changed_data = {"population_percent": percent_decimal}

    if changed_data:
        user_email = (recipe_data.get("creator", {}).get(
            "email", "")) or settings.NORMANDY_DEFAULT_CHANGELOG_USER
        update_experiment_with_change_log(experiment,
                                          changed_data,
                                          user_email,
                                          message="Updated Population Percent")


def update_firefox_versions(experiment, recipe_data, filter_objects):
    changed_data = {}

    if versions := filter_objects.get("version"):

        min_version = str(float(min(versions["versions"])))
        max_version = str(float(max(versions["versions"])))
        if experiment.firefox_min_version != min_version:
            changed_data["firefox_min_version"] = min_version
        if experiment.firefox_max_version != max_version:
            changed_data["firefox_max_version"] = max_version