From c1268c44a1449b109042ff1dbe3bc8fd592973ad Mon Sep 17 00:00:00 2001 From: Water-Melon Date: Thu, 25 Apr 2024 10:34:10 +0000 Subject: [PATCH] chore(tests): add more tests Modules: hash, http, iothread, ipc, json --- t/hash.c | 65 +++++++++++++++++++++++++++++++++++++++++++ t/http.c | 50 +++++++++++++++++++++++++++++++++ t/iothread.c | 46 +++++++++++++++++++++++++++++++ t/ipc.c | 78 ++++++++++++++++++++++++++++++++++++++++++++++++++++ t/json.c | 53 +++++++++++++++++++++++++++++++++++ 5 files changed, 292 insertions(+) create mode 100644 t/hash.c create mode 100644 t/http.c create mode 100644 t/iothread.c create mode 100644 t/ipc.c create mode 100644 t/json.c diff --git a/t/hash.c b/t/hash.c new file mode 100644 index 0000000..8f9a550 --- /dev/null +++ b/t/hash.c @@ -0,0 +1,65 @@ +#include +#include +#include "mln_hash.h" + +typedef struct mln_hash_test_s { + int key; + int val; +} mln_hash_test_t; + +static mln_u64_t calc_handler(mln_hash_t *h, void *key) +{ + return *((int *)key) % h->len; +} + +static int cmp_handler(mln_hash_t *h, void *key1, void *key2) +{ + return !(*((int *)key1) - *((int *)key2)); +} + +static void free_handler(void *val) +{ + free(val); +} + +int main(int argc, char *argv[]) +{ + mln_hash_t *h; + struct mln_hash_attr hattr; + mln_hash_test_t *item, *ret; + + hattr.pool = NULL; + hattr.pool_alloc = NULL; + hattr.pool_free = NULL; + hattr.hash = calc_handler; + hattr.cmp = cmp_handler; + hattr.key_freer = NULL; + hattr.val_freer = free_handler; + hattr.len_base = 97; + hattr.expandable = 0; + hattr.calc_prime = 0; + + if ((h = mln_hash_new(&hattr)) == NULL) { + fprintf(stderr, "Hash init failed.\n"); + return -1; + } + + item = (mln_hash_test_t *)malloc(sizeof(mln_hash_test_t)); + if (item == NULL) { + fprintf(stderr, "malloc failed.\n"); + return -1; + } + item->key = 1; + item->val = 10; + if (mln_hash_insert(h, &(item->key), item) < 0) { + fprintf(stderr, "insert failed.\n"); + return -1; + } + + ret = mln_hash_search(h, &(item->key)); + printf("%p %p\n", ret, item); + + mln_hash_free(h, M_HASH_F_VAL); + + return 0; +} diff --git a/t/http.c b/t/http.c new file mode 100644 index 0000000..63c4db7 --- /dev/null +++ b/t/http.c @@ -0,0 +1,50 @@ +#include +#include "mln_http.h" +#include + +int main(void) +{ + mln_http_t *http; + mln_tcp_conn_t conn; + mln_alloc_t *pool; + mln_chain_t *c, *head = NULL, *tail = NULL; + mln_buf_t *b; + char req[] = "GET / HTTP/1.1\r\nHost: 127.0.0.1:8080\r\nUser-Agent: curl/7.81.0\r\n\r\n"; + mln_string_t key = mln_string("Server"); + mln_string_t val = mln_string("Melon"); + + assert(mln_tcp_conn_init(&conn, -1) == 0); + assert((http = mln_http_init(&conn, NULL, NULL)) != NULL); //no body + + pool = mln_tcp_conn_pool_get(&conn); + + assert((c = mln_chain_new(pool)) != NULL); + assert((b = mln_buf_new(pool)) != NULL); + c->buf = b; + b->start = b->pos = b->left_pos = (mln_u8ptr_t)req; + b->last = b->end = (mln_u8ptr_t)req + sizeof(req) - 1; + b->temporary = 1; + + assert(mln_http_parse(http, &c) == M_HTTP_RET_DONE); + + mln_http_type_set(http, M_HTTP_RESPONSE); + + assert(mln_http_field_set(http, &key, &val) == 0); + + if (c != NULL) mln_chain_pool_release(c); + + assert(mln_http_generate(http, &head, &tail) == M_HTTP_RET_DONE); + + for (c = head; c != NULL; c = c->next) { + if (mln_buf_size(c->buf)) { + write(STDOUT_FILENO, c->buf->start, mln_buf_size(c->buf)); + } + } + + mln_chain_pool_release_all(head); + mln_http_destroy(http); + mln_tcp_conn_destroy(&conn); + + return 0; +} + diff --git a/t/iothread.c b/t/iothread.c new file mode 100644 index 0000000..30e7774 --- /dev/null +++ b/t/iothread.c @@ -0,0 +1,46 @@ +#include "mln_iothread.h" +#include +#include +#include + +static void msg_handler(mln_iothread_t *t, mln_iothread_ep_type_t from, mln_iothread_msg_t *msg) +{ + mln_u32_t type = mln_iothread_msg_type(msg); + printf("msg type: %u\n", type); +} + +static void *entry(void *args) +{ + int n; + mln_iothread_t *t = (mln_iothread_t *)args; + while (1) { + n = mln_iothread_recv(t, user_thread); + printf("recv %d message(s)\n", n); + } + + return NULL; +} + +int main(void) +{ + int i, rc; + mln_iothread_t t; + + if (mln_iothread_init(&t, 1, (mln_iothread_entry_t)entry, &t, (mln_iothread_msg_process_t)msg_handler) < 0) { + fprintf(stderr, "iothread init failed\n"); + return -1; + } + for (i = 0; i < 10000; ++i) { + if ((rc = mln_iothread_send(&t, i, NULL, io_thread, 1)) < 0) { + fprintf(stderr, "send failed\n"); + return -1; + } else if (rc > 0) + continue; + } + sleep(1); + mln_iothread_destroy(&t); + sleep(3); + printf("DONE\n"); + + return 0; +} diff --git a/t/ipc.c b/t/ipc.c new file mode 100644 index 0000000..188c6e5 --- /dev/null +++ b/t/ipc.c @@ -0,0 +1,78 @@ +#include +#include +#include "mln_framework.h" +#include "mln_ipc.h" +#include "mln_conf.h" +#include "mln_log.h" + +mln_string_t me_framework_mode = mln_string("multiprocess"); +mln_conf_item_t me_framework_conf = {CONF_STR, .val.s=&me_framework_mode}; +mln_conf_item_t me_workerproc_conf = {CONF_INT, .val.i=1}; +mln_ipc_cb_t *ipc_cb; + +static void master_ipc_handler(mln_event_t *ev, void *f_ptr, void *buf, mln_u32_t len, void **pdata) +{ + mln_log(debug, "received: [%s]\n", (char *)buf); + exit(0); +} + +static void worker_ipc_timer_handler(mln_event_t *ev, void *data) +{ + exit(0); +} + +static void worker_ipc_handler(mln_event_t *ev, void *f_ptr, void *buf, mln_u32_t len, void **pdata) +{ + mln_log(debug, "received: [%s]\n", (char *)buf); + assert(mln_ipc_worker_send_prepare(ev, 255, "bcd", 4) == 0); + assert(mln_event_timer_set(ev, 3000, NULL, worker_ipc_timer_handler) != NULL); +} + +static int global_init(void) +{ + mln_conf_t *cf; + mln_conf_domain_t *cd; + mln_conf_cmd_t *cc; + + cf = mln_conf(); + cd = cf->search(cf, "main"); + cc = cd->search(cd, "framework"); + if (cc == NULL) { + assert((cc = cd->insert(cd, "framework")) != NULL); + } + assert(cc->update(cc, &me_framework_conf, 1) == 0); + + cc = cd->search(cd, "worker_proc"); + if (cc == NULL) { + assert((cc = cd->insert(cd, "worker_proc")) != NULL); + } + assert(cc->update(cc, &me_workerproc_conf, 1) == 0); + + assert((ipc_cb = mln_ipc_handler_register(255, master_ipc_handler, worker_ipc_handler, NULL, NULL)) != NULL); + return 0; +} + +static int child_iterator(mln_event_t *ev, mln_fork_t *child, void *data) +{ + return mln_ipc_master_send_prepare(ev, 255, "abc", 4, child); +} + +static void master_handler(mln_event_t *ev) +{ + assert(mln_fork_iterate(ev, child_iterator, NULL) == 0); +} + +int main(int argc, char *argv[]) +{ + printf("NOTE: This test has memory leak because we don't release memory of log, conf and multiprocess-related stuffs.\n"); + printf("In fact, `mln_framework_init` should be the last function called in `main`, so we don't need to release anything.\n"); + + struct mln_framework_attr cattr; + cattr.argc = argc; + cattr.argv = argv; + cattr.global_init = global_init; + cattr.main_thread = NULL; + cattr.master_process = master_handler; + cattr.worker_process = NULL; + return mln_framework_init(&cattr); +} diff --git a/t/json.c b/t/json.c new file mode 100644 index 0000000..480113a --- /dev/null +++ b/t/json.c @@ -0,0 +1,53 @@ +#include +#include "mln_string.h" +#include "mln_json.h" + +static int callback(mln_json_t *j, void *data) +{ + mln_json_number_init(j, *(int *)data); + return 0; +} + +static int handler(mln_json_t *j, void *data) +{ + mln_json_dump(j, 0, ""); + return 0; +} + +int main(int argc, char *argv[]) +{ + int i = 1024; + mln_json_t j, k; + struct mln_json_call_attr ca; + mln_string_t *res, exp = mln_string("protocols.0"); + mln_string_t tmp = mln_string("{\"paths\":[\"/mock\"],\"methods\":null,\"sources\":null,\"destinations\":null,\"name\":\"example_route\",\"headers\":null,\"hosts\":null,\"preserve_host\":false,\"regex_priority\":0,\"snis\":null,\"https_redirect_status_code\":426,\"tags\":null,\"protocols\":[\"http\",\"https\"],\"path_handling\":\"v0\",\"id\":\"52d58293-ae25-4c69-acc8-6dd729718a61\",\"updated_at\":1661345592,\"service\":{\"id\":\"c1e98b2b-6e77-476c-82ca-a5f1fb877e07\"},\"response_buffering\":true,\"strip_path\":true,\"request_buffering\":true,\"created_at\":1661345592}"); + + if (mln_json_decode(&tmp, &j) < 0) { + fprintf(stderr, "decode error\n"); + return -1; + } + + mln_json_parse(&j, &exp, handler, NULL); + + ca.callback = callback; + ca.data = &i; + mln_json_init(&k); + if (mln_json_generate(&k, "[{s:d,s:d,s:{s:d}},d,[],j,c]", "a", 1, "b", 3, "c", "d", 4, 5, &j, &ca) < 0) { + fprintf(stderr, "generate failed\n"); + return -1; + } + mln_json_generate(&k, "[s,d]", "g", 99); + res = mln_json_encode(&k); + + mln_json_destroy(&k); + + if (res == NULL) { + fprintf(stderr, "encode failed\n"); + return -1; + } + write(STDOUT_FILENO, res->data, res->len); + write(STDOUT_FILENO, "\n", 1); + mln_string_free(res); + + return 0; +}