tests: eloop socket re-open from timeout/socket handler
Signed-off-by: Jouni Malinen <jouni@qca.qualcomm.com>
This commit is contained in:
parent
48b06c17fa
commit
569f8f9b87
2 changed files with 258 additions and 1 deletions
|
@ -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;
|
||||
|
||||
|
|
|
@ -4,12 +4,22 @@
|
|||
# This software may be distributed under the terms of the BSD license.
|
||||
# See README for more details.
|
||||
|
||||
import os
|
||||
import time
|
||||
|
||||
import hostapd
|
||||
|
||||
def test_module_wpa_supplicant(dev):
|
||||
def test_module_wpa_supplicant(dev, apdev, params):
|
||||
"""wpa_supplicant module tests"""
|
||||
if "OK" not in dev[0].global_request("MODULE_TESTS"):
|
||||
raise Exception("Module tests failed")
|
||||
# allow eloop test to complete
|
||||
time.sleep(0.75)
|
||||
dev[0].relog()
|
||||
with open(os.path.join(params['logdir'], 'log0'), 'r') as f:
|
||||
res = f.read()
|
||||
if "FAIL - should not have called this function" in res:
|
||||
raise Exception("eloop test failed")
|
||||
|
||||
def test_module_hostapd(dev):
|
||||
"""hostapd module tests"""
|
||||
|
|
Loading…
Reference in a new issue