Пример #1
0
    def test(self) -> None:
        creator = SubscriptionCreator(self.dataset)
        subscription = LegacySubscriptionData(
            project_id=1,
            conditions=[],
            aggregations=[["count()", "", "count"]],
            time_window=timedelta(minutes=10),
            resolution=timedelta(minutes=1),
        )
        identifier = creator.create(subscription, Timer("test"))
        assert (
            cast(
                List[Tuple[UUID, SubscriptionData]],
                RedisSubscriptionDataStore(
                    redis_client, self.dataset, identifier.partition,
                ).all(),
            )[0][1]
            == subscription
        )

        SubscriptionDeleter(self.dataset, identifier.partition).delete(identifier.uuid)
        assert (
            RedisSubscriptionDataStore(
                redis_client, self.dataset, identifier.partition,
            ).all()
            == []
        )
Пример #2
0
def build_legacy_subscription_data() -> LegacySubscriptionData:
    return LegacySubscriptionData(
        project_id=5,
        conditions=[["platform", "IN", ["a"]]],
        aggregations=[["count()", "", "count"]],
        time_window=timedelta(minutes=500),
        resolution=timedelta(minutes=1),
    )
Пример #3
0
def test_subscription_task_result_encoder() -> None:
    codec = SubscriptionTaskResultEncoder()

    timestamp = datetime.now()

    subscription_data = LegacySubscriptionData(
        project_id=1,
        conditions=[],
        aggregations=[["count()", "", "count"]],
        time_window=timedelta(minutes=1),
        resolution=timedelta(minutes=1),
    )

    # XXX: This seems way too coupled to the dataset.
    request = subscription_data.build_request(get_dataset("events"), timestamp,
                                              None, Timer("timer"))
    result: Result = {
        "meta": [{
            "type": "UInt64",
            "name": "count"
        }],
        "data": [{
            "count": 1
        }],
    }

    task_result = SubscriptionTaskResult(
        ScheduledTask(
            timestamp,
            Subscription(
                SubscriptionIdentifier(PartitionId(1), uuid.uuid1()),
                subscription_data,
            ),
        ),
        (request, result),
    )

    message = codec.encode(task_result)
    data = json.loads(message.value.decode("utf-8"))
    assert data["version"] == 2
    payload = data["payload"]

    assert payload["subscription_id"] == str(task_result.task.task.identifier)
    assert payload["request"] == request.body
    assert payload["result"] == result
    assert payload["timestamp"] == task_result.task.timestamp.isoformat()
Пример #4
0
 def build_subscription(self, resolution: timedelta) -> Subscription:
     return Subscription(
         SubscriptionIdentifier(self.partition_id, uuid.uuid4()),
         LegacySubscriptionData(
             project_id=1,
             conditions=[],
             aggregations=[["count()", "", "count"]],
             time_window=timedelta(minutes=1),
             resolution=resolution,
         ),
     )
Пример #5
0
    def test_invalid_time_window(self) -> None:
        creator = SubscriptionCreator(self.dataset)
        with raises(InvalidSubscriptionError):
            creator.create(
                LegacySubscriptionData(
                    123,
                    timedelta(minutes=1),
                    timedelta(),
                    [["platfo", "IN", ["a"]]],
                    [["count()", "", "count"]],
                ),
                self.timer,
            )

        with raises(InvalidSubscriptionError):
            creator.create(
                SnQLSubscriptionData(
                    project_id=123,
                    query=(
                        "MATCH (events) "
                        "SELECT count() AS count BY time "
                        "WHERE "
                        "platform IN tuple('a') "
                    ),
                    time_window=timedelta(minutes=1),
                    resolution=timedelta(),
                ),
                self.timer,
            )

        with raises(InvalidSubscriptionError):
            creator.create(
                LegacySubscriptionData(
                    123,
                    timedelta(minutes=1),
                    timedelta(hours=48),
                    [["platfo", "IN", ["a"]]],
                    [["count()", "", "count"]],
                ),
                self.timer,
            )
