Skip to content

Commit 4e7e799

Browse files
committed
CVV_COLUMNS table integration test
1. Added JdbcUtils and methods 2. Added svv_columns.sql for retrieving table's data 3. Added SvvColumnsTest test 4. Added CsvUtil and methods 5. Added Gradle reporting plugin 6. Setting dumper-integration-tests as a root independent Gradle project 7. Added required EnvVars to build.gradle
1 parent a99dd62 commit 4e7e799

File tree

15 files changed

+366
-202
lines changed

15 files changed

+366
-202
lines changed

dumper-integration-tests/gradlew

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../gradlew
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../gradlew.bat
Lines changed: 30 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,28 @@
1+
/*
2+
* Copyright 2022 Google LLC
3+
* Copyright 2013-2021 CompilerWorks
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
117
buildscript {
218
repositories {
319
mavenCentral()
420
}
5-
dependencies {
6-
classpath 'com.google.protobuf:protobuf-gradle-plugin:0.8.18'
7-
}
821
}
922

1023
plugins {
1124
id 'java'
12-
id "com.google.protobuf" version "0.8.18"
25+
id 'com.adarshr.test-logger' version '3.0.0'
1326
}
1427

1528
sourceCompatibility = 1.8
@@ -22,28 +35,30 @@ repositories {
2235
}
2336

2437
dependencies {
25-
implementation 'org.codehaus.groovy:groovy-all:3.0.5'
38+
implementation 'org.codehaus.groovy:groovy-all:3.0.10'
39+
implementation 'com.google.guava:guava:31.1-jre'
2640
implementation 'org.testng:testng:7.5'
2741
implementation 'org.slf4j:slf4j-api:2.0.0-alpha5'
2842
implementation 'org.slf4j:slf4j-jdk14:2.0.0-alpha5'
29-
implementation 'com.amazon.redshift:redshift-jdbc42:2.1.0.6'
3043
implementation 'commons-io:commons-io:2.11.0'
31-
implementation 'org.apache.commons:commons-collections4:4.4'
32-
implementation 'com.google.guava:guava:31.0.1-jre'
3344
implementation 'com.opencsv:opencsv:5.6'
34-
implementation 'com.google.protobuf:protobuf-gradle-plugin:0.8.18'
35-
implementation 'com.google.protobuf:protobuf-java:3.20.1'
45+
46+
implementation 'com.amazon.redshift:redshift-jdbc42:2.1.0.7'
47+
annotationProcessor 'com.google.auto.value:auto-value:1.9'
48+
compileOnly 'com.google.auto.value:auto-value-annotations:1.9'
3649
}
3750

3851
test {
52+
ignoreFailures = true
53+
3954
useTestNG {
4055
preserveOrder true
4156
systemProperty 'java.util.logging.config.file', 'src/main/resources/logging.properties'
4257
}
43-
}
4458

45-
protobuf {
46-
protoc {
47-
artifact = 'com.google.protobuf:protoc:3.20.1'
48-
}
59+
def envFiles = ['EXPORT_PATH']
60+
envFiles.each { if (System.env[it] != null) inputs.dir(System.env[it])}
61+
62+
def envProperties = ['DB_URL', 'USERNAME', 'PASSWORD']
63+
envProperties.each { if (System.env[it] != null) inputs.property it, System.env[it]}
4964
}

dumper-integration-tests/redshift-tests/src/main/java/com/google/base/TestBase.java

Lines changed: 0 additions & 59 deletions
This file was deleted.
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
/*
2+
* Copyright 2022 Google LLC
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package com.google.edwmigration.dumper.base;
17+
18+
import static java.lang.String.format;
19+
import static java.lang.System.lineSeparator;
20+
import static org.testng.Assert.assertEquals;
21+
22+
import com.google.common.base.Joiner;
23+
import com.google.common.collect.LinkedHashMultiset;
24+
import com.opencsv.CSVParser;
25+
import com.opencsv.CSVParserBuilder;
26+
import org.junit.Assert;
27+
import org.slf4j.Logger;
28+
import org.slf4j.LoggerFactory;
29+
30+
/** Base class with general values for all TestNG test suites */
31+
public abstract class TestBase {
32+
33+
public static final CSVParser CSV_PARSER = new CSVParserBuilder().withEscapeChar('\0').build();
34+
private static final Logger LOGGER = LoggerFactory.getLogger(TestBase.class);
35+
36+
/**
37+
* @param dbMultiset List of extracted from DB items.
38+
* @param csvMultiset List of uploaded from Avro items.
39+
*/
40+
public static void assertDbCsvDataEqual(
41+
LinkedHashMultiset<?> dbMultiset, LinkedHashMultiset<?> csvMultiset) {
42+
LinkedHashMultiset<?> dbMultisetCopy = LinkedHashMultiset.create(dbMultiset);
43+
csvMultiset.forEach(dbMultiset::remove);
44+
dbMultisetCopy.forEach(csvMultiset::remove);
45+
46+
String dbListForLogs = lineSeparator() + Joiner.on("").join(dbMultiset);
47+
String csvListForLogs = lineSeparator() + Joiner.on("").join(csvMultiset);
48+
49+
if (dbMultiset.isEmpty() && csvMultiset.isEmpty()) {
50+
LOGGER.info("DB view and CSV file are equal");
51+
} else if (!dbMultiset.isEmpty() && !csvMultiset.isEmpty()) {
52+
Assert.fail(
53+
format(
54+
"DB view and CSV file have mutually exclusive row(s)%n"
55+
+ "DB view has %d different row(s): %s%n"
56+
+ "CSV file has %d different row(s): %s",
57+
dbMultiset.size(), dbListForLogs, csvMultiset.size(), csvListForLogs));
58+
} else if (!dbMultiset.isEmpty()) {
59+
Assert.fail(format("DB view has %d extra row(s):%n%s", dbMultiset.size(), dbListForLogs));
60+
} else if (!csvMultiset.isEmpty()) {
61+
Assert.fail(format("CSV file has %d extra row(s):%n%s", csvMultiset.size(), csvListForLogs));
62+
}
63+
}
64+
65+
/**
66+
* @param dbHeaders Multiset of headers from DB.
67+
* @param csvHeaders Multiset of headers from CSV.
68+
*/
69+
public static void assertDbCsvHeadersEqual(
70+
LinkedHashMultiset<String> dbHeaders, LinkedHashMultiset<String> csvHeaders) {
71+
LinkedHashMultiset<String> dbColumnHeadersCopy = LinkedHashMultiset.create(dbHeaders);
72+
csvHeaders.forEach(dbHeaders::remove);
73+
dbColumnHeadersCopy.forEach(csvHeaders::remove);
74+
75+
assertEquals(csvHeaders, dbHeaders, "Table headers are different");
76+
}
77+
}
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
/*
22
* Copyright 2022 Google LLC
3-
* Copyright 2013-2021 CompilerWorks
43
*
54
* Licensed under the Apache License, Version 2.0 (the "License");
65
* you may not use this file except in compliance with the License.
@@ -14,24 +13,20 @@
1413
* See the License for the specific language governing permissions and
1514
* limitations under the License.
1615
*/
17-
package com.google.base;
16+
package com.google.edwmigration.dumper.base;
1817

