Example #1
0
def test_message_ordering_enabled(creds):
    client = publisher.Client(credentials=creds)
    assert not client._enable_message_ordering

    client = publisher.Client(
        publisher_options=types.PublisherOptions(enable_message_ordering=True),
        credentials=creds,
    )
    assert client._enable_message_ordering
def test_message_ordering_changes_retry_deadline():
    creds = mock.Mock(spec=credentials.Credentials)

    client = publisher.Client(credentials=creds)
    assert client.api._method_configs["Publish"].retry._deadline == 60

    client = publisher.Client(
        publisher_options=types.PublisherOptions(enable_message_ordering=True),
        credentials=creds,
    )
    assert client.api._method_configs["Publish"].retry._deadline == 2 ** 32 / 1000
Example #3
0
def test_publish_data_not_bytestring_error(creds):
    client = publisher.Client(credentials=creds)
    topic = "topic/path"
    with pytest.raises(TypeError):
        client.publish(topic, "This is a text string.")
    with pytest.raises(TypeError):
        client.publish(topic, 42)
Example #4
0
def test_publish(creds):
    client = publisher.Client(credentials=creds)

    future1 = mock.sentinel.future1
    future2 = mock.sentinel.future2
    future1.add_done_callback = mock.Mock(spec=["__call__"])
    future2.add_done_callback = mock.Mock(spec=["__call__"])

    # Use a mock in lieu of the actual batch class.
    batch = mock.Mock(spec=client._batch_class)

    # Set the mock up to claim indiscriminately that it accepts all messages.
    batch.publish.side_effect = (future1, future2)

    topic = "topic/path"
    client._set_batch(topic, batch)

    # Begin publishing.
    future1 = client.publish(topic, b"spam")
    future2 = client.publish(topic, b"foo", bar="baz")

    assert future1 is mock.sentinel.future1
    assert future2 is mock.sentinel.future2

    # Check mock.
    batch.publish.assert_has_calls([
        mock.call(gapic_types.PubsubMessage(data=b"spam")),
        mock.call(
            gapic_types.PubsubMessage(data=b"foo", attributes={"bar": "baz"})),
    ])
def test_publish():
    client = publisher.Client()

    # Use a mock in lieu of the actual batch class; set the mock up to claim
    # indiscriminately that it accepts all messages.
    batch = mock.Mock(spec=client._batch_class)
    batch.will_accept.return_value = True
    client._batches['topic_name'] = batch

    # Begin publishing.
    client.publish('topic_name', b'spam')
    client.publish('topic_name', b'foo', bar='baz')

    # The batch's publish method should have been called twice.
    assert batch.publish.call_count == 2

    # In both cases
    # The first call should correspond to the first message.
    _, args, _ = batch.publish.mock_calls[0]
    assert args[0].data == b'spam'
    assert not args[0].attributes

    # The second call should correspond to the second message.
    _, args, _ = batch.publish.mock_calls[1]
    assert args[0].data == b'foo'
    assert args[0].attributes == {u'bar': u'baz'}
Example #6
0
def test_init_w_api_endpoint(creds):
    client_options = {"api_endpoint": "testendpoint.google.com"}
    client = publisher.Client(client_options=client_options, credentials=creds)

    assert isinstance(client.api, publisher_client.PublisherClient)
    assert (client.api._transport.grpc_channel._channel.target()
            ).decode("utf-8") == "testendpoint.google.com:443"
Example #7
0
def test_publish():
    creds = mock.Mock(spec=credentials.Credentials)
    client = publisher.Client(credentials=creds)

    # Use a mock in lieu of the actual batch class.
    batch = mock.Mock(spec=client._batch_class)
    # Set the mock up to claim indiscriminately that it accepts all messages.
    batch.will_accept.return_value = True
    batch.publish.side_effect = (mock.sentinel.future1, mock.sentinel.future2)

    topic = "topic/path"
    client._batches[topic] = batch

    # Begin publishing.
    future1 = client.publish(topic, b"spam")
    future2 = client.publish(topic, b"foo", bar="baz")

    assert future1 is mock.sentinel.future1
    assert future2 is mock.sentinel.future2

    # Check mock.
    batch.publish.assert_has_calls([
        mock.call(types.PubsubMessage(data=b"spam")),
        mock.call(types.PubsubMessage(data=b"foo", attributes={"bar": "baz"})),
    ])
