quarkus: Dev Services for Kafka combined with continuous testing not working right.

Describe the bug

I’m trying to combine Dev Services for Kafka with Continuous testing and the experience isn’t that great. In all the scenarios I mention below I am creating an application from scratch using the SmallRye Reactive messaging & RESTEasy reactive extensions.

In all scenarios mentioned below the continuous testing hangs and the entire quarkus:dev needs to be CTRL-C’ed and restarted.

The PriceResourceTests class mentioned in all scenarios looks like this:

@QuarkusTest
class PriceResourceTests {
    @TestHTTPEndpoint(PriceResource.class)
    @TestHTTPResource("/stream")
    URI uri;

    @Test
    public void sseStream() {
        Client client = ClientBuilder.newClient();
        WebTarget target = client.target(this.uri);

        List<Double> received = new CopyOnWriteArrayList<>();

        try (SseEventSource source = SseEventSource.target(target).build()) {
            source.register(inboundSseEvent -> received.add(Double.valueOf(inboundSseEvent.readData())));
            source.open();

            await()
                .atMost(Duration.ofSeconds(15))
                .until(() -> received.size() == 2);
        }

        assertThat(received)
            .hasSize(2)
            .allMatch(value -> (value >= 0) && (value < 100));
    }
}

When completed, the PriceGenerator class looks like this:

@ApplicationScoped
public class PriceGenerator {
    private final Random random = new Random();

    @Outgoing("generated-price")
    public Multi<Integer> generate() {
        return Multi.createFrom().ticks().every(Duration.ofSeconds(5))
                .onOverflow().drop()
                .map(tick -> this.random.nextInt(100));
    }
}

When completed, the PriceConverter class looks like this:

@ApplicationScoped
public class PriceConverter {
    private static final double CONVERSION_RATE = 0.88;

    @Incoming("prices")
    @Outgoing("processed-prices")
    @Broadcast
    public double process(int priceInUsd) {
        return priceInUsd * CONVERSION_RATE;
    }
}

When completed, the PriceResource class looks like this:

@Path("/prices")
public class PriceResource {
    private final Publisher<Double> processedPrices;

    public PriceResource(@Channel("processed-prices") Publisher<Double> processedPrices) {
        this.processedPrices = processedPrices;
    }

    @GET
    @Path("/stream")
    @Produces(MediaType.SERVER_SENT_EVENTS)
    public Publisher<Double> ssePrices() {
        return this.processedPrices;
    }
}

When completed, the application.properties file looks like this:

# Configure the Kafka sink (we write to it)
mp.messaging.outgoing.generated-price.connector=smallrye-kafka
mp.messaging.outgoing.generated-price.topic=prices
mp.messaging.outgoing.generated-price.value.serializer=org.apache.kafka.common.serialization.IntegerSerializer

# Configure the Kafka source (we read from it)
mp.messaging.incoming.prices.connector=smallrye-kafka
mp.messaging.incoming.prices.health-readiness-enabled=false
mp.messaging.incoming.prices.topic=prices
mp.messaging.incoming.prices.value.deserializer=org.apache.kafka.common.serialization.IntegerDeserializer

Expected behavior

No response

Actual behavior

No response

How to Reproduce?

Scenario 1

  1. Generate project
  2. Add these dependencies to pom.xml
    <dependency>
       <groupId>org.jboss.resteasy</groupId>
       <artifactId>resteasy-client</artifactId>
       <scope>test</scope>
     </dependency>
     <dependency>
       <groupId>io.rest-assured</groupId>
       <artifactId>rest-assured</artifactId>
       <scope>test</scope>
     </dependency>
     <dependency>
       <groupId>org.awaitility</groupId>
       <artifactId>awaitility</artifactId>
       <scope>test</scope>
     </dependency>
     <dependency>
       <groupId>org.assertj</groupId>
       <artifactId>assertj-core</artifactId>
       <scope>test</scope>
     </dependency>
    
  3. Add an empty PriceGenerator, PriceConverter, and PriceResource classes in src/main/java/com/example
  4. Add a completed PriceResourceTests class in src/test/java/com/example
  5. Run quarkus:dev
  6. Turn on testing
  7. Complete PriceResource class
  8. Complete PriceGenerator class
  9. Complete PriceConverter class
  10. Complete application.properties

At this step the console output indicates the test is running but it never completes, even though the test itself has a 15 second timeout. Furthermore, it seems the application itself never even restarts itself unless, from another terminal, issue an http request to /prices/stream. Still, the continuous testing is hung and I have to CTRL-C.

