]> git.scottworley.com Git - overonion/blame - reverse_test.c
set -e doesn't catch failures inside <()
[overonion] / reverse_test.c
CommitLineData
e8aa0cd3 1#include "reverse_lib.h"
bdb40a5a 2#include "temp_file.h"
e8aa0cd3
SW
3
4#include <err.h>
5#include <stdio.h>
6#include <stdlib.h>
7#include <string.h>
8#include <sysexits.h>
9#include <unistd.h>
10
a3915755
SW
11/* Reverse input_file. Dump the result in a temporary file. Return the temp
12 * file's name. The caller must free the filename. */
e8aa0cd3 13char* reverse_to_temp_file(const char* input_file) {
bdb40a5a
SW
14 char* temp_filename;
15 FILE* f;
16 make_temporary_file(&temp_filename, &f);
a99e77b4
SW
17 reverse_file(input_file, f);
18 if (fclose(f) == EOF) err(EX_IOERR, "Couldn't close temporary file");
e8aa0cd3
SW
19 return temp_filename;
20}
21
a3915755
SW
22/* Compare the contents of two files. Terminate with a diagnostic if they
23 * differ. */
24void compare(const char* filename1, const char* filename2) {
25 FILE* f1 = fopen(filename1, "r");
26 if (f1 == NULL) err(EX_IOERR, "Couldn't open file %s", filename1);
27 FILE* f2 = fopen(filename2, "r");
28 if (f2 == NULL) err(EX_IOERR, "Couldn't open file %s", filename2);
e8aa0cd3
SW
29
30 for (int pos = 0; ; pos++) {
31 int c1 = fgetc(f1);
32 int c2 = fgetc(f2);
a3915755
SW
33 if (c1 == EOF && ferror(f1)) err(EX_IOERR, "Error reading file %s", filename1);
34 if (c2 == EOF && ferror(f2)) err(EX_IOERR, "Error reading file %s", filename2);
e8aa0cd3
SW
35 if (c1 != c2) {
36 errx(EX_SOFTWARE, "Unexpected difference found at offset %d after reversing twice. "
37 "Expected %d but found %d", pos, c1, c2);
38 }
39 if (c1 == EOF) break;
40 }
41
a3915755
SW
42 if (fclose(f1) != 0) err(EX_IOERR, "Couldn't close file %s", filename1);
43 if (fclose(f2) != 0) err(EX_IOERR, "Couldn't close file %s", filename2);
44}
45
622af8d7
SW
46void test_reverse_twice_from_files_is_the_same(const char* test_filename) {
47 char* intermediate = reverse_to_temp_file(test_filename);
a3915755
SW
48 char* back_to_normal = reverse_to_temp_file(intermediate);
49
622af8d7 50 compare(test_filename, back_to_normal);
a3915755 51
e8aa0cd3
SW
52 if (unlink(intermediate) == -1) err(EX_IOERR, "Couldn't remove intermediate temp file");
53 if (unlink(back_to_normal) == -1) err(EX_IOERR, "Couldn't remove twice-reversed temp file");
54 free(intermediate);
55 free(back_to_normal);
56}
57
622af8d7 58void test_reverse_from_file_then_from_stream_is_the_same(const char* test_filename) {
a3915755
SW
59 int pipefd[2];
60 if (pipe(pipefd) == -1) err(EX_OSERR, "Couldn't create pipe");
61
62 pid_t pid = fork();
63 if (pid == -1) err(EX_OSERR, "Couldn't fork");
64 if (pid == 0) {
65 if (close(pipefd[0]) == -1) err(EX_OSERR, "Couldn't close unneeded pipe descriptor");
66 FILE* to_second = fdopen(pipefd[1], "w");
67 if (to_second == NULL) err(EX_IOERR, "Couldn't open pipe for writing");
622af8d7 68 reverse_file(test_filename, to_second);
a3915755
SW
69 exit(0);
70 }
71 if (close(pipefd[1]) == -1) err(EX_OSERR, "Couldn't close unneeded pipe descriptor");
72 FILE* from_first = fdopen(pipefd[0], "r");
73 if (from_first == NULL) err(EX_IOERR, "Couldn't open pipe for reading");
bdb40a5a
SW
74 char* out_temp_filename;
75 FILE* out_file;
76 make_temporary_file(&out_temp_filename, &out_file);
a3915755
SW
77 reverse_stream(from_first, out_file);
78 if (fclose(out_file) == EOF) err(EX_IOERR, "Couldn't close temporary file");
79
622af8d7 80 compare(test_filename, out_temp_filename);
a3915755
SW
81
82 if (unlink(out_temp_filename) == -1) err(EX_IOERR, "Couldn't remove temp output file");
83 free(out_temp_filename);
84}
85
622af8d7
SW
86int main(int argc, char** argv) {
87 char* test_filename = "reverse.c";
88 if (argc > 2) {
89 errx(EX_USAGE, "usage: reverse_test [datafile]");
90 } else if (argc == 2) {
91 test_filename = argv[1];
92 }
93
94 test_reverse_twice_from_files_is_the_same(test_filename);
95 test_reverse_from_file_then_from_stream_is_the_same(test_filename);
96
e8aa0cd3
SW
97 puts("PASS");
98 return 0;
99}