Normally, when I am done looking at a JCL, I will type the JEM command into my ISPF command line and that will do a quick scan and tell me any errors, such as files not allocated.
The only problem is, when we have IF statements in the JCL, the JEM will skip over these sections. So even though the JCL JEM-ed clean, I can still end up with JCL errors. Is there anyway that I can validate the JCL, other than actually checking that every single file is allocated?
What you can do is check the condition code handling logic by using programs that can issue condition codes to replace the actual programs.
For a program that issues Cond code 0, simply replace the jcl for the step with a step that invokes the IEFBR14
programs.
e.g. replace the step with
//STEP010 EXEC PGM=IEFBR14
(including any condition code checking from the original step)
For a program that issues a condition code (e.g. 8 )you can use IDCAMS
with that has SET MAXCC=8
e.g.
//STEP010 EXEC PGM=IDCAMS
//SYSIN DD *
MAXCC = 8
//SYSPRINT DD SYSOUT=*
You could quite easily write a program Rexx, Cobol PL1 that could take a parameter as the code.
I personally had an assembler program called CCFIN (this could also issue User Abends) which was :-
TITLE 'ISSUE COND CODE OR ABEND' 00001000
PRINT NOGEN 00001100
INIT REGNUM=1 STANDARD INITIALISATION 00001200
*-------------------------------------------------------------------- 00001301
* GET PARAMETER INFORMATION 00001401
*-------------------------------------------------------------------- 00001501
L 2,0(1) AD OF PARAMETER 00001601
SR 3,3 00001701
LH 3,0(2) GET LENGTH OF PARAMETER 00001801
CH 3,=H'0' CHECK IF ANY PARAMETER 00001901
BH CCFIN001 OK SO FAR 00002001
TO_SHORT WTO 'CCFIN01 - NO PARAMETER GIVEN',ROUTCDE=(2),DESC=(1) 00002101
ERR_END L 13,4(13) 00002203
RETURN (14,12),RC=1 00002301
CCFIN001 CH 3,=H'6' MAX LENGTH OF 6 00002401
BH CCERET01 ERROR > 6 00002502
*-------------------------------------------------------------------- 00002601
* CHECK TO SEE IF USER ABEND IS REQUIRED (UA????) 00002701
*-------------------------------------------------------------------- 00002801
MVC UFLAG(1),=C'N' DEFAULT NO 00002901
CH 3,=H'3' IS PARAMETER < 3 00003001
BL CCFIN030 YES THEN CANT BE USER ABEND 00003101
CLC 2(2,2),=C'UA' CHECK FOR USER ABEND 00003201
BE CCFIN020 00003301
CH 3,=H'4' NOT USER ABEND SO MAX LEN IS 4 00003401
BH CCERET02 ERROR 00003502
B CCFIN030 NOT USER ABEND BUT LEN OK 00003601
CCFIN020 MVC UFLAG(1),=C'Y' SET USER ABEND REQUIRED 00003701
LA 5,1(0,0) 00003801
B CCFIN031 00003901
*-------------------------------------------------------------------- 00004001
* CONVERT PARAMETER TO COMPLETEION CODE 00004101
*-------------------------------------------------------------------- 00004201
CCFIN030 LA 5,1(0,0) 00004301
CCFIN031 LA 4,NSTR 00004401
LA 2,1(2) SKIP PARAMETER LENGTH 00004501
MVC 0(4,4),=C'0000' ENSURE LEFT PAD WITH 0 00004601
LA 4,3(4) END OF AREA 00004701
AR 2,3 END OF PARAMETER LIST 00004801
CLC UFLAG(1),=C'Y' USER ABEND 00004901
BNE CCFIN032 00005001
SR 3,5 00005101
SR 3,5 00005201
CCFIN032 MVC 0(1,4),0(2) 00005301
SR 2,5 00005401
SR 4,5 00005501
BCT 3,CCFIN032 00005601
*-------------------------------------------------------------------- 00005701
* NUMERICS ONLY 00005801
*-------------------------------------------------------------------- 00005901
LA 4,NSTR 00006001
LA 3,4 00006101
CCFIN040 CLC 0(1,4),=X'F0' 00006201
BL CCERET03 00006302
CLC 0(1,4),=X'F9' 00006401
BH CCERET03 00006502
LA 4,1(4) 00006601
BCT 3,CCFIN040 00006701
*-------------------------------------------------------------------- 00006801
* CONVERT NUMBER TO BINARY INTO R15 00006901
*-------------------------------------------------------------------- 00007001
PACK PSTR,NSTR(4) 00007101
CVB 15,PSTR 00007201
CLC UFLAG(1),=C'Y' 00007301
BE FINUA 00007401
FINCC L 13,4(13) 00007501
RETURN (14,12),RC=(15) 00007601
FINUA LR 2,15 00007701
CL 2,=F'4095' 00007801
BNH FU0001 00007901
WTO 'CCFIN02 - USER ABEND CODE GREATER THAN 4095', X00008001
ROUTCDE=(2),DESC=(1) 00008101
SR 2,2 00008201
FU0001 ABEND (2) 00008301
CCERET01 WTO 'CCFIN03 - PARAMETER GREATER THAN 6 CHARACTERS', X00008401
ROUTCDE=(2),DESC=(1) 00008501
B ERR_END 00008603
CCERET02 WTO 'CCFIN04 - PARAMETER GREATER THAN 4 CHARACTERS', X00008701
ROUTCDE=(2),DESC=(1) 00008801
B ERR_END 00008903
CCERET03 WTO 'CCFIN05 - NON NUMERICS CHARACTERS IN PARAMETER', X00009001
ROUTCDE=(2),DESC=(1) 00009101
B ERR_END 00009203
FINISH 00009300
UFLAG DS CL1 00010001
NSTR DS 1F 00020001
PSTR DS D'0' 00030001
END 00036900
The JCL for the above (to issue a condition code of 8) would then be:-
//STEP010 EXEC PGM=CCFIN,PARM="8"
//STEPLIB DD DSN=MY.LOADLIB,DISP=SHR
Assuming that the production(sic) JCL to be tested was :-
//CCOP010R JOB (@OPC,PROD,OPC),'MIKE TAYLOR',
// RESTART=STEP020,
// NOTIFY=CCOP010
//*--------------------------------------------------------------------
//STEP010 EXEC PGM=IKJEFT01,REGION=8M,TIME=10
//*
//* SELECT REQUIRED RECORDS FROM THE JOB/APPL XREF
//*
//SYSPROC DD DISP=SHR,DSN=ISPF.EI.XGROUP.CLIST
//SYSEXEC DD DISP=SHR,DSN=CCOP010.USER.EXEC
//SYSTPRT DD SYSOUT=*
//SYSTSPRT DD SYSOUT=*
//SYSTSIN DD *
OIR00001
//JXIN DD DISP=SHR,DSN=CCOP010.JX.LIST
//JXOUT DD DISP=SHR,DSN=CCOP010.JXMOD.LIST
//*--------------------------------------------------------------------
//STEP020 EXEC PGM=SORT,REGION=8M,COND=(0,NE)
//*
//* SORT BY APPLICATION OPNO AND JOBNAME REMOVING ANY DUPLICATES
//*
//SYSIN DD *
SORT FIELDS=(1,16,CH,A,19,3,CH,A,23,8,CH,A)
SUM FIELDS=NONE
//SORTIN DD DISP=SHR,DSN=CCOP010.JXMOD.LIST
//SORTOUT DD DISP=(,PASS),DSN=&&STEP020A,UNIT=SYSDA,SPACE=(CYL,(50,1))
//SYSOUT DD SYSOUT=*
//*--------------------------------------------------------------------
//STEP030 EXEC PGM=IKJEFT01,REGION=8M,TIME=30,COND=(0,NE)
//*
//* SELECT REQUIRED RECORDS FROM THE JOB/APPL XREF
//*
//SYSPROC DD DISP=SHR,DSN=ISPF.EI.XGROUP.CLIST
//SYSEXEC DD DISP=SHR,DSN=CCOP010.USER.EXEC
//SYSTPRT DD SYSOUT=*
//SYSTSPRT DD SYSOUT=*
//SYSTSIN DD *
OIR00002
//JXIN DD DISP=(SHR,DELETE),DSN=&&STEP020A
//OIIN DD DISP=SHR,DSN=CCOP010.OI.LIST
//IEBOUT DD DISP=SHR,DSN=CCOP010.OIPDS.DATA
//REPORT DD DISP=SHR,DSN=CCOP010.OIPDS.REPORT
//*--------------------------------------------------------------------
And we wanted to test to see if a condition code of 8 issued by STEP010 was handled correctly then :-
The above could be changed to :-
//CCOP010R JOB (@OPC,PROD,OPC),'MIKE TAYLOR',
// RESTART=STEP020,
// NOTIFY=CCOP010
//*--------------------------------------------------------------------
//STEP010 EXEC PGM=IDCAMS
//*
//* SELECT REQUIRED RECORDS FROM THE JOB/APPL XREF
//*
//SYSIN DD *
MAXCC = 8
//SYSPRINT DD SYSOUT=*
//*--------------------------------------------------------------------
//STEP020 EXEC PGM=IEFBR14,COND=(0,NE)
//*
//* SORT BY APPLICATION OPNO AND JOBNAME REMOVING ANY DUPLICATES
//*
//*--------------------------------------------------------------------
//STEP030 EXEC PGM=IEFBR14,COND=(0,NE)
//*
//* SELECT REQUIRED RECORDS FROM THE JOB/APPL XREF
//*
//*--------------------------------------------------------------------
e.g. Running a job with the same name as a job that is run and tracked via a scheduler could interfere with the production schedule.