@Test
  public void testCreateTable() throws Exception {
    try {
      resetHMSClient();

      final String dbName = "dbcreate";
      String tblName = "test_create_table_ext";
      TableType type = TableType.EXTERNAL_TABLE;
      StringBuilder table_params = new StringBuilder();
      table_params.append("key1=val1");
      table_params.append(";");
      table_params.append("EXTERNAL=TRUE");
      Map<String, Object> tProps = new HashMap<>();
      tProps.put("DBNAME", dbName);
      tProps.put("TBLNAME", tblName);
      tProps.put("TBLTYPE", type);
      tProps.put("PROPERTIES", table_params.toString());

      Table table = createTableWithCapabilities(tProps);

      // retrieve the table
      Table tbl2 = client.getTable(dbName, tblName);
      assertEquals("Table type expected to be EXTERNAL", "EXTERNAL_TABLE", tbl2.getTableType());

      tblName = "test_create_table_mgd_wc";
      type = TableType.MANAGED_TABLE;
      tProps.put("TBLNAME", tblName);
      tProps.put("TBLTYPE", TableType.MANAGED_TABLE);
      table_params = new StringBuilder();
      table_params.append("key1=val1");
      table_params.append(";");
      table_params.append("transactional_properties=default");
      tProps.put("PROPERTIES", table_params.toString());

      List<String> capabilities = new ArrayList<>();
      capabilities.add("HIVEFULLACIDWRITE");
      setHMSClient("TestCreateTableMGD#1", (String[])(capabilities.toArray(new String[0])));

      table = createTableWithCapabilities(tProps);

      // retrieve the table
      tbl2 = client.getTable(dbName, tblName);
      assertEquals("Table type expected to be converted to EXTERNAL", "EXTERNAL_TABLE", tbl2.getTableType());
      assertNotNull("external.table.purge is expected to be non-null", tbl2.getParameters().get("external.table.purge"));
      assertTrue("external.table.purge is expected to be true",
          tbl2.getParameters().get("external.table.purge").equalsIgnoreCase("TRUE"));
      assertTrue("Table params expected to contain original properties", tbl2.getParameters().get("key1").equals("val1"));

      resetHMSClient();

      capabilities = new ArrayList<>();
      capabilities.add("HIVEMANAGEDINSERTWRITE");
      setHMSClient("TestCreateTableMGD#2", (String[])(capabilities.toArray(new String[0])));

      table = createTableWithCapabilities(tProps);

      // retrieve the table
      tbl2 = client.getTable(dbName, tblName);
      assertEquals("Table type expected to be converted to EXTERNAL", "EXTERNAL_TABLE", tbl2.getTableType());
      assertNotNull("external.table.purge is expected to be non-null", tbl2.getParameters().get("external.table.purge"));
      assertTrue("external.table.purge is expected to be true",
          tbl2.getParameters().get("external.table.purge").equalsIgnoreCase("TRUE"));
      assertTrue("Table params expected to contain original properties", tbl2.getParameters().get("key1").equals("val1"));

      resetHMSClient();

      // Test for FULL ACID tables
      tblName = "test_create_table_acid_mgd_woc";
      type = TableType.MANAGED_TABLE;
      tProps.put("TBLNAME", tblName);
      tProps.put("TBLTYPE", type);
      table_params = new StringBuilder();
      table_params.append("key1=val1");
      table_params.append(";");
      table_params.append("transactional=true");
      tProps.put("PROPERTIES", table_params.toString());

      try {
        table = createTableWithCapabilities(tProps);
        fail("CreateTable expected to fail, but passed for " + tblName);
      } catch (MetaException me) {
        LOG.info("Create table expected to fail as ACID table cannot be created without possessing capabilities");
      }

      capabilities = new ArrayList<>();
      capabilities.add("CONNECTORWRITE");
      setHMSClient("TestCreateTableACID#1", (String[])(capabilities.toArray(new String[0])));

      try {
        table = createTableWithCapabilities(tProps);
        fail("Create table expected to fail but has succeeded.");
      } catch (MetaException me) {
        LOG.info("CreateTable expected to fail and has failed for " + tblName);
      }
      resetHMSClient();

      capabilities = new ArrayList<>();
      capabilities.add("HIVEFULLACIDWRITE");
      setHMSClient("TestCreateTableACID#2", (String[])(capabilities.toArray(new String[0])));

      try {
        table = createTableWithCapabilities(tProps);
        LOG.info("Create table expected to succeed and has succeeded.");

        // retrieve the table
        tbl2 = client.getTable(dbName, tblName);
        assertEquals("TableType expected to be MANAGED_TABLE", TableType.MANAGED_TABLE.name(), tbl2.getTableType());
        assertTrue("Table params expected to contain ACID properties",
            tbl2.getParameters().get("transactional").equals("true"));
        assertTrue("Table params not expected to contain INSERT ACID properties",
            ((tbl2.getParameters().get("transactional_properties") == null) ||
                !(tbl2.getParameters().get("transactional_properties").equalsIgnoreCase("insert_only"))));
      } catch (MetaException me) {
        fail("CreateTable expected to succeed, but failed for " + tblName);
      }
      resetHMSClient();

      tblName = "test_create_table_acid_mgd_wc";
      tProps.put("TBLNAME", tblName);
      table_params = new StringBuilder();
      table_params.append("key1=val1");
      table_params.append(";");
      table_params.append("transactional=true");
      table_params.append(";");
      table_params.append(CAPABILITIES_KEY).append("=").append("HIVEFULLACIDREAD,HIVEFULLACIDWRITE,HIVECACHEINVALIDATE,")
          .append("HIVEMANAGEDSTATS,CONNECTORREAD,CONNECTORWRITE");
      tProps.put("PROPERTIES", table_params.toString());

      try {
        table = createTableWithCapabilities(tProps);
        fail("CreateTable expected to fail, but passed for " + tblName);
      } catch (MetaException me) {
        LOG.info("Create table expected to fail as ACID table cannot be created without possessing capabilities");
      }

      tblName = "test_create_table_acid_mgd_wcw";
      tProps.put("TBLNAME", tblName);
      capabilities = new ArrayList<>();
      capabilities.add("CONNECTORWRITE");
      setHMSClient("TestCreateTableACID#3", (String[])(capabilities.toArray(new String[0])));

      try {
        table = createTableWithCapabilities(tProps);
        fail("Create table expected to fail but has succeeded.");
      } catch (MetaException me) {
        LOG.info("CreateTable expected to fail and has failed for " + tblName);
      }
      resetHMSClient();

      tblName = "test_create_table_acid_mgd_whfaw";
      table_params = new StringBuilder();
      table_params.append("key1=val1");
      table_params.append(";");
      table_params.append("transactional=true");
      table_params.append(";");
      table_params.append(CAPABILITIES_KEY).append("=").append("HIVEFULLACIDREAD,HIVEFULLACIDWRITE,HIVECACHEINVALIDATE,")
          .append("HIVEMANAGEDSTATS,CONNECTORREAD,CONNECTORWRITE");
      tProps.put("TBLNAME", tblName);
      capabilities = new ArrayList<>();
      capabilities.add("HIVEFULLACIDWRITE");
      setHMSClient("TestCreateTableACID#4", (String[])(capabilities.toArray(new String[0])));

      try {
        table = createTableWithCapabilities(tProps);
        LOG.info("Create table expected to succeed and has succeeded.");

        // retrieve the table
        tbl2 = client.getTable(dbName, tblName);
        assertEquals("TableType expected to be MANAGED_TABLE", TableType.MANAGED_TABLE.name(), tbl2.getTableType());
        assertTrue("Table params expected to contain ACID properties",
            tbl2.getParameters().get("transactional").equals("true"));
        assertTrue("Table params not expected to contain INSERT ACID properties",
            ((tbl2.getParameters().get("transactional_properties") == null) ||
                !(tbl2.getParameters().get("transactional_properties").equalsIgnoreCase("insert_only"))));
        assertEquals("Expected access of type READONLY", ACCESSTYPE_READWRITE, tbl2.getAccessType());
        assertNull("Expected null required write capabilities", tbl2.getRequiredWriteCapabilities());
      } catch (MetaException me) {
        fail("CreateTable expected to succeed, but failed for " + tblName);
      }
      resetHMSClient();

      tblName = "test_create_table_insert_mgd_woc";
      type = TableType.MANAGED_TABLE;
      tProps.put("TBLNAME", tblName);
      tProps.put("TBLTYPE", type);
      table_params = new StringBuilder();
      table_params.append("key1=val1");
      table_params.append(";");
      table_params.append("transactional=true");
      table_params.append(";");
      table_params.append("transactional_properties=insert_only");
      tProps.put("PROPERTIES", table_params.toString());

      try {
        table = createTableWithCapabilities(tProps);
        fail("CreateTable expected to fail, but passed for " + tblName);
      } catch (MetaException me) {
        LOG.info("Create table expected to fail as ACID table cannot be created without possessing capabilities");
      }

      capabilities = new ArrayList<>();
      capabilities.add("CONNECTORWRITE");
      setHMSClient("TestCreateTableMGD#1", (String[])(capabilities.toArray(new String[0])));

      try {
        table = createTableWithCapabilities(tProps);
        fail("Create table expected to fail but has succeeded.");
      } catch (MetaException me) {
        LOG.info("CreateTable expected to fail and has failed for " + tblName);
      }
      resetHMSClient();

      capabilities = new ArrayList<>();
      capabilities.add("HIVEMANAGEDINSERTWRITE");
      setHMSClient("TestCreateTableMGD#2", (String[])(capabilities.toArray(new String[0])));

      try {
        table = createTableWithCapabilities(tProps);
        LOG.info("Create table expected to succeed and has succeeded.");

        // retrieve the table
        tbl2 = client.getTable(dbName, tblName);
        assertEquals("TableType expected to be MANAGED_TABLE", TableType.MANAGED_TABLE.name(), tbl2.getTableType());
        assertTrue("Table params expected to contain ACID properties",
            tbl2.getParameters().get("transactional").equals("true"));
        assertTrue("Table params expected to contain ACID properties",
            tbl2.getParameters().get("transactional_properties").equals("insert_only"));
      } catch (MetaException me) {
        fail("CreateTable expected to succeed, but failed for " + tblName);
      }
      resetHMSClient();

      // table has capabilities
      tblName = "test_view_wc";
      table_params = new StringBuilder();
      table_params.append(CAPABILITIES_KEY).append("=").append("HIVESQL");
      tProps.put("TBLNAME", tblName);
      tProps.put("PROPERTIES", table_params.toString());

      try {
        table = createTableWithCapabilities(tProps);
        LOG.info("Create view is expected to succeed and has succeeded"); // no transformation for views
      } catch (Exception e) {
        LOG.info("Create view expected to succeed but has failed.");
        fail("Create view expected to succeed but has failed. <" + e.getMessage() +">");
      }
      resetHMSClient();
    } catch (Exception e) {
      System.err.println(org.apache.hadoop.util.StringUtils.stringifyException(e));
      System.err.println("testCreateTable() failed.");
      fail("testCreateTable failed:" + e.getMessage());
    } finally {
      resetHMSClient();
    }
  }
EXTERNAL_TABLE
  1) Old table (name in upper case) with no capabilities
  2) Old table with no capabilities
  3a) New table with capabilities with no client requirements
  3b) New table with capabilities with no matching client requirements
  3c) New table with capabilities with partial match requirements
  3d) New table with capabilities with full match requirements
itests/hive-unit/src/test/java/org/apache/hadoop/hive/metastore/TestHiveMetastoreTransformer.java