Merge branch '1.7' into 1.8
Project: http://git-wip-us.apache.org/repos/asf/accumulo/repo Commit: http://git-wip-us.apache.org/repos/asf/accumulo/commit/6aa47cf9 Tree: http://git-wip-us.apache.org/repos/asf/accumulo/tree/6aa47cf9 Diff: http://git-wip-us.apache.org/repos/asf/accumulo/diff/6aa47cf9 Branch: refs/heads/1.8 Commit: 6aa47cf9eb48f9eff36c980db2ec6a0361ce6c8c Parents: 512a25f 1d5cd11 Author: Josh Elser <els...@apache.org> Authored: Sun Jul 10 22:19:34 2016 -0400 Committer: Josh Elser <els...@apache.org> Committed: Sun Jul 10 22:19:34 2016 -0400 ---------------------------------------------------------------------- .../accumulo/harness/SharedMiniClusterBase.java | 28 ++++++++++++++++---- .../test/ArbitraryTablePropertiesIT.java | 12 +++++++++ .../test/CreateTableWithNewTableConfigIT.java | 12 +++++++++ .../org/apache/accumulo/test/ShellServerIT.java | 17 ++++++++++-- .../accumulo/test/SplitCancelsMajCIT.java | 12 +++++++++ .../accumulo/test/functional/CleanUpIT.java | 12 +++++++++ .../functional/DeletedTablesDontFlushIT.java | 12 +++++++++ .../functional/TabletStateChangeIteratorIT.java | 12 +++++++++ .../accumulo/test/proxy/SimpleProxyBase.java | 2 ++ .../accumulo/test/proxy/TBinaryProxyIT.java | 2 ++ .../accumulo/test/proxy/TCompactProxyIT.java | 2 ++ .../test/proxy/TJsonProtocolProxyIT.java | 2 ++ .../accumulo/test/proxy/TTupleProxyIT.java | 2 ++ .../test/replication/StatusCombinerMacIT.java | 12 +++++++++ 14 files changed, 132 insertions(+), 7 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/accumulo/blob/6aa47cf9/test/src/main/java/org/apache/accumulo/harness/SharedMiniClusterBase.java ---------------------------------------------------------------------- diff --cc test/src/main/java/org/apache/accumulo/harness/SharedMiniClusterBase.java index cb0fa7b,0000000..544b5de mode 100644,000000..100644 --- a/test/src/main/java/org/apache/accumulo/harness/SharedMiniClusterBase.java +++ b/test/src/main/java/org/apache/accumulo/harness/SharedMiniClusterBase.java @@@ -1,186 -1,0 +1,204 @@@ +/* + * 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.accumulo.harness; + +import static org.junit.Assert.assertTrue; + +import java.io.File; +import java.io.IOException; +import java.util.Random; + +import org.apache.accumulo.cluster.ClusterUser; +import org.apache.accumulo.cluster.ClusterUsers; +import org.apache.accumulo.core.client.Connector; +import org.apache.accumulo.core.client.security.tokens.AuthenticationToken; +import org.apache.accumulo.core.client.security.tokens.KerberosToken; +import org.apache.accumulo.core.client.security.tokens.PasswordToken; +import org.apache.accumulo.core.conf.Property; +import org.apache.accumulo.core.security.TablePermission; +import org.apache.accumulo.minicluster.impl.MiniAccumuloClusterImpl; +import org.apache.hadoop.conf.Configuration; +import org.apache.hadoop.fs.CommonConfigurationKeysPublic; +import org.apache.hadoop.security.UserGroupInformation; - import org.junit.AfterClass; - import org.junit.BeforeClass; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Convenience class which starts a single MAC instance for a test to leverage. + * + * There isn't a good way to build this off of the {@link AccumuloClusterHarness} (as would be the logical place) because we need to start the + * MiniAccumuloCluster in a static BeforeClass-annotated method. Because it is static and invoked before any other BeforeClass methods in the implementation, + * the actual test classes can't expose any information to tell the base class that it is to perform the one-MAC-per-class semantics. ++ * ++ * Implementations of this class must be sure to invoke {@link #startMiniCluster()} or {@link #startMiniClusterWithConfig(MiniClusterConfigurationCallback)} in ++ * a method annotated with the {@link org.junit.BeforeClass} JUnit annotation and {@link #stopMiniCluster()} in a method annotated with the ++ * {@link org.junit.AfterClass} JUnit annotation. + */ +public abstract class SharedMiniClusterBase extends AccumuloITBase implements ClusterUsers { + private static final Logger log = LoggerFactory.getLogger(SharedMiniClusterBase.class); + public static final String TRUE = Boolean.toString(true); + + private static String principal = "root"; + private static String rootPassword; + private static AuthenticationToken token; + private static MiniAccumuloClusterImpl cluster; + private static TestingKdc krb; + - @BeforeClass ++ /** ++ * Starts a MiniAccumuloCluster instance with the default configuration. ++ */ + public static void startMiniCluster() throws Exception { ++ startMiniClusterWithConfig(MiniClusterConfigurationCallback.NO_CALLBACK); ++ } ++ ++ /** ++ * Starts a MiniAccumuloCluster instance with the default configuration but also provides the caller the opportunity to update the configuration before the ++ * MiniAccumuloCluster is started. ++ * ++ * @param miniClusterCallback ++ * A callback to configure the minicluster before it is started. ++ */ ++ public static void startMiniClusterWithConfig(MiniClusterConfigurationCallback miniClusterCallback) throws Exception { + File baseDir = new File(System.getProperty("user.dir") + "/target/mini-tests"); + assertTrue(baseDir.mkdirs() || baseDir.isDirectory()); + + // Make a shared MAC instance instead of spinning up one per test method + MiniClusterHarness harness = new MiniClusterHarness(); + + if (TRUE.equals(System.getProperty(MiniClusterHarness.USE_KERBEROS_FOR_IT_OPTION))) { + krb = new TestingKdc(); + krb.start(); + // Enabled krb auth + Configuration conf = new Configuration(false); + conf.set(CommonConfigurationKeysPublic.HADOOP_SECURITY_AUTHENTICATION, "kerberos"); + UserGroupInformation.setConfiguration(conf); + // Login as the client + ClusterUser rootUser = krb.getRootUser(); + // Get the krb token + UserGroupInformation.loginUserFromKeytab(rootUser.getPrincipal(), rootUser.getKeytab().getAbsolutePath()); + token = new KerberosToken(); + } else { + rootPassword = "rootPasswordShared1"; + token = new PasswordToken(rootPassword); + } + - cluster = harness.create(SharedMiniClusterBase.class.getName(), System.currentTimeMillis() + "_" + new Random().nextInt(Short.MAX_VALUE), token, krb); ++ cluster = harness.create(SharedMiniClusterBase.class.getName(), System.currentTimeMillis() + "_" + new Random().nextInt(Short.MAX_VALUE), token, ++ miniClusterCallback, krb); + cluster.start(); + + if (null != krb) { + final String traceTable = Property.TRACE_TABLE.getDefaultValue(); + final ClusterUser systemUser = krb.getAccumuloServerUser(), rootUser = krb.getRootUser(); + // Login as the trace user + // Open a connector as the system user (ensures the user will exist for us to assign permissions to) + UserGroupInformation.loginUserFromKeytab(systemUser.getPrincipal(), systemUser.getKeytab().getAbsolutePath()); + Connector conn = cluster.getConnector(systemUser.getPrincipal(), new KerberosToken()); + + // Then, log back in as the "root" user and do the grant + UserGroupInformation.loginUserFromKeytab(rootUser.getPrincipal(), rootUser.getKeytab().getAbsolutePath()); + conn = cluster.getConnector(principal, token); + + // Create the trace table + conn.tableOperations().create(traceTable); + + // Trace user (which is the same kerberos principal as the system user, but using a normal KerberosToken) needs + // to have the ability to read, write and alter the trace table + conn.securityOperations().grantTablePermission(systemUser.getPrincipal(), traceTable, TablePermission.READ); + conn.securityOperations().grantTablePermission(systemUser.getPrincipal(), traceTable, TablePermission.WRITE); + conn.securityOperations().grantTablePermission(systemUser.getPrincipal(), traceTable, TablePermission.ALTER_TABLE); + } + } + - @AfterClass ++ /** ++ * Stops the MiniAccumuloCluster and related services if they are running. ++ */ + public static void stopMiniCluster() throws Exception { + if (null != cluster) { + try { + cluster.stop(); + } catch (Exception e) { + log.error("Failed to stop minicluster", e); + } + } + if (null != krb) { + try { + krb.stop(); + } catch (Exception e) { + log.error("Failed to stop KDC", e); + } + } + } + + public static String getRootPassword() { + return rootPassword; + } + + public static AuthenticationToken getToken() { + if (token instanceof KerberosToken) { + try { + UserGroupInformation.loginUserFromKeytab(getPrincipal(), krb.getRootUser().getKeytab().getAbsolutePath()); + } catch (IOException e) { + throw new RuntimeException("Failed to login", e); + } + } + return token; + } + + public static String getPrincipal() { + return principal; + } + + public static MiniAccumuloClusterImpl getCluster() { + return cluster; + } + + public static File getMiniClusterDir() { + return cluster.getConfig().getDir(); + } + + public static Connector getConnector() { + try { + return getCluster().getConnector(principal, getToken()); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + public static TestingKdc getKdc() { + return krb; + } + + @Override + public ClusterUser getAdminUser() { + if (null == krb) { + return new ClusterUser(getPrincipal(), getRootPassword()); + } else { + return krb.getRootUser(); + } + } + + @Override + public ClusterUser getUser(int offset) { + if (null == krb) { + String user = SharedMiniClusterBase.class.getName() + "_" + testName.getMethodName() + "_" + offset; + // Password is the username + return new ClusterUser(user, user); + } else { + return krb.getClientPrincipal(offset); + } + } +} http://git-wip-us.apache.org/repos/asf/accumulo/blob/6aa47cf9/test/src/main/java/org/apache/accumulo/test/ArbitraryTablePropertiesIT.java ---------------------------------------------------------------------- diff --cc test/src/main/java/org/apache/accumulo/test/ArbitraryTablePropertiesIT.java index 44124e4,0000000..0c38464 mode 100644,000000..100644 --- a/test/src/main/java/org/apache/accumulo/test/ArbitraryTablePropertiesIT.java +++ b/test/src/main/java/org/apache/accumulo/test/ArbitraryTablePropertiesIT.java @@@ -1,198 -1,0 +1,210 @@@ +/* + * 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.accumulo.test; + +import java.util.Map.Entry; + +import org.apache.accumulo.cluster.ClusterUser; +import org.apache.accumulo.core.client.AccumuloSecurityException; +import org.apache.accumulo.core.client.Connector; +import org.apache.accumulo.core.client.security.tokens.AuthenticationToken; +import org.apache.accumulo.core.client.security.tokens.PasswordToken; +import org.apache.accumulo.core.conf.Property; +import org.apache.accumulo.core.security.TablePermission; +import org.apache.accumulo.harness.SharedMiniClusterBase; ++import org.junit.AfterClass; +import org.junit.Assert; ++import org.junit.BeforeClass; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class ArbitraryTablePropertiesIT extends SharedMiniClusterBase { + private static final Logger log = LoggerFactory.getLogger(ArbitraryTablePropertiesIT.class); + + @Override + protected int defaultTimeoutSeconds() { + return 30; + } + ++ @BeforeClass ++ public static void setup() throws Exception { ++ SharedMiniClusterBase.startMiniCluster(); ++ } ++ ++ @AfterClass ++ public static void teardown() throws Exception { ++ SharedMiniClusterBase.stopMiniCluster(); ++ } ++ + // Test set, get, and remove arbitrary table properties on the root account + @Test + public void setGetRemoveTablePropertyRoot() throws Exception { + log.debug("Starting setGetRemoveTablePropertyRoot test ------------------------"); + + // make a table + final String tableName = getUniqueNames(1)[0]; + final Connector conn = getConnector(); + conn.tableOperations().create(tableName); + + // Set variables for the property name to use and the initial value + String propertyName = "table.custom.description"; + String description1 = "Description"; + + // Make sure the property name is valid + Assert.assertTrue(Property.isValidPropertyKey(propertyName)); + // Set the property to the desired value + conn.tableOperations().setProperty(tableName, propertyName, description1); + + // Loop through properties to make sure the new property is added to the list + int count = 0; + for (Entry<String,String> property : conn.tableOperations().getProperties(tableName)) { + if (property.getKey().equals(propertyName) && property.getValue().equals(description1)) + count++; + } + Assert.assertEquals(count, 1); + + // Set the property as something different + String description2 = "set second"; + conn.tableOperations().setProperty(tableName, propertyName, description2); + + // / Loop through properties to make sure the new property is added to the list + count = 0; + for (Entry<String,String> property : conn.tableOperations().getProperties(tableName)) { + if (property.getKey().equals(propertyName) && property.getValue().equals(description2)) + count++; + } + Assert.assertEquals(count, 1); + + // Remove the property and make sure there is no longer a value associated with it + conn.tableOperations().removeProperty(tableName, propertyName); + + // / Loop through properties to make sure the new property is added to the list + count = 0; + for (Entry<String,String> property : conn.tableOperations().getProperties(tableName)) { + if (property.getKey().equals(propertyName)) + count++; + } + Assert.assertEquals(count, 0); + } + + // Tests set, get, and remove of user added arbitrary properties using a non-root account with permissions to alter tables + @Test + public void userSetGetRemoveTablePropertyWithPermission() throws Exception { + log.debug("Starting userSetGetRemoveTablePropertyWithPermission test ------------------------"); + + // Make a test username and password + ClusterUser user = getUser(0); + String testUser = user.getPrincipal(); + AuthenticationToken testToken = user.getToken(); + + // Create a root user and create the table + // Create a test user and grant that user permission to alter the table + final String tableName = getUniqueNames(1)[0]; + final Connector c = getConnector(); + c.securityOperations().createLocalUser(testUser, (testToken instanceof PasswordToken ? (PasswordToken) testToken : null)); + c.tableOperations().create(tableName); + c.securityOperations().grantTablePermission(testUser, tableName, TablePermission.ALTER_TABLE); + + // Set variables for the property name to use and the initial value + String propertyName = "table.custom.description"; + String description1 = "Description"; + + // Make sure the property name is valid + Assert.assertTrue(Property.isValidPropertyKey(propertyName)); + + // Getting a fresh token will ensure we're logged in as this user (if necessary) + Connector testConn = c.getInstance().getConnector(testUser, user.getToken()); + // Set the property to the desired value + testConn.tableOperations().setProperty(tableName, propertyName, description1); + + // Loop through properties to make sure the new property is added to the list + int count = 0; + for (Entry<String,String> property : testConn.tableOperations().getProperties(tableName)) { + if (property.getKey().equals(propertyName) && property.getValue().equals(description1)) + count++; + } + Assert.assertEquals(count, 1); + + // Set the property as something different + String description2 = "set second"; + testConn.tableOperations().setProperty(tableName, propertyName, description2); + + // / Loop through properties to make sure the new property is added to the list + count = 0; + for (Entry<String,String> property : testConn.tableOperations().getProperties(tableName)) { + if (property.getKey().equals(propertyName) && property.getValue().equals(description2)) + count++; + } + Assert.assertEquals(count, 1); + + // Remove the property and make sure there is no longer a value associated with it + testConn.tableOperations().removeProperty(tableName, propertyName); + + // / Loop through properties to make sure the new property is added to the list + count = 0; + for (Entry<String,String> property : testConn.tableOperations().getProperties(tableName)) { + if (property.getKey().equals(propertyName)) + count++; + } + Assert.assertEquals(count, 0); + + } + + // Tests set and get of user added arbitrary properties using a non-root account without permissions to alter tables + @Test + public void userSetGetTablePropertyWithoutPermission() throws Exception { + log.debug("Starting userSetGetTablePropertyWithoutPermission test ------------------------"); + + // Make a test username and password + ClusterUser user = getUser(1); + String testUser = user.getPrincipal(); + AuthenticationToken testToken = user.getToken(); + + // Create a root user and create the table + // Create a test user and grant that user permission to alter the table + final String tableName = getUniqueNames(1)[0]; + final Connector c = getConnector(); + c.securityOperations().createLocalUser(testUser, (testToken instanceof PasswordToken ? (PasswordToken) testToken : null)); + c.tableOperations().create(tableName); + + // Set variables for the property name to use and the initial value + String propertyName = "table.custom.description"; + String description1 = "Description"; + + // Make sure the property name is valid + Assert.assertTrue(Property.isValidPropertyKey(propertyName)); + + // Getting a fresh token will ensure we're logged in as this user (if necessary) + Connector testConn = c.getInstance().getConnector(testUser, user.getToken()); + + // Try to set the property to the desired value. + // If able to set it, the test fails, since permission was never granted + try { + testConn.tableOperations().setProperty(tableName, propertyName, description1); + Assert.fail("Was able to set property without permissions"); + } catch (AccumuloSecurityException e) {} + + // Loop through properties to make sure the new property is not added to the list + int count = 0; + for (Entry<String,String> property : testConn.tableOperations().getProperties(tableName)) { + if (property.getKey().equals(propertyName)) + count++; + } + Assert.assertEquals(count, 0); + } +} http://git-wip-us.apache.org/repos/asf/accumulo/blob/6aa47cf9/test/src/main/java/org/apache/accumulo/test/CreateTableWithNewTableConfigIT.java ---------------------------------------------------------------------- diff --cc test/src/main/java/org/apache/accumulo/test/CreateTableWithNewTableConfigIT.java index a78b583,0000000..7fd2dd1 mode 100644,000000..100644 --- a/test/src/main/java/org/apache/accumulo/test/CreateTableWithNewTableConfigIT.java +++ b/test/src/main/java/org/apache/accumulo/test/CreateTableWithNewTableConfigIT.java @@@ -1,193 -1,0 +1,205 @@@ +/* + * 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.accumulo.test; + +import java.util.HashMap; +import java.util.Map; +import java.util.Map.Entry; + +import org.apache.accumulo.core.client.AccumuloException; +import org.apache.accumulo.core.client.Connector; +import org.apache.accumulo.core.client.Scanner; +import org.apache.accumulo.core.client.TableNotFoundException; +import org.apache.accumulo.core.client.admin.NewTableConfiguration; +import org.apache.accumulo.core.client.admin.TimeType; +import org.apache.accumulo.core.conf.Property; +import org.apache.accumulo.core.data.Key; +import org.apache.accumulo.core.data.Value; +import org.apache.accumulo.core.metadata.MetadataTable; +import org.apache.accumulo.core.metadata.schema.MetadataSchema.TabletsSection.ServerColumnFamily; +import org.apache.accumulo.core.security.Authorizations; +import org.apache.accumulo.harness.SharedMiniClusterBase; ++import org.junit.AfterClass; +import org.junit.Assert; ++import org.junit.BeforeClass; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.common.collect.Iterators; + +/** + * + */ +public class CreateTableWithNewTableConfigIT extends SharedMiniClusterBase { + static private final Logger log = LoggerFactory.getLogger(CreateTableWithNewTableConfigIT.class); + + @Override + protected int defaultTimeoutSeconds() { + return 30; + } + ++ @BeforeClass ++ public static void setup() throws Exception { ++ SharedMiniClusterBase.startMiniCluster(); ++ } ++ ++ @AfterClass ++ public static void teardown() throws Exception { ++ SharedMiniClusterBase.stopMiniCluster(); ++ } ++ + public int numProperties(Connector connector, String tableName) throws AccumuloException, TableNotFoundException { + return Iterators.size(connector.tableOperations().getProperties(tableName).iterator()); + } + + public int compareProperties(Connector connector, String tableNameOrig, String tableName, String changedProp) throws AccumuloException, + TableNotFoundException { + boolean inNew = false; + int countOrig = 0; + for (Entry<String,String> orig : connector.tableOperations().getProperties(tableNameOrig)) { + countOrig++; + for (Entry<String,String> entry : connector.tableOperations().getProperties(tableName)) { + if (entry.equals(orig)) { + inNew = true; + break; + } else if (entry.getKey().equals(orig.getKey()) && !entry.getKey().equals(changedProp)) + Assert.fail("Property " + orig.getKey() + " has different value than deprecated method"); + } + if (!inNew) + Assert.fail("Original property missing after using the new create method"); + } + return countOrig; + } + + public boolean checkTimeType(Connector connector, String tableName, TimeType expectedTimeType) throws TableNotFoundException { + final Scanner scanner = connector.createScanner(MetadataTable.NAME, Authorizations.EMPTY); + String tableID = connector.tableOperations().tableIdMap().get(tableName) + "<"; + for (Entry<Key,Value> entry : scanner) { + Key k = entry.getKey(); + + if (k.getRow().toString().equals(tableID) && k.getColumnQualifier().toString().equals(ServerColumnFamily.TIME_COLUMN.getColumnQualifier().toString())) { + if (expectedTimeType == TimeType.MILLIS && entry.getValue().toString().charAt(0) == 'M') + return true; + if (expectedTimeType == TimeType.LOGICAL && entry.getValue().toString().charAt(0) == 'L') + return true; + } + } + return false; + } + + @SuppressWarnings("deprecation") + @Test + public void tableNameOnly() throws Exception { + log.info("Starting tableNameOnly"); + + // Create a table with the initial properties + Connector connector = getConnector(); + String tableName = getUniqueNames(2)[0]; + connector.tableOperations().create(tableName, new NewTableConfiguration()); + + String tableNameOrig = "original"; + connector.tableOperations().create(tableNameOrig, true); + + int countNew = numProperties(connector, tableName); + int countOrig = compareProperties(connector, tableNameOrig, tableName, null); + + Assert.assertEquals("Extra properties using the new create method", countOrig, countNew); + Assert.assertTrue("Wrong TimeType", checkTimeType(connector, tableName, TimeType.MILLIS)); + } + + @SuppressWarnings("deprecation") + @Test + public void tableNameAndLimitVersion() throws Exception { + log.info("Starting tableNameAndLimitVersion"); + + // Create a table with the initial properties + Connector connector = getConnector(); + String tableName = getUniqueNames(2)[0]; + boolean limitVersion = false; + connector.tableOperations().create(tableName, new NewTableConfiguration().withoutDefaultIterators()); + + String tableNameOrig = "originalWithLimitVersion"; + connector.tableOperations().create(tableNameOrig, limitVersion); + + int countNew = numProperties(connector, tableName); + int countOrig = compareProperties(connector, tableNameOrig, tableName, null); + + Assert.assertEquals("Extra properties using the new create method", countOrig, countNew); + Assert.assertTrue("Wrong TimeType", checkTimeType(connector, tableName, TimeType.MILLIS)); + } + + @SuppressWarnings("deprecation") + @Test + public void tableNameLimitVersionAndTimeType() throws Exception { + log.info("Starting tableNameLimitVersionAndTimeType"); + + // Create a table with the initial properties + Connector connector = getConnector(); + String tableName = getUniqueNames(2)[0]; + boolean limitVersion = false; + TimeType tt = TimeType.LOGICAL; + connector.tableOperations().create(tableName, new NewTableConfiguration().withoutDefaultIterators().setTimeType(tt)); + + String tableNameOrig = "originalWithLimitVersionAndTimeType"; + connector.tableOperations().create(tableNameOrig, limitVersion, tt); + + int countNew = numProperties(connector, tableName); + int countOrig = compareProperties(connector, tableNameOrig, tableName, null); + + Assert.assertEquals("Extra properties using the new create method", countOrig, countNew); + Assert.assertTrue("Wrong TimeType", checkTimeType(connector, tableName, tt)); + } + + @SuppressWarnings("deprecation") + @Test + public void addCustomPropAndChangeExisting() throws Exception { + log.info("Starting addCustomPropAndChangeExisting"); + + // Create and populate initial properties map for creating table 1 + Map<String,String> properties = new HashMap<>(); + String propertyName = Property.TABLE_SPLIT_THRESHOLD.getKey(); + String volume = "10K"; + properties.put(propertyName, volume); + + String propertyName2 = "table.custom.testProp"; + String volume2 = "Test property"; + properties.put(propertyName2, volume2); + + // Create a table with the initial properties + Connector connector = getConnector(); + String tableName = getUniqueNames(2)[0]; + connector.tableOperations().create(tableName, new NewTableConfiguration().setProperties(properties)); + + String tableNameOrig = "originalWithTableName"; + connector.tableOperations().create(tableNameOrig, true); + + int countNew = numProperties(connector, tableName); + int countOrig = compareProperties(connector, tableNameOrig, tableName, propertyName); + + for (Entry<String,String> entry : connector.tableOperations().getProperties(tableName)) { + if (entry.getKey().equals(Property.TABLE_SPLIT_THRESHOLD.getKey())) + Assert.assertTrue("TABLE_SPLIT_THRESHOLD has been changed", entry.getValue().equals("10K")); + if (entry.getKey().equals("table.custom.testProp")) + Assert.assertTrue("table.custom.testProp has been changed", entry.getValue().equals("Test property")); + } + + Assert.assertEquals("Extra properties using the new create method", countOrig + 1, countNew); + Assert.assertTrue("Wrong TimeType", checkTimeType(connector, tableName, TimeType.MILLIS)); + + } +}