http://git-wip-us.apache.org/repos/asf/sentry/blob/bfb354f2/sentry-tests/sentry-tests-hive-v2/src/test/java/org/apache/sentry/tests/e2e/dbprovider/TestDbPrivilegeCleanupOnDrop.java
----------------------------------------------------------------------
diff --git 
a/sentry-tests/sentry-tests-hive-v2/src/test/java/org/apache/sentry/tests/e2e/dbprovider/TestDbPrivilegeCleanupOnDrop.java
 
b/sentry-tests/sentry-tests-hive-v2/src/test/java/org/apache/sentry/tests/e2e/dbprovider/TestDbPrivilegeCleanupOnDrop.java
new file mode 100644
index 0000000..767bcbe
--- /dev/null
+++ 
b/sentry-tests/sentry-tests-hive-v2/src/test/java/org/apache/sentry/tests/e2e/dbprovider/TestDbPrivilegeCleanupOnDrop.java
@@ -0,0 +1,354 @@
+/**
+ * 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.sentry.tests.e2e.dbprovider;
+
+import static org.hamcrest.Matchers.is;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.assertTrue;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.sql.Connection;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.sentry.tests.e2e.hive.AbstractTestWithStaticConfiguration;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import com.google.common.collect.Lists;
+import com.google.common.io.Resources;
+
+public class TestDbPrivilegeCleanupOnDrop extends
+    AbstractTestWithStaticConfiguration {
+
+  private final static int SHOW_GRANT_TABLE_POSITION = 2;
+  private final static int SHOW_GRANT_DB_POSITION = 1;
+
+  private final String SINGLE_TYPE_DATA_FILE_NAME = "kv1.dat";
+
+  private final static String tableName1 = "tb_1";
+  private final static String tableName2 = "tb_2";
+  private final static String tableName3 = "tb_3";
+  private final static String tableName4 = "tb_4";
+  private final static String renameTag = "_new";
+
+  @BeforeClass
+  public static void setupTestStaticConfiguration() throws Exception {
+    useSentryService = true;
+    if (!setMetastoreListener) {
+      setMetastoreListener = true;
+    }
+    AbstractTestWithStaticConfiguration.setupTestStaticConfiguration();
+  }
+
+  @Override
+  @Before
+  public void setup() throws Exception {
+    super.setupAdmin();
+    super.setup();
+    // context = createContext();
+    File dataFile = new File(dataDir, SINGLE_TYPE_DATA_FILE_NAME);
+    FileOutputStream to = new FileOutputStream(dataFile);
+    Resources.copy(Resources.getResource(SINGLE_TYPE_DATA_FILE_NAME), to);
+    to.close();
+  }
+
+  @After
+  public void tearDown() throws Exception {
+    if (context != null) {
+      context.close();
+    }
+  }
+
+  /**
+   * drop table and verify that the no privileges are referring to it drop db
+   * and verify that the no privileges are referring to it drop db cascade
+   * verify that the no privileges are referring to db and tables under it
+   *
+   * @throws Exception
+   */
+  @Test
+  public void testDropObjects() throws Exception {
+    Connection connection = context.createConnection(ADMIN1);
+    Statement statement = context.createStatement(connection);
+
+    setupRoles(statement); // create required roles
+    setupDbObjects(statement); // create test DBs and Tables
+    setupPrivileges(statement); // setup privileges for USER1
+    dropDbObjects(statement); // drop objects
+    verifyPrivilegesDropped(statement); // verify privileges are removed
+
+    statement.close();
+    connection.close();
+  }
+
+  /**
+   * Return the remaining rows of the current resultSet
+   * Cautiously it will modify the cursor position of the resultSet
+   *
+   */
+  private void assertRemainingRows(ResultSet resultSet, int expected) throws 
SQLException{
+    int count = 0;
+    while(resultSet.next()) {
+      count++;
+    }
+    assertThat(count, is(expected));
+  }
+
+  /**
+   * drop table and verify that the no privileges are referring to it drop db
+   * and verify that the no privileges are referring to it drop db cascade
+   * verify that the no privileges are referring to db and tables under it
+   *
+   * @throws Exception
+   */
+  @Test
+  public void testReCreateObjects() throws Exception {
+    Connection connection = context.createConnection(ADMIN1);
+    Statement statement = context.createStatement(connection);
+    setupRoles(statement); // create required roles
+    setupDbObjects(statement); // create test DBs and Tables
+    setupPrivileges(statement); // setup privileges for USER1
+    dropDbObjects(statement); // drop DB and tables
+
+    setupDbObjects(statement); // recreate same DBs and tables
+    verifyPrivilegesDropped(statement); // verify the stale privileges removed
+  }
+
+  /**
+   * rename table and verify that the no privileges are referring to it old 
table
+   * verify that the same privileges are created for the new table name
+   *
+   * @throws Exception
+   */
+  @Test
+  public void testRenameTables() throws Exception {
+    Connection connection = context.createConnection(ADMIN1);
+    Statement statement = context.createStatement(connection);
+
+    setupRoles(statement); // create required roles
+    setupDbObjects(statement); // create test DBs and Tables
+    setupPrivileges(statement); // setup privileges for USER1
+
+    // verify privileges on the created tables
+    statement.execute("USE " + DB2);
+    verifyTablePrivilegeExist(statement,
+        Lists.newArrayList("select_tbl1", "insert_tbl1", "all_tbl1"),
+        tableName1);
+    verifyTablePrivilegeExist(statement, Lists.newArrayList("all_tbl2"),
+        tableName2);
+
+    renameTables(statement); // alter tables to rename
+
+    // verify privileges removed for old tables
+    verifyTablePrivilegesDropped(statement);
+
+    // verify privileges created for new tables
+    statement.execute("USE " + DB2);
+    verifyTablePrivilegeExist(statement,
+        Lists.newArrayList("select_tbl1", "insert_tbl1", "all_tbl1"),
+        tableName1 + renameTag);
+    verifyTablePrivilegeExist(statement, Lists.newArrayList("all_tbl2"),
+        tableName2 + renameTag);
+
+    statement.close();
+    connection.close();
+  }
+
+  /**
+   * After we drop/rename table, we will drop/rename all 
privileges(ALL,SELECT,INSERT,ALTER,DROP...)
+   * from this role
+   *
+   * @throws Exception
+   */
+  @Test
+  public void testDropAndRenameWithMultiAction() throws Exception {
+    Connection connection = context.createConnection(ADMIN1);
+    Statement statement = context.createStatement(connection);
+    statement.execute("CREATE ROLE user_role");
+    statement.execute("GRANT ROLE user_role TO GROUP " + USERGROUP1);
+
+    statement.execute("CREATE DATABASE " + DB1);
+    statement.execute("USE " + DB1);
+    statement.execute("CREATE TABLE t1 (c1 string)");
+
+    // Grant SELECT/INSERT/DROP/ALTER to TABLE t1
+    statement.execute("GRANT SELECT ON TABLE t1 TO ROLE user_role");
+    statement.execute("GRANT INSERT ON TABLE t1 TO ROLE user_role");
+    statement.execute("GRANT ALTER ON TABLE t1 TO ROLE user_role");
+    statement.execute("GRANT DROP ON TABLE t1 TO ROLE user_role");
+    // For rename, grant CREATE to DB1
+    statement.execute("GRANT CREATE ON DATABASE " + DB1 + " TO ROLE 
user_role");
+
+    // After rename table t1 to t2, user_role will have no permission to drop 
t1
+    connection = context.createConnection(USER1_1);
+    statement = context.createStatement(connection);
+    statement.execute("USE " + DB1);
+    statement.execute("ALTER TABLE t1 RENAME TO t2");
+    context.assertSentrySemanticException(statement, "drop table t1", 
semanticException);
+
+    // After rename table t1 to t2, user_role should have permission to drop t2
+    statement.execute("drop table t2");
+    ResultSet resultSet = statement.executeQuery("SHOW GRANT ROLE user_role");
+    // user_role will revoke all privilege from table t2, only remain CREATE 
on db_1
+    assertRemainingRows(resultSet, 1);
+
+    statement.close();
+    connection.close();
+  }
+
+  // Create test roles
+  private void setupRoles(Statement statement) throws Exception {
+    statement.execute("CREATE ROLE all_db1");
+    statement.execute("CREATE ROLE read_db1");
+    statement.execute("CREATE ROLE select_tbl1");
+    statement.execute("CREATE ROLE insert_tbl1");
+    statement.execute("CREATE ROLE all_tbl1");
+    statement.execute("CREATE ROLE all_tbl2");
+    statement.execute("CREATE ROLE all_prod");
+
+    statement.execute("GRANT ROLE all_db1, read_db1, select_tbl1, insert_tbl1,"
+        + " all_tbl1, all_tbl2, all_prod to GROUP " + USERGROUP1);
+
+    statement.execute("DROP DATABASE IF EXISTS " + DB1 + " CASCADE");
+    statement.execute("DROP DATABASE IF EXISTS " + DB2 + " CASCADE");
+  }
+
+  // create test DBs and Tables
+  private void setupDbObjects(Statement statement) throws Exception {
+    statement.execute("CREATE DATABASE " + DB1);
+    statement.execute("CREATE DATABASE " + DB2);
+    statement.execute("create table " + DB2 + "." + tableName1
+        + " (under_col int comment 'the under column', value string)");
+    statement.execute("create table " + DB2 + "." + tableName2
+        + " (under_col int comment 'the under column', value string)");
+    statement.execute("create table " + DB1 + "." + tableName3
+        + " (under_col int comment 'the under column', value string)");
+    statement.execute("create table " + DB1 + "." + tableName4
+        + " (under_col int comment 'the under column', value string)");
+  }
+
+  // Create privileges on DB and Tables
+  private void setupPrivileges(Statement statement) throws Exception {
+    statement.execute("GRANT ALL ON DATABASE " + DB1 + " TO ROLE all_db1");
+    statement.execute("GRANT SELECT ON DATABASE " + DB1
+        + " TO ROLE read_db1");
+    statement.execute("GRANT ALL ON DATABASE " + DB2 + " TO ROLE all_prod");
+    statement.execute("USE " + DB2);
+    statement.execute("GRANT SELECT ON TABLE " + tableName1
+        + " TO ROLE select_tbl1");
+    statement.execute("GRANT INSERT ON TABLE " + tableName1
+        + " TO ROLE insert_tbl1");
+    statement.execute("GRANT ALL ON TABLE " + tableName1 + " TO ROLE 
all_tbl1");
+    statement.execute("GRANT ALL ON TABLE " + tableName2 + " TO ROLE 
all_tbl2");
+  }
+
+  // Drop test DBs and Tables
+  private void dropDbObjects(Statement statement) throws Exception {
+    statement.execute("DROP TABLE " + DB2 + "." + tableName1);
+    statement.execute("DROP TABLE " + DB2 + "." + tableName2);
+    statement.execute("DROP DATABASE " + DB2);
+    statement.execute("DROP DATABASE " + DB1 + " CASCADE");
+  }
+
+  // rename tables
+  private void renameTables(Statement statement) throws Exception {
+    statement.execute("USE " + DB2);
+    statement.execute("ALTER TABLE " + tableName1 + " RENAME TO " + tableName1
+        + renameTag);
+    statement.execute("ALTER TABLE " + tableName2 + " RENAME TO " + tableName2
+        + renameTag);
+    statement.execute("USE " + DB1);
+    statement.execute("ALTER TABLE " + tableName3 + " RENAME TO " + tableName3
+        + renameTag);
+    statement.execute("ALTER TABLE " + tableName4 + " RENAME TO " + tableName4
+        + renameTag);
+  }
+
+  // verify all the test privileges are dropped as we drop the objects
+  private void verifyPrivilegesDropped(Statement statement)
+      throws Exception {
+    verifyDbPrivilegesDropped(statement);
+    verifyTablePrivilegesDropped(statement);
+  }
+
+  // verify all the test privileges are dropped as we drop the objects
+  private void verifyTablePrivilegesDropped(Statement statement)
+      throws Exception {
+    List<String> roles = getRoles(statement);
+    verifyPrivilegeDropped(statement, roles, tableName1,
+        SHOW_GRANT_TABLE_POSITION);
+    verifyPrivilegeDropped(statement, roles, tableName2,
+        SHOW_GRANT_TABLE_POSITION);
+    verifyPrivilegeDropped(statement, roles, tableName3,
+        SHOW_GRANT_TABLE_POSITION);
+    verifyPrivilegeDropped(statement, roles, tableName4,
+        SHOW_GRANT_TABLE_POSITION);
+
+  }
+
+  // verify all the test privileges are dropped as we drop the objects
+  private void verifyDbPrivilegesDropped(Statement statement) throws Exception 
{
+    List<String> roles = getRoles(statement);
+    verifyPrivilegeDropped(statement, roles, DB2, SHOW_GRANT_DB_POSITION);
+    verifyPrivilegeDropped(statement, roles, DB1, SHOW_GRANT_DB_POSITION);
+
+  }
+
+  // verify given table/DB has no longer permissions
+  private void verifyPrivilegeDropped(Statement statement, List<String> roles,
+      String objectName, int resultPos) throws Exception {
+    for (String roleName : roles) {
+      ResultSet resultSet = statement.executeQuery("SHOW GRANT ROLE "
+          + roleName);
+      while (resultSet.next()) {
+        String returned = resultSet.getString(resultPos);
+        assertFalse("value " + objectName + " shouldn't be detected, but 
actually " + returned + " is found from resultSet",
+                objectName.equalsIgnoreCase(returned));
+      }
+      resultSet.close();
+    }
+  }
+
+  // verify given table is part of the role
+  private void verifyTablePrivilegeExist(Statement statement,
+      List<String> roles, String tableName) throws Exception {
+    for (String roleName : roles) {
+      ResultSet resultSet = statement.executeQuery("SHOW GRANT ROLE "
+          + roleName + " ON TABLE " + tableName);
+      assertTrue(resultSet.next());
+      resultSet.close();
+    }
+  }
+
+  private List<String> getRoles(Statement statement) throws Exception {
+    ArrayList<String> roleList = Lists.newArrayList();
+    ResultSet resultSet = statement.executeQuery("SHOW ROLES ");
+    while (resultSet.next()) {
+      roleList.add(resultSet.getString(1));
+    }
+    return roleList;
+  }
+}

http://git-wip-us.apache.org/repos/asf/sentry/blob/bfb354f2/sentry-tests/sentry-tests-hive-v2/src/test/java/org/apache/sentry/tests/e2e/dbprovider/TestDbPrivilegesAtColumnScope.java
----------------------------------------------------------------------
diff --git 
a/sentry-tests/sentry-tests-hive-v2/src/test/java/org/apache/sentry/tests/e2e/dbprovider/TestDbPrivilegesAtColumnScope.java
 
b/sentry-tests/sentry-tests-hive-v2/src/test/java/org/apache/sentry/tests/e2e/dbprovider/TestDbPrivilegesAtColumnScope.java
new file mode 100644
index 0000000..659c61f
--- /dev/null
+++ 
b/sentry-tests/sentry-tests-hive-v2/src/test/java/org/apache/sentry/tests/e2e/dbprovider/TestDbPrivilegesAtColumnScope.java
@@ -0,0 +1,38 @@
+/*
+ * 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.sentry.tests.e2e.dbprovider;
+
+import org.apache.sentry.tests.e2e.hive.TestPrivilegesAtColumnScope;
+import org.junit.Before;
+import org.junit.BeforeClass;
+
+public class TestDbPrivilegesAtColumnScope extends TestPrivilegesAtColumnScope 
{
+  @Override
+  @Before
+  public void setup() throws Exception {
+    setupAdmin();
+    super.setup();
+  }
+
+  @BeforeClass
+  public static void setupTestStaticConfiguration() throws Exception {
+    useSentryService = true;
+    TestPrivilegesAtColumnScope.setupTestStaticConfiguration();
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/sentry/blob/bfb354f2/sentry-tests/sentry-tests-hive-v2/src/test/java/org/apache/sentry/tests/e2e/dbprovider/TestDbPrivilegesAtDatabaseScope.java
----------------------------------------------------------------------
diff --git 
a/sentry-tests/sentry-tests-hive-v2/src/test/java/org/apache/sentry/tests/e2e/dbprovider/TestDbPrivilegesAtDatabaseScope.java
 
b/sentry-tests/sentry-tests-hive-v2/src/test/java/org/apache/sentry/tests/e2e/dbprovider/TestDbPrivilegesAtDatabaseScope.java
new file mode 100644
index 0000000..883bedd
--- /dev/null
+++ 
b/sentry-tests/sentry-tests-hive-v2/src/test/java/org/apache/sentry/tests/e2e/dbprovider/TestDbPrivilegesAtDatabaseScope.java
@@ -0,0 +1,46 @@
+/*
+ * 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.sentry.tests.e2e.dbprovider;
+
+import org.apache.sentry.tests.e2e.hive.AbstractTestWithStaticConfiguration;
+import org.apache.sentry.tests.e2e.hive.TestPrivilegesAtDatabaseScope;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class TestDbPrivilegesAtDatabaseScope extends
+    TestPrivilegesAtDatabaseScope {
+  private static final Logger LOGGER = LoggerFactory.
+          getLogger(TestDbPrivilegesAtDatabaseScope.class);
+
+  @Override
+  @Before
+  public void setup() throws Exception {
+    LOGGER.info("TestDbPrivilegesAtDatabaseScope setup");
+    super.setupAdmin();
+    super.setup();
+  }
+  @BeforeClass
+  public static void setupTestStaticConfiguration() throws Exception {
+    LOGGER.info("TestDbPrivilegesAtDatabaseScope 
setupTestStaticConfiguration");
+    useSentryService = true;
+    AbstractTestWithStaticConfiguration.setupTestStaticConfiguration();
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/sentry/blob/bfb354f2/sentry-tests/sentry-tests-hive-v2/src/test/java/org/apache/sentry/tests/e2e/dbprovider/TestDbPrivilegesAtFunctionScope.java
----------------------------------------------------------------------
diff --git 
a/sentry-tests/sentry-tests-hive-v2/src/test/java/org/apache/sentry/tests/e2e/dbprovider/TestDbPrivilegesAtFunctionScope.java
 
b/sentry-tests/sentry-tests-hive-v2/src/test/java/org/apache/sentry/tests/e2e/dbprovider/TestDbPrivilegesAtFunctionScope.java
new file mode 100644
index 0000000..cebad98
--- /dev/null
+++ 
b/sentry-tests/sentry-tests-hive-v2/src/test/java/org/apache/sentry/tests/e2e/dbprovider/TestDbPrivilegesAtFunctionScope.java
@@ -0,0 +1,39 @@
+/*
+ * 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.sentry.tests.e2e.dbprovider;
+
+import org.apache.sentry.tests.e2e.hive.AbstractTestWithStaticConfiguration;
+import org.apache.sentry.tests.e2e.hive.TestPrivilegesAtFunctionScope;
+import org.junit.Before;
+import org.junit.BeforeClass;
+
+public class TestDbPrivilegesAtFunctionScope extends
+    TestPrivilegesAtFunctionScope {
+  @Override
+  @Before
+  public void setup() throws Exception {
+    super.setupAdmin();
+    super.setup();
+  }
+  @BeforeClass
+  public static void setupTestStaticConfiguration() throws Exception {
+    useSentryService = true;
+    AbstractTestWithStaticConfiguration.setupTestStaticConfiguration();
+
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/sentry/blob/bfb354f2/sentry-tests/sentry-tests-hive-v2/src/test/java/org/apache/sentry/tests/e2e/dbprovider/TestDbPrivilegesAtTableScope.java
----------------------------------------------------------------------
diff --git 
a/sentry-tests/sentry-tests-hive-v2/src/test/java/org/apache/sentry/tests/e2e/dbprovider/TestDbPrivilegesAtTableScope.java
 
b/sentry-tests/sentry-tests-hive-v2/src/test/java/org/apache/sentry/tests/e2e/dbprovider/TestDbPrivilegesAtTableScope.java
new file mode 100644
index 0000000..a4f07df
--- /dev/null
+++ 
b/sentry-tests/sentry-tests-hive-v2/src/test/java/org/apache/sentry/tests/e2e/dbprovider/TestDbPrivilegesAtTableScope.java
@@ -0,0 +1,39 @@
+/*
+ * 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.sentry.tests.e2e.dbprovider;
+
+import org.apache.sentry.tests.e2e.hive.AbstractTestWithStaticConfiguration;
+import org.apache.sentry.tests.e2e.hive.TestPrivilegesAtTableScope;
+import org.junit.Before;
+import org.junit.BeforeClass;
+
+public class TestDbPrivilegesAtTableScope extends TestPrivilegesAtTableScope {
+  @Override
+  @Before
+  public void setup() throws Exception {
+    super.setupAdmin();
+    super.setup();
+    prepareDBDataForTest();
+  }
+  @BeforeClass
+  public static void setupTestStaticConfiguration() throws Exception {
+    useSentryService = true;
+    AbstractTestWithStaticConfiguration.setupTestStaticConfiguration();
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/sentry/blob/bfb354f2/sentry-tests/sentry-tests-hive-v2/src/test/java/org/apache/sentry/tests/e2e/dbprovider/TestDbRuntimeMetadataRetrieval.java
----------------------------------------------------------------------
diff --git 
a/sentry-tests/sentry-tests-hive-v2/src/test/java/org/apache/sentry/tests/e2e/dbprovider/TestDbRuntimeMetadataRetrieval.java
 
b/sentry-tests/sentry-tests-hive-v2/src/test/java/org/apache/sentry/tests/e2e/dbprovider/TestDbRuntimeMetadataRetrieval.java
new file mode 100644
index 0000000..8d98179
--- /dev/null
+++ 
b/sentry-tests/sentry-tests-hive-v2/src/test/java/org/apache/sentry/tests/e2e/dbprovider/TestDbRuntimeMetadataRetrieval.java
@@ -0,0 +1,46 @@
+/*
+ * 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.sentry.tests.e2e.dbprovider;
+
+import org.apache.sentry.tests.e2e.hive.AbstractTestWithStaticConfiguration;
+import org.apache.sentry.tests.e2e.hive.TestRuntimeMetadataRetrieval;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class TestDbRuntimeMetadataRetrieval extends
+    TestRuntimeMetadataRetrieval {
+  private static final Logger LOGGER = LoggerFactory.
+          getLogger(TestDbRuntimeMetadataRetrieval.class);
+
+  @Override
+  @Before
+  public void setup() throws Exception {
+    LOGGER.info("TestDbRuntimeMetadataRetrieval setup");
+    super.setupAdmin();
+    super.setup();
+  }
+  @BeforeClass
+  public static void setupTestStaticConfiguration() throws Exception {
+    LOGGER.info("TestDbRuntimeMetadataRetrieval setupTestStaticConfiguration");
+    useSentryService = true;
+    AbstractTestWithStaticConfiguration.setupTestStaticConfiguration();
+
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/sentry/blob/bfb354f2/sentry-tests/sentry-tests-hive-v2/src/test/java/org/apache/sentry/tests/e2e/dbprovider/TestDbSandboxOps.java
----------------------------------------------------------------------
diff --git 
a/sentry-tests/sentry-tests-hive-v2/src/test/java/org/apache/sentry/tests/e2e/dbprovider/TestDbSandboxOps.java
 
b/sentry-tests/sentry-tests-hive-v2/src/test/java/org/apache/sentry/tests/e2e/dbprovider/TestDbSandboxOps.java
new file mode 100644
index 0000000..fa429e7
--- /dev/null
+++ 
b/sentry-tests/sentry-tests-hive-v2/src/test/java/org/apache/sentry/tests/e2e/dbprovider/TestDbSandboxOps.java
@@ -0,0 +1,49 @@
+/*
+ * 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.sentry.tests.e2e.dbprovider;
+
+import org.apache.sentry.tests.e2e.hive.AbstractTestWithStaticConfiguration;
+import org.apache.sentry.tests.e2e.hive.TestSandboxOps;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Ignore;
+import org.junit.Test;
+
+public class TestDbSandboxOps extends TestSandboxOps {
+  @Override
+  @Before
+  public void setup() throws Exception {
+    super.setupAdmin();
+    super.setup();
+  }
+
+  @BeforeClass
+  public static void setupTestStaticConfiguration() throws Exception {
+    useSentryService = true;
+    AbstractTestWithStaticConfiguration.setupTestStaticConfiguration();
+
+  }
+
+  @Ignore
+  @Test
+  public void testPerDbPolicyOnDFS() throws Exception {
+    // TODO : Looks like the test in the base class is specifically meant for
+    // File based providers... Since it is assuming that multiple policy files
+    // in DFS would be handled by the provider..
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/sentry/blob/bfb354f2/sentry-tests/sentry-tests-hive-v2/src/test/java/org/apache/sentry/tests/e2e/dbprovider/TestDbSentryOnFailureHookLoading.java
----------------------------------------------------------------------
diff --git 
a/sentry-tests/sentry-tests-hive-v2/src/test/java/org/apache/sentry/tests/e2e/dbprovider/TestDbSentryOnFailureHookLoading.java
 
b/sentry-tests/sentry-tests-hive-v2/src/test/java/org/apache/sentry/tests/e2e/dbprovider/TestDbSentryOnFailureHookLoading.java
new file mode 100644
index 0000000..8cb04f7
--- /dev/null
+++ 
b/sentry-tests/sentry-tests-hive-v2/src/test/java/org/apache/sentry/tests/e2e/dbprovider/TestDbSentryOnFailureHookLoading.java
@@ -0,0 +1,271 @@
+/*
+ * 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.sentry.tests.e2e.dbprovider;
+
+import java.sql.Connection;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+
+import org.junit.Assert;
+
+import org.apache.hadoop.hive.ql.plan.HiveOperation;
+import org.apache.sentry.binding.hive.conf.HiveAuthzConf;
+import org.apache.sentry.provider.db.SentryAccessDeniedException;
+import org.apache.sentry.tests.e2e.hive.DummySentryOnFailureHook;
+import org.apache.sentry.tests.e2e.hive.hiveserver.HiveServerFactory;
+import org.junit.After;
+import org.junit.Assume;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+public class TestDbSentryOnFailureHookLoading extends 
AbstractTestWithDbProvider {
+
+
+  @BeforeClass
+  public static void setup() throws Exception {
+    properties = new HashMap<String, String>();
+    properties.put(HiveAuthzConf.AuthzConfVars.AUTHZ_ONFAILURE_HOOKS.getVar(),
+        DummySentryOnFailureHook.class.getName());
+    createContext();
+    DummySentryOnFailureHook.invoked = false;
+
+    // Do not run these tests if run with external HiveServer2
+    // This test checks for a static member, which will not
+    // be set if HiveServer2 and the test run in different JVMs
+    String hiveServer2Type = System
+        .getProperty(HiveServerFactory.HIVESERVER2_TYPE);
+    if(hiveServer2Type != null) {
+      Assume.assumeTrue(HiveServerFactory.isInternalServer(
+          HiveServerFactory.HiveServer2Type.valueOf(hiveServer2Type.trim())));
+    }
+  }
+
+  @After
+  public void clearDB() throws Exception {
+    Connection connection;
+    Statement statement;
+    connection = context.createConnection(ADMIN1);
+    statement = context.createStatement(connection);
+    ResultSet resultSet;
+    resultSet = statement.executeQuery("SHOW roles");
+    List<String> roles = new ArrayList<String>();
+    while ( resultSet.next()) {
+      roles.add(resultSet.getString(1));
+    }
+    for(String role:roles) {
+      statement.execute("DROP Role " + role);
+    }
+
+    statement.close();
+    connection.close();
+    if (context != null) {
+      context.close();
+    }
+  }
+
+  /* Admin creates database DB_2
+   * user1 tries to drop DB_2, but it has permissions for DB_1.
+   */
+  @Test
+  public void testOnFailureHookLoading() throws Exception {
+
+    // setup db objects needed by the test
+    Connection connection = context.createConnection(ADMIN1);
+    Statement statement = context.createStatement(connection);
+    try {
+      statement.execute("DROP ROLE admin_role");
+    } catch (Exception ex) {
+      //It is ok if admin_role already exists
+    }
+    statement.execute("CREATE ROLE admin_role");
+    statement.execute("GRANT ALL ON SERVER "
+        + HiveServerFactory.DEFAULT_AUTHZ_SERVER_NAME + " TO ROLE admin_role");
+    statement.execute("GRANT ROLE admin_role TO GROUP " + ADMINGROUP);
+
+    statement.execute("DROP DATABASE IF EXISTS DB_1 CASCADE");
+    statement.execute("DROP DATABASE IF EXISTS DB_2 CASCADE");
+    statement.execute("CREATE DATABASE DB_1");
+    statement.execute("CREATE DATABASE DB_2");
+    statement.execute("CREATE TABLE db_2.tab1(a int )");
+
+    statement.execute("CREATE ROLE all_db1");
+    statement.execute("GRANT ALL ON DATABASE DB_1 TO ROLE all_db1");
+    statement.execute("GRANT ROLE all_db1 TO GROUP " + USERGROUP1);
+
+    statement.execute("CREATE ROLE lock_db2_tab1");
+    statement.execute("GRANT ROLE lock_db2_tab1 TO GROUP " + USERGROUP1);
+
+    statement.execute("USE db_2");
+    statement.execute("GRANT LOCK ON TABLE tab1 TO ROLE lock_db2_tab1");// To 
give user1 privilege to do USE db_2
+    statement.close();
+    connection.close();
+
+    // test execution
+    connection = context.createConnection(USER1_1);
+    statement = context.createStatement(connection);
+
+    // Failure hook for create table when table doesnt exist
+    verifyFailureHook(statement, "CREATE TABLE DB_2.TAB2(id INT)", 
HiveOperation.CREATETABLE, "db_2", null, false);
+
+    // Failure hook for create table when table exist
+    verifyFailureHook(statement, "CREATE TABLE DB_2.TAB1(id INT)", 
HiveOperation.CREATETABLE, "db_2", null, false);
+
+    // Failure hook for select * from table when table exist
+    verifyFailureHook(statement, "select * from db_2.tab1", 
HiveOperation.QUERY,
+        null, null, false);
+
+    //Denied alter table invokes failure hook
+    statement.execute("USE DB_2");
+    verifyFailureHook(statement, "ALTER TABLE tab1 CHANGE id id1 INT", 
HiveOperation.ALTERTABLE_RENAMECOL,
+        "db_2", null, false);
+
+    statement.close();
+    connection.close();
+
+    //test cleanup
+    connection = context.createConnection(ADMIN1);
+    statement = context.createStatement(connection);
+    statement.execute("DROP DATABASE DB_1 CASCADE");
+    statement.execute("DROP DATABASE DB_2 CASCADE");
+    statement.close();
+    connection.close();
+    context.close();
+  }
+
+  /*
+   * Admin creates database DB_2 user1 tries to drop DB_2, but it has
+   * permissions for DB_1.
+   */
+  @Test
+  public void testOnFailureHookForAuthDDL() throws Exception {
+
+    // setup db objects needed by the test
+    Connection connection = context.createConnection(ADMIN1);
+    Statement statement = context.createStatement(connection);
+    statement.execute("CREATE ROLE admin_role");
+    statement.execute("GRANT ALL ON SERVER "
+        + HiveServerFactory.DEFAULT_AUTHZ_SERVER_NAME + " TO ROLE admin_role");
+    statement.execute("GRANT ROLE admin_role TO GROUP " + ADMINGROUP);
+    statement.execute("DROP DATABASE IF EXISTS DB_1 CASCADE");
+    statement.execute("DROP DATABASE IF EXISTS DB_2 CASCADE");
+    statement.execute("CREATE DATABASE DB_1");
+    statement.execute("CREATE TABLE DB_1.tab1(a int )");
+    statement.execute("CREATE ROLE all_db1");
+    statement.execute("GRANT ALL ON DATABASE DB_1 TO ROLE all_db1");
+    statement.execute("GRANT ROLE all_db1 TO GROUP " + USERGROUP1);
+    connection.close();
+
+    connection = context.createConnection(USER1_1);
+    statement = context.createStatement(connection);
+
+    statement.execute("USE DB_1");
+    statement.execute("CREATE TABLE foo (id int)");
+
+    verifyFailureHook(statement, "CREATE ROLE fooTest",
+        HiveOperation.CREATEROLE, null, null, true);
+
+    verifyFailureHook(statement, "DROP ROLE fooTest",
+        HiveOperation.DROPROLE, null, null, true);
+
+    verifyFailureHook(statement,
+        "GRANT ALL ON SERVER server1 TO ROLE admin_role",
+        HiveOperation.GRANT_PRIVILEGE, null, null, true);
+
+    verifyFailureHook(statement,
+        "REVOKE ALL ON SERVER server1 FROM ROLE admin_role",
+        HiveOperation.REVOKE_PRIVILEGE, null, null, true);
+
+    verifyFailureHook(statement, "GRANT ROLE all_db1 TO GROUP " + USERGROUP1,
+        HiveOperation.GRANT_ROLE, null, null, true);
+
+    verifyFailureHook(statement,
+        "REVOKE ROLE all_db1 FROM GROUP " + USERGROUP1,
+        HiveOperation.REVOKE_ROLE, null, null, true);
+
+    verifyFailureHook(statement, "SHOW ROLES",
+        HiveOperation.SHOW_ROLES, null, null, true);
+
+    verifyFailureHook(statement, "SHOW ROLE GRANT group group1",
+        HiveOperation.SHOW_ROLE_GRANT, null, null, true);
+
+    verifyFailureHook(statement, "SHOW GRANT role role1",
+        HiveOperation.SHOW_GRANT, null, null, true);
+
+    //Should pass as user1_1 is granted role all_db1
+    statement.execute("SHOW GRANT role all_db1");
+
+        //Grant privilege on table doesnt expose db and table objects
+    verifyFailureHook(statement,
+        "GRANT ALL ON TABLE db_1.tab1 TO ROLE admin_role",
+        HiveOperation.GRANT_PRIVILEGE, null, null, true);
+
+    //Revoke privilege on table doesnt expose db and table objects
+    verifyFailureHook(statement,
+        "REVOKE ALL ON TABLE db_1.tab1 FROM ROLE admin_role",
+        HiveOperation.REVOKE_PRIVILEGE, null, null, true);
+
+    //Grant privilege on database doesnt expose db and table objects
+    verifyFailureHook(statement,
+        "GRANT ALL ON Database db_1 TO ROLE admin_role",
+        HiveOperation.GRANT_PRIVILEGE, null, null, true);
+
+    //Revoke privilege on database doesnt expose db and table objects
+    verifyFailureHook(statement,
+        "REVOKE ALL ON Database db_1 FROM ROLE admin_role",
+        HiveOperation.REVOKE_PRIVILEGE, null, null, true);
+
+    statement.close();
+    connection.close();
+    context.close();
+  }
+
+  // run the given statement and verify that failure hook is invoked as 
expected
+  private void verifyFailureHook(Statement statement, String sqlStr, 
HiveOperation expectedOp,
+       String dbName, String tableName, boolean 
checkSentryAccessDeniedException) throws Exception {
+    // negative test case: non admin user can't create role
+    Assert.assertFalse(DummySentryOnFailureHook.invoked);
+    try {
+      statement.execute(sqlStr);
+      Assert.fail("Expected SQL exception for " + sqlStr);
+    } catch (SQLException e) {
+      Assert.assertTrue("FailureHook is not ran : " + e.getMessage(), 
DummySentryOnFailureHook.invoked);
+    } finally {
+      DummySentryOnFailureHook.invoked = false;
+    }
+    if (expectedOp != null) {
+      Assert.assertNotNull("Hive op is null for op: " + expectedOp, 
DummySentryOnFailureHook.hiveOp);
+      Assert.assertTrue(expectedOp.equals(DummySentryOnFailureHook.hiveOp));
+    }
+    if (checkSentryAccessDeniedException) {
+      Assert.assertTrue("Expected SentryDeniedException for op: " + expectedOp,
+          DummySentryOnFailureHook.exception.getCause() instanceof 
SentryAccessDeniedException);
+    }
+    if(tableName != null) {
+      Assert.assertNotNull("Table object is null for op: " + expectedOp, 
DummySentryOnFailureHook.table);
+      
Assert.assertTrue(tableName.equalsIgnoreCase(DummySentryOnFailureHook.table.getName()));
+    }
+    if(dbName != null) {
+      Assert.assertNotNull("Database object is null for op: " + expectedOp, 
DummySentryOnFailureHook.db);
+      
Assert.assertTrue(dbName.equalsIgnoreCase(DummySentryOnFailureHook.db.getName()));
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/sentry/blob/bfb354f2/sentry-tests/sentry-tests-hive-v2/src/test/java/org/apache/sentry/tests/e2e/dbprovider/TestDbUriPermissions.java
----------------------------------------------------------------------
diff --git 
a/sentry-tests/sentry-tests-hive-v2/src/test/java/org/apache/sentry/tests/e2e/dbprovider/TestDbUriPermissions.java
 
b/sentry-tests/sentry-tests-hive-v2/src/test/java/org/apache/sentry/tests/e2e/dbprovider/TestDbUriPermissions.java
new file mode 100644
index 0000000..1a90e06
--- /dev/null
+++ 
b/sentry-tests/sentry-tests-hive-v2/src/test/java/org/apache/sentry/tests/e2e/dbprovider/TestDbUriPermissions.java
@@ -0,0 +1,45 @@
+/*
+ * 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.sentry.tests.e2e.dbprovider;
+
+import org.apache.sentry.tests.e2e.hive.AbstractTestWithStaticConfiguration;
+import org.apache.sentry.tests.e2e.hive.TestUriPermissions;
+import org.junit.Before;
+import org.junit.BeforeClass;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class TestDbUriPermissions extends TestUriPermissions {
+  private static final Logger LOGGER = LoggerFactory.
+          getLogger(TestDbUriPermissions.class);
+
+  @Override
+  @Before
+  public void setup() throws Exception {
+    LOGGER.info("TestDbUriPermissions setup");
+    super.setupAdmin();
+    super.setup();
+  }
+  @BeforeClass
+  public static void setupTestStaticConfiguration() throws Exception {
+    LOGGER.info("TestDbUriPermissions setupTestStaticConfiguration");
+    useSentryService = true;
+    AbstractTestWithStaticConfiguration.setupTestStaticConfiguration();
+
+  }
+}

http://git-wip-us.apache.org/repos/asf/sentry/blob/bfb354f2/sentry-tests/sentry-tests-hive-v2/src/test/java/org/apache/sentry/tests/e2e/dbprovider/TestPrivilegeWithGrantOption.java
----------------------------------------------------------------------
diff --git 
a/sentry-tests/sentry-tests-hive-v2/src/test/java/org/apache/sentry/tests/e2e/dbprovider/TestPrivilegeWithGrantOption.java
 
b/sentry-tests/sentry-tests-hive-v2/src/test/java/org/apache/sentry/tests/e2e/dbprovider/TestPrivilegeWithGrantOption.java
new file mode 100644
index 0000000..65ece8f
--- /dev/null
+++ 
b/sentry-tests/sentry-tests-hive-v2/src/test/java/org/apache/sentry/tests/e2e/dbprovider/TestPrivilegeWithGrantOption.java
@@ -0,0 +1,269 @@
+/*
+ * 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.sentry.tests.e2e.dbprovider;
+
+import java.sql.Connection;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+
+import org.junit.Assert;
+
+import org.apache.hadoop.hive.ql.plan.HiveOperation;
+import org.apache.sentry.binding.hive.conf.HiveAuthzConf;
+import org.apache.sentry.provider.db.SentryAccessDeniedException;
+import org.apache.sentry.tests.e2e.hive.AbstractTestWithStaticConfiguration;
+import org.apache.sentry.tests.e2e.hive.DummySentryOnFailureHook;
+import org.apache.sentry.tests.e2e.hive.hiveserver.HiveServerFactory;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+public class TestPrivilegeWithGrantOption extends 
AbstractTestWithStaticConfiguration {
+
+  private static boolean isInternalServer = false;
+  private static int SHOW_GRANT_ROLE_DB_POSITION = 1;
+  private static int SHOW_GRANT_ROLE_TABLE_POSITION = 2;
+  private static int SHOW_GRANT_ROLE_WITH_GRANT_POSITION = 8;
+
+  @BeforeClass
+  public static void setupTestStaticConfiguration() throws Exception {
+    useSentryService = true;
+    String hiveServer2Type = System
+        .getProperty(HiveServerFactory.HIVESERVER2_TYPE);
+    if ((hiveServer2Type == null)
+        || HiveServerFactory.isInternalServer(HiveServerFactory.HiveServer2Type
+            .valueOf(hiveServer2Type.trim()))) {
+      System.setProperty(
+        HiveAuthzConf.AuthzConfVars.AUTHZ_ONFAILURE_HOOKS.getVar(),
+        DummySentryOnFailureHook.class.getName());
+      isInternalServer = true;
+    }
+    AbstractTestWithStaticConfiguration.setupTestStaticConfiguration();
+  }
+
+  @Override
+  @Before
+  public void setup() throws Exception {
+    DummySentryOnFailureHook.invoked = false;
+    super.setupAdmin();
+    super.setup();
+  }
+
+  /*
+   * Admin grant DB_1 user1 without grant option, grant user3 with grant 
option,
+   * user1 tries to grant it to user2, but failed.
+   * user3 can grant it to user2.
+   * user1 tries to revoke, but failed.
+   * user3 tries to revoke user2, user3 and user1, user3 revoke user1 will 
failed.
+   * permissions for DB_1.
+   */
+  @Test
+  public void testOnGrantPrivilege() throws Exception {
+
+    // setup db objects needed by the test
+    Connection connection = context.createConnection(ADMIN1);
+    Statement statement = context.createStatement(connection);
+    statement.execute("DROP DATABASE IF EXISTS db_1 CASCADE");
+    statement.execute("DROP DATABASE IF EXISTS db_2 CASCADE");
+    statement.execute("CREATE DATABASE db_1");
+    statement.execute("CREATE ROLE group1_role");
+    statement.execute("GRANT ALL ON DATABASE db_1 TO ROLE group1_role");
+    statement.execute("GRANT ROLE group1_role TO GROUP " + USERGROUP1);
+    statement.execute("CREATE ROLE group3_grant_role");
+    statement.execute("GRANT ALL ON DATABASE db_1 TO ROLE group3_grant_role 
WITH GRANT OPTION");
+    statement.execute("GRANT ROLE group3_grant_role TO GROUP " + USERGROUP3);
+    statement.execute("CREATE ROLE group2_role");
+    statement.execute("GRANT ROLE group2_role TO GROUP " + USERGROUP2);
+
+    connection.close();
+
+    connection = context.createConnection(USER1_1);
+    statement = context.createStatement(connection);
+
+    statement.execute("USE db_1");
+    statement.execute("CREATE TABLE foo (id int)");
+    runSQLWithError(statement, "GRANT ALL ON DATABASE db_1 TO ROLE 
group2_role",
+        HiveOperation.GRANT_PRIVILEGE, null, null, true);
+    runSQLWithError(statement,
+        "GRANT ALL ON DATABASE db_1 TO ROLE group2_role WITH GRANT OPTION",
+        HiveOperation.GRANT_PRIVILEGE, null, null, true);
+    connection.close();
+
+    connection = context.createConnection(USER3_1);
+    statement = context.createStatement(connection);
+    statement.execute("GRANT ALL ON DATABASE db_1 TO ROLE group2_role");
+    connection.close();
+
+    connection = context.createConnection(USER1_1);
+    statement = context.createStatement(connection);
+    runSQLWithError(statement, "REVOKE ALL ON Database db_1 FROM ROLE 
admin_role",
+        HiveOperation.REVOKE_PRIVILEGE, null, null, true);
+    runSQLWithError(statement, "REVOKE ALL ON Database db_1 FROM ROLE 
group2_role",
+        HiveOperation.REVOKE_PRIVILEGE, null, null, true);
+    runSQLWithError(statement,
+        "REVOKE ALL ON Database db_1 FROM ROLE group3_grant_role",
+        HiveOperation.REVOKE_PRIVILEGE, null, null, true);
+    connection.close();
+
+    connection = context.createConnection(USER3_1);
+    statement = context.createStatement(connection);
+    statement.execute("REVOKE ALL ON Database db_1 FROM ROLE group2_role");
+    statement.execute("REVOKE ALL ON Database db_1 FROM ROLE 
group3_grant_role");
+    runSQLWithError(statement, "REVOKE ALL ON Database db_1 FROM ROLE 
group1_role",
+        HiveOperation.REVOKE_PRIVILEGE, null, null, true);
+
+    connection.close();
+    context.close();
+  }
+
+  /**
+   * Test privileges with grant on parent objects are sufficient for operation
+   * on child objects
+   * @throws Exception
+   */
+  @Test
+  public void testImpliedPrivilegesWithGrant() throws Exception {
+    // setup db objects needed by the test
+    Connection connection = context.createConnection(ADMIN1);
+    Statement statement = context.createStatement(connection);
+
+    statement.execute("DROP DATABASE IF EXISTS db_1 CASCADE");
+    statement.execute("CREATE DATABASE db_1");
+
+    statement.execute("CREATE ROLE role1");
+    statement
+        .execute("GRANT ALL ON DATABASE db_1 TO ROLE role1 WITH GRANT OPTION");
+    statement.execute("GRANT ROLE role1 TO GROUP " + USERGROUP1);
+
+    statement.execute("CREATE ROLE role2");
+    statement.execute("GRANT ROLE role2 TO GROUP " + USERGROUP2);
+
+    statement.execute("CREATE ROLE role3_1");
+    statement.execute("GRANT ROLE role3_1 TO GROUP " + USERGROUP3);
+
+    statement.execute("CREATE ROLE role3_2");
+    statement.execute("GRANT ROLE role3_2 TO GROUP " + USERGROUP3);
+    connection.close();
+
+    connection = context.createConnection(USER1_1);
+    statement = context.createStatement(connection);
+
+    statement.execute("USE db_1");
+    statement.execute("CREATE TABLE foo (id int)");
+    // user1 with grant option of ALL on DB should be able grant ALL on TABLE
+    statement.execute("GRANT ALL ON TABLE foo TO ROLE role2");
+    // user1 with grant option of ALL on DB should be able grant SELECT on DB
+    statement.execute("GRANT SELECT ON DATABASE db_1 TO ROLE role3_1");
+    // user1 with grant option of ALL on DB should be able grant INSERT on 
TABLE
+    statement.execute("GRANT INSERT ON TABLE foo TO ROLE role3_2");
+    connection.close();
+
+    connection = context.createConnection(USER2_1);
+    statement = context.createStatement(connection);
+    statement.execute("USE db_1");
+    runSQLWithError(statement, "GRANT ALL ON TABLE foo TO ROLE role3_2",
+        HiveOperation.GRANT_PRIVILEGE, null, null, true);
+    connection.close();
+
+    connection = context.createConnection(ADMIN1);
+    statement = context.createStatement(connection);
+    statement.execute("use db_1");
+    verifySingleGrantWithGrantOption(statement,
+        "SHOW GRANT ROLE role2 ON TABLE foo", SHOW_GRANT_ROLE_TABLE_POSITION,
+        "foo");
+    verifySingleGrantWithGrantOption(statement,
+        "SHOW GRANT ROLE role3_1 ON DATABASE db_1",
+        SHOW_GRANT_ROLE_DB_POSITION, "db_1");
+    verifySingleGrantWithGrantOption(statement,
+        "SHOW GRANT ROLE role3_2 ON TABLE foo", SHOW_GRANT_ROLE_TABLE_POSITION,
+        "foo");
+
+    // test 'with grant option' status
+    verifySingleGrantWithGrantOption(statement, "show grant role role1",
+        SHOW_GRANT_ROLE_WITH_GRANT_POSITION, "true");
+    verifySingleGrantWithGrantOption(statement,
+        "SHOW GRANT ROLE role1 ON DATABASE db_1",
+        SHOW_GRANT_ROLE_WITH_GRANT_POSITION, "true");
+    verifySingleGrantWithGrantOption(statement,
+        "SHOW GRANT ROLE role1 ON TABLE foo",
+        SHOW_GRANT_ROLE_WITH_GRANT_POSITION, "true");
+    verifySingleGrantWithGrantOption(statement, "show grant role role2",
+        SHOW_GRANT_ROLE_WITH_GRANT_POSITION, "false");
+    verifySingleGrantWithGrantOption(statement,
+        "SHOW GRANT ROLE role2 ON TABLE foo",
+        SHOW_GRANT_ROLE_WITH_GRANT_POSITION, "false");
+    statement.close();
+    connection.close();
+  }
+
+  // run the given statement and verify that failure hook is invoked as 
expected
+  private void runSQLWithError(Statement statement, String sqlStr,
+      HiveOperation expectedOp, String dbName, String tableName,
+      boolean checkSentryAccessDeniedException) throws Exception {
+    // negative test case: non admin user can't create role
+    Assert.assertFalse(DummySentryOnFailureHook.invoked);
+    try {
+      statement.execute(sqlStr);
+      Assert.fail("Expected SQL exception for " + sqlStr);
+    } catch (SQLException e) {
+      verifyFailureHook(expectedOp, dbName, tableName, 
checkSentryAccessDeniedException);
+    } finally {
+      DummySentryOnFailureHook.invoked = false;
+    }
+
+  }
+
+  // run the given statement and verify that failure hook is invoked as 
expected
+  private void verifyFailureHook(HiveOperation expectedOp,
+      String dbName, String tableName, boolean 
checkSentryAccessDeniedException)
+      throws Exception {
+    if (!isInternalServer) {
+      return;
+    }
+
+    Assert.assertTrue(DummySentryOnFailureHook.invoked);
+    if (expectedOp != null) {
+      Assert.assertNotNull("Hive op is null for op: " + expectedOp, 
DummySentryOnFailureHook.hiveOp);
+      Assert.assertTrue(expectedOp.equals(DummySentryOnFailureHook.hiveOp));
+    }
+    if (checkSentryAccessDeniedException) {
+      Assert.assertTrue("Expected SentryDeniedException for op: " + expectedOp,
+          DummySentryOnFailureHook.exception.getCause() instanceof 
SentryAccessDeniedException);
+    }
+    if(tableName != null) {
+      Assert.assertNotNull("Table object is null for op: " + expectedOp, 
DummySentryOnFailureHook.table);
+      
Assert.assertTrue(tableName.equalsIgnoreCase(DummySentryOnFailureHook.table.getName()));
+    }
+    if(dbName != null) {
+      Assert.assertNotNull("Database object is null for op: " + expectedOp, 
DummySentryOnFailureHook.db);
+      
Assert.assertTrue(dbName.equalsIgnoreCase(DummySentryOnFailureHook.db.getName()));
+    }
+  }
+
+  // verify the expected object name at specific position in the SHOW GRANT 
result
+  private void verifySingleGrantWithGrantOption(Statement statetment,
+      String statementSql, int dbObjectPosition, String dbObjectName)
+      throws Exception {
+    ResultSet res = statetment.executeQuery(statementSql);
+    Assert.assertTrue(res.next());
+    Assert.assertEquals(dbObjectName, res.getString(dbObjectPosition));
+    res.close();
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/sentry/blob/bfb354f2/sentry-tests/sentry-tests-hive-v2/src/test/java/org/apache/sentry/tests/e2e/dbprovider/TestPrivilegeWithHAGrantOption.java
----------------------------------------------------------------------
diff --git 
a/sentry-tests/sentry-tests-hive-v2/src/test/java/org/apache/sentry/tests/e2e/dbprovider/TestPrivilegeWithHAGrantOption.java
 
b/sentry-tests/sentry-tests-hive-v2/src/test/java/org/apache/sentry/tests/e2e/dbprovider/TestPrivilegeWithHAGrantOption.java
new file mode 100644
index 0000000..d837a85
--- /dev/null
+++ 
b/sentry-tests/sentry-tests-hive-v2/src/test/java/org/apache/sentry/tests/e2e/dbprovider/TestPrivilegeWithHAGrantOption.java
@@ -0,0 +1,161 @@
+/*
+ * 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.sentry.tests.e2e.dbprovider;
+
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.HashMap;
+
+import org.junit.Assert;
+
+import org.apache.hadoop.hive.ql.plan.HiveOperation;
+import org.apache.sentry.binding.hive.conf.HiveAuthzConf;
+import org.apache.sentry.provider.db.SentryAccessDeniedException;
+import org.apache.sentry.tests.e2e.hive.DummySentryOnFailureHook;
+import org.apache.sentry.tests.e2e.hive.hiveserver.HiveServerFactory;
+import org.junit.Assume;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+public class TestPrivilegeWithHAGrantOption extends AbstractTestWithDbProvider 
{
+
+  @BeforeClass
+  public static void setup() throws Exception {
+    haEnabled = true;
+    properties = new HashMap<String, String>();
+    properties.put(HiveAuthzConf.AuthzConfVars.AUTHZ_ONFAILURE_HOOKS.getVar(),
+        DummySentryOnFailureHook.class.getName());
+    createContext();
+    DummySentryOnFailureHook.invoked = false;
+
+    // Do not run these tests if run with external HiveServer2
+    // This test checks for a static member, which will not
+    // be set if HiveServer2 and the test run in different JVMs
+    String hiveServer2Type = System
+        .getProperty(HiveServerFactory.HIVESERVER2_TYPE);
+    if(hiveServer2Type != null) {
+      Assume.assumeTrue(HiveServerFactory.isInternalServer(
+          HiveServerFactory.HiveServer2Type.valueOf(hiveServer2Type.trim())));
+    }
+  }
+
+  /*
+   * Admin grant DB_1 user1 without grant option, grant user3 with grant 
option,
+   * user1 tries to grant it to user2, but failed.
+   * user3 can grant it to user2.
+   * user1 tries to revoke, but failed.
+   * user3 tries to revoke user2, user3 and user1, user3 revoke user1 will 
failed.
+   * permissions for DB_1.
+   */
+  @Test
+  public void testOnGrantPrivilege() throws Exception {
+
+    // setup db objects needed by the test
+    Connection connection = context.createConnection(ADMIN1);
+    Statement statement = context.createStatement(connection);
+    statement.execute("CREATE ROLE admin_role");
+    statement.execute("GRANT ALL ON SERVER "
+        + HiveServerFactory.DEFAULT_AUTHZ_SERVER_NAME + " TO ROLE admin_role");
+    statement.execute("GRANT ROLE admin_role TO GROUP " + ADMINGROUP);
+    statement.execute("DROP DATABASE IF EXISTS db_1 CASCADE");
+    statement.execute("DROP DATABASE IF EXISTS db_2 CASCADE");
+    statement.execute("CREATE DATABASE db_1");
+    shutdownAllSentryService();
+    startSentryService(1);
+    statement.execute("CREATE ROLE group1_role");
+    statement.execute("GRANT ALL ON DATABASE db_1 TO ROLE group1_role");
+    statement.execute("GRANT ROLE group1_role TO GROUP " + USERGROUP1);
+    statement.execute("CREATE ROLE group3_grant_role");
+    shutdownAllSentryService();
+    startSentryService(1);
+    statement.execute("GRANT ALL ON DATABASE db_1 TO ROLE group3_grant_role 
WITH GRANT OPTION");
+    statement.execute("GRANT ROLE group3_grant_role TO GROUP " + USERGROUP3);
+    shutdownAllSentryService();
+    startSentryService(1);
+    statement.execute("CREATE ROLE group2_role");
+    statement.execute("GRANT ROLE group2_role TO GROUP " + USERGROUP2);
+
+    connection.close();
+
+    connection = context.createConnection(USER1_1);
+    statement = context.createStatement(connection);
+
+    statement.execute("USE db_1");
+    statement.execute("CREATE TABLE foo (id int)");
+    verifyFailureHook(statement,"GRANT ALL ON DATABASE db_1 TO ROLE 
group2_role",HiveOperation.GRANT_PRIVILEGE,null,null,true);
+    verifyFailureHook(statement,"GRANT ALL ON DATABASE db_1 TO ROLE 
group2_role WITH GRANT OPTION",HiveOperation.GRANT_PRIVILEGE,null,null,true);
+    connection.close();
+
+    connection = context.createConnection(USER3_1);
+    shutdownAllSentryService();
+    startSentryService(1);
+    statement = context.createStatement(connection);
+    statement.execute("GRANT ALL ON DATABASE db_1 TO ROLE group2_role");
+    connection.close();
+
+    connection = context.createConnection(USER1_1);
+    statement = context.createStatement(connection);
+    verifyFailureHook(statement,"REVOKE ALL ON Database db_1 FROM ROLE 
admin_role",HiveOperation.REVOKE_PRIVILEGE,null,null,true);
+    shutdownAllSentryService();
+    startSentryService(1);
+    verifyFailureHook(statement,"REVOKE ALL ON Database db_1 FROM ROLE 
group2_role",HiveOperation.REVOKE_PRIVILEGE,null,null,true);
+    verifyFailureHook(statement,"REVOKE ALL ON Database db_1 FROM ROLE 
group3_grant_role",HiveOperation.REVOKE_PRIVILEGE,null,null,true);
+    connection.close();
+
+    connection = context.createConnection(USER3_1);
+    statement = context.createStatement(connection);
+    statement.execute("REVOKE ALL ON Database db_1 FROM ROLE group2_role");
+    statement.execute("REVOKE ALL ON Database db_1 FROM ROLE 
group3_grant_role");
+    verifyFailureHook(statement,"REVOKE ALL ON Database db_1 FROM ROLE 
group1_role",HiveOperation.REVOKE_PRIVILEGE,null,null,true);
+
+    connection.close();
+    context.close();
+  }
+
+  // run the given statement and verify that failure hook is invoked as 
expected
+  private void verifyFailureHook(Statement statement, String sqlStr, 
HiveOperation expectedOp,
+       String dbName, String tableName, boolean 
checkSentryAccessDeniedException) throws Exception {
+    // negative test case: non admin user can't create role
+    Assert.assertFalse(DummySentryOnFailureHook.invoked);
+    try {
+      statement.execute(sqlStr);
+      Assert.fail("Expected SQL exception for " + sqlStr);
+    } catch (SQLException e) {
+      Assert.assertTrue(DummySentryOnFailureHook.invoked);
+    } finally {
+      DummySentryOnFailureHook.invoked = false;
+    }
+    if (expectedOp != null) {
+      Assert.assertNotNull("Hive op is null for op: " + expectedOp, 
DummySentryOnFailureHook.hiveOp);
+      Assert.assertTrue(expectedOp.equals(DummySentryOnFailureHook.hiveOp));
+    }
+    if (checkSentryAccessDeniedException) {
+      Assert.assertTrue("Expected SentryDeniedException for op: " + expectedOp,
+          DummySentryOnFailureHook.exception.getCause() instanceof 
SentryAccessDeniedException);
+    }
+    if(tableName != null) {
+      Assert.assertNotNull("Table object is null for op: " + expectedOp, 
DummySentryOnFailureHook.table);
+      
Assert.assertTrue(tableName.equalsIgnoreCase(DummySentryOnFailureHook.table.getName()));
+    }
+    if(dbName != null) {
+      Assert.assertNotNull("Database object is null for op: " + expectedOp, 
DummySentryOnFailureHook.db);
+      
Assert.assertTrue(dbName.equalsIgnoreCase(DummySentryOnFailureHook.db.getName()));
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/sentry/blob/bfb354f2/sentry-tests/sentry-tests-hive-v2/src/test/java/org/apache/sentry/tests/e2e/ha/TestHaEnd2End.java
----------------------------------------------------------------------
diff --git 
a/sentry-tests/sentry-tests-hive-v2/src/test/java/org/apache/sentry/tests/e2e/ha/TestHaEnd2End.java
 
b/sentry-tests/sentry-tests-hive-v2/src/test/java/org/apache/sentry/tests/e2e/ha/TestHaEnd2End.java
new file mode 100644
index 0000000..6ad70cf
--- /dev/null
+++ 
b/sentry-tests/sentry-tests-hive-v2/src/test/java/org/apache/sentry/tests/e2e/ha/TestHaEnd2End.java
@@ -0,0 +1,171 @@
+/**
+ * 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.sentry.tests.e2e.ha;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.sql.Connection;
+import java.sql.ResultSet;
+import java.sql.Statement;
+
+import org.apache.sentry.provider.db.SentryAccessDeniedException;
+import org.apache.sentry.provider.file.PolicyFile;
+import org.apache.sentry.service.thrift.HAClientInvocationHandler;
+import org.apache.sentry.tests.e2e.hive.AbstractTestWithStaticConfiguration;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import com.google.common.io.Resources;
+
+/**
+ * End2End tests with Sentry service HA enabled.
+ */
+public class TestHaEnd2End extends AbstractTestWithStaticConfiguration {
+
+  private final String SINGLE_TYPE_DATA_FILE_NAME = "kv1.dat";
+  private File dataFile;
+
+  @BeforeClass
+  public static void setupTestStaticConfiguration() throws Exception {
+    useSentryService = true;
+    enableSentryHA = true;
+    AbstractTestWithStaticConfiguration.setupTestStaticConfiguration();
+  }
+
+  @Override
+  @Before
+  public void setup() throws Exception {
+    super.setupAdmin();
+    super.setup();
+    dataFile = new File(dataDir, SINGLE_TYPE_DATA_FILE_NAME);
+    FileOutputStream to = new FileOutputStream(dataFile);
+    Resources.copy(Resources.getResource(SINGLE_TYPE_DATA_FILE_NAME), to);
+    to.close();
+    PolicyFile.setAdminOnServer1(ADMINGROUP);
+  }
+
+  /**
+   * Basic test with two Sentry service running.
+   * @throws Exception
+   */
+  @Test
+  public void testBasic() throws Exception {
+    Connection connection = context.createConnection(ADMIN1);
+    Statement statement = context.createStatement(connection);
+    statement.execute("CREATE TABLE t1 (c1 string)");
+    statement.execute("CREATE ROLE user_role");
+    statement.execute("GRANT SELECT ON TABLE t1 TO ROLE user_role");
+    statement.execute("GRANT ROLE user_role TO GROUP " + USERGROUP1);
+    statement.close();
+    connection.close();
+    connection = context.createConnection(USER1_1);
+    statement = context.createStatement(connection);
+    context.assertSentryException(statement, "CREATE ROLE r2",
+        SentryAccessDeniedException.class.getSimpleName());
+    // test default of ALL
+    statement.execute("SELECT * FROM t1");
+    // test a specific role
+    statement.execute("SET ROLE user_role");
+    statement.execute("SELECT * FROM t1");
+
+    // test ALL
+    statement.execute("SET ROLE ALL");
+    statement.execute("SELECT * FROM t1");
+    statement.close();
+    connection.close();
+
+    // cleanup
+    connection = context.createConnection(ADMIN1);
+    statement = context.createStatement(connection);
+    statement.execute("DROP ROLE user_role");
+    statement.close();
+    connection.close();
+  }
+
+  /**
+   * Test service failover. Run Sentry operations with shutting down one or 
more
+   * of the services.
+   * @throws Exception
+   */
+  @Test
+  public void testFailover() throws Exception {
+    String roleName1 = "test_role_1";
+    String roleName2 = "test_role_2";
+    String roleName3 = "test_role_3";
+
+    dropDb(ADMIN1, DB1);
+    createDb(ADMIN1, DB1);
+    createTable(ADMIN1, DB1, dataFile, TBL1);
+
+    Connection adminCon = context.createConnection(ADMIN1);
+    Statement adminStmt = context.createStatement(adminCon);
+    // access the new databases
+    adminStmt.execute("use " + DB1);
+
+    // stop server1 and verify sentry continues to work
+    getSentrySrv().stop(0);
+    adminStmt.execute("CREATE ROLE " + roleName1);
+    verifyRoleExists(adminStmt, roleName1);
+
+    // restart server1 and stop server2
+    getSentrySrv().start(0);
+    getSentrySrv().stop(1);
+    adminStmt.execute("CREATE ROLE " + roleName2);
+    verifyRoleExists(adminStmt, roleName2);
+
+    // stop both servers and verify it fails
+    getSentrySrv().stop(0);
+    getSentrySrv().stop(1);
+    context.assertAuthzExecHookException(adminStmt, "CREATE ROLE " + roleName3,
+        HAClientInvocationHandler.SENTRY_HA_ERROR_MESSAGE);
+
+    getSentrySrv().start(0);
+    getSentrySrv().start(1);
+    adminStmt.execute("CREATE ROLE " + roleName3);
+    verifyRoleExists(adminStmt, roleName3);
+
+    // cleanup
+
+    dropDb(ADMIN1, DB1);
+    adminStmt.execute("DROP ROLE " + roleName1);
+    adminStmt.execute("DROP ROLE " + roleName2);
+    adminStmt.execute("DROP ROLE " + roleName3);
+    adminStmt.close();
+    adminCon.close();
+
+  }
+
+  private void verifyRoleExists(Statement statement, String roleName)
+      throws Exception {
+    ResultSet resultSet = null;
+    try {
+      resultSet = statement.executeQuery("SHOW ROLES ");
+      while (resultSet.next()) {
+        if (roleName.equalsIgnoreCase(resultSet.getString(1))) {
+          return;
+        }
+      }
+      throw new Exception("Role " + roleName + " does not exist");
+    } finally {
+      if (resultSet != null) {
+        resultSet.close();
+      }
+    }
+  }
+}

Reply via email to