/* * 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.workflow; import java.io.File; import java.io.Serializable; import java.util.HashMap; import java.util.Map; import java.util.Map.Entry; import org.junit.Assert; import org.ow2.proactive.scheduler.common.job.*; import org.ow2.proactive.scheduler.common.job.factories.JobFactory; import org.ow2.proactive.scheduler.common.task.TaskState; import org.ow2.proactive.scheduler.common.task.TaskStatus; import org.ow2.proactive.scheduler.task.internal.InternalTask; import functionaltests.utils.SchedulerFunctionalTestNonForkedModeNoRestart; import functionaltests.utils.SchedulerTHelper; /** * Test the correctness of workflow jobs containing replicate actions * * * @author mschnoor * */ public class TRepJobs extends SchedulerFunctionalTestNonForkedModeNoRestart { public static class TRepCase { String jobPath; // total number of tasks public int total; // for each task name in the job descriptor, number // of actual tasks sharing the same base name when the job finishes public Map<String, Long> tasks; // for each task name in the job descriptor, sum // of the results of all tasks sharing the same base // name when the job finishes public Map<String, Long> results; /** * @param jobPath path to the XML job file to submit * @param total total number of tasks * @param t for all task at submission, number of actual tasks sharing the same * base name when finished, and sum of all results * ie: "T1,1,3 T2,2,5 T3,1,2 ..." */ public TRepCase(String jobPath, int total, String t) { this.jobPath = jobPath; this.total = total; readArg(t); } private void readArg(String param) { String[] arr = param.split(" "); this.tasks = new HashMap<>(arr.length); this.results = new HashMap<>(arr.length); for (String str : arr) { String[] split = str.split(","); String key = split[0]; long val = Long.parseLong(split[1]); long val2 = Long.parseLong(split[2]); tasks.put(key, val); results.put(key, val2); } } } public void testJobs(TRepCase... testCases) throws Throwable { for (TRepCase tcase : testCases) { String path = new File(TWorkflowJobs.class.getResource(tcase.jobPath).toURI()).getAbsolutePath(); Job job = JobFactory.getFactory().createJob(path); JobId id = schedulerHelper.submitJob(job); SchedulerTHelper.log("Job submitted, id " + id.toString()); JobState receivedstate = schedulerHelper.waitForEventJobSubmitted(id); Assert.assertEquals(id, receivedstate.getId()); JobInfo jInfo = schedulerHelper.waitForEventJobRunning(id); Assert.assertEquals(jInfo.getJobId(), id); Assert.assertEquals(JobStatus.RUNNING, jInfo.getStatus()); jInfo = schedulerHelper.waitForEventJobFinished(id); Assert.assertEquals(JobStatus.FINISHED, jInfo.getStatus()); SchedulerTHelper.log("Job finished"); JobResult res = schedulerHelper.getJobResult(id); Assert.assertFalse(schedulerHelper.getJobResult(id).hadException()); JobState js = schedulerHelper.getSchedulerInterface().getJobState(id); // final number of tasks Assert.assertEquals(tcase.total, js.getTasks().size()); // to be checked against this.tasks HashMap<String, Long> finalTaskCount = new HashMap<>(); // to be checked against this.results HashMap<String, Long> finalResSum = new HashMap<>(); for (TaskState ts : js.getTasks()) { String baseName = InternalTask.getInitialName(ts.getName()); long count = 0; long sum = 0; if (finalTaskCount.containsKey(baseName)) { count = finalTaskCount.get(baseName); sum = finalResSum.get(baseName); } finalTaskCount.put(baseName, count + 1); long tr = 0; if (ts.getStatus().equals(TaskStatus.SKIPPED)) { tr = -1; } else { Serializable sr = res.getAllResults().get(ts.getName()).value(); if (sr instanceof Long) { tr = ((Long) sr).longValue(); } } finalResSum.put(baseName, sum + tr); } Assert.assertEquals(tcase.tasks.size(), finalTaskCount.size()); Assert.assertEquals(tcase.results.size(), finalResSum.size()); Assert.assertEquals(finalTaskCount.size(), finalResSum.size()); for (Entry<String, Long> entry : finalTaskCount.entrySet()) { Assert.assertTrue(tcase.tasks.containsKey(entry.getKey())); long val = tcase.tasks.get(entry.getKey()); Assert.assertEquals(val, entry.getValue().longValue()); } for (Entry<String, Long> entry : finalResSum.entrySet()) { Assert.assertTrue(tcase.results.containsKey(entry.getKey())); long val = tcase.results.get(entry.getKey()); Assert.assertEquals(val, entry.getValue().longValue()); } schedulerHelper.removeJob(id); schedulerHelper.waitForEventJobRemoved(id); } } }