Skip to content
This repository has been archived by the owner on Apr 13, 2023. It is now read-only.

Created test cases for jobs with loops (issue #31, 1 commit) #56

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -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 {

}

}
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
Original file line number Diff line number Diff line change
@@ -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,
Expand All @@ -16,22 +16,31 @@
*/
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;
import org.testng.annotations.AfterTest;
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 {
Expand All @@ -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 {
Expand Down Expand Up @@ -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()+"<p>");
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()+"<p>");
assertObjEquals(BatchStatus.FAILED, jobExec.getBatchStatus());

Reporter.log("Obtaining StepExecutions for execution id: " + jobExec.getExecutionId() + "<p>");
List<StepExecution> 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() + "<p>");
List<StepExecution> 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()+"<p>");
assertObjEquals(ExecutionCountBatchlet.output+"2", restartedJobExec.getExitStatus());

Reporter.log("Second Job execution getBatchStatus()="+restartedJobExec.getBatchStatus()+"<p>");
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()+"<p>");
Expand Down Expand Up @@ -113,4 +256,22 @@ public void beforeTest() throws ClassNotFoundException {
public void afterTest() {
jobOp = null;
}

private void showStepState(StepExecution step) {
Reporter.log("---------------------------<p>");
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()+"<p>");
Reporter.log("---------------------------<p>");
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -257,11 +265,11 @@ public void testPropertyInnerScopePrecedence() throws Exception {
System.setProperty("property.junit.propName", "batchletProp");

Reporter.log("Invoke startJobAndWaitForResult<p>");
JobExecution jobExec = jobOp.startJobAndWaitForResult("job_properties2");
jobOp.startJobAndWaitForResult("job_properties2");

String result = System.getProperty("property.junit.result");
Reporter.log("Test result: " + result + "<p>");
assertObjEquals("batchletPropValue", result);
assertObjEquals("STEP_OVERRIDE", result);
} catch (Exception e) {
handleException(METHOD, e);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,20 +19,20 @@
<properties>
<property name="myprop1" value="step2" />
<property name="myprop2" value="#{jobProperties['myprop1']}" />
<property name="batchletProp" value="JOB_OVERRIDE" />
<property name="batchletPropVal" value="JOB_OVERRIDE" />
<property name="parentProp" value="SHOULD_BE_OUT_OF_SCOPE_OF_@INJECT_@BATCHLETPROPERTY" />
</properties>
<step id="step1" next="#{jobProperties['myprop1']}">
<properties>
<property name="batchletProp" value="STEP_OVERRIDE" />
<property name="batchletPropVal" value="STEP_OVERRIDE" />
</properties>
<batchlet ref="myBatchletWithPropertiesImpl">
<properties>
<property name="myProperty1" value="value1" />
<property name="myProperty2" value="value2" />
<property name="myProperty4" value="value4" />
<property name="mySubmittedProp" value="#{jobParameters['mySubmittedProp']}" />
<property name="batchletProp" value="batchletPropValue" />
<property name="batchletProp" value="#{jobProperties['batchletPropVal']}" />
<property name="defaultPropName1" value="#{jobParameters['infile.name']}?:myfile1.txt;" />
<property name="defaultPropName2" value="#{jobParameters['unresolving.prop']}?:#{systemProperties['file.separator']};#{jobParameters['infile.name']}?:#{systemProperties['file.name.junit']};.txt" />
<property name="myConcatProp" value="#{jobParameters['myFilename']}.txt" />
Expand Down
Loading