Skip to content

Commit

Permalink
Add native testing with GraalVM and test containers (#449)
Browse files Browse the repository at this point in the history
  • Loading branch information
graemerocher authored Apr 20, 2023
1 parent 3581c47 commit f94c850
Show file tree
Hide file tree
Showing 61 changed files with 703 additions and 656 deletions.
11 changes: 11 additions & 0 deletions buildSrc/build.gradle
Original file line number Diff line number Diff line change
@@ -1,3 +1,14 @@
plugins {
id 'groovy-gradle-plugin'
}
repositories {
gradlePluginPortal()
mavenCentral()
}

dependencies {
implementation libs.gradle.micronaut
implementation libs.gradle.kotlin
implementation libs.gradle.kotlin.allopen
implementation libs.gradle.kotlin.noarg
}
1 change: 1 addition & 0 deletions buildSrc/settings.gradle
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
rootProject.name = 'rabbitmq-parent'
dependencyResolutionManagement {
versionCatalogs {
libs {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,27 @@
plugins {
id 'io.micronaut.build.internal.rabbitmq-base'
id "io.micronaut.application"
id "io.micronaut.test-resources"
}

dependencies {
testImplementation projects.micronautRabbitmq

testImplementation mn.micronaut.inject
testImplementation mn.reactor
testImplementation mnSerde.micronaut.serde.support
testImplementation mnSerde.micronaut.serde.jackson
testImplementation libs.testcontainers
testImplementation libs.awaitility
testImplementation 'io.micronaut.testresources:micronaut-test-resources-client'
}
configurations.all {
resolutionStrategy.dependencySubstitution {
substitute module('io.micronaut.rabbitmq:micronaut-rabbitmq') using project(':micronaut-rabbitmq')
}
}
micronaut {
version libs.versions.micronaut.platform.get()
testRuntime "junit5"
testResources {
clientTimeout = 300
additionalModules.add(RABBITMQ)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
plugins {
id 'io.micronaut.build.internal.rabbitmq-examples'
id 'org.graalvm.buildtools.native'
}

tasks.named("check") { task ->
def graal = ["jvmci.Compiler", "java.vendor.version", "java.vendor"].any {
System.getProperty(it)?.toLowerCase(Locale.ENGLISH)?.contains("graal")
}
if (graal) {
task.dependsOn("nativeTest")
}
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,26 +1,35 @@
package io.micronaut.rabbitmq.docs.consumer.acknowledge.type

import io.micronaut.rabbitmq.AbstractRabbitMQTest
import io.micronaut.context.annotation.Property
import io.micronaut.test.extensions.spock.annotation.MicronautTest
import jakarta.inject.Inject
import spock.lang.Specification

class AcknowledgeSpec extends AbstractRabbitMQTest {
import static java.util.concurrent.TimeUnit.SECONDS
import static org.awaitility.Awaitility.await

@MicronautTest
@Property(name = "spec.name", value = "AcknowledgeSpec")
class AcknowledgeSpec extends Specification {

@Inject ProductClient productClient
@Inject ProductListener productListener

void "test acking with an acknowledgement argument"() {
startContext()

when:
// tag::producer[]
ProductClient productClient = applicationContext.getBean(ProductClient)
productClient.send("message body".bytes)
productClient.send("message body".bytes)
productClient.send("message body".bytes)
productClient.send("message body".bytes)
// end::producer[]

ProductListener productListener = applicationContext.getBean(ProductListener)
await().atMost(10, SECONDS).until {
productListener.messageCount.get() == 5
}

then:
waitFor {
assert productListener.messageCount.get() == 5
}
productListener.messageCount.get() == 5
}
}
Original file line number Diff line number Diff line change
@@ -1,21 +1,30 @@
package io.micronaut.rabbitmq.docs.consumer.concurrent

import io.micronaut.rabbitmq.AbstractRabbitMQTest
import io.micronaut.context.annotation.Property
import io.micronaut.test.extensions.spock.annotation.MicronautTest
import jakarta.inject.Inject
import spock.lang.Specification

class ConcurrentSpec extends AbstractRabbitMQTest {
import static java.util.concurrent.TimeUnit.SECONDS
import static org.awaitility.Awaitility.await


@MicronautTest
@Property(name = "spec.name", value = "ConcurrentSpec")
class ConcurrentSpec extends Specification {
@Inject ProductClient productClient
@Inject ProductListener productListener

void "test concurrent consumers"() {
startContext()

when:
ProductClient productClient = applicationContext.getBean(ProductClient)
4.times { productClient.send("body".bytes) }

ProductListener productListener = applicationContext.getBean(ProductListener)
await().atMost(10, SECONDS).until {
productListener.threads.size() == 4
}

then:
waitFor {
assert productListener.threads.size() == 4
}
productListener.threads.size() == 4
}
}
Original file line number Diff line number Diff line change
@@ -1,32 +1,49 @@
package io.micronaut.rabbitmq.docs.consumer.connection

import io.micronaut.rabbitmq.AbstractRabbitMQTest
import io.micronaut.context.annotation.Property
import io.micronaut.test.extensions.spock.annotation.MicronautTest
import io.micronaut.test.support.TestPropertyProvider
import io.micronaut.testresources.client.TestResourcesClientFactory
import jakarta.inject.Inject
import spock.lang.Specification

class ConnectionSpec extends AbstractRabbitMQTest {
import static java.util.concurrent.TimeUnit.SECONDS
import static org.awaitility.Awaitility.await


@MicronautTest(rebuildContext = true)
@Property(name = "spec.name", value = "ConnectionSpec")
class ConnectionSpec extends Specification implements TestPropertyProvider {
@Inject ProductClient productClient
@Inject ProductListener productListener

void "test product client and listener"() {
startContext()

when:
// tag::producer[]
def productClient = applicationContext.getBean(ProductClient)
productClient.send("connection-test".bytes)
// end::producer[]

ProductListener productListener = applicationContext.getBean(ProductListener)
await().atMost(10, SECONDS).until {
productListener.messageLengths.size() == 1 &&
productListener.messageLengths[0] == "connection-test"
}

then:
waitFor {
assert productListener.messageLengths.size() == 1
assert productListener.messageLengths[0] == "connection-test"
}
productListener.messageLengths.size() == 1
productListener.messageLengths[0] == "connection-test"

cleanup:
// Finding that the context is closing the channel before ack is sent
sleep 200
}

protected Map<String, Object> getConfiguration() {
super.configuration + ["rabbitmq.servers.product-cluster.port": super.configuration.remove("rabbitmq.port")]
@Override
Map<String, String> getProperties() {
var client = TestResourcesClientFactory.fromSystemProperties().get();
var rabbitURI = client.resolve("rabbitmq.uri", Map.of(), Map.of());
return rabbitURI
.map(uri -> Map.of("rabbitmq.servers.product-cluster.port", String.valueOf(URI.create(uri).getPort())))
.orElse(Collections.emptyMap());
}
}
Original file line number Diff line number Diff line change
@@ -1,25 +1,32 @@
package io.micronaut.rabbitmq.docs.consumer.custom.annotation

import io.micronaut.rabbitmq.AbstractRabbitMQTest
import io.micronaut.context.annotation.Property
import io.micronaut.test.extensions.spock.annotation.MicronautTest
import jakarta.inject.Inject
import spock.lang.Specification

class DeliveryTagSpec extends AbstractRabbitMQTest {
import static java.util.concurrent.TimeUnit.SECONDS
import static org.awaitility.Awaitility.await

@MicronautTest
@Property(name = "spec.name", value = "DeliveryTagSpec")
class DeliveryTagSpec extends Specification {
@Inject ProductClient productClient
@Inject ProductListener productListener

void "test using a custom annotation binder"() {
startContext()

when:
// tag::producer[]
ProductClient productClient = applicationContext.getBean(ProductClient)
productClient.send("body".bytes)
productClient.send("body2".bytes)
productClient.send("body3".bytes)
// end::producer[]

ProductListener productListener = applicationContext.getBean(ProductListener)
await().atMost(10, SECONDS).until {
productListener.messages.size() == 3
}

then:
waitFor {
assert productListener.messages.size() == 3
}
productListener.messages.size() == 3
}
}
Original file line number Diff line number Diff line change
@@ -1,37 +1,46 @@
package io.micronaut.rabbitmq.docs.consumer.custom.type

import io.micronaut.rabbitmq.AbstractRabbitMQTest
import io.micronaut.context.annotation.Property
import io.micronaut.test.extensions.spock.annotation.MicronautTest
import jakarta.inject.Inject
import spock.lang.Specification

class ProductInfoSpec extends AbstractRabbitMQTest {
import static java.util.concurrent.TimeUnit.SECONDS
import static org.awaitility.Awaitility.await

void "test using a custom type binder"() {
startContext()

@MicronautTest
@Property(name = "spec.name", value = "ProductInfoSpec")
class ProductInfoSpec extends Specification {
@Inject ProductClient productClient
@Inject ProductListener productListener

void "test using a custom type binder"() {
when:
// tag::producer[]
ProductClient productClient = applicationContext.getBean(ProductClient)
productClient.send("body".bytes)
productClient.send("medium", 20L, "body2".bytes)
productClient.send(null, 30L, "body3".bytes)
// end::producer[]

ProductListener productListener = applicationContext.getBean(ProductListener)

await().atMost(10, SECONDS).until {
productListener.messages.size() == 3
}

then:
waitFor {
assert productListener.messages.size() == 3
productListener.messages.size() == 3

assert productListener.messages.find({ pi ->
pi.size == "small" && pi.count == 10 && pi.sealed
}) != null
productListener.messages.find({ pi ->
pi.size == "small" && pi.count == 10 && pi.sealed
}) != null

assert productListener.messages.find({ pi ->
pi.size == "medium" && pi.count == 20 && pi.sealed
}) != null
productListener.messages.find({ pi ->
pi.size == "medium" && pi.count == 20 && pi.sealed
}) != null

assert productListener.messages.find({ pi ->
pi.size == null && pi.count == 30 && pi.sealed
}) != null
}
productListener.messages.find({ pi ->
pi.size == null && pi.count == 30 && pi.sealed
}) != null
}
}
Loading

0 comments on commit f94c850

Please sign in to comment.