diff --git a/dumper-integration-tests/redshift-tests/build.gradle b/dumper-integration-tests/redshift-tests/build.gradle index 4f3dd5975..d15faf866 100644 --- a/dumper-integration-tests/redshift-tests/build.gradle +++ b/dumper-integration-tests/redshift-tests/build.gradle @@ -1,15 +1,28 @@ +/* + * Copyright 2022 Google LLC + * Copyright 2013-2021 CompilerWorks + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ buildscript { repositories { mavenCentral() } - dependencies { - classpath 'com.google.protobuf:protobuf-gradle-plugin:0.8.18' - } } plugins { id 'java' - id "com.google.protobuf" version "0.8.18" + id 'com.adarshr.test-logger' version '3.0.0' } sourceCompatibility = 1.8 @@ -22,28 +35,30 @@ repositories { } dependencies { - implementation 'org.codehaus.groovy:groovy-all:3.0.5' - implementation 'org.testng:testng:7.5' + implementation 'org.codehaus.groovy:groovy-all:3.0.10' + implementation 'com.google.guava:guava:31.1-jre' + implementation 'junit:junit:4.13.2' implementation 'org.slf4j:slf4j-api:2.0.0-alpha5' implementation 'org.slf4j:slf4j-jdk14:2.0.0-alpha5' - implementation 'com.amazon.redshift:redshift-jdbc42:2.1.0.6' implementation 'commons-io:commons-io:2.11.0' - implementation 'org.apache.commons:commons-collections4:4.4' - implementation 'com.google.guava:guava:31.0.1-jre' - implementation 'com.opencsv:opencsv:5.6' - implementation 'com.google.protobuf:protobuf-gradle-plugin:0.8.18' - implementation 'com.google.protobuf:protobuf-java:3.20.1' + implementation 'org.apache.commons:commons-csv:1.9.0' + implementation 'com.google.truth:truth:1.1.3' + implementation 'com.google.truth.extensions:truth-java8-extension:1.1.3' + implementation 'com.amazon.redshift:redshift-jdbc42:2.1.0.7' + annotationProcessor 'com.google.auto.value:auto-value:1.9' + compileOnly 'com.google.auto.value:auto-value-annotations:1.9' } test { - useTestNG { - preserveOrder true + ignoreFailures = true + + useJUnit() { systemProperty 'java.util.logging.config.file', 'src/main/resources/logging.properties' } -} -protobuf { - protoc { - artifact = 'com.google.protobuf:protoc:3.20.1' - } + def envFiles = ['EXPORT_PATH'] + envFiles.each { if (System.env[it] != null) inputs.dir(System.env[it]) } + + def envProperties = ['DB_URL', 'USERNAME', 'PASSWORD'] + envProperties.each { if (System.env[it] != null) inputs.property it, System.env[it] } } \ No newline at end of file diff --git a/dumper-integration-tests/redshift-tests/src/main/java/com/google/base/TestBase.java b/dumper-integration-tests/redshift-tests/src/main/java/com/google/base/TestBase.java deleted file mode 100644 index 201a05f51..000000000 --- a/dumper-integration-tests/redshift-tests/src/main/java/com/google/base/TestBase.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright 2022 Google LLC - * Copyright 2013-2021 CompilerWorks - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.google.base; - -import static java.lang.String.format; -import static java.lang.System.lineSeparator; - -import com.google.common.base.Joiner; -import com.google.common.collect.LinkedHashMultiset; -import org.junit.Assert; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Base class with general values for all Junit test suites - */ -public abstract class TestBase { - - private static final Logger LOGGER = LoggerFactory.getLogger(TestBase.class); - - /** - * @param dbList List of extracted from DB items - * @param outputList List of uploaded from Avro items - */ - public static void assertListsEqual(final LinkedHashMultiset dbList, - final LinkedHashMultiset outputList) { - String dbListOutputForLogs = lineSeparator() + Joiner.on("").join(dbList); - String outputListForLogs = lineSeparator() + Joiner.on("").join(outputList); - - if (dbList.isEmpty() && outputList.isEmpty()) { - LOGGER.info("DB view and Output file are equal"); - } else if (!dbList.isEmpty() && !outputList.isEmpty()) { - Assert.fail(format("DB view and Output file have mutually exclusive row(s)%n" - + "DB view '%s' has %d different row(s): %s%n" - + "Output file %s has %d different row(s): %s", dbList.size(), dbListOutputForLogs, - outputList.size(), outputListForLogs)); - } else if (!dbList.isEmpty()) { - Assert.fail( - format("DB view '%s' has %d extra row(s):%n%s", dbList.size(), dbListOutputForLogs)); - } else if (!outputList.isEmpty()) { - Assert.fail( - format("Output file %s has %d extra row(s):%n%s", outputList.size(), outputListForLogs)); - } - } -} diff --git a/dumper-integration-tests/redshift-tests/src/main/java/com/google/edwmigration/dumper/base/TestBase.java b/dumper-integration-tests/redshift-tests/src/main/java/com/google/edwmigration/dumper/base/TestBase.java new file mode 100644 index 000000000..f46f8ed23 --- /dev/null +++ b/dumper-integration-tests/redshift-tests/src/main/java/com/google/edwmigration/dumper/base/TestBase.java @@ -0,0 +1,67 @@ +/* + * Copyright 2022 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.google.edwmigration.dumper.base; + +import static java.lang.String.format; +import static java.util.stream.Collectors.toList; + +import com.google.common.collect.LinkedHashMultiset; +import com.google.common.collect.Multiset; +import com.google.common.collect.Multisets; +import org.junit.Assert; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** Base class with general values for all TestNG test suites */ +public abstract class TestBase { + + private static final Logger LOGGER = LoggerFactory.getLogger(TestBase.class); + + /** + * @param dbMultiset List of extracted from DB items. + * @param csvMultiset List of uploaded from Avro items. + *
This custom method exists due to Java out of heap memory error in
+ * Truth.assertThat(dbMultiset).containsExactlyElementsIn(csvMultiset); It probably happens
+ * because .containsExactlyElementsIn() tries to print out not only the diff, let's say 1
+ * element, but entire collections.
+ */
+ public static void assertDbCsvDataEqual(
+ LinkedHashMultiset> dbMultiset, LinkedHashMultiset> csvMultiset) {
+ Multiset> dbReducedOnCsv = Multisets.difference(dbMultiset, csvMultiset);
+ Multiset> csvReducedOnDb = Multisets.difference(csvMultiset, dbMultiset);
+
+ String dbDiffEntries =
+ dbReducedOnCsv.stream().map(e -> e.toString() + "\n").collect(toList()).toString();
+ String csvDiffEntries =
+ csvReducedOnDb.stream().map(e -> e.toString() + "\n").collect(toList()).toString();
+
+ if (dbReducedOnCsv.isEmpty() && csvReducedOnDb.isEmpty()) {
+ LOGGER.info("DB view and CSV file are equal");
+ } else if (!dbReducedOnCsv.isEmpty() && !csvReducedOnDb.isEmpty()) {
+ Assert.fail(
+ format(
+ "DB view and CSV file have mutually exclusive row(s)%n"
+ + "DB view has %d different row(s): %s%n"
+ + "CSV file has %d different row(s): %s",
+ dbReducedOnCsv.size(), dbDiffEntries, csvReducedOnDb.size(), csvDiffEntries));
+ } else if (!dbReducedOnCsv.isEmpty()) {
+ Assert.fail(format("DB view has %d extra row(s):%n%s", dbReducedOnCsv.size(), dbDiffEntries));
+ } else if (!csvReducedOnDb.isEmpty()) {
+ Assert.fail(
+ format("CSV file has %d extra row(s):%n%s", csvReducedOnDb.size(), csvDiffEntries));
+ }
+ }
+}
diff --git a/dumper-integration-tests/redshift-tests/src/main/java/com/google/base/TestConstants.java b/dumper-integration-tests/redshift-tests/src/main/java/com/google/edwmigration/dumper/base/TestConstants.java
similarity index 72%
rename from dumper-integration-tests/redshift-tests/src/main/java/com/google/base/TestConstants.java
rename to dumper-integration-tests/redshift-tests/src/main/java/com/google/edwmigration/dumper/base/TestConstants.java
index 16d966dfd..4f3709455 100644
--- a/dumper-integration-tests/redshift-tests/src/main/java/com/google/base/TestConstants.java
+++ b/dumper-integration-tests/redshift-tests/src/main/java/com/google/edwmigration/dumper/base/TestConstants.java
@@ -1,6 +1,5 @@
/*
* Copyright 2022 Google LLC
- * Copyright 2013-2021 CompilerWorks
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,24 +13,20 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package com.google.base;
+package com.google.edwmigration.dumper.base;
import static java.lang.System.getenv;
-import java.util.regex.Pattern;
-
-/**
- * Stores constants common among all tests.
- */
+/** Stores constants common among all tests. */
public final class TestConstants {
public static final String URL_DB = getenv("DB_URL");
public static final String USERNAME_DB = getenv("USERNAME");
public static final String PASSWORD_DB = getenv("PASSWORD");
- public static final String ET_OUTPUT_PATH = getenv("EXPORT_PATH");
- public static final Pattern TRAILING_SPACES_REGEX = Pattern.compile("\\s+$");
+ public static final String EXPORTED_FILES_BASE_PATH = getenv("EXPORT_PATH");
+
+ public static final String SQL_REQUESTS_BASE_PATH = "sql/";
- private TestConstants() {
- }
+ private TestConstants() {}
}
diff --git a/dumper-integration-tests/redshift-tests/src/main/java/com/google/edwmigration/dumper/jdbc/JdbcUtil.java b/dumper-integration-tests/redshift-tests/src/main/java/com/google/edwmigration/dumper/jdbc/JdbcUtil.java
new file mode 100644
index 000000000..b051e0a6b
--- /dev/null
+++ b/dumper-integration-tests/redshift-tests/src/main/java/com/google/edwmigration/dumper/jdbc/JdbcUtil.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2022 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.google.edwmigration.dumper.jdbc;
+
+import java.sql.ResultSet;
+import java.sql.ResultSetMetaData;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * A helper class for checking Null values returned by executing SELECT request against a database.
+ */
+public final class JdbcUtil {
+
+ private JdbcUtil() {}
+
+ /**
+ * @param rs A row with SELECT results.
+ * @param column Database column name.
+ * @return String or an empty string if null.
+ */
+ public static String getStringNotNull(ResultSet rs, String column) throws SQLException {
+ String string = rs.getString(column);
+ return rs.wasNull() ? "" : string;
+ }
+
+ /**
+ * @param rs A row with SELECT results.
+ * @param columnIndex Database column index.
+ * @return String or an empty string if null.
+ */
+ public static String getStringNotNull(ResultSet rs, int columnIndex) throws SQLException {
+ String string = rs.getString(columnIndex);
+ return rs.wasNull() ? "" : string;
+ }
+
+ /**
+ * @param rsmd Metadata of the executed SQL query.
+ * @return List of column names.
+ * @throws SQLException
+ */
+ public static List