|
@@ -24,23 +24,34 @@ import org.apache.commons.io.FileUtils;
|
|
|
import org.apache.hadoop.conf.Configuration;
|
|
|
import org.apache.hadoop.yarn.conf.YarnConfiguration;
|
|
|
import org.apache.hadoop.yarn.exceptions.YarnException;
|
|
|
+import org.apache.hadoop.yarn.server.nodemanager.containermanager.linux.resources.ResourceHandlerException;
|
|
|
import org.apache.hadoop.yarn.server.nodemanager.containermanager.linux.resources.fpga.FpgaResourceAllocator;
|
|
|
-import org.junit.Assert;
|
|
|
+import org.apache.hadoop.yarn.server.nodemanager.containermanager.linux.resources.fpga.FpgaResourceAllocator.FpgaDevice;
|
|
|
import org.junit.Before;
|
|
|
+import org.junit.Rule;
|
|
|
import org.junit.Test;
|
|
|
+import org.junit.rules.ExpectedException;
|
|
|
|
|
|
import java.io.File;
|
|
|
import java.io.FileOutputStream;
|
|
|
import java.io.IOException;
|
|
|
import java.lang.reflect.Field;
|
|
|
-import java.util.*;
|
|
|
+import java.util.Collections;
|
|
|
+import java.util.HashMap;
|
|
|
+import java.util.LinkedList;
|
|
|
+import java.util.List;
|
|
|
+import java.util.Map;
|
|
|
+import java.util.Optional;
|
|
|
|
|
|
+import static org.junit.Assert.assertEquals;
|
|
|
import static org.mockito.ArgumentMatchers.anyInt;
|
|
|
import static org.mockito.ArgumentMatchers.anyString;
|
|
|
import static org.mockito.Mockito.mock;
|
|
|
import static org.mockito.Mockito.when;
|
|
|
|
|
|
public class TestFpgaDiscoverer {
|
|
|
+ @Rule
|
|
|
+ public ExpectedException expected = ExpectedException.none();
|
|
|
|
|
|
private String getTestParentFolder() {
|
|
|
File f = new File("target/temp/" + TestFpgaDiscoverer.class.getName());
|
|
@@ -57,6 +68,7 @@ public class TestFpgaDiscoverer {
|
|
|
File f = new File(folder);
|
|
|
FileUtils.deleteDirectory(f);
|
|
|
f.mkdirs();
|
|
|
+ FpgaDiscoverer.reset();
|
|
|
}
|
|
|
|
|
|
// A dirty hack to modify the env of the current JVM itself - Dirty, but
|
|
@@ -106,7 +118,7 @@ public class TestFpgaDiscoverer {
|
|
|
|
|
|
discoverer.initialize(conf);
|
|
|
// Case 1. No configuration set for binary(no environment "ALTERAOCLSDKROOT" set)
|
|
|
- Assert.assertEquals("No configuration(no environment ALTERAOCLSDKROOT set)" +
|
|
|
+ assertEquals("No configuration(no environment ALTERAOCLSDKROOT set)" +
|
|
|
"should return just a single binary name",
|
|
|
"aocl", openclPlugin.getPathToExecutable());
|
|
|
|
|
@@ -115,19 +127,19 @@ public class TestFpgaDiscoverer {
|
|
|
conf.set(YarnConfiguration.NM_FPGA_PATH_TO_EXEC, getTestParentFolder() + "/aocl");
|
|
|
touchFile(fakeBinary);
|
|
|
discoverer.initialize(conf);
|
|
|
- Assert.assertEquals("Correct configuration should return user setting",
|
|
|
+ assertEquals("Correct configuration should return user setting",
|
|
|
getTestParentFolder() + "/aocl", openclPlugin.getPathToExecutable());
|
|
|
|
|
|
// Case 3. With correct configuration but file doesn't exists. Use default
|
|
|
fakeBinary.delete();
|
|
|
discoverer.initialize(conf);
|
|
|
- Assert.assertEquals("Correct configuration but file doesn't exists should return just a single binary name",
|
|
|
+ assertEquals("Should return just a single binary name",
|
|
|
"aocl", openclPlugin.getPathToExecutable());
|
|
|
|
|
|
// Case 4. Set a empty value
|
|
|
conf.set(YarnConfiguration.NM_FPGA_PATH_TO_EXEC, "");
|
|
|
discoverer.initialize(conf);
|
|
|
- Assert.assertEquals("configuration with empty string value, should use aocl",
|
|
|
+ assertEquals("configuration with empty string value, should use aocl",
|
|
|
"aocl", openclPlugin.getPathToExecutable());
|
|
|
|
|
|
// Case 5. No configuration set for binary, but set environment "ALTERAOCLSDKROOT"
|
|
@@ -140,7 +152,7 @@ public class TestFpgaDiscoverer {
|
|
|
newEnv.put("ALTERAOCLSDKROOT", getTestParentFolder());
|
|
|
setNewEnvironmentHack(newEnv);
|
|
|
discoverer.initialize(conf);
|
|
|
- Assert.assertEquals("No configuration but with environment ALTERAOCLSDKROOT set",
|
|
|
+ assertEquals("No configuration but with environment ALTERAOCLSDKROOT set",
|
|
|
getTestParentFolder() + "/bin/aocl", openclPlugin.getPathToExecutable());
|
|
|
|
|
|
}
|
|
@@ -193,39 +205,229 @@ public class TestFpgaDiscoverer {
|
|
|
|
|
|
// Case 1. core parsing
|
|
|
openclPlugin.parseDiagnoseInfo(output, list);
|
|
|
- Assert.assertEquals(3, list.size());
|
|
|
- Assert.assertEquals("IntelOpenCL", list.get(0).getType());
|
|
|
- Assert.assertEquals("247", list.get(0).getMajor().toString());
|
|
|
- Assert.assertEquals("0", list.get(0).getMinor().toString());
|
|
|
- Assert.assertEquals("acl0", list.get(0).getAliasDevName());
|
|
|
- Assert.assertEquals("aclnalla_pcie0", list.get(0).getDevName());
|
|
|
- Assert.assertEquals("02:00.00", list.get(0).getBusNum());
|
|
|
- Assert.assertEquals("53.1 degrees C", list.get(0).getTemperature());
|
|
|
- Assert.assertEquals("31.7 Watts", list.get(0).getCardPowerUsage());
|
|
|
-
|
|
|
- Assert.assertEquals("IntelOpenCL", list.get(1).getType());
|
|
|
- Assert.assertEquals("247", list.get(1).getMajor().toString());
|
|
|
- Assert.assertEquals("1", list.get(1).getMinor().toString());
|
|
|
- Assert.assertEquals("acl1", list.get(1).getAliasDevName());
|
|
|
- Assert.assertEquals("aclnalla_pcie1", list.get(1).getDevName());
|
|
|
- Assert.assertEquals("03:00.00", list.get(1).getBusNum());
|
|
|
- Assert.assertEquals("43.1 degrees C", list.get(1).getTemperature());
|
|
|
- Assert.assertEquals("11.7 Watts", list.get(1).getCardPowerUsage());
|
|
|
-
|
|
|
- Assert.assertEquals("IntelOpenCL", list.get(2).getType());
|
|
|
- Assert.assertEquals("246", list.get(2).getMajor().toString());
|
|
|
- Assert.assertEquals("0", list.get(2).getMinor().toString());
|
|
|
- Assert.assertEquals("acl2", list.get(2).getAliasDevName());
|
|
|
- Assert.assertEquals("acla10_ref0", list.get(2).getDevName());
|
|
|
- Assert.assertEquals("09:00.00", list.get(2).getBusNum());
|
|
|
- Assert.assertEquals("50.5781 degrees C", list.get(2).getTemperature());
|
|
|
- Assert.assertEquals("", list.get(2).getCardPowerUsage());
|
|
|
+ assertEquals(3, list.size());
|
|
|
+ assertEquals("IntelOpenCL", list.get(0).getType());
|
|
|
+ assertEquals("247", list.get(0).getMajor().toString());
|
|
|
+ assertEquals("0", list.get(0).getMinor().toString());
|
|
|
+ assertEquals("acl0", list.get(0).getAliasDevName());
|
|
|
+ assertEquals("aclnalla_pcie0", list.get(0).getDevName());
|
|
|
+ assertEquals("02:00.00", list.get(0).getBusNum());
|
|
|
+ assertEquals("53.1 degrees C", list.get(0).getTemperature());
|
|
|
+ assertEquals("31.7 Watts", list.get(0).getCardPowerUsage());
|
|
|
+
|
|
|
+ assertEquals("IntelOpenCL", list.get(1).getType());
|
|
|
+ assertEquals("247", list.get(1).getMajor().toString());
|
|
|
+ assertEquals("1", list.get(1).getMinor().toString());
|
|
|
+ assertEquals("acl1", list.get(1).getAliasDevName());
|
|
|
+ assertEquals("aclnalla_pcie1", list.get(1).getDevName());
|
|
|
+ assertEquals("03:00.00", list.get(1).getBusNum());
|
|
|
+ assertEquals("43.1 degrees C", list.get(1).getTemperature());
|
|
|
+ assertEquals("11.7 Watts", list.get(1).getCardPowerUsage());
|
|
|
+
|
|
|
+ assertEquals("IntelOpenCL", list.get(2).getType());
|
|
|
+ assertEquals("246", list.get(2).getMajor().toString());
|
|
|
+ assertEquals("0", list.get(2).getMinor().toString());
|
|
|
+ assertEquals("acl2", list.get(2).getAliasDevName());
|
|
|
+ assertEquals("acla10_ref0", list.get(2).getDevName());
|
|
|
+ assertEquals("09:00.00", list.get(2).getBusNum());
|
|
|
+ assertEquals("50.5781 degrees C", list.get(2).getTemperature());
|
|
|
+ assertEquals("", list.get(2).getCardPowerUsage());
|
|
|
|
|
|
// Case 2. check alias map
|
|
|
Map<String, String> aliasMap = openclPlugin.getAliasMap();
|
|
|
- Assert.assertEquals("acl0", aliasMap.get("247:0"));
|
|
|
- Assert.assertEquals("acl1", aliasMap.get("247:1"));
|
|
|
- Assert.assertEquals("acl2", aliasMap.get("246:0"));
|
|
|
+ assertEquals("acl0", aliasMap.get("247:0"));
|
|
|
+ assertEquals("acl1", aliasMap.get("247:1"));
|
|
|
+ assertEquals("acl2", aliasMap.get("246:0"));
|
|
|
+ }
|
|
|
+
|
|
|
+ @Test
|
|
|
+ public void testDiscoveryWhenAvailableDevicesDefined()
|
|
|
+ throws YarnException {
|
|
|
+ Configuration conf = new Configuration(false);
|
|
|
+ conf.set(YarnConfiguration.NM_FPGA_AVAILABLE_DEVICES,
|
|
|
+ "acl0/243:0,acl1/244:1");
|
|
|
+ FpgaDiscoverer discoverer = FpgaDiscoverer.getInstance();
|
|
|
+
|
|
|
+ IntelFpgaOpenclPlugin openclPlugin = new IntelFpgaOpenclPlugin();
|
|
|
+ discoverer.setResourceHanderPlugin(openclPlugin);
|
|
|
+ openclPlugin.initPlugin(conf);
|
|
|
+ openclPlugin.setShell(mockPuginShell());
|
|
|
+
|
|
|
+ discoverer.initialize(conf);
|
|
|
+ List<FpgaDevice> devices = discoverer.discover();
|
|
|
+ assertEquals("Number of devices", 2, devices.size());
|
|
|
+ FpgaDevice device0 = devices.get(0);
|
|
|
+ FpgaDevice device1 = devices.get(1);
|
|
|
+
|
|
|
+ assertEquals("Device id", "acl0", device0.getAliasDevName());
|
|
|
+ assertEquals("Minor number", new Integer(0), device0.getMinor());
|
|
|
+ assertEquals("Major", new Integer(243), device0.getMajor());
|
|
|
+
|
|
|
+ assertEquals("Device id", "acl1", device1.getAliasDevName());
|
|
|
+ assertEquals("Minor number", new Integer(1), device1.getMinor());
|
|
|
+ assertEquals("Major", new Integer(244), device1.getMajor());
|
|
|
+ }
|
|
|
+
|
|
|
+ @Test
|
|
|
+ public void testDiscoveryWhenAvailableDevicesEmpty()
|
|
|
+ throws YarnException {
|
|
|
+ expected.expect(ResourceHandlerException.class);
|
|
|
+ expected.expectMessage("No FPGA devices were specified");
|
|
|
+
|
|
|
+ Configuration conf = new Configuration(false);
|
|
|
+ conf.set(YarnConfiguration.NM_FPGA_AVAILABLE_DEVICES,
|
|
|
+ "");
|
|
|
+ FpgaDiscoverer discoverer = FpgaDiscoverer.getInstance();
|
|
|
+
|
|
|
+ IntelFpgaOpenclPlugin openclPlugin = new IntelFpgaOpenclPlugin();
|
|
|
+ discoverer.setResourceHanderPlugin(openclPlugin);
|
|
|
+ openclPlugin.initPlugin(conf);
|
|
|
+ openclPlugin.setShell(mockPuginShell());
|
|
|
+
|
|
|
+ discoverer.initialize(conf);
|
|
|
+ discoverer.discover();
|
|
|
+ }
|
|
|
+
|
|
|
+ @Test
|
|
|
+ public void testDiscoveryWhenAvailableDevicesAreIllegalString()
|
|
|
+ throws YarnException {
|
|
|
+ expected.expect(ResourceHandlerException.class);
|
|
|
+ expected.expectMessage("Illegal device specification string");
|
|
|
+
|
|
|
+ Configuration conf = new Configuration(false);
|
|
|
+ conf.set(YarnConfiguration.NM_FPGA_AVAILABLE_DEVICES,
|
|
|
+ "illegal/243:0,acl1/244=1");
|
|
|
+ FpgaDiscoverer discoverer = FpgaDiscoverer.getInstance();
|
|
|
+
|
|
|
+ IntelFpgaOpenclPlugin openclPlugin = new IntelFpgaOpenclPlugin();
|
|
|
+ discoverer.setResourceHanderPlugin(openclPlugin);
|
|
|
+ openclPlugin.initPlugin(conf);
|
|
|
+ openclPlugin.setShell(mockPuginShell());
|
|
|
+
|
|
|
+ discoverer.initialize(conf);
|
|
|
+ discoverer.discover();
|
|
|
+ }
|
|
|
+
|
|
|
+ @Test
|
|
|
+ public void testDiscoveryWhenExternalScriptDefined()
|
|
|
+ throws YarnException {
|
|
|
+ Configuration conf = new Configuration(false);
|
|
|
+ conf.set(YarnConfiguration.NM_FPGA_DEVICE_DISCOVERY_SCRIPT,
|
|
|
+ "/dummy/script");
|
|
|
+ FpgaDiscoverer discoverer = FpgaDiscoverer.getInstance();
|
|
|
+
|
|
|
+ IntelFpgaOpenclPlugin openclPlugin = new IntelFpgaOpenclPlugin();
|
|
|
+ discoverer.setResourceHanderPlugin(openclPlugin);
|
|
|
+ openclPlugin.initPlugin(conf);
|
|
|
+ openclPlugin.setShell(mockPuginShell());
|
|
|
+ discoverer.setScriptRunner(s -> {
|
|
|
+ return Optional.of("acl0/243:0,acl1/244:1"); });
|
|
|
+
|
|
|
+ discoverer.initialize(conf);
|
|
|
+ List<FpgaDevice> devices = discoverer.discover();
|
|
|
+ assertEquals("Number of devices", 2, devices.size());
|
|
|
+ FpgaDevice device0 = devices.get(0);
|
|
|
+ FpgaDevice device1 = devices.get(1);
|
|
|
+
|
|
|
+ assertEquals("Device id", "acl0", device0.getAliasDevName());
|
|
|
+ assertEquals("Minor number", new Integer(0), device0.getMinor());
|
|
|
+ assertEquals("Major", new Integer(243), device0.getMajor());
|
|
|
+
|
|
|
+ assertEquals("Device id", "acl1", device1.getAliasDevName());
|
|
|
+ assertEquals("Minor number", new Integer(1), device1.getMinor());
|
|
|
+ assertEquals("Major", new Integer(244), device1.getMajor());
|
|
|
+ }
|
|
|
+
|
|
|
+ @Test
|
|
|
+ public void testDiscoveryWhenExternalScriptReturnsEmptyString()
|
|
|
+ throws YarnException {
|
|
|
+ expected.expect(ResourceHandlerException.class);
|
|
|
+ expected.expectMessage("No FPGA devices were specified");
|
|
|
+
|
|
|
+ Configuration conf = new Configuration(false);
|
|
|
+ conf.set(YarnConfiguration.NM_FPGA_DEVICE_DISCOVERY_SCRIPT,
|
|
|
+ "/dummy/script");
|
|
|
+ FpgaDiscoverer discoverer = FpgaDiscoverer.getInstance();
|
|
|
+
|
|
|
+ IntelFpgaOpenclPlugin openclPlugin = new IntelFpgaOpenclPlugin();
|
|
|
+ discoverer.setResourceHanderPlugin(openclPlugin);
|
|
|
+ openclPlugin.initPlugin(conf);
|
|
|
+ openclPlugin.setShell(mockPuginShell());
|
|
|
+ discoverer.setScriptRunner(s -> {
|
|
|
+ return Optional.of(""); });
|
|
|
+
|
|
|
+ discoverer.initialize(conf);
|
|
|
+ discoverer.discover();
|
|
|
+ }
|
|
|
+
|
|
|
+ @Test
|
|
|
+
|
|
|
+ public void testDiscoveryWhenExternalScriptFails()
|
|
|
+ throws YarnException {
|
|
|
+ expected.expect(ResourceHandlerException.class);
|
|
|
+ expected.expectMessage("Unable to run external script");
|
|
|
+
|
|
|
+ Configuration conf = new Configuration(false);
|
|
|
+ conf.set(YarnConfiguration.NM_FPGA_DEVICE_DISCOVERY_SCRIPT,
|
|
|
+ "/dummy/script");
|
|
|
+ FpgaDiscoverer discoverer = FpgaDiscoverer.getInstance();
|
|
|
+
|
|
|
+ IntelFpgaOpenclPlugin openclPlugin = new IntelFpgaOpenclPlugin();
|
|
|
+ discoverer.setResourceHanderPlugin(openclPlugin);
|
|
|
+ openclPlugin.initPlugin(conf);
|
|
|
+ openclPlugin.setShell(mockPuginShell());
|
|
|
+ discoverer.setScriptRunner(s -> {
|
|
|
+ return Optional.empty(); });
|
|
|
+
|
|
|
+ discoverer.initialize(conf);
|
|
|
+ discoverer.discover();
|
|
|
+ }
|
|
|
+
|
|
|
+ @Test
|
|
|
+ public void testDiscoveryWhenExternalScriptUndefined()
|
|
|
+ throws YarnException {
|
|
|
+ expected.expect(ResourceHandlerException.class);
|
|
|
+ expected.expectMessage("Unable to run external script");
|
|
|
+
|
|
|
+ Configuration conf = new Configuration(false);
|
|
|
+ conf.set(YarnConfiguration.NM_FPGA_DEVICE_DISCOVERY_SCRIPT, "");
|
|
|
+ FpgaDiscoverer discoverer = FpgaDiscoverer.getInstance();
|
|
|
+
|
|
|
+ IntelFpgaOpenclPlugin openclPlugin = new IntelFpgaOpenclPlugin();
|
|
|
+ discoverer.setResourceHanderPlugin(openclPlugin);
|
|
|
+ openclPlugin.initPlugin(conf);
|
|
|
+ openclPlugin.setShell(mockPuginShell());
|
|
|
+
|
|
|
+ discoverer.initialize(conf);
|
|
|
+ discoverer.discover();
|
|
|
+ }
|
|
|
+
|
|
|
+ @Test
|
|
|
+ public void testDiscoveryWhenExternalScriptCannotBeExecuted()
|
|
|
+ throws YarnException, IOException {
|
|
|
+ File fakeScript = new File(getTestParentFolder() + "/fakeScript");
|
|
|
+ try {
|
|
|
+ expected.expect(ResourceHandlerException.class);
|
|
|
+ expected.expectMessage("Unable to run external script");
|
|
|
+
|
|
|
+ Configuration conf = new Configuration(false);
|
|
|
+ fakeScript = new File(getTestParentFolder() + "/fakeScript");
|
|
|
+ touchFile(fakeScript);
|
|
|
+ fakeScript.setExecutable(false);
|
|
|
+ conf.set(YarnConfiguration.NM_FPGA_DEVICE_DISCOVERY_SCRIPT,
|
|
|
+ fakeScript.getAbsolutePath());
|
|
|
+ FpgaDiscoverer discoverer = FpgaDiscoverer.getInstance();
|
|
|
+
|
|
|
+ IntelFpgaOpenclPlugin openclPlugin = new IntelFpgaOpenclPlugin();
|
|
|
+ discoverer.setResourceHanderPlugin(openclPlugin);
|
|
|
+ openclPlugin.initPlugin(conf);
|
|
|
+ openclPlugin.setShell(mockPuginShell());
|
|
|
+
|
|
|
+ discoverer.initialize(conf);
|
|
|
+ discoverer.discover();
|
|
|
+ } finally {
|
|
|
+ fakeScript.delete();
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
private IntelFpgaOpenclPlugin.InnerShellExecutor mockPuginShell() {
|