/*
* 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 org.ow2.proactive.scheduler.common.job.factories;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import java.io.IOException;
import java.io.Serializable;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Map;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.log4j.BasicConfigurator;
import org.junit.Assert;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.ow2.proactive.scheduler.common.exception.JobCreationException;
import org.ow2.proactive.scheduler.common.job.Job;
import org.ow2.proactive.scheduler.common.job.JobVariable;
import org.ow2.proactive.scheduler.common.job.TaskFlowJob;
import org.ow2.proactive.scheduler.common.task.JavaTask;
import org.ow2.proactive.scheduler.common.task.TaskVariable;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
public class TestStaxJobFactory {
private static final ImmutableMap<String, String> EXPECTED_KEY_VALUE_ENTRIES = ImmutableMap.of("name1",
"value1",
"name2",
"value2");
private static final String JOB_FACTORY_IMPL = StaxJobFactory.class.getName();
private static URI jobDescriptorUri;
private static URI jobDescriptorSysPropsUri;
private StaxJobFactory factory;
@BeforeClass
public static void setJobDescriptorcUri() throws Exception {
jobDescriptorUri = TestStaxJobFactory.class.getResource("/org/ow2/proactive/scheduler/common/job/factories/job_update_variables.xml")
.toURI();
jobDescriptorSysPropsUri = TestStaxJobFactory.class.getResource("/org/ow2/proactive/scheduler/common/job/factories/job_update_variables_using_system_properties.xml")
.toURI();
BasicConfigurator.resetConfiguration();
BasicConfigurator.configure();
}
@Before
public void setJobFactory() {
factory = (StaxJobFactory) JobFactory.getFactory(JOB_FACTORY_IMPL);
}
@Test
public void testCreateJobShouldUseJobVariablesToReplaceJobNameVariable() throws Exception {
Job testScriptJob = factory.createJob(jobDescriptorUri);
assertEquals("updated_job_name", testScriptJob.getName());
}
@Test
public void testCreateJobShouldUseVariableMapToReplaceJobNameVariable() throws Exception {
Map<String, String> variablesMap = Maps.newHashMap();
variablesMap.put("job_name", "updated_job_name2");
Job testScriptJob = factory.createJob(jobDescriptorUri, variablesMap);
assertEquals("updated_job_name2", testScriptJob.getName());
}
@Test
public void testCreateJobShouldUseJobVariablesToReplaceTaskGenericInfoVariables() throws Exception {
TaskFlowJob testJob = (TaskFlowJob) factory.createJob(jobDescriptorUri);
assertEquals("updated_task_generic_info_value",
testJob.getTask("task1").getGenericInformation().get("task_generic_info"));
}
@Test
public void testCreateJobShouldUseVariableMapToReplaceTaskGenericInfoVariables() throws Exception {
Map<String, String> variablesMap = Maps.newHashMap();
variablesMap.put("task_generic_info", "updated_task_generic_info_value2");
TaskFlowJob testJob = (TaskFlowJob) factory.createJob(jobDescriptorUri, variablesMap);
assertEquals("updated_task_generic_info_value2",
testJob.getTask("task1").getGenericInformation().get("task_generic_info"));
}
@Test
public void testCreateJobShouldUseVariableMapParameterToReplaceVariableValue() throws Exception {
Map<String, String> variablesMap = Maps.newHashMap();
variablesMap.put("from_create_job_parameter", "from_create_job_parameter_value");
TaskFlowJob testJob = (TaskFlowJob) factory.createJob(jobDescriptorUri, variablesMap);
assertEquals("from_create_job_parameter_value",
testJob.getVariables().get("from_create_job_parameter").getValue());
}
@Test
public void testCreateJobShouldUseSyspropsToReplaceVariables() throws Exception {
System.setProperty("system_property", "system_property_value");
Job testJob = factory.createJob(jobDescriptorSysPropsUri);
assertEquals("system_property_value", testJob.getVariables().get("system_property").getValue());
}
/**
* The next 3 tests are there to check that parsing a workflow XML description involving XML elements
* with more than 1 attribute (defined in any order) returns an object description with expected values
* in corresponding data structures.
*/
@Test
public void testJobCreationAttributeOrderDefinitionGenericInformationXmlElement()
throws URISyntaxException, JobCreationException {
TaskFlowJob job = (TaskFlowJob) factory.createJob(getResource("job_attr_def_generic_information_xml_element.xml"));
Map<String, String> genericInformation = job.getTask("task").getGenericInformation();
assertExpectedKeyValueEntriesMatch(genericInformation);
}
@Test
public void testJobCreationAttributeOrderDefinitionParameterXmlElement()
throws URISyntaxException, JobCreationException, IOException, ClassNotFoundException {
TaskFlowJob job = (TaskFlowJob) factory.createJob(getResource("job_attr_def_parameter_xml_element.xml"));
Map<String, Serializable> arguments = ((JavaTask) job.getTask("task")).getArguments();
assertExpectedKeyValueEntriesMatch(arguments);
}
@Test
public void testJobCreationAttributeOrderDefinitionVariableXmlElement()
throws URISyntaxException, JobCreationException {
Job job = factory.createJob(getResource("job_attr_def_variable_xml_element.xml"));
Map<String, JobVariable> jobVariables = job.getVariables();
assertEquals(2, jobVariables.size());
JobVariable jobVariable = jobVariables.get("name1");
assertNotNull(jobVariable);
assertEquals("name1", jobVariable.getName());
assertEquals("value1", jobVariable.getValue());
assertEquals("model1", jobVariable.getModel());
jobVariable = jobVariables.get("name2");
assertNotNull(jobVariable);
assertEquals("name2", jobVariable.getName());
assertEquals("value2", jobVariable.getValue());
assertEquals("model2", jobVariable.getModel());
}
@Test
public void testHandleVariablesReplacements() throws JobCreationException {
// null replacement
Assert.assertEquals(ImmutableMap.<String, JobVariable> of("a1", new JobVariable("a1", "v1", "m1")),
factory.replaceVariablesInJobVariablesMap(ImmutableMap.<String, JobVariable> of("a1",
new JobVariable("a1",
"v1",
"m1")),
null));
// replace existing variable, leave the model intact
Assert.assertEquals(ImmutableMap.<String, JobVariable> of("a1", new JobVariable("a1", "v2", "m1")),
factory.replaceVariablesInJobVariablesMap(ImmutableMap.<String, JobVariable> of("a1",
new JobVariable("a1",
"v1",
"m1")),
ImmutableMap.<String, String> of("a1", "v2")));
// add new variable
Assert.assertEquals(ImmutableMap.<String, JobVariable> of("a1",
new JobVariable("a1", "v1", "m1"),
"a2",
new JobVariable("a2", "v2")),
factory.replaceVariablesInJobVariablesMap(ImmutableMap.<String, JobVariable> of("a1",
new JobVariable("a1",
"v1",
"m1")),
ImmutableMap.<String, String> of("a2", "v2")));
// reuse replacement variable in pattern and add new variable
Assert.assertEquals(ImmutableMap.<String, JobVariable> of("a1",
new JobVariable("a1", "v1v2", "m1v2"),
"a2",
new JobVariable("a2", "v2")),
factory.replaceVariablesInJobVariablesMap(ImmutableMap.<String, JobVariable> of("a1",
new JobVariable("a1",
"v1${a2}",
"m1${a2}")),
ImmutableMap.<String, String> of("a2", "v2")));
// existing variable uses another existing variable in a pattern, null replacements
Assert.assertEquals(ImmutableMap.<String, JobVariable> of("a1",
new JobVariable("a1", "v1v2", "m1v2"),
"a2",
new JobVariable("a2", "v2")),
factory.replaceVariablesInJobVariablesMap(ImmutableMap.<String, JobVariable> of("a1",
new JobVariable("a1",
"v1${a2}",
"m1${a2}"),
"a2",
new JobVariable("a2",
"v2")),
null));
// existing variable uses another existing variable in a pattern, this other existing variable uses itself a replacement variable
Assert.assertEquals(ImmutableMap.<String, JobVariable> of("a1",
new JobVariable("a1", "v1v3", "m1v3"),
"a2",
new JobVariable("a2", "v3", "m2v3"),
"a3",
new JobVariable("a3", "v3")),
factory.replaceVariablesInJobVariablesMap(ImmutableMap.<String, JobVariable> of("a1",
new JobVariable("a1",
"v1${a2}",
"m1${a2}"),
"a2",
new JobVariable("a2",
"${a3}",
"m2${a3}")),
ImmutableMap.<String, String> of("a3", "v3")));
// existing variable uses a replacement variable in a pattern, this replacement variable uses itself a job variable from the workflow
Assert.assertEquals(ImmutableMap.<String, JobVariable> of("a1",
new JobVariable("a1", "v1v3", "m1v3"),
"a2",
new JobVariable("a2", "v3"),
"a3",
new JobVariable("a3", "v3", "m3v3")),
factory.replaceVariablesInJobVariablesMap(ImmutableMap.<String, JobVariable> of("a1",
new JobVariable("a1",
"v1${a2}",
"m1${a2}"),
"a3",
new JobVariable("a3",
"v3",
"m3${a2}")),
ImmutableMap.<String, String> of("a2", "${a3}")));
// existing variable uses a replacement variable in a pattern, but is overwritten by another replacement variable
Assert.assertEquals(ImmutableMap.<String, JobVariable> of("a1",
new JobVariable("a1", "v1", "m1v2"),
"a2",
new JobVariable("a2", "v2")),
factory.replaceVariablesInJobVariablesMap(ImmutableMap.<String, JobVariable> of("a1",
new JobVariable("a1",
"v1${a2}",
"m1${a2}")),
ImmutableMap.<String, String> of("a2",
"v2",
"a1",
"v1")));
}
@Test
public void testTaskVariables() throws URISyntaxException, JobCreationException {
TaskFlowJob job = (TaskFlowJob) factory.createJob(getResource("task_variables.xml"));
Map<String, TaskVariable> taskVariables = job.getTask("task").getVariables();
assertEquals(2, taskVariables.size());
TaskVariable taskVariable = taskVariables.get("name1");
assertNotNull(taskVariable);
assertEquals("name1", taskVariable.getName());
assertEquals("value1", taskVariable.getValue());
assertEquals("model1", taskVariable.getModel());
assertFalse(taskVariable.isJobInherited());
taskVariable = taskVariables.get("name2");
assertNotNull(taskVariable);
assertEquals("name2", taskVariable.getName());
assertEquals("value2", taskVariable.getValue());
assertEquals("model2", taskVariable.getModel());
assertTrue(taskVariable.isJobInherited());
}
private static <K, V> void assertExpectedKeyValueEntriesMatch(Map<K, V> map) {
// map variable is assumed to contain attributes name/value parsed from XML
// expected attribute names and parsed ones should be the same, so the symmetric
// difference between both sets should be empty
Assert.assertTrue(Sets.symmetricDifference(EXPECTED_KEY_VALUE_ENTRIES.keySet(), map.keySet()).isEmpty());
// expected attribute values and parsed ones should be the same, so the symmetric
// difference between both sets should be empty
Assert.assertTrue(CollectionUtils.disjunction(EXPECTED_KEY_VALUE_ENTRIES.values(), map.values()).isEmpty());
}
private URI getResource(String filename) throws URISyntaxException {
return TestStaxJobFactory.class.getResource("/org/ow2/proactive/scheduler/common/job/factories/" + filename)
.toURI();
}
}