/*
* ProActive Parallel Suite(TM):
* The Open Source library for parallel and distributed
* Workflows & Scheduling, Orchestration, Cloud Automation
* and Big Data Analysis on Enterprise Grids & Clouds.
*
* Copyright (c) 2007 - 2017 ActiveEon
* Contact: contact@activeeon.com
*
* This library is free software: you can redistribute it and/or
* modify it under the terms of the GNU Affero General Public License
* as published by the Free Software Foundation: version 3 of
* the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* If needed, contact us to obtain a release under GPL Version 2 or 3
* or a different license than the AGPL.
*/
package functionaltests.nodestate;
import static org.junit.Assert.assertEquals;
import java.io.File;
import org.junit.Test;
import org.objectweb.proactive.api.PAFuture;
import org.objectweb.proactive.core.node.Node;
import org.ow2.proactive.resourcemanager.common.NodeState;
import org.ow2.proactive.resourcemanager.common.event.RMEventType;
import org.ow2.proactive.resourcemanager.common.event.RMNodeEvent;
import org.ow2.proactive.resourcemanager.core.properties.PAResourceManagerProperties;
import org.ow2.proactive.resourcemanager.frontend.ResourceManager;
import org.ow2.proactive.resourcemanager.nodesource.infrastructure.LocalInfrastructure;
import org.ow2.proactive.resourcemanager.nodesource.policy.StaticPolicy;
import org.ow2.proactive.utils.FileToBytesConverter;
import org.ow2.proactive.utils.NodeSet;
import functionaltests.utils.RMFunctionalTest;
import functionaltests.utils.RMTHelper;
/**
* This class tests actions of adding and removing node sources, particulary the removal
* of a node source, preemptively or not
*
* Add a node source (test 1)
* put nodes of the nodes in different states ; free, busy, down, to Release,
* remove the node source preemptively (test 2).
*
* Add another node source, and put nodes of the nodes in different states ;
* free, busy, down, to Release,
* Remove the node source non preemptively (test 3).
*
* @author ProActive team
*/
public class TestNodeSourcesActions extends RMFunctionalTest {
@Test
public void testAddRemoveNodesPreemptively() throws Exception {
String nodeSourceName = "TestNodeSourcesActions";
ResourceManager resourceManager = rmHelper.getResourceManager();
int nodeNumber = 5;
int pingFrequency = 5000;
byte[] creds = FileToBytesConverter.convertFileToByteArray(new File(PAResourceManagerProperties.getAbsolutePath(PAResourceManagerProperties.RM_CREDS.getValueAsString())));
resourceManager.createNodeSource(nodeSourceName,
LocalInfrastructure.class.getName(),
new Object[] { creds, nodeNumber, RMTHelper.DEFAULT_NODES_TIMEOUT, "" },
StaticPolicy.class.getName(),
null);
//wait for creation of GCM Node Source event, and deployment of its nodes
rmHelper.waitForNodeSourceEvent(RMEventType.NODESOURCE_CREATED, nodeSourceName);
resourceManager.setNodeSourcePingFrequency(pingFrequency, nodeSourceName);
RMTHelper.log("Test 1");
for (int i = 0; i < nodeNumber; i++) {
rmHelper.waitForAnyNodeEvent(RMEventType.NODE_ADDED);
//wait for the nodes to be in free state
rmHelper.waitForAnyNodeEvent(RMEventType.NODE_STATE_CHANGED);
}
assertEquals(nodeNumber, resourceManager.getState().getTotalNodesNumber());
assertEquals(nodeNumber, resourceManager.getState().getFreeNodesNumber());
//book 3 nodes
NodeSet nodes = resourceManager.getAtMostNodes(3, null);
PAFuture.waitFor(nodes);
assertEquals(3, nodes.size());
assertEquals(nodeNumber - 3, resourceManager.getState().getFreeNodesNumber());
assertEquals(nodeNumber, resourceManager.getState().getTotalNodesNumber());
for (int i = 0; i < 3; i++) {
RMNodeEvent evt = rmHelper.waitForAnyNodeEvent(RMEventType.NODE_STATE_CHANGED);
assertEquals(evt.getNodeState(), NodeState.BUSY);
}
//put one of the busy node in 'to release' state
Node n1 = nodes.remove(0);
resourceManager.removeNode(n1.getNodeInformation().getURL(), false);
RMNodeEvent evt = rmHelper.waitForNodeEvent(RMEventType.NODE_STATE_CHANGED, n1.getNodeInformation().getURL());
assertEquals(evt.getNodeState(), NodeState.TO_BE_REMOVED);
//put one of the busy node in 'down' state
Node n2 = nodes.remove(0);
try {
n2.getProActiveRuntime().killNode(n2.getNodeInformation().getName());
} catch (Exception e) {
e.printStackTrace();
}
evt = rmHelper.waitForNodeEvent(RMEventType.NODE_STATE_CHANGED, n2.getNodeInformation().getURL());
assertEquals(evt.getNodeState(), NodeState.DOWN);
//kill preemptively the node source
resourceManager.removeNodeSource(nodeSourceName, true);
for (int i = 0; i < nodeNumber; i++) {
rmHelper.waitForAnyNodeEvent(RMEventType.NODE_REMOVED);
}
//wait for the event of the node source removal
rmHelper.waitForNodeSourceEvent(RMEventType.NODESOURCE_REMOVED, nodeSourceName);
assertEquals(0, resourceManager.getState().getFreeNodesNumber());
assertEquals(0, resourceManager.getState().getTotalNodesNumber());
//test the non preemptive node source removal
RMTHelper.log("Test 2");
String nodeSourceName2 = "TestNodeSourcesActions2";
//first im parameter is default rmHelper url
int expectedNodeNumber = 3;
rmHelper.createNodeSource(nodeSourceName2, expectedNodeNumber);
resourceManager.setNodeSourcePingFrequency(pingFrequency, nodeSourceName2);
assertEquals(expectedNodeNumber, resourceManager.getState().getTotalNodesNumber());
assertEquals(expectedNodeNumber, resourceManager.getState().getFreeNodesNumber());
//book 3 nodes
nodes = resourceManager.getAtMostNodes(3, null);
PAFuture.waitFor(nodes);
for (int i = 0; i < 3; i++) {
evt = rmHelper.waitForAnyNodeEvent(RMEventType.NODE_STATE_CHANGED);
assertEquals(evt.getNodeState(), NodeState.BUSY);
}
assertEquals(3, nodes.size());
assertEquals(expectedNodeNumber - 3, resourceManager.getState().getFreeNodesNumber());
assertEquals(expectedNodeNumber, resourceManager.getState().getTotalNodesNumber());
//put one of the busy node in 'to release' state
n1 = nodes.remove(0);
resourceManager.removeNode(n1.getNodeInformation().getURL(), false);
evt = rmHelper.waitForNodeEvent(RMEventType.NODE_STATE_CHANGED, n1.getNodeInformation().getURL());
assertEquals(evt.getNodeState(), NodeState.TO_BE_REMOVED);
//put one of the busy node in 'down' state
n2 = nodes.remove(0);
Node n3 = nodes.remove(0);
try {
n2.getProActiveRuntime().killNode(n2.getNodeInformation().getName());
} catch (Exception e) {
e.printStackTrace();
}
evt = rmHelper.waitForNodeEvent(RMEventType.NODE_STATE_CHANGED, n2.getNodeInformation().getURL());
assertEquals(evt.getNodeState(), NodeState.DOWN);
//kill non preemptively the node source
resourceManager.removeNodeSource(nodeSourceName2, false);
//the node isn't removed immediately because one its node is
//in to Release state, and one in busy state
//the two free nodes and the down node (n2) are removed immediately
for (int i = 0; i < expectedNodeNumber - 2; i++) {
rmHelper.waitForAnyNodeEvent(RMEventType.NODE_REMOVED);
}
//the 'to release' node (n1) keeps the same state
//the busy node (n3) becomes a 'to release' node
evt = rmHelper.waitForNodeEvent(RMEventType.NODE_STATE_CHANGED, n3.getNodeInformation().getURL());
assertEquals(evt.getNodeState(), NodeState.TO_BE_REMOVED);
assertEquals(0, resourceManager.getState().getFreeNodesNumber());
assertEquals(2, resourceManager.getState().getTotalNodesNumber());
//give back the two nodes in 'to release' state, they are directly removed
resourceManager.releaseNode(n1);
resourceManager.releaseNode(n3);
for (int i = 0; i < 2; i++) {
rmHelper.waitForAnyNodeEvent(RMEventType.NODE_REMOVED);
}
assertEquals(0, resourceManager.getState().getFreeNodesNumber());
assertEquals(0, resourceManager.getState().getTotalNodesNumber());
}
}