diff options
Diffstat (limited to 'tests/snapshot_failure_test.c')
| -rw-r--r-- | tests/snapshot_failure_test.c | 91 |
1 files changed, 91 insertions, 0 deletions
diff --git a/tests/snapshot_failure_test.c b/tests/snapshot_failure_test.c new file mode 100644 index 0000000..4133bfd --- /dev/null +++ b/tests/snapshot_failure_test.c @@ -0,0 +1,91 @@ +#include "term/term.h" + +#include <assert.h> +#include <stdbool.h> +#include <stddef.h> +#include <stdlib.h> + +static bool fail_next_realloc; +static int malloc_failure_countdown = -1; +static bool malloc_was_failed; +void *__real_malloc(size_t); +void *__wrap_malloc(size_t size) +{ + if (malloc_failure_countdown >= 0) { + if (malloc_failure_countdown-- == 0) { + malloc_failure_countdown = -1; + malloc_was_failed = true; + return NULL; + } + } + return __real_malloc(size); +} + +void *__real_realloc(void *, size_t); +void *__wrap_realloc(void *p, size_t size) +{ + if (fail_next_realloc) { + fail_next_realloc = false; + return NULL; + } + return __real_realloc(p, size); +} + +int main(void) +{ + struct term_options options = { .size = { 8, 3 }, .scrollback = 5 }; + struct term *term = term_new(&options); + struct term_snapshot *snapshot = term_snapshot_new(); + assert(term && snapshot && term_snapshot_update(snapshot, term)); + + const char accented[] = "e\xcc\x81"; + term_feed(term, accented, sizeof(accented) - 1, 0); + fail_next_realloc = true; + assert(!term_snapshot_update(snapshot, term)); + assert(!fail_next_realloc); + assert(term_snapshot_view(snapshot)->size.x == 0); + assert(term_snapshot_view(snapshot)->size.y == 0); + assert(term_snapshot_row(snapshot, 0) == NULL); + + assert(term_snapshot_update(snapshot, term)); + const struct term_cell *row = term_snapshot_row(snapshot, 0); + assert(row); + uint32_t cps[4]; + assert(term_snapshot_cluster(snapshot, row[0].text, cps, 4) == 2); + assert(cps[0] == 'e' && cps[1] == 0x301); + + term_snapshot_free(snapshot); + term_free(term); + + /* More than 256 rows moves both temporary arrays off the stack. */ + options.size.y = 300; + term = term_new(&options); + snapshot = term_snapshot_new(); + assert(term && snapshot && term_snapshot_update(snapshot, term)); + + /* Fail new_keys allocation, then make sure retry fills all rows. */ + malloc_was_failed = false; + malloc_failure_countdown = 0; + assert(!term_snapshot_update(snapshot, term)); + assert(malloc_was_failed); + assert(term_snapshot_view(snapshot)->size.y == 0); + assert(term_snapshot_row(snapshot, 0) == NULL); + assert(term_snapshot_update(snapshot, term)); + assert(term_snapshot_view(snapshot)->size.y == 300); + assert(term_snapshot_row(snapshot, 299)); + + /* The first malloc is new_keys; fail the following selection-span array. */ + malloc_was_failed = false; + malloc_failure_countdown = 1; + assert(!term_snapshot_update(snapshot, term)); + assert(malloc_was_failed); + assert(term_snapshot_view(snapshot)->size.y == 0); + assert(term_snapshot_row(snapshot, 0) == NULL); + assert(term_snapshot_update(snapshot, term)); + assert(term_snapshot_view(snapshot)->size.y == 300); + assert(term_snapshot_row(snapshot, 299)); + + term_snapshot_free(snapshot); + term_free(term); + return 0; +} |
