fix(nimbus): use StrEnum for string conversion (#9933)

Because

- #9921 broke analysis results ingestion by including the enum member in
the string path to results instead of the enum value
- the fix was obvious enough that it was worth fixing instead of
reverting

This commit

- uses `StrEnum` as the base class for enums in
`experimenter.jetstream.models`

Fixes #9932
This commit is contained in:
Mike Williams 2023-12-12 11:59:42 -05:00 коммит произвёл GitHub
Родитель 536e98b8d0
Коммит 1341e904c2
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
2 изменённых файлов: 32 добавлений и 9 удалений

Просмотреть файл

@ -1,4 +1,4 @@
from enum import Enum
from enum import StrEnum
from typing import Any
from mozilla_nimbus_schemas.jetstream import AnalysisBasis
@ -8,32 +8,32 @@ from pydantic import BaseModel, create_model
from experimenter.experiments.models import NimbusExperiment
class AnalysisWindow(str, Enum):
class AnalysisWindow(StrEnum):
DAILY = "daily"
WEEKLY = "weekly"
OVERALL = "overall"
class Significance(str, Enum):
class Significance(StrEnum):
POSITIVE = "positive"
NEGATIVE = "negative"
NEUTRAL = "neutral"
class BranchComparison(str, Enum):
class BranchComparison(StrEnum):
ABSOLUTE = "absolute"
DIFFERENCE = "difference"
UPLIFT = "relative_uplift"
class Metric(str, Enum):
class Metric(StrEnum):
RETENTION = "retained"
SEARCH = "search_count"
DAYS_OF_USE = "days_of_use"
USER_COUNT = "identity"
class Statistic(str, Enum):
class Statistic(StrEnum):
"""
This is the list of statistics supported in Experimenter,
not a complete list of statistics available in Jetstream.
@ -45,13 +45,13 @@ class Statistic(str, Enum):
COUNT = "count"
class Segment(str, Enum):
class Segment(StrEnum):
ALL = "all"
# TODO: Consider a "guardrail_metrics" group containing "days_of_use",
# "retained", and "search_count".
class Group(str, Enum):
class Group(StrEnum):
SEARCH = "search_metrics"
USAGE = "usage_metrics"
OTHER = "other_metrics"

Просмотреть файл

@ -10,7 +10,8 @@ from parameterized import parameterized
from experimenter.experiments.models import NimbusExperiment
from experimenter.experiments.tests.factories import NimbusExperimentFactory
from experimenter.jetstream import tasks
from experimenter.jetstream.models import Group
from experimenter.jetstream.client import get_data
from experimenter.jetstream.models import AnalysisWindow, Group
from experimenter.jetstream.tests import mock_valid_outcomes
from experimenter.jetstream.tests.constants import (
JetstreamTestData,
@ -1113,6 +1114,28 @@ class TestFetchJetstreamDataTask(MockSizingDataMixin, TestCase):
with self.assertRaises(Exception):
tasks.fetch_experiment_data(experiment.id)
@patch("experimenter.jetstream.client.validate_data")
@patch("experimenter.jetstream.client.load_data_from_gcs")
def test_builds_statistics_filename(
self, mock_load_data_from_gcs, mock_validate_data
):
lifecycle = NimbusExperimentFactory.Lifecycles.ENDING_APPROVE_APPROVE
offset = NimbusExperiment.DAYS_ANALYSIS_BUFFER + 1
experiment = NimbusExperimentFactory.create_with_lifecycle(
lifecycle, end_date=datetime.date.today() - datetime.timedelta(days=offset)
)
mock_validate_data.return_value = True
recipe_slug = experiment.slug.replace("-", "_")
window = AnalysisWindow.OVERALL
get_data(recipe_slug, AnalysisWindow.OVERALL)
filename = f"statistics/statistics_{recipe_slug}_{window}.json"
mock_load_data_from_gcs.assert_called_with(filename)
assert "AnalysisWindow" not in filename
assert "overall" in filename
@patch("django.core.files.storage.default_storage.open")
@patch("django.core.files.storage.default_storage.exists")
def test_sizing_data_parsed_and_stored(self, mock_exists, mock_open):