-
-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Co-authored-by: Richard North <rich.north@gmail.com> Co-authored-by: Sergei Egorov <bsideup@gmail.com>
- Loading branch information
1 parent
d4d9bea
commit 7cb8ef5
Showing
6 changed files
with
339 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
# OrientDB Module | ||
|
||
!!! note | ||
This module is INCUBATING. While it is ready for use and operational in the current version of Testcontainers, it is possible that it may receive breaking changes in the future. See [our contributing guidelines](/contributing/#incubating-modules) for more information on our incubating modules policy. | ||
|
||
|
||
This module helps running [OrientDB](https://orientdb.org/download) using Testcontainers. | ||
|
||
Note that it's based on the [official Docker image](https://hub.docker.com/_/orientdb/) provided by OrientDB. | ||
|
||
## Usage example | ||
|
||
Declare your Testcontainer as a `@ClassRule` or `@Rule` in a JUnit 4 test or as static or member attribute of a JUnit 5 test annotated with `@Container` as you would with other Testcontainers. | ||
You can call `getDbUrl()` OrientDB container and build the `ODatabaseSession` by your own, but a more useful `getSession()` method is provided. | ||
On the JVM you would most likely use the [Java driver](https://github.com/). | ||
|
||
The following example uses the JUnit 5 extension `@Testcontainers` and demonstrates both the usage of the Java Client: | ||
|
||
```java tab="JUnit 5 example" | ||
@Testcontainers | ||
public class ExampleTest { | ||
|
||
@Container | ||
private static OrientDBContainer container = new OrientDBContainer(); | ||
|
||
@Test | ||
void testDbCreation() { | ||
|
||
final ODatabaseSession session = container.getSession(); | ||
|
||
session.command("CREATE CLASS Person EXTENDS V"); | ||
session.command("INSERT INTO Person set name='john'"); | ||
session.command("INSERT INTO Person set name='jane'"); | ||
|
||
assertThat(session.query("SELECT FROM Person").stream()).hasSize(2); | ||
} | ||
|
||
} | ||
``` | ||
|
||
You are not limited to Unit tests and can of course use an instance of the OrientDB Testcontainer in vanilla Java code as well. | ||
|
||
|
||
## Adding this module to your project dependencies | ||
|
||
Add the following dependency to your `pom.xml`/`build.gradle` file: | ||
|
||
```groovy tab='Gradle' | ||
testCompile "org.testcontainers:orientdb:{{latest_version}}" | ||
``` | ||
|
||
```xml tab='Maven' | ||
<dependency> | ||
<groupId>org.testcontainers</groupId> | ||
<artifactId>orientdb</artifactId> | ||
<version>{{latest_version}}</version> | ||
<scope>test</scope> | ||
</dependency> | ||
``` | ||
|
||
!!! hint | ||
Add the OrientDB Java client if you plan to access the Testcontainer: | ||
|
||
```groovy tab='Gradle' | ||
compile "com.orientechnologies:orientdb-client:3.0.24" | ||
``` | ||
|
||
```xml tab='Maven' | ||
<dependency> | ||
<groupId>com.orientechnologies</groupId> | ||
<artifactId>orientdb-client</artifactId> | ||
<version>3.0.24</version> | ||
</dependency> | ||
``` | ||
|
||
|
||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
description = "TestContainers :: Orientdb" | ||
|
||
dependencies { | ||
compile project(":testcontainers") | ||
|
||
compile "com.orientechnologies:orientdb-client:3.0.24" | ||
|
||
testCompile 'org.assertj:assertj-core:3.12.0' | ||
testCompile 'org.apache.tinkerpop:gremlin-driver:3.3.4' | ||
testCompile "com.orientechnologies:orientdb-gremlin:3.0.18" | ||
} |
153 changes: 153 additions & 0 deletions
153
modules/orientdb/src/main/java/org/testcontainers/containers/OrientDBContainer.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,153 @@ | ||
package org.testcontainers.containers; | ||
|
||
import com.github.dockerjava.api.command.InspectContainerResponse; | ||
import com.orientechnologies.orient.core.db.ODatabaseSession; | ||
import com.orientechnologies.orient.core.db.ODatabaseType; | ||
import com.orientechnologies.orient.core.db.OrientDB; | ||
import com.orientechnologies.orient.core.db.OrientDBConfig; | ||
import lombok.NonNull; | ||
import org.apache.commons.io.IOUtils; | ||
import org.slf4j.Logger; | ||
import org.slf4j.LoggerFactory; | ||
import org.testcontainers.containers.wait.strategy.HttpWaitStrategy; | ||
import org.testcontainers.containers.wait.strategy.Wait; | ||
import org.testcontainers.containers.wait.strategy.WaitAllStrategy; | ||
import org.testcontainers.containers.wait.strategy.WaitStrategy; | ||
|
||
import java.io.IOException; | ||
import java.net.URL; | ||
import java.nio.charset.StandardCharsets; | ||
import java.time.Duration; | ||
import java.util.Optional; | ||
|
||
import static java.net.HttpURLConnection.HTTP_OK; | ||
|
||
/** | ||
* @author robfrank | ||
*/ | ||
public class OrientDBContainer extends GenericContainer<OrientDBContainer> { | ||
private static final Logger LOGGER = LoggerFactory.getLogger(OrientDBContainer.class); | ||
|
||
private static final String DEFAULT_IMAGE_NAME = "orientdb"; | ||
private static final String DEFAULT_TAG = "3.0.24-tp3"; | ||
private static final String DOCKER_IMAGE_NAME = DEFAULT_IMAGE_NAME + ":" + DEFAULT_TAG; | ||
|
||
private static final String DEFAULT_USERNAME = "admin"; | ||
private static final String DEFAULT_PASSWORD = "admin"; | ||
private static final String DEFAULT_SERVER_PASSWORD = "root"; | ||
|
||
private static final String DEFAULT_DATABASE_NAME = "testcontainers"; | ||
|
||
private static final int DEFAULT_BINARY_PORT = 2424; | ||
private static final int DEFAULT_HTTP_PORT = 2480; | ||
|
||
private String databaseName; | ||
private String serverPassword; | ||
private Optional<String> scriptPath = Optional.empty(); | ||
|
||
private OrientDB orientDB; | ||
private ODatabaseSession session; | ||
|
||
public OrientDBContainer() { | ||
this(DOCKER_IMAGE_NAME); | ||
} | ||
|
||
public OrientDBContainer(@NonNull String dockerImageName) { | ||
super(dockerImageName); | ||
|
||
serverPassword = DEFAULT_SERVER_PASSWORD; | ||
databaseName = DEFAULT_DATABASE_NAME; | ||
|
||
WaitStrategy waitForHttp = new HttpWaitStrategy() | ||
.forPort(DEFAULT_HTTP_PORT) | ||
.forStatusCodeMatching(response -> response == HTTP_OK); | ||
|
||
waitStrategy = new WaitAllStrategy() | ||
.withStrategy(Wait.forListeningPort()) | ||
.withStrategy(waitForHttp) | ||
.withStartupTimeout(Duration.ofMinutes(2)); | ||
} | ||
|
||
@Override | ||
protected void configure() { | ||
addExposedPorts(DEFAULT_BINARY_PORT, DEFAULT_HTTP_PORT); | ||
addEnv("ORIENTDB_ROOT_PASSWORD", serverPassword); | ||
} | ||
|
||
public String getDatabaseName() { | ||
return databaseName; | ||
} | ||
|
||
public String getTestQueryString() { | ||
return "SELECT FROM V"; | ||
} | ||
|
||
public OrientDBContainer withDatabaseName(final String databaseName) { | ||
this.databaseName = databaseName; | ||
return self(); | ||
} | ||
|
||
public OrientDBContainer withServerPassword(final String serverPassword) { | ||
this.serverPassword = serverPassword; | ||
return self(); | ||
} | ||
|
||
public OrientDBContainer withScriptPath(String scriptPath) { | ||
this.scriptPath = Optional.of(scriptPath); | ||
return self(); | ||
} | ||
|
||
@Override | ||
protected void containerIsStarted(InspectContainerResponse containerInfo) { | ||
orientDB = new OrientDB(getServerUrl(), "root", serverPassword, OrientDBConfig.defaultConfig()); | ||
} | ||
|
||
public OrientDB getOrientDB() { | ||
return orientDB; | ||
} | ||
|
||
public String getServerUrl() { | ||
return "remote:" + getContainerIpAddress() + ":" + getMappedPort(2424); | ||
} | ||
|
||
public String getDbUrl() { | ||
return getServerUrl() + "/" + databaseName; | ||
} | ||
|
||
public ODatabaseSession getSession() { | ||
return getSession(DEFAULT_USERNAME, DEFAULT_PASSWORD); | ||
} | ||
|
||
public synchronized ODatabaseSession getSession(String username, String password) { | ||
orientDB.createIfNotExists(databaseName, ODatabaseType.PLOCAL); | ||
|
||
if (session == null) { | ||
session = orientDB.open(databaseName, username, password); | ||
|
||
scriptPath.ifPresent(path -> loadScript(path, session)); | ||
} | ||
return session; | ||
} | ||
|
||
private void loadScript(String path, ODatabaseSession session) { | ||
try { | ||
URL resource = getClass().getClassLoader().getResource(path); | ||
|
||
if (resource == null) { | ||
LOGGER.warn("Could not load classpath init script: {}", scriptPath); | ||
throw new RuntimeException("Could not load classpath init script: " + scriptPath + ". Resource not found."); | ||
} | ||
|
||
String script = IOUtils.toString(resource, StandardCharsets.UTF_8); | ||
|
||
session.execute("sql", script); | ||
} catch (IOException e) { | ||
LOGGER.warn("Could not load classpath init script: {}", scriptPath); | ||
throw new RuntimeException("Could not load classpath init script: " + scriptPath, e); | ||
} catch (UnsupportedOperationException e) { | ||
LOGGER.error("Error while executing init script: {}", scriptPath, e); | ||
throw new RuntimeException("Error while executing init script: " + scriptPath, e); | ||
} | ||
} | ||
|
||
} |
73 changes: 73 additions & 0 deletions
73
modules/orientdb/src/test/java/org/testcontainers/containers/OrientDBContainerTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
package org.testcontainers.containers; | ||
|
||
import com.orientechnologies.orient.core.db.ODatabaseSession; | ||
import org.junit.Test; | ||
|
||
import static org.assertj.core.api.Assertions.*; | ||
|
||
/** | ||
* @author robfrank | ||
*/ | ||
public class OrientDBContainerTest { | ||
|
||
@Test | ||
public void shouldReturnTheSameSession() { | ||
try (OrientDBContainer container = new OrientDBContainer()) { | ||
container.start(); | ||
|
||
final ODatabaseSession session = container.getSession(); | ||
final ODatabaseSession session2 = container.getSession(); | ||
|
||
assertThat(session).isSameAs(session2); | ||
} | ||
} | ||
|
||
@Test | ||
public void shouldInitializeWithCommands() { | ||
try (OrientDBContainer container = new OrientDBContainer()) { | ||
container.start(); | ||
|
||
final ODatabaseSession session = container.getSession(); | ||
|
||
session.command("CREATE CLASS Person EXTENDS V"); | ||
session.command("INSERT INTO Person set name='john'"); | ||
session.command("INSERT INTO Person set name='jane'"); | ||
|
||
assertThat(session.query("SELECT FROM Person").stream()).hasSize(2); | ||
} | ||
} | ||
|
||
@Test | ||
public void shouldQueryWithGremlin() { | ||
|
||
try (OrientDBContainer container = new OrientDBContainer()) { | ||
container.start(); | ||
|
||
final ODatabaseSession session = container.getSession("admin", "admin"); | ||
|
||
session.command("CREATE CLASS Person EXTENDS V"); | ||
session.command("INSERT INTO Person set name='john'"); | ||
session.command("INSERT INTO Person set name='jane'"); | ||
|
||
assertThat(session.execute("gremlin", | ||
"g.V().hasLabel('Person')").stream()).hasSize(2); | ||
} | ||
} | ||
|
||
@Test | ||
public void shouldInitializeDatabaseFromScript() { | ||
try (OrientDBContainer container = new OrientDBContainer() | ||
.withScriptPath("initscript.osql") | ||
.withDatabaseName("persons")) { | ||
|
||
container.start(); | ||
|
||
assertThat(container.getDbUrl()) | ||
.isEqualTo("remote:" + container.getContainerIpAddress() + ":" + container.getMappedPort(2424) + "/persons"); | ||
|
||
final ODatabaseSession session = container.getSession(); | ||
|
||
assertThat(session.query("SELECT FROM Person").stream()).hasSize(4); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
CREATE CLASS Person EXTENDS V; | ||
|
||
INSERT INTO Person set name="john"; | ||
INSERT INTO Person set name="paul"; | ||
INSERT INTO Person set name="luke"; | ||
INSERT INTO Person set name="albert"; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
<configuration> | ||
|
||
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> | ||
<!-- encoders are assigned the type | ||
ch.qos.logback.classic.encoder.PatternLayoutEncoder by default --> | ||
<encoder> | ||
<pattern>%d{HH:mm:ss.SSS} %-5level %logger - %msg%n</pattern> | ||
</encoder> | ||
</appender> | ||
|
||
<root level="INFO"> | ||
<appender-ref ref="STDOUT"/> | ||
</root> | ||
|
||
<logger name="org.testcontainers" level="DEBUG"/> | ||
<logger name="org.testcontainers.shaded" level="WARN"/> | ||
|
||
</configuration> |