예제 #1
0
  /*
   * Group lookup should not happen for static users
   */
  @Test
  public void testGroupLookupForStaticUsers() throws Exception {
    conf.setClass(
        CommonConfigurationKeys.HADOOP_SECURITY_GROUP_MAPPING,
        FakeunPrivilegedGroupMapping.class,
        ShellBasedUnixGroupsMapping.class);
    conf.set(
        CommonConfigurationKeys.HADOOP_USER_GROUP_STATIC_OVERRIDES,
        "me=;user1=group1;user2=group1,group2");
    Groups groups = new Groups(conf);
    List<String> userGroups = groups.getGroups("me");
    assertTrue("non-empty groups for static user", userGroups.isEmpty());
    assertFalse("group lookup done for static user", FakeunPrivilegedGroupMapping.invoked);

    List<String> expected = new ArrayList<String>();
    expected.add("group1");

    FakeunPrivilegedGroupMapping.invoked = false;
    userGroups = groups.getGroups("user1");
    assertTrue("groups not correct", expected.equals(userGroups));
    assertFalse("group lookup done for unprivileged user", FakeunPrivilegedGroupMapping.invoked);

    expected.add("group2");
    FakeunPrivilegedGroupMapping.invoked = false;
    userGroups = groups.getGroups("user2");
    assertTrue("groups not correct", expected.equals(userGroups));
    assertFalse("group lookup done for unprivileged user", FakeunPrivilegedGroupMapping.invoked);
  }
예제 #2
0
  @Test
  public void testExceptionsFromImplNotCachedInNegativeCache() {
    conf.setClass(
        CommonConfigurationKeys.HADOOP_SECURITY_GROUP_MAPPING,
        ExceptionalGroupMapping.class,
        ShellBasedUnixGroupsMapping.class);
    conf.setLong(CommonConfigurationKeys.HADOOP_SECURITY_GROUPS_NEGATIVE_CACHE_SECS, 10000);
    Groups groups = new Groups(conf);
    groups.cacheGroupsAdd(Arrays.asList(myGroups));
    groups.refresh();

    assertEquals(0, ExceptionalGroupMapping.getRequestCount());

    // First call should hit the wire
    try {
      groups.getGroups("anything");
      fail("Should have thrown");
    } catch (IOException e) {
      // okay
    }
    assertEquals(1, ExceptionalGroupMapping.getRequestCount());

    // Second call should hit the wire (no negative caching)
    try {
      groups.getGroups("anything");
      fail("Should have thrown");
    } catch (IOException e) {
      // okay
    }
    assertEquals(2, ExceptionalGroupMapping.getRequestCount());
  }
예제 #3
0
 @Override // RefreshAuthorizationPolicyProtocol
 public void refreshUserToGroupsMappings() throws IOException {
   LOG.info(
       "Refreshing all user-to-groups mappings. Requested by user: "
           + UserGroupInformation.getCurrentUser().getShortUserName());
   Groups.getUserToGroupsMappingService().refresh();
 }
