mirror of
https://github.com/sasjs/core.git
synced 2025-12-16 00:24:35 +00:00
Compare commits
53 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5f805b006f | ||
|
|
c6b65366b7 | ||
|
|
51ddd9c1e5 | ||
|
|
20bf3b86af | ||
|
|
de67cd329b | ||
|
|
779e4942c7 | ||
|
|
a69a1ac7f0 | ||
|
|
2a644d6c2b | ||
|
|
843930c666 | ||
|
|
90d69af7ee | ||
|
|
b7bafb49f4 | ||
|
|
2fa9e48286 | ||
|
|
5cee93c7bd | ||
|
|
1a595c64c6 | ||
|
|
2c901831b7 | ||
|
|
28209950ab | ||
|
|
44069e9867 | ||
|
|
e26af5c09a | ||
|
|
4ee13c9389 | ||
|
|
15f903aa42 | ||
|
|
58a0cce39e | ||
|
|
9a5574ea0e | ||
|
|
e6146dcbcf | ||
|
|
583c7e0c83 | ||
|
|
223bdd5983 | ||
|
|
aef14543f0 | ||
|
|
c88764c1d8 | ||
|
|
2c952c8b01 | ||
|
|
de3610d1aa | ||
|
|
d35d597437 | ||
|
|
3e8deda008 | ||
|
|
a27496c7b3 | ||
|
|
265389befc | ||
|
|
db2531e0b3 | ||
|
|
5e77494aa6 | ||
|
|
6a2ac51925 | ||
|
|
f625b04189 | ||
|
|
68aee776d3 | ||
|
|
38d2195d32 | ||
|
|
4e564b5409 | ||
|
|
298acc4e50 | ||
|
|
af98909753 | ||
|
|
b9d33b38bf | ||
|
|
b61b5f1856 | ||
|
|
805474bb46 | ||
|
|
61701f3c6a | ||
|
|
f20d7476bf | ||
|
|
04a3189a89 | ||
|
|
b1380983ec | ||
|
|
b4834f9b40 | ||
|
|
1b5ad93cad | ||
|
|
f2942f2032 | ||
|
|
4198448b81 |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -1,6 +1,7 @@
|
|||||||
node_modules
|
node_modules
|
||||||
.DS_Store
|
.DS_Store
|
||||||
sasjsbuild/
|
sasjsbuild/
|
||||||
|
sasjsresults/
|
||||||
|
|
||||||
# avoid filenames with spaces being committed to source control
|
# avoid filenames with spaces being committed to source control
|
||||||
**\ **
|
**\ **
|
||||||
|
|||||||
@@ -116,19 +116,19 @@ The **Macro Core** documentation is created using [doxygen](http://www.doxygen.n
|
|||||||
All macros must be commented in the doxygen format, to enable the [online documentation](https://core.sasjs.io).
|
All macros must be commented in the doxygen format, to enable the [online documentation](https://core.sasjs.io).
|
||||||
|
|
||||||
### Dependencies
|
### Dependencies
|
||||||
SAS code can contain one of two types of dependency - SAS Macros, and SAS Programs. When compiling projects using the [SASjs CLI](https://cli.sasjs.io) the doxygen header is scanned for ` @li` items under the following headers:
|
SAS code can contain one of two types of dependency - SAS Macros, and SAS Includes. When compiling projects using the [SASjs CLI](https://cli.sasjs.io) the doxygen header is scanned for ` @li` items under the following headers:
|
||||||
|
|
||||||
```sas
|
```sas
|
||||||
<h4> SAS Macros </h4>
|
<h4> SAS Macros </h4>
|
||||||
@li mf_nobs.sas
|
@li mf_nobs.sas
|
||||||
@li mm_assignlib.sas
|
@li mm_assignlib.sas
|
||||||
|
|
||||||
<h4> SAS Programs </h4>
|
<h4> SAS Includes </h4>
|
||||||
@li somefile.ddl SOMEFREF
|
@li somefile.ddl SOMEFREF
|
||||||
@li someprogram.sas FREFTWO
|
@li someprogram.sas FREFTWO
|
||||||
```
|
```
|
||||||
|
|
||||||
The CLI can then extract all the dependencies and insert as precode (SAS Macros) or in a temp engine fileref (SAS Programs) when creating SAS Jobs and Services.
|
The CLI can then extract all the dependencies and insert as precode (SAS Macros) or in a temp engine fileref (SAS Includes) when creating SAS Jobs and Services.
|
||||||
|
|
||||||
When contributing to this library, it is therefore important to ensure that all dependencies are listed in the header in this format.
|
When contributing to this library, it is therefore important to ensure that all dependencies are listed in the header in this format.
|
||||||
|
|
||||||
|
|||||||
@@ -1,23 +1,11 @@
|
|||||||
/**
|
/**
|
||||||
@file
|
@file
|
||||||
@brief abort gracefully according to context
|
@brief to be deprecated
|
||||||
@details Do not use directly! See bottom of explanation for details.
|
@details We will deprecate this macro in 2022
|
||||||
|
|
||||||
Configures an abort mechanism according to site specific policies or the
|
As you can see, it's not a macro function.
|
||||||
particulars of an environment. For instance, can stream custom
|
|
||||||
results back to the client in an STP Web App context, or completely stop
|
|
||||||
in the case of a batch run.
|
|
||||||
|
|
||||||
For the sharp eyed readers - this is no longer a macro function!! It became
|
Use mp_abort.sas instead.
|
||||||
a macro procedure during a project and now it's kinda stuck that way until
|
|
||||||
that project is updated (if it's ever updated). In the meantime we created
|
|
||||||
`mp_abort` which is just a wrapper for this one, and so we recomend you use
|
|
||||||
that for forwards compatibility reasons.
|
|
||||||
|
|
||||||
@param mac= to contain the name of the calling macro
|
|
||||||
@param type= deprecated. Not used.
|
|
||||||
@param msg= message to be returned
|
|
||||||
@param iftrue= supply a condition under which the macro should be executed.
|
|
||||||
|
|
||||||
@version 9.2
|
@version 9.2
|
||||||
@author Allan Bowe
|
@author Allan Bowe
|
||||||
|
|||||||
@@ -18,5 +18,5 @@
|
|||||||
|
|
||||||
|
|
||||||
%macro mf_getuniquename(prefix=MC);
|
%macro mf_getuniquename(prefix=MC);
|
||||||
&prefix.%substr(%sysfunc(compress(%sysfunc(uuidgen()),-)),1,32-%length(&prefix))
|
&prefix.%substr(%sysfunc(compress(%sysfunc(uuidgen()),-)),1,32-%length(&prefix))
|
||||||
%mend;
|
%mend mf_getuniquename;
|
||||||
@@ -23,9 +23,9 @@
|
|||||||
8.
|
8.
|
||||||
NOTE: Variable renegade does not exist in test
|
NOTE: Variable renegade does not exist in test
|
||||||
|
|
||||||
@param libds Two part dataset (or view) reference.
|
@param [in] libds Two part dataset (or view) reference.
|
||||||
@param var Variable name for which a format should be returned
|
@param [in] var Variable name for which a format should be returned
|
||||||
@param force Set to 1 to supply a default if the variable has no format
|
@param [in] force=(0) Set to 1 to supply a default if the variable has no format
|
||||||
@returns outputs format
|
@returns outputs format
|
||||||
|
|
||||||
@author Allan Bowe
|
@author Allan Bowe
|
||||||
@@ -60,7 +60,7 @@
|
|||||||
%let vlen = %sysfunc(varlen(&dsid, &vnum));
|
%let vlen = %sysfunc(varlen(&dsid, &vnum));
|
||||||
%let vtype = %sysfunc(vartype(&dsid, &vnum.));
|
%let vtype = %sysfunc(vartype(&dsid, &vnum.));
|
||||||
%if &vtype=C %then %let vformat=$&vlen..;
|
%if &vtype=C %then %let vformat=$&vlen..;
|
||||||
%else %let vformat=8.;
|
%else %let vformat=best.;
|
||||||
%end;
|
%end;
|
||||||
|
|
||||||
|
|
||||||
@@ -68,4 +68,4 @@
|
|||||||
%let rc = %sysfunc(close(&dsid));
|
%let rc = %sysfunc(close(&dsid));
|
||||||
/* Return variable format */
|
/* Return variable format */
|
||||||
&vformat
|
&vformat
|
||||||
%mend;
|
%mend mf_getVarFormat;
|
||||||
@@ -21,6 +21,10 @@
|
|||||||
@param [in] dlm= ( ) Provide a delimiter (eg comma or space) to separate the
|
@param [in] dlm= ( ) Provide a delimiter (eg comma or space) to separate the
|
||||||
variables
|
variables
|
||||||
@param [in] quote= (none) use either DOUBLE or SINGLE to quote the results
|
@param [in] quote= (none) use either DOUBLE or SINGLE to quote the results
|
||||||
|
@param [in] typefilter= (A) Filter for certain types of column. Valid values:
|
||||||
|
@li A Return All columns
|
||||||
|
@li C Return Character columns
|
||||||
|
@li N Return Numeric columns
|
||||||
|
|
||||||
@version 9.2
|
@version 9.2
|
||||||
@author Allan Bowe
|
@author Allan Bowe
|
||||||
@@ -30,9 +34,10 @@
|
|||||||
%macro mf_getvarlist(libds
|
%macro mf_getvarlist(libds
|
||||||
,dlm=%str( )
|
,dlm=%str( )
|
||||||
,quote=no
|
,quote=no
|
||||||
|
,typefilter=A
|
||||||
)/*/STORE SOURCE*/;
|
)/*/STORE SOURCE*/;
|
||||||
/* declare local vars */
|
/* declare local vars */
|
||||||
%local outvar dsid nvars x rc dlm q var;
|
%local outvar dsid nvars x rc dlm q var vtype;
|
||||||
|
|
||||||
/* credit Rowland Hale - byte34 is double quote, 39 is single quote */
|
/* credit Rowland Hale - byte34 is double quote, 39 is single quote */
|
||||||
%if %upcase("e)=DOUBLE %then %let q=%qsysfunc(byte(34));
|
%if %upcase("e)=DOUBLE %then %let q=%qsysfunc(byte(34));
|
||||||
@@ -40,21 +45,22 @@
|
|||||||
/* open dataset in macro */
|
/* open dataset in macro */
|
||||||
%let dsid=%sysfunc(open(&libds));
|
%let dsid=%sysfunc(open(&libds));
|
||||||
|
|
||||||
|
|
||||||
%if &dsid %then %do;
|
%if &dsid %then %do;
|
||||||
%let nvars=%sysfunc(attrn(&dsid,NVARS));
|
%let nvars=%sysfunc(attrn(&dsid,NVARS));
|
||||||
%if &nvars>0 %then %do;
|
%if &nvars>0 %then %do;
|
||||||
/* add first dataset variable to global macro variable */
|
/* add variables with supplied delimeter */
|
||||||
%let outvar=&q.%sysfunc(varname(&dsid,1))&q.;
|
|
||||||
/* add remaining variables with supplied delimeter */
|
|
||||||
%do x=1 %to &nvars;
|
%do x=1 %to &nvars;
|
||||||
%let var=&q.%sysfunc(varname(&dsid,&x))&q.;
|
/* get variable type */
|
||||||
%if &var=&q&q %then %do;
|
%let vtype=%sysfunc(vartype(&dsid,&x));
|
||||||
%put &sysmacroname: Empty column found in &libds!;
|
%if &vtype=&typefilter or &typefilter=A %then %do;
|
||||||
%let var=&q. &q.;
|
%let var=&q.%sysfunc(varname(&dsid,&x))&q.;
|
||||||
|
%if &var=&q&q %then %do;
|
||||||
|
%put &sysmacroname: Empty column found in &libds!;
|
||||||
|
%let var=&q. &q.;
|
||||||
|
%end;
|
||||||
|
%if %quote(&outvar)=%quote() %then %let outvar=&var;
|
||||||
|
%else %let outvar=&outvar.&dlm.&var.;
|
||||||
%end;
|
%end;
|
||||||
%if &x=1 %then %let outvar=&var;
|
|
||||||
%else %let outvar=&outvar.&dlm.&var.;
|
|
||||||
%end;
|
%end;
|
||||||
%end;
|
%end;
|
||||||
%let rc=%sysfunc(close(&dsid));
|
%let rc=%sysfunc(close(&dsid));
|
||||||
@@ -64,4 +70,4 @@
|
|||||||
%let rc=%sysfunc(close(&dsid));
|
%let rc=%sysfunc(close(&dsid));
|
||||||
%end;
|
%end;
|
||||||
&outvar
|
&outvar
|
||||||
%mend;
|
%mend mf_getvarlist;
|
||||||
@@ -45,4 +45,4 @@ Usage:
|
|||||||
%let rc = %sysfunc(close(&dsid));
|
%let rc = %sysfunc(close(&dsid));
|
||||||
/* Return variable type */
|
/* Return variable type */
|
||||||
&vtype
|
&vtype
|
||||||
%mend;
|
%mend mf_getvartype;
|
||||||
@@ -18,4 +18,4 @@
|
|||||||
|
|
||||||
&today._&now._&sysjobid._%sysevalf(%sysfunc(ranuni(0))*999,CEIL)
|
&today._&now._&sysjobid._%sysevalf(%sysfunc(ranuni(0))*999,CEIL)
|
||||||
|
|
||||||
%mend;
|
%mend mf_uid;
|
||||||
@@ -4,13 +4,24 @@
|
|||||||
@details Configures an abort mechanism according to site specific policies or
|
@details Configures an abort mechanism according to site specific policies or
|
||||||
the particulars of an environment. For instance, can stream custom
|
the particulars of an environment. For instance, can stream custom
|
||||||
results back to the client in an STP Web App context, or completely stop
|
results back to the client in an STP Web App context, or completely stop
|
||||||
in the case of a batch run.
|
in the case of a batch run. For STP sessions
|
||||||
|
|
||||||
|
The method used varies according to the context. Important points:
|
||||||
|
|
||||||
|
@li should not use endsas or abort cancel in 9.4m3 environments as this can
|
||||||
|
cause hung multibridge sessions and result in a frozen STP server
|
||||||
|
@li should not use endsas in viya 3.5 as this destroys the session and cannot
|
||||||
|
fetch results (although both mv_getjoblog.sas and the @sasjs/adapter will
|
||||||
|
recognise this and fetch the log of the parent session instead)
|
||||||
|
@li STP environments must finish cleanly to avoid the log being sent to
|
||||||
|
_webout. To assist with this, we also run stpsrvset('program error', 0)
|
||||||
|
and set SYSCC=0. For 9.4m3 we take a unique approach - we open a macro
|
||||||
|
but don't close it! This provides a graceful abort, EXCEPT when called
|
||||||
|
called within a %include within a macro (and that macro contains additional
|
||||||
|
logic). See mp_abort.test.nofix.sas for the example case.
|
||||||
|
If you know of another way to gracefully abort a 9.4m3 STP session, we'd
|
||||||
|
love to hear about it!
|
||||||
|
|
||||||
Using SAS Abort Cancel mechanisms can cause hung sessions in some Stored
|
|
||||||
Process environments. This macro takes a unique approach - we set the SAS
|
|
||||||
syscc to 0, run `stpsrvset('program error', 0)` (if SAS 9) and then - we open
|
|
||||||
a macro but don't close it! This provides a graceful abort for SAS web
|
|
||||||
services in all web enabled environments.
|
|
||||||
|
|
||||||
@param mac= to contain the name of the calling macro
|
@param mac= to contain the name of the calling macro
|
||||||
@param msg= message to be returned
|
@param msg= message to be returned
|
||||||
@@ -24,6 +35,8 @@
|
|||||||
%macro mp_abort(mac=mp_abort.sas, type=, msg=, iftrue=%str(1=1)
|
%macro mp_abort(mac=mp_abort.sas, type=, msg=, iftrue=%str(1=1)
|
||||||
)/*/STORE SOURCE*/;
|
)/*/STORE SOURCE*/;
|
||||||
|
|
||||||
|
%global sysprocessmode sysprocessname;
|
||||||
|
|
||||||
%if not(%eval(%unquote(&iftrue))) %then %return;
|
%if not(%eval(%unquote(&iftrue))) %then %return;
|
||||||
|
|
||||||
%put NOTE: /// mp_abort macro executing //;
|
%put NOTE: /// mp_abort macro executing //;
|
||||||
@@ -31,9 +44,7 @@
|
|||||||
%put NOTE - &msg;
|
%put NOTE - &msg;
|
||||||
|
|
||||||
/* Stored Process Server web app context */
|
/* Stored Process Server web app context */
|
||||||
%if %symexist(_metaperson)
|
%if %symexist(_metaperson) or "&SYSPROCESSNAME "="Compute Server " %then %do;
|
||||||
or (%symexist(SYSPROCESSNAME) and "&SYSPROCESSNAME"="Compute Server" )
|
|
||||||
%then %do;
|
|
||||||
options obs=max replace nosyntaxcheck mprint;
|
options obs=max replace nosyntaxcheck mprint;
|
||||||
/* extract log errs / warns, if exist */
|
/* extract log errs / warns, if exist */
|
||||||
%local logloc logline;
|
%local logloc logline;
|
||||||
@@ -63,7 +74,7 @@
|
|||||||
input;
|
input;
|
||||||
i=1;
|
i=1;
|
||||||
stoploop=0;
|
stoploop=0;
|
||||||
if _n_ ge &logline-5 and stoploop=0 then do until (i>12);
|
if _n_ ge &logline-15 and stoploop=0 then do until (i>22);
|
||||||
call symputx('logmsg',catx('\n',symget('logmsg'),_infile_));
|
call symputx('logmsg',catx('\n',symget('logmsg'),_infile_));
|
||||||
input;
|
input;
|
||||||
i+1;
|
i+1;
|
||||||
@@ -128,31 +139,59 @@
|
|||||||
if debug ge '"131"' then put '>>weboutEND<<';
|
if debug ge '"131"' then put '>>weboutEND<<';
|
||||||
run;
|
run;
|
||||||
|
|
||||||
%let syscc=0;
|
%put _all_;
|
||||||
%if %symexist(_metaport) %then %do;
|
|
||||||
|
%if "&sysprocessmode " = "SAS Stored Process Server " %then %do;
|
||||||
data _null_;
|
data _null_;
|
||||||
if symexist('sysprocessmode')
|
putlog 'stpsrvset program error and syscc';
|
||||||
then if symget("sysprocessmode")="SAS Stored Process Server"
|
rc=stpsrvset('program error', 0);
|
||||||
then rc=stpsrvset('program error', 0);
|
call symputx("syscc",0,"g");
|
||||||
|
run;
|
||||||
|
%if "%substr(&sysvlong.xxxxxxxxx,1,9)" ne "9.04.01M3" %then %do;
|
||||||
|
%put NOTE: Ending SAS session due to:;
|
||||||
|
%put NOTE- &msg;
|
||||||
|
endsas;
|
||||||
|
%end;
|
||||||
|
%end;
|
||||||
|
%else %if "&sysprocessmode " = "SAS Compute Server " %then %do;
|
||||||
|
/* endsas kills the session making it harder to fetch results */
|
||||||
|
data _null_;
|
||||||
|
syswarningtext=symget('syswarningtext');
|
||||||
|
syserrortext=symget('syserrortext');
|
||||||
|
abort_msg=symget('msg');
|
||||||
|
syscc=symget('syscc');
|
||||||
|
sysuserid=symget('sysuserid');
|
||||||
|
iftrue=symget('iftrue');
|
||||||
|
put (_all_)(/=);
|
||||||
|
abort cancel nolist;
|
||||||
run;
|
run;
|
||||||
%end;
|
%end;
|
||||||
/**
|
%else %if "%substr(&sysvlong.xxxxxxxxx,1,9)" = "9.04.01M3" %then %do;
|
||||||
* endsas is reliable but kills some deployments.
|
/**
|
||||||
* Abort variants are ungraceful (non zero return code)
|
* endsas kills 9.4m3 deployments by orphaning multibridges.
|
||||||
* This approach lets SAS run silently until the end :-)
|
* Abort variants are ungraceful (non zero return code)
|
||||||
*/
|
* This approach lets SAS run silently until the end :-)
|
||||||
%put _all_;
|
* Caution - fails when called within a %include within a macro
|
||||||
filename skip temp;
|
* See tests/mp_abort.test.1 for an example case.
|
||||||
data _null_;
|
*/
|
||||||
file skip;
|
filename skip temp;
|
||||||
put '%macro skip(); %macro skippy();';
|
data _null_;
|
||||||
run;
|
file skip;
|
||||||
%inc skip;
|
put '%macro skip();';
|
||||||
|
comment '%mend skip; -> fix lint ';
|
||||||
|
put '%macro skippy();';
|
||||||
|
comment '%mend skippy; -> fix lint ';
|
||||||
|
run;
|
||||||
|
%inc skip;
|
||||||
|
%end;
|
||||||
|
%else %do;
|
||||||
|
%abort cancel;
|
||||||
|
%end;
|
||||||
%end;
|
%end;
|
||||||
%else %do;
|
%else %do;
|
||||||
%put _all_;
|
%put _all_;
|
||||||
%abort cancel;
|
%abort cancel;
|
||||||
%end;
|
%end;
|
||||||
%mend;
|
%mend mp_abort;
|
||||||
|
|
||||||
/** @endcond */
|
/** @endcond */
|
||||||
56
base/mp_assert.sas
Normal file
56
base/mp_assert.sas
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
/**
|
||||||
|
@file
|
||||||
|
@brief Generic assertion
|
||||||
|
@details Useful in the context of writing sasjs tests. The results of the
|
||||||
|
test are _appended_ to the &outds. table.
|
||||||
|
|
||||||
|
Example usage:
|
||||||
|
|
||||||
|
%mp_assert(iftrue=(1=1),
|
||||||
|
desc=Obviously true
|
||||||
|
)
|
||||||
|
|
||||||
|
%mp_assert(iftrue=(1=0),
|
||||||
|
desc=Will fail
|
||||||
|
)
|
||||||
|
|
||||||
|
@param [in] iftrue= (1=1) A condition where, if true, the test is a PASS.
|
||||||
|
Else, the test is a fail.
|
||||||
|
|
||||||
|
@param [in] desc= (Testing observations) The user provided test description
|
||||||
|
@param [out] outds= (work.test_results) The output dataset to contain the
|
||||||
|
results. If it does not exist, it will be created, with the following format:
|
||||||
|
|TEST_DESCRIPTION:$256|TEST_RESULT:$4|TEST_COMMENTS:$256|
|
||||||
|
|---|---|---|
|
||||||
|
|User Provided description|PASS|Column &inds contained ALL columns|
|
||||||
|
|
||||||
|
@version 9.2
|
||||||
|
@author Allan Bowe
|
||||||
|
|
||||||
|
**/
|
||||||
|
|
||||||
|
%macro mp_assert(iftrue=(1=1),
|
||||||
|
desc=0,
|
||||||
|
outds=work.test_results
|
||||||
|
)/*/STORE SOURCE*/;
|
||||||
|
|
||||||
|
data ;
|
||||||
|
length test_description $256 test_result $4 test_comments $256;
|
||||||
|
test_description=symget('desc');
|
||||||
|
test_comments="&sysmacroname: Test result of "!!symget('iftrue');
|
||||||
|
%if %eval(%unquote(&iftrue)) %then %do;
|
||||||
|
test_result='PASS';
|
||||||
|
%end;
|
||||||
|
%else %do;
|
||||||
|
test_result='FAIL';
|
||||||
|
%end;
|
||||||
|
run;
|
||||||
|
|
||||||
|
%local ds ;
|
||||||
|
%let ds=&syslast;
|
||||||
|
proc append base=&outds data=&ds;
|
||||||
|
run;
|
||||||
|
proc sql;
|
||||||
|
drop table &ds;
|
||||||
|
|
||||||
|
%mend mp_assert;
|
||||||
@@ -25,6 +25,7 @@
|
|||||||
<h4> SAS Macros </h4>
|
<h4> SAS Macros </h4>
|
||||||
@li mf_existds.sas
|
@li mf_existds.sas
|
||||||
@li mf_existvarlist.sas
|
@li mf_existvarlist.sas
|
||||||
|
@li mf_getvarlist.sas
|
||||||
@li mf_wordsinstr1butnotstr2.sas
|
@li mf_wordsinstr1butnotstr2.sas
|
||||||
@li mp_abort.sas
|
@li mp_abort.sas
|
||||||
|
|
||||||
|
|||||||
@@ -1,20 +1,24 @@
|
|||||||
/**
|
/**
|
||||||
@file
|
@file
|
||||||
@brief Drops tables / views (if they exist) without warnings in the log
|
@brief Drops tables / views (if they exist) without warnings in the log
|
||||||
@details
|
@details Useful for dropping tables when you're not sure they exist, or if
|
||||||
|
you are not sure whether they are a dataset or view. Also efficient for
|
||||||
|
dropping multiple tables / views.
|
||||||
|
|
||||||
Example usage:
|
Example usage:
|
||||||
|
|
||||||
proc sql;
|
proc sql;
|
||||||
create table data1 as select * from sashelp.class;
|
create table data1 as select * from sashelp.class;
|
||||||
create view view2 as select * from sashelp.class;
|
create view view2 as select * from sashelp.class;
|
||||||
%mp_dropmembers(list=data1 view2)
|
%mp_dropmembers(data1 view2, libref=WORK)
|
||||||
|
|
||||||
|
|
||||||
<h4> SAS Macros </h4>
|
<h4> SAS Macros </h4>
|
||||||
@li mf_isblank.sas
|
@li mf_isblank.sas
|
||||||
|
|
||||||
|
|
||||||
@param list space separated list of datasets / views
|
@param list space separated list of datasets / views, WITHOUT libref
|
||||||
@param libref= can only drop from a single library at a time
|
@param libref= (WORK) Note - you can only drop from a single library at a time
|
||||||
|
|
||||||
@version 9.2
|
@version 9.2
|
||||||
@author Allan Bowe
|
@author Allan Bowe
|
||||||
@@ -35,4 +39,4 @@
|
|||||||
delete &list;
|
delete &list;
|
||||||
delete &list /mtype=view;
|
delete &list /mtype=view;
|
||||||
run;
|
run;
|
||||||
%mend;
|
%mend mp_dropmembers;
|
||||||
98
base/mp_ds2fmtds.sas
Normal file
98
base/mp_ds2fmtds.sas
Normal file
@@ -0,0 +1,98 @@
|
|||||||
|
/**
|
||||||
|
@file
|
||||||
|
@brief Converts every value in a dataset to it's formatted value
|
||||||
|
@details Converts every value to it's formatted value. All variables will
|
||||||
|
become character, and will be in the same order.
|
||||||
|
|
||||||
|
Usage:
|
||||||
|
|
||||||
|
%mp_ds2fmtds(sashelp.cars,work.cars)
|
||||||
|
|
||||||
|
@param [in] libds The library.dataset to be converted
|
||||||
|
@param [out] outds The dataset to create.
|
||||||
|
|
||||||
|
<h4> Related Macros <h4>
|
||||||
|
@li mp_jsonout.sas
|
||||||
|
|
||||||
|
@version 9.2
|
||||||
|
@author Allan Bowe
|
||||||
|
**/
|
||||||
|
|
||||||
|
%macro mp_ds2fmtds(libds, outds
|
||||||
|
)/*/STORE SOURCE*/;
|
||||||
|
|
||||||
|
/* validations */
|
||||||
|
%if not %sysfunc(exist(&libds)) %then %do;
|
||||||
|
%put %str(WARN)ING: &libds does not exist;
|
||||||
|
%return;
|
||||||
|
%end;
|
||||||
|
%if %index(&libds,.)=0 %then %let libds=WORK.&libds;
|
||||||
|
|
||||||
|
/* grab metadata */
|
||||||
|
proc contents noprint data=&libds
|
||||||
|
out=_data_(keep=name type length format formatl formatd varnum);
|
||||||
|
run;
|
||||||
|
proc sort;
|
||||||
|
by varnum;
|
||||||
|
run;
|
||||||
|
|
||||||
|
/* prepare formats and varnames */
|
||||||
|
data _null_;
|
||||||
|
set &syslast end=last;
|
||||||
|
name=upcase(name);
|
||||||
|
/* fix formats */
|
||||||
|
if type=2 or type=6 then do;
|
||||||
|
length fmt $49.;
|
||||||
|
if format='' then fmt=cats('$',length,'.');
|
||||||
|
else if formatl=0 then fmt=cats(format,'.');
|
||||||
|
else fmt=cats(format,formatl,'.');
|
||||||
|
newlen=max(formatl,length);
|
||||||
|
end;
|
||||||
|
else do;
|
||||||
|
if format='' then fmt='best.';
|
||||||
|
else if formatl=0 then fmt=cats(format,'.');
|
||||||
|
else if formatd=0 then fmt=cats(format,formatl,'.');
|
||||||
|
else fmt=cats(format,formatl,'.',formatd);
|
||||||
|
/* needs to be wide, for datetimes etc */
|
||||||
|
newlen=max(length,formatl,24);
|
||||||
|
end;
|
||||||
|
/* 32 char unique name */
|
||||||
|
newname='sasjs'!!substr(cats(put(md5(name),$hex32.)),1,27);
|
||||||
|
|
||||||
|
call symputx(cats('name',_n_),name,'l');
|
||||||
|
call symputx(cats('newname',_n_),newname,'l');
|
||||||
|
call symputx(cats('len',_n_),newlen,'l');
|
||||||
|
call symputx(cats('fmt',_n_),fmt,'l');
|
||||||
|
call symputx(cats('type',_n_),type,'l');
|
||||||
|
if last then call symputx('nobs',_n_,'l');
|
||||||
|
run;
|
||||||
|
|
||||||
|
/* clean up */
|
||||||
|
proc sql;
|
||||||
|
drop table &syslast;
|
||||||
|
|
||||||
|
%if &nobs=0 %then %do;
|
||||||
|
%put Dataset &libds has no columns!
|
||||||
|
data &outds;
|
||||||
|
set &libds;
|
||||||
|
run;
|
||||||
|
%return;
|
||||||
|
%end;
|
||||||
|
|
||||||
|
data &outds;
|
||||||
|
/* rename on entry */
|
||||||
|
set &libds(rename=(
|
||||||
|
%local i;
|
||||||
|
%do i=1 %to &nobs;
|
||||||
|
&&name&i=&&newname&i
|
||||||
|
%end;
|
||||||
|
));
|
||||||
|
%do i=1 %to &nobs;
|
||||||
|
length &&name&i $&&len&i;
|
||||||
|
&&name&i=left(put(&&newname&i,&&fmt&i));
|
||||||
|
drop &&newname&i;
|
||||||
|
%end;
|
||||||
|
if _error_ then call symputx('syscc',1012);
|
||||||
|
run;
|
||||||
|
|
||||||
|
%mend mp_ds2fmtds;
|
||||||
@@ -33,18 +33,19 @@
|
|||||||
@returns The &outds table containing any bad rows, plus a REASON_CD column.
|
@returns The &outds table containing any bad rows, plus a REASON_CD column.
|
||||||
|
|
||||||
@param [in] inds The table to be checked, with the format above
|
@param [in] inds The table to be checked, with the format above
|
||||||
@param [in] targetds= The target dataset against which to verify VARIABLE_NM
|
@param [in] targetds= The target dataset against which to verify VARIABLE_NM.
|
||||||
|
This must be available (ie, the library must be assigned).
|
||||||
@param [out] abort= (YES) If YES will call mp_abort.sas on any exceptions
|
@param [out] abort= (YES) If YES will call mp_abort.sas on any exceptions
|
||||||
@param [out] outds= The output table, which is a copy of the &inds. table
|
@param [out] outds= The output table, which is a copy of the &inds. table
|
||||||
plus a REASON_CD column, containing only bad records. If bad records found,
|
plus a REASON_CD column, containing only bad records. If bad records found,
|
||||||
the SYSCC value will be set to 1008 (general data problem). Downstream
|
the SYSCC value will be set to 1008 (general data problem). Downstream
|
||||||
processes should check this table (and return code) before continuing.
|
processes should check this table (and return code) before continuing.
|
||||||
|
|
||||||
<h4> SAS Macros </h4>
|
<h4> SAS Macros </h4>
|
||||||
@li mp_abort.sas
|
@li mp_abort.sas
|
||||||
@li mf_getuniquefileref.sas
|
@li mf_getuniquefileref.sas
|
||||||
@li mf_getvarlist.sas
|
@li mf_getvarlist.sas
|
||||||
@li mf_nobs.sas
|
@li mf_getvartype.sas
|
||||||
@li mp_filtergenerate.sas
|
@li mp_filtergenerate.sas
|
||||||
@li mp_filtervalidate.sas
|
@li mp_filtervalidate.sas
|
||||||
|
|
||||||
@@ -65,44 +66,71 @@
|
|||||||
,msg=%str(syscc=&syscc - on macro entry)
|
,msg=%str(syscc=&syscc - on macro entry)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
/* Validate input column */
|
||||||
|
%local vtype;
|
||||||
|
%let vtype=%mf_getvartype(&inds,RAW_VALUE);
|
||||||
|
%mp_abort(iftrue=(&abort=YES and &vtype ne C),
|
||||||
|
mac=&sysmacroname,
|
||||||
|
msg=%str(%str(ERR)OR: RAW_VALUE must be character)
|
||||||
|
)
|
||||||
|
%if &vtype ne C %then %do;
|
||||||
|
%put &sysmacroname: RAW_VALUE must be character;
|
||||||
|
%let syscc=42;
|
||||||
|
%return;
|
||||||
|
%end;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sanitise the values based on valid value lists, then strip out
|
* Sanitise the values based on valid value lists, then strip out
|
||||||
* quotes, commas, periods and spaces.
|
* quotes, commas, periods and spaces.
|
||||||
* Only numeric values should remain
|
* Only numeric values should remain
|
||||||
*/
|
*/
|
||||||
|
%local reason_cd nobs;
|
||||||
|
%let nobs=0;
|
||||||
data &outds;
|
data &outds;
|
||||||
|
/*length GROUP_LOGIC SUBGROUP_LOGIC $3 SUBGROUP_ID 8 VARIABLE_NM $32
|
||||||
|
OPERATOR_NM $10 RAW_VALUE $4000;*/
|
||||||
set &inds;
|
set &inds;
|
||||||
length reason_cd $32;
|
length reason_cd $4032;
|
||||||
|
|
||||||
/* closed list checks */
|
/* closed list checks */
|
||||||
if GROUP_LOGIC not in ('AND','OR') then do;
|
if GROUP_LOGIC not in ('AND','OR') then do;
|
||||||
REASON_CD='GROUP_LOGIC should be either AND or OR';
|
REASON_CD='GROUP_LOGIC should be AND/OR, not:'!!cats(GROUP_LOGIC);
|
||||||
putlog REASON_CD= GROUP_LOGIC=;
|
putlog REASON_CD= GROUP_LOGIC=;
|
||||||
|
call symputx('reason_cd',reason_cd,'l');
|
||||||
|
call symputx('nobs',_n_,'l');
|
||||||
output;
|
output;
|
||||||
end;
|
end;
|
||||||
if SUBGROUP_LOGIC not in ('AND','OR') then do;
|
if SUBGROUP_LOGIC not in ('AND','OR') then do;
|
||||||
REASON_CD='SUBGROUP_LOGIC should be either AND or OR';
|
REASON_CD='SUBGROUP_LOGIC should be AND/OR, not:'!!cats(SUBGROUP_LOGIC);
|
||||||
putlog REASON_CD= SUBGROUP_LOGIC=;
|
putlog REASON_CD= SUBGROUP_LOGIC=;
|
||||||
|
call symputx('reason_cd',reason_cd,'l');
|
||||||
|
call symputx('nobs',_n_,'l');
|
||||||
output;
|
output;
|
||||||
end;
|
end;
|
||||||
if mod(SUBGROUP_ID,1) ne 0 then do;
|
if mod(SUBGROUP_ID,1) ne 0 then do;
|
||||||
REASON_CD='SUBGROUP_ID should be integer';
|
REASON_CD='SUBGROUP_ID should be integer, not '!!left(subgroup_id);
|
||||||
putlog REASON_CD= SUBGROUP_ID=;
|
putlog REASON_CD= SUBGROUP_ID=;
|
||||||
|
call symputx('reason_cd',reason_cd,'l');
|
||||||
|
call symputx('nobs',_n_,'l');
|
||||||
output;
|
output;
|
||||||
end;
|
end;
|
||||||
if upcase(VARIABLE_NM) not in
|
if upcase(VARIABLE_NM) not in
|
||||||
(%upcase(%mf_getvarlist(&targetds,dlm=%str(,),quote=SINGLE)))
|
(%upcase(%mf_getvarlist(&targetds,dlm=%str(,),quote=SINGLE)))
|
||||||
then do;
|
then do;
|
||||||
REASON_CD="VARIABLE_NM not in &targetds";
|
REASON_CD="Variable "!!cats(variable_nm)!!" not in &targetds";
|
||||||
putlog REASON_CD= VARIABLE_NM=;
|
putlog REASON_CD= VARIABLE_NM=;
|
||||||
|
call symputx('reason_cd',reason_cd,'l');
|
||||||
|
call symputx('nobs',_n_,'l');
|
||||||
output;
|
output;
|
||||||
end;
|
end;
|
||||||
if OPERATOR_NM not in
|
if OPERATOR_NM not in
|
||||||
('=','>','<','<=','>=','BETWEEN','IN','NOT IN','NE','CONTAINS')
|
('=','>','<','<=','>=','BETWEEN','IN','NOT IN','NE','CONTAINS')
|
||||||
then do;
|
then do;
|
||||||
REASON_CD='Invalid OPERATOR_NM';
|
REASON_CD='Invalid OPERATOR_NM: '!!left(OPERATOR_NM);
|
||||||
putlog REASON_CD= OPERATOR_NM=;
|
putlog REASON_CD= OPERATOR_NM=;
|
||||||
|
call symputx('reason_cd',reason_cd,'l');
|
||||||
|
call symputx('nobs',_n_,'l');
|
||||||
output;
|
output;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@@ -112,8 +140,10 @@ data &outds;
|
|||||||
if substr(raw_value,1,1) ne '('
|
if substr(raw_value,1,1) ne '('
|
||||||
or substr(cats(reverse(raw_value)),1,1) ne ')'
|
or substr(cats(reverse(raw_value)),1,1) ne ')'
|
||||||
then do;
|
then do;
|
||||||
REASON_CD='Missing brackets in RAW_VALUE';
|
REASON_CD='Missing start/end bracket in RAW_VALUE';
|
||||||
putlog REASON_CD= OPERATOR_NM= raw_value= raw_value1= ;
|
putlog REASON_CD= OPERATOR_NM= raw_value= raw_value1= ;
|
||||||
|
call symputx('reason_cd',reason_cd,'l');
|
||||||
|
call symputx('nobs',_n_,'l');
|
||||||
output;
|
output;
|
||||||
end;
|
end;
|
||||||
else raw_value1=substr(raw_value,2,max(length(raw_value)-2,0));
|
else raw_value1=substr(raw_value,2,max(length(raw_value)-2,0));
|
||||||
@@ -134,25 +164,27 @@ data &outds;
|
|||||||
/* output records that contain values other than digits and spaces */
|
/* output records that contain values other than digits and spaces */
|
||||||
if notdigit(compress(raw_value3,' '))>0 then do;
|
if notdigit(compress(raw_value3,' '))>0 then do;
|
||||||
putlog raw_value3= $hex32.;
|
putlog raw_value3= $hex32.;
|
||||||
REASON_CD='Invalid RAW_VALUE';
|
REASON_CD=cats('Invalid RAW_VALUE:',raw_value);
|
||||||
putlog REASON_CD= raw_value= raw_value1= raw_value2= raw_value3=;
|
putlog REASON_CD= raw_value= raw_value1= raw_value2= raw_value3=;
|
||||||
|
call symputx('reason_cd',reason_cd,'l');
|
||||||
|
call symputx('nobs',_n_,'l');
|
||||||
output;
|
output;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
run;
|
run;
|
||||||
|
|
||||||
%if %mf_nobs(&outds)>0 %then %do;
|
|
||||||
%if &abort=YES %then %do;
|
data _null_;
|
||||||
data _null_;
|
set &outds end=last;
|
||||||
set &outds;
|
putlog (_all_)(=);
|
||||||
call symputx('REASON_CD',reason_cd,'l');
|
run;
|
||||||
stop;
|
|
||||||
run;
|
%mp_abort(iftrue=(&abort=YES and &nobs>0),
|
||||||
%mp_abort(
|
mac=&sysmacroname,
|
||||||
mac=&sysmacroname,
|
msg=%str(Data issue: %superq(reason_cd))
|
||||||
msg=%str(Filter issues in &inds, first was &reason_cd, details in &outds)
|
)
|
||||||
)
|
|
||||||
%end;
|
%if &nobs>0 %then %do;
|
||||||
%let syscc=1008;
|
%let syscc=1008;
|
||||||
%return;
|
%return;
|
||||||
%end;
|
%end;
|
||||||
@@ -168,4 +200,4 @@ run;
|
|||||||
/* this macro will also set syscc to 1008 if any issues found */
|
/* this macro will also set syscc to 1008 if any issues found */
|
||||||
%mp_filtervalidate(&fref1,&targetds,outds=&outds,abort=&abort)
|
%mp_filtervalidate(&fref1,&targetds,outds=&outds,abort=&abort)
|
||||||
|
|
||||||
%mend;
|
%mend mp_filtercheck;
|
||||||
|
|||||||
@@ -95,7 +95,8 @@ filename &fref1 clear;
|
|||||||
run;
|
run;
|
||||||
%mp_abort(
|
%mp_abort(
|
||||||
mac=&sysmacroname,
|
mac=&sysmacroname,
|
||||||
msg=%str(Filter issues in &inref: %quote(&reason_cd))
|
msg=%str(Filter validation issues. ERR=%superq(SYSERRORTEXT)
|
||||||
|
, WARN=%superq(SYSWARNINGTEXT) )
|
||||||
)
|
)
|
||||||
%end;
|
%end;
|
||||||
%let syscc=1008;
|
%let syscc=1008;
|
||||||
|
|||||||
@@ -56,7 +56,7 @@
|
|||||||
retain &prevkeyvar;
|
retain &prevkeyvar;
|
||||||
set &libds end=&lastvar;
|
set &libds end=&lastvar;
|
||||||
/* hash should include previous row */
|
/* hash should include previous row */
|
||||||
if _n_>1 then &keyvar=put(md5(&prevkeyvar
|
&keyvar=put(md5(&prevkeyvar
|
||||||
/* loop every column, hashing every individual value */
|
/* loop every column, hashing every individual value */
|
||||||
%do i=1 %to %sysfunc(countw(&varlist));
|
%do i=1 %to %sysfunc(countw(&varlist));
|
||||||
%let var=%scan(&varlist,&i,%str( ));
|
%let var=%scan(&varlist,&i,%str( ));
|
||||||
|
|||||||
@@ -48,6 +48,8 @@
|
|||||||
@param dbg= DEPRECATED - was used to conditionally add PRETTY to
|
@param dbg= DEPRECATED - was used to conditionally add PRETTY to
|
||||||
proc json but this can cause line truncation in large files.
|
proc json but this can cause line truncation in large files.
|
||||||
|
|
||||||
|
<h4> Related Macros <h4>
|
||||||
|
@li mp_ds2fmtds.sas
|
||||||
|
|
||||||
@version 9.2
|
@version 9.2
|
||||||
@author Allan Bowe
|
@author Allan Bowe
|
||||||
@@ -55,10 +57,11 @@
|
|||||||
|
|
||||||
**/
|
**/
|
||||||
|
|
||||||
%macro mp_jsonout(action,ds,jref=_webout,dslabel=,fmt=Y,engine=PROCJSON,dbg=0
|
%macro mp_jsonout(action,ds,jref=_webout,dslabel=,fmt=Y,engine=DATASTEP,dbg=0
|
||||||
)/*/STORE SOURCE*/;
|
)/*/STORE SOURCE*/;
|
||||||
%put output location=&jref;
|
%put output location=&jref;
|
||||||
%if &action=OPEN %then %do;
|
%if &action=OPEN %then %do;
|
||||||
|
options nobomfile;
|
||||||
data _null_;file &jref encoding='utf-8';
|
data _null_;file &jref encoding='utf-8';
|
||||||
put '{"START_DTTM" : "' "%sysfunc(datetime(),datetime20.3)" '"';
|
put '{"START_DTTM" : "' "%sysfunc(datetime(),datetime20.3)" '"';
|
||||||
run;
|
run;
|
||||||
@@ -86,6 +89,64 @@
|
|||||||
%put &sysmacroname: &ds NOT FOUND!!!;
|
%put &sysmacroname: &ds NOT FOUND!!!;
|
||||||
%return;
|
%return;
|
||||||
%end;
|
%end;
|
||||||
|
%if &fmt=Y %then %do;
|
||||||
|
%put converting every variable to a formatted variable;
|
||||||
|
/* see mp_ds2fmtds.sas for source */
|
||||||
|
proc contents noprint data=&ds
|
||||||
|
out=_data_(keep=name type length format formatl formatd varnum);
|
||||||
|
run;
|
||||||
|
proc sort;
|
||||||
|
by varnum;
|
||||||
|
run;
|
||||||
|
%local fmtds;
|
||||||
|
%let fmtds=%scan(&syslast,2,.);
|
||||||
|
/* prepare formats and varnames */
|
||||||
|
data _null_;
|
||||||
|
set &fmtds end=last;
|
||||||
|
name=upcase(name);
|
||||||
|
/* fix formats */
|
||||||
|
if type=2 or type=6 then do;
|
||||||
|
length fmt $49.;
|
||||||
|
if format='' then fmt=cats('$',length,'.');
|
||||||
|
else if formatl=0 then fmt=cats(format,'.');
|
||||||
|
else fmt=cats(format,formatl,'.');
|
||||||
|
newlen=max(formatl,length);
|
||||||
|
end;
|
||||||
|
else do;
|
||||||
|
if format='' then fmt='best.';
|
||||||
|
else if formatl=0 then fmt=cats(format,'.');
|
||||||
|
else if formatd=0 then fmt=cats(format,formatl,'.');
|
||||||
|
else fmt=cats(format,formatl,'.',formatd);
|
||||||
|
/* needs to be wide, for datetimes etc */
|
||||||
|
newlen=max(length,formatl,24);
|
||||||
|
end;
|
||||||
|
/* 32 char unique name */
|
||||||
|
newname='sasjs'!!substr(cats(put(md5(name),$hex32.)),1,27);
|
||||||
|
|
||||||
|
call symputx(cats('name',_n_),name,'l');
|
||||||
|
call symputx(cats('newname',_n_),newname,'l');
|
||||||
|
call symputx(cats('len',_n_),newlen,'l');
|
||||||
|
call symputx(cats('fmt',_n_),fmt,'l');
|
||||||
|
call symputx(cats('type',_n_),type,'l');
|
||||||
|
if last then call symputx('nobs',_n_,'l');
|
||||||
|
run;
|
||||||
|
data &fmtds;
|
||||||
|
/* rename on entry */
|
||||||
|
set &ds(rename=(
|
||||||
|
%local i;
|
||||||
|
%do i=1 %to &nobs;
|
||||||
|
&&name&i=&&newname&i
|
||||||
|
%end;
|
||||||
|
));
|
||||||
|
%do i=1 %to &nobs;
|
||||||
|
length &&name&i $&&len&i;
|
||||||
|
&&name&i=left(put(&&newname&i,&&fmt&i));
|
||||||
|
drop &&newname&i;
|
||||||
|
%end;
|
||||||
|
if _error_ then call symputx('syscc',1012);
|
||||||
|
run;
|
||||||
|
%let ds=&fmtds;
|
||||||
|
%end; /* &fmt=Y */
|
||||||
data _null_;file &jref mod ;
|
data _null_;file &jref mod ;
|
||||||
put "["; call symputx('cols',0,'l');
|
put "["; call symputx('cols',0,'l');
|
||||||
proc sort
|
proc sort
|
||||||
@@ -169,4 +230,4 @@
|
|||||||
put "}";
|
put "}";
|
||||||
run;
|
run;
|
||||||
%end;
|
%end;
|
||||||
%mend;
|
%mend mp_jsonout;
|
||||||
|
|||||||
@@ -9,7 +9,15 @@
|
|||||||
|
|
||||||
%mp_searchcols(libs=sashelp work, cols=name sex age)
|
%mp_searchcols(libs=sashelp work, cols=name sex age)
|
||||||
|
|
||||||
@param libs=
|
@param libs=(SASHELP) Space separated list of libraries to search for columns
|
||||||
|
@param cols= Space separated list of column names to search for (not case
|
||||||
|
sensitive)
|
||||||
|
@param outds=(mp_searchcols) the table to create with the results. Will have
|
||||||
|
one line per table match.
|
||||||
|
@param match=(ANY) The match type. Valid values:
|
||||||
|
@li ANY - The table contains at least one of the columns
|
||||||
|
@li WILD - The table contains a column with a name that partially matches
|
||||||
|
|
||||||
@version 9.2
|
@version 9.2
|
||||||
@author Allan Bowe
|
@author Allan Bowe
|
||||||
**/
|
**/
|
||||||
@@ -17,6 +25,7 @@
|
|||||||
%macro mp_searchcols(libs=sashelp
|
%macro mp_searchcols(libs=sashelp
|
||||||
,cols=
|
,cols=
|
||||||
,outds=mp_searchcols
|
,outds=mp_searchcols
|
||||||
|
,match=ANY
|
||||||
)/*/STORE SOURCE*/;
|
)/*/STORE SOURCE*/;
|
||||||
|
|
||||||
%put &sysmacroname process began at %sysfunc(datetime(),datetime19.);
|
%put &sysmacroname process began at %sysfunc(datetime(),datetime19.);
|
||||||
@@ -38,8 +47,10 @@ create table _data_ as
|
|||||||
%end;
|
%end;
|
||||||
order by 1,2,3;
|
order by 1,2,3;
|
||||||
|
|
||||||
|
%local tempds;
|
||||||
|
%let tempds=&syslast;
|
||||||
data &outds;
|
data &outds;
|
||||||
set &syslast;
|
set &tempds;
|
||||||
length cols matchcols $32767;
|
length cols matchcols $32767;
|
||||||
cols=upcase(symget('cols'));
|
cols=upcase(symget('cols'));
|
||||||
colcount=countw(cols);
|
colcount=countw(cols);
|
||||||
@@ -53,10 +64,29 @@ data &outds;
|
|||||||
retain matchcols;
|
retain matchcols;
|
||||||
matchcols='';
|
matchcols='';
|
||||||
end;
|
end;
|
||||||
|
%if &match=ANY %then %do;
|
||||||
if findw(cols,name,,'spit') then do;
|
if findw(cols,name,,'spit') then do;
|
||||||
sumcols+1;
|
sumcols+1;
|
||||||
matchcols=cats(matchcols)!!' '!!cats(name);
|
matchcols=cats(matchcols)!!' '!!cats(name);
|
||||||
end;
|
end;
|
||||||
|
%end;
|
||||||
|
%else %if &match=WILD %then %do;
|
||||||
|
if _n_=1 then do;
|
||||||
|
retain wcount;
|
||||||
|
wcount=countw(cols);
|
||||||
|
drop wcount;
|
||||||
|
end;
|
||||||
|
do i=1 to wcount;
|
||||||
|
length curword $32;
|
||||||
|
curword=scan(cols,i,' ');
|
||||||
|
drop curword;
|
||||||
|
if index(name,cats(curword)) then do;
|
||||||
|
sumcols+1;
|
||||||
|
matchcols=cats(matchcols)!!' '!!cats(curword);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
%end;
|
||||||
|
|
||||||
if last.memname then do;
|
if last.memname then do;
|
||||||
if sumcols>0 then output;
|
if sumcols>0 then output;
|
||||||
if sumcols=colcount then putlog "Full Match: " libname memname;
|
if sumcols=colcount then putlog "Full Match: " libname memname;
|
||||||
@@ -66,6 +96,8 @@ run;
|
|||||||
|
|
||||||
proc sort; by descending sumcols memname libname; run;
|
proc sort; by descending sumcols memname libname; run;
|
||||||
|
|
||||||
|
proc sql;
|
||||||
|
drop table &tempds;
|
||||||
%put &sysmacroname process finished at %sysfunc(datetime(),datetime19.);
|
%put &sysmacroname process finished at %sysfunc(datetime(),datetime19.);
|
||||||
|
|
||||||
%mend;
|
%mend mp_searchcols;
|
||||||
@@ -36,8 +36,20 @@
|
|||||||
%let contentype=%upcase(&contenttype);
|
%let contentype=%upcase(&contenttype);
|
||||||
%local platform; %let platform=%mf_getplatform();
|
%local platform; %let platform=%mf_getplatform();
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* check engine type to avoid the below err message:
|
||||||
|
* > Function is only valid for filerefs using the CACHE access method.
|
||||||
|
*/
|
||||||
|
%local streamweb;
|
||||||
|
%let streamweb=0;
|
||||||
|
data _null_;
|
||||||
|
set sashelp.vextfl(where=(upcase(fileref)="_WEBOUT"));
|
||||||
|
if xengine='STREAM' then call symputx('streamweb',1,'l');
|
||||||
|
run;
|
||||||
|
|
||||||
%if &contentype=ZIP %then %do;
|
%if &contentype=ZIP %then %do;
|
||||||
%if &platform=SASMETA %then %do;
|
%if &platform=SASMETA and &streamweb=1 %then %do;
|
||||||
data _null_;
|
data _null_;
|
||||||
rc=stpsrv_header('Content-type','application/zip');
|
rc=stpsrv_header('Content-type','application/zip');
|
||||||
rc=stpsrv_header('Content-disposition',"attachment; filename=&outname");
|
rc=stpsrv_header('Content-disposition',"attachment; filename=&outname");
|
||||||
@@ -51,7 +63,7 @@
|
|||||||
%end;
|
%end;
|
||||||
%else %if &contentype=EXCEL %then %do;
|
%else %if &contentype=EXCEL %then %do;
|
||||||
/* suitable for XLS format */
|
/* suitable for XLS format */
|
||||||
%if &platform=SASMETA %then %do;
|
%if &platform=SASMETA and &streamweb=1 %then %do;
|
||||||
data _null_;
|
data _null_;
|
||||||
rc=stpsrv_header('Content-type','application/vnd.ms-excel');
|
rc=stpsrv_header('Content-type','application/vnd.ms-excel');
|
||||||
rc=stpsrv_header('Content-disposition',"attachment; filename=&outname");
|
rc=stpsrv_header('Content-disposition',"attachment; filename=&outname");
|
||||||
@@ -64,7 +76,7 @@
|
|||||||
%end;
|
%end;
|
||||||
%end;
|
%end;
|
||||||
%else %if &contentype=XLSX %then %do;
|
%else %if &contentype=XLSX %then %do;
|
||||||
%if &platform=SASMETA %then %do;
|
%if &platform=SASMETA and &streamweb=1 %then %do;
|
||||||
data _null_;
|
data _null_;
|
||||||
rc=stpsrv_header('Content-type',
|
rc=stpsrv_header('Content-type',
|
||||||
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
|
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
|
||||||
@@ -79,7 +91,7 @@
|
|||||||
%end;
|
%end;
|
||||||
%end;
|
%end;
|
||||||
%else %if &contentype=TEXT %then %do;
|
%else %if &contentype=TEXT %then %do;
|
||||||
%if &platform=SASMETA %then %do;
|
%if &platform=SASMETA and &streamweb=1 %then %do;
|
||||||
data _null_;
|
data _null_;
|
||||||
rc=stpsrv_header('Content-type','application/text');
|
rc=stpsrv_header('Content-type','application/text');
|
||||||
rc=stpsrv_header('Content-disposition',"attachment; filename=&outname");
|
rc=stpsrv_header('Content-disposition',"attachment; filename=&outname");
|
||||||
@@ -92,7 +104,7 @@
|
|||||||
%end;
|
%end;
|
||||||
%end;
|
%end;
|
||||||
%else %if &contentype=CSV %then %do;
|
%else %if &contentype=CSV %then %do;
|
||||||
%if &platform=SASMETA %then %do;
|
%if &platform=SASMETA and &streamweb=1 %then %do;
|
||||||
data _null_;
|
data _null_;
|
||||||
rc=stpsrv_header('Content-type','application/csv');
|
rc=stpsrv_header('Content-type','application/csv');
|
||||||
rc=stpsrv_header('Content-disposition',"attachment; filename=&outname");
|
rc=stpsrv_header('Content-disposition',"attachment; filename=&outname");
|
||||||
@@ -122,4 +134,4 @@
|
|||||||
%mp_binarycopy(inloc="&inloc",outref=_webout)
|
%mp_binarycopy(inloc="&inloc",outref=_webout)
|
||||||
%end;
|
%end;
|
||||||
|
|
||||||
%mend;
|
%mend;
|
||||||
|
|||||||
259
base/mp_testservice.sas
Normal file
259
base/mp_testservice.sas
Normal file
@@ -0,0 +1,259 @@
|
|||||||
|
/**
|
||||||
|
@file mp_testservice.sas
|
||||||
|
@brief Will execute a test against a SASjs web service on SAS 9 or Viya
|
||||||
|
@details Prepares the input files and retrieves the resulting datasets from
|
||||||
|
the response JSON.
|
||||||
|
|
||||||
|
%mp_testjob(
|
||||||
|
duration=60*5
|
||||||
|
)
|
||||||
|
|
||||||
|
Note - the _webout fileref should NOT be assigned prior to running this macro.
|
||||||
|
|
||||||
|
@param [in] program The _PROGRAM endpoint to test
|
||||||
|
@param [in] inputfiles=(0) A list of space seperated fileref:filename pairs as
|
||||||
|
follows:
|
||||||
|
inputfiles=inref:filename inref2:filename2
|
||||||
|
@param [in] inputparams=(0) A dataset containing name/value pairs in the
|
||||||
|
following format:
|
||||||
|
|name:$32|value:$1000|
|
||||||
|
|---|---|
|
||||||
|
|stpmacname|some value|
|
||||||
|
|mustbevalidname|can be anything, oops, %abort!!|
|
||||||
|
|
||||||
|
@param [in] debug= (log) Provide the _debug value
|
||||||
|
@param [in] viyaresult=(WEBOUT_JSON) The Viya result type to return. For
|
||||||
|
more info, see mv_getjobresult.sas
|
||||||
|
@param [out] outlib= (0) Output libref to contain the final tables. Set to
|
||||||
|
0 if the service output is not in JSON format.
|
||||||
|
@param [out] outref= (0) Output fileref to create, to contain the full _webout
|
||||||
|
response.
|
||||||
|
|
||||||
|
<h4> SAS Macros </h4>
|
||||||
|
@li mf_getplatform.sas
|
||||||
|
@li mf_getuniquefileref.sas
|
||||||
|
@li mf_getuniquename.sas
|
||||||
|
@li mp_abort.sas
|
||||||
|
@li mp_binarycopy.sas
|
||||||
|
@li mv_getjobresult.sas
|
||||||
|
@li mv_jobflow.sas
|
||||||
|
|
||||||
|
@version 9.4
|
||||||
|
@author Allan Bowe
|
||||||
|
|
||||||
|
**/
|
||||||
|
|
||||||
|
%macro mp_testservice(program,
|
||||||
|
inputfiles=0,
|
||||||
|
inputparams=0,
|
||||||
|
debug=log,
|
||||||
|
outlib=0,
|
||||||
|
outref=0,
|
||||||
|
viyaresult=WEBOUT_JSON
|
||||||
|
)/*/STORE SOURCE*/;
|
||||||
|
%local mdebug;
|
||||||
|
%if &debug ne 0 %then %do;
|
||||||
|
%let mdebug=1;
|
||||||
|
%put &sysmacroname entry vars:;
|
||||||
|
%put _local_;
|
||||||
|
%end;
|
||||||
|
%else %let mdebug=0;
|
||||||
|
|
||||||
|
/* sanitise inputparams */
|
||||||
|
%local pcnt;
|
||||||
|
%let pcnt=0;
|
||||||
|
%if &inputparams ne 0 %then %do;
|
||||||
|
data _null_;
|
||||||
|
set &inputparams;
|
||||||
|
if not nvalid(name,'v7') then putlog (_all_)(=);
|
||||||
|
else if name in (
|
||||||
|
'program','inputfiles','inputparams','debug','outlib','outref'
|
||||||
|
) then putlog (_all_)(=);
|
||||||
|
else do;
|
||||||
|
x+1;
|
||||||
|
call symputx(name,quote(cats(value)),'l');
|
||||||
|
call symputx('pval'!!left(x),name,'l');
|
||||||
|
call symputx('pcnt',x,'l');
|
||||||
|
end;
|
||||||
|
run;
|
||||||
|
%mp_abort(iftrue= (%mf_nobs(&inputparams) ne &pcnt)
|
||||||
|
,mac=&sysmacroname
|
||||||
|
,msg=%str(Invalid values in &inputparams)
|
||||||
|
)
|
||||||
|
%end;
|
||||||
|
|
||||||
|
|
||||||
|
%local fref1 webref;
|
||||||
|
%let fref1=%mf_getuniquefileref();
|
||||||
|
%let webref=%mf_getuniquefileref();
|
||||||
|
|
||||||
|
%local platform;
|
||||||
|
%let platform=%mf_getplatform();
|
||||||
|
%if &platform=SASMETA %then %do;
|
||||||
|
|
||||||
|
/* parse the input files */
|
||||||
|
%local webcount i var;
|
||||||
|
%if %quote(&inputfiles) ne 0 %then %do;
|
||||||
|
%let webcount=%sysfunc(countw(&inputfiles));
|
||||||
|
%put &=webcount;
|
||||||
|
%do i=1 %to &webcount;
|
||||||
|
%let var=%scan(&inputfiles,&i,%str( ));
|
||||||
|
%local webfref&i webname&i;
|
||||||
|
%let webref&i=%scan(&var,1,%str(:));
|
||||||
|
%let webname&i=%scan(&var,2,%str(:));
|
||||||
|
%put webref&i=&&webref&i;
|
||||||
|
%put webname&i=&&webname&i;
|
||||||
|
%end;
|
||||||
|
%end;
|
||||||
|
%else %let webcount=0;
|
||||||
|
|
||||||
|
proc stp program="&program";
|
||||||
|
inputparam _program="&program"
|
||||||
|
%do i=1 %to &webcount;
|
||||||
|
%if &webcount=1 %then %do;
|
||||||
|
_webin_fileref="&&webref&i"
|
||||||
|
_webin_name="&&webname&i"
|
||||||
|
%end;
|
||||||
|
%else %do;
|
||||||
|
_webin_fileref&i="&&webref&i"
|
||||||
|
_webin_name&i="&&webname&i"
|
||||||
|
%end;
|
||||||
|
%end;
|
||||||
|
_webin_file_count="&webcount"
|
||||||
|
_debug="&debug"
|
||||||
|
%do i=1 %to &pcnt;
|
||||||
|
/* resolve name only, proc stp fetches value */
|
||||||
|
&&pval&i=&&&&&&pval&i
|
||||||
|
%end;
|
||||||
|
;
|
||||||
|
%do i=1 %to &webcount;
|
||||||
|
inputfile &&webref&i;
|
||||||
|
%end;
|
||||||
|
outputfile _webout=&webref;
|
||||||
|
run;
|
||||||
|
|
||||||
|
data _null_;
|
||||||
|
infile &webref;
|
||||||
|
file &fref1;
|
||||||
|
input;
|
||||||
|
length line $10000;
|
||||||
|
if index(_infile_,'>>weboutBEGIN<<') then do;
|
||||||
|
line=tranwrd(_infile_,'>>weboutBEGIN<<','');
|
||||||
|
put line;
|
||||||
|
end;
|
||||||
|
else if index(_infile_,'>>weboutEND<<') then do;
|
||||||
|
line=tranwrd(_infile_,'>>weboutEND<<','');
|
||||||
|
put line;
|
||||||
|
stop;
|
||||||
|
end;
|
||||||
|
else put _infile_;
|
||||||
|
run;
|
||||||
|
data _null_;
|
||||||
|
infile &fref1;
|
||||||
|
input;
|
||||||
|
put _infile_;
|
||||||
|
run;
|
||||||
|
%if &outlib ne 0 %then %do;
|
||||||
|
libname &outlib json (&fref1);
|
||||||
|
%end;
|
||||||
|
%if &outref ne 0 %then %do;
|
||||||
|
filename &outref temp;
|
||||||
|
%mp_binarycopy(inref=&webref,outref=&outref)
|
||||||
|
%end;
|
||||||
|
|
||||||
|
%end;
|
||||||
|
%else %if &platform=SASVIYA %then %do;
|
||||||
|
|
||||||
|
/* prepare inputparams */
|
||||||
|
%local ds1;
|
||||||
|
%let ds1=%mf_getuniquename();
|
||||||
|
%if "&inputparams" ne "0" %then %do;
|
||||||
|
proc transpose data=&inputparams out=&ds1;
|
||||||
|
id name;
|
||||||
|
var value;
|
||||||
|
run;
|
||||||
|
%end;
|
||||||
|
%else %do;
|
||||||
|
data &ds1;run;
|
||||||
|
%end;
|
||||||
|
|
||||||
|
/* parse the input files - convert to sasjs params */
|
||||||
|
%local webcount i var sasjs_tables;
|
||||||
|
%if %quote(&inputfiles) ne 0 %then %do;
|
||||||
|
%let webcount=%sysfunc(countw(&inputfiles));
|
||||||
|
%put &=webcount;
|
||||||
|
%do i=1 %to &webcount;
|
||||||
|
%let var=%scan(&inputfiles,&i,%str( ));
|
||||||
|
%local webfref&i webname&i sasjs&i.data;
|
||||||
|
%let webref&i=%scan(&var,1,%str(:));
|
||||||
|
%let webname&i=%scan(&var,2,%str(:));
|
||||||
|
%put webref&i=&&webref&i;
|
||||||
|
%put webname&i=&&webname&i;
|
||||||
|
|
||||||
|
%let sasjs_tables=&sasjs_tables &&webname&i;
|
||||||
|
data _null_;
|
||||||
|
infile &&webref&i lrecl=32767;
|
||||||
|
input;
|
||||||
|
if _n_=1 then call symputx("sasjs&i.data",_infile_);
|
||||||
|
else call symputx(
|
||||||
|
"sasjs&i.data",cats(symget("sasjs&i.data"),'0D0A'x,_infile_)
|
||||||
|
);
|
||||||
|
putlog "&sysmacroname infile: " _infile_;
|
||||||
|
run;
|
||||||
|
data &ds1;
|
||||||
|
set &ds1;
|
||||||
|
length sasjs&i.data $32767 sasjs_tables $1000;
|
||||||
|
sasjs&i.data=symget("sasjs&i.data");
|
||||||
|
sasjs_tables=symget("sasjs_tables");
|
||||||
|
run;
|
||||||
|
%end;
|
||||||
|
%end;
|
||||||
|
%else %let webcount=0;
|
||||||
|
|
||||||
|
data &ds1;
|
||||||
|
retain _program "&program";
|
||||||
|
set &ds1;
|
||||||
|
putlog "&sysmacroname inputparams:";
|
||||||
|
putlog (_all_)(=);
|
||||||
|
run;
|
||||||
|
|
||||||
|
%mv_jobflow(inds=&ds1
|
||||||
|
,maxconcurrency=1
|
||||||
|
,outds=work.results
|
||||||
|
,outref=&fref1
|
||||||
|
,mdebug=&mdebug
|
||||||
|
)
|
||||||
|
/* show the log */
|
||||||
|
data _null_;
|
||||||
|
infile &fref1;
|
||||||
|
input;
|
||||||
|
putlog _infile_;
|
||||||
|
run;
|
||||||
|
/* get the uri to fetch results */
|
||||||
|
data _null_;
|
||||||
|
set work.results;
|
||||||
|
call symputx('uri',uri);
|
||||||
|
putlog "&sysmacroname: fetching results for " uri;
|
||||||
|
run;
|
||||||
|
/* fetch results from webout.json */
|
||||||
|
%mv_getjobresult(uri=&uri,
|
||||||
|
result=&viyaresult,
|
||||||
|
outref=&outref,
|
||||||
|
outlib=&outlib,
|
||||||
|
mdebug=&mdebug
|
||||||
|
)
|
||||||
|
|
||||||
|
%end;
|
||||||
|
%else %do;
|
||||||
|
%put %str(ERR)OR: Unrecognised platform: &platform;
|
||||||
|
%end;
|
||||||
|
|
||||||
|
%if &mdebug=0 %then %do;
|
||||||
|
filename &webref clear;
|
||||||
|
%end;
|
||||||
|
%else %do;
|
||||||
|
%put &sysmacroname exit vars:;
|
||||||
|
%put _local_;
|
||||||
|
%end;
|
||||||
|
|
||||||
|
%mend mp_testservice;
|
||||||
@@ -22,6 +22,7 @@
|
|||||||
|
|
||||||
@param [in] incol The column to be validated
|
@param [in] incol The column to be validated
|
||||||
@param [in] rule The rule to apply. Current rules:
|
@param [in] rule The rule to apply. Current rules:
|
||||||
|
@li ISNUM - checks if the variable is numeric
|
||||||
@li LIBDS - matches LIBREF.DATASET format
|
@li LIBDS - matches LIBREF.DATASET format
|
||||||
@param [out] outcol The variable to create, with the results of the match
|
@param [out] outcol The variable to create, with the results of the match
|
||||||
|
|
||||||
@@ -62,4 +63,4 @@
|
|||||||
else &outcol=0;
|
else &outcol=0;
|
||||||
%end;
|
%end;
|
||||||
|
|
||||||
%mend;
|
%mend mp_validatecol;
|
||||||
|
|||||||
@@ -86,10 +86,11 @@ data _null_;
|
|||||||
put "/* Created on %sysfunc(datetime(),datetime19.) by %mf_getuser() */";
|
put "/* Created on %sysfunc(datetime(),datetime19.) by %mf_getuser() */";
|
||||||
/* WEBOUT BEGIN */
|
/* WEBOUT BEGIN */
|
||||||
put ' ';
|
put ' ';
|
||||||
put '%macro mp_jsonout(action,ds,jref=_webout,dslabel=,fmt=Y,engine=PROCJSON,dbg=0 ';
|
put '%macro mp_jsonout(action,ds,jref=_webout,dslabel=,fmt=Y,engine=DATASTEP,dbg=0 ';
|
||||||
put ')/*/STORE SOURCE*/; ';
|
put ')/*/STORE SOURCE*/; ';
|
||||||
put '%put output location=&jref; ';
|
put '%put output location=&jref; ';
|
||||||
put '%if &action=OPEN %then %do; ';
|
put '%if &action=OPEN %then %do; ';
|
||||||
|
put ' options nobomfile; ';
|
||||||
put ' data _null_;file &jref encoding=''utf-8''; ';
|
put ' data _null_;file &jref encoding=''utf-8''; ';
|
||||||
put ' put ''{"START_DTTM" : "'' "%sysfunc(datetime(),datetime20.3)" ''"''; ';
|
put ' put ''{"START_DTTM" : "'' "%sysfunc(datetime(),datetime20.3)" ''"''; ';
|
||||||
put ' run; ';
|
put ' run; ';
|
||||||
@@ -117,6 +118,64 @@ data _null_;
|
|||||||
put ' %put &sysmacroname: &ds NOT FOUND!!!; ';
|
put ' %put &sysmacroname: &ds NOT FOUND!!!; ';
|
||||||
put ' %return; ';
|
put ' %return; ';
|
||||||
put ' %end; ';
|
put ' %end; ';
|
||||||
|
put ' %if &fmt=Y %then %do; ';
|
||||||
|
put ' %put converting every variable to a formatted variable; ';
|
||||||
|
put ' /* see mp_ds2fmtds.sas for source */ ';
|
||||||
|
put ' proc contents noprint data=&ds ';
|
||||||
|
put ' out=_data_(keep=name type length format formatl formatd varnum); ';
|
||||||
|
put ' run; ';
|
||||||
|
put ' proc sort; ';
|
||||||
|
put ' by varnum; ';
|
||||||
|
put ' run; ';
|
||||||
|
put ' %local fmtds; ';
|
||||||
|
put ' %let fmtds=%scan(&syslast,2,.); ';
|
||||||
|
put ' /* prepare formats and varnames */ ';
|
||||||
|
put ' data _null_; ';
|
||||||
|
put ' set &fmtds end=last; ';
|
||||||
|
put ' name=upcase(name); ';
|
||||||
|
put ' /* fix formats */ ';
|
||||||
|
put ' if type=2 or type=6 then do; ';
|
||||||
|
put ' length fmt $49.; ';
|
||||||
|
put ' if format='''' then fmt=cats(''$'',length,''.''); ';
|
||||||
|
put ' else if formatl=0 then fmt=cats(format,''.''); ';
|
||||||
|
put ' else fmt=cats(format,formatl,''.''); ';
|
||||||
|
put ' newlen=max(formatl,length); ';
|
||||||
|
put ' end; ';
|
||||||
|
put ' else do; ';
|
||||||
|
put ' if format='''' then fmt=''best.''; ';
|
||||||
|
put ' else if formatl=0 then fmt=cats(format,''.''); ';
|
||||||
|
put ' else if formatd=0 then fmt=cats(format,formatl,''.''); ';
|
||||||
|
put ' else fmt=cats(format,formatl,''.'',formatd); ';
|
||||||
|
put ' /* needs to be wide, for datetimes etc */ ';
|
||||||
|
put ' newlen=max(length,formatl,24); ';
|
||||||
|
put ' end; ';
|
||||||
|
put ' /* 32 char unique name */ ';
|
||||||
|
put ' newname=''sasjs''!!substr(cats(put(md5(name),$hex32.)),1,27); ';
|
||||||
|
put ' ';
|
||||||
|
put ' call symputx(cats(''name'',_n_),name,''l''); ';
|
||||||
|
put ' call symputx(cats(''newname'',_n_),newname,''l''); ';
|
||||||
|
put ' call symputx(cats(''len'',_n_),newlen,''l''); ';
|
||||||
|
put ' call symputx(cats(''fmt'',_n_),fmt,''l''); ';
|
||||||
|
put ' call symputx(cats(''type'',_n_),type,''l''); ';
|
||||||
|
put ' if last then call symputx(''nobs'',_n_,''l''); ';
|
||||||
|
put ' run; ';
|
||||||
|
put ' data &fmtds; ';
|
||||||
|
put ' /* rename on entry */ ';
|
||||||
|
put ' set &ds(rename=( ';
|
||||||
|
put ' %local i; ';
|
||||||
|
put ' %do i=1 %to &nobs; ';
|
||||||
|
put ' &&name&i=&&newname&i ';
|
||||||
|
put ' %end; ';
|
||||||
|
put ' )); ';
|
||||||
|
put ' %do i=1 %to &nobs; ';
|
||||||
|
put ' length &&name&i $&&len&i; ';
|
||||||
|
put ' &&name&i=left(put(&&newname&i,&&fmt&i)); ';
|
||||||
|
put ' drop &&newname&i; ';
|
||||||
|
put ' %end; ';
|
||||||
|
put ' if _error_ then call symputx(''syscc'',1012); ';
|
||||||
|
put ' run; ';
|
||||||
|
put ' %let ds=&fmtds; ';
|
||||||
|
put ' %end; /* &fmt=Y */ ';
|
||||||
put ' data _null_;file &jref mod ; ';
|
put ' data _null_;file &jref mod ; ';
|
||||||
put ' put "["; call symputx(''cols'',0,''l''); ';
|
put ' put "["; call symputx(''cols'',0,''l''); ';
|
||||||
put ' proc sort ';
|
put ' proc sort ';
|
||||||
@@ -200,7 +259,7 @@ data _null_;
|
|||||||
put ' put "}"; ';
|
put ' put "}"; ';
|
||||||
put ' run; ';
|
put ' run; ';
|
||||||
put '%end; ';
|
put '%end; ';
|
||||||
put '%mend; ';
|
put '%mend mp_jsonout; ';
|
||||||
put '%macro mm_webout(action,ds,dslabel=,fref=_webout,fmt=Y); ';
|
put '%macro mm_webout(action,ds,dslabel=,fref=_webout,fmt=Y); ';
|
||||||
put '%global _webin_file_count _webin_fileref1 _webin_name1 _program _debug ';
|
put '%global _webin_file_count _webin_fileref1 _webin_name1 _program _debug ';
|
||||||
put ' sasjs_tables; ';
|
put ' sasjs_tables; ';
|
||||||
|
|||||||
@@ -48,7 +48,7 @@
|
|||||||
#### &prefix.added
|
#### &prefix.added
|
||||||
|name:$32.|metaID:$17.|SAStabName:$32.|
|
|name:$32.|metaID:$17.|SAStabName:$32.|
|
||||||
|---|---|---|
|
|---|---|---|
|
||||||
|||DATA1|
|
| | |DATA1|
|
||||||
|
|
||||||
#### &prefix.deleted
|
#### &prefix.deleted
|
||||||
|name:$32.|metaID:$17.|SAStabName:$32.|
|
|name:$32.|metaID:$17.|SAStabName:$32.|
|
||||||
@@ -59,7 +59,7 @@
|
|||||||
|tabName:$32.|tabMetaID:$17.|SAStabName:$32.|metaName:$32.|metaID:$17.|sasname:$32.|metaType:$16.|change:$64.|
|
|tabName:$32.|tabMetaID:$17.|SAStabName:$32.|metaName:$32.|metaID:$17.|sasname:$32.|metaType:$16.|change:$64.|
|
||||||
|---|---|---|---|---|---|---|---|
|
|---|---|---|---|---|---|---|---|
|
||||||
|TABLE2|A5XLSNXI.BK0001HN|TABLE2|c|A5XLSNXI.BM000MA9|c|Column|Deleted|
|
|TABLE2|A5XLSNXI.BK0001HN|TABLE2|c|A5XLSNXI.BM000MA9|c|Column|Deleted|
|
||||||
||||d||d|Column|Added|
|
| | | |d| |d|Column|Added|
|
||||||
|
|
||||||
#### &prefix.meta
|
#### &prefix.meta
|
||||||
|Label1:$28.|cValue1:$1.|nValue1:D12.3|
|
|Label1:$28.|cValue1:$1.|nValue1:D12.3|
|
||||||
@@ -80,9 +80,8 @@
|
|||||||
such as dangling metadata, embedded passwords, security issues and more.
|
such as dangling metadata, embedded passwords, security issues and more.
|
||||||
|
|
||||||
@param [in] libname= the metadata name of the library to be compared
|
@param [in] libname= the metadata name of the library to be compared
|
||||||
@param [out] outlib= The output library in which to store the output tables.
|
@param [out] outlib=(work) The library in which to store the output tables.
|
||||||
Default=WORK.
|
@param [out] prefix=(metadiff) The prefix for the four tables created.
|
||||||
@param [out] prefix The prefix for the four tables created. Default=metadiff.
|
|
||||||
|
|
||||||
@version 9.3
|
@version 9.3
|
||||||
@author Allan Bowe
|
@author Allan Bowe
|
||||||
|
|||||||
@@ -1,20 +1,26 @@
|
|||||||
/**
|
/**
|
||||||
@file
|
@file
|
||||||
@brief Writes the code of an to an external file, or the log if none provided
|
@brief Writes the code of an STP to an external file
|
||||||
@details Get the
|
@details Fetches the SAS code from a Stored Process where the code is stored
|
||||||
|
in metadata.
|
||||||
|
|
||||||
usage:
|
Usage:
|
||||||
|
|
||||||
%mm_getstpcode(tree=/some/meta/path
|
%mm_getstpcode(tree=/some/meta/path
|
||||||
,name=someSTP
|
,name=someSTP
|
||||||
,outloc=/some/unquoted/filename.ext
|
,outloc=/some/unquoted/filename.ext
|
||||||
)
|
)
|
||||||
|
|
||||||
@param tree= The metadata path of the Stored Process (can also contain name)
|
@param [in] tree= The metadata path of the Stored Process (can also contain
|
||||||
@param name= Stored Process name. Leave blank if included above.
|
name)
|
||||||
@param outloc= full and unquoted path to the desired text file. This will be
|
@param [in] name= Stored Process name. Leave blank if included above.
|
||||||
overwritten if it already exists. If not provided, the code will be written
|
@param [out] outloc= (0) full and unquoted path to the desired text file.
|
||||||
to the log.
|
This will be overwritten if it already exists.
|
||||||
|
@param [out] outref= (0) Fileref to which to write the code.
|
||||||
|
@param [out] showlog=(NO) Set to YES to print log to the window
|
||||||
|
|
||||||
|
<h4> SAS Macros </h4>
|
||||||
|
@li mf_getuniquefileref.sas
|
||||||
|
|
||||||
@author Allan Bowe
|
@author Allan Bowe
|
||||||
|
|
||||||
@@ -23,8 +29,10 @@
|
|||||||
%macro mm_getstpcode(
|
%macro mm_getstpcode(
|
||||||
tree=/User Folders/sasdemo/somestp
|
tree=/User Folders/sasdemo/somestp
|
||||||
,name=
|
,name=
|
||||||
,outloc=
|
,outloc=0
|
||||||
|
,outref=0
|
||||||
,mDebug=1
|
,mDebug=1
|
||||||
|
,showlog=NO
|
||||||
);
|
);
|
||||||
|
|
||||||
%local mD;
|
%local mD;
|
||||||
@@ -92,14 +100,18 @@ data _null_;
|
|||||||
stop;
|
stop;
|
||||||
|
|
||||||
%local outeng;
|
%local outeng;
|
||||||
%if %length(&outloc)=0 %then %let outeng=TEMP;
|
%if "&outloc"="0" %then %let outeng=TEMP;
|
||||||
%else %let outeng="&outloc";
|
%else %let outeng="&outloc";
|
||||||
|
%local fref;
|
||||||
|
%if &outref=0 %then %let fref=%mf_getuniquefileref();
|
||||||
|
%else %let fref=&outref;
|
||||||
|
|
||||||
/* read the content, byte by byte, resolving escaped chars */
|
/* read the content, byte by byte, resolving escaped chars */
|
||||||
filename __outdoc &outeng lrecl=100000;
|
filename &fref &outeng lrecl=100000;
|
||||||
data _null_;
|
data _null_;
|
||||||
length filein 8 fileid 8;
|
length filein 8 fileid 8;
|
||||||
filein = fopen("__getdoc","I",1,"B");
|
filein = fopen("__getdoc","I",1,"B");
|
||||||
fileid = fopen("__outdoc","O",1,"B");
|
fileid = fopen("&fref","O",1,"B");
|
||||||
rec = "20"x;
|
rec = "20"x;
|
||||||
length entity $6;
|
length entity $6;
|
||||||
do while(fread(filein)=0);
|
do while(fread(filein)=0);
|
||||||
@@ -140,9 +152,9 @@ data _null_;
|
|||||||
rc=fclose(fileid);
|
rc=fclose(fileid);
|
||||||
run;
|
run;
|
||||||
|
|
||||||
%if &outeng=TEMP %then %do;
|
%if &showlog=YES %then %do;
|
||||||
data _null_;
|
data _null_;
|
||||||
infile __outdoc lrecl=32767 end=last;
|
infile &fref lrecl=32767 end=last;
|
||||||
input;
|
input;
|
||||||
if _n_=1 then putlog '>>stpcodeBEGIN<<';
|
if _n_=1 then putlog '>>stpcodeBEGIN<<';
|
||||||
putlog _infile_;
|
putlog _infile_;
|
||||||
@@ -151,6 +163,8 @@ run;
|
|||||||
%end;
|
%end;
|
||||||
|
|
||||||
filename __getdoc clear;
|
filename __getdoc clear;
|
||||||
filename __outdoc clear;
|
%if &outref=0 %then %do;
|
||||||
|
filename &fref clear;
|
||||||
|
%end;
|
||||||
|
|
||||||
%mend;
|
%mend mm_getstpcode;
|
||||||
|
|||||||
@@ -16,24 +16,6 @@
|
|||||||
"readMe": "../../README.md"
|
"readMe": "../../README.md"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"serviceConfig": {
|
|
||||||
"initProgram": "tests/testinit.sas",
|
|
||||||
"termProgram": "tests/testterm.sas",
|
|
||||||
"serviceFolders": [
|
|
||||||
"tests/base",
|
|
||||||
"tests/viya"
|
|
||||||
],
|
|
||||||
"macroVars": {
|
|
||||||
"mcTestAppLoc": "/Public/temp/macrocore"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"testConfig": {
|
|
||||||
"initProgram": "tests/testinit.sas",
|
|
||||||
"termProgram": "tests/testterm.sas",
|
|
||||||
"macroVars": {
|
|
||||||
"mcTestAppLoc": "/Public/temp/macrocore"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"defaultTarget": "viya",
|
"defaultTarget": "viya",
|
||||||
"targets": [
|
"targets": [
|
||||||
{
|
{
|
||||||
@@ -44,7 +26,23 @@
|
|||||||
"deployConfig": {
|
"deployConfig": {
|
||||||
"deployServicePack": true
|
"deployServicePack": true
|
||||||
},
|
},
|
||||||
"contextName": "SAS Job Execution compute context"
|
"macroFolders": [
|
||||||
|
"base",
|
||||||
|
"meta",
|
||||||
|
"metax",
|
||||||
|
"viya",
|
||||||
|
"lua",
|
||||||
|
"tests/base",
|
||||||
|
"tests/viya"
|
||||||
|
],
|
||||||
|
"contextName": "SAS Job Execution compute context",
|
||||||
|
"testConfig": {
|
||||||
|
"initProgram": "tests/testinit.sas",
|
||||||
|
"termProgram": "tests/testterm.sas",
|
||||||
|
"macroVars": {
|
||||||
|
"mcTestAppLoc": "/Public/temp/macrocore"
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@@ -1,352 +0,0 @@
|
|||||||
test_target,test_loc,sasjs_test_id,test_suite_result,test_description
|
|
||||||
mp_assertcolvals,tests/services/base/mp_assertcolvals.test.sas,effe793c-9f51-4b15-b935-03b9c46c05ca,PASS,At least one value has a match
|
|
||||||
mp_assertcolvals,tests/services/base/mp_assertcolvals.test.sas,effe793c-9f51-4b15-b935-03b9c46c05ca,PASS,All values have a match
|
|
||||||
mp_filtercheck,tests/services/base/mp_filtercheck.test.sas,d50073ee-e648-4ae2-a948-8b1fb63cf110,PASS,Valid filter query
|
|
||||||
mp_filtercheck,tests/services/base/mp_filtercheck.test.sas,d50073ee-e648-4ae2-a948-8b1fb63cf110,PASS,Invalid column name
|
|
||||||
mp_filtercheck,tests/services/base/mp_filtercheck.test.sas,d50073ee-e648-4ae2-a948-8b1fb63cf110,PASS,Invalid raw value
|
|
||||||
mp_filtercheck,tests/services/base/mp_filtercheck.test.sas,d50073ee-e648-4ae2-a948-8b1fb63cf110,PASS,Code injection - column name
|
|
||||||
mp_filtercheck,tests/services/base/mp_filtercheck.test.sas,d50073ee-e648-4ae2-a948-8b1fb63cf110,PASS,Code injection - raw value abort
|
|
||||||
mp_filtergenerate,tests/services/base/mp_filtergenerate.test.sas,e25543aa-1070-4a13-9df9-95cfbc279708,PASS,Valid filter
|
|
||||||
mp_filtergenerate,tests/services/base/mp_filtergenerate.test.sas,e25543aa-1070-4a13-9df9-95cfbc279708,PASS,Empty filter (return all records)
|
|
||||||
mp_filtergenerate,tests/services/base/mp_filtergenerate.test.sas,e25543aa-1070-4a13-9df9-95cfbc279708,PASS,Single line filter
|
|
||||||
mp_filtergenerate,tests/services/base/mp_filtergenerate.test.sas,e25543aa-1070-4a13-9df9-95cfbc279708,PASS,Single line 2 group filter
|
|
||||||
mp_filtergenerate,tests/services/base/mp_filtergenerate.test.sas,e25543aa-1070-4a13-9df9-95cfbc279708,PASS,Filter with nothing returned
|
|
||||||
mp_filtervalidate,tests/services/base/mp_filtervalidate.test.sas,cb8df59b-fedb-40de-9590-f1aa948756b5,PASS,Valid filter
|
|
||||||
mp_filtervalidate,tests/services/base/mp_filtervalidate.test.sas,cb8df59b-fedb-40de-9590-f1aa948756b5,PASS,Valid filter
|
|
||||||
mp_filtervalidate,tests/services/base/mp_filtervalidate.test.sas,cb8df59b-fedb-40de-9590-f1aa948756b5,PASS,Valid filter
|
|
||||||
mp_validatecol,tests/services/base/mp_validatecol.test.sas,307f95c2-83b4-4caa-8b2f-ba1a673d6ff4,FAIL,Testing LIBDS
|
|
||||||
mp_validatecol,tests/services/base/mp_validatecol.test.sas,307f95c2-83b4-4caa-8b2f-ba1a673d6ff4,PASS,Test2 - ISNUM
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,FAIL,Creating web service with invisible character
|
|
||||||
mv_createwebservice,tests/services/viya/mv_createwebservice.test.sas,1eb31d67-d56e-4d7b-aa14-3f2d21fa3545,PASS,Creating web service with invisible character
|
|
||||||
|
File diff suppressed because it is too large
Load Diff
60
tests/base/mf_getvarlist.test.sas
Normal file
60
tests/base/mf_getvarlist.test.sas
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
/**
|
||||||
|
@file
|
||||||
|
@brief Testing mf_getvarlist macro
|
||||||
|
|
||||||
|
<h4> SAS Macros </h4>
|
||||||
|
@li mf_getvarlist.sas
|
||||||
|
|
||||||
|
**/
|
||||||
|
|
||||||
|
|
||||||
|
%let test1=%mf_getvarlist(sashelp.class);
|
||||||
|
%let test2=%mf_getvarlist(sashelp.class,dlm=X);
|
||||||
|
%let test3=%mf_getvarlist(sashelp.class,dlm=%str(,),quote=double);
|
||||||
|
%let test4=%mf_getvarlist(sashelp.class,typefilter=N);
|
||||||
|
%let test5=%mf_getvarlist(sashelp.class,typefilter=C);
|
||||||
|
|
||||||
|
data work.test_results;
|
||||||
|
length test_description $256 test_result $4 test_comments base result $256;
|
||||||
|
test_description="Basic test";
|
||||||
|
base=symget('test1');
|
||||||
|
result='Name Sex Age Height Weight';
|
||||||
|
if base=result then test_result='PASS';
|
||||||
|
else test_result='FAIL';
|
||||||
|
test_comments="Comparing "!!trim(base)!!' vs '!!trim(result);
|
||||||
|
output;
|
||||||
|
|
||||||
|
test_description="DLM test";
|
||||||
|
base=symget('test2');
|
||||||
|
result='NameXSexXAgeXHeightXWeight';
|
||||||
|
if base=result then test_result='PASS';
|
||||||
|
else test_result='FAIL';
|
||||||
|
test_comments="Comparing "!!trim(base)!!' vs '!!trim(result);
|
||||||
|
output;
|
||||||
|
|
||||||
|
test_description="DLM + quote test";
|
||||||
|
base=symget('test3');
|
||||||
|
result='"Name","Sex","Age","Height","Weight"';
|
||||||
|
if base=result then test_result='PASS';
|
||||||
|
else test_result='FAIL';
|
||||||
|
test_comments="Comparing "!!trim(base)!!' vs '!!trim(result);
|
||||||
|
output;
|
||||||
|
|
||||||
|
test_description="Numeric Filter";
|
||||||
|
base=symget('test4');
|
||||||
|
result='Age Height Weight';
|
||||||
|
if base=result then test_result='PASS';
|
||||||
|
else test_result='FAIL';
|
||||||
|
test_comments="Comparing "!!trim(base)!!' vs '!!trim(result);
|
||||||
|
output;
|
||||||
|
|
||||||
|
test_description="Char Filter";
|
||||||
|
base=symget('test5');
|
||||||
|
result='Name Sex';
|
||||||
|
if base=result then test_result='PASS';
|
||||||
|
else test_result='FAIL';
|
||||||
|
test_comments="Comparing "!!trim(base)!!' vs '!!trim(result);
|
||||||
|
output;
|
||||||
|
|
||||||
|
drop base result;
|
||||||
|
run;
|
||||||
36
tests/base/mp_abort.test.nofix.sas
Normal file
36
tests/base/mp_abort.test.nofix.sas
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
/**
|
||||||
|
@file
|
||||||
|
@brief Testing mp_abort macro
|
||||||
|
@details This is an unfixed problem with mp_abort when using the
|
||||||
|
'unclosed macro' technique. This is only relevant for 9.4m3 environments,
|
||||||
|
which can suffer from hung multibridge sessions from %abort and endsas.
|
||||||
|
|
||||||
|
The issue is that when called within a macro, within a %include, AND that
|
||||||
|
macro contains subsequent logic, the service does not end cleanly - rather,
|
||||||
|
we see:
|
||||||
|
|
||||||
|
ERROR: %EVAL function has no expression to evaluate, or %IF statement has no condition.
|
||||||
|
ERROR: The macro TEST will stop executing.
|
||||||
|
|
||||||
|
We are not able to test this without a 9.4m3 environment, it is marked as
|
||||||
|
nofix.
|
||||||
|
|
||||||
|
<h4> SAS Macros </h4>
|
||||||
|
@li mp_abort.sas
|
||||||
|
@li mp_assert.sas
|
||||||
|
|
||||||
|
**/
|
||||||
|
|
||||||
|
%macro test();
|
||||||
|
|
||||||
|
filename blah temp;
|
||||||
|
data _null_;
|
||||||
|
file blah;
|
||||||
|
put '%mp_abort();';
|
||||||
|
run;
|
||||||
|
%inc blah;
|
||||||
|
|
||||||
|
%if 1=1 %then %put Houston - we have a problem here;
|
||||||
|
%mend test;
|
||||||
|
|
||||||
|
%test()
|
||||||
28
tests/base/mp_ds2fmtds.test.sas
Normal file
28
tests/base/mp_ds2fmtds.test.sas
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
/**
|
||||||
|
@file
|
||||||
|
@brief Testing mp_ds2fmtds.sas macro
|
||||||
|
|
||||||
|
<h4> SAS Macros </h4>
|
||||||
|
@li mp_ds2fmtds.sas
|
||||||
|
@li mp_assert.sas
|
||||||
|
|
||||||
|
**/
|
||||||
|
|
||||||
|
proc sql;
|
||||||
|
create table test as select * from dictionary.tables where libname='SASHELP';
|
||||||
|
|
||||||
|
filename inc temp;
|
||||||
|
data _null_;
|
||||||
|
set work.test;
|
||||||
|
file inc;
|
||||||
|
line=cats('%mp_ds2fmtds(sashelp.',memname,',',memname,')');
|
||||||
|
put line;
|
||||||
|
run;
|
||||||
|
|
||||||
|
%inc inc;
|
||||||
|
|
||||||
|
%mp_assert(
|
||||||
|
iftrue=(&syscc=0),
|
||||||
|
desc=Checking tables were created successfully,
|
||||||
|
outds=work.test_results
|
||||||
|
)
|
||||||
@@ -5,6 +5,7 @@
|
|||||||
<h4> SAS Macros </h4>
|
<h4> SAS Macros </h4>
|
||||||
@li mp_filtercheck.sas
|
@li mp_filtercheck.sas
|
||||||
@li mp_assertdsobs.sas
|
@li mp_assertdsobs.sas
|
||||||
|
@li mp_assert.sas
|
||||||
|
|
||||||
**/
|
**/
|
||||||
|
|
||||||
@@ -125,3 +126,23 @@ run;
|
|||||||
outds=work.test_results
|
outds=work.test_results
|
||||||
)
|
)
|
||||||
|
|
||||||
|
/* Supply variables with incorrect types */
|
||||||
|
data work.inds;
|
||||||
|
infile datalines4 dsd;
|
||||||
|
input GROUP_LOGIC:$3. SUBGROUP_LOGIC:$3. SUBGROUP_ID:8. VARIABLE_NM:$32.
|
||||||
|
OPERATOR_NM:$10. RAW_VALUE:8;
|
||||||
|
datalines4;
|
||||||
|
AND,AND,1,age,=,0
|
||||||
|
;;;;
|
||||||
|
run;
|
||||||
|
%let syscc=0;
|
||||||
|
%mp_filtercheck(work.inds,
|
||||||
|
targetds=sashelp.class,
|
||||||
|
outds=work.badrecords,
|
||||||
|
abort=NO
|
||||||
|
)
|
||||||
|
%mp_assert(iftrue=(&syscc=42),
|
||||||
|
desc=Throw error if RAW_VALUE is incorrect,
|
||||||
|
outds=work.test_results
|
||||||
|
)
|
||||||
|
%let syscc=0;
|
||||||
|
|||||||
42
tests/base/mp_jsonout.test.sas
Normal file
42
tests/base/mp_jsonout.test.sas
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
/**
|
||||||
|
@file
|
||||||
|
@brief Testing mp_jsonout.sas macro
|
||||||
|
|
||||||
|
<h4> SAS Macros </h4>
|
||||||
|
@li mp_jsonout.sas
|
||||||
|
@li mp_assert.sas
|
||||||
|
|
||||||
|
**/
|
||||||
|
|
||||||
|
filename webref temp;
|
||||||
|
|
||||||
|
data demo;
|
||||||
|
dtval=date();
|
||||||
|
format dtval date9.;
|
||||||
|
compare=put(date(),date9.);
|
||||||
|
call symputx('compare',compare);
|
||||||
|
run;
|
||||||
|
|
||||||
|
%mp_jsonout(OPEN,jref=webref)
|
||||||
|
%mp_jsonout(OBJ,demo,jref=webref,fmt=Y)
|
||||||
|
%mp_jsonout(CLOSE,jref=webref)
|
||||||
|
|
||||||
|
data _null_;
|
||||||
|
infile webref;
|
||||||
|
input;
|
||||||
|
putlog _infile_;
|
||||||
|
run;
|
||||||
|
|
||||||
|
libname web JSON fileref=webref;
|
||||||
|
%let dtval=0;
|
||||||
|
data work.test;
|
||||||
|
set web.demo;
|
||||||
|
call symputx('dtval',dtval);
|
||||||
|
run;
|
||||||
|
|
||||||
|
|
||||||
|
%mp_assert(
|
||||||
|
iftrue=(&dtval=&compare),
|
||||||
|
desc=Checking tables were created successfully,
|
||||||
|
outds=work.test_results
|
||||||
|
)
|
||||||
50
tests/base/mp_searchcols.test.sas
Normal file
50
tests/base/mp_searchcols.test.sas
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
/**
|
||||||
|
@file
|
||||||
|
@brief Testing mp_searchcols.sas
|
||||||
|
|
||||||
|
<h4> SAS Macros </h4>
|
||||||
|
@li mp_searchcols.sas
|
||||||
|
@li mp_assertdsobs.sas
|
||||||
|
|
||||||
|
|
||||||
|
**/
|
||||||
|
|
||||||
|
|
||||||
|
/** Test 1 - full col match */
|
||||||
|
data example1;
|
||||||
|
var1=1;
|
||||||
|
var2=2;
|
||||||
|
var3=3;
|
||||||
|
data example2;
|
||||||
|
var1=1;
|
||||||
|
var2=2;
|
||||||
|
data example3;
|
||||||
|
var2=2;
|
||||||
|
var3=3;
|
||||||
|
data example4;
|
||||||
|
matchmehere=1;
|
||||||
|
data example5;
|
||||||
|
hereyoucan_matchme_also=1;
|
||||||
|
data example6;
|
||||||
|
do_not_forget_me=1;
|
||||||
|
data example7;
|
||||||
|
we_shall_not_forget=1;
|
||||||
|
run;
|
||||||
|
|
||||||
|
%mp_searchcols(libs=work,cols=var1 var2,outds=testme)
|
||||||
|
|
||||||
|
%mp_assertdsobs(work.testme,
|
||||||
|
desc=Test1 - check exact variables are found,
|
||||||
|
test=EQUALS 3,
|
||||||
|
outds=work.test_results
|
||||||
|
)
|
||||||
|
|
||||||
|
/* test 2 - wildcard match */
|
||||||
|
|
||||||
|
%mp_searchcols(libs=work,cols=matchme forget,match=WILD, outds=testme2)
|
||||||
|
|
||||||
|
%mp_assertdsobs(work.testme2,
|
||||||
|
desc=Test1 - check fuzzy matches are found,
|
||||||
|
test=EQUALS 4,
|
||||||
|
outds=work.test_results
|
||||||
|
)
|
||||||
@@ -17,7 +17,7 @@ data test1;
|
|||||||
input;
|
input;
|
||||||
libds=_infile_;
|
libds=_infile_;
|
||||||
%mp_validatecol(libds,LIBDS,is_libds)
|
%mp_validatecol(libds,LIBDS,is_libds)
|
||||||
if libds=1;
|
if is_libds=1;
|
||||||
datalines4;
|
datalines4;
|
||||||
some.libname
|
some.libname
|
||||||
!lib.blah
|
!lib.blah
|
||||||
|
|||||||
@@ -5,4 +5,4 @@
|
|||||||
**/
|
**/
|
||||||
|
|
||||||
/* location in metadata or SAS Drive for temporary files */
|
/* location in metadata or SAS Drive for temporary files */
|
||||||
%let mcTestAppLoc=/Public/temp/test;
|
%let mcTestAppLoc=/Public/temp/macrocore;
|
||||||
@@ -18,24 +18,28 @@ data _null_;
|
|||||||
file testref;
|
file testref;
|
||||||
put '01'x;
|
put '01'x;
|
||||||
run;
|
run;
|
||||||
|
%put TEST1: creating web service;
|
||||||
%mv_createwebservice(
|
%mv_createwebservice(
|
||||||
path=&mcTestAppLoc/tests/macros,
|
path=&mcTestAppLoc/temp/macros,
|
||||||
code=testref,
|
name=mv_createwebservice,
|
||||||
name=mv_createwebservice
|
code=testref
|
||||||
)
|
)
|
||||||
|
%put TEST1: fetching web service code;
|
||||||
filename compare temp;
|
|
||||||
%mv_getjobcode(
|
%mv_getjobcode(
|
||||||
path=&mcTestAppLoc/tests/macros
|
path=&mcTestAppLoc/temp/macros,
|
||||||
,name=mv_createwebservice
|
name=mv_createwebservice,
|
||||||
,outref=compare;
|
outref=compare
|
||||||
)
|
)
|
||||||
|
%put TEST1: checking web service code;
|
||||||
data test_results;
|
data work.test_results;
|
||||||
length test_description $256 test_result $4 test_comments $256;
|
length test_description $256 test_result $4 test_comments $256;
|
||||||
infile compare;
|
infile compare end=eof;
|
||||||
input;
|
input;
|
||||||
if _infile_='01'x then test_result='PASS';
|
if eof then do;
|
||||||
else test_result='FAIL';
|
if _infile_='01'x then test_result='PASS';
|
||||||
test_description="Creating web service with invisible character";
|
else test_result='FAIL';
|
||||||
|
test_description="Creating web service with invisible character";
|
||||||
|
output;
|
||||||
|
stop;
|
||||||
|
end;
|
||||||
run;
|
run;
|
||||||
49
tests/viya/mv_getjobcode.test.sas
Normal file
49
tests/viya/mv_getjobcode.test.sas
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
/**
|
||||||
|
@file
|
||||||
|
@brief Testing mv_getjobcode macro
|
||||||
|
|
||||||
|
<h4> SAS Macros </h4>
|
||||||
|
@li mp_assert.sas
|
||||||
|
@li mv_createjob.sas
|
||||||
|
@li mv_getjobcode.sas
|
||||||
|
|
||||||
|
**/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test Case 1
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* write some code to a job */
|
||||||
|
%let incode=%str(data test; set sashelp.class;run;);
|
||||||
|
filename testref temp;
|
||||||
|
data _null_;
|
||||||
|
file testref;
|
||||||
|
put "&incode";
|
||||||
|
run;
|
||||||
|
%mv_createjob(
|
||||||
|
code=testref,
|
||||||
|
path=&mcTestAppLoc/services/temp,
|
||||||
|
name=some_job
|
||||||
|
)
|
||||||
|
|
||||||
|
/* now get the code back */
|
||||||
|
%mv_getjobcode(
|
||||||
|
path=&mcTestAppLoc/services/temp,
|
||||||
|
name=some_job,
|
||||||
|
outref=mycode
|
||||||
|
)
|
||||||
|
|
||||||
|
%let diditexist=NO;
|
||||||
|
data work.test1;
|
||||||
|
infile mycode;
|
||||||
|
input;
|
||||||
|
putlog _infile_;
|
||||||
|
line=_infile_;
|
||||||
|
check=symget('incode');
|
||||||
|
if _infile_=symget('incode') then call symputx('diditexist','YES');
|
||||||
|
run;
|
||||||
|
|
||||||
|
%mp_assert(
|
||||||
|
iftrue=(&diditexist=NO),
|
||||||
|
desc=Check if the code that was sent was successfully retrieved
|
||||||
|
)
|
||||||
70
tests/viya/mv_getjoblog.test.sas
Normal file
70
tests/viya/mv_getjoblog.test.sas
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
/**
|
||||||
|
@file
|
||||||
|
@brief Testing mv_createwebservice macro
|
||||||
|
|
||||||
|
<h4> SAS Macros </h4>
|
||||||
|
@li mp_assert.sas
|
||||||
|
@li mv_createjob.sas
|
||||||
|
@li mv_jobexecute.sas
|
||||||
|
@li mv_jobwaitfor.sas
|
||||||
|
@li mv_getjoblog.sas
|
||||||
|
|
||||||
|
**/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test Case 1
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* create a service */
|
||||||
|
filename testref temp;
|
||||||
|
data _null_;
|
||||||
|
file testref;
|
||||||
|
put 'data;run;';
|
||||||
|
put 'endsas;';
|
||||||
|
run;
|
||||||
|
%mv_createjob(
|
||||||
|
path=&mcTestAppLoc/jobs/temp,
|
||||||
|
code=testref,
|
||||||
|
name=testjob
|
||||||
|
)
|
||||||
|
|
||||||
|
%* Execute it;
|
||||||
|
%mv_jobexecute(
|
||||||
|
path=&mcTestAppLoc/jobs/temp,
|
||||||
|
name=testjob,
|
||||||
|
outds=work.info
|
||||||
|
)
|
||||||
|
|
||||||
|
%* Wait for it to finish;
|
||||||
|
data work.info;
|
||||||
|
set work.info;
|
||||||
|
where method='GET' and rel='state';
|
||||||
|
run;
|
||||||
|
%mv_jobwaitfor(ALL,inds=work.info,outds=work.jobstates)
|
||||||
|
|
||||||
|
%* and grab the uri;
|
||||||
|
data _null_;
|
||||||
|
set work.jobstates;
|
||||||
|
call symputx('uri',uri);
|
||||||
|
run;
|
||||||
|
|
||||||
|
%* Finally, fetch the log;
|
||||||
|
%mv_getjoblog(uri=%str(&uri),outref=mylog)
|
||||||
|
|
||||||
|
|
||||||
|
data _null_;
|
||||||
|
infile mylog end=eof;
|
||||||
|
input;
|
||||||
|
putlog _infile_;
|
||||||
|
retain found 0;
|
||||||
|
if index(_infile_,'endsas;') then do;
|
||||||
|
found=1;
|
||||||
|
call symputx('found',found);
|
||||||
|
end;
|
||||||
|
else if eof and found ne 1 then call symputx('found',0);
|
||||||
|
run;
|
||||||
|
|
||||||
|
%mp_assert(
|
||||||
|
iftrue=(%str(&found)=1),
|
||||||
|
desc=Check if the log was still fetched even though endsas was submitted
|
||||||
|
)
|
||||||
74
tests/viya/mv_getjobresult.test.sas
Normal file
74
tests/viya/mv_getjobresult.test.sas
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
/**
|
||||||
|
@file
|
||||||
|
@brief Testing mv_createwebservice macro
|
||||||
|
|
||||||
|
<h4> SAS Macros </h4>
|
||||||
|
@li mp_assertdsobs.sas
|
||||||
|
@li mv_createwebservice.sas
|
||||||
|
@li mv_getjobresult.sas
|
||||||
|
@li mv_jobflow.sas
|
||||||
|
|
||||||
|
**/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test Case 1
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* create a service */
|
||||||
|
filename testref temp;
|
||||||
|
data _null_;
|
||||||
|
file testref;
|
||||||
|
put 'data test; set sashelp.class;run;';
|
||||||
|
put '%webout(OPEN)';
|
||||||
|
put '%webout(OBJ,test)';
|
||||||
|
put '%webout(CLOSE)';
|
||||||
|
run;
|
||||||
|
%mv_createwebservice(
|
||||||
|
path=&mcTestAppLoc/services/temp,
|
||||||
|
code=testref,
|
||||||
|
name=testsvc
|
||||||
|
)
|
||||||
|
|
||||||
|
/* trigger and wait for it to finish */
|
||||||
|
data work.inputjobs;
|
||||||
|
_program="&mcTestAppLoc/services/temp/testsvc";
|
||||||
|
run;
|
||||||
|
%mv_jobflow(inds=work.inputjobs
|
||||||
|
,maxconcurrency=4
|
||||||
|
,outds=work.results
|
||||||
|
,outref=myjoblog
|
||||||
|
)
|
||||||
|
/* stream the log */
|
||||||
|
data _null_;
|
||||||
|
infile myjoblog;
|
||||||
|
input;
|
||||||
|
put _infile_;
|
||||||
|
run;
|
||||||
|
|
||||||
|
/* fetch the uri */
|
||||||
|
data _null_;
|
||||||
|
set work.results;
|
||||||
|
call symputx('uri',uri);
|
||||||
|
put (_all_)(=);
|
||||||
|
run;
|
||||||
|
|
||||||
|
/* now get the results */
|
||||||
|
%mv_getjobresult(uri=&uri
|
||||||
|
,result=WEBOUT_JSON
|
||||||
|
,outref=myweb
|
||||||
|
,outlib=myweblib
|
||||||
|
)
|
||||||
|
data _null_;
|
||||||
|
infile myweb;
|
||||||
|
input;
|
||||||
|
putlog _infile_;
|
||||||
|
run;
|
||||||
|
data work.out;
|
||||||
|
set myweblib.test;
|
||||||
|
put (_all_)(=);
|
||||||
|
run;
|
||||||
|
%mp_assertdsobs(work.out,
|
||||||
|
desc=Test1 - 19 obs from sashelp.class in service result,
|
||||||
|
test=EQUALS 19,
|
||||||
|
outds=work.test_results
|
||||||
|
)
|
||||||
78
tests/viya/mv_jobflow.test.1.sas
Normal file
78
tests/viya/mv_jobflow.test.1.sas
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
/**
|
||||||
|
|
||||||
|
@file
|
||||||
|
@brief Testing mv_jobflow macro
|
||||||
|
@details One of the remote jobs aborts with syscc>0 - test to
|
||||||
|
make sure this comes back to the calling session
|
||||||
|
|
||||||
|
<h4> SAS Macros </h4>
|
||||||
|
@li mp_assert.sas
|
||||||
|
@li mv_createjob.sas
|
||||||
|
@li mv_jobflow.sas
|
||||||
|
|
||||||
|
**/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test Case 1
|
||||||
|
*/
|
||||||
|
|
||||||
|
filename testprog temp;
|
||||||
|
data _null_;
|
||||||
|
file testprog;
|
||||||
|
put '%put this is job: &_program;'
|
||||||
|
/ '%put this was run in flow &flow_id;'
|
||||||
|
/ 'data ;'
|
||||||
|
/ ' rval=rand("uniform");'
|
||||||
|
/ ' rand=rval*¯ovar1;'
|
||||||
|
/ ' do x=1 to rand;'
|
||||||
|
/ ' y=rand*¯ovar2;'
|
||||||
|
/ ' if (rval>0.50) then abort;'
|
||||||
|
/ ' else output;'
|
||||||
|
/ ' end;'
|
||||||
|
/ 'run;'
|
||||||
|
;
|
||||||
|
run;
|
||||||
|
|
||||||
|
%mv_createjob(path=/Public/temp,name=demo1,code=testprog)
|
||||||
|
%mv_createjob(path=/Public/temp,name=demo2,code=testprog)
|
||||||
|
|
||||||
|
data work.inputjobs;
|
||||||
|
_contextName='SAS Job Execution compute context';
|
||||||
|
do flow_id=1 to 2;
|
||||||
|
do i=1 to 4;
|
||||||
|
_program='/Public/temp/demo1';
|
||||||
|
macrovar1=10*i;
|
||||||
|
macrovar2=4*i;
|
||||||
|
output;
|
||||||
|
i+1;
|
||||||
|
_program='/Public/temp/demo2';
|
||||||
|
macrovar1=40*i;
|
||||||
|
macrovar2=44*i;
|
||||||
|
output;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
run;
|
||||||
|
|
||||||
|
* Trigger the flow ;
|
||||||
|
|
||||||
|
%put NOTE: &=syscc;
|
||||||
|
|
||||||
|
%mv_jobflow(inds=work.inputjobs
|
||||||
|
,maxconcurrency=2
|
||||||
|
,outds=work.results
|
||||||
|
,outref=myjoblog
|
||||||
|
,raise_err=1
|
||||||
|
,mdebug=1
|
||||||
|
)
|
||||||
|
|
||||||
|
%put NOTE: &=syscc;
|
||||||
|
|
||||||
|
data _null_;
|
||||||
|
infile myjoblog;
|
||||||
|
input; put _infile_;
|
||||||
|
run;
|
||||||
|
|
||||||
|
%mp_assert(
|
||||||
|
iftrue=(&syscc ne 0),
|
||||||
|
desc=Check that non zero return code is returned if called job fails
|
||||||
|
)
|
||||||
74
tests/viya/mv_jobflow.test.2.sas
Normal file
74
tests/viya/mv_jobflow.test.2.sas
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
/**
|
||||||
|
@file
|
||||||
|
@brief Testing mv_jobflow macro
|
||||||
|
@details All jobs complete successfully with syscc = 0 - test to
|
||||||
|
make sure this comes back to the calling session
|
||||||
|
|
||||||
|
<h4> SAS Macros </h4>
|
||||||
|
@li mp_assert.sas
|
||||||
|
@li mv_createjob.sas
|
||||||
|
@li mv_jobflow.sas
|
||||||
|
**/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test Case 1
|
||||||
|
*/
|
||||||
|
filename testprog temp;
|
||||||
|
data _null_;
|
||||||
|
file testprog;
|
||||||
|
put '%put this is job: &_program;'
|
||||||
|
/ '%put this was run in flow &flow_id;'
|
||||||
|
/ 'data ;'
|
||||||
|
/ ' rval=rand("uniform");'
|
||||||
|
/ ' rand=rval*¯ovar1;'
|
||||||
|
/ ' do x=1 to rand;'
|
||||||
|
/ ' y=rand*¯ovar2;'
|
||||||
|
/ ' output;'
|
||||||
|
/ ' end;'
|
||||||
|
/ 'run;'
|
||||||
|
;
|
||||||
|
run;
|
||||||
|
|
||||||
|
%mv_createjob(path=/Public/temp,name=demo1,code=testprog)
|
||||||
|
%mv_createjob(path=/Public/temp,name=demo2,code=testprog)
|
||||||
|
|
||||||
|
data work.inputjobs;
|
||||||
|
_contextName='SAS Job Execution compute context';
|
||||||
|
do flow_id=1 to 2;
|
||||||
|
do i=1 to 4;
|
||||||
|
_program='/Public/temp/demo1';
|
||||||
|
macrovar1=10*i;
|
||||||
|
macrovar2=4*i;
|
||||||
|
output;
|
||||||
|
i+1;
|
||||||
|
_program='/Public/temp/demo2';
|
||||||
|
macrovar1=40*i;
|
||||||
|
macrovar2=44*i;
|
||||||
|
output;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
run;
|
||||||
|
|
||||||
|
* Trigger the flow ;
|
||||||
|
|
||||||
|
%put NOTE: &=syscc;
|
||||||
|
|
||||||
|
%mv_jobflow(inds=work.inputjobs
|
||||||
|
,maxconcurrency=2
|
||||||
|
,outds=work.results
|
||||||
|
,outref=myjoblog
|
||||||
|
,raise_err=1
|
||||||
|
,mdebug=1
|
||||||
|
)
|
||||||
|
|
||||||
|
%put NOTE: &=syscc;
|
||||||
|
|
||||||
|
data _null_;
|
||||||
|
infile myjoblog;
|
||||||
|
input; put _infile_;
|
||||||
|
run;
|
||||||
|
|
||||||
|
%mp_assert(
|
||||||
|
iftrue=(&syscc eq 0),
|
||||||
|
desc=Check that a zero return code is returned if no called job fails
|
||||||
|
)
|
||||||
@@ -39,23 +39,26 @@
|
|||||||
@li mf_isblank.sas
|
@li mf_isblank.sas
|
||||||
@li mv_deletejes.sas
|
@li mv_deletejes.sas
|
||||||
|
|
||||||
@param path= The full path (on SAS Drive) where the service will be created
|
@param [in] path= The full path (on SAS Drive) where the service will be
|
||||||
@param name= The name of the service
|
created
|
||||||
@param desc= The description of the service
|
@param [in] name= The name of the service
|
||||||
@param precode= Space separated list of filerefs, pointing to the code that
|
@param [in] desc= The description of the service
|
||||||
needs to be attached to the beginning of the service
|
@param [in] precode= Space separated list of filerefs, pointing to the code
|
||||||
@param code= Fileref(s) of the actual code to be added
|
that needs to be attached to the beginning of the service
|
||||||
@param access_token_var= The global macro variable to contain the access token
|
@param [in] code= Fileref(s) of the actual code to be added
|
||||||
@param grant_type= valid values are "password" or "authorization_code"
|
@param [in] access_token_var= The global macro variable to contain the access
|
||||||
|
token
|
||||||
|
@param [in] grant_type= valid values are "password" or "authorization_code"
|
||||||
(unquoted). The default is authorization_code.
|
(unquoted). The default is authorization_code.
|
||||||
@param replace= select NO to avoid replacing any existing service in that
|
@param [in] replace=(YES) Select NO to avoid replacing any existing service in
|
||||||
location
|
that location
|
||||||
@param adapter= the macro uses the sasjs adapter by default. To use another
|
@param [in] adapter= the macro uses the sasjs adapter by default. To use
|
||||||
adapter, add a (different) fileref here.
|
another adapter, add a (different) fileref here.
|
||||||
@param contextname= Choose a specific context on which to run the Job. Leave
|
@param [in] contextname= Choose a specific context on which to run the Job. Leave
|
||||||
blank to use the default context. From Viya 3.5 it is possible to configure
|
blank to use the default context. From Viya 3.5 it is possible to configure
|
||||||
a shared context - see
|
a shared context - see
|
||||||
https://go.documentation.sas.com/?docsetId=calcontexts&docsetTarget=n1hjn8eobk5pyhn1wg3ja0drdl6h.htm&docsetVersion=3.5&locale=en
|
https://go.documentation.sas.com/?docsetId=calcontexts&docsetTarget=n1hjn8eobk5pyhn1wg3ja0drdl6h.htm&docsetVersion=3.5&locale=en
|
||||||
|
@param [in] mdebug=(0) set to 1 to enable DEBUG messages
|
||||||
|
|
||||||
@version VIYA V.03.04
|
@version VIYA V.03.04
|
||||||
@author Allan Bowe, source: https://github.com/sasjs/core
|
@author Allan Bowe, source: https://github.com/sasjs/core
|
||||||
@@ -71,9 +74,17 @@ https://go.documentation.sas.com/?docsetId=calcontexts&docsetTarget=n1hjn8eobk5p
|
|||||||
,grant_type=sas_services
|
,grant_type=sas_services
|
||||||
,replace=YES
|
,replace=YES
|
||||||
,adapter=sasjs
|
,adapter=sasjs
|
||||||
,debug=0
|
,mdebug=0
|
||||||
,contextname=
|
,contextname=
|
||||||
|
,debug=0 /* @TODO - Deprecate */
|
||||||
);
|
);
|
||||||
|
%local dbg;
|
||||||
|
%if &mdebug=1 %then %do;
|
||||||
|
%put &sysmacroname entry vars:;
|
||||||
|
%put _local_;
|
||||||
|
%end;
|
||||||
|
%else %let dbg=*;
|
||||||
|
|
||||||
%local oauth_bearer;
|
%local oauth_bearer;
|
||||||
%if &grant_type=detect %then %do;
|
%if &grant_type=detect %then %do;
|
||||||
%if %symexist(&access_token_var) %then %let grant_type=authorization_code;
|
%if %symexist(&access_token_var) %then %let grant_type=authorization_code;
|
||||||
@@ -126,7 +137,7 @@ proc http method='GET' out=&fname1 &oauth_bearer
|
|||||||
headers "Authorization"="Bearer &&&access_token_var";
|
headers "Authorization"="Bearer &&&access_token_var";
|
||||||
%end;
|
%end;
|
||||||
run;
|
run;
|
||||||
%if &debug %then %do;
|
%if &mdebug=1 %then %do;
|
||||||
data _null_;
|
data _null_;
|
||||||
infile &fname1;
|
infile &fname1;
|
||||||
input;
|
input;
|
||||||
@@ -165,7 +176,7 @@ proc http method='GET'
|
|||||||
%end;
|
%end;
|
||||||
'Accept'='application/vnd.sas.collection+json'
|
'Accept'='application/vnd.sas.collection+json'
|
||||||
'Accept-Language'='string';
|
'Accept-Language'='string';
|
||||||
%if &debug=1 %then %do;
|
%if &mdebug=1 %then %do;
|
||||||
debug level = 3;
|
debug level = 3;
|
||||||
%end;
|
%end;
|
||||||
run;
|
run;
|
||||||
@@ -220,16 +231,17 @@ run;
|
|||||||
* These put statements are auto generated - to change the macro, change the
|
* These put statements are auto generated - to change the macro, change the
|
||||||
* source (mv_webout) and run `build.py`
|
* source (mv_webout) and run `build.py`
|
||||||
*/
|
*/
|
||||||
filename sasjs temp lrecl=3000;
|
filename &adapter temp lrecl=3000;
|
||||||
data _null_;
|
data _null_;
|
||||||
file sasjs;
|
file &adapter;
|
||||||
put "/* Created on %sysfunc(datetime(),datetime19.) by &sysuserid */";
|
put "/* Created on %sysfunc(datetime(),datetime19.) by &sysuserid */";
|
||||||
/* WEBOUT BEGIN */
|
/* WEBOUT BEGIN */
|
||||||
put ' ';
|
put ' ';
|
||||||
put '%macro mp_jsonout(action,ds,jref=_webout,dslabel=,fmt=Y,engine=PROCJSON,dbg=0 ';
|
put '%macro mp_jsonout(action,ds,jref=_webout,dslabel=,fmt=Y,engine=DATASTEP,dbg=0 ';
|
||||||
put ')/*/STORE SOURCE*/; ';
|
put ')/*/STORE SOURCE*/; ';
|
||||||
put '%put output location=&jref; ';
|
put '%put output location=&jref; ';
|
||||||
put '%if &action=OPEN %then %do; ';
|
put '%if &action=OPEN %then %do; ';
|
||||||
|
put ' options nobomfile; ';
|
||||||
put ' data _null_;file &jref encoding=''utf-8''; ';
|
put ' data _null_;file &jref encoding=''utf-8''; ';
|
||||||
put ' put ''{"START_DTTM" : "'' "%sysfunc(datetime(),datetime20.3)" ''"''; ';
|
put ' put ''{"START_DTTM" : "'' "%sysfunc(datetime(),datetime20.3)" ''"''; ';
|
||||||
put ' run; ';
|
put ' run; ';
|
||||||
@@ -257,6 +269,64 @@ data _null_;
|
|||||||
put ' %put &sysmacroname: &ds NOT FOUND!!!; ';
|
put ' %put &sysmacroname: &ds NOT FOUND!!!; ';
|
||||||
put ' %return; ';
|
put ' %return; ';
|
||||||
put ' %end; ';
|
put ' %end; ';
|
||||||
|
put ' %if &fmt=Y %then %do; ';
|
||||||
|
put ' %put converting every variable to a formatted variable; ';
|
||||||
|
put ' /* see mp_ds2fmtds.sas for source */ ';
|
||||||
|
put ' proc contents noprint data=&ds ';
|
||||||
|
put ' out=_data_(keep=name type length format formatl formatd varnum); ';
|
||||||
|
put ' run; ';
|
||||||
|
put ' proc sort; ';
|
||||||
|
put ' by varnum; ';
|
||||||
|
put ' run; ';
|
||||||
|
put ' %local fmtds; ';
|
||||||
|
put ' %let fmtds=%scan(&syslast,2,.); ';
|
||||||
|
put ' /* prepare formats and varnames */ ';
|
||||||
|
put ' data _null_; ';
|
||||||
|
put ' set &fmtds end=last; ';
|
||||||
|
put ' name=upcase(name); ';
|
||||||
|
put ' /* fix formats */ ';
|
||||||
|
put ' if type=2 or type=6 then do; ';
|
||||||
|
put ' length fmt $49.; ';
|
||||||
|
put ' if format='''' then fmt=cats(''$'',length,''.''); ';
|
||||||
|
put ' else if formatl=0 then fmt=cats(format,''.''); ';
|
||||||
|
put ' else fmt=cats(format,formatl,''.''); ';
|
||||||
|
put ' newlen=max(formatl,length); ';
|
||||||
|
put ' end; ';
|
||||||
|
put ' else do; ';
|
||||||
|
put ' if format='''' then fmt=''best.''; ';
|
||||||
|
put ' else if formatl=0 then fmt=cats(format,''.''); ';
|
||||||
|
put ' else if formatd=0 then fmt=cats(format,formatl,''.''); ';
|
||||||
|
put ' else fmt=cats(format,formatl,''.'',formatd); ';
|
||||||
|
put ' /* needs to be wide, for datetimes etc */ ';
|
||||||
|
put ' newlen=max(length,formatl,24); ';
|
||||||
|
put ' end; ';
|
||||||
|
put ' /* 32 char unique name */ ';
|
||||||
|
put ' newname=''sasjs''!!substr(cats(put(md5(name),$hex32.)),1,27); ';
|
||||||
|
put ' ';
|
||||||
|
put ' call symputx(cats(''name'',_n_),name,''l''); ';
|
||||||
|
put ' call symputx(cats(''newname'',_n_),newname,''l''); ';
|
||||||
|
put ' call symputx(cats(''len'',_n_),newlen,''l''); ';
|
||||||
|
put ' call symputx(cats(''fmt'',_n_),fmt,''l''); ';
|
||||||
|
put ' call symputx(cats(''type'',_n_),type,''l''); ';
|
||||||
|
put ' if last then call symputx(''nobs'',_n_,''l''); ';
|
||||||
|
put ' run; ';
|
||||||
|
put ' data &fmtds; ';
|
||||||
|
put ' /* rename on entry */ ';
|
||||||
|
put ' set &ds(rename=( ';
|
||||||
|
put ' %local i; ';
|
||||||
|
put ' %do i=1 %to &nobs; ';
|
||||||
|
put ' &&name&i=&&newname&i ';
|
||||||
|
put ' %end; ';
|
||||||
|
put ' )); ';
|
||||||
|
put ' %do i=1 %to &nobs; ';
|
||||||
|
put ' length &&name&i $&&len&i; ';
|
||||||
|
put ' &&name&i=left(put(&&newname&i,&&fmt&i)); ';
|
||||||
|
put ' drop &&newname&i; ';
|
||||||
|
put ' %end; ';
|
||||||
|
put ' if _error_ then call symputx(''syscc'',1012); ';
|
||||||
|
put ' run; ';
|
||||||
|
put ' %let ds=&fmtds; ';
|
||||||
|
put ' %end; /* &fmt=Y */ ';
|
||||||
put ' data _null_;file &jref mod ; ';
|
put ' data _null_;file &jref mod ; ';
|
||||||
put ' put "["; call symputx(''cols'',0,''l''); ';
|
put ' put "["; call symputx(''cols'',0,''l''); ';
|
||||||
put ' proc sort ';
|
put ' proc sort ';
|
||||||
@@ -340,7 +410,7 @@ data _null_;
|
|||||||
put ' put "}"; ';
|
put ' put "}"; ';
|
||||||
put ' run; ';
|
put ' run; ';
|
||||||
put '%end; ';
|
put '%end; ';
|
||||||
put '%mend; ';
|
put '%mend mp_jsonout; ';
|
||||||
put '%macro mv_webout(action,ds,fref=_mvwtemp,dslabel=,fmt=Y); ';
|
put '%macro mv_webout(action,ds,fref=_mvwtemp,dslabel=,fmt=Y); ';
|
||||||
put '%global _webin_file_count _webin_fileuri _debug _omittextlog _webin_name ';
|
put '%global _webin_file_count _webin_fileuri _debug _omittextlog _webin_name ';
|
||||||
put ' sasjs_tables SYS_JES_JOB_URI; ';
|
put ' sasjs_tables SYS_JES_JOB_URI; ';
|
||||||
@@ -561,11 +631,12 @@ data _null_;
|
|||||||
run;
|
run;
|
||||||
|
|
||||||
/* insert the code, escaping double quotes and carriage returns */
|
/* insert the code, escaping double quotes and carriage returns */
|
||||||
|
%&dbg.put &sysmacroname: Creating final input file;
|
||||||
%local x fref freflist;
|
%local x fref freflist;
|
||||||
%let freflist= &adapter &precode &code ;
|
%let freflist= &adapter &precode &code ;
|
||||||
%do x=1 %to %sysfunc(countw(&freflist));
|
%do x=1 %to %sysfunc(countw(&freflist));
|
||||||
%let fref=%scan(&freflist,&x);
|
%let fref=%scan(&freflist,&x);
|
||||||
%put &sysmacroname: adding &fref;
|
%&dbg.put &sysmacroname: adding &fref fileref;
|
||||||
data _null_;
|
data _null_;
|
||||||
length filein 8 fileid 8;
|
length filein 8 fileid 8;
|
||||||
filein = fopen("&fref","I",1,"B");
|
filein = fopen("&fref","I",1,"B");
|
||||||
@@ -617,7 +688,12 @@ data _null_;
|
|||||||
put '"}';
|
put '"}';
|
||||||
run;
|
run;
|
||||||
|
|
||||||
/* now we can create the job!! */
|
%if &mdebug=1 and &SYS_PROCHTTP_STATUS_CODE ne 201 %then %do;
|
||||||
|
%put &sysmacroname: input about to be POSTed;
|
||||||
|
data _null_;infile &fname3;input;putlog _infile_;run;
|
||||||
|
%end;
|
||||||
|
|
||||||
|
%&dbg.put &sysmacroname: Creating the actual service!;
|
||||||
%local fname4;
|
%local fname4;
|
||||||
%let fname4=%mf_getuniquefileref();
|
%let fname4=%mf_getuniquefileref();
|
||||||
proc http method='POST'
|
proc http method='POST'
|
||||||
@@ -630,22 +706,18 @@ proc http method='POST'
|
|||||||
"Authorization"="Bearer &&&access_token_var"
|
"Authorization"="Bearer &&&access_token_var"
|
||||||
%end;
|
%end;
|
||||||
"Accept"="application/vnd.sas.job.definition+json";
|
"Accept"="application/vnd.sas.job.definition+json";
|
||||||
%if &debug=1 %then %do;
|
%if &mdebug=1 %then %do;
|
||||||
debug level = 3;
|
debug level = 3;
|
||||||
%end;
|
%end;
|
||||||
run;
|
run;
|
||||||
/*data _null_;infile &fname4;input;putlog _infile_;run;*/
|
%if &mdebug=1 and &SYS_PROCHTTP_STATUS_CODE ne 201 %then %do;
|
||||||
|
%put &sysmacroname: output from POSTing job definition;
|
||||||
|
data _null_;infile &fname4;input;putlog _infile_;run;
|
||||||
|
%end;
|
||||||
%mp_abort(iftrue=(&SYS_PROCHTTP_STATUS_CODE ne 201)
|
%mp_abort(iftrue=(&SYS_PROCHTTP_STATUS_CODE ne 201)
|
||||||
,mac=&sysmacroname
|
,mac=&sysmacroname
|
||||||
,msg=%str(&SYS_PROCHTTP_STATUS_CODE &SYS_PROCHTTP_STATUS_PHRASE)
|
,msg=%str(&SYS_PROCHTTP_STATUS_CODE &SYS_PROCHTTP_STATUS_PHRASE)
|
||||||
)
|
)
|
||||||
/* clear refs */
|
|
||||||
filename &fname1 clear;
|
|
||||||
filename &fname2 clear;
|
|
||||||
filename &fname3 clear;
|
|
||||||
filename &fname4 clear;
|
|
||||||
filename &adapter clear;
|
|
||||||
libname &libref1 clear;
|
|
||||||
|
|
||||||
/* get the url so we can give a helpful log message */
|
/* get the url so we can give a helpful log message */
|
||||||
%local url;
|
%local url;
|
||||||
@@ -660,6 +732,19 @@ data _null_;
|
|||||||
call symputx('url',url);
|
call symputx('url',url);
|
||||||
run;
|
run;
|
||||||
|
|
||||||
|
%if &mdebug=1 %then %do;
|
||||||
|
%put &sysmacroname exit vars:;
|
||||||
|
%put _local_;
|
||||||
|
%end;
|
||||||
|
%else %do;
|
||||||
|
/* clear refs */
|
||||||
|
filename &fname1 clear;
|
||||||
|
filename &fname2 clear;
|
||||||
|
filename &fname3 clear;
|
||||||
|
filename &fname4 clear;
|
||||||
|
filename &adapter clear;
|
||||||
|
libname &libref1 clear;
|
||||||
|
%end;
|
||||||
|
|
||||||
%put &sysmacroname: Job &name successfully created in &path;
|
%put &sysmacroname: Job &name successfully created in &path;
|
||||||
%put &sysmacroname:;
|
%put &sysmacroname:;
|
||||||
@@ -669,4 +754,4 @@ run;
|
|||||||
%put &sysmacroname:;
|
%put &sysmacroname:;
|
||||||
%put &sysmacroname:;
|
%put &sysmacroname:;
|
||||||
|
|
||||||
%mend;
|
%mend mv_createwebservice;
|
||||||
|
|||||||
@@ -10,17 +10,20 @@
|
|||||||
,outfile=/tmp/some_job.sas
|
,outfile=/tmp/some_job.sas
|
||||||
)
|
)
|
||||||
|
|
||||||
@param [in] access_token_var= The global macro variable to contain the access token
|
@param [in] access_token_var= The global macro variable to contain the access
|
||||||
|
token
|
||||||
@param [in] grant_type= valid values:
|
@param [in] grant_type= valid values:
|
||||||
* password
|
@li password
|
||||||
* authorization_code
|
@liauthorization_code
|
||||||
* detect - will check if access_token exists, if not will use sas_services if
|
@li detect - will check if access_token exists, if not will use sas_services
|
||||||
a SASStudioV session else authorization_code. Default option.
|
if a SASStudioV session else authorization_code. Default option.
|
||||||
* sas_services - will use oauth_bearer=sas_services
|
@li sas_services - will use oauth_bearer=sas_services
|
||||||
@param [in] path= The SAS Drive path of the job
|
@param [in] path= The SAS Drive path of the job
|
||||||
@param [in] name= The name of the job
|
@param [in] name= The name of the job
|
||||||
@param [out] outref= A fileref to which to write the source code
|
@param [in] mdebug=(0) set to 1 to enable DEBUG messages
|
||||||
@param [out] outfile= A file to which to write the source code
|
@param [out] outref=(0) A fileref to which to write the source code (will be
|
||||||
|
created with a TEMP engine)
|
||||||
|
@param [out] outfile=(0) A file to which to write the source code
|
||||||
|
|
||||||
@version VIYA V.03.04
|
@version VIYA V.03.04
|
||||||
@author Allan Bowe, source: https://github.com/sasjs/core
|
@author Allan Bowe, source: https://github.com/sasjs/core
|
||||||
@@ -39,7 +42,15 @@
|
|||||||
,contextName=SAS Job Execution compute context
|
,contextName=SAS Job Execution compute context
|
||||||
,access_token_var=ACCESS_TOKEN
|
,access_token_var=ACCESS_TOKEN
|
||||||
,grant_type=sas_services
|
,grant_type=sas_services
|
||||||
|
,mdebug=0
|
||||||
);
|
);
|
||||||
|
%local dbg;
|
||||||
|
%if &mdebug=1 %then %do;
|
||||||
|
%put &sysmacroname entry vars:;
|
||||||
|
%put _local_;
|
||||||
|
%end;
|
||||||
|
%else %let dbg=*;
|
||||||
|
|
||||||
%local oauth_bearer;
|
%local oauth_bearer;
|
||||||
%if &grant_type=detect %then %do;
|
%if &grant_type=detect %then %do;
|
||||||
%if %symexist(&access_token_var) %then %let grant_type=authorization_code;
|
%if %symexist(&access_token_var) %then %let grant_type=authorization_code;
|
||||||
@@ -133,18 +144,30 @@ data _null_;
|
|||||||
run;
|
run;
|
||||||
%inc "&fpath3..lua";
|
%inc "&fpath3..lua";
|
||||||
/* export to desired destination */
|
/* export to desired destination */
|
||||||
data _null_;
|
%if "&outref"="0" %then %do;
|
||||||
%if &outref=0 %then %do;
|
data _null_;
|
||||||
file "&outfile" lrecl=32767;
|
file "&outfile" lrecl=32767;
|
||||||
%end;
|
%end;
|
||||||
%else %do;
|
%else %do;
|
||||||
|
filename &outref temp;
|
||||||
|
data _null_;
|
||||||
file &outref;
|
file &outref;
|
||||||
%end;
|
%end;
|
||||||
infile &fname2;
|
infile &fname2;
|
||||||
input;
|
input;
|
||||||
put _infile_;
|
put _infile_;
|
||||||
|
&dbg. putlog _infile_;
|
||||||
run;
|
run;
|
||||||
filename &fname1 clear;
|
|
||||||
filename &fname2 clear;
|
%if &mdebug=1 %then %do;
|
||||||
filename &fname3 clear;
|
%put &sysmacroname exit vars:;
|
||||||
%mend;
|
%put _local_;
|
||||||
|
%end;
|
||||||
|
%else %do;
|
||||||
|
/* clear refs */
|
||||||
|
filename &fname1 clear;
|
||||||
|
filename &fname2 clear;
|
||||||
|
filename &fname3 clear;
|
||||||
|
%end;
|
||||||
|
|
||||||
|
%mend mv_getjobcode;
|
||||||
|
|||||||
@@ -1,21 +1,19 @@
|
|||||||
/**
|
/**
|
||||||
@file
|
@file
|
||||||
@brief Extract the log from a completed SAS Viya Job
|
@brief Extract the log from a completed SAS Viya Job
|
||||||
@details Extracts log from a Viya job and writes it out to a fileref
|
@details Extracts log from a Viya job and writes it out to a fileref.
|
||||||
|
|
||||||
To query the job, you need the URI. Sample code for achieving this
|
To query the job, you need the URI. Sample code for achieving this
|
||||||
is provided below.
|
is provided below.
|
||||||
|
|
||||||
## Example
|
## Example
|
||||||
|
|
||||||
First, compile the macros:
|
%* First, compile the macros;
|
||||||
|
|
||||||
filename mc url
|
filename mc url
|
||||||
"https://raw.githubusercontent.com/sasjs/core/main/all.sas";
|
"https://raw.githubusercontent.com/sasjs/core/main/all.sas";
|
||||||
%inc mc;
|
%inc mc;
|
||||||
|
|
||||||
Next, create a job (in this case, a web service):
|
%* Next, create a job (in this case, a web service);
|
||||||
|
|
||||||
filename ft15f001 temp;
|
filename ft15f001 temp;
|
||||||
parmcards4;
|
parmcards4;
|
||||||
data ;
|
data ;
|
||||||
@@ -31,39 +29,52 @@
|
|||||||
;;;;
|
;;;;
|
||||||
%mv_createwebservice(path=/Public/temp,name=demo)
|
%mv_createwebservice(path=/Public/temp,name=demo)
|
||||||
|
|
||||||
Execute it:
|
%* Execute it;
|
||||||
|
|
||||||
%mv_jobexecute(path=/Public/temp
|
%mv_jobexecute(path=/Public/temp
|
||||||
,name=demo
|
,name=demo
|
||||||
,outds=work.info
|
,outds=work.info
|
||||||
)
|
)
|
||||||
|
|
||||||
Wait for it to finish, and grab the uri:
|
%* Wait for it to finish;
|
||||||
|
data work.info;
|
||||||
data _null_;
|
|
||||||
set work.info;
|
set work.info;
|
||||||
if method='GET' and rel='self';
|
where method='GET' and rel='state';
|
||||||
|
run;
|
||||||
|
%mv_jobwaitfor(ALL,inds=work.info,outds=work.jobstates)
|
||||||
|
|
||||||
|
%* and grab the uri;
|
||||||
|
data _null_;
|
||||||
|
set work.jobstates;
|
||||||
call symputx('uri',uri);
|
call symputx('uri',uri);
|
||||||
run;
|
run;
|
||||||
|
|
||||||
Finally, fetch the log:
|
%* Finally, fetch the log;
|
||||||
|
|
||||||
%mv_getjoblog(uri=&uri,outref=mylog)
|
%mv_getjoblog(uri=&uri,outref=mylog)
|
||||||
|
|
||||||
This macro is used by the mv_jobwaitfor.sas macro, which is generally a more
|
This macro is used by the mv_jobwaitfor.sas macro, which is generally a more
|
||||||
convenient way to wait for the job to finish before fetching the log.
|
convenient way to wait for the job to finish before fetching the log.
|
||||||
|
|
||||||
|
If the remote session calls `endsas` then it is not possible to get the log
|
||||||
|
from the provided uri, and so the log from the parent session is fetched
|
||||||
|
instead. This happens for a 400 response, eg below:
|
||||||
|
|
||||||
@param [in] access_token_var= The global macro variable to contain the access token
|
ErrorResponse[version=2,status=400,err=5113,id=,message=The session
|
||||||
|
requested is currently in a failed or stopped state.,detail=[path:
|
||||||
|
/compute/sessions/LONGURI-ses0006/jobs/LONGURI/log/content, traceId: 63
|
||||||
|
51aa617d01fd2b],remediation=Correct the errors in the session request,
|
||||||
|
and create a new session.,targetUri=<null>,errors=[],links=[]]
|
||||||
|
|
||||||
|
@param [in] access_token_var= The global macro variable to contain the access
|
||||||
|
token
|
||||||
@param [in] mdebug= set to 1 to enable DEBUG messages
|
@param [in] mdebug= set to 1 to enable DEBUG messages
|
||||||
@param [in] grant_type= valid values:
|
@param [in] grant_type= valid values:
|
||||||
@li password
|
@li password
|
||||||
@li authorization_code
|
@li authorization_code
|
||||||
@li detect - will check if access_token exists, if not will use sas_services if
|
@li detect - will check if access_token exists, if not will use sas_services
|
||||||
a SASStudioV session else authorization_code. Default option.
|
if a SASStudioV session else authorization_code. Default option.
|
||||||
@li sas_services - will use oauth_bearer=sas_services.
|
@li sas_services - will use oauth_bearer=sas_services.
|
||||||
@param [in] uri= The uri of the running job for which to fetch the status,
|
@param [in] uri= The uri of the running job for which to fetch the status,
|
||||||
in the format `/jobExecution/jobs/$UUID/state` (unquoted).
|
in the format `/jobExecution/jobs/$UUID` (unquoted).
|
||||||
@param [out] outref= The output fileref to which to APPEND the log (is always
|
@param [out] outref= The output fileref to which to APPEND the log (is always
|
||||||
appended).
|
appended).
|
||||||
|
|
||||||
@@ -85,6 +96,13 @@
|
|||||||
,grant_type=sas_services
|
,grant_type=sas_services
|
||||||
,mdebug=0
|
,mdebug=0
|
||||||
);
|
);
|
||||||
|
%local dbg;
|
||||||
|
%if &mdebug=1 %then %do;
|
||||||
|
%put &sysmacroname entry vars:;
|
||||||
|
%put _local_;
|
||||||
|
%end;
|
||||||
|
%else %let dbg=*;
|
||||||
|
|
||||||
%local oauth_bearer;
|
%local oauth_bearer;
|
||||||
%if &grant_type=detect %then %do;
|
%if &grant_type=detect %then %do;
|
||||||
%if %symexist(&access_token_var) %then %let grant_type=authorization_code;
|
%if %symexist(&access_token_var) %then %let grant_type=authorization_code;
|
||||||
@@ -114,7 +132,7 @@ data _null_;
|
|||||||
call symputx('errflg',1);
|
call symputx('errflg',1);
|
||||||
call symputx('errmsg',
|
call symputx('errmsg',
|
||||||
"URI should be in format /jobExecution/jobs/$$$$UUID$$$$"
|
"URI should be in format /jobExecution/jobs/$$$$UUID$$$$"
|
||||||
!!" but is actually like: &uri",'l');
|
!!" but is actually like:"!!uri,'l');
|
||||||
end;
|
end;
|
||||||
run;
|
run;
|
||||||
|
|
||||||
@@ -147,6 +165,10 @@ proc http method='GET' out=&fname1 &oauth_bearer
|
|||||||
%end;
|
%end;
|
||||||
;
|
;
|
||||||
run;
|
run;
|
||||||
|
%if &mdebug=1 %then %do;
|
||||||
|
%put &sysmacroname: fetching log loc from &uri;
|
||||||
|
data _null_;infile &fname1;input;putlog _infile_;run;
|
||||||
|
%end;
|
||||||
%if &SYS_PROCHTTP_STATUS_CODE ne 200 and &SYS_PROCHTTP_STATUS_CODE ne 201 %then
|
%if &SYS_PROCHTTP_STATUS_CODE ne 200 and &SYS_PROCHTTP_STATUS_CODE ne 201 %then
|
||||||
%do;
|
%do;
|
||||||
data _null_;infile &fname1;input;putlog _infile_;run;
|
data _null_;infile &fname1;input;putlog _infile_;run;
|
||||||
@@ -184,43 +206,74 @@ run;
|
|||||||
data _null_;
|
data _null_;
|
||||||
infile &fname2;
|
infile &fname2;
|
||||||
input;
|
input;
|
||||||
uri=_infile_;
|
uri=cats(_infile_);
|
||||||
if length(uri)<12 then do;
|
if length(uri)<12 then do;
|
||||||
call symputx('errflg',1);
|
call symputx('errflg',1);
|
||||||
call symputx('errmsg',"URI is invalid (too short) - '&uri'",'l');
|
call symputx('errmsg',"URI is invalid (too short) - '&uri'",'l');
|
||||||
end;
|
end;
|
||||||
if scan(uri,1) ne 'files' or scan(uri,2) ne 'files' then do;
|
else if (scan(uri,1,'/') ne 'compute' or scan(uri,2,'/') ne 'sessions')
|
||||||
|
and (scan(uri,1,'/') ne 'files' or scan(uri,2,'/') ne 'files')
|
||||||
|
then do;
|
||||||
call symputx('errflg',1);
|
call symputx('errflg',1);
|
||||||
call symputx('errmsg',
|
call symputx('errmsg',
|
||||||
"URI should be in format /files/files/$$$$UUID$$$$"
|
"URI should be in format /compute/sessions/$$$$UUID$$$$/jobs/$$$$UUID$$$$"
|
||||||
!!" but is actually like: &uri",'l');
|
!!" or /files/files/$$$$UUID$$$$"
|
||||||
|
!!" but is actually like:"!!uri,'l');
|
||||||
|
end;
|
||||||
|
else do;
|
||||||
|
call symputx('errflg',0,'l');
|
||||||
|
call symputx('logloc',uri,'l');
|
||||||
end;
|
end;
|
||||||
call symputx('errflg',0,'l');
|
|
||||||
call symputx('logloc',uri,'l');
|
|
||||||
run;
|
run;
|
||||||
|
|
||||||
%mp_abort(iftrue=(&errflg=1)
|
%mp_abort(iftrue=(%str(&errflg)=1)
|
||||||
,mac=&sysmacroname
|
,mac=&sysmacroname
|
||||||
,msg=%str(&errmsg)
|
,msg=%str(&errmsg)
|
||||||
)
|
)
|
||||||
|
|
||||||
/* we have a log uri - now fetch the log */
|
/* we have a log uri - now fetch the log */
|
||||||
|
%&dbg.put &sysmacroname: querying &base_uri&logloc/content;
|
||||||
proc http method='GET' out=&fname1 &oauth_bearer
|
proc http method='GET' out=&fname1 &oauth_bearer
|
||||||
url="&base_uri&logloc/content";
|
url="&base_uri&logloc/content?limit=10000";
|
||||||
headers
|
headers
|
||||||
%if &grant_type=authorization_code %then %do;
|
%if &grant_type=authorization_code %then %do;
|
||||||
"Authorization"="Bearer &&&access_token_var"
|
"Authorization"="Bearer &&&access_token_var"
|
||||||
%end;
|
%end;
|
||||||
;
|
;
|
||||||
run;
|
run;
|
||||||
%if &SYS_PROCHTTP_STATUS_CODE ne 200 and &SYS_PROCHTTP_STATUS_CODE ne 201 %then
|
|
||||||
%do;
|
%if &mdebug=1 %then %do;
|
||||||
|
%put &sysmacroname: fetching log content from &base_uri&logloc/content;
|
||||||
data _null_;infile &fname1;input;putlog _infile_;run;
|
data _null_;infile &fname1;input;putlog _infile_;run;
|
||||||
|
%end;
|
||||||
|
|
||||||
|
%if &SYS_PROCHTTP_STATUS_CODE=400 %then %do;
|
||||||
|
/* fetch log from parent session */
|
||||||
|
%let logloc=%substr(&logloc,1,%index(&logloc,%str(/jobs/))-1);
|
||||||
|
%&dbg.put &sysmacroname: Now querying &base_uri&logloc/log/content;
|
||||||
|
proc http method='GET' out=&fname1 &oauth_bearer
|
||||||
|
url="&base_uri&logloc/log/content?limit=10000";
|
||||||
|
headers
|
||||||
|
%if &grant_type=authorization_code %then %do;
|
||||||
|
"Authorization"="Bearer &&&access_token_var"
|
||||||
|
%end;
|
||||||
|
;
|
||||||
|
run;
|
||||||
|
%if &mdebug=1 %then %do;
|
||||||
|
%put &sysmacroname: fetching log content from &base_uri&logloc/log/content;
|
||||||
|
data _null_;infile &fname1;input;putlog _infile_;run;
|
||||||
|
%end;
|
||||||
|
%end;
|
||||||
|
|
||||||
|
%if &SYS_PROCHTTP_STATUS_CODE ne 200 and &SYS_PROCHTTP_STATUS_CODE ne 201
|
||||||
|
%then %do;
|
||||||
|
%if &mdebug ne 1 %then %do; /* have already output above */
|
||||||
|
data _null_;infile &fname1;input;putlog _infile_;run;
|
||||||
|
%end;
|
||||||
%mp_abort(mac=&sysmacroname
|
%mp_abort(mac=&sysmacroname
|
||||||
,msg=%str(logfetch: &SYS_PROCHTTP_STATUS_CODE &SYS_PROCHTTP_STATUS_PHRASE)
|
,msg=%str(logfetch: &SYS_PROCHTTP_STATUS_CODE &SYS_PROCHTTP_STATUS_PHRASE)
|
||||||
)
|
)
|
||||||
%end;
|
%end;
|
||||||
|
|
||||||
data _null_;
|
data _null_;
|
||||||
file "&fpath3..lua";
|
file "&fpath3..lua";
|
||||||
put '
|
put '
|
||||||
@@ -260,9 +313,10 @@ run;
|
|||||||
filename &fname3 clear;
|
filename &fname3 clear;
|
||||||
%end;
|
%end;
|
||||||
%else %do;
|
%else %do;
|
||||||
|
%put &sysmacroname exit vars:;
|
||||||
%put _local_;
|
%put _local_;
|
||||||
%end;
|
%end;
|
||||||
%mend;
|
%mend mv_getjoblog;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
232
viya/mv_getjobresult.sas
Normal file
232
viya/mv_getjobresult.sas
Normal file
@@ -0,0 +1,232 @@
|
|||||||
|
/**
|
||||||
|
@file
|
||||||
|
@brief Extract the result from a completed SAS Viya Job
|
||||||
|
@details Extracts result from a Viya job and writes it out to a fileref
|
||||||
|
and/or a JSON-engine library.
|
||||||
|
|
||||||
|
To query the job, you need the URI. Sample code for achieving this
|
||||||
|
is provided below.
|
||||||
|
|
||||||
|
## Example
|
||||||
|
|
||||||
|
First, compile the macros:
|
||||||
|
|
||||||
|
filename mc url
|
||||||
|
"https://raw.githubusercontent.com/sasjs/core/main/all.sas";
|
||||||
|
%inc mc;
|
||||||
|
|
||||||
|
Next, create a job (in this case, a web service):
|
||||||
|
|
||||||
|
filename ft15f001 temp;
|
||||||
|
parmcards4;
|
||||||
|
data test;
|
||||||
|
rand=ranuni(0)*1000;
|
||||||
|
do x=1 to rand;
|
||||||
|
y=rand*4;
|
||||||
|
output;
|
||||||
|
end;
|
||||||
|
run;
|
||||||
|
proc sort data=&syslast
|
||||||
|
by descending y;
|
||||||
|
run;
|
||||||
|
%webout(OPEN)
|
||||||
|
%webout(OBJ, test)
|
||||||
|
%webout(CLOSE)
|
||||||
|
;;;;
|
||||||
|
%mv_createwebservice(path=/Public/temp,name=demo)
|
||||||
|
|
||||||
|
Execute it:
|
||||||
|
|
||||||
|
%mv_jobexecute(path=/Public/temp
|
||||||
|
,name=demo
|
||||||
|
,outds=work.info
|
||||||
|
)
|
||||||
|
|
||||||
|
Wait for it to finish, and grab the uri:
|
||||||
|
|
||||||
|
data _null_;
|
||||||
|
set work.info;
|
||||||
|
if method='GET' and rel='self';
|
||||||
|
call symputx('uri',uri);
|
||||||
|
run;
|
||||||
|
|
||||||
|
Finally, fetch the result (In this case, WEBOUT):
|
||||||
|
|
||||||
|
%mv_getjobresult(uri=&uri,result=WEBOUT_JSON,outref=myweb,outlib=myweblib)
|
||||||
|
|
||||||
|
|
||||||
|
@param [in] access_token_var= The global macro variable containing the access
|
||||||
|
token
|
||||||
|
@param [in] mdebug= set to 1 to enable DEBUG messages
|
||||||
|
@param [in] grant_type= valid values:
|
||||||
|
@li password
|
||||||
|
@li authorization_code
|
||||||
|
@li detect - will check if access_token exists, if not will use sas_services
|
||||||
|
if a SASStudioV session else authorization_code. Default option.
|
||||||
|
@li sas_services - will use oauth_bearer=sas_services.
|
||||||
|
@param [in] uri= The uri of the running job for which to fetch the status,
|
||||||
|
in the format `/jobExecution/jobs/$UUID` (unquoted).
|
||||||
|
|
||||||
|
@param [out] result= (WEBOUT_JSON) The result type to capture. Resolves
|
||||||
|
to "_[column name]" from the results table when parsed with the JSON libname
|
||||||
|
engine. Example values:
|
||||||
|
@li WEBOUT_JSON
|
||||||
|
@li WEBOUT_TXT
|
||||||
|
|
||||||
|
@param [out] outref= (0) The output fileref to which to write the results
|
||||||
|
@param [out] outlib= (0) The output library to which to assign the results
|
||||||
|
(assumes the data is in JSON format)
|
||||||
|
|
||||||
|
|
||||||
|
@version VIYA V.03.05
|
||||||
|
@author Allan Bowe, source: https://github.com/sasjs/core
|
||||||
|
|
||||||
|
<h4> SAS Macros </h4>
|
||||||
|
@li mp_abort.sas
|
||||||
|
@li mp_binarycopy.sas
|
||||||
|
@li mf_getplatform.sas
|
||||||
|
@li mf_existfileref.sas
|
||||||
|
|
||||||
|
**/
|
||||||
|
|
||||||
|
%macro mv_getjobresult(uri=0
|
||||||
|
,contextName=SAS Job Execution compute context
|
||||||
|
,access_token_var=ACCESS_TOKEN
|
||||||
|
,grant_type=sas_services
|
||||||
|
,mdebug=0
|
||||||
|
,result=WEBOUT_JSON
|
||||||
|
,outref=0
|
||||||
|
,outlib=0
|
||||||
|
);
|
||||||
|
%local dbg;
|
||||||
|
%if &mdebug=1 %then %do;
|
||||||
|
%put &sysmacroname entry vars:;
|
||||||
|
%put _local_;
|
||||||
|
%end;
|
||||||
|
%else %let dbg=*;
|
||||||
|
|
||||||
|
%local oauth_bearer;
|
||||||
|
%if &grant_type=detect %then %do;
|
||||||
|
%if %symexist(&access_token_var) %then %let grant_type=authorization_code;
|
||||||
|
%else %let grant_type=sas_services;
|
||||||
|
%end;
|
||||||
|
%if &grant_type=sas_services %then %do;
|
||||||
|
%let oauth_bearer=oauth_bearer=sas_services;
|
||||||
|
%let &access_token_var=;
|
||||||
|
%end;
|
||||||
|
|
||||||
|
%mp_abort(iftrue=(&grant_type ne authorization_code and &grant_type ne password
|
||||||
|
and &grant_type ne sas_services
|
||||||
|
)
|
||||||
|
,mac=&sysmacroname
|
||||||
|
,msg=%str(Invalid value for grant_type: &grant_type)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
/* validation in datastep for better character safety */
|
||||||
|
%local errmsg errflg;
|
||||||
|
data _null_;
|
||||||
|
uri=symget('uri');
|
||||||
|
if length(uri)<12 then do;
|
||||||
|
call symputx('errflg',1);
|
||||||
|
call symputx('errmsg',"URI is invalid (too short) - '&uri'",'l');
|
||||||
|
end;
|
||||||
|
if scan(uri,-1)='state' or scan(uri,1) ne 'jobExecution' then do;
|
||||||
|
call symputx('errflg',1);
|
||||||
|
call symputx('errmsg',
|
||||||
|
"URI should be in format /jobExecution/jobs/$$$$UUID$$$$"
|
||||||
|
!!" but is actually like: &uri",'l');
|
||||||
|
end;
|
||||||
|
run;
|
||||||
|
|
||||||
|
%mp_abort(iftrue=(&errflg=1)
|
||||||
|
,mac=&sysmacroname
|
||||||
|
,msg=%str(&errmsg)
|
||||||
|
)
|
||||||
|
|
||||||
|
%if &outref ne 0 and %mf_existfileref(&outref) ne 1 %then %do;
|
||||||
|
filename &outref temp;
|
||||||
|
%end;
|
||||||
|
|
||||||
|
options noquotelenmax;
|
||||||
|
%local base_uri; /* location of rest apis */
|
||||||
|
%let base_uri=%mf_getplatform(VIYARESTAPI);
|
||||||
|
|
||||||
|
/* fetch job info */
|
||||||
|
%local fname1;
|
||||||
|
%let fname1=%mf_getuniquefileref();
|
||||||
|
proc http method='GET' out=&fname1 &oauth_bearer
|
||||||
|
url="&base_uri&uri";
|
||||||
|
headers "Accept"="application/json"
|
||||||
|
%if &grant_type=authorization_code %then %do;
|
||||||
|
"Authorization"="Bearer &&&access_token_var"
|
||||||
|
%end;
|
||||||
|
;
|
||||||
|
run;
|
||||||
|
%if &SYS_PROCHTTP_STATUS_CODE ne 200 and &SYS_PROCHTTP_STATUS_CODE ne 201 %then
|
||||||
|
%do;
|
||||||
|
data _null_;infile &fname1;input;putlog _infile_;run;
|
||||||
|
%mp_abort(mac=&sysmacroname
|
||||||
|
,msg=%str(&SYS_PROCHTTP_STATUS_CODE &SYS_PROCHTTP_STATUS_PHRASE)
|
||||||
|
)
|
||||||
|
%end;
|
||||||
|
%if &mdebug=1 %then %do;
|
||||||
|
data _null_;
|
||||||
|
infile &fname1 lrecl=32767;
|
||||||
|
input;
|
||||||
|
putlog _infile_;
|
||||||
|
run;
|
||||||
|
%end;
|
||||||
|
|
||||||
|
/* extract results link */
|
||||||
|
%local lib1 resuri;
|
||||||
|
%let lib1=%mf_getuniquelibref();
|
||||||
|
libname &lib1 JSON fileref=&fname1;
|
||||||
|
data _null_;
|
||||||
|
set &lib1..results;
|
||||||
|
call symputx('resuri',_&result,'l');
|
||||||
|
&dbg putlog "&sysmacroname results: " (_all_)(=);
|
||||||
|
run;
|
||||||
|
%mp_abort(iftrue=("&resuri"=".")
|
||||||
|
,mac=&sysmacroname
|
||||||
|
,msg=%str(Variable _&result did not exist in the response json)
|
||||||
|
)
|
||||||
|
|
||||||
|
/* extract results */
|
||||||
|
%local fname2;
|
||||||
|
%let fname2=%mf_getuniquefileref();
|
||||||
|
proc http method='GET' out=&fname2 &oauth_bearer
|
||||||
|
url="&base_uri&resuri/content?limit=10000";
|
||||||
|
headers "Accept"="application/json"
|
||||||
|
%if &grant_type=authorization_code %then %do;
|
||||||
|
"Authorization"="Bearer &&&access_token_var"
|
||||||
|
%end;
|
||||||
|
;
|
||||||
|
run;
|
||||||
|
%if &mdebug=1 %then %do;
|
||||||
|
data _null_;
|
||||||
|
infile &fname2 lrecl=32767;
|
||||||
|
input;
|
||||||
|
putlog _infile_;
|
||||||
|
run;
|
||||||
|
%end;
|
||||||
|
|
||||||
|
%if &outref ne 0 %then %do;
|
||||||
|
filename &outref temp;
|
||||||
|
%mp_binarycopy(inref=&fname2,outref=&outref)
|
||||||
|
%end;
|
||||||
|
%if &outlib ne 0 %then %do;
|
||||||
|
libname &outlib JSON fileref=&fname2;
|
||||||
|
%end;
|
||||||
|
|
||||||
|
%if &mdebug=0 %then %do;
|
||||||
|
filename &fname1 clear;
|
||||||
|
filename &fname2 clear;
|
||||||
|
libname &lib1 clear;
|
||||||
|
%end;
|
||||||
|
%else %do;
|
||||||
|
%put &sysmacroname exit vars:;
|
||||||
|
%put _local_;
|
||||||
|
%end;
|
||||||
|
|
||||||
|
%mend mv_getjobresult;
|
||||||
@@ -23,24 +23,25 @@
|
|||||||
,paramstring=%str("macvarname":"macvarvalue","answer":42)
|
,paramstring=%str("macvarname":"macvarvalue","answer":42)
|
||||||
)
|
)
|
||||||
|
|
||||||
@param [in] access_token_var= The global macro variable to contain the access token
|
@param [in] access_token_var= The global macro variable to contain the access
|
||||||
|
token
|
||||||
@param [in] grant_type= valid values:
|
@param [in] grant_type= valid values:
|
||||||
|
@li password
|
||||||
* password
|
@li authorization_code
|
||||||
* authorization_code
|
@li detect - will check if access_token exists, if not will use sas_services
|
||||||
* detect - will check if access_token exists, if not will use sas_services if
|
if a SASStudioV session else authorization_code. Default option.
|
||||||
a SASStudioV session else authorization_code. Default option.
|
@li sas_services - will use oauth_bearer=sas_services
|
||||||
* sas_services - will use oauth_bearer=sas_services
|
|
||||||
|
|
||||||
@param [in] path= The SAS Drive path to the job being executed
|
@param [in] path= The SAS Drive path to the job being executed
|
||||||
@param [in] name= The name of the job to execute
|
@param [in] name= The name of the job to execute
|
||||||
@param [in] paramstring= A JSON fragment with name:value pairs, eg: `"name":"value"`
|
@param [in] paramstring= A JSON fragment with name:value pairs, eg:
|
||||||
or "name":"value","name2":42`. This will need to be wrapped in `%str()`.
|
`"name":"value"` or "name":"value","name2":42`. This will need to be
|
||||||
|
wrapped in `%str()`.
|
||||||
|
|
||||||
@param [in] contextName= Context name with which to run the job.
|
@param [in] contextName= Context name with which to run the job.
|
||||||
Default = `SAS Job Execution compute context`
|
Default = `SAS Job Execution compute context`
|
||||||
|
@param [in] mdebug= set to 1 to enable DEBUG messages
|
||||||
@param [out] outds= The output dataset containing links (Default=work.mv_jobexecute)
|
@param [out] outds= (work.mv_jobexecute) The output dataset containing links
|
||||||
|
|
||||||
|
|
||||||
@version VIYA V.03.04
|
@version VIYA V.03.04
|
||||||
@@ -62,7 +63,15 @@
|
|||||||
,grant_type=sas_services
|
,grant_type=sas_services
|
||||||
,paramstring=0
|
,paramstring=0
|
||||||
,outds=work.mv_jobexecute
|
,outds=work.mv_jobexecute
|
||||||
|
,mdebug=0
|
||||||
);
|
);
|
||||||
|
%local dbg;
|
||||||
|
%if &mdebug=1 %then %do;
|
||||||
|
%put &sysmacroname entry vars:;
|
||||||
|
%put _local_;
|
||||||
|
%end;
|
||||||
|
%else %let dbg=*;
|
||||||
|
|
||||||
%local oauth_bearer;
|
%local oauth_bearer;
|
||||||
%if &grant_type=detect %then %do;
|
%if &grant_type=detect %then %do;
|
||||||
%if %symexist(&access_token_var) %then %let grant_type=authorization_code;
|
%if %symexist(&access_token_var) %then %let grant_type=authorization_code;
|
||||||
@@ -164,9 +173,14 @@ data &outds;
|
|||||||
_program="&path/&name";
|
_program="&path/&name";
|
||||||
run;
|
run;
|
||||||
|
|
||||||
/* clear refs */
|
%if &mdebug=1 %then %do;
|
||||||
filename &fname0 clear;
|
%put &sysmacroname exit vars:;
|
||||||
filename &fname1 clear;
|
%put _local_;
|
||||||
libname &libref;
|
%end;
|
||||||
|
%else %do;
|
||||||
%mend;
|
/* clear refs */
|
||||||
|
filename &fname0 clear;
|
||||||
|
filename &fname1 clear;
|
||||||
|
libname &libref;
|
||||||
|
%end;
|
||||||
|
%mend mv_jobexecute;
|
||||||
@@ -97,8 +97,8 @@
|
|||||||
run;
|
run;
|
||||||
|
|
||||||
|
|
||||||
@param [in] access_token_var= The global macro variable to contain the access
|
@param [in] access_token_var= The global macro variable to contain the
|
||||||
token
|
access token
|
||||||
@param [in] grant_type= valid values:
|
@param [in] grant_type= valid values:
|
||||||
@li password
|
@li password
|
||||||
@li authorization_code
|
@li authorization_code
|
||||||
@@ -136,6 +136,13 @@
|
|||||||
,raise_err=0
|
,raise_err=0
|
||||||
,mdebug=0
|
,mdebug=0
|
||||||
);
|
);
|
||||||
|
%local dbg;
|
||||||
|
%if &mdebug=1 %then %do;
|
||||||
|
%put &sysmacroname entry vars:;
|
||||||
|
%put _local_;
|
||||||
|
%end;
|
||||||
|
%else %let dbg=*;
|
||||||
|
|
||||||
%local oauth_bearer;
|
%local oauth_bearer;
|
||||||
%if &grant_type=detect %then %do;
|
%if &grant_type=detect %then %do;
|
||||||
%if %symexist(&access_token_var) %then %let grant_type=authorization_code;
|
%if %symexist(&access_token_var) %then %let grant_type=authorization_code;
|
||||||
@@ -230,123 +237,150 @@ data;run;%let jdswaitfor=&syslast;
|
|||||||
|
|
||||||
/* start loop */
|
/* start loop */
|
||||||
%do fid=1 %to &flowcnt;
|
%do fid=1 %to &flowcnt;
|
||||||
%put preparing job attributes for flow &&flow&fid;
|
|
||||||
%local jds jcnt;
|
|
||||||
data &jds(drop=_contextName _program);
|
|
||||||
set &inds(where=(flow_id=&&flow&fid));
|
|
||||||
if _contextName='' then _contextName="SAS Job Execution compute context";
|
|
||||||
call symputx(cats('job',_n_),_program,'l');
|
|
||||||
call symputx(cats('context',_n_),_contextName,'l');
|
|
||||||
call symputx('jcnt',_n_,'l');
|
|
||||||
run;
|
|
||||||
%put exporting job variables in json format;
|
|
||||||
%do jid=1 %to &jcnt;
|
|
||||||
data &jjson;
|
|
||||||
set &jds;
|
|
||||||
if _n_=&jid then do;
|
|
||||||
output;
|
|
||||||
stop;
|
|
||||||
end;
|
|
||||||
run;
|
|
||||||
proc json out=&jfref;
|
|
||||||
export &jjson / nosastags fmtnumeric;
|
|
||||||
run;
|
|
||||||
data _null_;
|
|
||||||
infile &jfref lrecl=32767;
|
|
||||||
input;
|
|
||||||
jparams='jparams'!!left(symget('jid'));
|
|
||||||
call symputx(jparams,substr(_infile_,3,length(_infile_)-4));
|
|
||||||
run;
|
|
||||||
%local jobuid&jid;
|
|
||||||
%let jobuid&jid=0; /* used in next loop */
|
|
||||||
%end;
|
|
||||||
%local concurrency completed;
|
|
||||||
%let concurrency=0;
|
|
||||||
%let completed=0;
|
|
||||||
proc sql; drop table &jdsrunning;
|
|
||||||
%do jid=1 %to &jcnt;
|
|
||||||
/**
|
|
||||||
* now we can execute the jobs up to the maxconcurrency setting
|
|
||||||
*/
|
|
||||||
%if "&&job&jid" ne "0" %then %do; /* this var is zero if job finished */
|
|
||||||
|
|
||||||
/* check to see if the job finished in the previous round */
|
%if not ( &raise_err and &syscc ) %then %do;
|
||||||
%if %sysfunc(exist(&outds))=1 %then %do;
|
|
||||||
%local jobcheck; %let jobcheck=0;
|
%put preparing job attributes for flow &&flow&fid;
|
||||||
proc sql noprint;
|
%local jds jcnt;
|
||||||
select count(*) into: jobcheck
|
data &jds(drop=_contextName _program);
|
||||||
from &outds where uuid="&&jobuid&jid";
|
set &inds(where=(flow_id=&&flow&fid));
|
||||||
%if &jobcheck>0 %then %do;
|
if _contextName='' then _contextName="SAS Job Execution compute context";
|
||||||
%put &&job&jid in flow &fid with uid &&jobuid&jid completed!;
|
call symputx(cats('job',_n_),_program,'l');
|
||||||
%let job&jid=0;
|
call symputx(cats('context',_n_),_contextName,'l');
|
||||||
|
call symputx('jcnt',_n_,'l');
|
||||||
|
run;
|
||||||
|
%put exporting job variables in json format;
|
||||||
|
%do jid=1 %to &jcnt;
|
||||||
|
data &jjson;
|
||||||
|
set &jds;
|
||||||
|
if _n_=&jid then do;
|
||||||
|
output;
|
||||||
|
stop;
|
||||||
|
end;
|
||||||
|
run;
|
||||||
|
proc json out=&jfref;
|
||||||
|
export &jjson / nosastags fmtnumeric;
|
||||||
|
run;
|
||||||
|
data _null_;
|
||||||
|
infile &jfref lrecl=32767;
|
||||||
|
input;
|
||||||
|
jparams='jparams'!!left(symget('jid'));
|
||||||
|
call symputx(jparams,substr(_infile_,3,length(_infile_)-4));
|
||||||
|
run;
|
||||||
|
%local jobuid&jid;
|
||||||
|
%let jobuid&jid=0; /* used in next loop */
|
||||||
|
%end;
|
||||||
|
%local concurrency completed;
|
||||||
|
%let concurrency=0;
|
||||||
|
%let completed=0;
|
||||||
|
proc sql; drop table &jdsrunning;
|
||||||
|
%do jid=1 %to &jcnt;
|
||||||
|
/**
|
||||||
|
* now we can execute the jobs up to the maxconcurrency setting
|
||||||
|
*/
|
||||||
|
%if "&&job&jid" ne "0" %then %do; /* this var is zero if job finished */
|
||||||
|
|
||||||
|
/* check to see if the job finished in the previous round */
|
||||||
|
%if %sysfunc(exist(&outds))=1 %then %do;
|
||||||
|
%local jobcheck; %let jobcheck=0;
|
||||||
|
proc sql noprint;
|
||||||
|
select count(*) into: jobcheck
|
||||||
|
from &outds where uuid="&&jobuid&jid";
|
||||||
|
%if &jobcheck>0 %then %do;
|
||||||
|
%put &&job&jid in flow &fid with uid &&jobuid&jid completed!;
|
||||||
|
%let job&jid=0;
|
||||||
|
%end;
|
||||||
|
%end;
|
||||||
|
|
||||||
|
/* check if job was triggered and, if
|
||||||
|
so, if we have enough slots to run? */
|
||||||
|
%if ("&&jobuid&jid"="0") and (&concurrency<&maxconcurrency) %then %do;
|
||||||
|
|
||||||
|
/* But only start if no issues detected so far */
|
||||||
|
%if not ( &raise_err and &syscc ) %then %do;
|
||||||
|
|
||||||
|
%local jobname jobpath;
|
||||||
|
%let jobname=%scan(&&job&jid,-1,/);
|
||||||
|
%let jobpath=
|
||||||
|
%substr(&&job&jid,1,%length(&&job&jid)-%length(&jobname)-1);
|
||||||
|
|
||||||
|
%put executing &jobpath/&jobname with paramstring &&jparams&jid;
|
||||||
|
%mv_jobexecute(path=&jobpath
|
||||||
|
,name=&jobname
|
||||||
|
,paramstring=%superq(jparams&jid)
|
||||||
|
,outds=&jdsapp
|
||||||
|
)
|
||||||
|
data &jdsapp;
|
||||||
|
format jobparams $32767.;
|
||||||
|
set &jdsapp(where=(method='GET' and rel='state'));
|
||||||
|
jobparams=symget("jparams&jid");
|
||||||
|
/* uri here has the /state suffix */
|
||||||
|
uuid=scan(uri,-2,'/');
|
||||||
|
call symputx("jobuid&jid",uuid,'l');
|
||||||
|
run;
|
||||||
|
proc append base=&jdsrunning data=&jdsapp;
|
||||||
|
run;
|
||||||
|
%let concurrency=%eval(&concurrency+1);
|
||||||
|
/* sleep one second after every request to smooth the impact */
|
||||||
|
data _null_;
|
||||||
|
call sleep(1,1);
|
||||||
|
run;
|
||||||
|
|
||||||
|
%end;
|
||||||
|
%else %do; /* Job was skipped due to problems */
|
||||||
|
|
||||||
|
%put jobid &&job&jid in flow &fid skipped due to SYSCC (&syscc);
|
||||||
|
%let completed = %eval(&completed+1);
|
||||||
|
%let job&jid=0; /* Indicate job has finished */
|
||||||
|
|
||||||
|
%end;
|
||||||
|
|
||||||
%end;
|
%end;
|
||||||
%end;
|
%end;
|
||||||
|
%if &jid=&jcnt %then %do;
|
||||||
|
/* we are at the end of the loop - check which jobs have finished */
|
||||||
|
%mv_jobwaitfor(ANY,inds=&jdsrunning,outds=&jdswaitfor,outref=&outref
|
||||||
|
,raise_err=&raise_err,mdebug=&mdebug)
|
||||||
|
%local done;
|
||||||
|
%let done=%mf_nobs(&jdswaitfor);
|
||||||
|
%if &done>0 %then %do;
|
||||||
|
%let completed=%eval(&completed+&done);
|
||||||
|
%let concurrency=%eval(&concurrency-&done);
|
||||||
|
data &jdsapp;
|
||||||
|
set &jdswaitfor;
|
||||||
|
flow_id=&&flow&fid;
|
||||||
|
uuid=scan(uri,-1,'/');
|
||||||
|
run;
|
||||||
|
proc append base=&outds data=&jdsapp;
|
||||||
|
run;
|
||||||
|
%end;
|
||||||
|
proc sql;
|
||||||
|
delete from &jdsrunning
|
||||||
|
where uuid in (select uuid from &outds
|
||||||
|
where state in ('canceled','completed','failed')
|
||||||
|
);
|
||||||
|
|
||||||
/* check if job was triggered and if so, if we have enough slots to run */
|
/* loop again if jobs are left */
|
||||||
%if "&&jobuid&jid"="0" and &concurrency<&maxconcurrency %then %do;
|
%if &completed < &jcnt %then %do;
|
||||||
%local jobname jobpath;
|
%let jid=0;
|
||||||
%let jobname=%scan(&&job&jid,-1,/);
|
%put looping flow &fid again;
|
||||||
%let jobpath=
|
%put &completed of &jcnt jobs completed, &concurrency jobs running;
|
||||||
%substr(&&job&jid,1,%length(&&job&jid)-%length(&jobname)-1);
|
%end;
|
||||||
%put executing &jobpath/&jobname with paramstring &&jparams&jid;
|
|
||||||
%mv_jobexecute(path=&jobpath
|
|
||||||
,name=&jobname
|
|
||||||
,paramstring=%superq(jparams&jid)
|
|
||||||
,outds=&jdsapp
|
|
||||||
)
|
|
||||||
data &jdsapp;
|
|
||||||
format jobparams $32767.;
|
|
||||||
set &jdsapp(where=(method='GET' and rel='state'));
|
|
||||||
jobparams=symget("jparams&jid");
|
|
||||||
/* uri here has the /state suffix */
|
|
||||||
uuid=scan(uri,-2,'/');
|
|
||||||
call symputx("jobuid&jid",uuid,'l');
|
|
||||||
run;
|
|
||||||
proc append base=&jdsrunning data=&jdsapp;
|
|
||||||
run;
|
|
||||||
%let concurrency=%eval(&concurrency+1);
|
|
||||||
/* sleep one second after every request to smooth the impact */
|
|
||||||
data _null_;
|
|
||||||
call sleep(1,1);
|
|
||||||
run;
|
|
||||||
%end;
|
%end;
|
||||||
%end;
|
%end;
|
||||||
%if &jid=&jcnt %then %do;
|
|
||||||
/* we are at the end of the loop - time to see which jobs have finished */
|
|
||||||
%mv_jobwaitfor(ANY,inds=&jdsrunning,outds=&jdswaitfor,outref=&outref
|
|
||||||
,raise_err=&raise_err)
|
|
||||||
%local done;
|
|
||||||
%let done=%mf_nobs(&jdswaitfor);
|
|
||||||
%if &done>0 %then %do;
|
|
||||||
%let completed=%eval(&completed+&done);
|
|
||||||
%let concurrency=%eval(&concurrency-&done);
|
|
||||||
data &jdsapp;
|
|
||||||
set &jdswaitfor;
|
|
||||||
flow_id=&&flow&fid;
|
|
||||||
uuid=scan(uri,-1,'/');
|
|
||||||
run;
|
|
||||||
proc append base=&outds data=&jdsapp;
|
|
||||||
run;
|
|
||||||
%end;
|
|
||||||
proc sql;
|
|
||||||
delete from &jdsrunning
|
|
||||||
where uuid in (select uuid from &outds
|
|
||||||
where state in ('canceled','completed','failed')
|
|
||||||
);
|
|
||||||
|
|
||||||
/* loop again if jobs are left */
|
%end;
|
||||||
%if &completed < &jcnt %then %do;
|
%else %do;
|
||||||
%let jid=0;
|
|
||||||
%put looping flow &fid again - &completed of &jcnt jobs completed,
|
%put Flow &&flow&fid skipped due to SYSCC (&syscc);
|
||||||
&concurrency jobs running;
|
|
||||||
%end;
|
|
||||||
%end;
|
|
||||||
%end;
|
%end;
|
||||||
/* back up and execute the next flow */
|
/* back up and execute the next flow */
|
||||||
%end;
|
%end;
|
||||||
|
|
||||||
%if &mdebug=1 %then %do;
|
%if &mdebug=1 %then %do;
|
||||||
|
%put &sysmacroname exit vars:;
|
||||||
%put _local_;
|
%put _local_;
|
||||||
%end;
|
%end;
|
||||||
|
|
||||||
%mend;
|
%mend mv_jobflow;
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/**
|
/**
|
||||||
@file
|
@file
|
||||||
@brief Takes a dataset of running jobs and waits for ANY or ALL of them to complete
|
@brief Takes a table of running jobs and waits for ANY/ALL of them to complete
|
||||||
@details Will poll `/jobs/{jobId}/state` at set intervals until ANY or ALL
|
@details Will poll `/jobs/{jobId}/state` at set intervals until ANY or ALL
|
||||||
jobs are completed. Completion is determined by reference to the returned
|
jobs are completed. Completion is determined by reference to the returned
|
||||||
_state_, as per the following table:
|
_state_, as per the following table:
|
||||||
@@ -55,13 +55,14 @@
|
|||||||
|
|
||||||
%mv_deletejes(path=/Public/temp,name=demo)
|
%mv_deletejes(path=/Public/temp,name=demo)
|
||||||
|
|
||||||
@param [in] access_token_var= The global macro variable to contain the access token
|
@param [in] access_token_var= The global macro variable to contain the access
|
||||||
|
token
|
||||||
@param [in] grant_type= valid values:
|
@param [in] grant_type= valid values:
|
||||||
|
|
||||||
- password
|
- password
|
||||||
- authorization_code
|
- authorization_code
|
||||||
- detect - will check if access_token exists, if not will use sas_services if
|
- detect - will check if access_token exists, if not will use sas_services
|
||||||
a SASStudioV session else authorization_code. Default option.
|
if a SASStudioV session else authorization_code. Default option.
|
||||||
- sas_services - will use oauth_bearer=sas_services
|
- sas_services - will use oauth_bearer=sas_services
|
||||||
|
|
||||||
@param [in] action=Either ALL (to wait for every job) or ANY (if one job
|
@param [in] action=Either ALL (to wait for every job) or ANY (if one job
|
||||||
@@ -72,9 +73,11 @@
|
|||||||
should be in a `_program` variable.
|
should be in a `_program` variable.
|
||||||
@param [in] raise_err=0 Set to 1 to raise SYSCC when a job does not complete
|
@param [in] raise_err=0 Set to 1 to raise SYSCC when a job does not complete
|
||||||
succcessfully
|
succcessfully
|
||||||
|
@param [in] mdebug= set to 1 to enable DEBUG messages
|
||||||
@param [out] outds= The output dataset containing the list of states by job
|
@param [out] outds= The output dataset containing the list of states by job
|
||||||
(default=work.mv_jobexecute)
|
(default=work.mv_jobexecute)
|
||||||
@param [out] outref= A fileref to which the spawned job logs should be appended.
|
@param [out] outref= A fileref to which the spawned job logs should be
|
||||||
|
appended.
|
||||||
|
|
||||||
@version VIYA V.03.04
|
@version VIYA V.03.04
|
||||||
@author Allan Bowe, source: https://github.com/sasjs/core
|
@author Allan Bowe, source: https://github.com/sasjs/core
|
||||||
@@ -97,7 +100,15 @@
|
|||||||
,outds=work.mv_jobwaitfor
|
,outds=work.mv_jobwaitfor
|
||||||
,outref=0
|
,outref=0
|
||||||
,raise_err=0
|
,raise_err=0
|
||||||
|
,mdebug=0
|
||||||
);
|
);
|
||||||
|
%local dbg;
|
||||||
|
%if &mdebug=1 %then %do;
|
||||||
|
%put &sysmacroname entry vars:;
|
||||||
|
%put _local_;
|
||||||
|
%end;
|
||||||
|
%else %let dbg=*;
|
||||||
|
|
||||||
%local oauth_bearer;
|
%local oauth_bearer;
|
||||||
%if &grant_type=detect %then %do;
|
%if &grant_type=detect %then %do;
|
||||||
%if %symexist(&access_token_var) %then %let grant_type=authorization_code;
|
%if %symexist(&access_token_var) %then %let grant_type=authorization_code;
|
||||||
@@ -155,7 +166,8 @@ run;
|
|||||||
%let fname0=%mf_getuniquefileref();
|
%let fname0=%mf_getuniquefileref();
|
||||||
|
|
||||||
data &outds;
|
data &outds;
|
||||||
format _program uri $128. state $32. stateDetails $32. timestamp datetime19. jobparams $32767.;
|
format _program uri $128. state $32. stateDetails $32. timestamp datetime19.
|
||||||
|
jobparams $32767.;
|
||||||
stop;
|
stop;
|
||||||
run;
|
run;
|
||||||
|
|
||||||
@@ -168,8 +180,8 @@ run;
|
|||||||
"Authorization"="Bearer &&&access_token_var"
|
"Authorization"="Bearer &&&access_token_var"
|
||||||
%end; ;
|
%end; ;
|
||||||
run;
|
run;
|
||||||
%if &SYS_PROCHTTP_STATUS_CODE ne 200 and &SYS_PROCHTTP_STATUS_CODE ne 201 %then
|
%if &SYS_PROCHTTP_STATUS_CODE ne 200 and &SYS_PROCHTTP_STATUS_CODE ne 201
|
||||||
%do;
|
%then %do;
|
||||||
data _null_;infile &fname0;input;putlog _infile_;run;
|
data _null_;infile &fname0;input;putlog _infile_;run;
|
||||||
%mp_abort(mac=&sysmacroname
|
%mp_abort(mac=&sysmacroname
|
||||||
,msg=%str(&SYS_PROCHTTP_STATUS_CODE &SYS_PROCHTTP_STATUS_PHRASE)
|
,msg=%str(&SYS_PROCHTTP_STATUS_CODE &SYS_PROCHTTP_STATUS_PHRASE)
|
||||||
@@ -205,7 +217,7 @@ run;
|
|||||||
%let joburi&i=0; /* do not re-check */
|
%let joburi&i=0; /* do not re-check */
|
||||||
/* fetch log */
|
/* fetch log */
|
||||||
%if %str(&outref) ne 0 %then %do;
|
%if %str(&outref) ne 0 %then %do;
|
||||||
%mv_getjoblog(uri=&plainuri,outref=&outref)
|
%mv_getjoblog(uri=&plainuri,outref=&outref,mdebug=&mdebug)
|
||||||
%end;
|
%end;
|
||||||
%end;
|
%end;
|
||||||
%else %if &status=idle or &status=pending or &status=running %then %do;
|
%else %if &status=idle or &status=pending or &status=running %then %do;
|
||||||
@@ -220,10 +232,11 @@ run;
|
|||||||
%end;
|
%end;
|
||||||
|
|
||||||
%if (&raise_err) %then %do;
|
%if (&raise_err) %then %do;
|
||||||
%if (&status = canceled or &status = failed or %length(&stateDetails)>0) %then %do;
|
%if (&status = canceled or &status = failed or %length(&stateDetails)>0)
|
||||||
|
%then %do;
|
||||||
%if ("&stateDetails" = "%str(war)ning") %then %let SYSCC=4;
|
%if ("&stateDetails" = "%str(war)ning") %then %let SYSCC=4;
|
||||||
%else %let SYSCC=5;
|
%else %let SYSCC=5;
|
||||||
%put %str(ERR)OR: Job &&jobname&i. did not complete successfully. &stateDetails;
|
%put %str(ERR)OR: Job &&jobname&i. did not complete. &stateDetails;
|
||||||
%return;
|
%return;
|
||||||
%end;
|
%end;
|
||||||
%end;
|
%end;
|
||||||
@@ -238,7 +251,12 @@ run;
|
|||||||
%end;
|
%end;
|
||||||
%end;
|
%end;
|
||||||
|
|
||||||
/* clear refs */
|
%if &mdebug=1 %then %do;
|
||||||
filename &fname0 clear;
|
%put &sysmacroname exit vars:;
|
||||||
|
%put _local_;
|
||||||
%mend;
|
%end;
|
||||||
|
%else %do;
|
||||||
|
/* clear refs */
|
||||||
|
filename &fname0 clear;
|
||||||
|
%end;
|
||||||
|
%mend mv_jobwaitfor;
|
||||||
Reference in New Issue
Block a user