Search in sources :

Example 16 with Timeout

use of io.vertx.junit5.Timeout in project hono by eclipse.

the class HonoConnectionImplTest method testCreateSenderFailsOnDisconnectBeforeOpen.

/**
 * Verifies that the attempt to create a sender fails with a
 * {@code ServerErrorException} if the connection gets disconnected
 * before the remote peer has sent its attach frame. It is verified
 * that this is done before the link establishment timeout.
 *
 * @param ctx The vert.x test context.
 */
@Test
public void testCreateSenderFailsOnDisconnectBeforeOpen(final VertxTestContext ctx) {
    // choose a distinct value here
    final long linkEstablishmentTimeout = 444L;
    props.setLinkEstablishmentTimeout(linkEstablishmentTimeout);
    // don't run linkEstablishmentTimeout timer handler
    when(vertx.setTimer(eq(linkEstablishmentTimeout), VertxMockSupport.anyHandler())).thenAnswer(invocation -> 0L);
    final ProtonSender sender = mock(ProtonSender.class);
    when(sender.isOpen()).thenReturn(Boolean.TRUE);
    when(session.createSender(anyString())).thenReturn(sender);
    final Target target = new Target();
    target.setAddress("someAddress");
    when(sender.getRemoteTarget()).thenReturn(target);
    when(sender.getCredit()).thenReturn(0);
    // mock handlers
    final Handler<String> remoteCloseHook = VertxMockSupport.mockHandler();
    // GIVEN an established connection
    honoConnection.connect().compose(c -> {
        // WHEN creating a sender link with a close hook
        final Future<ProtonSender> result = honoConnection.createSender("target", ProtonQoS.AT_LEAST_ONCE, remoteCloseHook);
        // THEN the result is not completed at first
        ctx.verify(() -> assertThat(result.isComplete()).isFalse());
        // WHEN the downstream connection fails
        connectionFactory.getDisconnectHandler().handle(con);
        return result;
    }).onComplete(ctx.failing(t -> {
        ctx.verify(() -> assertThat(((ServerErrorException) t).getErrorCode()).isEqualTo(HttpURLConnection.HTTP_UNAVAILABLE));
        ctx.completeNow();
    }));
}
Also used : HttpURLConnection(java.net.HttpURLConnection) ProtonConnection(io.vertx.proton.ProtonConnection) ProtonReceiver(io.vertx.proton.ProtonReceiver) BeforeEach(org.junit.jupiter.api.BeforeEach) ArgumentMatchers.eq(org.mockito.ArgumentMatchers.eq) Context(io.vertx.core.Context) Timeout(io.vertx.junit5.Timeout) ConnectionFactory(org.eclipse.hono.connection.ConnectionFactory) SaslSystemException(io.vertx.proton.sasl.SaslSystemException) ExtendWith(org.junit.jupiter.api.extension.ExtendWith) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) ProtonMessageHandler(io.vertx.proton.ProtonMessageHandler) Mockito.doAnswer(org.mockito.Mockito.doAnswer) DisconnectListener(org.eclipse.hono.client.DisconnectListener) AmqpError(org.apache.qpid.proton.amqp.transport.AmqpError) ClientConfigProperties(org.eclipse.hono.config.ClientConfigProperties) Predicate(java.util.function.Predicate) ProtonQoS(io.vertx.proton.ProtonQoS) VertxExtension(io.vertx.junit5.VertxExtension) Future(io.vertx.core.Future) AdditionalAnswers(org.mockito.AdditionalAnswers) Test(org.junit.jupiter.api.Test) ErrorCondition(org.apache.qpid.proton.amqp.transport.ErrorCondition) VertxMockSupport(org.eclipse.hono.test.VertxMockSupport) ProtonSender(io.vertx.proton.ProtonSender) Mockito.mock(org.mockito.Mockito.mock) ArgumentMatchers.any(org.mockito.ArgumentMatchers.any) VertxTestContext(io.vertx.junit5.VertxTestContext) ArgumentMatchers.anyLong(org.mockito.ArgumentMatchers.anyLong) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) Target(org.apache.qpid.proton.amqp.messaging.Target) ClientErrorException(org.eclipse.hono.client.ClientErrorException) ServiceInvocationException(org.eclipse.hono.client.ServiceInvocationException) AtomicReference(java.util.concurrent.atomic.AtomicReference) Supplier(java.util.function.Supplier) CompositeFuture(io.vertx.core.CompositeFuture) ProtonSession(io.vertx.proton.ProtonSession) TelemetryConstants(org.eclipse.hono.util.TelemetryConstants) ArgumentCaptor(org.mockito.ArgumentCaptor) ProtonClientOptions(io.vertx.proton.ProtonClientOptions) Symbol(org.apache.qpid.proton.amqp.Symbol) BiConsumer(java.util.function.BiConsumer) UnsignedLong(org.apache.qpid.proton.amqp.UnsignedLong) AsyncResult(io.vertx.core.AsyncResult) HonoConnection(org.eclipse.hono.client.HonoConnection) Promise(io.vertx.core.Promise) Vertx(io.vertx.core.Vertx) ServerErrorException(org.eclipse.hono.client.ServerErrorException) Mockito.times(org.mockito.Mockito.times) Mockito.when(org.mockito.Mockito.when) Truth.assertThat(com.google.common.truth.Truth.assertThat) Mockito.verify(org.mockito.Mockito.verify) TimeUnit(java.util.concurrent.TimeUnit) Mockito.never(org.mockito.Mockito.never) Source(org.apache.qpid.proton.amqp.transport.Source) Handler(io.vertx.core.Handler) ArgumentMatchers.anyString(org.mockito.ArgumentMatchers.anyString) ProtonSender(io.vertx.proton.ProtonSender) Target(org.apache.qpid.proton.amqp.messaging.Target) Future(io.vertx.core.Future) CompositeFuture(io.vertx.core.CompositeFuture) ArgumentMatchers.anyString(org.mockito.ArgumentMatchers.anyString) ServerErrorException(org.eclipse.hono.client.ServerErrorException) Test(org.junit.jupiter.api.Test)

