Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/ISSUE_TEMPLATE/bug_report.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ body:
- Solace
- Solr
- TiDB
- Timeplus
- ToxiProxy
- Trino
- Vault
Expand Down
1 change: 1 addition & 0 deletions .github/ISSUE_TEMPLATE/enhancement.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ body:
- Solace
- Solr
- TiDB
- Timeplus
- ToxiProxy
- Trino
- Vault
Expand Down
1 change: 1 addition & 0 deletions .github/ISSUE_TEMPLATE/feature.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ body:
- Solace
- Solr
- TiDB
- Timeplus
- ToxiProxy
- Trino
- Vault
Expand Down
5 changes: 5 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -342,6 +342,11 @@ updates:
schedule:
interval: "weekly"
open-pull-requests-limit: 10
- package-ecosystem: "gradle"
directory: "/modules/timeplus"
schedule:
interval: "weekly"
open-pull-requests-limit: 10
- package-ecosystem: "gradle"
directory: "/modules/toxiproxy"
schedule:
Expand Down
4 changes: 4 additions & 0 deletions .github/labeler.yml
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,10 @@
- changed-files:
- any-glob-to-any-file:
- modules/tidb/**/*
"modules/timeplus":
- changed-files:
- any-glob-to-any-file:
- modules/timeplus/**/*
"modules/toxiproxy":
- changed-files:
- any-glob-to-any-file:
Expand Down
3 changes: 3 additions & 0 deletions .github/settings.yml
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,9 @@ labels:
- name: modules/tidb
color: '#006b75'

- name: modules/timeplus
color: '#006b75'

- name: modules/toxiproxy
color: '#006b75'

Expand Down
4 changes: 4 additions & 0 deletions docs/modules/databases/jdbc.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,10 @@ Insert `tc:` after `jdbc:` as follows. Note that the hostname, port and database

`jdbc:tc:tidb:v6.1.0:///databasename`

#### Using Timeplus

`jdbc:tc:timeplus:2.3.21:///databasename`

#### Using Trino

`jdbc:tc:trino:352://localhost/memory/default`
Expand Down
24 changes: 24 additions & 0 deletions docs/modules/databases/timeplus.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Timeplus Module

## Adding this module to your project dependencies

Add the following dependency to your `pom.xml`/`build.gradle` file:

=== "Gradle"
```groovy
testImplementation "org.testcontainers:timeplus:{{latest_version}}"
```

=== "Maven"
```xml
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>timeplus</artifactId>
<version>{{latest_version}}</version>
<scope>test</scope>
</dependency>
```

!!! hint
Adding this Testcontainers library JAR will not automatically add a database driver JAR to your project. You should ensure that your project also has a suitable database driver as a dependency.

1 change: 1 addition & 0 deletions mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ nav:
- modules/databases/presto.md
- modules/databases/questdb.md
- modules/databases/tidb.md
- modules/databases/timeplus.md
- modules/databases/trino.md
- modules/databases/yugabytedb.md
- modules/activemq.md
Expand Down
10 changes: 10 additions & 0 deletions modules/timeplus/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
description = "Testcontainers :: JDBC :: Timeplus"

