You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hive.apache.org by pv...@apache.org on 2018/01/27 19:17:28 UTC
[1/2] hive git commit: HIVE-18484: Create tests to cover
listPartition(s) methods (Adam Szita,
reviewed by Marta Kuczora and Peter Vary)
Repository: hive
Updated Branches:
refs/heads/master d95fd2071 -> 1833ac9bd
HIVE-18484: Create tests to cover listPartition(s) methods (Adam Szita, reviewed by Marta Kuczora and Peter Vary)
Project: http://git-wip-us.apache.org/repos/asf/hive/repo
Commit: http://git-wip-us.apache.org/repos/asf/hive/commit/fa0a8d27
Tree: http://git-wip-us.apache.org/repos/asf/hive/tree/fa0a8d27
Diff: http://git-wip-us.apache.org/repos/asf/hive/diff/fa0a8d27
Branch: refs/heads/master
Commit: fa0a8d27d4149cc5cc2dbb49d8eb6b03f46bc279
Parents: d95fd20
Author: Peter Vary <pv...@cloudera.com>
Authored: Sat Jan 27 20:07:48 2018 +0100
Committer: Peter Vary <pv...@cloudera.com>
Committed: Sat Jan 27 20:07:48 2018 +0100
----------------------------------------------------------------------
.../metastore/client/TestListPartitions.java | 1353 ++++++++++++++++++
1 file changed, 1353 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/hive/blob/fa0a8d27/standalone-metastore/src/test/java/org/apache/hadoop/hive/metastore/client/TestListPartitions.java
----------------------------------------------------------------------
diff --git a/standalone-metastore/src/test/java/org/apache/hadoop/hive/metastore/client/TestListPartitions.java b/standalone-metastore/src/test/java/org/apache/hadoop/hive/metastore/client/TestListPartitions.java
new file mode 100644
index 0000000..f4fa73b
--- /dev/null
+++ b/standalone-metastore/src/test/java/org/apache/hadoop/hive/metastore/client/TestListPartitions.java
@@ -0,0 +1,1353 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 org.apache.hadoop.hive.metastore.client;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import org.apache.hadoop.hive.metastore.IMetaStoreClient;
+import org.apache.hadoop.hive.metastore.api.Database;
+import org.apache.hadoop.hive.metastore.api.FieldSchema;
+import org.apache.hadoop.hive.metastore.api.MetaException;
+import org.apache.hadoop.hive.metastore.api.NoSuchObjectException;
+import org.apache.hadoop.hive.metastore.api.Partition;
+import org.apache.hadoop.hive.metastore.api.PartitionSpec;
+import org.apache.hadoop.hive.metastore.api.PartitionValuesRequest;
+import org.apache.hadoop.hive.metastore.api.PartitionValuesResponse;
+import org.apache.hadoop.hive.metastore.api.PartitionValuesRow;
+import org.apache.hadoop.hive.metastore.api.Table;
+import org.apache.hadoop.hive.metastore.client.builder.DatabaseBuilder;
+import org.apache.hadoop.hive.metastore.client.builder.PartitionBuilder;
+import org.apache.hadoop.hive.metastore.client.builder.TableBuilder;
+import org.apache.hadoop.hive.metastore.minihms.AbstractMetaStoreService;
+import org.apache.hadoop.hive.metastore.partition.spec.PartitionSpecProxy;
+import org.apache.thrift.TException;
+import org.apache.thrift.protocol.TProtocolException;
+import org.apache.thrift.transport.TTransportException;
+
+import com.google.common.collect.Lists;
+
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+import static java.util.stream.Collectors.joining;
+import static junit.framework.TestCase.assertNotNull;
+import static junit.framework.TestCase.assertNull;
+import static junit.framework.TestCase.assertTrue;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.fail;
+
+/**
+ * API tests for HMS client's listPartitions methods.
+ */
+@RunWith(Parameterized.class)
+public class TestListPartitions {
+
+ // Needed until there is no junit release with @BeforeParam, @AfterParam (junit 4.13)
+ // https://github.com/junit-team/junit4/commit/1bf8438b65858565dbb64736bfe13aae9cfc1b5a
+ // Then we should remove our own copy
+ private static Set<AbstractMetaStoreService> metaStoreServices = null;
+ private AbstractMetaStoreService metaStore;
+ private IMetaStoreClient client;
+
+ private static final String DB_NAME = "testpartdb";
+ private static final String TABLE_NAME = "testparttable";
+
+
+ @Parameterized.Parameters(name = "{0}")
+ public static List<Object[]> getMetaStoreToTest() throws Exception {
+ List<Object[]> result = MetaStoreFactoryForTests.getMetaStores();
+ metaStoreServices = result.stream()
+ .map(test -> (AbstractMetaStoreService)test[1])
+ .collect(Collectors.toSet());
+ return result;
+ }
+
+ public TestListPartitions(String name, AbstractMetaStoreService metaStore) throws Exception {
+ this.metaStore = metaStore;
+ this.metaStore.start();
+ }
+
+ // Needed until there is no junit release with @BeforeParam, @AfterParam (junit 4.13)
+ // https://github.com/junit-team/junit4/commit/1bf8438b65858565dbb64736bfe13aae9cfc1b5a
+ // Then we should move this to @AfterParam
+ @AfterClass
+ public static void stopMetaStores() throws Exception {
+ for(AbstractMetaStoreService metaStoreService : metaStoreServices) {
+ metaStoreService.stop();
+ }
+ }
+
+ @Before
+ public void setUp() throws Exception {
+ // Get new client
+ client = metaStore.getClient();
+
+ // Clean up the database
+ client.dropDatabase(DB_NAME, true, true, true);
+ createDB(DB_NAME);
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ try {
+ if (client != null) {
+ client.close();
+ }
+ } finally {
+ client = null;
+ }
+ }
+
+ private void createDB(String dbName) throws TException {
+ Database db = new DatabaseBuilder().
+ setName(dbName).
+ build();
+ client.createDatabase(db);
+ }
+
+ private static Table createTestTable(IMetaStoreClient client, String dbName, String tableName,
+ List<String> partCols) throws Exception {
+
+ return createTestTable(client, dbName, tableName, partCols, false);
+ }
+
+
+ private static Table createTestTable(IMetaStoreClient client, String dbName, String tableName,
+ List<String> partCols, boolean setPartitionLevelPrivilages)
+ throws Exception {
+ TableBuilder builder = new TableBuilder()
+ .setDbName(dbName)
+ .setTableName(tableName)
+ .addCol("id", "int")
+ .addCol("name", "string");
+
+ partCols.forEach(col -> builder.addPartCol(col, "string"));
+ Table table = builder.build();
+
+ if (setPartitionLevelPrivilages) {
+ table.putToParameters("PARTITION_LEVEL_PRIVILEGE", "true");
+ }
+
+ client.createTable(table);
+ return table;
+ }
+
+ private static void addPartition(IMetaStoreClient client, Table table, List<String> values)
+ throws TException {
+ PartitionBuilder partitionBuilder = new PartitionBuilder().fromTable(table);
+ values.forEach(val -> partitionBuilder.addValue(val));
+ client.add_partition(partitionBuilder.build());
+ }
+
+ private static void createTable3PartCols1PartGeneric(IMetaStoreClient client, boolean authOn)
+ throws Exception {
+ Table t = createTestTable(client, DB_NAME, TABLE_NAME, Lists.newArrayList("yyyy", "mm",
+ "dd"), authOn);
+ addPartition(client, t, Lists.newArrayList("1997", "05", "16"));
+ }
+
+ private static void createTable3PartCols1Part(IMetaStoreClient client) throws Exception {
+ createTable3PartCols1PartGeneric(client, false);
+ }
+
+ private static List<List<String>> createTable4PartColsPartsGeneric(IMetaStoreClient client,
+ boolean authOn) throws
+ Exception {
+ Table t = createTestTable(client, DB_NAME, TABLE_NAME, Lists.newArrayList("yyyy", "mm", "dd"),
+ authOn);
+ List<List<String>> testValues = Lists.newArrayList(
+ Lists.newArrayList("1999", "01", "02"),
+ Lists.newArrayList("2009", "02", "10"),
+ Lists.newArrayList("2017", "10", "26"),
+ Lists.newArrayList("2017", "11", "27"));
+
+ for(List<String> vals : testValues) {
+ addPartition(client, t, vals);
+ }
+
+ return testValues;
+ }
+
+ private static List<List<String>> createTable4PartColsParts(IMetaStoreClient client) throws
+ Exception {
+ return createTable4PartColsPartsGeneric(client, false);
+ }
+
+ private static List<List<String>> createTable4PartColsPartsAuthOn(IMetaStoreClient client) throws
+ Exception {
+ return createTable4PartColsPartsGeneric(client, true);
+ }
+
+ private static void assertAuthInfoReturned(String user, String group, Partition partition) {
+ assertNotNull(partition.getPrivileges());
+ assertEquals(Lists.newArrayList(),
+ partition.getPrivileges().getUserPrivileges().get(user));
+ assertEquals(Lists.newArrayList(),
+ partition.getPrivileges().getGroupPrivileges().get(group));
+ assertEquals(Lists.newArrayList(),
+ partition.getPrivileges().getRolePrivileges().get("public"));
+ }
+
+ private static void assertPartitionsHaveCorrectValues(List<Partition> partitions,
+ List<List<String>> testValues) throws Exception {
+ assertEquals(testValues.size(), partitions.size());
+ for (int i = 0; i < partitions.size(); ++i) {
+ assertEquals(testValues.get(i), partitions.get(i).getValues());
+ }
+ }
+
+ private static void assertCorrectPartitionNames(List<String> names,
+ List<List<String>> testValues,
+ List<String>partCols) throws Exception {
+ assertEquals(testValues.size(), names.size());
+ for (int i = 0; i < names.size(); ++i) {
+ List<String> expectedKVPairs = new ArrayList<>();
+ for (int j = 0; j < partCols.size(); ++j) {
+ expectedKVPairs.add(partCols.get(j) + "=" + testValues.get(i).get(j));
+ }
+ assertEquals(expectedKVPairs.stream().collect(joining("/")), names.get(i));
+ }
+ }
+
+ private static void assertPartitionsSpecProxy(PartitionSpecProxy partSpecProxy,
+ List<List<String>> testValues) throws Exception {
+ assertEquals(testValues.size(), partSpecProxy.size());
+ List<PartitionSpec> partitionSpecs = partSpecProxy.toPartitionSpec();
+ List<Partition> partitions = partitionSpecs.get(0).getPartitionList().getPartitions();
+ assertEquals(testValues.size(), partitions.size());
+
+ for (int i = 0; i < partitions.size(); ++i) {
+ assertEquals(testValues.get(i), partitions.get(i).getValues());
+ }
+ }
+
+ private static void assertCorrectPartitionValuesResponse(List<List<String>> testValues,
+ PartitionValuesResponse resp) throws Exception {
+ assertEquals(testValues.size(), resp.getPartitionValuesSize());
+ List<PartitionValuesRow> rowList = resp.getPartitionValues();
+ for (int i = 0; i < rowList.size(); ++i) {
+ PartitionValuesRow pvr = rowList.get(i);
+ List<String> values = pvr.getRow();
+ for (int j = 0; j < values.size(); ++j) {
+ assertEquals(testValues.get(i).get(j), values.get(j));
+ }
+ }
+ }
+
+
+
+ /**
+ * Testing listPartitions(String,String,short) ->
+ * get_partitions(String,String,short).
+ * @throws Exception
+ */
+ @Test
+ public void testListPartitionsAll() throws Exception {
+ List<List<String>> testValues = createTable4PartColsParts(client);
+ List<Partition> partitions = client.listPartitions(DB_NAME, TABLE_NAME, (short)-1);
+ assertPartitionsHaveCorrectValues(partitions, testValues);
+
+ partitions = client.listPartitions(DB_NAME, TABLE_NAME, (short)1);
+ assertPartitionsHaveCorrectValues(partitions, testValues.subList(0, 1));
+
+ partitions = client.listPartitions(DB_NAME, TABLE_NAME, (short)0);
+ assertTrue(partitions.isEmpty());
+
+ }
+
+ @Test(expected = MetaException.class)
+ public void testListPartitionsAllHighMaxParts() throws Exception {
+ createTable3PartCols1Part(client);
+ List<Partition> partitions = client.listPartitions(DB_NAME, TABLE_NAME, (short)101);
+ assertTrue(partitions.isEmpty());
+ }
+
+ @Test
+ public void testListPartitionsAllNoParts() throws Exception {
+ Table t = createTestTable(client, DB_NAME, TABLE_NAME, Lists.newArrayList("yyyy", "mm", "dd"));
+ List<Partition> partitions = client.listPartitions(DB_NAME, TABLE_NAME, (short)-1);
+ assertTrue(partitions.isEmpty());
+ }
+
+ @Test(expected = NoSuchObjectException.class)
+ public void testListPartitionsAllNoTable() throws Exception {
+ List<Partition> partitions = client.listPartitions(DB_NAME, TABLE_NAME, (short)-1);
+ }
+
+ @Test(expected = NoSuchObjectException.class)
+ public void testListPartitionsAllNoDb() throws Exception {
+ client.dropDatabase(DB_NAME);
+ client.listPartitions(DB_NAME, TABLE_NAME, (short)-1);
+ }
+
+ @Test(expected = NoSuchObjectException.class)
+ public void testListPartitionsAllNoDbName() throws Exception {
+ createTable3PartCols1Part(client);
+ client.listPartitions("", TABLE_NAME, (short)-1);
+ }
+
+ @Test(expected = NoSuchObjectException.class)
+ public void testListPartitionsAllNoTblName() throws Exception {
+ createTable3PartCols1Part(client);
+ client.listPartitions(DB_NAME, "", (short)-1);
+ }
+
+ @Test
+ public void testListPartitionsAllNullTblName() throws Exception {
+ try {
+ createTable3PartCols1Part(client);
+ List<Partition> partitions = client.listPartitions(DB_NAME, null, (short)-1);
+ fail("Should have thrown exception");
+ } catch (NullPointerException | TTransportException e) {
+ //TODO: should not throw different exceptions for different HMS deployment types
+ }
+ }
+
+ @Test
+ public void testListPartitionsAllNullDbName() throws Exception {
+ try {
+ createTable3PartCols1Part(client);
+ client.listPartitions(null, TABLE_NAME, (short)-1);
+ fail("Should have thrown exception");
+ } catch (NullPointerException | TTransportException e) {
+ //TODO: should not throw different exceptions for different HMS deployment types
+ }
+ }
+
+
+
+ /**
+ * Testing listPartitions(String,String,List(String),short) ->
+ * get_partitions(String,String,List(String),short).
+ * @throws Exception
+ */
+ @Test
+ public void testListPartitionsByValues() throws Exception {
+ List<List<String>> testValues = createTable4PartColsParts(client);
+
+ List<Partition> partitions = client.listPartitions(DB_NAME, TABLE_NAME,
+ Lists.newArrayList("2017"), (short)-1);
+ assertEquals(2, partitions.size());
+ assertEquals(testValues.get(2), partitions.get(0).getValues());
+ assertEquals(testValues.get(3), partitions.get(1).getValues());
+
+ partitions = client.listPartitions(DB_NAME, TABLE_NAME,
+ Lists.newArrayList("2017", "11"), (short)-1);
+ assertEquals(1, partitions.size());
+ assertEquals(testValues.get(3), partitions.get(0).getValues());
+
+ partitions = client.listPartitions(DB_NAME, TABLE_NAME,
+ Lists.newArrayList("20177", "11"), (short)-1);
+ assertEquals(0, partitions.size());
+ }
+
+ @Test(expected = MetaException.class)
+ public void testListPartitionsByValuesNoVals() throws Exception {
+ createTable3PartCols1Part(client);
+ client.listPartitions(DB_NAME, TABLE_NAME, Lists.newArrayList(), (short)-1);
+ }
+
+ @Test(expected = MetaException.class)
+ public void testListPartitionsByValuesTooManyVals() throws Exception {
+ createTable3PartCols1Part(client);
+ client.listPartitions(DB_NAME, TABLE_NAME, Lists.newArrayList("0", "1", "2", "3"), (short)-1);
+ }
+
+ @Test(expected = NoSuchObjectException.class)
+ public void testListPartitionsByValuesNoDbName() throws Exception {
+ createTable3PartCols1Part(client);
+ client.listPartitions("", TABLE_NAME, Lists.newArrayList("1999"), (short)-1);
+ }
+
+ @Test(expected = NoSuchObjectException.class)
+ public void testListPartitionsByValuesNoTblName() throws Exception {
+ createTable3PartCols1Part(client);
+ client.listPartitions(DB_NAME, "", Lists.newArrayList("1999"), (short)-1);
+ }
+
+ @Test(expected = NoSuchObjectException.class)
+ public void testListPartitionsByValuesNoTable() throws Exception {
+ client.listPartitions(DB_NAME, TABLE_NAME, Lists.newArrayList("1999"), (short)-1);
+ }
+
+ @Test(expected = NoSuchObjectException.class)
+ public void testListPartitionsByValuesNoDb() throws Exception {
+ client.dropDatabase(DB_NAME);
+ client.listPartitions(DB_NAME, TABLE_NAME, Lists.newArrayList("1999"), (short)-1);
+ }
+
+ @Test(expected = MetaException.class)
+ public void testListPartitionsByValuesNullDbName() throws Exception {
+ createTable3PartCols1Part(client);
+ client.listPartitions(null, TABLE_NAME, Lists.newArrayList("1999"), (short)-1);
+ }
+
+ @Test(expected = MetaException.class)
+ public void testListPartitionsByValuesNullTblName() throws Exception {
+ createTable3PartCols1Part(client);
+ client.listPartitions(DB_NAME, null, Lists.newArrayList("1999"), (short)-1);
+ }
+
+ @Test(expected = MetaException.class)
+ public void testListPartitionsByValuesNullValues() throws Exception {
+ createTable3PartCols1Part(client);
+ client.listPartitions(DB_NAME, TABLE_NAME, null, (short)-1);
+ }
+
+
+
+ /**
+ * Testing listPartitionSpecs(String,String,int) ->
+ * get_partitions_pspec(String,String,int).
+ * @throws Exception
+ */
+ @Test
+ public void testListPartitionSpecs() throws Exception {
+ List<List<String>> testValues = createTable4PartColsParts(client);
+
+ PartitionSpecProxy partSpecProxy = client.listPartitionSpecs(DB_NAME, TABLE_NAME, -1);
+ assertPartitionsSpecProxy(partSpecProxy, testValues);
+
+ partSpecProxy = client.listPartitionSpecs(DB_NAME, TABLE_NAME, 2);
+ assertPartitionsSpecProxy(partSpecProxy, testValues.subList(0, 2));
+
+ partSpecProxy = client.listPartitionSpecs(DB_NAME, TABLE_NAME, 0);
+ assertPartitionsSpecProxy(partSpecProxy, testValues.subList(0, 0));
+ }
+
+ @Test(expected = NoSuchObjectException.class)
+ public void testListPartitionSpecsNoTable() throws Exception {
+ client.listPartitionSpecs(DB_NAME, TABLE_NAME, -1);
+ }
+
+ @Test(expected = NoSuchObjectException.class)
+ public void testListPartitionSpecsNoDb() throws Exception {
+ client.dropDatabase(DB_NAME);
+ client.listPartitionSpecs(DB_NAME, TABLE_NAME, -1);
+ }
+
+ @Test(expected = MetaException.class)
+ public void testListPartitionSpecsHighMaxParts() throws Exception {
+ createTable4PartColsParts(client);
+ client.listPartitionSpecs(DB_NAME, TABLE_NAME, 101);
+ }
+
+ @Test(expected = NoSuchObjectException.class)
+ public void testListPartitionSpecsNoDbName() throws Exception {
+ createTable4PartColsParts(client);
+ client.listPartitionSpecs("", TABLE_NAME, -1);
+ }
+
+ @Test(expected = NoSuchObjectException.class)
+ public void testListPartitionSpecsNoTblName() throws Exception {
+ createTable4PartColsParts(client);
+ client.listPartitionSpecs(DB_NAME, "", -1);
+ }
+
+ @Test
+ public void testListPartitionSpecsNullDbName() throws Exception {
+ try {
+ createTable4PartColsParts(client);
+ client.listPartitionSpecs(null, TABLE_NAME, -1);
+ fail("Should have thrown exception");
+ } catch (NullPointerException | TTransportException e) {
+ //TODO: should not throw different exceptions for different HMS deployment types
+ }
+ }
+
+ @Test
+ public void testListPartitionSpecsNullTblName() throws Exception {
+ try {
+ createTable4PartColsParts(client);
+ client.listPartitionSpecs(DB_NAME, null, -1);
+ fail("Should have thrown exception");
+ } catch (NullPointerException | TTransportException e) {
+ //TODO: should not throw different exceptions for different HMS deployment types
+ }
+ }
+
+
+
+ /**
+ * Testing listPartitionsWithAuthInfo(String,String,short,String,List(String)) ->
+ * get_partitions_with_auth(String,String,short,String,List(String)).
+ * @throws Exception
+ */
+ @Test
+ public void testListPartitionsWithAuth() throws Exception {
+ List<List<String>> partValues = createTable4PartColsPartsAuthOn(client);
+ String user = "user0";
+ List<String> groups = Lists.newArrayList("group0");
+ List<Partition> partitions = client.listPartitionsWithAuthInfo(DB_NAME, TABLE_NAME, (short)-1,
+ user, groups);
+
+ assertEquals(4, partitions.size());
+ assertPartitionsHaveCorrectValues(partitions, partValues);
+ partitions.forEach(partition -> assertAuthInfoReturned(user, groups.get(0), partition));
+
+ partitions = client.listPartitionsWithAuthInfo(DB_NAME, TABLE_NAME, (short)2, user, groups);
+ assertEquals(2, partitions.size());
+ assertPartitionsHaveCorrectValues(partitions, partValues.subList(0, 2));
+ partitions.forEach(partition -> assertAuthInfoReturned(user, groups.get(0), partition));
+ }
+
+ @Test(expected = MetaException.class)
+ public void testListPartitionsWithAuthHighMaxParts() throws Exception {
+ createTable4PartColsParts(client);
+ client.listPartitionsWithAuthInfo(DB_NAME, TABLE_NAME, (short)101, "", Lists.newArrayList());
+ }
+
+ @Test
+ public void testListPartitionsWithAuthNoPrivilegesSet() throws Exception {
+ List<List<String>> partValues = createTable4PartColsParts(client);
+ List<Partition> partitions = client.listPartitionsWithAuthInfo(DB_NAME, TABLE_NAME, (short)-1,
+ "", Lists.newArrayList());
+
+ assertEquals(4, partitions.size());
+ assertPartitionsHaveCorrectValues(partitions, partValues);
+ partitions.forEach(partition -> assertNull(partition.getPrivileges()));
+ }
+
+ @Test(expected = NoSuchObjectException.class)
+ public void testListPartitionsWithAuthNoDbName() throws Exception {
+ createTable4PartColsParts(client);
+ client.listPartitionsWithAuthInfo("", TABLE_NAME, (short)-1, "", Lists.newArrayList());
+ }
+
+ @Test(expected = NoSuchObjectException.class)
+ public void testListPartitionsWithAuthNoTblName() throws Exception {
+ createTable4PartColsParts(client);
+ client.listPartitionsWithAuthInfo(DB_NAME, "", (short)-1, "", Lists.newArrayList());
+ }
+
+ @Test(expected = NoSuchObjectException.class)
+ public void testListPartitionsWithAuthNoTable() throws Exception {
+ client.listPartitionsWithAuthInfo(DB_NAME, TABLE_NAME, (short)-1, "", Lists.newArrayList());
+ }
+
+ @Test(expected = NoSuchObjectException.class)
+ public void testListPartitionsWithAuthNoDb() throws Exception {
+ client.dropDatabase(DB_NAME);
+ client.listPartitionsWithAuthInfo(DB_NAME, TABLE_NAME, (short)-1, "", Lists.newArrayList());
+ }
+
+
+ @Test(expected = MetaException.class)
+ public void testListPartitionsWithAuthNullDbName() throws Exception {
+ createTable4PartColsParts(client);
+ client.listPartitionsWithAuthInfo(null, TABLE_NAME, (short)-1, "", Lists.newArrayList());
+ }
+
+ @Test
+ public void testListPartitionsWithAuthNullTblName() throws Exception {
+ try {
+ createTable4PartColsParts(client);
+ client.listPartitionsWithAuthInfo(DB_NAME, null, (short)-1, "", Lists.newArrayList());
+ fail("Should have thrown exception");
+ } catch (AssertionError| TTransportException e) {
+ //TODO: should not throw different exceptions for different HMS deployment types
+ }
+ }
+
+ @Test
+ public void testListPartitionsWithAuthNullUser() throws Exception {
+ createTable4PartColsPartsAuthOn(client);
+ client.listPartitionsWithAuthInfo(DB_NAME, TABLE_NAME, (short)-1, null, Lists.newArrayList());
+ }
+
+ @Test
+ public void testListPartitionsWithAuthNullGroup() throws Exception {
+ createTable4PartColsPartsAuthOn(client);
+ client.listPartitionsWithAuthInfo(DB_NAME, TABLE_NAME, (short)-1, "user0", null);
+ }
+
+
+
+ /**
+ * Testing listPartitionsWithAuthInfo(String,String,List(String),short,String,List(String)) ->
+ * get_partitions_ps_with_auth(String,String,List(String),short,String,List(String)).
+ * @throws Exception
+ */
+ @Test
+ public void testListPartitionsWithAuthByValues() throws Exception {
+ List<List<String>> partValues = createTable4PartColsPartsAuthOn(client);
+ String user = "user0";
+ List<String> groups = Lists.newArrayList("group0");
+
+ List<Partition> partitions = client.listPartitionsWithAuthInfo(DB_NAME, TABLE_NAME, Lists
+ .newArrayList("2017", "11", "27"), (short)-1, user, groups);
+ assertEquals(1, partitions.size());
+ assertPartitionsHaveCorrectValues(partitions, partValues.subList(3, 4));
+ partitions.forEach(partition -> assertAuthInfoReturned(user, groups.get(0), partition));
+
+ partitions = client.listPartitionsWithAuthInfo(DB_NAME, TABLE_NAME, Lists
+ .newArrayList("2017"), (short)-1, user, groups);
+ assertEquals(2, partitions.size());
+ assertPartitionsHaveCorrectValues(partitions, partValues.subList(2, 4));
+ partitions.forEach(partition -> assertAuthInfoReturned(user, groups.get(0), partition));
+
+ partitions = client.listPartitionsWithAuthInfo(DB_NAME, TABLE_NAME, Lists
+ .newArrayList("2017"), (short)1, user, groups);
+ assertEquals(1, partitions.size());
+ assertPartitionsHaveCorrectValues(partitions, partValues.subList(2, 3));
+ partitions.forEach(partition -> assertAuthInfoReturned(user, groups.get(0), partition));
+
+ partitions = client.listPartitionsWithAuthInfo(DB_NAME, TABLE_NAME, Lists
+ .newArrayList("2013"), (short)-1, user, groups);
+ assertTrue(partitions.isEmpty());
+ }
+
+ @Test(expected = MetaException.class)
+ public void testListPartitionsWithAuthByValuesNoVals() throws Exception {
+ createTable4PartColsPartsAuthOn(client);
+ client.listPartitionsWithAuthInfo(DB_NAME, TABLE_NAME, Lists
+ .newArrayList(), (short)-1, "", Lists.newArrayList());
+ }
+
+
+ @Test(expected = MetaException.class)
+ public void testListPartitionsWithAuthByValuesTooManyVals() throws Exception {
+ createTable4PartColsPartsAuthOn(client);
+ client.listPartitionsWithAuthInfo(DB_NAME, TABLE_NAME, Lists
+ .newArrayList("0", "1", "2", "3"), (short)-1, "", Lists.newArrayList());
+ }
+
+ @Test
+ public void testListPartitionsWithAuthByValuesHighMaxParts() throws Exception {
+ List<List<String>> partValues = createTable4PartColsParts(client);
+ //This doesn't throw MetaException when setting to high max part count
+ List<Partition> partitions = client.listPartitionsWithAuthInfo(DB_NAME, TABLE_NAME, Lists
+ .newArrayList("2017"), (short)101, "", Lists.newArrayList());
+ assertPartitionsHaveCorrectValues(partitions, partValues.subList(2, 4));
+ }
+
+ @Test(expected = MetaException.class)
+ public void testListPartitionsWithAuthByValuesTooManyValsHighMaxParts() throws Exception {
+ createTable4PartColsParts(client);
+ client.listPartitionsWithAuthInfo(DB_NAME, TABLE_NAME, Lists
+ .newArrayList("0", "1", "2", "3"), (short)101, "", Lists.newArrayList());
+ }
+
+ @Test
+ public void testListPartitionsWithAuthByValuesNoPrivilegesSet() throws Exception {
+ List<List<String>> partValues = createTable4PartColsPartsAuthOn(client);
+ String user = "user0";
+ List<String> groups = Lists.newArrayList("group0");
+ List<Partition> partitions = client.listPartitionsWithAuthInfo(DB_NAME, TABLE_NAME, Lists
+ .newArrayList("2017", "11", "27"), (short)-1, user, groups);
+
+ assertEquals(1, partitions.size());
+ assertPartitionsHaveCorrectValues(partitions, partValues.subList(3, 4));
+ partitions.forEach(partition -> assertAuthInfoReturned(user, groups.get(0), partition));
+ }
+
+ @Test(expected = NoSuchObjectException.class)
+ public void testListPartitionsWithAuthByValuesNoDbName() throws Exception {
+ createTable4PartColsParts(client);
+ client.listPartitionsWithAuthInfo("", TABLE_NAME, Lists
+ .newArrayList("2017", "11", "27"), (short)-1, "", Lists.newArrayList());
+ }
+
+ @Test(expected = NoSuchObjectException.class)
+ public void testListPartitionsWithAuthByValuesNoTblName() throws Exception {
+ createTable4PartColsParts(client);
+ client.listPartitionsWithAuthInfo(DB_NAME, "", Lists
+ .newArrayList("2017", "11", "27"), (short)-1, "", Lists.newArrayList());
+ }
+
+ @Test(expected = NoSuchObjectException.class)
+ public void testListPartitionsWithAuthByValuesNoTable() throws Exception {
+ client.listPartitionsWithAuthInfo(DB_NAME, TABLE_NAME, Lists
+ .newArrayList("2017", "11", "27"), (short)-1, "", Lists.newArrayList());
+ }
+
+ @Test(expected = NoSuchObjectException.class)
+ public void testListPartitionsWithAuthByValuesNoDb() throws Exception {
+ client.dropDatabase(DB_NAME);
+ client.listPartitionsWithAuthInfo(DB_NAME, TABLE_NAME, Lists
+ .newArrayList("2017", "11", "27"), (short)-1, "", Lists.newArrayList());
+ }
+
+ @Test
+ public void testListPartitionsWithAuthByValuesNullDbName() throws Exception {
+ try {
+ createTable4PartColsParts(client);
+ client.listPartitionsWithAuthInfo(null, TABLE_NAME, Lists
+ .newArrayList("2017", "11", "27"), (short)-1, "", Lists.newArrayList());
+ fail("Should have thrown exception");
+ } catch (NullPointerException | TTransportException e) {
+ //TODO: should not throw different exceptions for different HMS deployment types
+ }
+ }
+
+ @Test
+ public void testListPartitionsWithAuthByValuesNullTblName() throws Exception {
+ try {
+ createTable4PartColsParts(client);
+ client.listPartitionsWithAuthInfo(DB_NAME, null, Lists
+ .newArrayList("2017", "11", "27"), (short)-1, "", Lists.newArrayList());
+ fail("Should have thrown exception");
+ } catch (NullPointerException | TTransportException e) {
+ //TODO: should not throw different exceptions for different HMS deployment types
+ }
+ }
+
+ @Test(expected = MetaException.class)
+ public void testListPartitionsWithAuthByValuesNullValues() throws Exception {
+ createTable4PartColsParts(client);
+ client.listPartitionsWithAuthInfo(DB_NAME, TABLE_NAME, null,
+ (short)-1, "", Lists.newArrayList());
+ }
+
+ @Test
+ public void testListPartitionsWithAuthByValuesNullUser() throws Exception {
+ List<List<String>> partValues = createTable4PartColsPartsAuthOn(client);
+ List<Partition> partitions = client.listPartitionsWithAuthInfo(DB_NAME, TABLE_NAME, Lists
+ .newArrayList("2017", "11", "27"), (short)-1, null, Lists.newArrayList());
+ assertPartitionsHaveCorrectValues(partitions, partValues.subList(3, 4));
+ }
+
+ @Test
+ public void testListPartitionsWithAuthByValuesNullGroup() throws Exception {
+ List<List<String>> partValues = createTable4PartColsPartsAuthOn(client);
+ List<Partition> partitions = client.listPartitionsWithAuthInfo(DB_NAME, TABLE_NAME, Lists
+ .newArrayList("2017", "11", "27"), (short)-1, "", null);
+ assertPartitionsHaveCorrectValues(partitions, partValues.subList(3, 4));
+ }
+
+
+
+ /**
+ * Testing listPartitionsByFilter(String,String,String,short) ->
+ * get_partitions_by_filter(String,String,String,short).
+ * @throws Exception
+ */
+ @Test
+ public void testListPartitionsByFilter() throws Exception {
+ List<List<String>> partValues = createTable4PartColsParts(client);
+ List<Partition> partitions = client.listPartitionsByFilter(DB_NAME, TABLE_NAME,
+ "yyyy=\"2017\" OR " + "mm=\"02\"", (short)-1);
+ assertEquals(3, partitions.size());
+ assertPartitionsHaveCorrectValues(partitions, partValues.subList(1, 4));
+
+ partitions = client.listPartitionsByFilter(DB_NAME, TABLE_NAME,
+ "yyyy=\"2017\" OR " + "mm=\"02\"", (short)2);
+ assertEquals(2, partitions.size());
+ assertPartitionsHaveCorrectValues(partitions, partValues.subList(1, 3));
+
+ partitions = client.listPartitionsByFilter(DB_NAME, TABLE_NAME,
+ "yyyy=\"2017\" OR " + "mm=\"02\"", (short)0);
+ assertTrue(partitions.isEmpty());
+
+ partitions = client.listPartitionsByFilter(DB_NAME, TABLE_NAME,
+ "yYyY=\"2017\"", (short)-1);
+ assertPartitionsHaveCorrectValues(partitions, partValues.subList(2, 4));
+
+ partitions = client.listPartitionsByFilter(DB_NAME, TABLE_NAME,
+ "yyyy=\"2017\" AND mm=\"99\"", (short)-1);
+ assertTrue(partitions.isEmpty());
+ }
+
+ @Test(expected = MetaException.class)
+ public void testListPartitionsByFilterInvalidFilter() throws Exception {
+ createTable4PartColsParts(client);
+ client.listPartitionsByFilter(DB_NAME, TABLE_NAME, "yyy=\"2017\"", (short)101);
+ }
+
+ @Test(expected = MetaException.class)
+ public void testListPartitionsByFilterHighMaxParts() throws Exception {
+ createTable4PartColsParts(client);
+ client.listPartitionsByFilter(DB_NAME, TABLE_NAME, "yyyy=\"2017\"", (short)101);
+ }
+
+ @Test(expected = NoSuchObjectException.class)
+ public void testListPartitionsByFilterNoTblName() throws Exception {
+ createTable4PartColsParts(client);
+ client.listPartitionsByFilter(DB_NAME, "", "yyyy=\"2017\"", (short)-1);
+ }
+
+ @Test(expected = NoSuchObjectException.class)
+ public void testListPartitionsByFilterNoDbName() throws Exception {
+ createTable4PartColsParts(client);
+ client.listPartitionsByFilter("", TABLE_NAME, "yyyy=\"2017\"", (short)-1);
+ }
+
+ @Test(expected = NoSuchObjectException.class)
+ public void testListPartitionsByFilterNoTable() throws Exception {
+ client.listPartitionsByFilter(DB_NAME, TABLE_NAME, "yyyy=\"2017\"", (short)-1);
+ }
+
+ @Test(expected = NoSuchObjectException.class)
+ public void testListPartitionsByFilterNoDb() throws Exception {
+ client.dropDatabase(DB_NAME);
+ client.listPartitionsByFilter(DB_NAME, TABLE_NAME, "yyyy=\"2017\"", (short)-1);
+ }
+
+ @Test
+ public void testListPartitionsByFilterNullTblName() throws Exception {
+ try {
+ createTable4PartColsParts(client);
+ client.listPartitionsByFilter(DB_NAME, null, "yyyy=\"2017\"", (short)-1);
+ fail("Should have thrown exception");
+ } catch (NullPointerException | TTransportException e) {
+ //TODO: should not throw different exceptions for different HMS deployment types
+ }
+ }
+
+ @Test
+ public void testListPartitionsByFilterNullDbName() throws Exception {
+ try {
+ createTable4PartColsParts(client);
+ client.listPartitionsByFilter(null, TABLE_NAME, "yyyy=\"2017\"", (short)-1);
+ fail("Should have thrown exception");
+ } catch (NullPointerException | TTransportException e) {
+ //TODO: should not throw different exceptions for different HMS deployment types
+ }
+ }
+
+ @Test
+ public void testListPartitionsByFilterNullFilter() throws Exception {
+ createTable4PartColsParts(client);
+ List<Partition> partitions = client.listPartitionsByFilter(DB_NAME, TABLE_NAME, null,
+ (short)-1);
+ assertEquals(4, partitions.size());
+ }
+
+ @Test
+ public void testListPartitionsByFilterEmptyFilter() throws Exception {
+ createTable4PartColsParts(client);
+ List<Partition> partitions = client.listPartitionsByFilter(DB_NAME, TABLE_NAME, "", (short)-1);
+ assertEquals(4, partitions.size());
+ }
+
+
+
+ /**
+ * Testing listPartitionSpecsByFilter(String,String,String,int) ->
+ * get_part_specs_by_filter(String,String,String,int).
+ * @throws Exception
+ */
+ @Test
+ public void testListPartitionsSpecsByFilter() throws Exception {
+ List<List<String>> testValues = createTable4PartColsParts(client);
+ PartitionSpecProxy partSpecProxy = client.listPartitionSpecsByFilter(DB_NAME, TABLE_NAME,
+ "yyyy=\"2017\" OR " + "mm=\"02\"", -1);
+
+ assertPartitionsSpecProxy(partSpecProxy, testValues.subList(1, 4));
+
+ partSpecProxy = client.listPartitionSpecsByFilter(DB_NAME, TABLE_NAME,
+ "yyyy=\"2017\" OR " + "mm=\"02\"", 2);
+ assertPartitionsSpecProxy(partSpecProxy, testValues.subList(1, 3));
+
+ partSpecProxy = client.listPartitionSpecsByFilter(DB_NAME, TABLE_NAME,
+ "yyyy=\"2017\" OR " + "mm=\"02\"", 0);
+ assertPartitionsSpecProxy(partSpecProxy, Lists.newArrayList());
+
+ partSpecProxy = client.listPartitionSpecsByFilter(DB_NAME, TABLE_NAME,
+ "yyyy=\"20177\"", -1);
+ assertPartitionsSpecProxy(partSpecProxy, Lists.newArrayList());
+
+ partSpecProxy = client.listPartitionSpecsByFilter(DB_NAME, TABLE_NAME,
+ "yYyY=\"2017\"", -1);
+ assertPartitionsSpecProxy(partSpecProxy, testValues.subList(2, 4));
+
+ partSpecProxy = client.listPartitionSpecsByFilter(DB_NAME, TABLE_NAME,
+ "yyyy=\"2017\" AND mm=\"99\"", -1);
+ assertPartitionsSpecProxy(partSpecProxy, Lists.newArrayList());
+ }
+
+ @Test(expected = MetaException.class)
+ public void testListPartitionSpecsByFilterInvalidFilter() throws Exception {
+ createTable4PartColsParts(client);
+ client.listPartitionSpecsByFilter(DB_NAME, TABLE_NAME, "yyy=\"2017\"", 101);
+ }
+
+ @Test(expected = MetaException.class)
+ public void testListPartitionSpecsByFilterHighMaxParts() throws Exception {
+ createTable4PartColsParts(client);
+ client.listPartitionSpecsByFilter(DB_NAME, TABLE_NAME, "yyyy=\"2017\"", 101);
+ }
+
+ @Test(expected = NoSuchObjectException.class)
+ public void testListPartitionSpecsByFilterNoTblName() throws Exception {
+ createTable4PartColsParts(client);
+ client.listPartitionSpecsByFilter(DB_NAME, "", "yyyy=\"2017\"", -1);
+ }
+
+ @Test(expected = NoSuchObjectException.class)
+ public void testListPartitionSpecsByFilterNoDbName() throws Exception {
+ createTable4PartColsParts(client);
+ client.listPartitionSpecsByFilter("", TABLE_NAME, "yyyy=\"2017\"", -1);
+ }
+
+ @Test(expected = NoSuchObjectException.class)
+ public void testListPartitionSpecsByFilterNoTable() throws Exception {
+ client.listPartitionSpecsByFilter(DB_NAME, TABLE_NAME, "yyyy=\"2017\"", -1);
+ }
+
+ @Test(expected = NoSuchObjectException.class)
+ public void testListPartitionSpecsByFilterNoDb() throws Exception {
+ client.dropDatabase(DB_NAME);
+ client.listPartitionSpecsByFilter(DB_NAME, TABLE_NAME, "yyyy=\"2017\"", -1);
+ }
+
+ @Test(expected = MetaException.class)
+ public void testListPartitionSpecsByFilterNullTblName() throws Exception {
+ createTable4PartColsParts(client);
+ client.listPartitionSpecsByFilter(DB_NAME, null, "yyyy=\"2017\"", -1);
+ }
+
+ @Test(expected = MetaException.class)
+ public void testListPartitionSpecsByFilterNullDbName() throws Exception {
+ createTable4PartColsParts(client);
+ client.listPartitionSpecsByFilter(null, TABLE_NAME, "yyyy=\"2017\"", -1);
+ }
+
+ @Test
+ public void testListPartitionSpecsByFilterNullFilter() throws Exception {
+ List<List<String>> values = createTable4PartColsParts(client);
+ PartitionSpecProxy pproxy = client.listPartitionSpecsByFilter(DB_NAME, TABLE_NAME, null, -1);
+ assertPartitionsSpecProxy(pproxy, values);
+ }
+
+ @Test
+ public void testListPartitionSpecsByFilterEmptyFilter() throws Exception {
+ List<List<String>> values = createTable4PartColsParts(client);
+ PartitionSpecProxy pproxy = client.listPartitionSpecsByFilter(DB_NAME, TABLE_NAME, "", -1);
+ assertPartitionsSpecProxy(pproxy, values);
+ }
+
+
+
+ /**
+ * Testing getNumPartitionsByFilter(String,String,String) ->
+ * get_num_partitions_by_filter(String,String,String).
+ * @throws Exception
+ */
+ @Test
+ public void testGetNumPartitionsByFilter() throws Exception {
+ createTable4PartColsParts(client);
+ int n = client.getNumPartitionsByFilter(DB_NAME, TABLE_NAME, "yyyy=\"2017\" OR " +
+ "mm=\"02\"");
+ assertEquals(3, n);
+
+ n = client.getNumPartitionsByFilter(DB_NAME, TABLE_NAME, "");
+ assertEquals(4, n);
+
+ n = client.getNumPartitionsByFilter(DB_NAME, TABLE_NAME, "yyyy=\"20177\"");
+ assertEquals(0, n);
+
+ n = client.getNumPartitionsByFilter(DB_NAME, TABLE_NAME, "yYyY=\"2017\"");
+ assertEquals(2, n);
+
+ n = client.getNumPartitionsByFilter(DB_NAME, TABLE_NAME, "yyyy=\"2017\" AND mm=\"99\"");
+ assertEquals(0, n);
+
+ }
+
+ @Test(expected = MetaException.class)
+ public void testGetNumPartitionsByFilterInvalidFilter() throws Exception {
+ createTable4PartColsParts(client);
+ client.getNumPartitionsByFilter(DB_NAME, TABLE_NAME, "yyy=\"2017\"");
+ }
+
+ @Test(expected = NoSuchObjectException.class)
+ public void testGetNumPartitionsByFilterNoTblName() throws Exception {
+ createTable4PartColsParts(client);
+ client.getNumPartitionsByFilter(DB_NAME, "", "yyyy=\"2017\"");
+ }
+
+ @Test(expected = NoSuchObjectException.class)
+ public void testGetNumPartitionsByFilterNoDbName() throws Exception {
+ createTable4PartColsParts(client);
+ client.getNumPartitionsByFilter("", TABLE_NAME, "yyyy=\"2017\"");
+ }
+
+ @Test(expected = NoSuchObjectException.class)
+ public void testGetNumPartitionsByFilterNoTable() throws Exception {
+ client.getNumPartitionsByFilter(DB_NAME, TABLE_NAME, "yyyy=\"2017\"");
+ }
+
+ @Test(expected = NoSuchObjectException.class)
+ public void testGetNumPartitionsByFilterNoDb() throws Exception {
+ client.dropDatabase(DB_NAME);
+ client.getNumPartitionsByFilter(DB_NAME, TABLE_NAME, "yyyy=\"2017\"");
+ }
+
+ @Test
+ public void testGetNumPartitionsByFilterNullTblName() throws Exception {
+ try {
+ createTable4PartColsParts(client);
+ client.getNumPartitionsByFilter(DB_NAME, null, "yyyy=\"2017\"");
+ fail("Should have thrown exception");
+ } catch (AssertionError | TTransportException e) {
+ //TODO: should not throw different exceptions for different HMS deployment types
+ }
+ }
+
+ @Test(expected = MetaException.class)
+ public void testGetNumPartitionsByFilterNullDbName() throws Exception {
+ createTable4PartColsParts(client);
+ client.getNumPartitionsByFilter(null, TABLE_NAME, "yyyy=\"2017\"");
+ }
+
+ @Test
+ public void testGetNumPartitionsByFilterNullFilter() throws Exception {
+ createTable4PartColsParts(client);
+ int n = client.getNumPartitionsByFilter(DB_NAME, TABLE_NAME, null);
+ assertEquals(4, n);
+ }
+
+
+
+ /**
+ * Testing listPartitionNames(String,String,short) ->
+ * get_partition_names(String,String,short).
+ * @throws Exception
+ */
+ @Test
+ public void testListPartitionNames() throws Exception {
+ List<List<String>> testValues = createTable4PartColsParts(client);
+ List<String> partitionNames = client.listPartitionNames(DB_NAME, TABLE_NAME, (short)-1);
+ assertCorrectPartitionNames(partitionNames, testValues, Lists.newArrayList("yyyy", "mm",
+ "dd"));
+
+ partitionNames = client.listPartitionNames(DB_NAME, TABLE_NAME, (short)2);
+ assertCorrectPartitionNames(partitionNames, testValues.subList(0, 2),
+ Lists.newArrayList("yyyy", "mm", "dd"));
+
+
+ //TODO: surprisingly listPartitionNames returns everything when 0 parts are requested
+ partitionNames = client.listPartitionNames(DB_NAME, TABLE_NAME, (short)0);
+ assertFalse(partitionNames.isEmpty());
+ assertCorrectPartitionNames(partitionNames, testValues, Lists.newArrayList("yyyy", "mm",
+ "dd"));
+
+ //TODO: surprisingly listPartitionNames doesn't fail when >100 parts are requested
+ partitionNames = client.listPartitionNames(DB_NAME, TABLE_NAME, (short)101);
+ assertCorrectPartitionNames(partitionNames, testValues, Lists.newArrayList("yyyy", "mm",
+ "dd"));
+
+ }
+
+ @Test(expected = NoSuchObjectException.class)
+ public void testListPartitionNamesNoDbName() throws Exception {
+ createTable4PartColsParts(client);
+ client.listPartitionNames("", TABLE_NAME, (short)-1);
+ }
+
+ @Test(expected = NoSuchObjectException.class)
+ public void testListPartitionNamesNoTblName() throws Exception {
+ createTable4PartColsParts(client);
+ client.listPartitionNames(DB_NAME, "", (short)-1);
+ }
+
+ @Test(expected = NoSuchObjectException.class)
+ public void testListPartitionNamesNoTable() throws Exception {
+ client.listPartitionNames(DB_NAME, TABLE_NAME, (short)-1);
+ }
+
+ @Test(expected = NoSuchObjectException.class)
+ public void testListPartitionNamesNoDb() throws Exception {
+ client.dropDatabase(DB_NAME);
+ client.listPartitionNames(DB_NAME, TABLE_NAME, (short)-1);
+ }
+
+ @Test
+ public void testListPartitionNamesNullDbName() throws Exception {
+ try {
+ createTable4PartColsParts(client);
+ client.listPartitionNames(null, TABLE_NAME, (short)-1);
+ fail("Should have thrown exception");
+ } catch (NullPointerException | TTransportException e) {
+ //TODO: should not throw different exceptions for different HMS deployment types
+ }
+ }
+
+ @Test
+ public void testListPartitionNamesNullTblName() throws Exception {
+ try {
+ createTable4PartColsParts(client);
+ client.listPartitionNames(DB_NAME, null, (short)-1);
+ fail("Should have thrown exception");
+ } catch (NullPointerException | TTransportException e) {
+ //TODO: should not throw different exceptions for different HMS deployment types
+ }
+ }
+
+
+
+ /**
+ * Testing listPartitionNames(String,String,List(String),short) ->
+ * get_partition_names_ps(String,String,List(String),short).
+ * @throws Exception
+ */
+ @Test
+ public void testListPartitionNamesByValues() throws Exception {
+ List<List<String>> testValues = createTable4PartColsParts(client);
+ List<String> partitionNames = client.listPartitionNames(DB_NAME, TABLE_NAME,
+ Lists.newArrayList("2017"), (short)-1);
+ assertCorrectPartitionNames(partitionNames, testValues.subList(2, 4),
+ Lists.newArrayList("yyyy", "mm", "dd"));
+
+ partitionNames = client.listPartitionNames(DB_NAME, TABLE_NAME,
+ Lists.newArrayList("2017"), (short)101);
+ assertCorrectPartitionNames(partitionNames, testValues.subList(2, 4),
+ Lists.newArrayList("yyyy", "mm", "dd"));
+
+ partitionNames = client.listPartitionNames(DB_NAME, TABLE_NAME,
+ Lists.newArrayList("2017"), (short)1);
+ assertCorrectPartitionNames(partitionNames, testValues.subList(2, 3),
+ Lists.newArrayList("yyyy", "mm", "dd"));
+
+ partitionNames = client.listPartitionNames(DB_NAME, TABLE_NAME,
+ Lists.newArrayList("2017"), (short)0);
+ assertTrue(partitionNames.isEmpty());
+
+ partitionNames = client.listPartitionNames(DB_NAME, TABLE_NAME,
+ Lists.newArrayList("2017", "10"), (short)-1);
+ assertCorrectPartitionNames(partitionNames, testValues.subList(2, 3),
+ Lists.newArrayList("yyyy", "mm", "dd"));
+
+ }
+
+ @Test
+ public void testListPartitionNamesByValuesMaxPartCountUnlimited() throws Exception {
+ List<List<String>> testValues = createTable4PartColsParts(client);
+ //TODO: due to value 101 this probably should throw an exception
+ List<String> partitionNames = client.listPartitionNames(DB_NAME, TABLE_NAME,
+ Lists.newArrayList("2017"), (short) 101);
+ assertCorrectPartitionNames(partitionNames, testValues.subList(2, 4),
+ Lists.newArrayList("yyyy", "mm", "dd"));
+ }
+
+ @Test(expected = MetaException.class)
+ public void testListPartitionNamesByValuesNoPartVals() throws Exception {
+ createTable4PartColsParts(client);
+ client.listPartitionNames(DB_NAME, TABLE_NAME, Lists.newArrayList(), (short)-1);
+ }
+
+ @Test(expected = MetaException.class)
+ public void testListPartitionNamesByValuesTooManyVals() throws Exception {
+ createTable4PartColsParts(client);
+ client.listPartitionNames(DB_NAME, TABLE_NAME, Lists.newArrayList("1", "2", "3", "4"),
+ (short)-1);
+ }
+
+ @Test(expected = NoSuchObjectException.class)
+ public void testListPartitionNamesByValuesNoDbName() throws Exception {
+ createTable4PartColsParts(client);
+ client.listPartitionNames("", TABLE_NAME, Lists.newArrayList("2017"), (short)-1);
+ }
+
+ @Test(expected = NoSuchObjectException.class)
+ public void testListPartitionNamesByValuesNoTblName() throws Exception {
+ createTable4PartColsParts(client);
+ client.listPartitionNames(DB_NAME, "", Lists.newArrayList("2017"), (short)-1);
+ }
+
+ @Test(expected = NoSuchObjectException.class)
+ public void testListPartitionNamesByValuesNoTable() throws Exception {
+ client.listPartitionNames(DB_NAME, TABLE_NAME, Lists.newArrayList("2017"), (short)-1);
+ }
+
+ @Test(expected = NoSuchObjectException.class)
+ public void testListPartitionNamesByValuesNoDb() throws Exception {
+ client.dropDatabase(DB_NAME);
+ client.listPartitionNames(DB_NAME, TABLE_NAME, Lists.newArrayList("2017"), (short)-1);
+ }
+
+ @Test
+ public void testListPartitionNamesByValuesNullDbName() throws Exception {
+ try {
+ createTable4PartColsParts(client);
+ client.listPartitionNames(null, TABLE_NAME, Lists.newArrayList("2017"), (short) -1);
+ fail("Should have thrown exception");
+ } catch (NullPointerException | TTransportException e) {
+ //TODO: should not throw different exceptions for different HMS deployment types
+ }
+ }
+
+ @Test
+ public void testListPartitionNamesByValuesNullTblName() throws Exception {
+ try {
+ createTable4PartColsParts(client);
+ client.listPartitionNames(DB_NAME, null, Lists.newArrayList("2017"), (short)-1);
+ fail("Should have thrown exception");
+ } catch (NullPointerException | TTransportException e) {
+ //TODO: should not throw different exceptions for different HMS deployment types
+ }
+ }
+
+ @Test(expected = MetaException.class)
+ public void testListPartitionNamesByValuesNullValues() throws Exception {
+ createTable4PartColsParts(client);
+ client.listPartitionNames(DB_NAME, TABLE_NAME, null, (short)-1);
+ }
+
+
+
+ /**
+ * Testing listPartitionValues(PartitionValuesRequest) ->
+ * get_partition_values(PartitionValuesRequest).
+ * @throws Exception
+ */
+ @Test
+ public void testListPartitionValues() throws Exception {
+ List<List<String>> testValues = createTable4PartColsParts(client);
+ List<FieldSchema> partitionSchema = Lists.newArrayList(
+ new FieldSchema("yyyy", "string", ""),
+ new FieldSchema("mm", "string", ""));
+
+ PartitionValuesRequest request = new PartitionValuesRequest(DB_NAME, TABLE_NAME,
+ partitionSchema);
+ PartitionValuesResponse response = client.listPartitionValues(request);
+ assertCorrectPartitionValuesResponse(testValues, response);
+
+ }
+
+ @Test
+ public void testListPartitionValuesEmptySchema() throws Exception {
+ try {
+ List<List<String>> testValues = createTable4PartColsParts(client);
+ List<FieldSchema> partitionSchema = Lists.newArrayList();
+
+ PartitionValuesRequest request = new PartitionValuesRequest(DB_NAME, TABLE_NAME,
+ partitionSchema);
+ client.listPartitionValues(request);
+ fail("Should have thrown exception");
+ } catch (IndexOutOfBoundsException | TTransportException e) {
+ //TODO: should not throw different exceptions for different HMS deployment types
+ }
+ }
+
+ @Test(expected = MetaException.class)
+ public void testListPartitionValuesNoDbName() throws Exception {
+ createTable4PartColsParts(client);
+ List<FieldSchema> partitionSchema = Lists.newArrayList(
+ new FieldSchema("yyyy", "string", ""),
+ new FieldSchema("mm", "string", ""));
+
+ PartitionValuesRequest request = new PartitionValuesRequest("", TABLE_NAME,
+ partitionSchema);
+ client.listPartitionValues(request);
+ }
+
+ @Test(expected = MetaException.class)
+ public void testListPartitionValuesNoTblName() throws Exception {
+ createTable4PartColsParts(client);
+ List<FieldSchema> partitionSchema = Lists.newArrayList(
+ new FieldSchema("yyyy", "string", ""),
+ new FieldSchema("mm", "string", ""));
+
+ PartitionValuesRequest request = new PartitionValuesRequest(DB_NAME, "",
+ partitionSchema);
+ client.listPartitionValues(request);
+ }
+
+ @Test(expected = MetaException.class)
+ public void testListPartitionValuesNoTable() throws Exception {
+ List<FieldSchema> partitionSchema = Lists.newArrayList(
+ new FieldSchema("yyyy", "string", ""),
+ new FieldSchema("mm", "string", ""));
+
+ PartitionValuesRequest request = new PartitionValuesRequest(DB_NAME, TABLE_NAME,
+ partitionSchema);
+ client.listPartitionValues(request);
+ }
+
+ @Test(expected = MetaException.class)
+ public void testListPartitionValuesNoDb() throws Exception {
+ client.dropDatabase(DB_NAME);
+ List<FieldSchema> partitionSchema = Lists.newArrayList(
+ new FieldSchema("yyyy", "string", ""),
+ new FieldSchema("mm", "string", ""));
+
+ PartitionValuesRequest request = new PartitionValuesRequest(DB_NAME, TABLE_NAME,
+ partitionSchema);
+ client.listPartitionValues(request);
+ }
+
+ @Test
+ public void testListPartitionValuesNullDbName() throws Exception {
+ try {
+ createTable4PartColsParts(client);
+ List<FieldSchema> partitionSchema = Lists.newArrayList(
+ new FieldSchema("yyyy", "string", ""),
+ new FieldSchema("mm", "string", ""));
+
+ PartitionValuesRequest request = new PartitionValuesRequest(null, TABLE_NAME,
+ partitionSchema);
+ client.listPartitionValues(request);
+ fail("Should have thrown exception");
+ } catch (NullPointerException | TProtocolException e) {
+ //TODO: should not throw different exceptions for different HMS deployment types
+ }
+ }
+
+ @Test
+ public void testListPartitionValuesNullTblName() throws Exception {
+ try {
+ createTable4PartColsParts(client);
+ List<FieldSchema> partitionSchema = Lists.newArrayList(
+ new FieldSchema("yyyy", "string", ""),
+ new FieldSchema("mm", "string", ""));
+
+ PartitionValuesRequest request = new PartitionValuesRequest(DB_NAME, null,
+ partitionSchema);
+ client.listPartitionValues(request);
+ fail("Should have thrown exception");
+ } catch (NullPointerException | TProtocolException e) {
+ //TODO: should not throw different exceptions for different HMS deployment types
+ }
+ }
+
+ @Test
+ public void testListPartitionValuesNullSchema() throws Exception {
+ try {
+ createTable4PartColsParts(client);
+ PartitionValuesRequest request = new PartitionValuesRequest(DB_NAME, TABLE_NAME,
+ null);
+ client.listPartitionValues(request);
+ fail("Should have thrown exception");
+ } catch (NullPointerException | TProtocolException e) {
+ //TODO: should not throw different exceptions for different HMS deployment types
+ }
+ }
+
+ @Test
+ public void testListPartitionValuesNullRequest() throws Exception {
+ try {
+ createTable4PartColsParts(client);
+ client.listPartitionValues(null);
+ fail("Should have thrown exception");
+ } catch (NullPointerException | TTransportException e) {
+ //TODO: should not throw different exceptions for different HMS deployment types
+ }
+ }
+
+}
[2/2] hive git commit: HIVE-18509: Create tests for table
manipulation related methods (create, alter, drop) (Peter Vary,
reviewed by Yongzhi Chen, Marta Kuczora and Adam Szita)
Posted by pv...@apache.org.
HIVE-18509: Create tests for table manipulation related methods (create, alter, drop) (Peter Vary, reviewed by Yongzhi Chen, Marta Kuczora and Adam Szita)
Project: http://git-wip-us.apache.org/repos/asf/hive/repo
Commit: http://git-wip-us.apache.org/repos/asf/hive/commit/1833ac9b
Tree: http://git-wip-us.apache.org/repos/asf/hive/tree/1833ac9b
Diff: http://git-wip-us.apache.org/repos/asf/hive/diff/1833ac9b
Branch: refs/heads/master
Commit: 1833ac9bd5fa5ab579e112b6cdd641c8ff69b770
Parents: fa0a8d2
Author: Peter Vary <pv...@cloudera.com>
Authored: Sat Jan 27 20:16:27 2018 +0100
Committer: Peter Vary <pv...@cloudera.com>
Committed: Sat Jan 27 20:16:27 2018 +0100
----------------------------------------------------------------------
.../TestTablesCreateDropAlterTruncate.java | 1129 ++++++++++++++++++
1 file changed, 1129 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/hive/blob/1833ac9b/standalone-metastore/src/test/java/org/apache/hadoop/hive/metastore/client/TestTablesCreateDropAlterTruncate.java
----------------------------------------------------------------------
diff --git a/standalone-metastore/src/test/java/org/apache/hadoop/hive/metastore/client/TestTablesCreateDropAlterTruncate.java b/standalone-metastore/src/test/java/org/apache/hadoop/hive/metastore/client/TestTablesCreateDropAlterTruncate.java
new file mode 100644
index 0000000..abc400a
--- /dev/null
+++ b/standalone-metastore/src/test/java/org/apache/hadoop/hive/metastore/client/TestTablesCreateDropAlterTruncate.java
@@ -0,0 +1,1129 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 org.apache.hadoop.hive.metastore.client;
+
+import org.apache.hadoop.fs.Path;
+import org.apache.hadoop.hive.common.StatsSetupConst;
+import org.apache.hadoop.hive.metastore.IMetaStoreClient;
+import org.apache.hadoop.hive.metastore.api.AlreadyExistsException;
+import org.apache.hadoop.hive.metastore.api.EnvironmentContext;
+import org.apache.hadoop.hive.metastore.api.FieldSchema;
+import org.apache.hadoop.hive.metastore.api.InvalidObjectException;
+import org.apache.hadoop.hive.metastore.api.InvalidOperationException;
+import org.apache.hadoop.hive.metastore.api.MetaException;
+import org.apache.hadoop.hive.metastore.api.NoSuchObjectException;
+import org.apache.hadoop.hive.metastore.api.Partition;
+import org.apache.hadoop.hive.metastore.api.SerDeInfo;
+import org.apache.hadoop.hive.metastore.api.SkewedInfo;
+import org.apache.hadoop.hive.metastore.api.StorageDescriptor;
+import org.apache.hadoop.hive.metastore.api.Table;
+import org.apache.hadoop.hive.metastore.client.builder.DatabaseBuilder;
+import org.apache.hadoop.hive.metastore.client.builder.PartitionBuilder;
+import org.apache.hadoop.hive.metastore.client.builder.TableBuilder;
+import org.apache.hadoop.hive.metastore.conf.MetastoreConf;
+import org.apache.hadoop.hive.metastore.minihms.AbstractMetaStoreService;
+import org.apache.thrift.protocol.TProtocolException;
+import org.apache.thrift.transport.TTransportException;
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+/**
+ * Test class for IMetaStoreClient API. Testing the Table related functions for metadata
+ * manipulation, like creating, dropping and altering tables.
+ */
+@RunWith(Parameterized.class)
+public class TestTablesCreateDropAlterTruncate {
+ // Needed until there is no junit release with @BeforeParam, @AfterParam (junit 4.13)
+ // https://github.com/junit-team/junit4/commit/1bf8438b65858565dbb64736bfe13aae9cfc1b5a
+ // Then we should remove our own copy
+ private static Set<AbstractMetaStoreService> metaStoreServices = null;
+ private static final String DEFAULT_DATABASE = "default";
+ private static final String OTHER_DATABASE = "dummy";
+ private final AbstractMetaStoreService metaStore;
+ private IMetaStoreClient client;
+ private Table[] testTables = new Table[6];
+ private Table partitionedTable = null;
+ private Table externalTable = null;
+
+ @Parameterized.Parameters(name = "{0}")
+ public static List<Object[]> getMetaStoreToTest() throws Exception {
+ List<Object[]> result = MetaStoreFactoryForTests.getMetaStores();
+ metaStoreServices = result.stream()
+ .map(test -> (AbstractMetaStoreService)test[1])
+ .collect(Collectors.toSet());
+ return result;
+ }
+
+ public TestTablesCreateDropAlterTruncate(String name, AbstractMetaStoreService metaStore) throws Exception {
+ this.metaStore = metaStore;
+ Map<MetastoreConf.ConfVars, String> msConf = new HashMap<MetastoreConf.ConfVars, String>();
+ // Enable trash, so it can be tested
+ Map<String, String> extraConf = new HashMap<String, String>();
+ extraConf.put("fs.trash.checkpoint.interval", "30"); // FS_TRASH_CHECKPOINT_INTERVAL_KEY
+ extraConf.put("fs.trash.interval", "30"); // FS_TRASH_INTERVAL_KEY (hadoop-2)
+
+ this.metaStore.start(msConf, extraConf);
+ }
+
+ // Needed until there is no junit release with @BeforeParam, @AfterParam (junit 4.13)
+ // https://github.com/junit-team/junit4/commit/1bf8438b65858565dbb64736bfe13aae9cfc1b5a
+ // Then we should move this to @AfterParam
+ @AfterClass
+ public static void stopMetaStores() throws Exception {
+ for(AbstractMetaStoreService metaStoreService : metaStoreServices) {
+ metaStoreService.stop();
+ }
+ }
+
+ @Before
+ public void setUp() throws Exception {
+ // Get new client
+ client = metaStore.getClient();
+
+ // Clean up the database
+ client.dropDatabase(OTHER_DATABASE, true, true, true);
+ // Drop every table in the default database
+ for(String tableName : client.getAllTables(DEFAULT_DATABASE)) {
+ client.dropTable(DEFAULT_DATABASE, tableName, true, true, true);
+ }
+
+ // Clean up trash
+ metaStore.cleanWarehouseDirs();
+
+ testTables[0] =
+ new TableBuilder()
+ .setDbName(DEFAULT_DATABASE)
+ .setTableName("test_table")
+ .addCol("test_col", "int")
+ .build();
+
+ testTables[1] =
+ new TableBuilder()
+ .setDbName(DEFAULT_DATABASE)
+ .setTableName("test_view")
+ .addCol("test_col", "int")
+ .setType("VIRTUAL_VIEW")
+ .build();
+
+ testTables[2] =
+ new TableBuilder()
+ .setDbName(DEFAULT_DATABASE)
+ .setTableName("test_table_to_find_1")
+ .addCol("test_col", "int")
+ .build();
+
+ testTables[3] =
+ new TableBuilder()
+ .setDbName(DEFAULT_DATABASE)
+ .setTableName("test_partitioned_table")
+ .addCol("test_col1", "int")
+ .addCol("test_col2", "int")
+ .addPartCol("test_part_col", "int")
+ .build();
+
+ testTables[4] =
+ new TableBuilder()
+ .setDbName(DEFAULT_DATABASE)
+ .setTableName("external_table_for_test")
+ .addCol("test_col", "int")
+ .setLocation(metaStore.getWarehouseRoot() + "/external/table_dir")
+ .addTableParam("EXTERNAL", "TRUE")
+ .setType("EXTERNAL_TABLE")
+ .build();
+
+
+ client.createDatabase(new DatabaseBuilder().setName(OTHER_DATABASE).build());
+
+ testTables[5] =
+ new TableBuilder()
+ .setDbName(OTHER_DATABASE)
+ .setTableName("test_table")
+ .addCol("test_col", "int")
+ .build();
+
+ // Create the tables in the MetaStore
+ for(int i=0; i < testTables.length; i++) {
+ client.createTable(testTables[i]);
+ }
+
+ // Create partitions for the partitioned table
+ for(int i=0; i < 3; i++) {
+ Partition partition =
+ new PartitionBuilder()
+ .fromTable(testTables[3])
+ .addValue("a" + i)
+ .build();
+ client.add_partition(partition);
+ }
+ // Add data files to the partitioned table
+ List<Partition> partitions =
+ client.listPartitions(testTables[3].getDbName(), testTables[3].getTableName(), (short)-1);
+ for(Partition partition : partitions) {
+ Path dataFile = new Path(partition.getSd().getLocation().toString() + "/dataFile");
+ metaStore.createFile(dataFile, "100");
+ }
+
+ // Reload tables from the MetaStore, and create data files
+ for(int i=0; i < testTables.length; i++) {
+ testTables[i] = client.getTable(testTables[i].getDbName(), testTables[i].getTableName());
+ if (testTables[i].getPartitionKeys().isEmpty()) {
+ if (testTables[i].getSd().getLocation() != null) {
+ Path dataFile = new Path(testTables[i].getSd().getLocation().toString() + "/dataFile");
+ metaStore.createFile(dataFile, "100");
+ }
+ }
+ }
+ partitionedTable = testTables[3];
+ externalTable = testTables[4];
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ try {
+ if (client != null) {
+ client.close();
+ }
+ } finally {
+ client = null;
+ }
+ }
+
+ /**
+ * This test creates and queries a table and then drops it. Good for testing the happy path
+ * @throws Exception
+ */
+ @Test
+ public void testCreateGetDeleteTable() throws Exception {
+ // Try to create a table with all of the parameters set
+ Table table = getTableWithAllParametersSet();
+ client.createTable(table);
+ Table createdTable = client.getTable(table.getDbName(), table.getTableName());
+ // The createTime will be set on the server side, so the comparison should skip it
+ table.setCreateTime(createdTable.getCreateTime());
+ // The extra parameters will be added on server side, so check that the required ones are
+ // present
+ for(String key: table.getParameters().keySet()) {
+ Assert.assertEquals("parameters are the same",
+ table.getParameters().get(key), createdTable.getParameters().get(key));
+ }
+ // Reset the parameters, so we can compare
+ table.setParameters(createdTable.getParameters());
+ table.setCreationMetadata(createdTable.getCreationMetadata());
+ Assert.assertEquals("create/get table data", table, createdTable);
+
+ // Check that the directory is created
+ Assert.assertTrue("The directory should not be created",
+ metaStore.isPathExists(new Path(createdTable.getSd().getLocation())));
+
+ client.dropTable(table.getDbName(), table.getTableName(), true, false);
+ try {
+ client.getTable(table.getDbName(), table.getTableName());
+ Assert.fail("Expected a NoSuchObjectException to be thrown");
+ } catch (NoSuchObjectException exception) {
+ // Expected exception
+ }
+ }
+
+ @Test
+ public void testCreateTableDefaultValues() throws Exception {
+ Table table = new Table();
+ StorageDescriptor sd = new StorageDescriptor();
+ List<FieldSchema> cols = new ArrayList<FieldSchema>();
+
+ table.setDbName(DEFAULT_DATABASE);
+ table.setTableName("test_table_2");
+ cols.add(new FieldSchema("column_name", "int", null));
+ sd.setCols(cols);
+ sd.setSerdeInfo(new SerDeInfo());
+ table.setSd(sd);
+
+ client.createTable(table);
+ Table createdTable = client.getTable(table.getDbName(), table.getTableName());
+
+ Assert.assertNull("Comparing OwnerName", createdTable.getOwner());
+ Assert.assertNotEquals("Comparing CreateTime", 0, createdTable.getCreateTime());
+ Assert.assertEquals("Comparing LastAccessTime", 0, createdTable.getLastAccessTime());
+ Assert.assertEquals("Comparing Retention", 0, createdTable.getRetention());
+ Assert.assertEquals("Comparing PartitionKeys", 0, createdTable.getPartitionKeys().size());
+ // TODO: If this test method is the first to run, then the parameters does not contain totalSize
+ // and numFiles, if this runs after other tests (setUp/dropDatabase is successful), then the
+ // totalSize and the numFiles are set.
+ Assert.assertEquals("Comparing Parameters length", 1, createdTable.getParameters().size());
+ Assert.assertNotEquals("Comparing Parameters(transient_lastDdlTime)", "0",
+ createdTable.getParameters().get("transient_lastDdlTime"));
+// Assert.assertEquals("Comparing Parameters(totalSize)", "0",
+// createdTable.getParameters().get("totalSize"));
+// Assert.assertEquals("Comparing Parameters(numFiles)", "0",
+// createdTable.getParameters().get("numFiles"));
+ Assert.assertNull("Comparing ViewOriginalText", createdTable.getViewOriginalText());
+ Assert.assertNull("Comparing ViewExpandedText", createdTable.getViewExpandedText());
+ Assert.assertEquals("Comparing TableType", "MANAGED_TABLE", createdTable.getTableType());
+ Assert.assertTrue("Creation metadata should be empty", createdTable.getCreationMetadata().isEmpty());
+
+ // Storage Descriptor data
+ StorageDescriptor createdSd = createdTable.getSd();
+ Assert.assertEquals("Storage descriptor cols", 1, createdSd.getCols().size());
+ Assert.assertNull("Storage descriptor cols[0].comment",
+ createdSd.getCols().get(0).getComment());
+ Assert.assertEquals("Storage descriptor location", metaStore.getWarehouseRoot()
+ + "/" + table.getTableName(), createdSd.getLocation());
+ Assert.assertTrue("Table path should be created",
+ metaStore.isPathExists(new Path(createdSd.getLocation())));
+ // TODO: Embedded MetaStore changes the table object when client.createTable is called
+ //Assert.assertNull("Original table storage descriptor location should be null",
+ // table.getSd().getLocation());
+
+ Assert.assertNull("Storage descriptor input format", createdSd.getInputFormat());
+ Assert.assertNull("Storage descriptor output format", createdSd.getOutputFormat());
+ Assert.assertFalse("Storage descriptor compressed", createdSd.isCompressed());
+ Assert.assertEquals("Storage descriptor num buckets", 0, createdSd.getNumBuckets());
+ Assert.assertEquals("Storage descriptor bucket cols", 0, createdSd.getBucketCols().size());
+ Assert.assertEquals("Storage descriptor sort cols", 0, createdSd.getSortCols().size());
+ Assert.assertEquals("Storage descriptor parameters", 0, createdSd.getParameters().size());
+ Assert.assertFalse("Storage descriptor stored as subdir", createdSd.isStoredAsSubDirectories());
+
+ // Serde info
+ SerDeInfo serDeInfo = createdSd.getSerdeInfo();
+ Assert.assertNull("SerDeInfo name", serDeInfo.getName());
+ Assert.assertNull("SerDeInfo serialization lib", serDeInfo.getSerializationLib());
+ Assert.assertEquals("SerDeInfo parameters", 0, serDeInfo.getParameters().size());
+
+ // Skewed info
+ SkewedInfo skewedInfo = createdSd.getSkewedInfo();
+ Assert.assertEquals("Skewed info col names", 0, skewedInfo.getSkewedColNames().size());
+ Assert.assertEquals("Skewed info col values", 0, skewedInfo.getSkewedColValues().size());
+ Assert.assertEquals("Skewed info col value maps", 0,
+ skewedInfo.getSkewedColValueLocationMaps().size());
+ }
+
+ @Test
+ public void testCreateTableDefaultLocationInSpecificDatabase() throws Exception {
+ Table table = new Table();
+ StorageDescriptor sd = new StorageDescriptor();
+ List<FieldSchema> cols = new ArrayList<FieldSchema>();
+
+ table.setDbName(OTHER_DATABASE);
+ table.setTableName("test_table_2");
+ cols.add(new FieldSchema("column_name", "int", null));
+ sd.setCols(cols);
+ sd.setSerdeInfo(new SerDeInfo());
+ table.setSd(sd);
+
+ client.createTable(table);
+ Table createdTable = client.getTable(table.getDbName(), table.getTableName());
+ Assert.assertEquals("Storage descriptor location", metaStore.getWarehouseRoot()
+ + "/" + table.getDbName() + ".db/" + table.getTableName(),
+ createdTable.getSd().getLocation());
+ }
+
+ @Test
+ public void testCreateTableDefaultValuesView() throws Exception {
+ Table table = new Table();
+ StorageDescriptor sd = new StorageDescriptor();
+ List<FieldSchema> cols = new ArrayList<FieldSchema>();
+
+ table.setDbName(DEFAULT_DATABASE);
+ table.setTableName("test_table_2");
+ table.setTableType("VIRTUAL_VIEW");
+ cols.add(new FieldSchema("column_name", "int", null));
+ sd.setCols(cols);
+ sd.setSerdeInfo(new SerDeInfo());
+ table.setSd(sd);
+
+ client.createTable(table);
+ Table createdTable = client.getTable(table.getDbName(), table.getTableName());
+
+ // No location should be created for views
+ StorageDescriptor createdSd = createdTable.getSd();
+ Assert.assertNull("Storage descriptor location should be null",
+ createdTable.getSd().getLocation());
+ }
+
+ @Test(expected = MetaException.class)
+ public void testCreateTableNullDatabase() throws Exception {
+ Table table = testTables[0];
+ table.setDbName(null);
+
+ client.createTable(table);
+ }
+
+ @Test(expected = MetaException.class)
+ public void testCreateTableNullTableName() throws Exception {
+ Table table = testTables[0];
+ table.setTableName(null);
+
+ client.createTable(table);
+ }
+
+ @Test(expected = InvalidObjectException.class)
+ public void testCreateTableInvalidTableName() throws Exception {
+ Table table = testTables[0];
+ table.setTableName("test_table;");
+
+ client.createTable(table);
+ }
+
+ @Test(expected = InvalidObjectException.class)
+ public void testCreateTableEmptyName() throws Exception {
+ Table table = testTables[0];
+ table.setTableName("");
+
+ client.createTable(table);
+ }
+
+ @Test(expected = MetaException.class)
+ public void testCreateTableNullStorageDescriptor() throws Exception {
+ Table table = testTables[0];
+ table.setSd(null);
+
+ client.createTable(table);
+ }
+
+ private Table getNewTable() throws MetaException {
+ return new TableBuilder()
+ .setDbName(DEFAULT_DATABASE)
+ .setTableName("test_table_with_invalid_sd")
+ .addCol("test_col", "int")
+ .build();
+ }
+
+ @Test(expected = MetaException.class)
+ public void testCreateTableInvalidStorageDescriptorNullColumns() throws Exception {
+ Table table = getNewTable();
+ table.getSd().setCols(null);
+ client.createTable(table);
+ }
+
+ @Test(expected = MetaException.class)
+ public void testCreateTableInvalidStorageDescriptorNullSerdeInfo() throws Exception {
+ Table table = getNewTable();
+ table.getSd().setSerdeInfo(null);
+
+ client.createTable(table);
+ }
+
+ @Test(expected = MetaException.class)
+ public void testCreateTableInvalidStorageDescriptorNullColumnType() throws Exception {
+ Table table = getNewTable();
+ table.getSd().getCols().get(0).setType(null);
+
+ client.createTable(table);
+ }
+
+ @Test(expected = InvalidObjectException.class)
+ public void testCreateTableInvalidStorageDescriptorInvalidColumnType() throws Exception {
+ Table table = getNewTable();
+ table.getSd().getCols().get(0).setType("xyz");
+
+ client.createTable(table);
+ }
+
+ @Test(expected = InvalidObjectException.class)
+ public void testCreateTableNoSuchDatabase() throws Exception {
+ Table table = testTables[0];
+ table.setDbName("no_such_database");
+
+ client.createTable(table);
+ }
+
+ @Test(expected = AlreadyExistsException.class)
+ public void testCreateTableAlreadyExists() throws Exception {
+ Table table = testTables[0];
+
+ client.createTable(table);
+ }
+
+ @Test(expected = NoSuchObjectException.class)
+ public void testDropTableNoSuchDatabase() throws Exception {
+ Table table = testTables[2];
+
+ client.dropTable("no_such_database", table.getTableName(), true, false);
+ }
+
+ @Test(expected = NoSuchObjectException.class)
+ public void testDropTableNoSuchTable() throws Exception {
+ Table table = testTables[2];
+
+ client.dropTable(table.getDbName(), "no_such_table", true, false);
+ }
+
+ @Test(expected = NoSuchObjectException.class)
+ public void testDropTableNoSuchTableInTheDatabase() throws Exception {
+ Table table = testTables[2];
+
+ client.dropTable(OTHER_DATABASE, table.getTableName(), true, false);
+ }
+
+ @Test
+ public void testDropTableNullDatabase() throws Exception {
+ // Missing database in the query
+ try {
+ client.dropTable(null, OTHER_DATABASE, true, false);
+ // TODO: Should be checked on server side. On Embedded metastore it throws MetaException,
+ // on Remote metastore it throws TProtocolException
+ Assert.fail("Expected an MetaException or TProtocolException to be thrown");
+ } catch (MetaException exception) {
+ // Expected exception - Embedded MetaStore
+ } catch (TProtocolException exception) {
+ // Expected exception - Remote MetaStore
+ }
+ }
+
+ @Test
+ public void testDropTableNullTableName() throws Exception {
+ try {
+ client.dropTable(DEFAULT_DATABASE, null, true, false);
+ // TODO: Should be checked on server side. On Embedded metastore it throws MetaException,
+ // on Remote metastore it throws TProtocolException
+ Assert.fail("Expected an MetaException or TProtocolException to be thrown");
+ } catch (MetaException exception) {
+ // Expected exception - Embedded MetaStore
+ } catch (TProtocolException exception) {
+ // Expected exception - Remote MetaStore
+ }
+ }
+
+ @Test
+ public void testDropTableCaseInsensitive() throws Exception {
+ Table table = testTables[0];
+
+ // Test in upper case
+ client.dropTable(table.getDbName().toUpperCase(), table.getTableName().toUpperCase());
+ try {
+ client.getTable(table.getDbName(), table.getTableName());
+ Assert.fail("Expected a NoSuchObjectException to be thrown");
+ } catch (NoSuchObjectException exception) {
+ // Expected exception
+ }
+
+ // Test in mixed case
+ client.createTable(table);
+ client.dropTable("DeFaUlt", "TeST_tAbLE");
+ try {
+ client.getTable(table.getDbName(), table.getTableName());
+ Assert.fail("Expected a NoSuchObjectException to be thrown");
+ } catch (NoSuchObjectException exception) {
+ // Expected exception
+ }
+ }
+
+ @Test
+ public void testDropTableDeleteDir() throws Exception {
+ Table table = testTables[0];
+
+ client.dropTable(table.getDbName(), table.getTableName(), true, false);
+
+ Assert.assertFalse("Table path should be removed",
+ metaStore.isPathExists(new Path(table.getSd().getLocation())));
+
+ client.createTable(table);
+ client.dropTable(table.getDbName(), table.getTableName(), false, false);
+
+ Assert.assertTrue("Table path should be kept",
+ metaStore.isPathExists(new Path(table.getSd().getLocation())));
+
+ // Drop table with partitions
+ client.dropTable(partitionedTable.getDbName(), partitionedTable.getTableName(), true, false);
+
+ Assert.assertFalse("Table path should be removed",
+ metaStore.isPathExists(new Path(partitionedTable.getSd().getLocation())));
+ }
+
+ @Test
+ public void testDropTableIgnoreUnknown() throws Exception {
+ Table table = testTables[0];
+
+ // Check what happens, when we ignore these errors
+ client.dropTable("no_such_database", table.getTableName(), true, true);
+ client.dropTable(table.getDbName(), "no_such_table", false, true);
+ client.dropTable(OTHER_DATABASE, table.getTableName(), true, true);
+
+ // TODO: Strangely the default parametrization is to ignore missing tables
+ client.dropTable("no_such_database", table.getTableName());
+ client.dropTable(table.getDbName(), "no_such_table");
+ client.dropTable(OTHER_DATABASE, table.getTableName());
+ }
+
+ @Test
+ public void testDropTableWithPurge() throws Exception {
+ Table table = testTables[0];
+
+ client.dropTable(table.getDbName(), table.getTableName(), true, true, true);
+
+ Assert.assertFalse("Table path should be removed",
+ metaStore.isPathExists(new Path(table.getSd().getLocation())));
+ Assert.assertFalse("Table path should not be in trash",
+ metaStore.isPathExistsInTrash(new Path(table.getSd().getLocation())));
+ }
+
+ @Test
+ public void testDropTableWithoutPurge() throws Exception {
+ Table table = testTables[0];
+
+ client.dropTable(table.getDbName(), table.getTableName(), true, true, false);
+
+ Assert.assertFalse("Table path should be removed",
+ metaStore.isPathExists(new Path(table.getSd().getLocation())));
+ Assert.assertTrue("Table path should be in trash",
+ metaStore.isPathExistsInTrash(new Path(table.getSd().getLocation())));
+ }
+
+ @Test
+ public void testDropTableExternalWithPurge() throws Exception {
+ Table table = externalTable;
+
+ client.dropTable(table.getDbName(), table.getTableName(), true, true, true);
+
+ Assert.assertTrue("Table path should not be removed",
+ metaStore.isPathExists(new Path(table.getSd().getLocation())));
+ Assert.assertFalse("Table path should not be in trash",
+ metaStore.isPathExistsInTrash(new Path(table.getSd().getLocation())));
+ }
+
+ @Test
+ public void testDropTableExternalWithoutPurge() throws Exception {
+ Table table = externalTable;
+
+ client.dropTable(table.getDbName(), table.getTableName(), true, true, false);
+
+ Assert.assertTrue("Table path should not be removed",
+ metaStore.isPathExists(new Path(table.getSd().getLocation())));
+ Assert.assertFalse("Table path should be in trash",
+ metaStore.isPathExistsInTrash(new Path(table.getSd().getLocation())));
+ }
+
+ @Test
+ public void testTruncateTableUnpartitioned() throws Exception {
+ // Unpartitioned table
+ Path dataFile = new Path(testTables[0].getSd().getLocation().toString() + "/dataFile");
+ client.truncateTable(testTables[0].getDbName(), testTables[0].getTableName(), null);
+ Assert.assertTrue("Location should exist",
+ metaStore.isPathExists(new Path(testTables[0].getSd().getLocation())));
+ Assert.assertFalse("DataFile should be removed", metaStore.isPathExists(dataFile));
+
+ }
+
+ @Test
+ public void testTruncateTablePartitioned() throws Exception {
+ // Partitioned table - delete specific partitions a0, a2
+ List<String> partitionsToDelete = new ArrayList<String>();
+ partitionsToDelete.add("test_part_col=a0");
+ partitionsToDelete.add("test_part_col=a2");
+ client.truncateTable(partitionedTable.getDbName(), partitionedTable.getTableName(),
+ partitionsToDelete);
+ Assert.assertTrue("Location should exist",
+ metaStore.isPathExists(new Path(testTables[0].getSd().getLocation())));
+ List<Partition> partitions =
+ client.listPartitions(partitionedTable.getDbName(), partitionedTable.getTableName(),
+ (short)-1);
+ for(Partition partition : partitions) {
+ Path dataFile = new Path(partition.getSd().getLocation().toString() + "/dataFile");
+ if (partition.getValues().contains("a0") || partition.getValues().contains("a2")) {
+ // a0, a2 should be empty
+ Assert.assertFalse("DataFile should be removed", metaStore.isPathExists(dataFile));
+ } else {
+ // Others (a1) should be kept
+ Assert.assertTrue("DataFile should not be removed", metaStore.isPathExists(dataFile));
+ }
+ }
+
+ }
+
+ @Test
+ public void testTruncateTablePartitionedDeleteAll() throws Exception {
+ // Partitioned table - delete all
+ client.truncateTable(partitionedTable.getDbName(), partitionedTable.getTableName(), null);
+ Assert.assertTrue("Location should exist",
+ metaStore.isPathExists(new Path(testTables[0].getSd().getLocation())));
+ List<Partition> partitions =
+ client.listPartitions(partitionedTable.getDbName(), partitionedTable.getTableName(),
+ (short)-1);
+ for(Partition partition : partitions) {
+ Path dataFile = new Path(partition.getSd().getLocation().toString() + "/dataFile");
+ Assert.assertFalse("Every dataFile should be removed", metaStore.isPathExists(dataFile));
+ }
+ }
+
+ @Test
+ public void testAlterTable() throws Exception {
+ Table originalTable = testTables[2];
+ String originalTableName = originalTable.getTableName();
+ String originalDatabase = originalTable.getDbName();
+
+ Table newTable = getTableWithAllParametersSet();
+ newTable.setTableName(originalTableName);
+ newTable.setDbName(originalDatabase);
+ // Partition keys can not be set, but getTableWithAllParametersSet is added one, so remove for
+ // this test
+ newTable.setPartitionKeys(originalTable.getPartitionKeys());
+ client.alter_table(originalDatabase, originalTableName, newTable);
+ Table alteredTable = client.getTable(originalDatabase, originalTableName);
+
+ // The extra parameters will be added on server side, so check that the required ones are
+ // present
+ for(String key: newTable.getParameters().keySet()) {
+ Assert.assertEquals("parameters are present", newTable.getParameters().get(key),
+ alteredTable.getParameters().get(key));
+ }
+ // The parameters are checked manually, so do not check them
+ newTable.setParameters(alteredTable.getParameters());
+
+ // Some of the data is set on the server side, so reset those
+ newTable.setCreateTime(alteredTable.getCreateTime());
+ newTable.setCreationMetadata(alteredTable.getCreationMetadata());
+ Assert.assertEquals("The table data should be the same", newTable, alteredTable);
+ }
+
+ @Test
+ public void testAlterTableRename() throws Exception {
+ Table originalTable = testTables[2];
+ String originalTableName = originalTable.getTableName();
+ String originalDatabase = originalTable.getDbName();
+
+ Table newTable = originalTable.deepCopy();
+ // Do not change the location, so it is tested that the location will be changed even if the
+ // location is not set to null, just remain the same
+ newTable.setTableName("new_table");
+ client.alter_table(originalDatabase, originalTableName, newTable);
+ List<String> tableNames = client.getTables(originalDatabase, originalTableName);
+ Assert.assertEquals("Original table should be removed", 0, tableNames.size());
+ Assert.assertFalse("Original table directory should be removed",
+ metaStore.isPathExists(new Path(originalTable.getSd().getLocation())));
+ Table alteredTable = client.getTable(newTable.getDbName(), newTable.getTableName());
+ Assert.assertTrue("New table directory should exist",
+ metaStore.isPathExists(new Path(alteredTable.getSd().getLocation())));
+ Assert.assertEquals("New directory should be set", new Path(metaStore.getWarehouseRoot()
+ + "/" + alteredTable.getTableName()), new Path(alteredTable.getSd().getLocation()));
+
+ Path dataFile = new Path(alteredTable.getSd().getLocation().toString() + "/dataFile");
+ Assert.assertTrue("New directory should contain data", metaStore.isPathExists(dataFile));
+
+ // The following data should be changed
+ newTable.getSd().setLocation(alteredTable.getSd().getLocation());
+ Assert.assertEquals("The table data should be the same", newTable, alteredTable);
+ }
+
+ @Test
+ public void testAlterTableChangingDatabase() throws Exception {
+ Table originalTable = testTables[2];
+ String originalTableName = originalTable.getTableName();
+ String originalDatabase = originalTable.getDbName();
+
+ Table newTable = originalTable.deepCopy();
+ newTable.setDbName(OTHER_DATABASE);
+ client.alter_table(originalDatabase, originalTableName, newTable);
+ List<String> tableNames = client.getTables(originalDatabase, originalTableName);
+ Assert.assertEquals("Original table should be removed", 0, tableNames.size());
+ Assert.assertFalse("Original table directory should be removed",
+ metaStore.isPathExists(new Path(originalTable.getSd().getLocation())));
+ Table alteredTable = client.getTable(newTable.getDbName(), newTable.getTableName());
+ Assert.assertTrue("New table directory should exist",
+ metaStore.isPathExists(new Path(alteredTable.getSd().getLocation())));
+ Assert.assertEquals("New directory should be set", new Path(metaStore.getWarehouseRoot()
+ + "/" + alteredTable.getDbName() + ".db/" + alteredTable.getTableName()),
+ new Path(alteredTable.getSd().getLocation()));
+ Path dataFile = new Path(alteredTable.getSd().getLocation().toString() + "/dataFile");
+ Assert.assertTrue("New directory should contain data", metaStore.isPathExists(dataFile));
+
+ // The following data should be changed, other data should be the same
+ newTable.getSd().setLocation(alteredTable.getSd().getLocation());
+ Assert.assertEquals("The table data should be the same", newTable, alteredTable);
+ }
+
+ @Test
+ public void testAlterTableExternalTable() throws Exception {
+ Table originalTable = externalTable;
+ String originalTableName = originalTable.getTableName();
+ String originalDatabase = originalTable.getDbName();
+
+ Table newTable = originalTable.deepCopy();
+ newTable.setTableName("new_external_table_for_test");
+ client.alter_table(originalDatabase, originalTableName, newTable);
+ List<String> tableNames = client.getTables(originalDatabase, originalTableName);
+ Assert.assertEquals("Original table should be removed", 0, tableNames.size());
+ Assert.assertTrue("Original table directory should be kept",
+ metaStore.isPathExists(new Path(originalTable.getSd().getLocation())));
+ Table alteredTable = client.getTable(newTable.getDbName(), newTable.getTableName());
+ Assert.assertEquals("New location should be the same", originalTable.getSd().getLocation(),
+ alteredTable.getSd().getLocation());
+ Path dataFile = new Path(alteredTable.getSd().getLocation().toString() + "/dataFile");
+ Assert.assertTrue("The location should contain data", metaStore.isPathExists(dataFile));
+
+ // The extra parameters will be added on server side, so check that the required ones are
+ // present
+ for(String key: newTable.getParameters().keySet()) {
+ Assert.assertEquals("parameters are present", newTable.getParameters().get(key),
+ alteredTable.getParameters().get(key));
+ }
+ // The parameters are checked manually, so do not check them
+ newTable.setParameters(alteredTable.getParameters());
+ Assert.assertEquals("The table data should be the same", newTable, alteredTable);
+ }
+
+ @Test
+ public void testAlterTableExternalTableChangeLocation() throws Exception {
+ Table originalTable = externalTable;
+
+ // Change the location, and see the results
+ Table newTable = originalTable.deepCopy();
+ newTable.getSd().setLocation(newTable.getSd().getLocation() + "_modified");
+ client.alter_table(originalTable.getDbName(), originalTable.getTableName(), newTable);
+ Table alteredTable = client.getTable(newTable.getDbName(), newTable.getTableName());
+ Assert.assertTrue("Original table directory should be kept",
+ metaStore.isPathExists(new Path(originalTable.getSd().getLocation())));
+ Assert.assertEquals("New location should be the new one", newTable.getSd().getLocation(),
+ alteredTable.getSd().getLocation());
+ Path dataFile = new Path(alteredTable.getSd().getLocation().toString() + "/dataFile");
+ Assert.assertFalse("The location should not contain data", metaStore.isPathExists(dataFile));
+
+ // The extra parameters will be added on server side, so check that the required ones are
+ // present
+ for(String key: newTable.getParameters().keySet()) {
+ Assert.assertEquals("parameters are present", newTable.getParameters().get(key),
+ alteredTable.getParameters().get(key));
+ }
+ // The parameters are checked manually, so do not check them
+ newTable.setParameters(alteredTable.getParameters());
+
+ // The following data should be changed, other data should be the same
+ newTable.getSd().setLocation(alteredTable.getSd().getLocation());
+ Assert.assertEquals("The table data should be the same", newTable, alteredTable);
+ }
+
+ @Test
+ public void testAlterTableChangeCols() throws Exception {
+ Table originalTable = partitionedTable;
+
+ Table newTable = originalTable.deepCopy();
+
+ List<FieldSchema> cols = newTable.getSd().getCols();
+ // Change a column
+ cols.get(0).setName("modified_col");
+ // Remove a column
+ cols.remove(1);
+ // Add a new column
+ cols.add(new FieldSchema("new_col", "int", null));
+ // Store the changes
+ client.alter_table(originalTable.getDbName(), originalTable.getTableName(), newTable);
+ Table alteredTable = client.getTable(newTable.getDbName(), newTable.getTableName());
+ Assert.assertTrue("Original table directory should be kept",
+ metaStore.isPathExists(new Path(originalTable.getSd().getLocation())));
+
+ // The following data might be changed
+ alteredTable.setParameters(newTable.getParameters());
+ Assert.assertEquals("The table data should be the same", newTable, alteredTable);
+
+ // Modify partition column type, and comment
+ newTable.getPartitionKeys().get(0).setType("string");
+ newTable.getPartitionKeys().get(0).setComment("changed comment");
+
+ client.alter_table(originalTable.getDbName(), originalTable.getTableName(), newTable);
+ alteredTable = client.getTable(newTable.getDbName(), newTable.getTableName());
+ // The following data might be changed
+ alteredTable.setParameters(newTable.getParameters());
+ Assert.assertEquals("The table data should be the same", newTable, alteredTable);
+ }
+
+ @Test
+ public void testAlterTableCascade() throws Exception {
+ Table originalTable = partitionedTable;
+
+ Table newTable = originalTable.deepCopy();
+ List<FieldSchema> cols = newTable.getSd().getCols();
+ cols.add(new FieldSchema("new_col_1", "int", null));
+
+ // Run without cascade
+ client.alter_table(originalTable.getDbName(), originalTable.getTableName(), newTable, false);
+ Table alteredTable = client.getTable(newTable.getDbName(), newTable.getTableName());
+ Assert.assertEquals("The table data should be changed", newTable, alteredTable);
+
+ List<Partition> partitions =
+ client.listPartitions(originalTable.getDbName(), originalTable.getTableName(), (short)-1);
+ for(Partition partition : partitions) {
+ Assert.assertEquals("Partition columns should not be changed", 2,
+ partition.getSd().getCols().size());
+ }
+
+ // Run with cascade
+ cols.add(new FieldSchema("new_col_2", "int", null));
+ client.alter_table(originalTable.getDbName(), originalTable.getTableName(), newTable, true);
+ alteredTable = client.getTable(newTable.getDbName(), newTable.getTableName());
+ Assert.assertEquals("The table data should be changed", newTable, alteredTable);
+
+ partitions =
+ client.listPartitions(originalTable.getDbName(), originalTable.getTableName(), (short)-1);
+ for(Partition partition : partitions) {
+ Assert.assertEquals("Partition columns should be changed", 4,
+ partition.getSd().getCols().size());
+ }
+
+ // Run using environment context with cascade
+ cols.add(new FieldSchema("new_col_3", "int", null));
+ EnvironmentContext context = new EnvironmentContext();
+ context.putToProperties(StatsSetupConst.CASCADE, "true");
+ client.alter_table_with_environmentContext(originalTable.getDbName(),
+ originalTable.getTableName(), newTable, context);
+ alteredTable = client.getTable(newTable.getDbName(), newTable.getTableName());
+ Assert.assertEquals("The table data should be changed", newTable, alteredTable);
+
+ partitions =
+ client.listPartitions(originalTable.getDbName(), originalTable.getTableName(), (short)-1);
+ for(Partition partition : partitions) {
+ Assert.assertEquals("Partition columns should be changed", 5,
+ partition.getSd().getCols().size());
+ }
+ }
+
+ @Test(expected = MetaException.class)
+ public void testAlterTableNullDatabaseInNew() throws Exception {
+ Table originalTable = testTables[0];
+ Table newTable = originalTable.deepCopy();
+ newTable.setDbName(null);
+
+ client.alter_table(originalTable.getDbName(), originalTable.getTableName(), newTable);
+ }
+
+ @Test(expected = MetaException.class)
+ public void testAlterTableNullTableNameInNew() throws Exception {
+ Table originalTable = testTables[0];
+ Table newTable = originalTable.deepCopy();
+ newTable.setTableName(null);
+
+ client.alter_table(originalTable.getDbName(), originalTable.getTableName(), newTable);
+ }
+
+ @Test(expected = InvalidOperationException.class)
+ public void testAlterTableInvalidTableNameInNew() throws Exception {
+ Table originalTable = testTables[0];
+ Table newTable = originalTable.deepCopy();
+ newTable.setTableName("test_table;");
+ client.alter_table(originalTable.getDbName(), originalTable.getTableName(), newTable);
+ }
+
+ @Test(expected = InvalidOperationException.class)
+ public void testAlterTableEmptyTableNameInNew() throws Exception {
+ Table originalTable = testTables[0];
+ Table newTable = originalTable.deepCopy();
+ newTable.setTableName("");
+
+ client.alter_table(originalTable.getDbName(), originalTable.getTableName(), newTable);
+ }
+
+ @Test(expected = MetaException.class)
+ public void testAlterTableNullStorageDescriptorInNew() throws Exception {
+ Table originalTable = testTables[0];
+ Table newTable = originalTable.deepCopy();
+ newTable.setSd(null);
+
+ client.alter_table(originalTable.getDbName(), originalTable.getTableName(), newTable);
+ }
+
+ @Test(expected = MetaException.class)
+ public void testAlterTableNullDatabase() throws Exception {
+ Table originalTable = testTables[0];
+ Table newTable = originalTable.deepCopy();
+
+ client.alter_table(null, originalTable.getTableName(), newTable);
+ }
+
+ @Test(expected = MetaException.class)
+ public void testAlterTableNullTableName() throws Exception {
+ Table originalTable = testTables[0];
+ Table newTable = originalTable.deepCopy();
+
+ client.alter_table(originalTable.getDbName(), null, newTable);
+ }
+
+ @Test
+ public void testAlterTableNullNewTable() throws Exception {
+ Table originalTable = testTables[0];
+ try {
+ client.alter_table(originalTable.getDbName(), originalTable.getTableName(), null);
+ // TODO: Should be checked on server side. On Embedded metastore it throws
+ // NullPointerException, on Remote metastore it throws TTransportException
+ Assert.fail("Expected a NullPointerException or TTransportException to be thrown");
+ } catch (NullPointerException exception) {
+ // Expected exception - Embedded MetaStore
+ } catch (TTransportException exception) {
+ // Expected exception - Remote MetaStore
+ }
+ }
+
+ @Test(expected = MetaException.class)
+ public void testAlterTableInvalidStorageDescriptorNullCols() throws Exception {
+ Table originalTable = testTables[0];
+ Table newTable = originalTable.deepCopy();
+ newTable.getSd().setCols(null);
+
+ client.alter_table(originalTable.getDbName(), originalTable.getTableName(), newTable);
+ }
+
+ @Test(expected = MetaException.class)
+ public void testAlterTableInvalidStorageDescriptorNullSerdeInfo() throws Exception {
+ Table originalTable = testTables[0];
+ Table newTable = originalTable.deepCopy();
+ newTable.getSd().setSerdeInfo(null);
+
+ client.alter_table(originalTable.getDbName(), originalTable.getTableName(), newTable);
+ }
+
+ @Test(expected = MetaException.class)
+ public void testAlterTableInvalidStorageDescriptorNullColumnType() throws Exception {
+ Table originalTable = testTables[0];
+ Table newTable = originalTable.deepCopy();
+ newTable.getSd().getCols().get(0).setType(null);
+
+ client.alter_table(originalTable.getDbName(), originalTable.getTableName(), newTable);
+ }
+
+ @Test(expected = MetaException.class)
+ public void testAlterTableInvalidStorageDescriptorNullLocation() throws Exception {
+ Table originalTable = testTables[0];
+ Table newTable = originalTable.deepCopy();
+ newTable.getSd().setLocation(null);
+
+ client.alter_table(originalTable.getDbName(), originalTable.getTableName(), newTable);
+ }
+
+ @Test(expected = InvalidOperationException.class)
+ public void testAlterTableInvalidStorageDescriptorInvalidColumnType() throws Exception {
+ Table originalTable = testTables[0];
+ Table newTable = originalTable.deepCopy();
+ newTable.getSd().getCols().get(0).setType("xyz");
+
+ client.alter_table(originalTable.getDbName(), originalTable.getTableName(), newTable);
+ }
+
+ @Test(expected = InvalidOperationException.class)
+ public void testAlterTableInvalidStorageDescriptorAddPartitionColumns() throws Exception {
+ Table originalTable = testTables[0];
+ Table newTable = originalTable.deepCopy();
+ newTable.addToPartitionKeys(new FieldSchema("new_part", "int", "comment"));
+
+ client.alter_table(originalTable.getDbName(), originalTable.getTableName(), newTable);
+ }
+
+ @Test(expected = InvalidOperationException.class)
+ public void testAlterTableInvalidStorageDescriptorAlterPartitionColumnName() throws Exception {
+ Table originalTable = partitionedTable;
+ Table newTable = originalTable.deepCopy();
+ newTable.getPartitionKeys().get(0).setName("altered_name");
+
+ client.alter_table(originalTable.getDbName(), originalTable.getTableName(), newTable);
+ }
+
+ @Test(expected = InvalidOperationException.class)
+ public void testAlterTableInvalidStorageDescriptorRemovePartitionColumn() throws Exception {
+ Table originalTable = partitionedTable;
+ Table newTable = originalTable.deepCopy();
+ newTable.getPartitionKeys().remove(0);
+ client.alter_table(originalTable.getDbName(), originalTable.getTableName(), newTable);
+ }
+
+ @Test(expected = InvalidOperationException.class)
+ public void testAlterTableNoSuchDatabase() throws Exception {
+ Table originalTable = testTables[2];
+ Table newTable = originalTable.deepCopy();
+
+ client.alter_table("no_such_database", originalTable.getTableName(), newTable);
+ }
+
+ @Test(expected = InvalidOperationException.class)
+ public void testAlterTableNoSuchTable() throws Exception {
+ Table originalTable = testTables[2];
+ Table newTable = originalTable.deepCopy();
+
+ client.alter_table(originalTable.getDbName(), "no_such_table_name", newTable);
+ }
+
+ @Test(expected = InvalidOperationException.class)
+ public void testAlterTableNoSuchTableInThisDatabase() throws Exception {
+ Table originalTable = testTables[2];
+ Table newTable = originalTable.deepCopy();
+
+ client.alter_table(OTHER_DATABASE, originalTable.getTableName(), newTable);
+ }
+
+ @Test
+ public void testAlterTableAlreadyExists() throws Exception {
+ Table originalTable = testTables[0];
+ Table newTable = originalTable.deepCopy();
+
+ newTable.setTableName(testTables[2].getTableName());
+ try {
+ // Already existing table
+ client.alter_table(originalTable.getDbName(), originalTable.getTableName(), newTable);
+ // TODO: Maybe throw AlreadyExistsException.
+ Assert.fail("Expected an InvalidOperationException to be thrown");
+ } catch (InvalidOperationException exception) {
+ // Expected exception
+ }
+ }
+
+ /**
+ * Creates a Table with all of the parameters set. The temporary table is available only on HS2
+ * server, so do not use it.
+ * @return The Table object
+ */
+ private Table getTableWithAllParametersSet() throws MetaException {
+ return new TableBuilder()
+ .setDbName(DEFAULT_DATABASE)
+ .setTableName("test_table_with_all_parameters_set")
+ .setCreateTime(100)
+ .setOwner("owner")
+ .setLastAccessTime(200)
+ .addPartCol("part_col", "int", "part col comment")
+ .addCol("test_col", "int", "test col comment")
+ .addCol("test_bucket_col", "int", "test bucket col comment")
+ .addCol("test_skewed_col", "int", "test skewed col comment")
+ .addCol("test_sort_col", "int", "test sort col comment")
+ .addBucketCol("test_bucket_col")
+ .addSkewedColName("test_skewed_col")
+ .addSortCol("test_sort_col", 1)
+ .setCompressed(true)
+ .setInputFormat("inputFormat")
+ .setInputFormat("outputFormat")
+ .setLocation(metaStore.getWarehouseRoot() + "/location")
+ .setNumBuckets(4)
+ .setRetention(30000)
+ .setRewriteEnabled(true)
+ .setType("VIEW")
+ .setViewExpandedText("viewExplainedText")
+ .setViewOriginalText("viewOriginalText")
+ .setSerdeLib("serdelib")
+ .setSerdeName("serdename")
+ .setStoredAsSubDirectories(true)
+ .addSerdeParam("serdeParam", "serdeParamValue")
+ .addTableParam("tableParam", "tableParamValue")
+ .addStorageDescriptorParam("sdParam", "sdParamValue")
+ .build();
+ }
+}