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