Skip to content
Merged
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
2 changes: 1 addition & 1 deletion docs/language_status/register/X70.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,5 @@ reached: "yes (CardDemo COCRDUPC, CBSA INQACCCU, CBSA INQCUST)"
- **What IBM leaves open, and what we do.** (1) Which codes: AFCR, AFCS and AFCT only (the three RLS file control abends the burned estates test for); any other code is REFUSED. (2) Which command meets the abend: the real trigger is the RLS server, not a particular command, so a plan names the command and the Nth occurrence of it (ASSUMED); a non-file command is REFUSED. (3) RESP2: IBM states none, a plan naming one is REFUSED. (4) The state of an open browse or a held update lock after the abend: the task ends or the exit runs, and the model keeps no file lock between tasks (ASSUMED).
- **LINK (ASSUMED):** a plan `LINK PROGRAM NTH -1 0 ABCODE` abends the task at the LINK in the caller (event `ABEND`, then `LINK ... resp=0`); the callee never runs and its own HANDLE ABEND exit does not absorb the abend (a file abend inside the callee is the callee's to handle, which the file plans already cover). The abend searches the exit from the issuing level upward; a det port runs it at the task's first program level, so a LINK issued from a deeper level is not planned (ASSUMED). Proven on INQACCCU (cbsa-inqacccu: `link-inqcust-abends-afcr` / `afcs` / `afct`).
- **Browse commands (ASSUMED):** a READNEXT / READPREV that abends answers RESP 0 with no key and no record; the det runtime's `Browsed.normal()` / `BrowsedRba.normal()` are false for it, so a port never reads the record before it checks the exit. Proven on INQCUST (cbsa-inqcust: `read-abends-afcr`, `startbr-abends-afcs`, `readprev-abends-afct`: the storm-drain arm of ABEND-HANDLING answers 'N' / '2'; `read-abends-afcr-rollback-fails`: the SYNCPOINT ROLLBACK fails INVREQ (X71), so the arm LINKs ABNDPROC and ABENDs HROL CANCEL).
- **Refused by name:** the list in the summary. None of the twelve burned programs that hold a HANDLE ABEND issues a COBOL CALL, so an abend of a CALLed program is refused (nothing to prove). An abend of a non-file CICS command other than the LINK above is refused too; ZECS000's `9100-ABEND` exit is the one open candidate (#6271). Db2 AD2Z is X73.
- **Refused by name:** the list in the summary. None of the twelve burned programs that hold a HANDLE ABEND issues a COBOL CALL, so an abend of a CALLed program is refused (nothing to prove). An abend of a non-file CICS command other than the LINK above is refused too; ZECS000's `9100-ABEND` exit is reached by a file abend on its control READ (zecs-zecs000: `control-read-abends-afcr` / `afcs` / `afct`), so no non-file abend is needed. Db2 AD2Z is X73.
- **Status:** ASSUMED for the command it is planned on and the unit-of-work backout, REFUSED where listed. The oracle is GnuCOBOL plus our stub, not z/OS. Unit-proven (tests/tools/test_equivalence_cics_abend_injection.py) and proven on COCRDUPC (carddemo-cardupdate: `search-card-read-rls-abend-afcr`, `pf5-rewrite-rls-abend-afct`).
42 changes: 32 additions & 10 deletions tests/equivalence/det_sweep_coverage/zecs-zecs000.json
Original file line number Diff line number Diff line change
@@ -1,30 +1,52 @@
{
"format": "det-sweep-coverage/2",
"scenarios": 10,
"scenarios": 13,
"paragraphs": {
"covered": 33,
"covered": 34,
"live": 38
},
"branches": {
"covered": 38,
"total": 46
},
"uncovered": {
"paragraphs": [
"3220-SYNCPOINT:557",
"3220-EXIT:566",
"8100-RESTART:727",
"8100-EXIT:739"
],
"branches": [
"446:false",
"451:false",
"457:false",
"486:false",
"508:true",
"531:true",
"535:true",
"620:true",
"paragraph:3220-SYNCPOINT",
"paragraph:3220-EXIT",
"paragraph:8100-RESTART",
"paragraph:8100-EXIT"
]
},
"inputs": {
"case": "9b239e4c6a551269a16d53d57caa5e68790de1e2febb9f6a0a950b3150137530",
"case": "002b5a66b0c03d54936cd827580ffd33ebfbd47558d6c98c67405e431717b1e0",
"corpus": "09feecf8028c77a136bbff56380f9babddf0b2e28fbb6a7ad7ba456273989ff6",
"harness": "efbe51075ec1adca1d2de680be9c28392f4d525f661d39c1d5f9eeaf7ae38c86",
"oracle": "e9e74c7b948ad1020416ad6ae58cb9ae52e4027557d0f25419d12926e20cc83e",
"harness": "9cbaac73873e515cc3732b7bb7baa435afd359b30e0be41281fa9d52920ea1c5",
"oracle": "1591faa65a38117c94da9535751bfc94c2901419abb880944eab417d1b42c2ba",
"components": {
"harness": {
"harness:cics": "524c7ec5b94a8002f7cb66755e3328f295865ecc7399685916101df02b20703c",
"harness:core": "d62c9af2a5f83bb39a1deffe40cd7d7d63bb0d2945c4e8cec6b12503931f45ef"
"harness:cics": "f57f3006faeb437f89e2c38d1342c90f6267381148e72bce38fc1bcdb4d1773e",
"harness:core": "7e08e5e0849996c23ddf4e3cc22a74a932455ae21291cadb431d411566062741"
},
"oracle": {
"oracle:cics-stub": "a87ec1941cad022e2a2706e2d20545b3da939139e7764b7aa9bec9358bcc82ae",
"oracle:cics-stub": "ad541885330dbe0b7018c57237eb806ba1c0ec211ff032ddc13a7808f2cf8824",
"oracle:core": "b5ba772713fe1ad0da7935c39e6bcfe79fcdaf13f631fb62ed6e2a003fab534a",
"oracle:le": "784d29a91956cd3efd57e16b59789a42c3ee30f3105125ef14a67fc9271a6ba2"
"oracle:le": "4fec0fd2411f43c866dc95cbc9e40f5caf30ad88dd1f430b47625c41da044764"
}
}
},
"measured_at": "28734a013e294b3a60b9d42c48375c826e01abde"
"measured_at": "8d7aff6a598a19b5f917dbed0416f55a084a8514"
}
47 changes: 46 additions & 1 deletion tests/equivalence/zecs-zecs000/case.json
Original file line number Diff line number Diff line change
Expand Up @@ -273,9 +273,54 @@
}
},
"why": "#6072: the control record ZX01 was written 3000 s before the task (clock 10:30:15; its interval is 1800 s): 1400-UPDATE finds RELATIVE-TIME not below the TTL (line 381 false), REWRITEs the record with the new ABSTIME, and 1400-EXIT and 1100-EXIT are reached before the expiration browse of the instance's file"
},
{
"name": "control-read-abends-afcr",
"commarea": null,
"startcode": "S",
"faults": [
{
"cmd": "READ",
"file": "ZCEXPIRE",
"resp": "ABEND",
"abcode": "AFCR",
"why": "the RLS server abends the control-record READ UPDATE (X70)"
}
],
"why": "the READ UPDATE of the control record ZX01 abends AFCR: no condition is raised, the HANDLE ABEND exit registered in 1000-RETRIEVE takes the task to 9100-ABEND, which runs 8000-RESTART (START TRANSID) and 9000-RETURN before the control record is read"
},
{
"name": "control-read-abends-afcs",
"commarea": null,
"startcode": "S",
"faults": [
{
"cmd": "READ",
"file": "ZCEXPIRE",
"resp": "ABEND",
"abcode": "AFCS",
"why": "the RLS server abends the control-record READ UPDATE (X70)"
}
],
"why": "the READ UPDATE of the control record ZX01 abends AFCS: no condition is raised, the HANDLE ABEND exit registered in 1000-RETRIEVE takes the task to 9100-ABEND, which runs 8000-RESTART (START TRANSID) and 9000-RETURN before the control record is read"
},
{
"name": "control-read-abends-afct",
"commarea": null,
"startcode": "S",
"faults": [
{
"cmd": "READ",
"file": "ZCEXPIRE",
"resp": "ABEND",
"abcode": "AFCT",
"why": "the RLS server abends the control-record READ UPDATE (X70)"
}
],
"why": "the READ UPDATE of the control record ZX01 abends AFCT: no condition is raised, the HANDLE ABEND exit registered in 1000-RETRIEVE takes the task to 9100-ABEND, which runs 8000-RESTART (START TRANSID) and 9000-RETURN before the control record is read"
}
],
"notes": "zECS's expiration task for one instance (ZECS000, started by the ZX## transaction, here ZX01: EIBTRNID names the instance's files ZC01FILE and ZC01KEY, and the control file ZCEXPIRE). #5089: the CICS file ZCEXPIRE is defined with install symbols (CSD DEFINE FILE DSNAME @ecs_hlq@.ZCEXPIRE.@environment@) and zECS's IDCAMS job is Source/ZCEXPIRE.idcams, which the engine does not read as a define. The case states the substitution (\"install_symbols\": ECS_HLQ ZECS, ENVIRONMENT TEST -- never guessed) and the file's KEYS(4 0) from that job (\"vsam\" under the resolved name). RECORDSIZE(80 2048) and RECORDFORMAT(V) make ZCEXPIRE a variable-length KSDS; the stub keeps fixed-length records, so the case states reclen 70 -- every record the program writes and reads is its ZX-RECORD (LENGTH OF ZX-RECORD) -- and \"variable\": true says so; a record of another length would be a different case. The control record in zcexpire.bin is the one written 600 s before the task. The task is started with no start data (RETRIEVE answers ENDDATA: ZC-KEY stays LOW-VALUES) at the harness's STARTCODE 'S'. HOLES, named: ZC##FILE and ZC##KEY are named at run time from the RETRIEVEd transaction id (#4771) and defined by zECS's own IDCAMS jobs with install placeholders, so the Java side refuses the READ of the instance's file by name (Hole 'CICS file FILE: no store in the generated project') where GnuCOBOL answers FILENOTFOUND; every path that goes on to the expiration browse (2000-READ-FILE and everything after: the DOCUMENT / WEB replication, 3100-3220 deletes, 8100-RESTART) is therefore not in the case, and its paragraphs are uncovered and unproven (coverage 9/38 paragraphs). The two scenarios end before it: the control record is too young (1400-UPDATE restarts and returns) and a WRITE of the control record that answers DUPREC (1300-WRITE). ENQ BUSY, the control file's other conditions and the HANDLE ABEND label are not reached (the harness plans no fault for ENQ). Derived from zECS (github.com/walmartlabs/zECS, Apache-2.0): LICENSE here is the corpus's own, NOTICE names the source and what was derived. #5089 (#4771): two scenarios start the task with start data naming the instance (ZC01), so ZC##FILE / ZC##KEY resolve to the stated datasets ZECS.ZC01FILE.TEST / ZECS.ZC01KEY.TEST (the same stores and seeds as zecs-zecs003) and 2000-READ-FILE runs. The expired-record path (3000-DEPLICATE: DOCUMENT / WEB replication, the 3100-3220 deletes) is still not in the case.",
"notes": "zECS's expiration task for one instance (ZECS000, started by the ZX## transaction, here ZX01: EIBTRNID names the instance's files ZC01FILE and ZC01KEY, and the control file ZCEXPIRE). #5089: the CICS file ZCEXPIRE is defined with install symbols (CSD DEFINE FILE DSNAME @ecs_hlq@.ZCEXPIRE.@environment@) and zECS's IDCAMS job is Source/ZCEXPIRE.idcams, which the engine does not read as a define. The case states the substitution (\"install_symbols\": ECS_HLQ ZECS, ENVIRONMENT TEST -- never guessed) and the file's KEYS(4 0) from that job (\"vsam\" under the resolved name). RECORDSIZE(80 2048) and RECORDFORMAT(V) make ZCEXPIRE a variable-length KSDS; the stub keeps fixed-length records, so the case states reclen 70 -- every record the program writes and reads is its ZX-RECORD (LENGTH OF ZX-RECORD) -- and \"variable\": true says so; a record of another length would be a different case. The control record in zcexpire.bin is the one written 600 s before the task. The task is started with no start data (RETRIEVE answers ENDDATA: ZC-KEY stays LOW-VALUES) at the harness's STARTCODE 'S'. HOLES, named: ZC##FILE and ZC##KEY are named at run time from the RETRIEVEd transaction id (#4771) and defined by zECS's own IDCAMS jobs with install placeholders, so the Java side refuses the READ of the instance's file by name (Hole 'CICS file FILE: no store in the generated project') where GnuCOBOL answers FILENOTFOUND; every path that goes on to the expiration browse (2000-READ-FILE and everything after: the DOCUMENT / WEB replication, 3100-3220 deletes, 8100-RESTART) is therefore not in the case, and its paragraphs are uncovered and unproven (coverage 9/38 paragraphs). The two scenarios end before it: the control record is too young (1400-UPDATE restarts and returns) and a WRITE of the control record that answers DUPREC (1300-WRITE). ENQ BUSY, the control file's other conditions are not reached; the HANDLE ABEND label 9100-ABEND is reached by an AFCR / AFCS / AFCT abend planned on the control READ (#6271, X70) (the harness plans no fault for ENQ). Derived from zECS (github.com/walmartlabs/zECS, Apache-2.0): LICENSE here is the corpus's own, NOTICE names the source and what was derived. #5089 (#4771): two scenarios start the task with start data naming the instance (ZC01), so ZC##FILE / ZC##KEY resolve to the stated datasets ZECS.ZC01FILE.TEST / ZECS.ZC01KEY.TEST (the same stores and seeds as zecs-zecs003) and 2000-READ-FILE runs. The expired-record path (3000-DEPLICATE: DOCUMENT / WEB replication, the 3100-3220 deletes) is still not in the case.",
"region": {
"applid": "ZECSAPPL",
"sysid": "ZECS"
Expand Down
14 changes: 14 additions & 0 deletions tests/tools/test_equivalence_cics_abend_injection.py
Original file line number Diff line number Diff line change
Expand Up @@ -147,3 +147,17 @@ def test_inqcust_plans_an_rls_abend_on_the_read_the_startbr_and_the_readprev():
(f["cmd"], f["abcode"]) for sc in case["scenarios"] for f in sc.get("faults", []) if f.get("resp") == "ABEND"
}
assert planned == {("READ", "AFCR"), ("STARTBR", "AFCS"), ("READPREV", "AFCT")}


def test_zecs000_plans_an_rls_abend_on_the_control_read():
"""#6271: 9100-ABEND (the HANDLE ABEND label of 1000-RETRIEVE) is reached by a file abend, so no non-file command abend is needed."""
import json

case = json.loads((TESTS / "equivalence" / "zecs-zecs000" / "case.json").read_text(encoding="utf-8"))
planned = {
f["abcode"]
for sc in case["scenarios"]
for f in sc.get("faults", [])
if f.get("resp") == "ABEND" and f["cmd"] == "READ" and f["file"] == "ZCEXPIRE"
}
assert planned == {"AFCR", "AFCS", "AFCT"}
Loading