diff --git a/README.md b/README.md index 90d37d6a4..13ff4015a 100644 --- a/README.md +++ b/README.md @@ -1065,6 +1065,10 @@ a collection using a filter and a projection. All tests are performed using: Reactive equivalent of `nosql-db/mongodb`. Uses reactive ReactiveMongoClient (without codecs) +### `nosql-db/infinispan` + +Provides some coverage similar to `infinispan-client` module, but with focus on connecting to local cluster and Dev mode and not on working with OpenShift + ### `websockets/quarkus-websockets` Coverage for sending messages over websockets @@ -1106,4 +1110,4 @@ Test coverage includes: - normal HTTP requests - Cloud Event Binary mode - Structured Mode -- Multiple functions declared in one application \ No newline at end of file +- Multiple functions declared in one application diff --git a/external-applications/src/test/java/io/quarkus/ts/external/applications/TodoDemoIT.java b/external-applications/src/test/java/io/quarkus/ts/external/applications/TodoDemoIT.java index cead8f399..32dd88d75 100644 --- a/external-applications/src/test/java/io/quarkus/ts/external/applications/TodoDemoIT.java +++ b/external-applications/src/test/java/io/quarkus/ts/external/applications/TodoDemoIT.java @@ -11,14 +11,30 @@ @DisabledOnNative(reason = "This scenario is using uber-jar, so it's incompatible with Native") @QuarkusScenario public class TodoDemoIT { - @GitRepositoryQuarkusApplication(repo = "https://github.com/quarkusio/todo-demo-app.git", mavenArgs = "-Dquarkus.package.type=uber-jar -DskipTests=true -Dquarkus.platform.group-id=${QUARKUS_PLATFORM_GROUP-ID} -Dquarkus.platform.version=${QUARKUS_VERSION} ") + private static final String TODO_REPO = "https://github.com/quarkusio/todo-demo-app.git"; + private static final String VERSIONS = "-Dquarkus.platform.group-id=${QUARKUS_PLATFORM_GROUP-ID} -Dquarkus.platform.version=${QUARKUS_VERSION} "; + private static final String DEFAULT_OPTIONS = "-DskipTests=true " + VERSIONS; + + @GitRepositoryQuarkusApplication(repo = TODO_REPO, mavenArgs = "-Dquarkus.package.type=uber-jar " + DEFAULT_OPTIONS) static final RestService app = new RestService(); + @GitRepositoryQuarkusApplication(repo = TODO_REPO, artifact = "todo-backend-1.0-SNAPSHOT.jar", mavenArgs = "-Dquarkus.package.type=uber-jar -Dquarkus.package.add-runner-suffix=false" + + DEFAULT_OPTIONS) + static final RestService replaced = new RestService(); + @Test - public void verify() { + public void startsSuccessfully() { app.given() .get() .then() .statusCode(HttpStatus.SC_OK); } + + @Test + public void replacedStartsSuccessfully() { + replaced.given() + .get() + .then() + .statusCode(HttpStatus.SC_OK); + } } diff --git a/http/http-advanced-reactive/src/main/resources/application.properties b/http/http-advanced-reactive/src/main/resources/application.properties index ff0e6a6d9..59ebbc627 100644 --- a/http/http-advanced-reactive/src/main/resources/application.properties +++ b/http/http-advanced-reactive/src/main/resources/application.properties @@ -67,3 +67,5 @@ pl-container-request-filter.enabled=false # Register MultipartFormDataReader as provider (used by io.quarkus.ts.http.advanced.reactive.MultipartResource.multipartFormData) quarkus.index-dependency.resteasy-multipart.group-id=org.jboss.resteasy quarkus.index-dependency.resteasy-multipart.artifact-id=resteasy-multipart-provider + +quarkus.qe.test.value=42 diff --git a/http/http-advanced-reactive/src/test/java/io/quarkus/ts/http/advanced/reactive/DevModeHttpsIT.java b/http/http-advanced-reactive/src/test/java/io/quarkus/ts/http/advanced/reactive/DevModeHttpsIT.java new file mode 100644 index 000000000..9ebd138c1 --- /dev/null +++ b/http/http-advanced-reactive/src/test/java/io/quarkus/ts/http/advanced/reactive/DevModeHttpsIT.java @@ -0,0 +1,106 @@ +package io.quarkus.ts.http.advanced.reactive; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.io.IOException; + +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import com.gargoylesoftware.htmlunit.WebClient; +import com.gargoylesoftware.htmlunit.html.DomElement; +import com.gargoylesoftware.htmlunit.html.HtmlPage; + +import io.quarkus.test.bootstrap.DevModeQuarkusService; +import io.quarkus.test.bootstrap.Protocol; +import io.quarkus.test.bootstrap.RestService; +import io.quarkus.test.scenarios.QuarkusScenario; +import io.quarkus.test.scenarios.annotations.DisabledOnQuarkusVersion; +import io.quarkus.test.services.DevModeQuarkusApplication; +import io.quarkus.test.services.URILike; +import io.quarkus.test.utils.AwaitilityUtils; + +@QuarkusScenario +@DisabledOnQuarkusVersion(version = "2\\.13\\.[0-6].*", reason = "Fixed in Quarkus 2.13.7") +public class DevModeHttpsIT { + private static final String PROPERTY = "quarkus.qe.test.value"; + + @DevModeQuarkusApplication(ssl = true) + static RestService app = new DevModeQuarkusService() + .withProperty("quarkus.oidc.enabled", "false") + .withProperty("quarkus.keycloak.policy-enforcer.enable", "false") + .withProperty("quarkus.keycloak.devservices.enabled", "false"); + + private WebClient webClient; + + @BeforeEach + void setUp() { + webClient = new WebClient(); + + webClient.getOptions().setRedirectEnabled(true); //required for the test case + //The execution breaks without the two options below + webClient.getOptions().setUseInsecureSSL(true); + webClient.getOptions().setWebSocketEnabled(false); + + //make sure, that the cache doesn't affect us + webClient.getCookieManager().clearCookies(); + webClient.getCookieManager().setCookiesEnabled(false); + webClient.getCache().clear(); + webClient.getCache().setMaxSize(0); + + //disable everything, that we don't need + webClient.getOptions().setDownloadImages(false); + webClient.getOptions().setGeolocationEnabled(false); + webClient.getOptions().setAppletEnabled(false); + webClient.getOptions().setCssEnabled(false); + } + + @AfterEach + void tearDown() { + webClient.close(); + } + + @Test + public void uiChange() throws IOException { + URILike uri = app.getURI(Protocol.HTTPS); + + HtmlPage before = webClient.getPage(uri.withPath("/q/dev/io.quarkus.quarkus-vertx-http/config").toString()); + QuarkusUIField field = new QuarkusUIField(before.getElementById(PROPERTY)); + assertEquals("42", field.getValue()); + assertEquals("42", app.getProperty(PROPERTY, "")); + + field.setValue("23"); + HtmlPage saved = field.getSaveButton().click(); + QuarkusUIField updated = new QuarkusUIField(saved.getElementById(PROPERTY)); + assertEquals("23", updated.getValue()); + + AwaitilityUtils.untilIsTrue(() -> app.getLogs().stream().anyMatch(log -> log.contains("File change detected"))); + assertEquals("23", app.getProperty(PROPERTY, "")); + } +} + +class QuarkusUIField { + private final DomElement element; + + QuarkusUIField(DomElement element) { + this.element = element; + } + + public String getValue() { + return element.getAttribute("value"); + } + + public void setValue(String newValue) { + element.setAttribute("value", newValue); + } + + public DomElement getSaveButton() { + for (DomElement sibling : element.getParentNode().getDomElementDescendants()) { + if (sibling.getAttribute("class").equals("input-group-text formInputButton")) { + return sibling; + } + } + throw new IllegalStateException("Save button was not found!"); + } +} diff --git a/lifecycle-application/src/main/java/io/quarkus/ts/lifecycle/Main.java b/lifecycle-application/src/main/java/io/quarkus/ts/lifecycle/Main.java index c9481585b..f17ea7343 100644 --- a/lifecycle-application/src/main/java/io/quarkus/ts/lifecycle/Main.java +++ b/lifecycle-application/src/main/java/io/quarkus/ts/lifecycle/Main.java @@ -16,6 +16,10 @@ private Main() { public static void main(String... args) { LOG.info(ARGUMENTS_FROM_MAIN + String.join(",", args)); - Quarkus.run(args); + if (args.length > 0 && "cli".equals(args[0])) { + return; + } else { + Quarkus.run(args); + } } } diff --git a/lifecycle-application/src/test/java/io/quarkus/ts/lifecycle/AlphabeticallyFirstTest.java b/lifecycle-application/src/test/java/io/quarkus/ts/lifecycle/AlphabeticallyFirstTest.java new file mode 100644 index 000000000..08cc13c44 --- /dev/null +++ b/lifecycle-application/src/test/java/io/quarkus/ts/lifecycle/AlphabeticallyFirstTest.java @@ -0,0 +1,27 @@ +package io.quarkus.ts.lifecycle; + +import static io.restassured.RestAssured.given; +import static org.hamcrest.Matchers.is; + +import org.junit.jupiter.api.Tag; +import org.junit.jupiter.api.Test; + +import io.quarkus.test.junit.QuarkusTest; + +/** + * The name of the test is crucial to make it run before HelloMainTest. + * See comments to the issue for the explanation. + */ +@QuarkusTest +@Tag("QUARKUS-2789") +public class AlphabeticallyFirstTest { + + @Test + public void shouldBeOk() { + given() + .when().get("/args") + .then() + .statusCode(200) + .body(is("")); + } +} diff --git a/lifecycle-application/src/test/java/io/quarkus/ts/lifecycle/HelloMainTest.java b/lifecycle-application/src/test/java/io/quarkus/ts/lifecycle/HelloMainTest.java new file mode 100644 index 000000000..f231912ba --- /dev/null +++ b/lifecycle-application/src/test/java/io/quarkus/ts/lifecycle/HelloMainTest.java @@ -0,0 +1,29 @@ +package io.quarkus.ts.lifecycle; + +import java.util.List; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +import io.quarkus.test.junit.main.Launch; +import io.quarkus.test.junit.main.LaunchResult; +import io.quarkus.test.junit.main.QuarkusMainTest; + +@QuarkusMainTest +public class HelloMainTest { + + @Test + @Launch({ "cli", "Hello", "World" }) + public void annotatedLaunch(LaunchResult result) { + List outputStream = result.getOutputStream(); + String args = null; + for (String output : outputStream) { + if (output.contains("Received arguments:")) { + args = output; + } + } + Assertions.assertNotNull(args); + Assertions.assertTrue(args.contains("Hello"), "No 'Hello' in the output!"); + Assertions.assertTrue(args.contains("World"), "No 'World' in the output!"); + } +} diff --git a/nosql-db/infinispan/pom.xml b/nosql-db/infinispan/pom.xml new file mode 100644 index 000000000..5bd1b3951 --- /dev/null +++ b/nosql-db/infinispan/pom.xml @@ -0,0 +1,69 @@ + + + 4.0.0 + + io.quarkus.ts.qe + parent + 1.0.0-SNAPSHOT + ../.. + + infinispan + jar + Quarkus QE TS: NoSQL Database: Infinispan + + + io.quarkus + quarkus-resteasy + + + io.quarkus + quarkus-infinispan-client + + + io.quarkus.qe + quarkus-test-service-infinispan + test + + + + + + skip-tests-on-windows + + + windows + + + + + + maven-surefire-plugin + + true + + + + maven-failsafe-plugin + + true + + + + + + + + + native + + + native + + + + + fast-jar + + + + diff --git a/nosql-db/infinispan/src/main/java/io/quarkus/ts/infinispan/client/FirstCounterResource.java b/nosql-db/infinispan/src/main/java/io/quarkus/ts/infinispan/client/FirstCounterResource.java new file mode 100644 index 000000000..74319a9c5 --- /dev/null +++ b/nosql-db/infinispan/src/main/java/io/quarkus/ts/infinispan/client/FirstCounterResource.java @@ -0,0 +1,7 @@ +package io.quarkus.ts.infinispan.client; + +import javax.ws.rs.Path; + +@Path("/first-counter") +public class FirstCounterResource extends InfinispanCounterResource { +} diff --git a/nosql-db/infinispan/src/main/java/io/quarkus/ts/infinispan/client/InfinispanClientApp.java b/nosql-db/infinispan/src/main/java/io/quarkus/ts/infinispan/client/InfinispanClientApp.java new file mode 100644 index 000000000..40d467356 --- /dev/null +++ b/nosql-db/infinispan/src/main/java/io/quarkus/ts/infinispan/client/InfinispanClientApp.java @@ -0,0 +1,63 @@ +package io.quarkus.ts.infinispan.client; + +import javax.enterprise.context.ApplicationScoped; +import javax.enterprise.event.Observes; +import javax.inject.Inject; + +import org.infinispan.client.hotrod.RemoteCache; +import org.infinispan.client.hotrod.RemoteCacheManager; +import org.infinispan.client.hotrod.annotation.ClientCacheEntryCreated; +import org.infinispan.client.hotrod.annotation.ClientCacheEntryModified; +import org.infinispan.client.hotrod.annotation.ClientCacheEntryRemoved; +import org.infinispan.client.hotrod.annotation.ClientListener; +import org.infinispan.client.hotrod.event.ClientCacheEntryCreatedEvent; +import org.infinispan.client.hotrod.event.ClientCacheEntryModifiedEvent; +import org.infinispan.client.hotrod.event.ClientCacheEntryRemovedEvent; +import org.infinispan.commons.configuration.XMLStringConfiguration; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import io.quarkus.runtime.StartupEvent; + +@ApplicationScoped +public class InfinispanClientApp { + + private static final Logger LOGGER = LoggerFactory.getLogger("InfinispanClientApp"); + + @Inject + RemoteCacheManager cacheManager; + + private static final String MYCACHE_CACHE_CONFIG = "" + + "" + + ""; + + void onStart(@Observes StartupEvent ev) { + LOGGER.info("Create or get cache named mycache with the default configuration"); + RemoteCache cache = cacheManager.administration().getOrCreateCache("mycache", + new XMLStringConfiguration(String.format(MYCACHE_CACHE_CONFIG, "mycache"))); + cache.addClientListener(new EventPrintListener()); + if (cache.isEmpty()) { + cache.put("counter", 0); + } + } + + @ClientListener + static class EventPrintListener { + + @ClientCacheEntryCreated + public void handleCreatedEvent(ClientCacheEntryCreatedEvent e) { + LOGGER.info("Listener: cache entry was CREATED: " + e); + } + + @ClientCacheEntryModified + public void handleModifiedEvent(ClientCacheEntryModifiedEvent e) { + LOGGER.info("Listener: cache entry was MODIFIED: " + e); + } + + @ClientCacheEntryRemoved + public void handleRemovedEvent(ClientCacheEntryRemovedEvent e) { + LOGGER.info("Listener: cache entry was REMOVED: " + e); + } + + } +} diff --git a/nosql-db/infinispan/src/main/java/io/quarkus/ts/infinispan/client/InfinispanCounterResource.java b/nosql-db/infinispan/src/main/java/io/quarkus/ts/infinispan/client/InfinispanCounterResource.java new file mode 100644 index 000000000..e3713c909 --- /dev/null +++ b/nosql-db/infinispan/src/main/java/io/quarkus/ts/infinispan/client/InfinispanCounterResource.java @@ -0,0 +1,62 @@ +package io.quarkus.ts.infinispan.client; + +import java.util.concurrent.atomic.AtomicInteger; + +import javax.inject.Inject; +import javax.ws.rs.GET; +import javax.ws.rs.PUT; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; + +import org.infinispan.client.hotrod.RemoteCache; + +import io.quarkus.infinispan.client.Remote; + +public class InfinispanCounterResource { + protected AtomicInteger counter = new AtomicInteger(0); + + @Inject + @Remote("mycache") + RemoteCache cache; + + @Path("/get-cache") + @GET + @Produces(MediaType.TEXT_PLAIN) + public Integer getCacheCounter() { + return cache.get("counter"); + } + + @Path("/get-client") + @GET + @Produces(MediaType.TEXT_PLAIN) + public Integer getClientCounter() { + return counter.get(); + } + + @Path("/increment-counters") + @PUT + @Produces(MediaType.TEXT_PLAIN) + public String incCounters() { + int invocationClientNumber = counter.incrementAndGet(); + int invocationCacheNumber = cache.get("counter") + 1; + cache.put("counter", invocationCacheNumber); + return "Cache=" + invocationCacheNumber + " Client=" + invocationClientNumber; + } + + @Path("/reset-cache") + @PUT + @Produces(MediaType.TEXT_PLAIN) + public String resetCacheCounter() { + cache.put("counter", 0); + return "Cache=" + cache.get("counter"); + } + + @Path("/reset-client") + @PUT + @Produces(MediaType.TEXT_PLAIN) + public String resetClientCounter() { + counter.set(0); + return "Client=" + counter.get(); + } +} diff --git a/nosql-db/infinispan/src/main/java/io/quarkus/ts/infinispan/client/SecondCounterResource.java b/nosql-db/infinispan/src/main/java/io/quarkus/ts/infinispan/client/SecondCounterResource.java new file mode 100644 index 000000000..6294c22ec --- /dev/null +++ b/nosql-db/infinispan/src/main/java/io/quarkus/ts/infinispan/client/SecondCounterResource.java @@ -0,0 +1,7 @@ +package io.quarkus.ts.infinispan.client; + +import javax.ws.rs.Path; + +@Path("/second-counter") +public class SecondCounterResource extends InfinispanCounterResource { +} diff --git a/nosql-db/infinispan/src/main/resources/application.properties b/nosql-db/infinispan/src/main/resources/application.properties new file mode 100644 index 000000000..67631119e --- /dev/null +++ b/nosql-db/infinispan/src/main/resources/application.properties @@ -0,0 +1,7 @@ +quarkus.infinispan-client.auth-username=admin +quarkus.infinispan-client.auth-password=password +quarkus.infinispan-client.client-intelligence=BASIC + +quarkus.infinispan-client.cache."cache".configuration-uri=cache-configuration.xml +quarkus.infinispan-client.cache."cache".near-cache-mode: disabled +quarkus.infinispan-client.cache."cache".near-cache-max-entries: -1 diff --git a/nosql-db/infinispan/src/main/resources/cache-configuration.xml b/nosql-db/infinispan/src/main/resources/cache-configuration.xml new file mode 100644 index 000000000..2f5f86fa1 --- /dev/null +++ b/nosql-db/infinispan/src/main/resources/cache-configuration.xml @@ -0,0 +1,11 @@ + + + Very basic cache configuration + + + + + + + + diff --git a/nosql-db/infinispan/src/test/java/io/quarkus/ts/infinispan/DevModeInfinispanIT.java b/nosql-db/infinispan/src/test/java/io/quarkus/ts/infinispan/DevModeInfinispanIT.java new file mode 100644 index 000000000..d26d27252 --- /dev/null +++ b/nosql-db/infinispan/src/test/java/io/quarkus/ts/infinispan/DevModeInfinispanIT.java @@ -0,0 +1,39 @@ +package io.quarkus.ts.infinispan; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.apache.http.HttpStatus; +import org.junit.jupiter.api.Test; + +import io.quarkus.test.bootstrap.InfinispanService; +import io.quarkus.test.bootstrap.RestService; +import io.quarkus.test.scenarios.QuarkusScenario; +import io.quarkus.test.services.Container; +import io.quarkus.test.services.DevModeQuarkusApplication; + +@QuarkusScenario +public class DevModeInfinispanIT { + @Container(image = "${infinispan.image}", port = 11222) + static InfinispanService infinispan = new InfinispanService() + .withUsername("admin") + .withPassword("password"); + + @DevModeQuarkusApplication() + static RestService service = new RestService() + .withProperty("quarkus.infinispan-client.server-list", + () -> infinispan.getURI().toString()); + + @Test + void smoke() { + String firstCache = service.given() + .get("/first-counter/get-cache") + .then().statusCode(HttpStatus.SC_OK) + .extract().asString(); + String secondCache = service.given() + .get("/second-counter/get-cache") + .then().statusCode(HttpStatus.SC_OK) + .extract().asString(); + + assertEquals(firstCache, secondCache); + } +} diff --git a/nosql-db/infinispan/src/test/java/io/quarkus/ts/infinispan/InfinispanIT.java b/nosql-db/infinispan/src/test/java/io/quarkus/ts/infinispan/InfinispanIT.java new file mode 100644 index 000000000..68061aeeb --- /dev/null +++ b/nosql-db/infinispan/src/test/java/io/quarkus/ts/infinispan/InfinispanIT.java @@ -0,0 +1,41 @@ +package io.quarkus.ts.infinispan; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.apache.http.HttpStatus; +import org.junit.jupiter.api.Test; + +import io.quarkus.test.bootstrap.InfinispanService; +import io.quarkus.test.bootstrap.RestService; +import io.quarkus.test.scenarios.QuarkusScenario; +import io.quarkus.test.scenarios.annotations.DisabledOnNative; +import io.quarkus.test.services.Container; +import io.quarkus.test.services.QuarkusApplication; + +@QuarkusScenario +@DisabledOnNative(reason = "https://github.com/quarkusio/quarkus/issues/30304") +public class InfinispanIT { + @Container(image = "${infinispan.image}", port = 11222) + static InfinispanService infinispan = new InfinispanService() + .withUsername("admin") + .withPassword("password"); + + @QuarkusApplication() + static RestService service = new RestService() + .withProperty("quarkus.infinispan-client.server-list", + () -> infinispan.getURI().toString()); + + @Test + void smoke() { + String firstCache = service.given() + .get("/first-counter/get-cache") + .then().statusCode(HttpStatus.SC_OK) + .extract().asString(); + String secondCache = service.given() + .get("/second-counter/get-cache") + .then().statusCode(HttpStatus.SC_OK) + .extract().asString(); + + assertEquals(firstCache, secondCache); + } +} diff --git a/pom.xml b/pom.xml index 29afeb755..79016ab35 100644 --- a/pom.xml +++ b/pom.xml @@ -19,7 +19,7 @@ quarkus-bom io.quarkus 2.13.6.Final - 1.2.0.Final + 1.2.1.Final 0.38.0 2.12.1.Final 4.5.13 @@ -553,6 +553,7 @@ env-info nosql-db/mongodb nosql-db/mongodb-reactive + nosql-db/infinispan