/* * 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.facebook.presto.plugin.blackhole; import com.facebook.presto.Session; import com.facebook.presto.metadata.QualifiedObjectName; import com.facebook.presto.testing.MaterializedResult; import com.facebook.presto.testing.MaterializedRow; import com.facebook.presto.testing.QueryRunner; import com.google.common.base.Stopwatch; import com.google.common.collect.Iterables; import io.airlift.units.Duration; import org.testng.annotations.AfterTest; import org.testng.annotations.BeforeTest; import org.testng.annotations.Test; import java.math.BigDecimal; import java.sql.Date; import java.sql.SQLException; import java.sql.Timestamp; import java.util.List; import static com.facebook.presto.plugin.blackhole.BlackHoleConnector.FIELD_LENGTH_PROPERTY; import static com.facebook.presto.plugin.blackhole.BlackHoleConnector.PAGES_PER_SPLIT_PROPERTY; import static com.facebook.presto.plugin.blackhole.BlackHoleConnector.PAGE_PROCESSING_DELAY; import static com.facebook.presto.plugin.blackhole.BlackHoleConnector.ROWS_PER_PAGE_PROPERTY; import static com.facebook.presto.plugin.blackhole.BlackHoleConnector.SPLIT_COUNT_PROPERTY; import static com.facebook.presto.plugin.blackhole.BlackHoleQueryRunner.createQueryRunner; import static com.facebook.presto.testing.TestingSession.testSessionBuilder; import static io.airlift.testing.Assertions.assertGreaterThan; import static java.lang.String.format; import static java.util.concurrent.TimeUnit.MILLISECONDS; import static java.util.concurrent.TimeUnit.SECONDS; import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertTrue; import static org.testng.Assert.fail; @Test(singleThreaded = true) public class TestBlackHoleSmoke { private QueryRunner queryRunner; @BeforeTest public void setUp() throws Exception { queryRunner = createQueryRunner(); } @AfterTest public void tearDown() { assertThatNoBlackHoleTableIsCreated(); queryRunner.close(); } @Test public void createTableWhenTableIsAlreadyCreated() throws SQLException { String createTableSql = "CREATE TABLE nation as SELECT * FROM tpch.tiny.nation"; queryRunner.execute(createTableSql); try { queryRunner.execute(createTableSql); fail("Expected exception to be thrown here!"); } catch (RuntimeException ex) { // it has to RuntimeException as FailureInfo$FailureException is private assertTrue(ex.getMessage().equals("line 1:1: Destination table 'blackhole.default.nation' already exists")); } finally { assertThatQueryReturnsValue("DROP TABLE nation", true); } } @Test public void blackHoleConnectorUsage() throws SQLException { assertThatQueryReturnsValue("CREATE TABLE nation as SELECT * FROM tpch.tiny.nation", 25L); List<QualifiedObjectName> tableNames = listBlackHoleTables(); assertTrue(tableNames.size() == 1, "Expected only one table."); assertTrue(tableNames.get(0).getObjectName().equals("nation"), "Expected 'nation' table."); assertThatQueryReturnsValue("INSERT INTO nation SELECT * FROM tpch.tiny.nation", 25L); assertThatQueryReturnsValue("INSERT INTO nation SELECT * FROM tpch.tiny.nation", 25L); assertThatQueryReturnsValue("SELECT count(*) FROM nation", 0L); assertThatQueryReturnsValue("DROP TABLE nation", true); } @Test public void notAllPropertiesSetForDataGeneration() { Session session = testSessionBuilder() .setCatalog("blackhole") .setSchema("default") .build(); try { assertThatQueryReturnsValue( format("CREATE TABLE nation WITH ( %s = 3, %s = 1 ) as SELECT * FROM tpch.tiny.nation", ROWS_PER_PAGE_PROPERTY, SPLIT_COUNT_PROPERTY), 25L, session); fail("Expected exception to be thrown here!"); } catch (RuntimeException ex) { // expected exception } } @Test public void createTableWithDistribution() { assertThatQueryReturnsValue( "CREATE TABLE distributed_test WITH ( distributed_on = array['orderkey'] ) AS SELECT * FROM tpch.tiny.orders", 15000L); assertThatQueryReturnsValue("DROP TABLE distributed_test", true); } @Test public void dataGenerationUsage() { Session session = testSessionBuilder() .setCatalog("blackhole") .setSchema("default") .build(); assertThatQueryReturnsValue( format("CREATE TABLE nation WITH ( %s = 3, %s = 2, %s = 1 ) as SELECT * FROM tpch.tiny.nation", ROWS_PER_PAGE_PROPERTY, PAGES_PER_SPLIT_PROPERTY, SPLIT_COUNT_PROPERTY), 25L, session); assertThatQueryReturnsValue("SELECT count(*) FROM nation", 6L, session); assertThatQueryReturnsValue("INSERT INTO nation SELECT * FROM tpch.tiny.nation", 25L, session); assertThatQueryReturnsValue("SELECT count(*) FROM nation", 6L, session); MaterializedResult rows = queryRunner.execute(session, "SELECT * FROM nation LIMIT 1"); assertEquals(rows.getRowCount(), 1); MaterializedRow row = Iterables.getOnlyElement(rows); assertEquals(row.getFieldCount(), 4); assertEquals(row.getField(0), 0L); assertEquals(row.getField(1), "****************"); assertEquals(row.getField(2), 0L); assertEquals(row.getField(3), "****************"); assertThatQueryReturnsValue("DROP TABLE nation", true); } @Test public void fieldLength() { Session session = testSessionBuilder() .setCatalog("blackhole") .setSchema("default") .build(); assertThatQueryReturnsValue( format("CREATE TABLE nation WITH ( %s = 8, %s = 1, %s = 1, %s = 1 ) AS " + "SELECT nationkey, name, regionkey, comment, 'abc' short_varchar FROM tpch.tiny.nation", FIELD_LENGTH_PROPERTY, ROWS_PER_PAGE_PROPERTY, PAGES_PER_SPLIT_PROPERTY, SPLIT_COUNT_PROPERTY), 25L, session); MaterializedResult rows = queryRunner.execute(session, "SELECT * FROM nation"); assertEquals(rows.getRowCount(), 1); MaterializedRow row = Iterables.getOnlyElement(rows); assertEquals(row.getFieldCount(), 5); assertEquals(row.getField(0), 0L); assertEquals(row.getField(1), "********"); assertEquals(row.getField(2), 0L); assertEquals(row.getField(3), "********"); assertEquals(row.getField(4), "***"); // this one is shorter due to column type being VARCHAR(3) assertThatQueryReturnsValue("DROP TABLE nation", true); } @Test public void testInsertAllTypes() throws Exception { createBlackholeAllTypesTable(); assertThatQueryReturnsValue( "INSERT INTO blackhole_all_types VALUES (" + "'abc', " + "BIGINT '1', " + "INTEGER '2', " + "SMALLINT '3', " + "TINYINT '4', " + "REAL '5.1', " + "DOUBLE '5.2', " + "true, " + "DATE '2014-01-02', " + "TIMESTAMP '2014-01-02 12:12', " + "cast('bar' as varbinary), " + "DECIMAL '3.14', " + "DECIMAL '1234567890.123456789')", 1L); dropBlackholeAllTypesTable(); } @Test public void testSelectAllTypes() throws Exception { createBlackholeAllTypesTable(); MaterializedResult rows = queryRunner.execute("SELECT * FROM blackhole_all_types"); assertEquals(rows.getRowCount(), 1); MaterializedRow row = Iterables.getOnlyElement(rows); assertEquals(row.getFieldCount(), 13); assertEquals(row.getField(0), "**********"); assertEquals(row.getField(1), 0L); assertEquals(row.getField(2), 0); assertEquals(row.getField(3), (short) 0); assertEquals(row.getField(4), (byte) 0); assertEquals(row.getField(5), 0.0f); assertEquals(row.getField(6), 0.0); assertEquals(row.getField(7), false); assertEquals(row.getField(8), new Date(0)); assertEquals(row.getField(9), new Timestamp(0)); assertEquals(row.getField(10), "****************".getBytes()); assertEquals(row.getField(11), new BigDecimal("0.00")); assertEquals(row.getField(12), new BigDecimal("00000000000000000000.0000000000")); dropBlackholeAllTypesTable(); } private void createBlackholeAllTypesTable() { assertThatQueryReturnsValue( format("CREATE TABLE blackhole_all_types (" + " _varchar VARCHAR(10)" + ", _bigint BIGINT" + ", _integer INTEGER" + ", _smallint SMALLINT" + ", _tinyint TINYINT" + ", _real REAL" + ", _double DOUBLE" + ", _boolean BOOLEAN" + ", _date DATE" + ", _timestamp TIMESTAMP" + ", _varbinary VARBINARY" + ", _decimal_short DECIMAL(3,2)" + ", _decimal_long DECIMAL(30,10)" + ") WITH ( %s = 1, %s = 1, %s = 1 ) ", ROWS_PER_PAGE_PROPERTY, PAGES_PER_SPLIT_PROPERTY, SPLIT_COUNT_PROPERTY), true); } private void dropBlackholeAllTypesTable() { assertThatQueryReturnsValue("DROP TABLE IF EXISTS blackhole_all_types", true); } @Test public void pageProcessingDelay() throws Exception { Session session = testSessionBuilder() .setCatalog("blackhole") .setSchema("default") .build(); Duration pageProcessingDelay = new Duration(1, SECONDS); assertThatQueryReturnsValue( format("CREATE TABLE nation WITH ( %s = 8, %s = 1, %s = 1, %s = 1, %s = '%s' ) AS " + "SELECT * FROM tpch.tiny.nation", FIELD_LENGTH_PROPERTY, ROWS_PER_PAGE_PROPERTY, PAGES_PER_SPLIT_PROPERTY, SPLIT_COUNT_PROPERTY, PAGE_PROCESSING_DELAY, pageProcessingDelay), 25L, session); Stopwatch stopwatch = Stopwatch.createStarted(); assertEquals(queryRunner.execute(session, "SELECT * FROM nation").getRowCount(), 1); queryRunner.execute(session, "INSERT INTO nation SELECT CAST(null AS BIGINT), CAST(null AS VARCHAR(25)), CAST(null AS BIGINT), CAST(null AS VARCHAR(152))"); stopwatch.stop(); assertGreaterThan(stopwatch.elapsed(MILLISECONDS), pageProcessingDelay.toMillis()); assertThatQueryReturnsValue("DROP TABLE nation", true); } private void assertThatNoBlackHoleTableIsCreated() { assertTrue(listBlackHoleTables().size() == 0, "No blackhole tables expected"); } private List<QualifiedObjectName> listBlackHoleTables() { return queryRunner.listTables(queryRunner.getDefaultSession(), "blackhole", "default"); } private void assertThatQueryReturnsValue(String sql, Object expected) { assertThatQueryReturnsValue(sql, expected, null); } private void assertThatQueryReturnsValue(String sql, Object expected, Session session) { MaterializedResult rows = session == null ? queryRunner.execute(sql) : queryRunner.execute(session, sql); MaterializedRow materializedRow = Iterables.getOnlyElement(rows); int fieldCount = materializedRow.getFieldCount(); assertTrue(fieldCount == 1, format("Expected only one column, but got '%d'", fieldCount)); Object value = materializedRow.getField(0); assertEquals(value, expected); assertTrue(Iterables.getOnlyElement(rows).getFieldCount() == 1); } }