Example #8
0
def test_ordered_sequencer_cleaned_up(creds):
    # Max latency is infinite so a commit thread is not created.
    # We don't want a commit thread to interfere with this test.
    batch_settings = types.BatchSettings(max_latency=float("inf"))
    publisher_options = types.PublisherOptions(enable_message_ordering=True)
    client = publisher.Client(
        batch_settings=batch_settings,
        publisher_options=publisher_options,
        credentials=creds,
    )

    topic = "topic"
    ordering_key = "ord_key"
    sequencer = mock.Mock(spec=ordered_sequencer.OrderedSequencer)
    sequencer.is_finished.return_value = False
    client._set_sequencer(topic=topic,
                          sequencer=sequencer,
                          ordering_key=ordering_key)

    assert len(client._sequencers) == 1
    # 'sequencer' is not finished yet so don't remove it.
    client._commit_sequencers()
    assert len(client._sequencers) == 1

    sequencer.is_finished.return_value = True
    # 'sequencer' is finished so remove it.
    client._commit_sequencers()
    assert len(client._sequencers) == 0
def test_init_w_empty_client_options():
    client = publisher.Client(client_options={})

    assert isinstance(client.api, publisher_client.PublisherClient)
    assert (client.api._transport.grpc_channel._channel.target()).decode(
        "utf-8"
    ) == publisher_client.PublisherClient.SERVICE_ADDRESS
Example #10
0
def test_publish_new_batch_needed():
    creds = mock.Mock(spec=credentials.Credentials)
    client = publisher.Client(credentials=creds)

    # Use mocks in lieu of the actual batch class.
    batch1 = mock.Mock(spec=client._batch_class)
    batch2 = mock.Mock(spec=client._batch_class)
    # Set the first mock up to claim indiscriminately that it rejects all
    # messages and the second accepts all.
    batch1.publish.return_value = None
    batch2.publish.return_value = mock.sentinel.future

    topic = "topic/path"
    client._batches[topic] = batch1

    # Actually mock the batch class now.
    batch_class = mock.Mock(spec=(), return_value=batch2)
    client._batch_class = batch_class

    # Publish a message.
    future = client.publish(topic, b"foo", bar=b"baz")
    assert future is mock.sentinel.future

    # Check the mocks.
    batch_class.assert_called_once_with(autocommit=True,
                                        client=client,
                                        settings=client.batch_settings,
                                        topic=topic)
    message_pb = types.PubsubMessage(data=b"foo", attributes={"bar": u"baz"})
    batch1.publish.assert_called_once_with(message_pb)
    batch2.publish.assert_called_once_with(message_pb)
Example #11
0
def test_init_w_unicode_api_endpoint():
    client_options = {"api_endpoint": u"testendpoint.google.com"}
    client = publisher.Client(client_options=client_options)

    assert isinstance(client.api, publisher_client.PublisherClient)
    assert (client.api.transport._channel._channel.target()
            ).decode("utf-8") == "testendpoint.google.com"
Example #12
0
def test_publish_with_ordering_key():
    creds = mock.Mock(spec=credentials.Credentials)
    publisher_options = types.PublisherOptions(enable_message_ordering=True)
    client = publisher.Client(publisher_options=publisher_options,
                              credentials=creds)

    # Use a mock in lieu of the actual batch class.
    batch = mock.Mock(spec=client._batch_class)
    # Set the mock up to claim indiscriminately that it accepts all messages.
    batch.will_accept.return_value = True
    batch.publish.side_effect = (mock.sentinel.future1, mock.sentinel.future2)

    topic = "topic/path"
    ordering_key = "k1"
    client._set_batch(topic, batch, ordering_key=ordering_key)

    # Begin publishing.
    future1 = client.publish(topic, b"spam", ordering_key=ordering_key)
    future2 = client.publish(topic,
                             b"foo",
                             bar="baz",
                             ordering_key=ordering_key)

    assert future1 is mock.sentinel.future1
    assert future2 is mock.sentinel.future2

    # Check mock.
    batch.publish.assert_has_calls([
        mock.call(types.PubsubMessage(data=b"spam", ordering_key="k1")),
        mock.call(
            types.PubsubMessage(data=b"foo",
                                attributes={"bar": "baz"},
                                ordering_key="k1")),
    ])