Example 17 with Timeout

use of io.vertx.junit5.Timeout in project hono by eclipse.

the class RequestResponseClientTest method testCreateAndSendRequestSetsNoTimerIfRequestTimeoutZero.

/**
 * Verifies that the client configured with a zero request timeout sets no timer for
 * canceling the request in case of no received response.
 *
 * @param ctx The vert.x test context.
 */
@Test
public void testCreateAndSendRequestSetsNoTimerIfRequestTimeoutZero(final VertxTestContext ctx) {
    // WHEN configuring the client with a zero request timeout and sending a request message
    final JsonObject payload = new JsonObject().put("key", "value");
    client.map(c -> {
        c.setRequestTimeout(0);
        return c;
    }).onComplete(ctx.succeeding(c -> {
        c.createAndSendRequest("get", null, payload.toBuffer(), "application/json", SimpleRequestResponseResult::from, span);
    }));
    // THEN the message is sent
    final Message request = verifySenderSend();
    assertThat(request).isNotNull();
    assertThat(request.getBody()).isNotNull();
    assertThat(request.getBody()).isInstanceOf(Data.class);
    final Buffer body = MessageHelper.getPayload(request);
    assertThat(body.getBytes()).isEqualTo(payload.toBuffer().getBytes());
    // and no timer has been set to time out the request
    verify(vertx, never()).setTimer(anyLong(), VertxMockSupport.anyHandler());
    ctx.completeNow();
}
Also used : HttpURLConnection(java.net.HttpURLConnection) ProtonReceiver(io.vertx.proton.ProtonReceiver) BeforeEach(org.junit.jupiter.api.BeforeEach) ArgumentMatchers.eq(org.mockito.ArgumentMatchers.eq) Timeout(io.vertx.junit5.Timeout) EventBus(io.vertx.core.eventbus.EventBus) ExtendWith(org.junit.jupiter.api.extension.ExtendWith) ProtonMessageHandler(io.vertx.proton.ProtonMessageHandler) Map(java.util.Map) DeliveryState(org.apache.qpid.proton.amqp.transport.DeliveryState) TracingMockSupport(org.eclipse.hono.test.TracingMockSupport) JsonObject(io.vertx.core.json.JsonObject) AmqpError(org.apache.qpid.proton.amqp.transport.AmqpError) Data(org.apache.qpid.proton.amqp.messaging.Data) ProtonQoS(io.vertx.proton.ProtonQoS) MessageHelper(org.eclipse.hono.util.MessageHelper) VertxExtension(io.vertx.junit5.VertxExtension) Future(io.vertx.core.Future) Test(org.junit.jupiter.api.Test) Buffer(io.vertx.core.buffer.Buffer) VertxMockSupport(org.eclipse.hono.test.VertxMockSupport) Span(io.opentracing.Span) ProtonSender(io.vertx.proton.ProtonSender) Accepted(org.apache.qpid.proton.amqp.messaging.Accepted) Mockito.mock(org.mockito.Mockito.mock) ArgumentMatchers.any(org.mockito.ArgumentMatchers.any) VertxTestContext(io.vertx.junit5.VertxTestContext) ArgumentMatchers.anyLong(org.mockito.ArgumentMatchers.anyLong) ProtonDelivery(io.vertx.proton.ProtonDelivery) Rejected(org.apache.qpid.proton.amqp.messaging.Rejected) AmqpClientUnitTestHelper(org.eclipse.hono.client.amqp.test.AmqpClientUnitTestHelper) ClientErrorException(org.eclipse.hono.client.ClientErrorException) ServiceInvocationException(org.eclipse.hono.client.ServiceInvocationException) ArgumentCaptor(org.mockito.ArgumentCaptor) Symbol(org.apache.qpid.proton.amqp.Symbol) Message(org.apache.qpid.proton.message.Message) Assertions.assertEquals(org.junit.jupiter.api.Assertions.assertEquals) HonoConnection(org.eclipse.hono.client.HonoConnection) ArgumentMatchers.isA(org.mockito.ArgumentMatchers.isA) RequestResponseClientConfigProperties(org.eclipse.hono.client.RequestResponseClientConfigProperties) Tracer(io.opentracing.Tracer) Vertx(io.vertx.core.Vertx) ServerErrorException(org.eclipse.hono.client.ServerErrorException) ProtonHelper(io.vertx.proton.ProtonHelper) Mockito.when(org.mockito.Mockito.when) Truth.assertThat(com.google.common.truth.Truth.assertThat) Mockito.verify(org.mockito.Mockito.verify) TimeUnit(java.util.concurrent.TimeUnit) Consumer(java.util.function.Consumer) Mockito.never(org.mockito.Mockito.never) ResourceLimitExceededException(org.eclipse.hono.client.ResourceLimitExceededException) SendMessageSampler(org.eclipse.hono.client.SendMessageSampler) Handler(io.vertx.core.Handler) ArgumentMatchers.anyString(org.mockito.ArgumentMatchers.anyString) Buffer(io.vertx.core.buffer.Buffer) Message(org.apache.qpid.proton.message.Message) JsonObject(io.vertx.core.json.JsonObject) Test(org.junit.jupiter.api.Test)

