gboolean assert_string_array_non_fatal(gchar **actual, guint32 actual_length, gchar **expected, guint32 expected_length, const gchar *error_message, ...) { va_list args; gboolean assertion_ok = TRUE; guint32 i; va_start(args, error_message); assertion_ok = compare_arrays_trivially((void *)actual, actual_length, (void *)expected, expected_length, error_message, args); if (assertion_ok) { for (i = 0; i < expected_length; ++i) { if (!are_strings_equal(actual[i], expected[i])) { print_failure(error_message, args, "actual=" PRETTY_STRING_FORMAT ", expected=" PRETTY_STRING_FORMAT ", index=%u", PRETTY_STRING(actual[i]), PRETTY_STRING(expected[i]), i); assertion_ok = FALSE; break; } } } va_end(args); return assertion_ok; }
gboolean assert_guint32_array_non_fatal(guint32 *actual, guint32 actual_length, guint32 *expected, guint32 expected_length, const gchar *error_message, ...) { va_list args; gboolean assertion_ok = TRUE; guint32 i; va_start(args, error_message); assertion_ok = compare_arrays_trivially((void *)actual, actual_length, (void *)expected, expected_length, error_message, args); if (assertion_ok) { for (i = 0; i < expected_length; ++i) { if (expected[i] != actual[i]) { print_failure(error_message, args, "actual=%u, expected=%u, index=%u", actual[i], expected[i], i); assertion_ok = FALSE; break; } } } va_end(args); return assertion_ok; }
gboolean assert_grabbed_messages_contain_non_fatal(const gchar *pattern, const gchar *error_message, ...) { GList *l; va_list args; for (l = internal_messages; l; l = l->next) { LogMessage *msg = (LogMessage *) l->data; const gchar *msg_text = log_msg_get_value(msg, LM_V_MESSAGE, NULL); if (strstr(msg_text, pattern)) { return TRUE; } } va_start(args, error_message); print_failure(error_message, args, "no grabbed message contains the pattern=%s", pattern); va_end(args); fprintf(stderr, " # Grabbed internal messages follow:\n"); for (l = internal_messages; l; l = l->next) { LogMessage *msg = (LogMessage *) l->data; const gchar *msg_text = log_msg_get_value(msg, LM_V_MESSAGE, NULL); fprintf(stderr, " #\t%s\n", msg_text); } return FALSE; }
static gboolean compare_arrays_trivially(void *actual, guint32 actual_length, void *expected, guint32 expected_length, const gchar *error_message_template, va_list error_message_args) { if (expected_length != actual_length) { print_failure(error_message_template, error_message_args, "actual_length=%u, expected_length=%u", actual_length, expected_length); return FALSE; } if (expected_length > 0 && actual == NULL) { print_failure(error_message_template, error_message_args, "actual=NULL, expected_length=%u", expected_length); return FALSE; } return TRUE; }
gboolean assert_gpointer_non_fatal(gpointer actual, gpointer expected, const gchar *error_message, ...) { va_list args; if (actual == expected) return TRUE; va_start(args, error_message); print_failure(error_message, args, "actual=%x, expected=%x", actual, expected); va_end(args); return FALSE; }
gboolean assert_no_error_non_fatal(GError *error, const gchar *error_message, ...) { va_list args; if (error == NULL) return TRUE; va_start(args, error_message); print_failure(error_message, args, "GError expected to be NULL; message='%s'", error->message); va_end(args); return FALSE; }
gboolean assert_not_null_non_fatal(void *pointer, const gchar *error_message, ...) { va_list args; if (pointer != NULL) return TRUE; va_start(args, error_message); print_failure(error_message, args, "Unexpected NULL pointer"); va_end(args); return FALSE; }
gboolean assert_null_non_fatal(void *pointer, const gchar *error_message, ...) { va_list args; if (pointer == NULL) return TRUE; va_start(args, error_message); print_failure(error_message, args, "Pointer expected to be NULL; pointer=%llx", (guint64)pointer); va_end(args); return FALSE; }
gboolean assert_gboolean_non_fatal(gboolean actual, gboolean expected, const gchar *error_message, ...) { va_list args; if (actual == expected) return TRUE; va_start(args, error_message); print_failure(error_message, args, "actual=%s, expected=%s", gboolean_to_string(actual), gboolean_to_string(expected)); va_end(args); return FALSE; }
static gboolean assert_nstring_non_fatal_va(const gchar *actual, gint actual_len, const gchar *expected, gint expected_len, const gchar *error_message, va_list args) { if (expected == NULL && actual == NULL) return TRUE; if (actual && actual_len < 0) actual_len = strlen(actual); if (expected && expected_len < 0) expected_len = strlen(expected); if (actual_len == expected_len && actual != NULL && expected != NULL && memcmp(actual, expected, actual_len) == 0) return TRUE; print_failure(error_message, args, "actual=" PRETTY_NSTRING_FORMAT ", expected=" PRETTY_NSTRING_FORMAT " actual_length=%d expected_length=%d", PRETTY_NSTRING(actual, actual_len), PRETTY_NSTRING(expected, expected_len), actual_len, expected_len); return FALSE; }
gboolean assert_guint32_set_non_fatal(guint32 *actual, guint32 actual_length, guint32 *expected, guint32 expected_length, const gchar *error_message, ...) { va_list args; gboolean ret; if (actual_length != expected_length) { va_start(args, error_message); print_failure(error_message, args, "actual_length='%d', expected_length='%d'", actual_length, expected_length); va_end(args); return FALSE; } qsort(actual, actual_length, sizeof(guint32), cmp_guint32); qsort(expected, expected_length, sizeof(guint32), cmp_guint32); va_start(args, error_message); ret = assert_guint32_array(actual, actual_length, expected, expected_length, error_message, args); va_end(args); return ret; }
int main(int argc, char *argv[]) { int ret = THP_FAILURE; pid_t child; siginfo_t sig; /* * 1. Options check. */ get_options_or_die(argc, argv); /* Fork a child process for test */ child = fork(); if (child < 0) { print_err("Failed to fork child process.\n"); return THP_FAILURE; } if (child == 0) { /* Child process */ int ret = THP_FAILURE; signal(SIGBUS, SIG_DFL); /* * 2. Groundwork for hwpoison injection. */ if (prep_memory_map() == THP_FAILURE) _exit(1); if (prep_injection() == THP_FAILURE) goto free_mem; /* Print the prepared information before hwpoison injection. */ print_prep_info(); /* * 3. Hwpoison Injection. */ if (do_injection() == THP_FAILURE) goto free_mem; if (post_injection() == THP_FAILURE) goto free_mem; ret = THP_SUCCESS; free_mem: post_memory_map(); if (ret == THP_SUCCESS) _exit(0); _exit(1); } /* Parent process */ if (waitid(P_PID, child, &sig, WEXITED) < 0) { print_err("Failed to wait child process.\n"); return THP_FAILURE; } /* * 4. Check the result of hwpoison injection. */ if (avoid_touch) { if (sig.si_code == CLD_EXITED && sig.si_status == 0) { print_success("Child process survived.\n"); ret = THP_SUCCESS; } else print_failure("Child process could not survive.\n"); } else { if ((sig.si_code & (CLD_KILLED|CLD_DUMPED)) && sig.si_status == SIGBUS) { print_success("Child process was killed by SIGBUS.\n"); ret = THP_SUCCESS; } else print_failure("Child process could not be killed" " by SIGBUS.\n"); } return ret; }