SASUnit Examples  Version 1.2
assertlibrary.sas
Go to the documentation of this file.
1 
37 /*
38  29.01.2013 KL changed link from _sasunit_doc.sas to Sourceforge SASUnit User's Guide
39  13.12.2012 KL Despite the noprint option PROC COMPARE issues a warning when there is no opeb output destination.
40  So the listing destination is opened prior to calling PROC COMPARE.
41  28.05.2010 KL Pfade mit Sonderzeichen machen unter SAS9.2 Probleme, deshalb Strings in Hochkommata
42  06.02.2008 AM Dokumentation verbessert
43  05.11.2008 KL Unterdrücken von Warnings (Keine ODS Destination offen).
44  21.10.2008 KL Logik bei MoreColumns etc. war leider falschrum.
45  17.12.2007 KL Parameter ExcludeList hinzugefügt
46 */
47 
48 %MACRO assertLibrary (
49  i_actual = _NONE_
50  ,i_expected = _NONE_
51  ,i_desc = Bibliotheken prüfen
52  ,i_libraryCheck = STRICT
53  ,i_CompareCheck = STRICT
54  ,i_fuzz = _NONE_
55  ,i_id = _NONE_
56  ,i_ExcludeList = _NONE_
57 );
58 
59  %GLOBAL g_inTestcase;
60  %IF &g_inTestcase EQ 1 %THEN %DO;
61  %endTestcall;
62  %END;
63  %ELSE %IF &g_inTestcase NE 2 %THEN %DO;
64  %PUT &g_error: assert must be called after initTestcase;
65  %RETURN;
66  %END;
67 
68  %LOCAL l_casid l_tstid;
69  %_sasunit_asserts(
70  i_type = assertLibrary
71  ,i_expected = %eval (%sysfunc (libref (&i_expected.))=0)
72  ,i_actual = %eval (%sysfunc (libref (&i_actual.))=0)
73  ,i_desc = &i_desc
74  ,i_result = .
75  ,r_casid = l_casid
76  ,r_tstid = l_tstid
77  )
78 
79  %local l_actual_ok l_expected_ok l_result l_path_actual l_path_expected _sysinfo l_col_names l_id_col l_counter l_id;
80 
81  %*************************************************************;
82  %*** Check preconditions ***;
83  %*************************************************************;
84 
85  %*** check for valid actual libref ***;
86  %let l_actual_ok=%sysfunc (libref (&i_actual.));
87  %if (&l_actual_ok. > 0) %then %do;
88  %put &g_error: Libref i_actual (&i_actual.) is invalid!;
89  %let l_rc=1;
90  %goto Update;
91  %end;
92 
93  %*** check for valid expected libref ***;
94  %let l_expected_ok=%sysfunc (libref (&i_expected.));
95  %if (&l_expected_ok. > 0) %then %do;
96  %put &g_error: Libref i_expected (&i_expected.) is invalid!;
97  %let l_rc=1;
98  %goto Update;
99  %end;
100 
101  %*** check for equal librefs ***;
102  %if (&i_actual. = &i_expected.) %then %do;
103  %put &g_error: Librefs are identical!;
104  %let l_rc=1;
105  %goto Update;
106  %end;
107 
108  %*** check for identical paths ***;
109  %let l_path_actual = %sysfunc (pathname (&i_actual.));
110  %let l_path_expected = %sysfunc (pathname (&i_expected.));
111  %if ("&l_path_actual." = "&l_path_expected.") %then %do;
112  %put &g_error: paths are identical!;
113  %let l_rc=1;
114  %goto Update;
115  %end;
116 
117  %let i_LibraryCheck = %upcase (%trim(&i_LibraryCheck.));
118  %if (&i_LibraryCheck. ne STRICT AND &i_LibraryCheck. ne MORETABLES) %then %do;
119  %put &g_error: Value of i_LibraryCheck (%trim(&i_LibraryCheck.)) is invalid!;
120  %let l_rc=1;
121  %goto Update;
122  %end;
123 
124  %let i_CompareCheck = %upcase (%trim(&i_CompareCheck.));
125  %if (&i_CompareCheck. ne STRICT AND &i_CompareCheck. ne MORECOLUMNS
126  AND &i_CompareCheck. ne MOREOBS AND &i_CompareCheck. ne MORECOLSNOBS) %then %do;
127  %put &g_error: Value of i_CompareCheck (%trim(&i_CompareCheck.)) is invalid!;
128  %let l_rc=1;
129  %goto Update;
130  %end;
131 
132  %let i_ExcludeList = %upcase (%trim(&i_ExcludeList.));
133 
134  %local AnzCompares;
135 
136  %*************************************************************;
137  %*** start tests ***;
138  %*************************************************************;
139 
140  %*** get table names from the two libraries ***;
141  proc sql noprint;
142  create table WORK._assertLibraryActual as
143  select libname as BaseLibname,
144  memname as BaseMemName,
145  nlobs as BaseObs format=commax18.,
146  nvar as BaseNVar format=commax18.
147  from dictionary.tables
148  where libname = "%upcase(&i_actual)"
149  %if (&i_ExcludeList. ne _NONE_) %then %do;
150  AND memname not in (
151  %let counter=1;
152  %let l_id_col = %scan (&i_ExcludeList.,&counter., %str ( ));
153  %do %while (&l_id_col. ne );
154  "&l_id_col."
155  %let counter=%eval (&counter.+1);
156  %let l_id_col = %scan (&i_ExcludeList.,&counter., %str ( ));
157  %end;
158  )
159  %end;
160  order by memname;
161  create table WORK._assertLibraryExpected as
162  select libname as CmpLibname,
163  memname as CmpMemName,
164  nlobs as CmpObs format=commax18.,
165  nvar as CmpNVar format=commax18.
166  from dictionary.tables
167  where libname = "%upcase(&i_expected)"
168  %if (&i_ExcludeList. ne _NONE_) %then %do;
169  AND memname not in (
170  %let counter=1;
171  %let l_id_col = %scan (&i_ExcludeList.,&counter., %str ( ));
172  %do %while (&l_id_col. ne );
173  "&l_id_col."
174  %let counter=%eval (&counter.+1);
175  %let l_id_col = %scan (&i_ExcludeList.,&counter., %str ( ));
176  %end;
177  )
178  %end;
179  order by memname;
180  quit;
181 
182  %*** flag tables according to check results ***;
183  data work._ergebnis;
184  length DoCompare CompareFailed l_rc 8;
185  merge WORK._assertLibraryActual (in=InAct rename=(BaseMemname=memname))
186  WORK._assertLibraryExpected (in=InExp rename=(CmpMemname=memname));
187  by memname;
188  l_rc = .;
189  InActual=InAct;
190  InExpected=InExp;
191  if (InAct AND inExp) then do;
192  DoCompare=1;
193  CompareFailed=1;
194  if (BaseObs ne CmpObs) then do;
195  if ("&i_CompareCheck." = "STRICT" OR "&i_CompareCheck." = "MORECOLUMNS") then do;
196  DoCompare=0;
197  end;
198  end;
199  if (BaseNVar ne CmpNVar) then do;
200  if ("&i_CompareCheck." = "STRICT" OR "&i_CompareCheck." = "MOREOBS") then do;
201  DoCompare=0;
202  end;
203  end;
204  end;
205  else if (InAct AND not inExp AND "&i_LibraryCheck." ne "STRICT") then do;
206  DoCompare=0;
207  CompareFailed=0;
208  end;
209  else do;
210  DoCompare=0;
211  CompareFailed=1;
212  end;
213  run;
214 
215  %*** determine number of compared tables ***;
216  proc sql noprint;
217  select sum (DoCompare) into :AnzCompares
218  from work._ergebnis;
219  quit;
220 
221  %if (&AnzCompares. > 0) %then %do;
222  %do i=1 %to &AnzCompares.;
223  %local Memname&i.;
224  %end;
225 
226  proc sql noprint;
227  select memname into :Memname1-:Memname%trim(&AnzCompares.)
228  from work._ergebnis
229  where DoCompare=1;
230  quit;
231 
232  %*** upcase for id columns ***;
233  %if (&i_id. ne _NONE_) %then %do;
234  %let i_id=%upcase (&i_id.);
235  %end;
236 
237  %*** Check for open ODS DESTINATIONS ***;
238  %local OpenODSDestinations;
239  %let OpenODSDestinations=0;
240 
241  %*** SASHELP.VDEST is only available in 9.2 or later ***;
242  %if (&sysver. NE 9.1) %then %do;
243  proc sql noprint;
244  select count (*) into :OpenODSDestinations from sashelp.vdest;
245  quit;
246  %end;
247 
248  %if (&OpenODSDestinations. = 0) %then %do;
249  ods listing;
250  %end;
251 
252  %*** Compare each pair of tables ***;
253  %do i=1 %to &AnzCompares.;
254  %if (&i_id. ne _NONE_) %then %do;
255  %let l_col_names=;
256  %let l_id=;
257  proc sql noprint;
258  select distinct upcase (name) into :l_col_names separated by ' '
259  from dictionary.columns
260  where libname = "%upcase (&i_actual.)" AND upcase (memname) = "%upcase(&&memname&i.)";
261  quit;
262 
263  %let counter=1;
264  %let l_id_col = %scan (&i_id.,&counter., %str ( ));
265  %do %while (&l_id_col. ne );
266  %let l_found=%sysfunc (indexw (&l_col_names, &l_id_col.));
267  %if (&l_found. > 0) %then %do;
268  %let l_id = &l_id. &l_id_col;
269  %end;
270  %let counter=%eval (&counter.+1);
271  %let l_id_col = %scan (&i_id.,&counter., %str ( ));
272  %end;
273  %end;
274 
275  proc compare
276  base=&i_expected..&&memname&i.
277  compare=&i_actual..&&memname&i.
278  %if (&i_fuzz. ne _NONE_) %then %do;
279  CRITERION=&i_fuzz.
280  %end;
281  noprint;
282  %if (&i_id. ne _NONE_) %then %do;
283  id &l_id.;
284  %end;
285  run;
286  %let _sysinfo=&sysinfo.;
287  proc sql noprint;
288  update work._ergebnis
289  set l_rc=&_sysinfo.
290  where upcase (memname)="%upcase (&&memname&i.)";
291  quit;
292  %end;
293  %end;
294 
295  %if (&OpenODSDestinations. = 0) %then %do;
296  ods listing close;
297  %end;
298 
299  %*** set test result ***;
300  data work._ergebnis;
301  set work._ergebnis;
302  select (l_rc);
303  when (0)
304  Comparefailed=0;
305  when (128) do; /* COMPOBS - Comparison data set has observation not in base */
306  if ("&i_CompareCheck." = "MOREOBS" OR "&i_CompareCheck." = "MORECOLSNOBS") then do;
307  Comparefailed=0;
308  end;
309  end;
310  when (2048) do; /* COMPVAR - Comparison data set has variable not in base */
311  if ("&i_CompareCheck." = "MORECOLUMNS" OR "&i_CompareCheck." = "MORECOLSNOBS") then do;
312  Comparefailed=0;
313  end;
314  end;
315  when (2176) do; /* COMPOBS & COMPVAR */
316  if ("&i_CompareCheck." = "MORECOLSNOBS") then do;
317  Comparefailed=0;
318  end;
319  end;
320  otherwise;
321  end;
322  run;
323 
324  %*** format results for report ***;
325  data work._ergebnis;
326  length icon_column $45 i_LibraryCheck i_CompareCheck $15 i_id i_ExcludeList $80;
327  set work._ergebnis;
328  SELECT (CompareFailed);
329  WHEN (0) icon_column='<img src="ok.png" alt="OK"></img>';
330  WHEN (1) icon_column='<img src="error.png" alt="Fehler"></img>';
331  OTHERWISE icon_column='&nbsp;';
332  END;
333  i_LibraryCheck="&i_LibraryCheck.";
334  i_CompareCheck="&i_CompareCheck.";
335  i_id="&i_id.";
336  i_ExcludeList="&i_ExcludeList.";
337  run;
338 
339  %*** determine return value for test ***;
340  proc sql noprint;
341  select max (CompareFailed) into :l_rc
342  from work._ergebnis;
343  quit;
344 
345  %*** create library listing ***;
346  ods document name=testout._%substr(00&g_scnid,%length(&g_scnid))_&l_casid._&l_tstid._Library_act(WRITE);
347  proc print data=WORK._assertLibraryActual label noobs;
348  run;
349  ods document close;
350  ods document name=testout._%substr(00&g_scnid,%length(&g_scnid))_&l_casid._&l_tstid._Library_exp(WRITE);
351  proc print data=WORK._assertLibraryExpected label noobs;
352  run;
353  ods document close;
354  data testout._%substr(00&g_scnid,%length(&g_scnid))_&l_casid._&l_tstid._Library_rep;
355  set work._ergebnis;
356  run;
357 
358  proc datasets lib=work nolist memtype=(data view);
359  delete _ergebnis _assertLibraryActual _assertLibraryExpected;
360  quit;
361 
362 %Update:;
363  /* update result in test database */
364  PROC SQL NOPRINT;
365  UPDATE target.tst
366  SET tst_res = &l_rc
367  WHERE
368  tst_scnid = &g_scnid AND
369  tst_casid = &l_casid AND
370  tst_id = &l_tstid
371  ;
372  QUIT;
373 %MEND;