aboutsummaryrefslogtreecommitdiffstats
path: root/src/utils
diff options
context:
space:
mode:
authorJouni Malinen <jouni@qca.qualcomm.com>2015-07-23 15:39:02 (GMT)
committerJouni Malinen <j@w1.fi>2015-07-23 15:39:02 (GMT)
commit569f8f9b870bf3b458a65d9030cb62fbcb3cc7e2 (patch)
tree823d5371c415879df575c84b4edf60f3c4e78230 /src/utils
parent48b06c17fa982cf8174fbd94d7a8e85dc7fa5054 (diff)
downloadhostap-569f8f9b870bf3b458a65d9030cb62fbcb3cc7e2.zip
hostap-569f8f9b870bf3b458a65d9030cb62fbcb3cc7e2.tar.gz
hostap-569f8f9b870bf3b458a65d9030cb62fbcb3cc7e2.tar.bz2
tests: eloop socket re-open from timeout/socket handler
Signed-off-by: Jouni Malinen <jouni@qca.qualcomm.com>
Diffstat (limited to 'src/utils')
-rw-r--r--src/utils/utils_module_tests.c247
1 files changed, 247 insertions, 0 deletions
diff --git a/src/utils/utils_module_tests.c b/src/utils/utils_module_tests.c
index c0ca4a5..41511b9 100644
--- a/src/utils/utils_module_tests.c
+++ b/src/utils/utils_module_tests.c
@@ -15,6 +15,7 @@
#include "utils/trace.h"
#include "utils/base64.h"
#include "utils/ip_addr.h"
+#include "utils/eloop.h"
struct printf_test_data {
@@ -592,6 +593,251 @@ static int ip_addr_tests(void)
}
+struct test_eloop {
+ unsigned int magic;
+ int close_in_timeout;
+ int pipefd1[2];
+ int pipefd2[2];
+};
+
+
+static void eloop_tests_start(int close_in_timeout);
+
+
+static void eloop_test_read_2(int sock, void *eloop_ctx, void *sock_ctx)
+{
+ struct test_eloop *t = eloop_ctx;
+ ssize_t res;
+ char buf[10];
+
+ wpa_printf(MSG_INFO, "%s: sock=%d", __func__, sock);
+
+ if (t->magic != 0x12345678) {
+ wpa_printf(MSG_INFO, "%s: unexpected magic 0x%x",
+ __func__, t->magic);
+ }
+
+ if (t->pipefd2[0] != sock) {
+ wpa_printf(MSG_INFO, "%s: unexpected sock %d != %d",
+ __func__, sock, t->pipefd2[0]);
+ }
+
+ res = read(sock, buf, sizeof(buf));
+ wpa_printf(MSG_INFO, "%s: sock=%d --> res=%d",
+ __func__, sock, (int) res);
+}
+
+
+static void eloop_test_read_2_wrong(int sock, void *eloop_ctx, void *sock_ctx)
+{
+ struct test_eloop *t = eloop_ctx;
+
+ wpa_printf(MSG_INFO, "%s: sock=%d", __func__, sock);
+
+ if (t->magic != 0x12345678) {
+ wpa_printf(MSG_INFO, "%s: unexpected magic 0x%x",
+ __func__, t->magic);
+ }
+
+ if (t->pipefd2[0] != sock) {
+ wpa_printf(MSG_INFO, "%s: unexpected sock %d != %d",
+ __func__, sock, t->pipefd2[0]);
+ }
+
+ /*
+ * This is expected to block due to the original socket with data having
+ * been closed and no new data having been written to the new socket
+ * with the same fd. To avoid blocking the process during test, skip the
+ * read here.
+ */
+ wpa_printf(MSG_ERROR, "%s: FAIL - should not have called this function",
+ __func__);
+}
+
+
+static void reopen_pipefd2(struct test_eloop *t)
+{
+ if (t->pipefd2[0] < 0) {
+ wpa_printf(MSG_INFO, "pipefd2 had been closed");
+ } else {
+ int res;
+
+ wpa_printf(MSG_INFO, "close pipefd2");
+ eloop_unregister_read_sock(t->pipefd2[0]);
+ close(t->pipefd2[0]);
+ t->pipefd2[0] = -1;
+ close(t->pipefd2[1]);
+ t->pipefd2[1] = -1;
+
+ res = pipe(t->pipefd2);
+ if (res < 0) {
+ wpa_printf(MSG_INFO, "pipe: %s", strerror(errno));
+ t->pipefd2[0] = -1;
+ t->pipefd2[1] = -1;
+ return;
+ }
+
+ wpa_printf(MSG_INFO,
+ "re-register pipefd2 with new sockets %d,%d",
+ t->pipefd2[0], t->pipefd2[1]);
+ eloop_register_read_sock(t->pipefd2[0], eloop_test_read_2_wrong,
+ t, NULL);
+ }
+}
+
+
+static void eloop_test_read_1(int sock, void *eloop_ctx, void *sock_ctx)
+{
+ struct test_eloop *t = eloop_ctx;
+ ssize_t res;
+ char buf[10];
+
+ wpa_printf(MSG_INFO, "%s: sock=%d", __func__, sock);
+
+ if (t->magic != 0x12345678) {
+ wpa_printf(MSG_INFO, "%s: unexpected magic 0x%x",
+ __func__, t->magic);
+ }
+
+ if (t->pipefd1[0] != sock) {
+ wpa_printf(MSG_INFO, "%s: unexpected sock %d != %d",
+ __func__, sock, t->pipefd1[0]);
+ }
+
+ res = read(sock, buf, sizeof(buf));
+ wpa_printf(MSG_INFO, "%s: sock=%d --> res=%d",
+ __func__, sock, (int) res);
+
+ if (!t->close_in_timeout)
+ reopen_pipefd2(t);
+}
+
+
+static void eloop_test_cb(void *eloop_data, void *user_ctx)
+{
+ struct test_eloop *t = eloop_data;
+
+ wpa_printf(MSG_INFO, "%s", __func__);
+
+ if (t->magic != 0x12345678) {
+ wpa_printf(MSG_INFO, "%s: unexpected magic 0x%x",
+ __func__, t->magic);
+ }
+
+ if (t->close_in_timeout)
+ reopen_pipefd2(t);
+}
+
+
+static void eloop_test_timeout(void *eloop_data, void *user_ctx)
+{
+ struct test_eloop *t = eloop_data;
+ int next_run = 0;
+
+ wpa_printf(MSG_INFO, "%s", __func__);
+
+ if (t->magic != 0x12345678) {
+ wpa_printf(MSG_INFO, "%s: unexpected magic 0x%x",
+ __func__, t->magic);
+ }
+
+ if (t->pipefd1[0] >= 0) {
+ wpa_printf(MSG_INFO, "pipefd1 had not been closed");
+ eloop_unregister_read_sock(t->pipefd1[0]);
+ close(t->pipefd1[0]);
+ t->pipefd1[0] = -1;
+ close(t->pipefd1[1]);
+ t->pipefd1[1] = -1;
+ }
+
+ if (t->pipefd2[0] >= 0) {
+ wpa_printf(MSG_INFO, "pipefd2 had not been closed");
+ eloop_unregister_read_sock(t->pipefd2[0]);
+ close(t->pipefd2[0]);
+ t->pipefd2[0] = -1;
+ close(t->pipefd2[1]);
+ t->pipefd2[1] = -1;
+ }
+
+ next_run = t->close_in_timeout;
+ t->magic = 0;
+ wpa_printf(MSG_INFO, "%s - free(%p)", __func__, t);
+ os_free(t);
+
+ if (next_run)
+ eloop_tests_start(0);
+}
+
+
+static void eloop_tests_start(int close_in_timeout)
+{
+ struct test_eloop *t;
+ int res;
+
+ t = os_zalloc(sizeof(*t));
+ if (!t)
+ return;
+ t->magic = 0x12345678;
+ t->close_in_timeout = close_in_timeout;
+
+ wpa_printf(MSG_INFO, "starting eloop tests (%p) (close_in_timeout=%d)",
+ t, close_in_timeout);
+
+ res = pipe(t->pipefd1);
+ if (res < 0) {
+ wpa_printf(MSG_INFO, "pipe: %s", strerror(errno));
+ os_free(t);
+ return;
+ }
+
+ res = pipe(t->pipefd2);
+ if (res < 0) {
+ wpa_printf(MSG_INFO, "pipe: %s", strerror(errno));
+ close(t->pipefd1[0]);
+ close(t->pipefd1[1]);
+ os_free(t);
+ return;
+ }
+
+ wpa_printf(MSG_INFO, "pipe fds: %d,%d %d,%d",
+ t->pipefd1[0], t->pipefd1[1],
+ t->pipefd2[0], t->pipefd2[1]);
+
+ eloop_register_read_sock(t->pipefd1[0], eloop_test_read_1, t, NULL);
+ eloop_register_read_sock(t->pipefd2[0], eloop_test_read_2, t, NULL);
+ eloop_register_timeout(0, 0, eloop_test_cb, t, NULL);
+ eloop_register_timeout(0, 200000, eloop_test_timeout, t, NULL);
+
+ if (write(t->pipefd1[1], "HELLO", 5) < 0)
+ wpa_printf(MSG_INFO, "write: %s", strerror(errno));
+ if (write(t->pipefd2[1], "TEST", 4) < 0)
+ wpa_printf(MSG_INFO, "write: %s", strerror(errno));
+ os_sleep(0, 50000);
+ wpa_printf(MSG_INFO, "waiting for eloop callbacks");
+}
+
+
+static void eloop_tests_run(void *eloop_data, void *user_ctx)
+{
+ eloop_tests_start(1);
+}
+
+
+static int eloop_tests(void)
+{
+ wpa_printf(MSG_INFO, "schedule eloop tests to be run");
+
+ /*
+ * Cannot return error from these without a significant design change,
+ * so for now, run the tests from a scheduled timeout and require
+ * separate verification of the results from the debug log.
+ */
+ eloop_register_timeout(0, 0, eloop_tests_run, NULL, NULL);
+
+ return 0;
+}
+
+
int utils_module_tests(void)
{
int ret = 0;
@@ -607,6 +853,7 @@ int utils_module_tests(void)
os_tests() < 0 ||
wpabuf_tests() < 0 ||
ip_addr_tests() < 0 ||
+ eloop_tests() < 0 ||
int_array_tests() < 0)
ret = -1;