/*
* Copyright (c) 2014 Red Hat, Inc. and/or its affiliates.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Cheng Fang - Initial API and implementation
*/
package org.jberet.job.model;
import java.util.ArrayList;
import java.util.List;
import javax.batch.operations.JobStartException;
import org.jberet.creation.ArchiveXmlLoader;
import org.jberet.tools.MetaInfBatchJobsJobXmlResolver;
import org.junit.Assert;
import org.junit.Test;
public class JobMergerTest {
@Test
public void stepInheritanceCycle() throws Exception {
jobStartException("step-inheritance-cycle.xml", "Expecting JobStartException from cyclic inheritance");
}
@Test
public void stepInheritanceSelf() throws Exception {
jobStartException("step-inheritance-self.xml", "Expecting JobStartException from self inheritance");
}
@Test
public void jobInheritanceSelf() throws Exception {
jobStartException("job-inheritance-self.xml", "Expecting JobStartException from cyclic inheritance");
}
@Test
public void jobInheritanceCycle() throws Exception {
jobStartException("job-inheritance-cycle-child.xml", "Expecting JobStartException from cyclic inheritance");
}
@Test
public void jobWithNonexistentParent() throws Exception {
jobStartException("job-with-nonexistent-parent.xml", "Expecting JobStartException for nonexistent parent");
}
@Test
public void stepWithNonexistentParent() throws Exception {
jobStartException("step-with-nonexistent-parent.xml", "Expecting JobStartException for nonexistent parent");
}
/**
* Shared by tests expecting JobStartException.
*
* @param jobName the job name to load
* @param failureMessage the message to include when failing the test
*/
private void jobStartException(final String jobName, final String failureMessage) {
try {
loadJob(jobName);
Assert.fail(failureMessage);
} catch (final JobStartException e) {
e.printStackTrace();
System.out.printf("Got expected %s%n", e);
} catch (final Exception e) {
Assert.fail(failureMessage + ", but got " + e);
}
}
@Test
public void propertiesListenersFromParentJob() throws Exception {
//parent job-properties-listeners-parent.xml
final Job child = loadJob("job-properties-listeners-child.xml");
Assert.assertEquals("true", child.getRestartable());
Assert.assertEquals(2, child.getProperties().getPropertiesMapping().size());
Assert.assertEquals(2, child.getListeners().getListeners().size());
JobMergerTest.propertiesContain(child.getProperties(), new String[]{"parent", "parent2"});
}
@Test
public void mergeFalse() throws Exception {
//parent job-merge-false-parent.xml
final Job child = loadJob("job-merge-false-child.xml");
Assert.assertEquals("false", child.getRestartable());
Assert.assertEquals(0, child.getProperties().getPropertiesMapping().size());
Assert.assertEquals(0, child.getListeners().getListeners().size());
}
@Test
public void mergeTrue() throws Exception {
//parent job-merge-true-parent.xml
final Job child = loadJob("job-merge-true-child.xml");
Assert.assertEquals(2, child.getProperties().getPropertiesMapping().size());
Assert.assertEquals(2, child.getListeners().getListeners().size());
JobMergerTest.propertiesContain(child.getProperties(), new String[]{"parent", "child"});
}
/**
* Verifies that a job xml can reference custom entities for reusing common segments of job definition.
* This test does not use JSL inheritance.
*
* @throws Exception
* @see <a href="https://issues.jboss.org/browse/JBERET-139">JBERET-139 Implement XMLResolver for Job XML parsing</a>
*/
@Test
public void testEntityXMLResolver() throws Exception {
final String jobName = "job-with-xml-entities";
Job job = loadJob(jobName);
Assert.assertEquals(jobName, job.getId());
Assert.assertEquals(true, job.getRestartableBoolean());
Assert.assertEquals(null, job.getRestartable());
Assert.assertEquals(null, job.getParent());
Assert.assertEquals(null, job.getJslName());
final List<JobElement> jobElements = job.getJobElements();
Assert.assertEquals(1, jobElements.size());
final Step step = (Step) jobElements.get(0);
Assert.assertEquals(jobName + ".step1", step.getId());
Assert.assertEquals(null, step.getAttributeNext());
Assert.assertEquals(null, step.getChunk());
final RefArtifact batchlet = step.getBatchlet();
Assert.assertEquals("batchlet1", batchlet.getRef());
Assert.assertEquals(null, batchlet.getScript());
Assert.assertEquals(null, batchlet.getProperties());
//check resolved XML entities
final Properties properties = job.getProperties();
Assert.assertEquals(1, properties.size());
Assert.assertEquals("common.property.value", properties.get("common.property.key"));
final List<RefArtifact> listeners = job.getListeners().getListeners();
Assert.assertEquals(2, listeners.size());
Assert.assertEquals("EL1", listeners.get(0).getRef());
Assert.assertEquals("EL2", listeners.get(1).getRef());
}
/**
* verifies that the Properties (generated jaxb type, not java.util.Properties) props contains every key in keys.
* As a testing convention, the value is the same as the key. For instance, the Properties can be:
* "foo": "foo", "bar": "bar"
*
* @param props Properties from job xml
* @param keys a String array of keys
* @param checkValues whether to check property value
* @throws IllegalStateException if any key is not found
*/
public static void propertiesContain(final Properties props, final String[] keys, final boolean... checkValues) throws IllegalStateException {
final boolean checkVal = checkValues.length == 0 ? false : checkValues[0];
final java.util.Properties javaUtilProps = Properties.toJavaUtilProperties(props);
for (final String k : keys) {
final String v = javaUtilProps.getProperty(k);
if (v == null) {
throw new IllegalStateException(String.format("Expecting key %s in properties %s, but found none.", k, javaUtilProps));
}
if (checkVal && !v.equals(k)) {
throw new IllegalStateException(String.format("Expecting property %s : %s, but found %s : %s", k, k, k, v));
}
}
}
public static List<String> getListenerRefs(final Listeners listeners) {
final List<String> results = new ArrayList<String>();
for (final RefArtifact a : listeners.getListeners()) {
results.add(a.getRef());
}
return results;
}
public static void listenersContain(final Listeners listeners, final String[] keys) throws IllegalStateException {
final List<String> refs = getListenerRefs(listeners);
for (final String k : keys) {
if (!refs.contains(k)) {
throw new IllegalStateException(String.format("Expecting ref %s in listeners %s, but found none.", k, refs));
}
}
}
static Job loadJob(final String jobName) {
return ArchiveXmlLoader.loadJobXml(jobName, JobMergerTest.class.getClassLoader(), new ArrayList<Job>(), new MetaInfBatchJobsJobXmlResolver());
}
}