IGNITE-6416: SQL: dynamic columns tests refactoring. This closes #2774.
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/43aa4a89 Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/43aa4a89 Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/43aa4a89 Branch: refs/heads/ignite-zk Commit: 43aa4a8938bae9c77921764826ceb9e10c59404b Parents: 9a0e36b Author: devozerov <voze...@gridgain.com> Authored: Mon Nov 20 11:02:09 2017 +0300 Committer: devozerov <voze...@gridgain.com> Committed: Mon Nov 20 11:02:09 2017 +0300 ---------------------------------------------------------------------- ...ynamicColumnsAbstractConcurrentSelfTest.java | 25 +-- .../cache/index/DynamicColumnsAbstractTest.java | 180 ++++--------------- .../H2DynamicColumnsAbstractBasicSelfTest.java | 35 ++-- 3 files changed, 66 insertions(+), 174 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ignite/blob/43aa4a89/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/DynamicColumnsAbstractConcurrentSelfTest.java ---------------------------------------------------------------------- diff --git a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/DynamicColumnsAbstractConcurrentSelfTest.java b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/DynamicColumnsAbstractConcurrentSelfTest.java index 3d4b2a3..0263f5c 100644 --- a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/DynamicColumnsAbstractConcurrentSelfTest.java +++ b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/DynamicColumnsAbstractConcurrentSelfTest.java @@ -149,7 +149,7 @@ public abstract class DynamicColumnsAbstractConcurrentSelfTest extends DynamicCo // Start servers. Ignite srv1 = ignitionStart(serverConfiguration(1), null); Ignite srv2 = ignitionStart(serverConfiguration(2), null); - ignitionStart(serverConfiguration(3, true), finishLatch); + Ignite srv3 = ignitionStart(serverConfiguration(3, true), finishLatch); UUID srv1Id = srv1.cluster().localNode().id(); UUID srv2Id = srv2.cluster().localNode().id(); @@ -175,7 +175,8 @@ public abstract class DynamicColumnsAbstractConcurrentSelfTest extends DynamicCo colFut1.get(); - checkNodesState(TBL_NAME, c("age", Integer.class.getName())); + // Port number is for srv2. + checkTableState(QueryUtils.DFLT_SCHEMA, TBL_NAME, 10801, c("age", Integer.class.getName())); // Test migration from normal server to non-affinity server. idxLatch = blockIndexing(srv2Id); @@ -191,7 +192,11 @@ public abstract class DynamicColumnsAbstractConcurrentSelfTest extends DynamicCo colFut2.get(); - checkNodesState(TBL_NAME, c("city", String.class.getName())); + // Let's actually create cache on non affinity server. + srv3.cache(QueryUtils.createTableCacheName(QueryUtils.DFLT_SCHEMA, "PERSON")); + + // Port number is for srv3. + checkTableState(QueryUtils.DFLT_SCHEMA, TBL_NAME, 10802, c("city", String.class.getName())); } /** @@ -239,7 +244,7 @@ public abstract class DynamicColumnsAbstractConcurrentSelfTest extends DynamicCo U.await(finishLatch); - checkNodesState(TBL_NAME, c1, c2); + checkTableState(QueryUtils.DFLT_SCHEMA, TBL_NAME, c1, c2); } /** @@ -276,7 +281,7 @@ public abstract class DynamicColumnsAbstractConcurrentSelfTest extends DynamicCo U.await(finishLatch); - checkNodesState(TBL_NAME, c); + checkTableState(QueryUtils.DFLT_SCHEMA, TBL_NAME, c); } /** @@ -335,7 +340,7 @@ public abstract class DynamicColumnsAbstractConcurrentSelfTest extends DynamicCo finishLatch.await(); // Make sure new column is there. - checkNodesState(TBL_NAME, c("v", Integer.class.getName())); + checkTableState(QueryUtils.DFLT_SCHEMA, TBL_NAME, c("v", Integer.class.getName())); run(srv1, "update person set \"v\" = case when mod(id, 2) <> 0 then substring(name, 7, length(name) - 6) " + "else null end"); @@ -429,7 +434,7 @@ public abstract class DynamicColumnsAbstractConcurrentSelfTest extends DynamicCo CountDownLatch idxLatch1 = blockIndexing(srv1); CountDownLatch idxLatch2 = blockIndexing(srv2); - QueryField c = c("salary", Float.class.getName()); + QueryField c = c("salary", Double.class.getName()); final IgniteInternalFuture<?> idxFut = addCols(srv1, QueryUtils.DFLT_SCHEMA, c); @@ -449,7 +454,7 @@ public abstract class DynamicColumnsAbstractConcurrentSelfTest extends DynamicCo // Validate index state. idxFut.get(); - checkNodesState(TBL_NAME, c); + checkTableState(QueryUtils.DFLT_SCHEMA, TBL_NAME, c); } /** @@ -655,7 +660,7 @@ public abstract class DynamicColumnsAbstractConcurrentSelfTest extends DynamicCo } }); - checkNodeState((IgniteEx)cli, schemaName, TBL_NAME, cols); + checkTableState(schemaName, TBL_NAME, cols); } /** @@ -844,7 +849,7 @@ public abstract class DynamicColumnsAbstractConcurrentSelfTest extends DynamicCo idxQry += ')'; - checkNodesState(TBL_NAME, expCols); + checkTableState(QueryUtils.DFLT_SCHEMA, TBL_NAME, expCols); put(cli, 0, 500); http://git-wip-us.apache.org/repos/asf/ignite/blob/43aa4a89/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/DynamicColumnsAbstractTest.java ---------------------------------------------------------------------- diff --git a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/DynamicColumnsAbstractTest.java b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/DynamicColumnsAbstractTest.java index 2beea8b..34be76e 100644 --- a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/DynamicColumnsAbstractTest.java +++ b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/DynamicColumnsAbstractTest.java @@ -17,41 +17,34 @@ package org.apache.ignite.internal.processors.cache.index; -import java.util.Arrays; -import java.util.Collection; +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; import java.util.Collections; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.List; -import java.util.Map; import java.util.concurrent.Callable; import org.apache.ignite.Ignite; import org.apache.ignite.IgniteCache; -import org.apache.ignite.Ignition; import org.apache.ignite.cache.QueryEntity; import org.apache.ignite.cache.query.SqlFieldsQuery; import org.apache.ignite.configuration.CacheConfiguration; +import org.apache.ignite.configuration.ClientConnectorConfiguration; +import org.apache.ignite.configuration.DataRegionConfiguration; import org.apache.ignite.configuration.DataStorageConfiguration; import org.apache.ignite.configuration.IgniteConfiguration; -import org.apache.ignite.configuration.DataRegionConfiguration; import org.apache.ignite.internal.IgniteEx; -import org.apache.ignite.internal.processors.cache.DynamicCacheDescriptor; -import org.apache.ignite.internal.processors.query.GridQueryTypeDescriptor; import org.apache.ignite.internal.processors.query.IgniteSQLException; import org.apache.ignite.internal.processors.query.QueryField; -import org.apache.ignite.internal.processors.query.QuerySchema; import org.apache.ignite.internal.processors.query.QueryUtils; -import org.apache.ignite.internal.processors.query.h2.IgniteH2Indexing; -import org.apache.ignite.internal.processors.query.h2.opt.GridH2KeyValueRowOnheap; -import org.apache.ignite.internal.processors.query.h2.opt.GridH2RowDescriptor; -import org.apache.ignite.internal.processors.query.h2.opt.GridH2Table; -import org.apache.ignite.internal.util.typedef.F; import org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi; import org.apache.ignite.spi.discovery.tcp.ipfinder.TcpDiscoveryIpFinder; import org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder; import org.apache.ignite.testframework.GridTestUtils; import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest; -import org.h2.table.Column; import org.h2.value.DataType; /** @@ -68,158 +61,61 @@ public abstract class DynamicColumnsAbstractTest extends GridCommonAbstractTest private static final TcpDiscoveryIpFinder IP_FINDER = new TcpDiscoveryVmIpFinder(true); /** - * Check that given columns have been added to all related structures on target node exactly where needed - * (namely, schema in cache descriptor, type descriptor on started cache, and H2 state on started cache). - * @param node Target node. + * Check that given columns are seen by client. * @param schemaName Schema name to look for the table in. * @param tblName Table name to check. * @param cols Columns whose presence must be checked. */ - static void checkNodeState(IgniteEx node, String schemaName, String tblName, QueryField... cols) { - String cacheName = F.eq(schemaName, QueryUtils.DFLT_SCHEMA) ? - QueryUtils.createTableCacheName(schemaName, tblName) : schemaName; - - // Schema state check - should pass regardless of cache state. - { - DynamicCacheDescriptor desc = node.context().cache().cacheDescriptor(cacheName); - - assertNotNull("Cache descriptor not found", desc); - - assertTrue(desc.sql() == F.eq(schemaName, QueryUtils.DFLT_SCHEMA)); - - QuerySchema schema = desc.schema(); - - assertNotNull(schema); - - QueryEntity entity = null; - - for (QueryEntity e : schema.entities()) { - if (F.eq(tblName, e.getTableName())) { - entity = e; - - break; - } - } - - assertNotNull("Query entity not found", entity); - - Iterator<Map.Entry<String, String>> it = entity.getFields().entrySet().iterator(); - - for (int i = entity.getFields().size() - cols.length; i > 0 && it.hasNext(); i--) - it.next(); - - for (QueryField col : cols) { - assertTrue("New column not found in query entity: " + col.name(), it.hasNext()); - - Map.Entry<String, String> e = it.next(); - - assertEquals(col.name(), e.getKey()); - - assertEquals(col.typeName(), e.getValue()); - - if (!col.isNullable()) { - assertNotNull(entity.getNotNullFields()); + static void checkTableState(String schemaName, String tblName, QueryField... cols) throws SQLException { + checkTableState(schemaName, tblName, ClientConnectorConfiguration.DFLT_PORT, cols); + } - assertTrue(entity.getNotNullFields().contains(col.name())); - } - else if (entity.getNotNullFields() != null) - assertFalse(entity.getNotNullFields().contains(col.name())); - } - } + /** + * Check that given columns are seen by client. + * @param schemaName Schema name to look for the table in. + * @param tblName Table name to check. + * @param port Port number. + * @param cols Columns whose presence must be checked. + */ + static void checkTableState(String schemaName, String tblName, int port, QueryField... cols) throws SQLException { + List<QueryField> flds = new ArrayList<>(); - // Start cache on this node if we haven't yet. - node.cache(cacheName); + try (Connection c = DriverManager.getConnection("jdbc:ignite:thin://127.0.0.1:" + port)) { + try (ResultSet rs = c.getMetaData().getColumns(null, schemaName, tblName, "%")) { + while (rs.next()) { + String name = rs.getString("COLUMN_NAME"); - // Type descriptor state check. - { - Collection<GridQueryTypeDescriptor> descs = node.context().query().types(cacheName); + short type = rs.getShort("DATA_TYPE"); - GridQueryTypeDescriptor desc = null; + String typeClsName = DataType.getTypeClassName(DataType.convertSQLTypeToValueType(type)); - for (GridQueryTypeDescriptor d : descs) { - if (F.eq(tblName, d.tableName())) { - desc = d; + short nullable = rs.getShort("NULLABLE"); - break; + flds.add(new QueryField(name, typeClsName, nullable == 1)); } } - - assertNotNull("Type descriptor not found", desc); - - Iterator<Map.Entry<String, Class<?>>> it = desc.fields().entrySet().iterator(); - - for (int i = desc.fields().size() - cols.length; i > 0 && it.hasNext(); i--) - it.next(); - - for (QueryField col : cols) { - assertTrue("New column not found in type descriptor: " + col.name(), it.hasNext()); - - Map.Entry<String, Class<?>> e = it.next(); - - assertEquals(col.name(), e.getKey()); - - assertEquals(col.typeName(), e.getValue().getName()); - - assertTrue(col.isNullable() || desc.property(col.name()).notNull()); - } } - // H2 table state check. - { - GridH2Table tbl = ((IgniteH2Indexing)node.context().query().getIndexing()).dataTable(schemaName, - tblName); - - assertNotNull("Table not found", tbl); - - Iterator<Column> colIt = Arrays.asList(tbl.getColumns()).iterator(); - - GridH2RowDescriptor rowDesc = tbl.rowDescriptor(); - - int i = 0; + Iterator<QueryField> it = flds.iterator(); - for (; i < tbl.getColumns().length - cols.length && colIt.hasNext(); i++) - colIt.next(); + for (int i = flds.size() - cols.length; i > 0 && it.hasNext(); i--) + it.next(); - for (QueryField col : cols) { - assertTrue("New column not found in H2 table: " + col.name(), colIt.hasNext()); + for (QueryField exp : cols) { + assertTrue("New column not found in metadata: " + exp.name(), it.hasNext()); - assertTrue(colIt.hasNext()); + QueryField act = it.next(); - Column c = colIt.next(); + assertEquals(exp.name(), act.name()); - assertEquals(col.name(), c.getName()); + assertEquals(exp.typeName(), act.typeName()); - assertEquals(col.typeName(), DataType.getTypeClassName(c.getType())); - - assertFalse(rowDesc.isKeyValueOrVersionColumn(i)); - - assertEquals(col.isNullable(), c.isNullable()); - - try { - assertEquals(DataType.getTypeFromClass(Class.forName(col.typeName())), - rowDesc.fieldType(i - GridH2KeyValueRowOnheap.DEFAULT_COLUMNS_COUNT)); - } - catch (ClassNotFoundException e) { - throw new AssertionError(e); - } - - i++; - } + // TODO uncomment after IGNITE-6529 is implemented. + //assertEquals(exp.isNullable(), act.isNullable()); } } /** - * Check that given columns have been added to all related structures on all started nodes (namely, schema - * in cache descriptor, type descriptor on started cache, and H2 state on started cache). - * @param tblName Table name to check. - * @param cols Columns whose presence must be checked. - */ - static void checkNodesState(String tblName, QueryField... cols) { - for (Ignite node : Ignition.allGrids()) - checkNodeState((IgniteEx)node, QueryUtils.DFLT_SCHEMA, tblName, cols); - } - - /** * @param name New column name. * @param typeName Class name for this new column's data type. * @return New column with given name and type. http://git-wip-us.apache.org/repos/asf/ignite/blob/43aa4a89/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/H2DynamicColumnsAbstractBasicSelfTest.java ---------------------------------------------------------------------- diff --git a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/H2DynamicColumnsAbstractBasicSelfTest.java b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/H2DynamicColumnsAbstractBasicSelfTest.java index b9f8c61..e4681ae 100644 --- a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/H2DynamicColumnsAbstractBasicSelfTest.java +++ b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/cache/index/H2DynamicColumnsAbstractBasicSelfTest.java @@ -17,17 +17,16 @@ package org.apache.ignite.internal.processors.cache.index; +import java.sql.SQLException; import java.util.Arrays; import java.util.Collections; import java.util.List; -import org.apache.ignite.Ignite; import org.apache.ignite.IgniteCache; import org.apache.ignite.Ignition; import org.apache.ignite.binary.BinaryObject; import org.apache.ignite.cache.query.annotations.QuerySqlField; import org.apache.ignite.configuration.CacheConfiguration; import org.apache.ignite.configuration.IgniteConfiguration; -import org.apache.ignite.internal.IgniteEx; import org.apache.ignite.internal.processors.query.QueryField; import org.apache.ignite.internal.processors.query.QueryUtils; import org.apache.ignite.testframework.config.GridTestProperties; @@ -97,29 +96,25 @@ public abstract class H2DynamicColumnsAbstractBasicSelfTest extends DynamicColum /** * Test column addition to the end of the columns list. */ - public void testAddColumnSimple() { + public void testAddColumnSimple() throws SQLException { run("ALTER TABLE Person ADD COLUMN age int"); doSleep(500); QueryField c = c("AGE", Integer.class.getName()); - for (Ignite node : Ignition.allGrids()) - checkNodeState((IgniteEx)node, QueryUtils.DFLT_SCHEMA, "PERSON", c); + checkTableState(QueryUtils.DFLT_SCHEMA, "PERSON", c); } /** * Test column addition to the end of the columns list. */ - public void testAddFewColumnsSimple() { + public void testAddFewColumnsSimple() throws SQLException { run("ALTER TABLE Person ADD COLUMN (age int, \"city\" varchar)"); doSleep(500); - for (Ignite node : Ignition.allGrids()) - checkNodeState((IgniteEx)node, QueryUtils.DFLT_SCHEMA, "PERSON", - c("AGE", Integer.class.getName()), - c("city", String.class.getName())); + checkTableState(QueryUtils.DFLT_SCHEMA, "PERSON", c("AGE", Integer.class.getName()), c("city", String.class.getName())); } /** @@ -217,22 +212,21 @@ public abstract class H2DynamicColumnsAbstractBasicSelfTest extends DynamicColum /** * Test that we can add columns dynamically to tables associated with non dynamic caches as well. */ - public void testAddColumnToNonDynamicCache() { + public void testAddColumnToNonDynamicCache() throws SQLException { run("ALTER TABLE \"idx\".PERSON ADD COLUMN CITY varchar"); doSleep(500); QueryField c = c("CITY", String.class.getName()); - for (Ignite node : Ignition.allGrids()) - checkNodeState((IgniteEx)node, "idx", "PERSON", c); + checkTableState("idx", "PERSON", c); } /** * Test that we can add columns dynamically to tables associated with non dynamic caches storing user types as well. */ @SuppressWarnings("unchecked") - public void testAddColumnToNonDynamicCacheWithRealValueType() { + public void testAddColumnToNonDynamicCacheWithRealValueType() throws SQLException { CacheConfiguration<Integer, City> ccfg = defaultCacheConfiguration().setName("City") .setIndexedTypes(Integer.class, City.class); @@ -244,8 +238,7 @@ public abstract class H2DynamicColumnsAbstractBasicSelfTest extends DynamicColum QueryField c = c("POPULATION", Integer.class.getName()); - for (Ignite node : Ignition.allGrids()) - checkNodeState((IgniteEx)node, "City", "CITY", c); + checkTableState("City", "CITY", c); run(cache, "INSERT INTO \"City\".City (_key, id, name, state, population) values " + "(1, 1, 'Washington', 'DC', 2500000)"); @@ -276,29 +269,27 @@ public abstract class H2DynamicColumnsAbstractBasicSelfTest extends DynamicColum /** * Test addition of column with not null constraint. */ - public void testAddNotNullColumn() { + public void testAddNotNullColumn() throws SQLException { run("ALTER TABLE Person ADD COLUMN age int NOT NULL"); doSleep(500); QueryField c = new QueryField("AGE", Integer.class.getName(), false); - for (Ignite node : Ignition.allGrids()) - checkNodeState((IgniteEx)node, QueryUtils.DFLT_SCHEMA, "PERSON", c); + checkTableState(QueryUtils.DFLT_SCHEMA, "PERSON", c); } /** * Test addition of column explicitly defined as nullable. */ - public void testAddNullColumn() { + public void testAddNullColumn() throws SQLException { run("ALTER TABLE Person ADD COLUMN age int NULL"); doSleep(500); QueryField c = new QueryField("AGE", Integer.class.getName(), true); - for (Ignite node : Ignition.allGrids()) - checkNodeState((IgniteEx)node, QueryUtils.DFLT_SCHEMA, "PERSON", c); + checkTableState(QueryUtils.DFLT_SCHEMA, "PERSON", c); } /**