]> git.ipfire.org Git - thirdparty/cups.git/blame - cups/testfile.c
Merge changes from CUPS 1.4svn-r8639.
[thirdparty/cups.git] / cups / testfile.c
CommitLineData
ef416fc2 1/*
b19ccc9e 2 * "$Id: testfile.c 7720 2008-07-11 22:46:21Z mike $"
ef416fc2 3 *
4 * File test program for the Common UNIX Printing System (CUPS).
5 *
ae71f5de 6 * Copyright 2007-2008 by Apple Inc.
b86bc4cf 7 * Copyright 1997-2007 by Easy Software Products.
ef416fc2 8 *
9 * These coded instructions, statements, and computer programs are the
bc44d920 10 * property of Apple Inc. and are protected by Federal copyright
11 * law. Distribution and use rights are outlined in the file "LICENSE.txt"
12 * which should have been included with this file. If this file is
13 * file is missing or damaged, see the license at "http://www.cups.org/".
ef416fc2 14 *
15 * This file is subject to the Apple OS-Developed Software exception.
16 *
17 * Contents:
18 *
c277e2f8 19 * main() - Main entry.
c9fc04c6 20 * count_lines() - Count the number of lines in a file.
7a14d768 21 * random_tests() - Do random access tests.
c277e2f8 22 * read_write_tests() - Perform read/write tests.
ef416fc2 23 */
24
25/*
26 * Include necessary headers...
27 */
28
29#include <stdio.h>
30#include <stdlib.h>
31#include <errno.h>
32#include <time.h>
33#include "string.h"
34#include "file.h"
35#include "debug.h"
b423cd4c 36#ifdef HAVE_LIBZ
37# include <zlib.h>
38#endif /* HAVE_LIBZ */
536bc2c6
MS
39#ifdef WIN32
40# include <io.h>
41#else
42# include <unistd.h>
43#endif /* WIN32 */
ae71f5de 44#include <fcntl.h>
ef416fc2 45
46
47/*
48 * Local functions...
49 */
50
c9fc04c6 51static int count_lines(cups_file_t *fp);
634763e8 52static int random_tests(void);
ef416fc2 53static int read_write_tests(int compression);
54
55
56/*
57 * 'main()' - Main entry.
58 */
59
60int /* O - Exit status */
61main(int argc, /* I - Number of command-line arguments */
62 char *argv[]) /* I - Command-line arguments */
63{
ae71f5de
MS
64 int status; /* Exit status */
65 char filename[1024]; /* Filename buffer */
c9fc04c6 66 cups_file_t *fp; /* File pointer */
ae71f5de
MS
67 int fds[2]; /* Open file descriptors */
68 cups_file_t *fdfile; /* File opened with cupsFileOpenFd() */
c9fc04c6 69 int count; /* Number of lines in file */
ef416fc2 70
71
fa73b229 72 if (argc == 1)
73 {
74 /*
75 * Do uncompressed file tests...
76 */
ef416fc2 77
fa73b229 78 status = read_write_tests(0);
ef416fc2 79
80#ifdef HAVE_LIBZ
fa73b229 81 /*
82 * Do compressed file tests...
83 */
ef416fc2 84
fa73b229 85 putchar('\n');
ef416fc2 86
fa73b229 87 status += read_write_tests(1);
ef416fc2 88#endif /* HAVE_LIBZ */
89
634763e8
MS
90 /*
91 * Do uncompressed random I/O tests...
92 */
93
1f0275e3 94 status += random_tests();
634763e8 95
ae71f5de
MS
96 /*
97 * Test fdopen and close without reading...
98 */
99
100 pipe(fds);
101 close(fds[1]);
102
634763e8 103 fputs("\ncupsFileOpenFd(fd, \"r\"): ", stdout);
ae71f5de
MS
104 fflush(stdout);
105
106 if ((fdfile = cupsFileOpenFd(fds[0], "r")) == NULL)
107 {
108 puts("FAIL");
109 status ++;
110 }
111 else
112 {
113 /*
114 * Able to open file, now close without reading. If we don't return
115 * before the alarm fires, that is a failure and we will crash on the
116 * alarm signal...
117 */
118
119 puts("PASS");
120 fputs("cupsFileClose(no read): ", stdout);
121 fflush(stdout);
122
123 alarm(5);
124 cupsFileClose(fdfile);
125 alarm(0);
126
127 puts("PASS");
128 }
129
c9fc04c6
MS
130 /*
131 * Count lines in euc-jp.txt, rewind, then count again.
132 */
133
134 fputs("\ncupsFileOpen(\"../data/euc-jp.txt\", \"r\"): ", stdout);
135
136 if ((fp = cupsFileOpen("../data/euc-jp.txt", "r")) == NULL)
137 {
138 puts("FAIL");
139 status ++;
140 }
141 else
142 {
143 puts("PASS");
144 fputs("cupsFileGets: ", stdout);
145
146 if ((count = count_lines(fp)) != 15184)
147 {
148 printf("FAIL (got %d lines, expected 15184)\n", count);
149 status ++;
150 }
151 else
152 {
153 puts("PASS");
154 fputs("cupsFileRewind: ", stdout);
155
156 if (cupsFileRewind(fp) != 0)
157 {
158 puts("FAIL");
159 status ++;
160 }
161 else
162 {
163 puts("PASS");
164 fputs("cupsFileGets: ", stdout);
165
166 if ((count = count_lines(fp)) != 15184)
167 {
168 printf("FAIL (got %d lines, expected 15184)\n", count);
169 status ++;
170 }
171 else
172 puts("PASS");
173 }
174 }
175
176 cupsFileClose(fp);
177 }
178
fa73b229 179 /*
180 * Test path functions...
181 */
182
634763e8 183 fputs("\ncupsFileFind: ", stdout);
b86bc4cf 184#ifdef WIN32
185 if (cupsFileFind("notepad.exe", "C:/WINDOWS", 1, filename, sizeof(filename)) &&
186 cupsFileFind("notepad.exe", "C:/WINDOWS;C:/WINDOWS/SYSTEM32", 1, filename, sizeof(filename)))
187#else
4400e98d 188 if (cupsFileFind("cat", "/bin", 1, filename, sizeof(filename)) &&
189 cupsFileFind("cat", "/bin:/usr/bin", 1, filename, sizeof(filename)))
b86bc4cf 190#endif /* WIN32 */
fa73b229 191 printf("PASS (%s)\n", filename);
192 else
193 {
194 puts("FAIL");
195 status ++;
196 }
ef416fc2 197
fa73b229 198 /*
199 * Summarize the results and return...
200 */
201
202 if (!status)
203 puts("\nALL TESTS PASSED!");
204 else
205 printf("\n%d TEST(S) FAILED!\n", status);
206 }
ef416fc2 207 else
fa73b229 208 {
209 /*
210 * Cat the filename on the command-line...
211 */
212
fa73b229 213 char line[1024]; /* Line from file */
214
fa73b229 215 if ((fp = cupsFileOpen(argv[1], "r")) == NULL)
216 {
217 perror(argv[1]);
218 status = 1;
219 }
220 else
221 {
222 status = 0;
223
224 while (cupsFileGets(fp, line, sizeof(line)))
225 puts(line);
226
227 if (!cupsFileEOF(fp))
228 perror(argv[1]);
229
230 cupsFileClose(fp);
231 }
232 }
ef416fc2 233
234 return (status);
235}
236
237
c9fc04c6
MS
238/*
239 * 'count_lines()' - Count the number of lines in a file.
240 */
241
242static int /* O - Number of lines */
243count_lines(cups_file_t *fp) /* I - File to read from */
244{
245 int count; /* Number of lines */
246 char line[1024]; /* Line buffer */
247
248
249 for (count = 0; cupsFileGets(fp, line, sizeof(line)); count ++);
250
251 return (count);
252}
253
254
634763e8
MS
255/*
256 * 'random_tests()' - Do random access tests.
257 */
258
259static int /* O - Status */
260random_tests(void)
261{
262 int status, /* Status of tests */
263 pass, /* Current pass */
264 count, /* Number of records read */
265 record, /* Current record */
266 num_records; /* Number of records */
267 ssize_t pos, /* Position in file */
268 expected; /* Expected position in file */
269 cups_file_t *fp; /* File */
270 char buffer[512]; /* Data buffer */
271
272
273 /*
274 * Run 4 passes, each time appending to a data file and then reopening the
275 * file for reading to validate random records in the file.
276 */
277
278 for (status = 0, pass = 0; pass < 4; pass ++)
279 {
280 /*
281 * cupsFileOpen(append)
282 */
283
284 printf("\ncupsFileOpen(append %d): ", pass);
285
286 if ((fp = cupsFileOpen("testfile.dat", "a")) == NULL)
287 {
288 printf("FAIL (%s)\n", strerror(errno));
289 status ++;
290 break;
291 }
292 else
293 puts("PASS");
294
295 /*
296 * cupsFileTell()
297 */
298
299 expected = 256 * sizeof(buffer) * pass;
300
301 fputs("cupsFileTell(): ", stdout);
302 if ((pos = cupsFileTell(fp)) != expected)
303 {
304 printf("FAIL (" CUPS_LLFMT " instead of " CUPS_LLFMT ")\n",
305 CUPS_LLCAST pos, CUPS_LLCAST expected);
306 status ++;
307 break;
308 }
309 else
310 puts("PASS");
311
312 /*
313 * cupsFileWrite()
314 */
315
316 fputs("cupsFileWrite(256 512-byte records): ", stdout);
317 for (record = 0; record < 256; record ++)
318 {
319 memset(buffer, record, sizeof(buffer));
320 if (cupsFileWrite(fp, buffer, sizeof(buffer)) < sizeof(buffer))
321 break;
322 }
323
324 if (record < 256)
325 {
326 printf("FAIL (%d: %s)\n", record, strerror(errno));
327 status ++;
328 break;
329 }
330 else
331 puts("PASS");
332
333 /*
334 * cupsFileTell()
335 */
336
337 expected += 256 * sizeof(buffer);
338
339 fputs("cupsFileTell(): ", stdout);
340 if ((pos = cupsFileTell(fp)) != expected)
341 {
342 printf("FAIL (" CUPS_LLFMT " instead of " CUPS_LLFMT ")\n",
343 CUPS_LLCAST pos, CUPS_LLCAST expected);
344 status ++;
345 break;
346 }
347 else
348 puts("PASS");
349
350 cupsFileClose(fp);
351
352 /*
353 * cupsFileOpen(read)
354 */
355
356 printf("\ncupsFileOpen(read %d): ", pass);
357
358 if ((fp = cupsFileOpen("testfile.dat", "r")) == NULL)
359 {
360 printf("FAIL (%s)\n", strerror(errno));
361 status ++;
362 break;
363 }
364 else
365 puts("PASS");
366
367 /*
368 * cupsFileSeek, cupsFileRead
369 */
370
371 fputs("cupsFileSeek(), cupsFileRead(): ", stdout);
372
373 for (num_records = (pass + 1) * 256, count = (pass + 1) * 256,
374 record = rand() % num_records;
375 count > 0;
376 count --, record = (record + (rand() & 31) - 16 + num_records) %
377 num_records)
378 {
379 /*
380 * The last record is always the first...
381 */
382
383 if (count == 1)
384 record = 0;
385
386 /*
387 * Try reading the data for the specified record, and validate the
388 * contents...
389 */
390
391 expected = sizeof(buffer) * record;
392
393 if ((pos = cupsFileSeek(fp, expected)) != expected)
394 {
395 printf("FAIL (" CUPS_LLFMT " instead of " CUPS_LLFMT ")\n",
396 CUPS_LLCAST pos, CUPS_LLCAST expected);
397 status ++;
398 break;
399 }
400 else
401 {
402 if (cupsFileRead(fp, buffer, sizeof(buffer)) != sizeof(buffer))
403 {
404 printf("FAIL (%s)\n", strerror(errno));
405 status ++;
406 break;
407 }
408 else if ((buffer[0] & 255) != (record & 255) ||
409 memcmp(buffer, buffer + 1, sizeof(buffer) - 1))
410 {
411 printf("FAIL (Bad Data - %d instead of %d)\n", buffer[0] & 255,
412 record & 255);
413 status ++;
414 break;
415 }
416 }
417 }
418
419 if (count == 0)
420 puts("PASS");
421
422 cupsFileClose(fp);
423 }
424
425 /*
426 * Remove the test file...
427 */
428
429 unlink("testfile.dat");
430
431 /*
432 * Return the test status...
433 */
434
435 return (status);
436}
437
438
ef416fc2 439/*
440 * 'read_write_tests()' - Perform read/write tests.
441 */
442
443static int /* O - Status */
444read_write_tests(int compression) /* I - Use compression? */
445{
446 int i; /* Looping var */
634763e8 447 cups_file_t *fp; /* File */
ef416fc2 448 int status; /* Exit status */
449 char line[1024], /* Line from file */
450 *value; /* Directive value from line */
451 int linenum; /* Line number */
452 unsigned char readbuf[8192], /* Read buffer */
453 writebuf[8192]; /* Write buffer */
454 int byte; /* Byte from file */
634763e8 455 off_t length; /* Length of file */
c277e2f8
MS
456 static const char *partial_line = "partial line";
457 /* Partial line */
ef416fc2 458
459
460 /*
461 * No errors so far...
462 */
463
464 status = 0;
465
466 /*
467 * Initialize the write buffer with random data...
468 */
469
b86bc4cf 470#ifdef WIN32
471 srand((unsigned)time(NULL));
472#else
ef416fc2 473 srand(time(NULL));
b86bc4cf 474#endif /* WIN32 */
475
ef416fc2 476 for (i = 0; i < (int)sizeof(writebuf); i ++)
477 writebuf[i] = rand();
478
479 /*
480 * cupsFileOpen(write)
481 */
482
483 printf("cupsFileOpen(write%s): ", compression ? " compressed" : "");
484
485 fp = cupsFileOpen(compression ? "testfile.dat.gz" : "testfile.dat",
486 compression ? "w9" : "w");
487 if (fp)
488 {
489 puts("PASS");
490
491 /*
492 * cupsFileCompression()
493 */
494
495 fputs("cupsFileCompression(): ", stdout);
496
497 if (cupsFileCompression(fp) == compression)
498 puts("PASS");
499 else
500 {
501 printf("FAIL (Got %d, expected %d)\n", cupsFileCompression(fp),
502 compression);
503 status ++;
504 }
505
506 /*
507 * cupsFilePuts()
508 */
509
510 fputs("cupsFilePuts(): ", stdout);
511
512 if (cupsFilePuts(fp, "# Hello, World\n") > 0)
513 puts("PASS");
514 else
515 {
516 printf("FAIL (%s)\n", strerror(errno));
517 status ++;
518 }
519
520 /*
521 * cupsFilePrintf()
522 */
523
524 fputs("cupsFilePrintf(): ", stdout);
525
526 for (i = 0; i < 1000; i ++)
634763e8 527 if (cupsFilePrintf(fp, "TestLine %03d\n", i) < 0)
ef416fc2 528 break;
529
530 if (i >= 1000)
531 puts("PASS");
532 else
533 {
534 printf("FAIL (%s)\n", strerror(errno));
535 status ++;
536 }
537
538 /*
539 * cupsFilePutChar()
540 */
541
542 fputs("cupsFilePutChar(): ", stdout);
543
544 for (i = 0; i < 256; i ++)
545 if (cupsFilePutChar(fp, i) < 0)
546 break;
547
548 if (i >= 256)
549 puts("PASS");
550 else
551 {
552 printf("FAIL (%s)\n", strerror(errno));
553 status ++;
554 }
555
556 /*
557 * cupsFileWrite()
558 */
559
560 fputs("cupsFileWrite(): ", stdout);
561
c277e2f8 562 for (i = 0; i < 10000; i ++)
ef416fc2 563 if (cupsFileWrite(fp, (char *)writebuf, sizeof(writebuf)) < 0)
564 break;
565
c277e2f8
MS
566 if (i >= 10000)
567 puts("PASS");
568 else
569 {
570 printf("FAIL (%s)\n", strerror(errno));
571 status ++;
572 }
573
574 /*
575 * cupsFilePuts() with partial line...
576 */
577
578 fputs("cupsFilePuts(\"partial line\"): ", stdout);
579
580 if (cupsFilePuts(fp, partial_line) > 0)
ef416fc2 581 puts("PASS");
582 else
583 {
584 printf("FAIL (%s)\n", strerror(errno));
585 status ++;
586 }
587
634763e8
MS
588 /*
589 * cupsFileTell()
590 */
591
592 fputs("cupsFileTell(): ", stdout);
593
594 if ((length = cupsFileTell(fp)) == 81933283)
595 puts("PASS");
596 else
597 {
598 printf("FAIL (" CUPS_LLFMT " instead of 81933283)\n", CUPS_LLCAST length);
599 status ++;
600 }
601
ef416fc2 602 /*
603 * cupsFileClose()
604 */
605
606 fputs("cupsFileClose(): ", stdout);
607
608 if (!cupsFileClose(fp))
609 puts("PASS");
610 else
611 {
612 printf("FAIL (%s)\n", strerror(errno));
613 status ++;
614 }
615 }
616 else
617 {
618 printf("FAIL (%s)\n", strerror(errno));
619 status ++;
620 }
621
622 /*
623 * cupsFileOpen(read)
624 */
625
634763e8 626 fputs("\ncupsFileOpen(read): ", stdout);
ef416fc2 627
628 fp = cupsFileOpen(compression ? "testfile.dat.gz" : "testfile.dat", "r");
629 if (fp)
630 {
631 puts("PASS");
632
633 /*
634 * cupsFileGets()
635 */
636
637 fputs("cupsFileGets(): ", stdout);
638
639 if (cupsFileGets(fp, line, sizeof(line)))
640 {
641 if (line[0] == '#')
642 puts("PASS");
643 else
644 {
645 printf("FAIL (Got line \"%s\", expected comment line)\n", line);
646 status ++;
647 }
648 }
649 else
650 {
651 printf("FAIL (%s)\n", strerror(errno));
652 status ++;
653 }
654
655 /*
656 * cupsFileCompression()
657 */
658
659 fputs("cupsFileCompression(): ", stdout);
660
661 if (cupsFileCompression(fp) == compression)
662 puts("PASS");
663 else
664 {
665 printf("FAIL (Got %d, expected %d)\n", cupsFileCompression(fp),
666 compression);
667 status ++;
668 }
669
670 /*
671 * cupsFileGetConf()
672 */
673
674 linenum = 1;
675
676 fputs("cupsFileGetConf(): ", stdout);
677
678 for (i = 0; i < 1000; i ++)
679 if (!cupsFileGetConf(fp, line, sizeof(line), &value, &linenum))
680 break;
681 else if (strcasecmp(line, "TestLine") || !value || atoi(value) != i ||
682 linenum != (i + 2))
683 break;
684
685 if (i >= 1000)
686 puts("PASS");
687 else if (line[0])
688 {
689 printf("FAIL (Line %d, directive \"%s\", value \"%s\")\n", linenum,
690 line, value ? value : "(null)");
691 status ++;
692 }
693 else
694 {
695 printf("FAIL (%s)\n", strerror(errno));
696 status ++;
697 }
698
699 /*
b86bc4cf 700 * cupsFileGetChar()
ef416fc2 701 */
702
b86bc4cf 703 fputs("cupsFileGetChar(): ", stdout);
704
ef416fc2 705 for (i = 0; i < 256; i ++)
706 if ((byte = cupsFileGetChar(fp)) != i)
707 break;
708
709 if (i >= 256)
710 puts("PASS");
711 else if (byte >= 0)
712 {
713 printf("FAIL (Got %d, expected %d)\n", byte, i);
714 status ++;
715 }
716 else
717 {
718 printf("FAIL (%s)\n", strerror(errno));
719 status ++;
720 }
721
722 /*
723 * cupsFileRead()
724 */
725
726 fputs("cupsFileRead(): ", stdout);
727
c277e2f8 728 for (i = 0; i < 10000; i ++)
ef416fc2 729 if ((byte = cupsFileRead(fp, (char *)readbuf, sizeof(readbuf))) < 0)
730 break;
731 else if (memcmp(readbuf, writebuf, sizeof(readbuf)))
732 break;
733
c277e2f8 734 if (i >= 10000)
ef416fc2 735 puts("PASS");
736 else if (byte > 0)
737 {
738 printf("FAIL (Pass %d, ", i);
739
740 for (i = 0; i < (int)sizeof(readbuf); i ++)
741 if (readbuf[i] != writebuf[i])
742 break;
743
744 printf("match failed at offset %d - got %02X, expected %02X)\n",
745 i, readbuf[i], writebuf[i]);
746 }
747 else
748 {
749 printf("FAIL (%s)\n", strerror(errno));
750 status ++;
751 }
752
c277e2f8
MS
753 /*
754 * cupsFileGetChar() with partial line...
755 */
756
757 fputs("cupsFileGetChar(partial line): ", stdout);
758
759 for (i = 0; i < strlen(partial_line); i ++)
760 if ((byte = cupsFileGetChar(fp)) < 0)
761 break;
762 else if (byte != partial_line[i])
763 break;
764
765 if (!partial_line[i])
766 puts("PASS");
767 else
768 {
769 printf("FAIL (got '%c', expected '%c')\n", byte, partial_line[i]);
770 status ++;
771 }
772
634763e8
MS
773 /*
774 * cupsFileTell()
775 */
776
777 fputs("cupsFileTell(): ", stdout);
778
779 if ((length = cupsFileTell(fp)) == 81933283)
780 puts("PASS");
781 else
782 {
783 printf("FAIL (" CUPS_LLFMT " instead of 81933283)\n", CUPS_LLCAST length);
784 status ++;
785 }
786
ef416fc2 787 /*
788 * cupsFileClose()
789 */
790
791 fputs("cupsFileClose(): ", stdout);
792
793 if (!cupsFileClose(fp))
794 puts("PASS");
795 else
796 {
797 printf("FAIL (%s)\n", strerror(errno));
798 status ++;
799 }
800 }
801 else
802 {
803 printf("FAIL (%s)\n", strerror(errno));
804 status ++;
805 }
806
634763e8
MS
807 /*
808 * Remove the test file...
809 */
810
811 unlink(compression ? "testfile.dat.gz" : "testfile.dat");
812
ef416fc2 813 /*
814 * Return the test status...
815 */
816
817 return (status);
818}
819
820
821/*
b19ccc9e 822 * End of "$Id: testfile.c 7720 2008-07-11 22:46:21Z mike $".
ef416fc2 823 */