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