From 1a7730fbdae3661f5de43060e9c18d5cbfb9f701 Mon Sep 17 00:00:00 2001 From: squid-protocol Date: Sat, 17 Oct 2026 23:04:01 -0400 Subject: [PATCH 1/2] equivalence: GenApp lgapvs01 and lgupvs01 error paths run with LGSTSQ and injected RESPs (Part of #5252) Neither program ASSIGNs STARTCODE, so there is no D path to add. Their uncovered branches were the WRITE-ERROR-MESSAGE paths the case notes called refused; as in #5324 the case now runs LGSTSQ in the same task (X6) with DUPREC, NOSPACE, IOERR (lgapvs01) and NOTFND, READ IOERR, REWRITE IOERR / NOSPACE (lgupvs01). The four EIBCALEN branches stay uncovered: the 101-byte ERROR-MSG exceeds LGSTSQ's WRITE-MSG, which X6 refuses at the first LINK. Coverage ledgers and lgapvs01 evidence re-proved. Co-Authored-By: Claude Sonnet 5.5 --- .../det_sweep_coverage/genapp-lgapvs01.json | 28 +++-- .../det_sweep_coverage/genapp-lgupvs01.json | 28 +++-- tests/equivalence/genapp-lgapvs01/case.json | 56 +++++++++- .../equivalence/genapp-lgapvs01/evidence.json | 104 ++++++++++++++---- tests/equivalence/genapp-lgupvs01/case.json | 73 +++++++++++- 5 files changed, 249 insertions(+), 40 deletions(-) diff --git a/tests/equivalence/det_sweep_coverage/genapp-lgapvs01.json b/tests/equivalence/det_sweep_coverage/genapp-lgapvs01.json index 6b47e1e594..69db729217 100644 --- a/tests/equivalence/det_sweep_coverage/genapp-lgapvs01.json +++ b/tests/equivalence/det_sweep_coverage/genapp-lgapvs01.json @@ -1,30 +1,42 @@ { "format": "det-sweep-coverage/2", - "scenarios": 8, + "scenarios": 11, "paragraphs": { - "covered": 2, + "covered": 3, "live": 3 }, "branches": { "covered": 5, "total": 9 }, + "linked": { + "LGSTSQ": { + "paragraphs": { + "covered": 1, + "live": 1 + }, + "branches": { + "covered": 2, + "total": 6 + } + } + }, "inputs": { - "case": "43ffec29fa8c2a0550158fe549d117033843e9741c072eae52f4d08209b5d2a0", + "case": "bd6f078a18022659081c1d65408f8093c52c2ea4b5090b5c0c35ad5a6e7ec9b7", "corpus": "c5e4d52071fad96bed24e9ba06f30417340bfc5e998e7c1cd5f2383be73d6ff6", - "harness": "988bce4bb838393cdaef012a2baba7c78bcb0c45e014c32b07185325fa4200d1", - "oracle": "babe8646430a9e1b33351b6c160d6e452abe4b8363444208954834e6e556119a", + "harness": "6f6e8b308a1e087561982b3157c427f7a9595772b16f50bf58cd5411558c2449", + "oracle": "db4ce1a1215ccfb5ed86d706f91ab5afa29d583d2fe8c84bb34f6852598f7032", "components": { "harness": { "harness:cics": "15d0de8f2010751dfc90928cfd4b28c296306d86fba8b79edf32c47b7d14e6bf", - "harness:core": "6e7670f33404fd3fb12eacc2a12b4d9b8a0329a68cfeed15d95bc33ac1820222" + "harness:core": "1110c2bab773a074f405a5acf8189b68a73485cdccf4ba344b57a54321acff56" }, "oracle": { "oracle:cics-stub": "807c182704dce3b9066d2f03b84f40dc9790264f91deed4df4f561391683faef", "oracle:core": "eea2a006cc58ebd1141804b10def30c657d4d2d2a3d2a19cf5d137d9dea04359", - "oracle:le": "66f2875621048177f9d8c839aa5b86b7a6c4888fcf8a837c04900fe6e6fe673b" + "oracle:le": "fcb5955019dd536a60d5cb03771f58f75ebf5b57d2ef4001b7e31d8b79a9a6ec" } } }, - "measured_at": "f484174367c47b2fddf9cb5ef05cc5febdce81ac" + "measured_at": "be82f2e870f21d7a344d17fa03493991588f57f5" } diff --git a/tests/equivalence/det_sweep_coverage/genapp-lgupvs01.json b/tests/equivalence/det_sweep_coverage/genapp-lgupvs01.json index 5ed305a026..14ba36c0fd 100644 --- a/tests/equivalence/det_sweep_coverage/genapp-lgupvs01.json +++ b/tests/equivalence/det_sweep_coverage/genapp-lgupvs01.json @@ -1,30 +1,42 @@ { "format": "det-sweep-coverage/2", - "scenarios": 6, + "scenarios": 10, "paragraphs": { - "covered": 2, + "covered": 3, "live": 3 }, "branches": { "covered": 5, "total": 9 }, + "linked": { + "LGSTSQ": { + "paragraphs": { + "covered": 1, + "live": 1 + }, + "branches": { + "covered": 2, + "total": 6 + } + } + }, "inputs": { - "case": "c9ce6f6f6962d4c7aee349ab8ad98699a1fcc799bbe1bb91c8e7f485a68221cb", + "case": "52e4cbe907cdaa8705b7c6e82cbf07a07afca94f325ce1bd1f24eba2b8cb6532", "corpus": "c5e4d52071fad96bed24e9ba06f30417340bfc5e998e7c1cd5f2383be73d6ff6", - "harness": "988bce4bb838393cdaef012a2baba7c78bcb0c45e014c32b07185325fa4200d1", - "oracle": "babe8646430a9e1b33351b6c160d6e452abe4b8363444208954834e6e556119a", + "harness": "6f6e8b308a1e087561982b3157c427f7a9595772b16f50bf58cd5411558c2449", + "oracle": "db4ce1a1215ccfb5ed86d706f91ab5afa29d583d2fe8c84bb34f6852598f7032", "components": { "harness": { "harness:cics": "15d0de8f2010751dfc90928cfd4b28c296306d86fba8b79edf32c47b7d14e6bf", - "harness:core": "6e7670f33404fd3fb12eacc2a12b4d9b8a0329a68cfeed15d95bc33ac1820222" + "harness:core": "1110c2bab773a074f405a5acf8189b68a73485cdccf4ba344b57a54321acff56" }, "oracle": { "oracle:cics-stub": "807c182704dce3b9066d2f03b84f40dc9790264f91deed4df4f561391683faef", "oracle:core": "eea2a006cc58ebd1141804b10def30c657d4d2d2a3d2a19cf5d137d9dea04359", - "oracle:le": "66f2875621048177f9d8c839aa5b86b7a6c4888fcf8a837c04900fe6e6fe673b" + "oracle:le": "fcb5955019dd536a60d5cb03771f58f75ebf5b57d2ef4001b7e31d8b79a9a6ec" } } }, - "measured_at": "f484174367c47b2fddf9cb5ef05cc5febdce81ac" + "measured_at": "be82f2e870f21d7a344d17fa03493991588f57f5" } diff --git a/tests/equivalence/genapp-lgapvs01/case.json b/tests/equivalence/genapp-lgapvs01/case.json index acc3680764..b64e09c8cb 100644 --- a/tests/equivalence/genapp-lgapvs01/case.json +++ b/tests/equivalence/genapp-lgapvs01/case.json @@ -104,7 +104,61 @@ "CA-REQUEST-SPECIFIC": "0000000005 0000000000 000000BUNGALOW 00200180000" }, "why": "customer 3 / policy 5 exist as an E record; under H the key differs, so the WRITE is NORMAL and both records stay" + }, + { + "name": "add-duplicate-key", + "commarea": { + "CA-REQUEST-ID": "01AEND", + "CA-CUSTOMER-NUM": 3, + "CA-REQUEST-SPECIFIC": "0000000005 0000000000 000000YNYGROWTHFUND25250000Life Assured Person With 31chrs" + }, + "why": "WRITE of E/3/5, a key already in ksdspoly.txt: DUPREC: '80' to CA-RETURN-CODE, WRITE-ERROR-MESSAGE (LINK LGSTSQ twice), RETURN; the file is unchanged" + }, + { + "name": "add-io-error", + "commarea": { + "CA-REQUEST-ID": "01AEND", + "CA-CUSTOMER-NUM": 1, + "CA-REQUEST-SPECIFIC": "0000000011 0000000000 000000YNYGROWTHFUND25250000Life Assured Person With 31chrs" + }, + "faults": [ + { + "cmd": "WRITE", + "file": "KSDSPOLY", + "resp": "IOERR", + "why": "an I/O error on the data set (IBM: WRITE IOERR)" + } + ], + "why": "WRITE of E/1/11 fails IOERR: '80', WRITE-ERROR-MESSAGE" + }, + { + "name": "add-nospace", + "commarea": { + "CA-REQUEST-ID": "01AEND", + "CA-CUSTOMER-NUM": 1, + "CA-REQUEST-SPECIFIC": "0000000011 0000000000 000000YNYGROWTHFUND25250000Life Assured Person With 31chrs" + }, + "faults": [ + { + "cmd": "WRITE", + "file": "KSDSPOLY", + "resp": "NOSPACE", + "why": "the data set is full (IBM: WRITE NOSPACE)" + } + ], + "why": "WRITE of E/1/11 fails NOSPACE: '80', WRITE-ERROR-MESSAGE" + } + ], + "notes": "GenApp's VSAM 'add policy' (LGAPVS01, LINKed by LGAPDB01): the policy key is CA-REQUEST-ID(4:1) (the type: E/H/M/C) + CA-CUSTOMER-NUM + CA-POLICY-NUM; an EVALUATE on the type moves that type's fields into WF-POLICY-DATA (WHEN OTHER: spaces), then EXEC CICS WRITE FILE('KSDSPOLY') FROM(WF-Policy-Info) LENGTH(64) RIDFLD(WF-Policy-Key) KEYLENGTH(21); on NORMAL it GOBACKs. Each scenario's KSDSPOLY is compared after the task. Every non-NORMAL RESP in this program goes to WRITE-ERROR-MESSAGE (ASKTIME, FORMATTIME, then EXEC CICS LINK PROGRAM('LGSTSQ') with ERROR-MSG and a second LINK with the 99-byte CA-ERROR-MSG). The case's programs list adds LGSTSQ to the same task (X6, #4607), so the error paths run: DUPREC on an existing key, and the injected NOSPACE and IOERR ('80' to CA-RETURN-CODE, then RETURN). A task that reaches WRITE-ERROR-MESSAGE is judged only up to the first LGSTSQ LINK: this program's 101-byte ERROR-MSG is longer than LGSTSQ's 95-byte WRITE-MSG, so the oracle refuses the WRITEQ TD by name (X6, LENGTH > FROM: not modelled); the RESP, the file and the LINK itself are compared before it. The region ASSIGN SYSID is a deployment fact the corpus does not name. The IF EIBCALEN > 0 / IF EIBCALEN < 91 arms of WRITE-ERROR-MESSAGE (4 branches) come after that first LINK and stay uncovered until X6 models LENGTH > FROM; a short-commarea scenario would stop at the same refusal, so none is stated. There is no STARTCODE D arm in this program (it never ASSIGNs STARTCODE). Keys: WF-POLICY-KEY is the request-type byte followed by 20 digits, so every key mixes a letter and digits; the WHEN OTHER scenario puts a digit in that first byte (digits sort before letters in ASCII, after them in EBCDIC). No browse is issued, so no key order is exercised (the comparison sorts each side's records by key bytes). Data: ksdspoly.txt is built from GenApp's own sample policies (base/cntl/db2cre.jcl's policy rows joined with their endowment / house / motor / commercial rows), laid out as WF-POLICY-INFO (request-type letter + customer + policy number, then the type's 43 bytes) -- the record LGAPVS01 writes; policy 7 (type C, no commercial row) is left out. Derived from the CICS General Insurance Application (GenApp, github.com/cicsdev/cics-genapp; (C) Copyright IBM Corp. 2011, 2020), licensed under the Eclipse Public License 2.0: LICENSE here is the corpus's own, NOTICE names the source and what was derived.", + "programs": [ + { + "program": "LGSTSQ", + "program_source": "base/src/lgstsq.cbl" } ], - "notes": "GenApp's VSAM 'add policy' (LGAPVS01, LINKed by LGAPDB01): the policy key is CA-REQUEST-ID(4:1) (the type: E/H/M/C) + CA-CUSTOMER-NUM + CA-POLICY-NUM; an EVALUATE on the type moves that type's fields into WF-POLICY-DATA (WHEN OTHER: spaces), then EXEC CICS WRITE FILE('KSDSPOLY') FROM(WF-Policy-Info) LENGTH(64) RIDFLD(WF-Policy-Key) KEYLENGTH(21); on NORMAL it GOBACKs. Each scenario's KSDSPOLY is compared after the task. Every non-NORMAL RESP in this program goes to WRITE-ERROR-MESSAGE, whose first act is EXEC CICS LINK PROGRAM('LGSTSQ') (GenApp's TS/TD error logger, defined in the CSD); the equivalence harness runs one program and has no port of LGSTSQ, so a scenario that reaches it is refused (Unsupported: LINK PROGRAM(LGSTSQ)). The error paths -- DUPREC on an existing key, NOSPACE / NOTOPEN / IOERR, CA-RETURN-CODE '80' -- are therefore NOT exercised here; they need LGSTSQ modelled (or ported) first. Keys: WF-POLICY-KEY is the request-type byte followed by 20 digits, so every key mixes a letter and digits; the WHEN OTHER scenario puts a digit in that first byte (digits sort before letters in ASCII, after them in EBCDIC). No browse is issued, so no key order is exercised (the comparison sorts each side's records by key bytes). Data: ksdspoly.txt is built from GenApp's own sample policies (base/cntl/db2cre.jcl's policy rows joined with their endowment / house / motor / commercial rows), laid out as WF-POLICY-INFO (request-type letter + customer + policy number, then the type's 43 bytes) -- the record LGAPVS01 writes; policy 7 (type C, no commercial row) is left out. Derived from the CICS General Insurance Application (GenApp, github.com/cicsdev/cics-genapp; (C) Copyright IBM Corp. 2011, 2020), licensed under the Eclipse Public License 2.0: LICENSE here is the corpus's own, NOTICE names the source and what was derived." + "region": { + "applid": "GENAPP", + "sysid": "CICA", + "why": "a deployment fact: LGSTSQ (the error logger every non-NORMAL RESP LINKs) ASSIGNs SYSID into the message it writes; GenApp names no region in the corpus" + } } diff --git a/tests/equivalence/genapp-lgapvs01/evidence.json b/tests/equivalence/genapp-lgapvs01/evidence.json index 5f762de476..d418cb2e29 100644 --- a/tests/equivalence/genapp-lgapvs01/evidence.json +++ b/tests/equivalence/genapp-lgapvs01/evidence.json @@ -26,7 +26,7 @@ "tests/equivalence/genapp-lgapvs01/**" ], "files": 2, - "sha256": "43ffec29fa8c2a0550158fe549d117033843e9741c072eae52f4d08209b5d2a0" + "sha256": "bd6f078a18022659081c1d65408f8093c52c2ea4b5090b5c0c35ad5a6e7ec9b7" }, "harness": { "paths": [ @@ -45,10 +45,10 @@ "tests/tools/equivalence_ims.py" ], "files": 13, - "sha256": "988bce4bb838393cdaef012a2baba7c78bcb0c45e014c32b07185325fa4200d1", + "sha256": "6f6e8b308a1e087561982b3157c427f7a9595772b16f50bf58cd5411558c2449", "components": { "harness:cics": "15d0de8f2010751dfc90928cfd4b28c296306d86fba8b79edf32c47b7d14e6bf", - "harness:core": "6e7670f33404fd3fb12eacc2a12b4d9b8a0329a68cfeed15d95bc33ac1820222" + "harness:core": "1110c2bab773a074f405a5acf8189b68a73485cdccf4ba344b57a54321acff56" } }, "oracle": { @@ -63,36 +63,74 @@ "tests/tools/equivalence_sql.py", "tests/equivalence/ims/ggdli.c" ], - "files": 30, - "sha256": "babe8646430a9e1b33351b6c160d6e452abe4b8363444208954834e6e556119a", + "files": 31, + "sha256": "db4ce1a1215ccfb5ed86d706f91ab5afa29d583d2fe8c84bb34f6852598f7032", "components": { "oracle:cics-stub": "807c182704dce3b9066d2f03b84f40dc9790264f91deed4df4f561391683faef", "oracle:core": "eea2a006cc58ebd1141804b10def30c657d4d2d2a3d2a19cf5d137d9dea04359", - "oracle:le": "66f2875621048177f9d8c839aa5b86b7a6c4888fcf8a837c04900fe6e6fe673b" + "oracle:le": "fcb5955019dd536a60d5cb03771f58f75ebf5b57d2ef4001b7e31d8b79a9a6ec" } }, "generator": { "paths": [ "gitgalaxy/tools/cobol_to_java/**" ], - "files": 93, - "sha256": "e0d8ed202dd1af9bb4b2c1268eeeb50374935e4279a919935fa62065baa2bff3", + "files": 94, + "sha256": "bee96bb388a2333020f55aefa56243dcbc98a4d56c7cc698c6b0bfe31b791444", "components": { - "generator:core": "c59e42618e3d5bf1c0593ffc4f8843d6f27af59f1dbbbdfd5e30ec2c6a1a3add", + "generator:cobolrt/Accept.java": "4bc260fc6386c11e4654cc76eb67a87ca1fad76647373d1e75484ed61b6a0cf3", + "generator:cobolrt/Cobol.java": "864cefa146ee3b203471b97d3245a739b56bde41ed6f460495d73880723878fc", + "generator:cobolrt/Codec.java": "a7020a42ac570db768268a0918c6c96ff6ce5ecccdd56b21476c8c8f6edf6741", + "generator:cobolrt/Editing.java": "2ea7c7da4d7aa9a4c07b3358d929740fdc65dd0e44a982cdf5ef6c5f80c15b25", + "generator:cobolrt/Field.java": "42603aaae152d6b50f1525d2f32e7ee06ab116bd56e9d9598594242305746894", + "generator:cobolrt/Figurative.java": "be9444226c7a0e96840cee639b855212ab715c4cc37222519b2f3a14cbbad867", + "generator:cobolrt/Funcs.java": "dce1f5a3039b26d4b69be1a50a52b61b9314827649277dc30b7f3d0b10b8c4e7", + "generator:cobolrt/Hfp.java": "e198bbd4e84477378344f318e35fee606c0c0fe996494efc2acf89069cb3b121", + "generator:cobolrt/Hole.java": "ef69982f0dadcfd31c7396b6dc5ad16712b01cdbde71b007fe90ce14bd116c0f", + "generator:cobolrt/Lossless.java": "63b2383bf7af1a92e7bb67681568779e4a7a7cb93d8fdf49626a9b79478faece", + "generator:cobolrt/Sort.java": "c0c00763b985f8d4f2fd6b764052cd940411552f7c37349cb11814d0343e1262", + "generator:cobolrt/Storage.java": "bf9f9b58fb42e3f5287273714f3ec55d074f42f45ca59bd190849af5d122a0ec", + "generator:cobolrt/Zoned.java": "8244f9c4e847846349434c8c4c44e2dc10d02fa07b25f7635c68d3df5cbb284c", + "generator:cobolrt/batch/DetFiles.java": "e3e95239ad75ee5f5e6c695eda6f7958d7e77db4febd5e743403c8a8dfefac9c", + "generator:cobolrt/cics/DetCics.java": "a43284c097b393834302c2abc40b4bfdea8c5ba5a1f316032582b6912dd9937f", + "generator:cobolrt/cics/DetJustify.java": "ecf7fab2a14ac125e87f05d7be9bbb13610d1423fc7410c644d00b5767fb812a", + "generator:cobolrt/cics/DetMq.java": "40204edf5e82cd78739db956e424860a0121cb3ec44e0a9c1e508ed41fcf3187", + "generator:cobolrt/dli/DetDli.java": "3a9c2f1fc254d65df27eb872b29bdb7060716a9b8559adfeb8ee9d2d960fd565", + "generator:cobolrt/le/Ceedate.java": "70613bf5c75dbdf02cc883a0ba74b4a83fd60292085c9ceae3fbc5b5c272d503", + "generator:cobolrt/le/Ceedatm.java": "1585bc803db4c422637cad851a8bf3285d3a761d2b118badef6b006852f6e248", + "generator:cobolrt/le/Ceedays.java": "bbaf2a374a74f5a87ee2c0383fbd6a1881219ff075d37565ab885c7c4dc8c0f2", + "generator:cobolrt/le/Ceegmt.java": "0b6f7fb4d7671d19074ef50ee418a0fef8b752f0cabc68a6db21ecb8c6e40c1f", + "generator:cobolrt/le/Ceeisec.java": "394d7c9ff85144cc898a78448f6b17b5a930f8902f42068b6af5f2be8ea7a2eb", + "generator:cobolrt/le/Ceeloct.java": "5db69f3f3fef44d4303e9e66857f489d30ae6f862c2dee03574c7eb9349f3faf", + "generator:cobolrt/le/Ceeqcen.java": "1b9496c7c203143ae6a6da57cfe621035b13935c03c6d9b084fedb9a26d31237", + "generator:cobolrt/le/Ceesecs.java": "3efb7a9fa32409ac3bd9f09359c1bad10848dd9f01305870ac7489952d8dfb3e", + "generator:cobolrt/le/Ceeutc.java": "c12810fda2a51dac477c0ba79f913f08a5d54d20c49bc778d345fc8f2c32519d", + "generator:cobolrt/le/Cobdatft.java": "557be70b157d3a4fd55fbb9fbb20820dea0a23000f3be0170236593826a72e3f", + "generator:cobolrt/le/LeTime.java": "521883d8656b121631ec5b1a7e910172b9908385b4b1171018a7180245936fa3", + "generator:cobolrt/le/Mvswait.java": "41482047bde3829fba1da896ce716536e5535ee7d637142d426efd650ec64672", + "generator:cobolrt/mq/QueueManager.java": "229bbdaf9082354aa501eb66f45eb7b8d9f3557e653421dc8bed3932cb7cf77b", + "generator:cobolrt/sql/DetSql.java": "b58a70cc1fc4e675c9f358dbf2230e133426e0213ef082b732bc6fcfe9338698", + "generator:cobolrt/standalone/CobolAbend.java": "f8b72030ecb8862738c562b0c826ff9b1a085d92050664082f96e6107d5dfdb7", + "generator:cobolrt/standalone/Sysout.java": "407512cfedf89455f08193fe4aed96e26fdfc9fd34e8636a662b6574a5645b4f", + "generator:core": "bb38bb2bf8146dbabcd770c9792c7a4fc49e2b3a6945d3a4fafedb4618b2df4e", "generator:det/__init__": "9dedbc9da92e2e4bfd260e7fd5fb78ee2e41a061466c948250d088ffaa464386", + "generator:det/bll": "d2733f29724746445eb38171372d0956fae4beb31b8ebf3259e1cb270cee9d98", "generator:det/cics": "31ed8476f3b91595139af03de36c1635a68d0dca4aecf55856709785f46d4a9f", "generator:det/cics_containers": "5fc989229d444423f5b14d2c65a2c7c541efbe6cd0e5dc5a833beaf90c578b6b", "generator:det/cvda": "894dce1a06a317be4fee0935fba219b066ef141e48f783953a5fe85c16338e26", - "generator:det/dli": "834aba674d85c25af1299ae19d8b49288f4bd831b578889d9bf40d83b5fea342", + "generator:det/dli": "9def9f478c846ec80e8aba907919660c5eb32d81c6e5ec5d33030dbcc8d92caa", "generator:det/dyncall": "bd15eb2918020d644135fd7f2565937f836b05a223de5ca05af33f0ec7fb0a4f", "generator:det/entity": "b6aa37067dc0413f6700ac83e7dd35610d8e2474aa607bdf54b5b8419ee4c7d6", "generator:det/expr": "fbb3c70683ccd2e64382901efe4846b8d908a8c3c7c9bfa9641c6ff6d48a9c4d", - "generator:det/gen": "8f2d087c9f0d6215eff1dd1272bee7551592e1d22a404c5da27ce0ab2023cf0c", + "generator:det/gen": "a2649e6f2c3a331f884630935c485adad0cea9f4a406004f339e958904be39b6", "generator:det/hfp": "7371422d1821ad22c526f9ba0e37deaa0ffc38ed190c6ad76e7475d820df95a1", "generator:det/layout": "e3c70e4dcbb512324b5b16a57dac4010e60d18b7926c06fff5edbd6cf1a79e3e", "generator:det/mq": "25055224f7c943069e828db7a79887ca1f4e6f4a06ec3b9781c97b31226491a0", "generator:det/osvs": "4ca3599a4d9a49bd17def291a921278d6f4f45858f65acaf75ae817c17644dd5", + "generator:det/program": "71e9e6ddb6619fece7be1d2f53c4f053e0f51570687352b48606c3181d410079", + "generator:det/refine": "4daa99d7534a589b4b46b8517f4109b95f64c956cd101a890e57b6a59eac4e44", "generator:det/source": "8bd64a1f9b6a3f3ae66fd9f8380a206be5a1601cdb84a24209f659822ce4919f", + "generator:det/sql": "63f774a84e78d3e87cf6d198736e76c197b9a4e221be4155c8d2702c6ce53ba0", "generator:det/stmt": "c721d141835a1d80dd7aa3d6218e00a2f8e97d4336d12c1e2c1de32b6523acb5" } }, @@ -181,13 +219,13 @@ } } }, - "digest": "83865539a4e4c84ed5f2985f7f4927f281fa8ab4c9b334fc8f0de27686775298" + "digest": "146671ce5deec851139840d68f249331b6282e0583a63c61eaa403a7ee133711" }, "proof": { - "at": "2026-10-17T21:45:27Z", + "at": "2026-10-18T02:58:48Z", "verdict": "proven", - "runs": 8, - "fault_runs": 0, + "runs": 11, + "fault_runs": 2, "environments": null, "outputs": { "add-endowment": { @@ -221,6 +259,24 @@ "add-same-numbers-other-type": { "equal": 2, "records": 2 + }, + "add-duplicate-key": { + "equal": 1, + "records": 1, + "judged_to": "the refused WRITEQ (X6: its LENGTH runs past FROM; not settled on z/OS, #4050) -- what the task did before it is compared, its end state (files, tables, the COMMAREA it leaves) is not", + "assumes": "X6" + }, + "add-io-error": { + "equal": 1, + "records": 1, + "judged_to": "the refused WRITEQ (X6: its LENGTH runs past FROM; not settled on z/OS, #4050) -- what the task did before it is compared, its end state (files, tables, the COMMAREA it leaves) is not", + "assumes": "X6" + }, + "add-nospace": { + "equal": 1, + "records": 1, + "judged_to": "the refused WRITEQ (X6: its LENGTH runs past FROM; not settled on z/OS, #4050) -- what the task did before it is compared, its end state (files, tables, the COMMAREA it leaves) is not", + "assumes": "X6" } }, "return_code_equal": null, @@ -229,20 +285,20 @@ "java_failed": false, "facade": { "verdict": "proven", - "runs": 8, - "passed": 8, + "runs": 11, + "passed": 11, "entry_points": [ "handleLink" ], "failed": [], "error": null }, - "harness_commit": "f484174367c47b2fddf9cb5ef05cc5febdce81ac+uncommitted", - "inputs_digest": "83865539a4e4c84ed5f2985f7f4927f281fa8ab4c9b334fc8f0de27686775298" + "harness_commit": "be82f2e870f21d7a344d17fa03493991588f57f5+uncommitted", + "inputs_digest": "146671ce5deec851139840d68f249331b6282e0583a63c61eaa403a7ee133711" }, "coverage": { "paragraphs": { - "covered": 2, + "covered": 3, "live": 3 }, "branches": { @@ -280,7 +336,7 @@ "total": 0 }, "source": "the proof's own traced COBOL runs (cobol_coverage.py)", - "inputs_digest": "83865539a4e4c84ed5f2985f7f4927f281fa8ab4c9b334fc8f0de27686775298" + "inputs_digest": "146671ce5deec851139840d68f249331b6282e0583a63c61eaa403a7ee133711" }, "reach": { "entry_points": [ @@ -378,7 +434,7 @@ "compiler_options": null, "image": { "name": "gitgalaxy-gnucobol:3", - "id": "sha256:ea49b2f90e87e7e7f9696c7951331be9f090cbf0217741d2b7bdea7324461f7f", + "id": "sha256:eae1ab4fb27bc61f089c6749e8c3bee3bfc1bf205323df7ce9d118d5e0193005", "base": "debian:bookworm-slim@sha256:3783cc01769c7b2b1b83a5c5ad96c815348e28ed7da68e2e3687004faa906251", "matches_pin": true, "mismatches": [] @@ -496,6 +552,10 @@ "path": "tests/equivalence/le/le_time.c", "sha256": "aa951d4f9e065423e5aa9e4aec605145a9250924034be2a70c736e5b7b2633ce" }, + { + "path": "tests/equivalence/le/mvswait.c", + "sha256": "ed25d9c9cf3b8f2c7a9e319fdc117bff0ff775b15c1c32b3e0d9c20c33d66321" + }, { "path": "tests/equivalence/odbc_cli.pin", "sha256": "1b2288b610ccf5fe0128e1d91d18139978abb261451aa545cc8772e3f2101ff5" diff --git a/tests/equivalence/genapp-lgupvs01/case.json b/tests/equivalence/genapp-lgupvs01/case.json index 37c1194b9a..65f521d37d 100644 --- a/tests/equivalence/genapp-lgupvs01/case.json +++ b/tests/equivalence/genapp-lgupvs01/case.json @@ -86,7 +86,78 @@ "CA-REQUEST-SPECIFIC": "0000000002 0000000000 000000 000000 0000 000000000000" }, "why": "M/10/2 (the last record) with no details: make / model / registration blank, value 0" + }, + { + "name": "update-not-on-file", + "commarea": { + "CA-REQUEST-ID": "01UEND", + "CA-CUSTOMER-NUM": 99, + "CA-REQUEST-SPECIFIC": "0000000004 0000000000 000000YNYGROWTHFUND25250000Life Assured Person With 31chrs" + }, + "why": "READ UPDATE of E/99/4: NOTFND (RESP2 80): '81' to CA-RETURN-CODE, WRITE-ERROR-MESSAGE (LINK LGSTSQ with ERROR-MSG, then the 99-byte CA-ERROR-MSG since EIBCALEN >= 91), ABEND LGV3; the file is unchanged" + }, + { + "name": "update-read-io-error", + "commarea": { + "CA-REQUEST-ID": "01UEND", + "CA-CUSTOMER-NUM": 8, + "CA-REQUEST-SPECIFIC": "0000000004 0000000000 000000YNYGROWTHFUND25250000Life Assured Person With 31chrs" + }, + "faults": [ + { + "cmd": "READ", + "file": "KSDSPOLY", + "resp": "IOERR", + "why": "an I/O error on the data set (IBM: READ IOERR)" + } + ], + "why": "READ UPDATE of E/8/4 fails IOERR: '81', WRITE-ERROR-MESSAGE, ABEND LGV3" + }, + { + "name": "update-rewrite-io-error", + "commarea": { + "CA-REQUEST-ID": "01UEND", + "CA-CUSTOMER-NUM": 8, + "CA-REQUEST-SPECIFIC": "0000000004 0000000000 000000YNYGROWTHFUND25250000Life Assured Person With 31chrs" + }, + "faults": [ + { + "cmd": "REWRITE", + "file": "KSDSPOLY", + "resp": "IOERR", + "why": "an I/O error on the data set (IBM: REWRITE IOERR)" + } + ], + "why": "READ UPDATE of E/8/4 is NORMAL, the REWRITE fails IOERR: '82', WRITE-ERROR-MESSAGE, ABEND LGV4" + }, + { + "name": "update-rewrite-nospace", + "commarea": { + "CA-REQUEST-ID": "01UEND", + "CA-CUSTOMER-NUM": 8, + "CA-REQUEST-SPECIFIC": "0000000004 0000000000 000000YNYGROWTHFUND25250000Life Assured Person With 31chrs" + }, + "faults": [ + { + "cmd": "REWRITE", + "file": "KSDSPOLY", + "resp": "NOSPACE", + "why": "the data set is full (IBM: REWRITE NOSPACE)" + } + ], + "why": "the REWRITE fails NOSPACE: '82', WRITE-ERROR-MESSAGE, ABEND LGV4" + } + ], + "notes": "GenApp's VSAM 'update policy' (LGUPVS01, LINKed by LGUPDB01): the key and WF-POLICY-DATA built as in LGAPVS01, then EXEC CICS READ FILE('KSDSPOLY') INTO(WS-FileIn) LENGTH(WS-Commarea-Len = EIBCALEN) RIDFLD(WF-Policy-Key) KEYLENGTH(21) UPDATE and REWRITE FROM(WF-Policy-Info) LENGTH(64); on NORMAL it GOBACKs. Each scenario's KSDSPOLY is compared after the task. Every non-NORMAL RESP in this program goes to WRITE-ERROR-MESSAGE (ASKTIME, FORMATTIME, then EXEC CICS LINK PROGRAM('LGSTSQ') with ERROR-MSG and a second LINK with the 99-byte CA-ERROR-MSG). The case's programs list adds LGSTSQ to the same task (X6, #4607), so the error paths run: NOTFND on the READ UPDATE ('81', ABEND LGV3) and IOERR on it, IOERR and NOSPACE on the REWRITE ('82', ABEND LGV4). A task that reaches WRITE-ERROR-MESSAGE is judged only up to the first LGSTSQ LINK: this program's 101-byte ERROR-MSG is longer than LGSTSQ's 95-byte WRITE-MSG, so the oracle refuses the WRITEQ TD by name (X6, LENGTH > FROM: not modelled); the RESP, the file and the LINK itself are compared before it. The faults list injects the file RESPs a healthy data set cannot give; the region ASSIGN SYSID is a deployment fact the corpus does not name. The IF EIBCALEN > 0 / IF EIBCALEN < 91 arms of WRITE-ERROR-MESSAGE (4 branches) come after that first LINK and stay uncovered until X6 models LENGTH > FROM; a short-commarea scenario would stop at the same refusal, so none is stated. There is no STARTCODE D arm in this program (it never ASSIGNs STARTCODE). The READ's LENGTH is modelled on both sides (#4436, oracle_assumptions.md X14): WS-Commarea-Len is MOVEd from EIBCALEN (32500 here; 225 when LGUPDB01 LINKs it), unlike the 1024-byte INTO area; the 64-byte record is shorter than both (NORMAL), and LENGTH is set back to 64. A shorter LENGTH would truncate with LENGERR -- on READ UPDATE refused by name, and its path LINKs LGSTSQ anyway. Keys: WF-POLICY-KEY is the request-type byte followed by 20 digits, so every key mixes a letter and digits; the WHEN OTHER scenario puts a digit in that first byte (digits sort before letters in ASCII, after them in EBCDIC). No browse is issued, so no key order is exercised (the comparison sorts each side's records by key bytes). Data: ksdspoly.txt is built from GenApp's own sample policies (base/cntl/db2cre.jcl's policy rows joined with their endowment / house / motor / commercial rows), laid out as WF-POLICY-INFO (request-type letter + customer + policy number, then the type's 43 bytes) -- the record LGAPVS01 writes; policy 7 (type C, no commercial row) is left out. ONE synthetic record is added: key '9' + customer 6 + policy 7 with blank data, so that the WHEN OTHER branch has an existing record to rewrite (GenApp never writes such a key itself). Derived from the CICS General Insurance Application (GenApp, github.com/cicsdev/cics-genapp; (C) Copyright IBM Corp. 2011, 2020), licensed under the Eclipse Public License 2.0: LICENSE here is the corpus's own, NOTICE names the source and what was derived.", + "programs": [ + { + "program": "LGSTSQ", + "program_source": "base/src/lgstsq.cbl" } ], - "notes": "GenApp's VSAM 'update policy' (LGUPVS01, LINKed by LGUPDB01): the key and WF-POLICY-DATA built as in LGAPVS01, then EXEC CICS READ FILE('KSDSPOLY') INTO(WS-FileIn) LENGTH(WS-Commarea-Len = EIBCALEN) RIDFLD(WF-Policy-Key) KEYLENGTH(21) UPDATE and REWRITE FROM(WF-Policy-Info) LENGTH(64); on NORMAL it GOBACKs. Each scenario's KSDSPOLY is compared after the task. Every non-NORMAL RESP in this program goes to WRITE-ERROR-MESSAGE, whose first act is EXEC CICS LINK PROGRAM('LGSTSQ') (GenApp's TS/TD error logger, defined in the CSD); the equivalence harness runs one program and has no port of LGSTSQ, so a scenario that reaches it is refused (Unsupported: LINK PROGRAM(LGSTSQ)). The error paths -- NOTFND on the READ ('81', ABEND LGV3) and a failing REWRITE ('82', ABEND LGV4) -- are therefore NOT exercised here; they need LGSTSQ modelled (or ported) first. The READ's LENGTH is modelled on both sides (#4436, oracle_assumptions.md X14): WS-Commarea-Len is MOVEd from EIBCALEN (32500 here; 225 when LGUPDB01 LINKs it), unlike the 1024-byte INTO area; the 64-byte record is shorter than both (NORMAL), and LENGTH is set back to 64. A shorter LENGTH would truncate with LENGERR -- on READ UPDATE refused by name, and its path LINKs LGSTSQ anyway. Keys: WF-POLICY-KEY is the request-type byte followed by 20 digits, so every key mixes a letter and digits; the WHEN OTHER scenario puts a digit in that first byte (digits sort before letters in ASCII, after them in EBCDIC). No browse is issued, so no key order is exercised (the comparison sorts each side's records by key bytes). Data: ksdspoly.txt is built from GenApp's own sample policies (base/cntl/db2cre.jcl's policy rows joined with their endowment / house / motor / commercial rows), laid out as WF-POLICY-INFO (request-type letter + customer + policy number, then the type's 43 bytes) -- the record LGAPVS01 writes; policy 7 (type C, no commercial row) is left out. ONE synthetic record is added: key '9' + customer 6 + policy 7 with blank data, so that the WHEN OTHER branch has an existing record to rewrite (GenApp never writes such a key itself). Derived from the CICS General Insurance Application (GenApp, github.com/cicsdev/cics-genapp; (C) Copyright IBM Corp. 2011, 2020), licensed under the Eclipse Public License 2.0: LICENSE here is the corpus's own, NOTICE names the source and what was derived." + "region": { + "applid": "GENAPP", + "sysid": "CICA", + "why": "a deployment fact: LGSTSQ (the error logger every non-NORMAL RESP LINKs) ASSIGNs SYSID into the message it writes; GenApp names no region in the corpus" + } } From 2323be0b538405aefcf8b8fe5d4d7770f0990a0a Mon Sep 17 00:00:00 2001 From: squid-protocol Date: Sun, 18 Oct 2026 00:46:20 -0400 Subject: [PATCH 2/2] test_evidence_report: LGSTSQ linked-case test keeps only the Db2 case now that lgapvs01 proves its LINK (Part of #5252) Co-Authored-By: Claude Sonnet 5.5 --- tests/tools/test_evidence_report.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tests/tools/test_evidence_report.py b/tests/tools/test_evidence_report.py index c5fa5a9181..2c34bd3f21 100644 --- a/tests/tools/test_evidence_report.py +++ b/tests/tools/test_evidence_report.py @@ -508,6 +508,12 @@ def test_a_linked_program_never_inherits_the_cases_coverage_and_its_ledger_verdi """LGSTSQ is only LINKed by the GenApp Db2 cases (here only DB2_CASE has a ledger entry): equal by the ledger is L2 (no coverage of its own, #4270), stale with the entry it rests on.""" stale = {"coverage": DB2_COV, "stale_inputs": ["oracle"], "stale_since": "abc1234def5678"} + # the VSAM front ends (lgapvs01, lgupvs01) LINK LGSTSQ too, and CI's ratchet proves them current (#5252): keep only + # the Db2 case, which is the one this test is about + real = er.pb.equivalence_runs + monkeypatch.setattr( + er.pb, "equivalence_runs", lambda: {k: [r for r in v if r.case == DB2_CASE] for k, v in real().items()} + ) db2_fixture(tmp_path, monkeypatch, stale, isolate=True) rep = json.loads((tmp_path / GENAPP / "report.json").read_text("utf-8")) p = next(p for p in rep["programs"] if p["program"].endswith("lgstsq.cbl"))