def test_register(self):
     callback = object()
     other_callback = object()
     register_subscriber("hello")(callback)
     assert subscriber_registry["hello"] == callback
     register_subscriber("goodbye")(other_callback)
     assert subscriber_registry["goodbye"] == other_callback
    def test_normal(self):
        cluster_name = settings.KAFKA_TOPICS[self.topic]["cluster"]

        conf = {
            "bootstrap.servers":
            settings.KAFKA_CLUSTERS[cluster_name]["bootstrap.servers"],
            "session.timeout.ms":
            6000,
        }

        producer = Producer(conf)
        producer.produce(self.topic, json.dumps(self.valid_wrapper))
        producer.flush()
        mock_callback = Mock()
        mock_callback.side_effect = KeyboardInterrupt()
        register_subscriber(self.registration_key)(mock_callback)
        sub = self.create_subscription()
        consumer = QuerySubscriptionConsumer("hi",
                                             topic=self.topic,
                                             commit_batch_size=1)
        consumer.run()

        payload = self.valid_payload
        payload["values"] = payload["result"]
        payload["timestamp"] = parse_date(
            payload["timestamp"]).replace(tzinfo=pytz.utc)
        mock_callback.assert_called_once_with(payload, sub)
    def test_normal(self):
        cluster_name = settings.KAFKA_TOPICS[self.topic]["cluster"]

        conf = {
            "bootstrap.servers":
            settings.KAFKA_CLUSTERS[cluster_name]["bootstrap.servers"],
            "session.timeout.ms":
            6000,
        }

        producer = Producer(conf)
        producer.produce(self.topic, json.dumps(self.valid_wrapper))
        producer.flush()
        mock_callback = Mock()
        mock_callback.side_effect = KeyboardInterrupt()
        register_subscriber(self.registration_key)(mock_callback)
        sub = QuerySubscription.objects.create(
            project=self.project,
            type=self.registration_key,
            subscription_id=self.subscription_id,
            dataset="something",
            query="hello",
            aggregations=[],
            time_window=1,
            resolution=1,
        )
        consumer = QuerySubscriptionConsumer("hi",
                                             topic=self.topic,
                                             commit_batch_size=1)
        consumer.run()
        mock_callback.assert_called_once_with(self.valid_payload, sub)
    def test_subscription_registered(self):
        registration_key = "registered_test"
        mock_callback = Mock()
        register_subscriber(registration_key)(mock_callback)
        with self.tasks():
            snuba_query = create_snuba_query(
                QueryDatasets.EVENTS,
                "hello",
                QueryAggregations.TOTAL,
                timedelta(minutes=10),
                timedelta(minutes=1),
                None,
            )
            sub = create_snuba_subscription(self.project, registration_key,
                                            snuba_query)
        sub.refresh_from_db()

        data = self.valid_wrapper
        data["payload"]["subscription_id"] = sub.subscription_id
        self.consumer.handle_message(self.build_mock_message(data))
        data = deepcopy(data)
        data["payload"]["values"] = data["payload"]["result"]
        data["payload"]["timestamp"] = parse_date(
            data["payload"]["timestamp"]).replace(tzinfo=pytz.utc)
        mock_callback.assert_called_once_with(data["payload"], sub)