Scenario 2

  1. Generate project
  2. Add these dependencies to pom.xml
    <dependency>
       <groupId>org.jboss.resteasy</groupId>
       <artifactId>resteasy-client</artifactId>
       <scope>test</scope>
     </dependency>
     <dependency>
       <groupId>io.rest-assured</groupId>
       <artifactId>rest-assured</artifactId>
       <scope>test</scope>
     </dependency>
     <dependency>
       <groupId>org.awaitility</groupId>
       <artifactId>awaitility</artifactId>
       <scope>test</scope>
     </dependency>
     <dependency>
       <groupId>org.assertj</groupId>
       <artifactId>assertj-core</artifactId>
       <scope>test</scope>
     </dependency>
    
  3. Add an empty PriceGenerator, PriceConverter, and PriceResource classes in src/main/java/com/example
  4. Add a completed PriceResourceTests class in src/test/java/com/example
  5. Complete application.properties
  6. Run quarkus:dev
  7. Turn on testing
  8. Complete PriceResource class
  9. Complete PriceGenerator class
  10. Complete PriceConverter class

Same result as scenario 1

Scenario 3

  1. Generate project
  2. Add these dependencies to pom.xml
    <dependency>
       <groupId>org.jboss.resteasy</groupId>
       <artifactId>resteasy-client</artifactId>
       <scope>test</scope>
     </dependency>
     <dependency>
       <groupId>io.rest-assured</groupId>
       <artifactId>rest-assured</artifactId>
       <scope>test</scope>
     </dependency>
     <dependency>
       <groupId>org.awaitility</groupId>
       <artifactId>awaitility</artifactId>
       <scope>test</scope>
     </dependency>
     <dependency>
       <groupId>org.assertj</groupId>
       <artifactId>assertj-core</artifactId>
       <scope>test</scope>
     </dependency>
    
  3. Add an empty PriceGenerator, PriceConverter, and PriceResource classes in src/main/java/com/example
  4. Add a completed PriceResourceTests class in src/test/java/com/example
  5. Complete application.properties
  6. Run quarkus:dev
  7. Complete PriceResource class
  8. Complete PriceGenerator class
  9. Complete PriceConverter class
  10. Turn on testing

Same result as scenario 1

Scenario 4

  1. Generate project
  2. Add these dependencies to pom.xml
    <dependency>
       <groupId>org.jboss.resteasy</groupId>
       <artifactId>resteasy-client</artifactId>
       <scope>test</scope>
     </dependency>
     <dependency>
       <groupId>io.rest-assured</groupId>
       <artifactId>rest-assured</artifactId>
       <scope>test</scope>
     </dependency>
     <dependency>
       <groupId>org.awaitility</groupId>
       <artifactId>awaitility</artifactId>
       <scope>test</scope>
     </dependency>
     <dependency>
       <groupId>org.assertj</groupId>
       <artifactId>assertj-core</artifactId>
       <scope>test</scope>
     </dependency>
    
  3. Add a completed PriceGenerator and PriceResource classes in src/main/java/com/example
  4. Add a completed PriceResourceTests class in src/test/java/com/example
  5. Complete application.properties
  6. Run quarkus:dev
  7. Turn on testing
  8. Complete PriceConverter class

Same result as scenario 1

Output of uname -a or ver

Darwin edeandre-mac 20.5.0 Darwin Kernel Version 20.5.0: Sat May 8 05:10:33 PDT 2021; root:xnu-7195.121.3~9/RELEASE_X86_64 x86_64

Output of java -version

openjdk version "11.0.2" 2019-01-15
OpenJDK Runtime Environment 18.9 (build 11.0.2+9)
OpenJDK 64-Bit Server VM 18.9 (build 11.0.2+9, mixed mode)

GraalVM version (if different from Java)

openjdk version "11.0.11" 2021-04-20
OpenJDK Runtime Environment GraalVM CE 21.1.0 (build 11.0.11+8-jvmci-21.1-b05)
OpenJDK 64-Bit Server VM GraalVM CE 21.1.0 (build 11.0.11+8-jvmci-21.1-b05, mixed mode, sharing)

Quarkus version or git rev

2.1.0.Final

Build tool (ie. output of mvnw --version or gradlew --version)

Apache Maven 3.8.1 (05c21c65bdfed0f71a2f2ada8b84da59348c4c5d)
Maven home: /Users/edeandre/.m2/wrapper/dists/apache-maven-3.8.1-bin/2l5mhf2pq2clrde7f7qp1rdt5m/apache-maven-3.8.1
Java version: 11.0.2, vendor: Oracle Corporation, runtime: /Users/edeandre/.sdkman/candidates/java/11.0.2-open
Default locale: en_US, platform encoding: UTF-8
OS name: "mac os x", version: "10.16", arch: "x86_64", family: "mac"

Additional information

No response

About this issue

  • Original URL
  • State: closed
  • Created 3 years ago
  • Comments: 32 (31 by maintainers)

Commits related to this issue

Most upvoted comments

I think that is a known intermittent failure. We know it is fixed on main anyway, so I am not sure how much it matters.

Yes please have a look at it now. Since we have no idea what fixed your issue, starting with the things I will backport sounds like a good idea.