Macros for SAS Application Developers
https://github.com/sasjs/core
Loading...
Searching...
No Matches
mv_getjobresult.test.sas
Go to the documentation of this file.
1/**
2 @file
3 @brief Testing mv_createwebservice macro
4
5 <h4> SAS Macros </h4>
6 @li mp_assert.sas
7 @li mp_assertdsobs.sas
8 @li mv_createwebservice.sas
9 @li mv_getjobresult.sas
10 @li mv_jobflow.sas
11
12 @sasjslint {"ignoredMacros": ["mp_abort"]}
13**/
14
15options mprint notes;
16
17/**
18 * Test Case 1
19 */
20
21/* create a service */
22filename testref temp;
23data _null_;
24 file testref;
25 put 'data test; set sashelp.class;run;';
26 put '%webout(OPEN)';
27 put '%webout(OBJ,test)';
28 put '%webout(CLOSE)';
29run;
30%mv_createwebservice(
31 path=&mcTestAppLoc/services/temp,
32 code=testref,
33 name=testsvc
34)
35
36/* trigger and wait for it to finish */
37data work.inputjobs;
38 _program="&mcTestAppLoc/services/temp/testsvc";
39run;
40%mv_jobflow(inds=work.inputjobs
41 ,maxconcurrency=4
42 ,outds=work.results
43 ,outref=myjoblog
44)
45/* stream the log */
46data _null_;
47 infile myjoblog;
48 input;
49 put _infile_;
50run;
51
52/* fetch the uri */
53data _null_;
54 set work.results;
55 call symputx('uri',uri);
56 put (_all_)(=);
57run;
58
59/* now get the results */
60%mv_getjobresult(uri=&uri
61 ,result=WEBOUT_JSON
62 ,outref=myweb
63 ,outlib=myweblib
64)
65data _null_;
66 infile myweb;
67 input;
68 putlog _infile_;
69run;
70data work.out;
71 set myweblib.test;
72 put (_all_)(=);
73run;
74%mp_assertdsobs(work.out,
75 desc=Test1 - 19 obs from sashelp.class in service result,
76 test=EQUALS 19,
77 outds=work.test_results
78)
79
80/**
81 * Test Case 2 - a binary webout
82 *
83 * A job that streams a file registers its result under the file's own name
84 * (_webout.pdf and friends). A dotted key cannot be named through result=,
85 * so the macro has to find the member itself. The payload carries the bytes
86 * a text-mode copy would damage - CR, LF and NUL - so the first nine bytes are
87 * compared exactly.
88 */
89filename testref2 temp;
90data _null_;
91 file testref2;
92 put 'filename binref filesrvc parenturi="&SYS_JES_JOB_URI"';
93 put " name='_webout.pdf' contenttype='application/pdf';";
94 put 'data _null_;';
95 put ' length payload $9;';
96 put ' payload=cat(byte(71),byte(73),byte(70),byte(56),byte(57),byte(97)';
97 put ' ,byte(13),byte(10),byte(0));';
98 put ' file binref recfm=n;';
99 put ' put payload $char9.;';
100 put 'run;';
101run;
102%mv_createwebservice(
103 path=&mcTestAppLoc/services/temp,
104 code=testref2,
105 name=testsvcbin
106)
107
108data work.inputjobs2;
109 _program="&mcTestAppLoc/services/temp/testsvcbin";
110run;
111%mv_jobflow(inds=work.inputjobs2
112 ,maxconcurrency=1
113 ,outds=work.results2
114 ,outref=myjoblog2
115)
116data _null_;
117 set work.results2;
118 call symputx('uri2',uri);
119run;
120
121/* no result= on purpose - the caller cannot name a dotted member */
122%mv_getjobresult(uri=&uri2, outref=mybin)
123/* the first nine bytes are compared, which is also how DC's own download
124 * test reads a binary payload: a text-mode copy would drop the NUL and
125 * shift the rest, so the comparison fails rather than passing on a prefix */
126data _null_;
127 infile mybin recfm=f lrecl=9 obs=1;
128 length sig $9 want $9;
129 input sig $9.;
130 want=cat(byte(71),byte(73),byte(70),byte(56),byte(57),byte(97)
131 ,byte(13),byte(10),byte(0));
132 call symputx('isbin',ifn(sig=want,1,0),'l');
133run;
134%mp_assert(
135 iftrue=(&isbin=1),
136 desc=Test2 - binary webout returned byte for byte (CR LF NUL intact),
137 outds=work.test_results
138)
139
140/**
141 * Test Case 3 - an aborted child still yields a parsable result
142 *
143 * mp_abort writes the transport envelope (>>weboutBEGIN<<) around the abort
144 * object, because that is what the client frames the response with. The JSON
145 * engine knows nothing of it, so a libname over the raw artefact fails on line
146 * one - for exactly the responses a caller reads to find out why a child
147 * stopped. The abort object is the result here, so parsing it is the test.
148 */
149filename testref3 temp;
150data _null_;
151 file testref3;
152 put '%mp_abort(mac=test,msg=%str(deliberate abort from getjobresult test))';
153run;
154%mv_createwebservice(
155 path=&mcTestAppLoc/services/temp,
156 code=testref3,
157 name=testsvcabort
158)
159
160data work.inputjobs3;
161 _program="&mcTestAppLoc/services/temp/testsvcabort";
162run;
163%mv_jobflow(inds=work.inputjobs3
164 ,maxconcurrency=1
165 ,outds=work.results3
166 ,outref=myjoblog3
167)
168data _null_;
169 set work.results3;
170 call symputx('uri3',uri);
171 put (_all_)(=);
172run;
173
174/* no outref on purpose - the library is what used to break */
175%mv_getjobresult(uri=&uri3
176 ,result=WEBOUT_JSON
177 ,outlib=myabortlib
178)
179
180%let abortrows=0;
181%let abortmsg=;
182%if %sysfunc(exist(myabortlib.sasjsAbort)) %then %do;
183 data work.abortrows;
184 set myabortlib.sasjsAbort;
185 run;
186 data _null_;
187 set work.abortrows nobs=nobs;
188 call symputx('abortrows',nobs,'l');
189 call symputx('abortmsg',msg,'l');
190 run;
191%end;
192%mp_assert(
193 iftrue=(&abortrows=1),
194 desc=Test3 - aborted child result parses despite the response envelope,
195 outds=work.test_results
196)
197%mp_assert(
198 iftrue=(%index(%superq(abortmsg),deliberate abort)>0),
199 desc=Test3b - the parsed result carries the abort message,
200 outds=work.test_results
201)