1 /** 2 * Licensed to the Apache Software Foundation (ASF) under one 3 * or more contributor license agreements. See the NOTICE file 4 * distributed with this work for additional information 5 * regarding copyright ownership. The ASF licenses this file 6 * to you under the Apache License, Version 2.0 (the 7 * "License"); you may not use this file except in compliance 8 * with the License. You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, software 13 * distributed under the License is distributed on an "AS IS" BASIS, 14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 * See the License for the specific language governing permissions and 16 * limitations under the License. 17 */ 18 19 package org.apache.hadoop.yarn.server.nodemanager; 20 21 import java.io.File; 22 import java.io.IOException; 23 import java.util.List; 24 import java.util.ListIterator; 25 26 import org.apache.hadoop.conf.Configuration; 27 import org.apache.hadoop.fs.CommonConfigurationKeys; 28 import org.apache.hadoop.fs.FileContext; 29 import org.apache.hadoop.fs.FileStatus; 30 import org.apache.hadoop.fs.FileUtil; 31 import org.apache.hadoop.fs.Path; 32 import org.apache.hadoop.fs.permission.FsPermission; 33 import org.apache.hadoop.yarn.conf.YarnConfiguration; 34 import org.junit.After; 35 import org.junit.Assert; 36 import org.junit.Before; 37 import org.junit.BeforeClass; 38 import org.junit.Before; 39 import org.junit.Test; 40 41 public class TestDirectoryCollection { 42 43 private static final File testDir = new File("target", 44 TestDirectoryCollection.class.getName()).getAbsoluteFile(); 45 private static final File testFile = new File(testDir, "testfile"); 46 47 private Configuration conf; 48 private FileContext localFs; 49 50 @Before setupForTests()51 public void setupForTests() throws IOException { 52 conf = new Configuration(); 53 localFs = FileContext.getLocalFSFileContext(conf); 54 testDir.mkdirs(); 55 testFile.createNewFile(); 56 } 57 58 @After teardown()59 public void teardown() { 60 FileUtil.fullyDelete(testDir); 61 } 62 63 @Test testConcurrentAccess()64 public void testConcurrentAccess() throws IOException { 65 // Initialize DirectoryCollection with a file instead of a directory 66 67 String[] dirs = {testFile.getPath()}; 68 DirectoryCollection dc = 69 new DirectoryCollection(dirs, conf.getFloat( 70 YarnConfiguration.NM_MAX_PER_DISK_UTILIZATION_PERCENTAGE, 71 YarnConfiguration.DEFAULT_NM_MAX_PER_DISK_UTILIZATION_PERCENTAGE)); 72 73 // Create an iterator before checkDirs is called to reliable test case 74 List<String> list = dc.getGoodDirs(); 75 ListIterator<String> li = list.listIterator(); 76 77 // DiskErrorException will invalidate iterator of non-concurrent 78 // collections. ConcurrentModificationException will be thrown upon next 79 // use of the iterator. 80 Assert.assertTrue("checkDirs did not remove test file from directory list", 81 dc.checkDirs()); 82 83 // Verify no ConcurrentModification is thrown 84 li.next(); 85 } 86 87 @Test testCreateDirectories()88 public void testCreateDirectories() throws IOException { 89 90 conf.set(CommonConfigurationKeys.FS_PERMISSIONS_UMASK_KEY, "077"); 91 92 String dirA = new File(testDir, "dirA").getPath(); 93 String dirB = new File(dirA, "dirB").getPath(); 94 String dirC = new File(testDir, "dirC").getPath(); 95 Path pathC = new Path(dirC); 96 FsPermission permDirC = new FsPermission((short)0710); 97 98 localFs.mkdir(pathC, null, true); 99 localFs.setPermission(pathC, permDirC); 100 101 String[] dirs = { dirA, dirB, dirC }; 102 DirectoryCollection dc = 103 new DirectoryCollection(dirs, conf.getFloat( 104 YarnConfiguration.NM_MAX_PER_DISK_UTILIZATION_PERCENTAGE, 105 YarnConfiguration.DEFAULT_NM_MAX_PER_DISK_UTILIZATION_PERCENTAGE)); 106 FsPermission defaultPerm = FsPermission.getDefault() 107 .applyUMask(new FsPermission((short)FsPermission.DEFAULT_UMASK)); 108 boolean createResult = dc.createNonExistentDirs(localFs, defaultPerm); 109 Assert.assertTrue(createResult); 110 111 FileStatus status = localFs.getFileStatus(new Path(dirA)); 112 Assert.assertEquals("local dir parent not created with proper permissions", 113 defaultPerm, status.getPermission()); 114 status = localFs.getFileStatus(new Path(dirB)); 115 Assert.assertEquals("local dir not created with proper permissions", 116 defaultPerm, status.getPermission()); 117 status = localFs.getFileStatus(pathC); 118 Assert.assertEquals("existing local directory permissions modified", 119 permDirC, status.getPermission()); 120 } 121 122 @Test testDiskSpaceUtilizationLimit()123 public void testDiskSpaceUtilizationLimit() throws IOException { 124 125 String dirA = new File(testDir, "dirA").getPath(); 126 String[] dirs = { dirA }; 127 DirectoryCollection dc = new DirectoryCollection(dirs, 0.0F); 128 dc.checkDirs(); 129 Assert.assertEquals(0, dc.getGoodDirs().size()); 130 Assert.assertEquals(1, dc.getFailedDirs().size()); 131 Assert.assertEquals(1, dc.getFullDirs().size()); 132 133 dc = new DirectoryCollection(dirs, 100.0F); 134 dc.checkDirs(); 135 Assert.assertEquals(1, dc.getGoodDirs().size()); 136 Assert.assertEquals(0, dc.getFailedDirs().size()); 137 Assert.assertEquals(0, dc.getFullDirs().size()); 138 139 dc = new DirectoryCollection(dirs, testDir.getTotalSpace() / (1024 * 1024)); 140 dc.checkDirs(); 141 Assert.assertEquals(0, dc.getGoodDirs().size()); 142 Assert.assertEquals(1, dc.getFailedDirs().size()); 143 Assert.assertEquals(1, dc.getFullDirs().size()); 144 145 dc = new DirectoryCollection(dirs, 100.0F, 0); 146 dc.checkDirs(); 147 Assert.assertEquals(1, dc.getGoodDirs().size()); 148 Assert.assertEquals(0, dc.getFailedDirs().size()); 149 Assert.assertEquals(0, dc.getFullDirs().size()); 150 } 151 152 @Test testDiskLimitsCutoffSetters()153 public void testDiskLimitsCutoffSetters() throws IOException { 154 155 String[] dirs = { "dir" }; 156 DirectoryCollection dc = new DirectoryCollection(dirs, 0.0F, 100); 157 float testValue = 57.5F; 158 float delta = 0.1F; 159 dc.setDiskUtilizationPercentageCutoff(testValue); 160 Assert.assertEquals(testValue, dc.getDiskUtilizationPercentageCutoff(), 161 delta); 162 testValue = -57.5F; 163 dc.setDiskUtilizationPercentageCutoff(testValue); 164 Assert.assertEquals(0.0F, dc.getDiskUtilizationPercentageCutoff(), delta); 165 testValue = 157.5F; 166 dc.setDiskUtilizationPercentageCutoff(testValue); 167 Assert.assertEquals(100.0F, dc.getDiskUtilizationPercentageCutoff(), delta); 168 169 long spaceValue = 57; 170 dc.setDiskUtilizationSpaceCutoff(spaceValue); 171 Assert.assertEquals(spaceValue, dc.getDiskUtilizationSpaceCutoff()); 172 spaceValue = -57; 173 dc.setDiskUtilizationSpaceCutoff(spaceValue); 174 Assert.assertEquals(0, dc.getDiskUtilizationSpaceCutoff()); 175 } 176 177 @Test testFailedDisksBecomingGoodAgain()178 public void testFailedDisksBecomingGoodAgain() throws Exception { 179 180 String dirA = new File(testDir, "dirA").getPath(); 181 String[] dirs = { dirA }; 182 DirectoryCollection dc = new DirectoryCollection(dirs, 0.0F); 183 dc.checkDirs(); 184 Assert.assertEquals(0, dc.getGoodDirs().size()); 185 Assert.assertEquals(1, dc.getFailedDirs().size()); 186 Assert.assertEquals(1, dc.getFullDirs().size()); 187 188 dc.setDiskUtilizationPercentageCutoff(100.0F); 189 dc.checkDirs(); 190 Assert.assertEquals(1, dc.getGoodDirs().size()); 191 Assert.assertEquals(0, dc.getFailedDirs().size()); 192 Assert.assertEquals(0, dc.getFullDirs().size()); 193 194 conf.set(CommonConfigurationKeys.FS_PERMISSIONS_UMASK_KEY, "077"); 195 196 String dirB = new File(testDir, "dirB").getPath(); 197 Path pathB = new Path(dirB); 198 FsPermission permDirB = new FsPermission((short) 0400); 199 200 localFs.mkdir(pathB, null, true); 201 localFs.setPermission(pathB, permDirB); 202 203 String[] dirs2 = { dirB }; 204 205 dc = new DirectoryCollection(dirs2, 100.0F); 206 dc.checkDirs(); 207 Assert.assertEquals(0, dc.getGoodDirs().size()); 208 Assert.assertEquals(1, dc.getFailedDirs().size()); 209 Assert.assertEquals(0, dc.getFullDirs().size()); 210 permDirB = new FsPermission((short) 0700); 211 localFs.setPermission(pathB, permDirB); 212 dc.checkDirs(); 213 Assert.assertEquals(1, dc.getGoodDirs().size()); 214 Assert.assertEquals(0, dc.getFailedDirs().size()); 215 Assert.assertEquals(0, dc.getFullDirs().size()); 216 } 217 218 @Test testConstructors()219 public void testConstructors() { 220 221 String[] dirs = { "dir" }; 222 float delta = 0.1F; 223 DirectoryCollection dc = new DirectoryCollection(dirs); 224 Assert.assertEquals(100.0F, dc.getDiskUtilizationPercentageCutoff(), delta); 225 Assert.assertEquals(0, dc.getDiskUtilizationSpaceCutoff()); 226 227 dc = new DirectoryCollection(dirs, 57.5F); 228 Assert.assertEquals(57.5F, dc.getDiskUtilizationPercentageCutoff(), delta); 229 Assert.assertEquals(0, dc.getDiskUtilizationSpaceCutoff()); 230 231 dc = new DirectoryCollection(dirs, 57); 232 Assert.assertEquals(100.0F, dc.getDiskUtilizationPercentageCutoff(), delta); 233 Assert.assertEquals(57, dc.getDiskUtilizationSpaceCutoff()); 234 235 dc = new DirectoryCollection(dirs, 57.5F, 67); 236 Assert.assertEquals(57.5F, dc.getDiskUtilizationPercentageCutoff(), delta); 237 Assert.assertEquals(67, dc.getDiskUtilizationSpaceCutoff()); 238 239 dc = new DirectoryCollection(dirs, -57.5F, -67); 240 Assert.assertEquals(0.0F, dc.getDiskUtilizationPercentageCutoff(), delta); 241 Assert.assertEquals(0, dc.getDiskUtilizationSpaceCutoff()); 242 243 dc = new DirectoryCollection(dirs, 157.5F, -67); 244 Assert.assertEquals(100.0F, dc.getDiskUtilizationPercentageCutoff(), delta); 245 Assert.assertEquals(0, dc.getDiskUtilizationSpaceCutoff()); 246 } 247 } 248