X-Git-Url: http://git.scottworley.com/overonion/blobdiff_plain/a99e77b43df141c988b52e663d64d40e79f11895..2377b838ff45bc3407e0c65028eac858c47c9d4e:/reverse_test.c diff --git a/reverse_test.c b/reverse_test.c index 512edaa..30aff32 100644 --- a/reverse_test.c +++ b/reverse_test.c @@ -9,6 +9,8 @@ static const char test_file[] = "reverse.c"; +/* Reverse input_file. Dump the result in a temporary file. Return the temp + * file's name. The caller must free the filename. */ char* reverse_to_temp_file(const char* input_file) { char* temp_filename = strdup("/tmp/reverse_test.XXXXXX"); int fd = mkstemp(temp_filename); @@ -20,20 +22,19 @@ char* reverse_to_temp_file(const char* input_file) { return temp_filename; } -void test_reverse_twice_is_the_same() { - char* intermediate = reverse_to_temp_file(test_file); - char* back_to_normal = reverse_to_temp_file(intermediate); - - FILE* f1 = fopen(test_file, "r"); - if (f1 == NULL) err(EX_IOERR, "Couldn't open test file"); - FILE* f2 = fopen(back_to_normal, "r"); - if (f2 == NULL) err(EX_IOERR, "Couldn't open twice-reversed temp file"); +/* Compare the contents of two files. Terminate with a diagnostic if they + * differ. */ +void compare(const char* filename1, const char* filename2) { + FILE* f1 = fopen(filename1, "r"); + if (f1 == NULL) err(EX_IOERR, "Couldn't open file %s", filename1); + FILE* f2 = fopen(filename2, "r"); + if (f2 == NULL) err(EX_IOERR, "Couldn't open file %s", filename2); for (int pos = 0; ; pos++) { int c1 = fgetc(f1); int c2 = fgetc(f2); - if (c1 == EOF && ferror(f1)) err(EX_IOERR, "Error reading test file"); - if (c2 == EOF && ferror(f2)) err(EX_IOERR, "Error reading twice-reversed temp file"); + if (c1 == EOF && ferror(f1)) err(EX_IOERR, "Error reading file %s", filename1); + if (c2 == EOF && ferror(f2)) err(EX_IOERR, "Error reading file %s", filename2); if (c1 != c2) { errx(EX_SOFTWARE, "Unexpected difference found at offset %d after reversing twice. " "Expected %d but found %d", pos, c1, c2); @@ -41,16 +42,55 @@ void test_reverse_twice_is_the_same() { if (c1 == EOF) break; } - if (fclose(f1) != 0) err(EX_IOERR, "Couldn't close test file"); - if (fclose(f2) != 0) err(EX_IOERR, "Couldn't close twice-reversed temp file"); + if (fclose(f1) != 0) err(EX_IOERR, "Couldn't close file %s", filename1); + if (fclose(f2) != 0) err(EX_IOERR, "Couldn't close file %s", filename2); +} + +void test_reverse_twice_from_files_is_the_same() { + char* intermediate = reverse_to_temp_file(test_file); + char* back_to_normal = reverse_to_temp_file(intermediate); + + compare(test_file, back_to_normal); + if (unlink(intermediate) == -1) err(EX_IOERR, "Couldn't remove intermediate temp file"); if (unlink(back_to_normal) == -1) err(EX_IOERR, "Couldn't remove twice-reversed temp file"); free(intermediate); free(back_to_normal); } +void test_reverse_from_file_then_from_stream_is_the_same() { + int pipefd[2]; + if (pipe(pipefd) == -1) err(EX_OSERR, "Couldn't create pipe"); + + pid_t pid = fork(); + if (pid == -1) err(EX_OSERR, "Couldn't fork"); + if (pid == 0) { + if (close(pipefd[0]) == -1) err(EX_OSERR, "Couldn't close unneeded pipe descriptor"); + FILE* to_second = fdopen(pipefd[1], "w"); + if (to_second == NULL) err(EX_IOERR, "Couldn't open pipe for writing"); + reverse_file(test_file, to_second); + exit(0); + } + if (close(pipefd[1]) == -1) err(EX_OSERR, "Couldn't close unneeded pipe descriptor"); + FILE* from_first = fdopen(pipefd[0], "r"); + if (from_first == NULL) err(EX_IOERR, "Couldn't open pipe for reading"); + char* out_temp_filename = strdup("/tmp/reverse_test.XXXXXX"); + int out_fd = mkstemp(out_temp_filename); + if (out_fd == -1) err(EX_IOERR, "Couldn't make a temporary file"); + FILE* out_file = fdopen(out_fd, "w"); + if (out_file == NULL) err(EX_IOERR, "Couldn't open temporary file"); + reverse_stream(from_first, out_file); + if (fclose(out_file) == EOF) err(EX_IOERR, "Couldn't close temporary file"); + + compare(test_file, out_temp_filename); + + if (unlink(out_temp_filename) == -1) err(EX_IOERR, "Couldn't remove temp output file"); + free(out_temp_filename); +} + int main() { - test_reverse_twice_is_the_same(); + test_reverse_twice_from_files_is_the_same(); + test_reverse_from_file_then_from_stream_is_the_same(); puts("PASS"); return 0; }