|
@@ -34,6 +34,7 @@ import org.apache.hadoop.yarn.server.nodemanager.NodeHealthCheckerService;
|
|
|
import org.apache.hadoop.yarn.server.nodemanager.NodeManager;
|
|
|
import org.apache.hadoop.yarn.server.nodemanager.NodeManagerTestBase;
|
|
|
import org.apache.hadoop.yarn.server.nodemanager.NodeStatusUpdater;
|
|
|
+import org.apache.hadoop.yarn.server.nodemanager.api.deviceplugin.DevicePlugin;
|
|
|
import org.apache.hadoop.yarn.server.nodemanager.containermanager.ContainerManagerImpl;
|
|
|
import org.apache.hadoop.yarn.server.nodemanager.containermanager.container.Container;
|
|
|
import org.apache.hadoop.yarn.server.nodemanager.containermanager.linux.privileged.PrivilegedOperation;
|
|
@@ -42,7 +43,10 @@ import org.apache.hadoop.yarn.server.nodemanager.containermanager.linux.resource
|
|
|
import org.apache.hadoop.yarn.server.nodemanager.containermanager.linux.resources.ResourceHandler;
|
|
|
import org.apache.hadoop.yarn.server.nodemanager.containermanager.linux.resources.ResourceHandlerChain;
|
|
|
import org.apache.hadoop.yarn.server.nodemanager.containermanager.linux.resources.ResourceHandlerException;
|
|
|
+import org.apache.hadoop.yarn.server.nodemanager.containermanager.resourceplugin.deviceframework.*;
|
|
|
import org.apache.hadoop.yarn.server.security.ApplicationACLsManager;
|
|
|
+import org.apache.hadoop.yarn.util.resource.ResourceUtils;
|
|
|
+import org.apache.hadoop.yarn.util.resource.TestResourceUtils;
|
|
|
import org.junit.After;
|
|
|
import org.junit.Assert;
|
|
|
import org.junit.Before;
|
|
@@ -51,6 +55,7 @@ import org.junit.Test;
|
|
|
import java.util.HashMap;
|
|
|
import java.util.List;
|
|
|
import java.util.Map;
|
|
|
+import java.io.File;
|
|
|
|
|
|
import static org.mockito.Matchers.any;
|
|
|
import static org.mockito.Mockito.mock;
|
|
@@ -64,9 +69,16 @@ public class TestResourcePluginManager extends NodeManagerTestBase {
|
|
|
|
|
|
private YarnConfiguration conf;
|
|
|
|
|
|
+ private String tempResourceTypesFile;
|
|
|
+
|
|
|
@Before
|
|
|
public void setup() throws Exception {
|
|
|
this.conf = createNMConfig();
|
|
|
+ // setup resource-types.xml
|
|
|
+ ResourceUtils.resetResourceTypes();
|
|
|
+ String resourceTypesFile = "resource-types-pluggable-devices.xml";
|
|
|
+ this.tempResourceTypesFile =
|
|
|
+ TestResourceUtils.setupResourceTypes(this.conf, resourceTypesFile);
|
|
|
}
|
|
|
|
|
|
ResourcePluginManager stubResourcePluginmanager() {
|
|
@@ -101,6 +113,11 @@ public class TestResourcePluginManager extends NodeManagerTestBase {
|
|
|
// ignore
|
|
|
}
|
|
|
}
|
|
|
+ // cleanup resource-types.xml
|
|
|
+ File dest = new File(this.tempResourceTypesFile);
|
|
|
+ if (dest.exists()) {
|
|
|
+ dest.delete();
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
private class CustomizedResourceHandler implements ResourceHandler {
|
|
@@ -153,8 +170,8 @@ public class TestResourcePluginManager extends NodeManagerTestBase {
|
|
|
protected NodeStatusUpdater createNodeStatusUpdater(Context context,
|
|
|
Dispatcher dispatcher, NodeHealthCheckerService healthChecker) {
|
|
|
((NodeManager.NMContext)context).setResourcePluginManager(rpm);
|
|
|
- return new BaseNodeStatusUpdaterForTest(context, dispatcher, healthChecker,
|
|
|
- metrics, new BaseResourceTrackerForTest());
|
|
|
+ return new BaseNodeStatusUpdaterForTest(context, dispatcher,
|
|
|
+ healthChecker, metrics, new BaseResourceTrackerForTest());
|
|
|
}
|
|
|
|
|
|
@Override
|
|
@@ -174,7 +191,8 @@ public class TestResourcePluginManager extends NodeManagerTestBase {
|
|
|
}
|
|
|
|
|
|
public class MyLCE extends LinuxContainerExecutor {
|
|
|
- private PrivilegedOperationExecutor poe = mock(PrivilegedOperationExecutor.class);
|
|
|
+ private PrivilegedOperationExecutor poe =
|
|
|
+ mock(PrivilegedOperationExecutor.class);
|
|
|
|
|
|
@Override
|
|
|
protected PrivilegedOperationExecutor getPrivilegedOperationExecutor() {
|
|
@@ -199,7 +217,8 @@ public class TestResourcePluginManager extends NodeManagerTestBase {
|
|
|
* Make sure ResourcePluginManager is invoked during NM update.
|
|
|
*/
|
|
|
@Test(timeout = 30000)
|
|
|
- public void testNodeStatusUpdaterWithResourcePluginsEnabled() throws Exception {
|
|
|
+ public void testNodeStatusUpdaterWithResourcePluginsEnabled()
|
|
|
+ throws Exception {
|
|
|
final ResourcePluginManager rpm = stubResourcePluginmanager();
|
|
|
|
|
|
nm = new MyMockNM(rpm);
|
|
@@ -211,15 +230,16 @@ public class TestResourcePluginManager extends NodeManagerTestBase {
|
|
|
rpm.getNameToPlugins().get("resource1")
|
|
|
.getNodeResourceHandlerInstance();
|
|
|
|
|
|
- verify(nodeResourceUpdaterPlugin, times(1)).updateConfiguredResource(
|
|
|
- any(Resource.class));
|
|
|
+ verify(nodeResourceUpdaterPlugin, times(1))
|
|
|
+ .updateConfiguredResource(any(Resource.class));
|
|
|
}
|
|
|
|
|
|
/*
|
|
|
* Make sure ResourcePluginManager is used to initialize ResourceHandlerChain
|
|
|
*/
|
|
|
@Test(timeout = 30000)
|
|
|
- public void testLinuxContainerExecutorWithResourcePluginsEnabled() throws Exception {
|
|
|
+ public void testLinuxContainerExecutorWithResourcePluginsEnabled()
|
|
|
+ throws Exception {
|
|
|
final ResourcePluginManager rpm = stubResourcePluginmanager();
|
|
|
final LinuxContainerExecutor lce = new MyLCE();
|
|
|
|
|
@@ -261,6 +281,9 @@ public class TestResourcePluginManager extends NodeManagerTestBase {
|
|
|
boolean newHandlerAdded = false;
|
|
|
for (ResourceHandler h : ((ResourceHandlerChain) handler)
|
|
|
.getResourceHandlerList()) {
|
|
|
+ if (h instanceof DevicePluginAdapter) {
|
|
|
+ Assert.assertTrue(false);
|
|
|
+ }
|
|
|
if (h instanceof CustomizedResourceHandler) {
|
|
|
newHandlerAdded = true;
|
|
|
break;
|
|
@@ -320,7 +343,7 @@ public class TestResourcePluginManager extends NodeManagerTestBase {
|
|
|
true);
|
|
|
conf.setStrings(
|
|
|
YarnConfiguration.NM_PLUGGABLE_DEVICE_FRAMEWORK_DEVICE_CLASSES,
|
|
|
- "com.cmp1.hdw1plugin");
|
|
|
+ FakeTestDevicePlugin1.class.getCanonicalName());
|
|
|
nm.init(conf);
|
|
|
nm.start();
|
|
|
verify(rpmSpy, times(1)).initialize(
|
|
@@ -332,7 +355,8 @@ public class TestResourcePluginManager extends NodeManagerTestBase {
|
|
|
// Enable pluggable framework, but leave device classes un-configured
|
|
|
// initializePluggableDevicePlugins invoked but it should throw an exception
|
|
|
@Test(timeout = 30000)
|
|
|
- public void testInitializationWithPluggableDeviceFrameworkEnabled2() {
|
|
|
+ public void testInitializationWithPluggableDeviceFrameworkEnabled2()
|
|
|
+ throws ClassNotFoundException {
|
|
|
ResourcePluginManager rpm = new ResourcePluginManager();
|
|
|
|
|
|
ResourcePluginManager rpmSpy = spy(rpm);
|
|
@@ -353,4 +377,131 @@ public class TestResourcePluginManager extends NodeManagerTestBase {
|
|
|
any(Context.class), any(Configuration.class), any(Map.class));
|
|
|
Assert.assertTrue(fail);
|
|
|
}
|
|
|
+
|
|
|
+ @Test(timeout = 30000)
|
|
|
+ public void testNormalInitializationOfPluggableDeviceClasses()
|
|
|
+ throws Exception {
|
|
|
+
|
|
|
+ ResourcePluginManager rpm = new ResourcePluginManager();
|
|
|
+
|
|
|
+ ResourcePluginManager rpmSpy = spy(rpm);
|
|
|
+ nm = new MyMockNM(rpmSpy);
|
|
|
+
|
|
|
+ conf.setBoolean(YarnConfiguration.NM_PLUGGABLE_DEVICE_FRAMEWORK_ENABLED,
|
|
|
+ true);
|
|
|
+ conf.setStrings(
|
|
|
+ YarnConfiguration.NM_PLUGGABLE_DEVICE_FRAMEWORK_DEVICE_CLASSES,
|
|
|
+ FakeTestDevicePlugin1.class.getCanonicalName());
|
|
|
+ nm.init(conf);
|
|
|
+ nm.start();
|
|
|
+ Map<String, ResourcePlugin> pluginMap = rpmSpy.getNameToPlugins();
|
|
|
+ Assert.assertEquals(1, pluginMap.size());
|
|
|
+ ResourcePlugin rp = pluginMap.get("cmpA.com/hdwA");
|
|
|
+ if (!(rp instanceof DevicePluginAdapter)) {
|
|
|
+ Assert.assertTrue(false);
|
|
|
+ }
|
|
|
+ verify(rpmSpy, times(1)).checkInterfaceCompatibility(
|
|
|
+ DevicePlugin.class, FakeTestDevicePlugin1.class);
|
|
|
+ }
|
|
|
+
|
|
|
+ // Fail to load a class which doesn't implement interface DevicePlugin
|
|
|
+ @Test(timeout = 30000)
|
|
|
+ public void testLoadInvalidPluggableDeviceClasses()
|
|
|
+ throws Exception{
|
|
|
+ ResourcePluginManager rpm = new ResourcePluginManager();
|
|
|
+
|
|
|
+ ResourcePluginManager rpmSpy = spy(rpm);
|
|
|
+ nm = new MyMockNM(rpmSpy);
|
|
|
+
|
|
|
+ conf.setBoolean(YarnConfiguration.NM_PLUGGABLE_DEVICE_FRAMEWORK_ENABLED,
|
|
|
+ true);
|
|
|
+ conf.setStrings(
|
|
|
+ YarnConfiguration.NM_PLUGGABLE_DEVICE_FRAMEWORK_DEVICE_CLASSES,
|
|
|
+ FakeTestDevicePlugin2.class.getCanonicalName());
|
|
|
+
|
|
|
+ String expectedMessage = "Class: "
|
|
|
+ + FakeTestDevicePlugin2.class.getCanonicalName()
|
|
|
+ + " not instance of " + DevicePlugin.class.getCanonicalName();
|
|
|
+ String actualMessage = "";
|
|
|
+ try {
|
|
|
+ nm.init(conf);
|
|
|
+ nm.start();
|
|
|
+ } catch (YarnRuntimeException e) {
|
|
|
+ actualMessage = e.getMessage();
|
|
|
+ }
|
|
|
+ Assert.assertEquals(expectedMessage, actualMessage);
|
|
|
+ }
|
|
|
+
|
|
|
+ // Fail to register duplicated resource name.
|
|
|
+ @Test(timeout = 30000)
|
|
|
+ public void testLoadDuplicateResourceNameDevicePlugin()
|
|
|
+ throws Exception{
|
|
|
+ ResourcePluginManager rpm = new ResourcePluginManager();
|
|
|
+
|
|
|
+ ResourcePluginManager rpmSpy = spy(rpm);
|
|
|
+ nm = new MyMockNM(rpmSpy);
|
|
|
+
|
|
|
+ conf.setBoolean(YarnConfiguration.NM_PLUGGABLE_DEVICE_FRAMEWORK_ENABLED,
|
|
|
+ true);
|
|
|
+ conf.setStrings(
|
|
|
+ YarnConfiguration.NM_PLUGGABLE_DEVICE_FRAMEWORK_DEVICE_CLASSES,
|
|
|
+ FakeTestDevicePlugin1.class.getCanonicalName() + "," +
|
|
|
+ FakeTestDevicePlugin3.class.getCanonicalName());
|
|
|
+
|
|
|
+ String expectedMessage = "cmpA.com/hdwA" +
|
|
|
+ " already registered! Please change resource type name"
|
|
|
+ + " or configure correct resource type name"
|
|
|
+ + " in resource-types.xml for "
|
|
|
+ + FakeTestDevicePlugin3.class.getCanonicalName();
|
|
|
+ String actualMessage = "";
|
|
|
+ try {
|
|
|
+ nm.init(conf);
|
|
|
+ nm.start();
|
|
|
+ } catch (YarnRuntimeException e) {
|
|
|
+ actualMessage = e.getMessage();
|
|
|
+ }
|
|
|
+ Assert.assertEquals(expectedMessage, actualMessage);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Fail a plugin due to incompatible interface implemented.
|
|
|
+ * It doesn't implement the "getRegisterRequestInfo"
|
|
|
+ */
|
|
|
+ @Test(timeout = 30000)
|
|
|
+ public void testIncompatibleDevicePlugin()
|
|
|
+ throws Exception {
|
|
|
+ ResourcePluginManager rpm = new ResourcePluginManager();
|
|
|
+
|
|
|
+ ResourcePluginManager rpmSpy = spy(rpm);
|
|
|
+ nm = new MyMockNM(rpmSpy);
|
|
|
+
|
|
|
+ conf.setBoolean(YarnConfiguration.NM_PLUGGABLE_DEVICE_FRAMEWORK_ENABLED,
|
|
|
+ true);
|
|
|
+ conf.setStrings(
|
|
|
+ YarnConfiguration.NM_PLUGGABLE_DEVICE_FRAMEWORK_DEVICE_CLASSES,
|
|
|
+ FakeTestDevicePlugin4.class.getCanonicalName());
|
|
|
+
|
|
|
+ String expectedMessage = "Method getRegisterRequestInfo" +
|
|
|
+ " is expected but not implemented in "
|
|
|
+ + FakeTestDevicePlugin4.class.getCanonicalName();
|
|
|
+ String actualMessage = "";
|
|
|
+ try {
|
|
|
+ nm.init(conf);
|
|
|
+ nm.start();
|
|
|
+ } catch (YarnRuntimeException e) {
|
|
|
+ actualMessage = e.getMessage();
|
|
|
+ }
|
|
|
+ Assert.assertEquals(expectedMessage, actualMessage);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Test(timeout = 30000)
|
|
|
+ public void testRequestedResourceNameIsConfigured()
|
|
|
+ throws Exception{
|
|
|
+ ResourcePluginManager rpm = new ResourcePluginManager();
|
|
|
+ String resourceName = "a.com/a";
|
|
|
+ Assert.assertFalse(rpm.isConfiguredResourceName(resourceName));
|
|
|
+ resourceName = "cmp.com/cmp";
|
|
|
+ Assert.assertTrue(rpm.isConfiguredResourceName(resourceName));
|
|
|
+ }
|
|
|
+
|
|
|
}
|