예제 #4
0
  @Override
  public RefreshUserToGroupsMappingsResponse refreshUserToGroupsMappings(
      RefreshUserToGroupsMappingsRequest request) throws YarnException, IOException {
    String argName = "refreshUserToGroupsMappings";
    UserGroupInformation user = checkAcls(argName);

    if (!isRMActive()) {
      RMAuditLogger.logFailure(
          user.getShortUserName(),
          argName,
          adminAcl.toString(),
          "AdminService",
          "ResourceManager is not active. Can not refresh user-groups.");
      throwStandbyException();
    }

    Groups.getUserToGroupsMappingService(
            getConfiguration(
                new Configuration(false), YarnConfiguration.CORE_SITE_CONFIGURATION_FILE))
        .refresh();

    RMAuditLogger.logSuccess(user.getShortUserName(), argName, "AdminService");

    return recordFactory.newRecordInstance(RefreshUserToGroupsMappingsResponse.class);
  }
  /**
   * Set the configuration values for UGI.
   *
   * @param conf the configuration to use
   */
  private static synchronized void initialize(Configuration conf) {
    String value = conf.get(HADOOP_SECURITY_AUTHENTICATION);
    if (value == null || "simple".equals(value)) {
      useKerberos = false;
      useConfiguredFileAuth = false;
    } else if ("kerberos".equals(value)) {
      useKerberos = true;
      useConfiguredFileAuth = false;
    } else if ("configfile".equals(value)) {
      useKerberos = false;
      useConfiguredFileAuth = true;
    } else {
      throw new IllegalArgumentException(
          "Invalid attribute value for " + HADOOP_SECURITY_AUTHENTICATION + " of " + value);
    }

    // The getUserToGroupsMappingService will change the conf value, record the UGI information
    // firstly
    if (configUGIInformation == null) {
      configUGIInformation = conf.getStrings("hadoop.client.ugi");
    }

    // If we haven't set up testing groups, use the configuration to find it
    if (!(groups instanceof TestingGroups)) {
      groups = Groups.getUserToGroupsMappingService(conf);
    }
    // Set the configuration for JAAS to be the Hadoop configuration.
    // This is done here rather than a static initializer to avoid a
    // circular dependence.
    javax.security.auth.login.Configuration existingConfig = null;
    try {
      existingConfig = javax.security.auth.login.Configuration.getConfiguration();
    } catch (SecurityException se) {
      // If no security configuration is on the classpath, then
      // we catch this exception, and we don't need to delegate
      // to anyone
    }

    if (existingConfig instanceof HadoopConfiguration) {
      LOG.info("JAAS Configuration already set up for Hadoop, not re-installing.");
    } else {
      javax.security.auth.login.Configuration.setConfiguration(
          new HadoopConfiguration(existingConfig));
    }

    // We're done initializing at this point. Important not to classload
    // KerberosName before this point, or else its static initializer
    // may call back into this same method!
    isInitialized = true;
    UserGroupInformation.conf = conf;

    // give the configuration on how to translate Kerberos names
    try {
      KerberosName.setConfiguration(conf);
    } catch (IOException ioe) {
      throw new RuntimeException(
          "Problem with Kerberos auth_to_local name " + "configuration", ioe);
    }
  }
예제 #6
0
  @Test
  public void testGroupsCaching() throws Exception {
    // Disable negative cache.
    conf.setLong(CommonConfigurationKeys.HADOOP_SECURITY_GROUPS_NEGATIVE_CACHE_SECS, 0);
    Groups groups = new Groups(conf);
    groups.cacheGroupsAdd(Arrays.asList(myGroups));
    groups.refresh();
    FakeGroupMapping.clearBlackList();
    FakeGroupMapping.addToBlackList("user1");

    // regular entry
    assertTrue(groups.getGroups("me").size() == 2);

    // this must be cached. blacklisting should have no effect.
    FakeGroupMapping.addToBlackList("me");
    assertTrue(groups.getGroups("me").size() == 2);

    // ask for a negative entry
    try {
      LOG.error("We are not supposed to get here." + groups.getGroups("user1").toString());
      fail();
    } catch (IOException ioe) {
      if (!ioe.getMessage().startsWith("No groups found")) {
        LOG.error("Got unexpected exception: " + ioe.getMessage());
        fail();
      }
    }

    // this shouldn't be cached. remove from the black list and retry.
    FakeGroupMapping.clearBlackList();
    assertTrue(groups.getGroups("user1").size() == 2);
  }
 @Override
 public Set<String> getGroups(String user) {
   try {
     return new HashSet<String>(groups.getGroups(user));
   } catch (IOException e) {
     LOGGER.warn("Unable to obtain groups for " + user, e);
   }
   return Collections.emptySet();
 }