Example 18 with Timeout

use of io.vertx.junit5.Timeout in project hono by eclipse.

the class TelemetryCoapIT method testUploadFailsForLargePayload.

/**
 * Verifies that the upload of a telemetry message containing a payload that
 * exceeds the CoAP adapter's configured max payload size fails with a 4.13
 * response code.
 *
 * @param ctx The test context.
 * @throws IOException if the CoAP request cannot be sent to the adapter.
 * @throws ConnectorException  if the CoAP request cannot be sent to the adapter.
 */
@Test
@Timeout(value = 10, timeUnit = TimeUnit.SECONDS)
public void testUploadFailsForLargePayload(final VertxTestContext ctx) throws ConnectorException, IOException {
    final Tenant tenant = new Tenant();
    helper.registry.addPskDeviceForTenant(tenantId, tenant, deviceId, SECRET).compose(ok -> {
        final CoapClient client = getCoapsClient(deviceId, tenantId, SECRET);
        final Request request = createCoapsRequest(Code.POST, Type.CON, getPostResource(), IntegrationTestSupport.getPayload(4096));
        final Promise<OptionSet> result = Promise.promise();
        client.advanced(getHandler(result, ResponseCode.REQUEST_ENTITY_TOO_LARGE), request);
        return result.future();
    }).onComplete(ctx.succeedingThenComplete());
}
Also used : X509Certificate(java.security.cert.X509Certificate) ResponseCode(org.eclipse.californium.core.coap.CoAP.ResponseCode) VertxTestContext(io.vertx.junit5.VertxTestContext) CoapClient(org.eclipse.californium.core.CoapClient) DownstreamMessage(org.eclipse.hono.application.client.DownstreamMessage) ConnectorException(org.eclipse.californium.elements.exception.ConnectorException) KeyLoader(org.eclipse.hono.config.KeyLoader) Tenant(org.eclipse.hono.service.management.tenant.Tenant) Timeout(io.vertx.junit5.Timeout) TelemetryConstants(org.eclipse.hono.util.TelemetryConstants) IntegrationTestSupport(org.eclipse.hono.tests.IntegrationTestSupport) ExtendWith(org.junit.jupiter.api.extension.ExtendWith) Assumptions.assumeTrue(org.junit.jupiter.api.Assumptions.assumeTrue) Tenants(org.eclipse.hono.tests.Tenants) Type(org.eclipse.californium.core.coap.CoAP.Type) MessageContext(org.eclipse.hono.application.client.MessageContext) Promise(io.vertx.core.Promise) IOException(java.io.IOException) Truth.assertThat(com.google.common.truth.Truth.assertThat) VertxExtension(io.vertx.junit5.VertxExtension) Future(io.vertx.core.Future) StandardCharsets(java.nio.charset.StandardCharsets) TimeUnit(java.util.concurrent.TimeUnit) Test(org.junit.jupiter.api.Test) Code(org.eclipse.californium.core.coap.CoAP.Code) Request(org.eclipse.californium.core.coap.Request) MessageConsumer(org.eclipse.hono.application.client.MessageConsumer) OptionSet(org.eclipse.californium.core.coap.OptionSet) Handler(io.vertx.core.Handler) QoS(org.eclipse.hono.util.QoS) Promise(io.vertx.core.Promise) Tenant(org.eclipse.hono.service.management.tenant.Tenant) Request(org.eclipse.californium.core.coap.Request) CoapClient(org.eclipse.californium.core.CoapClient) Test(org.junit.jupiter.api.Test) Timeout(io.vertx.junit5.Timeout)