Пример #6
0
 def test_invalid_resolution(self) -> None:
     creator = SubscriptionCreator(self.dataset)
     with raises(InvalidSubscriptionError):
         creator.create(
             LegacySubscriptionData(
                 123,
                 timedelta(),
                 timedelta(minutes=1),
                 [["platfo", "IN", ["a"]]],
                 [["count()", "", "count"]],
             ),
             self.timer,
         )
Пример #7
0
 def test_invalid_aggregation(self) -> None:
     creator = SubscriptionCreator(self.dataset)
     with raises(QueryException):
         creator.create(
             LegacySubscriptionData(
                 123,
                 timedelta(minutes=1),
                 timedelta(minutes=10),
                 [["platform", "IN", ["a"]]],
                 [["cout()", "", "count"]],
             ),
             self.timer,
         )
Пример #8
0
    def decode(self, value: bytes) -> SubscriptionData:
        try:
            data = json.loads(value.decode("utf-8"))
        except json.JSONDecodeError:
            raise InvalidQueryException("Invalid JSON")

        subscription_type = data.get(SubscriptionData.TYPE_FIELD)
        if subscription_type == SubscriptionType.SNQL.value:
            return SnQLSubscriptionData.from_dict(data)
        elif subscription_type == SubscriptionType.DELEGATE.value:
            return DelegateSubscriptionData.from_dict(data)
        elif subscription_type is None:
            return LegacySubscriptionData.from_dict(data)
        else:
            raise InvalidSubscriptionError("Invalid subscription data")
Пример #9
0
 def subscription(self) -> Sequence[SubscriptionData]:
     return [
         LegacySubscriptionData(
             project_id=self.project_id,
             conditions=[["platform", "IN", ["a"]]],
             aggregations=[["count()", "", "count"]],
             time_window=timedelta(minutes=500),
             resolution=timedelta(minutes=1),
         ),
         SnQLSubscriptionData(
             project_id=self.project_id,
             time_window=timedelta(minutes=500),
             resolution=timedelta(minutes=1),
             query="MATCH events SELECT count() WHERE in(platform, 'a')",
         ),
     ]
Пример #10
0
    LegacySubscriptionData,
    SnQLSubscriptionData,
    SubscriptionData,
)
from snuba.subscriptions.store import RedisSubscriptionDataStore
from snuba.subscriptions.subscription import SubscriptionCreator, SubscriptionDeleter
from snuba.utils.metrics.timer import Timer
from snuba.web import QueryException
from tests.subscriptions import BaseSubscriptionTest

TESTS_CREATE = [
    pytest.param(
        LegacySubscriptionData(
            project_id=123,
            conditions=[["platform", "IN", ["a"]]],
            aggregations=[["count()", "", "count"]],
            time_window=timedelta(minutes=10),
            resolution=timedelta(minutes=1),
        ),
        id="Legacy subscription",
    ),
    pytest.param(
        SnQLSubscriptionData(
            project_id=123,
            query=(
                "MATCH (events) "
                "SELECT count() AS count "
                "WHERE "
                "platform IN tuple('a')"
            ),
            time_window=timedelta(minutes=10),
Пример #11
0
    Matches one specific datetime.
    """

    value: datetime

    def match(self, node: Any) -> Optional[MatchResult]:
        return MatchResult() if node == self.value else None


@pytest.fixture(
    ids=["Legacy", "SnQL", "Delegate"],
    params=[
        LegacySubscriptionData(
            project_id=1,
            conditions=[],
            aggregations=[["count()", "", "count"]],
            time_window=timedelta(minutes=60),
            resolution=timedelta(minutes=1),
        ),
        SnQLSubscriptionData(
            project_id=1,
            query=("MATCH (events) SELECT count() AS count"),
            time_window=timedelta(minutes=60),
            resolution=timedelta(minutes=1),
        ),
        DelegateSubscriptionData(
            project_id=1,
            conditions=[],
            aggregations=[["count()", "", "count"]],
            query=("MATCH (events) SELECT count() AS count"),
            time_window=timedelta(minutes=60),