예제 #8
0
  @Test
  public void testOnlyOneRequestWhenExpiredEntryExists() throws Exception {
    conf.setLong(CommonConfigurationKeys.HADOOP_SECURITY_GROUPS_CACHE_SECS, 1);
    FakeTimer timer = new FakeTimer();
    final Groups groups = new Groups(conf, timer);
    groups.cacheGroupsAdd(Arrays.asList(myGroups));
    groups.refresh();
    FakeGroupMapping.clearBlackList();
    FakeGroupMapping.setGetGroupsDelayMs(100);

    // We make an initial request to populate the cache
    groups.getGroups("me");
    int startingRequestCount = FakeGroupMapping.getRequestCount();

    // Then expire that entry
    timer.advance(400 * 1000);
    Thread.sleep(100);

    ArrayList<Thread> threads = new ArrayList<Thread>();
    for (int i = 0; i < 10; i++) {
      threads.add(
          new Thread() {
            public void run() {
              try {
                assertEquals(2, groups.getGroups("me").size());
              } catch (IOException e) {
                fail("Should not happen");
              }
            }
          });
    }

    // We start a bunch of threads who all see the cached value
    for (Thread t : threads) {
      t.start();
    }

    for (Thread t : threads) {
      t.join();
    }

    // Only one extra request is made
    assertEquals(startingRequestCount + 1, FakeGroupMapping.getRequestCount());
  }
예제 #9
0
  @Test
  public void testNegativeCacheEntriesExpire() throws Exception {
    conf.setLong(CommonConfigurationKeys.HADOOP_SECURITY_GROUPS_NEGATIVE_CACHE_SECS, 2);
    FakeTimer timer = new FakeTimer();
    // Ensure that stale entries are removed from negative cache every 2 seconds
    Groups groups = new Groups(conf, timer);
    groups.cacheGroupsAdd(Arrays.asList(myGroups));
    groups.refresh();
    // Add both these users to blacklist so that they
    // can be added to negative cache
    FakeGroupMapping.addToBlackList("user1");
    FakeGroupMapping.addToBlackList("user2");

    // Put user1 in negative cache.
    try {
      groups.getGroups("user1");
      fail("Did not throw IOException : Failed to obtain groups" + " from FakeGroupMapping.");
    } catch (IOException e) {
      GenericTestUtils.assertExceptionContains("No groups found for user", e);
    }
    // Check if user1 exists in negative cache
    assertTrue(groups.getNegativeCache().contains("user1"));

    // Advance fake timer
    timer.advance(1000);
    // Put user2 in negative cache
    try {
      groups.getGroups("user2");
      fail("Did not throw IOException : Failed to obtain groups" + " from FakeGroupMapping.");
    } catch (IOException e) {
      GenericTestUtils.assertExceptionContains("No groups found for user", e);
    }
    // Check if user2 exists in negative cache
    assertTrue(groups.getNegativeCache().contains("user2"));

    // Advance timer. Only user2 should be present in negative cache.
    timer.advance(1100);
    assertFalse(groups.getNegativeCache().contains("user1"));
    assertTrue(groups.getNegativeCache().contains("user2"));

    // Advance timer. Even user2 should not be present in negative cache.
    timer.advance(1000);
    assertFalse(groups.getNegativeCache().contains("user2"));
  }
예제 #10
0
  @Test
  public void testCacheEntriesExpire() throws Exception {
    conf.setLong(CommonConfigurationKeys.HADOOP_SECURITY_GROUPS_CACHE_SECS, 1);
    FakeTimer timer = new FakeTimer();
    final Groups groups = new Groups(conf, timer);
    groups.cacheGroupsAdd(Arrays.asList(myGroups));
    groups.refresh();
    FakeGroupMapping.clearBlackList();

    // We make an entry
    groups.getGroups("me");
    int startingRequestCount = FakeGroupMapping.getRequestCount();

    timer.advance(20 * 1000);

    // Cache entry has expired so it results in a new fetch
    groups.getGroups("me");
    assertEquals(startingRequestCount + 1, FakeGroupMapping.getRequestCount());
  }