Example 19 with Timeout

use of io.vertx.junit5.Timeout in project hono by eclipse.

the class KafkaBasedCommandConsumerFactoryImplIT method testCommandsGetForwardedInIncomingOrder.

/**
 * Verifies that records, published on the tenant-specific Kafka command topic, get received by
 * the consumer created by the factory and get forwarded on the internal command topic in the
 * same order they were published.
 *
 * @param ctx The vert.x test context.
 * @throws InterruptedException if test execution gets interrupted.
 */
@Test
@Timeout(value = 10, timeUnit = TimeUnit.SECONDS)
public void testCommandsGetForwardedInIncomingOrder(final VertxTestContext ctx) throws InterruptedException {
    final String tenantId = "tenant_" + UUID.randomUUID();
    final VertxTestContext setup = new VertxTestContext();
    final int numTestCommands = 10;
    final List<KafkaConsumerRecord<String, Buffer>> receivedRecords = new ArrayList<>();
    final Promise<Void> allRecordsReceivedPromise = Promise.promise();
    final List<String> receivedCommandSubjects = new ArrayList<>();
    final Handler<KafkaConsumerRecord<String, Buffer>> recordHandler = record -> {
        receivedRecords.add(record);
        LOG.trace("received {}", record);
        receivedCommandSubjects.add(KafkaRecordHelper.getSubject(record.headers()).orElse(""));
        if (receivedRecords.size() == numTestCommands) {
            allRecordsReceivedPromise.tryComplete();
        }
    };
    final Deque<Promise<Void>> completionPromisesQueue = new LinkedList<>();
    // don't let getting the target adapter instance finish immediately
    // - let the futures complete in the reverse order
    final Supplier<Future<Void>> targetAdapterInstanceGetterCompletionFutureSupplier = () -> {
        final Promise<Void> resultPromise = Promise.promise();
        completionPromisesQueue.addFirst(resultPromise);
        // complete all promises in reverse order when processing the last command
        if (completionPromisesQueue.size() == numTestCommands) {
            completionPromisesQueue.forEach(Promise::complete);
        }
        return resultPromise.future();
    };
    final Context vertxContext = vertx.getOrCreateContext();
    vertxContext.runOnContext(v0 -> {
        final HonoKafkaConsumer internalConsumer = getInternalCommandConsumer(recordHandler);
        final KafkaBasedCommandConsumerFactoryImpl consumerFactory = getKafkaBasedCommandConsumerFactory(targetAdapterInstanceGetterCompletionFutureSupplier, tenantId);
        CompositeFuture.join(internalConsumer.start(), consumerFactory.start()).compose(f -> createCommandConsumer(tenantId, consumerFactory)).onComplete(setup.succeedingThenComplete());
    });
    assertThat(setup.awaitCompletion(IntegrationTestSupport.getTestSetupTimeout(), TimeUnit.SECONDS)).isTrue();
    if (setup.failed()) {
        ctx.failNow(setup.causeOfFailure());
        return;
    }
    LOG.debug("command consumer started");
    final List<String> sentCommandSubjects = new ArrayList<>();
    IntStream.range(0, numTestCommands).forEach(i -> {
        final String subject = "cmd_" + i;
        sentCommandSubjects.add(subject);
        sendOneWayCommand(tenantId, "myDeviceId", subject);
    });
    final long timerId = vertx.setTimer(8000, tid -> {
        LOG.info("received records:{}{}", System.lineSeparator(), receivedRecords.stream().map(Object::toString).collect(Collectors.joining("," + System.lineSeparator())));
        allRecordsReceivedPromise.tryFail(String.format("only received %d out of %d expected messages after 8s", receivedRecords.size(), numTestCommands));
    });
    allRecordsReceivedPromise.future().onComplete(ctx.succeeding(v -> {
        vertx.cancelTimer(timerId);
        ctx.verify(() -> {
            assertThat(receivedCommandSubjects).isEqualTo(sentCommandSubjects);
        });
        ctx.completeNow();
    }));
}
Also used : BeforeEach(org.junit.jupiter.api.BeforeEach) MessagingKafkaConsumerConfigProperties(org.eclipse.hono.client.kafka.consumer.MessagingKafkaConsumerConfigProperties) LoggerFactory(org.slf4j.LoggerFactory) Context(io.vertx.core.Context) KafkaProducer(io.vertx.kafka.client.producer.KafkaProducer) Timeout(io.vertx.junit5.Timeout) AfterAll(org.junit.jupiter.api.AfterAll) MessagingType(org.eclipse.hono.util.MessagingType) IntegrationTestSupport(org.eclipse.hono.tests.IntegrationTestSupport) ExtendWith(org.junit.jupiter.api.extension.ExtendWith) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) BeforeAll(org.junit.jupiter.api.BeforeAll) Map(java.util.Map) TracingMockSupport(org.eclipse.hono.test.TracingMockSupport) JsonObject(io.vertx.core.json.JsonObject) DeviceConnectionConstants(org.eclipse.hono.util.DeviceConnectionConstants) CachingKafkaProducerFactory(org.eclipse.hono.client.kafka.producer.CachingKafkaProducerFactory) Set(java.util.Set) CommandTargetMapper(org.eclipse.hono.commandrouter.CommandTargetMapper) ConsumerConfig(org.apache.kafka.clients.consumer.ConsumerConfig) UUID(java.util.UUID) TenantClient(org.eclipse.hono.client.registry.TenantClient) KafkaBasedCommandConsumerFactoryImpl(org.eclipse.hono.commandrouter.impl.kafka.KafkaBasedCommandConsumerFactoryImpl) VertxExtension(io.vertx.junit5.VertxExtension) Collectors(java.util.stream.Collectors) Future(io.vertx.core.Future) AsyncHandlingAutoCommitKafkaConsumer(org.eclipse.hono.client.kafka.consumer.AsyncHandlingAutoCommitKafkaConsumer) TestInfo(org.junit.jupiter.api.TestInfo) Test(org.junit.jupiter.api.Test) List(java.util.List) KafkaProducerFactory(org.eclipse.hono.client.kafka.producer.KafkaProducerFactory) Buffer(io.vertx.core.buffer.Buffer) KafkaConsumerRecord(io.vertx.kafka.client.consumer.KafkaConsumerRecord) Span(io.opentracing.Span) Mockito.mock(org.mockito.Mockito.mock) IntStream(java.util.stream.IntStream) VertxTestContext(io.vertx.junit5.VertxTestContext) X500Principal(javax.security.auth.x500.X500Principal) HonoKafkaConsumer(org.eclipse.hono.client.kafka.consumer.HonoKafkaConsumer) Lifecycle(org.eclipse.hono.util.Lifecycle) Deque(java.util.Deque) AtomicReference(java.util.concurrent.atomic.AtomicReference) Supplier(java.util.function.Supplier) ArrayList(java.util.ArrayList) HashSet(java.util.HashSet) CompositeFuture(io.vertx.core.CompositeFuture) Timer(io.micrometer.core.instrument.Timer) LinkedList(java.util.LinkedList) Logger(org.slf4j.Logger) Tracer(io.opentracing.Tracer) Promise(io.vertx.core.Promise) Vertx(io.vertx.core.Vertx) Mockito.when(org.mockito.Mockito.when) KafkaRecordHelper(org.eclipse.hono.client.kafka.KafkaRecordHelper) Truth.assertThat(com.google.common.truth.Truth.assertThat) AssumeMessagingSystem(org.eclipse.hono.tests.AssumeMessagingSystem) TenantObject(org.eclipse.hono.util.TenantObject) SpanContext(io.opentracing.SpanContext) TimeUnit(java.util.concurrent.TimeUnit) NoopKafkaClientMetricsSupport(org.eclipse.hono.client.kafka.metrics.NoopKafkaClientMetricsSupport) HonoTopic(org.eclipse.hono.client.kafka.HonoTopic) CommandRouterMetrics(org.eclipse.hono.commandrouter.CommandRouterMetrics) AfterEach(org.junit.jupiter.api.AfterEach) Handler(io.vertx.core.Handler) KafkaHeader(io.vertx.kafka.client.producer.KafkaHeader) KafkaProducerRecord(io.vertx.kafka.client.producer.KafkaProducerRecord) KafkaAdminClient(io.vertx.kafka.admin.KafkaAdminClient) Context(io.vertx.core.Context) VertxTestContext(io.vertx.junit5.VertxTestContext) SpanContext(io.opentracing.SpanContext) KafkaBasedCommandConsumerFactoryImpl(org.eclipse.hono.commandrouter.impl.kafka.KafkaBasedCommandConsumerFactoryImpl) VertxTestContext(io.vertx.junit5.VertxTestContext) ArrayList(java.util.ArrayList) KafkaConsumerRecord(io.vertx.kafka.client.consumer.KafkaConsumerRecord) LinkedList(java.util.LinkedList) Promise(io.vertx.core.Promise) HonoKafkaConsumer(org.eclipse.hono.client.kafka.consumer.HonoKafkaConsumer) Future(io.vertx.core.Future) CompositeFuture(io.vertx.core.CompositeFuture) JsonObject(io.vertx.core.json.JsonObject) TenantObject(org.eclipse.hono.util.TenantObject) Test(org.junit.jupiter.api.Test) Timeout(io.vertx.junit5.Timeout)

