Skip to content

Commit 7d9e967

Browse files
authored
Merge pull request #52 from mlozbin-cybervisiontech/feature/CDAP-15658-automated-db-integration-tests
CDAP-15658 Make the DB integration tests automated
2 parents 3b2820c + e59c2fd commit 7d9e967

File tree

16 files changed

+196
-48
lines changed

16 files changed

+196
-48
lines changed

README.md

Lines changed: 58 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,4 +18,61 @@ mvn clean test \
1818
-DauroraPostgresql.clusterEndpoint=pginstance.cxywmbgwp60k.eu-central-1.rds.amazonaws.com -DauroraPostgresql.port=5432 \
1919
-DauroraPostgresql.database=cdappg -DauroraPostgresql.username=cdap -DauroraPostgresql.password=cdap
2020
-DjdbcDriversJars="/jdbc/drivers/jars/some.jar, "
21-
```
21+
```
22+
23+
## Setup Local Environment
24+
MySQL, Postgresql, MSSQL, DB2 are using prebuild images.
25+
26+
Oracle DB image should be build separately.
27+
28+
Netezza requires VMware Player for running Netezza emulator.
29+
30+
* [Install Docker Compose](https://docs.docker.com/compose/install/)
31+
* Build local docker images
32+
* [Build Oracle DB docker image version 12.1.0.2-ee](https://github.com/oracle/docker-images/tree/master/OracleDatabase/SingleInstance)
33+
* Start docker environment by running commands:
34+
```bash
35+
cd docker-compose/db-plugins-env/
36+
docker-compose up -d
37+
```
38+
* [Install and start Netezza emulator](http://dwgeek.com/install-vmware-player-netezza-emulator.html/)
39+
40+
### Properties
41+
#### MySQL
42+
* **mysql.host** - Server host. Default: localhost.
43+
* **mysql.port** - Server port. Default: 3306.
44+
* **mysql.database** - Server namespace for test databases. Default: mydb.
45+
* **mysql.username** - Server username Default: root.
46+
* **mysql.password** - Server password. Default: 123Qwe123.
47+
#### Postgresql
48+
* **postgresql.host** - Server host. Default: localhost.
49+
* **postgresql.port** - Server port. Default: 5432.
50+
* **postgresql.database** - Server namespace for test databases. Default: mydb.
51+
* **postgresql.username** - Server username Default: postgres.
52+
* **postgresql.password** - Server password. Default: 123Qwe123.
53+
#### MSSQL
54+
* **mssql.host** - Server host. Default: localhost.
55+
* **mssql.port** - Server port. Default: 1433.
56+
* **mssql.database** - Server namespace for test databases. Default: tempdb.
57+
* **mssql.username** - Server username Default: sa.
58+
* **mssql.password** - Server password. Default: 123Qwe123.
59+
#### DB2
60+
* **db2.host** - Server host. Default: localhost.
61+
* **db2.port** - Server port. Default: 50000.
62+
* **db2.database** - Server namespace for test databases. Default: mydb.
63+
* **db2.username** - Server username Default: db2inst1.
64+
* **db2.password** - Server password. Default: 123Qwe123.
65+
#### Oracle
66+
* **oracle.host** - Server host. Default: localhost.
67+
* **oracle.port** - Server port. Default: 1521.
68+
* **oracle.username** - Server username Default: SYSTEM.
69+
* **oracle.password** - Server password. Default: 123Qwe123.
70+
* **oracle.database** - Server sid/database. Default: cdap.
71+
* **oracle.connectionType** - Server connection type (service/sid) Default: sid.
72+
#### Netezza
73+
* **netezza.host** - Server host. Default: localhost.
74+
* **netezza.port** - Server port. Default: 5480.
75+
* **netezza.database** - Server namespace for test databases. Default: mydb.
76+
* **netezza.username** - Server username Default: admin.
77+
* **netezza.password** - Server password. Default: password.
78+

database-commons/src/main/java/io/cdap/plugin/db/batch/sink/AbstractDBSink.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -350,6 +350,10 @@ protected boolean isFieldCompatible(Schema.Field field, ResultSetMetaData metada
350350

351351
int sqlType = metadata.getColumnType(index);
352352

353+
return isFieldCompatible(fieldType, fieldLogicalType, sqlType);
354+
}
355+
356+
protected boolean isFieldCompatible(Schema.Type fieldType, Schema.LogicalType fieldLogicalType, int sqlType) {
353357
// Handle logical types first
354358
if (fieldLogicalType != null) {
355359
switch (fieldLogicalType) {
@@ -375,7 +379,7 @@ protected boolean isFieldCompatible(Schema.Field field, ResultSetMetaData metada
375379
|| sqlType == Types.BIT;
376380
case INT:
377381
return sqlType == Types.INTEGER
378-
|| sqlType == Types.SMALLINT
382+
|| sqlType == Types.SMALLINT
379383
|| sqlType == Types.TINYINT;
380384
case LONG:
381385
return sqlType == Types.BIGINT;

database-commons/src/test/java/io/cdap/plugin/db/batch/DatabasePluginTestBase.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ protected void testDBSinkValidation(String inputDatasetName, String appName, Sch
137137

138138
protected void writeDataForInvalidDataWriteTest(String inputDatasetName, String stringColumnName) throws Exception {
139139
Schema validSchema = Schema.recordOf(
140-
"wrongDBRecord",
140+
"validDBRecord",
141141
Schema.Field.of("ID", Schema.of(Schema.Type.INT)),
142142
Schema.Field.of(stringColumnName, Schema.of(Schema.Type.STRING))
143143
);

db2-plugin/src/main/java/io/cdap/plugin/db2/DB2Record.java

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,12 @@
1818

1919
import io.cdap.cdap.api.data.format.StructuredRecord;
2020
import io.cdap.cdap.api.data.schema.Schema;
21+
import io.cdap.cdap.etl.api.validation.InvalidStageException;
2122
import io.cdap.plugin.db.ColumnType;
2223
import io.cdap.plugin.db.DBRecord;
2324
import io.cdap.plugin.db.SchemaReader;
2425

26+
import java.sql.PreparedStatement;
2527
import java.sql.ResultSet;
2628
import java.sql.ResultSetMetaData;
2729
import java.sql.SQLException;
@@ -31,7 +33,7 @@
3133
* Writable class for DB2 Source/Sink.
3234
*/
3335
public class DB2Record extends DBRecord {
34-
36+
private static final int ILLEGAL_CONVERSION_ERROR_CODE = -4474;
3537
/**
3638
* Used in map-reduce. Do not remove.
3739
*/
@@ -58,6 +60,21 @@ protected void handleField(ResultSet resultSet, StructuredRecord.Builder recordB
5860
}
5961
}
6062

63+
@Override
64+
public void write(PreparedStatement stmt) throws SQLException {
65+
// DB2 driver throws SQLException if data conversation fails, but SQLException is skipped.
66+
// So we need to throw another exception to fail pipeline in this case.
67+
try {
68+
super.write(stmt);
69+
} catch (SQLException e) {
70+
if (e.getErrorCode() == ILLEGAL_CONVERSION_ERROR_CODE) {
71+
throw new InvalidStageException(e.getMessage(), e);
72+
} else {
73+
throw e;
74+
}
75+
}
76+
}
77+
6178
private void handleSpecificType(ResultSet resultSet,
6279
StructuredRecord.Builder recordBuilder,
6380
Schema.Field field, int columnIndex) throws SQLException {

db2-plugin/src/test/java/io/cdap/plugin/db2/Db2PluginTestBase.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -74,11 +74,11 @@ public class Db2PluginTestBase extends DatabasePluginTestBase {
7474
}
7575

7676
protected static final Map<String, String> BASE_PROPS = ImmutableMap.<String, String>builder()
77-
.put(ConnectionConfig.HOST, System.getProperty("db2.host"))
78-
.put(ConnectionConfig.PORT, System.getProperty("db2.port"))
79-
.put(ConnectionConfig.DATABASE, System.getProperty("db2.database"))
80-
.put(ConnectionConfig.USER, System.getProperty("db2.username"))
81-
.put(ConnectionConfig.PASSWORD, System.getProperty("db2.password"))
77+
.put(ConnectionConfig.HOST, System.getProperty("db2.host", "localhost"))
78+
.put(ConnectionConfig.PORT, System.getProperty("db2.port", "50000"))
79+
.put(ConnectionConfig.DATABASE, System.getProperty("db2.database", "mydb"))
80+
.put(ConnectionConfig.USER, System.getProperty("db2.username", "db2inst1"))
81+
.put(ConnectionConfig.PASSWORD, System.getProperty("db2.password", "123Qwe123"))
8282
.put(ConnectionConfig.JDBC_PLUGIN_NAME, JDBC_DRIVER_NAME)
8383
.build();
8484

db2-plugin/src/test/java/io/cdap/plugin/db2/Db2SinkTestRun.java

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ public void testDBSinkWithInvalidFieldLogicalType() throws Exception {
9898

9999
@Test
100100
public void testDBSinkWithDBSchemaAndInvalidData() throws Exception {
101-
String stringColumnName = "CHAR_COL";
101+
String stringColumnName = "BINARY_COL";
102102
startPipelineAndWriteInvalidData(stringColumnName, getSinkConfig(), DATAPIPELINE_ARTIFACT);
103103
try (Connection conn = createConnection();
104104
Statement stmt = conn.createStatement();
@@ -169,29 +169,29 @@ public void testDBSink(String appName, String inputDatasetName, boolean setInput
169169
}
170170

171171
@Override
172-
protected void writeDataForInvalidDataWriteTest(String inputDatasetName, String stringColumnName) throws Exception {
172+
protected void writeDataForInvalidDataWriteTest(String inputDatasetName, String columnName) throws Exception {
173173
Schema validSchema = Schema.recordOf(
174-
"wrongDBRecord",
175-
Schema.Field.of(stringColumnName, Schema.of(Schema.Type.STRING))
174+
"validDBRecord",
175+
Schema.Field.of(columnName, Schema.of(Schema.Type.BYTES))
176176
);
177177

178178
Schema invalidSchema = Schema.recordOf(
179179
"wrongDBRecord",
180-
Schema.Field.of(stringColumnName, Schema.of(Schema.Type.INT))
180+
Schema.Field.of(columnName, Schema.of(Schema.Type.INT))
181181
);
182182

183183
// add some data to the input table
184184
DataSetManager<Table> inputManager = getDataset(inputDatasetName);
185185

186186
List<StructuredRecord> inputRecords = new ArrayList<>();
187187
inputRecords.add(StructuredRecord.builder(validSchema)
188-
.set(stringColumnName, "user1")
188+
.set(columnName, "user1".getBytes())
189189
.build());
190190
inputRecords.add(StructuredRecord.builder(invalidSchema)
191-
.set(stringColumnName, 1)
191+
.set(columnName, 1)
192192
.build());
193193
inputRecords.add(StructuredRecord.builder(validSchema)
194-
.set(stringColumnName, "user3")
194+
.set(columnName, "user3".getBytes())
195195
.build());
196196
MockSource.writeInput(inputManager, inputRecords);
197197
}
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
# Copyright © 2019 Cask Data, Inc.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License"); you may not
4+
# use this file except in compliance with the License. You may obtain a copy of
5+
# the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11+
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12+
# License for the specific language governing permissions and limitations under
13+
# the License.
14+
15+
version: '3'
16+
services:
17+
mysql:
18+
image: mysql:8.0.16
19+
ports:
20+
- 3306:3306
21+
environment:
22+
- MYSQL_ROOT_PASSWORD=123Qwe123
23+
- MYSQL_DATABASE=mydb
24+
25+
postgres:
26+
image: postgres:11.3-alpine
27+
ports:
28+
- 5432:5432
29+
environment:
30+
- POSTGRES_PASSWORD=123Qwe123
31+
- POSTGRES_DB=mydb
32+
33+
mssql:
34+
image: mcr.microsoft.com/mssql/server:2017-CU14-ubuntu
35+
ports:
36+
- 1433:1433
37+
environment:
38+
- SA_PASSWORD=123Qwe123
39+
- MSSQL_DB=mydb
40+
- ACCEPT_EULA=Y
41+
42+
db2:
43+
image: ibmcom/db2:11.5.0.0
44+
ports:
45+
- 50000:50000
46+
environment:
47+
- DB2INST1_PASSWORD=123Qwe123
48+
- DBNAME=mydb
49+
- LICENSE=accept
50+
privileged: true
51+
52+
oracle:
53+
image: oracle/database:12.1.0.2-ee
54+
ports:
55+
- 1521:1521
56+
environment:
57+
- ORACLE_SID=cdap
58+
- ORACLE_PDB=mydb
59+
- ORACLE_PWD=123Qwe123

mssql-plugin/src/test/java/io/cdap/plugin/mssql/SqlServerPluginTestBase.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -82,11 +82,11 @@ public class SqlServerPluginTestBase extends DatabasePluginTestBase {
8282
public static final TestConfiguration CONFIG = new TestConfiguration("explore.enabled", false);
8383

8484
protected static final Map<String, String> BASE_PROPS = ImmutableMap.<String, String>builder()
85-
.put(ConnectionConfig.HOST, System.getProperty("mssql.host"))
86-
.put(ConnectionConfig.PORT, System.getProperty("mssql.port"))
87-
.put(ConnectionConfig.DATABASE, System.getProperty("mssql.database"))
88-
.put(ConnectionConfig.USER, System.getProperty("mssql.username"))
89-
.put(ConnectionConfig.PASSWORD, System.getProperty("mssql.password"))
85+
.put(ConnectionConfig.HOST, System.getProperty("mssql.host", "localhost"))
86+
.put(ConnectionConfig.PORT, System.getProperty("mssql.port", "1433"))
87+
.put(ConnectionConfig.DATABASE, System.getProperty("mssql.database", "tempdb"))
88+
.put(ConnectionConfig.USER, System.getProperty("mssql.username", "sa"))
89+
.put(ConnectionConfig.PASSWORD, System.getProperty("mssql.password", "123Qwe123"))
9090
.put(ConnectionConfig.JDBC_PLUGIN_NAME, JDBC_DRIVER_NAME)
9191
.build();
9292

mysql-plugin/src/test/java/io/cdap/plugin/mysql/MysqlPluginTestBase.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -78,11 +78,11 @@ public class MysqlPluginTestBase extends DatabasePluginTestBase {
7878
}
7979

8080
protected static final Map<String, String> BASE_PROPS = ImmutableMap.<String, String>builder()
81-
.put(ConnectionConfig.HOST, System.getProperty("mysql.host"))
82-
.put(ConnectionConfig.PORT, System.getProperty("mysql.port"))
83-
.put(ConnectionConfig.DATABASE, System.getProperty("mysql.database"))
84-
.put(ConnectionConfig.USER, System.getProperty("mysql.username"))
85-
.put(ConnectionConfig.PASSWORD, System.getProperty("mysql.password"))
81+
.put(ConnectionConfig.HOST, System.getProperty("mysql.host", "localhost"))
82+
.put(ConnectionConfig.PORT, System.getProperty("mysql.port", "3306"))
83+
.put(ConnectionConfig.DATABASE, System.getProperty("mysql.database", "mydb"))
84+
.put(ConnectionConfig.USER, System.getProperty("mysql.username", "root"))
85+
.put(ConnectionConfig.PASSWORD, System.getProperty("mysql.password", "123Qwe123"))
8686
.put(ConnectionConfig.JDBC_PLUGIN_NAME, JDBC_DRIVER_NAME)
8787
.build();
8888

netezza-plugin/src/main/java/io/cdap/plugin/netezza/NetezzaDBRecord.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333
*/
3434
public class NetezzaDBRecord extends DBRecord {
3535

36-
private static final int INTERVAL = 101;
36+
public static final int INTERVAL = 101;
3737

3838
private static final Set<Integer> netezzaTypes = ImmutableSet.of(
3939
Types.VARBINARY,

0 commit comments

Comments
 (0)