/* * 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.rm; import static functionaltests.utils.SchedulerTHelper.log; import static org.junit.Assert.assertEquals; import static org.junit.Assert.fail; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.util.Properties; import org.junit.*; import org.junit.rules.TemporaryFolder; import org.ow2.proactive.resourcemanager.common.event.RMEventType; import org.ow2.proactive.resourcemanager.frontend.ResourceManager; import org.ow2.proactive.scheduler.common.Scheduler; import org.ow2.proactive.scheduler.common.SchedulerEvent; import org.ow2.proactive.scheduler.common.job.JobId; import org.ow2.proactive.scheduler.common.job.JobResult; import org.ow2.proactive.scheduler.common.job.TaskFlowJob; import org.ow2.proactive.scheduler.common.task.JavaTask; import org.ow2.proactive.scheduler.common.task.OnTaskError; import org.ow2.proactive.scheduler.common.task.TaskResult; import org.ow2.proactive.scheduler.core.properties.PASchedulerProperties; import org.ow2.proactive.scheduler.examples.EmptyTask; import org.ow2.proactive.scripting.SelectionScript; import org.ow2.tests.ProActiveTest; import functionaltests.utils.*; /** * Test checks that it is possible to submit, pause and kill jobs when * scheduler isn't linked to RM. * * @author ProActive team * */ public class TestOperationsWhenUnlinked extends ProActiveTest { static final String TASK_NAME = "Test task"; static final long EVENT_TIMEOUT = 5 * 60000; static final int pnp_port = 1299; @ClassRule public static TemporaryFolder tmpFolder = new TemporaryFolder(); private static File config; private static RMTHelper rmHelper; private static SchedulerTHelper schedulerHelper; private static TestNode testNode; @Before public void createConfigAndStart() throws Exception { if (TestScheduler.isStarted()) { SchedulerTHelper.log("Killing previous scheduler."); TestScheduler.kill(); } // set property SCHEDULER_RMCONNECTION_AUTO_CONNECT to false so that RM failure is detected more fast File configurationFile = new File(SchedulerTestConfiguration.SCHEDULER_DEFAULT_CONFIGURATION.toURI()); Properties properties = new Properties(); properties.load(new FileInputStream(configurationFile)); config = tmpFolder.newFile("scheduler_config.ini"); properties.put(PASchedulerProperties.SCHEDULER_RMCONNECTION_AUTO_CONNECT.getKey(), "false"); properties.store(new FileOutputStream(config), null); rmHelper = new RMTHelper(); rmHelper.startRM(null, pnp_port); schedulerHelper = new SchedulerTHelper(false, config.getAbsolutePath(), null, rmHelper.getLocalUrl()); } @After public void cleanUp() { if (testNode != null) { try { testNode.kill(); } catch (Exception ignored) { } } try { rmHelper.killRM(); } catch (Exception ignored) { } try { schedulerHelper.killScheduler(); } catch (Exception ignored) { } } @Ignore("Test is not compatible with the test suite any more, see comments below") @Test public void testKillJob() throws Throwable { testNode = RMTHelper.createNode("test-node"); String nodeUrl = testNode.getNode().getNodeInformation().getURL(); schedulerHelper.getResourceManager().addNode(nodeUrl); schedulerHelper.waitForAnyNodeEvent(RMEventType.NODE_ADDED); Scheduler scheduler = schedulerHelper.getSchedulerInterface(); log("Submitting job1"); JobId jobId1 = scheduler.submit(createJobWithPendingTask(true)); log("Submitting job2"); JobId jobId2 = scheduler.submit(createJobWithPendingTask(false)); log("Waiting when one task finishes"); schedulerHelper.waitForEventTaskFinished(jobId1, TASK_NAME); log("Killing RM"); rmHelper.killRM(); log("Waiting RM_DOWN event"); schedulerHelper.waitForEventSchedulerState(SchedulerEvent.RM_DOWN, EVENT_TIMEOUT); log("Killing job1"); if (!scheduler.killJob(jobId1)) { fail("Failed to kill job " + jobId1); } log("Killing job2"); if (!scheduler.killJob(jobId2)) { fail("Failed to kill job " + jobId2); } // The test is not compatible with the testsuite any more because the following calls require a connexion to // an alive RM and here the RM has been killed schedulerHelper.waitForEventJobFinished(jobId1, EVENT_TIMEOUT); schedulerHelper.waitForEventPendingJobFinished(jobId2, EVENT_TIMEOUT); checkJobResult(scheduler, jobId1, 1); checkJobResult(scheduler, jobId2, 0); } @Test public void testSubmitAndPause() throws Throwable { Scheduler scheduler = schedulerHelper.getSchedulerInterface(); log("Submitting job"); JobId jobId1 = scheduler.submit(createJob()); log("Killing RM"); rmHelper.killRM(); log("Waiting RM_DOWN event"); schedulerHelper.waitForEventSchedulerState(SchedulerEvent.RM_DOWN, EVENT_TIMEOUT); log("Submitting new job"); JobId jobId2 = scheduler.submit(createJob()); if (!scheduler.pauseJob(jobId2)) { fail("Failed to pause job " + jobId2); } if (!scheduler.resumeJob(jobId2)) { fail("Failed to resume job " + jobId2); } log("Creating new RM"); rmHelper = new RMTHelper(); rmHelper.startRM(null, pnp_port); ResourceManager rm = rmHelper.getResourceManager(); testNode = RMTHelper.createNode("test-node"); String nodeUrl = testNode.getNode().getNodeInformation().getURL(); rm.addNode(nodeUrl); rmHelper.waitForAnyNodeEvent(RMEventType.NODE_ADDED); log("Linking new RM"); if (!scheduler.linkResourceManager(rmHelper.getLocalUrl())) { fail("Failed to link another RM"); } log("Waiting when jobs finish"); schedulerHelper.waitForEventJobFinished(jobId1, EVENT_TIMEOUT); schedulerHelper.waitForEventJobFinished(jobId2, EVENT_TIMEOUT); checkJobResult(scheduler, jobId1, 1); checkJobResult(scheduler, jobId2, 1); } private void checkJobResult(Scheduler scheduler, JobId jobId, int expectedTasksNumber) throws Throwable { JobResult jobResult = scheduler.getJobResult(jobId); assertEquals("Unexpected number of task results", expectedTasksNumber, jobResult.getAllResults().size()); for (TaskResult taskResult : jobResult.getAllResults().values()) { log("Task " + taskResult.getTaskId()); if (taskResult.getException() != null) { fail("Unexpected task result exception:" + taskResult.getException()); } assertEquals(taskResult.value(), "Nothing"); } } private TaskFlowJob createJob() throws Exception { TaskFlowJob job = new TaskFlowJob(); job.setName(this.getClass().getSimpleName()); JavaTask javaTask = new JavaTask(); javaTask.setExecutableClassName(EmptyTask.class.getName()); javaTask.setName(TASK_NAME); job.addTask(javaTask); return job; } private TaskFlowJob createJobWithPendingTask(boolean addNormalTask) throws Exception { TaskFlowJob job = new TaskFlowJob(); job.setName(this.getClass().getSimpleName() + "_pending"); job.setOnTaskError(OnTaskError.CONTINUE_JOB_EXECUTION); if (addNormalTask) { JavaTask javaTask = new JavaTask(); javaTask.setExecutableClassName(EmptyTask.class.getName()); javaTask.setName(TASK_NAME); job.addTask(javaTask); } JavaTask javaTask = new JavaTask(); javaTask.setExecutableClassName(EmptyTask.class.getName()); javaTask.setName("TestPendingTask"); javaTask.setSelectionScript(new SelectionScript("selected = false;", "JavaScript", false)); job.addTask(javaTask); return job; } }