mainframejclispf

Validating JCL with conditional logic


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?


Solution

  • 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
    

    Example

    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
    //*
    //*--------------------------------------------------------------------
    

    Note! serious consideration should be given to the impact that not changing Jobname and accounting info could have. i.e. It would be advisable to change these to suit the in-house use.

    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.