Whamcloud - gitweb
This commit was generated by cvs2svn to compensate for changes in r46154,
[fs/lustre-release.git] / libsysio / tests / test_rw.pl
1 #!/usr/bin/perl -w
2
3 #
4 # rw test: Write a buffer out using all the different writes, read it back
5 #          and make sure it matches
6
7 #
8
9 use IPC::Open2;
10
11 use strict;
12 use FindBin;
13 use lib "$FindBin::Bin";
14 use helper;
15
16 sub usage
17 {
18   print "Usage: ./test_rw.pl [-alpha] <file>: Write to/read from file\n";
19   exit(-1);
20 }
21
22 sub verify_result
23 {
24         my ($cmdfh, $outfh, $cmdstr, $exp_val, $eq_op) = @_;
25         my $print_err = 0;
26
27         my $res = helper::verify_cmd($cmdfh, $outfh, $cmdstr);
28         $res = oct($res);
29
30         if ($eq_op eq "!=") {
31                 if ($res != $exp_val) {
32                         print STDOUT "Error! $cmdstr returned $res insted of $exp_val\n";
33                         exit 1;
34                 }
35         } else {
36                 if ($eq_op eq ">") {
37                         if ($res > $exp_val) {
38                                 $print_err = 1;
39                         }
40                 } elsif ($eq_op eq "<")  {
41                         if ($res < $exp_val) {
42                                 $print_err = 1;
43                         }
44                 } elsif ($eq_op eq "==") {
45                         if ($res == $exp_val) {
46                                 $print_err = 1;
47                         }
48                 }
49                 if ($print_err == 1) {
50                         helper::print_and_exit($cmdfh, $outfh, 1, "Error! $cmdstr returned $res\n");
51                 }
52         }
53 }
54                 
55 sub do_iowait
56 {
57         my ($cmdfh, $outfh, $id, $rwcmd, $exp_size) = @_;
58
59         my $cmdstr = "CALL iowait $id\n";
60         helper::send_cmd($cmdfh, $outfh, "iowait", $cmdstr);
61
62         my $descstr = "iowait:$rwcmd";
63         verify_result($cmdfh, $outfh, $descstr, $exp_size, "!=");
64 }
65
66 sub set_iovecs
67 {
68         my ($cmdfh, $outfh, $callnum) = @_;
69         my $NUMVECS = 8;
70         my $VECLEN = $NUMVECS * 1024;
71
72         my $varname = "iovbuf$callnum";
73
74         # Get size of iovecs
75         my $cmdstr = '$iovsize = CALL sizeof iovec'."\n";
76         helper::send_cmd($cmdfh, $outfh, "sizeof", $cmdstr);
77         my $size = helper::verify_cmd($cmdfh, $outfh, "sizeof iovec");
78         $size = oct($size);
79         $size = $size * $NUMVECS;
80
81         # Allocate iovec buffer
82         $cmdstr = '$'."$varname = ALLOC $size\n";
83         helper::send_cmd($cmdfh, $outfh, "alloc", $cmdstr);
84         
85
86         # Now initilize all of them
87         my $off = 0;
88         for (my $i=0; $i < $NUMVECS; $i++) {
89                 $cmdstr = 'CALL init_iovec $buf '."$off $VECLEN $i ". '$'."$varname\n";
90                 helper::send_cmd($cmdfh, $outfh, "init_iovec", $cmdstr);
91                 helper::verify_cmd($cmdfh, $outfh, "init_iovec");
92                 $off += $VECLEN;
93         }
94
95         return $varname;
96 }
97
98
99 sub set_xtvecs
100 {
101         my ($cmdfh, $outfh, $callnum, $startoff) = @_;
102         my $VECLEN = 4 * 8 * 1024;
103
104         my $varname = "xtvbuf$callnum";
105
106         # Get size of iovecs
107         my $cmdstr = '$xtvsize = CALL sizeof xtvec'."\n";
108         helper::send_cmd($cmdfh, $outfh, "sizeof", $cmdstr);
109         my $size = helper::verify_cmd($cmdfh, $outfh, "sizeof xtvec");
110         $size = oct($size);
111         $size = $size * 2;
112
113         # Allocate iovec buffer
114         $cmdstr = '$'."$varname = ALLOC $size\n";
115         helper::send_cmd($cmdfh, $outfh, "alloc", $cmdstr);
116         
117
118         # Now initilize all of them
119         my $off = $startoff;
120         for (my $i=0; $i < 2; $i++) {
121                 $cmdstr = "CALL init_xtvec $off $VECLEN $i ". '$'."$varname\n";
122                 helper::send_cmd($cmdfh, $outfh, "init_xtvec", $cmdstr);
123                 helper::verify_cmd($cmdfh, $outfh, "init_xtvec");
124                 $off += $VECLEN;
125         }
126
127         return $varname;
128 }
129
130 sub check_buf
131 {
132
133         my ($cmdfh, $outfh, $bufsize, $readcmd) = @_;
134         my $i;
135         my $digit = 0;
136         my $offset = 0;
137         my $cmdstr;
138
139         for ($i =0; $i < 64; $i++) {
140                 $cmdstr = 'CALL checkbuf $buf'. " 1024 $digit $offset\n";
141                 helper::send_cmd($cmdfh, $outfh, "checkbuf", $cmdstr);
142                 my $res = helper::verify_cmd($cmdfh, $outfh, "checkbuf");
143                 $res = oct($res);
144
145                 if ($res != 0) {
146                         print STDOUT "Checkbuf returned $res\n";
147                         helper::print_and_exit($cmdfh, $outfh, 1, "$readcmd did not return all $digit 's\n");
148                 } 
149         
150                 $offset += 1024;
151                 $digit++;
152                 if ($digit == 10) {
153                         $digit = 0;
154                 }
155         }
156
157         # Now fill the buffer with 0s
158         $cmdstr = '$buf = CALL setbuf 0 '."$bufsize ".'$buf'." 0\n";
159   helper::send_cmd($cmdfh, $outfh, "setbuf", $cmdstr);
160         
161 }
162
163 sub fill_buf
164 {
165         my ($cmdfh, $outfh) = @_;
166         my $i;
167         my $digit=0;
168         my $cmdstr;
169         my $offset = 0;
170
171         # Fill up the buffer with alternating digits
172         # from 0-9
173
174         for ($i=0; $i < 64 ; $i++) {
175                 my $cmdstr = "CALL setbuf $digit 1024 ".'$buf'." $offset\n";
176                 helper::send_cmd($cmdfh, $outfh, "setbuf", $cmdstr);            
177                 $offset += 1024;
178                 $digit++;
179                 if ($digit == 10) {
180                         $digit = 0;
181                 }
182         }
183 }
184
185 sub do_rwcalls
186 {
187                 my ($cmdfh, $outfh, $bufsize) = @_;
188                 my $IOID_FAIL = 0;
189                 my $NUMVECS = 8;
190
191                 # Initilize buffer
192                 fill_buf($cmdfh, $outfh);
193
194                 # write 64K bytes at pos 0
195                 my $cmdstr = 'CALL write $fd $buf '."$bufsize\n";
196                 helper::send_cmd($cmdfh, $outfh, "write", $cmdstr);
197                 verify_result($cmdfh, $outfh, "write", $bufsize, "!=");
198
199                 # Initilize buffer
200                 fill_buf($cmdfh, $outfh);
201
202                 # iwrite 64K bytes at pos 64K
203                 $cmdstr = '$id1 = CALL iwrite $fd $buf '."$bufsize\n";
204                 helper::send_cmd($cmdfh, $outfh, "iwrite", $cmdstr);
205                 verify_result($cmdfh, $outfh, "iwrite", $IOID_FAIL, "==");
206                 do_iowait($cmdfh, $outfh, '$id1', "iwrite", $bufsize);
207                 
208                 # Set up the iovecs
209                 my $iovcnt = 0;
210                 my $iovname = set_iovecs($cmdfh, $outfh, $iovcnt);
211
212                 # Initilize buffer
213                 fill_buf($cmdfh, $outfh);
214                 
215                 # writev 64K bytes using 8 iovecs at pos 128K
216                 $cmdstr = 'CALL writev $fd $'."$iovname $NUMVECS\n";
217                 helper::send_cmd($cmdfh, $outfh, "writev", $cmdstr);
218                 verify_result($cmdfh, $outfh, "writev", $bufsize, "!=");
219
220                 # Initilize buffer
221                 fill_buf($cmdfh, $outfh);
222                 
223                 # iwritev 64K bytes using 8 iovecs at pos 192K
224                 $cmdstr = '$id2 = CALL iwritev $fd $'."$iovname $NUMVECS\n";
225                 helper::send_cmd($cmdfh, $outfh, "iwritev", $cmdstr);
226                 verify_result($cmdfh, $outfh, "iwritev", $IOID_FAIL, "==");
227                 do_iowait($cmdfh, $outfh, '$id2', "iwritev", $bufsize);
228
229                 # Initilize buffer
230                 fill_buf($cmdfh, $outfh);
231
232                 # pwrite 64K bytes starting at pos 256K
233                 my $offset = 256 * 1024;
234                 $cmdstr = 'CALL pwrite $fd $buf '."$bufsize $offset\n";
235                 helper::send_cmd($cmdfh, $outfh, "pwrite", $cmdstr);
236                 verify_result($cmdfh, $outfh, "pwrite", $bufsize, "!=");
237                 
238                 # Initilize buffer
239                 fill_buf($cmdfh, $outfh);
240
241                 # ipwrite 64K bytes starting at pos 320K
242                 $offset = 320 * 1024;
243                 $cmdstr = '$id3 = CALL ipwrite $fd $buf '."$bufsize $offset\n";
244                 helper::send_cmd($cmdfh, $outfh, "ipwrite", $cmdstr);
245                 verify_result($cmdfh, $outfh, "ipwrite", $IOID_FAIL, "==");
246                 do_iowait($cmdfh, $outfh, '$id3', "ipwrite", $bufsize);
247
248                 $iovcnt++;
249
250                 # Initilize buffer
251                 fill_buf($cmdfh, $outfh);
252
253                 # pwritev using 8 8K buffers at offset 384
254                 $offset = 384 * 1024;
255                 $cmdstr = 'CALL pwritev $fd $'."$iovname $NUMVECS $offset\n";
256                 helper::send_cmd($cmdfh, $outfh, "pwritev", $cmdstr);
257                 verify_result($cmdfh, $outfh, "pwritev", $bufsize, "!=");       
258
259                 # Initilize buffer
260                 fill_buf($cmdfh, $outfh);
261
262                 # ipwritev using 8 8k buffers at offset 448
263                 $offset = 448 * 1024;
264                 $cmdstr = '$id4 = CALL ipwritev $fd $'."$iovname $NUMVECS $offset\n";
265                 helper::send_cmd($cmdfh, $outfh, "ipwritev", $cmdstr);
266                 verify_result($cmdfh, $outfh, "ipwritev", $IOID_FAIL, "==");
267                 do_iowait($cmdfh, $outfh, '$id4', "ipwritev", $bufsize);
268
269                 # Set up the xtvecs.  Starting offset is 512K
270                 my $xtvcnt = 0;
271                 my $xtvname = set_xtvecs($cmdfh, $outfh, $xtvcnt, 512 * 1024);
272
273                 $iovcnt++;
274
275                 # Initilize buffer
276                 fill_buf($cmdfh, $outfh);
277                 
278                 # Call writex using 8 8k buffers at offset 512
279                 $cmdstr = 'CALL writex $fd $'."$iovname $NUMVECS ".'$'."$xtvname 2\n";
280                 helper::send_cmd($cmdfh, $outfh, "writex", $cmdstr);
281                 verify_result($cmdfh, $outfh, "writex", $bufsize, "!=");
282
283                 # Call iwritex using 8 8k buffers starting at offset 576
284                 # Re-setup xtvs since I am lazy.  This is leaking memory like
285                 # a seive...
286                 $xtvcnt++;
287                 $xtvname = set_xtvecs($cmdfh, $outfh, $xtvcnt, 576 * 1024);
288
289                 $iovcnt++;
290
291                 # Initilize buffer
292                 fill_buf($cmdfh, $outfh);
293
294                 $cmdstr = '$id5 = CALL iwritex $fd $'."$iovname $NUMVECS ".'$'."$xtvname 2\n";
295                 helper::send_cmd($cmdfh, $outfh, "iwritex", $cmdstr);
296                 verify_result($cmdfh, $outfh, "iwritex", $IOID_FAIL, "==");
297                 do_iowait($cmdfh, $outfh, '$id5', "iwritex", $bufsize);
298
299                 # Now do the reads
300
301                 # Lseek back to pos 0
302                 $cmdstr = 'CALL lseek $fd 0 SEEK_SET'."\n";
303                 helper::send_cmd($cmdfh, $outfh, "sizeof", $cmdstr);
304                 helper::verify_cmd($cmdfh, $outfh, "sizeof xtvec");
305
306                 # fill the buffer with 0's
307                 $cmdstr = '$buf = CALL setbuf 0 '."$bufsize ".'$buf'." 0\n";
308                 helper::send_cmd($cmdfh, $outfh, "setbuf", $cmdstr);
309
310                 # read 64K bytes from pos 0
311                 $cmdstr = 'CALL read $fd $buf '."$bufsize\n";
312                 helper::send_cmd($cmdfh, $outfh, "read", $cmdstr);
313                 verify_result($cmdfh, $outfh, "read", $bufsize, "!=");
314
315                 # Check the buffer to make sure it matches
316                 check_buf($cmdfh, $outfh, $bufsize, "read");
317
318                 # iread 64K bytes at pos 64K
319                 $cmdstr = '$id6 = CALL iread $fd $buf '."$bufsize\n";
320                 helper::send_cmd($cmdfh, $outfh, "iread", $cmdstr);
321                 verify_result($cmdfh, $outfh, "iread", $IOID_FAIL, "==");
322                 do_iowait($cmdfh, $outfh, '$id6', "iread", $bufsize);
323                 check_buf($cmdfh, $outfh, $bufsize, "iread");
324
325                 $iovcnt++;
326
327                 # readv 64K bytes using 8 iovecs at pos 128K
328                 $cmdstr = 'CALL readv $fd $'."$iovname $NUMVECS\n";
329                 helper::send_cmd($cmdfh, $outfh, "readv", $cmdstr);
330                 verify_result($cmdfh, $outfh, "readv", $bufsize, "!=");
331                 check_buf($cmdfh, $outfh, $bufsize, "readv");           
332
333                 # ireadv 64K bytes using 8 iovecs at pos 192K
334                 $cmdstr = '$id7 = CALL ireadv $fd $'."$iovname $NUMVECS\n";
335                 helper::send_cmd($cmdfh, $outfh, "ireadv", $cmdstr);
336                 verify_result($cmdfh, $outfh, "ireadv", $IOID_FAIL, "==");
337                 do_iowait($cmdfh, $outfh, '$id7', "ireadv", $bufsize);
338                 check_buf($cmdfh, $outfh, $bufsize, "ireadv");
339
340                 # pread64K bytes starting at pos 256K
341                 $offset = 256 * 1024;
342                 $cmdstr = 'CALL pread $fd $buf '."$bufsize $offset\n";
343                 helper::send_cmd($cmdfh, $outfh, "pread", $cmdstr);
344                 verify_result($cmdfh, $outfh, "pread", $bufsize, "!=");
345                 check_buf($cmdfh, $outfh, $bufsize, "pread");
346                 
347                 # ipread 64K bytes starting at pos 320K
348                 $offset = 320 * 1024;
349                 $cmdstr = '$id8 = CALL ipread $fd $buf '."$bufsize $offset\n";
350                 helper::send_cmd($cmdfh, $outfh, "ipread", $cmdstr);
351                 verify_result($cmdfh, $outfh, "ipread", $IOID_FAIL, "==");
352                 do_iowait($cmdfh, $outfh, '$id8', "ipread", $bufsize);
353                 check_buf($cmdfh, $outfh, $bufsize, "ipread");
354
355
356                 $iovcnt++;
357
358                 # preadv using 8 8K buffers at offset 384
359                 $offset = 384 * 1024;
360                 $cmdstr = 'CALL preadv $fd $'."$iovname $NUMVECS $offset\n";
361                 helper::send_cmd($cmdfh, $outfh, "preadv", $cmdstr);
362                 verify_result($cmdfh, $outfh, "preadv", $bufsize, "!=");        
363                 check_buf($cmdfh, $outfh, $bufsize, "preadv");
364                 
365                 # ipreadv using 8 8k buffers at offset 448
366                 $offset = 448 * 1024;
367                 $cmdstr = '$id9 = CALL ipreadv $fd $'."$iovname $NUMVECS $offset\n";
368                 helper::send_cmd($cmdfh, $outfh, "ipreadv", $cmdstr);
369                 verify_result($cmdfh, $outfh, "ipreadv", $IOID_FAIL, "==");
370                 do_iowait($cmdfh, $outfh, '$id9', "ipreadv", $bufsize);
371                 check_buf($cmdfh, $outfh, $bufsize, "ipreadv");
372
373                 # Set up the xtvecs.  Starting offset is 512K
374                 $xtvcnt++;
375                 $xtvname = set_xtvecs($cmdfh, $outfh, $xtvcnt, 512 * 1024);
376
377                 $iovcnt++;
378                 
379                 # Call readx using 8 8k buffers at offset 512
380                 $cmdstr = 'CALL readx $fd $'."$iovname $NUMVECS ".'$'."$xtvname 2\n";
381                 helper::send_cmd($cmdfh, $outfh, "readx", $cmdstr);
382                 verify_result($cmdfh, $outfh, "readx", $bufsize, "!=");
383                 check_buf($cmdfh, $outfh, $bufsize, "readx");
384
385                 # Call ireadx using 8 8k buffers starting at offset 576
386                 # Re-setup xtvs since I am lazy.  This is leaking memory like
387                 # a seive...
388                 $xtvcnt++;
389                 $xtvname = set_xtvecs($cmdfh, $outfh, $xtvcnt, 576 * 1024);
390
391                 $iovcnt++;
392
393                 $cmdstr = '$id10 = CALL ireadx $fd $'."$iovname $NUMVECS ".'$'."$xtvname 2\n";
394                 helper::send_cmd($cmdfh, $outfh, "ireadx", $cmdstr);
395                 verify_result($cmdfh, $outfh, "ireadx", $IOID_FAIL, "==");
396                 do_iowait($cmdfh, $outfh, '$id10', "ireadx", $bufsize);
397                 check_buf($cmdfh, $outfh, $bufsize, "ireadx");
398 }
399
400
401 sub check_array
402 {
403         my ($exp_digit, @arr) = @_;
404         my $exp_char;
405         my $pos = 0;
406
407         if ($exp_digit == 0) {
408                 $exp_char = "\\0";
409         } elsif ($exp_digit < 7) {
410                 $exp_char = "00".$exp_digit;
411         } elsif ($exp_digit == 7) {
412                 $exp_char = "\\a";
413         } elsif ($exp_digit == 8) {
414                 $exp_char = "\\b";
415         } elsif ($exp_digit == 9) {
416                 $exp_char = "\\t";
417         } else {
418                 print STDERR "Invalid expected digit $exp_digit\n";
419                 return(1);
420         }
421
422         foreach my $str (@arr) {
423                 if ($str ne $exp_char) {
424                         print STDERR "At pos $pos got digit $str instead of $exp_char\n";
425                         return(1);
426                 }
427                 $pos++;
428         }
429
430         return(0);
431 }
432
433 # Perform an od on the output and verify that the output makes
434 # sense
435 sub od_verify
436 {
437         my ($cmdfh, $outfh, $file) = @_;
438         my $exp_digit = 0;
439
440         # Do an od in order to verify the contents of the file
441         system("od -c $file > tmp.out.$$");
442         open(ODFILE, "<tmp.out.$$") || 
443                         helper::print_and_exit($cmdfh, $outfh, 1, "Unable to open tmp.out.$$\n");
444
445         while (<ODFILE>) {
446                 if (/^\*/) {
447                         # Do nothing...
448                 } else {
449                         my ($lineno, @nums) = split($_);
450                         if (check_array($exp_digit, @nums) != 0) {
451                                 helper::print_and_exit($cmdfh, $outfh, 1, "At line $lineno, got unexpected result\n");
452                         }
453                         if ($exp_digit < 9) {
454                                 $exp_digit ++;
455                         } else {
456                                 $exp_digit = 0;
457                         }
458                 }
459         }
460
461         close(ODFILE);
462         system("rm -f tmp.out.$$");
463 }
464
465 sub process_cmd
466 {
467   my ($file, $is_alpha) = @_;
468   
469   # Get tests directory
470   my $testdir = $FindBin::Bin;
471         my $bufsize = 65536;
472
473   eval {
474       if ($is_alpha == 0) {
475                                         open2(\*OUTFILE, \*CMDFILE, "$testdir/test_driver --np");
476       } else {
477                                         open2(\*OUTFILE, \*CMDFILE, "yod -quiet -sz 1 $testdir/test_driver --np");
478       }
479   };
480
481   if ($@) {
482     if ($@ =~ /^open2/) {
483       warn "open2 failed: $!\n$@\n";
484       return;
485     }
486     die;
487
488   }
489
490   my $outfh = \*OUTFILE;
491   my $cmdfh = \*CMDFILE;
492
493   if ($is_alpha == 0) {
494     helper::send_cmd($cmdfh, $outfh, "init", "CALL init\n");
495   }
496   
497   # Open file
498   my $cmdstr = '$fd = CALL open '."$file O_RDWR|O_CREAT 0777\n";
499   helper::send_cmd($cmdfh, $outfh, "open", $cmdstr);
500         helper::verify_cmd($cmdfh, $outfh, $cmdstr);
501
502    
503   # Allocate buffer
504   $cmdstr = '$buf = ALLOC '."$bufsize\n";
505   helper::send_cmd($cmdfh, $outfh, "ALLOC", $cmdstr);
506
507
508         do_rwcalls($cmdfh, $outfh, $bufsize);
509
510   # Clean up
511   $cmdstr = 'CALL close $fd'."\n";
512   helper::send_cmd($cmdfh, $outfh, "close", $cmdstr);
513
514         # Verify it worked
515         od_verify($cmdfh, $outfh, $file);
516
517         system("rm -f $file");
518   helper::print_and_exit($cmdfh, $outfh, 0, "rw test successful\n");
519 }
520
521 my $currarg = 0;
522 my $is_alpha = 0;
523
524 if (@ARGV < 1) {
525   usage;
526 } elsif (@ARGV > 1 ) {
527   if ($ARGV[$currarg++] eq "-alpha") {
528     $is_alpha = 1;
529   }
530 }
531
532 my $file = $ARGV[$currarg];
533
534 process_cmd($file, $is_alpha);
535
536
537 exit 0;