En banca no se puede probar con datos reales de clientes: los entornos de pruebas los usa mucha más gente y el RGPD lo prohíbe. Pero las pruebas necesitan datos realistas. El Test Data Management resuelve justo eso, y quería entenderlo de principio a fin, no solo de oídas.
Construí en un mainframe real (IBM Z Xplore) un proceso TDM completo: un JCL de 7 pasos encadenados con condiciones, con tres programas COBOL que extraen, enmascaran y cargan, más SORT, GDG y VSAM gestionado con IDCAMS. Todo desde ISPF.
Datos de prueba disfrazados pero válidos, que se refrescan con un solo submit y cuadran en cada paso. Además provoqué y resolví dos incidencias reales: un abend S0C7 con relanzamiento por RESTART y una clave duplicada controlada sin parar la cadena.
Cada paso solo se ejecuta si el anterior terminó bien (IF paso.RC = 0
THEN). Si algo falla, no se cargan datos a medias en el entorno de pruebas.
50 clientes inventados pero con formato real: DNI con la
letra bien calculada e IBAN con dígitos de control correctos. Incluye a propósito casos raros
(saldos negativos y a cero), como en producción. El copybook CLIENTE describe el
registro de 80 posiciones y lo comparten los tres programas.
El programa TDMSUBS extrae los clientes de Madrid y todos los de
saldo negativo, que son los casos que el equipo de pruebas quiere probar. Antes de ejecutar
calculé el resultado esperado (15 de 50) y después lo comprobé con los
contadores y mirando los datos.
El programa TDMMASK disfraza nombre, DNI e IBAN. La clave es que
es consistente: el mismo dato real da siempre el mismo dato falso, así que las
relaciones entre ficheros se mantienen (integridad referencial). Y el resultado tiene
formato válido: se recalcula la letra del DNI y los dígitos de control del
IBAN. El ID, el saldo y la provincia no se tocan.
* DNI: FORMULA FIJA SOBRE EL NUMERO Y LETRA RECALCULADA.
* 7919 NO TIENE FACTORES COMUNES CON 10^8: DOS DNI DISTINTOS
* NUNCA DAN EL MISMO DNI FALSO (SIN CLAVES DUPLICADAS)
2200-DNI.
COMPUTE WS-DNI-CALC = WS-DNI-NUM * 7919 + 13579
COMPUTE WS-DNI-NUM = FUNCTION MOD(WS-DNI-CALC, 100000000)
COMPUTE WS-I = FUNCTION MOD(WS-DNI-NUM, 23) + 1
MOVE WS-LETRA(WS-I) TO WS-DNI-LETRA
MOVE WS-DNI TO CLI-DNI.
El SORT ordena por clave, porque la carga en un VSAM KSDS lo
exige, y guarda cada refresco como una generación de un GDG con
LIMIT(5): siempre se puede volver a los datos de una versión anterior. Después,
IDCAMS borra y vuelve a crear el VSAM (el refresco) y se carga y revisa con
PRINT.
Metí a propósito un saldo no numérico en producción. El paso SUBSET abendó con S0C7 y, gracias a las condiciones, ningún paso posterior se ejecutó. Lo diagnostiqué en SDSF, localicé el registro con un FIND de caracteres no numéricos, lo corregí y relancé desde el paso que había fallado, sin repetir lo que ya había ido bien: lo mismo que se hace con Control-M en un entorno real.
Reproduce un caso real que viví en mi experiencia: un programa que no controlaba los duplicados (SQLCODE -803 en DB2) y paraba la cadena. Aquí el equivalente en VSAM es el file status 22: el registro duplicado va a un fichero de errores, el resto se carga y el paso termina con RC 4 como aviso. Siempre se cumple leídos = cargados + duplicados.
2000-PROCESO.
MOVE REG-CLIENTE TO REG-VSAM
WRITE REG-VSAM
EVALUATE WS-FS-VSAM
WHEN '00'
ADD 1 TO WS-CARGADOS
WHEN '22' *> CLAVE DUPLICADA
PERFORM 2100-DUPLICADO *> A ERRORES Y SIGUE
WHEN OTHER *> ERROR GRAVE: RC 16
MOVE 16 TO RETURN-CODE
STOP RUN
END-EVALUATE
//TDMPROC JOB ,MSGLEVEL=(2,0),NOTIFY=&SYSUID
//* BORRA LAS SALIDAS DE LA EJECUCION ANTERIOR
//BORRA EXEC PGM=IEFBR14
//DD1 DD DSN=Z76766.TDM.CLIENTES.SUBSET,
// DISP=(MOD,DELETE,DELETE),SPACE=(TRK,(1,1))
//DD2 DD DSN=Z76766.TDM.CLIENTES.MASK,
// DISP=(MOD,DELETE,DELETE),SPACE=(TRK,(1,1))
//DD3 DD DSN=Z76766.TDM.CLIENTES.ERRORES,
// DISP=(MOD,DELETE,DELETE),SPACE=(TRK,(1,1))
//* PASO 1: SUBSET - CLIENTES DE MADRID Y SALDO NEGATIVO
//SUBSET EXEC PGM=TDMSUBS
//STEPLIB DD DSN=&SYSUID..LOAD,DISP=SHR
//ENTRADA DD DSN=Z76766.TDM.CLIENTES.PROD,DISP=SHR
//SALIDA DD DSN=Z76766.TDM.CLIENTES.SUBSET,
// DISP=(NEW,CATLG,DELETE),SPACE=(TRK,(1,1)),
// DCB=(RECFM=FB,LRECL=80,BLKSIZE=0)
//SYSOUT DD SYSOUT=*
//* PASO 2: ENMASCARAMIENTO
// IF SUBSET.RC = 0 THEN
//MASK EXEC PGM=TDMMASK
//STEPLIB DD DSN=&SYSUID..LOAD,DISP=SHR
//ENTRADA DD DSN=Z76766.TDM.CLIENTES.SUBSET,DISP=SHR
//SALIDA DD DSN=Z76766.TDM.CLIENTES.MASK,
// DISP=(NEW,CATLG,DELETE),SPACE=(TRK,(1,1)),
// DCB=(RECFM=FB,LRECL=80,BLKSIZE=0)
//SYSOUT DD SYSOUT=*
// ENDIF
//* PASO 3: ORDENA POR ID Y GUARDA UNA GENERACION NUEVA
// IF MASK.RC = 0 THEN
//ORDENA EXEC PGM=SORT
//SYSOUT DD SYSOUT=*
//SORTIN DD DSN=Z76766.TDM.CLIENTES.MASK,DISP=SHR
//SORTOUT DD DSN=Z76766.TDM.CLIENTES.HIST(+1),
// DISP=(NEW,CATLG,DELETE),SPACE=(TRK,(1,1)),
// DCB=(RECFM=FB,LRECL=80,BLKSIZE=0)
//SYSIN DD *
SORT FIELDS=(1,6,CH,A)
/*
// ENDIF
//* PASO 4: CREA EL VSAM DE PRUEBAS VACIO (REFRESCO)
// IF ORDENA.RC = 0 THEN
//DEFVSAM EXEC PGM=IDCAMS
//SYSPRINT DD SYSOUT=*
//SYSIN DD *
DELETE Z76766.TDM.CLIENTES.KSDS CLUSTER PURGE
SET MAXCC = 0
DEFINE CLUSTER (NAME(Z76766.TDM.CLIENTES.KSDS) -
INDEXED KEYS(6 0) RECORDSIZE(80 80) -
TRACKS(1 1)) -
DATA (NAME(Z76766.TDM.CLIENTES.KSDS.DATA)) -
INDEX (NAME(Z76766.TDM.CLIENTES.KSDS.INDEX))
/*
// ENDIF
//* PASO 5: CARGA CON CONTROL DE DUPLICADOS (FILE STATUS 22)
// IF DEFVSAM.RC = 0 THEN
//CARGA EXEC PGM=TDMCARGA
//STEPLIB DD DSN=&SYSUID..LOAD,DISP=SHR
//ENTRADA DD DSN=Z76766.TDM.CLIENTES.HIST(+1),DISP=SHR
//VSAMCLI DD DSN=Z76766.TDM.CLIENTES.KSDS,DISP=SHR
//ERRORES DD DSN=Z76766.TDM.CLIENTES.ERRORES,
// DISP=(NEW,CATLG,DELETE),SPACE=(TRK,(1,1)),
// DCB=(RECFM=FB,LRECL=80,BLKSIZE=0)
//SYSOUT DD SYSOUT=*
// ENDIF
//* PASO 6: REVISA EL CONTENIDO DEL VSAM
// IF CARGA.RC <= 4 THEN
//LISTA EXEC PGM=IDCAMS
//SYSPRINT DD SYSOUT=*
//SYSIN DD *
PRINT INDATASET(Z76766.TDM.CLIENTES.KSDS) CHARACTER
/*
// ENDIF
Datos de prueba limpios en cada ejecución, con histórico de los últimos 5 refrescos en un GDG.
50 → 15 → 15 → 15, y leídos = cargados + duplicados. Contadores en cada paso y ningún dato personal en los logs.
S0C7 diagnosticado y relanzado con RESTART; clave duplicada apartada sin parar la cadena.
Batch, JCL, DB2 y Control-M, con experiencia real en banca.