]> git.ipfire.org Git - thirdparty/cups.git/blame - cups/testfile.c
Add Travis CI support.
[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 *
e3101897 7 * Licensed under Apache License v2.0. See the file "LICENSE" for more information.
ef416fc2 8 */
9
10/*
11 * Include necessary headers...
12 */
13
71e16022
MS
14#include "string-private.h"
15#include "debug-private.h"
16#include "file.h"
ef416fc2 17#include <stdlib.h>
ef416fc2 18#include <time.h>
b423cd4c 19#ifdef HAVE_LIBZ
20# include <zlib.h>
21#endif /* HAVE_LIBZ */
536bc2c6
MS
22#ifdef WIN32
23# include <io.h>
24#else
25# include <unistd.h>
26#endif /* WIN32 */
ae71f5de 27#include <fcntl.h>
ef416fc2 28
29
30/*
31 * Local functions...
32 */
33
c9fc04c6 34static int count_lines(cups_file_t *fp);
634763e8 35static int random_tests(void);
ef416fc2 36static int read_write_tests(int compression);
37
38
39/*
40 * 'main()' - Main entry.
41 */
42
43int /* O - Exit status */
44main(int argc, /* I - Number of command-line arguments */
45 char *argv[]) /* I - Command-line arguments */
46{
ae71f5de
MS
47 int status; /* Exit status */
48 char filename[1024]; /* Filename buffer */
c9fc04c6 49 cups_file_t *fp; /* File pointer */
7a0cbd5e 50#ifndef WIN32
ae71f5de
MS
51 int fds[2]; /* Open file descriptors */
52 cups_file_t *fdfile; /* File opened with cupsFileOpenFd() */
7a0cbd5e 53#endif /* !WIN32 */
c9fc04c6 54 int count; /* Number of lines in file */
ef416fc2 55
56
fa73b229 57 if (argc == 1)
58 {
59 /*
60 * Do uncompressed file tests...
61 */
ef416fc2 62
fa73b229 63 status = read_write_tests(0);
ef416fc2 64
65#ifdef HAVE_LIBZ
fa73b229 66 /*
67 * Do compressed file tests...
68 */
ef416fc2 69
fa73b229 70 putchar('\n');
ef416fc2 71
fa73b229 72 status += read_write_tests(1);
ef416fc2 73#endif /* HAVE_LIBZ */
74
634763e8
MS
75 /*
76 * Do uncompressed random I/O tests...
77 */
78
1f0275e3 79 status += random_tests();
634763e8 80
7a0cbd5e 81#ifndef WIN32
ae71f5de
MS
82 /*
83 * Test fdopen and close without reading...
84 */
85
86 pipe(fds);
87 close(fds[1]);
88
634763e8 89 fputs("\ncupsFileOpenFd(fd, \"r\"): ", stdout);
ae71f5de
MS
90 fflush(stdout);
91
92 if ((fdfile = cupsFileOpenFd(fds[0], "r")) == NULL)
93 {
94 puts("FAIL");
95 status ++;
96 }
97 else
98 {
99 /*
100 * Able to open file, now close without reading. If we don't return
101 * before the alarm fires, that is a failure and we will crash on the
102 * alarm signal...
103 */
104
105 puts("PASS");
106 fputs("cupsFileClose(no read): ", stdout);
107 fflush(stdout);
108
109 alarm(5);
110 cupsFileClose(fdfile);
111 alarm(0);
112
113 puts("PASS");
114 }
7a0cbd5e 115#endif /* !WIN32 */
ae71f5de 116
c9fc04c6 117 /*
e22f464e 118 * Count lines in test file, rewind, then count again.
c9fc04c6
MS
119 */
120
e22f464e 121 fputs("\ncupsFileOpen(\"testfile.txt\", \"r\"): ", stdout);
c9fc04c6 122
e22f464e 123 if ((fp = cupsFileOpen("testfile.txt", "r")) == NULL)
c9fc04c6
MS
124 {
125 puts("FAIL");
126 status ++;
127 }
128 else
129 {
130 puts("PASS");
131 fputs("cupsFileGets: ", stdout);
132
e22f464e 133 if ((count = count_lines(fp)) != 477)
c9fc04c6 134 {
e22f464e 135 printf("FAIL (got %d lines, expected 477)\n", count);
c9fc04c6
MS
136 status ++;
137 }
138 else
139 {
140 puts("PASS");
141 fputs("cupsFileRewind: ", stdout);
142
143 if (cupsFileRewind(fp) != 0)
144 {
145 puts("FAIL");
146 status ++;
147 }
148 else
149 {
150 puts("PASS");
151 fputs("cupsFileGets: ", stdout);
152
e22f464e 153 if ((count = count_lines(fp)) != 477)
c9fc04c6 154 {
e22f464e 155 printf("FAIL (got %d lines, expected 477)\n", count);
c9fc04c6
MS
156 status ++;
157 }
158 else
159 puts("PASS");
160 }
161 }
162
163 cupsFileClose(fp);
164 }
165
fa73b229 166 /*
167 * Test path functions...
168 */
169
634763e8 170 fputs("\ncupsFileFind: ", stdout);
b86bc4cf 171#ifdef WIN32
172 if (cupsFileFind("notepad.exe", "C:/WINDOWS", 1, filename, sizeof(filename)) &&
173 cupsFileFind("notepad.exe", "C:/WINDOWS;C:/WINDOWS/SYSTEM32", 1, filename, sizeof(filename)))
174#else
4400e98d 175 if (cupsFileFind("cat", "/bin", 1, filename, sizeof(filename)) &&
176 cupsFileFind("cat", "/bin:/usr/bin", 1, filename, sizeof(filename)))
b86bc4cf 177#endif /* WIN32 */
fa73b229 178 printf("PASS (%s)\n", filename);
179 else
180 {
181 puts("FAIL");
182 status ++;
183 }
ef416fc2 184
fa73b229 185 /*
186 * Summarize the results and return...
187 */
188
189 if (!status)
190 puts("\nALL TESTS PASSED!");
191 else
192 printf("\n%d TEST(S) FAILED!\n", status);
193 }
ef416fc2 194 else
fa73b229 195 {
196 /*
197 * Cat the filename on the command-line...
198 */
199
cbf9404a 200 char line[8192]; /* Line from file */
fa73b229 201
fa73b229 202 if ((fp = cupsFileOpen(argv[1], "r")) == NULL)
203 {
204 perror(argv[1]);
205 status = 1;
206 }
cbf9404a 207 else if (argc == 2)
fa73b229 208 {
209 status = 0;
210
211 while (cupsFileGets(fp, line, sizeof(line)))
212 puts(line);
213
214 if (!cupsFileEOF(fp))
215 perror(argv[1]);
216
217 cupsFileClose(fp);
218 }
cbf9404a
MS
219 else
220 {
221 status = 0;
222 ssize_t bytes;
223
224 while ((bytes = cupsFileRead(fp, line, sizeof(line))) > 0)
225 printf("%s: %d bytes\n", argv[1], (int)bytes);
226
227 if (cupsFileEOF(fp))
228 printf("%s: EOF\n", argv[1]);
229 else
230 perror(argv[1]);
231
232 cupsFileClose(fp);
233 }
fa73b229 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 */
7e86f2f6
MS
269 off_t pos; /* Position in file */
270 ssize_t expected; /* Expected position in file */
634763e8
MS
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
7e86f2f6 301 expected = 256 * (ssize_t)sizeof(buffer) * pass;
634763e8
MS
302
303 fputs("cupsFileTell(): ", stdout);
7e86f2f6 304 if ((pos = cupsFileTell(fp)) != (off_t)expected)
634763e8
MS
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));
7e86f2f6 322 if (cupsFileWrite(fp, buffer, sizeof(buffer)) < (ssize_t)sizeof(buffer))
634763e8
MS
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
7e86f2f6 339 expected += 256 * (ssize_t)sizeof(buffer);
634763e8
MS
340
341 fputs("cupsFileTell(): ", stdout);
7e86f2f6 342 if ((pos = cupsFileTell(fp)) != (off_t)expected)
634763e8
MS
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
7e86f2f6 375 for (num_records = (pass + 1) * 256, count = (pass + 1) * 256, record = ((int)CUPS_RAND() & 65535) % num_records;
634763e8 376 count > 0;
7e86f2f6 377 count --, record = (record + ((int)CUPS_RAND() & 31) - 16 + num_records) % num_records)
634763e8
MS
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
7e86f2f6 391 expected = (ssize_t)sizeof(buffer) * record;
634763e8
MS
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");
88f9aafc 430
634763e8
MS
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 */
7e86f2f6 455 ssize_t bytes; /* Number of bytes read/written */
634763e8 456 off_t length; /* Length of file */
c277e2f8
MS
457 static const char *partial_line = "partial line";
458 /* Partial line */
ef416fc2 459
460
461 /*
462 * No errors so far...
463 */
464
465 status = 0;
466
467 /*
468 * Initialize the write buffer with random data...
469 */
470
7cf5915e 471 CUPS_SRAND((unsigned)time(NULL));
b86bc4cf 472
ef416fc2 473 for (i = 0; i < (int)sizeof(writebuf); i ++)
7e86f2f6 474 writebuf[i] = (unsigned char)CUPS_RAND();
ef416fc2 475
476 /*
477 * cupsFileOpen(write)
478 */
479
480 printf("cupsFileOpen(write%s): ", compression ? " compressed" : "");
481
482 fp = cupsFileOpen(compression ? "testfile.dat.gz" : "testfile.dat",
483 compression ? "w9" : "w");
484 if (fp)
485 {
486 puts("PASS");
487
488 /*
489 * cupsFileCompression()
490 */
491
492 fputs("cupsFileCompression(): ", stdout);
493
494 if (cupsFileCompression(fp) == compression)
495 puts("PASS");
496 else
497 {
498 printf("FAIL (Got %d, expected %d)\n", cupsFileCompression(fp),
499 compression);
500 status ++;
501 }
502
503 /*
504 * cupsFilePuts()
505 */
506
507 fputs("cupsFilePuts(): ", stdout);
508
509 if (cupsFilePuts(fp, "# Hello, World\n") > 0)
510 puts("PASS");
511 else
512 {
513 printf("FAIL (%s)\n", strerror(errno));
514 status ++;
515 }
516
517 /*
518 * cupsFilePrintf()
519 */
520
521 fputs("cupsFilePrintf(): ", stdout);
522
523 for (i = 0; i < 1000; i ++)
634763e8 524 if (cupsFilePrintf(fp, "TestLine %03d\n", i) < 0)
ef416fc2 525 break;
526
527 if (i >= 1000)
528 puts("PASS");
529 else
530 {
531 printf("FAIL (%s)\n", strerror(errno));
532 status ++;
533 }
534
535 /*
536 * cupsFilePutChar()
537 */
538
539 fputs("cupsFilePutChar(): ", stdout);
540
541 for (i = 0; i < 256; i ++)
542 if (cupsFilePutChar(fp, i) < 0)
543 break;
544
545 if (i >= 256)
546 puts("PASS");
547 else
548 {
549 printf("FAIL (%s)\n", strerror(errno));
550 status ++;
551 }
552
553 /*
554 * cupsFileWrite()
555 */
556
557 fputs("cupsFileWrite(): ", stdout);
558
c277e2f8 559 for (i = 0; i < 10000; i ++)
ef416fc2 560 if (cupsFileWrite(fp, (char *)writebuf, sizeof(writebuf)) < 0)
561 break;
562
c277e2f8
MS
563 if (i >= 10000)
564 puts("PASS");
565 else
566 {
567 printf("FAIL (%s)\n", strerror(errno));
568 status ++;
569 }
570
571 /*
572 * cupsFilePuts() with partial line...
573 */
574
575 fputs("cupsFilePuts(\"partial line\"): ", stdout);
576
577 if (cupsFilePuts(fp, partial_line) > 0)
ef416fc2 578 puts("PASS");
579 else
580 {
581 printf("FAIL (%s)\n", strerror(errno));
582 status ++;
583 }
584
634763e8
MS
585 /*
586 * cupsFileTell()
587 */
588
589 fputs("cupsFileTell(): ", stdout);
590
591 if ((length = cupsFileTell(fp)) == 81933283)
592 puts("PASS");
593 else
594 {
595 printf("FAIL (" CUPS_LLFMT " instead of 81933283)\n", CUPS_LLCAST length);
596 status ++;
597 }
598
ef416fc2 599 /*
600 * cupsFileClose()
601 */
602
603 fputs("cupsFileClose(): ", stdout);
604
605 if (!cupsFileClose(fp))
606 puts("PASS");
607 else
608 {
609 printf("FAIL (%s)\n", strerror(errno));
610 status ++;
611 }
612 }
613 else
614 {
615 printf("FAIL (%s)\n", strerror(errno));
616 status ++;
617 }
618
619 /*
620 * cupsFileOpen(read)
621 */
622
634763e8 623 fputs("\ncupsFileOpen(read): ", stdout);
ef416fc2 624
625 fp = cupsFileOpen(compression ? "testfile.dat.gz" : "testfile.dat", "r");
626 if (fp)
627 {
628 puts("PASS");
629
630 /*
631 * cupsFileGets()
632 */
633
634 fputs("cupsFileGets(): ", stdout);
635
636 if (cupsFileGets(fp, line, sizeof(line)))
637 {
638 if (line[0] == '#')
639 puts("PASS");
640 else
641 {
642 printf("FAIL (Got line \"%s\", expected comment line)\n", line);
643 status ++;
644 }
645 }
646 else
647 {
648 printf("FAIL (%s)\n", strerror(errno));
649 status ++;
650 }
651
652 /*
653 * cupsFileCompression()
654 */
655
656 fputs("cupsFileCompression(): ", stdout);
657
658 if (cupsFileCompression(fp) == compression)
659 puts("PASS");
660 else
661 {
662 printf("FAIL (Got %d, expected %d)\n", cupsFileCompression(fp),
663 compression);
664 status ++;
665 }
666
667 /*
668 * cupsFileGetConf()
669 */
670
671 linenum = 1;
672
673 fputs("cupsFileGetConf(): ", stdout);
674
7e86f2f6 675 for (i = 0, value = NULL; i < 1000; i ++)
ef416fc2 676 if (!cupsFileGetConf(fp, line, sizeof(line), &value, &linenum))
677 break;
88f9aafc 678 else if (_cups_strcasecmp(line, "TestLine") || !value || atoi(value) != i ||
ef416fc2 679 linenum != (i + 2))
680 break;
681
682 if (i >= 1000)
683 puts("PASS");
684 else if (line[0])
685 {
686 printf("FAIL (Line %d, directive \"%s\", value \"%s\")\n", linenum,
687 line, value ? value : "(null)");
688 status ++;
689 }
690 else
691 {
692 printf("FAIL (%s)\n", strerror(errno));
693 status ++;
694 }
695
696 /*
b86bc4cf 697 * cupsFileGetChar()
ef416fc2 698 */
699
b86bc4cf 700 fputs("cupsFileGetChar(): ", stdout);
701
7e86f2f6 702 for (i = 0, byte = 0; i < 256; i ++)
ef416fc2 703 if ((byte = cupsFileGetChar(fp)) != i)
704 break;
705
706 if (i >= 256)
707 puts("PASS");
708 else if (byte >= 0)
709 {
710 printf("FAIL (Got %d, expected %d)\n", byte, i);
711 status ++;
712 }
713 else
714 {
715 printf("FAIL (%s)\n", strerror(errno));
716 status ++;
717 }
718
719 /*
720 * cupsFileRead()
721 */
722
723 fputs("cupsFileRead(): ", stdout);
724
7e86f2f6
MS
725 for (i = 0, bytes = 0; i < 10000; i ++)
726 if ((bytes = cupsFileRead(fp, (char *)readbuf, sizeof(readbuf))) < 0)
ef416fc2 727 break;
728 else if (memcmp(readbuf, writebuf, sizeof(readbuf)))
729 break;
730
c277e2f8 731 if (i >= 10000)
ef416fc2 732 puts("PASS");
7e86f2f6 733 else if (bytes > 0)
ef416fc2 734 {
735 printf("FAIL (Pass %d, ", i);
736
737 for (i = 0; i < (int)sizeof(readbuf); i ++)
738 if (readbuf[i] != writebuf[i])
739 break;
740
741 printf("match failed at offset %d - got %02X, expected %02X)\n",
742 i, readbuf[i], writebuf[i]);
743 }
744 else
745 {
746 printf("FAIL (%s)\n", strerror(errno));
747 status ++;
748 }
749
c277e2f8
MS
750 /*
751 * cupsFileGetChar() with partial line...
752 */
753
754 fputs("cupsFileGetChar(partial line): ", stdout);
755
7a0cbd5e 756 for (i = 0; i < (int)strlen(partial_line); i ++)
c277e2f8
MS
757 if ((byte = cupsFileGetChar(fp)) < 0)
758 break;
759 else if (byte != partial_line[i])
760 break;
761
762 if (!partial_line[i])
763 puts("PASS");
764 else
765 {
766 printf("FAIL (got '%c', expected '%c')\n", byte, partial_line[i]);
767 status ++;
768 }
769
634763e8
MS
770 /*
771 * cupsFileTell()
772 */
773
774 fputs("cupsFileTell(): ", stdout);
775
776 if ((length = cupsFileTell(fp)) == 81933283)
777 puts("PASS");
778 else
779 {
780 printf("FAIL (" CUPS_LLFMT " instead of 81933283)\n", CUPS_LLCAST length);
781 status ++;
782 }
783
ef416fc2 784 /*
785 * cupsFileClose()
786 */
787
788 fputs("cupsFileClose(): ", stdout);
789
790 if (!cupsFileClose(fp))
791 puts("PASS");
792 else
793 {
794 printf("FAIL (%s)\n", strerror(errno));
795 status ++;
796 }
797 }
798 else
799 {
800 printf("FAIL (%s)\n", strerror(errno));
801 status ++;
802 }
803
634763e8
MS
804 /*
805 * Remove the test file...
806 */
807
cbf9404a
MS
808 if (!status)
809 unlink(compression ? "testfile.dat.gz" : "testfile.dat");
88f9aafc 810
ef416fc2 811 /*
812 * Return the test status...
813 */
814
815 return (status);
816}