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