Example 20 with Timeout

use of io.vertx.junit5.Timeout in project hono by eclipse.

the class CommandAndControlMqttIT method testSendCommandFailsForCommandNotAcknowledgedByDevice.

/**
 * Verifies that the adapter forwards the <em>released</em> disposition back to the
 * application if the device hasn't sent an acknowledgement for the command message
 * published to the device.
 *
 * @param endpointConfig The endpoints to use for sending/receiving commands.
 * @param ctx The vert.x test context.
 * @throws InterruptedException if not all commands and responses are exchanged in time.
 */
@ParameterizedTest(name = IntegrationTestSupport.PARAMETERIZED_TEST_NAME_PATTERN)
@MethodSource("allCombinations")
@Timeout(timeUnit = TimeUnit.SECONDS, value = 20)
public void testSendCommandFailsForCommandNotAcknowledgedByDevice(final MqttCommandEndpointConfiguration endpointConfig, final VertxTestContext ctx) throws InterruptedException {
    final MqttQoS subscribeQos = MqttQoS.AT_LEAST_ONCE;
    final VertxTestContext setup = new VertxTestContext();
    final Checkpoint ready = setup.checkpoint(2);
    final String commandTargetDeviceId = endpointConfig.isSubscribeAsGateway() ? helper.setupGatewayDeviceBlocking(tenantId, deviceId, 5) : deviceId;
    final int totalNoOfCommandsToSend = 2;
    final CountDownLatch commandsFailed = new CountDownLatch(totalNoOfCommandsToSend);
    final AtomicInteger receivedMessagesCounter = new AtomicInteger(0);
    final AtomicInteger counter = new AtomicInteger();
    final Handler<MqttPublishMessage> commandConsumer = msg -> {
        LOGGER.trace("received command [{}] - no response sent here", msg.topicName());
        final ResourceIdentifier topic = ResourceIdentifier.fromString(msg.topicName());
        ctx.verify(() -> {
            endpointConfig.assertCommandPublishTopicStructure(topic, commandTargetDeviceId, false, "setValue");
        });
        receivedMessagesCounter.incrementAndGet();
    };
    final Function<Buffer, Future<Void>> commandSender = payload -> {
        counter.incrementAndGet();
        return helper.sendCommand(tenantId, commandTargetDeviceId, "setValue", "text/plain", payload, helper.getSendCommandTimeout(counter.get() == 1)).mapEmpty();
    };
    helper.registry.addDeviceToTenant(tenantId, deviceId, password).compose(ok -> connectToAdapter(IntegrationTestSupport.getUsername(deviceId, tenantId), password)).compose(ok -> injectMqttClientPubAckBlocker(new AtomicBoolean(true))).compose(ok -> createConsumer(tenantId, msg -> {
        // expect empty notification with TTD -1
        setup.verify(() -> assertThat(msg.getContentType()).isEqualTo(EventConstants.CONTENT_TYPE_EMPTY_NOTIFICATION));
        final TimeUntilDisconnectNotification notification = msg.getTimeUntilDisconnectNotification().orElse(null);
        LOGGER.info("received notification [{}]", notification);
        setup.verify(() -> assertThat(notification).isNotNull());
        if (notification.getTtd() == -1) {
            ready.flag();
        }
    })).compose(conAck -> subscribeToCommands(commandTargetDeviceId, commandConsumer, endpointConfig, subscribeQos)).onComplete(setup.succeeding(ok -> ready.flag()));
    assertWithMessage("setup of adapter finished within %s seconds", IntegrationTestSupport.getTestSetupTimeout()).that(setup.awaitCompletion(IntegrationTestSupport.getTestSetupTimeout(), TimeUnit.SECONDS)).isTrue();
    if (setup.failed()) {
        ctx.failNow(setup.causeOfFailure());
        return;
    }
    final AtomicInteger commandsSent = new AtomicInteger(0);
    final AtomicLong lastReceivedTimestamp = new AtomicLong(0);
    final long start = System.currentTimeMillis();
    while (commandsSent.get() < totalNoOfCommandsToSend) {
        final CountDownLatch commandSent = new CountDownLatch(1);
        context.runOnContext(go -> {
            final Buffer msg = Buffer.buffer("value: " + commandsSent.getAndIncrement());
            commandSender.apply(msg).onComplete(sendAttempt -> {
                if (sendAttempt.succeeded()) {
                    LOGGER.debug("sending command {} succeeded unexpectedly", commandsSent.get());
                } else {
                    if (sendAttempt.cause() instanceof ServerErrorException && ((ServerErrorException) sendAttempt.cause()).getErrorCode() == HttpURLConnection.HTTP_UNAVAILABLE && !(sendAttempt.cause() instanceof SendMessageTimeoutException)) {
                        LOGGER.debug("sending command {} failed as expected: {}", commandsSent.get(), sendAttempt.cause().toString());
                        lastReceivedTimestamp.set(System.currentTimeMillis());
                        commandsFailed.countDown();
                        if (commandsFailed.getCount() % 20 == 0) {
                            LOGGER.info("commands failed as expected: {}", totalNoOfCommandsToSend - commandsFailed.getCount());
                        }
                    } else {
                        LOGGER.debug("sending command {} failed with an unexpected error", commandsSent.get(), sendAttempt.cause());
                    }
                }
                commandSent.countDown();
            });
        });
        commandSent.await();
    }
    // have to wait an extra MqttAdapterProperties.DEFAULT_COMMAND_ACK_TIMEOUT (100ms) for each command message
    final long timeToWait = totalNoOfCommandsToSend * 300;
    if (!commandsFailed.await(timeToWait, TimeUnit.MILLISECONDS)) {
        LOGGER.info("Timeout of {} milliseconds reached, stop waiting for commands", timeToWait);
    }
    assertThat(receivedMessagesCounter.get()).isEqualTo(totalNoOfCommandsToSend);
    final long commandsCompleted = totalNoOfCommandsToSend - commandsFailed.getCount();
    LOGGER.info("commands sent: {}, commands failed: {} after {} milliseconds", commandsSent.get(), commandsCompleted, lastReceivedTimestamp.get() - start);
    if (commandsCompleted == commandsSent.get()) {
        ctx.completeNow();
    } else {
        ctx.failNow(new java.lang.IllegalStateException("did not complete all commands sent"));
    }
}
Also used : HttpURLConnection(java.net.HttpURLConnection) BeforeEach(org.junit.jupiter.api.BeforeEach) DownstreamMessage(org.eclipse.hono.application.client.DownstreamMessage) MqttPublishMessage(io.vertx.mqtt.messages.MqttPublishMessage) Timeout(io.vertx.junit5.Timeout) MessagingType(org.eclipse.hono.util.MessagingType) IntegrationTestSupport(org.eclipse.hono.tests.IntegrationTestSupport) ExtendWith(org.junit.jupiter.api.extension.ExtendWith) ChannelPromise(io.netty.channel.ChannelPromise) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) Map(java.util.Map) MqttClientImpl(io.vertx.mqtt.impl.MqttClientImpl) ResourceIdentifier(org.eclipse.hono.util.ResourceIdentifier) Method(java.lang.reflect.Method) MethodSource(org.junit.jupiter.params.provider.MethodSource) ChannelOutboundHandlerAdapter(io.netty.channel.ChannelOutboundHandlerAdapter) MessageContext(org.eclipse.hono.application.client.MessageContext) SubscriberRole(org.eclipse.hono.tests.CommandEndpointConfiguration.SubscriberRole) Truth.assertWithMessage(com.google.common.truth.Truth.assertWithMessage) IllegalStateException(javax.jms.IllegalStateException) MessageHelper(org.eclipse.hono.util.MessageHelper) VertxExtension(io.vertx.junit5.VertxExtension) EventConstants(org.eclipse.hono.util.EventConstants) Future(io.vertx.core.Future) CountDownLatch(java.util.concurrent.CountDownLatch) Stream(java.util.stream.Stream) Buffer(io.vertx.core.buffer.Buffer) Checkpoint(io.vertx.junit5.Checkpoint) NetSocketInternal(io.vertx.core.net.impl.NetSocketInternal) VertxTestContext(io.vertx.junit5.VertxTestContext) GenericKafkaSender(org.eclipse.hono.tests.GenericKafkaSender) MqttQoS(io.netty.handler.codec.mqtt.MqttQoS) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) ClientErrorException(org.eclipse.hono.client.ClientErrorException) AtomicReference(java.util.concurrent.atomic.AtomicReference) Function(java.util.function.Function) TimeUntilDisconnectNotification(org.eclipse.hono.util.TimeUntilDisconnectNotification) ChannelHandlerContext(io.netty.channel.ChannelHandlerContext) Message(org.apache.qpid.proton.message.Message) MqttPubAckMessage(io.netty.handler.codec.mqtt.MqttPubAckMessage) Promise(io.vertx.core.Promise) ServerErrorException(org.eclipse.hono.client.ServerErrorException) ProtonHelper(io.vertx.proton.ProtonHelper) KafkaRecordHelper(org.eclipse.hono.client.kafka.KafkaRecordHelper) Truth.assertThat(com.google.common.truth.Truth.assertThat) AssumeMessagingSystem(org.eclipse.hono.tests.AssumeMessagingSystem) TimeUnit(java.util.concurrent.TimeUnit) AtomicLong(java.util.concurrent.atomic.AtomicLong) HonoTopic(org.eclipse.hono.client.kafka.HonoTopic) ParameterizedTest(org.junit.jupiter.params.ParameterizedTest) MessageConsumer(org.eclipse.hono.application.client.MessageConsumer) SendMessageTimeoutException(org.eclipse.hono.client.SendMessageTimeoutException) NoopSpan(io.opentracing.noop.NoopSpan) GenericSenderLink(org.eclipse.hono.client.amqp.GenericSenderLink) Handler(io.vertx.core.Handler) Buffer(io.vertx.core.buffer.Buffer) VertxTestContext(io.vertx.junit5.VertxTestContext) CountDownLatch(java.util.concurrent.CountDownLatch) Checkpoint(io.vertx.junit5.Checkpoint) ResourceIdentifier(org.eclipse.hono.util.ResourceIdentifier) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) Checkpoint(io.vertx.junit5.Checkpoint) AtomicLong(java.util.concurrent.atomic.AtomicLong) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) MqttPublishMessage(io.vertx.mqtt.messages.MqttPublishMessage) TimeUntilDisconnectNotification(org.eclipse.hono.util.TimeUntilDisconnectNotification) Future(io.vertx.core.Future) ServerErrorException(org.eclipse.hono.client.ServerErrorException) SendMessageTimeoutException(org.eclipse.hono.client.SendMessageTimeoutException) MqttQoS(io.netty.handler.codec.mqtt.MqttQoS) Timeout(io.vertx.junit5.Timeout) ParameterizedTest(org.junit.jupiter.params.ParameterizedTest) MethodSource(org.junit.jupiter.params.provider.MethodSource)

Aggregations

Timeout (io.vertx.junit5.Timeout)73 VertxTestContext (io.vertx.junit5.VertxTestContext)73 Test (org.junit.jupiter.api.Test)71 TimeUnit (java.util.concurrent.TimeUnit)67 Truth.assertThat (com.google.common.truth.Truth.assertThat)65 Future (io.vertx.core.Future)54 HttpURLConnection (java.net.HttpURLConnection)52 IntegrationTestSupport (org.eclipse.hono.tests.IntegrationTestSupport)49 Handler (io.vertx.core.Handler)47 Buffer (io.vertx.core.buffer.Buffer)46 BeforeEach (org.junit.jupiter.api.BeforeEach)46 Promise (io.vertx.core.Promise)45 Vertx (io.vertx.core.Vertx)37 JsonObject (io.vertx.core.json.JsonObject)37 VertxExtension (io.vertx.junit5.VertxExtension)37 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)37 ExtendWith (org.junit.jupiter.api.extension.ExtendWith)37 ParameterizedTest (org.junit.jupiter.params.ParameterizedTest)37 Tenant (org.eclipse.hono.service.management.tenant.Tenant)36 MethodSource (org.junit.jupiter.params.provider.MethodSource)35