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