Core 7.0.3 fills outstatus.errmsg on both platforms - the SASJS branch since 7.0.2, the Viya branch from the job result as of 7.0.3 - so a canceled call now always carries the reason it was canceled. That removes the last platform difference from the assertion: while Viya wrote a blank errmsg, an expected message could only be checked on one platform and the state alone had to stand in on the other. A comparison against a message that was never recorded now fails instead of passing silently, which is the point of asking for it.
289 lines
7.0 KiB
SAS
289 lines
7.0 KiB
SAS
/**
|
|
@file
|
|
@brief testing the mpe_assert_abort macro
|
|
|
|
@details The macro decides PASS/FAIL from the child's status row - STATE says
|
|
whether the child was canceled, ERRMSG holds the reason - so the cases can be
|
|
built as datasets instead of services: an abort with the expected message, an
|
|
abort with a different one, a completed call, a status dataset that does not
|
|
exist, a message past the old 256 character width, quotes, backslashes, and
|
|
the log extract that mp_abort appends to the message.
|
|
|
|
Each case asserts on the PASS/FAIL the macro recorded, so a regression in the
|
|
comparison fails here rather than silently passing an abort assertion in a
|
|
service test.
|
|
|
|
<h4> SAS Macros </h4>
|
|
@li mp_assert.sas
|
|
@li mpe_assert_abort.sas
|
|
|
|
@author 4GL Apps Ltd
|
|
@copyright 4GL Apps Ltd. This code may only be used within Data Controller
|
|
and may not be re-distributed or re-sold without the express permission of
|
|
4GL Apps Ltd.
|
|
|
|
**/
|
|
|
|
/** a status row as %mpe_execute leaves it: the job state and the message */
|
|
%macro mk_status(ds, state, msg);
|
|
/* the values come from the symbol table rather than from quoted text: a
|
|
message holding double quotes would otherwise end the literal early */
|
|
data &ds;
|
|
length state $20 uri $256 errmsg $32767 platform $10;
|
|
state=symget('state');
|
|
uri='';
|
|
errmsg=symget('msg');
|
|
platform='SASJS';
|
|
run;
|
|
%mend mk_status;
|
|
|
|
/**
|
|
* Test 1 - an abort whose message matches is a PASS
|
|
*/
|
|
%mk_status(work.st1, canceled, Invalid libds)
|
|
|
|
%mpe_assert_abort(
|
|
desc=an abort with the expected MSG,
|
|
outstatus=work.st1,
|
|
msg=Invalid libds,
|
|
outds=work.rc1
|
|
)
|
|
|
|
/**
|
|
* Test 2 - an abort for a different reason is a FAIL
|
|
*/
|
|
%mk_status(work.st2, canceled, Invalid libds)
|
|
|
|
%mpe_assert_abort(
|
|
desc=an abort with a different MSG,
|
|
outstatus=work.st2,
|
|
msg=Invalid filter,
|
|
outds=work.rc2
|
|
)
|
|
|
|
/**
|
|
* Test 3 - a completed call is a FAIL
|
|
*/
|
|
%mk_status(work.st3, completed, )
|
|
|
|
%mpe_assert_abort(
|
|
desc=a completed call,
|
|
outstatus=work.st3,
|
|
msg=0,
|
|
outds=work.rc3
|
|
)
|
|
|
|
/**
|
|
* Test 4 - a status dataset that does not exist fails the assertion, not the step
|
|
*/
|
|
%mpe_assert_abort(
|
|
desc=a status dataset that was never written,
|
|
outstatus=work.doesnotexist,
|
|
msg=0,
|
|
outds=work.rc4
|
|
)
|
|
|
|
/**
|
|
* Test 5 - a message longer than the old capture width is compared in full
|
|
*
|
|
* The status row carries the whole message, so a caller comparing a long one
|
|
* gets an answer rather than a silent 256 character cut.
|
|
*/
|
|
%let longmsg=;
|
|
data work.st5;
|
|
length state $20 errmsg $32767;
|
|
state='canceled';
|
|
errmsg=repeat('a clause that runs on ',30);
|
|
call symputx('longmsg',errmsg,'l');
|
|
run;
|
|
|
|
%mpe_assert_abort(
|
|
desc=an abort with a message past the old capture width,
|
|
outstatus=work.st5,
|
|
msg=%superq(longmsg),
|
|
outds=work.rc5
|
|
)
|
|
|
|
/**
|
|
* Test 6 - quotes in the message survive
|
|
*/
|
|
%mk_status(work.st6, canceled, %str(alpha "quoted" beta))
|
|
|
|
%mpe_assert_abort(
|
|
desc=a message holding double quotes,
|
|
outstatus=work.st6,
|
|
msg=%str(alpha "quoted" beta),
|
|
outds=work.rc6
|
|
)
|
|
|
|
/**
|
|
* Test 7 - the log extract mp_abort appends is not part of the message
|
|
*/
|
|
data work.st7;
|
|
length state $20 errmsg $32767;
|
|
state='canceled';
|
|
errmsg=cats('Invalid libds','0A0A'x,'Log Extract:','0A0A'x,'NOTE: a log line');
|
|
run;
|
|
|
|
%mpe_assert_abort(
|
|
desc=an abort with the appended log extract,
|
|
outstatus=work.st7,
|
|
msg=Invalid libds,
|
|
outds=work.rc7
|
|
)
|
|
|
|
/**
|
|
* Test 8 - a message that itself mentions the marker is not cut at it
|
|
*
|
|
* Only the two newlines before the marker identify the appended extract; a
|
|
* message that merely says "Log Extract:" keeps its text.
|
|
*/
|
|
data work.st8;
|
|
length state $20 errmsg $32767;
|
|
state='canceled';
|
|
errmsg='check the hook Log Extract: is mentioned here';
|
|
run;
|
|
|
|
%mpe_assert_abort(
|
|
desc=a message containing the extract marker,
|
|
outstatus=work.st8,
|
|
msg=%str(check the hook Log Extract: is mentioned here),
|
|
outds=work.rc8
|
|
)
|
|
|
|
/**
|
|
* Test 9 - a canceled call with no message fails a comparison it cannot support
|
|
*
|
|
* Core fills errmsg on both platforms now, so a blank one means the reason was
|
|
* never recorded - an expected message cannot be proved, and the assertion
|
|
* says so rather than passing on the state alone.
|
|
*/
|
|
%mk_status(work.st9, canceled, )
|
|
|
|
%mpe_assert_abort(
|
|
desc=a canceled call whose status row carries no message,
|
|
outstatus=work.st9,
|
|
msg=Invalid libds,
|
|
outds=work.rc9
|
|
)
|
|
|
|
/**
|
|
* Test 10 - backslashes in the message compare as they were raised
|
|
*/
|
|
%mk_status(work.st10, canceled, %str(C:\temp\share))
|
|
|
|
%mpe_assert_abort(
|
|
desc=a message holding backslashes,
|
|
outstatus=work.st10,
|
|
msg=%str(C:\temp\share),
|
|
outds=work.rc10
|
|
)
|
|
|
|
/**
|
|
* Test 11 - the doubled separator the escaping producer writes
|
|
*
|
|
* mp_abort doubles backslashes, so the appended extract arrives as a literal
|
|
* doubled pair rather than as characters.
|
|
*/
|
|
data work.st11;
|
|
length state $20 errmsg $32767;
|
|
state='canceled';
|
|
errmsg=cats('Invalid libds','\\n\\nLog Extract:\\n','NOTE: a log line');
|
|
run;
|
|
|
|
%mpe_assert_abort(
|
|
desc=an abort whose extract arrives doubled,
|
|
outstatus=work.st11,
|
|
msg=Invalid libds,
|
|
outds=work.rc11
|
|
)
|
|
|
|
/**
|
|
* Test 12 - the recorded results
|
|
*/
|
|
|
|
%macro getres(ds, var);
|
|
data _null_;
|
|
set &ds;
|
|
call symputx("&var",test_result,'g');
|
|
run;
|
|
%mend getres;
|
|
|
|
%getres(work.rc1, res_any)
|
|
%getres(work.rc2, res_other)
|
|
%getres(work.rc3, res_none)
|
|
%getres(work.rc4, res_noref)
|
|
%getres(work.rc5, res_long)
|
|
%getres(work.rc6, res_quotes)
|
|
%getres(work.rc7, res_logmark)
|
|
%getres(work.rc8, res_marker)
|
|
%getres(work.rc9, res_nomsg)
|
|
%getres(work.rc10, res_bslash)
|
|
%getres(work.rc11, res_doubled)
|
|
|
|
%mp_assert(
|
|
iftrue=("&res_any"="PASS"),
|
|
desc=%str(Checking an abort with the expected MSG passes),
|
|
outds=work.test_results
|
|
)
|
|
|
|
%mp_assert(
|
|
iftrue=("&res_other"="FAIL"),
|
|
desc=%str(Checking an abort with a different MSG fails),
|
|
outds=work.test_results
|
|
)
|
|
|
|
%mp_assert(
|
|
iftrue=("&res_none"="FAIL"),
|
|
desc=%str(Checking a completed call fails),
|
|
outds=work.test_results
|
|
)
|
|
|
|
%mp_assert(
|
|
iftrue=("&res_noref"="FAIL"),
|
|
desc=%str(Checking a missing status dataset fails the assertion, not the step),
|
|
outds=work.test_results
|
|
)
|
|
|
|
%mp_assert(
|
|
iftrue=("&res_long"="PASS"),
|
|
desc=%str(Checking an abort message past the old capture width matches in full),
|
|
outds=work.test_results
|
|
)
|
|
|
|
%mp_assert(
|
|
iftrue=("&res_quotes"="PASS"),
|
|
desc=%str(Checking a message holding double quotes compares),
|
|
outds=work.test_results
|
|
)
|
|
|
|
%mp_assert(
|
|
iftrue=("&res_logmark"="PASS"),
|
|
desc=%str(Checking the appended log extract is stripped),
|
|
outds=work.test_results
|
|
)
|
|
|
|
%mp_assert(
|
|
iftrue=("&res_marker"="PASS"),
|
|
desc=%str(Checking a message containing the extract marker is not cut at it),
|
|
outds=work.test_results
|
|
)
|
|
|
|
%mp_assert(
|
|
iftrue=("&res_nomsg"="FAIL"),
|
|
desc=%str(Checking a canceled call with no message fails the comparison),
|
|
outds=work.test_results
|
|
)
|
|
|
|
%mp_assert(
|
|
iftrue=("&res_bslash"="PASS"),
|
|
desc=%str(Checking a message holding backslashes compares),
|
|
outds=work.test_results
|
|
)
|
|
|
|
%mp_assert(
|
|
iftrue=("&res_doubled"="PASS"),
|
|
desc=%str(Checking the doubled extract separator is stripped),
|
|
outds=work.test_results
|
|
)
|