mirror of
https://github.com/ebean-orm/ebean.git
synced 2024-04-21 10:51:47 +00:00
#2068 - Add ebean-test as module
This commit is contained in:
@@ -0,0 +1,128 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<artifactId>ebean-parent</artifactId>
|
||||
<groupId>io.ebean</groupId>
|
||||
<version>12.4.3-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>ebean-test</artifactId>
|
||||
|
||||
<dependencies>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-api</artifactId>
|
||||
<version>1.7.25</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean</groupId>
|
||||
<artifactId>ebean</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.ebean.test</groupId>
|
||||
<artifactId>ebean-test-docker</artifactId>
|
||||
<version>3.1.5</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.assertj</groupId>
|
||||
<artifactId>assertj-core</artifactId>
|
||||
<version>3.14.0</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Including JAXB for DB Migration generation with Java 11+ -->
|
||||
<dependency>
|
||||
<groupId>org.glassfish.jaxb</groupId>
|
||||
<artifactId>jaxb-runtime</artifactId>
|
||||
<version>2.3.2</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Not strictly required but bring in H2 Driver because we use it so much -->
|
||||
<dependency>
|
||||
<groupId>com.h2database</groupId>
|
||||
<artifactId>h2</artifactId>
|
||||
<version>1.4.200</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.postgresql</groupId>
|
||||
<artifactId>postgresql</artifactId>
|
||||
<version>42.2.12</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- Test dependencies -->
|
||||
|
||||
<dependency>
|
||||
<groupId>com.microsoft.sqlserver</groupId>
|
||||
<artifactId>mssql-jdbc</artifactId>
|
||||
<version>6.2.2.jre8</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>mysql</groupId>
|
||||
<artifactId>mysql-connector-java</artifactId>
|
||||
<version>8.0.16</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.mariadb.jdbc</groupId>
|
||||
<artifactId>mariadb-java-client</artifactId>
|
||||
<version>2.6.0</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.sap.cloud.db.jdbc</groupId>
|
||||
<artifactId>ngdbc</artifactId>
|
||||
<version>2.3.48</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>ch.qos.logback</groupId>
|
||||
<artifactId>logback-classic</artifactId>
|
||||
<version>1.2.3</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>4.12</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
|
||||
<plugin>
|
||||
<groupId>io.repaint.maven</groupId>
|
||||
<artifactId>tiles-maven-plugin</artifactId>
|
||||
<version>2.17</version>
|
||||
<extensions>true</extensions>
|
||||
<configuration>
|
||||
<tiles>
|
||||
<tile>io.ebean.tile:enhancement:12.4.2</tile>
|
||||
</tiles>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,64 @@
|
||||
package io.ebean.test;
|
||||
|
||||
import io.ebeaninternal.api.SpiLogger;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Capture the log messages (executed SQL) for testing.
|
||||
*/
|
||||
class CaptureLogger implements SpiLogger {
|
||||
|
||||
private final SpiLogger wrapped;
|
||||
|
||||
private List<String> messages = new ArrayList<>();
|
||||
|
||||
private boolean active;
|
||||
|
||||
CaptureLogger(SpiLogger wrapped) {
|
||||
this.wrapped = wrapped;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDebug() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isTrace() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void debug(String msg) {
|
||||
if (active) {
|
||||
messages.add(msg);
|
||||
}
|
||||
wrapped.debug(msg);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void trace(String msg) {
|
||||
if (active) {
|
||||
messages.add(msg);
|
||||
}
|
||||
wrapped.trace(msg);
|
||||
}
|
||||
|
||||
List<String> start() {
|
||||
this.active = true;
|
||||
return collect();
|
||||
}
|
||||
|
||||
List<String> stop() {
|
||||
this.active = false;
|
||||
return collect();
|
||||
}
|
||||
|
||||
List<String> collect() {
|
||||
List<String> response = messages;
|
||||
messages = new ArrayList<>();
|
||||
return response;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package io.ebean.test;
|
||||
|
||||
import io.ebeaninternal.api.SpiLogger;
|
||||
import io.ebeaninternal.api.SpiLoggerFactory;
|
||||
import io.ebeaninternal.server.logger.DSpiLogger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* Create a logger that captures the SQL and register it for later access in tests.
|
||||
* <p>
|
||||
* The logged SQL is accessed by LoggedSql.
|
||||
* </p>
|
||||
*/
|
||||
public class CapturingLoggerFactory implements SpiLoggerFactory {
|
||||
|
||||
@Override
|
||||
public SpiLogger create(String name) {
|
||||
|
||||
DSpiLogger logger = new DSpiLogger(LoggerFactory.getLogger(name));
|
||||
if (name.equals("io.ebean.SQL")) {
|
||||
return LoggedSql.register(logger);
|
||||
}
|
||||
return logger;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,110 @@
|
||||
package io.ebean.test;
|
||||
|
||||
import io.ebean.DB;
|
||||
import io.ebean.migration.util.IOUtils;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Helper for testing to assert that the JSON form of an entity
|
||||
* or list of entities match a String / typically test resource.
|
||||
*
|
||||
* <pre>{@code
|
||||
*
|
||||
* DbJson.of(timedEntries)
|
||||
* .replace("id", "eventTime")
|
||||
* .assertContentMatches("/assertJson/full-1-timed.json");
|
||||
*
|
||||
* }</pre>
|
||||
*/
|
||||
public class DbJson {
|
||||
|
||||
/**
|
||||
* Create a PrettyJson object that has the JSON form of the
|
||||
* entity bean or beans.
|
||||
*
|
||||
* <pre>{@code
|
||||
*
|
||||
* DbJson.of(timedEntries)
|
||||
* .replace("id", "eventTime")
|
||||
* .assertContentMatches("/assertJson/full-1-timed.json");
|
||||
*
|
||||
* }</pre>
|
||||
*/
|
||||
public static PrettyJson of(Object bean) {
|
||||
return new PrettyJson(DB.json().toJsonPretty(bean));
|
||||
}
|
||||
|
||||
/**
|
||||
* Read the content for the given resource path.
|
||||
*/
|
||||
public static String readResource(String resourcePath) {
|
||||
InputStream is = DbJson.class.getResourceAsStream(resourcePath);
|
||||
try {
|
||||
return IOUtils.readUtf8(is).trim();
|
||||
} catch (IOException e) {
|
||||
throw new IllegalArgumentException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Contains the JSON of beans(s).
|
||||
*/
|
||||
public static class PrettyJson {
|
||||
|
||||
private String placeHolder = "\"*\"";
|
||||
private String rawJson;
|
||||
|
||||
PrettyJson(String rawJson) {
|
||||
this.rawJson = rawJson;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the placeHolder to use when replacing property values.
|
||||
*/
|
||||
public PrettyJson withPlaceholder(String placeHolder) {
|
||||
this.placeHolder = placeHolder;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace the values of the given properties with a placeholder value.
|
||||
* <p>
|
||||
* Typically we do this on generated properties such as id and timestamp properties.
|
||||
* </p>
|
||||
*/
|
||||
public PrettyJson replace(String... propertyNames) {
|
||||
for (String propertyName : propertyNames) {
|
||||
String placeholder = "\"" + propertyName + "\": " + placeHolder;
|
||||
rawJson = rawJson.replaceAll("\"" + propertyName + "\": (\\d+)", placeholder);
|
||||
rawJson = rawJson.replaceAll("\"" + propertyName + "\": \"(.*?)\"", placeholder);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the JSON content.
|
||||
*/
|
||||
public String asJson() {
|
||||
return rawJson;
|
||||
}
|
||||
|
||||
/**
|
||||
* Assert the json matches the content at the given resource path.
|
||||
*
|
||||
* <pre>{@code
|
||||
*
|
||||
* DbJson.of(timedEntries)
|
||||
* .replace("id", "eventTime")
|
||||
* .assertContentMatches("/assertJson/full-1-timed.json");
|
||||
*
|
||||
* }</pre>
|
||||
*/
|
||||
public void assertContentMatches(String resourcePath) {
|
||||
assertThat(rawJson).isEqualTo(readResource(resourcePath));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,115 @@
|
||||
package io.ebean.test;
|
||||
|
||||
import io.ebean.DB;
|
||||
import io.ebean.Transaction;
|
||||
import io.ebeaninternal.api.HelpScopeTrans;
|
||||
|
||||
/**
|
||||
* Helper methods for testing.
|
||||
*/
|
||||
public class ForTests {
|
||||
|
||||
/**
|
||||
* Enable or disable <code>@Transactional</code> methods.
|
||||
* <p>
|
||||
* This is intended for testing purposes such that tests
|
||||
* on code with {@code @Transactional} methods don't actually
|
||||
* start or complete transactions.
|
||||
* </p>
|
||||
*
|
||||
* @param enable Set false to disable {@code @Transactional} methods
|
||||
*/
|
||||
public static void enableTransactional(boolean enable) {
|
||||
HelpScopeTrans.setEnabled(enable);
|
||||
}
|
||||
|
||||
/**
|
||||
* Run the closure with <code>@Transactional</code> methods
|
||||
* effectively disabled (they won't create/commit transactions).
|
||||
*/
|
||||
public static void noTransactional(Runnable run) {
|
||||
try {
|
||||
enableTransactional(false);
|
||||
run.run();
|
||||
} finally {
|
||||
enableTransactional(true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* All transactions started in the closure are effectively rolled back.
|
||||
* <p>
|
||||
* This creates a wrapping transaction that uses {@link Transaction#setNestedUseSavepoint()}.
|
||||
* All nested transactions are created as savepoints. On completion the wrapping
|
||||
* transaction is rolled back.
|
||||
* </p>
|
||||
*
|
||||
* @param run Closure that runs such that all the transactions are rolled back.
|
||||
*/
|
||||
public static void rollbackAll(Runnable run) {
|
||||
|
||||
try (Transaction transaction = DB.beginTransaction()) {
|
||||
transaction.setNestedUseSavepoint();
|
||||
run.run();
|
||||
|
||||
transaction.rollback();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create and return a RollbackAll which should be closed at the end of the test(s).
|
||||
* <p>
|
||||
* In tests for <code>@Before</code> we create the rollbackAll and on
|
||||
* <code>@After</code> we <code>close()</code> it effectively rolling
|
||||
* back all changes made during test execution.
|
||||
* </p>
|
||||
*
|
||||
* <pre>{@code
|
||||
*
|
||||
* private ForTests.RollbackAll rollbackAll;
|
||||
*
|
||||
* @Before
|
||||
* public void before() {
|
||||
* rollbackAll = ForTests.createRollbackAll();
|
||||
* }
|
||||
*
|
||||
* @After
|
||||
* public void after() {
|
||||
* rollbackAll.close();
|
||||
* }
|
||||
*
|
||||
* ... tests execute and everything is rolled back
|
||||
*
|
||||
*
|
||||
* }</pre>
|
||||
*/
|
||||
public static RollbackAll createRollbackAll() {
|
||||
|
||||
final Transaction transaction = DB.beginTransaction();
|
||||
transaction.setNestedUseSavepoint();
|
||||
return new RollbackAll(transaction);
|
||||
}
|
||||
|
||||
/**
|
||||
* A wrapping transaction used in test code to rollback all changes.
|
||||
* <p>
|
||||
* We must ensure that <code>close()</code> is called.
|
||||
* </p>
|
||||
*/
|
||||
public static class RollbackAll implements AutoCloseable {
|
||||
|
||||
private final Transaction transaction;
|
||||
|
||||
private RollbackAll(Transaction transaction) {
|
||||
this.transaction = transaction;
|
||||
}
|
||||
|
||||
/**
|
||||
* Rollback the wrapping transaction.
|
||||
*/
|
||||
@Override
|
||||
public void close() {
|
||||
transaction.rollback();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
package io.ebean.test;
|
||||
|
||||
import io.ebeaninternal.api.SpiLogger;
|
||||
import io.ebeaninternal.server.logger.DSpiLogger;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Provides access to the messages logged to <code>io.ebean.SQL</code>.
|
||||
* <p>
|
||||
* This is here to allow easy access to the SQL that was executed during testing and
|
||||
* if desired we can use that to perform asserts in tests.
|
||||
* </p>
|
||||
* <pre>{@code
|
||||
*
|
||||
* // start capturing SQL log messages
|
||||
* LoggedSql.start();
|
||||
*
|
||||
* List<Customer> customers =
|
||||
* Customer.find.where()
|
||||
* .name.ilike("rob%")
|
||||
* .findList();
|
||||
*
|
||||
* assertNotNull(customers);
|
||||
*
|
||||
* // perform an insert
|
||||
* new Product("ad", "asd").save()
|
||||
*
|
||||
*
|
||||
* // return the captured SQL log messages
|
||||
* // since LoggedSql.start()
|
||||
* List<String> sql = LoggedSql.stop();
|
||||
*
|
||||
* assertThat(sql).hasSize(2);
|
||||
* assertThat(sql.get(0)).contains("from customer");
|
||||
* assertThat(sql.get(1)).contains("into product");
|
||||
*
|
||||
* }</pre>
|
||||
*/
|
||||
public class LoggedSql {
|
||||
|
||||
private static CaptureLogger sqlLogger;
|
||||
|
||||
/**
|
||||
* Internal use - register the logger for <code>io.ebean.SQL</code>.
|
||||
*/
|
||||
static SpiLogger register(DSpiLogger logger) {
|
||||
if (sqlLogger == null) {
|
||||
sqlLogger = new CaptureLogger(logger);
|
||||
}
|
||||
return sqlLogger;
|
||||
}
|
||||
|
||||
/**
|
||||
* Start the capture of the <code>io.ebean.SQL</code> messages.
|
||||
*/
|
||||
public static List<String> start() {
|
||||
return sqlLogger.start();
|
||||
}
|
||||
|
||||
/**
|
||||
* Stop the capture of the <code>io.ebean.SQL</code> messages and return the messages/sql
|
||||
* that was captured since the call to start().
|
||||
*/
|
||||
public static List<String> stop() {
|
||||
return sqlLogger.stop();
|
||||
}
|
||||
|
||||
/**
|
||||
* Collect and return the messages/sql that was captured since the call to start() or collect().
|
||||
* <p>
|
||||
* Unlike stop() collection of messages will continue.
|
||||
* </p>
|
||||
*/
|
||||
public static List<String> collect() {
|
||||
return sqlLogger.collect();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
package io.ebean.test;
|
||||
|
||||
/**
|
||||
* Use in test code when the CurrentUserProvider and/or CurrentTenantProvider were configured by
|
||||
* this ebean-test-config plugin.
|
||||
* <p>
|
||||
* That is, the ebean-test-config plugin will check if there ia a CurrentUserProvider and if not
|
||||
* automatically set one and that provider reads the 'current user' from this UserContext.
|
||||
* <pre>{@code
|
||||
*
|
||||
* // set the current userId which will be put
|
||||
* // into 'WhoCreated' and 'WhoModified' properties
|
||||
*
|
||||
* UserContext.setUserId("U1");
|
||||
*
|
||||
* // persist bean that has ... a 'WhoModified' property
|
||||
* Content content = new Content();
|
||||
* content.setName("hello");
|
||||
*
|
||||
* content.save();
|
||||
*
|
||||
* }</pre>
|
||||
*/
|
||||
public class UserContext {
|
||||
|
||||
private static final UserContextThreadLocal local = new UserContextThreadLocal();
|
||||
|
||||
private Object userId;
|
||||
private Object tenantId;
|
||||
|
||||
private UserContext() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the current user.
|
||||
*/
|
||||
public static Object currentUserId() {
|
||||
return local.get().userId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the current tenantId.
|
||||
*/
|
||||
public static Object currentTenantId() {
|
||||
return local.get().tenantId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the current userId - this value is put into 'WhoCreated' and 'WhoModified' properties.
|
||||
*/
|
||||
public static void setUserId(Object userId) {
|
||||
local.get().userId = userId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the current tenantId.
|
||||
*/
|
||||
public static void setTenantId(Object tenantId) {
|
||||
local.get().tenantId = tenantId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear both the current userId and tenantId.
|
||||
*/
|
||||
public static void reset() {
|
||||
local.remove();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set both the current userId and current tenantId.
|
||||
*/
|
||||
public static void set(Object userId, String tenantId) {
|
||||
UserContext userContext = local.get();
|
||||
userContext.userId = userId;
|
||||
userContext.tenantId = tenantId;
|
||||
}
|
||||
|
||||
private static class UserContextThreadLocal extends ThreadLocal<UserContext> {
|
||||
|
||||
@Override
|
||||
protected UserContext initialValue() {
|
||||
return new UserContext();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
package io.ebean.test.config;
|
||||
|
||||
import io.ebean.config.AutoConfigure;
|
||||
import io.ebean.config.DatabaseConfig;
|
||||
import io.ebean.datasource.DataSourceConfig;
|
||||
import io.ebean.test.config.platform.PlatformAutoConfig;
|
||||
import io.ebean.test.config.provider.ProviderAutoConfig;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.Properties;
|
||||
|
||||
/**
|
||||
* Automatically configure ServerConfig for testing purposes.
|
||||
* <p>
|
||||
* Can setup and execute docker based databases and other containers.
|
||||
* Can setup DataSource configuration (to match docker db setup).
|
||||
* Can setup a CurrentUserProvider and CurrentTenantProvider for testing.
|
||||
* Can setup a EncryptKeyManager for testing purposes with fixed key.
|
||||
*/
|
||||
public class AutoConfigureForTesting implements AutoConfigure {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(AutoConfigureForTesting.class);
|
||||
|
||||
/**
|
||||
* System property that can override the platform. mvn clean test -Ddb=sqlserver
|
||||
*/
|
||||
private final String environmentDb = System.getProperty("db");
|
||||
|
||||
@Override
|
||||
public void preConfigure(DatabaseConfig config) {
|
||||
|
||||
Properties properties = config.getProperties();
|
||||
if (isExtraServer(config, properties)) {
|
||||
setupExtraDataSourceIfNecessary(config);
|
||||
return;
|
||||
}
|
||||
|
||||
String testPlatform = properties.getProperty("ebean.test.platform");
|
||||
log.debug("automatic testing config - with ebean.test.platform:{} environment db:{} name:{}", testPlatform, environmentDb, config.getName());
|
||||
|
||||
if (RunOnceMarker.isRun()) {
|
||||
setupPlatform(environmentDb, config);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void postConfigure(DatabaseConfig config) {
|
||||
setupProviders(config);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if this is not the primary server and return true if that is the case.
|
||||
*/
|
||||
private boolean isExtraServer(DatabaseConfig config, Properties properties) {
|
||||
String extraDb = properties.getProperty("ebean.test.extraDb.dbName", properties.getProperty("ebean.test.extraDb"));
|
||||
if (extraDb != null && extraDb.equals(config.getName())) {
|
||||
config.setDefaultServer(false);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setup the DataSource on the extra database if necessary.
|
||||
*/
|
||||
private void setupExtraDataSourceIfNecessary(DatabaseConfig config) {
|
||||
DataSourceConfig dataSourceConfig = config.getDataSourceConfig();
|
||||
if (dataSourceConfig == null || dataSourceConfig.getUsername() == null) {
|
||||
new PlatformAutoConfig(environmentDb, config)
|
||||
.configExtraDataSource();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Setup support for Who, Multi-Tenant and DB encryption if they are not already set.
|
||||
*/
|
||||
private void setupProviders(DatabaseConfig config) {
|
||||
new ProviderAutoConfig(config).run();
|
||||
}
|
||||
|
||||
/**
|
||||
* Setup the platform for testing including docker as needed and adjusting datasource config as needed.
|
||||
*/
|
||||
private void setupPlatform(String db, DatabaseConfig config) {
|
||||
new PlatformAutoConfig(db, config).run();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package io.ebean.test.config;
|
||||
|
||||
import io.ebeaninternal.dbmigration.DbOffline;
|
||||
|
||||
class RunOnceMarker {
|
||||
|
||||
private static boolean hasRun;
|
||||
|
||||
static synchronized boolean isRun() {
|
||||
if (DbOffline.isSet() || hasRun) {
|
||||
return false;
|
||||
}
|
||||
hasRun = true;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
package io.ebean.test.config.platform;
|
||||
|
||||
import java.util.Properties;
|
||||
|
||||
class ClickHouseSetup implements PlatformSetup {
|
||||
|
||||
@Override
|
||||
public Properties setup(Config config) {
|
||||
|
||||
config.ddlMode("dropCreate");
|
||||
config.setDefaultPort(8123);
|
||||
config.setUsername("default");
|
||||
config.setPassword("");
|
||||
config.setUrl("jdbc:clickhouse://localhost:${port}/${databaseName}");
|
||||
config.setDriver("ru.yandex.clickhouse.ClickHouseDriver");
|
||||
config.datasourceDefaults();
|
||||
|
||||
return dockerProperties(config);
|
||||
}
|
||||
|
||||
private Properties dockerProperties(Config dbConfig) {
|
||||
|
||||
if (!dbConfig.isUseDocker()) {
|
||||
return new Properties();
|
||||
}
|
||||
|
||||
dbConfig.setDockerVersion("latest");
|
||||
return dbConfig.getDockerProperties();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setupExtraDbDataSource(Config config) {
|
||||
// not supported yet
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLocal() {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
package io.ebean.test.config.platform;
|
||||
|
||||
import java.util.Properties;
|
||||
|
||||
class CockroachSetup implements PlatformSetup {
|
||||
|
||||
@Override
|
||||
public Properties setup(Config config) {
|
||||
|
||||
config.ddlMode("dropCreate");
|
||||
config.setDefaultPort(26257);
|
||||
config.setUsername("root");
|
||||
config.setPassword("");
|
||||
config.setUrl("jdbc:postgresql://localhost:${port}/${databaseName}?sslmode=disable");
|
||||
config.setDriver("org.postgresql.Driver");
|
||||
config.datasourceDefaults();
|
||||
|
||||
return dockerProperties(config);
|
||||
}
|
||||
|
||||
private Properties dockerProperties(Config dbConfig) {
|
||||
|
||||
if (!dbConfig.isUseDocker()) {
|
||||
return new Properties();
|
||||
}
|
||||
|
||||
dbConfig.setDockerVersion("v19.1.3");
|
||||
return dbConfig.getDockerProperties();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setupExtraDbDataSource(Config config) {
|
||||
// not supported yet
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLocal() {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,454 @@
|
||||
package io.ebean.test.config.platform;
|
||||
|
||||
import io.ebean.config.DatabaseConfig;
|
||||
import io.ebean.datasource.DataSourceConfig;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Properties;
|
||||
|
||||
/**
|
||||
* Config for a database / datasource with associated DDL mode and Docker configuration.
|
||||
*/
|
||||
class Config {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(Config.class);
|
||||
|
||||
/**
|
||||
* Common optional docker parameters that we just transfer to docker properties.
|
||||
*/
|
||||
private static final String[] DOCKER_TEST_PARAMS = {"fastStartMode", "inMemory", "initSqlFile", "seedSqlFile", "adminUser", "adminPassword", "extraDb", "extraDb.dbName", "extraDb.username", "extraDb.password", "extraDb.initSqlFile", "extraDb.seedSqlFile"};
|
||||
private static final String[] DOCKER_PLATFORM_PARAMS = {"containerName", "image", "internalPort", "startMode", "stopMode", "shutdown", "maxReadyAttempts", "tmpfs", "collation", "characterSet"};
|
||||
|
||||
private static final String DDL_MODE_OPTIONS = "dropCreate, create, none, migration, createOnly or migrationDropCreate";
|
||||
|
||||
private final String db;
|
||||
private final String platform;
|
||||
private String dockerPlatform;
|
||||
|
||||
private String databaseName;
|
||||
|
||||
private final Properties properties;
|
||||
|
||||
private int port;
|
||||
|
||||
private String url;
|
||||
private String driver;
|
||||
private String schema;
|
||||
private String username;
|
||||
private String password;
|
||||
|
||||
private final DatabaseConfig config;
|
||||
|
||||
private boolean containerDropCreate;
|
||||
|
||||
private final Properties dockerProperties = new Properties();
|
||||
|
||||
Config(String db, String platform, String databaseName, DatabaseConfig config) {
|
||||
this.db = db;
|
||||
this.platform = platform;
|
||||
this.dockerPlatform = platform;
|
||||
this.databaseName = databaseName;
|
||||
this.config = config;
|
||||
this.properties = config.getProperties();
|
||||
}
|
||||
|
||||
void setSchemaFromDbName(String newDbName) {
|
||||
this.schema = databaseName;
|
||||
this.databaseName = newDbName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the docker platform name (when it is different from the test platform name).
|
||||
* For example test platform name of "postgis" maps to "postgres" docker platform name.
|
||||
*/
|
||||
void setDockerPlatform(String dockerPlatform) {
|
||||
this.dockerPlatform = dockerPlatform;
|
||||
}
|
||||
|
||||
void setDefaultPort(int defaultPort) {
|
||||
String val = getPlatformKey("port", null);
|
||||
if (val != null) {
|
||||
port = Integer.parseInt(val);
|
||||
} else {
|
||||
port = defaultPort;
|
||||
}
|
||||
}
|
||||
|
||||
void ddlMode(String defaultMode) {
|
||||
String ddlMode = properties.getProperty("ebean.test.ddlMode", defaultMode);
|
||||
if (ddlMode == null) {
|
||||
throw new IllegalStateException("No ebean.test.ddlMode set? Expect one of " + DDL_MODE_OPTIONS);
|
||||
}
|
||||
switch (ddlMode.toLowerCase()) {
|
||||
case "none": {
|
||||
disableMigrationRun();
|
||||
break;
|
||||
}
|
||||
case "migrationonly":
|
||||
case "migrationsonly": {
|
||||
setMigrationRun();
|
||||
break;
|
||||
}
|
||||
case "migrationdropcreate":
|
||||
case "migrationsdropcreate":
|
||||
case "migration":
|
||||
case "migrations": {
|
||||
setMigrationRun();
|
||||
containerDropCreate = true;
|
||||
break;
|
||||
}
|
||||
case "createonly": {
|
||||
setCreate();
|
||||
break;
|
||||
}
|
||||
case "create": {
|
||||
containerDropCreate = true;
|
||||
setCreate();
|
||||
break;
|
||||
}
|
||||
case "dropcreate": {
|
||||
setDropCreate();
|
||||
break;
|
||||
}
|
||||
case "runonly": {
|
||||
setRunOnly();
|
||||
break;
|
||||
}
|
||||
default:
|
||||
throw new IllegalStateException("Unknown ebean.test.ddlMode [" + ddlMode + "] expecting one of " + DDL_MODE_OPTIONS);
|
||||
}
|
||||
}
|
||||
|
||||
private void setCreate() {
|
||||
setDropCreate();
|
||||
config.setDdlCreateOnly(true);
|
||||
setDdlProperty("createOnly");
|
||||
}
|
||||
|
||||
private void setDropCreate() {
|
||||
disableMigrationRun();
|
||||
config.setDdlGenerate(true);
|
||||
config.setDdlRun(true);
|
||||
setDdlProperty("generate");
|
||||
setDdlProperty("run");
|
||||
setDdlInitSeed();
|
||||
}
|
||||
|
||||
private void setRunOnly() {
|
||||
disableMigrationRun();
|
||||
config.setDdlGenerate(false);
|
||||
config.setDdlRun(true);
|
||||
setDdlProperty("run");
|
||||
setDdlInitSeed();
|
||||
}
|
||||
|
||||
private void setDdlInitSeed() {
|
||||
final String initSql = getKey("initSql", null);
|
||||
if (initSql != null) {
|
||||
setProperty("ebean." + db + ".ddl.initSql", initSql);
|
||||
}
|
||||
final String seedSql = getKey("seedSql", null);
|
||||
if (seedSql != null) {
|
||||
setProperty("ebean." + db + ".ddl.seedSql", seedSql);
|
||||
}
|
||||
}
|
||||
|
||||
private void setMigrationRun() {
|
||||
config.getMigrationConfig().setRunMigration(true);
|
||||
setProperty("ebean." + db + ".migration.run", "true");
|
||||
}
|
||||
|
||||
private void disableMigrationRun() {
|
||||
System.setProperty("ddl.migration.run", "false");
|
||||
}
|
||||
|
||||
/**
|
||||
* Override the dataSource property.
|
||||
*/
|
||||
private void setDdlProperty(String key) {
|
||||
setProperty("ebean." + db + ".ddl." + key, "true");
|
||||
}
|
||||
|
||||
DataSourceConfig datasourceDefaults() {
|
||||
return datasourceDefaults(platform);
|
||||
}
|
||||
|
||||
void extraDatasourceDefaults() {
|
||||
datasourceDefaults("extraDb");
|
||||
}
|
||||
|
||||
private DataSourceConfig datasourceDefaults(String platform) {
|
||||
// default username to databaseName
|
||||
if (username == null) {
|
||||
throw new IllegalStateException("username not set?");
|
||||
}
|
||||
if (password == null) {
|
||||
throw new IllegalStateException("password not set?");
|
||||
}
|
||||
|
||||
DataSourceConfig ds = new DataSourceConfig();
|
||||
ds.setUsername(datasourceProperty(platform, "username", username));
|
||||
ds.setPassword(datasourceProperty(platform, "password", password));
|
||||
ds.setOwnerUsername(datasourceProperty(platform, "ownerUsername", null));
|
||||
ds.setOwnerPassword(datasourceProperty(platform, "ownerPassword", null));
|
||||
ds.setUrl(datasourceProperty(platform, "url", url));
|
||||
String driverClass = datasourceProperty(platform, "driver", driver);
|
||||
ds.setDriver(driverClass);
|
||||
config.setDataSourceConfig(ds);
|
||||
|
||||
log.info("Using jdbc settings - username:{} url:{} driver:{}", ds.getUsername(), ds.getUrl(), ds.getDriver());
|
||||
|
||||
if (driverClass != null) {
|
||||
try {
|
||||
Class.forName(driverClass);
|
||||
} catch (ClassNotFoundException e) {
|
||||
throw new IllegalStateException("JDBC Driver " + driverClass + " does not appear to be in the classpath?");
|
||||
}
|
||||
}
|
||||
return ds;
|
||||
}
|
||||
|
||||
String datasourceProperty(String key, String defaultValue) {
|
||||
return datasourceProperty(platform, key, defaultValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* Override the dataSource property.
|
||||
*/
|
||||
private String datasourceProperty(String platform, String key, String defaultValue) {
|
||||
String val = getTestKey(platform, key, defaultValue);
|
||||
if (val != null) {
|
||||
setProperty("datasource." + db + "." + key, val);
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
private void setProperty(String dsKey, String val) {
|
||||
properties.setProperty(dsKey, val);
|
||||
}
|
||||
|
||||
void setUrl(String urlPattern) {
|
||||
String val = getPlatformKey("url", urlPattern);
|
||||
val = val.replace("${port}", String.valueOf(port));
|
||||
val = val.replace("${databaseName}", databaseName);
|
||||
this.url = val;
|
||||
}
|
||||
|
||||
/**
|
||||
* Append to the connection URL.
|
||||
*/
|
||||
void urlAppend(String dbSchemaSuffix) {
|
||||
this.url += dbSchemaSuffix;
|
||||
}
|
||||
|
||||
void setDriver(String driver) {
|
||||
this.driver = getPlatformKey("driver", driver);
|
||||
}
|
||||
|
||||
void setPasswordDefault() {
|
||||
setPassword("test");
|
||||
}
|
||||
|
||||
void setExtraDbPasswordDefault() {
|
||||
setExtraDbPassword("test");
|
||||
}
|
||||
|
||||
private String deriveDbSchema() {
|
||||
String dbSchema = properties.getProperty("ebean.dbSchema", config.getDbSchema());
|
||||
dbSchema = properties.getProperty("ebean.test.dbSchema", dbSchema);
|
||||
return getPlatformKey("schema", dbSchema);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the username to default to database name.
|
||||
*/
|
||||
void setUsernameDefault() {
|
||||
this.schema = first(deriveDbSchema());
|
||||
String defaultValue = schema != null ? schema : getPlatformKey("databaseName", this.databaseName);
|
||||
this.username = getKey("username", defaultValue);
|
||||
}
|
||||
|
||||
void setUsernameDefaultSchema() {
|
||||
this.username = getKey("username", schema);
|
||||
}
|
||||
|
||||
void setExtraUsernameDefault() {
|
||||
this.username = getKey("extraDb.username", this.databaseName);
|
||||
}
|
||||
|
||||
private String first(String dbSchema) {
|
||||
if (dbSchema == null) {
|
||||
return null;
|
||||
}
|
||||
String[] schemas = dbSchema.split(",");
|
||||
if (schemas.length > 1) {
|
||||
// multiple schemas specified so just use the first one
|
||||
return schemas[0];
|
||||
}
|
||||
return dbSchema;
|
||||
}
|
||||
|
||||
String getUsername() {
|
||||
return username;
|
||||
}
|
||||
|
||||
String getSchema() {
|
||||
return schema;
|
||||
}
|
||||
|
||||
private void setExtraDbPassword(String password) {
|
||||
this.password = getKey("extraDb.password", password);
|
||||
}
|
||||
|
||||
void setPassword(String password) {
|
||||
this.password = getKey("password", password);
|
||||
}
|
||||
|
||||
void setUsername(String username) {
|
||||
this.username = getPlatformKey("username", username);
|
||||
}
|
||||
|
||||
void setDatabaseName(String databaseName) {
|
||||
this.databaseName = getPlatformKey("databaseName", databaseName);
|
||||
}
|
||||
|
||||
boolean isUseDocker() {
|
||||
String val = getPlatformKey("useDocker", properties.getProperty("ebean.test.useDocker"));
|
||||
return val == null || !val.equalsIgnoreCase("false");
|
||||
}
|
||||
|
||||
void setDockerVersion(String version) {
|
||||
String val = getPlatformKey("version", version);
|
||||
dockerProperties.setProperty(dockerKey("version"), val);
|
||||
|
||||
if (containerDropCreate) {
|
||||
dockerProperties.setProperty(dockerKey("startMode"), "dropCreate");
|
||||
}
|
||||
String mode = properties.getProperty("ebean.test.containerMode");
|
||||
if (mode != null) {
|
||||
dockerProperties.setProperty(dockerKey("startMode"), mode);
|
||||
}
|
||||
initDockerProperties();
|
||||
}
|
||||
|
||||
void setDockerContainerName(String containerName) {
|
||||
dockerProperties.setProperty(dockerKey("containerName"), getPlatformKey("containerName", containerName));
|
||||
}
|
||||
|
||||
void setDockerImage(String defaultImage) {
|
||||
dockerProperties.setProperty(dockerKey("image"), getPlatformKey("image", defaultImage));
|
||||
}
|
||||
|
||||
void setExtensions(String defaultValue) {
|
||||
// ebean.test.postgres.extensions=hstore,pgcrypto
|
||||
String val = getPlatformKey("extensions", defaultValue);
|
||||
if (val != null) {
|
||||
dockerProperties.setProperty(dockerKey("extensions"), trimExtensions(val));
|
||||
}
|
||||
}
|
||||
|
||||
String trimExtensions(String val) {
|
||||
val = val.replaceAll(" ", "");
|
||||
val = val.replaceAll(",,", ",");
|
||||
return val;
|
||||
}
|
||||
|
||||
private String getTestKey(String platform, String key, String defaultValue) {
|
||||
return properties.getProperty("ebean.test." + platform + "." + key, defaultValue);
|
||||
}
|
||||
|
||||
String getPlatformKey(String key, String defaultValue) {
|
||||
return properties.getProperty("ebean.test." + platform + "." + key, defaultValue);
|
||||
}
|
||||
|
||||
private String getKey(String key, String defaultValue) {
|
||||
defaultValue = properties.getProperty("ebean.test." + key, defaultValue);
|
||||
return properties.getProperty("ebean.test." + platform + "." + key, defaultValue);
|
||||
}
|
||||
|
||||
private void initDockerProperties() {
|
||||
|
||||
dockerProperties.setProperty(dockerKey("port"), String.valueOf(port));
|
||||
dockerProperties.setProperty(dockerKey("dbName"), databaseName);
|
||||
if (schema != null) {
|
||||
dockerProperties.setProperty(dockerKey("schema"), schema);
|
||||
}
|
||||
dockerProperties.setProperty(dockerKey("username"), username);
|
||||
dockerProperties.setProperty(dockerKey("password"), password);
|
||||
dockerProperties.setProperty(dockerKey("url"), url);
|
||||
if (driver != null) {
|
||||
dockerProperties.setProperty(dockerKey("driver"), driver);
|
||||
}
|
||||
setDockerOptionalParameters();
|
||||
}
|
||||
|
||||
private void setDockerOptionalParameters() {
|
||||
|
||||
// check for shutdown mode on all containers
|
||||
String mode = properties.getProperty("ebean.test.shutdown");
|
||||
if (mode != null && !ignoreDockerShutdown()) {
|
||||
dockerProperties.setProperty(dockerKey("shutdown"), mode);
|
||||
}
|
||||
for (String key : DOCKER_TEST_PARAMS) {
|
||||
String val = getKey(key, null);
|
||||
val = properties.getProperty("docker." + platform + "." + key, val);
|
||||
if (val != null) {
|
||||
dockerProperties.setProperty(dockerKey(key), val);
|
||||
}
|
||||
}
|
||||
for (String key : DOCKER_PLATFORM_PARAMS) {
|
||||
String val = getPlatformKey(key, null);
|
||||
val = properties.getProperty("docker." + platform + "." + key, val);
|
||||
if (val != null) {
|
||||
dockerProperties.setProperty(dockerKey(key), val);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* For local development we might want to ignore docker shutdown.
|
||||
* <p>
|
||||
* So we just want the shutdown mode to be used on the CI server.
|
||||
*/
|
||||
boolean ignoreDockerShutdown() {
|
||||
String localDev = properties.getProperty("ebean.test.localDevelopment", "~/.ebean/ignore-docker-shutdown");
|
||||
return ignoreDockerShutdown(localDev);
|
||||
}
|
||||
|
||||
boolean ignoreDockerShutdown(String localDev) {
|
||||
|
||||
if (localDev.startsWith("~/")) {
|
||||
File homeDir = new File(System.getProperty("user.home"));
|
||||
return new File(homeDir, localDev.substring(2)).exists();
|
||||
}
|
||||
|
||||
return new File(localDev).exists();
|
||||
}
|
||||
|
||||
private String dockerKey(String key) {
|
||||
return dockerPlatform + "." + key;
|
||||
}
|
||||
|
||||
Properties getDockerProperties() {
|
||||
return dockerProperties;
|
||||
}
|
||||
|
||||
/**
|
||||
* Pretty much only for SqlServer as we have the 2 platforms we need to choose from.
|
||||
*/
|
||||
void setDatabasePlatformName() {
|
||||
String databasePlatformName = getPlatformKey("databasePlatformName", null);
|
||||
if (databasePlatformName != null) {
|
||||
setProperty("ebean." + db + ".databasePlatformName", databasePlatformName);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the docker platform name. Should be a name that ebean-test-docker understands.
|
||||
*/
|
||||
String getDockerPlatform() {
|
||||
return dockerPlatform;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
package io.ebean.test.config.platform;
|
||||
|
||||
import io.ebean.docker.commands.ElasticConfig;
|
||||
import io.ebean.docker.commands.ElasticContainer;
|
||||
|
||||
import java.util.Properties;
|
||||
|
||||
/**
|
||||
* Setup and start a Docker container for ElasticSearch.
|
||||
*/
|
||||
class ElasticSearchSetup {
|
||||
|
||||
private static final String[] DOCKER_PARAMS = {"containerName", "image", "internalPort", "startMode", "shutdown"};
|
||||
|
||||
private final Properties config;
|
||||
|
||||
ElasticSearchSetup(Properties config) {
|
||||
this.config = config;
|
||||
}
|
||||
|
||||
void run() {
|
||||
ElasticConfig elasticConfig = readConfig();
|
||||
if (elasticConfig != null) {
|
||||
new ElasticContainer(elasticConfig).start();
|
||||
}
|
||||
}
|
||||
|
||||
ElasticConfig readConfig() {
|
||||
|
||||
String version = read("version", null);
|
||||
if (version == null) {
|
||||
// we need an explicit version to run
|
||||
return null;
|
||||
}
|
||||
|
||||
return new ElasticConfig(version, populateDockerProperties(version));
|
||||
}
|
||||
|
||||
private Properties populateDockerProperties(String version) {
|
||||
|
||||
PropertiesBuilder properties = new PropertiesBuilder();
|
||||
|
||||
String mode = config.getProperty("ebean.test.shutdown");
|
||||
if (mode != null) {
|
||||
properties.set("shutdown", mode);
|
||||
}
|
||||
|
||||
properties.set("version", version);
|
||||
properties.set("port", read("port", "9201"));
|
||||
for (String dockerParam : DOCKER_PARAMS) {
|
||||
String val = read(dockerParam, null);
|
||||
if (val != null) {
|
||||
properties.set(dockerParam, val);
|
||||
}
|
||||
}
|
||||
|
||||
return properties.build();
|
||||
}
|
||||
|
||||
private String read(String key, String defaultValue) {
|
||||
return config.getProperty("ebean.docstore.elastic." + key, defaultValue);
|
||||
}
|
||||
|
||||
private static class PropertiesBuilder {
|
||||
|
||||
private Properties dockerProperties = new Properties();
|
||||
|
||||
private void set(String key, String val) {
|
||||
dockerProperties.setProperty("elastic." + key, val);
|
||||
}
|
||||
|
||||
private Properties build() {
|
||||
return dockerProperties;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package io.ebean.test.config.platform;
|
||||
|
||||
import java.util.Properties;
|
||||
|
||||
class H2Setup implements PlatformSetup {
|
||||
|
||||
@Override
|
||||
public Properties setup(Config config) {
|
||||
|
||||
config.ddlMode("create");
|
||||
config.setUsername("sa");
|
||||
config.setPassword("");
|
||||
config.setUrl("jdbc:h2:mem:${databaseName}");
|
||||
config.setDriver("org.h2.Driver");
|
||||
config.datasourceDefaults();
|
||||
|
||||
// return empty properties
|
||||
return new Properties();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setupExtraDbDataSource(Config config) {
|
||||
// not supported yet
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLocal() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
package io.ebean.test.config.platform;
|
||||
|
||||
import java.util.Properties;
|
||||
|
||||
class HanaSetup implements PlatformSetup {
|
||||
|
||||
@Override
|
||||
public Properties setup(Config config) {
|
||||
|
||||
config.setDatabasePlatformName();
|
||||
|
||||
config.ddlMode("dropCreate");
|
||||
int instanceNumber = Integer.parseInt(config.getPlatformKey("instanceNumber", "90"));
|
||||
if (instanceNumber >= 0 && instanceNumber <= 99) {
|
||||
config.setDefaultPort(30017 + (instanceNumber * 100));
|
||||
} else {
|
||||
config.setDefaultPort(39017);
|
||||
}
|
||||
config.setUsernameDefault();
|
||||
config.setUsername("SYSTEM");
|
||||
config.setPassword("HXEHana1");
|
||||
config.setDatabaseName("HXE");
|
||||
config.setUrl("jdbc:sap://localhost:${port}/?databaseName=${databaseName}");
|
||||
String schema = config.getSchema();
|
||||
if (schema != null && !schema.equals(config.getUsername())) {
|
||||
config.urlAppend("¤tSchema=" + schema);
|
||||
}
|
||||
config.setDriver("com.sap.db.jdbc.Driver");
|
||||
config.datasourceDefaults();
|
||||
|
||||
return dockerProperties(config);
|
||||
}
|
||||
|
||||
private Properties dockerProperties(Config dbConfig) {
|
||||
|
||||
if (!dbConfig.isUseDocker()) {
|
||||
return new Properties();
|
||||
}
|
||||
|
||||
dbConfig.setDockerVersion("latest");
|
||||
|
||||
setDockerProperty("agreeToSapLicense", String.valueOf(false), dbConfig);
|
||||
setDockerProperty("passwordsUrl", null, dbConfig);
|
||||
setDockerProperty("mountsDirectory", null, dbConfig);
|
||||
setDockerProperty("instanceNumber", null, dbConfig);
|
||||
|
||||
return dbConfig.getDockerProperties();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLocal() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setupExtraDbDataSource(Config config) {
|
||||
// not supported yet
|
||||
}
|
||||
|
||||
private void setDockerProperty(String key, String defaultValue, Config dbConfig) {
|
||||
String value = dbConfig.getPlatformKey(key, defaultValue);
|
||||
if (value != null) {
|
||||
dbConfig.getDockerProperties().put("hana." + key, value);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
package io.ebean.test.config.platform;
|
||||
|
||||
import java.util.Properties;
|
||||
|
||||
class MariaDBSetup implements PlatformSetup {
|
||||
|
||||
@Override
|
||||
public Properties setup(Config config) {
|
||||
|
||||
int defaultPort = config.isUseDocker() ? 4306 : 3306;
|
||||
|
||||
config.ddlMode("dropCreate");
|
||||
config.setDefaultPort(defaultPort);
|
||||
config.setUsernameDefault();
|
||||
config.setPasswordDefault();
|
||||
config.setUrl("jdbc:mariadb://localhost:${port}/${databaseName}?useLegacyDatetimeCode=false");
|
||||
config.datasourceDefaults();
|
||||
|
||||
return dockerProperties(config);
|
||||
}
|
||||
|
||||
private Properties dockerProperties(Config dbConfig) {
|
||||
if (!dbConfig.isUseDocker()) {
|
||||
return new Properties();
|
||||
}
|
||||
dbConfig.setDockerVersion("10");
|
||||
return dbConfig.getDockerProperties();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setupExtraDbDataSource(Config config) {
|
||||
// not supported yet
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLocal() {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
package io.ebean.test.config.platform;
|
||||
|
||||
import java.util.Properties;
|
||||
|
||||
class MySqlSetup implements PlatformSetup {
|
||||
|
||||
@Override
|
||||
public Properties setup(Config config) {
|
||||
|
||||
int defaultPort = config.isUseDocker() ? 4306 : 3306;
|
||||
|
||||
config.ddlMode("dropCreate");
|
||||
config.setDefaultPort(defaultPort);
|
||||
config.setUsernameDefault();
|
||||
config.setPasswordDefault();
|
||||
config.setUrl("jdbc:mysql://localhost:${port}/${databaseName}");
|
||||
config.setDriver(defaultDriver());
|
||||
config.datasourceDefaults();
|
||||
|
||||
return dockerProperties(config);
|
||||
}
|
||||
|
||||
private String defaultDriver() {
|
||||
try {
|
||||
String newDriver = "com.mysql.cj.jdbc.Driver";
|
||||
Class.forName(newDriver);
|
||||
return newDriver;
|
||||
} catch (ClassNotFoundException e) {
|
||||
return "com.mysql.jdbc.Driver";
|
||||
}
|
||||
}
|
||||
|
||||
private Properties dockerProperties(Config dbConfig) {
|
||||
|
||||
if (!dbConfig.isUseDocker()) {
|
||||
return new Properties();
|
||||
}
|
||||
|
||||
dbConfig.setDockerVersion("8.0");
|
||||
return dbConfig.getDockerProperties();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setupExtraDbDataSource(Config config) {
|
||||
// not supported yet
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLocal() {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
package io.ebean.test.config.platform;
|
||||
|
||||
import io.ebean.datasource.DataSourceConfig;
|
||||
|
||||
import java.util.Properties;
|
||||
|
||||
class NuoDBSetup implements PlatformSetup {
|
||||
|
||||
@Override
|
||||
public Properties setup(Config config) {
|
||||
// use testdb as our standard db name and instead use schema
|
||||
config.setSchemaFromDbName("testdb");
|
||||
config.ddlMode("dropCreate");
|
||||
config.setDefaultPort(8888);
|
||||
config.setUsernameDefaultSchema();
|
||||
config.setPasswordDefault();
|
||||
config.setUrl("jdbc:com.nuodb://localhost/testdb");
|
||||
config.setDriver("com.nuodb.jdbc.Driver");
|
||||
|
||||
final DataSourceConfig dsConfig = config.datasourceDefaults();
|
||||
dsConfig.setSchema(config.getSchema());
|
||||
return dockerProperties(config);
|
||||
}
|
||||
|
||||
private Properties dockerProperties(Config dbConfig) {
|
||||
|
||||
if (!dbConfig.isUseDocker()) {
|
||||
return new Properties();
|
||||
}
|
||||
|
||||
dbConfig.setDockerVersion("4.0.0");
|
||||
return dbConfig.getDockerProperties();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setupExtraDbDataSource(Config config) {
|
||||
// not supported yet
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLocal() {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
package io.ebean.test.config.platform;
|
||||
|
||||
import java.util.Properties;
|
||||
|
||||
class OracleSetup implements PlatformSetup {
|
||||
|
||||
@Override
|
||||
public Properties setup(Config config) {
|
||||
|
||||
config.ddlMode("dropCreate");
|
||||
config.setDefaultPort(1521);
|
||||
config.setUsernameDefault();
|
||||
config.setPasswordDefault();
|
||||
config.setDatabaseName("XE");
|
||||
config.setUrl("jdbc:oracle:thin:@localhost:${port}:${databaseName}");
|
||||
config.setDriver("oracle.jdbc.driver.OracleDriver");
|
||||
config.datasourceDefaults();
|
||||
return dockerProperties(config);
|
||||
}
|
||||
|
||||
private Properties dockerProperties(Config dbConfig) {
|
||||
|
||||
if (!dbConfig.isUseDocker()) {
|
||||
return new Properties();
|
||||
}
|
||||
|
||||
dbConfig.setDockerVersion("latest");
|
||||
return dbConfig.getDockerProperties();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setupExtraDbDataSource(Config config) {
|
||||
// not supported yet
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLocal() {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,157 @@
|
||||
package io.ebean.test.config.platform;
|
||||
|
||||
import io.ebean.config.DatabaseConfig;
|
||||
import io.ebean.docker.container.ContainerFactory;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
|
||||
import static java.util.concurrent.CompletableFuture.allOf;
|
||||
import static java.util.concurrent.CompletableFuture.runAsync;
|
||||
|
||||
public class PlatformAutoConfig {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(PlatformAutoConfig.class);
|
||||
|
||||
/**
|
||||
* Known platforms we can setup locally or via docker container.
|
||||
*/
|
||||
private static final Map<String, PlatformSetup> KNOWN_PLATFORMS = new HashMap<>();
|
||||
|
||||
static {
|
||||
KNOWN_PLATFORMS.put("h2", new H2Setup());
|
||||
KNOWN_PLATFORMS.put("sqlite", new SqliteSetup());
|
||||
KNOWN_PLATFORMS.put("postgres", new PostgresSetup());
|
||||
KNOWN_PLATFORMS.put("postgis", new PostgisSetup());
|
||||
KNOWN_PLATFORMS.put("nuodb", new NuoDBSetup());
|
||||
KNOWN_PLATFORMS.put("mysql", new MySqlSetup());
|
||||
KNOWN_PLATFORMS.put("mariadb", new MariaDBSetup());
|
||||
KNOWN_PLATFORMS.put("sqlserver", new SqlServerSetup());
|
||||
KNOWN_PLATFORMS.put("oracle", new OracleSetup());
|
||||
KNOWN_PLATFORMS.put("clickhouse", new ClickHouseSetup());
|
||||
KNOWN_PLATFORMS.put("cockroach", new CockroachSetup());
|
||||
KNOWN_PLATFORMS.put("hana", new HanaSetup());
|
||||
}
|
||||
|
||||
private final DatabaseConfig config;
|
||||
|
||||
private final Properties properties;
|
||||
|
||||
private String db;
|
||||
|
||||
private String platform;
|
||||
|
||||
private PlatformSetup platformSetup;
|
||||
|
||||
private String databaseName;
|
||||
|
||||
public PlatformAutoConfig(String db, DatabaseConfig config) {
|
||||
this.db = db;
|
||||
this.config = config;
|
||||
this.properties = config.getProperties();
|
||||
}
|
||||
|
||||
/**
|
||||
* Configure the DataSource for the extra database.
|
||||
*/
|
||||
public void configExtraDataSource() {
|
||||
determineTestPlatform();
|
||||
if (isKnownPlatform()) {
|
||||
databaseName = config.getName();
|
||||
db = config.getName();
|
||||
|
||||
Config config = new Config(db, platform, databaseName, this.config);
|
||||
platformSetup.setupExtraDbDataSource(config);
|
||||
log.debug("configured dataSource for extraDb name:{} url:{}", db, this.config.getDataSourceConfig().getUrl());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Run setting up for testing.
|
||||
*/
|
||||
public void run() {
|
||||
determineTestPlatform();
|
||||
if (isKnownPlatform()) {
|
||||
readDbName();
|
||||
setupForTesting();
|
||||
}
|
||||
}
|
||||
|
||||
private void setupForTesting() {
|
||||
// start containers in parallel
|
||||
RedisSetup.run(properties);
|
||||
allOf(runAsync(this::setupElasticSearch), runAsync(this::setupDatabase)).join();
|
||||
}
|
||||
|
||||
private void setupElasticSearch() {
|
||||
new ElasticSearchSetup(properties).run();
|
||||
}
|
||||
|
||||
private void setupDatabase() {
|
||||
Config config = new Config(db, platform, databaseName, this.config);
|
||||
Properties dockerProperties = platformSetup.setup(config);
|
||||
if (!dockerProperties.isEmpty()) {
|
||||
if (isDebug()) {
|
||||
log.info("Docker properties: {}", dockerProperties);
|
||||
} else {
|
||||
log.debug("Docker properties: {}", dockerProperties);
|
||||
}
|
||||
// start the docker container with appropriate configuration
|
||||
new ContainerFactory(dockerProperties, config.getDockerPlatform()).startContainers();
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isDebug() {
|
||||
String val = properties.getProperty("ebean.test.debug");
|
||||
return (val != null && val.equalsIgnoreCase("true"));
|
||||
}
|
||||
|
||||
private void readDbName() {
|
||||
databaseName = properties.getProperty("ebean.test.dbName");
|
||||
if (databaseName == null) {
|
||||
if (inMemoryDb()) {
|
||||
databaseName = "test_db";
|
||||
} else {
|
||||
throw new IllegalStateException("ebean.test.dbName is not set but required for testing configuration with platform " + platform);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean inMemoryDb() {
|
||||
return platformSetup.isLocal();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if we match a known platform and know how to set it up for testing (via docker usually).
|
||||
*/
|
||||
private boolean isKnownPlatform() {
|
||||
if (platform == null) {
|
||||
return false;
|
||||
}
|
||||
this.platformSetup = KNOWN_PLATFORMS.get(platform);
|
||||
if (platformSetup == null) {
|
||||
log.warn("unknown platform {} - skipping platform setup", platform);
|
||||
}
|
||||
return platformSetup != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine the platform we are going to use to run testing.
|
||||
*/
|
||||
private void determineTestPlatform() {
|
||||
String testPlatform = properties.getProperty("ebean.test.platform");
|
||||
if (testPlatform != null && !testPlatform.isEmpty()) {
|
||||
if (db == null) {
|
||||
platform = testPlatform.trim();
|
||||
db = "db";
|
||||
} else {
|
||||
// using command line system property to test alternate platform
|
||||
// and we expect db to match a platform name
|
||||
platform = db;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package io.ebean.test.config.platform;
|
||||
|
||||
import java.util.Properties;
|
||||
|
||||
interface PlatformSetup {
|
||||
|
||||
/**
|
||||
* Return true if a local database (H2 and Sqlite - don't need a database name to be configured).
|
||||
*/
|
||||
boolean isLocal();
|
||||
|
||||
/**
|
||||
* Run the setup for the given platform (set DataSource and DDL configuration).
|
||||
*
|
||||
* Return the properties used to configure the docker container.
|
||||
*/
|
||||
Properties setup(Config dbConfig);
|
||||
|
||||
/**
|
||||
* Set DataSource configuration for the extra database.
|
||||
*/
|
||||
void setupExtraDbDataSource(Config config);
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
package io.ebean.test.config.platform;
|
||||
|
||||
import java.util.Properties;
|
||||
|
||||
/**
|
||||
* A variation of Postgres that expected Postgis extension support.
|
||||
*
|
||||
* Uses mdillon/postgis image by default.
|
||||
*/
|
||||
class PostgisSetup implements PlatformSetup {
|
||||
|
||||
@Override
|
||||
public Properties setup(Config config) {
|
||||
|
||||
int defaultPort = config.isUseDocker() ? 7432 : 5432;
|
||||
|
||||
config.setDockerPlatform("postgres");
|
||||
config.ddlMode("dropCreate");
|
||||
config.setDefaultPort(defaultPort);
|
||||
config.setUsernameDefault();
|
||||
config.setPasswordDefault();
|
||||
config.setDriver("org.postgis.DriverWrapperLW");
|
||||
config.setUrl("jdbc:postgresql_lwgis://localhost:${port}/${databaseName}");
|
||||
|
||||
String schema = config.getSchema();
|
||||
if (schema != null && !schema.equals(config.getUsername())) {
|
||||
config.urlAppend("?currentSchema=" + schema);
|
||||
}
|
||||
config.datasourceDefaults();
|
||||
|
||||
return dockerProperties(config);
|
||||
}
|
||||
|
||||
private Properties dockerProperties(Config config) {
|
||||
|
||||
if (!config.isUseDocker()) {
|
||||
return new Properties();
|
||||
}
|
||||
|
||||
config.setExtensions("hstore,pgcrypto,postgis");
|
||||
config.setDockerImage("mdillon/postgis");
|
||||
config.setDockerContainerName("postgis");
|
||||
config.setDockerVersion("10");
|
||||
return config.getDockerProperties();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setupExtraDbDataSource(Config config) {
|
||||
// not supported yet
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLocal() {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
package io.ebean.test.config.platform;
|
||||
|
||||
import java.util.Properties;
|
||||
|
||||
class PostgresSetup implements PlatformSetup {
|
||||
|
||||
@Override
|
||||
public Properties setup(Config config) {
|
||||
|
||||
int defaultPort = config.isUseDocker() ? 6432 : 5432;
|
||||
|
||||
config.ddlMode("dropCreate");
|
||||
config.setDefaultPort(defaultPort);
|
||||
config.setUsernameDefault();
|
||||
config.setPasswordDefault();
|
||||
config.setUrl("jdbc:postgresql://localhost:${port}/${databaseName}");
|
||||
|
||||
String schema = config.getSchema();
|
||||
if (schema != null && !schema.equals(config.getUsername())) {
|
||||
config.urlAppend("?currentSchema=" + schema);
|
||||
}
|
||||
config.setDriver("org.postgresql.Driver");
|
||||
config.datasourceDefaults();
|
||||
|
||||
return dockerProperties(config);
|
||||
}
|
||||
|
||||
private Properties dockerProperties(Config config) {
|
||||
|
||||
if (!config.isUseDocker()) {
|
||||
return new Properties();
|
||||
}
|
||||
|
||||
config.setDockerVersion("12");
|
||||
config.setExtensions("hstore,pgcrypto");
|
||||
return config.getDockerProperties();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setupExtraDbDataSource(Config config) {
|
||||
|
||||
int defaultPort = config.isUseDocker() ? 6432 : 5432;
|
||||
|
||||
config.setDefaultPort(defaultPort);
|
||||
config.setExtraUsernameDefault();
|
||||
config.setExtraDbPasswordDefault();
|
||||
config.setUrl("jdbc:postgresql://localhost:${port}/${databaseName}");
|
||||
config.setDriver("org.postgresql.Driver");
|
||||
config.extraDatasourceDefaults();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLocal() {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package io.ebean.test.config.platform;
|
||||
|
||||
import io.ebean.docker.commands.RedisConfig;
|
||||
import io.ebean.docker.commands.RedisContainer;
|
||||
|
||||
import java.util.Properties;
|
||||
|
||||
class RedisSetup {
|
||||
|
||||
static void run(Properties properties) {
|
||||
|
||||
String version = properties.getProperty("ebean.test.redis");
|
||||
version = properties.getProperty("ebean.test.redis.version", version);
|
||||
if (version != null) {
|
||||
RedisConfig redisConfig = new RedisConfig(version, properties);
|
||||
RedisContainer container = new RedisContainer(redisConfig);
|
||||
container.start();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
package io.ebean.test.config.platform;
|
||||
|
||||
import java.util.Properties;
|
||||
|
||||
class SqlServerSetup implements PlatformSetup {
|
||||
|
||||
@Override
|
||||
public Properties setup(Config config) {
|
||||
|
||||
config.setDatabasePlatformName();
|
||||
|
||||
config.ddlMode("dropCreate");
|
||||
config.setDefaultPort(1433);
|
||||
config.setUsernameDefault();
|
||||
config.setPassword("SqlS3rv#r");
|
||||
config.setUrl("jdbc:sqlserver://localhost:${port};databaseName=${databaseName}");
|
||||
config.setDriver("com.microsoft.sqlserver.jdbc.SQLServerDriver");
|
||||
config.datasourceDefaults();
|
||||
|
||||
return dockerProperties(config);
|
||||
}
|
||||
|
||||
private Properties dockerProperties(Config dbConfig) {
|
||||
|
||||
if (!dbConfig.isUseDocker()) {
|
||||
return new Properties();
|
||||
}
|
||||
|
||||
dbConfig.setDockerVersion("2019-GA-ubuntu-16.04");
|
||||
return dbConfig.getDockerProperties();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setupExtraDbDataSource(Config config) {
|
||||
// not supported yet
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLocal() {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package io.ebean.test.config.platform;
|
||||
|
||||
import java.util.Properties;
|
||||
|
||||
class SqliteSetup implements PlatformSetup {
|
||||
|
||||
@Override
|
||||
public Properties setup(Config config) {
|
||||
|
||||
config.ddlMode("dropCreate");
|
||||
config.setUsername("");
|
||||
config.setPassword("");
|
||||
config.setUrl("jdbc:sqlite:${databaseName}");
|
||||
config.setDriver("org.sqlite.JDBC");
|
||||
config.datasourceProperty("isolationlevel", "read_uncommitted");
|
||||
config.datasourceDefaults();
|
||||
|
||||
// return empty properties
|
||||
return new Properties();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setupExtraDbDataSource(Config config) {
|
||||
// not supported
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLocal() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package io.ebean.test.config.provider;
|
||||
|
||||
import io.ebean.config.EncryptKey;
|
||||
|
||||
class FixedEncryptKey implements EncryptKey {
|
||||
|
||||
private final String key;
|
||||
|
||||
FixedEncryptKey(String key) {
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getStringValue() {
|
||||
return key;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package io.ebean.test.config.provider;
|
||||
|
||||
import io.ebean.config.EncryptKey;
|
||||
import io.ebean.config.EncryptKeyManager;
|
||||
|
||||
class FixedEncryptKeyManager implements EncryptKeyManager {
|
||||
|
||||
private final FixedEncryptKey key;
|
||||
|
||||
FixedEncryptKeyManager(String fixedKey) {
|
||||
this.key = new FixedEncryptKey(fixedKey);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialise the key manager.
|
||||
*/
|
||||
@Override
|
||||
public void initialise() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public EncryptKey getEncryptKey(String tableName, String columnName) {
|
||||
return key;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
package io.ebean.test.config.provider;
|
||||
|
||||
import io.ebean.config.CurrentTenantProvider;
|
||||
import io.ebean.config.CurrentUserProvider;
|
||||
import io.ebean.config.DatabaseConfig;
|
||||
import io.ebean.config.EncryptKeyManager;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.Properties;
|
||||
|
||||
/**
|
||||
* Auto configuration of User and Tenant providers and Encrypt key manager for testing purposes.
|
||||
*/
|
||||
public class ProviderAutoConfig {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(ProviderAutoConfig.class);
|
||||
|
||||
private final DatabaseConfig config;
|
||||
private final Properties properties;
|
||||
|
||||
public ProviderAutoConfig(DatabaseConfig config) {
|
||||
this.config = config;
|
||||
this.properties = config.getProperties();
|
||||
}
|
||||
|
||||
public void run() {
|
||||
|
||||
int providerSetFlag = 0;
|
||||
|
||||
CurrentUserProvider provider = config.getCurrentUserProvider();
|
||||
if (provider == null) {
|
||||
providerSetFlag = 1;
|
||||
config.setCurrentUserProvider(new WhoUserProvider());
|
||||
}
|
||||
|
||||
CurrentTenantProvider tenantProvider = config.getCurrentTenantProvider();
|
||||
if (tenantProvider == null) {
|
||||
providerSetFlag += 2;
|
||||
config.setCurrentTenantProvider(new WhoTenantProvider());
|
||||
}
|
||||
|
||||
EncryptKeyManager keyManager = config.getEncryptKeyManager();
|
||||
if (keyManager == null) {
|
||||
// Must be 16 Chars for Oracle function
|
||||
String keyVal = properties.getProperty("ebean.test.encryptKey", "simple0123456789");
|
||||
log.debug("for testing - using FixedEncryptKeyManager() keyVal:{}", keyVal);
|
||||
config.setEncryptKeyManager(new FixedEncryptKeyManager(keyVal));
|
||||
}
|
||||
|
||||
if (providerSetFlag > 0) {
|
||||
log.info(msg(providerSetFlag));
|
||||
}
|
||||
}
|
||||
|
||||
String msg(int providerSetFlag) {
|
||||
String msg = msgProvider(providerSetFlag);
|
||||
String usage = msgUsage(providerSetFlag);
|
||||
return "for testing purposes "+msg+" has been configured. Use io.ebean.test.UserContext to "+usage+" in tests.";
|
||||
}
|
||||
|
||||
private String msgProvider(int providerSetFlag) {
|
||||
switch (providerSetFlag) {
|
||||
case 1: return "a current user provider";
|
||||
case 2: return "a current tenant provider";
|
||||
case 3: return "a current user and tenant provider";
|
||||
}
|
||||
return "[unexpected??]";
|
||||
}
|
||||
|
||||
private String msgUsage(int providerSetFlag) {
|
||||
switch (providerSetFlag) {
|
||||
case 1: return "set current user";
|
||||
case 2: return "set current tenant";
|
||||
case 3: return "set current user and tenant";
|
||||
}
|
||||
return "[unexpected??]";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package io.ebean.test.config.provider;
|
||||
|
||||
import io.ebean.config.CurrentTenantProvider;
|
||||
import io.ebean.test.UserContext;
|
||||
|
||||
class WhoTenantProvider implements CurrentTenantProvider{
|
||||
|
||||
@Override
|
||||
public Object currentId() {
|
||||
return UserContext.currentTenantId();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package io.ebean.test.config.provider;
|
||||
|
||||
import io.ebean.config.CurrentUserProvider;
|
||||
import io.ebean.test.UserContext;
|
||||
|
||||
class WhoUserProvider implements CurrentUserProvider {
|
||||
|
||||
@Override
|
||||
public Object currentUser() {
|
||||
return UserContext.currentUserId();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
io.ebean.test.config.AutoConfigureForTesting
|
||||
@@ -0,0 +1 @@
|
||||
io.ebean.test.CapturingLoggerFactory
|
||||
@@ -0,0 +1,41 @@
|
||||
package io.ebean.test;
|
||||
|
||||
import io.ebean.DB;
|
||||
import org.junit.Test;
|
||||
import org.test.BSimpleWithGen;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
|
||||
public class DbJsonTest {
|
||||
|
||||
@Test
|
||||
public void of() {
|
||||
|
||||
DB.find(BSimpleWithGen.class).delete();
|
||||
|
||||
BSimpleWithGen bean = new BSimpleWithGen("something");
|
||||
DB.save(bean);
|
||||
|
||||
assertThat(bean.getVersion()).isEqualTo(1);
|
||||
|
||||
DbJson.of(bean)
|
||||
.withPlaceholder("_")
|
||||
.replace("id", "whenModified")
|
||||
.assertContentMatches("/bean/example-bean.json");
|
||||
|
||||
|
||||
BSimpleWithGen bean2 = new BSimpleWithGen("other");
|
||||
DB.save(bean2);
|
||||
|
||||
final List<BSimpleWithGen> beans = DB.find(BSimpleWithGen.class).findList();
|
||||
|
||||
DbJson.of(beans)
|
||||
//.withPlaceholder("_")
|
||||
.replace("id", "whenModified")
|
||||
.assertContentMatches("/bean/example-list.json");
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
package io.ebean.test;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
public class UserContextTest {
|
||||
|
||||
@Test
|
||||
public void set() {
|
||||
|
||||
UserContext.set("u1", "t1");
|
||||
|
||||
assertEquals("u1", UserContext.currentUserId());
|
||||
assertEquals("t1", UserContext.currentTenantId());
|
||||
|
||||
UserContext.set("u2", "t1");
|
||||
|
||||
assertEquals("u2", UserContext.currentUserId());
|
||||
assertEquals("t1", UserContext.currentTenantId());
|
||||
|
||||
UserContext.set("u3", "t3");
|
||||
|
||||
assertEquals("u3", UserContext.currentUserId());
|
||||
assertEquals("t3", UserContext.currentTenantId());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setUserId() {
|
||||
|
||||
UserContext.reset();
|
||||
UserContext.setUserId("u1");
|
||||
assertEquals("u1", UserContext.currentUserId());
|
||||
assertNull(UserContext.currentTenantId());
|
||||
|
||||
UserContext.setUserId("u2");
|
||||
assertEquals("u2", UserContext.currentUserId());
|
||||
assertNull(UserContext.currentTenantId());
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void setTenantId() {
|
||||
|
||||
UserContext.reset();
|
||||
UserContext.setTenantId("t1");
|
||||
assertEquals("t1", UserContext.currentTenantId());
|
||||
assertNull(UserContext.currentUserId());
|
||||
|
||||
UserContext.setTenantId("t2");
|
||||
assertEquals("t2", UserContext.currentTenantId());
|
||||
assertNull(UserContext.currentUserId());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,163 @@
|
||||
package io.ebean.test.config.platform;
|
||||
|
||||
import io.ebean.config.ServerConfig;
|
||||
import io.ebean.datasource.DataSourceConfig;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.Properties;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
|
||||
public class ConfigTest {
|
||||
|
||||
@Test
|
||||
public void trimExtensions() {
|
||||
|
||||
Config config = new Config("db", "db", "db", new ServerConfig());
|
||||
|
||||
assertThat(config.trimExtensions("a,b")).isEqualTo("a,b");
|
||||
assertThat(config.trimExtensions(" a , b ")).isEqualTo("a,b");
|
||||
assertThat(config.trimExtensions(" a , , b ")).isEqualTo("a,b");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void extraDbProperties_basic() {
|
||||
|
||||
Properties p = new Properties();
|
||||
p.setProperty("ebean.test.extraDb", "other");
|
||||
|
||||
ServerConfig serverConfig = new ServerConfig();
|
||||
serverConfig.loadFromProperties(p);
|
||||
|
||||
Config config = new Config("other", "postgres", "other", serverConfig);
|
||||
|
||||
PostgresSetup postgresSetup = new PostgresSetup();
|
||||
postgresSetup.setupExtraDbDataSource(config);
|
||||
|
||||
DataSourceConfig ds = serverConfig.getDataSourceConfig();
|
||||
assertThat(ds.getUsername()).isEqualTo("other");
|
||||
|
||||
p = serverConfig.getProperties();
|
||||
assertThat(p.getProperty("datasource.other.username")).isEqualTo("other");
|
||||
assertThat(p.getProperty("datasource.other.password")).isEqualTo("test");
|
||||
assertThat(p.getProperty("datasource.other.url")).isEqualTo("jdbc:postgresql://localhost:6432/other");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void extraDbProperties_basic_extraDb_dbName() {
|
||||
|
||||
Properties p = new Properties();
|
||||
p.setProperty("ebean.test.extraDb.dbName", "other");
|
||||
|
||||
ServerConfig serverConfig = new ServerConfig();
|
||||
serverConfig.loadFromProperties(p);
|
||||
|
||||
Config config = new Config("other", "postgres", "other", serverConfig);
|
||||
|
||||
PostgresSetup postgresSetup = new PostgresSetup();
|
||||
postgresSetup.setupExtraDbDataSource(config);
|
||||
|
||||
DataSourceConfig ds = serverConfig.getDataSourceConfig();
|
||||
assertThat(ds.getUsername()).isEqualTo("other");
|
||||
|
||||
p = serverConfig.getProperties();
|
||||
assertThat(p.getProperty("datasource.other.username")).isEqualTo("other");
|
||||
assertThat(p.getProperty("datasource.other.password")).isEqualTo("test");
|
||||
assertThat(p.getProperty("datasource.other.url")).isEqualTo("jdbc:postgresql://localhost:6432/other");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void extraDbProperties_withOptions() {
|
||||
|
||||
Properties p = new Properties();
|
||||
p.setProperty("ebean.test.extraDb", "other1");
|
||||
p.setProperty("ebean.test.extraDb.dbName", "other_db_name");
|
||||
p.setProperty("ebean.test.extraDb.username", "other_user");
|
||||
p.setProperty("ebean.test.extraDb.password", "other_pwd");
|
||||
p.setProperty("ebean.test.extraDb.url", "other_url");
|
||||
|
||||
ServerConfig serverConfig = new ServerConfig();
|
||||
serverConfig.setName("scOther");
|
||||
serverConfig.loadFromProperties(p);
|
||||
|
||||
Config config = new Config("other_db_name", "postgres", "other_db_name", serverConfig);
|
||||
|
||||
PostgresSetup postgresSetup = new PostgresSetup();
|
||||
postgresSetup.setupExtraDbDataSource(config);
|
||||
|
||||
|
||||
DataSourceConfig ds = serverConfig.getDataSourceConfig();
|
||||
assertThat(ds.getUsername()).isEqualTo("other_user");
|
||||
|
||||
p = serverConfig.getProperties();
|
||||
assertThat(p.getProperty("datasource.other_db_name.username")).isEqualTo("other_user");
|
||||
assertThat(p.getProperty("datasource.other_db_name.password")).isEqualTo("other_pwd");
|
||||
assertThat(p.getProperty("datasource.other_db_name.url")).isEqualTo("other_url");
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void extraDbProperties_withExtraDbOptions() {
|
||||
|
||||
Properties sourceProperties = new Properties();
|
||||
sourceProperties.setProperty("ebean.test.dbName", "main");
|
||||
sourceProperties.setProperty("ebean.test.extraDb.dbName", "central");
|
||||
|
||||
ServerConfig serverConfig = new ServerConfig();
|
||||
serverConfig.setName("main");
|
||||
serverConfig.loadFromProperties(sourceProperties);
|
||||
|
||||
Config config = new Config("main", "postgres", "main", serverConfig);
|
||||
|
||||
PostgresSetup postgresSetup = new PostgresSetup();
|
||||
postgresSetup.setup(config);
|
||||
|
||||
Properties mainProps = serverConfig.getProperties();
|
||||
assertThat(mainProps.getProperty("datasource.main.username")).isEqualTo("main");
|
||||
|
||||
|
||||
ServerConfig centralConfig = new ServerConfig();
|
||||
centralConfig.setName("central");
|
||||
centralConfig.loadFromProperties(sourceProperties);
|
||||
|
||||
Config extraConfig = new Config("central", "postgres", "central", serverConfig);
|
||||
|
||||
postgresSetup = new PostgresSetup();
|
||||
postgresSetup.setupExtraDbDataSource(extraConfig);
|
||||
|
||||
Properties centralProps = serverConfig.getProperties();
|
||||
assertThat(centralProps.getProperty("datasource.central.username")).isEqualTo("central");
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void ignoreDockerShutdown() {
|
||||
|
||||
Properties sourceProperties = new Properties();
|
||||
ServerConfig serverConfig = new ServerConfig();
|
||||
serverConfig.loadFromProperties(sourceProperties);
|
||||
|
||||
Config config = new Config("main", "postgres", "main", serverConfig);
|
||||
|
||||
assertThat(config.ignoreDockerShutdown("./src/test/resources/logback-test.xml")).isTrue();
|
||||
assertThat(config.ignoreDockerShutdown("./src/test/resources/file-does-not-exist")).isFalse();
|
||||
|
||||
assertThat(config.ignoreDockerShutdown("~/.ebean/ignore-docker-shutdown")).isTrue();
|
||||
assertThat(config.ignoreDockerShutdown()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void ignoreDockerShutdown_viaProperties() {
|
||||
|
||||
Properties sourceProperties = new Properties();
|
||||
sourceProperties.setProperty("ebean.test.localDevelopment", "./src/test/resources/logback-test.xml");
|
||||
|
||||
ServerConfig serverConfig = new ServerConfig();
|
||||
serverConfig.loadFromProperties(sourceProperties);
|
||||
|
||||
Config config = new Config("main", "postgres", "main", serverConfig);
|
||||
assertThat(config.ignoreDockerShutdown()).isTrue();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package io.ebean.test.config.provider;
|
||||
|
||||
import io.ebean.config.ServerConfig;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
public class ProviderAutoConfigTest {
|
||||
|
||||
private ProviderAutoConfig config = new ProviderAutoConfig(new ServerConfig());
|
||||
|
||||
@Test
|
||||
public void msg() {
|
||||
|
||||
assertEquals(config.msg(1), "for testing purposes a current user provider has been configured. Use io.ebean.test.UserContext to set current user in tests.");
|
||||
assertEquals(config.msg(2), "for testing purposes a current tenant provider has been configured. Use io.ebean.test.UserContext to set current tenant in tests.");
|
||||
assertEquals(config.msg(3), "for testing purposes a current user and tenant provider has been configured. Use io.ebean.test.UserContext to set current user and tenant in tests.");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void msgUnexpected() {
|
||||
// rather than fail ...
|
||||
assertEquals(config.msg(4), "for testing purposes [unexpected??] has been configured. Use io.ebean.test.UserContext to [unexpected??] in tests.");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
package org.test;
|
||||
|
||||
import io.ebean.annotation.WhenModified;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.Transient;
|
||||
import javax.persistence.Version;
|
||||
import java.time.Instant;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@Entity
|
||||
public class BSimpleWithGen {
|
||||
|
||||
@Id
|
||||
private Integer id;
|
||||
|
||||
private String name;
|
||||
|
||||
@Transient
|
||||
private Map<String, List<String>> someMap;
|
||||
|
||||
@WhenModified
|
||||
private Instant whenModified;
|
||||
|
||||
@Version
|
||||
private long version;
|
||||
|
||||
public BSimpleWithGen(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public Integer getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Integer id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public Map<String, List<String>> getSomeMap() {
|
||||
return someMap;
|
||||
}
|
||||
|
||||
public void setSomeMap(Map<String, List<String>> someMap) {
|
||||
this.someMap = someMap;
|
||||
}
|
||||
|
||||
public Instant getWhenModified() {
|
||||
return whenModified;
|
||||
}
|
||||
|
||||
public long getVersion() {
|
||||
return version;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
package org.test;
|
||||
|
||||
import io.ebean.DB;
|
||||
import io.ebean.annotation.Transactional;
|
||||
import io.ebean.test.ForTests;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
|
||||
public class ForTestsBeforeAfterTest {
|
||||
|
||||
private ForTests.RollbackAll rollbackAll;
|
||||
|
||||
@Before
|
||||
public void before() {
|
||||
rollbackAll = ForTests.createRollbackAll();
|
||||
}
|
||||
|
||||
@After
|
||||
public void after() {
|
||||
rollbackAll.close();
|
||||
assertThat(getCount()).isEqualTo(0);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void createRollbackAll() {
|
||||
|
||||
doInsert();
|
||||
assertThat(getCount()).isEqualTo(1);
|
||||
}
|
||||
|
||||
private int getCount() {
|
||||
return DB.find(BSimpleWithGen.class)
|
||||
.where().eq("name", "ForTestsBeforeAfterTest")
|
||||
.findCount();
|
||||
}
|
||||
|
||||
@Transactional
|
||||
private void doInsert() {
|
||||
|
||||
BSimpleWithGen bean = new BSimpleWithGen("ForTestsBeforeAfterTest");
|
||||
DB.save(bean);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
package org.test;
|
||||
|
||||
import io.ebean.DB;
|
||||
import io.ebean.Transaction;
|
||||
import io.ebean.annotation.Transactional;
|
||||
import io.ebean.test.ForTests;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
public class ForTestsTest {
|
||||
|
||||
@Test
|
||||
public void noTransactional_expect_noTransactionEnterExitCalled() {
|
||||
|
||||
ForTests.noTransactional(this::checkForTransactional);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void enableTransactional() {
|
||||
|
||||
ForTests.enableTransactional(false);
|
||||
|
||||
checkForTransactional();
|
||||
|
||||
ForTests.enableTransactional(true);
|
||||
}
|
||||
|
||||
@Transactional
|
||||
private void checkForTransactional() {
|
||||
|
||||
final Transaction transaction = DB.currentTransaction();
|
||||
assertThat(transaction).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void rollbackTransactions() {
|
||||
|
||||
DB.find(BSimpleWithGen.class).delete();
|
||||
|
||||
ForTests.rollbackAll(this::doInsert);
|
||||
|
||||
final int count = DB.find(BSimpleWithGen.class).findCount();
|
||||
assertThat(count).isEqualTo(0);
|
||||
}
|
||||
|
||||
@Transactional
|
||||
private void doInsert() {
|
||||
|
||||
BSimpleWithGen bean = new BSimpleWithGen("doInsert");
|
||||
DB.save(bean);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
datasource:
|
||||
db:
|
||||
username: sa
|
||||
password:
|
||||
databaseUrl: jdbc:h2:mem:tests
|
||||
databaseDriver: org.h2.Driver
|
||||
|
||||
ebean:
|
||||
# migration:
|
||||
# run: false
|
||||
#
|
||||
# ddl:
|
||||
# generate: true
|
||||
# run: true
|
||||
## createOnly: true
|
||||
|
||||
docstore:
|
||||
url: http://127.0.0.1:9200
|
||||
active: true
|
||||
generateMapping: true
|
||||
dropCreate: true
|
||||
# useDocker: true
|
||||
elasticVersion: 5.6
|
||||
|
||||
# create: true
|
||||
|
||||
test:
|
||||
redis: latest
|
||||
platform: mariadb #, postgres, mysql, mariadb, oracle, sqlserver, hana
|
||||
# useDocker: false
|
||||
# dockerMode: dropCreate
|
||||
ddlMode: dropCreate # none | dropCreate | create | migrations
|
||||
dbName: junk
|
||||
postgres:
|
||||
version: 9.6
|
||||
extensions: pgcryto, hstore
|
||||
username: asd
|
||||
password: test
|
||||
url: asd
|
||||
driver: asd
|
||||
|
||||
|
||||
|
||||
docker:
|
||||
postgres:
|
||||
# port: 6432
|
||||
version: 9.6
|
||||
extensions: pgcryto, hstore
|
||||
username: ${test_db}
|
||||
password: test
|
||||
databaseUrl: jdbc:postgresql://localhost:6432/${test_db}
|
||||
databaseDriver: org.postgresql.Driver
|
||||
|
||||
mysql:
|
||||
version: 5.6
|
||||
username: ${test_db}
|
||||
password: test
|
||||
databaseUrl: jdbc:mysql://localhost:4306/${test_db}
|
||||
databaseDriver: com.mysql.jdbc.Driver
|
||||
|
||||
sqlserver:
|
||||
version: 2017-CE
|
||||
username: ${test_db}
|
||||
password: SqlS3rv#r
|
||||
databaseUrl: jdbc:sqlserver://localhost:1433;databaseName=${test_db}
|
||||
databaseDriver: com.microsoft.sqlserver.jdbc.SQLServerDriver
|
||||
|
||||
oracle:
|
||||
username: ${test_db}
|
||||
password: test
|
||||
databaseUrl: jdbc:oracle:thin:@127.0.0.1:1521:XE
|
||||
databaseDriver: oracle.jdbc.driver.OracleDriver
|
||||
|
||||
hana:
|
||||
username: ${test_db}
|
||||
password: HXEHana1
|
||||
databaseUrl: jdbc:sap://localhost:39017/?databaseName=HXE
|
||||
databaseDriver: com.sap.db.jdbc.Driver
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"id": _,
|
||||
"name": "something",
|
||||
"whenModified": _,
|
||||
"version": 1
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
[ {
|
||||
"id": "*",
|
||||
"name": "something",
|
||||
"whenModified": "*",
|
||||
"version": 1
|
||||
}, {
|
||||
"id": "*",
|
||||
"name": "other",
|
||||
"whenModified": "*",
|
||||
"version": 1
|
||||
} ]
|
||||
@@ -0,0 +1,21 @@
|
||||
postgres.version=9.6
|
||||
postgres.dbName=test_db
|
||||
postgres.dbUser=test_user
|
||||
postgres.dbPassword=test
|
||||
postgres.dbExtensions=hstore,pgcrypto
|
||||
|
||||
|
||||
sqlserver.version=2017-CU2
|
||||
#sqlserver.port=1433
|
||||
#sqlserver.dbName=test_db
|
||||
#sqlserver.dbUser=test_user
|
||||
#sqlserver.dbPassword=SqlS3rv#r
|
||||
|
||||
|
||||
hana.version=2.00.033.00.20180925.2
|
||||
hana.port=39117
|
||||
hana.instanceNumber=91
|
||||
hana.passwordsUrl=file:///hana/mounts/passwords.json
|
||||
hana.mountsDirectory=/data/dockermounts
|
||||
# agree to the SAP license (https://www.sap.com/docs/download/cmp/2016/06/sap-hana-express-dev-agmt-and-exhibit.pdf)
|
||||
hana.agreeToSapLicense=false
|
||||
@@ -0,0 +1,2 @@
|
||||
entity-packages: org.test
|
||||
transactional-packages: org.test
|
||||
@@ -0,0 +1,22 @@
|
||||
<configuration scan="true" scanPeriod="10 seconds">
|
||||
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
|
||||
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<root level="INFO">
|
||||
<appender-ref ref="STDOUT"/>
|
||||
</root>
|
||||
|
||||
<logger name="org.avaje" level="TRACE"/>
|
||||
<logger name="io.ebean" level="INFO"/>
|
||||
|
||||
<logger name="io.ebean.docker" level="TRACE"/>
|
||||
<logger name="io.ebean.DDL" level="DEBUG"/>
|
||||
|
||||
<logger name="io.ebean.SQL" level="TRACE"/>
|
||||
<logger name="io.ebean.TXN" level="TRACE"/>
|
||||
<logger name="io.ebean.SUM" level="TRACE"/>
|
||||
|
||||
</configuration>
|
||||
Reference in New Issue
Block a user