예제 #5
0
 def test_already_registered(self):
     callback = object()
     other_callback = object()
     register_subscriber("hello")(callback)
     assert subscriber_registry["hello"] == callback
     with self.assertRaises(Exception) as cm:
         register_subscriber("hello")(other_callback)
     assert six.text_type(cm.exception) == "Handler already registered for hello"
    def test_shutdown(self):
        self.producer.produce(self.topic, json.dumps(self.valid_wrapper))
        valid_wrapper_2 = deepcopy(self.valid_wrapper)
        valid_wrapper_2["payload"]["values"]["hello"] = 25
        valid_wrapper_3 = deepcopy(valid_wrapper_2)
        valid_wrapper_3["payload"]["values"]["hello"] = 5000
        self.producer.produce(self.topic, json.dumps(valid_wrapper_2))
        self.producer.flush()

        counts = [0]

        def mock_callback(*args, **kwargs):
            counts[0] += 1
            if counts[0] > 1:
                raise KeyboardInterrupt()

        mock = Mock()
        mock.side_effect = mock_callback

        register_subscriber(self.registration_key)(mock)
        sub = QuerySubscription.objects.create(
            project=self.project,
            type=self.registration_key,
            subscription_id=self.subscription_id,
            dataset="something",
            query="hello",
            aggregation=0,
            time_window=1,
            resolution=1,
        )
        consumer = QuerySubscriptionConsumer("hi",
                                             topic=self.topic,
                                             commit_batch_size=100)
        consumer.run()
        valid_payload = self.valid_payload
        valid_payload["timestamp"] = parse_date(
            valid_payload["timestamp"]).replace(tzinfo=pytz.utc)
        valid_wrapper_2["payload"]["timestamp"] = parse_date(
            valid_wrapper_2["payload"]["timestamp"]).replace(tzinfo=pytz.utc)
        mock.assert_has_calls(
            [call(valid_payload, sub),
             call(valid_wrapper_2["payload"], sub)])
        # Offset should be committed for the first message, so second run should process
        # the second message again
        self.producer.produce(self.topic, json.dumps(valid_wrapper_3))
        self.producer.flush()
        mock.reset_mock()
        counts[0] = 0
        consumer.run()
        valid_wrapper_3["payload"]["timestamp"] = parse_date(
            valid_wrapper_3["payload"]["timestamp"]).replace(tzinfo=pytz.utc)

        mock.assert_has_calls([
            call(valid_wrapper_2["payload"], sub),
            call(valid_wrapper_3["payload"], sub)
        ])
예제 #7
0
    def test_shutdown(self):
        valid_wrapper_2 = deepcopy(self.valid_wrapper)
        valid_wrapper_2["payload"]["result"]["hello"] = 25

        valid_wrapper_3 = deepcopy(self.valid_wrapper)
        valid_wrapper_3["payload"]["result"]["hello"] = 5000

        self.producer.produce(self.topic, json.dumps(self.valid_wrapper))
        self.producer.produce(self.topic, json.dumps(valid_wrapper_2))
        self.producer.produce(self.topic, json.dumps(valid_wrapper_3))
        self.producer.flush()

        def normalize_payload(payload):
            return {
                **payload,
                "values":
                payload["result"],
                "timestamp":
                parse_date(payload["timestamp"]).replace(tzinfo=pytz.utc),
            }

        consumer = QuerySubscriptionConsumer("hi",
                                             topic=self.topic,
                                             commit_batch_size=100)

        def mock_callback(*args, **kwargs):
            if mock.call_count >= len(expected_calls):
                consumer.shutdown()

        mock = Mock(side_effect=mock_callback)

        register_subscriber(self.registration_key)(mock)
        sub = self.create_subscription()

        expected_calls = [
            call(normalize_payload(self.valid_payload), sub),
            call(normalize_payload(valid_wrapper_2["payload"]), sub),
        ]

        consumer.run()

        mock.assert_has_calls(expected_calls)

        expected_calls = [
            call(normalize_payload(valid_wrapper_3["payload"]), sub)
        ]
        mock.reset_mock()

        consumer.run()

        mock.assert_has_calls(expected_calls)
 def test_subscription_registered(self):
     registration_key = "registered_test"
     mock_callback = Mock()
     register_subscriber(registration_key)(mock_callback)
     sub = QuerySubscription.objects.create(
         project=self.project,
         type=registration_key,
         subscription_id="an_id",
         dataset="something",
         query="hello",
         aggregation=0,
         time_window=1,
         resolution=1,
     )
     data = self.valid_wrapper
     data["payload"]["subscription_id"] = sub.subscription_id
     self.consumer.handle_message(self.build_mock_message(data))
     mock_callback.assert_called_once_with(data["payload"], sub)
    def test_batch_timeout(self, commit_offset_mock):
        self.producer.produce(self.topic, json.dumps(self.valid_wrapper))
        self.producer.flush()

        consumer = QuerySubscriptionConsumer("hi",
                                             topic=self.topic,
                                             commit_batch_size=100,
                                             commit_batch_timeout_ms=1)

        def mock_callback(*args, **kwargs):
            time.sleep(0.1)
            consumer.shutdown()

        mock = Mock(side_effect=mock_callback)

        register_subscriber(self.registration_key)(mock)
        self.create_subscription()

        consumer.run()
        # Once on revoke, once on shutdown, and once due to batch timeout
        assert len(commit_offset_mock.call_args_list) == 3