You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sentry.apache.org by ls...@apache.org on 2015/08/05 09:58:09 UTC

incubator-sentry git commit: SENTRY-829: Fix Sentry Hive Test Failures in TestDbCrossDb class when running E2E (Anne Yu via Lenni Kuff)

Repository: incubator-sentry
Updated Branches:
  refs/heads/master 1e26d56ef -> 19bbaacd1


SENTRY-829: Fix Sentry Hive Test Failures in TestDbCrossDb class when running E2E (Anne Yu via Lenni Kuff)


Project: http://git-wip-us.apache.org/repos/asf/incubator-sentry/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-sentry/commit/19bbaacd
Tree: http://git-wip-us.apache.org/repos/asf/incubator-sentry/tree/19bbaacd
Diff: http://git-wip-us.apache.org/repos/asf/incubator-sentry/diff/19bbaacd

Branch: refs/heads/master
Commit: 19bbaacd1de4d3e7e23083a85ac8466f3e26fab9
Parents: 1e26d56
Author: Lenni Kuff <ls...@cloudera.com>
Authored: Wed Aug 5 00:57:50 2015 -0700
Committer: Lenni Kuff <ls...@cloudera.com>
Committed: Wed Aug 5 00:57:50 2015 -0700

----------------------------------------------------------------------
 .../e2e/dbprovider/TestDatabaseProvider.java    |   3 +-
 .../tests/e2e/dbprovider/TestDbCrossDbOps.java  |   4 +-
 .../AbstractTestWithStaticConfiguration.java    |  65 +++-
 .../tests/e2e/hive/PrivilegeResultSet.java      | 124 ++++++
 .../sentry/tests/e2e/hive/TestCrossDbOps.java   | 380 +++++++++++++------
 .../tests/e2e/hive/TestUserManagement.java      |   2 +-
 ...actMetastoreTestWithStaticConfiguration.java |   7 +-
 7 files changed, 448 insertions(+), 137 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/19bbaacd/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/dbprovider/TestDatabaseProvider.java
