#ifndef AKERR_TEST_CAPTURE_H #define AKERR_TEST_CAPTURE_H /* * Shared test helpers for libakerror. * * Installs a capturing implementation of akerr_log_method so tests can assert * on the *content* of log/stacktrace output (messages, status codes, error * names) instead of relying solely on process exit codes. * * Also provides AKERR_CHECK(), a NDEBUG-proof assertion that fails the test by * returning non-zero from main() (unlike assert(), which is compiled out in * release builds and would silently turn a test into a no-op). */ #include "akerror.h" #include #include #include #define AKERR_CAPTURE_BUFSZ 65536 static char akerr_capture_buf[AKERR_CAPTURE_BUFSZ]; static size_t akerr_capture_len = 0; static void __attribute__((unused)) akerr_capture_logger(const char *fmt, ...) { va_list ap; va_start(ap, fmt); int n = vsnprintf(akerr_capture_buf + akerr_capture_len, AKERR_CAPTURE_BUFSZ - akerr_capture_len, fmt, ap); va_end(ap); if ( n > 0 ) { akerr_capture_len += (size_t)n; if ( akerr_capture_len >= AKERR_CAPTURE_BUFSZ ) { akerr_capture_len = AKERR_CAPTURE_BUFSZ - 1; } } } static void __attribute__((unused)) akerr_capture_reset(void) { akerr_capture_len = 0; akerr_capture_buf[0] = '\0'; } /* * Install the capturing logger. akerr_init() only assigns a default logger when * akerr_log_method is NULL, and it is idempotent, so calling this either before * or after the first PREPARE_ERROR keeps our logger in place. */ static void __attribute__((unused)) akerr_capture_install(void) { akerr_capture_reset(); akerr_log_method = &akerr_capture_logger; } /* Count array slots currently checked out of the pool (refcount != 0). */ static int __attribute__((unused)) akerr_slots_in_use(void) { int n = 0; for ( int i = 0; i < AKERR_MAX_ARRAY_ERROR; i++ ) { if ( AKERR_ARRAY_ERROR[i].refcount != 0 ) { n++; } } return n; } #define AKERR_CHECK(cond) \ do { \ if ( !(cond) ) { \ fprintf(stderr, "CHECK FAILED: %s at %s:%d\n", \ #cond, __FILE__, __LINE__); \ return 1; \ } \ } while ( 0 ) #define AKERR_CHECK_CONTAINS(needle) \ AKERR_CHECK(strstr(akerr_capture_buf, (needle)) != NULL) #define AKERR_CHECK_NOT_CONTAINS(needle) \ AKERR_CHECK(strstr(akerr_capture_buf, (needle)) == NULL) #endif // AKERR_TEST_CAPTURE_H