Skip to content

Commit

Permalink
Issue helidon-io#2279 - Fixed Mongo tests.
Browse files Browse the repository at this point in the history
Signed-off-by: Tomáš Kraus <[email protected]>
  • Loading branch information
Tomas-Kraus committed Aug 2, 2024
1 parent 5bf3dc0 commit 471d81a
Show file tree
Hide file tree
Showing 9 changed files with 146 additions and 87 deletions.
12 changes: 12 additions & 0 deletions dbclient/jdbc/etc/spotbugs/exclude.xml
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,16 @@
<Method name="prepareStatement"/>
<Bug pattern="SQL_INJECTION_JDBC"/>
</Match>
<Match>
<!-- Doesn't construct SQL string. It converts string to statement -->
<Class name="io.helidon.dbclient.jdbc.JdbcStatementDml"/>
<Method name="prepareStatement"/>
<Bug pattern="SQL_INJECTION_JDBC"/>
</Match>
<Match>
<!-- Doesn't construct SQL string. It converts string to statement -->
<Class name="io.helidon.dbclient.jdbc.JdbcTransactionStatementDml"/>
<Method name="prepareStatement"/>
<Bug pattern="SQL_INJECTION_JDBC"/>
</Match>
</FindBugsFilter>
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ public long execute() {
case INSERT -> executeInsert(stmt);
case UPDATE -> executeUpdate(stmt);
case DELETE -> executeDelete(stmt);
case DML -> executeDml(stmt);
default -> throw new UnsupportedOperationException(String.format(
"Statement operation not yet supported: %s",
type.name()));
Expand Down Expand Up @@ -103,6 +104,7 @@ public DbResultDml insert() {
case INSERT -> executeInsertAsDbResultDml(stmt);
case UPDATE -> executeUpdateAsDbResultDml(stmt);
case DELETE -> executeDeleteAsDbResultDml(stmt);
case DML -> executeDmlAsDbResultDml(stmt);
default -> throw new UnsupportedOperationException(String.format(
"Statement operation not yet supported: %s",
type.name()));
Expand Down Expand Up @@ -198,4 +200,28 @@ private DbResultDml executeDeleteAsDbResultDml(MongoStatement stmt) {
return DbResultDml.create(Stream.of(), executeDelete(stmt));
}

private Long executeDml(MongoStatement stmt) {
switch (stmt.getOperation()) {
case INSERT: return executeInsert(stmt);
case UPDATE: return executeUpdate(stmt);
case DELETE: return executeDelete(stmt);
case COMMAND:
default: throw new UnsupportedOperationException(String.format(
"Statement operation %s is not supported as DML",
stmt.getOperation()));
}
}

private DbResultDml executeDmlAsDbResultDml(MongoStatement stmt) {
switch (stmt.getOperation()) {
case INSERT: return executeInsertAsDbResultDml(stmt);
case UPDATE: return executeUpdateAsDbResultDml(stmt);
case DELETE: return executeDeleteAsDbResultDml(stmt);
case COMMAND:
default: throw new UnsupportedOperationException(String.format(
"Statement operation %s is not supported as DML",
stmt.getOperation()));
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,10 @@ public void testQueryMapParams() {

@Test
public void testQueryMapMissingParams() {
// Not supported in Mongo (current parameters parser does not allow to implement this feature)
if (dbClient.dbType().equals("mongoDb")) {
return;
}
Map<String, Integer> params = new HashMap<>(2);
params.put("id", 1);
Stream<DbRow> rows = dbClient.execute()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,13 @@ void testInsertNamedArgsReturnedKeys() throws Exception {
AtomicInteger columnsCount = new AtomicInteger(0);
keysRow.forEach(dbColumn -> columnsCount.incrementAndGet());
assertThat(columnsCount.get(), equalTo(1));
DbColumn keyByName = keysRow.column("id");
DbColumn keyByName;
// Mongo will always return just new _id value
if (dbClient.dbType().equals("mongoDb")) {
keyByName = keysRow.column("_id");
} else {
keyByName = keysRow.column("id");
}
DbColumn keyByIndex = keysRow.column(1);
assertThat(keyByName, equalTo(keyByIndex));
}
Expand All @@ -173,6 +179,10 @@ void testInsertNamedArgsReturnedKeys() throws Exception {
*/
@Test
void testInsertNamedArgsReturnedColumns() throws Exception {
// Not supported in Mongo
if (dbClient.dbType().equals("mongoDb")) {
return;
}
try (DbResultDml result = dbClient.execute().createNamedInsert("insert-match")
.addParam("red", Pokemon.POKEMONS.get(4).getId())
.addParam("blue", Pokemon.POKEMONS.get(5).getId())
Expand Down
31 changes: 16 additions & 15 deletions tests/integration/dbclient/mongodb/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -44,37 +44,31 @@
<groupId>io.helidon.tests.integration.dbclient</groupId>
<artifactId>helidon-tests-integration-dbclient-common</artifactId>
<version>${project.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.helidon.config</groupId>
<artifactId>helidon-config</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.helidon.config</groupId>
<artifactId>helidon-config-yaml</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.helidon.dbclient</groupId>
<artifactId>helidon-dbclient-mongodb</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.helidon.tests.integration</groupId>
<artifactId>helidon-tests-integration-harness</artifactId>
<version>${project.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-all</artifactId>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
Expand Down Expand Up @@ -106,6 +100,18 @@
<systemPropertyVariables>
<junit.jupiter.extensions.autodetection.enabled>true</junit.jupiter.extensions.autodetection.enabled>
</systemPropertyVariables>
<dependenciesToScan>
<dependency>io.helidon.tests.integration.dbclient:helidon-tests-integration-dbclient-common</dependency>
</dependenciesToScan>
<includes>
<include>io.helidon.tests.integration.dbclient.common.tests.*IT</include>
</includes>
<excludes>
<!-- Transactions are not implemented -->
<exclude>io.helidon.tests.integration.dbclient.common.tests.Transaction*IT</exclude>
<!-- Metrics are broken -->
<exclude>io.helidon.tests.integration.dbclient.common.tests.ServerMetricsCheckIT</exclude>
</excludes>
</configuration>
<executions>
<execution>
Expand All @@ -115,11 +121,6 @@
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
<configuration>
<includes>
<include>**/*SuiteIT</include>
</includes>
</configuration>
</execution>
</executions>
</plugin>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2023 Oracle and/or its affiliates.
* Copyright (c) 2023, 2024 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.
Expand Down Expand Up @@ -28,16 +28,9 @@
import io.helidon.dbclient.DbRow;
import io.helidon.tests.integration.dbclient.common.model.Pokemon;
import io.helidon.tests.integration.dbclient.common.model.Type;
import io.helidon.tests.integration.dbclient.common.utils.TestConfig;
import io.helidon.tests.integration.dbclient.common.spi.SetupProvider;
import io.helidon.tests.integration.dbclient.common.tests.MapperIT;

import io.helidon.tests.integration.harness.AfterSuite;
import io.helidon.tests.integration.harness.BeforeSuite;
import org.junit.platform.suite.api.ExcludeClassNamePatterns;
import org.junit.platform.suite.api.IncludeClassNamePatterns;
import org.junit.platform.suite.api.SelectPackages;
import org.junit.platform.suite.api.Suite;

import static io.helidon.tests.integration.dbclient.common.model.Pokemon.POKEMONS;
import static io.helidon.tests.integration.dbclient.common.model.Type.TYPES;
import static org.hamcrest.MatcherAssert.assertThat;
Expand All @@ -47,53 +40,52 @@
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.not;

/*
docker run -it --name MongoDb -p 27017:27017 \
-e MONGO_INITDB_ROOT_USERNAME='root' -e MONGO_INITDB_ROOT_PASSWORD='I4mGr00t' mongo:latest
*/
/**
* Test Database Client MongoDB.
*/
@Suite
@SelectPackages("io.helidon.tests.integration.dbclient.common.tests")
@ExcludeClassNamePatterns(".*Transaction.*")
@IncludeClassNamePatterns(".*IT")
class MongoDBSuiteIT {
public class MongoDBSuiteIT implements SetupProvider {

private static final System.Logger LOGGER = System.getLogger(MapperIT.class.getName());
private static final int TIMEOUT = 60;
private static final Config CONFIG = initConfig();

@BeforeSuite
static Map<String, Object> setup() {
Config config = Config.create(ConfigSources.classpath(TestConfig.configFile()));
DbClient dbClient = DbClient.builder(config.get("db")).build();
static {
DbClient dbClient = DbClient.builder(CONFIG.get("db")).build();
waitForStart(dbClient);
ping(dbClient);
initSchema(dbClient);
deleteSchema(dbClient);
initData(dbClient);
testListTypes(dbClient);
testListPokemons(dbClient);
testListPokemonTypes(dbClient);
return Map.of("dbClient", dbClient);
}

@AfterSuite
static void tearDown(DbClient dbClient) {
deleteSchema(dbClient);
testDeletedSchema(dbClient);
private static Config initConfig() {
return Config.create(ConfigSources.classpath("mongo.yaml"));
}

@Override
public Config config() {
return CONFIG;
}

@Override
public DbClient dbClient() {
return DbClient.builder(CONFIG.get("db")).build();
}

private static void ping(DbClient dbClient) {
DbExecute exec = dbClient.execute();
DbRow row = exec.namedQuery("ping-query").findFirst().orElseThrow();
Double ok = row.column("ok").as(Double.class);
Double ok = row.column("ok").as(Double.class).get();
assertThat(ok, equalTo(1.0));
LOGGER.log(System.Logger.Level.DEBUG, () -> String.format("Command ping row: %s", row));
}

private static void initSchema(DbClient dbClient) {
DbExecute exec = dbClient.execute();
exec.namedDml("create-types");
exec.namedDml("create-pokemons");
exec.namedDml("create-poketypes");
}

private static void initData(DbClient dbClient) {
DbExecute exec = dbClient.execute();
long count = 0;
Expand Down Expand Up @@ -122,8 +114,8 @@ private static void testListTypes(DbClient dbClient) {

Set<Integer> ids = new HashSet<>(TYPES.keySet());
for (DbRow row : rows) {
Integer id = row.column(1).as(Integer.class);
String name = row.column(2).as(String.class);
Integer id = row.column(1).as(Integer.class).get();
String name = row.column(2).as(String.class).get();
assertThat(ids, hasItem(id));
assertThat(name, TYPES.get(id).name().equals(name));
}
Expand All @@ -137,8 +129,8 @@ private static void testListPokemons(DbClient dbClient) {

Set<Integer> ids = new HashSet<>(POKEMONS.keySet());
for (DbRow row : rowsList) {
Integer id = row.column(1).as(Integer.class);
String name = row.column(2).as(String.class);
Integer id = row.column(1).as(Integer.class).get();
String name = row.column(2).as(String.class).get();
assertThat(ids, hasItem(id));
assertThat(name, POKEMONS.get(id).getName().equals(name));
}
Expand All @@ -151,16 +143,16 @@ private static void testListPokemonTypes(DbClient dbClient) {
assertThat(rows, not(empty()));

for (DbRow row : rows) {
Integer pokemonId = row.column(1).as(Integer.class);
String pokemonName = row.column(2).as(String.class);
Integer pokemonId = row.column(1).as(Integer.class).get();
String pokemonName = row.column(2).as(String.class).get();
Pokemon pokemon = POKEMONS.get(pokemonId);
assertThat(pokemonName, POKEMONS.get(pokemonId).getName().equals(pokemonName));
Stream<DbRow> typeRows = exec.namedQuery("select-poketypes", pokemonId);

List<DbRow> typeRowsList = typeRows.toList();
assertThat(typeRowsList.size(), equalTo(pokemon.getTypes().size()));
for (DbRow typeRow : typeRowsList) {
Integer typeId = typeRow.column(2).as(Integer.class);
Integer typeId = typeRow.column(2).as(Integer.class).get();
assertThat(pokemon.getTypes(), hasItem(TYPES.get(typeId)));
}
}
Expand All @@ -185,7 +177,7 @@ private static void waitForStart(DbClient dbClient) {
long endTm = 1000 * TIMEOUT + System.currentTimeMillis();
while (true) {
try {
dbClient.execute().namedGet("ping");
dbClient.execute().namedGet("ping-query");
break;
} catch (Throwable th) {
if (System.currentTimeMillis() > endTm) {
Expand Down
33 changes: 33 additions & 0 deletions tests/integration/dbclient/mongodb/src/main/java/module-info.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/*
* Copyright (c) 2024 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.
* 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.
*/

/**
* Helidon Database Client Integration Tests with Mongo Database.
*/
module io.helidon.tests.integration.dbclient.mongodb {

requires io.helidon.config;
requires io.helidon.dbclient;
requires io.helidon.tests.integration.dbclient.common;
requires io.helidon.tests.integration.harness;

requires hamcrest.all;
requires org.mongodb.driver.sync.client;

provides io.helidon.tests.integration.dbclient.common.spi.SetupProvider
with io.helidon.tests.integration.dbclient.mongodb.MongoDBSuiteIT;

}
Loading

0 comments on commit 471d81a

Please sign in to comment.