----------------------------------------------------------------------
diff --git a/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/dbprovider/TestDatabaseProvider.java b/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/dbprovider/TestDatabaseProvider.java
index 7df32fb..87b281b 100644
--- a/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/dbprovider/TestDatabaseProvider.java
+++ b/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/dbprovider/TestDatabaseProvider.java
@@ -52,6 +52,7 @@ public class TestDatabaseProvider extends AbstractTestWithStaticConfiguration {
   @BeforeClass
   public static void setupTestStaticConfiguration() throws Exception{
     useSentryService = true;
+    clearDbAfterPerTest = false;
     AbstractTestWithStaticConfiguration.setupTestStaticConfiguration();
   }
 
@@ -61,7 +62,7 @@ public class TestDatabaseProvider extends AbstractTestWithStaticConfiguration {
    */
   @Override
   @After
-  public void clearDB() throws Exception {
+  public void clearAfterPerTest() throws Exception {
     Connection connection;
     Statement statement;
     connection = context.createConnection(ADMIN1);

http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/19bbaacd/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/dbprovider/TestDbCrossDbOps.java
----------------------------------------------------------------------
diff --git a/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/dbprovider/TestDbCrossDbOps.java b/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/dbprovider/TestDbCrossDbOps.java
index 719dddf..8d23ea6 100644
--- a/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/dbprovider/TestDbCrossDbOps.java
+++ b/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/dbprovider/TestDbCrossDbOps.java
@@ -31,11 +31,13 @@ public class TestDbCrossDbOps extends TestCrossDbOps {
   public void setup() throws Exception {
     super.setupAdmin();
     super.setup();
+    clearAll(true);
   }
   @BeforeClass
   public static void setupTestStaticConfiguration() throws Exception{
-    //policy_on_hdfs = true;
     useSentryService = true;
+    clearDbAfterPerTest = true;
+    clearDbBeforePerTest = true;
     AbstractTestWithStaticConfiguration.setupTestStaticConfiguration();
   }
 }

http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/19bbaacd/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/AbstractTestWithStaticConfiguration.java
----------------------------------------------------------------------
diff --git a/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/AbstractTestWithStaticConfiguration.java b/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/AbstractTestWithStaticConfiguration.java
index 2a1c9f0..16695f5 100644
--- a/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/AbstractTestWithStaticConfiguration.java
+++ b/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/AbstractTestWithStaticConfiguration.java
@@ -32,7 +32,6 @@ import java.util.Arrays;
 import java.util.Collection;
 import java.util.List;
 import java.util.Map;
-import java.util.concurrent.TimeoutException;
 
 import junit.framework.Assert;
 
@@ -121,6 +120,7 @@ public abstract class AbstractTestWithStaticConfiguration {
   protected static boolean enableHiveConcurrency = false;
   // indicate if the database need to be clear for every test case in one test class
   protected static boolean clearDbAfterPerTest = true;
+  protected static boolean clearDbBeforePerTest = false;
 
   protected static File baseDir;
   protected static File logDir;
@@ -138,7 +138,6 @@ public abstract class AbstractTestWithStaticConfiguration {
   protected static Context context;
   protected final String semanticException = "SemanticException No valid privileges";
 
-
   public static void createContext() throws Exception {
     context = new Context(hiveServer, fileSystem,
         baseDir, confDir, dataDir, policyFileLocation);
@@ -272,8 +271,10 @@ public abstract class AbstractTestWithStaticConfiguration {
   protected static void writePolicyFile(PolicyFile policyFile) throws Exception {
     policyFile.write(context.getPolicyFile());
     if(policyOnHdfs) {
+      LOGGER.info("use policy file on HDFS");
       dfs.writePolicyFile(context.getPolicyFile());
     } else if(useSentryService) {
+      LOGGER.info("use sentry service, granting permissions");
       grantPermissions(policyFile);
     }
   }
@@ -286,16 +287,20 @@ public abstract class AbstractTestWithStaticConfiguration {
     ResultSet resultSet = statement.executeQuery("SHOW ROLES");
     while( resultSet.next()) {
       Statement statement1 = context.createStatement(connection);
-      if(!resultSet.getString(1).equalsIgnoreCase("admin_role")) {
-        statement1.execute("DROP ROLE " + resultSet.getString(1));
+      String roleName = resultSet.getString(1).trim();
+      if(!roleName.equalsIgnoreCase("admin_role")) {
+        LOGGER.info("Dropping role :" + roleName);
+        statement1.execute("DROP ROLE " + roleName);
       }
     }
 
     // create roles and add privileges
     for (Map.Entry<String, Collection<String>> roleEntry : policyFile.getRolesToPermissions()
         .asMap().entrySet()) {
+      String roleName = roleEntry.getKey();
       if(!roleEntry.getKey().equalsIgnoreCase("admin_role")){
-        statement.execute("CREATE ROLE " + roleEntry.getKey());
+        LOGGER.info("Creating role : " + roleName);
+        statement.execute("CREATE ROLE " + roleName);
         for (String privilege : roleEntry.getValue()) {
           addPrivilege(roleEntry.getKey(), privilege, statement);
         }
@@ -306,7 +311,9 @@ public abstract class AbstractTestWithStaticConfiguration {
         .entrySet()) {
       for (String roleNames : groupEntry.getValue()) {
         for (String roleName : roleNames.split(",")) {
-          statement.execute("GRANT ROLE " + roleName + " TO GROUP " + groupEntry.getKey());
+          String sql = "GRANT ROLE " + roleName + " TO GROUP " + groupEntry.getKey();
+          LOGGER.info("Granting role to group: " + sql);
+          statement.execute(sql);
         }
       }
     }
@@ -346,21 +353,31 @@ public abstract class AbstractTestWithStaticConfiguration {
         }
       }
 
+      LOGGER.info("addPrivilege");
       if (columnName != null) {
         statement.execute("CREATE DATABASE IF NOT EXISTS " + dbName);
         statement.execute("USE " + dbName);
-        statement.execute("GRANT " + action + " ( " + columnName + " ) ON TABLE " + tableName + " TO ROLE " + roleName);
+        String sql = "GRANT " + action + " ( " + columnName + " ) ON TABLE " + tableName + " TO ROLE " + roleName;
+        LOGGER.info("Granting column level privilege: database = " + dbName + ", sql = " + sql);
+        statement.execute(sql);
       } else if (tableName != null) {
         statement.execute("CREATE DATABASE IF NOT EXISTS " + dbName);
         statement.execute("USE " + dbName);
-        statement.execute("GRANT " + action + " ON TABLE " + tableName + " TO ROLE " + roleName);
+        String sql = "GRANT " + action + " ON TABLE " + tableName + " TO ROLE " + roleName;
+        LOGGER.info("Granting table level privilege:  database = " + dbName + ", sql = " + sql);
+        statement.execute(sql);
       } else if (dbName != null) {
-        statement.execute("GRANT " + action + " ON DATABASE " + dbName + " TO ROLE " + roleName);
+        String sql = "GRANT " + action + " ON DATABASE " + dbName + " TO ROLE " + roleName;
+        LOGGER.info("Granting db level privilege: " + sql);
+        statement.execute(sql);
       } else if (uriPath != null) {
-        statement.execute("GRANT " + action + " ON URI '" + uriPath + "' TO ROLE " + roleName);//ALL?
+        String sql = "GRANT " + action + " ON URI '" + uriPath + "' TO ROLE " + roleName;
+        LOGGER.info("Granting uri level privilege: " + sql);
+        statement.execute(sql);//ALL?
       } else if (serverName != null) {
-        statement.execute("GRANT ALL ON SERVER " + serverName + " TO ROLE " + roleName);
-        ;
+        String sql = "GRANT ALL ON SERVER " + serverName + " TO ROLE " + roleName;
+        LOGGER.info("Granting server level privilege: " + sql);
+        statement.execute(sql);
       }
     }
   }
@@ -429,16 +446,30 @@ public abstract class AbstractTestWithStaticConfiguration {
 
   @Before
   public void setup() throws Exception{
+    LOGGER.info("Before per test run setup");
     dfs.createBaseDir();
+    if (clearDbBeforePerTest) {
+      LOGGER.info("Before per test run clean up");
+      clearAll(true);
+    }
   }
 
   @After
-  public void clearDB() throws Exception {
+  public void clearAfterPerTest() throws Exception {
+    LOGGER.info("After per test run clearAfterPerTest");
+    if (clearDbAfterPerTest) {
+      clearAll(true);
+    }
+  }
+
+  protected void clearAll(boolean clearDb) throws Exception {
+    LOGGER.info("About to run clearAll");
     ResultSet resultSet;
     Connection connection = context.createConnection(ADMIN1);
     Statement statement = context.createStatement(connection);
 
-    if (clearDbAfterPerTest) {
+    if (clearDb) {
+      LOGGER.info("About to clear all databases and default database tables");
       String[] dbs = { DB1, DB2, DB3 };
       for (String db : dbs) {
         statement.execute("DROP DATABASE if exists " + db + " CASCADE");
@@ -453,10 +484,14 @@ public abstract class AbstractTestWithStaticConfiguration {
     }
 
     if(useSentryService) {
+      LOGGER.info("About to clear all roles");
       resultSet = statement.executeQuery("SHOW roles");
       List<String> roles = new ArrayList<String>();
       while (resultSet.next()) {
-        roles.add(resultSet.getString(1));
+        String roleName = resultSet.getString(1);
+        if (!roleName.toLowerCase().contains("admin")) {
+          roles.add(roleName);
+        }
       }
       for (String role : roles) {
         statement.execute("DROP Role " + role);

http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/19bbaacd/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/PrivilegeResultSet.java
----------------------------------------------------------------------
diff --git a/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/PrivilegeResultSet.java b/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/PrivilegeResultSet.java
new file mode 100644
index 0000000..cee05a0
--- /dev/null
+++ b/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/PrivilegeResultSet.java
@@ -0,0 +1,124 @@
+/*
+ * 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.hive;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.sql.ResultSet;
+import java.sql.ResultSetMetaData;
+import java.sql.Statement;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * This class holds ResultSet after query sentry privileges
+ * header: contain result header information, which is a array of string
+ * privilegeResultSet: contain privilege results from query
+ */
+public class PrivilegeResultSet {
+    private static final Logger LOGGER = LoggerFactory
+            .getLogger(PrivilegeResultSet.class);
+
+    protected int colNum = 0;
+    protected List<String> header;
+    protected List<ArrayList<String>> privilegeResultSet;
+
+    public PrivilegeResultSet() {
+        header = new ArrayList<String>();
+        privilegeResultSet = new ArrayList<ArrayList<String>>();
+    }
+
+    public PrivilegeResultSet(Statement stmt, String query) {
+        LOGGER.info("Getting result set for " + query);
+        this.header = new ArrayList<String>();
+        this.privilegeResultSet = new ArrayList<ArrayList<String>>();
+        ResultSet rs = null;
+        try {
+            rs = stmt.executeQuery(query);
+            ResultSetMetaData rsmd = rs.getMetaData();
+            this.colNum = rsmd.getColumnCount();
+            for (int i = 1; i <= this.colNum; i++) {
+                this.header.add(rsmd.getColumnName(i).trim());
+            }
+            while (rs.next()) {
+                ArrayList<String> row = new ArrayList<String>();
+                for (int i = 1; i <= colNum; i++) {
+                    row.add(rs.getString(i).trim());
+                }
+                this.privilegeResultSet.add(row);
+            }
+        } catch (Exception ex) {
+            LOGGER.info("Exception when executing query: " + ex);
+        } finally {
+            try {
+                rs.close();
+            } catch (Exception ex) {
+                LOGGER.error("failed to close result set: " + ex.getStackTrace());
+            }
+        }
+    }
+
+    protected List<ArrayList<String>> getResultSet() {
+        return this.privilegeResultSet;
+    }
+
+    protected List<String> getHeader() {
+        return this.header;
+    }
+
+    /**
+     * Given a column name, validate if one of its values equals to given colVal
+     */
+    protected boolean verifyResultSetColumn(String colName, String colVal) {
+        for (int i = 0; i < this.colNum; i ++) {
+            if (this.header.get(i).equalsIgnoreCase(colName)) {
+                for (int j = 0; j < this.privilegeResultSet.size(); j ++) {
+                    if (this.privilegeResultSet.get(j).get(i).equalsIgnoreCase(colVal)) {
+                        LOGGER.info("Found " + colName + " contains a value = " + colVal);
+                        return true;
+                    }
+                }
+            }
+        }
+        LOGGER.error("Failed to detect " + colName + " contains a value = " + colVal);
+        return false;
+    }
+
+    /**
+     * Unmarshall ResultSet into a string
+     */
+    @Override
+    public String toString() {
+        String prettyPrintString = new String("\n");
+        for (String h : this.header) {
+            prettyPrintString += h + ",";
+        }
+        prettyPrintString += "\n";
+        for (ArrayList<String> row : this.privilegeResultSet) {
+            for (String val : row) {
+                if (val.isEmpty()) {
+                    val = "null";
+                }
+                prettyPrintString += val + ",";
+            }
+            prettyPrintString += "\n";
+        }
+        return prettyPrintString;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/19bbaacd/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/TestCrossDbOps.java
----------------------------------------------------------------------
diff --git a/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/TestCrossDbOps.java b/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/TestCrossDbOps.java
index 38c361c..5b1e2b8 100644
--- a/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/TestCrossDbOps.java
+++ b/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/TestCrossDbOps.java
@@ -17,12 +17,15 @@
 
 package org.apache.sentry.tests.e2e.hive;
 
+import org.apache.sentry.provider.file.PolicyFile;
+import static org.junit.Assert.assertEquals;
 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.ResultSetMetaData;
 import java.sql.SQLException;
 import java.sql.Statement;
 import java.util.ArrayList;
@@ -30,16 +33,20 @@ import java.util.List;
 
 import junit.framework.Assert;
 
-import org.apache.sentry.provider.file.PolicyFile;
 import org.junit.Before;
 import org.junit.BeforeClass;
 import org.junit.Test;
 
 import com.google.common.io.Resources;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 /* Tests privileges at table scope with cross database access */
 
 public class TestCrossDbOps extends AbstractTestWithStaticConfiguration {
+  private static final Logger LOGGER = LoggerFactory
+          .getLogger(TestCrossDbOps.class);
+
   private File dataFile;
   private PolicyFile policyFile;
   private String loadData;
@@ -47,6 +54,8 @@ public class TestCrossDbOps extends AbstractTestWithStaticConfiguration {
   @BeforeClass
   public static void setupTestStaticConfiguration() throws Exception{
     policyOnHdfs = true;
+    clearDbAfterPerTest = true;
+    clearDbBeforePerTest = true;
     AbstractTestWithStaticConfiguration.setupTestStaticConfiguration();
   }
 
@@ -59,8 +68,20 @@ public class TestCrossDbOps extends AbstractTestWithStaticConfiguration {
     Resources.copy(Resources.getResource(SINGLE_TYPE_DATA_FILE_NAME), to);
     to.close();
     policyFile = PolicyFile.setAdminOnServer1(ADMINGROUP);
+    // Precreate policy file
+    policyFile.setUserGroupMapping(StaticUserGroup.getStaticMapping());
+    writePolicyFile(policyFile);
     loadData = "server=server1->uri=file://" + dataFile.getPath();
+    // debug
+    LOGGER.info("setMetastoreListener = " + String.valueOf(setMetastoreListener));
+    clearAll(true);
+  }
 
+  private void validateReturnedResult(List<String> expected, List<String> returned) {
+    for (String obj : expected) {
+      assertTrue("expected " + obj + " not found in the " + returned.toString(),
+              returned.contains(obj));
+    }
   }
 
   /*
@@ -71,24 +92,106 @@ public class TestCrossDbOps extends AbstractTestWithStaticConfiguration {
    */
   @Test
   public void testShowDatabasesAndShowTables() throws Exception {
-    // edit policy file
+    // admin create two databases
+    Connection connection = context.createConnection(ADMIN1);
+    Statement statement = context.createStatement(connection);
+    statement.execute("CREATE DATABASE " + DB1);
+    statement.execute("CREATE DATABASE " + DB2);
+    statement.execute("USE " + DB1);
+    statement.execute("CREATE TABLE TAB1(id int)");
+    statement.executeQuery("SHOW TABLES");
+    statement.execute("USE " + DB2);
+    statement.execute("CREATE TABLE TAB2(id int)");
+    statement.execute("CREATE TABLE TAB3(id int)");
+
+    // load policy file and grant role with privileges
     policyFile
-        .addRolesToGroup(USERGROUP1, "select_tab1", "insert_tab2")
-        .addRolesToGroup(USERGROUP2, "select_tab3")
-        .addPermissionsToRole("select_tab1",  "server=server1->db=" + DB1 + "->table=tab1->action=select")
-        .addPermissionsToRole("select_tab3", "server=server1->db=" + DB2 + "->table=tab3->action=select")
-        .addPermissionsToRole("insert_tab2", "server=server1->db=" + DB2 + "->table=tab2->action=insert")
-        .setUserGroupMapping(StaticUserGroup.getStaticMapping());
+            .addRolesToGroup(USERGROUP1, "select_tab1", "insert_tab2")
+            .addRolesToGroup(USERGROUP2, "select_tab3")
+            .addPermissionsToRole("select_tab1",  "server=server1->db=" + DB1 + "->table=tab1->action=select")
+            .addPermissionsToRole("select_tab3", "server=server1->db=" + DB2 + "->table=tab3->action=select")
+            .addPermissionsToRole("insert_tab2", "server=server1->db=" + DB2 + "->table=tab2->action=insert")
+            .setUserGroupMapping(StaticUserGroup.getStaticMapping());
     writePolicyFile(policyFile);
 
+    // show grant to validate roles and privileges
+    if(useSentryService) {
+      PrivilegeResultSet pRset = new PrivilegeResultSet(statement, "SHOW GRANT ROLE select_tab1 ON DATABASE " + DB1);
+      LOGGER.info("SHOW GRANT ROLE select_tab1 ON DATABASE " + DB1 + " : " + pRset.toString());
+      pRset.verifyResultSetColumn("database", DB1);
+      pRset.verifyResultSetColumn("table", "tab1");
+
+      pRset = new PrivilegeResultSet(statement, "SHOW GRANT ROLE insert_tab2 ON DATABASE " + DB2);
+      LOGGER.info("SHOW GRANT ROLE insert_tab2 ON DATABASE " + DB2 + " : " + pRset.toString());
+      pRset.verifyResultSetColumn("database", DB2);
+      pRset.verifyResultSetColumn("table", "tab2");
+
+      pRset = new PrivilegeResultSet(statement, "SHOW GRANT ROLE select_tab3 ON DATABASE " + DB2);
+      LOGGER.info("SHOW GRANT ROLE select_tab3 ON DATABASE " + DB2 + " : " + pRset.toString());
+      pRset.verifyResultSetColumn("database", DB2);
+      pRset.verifyResultSetColumn("table", "tab3");
+    }
+
+    // test show databases
+    // show databases shouldn't filter any of the dbs from the resultset
+    Connection conn = context.createConnection(USER1_1);
+    Statement stmt = context.createStatement(conn);
+    PrivilegeResultSet pRset = new PrivilegeResultSet(stmt, "SHOW DATABASES");
+    LOGGER.info("found databases :" + pRset.toString());
+    pRset.verifyResultSetColumn("database_name", DB1);
+    pRset.verifyResultSetColumn("database_name", DB2);
+
+    // test show tables
+    stmt.execute("USE " + DB1);
+    pRset = new PrivilegeResultSet(stmt, "SHOW TABLES");
+    LOGGER.info("found tables :" + pRset.toString());
+    pRset.verifyResultSetColumn("tab_name", "tab1");
+
+    stmt.execute("USE " + DB2);
+    pRset = new PrivilegeResultSet(stmt, "SHOW TABLES");
+    LOGGER.info("found tables :" + pRset.toString());
+    pRset.verifyResultSetColumn("tab_name", "tab2");
+
+    try {
+      stmt.close();
+      conn.close();
+    } catch (Exception ex) {
+      // nothing to do
+    }
+
+    // test show databases and show tables for user2_1
+    conn = context.createConnection(USER2_1);
+    stmt = context.createStatement(conn);
+
+    pRset = new PrivilegeResultSet(stmt, "SHOW DATABASES");
+    pRset.verifyResultSetColumn("database_name", DB2);
+
+    // test show tables
+    stmt.execute("USE " + DB2);
+    pRset = new PrivilegeResultSet(stmt, "SHOW TABLES");
+    pRset.verifyResultSetColumn("tab_name", "tab3");
+
+    try {
+      stmt.execute("USE " + DB1);
+      Assert.fail("Expected SQL exception");
+    } catch (SQLException e) {
+      context.verifyAuthzException(e);
+    }
+
+    context.close();
+  }
+
+  /*
+   * Admin creates DB_1, DB2, tables (tab_1 ) and (tab_2, tab_3) in DB_1 and
+   * DB_2 respectively. User user1 has select on DB_1.tab_1, insert on
+   * DB2.tab_2 User user2 has select on DB2.tab_3 Test show database and show
+   * tables for both user1 and user2
+   */
+  @Test
+  public void testJDBCGetSchemasAndGetTables() throws Exception {
     // admin create two databases
     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("DROP DATABASE IF EXISTS DB1 CASCADE");
-    statement.execute("DROP DATABASE IF EXISTS DB2 CASCADE");
-
     statement.execute("CREATE DATABASE " + DB1);
     statement.execute("CREATE DATABASE " + DB2);
     statement.execute("USE " + DB1);
@@ -98,89 +201,146 @@ public class TestCrossDbOps extends AbstractTestWithStaticConfiguration {
     statement.execute("CREATE TABLE TAB2(id int)");
     statement.execute("CREATE TABLE TAB3(id int)");
 
+    // edit policy file
+    policyFile.addRolesToGroup(USERGROUP1, "select_tab1", "insert_tab2")
+            .addRolesToGroup(USERGROUP2, "select_tab3")
+            .addPermissionsToRole("select_tab1", "server=server1->db=" + DB1 + "->table=tab1->action=select")
+            .addPermissionsToRole("select_tab3", "server=server1->db=" + DB2 + "->table=tab3->action=select")
+            .addPermissionsToRole("insert_tab2", "server=server1->db=" + DB2 + "->table=tab2->action=insert")
+            .setUserGroupMapping(StaticUserGroup.getStaticMapping());
+    writePolicyFile(policyFile);
+
     // test show databases
     // show databases shouldn't filter any of the dbs from the resultset
     Connection conn = context.createConnection(USER1_1);
     Statement stmt = context.createStatement(conn);
+    // test direct JDBC metadata API
     ResultSet res = stmt.executeQuery("SHOW DATABASES");
-    List<String> result = new ArrayList<String>();
-    result.add(DB1);
-    result.add(DB2);
-    result.add("default");
+    res = conn.getMetaData().getSchemas();
+    ResultSetMetaData resMeta = res.getMetaData();
+    assertEquals(2, resMeta.getColumnCount());
+    assertEquals("TABLE_SCHEM", resMeta.getColumnName(1));
+    assertEquals("TABLE_CATALOG", resMeta.getColumnName(2));
+
+    List<String> expectedResult = new ArrayList<String>();
+    List<String> returnedResult = new ArrayList<String>();
 
+    expectedResult.add(DB1);
+    expectedResult.add(DB2);
     while (res.next()) {
-      String dbName = res.getString(1);
-      assertTrue(dbName, result.remove(dbName));
+      returnedResult.add(res.getString(1).trim());
     }
-    assertTrue(result.toString(), result.isEmpty());
+    validateReturnedResult(expectedResult, returnedResult);
+    returnedResult.clear();
+    expectedResult.clear();
     res.close();
 
-    // test show tables
-    stmt.execute("USE " + DB1);
-    res = stmt.executeQuery("SHOW TABLES");
-    result.clear();
-    result.add("tab1");
+    // test direct JDBC metadata API
+    res = conn.getMetaData().getTables(null, DB1, "tab%", null);
+    expectedResult.add("tab1");
+    while (res.next()) {
+      returnedResult.add(res.getString(3).trim());
+    }
+    validateReturnedResult(expectedResult, returnedResult);
+    returnedResult.clear();
+    expectedResult.clear();
+    res.close();
 
+    // test direct JDBC metadata API
+    res = conn.getMetaData().getTables(null, DB2, "tab%", null);
+    expectedResult.add("tab2");
     while (res.next()) {
-      String tableName = res.getString(1);
-      assertTrue(tableName, result.remove(tableName));
+      returnedResult.add(res.getString(3).trim());
     }
-    assertTrue(result.toString(), result.isEmpty());
+    validateReturnedResult(expectedResult, returnedResult);
+    returnedResult.clear();
+    expectedResult.clear();
     res.close();
 
-    stmt.execute("USE " + DB2);
-    res = stmt.executeQuery("SHOW TABLES");
-    result.clear();
-    result.add("tab2");
+    res = conn.getMetaData().getTables(null, "DB%", "tab%", null);
+    expectedResult.add("tab2");
+    expectedResult.add("tab1");
+    while (res.next()) {
+      returnedResult.add(res.getString(3).trim());
+    }
+    validateReturnedResult(expectedResult, returnedResult);
+    returnedResult.clear();
+    expectedResult.clear();
+    res.close();
+
+    //test show columns
+    res = conn.getMetaData().getColumns(null, "DB%", "tab%","i%" );
+    expectedResult.add("id");
 
     while (res.next()) {
-      String tableName = res.getString(1);
-      assertTrue(tableName, result.remove(tableName));
+      returnedResult.add(res.getString(4).trim());
     }
-    assertTrue(result.toString(), result.isEmpty());
+    validateReturnedResult(expectedResult, returnedResult);
+    returnedResult.clear();
+    expectedResult.clear();
     res.close();
 
-    stmt.close();
     conn.close();
 
-    // test show databases and show tables for user2_1
+    // test show databases and show tables for user2
     conn = context.createConnection(USER2_1);
-    stmt = context.createStatement(conn);
-    res = stmt.executeQuery("SHOW DATABASES");
-    result.clear();
-    result.add(DB2);
-    result.add("default");
+
+    // test direct JDBC metadata API
+    res = conn.getMetaData().getSchemas();
+    resMeta = res.getMetaData();
+    assertEquals(2, resMeta.getColumnCount());
+    assertEquals("TABLE_SCHEM", resMeta.getColumnName(1));
+    assertEquals("TABLE_CATALOG", resMeta.getColumnName(2));
+
+    expectedResult.add(DB2);
+    expectedResult.add("default");
 
     while (res.next()) {
-      String dbName = res.getString(1);
-      assertTrue(dbName, result.remove(dbName));
+      returnedResult.add(res.getString(1).trim());
     }
-    assertTrue(result.toString(), result.isEmpty());
+    validateReturnedResult(expectedResult, returnedResult);
+    returnedResult.clear();
+    expectedResult.clear();
     res.close();
 
-    // test show tables
-    stmt.execute("USE " + DB2);
-    res = stmt.executeQuery("SHOW TABLES");
-    result.clear();
-    result.add("tab3");
+    // test JDBC direct API
+    res = conn.getMetaData().getTables(null, "DB%", "tab%", null);
+    expectedResult.add("tab3");
 
     while (res.next()) {
-      String tableName = res.getString(1);
-      assertTrue(tableName, result.remove(tableName));
+      returnedResult.add(res.getString(3).trim());
     }
-    assertTrue(result.toString(), result.isEmpty());
+    validateReturnedResult(expectedResult, returnedResult);
+    returnedResult.clear();
+    expectedResult.clear();
     res.close();
 
-    try {
-      stmt.execute("USE " + DB1);
-      Assert.fail("Expected SQL exception");
-    } catch (SQLException e) {
-      context.verifyAuthzException(e);
+
+    //test show columns
+    res = conn.getMetaData().getColumns(null, "DB%", "tab%","i%" );
+    expectedResult.add("id");
+
+    while (res.next()) {
+      returnedResult.add(res.getString(4).trim());
     }
-    context.close();
-  }
+    validateReturnedResult(expectedResult, returnedResult);
+    returnedResult.clear();
+    expectedResult.clear();
+    res.close();
 
+    //test show columns
+    res = conn.getMetaData().getColumns(null, DB1, "tab%","i%" );
 
+    while (res.next()) {
+      returnedResult.add(res.getString(4).trim());
+    }
+    validateReturnedResult(expectedResult, returnedResult);
+    returnedResult.clear();
+    expectedResult.clear();
+    res.close();
+
+    context.close();
+  }
 
   /**
    * 2.8 admin user create two database, DB_1, DB_2 admin grant all to USER1_1,
@@ -190,16 +350,16 @@ public class TestCrossDbOps extends AbstractTestWithStaticConfiguration {
    */
   @Test
   public void testDbPrivileges() throws Exception {
+    createDb(ADMIN1, DB1, DB2);
+
     // edit policy file
     policyFile.addRolesToGroup(USERGROUP1, "db1_all,db2_all, load_data")
-        .addPermissionsToRole("db1_all", "server=server1->db=" + DB1)
-        .addPermissionsToRole("db2_all", "server=server1->db=" + DB2)
-        .addPermissionsToRole("load_data", "server=server1->URI=file://" + dataFile.getPath())
-        .setUserGroupMapping(StaticUserGroup.getStaticMapping());
+            .addPermissionsToRole("db1_all", "server=server1->db=" + DB1)
+            .addPermissionsToRole("db2_all", "server=server1->db=" + DB2)
+            .addPermissionsToRole("load_data", "server=server1->URI=file://" + dataFile.getPath())
+            .setUserGroupMapping(StaticUserGroup.getStaticMapping());
     writePolicyFile(policyFile);
 
-    dropDb(ADMIN1, DB1, DB2);
-    createDb(ADMIN1, DB1, DB2);
     for (String user : new String[]{USER1_1, USER1_2}) {
       for (String dbName : new String[]{DB1, DB2}) {
         Connection userConn = context.createConnection(user);
@@ -225,12 +385,12 @@ public class TestCrossDbOps extends AbstractTestWithStaticConfiguration {
    */
   @Test
   public void testAdminDbPrivileges() throws Exception {
+    createDb(ADMIN1, DB1);
+
     policyFile
-        .setUserGroupMapping(StaticUserGroup.getStaticMapping());
+            .setUserGroupMapping(StaticUserGroup.getStaticMapping());
     writePolicyFile(policyFile);
 
-    dropDb(ADMIN1, DB1);
-    createDb(ADMIN1, DB1);
     Connection adminCon = context.createConnection(ADMIN1);
     Statement adminStmt = context.createStatement(adminCon);
     String tabName = DB1 + "." + "admin_tab1";
@@ -252,21 +412,21 @@ public class TestCrossDbOps extends AbstractTestWithStaticConfiguration {
    */
   @Test
   public void testNegativeUserPrivileges() throws Exception {
-    // edit policy file
-    policyFile.addRolesToGroup(USERGROUP1, "db1_tab1_insert", "db1_tab2_all")
-        .addPermissionsToRole("db1_tab2_all", "server=server1->db=" + DB1 + "->table=table_2")
-        .addPermissionsToRole("db1_tab1_insert", "server=server1->db=" + DB1 + "->table=table_1->action=insert")
-        .setUserGroupMapping(StaticUserGroup.getStaticMapping());
-    writePolicyFile(policyFile);
-
     Connection adminCon = context.createConnection(ADMIN1);
     Statement adminStmt = context.createStatement(adminCon);
     adminStmt.execute("use default");
-    adminStmt.execute("DROP DATABASE IF EXISTS " + DB1 + " CASCADE");
     adminStmt.execute("CREATE DATABASE " + DB1);
     adminStmt.execute("create table " + DB1 + ".table_1 (id int)");
     adminStmt.close();
     adminCon.close();
+
+    // edit policy file
+    policyFile.addRolesToGroup(USERGROUP1, "db1_tab1_insert", "db1_tab2_all")
+            .addPermissionsToRole("db1_tab2_all", "server=server1->db=" + DB1 + "->table=table_2")
+            .addPermissionsToRole("db1_tab1_insert", "server=server1->db=" + DB1 + "->table=table_1->action=insert")
+            .setUserGroupMapping(StaticUserGroup.getStaticMapping());
+    writePolicyFile(policyFile);
+
     Connection userConn = context.createConnection(USER1_1);
     Statement userStmt = context.createStatement(userConn);
     context.assertAuthzException(userStmt, "select * from " + DB1 + ".table_1");
@@ -282,13 +442,6 @@ public class TestCrossDbOps extends AbstractTestWithStaticConfiguration {
    */
   @Test
   public void testNegativeUserDMLPrivileges() throws Exception {
-    policyFile
-        .addPermissionsToRole("db1_tab2_all", "server=server1->db=" + DB1 + "->table=table_2")
-        .addRolesToGroup(USERGROUP1, "db1_tab2_all")
-        .setUserGroupMapping(StaticUserGroup.getStaticMapping());
-    writePolicyFile(policyFile);
-
-    dropDb(ADMIN1, DB1);
     createDb(ADMIN1, DB1);
     Connection adminCon = context.createConnection(ADMIN1);
     Statement adminStmt = context.createStatement(adminCon);
@@ -296,6 +449,13 @@ public class TestCrossDbOps extends AbstractTestWithStaticConfiguration {
     adminStmt.execute("create table " + DB1 + ".table_2 (id int)");
     adminStmt.close();
     adminCon.close();
+
+    policyFile
+            .addPermissionsToRole("db1_tab2_all", "server=server1->db=" + DB1 + "->table=table_2")
+            .addRolesToGroup(USERGROUP1, "db1_tab2_all")
+            .setUserGroupMapping(StaticUserGroup.getStaticMapping());
+    writePolicyFile(policyFile);
+
     Connection userConn = context.createConnection(USER1_1);
     Statement userStmt = context.createStatement(userConn);
     context.assertAuthzException(userStmt, "insert overwrite table  " + DB1
@@ -325,15 +485,6 @@ public class TestCrossDbOps extends AbstractTestWithStaticConfiguration {
    */
   @Test
   public void testNegUserPrivilegesAll() throws Exception {
-
-    policyFile
-        .addRolesToGroup(USERGROUP1, "db1_all")
-        .addRolesToGroup(USERGROUP2, "db1_tab1_select")
-        .addPermissionsToRole("db1_all", "server=server1->db=" + DB1)
-        .addPermissionsToRole("db1_tab1_select", "server=server1->db=" + DB1 + "->table=table_1->action=select")
-        .setUserGroupMapping(StaticUserGroup.getStaticMapping());
-    writePolicyFile(policyFile);
-
     // create dbs
     Connection adminCon = context.createConnection(ADMIN1);
     Statement adminStmt = context.createStatement(adminCon);
@@ -343,7 +494,6 @@ public class TestCrossDbOps extends AbstractTestWithStaticConfiguration {
     adminStmt
     .execute("load data local inpath '" + dataFile.getPath() + "' into table table_def");
 
-    adminStmt.execute("DROP DATABASE IF EXISTS " + DB1 + " CASCADE");
     adminStmt.execute("CREATE DATABASE " + DB1);
     adminStmt.execute("use " + DB1);
 
@@ -361,6 +511,14 @@ public class TestCrossDbOps extends AbstractTestWithStaticConfiguration {
     adminStmt.close();
     adminCon.close();
 
+    policyFile
+            .addRolesToGroup(USERGROUP1, "db1_all")
+            .addRolesToGroup(USERGROUP2, "db1_tab1_select")
+            .addPermissionsToRole("db1_all", "server=server1->db=" + DB1)
+            .addPermissionsToRole("db1_tab1_select", "server=server1->db=" + DB1 + "->table=table_1->action=select")
+            .setUserGroupMapping(StaticUserGroup.getStaticMapping());
+    writePolicyFile(policyFile);
+
     Connection userConn = context.createConnection(USER2_1);
     Statement userStmt = context.createStatement(userConn);
 
@@ -404,15 +562,14 @@ public class TestCrossDbOps extends AbstractTestWithStaticConfiguration {
    */
   @Test
   public void testSandboxOpt9() throws Exception {
+    createDb(ADMIN1, DB1, DB2);
+
     policyFile
-        .addPermissionsToRole(GROUP1_ROLE, ALL_DB1, ALL_DB2, loadData)
-        .addRolesToGroup(USERGROUP1, GROUP1_ROLE)
-        .setUserGroupMapping(StaticUserGroup.getStaticMapping());
+            .addPermissionsToRole(GROUP1_ROLE, ALL_DB1, ALL_DB2, loadData)
+            .addRolesToGroup(USERGROUP1, GROUP1_ROLE)
+            .setUserGroupMapping(StaticUserGroup.getStaticMapping());
     writePolicyFile(policyFile);
 
-    dropDb(ADMIN1, DB1, DB2);
-    createDb(ADMIN1, DB1, DB2);
-
     Connection connection = context.createConnection(USER1_1);
     Statement statement = context.createStatement(connection);
 
@@ -454,8 +611,6 @@ public class TestCrossDbOps extends AbstractTestWithStaticConfiguration {
     context.assertAuthzException(statement, "CREATE TABLE " + DB1 + "." + TBL2 +
         " AS SELECT value from " + DB2 + "." + TBL2 + " LIMIT 10");
 
-
-
     statement.close();
     connection.close();
   }
@@ -473,18 +628,7 @@ public class TestCrossDbOps extends AbstractTestWithStaticConfiguration {
    */
   @Test
   public void testCrossDbViewOperations() throws Exception {
-    // edit policy file
-    policyFile
-        .addRolesToGroup(USERGROUP1, "all_db1", "load_data", "select_tb2")
-        .addPermissionsToRole("all_db1", "server=server1->db=" + DB1)
-        .addPermissionsToRole("all_db2", "server=server1->db=" + DB2)
-        .addPermissionsToRole("select_tb2", "server=server1->db=" + DB2 + "->table=tb_1->action=select")
-        .addPermissionsToRole("load_data", "server=server1->URI=file://" + dataFile.getPath())
-        .setUserGroupMapping(StaticUserGroup.getStaticMapping());
-    writePolicyFile(policyFile);
-
     // admin create two databases
-    dropDb(ADMIN1, DB1, DB2);
     createDb(ADMIN1, DB1, DB2);
     Connection connection = context.createConnection(ADMIN1);
     Statement statement = context.createStatement(connection);
@@ -496,6 +640,16 @@ public class TestCrossDbOps extends AbstractTestWithStaticConfiguration {
     .execute("CREATE TABLE " + DB2 + "." + TBL2 + "(id int)");
     context.close();
 
+    // edit policy file
+    policyFile
+            .addRolesToGroup(USERGROUP1, "all_db1", "load_data", "select_tb2")
+            .addPermissionsToRole("all_db1", "server=server1->db=" + DB1)
+            .addPermissionsToRole("all_db2", "server=server1->db=" + DB2)
+            .addPermissionsToRole("select_tb2", "server=server1->db=" + DB2 + "->table=tb_1->action=select")
+            .addPermissionsToRole("load_data", "server=server1->URI=file://" + dataFile.getPath())
+            .setUserGroupMapping(StaticUserGroup.getStaticMapping());
+    writePolicyFile(policyFile);
+
     connection = context.createConnection(USER1_1);
     statement = context.createStatement(connection);
 

http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/19bbaacd/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/TestUserManagement.java
----------------------------------------------------------------------
diff --git a/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/TestUserManagement.java b/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/TestUserManagement.java
index fa34c33..be9f601 100644
--- a/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/TestUserManagement.java
+++ b/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/hive/TestUserManagement.java
@@ -51,7 +51,7 @@ public class TestUserManagement extends AbstractTestWithStaticConfiguration {
   }
   @Override
   @After
-  public void clearDB() throws Exception {
+  public void clearAfterPerTest() throws Exception {
     if (context != null) {
       context.close();
     }

http://git-wip-us.apache.org/repos/asf/incubator-sentry/blob/19bbaacd/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/metastore/AbstractMetastoreTestWithStaticConfiguration.java
----------------------------------------------------------------------
diff --git a/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/metastore/AbstractMetastoreTestWithStaticConfiguration.java b/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/metastore/AbstractMetastoreTestWithStaticConfiguration.java
index 23027d1..2c14c82 100644
--- a/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/metastore/AbstractMetastoreTestWithStaticConfiguration.java
+++ b/sentry-tests/sentry-tests-hive/src/test/java/org/apache/sentry/tests/e2e/metastore/AbstractMetastoreTestWithStaticConfiguration.java
@@ -54,16 +54,11 @@ public abstract class AbstractMetastoreTestWithStaticConfiguration extends
   @BeforeClass
   public static void setupTestStaticConfiguration() throws Exception {
     useSentryService = true;
+    clearDbAfterPerTest = false;
     testServerType = HiveServer2Type.InternalMetastore.name();
     AbstractTestWithStaticConfiguration.setupTestStaticConfiguration();
   }
 
-  @Override
-  @After
-  public void clearDB() throws Exception {
-
-  }
-
   protected static void writePolicyFile(PolicyFile policyFile) throws Exception {
     policyFile.write(context.getPolicyFile());
   }