Example #13
0
def test_stop():
    creds = mock.Mock(spec=credentials.Credentials)
    client = publisher.Client(credentials=creds)

    batch = client._batch("topic1", autocommit=False)
    batch2 = client._batch("topic2", autocommit=False)

    pubsub_msg = types.PubsubMessage(data=b"msg")

    patch = mock.patch.object(batch, "commit")
    patch2 = mock.patch.object(batch2, "commit")

    with patch as commit_mock, patch2 as commit_mock2:
        batch.publish(pubsub_msg)
        batch2.publish(pubsub_msg)

        client.stop()

        # check if commit() called
        commit_mock.assert_called()
        commit_mock2.assert_called()

    # check that closed publisher doesn't accept new messages
    with pytest.raises(RuntimeError):
        client.publish("topic1", b"msg2")

    with pytest.raises(RuntimeError):
        client.stop()
def test_publish_data_not_bytestring_error():
    creds = mock.Mock(spec=credentials.Credentials)
    client = publisher.Client(credentials=creds)
    with pytest.raises(TypeError):
        client.publish('topic_name', u'This is a text string.')
    with pytest.raises(TypeError):
        client.publish('topic_name', 42)
def test_gapic_instance_method():
    client = publisher.Client()
    with mock.patch.object(client.api, '_create_topic', autospec=True) as ct:
        client.create_topic('projects/foo/topics/bar')
        assert ct.call_count == 1
        _, args, _ = ct.mock_calls[0]
        assert args[0] == types.Topic(name='projects/foo/topics/bar')
Example #16
0
def test_commit_thread_not_created_on_publish_if_max_latency_is_inf(creds):
    # Max latency is infinite so a commit thread is not created.
    batch_settings = types.BatchSettings(max_latency=float("inf"))
    client = publisher.Client(batch_settings=batch_settings, credentials=creds)

    assert client.publish("topic", b"bytestring body",
                          ordering_key="") is not None
    assert client._commit_thread is None
Example #17
0
def test_publish_empty_ordering_key_when_message_ordering_enabled(creds):
    client = publisher.Client(
        publisher_options=types.PublisherOptions(enable_message_ordering=True),
        credentials=creds,
    )
    topic = "topic/path"
    assert client.publish(topic, b"bytestring body",
                          ordering_key="") is not None
Example #18
0
 def Start(self, request, context):
     self.message_size = request.message_size
     self.batch_size = request.publish_batch_size
     self.topic = "projects/" + request.project + "/topics/" + request.topic
     self.client = publisher.Client(batch_settings=BatchSettings(
         max_latency=float(request.publish_batch_duration.seconds) +
         float(request.publish_batch_duration.nanos) / 1000000000.0))
     return loadtest_pb2.StartResponse()
Example #19
0
def test_resume_publish_ordering_keys_not_enabled(creds):
    publisher_options = types.PublisherOptions(enable_message_ordering=False)
    client = publisher.Client(publisher_options=publisher_options,
                              credentials=creds)

    # Throw on calling resume_publish() when enable_message_ordering is False.
    with pytest.raises(ValueError):
        client.resume_publish("topic", "ord_key")
Example #20
0
def test_batch_create():
    creds = mock.Mock(spec=credentials.Credentials)
    client = publisher.Client(credentials=creds)

    assert len(client._batches) == 0
    topic = "topic/path"
    batch = client._batch(topic, autocommit=False)
    assert client._batches == {topic: batch}
Example #21
0
def test_resume_publish_no_sequencer_found(creds):
    publisher_options = types.PublisherOptions(enable_message_ordering=True)
    client = publisher.Client(publisher_options=publisher_options,
                              credentials=creds)

    # Check no exception is thrown if a sequencer with the (topic, ordering_key)
    # pair does not exist.
    client.resume_publish("topic", "ord_key")
