diff --git a/base/mp_testservice.sas b/base/mp_testservice.sas
index 12e7466..74b3ff6 100644
--- a/base/mp_testservice.sas
+++ b/base/mp_testservice.sas
@@ -42,6 +42,7 @@
@li mp_binarycopy.sas
@li mp_chop.sas
@li mp_ds2csv.sas
+ @li ms_testservice.sas
@li mv_getjobresult.sas
@li mv_jobflow.sas
@@ -270,95 +271,16 @@ filename &webref "&webrefpath";
%end;
%else %if &platform=SASJS %then %do;
- /* avoid sending bom marker to API */
- %local optval;
- %let optval=%sysfunc(getoption(bomfile));
- options nobomfile;
-
- data _null_;
- file &fname0 termstr=crlf;
- infile &inref end=eof;
- if _n_ = 1 then do;
- put "--&boundary.";
- put 'Content-Disposition: form-data; name="filePath"';
- put ;
- put "&driveloc";
- put "--&boundary";
- put 'Content-Disposition: form-data; name="file"; filename="ignore.sas"';
- put "Content-Type: text/plain";
- put ;
- end;
- input;
- put _infile_; /* add the actual file to be sent */
- if eof then do;
- put ;
- put "--&boundary--";
- end;
- run;
-
- data _null_;
- file &fname1 lrecl=1000;
- infile "&_sasjs_tokenfile" lrecl=1000;
- input;
- put "Content-Type: multipart/form-data; boundary=&boundary";
- put "Authorization: Bearer " _infile_;
- run;
-
- %if &mdebug=1 %then %do;
- data _null_;
- infile &fname0;
- input;
- put _infile_;
- data _null_;
- infile &fname1;
- input;
- put _infile_;
- run;
- %end;
-
- proc http method='POST' in=&fname0 headerin=&fname1 out=&webref
- url="&_sasjs_apiserverurl/SASjsApi/drive/file";
- %if &mdebug=1 %then %do;
- debug level=1;
- %end;
- run;
-
- /* reset options */
- options &optval;
-
- /* SASjs services have the _webout embedded in wrapper JSON */
- /* Files can also be very large - so use a dedicated macro to chop it out */
- %local matchstr1 matchstr2 chopout1 chopout2;
- %let matchstr1={"status":"success","_webout":{;
- %let matchst2=},"log":[{;
- %let chopout1=&webrefpath._1;
- %let chopout2=&webrefpath._2;
-
- %mp_chop("&webrefpath"
- ,matchvar=matchstr1
- ,keep=LAST
- ,matchpoint=END
- ,offset=-1
- ,outfile="&chopout1"
+ %ms_testservice(&program
+ ,inputfiles=&inputfiles
+ ,inputdatasets=&inputdatasets
+ ,inputparams=&inputparams
+ ,debug=&debug
,mdebug=&mdebug
+ ,outlib=&outlib
+ ,outref=&outref
)
- %mp_chop("&chopout1"
- ,matchvar=matchstr2
- ,keep=FIRST
- ,matchpoint=START
- ,offset=1
- ,outfile="&chopout2"
- ,mdebug=&mdebug
- )
-
- %if &outlib ne 0 %then %do;
- libname &outlib json ("&chopout2");
- %end;
- %if &outref ne 0 %then %do;
- filename &outref "&chopout2";
- %end;
-
%end;
%else %do;
%put %str(ERR)OR: Unrecognised platform: &platform;
diff --git a/server/ms_testservice.sas b/server/ms_testservice.sas
new file mode 100644
index 0000000..16db635
--- /dev/null
+++ b/server/ms_testservice.sas
@@ -0,0 +1,152 @@
+/**
+ @file
+ @brief Will execute a SASjs web service on SASjs Server
+ @details Prepares the input files and retrieves the resulting datasets from
+ the response JSON.
+
+ @param [in] program The Stored 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] inputdatasets= (0) All datasets in this space seperated list are
+ converted into SASJS-formatted CSVs (see mp_ds2csv.sas) files and added to
+ the list of `inputfiles` for ingestion. The dataset will be sent with the
+ same name (no need for a colon modifier).
+ @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= (131) Provide the _debug value to pass to the STP
+ @param [in] mdebug= (0) Set to 1 to provide macro debugging (this macro)
+ @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.
+ @param [out] outlogds= (_null_) Set to the name of a dataset to contain the
+ log. Table format:
+ |line:$2000|
+ |---|
+ |log line 1|
+ |log line 2|
+
+
SAS Macros
+ @li mf_getuniquefileref.sas
+ @li mf_getuniquename.sas
+ @li mp_abort.sas
+ @li mp_binarycopy.sas
+ @li mp_chop.sas
+ @li mp_ds2csv.sas
+ @li ms_runstp.sas
+
+ Related Programs
+ @li mp_testservice.test.sas
+
+ @version 9.4
+ @author Allan Bowe
+
+**/
+
+%macro ms_testservice(program,
+ inputfiles=0,
+ inputdatasets=0,
+ inputparams=0,
+ debug=0,
+ mdebug=0,
+ outlib=0,
+ outref=0,
+ outlogds=_null_
+)/*/STORE SOURCE*/;
+%local dbg fref1 chopout1 chopout2;
+%if &mdebug=1 %then %do;
+ %put &sysmacroname entry vars:;
+ %put _local_;
+%end;
+%else %let dbg=*;
+
+/* convert inputdatasets to filerefs */
+%if "&inputdatasets" ne "0" %then %do;
+ %if %quote(&inputfiles)=0 %then %let inputfiles=;
+ %do i=1 %to %sysfunc(countw(&inputdatasets,%str( )));
+ %let var=%scan(&inputdatasets,&i,%str( ));
+ %local dsref&i;
+ %let dsref&i=%mf_getuniquefileref();
+ %mp_ds2csv(&var,outref=&&dsref&i,headerformat=SASJS)
+ %let inputfiles=&inputfiles &&dsref&i:%scan(&var,-1,.);
+ %end;
+%end;
+
+/* parse the filerefs - convert to a dataset */
+%let ds1=%mf_getuniquename();
+data &ds1;
+ length fileref $8 name $32 filename $256 var $300;
+ webcount=countw("&inputfiles");
+ do i=1 to webcount;
+ var=scan("&inputfiles",i,' ');
+ fileref=scan(var,1,':');
+ name=scan(var,2,':');
+ filename=cats(name,'.csv');
+ output;
+ end;
+run;
+
+
+/* execute the STP */
+%let fref1=%mf_getuniquefileref();
+
+%ms_runstp(&program
+ ,debug=&debug
+ ,inputparams=&inputparams
+ ,inputfiles=&ds1
+ ,outref=&fref1
+ ,mdebug=&mdebug
+ ,outlogds=&outlogds
+)
+
+
+/* SASjs services have the _webout embedded in wrapper JSON */
+/* Files can also be very large - so use a dedicated macro to chop it out */
+%local matchstr1 matchstr2 ;
+%let matchstr1={"status":"success","_webout":{;
+%let matchstr2=},"log":[{;
+%let chopout1=%sysfunc(pathname(work))/%mf_getuniquename(prefix=chop1);
+%let chopout2=%sysfunc(pathname(work))/%mf_getuniquename(prefix=chop2);
+
+%mp_chop("%sysfunc(pathname(&fref1,F))"
+ ,matchvar=matchstr1
+ ,keep=LAST
+ ,matchpoint=END
+ ,offset=-1
+ ,outfile="&chopout1"
+ ,mdebug=&mdebug
+)
+
+%mp_chop("&chopout1"
+ ,matchvar=matchstr2
+ ,keep=FIRST
+ ,matchpoint=START
+ ,offset=1
+ ,outfile="&chopout2"
+ ,mdebug=&mdebug
+)
+
+%if &outlib ne 0 %then %do;
+ libname &outlib json "&chopout2";
+%end;
+%if &outref ne 0 %then %do;
+ filename &outref "&chopout2";
+%end;
+
+%if &mdebug=0 %then %do;
+ filename &webref clear;
+ filename &fref1 clear;
+ filename &fref2 clear;
+%end;
+%else %do;
+ %put &sysmacroname exit vars:;
+ %put _local_;
+%end;
+
+%mend ms_testservice;
\ No newline at end of file
diff --git a/tests/crossplatform/mp_testservice.test.sas b/tests/crossplatform/mp_testservice.test.sas
index 315326d..d52cefc 100644
--- a/tests/crossplatform/mp_testservice.test.sas
+++ b/tests/crossplatform/mp_testservice.test.sas
@@ -55,37 +55,28 @@ run;
outlib=testlib1,
outref=test1
)
-
-%global test1a test1b test1c test1d;
+%let test1=FAIL;
data _null_;
- infile test1;
- input;
- putlog _n_ _infile_;
- if _infile_=', "somedata1":' then call symputx('test1a','PASS');
- if _infile_='{"X":1 ,"Y":" t\"w\"o" ,"Z":"Z" }' then
- call symputx('test1b','PASS');
- if _infile_='], "somedata2":' then call symputx('test1c','PASS');
- if _infile_='{"X":1 ,"Y":" t\"w\"o" ,"Z":"Z" }' then
- call symputx('test1d','PASS');
+ set testlib1.somedata1;
+ if x=1 and y=' t"w"o' and z="Z" then call symputx('test1','PASS');
+ putlog (_all_)(=);
run;
+%let test2=FAIL;
+data _null_;
+ set testlib1.somedata2;
+ if x=1 and y=' t"w"o' and z="Z" then call symputx('test2','PASS');
+ putlog (_all_)(=);
+run;
+
+
%mp_assert(
- iftrue=(&test1a=PASS),
- desc=Test 1 table 1 name,
+ iftrue=(&test1=PASS),
+ desc=somedata1 created correctly,
outds=work.test_results
)
%mp_assert(
- iftrue=(&test1b=PASS),
- desc=Test 1 table 1 values,
+ iftrue=(&test2=PASS),
+ desc=somedata2 created correctly,
outds=work.test_results
)
-%mp_assert(
- iftrue=(&test1c=PASS),
- desc=Test 1 table 2 name,
- outds=work.test_results
-)
-%mp_assert(
- iftrue=(&test1d=PASS),
- desc=Test 1 table 2 values,
- outds=work.test_results
-)
\ No newline at end of file
diff --git a/tests/serveronly/ms_testservice.test.sas b/tests/serveronly/ms_testservice.test.sas
new file mode 100644
index 0000000..e61f7dc
--- /dev/null
+++ b/tests/serveronly/ms_testservice.test.sas
@@ -0,0 +1,87 @@
+/**
+ @file
+ @brief Testing ms_testservice.sas macro
+
+ SAS Macros
+ @li ms_createwebservice.sas
+ @li ms_testservice.sas
+ @li mp_assert.sas
+
+**/
+
+filename ft15f001 temp;
+parmcards4;
+ %put Initialising sendObj: ;
+ %put _all_;
+ %webout(FETCH)
+ %webout(OPEN)
+ %macro x();
+ %if (%symexist(sasjs_tables) and %length(&sasjs_tables)>0)
+ %then %do i=1 %to %sysfunc(countw(&sasjs_tables));
+ %let table=%scan(&sasjs_tables,&i);
+ %webout(OBJ,&table,missing=STRING)
+ %end;
+ %else %do i=1 %to &_webin_file_count;
+ %webout(OBJ,&&_webin_name&i,missing=STRING)
+ %end;
+ %mend x; %x()
+ %webout(CLOSE)
+;;;;
+%put creating web service: &mcTestAppLoc/services;
+%ms_createwebservice(
+ path=&mcTestAppLoc/services,
+ name=sendObj,
+ mdebug=&sasjs_mdebug
+)
+%put created web service: &mcTestAppLoc/services;
+
+%mp_assert(
+ iftrue=(&syscc=0),
+ desc=No errors after service creation,
+ outds=work.test_results
+)
+
+/**
+ * Test 1 - send a dataset
+ */
+data work.somedata1 work.somedata2;
+ x=1;
+ y=' t"w"o';
+ z=.z;
+ label x='x factor';
+ output;
+run;
+
+%ms_testservice(&mcTestAppLoc/services/sendObj,
+ inputdatasets=work.somedata1 work.somedata2,
+ debug=log,
+ mdebug=1,
+ outlib=testlib1,
+ outref=test1
+)
+
+%let test1=FAIL;
+data _null_;
+ set testlib1.somedata1;
+ if x=1 and y=' t"w"o' and z="Z" then call symputx('test1','PASS');
+ putlog (_all_)(=);
+run;
+
+%let test2=FAIL;
+data _null_;
+ set testlib1.somedata2;
+ if x=1 and y=' t"w"o' and z="Z" then call symputx('test2','PASS');
+ putlog (_all_)(=);
+run;
+
+
+%mp_assert(
+ iftrue=(&test1=PASS),
+ desc=somedata1 created correctly,
+ outds=work.test_results
+)
+%mp_assert(
+ iftrue=(&test2=PASS),
+ desc=somedata2 created correctly,
+ outds=work.test_results
+)