@Test
public void testGrantRevokeCheckWithGrantOption() throws Exception {

  addGroupsToUser(GRANT_OPTION_USER, GRANT_OPTION_GROUP);
  addGroupsToUser(NO_GRANT_OPTION_USER, NO_GRANT_OPTION_GROUP);
  writePolicyFile();
  String roleName1 = "r1";
  String roleName2 = "r2";
  String grantor = "g1";
  sentryStore.createRole(SEARCH, roleName1, grantor);
  sentryStore.createRole(SEARCH, roleName2, grantor);
  /**
   * grant query privilege to role r1 with grant option
   */
  PrivilegeObject queryPrivilege1 = new Builder()
      .setComponent(SEARCH)
      .setAction(SearchConstants.QUERY)
      .setService(SERVICE)
      .setAuthorizables(Arrays.asList(new Collection(COLLECTION_NAME)))
      .withGrantOption(true)
      .build();
  sentryStore.alterRoleGrantPrivilege(SEARCH, roleName1, queryPrivilege1,
      ADMIN_USER);
  assertEquals(Sets.newHashSet(queryPrivilege1),
      sentryStore.getPrivilegesByRole(SEARCH, Sets.newHashSet(roleName1)));
  /**
   * grant query privilege to role r2 no grant option
   */
  PrivilegeObject queryPrivilege2 = new Builder()
      .setComponent(SEARCH)
      .setAction(SearchConstants.QUERY)
      .setService(SERVICE)
      .setAuthorizables(Arrays.asList(new Collection(COLLECTION_NAME)))
      .withGrantOption(false).build();
  sentryStore.alterRoleGrantPrivilege(SEARCH, roleName2, queryPrivilege2,
      ADMIN_USER);
  assertEquals(Sets.newHashSet(queryPrivilege2),
      sentryStore.getPrivilegesByRole(SEARCH, Sets.newHashSet(roleName2)));
  sentryStore.alterRoleAddGroups(SEARCH, roleName1,
      Sets.newHashSet(GRANT_OPTION_GROUP), grantor);
  sentryStore.alterRoleAddGroups(SEARCH, roleName2,
      Sets.newHashSet(NO_GRANT_OPTION_GROUP), grantor);
  String roleName3 = "r3";
  sentryStore.createRole(SEARCH, roleName3, grantor);
  /**
   * the user with grant option grant query privilege to rolr r3
   */
  try{
    sentryStore.alterRoleGrantPrivilege(SEARCH, roleName3, queryPrivilege1,
        GRANT_OPTION_USER);
  } catch (SentryGrantDeniedException e) {
    fail("SentryGrantDeniedException shouldn't have been thrown");
  }
  /**
   * the user with grant option revoke query privilege to rolr r3
   */
  try{
    sentryStore.alterRoleRevokePrivilege(SEARCH, roleName3, queryPrivilege1,
        GRANT_OPTION_USER);
  } catch (SentryGrantDeniedException e) {
    fail("SentryGrantDeniedException shouldn't have been thrown");
  }
  /**
   * the user with no grant option grant query privilege to rolr r3, it will
   * throw SentryGrantDeniedException
   */
  try {
    sentryStore.alterRoleGrantPrivilege(SEARCH, roleName3, queryPrivilege2,
        NO_GRANT_OPTION_USER);
    fail("SentryGrantDeniedException should have been thrown");
  } catch (SentryGrantDeniedException e) {
    //ignore the exception
  }
  /**
   * the user with no grant option revoke query privilege to rolr r3, it will
   * throw SentryGrantDeniedException
   */
  try {
    sentryStore.alterRoleGrantPrivilege(SEARCH, roleName3, queryPrivilege2,
        NO_GRANT_OPTION_USER);
    fail("SentryGrantDeniedException should have been thrown");
  } catch (SentryGrantDeniedException e) {
    //ignore the exception
  }
}