/*********************************************************************************************************************** * Copyright (C) 2010-2013 by the Stratosphere project (http://stratosphere.eu) * * Licensed 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 eu.stratosphere.nephele.instance.cluster; import static org.junit.Assert.assertEquals; import static org.junit.Assert.fail; import java.net.InetAddress; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; import org.junit.Assert; import org.junit.BeforeClass; import org.junit.Test; import eu.stratosphere.configuration.ConfigConstants; import eu.stratosphere.configuration.Configuration; import eu.stratosphere.configuration.GlobalConfiguration; import eu.stratosphere.nephele.instance.AllocatedResource; import eu.stratosphere.nephele.instance.AllocationID; import eu.stratosphere.nephele.instance.HardwareDescription; import eu.stratosphere.nephele.instance.HardwareDescriptionFactory; import eu.stratosphere.nephele.instance.InstanceConnectionInfo; import eu.stratosphere.nephele.instance.InstanceException; import eu.stratosphere.nephele.instance.InstanceRequestMap; import eu.stratosphere.nephele.instance.InstanceType; import eu.stratosphere.nephele.instance.InstanceTypeDescription; import eu.stratosphere.nephele.jobgraph.JobID; import eu.stratosphere.util.LogUtils; /** * Tests for {@link ClusterManager}. */ public class ClusterManagerTest { @BeforeClass public static void initLogging() { LogUtils.initializeDefaultTestConsoleLogger(); } @Test public void testInstanceRegistering() { try { ClusterManager cm = new ClusterManager(); TestInstanceListener testInstanceListener = new TestInstanceListener(); cm.setInstanceListener(testInstanceListener); int ipcPort = ConfigConstants.DEFAULT_TASK_MANAGER_IPC_PORT; int dataPort = ConfigConstants.DEFAULT_TASK_MANAGER_DATA_PORT; HardwareDescription hardwareDescription = HardwareDescriptionFactory.construct(2, 2L * 1024L * 1024L * 1024L, 2L * 1024L * 1024L * 1024L); String hostname = "192.168.198.1"; InetAddress address = InetAddress.getByName("192.168.198.1"); InstanceConnectionInfo ici1 = new InstanceConnectionInfo(address, hostname, null, ipcPort + 0, dataPort + 0); InstanceConnectionInfo ici2 = new InstanceConnectionInfo(address, hostname, null, ipcPort + 15, dataPort + 15); InstanceConnectionInfo ici3 = new InstanceConnectionInfo(address, hostname, null, ipcPort + 30, dataPort + 30); // register three instances cm.reportHeartBeat(ici1, hardwareDescription); cm.reportHeartBeat(ici2, hardwareDescription); cm.reportHeartBeat(ici3, hardwareDescription); Map<InstanceType, InstanceTypeDescription> instanceTypeDescriptions = cm.getMapOfAvailableInstanceTypes(); assertEquals(1, instanceTypeDescriptions.size()); InstanceTypeDescription descr = instanceTypeDescriptions.entrySet().iterator().next().getValue(); assertEquals(3, descr.getMaximumNumberOfAvailableInstances()); cm.shutdown(); } catch (Exception e) { System.err.println(e.getMessage()); e.printStackTrace(); Assert.fail("Test erroneous: " + e.getMessage()); } } @Test public void testAllocationDeallocation() { try { ClusterManager cm = new ClusterManager(); TestInstanceListener testInstanceListener = new TestInstanceListener(); cm.setInstanceListener(testInstanceListener); int ipcPort = ConfigConstants.DEFAULT_TASK_MANAGER_IPC_PORT; int dataPort = ConfigConstants.DEFAULT_TASK_MANAGER_DATA_PORT; HardwareDescription hardwareDescription = HardwareDescriptionFactory.construct(2, 2L * 1024L * 1024L * 1024L, 2L * 1024L * 1024L * 1024L); String hostname = "192.168.198.1"; InetAddress address = InetAddress.getByName("192.168.198.1"); InstanceConnectionInfo ici1 = new InstanceConnectionInfo(address, hostname, null, ipcPort + 0, dataPort + 0); InstanceConnectionInfo ici2 = new InstanceConnectionInfo(address, hostname, null, ipcPort + 15, dataPort + 15); // register three instances cm.reportHeartBeat(ici1, hardwareDescription); cm.reportHeartBeat(ici2, hardwareDescription); Map<InstanceType, InstanceTypeDescription> instanceTypeDescriptions = cm.getMapOfAvailableInstanceTypes(); assertEquals(1, instanceTypeDescriptions.size()); InstanceTypeDescription descr = instanceTypeDescriptions.entrySet().iterator().next().getValue(); assertEquals(2, descr.getMaximumNumberOfAvailableInstances()); // allocate something JobID jobID = new JobID(); Configuration conf = new Configuration(); InstanceRequestMap instanceRequestMap = new InstanceRequestMap(); instanceRequestMap.setNumberOfInstances(cm.getDefaultInstanceType(), 2); cm.requestInstance(jobID, conf, instanceRequestMap, null); ClusterManagerTestUtils.waitForInstances(jobID, testInstanceListener, 3, 1000); List<AllocatedResource> allocatedResources = testInstanceListener.getAllocatedResourcesForJob(jobID); assertEquals(2, allocatedResources.size()); Iterator<AllocatedResource> it = allocatedResources.iterator(); Set<AllocationID> allocationIDs = new HashSet<AllocationID>(); while (it.hasNext()) { AllocatedResource allocatedResource = it.next(); if (ConfigConstants.DEFAULT_INSTANCE_TYPE.equals(allocatedResource.getInstance().getType().getIdentifier())) { fail("Allocated unexpected instance of type " + allocatedResource.getInstance().getType().getIdentifier()); } if (allocationIDs.contains(allocatedResource.getAllocationID())) { fail("Discovered allocation ID " + allocatedResource.getAllocationID() + " at least twice"); } else { allocationIDs.add(allocatedResource.getAllocationID()); } } // Try to allocate more resources which must result in an error try { InstanceRequestMap instancem = new InstanceRequestMap(); instancem.setNumberOfInstances(cm.getDefaultInstanceType(), 1); cm.requestInstance(jobID, conf, instancem, null); fail("ClusterManager allowed to request more instances than actually available"); } catch (InstanceException ie) { // Exception is expected and correct behavior here } // Release all allocated resources it = allocatedResources.iterator(); while (it.hasNext()) { final AllocatedResource allocatedResource = it.next(); cm.releaseAllocatedResource(jobID, conf, allocatedResource); } // Now further allocations should be possible InstanceRequestMap instancem = new InstanceRequestMap(); instancem.setNumberOfInstances(cm.getDefaultInstanceType(), 1); cm.requestInstance(jobID, conf, instancem, null); cm.shutdown(); } catch (Exception e) { System.err.println(e.getMessage()); e.printStackTrace(); Assert.fail("Test erroneous: " + e.getMessage()); } } /** * This test checks the clean-up routines of the cluster manager. */ @Test public void testCleanUp() { try { final int CLEANUP_INTERVAL = 2; // configure a short cleanup interval Configuration config = new Configuration(); config.setInteger("instancemanager.cluster.cleanupinterval", CLEANUP_INTERVAL); GlobalConfiguration.includeConfiguration(config); ClusterManager cm = new ClusterManager(); TestInstanceListener testInstanceListener = new TestInstanceListener(); cm.setInstanceListener(testInstanceListener); int ipcPort = ConfigConstants.DEFAULT_TASK_MANAGER_IPC_PORT; int dataPort = ConfigConstants.DEFAULT_TASK_MANAGER_DATA_PORT; HardwareDescription hardwareDescription = HardwareDescriptionFactory.construct(2, 2L * 1024L * 1024L * 1024L, 2L * 1024L * 1024L * 1024L); String hostname = "192.168.198.1"; InetAddress address = InetAddress.getByName("192.168.198.1"); InstanceConnectionInfo ici1 = new InstanceConnectionInfo(address, hostname, null, ipcPort + 0, dataPort + 0); InstanceConnectionInfo ici2 = new InstanceConnectionInfo(address, hostname, null, ipcPort + 15, dataPort + 15); InstanceConnectionInfo ici3 = new InstanceConnectionInfo(address, hostname, null, ipcPort + 30, dataPort + 30); // register three instances cm.reportHeartBeat(ici1, hardwareDescription); cm.reportHeartBeat(ici2, hardwareDescription); cm.reportHeartBeat(ici3, hardwareDescription); Map<InstanceType, InstanceTypeDescription> instanceTypeDescriptions = cm.getMapOfAvailableInstanceTypes(); assertEquals(1, instanceTypeDescriptions.size()); InstanceTypeDescription descr = instanceTypeDescriptions.entrySet().iterator().next().getValue(); assertEquals(3, descr.getMaximumNumberOfAvailableInstances()); // request some instances JobID jobID = new JobID(); Configuration conf = new Configuration(); InstanceRequestMap instancem = new InstanceRequestMap(); instancem.setNumberOfInstances(cm.getDefaultInstanceType(), 1); cm.requestInstance(jobID, conf, instancem, null); ClusterManagerTestUtils.waitForInstances(jobID, testInstanceListener, 1, 1000); assertEquals(1, testInstanceListener.getNumberOfAllocatedResourcesForJob(jobID)); // wait for the cleanup to kick in Thread.sleep(2000 * CLEANUP_INTERVAL); // check that the instances are gone ClusterManagerTestUtils.waitForInstances(jobID, testInstanceListener, 0, 1000); assertEquals(0, testInstanceListener.getNumberOfAllocatedResourcesForJob(jobID)); instanceTypeDescriptions = cm.getMapOfAvailableInstanceTypes(); assertEquals(1, instanceTypeDescriptions.size()); descr = instanceTypeDescriptions.entrySet().iterator().next().getValue(); assertEquals(0, descr.getMaximumNumberOfAvailableInstances()); cm.shutdown(); } catch (Exception e) { System.err.println(e.getMessage()); e.printStackTrace(); Assert.fail("Test erroneous: " + e.getMessage()); } } }