dependencies {
api project(':testcontainers')
api project(':jdbc')

testImplementation project(':jdbc-test')
testRuntimeOnly 'com.timeplus:timeplus-native-jdbc:2.0.4'
testImplementation 'org.assertj:assertj-core:3.26.3'
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
package org.testcontainers.timeplus;

import org.testcontainers.containers.JdbcDatabaseContainer;
import org.testcontainers.containers.wait.strategy.Wait;
import org.testcontainers.utility.DockerImageName;

import java.time.Duration;
import java.util.HashSet;
import java.util.Set;

/**
* Testcontainers implementation for Timeplus.
* <p>
* Supported image: {@code timeplus/timeplusd}
* <p>
* Exposed ports:
* <ul>
* <li>Database: 8463</li>
* <li>HTTP: 3218</li>
* </ul>
*/
public class TimeplusContainer extends JdbcDatabaseContainer<TimeplusContainer> {
Comment thread
eddumelendez marked this conversation as resolved.

static final String NAME = "timeplus";

static final String DOCKER_IMAGE_NAME = "timeplus/timeplusd";

private static final DockerImageName TIMEPLUS_IMAGE_NAME = DockerImageName.parse(DOCKER_IMAGE_NAME);

private static final Integer HTTP_PORT = 3218;

private static final Integer NATIVE_PORT = 8463;

private static final String DRIVER_CLASS_NAME = "com.timeplus.jdbc.TimeplusDriver";

private static final String JDBC_URL_PREFIX = "jdbc:" + NAME + "://";

private static final String TEST_QUERY = "SELECT 1";

private String databaseName = "default";

private String username = "default";

private String password = "";

public TimeplusContainer(String dockerImageName) {
this(DockerImageName.parse(dockerImageName));
}

public TimeplusContainer(final DockerImageName dockerImageName) {
super(dockerImageName);
dockerImageName.assertCompatibleWith(TIMEPLUS_IMAGE_NAME);

addExposedPorts(HTTP_PORT, NATIVE_PORT);
waitingFor(Wait.forHttp("/timeplusd/v1/ping").forStatusCode(200).withStartupTimeout(Duration.ofMinutes(1)));
}

@Override
protected void configure() {
withEnv("TIMEPLUS_DB", this.databaseName);
withEnv("TIMEPLUS_USER", this.username);
withEnv("TIMEPLUS_PASSWORD", this.password);
}

@Override
public Set<Integer> getLivenessCheckPortNumbers() {
return new HashSet<>(getMappedPort(HTTP_PORT));
}

@Override
public String getDriverClassName() {
return DRIVER_CLASS_NAME;
}

@Override
public String getJdbcUrl() {
return (
JDBC_URL_PREFIX +
getHost() +
":" +
getMappedPort(NATIVE_PORT) +
"/" +
this.databaseName +
constructUrlParameters("?", "&")
);
}

@Override
public String getUsername() {
return this.username;
}

@Override
public String getPassword() {
return this.password;
}

@Override
public String getDatabaseName() {
return this.databaseName;
}

@Override
public String getTestQueryString() {
return TEST_QUERY;
}

@Override
public TimeplusContainer withUsername(String username) {
this.username = username;
return this;
}

@Override
public TimeplusContainer withPassword(String password) {
this.password = password;
return this;
}

@Override
public TimeplusContainer withDatabaseName(String databaseName) {
this.databaseName = databaseName;
return this;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package org.testcontainers.timeplus;

import org.testcontainers.containers.JdbcDatabaseContainer;
import org.testcontainers.containers.JdbcDatabaseContainerProvider;
import org.testcontainers.utility.DockerImageName;

/**
* Factory for Timeplus containers.
*/
public class TimeplusContainerProvider extends JdbcDatabaseContainerProvider {

private static final String DEFAULT_TAG = "2.3.21";

@Override
public boolean supports(String databaseType) {
return databaseType.equals(TimeplusContainer.NAME);
}

@Override
public JdbcDatabaseContainer newInstance() {
return newInstance(DEFAULT_TAG);
}

@Override
public JdbcDatabaseContainer newInstance(String tag) {
if (tag != null) {
return new TimeplusContainer(DockerImageName.parse(TimeplusContainer.DOCKER_IMAGE_NAME).withTag(tag));
} else {
return newInstance();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
org.testcontainers.timeplus.TimeplusContainerProvider
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package org.testcontainers;

import org.testcontainers.utility.DockerImageName;

public interface TimeplusImages {
DockerImageName TIMEPLUS_IMAGE = DockerImageName.parse("timeplus/timeplusd:2.3.21");
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package org.testcontainers.junit.timeplus;

import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.testcontainers.jdbc.AbstractJDBCDriverTest;

import java.util.Arrays;
import java.util.EnumSet;

@RunWith(Parameterized.class)
public class TimeplusJDBCDriverTest extends AbstractJDBCDriverTest {

@Parameterized.Parameters(name = "{index} - {0}")
public static Iterable<Object[]> data() {
return Arrays.asList(
new Object[][] { { "jdbc:tc:timeplus:2.3.21://hostname", EnumSet.noneOf(Options.class) } }
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package org.testcontainers.timeplus;

import org.junit.Test;
import org.testcontainers.TimeplusImages;
import org.testcontainers.db.AbstractContainerDatabaseTest;

import java.sql.ResultSet;
import java.sql.SQLException;

import static org.assertj.core.api.Assertions.assertThat;

public class TimeplusContainerTest extends AbstractContainerDatabaseTest {

@Test
public void testSimple() throws SQLException {
try (TimeplusContainer timeplus = new TimeplusContainer(TimeplusImages.TIMEPLUS_IMAGE)) {
timeplus.start();

ResultSet resultSet = performQuery(timeplus, "SELECT 1");

int resultSetInt = resultSet.getInt(1);
assertThat(resultSetInt).isEqualTo(1);
}
}

@Test
public void customCredentialsWithUrlParams() throws SQLException {
try (
TimeplusContainer timeplus = new TimeplusContainer(TimeplusImages.TIMEPLUS_IMAGE)
.withUsername("system")
.withPassword("sys@t+")
.withDatabaseName("system")
.withUrlParam("interactive_delay", "5")
) {
timeplus.start();

ResultSet resultSet = performQuery(
timeplus,
"SELECT to_int(value) FROM system.settings where name='interactive_delay'"
);

int resultSetInt = resultSet.getInt(1);
assertThat(resultSetInt).isEqualTo(5);
}
}
}
16 changes: 16 additions & 0 deletions modules/timeplus/src/test/resources/logback-test.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<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="INFO"/>
</configuration>