1918
import static java.lang.System.getenv;
2019

21-
import java.util.regex.Pattern;
22-
23-
/**
24-
* Stores constants common among all tests.
25-
*/
20+
/** Stores constants common among all tests. */
2621
public final class TestConstants {
2722

2823
public static final String URL_DB = getenv("DB_URL");
2924
public static final String USERNAME_DB = getenv("USERNAME");
3025
public static final String PASSWORD_DB = getenv("PASSWORD");
3126

32-
public static final String ET_OUTPUT_PATH = getenv("EXPORT_PATH");
33-
public static final Pattern TRAILING_SPACES_REGEX = Pattern.compile("\\s+$");
27+
public static final String EXPORTED_FILES_BASE_PATH = getenv("EXPORT_PATH");
28+
29+
public static final String SQL_REQUESTS_BASE_PATH = "sql/";
3430

35-
private TestConstants() {
36-
}
31+
private TestConstants() {}
3732
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/*
2+
* Copyright 2022 Google LLC
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package com.google.edwmigration.dumper.csv;
17+
18+
import static java.lang.Integer.parseInt;
19+
20+
/** A helper class for reading and extracting data from CSV files. */
21+
public final class CsvUtil {
22+
23+
private CsvUtil() {}
24+
25+
/**
26+
* @return String or an empty string if null.
27+
*/
28+
public static String getStringNotNull(String value) {
29+
return value == null ? "" : value;
30+
}
31+
32+
/**
33+
* @return int or 0 if "".
34+
*/
35+
public static int getIntNotNull(String value) {
36+
return getStringNotNull(value).equals("") ? 0 : parseInt(value);
37+
}
38+
}
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
/*
2+
* Copyright 2022 Google LLC
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package com.google.edwmigration.dumper.jdbc;
17+
18+
import java.sql.ResultSet;
19+
import java.sql.ResultSetMetaData;
20+
import java.sql.SQLException;
21+
import java.util.ArrayList;
22+
import java.util.List;
23+
24+
/**
25+
* A helper class for checking Null values returned by executing SELECT request against a database.
26+
*/
27+
public final class JdbcUtil {
28+
29+
private JdbcUtil() {}
30+
31+
/**
32+
* @param rs A row with SELECT results.
33+
* @param column Database column name.
34+
* @return String or an empty string if null.
35+
*/
36+
public static String getStringNotNull(ResultSet rs, String column) throws SQLException {
37+
String string = rs.getString(column);
38+
return rs.wasNull() ? "" : string;
39+
}
40+
41+
/**
42+
* @param rs A row with SELECT results.
43+
* @param columnIndex Database column index.
44+
* @return String or an empty string if null.
45+
*/
46+
public static String getStringNotNull(ResultSet rs, int columnIndex) throws SQLException {
47+
String string = rs.getString(columnIndex);
48+
return rs.wasNull() ? "" : string;
49+
}
50+
51+
/**
52+
* @param rsmd Metadata of the executed SQL query.
53+
* @return List of column names.
54+
* @throws SQLException
55+
*/
56+
public static List<String> getDbColumnNames(ResultSetMetaData rsmd) throws SQLException {
57+
List<String> columnNames = new ArrayList<>();
58+
for (int i = 1; i <= rsmd.getColumnCount(); i++) {
59+
columnNames.add(rsmd.getColumnName(i));
60+
}
61+
return columnNames;
62+
}
63+
}

0 commit comments

Comments
 (0)