[PATCH 34/42] os: allow multiple failures in one test
Andrei Otcheretianski
andrei.otcheretianski at intel.com
Mon Nov 20 15:51:48 PST 2023
From: Benjamin Berg <benjamin.berg at intel.com>
Refactor the backtrace matching a bit in order to allow triggering
multiple failures in one test.
Signed-off-by: Benjamin Berg <benjamin.berg at intel.com>
---
hostapd/ctrl_iface.c | 77 +---------------
src/utils/os.h | 20 +++--
src/utils/os_unix.c | 170 ++++++++++++++++--------------------
wpa_supplicant/ctrl_iface.c | 74 +---------------
4 files changed, 98 insertions(+), 243 deletions(-)
diff --git a/hostapd/ctrl_iface.c b/hostapd/ctrl_iface.c
index 6ad86142e6..8d34cf1627 100644
--- a/hostapd/ctrl_iface.c
+++ b/hostapd/ctrl_iface.c
@@ -2006,74 +2006,6 @@ done:
}
-static int hostapd_ctrl_test_alloc_fail(struct hostapd_data *hapd, char *cmd)
-{
-#ifdef WPA_TRACE_BFD
- char *pos;
-
- wpa_trace_fail_after = atoi(cmd);
- pos = os_strchr(cmd, ':');
- if (pos) {
- pos++;
- os_strlcpy(wpa_trace_fail_func, pos,
- sizeof(wpa_trace_fail_func));
- } else {
- wpa_trace_fail_after = 0;
- }
-
- return 0;
-#else /* WPA_TRACE_BFD */
- return -1;
-#endif /* WPA_TRACE_BFD */
-}
-
-
-static int hostapd_ctrl_get_alloc_fail(struct hostapd_data *hapd,
- char *buf, size_t buflen)
-{
-#ifdef WPA_TRACE_BFD
- return os_snprintf(buf, buflen, "%u:%s", wpa_trace_fail_after,
- wpa_trace_fail_func);
-#else /* WPA_TRACE_BFD */
- return -1;
-#endif /* WPA_TRACE_BFD */
-}
-
-
-static int hostapd_ctrl_test_fail(struct hostapd_data *hapd, char *cmd)
-{
-#ifdef WPA_TRACE_BFD
- char *pos;
-
- wpa_trace_test_fail_after = atoi(cmd);
- pos = os_strchr(cmd, ':');
- if (pos) {
- pos++;
- os_strlcpy(wpa_trace_test_fail_func, pos,
- sizeof(wpa_trace_test_fail_func));
- } else {
- wpa_trace_test_fail_after = 0;
- }
-
- return 0;
-#else /* WPA_TRACE_BFD */
- return -1;
-#endif /* WPA_TRACE_BFD */
-}
-
-
-static int hostapd_ctrl_get_fail(struct hostapd_data *hapd,
- char *buf, size_t buflen)
-{
-#ifdef WPA_TRACE_BFD
- return os_snprintf(buf, buflen, "%u:%s", wpa_trace_test_fail_after,
- wpa_trace_test_fail_func);
-#else /* WPA_TRACE_BFD */
- return -1;
-#endif /* WPA_TRACE_BFD */
-}
-
-
static int hostapd_ctrl_reset_pn(struct hostapd_data *hapd, const char *cmd)
{
struct sta_info *sta;
@@ -3704,16 +3636,15 @@ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
if (hostapd_ctrl_iface_data_test_frame(hapd, buf + 16) < 0)
reply_len = -1;
} else if (os_strncmp(buf, "TEST_ALLOC_FAIL ", 16) == 0) {
- if (hostapd_ctrl_test_alloc_fail(hapd, buf + 16) < 0)
+ if (testing_set_fail_pattern(true, buf + 16) < 0)
reply_len = -1;
} else if (os_strcmp(buf, "GET_ALLOC_FAIL") == 0) {
- reply_len = hostapd_ctrl_get_alloc_fail(hapd, reply,
- reply_size);
+ reply_len = testing_get_fail_pattern(true, reply, reply_size);
} else if (os_strncmp(buf, "TEST_FAIL ", 10) == 0) {
- if (hostapd_ctrl_test_fail(hapd, buf + 10) < 0)
+ if (testing_set_fail_pattern(false, buf + 10) < 0)
reply_len = -1;
} else if (os_strcmp(buf, "GET_FAIL") == 0) {
- reply_len = hostapd_ctrl_get_fail(hapd, reply, reply_size);
+ reply_len = testing_get_fail_pattern(false, reply, reply_size);
} else if (os_strncmp(buf, "RESET_PN ", 9) == 0) {
if (hostapd_ctrl_reset_pn(hapd, buf + 9) < 0)
reply_len = -1;
diff --git a/src/utils/os.h b/src/utils/os.h
index 21ba5c3ff8..83d5ad99b2 100644
--- a/src/utils/os.h
+++ b/src/utils/os.h
@@ -667,14 +667,22 @@ int os_exec(const char *program, const char *arg, int wait_completion);
#if defined(WPA_TRACE_BFD) && defined(CONFIG_TESTING_OPTIONS)
-#define TEST_FAIL() testing_test_fail()
-int testing_test_fail(void);
-extern char wpa_trace_fail_func[256];
-extern unsigned int wpa_trace_fail_after;
-extern char wpa_trace_test_fail_func[256];
-extern unsigned int wpa_trace_test_fail_after;
+#define TEST_FAIL() testing_test_fail(false)
+int testing_test_fail(bool is_alloc);
+int testing_set_fail_pattern(bool is_alloc, char *patterns);
+int testing_get_fail_pattern(bool is_alloc, char *buf, size_t buflen);
#else
#define TEST_FAIL() 0
+static inline int testing_set_fail_pattern(bool is_alloc, char *patterns)
+{
+ return -1;
+}
+
+static inline int testing_get_fail_pattern(bool is_alloc, char *buf,
+ size_t buflen)
+{
+ return -1;
+}
#endif
#endif /* OS_H */
diff --git a/src/utils/os_unix.c b/src/utils/os_unix.c
index 258deef9dd..d9664b0f79 100644
--- a/src/utils/os_unix.c
+++ b/src/utils/os_unix.c
@@ -540,39 +540,46 @@ void * os_memdup(const void *src, size_t len)
#ifdef WPA_TRACE
#if defined(WPA_TRACE_BFD) && defined(CONFIG_TESTING_OPTIONS)
-char wpa_trace_fail_func[256] = { 0 };
-unsigned int wpa_trace_fail_after;
+struct wpa_trace_test_fail {
+ unsigned int fail_after;
+ char pattern[256];
+} wpa_trace_test_fail[5][2];
-static int testing_fail_alloc(void)
+int testing_test_fail(bool is_alloc)
{
+ const char *ignore_list[] = {
+ __func__, "os_malloc", "os_zalloc", "os_calloc", "os_realloc",
+ "os_realloc_array", "os_strdup", "os_memdup"
+ };
const char *func[WPA_TRACE_LEN];
- size_t i, res, len;
+ size_t i, j, res, len, idx;
char *pos, *next;
int match;
- if (!wpa_trace_fail_after)
+ is_alloc = !!is_alloc;
+
+ for (idx = 0; idx < ARRAY_SIZE(wpa_trace_test_fail[is_alloc]); idx++) {
+ if (wpa_trace_test_fail[is_alloc][idx].fail_after != 0)
+ break;
+ }
+ if (idx >= ARRAY_SIZE(wpa_trace_test_fail[is_alloc]))
return 0;
res = wpa_trace_calling_func(func, WPA_TRACE_LEN);
i = 0;
- if (i < res && os_strcmp(func[i], __func__) == 0)
- i++;
- if (i < res && os_strcmp(func[i], "os_malloc") == 0)
- i++;
- if (i < res && os_strcmp(func[i], "os_zalloc") == 0)
- i++;
- if (i < res && os_strcmp(func[i], "os_calloc") == 0)
- i++;
- if (i < res && os_strcmp(func[i], "os_realloc") == 0)
- i++;
- if (i < res && os_strcmp(func[i], "os_realloc_array") == 0)
- i++;
- if (i < res && os_strcmp(func[i], "os_strdup") == 0)
- i++;
- if (i < res && os_strcmp(func[i], "os_memdup") == 0)
- i++;
- pos = wpa_trace_fail_func;
+ /* Skip this function as well as allocation helpers */
+ for (j = 0; j < ARRAY_SIZE(ignore_list) && i < res; j++) {
+ if (os_strcmp(func[i], ignore_list[j]) == 0)
+ i++;
+ }
+
+ pos = wpa_trace_test_fail[is_alloc][idx].pattern;
+
+ /* The prefixes mean:
+ * - '=': The function needs to be next in the backtrace
+ * - '?': The function is optionally present in the backtrace
+ */
match = 0;
while (i < res) {
@@ -612,10 +619,10 @@ static int testing_fail_alloc(void)
if (!match)
return 0;
- wpa_trace_fail_after--;
- if (wpa_trace_fail_after == 0) {
- wpa_printf(MSG_INFO, "TESTING: fail allocation at %s",
- wpa_trace_fail_func);
+ wpa_trace_test_fail[is_alloc][idx].fail_after--;
+ if (wpa_trace_test_fail[is_alloc][idx].fail_after == 0) {
+ wpa_printf(MSG_INFO, "TESTING: fail at %s",
+ wpa_trace_test_fail[is_alloc][idx].pattern);
for (i = 0; i < res; i++)
wpa_printf(MSG_INFO, "backtrace[%d] = %s",
(int) i, func[i]);
@@ -625,83 +632,58 @@ static int testing_fail_alloc(void)
return 0;
}
-
-char wpa_trace_test_fail_func[256] = { 0 };
-unsigned int wpa_trace_test_fail_after;
-
-int testing_test_fail(void)
+int testing_set_fail_pattern(bool is_alloc, char *patterns)
{
- const char *func[WPA_TRACE_LEN];
- size_t i, res, len;
- char *pos, *next;
- int match;
+ char *token, *context = NULL;
+ size_t idx;
+
+ is_alloc = !!is_alloc;
+
+ os_memset(wpa_trace_test_fail[is_alloc], 0,
+ sizeof(wpa_trace_test_fail[is_alloc]));
+
+ idx = 0;
+ while ((token = str_token(patterns, " \n\r\t", &context)) &&
+ idx < ARRAY_SIZE(wpa_trace_test_fail[is_alloc])) {
+ wpa_trace_test_fail[is_alloc][idx].fail_after = atoi(token);
+ token = os_strchr(token, ':');
+ if (!token) {
+ os_memset(wpa_trace_test_fail[is_alloc], 0,
+ sizeof(wpa_trace_test_fail[is_alloc]));
+ return -1;
+ }
- if (!wpa_trace_test_fail_after)
- return 0;
+ os_strlcpy(wpa_trace_test_fail[is_alloc][idx].pattern,
+ token + 1,
+ sizeof(wpa_trace_test_fail[is_alloc][0].pattern));
+ idx++;
+ }
- res = wpa_trace_calling_func(func, WPA_TRACE_LEN);
- i = 0;
- if (i < res && os_strcmp(func[i], __func__) == 0)
- i++;
+ return 0;
+}
- pos = wpa_trace_test_fail_func;
+int testing_get_fail_pattern(bool is_alloc, char *buf, size_t buflen)
+{
+ size_t idx, ret;
+ char *pos = buf;
+ char *end = buf + buflen;
- match = 0;
- while (i < res) {
- int allow_skip = 1;
- int maybe = 0;
+ is_alloc = !!is_alloc;
- if (*pos == '=') {
- allow_skip = 0;
- pos++;
- } else if (*pos == '?') {
- maybe = 1;
- pos++;
- }
- next = os_strchr(pos, ';');
- if (next)
- len = next - pos;
- else
- len = os_strlen(pos);
- if (os_memcmp(pos, func[i], len) != 0) {
- if (maybe && next) {
- pos = next + 1;
- continue;
- }
- if (allow_skip) {
- i++;
- continue;
- }
- return 0;
- }
- if (!next) {
- match = 1;
+ for (idx = 0; idx < ARRAY_SIZE(wpa_trace_test_fail[is_alloc]); idx++) {
+ if (wpa_trace_test_fail[is_alloc][idx].pattern[0] == '\0')
break;
- }
- pos = next + 1;
- i++;
- }
- if (!match)
- return 0;
- wpa_trace_test_fail_after--;
- if (wpa_trace_test_fail_after == 0) {
- wpa_printf(MSG_INFO, "TESTING: fail at %s",
- wpa_trace_test_fail_func);
- for (i = 0; i < res; i++)
- wpa_printf(MSG_INFO, "backtrace[%d] = %s",
- (int) i, func[i]);
- return 1;
+ ret = os_snprintf(pos, end - pos, "%s%u:%s",
+ pos == buf ? "" : " ",
+ wpa_trace_test_fail[is_alloc][idx].fail_after,
+ wpa_trace_test_fail[is_alloc][idx].pattern);
+ if (os_snprintf_error(end - pos, ret))
+ break;
+ pos += ret;
}
- return 0;
-}
-
-#else
-
-static inline int testing_fail_alloc(void)
-{
- return 0;
+ return pos - buf;
}
#endif
@@ -709,7 +691,7 @@ void * os_malloc(size_t size)
{
struct os_alloc_trace *a;
- if (testing_fail_alloc())
+ if (testing_test_fail(true))
return NULL;
a = malloc(sizeof(*a) + size);
diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c
index a68802e493..b716fa774e 100644
--- a/wpa_supplicant/ctrl_iface.c
+++ b/wpa_supplicant/ctrl_iface.c
@@ -10134,72 +10134,6 @@ done:
}
-static int wpas_ctrl_test_alloc_fail(struct wpa_supplicant *wpa_s, char *cmd)
-{
-#ifdef WPA_TRACE_BFD
- char *pos;
-
- wpa_trace_fail_after = atoi(cmd);
- pos = os_strchr(cmd, ':');
- if (pos) {
- pos++;
- os_strlcpy(wpa_trace_fail_func, pos,
- sizeof(wpa_trace_fail_func));
- } else {
- wpa_trace_fail_after = 0;
- }
- return 0;
-#else /* WPA_TRACE_BFD */
- return -1;
-#endif /* WPA_TRACE_BFD */
-}
-
-
-static int wpas_ctrl_get_alloc_fail(struct wpa_supplicant *wpa_s,
- char *buf, size_t buflen)
-{
-#ifdef WPA_TRACE_BFD
- return os_snprintf(buf, buflen, "%u:%s", wpa_trace_fail_after,
- wpa_trace_fail_func);
-#else /* WPA_TRACE_BFD */
- return -1;
-#endif /* WPA_TRACE_BFD */
-}
-
-
-static int wpas_ctrl_test_fail(struct wpa_supplicant *wpa_s, char *cmd)
-{
-#ifdef WPA_TRACE_BFD
- char *pos;
-
- wpa_trace_test_fail_after = atoi(cmd);
- pos = os_strchr(cmd, ':');
- if (pos) {
- pos++;
- os_strlcpy(wpa_trace_test_fail_func, pos,
- sizeof(wpa_trace_test_fail_func));
- } else {
- wpa_trace_test_fail_after = 0;
- }
- return 0;
-#else /* WPA_TRACE_BFD */
- return -1;
-#endif /* WPA_TRACE_BFD */
-}
-
-
-static int wpas_ctrl_get_fail(struct wpa_supplicant *wpa_s,
- char *buf, size_t buflen)
-{
-#ifdef WPA_TRACE_BFD
- return os_snprintf(buf, buflen, "%u:%s", wpa_trace_test_fail_after,
- wpa_trace_test_fail_func);
-#else /* WPA_TRACE_BFD */
- return -1;
-#endif /* WPA_TRACE_BFD */
-}
-
-
static void wpas_ctrl_event_test_cb(void *eloop_ctx, void *timeout_ctx)
{
struct wpa_supplicant *wpa_s = eloop_ctx;
@@ -12886,15 +12820,15 @@ char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s,
if (wpas_ctrl_iface_data_test_frame(wpa_s, buf + 16) < 0)
reply_len = -1;
} else if (os_strncmp(buf, "TEST_ALLOC_FAIL ", 16) == 0) {
- if (wpas_ctrl_test_alloc_fail(wpa_s, buf + 16) < 0)
+ if (testing_set_fail_pattern(true, buf + 16) < 0)
reply_len = -1;
} else if (os_strcmp(buf, "GET_ALLOC_FAIL") == 0) {
- reply_len = wpas_ctrl_get_alloc_fail(wpa_s, reply, reply_size);
+ reply_len = testing_get_fail_pattern(true, reply, reply_size);
} else if (os_strncmp(buf, "TEST_FAIL ", 10) == 0) {
- if (wpas_ctrl_test_fail(wpa_s, buf + 10) < 0)
+ if (testing_set_fail_pattern(false, buf + 10) < 0)
reply_len = -1;
} else if (os_strcmp(buf, "GET_FAIL") == 0) {
- reply_len = wpas_ctrl_get_fail(wpa_s, reply, reply_size);
+ reply_len = testing_get_fail_pattern(false, reply, reply_size);
} else if (os_strncmp(buf, "EVENT_TEST ", 11) == 0) {
if (wpas_ctrl_event_test(wpa_s, buf + 11) < 0)
reply_len = -1;
--
2.38.1
More information about the Hostap
mailing list