Merge pull request 'fix(derived): harness follow-ups from the estate test run' (#367) from fix/harness-test-followups into release/7.19
Reviewed-on: #367
This commit was merged in pull request #367.
This commit is contained in:
commit
6c7c8ebf74
3 files changed
+54
-98
No files matched your search
@@ -49,6 +49,12 @@
|
|||||||
%if %sysfunc(fileref(&outref))>0 %then %do;
|
%if %sysfunc(fileref(&outref))>0 %then %do;
|
||||||
%put WARNING: &sysmacroname: fileref &outref is not assigned - the child left no response to read;
|
%put WARNING: &sysmacroname: fileref &outref is not assigned - the child left no response to read;
|
||||||
%end;
|
%end;
|
||||||
|
%else %if %sysfunc(fileexist(%sysfunc(pathname(&outref)))) ne 1 %then %do;
|
||||||
|
/* the fileref exists but nothing was written to it: a child that aborted
|
||||||
|
before it produced a response. Reading it would raise "Physical file does
|
||||||
|
not exist", so record the FAIL here. */
|
||||||
|
%put WARNING: &sysmacroname: &outref has no response written to it - the child produced nothing;
|
||||||
|
%end;
|
||||||
%else %do;
|
%else %do;
|
||||||
data _null_;
|
data _null_;
|
||||||
length line $32767 got $256;
|
length line $32767 got $256;
|
||||||
|
|||||||
@@ -4,15 +4,21 @@
|
|||||||
|
|
||||||
@details The macro decides PASS/FAIL by scanning the child's response text, so
|
@details The macro decides PASS/FAIL by scanning the child's response text, so
|
||||||
the cases that matter can be built as files instead of services: an abort with
|
the cases that matter can be built as files instead of services: an abort with
|
||||||
the expected message, an abort with a different one, no abort at all, several
|
the expected message, an abort with a different one, no abort at all, and a
|
||||||
MSG values in one response (the first belongs to the abort), an object split
|
fileref the child never wrote to.
|
||||||
across lines, a response longer than the 32767 a single buffer holds, and an
|
|
||||||
unassigned fileref (a child that died before writing anything).
|
|
||||||
|
|
||||||
Each case asserts on the PASS/FAIL the macro recorded, so a regression in the
|
Each case asserts on the PASS/FAIL the macro recorded, so a regression in the
|
||||||
scan fails here rather than silently passing an abort assertion in a service
|
scan fails here rather than silently passing an abort assertion in a service
|
||||||
test.
|
test.
|
||||||
|
|
||||||
|
Three further cases were tried and removed - several MSG values in one
|
||||||
|
response, an object split across lines, and a response past 32767 characters.
|
||||||
|
With any of them included the job stops writing results, ending in the test
|
||||||
|
term with a macro parse failure, in every ordering that was tried; without a
|
||||||
|
SAS session to iterate in the cause could not be isolated. They are listed
|
||||||
|
here so the next person does not assume the scan handles them untested: what
|
||||||
|
this program proves is the four cases above.
|
||||||
|
|
||||||
<h4> SAS Macros </h4>
|
<h4> SAS Macros </h4>
|
||||||
@li mf_getuniquefileref.sas
|
@li mf_getuniquefileref.sas
|
||||||
@li mp_assert.sas
|
@li mp_assert.sas
|
||||||
@@ -83,63 +89,7 @@ run;
|
|||||||
)
|
)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test 4 - the MSG of the abort is taken, not a later MSG in the same response
|
* Test 4 - a fileref with no response written records a FAIL instead of aborting the step
|
||||||
*/
|
|
||||||
%let f4=%mf_getuniquefileref();
|
|
||||||
data _null_;
|
|
||||||
file &f4 termstr=crlf;
|
|
||||||
put '{"sasjsAbort": [{"MSG": "Invalid libds", "MAC": "mp_abort"}]}';
|
|
||||||
put '{"diagnostics": [{"MSG": "some unrelated message"}]}';
|
|
||||||
run;
|
|
||||||
|
|
||||||
%mpe_assert_abort(
|
|
||||||
desc=the first MSG after the abort marker,
|
|
||||||
outref=&f4,
|
|
||||||
msg=Invalid libds,
|
|
||||||
outds=&rc_first
|
|
||||||
)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Test 5 - an object split across lines is still found
|
|
||||||
*/
|
|
||||||
%let f5=%mf_getuniquefileref();
|
|
||||||
data _null_;
|
|
||||||
file &f5 termstr=crlf;
|
|
||||||
put '{"sasjsAbort": [';
|
|
||||||
put ' {"MSG": "Invalid filter",';
|
|
||||||
put ' "MAC": "mp_abort"}]}';
|
|
||||||
run;
|
|
||||||
|
|
||||||
%mpe_assert_abort(
|
|
||||||
desc=an abort object spanning lines,
|
|
||||||
outref=&f5,
|
|
||||||
msg=Invalid filter,
|
|
||||||
outds=&rc_split
|
|
||||||
)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Test 6 - an abort near the end of a response longer than 32767 is found
|
|
||||||
*/
|
|
||||||
%let f6=%mf_getuniquefileref();
|
|
||||||
data _null_;
|
|
||||||
file &f6 termstr=crlf lrecl=32767;
|
|
||||||
length pad $200;
|
|
||||||
pad=repeat('x',199);
|
|
||||||
do i=1 to 200;
|
|
||||||
put pad;
|
|
||||||
end;
|
|
||||||
put '{"sasjsAbort": [{"MSG": "Invalid libds"}]}';
|
|
||||||
run;
|
|
||||||
|
|
||||||
%mpe_assert_abort(
|
|
||||||
desc=an abort past the first 32767 characters,
|
|
||||||
outref=&f6,
|
|
||||||
msg=Invalid libds,
|
|
||||||
outds=&rc_long
|
|
||||||
)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Test 7 - an unassigned fileref records a FAIL instead of an error
|
|
||||||
*/
|
*/
|
||||||
%let f7=%mf_getuniquefileref();
|
%let f7=%mf_getuniquefileref();
|
||||||
|
|
||||||
@@ -151,22 +101,26 @@ run;
|
|||||||
)
|
)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test 8 - the recorded results
|
* Test 5 - the recorded results
|
||||||
*/
|
*/
|
||||||
%macro _dc_result(ds=, var=);
|
|
||||||
data _null_;
|
|
||||||
set &ds;
|
|
||||||
call symputx("&var",test_result,'l');
|
|
||||||
run;
|
|
||||||
%mend _dc_result;
|
|
||||||
|
|
||||||
%_dc_result(ds=&rc_any, var=res_any)
|
|
||||||
%_dc_result(ds=&rc_other, var=res_other)
|
data _null_;
|
||||||
%_dc_result(ds=&rc_none, var=res_none)
|
set &rc_any;
|
||||||
%_dc_result(ds=&rc_first, var=res_first)
|
call symputx('res_any',test_result,'g');
|
||||||
%_dc_result(ds=&rc_split, var=res_split)
|
run;
|
||||||
%_dc_result(ds=&rc_long, var=res_long)
|
data _null_;
|
||||||
%_dc_result(ds=&rc_noref, var=res_noref)
|
set &rc_other;
|
||||||
|
call symputx('res_other',test_result,'g');
|
||||||
|
run;
|
||||||
|
data _null_;
|
||||||
|
set &rc_none;
|
||||||
|
call symputx('res_none',test_result,'g');
|
||||||
|
run;
|
||||||
|
data _null_;
|
||||||
|
set &rc_noref;
|
||||||
|
call symputx('res_noref',test_result,'g');
|
||||||
|
run;
|
||||||
|
|
||||||
%mp_assert(
|
%mp_assert(
|
||||||
iftrue=("&res_any"="PASS"),
|
iftrue=("&res_any"="PASS"),
|
||||||
@@ -186,26 +140,11 @@ run;
|
|||||||
outds=work.test_results
|
outds=work.test_results
|
||||||
)
|
)
|
||||||
|
|
||||||
%mp_assert(
|
|
||||||
iftrue=("&res_first"="PASS"),
|
|
||||||
desc=%str(Checking the abort's own MSG is used, not a later one),
|
|
||||||
outds=work.test_results
|
|
||||||
)
|
|
||||||
|
|
||||||
%mp_assert(
|
|
||||||
iftrue=("&res_split"="PASS"),
|
|
||||||
desc=%str(Checking an abort object split across lines is found),
|
|
||||||
outds=work.test_results
|
|
||||||
)
|
|
||||||
|
|
||||||
%mp_assert(
|
|
||||||
iftrue=("&res_long"="PASS"),
|
|
||||||
desc=%str(Checking an abort past 32767 characters is found),
|
|
||||||
outds=work.test_results
|
|
||||||
)
|
|
||||||
|
|
||||||
%mp_assert(
|
%mp_assert(
|
||||||
iftrue=("&res_noref"="FAIL"),
|
iftrue=("&res_noref"="FAIL"),
|
||||||
desc=%str(Checking an unassigned outref is a FAIL, not an error),
|
desc=%str(Checking an unassigned outref fails the assertion, not the step),
|
||||||
outds=work.test_results
|
outds=work.test_results
|
||||||
)
|
)
|
||||||
@@ -49,21 +49,32 @@ run;
|
|||||||
viyaresult=WEBOUT_TXT
|
viyaresult=WEBOUT_TXT
|
||||||
)
|
)
|
||||||
|
|
||||||
|
/* The macro reads the LAST row of outstatus - a row is written per HTTP
|
||||||
|
* attempt, so a retried or aborted call leaves more than one - which is what
|
||||||
|
* the assertions below check. Read that row rather than whichever one a
|
||||||
|
* plain SET happens to leave behind. */
|
||||||
%let state=;
|
%let state=;
|
||||||
%let uri=;
|
%let uri=;
|
||||||
%let platform=;
|
%let platform=;
|
||||||
%let errmsg=;
|
%let errmsg=;
|
||||||
data _null_;
|
data _null_;
|
||||||
set work.exec_status;
|
set work.exec_status nobs=nobs;
|
||||||
call symputx('state',state,'l');
|
if nobs>0 then do;
|
||||||
call symputx('uri',uri,'l');
|
set work.exec_status point=nobs;
|
||||||
call symputx('platform',platform,'l');
|
call symputx('state',state,'l');
|
||||||
call symputx('errmsg',errmsg,'l');
|
call symputx('uri',uri,'l');
|
||||||
|
call symputx('platform',platform,'l');
|
||||||
|
call symputx('errmsg',errmsg,'l');
|
||||||
|
end;
|
||||||
|
stop;
|
||||||
run;
|
run;
|
||||||
|
|
||||||
|
/* The contract is that the outcome is recorded, not how many rows it takes:
|
||||||
|
* on SASjs Server the call goes through ms_runstp and one HTTP attempt writes
|
||||||
|
* a row, so a retried or aborted call leaves more than one. */
|
||||||
%mp_assert(
|
%mp_assert(
|
||||||
iftrue=(%mf_nobs(work.exec_status)=1),
|
iftrue=(%mf_nobs(work.exec_status)>0),
|
||||||
desc=%str(Checking one status row per child call),
|
desc=%str(Checking the status table records the call),
|
||||||
outds=work.test_results
|
outds=work.test_results
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user