| /* |
| * * |
| * 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.hadoop.yarn.server.nodemanager.containermanager.linux.resources; |
| |
| import org.apache.commons.io.FileUtils; |
| import org.slf4j.Logger; |
| import org.slf4j.LoggerFactory; |
| import org.apache.hadoop.conf.Configuration; |
| import org.apache.hadoop.fs.FileUtil; |
| import org.apache.hadoop.fs.Path; |
| import org.apache.hadoop.yarn.conf.YarnConfiguration; |
| import org.apache.hadoop.yarn.server.nodemanager.containermanager.linux.privileged.PrivilegedOperation; |
| import org.apache.hadoop.yarn.server.nodemanager.containermanager.linux.privileged.PrivilegedOperationException; |
| import org.apache.hadoop.yarn.server.nodemanager.containermanager.linux.privileged.PrivilegedOperationExecutor; |
| import org.junit.After; |
| import org.junit.Assert; |
| import org.junit.Before; |
| import org.junit.Test; |
| import org.mockito.ArgumentCaptor; |
| |
| import java.io.File; |
| import java.io.FileWriter; |
| import java.io.IOException; |
| import java.nio.file.Files; |
| import java.security.Permission; |
| import java.util.Collections; |
| import java.util.LinkedHashMap; |
| import java.util.Map; |
| import java.util.Set; |
| import java.util.UUID; |
| |
| import static org.junit.Assert.assertTrue; |
| import static org.mockito.Matchers.eq; |
| import static org.mockito.Mockito.mock; |
| import static org.mockito.Mockito.verify; |
| import static org.mockito.Mockito.verifyNoMoreInteractions; |
| import static org.mockito.Mockito.verifyZeroInteractions; |
| |
| /** |
| * Tests for the CGroups handler implementation. |
| */ |
| public class TestCGroupsHandlerImpl { |
| private static final Logger LOG = |
| LoggerFactory.getLogger(TestCGroupsHandlerImpl.class); |
| |
| private PrivilegedOperationExecutor privilegedOperationExecutorMock; |
| private String tmpPath; |
| private String hierarchy; |
| private CGroupsHandler.CGroupController controller; |
| private String controllerPath; |
| |
| @Before |
| public void setup() { |
| privilegedOperationExecutorMock = mock(PrivilegedOperationExecutor.class); |
| |
| // Prepare test directory |
| tmpPath = System.getProperty("test.build.data") + "/cgroups"; |
| File tmpDir = new File(tmpPath); |
| FileUtils.deleteQuietly(tmpDir); |
| assertTrue(tmpDir.mkdirs()); |
| |
| //no leading or trailing slashes here |
| hierarchy = "test-hadoop-yarn"; |
| |
| // Sample subsystem. Not used by all the tests |
| controller = CGroupsHandler.CGroupController.NET_CLS; |
| controllerPath = |
| new File(new File(tmpPath, controller.getName()), hierarchy) |
| .getAbsolutePath(); |
| } |
| |
| @After |
| public void teardown() { |
| FileUtil.fullyDelete(new File(tmpPath)); |
| } |
| |
| /** |
| * Security manager simulating access denied. |
| */ |
| private class MockSecurityManagerDenyWrite extends SecurityManager { |
| @Override |
| public void checkPermission(Permission perm) { |
| if(perm.getActions().equals("write")) { |
| throw new SecurityException("Mock not allowed"); |
| } |
| } |
| } |
| |
| /** |
| * Create configuration to mount cgroups that do not exist. |
| * @return configuration object |
| */ |
| private YarnConfiguration createMountConfiguration() { |
| YarnConfiguration conf = new YarnConfiguration(); |
| conf.set(YarnConfiguration.NM_LINUX_CONTAINER_CGROUPS_HIERARCHY, hierarchy); |
| conf.setBoolean(YarnConfiguration.NM_LINUX_CONTAINER_CGROUPS_MOUNT, true); |
| conf.set(YarnConfiguration.NM_LINUX_CONTAINER_CGROUPS_MOUNT_PATH, tmpPath); |
| return conf; |
| } |
| |
| /** |
| * Create configuration where the cgroups are premounted. |
| * @param myHierarchy Yarn cgroup |
| * @return configuration object |
| */ |
| private Configuration createNoMountConfiguration(String myHierarchy) { |
| Configuration confNoMount = new Configuration(); |
| confNoMount.set(YarnConfiguration.NM_LINUX_CONTAINER_CGROUPS_HIERARCHY, |
| myHierarchy); |
| confNoMount.setBoolean(YarnConfiguration.NM_LINUX_CONTAINER_CGROUPS_MOUNT, |
| false); |
| return confNoMount; |
| } |
| |
| /** |
| * Create an empty mtab file. No cgroups are premounted |
| * @return mtab file |
| * @throws IOException could not create file |
| */ |
| private File createEmptyCgroups() throws IOException { |
| File emptyMtab = new File(tmpPath, "mtab"); |
| assertTrue("New file should have been created", emptyMtab.createNewFile()); |
| return emptyMtab; |
| } |
| |
| /** |
| * Create simulated cgroups mount point. |
| * @param parentDir cgroups mount point |
| * @param cpuAcct simulate newer Linux behavior by mounting cpu with cpuacct |
| * @return simulated mtab file location |
| * @throws IOException mtab file was not created |
| */ |
| public static File createPremountedCgroups(File parentDir, boolean cpuAcct) |
| throws IOException { |
| // Mark an empty directory called 'cp' cgroup. It is processed before 'cpu' |
| String cpuMtabContentMissing = |
| "none " + parentDir.getAbsolutePath() |
| + "/cp cgroup rw,relatime,cpu 0 0\n"; |
| |
| File cpuCgroup = new File(parentDir, "cpu"); |
| String cpuMtabContent = |
| "none " + cpuCgroup.getAbsolutePath() |
| + " cgroup rw,relatime,cpu" |
| + (cpuAcct ? ",cpuacct" :"") |
| + " 0 0\n"; |
| assertTrue("Directory should be created", cpuCgroup.mkdirs()); |
| |
| File blkioCgroup = new File(parentDir, "blkio"); |
| String blkioMtabContent = |
| "none " + blkioCgroup.getAbsolutePath() |
| + " cgroup rw,relatime,blkio 0 0\n"; |
| assertTrue("Directory should be created", blkioCgroup.mkdirs()); |
| |
| File mockMtab = new File(parentDir, UUID.randomUUID().toString()); |
| if (!mockMtab.exists()) { |
| if (!mockMtab.createNewFile()) { |
| String message = "Could not create file " + mockMtab.getAbsolutePath(); |
| throw new IOException(message); |
| } |
| } |
| FileWriter mtabWriter = new FileWriter(mockMtab.getAbsoluteFile()); |
| mtabWriter.write(cpuMtabContentMissing); |
| mtabWriter.write(cpuMtabContent); |
| mtabWriter.write(blkioMtabContent); |
| mtabWriter.close(); |
| mockMtab.deleteOnExit(); |
| return mockMtab; |
| } |
| |
| @Test |
| public void testMountController() throws IOException { |
| File parentDir = new File(tmpPath); |
| File cgroup = new File(parentDir, controller.getName()); |
| assertTrue("cgroup dir should be cerated", cgroup.mkdirs()); |
| //Since we enabled (deferred) cgroup controller mounting, no interactions |
| //should have occurred, with this mock |
| verifyZeroInteractions(privilegedOperationExecutorMock); |
| File emptyMtab = createEmptyCgroups(); |
| |
| try { |
| CGroupsHandler cGroupsHandler = new CGroupsHandlerImpl( |
| createMountConfiguration(), |
| privilegedOperationExecutorMock, |
| emptyMtab.getAbsolutePath()); |
| PrivilegedOperation expectedOp = new PrivilegedOperation( |
| PrivilegedOperation.OperationType.MOUNT_CGROUPS); |
| //This is expected to be of the form : |
| //net_cls=<mount_path>/net_cls |
| String controllerKV = controller.getName() + "=" + tmpPath |
| + Path.SEPARATOR + controller.getName(); |
| expectedOp.appendArgs(hierarchy, controllerKV); |
| |
| cGroupsHandler.initializeCGroupController(controller); |
| try { |
| ArgumentCaptor<PrivilegedOperation> opCaptor = ArgumentCaptor.forClass( |
| PrivilegedOperation.class); |
| verify(privilegedOperationExecutorMock) |
| .executePrivilegedOperation(opCaptor.capture(), eq(false)); |
| |
| //we'll explicitly capture and assert that the |
| //captured op and the expected op are identical. |
| Assert.assertEquals(expectedOp, opCaptor.getValue()); |
| verifyNoMoreInteractions(privilegedOperationExecutorMock); |
| |
| //Try mounting the same controller again - this should be a no-op |
| cGroupsHandler.initializeCGroupController(controller); |
| verifyNoMoreInteractions(privilegedOperationExecutorMock); |
| } catch (PrivilegedOperationException e) { |
| LOG.error("Caught exception: " + e); |
| assertTrue("Unexpected PrivilegedOperationException from mock!", |
| false); |
| } |
| } catch (ResourceHandlerException e) { |
| LOG.error("Caught exception: " + e); |
| assertTrue("Unexpected ResourceHandler Exception!", false); |
| } |
| } |
| |
| @Test |
| public void testCGroupPaths() throws IOException { |
| //As per junit behavior, we expect a new mock object to be available |
| //in this test. |
| verifyZeroInteractions(privilegedOperationExecutorMock); |
| CGroupsHandler cGroupsHandler = null; |
| File mtab = createEmptyCgroups(); |
| |
| // Lets manually create a path to (partially) simulate a controller mounted |
| // later in the test. This is required because the handler uses a mocked |
| // privileged operation executor |
| assertTrue("Sample subsystem should be created", |
| new File(controllerPath).mkdirs()); |
| |
| try { |
| cGroupsHandler = new CGroupsHandlerImpl(createMountConfiguration(), |
| privilegedOperationExecutorMock, mtab.getAbsolutePath()); |
| cGroupsHandler.initializeCGroupController(controller); |
| } catch (ResourceHandlerException e) { |
| LOG.error("Caught exception: " + e); |
| assertTrue( |
| "Unexpected ResourceHandlerException when mounting controller!", |
| false); |
| } |
| |
| String testCGroup = "container_01"; |
| String expectedPath = |
| controllerPath + Path.SEPARATOR + testCGroup; |
| String path = cGroupsHandler.getPathForCGroup(controller, testCGroup); |
| Assert.assertEquals(expectedPath, path); |
| |
| String expectedPathTasks = expectedPath + Path.SEPARATOR |
| + CGroupsHandler.CGROUP_FILE_TASKS; |
| path = cGroupsHandler.getPathForCGroupTasks(controller, testCGroup); |
| Assert.assertEquals(expectedPathTasks, path); |
| |
| String param = CGroupsHandler.CGROUP_PARAM_CLASSID; |
| String expectedPathParam = expectedPath + Path.SEPARATOR |
| + controller.getName() + "." + param; |
| path = cGroupsHandler.getPathForCGroupParam(controller, testCGroup, param); |
| Assert.assertEquals(expectedPathParam, path); |
| } |
| |
| @Test |
| public void testCGroupOperations() throws IOException { |
| //As per junit behavior, we expect a new mock object to be available |
| //in this test. |
| verifyZeroInteractions(privilegedOperationExecutorMock); |
| CGroupsHandler cGroupsHandler = null; |
| File mtab = createEmptyCgroups(); |
| |
| // Lets manually create a path to (partially) simulate a controller mounted |
| // later in the test. This is required because the handler uses a mocked |
| // privileged operation executor |
| assertTrue("Sample subsystem should be created", |
| new File(controllerPath).mkdirs()); |
| |
| try { |
| cGroupsHandler = new CGroupsHandlerImpl(createMountConfiguration(), |
| privilegedOperationExecutorMock, mtab.getAbsolutePath()); |
| cGroupsHandler.initializeCGroupController(controller); |
| } catch (ResourceHandlerException e) { |
| LOG.error("Caught exception: " + e); |
| assertTrue( |
| "Unexpected ResourceHandlerException when mounting controller!", |
| false); |
| } |
| |
| String testCGroup = "container_01"; |
| String expectedPath = controllerPath |
| + Path.SEPARATOR + testCGroup; |
| try { |
| String path = cGroupsHandler.createCGroup(controller, testCGroup); |
| |
| assertTrue(new File(expectedPath).exists()); |
| Assert.assertEquals(expectedPath, path); |
| |
| //update param and read param tests. |
| //We don't use net_cls.classid because as a test param here because |
| //cgroups provides very specific read/write semantics for classid (only |
| //numbers can be written - potentially as hex but can be read out only |
| //as decimal) |
| String param = "test_param"; |
| String paramValue = "test_param_value"; |
| |
| cGroupsHandler |
| .updateCGroupParam(controller, testCGroup, param, paramValue); |
| String paramPath = expectedPath |
| + Path.SEPARATOR + controller.getName() |
| + "." + param; |
| File paramFile = new File(paramPath); |
| |
| assertTrue(paramFile.exists()); |
| try { |
| Assert.assertEquals(paramValue, new String(Files.readAllBytes( |
| paramFile.toPath()))); |
| } catch (IOException e) { |
| LOG.error("Caught exception: " + e); |
| Assert.fail("Unexpected IOException trying to read cgroup param!"); |
| } |
| |
| Assert.assertEquals(paramValue, |
| cGroupsHandler.getCGroupParam(controller, testCGroup, param)); |
| |
| //We can't really do a delete test here. Linux cgroups |
| //implementation provides additional semantics - the cgroup cannot be |
| //deleted if there are any tasks still running in the cgroup even if |
| //the user attempting the delete has the file permissions to do so - we |
| //cannot simulate that here. Even if we create a dummy 'tasks' file, we |
| //wouldn't be able to simulate the delete behavior we need, since a cgroup |
| //can be deleted using using 'rmdir' if the tasks file is empty. Such a |
| //delete is not possible with a regular non-empty directory. |
| } catch (ResourceHandlerException e) { |
| LOG.error("Caught exception: " + e); |
| Assert |
| .fail("Unexpected ResourceHandlerException during cgroup operations!"); |
| } |
| } |
| |
| /** |
| * Tests whether mtab parsing works as expected with a valid hierarchy set. |
| * @throws Exception the test will fail |
| */ |
| @Test |
| public void testMtabParsing() throws Exception { |
| // Initialize mtab and cgroup dir |
| File parentDir = new File(tmpPath); |
| // create mock cgroup |
| File mockMtabFile = createPremountedCgroups(parentDir, false); |
| |
| // Run mtabs parsing |
| Map<String, Set<String>> newMtab = |
| CGroupsHandlerImpl.parseMtab(mockMtabFile.getAbsolutePath()); |
| Map<CGroupsHandler.CGroupController, String> controllerPaths = |
| CGroupsHandlerImpl.initializeControllerPathsFromMtab( |
| newMtab); |
| |
| // Verify |
| Assert.assertEquals(2, controllerPaths.size()); |
| assertTrue(controllerPaths |
| .containsKey(CGroupsHandler.CGroupController.CPU)); |
| assertTrue(controllerPaths |
| .containsKey(CGroupsHandler.CGroupController.BLKIO)); |
| String cpuDir = controllerPaths.get(CGroupsHandler.CGroupController.CPU); |
| String blkioDir = |
| controllerPaths.get(CGroupsHandler.CGroupController.BLKIO); |
| Assert.assertEquals(parentDir.getAbsolutePath() + "/cpu", cpuDir); |
| Assert.assertEquals(parentDir.getAbsolutePath() + "/blkio", blkioDir); |
| } |
| |
| /** |
| * Tests whether mtab parsing works as expected with the specified hierarchy. |
| * @param myHierarchy path to local cgroup hierarchy |
| * @throws Exception the test will fail |
| */ |
| private void testPreMountedControllerInitialization(String myHierarchy) |
| throws Exception { |
| // Initialize mount point |
| File parentDir = new File(tmpPath); |
| File mtab = createPremountedCgroups(parentDir, false); |
| File mountPoint = new File(parentDir, "cpu"); |
| |
| // Initialize Yarn classes |
| Configuration confNoMount = createNoMountConfiguration(myHierarchy); |
| CGroupsHandlerImpl cGroupsHandler = new CGroupsHandlerImpl(confNoMount, |
| privilegedOperationExecutorMock, mtab.getAbsolutePath()); |
| |
| File cpuCgroupMountDir = new File( |
| cGroupsHandler.getPathForCGroup(CGroupsHandler.CGroupController.CPU, |
| "")); |
| // Test that a missing yarn hierarchy will be created automatically |
| if (!cpuCgroupMountDir.equals(mountPoint)) { |
| assertTrue("Directory should be deleted", |
| !cpuCgroupMountDir.exists()); |
| } |
| cGroupsHandler.initializeCGroupController( |
| CGroupsHandler.CGroupController.CPU); |
| assertTrue("Cgroups not writable", cpuCgroupMountDir.exists() && |
| cpuCgroupMountDir.canWrite()); |
| |
| // Test that an inaccessible yarn hierarchy results in an exception |
| assertTrue(cpuCgroupMountDir.setWritable(false)); |
| try { |
| cGroupsHandler.initializeCGroupController( |
| CGroupsHandler.CGroupController.CPU); |
| Assert.fail("An inaccessible path should result in an exception"); |
| } catch (Exception e) { |
| assertTrue("Unexpected exception " + e.getClass().toString(), |
| e instanceof ResourceHandlerException); |
| } finally { |
| assertTrue("Could not revert writable permission", |
| cpuCgroupMountDir.setWritable(true)); |
| } |
| |
| // Test that a non-accessible mount directory results in an exception |
| if (!cpuCgroupMountDir.equals(mountPoint)) { |
| assertTrue("Could not delete cgroups", cpuCgroupMountDir.delete()); |
| assertTrue("Directory should be deleted", |
| !cpuCgroupMountDir.exists()); |
| } |
| assertTrue(mountPoint.setWritable(false)); |
| try { |
| cGroupsHandler.initializeCGroupController( |
| CGroupsHandler.CGroupController.CPU); |
| Assert.fail("An inaccessible path should result in an exception"); |
| } catch (Exception e) { |
| assertTrue("Unexpected exception " + e.getClass().toString(), |
| e instanceof ResourceHandlerException); |
| } finally { |
| assertTrue("Could not revert writable permission", |
| mountPoint.setWritable(true)); |
| } |
| |
| // Test that a SecurityException results in an exception |
| if (!cpuCgroupMountDir.equals(mountPoint)) { |
| Assert.assertFalse("Could not delete cgroups", |
| cpuCgroupMountDir.delete()); |
| assertTrue("Directory should be deleted", |
| !cpuCgroupMountDir.exists()); |
| SecurityManager manager = System.getSecurityManager(); |
| System.setSecurityManager(new MockSecurityManagerDenyWrite()); |
| try { |
| cGroupsHandler.initializeCGroupController( |
| CGroupsHandler.CGroupController.CPU); |
| Assert.fail("An inaccessible path should result in an exception"); |
| } catch (Exception e) { |
| assertTrue("Unexpected exception " + e.getClass().toString(), |
| e instanceof ResourceHandlerException); |
| } finally { |
| System.setSecurityManager(manager); |
| } |
| } |
| |
| // Test that a non-existing mount directory results in an exception |
| if (!cpuCgroupMountDir.equals(mountPoint)) { |
| Assert.assertFalse("Could not delete cgroups", |
| cpuCgroupMountDir.delete()); |
| assertTrue("Directory should be deleted", |
| !cpuCgroupMountDir.exists()); |
| } |
| FileUtils.deleteQuietly(mountPoint); |
| assertTrue("cgroups mount point should be deleted", |
| !mountPoint.exists()); |
| try { |
| cGroupsHandler.initializeCGroupController( |
| CGroupsHandler.CGroupController.CPU); |
| Assert.fail("An inaccessible path should result in an exception"); |
| } catch (Exception e) { |
| assertTrue("Unexpected exception " + e.getClass().toString(), |
| e instanceof ResourceHandlerException); |
| } |
| } |
| |
| @Test |
| public void testSelectCgroup() throws Exception { |
| File cpu = new File(tmpPath, "cpu"); |
| File cpuNoExist = new File(tmpPath, "cpuNoExist"); |
| File memory = new File(tmpPath, "memory"); |
| try { |
| CGroupsHandlerImpl handler = new CGroupsHandlerImpl( |
| createNoMountConfiguration(tmpPath), |
| privilegedOperationExecutorMock); |
| Map<String, Set<String>> cgroups = new LinkedHashMap<>(); |
| |
| Assert.assertTrue("temp dir should be created", cpu.mkdirs()); |
| Assert.assertTrue("temp dir should be created", memory.mkdirs()); |
| Assert.assertFalse("temp dir should not be created", cpuNoExist.exists()); |
| |
| cgroups.put( |
| memory.getAbsolutePath(), Collections.singleton("memory")); |
| cgroups.put( |
| cpuNoExist.getAbsolutePath(), Collections.singleton("cpu")); |
| cgroups.put(cpu.getAbsolutePath(), Collections.singleton("cpu")); |
| String selectedCPU = handler.findControllerInMtab("cpu", cgroups); |
| Assert.assertEquals("Wrong CPU mount point selected", |
| cpu.getAbsolutePath(), selectedCPU); |
| } finally { |
| FileUtils.deleteQuietly(cpu); |
| FileUtils.deleteQuietly(memory); |
| } |
| } |
| |
| /** |
| * Tests whether mtab parsing works as expected with an empty hierarchy set. |
| * @throws Exception the test will fail |
| */ |
| @Test |
| public void testPreMountedControllerEmpty() throws Exception { |
| testPreMountedControllerInitialization(""); |
| } |
| |
| /** |
| * Tests whether mtab parsing works as expected with a / hierarchy set. |
| * @throws Exception the test will fail |
| */ |
| @Test |
| public void testPreMountedControllerRoot() throws Exception { |
| testPreMountedControllerInitialization("/"); |
| } |
| |
| /** |
| * Tests whether mtab parsing works as expected with the specified hierarchy. |
| * @throws Exception the test will fail |
| */ |
| @Test |
| public void testRemount() |
| throws Exception { |
| // Initialize mount point |
| File parentDir = new File(tmpPath); |
| |
| final String oldMountPointDir = "oldmount"; |
| final String newMountPointDir = "newmount"; |
| |
| File oldMountPoint = new File(parentDir, oldMountPointDir); |
| File mtab = createPremountedCgroups( |
| oldMountPoint, true); |
| |
| File newMountPoint = new File(parentDir, newMountPointDir); |
| assertTrue("Could not create dirs", |
| new File(newMountPoint, "cpu").mkdirs()); |
| |
| // Initialize Yarn classes |
| Configuration confMount = createMountConfiguration(); |
| confMount.set(YarnConfiguration.NM_LINUX_CONTAINER_CGROUPS_MOUNT_PATH, |
| parentDir.getAbsolutePath() + Path.SEPARATOR + newMountPointDir); |
| CGroupsHandlerImpl cGroupsHandler = new CGroupsHandlerImpl(confMount, |
| privilegedOperationExecutorMock, mtab.getAbsolutePath()); |
| |
| cGroupsHandler.initializeCGroupController( |
| CGroupsHandler.CGroupController.CPU); |
| |
| ArgumentCaptor<PrivilegedOperation> opCaptor = ArgumentCaptor.forClass( |
| PrivilegedOperation.class); |
| verify(privilegedOperationExecutorMock) |
| .executePrivilegedOperation(opCaptor.capture(), eq(false)); |
| File hierarchyFile = |
| new File(new File(newMountPoint, "cpu"), this.hierarchy); |
| assertTrue("Yarn cgroup should exist", hierarchyFile.exists()); |
| } |
| |
| |
| @Test |
| public void testManualCgroupSetting() throws ResourceHandlerException { |
| YarnConfiguration conf = new YarnConfiguration(); |
| conf.set(YarnConfiguration.NM_LINUX_CONTAINER_CGROUPS_MOUNT_PATH, tmpPath); |
| conf.set(YarnConfiguration.NM_LINUX_CONTAINER_CGROUPS_HIERARCHY, |
| "/hadoop-yarn"); |
| File cpu = new File(new File(tmpPath, "cpuacct,cpu"), "/hadoop-yarn"); |
| |
| try { |
| Assert.assertTrue("temp dir should be created", cpu.mkdirs()); |
| |
| CGroupsHandlerImpl cGroupsHandler = new CGroupsHandlerImpl(conf, null); |
| cGroupsHandler.initializeCGroupController( |
| CGroupsHandler.CGroupController.CPU); |
| |
| Assert.assertEquals("CPU CGRoup path was not set", cpu.getAbsolutePath(), |
| new File(cGroupsHandler.getPathForCGroup( |
| CGroupsHandler.CGroupController.CPU, "")).getAbsolutePath()); |
| |
| } finally { |
| FileUtils.deleteQuietly(cpu); |
| } |
| } |
| } |