Files
dc/sas/sasjs/macros/mpe_assert_abort.sas
T
dc 33efc5ae1e
Build / Build-and-ng-test (pull_request) Successful in 5m42s
Lighthouse Checks / lighthouse (pull_request) Successful in 18m48s
Build / Build-and-test-development (pull_request) Failing after 13m0s
chore(lint): enforce an 80 character line and give the oversize files exact ceilings
sas/.sasjslint takes maxLineLength from 180 to 80 - the linter's own default -
and promotes it to "error".

53 of the 258 .sas files already hold a line longer than 80. Rewrapping them
would be a large, reviewable-only-in-theory diff, so each keeps its current
longest line as an exact ceiling via a per-file override, e.g.
@sasjslint {"maxLineLength": 95} in services/validations/tables_all.sas. A
file with no override is held to 80, and an overridden file cannot grow past
the length it has today: the ceiling is the file's longest line, not a round
number.

Both directions were checked: a 101 character line added to an
un-overridden file fails with "Line exceeds maximum length by 21 characters",
and a 114 character line added to macros/mpe_execute.sas (ceiling 101) fails
by 13. `npm run lint:sas` is clean with the setting in force.
2026-11-01 10:21:06 +00:00

88 lines
2.9 KiB
SAS

/**
@file
@brief Asserts that a service returned a sasjsAbort object
@details Reads the child's status row and records a PASS when the child was
canceled, which is what happens when a service rejects its input and calls
mp_abort. When msg is supplied the ERRMSG value must match it, so the
assertion proves the service aborted for the expected reason rather than for
any reason at all.
The message comes from the status row rather than from the response text: core
publishes STATE and ERRMSG per call, ERRMSG holds the whole message including
quotes and anything longer than a single record, and reading it needs no
parsing of the response.
Two things are handled here rather than in core:
- mp_abort appends cats(msg,'\n\nLog Extract:\n',logmsg) to the message, so
the tail is cut at the two newlines that precede the marker. A message that
merely mentions "Log Extract:" is not preceded by them and survives.
- a platform that reports no job state at all (SAS 9 PROC STP) cannot show the
abort this way; the row reads 'unknown' and the assertion fails rather than
guessing.
Usage:
%mpe_execute(&_program,
inputfiles=&f1:sascontroltable,
outstatus=work.ab1,
failfast=0
)
%mpe_assert_abort(
desc=An invalid libds aborts the service,
outstatus=work.ab1,
msg=Invalid libds
)
@param [in] desc The description recorded in the test results
@param [in] outstatus The dataset given to %mpe_execute, holding STATE and
ERRMSG for the child call
@param [in] msg= (0) Expected ERRMSG value. 0 accepts any abort message.
@param [out] outds= (work.test_results) Results dataset
<h4> SAS Macros </h4>
@li mp_assert.sas
@sasjslint {"maxLineLength": 94}
**/
%macro mpe_assert_abort(desc, outstatus, msg=0, outds=work.test_results);
%local ok seen abortseen;
%let ok=0;
%let seen=;
%let abortseen=0;
%if %sysfunc(exist(&outstatus)) ne 1 %then %do;
%put %str(WARN)ING: &sysmacroname: &outstatus does not exist - the child left no status row;
%end;
%else %do;
data _null_;
length got $32767;
set &outstatus;
if state='canceled' then call symputx('abortseen',1,'l');
got=errmsg;
/* mp_abort appends cats(msg,'\n\nLog Extract:\n',logmsg). Those newlines
reach here as characters, as an escaped pair, or as a doubled pair - which
one depends on the producer - so all three are tried */
cut=index(got,'0A0A'x||'Log Extract:');
if cut=0 then cut=index(got,'\n\nLog Extract:');
if cut=0 then cut=index(got,'\\n\\nLog Extract:');
if cut>1 then got=substr(got,1,cut-1);
call symputx('seen',got,'l');
run;
%end;
%if &abortseen=1 %then %do;
%if "%superq(msg)"="0" %then %let ok=1;
%else %if "%superq(seen)"="%superq(msg)" %then %let ok=1;
%end;
%if "%superq(seen)" ne "" %then %put NOTE: &sysmacroname: sasjsAbort MSG=&seen;
%mp_assert(
iftrue=(&ok=1),
desc=&desc,
outds=&outds
)
%mend mpe_assert_abort;