IDENTIFICATION DIVISION. PROGRAM-ID. CEPIS-TESTS. *> --------------------------------------------------------------------- *> The suite. Run it through tests/server.py, which binds a loopback *> port, exports CEPIS_TEST_URL and runs this program: *> *> python3 tests/server.py ./build/cepis-tests *> *> Every test goes through the real transport against that server, so *> what is exercised is the code that runs in production -- request *> construction, header handling and error-body reading included. It *> doubles as the test that CFG-BASE-URL works: without it none of this *> would reach anything. *> *> The process exits non-zero if any check fails. *> --------------------------------------------------------------------- DATA DIVISION. WORKING-STORAGE SECTION. COPY "cepis.cpy". COPY "cepis-http.cpy". 01 WS-BASE PIC X(200). 01 WS-CHECKS PIC 9(4) VALUE 0. 01 WS-FAILURES PIC 9(4) VALUE 0. 01 WS-LABEL PIC X(56). 01 WS-DETAIL PIC X(200). 01 WS-OK PIC X. 01 WS-TALLY PIC 9(4). 01 WS-I PIC 9(4). 01 WS-COUNT PIC 9(9). 01 WS-COUNT-BEFORE PIC 9(9). 01 WS-COUNT-PATH PIC X(40). 01 WS-NUM8 PIC 9(8). 01 WS-T0 PIC S9(18) COMP-5. 01 WS-T1 PIC S9(18) COMP-5. 01 WS-ELAPSED PIC S9(18). 01 WS-SAVED-ATTEMPTS PIC 9(4). 01 WS-SAVED-RETRY PIC S9(9). 01 WS-GOOD-TABLE. 05 FILLER PIC X(20) VALUE "01001000". 05 FILLER PIC X(20) VALUE "01001-000". 05 FILLER PIC X(20) VALUE " 01001-000 ". 05 FILLER PIC X(20) VALUE "01001.000". 01 WS-GOODS REDEFINES WS-GOOD-TABLE. 05 WS-GOOD OCCURS 4 TIMES PIC X(20). 01 WS-BAD-TABLE. 05 FILLER PIC X(20) VALUE SPACES. 05 FILLER PIC X(20) VALUE "123". 05 FILLER PIC X(20) VALUE "0100100a". 05 FILLER PIC X(20) VALUE "010010000". 05 FILLER PIC X(20) VALUE "abcdefgh". 01 WS-BADS REDEFINES WS-BAD-TABLE. 05 WS-BAD OCCURS 5 TIMES PIC X(20). PROCEDURE DIVISION. MAIN-START. MOVE SPACES TO WS-BASE ACCEPT WS-BASE FROM ENVIRONMENT "CEPIS_TEST_URL" IF WS-BASE = SPACES DISPLAY "CEPIS_TEST_URL is not set -- run through " "tests/server.py" MOVE 2 TO RETURN-CODE STOP RUN END-IF DISPLAY "cepis 0.1.0 test suite against " FUNCTION TRIM (WS-BASE) DISPLAY " " PERFORM T-NORMALIZE-ACCEPTS PERFORM T-NORMALIZE-REJECTS PERFORM T-LOOKUP-SUCCESS PERFORM T-GEO-PRECISE PERFORM T-GEO-CITY-WIDE PERFORM T-GEO-MALFORMED PERFORM T-UNKNOWN-FIELDS PERFORM T-LONG-VALUE-FLAGGED PERFORM T-NOT-FOUND PERFORM T-NOT-FOUND-NOT-RETRIED PERFORM T-INVALID-NEVER-LEAVES PERFORM T-API-400 PERFORM T-NOT-JSON PERFORM T-RETRY-THEN-SUCCESS PERFORM T-RETRY-EXHAUSTED PERFORM T-ONE-ATTEMPT-NO-RETRY PERFORM T-RATE-LIMITED PERFORM T-RETRY-AFTER-CAPPED PERFORM T-RETRY-AFTER-HTTP-DATE PERFORM T-NETWORK-ERROR PERFORM T-TOTAL-TIMEOUT PERFORM T-BATCH-ORDER PERFORM T-BATCH-QUOTING PERFORM T-BATCH-MALFORMED-ENTRY PERFORM T-BATCH-EMPTY PERFORM T-BATCH-TRUNCATED PERFORM T-BATCH-CHUNKING PERFORM T-BATCH-OVER-CAPACITY PERFORM T-HEALTH PERFORM T-HEALTH-DEGRADED PERFORM T-TRAILING-SLASH PERFORM T-DEFAULT-USER-AGENT DISPLAY " " DISPLAY WS-CHECKS " checks, " WS-FAILURES " failed" IF WS-FAILURES > 0 MOVE 1 TO RETURN-CODE ELSE MOVE 0 TO RETURN-CODE END-IF STOP RUN. *> =================================================================== *> Fixtures *> =================================================================== FRESH-CONFIG. CALL "CEPIS-DEFAULT-CONFIG" USING CEPIS-CONFIG MOVE WS-BASE TO CFG-BASE-URL MOVE 5000 TO CFG-TIMEOUT-MS MOVE 3 TO CFG-MAX-ATTEMPTS MOVE 1 TO CFG-BACKOFF-BASE-MS MOVE 10 TO CFG-BACKOFF-MAX-MS MOVE 0 TO CFG-TOTAL-TIMEOUT-MS. CHECK. ADD 1 TO WS-CHECKS IF WS-OK = "Y" DISPLAY "ok " WS-LABEL ELSE ADD 1 TO WS-FAILURES DISPLAY "FAIL " WS-LABEL " -- " FUNCTION TRIM (WS-DETAIL) END-IF MOVE SPACES TO WS-DETAIL MOVE "N" TO WS-OK. *> The fake server counts requests per path; that is how a 404 not being *> retried, or 501 CEPs becoming two requests, is proved rather than *> assumed. COUNT-FOR. PERFORM FRESH-CONFIG MOVE 1 TO CFG-MAX-ATTEMPTS MOVE SPACES TO HTTPQ-PATH STRING "/count?path=" FUNCTION TRIM (WS-COUNT-PATH) DELIMITED BY SIZE INTO HTTPQ-PATH END-STRING COMPUTE HTTPQ-PATH-LEN = 12 + FUNCTION LENGTH (FUNCTION TRIM (WS-COUNT-PATH)) MOVE "N" TO HTTPQ-ALLOW-503 MOVE 0 TO WS-COUNT CALL "CEPIS-REQUEST" USING CEPIS-CONFIG CEPIS-HTTP-REQUEST CEPIS-HTTP-RESPONSE CEPIS-STATUS END-CALL IF CEPIS-OK AND HTTP-BODY-LEN > 0 COMPUTE WS-COUNT = FUNCTION NUMVAL (HTTP-BODY (1:HTTP-BODY-LEN)) END-IF. *> =================================================================== *> Local validation *> =================================================================== T-NORMALIZE-ACCEPTS. PERFORM VARYING WS-I FROM 1 BY 1 UNTIL WS-I > 4 MOVE WS-GOOD (WS-I) TO CEPIS-CEP-INPUT CALL "CEPIS-NORMALIZE-CEP" USING CEPIS-CEP-INPUT CEPIS-CEP CEPIS-STATUS END-CALL MOVE "N" TO WS-OK IF CEPIS-OK AND CEPIS-CEP = "01001000" MOVE "Y" TO WS-OK END-IF MOVE SPACES TO WS-LABEL STRING "normalize accepts " WS-GOOD (WS-I) DELIMITED BY SIZE INTO WS-LABEL END-STRING MOVE CEPIS-CEP TO WS-DETAIL PERFORM CHECK END-PERFORM. T-NORMALIZE-REJECTS. PERFORM VARYING WS-I FROM 1 BY 1 UNTIL WS-I > 5 MOVE WS-BAD (WS-I) TO CEPIS-CEP-INPUT CALL "CEPIS-NORMALIZE-CEP" USING CEPIS-CEP-INPUT CEPIS-CEP CEPIS-STATUS END-CALL MOVE "N" TO WS-OK IF CEPIS-INVALID-CEP AND CEPIS-CEP = SPACES MOVE "Y" TO WS-OK END-IF MOVE SPACES TO WS-LABEL STRING "normalize rejects '" WS-BAD (WS-I) "'" DELIMITED BY SIZE INTO WS-LABEL END-STRING MOVE CEPIS-STATUS-MESSAGE TO WS-DETAIL PERFORM CHECK END-PERFORM. *> =================================================================== *> Single lookup *> =================================================================== T-LOOKUP-SUCCESS. PERFORM FRESH-CONFIG MOVE "01001-000" TO CEPIS-CEP-INPUT CALL "CEPIS-LOOKUP" USING CEPIS-CONFIG CEPIS-CEP-INPUT CEPIS-ADDRESS CEPIS-STATUS END-CALL MOVE "N" TO WS-OK IF CEPIS-OK AND ADDR-LOCALIDADE = "São Paulo" AND ADDR-UF = "SP" AND ADDR-LOGRADOURO = "Praça da Sé" AND ADDR-IBGE = "3550308" AND ADDR-CEP-MASKED = "01001-000" AND ADDR-GEO-ABSENT AND ADDR-NOT-TRUNCATED MOVE "Y" TO WS-OK END-IF MOVE "lookup returns the address, masked cep, no geo" TO WS-LABEL MOVE CEPIS-STATUS-MESSAGE TO WS-DETAIL PERFORM CHECK. T-GEO-PRECISE. PERFORM FRESH-CONFIG MOVE "01310100" TO CEPIS-CEP-INPUT CALL "CEPIS-LOOKUP" USING CEPIS-CONFIG CEPIS-CEP-INPUT CEPIS-ADDRESS CEPIS-STATUS END-CALL MOVE "N" TO WS-OK IF CEPIS-OK AND ADDR-GEO-KNOWN AND ADDR-GEO-PRECISE AND ADDR-GEO-RAIO-M = 120 AND ADDR-GEO-LAT < -23.5 AND ADDR-GEO-LAT > -23.6 AND ADDR-GEO-LON < -46.6 AND ADDR-GEO-LON > -46.7 MOVE "Y" TO WS-OK END-IF MOVE "geo present is read and reports precisao logradouro" TO WS-LABEL PERFORM CHECK. T-GEO-CITY-WIDE. PERFORM FRESH-CONFIG MOVE "01001001" TO CEPIS-CEP-INPUT CALL "CEPIS-LOOKUP" USING CEPIS-CONFIG CEPIS-CEP-INPUT CEPIS-ADDRESS CEPIS-STATUS END-CALL MOVE "N" TO WS-OK IF CEPIS-OK AND ADDR-GEO-KNOWN AND ADDR-GEO-CITY-WIDE AND NOT ADDR-GEO-PRECISE AND ADDR-GEO-RAIO-M = 22000 MOVE "Y" TO WS-OK END-IF MOVE "a municipality centroid is not precise" TO WS-LABEL PERFORM CHECK. T-GEO-MALFORMED. PERFORM FRESH-CONFIG MOVE "01001002" TO CEPIS-CEP-INPUT CALL "CEPIS-LOOKUP" USING CEPIS-CONFIG CEPIS-CEP-INPUT CEPIS-ADDRESS CEPIS-STATUS END-CALL MOVE "N" TO WS-OK IF CEPIS-OK AND ADDR-GEO-ABSENT AND ADDR-LOCALIDADE = "São Paulo" MOVE "Y" TO WS-OK END-IF MOVE "a malformed geo does not lose the address" TO WS-LABEL PERFORM CHECK. T-UNKNOWN-FIELDS. PERFORM FRESH-CONFIG MOVE "01001003" TO CEPIS-CEP-INPUT CALL "CEPIS-LOOKUP" USING CEPIS-CONFIG CEPIS-CEP-INPUT CEPIS-ADDRESS CEPIS-STATUS END-CALL MOVE "N" TO WS-OK IF CEPIS-OK AND ADDR-LOCALIDADE = "São Paulo" AND ADDR-GEO-ABSENT MOVE "Y" TO WS-OK END-IF MOVE "fields the client does not know are ignored" TO WS-LABEL MOVE CEPIS-STATUS-MESSAGE TO WS-DETAIL PERFORM CHECK. T-LONG-VALUE-FLAGGED. PERFORM FRESH-CONFIG MOVE "01001010" TO CEPIS-CEP-INPUT CALL "CEPIS-LOOKUP" USING CEPIS-CONFIG CEPIS-CEP-INPUT CEPIS-ADDRESS CEPIS-STATUS END-CALL MOVE "N" TO WS-OK IF CEPIS-OK AND ADDR-WAS-TRUNCATED MOVE "Y" TO WS-OK END-IF MOVE "a value past the field width sets ADDR-TRUNCATED" TO WS-LABEL PERFORM CHECK. T-NOT-FOUND. PERFORM FRESH-CONFIG MOVE "99999999" TO CEPIS-CEP-INPUT CALL "CEPIS-LOOKUP" USING CEPIS-CONFIG CEPIS-CEP-INPUT CEPIS-ADDRESS CEPIS-STATUS END-CALL MOVE "N" TO WS-OK IF CEPIS-NOT-FOUND AND ADDR-LOCALIDADE = SPACES MOVE "Y" TO WS-OK END-IF MOVE "a missing CEP is CEPIS-NOT-FOUND" TO WS-LABEL MOVE CEPIS-STATUS-MESSAGE TO WS-DETAIL PERFORM CHECK. T-NOT-FOUND-NOT-RETRIED. MOVE "/99999999" TO WS-COUNT-PATH PERFORM COUNT-FOR MOVE "N" TO WS-OK IF WS-COUNT = 1 MOVE "Y" TO WS-OK END-IF MOVE "404 is definitive and is not retried" TO WS-LABEL MOVE SPACES TO WS-DETAIL STRING "requests: " WS-COUNT DELIMITED BY SIZE INTO WS-DETAIL END-STRING PERFORM CHECK. T-INVALID-NEVER-LEAVES. PERFORM FRESH-CONFIG MOVE "123" TO CEPIS-CEP-INPUT CALL "CEPIS-LOOKUP" USING CEPIS-CONFIG CEPIS-CEP-INPUT CEPIS-ADDRESS CEPIS-STATUS END-CALL MOVE "N" TO WS-OK IF CEPIS-INVALID-CEP MOVE "Y" TO WS-OK END-IF MOVE "/123" TO WS-COUNT-PATH PERFORM COUNT-FOR IF WS-COUNT NOT = 0 MOVE "N" TO WS-OK END-IF MOVE "a malformed CEP never leaves the machine" TO WS-LABEL PERFORM CHECK. T-API-400. PERFORM FRESH-CONFIG MOVE "00000000" TO CEPIS-CEP-INPUT CALL "CEPIS-LOOKUP" USING CEPIS-CONFIG CEPIS-CEP-INPUT CEPIS-ADDRESS CEPIS-STATUS END-CALL MOVE 0 TO WS-TALLY INSPECT CEPIS-STATUS-MESSAGE TALLYING WS-TALLY FOR ALL "rejected by the API" MOVE "N" TO WS-OK IF CEPIS-INVALID-CEP AND WS-TALLY = 1 MOVE "Y" TO WS-OK END-IF MOVE "an API 400 carries the API's own message" TO WS-LABEL MOVE CEPIS-STATUS-MESSAGE TO WS-DETAIL PERFORM CHECK. T-NOT-JSON. PERFORM FRESH-CONFIG MOVE "01001004" TO CEPIS-CEP-INPUT CALL "CEPIS-LOOKUP" USING CEPIS-CONFIG CEPIS-CEP-INPUT CEPIS-ADDRESS CEPIS-STATUS END-CALL MOVE "N" TO WS-OK IF CEPIS-INVALID-RESPONSE MOVE "Y" TO WS-OK END-IF MOVE "a body that is not JSON is CEPIS-INVALID-RESPONSE" TO WS-LABEL MOVE CEPIS-STATUS-MESSAGE TO WS-DETAIL PERFORM CHECK. *> =================================================================== *> Retrying *> =================================================================== T-RETRY-THEN-SUCCESS. PERFORM FRESH-CONFIG MOVE "01001005" TO CEPIS-CEP-INPUT CALL "CEPIS-LOOKUP" USING CEPIS-CONFIG CEPIS-CEP-INPUT CEPIS-ADDRESS CEPIS-STATUS END-CALL MOVE "N" TO WS-OK IF CEPIS-OK AND ADDR-LOCALIDADE = "São Paulo" MOVE "Y" TO WS-OK END-IF MOVE "/01001005" TO WS-COUNT-PATH PERFORM COUNT-FOR IF WS-COUNT NOT = 2 MOVE "N" TO WS-OK END-IF MOVE "500 is retried and the second attempt succeeds" TO WS-LABEL MOVE SPACES TO WS-DETAIL STRING "requests: " WS-COUNT DELIMITED BY SIZE INTO WS-DETAIL END-STRING PERFORM CHECK. T-RETRY-EXHAUSTED. PERFORM FRESH-CONFIG MOVE "01001006" TO CEPIS-CEP-INPUT CALL "CEPIS-LOOKUP" USING CEPIS-CONFIG CEPIS-CEP-INPUT CEPIS-ADDRESS CEPIS-STATUS END-CALL MOVE "N" TO WS-OK IF CEPIS-SERVER-ERROR AND CEPIS-STATUS-HTTP = 503 AND CEPIS-STATUS-ATTEMPTS = 3 MOVE "Y" TO WS-OK END-IF MOVE "/01001006" TO WS-COUNT-PATH PERFORM COUNT-FOR IF WS-COUNT NOT = 3 MOVE "N" TO WS-OK END-IF MOVE "three attempts, then CEPIS-SERVER-ERROR" TO WS-LABEL MOVE SPACES TO WS-DETAIL STRING "requests: " WS-COUNT DELIMITED BY SIZE INTO WS-DETAIL END-STRING PERFORM CHECK. T-ONE-ATTEMPT-NO-RETRY. PERFORM FRESH-CONFIG MOVE 1 TO CFG-MAX-ATTEMPTS MOVE "01001012" TO CEPIS-CEP-INPUT CALL "CEPIS-LOOKUP" USING CEPIS-CONFIG CEPIS-CEP-INPUT CEPIS-ADDRESS CEPIS-STATUS END-CALL MOVE "N" TO WS-OK IF CEPIS-SERVER-ERROR MOVE "Y" TO WS-OK END-IF MOVE "/01001012" TO WS-COUNT-PATH PERFORM COUNT-FOR IF WS-COUNT NOT = 1 MOVE "N" TO WS-OK END-IF MOVE "CFG-MAX-ATTEMPTS of 1 disables retrying" TO WS-LABEL PERFORM CHECK. T-RATE-LIMITED. PERFORM FRESH-CONFIG MOVE "01001007" TO CEPIS-CEP-INPUT CALL "CEPIS-LOOKUP" USING CEPIS-CONFIG CEPIS-CEP-INPUT CEPIS-ADDRESS CEPIS-STATUS END-CALL MOVE "N" TO WS-OK IF CEPIS-RATE-LIMITED AND CEPIS-STATUS-RETRY-AFTER-MS = 7000 MOVE "Y" TO WS-OK END-IF MOVE "429 exposes Retry-After in seconds" TO WS-LABEL MOVE SPACES TO WS-DETAIL STRING "retry-after ms: " CEPIS-STATUS-RETRY-AFTER-MS DELIMITED BY SIZE INTO WS-DETAIL END-STRING PERFORM CHECK. T-RETRY-AFTER-CAPPED. PERFORM FRESH-CONFIG MOVE "01001008" TO CEPIS-CEP-INPUT CALL "cepis_monotonic_ms" USING WS-T0 CALL "CEPIS-LOOKUP" USING CEPIS-CONFIG CEPIS-CEP-INPUT CEPIS-ADDRESS CEPIS-STATUS END-CALL CALL "cepis_monotonic_ms" USING WS-T1 COMPUTE WS-ELAPSED = WS-T1 - WS-T0 MOVE "N" TO WS-OK IF CEPIS-RATE-LIMITED AND WS-ELAPSED < 3000 MOVE "Y" TO WS-OK END-IF MOVE "an absurd Retry-After is capped at the backoff maximum" TO WS-LABEL MOVE SPACES TO WS-DETAIL STRING "elapsed ms: " WS-ELAPSED DELIMITED BY SIZE INTO WS-DETAIL END-STRING PERFORM CHECK. T-RETRY-AFTER-HTTP-DATE. PERFORM FRESH-CONFIG MOVE "01001009" TO CEPIS-CEP-INPUT CALL "CEPIS-LOOKUP" USING CEPIS-CONFIG CEPIS-CEP-INPUT CEPIS-ADDRESS CEPIS-STATUS END-CALL MOVE "N" TO WS-OK IF CEPIS-RATE-LIMITED AND CEPIS-STATUS-RETRY-AFTER-MS >= 1000 AND CEPIS-STATUS-RETRY-AFTER-MS <= 8000 MOVE "Y" TO WS-OK END-IF MOVE "Retry-After is also read as an HTTP date" TO WS-LABEL MOVE SPACES TO WS-DETAIL STRING "retry-after ms: " CEPIS-STATUS-RETRY-AFTER-MS DELIMITED BY SIZE INTO WS-DETAIL END-STRING PERFORM CHECK. T-NETWORK-ERROR. PERFORM FRESH-CONFIG MOVE "http://127.0.0.1:1" TO CFG-BASE-URL MOVE 2 TO CFG-MAX-ATTEMPTS MOVE 1000 TO CFG-TIMEOUT-MS MOVE "01001000" TO CEPIS-CEP-INPUT CALL "CEPIS-LOOKUP" USING CEPIS-CONFIG CEPIS-CEP-INPUT CEPIS-ADDRESS CEPIS-STATUS END-CALL MOVE "N" TO WS-OK IF CEPIS-NETWORK-ERROR AND CEPIS-STATUS-ATTEMPTS = 2 MOVE "Y" TO WS-OK END-IF MOVE "a refused connection is CEPIS-NETWORK-ERROR" TO WS-LABEL MOVE CEPIS-STATUS-MESSAGE TO WS-DETAIL PERFORM CHECK. T-TOTAL-TIMEOUT. PERFORM FRESH-CONFIG MOVE 50 TO CFG-MAX-ATTEMPTS MOVE 50 TO CFG-BACKOFF-BASE-MS MOVE 50 TO CFG-BACKOFF-MAX-MS MOVE 300 TO CFG-TOTAL-TIMEOUT-MS MOVE "01001011" TO CEPIS-CEP-INPUT CALL "cepis_monotonic_ms" USING WS-T0 CALL "CEPIS-LOOKUP" USING CEPIS-CONFIG CEPIS-CEP-INPUT CEPIS-ADDRESS CEPIS-STATUS END-CALL CALL "cepis_monotonic_ms" USING WS-T1 COMPUTE WS-ELAPSED = WS-T1 - WS-T0 MOVE CEPIS-STATUS-ATTEMPTS TO WS-SAVED-ATTEMPTS MOVE "N" TO WS-OK IF CEPIS-SERVER-ERROR AND WS-ELAPSED < 3000 AND WS-SAVED-ATTEMPTS < 50 MOVE "Y" TO WS-OK END-IF MOVE "CFG-TOTAL-TIMEOUT-MS bounds the whole call" TO WS-LABEL MOVE SPACES TO WS-DETAIL STRING "elapsed ms: " WS-ELAPSED " attempts: " WS-SAVED-ATTEMPTS DELIMITED BY SIZE INTO WS-DETAIL END-STRING PERFORM CHECK. *> =================================================================== *> Batch *> =================================================================== T-BATCH-ORDER. PERFORM FRESH-CONFIG MOVE 3 TO BATCH-COUNT MOVE "01001000" TO BATCH-REQUESTED (1) MOVE "99999999" TO BATCH-REQUESTED (2) MOVE "20040020" TO BATCH-REQUESTED (3) CALL "CEPIS-LOOKUP-MANY" USING CEPIS-CONFIG CEPIS-BATCH CEPIS-STATUS END-CALL MOVE "N" TO WS-OK IF CEPIS-OK AND BATCH-ENTRY-FOUND (1) AND BAT-LOCALIDADE (1) = "São Paulo" AND BATCH-ENTRY-MISSING (2) AND BATCH-ENTRY-FOUND (3) AND BAT-UF (3) = "RJ" AND BAT-GEO-ABSENT (1) MOVE "Y" TO WS-OK END-IF MOVE "a missing CEP keeps its slot and nothing shifts" TO WS-LABEL MOVE CEPIS-STATUS-MESSAGE TO WS-DETAIL PERFORM CHECK. T-BATCH-QUOTING. PERFORM FRESH-CONFIG MOVE 1 TO BATCH-COUNT MOVE "01001111" TO BATCH-REQUESTED (1) CALL "CEPIS-LOOKUP-MANY" USING CEPIS-CONFIG CEPIS-BATCH CEPIS-STATUS END-CALL MOVE "N" TO WS-OK IF CEPIS-OK AND BATCH-ENTRY-FOUND (1) AND BAT-LOGRADOURO (1) = "Rua Um, Dois" AND BAT-COMPLEMENTO (1) = 'aspas "aqui"' MOVE "Y" TO WS-OK END-IF MOVE "quoted CSV fields with commas and quotes are parsed" TO WS-LABEL MOVE BAT-LOGRADOURO (1) TO WS-DETAIL PERFORM CHECK. T-BATCH-MALFORMED-ENTRY. PERFORM FRESH-CONFIG MOVE 3 TO BATCH-COUNT MOVE "01001000" TO BATCH-REQUESTED (1) MOVE "nonsense" TO BATCH-REQUESTED (2) MOVE "20040020" TO BATCH-REQUESTED (3) CALL "CEPIS-LOOKUP-MANY" USING CEPIS-CONFIG CEPIS-BATCH CEPIS-STATUS END-CALL MOVE "N" TO WS-OK IF CEPIS-OK AND BATCH-ENTRY-FOUND (1) AND BATCH-ENTRY-MISSING (2) AND BATCH-ENTRY-FOUND (3) AND BAT-UF (3) = "RJ" MOVE "Y" TO WS-OK END-IF MOVE "a malformed CEP is missing, not an error" TO WS-LABEL PERFORM CHECK. T-BATCH-EMPTY. MOVE "/csv" TO WS-COUNT-PATH PERFORM COUNT-FOR MOVE WS-COUNT TO WS-COUNT-BEFORE PERFORM FRESH-CONFIG MOVE 0 TO BATCH-COUNT CALL "CEPIS-LOOKUP-MANY" USING CEPIS-CONFIG CEPIS-BATCH CEPIS-STATUS END-CALL MOVE "N" TO WS-OK IF CEPIS-OK MOVE "Y" TO WS-OK END-IF MOVE "/csv" TO WS-COUNT-PATH PERFORM COUNT-FOR IF WS-COUNT NOT = WS-COUNT-BEFORE MOVE "N" TO WS-OK END-IF MOVE "an empty batch makes no request" TO WS-LABEL PERFORM CHECK. T-BATCH-TRUNCATED. PERFORM FRESH-CONFIG MOVE 2 TO BATCH-COUNT MOVE "01001000" TO BATCH-REQUESTED (1) MOVE "00000099" TO BATCH-REQUESTED (2) CALL "CEPIS-LOOKUP-MANY" USING CEPIS-CONFIG CEPIS-BATCH CEPIS-STATUS END-CALL MOVE "N" TO WS-OK IF CEPIS-OK AND BATCH-ENTRY-FOUND (1) AND BATCH-ENTRY-MISSING (2) MOVE "Y" TO WS-OK END-IF MOVE "a short response pads rather than shifts" TO WS-LABEL PERFORM CHECK. T-BATCH-CHUNKING. MOVE "/csv" TO WS-COUNT-PATH PERFORM COUNT-FOR MOVE WS-COUNT TO WS-COUNT-BEFORE PERFORM FRESH-CONFIG MOVE 501 TO BATCH-COUNT PERFORM VARYING WS-I FROM 1 BY 1 UNTIL WS-I > 501 COMPUTE WS-NUM8 = 70000000 + WS-I MOVE WS-NUM8 TO BATCH-REQUESTED (WS-I) END-PERFORM CALL "CEPIS-LOOKUP-MANY" USING CEPIS-CONFIG CEPIS-BATCH CEPIS-STATUS END-CALL MOVE "N" TO WS-OK IF CEPIS-OK AND BATCH-ENTRY-FOUND (1) AND BATCH-ENTRY-FOUND (500) AND BATCH-ENTRY-FOUND (501) AND BAT-LOCALIDADE (501) = "Cidade Sintetica" MOVE "Y" TO WS-OK END-IF MOVE "/csv" TO WS-COUNT-PATH PERFORM COUNT-FOR COMPUTE WS-COUNT = WS-COUNT - WS-COUNT-BEFORE IF WS-COUNT NOT = 2 MOVE "N" TO WS-OK END-IF MOVE "501 CEPs become two requests, not one 400" TO WS-LABEL MOVE SPACES TO WS-DETAIL STRING "requests: " WS-COUNT " status: " CEPIS-STATUS-MESSAGE DELIMITED BY SIZE INTO WS-DETAIL END-STRING PERFORM CHECK. T-BATCH-OVER-CAPACITY. PERFORM FRESH-CONFIG MOVE 1001 TO BATCH-COUNT CALL "CEPIS-LOOKUP-MANY" USING CEPIS-CONFIG CEPIS-BATCH CEPIS-STATUS END-CALL MOVE "N" TO WS-OK IF CEPIS-INVALID-CEP MOVE "Y" TO WS-OK END-IF MOVE 0 TO BATCH-COUNT MOVE "a BATCH-COUNT past the table is refused, not truncated" TO WS-LABEL MOVE CEPIS-STATUS-MESSAGE TO WS-DETAIL PERFORM CHECK. *> =================================================================== *> Health and configuration *> =================================================================== T-HEALTH. PERFORM FRESH-CONFIG CALL "CEPIS-HEALTH" USING CEPIS-CONFIG CEPIS-HEALTH CEPIS-STATUS END-CALL MOVE "N" TO WS-OK IF CEPIS-OK AND HEALTH-OK AND HEALTH-DNE = "26071" AND HEALTH-CEPS = 1596168 AND HEALTH-GEO = 894489 AND HEALTH-BASE-GERADA-EM = "2026-07-24T03:48:28Z" MOVE "Y" TO WS-OK END-IF MOVE "health reports the live database" TO WS-LABEL MOVE CEPIS-STATUS-MESSAGE TO WS-DETAIL PERFORM CHECK. T-HEALTH-DEGRADED. PERFORM FRESH-CONFIG MOVE SPACES TO CFG-BASE-URL STRING FUNCTION TRIM (WS-BASE) "/degraded" DELIMITED BY SIZE INTO CFG-BASE-URL END-STRING CALL "CEPIS-HEALTH" USING CEPIS-CONFIG CEPIS-HEALTH CEPIS-STATUS END-CALL MOVE "N" TO WS-OK IF CEPIS-OK AND NOT HEALTH-OK AND HEALTH-STATUS = "degradado" AND CEPIS-STATUS-ATTEMPTS = 1 MOVE "Y" TO WS-OK END-IF MOVE "a degraded API is diagnosed, not retried" TO WS-LABEL MOVE HEALTH-STATUS TO WS-DETAIL PERFORM CHECK. T-TRAILING-SLASH. PERFORM FRESH-CONFIG MOVE SPACES TO CFG-BASE-URL STRING FUNCTION TRIM (WS-BASE) "/" DELIMITED BY SIZE INTO CFG-BASE-URL END-STRING MOVE "01001000" TO CEPIS-CEP-INPUT CALL "CEPIS-LOOKUP" USING CEPIS-CONFIG CEPIS-CEP-INPUT CEPIS-ADDRESS CEPIS-STATUS END-CALL MOVE "N" TO WS-OK IF CEPIS-OK AND ADDR-UF = "SP" MOVE "Y" TO WS-OK END-IF MOVE "a trailing slash on the base URL is dropped" TO WS-LABEL MOVE CEPIS-STATUS-MESSAGE TO WS-DETAIL PERFORM CHECK. T-DEFAULT-USER-AGENT. CALL "CEPIS-DEFAULT-CONFIG" USING CEPIS-CONFIG MOVE 0 TO WS-TALLY INSPECT CFG-USER-AGENT TALLYING WS-TALLY FOR ALL "cepis-cobol/0.1.0" MOVE "N" TO WS-OK IF WS-TALLY = 1 AND CFG-BASE-URL = "https://cep.is" AND CFG-MAX-ATTEMPTS = 3 AND CFG-BACKOFF-BASE-MS = 500 AND CFG-BACKOFF-MAX-MS = 8000 MOVE "Y" TO WS-OK END-IF MOVE "the defaults identify the library and its version" TO WS-LABEL MOVE CFG-USER-AGENT TO WS-DETAIL PERFORM CHECK. END PROGRAM CEPIS-TESTS.