/** @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

SAS Macros

@li mp_assert.sas **/ %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;