/**
 * 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 java.io.File;
import java.time.Instant;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;

import com.google.common.collect.Lists;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.StringUtils;
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.SentryOwnerInfo;
import org.apache.sentry.api.common.ApiConstants.PrivilegeScope;
import org.apache.sentry.api.service.thrift.TSentryPrivilegeMap;
import org.apache.sentry.core.common.exception.SentryAccessDeniedException;
import org.apache.sentry.core.common.exception.SentryInvalidInputException;
import org.apache.sentry.core.common.utils.SentryConstants;
import org.apache.sentry.core.model.db.AccessConstants;
import org.apache.sentry.core.common.exception.SentryAlreadyExistsException;
import org.apache.sentry.core.common.exception.SentryNoSuchObjectException;
import org.apache.sentry.hdfs.PathsUpdate;
import org.apache.sentry.hdfs.PermissionsUpdate;
import org.apache.sentry.hdfs.UniquePathsUpdate;
import org.apache.sentry.hdfs.Updateable;
import org.apache.sentry.hdfs.service.thrift.TPathEntry;
import org.apache.sentry.hdfs.service.thrift.TPathsDump;
import org.apache.sentry.hdfs.service.thrift.TPathsUpdate;
import org.apache.sentry.hdfs.service.thrift.TPrivilegeChanges;
import org.apache.sentry.hdfs.service.thrift.TPrivilegePrincipal;
import org.apache.sentry.hdfs.service.thrift.TPrivilegePrincipalType;
import org.apache.sentry.hdfs.service.thrift.TRoleChanges;
import org.apache.sentry.provider.db.service.model.MSentryPermChange;
import org.apache.sentry.provider.db.service.model.MSentryPathChange;
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.model.MPath;
import org.apache.sentry.api.service.thrift.TSentryActiveRoleSet;
import org.apache.sentry.api.service.thrift.TSentryAuthorizable;
import org.apache.sentry.api.service.thrift.TSentryGrantOption;
import org.apache.sentry.api.service.thrift.TSentryGroup;
import org.apache.sentry.api.service.thrift.TSentryPrivilege;
import org.apache.sentry.api.service.thrift.TSentryRole;
import org.apache.sentry.provider.db.service.model.MSentryUser;
import org.apache.sentry.provider.file.PolicyFile;
import org.apache.sentry.api.common.SentryServiceUtil;
import org.apache.sentry.service.common.ServiceConstants;
import org.apache.sentry.service.common.ServiceConstants.SentryPrincipalType;
import org.apache.sentry.service.common.ServiceConstants.ServerConfig;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;

import com.google.common.collect.Iterables;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import com.google.common.io.Files;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import static org.apache.sentry.provider.db.service.persistent.QueryParamBuilder.newQueryParamBuilder;

import javax.jdo.JDODataStoreException;

public class TestSentryStore extends org.junit.Assert {

  private static final Logger LOGGER = LoggerFactory.getLogger(TestSentryStore.class);

  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 = 5;  // > 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(true);
    final String ourUrl = UserProvider.SCHEME_NAME + ":///";
    conf.set(CredentialProviderFactory.CREDENTIAL_PROVIDER_PATH, ourUrl);

    // enable HDFS sync, so perm and path changes will be saved into DB
    conf.set(ServiceConstants.ServerConfig.PROCESSOR_FACTORIES, "org.apache.sentry.hdfs.SentryHDFSServiceProcessorFactory");
    conf.set(ServiceConstants.ServerConfig.SENTRY_POLICY_STORE_PLUGINS, "org.apache.sentry.hdfs.SentryPlugin");

    // THis should be a UserGroupInformation provider
    CredentialProvider provider = CredentialProviderFactory.getProviders(conf).get(0);


    // The user credentials are stored as a static variable by UserGrouoInformation provider.
    // We need to only set the password the first time, an attempt to set it for the second
    // time fails with an exception.
    if(provider.getCredentialEntry(ServerConfig.SENTRY_STORE_JDBC_PASS) == null) {
      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());

    // These tests do not need to retry transactions, so setting to 1 to reduce testing time
    conf.setInt(ServerConfig.SENTRY_STORE_TRANSACTION_RETRY, 1);

    // SentryStore should be initialized only once. The tables created by the test cases will
    // be cleaned up during the @After method.
    sentryStore = new SentryStore(conf);

    boolean hdfsSyncEnabled = SentryServiceUtil.isHDFSSyncEnabled(conf);
    sentryStore.setPersistUpdateDeltas(hdfsSyncEnabled);
  }

  @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 (dataDir != null) {
      FileUtils.deleteQuietly(dataDir);
    }

    sentryStore.stop();
  }

  /**
   * Fail test if role already exists
   * @param roleName Role name to checl
   * @throws Exception
   */
  private void checkRoleDoesNotExist(String roleName) throws Exception {
    try {
      sentryStore.getMSentryRoleByName(roleName);
      fail("Role " + roleName + "already exists");
    } catch (SentryNoSuchObjectException e) {
      // Ok
    }
  }

  /**
   * Fail test if role doesn't exist
   * @param roleName Role name to checl
   * @throws Exception
   */
  private void checkRoleExists(String roleName) throws Exception {
    assertEquals(roleName.toLowerCase(),
            sentryStore.getMSentryRoleByName(roleName).getRoleName());
  }

  /**
   * Create a role with the given name and verify that it is created
   * @param roleName
   * @throws Exception
   */
  private void createRole(String roleName) throws Exception {
    checkRoleDoesNotExist(roleName);
    sentryStore.createSentryRole(roleName);
    checkRoleExists(roleName);
  }

  @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());

    Set<String> users = Sets.newHashSet("user1");

    createRole(roleName);

    sentryStore.alterSentryRoleAddGroups(grantor, roleName, groups);
    sentryStore.alterSentryRoleDeleteGroups(roleName, groups);
    sentryStore.alterSentryRoleAddUsers(roleName, users);
    MSentryUser user = sentryStore.getMSentryUserByName(users.iterator().next());
    assertNotNull(user);

    sentryStore.alterSentryRoleDeleteUsers(roleName, users);
    user = sentryStore.getMSentryUserByName(users.iterator().next(), false);
    assertNull(user);

    sentryStore.alterSentryGrantPrivileges(SentryPrincipalType.ROLE, roleName, Sets.newHashSet(privilege), null);
    sentryStore.alterSentryRevokePrivileges(SentryPrincipalType.ROLE, roleName, Sets.newHashSet(privilege), null);
  }

  @Test
  public void testURI() throws Exception {
    String roleName1 = "test-role1";
    String roleName2 = "test-role2";
    String grantor = "g1";
    String uri1 = "file:///var/folders/dt/9zm44z9s6bjfxbrm4v36lzdc0000gp/T/1401860678102-0/data/kv1.dat";
    String uri2 = "file:///var/folders/dt/9zm44z9s6bjfxbrm4v36lzdc0000gp/T/1401860678102-0/data/kv2.dat";
    createRole(roleName1);
    createRole(roleName2);
    TSentryPrivilege tSentryPrivilege1 = new TSentryPrivilege("URI", "server1", "ALL");
    tSentryPrivilege1.setURI(uri1);
    TSentryPrivilege tSentryPrivilege2 = new TSentryPrivilege("URI", "server1", "ALL");
    tSentryPrivilege2.setURI(uri2);
    sentryStore.alterSentryGrantPrivileges(SentryPrincipalType.ROLE, roleName1, Sets.newHashSet(tSentryPrivilege1), null);
    sentryStore.alterSentryGrantPrivileges(SentryPrincipalType.ROLE, roleName2, Sets.newHashSet(tSentryPrivilege2), null);

    TSentryAuthorizable tSentryAuthorizable1 = new TSentryAuthorizable();
    tSentryAuthorizable1.setUri(uri1);
    tSentryAuthorizable1.setServer("server1");

    TSentryAuthorizable tSentryAuthorizable2 = new TSentryAuthorizable();
    tSentryAuthorizable2.setUri(uri2);
    tSentryAuthorizable2.setServer("server1");

    Set<TSentryPrivilege> privileges =
        sentryStore.getTSentryPrivileges(SentryPrincipalType.ROLE, new HashSet<String>(Arrays.asList(roleName1, roleName2)), tSentryAuthorizable1);

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

    //Test with other URI Authorizable
    privileges =
        sentryStore.getTSentryPrivileges(SentryPrincipalType.ROLE, new HashSet<String>(Arrays.asList(roleName1, roleName2)), tSentryAuthorizable2);
    assertTrue(privileges.size() == 1);

    Set<TSentryGroup> tSentryGroups = new HashSet<TSentryGroup>();
    tSentryGroups.add(new TSentryGroup("group1"));
    sentryStore.alterSentryRoleAddGroups(grantor, roleName1, tSentryGroups);
    sentryStore.alterSentryRoleAddUsers(roleName1, Sets.newHashSet("user1"));
    sentryStore.alterSentryRoleAddGroups(grantor, roleName2, tSentryGroups);
    sentryStore.alterSentryRoleAddUsers(roleName2, Sets.newHashSet("user1"));

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

    // list privilege for group only
    Set<String> privs = sentryStore.listSentryPrivilegesForProvider(
        new HashSet<String>(Arrays.asList("group1")), Sets.newHashSet(""), thriftRoleSet,
        tSentryAuthorizable1);
    assertTrue(privs.size()==1);
    assertTrue(privs.contains("server=server1->uri=" + uri1 + "->action=all"));

    privs = sentryStore.listSentryPrivilegesForProvider(
        new HashSet<String>(Arrays.asList("group1")), Sets.newHashSet(""), thriftRoleSet,
        tSentryAuthorizable2);
    assertTrue(privs.size()==1);
    assertTrue(privs.contains("server=server1->uri=" + uri2 + "->action=all"));

    // list privilege for user only
    privs = sentryStore.listSentryPrivilegesForProvider(new HashSet<String>(Arrays.asList("")),
        Sets.newHashSet("user1"), thriftRoleSet, tSentryAuthorizable1);
    assertTrue(privs.size() == 1);
    assertTrue(privs.contains("server=server1->uri=" + uri1 + "->action=all"));

    privs = sentryStore.listSentryPrivilegesForProvider(new HashSet<String>(Arrays.asList("")),
        Sets.newHashSet("user1"), thriftRoleSet, tSentryAuthorizable2);
    assertTrue(privs.size() == 1);
    assertTrue(privs.contains("server=server1->uri=" + uri2 + "->action=all"));

    // list privilege for both user and group
    privs = sentryStore.listSentryPrivilegesForProvider(
        new HashSet<String>(Arrays.asList("group1")), Sets.newHashSet("user1"), thriftRoleSet,
        tSentryAuthorizable1);
    assertTrue(privs.size() == 1);
    assertTrue(privs.contains("server=server1->uri=" + uri1 + "->action=all"));

    privs = sentryStore.listSentryPrivilegesForProvider(
        new HashSet<String>(Arrays.asList("group1")), Sets.newHashSet("user1"), thriftRoleSet,
        tSentryAuthorizable2);
    assertTrue(privs.size() == 1);
    assertTrue(privs.contains("server=server1->uri=" + uri2 + "->action=all"));
  }

  @Test
  public void testURIGrantRevokeOnEmptyPath() throws Exception {
    String roleName = "test-empty-uri-role";
    String uri = "";
    createRole(roleName);
    TSentryPrivilege tSentryPrivilege = new TSentryPrivilege("URI", "server1", "ALL");
    tSentryPrivilege.setURI(uri);
    //Test grant on empty URI
    try {
      sentryStore.alterSentryGrantPrivileges(SentryPrincipalType.ROLE, roleName, Sets.newHashSet(tSentryPrivilege), null);
      fail("Expected SentryInvalidInputException");
    } catch(SentryInvalidInputException e) {
      // expected
    }
    //Test revoke on empty URI
    try {
      sentryStore.alterSentryRevokePrivileges(SentryPrincipalType.ROLE, roleName, Sets.newHashSet(tSentryPrivilege), null);
      fail("Expected SentryInvalidInputException");
    } catch(SentryInvalidInputException e) {
      // expected
    }
  }

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

  @Test
  public void testCaseSensitiveScope() throws Exception {
    String roleName = "role1";
    createRole(roleName);
    TSentryPrivilege sentryPrivilege = new TSentryPrivilege("Database", "server1", "all");
    sentryPrivilege.setDbName("db1");
    sentryStore.alterSentryGrantPrivileges(SentryPrincipalType.ROLE, roleName, Sets.newHashSet(sentryPrivilege), null);
  }

  /**
   * Create a new role and then destroy it
   * @throws Exception
   */
  @Test
  public void testCreateDropRole() throws Exception {
    String roleName = "test-drop-role";
    createRole(roleName);
    sentryStore.dropSentryRole(roleName);
    checkRoleDoesNotExist(roleName);
  }

  @Test
  public void testAddDeleteGroupsNonExistantRole()
      throws Exception {
    String roleName = "non-existant-role";
    String grantor = "g1";
    Set<TSentryGroup> groups = Sets.newHashSet();
    Set<String> users = Sets.newHashSet(grantor);
    try {
      sentryStore.alterSentryRoleAddGroups(grantor, roleName, groups);
      fail("Expected SentryNoSuchObjectException exception");
    } catch (SentryNoSuchObjectException e) {
      // excepted exception
    }
    try {
      sentryStore.alterSentryRoleAddUsers(roleName, users);
      fail("Expected SentryNoSuchObjectException exception");
    } catch (SentryNoSuchObjectException e) {
      // excepted exception
    }
  }

  @Test
  public void testAddDeleteGroups() throws Exception {
    String roleName = "test-groups";
    String grantor = "g1";
    createRole(roleName);
    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);
    sentryStore.alterSentryRoleAddGroups(grantor, roleName, groups);
    sentryStore.alterSentryRoleDeleteGroups(roleName, groups);
    MSentryRole role = sentryStore.getMSentryRoleByName(roleName);
    assertEquals(Collections.emptySet(), role.getGroups());
  }

  @Test
  public void testAddDeleteUsers() throws Exception {
    String roleName = "test-users";
    createRole(roleName);
    Set<String> users = Sets.newHashSet("test-user-u1", "test-user-u2");
    sentryStore.alterSentryRoleAddUsers(roleName, users);
    MSentryRole role = sentryStore.getMSentryRoleByName(roleName);
    role.getUsers().size();
    sentryStore.alterSentryRoleDeleteUsers(roleName, users);
    role = sentryStore.getMSentryRoleByName(roleName);
    assertEquals(0, role.getUsers().size());
  }

  @Test
  public void testGetTSentryRolesForUser() throws Exception {
    // Test the method GetTSentryRolesForUser according to the following test data:
    // user1->group1
    // user2->group1
    // user3->group1, group2
    // user4->group2, group3
    // group1->r1
    // group2->r2
    // group3->r2
    // user2->r3
    // user4->r3
    String roleName1 = "r1";
    String roleName2 = "r2";
    String roleName3 = "r3";
    String user1 = "u1";
    String user2 = "u2";
    String user3 = "u3";
    String user4 = "u4";
    String group1 = "group1";
    String group2 = "group2";
    String group3 = "group3";
    Map<String, Set<String>> userToGroups = Maps.newHashMap();
    userToGroups.put(user1, Sets.newHashSet(group1));
    userToGroups.put(user2, Sets.newHashSet(group1));
    userToGroups.put(user3, Sets.newHashSet(group1, group2));
    userToGroups.put(user4, Sets.newHashSet(group2, group3));

    sentryStore.createSentryRole(roleName1);
    sentryStore.createSentryRole(roleName2);
    sentryStore.createSentryRole(roleName3);
    sentryStore.alterSentryRoleAddUsers(roleName1, Sets.newHashSet(user1));
    sentryStore.alterSentryRoleAddUsers(roleName2, Sets.newHashSet(user2));
    sentryStore.alterSentryRoleAddUsers(roleName2, Sets.newHashSet(user3));
    sentryStore.alterSentryRoleAddUsers(roleName3, Sets.newHashSet(user2, user4));

    Set<TSentryRole> roles = sentryStore.getTSentryRolesByUserNames(Sets.newHashSet(user1));
    assertEquals(1, roles.size());
    for (TSentryRole role : roles) {
      assertTrue(roleName1.equals(role.getRoleName()));
    }

    roles = sentryStore.getTSentryRolesByUserNames(Sets.newHashSet(user2));
    assertEquals(2, roles.size());
    for (TSentryRole role : roles) {
      assertTrue(roleName2.equals(role.getRoleName()) || roleName3.equals(role.getRoleName()));
    }

    roles = sentryStore.getTSentryRolesByUserNames(Sets.newHashSet(user3));
    assertEquals(1, roles.size());
    for (TSentryRole role : roles) {
      assertTrue(roleName2.equals(role.getRoleName()));
    }

    roles = sentryStore.getTSentryRolesByUserNames(Sets.newHashSet(user4));
    assertEquals(1, roles.size());
    for (TSentryRole role : roles) {
      assertTrue(roleName3.equals(role.getRoleName()));
    }
  }

  @Test
  public void testGetTSentryRolesForUsers() throws Exception {
    // Test the method getTSentryRolesByUserNames according to the following test data:
    // user1->r1
    // user2->r3
    // user3->r2
    // user4->r3, r2
    String roleName1 = "r1";
    String roleName2 = "r2";
    String roleName3 = "r3";
    String user1 = "u1";
    String user2 = "u2";
    String user3 = "u3";
    String user4 = "u4";

    createRole(roleName1);
    createRole(roleName2);
    createRole(roleName3);
    sentryStore.alterSentryRoleAddUsers(roleName1, Sets.newHashSet(user1));
    sentryStore.alterSentryRoleAddUsers(roleName2, Sets.newHashSet(user3));
    sentryStore.alterSentryRoleAddUsers(roleName2, Sets.newHashSet(user4));
    sentryStore.alterSentryRoleAddUsers(roleName3, Sets.newHashSet(user2, user4));

    Set<String> userSet1 = Sets.newHashSet(user1, user2, user3);
    Set<String> roleSet1 = Sets.newHashSet(roleName1, roleName2, roleName3);

    Set<String> userSet2 = Sets.newHashSet(user4);
    Set<String> roleSet2 = Sets.newHashSet(roleName2, roleName3);

    Set<String> userSet3 = Sets.newHashSet("foo");
    Set<String> roleSet3 = Sets.newHashSet();

    // Query for multiple users
    Set<String> roles = convertToRoleNameSet(sentryStore.getTSentryRolesByUserNames(userSet1));
    assertEquals("Returned roles should match the expected roles", 0, Sets.symmetricDifference(roles, roleSet1).size());

    // Query for single users
    roles = convertToRoleNameSet(sentryStore.getTSentryRolesByUserNames(userSet2));
    assertEquals("Returned roles should match the expected roles", 0, Sets.symmetricDifference(roles, roleSet2).size());

    // Query for non-existing user
    roles = convertToRoleNameSet(sentryStore.getTSentryRolesByUserNames(userSet3));
    assertEquals("Returned roles should match the expected roles", 0, Sets.symmetricDifference(roles, roleSet3).size());
  }

  private Set<String> convertToRoleNameSet(Set<TSentryRole> tSentryRoles) {
    Set<String> roleNameSet = Sets.newHashSet();
    for (TSentryRole role : tSentryRoles) {
      roleNameSet.add(role.getRoleName());
    }
    return roleNameSet;
  }

  @Test
  public void testGetTSentryRolesForGroups() throws Exception {
    // Test the method getRoleNamesForGroups according to the following test data:
    // group1->r1
    // group2->r2
    // group3->r2
    String grantor = "g1";
    String roleName1 = "r1";
    String roleName2 = "r2";
    String roleName3 = "r3";
    String group1 = "group1";
    String group2 = "group2";
    String group3 = "group3";

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

    Set<String> groupSet1 = Sets.newHashSet(group1, group2, group3);
    Set<String> roleSet1 = Sets.newHashSet(roleName1, roleName2);

    Set<String> groupSet2 = Sets.newHashSet(group1);
    Set<String> roleSet2 = Sets.newHashSet(roleName1);

    Set<String> groupSet3 = Sets.newHashSet("foo");
    Set<String> roleSet3 = Sets.newHashSet();

    // Query for multiple groups
    Set<String> roles = sentryStore.getRoleNamesForGroups(groupSet1);
    assertEquals("Returned roles should match the expected roles", 0, Sets.symmetricDifference(roles, roleSet1).size());

    // Query for single group
    roles = sentryStore.getRoleNamesForGroups(groupSet2);
    assertEquals("Returned roles should match the expected roles", 0, Sets.symmetricDifference(roles, roleSet2).size());

    // Query for non-existing group
    roles = sentryStore.getRoleNamesForGroups(groupSet3);
    assertEquals("Returned roles should match the expected roles", 0, Sets.symmetricDifference(roles, roleSet3).size());
  }

  @Test
  public void testGrantRevokePrivilege() throws Exception {
    String roleName = "test-privilege";
    String server = "server1";
    String db = "db1";
    String table = "tbl1";
    createRole(roleName);
    TSentryPrivilege privilege = new TSentryPrivilege();
    privilege.setPrivilegeScope("TABLE");
    privilege.setServerName(server);
    privilege.setDbName(db);
    privilege.setTableName(table);
    privilege.setAction(AccessConstants.ALL);
    privilege.setCreateTime(System.currentTimeMillis());
    sentryStore.alterSentryGrantPrivileges(SentryPrincipalType.ROLE, roleName, Sets.newHashSet(privilege), null);
    MSentryRole role = sentryStore.getMSentryRoleByName(roleName);
    Set<MSentryPrivilege> privileges = role.getPrivileges();
    assertEquals(privileges.toString(), 1, privileges.size());
    privilege.setAction(AccessConstants.SELECT);
    sentryStore.alterSentryRevokePrivileges(SentryPrincipalType.ROLE, roleName, Sets.newHashSet(privilege), null);
    // after having ALL and revoking SELECT, we should have INSERT
    role = sentryStore.getMSentryRoleByName(roleName);
    privileges = role.getPrivileges();
    assertEquals(privileges.toString(), 1, privileges.size());
    for (MSentryPrivilege mPrivilege : privileges) {
      assertEquals(server, mPrivilege.getServerName());
      assertEquals(db, mPrivilege.getDbName());
      assertEquals(table, mPrivilege.getTableName());
      assertNotSame(AccessConstants.SELECT, mPrivilege.getAction());
      assertFalse(mPrivilege.getGrantOption());
    }
    long numDBPrivs = sentryStore.countMSentryPrivileges();
    assertEquals("Privilege count", numDBPrivs,1);
  }

  private void verifyOrphanCleanup() throws Exception {
    assertFalse("Failed to cleanup orphaned privileges", sentryStore.findOrphanedPrivileges());
  }

  /**
   * 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 server = "server";
    final String dBase = "db";
    final String table = "table-";

    createRole(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.alterSentryGrantPrivileges(SentryPrincipalType.ROLE, roleName, Sets.newHashSet(priv), null);
    }

    // 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();

    List<MSentryPrivilege> list = sentryStore.getAllMSentryPrivileges();
    assertEquals(list.size(), 0);
  }

  /**
   * 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 server = "server";
    final String dBase = "db";
    final String table = "table-";

    createRole(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.alterSentryGrantPrivileges(SentryPrincipalType.ROLE, roleName, Sets.newHashSet(priv), null);

      priv.setAction(AccessConstants.SELECT);
      priv.setGrantOption(TSentryGrantOption.UNSET);
      sentryStore.alterSentryRevokePrivileges(SentryPrincipalType.ROLE, roleName, Sets.newHashSet(priv), null);
      // after having ALL and revoking SELECT, we should have INSERT
      MSentryRole role = sentryStore.getMSentryRoleByName(roleName);
      Set<MSentryPrivilege> privileges = role.getPrivileges();
      assertEquals(privileges.toString(), 1 * (i+1), privileges.size());
      for ( MSentryPrivilege mSentryPrivilege : privileges) {
        assertNotSame(AccessConstants.INSERT, mSentryPrivilege.getAction());
        assertNotSame(AccessConstants.ALL, mSentryPrivilege.getAction());
      }
    }

    // Drop the role and clean up as before
    sentryStore.dropSentryRole(roleName);
    verifyOrphanCleanup();
    //There should not be any Privileges left
    List<MSentryPrivilege> list = sentryStore.getAllMSentryPrivileges();
    assertEquals(list.size(), 0);
  }

  /**
   * This method tries to add ALL privileges on
   * databases to a role and immediately revokes
   * SELECT and INSERT privileges. At the end of
   * each iteration we should not find any privileges
   * for that role. Finally we should not find any
   * privileges, as we are cleaning up orphan privileges
   * immediately.
   * @throws Exception
   */
  @Test
  public void testPrivilegeCleanup3() throws Exception {
    final String roleName = "test-priv-cleanup";
    final String server = "server";
    final String dBase = "db";
    final String table = "table-";

    createRole(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.alterSentryGrantPrivileges(SentryPrincipalType.ROLE, roleName, Sets.newHashSet(priv), null);

      priv.setAction(AccessConstants.SELECT);
      priv.setGrantOption(TSentryGrantOption.UNSET);
      sentryStore.alterSentryRevokePrivileges(SentryPrincipalType.ROLE, roleName, Sets.newHashSet(priv), null);

      assertFalse(sentryStore.findOrphanedPrivileges());

      //After having ALL and revoking SELECT, we should have INSERT
      //Remove the INSERT privilege as well.
      //There should not be any more privileges in the sentry store
      priv.setAction(AccessConstants.INSERT);
      sentryStore.alterSentryRevokePrivileges(SentryPrincipalType.ROLE, roleName, Sets.newHashSet(priv), null);

      MSentryRole role = sentryStore.getMSentryRoleByName(roleName);
      assertEquals("Privilege Count", 0, role.getPrivileges().size());

      priv.setAction(AccessConstants.CREATE);
      sentryStore.alterSentryRevokePrivileges(SentryPrincipalType.ROLE, roleName, Sets.newHashSet(priv), null);

      role = sentryStore.getMSentryRoleByName(roleName);
      assertEquals("Privilege Count", 0, role.getPrivileges().size());

      priv.setAction(AccessConstants.DROP);
      sentryStore.alterSentryRevokePrivileges(SentryPrincipalType.ROLE, roleName, Sets.newHashSet(priv), null);

      role = sentryStore.getMSentryRoleByName(roleName);
      assertEquals("Privilege Count", 0, role.getPrivileges().size());

      priv.setAction(AccessConstants.ALTER);
      sentryStore.alterSentryRevokePrivileges(SentryPrincipalType.ROLE, roleName, Sets.newHashSet(priv), null);

      role = sentryStore.getMSentryRoleByName(roleName);
      assertEquals("Privilege Count", 0, role.getPrivileges().size());
    }

    // Drop the role and clean up as before
    verifyOrphanCleanup();

    //There should not be any Privileges left
    List<MSentryPrivilege> list = sentryStore.getAllMSentryPrivileges();
    assertEquals(list.size(), 0);

  }

  /**
   * This method "n" privileges with action "ALL" on
   * tables to a role. Later we are revoking insert
   * and select privileges to of the tables making the
   * the privilege orphan. Finally we should find only
   * n -1 privileges, as we are cleaning up orphan
   * privileges immediately.
   * @throws Exception
   */
  @Test
  public void testPrivilegeCleanup4 () throws Exception {
    final String roleName = "test-priv-cleanup";
    final String server = "server";
    final String dBase = "db";
    final String table = "table-";

    createRole(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.alterSentryGrantPrivileges(SentryPrincipalType.ROLE, roleName, Sets.newHashSet(priv), null);
    }

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

    //Revoking INSERT privilege. This is change the privilege to SELECT, CREATE, DROP, ALTER
    TSentryPrivilege priv = new TSentryPrivilege();
    priv.setPrivilegeScope("TABLE");
    priv.setServerName(server);
    priv.setAction(AccessConstants.INSERT);
    priv.setCreateTime(System.currentTimeMillis());
    priv.setTableName(table + '0');
    priv.setDbName(dBase);
    sentryStore.alterSentryRevokePrivileges(SentryPrincipalType.ROLE, roleName, Sets.newHashSet(priv), null);

    //There should be SELECT privilege in the sentry store
    priv = new TSentryPrivilege();
    priv.setPrivilegeScope("TABLE");
    priv.setServerName(server);
    priv.setAction(AccessConstants.SELECT);
    priv.setCreateTime(System.currentTimeMillis());
    priv.setTableName(table + '0');
    priv.setDbName(dBase);
    MSentryPrivilege mPriv = sentryStore.findMSentryPrivilegeFromTSentryPrivilege(priv);
    assertNotNull(mPriv);

    MSentryRole role = sentryStore.getMSentryRoleByName(roleName);

    // should have NUM_PRIVS - 1 ALL privileges, and 4 privileges (SELECT, CREATE, DROP, ALTER)
    assertEquals("Privilege Count", NUM_PRIVS, role.getPrivileges().size());

    sentryStore.alterSentryRevokePrivileges(SentryPrincipalType.ROLE, roleName, Sets.newHashSet(priv), null);
    role = sentryStore.getMSentryRoleByName(roleName);
    assertEquals("Privilege Count", NUM_PRIVS - 1, role.getPrivileges().size());

  }

  /**
   * This method tries to add alter privileges on
   * databases to a role and immediately revokes
   * them. At the end of each iteration we should
   * not find any privileges for that role
   * Finally we should not find any privileges, as
   * we are cleaning up orphan privileges immediately.
   * @throws Exception
   */
  @Test
  public void testPrivilegeCleanup5() throws Exception {
    final String roleName = "test-priv-cleanup";
    final String server = "server";
    final String dBase = "db";
    final String table = "table-";

    createRole(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.ALTER);
      priv.setCreateTime(System.currentTimeMillis());
      priv.setTableName(table + i);
      priv.setDbName(dBase);
      priv.setGrantOption(TSentryGrantOption.TRUE);
      sentryStore.alterSentryGrantPrivileges(SentryPrincipalType.ROLE, roleName, Sets.newHashSet(priv), null);

      priv.setAction(AccessConstants.ALTER);
      sentryStore.alterSentryRevokePrivileges( SentryPrincipalType.ROLE, roleName, Sets.newHashSet(priv), null);

      MSentryRole role = sentryStore.getMSentryRoleByName(roleName);
      assertEquals("Privilege Count", 0, role.getPrivileges().size());
    }
    //There should not be any Privileges left
    List<MSentryPrivilege> list = sentryStore.getAllMSentryPrivileges();
    assertEquals(list.size(), 0);

  }

  @Test
  public void testDropIndividualPrivilegesWhenGrantAllIsGranted() throws Exception {
    final String ROLE_NAME = "r1";
    final String SERVER_NAME = "server1";
    final String DB_NAME = "db1";
    final String TABLE_NAME = "table1";

    TSentryPrivilege allPrivilege = toTSentryPrivilege(AccessConstants.ACTION_ALL,
      PrivilegeScope.SERVER.toString(), SERVER_NAME, DB_NAME, TABLE_NAME, TSentryGrantOption.FALSE);

    TSentryPrivilege allWithGrant = toTSentryPrivilege(AccessConstants.ACTION_ALL,
      PrivilegeScope.SERVER.toString(), SERVER_NAME, DB_NAME, TABLE_NAME, TSentryGrantOption.TRUE);

    TSentryPrivilege ownerPrivilege = toTSentryPrivilege(AccessConstants.OWNER,
      PrivilegeScope.DATABASE.toString(), SERVER_NAME, DB_NAME, TABLE_NAME);

    Set<TSentryPrivilege> grantPrivileges = Sets.newHashSet(
      toTSentryPrivilege(AccessConstants.SELECT, PrivilegeScope.SERVER.toString(), SERVER_NAME,
        DB_NAME, TABLE_NAME),
      toTSentryPrivilege(AccessConstants.INSERT, PrivilegeScope.SERVER.toString(), SERVER_NAME,
        DB_NAME, TABLE_NAME),
      toTSentryPrivilege(AccessConstants.CREATE, PrivilegeScope.SERVER.toString(), SERVER_NAME,
        DB_NAME, TABLE_NAME),
      toTSentryPrivilege(AccessConstants.ALTER, PrivilegeScope.SERVER.toString(), SERVER_NAME,
        DB_NAME, TABLE_NAME),
      toTSentryPrivilege(AccessConstants.DROP, PrivilegeScope.SERVER.toString(), SERVER_NAME,
        DB_NAME, TABLE_NAME),
      toTSentryPrivilege(AccessConstants.INDEX, PrivilegeScope.SERVER.toString(), SERVER_NAME,
        DB_NAME, TABLE_NAME),
      toTSentryPrivilege(AccessConstants.LOCK, PrivilegeScope.SERVER.toString(), SERVER_NAME,
        DB_NAME, TABLE_NAME),

      // This special privilege will not be removed when granting all privileges
      ownerPrivilege
    );

    // Grant individual privileges to a role
    createRole(ROLE_NAME);
    sentryStore.alterSentryRoleGrantPrivileges(ROLE_NAME, grantPrivileges);

    // Check those individual privileges are granted
    Set<TSentryPrivilege> rolePrivileges = sentryStore.getAllTSentryPrivilegesByRoleName(ROLE_NAME);
    assertEquals(grantPrivileges.size(), rolePrivileges.size());
    for (TSentryPrivilege privilege : grantPrivileges) {
      assertTrue(String.format("Privilege %s was not granted.", privilege.getAction()),
        rolePrivileges.contains(privilege));
    }

    // Grant the ALL privilege (this should remove all individual privileges, and grant only ALL)
    sentryStore.alterSentryRoleGrantPrivileges(ROLE_NAME, Sets.newHashSet(allPrivilege));

    // Check the ALL and OWNER privileges are the only privileges
    rolePrivileges = sentryStore.getAllTSentryPrivilegesByRoleName(ROLE_NAME);
    assertEquals(2, rolePrivileges.size()); // ALL and OWNER privileges should be there
    assertTrue("Privilege ALL was not granted.", rolePrivileges.contains(allPrivilege));
    assertTrue("Privilege OWNER was dropped.", rolePrivileges.contains(ownerPrivilege));

    // Check the ALL WITH GRANT privilege just replaces the ALL and keeps the OWNER privilege
    sentryStore.alterSentryRoleGrantPrivileges(ROLE_NAME, Sets.newHashSet(allWithGrant));
    rolePrivileges = sentryStore.getAllTSentryPrivilegesByRoleName(ROLE_NAME);
    assertTrue("Privilege ALL WITH GRANT was not granted.", rolePrivileges.contains(allWithGrant));
    assertTrue("Privilege OWNER was dropped.", rolePrivileges.contains(ownerPrivilege));

    // Check the ALL privilege just replaces the ALL WITH GRANT and keeps the OWNER privilege
    sentryStore.alterSentryRoleGrantPrivileges(ROLE_NAME, Sets.newHashSet(allPrivilege));
    rolePrivileges = sentryStore.getAllTSentryPrivilegesByRoleName(ROLE_NAME);
    assertTrue("Privilege ALL was not granted.", rolePrivileges.contains(allPrivilege));
    assertTrue("Privilege OWNER was dropped.", rolePrivileges.contains(ownerPrivilege));


    // Clean-up test
    sentryStore.dropSentryRole(ROLE_NAME);
  }

  //TODO Use new transaction Manager logic, Instead of

  @Test
  public void testGrantRevokeMultiPrivileges() throws Exception {
    String roleName = "test-privilege";
    String server = "server1";
    String db = "db1";
    String table = "tbl1";
    String[] columns = {"c1","c2","c3","c4"};
    createRole(roleName);
    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);
    }
    sentryStore.alterSentryRoleGrantPrivileges(roleName, tPrivileges);
    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);
    }
    sentryStore.alterSentryRoleRevokePrivileges(roleName, tPrivileges);
    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());
    sentryStore.alterSentryRevokePrivileges(SentryPrincipalType.ROLE, roleName, Sets.newHashSet(privilege), null);
    // 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 server = "server1";
    String db = "db1";
    String table = "tbl1";
    String column1 = "c1";
    String column2 = "c2";
    createRole(roleName);
    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
    sentryStore.alterSentryGrantPrivileges(SentryPrincipalType.ROLE, roleName, Sets.newHashSet(privilege), null);
    privilege.setColumnName(column2);
    sentryStore.alterSentryGrantPrivileges(SentryPrincipalType.ROLE, roleName, Sets.newHashSet(privilege), null);
    MSentryRole role = sentryStore.getMSentryRoleByName(roleName);
    Set<MSentryPrivilege> privileges = role.getPrivileges();
    assertEquals(privileges.toString(), 2, privileges.size());

    // Revoke SELECT on c2
    privilege.setAction(AccessConstants.SELECT);
    sentryStore.alterSentryRevokePrivileges(SentryPrincipalType.ROLE, roleName, Sets.newHashSet(privilege), null);

    // At this point c1 has ALL privileges and c2 should have (INSERT, CREATE, DROP, ALTER)
    // 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)) {
        assertNotSame(AccessConstants.SELECT, mPrivilege.getAction());
        assertNotSame(AccessConstants.ALL, mPrivilege.getAction());
      } else {
        fail("Unexpected column name: " + mPrivilege.getColumnName());
      }
    }

    // after revoking INSERT table level privilege will remove INSERT 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());
    sentryStore.alterSentryRevokePrivileges(SentryPrincipalType.ROLE, roleName, Sets.newHashSet(privilege), null);
    role = sentryStore.getMSentryRoleByName(roleName);
    privileges = role.getPrivileges();
    assertEquals(privileges.toString(), 1, privileges.size());

    // Revoke ALL from the table should now remove all the column privileges.
    privilege.setAction(AccessConstants.ALL);
    privilege.setCreateTime(System.currentTimeMillis());
    sentryStore.alterSentryRevokePrivileges(SentryPrincipalType.ROLE, roleName, Sets.newHashSet(privilege), null);
    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 server = "server1";
    String db = "db1";
    String table1 = "tbl1";
    String table2 = "tbl2";
    createRole(roleName);
    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
    sentryStore.alterSentryGrantPrivileges(SentryPrincipalType.ROLE, roleName, Sets.newHashSet(privilegeTable1), null);
    sentryStore.alterSentryGrantPrivileges(SentryPrincipalType.ROLE, roleName, Sets.newHashSet(privilegeTable2), null);
    MSentryRole role = sentryStore.getMSentryRoleByName(roleName);
    Set<MSentryPrivilege> privileges = role.getPrivileges();
    assertEquals(privileges.toString(), 2, privileges.size());

    // Revoke SELECT on table2
    privilegeTable2.setAction(AccessConstants.SELECT);
    sentryStore.alterSentryRevokePrivileges(SentryPrincipalType.ROLE, roleName, Sets.newHashSet(privilegeTable2), null);
    // after having ALL and revoking SELECT, we should have (INSERT) at table2
    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)) {
        assertNotSame(AccessConstants.SELECT, mPrivilege.getAction());
        assertNotSame(AccessConstants.ALL, mPrivilege.getAction());
      } else {
        fail("Unexpected table name: " + mPrivilege.getTableName());
      }
    }

    // Revoke INSERT on Database
    privilegeTable2.setAction(AccessConstants.INSERT);
    privilegeTable2.setPrivilegeScope("DATABASE");
    privilegeTable2.unsetTableName();
    sentryStore.alterSentryRevokePrivileges(SentryPrincipalType.ROLE, roleName, Sets.newHashSet(privilegeTable2), null);
    role = sentryStore.getMSentryRoleByName(roleName);
    privileges = role.getPrivileges();

    // after revoking INSERT database level privilege
    // table1 should have (SELECT)
    // table2 should have ()
    assertEquals(privileges.toString(), 1, privileges.size());
    for (MSentryPrivilege mPrivilege : privileges) {
      assertEquals(server, mPrivilege.getServerName());
      assertEquals(db, mPrivilege.getDbName());
      if (table1.equals(mPrivilege.getTableName())) {
        assertNotSame(AccessConstants.INSERT, mPrivilege.getAction());
        assertNotSame(AccessConstants.ALL, mPrivilege.getAction());
      } else if (table2.equals(mPrivilege.getTableName())) {
        assertNotSame(AccessConstants.INSERT, mPrivilege.getAction());
        assertNotSame(AccessConstants.SELECT, mPrivilege.getAction());
        assertNotSame(AccessConstants.ALL, mPrivilege.getAction());
      }
      assertFalse(mPrivilege.getGrantOption());
    }
  }

  /**
   * Regression test for SENTRY-552
   */
  @Test
  public void testGrantRevokeColumnPrivilegeDowngradeByDb() throws Exception {
    String roleName = "test-column-db-downgrade-privilege";
    String server = "server1";
    String db = "db1";
    String table = "tbl1";
    String column1 = "c1";
    String column2 = "c2";
    createRole(roleName);
    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
    sentryStore.alterSentryGrantPrivileges(SentryPrincipalType.ROLE, roleName, Sets.newHashSet(privilegeCol1), null);
    sentryStore.alterSentryGrantPrivileges(SentryPrincipalType.ROLE, roleName, Sets.newHashSet(privilegeCol2), null);
    MSentryRole role = sentryStore.getMSentryRoleByName(roleName);
    Set<MSentryPrivilege> privileges = role.getPrivileges();
    assertEquals(privileges.toString(), 2, privileges.size());

    // Revoke SELECT on column2
    privilegeCol2.setAction(AccessConstants.SELECT);
    sentryStore.alterSentryRevokePrivileges(SentryPrincipalType.ROLE, roleName, Sets.newHashSet(privilegeCol2), null);
    // after having ALL and revoking SELECT, we should have (INSERT)
    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)) {
        assertNotSame(AccessConstants.SELECT, mPrivilege.getAction());
      } else {
        fail("Unexpected column name: " + mPrivilege.getColumnName());
      }
    }

    // Revoke INSERT on Database
    privilegeCol2.setAction(AccessConstants.INSERT);
    privilegeCol2.setPrivilegeScope("DATABASE");
    privilegeCol2.unsetTableName();
    privilegeCol2.unsetColumnName();
    sentryStore.alterSentryRevokePrivileges(SentryPrincipalType.ROLE, roleName, Sets.newHashSet(privilegeCol2), null);
    role = sentryStore.getMSentryRoleByName(roleName);
    privileges = role.getPrivileges();

    // after revoking INSERT database level privilege
    // column2 has ()
    // and downgrade column1 to (SELECT) privileges.
    assertEquals(privileges.toString(), 1, privileges.size());
    for (MSentryPrivilege mPrivilege : privileges) {
      assertEquals(server, mPrivilege.getServerName());
      assertEquals(db, mPrivilege.getDbName());
      assertEquals(table, mPrivilege.getTableName());
      if (column1.equals(mPrivilege.getColumnName())) {
        assertNotSame(AccessConstants.INSERT, mPrivilege.getAction());
      } else if (column1.equals(mPrivilege.getColumnName())) {
        assertNotSame(AccessConstants.SELECT, mPrivilege.getAction());
        assertNotSame(AccessConstants.INSERT, mPrivilege.getAction());
      }
      assertFalse(mPrivilege.getGrantOption());
    }
  }

  @Test
  public void testGrantRevokePrivilegeWithGrantOption() throws Exception {
    String roleName = "test-grantOption-table";
    String server = "server1";
    String db = "db1";
    String table = "tbl1";
    TSentryGrantOption grantOption = TSentryGrantOption.TRUE;
    createRole(roleName);

    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);
    sentryStore.alterSentryGrantPrivileges(SentryPrincipalType.ROLE, roleName, Sets.newHashSet(privilege), null);
    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());
    sentryStore.alterSentryRevokePrivileges(SentryPrincipalType.ROLE, roleName, Sets.newHashSet(privilege), null);
    role = sentryStore.getMSentryRoleByName(roleName);
    privileges = role.getPrivileges();
    assertEquals(0, privileges.size());

    roleName = "test-grantOption-db";

    createRole(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.alterSentryGrantPrivileges(SentryPrincipalType.ROLE, roleName, Sets.newHashSet(privilege), null);
    role = sentryStore.getMSentryRoleByName(roleName);
    privileges = role.getPrivileges();
    assertEquals(privileges.toString(), 1, privileges.size());

    privilege.setAction(AccessConstants.SELECT);
    privilege.setGrantOption(TSentryGrantOption.UNSET);
    sentryStore.alterSentryRevokePrivileges(SentryPrincipalType.ROLE, roleName, Sets.newHashSet(privilege), null);
    // after having ALL and revoking SELECT, we should have (INSERT)
    role = sentryStore.getMSentryRoleByName(roleName);
    privileges = role.getPrivileges();
    assertEquals(privileges.toString(), 1, privileges.size());
    for (MSentryPrivilege mPrivilege : privileges) {
      assertEquals(server, mPrivilege.getServerName());
      assertEquals(db, mPrivilege.getDbName());
      assertNotSame(AccessConstants.SELECT, mPrivilege.getAction());
    }
  }

  @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];
    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.alterSentryGrantPrivileges(SentryPrincipalType.ROLE, roleName, Sets.newHashSet(privilege), null);

    // 3. g1 grant select on table tb1 to role0, no grant option
    roleName = roles[0];
    privilege.setGrantOption(TSentryGrantOption.FALSE);
    sentryStore.alterSentryGrantPrivileges(SentryPrincipalType.ROLE, roleName, Sets.newHashSet(privilege), null);

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

  @Test
  public void testGrantDuplicatePrivilege() throws Exception {
    String roleName = "test-privilege";
    String server = "server1";
    String db = "db1";
    String table = "tbl1";
    createRole(roleName);
    TSentryPrivilege privilege = new TSentryPrivilege();
    privilege.setPrivilegeScope("TABLE");
    privilege.setServerName(server);
    privilege.setDbName(db);
    privilege.setTableName(table);
    privilege.setAction(AccessConstants.ALL);
    privilege.setCreateTime(System.currentTimeMillis());
    sentryStore.alterSentryGrantPrivileges(SentryPrincipalType.ROLE, roleName, Sets.newHashSet(privilege), null);
    sentryStore.alterSentryGrantPrivileges(SentryPrincipalType.ROLE, roleName, Sets.newHashSet(privilege), null);
    privilege.setServerName("Server1");
    privilege.setDbName("DB1");
    privilege.setTableName("TBL1");
    sentryStore.alterSentryGrantPrivileges(SentryPrincipalType.ROLE, roleName, Sets.newHashSet(privilege), null);
    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 userName1 = "list-privs-u1", userName2 = "list-privs-u2";
    String userWithoutRole = "user-no-privs";
    Set<String> noRoleUsers = Sets.newHashSet(userWithoutRole);
    String grantor = "g1";
    sentryStore.createSentryRole(roleName1);
    sentryStore.createSentryRole(roleName2);
    TSentryPrivilege privilege1 = new TSentryPrivilege();
    privilege1.setPrivilegeScope("TABLE");
    privilege1.setServerName("server1");
    privilege1.setDbName("db1");
    privilege1.setTableName("tbl1");
    privilege1.setAction("SELECT");
    privilege1.setCreateTime(System.currentTimeMillis());
    sentryStore.alterSentryGrantPrivileges(SentryPrincipalType.ROLE, roleName1, Sets.newHashSet(privilege1), null);
    sentryStore.alterSentryGrantPrivileges(SentryPrincipalType.ROLE, roleName2, Sets.newHashSet(privilege1), null);
    TSentryPrivilege privilege2 = new TSentryPrivilege();
    privilege2.setPrivilegeScope("SERVER");
    privilege2.setServerName("server1");
    privilege2.setCreateTime(System.currentTimeMillis());
    sentryStore.alterSentryGrantPrivileges(SentryPrincipalType.ROLE, roleName2, Sets.newHashSet(privilege2), null);
    Set<TSentryGroup> groups = Sets.newHashSet();
    Set<String> users = Sets.newHashSet();
    TSentryGroup group = new TSentryGroup();
    group.setGroupName(groupName1);
    groups.add(group);
    users.add(userName1);
    sentryStore.alterSentryRoleAddGroups(grantor, roleName1, groups);
    sentryStore.alterSentryRoleAddUsers(roleName1, users);
    groups.clear();
    users.clear();
    group = new TSentryGroup();
    group.setGroupName(groupName2);
    groups.add(group);
    users.add(userName2);
    // group 2 and user2 has both roles 1 and 2
    sentryStore.alterSentryRoleAddGroups(grantor, roleName1, groups);
    sentryStore.alterSentryRoleAddGroups(grantor, roleName2, groups);
    sentryStore.alterSentryRoleAddUsers(roleName1, users);
    sentryStore.alterSentryRoleAddUsers(roleName2, users);
    // group1 all roles
    assertEquals(Sets.newHashSet("server=server1->db=db1->table=tbl1->action=select"),
        SentryStore.toTrimedLower(sentryStore.listAllSentryPrivilegesForProvider(Sets
            .newHashSet(groupName1), noRoleUsers, new TSentryActiveRoleSet(true,
            new HashSet<String>()))));
    // user1 all roles
    assertEquals(Sets.newHashSet("server=server1->db=db1->table=tbl1->action=select"),
        SentryStore.toTrimedLower(sentryStore.listAllSentryPrivilegesForProvider(Sets
            .newHashSet(""), Sets.newHashSet(userName1), new TSentryActiveRoleSet(true,
            new HashSet<String>()))));
    // group1 and user1 all roles
    assertEquals(Sets.newHashSet("server=server1->db=db1->table=tbl1->action=select"),
        SentryStore.toTrimedLower(sentryStore.listAllSentryPrivilegesForProvider(Sets
            .newHashSet(groupName1), Sets.newHashSet(userName1), 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), noRoleUsers,
            new TSentryActiveRoleSet(false, Sets.newHashSet(roleName1)))));
    // unknown active role
    assertEquals(
        Sets.newHashSet(),
        SentryStore.toTrimedLower(sentryStore.listAllSentryPrivilegesForProvider(
            Sets.newHashSet(groupName1), noRoleUsers,
            new TSentryActiveRoleSet(false, Sets.newHashSet("not a role")))));
    // no active roles
    assertEquals(Sets.newHashSet(), SentryStore.toTrimedLower(sentryStore
        .listAllSentryPrivilegesForProvider(Sets.newHashSet(groupName1), noRoleUsers,
            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), Sets.newHashSet(""),
            new TSentryActiveRoleSet(true, new HashSet<String>()))));
    // user2 all roles
    assertEquals(Sets.newHashSet("server=server1->db=db1->table=tbl1->action=select",
        "server=server1"), SentryStore.toTrimedLower(sentryStore
        .listAllSentryPrivilegesForProvider(Sets.newHashSet(""), Sets.newHashSet(userName2),
            new TSentryActiveRoleSet(true, new HashSet<String>()))));
    // user2 and group2 all roles
    assertEquals(Sets.newHashSet("server=server1->db=db1->table=tbl1->action=select",
        "server=server1"), SentryStore.toTrimedLower(sentryStore
        .listAllSentryPrivilegesForProvider(Sets.newHashSet(groupName2),
            Sets.newHashSet(userName2), 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), noRoleUsers,
            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), noRoleUsers,
            new TSentryActiveRoleSet(false, Sets.newHashSet(roleName2)))));
    // unknown active role
    assertEquals(
        Sets.newHashSet(),
        SentryStore.toTrimedLower(sentryStore.listAllSentryPrivilegesForProvider(
            Sets.newHashSet(groupName2), noRoleUsers,
            new TSentryActiveRoleSet(false, Sets.newHashSet("not a role")))));
    // no active roles
    assertEquals(Sets.newHashSet(), SentryStore.toTrimedLower(sentryStore
        .listAllSentryPrivilegesForProvider(Sets.newHashSet(groupName2), noRoleUsers,
            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), noRoleUsers,
            new TSentryActiveRoleSet(true, new HashSet<String>()))));
    // both users and 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), Sets
            .newHashSet(userName1, userName2),
            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), noRoleUsers,
            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), noRoleUsers,
            new TSentryActiveRoleSet(false, Sets.newHashSet(roleName2)))));
    // unknown active role
    assertEquals(Sets.newHashSet(), SentryStore.toTrimedLower(sentryStore
        .listAllSentryPrivilegesForProvider(Sets.newHashSet(groupName1, groupName2), noRoleUsers,
            new TSentryActiveRoleSet(false, Sets.newHashSet("not a role")))));
    // no active roles
    assertEquals(Sets.newHashSet(), SentryStore.toTrimedLower(sentryStore
        .listAllSentryPrivilegesForProvider(Sets.newHashSet(groupName1, groupName2), noRoleUsers,
            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 and users
   * drop privilege for the object verify that it's removed correctly
   * @throws Exception
   */
  @Test
  public void testDropDbObject() throws Exception {
    String roleName1 = "list-privs-r1", roleName2 = "list-privs-r2", roleName3 = "list-privs-r3";
    String userName1 = "user-1", userName2 = "user-2";
    sentryStore.createSentryRole(roleName1);
    sentryStore.createSentryRole(roleName2);
    sentryStore.createSentryRole(roleName3);
    sentryStore.createSentryUser(userName1);
    sentryStore.createSentryUser(userName2);

    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.alterSentryGrantPrivileges(SentryPrincipalType.ROLE, roleName1, Sets.newHashSet(privilege1), null);

    sentryStore.alterSentryGrantPrivileges(SentryPrincipalType.ROLE, roleName2, Sets.newHashSet(privilege2_1), null);
    sentryStore.alterSentryGrantPrivileges(SentryPrincipalType.ROLE, roleName2, Sets.newHashSet(privilege_server), null);
    sentryStore.alterSentryGrantPrivileges(SentryPrincipalType.ROLE, roleName2, Sets.newHashSet(privilege2_3), null);

    sentryStore.alterSentryGrantPrivileges(SentryPrincipalType.ROLE, roleName3, Sets.newHashSet(privilege3_1), null);
    sentryStore.alterSentryGrantPrivileges(SentryPrincipalType.ROLE, roleName3, Sets.newHashSet(privilege3_2), null);

    sentryStore.alterSentryGrantPrivileges(SentryPrincipalType.USER, userName1, Sets.newHashSet(privilege1), null);
    sentryStore.alterSentryGrantPrivileges(SentryPrincipalType.USER, userName2, Sets.newHashSet(privilege2_3), null);


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


    try {
      sentryStore.getAllTSentryPrivilegesByUserName(userName1);
      fail("Should have received an exception");
    } catch (Exception e) {

    }
    assertEquals(1, sentryStore.getAllTSentryPrivilegesByUserName(userName2)
            .size());
    sentryStore.dropPrivilege(toTSentryAuthorizable(privilege_tbl2));
    assertEquals(0, sentryStore.getAllTSentryPrivilegesByRoleName(roleName1)
        .size());
    assertEquals(1, sentryStore.getAllTSentryPrivilegesByRoleName(roleName2)
        .size());
    assertEquals(0, sentryStore.getAllTSentryPrivilegesByRoleName(roleName3)
        .size());
    try {
      sentryStore.getAllTSentryPrivilegesByUserName(userName2);
      fail("Should have received an exception");
    } catch (Exception e) {
    }
  }

  /**
   * Grants owner privileges to role/user and updates the owner
   * and makes sure that the owner privilege is updated.
   * @throws Exception
   */
  @Test
  public void testUpdateOwnerPrivilege() throws Exception {
    String roleName1 = "list-privs-r1", roleName2 = "list-privs-r2", roleName3 = "list-privs-r3";
    String userName1 = "user1", userName2 = "user2";
    List<SentryOwnerInfo> ownerInfoList  = null;
    sentryStore.createSentryRole(roleName1);
    sentryStore.createSentryRole(roleName2);
    sentryStore.createSentryRole(roleName3);
    sentryStore.createSentryUser(userName1);
    sentryStore.createSentryUser(userName2);


    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());
    privilege_tbl1.setAction("OWNER");

    TSentryAuthorizable tSentryAuthorizable = new TSentryAuthorizable();
    tSentryAuthorizable.setServer("server1");
    tSentryAuthorizable.setDb("db1");
    tSentryAuthorizable.setTable("tbl1");

    sentryStore.alterSentryGrantPrivileges(SentryPrincipalType.ROLE, roleName1, Sets.newHashSet(privilege_tbl1), null);

    assertEquals(1, sentryStore.getAllTSentryPrivilegesByRoleName(roleName1)
            .size());
    assertEquals(0, sentryStore.getAllTSentryPrivilegesByRoleName(roleName2)
            .size());

    ownerInfoList  = sentryStore.listOwnersByAuthorizable(tSentryAuthorizable);
    assertEquals(1, ownerInfoList.size());
    assertEquals(SentryPrincipalType.ROLE, ownerInfoList.get(0).getOwnerType());
    assertEquals(roleName1, ownerInfoList.get(0).getOwnerName());


    // Change owner from a one role to another role
    sentryStore.updateOwnerPrivilege(tSentryAuthorizable, roleName2, SentryPrincipalType.ROLE, null);
    ownerInfoList  = sentryStore.listOwnersByAuthorizable(tSentryAuthorizable);
    assertEquals(1, ownerInfoList.size());
    assertEquals(SentryPrincipalType.ROLE, ownerInfoList.get(0).getOwnerType());
    assertEquals(roleName2, ownerInfoList.get(0).getOwnerName());

    assertEquals(0, sentryStore.getAllTSentryPrivilegesByRoleName(roleName1)
            .size());
    assertEquals(1, sentryStore.getAllTSentryPrivilegesByRoleName(roleName2)
            .size());

    tSentryAuthorizable.setTable("tbl2");
    TSentryPrivilege privilege_tbl2 = new TSentryPrivilege(privilege_tbl1);
    privilege_tbl2.setTableName("tbl2");

    // Change owner from a one user to another user
    sentryStore.alterSentryGrantPrivileges(SentryPrincipalType.USER,userName1, Sets.newHashSet(privilege_tbl2), null);
    assertEquals(1, sentryStore.getAllTSentryPrivilegesByUserName(userName1)
            .size());



    sentryStore.updateOwnerPrivilege(tSentryAuthorizable, userName2, SentryPrincipalType.USER, null);
    assertEquals(1, sentryStore.getAllTSentryPrivilegesByUserName(userName2)
            .size());
    ownerInfoList  = sentryStore.listOwnersByAuthorizable(tSentryAuthorizable);
    assertEquals(1, ownerInfoList.size());
    assertEquals(SentryPrincipalType.USER, ownerInfoList.get(0).getOwnerType());
    assertEquals(userName2, ownerInfoList.get(0).getOwnerName());

  // Change owner from a user to role
    sentryStore.updateOwnerPrivilege(tSentryAuthorizable, roleName1, SentryPrincipalType.ROLE, null);
    assertEquals(1, sentryStore.getAllTSentryPrivilegesByRoleName(roleName1)
            .size());

    // At this point  roleName1 has owner privilege on db1.tb2
    //Add all privilege to roleName1 and make sure that owner privilege is not effected.
    TSentryPrivilege privilege_tbl2_all = new TSentryPrivilege(privilege_tbl2);
    privilege_tbl2_all.setAction(AccessConstants.ALL);
    sentryStore.alterSentryGrantPrivileges(SentryPrincipalType.ROLE, roleName1, Sets.newHashSet(privilege_tbl2_all), null);
    // Verify that there are two privileges.
    assertEquals(2, sentryStore.getAllTSentryPrivilegesByRoleName(roleName1)
            .size());


    tSentryAuthorizable.setTable("tbl3");
    TSentryPrivilege privilege_tbl3_all = new TSentryPrivilege(privilege_tbl2);
    privilege_tbl3_all.setAction(AccessConstants.ALL);
    privilege_tbl3_all.setTableName("tbl3");
    sentryStore.alterSentryGrantPrivileges(SentryPrincipalType.ROLE, roleName3, Sets.newHashSet(privilege_tbl3_all), null);
    assertEquals(1, sentryStore.getAllTSentryPrivilegesByRoleName(roleName3)
            .size());
    TSentryPrivilege privilege_tbl3_owner = new TSentryPrivilege(privilege_tbl3_all);
    privilege_tbl3_owner.setAction(AccessConstants.OWNER);
    sentryStore.alterSentryGrantPrivileges(SentryPrincipalType.ROLE, roleName3, Sets.newHashSet(privilege_tbl3_owner), null);

    assertEquals(2, sentryStore.getAllTSentryPrivilegesByRoleName(roleName3)
            .size());
  }

  @Test
  public void testListSentryOwnerPrivilegesByAuthorizable() throws Exception {
    String roleName1 = "list-privs-r1";
    String userName1 = "user1";
    sentryStore.createSentryRole(roleName1);
    sentryStore.createSentryUser(userName1);

    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());
    privilege_tbl1.setAction("OWNER");
    privilege_tbl1.setGrantOption(TSentryGrantOption.TRUE);

    TSentryAuthorizable tSentryAuthorizable = new TSentryAuthorizable();
    tSentryAuthorizable.setServer("server1");
    tSentryAuthorizable.setDb("db1");
    tSentryAuthorizable.setTable("tbl1");

    sentryStore.alterSentryGrantPrivileges(SentryPrincipalType.ROLE, roleName1, Sets.newHashSet(privilege_tbl1), null);

    sentryStore.updateOwnerPrivilege(tSentryAuthorizable, userName1, SentryPrincipalType.USER, null);
    assertEquals(1, sentryStore.getAllTSentryPrivilegesByUserName(userName1)
            .size());
  }

  @Test
  public void testRevokeOwnerPrivilege() throws Exception {

    String roleName1 = "list-privs-r1";
    String userName1 = "user1";
    sentryStore.createSentryRole(roleName1);
    sentryStore.createSentryUser(userName1);

    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());
    privilege_tbl1.setAction("OWNER");
    privilege_tbl1.setGrantOption(TSentryGrantOption.TRUE);

    TSentryAuthorizable tSentryAuthorizable = new TSentryAuthorizable();
    tSentryAuthorizable.setServer("server1");
    tSentryAuthorizable.setDb("db1");
    tSentryAuthorizable.setTable("tbl1");

    sentryStore.alterSentryGrantPrivileges(SentryPrincipalType.ROLE, roleName1, Sets.newHashSet(privilege_tbl1), null);

    sentryStore.revokeOwnerPrivileges(tSentryAuthorizable, null);
    assertEquals(0, sentryStore.getAllTSentryPrivilegesByUserName(userName1)
            .size());
  }


  @Test
  public void testgetPrivilegesForAuthorizables() throws Exception {

    String roleName1 = "list-privs-r1";
    String userName1 = "user1";
    String uri1 = "file:///var/folders/dt/9zm44z9s6bjfxbrm4v36lzdc0000gp/T/1401860678102-0/data/kv1.dat";

    sentryStore.createSentryRole(roleName1);
    sentryStore.createSentryUser(userName1);

    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());
    privilege_tbl1.setAction("SELECT");
    privilege_tbl1.setGrantOption(TSentryGrantOption.TRUE);

    TSentryAuthorizable tSentryAuthorizable = new TSentryAuthorizable();
    tSentryAuthorizable.setServer("server1");
    tSentryAuthorizable.setDb("db1");
    tSentryAuthorizable.setTable("tbl1");


    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());
    privilege_tbl2.setAction("SELECT");
    privilege_tbl2.setGrantOption(TSentryGrantOption.TRUE);

    TSentryAuthorizable tSentryAuthorizable2 = new TSentryAuthorizable();
    tSentryAuthorizable2.setServer("server1");
    tSentryAuthorizable2.setDb("db1");
    tSentryAuthorizable2.setTable("tbl2");

    TSentryPrivilege privilege_col1 = new TSentryPrivilege(privilege_tbl2);
    privilege_col1.setPrivilegeScope("TABLE");
    privilege_col1.setServerName("server1");
    privilege_col1.setDbName("db3");
    privilege_col1.setTableName("tbl3");
    privilege_col1.setCreateTime(System.currentTimeMillis());
    privilege_col1.setAction("SELECT");
    privilege_col1.setGrantOption(TSentryGrantOption.TRUE);
    privilege_col1.setColumnName("Column1");

    TSentryAuthorizable tSentryAuthorizable3 = new TSentryAuthorizable();
    tSentryAuthorizable3.setServer("server1");
    tSentryAuthorizable3.setDb("db3");
    tSentryAuthorizable3.setTable("tbl3");
    tSentryAuthorizable3.setColumn("Column1");

    TSentryPrivilege tSentryUriPrivilege = new TSentryPrivilege("URI", "server1", "ALL");
    tSentryUriPrivilege.setURI(uri1);

    TSentryAuthorizable tSentryUriAuthorizable = new TSentryAuthorizable();
    tSentryUriAuthorizable.setUri(uri1);
    tSentryUriAuthorizable.setServer("server1");


    sentryStore.alterSentryGrantPrivileges(SentryPrincipalType.ROLE, roleName1, Sets.newHashSet(privilege_tbl1,privilege_tbl2, privilege_col1, tSentryUriPrivilege), null);

    // Verify the privilege count
    List<MSentryPrivilege> privilege = sentryStore.getPrivilegesForAuthorizables(Lists.newArrayList(tSentryAuthorizable,tSentryAuthorizable2, tSentryUriAuthorizable, tSentryAuthorizable3));
    assertEquals(4, privilege.size());

   // Verify the behavior when the empty authorizable list provided.
   privilege = sentryStore.getPrivilegesForAuthorizables(Collections.EMPTY_LIST);
   assertNotNull(privilege);
   assertEquals(4, privilege.size());

    // Verify the behvaior when the authorizable list is null.
    privilege = sentryStore.getPrivilegesForAuthorizables(null);
    assertNotNull(privilege);
    assertEquals(4, privilege.size());

    // Verify the privilege granted to URI is returned
    privilege = sentryStore.getPrivilegesForAuthorizables(Lists.newArrayList(tSentryAuthorizable2));
    assertEquals(1, privilege.size());


    TSentryAuthorizable tSentrDbAuthorizable = new TSentryAuthorizable();
    tSentrDbAuthorizable.setServer("server1");
    tSentrDbAuthorizable.setDb("db1");

    // Verify that all the privileges granted to tables in database db1 are returned.
    privilege = sentryStore.getPrivilegesForAuthorizables(Lists.newArrayList(tSentrDbAuthorizable));
    assertEquals(2, privilege.size());


    // Verify that all the privileges granted to server are returned.
    privilege = sentryStore.getPrivilegesForAuthorizables(Lists.newArrayList(tSentryAuthorizable3));
    assertEquals(1, privilege.size());

    TSentryAuthorizable tSentrServerAuthorizable = new TSentryAuthorizable();
    tSentrServerAuthorizable.setServer("server1");

    // Verify that all the privileges granted to server are returned.
    privilege = sentryStore.getPrivilegesForAuthorizables(Lists.newArrayList(tSentrServerAuthorizable));
    assertEquals(4, privilege.size());

    // Grant user1 same privileges granted to role1 and make sure that there are no duplicates in the privileges.
    sentryStore.alterSentryGrantPrivileges(SentryPrincipalType.USER, userName1, Sets.newHashSet(privilege_tbl1,privilege_tbl2, tSentryUriPrivilege), null);

    // Verify that all the privileges granted to server are returned.
    privilege = sentryStore.getPrivilegesForAuthorizables(Lists.newArrayList(tSentrServerAuthorizable));
    assertEquals(4, privilege.size());
  }


  @Test
  public void testgetPrivilegesForURIs() throws Exception {

    String roleName1 = "list-privs-r1";
    String uriPrefix = "file:///var/folders/dt/9zm44z9s6bjfxbrm4v36lzdc0000gp/T/1401860678102-0/";
    String uri1 = "file:///var/folders/dt/9zm44z9s6bjfxbrm4v36lzdc0000gp/T/1401860678102-0/data/kv1.dat";
    String uri2 = "file:///var/folders/dt/9zm44z9s6bjfxbrm4v36lzdc0000gp/T/1401860678102-0/data/kv2.dat";


    sentryStore.createSentryRole(roleName1);

    TSentryPrivilege tSentryUriPrivilege1 = new TSentryPrivilege("URI", "server1", "ALL");
    tSentryUriPrivilege1.setURI(uri1);

    TSentryPrivilege tSentryUriPrivilege2 = new TSentryPrivilege("URI", "server1", "ALL");
    tSentryUriPrivilege2.setURI(uri2);

    TSentryAuthorizable tSentryUriAuthorizable = new TSentryAuthorizable();
    tSentryUriAuthorizable.setUri(uriPrefix);
    tSentryUriAuthorizable.setServer("server1");


    // Grant user1 same privileges granted to role1 and make sure that there are no duplicates in the privileges.
    sentryStore.alterSentryGrantPrivileges(SentryPrincipalType.ROLE, roleName1, Sets.newHashSet(tSentryUriPrivilege1, tSentryUriPrivilege2), null);

    // Verify that all the privileges granted to all the URI;s under given prefix are returned.
    List<MSentryPrivilege> privilege = sentryStore.getPrivilegesForAuthorizables(Lists.newArrayList(tSentryUriAuthorizable));
    assertEquals(2, privilege.size());
  }

  @Test
  public void testDropUserOnUpdateOwnerPrivilege() throws Exception {
    String userName1 = "user1", userName2 = "user2";
    sentryStore.createSentryUser(userName1);
    sentryStore.createSentryUser(userName2);


    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());
    privilege_tbl1.setAction("OWNER");

    TSentryAuthorizable tSentryAuthorizable = new TSentryAuthorizable();
    tSentryAuthorizable.setServer("server1");
    tSentryAuthorizable.setDb("db1");
    tSentryAuthorizable.setTable("tbl1");


    // Change owner from a one user to another user
    sentryStore.alterSentryGrantPrivileges(SentryPrincipalType.USER, userName1, Sets.newHashSet(privilege_tbl1), null);
    assertEquals(1, sentryStore.getAllTSentryPrivilegesByUserName(userName1)
            .size());


    sentryStore.updateOwnerPrivilege(tSentryAuthorizable, userName2, SentryPrincipalType.USER, null);
    assertEquals(1, sentryStore.getAllTSentryPrivilegesByUserName(userName2)
            .size());

    try {
      sentryStore.createSentryUser(userName1);
    } catch (Exception e) {
      fail("Exception should not be seen asthe user: " + userName1 + " should have been deleted.");
    }

  }
  /**
   * 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";
    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.alterSentryGrantPrivileges(SentryPrincipalType.ROLE, roleName1, Sets.newHashSet(privilege_tbl1_insert), null);
    sentryStore.alterSentryGrantPrivileges(SentryPrincipalType.ROLE, roleName1, Sets.newHashSet(privilege_tbl1_select), null);
    sentryStore.alterSentryGrantPrivileges(SentryPrincipalType.ROLE, roleName1, Sets.newHashSet(privilege_tbl1_alter), null);
    sentryStore.alterSentryGrantPrivileges(SentryPrincipalType.ROLE, roleName1, Sets.newHashSet(privilege_tbl1_drop), null);

    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 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.alterSentryGrantPrivileges(SentryPrincipalType.ROLE, roleName1, Sets.newHashSet(privilege_tbl1_c1), null);
    sentryStore.alterSentryGrantPrivileges(SentryPrincipalType.ROLE, roleName1, Sets.newHashSet(privilege_tbl1_c2), null);
    sentryStore.alterSentryGrantPrivileges(SentryPrincipalType.ROLE, roleName2, Sets.newHashSet(privilege_tbl1_c3), null);

    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";
    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.alterSentryGrantPrivileges(SentryPrincipalType.ROLE, roleName1, Sets.newHashSet(privilege_tbl1_insert), null);
    sentryStore.alterSentryGrantPrivileges(SentryPrincipalType.ROLE, roleName1, Sets.newHashSet(privilege_tbl1_all), null);

    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 users 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 userName1 = "user-1", userName2 = "user-2", userName3 = "user-3";
    String table1 = "tbl1", table2 = "tbl2";

    sentryStore.createSentryRole(roleName1);
    sentryStore.createSentryRole(roleName2);
    sentryStore.createSentryRole(roleName3);
    sentryStore.createSentryUser(userName1);
    sentryStore.createSentryUser(userName2);
    sentryStore.createSentryUser(userName3);

    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.alterSentryGrantPrivileges(SentryPrincipalType.ROLE, roleName1, Sets.newHashSet(privilege_tbl1_insert), null);
    sentryStore.alterSentryGrantPrivileges(SentryPrincipalType.ROLE, roleName2, Sets.newHashSet(privilege_tbl1_select), null);
    sentryStore.alterSentryGrantPrivileges(SentryPrincipalType.ROLE, roleName3, Sets.newHashSet(privilege_tbl1_all), null);
    sentryStore.alterSentryGrantPrivileges(SentryPrincipalType.USER, userName1, Sets.newHashSet(privilege_tbl1_insert), null);
    sentryStore.alterSentryGrantPrivileges(SentryPrincipalType.USER, userName2, Sets.newHashSet(privilege_tbl1_select), null);
    sentryStore.alterSentryGrantPrivileges(SentryPrincipalType.USER, userName3, Sets.newHashSet(privilege_tbl1_all), null);

    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()));
      }
    }
    for (String userName : Sets.newHashSet(userName1, userName2, userName3)) {
      Set<TSentryPrivilege> privilegeSet = sentryStore
              .getAllTSentryPrivilegesByUserName(userName);
      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 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.alterSentryGrantPrivileges(SentryPrincipalType.ROLE, roleName1, Sets.newHashSet(privilege_tbl1_insert), null);
    sentryStore.alterSentryGrantPrivileges(SentryPrincipalType.ROLE, roleName1, Sets.newHashSet(privilege_tbl1_select), null);
    sentryStore.alterSentryGrantPrivileges(SentryPrincipalType.ROLE, roleName1, Sets.newHashSet(privilege_tbl1_alter), null);
    sentryStore.alterSentryGrantPrivileges(SentryPrincipalType.ROLE, roleName1, Sets.newHashSet(privilege_tbl1_drop), null);

    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());

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

    sentryStore.alterSentryGrantPrivileges(SentryPrincipalType.ROLE, role1, Sets.newHashSet(privilege), null);
    assertEquals(Long.valueOf(1), sentryStore.getPrivilegeCountGauge().getValue());

    sentryStore.alterSentryGrantPrivileges(SentryPrincipalType.ROLE, role2, Sets.newHashSet(privilege), null);
    assertEquals(Long.valueOf(1), sentryStore.getPrivilegeCountGauge().getValue());

    privilege.setTableName("tb2");
    sentryStore.alterSentryGrantPrivileges(SentryPrincipalType.ROLE, role2, Sets.newHashSet(privilege), null);
    assertEquals(Long.valueOf(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(Long.valueOf(1), sentryStore.getGroupCountGauge().getValue());

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

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

  }

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

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

    Set<String> users = Sets.newHashSet("user1");

    sentryStore.alterSentryRoleAddUsers(role1, users);
    assertEquals(Long.valueOf(1), sentryStore.getUserCountGauge().getValue());

    sentryStore.alterSentryRoleAddUsers(role2, users);
    assertEquals(Long.valueOf(1), sentryStore.getUserCountGauge().getValue());

    users.add("user2");
    sentryStore.alterSentryRoleAddUsers(role2, users);
    assertEquals(Long.valueOf(2), sentryStore.getUserCountGauge().getValue());

  }

  @Test
  public void testRenameTableWithColumn() throws Exception {
    String roleName1 = "role1", roleName2 = "role2";
    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.alterSentryGrantPrivileges(SentryPrincipalType.ROLE, roleName1, Sets.newHashSet(privilege_tbl1_c1), null);
    sentryStore.alterSentryGrantPrivileges(SentryPrincipalType.ROLE, roleName1, Sets.newHashSet(privilege_tbl1_c2), null);
    sentryStore.alterSentryGrantPrivileges(SentryPrincipalType.ROLE, roleName2, Sets.newHashSet(privilege_tbl1_c3), null);

    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());
  }

  @Test
  public void testSentryTablePrivilegeSome() throws Exception {
    String roleName = "test-table-privilege-some";
    String grantor = "g1";
    String dbName = "db1";
    String table = "tb1";
    createRole(roleName);
    TSentryPrivilege tSentryPrivilege = new TSentryPrivilege("TABLE", "server1", "ALL");
    tSentryPrivilege.setDbName(dbName);
    tSentryPrivilege.setTableName(table);
    sentryStore.alterSentryGrantPrivileges(SentryPrincipalType.ROLE, roleName, Sets.newHashSet(tSentryPrivilege), null);

    TSentryAuthorizable tSentryAuthorizable = new TSentryAuthorizable();
    tSentryAuthorizable.setDb(dbName);
    tSentryAuthorizable.setTable(AccessConstants.SOME);
    tSentryAuthorizable.setServer("server1");

    Set<TSentryPrivilege> privileges =
        sentryStore.getTSentryPrivileges(SentryPrincipalType.ROLE, 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")),
            Sets.newHashSet(grantor), thriftRoleSet, tSentryAuthorizable);

    assertTrue(privs.size()==1);
    assertTrue(privs.contains("server=server1->db=" + dbName + "->table=" + table + "->action=all"));

  }


  @Test
  public void testSentryColumnPrivilegeSome() throws Exception {
    String roleName = "test-column-privilege-some";
    String grantor = "g1";
    String dbName = "db1";
    String table = "tb1";
    String column = "col1";
    createRole(roleName);
    TSentryPrivilege tSentryPrivilege = new TSentryPrivilege("TABLE", "server1", "ALL");
    tSentryPrivilege.setDbName(dbName);
    tSentryPrivilege.setTableName(table);
    tSentryPrivilege.setColumnName(column);
    sentryStore.alterSentryGrantPrivileges(SentryPrincipalType.ROLE, roleName, Sets.newHashSet(tSentryPrivilege), null);

    TSentryAuthorizable tSentryAuthorizable = new TSentryAuthorizable();
    tSentryAuthorizable.setDb(dbName);
    tSentryAuthorizable.setTable(table);
    tSentryAuthorizable.setColumn(AccessConstants.SOME);
    tSentryAuthorizable.setServer("server1");

    Set<TSentryPrivilege> privileges =
        sentryStore.getTSentryPrivileges(SentryPrincipalType.ROLE, 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")), Sets.newHashSet(grantor),
                thriftRoleSet, tSentryAuthorizable);

    assertTrue(privs.size() == 1);
    assertTrue(privs.contains("server=server1->db=" + dbName + "->table=" + table + "->column="
        + column + "->action=all"));

  }

  @Test
  public void testSentryVersionCheck() throws Exception {
    // don't verify version, the current version willll be set in MSentryVersion
    sentryStore.verifySentryStoreSchema(false);
    assertEquals(sentryStore.getSentryVersion(),
        SentryStoreSchemaInfo.getSentryVersion());

    // verify the version with the same value
    sentryStore.verifySentryStoreSchema(true);

    // verify the version with the different value
    sentryStore.setSentryVersion("test-version", "test-version");
    try {
      sentryStore.verifySentryStoreSchema(true);
      fail("SentryAccessDeniedException should be thrown.");
    } catch (SentryAccessDeniedException e) {
      // the excepted exception, recover the version
      sentryStore.verifySentryStoreSchema(false);
    }
  }

  @Test
  public void testRetrieveFullPermssionsImage() throws Exception {

    // Create roles
    String roleName1 = "privs-r1", roleName2 = "privs-r2";
    String groupName1 = "privs-g1";
    String grantor = "g1";
    sentryStore.createSentryRole(roleName1);
    sentryStore.createSentryRole(roleName2);

    // Grant Privileges to the roles
    TSentryPrivilege privilege1 = new TSentryPrivilege();
    privilege1.setPrivilegeScope("TABLE");
    privilege1.setServerName("server1");
    privilege1.setDbName("db1");
    privilege1.setTableName("tbl1");
    privilege1.setAction("SELECT");
    privilege1.setCreateTime(System.currentTimeMillis());
    sentryStore.alterSentryGrantPrivileges(SentryPrincipalType.ROLE, roleName1, Sets.newHashSet(privilege1), null);
    sentryStore.alterSentryGrantPrivileges(SentryPrincipalType.ROLE, roleName2, Sets.newHashSet(privilege1), null);

    TSentryPrivilege privilege2 = new TSentryPrivilege();
    privilege2.setPrivilegeScope("SERVER");
    privilege2.setServerName("server1");
    privilege1.setDbName("db2");
    privilege1.setAction("ALL");
    privilege2.setCreateTime(System.currentTimeMillis());
    sentryStore.alterSentryGrantPrivileges(SentryPrincipalType.ROLE, roleName2, Sets.newHashSet(privilege2), null);

    // Grant roles to the groups
    Set<TSentryGroup> groups = Sets.newHashSet();
    TSentryGroup group = new TSentryGroup();
    group.setGroupName(groupName1);
    groups.add(group);
    sentryStore.alterSentryRoleAddGroups(grantor, roleName1, groups);
    sentryStore.alterSentryRoleAddGroups(grantor, roleName2, groups);

    //Grant owner privilege to role
    TSentryPrivilege privilege3 = new TSentryPrivilege();
    privilege3.setPrivilegeScope("TABLE");
    privilege3.setServerName("server1");
    privilege3.setDbName("db3");
    privilege3.setTableName("tbl1");
    privilege3.setAction("OWNER");
    privilege3.setCreateTime(System.currentTimeMillis());
    sentryStore.alterSentryGrantPrivileges(SentryPrincipalType.ROLE, roleName1, Sets.newHashSet(privilege3), null);
    sentryStore.alterSentryGrantPrivileges(SentryPrincipalType.ROLE, roleName2, Sets.newHashSet(privilege3), null);

    PermissionsImage permImage = sentryStore.retrieveFullPermssionsImage();
    Map<String, Map<TPrivilegePrincipal, String>> privs = permImage.getPrivilegeImage();
    Map<String, List<String>> roles = permImage.getRoleImage();
    assertEquals(2, privs.get("db1.tbl1").size());
    assertEquals(2, roles.size());

    assertEquals(2, privs.get("db3.tbl1").size());
    assertEquals("ALL", privs.get("db3.tbl1").get(new TPrivilegePrincipal(TPrivilegePrincipalType.ROLE, roleName1)));
    assertEquals("ALL", privs.get("db3.tbl1").get(new TPrivilegePrincipal(TPrivilegePrincipalType.ROLE, roleName2)));

  }

  @Test
  public void testRetrieveFullPermssionsImageWithMultiplePrivielgesPerRolePerObject() throws Exception {

    // Create roles
    String roleName1 = "privs-r1";
    String groupName1 = "privs-g1";
    String grantor = "g1";
    sentryStore.createSentryRole(roleName1);

    // Grant roles to the groups
    Set<TSentryGroup> groups = Sets.newHashSet();
    TSentryGroup group = new TSentryGroup();
    group.setGroupName(groupName1);
    groups.add(group);
    sentryStore.alterSentryRoleAddGroups(grantor, roleName1, groups);

    // Grant multiple privileges to a role on one object
    TSentryPrivilege privilege1 = new TSentryPrivilege();
    privilege1.setPrivilegeScope("TABLE");
    privilege1.setServerName("server1");
    privilege1.setDbName("db1");
    privilege1.setTableName("tbl1");
    privilege1.setAction("SELECT");
    privilege1.setCreateTime(System.currentTimeMillis());
    TSentryPrivilege privilege2 = new TSentryPrivilege();
    privilege2.setPrivilegeScope("TABLE");
    privilege2.setServerName("server1");
    privilege2.setDbName("db1");
    privilege2.setTableName("tbl1");
    privilege2.setAction("INSERT");
    privilege2.setCreateTime(System.currentTimeMillis());
    TSentryPrivilege privilege3 = new TSentryPrivilege();
    privilege3.setPrivilegeScope("TABLE");
    privilege3.setServerName("server1");
    privilege3.setDbName("db1");
    privilege3.setTableName("tbl1");
    privilege3.setAction("REFRESH");
    privilege3.setCreateTime(System.currentTimeMillis());
    sentryStore.alterSentryGrantPrivileges(SentryPrincipalType.ROLE, roleName1, Sets.newHashSet(privilege1), null);
    sentryStore.alterSentryGrantPrivileges(SentryPrincipalType.ROLE, roleName1, Sets.newHashSet(privilege2), null);
    sentryStore.alterSentryGrantPrivileges(SentryPrincipalType.ROLE, roleName1, Sets.newHashSet(privilege3), null);

    PermissionsImage permImage = sentryStore.retrieveFullPermssionsImage();
    Map<String, Map<TPrivilegePrincipal, String>> privs = permImage.getPrivilegeImage();
    assertEquals(1, privs.get("db1.tbl1").size());
    assertEquals("REFRESH,INSERT,SELECT", privs.get("db1.tbl1").get(new TPrivilegePrincipal(TPrivilegePrincipalType.ROLE, roleName1)));

  }

  /**
   * Verifies complete snapshot of HMS Paths can be persisted and retrieved properly.
   */
  @Test
  public void testPersistFullPathsImage() throws Exception {
    Map<String, Collection<String>> authzPaths = new HashMap<>();
    String[] prefixes = {"/user/hive/warehouse"};
    // Makes sure that authorizable object could be associated
    // with different paths and can be properly persisted into database.
    authzPaths.put("db1.table1", Sets.newHashSet("/user/hive/warehouse/db2.db/table1.1",
        "/user/hive/warehouse/db2.db/table1.2"));
    // Makes sure that the same MPaths object could be associated
    // with multiple authorizable and can be properly persisted into database.
    authzPaths.put("db1.table2", Sets.newHashSet("/user/hive/warehouse/db2.db/table2.1",
        "/user/hive/warehouse/db2.db/table2.2"));
    authzPaths.put("db2.table2", Sets.newHashSet("/user/hive/warehouse/db2.db/table2.1",
        "/user/hive/warehouse/db2.db/table2.3"));
    long notificationID = 11;
    sentryStore.persistFullPathsImage(authzPaths, notificationID);
    PathsUpdate pathsUpdate = sentryStore.retrieveFullPathsImageUpdate(prefixes);
    long savedNotificationID = sentryStore.getLastProcessedNotificationID();
    assertEquals(1, pathsUpdate.getImgNum());
    TPathsDump pathDump = pathsUpdate.toThrift().getPathsDump();
    Map<Integer, TPathEntry> nodeMap = pathDump.getNodeMap();

    assertEquals(10, nodeMap.size());
    //First element is "/"
    int rootId = pathDump.getRootId();
    TPathEntry root = nodeMap.get(rootId);
    assertEquals("/", root.getPathElement());

    Map<String, Collection<String>>pathImage = new HashMap<>();
    buildPathsImageMap(nodeMap, root, "", pathImage, true);

    assertEquals(3, pathImage.size());
    for (Map.Entry<String, Collection<String>> entry : pathImage.entrySet()) {
      assertEquals(2, entry.getValue().size());
    }
    assertEquals(2, pathImage.get("db2.table2").size());
    assertTrue(CollectionUtils.isEqualCollection(Lists.newArrayList("/user/hive/warehouse/db2.db/table1.1",
        "/user/hive/warehouse/db2.db/table1.2"),
        pathImage.get("db1.table1")));
    assertTrue(CollectionUtils.isEqualCollection(Lists.newArrayList("/user/hive/warehouse/db2.db/table2.1",
        "/user/hive/warehouse/db2.db/table2.2"),
        pathImage.get("db1.table2")));
    assertTrue(CollectionUtils.isEqualCollection(Lists.newArrayList("/user/hive/warehouse/db2.db/table2.1",
        "/user/hive/warehouse/db2.db/table2.3"),
        pathImage.get("db2.table2")));
    assertEquals(6, sentryStore.getPathCount());
    assertEquals(notificationID, savedNotificationID);
  }

  @Test
  public void testAddAuthzPathsMapping() throws Exception {
    Set<MPath> paths;
    // Persist an empty image so that we can add paths to it.
    sentryStore.persistFullPathsImage(new HashMap<String, Collection<String>>(), 0);

    // Check the latest persisted ID matches to both the path updates
    long latestID = sentryStore.getCurrentAuthzPathsSnapshotID();


    // Persist the path
    sentryStore.addAuthzPathsMapping("db1.tb1", Arrays.asList("/hive/db1/tb1"), null);
    paths = sentryStore.getMAuthzPaths(latestID, "db1.tb1");
    // Verify that mapping is been added
    assertEquals(paths.size(), 1);
    assertTrue(paths.stream().anyMatch(x -> x.getPath().equalsIgnoreCase("/hive/db1/tb1")));

    // Add new path to an existing mapping
    sentryStore.addAuthzPathsMapping("db1.tb1", Arrays.asList("/hive/db1/tb1/par1"), null);
    paths = sentryStore.getMAuthzPaths(latestID, "db1.tb1");
    // Verify that mapping is been updated with the new path
    assertEquals(paths.size(), 2);
    assertTrue(paths.stream().anyMatch(x -> x.getPath().equalsIgnoreCase("/hive/db1/tb1/par1")));

    // Add multiples path to an existing mapping
    sentryStore.addAuthzPathsMapping("db1.tb1", Arrays.asList("/hive/db1/tb1/par2","/hive/db1/tb1/par3"), null);
    paths = sentryStore.getMAuthzPaths(latestID, "db1.tb1");
    // Verify that mapping is been updated with the new path
    assertEquals(paths.size(), 4);
    assertTrue(paths.stream().anyMatch(x -> x.getPath().equalsIgnoreCase("/hive/db1/tb1/par2")));
    assertTrue(paths.stream().anyMatch(x -> x.getPath().equalsIgnoreCase("/hive/db1/tb1/par3")));

    //Add null paths to an existing mapping and verify that there are no exceptions
    try {
      sentryStore.addAuthzPathsMapping("db1.tb1", null, null);
    } catch (Exception e) {
      fail("Exception occurred while adding mapping with null paths");
    }

    //Add new mapping with null paths and verify that there are no exceptions
    try {
      sentryStore.addAuthzPathsMapping("db1.tb5", null, null);
    } catch (Exception e) {
      fail("Exception occurred while adding mapping with null paths");
    }

    //Add empty paths collection to existing mapping verify that there are no exceptions
    try {
      sentryStore.addAuthzPathsMapping("db1.tb6", Collections.EMPTY_SET, null);
    } catch (Exception e) {
      fail("Exception occurred while adding mapping with empty path collection");
    }

    //Add new mapping with empty paths collection and verify that there are no exceptions
    try {
      sentryStore.addAuthzPathsMapping("db1.tb1", Collections.EMPTY_SET, null);
    } catch (Exception e) {
      fail("Exception occurred while adding mapping with empty path collection");
    }
  }

  @Test
  public void testAddPathsWithDuplicatedNotificationIdShouldBeAllowed() throws Exception {
    long notificationID = 1;

    // Persist an empty image so that we can add paths to it.
    sentryStore.persistFullPathsImage(new HashMap<String, Collection<String>>(), 0);

    // Create two path updates with the same sequence ID
    UniquePathsUpdate update1 = new UniquePathsUpdate("u1", notificationID, false);
    UniquePathsUpdate update2 = new UniquePathsUpdate("u2", notificationID, false);

    // Populate the path updates with different objects and paths
    update1.newPathChange("db1").addToAddPaths(Arrays.asList("/hive/db1"));
    update2.newPathChange("db2").addToAddPaths(Arrays.asList("/hive/db2"));

    // Persist both path updates. Persisting should be allowed, and paths should be
    // persisted even if they have the same sequence ID
    sentryStore.addAuthzPathsMapping("db1", Arrays.asList("/hive/db1"), update1);
    sentryStore.addAuthzPathsMapping("db2", Arrays.asList("/hive/db2"), update2);

    // Check the latest persisted ID matches to both the path updates
    long latestID = sentryStore.getLastProcessedNotificationID();
    assertEquals(notificationID, latestID);

    String []prefixes = {"/hive"};
    PathsUpdate pathsUpdate = sentryStore.retrieveFullPathsImageUpdate(prefixes);
    TPathsDump pathDump = pathsUpdate.toThrift().getPathsDump();
    Map<Integer, TPathEntry> nodeMap = pathDump.getNodeMap();
    assertEquals(4, nodeMap.size());
    int rootId = pathDump.getRootId();
    TPathEntry root = nodeMap.get(rootId);
    assertEquals("/", root.getPathElement());

    Map<String, Collection<String>>pathsImage = new HashMap<>();
    buildPathsImageMap(nodeMap, root, "", pathsImage, true);

    // Check that retrieving a full paths image returns both paths updates
    assertEquals(2, pathsImage.size());
    assertEquals(1, pathsImage.get("db1").size());
    assertTrue(pathsImage.get("db1").contains("/hive/db1"));
    assertEquals(1, pathsImage.get("db2").size());
    assertTrue(pathsImage.get("db2").contains("/hive/db2"));

    // Check that retrieving delta changes returns both patch updates
    List<MSentryPathChange> pathsChanges = sentryStore.getMSentryPathChanges();
    assertEquals(2, pathsChanges.size());
    assertEquals(1, pathsChanges.get(0).getChangeID()); // changeID = 1
    assertTrue(pathsChanges.get(0).getPathChange().contains("/hive/db1"));
    assertEquals(2, pathsChanges.get(1).getChangeID()); // changeID = 2
    assertTrue(pathsChanges.get(1).getPathChange().contains("/hive/db2"));

    // Check that the SHA1 hash calculated for unique notifications is correct
    assertEquals("u1", pathsChanges.get(0).getNotificationHash());
    assertEquals("u2", pathsChanges.get(1).getNotificationHash());
  }

  private void buildPathsImageMap(Map<Integer, TPathEntry> nodeMap, TPathEntry node, String path,
      Map<String, Collection<String>> pathsImage, boolean includeLeadingSlash) {
    path = path.isEmpty()?node.getPathElement(): (path + node.getPathElement() + "/");
    TPathEntry tempNode = node;
    for(int childVal:node.getChildren()) {
      node = nodeMap.get(childVal);
      buildPathsImageMap(nodeMap, node, path, pathsImage, includeLeadingSlash);
    }
    if(tempNode.getChildren().isEmpty() && node.getAuthzObjs() != null) {
      for (String authz : node.getAuthzObjs()) {
        if (!pathsImage.containsKey(authz)) {
          pathsImage.put(authz, new LinkedList<>());
        }
        if(includeLeadingSlash) {
          pathsImage.get(authz).add(path.replaceAll("(/+$)", ""));
        } else {
          pathsImage.get(authz).add(path.replaceAll("(^/+)|(/+$)", ""));
        }
      }
    }
  }

  @Test
  public void testPersistDuplicatedNotificationIdShouldBeAllowed() throws Exception {
    long notificationID = 1;

    // Persist the same ID twice should not cause any issues
    sentryStore.persistLastProcessedNotificationID(notificationID);
    sentryStore.persistLastProcessedNotificationID(notificationID);

    // Retrieving latest peristed ID should match with the previous persisted ID
    long latestID = sentryStore.getLastProcessedNotificationID();
    assertEquals(notificationID, latestID);
  }

  @Test
  public void testAddDeleteAuthzPathsMapping() throws Exception {
    long notificationID = 0;

    // Persist an empty image so that we can add paths to it.
    sentryStore.persistFullPathsImage(new HashMap<String, Collection<String>>(), notificationID);

    // Add "db1.table1" authzObj
    Long lastNotificationId = sentryStore.getLastProcessedNotificationID();
    UniquePathsUpdate addUpdate = new UniquePathsUpdate("u1", 1, false);
    addUpdate.newPathChange("db1.table").
          addToAddPaths(Arrays.asList("db1", "tbl1"));
    addUpdate.newPathChange("db1.table").
          addToAddPaths(Arrays.asList("db1", "tbl2"));

    sentryStore.addAuthzPathsMapping("db1.table",
          Sets.newHashSet("db1/tbl1", "db1/tbl2"), addUpdate);
    String[]prefixes = {"/"};
    PathsUpdate pathsUpdate = sentryStore.retrieveFullPathsImageUpdate(prefixes);
    TPathsDump pathsDump = pathsUpdate.toThrift().getPathsDump();
    Map<Integer, TPathEntry>nodeMap = pathsDump.getNodeMap();
    TPathEntry root = nodeMap.get(pathsDump.getRootId());
    Map<String, Collection<String>> pathImage = new HashMap<>();
    buildPathsImageMap(nodeMap, root, "", pathImage, false);

    assertEquals(4, nodeMap.size());//Tree size
    assertEquals("/", root.getPathElement());
    assertEquals(1, pathImage.size());
    assertEquals(2, pathImage.get("db1.table").size());
    assertEquals(2, sentryStore.getMPaths().size());

    // Query the persisted path change and ensure it equals to the original one
    long lastChangeID = sentryStore.getLastProcessedPathChangeID();
    MSentryPathChange addPathChange = sentryStore.getMSentryPathChangeByID(lastChangeID);
    assertEquals(addUpdate.JSONSerialize(), addPathChange.getPathChange());
    lastNotificationId = sentryStore.getLastProcessedNotificationID();
    assertEquals(1, lastNotificationId.longValue());

    // Delete path 'db1.db/tbl1' from "db1.table1" authzObj.
    UniquePathsUpdate delUpdate = new UniquePathsUpdate("u2",2, false);
    delUpdate.newPathChange("db1.table")
          .addToDelPaths(Arrays.asList("db1", "tbl1"));
    sentryStore.deleteAuthzPathsMapping("db1.table", Sets.newHashSet("db1/tbl1"), delUpdate);
    pathsUpdate = sentryStore.retrieveFullPathsImageUpdate(prefixes);
    pathsDump = pathsUpdate.toThrift().getPathsDump();
    nodeMap = pathsDump.getNodeMap();
    root = nodeMap.get(pathsDump.getRootId());
    pathImage = new HashMap<>();
    buildPathsImageMap(nodeMap, root, "", pathImage, false);

    assertEquals("/", root.getPathElement());
    assertEquals(3, nodeMap.size());//Tree size
    assertEquals(1, pathImage.size());
    assertEquals(1, pathImage.get("db1.table").size());
    assertEquals(1, sentryStore.getMPaths().size());

    // Query the persisted path change and ensure it equals to the original one
    lastChangeID = sentryStore.getLastProcessedPathChangeID();
    MSentryPathChange delPathChange = sentryStore.getMSentryPathChangeByID(lastChangeID);
    assertEquals(delUpdate.JSONSerialize(), delPathChange.getPathChange());
    lastNotificationId = sentryStore.getLastProcessedNotificationID();
    assertEquals(2, lastNotificationId.longValue());

    // Delete "db1.table" authzObj from the authzObj -> [Paths] mapping.
    UniquePathsUpdate delAllupdate = new UniquePathsUpdate("u3",3, false);
    delAllupdate.newPathChange("db1.table")
        .addToDelPaths(Lists.newArrayList(PathsUpdate.ALL_PATHS));
    sentryStore.deleteAllAuthzPathsMapping("db1.table", delAllupdate);
    pathsUpdate = sentryStore.retrieveFullPathsImageUpdate(prefixes);
    pathsDump = pathsUpdate.toThrift().getPathsDump();
    nodeMap = pathsDump.getNodeMap();
    root = nodeMap.get(pathsDump.getRootId());
    pathImage = new HashMap<>();
    buildPathsImageMap(nodeMap, root, "", pathImage, false);

    assertEquals("/", root.getPathElement());
    assertEquals(1, nodeMap.size());//Tree size
    assertEquals(0, pathImage.size());
    assertEquals(0, sentryStore.getMPaths().size());
    assertEquals(0, sentryStore.getCount(MPath.class).intValue());

    // Query the persisted path change and ensure it equals to the original one
    lastChangeID = sentryStore.getLastProcessedPathChangeID();
    MSentryPathChange delAllPathChange = sentryStore.getMSentryPathChangeByID(lastChangeID);
    assertEquals(delAllupdate.JSONSerialize(), delAllPathChange.getPathChange());

    lastNotificationId = sentryStore.getLastProcessedNotificationID();
    assertEquals(3, lastNotificationId.longValue());

  }

  @Test
  public void testDeleteAuthzPathsMapping() throws Exception {

    long notificationID = 0;

    // Persist an empty image so that we can add paths to it.
    sentryStore.persistFullPathsImage(new HashMap<String, Collection<String>>(), notificationID);

    // Add a mapping to two paths
    sentryStore.addAuthzPathsMapping("db1.table",
            Sets.newHashSet("db1/tbl1", "db1/tbl2"), null);

    // Verify the Path count
    assertEquals(2, sentryStore.getCount(MPath.class).intValue());

    // Add a mapping to three paths
    sentryStore.addAuthzPathsMapping("db2.table",
            Sets.newHashSet("db2/tbl1", "db2/tbl2", "db2/tbl3"), null);


    // Verify the Path count
    assertEquals(5, sentryStore.getCount(MPath.class).intValue());

    // deleting the mapping and verifying the MPath count
    sentryStore.deleteAllAuthzPathsMapping("db1.table", null);
   // Verify the Path count
    assertEquals(3, sentryStore.getCount(MPath.class).intValue());


    // deleting the mapping and verifying the MPath count
    sentryStore.deleteAllAuthzPathsMapping("db2.table", null);
    // Verify the Path count
    assertEquals(0, sentryStore.getCount(MPath.class).intValue());

    // Add a mapping to two paths
    sentryStore.addAuthzPathsMapping("db1.table",
            Sets.newHashSet("db1/tbl1", "db1/tbl2"), null);
    // deleting the mapping with paths as null and verifying that all the paths are deleted.
    sentryStore.deleteAuthzPathsMapping("db1.table", null, null);
    // Verify the Path count
    assertEquals(0, sentryStore.getCount(MPath.class).intValue());

    // Add a mapping to two paths
    sentryStore.addAuthzPathsMapping("db1.table",
            Sets.newHashSet("db1/tbl1", "db1/tbl2"), null);
    // deleting the mapping with paths as empty set and verifying that all the paths are deleted.
    sentryStore.deleteAuthzPathsMapping("db1.table", Collections.EMPTY_SET, null);
    // Verify the Path count
    assertEquals(0, sentryStore.getCount(MPath.class).intValue());


  }

  @Test
  public void testRenameUpdateAuthzPathsMapping() throws Exception {
    Map<String, Collection<String>> authzPaths = new HashMap<>();
    Long lastNotificationId = sentryStore.getLastProcessedNotificationID();
    authzPaths.put("db1.table1", Sets.newHashSet("user/hive/warehouse/db1.db/table1",
                                                "user/hive/warehouse/db1.db/table1/p1"));
    authzPaths.put("db1.table2", Sets.newHashSet("user/hive/warehouse/db1.db/table2"));
    sentryStore.persistFullPathsImage(authzPaths, lastNotificationId);
    String[]prefixes = {"/user/hive/warehouse"};
    PathsUpdate pathsUpdate = sentryStore.retrieveFullPathsImageUpdate(prefixes);
    TPathsDump pathsDump = pathsUpdate.toThrift().getPathsDump();
    Map<Integer, TPathEntry>nodeMap = pathsDump.getNodeMap();
    TPathEntry root = nodeMap.get(pathsDump.getRootId());
    Map<String, Collection<String>> pathsImage = new HashMap<>();
    buildPathsImageMap(nodeMap, root, "", pathsImage, false);

    assertEquals("/", root.getPathElement());
    assertEquals(8, nodeMap.size());//Tree size
    assertEquals(2, pathsImage.size());


    // Rename path of 'db1.table1' from 'db1.table1' to 'db1.newTable1'
    UniquePathsUpdate renameUpdate = new UniquePathsUpdate("u1",1, false);
    renameUpdate.newPathChange("db1.table1")
        .addToDelPaths(Arrays.asList("user", "hive", "warehouse", "db1.db", "table1"));
    renameUpdate.newPathChange("db1.newTable1")
        .addToAddPaths(Arrays.asList("user", "hive", "warehouse", "db1.db", "newTable1"));
    sentryStore.renameAuthzPathsMapping("db1.table1", "db1.newTable1",
    "user/hive/warehouse/db1.db/table1", "user/hive/warehouse/db1.db/newTable1", renameUpdate);
    pathsUpdate = sentryStore.retrieveFullPathsImageUpdate(prefixes);
    pathsDump = pathsUpdate.toThrift().getPathsDump();
    nodeMap = pathsDump.getNodeMap();
    root = nodeMap.get(pathsDump.getRootId());
    pathsImage = new HashMap<>();
    buildPathsImageMap(nodeMap, root, "", pathsImage, false);

    assertEquals("/", root.getPathElement());
    assertEquals(9, nodeMap.size());//Tree size
    assertEquals(2, pathsImage.size());
    assertEquals(3, sentryStore.getMPaths().size());
    assertTrue(pathsImage.containsKey("db1.newTable1"));
    assertTrue(CollectionUtils.isEqualCollection(Lists.newArrayList("user/hive/warehouse/db1.db/table1/p1",
            "user/hive/warehouse/db1.db/newTable1"),
            pathsImage.get("db1.newTable1")));

    // Query the persisted path change and ensure it equals to the original one
    long lastChangeID = sentryStore.getLastProcessedPathChangeID();
    MSentryPathChange renamePathChange = sentryStore.getMSentryPathChangeByID(lastChangeID);
    assertEquals(renameUpdate.JSONSerialize(), renamePathChange.getPathChange());
    lastNotificationId = sentryStore.getLastProcessedNotificationID();
    assertEquals(1, lastNotificationId.longValue());
    // Rename 'db1.table1' to "db1.table2" but did not change its location.
    renameUpdate = new UniquePathsUpdate("u2",2, false);
    renameUpdate.newPathChange("db1.newTable1")
        .addToDelPaths(Arrays.asList("user", "hive", "warehouse", "db1.db", "newTable1"));
    renameUpdate.newPathChange("db1.newTable2")
        .addToAddPaths(Arrays.asList("user", "hive", "warehouse", "db1.db", "newTable1"));
    sentryStore.renameAuthzObj("db1.newTable1", "db1.newTable2", renameUpdate);
    pathsUpdate = sentryStore.retrieveFullPathsImageUpdate(prefixes);
    pathsDump = pathsUpdate.toThrift().getPathsDump();
    nodeMap = pathsDump.getNodeMap();
    root = nodeMap.get(pathsDump.getRootId());
    pathsImage = new HashMap<>();
    buildPathsImageMap(nodeMap, root, "", pathsImage, false);

    assertEquals("/", root.getPathElement());
    assertEquals(9, nodeMap.size());//Tree size
    assertEquals(2, pathsImage.size());
    assertEquals(3, sentryStore.getMPaths().size());
    assertTrue(pathsImage.containsKey("db1.newTable2"));
    assertTrue(CollectionUtils.isEqualCollection(Lists.newArrayList("user/hive/warehouse/db1.db/table1/p1",
            "user/hive/warehouse/db1.db/newTable1"),
            pathsImage.get("db1.newTable2")));
    lastNotificationId = sentryStore.getLastProcessedNotificationID();
    assertEquals(2, lastNotificationId.longValue());

    // Query the persisted path change and ensure it equals to the original one
    lastChangeID = sentryStore.getLastProcessedPathChangeID();
    renamePathChange = sentryStore.getMSentryPathChangeByID(lastChangeID);
    assertEquals(renameUpdate.JSONSerialize(), renamePathChange.getPathChange());

    // Update path of 'db1.newTable2' from 'db1.newTable1' to 'db1.newTable2'
    UniquePathsUpdate update = new UniquePathsUpdate("u3",3, false);
    update.newPathChange("db1.newTable1")
        .addToDelPaths(Arrays.asList("user", "hive", "warehouse", "db1.db", "newTable1"));
    update.newPathChange("db1.newTable1")
        .addToAddPaths(Arrays.asList("user", "hive", "warehouse", "db1.db", "newTable2"));
    sentryStore.updateAuthzPathsMapping("db1.newTable2",
            "user/hive/warehouse/db1.db/newTable1",
            "user/hive/warehouse/db1.db/newTable2",
            update);
    pathsUpdate = sentryStore.retrieveFullPathsImageUpdate(prefixes);
    pathsDump = pathsUpdate.toThrift().getPathsDump();
    nodeMap = pathsDump.getNodeMap();
    root = nodeMap.get(pathsDump.getRootId());
    pathsImage = new HashMap<>();
    buildPathsImageMap(nodeMap, root, "", pathsImage, false);

    assertEquals("/", root.getPathElement());
    assertEquals(9, nodeMap.size());//Tree size
    assertEquals(2, pathsImage.size());
    assertEquals(3, sentryStore.getMPaths().size());
    assertTrue(pathsImage.containsKey("db1.newTable2"));
    assertTrue(CollectionUtils.isEqualCollection(Lists.newArrayList("user/hive/warehouse/db1.db/table1/p1",
            "user/hive/warehouse/db1.db/newTable2"),
            pathsImage.get("db1.newTable2")));

    // Query the persisted path change and ensure it equals to the original one
    lastChangeID = sentryStore.getLastProcessedPathChangeID();
    MSentryPathChange updatePathChange = sentryStore.getMSentryPathChangeByID(lastChangeID);
    assertEquals(update.JSONSerialize(), updatePathChange.getPathChange());
    lastNotificationId = sentryStore.getLastProcessedNotificationID();
    assertEquals(3, lastNotificationId.longValue());
  }

  @Test
  public void testPersistAndReplaceANewPathsImage() throws Exception {
    Map<String, Collection<String>> authzPaths = new HashMap<>();
    long notificationID = 1;

    // First image to persist (this will be replaced later)
    authzPaths.put("db1.table1", Sets.newHashSet("/user/hive/warehouse/db2.db/table1.1",
        "/user/hive/warehouse/db2.db/table1.2"));
    authzPaths.put("db1.table2", Sets.newHashSet("/user/hive/warehouse/db2.db/table2.1",
        "/user/hive/warehouse/db2.db/table2.2"));
    sentryStore.persistFullPathsImage(authzPaths, notificationID);
    String[]prefixes = {"/user/hive/warehouse"};
    PathsUpdate pathsUpdate = sentryStore.retrieveFullPathsImageUpdate(prefixes);
    TPathsDump pathsDump = pathsUpdate.toThrift().getPathsDump();
    Map<Integer, TPathEntry>nodeMap = pathsDump.getNodeMap();
    TPathEntry root = nodeMap.get(pathsDump.getRootId());
    Map<String, Collection<String>> pathImage = new HashMap<>();
    buildPathsImageMap(nodeMap, root, "", pathImage, true);

    assertEquals("/", root.getPathElement());
    assertEquals(9, nodeMap.size());//Tree size
    assertEquals(1, pathsUpdate.getImgNum());

    // Second image to persist (it should replace first image)
    authzPaths.clear();
    authzPaths.put("db3.table1", Sets.newHashSet("/another-warehouse/db2.db/table1.1",
        "/another-warehouse/db2.db/table1.2"));
    authzPaths.put("db3.table2", Sets.newHashSet("/another-warehouse/db2.db/table2.1",
        "/another-warehouse/db2.db/table2.2"));
    authzPaths.put("db4.table2", Sets.newHashSet("/another-warehouse/db2.db/table2.1",
        "/another-warehouse/db2.db/table2.3"));
    sentryStore.persistFullPathsImage(authzPaths, notificationID+1);

    prefixes = new String[]{"/another-warehouse"};
    pathsUpdate = sentryStore.retrieveFullPathsImageUpdate(prefixes);
    pathsDump = pathsUpdate.toThrift().getPathsDump();
    nodeMap = pathsDump.getNodeMap();
    root = nodeMap.get(pathsDump.getRootId());
    pathImage = new HashMap<>();
    buildPathsImageMap(nodeMap, root, "", pathImage, true);

    assertEquals("/", root.getPathElement());
    assertEquals(8, nodeMap.size());//Tree size
    assertEquals(2, pathsUpdate.getImgNum());
    assertEquals(3, pathImage.size());

    for (Map.Entry<String, Collection<String>> entry : pathImage.entrySet()) {
      assertEquals(2, entry.getValue().size());
    }

    assertEquals(2, pathImage.get("db4.table2").size());
    assertTrue(CollectionUtils.isEqualCollection(Lists.newArrayList("/another-warehouse/db2.db/table1.1",
            "/another-warehouse/db2.db/table1.2"),
            pathImage.get("db3.table1")));
    assertTrue(CollectionUtils.isEqualCollection(Lists.newArrayList("/another-warehouse/db2.db/table2.1",
            "/another-warehouse/db2.db/table2.2"),
            pathImage.get("db3.table2")));

    assertTrue(CollectionUtils.isEqualCollection(Lists.newArrayList("/another-warehouse/db2.db/table2.1",
            "/another-warehouse/db2.db/table2.3"),
            pathImage.get("db4.table2")));

    assertEquals(6, sentryStore.getMPaths().size());
  }

  @Test
  public void testAddDeleteAfterReplacingANewPathsImage() throws Exception {
    long notificationID = 1;

    // Add some paths first (these should be replaced)
    UniquePathsUpdate addUpdate = new UniquePathsUpdate("u1", notificationID, false);
    addUpdate.newPathChange("db1.table").addToAddPaths(Arrays.asList("db1", "tbl1"));
    addUpdate.newPathChange("db1.table").addToAddPaths(Arrays.asList("db1", "tbl2"));
    sentryStore.addAuthzPathsMapping("db1.table", Sets.newHashSet("db1/tbl1", "db1/tbl2"), addUpdate);

    // Persist a new image that contains a new image ID (it replaces previous paths)
    notificationID ++;
    Map<String, Collection<String>> authzPaths = new HashMap<>();
    authzPaths.put("db2.table3", Sets.newHashSet("/user/hive/warehouse/db2.db/table1.1",
        "/user/hive/warehouse/db2.db/table1.2"));
    sentryStore.persistFullPathsImage(authzPaths, notificationID);

    // Add new paths
    notificationID ++;
    UniquePathsUpdate newAddUpdate = new UniquePathsUpdate("u2", notificationID, false);
    newAddUpdate.newPathChange("db2.table").addToAddPaths(Arrays.asList("db2", "tbl1"));
    newAddUpdate.newPathChange("db2.table").addToAddPaths(Arrays.asList("db2", "tbl2"));
    sentryStore.addAuthzPathsMapping("db2.table", Sets.newHashSet("db2/tbl1", "db2/tbl2"), newAddUpdate);
    String[]prefixes = {"/"};
    PathsUpdate pathsUpdate = sentryStore.retrieveFullPathsImageUpdate(prefixes);
    TPathsDump pathsDump = pathsUpdate.toThrift().getPathsDump();
    Map<Integer, TPathEntry>nodeMap = pathsDump.getNodeMap();
    TPathEntry root = nodeMap.get(pathsDump.getRootId());
    Map<String, Collection<String>> pathImage = new HashMap<>();
    buildPathsImageMap(nodeMap, root, "", pathImage, false);

    assertEquals("/", root.getPathElement());
    assertEquals(10, nodeMap.size());//Tree size
    assertEquals(2, pathImage.size());
    assertEquals(2, pathImage.get("db2.table").size());
    assertEquals(4, sentryStore.getMPaths().size());

    // Delete one path
    notificationID ++;
    UniquePathsUpdate delUpdate = new UniquePathsUpdate("u3", notificationID, false);
    delUpdate.newPathChange("db2.table").addToDelPaths(Arrays.asList("db2", "tbl1"));
    sentryStore.deleteAuthzPathsMapping("db2.table", Sets.newHashSet("db2/tbl1"), delUpdate);
    pathsUpdate = sentryStore.retrieveFullPathsImageUpdate(prefixes);
    pathsDump = pathsUpdate.toThrift().getPathsDump();
    nodeMap = pathsDump.getNodeMap();
    root = nodeMap.get(pathsDump.getRootId());
    pathImage = new HashMap<>();
    buildPathsImageMap(nodeMap, root, "", pathImage, false);

    assertEquals("/", root.getPathElement());
    assertEquals(9, nodeMap.size());//Tree size
    assertEquals(2, pathImage.size());
    assertEquals(1, pathImage.get("db2.table").size());
    assertEquals(3, sentryStore.getMPaths().size());

    Long lastNotificationId = sentryStore.getLastProcessedNotificationID();
    assertEquals(notificationID, lastNotificationId.longValue());
  }


  @Test
  public void testRenameUpdateAfterReplacingANewPathsImage() throws Exception {
    long notificationID = 1;

    Map<String, Collection<String>> authzPaths = new HashMap<>();
    // First image to persist (this will be replaced later)
    authzPaths.put("db1.table1", Sets.newHashSet("/user/hive/warehouse/db2.db/table1.1",
        "/user/hive/warehouse/db2.db/table1.2"));
    authzPaths.put("db1.table2", Sets.newHashSet("/user/hive/warehouse/db2.db/table2.1",
        "/user/hive/warehouse/db2.db/table2.2"));
    sentryStore.persistFullPathsImage(authzPaths, notificationID);

    // Second image to persist (it should replace first image)
    notificationID ++;
    authzPaths.clear();
    authzPaths.put("db3.table1", Sets.newHashSet("/another-warehouse/db3.db/table1.1",
        "/another-warehouse/db3.db/table1.2"));
    authzPaths.put("db3.table2", Sets.newHashSet("/another-warehouse/db3.db/table2.1",
        "/another-warehouse/db3.db/table2.2"));
    sentryStore.persistFullPathsImage(authzPaths, notificationID);

    // Rename path of 'db1.table1' from 'db1.table1' to 'db1.newTable1'
    notificationID ++;
    UniquePathsUpdate renameUpdate = new UniquePathsUpdate("u1", notificationID, false);
    renameUpdate.newPathChange("db3.table1")
        .addToDelPaths(Arrays.asList("another-warehouse", "db3.db", "table1.1"));
    renameUpdate.newPathChange("db1.newTable1")
        .addToAddPaths(Arrays.asList("user", "hive", "warehouse", "db1.db", "newTable1"));
    sentryStore.renameAuthzPathsMapping("db3.table1", "db1.newTable1",
        "/another-warehouse/db3.db/table1.1", "user/hive/warehouse/db1.db/newTable1", renameUpdate);
    String[]prefixes = {"/"};
    PathsUpdate pathsUpdate = sentryStore.retrieveFullPathsImageUpdate(prefixes);
    TPathsDump pathsDump = pathsUpdate.toThrift().getPathsDump();
    Map<Integer, TPathEntry>nodeMap = pathsDump.getNodeMap();
    TPathEntry root = nodeMap.get(pathsDump.getRootId());
    Map<String, Collection<String>> pathsImage = new HashMap<>();
    buildPathsImageMap(nodeMap, root, "", pathsImage, true);

    assertEquals("/", root.getPathElement());
    assertEquals(11, nodeMap.size());//Tree size
    assertEquals(2, pathsImage.size());
    assertEquals(4, sentryStore.getMPaths().size());
    assertTrue(pathsImage.containsKey("db1.newTable1"));
    assertTrue(CollectionUtils.isEqualCollection(Lists.newArrayList("/another-warehouse/db3.db/table1.2",
            "/user/hive/warehouse/db1.db/newTable1"),
            pathsImage.get("db1.newTable1")));

    // Update path of 'db1.newTable2' from 'db1.newTable1' to 'db1.newTable2'
    notificationID++;
    UniquePathsUpdate update = new UniquePathsUpdate("u2", notificationID, false);
    update.newPathChange("db1.newTable1")
        .addToDelPaths(Arrays.asList("user", "hive", "warehouse", "db1.db", "newTable1"));
    update.newPathChange("db1.newTable1")
        .addToAddPaths(Arrays.asList("user", "hive", "warehouse", "db1.db", "newTable2"));
    sentryStore.updateAuthzPathsMapping("db1.newTable2",
        "user/hive/warehouse/db1.db/newTable1",
        "user/hive/warehouse/db1.db/newTable2",
        update);
    pathsUpdate = sentryStore.retrieveFullPathsImageUpdate(prefixes);
    pathsDump = pathsUpdate.toThrift().getPathsDump();
    nodeMap = pathsDump.getNodeMap();
    root = nodeMap.get(pathsDump.getRootId());
    pathsImage = new HashMap<>();
    buildPathsImageMap(nodeMap, root, "", pathsImage, false);

    assertEquals("/", root.getPathElement());
    assertEquals(12, nodeMap.size());//Tree size
    assertEquals(3, pathsImage.size());
    assertEquals(5, sentryStore.getMPaths().size());
    assertTrue(pathsImage.containsKey("db1.newTable2"));
    assertEquals(Lists.newArrayList("user/hive/warehouse/db1.db/newTable2"),
        pathsImage.get("db1.newTable2"));
  }

  @Test
  public void testQueryParamBuilder() {
    QueryParamBuilder paramBuilder;
    paramBuilder = newQueryParamBuilder();
    // Try single parameter
    paramBuilder.add("key", "val");
    assertEquals("(this.key == :key)", paramBuilder.toString());
    // Try adding second parameter plus add trimming and conversion
    // to lower case
    paramBuilder.add("key1", " Val1 ", true);
    assertEquals("(this.key == :key && this.key1 == :key1)",
            paramBuilder.toString());
    Map<String, Object> params = paramBuilder.getArguments();
    assertEquals("val", params.get("key"));
    assertEquals("Val1", params.get("key1"));

    paramBuilder = newQueryParamBuilder(QueryParamBuilder.Op.OR);
    paramBuilder.add("key", " Val ", true);
    paramBuilder.addNotNull("notNullField");
    paramBuilder.addNull("nullField");
    assertEquals("(this.key == :key || this.notNullField != \"__NULL__\" || this.nullField == \"__NULL__\")",
            paramBuilder.toString());
    params = paramBuilder.getArguments();
    assertEquals("Val", params.get("key"));

    paramBuilder = newQueryParamBuilder()
            .addNull("var1")
            .addNotNull("var2");
    assertEquals("(this.var1 == \"__NULL__\" && this.var2 != \"__NULL__\")",
            paramBuilder.toString());

    // Test newChild()
    paramBuilder = newQueryParamBuilder();
    paramBuilder
            .addString("e1")
            .addString("e2")
            .newChild()
            .add("v3", "e3")
            .add("v4", "e4")
            .newChild()
            .addString("e5")
            .addString("e6")
    ;
    assertEquals("(e1 && e2 && (this.v3 == :v3 || this.v4 == :v4 || (e5 && e6)))",
            paramBuilder.toString());


    paramBuilder = newQueryParamBuilder();
    paramBuilder
            .addString("e1")
            .addString("e2")
            .newChild()
            .add("v3", "e3")
            .add("v4", "e4")
            .newChild()
            .addString("e5")
            .addString("e6")
    ;

    params = paramBuilder.getArguments();
    assertEquals("e3", params.get("v3"));
    assertEquals("e4", params.get("v4"));

    // Test addSet
    paramBuilder = newQueryParamBuilder();
    Set<String>names = new HashSet<>();
    names.add("foo");
    names.add("bar");
    names.add("bob");

    paramBuilder.addSet("prefix == ", names, true);
    assertEquals("(prefix == :var0 && prefix == :var1 && prefix == :var2)",
            paramBuilder.toString());
    params = paramBuilder.getArguments();

    Set<String>result = new HashSet<>();
    result.add((String)params.get("var0"));
    result.add((String)params.get("var1"));
    result.add((String)params.get("var2"));
    assertTrue(result.containsAll(names));
    assertTrue(names.containsAll(result));
  }

  @Test
  public void testPrivilegesWithPermUpdate() throws Exception {
    String roleName = "test-privilege";
    String server = "server1";
    String db = "db1";
    String table = "tbl1";
    String authzObj = "db1.tbl1";
    createRole(roleName);

    TSentryPrivilege privilege = new TSentryPrivilege();
    privilege.setPrivilegeScope("Column");
    privilege.setServerName(server);
    privilege.setDbName(db);
    privilege.setTableName(table);
    privilege.setAction(AccessConstants.SELECT);
    privilege.setCreateTime(System.currentTimeMillis());

    // Generate the permission add update authzObj "db1.tbl1"
    PermissionsUpdate addUpdate = new PermissionsUpdate(0, false);
    addUpdate.addPrivilegeUpdate(authzObj).putToAddPrivileges(
        new TPrivilegePrincipal(TPrivilegePrincipalType.ROLE, roleName), privilege.getAction().toUpperCase());

    // Grant the privilege to role test-privilege and verify it has been persisted.
    Map<TSentryPrivilege, Updateable.Update> addPrivilegesUpdateMap = Maps.newHashMap();
    addPrivilegesUpdateMap.put(privilege, addUpdate);
    sentryStore.alterSentryRoleGrantPrivileges(roleName, Sets.newHashSet(privilege), addPrivilegesUpdateMap);
    MSentryRole role = sentryStore.getMSentryRoleByName(roleName);
    Set<MSentryPrivilege> privileges = role.getPrivileges();
    assertEquals(privileges.toString(), 1, privileges.size());

    // Query the persisted perm change and ensure it equals to the original one
    long lastChangeID = sentryStore.getLastProcessedPermChangeID();
    long initialID = lastChangeID;
    MSentryPermChange addPermChange = sentryStore.getMSentryPermChangeByID(lastChangeID);
    assertEquals(addUpdate.JSONSerialize(), addPermChange.getPermChange());

    // Generate the permission delete update authzObj "db1.tbl1"
    PermissionsUpdate delUpdate = new PermissionsUpdate(0, false);
    delUpdate.addPrivilegeUpdate(authzObj).putToDelPrivileges(
            new TPrivilegePrincipal(TPrivilegePrincipalType.ROLE, roleName),
            privilege.getAction().toUpperCase());

    // Revoke the same privilege and verify it has been removed.
    Map<TSentryPrivilege, Updateable.Update> delPrivilegesUpdateMap = Maps.newHashMap();
    delPrivilegesUpdateMap.put(privilege, delUpdate);
    sentryStore.alterSentryRoleRevokePrivileges(roleName,
        Sets.newHashSet(privilege), delPrivilegesUpdateMap);
    role = sentryStore.getMSentryRoleByName(roleName);
    privileges = role.getPrivileges();
    assertEquals(0, privileges.size());

    // Query the persisted perm change and ensure it equals to the original one
    lastChangeID = sentryStore.getLastProcessedPermChangeID();
    MSentryPermChange delPermChange = sentryStore.getMSentryPermChangeByID(lastChangeID);
    assertEquals(delUpdate.JSONSerialize(), delPermChange.getPermChange());

    // Verify getMSentryPermChanges will return all MSentryPermChanges up
    // to the given changeID.
    List<MSentryPermChange> mSentryPermChanges = sentryStore.getMSentryPermChanges(initialID);
    assertEquals(lastChangeID - initialID + 1, mSentryPermChanges.size());

    // Verify ifPermChangeExists will return true for persisted MSentryPermChange.
    assertEquals(true, sentryStore.permChangeExists(1));
  }

  @Test
  public void testAddDeleteGroupsWithPermUpdate() throws Exception {
    String roleName = "test-groups";
    String grantor = "g1";
    createRole(roleName);

    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);

    // Generate the permission add update for role "test-groups"
    PermissionsUpdate addUpdate = new PermissionsUpdate(0, false);
    TRoleChanges addrUpdate = addUpdate.addRoleUpdate(roleName);
    for (TSentryGroup g : groups) {
      addrUpdate.addToAddGroups(g.getGroupName());
    }

    // Assign the role "test-groups" to the groups and verify.
    sentryStore.alterSentryRoleAddGroups(grantor, roleName, groups, addUpdate);
    MSentryRole role = sentryStore.getMSentryRoleByName(roleName);
    assertEquals(2, role.getGroups().size());

    // Query the persisted perm change and ensure it equals to the original one
    long lastChangeID = sentryStore.getLastProcessedPermChangeID();
    MSentryPermChange addPermChange = sentryStore.getMSentryPermChangeByID(lastChangeID);
    assertEquals(addUpdate.JSONSerialize(), addPermChange.getPermChange());

    // Generate the permission add update for role "test-groups"
    PermissionsUpdate delUpdate = new PermissionsUpdate(0, false);
    TRoleChanges delrUpdate = delUpdate.addRoleUpdate(roleName);
    for (TSentryGroup g : groups) {
      delrUpdate.addToDelGroups(g.getGroupName());
    }

    // Revoke the role "test-groups" to the groups and verify.
    sentryStore.alterSentryRoleDeleteGroups(roleName, groups, delUpdate);
    role = sentryStore.getMSentryRoleByName(roleName);
    assertEquals(Collections.emptySet(), role.getGroups());

    // Query the persisted perm change and ensure it equals to the original one
    MSentryPermChange delPermChange = sentryStore.getMSentryPermChangeByID(lastChangeID + 1);
    assertEquals(delUpdate.JSONSerialize(), delPermChange.getPermChange());
  }

  @Test
  public void testCreateDropRoleWithPermUpdate() throws Exception {
    String roleName = "test-drop-role";
    createRole(roleName);

    // Generate the permission del update for dropping role "test-drop-role"
    PermissionsUpdate delUpdate = new PermissionsUpdate(0, false);
    delUpdate.addPrivilegeUpdate(PermissionsUpdate.ALL_AUTHZ_OBJ).putToDelPrivileges(
            new TPrivilegePrincipal(TPrivilegePrincipalType.ROLE, roleName),
            PermissionsUpdate.ALL_AUTHZ_OBJ);
    delUpdate.addRoleUpdate(roleName).addToDelGroups(PermissionsUpdate.ALL_GROUPS);

    // Drop the role and verify.
    sentryStore.dropSentryRole(roleName, delUpdate);
    checkRoleDoesNotExist(roleName);

    // Query the persisted perm change and ensure it equals to the original one
    long lastChangeID = sentryStore.getLastProcessedPermChangeID();
    MSentryPermChange delPermChange = sentryStore.getMSentryPermChangeByID(lastChangeID);
    assertEquals(delUpdate.JSONSerialize(), delPermChange.getPermChange());
  }

  @Test
  public void testDropObjWithPermUpdate() throws Exception {
    String roleName1 = "list-privs-r1", roleName2 = "list-privs-r2";
    sentryStore.createSentryRole(roleName1);
    sentryStore.createSentryRole(roleName2);

    String authzObj = "db1.tbl1";
    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());
    privilege_tbl1.setAction("SELECT");

    sentryStore.alterSentryGrantPrivileges(SentryPrincipalType.ROLE, roleName1, Sets.newHashSet(privilege_tbl1), null);

    // Generate the permission drop update for dropping privilege for "db1.tbl1"
    PermissionsUpdate dropUpdate = new PermissionsUpdate(0, false);
    dropUpdate.addPrivilegeUpdate(authzObj).putToDelPrivileges(new TPrivilegePrincipal(TPrivilegePrincipalType.ROLE,
            PermissionsUpdate.ALL_ROLES),
            PermissionsUpdate.ALL_ROLES);

    // Drop the privilege and verify.
    sentryStore.dropPrivilege(toTSentryAuthorizable(privilege_tbl1), dropUpdate);
    assertEquals(0, sentryStore.getAllTSentryPrivilegesByRoleName(roleName1).size());
    assertEquals(0, sentryStore.getAllTSentryPrivilegesByRoleName(roleName2).size());

    // Query the persisted perm change and ensure it equals to the original one
    long lastChangeID = sentryStore.getLastProcessedPermChangeID();
    MSentryPermChange dropPermChange = sentryStore.getMSentryPermChangeByID(lastChangeID);
    assertEquals(dropUpdate.JSONSerialize(), dropPermChange.getPermChange());
  }

  @Test
  public void testRenameObjWithPermUpdate() throws Exception {
    String roleName1 = "role1";
    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());
    privilege_tbl1.setAction(AccessConstants.ALL);

    sentryStore.alterSentryGrantPrivileges(SentryPrincipalType.ROLE, roleName1, Sets.newHashSet(privilege_tbl1), null);

    // Generate the permission rename update for renaming privilege for "db1.tbl1"
    String oldAuthz = "db1.tbl1";
    String newAuthz = "db1.tbl2";
    PermissionsUpdate renameUpdate = new PermissionsUpdate(0, false);
    TPrivilegeChanges privUpdate = renameUpdate.addPrivilegeUpdate(PermissionsUpdate.RENAME_PRIVS);
    privUpdate.putToAddPrivileges(new TPrivilegePrincipal(TPrivilegePrincipalType.AUTHZ_OBJ, newAuthz), newAuthz);
    privUpdate.putToDelPrivileges(new TPrivilegePrincipal(TPrivilegePrincipalType.AUTHZ_OBJ, oldAuthz), oldAuthz);

    // Rename the privilege and verify.
    TSentryAuthorizable oldTable = toTSentryAuthorizable(privilege_tbl1);
    TSentryAuthorizable newTable = toTSentryAuthorizable(privilege_tbl1);
    newTable.setTable(table2);
    sentryStore.renamePrivilege(oldTable, newTable, renameUpdate);

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

    // Query the persisted perm change and ensure it equals to the original one
    long lastChangeID = sentryStore.getLastProcessedPermChangeID();
    MSentryPermChange renamePermChange = sentryStore.getMSentryPermChangeByID(lastChangeID);
    assertEquals(renameUpdate.JSONSerialize(), renamePermChange.getPermChange());
  }

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

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

  @Test
  public void testPurgeDeltaChanges() throws Exception {
    String role = "purgeRole";
    String table = "purgeTable";

    assertEquals(0, sentryStore.getMSentryPermChanges().size());
    assertEquals(0, sentryStore.getMSentryPathChanges().size());

    sentryStore.createSentryRole(role);
    int privCleanCount = ServerConfig.SENTRY_DELTA_KEEP_COUNT_DEFAULT;
    int extraPrivs = 5;

    final int numPermChanges = extraPrivs + privCleanCount;
    for (int i = 0; i < numPermChanges; i++) {
      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());

      PermissionsUpdate update = new PermissionsUpdate(i + 1, false);
      sentryStore.alterSentryGrantPrivileges(SentryPrincipalType.ROLE, role, Sets.newHashSet(privilege), Lists.newArrayList(update));
    }
    assertEquals(numPermChanges, sentryStore.getMSentryPermChanges().size());

    sentryStore.purgeDeltaChangeTables();
    assertEquals(privCleanCount, sentryStore.getMSentryPermChanges().size());

    // TODO: verify MSentryPathChange being purged.
    // assertEquals(1, sentryStore.getMSentryPathChanges().size());
  }

  @Test
  public void testpurgeNotificationIdTable() throws Exception {

    int totalentires = 200;
    int remainingEntires = ServerConfig.SENTRY_HMS_NOTIFICATION_ID_KEEP_COUNT_DEFAULT;
    assertTrue(sentryStore.isHmsNotificationEmpty());
    for(int id = 1; id <= totalentires; id++) {
      sentryStore.persistLastProcessedNotificationID((long)id);
    }
    assertEquals(totalentires, sentryStore.getMSentryHmsNotificationCore().size());
    sentryStore.purgeNotificationIdTable();

    // Make sure that sentry store still hold entries based on SENTRY_HMS_NOTIFICATION_ID_KEEP_COUNT_DEFAULT
    assertEquals(remainingEntires, sentryStore.getMSentryHmsNotificationCore().size());

    sentryStore.purgeNotificationIdTable();
    // Make sure that sentry store still hold entries based on SENTRY_HMS_NOTIFICATION_ID_KEEP_COUNT_DEFAULT
    assertEquals(remainingEntires, sentryStore.getMSentryHmsNotificationCore().size());

    sentryStore.clearAllTables();


    totalentires = 50;
    for(int id = 1; id <= totalentires; id++) {
      sentryStore.persistLastProcessedNotificationID((long)id);
    }
    assertEquals(totalentires, sentryStore.getMSentryHmsNotificationCore().size());
    sentryStore.purgeNotificationIdTable();

    // Make sure that sentry store still holds all the entries as total entries is less than
    // SENTRY_HMS_NOTIFICATION_ID_KEEP_COUNT_DEFAULT.
    assertEquals(totalentires, sentryStore.getMSentryHmsNotificationCore().size());
  }


  /**
   * This test verifies that in the case of concurrently updating delta change tables, no gap
   * between change ID was made. All the change IDs must be consecutive ({@see SENTRY-1643}).
   *
   * @throws Exception
   */
  @Test(timeout = 60000)
  public void testConcurrentUpdateChanges() throws Exception {
    final int numThreads = 20;
    final int numChangesPerThread = 100;
    final TransactionManager tm = sentryStore.getTransactionManager();
    final AtomicLong seqNumGenerator = new AtomicLong(0);
    final CyclicBarrier barrier = new CyclicBarrier(numThreads);

    ExecutorService executor = Executors.newFixedThreadPool(numThreads);
    for (int i = 0; i < numThreads; i++) {
      executor.submit(new Runnable() {
        @Override
        public void run() {
          try {
            barrier.await();
          } catch (Exception e) {
            LOGGER.error("Barrier failed to await", e);
            return;
          }
          for (int j = 0; j < numChangesPerThread; j++) {
            List<TransactionBlock<Object>> tbs = new ArrayList<>();
            PermissionsUpdate update =
                new PermissionsUpdate(seqNumGenerator.getAndIncrement(), false);
            tbs.add(new DeltaTransactionBlock(update));
            try {
              tm.executeTransactionBlocksWithRetry(tbs);
            } catch (Exception e) {
              LOGGER.error("Failed to execute permission update transaction", e);
              fail(String.format("Transaction failed: %s", e.getMessage()));
            }
          }
        }
      });
    }
    executor.shutdown();
    executor.awaitTermination(60, TimeUnit.SECONDS);

    List<MSentryPermChange> changes = sentryStore.getMSentryPermChanges();
    int actualSize = changes.size();
    if (actualSize != (numThreads * numChangesPerThread)) {
      LOGGER.warn("Detected {} dropped changes", ((numChangesPerThread * numThreads) - actualSize));
    }
    TreeSet<Long> changeIDs = new TreeSet<>();
    for (MSentryPermChange change : changes) {
      changeIDs.add(change.getChangeID());
    }
    assertEquals("duplicated change ID", actualSize, changeIDs.size());

    long prevId = changeIDs.first() - 1;
    for (Long changeId : changeIDs) {
      assertTrue(String.format("Found non-consecutive number: prev=%d cur=%d", prevId, changeId),
          changeId - prevId == 1);
      prevId = changeId;
    }
  }

  @Test
  public void testDuplicateNotification() throws Exception {
    Map<String, Collection<String>> authzPaths = new HashMap<>();
    Long lastNotificationId = sentryStore.getLastProcessedNotificationID();

    lastNotificationId ++;
    authzPaths.put("db1.table1", Sets.newHashSet("user/hive/warehouse/db1.db/table1",
      "user/hive/warehouse/db1.db/table1/p1"));
    authzPaths.put("db1.table2", Sets.newHashSet("user/hive/warehouse/db1.db/table2"));
    sentryStore.persistFullPathsImage(authzPaths, lastNotificationId);
    String[]prefixes = {"/user/hive/warehouse"};
    PathsUpdate pathsUpdate = sentryStore.retrieveFullPathsImageUpdate(prefixes);
    TPathsDump pathsDump = pathsUpdate.toThrift().getPathsDump();
    Map<Integer, TPathEntry>nodeMap = pathsDump.getNodeMap();
    TPathEntry root = nodeMap.get(pathsDump.getRootId());
    Map<String, Collection<String>> pathsImage = new HashMap<>();
    buildPathsImageMap(nodeMap, root, "", pathsImage, false);

    assertEquals("/", root.getPathElement());
    assertEquals(8, nodeMap.size());//Tree size
    assertEquals(2, pathsImage.size());

    if (lastNotificationId == null) {
      lastNotificationId = SentryConstants.EMPTY_NOTIFICATION_ID;
    }

    // Rename path of 'db1.table1' from 'db1.table1' to 'db1.newTable1'
    lastNotificationId ++;
    UniquePathsUpdate renameUpdate = new UniquePathsUpdate("u1", lastNotificationId, false);
    renameUpdate.newPathChange("db1.table1")
      .addToDelPaths(Arrays.asList("user", "hive", "warehouse", "db1.db", "table1"));
    renameUpdate.newPathChange("db1.newTable1")
      .addToAddPaths(Arrays.asList("user", "hive", "warehouse", "db1.db", "newTable1"));
    sentryStore.renameAuthzPathsMapping("db1.table1", "db1.newTable1",
      "user/hive/warehouse/db1.db/table1", "user/hive/warehouse/db1.db/newTable1", renameUpdate);
    pathsUpdate = sentryStore.retrieveFullPathsImageUpdate(prefixes);
    pathsDump = pathsUpdate.toThrift().getPathsDump();
    nodeMap = pathsDump.getNodeMap();
    root = nodeMap.get(pathsDump.getRootId());
    pathsImage = new HashMap<>();
    buildPathsImageMap(nodeMap, root, "", pathsImage, false);

    assertEquals("/", root.getPathElement());
    assertEquals(9, nodeMap.size());//Tree size
    assertEquals(2, pathsImage.size());
    assertEquals(3, sentryStore.getMPaths().size());
    assertTrue(pathsImage.containsKey("db1.newTable1"));
    assertTrue(CollectionUtils.isEqualCollection(Lists.newArrayList("user/hive/warehouse/db1.db/table1/p1",
            "user/hive/warehouse/db1.db/newTable1"),
            pathsImage.get("db1.newTable1")));

    // Query the persisted path change and ensure it equals to the original one
    long lastChangeID = sentryStore.getLastProcessedPathChangeID();
    MSentryPathChange renamePathChange = sentryStore.getMSentryPathChangeByID(lastChangeID);
    assertEquals(renameUpdate.JSONSerialize(), renamePathChange.getPathChange());
    Long savedLastNotificationId = sentryStore.getLastProcessedNotificationID();
    assertEquals(lastNotificationId.longValue(), savedLastNotificationId.longValue());


    // Process the notificaiton second time
    try {
      sentryStore.renameAuthzPathsMapping("db1.table1", "db1.newTable1",
        "user/hive/warehouse/db1.db/table1", "user/hive/warehouse/db1.db/newTable1", renameUpdate);
    } catch (Exception e) {
      if (!(e.getCause() instanceof JDODataStoreException)) {
        fail("Unexpected failure occured while processing duplicate notification");
      }
    }
  }

  @Test
  public void testIsAuthzPathsMappingEmpty() throws Exception {
    // Add "db1.table1" authzObj
    UniquePathsUpdate addUpdate = new UniquePathsUpdate("u1",1, false);
    addUpdate.newPathChange("db1.table").
      addToAddPaths(Arrays.asList("db1", "tbl1"));
    addUpdate.newPathChange("db1.table").
      addToAddPaths(Arrays.asList("db1", "tbl2"));

    // Persist an empty image so that we can add paths to it.
    sentryStore.persistFullPathsImage(new HashMap<String, Collection<String>>(), 0);

    assertEquals(sentryStore.isAuthzPathsMappingEmpty(), true);
    sentryStore.addAuthzPathsMapping("db1.table",
      Sets.newHashSet("db1/tbl1", "db1/tbl2"), addUpdate);
    String[]prefixes = {"/"};
    PathsUpdate pathsUpdate = sentryStore.retrieveFullPathsImageUpdate(prefixes);
    TPathsDump pathsDump = pathsUpdate.toThrift().getPathsDump();
    Map<Integer, TPathEntry>nodeMap = pathsDump.getNodeMap();
    TPathEntry root = nodeMap.get(pathsDump.getRootId());
    Map<String, Collection<String>> pathImage = new HashMap<>();
    buildPathsImageMap(nodeMap, root, "", pathImage, false);

    assertEquals("/", root.getPathElement());
    assertEquals(4, nodeMap.size());//Tree size
    assertEquals(1, pathImage.size());
    assertEquals(2, pathImage.get("db1.table").size());
    assertEquals(2, sentryStore.getMPaths().size());
    assertEquals(sentryStore.isAuthzPathsMappingEmpty(), false);
    sentryStore.clearAllTables();
    assertEquals(sentryStore.isAuthzPathsMappingEmpty(), true);
  }

  @Test
  public void testAddDeleteAuthzPathsMappingNoDeltaSavedWithoutHDFSSync() throws Exception {

    // disable HDFS
    conf.set(ServiceConstants.ServerConfig.PROCESSOR_FACTORIES, "");
    conf.set(ServiceConstants.ServerConfig.SENTRY_POLICY_STORE_PLUGINS, "");
    SentryStore localSentryStore = new SentryStore(conf);

    // Persist an empty image so that we can add paths to it.
    localSentryStore.persistFullPathsImage(new HashMap<String, Collection<String>>(), 0);

    // Add "db1.table1" authzObj
    Long lastNotificationId = sentryStore.getLastProcessedNotificationID();
    UniquePathsUpdate addUpdate = new UniquePathsUpdate("u1",1, false);
    addUpdate.newPathChange("db1.table").
        addToAddPaths(Arrays.asList("db1", "tbl1"));
    addUpdate.newPathChange("db1.table").
        addToAddPaths(Arrays.asList("db1", "tbl2"));

    localSentryStore.addAuthzPathsMapping("db1.table",
        Sets.newHashSet("db1/tbl1", "db1/tbl2"), addUpdate);
    String[]prefixes = {"/"};
    PathsUpdate pathsUpdate = localSentryStore.retrieveFullPathsImageUpdate(prefixes);
    TPathsDump pathsDump = pathsUpdate.toThrift().getPathsDump();
    Map<Integer, TPathEntry>nodeMap = pathsDump.getNodeMap();
    TPathEntry root = nodeMap.get(pathsDump.getRootId());
    Map<String, Collection<String>> pathImage = new HashMap<>();
    buildPathsImageMap(nodeMap, root, "", pathImage, false);

    assertEquals("/", root.getPathElement());
    assertEquals(4, nodeMap.size());//Tree size
    assertEquals(1, pathImage.size());
    assertEquals(2, pathImage.get("db1.table").size());
    assertEquals(2, localSentryStore.getMPaths().size());

    // Query the persisted path change and ensure it is not saved
    long lastChangeID = localSentryStore.getLastProcessedPathChangeID();
    assertEquals(0, lastChangeID);

    // Delete path 'db1.db/tbl1' from "db1.table1" authzObj.
    UniquePathsUpdate delUpdate = new UniquePathsUpdate("u2",2, false);
    delUpdate.newPathChange("db1.table")
        .addToDelPaths(Arrays.asList("db1", "tbl1"));
    localSentryStore.deleteAuthzPathsMapping("db1.table", Sets.newHashSet("db1/tbl1"), delUpdate);
    pathsUpdate = localSentryStore.retrieveFullPathsImageUpdate(prefixes);
    pathsDump = pathsUpdate.toThrift().getPathsDump();
    nodeMap = pathsDump.getNodeMap();
    root = nodeMap.get(pathsDump.getRootId());
    pathImage = new HashMap<>();
    buildPathsImageMap(nodeMap, root, "", pathImage, false);

    assertEquals("/", root.getPathElement());
    assertEquals(3, nodeMap.size());//Tree size
    assertEquals(1, pathImage.size());
    assertEquals(1, pathImage.get("db1.table").size());
    assertEquals(1, localSentryStore.getMPaths().size());

    // Query the persisted path change and ensure it is not saved
    lastChangeID = localSentryStore.getLastProcessedPathChangeID();
    assertEquals(0, lastChangeID);

    // Delete "db1.table" authzObj from the authzObj -> [Paths] mapping.
    UniquePathsUpdate delAllupdate = new UniquePathsUpdate("u3",3, false);
    delAllupdate.newPathChange("db1.table")
        .addToDelPaths(Lists.newArrayList(PathsUpdate.ALL_PATHS));
    localSentryStore.deleteAllAuthzPathsMapping("db1.table", delAllupdate);
    pathsUpdate = localSentryStore.retrieveFullPathsImageUpdate(prefixes);
    pathsDump = pathsUpdate.toThrift().getPathsDump();
    nodeMap = pathsDump.getNodeMap();
    root = nodeMap.get(pathsDump.getRootId());
    pathImage = new HashMap<>();
    buildPathsImageMap(nodeMap, root, "", pathImage, false);

    assertEquals("/", root.getPathElement());
    assertEquals(1, nodeMap.size());//Tree size
    assertEquals(0, pathImage.size());
    assertEquals(0, localSentryStore.getMPaths().size());

    // Query the persisted path change and ensure it is not saved
    lastChangeID = localSentryStore.getLastProcessedPathChangeID();
    assertEquals(0, lastChangeID);

    lastNotificationId = localSentryStore.getLastProcessedNotificationID();
    assertEquals(0, lastNotificationId.longValue());

    // enable HDFS for other tests
    conf.set(ServiceConstants.ServerConfig.PROCESSOR_FACTORIES, "org.apache.sentry.hdfs.SentryHDFSServiceProcessorFactory");
    conf.set(ServiceConstants.ServerConfig.SENTRY_POLICY_STORE_PLUGINS, "org.apache.sentry.hdfs.SentryPlugin");
  }

  /**
   * Test retrieveFullPathsImageUpdate() when no image is present.
   * @throws Exception
   */
  @Test
  public void testRetrieveEmptyPathImage() throws Exception {
    String[] prefixes = {};

    PathsUpdate pathsUpdate = sentryStore.retrieveFullPathsImageUpdate(prefixes);
    TPathsUpdate tPathsUpdate = pathsUpdate.toThrift();
    TPathsDump pathDump = tPathsUpdate.getPathsDump();
    Map<Integer, TPathEntry> nodeMap = pathDump.getNodeMap();
    assertEquals(1, nodeMap.size());
    System.out.printf(nodeMap.toString());
  }

  /**
   * Test retrieveFullPathsImageUpdate() when a single path is present.
   * @throws Exception
   */
  @Test
  public void testRetrievePathImageWithSingleEntry() throws Exception {
    String prefix = "user/hive/warehouse";
    String[] prefixes = {"/" + prefix};
    Map<String, Collection<String>> authzPaths = new HashMap<>();
    // Makes sure that authorizable object could be associated
    // with different paths and can be properly persisted into database.
    String tablePath = prefix + "/db2.db/table1.1";
    authzPaths.put("db1.table1", Sets.newHashSet(tablePath));
    long notificationID = 1;
    sentryStore.persistFullPathsImage(authzPaths, notificationID);

    PathsUpdate pathsUpdate = sentryStore.retrieveFullPathsImageUpdate(prefixes);
    assertEquals(notificationID, pathsUpdate.getImgNum());
    TPathsUpdate tPathsUpdate = pathsUpdate.toThrift();
    TPathsDump pathDump = tPathsUpdate.getPathsDump();
    Map<Integer, TPathEntry> nodeMap = pathDump.getNodeMap();
    System.out.printf(nodeMap.toString());
    assertEquals(6, nodeMap.size());
    int rootId = pathDump.getRootId();
    TPathEntry root = nodeMap.get(rootId);
    assertEquals("/", root.getPathElement());
    List<Integer> children;
    TPathEntry child = root;

    // Walk tree down and verify elements
    for (String path: tablePath.split("/")) {
      children = child.getChildren();
      assertEquals(1, children.size());
      child = nodeMap.get(children.get(0));
      assertEquals(path, child.getPathElement());
    }
  }

  /**
   * Test paths with multiple leading slashes
   * @throws Exception
   */
  @Test
  public void testRetrievePathImageWithMultipleLeadingSlashes() throws Exception {
    //Test with no leading slashes
    String prefix = "user/hive/warehouse";
    String []prefixes = {"/" + prefix};
    Map<String, Collection<String>> authzPaths = new HashMap<>();
    // Makes sure that authorizable object could be associated
    // with different paths and can be properly persisted into database.
    String tablePath = prefix + "/loc1/db2.db/table1.1";
    authzPaths.put("db1.table1", Sets.newHashSet(tablePath));
    long notificationID = 1;
    sentryStore.persistFullPathsImage(authzPaths, notificationID);
    PathsUpdate pathsUpdate = sentryStore.retrieveFullPathsImageUpdate(prefixes);
    assertEquals(notificationID, pathsUpdate.getImgNum());
    TPathsUpdate tPathsUpdate = pathsUpdate.toThrift();
    TPathsDump pathDump = tPathsUpdate.getPathsDump();
    Map<Integer, TPathEntry> nodeMap = pathDump.getNodeMap();
    assertEquals(7, nodeMap.size());

    //Test with single leading slashes
    prefix = "/user/hive/warehouse";
    prefixes = new String[]{prefix};
    authzPaths = new HashMap<>();
    // Makes sure that authorizable object could be associated
    // with different paths and can be properly persisted into database.
    tablePath = prefix + "/loc1/db2.db/table1.1";
    authzPaths.put("db1.table1", Sets.newHashSet(tablePath));
    notificationID = 2;
    sentryStore.persistFullPathsImage(authzPaths, notificationID);
    pathsUpdate = sentryStore.retrieveFullPathsImageUpdate(prefixes);
    assertEquals(notificationID, pathsUpdate.getImgNum());
    tPathsUpdate = pathsUpdate.toThrift();
    pathDump = tPathsUpdate.getPathsDump();
    nodeMap = pathDump.getNodeMap();
    assertEquals(7, nodeMap.size());

    //Test with multiple leading slash
    prefix = "///user/hive/warehouse";
    prefixes = new String[]{prefix};
    authzPaths = new HashMap<>();
    // Makes sure that authorizable object could be associated
    // with different paths and can be properly persisted into database.
    tablePath = prefix + "/loc1/db2.db/table1.1";
    authzPaths.put("db1.table1", Sets.newHashSet(tablePath));
    notificationID = 3;
    sentryStore.persistFullPathsImage(authzPaths, notificationID);
    pathsUpdate = sentryStore.retrieveFullPathsImageUpdate(prefixes);
    assertEquals(notificationID, pathsUpdate.getImgNum());
    tPathsUpdate = pathsUpdate.toThrift();
    pathDump = tPathsUpdate.getPathsDump();
    nodeMap = pathDump.getNodeMap();
    assertEquals(7, nodeMap.size());
  }

  /**
   * Create a user with the given name and verify that it is created
   *
   * @param userName
   * @throws Exception
   */
  private void createUser(String userName) throws Exception {
    checkUserDoesNotExist(userName);
    sentryStore.createSentryUser(userName);
    checkUserExists(userName);
  }

  /**
   * Fail test if user already exists
   * @param userName User name to checl
   * @throws Exception
   */
  private void checkUserDoesNotExist(String userName) throws Exception {
    try {
      sentryStore.getMSentryUserByName(userName);
      fail("User " + userName + "already exists");
    } catch (SentryNoSuchObjectException e) {
      // Ok
    }
  }

  /**
   * Fail test if user doesn't exist
   * @param userName User name to checl
   * @throws Exception
   */
  private void checkUserExists(String userName) throws Exception {
    assertEquals(userName.toLowerCase(),
        sentryStore.getMSentryUserByName(userName).getUserName());
  }

  @Test
  public void testGrantRevokePrivilegeForUser() throws Exception {
    String userName = "test-privilege";
    String server = "server1";
    String db = "db1";
    String table = "tbl1";
    createUser(userName);
    TSentryPrivilege privilege = new TSentryPrivilege();
    privilege.setPrivilegeScope("TABLE");
    privilege.setServerName(server);
    privilege.setDbName(db);
    privilege.setTableName(table);
    privilege.setAction(AccessConstants.ALL);
    privilege.setCreateTime(System.currentTimeMillis());
    sentryStore.alterSentryGrantPrivileges(SentryPrincipalType.USER, userName, Sets.newHashSet(privilege), null);
    MSentryUser user = sentryStore.getMSentryUserByName(userName);
    Set<MSentryPrivilege> privileges = user.getPrivileges();
    assertEquals(privileges.toString(), 1, privileges.size());
    privilege.setAction(AccessConstants.SELECT);
    sentryStore.alterSentryRevokePrivileges(SentryPrincipalType.USER, userName, Sets.newHashSet(privilege), null);
    // after having ALL and revoking SELECT, we should have (INSERT)
    user = sentryStore.getMSentryUserByName(userName);
    privileges = user.getPrivileges();
    assertEquals(privileges.toString(), 1, privileges.size());
    for (MSentryPrivilege mPrivilege : privileges) {
      assertEquals(server, mPrivilege.getServerName());
      assertEquals(db, mPrivilege.getDbName());
      assertEquals(table, mPrivilege.getTableName());
      assertNotSame(AccessConstants.SELECT, mPrivilege.getAction());
      assertFalse(mPrivilege.getGrantOption());
    }
    long numDBPrivs = sentryStore.countMSentryPrivileges();
    assertEquals("Privilege count", numDBPrivs,1);

    privilege.setAction(AccessConstants.INSERT);

    sentryStore.alterSentryRevokePrivileges(SentryPrincipalType.USER, userName, Sets.newHashSet(privilege), null);
    user = sentryStore.getMSentryUserByName(userName, false);
    assertNull(user);
  }

  /**
   * Test after granting DB ALL privilege, can still grant table ALL privilege
   * @throws Exception
   */
  @Test
  public void testGrantDuplicatePrivilegeHierchy() throws Exception {
    // grant database all privilege
    String roleName = "test-privilege";
    String server = "server1";
    String db = "db1";
    String table = "tbl1";
    createRole(roleName);
    TSentryPrivilege privilege = new TSentryPrivilege();
    privilege.setPrivilegeScope("DATABASE");
    privilege.setServerName(server);
    privilege.setDbName(db);
    privilege.setAction(AccessConstants.ALL);
    privilege.setCreateTime(System.currentTimeMillis());
    sentryStore.alterSentryGrantPrivileges(SentryPrincipalType.ROLE, roleName, Sets.newHashSet(privilege), null);
    MSentryRole role = sentryStore.getMSentryRoleByName(roleName);
    Set<MSentryPrivilege> privileges = role.getPrivileges();
    assertEquals(privileges.toString(), 1, privileges.size());

    // grant table all privlege
    privilege.setPrivilegeScope("TABLE");
    privilege.setServerName(server.toUpperCase());
    privilege.setDbName(db.toUpperCase());
    privilege.setTableName(table.toUpperCase());
    sentryStore.alterSentryGrantPrivileges(SentryPrincipalType.ROLE, roleName, Sets.newHashSet(privilege), null);

    // check if the table privilege is created
    role = sentryStore.getMSentryRoleByName(roleName);
    privileges = role.getPrivileges();
    assertEquals(privileges.toString(), 2, privileges.size());
  }

  @Test
  public void testListSentryPrivilegesForUsersAndGroups() throws Exception {
    String roleName = "role1";
    String groupName = "list-privs-g1";
    String userName = "u1";
    String grantor = "g1";
    sentryStore.createSentryRole(roleName);

    TSentryPrivilege privilege1 = new TSentryPrivilege();
    privilege1.setPrivilegeScope("TABLE");
    privilege1.setServerName("server1");
    privilege1.setDbName("db1");
    privilege1.setTableName("tbl1");
    privilege1.setAction("SELECT");
    privilege1.setCreateTime(System.currentTimeMillis());
    sentryStore.alterSentryGrantPrivileges(SentryPrincipalType.ROLE, roleName, Sets.newHashSet(privilege1), null);

    TSentryPrivilege privilege2 = new TSentryPrivilege();
    privilege2.setPrivilegeScope("SERVER");
    privilege2.setServerName("server1");
    privilege2.setCreateTime(System.currentTimeMillis());
    sentryStore.alterSentryGrantPrivileges(SentryPrincipalType.USER, userName, Sets.newHashSet(privilege2), null);

    Set<TSentryGroup> groups = Sets.newHashSet();
    TSentryGroup group = new TSentryGroup();
    group.setGroupName(groupName);
    groups.add(group);
    sentryStore.alterSentryRoleAddGroups(grantor, roleName, groups);

    // list-privs-g1 has privilege1
    // u1 has privilege2
    Set<TSentryPrivilege> expectedPrivs = new HashSet<>();
    expectedPrivs.add(privilege1);
    expectedPrivs.add(privilege2);

    assertEquals(expectedPrivs,
                 sentryStore.listSentryPrivilegesByUsersAndGroups(
                     Sets.newHashSet(groupName),
                     Sets.newHashSet(userName),
                     new TSentryActiveRoleSet(true, new HashSet<>()),
                     null));
  }

  @Test
  public void testListSentryPrivilegesForProviderForUser() throws Exception {
    String userName1 = "list-privs-user1";
    String userName2 = "list-privs-user2";
    sentryStore.createSentryUser(userName1);
    sentryStore.createSentryUser(userName2);

    TSentryPrivilege privilege1 = new TSentryPrivilege();
    privilege1.setPrivilegeScope("TABLE");
    privilege1.setServerName("server1");
    privilege1.setDbName("db1");
    privilege1.setTableName("tbl1");
    privilege1.setAction("SELECT");
    privilege1.setCreateTime(System.currentTimeMillis());
    sentryStore.alterSentryGrantPrivileges(SentryPrincipalType.USER, userName1, Sets.newHashSet(privilege1), null);

    privilege1.setAction("ALL");
    sentryStore.alterSentryGrantPrivileges(SentryPrincipalType.USER, userName2, Sets.newHashSet(privilege1), null);

    assertEquals(Sets.newHashSet("server=server1->db=db1->table=tbl1->action=select"),
        SentryStore.toTrimedLower(sentryStore.listAllSentryPrivilegesForProvider(
            new HashSet<String>(),
            Sets.newHashSet(userName1),
            new TSentryActiveRoleSet(true, new HashSet<String>()))));
  }

  @Test
  public void testListSentryPrivilegesByAuthorizableForUser() throws Exception {
    String userName1 = "list-privs-user1";
    sentryStore.createSentryUser(userName1);

    TSentryPrivilege privilege1 = new TSentryPrivilege();
    privilege1.setPrivilegeScope("TABLE");
    privilege1.setServerName("server1");
    privilege1.setDbName("db1");
    privilege1.setTableName("tbl1");
    privilege1.setAction("SELECT");
    privilege1.setCreateTime(System.currentTimeMillis());
    sentryStore.alterSentryGrantPrivileges(SentryPrincipalType.USER, userName1, Sets.newHashSet(privilege1), null);

    TSentryAuthorizable tSentryAuthorizable = new TSentryAuthorizable();
    tSentryAuthorizable.setServer("server1");
    tSentryAuthorizable.setDb("db1");
    tSentryAuthorizable.setTable("tbl1");

    TSentryPrivilegeMap map = sentryStore.listSentryPrivilegesByAuthorizableForUser(
        Sets.newHashSet(userName1),
        tSentryAuthorizable,false);
    assertEquals(1, map.getPrivilegeMapSize());
    assertEquals(Sets.newHashSet(userName1), map.getPrivilegeMap().keySet());
  }

  @Test
  public void testGrantRevokePrivilegeMultipleTimesForRole() throws Exception {
    String roleName = "test-privilege";
    String server = "server1";
    String db = "db1";
    String table = "tbl1";
    createRole(roleName);
    TSentryPrivilege privilege = new TSentryPrivilege();
    privilege.setPrivilegeScope("TABLE");
    privilege.setServerName(server);
    privilege.setDbName(db);
    privilege.setTableName(table);
    privilege.setAction(AccessConstants.ALL);
    privilege.setCreateTime(System.currentTimeMillis());
    sentryStore.alterSentryGrantPrivileges(SentryPrincipalType.ROLE, roleName, Sets.newHashSet(privilege), null);

    MSentryRole role = sentryStore.getMSentryRoleByName(roleName);
    Set<MSentryPrivilege> privileges = role.getPrivileges();
    assertEquals(privileges.toString(), 1, privileges.size());

    privilege.setAction(AccessConstants.SELECT);
    sentryStore.alterSentryRevokePrivileges(SentryPrincipalType.ROLE, roleName, Sets.newHashSet(privilege), null);
    // after having ALL and revoking SELECT, we should have (INSERT)
    role = sentryStore.getMSentryRoleByName(roleName);
    privileges = role.getPrivileges();
    assertEquals(privileges.toString(), 1, privileges.size());

    // second round
    privilege.setAction(AccessConstants.ALL);
    sentryStore.alterSentryGrantPrivileges(SentryPrincipalType.ROLE, roleName, Sets.newHashSet(privilege), null);
    List<MSentryPrivilege> totalPrivileges = sentryStore.getAllMSentryPrivileges();
    assertEquals(totalPrivileges.toString(),1, totalPrivileges.size());

    role = sentryStore.getMSentryRoleByName(roleName);
    privileges = role.getPrivileges();
    assertEquals(privileges.toString(), 1, privileges.size());

    privilege.setAction(AccessConstants.INSERT);
    sentryStore.alterSentryRevokePrivileges(SentryPrincipalType.ROLE, roleName, Sets.newHashSet(privilege), null);
    // after having ALL and revoking INSERT, we should have (SELECT)
    totalPrivileges = sentryStore.getAllMSentryPrivileges();
    assertEquals(totalPrivileges.toString(),1, totalPrivileges.size());
    role = sentryStore.getMSentryRoleByName(roleName);
    privileges = role.getPrivileges();
    assertEquals(privileges.toString(), 1, privileges.size());

    sentryStore.dropSentryRole(roleName);
  }

  @Test
  public void testGrantRevokePrivilegeMultipleTimesForUser() throws Exception {
    String userName = "test-privilege";
    String server = "server1";
    String db = "db1";
    String table = "tbl1";
    createUser(userName);
    TSentryPrivilege privilege = new TSentryPrivilege();
    privilege.setPrivilegeScope("TABLE");
    privilege.setServerName(server);
    privilege.setDbName(db);
    privilege.setTableName(table);
    privilege.setAction(AccessConstants.ALL);
    privilege.setCreateTime(System.currentTimeMillis());
    sentryStore.alterSentryGrantPrivileges(SentryPrincipalType.USER, userName, Sets.newHashSet(privilege), null);

    MSentryUser user = sentryStore.getMSentryUserByName(userName);
    Set<MSentryPrivilege> privileges = user.getPrivileges();
    assertEquals(privileges.toString(), 1, privileges.size());

    privilege.setAction(AccessConstants.SELECT);
    sentryStore.alterSentryRevokePrivileges(SentryPrincipalType.USER, userName, Sets.newHashSet(privilege), null);
    // after having ALL and revoking SELECT, we should have (INSERT)
    user = sentryStore.getMSentryUserByName(userName);
    privileges = user.getPrivileges();
    assertEquals(privileges.toString(), 1, privileges.size());

    // second round
    privilege.setAction(AccessConstants.ALL);
    sentryStore.alterSentryGrantPrivileges(SentryPrincipalType.USER, userName, Sets.newHashSet(privilege), null);
    List<MSentryPrivilege> totalPrivileges = sentryStore.getAllMSentryPrivileges();
    assertEquals(totalPrivileges.toString(),1, totalPrivileges.size());

    user = sentryStore.getMSentryUserByName(userName);
    privileges = user.getPrivileges();
    assertEquals(privileges.toString(), 1, privileges.size());

    privilege.setAction(AccessConstants.INSERT);
    sentryStore.alterSentryRevokePrivileges(SentryPrincipalType.USER, userName, Sets.newHashSet(privilege), null);
    // after having ALL and revoking INSERT, we should have (SELECT)
    totalPrivileges = sentryStore.getAllMSentryPrivileges();
    assertEquals(totalPrivileges.toString(),1, totalPrivileges.size());

    user = sentryStore.getMSentryUserByName(userName);
    privileges = user.getPrivileges();
    assertEquals(privileges.toString(), 1, privileges.size());

    privilege.setAction(AccessConstants.SELECT);
    sentryStore.alterSentryRevokePrivileges(SentryPrincipalType.USER, userName, Sets.newHashSet(privilege), null);
    // after having ALL and revoking INSERT and SELECT, we should have NO privileges
    // user should be removed automatically
    user = sentryStore.getMSentryUserByName(userName, false);
    assertNull(user);
  }

  @Test
  public void testGetAllRolesPrivileges() throws Exception {
    Map<String, Set<TSentryPrivilege>> allPrivileges;

    // The map must be empty (no null) if no roles exist on the system yet
    allPrivileges = sentryStore.getAllRolesPrivileges();
    assertNotNull(allPrivileges);
    assertTrue(allPrivileges.isEmpty());

    final String ROLE1 = "role1";
    final TSentryPrivilege ROLE1_PRIV1 =
      toTSentryPrivilege("ALL", "TABLE", "server1", "db1", "table1");
    final TSentryPrivilege ROLE1_PRIV2 =
      toTSentryPrivilege("SELECT", "TABLE", "server1", "db1", "table2");

    createRole(ROLE1);
    sentryStore.alterSentryGrantPrivileges(SentryPrincipalType.ROLE, ROLE1, Sets.newHashSet(ROLE1_PRIV1), null);
    sentryStore.alterSentryGrantPrivileges(SentryPrincipalType.ROLE, ROLE1, Sets.newHashSet(ROLE1_PRIV2), null);

    final String ROLE2 = "role2";
    final TSentryPrivilege ROLE2_PRIV1 =
      toTSentryPrivilege("INSERT", "DATABASE", "server1", "db1", "");
    final TSentryPrivilege ROLE2_PRIV2 =
      toTSentryPrivilege("ALL", "SERVER", "server1", "", "");

    createRole(ROLE2);
    sentryStore.alterSentryGrantPrivileges(SentryPrincipalType.ROLE, ROLE2, Sets.newHashSet(ROLE2_PRIV1), null);
    sentryStore.alterSentryGrantPrivileges(SentryPrincipalType.ROLE, ROLE2, Sets.newHashSet(ROLE2_PRIV2), null);

    final String ROLE3 = "role3";

    createRole(ROLE3);

    allPrivileges = sentryStore.getAllRolesPrivileges();

    // Must return 3 roles, 2 roles has 2 privileges each, 1 role has no privileges
    assertEquals(3, allPrivileges.size());
    assertEquals(2, allPrivileges.get(ROLE1).size());
    assertTrue(allPrivileges.get(ROLE1).contains(ROLE1_PRIV1));
    assertTrue(allPrivileges.get(ROLE1).contains(ROLE1_PRIV2));
    assertEquals(2, allPrivileges.get(ROLE2).size());
    assertTrue(allPrivileges.get(ROLE2).contains(ROLE2_PRIV1));
    assertTrue(allPrivileges.get(ROLE2).contains(ROLE2_PRIV2));
    assertEquals(0, allPrivileges.get(ROLE3).size());
  }

  @Test
  public void testGetAllUsersPrivileges() throws Exception {
    Map<String, Set<TSentryPrivilege>> allPrivileges;

    // The map must be empty (no null) if no roles exist on the system yet
    allPrivileges = sentryStore.getAllUsersPrivileges();
    assertNotNull(allPrivileges);
    assertTrue(allPrivileges.isEmpty());

    final String USER1 = "user1";
    final TSentryPrivilege USER1_PRIV1 =
      toTSentryPrivilege("ALL", "TABLE", "server1", "db1", "table1");
    final TSentryPrivilege USER1_PRIV2 =
      toTSentryPrivilege("SELECT", "TABLE", "server1", "db1", "table2");

    createUser(USER1);
    sentryStore.alterSentryGrantPrivileges(SentryPrincipalType.USER, USER1, Sets.newHashSet(USER1_PRIV1), null);
    sentryStore.alterSentryGrantPrivileges(SentryPrincipalType.USER,USER1, Sets.newHashSet(USER1_PRIV2), null);

    final String USER2 = "user2";
    final TSentryPrivilege USER2_PRIV1 =
      toTSentryPrivilege("INSERT", "DATABASE", "server1", "db1", "");
    final TSentryPrivilege USER2_PRIV2 =
      toTSentryPrivilege("ALL", "SERVER", "server1", "", "");

    createUser(USER2);
    sentryStore.alterSentryGrantPrivileges(SentryPrincipalType.USER,USER2, Sets.newHashSet(USER2_PRIV1), null);
    sentryStore.alterSentryGrantPrivileges(SentryPrincipalType.USER,USER2, Sets.newHashSet(USER2_PRIV2), null);

    final String USER3 = "user3";

    createUser(USER3);

    allPrivileges = sentryStore.getAllUsersPrivileges();

    // Must return 3 roles, 2 roles has 2 privileges each, 1 role has no privileges
    assertEquals(3, allPrivileges.size());
    assertEquals(2, allPrivileges.get(USER1).size());
    assertTrue(allPrivileges.get(USER1).contains(USER1_PRIV1));
    assertTrue(allPrivileges.get(USER1).contains(USER1_PRIV2));
    assertEquals(2, allPrivileges.get(USER2).size());
    assertTrue(allPrivileges.get(USER2).contains(USER2_PRIV1));
    assertTrue(allPrivileges.get(USER2).contains(USER2_PRIV2));
    assertEquals(0, allPrivileges.get(USER3).size());
  }

  @Test
  public void testPersistFullPathsImageWithHugeData() throws Exception {
    Map<String, Collection<String>> authzPaths = new HashMap<>();
    String[] prefixes = {"/user/hive/warehouse/"};
    int dbCount = 10, tableCount = 10, partitionCount = 10, prefixSize;
    prefixSize = StringUtils.countMatches(prefixes[0], "/");

    // Makes sure that authorizable object could be associated
    // with different paths and can be properly persisted into database.
    for(int db_index = 1 ; db_index <= dbCount; db_index++) {
      String db_name = "db" + db_index;
      for( int table_index = 1; table_index <= tableCount; table_index++) {
        Set<String> paths = Sets.newHashSet();
        String table_name = "tb" + table_index;
        String location = prefixes[0] + db_name + "/" + table_name;
        paths.add(location);
        for (int part_index = 1; part_index <= partitionCount; part_index++) {
          paths.add(location + "/" + part_index);
        }
        authzPaths.put(db_name+table_name, paths);
      }
    }
    long notificationID = 110000;
    LOGGER.debug("Before " + Instant.now());
    sentryStore.persistFullPathsImage(authzPaths, notificationID);
    LOGGER.debug("After " + Instant.now());
    PathsUpdate pathsUpdate = sentryStore.retrieveFullPathsImageUpdate(prefixes);
    assertTrue(pathsUpdate.hasFullImage());
    long savedNotificationID = sentryStore.getLastProcessedNotificationID();
    assertEquals(1, pathsUpdate.getImgNum());
    TPathsDump pathDump = pathsUpdate.toThrift().getPathsDump();
    assertNotNull(pathDump);
    Map<Integer, TPathEntry> nodeMap = pathDump.getNodeMap();
    int nodeCount = prefixSize + dbCount + (dbCount * tableCount) +
            (dbCount * tableCount * partitionCount);
    assertTrue(nodeMap.size()  == nodeCount);
    assertEquals(notificationID, savedNotificationID);
  }

  @Test
  public void testRevokeHiveAllPrivilegeFromImpalaUnset() throws Exception {

    String roleName1 = "impala-r1";
    String serverName = "server1";
    String dbName = "db1";
    String tableName = "tbl1";
    String hiveAll = "*";
    sentryStore.createSentryRole(roleName1);

    TSentryPrivilege hive_privilege_tbl1 = new TSentryPrivilege();
    hive_privilege_tbl1.setPrivilegeScope("TABLE");
    hive_privilege_tbl1.setServerName(serverName);
    hive_privilege_tbl1.setDbName(dbName);
    hive_privilege_tbl1.setTableName(tableName);
    hive_privilege_tbl1.setCreateTime(System.currentTimeMillis());
    hive_privilege_tbl1.setAction(hiveAll);
    hive_privilege_tbl1.setGrantOption(TSentryGrantOption.FALSE);

    TSentryPrivilege impala_privilege_tbl1_unset = new TSentryPrivilege();
    impala_privilege_tbl1_unset.setPrivilegeScope("TABLE");
    impala_privilege_tbl1_unset.setServerName(serverName);
    impala_privilege_tbl1_unset.setDbName(dbName);
    impala_privilege_tbl1_unset.setTableName(tableName);
    impala_privilege_tbl1_unset.setCreateTime(System.currentTimeMillis());
    impala_privilege_tbl1_unset.setAction("ALL");
    impala_privilege_tbl1_unset.setGrantOption(TSentryGrantOption.UNSET);

    TSentryAuthorizable tSentryAuthorizable = new TSentryAuthorizable();
    tSentryAuthorizable.setServer(serverName);
    tSentryAuthorizable.setDb(dbName);
    tSentryAuthorizable.setTable(tableName);

    // grant hive ALL privilege to role roleName1
    sentryStore.alterSentryGrantPrivileges(SentryPrincipalType.ROLE, roleName1, Sets.newHashSet(hive_privilege_tbl1), null);

    // revoke impala ALL privilege to role roleName1
    sentryStore.alterSentryRoleRevokePrivileges(roleName1, Sets.newHashSet(impala_privilege_tbl1_unset));
    Map<String, Set<TSentryPrivilege>> rolePrivilegesMap = sentryStore.getRoleNameTPrivilegesMap(dbName, tableName);
    assertNotNull(rolePrivilegesMap);
    Set<TSentryPrivilege> rolePrivileges = rolePrivilegesMap.get(roleName1);
    boolean privilegeRevoked = (rolePrivileges == null) || (rolePrivileges.size() == 0);
    assertTrue(privilegeRevoked);
  }

  @Test
  public void testRevokeHiveAllPrivilegeGrantOptionFromImpalaUnset() throws Exception {

    String roleName1 = "impala-r1";
    String serverName = "server1";
    String dbName = "db1";
    String tableName = "tbl1";
    String hiveAll = "*";
    sentryStore.createSentryRole(roleName1);

    TSentryPrivilege hive_privilege_tbl1 = new TSentryPrivilege();
    hive_privilege_tbl1.setPrivilegeScope("TABLE");
    hive_privilege_tbl1.setServerName(serverName);
    hive_privilege_tbl1.setDbName(dbName);
    hive_privilege_tbl1.setTableName(tableName);
    hive_privilege_tbl1.setCreateTime(System.currentTimeMillis());
    hive_privilege_tbl1.setAction(hiveAll);
    hive_privilege_tbl1.setGrantOption(TSentryGrantOption.FALSE);

    TSentryPrivilege impala_privilege_tbl1_unset = new TSentryPrivilege();
    impala_privilege_tbl1_unset.setPrivilegeScope("TABLE");
    impala_privilege_tbl1_unset.setServerName(serverName);
    impala_privilege_tbl1_unset.setDbName(dbName);
    impala_privilege_tbl1_unset.setTableName(tableName);
    impala_privilege_tbl1_unset.setCreateTime(System.currentTimeMillis());
    impala_privilege_tbl1_unset.setAction("ALL");
    impala_privilege_tbl1_unset.setGrantOption(TSentryGrantOption.UNSET);

    TSentryAuthorizable tSentryAuthorizable = new TSentryAuthorizable();
    tSentryAuthorizable.setServer(serverName);
    tSentryAuthorizable.setDb(dbName);
    tSentryAuthorizable.setTable(tableName);

    // grant hive ALL privilege to role roleName1
    hive_privilege_tbl1.setGrantOption(TSentryGrantOption.FALSE);
    sentryStore.alterSentryGrantPrivileges(SentryPrincipalType.ROLE, roleName1, Sets.newHashSet(hive_privilege_tbl1), null);
    hive_privilege_tbl1.setGrantOption(TSentryGrantOption.TRUE);
    sentryStore.alterSentryGrantPrivileges(SentryPrincipalType.ROLE, roleName1, Sets.newHashSet(hive_privilege_tbl1), null);

    // revoke impala ALL privilege to role roleName1
    sentryStore.alterSentryRoleRevokePrivileges(roleName1, Sets.newHashSet(impala_privilege_tbl1_unset));
    Map<String, Set<TSentryPrivilege>> rolePrivilegesMap = sentryStore.getRoleNameTPrivilegesMap(dbName, tableName);
    assertNotNull(rolePrivilegesMap);
    Set<TSentryPrivilege> rolePrivileges = rolePrivilegesMap.get(roleName1);
    boolean privilegeRevoked = (rolePrivileges == null) || (rolePrivileges.size() == 0);
    assertTrue(privilegeRevoked);
  }

  @Test
  public void testRevokeHiveAllPrivilegeFromImpala() throws Exception {

    String roleName1 = "impala-r1";
    String serverName = "server1";
    String dbName = "db1";
    String tableName = "tbl1";
    sentryStore.createSentryRole(roleName1);

    TSentryPrivilege hive_privilege_tbl1 = new TSentryPrivilege();
    hive_privilege_tbl1.setPrivilegeScope("TABLE");
    hive_privilege_tbl1.setServerName(serverName);
    hive_privilege_tbl1.setDbName(dbName);
    hive_privilege_tbl1.setTableName(tableName);
    hive_privilege_tbl1.setCreateTime(System.currentTimeMillis());
    hive_privilege_tbl1.setAction("*");
    hive_privilege_tbl1.setGrantOption(TSentryGrantOption.FALSE);

    TSentryPrivilege impala_privilege_tbl1 = new TSentryPrivilege();
    impala_privilege_tbl1.setPrivilegeScope("TABLE");
    impala_privilege_tbl1.setServerName(serverName);
    impala_privilege_tbl1.setDbName(dbName);
    impala_privilege_tbl1.setTableName(tableName);
    impala_privilege_tbl1.setCreateTime(System.currentTimeMillis());
    impala_privilege_tbl1.setAction("ALL");
    impala_privilege_tbl1.setGrantOption(TSentryGrantOption.FALSE);

    TSentryAuthorizable tSentryAuthorizable = new TSentryAuthorizable();
    tSentryAuthorizable.setServer(serverName);
    tSentryAuthorizable.setDb(dbName);
    tSentryAuthorizable.setTable(tableName);

    // grant hive ALL privilege to role roleName1
    sentryStore.alterSentryGrantPrivileges(SentryPrincipalType.ROLE, roleName1, Sets.newHashSet(hive_privilege_tbl1), null);

    // revoke impala ALL privilege to role roleName1
    sentryStore.alterSentryRoleRevokePrivileges(roleName1, Sets.newHashSet(impala_privilege_tbl1));
    Map<String, Set<TSentryPrivilege>> rolePrivilegesMap = sentryStore.getRoleNameTPrivilegesMap(dbName, tableName);
    assertNotNull(rolePrivilegesMap);
    Set<TSentryPrivilege> rolePrivileges = rolePrivilegesMap.get(roleName1);
    boolean privilegeRevoked = (rolePrivileges == null) || (rolePrivileges.size() == 0);
    assertTrue(privilegeRevoked);
  }

  @Test
  public void testRevokeImpalaAllPrivilegeFromHive() throws Exception {

    String roleName1 = "impala-r1";
    String serverName = "server1";
    String dbName = "db1";
    String tableName = "tbl1";
    sentryStore.createSentryRole(roleName1);

    TSentryPrivilege hive_privilege_tbl1 = new TSentryPrivilege();
    hive_privilege_tbl1.setPrivilegeScope("TABLE");
    hive_privilege_tbl1.setServerName(serverName);
    hive_privilege_tbl1.setDbName(dbName);
    hive_privilege_tbl1.setTableName(tableName);
    hive_privilege_tbl1.setCreateTime(System.currentTimeMillis());
    hive_privilege_tbl1.setAction("*");
    hive_privilege_tbl1.setGrantOption(TSentryGrantOption.FALSE);

    TSentryPrivilege impala_privilege_tbl1 = new TSentryPrivilege();
    impala_privilege_tbl1.setPrivilegeScope("TABLE");
    impala_privilege_tbl1.setServerName(serverName);
    impala_privilege_tbl1.setDbName(dbName);
    impala_privilege_tbl1.setTableName(tableName);
    impala_privilege_tbl1.setCreateTime(System.currentTimeMillis());
    impala_privilege_tbl1.setAction("ALL");
    impala_privilege_tbl1.setGrantOption(TSentryGrantOption.FALSE);

    TSentryAuthorizable tSentryAuthorizable = new TSentryAuthorizable();
    tSentryAuthorizable.setServer(serverName);
    tSentryAuthorizable.setDb(dbName);
    tSentryAuthorizable.setTable(tableName);

    // grant impala ALL privilege to role roleName1
    sentryStore.alterSentryGrantPrivileges(SentryPrincipalType.ROLE, roleName1, Sets.newHashSet(impala_privilege_tbl1), null);

    // revoke hive ALL privilege to role roleName1
    sentryStore.alterSentryRoleRevokePrivileges(roleName1, Sets.newHashSet(hive_privilege_tbl1));
    Map<String, Set<TSentryPrivilege>> rolePrivilegesMap = sentryStore.getRoleNameTPrivilegesMap(dbName, tableName);
    assertNotNull(rolePrivilegesMap);
    Set<TSentryPrivilege> rolePrivileges = rolePrivilegesMap.get(roleName1);
    boolean privilegeRevoked = (rolePrivileges == null) || (rolePrivileges.size() == 0);
    assertTrue(privilegeRevoked);
  }

  private TSentryPrivilege toTSentryPrivilege(String action, String scope, String server,
    String dbName, String tableName) {
    TSentryPrivilege privilege = new TSentryPrivilege();
    privilege.setPrivilegeScope(scope);
    privilege.setServerName(server);
    privilege.setDbName(dbName);
    privilege.setTableName(tableName);
    privilege.setAction(action);
    privilege.setCreateTime(System.currentTimeMillis());

    return privilege;
  }

  private TSentryPrivilege toTSentryPrivilege(String action, String scope, String server,
    String dbName, String tableName, TSentryGrantOption grantOption) {
    TSentryPrivilege privilege = toTSentryPrivilege(action, scope, server, dbName, tableName);
    privilege.setGrantOption(grantOption);
    return privilege;
  }
}