예제 #11
0
  @Test
  public void testCachePreventsImplRequest() throws Exception {
    // Disable negative cache.
    conf.setLong(CommonConfigurationKeys.HADOOP_SECURITY_GROUPS_NEGATIVE_CACHE_SECS, 0);
    Groups groups = new Groups(conf);
    groups.cacheGroupsAdd(Arrays.asList(myGroups));
    groups.refresh();
    FakeGroupMapping.clearBlackList();

    assertEquals(0, FakeGroupMapping.getRequestCount());

    // First call hits the wire
    assertTrue(groups.getGroups("me").size() == 2);
    assertEquals(1, FakeGroupMapping.getRequestCount());

    // Second count hits cache
    assertTrue(groups.getGroups("me").size() == 2);
    assertEquals(1, FakeGroupMapping.getRequestCount());
  }
 /**
  * Get the group names for this user.
  *
  * @return the list of users with the primary group first. If the command fails, it returns an
  *     empty list.
  */
 public synchronized String[] getGroupNames() {
   ensureInitialized();
   try {
     List<String> result = groups.getGroups(getShortUserName());
     return result.toArray(new String[result.size()]);
   } catch (IOException ie) {
     LOG.warn("No groups available for user " + getShortUserName());
     return new String[0];
   }
 }
 public static void refreshGroupPassword() {
   if (groups != null) {
     GroupMappingServiceProvider gmspImpl = groups.getUserToGroupsMappingServiceImpl();
     if (gmspImpl != null) {
       try {
         gmspImpl.cacheGroupsRefresh();
       } catch (Exception e) {
         LOG.warn("UIG refreshGroupPassword fail: " + e);
       }
     }
   }
 }
예제 #14
0
  @Test
  public void testNegativeCacheClearedOnRefresh() throws Exception {
    conf.setLong(CommonConfigurationKeys.HADOOP_SECURITY_GROUPS_NEGATIVE_CACHE_SECS, 100);
    final Groups groups = new Groups(conf);
    groups.cacheGroupsAdd(Arrays.asList(myGroups));
    groups.refresh();
    FakeGroupMapping.clearBlackList();
    FakeGroupMapping.addToBlackList("dne");

    try {
      groups.getGroups("dne");
      fail("Should have failed to find this group");
    } catch (IOException e) {
      // pass
    }

    int startingRequestCount = FakeGroupMapping.getRequestCount();

    groups.refresh();
    FakeGroupMapping.addToBlackList("dne");

    try {
      List<String> g = groups.getGroups("dne");
      fail("Should have failed to find this group");
    } catch (IOException e) {
      // pass
    }

    assertEquals(startingRequestCount + 1, FakeGroupMapping.getRequestCount());
  }
  @Before
  public void setUp() throws Exception {
    config = new Configuration();
    config.setClass(
        "hadoop.security.group.mapping",
        TestRefreshUserMappings.MockUnixGroupsMapping.class,
        GroupMappingServiceProvider.class);
    config.setLong("hadoop.security.groups.cache.secs", groupRefreshTimeoutSec);
    Groups.getUserToGroupsMappingService(config);

    FileSystem.setDefaultUri(config, "hdfs://localhost:" + "0");
    cluster = new MiniDFSCluster(0, config, 1, true, true, true, null, null, null, null);
    cluster.waitActive();
  }
예제 #16
0
  @Test
  public void testOnlyOneRequestWhenNoEntryIsCached() throws Exception {
    // Disable negative cache.
    conf.setLong(CommonConfigurationKeys.HADOOP_SECURITY_GROUPS_NEGATIVE_CACHE_SECS, 0);
    final Groups groups = new Groups(conf);
    groups.cacheGroupsAdd(Arrays.asList(myGroups));
    groups.refresh();
    FakeGroupMapping.clearBlackList();
    FakeGroupMapping.setGetGroupsDelayMs(100);

    ArrayList<Thread> threads = new ArrayList<Thread>();
    for (int i = 0; i < 10; i++) {
      threads.add(
          new Thread() {
            public void run() {
              try {
                assertEquals(2, groups.getGroups("me").size());
              } catch (IOException e) {
                fail("Should not happen");
              }
            }
          });
    }

    // We start a bunch of threads who all see no cached value
    for (Thread t : threads) {
      t.start();
    }

    for (Thread t : threads) {
      t.join();
    }

    // But only one thread should have made the request
    assertEquals(1, FakeGroupMapping.getRequestCount());
  }
