From e38c3626b71247ee22cd91c33ac95d70eb810406 Mon Sep 17 00:00:00 2001 From: Thibault Vallin Date: Sat, 20 Feb 2021 09:24:56 +0100 Subject: [PATCH 1/7] Cover todo app with tests Signed-off-by: tvallin --- examples/todo-app/backend/pom.xml | 34 +++ .../demo/todos/backend/BackendTests.java | 172 ++++++++++++ .../src/test/resources/test-application.yaml | 36 +++ examples/todo-app/frontend/pom.xml | 15 + .../demo/todos/frontend/FrontendTest.java | 256 ++++++++++++++++++ .../test/resources/frontend-application.yaml | 35 +++ 6 files changed, 548 insertions(+) create mode 100644 examples/todo-app/backend/src/test/java/io/helidon/demo/todos/backend/BackendTests.java create mode 100644 examples/todo-app/backend/src/test/resources/test-application.yaml create mode 100644 examples/todo-app/frontend/src/test/java/io/helidon/demo/todos/frontend/FrontendTest.java create mode 100644 examples/todo-app/frontend/src/test/resources/frontend-application.yaml diff --git a/examples/todo-app/backend/pom.xml b/examples/todo-app/backend/pom.xml index 940467e3746..6eaae0f55a3 100644 --- a/examples/todo-app/backend/pom.xml +++ b/examples/todo-app/backend/pom.xml @@ -85,6 +85,40 @@ com.datastax.cassandra cassandra-driver-core + + org.junit.jupiter + junit-jupiter-api + test + + + io.helidon.webclient + helidon-webclient + test + + + org.cassandraunit + cassandra-unit + 4.3.1.0 + test + + + com.datastax.oss + java-driver-core + 4.9.0 + test + + + com.datastax.oss + java-driver-query-builder + 4.9.0 + test + + + com.codahale.metrics + metrics-core + 3.0.2 + test + diff --git a/examples/todo-app/backend/src/test/java/io/helidon/demo/todos/backend/BackendTests.java b/examples/todo-app/backend/src/test/java/io/helidon/demo/todos/backend/BackendTests.java new file mode 100644 index 00000000000..b9866a0e65b --- /dev/null +++ b/examples/todo-app/backend/src/test/java/io/helidon/demo/todos/backend/BackendTests.java @@ -0,0 +1,172 @@ +/* + * Copyright (c) 2021 Oracle and/or its affiliates. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.helidon.demo.todos.backend; + +import com.datastax.driver.core.Cluster; +import com.datastax.driver.core.Session; +import io.helidon.common.http.Http; +import io.helidon.config.Config; +import io.helidon.media.jsonp.JsonpSupport; +import io.helidon.microprofile.server.Server; +import io.helidon.webclient.WebClient; +import org.cassandraunit.utils.EmbeddedCassandraServerHelper; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + +import javax.json.Json; +import javax.json.JsonArray; +import javax.json.JsonObject; +import java.io.IOException; +import java.util.Base64; +import java.util.List; + +import static io.helidon.config.ConfigSources.classpath; + +public class BackendTests { + + private static WebClient client; + private static Server server; + + @BeforeAll + public static void init() throws IOException { + Config config = Config.builder() + .sources(List.of( + classpath("test-application.yaml") + )) + .build(); + + initCassandra(config); + + server = Server.builder() + .config(config) + .build(); + + server.start(); + + client = WebClient.builder() + .baseUri("http://0.0.0.0:" + server.port()) + .addMediaSupport(JsonpSupport.create()) + .build(); + } + + @AfterAll + public static void stopServer() { + EmbeddedCassandraServerHelper.cleanEmbeddedCassandra(); + server.stop(); + } + + private static void initCassandra(Config config) throws IOException { + EmbeddedCassandraServerHelper.startEmbeddedCassandra(20000L); + + Cluster.Builder clusterBuilder = Cluster.builder().withoutMetrics(); + config.get("cassandra").get("servers").asList(Config.class).get().forEach(serverConfig -> { + clusterBuilder.addContactPoints( + serverConfig.get("host").asString().get()); + }); + config.get("cassandra").get("port").asInt().ifPresent(clusterBuilder::withPort); + Cluster cluster = clusterBuilder.build(); + + Session session = cluster.connect(); + session.execute("CREATE KEYSPACE backend WITH REPLICATION = {'class' : 'SimpleStrategy', 'replication_factor' : 1};"); + session.execute("CREATE TABLE backend.backend (id ascii, user ascii, message ascii, completed Boolean, created timestamp, PRIMARY KEY (id));"); + session.execute("select * from backend.backend;"); + + session.close(); + cluster.close(); + } + + @Test + public void testTODOScenario() { + final String encodingID = Base64.getEncoder().encodeToString("john:password".getBytes()); + JsonObject todo = Json.createObjectBuilder() + .add("title", "todo title") + .build(); + + // Add a new todo + final JsonObject returnedTodo = client.post() + .path("/api/backend") + .headers(headers -> { + headers.add(Http.Header.AUTHORIZATION, "Basic " + encodingID); + return headers; + }) + .submit(todo, JsonObject.class) + .await(); + + Assertions.assertEquals("john", returnedTodo.getString("user")); + Assertions.assertEquals(todo.getString("title"), returnedTodo.getString("title")); + + // Get the todo created earlier + client.get() + .path("/api/backend/" + returnedTodo.getString("id")) + .headers(headers -> { + headers.add(Http.Header.AUTHORIZATION, "Basic " + encodingID); + return headers; + }) + .request(JsonObject.class) + .thenAccept(jsonObject -> { + Assertions.assertEquals(returnedTodo, jsonObject); + }) + .await(); + + // Update the todo created earlier + JsonObject updatedTODO = Json.createObjectBuilder() + .add("title", "updated title") + .add("completed", false) + .build(); + + client.put() + .path("/api/backend/" + returnedTodo.getString("id")) + .headers(headers -> { + headers.add(Http.Header.AUTHORIZATION, "Basic " + encodingID); + return headers; + }) + .submit(updatedTODO, JsonObject.class) + .thenAccept(jsonObject -> { + Assertions.assertEquals(updatedTODO.getString("title"), jsonObject.getString("title")); + }) + .await(); + + // Delete the todo created earlier + client.delete() + .path("/api/backend/" + returnedTodo.getString("id")) + .headers(headers -> { + headers.add(Http.Header.AUTHORIZATION, "Basic " + encodingID); + return headers; + }) + .request(JsonObject.class) + .thenAccept(jsonObject -> { + Assertions.assertEquals(returnedTodo.getString("id"), jsonObject.getString("id")); + }) + .await(); + + // Get list of todos + client.get() + .path("/api/backend") + .headers(headers -> { + headers.add(Http.Header.AUTHORIZATION, "Basic " + encodingID); + return headers; + }) + .request(JsonArray.class) + .thenAccept(jsonValues -> { + Assertions.assertEquals(0, jsonValues.size()); + }) + .await(); + } + +} diff --git a/examples/todo-app/backend/src/test/resources/test-application.yaml b/examples/todo-app/backend/src/test/resources/test-application.yaml new file mode 100644 index 00000000000..9a02a2d18ae --- /dev/null +++ b/examples/todo-app/backend/src/test/resources/test-application.yaml @@ -0,0 +1,36 @@ +# +# Copyright (c) 2021 Oracle and/or its affiliates. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +server: + port: 8854 + host: 0.0.0.0 + +tracing: + service: "todo:back" + host: "zipkin" + +cassandra: + port: 9142 + servers: + - host: 127.0.0.1 + +security: + providers: + - http-basic-auth: + realm: "helidon" + users: + - login: "john" + password: "password" \ No newline at end of file diff --git a/examples/todo-app/frontend/pom.xml b/examples/todo-app/frontend/pom.xml index df26657ec6f..d0b743227bc 100644 --- a/examples/todo-app/frontend/pom.xml +++ b/examples/todo-app/frontend/pom.xml @@ -121,6 +121,21 @@ org.glassfish.jersey.core jersey-common + + org.junit.jupiter + junit-jupiter-api + test + + + io.helidon.webserver + helidon-webserver-jersey + test + + + io.helidon.webclient + helidon-webclient + test + diff --git a/examples/todo-app/frontend/src/test/java/io/helidon/demo/todos/frontend/FrontendTest.java b/examples/todo-app/frontend/src/test/java/io/helidon/demo/todos/frontend/FrontendTest.java new file mode 100644 index 00000000000..b9d3a81120f --- /dev/null +++ b/examples/todo-app/frontend/src/test/java/io/helidon/demo/todos/frontend/FrontendTest.java @@ -0,0 +1,256 @@ +/* + * Copyright (c) 2021 Oracle and/or its affiliates. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.helidon.demo.todos.frontend; + +import io.helidon.common.http.Http; +import io.helidon.config.Config; +import io.helidon.media.jsonp.JsonpSupport; +import io.helidon.security.Security; +import io.helidon.security.integration.webserver.WebSecurity; +import io.helidon.webclient.WebClient; +import io.helidon.webserver.Routing; +import io.helidon.webserver.WebServer; +import io.helidon.webserver.jersey.JerseySupport; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + +import javax.json.Json; +import javax.json.JsonArray; +import javax.json.JsonObject; +import javax.ws.rs.Consumes; +import javax.ws.rs.DELETE; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.PUT; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.client.Client; +import javax.ws.rs.client.ClientBuilder; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import java.util.Base64; +import java.util.List; +import java.util.concurrent.ExecutionException; + +import static io.helidon.config.ConfigSources.classpath; + +public class FrontendTest { + + private static WebServer serverBackend; + private static WebServer serverFrontend; + private static WebClient client; + private static final JsonObject TODO = Json.createObjectBuilder().add("msg", "todo").build(); + private static final String ENCODED_ID = Base64.getEncoder().encodeToString("john:password".getBytes()); + + @Path("/api/backend") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + public static class FakeBackendService { + + @GET + @Produces(MediaType.APPLICATION_JSON) + public Response getAllTodo() { + JsonArray jsonArray = Json.createArrayBuilder().add(TODO).build(); + return Response.ok(jsonArray, MediaType.APPLICATION_JSON).build(); + } + + @POST + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + public Response createTodo(JsonObject object) { + return Response.ok(object, MediaType.APPLICATION_JSON).build(); + } + + @GET + @Path("/{id}") + @Produces(MediaType.APPLICATION_JSON) + public Response getTodo() { + return Response.ok(TODO, MediaType.APPLICATION_JSON).build(); + } + + @DELETE + @Path("/{id}") + @Produces(MediaType.APPLICATION_JSON) + public Response deleteTodo() { + return Response.ok(TODO, MediaType.APPLICATION_JSON).build(); + } + + @PUT + @Path("/{id}") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + public Response updateTodo(JsonObject object) { + return Response.ok(object, MediaType.APPLICATION_JSON).build(); + } + } + + @BeforeAll + public static void init() { + startBackendServer(); + startFrontendServer(); + client = WebClient.builder() + .baseUri("http://localhost:" + serverFrontend.port()) + .addMediaSupport(JsonpSupport.create()) + .build(); + } + + @AfterAll + public static void stopServers() { + serverBackend.shutdown(); + serverFrontend.shutdown(); + } + + private static void startBackendServer() { + serverBackend = WebServer.builder(createRouting()) + .port(8854) + .addMediaSupport(JsonpSupport.create()) + .build(); + + serverBackend.start(); + } + + private static Routing createRouting() { + return Routing.builder() + .register("/", JerseySupport.builder() + .register(FakeBackendService.class) + .build()) + .build(); + } + + private static void startFrontendServer() { + Config config = Config.builder() + .sources(List.of( + classpath("frontend-application.yaml") + )) + .build(); + Client client = ClientBuilder.newClient(); + BackendServiceClient bsc = new BackendServiceClient(client, config); + + serverFrontend = WebServer.builder(createRouting( + Security.create(config.get("security")), + config, + bsc)) + .config(config.get("webserver")) + .addMediaSupport(JsonpSupport.create()) + .build(); + + serverFrontend.start(); + } + + private static Routing createRouting(Security security, Config config, BackendServiceClient bsc) { + return Routing.builder() + .register(WebSecurity.create(security, config.get("security"))) + .register("/env", new EnvHandler(config)) + .register("/api", new TodosHandler(bsc)) + .build(); + } + + @Test + public void testGetList() throws ExecutionException, InterruptedException { + client.get() + .path("/api/todo") + .headers(headers -> { + headers.add(Http.Header.AUTHORIZATION, "Basic " + ENCODED_ID); + return headers; + }) + .request(JsonArray.class) + .thenAccept(jsonValues -> { + Assertions.assertEquals(TODO, jsonValues.getJsonObject(0)); + }) + .toCompletableFuture() + .get(); + } + + @Test + public void testPostTodo() throws ExecutionException, InterruptedException { + client.post() + .path("/api/todo") + .headers(headers -> { + headers.add(Http.Header.AUTHORIZATION, "Basic " + ENCODED_ID); + return headers; + }) + .submit(TODO, JsonObject.class) + .thenAccept(jsonObject -> { + Assertions.assertEquals(TODO, jsonObject); + }) + .toCompletableFuture() + .get(); + } + + @Test + public void testGetTodo() throws ExecutionException, InterruptedException { + client.get() + .path("/api/todo/1") + .headers(headers -> { + headers.add(Http.Header.AUTHORIZATION, "Basic " + ENCODED_ID); + return headers; + }) + .request(JsonObject.class) + .thenAccept(jsonObject -> { + Assertions.assertEquals(TODO, jsonObject); + }) + .toCompletableFuture() + .get(); + } + + @Test + public void testDeleteTodo() throws ExecutionException, InterruptedException { + client.delete() + .path("/api/todo/1") + .headers(headers -> { + headers.add(Http.Header.AUTHORIZATION, "Basic " + ENCODED_ID); + return headers; + }) + .request(JsonObject.class) + .thenAccept(jsonObject -> { + Assertions.assertEquals(TODO, jsonObject); + }) + .toCompletableFuture() + .get(); + } + + @Test + public void testUpdateTodo() throws ExecutionException, InterruptedException { + client.put() + .path("/api/todo/1") + .headers(headers -> { + headers.add(Http.Header.AUTHORIZATION, "Basic " + ENCODED_ID); + return headers; + }) + .submit(TODO, JsonObject.class) + .thenAccept(jsonObject -> { + Assertions.assertEquals(TODO, jsonObject); + }) + .toCompletableFuture() + .get(); + } + + @Test + public void testEnvHandler() throws ExecutionException, InterruptedException { + client.get() + .path("/env") + .request(String.class) + .thenAccept(s -> { + Assertions.assertEquals("docker", s); + }) + .toCompletableFuture() + .get(); + } + +} diff --git a/examples/todo-app/frontend/src/test/resources/frontend-application.yaml b/examples/todo-app/frontend/src/test/resources/frontend-application.yaml new file mode 100644 index 00000000000..e6287df0e43 --- /dev/null +++ b/examples/todo-app/frontend/src/test/resources/frontend-application.yaml @@ -0,0 +1,35 @@ +# +# Copyright (c) 2021 Oracle and/or its affiliates. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +env: docker + +webserver: + port: 8080 + +services: + backend.endpoint: "http://127.0.0.1:8854" + +security: + providers: + - http-basic-auth: + realm: "helidon" + users: + - login: "john" + password: "password" + web-server: + paths: + - path: "/api/{+}" + authenticate: true \ No newline at end of file From e73cac1c9df0c89d471b53373a01769cb95cabd4 Mon Sep 17 00:00:00 2001 From: Thibault Vallin Date: Tue, 6 Apr 2021 14:25:22 +0200 Subject: [PATCH 2/7] Use random port Signed-off-by: tvallin --- .../demo/todos/backend/BackendTests.java | 31 ++++++++++++------- .../src/test/resources/test-application.yaml | 9 ++---- .../demo/todos/frontend/FrontendTest.java | 16 ++++++++-- .../test/resources/frontend-application.yaml | 5 +-- 4 files changed, 36 insertions(+), 25 deletions(-) diff --git a/examples/todo-app/backend/src/test/java/io/helidon/demo/todos/backend/BackendTests.java b/examples/todo-app/backend/src/test/java/io/helidon/demo/todos/backend/BackendTests.java index b9866a0e65b..fdb97ee1da9 100644 --- a/examples/todo-app/backend/src/test/java/io/helidon/demo/todos/backend/BackendTests.java +++ b/examples/todo-app/backend/src/test/java/io/helidon/demo/todos/backend/BackendTests.java @@ -20,6 +20,7 @@ import com.datastax.driver.core.Session; import io.helidon.common.http.Http; import io.helidon.config.Config; +import io.helidon.config.ConfigSources; import io.helidon.media.jsonp.JsonpSupport; import io.helidon.microprofile.server.Server; import io.helidon.webclient.WebClient; @@ -35,6 +36,7 @@ import java.io.IOException; import java.util.Base64; import java.util.List; +import java.util.Properties; import static io.helidon.config.ConfigSources.classpath; @@ -42,17 +44,19 @@ public class BackendTests { private static WebClient client; private static Server server; + private final static String CASSANDRA_HOST = "127.0.0.1"; @BeforeAll public static void init() throws IOException { + Properties cassandraProperties = initCassandra(); + Config config = Config.builder() .sources(List.of( - classpath("test-application.yaml") + classpath("test-application.yaml"), + ConfigSources.create(cassandraProperties) )) .build(); - initCassandra(config); - server = Server.builder() .config(config) .build(); @@ -71,16 +75,17 @@ public static void stopServer() { server.stop(); } - private static void initCassandra(Config config) throws IOException { - EmbeddedCassandraServerHelper.startEmbeddedCassandra(20000L); + private static Properties initCassandra() throws IOException { + EmbeddedCassandraServerHelper.startEmbeddedCassandra(EmbeddedCassandraServerHelper.CASSANDRA_RNDPORT_YML_FILE, 20000L); + Properties prop = new Properties(); + prop.put("cassandra.port", EmbeddedCassandraServerHelper.getNativeTransportPort()); + prop.put("cassandra.servers.host.host", CASSANDRA_HOST); - Cluster.Builder clusterBuilder = Cluster.builder().withoutMetrics(); - config.get("cassandra").get("servers").asList(Config.class).get().forEach(serverConfig -> { - clusterBuilder.addContactPoints( - serverConfig.get("host").asString().get()); - }); - config.get("cassandra").get("port").asInt().ifPresent(clusterBuilder::withPort); - Cluster cluster = clusterBuilder.build(); + Cluster cluster = Cluster.builder() + .withoutMetrics() + .addContactPoint(CASSANDRA_HOST) + .withPort(EmbeddedCassandraServerHelper.getNativeTransportPort()) + .build(); Session session = cluster.connect(); session.execute("CREATE KEYSPACE backend WITH REPLICATION = {'class' : 'SimpleStrategy', 'replication_factor' : 1};"); @@ -89,6 +94,8 @@ private static void initCassandra(Config config) throws IOException { session.close(); cluster.close(); + + return prop; } @Test diff --git a/examples/todo-app/backend/src/test/resources/test-application.yaml b/examples/todo-app/backend/src/test/resources/test-application.yaml index 9a02a2d18ae..4f4e16b7c5c 100644 --- a/examples/todo-app/backend/src/test/resources/test-application.yaml +++ b/examples/todo-app/backend/src/test/resources/test-application.yaml @@ -15,22 +15,17 @@ # server: - port: 8854 + port: 0 host: 0.0.0.0 tracing: service: "todo:back" host: "zipkin" -cassandra: - port: 9142 - servers: - - host: 127.0.0.1 - security: providers: - http-basic-auth: realm: "helidon" users: - login: "john" - password: "password" \ No newline at end of file + password: "password" diff --git a/examples/todo-app/frontend/src/test/java/io/helidon/demo/todos/frontend/FrontendTest.java b/examples/todo-app/frontend/src/test/java/io/helidon/demo/todos/frontend/FrontendTest.java index b9d3a81120f..a956c7584e9 100644 --- a/examples/todo-app/frontend/src/test/java/io/helidon/demo/todos/frontend/FrontendTest.java +++ b/examples/todo-app/frontend/src/test/java/io/helidon/demo/todos/frontend/FrontendTest.java @@ -18,6 +18,7 @@ import io.helidon.common.http.Http; import io.helidon.config.Config; +import io.helidon.config.ConfigSources; import io.helidon.media.jsonp.JsonpSupport; import io.helidon.security.Security; import io.helidon.security.integration.webserver.WebSecurity; @@ -46,7 +47,9 @@ import javax.ws.rs.core.Response; import java.util.Base64; import java.util.List; +import java.util.Properties; import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; import static io.helidon.config.ConfigSources.classpath; @@ -118,11 +121,17 @@ public static void stopServers() { private static void startBackendServer() { serverBackend = WebServer.builder(createRouting()) - .port(8854) + .port(0) .addMediaSupport(JsonpSupport.create()) .build(); serverBackend.start(); + + try { + TimeUnit.SECONDS.sleep(5); + } catch (InterruptedException ie) { + ie.printStackTrace(); + } } private static Routing createRouting() { @@ -134,9 +143,12 @@ private static Routing createRouting() { } private static void startFrontendServer() { + Properties prop = new Properties(); + prop.put("services.backend.endpoint", "http://127.0.0.1:" + serverBackend.port()); Config config = Config.builder() .sources(List.of( - classpath("frontend-application.yaml") + classpath("frontend-application.yaml"), + ConfigSources.create(prop) )) .build(); Client client = ClientBuilder.newClient(); diff --git a/examples/todo-app/frontend/src/test/resources/frontend-application.yaml b/examples/todo-app/frontend/src/test/resources/frontend-application.yaml index e6287df0e43..930036dc31c 100644 --- a/examples/todo-app/frontend/src/test/resources/frontend-application.yaml +++ b/examples/todo-app/frontend/src/test/resources/frontend-application.yaml @@ -17,10 +17,7 @@ env: docker webserver: - port: 8080 - -services: - backend.endpoint: "http://127.0.0.1:8854" + port: 0 security: providers: From c8d281c43cccb976c62c6e4396ab4ef43ee41a85 Mon Sep 17 00:00:00 2001 From: tvallin Date: Fri, 4 Jun 2021 09:28:35 +0200 Subject: [PATCH 3/7] Use version properties Signed-off-by: tvallin --- examples/todo-app/backend/pom.xml | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/examples/todo-app/backend/pom.xml b/examples/todo-app/backend/pom.xml index 6eaae0f55a3..8959a02245f 100644 --- a/examples/todo-app/backend/pom.xml +++ b/examples/todo-app/backend/pom.xml @@ -38,6 +38,10 @@ io.helidon.demo.todos.backend.Main 3.10.2 + 4.3.1.0 + 4.9.0 + 4.9.0 + 3.0.2 @@ -98,25 +102,25 @@ org.cassandraunit cassandra-unit - 4.3.1.0 + ${version.cassandra.unit} test com.datastax.oss java-driver-core - 4.9.0 + ${version.datastax.driver.core} test com.datastax.oss java-driver-query-builder - 4.9.0 + ${version.datastax.driver.query.builder} test com.codahale.metrics metrics-core - 3.0.2 + ${version.codahale.metrics.core} test From 46df5c3d1bd31c07910e0fd7313a73c28a66dc7d Mon Sep 17 00:00:00 2001 From: tvallin Date: Fri, 4 Jun 2021 11:10:30 +0200 Subject: [PATCH 4/7] Fix Copyright Format Signed-off-by: tvallin --- .../test/java/io/helidon/demo/todos/backend/BackendTests.java | 2 +- .../todo-app/backend/src/test/resources/test-application.yaml | 2 +- .../test/java/io/helidon/demo/todos/frontend/FrontendTest.java | 2 +- .../frontend/src/test/resources/frontend-application.yaml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/examples/todo-app/backend/src/test/java/io/helidon/demo/todos/backend/BackendTests.java b/examples/todo-app/backend/src/test/java/io/helidon/demo/todos/backend/BackendTests.java index fdb97ee1da9..29eda0a90f8 100644 --- a/examples/todo-app/backend/src/test/java/io/helidon/demo/todos/backend/BackendTests.java +++ b/examples/todo-app/backend/src/test/java/io/helidon/demo/todos/backend/BackendTests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021 Oracle and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/examples/todo-app/backend/src/test/resources/test-application.yaml b/examples/todo-app/backend/src/test/resources/test-application.yaml index 4f4e16b7c5c..7fb211f23e7 100644 --- a/examples/todo-app/backend/src/test/resources/test-application.yaml +++ b/examples/todo-app/backend/src/test/resources/test-application.yaml @@ -1,5 +1,5 @@ # -# Copyright (c) 2021 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2021 Oracle and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/examples/todo-app/frontend/src/test/java/io/helidon/demo/todos/frontend/FrontendTest.java b/examples/todo-app/frontend/src/test/java/io/helidon/demo/todos/frontend/FrontendTest.java index a956c7584e9..23d69ad0684 100644 --- a/examples/todo-app/frontend/src/test/java/io/helidon/demo/todos/frontend/FrontendTest.java +++ b/examples/todo-app/frontend/src/test/java/io/helidon/demo/todos/frontend/FrontendTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021 Oracle and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/examples/todo-app/frontend/src/test/resources/frontend-application.yaml b/examples/todo-app/frontend/src/test/resources/frontend-application.yaml index 930036dc31c..7023ef634b4 100644 --- a/examples/todo-app/frontend/src/test/resources/frontend-application.yaml +++ b/examples/todo-app/frontend/src/test/resources/frontend-application.yaml @@ -1,5 +1,5 @@ # -# Copyright (c) 2021 Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2021 Oracle and/or its affiliates. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. From 91388abef7e5da1ab6a04538b784c9fdf8120067 Mon Sep 17 00:00:00 2001 From: Tomas Langer Date: Wed, 6 Oct 2021 12:43:55 +0200 Subject: [PATCH 5/7] Remove public from test --- .../java/io/helidon/demo/todos/backend/BackendTests.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/examples/todo-app/backend/src/test/java/io/helidon/demo/todos/backend/BackendTests.java b/examples/todo-app/backend/src/test/java/io/helidon/demo/todos/backend/BackendTests.java index 29eda0a90f8..91be0c4f251 100644 --- a/examples/todo-app/backend/src/test/java/io/helidon/demo/todos/backend/BackendTests.java +++ b/examples/todo-app/backend/src/test/java/io/helidon/demo/todos/backend/BackendTests.java @@ -40,14 +40,14 @@ import static io.helidon.config.ConfigSources.classpath; -public class BackendTests { +class BackendTests { private static WebClient client; private static Server server; private final static String CASSANDRA_HOST = "127.0.0.1"; @BeforeAll - public static void init() throws IOException { + static void init() throws IOException { Properties cassandraProperties = initCassandra(); Config config = Config.builder() @@ -70,7 +70,7 @@ public static void init() throws IOException { } @AfterAll - public static void stopServer() { + static void stopServer() { EmbeddedCassandraServerHelper.cleanEmbeddedCassandra(); server.stop(); } @@ -99,7 +99,7 @@ private static Properties initCassandra() throws IOException { } @Test - public void testTODOScenario() { + void testTODOScenario() { final String encodingID = Base64.getEncoder().encodeToString("john:password".getBytes()); JsonObject todo = Json.createObjectBuilder() .add("title", "todo title") From 74730847d5c428f4aba27839c61c0865e2cae806 Mon Sep 17 00:00:00 2001 From: Tomas Langer Date: Thu, 7 Oct 2021 12:38:49 +0200 Subject: [PATCH 6/7] Changed to @HelidonTest Signed-off-by: Tomas Langer --- examples/todo-app/backend/pom.xml | 4 +- .../demo/todos/backend/BackendTests.java | 165 ++++++++---------- .../src/test/resources/test-application.yaml | 13 +- 3 files changed, 84 insertions(+), 98 deletions(-) diff --git a/examples/todo-app/backend/pom.xml b/examples/todo-app/backend/pom.xml index 8959a02245f..35cc9f53814 100644 --- a/examples/todo-app/backend/pom.xml +++ b/examples/todo-app/backend/pom.xml @@ -95,8 +95,8 @@ test - io.helidon.webclient - helidon-webclient + io.helidon.microprofile.tests + helidon-microprofile-tests-junit5 test diff --git a/examples/todo-app/backend/src/test/java/io/helidon/demo/todos/backend/BackendTests.java b/examples/todo-app/backend/src/test/java/io/helidon/demo/todos/backend/BackendTests.java index 91be0c4f251..765e49ab3b3 100644 --- a/examples/todo-app/backend/src/test/java/io/helidon/demo/todos/backend/BackendTests.java +++ b/examples/todo-app/backend/src/test/java/io/helidon/demo/todos/backend/BackendTests.java @@ -16,72 +16,70 @@ package io.helidon.demo.todos.backend; +import java.io.IOException; +import java.util.Base64; +import java.util.Properties; + +import javax.inject.Inject; +import javax.json.Json; +import javax.json.JsonArray; +import javax.json.JsonObject; +import javax.ws.rs.client.Entity; +import javax.ws.rs.client.WebTarget; +import javax.ws.rs.core.MediaType; + +import io.helidon.common.http.Http; +import io.helidon.config.mp.MpConfigSources; +import io.helidon.config.yaml.YamlMpConfigSource; +import io.helidon.microprofile.tests.junit5.Configuration; +import io.helidon.microprofile.tests.junit5.HelidonTest; + import com.datastax.driver.core.Cluster; import com.datastax.driver.core.Session; -import io.helidon.common.http.Http; -import io.helidon.config.Config; -import io.helidon.config.ConfigSources; -import io.helidon.media.jsonp.JsonpSupport; -import io.helidon.microprofile.server.Server; -import io.helidon.webclient.WebClient; import org.cassandraunit.utils.EmbeddedCassandraServerHelper; +import org.eclipse.microprofile.config.spi.ConfigProviderResolver; import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; -import javax.json.Json; -import javax.json.JsonArray; -import javax.json.JsonObject; -import java.io.IOException; -import java.util.Base64; -import java.util.List; -import java.util.Properties; - -import static io.helidon.config.ConfigSources.classpath; +import static org.junit.jupiter.api.Assertions.assertEquals; +@HelidonTest +@Configuration(useExisting = true) class BackendTests { - private static WebClient client; - private static Server server; private final static String CASSANDRA_HOST = "127.0.0.1"; + @Inject + private WebTarget webTarget; + @BeforeAll static void init() throws IOException { Properties cassandraProperties = initCassandra(); - Config config = Config.builder() - .sources(List.of( - classpath("test-application.yaml"), - ConfigSources.create(cassandraProperties) - )) - .build(); + ClassLoader cl = Thread.currentThread().getContextClassLoader(); + ConfigProviderResolver configResolver = ConfigProviderResolver.instance(); - server = Server.builder() - .config(config) + org.eclipse.microprofile.config.Config mpConfig = configResolver.getBuilder() + .withSources(YamlMpConfigSource.create(cl.getResource("test-application.yaml")), + MpConfigSources.create(cassandraProperties)) .build(); - server.start(); - - client = WebClient.builder() - .baseUri("http://0.0.0.0:" + server.port()) - .addMediaSupport(JsonpSupport.create()) - .build(); + configResolver.registerConfig(mpConfig, null); } @AfterAll static void stopServer() { EmbeddedCassandraServerHelper.cleanEmbeddedCassandra(); - server.stop(); } private static Properties initCassandra() throws IOException { EmbeddedCassandraServerHelper.startEmbeddedCassandra(EmbeddedCassandraServerHelper.CASSANDRA_RNDPORT_YML_FILE, 20000L); Properties prop = new Properties(); - prop.put("cassandra.port", EmbeddedCassandraServerHelper.getNativeTransportPort()); + prop.put("cassandra.port", String.valueOf(EmbeddedCassandraServerHelper.getNativeTransportPort())); prop.put("cassandra.servers.host.host", CASSANDRA_HOST); - Cluster cluster = Cluster.builder() + Cluster cluster = Cluster.builder() .withoutMetrics() .addContactPoint(CASSANDRA_HOST) .withPort(EmbeddedCassandraServerHelper.getNativeTransportPort()) @@ -89,7 +87,9 @@ private static Properties initCassandra() throws IOException { Session session = cluster.connect(); session.execute("CREATE KEYSPACE backend WITH REPLICATION = {'class' : 'SimpleStrategy', 'replication_factor' : 1};"); - session.execute("CREATE TABLE backend.backend (id ascii, user ascii, message ascii, completed Boolean, created timestamp, PRIMARY KEY (id));"); + session.execute( + "CREATE TABLE backend.backend (id ascii, user ascii, message ascii, completed Boolean, created timestamp, " + + "PRIMARY KEY (id));"); session.execute("select * from backend.backend;"); session.close(); @@ -99,81 +99,58 @@ private static Properties initCassandra() throws IOException { } @Test - void testTODOScenario() { - final String encodingID = Base64.getEncoder().encodeToString("john:password".getBytes()); + void testTodoScenario() { + String basicAuth = "Basic " + Base64.getEncoder().encodeToString("john:password".getBytes()); JsonObject todo = Json.createObjectBuilder() - .add("title", "todo title") + .add("title", "todo title") .build(); // Add a new todo - final JsonObject returnedTodo = client.post() + JsonObject returnedTodo = webTarget .path("/api/backend") - .headers(headers -> { - headers.add(Http.Header.AUTHORIZATION, "Basic " + encodingID); - return headers; - }) - .submit(todo, JsonObject.class) - .await(); + .request(MediaType.APPLICATION_JSON_TYPE) + .header(Http.Header.AUTHORIZATION, basicAuth) + .post(Entity.json(todo), JsonObject.class); - Assertions.assertEquals("john", returnedTodo.getString("user")); - Assertions.assertEquals(todo.getString("title"), returnedTodo.getString("title")); + assertEquals("john", returnedTodo.getString("user")); + assertEquals(todo.getString("title"), returnedTodo.getString("title")); // Get the todo created earlier - client.get() - .path("/api/backend/" + returnedTodo.getString("id")) - .headers(headers -> { - headers.add(Http.Header.AUTHORIZATION, "Basic " + encodingID); - return headers; - }) - .request(JsonObject.class) - .thenAccept(jsonObject -> { - Assertions.assertEquals(returnedTodo, jsonObject); - }) - .await(); + JsonObject fromServer = webTarget.path("/api/backend/" + returnedTodo.getString("id")) + .request(MediaType.APPLICATION_JSON_TYPE) + .header(Http.Header.AUTHORIZATION, basicAuth) + .get(JsonObject.class); + + assertEquals(returnedTodo, fromServer); // Update the todo created earlier - JsonObject updatedTODO = Json.createObjectBuilder() - .add("title", "updated title") + JsonObject updatedTodo = Json.createObjectBuilder() + .add("title", "updated title") .add("completed", false) .build(); - client.put() - .path("/api/backend/" + returnedTodo.getString("id")) - .headers(headers -> { - headers.add(Http.Header.AUTHORIZATION, "Basic " + encodingID); - return headers; - }) - .submit(updatedTODO, JsonObject.class) - .thenAccept(jsonObject -> { - Assertions.assertEquals(updatedTODO.getString("title"), jsonObject.getString("title")); - }) - .await(); + fromServer = webTarget.path("/api/backend/" + returnedTodo.getString("id")) + .request(MediaType.APPLICATION_JSON_TYPE) + .header(Http.Header.AUTHORIZATION, basicAuth) + .put(Entity.json(updatedTodo), JsonObject.class); + + assertEquals(updatedTodo.getString("title"), fromServer.getString("title")); // Delete the todo created earlier - client.delete() - .path("/api/backend/" + returnedTodo.getString("id")) - .headers(headers -> { - headers.add(Http.Header.AUTHORIZATION, "Basic " + encodingID); - return headers; - }) - .request(JsonObject.class) - .thenAccept(jsonObject -> { - Assertions.assertEquals(returnedTodo.getString("id"), jsonObject.getString("id")); - }) - .await(); + fromServer = webTarget.path("/api/backend/" + returnedTodo.getString("id")) + .request(MediaType.APPLICATION_JSON_TYPE) + .header(Http.Header.AUTHORIZATION, basicAuth) + .delete(JsonObject.class); + + assertEquals(returnedTodo.getString("id"), fromServer.getString("id")); // Get list of todos - client.get() - .path("/api/backend") - .headers(headers -> { - headers.add(Http.Header.AUTHORIZATION, "Basic " + encodingID); - return headers; - }) - .request(JsonArray.class) - .thenAccept(jsonValues -> { - Assertions.assertEquals(0, jsonValues.size()); - }) - .await(); + JsonArray jsonValues = webTarget.path("/api/backend") + .request(MediaType.APPLICATION_JSON_TYPE) + .header(Http.Header.AUTHORIZATION, basicAuth) + .get(JsonArray.class); + + assertEquals(0, jsonValues.size(), "There should be no todos on server"); } } diff --git a/examples/todo-app/backend/src/test/resources/test-application.yaml b/examples/todo-app/backend/src/test/resources/test-application.yaml index 7fb211f23e7..aa071626dd7 100644 --- a/examples/todo-app/backend/src/test/resources/test-application.yaml +++ b/examples/todo-app/backend/src/test/resources/test-application.yaml @@ -14,13 +14,22 @@ # limitations under the License. # +# increase importance +config_ordinal: 500 + +# we use custom config and Helidon JUnit integration, must allow initializer +mp: + initializer: + allow: true + no-warn: true + server: port: 0 - host: 0.0.0.0 + host: localhost tracing: service: "todo:back" - host: "zipkin" + enabled: false security: providers: From 3dc1206eacc75cf07453c2c3e7bc9541d4979a8c Mon Sep 17 00:00:00 2001 From: Tomas Langer Date: Thu, 7 Oct 2021 13:13:22 +0200 Subject: [PATCH 7/7] Fixed test to work with latest code Signed-off-by: Tomas Langer --- dependencies/pom.xml | 5 +++++ examples/todo-app/backend/pom.xml | 5 +++++ .../java/io/helidon/demo/todos/backend/BackendTests.java | 5 +++-- 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/dependencies/pom.xml b/dependencies/pom.xml index 7796a2493cd..0921656f7f3 100644 --- a/dependencies/pom.xml +++ b/dependencies/pom.xml @@ -1158,6 +1158,11 @@ logback-classic ${version.lib.logback} + + ch.qos.logback + logback-core + ${version.lib.logback} + org.apache.activemq activemq-client diff --git a/examples/todo-app/backend/pom.xml b/examples/todo-app/backend/pom.xml index 35cc9f53814..ca05f12a5e2 100644 --- a/examples/todo-app/backend/pom.xml +++ b/examples/todo-app/backend/pom.xml @@ -99,6 +99,11 @@ helidon-microprofile-tests-junit5 test + + io.helidon.config + helidon-config-mp + test + org.cassandraunit cassandra-unit diff --git a/examples/todo-app/backend/src/test/java/io/helidon/demo/todos/backend/BackendTests.java b/examples/todo-app/backend/src/test/java/io/helidon/demo/todos/backend/BackendTests.java index 765e49ab3b3..ca6aa8ac21b 100644 --- a/examples/todo-app/backend/src/test/java/io/helidon/demo/todos/backend/BackendTests.java +++ b/examples/todo-app/backend/src/test/java/io/helidon/demo/todos/backend/BackendTests.java @@ -30,7 +30,7 @@ import io.helidon.common.http.Http; import io.helidon.config.mp.MpConfigSources; -import io.helidon.config.yaml.YamlMpConfigSource; +import io.helidon.config.yaml.mp.YamlMpConfigSource; import io.helidon.microprofile.tests.junit5.Configuration; import io.helidon.microprofile.tests.junit5.HelidonTest; @@ -74,7 +74,8 @@ static void stopServer() { } private static Properties initCassandra() throws IOException { - EmbeddedCassandraServerHelper.startEmbeddedCassandra(EmbeddedCassandraServerHelper.CASSANDRA_RNDPORT_YML_FILE, 20000L); + EmbeddedCassandraServerHelper.startEmbeddedCassandra(EmbeddedCassandraServerHelper.CASSANDRA_RNDPORT_YML_FILE, + 20000L); Properties prop = new Properties(); prop.put("cassandra.port", String.valueOf(EmbeddedCassandraServerHelper.getNativeTransportPort())); prop.put("cassandra.servers.host.host", CASSANDRA_HOST);