ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/COMP/SCRAM/src/Utilities/TestClass.pm
Revision: 1.13
Committed: Fri Sep 29 06:42:03 2000 UTC (24 years, 7 months ago) by williamc
Content type: text/plain
Branch: MAIN
CVS Tags: v102p1, V1_0_1, V1_0_0, V1_pre0, SCRAM_V1, SCRAMV1_IMPORT, V0_19_7, V0_19_6, V0_19_6p1, V0_19_5, SFATEST, V0_19_4, V0_19_4_pre3, V0_19_4_pre2, V0_19_4_pre1, V0_19_3, V0_19_2, V0_19_1, V0_19_0, V0_18_5, V0_18_4, V_18_3_TEST, VO_18_3, V0_18_2, V0_18_1
Branch point for: V1_pre1, SCRAM_V1_BRANCH, V0_19_4_B
Changes since 1.12: +6 -1 lines
Log Message:
add testswitch method

File Contents

# Content
1 #
2 # Test a documented perl class
3 #
4 # Interface
5 # ---------
6 # new($module,testdatadir) : module example - Utilities/urlhandler
7 # dotest(@args) : Start testing - arguments dependent on inheriting class
8 #
9 # cmpstring(expectedstring,returnedstring) : cmp a string and fail if not equal
10 # newtest() : Initiate a testing sequence
11 # verify(actual_result_file, expected_result_file) : compare two files
12 # verifydir(dir) : Check existence of the directory
13 # verifyexists(file) : Verify the existence of file
14 # datadir([dir]) : return the current data directory (set it to dir if supplied)
15 # testswitch(int,"0 text"," non 0 text") : testpass or fail according to bool
16 # testfail(string) : report that current test has failed
17 # testpass(string) : report that current test has passed
18 # newfilename() : return a new filename that can be opened etc.
19 # temparea() : return a directory for building temporary stuff
20 # newobject(@args) : Set up a new object to be tested
21 # testinterface($name,@args) : perform interface tests for $name with @args
22 # expect(string) : tell the testinterface of any expected return values
23 # clearexpect() : Reset any expect variables.
24 #cleantemp() : delete the temporary area
25 # cmparray(arrayref, @reqvals) : test the arrayref against expected
26 # cmpstring(expectedstring,actualstring) :
27
28 package Utilities::TestClass;
29 require 5.004;
30 $bold = "\033[1m";
31 $normal = "\033[0m";
32
33 # -------------------- Front line Interface methods ---------------------
34 sub new {
35 my $class=shift;
36 my $fullmodule=shift;
37 chomp $fullmodule;
38 my $datadir=shift;
39
40 # The usual Object blessing
41 $self={};
42 bless $self,$class;
43
44 #some local working variables
45 my $testmodule;
46 my $module;
47 my $dir="";
48 # if ( $fullmodule=~/\// ) {
49 # ($dir=$fullmodule)=~s/(.*\/)(.*)/$1/;
50 # }
51 if ( $fullmodule=~/::/ ) {
52 ($dir=$fullmodule)=~s/(.*::)(.*)/$1/;
53 }
54 else { $dir="" }
55 ($testmodule=$fullmodule)=~s/(.*\/)(.*)/$1test::test_$2/;
56 ($testmodule=$fullmodule)=~s/${dir}(.*)/${dir}test::test_$1/;
57 ($module=$testmodule)=~s/.*\///g;
58
59 $self->{class}=$module;
60 $self->{"datadir"}=$datadir;
61 $self->{filenumber}=0;
62 rmtree("/tmp/SCRAMtest++");
63 $self->{temparea}="/tmp/SCRAMtest++";
64 use File::Path;
65 mkpath ($self->{temparea},0, 0777);
66
67 # Now setup a new testobject of the appropriate type
68 eval "require $testmodule";
69 die $@ if $@;
70 $self->{testobj}=$module->_new($self, $fullmodule);
71
72 # make sure the temparea is cleaned
73 use File::Path;
74
75 return $self;
76 }
77
78 #
79 # Call the test routine of our inheriting class
80 #
81 sub dotest {
82 $self=shift;
83 $self->{testobj}->test(@_);
84 $self->{testobj}->checktests();
85 }
86
87 sub cmparray {
88 my $self=shift;
89 my $array=shift;
90 my @vals=@_;
91
92 if ( $#{$array} ne $#vals) { $self->testfail(
93 $#{$array}." items retuned, $#vals expected");
94 }
95 else {
96 for( my $i=0; $i<= $#{$array}; $i++) {
97 $self->cmpstring($vals[$i],$$array[$i]);
98 }
99 }
100 }
101
102
103 sub cmpstring {
104 my $self=shift;
105 my $s1=shift;
106 my $s2=shift;
107
108 if ( ! defined $s2) {
109 if ( ( ! defined $s1 ) || ( $s1==undef )) {
110 $self->testpass("Got undefined as expected");
111 }
112 else {
113 $self->testfail("Return string is undefined expecting $s1"),
114 }
115 }
116 elsif ( $s1 ne $s2 ) {
117 $self->testfail("Expecting $s1 got $s2");
118 }
119 else {
120 $self->testpass("Got $s2 as expected");
121 }
122 }
123
124 # A virtual method to be overridden
125 sub init {
126 my $self=shift;
127 }
128
129 #
130 # initiate a new test sequence
131 #
132 sub newtest {
133 my $self=shift;
134 my $string=shift;
135 $self->{testnumber}++;
136 $self->_testout("");
137 $self->_testout("---------------------------* Test $self->{testnumber}".
138 " *------------------------------");
139 $self->_testout("| $string ");
140 $self->_testout("|");
141 $self->_testout(
142 "---------------------------------------------------------------");
143
144 }
145
146 sub verify {
147 my $self=shift;
148 my $file1=shift;
149 my $file2=shift;
150 my $same=1;
151
152 $self->_testout(">Verifying files : $file1 \n".
153 " $file2");
154 open ( FILE1, "<$file1" ) or die "Cannot Read Test Output $file1 $!\n";
155 open ( FILE2, "<$file2" ) or die "Cannot Read Benchmark file ".
156 "$file2 $!\n";
157 while ( $f1=<FILE2> ) {
158 $f2=<FILE1>;
159 if ( (!defined $f2 ) || ( ! defined $f1) || ($f2 ne $f1 )) {
160 #print "T:\n$f1\nB:$f2\n";
161 $same=0;
162 }
163 }
164 close FILE1;
165 close FILE2;
166 if ( $same==0 ) {
167 $self->testfail("File $file1 is not the same as $file2");
168 }
169 }
170
171 sub verifydir {
172 my $self=shift;
173 my $name=shift;
174
175 if ( -d "$name" ) {
176 $self->testpass("Directory $name exists - test passed");
177 }
178 else {
179 $self->testfail("Directory $name does not exist");
180 }
181 }
182
183 sub verifyexists {
184 my $self=shift;
185 my $name=shift;
186
187 if ( -e "$name" ) {
188 $self->testpass("$name exists - test passed");
189 }
190 else {
191 $self->testfail("$name does not exist");
192 }
193 }
194
195 sub testswitch {
196 my $self=shift;
197 my $bool=shift;
198 my $string1=shift;
199 my $string2=shift;
200
201 if ( ! $bool ) {
202 $self->testpass($string1);
203 }
204 else {
205 $self->testfail($string2);
206 }
207 }
208
209 sub testfail {
210 my $self=shift;
211 my $string=shift;
212
213 $self->_testout("$bold $string $normal");
214 push @{$self->{failedtests}}, $self->{testnumber};
215 }
216
217 sub testpass {
218 my $self=shift;
219 my $string=shift;
220
221 $self->_testout($string);
222 }
223
224 sub newfilename {
225 my $self=shift;
226 $self->{filenumber}++;
227 return "temptest_$self->{filenumber}";
228 }
229
230 sub temparea {
231 my $self=shift;
232 return $self->{temparea};
233 }
234
235 #
236 # return the data directory ( and set if given an argument )
237 #
238 sub datadir {
239 my $self=shift;
240 my $dir=shift;
241 if ( $dir ne "" ) {
242 $self->{datadir}=$dir;
243 }
244 return $self->{datadir};
245 }
246
247 #
248 # -------------------- Private Methods ----------------------------
249 # (only to be used by the inheriting class)
250
251 #
252 # A basic new method for inheriting classes
253 #
254
255 sub _new {
256 my $class=shift;
257 my $testobject=shift;
258 my $module=shift;
259
260
261 # Bless this object and all those who inherit from her
262 my $self={};
263 bless $self, $class;
264
265 # we want the dat members from the initialisation of our class in
266 # here too
267 foreach $key ( keys %$testobject ) {
268 $self->{$key}=$testobject->{$key};
269 }
270
271 print "Initialising $class\n";
272
273 # Data Initialisation
274 $self->{testclass}=$class;
275 ($self->{classname}=$module)=~s/::/\//g;
276 ($self->{class}=$module)=~s/.*\///g;
277 $self->{classfile}=$ENV{SCRAM_HOME}."/src/".$self->{classname}."\.pm";
278 $self->init(@_);
279 $self->analyseInterface();
280 delete $self->{expect};
281 return $self;
282 }
283
284 #
285 # Test the interface
286 #
287 sub testinterface {
288 my $self=shift;
289 my $subname=shift;
290 my $myreturn;
291 my $expected;
292
293 $self->_checkdoc($subname);
294 $self->{inttest}{$subname}++;
295 $self->_testout(">Trying interface $subname ");
296 my $args=join ', ', @_;
297 $self->_testout( " (".$args.")" );
298 $num=0;
299 if ( exists $self->{expect} ) {
300 print "Testing Expected Values against actual returns ....\n";
301 @mylist=eval { $self->{object}->$subname(@_); };
302 die "Test Failed $@\n" if $@;
303 my $nrv=$#mylist+1; my $nrve=$#{$self->{expect}}+1;
304 print $nrv." values returned ".$nrve." expected\n";
305 if ( $nrv != $nrve ) {
306 $self->testfail("Number of returned values != that expected");
307 }
308 if ( defined @mylist ) {
309 # size check
310 if ( $#mylist != $#{$self->{expect}} ) {
311 $self->testfail("Number of returned values inconsistent");
312 }
313 foreach $myreturn ( @mylist ) {
314 if ( ! defined $myreturn ) {
315 print "Undefined Value Passed Back\n";
316 }
317 elsif ( $myreturn=~/HASH/ ) {
318 print "Hash Ref ".ref($myreturn)." returned\n";
319 }
320 elsif ( $myreturn=~/CODE/ ) {
321 print "Code Ref returned\n";
322 }
323 elsif ( $myreturn=~/ARRAY/ ) {
324 print "Array Ref returned\n";
325 }
326 else {
327 $expected=$self->{expect}[$num++];
328 if ( $myreturn eq $expected ) { #simple return case
329 $self->testpass("OK - returned as expected ($expected)");
330 }
331 else {
332 $self->testfail("Expecting $expected, got ".
333 $myreturn);
334 }
335 }
336 } # end foreach block
337 }
338 return @mylist;
339 }
340 else {
341 return ($self->{object}->$subname(@_));
342 }
343 }
344
345 #
346 # expect - tell testinterface what returns to expect and fail/pass
347 #
348 sub expect {
349 my $self=shift;
350
351 push @{$self->{expect}}, @_;
352 }
353
354 sub clearexpect {
355 my $self=shift;
356 my $string=shift;
357
358 delete $self->{expect};
359 }
360
361 #
362 # checktests
363 #
364 sub checktests {
365 my $self=shift;
366 $self->newtest(">Checking all documented Interfaces have been tested ");
367 foreach $key ( keys %{$self->{interfaceargs}} ) {
368 if ( ! exists $self->{inttest}{$key} ) {
369 $self->testfail ("$key has not been tested");
370 }
371 }
372 # Now see whats failed
373 foreach $fail ( @{$self->{failedtests}} ) {
374 $self->_testout("$bold Failed in $fail $normal");
375 }
376 }
377
378 #
379 # Create a new object
380 #
381 sub newobject {
382 my $self=shift;
383
384 $self->_checkdoc("new");
385 $self->_testout(">Creating new Object $self->{class}");
386 $self->{object}=$self->{class}->new(@_);
387 $self->_testout(" ( $self->{object} )");
388 $self->{inttest}{"new"}++;
389 }
390
391 #
392 # check if interface has been documented
393 #
394 sub _checkdoc {
395 my $self=shift;
396 my $name=shift;
397
398 if ( exists $self->{interfaceargs}{$name} ) {
399 }
400 else {
401 $self->_testout
402 ("Tester: Interface Method '$name' is not documented\n");
403 }
404 }
405
406 #
407 # Output messages to screen/logs etc
408 #
409 sub _testout($) {
410 my $self=shift;
411 my $string=shift;
412
413 print $string;
414 print "\n";
415 }
416 #
417 # Method to read the interface documentation
418 #
419
420 sub analyseInterface {
421 my $self=shift;
422 my $intregion=0;
423
424 open ( SRCIN, $self->{"classfile"} )
425 or die "Unable to open $classfile $!\n";
426 while ( <SRCIN> ) {
427 if ( $_=~/#\s*Interface/g ) {
428 $intregion=1;
429 next;
430 }
431 if ( $intregion ) { # if we are in the interface documentation
432 if ( ( $_!~/^#/ ) || ( $_=~/^#\s?-{40}/ ) ) { #moving out of Int doc
433 $intregion=0;
434 next;
435 }
436 if ( $_=~/^#\s*(.*)\((.*)\)?:(.*)/ ) {
437 $interface=$1;
438 $args=$2;
439 $rest=$3;
440 next if ($interface eq "");
441 push @{$self->{'interfaces'}},$interface;
442 $self->{interfaceargs}{$interface}=$args;
443 print " Documented Interface $interface\n";
444 }
445 }
446 }
447 close SRCIN;
448 }
449
450 sub cleantemp {
451 my $self=shift;
452 use File::Path;
453 rmtree($self->temparea());
454 }