org.apache.sentry.provider.db.service.persistent.TestSentryStore.java Source code

Java tutorial

Introduction

Here is the source code for org.apache.sentry.provider.db.service.persistent.TestSentryStore.java

Source

/**
 * 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.provider.db.service.persistent;

import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertFalse;
import static junit.framework.Assert.assertTrue;
import static junit.framework.Assert.fail;

import java.io.File;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.apache.commons.io.FileUtils;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.security.alias.CredentialProvider;
import org.apache.hadoop.security.alias.CredentialProviderFactory;
import org.apache.hadoop.security.alias.UserProvider;
import org.apache.sentry.core.model.db.AccessConstants;
import org.apache.sentry.provider.db.SentryAlreadyExistsException;
import org.apache.sentry.provider.db.SentryGrantDeniedException;
import org.apache.sentry.provider.db.SentryNoSuchObjectException;
import org.apache.sentry.provider.db.service.model.MSentryPrivilege;
import org.apache.sentry.provider.db.service.model.MSentryRole;
import org.apache.sentry.provider.db.service.thrift.TSentryActiveRoleSet;
import org.apache.sentry.provider.db.service.thrift.TSentryAuthorizable;
import org.apache.sentry.provider.db.service.thrift.TSentryGrantOption;
import org.apache.sentry.provider.db.service.thrift.TSentryGroup;
import org.apache.sentry.provider.db.service.thrift.TSentryPrivilege;
import org.apache.sentry.provider.file.PolicyFile;
import org.apache.sentry.service.thrift.ServiceConstants.ServerConfig;
import org.junit.After;
import org.junit.AfterClass;
import static org.junit.Assert.assertArrayEquals;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Ignore;
import org.junit.Test;

import com.google.common.collect.Iterables;
import com.google.common.collect.Sets;
import com.google.common.io.Files;

public class TestSentryStore {

    private static File dataDir;
    private static SentryStore sentryStore;
    private static String[] adminGroups = { "adminGroup1" };
    private static PolicyFile policyFile;
    private static File policyFilePath;
    final long NUM_PRIVS = 60; // > SentryStore.PrivCleaner.NOTIFY_THRESHOLD
    private static Configuration conf = null;
    private static char[] passwd = new char[] { '1', '2', '3' };

    @BeforeClass
    public static void setup() throws Exception {
        conf = new Configuration(false);
        final String ourUrl = UserProvider.SCHEME_NAME + ":///";
        conf.set(CredentialProviderFactory.CREDENTIAL_PROVIDER_PATH, ourUrl);
        CredentialProvider provider = CredentialProviderFactory.getProviders(conf).get(0);
        provider.createCredentialEntry(ServerConfig.SENTRY_STORE_JDBC_PASS, passwd);
        provider.flush();

        dataDir = new File(Files.createTempDir(), "sentry_policy_db");
        conf.set(ServerConfig.SENTRY_VERIFY_SCHEM_VERSION, "false");
        conf.set(ServerConfig.SENTRY_STORE_JDBC_URL,
                "jdbc:derby:;databaseName=" + dataDir.getPath() + ";create=true");
        conf.set(ServerConfig.SENTRY_STORE_JDBC_PASS, "dummy");
        conf.setStrings(ServerConfig.ADMIN_GROUPS, adminGroups);
        conf.set(ServerConfig.SENTRY_STORE_GROUP_MAPPING, ServerConfig.SENTRY_STORE_LOCAL_GROUP_MAPPING);
        policyFilePath = new File(dataDir, "local_policy_file.ini");
        conf.set(ServerConfig.SENTRY_STORE_GROUP_MAPPING_RESOURCE, policyFilePath.getPath());
        sentryStore = new SentryStore(conf);
    }

    @Before
    public void before() throws Exception {
        policyFile = new PolicyFile();
        String adminUser = "g1";
        addGroupsToUser(adminUser, adminGroups);
        writePolicyFile();
    }

    @After
    public void after() {
        sentryStore.clearAllTables();
    }

    @AfterClass
    public static void teardown() {
        if (sentryStore != null) {
            sentryStore.stop();
        }
        if (dataDir != null) {
            FileUtils.deleteQuietly(dataDir);
        }
    }

    @Test
    public void testCredentialProvider() throws Exception {
        assertArrayEquals(passwd, conf.getPassword(ServerConfig.SENTRY_STORE_JDBC_PASS));
    }

    @Test
    public void testCaseInsensitiveRole() throws Exception {
        String roleName = "newRole";
        String grantor = "g1";
        Set<TSentryGroup> groups = Sets.newHashSet();
        TSentryGroup group = new TSentryGroup();
        group.setGroupName("test-groups-g1");
        groups.add(group);

        TSentryPrivilege privilege = new TSentryPrivilege();
        privilege.setPrivilegeScope("TABLE");
        privilege.setServerName("server1");
        privilege.setDbName("default");
        privilege.setTableName("table1");
        privilege.setAction(AccessConstants.ALL);
        privilege.setCreateTime(System.currentTimeMillis());

        long seqId = sentryStore.createSentryRole(roleName).getSequenceId();
        assertEquals(seqId + 1, sentryStore.alterSentryRoleAddGroups(grantor, roleName, groups).getSequenceId());
        assertEquals(seqId + 2, sentryStore.alterSentryRoleDeleteGroups(roleName, groups).getSequenceId());
        assertEquals(seqId + 3,
                sentryStore.alterSentryRoleGrantPrivilege(grantor, roleName, privilege).getSequenceId());
        assertEquals(seqId + 4,
                sentryStore.alterSentryRoleRevokePrivilege(grantor, roleName, privilege).getSequenceId());
    }

    @Test
    public void testURI() throws Exception {
        String roleName = "test-dup-role";
        String grantor = "g1";
        String uri = "file:///var/folders/dt/9zm44z9s6bjfxbrm4v36lzdc0000gp/T/1401860678102-0/data/kv1.dat";
        sentryStore.createSentryRole(roleName);
        TSentryPrivilege tSentryPrivilege = new TSentryPrivilege("URI", "server1", "ALL");
        tSentryPrivilege.setURI(uri);
        sentryStore.alterSentryRoleGrantPrivilege(grantor, roleName, tSentryPrivilege);

        TSentryAuthorizable tSentryAuthorizable = new TSentryAuthorizable();
        tSentryAuthorizable.setUri(uri);
        tSentryAuthorizable.setServer("server1");

        Set<TSentryPrivilege> privileges = sentryStore
                .getTSentryPrivileges(new HashSet<String>(Arrays.asList(roleName)), tSentryAuthorizable);

        assertTrue(privileges.size() == 1);

        Set<TSentryGroup> tSentryGroups = new HashSet<TSentryGroup>();
        tSentryGroups.add(new TSentryGroup("group1"));
        sentryStore.alterSentryRoleAddGroups(grantor, roleName, tSentryGroups);

        TSentryActiveRoleSet thriftRoleSet = new TSentryActiveRoleSet(true,
                new HashSet<String>(Arrays.asList(roleName)));

        Set<String> privs = sentryStore.listSentryPrivilegesForProvider(
                new HashSet<String>(Arrays.asList("group1")), thriftRoleSet, tSentryAuthorizable);

        assertTrue(privs.size() == 1);
        assertTrue(privs.contains("server=server1->uri=" + uri + "->action=all"));
    }

    @Test
    public void testCreateDuplicateRole() throws Exception {
        String roleName = "test-dup-role";
        sentryStore.createSentryRole(roleName);
        try {
            sentryStore.createSentryRole(roleName);
            fail("Expected SentryAlreadyExistsException");
        } catch (SentryAlreadyExistsException e) {
            // expected
        }
    }

    @Test
    public void testCaseSensitiveScope() throws Exception {
        String roleName = "role1";
        String grantor = "g1";
        long seqId = sentryStore.createSentryRole(roleName).getSequenceId();
        TSentryPrivilege sentryPrivilege = new TSentryPrivilege("Database", "server1", "all");
        sentryPrivilege.setDbName("db1");
        assertEquals(seqId + 1,
                sentryStore.alterSentryRoleGrantPrivilege(grantor, roleName, sentryPrivilege).getSequenceId());
    }

    @Test
    public void testCreateDropRole() throws Exception {
        String roleName = "test-drop-role";
        long seqId = sentryStore.createSentryRole(roleName).getSequenceId();
        assertEquals(seqId + 1, sentryStore.dropSentryRole(roleName).getSequenceId());
    }

    @Test(expected = SentryNoSuchObjectException.class)
    public void testAddDeleteGroupsNonExistantRole() throws Exception {
        String roleName = "non-existant-role";
        String grantor = "g1";
        Set<TSentryGroup> groups = Sets.newHashSet();
        sentryStore.alterSentryRoleAddGroups(grantor, roleName, groups);
    }

    @Test
    public void testAddDeleteGroups() throws Exception {
        String roleName = "test-groups";
        String grantor = "g1";
        long seqId = sentryStore.createSentryRole(roleName).getSequenceId();
        Set<TSentryGroup> groups = Sets.newHashSet();
        TSentryGroup group = new TSentryGroup();
        group.setGroupName("test-groups-g1");
        groups.add(group);
        group = new TSentryGroup();
        group.setGroupName("test-groups-g2");
        groups.add(group);
        assertEquals(seqId + 1, sentryStore.alterSentryRoleAddGroups(grantor, roleName, groups).getSequenceId());
        assertEquals(seqId + 2, sentryStore.alterSentryRoleDeleteGroups(roleName, groups).getSequenceId());
        MSentryRole role = sentryStore.getMSentryRoleByName(roleName);
        assertEquals(Collections.emptySet(), role.getGroups());
    }

    @Test
    public void testGrantRevokePrivilege() throws Exception {
        String roleName = "test-privilege";
        String grantor = "g1";
        String server = "server1";
        String db = "db1";
        String table = "tbl1";
        long seqId = sentryStore.createSentryRole(roleName).getSequenceId();
        TSentryPrivilege privilege = new TSentryPrivilege();
        privilege.setPrivilegeScope("TABLE");
        privilege.setServerName(server);
        privilege.setDbName(db);
        privilege.setTableName(table);
        privilege.setAction(AccessConstants.ALL);
        privilege.setCreateTime(System.currentTimeMillis());
        assertEquals(seqId + 1,
                sentryStore.alterSentryRoleGrantPrivilege(grantor, roleName, privilege).getSequenceId());
        MSentryRole role = sentryStore.getMSentryRoleByName(roleName);
        Set<MSentryPrivilege> privileges = role.getPrivileges();
        assertEquals(privileges.toString(), 1, privileges.size());
        privilege.setAction(AccessConstants.SELECT);
        assertEquals(seqId + 2,
                sentryStore.alterSentryRoleRevokePrivilege(grantor, roleName, privilege).getSequenceId());
        // after having ALL and revoking SELECT, we should have INSERT
        role = sentryStore.getMSentryRoleByName(roleName);
        privileges = role.getPrivileges();
        assertEquals(privileges.toString(), 1, privileges.size());
        MSentryPrivilege mPrivilege = Iterables.get(privileges, 0);
        assertEquals(server, mPrivilege.getServerName());
        assertEquals(db, mPrivilege.getDbName());
        assertEquals(table, mPrivilege.getTableName());
        assertEquals(AccessConstants.INSERT, mPrivilege.getAction());
        assertFalse(mPrivilege.getGrantOption());
    }

    private void verifyOrphanCleanup() throws Exception {
        boolean success = false;
        int iterations = 30;
        while (!success && iterations > 0) {
            Thread.sleep(1000);
            long numDBPrivs = sentryStore.countMSentryPrivileges();
            if (numDBPrivs < NUM_PRIVS) {
                assertEquals(0, numDBPrivs);
                success = true;
            }
            iterations--;
        }
        assertTrue("Failed to cleanup orphaned privileges", success);
    }

    /**
     * Create several privileges in the database, then delete the role that
     * created them.  This makes them all orphans.  Wait a bit to ensure the
     * cleanup thread runs, and expect them all to be gone from the database.
     * @throws Exception
     */
    @Ignore("Disabled with SENTRY-545 following SENTRY-140 problems")
    @Test
    public void testPrivilegeCleanup() throws Exception {
        final String roleName = "test-priv-cleanup";
        final String grantor = "g1";
        final String server = "server";
        final String dBase = "db";
        final String table = "table-";

        sentryStore.createSentryRole(roleName);

        // Create NUM_PRIVS unique privilege objects in the database
        for (int i = 0; i < NUM_PRIVS; i++) {
            TSentryPrivilege priv = new TSentryPrivilege();
            priv.setPrivilegeScope("TABLE");
            priv.setServerName(server);
            priv.setAction(AccessConstants.ALL);
            priv.setCreateTime(System.currentTimeMillis());
            priv.setTableName(table + i);
            priv.setDbName(dBase);
            sentryStore.alterSentryRoleGrantPrivilege(grantor, roleName, priv);
        }

        // Make sure we really have the expected number of privs in the database
        assertEquals(sentryStore.countMSentryPrivileges(), NUM_PRIVS);

        // Now to make a bunch of orphans, we just remove the role that
        // created them.
        sentryStore.dropSentryRole(roleName);

        // Now wait and see if the orphans get cleaned up
        verifyOrphanCleanup();
    }

    /**
     * Much like testPrivilegeCleanup, make a lot of privileges and make sure
     * they get cleaned up.  The difference here is that the privileges are
     * created by granting ALL and then removing SELECT - thus leaving INSERT.
     * This test exists because the revocation plays havoc with the orphan
     * cleanup thread.
     * @throws Exception
     */
    @Ignore("Disabled with SENTRY-545 following SENTRY-140 problems")
    @Test
    public void testPrivilegeCleanup2() throws Exception {
        final String roleName = "test-priv-cleanup";
        final String grantor = "g1";
        final String server = "server";
        final String dBase = "db";
        final String table = "table-";

        sentryStore.createSentryRole(roleName);

        // Create NUM_PRIVS unique privilege objects in the database once more,
        // this time granting ALL and revoking SELECT to make INSERT.
        for (int i = 0; i < NUM_PRIVS; i++) {
            TSentryPrivilege priv = new TSentryPrivilege();
            priv.setPrivilegeScope("DATABASE");
            priv.setServerName(server);
            priv.setAction(AccessConstants.ALL);
            priv.setCreateTime(System.currentTimeMillis());
            priv.setTableName(table + i);
            priv.setDbName(dBase);
            priv.setGrantOption(TSentryGrantOption.TRUE);
            sentryStore.alterSentryRoleGrantPrivilege(grantor, roleName, priv);

            priv.setAction(AccessConstants.SELECT);
            priv.setGrantOption(TSentryGrantOption.UNSET);
            sentryStore.alterSentryRoleRevokePrivilege(grantor, roleName, priv);
            // after having ALL and revoking SELECT, we should have INSERT
            MSentryRole role = sentryStore.getMSentryRoleByName(roleName);
            Set<MSentryPrivilege> privileges = role.getPrivileges();
            assertEquals(privileges.toString(), i + 1, privileges.size());
            MSentryPrivilege mPrivilege = Iterables.get(privileges, 0);
            assertEquals(AccessConstants.INSERT, mPrivilege.getAction());
        }

        // Drop the role and clean up as before
        sentryStore.dropSentryRole(roleName);
        verifyOrphanCleanup();
    }

    @Test
    public void testGrantRevokeMultiPrivileges() throws Exception {
        String roleName = "test-privilege";
        String grantor = "g1";
        String server = "server1";
        String db = "db1";
        String table = "tbl1";
        String[] columns = { "c1", "c2", "c3", "c4" };
        long seqId = sentryStore.createSentryRole(roleName).getSequenceId();
        Set<TSentryPrivilege> tPrivileges = Sets.newHashSet();
        for (String column : columns) {
            TSentryPrivilege privilege = new TSentryPrivilege();
            privilege.setPrivilegeScope("Column");
            privilege.setServerName(server);
            privilege.setDbName(db);
            privilege.setTableName(table);
            privilege.setColumnName(column);
            privilege.setAction(AccessConstants.SELECT);
            privilege.setCreateTime(System.currentTimeMillis());
            tPrivileges.add(privilege);
        }
        assertEquals(seqId + 1,
                sentryStore.alterSentryRoleGrantPrivileges(grantor, roleName, tPrivileges).getSequenceId());
        MSentryRole role = sentryStore.getMSentryRoleByName(roleName);
        Set<MSentryPrivilege> privileges = role.getPrivileges();
        assertEquals(privileges.toString(), 4, privileges.size());

        tPrivileges = Sets.newHashSet();
        for (int i = 0; i < 2; i++) {
            TSentryPrivilege privilege = new TSentryPrivilege();
            privilege.setPrivilegeScope("Column");
            privilege.setServerName(server);
            privilege.setDbName(db);
            privilege.setTableName(table);
            privilege.setColumnName(columns[i]);
            privilege.setAction(AccessConstants.SELECT);
            privilege.setCreateTime(System.currentTimeMillis());
            tPrivileges.add(privilege);
        }
        assertEquals(seqId + 2,
                sentryStore.alterSentryRoleRevokePrivileges(grantor, roleName, tPrivileges).getSequenceId());
        role = sentryStore.getMSentryRoleByName(roleName);
        privileges = role.getPrivileges();
        assertEquals(privileges.toString(), 2, privileges.size());

        TSentryPrivilege privilege = new TSentryPrivilege();
        privilege.setPrivilegeScope("Table");
        privilege.setServerName(server);
        privilege.setDbName(db);
        privilege.setTableName(table);
        privilege.setAction(AccessConstants.SELECT);
        privilege.setCreateTime(System.currentTimeMillis());
        assertEquals(seqId + 3,
                sentryStore.alterSentryRoleRevokePrivilege(grantor, roleName, privilege).getSequenceId());
        // After revoking table scope, we will have 0 privileges
        role = sentryStore.getMSentryRoleByName(roleName);
        privileges = role.getPrivileges();
        assertEquals(privileges.toString(), 0, privileges.size());
    }

    /**
     * Regression test for SENTRY-74 and SENTRY-552
     */
    @Test
    public void testGrantRevokePrivilegeWithColumn() throws Exception {
        String roleName = "test-col-privilege";
        String grantor = "g1";
        String server = "server1";
        String db = "db1";
        String table = "tbl1";
        String column1 = "c1";
        String column2 = "c2";
        long seqId = sentryStore.createSentryRole(roleName).getSequenceId();
        TSentryPrivilege privilege = new TSentryPrivilege();
        privilege.setPrivilegeScope("COLUMN");
        privilege.setServerName(server);
        privilege.setDbName(db);
        privilege.setTableName(table);
        privilege.setColumnName(column1);
        privilege.setAction(AccessConstants.ALL);
        privilege.setCreateTime(System.currentTimeMillis());

        // Grant ALL on c1 and c2
        assertEquals(seqId + 1,
                sentryStore.alterSentryRoleGrantPrivilege(grantor, roleName, privilege).getSequenceId());
        privilege.setColumnName(column2);
        assertEquals(seqId + 2,
                sentryStore.alterSentryRoleGrantPrivilege(grantor, roleName, privilege).getSequenceId());
        MSentryRole role = sentryStore.getMSentryRoleByName(roleName);
        Set<MSentryPrivilege> privileges = role.getPrivileges();
        assertEquals(privileges.toString(), 2, privileges.size());

        // Revoke SELECT on c2
        privilege.setAction(AccessConstants.SELECT);
        assertEquals(seqId + 3,
                sentryStore.alterSentryRoleRevokePrivilege(grantor, roleName, privilege).getSequenceId());

        // At this point c1 has ALL privileges and c2 should have INSERT after revoking SELECT
        role = sentryStore.getMSentryRoleByName(roleName);
        privileges = role.getPrivileges();
        assertEquals(privileges.toString(), 2, privileges.size());
        for (MSentryPrivilege mPrivilege : privileges) {
            assertEquals(server, mPrivilege.getServerName());
            assertEquals(db, mPrivilege.getDbName());
            assertEquals(table, mPrivilege.getTableName());
            assertFalse(mPrivilege.getGrantOption());
            if (mPrivilege.getColumnName().equals(column1)) {
                assertEquals(AccessConstants.ALL, mPrivilege.getAction());
            } else if (mPrivilege.getColumnName().equals(column2)) {
                assertEquals(AccessConstants.INSERT, mPrivilege.getAction());
            } else {
                fail("Unexpected column name: " + mPrivilege.getColumnName());
            }
        }

        // after revoking INSERT table level privilege will remove privileges from column2
        // and downgrade column1 to SELECT privileges.
        privilege = new TSentryPrivilege();
        privilege.setPrivilegeScope("TABLE");
        privilege.setServerName(server);
        privilege.setDbName(db);
        privilege.setTableName(table);
        privilege.setAction(AccessConstants.INSERT);
        privilege.setCreateTime(System.currentTimeMillis());
        assertEquals(seqId + 4,
                sentryStore.alterSentryRoleRevokePrivilege(grantor, roleName, privilege).getSequenceId());
        role = sentryStore.getMSentryRoleByName(roleName);
        privileges = role.getPrivileges();
        assertEquals(privileges.toString(), 1, privileges.size());
        assertEquals(column1, Iterables.get(privileges, 0).getColumnName());
        assertEquals(AccessConstants.SELECT, Iterables.get(privileges, 0).getAction());

        // Revoke ALL from the table should now remove all the column privileges.
        privilege.setAction(AccessConstants.ALL);
        privilege.setCreateTime(System.currentTimeMillis());
        assertEquals(seqId + 5,
                sentryStore.alterSentryRoleRevokePrivilege(grantor, roleName, privilege).getSequenceId());
        role = sentryStore.getMSentryRoleByName(roleName);
        privileges = role.getPrivileges();
        assertEquals(privileges.toString(), 0, privileges.size());
    }

    /**
     * Regression test for SENTRY-552
     */
    @Test
    public void testGrantRevokeTablePrivilegeDowngradeByDb() throws Exception {
        String roleName = "test-table-db-downgrade-privilege";
        String grantor = "g1";
        String server = "server1";
        String db = "db1";
        String table1 = "tbl1";
        String table2 = "tbl2";
        long seqId = sentryStore.createSentryRole(roleName).getSequenceId();
        TSentryPrivilege privilegeTable1 = new TSentryPrivilege();
        privilegeTable1.setPrivilegeScope("TABLE");
        privilegeTable1.setServerName(server);
        privilegeTable1.setDbName(db);
        privilegeTable1.setTableName(table1);
        privilegeTable1.setAction(AccessConstants.ALL);
        privilegeTable1.setCreateTime(System.currentTimeMillis());
        TSentryPrivilege privilegeTable2 = privilegeTable1.deepCopy();
        ;
        privilegeTable2.setTableName(table2);

        // Grant ALL on table1 and table2
        assertEquals(seqId + 1,
                sentryStore.alterSentryRoleGrantPrivilege(grantor, roleName, privilegeTable1).getSequenceId());
        assertEquals(seqId + 2,
                sentryStore.alterSentryRoleGrantPrivilege(grantor, roleName, privilegeTable2).getSequenceId());
        MSentryRole role = sentryStore.getMSentryRoleByName(roleName);
        Set<MSentryPrivilege> privileges = role.getPrivileges();
        assertEquals(privileges.toString(), 2, privileges.size());

        // Revoke SELECT on table2
        privilegeTable2.setAction(AccessConstants.SELECT);
        assertEquals(seqId + 3,
                sentryStore.alterSentryRoleRevokePrivilege(grantor, roleName, privilegeTable2).getSequenceId());
        // after having ALL and revoking SELECT, we should have INSERT
        role = sentryStore.getMSentryRoleByName(roleName);
        privileges = role.getPrivileges();
        assertEquals(privileges.toString(), 2, privileges.size());

        // At this point table1 has ALL privileges and table2 should have INSERT after revoking SELECT
        role = sentryStore.getMSentryRoleByName(roleName);
        privileges = role.getPrivileges();
        assertEquals(privileges.toString(), 2, privileges.size());
        for (MSentryPrivilege mPrivilege : privileges) {
            assertEquals(server, mPrivilege.getServerName());
            assertEquals(db, mPrivilege.getDbName());
            assertFalse(mPrivilege.getGrantOption());
            if (mPrivilege.getTableName().equals(table1)) {
                assertEquals(AccessConstants.ALL, mPrivilege.getAction());
            } else if (mPrivilege.getTableName().equals(table2)) {
                assertEquals(AccessConstants.INSERT, mPrivilege.getAction());
            } else {
                fail("Unexpected table name: " + mPrivilege.getTableName());
            }
        }

        // Revoke INSERT on Database
        privilegeTable2.setAction(AccessConstants.INSERT);
        privilegeTable2.setPrivilegeScope("DATABASE");
        privilegeTable2.unsetTableName();
        assertEquals(seqId + 4,
                sentryStore.alterSentryRoleRevokePrivilege(grantor, roleName, privilegeTable2).getSequenceId());
        role = sentryStore.getMSentryRoleByName(roleName);
        privileges = role.getPrivileges();

        // after revoking INSERT database level privilege will remove privileges from table2
        // and downgrade table1 to SELECT privileges.
        assertEquals(privileges.toString(), 1, privileges.size());
        MSentryPrivilege mPrivilege = Iterables.get(privileges, 0);
        assertEquals(server, mPrivilege.getServerName());
        assertEquals(db, mPrivilege.getDbName());
        assertEquals(table1, mPrivilege.getTableName());
        assertEquals(AccessConstants.SELECT, mPrivilege.getAction());
        assertFalse(mPrivilege.getGrantOption());
    }

    /**
     * Regression test for SENTRY-552
     */
    @Test
    public void testGrantRevokeColumnPrivilegeDowngradeByDb() throws Exception {
        String roleName = "test-column-db-downgrade-privilege";
        String grantor = "g1";
        String server = "server1";
        String db = "db1";
        String table = "tbl1";
        String column1 = "c1";
        String column2 = "c2";
        long seqId = sentryStore.createSentryRole(roleName).getSequenceId();
        TSentryPrivilege privilegeCol1 = new TSentryPrivilege();
        privilegeCol1.setPrivilegeScope("COLUMN");
        privilegeCol1.setServerName(server);
        privilegeCol1.setDbName(db);
        privilegeCol1.setTableName(table);
        privilegeCol1.setColumnName(column1);
        privilegeCol1.setAction(AccessConstants.ALL);
        privilegeCol1.setCreateTime(System.currentTimeMillis());
        TSentryPrivilege privilegeCol2 = privilegeCol1.deepCopy();
        ;
        privilegeCol2.setColumnName(column2);

        // Grant ALL on column1 and column2
        assertEquals(seqId + 1,
                sentryStore.alterSentryRoleGrantPrivilege(grantor, roleName, privilegeCol1).getSequenceId());
        assertEquals(seqId + 2,
                sentryStore.alterSentryRoleGrantPrivilege(grantor, roleName, privilegeCol2).getSequenceId());
        MSentryRole role = sentryStore.getMSentryRoleByName(roleName);
        Set<MSentryPrivilege> privileges = role.getPrivileges();
        assertEquals(privileges.toString(), 2, privileges.size());

        // Revoke SELECT on column2
        privilegeCol2.setAction(AccessConstants.SELECT);
        assertEquals(seqId + 3,
                sentryStore.alterSentryRoleRevokePrivilege(grantor, roleName, privilegeCol2).getSequenceId());
        // after having ALL and revoking SELECT, we should have INSERT
        role = sentryStore.getMSentryRoleByName(roleName);
        privileges = role.getPrivileges();
        assertEquals(privileges.toString(), 2, privileges.size());

        // At this point column1 has ALL privileges and column2 should have INSERT after revoking SELECT
        role = sentryStore.getMSentryRoleByName(roleName);
        privileges = role.getPrivileges();
        assertEquals(privileges.toString(), 2, privileges.size());
        for (MSentryPrivilege mPrivilege : privileges) {
            assertEquals(server, mPrivilege.getServerName());
            assertEquals(db, mPrivilege.getDbName());
            assertEquals(table, mPrivilege.getTableName());
            assertFalse(mPrivilege.getGrantOption());
            if (mPrivilege.getColumnName().equals(column1)) {
                assertEquals(AccessConstants.ALL, mPrivilege.getAction());
            } else if (mPrivilege.getColumnName().equals(column2)) {
                assertEquals(AccessConstants.INSERT, mPrivilege.getAction());
            } else {
                fail("Unexpected column name: " + mPrivilege.getColumnName());
            }
        }

        // Revoke INSERT on Database
        privilegeCol2.setAction(AccessConstants.INSERT);
        privilegeCol2.setPrivilegeScope("DATABASE");
        privilegeCol2.unsetTableName();
        privilegeCol2.unsetColumnName();
        assertEquals(seqId + 4,
                sentryStore.alterSentryRoleRevokePrivilege(grantor, roleName, privilegeCol2).getSequenceId());
        role = sentryStore.getMSentryRoleByName(roleName);
        privileges = role.getPrivileges();

        // after revoking INSERT database level privilege will remove privileges from column2
        // and downgrade column1 to SELECT privileges.
        assertEquals(privileges.toString(), 1, privileges.size());
        MSentryPrivilege mPrivilege = Iterables.get(privileges, 0);
        assertEquals(server, mPrivilege.getServerName());
        assertEquals(db, mPrivilege.getDbName());
        assertEquals(table, mPrivilege.getTableName());
        assertEquals(column1, mPrivilege.getColumnName());
        assertEquals(AccessConstants.SELECT, mPrivilege.getAction());
        assertFalse(mPrivilege.getGrantOption());
    }

    @Test
    public void testGrantRevokePrivilegeWithGrantOption() throws Exception {
        String roleName = "test-grantOption-table";
        String grantor = "g1";
        String server = "server1";
        String db = "db1";
        String table = "tbl1";
        TSentryGrantOption grantOption = TSentryGrantOption.TRUE;
        long seqId = sentryStore.createSentryRole(roleName).getSequenceId();
        TSentryPrivilege privilege = new TSentryPrivilege();
        privilege.setPrivilegeScope("TABLE");
        privilege.setServerName(server);
        privilege.setDbName(db);
        privilege.setTableName(table);
        privilege.setAction(AccessConstants.ALL);
        privilege.setCreateTime(System.currentTimeMillis());
        privilege.setGrantOption(grantOption);
        assertEquals(seqId + 1,
                sentryStore.alterSentryRoleGrantPrivilege(grantor, roleName, privilege).getSequenceId());
        MSentryRole role = sentryStore.getMSentryRoleByName(roleName);
        Set<MSentryPrivilege> privileges = role.getPrivileges();
        assertEquals(privileges.toString(), 1, privileges.size());
        assertEquals(Boolean.valueOf(privilege.getGrantOption().toString()),
                Iterables.get(privileges, 0).getGrantOption());
        assertEquals(seqId + 2,
                sentryStore.alterSentryRoleRevokePrivilege(grantor, roleName, privilege).getSequenceId());
        role = sentryStore.getMSentryRoleByName(roleName);
        privileges = role.getPrivileges();
        assertEquals(0, privileges.size());

        roleName = "test-grantOption-db";
        sentryStore.createSentryRole(roleName);
        privilege = new TSentryPrivilege();
        privilege.setPrivilegeScope("DATABASE");
        privilege.setServerName(server);
        privilege.setDbName(db);
        privilege.setAction(AccessConstants.ALL);
        privilege.setGrantOption(TSentryGrantOption.TRUE);
        privilege.setCreateTime(System.currentTimeMillis());
        privilege.setGrantOption(grantOption);
        sentryStore.alterSentryRoleGrantPrivilege(grantor, roleName, privilege);
        role = sentryStore.getMSentryRoleByName(roleName);
        privileges = role.getPrivileges();
        assertEquals(privileges.toString(), 1, privileges.size());

        privilege.setAction(AccessConstants.SELECT);
        privilege.setGrantOption(TSentryGrantOption.UNSET);
        sentryStore.alterSentryRoleRevokePrivilege(grantor, roleName, privilege);
        // after having ALL and revoking SELECT, we should have INSERT
        role = sentryStore.getMSentryRoleByName(roleName);
        privileges = role.getPrivileges();
        assertEquals(privileges.toString(), 1, privileges.size());
        MSentryPrivilege mPrivilege = Iterables.get(privileges, 0);
        assertEquals(server, mPrivilege.getServerName());
        assertEquals(db, mPrivilege.getDbName());
        assertEquals(AccessConstants.INSERT, mPrivilege.getAction());
    }

    @Test
    public void testGrantCheckWithGrantOption() throws Exception {
        // 1. set local group mapping
        // user0->group0->role0
        // user1->group1->role1
        // user2->group2->role2
        // user3->group3->role3
        // user4->group4->role4
        String grantor = "g1";
        String[] users = { "user0", "user1", "user2", "user3", "user4" };
        String[] roles = { "role0", "role1", "role2", "role3", "role4" };
        String[] groups = { "group0", "group1", "group2", "group3", "group4" };
        for (int i = 0; i < users.length; i++) {
            addGroupsToUser(users[i], groups[i]);
            sentryStore.createSentryRole(roles[i]);
            Set<TSentryGroup> tGroups = Sets.newHashSet();
            TSentryGroup tGroup = new TSentryGroup(groups[i]);
            tGroups.add(tGroup);
            sentryStore.alterSentryRoleAddGroups(grantor, roles[i], tGroups);
        }
        writePolicyFile();

        // 2. g1 grant all on database db1 to role0 with grant option
        String server = "server1";
        String db = "db1";
        String table = "tbl1";
        String roleName = roles[0];
        grantor = "g1";
        TSentryPrivilege privilege1 = new TSentryPrivilege();
        privilege1.setPrivilegeScope("DATABASE");
        privilege1.setServerName(server);
        privilege1.setDbName(db);
        privilege1.setAction(AccessConstants.ALL);
        privilege1.setCreateTime(System.currentTimeMillis());
        privilege1.setGrantOption(TSentryGrantOption.TRUE);
        sentryStore.alterSentryRoleGrantPrivilege(grantor, roleName, privilege1);
        MSentryRole role = sentryStore.getMSentryRoleByName(roleName);
        Set<MSentryPrivilege> privileges = role.getPrivileges();
        assertEquals(privileges.toString(), 1, privileges.size());

        // 3. user0 grant select on database db1 to role1, with grant option
        roleName = roles[1];
        grantor = users[0];
        TSentryPrivilege privilege2 = new TSentryPrivilege();
        privilege2.setPrivilegeScope("DATABASE");
        privilege2.setServerName(server);
        privilege2.setDbName(db);
        privilege2.setAction(AccessConstants.SELECT);
        privilege2.setCreateTime(System.currentTimeMillis());
        privilege2.setGrantOption(TSentryGrantOption.TRUE);
        sentryStore.alterSentryRoleGrantPrivilege(grantor, roleName, privilege2);

        // 4. user0 grant all on table tb1 to role2, no grant option
        roleName = roles[2];
        grantor = users[0];
        TSentryPrivilege privilege3 = new TSentryPrivilege();
        privilege3.setPrivilegeScope("TABLE");
        privilege3.setServerName(server);
        privilege3.setDbName(db);
        privilege3.setTableName(table);
        privilege3.setAction(AccessConstants.ALL);
        privilege3.setCreateTime(System.currentTimeMillis());
        privilege3.setGrantOption(TSentryGrantOption.FALSE);
        sentryStore.alterSentryRoleGrantPrivilege(grantor, roleName, privilege3);

        // 5. user1 has role1, no insert privilege,
        // grant insert to role3, will throw no grant exception
        roleName = roles[3];
        grantor = users[1];
        TSentryPrivilege privilege4 = new TSentryPrivilege();
        privilege4.setPrivilegeScope("DATABASE");
        privilege4.setServerName(server);
        privilege4.setDbName(db);
        privilege4.setAction(AccessConstants.INSERT);
        privilege4.setCreateTime(System.currentTimeMillis());
        privilege4.setGrantOption(TSentryGrantOption.FALSE);
        boolean isGrantOptionException = false;
        try {
            sentryStore.alterSentryRoleGrantPrivilege(grantor, roleName, privilege4);
        } catch (SentryGrantDeniedException e) {
            isGrantOptionException = true;
            System.err.println(e.getMessage());
        }
        assertTrue(isGrantOptionException);

        // 6. user2 has role2, no grant option,
        // grant insert to role4, will throw no grant exception
        roleName = roles[4];
        grantor = users[2];
        TSentryPrivilege privilege5 = new TSentryPrivilege();
        privilege5.setPrivilegeScope("TABLE");
        privilege5.setServerName(server);
        privilege5.setDbName(db);
        privilege5.setTableName(table);
        privilege5.setAction(AccessConstants.INSERT);
        privilege5.setCreateTime(System.currentTimeMillis());
        privilege5.setGrantOption(TSentryGrantOption.FALSE);
        isGrantOptionException = false;
        try {
            sentryStore.alterSentryRoleGrantPrivilege(grantor, roleName, privilege5);
        } catch (SentryGrantDeniedException e) {
            isGrantOptionException = true;
            System.err.println(e.getMessage());
        }
        assertTrue(isGrantOptionException);
    }

    @Test
    public void testRevokeCheckWithGrantOption() throws Exception {
        // 1. set local group mapping
        // user0->group0->role0
        // user1->group1->role1
        // user2->group2->role2
        String grantor = "g1";
        String[] users = { "user0", "user1", "user2" };
        String[] roles = { "role0", "role1", "role2" };
        String[] groups = { "group0", "group1", "group2" };
        for (int i = 0; i < users.length; i++) {
            addGroupsToUser(users[i], groups[i]);
            sentryStore.createSentryRole(roles[i]);
            Set<TSentryGroup> tGroups = Sets.newHashSet();
            TSentryGroup tGroup = new TSentryGroup(groups[i]);
            tGroups.add(tGroup);
            sentryStore.alterSentryRoleAddGroups(grantor, roles[i], tGroups);
        }
        writePolicyFile();

        // 2. g1 grant select on database db1 to role0, with grant option
        String server = "server1";
        String db = "db1";
        String table = "tbl1";
        String roleName = roles[0];
        grantor = "g1";
        TSentryPrivilege privilege1 = new TSentryPrivilege();
        privilege1.setPrivilegeScope("DATABASE");
        privilege1.setServerName(server);
        privilege1.setDbName(db);
        privilege1.setAction(AccessConstants.SELECT);
        privilege1.setCreateTime(System.currentTimeMillis());
        privilege1.setGrantOption(TSentryGrantOption.TRUE);
        sentryStore.alterSentryRoleGrantPrivilege(grantor, roleName, privilege1);
        MSentryRole role = sentryStore.getMSentryRoleByName(roleName);
        Set<MSentryPrivilege> privileges = role.getPrivileges();
        assertEquals(privileges.toString(), 1, privileges.size());

        // 3. g1 grant all on table tb1 to role1, no grant option
        roleName = roles[1];
        grantor = "g1";
        TSentryPrivilege privilege2 = new TSentryPrivilege();
        privilege2.setPrivilegeScope("TABLE");
        privilege2.setServerName(server);
        privilege2.setDbName(db);
        privilege2.setTableName(table);
        privilege2.setAction(AccessConstants.ALL);
        privilege2.setCreateTime(System.currentTimeMillis());
        privilege2.setGrantOption(TSentryGrantOption.FALSE);
        sentryStore.alterSentryRoleGrantPrivilege(grantor, roleName, privilege2);

        // 4. g1 grant select on table tb1 to role2, no grant option
        roleName = roles[2];
        grantor = "g1";
        TSentryPrivilege privilege3 = new TSentryPrivilege();
        privilege3.setPrivilegeScope("TABLE");
        privilege3.setServerName(server);
        privilege3.setDbName(db);
        privilege3.setTableName(table);
        privilege3.setAction(AccessConstants.SELECT);
        privilege3.setCreateTime(System.currentTimeMillis());
        privilege3.setGrantOption(TSentryGrantOption.FALSE);
        sentryStore.alterSentryRoleGrantPrivilege(grantor, roleName, privilege3);

        // 5. user1 has role1, no grant option,
        // revoke from role2 will throw no grant exception
        roleName = roles[2];
        grantor = users[1];
        boolean isGrantOptionException = false;
        try {
            sentryStore.alterSentryRoleRevokePrivilege(grantor, roleName, privilege3);
        } catch (SentryGrantDeniedException e) {
            isGrantOptionException = true;
            System.err.println(e.getMessage());
        }
        assertTrue(isGrantOptionException);

        // 6. user0 has role0, only have select,
        // revoke all from role1 will throw no grant exception
        roleName = roles[1];
        grantor = users[0];
        try {
            sentryStore.alterSentryRoleRevokePrivilege(grantor, roleName, privilege2);
        } catch (SentryGrantDeniedException e) {
            isGrantOptionException = true;
            System.err.println(e.getMessage());
        }
        assertTrue(isGrantOptionException);

        // 7. user0 has role0, has select and grant option,
        // revoke select from role2
        roleName = roles[2];
        grantor = users[0];
        sentryStore.alterSentryRoleRevokePrivilege(grantor, roleName, privilege3);
        role = sentryStore.getMSentryRoleByName(roleName);
        privileges = role.getPrivileges();
        assertEquals(0, privileges.size());
    }

    @Test
    public void testRevokeAllGrantOption() throws Exception {
        // 1. set local group mapping
        // user0->group0->role0
        String grantor = "g1";
        String[] users = { "user0" };
        String[] roles = { "role0" };
        String[] groups = { "group0" };
        for (int i = 0; i < users.length; i++) {
            addGroupsToUser(users[i], groups[i]);
            sentryStore.createSentryRole(roles[i]);
            Set<TSentryGroup> tGroups = Sets.newHashSet();
            TSentryGroup tGroup = new TSentryGroup(groups[i]);
            tGroups.add(tGroup);
            sentryStore.alterSentryRoleAddGroups(grantor, roles[i], tGroups);
        }
        writePolicyFile();

        // 2. g1 grant select on table tb1 to role0, with grant option
        String server = "server1";
        String db = "db1";
        String table = "tbl1";
        String roleName = roles[0];
        grantor = "g1";
        TSentryPrivilege privilege = new TSentryPrivilege();
        privilege.setPrivilegeScope("TABLE");
        privilege.setServerName(server);
        privilege.setDbName(db);
        privilege.setTableName(table);
        privilege.setAction(AccessConstants.SELECT);
        privilege.setCreateTime(System.currentTimeMillis());
        privilege.setGrantOption(TSentryGrantOption.TRUE);
        sentryStore.alterSentryRoleGrantPrivilege(grantor, roleName, privilege);

        // 3. g1 grant select on table tb1 to role0, no grant option
        roleName = roles[0];
        grantor = "g1";
        privilege.setGrantOption(TSentryGrantOption.FALSE);
        sentryStore.alterSentryRoleGrantPrivilege(grantor, roleName, privilege);

        // 4. g1 revoke all privilege from role0
        roleName = roles[0];
        grantor = "g1";
        privilege.setGrantOption(TSentryGrantOption.UNSET);
        sentryStore.alterSentryRoleRevokePrivilege(grantor, roleName, privilege);
        MSentryRole role = sentryStore.getMSentryRoleByName(roleName);
        Set<MSentryPrivilege> privileges = role.getPrivileges();
        assertEquals(privileges.toString(), 0, privileges.size());
    }

    @Test
    public void testGrantCheckWithColumn() throws Exception {
        // 1. set local group mapping
        // user0->group0->role0
        // user1->group1->role1
        String grantor = "g1";
        String[] users = { "user0", "user1" };
        String[] roles = { "role0", "role1" };
        String[] groups = { "group0", "group1" };
        for (int i = 0; i < users.length; i++) {
            addGroupsToUser(users[i], groups[i]);
            sentryStore.createSentryRole(roles[i]);
            Set<TSentryGroup> tGroups = Sets.newHashSet();
            TSentryGroup tGroup = new TSentryGroup(groups[i]);
            tGroups.add(tGroup);
            sentryStore.alterSentryRoleAddGroups(grantor, roles[i], tGroups);
        }
        writePolicyFile();

        // 2. g1 grant select on table tb1 to role0, with grant option
        String server = "server1";
        String db = "db1";
        String table = "tbl1";
        String roleName = roles[0];
        grantor = "g1";
        TSentryPrivilege privilege1 = new TSentryPrivilege();
        privilege1.setPrivilegeScope("TABLE");
        privilege1.setServerName(server);
        privilege1.setDbName(db);
        privilege1.setTableName(table);
        privilege1.setAction(AccessConstants.SELECT);
        privilege1.setCreateTime(System.currentTimeMillis());
        privilege1.setGrantOption(TSentryGrantOption.TRUE);
        sentryStore.alterSentryRoleGrantPrivilege(grantor, roleName, privilege1);
        MSentryRole role = sentryStore.getMSentryRoleByName(roleName);
        Set<MSentryPrivilege> privileges = role.getPrivileges();
        assertEquals(privileges.toString(), 1, privileges.size());

        // 3. user0 grant select on column tb1.c1 to role1, with grant option
        roleName = roles[1];
        grantor = users[0];
        String column = "c1";
        TSentryPrivilege privilege2 = new TSentryPrivilege();
        privilege2.setPrivilegeScope("COLUMN");
        privilege2.setServerName(server);
        privilege2.setDbName(db);
        privilege2.setTableName(table);
        privilege2.setColumnName(column);
        privilege2.setAction(AccessConstants.SELECT);
        privilege2.setCreateTime(System.currentTimeMillis());
        privilege2.setGrantOption(TSentryGrantOption.TRUE);
        sentryStore.alterSentryRoleGrantPrivilege(grantor, roleName, privilege2);

        // 4. user1 revoke table level privilege from user0, will throw grant denied exception
        roleName = roles[0];
        grantor = users[1];
        boolean isGrantOptionException = false;
        try {
            sentryStore.alterSentryRoleRevokePrivilege(grantor, roleName, privilege1);
        } catch (SentryGrantDeniedException e) {
            isGrantOptionException = true;
            System.err.println(e.getMessage());
        }
        assertTrue(isGrantOptionException);

        // 5. user0 revoke column level privilege from user1
        roleName = roles[1];
        grantor = users[0];
        sentryStore.alterSentryRoleRevokePrivilege(grantor, roleName, privilege2);
        role = sentryStore.getMSentryRoleByName(roleName);
        privileges = role.getPrivileges();
        assertEquals(0, privileges.size());
    }

    @Test
    public void testGrantDuplicatePrivilege() throws Exception {
        String roleName = "test-privilege";
        String grantor = "g1";
        String server = "server1";
        String db = "db1";
        String table = "tbl1";
        long seqId = sentryStore.createSentryRole(roleName).getSequenceId();
        TSentryPrivilege privilege = new TSentryPrivilege();
        privilege.setPrivilegeScope("TABLE");
        privilege.setServerName(server);
        privilege.setDbName(db);
        privilege.setTableName(table);
        privilege.setAction(AccessConstants.ALL);
        privilege.setCreateTime(System.currentTimeMillis());
        assertEquals(seqId + 1,
                sentryStore.alterSentryRoleGrantPrivilege(grantor, roleName, privilege).getSequenceId());
        assertEquals(seqId + 2,
                sentryStore.alterSentryRoleGrantPrivilege(grantor, roleName, privilege).getSequenceId());
        privilege.setServerName("Server1");
        privilege.setDbName("DB1");
        privilege.setTableName("TBL1");
        assertEquals(seqId + 3,
                sentryStore.alterSentryRoleGrantPrivilege(grantor, roleName, privilege).getSequenceId());
        MSentryRole role = sentryStore.getMSentryRoleByName(roleName);
        Set<MSentryPrivilege> privileges = role.getPrivileges();
        assertEquals(privileges.toString(), 1, privileges.size());
    }

    @Test
    public void testListSentryPrivilegesForProvider() throws Exception {
        String roleName1 = "list-privs-r1", roleName2 = "list-privs-r2";
        String groupName1 = "list-privs-g1", groupName2 = "list-privs-g2";
        String grantor = "g1";
        long seqId = sentryStore.createSentryRole(roleName1).getSequenceId();
        assertEquals(seqId + 1, sentryStore.createSentryRole(roleName2).getSequenceId());
        TSentryPrivilege privilege1 = new TSentryPrivilege();
        privilege1.setPrivilegeScope("TABLE");
        privilege1.setServerName("server1");
        privilege1.setDbName("db1");
        privilege1.setTableName("tbl1");
        privilege1.setAction("SELECT");
        privilege1.setCreateTime(System.currentTimeMillis());
        assertEquals(seqId + 2,
                sentryStore.alterSentryRoleGrantPrivilege(grantor, roleName1, privilege1).getSequenceId());
        assertEquals(seqId + 3,
                sentryStore.alterSentryRoleGrantPrivilege(grantor, roleName2, privilege1).getSequenceId());
        TSentryPrivilege privilege2 = new TSentryPrivilege();
        privilege2.setPrivilegeScope("SERVER");
        privilege2.setServerName("server1");
        privilege2.setCreateTime(System.currentTimeMillis());
        assertEquals(seqId + 4,
                sentryStore.alterSentryRoleGrantPrivilege(grantor, roleName2, privilege2).getSequenceId());
        Set<TSentryGroup> groups = Sets.newHashSet();
        TSentryGroup group = new TSentryGroup();
        group.setGroupName(groupName1);
        groups.add(group);
        assertEquals(seqId + 5, sentryStore.alterSentryRoleAddGroups(grantor, roleName1, groups).getSequenceId());
        groups.clear();
        group = new TSentryGroup();
        group.setGroupName(groupName2);
        groups.add(group);
        // group 2 has both roles 1 and 2
        assertEquals(seqId + 6, sentryStore.alterSentryRoleAddGroups(grantor, roleName1, groups).getSequenceId());
        assertEquals(seqId + 7, sentryStore.alterSentryRoleAddGroups(grantor, roleName2, groups).getSequenceId());
        // group1 all roles
        assertEquals(Sets.newHashSet("server=server1->db=db1->table=tbl1->action=select"),
                SentryStore.toTrimedLower(sentryStore.listAllSentryPrivilegesForProvider(
                        Sets.newHashSet(groupName1), new TSentryActiveRoleSet(true, new HashSet<String>()))));
        // one active role
        assertEquals(Sets.newHashSet("server=server1->db=db1->table=tbl1->action=select"),
                SentryStore.toTrimedLower(sentryStore.listAllSentryPrivilegesForProvider(
                        Sets.newHashSet(groupName1), new TSentryActiveRoleSet(false, Sets.newHashSet(roleName1)))));
        // unknown active role
        assertEquals(Sets.newHashSet(), SentryStore.toTrimedLower(sentryStore.listAllSentryPrivilegesForProvider(
                Sets.newHashSet(groupName1), new TSentryActiveRoleSet(false, Sets.newHashSet("not a role")))));
        // no active roles
        assertEquals(Sets.newHashSet(), SentryStore.toTrimedLower(sentryStore.listAllSentryPrivilegesForProvider(
                Sets.newHashSet(groupName1), new TSentryActiveRoleSet(false, new HashSet<String>()))));

        // group2 all roles
        assertEquals(Sets.newHashSet("server=server1->db=db1->table=tbl1->action=select", "server=server1"),
                SentryStore.toTrimedLower(sentryStore.listAllSentryPrivilegesForProvider(
                        Sets.newHashSet(groupName2), new TSentryActiveRoleSet(true, new HashSet<String>()))));
        // one active role
        assertEquals(Sets.newHashSet("server=server1->db=db1->table=tbl1->action=select"),
                SentryStore.toTrimedLower(sentryStore.listAllSentryPrivilegesForProvider(
                        Sets.newHashSet(groupName2), new TSentryActiveRoleSet(false, Sets.newHashSet(roleName1)))));
        assertEquals(Sets.newHashSet("server=server1->db=db1->table=tbl1->action=select", "server=server1"),
                SentryStore.toTrimedLower(sentryStore.listAllSentryPrivilegesForProvider(
                        Sets.newHashSet(groupName2), new TSentryActiveRoleSet(false, Sets.newHashSet(roleName2)))));
        // unknown active role
        assertEquals(Sets.newHashSet(), SentryStore.toTrimedLower(sentryStore.listAllSentryPrivilegesForProvider(
                Sets.newHashSet(groupName2), new TSentryActiveRoleSet(false, Sets.newHashSet("not a role")))));
        // no active roles
        assertEquals(Sets.newHashSet(), SentryStore.toTrimedLower(sentryStore.listAllSentryPrivilegesForProvider(
                Sets.newHashSet(groupName2), new TSentryActiveRoleSet(false, new HashSet<String>()))));

        // both groups, all active roles
        assertEquals(Sets.newHashSet("server=server1->db=db1->table=tbl1->action=select", "server=server1"),
                SentryStore.toTrimedLower(
                        sentryStore.listAllSentryPrivilegesForProvider(Sets.newHashSet(groupName1, groupName2),
                                new TSentryActiveRoleSet(true, new HashSet<String>()))));
        // one active role
        assertEquals(Sets.newHashSet("server=server1->db=db1->table=tbl1->action=select"),
                SentryStore.toTrimedLower(
                        sentryStore.listAllSentryPrivilegesForProvider(Sets.newHashSet(groupName1, groupName2),
                                new TSentryActiveRoleSet(false, Sets.newHashSet(roleName1)))));
        assertEquals(Sets.newHashSet("server=server1->db=db1->table=tbl1->action=select", "server=server1"),
                SentryStore.toTrimedLower(
                        sentryStore.listAllSentryPrivilegesForProvider(Sets.newHashSet(groupName1, groupName2),
                                new TSentryActiveRoleSet(false, Sets.newHashSet(roleName2)))));
        // unknown active role
        assertEquals(Sets.newHashSet(),
                SentryStore.toTrimedLower(
                        sentryStore.listAllSentryPrivilegesForProvider(Sets.newHashSet(groupName1, groupName2),
                                new TSentryActiveRoleSet(false, Sets.newHashSet("not a role")))));
        // no active roles
        assertEquals(Sets.newHashSet(), SentryStore.toTrimedLower(sentryStore.listAllSentryPrivilegesForProvider(
                Sets.newHashSet(groupName1, groupName2), new TSentryActiveRoleSet(false, new HashSet<String>()))));
    }

    @Test
    public void testListRole() throws Exception {
        String roleName1 = "role1", roleName2 = "role2", roleName3 = "role3";
        String group1 = "group1", group2 = "group2";
        String grantor = "g1";

        sentryStore.createSentryRole(roleName1);
        sentryStore.createSentryRole(roleName2);
        sentryStore.createSentryRole(roleName3);

        sentryStore.alterSentryRoleAddGroups(grantor, roleName1, Sets.newHashSet(new TSentryGroup(group1)));
        sentryStore.alterSentryRoleAddGroups(grantor, roleName2, Sets.newHashSet(new TSentryGroup(group2)));
        sentryStore.alterSentryRoleAddGroups(grantor, roleName3,
                Sets.newHashSet(new TSentryGroup(group1), new TSentryGroup(group2)));

        assertEquals(2, sentryStore.getTSentryRolesByGroupName(Sets.newHashSet(group1), false).size());
        assertEquals(2, sentryStore.getTSentryRolesByGroupName(Sets.newHashSet(group2), false).size());
        assertEquals(3, sentryStore.getTSentryRolesByGroupName(Sets.newHashSet(group1, group2), false).size());
        assertEquals(0, sentryStore.getTSentryRolesByGroupName(Sets.newHashSet("foo"), true).size());
    }

    /**
     * Assign multiple table and SERVER privileges to roles
     * drop privilege for the object verify that it's removed correctl
     * @throws Exception
     */
    @Test
    public void testDropDbObject() throws Exception {
        String roleName1 = "list-privs-r1", roleName2 = "list-privs-r2", roleName3 = "list-privs-r3";
        String grantor = "g1";
        sentryStore.createSentryRole(roleName1);
        sentryStore.createSentryRole(roleName2);
        sentryStore.createSentryRole(roleName3);

        TSentryPrivilege privilege_tbl1 = new TSentryPrivilege();
        privilege_tbl1.setPrivilegeScope("TABLE");
        privilege_tbl1.setServerName("server1");
        privilege_tbl1.setDbName("db1");
        privilege_tbl1.setTableName("tbl1");
        privilege_tbl1.setCreateTime(System.currentTimeMillis());

        TSentryPrivilege privilege1 = new TSentryPrivilege(privilege_tbl1);
        privilege1.setAction("SELECT");

        TSentryPrivilege privilege2_1 = new TSentryPrivilege(privilege_tbl1);
        privilege2_1.setAction("INSERT");
        TSentryPrivilege privilege3_1 = new TSentryPrivilege(privilege_tbl1);
        privilege3_1.setAction("*");

        TSentryPrivilege privilege_server = new TSentryPrivilege();
        privilege_server.setPrivilegeScope("SERVER");
        privilege_server.setServerName("server1");
        privilege_server.setCreateTime(System.currentTimeMillis());

        TSentryPrivilege privilege_tbl2 = new TSentryPrivilege();
        privilege_tbl2.setPrivilegeScope("TABLE");
        privilege_tbl2.setServerName("server1");
        privilege_tbl2.setDbName("db1");
        privilege_tbl2.setTableName("tbl2");
        privilege_tbl2.setCreateTime(System.currentTimeMillis());

        TSentryPrivilege privilege2_3 = new TSentryPrivilege(privilege_tbl2);
        privilege2_3.setAction("SELECT");

        TSentryPrivilege privilege3_2 = new TSentryPrivilege(privilege_tbl2);
        privilege3_2.setAction("INSERT");

        sentryStore.alterSentryRoleGrantPrivilege(grantor, roleName1, privilege1);

        sentryStore.alterSentryRoleGrantPrivilege(grantor, roleName2, privilege2_1);
        sentryStore.alterSentryRoleGrantPrivilege(grantor, roleName2, privilege_server);
        sentryStore.alterSentryRoleGrantPrivilege(grantor, roleName2, privilege2_3);

        sentryStore.alterSentryRoleGrantPrivilege(grantor, roleName3, privilege3_1);
        sentryStore.alterSentryRoleGrantPrivilege(grantor, roleName3, privilege3_2);

        sentryStore.dropPrivilege(toTSentryAuthorizable(privilege_tbl1));
        assertEquals(0, sentryStore.getAllTSentryPrivilegesByRoleName(roleName1).size());
        assertEquals(2, sentryStore.getAllTSentryPrivilegesByRoleName(roleName2).size());
        assertEquals(1, sentryStore.getAllTSentryPrivilegesByRoleName(roleName3).size());

        sentryStore.dropPrivilege(toTSentryAuthorizable(privilege_tbl2));
        assertEquals(0, sentryStore.getAllTSentryPrivilegesByRoleName(roleName1).size());
        assertEquals(1, sentryStore.getAllTSentryPrivilegesByRoleName(roleName2).size());
        assertEquals(0, sentryStore.getAllTSentryPrivilegesByRoleName(roleName3).size());
    }

    /**
     * Regression test for SENTRY-547 and SENTRY-548
     * Use case:
     * GRANT INSERT on TABLE tbl1 to ROLE role1
     * GRANT SELECT on TABLE tbl1 to ROLE role1
     * GRANT ALTER on TABLE tbl1 to ROLE role1
     * GRANT DROP on TABLE tbl1 to ROLE role1
     * DROP TABLE tbl1
     *
     * After drop tbl1, role1 should have 0 privileges
     */
    @Test
    public void testDropTableWithMultiAction() throws Exception {
        String roleName1 = "role1";
        String grantor = "g1";
        sentryStore.createSentryRole(roleName1);

        TSentryPrivilege privilege_tbl1 = new TSentryPrivilege();
        privilege_tbl1.setPrivilegeScope("TABLE");
        privilege_tbl1.setServerName("server1");
        privilege_tbl1.setDbName("db1");
        privilege_tbl1.setTableName("tbl1");
        privilege_tbl1.setCreateTime(System.currentTimeMillis());

        TSentryPrivilege privilege_tbl1_insert = new TSentryPrivilege(privilege_tbl1);
        privilege_tbl1_insert.setAction(AccessConstants.INSERT);

        TSentryPrivilege privilege_tbl1_select = new TSentryPrivilege(privilege_tbl1);
        privilege_tbl1_select.setAction(AccessConstants.SELECT);

        TSentryPrivilege privilege_tbl1_alter = new TSentryPrivilege(privilege_tbl1);
        privilege_tbl1_alter.setAction(AccessConstants.ALTER);

        TSentryPrivilege privilege_tbl1_drop = new TSentryPrivilege(privilege_tbl1);
        privilege_tbl1_drop.setAction(AccessConstants.DROP);

        sentryStore.alterSentryRoleGrantPrivilege(grantor, roleName1, privilege_tbl1_insert);
        sentryStore.alterSentryRoleGrantPrivilege(grantor, roleName1, privilege_tbl1_select);
        sentryStore.alterSentryRoleGrantPrivilege(grantor, roleName1, privilege_tbl1_alter);
        sentryStore.alterSentryRoleGrantPrivilege(grantor, roleName1, privilege_tbl1_drop);

        assertEquals(4, sentryStore.getAllTSentryPrivilegesByRoleName(roleName1).size());

        // after drop privilege_tbl1, role1 should have 0 privileges
        sentryStore.dropPrivilege(toTSentryAuthorizable(privilege_tbl1));
        assertEquals(0, sentryStore.getAllTSentryPrivilegesByRoleName(roleName1).size());
    }

    @Test
    public void testDropTableWithColumn() throws Exception {
        String roleName1 = "role1", roleName2 = "role2";
        String grantor = "g1";
        String table1 = "tbl1";

        sentryStore.createSentryRole(roleName1);
        sentryStore.createSentryRole(roleName2);

        TSentryPrivilege privilege_tbl1 = new TSentryPrivilege();
        privilege_tbl1.setPrivilegeScope("TABLE");
        privilege_tbl1.setServerName("server1");
        privilege_tbl1.setDbName("db1");
        privilege_tbl1.setTableName(table1);
        privilege_tbl1.setAction(AccessConstants.SELECT);
        privilege_tbl1.setCreateTime(System.currentTimeMillis());

        TSentryPrivilege privilege_tbl1_c1 = new TSentryPrivilege(privilege_tbl1);
        privilege_tbl1_c1.setPrivilegeScope("COLUMN");
        privilege_tbl1_c1.setColumnName("c1");
        privilege_tbl1_c1.setCreateTime(System.currentTimeMillis());

        TSentryPrivilege privilege_tbl1_c2 = new TSentryPrivilege(privilege_tbl1);
        privilege_tbl1_c2.setPrivilegeScope("COLUMN");
        privilege_tbl1_c2.setColumnName("c2");
        privilege_tbl1_c2.setCreateTime(System.currentTimeMillis());

        TSentryPrivilege privilege_tbl1_c3 = new TSentryPrivilege(privilege_tbl1);
        privilege_tbl1_c3.setPrivilegeScope("COLUMN");
        privilege_tbl1_c3.setColumnName("c3");
        privilege_tbl1_c3.setCreateTime(System.currentTimeMillis());

        sentryStore.alterSentryRoleGrantPrivilege(grantor, roleName1, privilege_tbl1_c1);
        sentryStore.alterSentryRoleGrantPrivilege(grantor, roleName1, privilege_tbl1_c2);
        sentryStore.alterSentryRoleGrantPrivilege(grantor, roleName2, privilege_tbl1_c3);

        Set<TSentryPrivilege> privilegeSet = sentryStore.getAllTSentryPrivilegesByRoleName(roleName1);
        assertEquals(2, privilegeSet.size());
        privilegeSet = sentryStore.getAllTSentryPrivilegesByRoleName(roleName2);
        assertEquals(1, privilegeSet.size());

        TSentryAuthorizable tableAuthorizable = toTSentryAuthorizable(privilege_tbl1);
        sentryStore.dropPrivilege(tableAuthorizable);

        privilegeSet = sentryStore.getAllTSentryPrivilegesByRoleName(roleName1);
        assertEquals(0, privilegeSet.size());
        privilegeSet = sentryStore.getAllTSentryPrivilegesByRoleName(roleName2);
        assertEquals(0, privilegeSet.size());
    }

    @Test
    public void testDropOverlappedPrivileges() throws Exception {
        String roleName1 = "list-privs-r1";
        String grantor = "g1";
        sentryStore.createSentryRole(roleName1);

        TSentryPrivilege privilege_tbl1 = new TSentryPrivilege();
        privilege_tbl1.setPrivilegeScope("TABLE");
        privilege_tbl1.setServerName("server1");
        privilege_tbl1.setDbName("db1");
        privilege_tbl1.setTableName("tbl1");
        privilege_tbl1.setCreateTime(System.currentTimeMillis());

        TSentryPrivilege privilege_tbl1_insert = new TSentryPrivilege(privilege_tbl1);
        privilege_tbl1_insert.setAction("INSERT");

        TSentryPrivilege privilege_tbl1_all = new TSentryPrivilege(privilege_tbl1);
        privilege_tbl1_all.setAction("*");

        sentryStore.alterSentryRoleGrantPrivilege(grantor, roleName1, privilege_tbl1_insert);
        sentryStore.alterSentryRoleGrantPrivilege(grantor, roleName1, privilege_tbl1_all);

        sentryStore.dropPrivilege(toTSentryAuthorizable(privilege_tbl1));
        assertEquals(0, sentryStore.getAllTSentryPrivilegesByRoleName(roleName1).size());
    }

    private TSentryAuthorizable toTSentryAuthorizable(TSentryPrivilege tSentryPrivilege) {
        TSentryAuthorizable tSentryAuthorizable = new TSentryAuthorizable();
        tSentryAuthorizable.setServer(tSentryPrivilege.getServerName());
        tSentryAuthorizable.setDb(tSentryPrivilege.getDbName());
        tSentryAuthorizable.setTable(tSentryPrivilege.getTableName());
        tSentryAuthorizable.setUri(tSentryPrivilege.getURI());
        return tSentryAuthorizable;
    }

    /***
     * Create roles and assign privileges for same table rename the privileges for
     * the table and verify the new privileges
     * @throws Exception
     */
    @Test
    public void testRenameTable() throws Exception {
        String roleName1 = "role1", roleName2 = "role2", roleName3 = "role3";
        String grantor = "g1";
        String table1 = "tbl1", table2 = "tbl2";

        sentryStore.createSentryRole(roleName1);
        sentryStore.createSentryRole(roleName2);
        sentryStore.createSentryRole(roleName3);

        TSentryPrivilege privilege_tbl1 = new TSentryPrivilege();
        privilege_tbl1.setPrivilegeScope("TABLE");
        privilege_tbl1.setServerName("server1");
        privilege_tbl1.setDbName("db1");
        privilege_tbl1.setTableName(table1);
        privilege_tbl1.setCreateTime(System.currentTimeMillis());

        TSentryPrivilege privilege_tbl1_insert = new TSentryPrivilege(privilege_tbl1);
        privilege_tbl1_insert.setAction(AccessConstants.INSERT);

        TSentryPrivilege privilege_tbl1_select = new TSentryPrivilege(privilege_tbl1);
        privilege_tbl1_select.setAction(AccessConstants.SELECT);

        TSentryPrivilege privilege_tbl1_all = new TSentryPrivilege(privilege_tbl1);
        privilege_tbl1_all.setAction(AccessConstants.ALL);

        sentryStore.alterSentryRoleGrantPrivilege(grantor, roleName1, privilege_tbl1_insert);
        sentryStore.alterSentryRoleGrantPrivilege(grantor, roleName2, privilege_tbl1_select);
        sentryStore.alterSentryRoleGrantPrivilege(grantor, roleName3, privilege_tbl1_all);

        TSentryAuthorizable oldTable = toTSentryAuthorizable(privilege_tbl1);
        TSentryAuthorizable newTable = toTSentryAuthorizable(privilege_tbl1);
        newTable.setTable(table2);
        sentryStore.renamePrivilege(oldTable, newTable);

        for (String roleName : Sets.newHashSet(roleName1, roleName2, roleName3)) {
            Set<TSentryPrivilege> privilegeSet = sentryStore.getAllTSentryPrivilegesByRoleName(roleName);
            assertEquals(1, privilegeSet.size());
            for (TSentryPrivilege privilege : privilegeSet) {
                assertTrue(table2.equalsIgnoreCase(privilege.getTableName()));
            }
        }
    }

    /**
     * Regression test for SENTRY-550
     * Use case:
     * GRANT INSERT on TABLE tbl1 to ROLE role1
     * GRANT SELECT on TABLE tbl1 to ROLE role1
     * GRANT ALTER on TABLE tbl1 to ROLE role1
     * GRANT DROP on TABLE tbl1 to ROLE role1
     * RENAME TABLE tbl1 to tbl2
     *
     * After rename tbl1 to tbl2, table name of all role1's privileges should be "tbl2"
     */
    @Test
    public void testRenameTableWithMultiAction() throws Exception {
        String roleName1 = "role1";
        String grantor = "g1";
        String table1 = "tbl1", table2 = "tbl2";
        sentryStore.createSentryRole(roleName1);

        TSentryPrivilege privilege_tbl1 = new TSentryPrivilege();
        privilege_tbl1.setPrivilegeScope("TABLE");
        privilege_tbl1.setServerName("server1");
        privilege_tbl1.setDbName("db1");
        privilege_tbl1.setTableName(table1);
        privilege_tbl1.setCreateTime(System.currentTimeMillis());

        TSentryPrivilege privilege_tbl1_insert = new TSentryPrivilege(privilege_tbl1);
        privilege_tbl1_insert.setAction(AccessConstants.INSERT);

        TSentryPrivilege privilege_tbl1_select = new TSentryPrivilege(privilege_tbl1);
        privilege_tbl1_select.setAction(AccessConstants.SELECT);

        TSentryPrivilege privilege_tbl1_alter = new TSentryPrivilege(privilege_tbl1);
        privilege_tbl1_alter.setAction(AccessConstants.ALTER);

        TSentryPrivilege privilege_tbl1_drop = new TSentryPrivilege(privilege_tbl1);
        privilege_tbl1_drop.setAction(AccessConstants.DROP);

        sentryStore.alterSentryRoleGrantPrivilege(grantor, roleName1, privilege_tbl1_insert);
        sentryStore.alterSentryRoleGrantPrivilege(grantor, roleName1, privilege_tbl1_select);
        sentryStore.alterSentryRoleGrantPrivilege(grantor, roleName1, privilege_tbl1_alter);
        sentryStore.alterSentryRoleGrantPrivilege(grantor, roleName1, privilege_tbl1_drop);

        TSentryAuthorizable oldTable = toTSentryAuthorizable(privilege_tbl1);
        TSentryAuthorizable newTable = toTSentryAuthorizable(privilege_tbl1);
        newTable.setTable(table2);
        sentryStore.renamePrivilege(oldTable, newTable);

        // after rename tbl1 to tbl2, all table name of role's privilege will be tbl2
        Set<TSentryPrivilege> privilegeSet = sentryStore.getAllTSentryPrivilegesByRoleName(roleName1);
        assertEquals(4, privilegeSet.size());
        for (TSentryPrivilege privilege : privilegeSet) {
            assertTrue(table2.equalsIgnoreCase(privilege.getTableName()));
        }
    }

    @Test
    public void testSentryRoleSize() throws Exception {
        for (long i = 0; i < 5; i++) {
            assertEquals((Long) i, sentryStore.getRoleCountGauge().getValue());
            sentryStore.createSentryRole("role" + i);
        }
    }

    @Test
    public void testSentryPrivilegeSize() throws Exception {
        String role1 = "role1";
        String role2 = "role2";

        sentryStore.createSentryRole(role1);
        sentryStore.createSentryRole(role2);

        TSentryPrivilege privilege = new TSentryPrivilege();
        privilege.setPrivilegeScope("TABLE");
        privilege.setServerName("server1");
        privilege.setDbName("db1");
        privilege.setTableName("tb1");
        privilege.setCreateTime(System.currentTimeMillis());

        String grantor = "g1";

        assertEquals(new Long(0), sentryStore.getPrivilegeCountGauge().getValue());

        sentryStore.alterSentryRoleGrantPrivilege(grantor, role1, privilege);
        assertEquals(new Long(1), sentryStore.getPrivilegeCountGauge().getValue());

        sentryStore.alterSentryRoleGrantPrivilege(grantor, role2, privilege);
        assertEquals(new Long(1), sentryStore.getPrivilegeCountGauge().getValue());

        privilege.setTableName("tb2");
        sentryStore.alterSentryRoleGrantPrivilege(grantor, role2, privilege);
        assertEquals(new Long(2), sentryStore.getPrivilegeCountGauge().getValue());
    }

    @Test
    public void testSentryGroupsSize() throws Exception {
        String role1 = "role1";
        String role2 = "role2";

        sentryStore.createSentryRole(role1);
        sentryStore.createSentryRole(role2);

        Set<TSentryGroup> groups = Sets.newHashSet();
        TSentryGroup group = new TSentryGroup();
        group.setGroupName("group1");
        groups.add(group);

        String grantor = "g1";

        sentryStore.alterSentryRoleAddGroups(grantor, role1, groups);
        assertEquals(new Long(1), sentryStore.getGroupCountGauge().getValue());

        sentryStore.alterSentryRoleAddGroups(grantor, role2, groups);
        assertEquals(new Long(1), sentryStore.getGroupCountGauge().getValue());

        groups.add(new TSentryGroup("group2"));
        sentryStore.alterSentryRoleAddGroups(grantor, role2, groups);
        assertEquals(new Long(2), sentryStore.getGroupCountGauge().getValue());

    }

    @Test
    public void testRenameTableWithColumn() throws Exception {
        String roleName1 = "role1", roleName2 = "role2";
        String grantor = "g1";
        String table1 = "tbl1", table2 = "tbl2";

        sentryStore.createSentryRole(roleName1);
        sentryStore.createSentryRole(roleName2);

        TSentryPrivilege privilege_tbl1 = new TSentryPrivilege();
        privilege_tbl1.setPrivilegeScope("TABLE");
        privilege_tbl1.setServerName("server1");
        privilege_tbl1.setDbName("db1");
        privilege_tbl1.setTableName(table1);
        privilege_tbl1.setAction(AccessConstants.SELECT);
        privilege_tbl1.setCreateTime(System.currentTimeMillis());

        TSentryPrivilege privilege_tbl1_c1 = new TSentryPrivilege(privilege_tbl1);
        privilege_tbl1_c1.setPrivilegeScope("COLUMN");
        privilege_tbl1_c1.setColumnName("c1");
        privilege_tbl1_c1.setCreateTime(System.currentTimeMillis());

        TSentryPrivilege privilege_tbl1_c2 = new TSentryPrivilege(privilege_tbl1);
        privilege_tbl1_c2.setPrivilegeScope("COLUMN");
        privilege_tbl1_c2.setColumnName("c2");
        privilege_tbl1_c2.setCreateTime(System.currentTimeMillis());

        TSentryPrivilege privilege_tbl1_c3 = new TSentryPrivilege(privilege_tbl1);
        privilege_tbl1_c3.setPrivilegeScope("COLUMN");
        privilege_tbl1_c3.setColumnName("c3");
        privilege_tbl1_c3.setCreateTime(System.currentTimeMillis());

        sentryStore.alterSentryRoleGrantPrivilege(grantor, roleName1, privilege_tbl1_c1);
        sentryStore.alterSentryRoleGrantPrivilege(grantor, roleName1, privilege_tbl1_c2);
        sentryStore.alterSentryRoleGrantPrivilege(grantor, roleName2, privilege_tbl1_c3);

        Set<TSentryPrivilege> privilegeSet = sentryStore.getAllTSentryPrivilegesByRoleName(roleName1);
        assertEquals(2, privilegeSet.size());
        privilegeSet = sentryStore.getAllTSentryPrivilegesByRoleName(roleName2);
        assertEquals(1, privilegeSet.size());

        TSentryAuthorizable oldTable = toTSentryAuthorizable(privilege_tbl1);
        TSentryAuthorizable newTable = toTSentryAuthorizable(privilege_tbl1);
        newTable.setTable(table2);
        sentryStore.renamePrivilege(oldTable, newTable);

        privilegeSet = sentryStore.getAllTSentryPrivilegesByRoleName(roleName1);
        assertEquals(2, privilegeSet.size());
        for (TSentryPrivilege privilege : privilegeSet) {
            assertTrue(table2.equalsIgnoreCase(privilege.getTableName()));
        }
        privilegeSet = sentryStore.getAllTSentryPrivilegesByRoleName(roleName2);
        assertEquals(1, privilegeSet.size());
    }

    protected static void addGroupsToUser(String user, String... groupNames) {
        policyFile.addGroupsToUser(user, groupNames);
    }

    protected static void writePolicyFile() throws Exception {
        policyFile.write(policyFilePath);
    }

}