Example #22
0
def test_publish_data_too_large():
    creds = mock.Mock(spec=credentials.Credentials)
    client = publisher.Client(credentials=creds)
    topic = 'topic/path'
    client.batch_settings = types.BatchSettings(
        0, client.batch_settings.max_latency,
        client.batch_settings.max_messages)
    with pytest.raises(ValueError):
        client.publish(topic, b'This is a text string.')
Example #23
0
def test_init(creds):
    client = publisher.Client(credentials=creds)

    # A plain client should have an `api` (the underlying GAPIC) and a
    # batch settings object, which should have the defaults.
    assert isinstance(client.api, publisher_client.PublisherClient)
    assert client.batch_settings.max_bytes == 1 * 1000 * 1000
    assert client.batch_settings.max_latency == 0.01
    assert client.batch_settings.max_messages == 100
def test_init_emulator(monkeypatch):
    monkeypatch.setenv('PUBSUB_EMULATOR_HOST', '/foo/bar/')
    client = publisher.Client()

    # Establish that a gRPC request would attempt to hit the emulator host.
    #
    # Sadly, there seems to be no good way to do this without poking at
    # the private API of gRPC.
    channel = client.api.publisher_stub.Publish._channel
    assert channel.target().decode('utf8') == '/foo/bar/'
def test_batch_without_autocreate():
    client = publisher.Client()
    message = types.PubsubMessage(data=b'foo')

    # If `create=False` is sent, then when the batch is not found, None
    # is returned instead.
    ante = len(client._batches)
    batch = client.batch('topic_name', message, create=False)
    assert batch is None
    assert len(client._batches) == ante
Example #26
0
def test_batch_create_and_exists():
    creds = mock.Mock(spec=credentials.Credentials)
    client = publisher.Client(credentials=creds)

    topic = "topic/path"
    client._batches[topic] = mock.sentinel.batch

    # A subsequent request should return the same batch.
    batch = client._batch(topic, create=True, autocommit=False)
    assert batch is not mock.sentinel.batch
    assert client._batches == {topic: batch}
Example #27
0
def test_init_w_custom_transport():
    transport = object()
    client = publisher.Client(transport=transport)

    # A plain client should have an `api` (the underlying GAPIC) and a
    # batch settings object, which should have the defaults.
    assert isinstance(client.api, publisher_client.PublisherClient)
    assert client.api.transport is transport
    assert client.batch_settings.max_bytes == 10 * 1000 * 1000
    assert client.batch_settings.max_latency == 0.05
    assert client.batch_settings.max_messages == 1000
Example #28
0
def test_gapic_instance_method():
    creds = mock.Mock(spec=credentials.Credentials)
    client = publisher.Client(credentials=creds)

    ct = mock.Mock()
    client.api._inner_api_calls["create_topic"] = ct

    client.create_topic("projects/foo/topics/bar")
    assert ct.call_count == 1
    _, args, _ = ct.mock_calls[0]
    assert args[0] == types.Topic(name="projects/foo/topics/bar")
Example #29
0
def test_init_emulator(monkeypatch):
    monkeypatch.setenv("PUBSUB_EMULATOR_HOST", "/foo/bar/")
    # NOTE: When the emulator host is set, a custom channel will be used, so
    #       no credentials (mock ot otherwise) can be passed in.
    client = publisher.Client()

    # Establish that a gRPC request would attempt to hit the emulator host.
    #
    # Sadly, there seems to be no good way to do this without poking at
    # the private API of gRPC.
    channel = client.api.transport.publish._channel
    assert channel.target().decode("utf8") == "/foo/bar/"
def test_resume_publish():
    creds = mock.Mock(spec=credentials.Credentials)
    publisher_options = types.PublisherOptions(enable_message_ordering=True)
    client = publisher.Client(publisher_options=publisher_options, credentials=creds)

    topic = "topic"
    ordering_key = "ord_key"
    sequencer = mock.Mock(spec=ordered_sequencer.OrderedSequencer)
    client._set_sequencer(topic=topic, sequencer=sequencer, ordering_key=ordering_key)

    client.resume_publish(topic, ordering_key)
    assert sequencer.unpause.called_once()