diff --git a/com.ibm.jbatch.tck/src/main/java/com/ibm/jbatch/tck/artifacts/specialized/ExecutionCountBatchlet.java b/com.ibm.jbatch.tck/src/main/java/com/ibm/jbatch/tck/artifacts/specialized/ExecutionCountBatchlet.java new file mode 100644 index 0000000..d115b0b --- /dev/null +++ b/com.ibm.jbatch.tck/src/main/java/com/ibm/jbatch/tck/artifacts/specialized/ExecutionCountBatchlet.java @@ -0,0 +1,58 @@ +/* + * Copyright 2016 International Business Machines Corp. + * + * See the NOTICE file distributed with this work for additional information + * regarding copyright ownership. Licensed under the Apache License, + * Version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +*/ +package com.ibm.jbatch.tck.artifacts.specialized; + +import javax.batch.api.AbstractBatchlet; +import javax.batch.api.BatchProperty; +import javax.batch.runtime.context.JobContext; +import javax.inject.Inject; + +@javax.inject.Named("executionCountBatchlet") +public class ExecutionCountBatchlet extends AbstractBatchlet { + + @Inject + JobContext jobCtx; + + @Inject + @BatchProperty (name="executionCount.number") + String executionNumber; + + public static final String output="ExecutionCountBatchlet Exited on execution "; + + @Override + public String process() throws Exception { + + Integer executionCount; + + if(executionNumber!=null){ + executionCount=Integer.parseInt(executionNumber); + } + else{ + executionCount=0; + } + + jobCtx.setExitStatus(output+executionCount); + + return "EXECUTION "+executionCount; + } + + @Override + public void stop() throws Exception { + + } + +} diff --git a/com.ibm.jbatch.tck/src/main/java/com/ibm/jbatch/tck/tests/jslxml/ChunkTests.java b/com.ibm.jbatch.tck/src/main/java/com/ibm/jbatch/tck/tests/jslxml/ChunkTests.java index c9aec22..37a62c8 100755 --- a/com.ibm.jbatch.tck/src/main/java/com/ibm/jbatch/tck/tests/jslxml/ChunkTests.java +++ b/com.ibm.jbatch.tck/src/main/java/com/ibm/jbatch/tck/tests/jslxml/ChunkTests.java @@ -1331,13 +1331,16 @@ public void testChunkSkipWriteExceedSkip() throws Exception { * the specified item-count, and that none of those objects are null. */ @TCKTest( - specRef={ - @SpecRef(section={"9.2.7"},version="1.0", note="See Javadoc"), + specRefs={ + @SpecRef(section="9.2.7",version="1.0", notes={"See Javadoc"}), }, - apiRef={ - @APIRef(className="javax.batch.api.chunk.listener.SkipWriteListener") + apiRefs={ + @APIRef(className="") }, - tckVersionUpdated="1.1.WORKING") + assertions={"The number of items in the list passed to the listener is correct", + "All of the items are non-null", + "The values of the items match the expected values"}, + versions="1.1.WORKING") @Test @org.junit.Test public void testChunkSkipWriteVerify() throws Exception { diff --git a/com.ibm.jbatch.tck/src/main/java/com/ibm/jbatch/tck/tests/jslxml/JobExecutableSequenceTests.java b/com.ibm.jbatch.tck/src/main/java/com/ibm/jbatch/tck/tests/jslxml/JobExecutableSequenceTests.java index 21595fd..951e13a 100755 --- a/com.ibm.jbatch.tck/src/main/java/com/ibm/jbatch/tck/tests/jslxml/JobExecutableSequenceTests.java +++ b/com.ibm.jbatch.tck/src/main/java/com/ibm/jbatch/tck/tests/jslxml/JobExecutableSequenceTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013 International Business Machines Corp. + * Copyright 2016 International Business Machines Corp. * * See the NOTICE file distributed with this work for additional information * regarding copyright ownership. Licensed under the Apache License, @@ -16,15 +16,20 @@ */ package com.ibm.jbatch.tck.tests.jslxml; +import static com.ibm.jbatch.tck.utils.AssertionUtils.assertObjEquals; import static com.ibm.jbatch.tck.utils.AssertionUtils.assertWithMessage; import java.io.FileNotFoundException; import java.io.IOException; +import java.util.List; import java.util.Properties; import javax.batch.operations.JobStartException; import javax.batch.runtime.BatchStatus; import javax.batch.runtime.JobExecution; +import javax.batch.runtime.Metric; +import javax.batch.runtime.StepExecution; +import javax.crypto.CipherInputStream; import org.junit.Before; import org.testng.Reporter; @@ -32,6 +37,10 @@ import org.testng.annotations.BeforeTest; import org.testng.annotations.Test; +import com.ibm.jbatch.tck.annotations.APIRef; +import com.ibm.jbatch.tck.annotations.SpecRef; +import com.ibm.jbatch.tck.annotations.TCKTest; +import com.ibm.jbatch.tck.artifacts.specialized.ExecutionCountBatchlet; import com.ibm.jbatch.tck.utils.JobOperatorBridge; public class JobExecutableSequenceTests { @@ -50,6 +59,17 @@ public class JobExecutableSequenceTests { * @throws IOException * @throws InterruptedException */ + + @TCKTest( + specRefs={ + @SpecRef(section="5.3",version="1.0", notes={""}) + }, + apiRefs={ + @APIRef(className="") + }, + versions="1.1.WORKING", + assertions={"Section 5.3 Flow"} + ) @Test @org.junit.Test public void testJobExecutableSequenceToUnknown() throws Exception { @@ -79,6 +99,129 @@ public void testJobExecutableSequenceToUnknown() throws Exception { handleException(METHOD, e); } } + + @TCKTest( + specRefs={ + @SpecRef(section="8.9.3",version="1.0", citations={"The specification prohibits ‘next’ and ‘to’ attribute values that result in a “loop”."}) + }, + apiRefs={ + @APIRef(className="") + }, + versions="1.1.WORKING", + assertions={"A step is transitioned to more than one in execution of a job"} + ) + + + @Test + @org.junit.Test + public void testJobTransitionWithSimpleLoop() throws Exception { + + String METHOD = "testJobTransitionWithSimpleLoop"; + + try { + JobExecution jobExec = null; + try{ + jobExec = jobOp.startJobAndWaitForResult("job_simple_loop", null); + } catch (JobStartException e) { + Reporter.log("Caught JobStartException: " + e.getLocalizedMessage()); + return; //Since the job will be invalid when it loops, if the job fails to start because of that, the test should pass. + } + + Reporter.log("Job execution getBatchStatus()="+jobExec.getBatchStatus()+"

"); + assertObjEquals(BatchStatus.FAILED, jobExec.getBatchStatus()); + + } + catch (Exception e) { + handleException(METHOD, e); + } + } + + + /** + * @testName: testJobTransitionLoopWithRestart + * @assertion: Section 10.8 restart processing + * @test_Strategy: 1. setup a job consisting of 3 steps (step1 next to step2, step2 fail, restart @ step1, transition to step 2, back to step 1) + * 2. start job + * 3. job should fail because it shouldn't be able to transition twice to step 1 in the same execution + * + * @throws JobStartException + * @throws FileNotFoundException + * @throws IOException + * @throws InterruptedException + */ + @TCKTest( + specRefs={ + @SpecRef(section="10.8",version="1.0", citations={"...for restart we need: a definition of where in the job definition to begin; rules for deciding whether or not to execute the current execution element; and rules for performing transitioning, especially taking into account that all steps relevant to transitioning may not have executed on this (restart) execution."}), + @SpecRef(section="8.9.3",version="1.0", notes={""}) + }, + apiRefs={ + @APIRef(className="") + }, + versions="1.1.WORKING", + assertions={"A step is not executed more than once on job restart if not set with \"allow-start-if-complete\"", + "A step may be executed more than once on job restart if set with \"allow-start-if-complete\""}, + issueRefs={"Bugzilla 5691", "Github 31"}) + + @Test + @org.junit.Test + public void testJobTransitionLoopWithRestart() throws Exception { + + String METHOD = "testJobTransitionLoopWithRestart"; + + try { + JobExecution jobExec = null; + try{ + Properties jobParams = new Properties(); + jobParams.put("executionCount.number", "1"); + jobExec = jobOp.startJobAndWaitForResult("job_restart_second_transition", null); + } catch (JobStartException e) { + Reporter.log("Caught JobStartException: " + e.getLocalizedMessage()); + return; //Since the job will be invalid when it loops, if the job fails to start because of that, the test should pass. + } + Reporter.log("First Job execution getBatchStatus()="+jobExec.getBatchStatus()+"

"); + assertObjEquals(BatchStatus.FAILED, jobExec.getBatchStatus()); + + Reporter.log("Obtaining StepExecutions for execution id: " + jobExec.getExecutionId() + "

"); + List steps = jobOp.getStepExecutions(jobExec.getExecutionId()); + + assertObjEquals(2, steps.size()); + + for (StepExecution step : steps) { + showStepState(step); + assertObjEquals(BatchStatus.COMPLETED, step.getBatchStatus()); + } + + JobExecution restartedJobExec =null; + try{ + Properties jobParams = new Properties(); + jobParams.put("executionCount.number", "2"); + restartedJobExec = jobOp.restartJobAndWaitForResult(jobExec.getExecutionId(),jobParams); + } catch(JobStartException e) { + Reporter.log("Caught JobStartException: " + e.getLocalizedMessage()); + return; + } + + Reporter.log("Obtaining StepExecutions for execution id: " + restartedJobExec.getExecutionId() + "

"); + List steps2 = jobOp.getStepExecutions(restartedJobExec.getExecutionId()); + + final String message="Number of steps in this execution: "; + + assertObjEquals(message+"1", message+steps2.size()); + StepExecution step=steps2.get(0); + showStepState(step); + assertObjEquals(BatchStatus.COMPLETED, step.getBatchStatus()); + assertObjEquals("step2", step.getStepName()); + + Reporter.log("Second Job execution getExitStatus()="+restartedJobExec.getExitStatus()+"

"); + assertObjEquals(ExecutionCountBatchlet.output+"2", restartedJobExec.getExitStatus()); + + Reporter.log("Second Job execution getBatchStatus()="+restartedJobExec.getBatchStatus()+"

"); + assertObjEquals(BatchStatus.FAILED, restartedJobExec.getBatchStatus()); + + } catch (Exception e) { + handleException(METHOD, e); + } + } private static void handleException(String methodName, Exception e) throws Exception { Reporter.log("Caught exception: " + e.getMessage()+"

"); @@ -113,4 +256,22 @@ public void beforeTest() throws ClassNotFoundException { public void afterTest() { jobOp = null; } + + private void showStepState(StepExecution step) { + Reporter.log("---------------------------

"); + Reporter.log("getStepName(): " + step.getStepName() + " - "); + Reporter.log("getStepExecutionId(): " + step.getStepExecutionId() + " - "); + Metric[] metrics = step.getMetrics(); + + for (int i = 0; i < metrics.length; i++) { + Reporter.log(metrics[i].getType() + ": " + metrics[i].getValue() + " - "); + } + + Reporter.log("getStartTime(): " + step.getStartTime() + " - "); + Reporter.log("getEndTime(): " + step.getEndTime() + " - "); + Reporter.log("getBatchStatus(): " + step.getBatchStatus() + " - "); + Reporter.log("getExitStatus(): " + step.getExitStatus()+"

"); + Reporter.log("---------------------------

"); + } } + diff --git a/com.ibm.jbatch.tck/src/main/java/com/ibm/jbatch/tck/tests/jslxml/PropertySubstitutionTests.java b/com.ibm.jbatch.tck/src/main/java/com/ibm/jbatch/tck/tests/jslxml/PropertySubstitutionTests.java index fb071b7..0aa10b1 100755 --- a/com.ibm.jbatch.tck/src/main/java/com/ibm/jbatch/tck/tests/jslxml/PropertySubstitutionTests.java +++ b/com.ibm.jbatch.tck/src/main/java/com/ibm/jbatch/tck/tests/jslxml/PropertySubstitutionTests.java @@ -235,15 +235,23 @@ public void testGivenPropertyName() throws Exception { } } - /* - * @testName: testPropertyInnerScopePrecedence - * - * @assertion: A batch artifacts properties overrides any parent properties defined in - * an outer XML scope. Child properties always override parent properties with the same name. - * - * @test_Strategy: Issue a job with a step level property and batchlet property with the same name. - * Verify that the injected property value is from the artifact level property. - */ + @TCKTest( + versions={"1.0", "1.1.WORKING"}, + assertions={"For an artifact level property that is resolved via the jobProperties substitution operator, a " + + "step level property holds precedence over a job level property with the specified target name."}, + specRefs={ + @SpecRef( + version="1.0", section="8.8.1.2", + citations={"The jobProperties substitution operator resolves to the value of the job property with " + + "the specified target name. This property is found by recursively searching from the " + + "innermost containment scope (this includes earlier properties within the current scope) " + + "to the outermost scope until a property with the specified target name is found."} + ), + }, + strategy="Issue a job with a batchlet level property of #{jobProperties['batchletPropVal']}. The job will have " + + "a job level property and a step level property, both with the name of batchletPropVal. Verify that " + + "the step level property is the one used for substitution." + ) @Test @org.junit.Test public void testPropertyInnerScopePrecedence() throws Exception { @@ -257,11 +265,11 @@ public void testPropertyInnerScopePrecedence() throws Exception { System.setProperty("property.junit.propName", "batchletProp"); Reporter.log("Invoke startJobAndWaitForResult

"); - JobExecution jobExec = jobOp.startJobAndWaitForResult("job_properties2"); + jobOp.startJobAndWaitForResult("job_properties2"); String result = System.getProperty("property.junit.result"); Reporter.log("Test result: " + result + "

"); - assertObjEquals("batchletPropValue", result); + assertObjEquals("STEP_OVERRIDE", result); } catch (Exception e) { handleException(METHOD, e); } diff --git a/com.ibm.jbatch.tck/src/main/resources/META-INF/batch-jobs/job_properties2.xml b/com.ibm.jbatch.tck/src/main/resources/META-INF/batch-jobs/job_properties2.xml index a7c9276..8844965 100755 --- a/com.ibm.jbatch.tck/src/main/resources/META-INF/batch-jobs/job_properties2.xml +++ b/com.ibm.jbatch.tck/src/main/resources/META-INF/batch-jobs/job_properties2.xml @@ -19,12 +19,12 @@ - + - + @@ -32,7 +32,7 @@ - + diff --git a/com.ibm.jbatch.tck/src/main/resources/META-INF/batch-jobs/job_restart_second_transition.xml b/com.ibm.jbatch.tck/src/main/resources/META-INF/batch-jobs/job_restart_second_transition.xml new file mode 100644 index 0000000..e0313a9 --- /dev/null +++ b/com.ibm.jbatch.tck/src/main/resources/META-INF/batch-jobs/job_restart_second_transition.xml @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/com.ibm.jbatch.tck/src/main/resources/META-INF/batch-jobs/job_simple_loop.xml b/com.ibm.jbatch.tck/src/main/resources/META-INF/batch-jobs/job_simple_loop.xml new file mode 100644 index 0000000..37c5f3c --- /dev/null +++ b/com.ibm.jbatch.tck/src/main/resources/META-INF/batch-jobs/job_simple_loop.xml @@ -0,0 +1,28 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/com.ibm.jbatch.tck/src/main/resources/META-INF/batch.xml b/com.ibm.jbatch.tck/src/main/resources/META-INF/batch.xml index 05e74b0..6a27f73 100755 --- a/com.ibm.jbatch.tck/src/main/resources/META-INF/batch.xml +++ b/com.ibm.jbatch.tck/src/main/resources/META-INF/batch.xml @@ -56,6 +56,7 @@ +