From 811c1b35346df72875455bf9018498bd29e32a84 Mon Sep 17 00:00:00 2001 From: "Alina (Xi) Li" <96995091+alinaliBQ@users.noreply.github.com> Date: Thu, 5 Jan 2023 10:40:05 -0800 Subject: [PATCH] Integration tests addition and refactoring (#23) Added test cases that handles scenarios in a given region: 1/ No databases 2/ One database; no tables 3/ One database ; one table 4/ One database; multiple tables with different naming pattern to test 'LIKE' 5/ Multiple databases; multiple tables in each In those test cases, `getSchemas()`, `getTables()` are tested with different naming schema patterns and table patterns to test 'LIKE'. They also check that `getCatalogs()` return empty result sets. Refactoring: - Refactored existing test suite `DatabaseMetaDataIntegrationTest` to automatically create / delete databases - Refactored `Constants.DATABASES_NAMES` to have clearer database names that indicate they are for integration tests Co-authored-by: RoyZhang2022 Co-authored-by: RoyZhang2022 Co-authored-by: RoyZhang2022 <104782736+RoyZhang2022@users.noreply.github.com> --- .../timestream/integrationtest/Constants.java | 64 ++++- .../DatabaseMetaDataIntegrationTest.java | 9 +- ...MetaDataMultiDBMultiTBIntegrationTest.java | 228 ++++++++++++++++++ .../DatabaseMetaDataNoDBIntegrationTest.java | 96 ++++++++ ...seMetaDataOneDBMultiTBIntegrationTest.java | 160 ++++++++++++ ...abaseMetaDataOneDBNoTBIntegrationTest.java | 110 +++++++++ ...baseMetaDataOneDBOneTBIntegrationTest.java | 148 ++++++++++++ .../integrationtest/DatabaseMetaDataTest.java | 189 +++++++++++++++ .../QueryExecutionIntegrationTest.java | 6 +- .../integrationtest/TableManager.java | 160 +++++++++++- .../jdbc/TimestreamSchemasResultSet.java | 2 +- .../jdbc/TimestreamDatabaseMetaDataTest.java | 11 +- 12 files changed, 1151 insertions(+), 32 deletions(-) create mode 100644 integrationtest/src/main/java/software/amazon/timestream/integrationtest/DatabaseMetaDataMultiDBMultiTBIntegrationTest.java create mode 100644 integrationtest/src/main/java/software/amazon/timestream/integrationtest/DatabaseMetaDataNoDBIntegrationTest.java create mode 100644 integrationtest/src/main/java/software/amazon/timestream/integrationtest/DatabaseMetaDataOneDBMultiTBIntegrationTest.java create mode 100644 integrationtest/src/main/java/software/amazon/timestream/integrationtest/DatabaseMetaDataOneDBNoTBIntegrationTest.java create mode 100644 integrationtest/src/main/java/software/amazon/timestream/integrationtest/DatabaseMetaDataOneDBOneTBIntegrationTest.java create mode 100644 integrationtest/src/main/java/software/amazon/timestream/integrationtest/DatabaseMetaDataTest.java diff --git a/integrationtest/src/main/java/software/amazon/timestream/integrationtest/Constants.java b/integrationtest/src/main/java/software/amazon/timestream/integrationtest/Constants.java index 187deaa..40adde7 100644 --- a/integrationtest/src/main/java/software/amazon/timestream/integrationtest/Constants.java +++ b/integrationtest/src/main/java/software/amazon/timestream/integrationtest/Constants.java @@ -17,6 +17,7 @@ import com.amazonaws.services.timestreamwrite.model.MeasureValueType; import com.google.common.collect.ImmutableMap; + import java.util.Map; /** @@ -28,16 +29,9 @@ final class Constants { static final String TABLE_NAME = "Integration_Test_Table_07"; static final String NON_EXISTENT_TABLE_NAME = "NotExistTableName"; static final String[] DATABASES_NAMES = new String[]{ - "FAST_PATH_TEST_DB", "JDBC_Integration07_Test_DB", - "TestV1", - "devops", - "grafanaPerfDB", - "grafana_db", - "perf07", - "performance07", - "sampleDB", - "testDB" + "Integration_Test_DB01", + "Integration_Test_DB02" }; static final String[] COLUMN_NAMES = new String[]{ "hostname", @@ -56,6 +50,55 @@ final class Constants { "measure_value::varchar", }; + static final String NO_DB_NO_TB_REGION = "ap-southeast-2"; + static final String[] NO_DB_DATABASE_NAMES = new String[]{}; + static final String[] NO_TB_TABLE_NAMES = new String[]{}; + + static final String ONE_DB_NO_TB_REGION = "ap-northeast-1"; + static final String[] ONE_DB_NO_TB_DATABASE_NAME = new String[]{ + "EmptyDb_1_2.34" + }; + static final String[] ONE_DB_NO_TB_TABLE_NAMES = new String[]{}; + + static final String ONE_DB_ONE_TB_REGION = "eu-central-1"; + static final String[] ONE_DB_ONE_TB_DATABASE_NAME = new String[]{ + "JDBC_.IntegrationTestDB0088" + }; + static final String[] ONE_DB_ONE_TB_TABLE_NAME = new String[]{ + "IntegrationTestTable0888", + }; + + static final String ONE_DB_MUTLI_TB_REGION = "eu-west-1"; + static final String[] ONE_DB_MUTLI_TB_DATABASES_NAME = new String[]{ + "JDBC_Inte.gration_Te.st_DB_01" + }; + static final String[] ONE_DB_MUTLI_TB_TABLE_NAMES = new String[]{ + "Inte.gration_Tes_t_Tab_le_03", + "Integ.ration_Te_st_T_able_01", + "Integr.ation_Test_Ta_ble_02" + }; + + static final String[] MULTI_DB_MUTLI_TB_DATABASES_NAMES = new String[]{ + "JD_BC_Int.egration_Test_DB_001", + "JDB.C_Integration-Test_DB_002", + "JD-BC_Integration.Test_DB_003" + }; + static final String[] MULTI_DB_MUTLI_TB_TABLE_NAMES1 = new String[]{ + "Inte-gration_Tes1t_Table_01_01", + "Inte-gration2_Te-st_Table_01_02", + "Inte-gration_Test_3Ta-ble_01_03" + }; + static final String[] MULTI_DB_MUTLI_TB_TABLE_NAMES2 = new String[]{ + "Integration-Test_Ta1ble_02_01", + "Integration.-Te-st_Table_02_02" + }; + static final String[] MULTI_DB_MUTLI_TB_TABLE_NAMES3 = new String[]{ + "JD-BC_Integration-Test_Ta1ble_03_01", + "JD-BC_Integration.-Te-st_Table_03_02", + "JD-BC_Integration--Test2_Table_03_03", + "JD-BC_Integration0-Te-st_Ta.ble_03_04" + }; + static final int TABLE_COLUMN_NUM = 9; static final int TABLE_ROW_SIZE = 4; static final long HT_TTL_HOURS = 24L; @@ -72,5 +115,6 @@ final class Constants { .put(MeasureValueType.BOOLEAN, BOOLEAN_VALUE) .build(); - private Constants() { } + private Constants() { + } } diff --git a/integrationtest/src/main/java/software/amazon/timestream/integrationtest/DatabaseMetaDataIntegrationTest.java b/integrationtest/src/main/java/software/amazon/timestream/integrationtest/DatabaseMetaDataIntegrationTest.java index 0b72822..c11644d 100644 --- a/integrationtest/src/main/java/software/amazon/timestream/integrationtest/DatabaseMetaDataIntegrationTest.java +++ b/integrationtest/src/main/java/software/amazon/timestream/integrationtest/DatabaseMetaDataIntegrationTest.java @@ -46,13 +46,15 @@ class DatabaseMetaDataIntegrationTest { @BeforeAll private static void setUp() { - TableManager.createTable(); + TableManager.createDatabases(Constants.DATABASES_NAMES); + TableManager.createTable(Constants.TABLE_NAME, Constants.DATABASE_NAME); TableManager.writeRecords(); } @AfterAll private static void cleanUp() { - TableManager.deleteTable(); + TableManager.deleteTable(Constants.TABLE_NAME, Constants.DATABASE_NAME); + TableManager.deleteDatabases(Constants.DATABASES_NAMES); } @BeforeEach @@ -69,6 +71,7 @@ private void terminate() throws SQLException { /** * Test getCatalogs returns empty ResultSet. + * * @throws SQLException the exception thrown */ @Test @@ -85,6 +88,7 @@ void testCatalogs() throws SQLException { /** * Test getSchemas returns the list of all databases. + * * @throws SQLException the exception thrown */ @Test @@ -102,6 +106,7 @@ void testSchemas() throws SQLException { /** * Test getSchemas returns database "JDBC_Integration07_Test_DB" when given matching patterns. + * * @param schemaPattern the schema pattern to be tested * @throws SQLException the exception thrown */ diff --git a/integrationtest/src/main/java/software/amazon/timestream/integrationtest/DatabaseMetaDataMultiDBMultiTBIntegrationTest.java b/integrationtest/src/main/java/software/amazon/timestream/integrationtest/DatabaseMetaDataMultiDBMultiTBIntegrationTest.java new file mode 100644 index 0000000..0979fe5 --- /dev/null +++ b/integrationtest/src/main/java/software/amazon/timestream/integrationtest/DatabaseMetaDataMultiDBMultiTBIntegrationTest.java @@ -0,0 +1,228 @@ +/* + * Copyright <2020> Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). + * You may not use this file except in compliance with the License. + * A copy of the License is located at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * or in the "license" file accompanying this file. This file 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 software.amazon.timestream.integrationtest; + +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; +import software.amazon.timestream.jdbc.TimestreamDatabaseMetaData; + +import java.sql.Connection; +import java.sql.DatabaseMetaData; +import java.sql.DriverManager; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Properties; + +/** + * Integration tests for supported getters in {@link TimestreamDatabaseMetaData} + * Test case: Multiples databases with multiple tables + */ +class DatabaseMetaDataMultiDBMultiTBIntegrationTest { + private DatabaseMetaData metaData; + private Connection connection; + private List tables; + + @BeforeAll + private static void setUp() { + TableManager.createDatabases(Constants.MULTI_DB_MUTLI_TB_DATABASES_NAMES); + TableManager.createTables(Constants.MULTI_DB_MUTLI_TB_TABLE_NAMES1, Constants.MULTI_DB_MUTLI_TB_DATABASES_NAMES[0]); + TableManager.createTables(Constants.MULTI_DB_MUTLI_TB_TABLE_NAMES2, Constants.MULTI_DB_MUTLI_TB_DATABASES_NAMES[1]); + TableManager.createTables(Constants.MULTI_DB_MUTLI_TB_TABLE_NAMES3, Constants.MULTI_DB_MUTLI_TB_DATABASES_NAMES[2]); + } + + @AfterAll + private static void cleanUp() { + TableManager.deleteTables(Constants.MULTI_DB_MUTLI_TB_TABLE_NAMES1, Constants.MULTI_DB_MUTLI_TB_DATABASES_NAMES[0]); + TableManager.deleteTables(Constants.MULTI_DB_MUTLI_TB_TABLE_NAMES2, Constants.MULTI_DB_MUTLI_TB_DATABASES_NAMES[1]); + TableManager.deleteTables(Constants.MULTI_DB_MUTLI_TB_TABLE_NAMES3, Constants.MULTI_DB_MUTLI_TB_DATABASES_NAMES[2]); + TableManager.deleteDatabases(Constants.MULTI_DB_MUTLI_TB_DATABASES_NAMES); + } + + @BeforeEach + private void init() throws SQLException { + final Properties p = new Properties(); + connection = DriverManager.getConnection(Constants.URL, p); + metaData = connection.getMetaData(); + tables = new ArrayList<>(); + tables.add(Constants.MULTI_DB_MUTLI_TB_TABLE_NAMES1); + tables.add(Constants.MULTI_DB_MUTLI_TB_TABLE_NAMES2); + tables.add(Constants.MULTI_DB_MUTLI_TB_TABLE_NAMES3); + } + + @AfterEach + private void terminate() throws SQLException { + connection.close(); + } + + /** + * Test getCatalogs returns empty ResultSet. + * + * @throws SQLException the exception thrown + */ + @Test + @DisplayName("Test getCatalogs(). Empty result set should be returned") + void testCatalogs() throws SQLException { + final List catalogsList = new ArrayList<>(); + try (ResultSet catalogs = metaData.getCatalogs()) { + while (catalogs.next()) { + catalogsList.add(catalogs.getString("TABLE_CAT")); + } + } + Assertions.assertTrue(catalogsList.isEmpty()); + } + + /** + * Test getSchemas returns the databases. + * + * @throws SQLException the exception thrown + */ + @Test + @DisplayName("Test retrieving the databases.") + void testSchemas() throws SQLException { + final List databasesList = Arrays.asList(Constants.MULTI_DB_MUTLI_TB_DATABASES_NAMES); + final List schemasList = new ArrayList<>(); + try (ResultSet schemas = metaData.getSchemas()) { + while (schemas.next()) { + schemasList.add(schemas.getString("TABLE_SCHEM")); + } + } + Assertions.assertTrue(schemasList.containsAll(databasesList)); + } + + /** + * Test getTables returns all tables. + * + * @throws SQLException the exception thrown + */ + @Test + @DisplayName("Test getTables returns all tables") + void testTables() throws SQLException { + final List allTables = new ArrayList<>(); + + // Test all tables from specified database are returned + for (int i = 0; i < tables.size(); i++) { + final List tableList = Arrays.asList(tables.get(i)); + allTables.addAll(tableList); + final List returnTableList = new ArrayList<>(); + try (ResultSet tables = metaData.getTables(null, Constants.MULTI_DB_MUTLI_TB_DATABASES_NAMES[i], null, null)) { + while (tables.next()) { + returnTableList.add(tables.getString("TABLE_NAME")); + } + } + Assertions.assertTrue(returnTableList.containsAll(tableList)); + } + + // Test all tables from region are returned when no database is specified + final List returnAllTableList = new ArrayList<>(); + try (ResultSet tables = metaData.getTables(null, null, null, null)) { + while (tables.next()) { + returnAllTableList.add(tables.getString("TABLE_NAME")); + } + } + Assertions.assertTrue(returnAllTableList.containsAll(allTables)); + } + + /** + * Test getSchemas returns databases when given matching patterns. + * + * @param schemaPattern the schema pattern to be tested + * @param index index of database name in Constants.MULTI_DB_MUTLI_TB_DATABASES_NAMES + * @throws SQLException the exception thrown + */ + @ParameterizedTest + @CsvSource(value = { + "%ion!_T%' escape '!, 0", + "%DB_001, 0", + "JDB.C%, 1", + "%DB_002, 1", + "JD-BC%, 2", + "%DB!_003' escape '!, 2", + }) + @DisplayName("Test retrieving database name JD_BC_Int.egration_Test_DB_001, JDB.C_Integration-Test_DB_002, JD-BC_Integration.Test_DB_003 with pattern.") + void testGetSchemasWithSchemaPattern(String schemaPattern, int index) throws SQLException { + try (ResultSet schemas = metaData.getSchemas(null, schemaPattern)) { + Assertions.assertTrue(schemas.next()); + Assertions.assertEquals(Constants.MULTI_DB_MUTLI_TB_DATABASES_NAMES[index], schemas.getString("TABLE_SCHEM")); + } + } + + /** + * Test getTables returns tables from JD-BC_Integration.Test_DB_003 when given matching patterns. + * + * @param tablePattern the table pattern to be tested + * @param schemaPattern the database pattern to be tested + * @param dbIndex index of database. 0 corresponds to Constants.MULTI_DB_MUTLI_TB_TABLE_NAMES1 + * @param tbIndex index of table name in specified database + * @throws SQLException the exception thrown + */ + @ParameterizedTest + @CsvSource(value = { + "%_Table_01_01, %ion!_T%' escape '!, 0, 0", + "%-gration2_Te-st%, JD_BC_Int.%, 0, 1", + "_nte-gration_Test_3Ta-ble_0__03, %DB_001, 0, 2", + "%!_02!_01' escape '!, %DB_002, 1, 0", + "%gration.-Te-st%, %ion-T%, 1, 1", + "JD-BC__ntegration-Test_Ta1ble_0__01, %DB!_003' escape '!, 2, 0", + "%.-Te-st_T%, %ion.T%, 2, 1", + "%3_03, JD-BC%, 2, 2", + "%a.ble%' escape '!, %DB!_003' escape '!, 2, 3" + }) + @DisplayName("Test retrieving tables from databases when given matching table and schema patterns.") + void testTablesWithTBPatternDBPattern(final String tablePattern, final String schemaPattern, final int dbIndex, final int tbIndex) throws SQLException { + try (ResultSet tableResultSet = metaData.getTables(null, schemaPattern, tablePattern, null)) { + Assertions.assertTrue(tableResultSet.next()); + Assertions.assertEquals(tables.get(dbIndex)[tbIndex], tableResultSet.getObject("TABLE_NAME")); + } + } + + /** + * Test getTables returns tables from databases when given matching table patterns. + * + * @param tablePattern the table pattern to be tested + * @param dbIndex index of database. 0 corresponds to Constants.MULTI_DB_MUTLI_TB_TABLE_NAMES1 + * @param tbIndex index of table name in specified database + * @throws SQLException the exception thrown + */ + @ParameterizedTest + @CsvSource(value = { + "_nte-gration_Tes1t_Table_0__01, 0, 0", + "%_Table_01_02%, 0, 1", + "%-gration_Test%, 0, 2", + "%!_02!_01' escape '!, 1, 0", + "%_Table_02_02, 1, 1", + "%-BC_Integration-Test_Ta1%, 2, 0", + "%.-Te-st_T%, 2, 1", + "%t2!_T%' escape '!, 2, 2", + "%a.ble%' escape '!, 2, 3" + }) + @DisplayName("Test retrieving tables from databases when given matching table patterns.") + void testTablesWithTBPattern(final String tablePattern, final int dbIndex, final int tbIndex) throws SQLException { + try (ResultSet tableResultSet = metaData.getTables(null, Constants.MULTI_DB_MUTLI_TB_DATABASES_NAMES[dbIndex], tablePattern, null)) { + Assertions.assertTrue(tableResultSet.next()); + Assertions.assertEquals(tables.get(dbIndex)[tbIndex], tableResultSet.getObject("TABLE_NAME")); + } + } +} diff --git a/integrationtest/src/main/java/software/amazon/timestream/integrationtest/DatabaseMetaDataNoDBIntegrationTest.java b/integrationtest/src/main/java/software/amazon/timestream/integrationtest/DatabaseMetaDataNoDBIntegrationTest.java new file mode 100644 index 0000000..1960e18 --- /dev/null +++ b/integrationtest/src/main/java/software/amazon/timestream/integrationtest/DatabaseMetaDataNoDBIntegrationTest.java @@ -0,0 +1,96 @@ +/* + * Copyright <2020> Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). + * You may not use this file except in compliance with the License. + * A copy of the License is located at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * or in the "license" file accompanying this file. This file 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 software.amazon.timestream.integrationtest; + +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import software.amazon.timestream.jdbc.TimestreamDatabaseMetaData; + +import java.sql.SQLException; + + +/** + * Integration tests for supported getters in {@link TimestreamDatabaseMetaData} + * Test case: No database + */ +class DatabaseMetaDataNoDBIntegrationTest { + private final DatabaseMetaDataTest dbTest = new DatabaseMetaDataTest(Constants.NO_DB_NO_TB_REGION, + Constants.NO_DB_DATABASE_NAMES, + Constants.NO_TB_TABLE_NAMES); + + @BeforeAll + private static void setUp() { + DatabaseMetaDataTest.setUp( + Constants.NO_DB_NO_TB_REGION, + Constants.NO_DB_DATABASE_NAMES, + Constants.NO_TB_TABLE_NAMES); + } + + @AfterAll + private static void cleanUp() { + DatabaseMetaDataTest.cleanUp( + Constants.NO_DB_NO_TB_REGION, + Constants.NO_DB_DATABASE_NAMES, + Constants.NO_TB_TABLE_NAMES); + } + + @BeforeEach + private void init() throws SQLException { + dbTest.init(); + } + + @AfterEach + private void terminate() throws SQLException { + dbTest.terminate(); + } + + /** + * Test getCatalogs returns empty ResultSet. + * + * @throws SQLException the exception thrown + */ + @Test + @DisplayName("Test getCatalogs(). Empty result set should be returned") + void testCatalogs() throws SQLException { + dbTest.testCatalogs(); + } + + /** + * Test getSchemas returns empty ResultSet. + * + * @throws SQLException the exception thrown + */ + @Test + @DisplayName("Test getSchemas(), no database should be returned.") + void testSchemas() throws SQLException { + dbTest.testSchemas(); + } + + /** + * Test getTables returns no table. + * + * @throws SQLException the exception thrown + */ + @Test + @DisplayName("Test getTables(), no table should be returned.") + void testTables() throws SQLException { + dbTest.testTables(); + } +} diff --git a/integrationtest/src/main/java/software/amazon/timestream/integrationtest/DatabaseMetaDataOneDBMultiTBIntegrationTest.java b/integrationtest/src/main/java/software/amazon/timestream/integrationtest/DatabaseMetaDataOneDBMultiTBIntegrationTest.java new file mode 100644 index 0000000..ee3a302 --- /dev/null +++ b/integrationtest/src/main/java/software/amazon/timestream/integrationtest/DatabaseMetaDataOneDBMultiTBIntegrationTest.java @@ -0,0 +1,160 @@ +/* + * Copyright <2020> Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). + * You may not use this file except in compliance with the License. + * A copy of the License is located at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * or in the "license" file accompanying this file. This file 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 software.amazon.timestream.integrationtest; + +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; +import org.junit.jupiter.params.provider.ValueSource; +import software.amazon.timestream.jdbc.TimestreamDatabaseMetaData; + +import java.sql.SQLException; + +/** + * Integration tests for supported getters in {@link TimestreamDatabaseMetaData} + * Test case: One database with multiple tables + */ +class DatabaseMetaDataOneDBMultiTBIntegrationTest { + private final DatabaseMetaDataTest dbTest = new DatabaseMetaDataTest(Constants.ONE_DB_MUTLI_TB_REGION, + Constants.ONE_DB_MUTLI_TB_DATABASES_NAME, + Constants.ONE_DB_MUTLI_TB_TABLE_NAMES); + + @BeforeAll + private static void setUp() { + DatabaseMetaDataTest.setUp( + Constants.ONE_DB_MUTLI_TB_REGION, + Constants.ONE_DB_MUTLI_TB_DATABASES_NAME, + Constants.ONE_DB_MUTLI_TB_TABLE_NAMES); + } + + @AfterAll + private static void cleanUp() { + DatabaseMetaDataTest.cleanUp( + Constants.ONE_DB_MUTLI_TB_REGION, + Constants.ONE_DB_MUTLI_TB_DATABASES_NAME, + Constants.ONE_DB_MUTLI_TB_TABLE_NAMES); + } + + @BeforeEach + private void init() throws SQLException { + dbTest.init(); + } + + @AfterEach + private void terminate() throws SQLException { + dbTest.terminate(); + } + + /** + * Test getCatalogs returns empty ResultSet. + * + * @throws SQLException the exception thrown + */ + @Test + @DisplayName("Test getCatalogs(). Empty result set should be returned") + void testCatalogs() throws SQLException { + dbTest.testCatalogs(); + } + + /** + * Test getSchemas returns the database. + * + * @throws SQLException the exception thrown + */ + @Test + @DisplayName("Test retrieving the database.") + void testSchemas() throws SQLException { + dbTest.testSchemas(); + } + + /** + * Test getSchemas returns database "JDBC_Inte.gration_Te.st_DB_01" when given matching patterns. + * + * @param schemaPattern the schema pattern to be tested + * @throws SQLException the exception thrown + */ + @ParameterizedTest + @ValueSource(strings = {"%_01", "%_Inte.gration%", "%Te.st_DB%"}) + @DisplayName("Test retrieving database name JDBC_Inte.gration_Te.st_DB_01 with pattern.") + void testGetSchemasWithSchemaPattern(String schemaPattern) throws SQLException { + dbTest.testGetSchemasWithSchemaPattern(schemaPattern); + } + + /** + * Test getTables returns all tables from database "JDBC_Inte.gration_Te.st_DB_01". + * + * @throws SQLException the exception thrown + */ + @Test + @DisplayName("Test getTables returns all tables from database \"JDBC_Inte.gration_Te.st_DB_01\"") + void testTables() throws SQLException { + dbTest.testTables(); + } + + /** + * Test getTables returns tables from JDBC_Inte.gration_Te.st_DB_01 when given matching patterns. + * + * @param tablePattern the table pattern to be tested + * @param schemaPattern the database pattern to be tested + * @param index index of table name in Constants.ONE_DB_MUTLI_TB_TABLE_NAMES + * @throws SQLException the exception thrown + */ + @ParameterizedTest + @CsvSource(value = { + "%tion_Tes_t%, %_01, 0", + "_nte.grat_%, %_Inte.gration%, 0", + "%_Tes_t_Tab_le_%, %Te.st_DB%, 0", + "%g.ration_Te_st%, %_01, 1", + "%_nteg.rat_%, %_Inte.gration%, 1", + "%_Te_st_T_able_0_, %Te.st_DB%, 1", + "%tion_Test%, %_01, 2", + "_ntegr.at_%, %_Inte.gration%, 2", + "%_Test_Ta_ble_02, %Te.st_DB%, 2" + }) + @DisplayName("Test retrieving Inte.gration_Tes_t_Tab_le_03, Integ.ration_Te_st_T_able_01, Integr.ation_Test_Ta_ble_02 from JDBC_Inte.gration_Te.st_DB_01.") + void testTablesWithPatternFromDBWithPattern(final String tablePattern, final String schemaPattern, final int index) throws SQLException { + dbTest.testTablesWithPatternFromDBWithPattern(tablePattern, schemaPattern, index); + } + + /** + * Test getTables returns tables from JDBC_Inte.gration_Te.st_DB_01 when given matching patterns. + * + * @param tablePattern the table pattern to be tested + * @param index index of table name in Constants.ONE_DB_MUTLI_TB_TABLE_NAMES + * @throws SQLException the exception thrown + */ + @ParameterizedTest + @CsvSource(value = { + "%tion_Tes_t%, 0", + "_nte.grat_%, 0", + "%_Tes_t_Tab_le_%, 0", + "%g.ration_Te_st%, 1", + "%_nteg.rat_%, 1", + "%_Te_st_T_able_0_, 1", + "%tion_Test%, 2", + "_ntegr.at_%, 2", + "%_Test_Ta_ble_02, 2" + }) + @DisplayName("Test retrieving Inte.gration_Tes_t_Tab_le_03, Integ.ration_Te_st_T_able_01, Integr.ation_Test_Ta_ble_02 from JDBC_Inte.gration_Te.st_DB_01.") + void testTablesWithPattern(final String tablePattern, final int index) throws SQLException { + dbTest.testTablesWithPattern(tablePattern, index); + } +} diff --git a/integrationtest/src/main/java/software/amazon/timestream/integrationtest/DatabaseMetaDataOneDBNoTBIntegrationTest.java b/integrationtest/src/main/java/software/amazon/timestream/integrationtest/DatabaseMetaDataOneDBNoTBIntegrationTest.java new file mode 100644 index 0000000..6dd533d --- /dev/null +++ b/integrationtest/src/main/java/software/amazon/timestream/integrationtest/DatabaseMetaDataOneDBNoTBIntegrationTest.java @@ -0,0 +1,110 @@ +/* + * Copyright <2020> Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). + * You may not use this file except in compliance with the License. + * A copy of the License is located at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * or in the "license" file accompanying this file. This file 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 software.amazon.timestream.integrationtest; + +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; +import software.amazon.timestream.jdbc.TimestreamDatabaseMetaData; + +import java.sql.SQLException; + +/** + * Integration tests for supported getters in {@link TimestreamDatabaseMetaData} + * Test case: One database with no tables + */ +class DatabaseMetaDataOneDBNoTBIntegrationTest { + private final DatabaseMetaDataTest dbTest = new DatabaseMetaDataTest(Constants.ONE_DB_NO_TB_REGION, + Constants.ONE_DB_NO_TB_DATABASE_NAME, + Constants.ONE_DB_NO_TB_TABLE_NAMES); + + @BeforeAll + private static void setUp() { + DatabaseMetaDataTest.setUp( + Constants.ONE_DB_NO_TB_REGION, + Constants.ONE_DB_NO_TB_DATABASE_NAME, + Constants.ONE_DB_NO_TB_TABLE_NAMES); + } + + @AfterAll + private static void cleanUp() { + DatabaseMetaDataTest.cleanUp( + Constants.ONE_DB_NO_TB_REGION, + Constants.ONE_DB_NO_TB_DATABASE_NAME, + Constants.ONE_DB_NO_TB_TABLE_NAMES); + } + + @BeforeEach + private void init() throws SQLException { + dbTest.init(); + } + + @AfterEach + private void terminate() throws SQLException { + dbTest.terminate(); + } + + /** + * Test getCatalogs returns empty ResultSet. + * + * @throws SQLException the exception thrown + */ + @Test + @DisplayName("Test getCatalogs(). Empty result set should be returned") + void testCatalogs() throws SQLException { + dbTest.testCatalogs(); + } + + /** + * Test getSchemas returns the database. + * + * @throws SQLException the exception thrown + */ + @Test + @DisplayName("Test retrieving the database.") + void testSchemas() throws SQLException { + dbTest.testSchemas(); + } + + /** + * Test getSchemas returns database "EmptyDb_1_2.34" when given matching patterns. + * + * @param schemaPattern the schema pattern to be tested + * @throws SQLException the exception thrown + */ + @ParameterizedTest + @ValueSource(strings = {"Empty_b!_1!_2.34' escape '!", "EmptyDb%", "%___2.34"}) + @DisplayName("Test retrieving database name EmptyDb_1_2.34 with pattern.") + void testGetSchemasWithSchemaPattern(String schemaPattern) throws SQLException { + dbTest.testGetSchemasWithSchemaPattern(schemaPattern); + } + + /** + * Test getTables returns no tables from empty database. + * + * @throws SQLException the exception thrown + */ + @Test + @DisplayName("Test getTables returns no tables from empty database \"EmptyDb_1_2.34\"") + void testTables() throws SQLException { + dbTest.testTables(); + } +} diff --git a/integrationtest/src/main/java/software/amazon/timestream/integrationtest/DatabaseMetaDataOneDBOneTBIntegrationTest.java b/integrationtest/src/main/java/software/amazon/timestream/integrationtest/DatabaseMetaDataOneDBOneTBIntegrationTest.java new file mode 100644 index 0000000..b2759a0 --- /dev/null +++ b/integrationtest/src/main/java/software/amazon/timestream/integrationtest/DatabaseMetaDataOneDBOneTBIntegrationTest.java @@ -0,0 +1,148 @@ +/* + * Copyright <2020> Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). + * You may not use this file except in compliance with the License. + * A copy of the License is located at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * or in the "license" file accompanying this file. This file 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 software.amazon.timestream.integrationtest; + +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; +import org.junit.jupiter.params.provider.ValueSource; +import software.amazon.timestream.jdbc.TimestreamDatabaseMetaData; + +import java.sql.SQLException; + +/** + * Integration tests for supported getters in {@link TimestreamDatabaseMetaData} + * Test case: One databases with one table + */ +class DatabaseMetaDataOneDBOneTBIntegrationTest { + private final DatabaseMetaDataTest dbTest = new DatabaseMetaDataTest(Constants.ONE_DB_ONE_TB_REGION, + Constants.ONE_DB_ONE_TB_DATABASE_NAME, + Constants.ONE_DB_ONE_TB_TABLE_NAME); + + @BeforeAll + private static void setUp() { + DatabaseMetaDataTest.setUp( + Constants.ONE_DB_ONE_TB_REGION, + Constants.ONE_DB_ONE_TB_DATABASE_NAME, + Constants.ONE_DB_ONE_TB_TABLE_NAME); + } + + @AfterAll + private static void cleanUp() { + DatabaseMetaDataTest.cleanUp( + Constants.ONE_DB_ONE_TB_REGION, + Constants.ONE_DB_ONE_TB_DATABASE_NAME, + Constants.ONE_DB_ONE_TB_TABLE_NAME); + } + + @BeforeEach + private void init() throws SQLException { + dbTest.init(); + } + + @AfterEach + private void terminate() throws SQLException { + dbTest.terminate(); + } + + /** + * Test getCatalogs returns empty ResultSet. + * + * @throws SQLException the exception thrown + */ + @Test + @DisplayName("Test getCatalogs(). Empty result set should be returned") + void testCatalogs() throws SQLException { + dbTest.testCatalogs(); + } + + /** + * Test getSchemas returns the database. + * + * @throws SQLException the exception thrown + */ + @Test + @DisplayName("Test retrieving the database.") + void testSchemas() throws SQLException { + dbTest.testSchemas(); + } + + /** + * Test getSchemas returns database "JDBC_.IntegrationTestDB0088" when given matching patterns. + * + * @param schemaPattern the schema pattern to be tested + * @throws SQLException the exception thrown + */ + @ParameterizedTest + @ValueSource(strings = {"%0_88", "%!_.Integration%' escape '!", "JDBC%_ntegrationTestD_00_8"}) + @DisplayName("Test retrieving database name JDBC_.IntegrationTestDB0088 with pattern.") + void testGetSchemasWithSchemaPattern(String schemaPattern) throws SQLException { + dbTest.testGetSchemasWithSchemaPattern(schemaPattern); + } + + /** + * Test getTables returns the table from database "JDBC_.IntegrationTestDB0088". + * + * @throws SQLException the exception thrown + */ + @Test + @DisplayName("Test getTables returns the table from database \"JDBC_.IntegrationTestDB0088\"") + void testTables() throws SQLException { + dbTest.testTables(); + } + + /** + * Test getTables returns tables from IntegrationTestTable0888 when given matching patterns. + * + * @param tablePattern the table pattern to be tested + * @param schemaPattern the database pattern to be tested + * @param index index of table name in Constants.ONE_DB_ONE_TB_TABLE_NAMES + * @throws SQLException the exception thrown + */ + @ParameterizedTest + @CsvSource(value = { + "%Test%le08%, %0_88, 0", + "In_egratio_TestTable_888, %!_.Integration%' escape '!, 0", + "%8, JDBC%_ntegrationTestD_00_8, 0", + }) + @DisplayName("Test retrieving IntegrationTestTable0888 from JDBC_.IntegrationTestDB0088.") + void testTablesWithPatternFromDBWithPattern(final String tablePattern, final String schemaPattern, final int index) throws SQLException { + dbTest.testTablesWithPatternFromDBWithPattern(tablePattern, schemaPattern, index); + } + + /** + * Test getTables returns tables from IntegrationTestTable0888 when given matching patterns. + * + * @param tablePattern the table pattern to be tested + * @param index index of table name in Constants.ONE_DB_ONE_TB_TABLE_NAMES + * @throws SQLException the exception thrown + */ + @ParameterizedTest + @CsvSource(value = { + "%Test%le08%, 0", + "In_egratio_TestTable_888, 0", + "%8, 0", + }) + @DisplayName("Test retrieving IntegrationTestTable0888 from JDBC_.IntegrationTestDB0088.") + void testTablesWithPattern(final String tablePattern, final int index) throws SQLException { + dbTest.testTablesWithPattern(tablePattern, index); + } +} diff --git a/integrationtest/src/main/java/software/amazon/timestream/integrationtest/DatabaseMetaDataTest.java b/integrationtest/src/main/java/software/amazon/timestream/integrationtest/DatabaseMetaDataTest.java new file mode 100644 index 0000000..ec4d5cc --- /dev/null +++ b/integrationtest/src/main/java/software/amazon/timestream/integrationtest/DatabaseMetaDataTest.java @@ -0,0 +1,189 @@ +/* + * Copyright <2020> Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"). + * You may not use this file except in compliance with the License. + * A copy of the License is located at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * or in the "license" file accompanying this file. This file 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 software.amazon.timestream.integrationtest; + +import org.junit.jupiter.api.Assertions; +import software.amazon.timestream.jdbc.TimestreamDatabaseMetaData; + +import java.sql.Connection; +import java.sql.DatabaseMetaData; +import java.sql.DriverManager; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Properties; + +/** + * Integration tests for supported getters in {@link TimestreamDatabaseMetaData} + */ +class DatabaseMetaDataTest { + private DatabaseMetaData metaData; + private Connection connection; + + private final String region; + private final String[] databases; + private final String[] tables; + + DatabaseMetaDataTest(String r, String[] ds, String[] ts) { + region = r; + databases = ds; + tables = ts; + } + + static void setUp(String r, String[] ds, String[] ts) { + TableManager.setRegion(r); + TableManager.createDatabases(ds); + TableManager.createTables(ts, ds); + } + + static void cleanUp(String r, String[] ds, String[] ts) { + TableManager.setRegion(r); + TableManager.deleteTables(ts, ds); + TableManager.deleteDatabases(ds); + } + + void init() throws SQLException { + final Properties p = new Properties(); + p.setProperty("Region", region); + connection = DriverManager.getConnection(Constants.URL, p); + metaData = connection.getMetaData(); + } + + void terminate() throws SQLException { + connection.close(); + } + + /** + * Test getCatalogs returns empty ResultSet. + * + * @throws SQLException the exception thrown + */ + void testCatalogs() throws SQLException { + final List catalogsList = new ArrayList<>(); + try (ResultSet catalogs = metaData.getCatalogs()) { + while (catalogs.next()) { + catalogsList.add(catalogs.getString("TABLE_CAT")); + } + } + Assertions.assertTrue(catalogsList.isEmpty()); + } + + /** + * Test getSchemas returns the database. + * + * @throws SQLException the exception thrown + */ + public void testSchemas() throws SQLException { + final List databaseList = Arrays.asList(databases); + final List schemasList = new ArrayList<>(); + try (ResultSet schemas = metaData.getSchemas()) { + while (schemas.next()) { + schemasList.add(schemas.getString("TABLE_SCHEM")); + } + } + Assertions.assertEquals(databaseList, schemasList); + } + + /** + * Test getSchemas returns databases when given matching patterns. + * + * @param schemaPattern the schema pattern to be tested + * @throws SQLException the exception thrown + */ + public void testGetSchemasWithSchemaPattern(final String schemaPattern) throws SQLException { + int schemasSize = 0; + try (ResultSet schemas = metaData.getSchemas(null, schemaPattern)) { + while (schemas.next()) { + final String schema = schemas.getString("TABLE_SCHEM"); + final String match = Arrays + .stream(databases) + .filter(x -> x.equals(schema)) + .findFirst() + .orElse(null); + Assertions.assertNotNull(match); + schemasSize++; + } + // Check the number of databases found match the actual number of databases + Assertions.assertEquals(databases.length, schemasSize); + } + } + + /** + * Retrieve all tables from database + * + * @param schemaPattern database pattern + * @throws SQLException the exception thrown + */ + private void getAllTables(String schemaPattern) throws SQLException { + final List tableList = Arrays.asList(tables); + final List returnTableList = new ArrayList<>(); + try (ResultSet tables = metaData.getTables(null, schemaPattern, null, null)) { + while (tables.next()) { + returnTableList.add(tables.getString("TABLE_NAME")); + } + } + Assertions.assertEquals(tableList, returnTableList); + } + + /** + * Test getTables returns the tables from the database. + * + * @throws SQLException the exception thrown + */ + public void testTables() throws SQLException { + if (databases.length == 0) { + getAllTables(null); + } + for (String database : databases) { + getAllTables(database); + } + } + + /** + * Test getTables returns tables from database when given matching patterns. + * + * @param tablePattern the table pattern to be tested + * @param index index of table name in the database + * @throws SQLException the exception thrown + */ + public void testTablesWithPattern(final String tablePattern, final int index) throws SQLException { + for (String database : databases) { + try (ResultSet tableResultSet = metaData.getTables(null, database, tablePattern, null)) { + Assertions.assertTrue(tableResultSet.next()); + Assertions.assertEquals(tables[index], tableResultSet.getObject("TABLE_NAME")); + } + } + } + + /** + * Test getTables returns tables from database when given matching patterns. + * + * @param tablePattern the table pattern to be tested + * @param schemaPattern the database pattern to be tested + * @param index index of table name in the database + * @throws SQLException the exception thrown + */ + public void testTablesWithPatternFromDBWithPattern(final String tablePattern, final String schemaPattern, final int index) throws SQLException { + for (String database : databases) { + try (ResultSet tableResultSet = metaData.getTables(null, schemaPattern, tablePattern, null)) { + Assertions.assertTrue(tableResultSet.next()); + Assertions.assertEquals(tables[index], tableResultSet.getObject("TABLE_NAME")); + } + } + } +} diff --git a/integrationtest/src/main/java/software/amazon/timestream/integrationtest/QueryExecutionIntegrationTest.java b/integrationtest/src/main/java/software/amazon/timestream/integrationtest/QueryExecutionIntegrationTest.java index abecdba..441bcf8 100644 --- a/integrationtest/src/main/java/software/amazon/timestream/integrationtest/QueryExecutionIntegrationTest.java +++ b/integrationtest/src/main/java/software/amazon/timestream/integrationtest/QueryExecutionIntegrationTest.java @@ -40,13 +40,15 @@ class QueryExecutionIntegrationTest { @BeforeAll private static void setUp() { - TableManager.createTable(); + TableManager.createDatabase(Constants.DATABASE_NAME); + TableManager.createTable(Constants.TABLE_NAME, Constants.DATABASE_NAME); TableManager.writeRecords(); } @AfterAll private static void cleanUp() { - TableManager.deleteTable(); + TableManager.deleteTable(Constants.TABLE_NAME, Constants.DATABASE_NAME); + TableManager.deleteDatabase(Constants.DATABASE_NAME); } @BeforeEach diff --git a/integrationtest/src/main/java/software/amazon/timestream/integrationtest/TableManager.java b/integrationtest/src/main/java/software/amazon/timestream/integrationtest/TableManager.java index 39a7318..edebd5a 100644 --- a/integrationtest/src/main/java/software/amazon/timestream/integrationtest/TableManager.java +++ b/integrationtest/src/main/java/software/amazon/timestream/integrationtest/TableManager.java @@ -18,7 +18,9 @@ import com.amazonaws.services.timestreamwrite.AmazonTimestreamWrite; import com.amazonaws.services.timestreamwrite.AmazonTimestreamWriteClientBuilder; import com.amazonaws.services.timestreamwrite.model.ConflictException; +import com.amazonaws.services.timestreamwrite.model.CreateDatabaseRequest; import com.amazonaws.services.timestreamwrite.model.CreateTableRequest; +import com.amazonaws.services.timestreamwrite.model.DeleteDatabaseRequest; import com.amazonaws.services.timestreamwrite.model.DeleteTableRequest; import com.amazonaws.services.timestreamwrite.model.Dimension; import com.amazonaws.services.timestreamwrite.model.MeasureValueType; @@ -35,15 +37,91 @@ * Handles table creation and clean up for the integration tests. */ class TableManager { + static String region = "us-east-1"; + + static void setRegion(String regionVal) { + region = regionVal; + } + + static String getRegion() { + return region; + } + + /** + * Creates a new database if not already existed. + * Deletes the database if already existed and then creates a new one. + * + * @param database Database to be created + */ + static void createDatabase(String database) { + final CreateDatabaseRequest createDatabaseRequest = new CreateDatabaseRequest(); + createDatabaseRequest.setDatabaseName(database); + try { + buildWriteClient().createDatabase(createDatabaseRequest); + } catch (ConflictException e) { + final DeleteDatabaseRequest deleteDatabaseRequest = new DeleteDatabaseRequest(); + deleteDatabaseRequest.setDatabaseName(database); + try { + buildWriteClient().deleteDatabase(deleteDatabaseRequest); + } catch (Exception exception) { + System.out.println(exception.getMessage()); + } + buildWriteClient().createDatabase(createDatabaseRequest); + } catch (Exception e) { + System.out.println(e.getMessage()); + } + + } + + /** + * Creates databases if not already existed. + * For each database, deletes the database if already existed and then creates a new one. + * + * @param databases Databases to be created + */ + static void createDatabases(String[] databases) { + for (String database : databases) { + createDatabase(database); + } + } + + /** + * Creates new tables in the database if not already existed. + * Deletes the table if already existed and then creates a new one. + * + * @param tables Tables to be created + * @param database Database to contain the tables + */ + static void createTables(String[] tables, String database) { + for (String table : tables) { + createTable(table, database); + } + } + + /** + * Creates new tables in the databases if not already existed. + * Deletes the table if already existed and then creates a new one. + * + * @param tables Tables to be created + * @param databases List of databases to contain the tables + */ + static void createTables(String[] tables, String[] databases) { + for (String database : databases) { + createTables(tables, database); + } + } /** - * Creates a new table {@link Constants#TABLE_NAME} in the {@link Constants#DATABASE_NAME} if not - * already existed. Deletes the table if already existed and then creates a new one. + * Creates new tables in the database if not already existed. + * Deletes the table if already existed and then creates a new one. + * + * @param table Table to be created + * @param database Database to contain the table */ - static void createTable() { + static void createTable(String table, String database) { final CreateTableRequest createTableRequest = new CreateTableRequest(); - createTableRequest.setDatabaseName(Constants.DATABASE_NAME); - createTableRequest.setTableName(Constants.TABLE_NAME); + createTableRequest.setDatabaseName(database); + createTableRequest.setTableName(table); final RetentionProperties retentionProperties = new RetentionProperties() .withMemoryStoreRetentionPeriodInHours(Constants.HT_TTL_HOURS) .withMagneticStoreRetentionPeriodInDays(Constants.CT_TTL_DAYS); @@ -51,7 +129,7 @@ static void createTable() { try { buildWriteClient().createTable(createTableRequest); } catch (ConflictException e) { - deleteTable(); + deleteTable(table, database); buildWriteClient().createTable(createTableRequest); } } @@ -86,13 +164,71 @@ static void writeRecords() { } /** - * Deletes the table {@link Constants#TABLE_NAME} from {@link Constants#DATABASE_NAME}. + * Deletes the database. Precondition: database is empty + * + * @param database Database to be deleted + */ + static void deleteDatabase(String database) { + final DeleteDatabaseRequest deleteDatabaseRequest = new DeleteDatabaseRequest(); + deleteDatabaseRequest.setDatabaseName(database); + try { + buildWriteClient().deleteDatabase(deleteDatabaseRequest); + } catch (Exception e) { + System.out.println(e.getMessage()); + } + } + + /** + * Deletes the databases in provided array. + * Precondition: databases are empty + * + * @param databases Databases to be deleted + */ + static void deleteDatabases(String[] databases) { + for (String database : databases) { + deleteDatabase(database); + } + } + + /** + * Deletes the table from database + * + * @param table Table to be deleted + * @param database Database to delete the table from */ - static void deleteTable() { + static void deleteTable(String table, String database) { final DeleteTableRequest deleteTableRequest = new DeleteTableRequest(); - deleteTableRequest.setDatabaseName(Constants.DATABASE_NAME); - deleteTableRequest.setTableName(Constants.TABLE_NAME); - buildWriteClient().deleteTable(deleteTableRequest); + deleteTableRequest.setDatabaseName(database); + deleteTableRequest.setTableName(table); + try { + buildWriteClient().deleteTable(deleteTableRequest); + } catch (Exception e) { + System.out.println(e.getMessage()); + } + } + + /** + * Deletes the tables from database + * + * @param tables Tables to be deleted + * @param database Database to delete the tables from + */ + static void deleteTables(String[] tables, String database) { + for (String table : tables) { + deleteTable(table, database); + } + } + + /** + * Deletes new tables in the databases + * + * @param tables Tables to be created + * @param databases List of databases that contain the tables + */ + static void deleteTables(String[] tables, String[] databases) { + for (String database : databases) { + deleteTables(tables, database); + } } /** @@ -101,6 +237,6 @@ static void deleteTable() { * @return the {@link AmazonTimestreamWrite}. */ private static AmazonTimestreamWrite buildWriteClient() { - return AmazonTimestreamWriteClientBuilder.standard().withRegion("us-east-1").build(); + return AmazonTimestreamWriteClientBuilder.standard().withRegion(getRegion()).build(); } } diff --git a/jdbc/src/main/java/software/amazon/timestream/jdbc/TimestreamSchemasResultSet.java b/jdbc/src/main/java/software/amazon/timestream/jdbc/TimestreamSchemasResultSet.java index 56fafea..c2bc550 100644 --- a/jdbc/src/main/java/software/amazon/timestream/jdbc/TimestreamSchemasResultSet.java +++ b/jdbc/src/main/java/software/amazon/timestream/jdbc/TimestreamSchemasResultSet.java @@ -99,7 +99,7 @@ private void populateCurrentRows(TimestreamConnection connection, String schemaP final String query = "SHOW DATABASES" + (Strings.isNullOrEmpty(schemaPattern) ? "" : " LIKE '" + schemaPattern + "'"); try (ResultSet rs = statement.executeQuery(query)) { - while (rs != null && rs.next()) { + while (rs.next()) { databases.add(new Row().withData( new Datum().withScalarValue(rs.getString(1)), NULL_DATUM diff --git a/jdbc/src/test/java/software/amazon/timestream/jdbc/TimestreamDatabaseMetaDataTest.java b/jdbc/src/test/java/software/amazon/timestream/jdbc/TimestreamDatabaseMetaDataTest.java index 3deee61..03e79e5 100644 --- a/jdbc/src/test/java/software/amazon/timestream/jdbc/TimestreamDatabaseMetaDataTest.java +++ b/jdbc/src/test/java/software/amazon/timestream/jdbc/TimestreamDatabaseMetaDataTest.java @@ -31,8 +31,8 @@ import java.sql.ResultSetMetaData; import java.sql.SQLException; import java.util.ArrayList; -import java.util.Arrays; import java.util.List; +import java.util.Objects; import java.util.Properties; /** @@ -121,7 +121,7 @@ void testGetSchemasWithSchemaPattern(String schemaPattern, int expectedValue) th @ParameterizedTest @ValueSource(strings = {"invalidDB"}) void testGetSchemasWithInvalidSchemaPattern(String schemaPattern) throws SQLException { - initializeWithTwoResults(); + initializeWithResult(); try (ResultSet resultSet = dbMetaData .getSchemas(null, schemaPattern)) { testGetSchemasResult(resultSet, 0); @@ -394,6 +394,7 @@ private void initializeWithResult() throws SQLException { Mockito.when(mockStatement.executeQuery("SHOW DATABASES LIKE 'testDB'")).thenReturn(dbResultSet); Mockito.when(mockStatement.executeQuery("SHOW DATABASES LIKE '%testDB%'")).thenReturn(dbResultSet); Mockito.when(mockStatement.executeQuery("SHOW DATABASES LIKE 'emptyDB'")).thenReturn(emptydbResultSet); + Mockito.when(mockStatement.executeQuery("SHOW DATABASES LIKE 'invalidDB'")).thenReturn(emptyResultSet); final ResultSet singleTableResultSet = Mockito.mock(ResultSet.class); Mockito.when(singleTableResultSet.next()).thenReturn(true).thenReturn(false); @@ -412,7 +413,7 @@ private void initializeWithResult() throws SQLException { Mockito.when(mockStatement.executeQuery("SHOW TABLES FROM \"testDB\" LIKE '%Ta_le'")) .thenReturn(singleTableResultSet); Mockito.when(mockStatement.executeQuery("SHOW TABLES FROM \"emptyDB\"")) - .thenReturn(emptyResultSet); + .thenReturn(emptyResultSet); final ResultSet columnsResultSet = Mockito.mock(ResultSet.class); Mockito.when(columnsResultSet.next()).thenReturn(true).thenReturn(true).thenReturn(false); @@ -420,7 +421,7 @@ private void initializeWithResult() throws SQLException { Mockito.when(mockStatement.executeQuery("DESCRIBE \"testDB\".\"testTable\"")) .thenReturn(columnsResultSet); Mockito.when(mockStatement.executeQuery("DESCRIBE \"testDB\".\"secondTable\"")) - .thenReturn(columnsResultSet); + .thenReturn(columnsResultSet); } /** @@ -469,7 +470,7 @@ private void testGetSchemasResult(ResultSet resultSet, int expectedNumRows) thro while (resultSet.next()) { int match = 0; for (int i = 1; i <= resultSet.getMetaData().getColumnCount(); ++i) { - if (strings.get(numRows)[i-1] == resultSet.getString(i)) { + if (Objects.equals(strings.get(numRows)[i - 1], resultSet.getString(i))) { match++; } }