예제 #17
0
  @Test
  public void testNegativeGroupCaching() throws Exception {
    final String user = "******";
    final String failMessage = "Did not throw IOException: ";
    conf.setLong(CommonConfigurationKeys.HADOOP_SECURITY_GROUPS_NEGATIVE_CACHE_SECS, 2);
    FakeTimer timer = new FakeTimer();
    Groups groups = new Groups(conf, timer);
    groups.cacheGroupsAdd(Arrays.asList(myGroups));
    groups.refresh();
    FakeGroupMapping.addToBlackList(user);

    // In the first attempt, the user will be put in the negative cache.
    try {
      groups.getGroups(user);
      fail(failMessage + "Failed to obtain groups from FakeGroupMapping.");
    } catch (IOException e) {
      // Expects to raise exception for the first time. But the user will be
      // put into the negative cache
      GenericTestUtils.assertExceptionContains("No groups found for user", e);
    }

    // The second time, the user is in the negative cache.
    try {
      groups.getGroups(user);
      fail(failMessage + "The user is in the negative cache.");
    } catch (IOException e) {
      GenericTestUtils.assertExceptionContains("No groups found for user", e);
    }

    // Brings back the backend user-group mapping service.
    FakeGroupMapping.clearBlackList();

    // It should still get groups from the negative cache.
    try {
      groups.getGroups(user);
      fail(
          failMessage
              + "The user is still in the negative cache, even "
              + "FakeGroupMapping has resumed.");
    } catch (IOException e) {
      GenericTestUtils.assertExceptionContains("No groups found for user", e);
    }

    // Let the elements in the negative cache expire.
    timer.advance(4 * 1000);

    // The groups for the user is expired in the negative cache, a new copy of
    // groups for the user is fetched.
    assertEquals(Arrays.asList(myGroups), groups.getGroups(user));
  }
  /** whether user is authorized? */
  public boolean isAuthorized() {
    if (!useConfiguredFileAuth) {
      return true;
    }

    Set privateCredList = subject.getPrivateCredentials();
    String userName = user.getName();
    String userPassword = null;
    if ((userName == null) || (privateCredList == null)) {
      return false;
    }

    userPassword = getPassword();
    try {
      String correctPassword = groups.getPassword(user.getName());
      if ((correctPassword != null) && (correctPassword.equals(userPassword))) {
        return true;
      }
    } catch (Exception e) {
      e.printStackTrace();
    }
    return false;
  }
  @Test
  public void testGroupMappingRefresh() throws Exception {
    DFSAdmin admin = new DFSAdmin(config);
    String[] args = new String[] {"-refreshUserToGroupsMappings"};
    Groups groups = Groups.getUserToGroupsMappingService(config);
    String user = UserGroupInformation.getCurrentUser().getUserName();
    System.out.println("first attempt:");
    List<String> g1 = groups.getGroups(user);
    String[] str_groups = new String[g1.size()];
    g1.toArray(str_groups);
    System.out.println(Arrays.toString(str_groups));

    System.out.println("second attempt, should be same:");
    List<String> g2 = groups.getGroups(user);
    g2.toArray(str_groups);
    System.out.println(Arrays.toString(str_groups));
    for (int i = 0; i < g2.size(); i++) {
      assertEquals("Should be same group ", g1.get(i), g2.get(i));
    }
    admin.run(args);
    System.out.println("third attempt(after refresh command), should be different:");
    List<String> g3 = groups.getGroups(user);
    g3.toArray(str_groups);
    System.out.println(Arrays.toString(str_groups));
    for (int i = 0; i < g3.size(); i++) {
      assertFalse(
          "Should be different group: " + g1.get(i) + " and " + g3.get(i),
          g1.get(i).equals(g3.get(i)));
    }

    // test time out
    Thread.sleep(groupRefreshTimeoutSec * 1100);
    System.out.println("fourth attempt(after timeout), should be different:");
    List<String> g4 = groups.getGroups(user);
    g4.toArray(str_groups);
    System.out.println(Arrays.toString(str_groups));
    for (int i = 0; i < g4.size(); i++) {
      assertFalse("Should be different group ", g3.get(i).equals(g4.get(i)));
    }
  }
  @Test
  public void testRMInitialsWithFileSystemBasedConfigurationProvider() throws Exception {
    configuration.set(
        YarnConfiguration.RM_CONFIGURATION_PROVIDER_CLASS,
        "org.apache.hadoop.yarn.FileSystemBasedConfigurationProvider");

    // upload configurations
    final File excludeHostsFile = new File(tmpDir.toString(), "excludeHosts");
    if (excludeHostsFile.exists()) {
      excludeHostsFile.delete();
    }
    if (!excludeHostsFile.createNewFile()) {
      Assert.fail("Can not create " + "excludeHosts");
    }
    PrintWriter fileWriter = new PrintWriter(excludeHostsFile);
    fileWriter.write("0.0.0.0:123");
    fileWriter.close();
    uploadToRemoteFileSystem(new Path(excludeHostsFile.getAbsolutePath()));

    YarnConfiguration yarnConf = new YarnConfiguration();
    yarnConf.set(YarnConfiguration.YARN_ADMIN_ACL, "world:anyone:rwcda");
    yarnConf.set(YarnConfiguration.RM_NODES_EXCLUDE_FILE_PATH, this.workingPath + "/excludeHosts");
    uploadConfiguration(yarnConf, "yarn-site.xml");

    CapacitySchedulerConfiguration csConf = new CapacitySchedulerConfiguration();
    csConf.set("yarn.scheduler.capacity.maximum-applications", "5000");
    uploadConfiguration(csConf, "capacity-scheduler.xml");

    String aclsString = "alice,bob users,wheel";
    Configuration newConf = new Configuration();
    newConf.set("security.applicationclient.protocol.acl", aclsString);
    uploadConfiguration(newConf, "hadoop-policy.xml");

    Configuration conf = new Configuration();
    conf.setBoolean(CommonConfigurationKeysPublic.HADOOP_SECURITY_AUTHORIZATION, true);
    conf.set("hadoop.proxyuser.test.groups", "test_groups");
    conf.set("hadoop.proxyuser.test.hosts", "test_hosts");
    conf.setClass(
        CommonConfigurationKeys.HADOOP_SECURITY_GROUP_MAPPING,
        MockUnixGroupsMapping.class,
        GroupMappingServiceProvider.class);
    uploadConfiguration(conf, "core-site.xml");

    // update the groups
    MockUnixGroupsMapping.updateGroups();

    ResourceManager resourceManager = null;
    try {
      try {
        resourceManager = new ResourceManager();
        resourceManager.init(configuration);
        resourceManager.start();
      } catch (Exception ex) {
        fail("Should not get any exceptions");
      }

      // validate values for excludeHosts
      Set<String> excludeHosts =
          resourceManager.getRMContext().getNodesListManager().getHostsReader().getExcludedHosts();
      Assert.assertTrue(excludeHosts.size() == 1);
      Assert.assertTrue(excludeHosts.contains("0.0.0.0:123"));

      // validate values for admin-acls
      String aclStringAfter =
          resourceManager.adminService.getAccessControlList().getAclString().trim();
      Assert.assertEquals(aclStringAfter, "world:anyone:rwcda");

      // validate values for queue configuration
      CapacityScheduler cs = (CapacityScheduler) resourceManager.getRMContext().getScheduler();
      int maxAppsAfter = cs.getConfiguration().getMaximumSystemApplications();
      Assert.assertEquals(maxAppsAfter, 5000);

      // verify service Acls for AdminService
      ServiceAuthorizationManager adminServiceServiceManager =
          resourceManager.adminService.getServer().getServiceAuthorizationManager();
      verifyServiceACLsRefresh(
          adminServiceServiceManager,
          org.apache.hadoop.yarn.api.ApplicationClientProtocolPB.class,
          aclsString);

      // verify service ACLs for ClientRMService
      ServiceAuthorizationManager clientRMServiceServiceManager =
          resourceManager
              .getRMContext()
              .getClientRMService()
              .getServer()
              .getServiceAuthorizationManager();
      verifyServiceACLsRefresh(
          clientRMServiceServiceManager,
          org.apache.hadoop.yarn.api.ApplicationClientProtocolPB.class,
          aclsString);

      // verify service ACLs for ApplicationMasterService
      ServiceAuthorizationManager appMasterService =
          resourceManager
              .getRMContext()
              .getApplicationMasterService()
              .getServer()
              .getServiceAuthorizationManager();
      verifyServiceACLsRefresh(
          appMasterService,
          org.apache.hadoop.yarn.api.ApplicationClientProtocolPB.class,
          aclsString);

      // verify service ACLs for ResourceTrackerService
      ServiceAuthorizationManager RTService =
          resourceManager
              .getRMContext()
              .getResourceTrackerService()
              .getServer()
              .getServiceAuthorizationManager();
      verifyServiceACLsRefresh(
          RTService, org.apache.hadoop.yarn.api.ApplicationClientProtocolPB.class, aclsString);

      // verify ProxyUsers and ProxyHosts
      Assert.assertTrue(
          ProxyUsers.getProxyGroups().get("hadoop.proxyuser.test.groups").size() == 1);
      Assert.assertTrue(
          ProxyUsers.getProxyGroups().get("hadoop.proxyuser.test.groups").contains("test_groups"));

      Assert.assertTrue(ProxyUsers.getProxyHosts().get("hadoop.proxyuser.test.hosts").size() == 1);
      Assert.assertTrue(
          ProxyUsers.getProxyHosts().get("hadoop.proxyuser.test.hosts").contains("test_hosts"));

      // verify UserToGroupsMappings
      List<String> groupAfter =
          Groups.getUserToGroupsMappingService(configuration)
              .getGroups(UserGroupInformation.getCurrentUser().getUserName());
      Assert.assertTrue(
          groupAfter.contains("test_group_D")
              && groupAfter.contains("test_group_E")
              && groupAfter.contains("test_group_F")
              && groupAfter.size() == 3);
    } finally {
      if (resourceManager != null) {
        resourceManager.stop();
      }
    }
  }
  @Test
  public void testRefreshUserToGroupsMappingsWithFileSystemBasedConfigurationProvider()
      throws IOException, YarnException {
    configuration.set(
        YarnConfiguration.RM_CONFIGURATION_PROVIDER_CLASS,
        "org.apache.hadoop.yarn.FileSystemBasedConfigurationProvider");

    String[] defaultTestUserGroups = {"dummy_group1", "dummy_group2"};
    UserGroupInformation ugi =
        UserGroupInformation.createUserForTesting("dummyUser", defaultTestUserGroups);

    String user = ugi.getUserName();
    List<String> groupWithInit = new ArrayList<String>(2);
    for (int i = 0; i < ugi.getGroupNames().length; i++) {
      groupWithInit.add(ugi.getGroupNames()[i]);
    }

    // upload default configurations
    uploadDefaultConfiguration();
    Configuration conf = new Configuration();
    conf.setClass(
        CommonConfigurationKeys.HADOOP_SECURITY_GROUP_MAPPING,
        MockUnixGroupsMapping.class,
        GroupMappingServiceProvider.class);
    uploadConfiguration(conf, "core-site.xml");

    try {
      rm = new MockRM(configuration);
      rm.init(configuration);
      rm.start();
    } catch (Exception ex) {
      fail("Should not get any exceptions");
    }

    // Make sure RM will use the updated GroupMappingServiceProvider
    List<String> groupBefore =
        new ArrayList<String>(Groups.getUserToGroupsMappingService(configuration).getGroups(user));
    Assert.assertTrue(
        groupBefore.contains("test_group_A")
            && groupBefore.contains("test_group_B")
            && groupBefore.contains("test_group_C")
            && groupBefore.size() == 3);
    Assert.assertTrue(groupWithInit.size() != groupBefore.size());
    Assert.assertFalse(
        groupWithInit.contains("test_group_A")
            || groupWithInit.contains("test_group_B")
            || groupWithInit.contains("test_group_C"));

    // update the groups
    MockUnixGroupsMapping.updateGroups();

    rm.adminService.refreshUserToGroupsMappings(RefreshUserToGroupsMappingsRequest.newInstance());
    List<String> groupAfter = Groups.getUserToGroupsMappingService(configuration).getGroups(user);

    // should get the updated groups
    Assert.assertTrue(
        groupAfter.contains("test_group_D")
            && groupAfter.contains("test_group_E")
            && groupAfter.contains("test_group_F")
            && groupAfter.size() == 3);
  }