IdUserGroup { @VisibleForTesting public static void updateMapInternal(BiMap<Integer, String> map, String mapName, String command, String regex) throws IOException { BufferedReader br = null; try { Process process = Runtime.getRuntime().exec( new String[] { "bash", "-c", command }); br = new BufferedReader(new InputStreamReader(process.getInputStream())); String line = null; while ((line = br.readLine()) != null) { String[] nameId = line.split(regex); if ((nameId == null) || (nameId.length != 2)) { throw new IOException("Can't parse " + mapName + " list entry:" + line); } LOG.debug("add to " + mapName + "map:" + nameId[0] + " id:" + nameId[1]); final Integer key = parseId(nameId[1]); final String value = nameId[0]; if (map.containsKey(key)) { final String prevValue = map.get(key); if (value.equals(prevValue)) { continue; } reportDuplicateEntry( "Got multiple names associated with the same id: ", key, value, key, prevValue); continue; } if (map.containsValue(value)) { final Integer prevKey = map.inverse().get(value); reportDuplicateEntry( "Got multiple ids associated with the same name: ", key, value, prevKey, value); continue; } map.put(key, value); } LOG.info("Updated " + mapName + " map size:" + map.size()); } catch (IOException e) { LOG.error("Can't update " + mapName + " map"); throw e; } finally { if (br != null) { try { br.close(); } catch (IOException e1) { LOG.error("Can't close BufferedReader of command result", e1); } } } } IdUserGroup();  IdUserGroup(Configuration conf); @VisibleForTesting long getTimeout(); @VisibleForTesting static void updateMapInternal(BiMap<Integer, String> map, String mapName,
      String command, String regex); synchronized void updateMaps(); synchronized int getUid(String user); synchronized int getGid(String group); synchronized String getUserName(int uid, String unknown); synchronized String getGroupName(int gid, String unknown); int getUidAllowingUnknown(String user); int getGidAllowingUnknown(String group);  }
@Test public void testDuplicates() throws IOException { String GET_ALL_USERS_CMD = "echo \"root:x:0:0:root:/root:/bin/bash\n" + "hdfs:x:11501:10787:Grid Distributed File System:/home/hdfs:/bin/bash\n" + "hdfs:x:11502:10788:Grid Distributed File System:/home/hdfs:/bin/bash\n" + "hdfs1:x:11501:10787:Grid Distributed File System:/home/hdfs:/bin/bash\n" + "hdfs2:x:11502:10787:Grid Distributed File System:/home/hdfs:/bin/bash\n" + "bin:x:2:2:bin:/bin:/bin/sh\n" + "bin:x:1:1:bin:/bin:/sbin/nologin\n" + "daemon:x:1:1:daemon:/usr/sbin:/bin/sh\n" + "daemon:x:2:2:daemon:/sbin:/sbin/nologin\"" + " | cut -d: -f1,3"; String GET_ALL_GROUPS_CMD = "echo \"hdfs:*:11501:hrt_hdfs\n" + "mapred:x:497\n" + "mapred2:x:497\n" + "mapred:x:498\n" + "mapred3:x:498\"" + " | cut -d: -f1,3"; BiMap<Integer, String> uMap = HashBiMap.create(); BiMap<Integer, String> gMap = HashBiMap.create(); IdUserGroup.updateMapInternal(uMap, "user", GET_ALL_USERS_CMD, ":"); assertTrue(uMap.size() == 5); assertEquals(uMap.get(0), "root"); assertEquals(uMap.get(11501), "hdfs"); assertEquals(uMap.get(11502), "hdfs2"); assertEquals(uMap.get(2), "bin"); assertEquals(uMap.get(1), "daemon"); IdUserGroup.updateMapInternal(gMap, "group", GET_ALL_GROUPS_CMD, ":"); assertTrue(gMap.size() == 3); assertEquals(gMap.get(11501), "hdfs"); assertEquals(gMap.get(497), "mapred"); assertEquals(gMap.get(498), "mapred3"); }
@Test public void testIdOutOfIntegerRange() throws IOException { String GET_ALL_USERS_CMD = "echo \"" + "nfsnobody:x:4294967294:4294967294:Anonymous NFS User:/var/lib/nfs:/sbin/nologin\n" + "nfsnobody1:x:4294967295:4294967295:Anonymous NFS User:/var/lib/nfs1:/sbin/nologin\n" + "maxint:x:2147483647:2147483647:Grid Distributed File System:/home/maxint:/bin/bash\n" + "minint:x:2147483648:2147483648:Grid Distributed File System:/home/minint:/bin/bash\n" + "archivebackup:*:1031:4294967294:Archive Backup:/home/users/archivebackup:/bin/sh\n" + "hdfs:x:11501:10787:Grid Distributed File System:/home/hdfs:/bin/bash\n" + "daemon:x:2:2:daemon:/sbin:/sbin/nologin\"" + " | cut -d: -f1,3"; String GET_ALL_GROUPS_CMD = "echo \"" + "hdfs:*:11501:hrt_hdfs\n" + "rpcuser:*:29:\n" + "nfsnobody:*:4294967294:\n" + "nfsnobody1:*:4294967295:\n" + "maxint:*:2147483647:\n" + "minint:*:2147483648:\n" + "mapred3:x:498\"" + " | cut -d: -f1,3"; BiMap<Integer, String> uMap = HashBiMap.create(); BiMap<Integer, String> gMap = HashBiMap.create(); IdUserGroup.updateMapInternal(uMap, "user", GET_ALL_USERS_CMD, ":"); assertTrue(uMap.size() == 7); assertEquals("nfsnobody", uMap.get(-2)); assertEquals("nfsnobody1", uMap.get(-1)); assertEquals("maxint", uMap.get(2147483647)); assertEquals("minint", uMap.get(-2147483648)); assertEquals("archivebackup", uMap.get(1031)); assertEquals("hdfs",uMap.get(11501)); assertEquals("daemon", uMap.get(2)); IdUserGroup.updateMapInternal(gMap, "group", GET_ALL_GROUPS_CMD, ":"); assertTrue(gMap.size() == 7); assertEquals("hdfs",gMap.get(11501)); assertEquals("rpcuser", gMap.get(29)); assertEquals("nfsnobody", gMap.get(-2)); assertEquals("nfsnobody1", gMap.get(-1)); assertEquals("maxint", gMap.get(2147483647)); assertEquals("minint", gMap.get(-2147483648)); assertEquals("mapred3", gMap.get(498)); }