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() == [] )
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), )
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()
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, ), )
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, )
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, )
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, )
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")
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')", ), ]
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),
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),