diff options
Diffstat (limited to 'src/libdisfluid/disfluid-tests.h')
-rw-r--r-- | src/libdisfluid/disfluid-tests.h | 514 |
1 files changed, 345 insertions, 169 deletions
diff --git a/src/libdisfluid/disfluid-tests.h b/src/libdisfluid/disfluid-tests.h index 0a40f20..0819bb0 100644 --- a/src/libdisfluid/disfluid-tests.h +++ b/src/libdisfluid/disfluid-tests.h @@ -11,8 +11,8 @@ static inline char *run_tests (size_t *n_tests, size_t *n_errors); # include "disfluid-version.h" # include "disfluid-cache-entry.h" -static inline int -test_open_file_with_content (const char *content) +static inline char * +test_tmp_file_name_with_content (size_t n, const uint8_t * content) { char name[] = "/tmp/disfluid-cache-entry-test-XXXXXX"; int fd = mkstemp (name); @@ -20,27 +20,34 @@ test_open_file_with_content (const char *content) { abort (); } - size_t n_written = 0; - while (n_written < strlen (content)) + while (n > 0) { - ssize_t next = - write (fd, &(content[n_written]), strlen (content) - n_written); + ssize_t next = write (fd, content, n); if (next <= 0) { abort (); } - n_written += next; + else if (next == 0) + { + /* Impossible */ + abort (); + } + else + { + assert (next > 0); + assert ((size_t) next <= n); + n -= next; + content = &(content[next]); + } } - remove (name); - lseek (fd, 0, SEEK_SET); - return fd; -} - -static inline void -fwrite_text (FILE * file, const char *text) -{ - fwrite (text, 1, strlen (text), file); - fflush (file); + close (fd); + char *ret = malloc (strlen (name) + 1); + if (ret == NULL) + { + abort (); + } + strcpy (ret, name); + return ret; } /* *INDENT-OFF* */ @@ -56,204 +63,312 @@ END_TEST /* *INDENT-ON* */ /* *INDENT-OFF* */ -START_TEST (test_read_invalid_cache_entry_file) +START_TEST (test_read_invalid_magic_number) /* *INDENT-ON* */ { - int fd_source = test_open_file_with_content ("Hello, world!"); - if (fd_source < 0) + uint8_t data[16 + 12 + 12 + 1] = { 0 }; + memcpy (data, "invalid magic no", 16); + char *filename = + test_tmp_file_name_with_content (sizeof (data) / sizeof (data[0]), data); + if (filename == NULL) + { + abort (); + } + struct disfluid_cache_entry *entry = cache_entry_alloc (); + if (entry == NULL) { abort (); } - struct disfluid_cache_entry *entry = - disfluid_cache_entry_from_fd (fd_source); - ck_assert_ptr_null (entry); - close (fd_source); + int error = cache_entry_load (entry, filename); + cache_entry_free (entry); + remove (filename); + free (filename); + ck_assert_int_ne (error, 0); } /* *INDENT-OFF* */ END_TEST /* *INDENT-ON* */ /* *INDENT-OFF* */ -START_TEST (test_read_cache_entry_no_date) +START_TEST (test_read_inexistent_file) /* *INDENT-ON* */ { - int fd_source = test_open_file_with_content ("Invalidated: true\r\n\r\n"); - if (fd_source < 0) + static const char *filename = + "/disfluid-this-file-should-not-exist-to-pass-tests"; + struct disfluid_cache_entry *entry = cache_entry_alloc (); + if (entry == NULL) { abort (); } - struct disfluid_cache_entry *entry = - disfluid_cache_entry_from_fd (fd_source); - ck_assert_ptr_ne (entry, NULL); - close (fd_source); - struct timespec request_date = {.tv_sec = 42,.tv_nsec = 69 }; - struct timespec response_date = {.tv_sec = 42,.tv_nsec = 69 }; - disfluid_cache_entry_get_request_date (entry, &request_date); - disfluid_cache_entry_get_request_date (entry, &response_date); - ck_assert_int_eq (request_date.tv_sec, 0); - ck_assert_int_eq (request_date.tv_nsec, 0); - ck_assert_int_eq (response_date.tv_sec, 0); - ck_assert_int_eq (response_date.tv_nsec, 0); - ck_assert ((bool) disfluid_cache_entry_invalidated (entry)); - disfluid_cache_entry_free (entry); + int error = cache_entry_load (entry, filename); + cache_entry_free (entry); + ck_assert_int_ne (error, 0); } /* *INDENT-OFF* */ END_TEST /* *INDENT-ON* */ /* *INDENT-OFF* */ -START_TEST (test_read_cache_entry_whole_seconds) +START_TEST (test_read_inexistent_file_with_valid_backup) /* *INDENT-ON* */ { - int fd_source = test_open_file_with_content ("\ -Request-Date: 42\r\n\ -Response-Date: 69\r\n\ -Invalidated: true\r\n\ -\r\n"); - if (fd_source < 0) + uint8_t data[16 + 12 + 12 + 1] = { 0 }; + memcpy (data, "disfluid c.entry", 16); + char *filename = + test_tmp_file_name_with_content (sizeof (data) / sizeof (data[0]), data); + if (filename == NULL) + { + abort (); + } + char *filename_backup = malloc (strlen (filename) + strlen ("~") + 1); + if (filename_backup == NULL) + { + abort (); + } + strcpy (filename_backup, filename); + strcat (filename_backup, "~"); + rename (filename, filename_backup); + struct disfluid_cache_entry *entry = cache_entry_alloc (); + if (entry == NULL) { abort (); } - struct disfluid_cache_entry *entry = - disfluid_cache_entry_from_fd (fd_source); - close (fd_source); - ck_assert_ptr_ne (entry, NULL); - struct timespec request_date = {.tv_sec = 1,.tv_nsec = 3 }; - struct timespec response_date = {.tv_sec = 2,.tv_nsec = 4 }; - disfluid_cache_entry_get_request_date (entry, &request_date); - disfluid_cache_entry_get_response_date (entry, &response_date); - ck_assert_int_eq (request_date.tv_sec, 42); - ck_assert_int_eq (request_date.tv_nsec, 0); - ck_assert_int_eq (response_date.tv_sec, 69); - ck_assert_int_eq (response_date.tv_nsec, 0); - ck_assert ((bool) disfluid_cache_entry_invalidated (entry)); - disfluid_cache_entry_free (entry); + int error = cache_entry_load (entry, filename); + cache_entry_free (entry); + remove (filename_backup); + free (filename_backup); + free (filename); + ck_assert_int_ne (error, 0); } /* *INDENT-OFF* */ END_TEST /* *INDENT-ON* */ +static inline void +test_check_partial_situation (size_t n_partial) +{ + uint8_t data[16 + 12 + 12 + 1] = { 0 }; + memcpy (data, "disfluid c.entry", 16); + /* The data is all zeros */ + uint8_t backup_data[16 + 12 + 12 + 1] = { 0 }; + memcpy (backup_data, "disfluid c.entry", 16); + backup_data[16 + 8 - 1] = 1; + backup_data[16 + 12 - 1] = 2; + backup_data[16 + 12 + 8 - 1] = 3; + backup_data[16 + 12 + 12 - 1] = 4; + backup_data[16 + 12 + 12 + 1 - 1] = 0x80; + /* The backup has a request date of 1s + 2ns, response of 3s + 4ns, + and is invalidated. */ + assert (n_partial <= sizeof (data) / sizeof (data[0])); + char *filename = test_tmp_file_name_with_content (n_partial, data); + if (filename == NULL) + { + abort (); + } + char *filename_backup = malloc (strlen (filename) + strlen ("~") + 1); + if (filename_backup == NULL) + { + abort (); + } + strcpy (filename_backup, filename); + strcat (filename_backup, "~"); + char *backup_content_filename = + test_tmp_file_name_with_content (sizeof (backup_data) / + sizeof (backup_data[0]), backup_data); + if (backup_content_filename == NULL) + { + abort (); + } + rename (backup_content_filename, filename_backup); + /* Now, filename is a partial file, and filename~ is a valid + backup. */ + struct disfluid_cache_entry *entry = cache_entry_alloc (); + if (entry == NULL) + { + abort (); + } + int error = cache_entry_load (entry, filename); + ck_assert_int_eq (error, 0); + if (n_partial < sizeof (data) / sizeof (data[0])) + { + /* This should be the content of the backup file. */ + struct timespec request, response; + cache_entry_get_request_date (entry, &request); + cache_entry_get_response_date (entry, &response); + bool invalidated = cache_entry_invalidated (entry); + ck_assert_int_eq (request.tv_sec, 1); + ck_assert_int_eq (request.tv_nsec, 2); + ck_assert_int_eq (response.tv_sec, 3); + ck_assert_int_eq (response.tv_nsec, 4); + ck_assert (invalidated); + } + else + { + /* This should be the content of the full file. */ + struct timespec request, response; + cache_entry_get_request_date (entry, &request); + cache_entry_get_response_date (entry, &response); + bool invalidated = cache_entry_invalidated (entry); + ck_assert_int_eq (request.tv_sec, 0); + ck_assert_int_eq (request.tv_nsec, 0); + ck_assert_int_eq (response.tv_sec, 0); + ck_assert_int_eq (response.tv_nsec, 0); + ck_assert (!invalidated); + } + cache_entry_free (entry); + free (backup_content_filename); + free (filename_backup); + free (filename); +} + /* *INDENT-OFF* */ -START_TEST (test_read_cache_entry_whole_seconds_dot) +START_TEST (test_read_file_with_valid_backup) /* *INDENT-ON* */ { - int fd_source = test_open_file_with_content ("\ -Request-Date: 42.\r\n\ -Response-Date: 69.\r\n\ -Invalidated: true\r\n\ -\r\n"); - if (fd_source < 0) + uint8_t data[16 + 12 + 12 + 1] = { 0 }; + memcpy (data, "disfluid c.entry", 16); + /* The data is all zeros */ + uint8_t backup_data[16 + 12 + 12 + 1] = { 0 }; + memcpy (backup_data, "disfluid c.entry", 16); + backup_data[16 + 8 - 1] = 1; + backup_data[16 + 12 - 1] = 2; + backup_data[16 + 12 + 8 - 1] = 3; + backup_data[16 + 12 + 12 - 1] = 4; + backup_data[16 + 12 + 12 + 1 - 1] = 0x80; + /* The backup has a request date of 1s + 2ns, response of 3s + 4ns, + and is invalidated. */ + char *filename = + test_tmp_file_name_with_content (sizeof (data) / sizeof (data[0]), data); + if (filename == NULL) + { + abort (); + } + char *filename_backup = malloc (strlen (filename) + strlen ("~") + 1); + if (filename_backup == NULL) + { + abort (); + } + strcpy (filename_backup, filename); + strcat (filename_backup, "~"); + rename (filename, filename_backup); + struct disfluid_cache_entry *entry = cache_entry_alloc (); + if (entry == NULL) { abort (); } - struct disfluid_cache_entry *entry = - disfluid_cache_entry_from_fd (fd_source); - close (fd_source); - ck_assert_ptr_ne (entry, NULL); - struct timespec request_date = {.tv_sec = 1,.tv_nsec = 3 }; - struct timespec response_date = {.tv_sec = 2,.tv_nsec = 4 }; - disfluid_cache_entry_get_request_date (entry, &request_date); - disfluid_cache_entry_get_response_date (entry, &response_date); - ck_assert_int_eq (request_date.tv_sec, 42); - ck_assert_int_eq (request_date.tv_nsec, 0); - ck_assert_int_eq (response_date.tv_sec, 69); - ck_assert_int_eq (response_date.tv_nsec, 0); - ck_assert ((bool) disfluid_cache_entry_invalidated (entry)); - disfluid_cache_entry_free (entry); + int error = cache_entry_load (entry, filename); + remove (filename_backup); + free (filename_backup); + free (filename); + cache_entry_free (entry); + ck_assert_int_ne (error, 0); } /* *INDENT-OFF* */ END_TEST /* *INDENT-ON* */ /* *INDENT-OFF* */ -START_TEST (test_read_cache_entry_milliseconds) +START_TEST (test_read_cache_file_partial_0) /* *INDENT-ON* */ { - int fd_source = test_open_file_with_content ("\ -Request-Date: 42.123\r\n\ -Response-Date: 69.456\r\n\ -Invalidated: true\r\n\ -\r\n"); - if (fd_source < 0) - { - abort (); - } - struct disfluid_cache_entry *entry = - disfluid_cache_entry_from_fd (fd_source); - close (fd_source); - ck_assert_ptr_ne (entry, NULL); - struct timespec request_date = {.tv_sec = 1,.tv_nsec = 3 }; - struct timespec response_date = {.tv_sec = 2,.tv_nsec = 4 }; - disfluid_cache_entry_get_request_date (entry, &request_date); - disfluid_cache_entry_get_response_date (entry, &response_date); - ck_assert_int_eq (request_date.tv_sec, 42); - ck_assert_int_eq (request_date.tv_nsec, 123000000); - ck_assert_int_eq (response_date.tv_sec, 69); - ck_assert_int_eq (response_date.tv_nsec, 456000000); - ck_assert ((bool) disfluid_cache_entry_invalidated (entry)); - disfluid_cache_entry_free (entry); + test_check_partial_situation (0); } /* *INDENT-OFF* */ END_TEST /* *INDENT-ON* */ /* *INDENT-OFF* */ -START_TEST (test_read_cache_entry_precise) +START_TEST (test_read_cache_file_partial_1) /* *INDENT-ON* */ { - int fd_source = test_open_file_with_content ("\ -Request-Date: 42.123456789\r\n\ -Response-Date: 69.456789123\r\n\ -Invalidated: true\r\n\ -\r\n"); - if (fd_source < 0) - { - abort (); - } - struct disfluid_cache_entry *entry = - disfluid_cache_entry_from_fd (fd_source); - close (fd_source); - ck_assert_ptr_ne (entry, NULL); - struct timespec request_date = {.tv_sec = 1,.tv_nsec = 3 }; - struct timespec response_date = {.tv_sec = 2,.tv_nsec = 4 }; - disfluid_cache_entry_get_request_date (entry, &request_date); - disfluid_cache_entry_get_response_date (entry, &response_date); - ck_assert_int_eq (request_date.tv_sec, 42); - ck_assert_int_eq (request_date.tv_nsec, 123456789); - ck_assert_int_eq (response_date.tv_sec, 69); - ck_assert_int_eq (response_date.tv_nsec, 456789123); - ck_assert ((bool) disfluid_cache_entry_invalidated (entry)); - disfluid_cache_entry_free (entry); + test_check_partial_situation (1); } /* *INDENT-OFF* */ END_TEST /* *INDENT-ON* */ /* *INDENT-OFF* */ -START_TEST (test_read_cache_entry_ambiguous) +START_TEST (test_read_cache_file_partial_16) /* *INDENT-ON* */ { - int fd_source = test_open_file_with_content ("\ -Request-Date: 42.123456789\r\n\ -Response-Date: 69.456789123\r\n"); - /* Notice how we don’t know if we’re at the end because of a missing - \r\n. */ - if (fd_source < 0) - { - abort (); - } - /* Is it the end? */ - struct disfluid_cache_entry *entry = - disfluid_cache_entry_from_fd (fd_source); - ck_assert_ptr_eq (entry, NULL); - close (fd_source); + test_check_partial_situation (16); +} +/* *INDENT-OFF* */ +END_TEST + +/* *INDENT-ON* */ + +START_TEST (test_read_cache_file_partial_17) +/* *INDENT-ON* */ +{ + test_check_partial_situation (17); +} +/* *INDENT-OFF* */ +END_TEST +/* *INDENT-ON* */ + +/* *INDENT-ON* */ +START_TEST (test_read_cache_file_partial_28) +/* *INDENT-ON* */ +{ + test_check_partial_situation (28); +} +/* *INDENT-OFF* */ +END_TEST +/* *INDENT-ON* */ + +/* *INDENT-ON* */ +START_TEST (test_read_cache_file_partial_29) +/* *INDENT-ON* */ +{ + test_check_partial_situation (29); +} +/* *INDENT-OFF* */ +END_TEST +/* *INDENT-ON* */ + +/* *INDENT-ON* */ +START_TEST (test_read_cache_file_partial_36) +/* *INDENT-ON* */ +{ + test_check_partial_situation (36); +} +/* *INDENT-OFF* */ +END_TEST +/* *INDENT-ON* */ + +/* *INDENT-ON* */ +START_TEST (test_read_cache_file_partial_37) +/* *INDENT-ON* */ +{ + test_check_partial_situation (37); +} +/* *INDENT-OFF* */ +END_TEST +/* *INDENT-ON* */ + +/* *INDENT-ON* */ +START_TEST (test_read_cache_file_partial_40) +/* *INDENT-ON* */ +{ + test_check_partial_situation (40); +} +/* *INDENT-OFF* */ +END_TEST +/* *INDENT-ON* */ + +/* *INDENT-ON* */ +START_TEST (test_read_cache_file_partial_41) +/* *INDENT-ON* */ +{ + test_check_partial_situation (41); } /* *INDENT-OFF* */ END_TEST @@ -264,30 +379,84 @@ START_TEST (test_write_cache_entry) /* *INDENT-ON* */ { - int fd_dest = test_open_file_with_content ("hehe"); - if (fd_dest < 0) + uint8_t old_data[16 + 12 + 12 + 1] = { 0 }; + memcpy (old_data, "disfluid c.entry", 16); + old_data[16 + 8 - 1] = 1; + old_data[16 + 12 - 1] = 2; + old_data[16 + 12 + 8 - 1] = 3; + old_data[16 + 12 + 12 - 1] = 4; + old_data[16 + 12 + 12 + 1 - 1] = 0x80; + /* The old data has a request date of 1s + 2ns, response of 3s + + 4ns, and is invalidated. */ + char *filename = + test_tmp_file_name_with_content (sizeof (old_data) / sizeof (old_data[0]), + old_data); + if (filename == NULL) + { + abort (); + } + char *filename_backup = malloc (strlen (filename) + strlen ("~") + 1); + if (filename_backup == NULL) { abort (); } - struct disfluid_cache_entry *entry = disfluid_cache_entry_alloc (); + strcpy (filename_backup, filename); + strcat (filename_backup, "~"); + struct disfluid_cache_entry *entry = cache_entry_alloc (); if (entry == NULL) { abort (); } - const struct timespec rq = { - .tv_sec = 123, - .tv_nsec = 456 - }; - const struct timespec rs = { - .tv_sec = 789, - .tv_nsec = 101112 - }; - disfluid_cache_entry_set_request_date (entry, &rq); - disfluid_cache_entry_set_response_date (entry, &rs); - int error = disfluid_cache_entry_save_other_fd (entry, fd_dest); + struct timespec request, response; + request.tv_sec = 10; + request.tv_nsec = 11; + response.tv_sec = 12; + response.tv_nsec = 13; + cache_entry_set_request_date (entry, &request); + cache_entry_set_response_date (entry, &response); + cache_entry_set_invalidated (entry, false); + int error = cache_entry_save (entry, filename); ck_assert_int_eq (error, 0); - disfluid_cache_entry_free (entry); - close (fd_dest); + uint8_t check_backup_data[16 + 12 + 12 + 1]; + uint8_t check_data[16 + 12 + 12 + 1]; + assert (sizeof (check_data) == sizeof (old_data)); + assert (sizeof (check_backup_data) == sizeof (old_data)); + bool file_incomplete, backup_file_incomplete; + int fd = open (filename, O_RDONLY, 0); + int fd_backup = open (filename_backup, O_RDONLY, 0); + if (fd < 0 || fd_backup < 0) + { + abort (); + } + int check_error = + (cache_entry_really_read_n + (fd, sizeof (check_data) / sizeof (check_data[0]), check_data, + &file_incomplete) != 0); + int check_backup_error = + (cache_entry_really_read_n + (fd_backup, sizeof (check_backup_data) / sizeof (check_backup_data[0]), + check_backup_data, &backup_file_incomplete) != 0); + ck_assert_int_eq (check_error, 0); + ck_assert_int_eq (check_backup_error, 0); + ck_assert (!file_incomplete); + ck_assert (!backup_file_incomplete); + ck_assert_int_eq (memcmp (check_data, "disfluid c.entry", 16), 0); + ck_assert_int_eq (check_data[16 + 8 - 1], 10); + ck_assert_int_eq (check_data[16 + 12 - 1], 11); + ck_assert_int_eq (check_data[16 + 12 + 8 - 1], 12); + ck_assert_int_eq (check_data[16 + 12 + 12 - 1], 13); + ck_assert_int_eq (check_data[16 + 12 + 12 + 1 - 1], 0); + ck_assert_int_eq (memcmp + (check_backup_data, old_data, + sizeof (check_backup_data) / + sizeof (check_backup_data[0])), 0); + close (fd); + close (fd_backup); + remove (filename); + remove (filename_backup); + cache_entry_free (entry); + free (filename_backup); + free (filename); } /* *INDENT-OFF* */ END_TEST @@ -327,13 +496,20 @@ run_tests (size_t *n_tests, size_t *n_errors) tcase_add_test (general, test_check_version); suite_add_tcase (suite, general); TCase *cache_entry = tcase_create (_("disfluid cache entry files")); - tcase_add_test (cache_entry, test_read_invalid_cache_entry_file); - tcase_add_test (cache_entry, test_read_cache_entry_no_date); - tcase_add_test (cache_entry, test_read_cache_entry_whole_seconds); - tcase_add_test (cache_entry, test_read_cache_entry_whole_seconds_dot); - tcase_add_test (cache_entry, test_read_cache_entry_milliseconds); - tcase_add_test (cache_entry, test_read_cache_entry_precise); - tcase_add_test (cache_entry, test_read_cache_entry_ambiguous); + tcase_add_test (cache_entry, test_read_invalid_magic_number); + tcase_add_test (cache_entry, test_read_inexistent_file); + tcase_add_test (cache_entry, test_read_inexistent_file_with_valid_backup); + tcase_add_test (cache_entry, test_read_file_with_valid_backup); + tcase_add_test (cache_entry, test_read_cache_file_partial_0); + tcase_add_test (cache_entry, test_read_cache_file_partial_1); + tcase_add_test (cache_entry, test_read_cache_file_partial_16); + tcase_add_test (cache_entry, test_read_cache_file_partial_17); + tcase_add_test (cache_entry, test_read_cache_file_partial_28); + tcase_add_test (cache_entry, test_read_cache_file_partial_29); + tcase_add_test (cache_entry, test_read_cache_file_partial_36); + tcase_add_test (cache_entry, test_read_cache_file_partial_37); + tcase_add_test (cache_entry, test_read_cache_file_partial_40); + tcase_add_test (cache_entry, test_read_cache_file_partial_41); tcase_add_test (cache_entry, test_write_cache_entry); suite_add_tcase (suite, cache_entry); SRunner *runner = srunner_create (suite); |