test(derived): guard the getdata fixture, fix two harness faults, cover the RLS rejection
Build / Build-and-ng-test (pull_request) Successful in 5m57s
Lighthouse Checks / lighthouse (pull_request) Successful in 20m56s
Build / Build-and-test-development (pull_request) Successful in 32m39s

- getdata.test now checks the child job state before reading its outlib: a
  cancelled child returns no webout, so the previous call's members were being
  asserted against and the failures described the wrong problem.
- validatefilter.test's inputdatasets call needs a _PROGRAM column, which
  mx_execute reads to decide what to run - without it the job stopped at
  'The _PROGRAM column must exist'.
- stagedata.test.3 covers the new RLS check: an MPE_ROW_LEVEL_SECURITY rule
  naming a derived variable must be rejected at save time.
This commit is contained in:
dc committed 2026-10-21 17:59:49 +00:00
1 parent ccd468b335
commit c5a8de38b3
3 files changed
+113 -5

No files matched your search

+29 -5
View File
@@ -3,6 +3,7 @@
@brief testing gethistory service
<h4> SAS Macros </h4>
@li mp_assert.sas
@li mp_assertcols.sas
@li mp_assertcolvals.sas
@li mp_assertdsobs.sas
@@ -324,13 +325,36 @@ run;
mdebug=&sasjs_mdebug
)
data sasdata4;
set web4.sasdata;
run;
data cols4;
set web4.cols;
/* a cancelled child returns no webout, so the outlib keeps whatever an
earlier call left in it - check the job state before reading its members,
otherwise the assertion failures below describe the wrong problem */
%let abort4=0;
data _null_;
set work.results;
if state='canceled' then call symputx('abort4',1);
run;
%mp_assert(
iftrue=(&abort4=0),
desc=Test4 - the derived variable call completes,
outds=work.test_results
)
%if &abort4=0 %then %do;
data sasdata4;
set web4.sasdata;
run;
data cols4;
set web4.cols;
run;
%end;
%else %do;
data cols4;
length name $32;
stop;
run;
%end;
%mp_assertcols(work.cols4,
desc=Test4 - derived column is in the COLS payload,
cols=DERIVED_NOTE,
@@ -132,6 +132,88 @@ quit;
outds=work.test_results
)
/**
* Test 3 - an RLS rule naming a DERIVED variable must be rejected at save
* time: the rule is evaluated against the submitted data, where a derived
* column does not exist
*/
%let t3=%sysfunc(datetime());
/* define a derived variable on the target table */
proc sql noprint;
delete from &dc_libref..mpe_derived
where upcase(libref)='DCTEST' and upcase(dsn)='DC_REPLACE';
insert into &dc_libref..mpe_derived
set tx_from=0
,tx_to='31DEC5999:23:59:59'dt
,libref='DCTEST'
,dsn='DC_REPLACE'
,var_nm='DERIVED_X'
,var_deps='X'
,var_type='N'
,var_len=8
,var_fmt=''
,var_logic='X + 1'
,active=1;
quit;
data work.sascontroltable;
action='LOAD';
message='RLS rule on a derived variable should abort';
libds="&dc_libref..MPE_ROW_LEVEL_SECURITY";
output;
stop;
run;
data work.jsdata;
length RLS_SCOPE $8 RLS_GROUP $128 RLS_LIBREF $8 RLS_TABLE $32
RLS_GROUP_LOGIC $3 RLS_SUBGROUP_LOGIC $3 RLS_VARIABLE_NM $32
RLS_OPERATOR_NM $12 RLS_RAW_VALUE $4000
_____DELETE__THIS__RECORD_____ $3;
RLS_SCOPE='EDIT';
RLS_GROUP='SASAdministrators';
RLS_LIBREF='DCTEST';
RLS_TABLE='DC_REPLACE';
RLS_GROUP_LOGIC='AND';
RLS_SUBGROUP_LOGIC='OR';
RLS_SUBGROUP_ID=0;
RLS_VARIABLE_NM='DERIVED_X';
RLS_OPERATOR_NM='NE';
RLS_RAW_VALUE='1';
RLS_ACTIVE=1;
_____DELETE__THIS__RECORD_____='No';
output;
run;
%mx_execute(&_program,
viyacontext=&defaultcontext,
inputdatasets=work.sascontroltable work.jsdata,
outlib=web3,
outref=wb3,
mdebug=&sasjs_mdebug
)
%let abort3=0;
proc sql noprint;
select count(*) into: abort3
from &dc_libref..mpe_loads
where processed_dttm>&t3
and reason_txt="RLS rule on a derived variable should abort"
and upcase(status) ne 'SUCCESS';
quit;
%mp_assert(
iftrue=(&abort3>0),
desc=Checking an RLS rule on a derived variable is rejected,
outds=work.test_results
)
/* tidy up the derived configuration */
proc sql noprint;
delete from &dc_libref..mpe_derived
where upcase(libref)='DCTEST' and upcase(dsn)='DC_REPLACE';
quit;
/**
* Test 2 - applying REPLACE loadtype to a table with RLS EDIT security
* should abort. The active EDIT rule was inserted in the prep section,
@@ -48,6 +48,8 @@ run;
data work.iwant;
filter_table='DCTEST.DCFMTS-FC';
/* mx_execute reads the program to run from the input dataset */
_program="&_program";
run;
data work.filterquery;
GROUP_LOGIC='AND';