diff --git a/dmentry.c b/dmentry.c index 5017913f..b15586f5 100644 --- a/dmentry.c +++ b/dmentry.c @@ -34,6 +34,8 @@ static char library_hash[64] = {0}; static bool first_boot = false; #endif +static void load_dynamic_arrays(struct dmctx *ctx); + int dm_debug_browse_path(char *buff, size_t len) { if (!buff) @@ -150,22 +152,34 @@ static int dm_ctx_clean_custom(struct dmctx *ctx, int custom) DMFREE(ctx->addobj_instance); if (custom == CTX_INIT_ALL) { bbf_uci_exit(); - dmubus_free(); dmcleanmem(); } return 0; } +void dm_config_ubus(struct ubus_context *ctx) +{ + dmubus_configure(ctx); +} + int dm_ctx_init(struct dmctx *ctx, unsigned int instance_mode) { + dmubus_clean_endlife_entries(); return dm_ctx_init_custom(ctx, instance_mode, CTX_INIT_ALL); } int dm_ctx_clean(struct dmctx *ctx) { + dmubus_update_cached_entries(); return dm_ctx_clean_custom(ctx, CTX_INIT_ALL); } +int dm_ctx_init_cache(int time) +{ + dmubus_set_caching_time(time); + return 0; +} + int dm_ctx_init_sub(struct dmctx *ctx, unsigned int instance_mode) { return dm_ctx_init_custom(ctx, instance_mode, CTX_INIT_SUB); @@ -490,7 +504,7 @@ static int check_stats_folder(bool json_path) } #endif /* (BBFDM_ENABLE_JSON_PLUGIN || BBFDM_ENABLE_DOTSO_PLUGIN) */ -void load_dynamic_arrays(struct dmctx *ctx) +static void load_dynamic_arrays(struct dmctx *ctx) { #ifdef BBFDM_ENABLE_JSON_PLUGIN // Load dynamic objects and parameters exposed via a JSON file @@ -518,7 +532,7 @@ void load_dynamic_arrays(struct dmctx *ctx) #endif } -void free_dynamic_arrays(void) +static void free_dynamic_arrays(void) { DMOBJ *root = tEntry181Obj; DMNODE node = {.current_object = ""}; @@ -535,5 +549,11 @@ void free_dynamic_arrays(void) free_vendor_dynamic_arrays(tEntry181Obj); #endif free_dm_browse_node_dynamic_object_tree(&node, root); - dm_dynamic_cleanmem(&main_memhead); +} + +void bbf_dm_cleanup(void) +{ + dmubus_free(); + dm_dynamic_cleanmem(&main_memhead); + free_dynamic_arrays(); } diff --git a/dmentry.h b/dmentry.h index 7bdf8abf..5cf2e602 100644 --- a/dmentry.h +++ b/dmentry.h @@ -41,9 +41,10 @@ int dm_entry_revert_changes(void); int usp_fault_map(int fault); int dm_ctx_clean(struct dmctx *ctx); int dm_ctx_clean_sub(struct dmctx *ctx); -void load_dynamic_arrays(struct dmctx *ctx); -void free_dynamic_arrays(void); int dm_get_supported_dm(struct dmctx *ctx, char *path, bool first_level, schema_type_t schema_type); +void dm_config_ubus(struct ubus_context *ctx); +int dm_ctx_init_cache(int time); +void bbf_dm_cleanup(void); /** * @brief dm_debug_browse_path diff --git a/libbbf_api/dmubus.c b/libbbf_api/dmubus.c index 8d75e58c..23087fda 100644 --- a/libbbf_api/dmubus.c +++ b/libbbf_api/dmubus.c @@ -11,18 +11,25 @@ * Author: Anis Ellouze */ -#include -#include #include "dmubus.h" #include "dmmem.h" #include "dmcommon.h" +#define UBUS_TIMEOUT 5000 + static LIST_HEAD(dmubus_cache); struct dm_ubus_cache_entry { struct list_head list; json_object *data; unsigned hash; + time_t last_request; + time_t resp_time; + bool failed; + bool async_call_running; + char obj[100]; + char method[100]; + struct blob_attr *breq; }; struct dm_ubus_req { @@ -32,29 +39,60 @@ struct dm_ubus_req { unsigned n_args; }; -static struct blob_buf b; +struct dm_ubus_hash_req { + const char *obj; + const char *method; + struct blob_attr *attr; +}; + static struct ubus_context *ubus_ctx; -static int timeout = 5000; static json_object *json_res = NULL; static char ubus_method[32] = {0}; static bool ubus_method_exists = false; +static bool local_ctx_g = false; +static int soft_limit_g = 0; /* In seconds */ +static int hard_limit_g = 0; /* In seconds */ -static void dm_libubus_free() -{ - if (ubus_ctx) { - ubus_free(ubus_ctx); - ubus_ctx = NULL; - } - - blob_buf_free(&b); - memset(&b, 0, sizeof(b)); -} +static const struct dm_ubus_cache_entry * dm_ubus_cache_lookup(unsigned hash); static struct ubus_context * dm_libubus_init() { + local_ctx_g = true; return ubus_connect(NULL); } +static void dm_libubus_free() +{ + if (local_ctx_g && ubus_ctx) { + ubus_free(ubus_ctx); + ubus_ctx = NULL; + local_ctx_g = false; + } +} + +static void prepare_blob_message(struct blob_buf *b, const struct ubus_arg u_args[], int u_args_size) +{ + if (!b) + return; + + blob_buf_init(b, 0); + for (int i = 0; i < u_args_size; i++) { + if (u_args[i].type == Integer) { + blobmsg_add_u32(b, u_args[i].key, atoi(u_args[i].val)); + } else if (u_args[i].type == Boolean) { + bool val = false; + string_to_bool((char *)u_args[i].val, &val); + blobmsg_add_u8(b, u_args[i].key, val); + } else if (u_args[i].type == Table) { + json_object *jobj = json_tokener_parse(u_args[i].val); + blobmsg_add_json_element(b, u_args[i].key, jobj); + json_object_put(jobj); + } else { + blobmsg_add_string(b, u_args[i].key, u_args[i].val); + } + } +} + static void receive_call_result_data(struct ubus_request *req, int type, struct blob_attr *msg) { const char *str; @@ -72,40 +110,86 @@ static void receive_call_result_data(struct ubus_request *req, int type, struct free((char *)str); //MEM should be free and not dmfree } -static int __dm_ubus_call(const char *obj, const char *method, const struct ubus_arg u_args[], int u_args_size) +static void __async_result_callback(struct ubus_request *req, int type, struct blob_attr *msg) +{ + const char *str; + time_t resp_time = time(NULL); + + const unsigned *hash = (unsigned *)req->priv; + + if (!hash) { + // This should not happen + printf("Hash found NULL in callback request\n\r"); + return; + } + + struct dm_ubus_cache_entry *entry = (struct dm_ubus_cache_entry *)dm_ubus_cache_lookup(*hash); + + if (!entry) { + // This should not happen unless resp took too long + printf("Hash not found in cache\n\r"); + } else { + entry->resp_time = resp_time; + entry->async_call_running = false; + + if (entry->data) { + json_object_put(entry->data); + } + + if (difftime(resp_time, entry->last_request) >= UBUS_TIMEOUT/1000) { + printf("Req [%s:%s] has been timedout in async call %lu, %lu\n\r", + entry->obj, entry->method, resp_time, entry->last_request); + entry->failed = true; + } else { + entry->failed = false; + } + + if (!msg) { + entry->data = NULL; + return; + } + + str = blobmsg_format_json_indent(msg, true, -1); + if (!str) { + entry->data = NULL; + return; + } + + json_object *json_resp = json_tokener_parse(str); + entry->data = json_resp; + free((char *)str); //MEM should be free and not dmfree + } +} + +static void __async_complete_callback(struct ubus_request *req, int ret) +{ + if (req) { + if (req->priv) { + free(req->priv); + } + + free(req); + } +} + +static int __dm_ubus_call(const char *obj, const char *method, struct blob_attr *attr) { uint32_t id; - int i = 0; int rc = 0; json_res = NULL; if (ubus_ctx == NULL) { ubus_ctx = dm_libubus_init(); - if (ubus_ctx == NULL) + if (ubus_ctx == NULL) { + printf("UBUS context is null\n\r"); return -1; - } - - blob_buf_init(&b, 0); - for (i = 0; i < u_args_size; i++) { - if (u_args[i].type == Integer) { - blobmsg_add_u32(&b, u_args[i].key, atoi(u_args[i].val)); - } else if (u_args[i].type == Boolean) { - bool val = false; - string_to_bool((char *)u_args[i].val, &val); - blobmsg_add_u8(&b, u_args[i].key, val); - } else if (u_args[i].type == Table) { - json_object *obj = json_tokener_parse(u_args[i].val); - blobmsg_add_json_element(&b, u_args[i].key, obj); - json_object_put(obj); - } else { - blobmsg_add_string(&b, u_args[i].key, u_args[i].val); } } if (!ubus_lookup_id(ubus_ctx, obj, &id)) - rc = ubus_invoke(ubus_ctx, id, method, b.head, - receive_call_result_data, NULL, timeout); + rc = ubus_invoke(ubus_ctx, id, method, attr, + receive_call_result_data, NULL, UBUS_TIMEOUT); else rc = -1; @@ -114,15 +198,79 @@ static int __dm_ubus_call(const char *obj, const char *method, const struct ubus int dmubus_call_set(char *obj, char *method, struct ubus_arg u_args[], int u_args_size) { - int rc = __dm_ubus_call(obj, method, u_args, u_args_size); + struct blob_buf b; + + memset(&b, 0, sizeof(struct blob_buf)); + prepare_blob_message(&b, u_args, u_args_size); + + int rc = __dm_ubus_call(obj, method, b.head); if (json_res != NULL) { json_object_put(json_res); json_res = NULL; } + + blob_buf_free(&b); return rc; } +static inline json_object *ubus_call_req(char *obj, char *method, struct blob_attr *attr) +{ + __dm_ubus_call(obj, method, attr); + return json_res; +} + +static int ubus_call_req_async(const char *obj, const char *method, const unsigned hash, struct blob_attr *attr) +{ + uint32_t id; + int rc = 0; + struct ubus_request *req; + + if (ubus_ctx == NULL) { + ubus_ctx = dm_libubus_init(); + if (ubus_ctx == NULL) { + printf("UBUS context is null\n\r"); + return -1; + } + } + + if (!ubus_lookup_id(ubus_ctx, obj, &id)) { + req = (struct ubus_request *)malloc(sizeof(struct ubus_request)); + if (req == NULL) { + printf("Out of memory!\n\r"); + return -1; + } + + memset(req, 0, sizeof(struct ubus_request)); + + rc = ubus_invoke_async(ubus_ctx, id, method, attr, req); + if (rc) { + printf("Ubus async invoke failed (%s)\n\r", ubus_strerror(rc)); + free(req); + return -1; + } + + unsigned *p = (unsigned *)malloc(sizeof(unsigned)); + if (p == NULL) { + printf("memory allocation failed\n\r"); + free(req); + return -1; + } + + *p = hash; + req->data_cb = __async_result_callback; + req->complete_cb = __async_complete_callback; + req->priv = (void *)p; + + ubus_complete_request_async(ubus_ctx, req); + } else { + printf("Ubus lookup id failed from async call\n\r"); + return -1; + } + + return 0; +} + int dmubus_operate_blob_set(char *obj, char *method, void *value, json_object **resp) { uint32_t id; @@ -134,8 +282,10 @@ int dmubus_operate_blob_set(char *obj, char *method, void *value, json_object ** if (ubus_ctx == NULL) { ubus_ctx = dm_libubus_init(); - if (ubus_ctx == NULL) - return rc; + if (ubus_ctx == NULL) { + printf("UBUS context is null\n\r"); + return -1; + } } memset(&blob, 0, sizeof(struct blob_buf)); @@ -150,19 +300,12 @@ int dmubus_operate_blob_set(char *obj, char *method, void *value, json_object ** if (!ubus_lookup_id(ubus_ctx, obj, &id)) { rc = ubus_invoke(ubus_ctx, id, method, blob.head, - receive_call_result_data, NULL, timeout); + receive_call_result_data, NULL, UBUS_TIMEOUT); } *resp = json_res; blob_buf_free(&blob); return rc; - -} - -static inline json_object *ubus_call_req(char *obj, char *method, struct ubus_arg u_args[], int u_args_size) -{ - __dm_ubus_call(obj, method, u_args, u_args_size); - return json_res; } /* Based on an efficient hash function published by D. J. Bernstein @@ -177,18 +320,23 @@ static unsigned int djbhash(unsigned hash, const char *data, unsigned len) return (hash & 0x7FFFFFFF); } -static unsigned dm_ubus_req_hash(const struct dm_ubus_req *req) +static unsigned dm_ubus_req_hash_from_blob(const struct dm_ubus_hash_req *req) { unsigned hash = 5381; - unsigned i; + if (!req) { + return hash; + } hash = djbhash(hash, req->obj, strlen(req->obj)); hash = djbhash(hash, req->method, strlen(req->method)); - for (i = 0; i < req->n_args; i++) { - hash = djbhash(hash, req->args[i].key, strlen(req->args[i].key)); - hash = djbhash(hash, req->args[i].val, strlen(req->args[i].val)); + char *jmsg = blobmsg_format_json(req->attr, true); + if (!jmsg) { + return hash; } + + hash = djbhash(hash, jmsg, strlen(jmsg)); + free(jmsg); return hash; } @@ -206,13 +354,21 @@ static const struct dm_ubus_cache_entry * dm_ubus_cache_lookup(unsigned hash) return entry_match; } -static void dm_ubus_cache_entry_new(unsigned hash, json_object *data) +static void dm_ubus_cache_entry_new(unsigned hash, json_object *data, char *obj, char *method, + time_t req_time, time_t resp_time, struct blob_attr *breq) { struct dm_ubus_cache_entry *entry = malloc(sizeof(*entry)); if (entry) { entry->data = data; entry->hash = hash; + entry->last_request = req_time; + entry->resp_time = resp_time; + entry->breq = breq; + entry->failed = data ? true : false; + entry->async_call_running = false; + DM_STRNCPY(entry->obj, obj, sizeof(entry->obj)); + DM_STRNCPY(entry->method, method, sizeof(entry->method)); list_add_tail(&entry->list, &dmubus_cache); } } @@ -220,33 +376,78 @@ static void dm_ubus_cache_entry_new(unsigned hash, json_object *data) static void dm_ubus_cache_entry_free(struct dm_ubus_cache_entry *entry) { list_del(&entry->list); - json_object_put(entry->data); - free(entry); + + if (entry->breq) + FREE(entry->breq); + + if (entry->data) + json_object_put(entry->data); + + FREE(entry); } int dmubus_call(char *obj, char *method, struct ubus_arg u_args[], int u_args_size, json_object **req_res) { - const struct dm_ubus_req req = { + struct blob_buf bmsg; + + memset(&bmsg, 0, sizeof(struct blob_buf)); + prepare_blob_message(&bmsg, u_args, u_args_size); + + const struct dm_ubus_hash_req hash_req = { .obj = obj, .method = method, - .args = u_args, - .n_args = u_args_size + .attr = bmsg.head }; - const unsigned hash = dm_ubus_req_hash(&req); + + const unsigned hash = dm_ubus_req_hash_from_blob(&hash_req); const struct dm_ubus_cache_entry *entry = dm_ubus_cache_lookup(hash); json_object *res; if (entry) { res = entry->data; } else { - res = ubus_call_req(obj, method, u_args, u_args_size); - dm_ubus_cache_entry_new(hash, res); + time_t req_time = time(NULL); + res = ubus_call_req(obj, method, bmsg.head); + time_t resp_time = time(NULL); + + dm_ubus_cache_entry_new(hash, res, obj, method, req_time, resp_time, blob_memdup(bmsg.head)); } + blob_buf_free(&bmsg); *req_res = res; return 0; } +static int dmubus_call_async(const char *obj, const char *method, struct blob_attr *attr) +{ + const struct dm_ubus_hash_req hash_req = { + .obj = obj, + .method = method, + .attr = attr + }; + + const unsigned hash = dm_ubus_req_hash_from_blob(&hash_req); + struct dm_ubus_cache_entry *entry = (struct dm_ubus_cache_entry *)dm_ubus_cache_lookup(hash); + + if (entry) { + entry->last_request = time(NULL); + entry->failed = false; + entry->async_call_running = true; + if (-1 == ubus_call_req_async(obj, method, hash, attr)) { + printf("Ubus call async failed\n\r"); + entry->failed = true; + entry->resp_time = time(NULL); + if (entry->data) { + json_object_put(entry->data); + entry->data = NULL; + } + entry->async_call_running = false; + } + } + + return 0; +} + static void receive_list_result(struct ubus_context *ctx, struct ubus_object_data *obj, void *priv) { struct blob_attr *cur = NULL; @@ -268,8 +469,10 @@ bool dmubus_object_method_exists(const char *obj) { if (ubus_ctx == NULL) { ubus_ctx = dm_libubus_init(); - if (ubus_ctx == NULL) - return false; + if (ubus_ctx == NULL) { + printf("UBUS context is null\n\r"); + return -1; + } } char *method = ""; @@ -293,6 +496,50 @@ bool dmubus_object_method_exists(const char *obj) return true; } +void dmubus_configure(struct ubus_context *ctx) +{ + ubus_ctx = ctx; +} + +void dmubus_clean_endlife_entries() +{ + if (hard_limit_g != 0) { + struct dm_ubus_cache_entry *entry, *tmp; + time_t curr_time = time(NULL); + + list_for_each_entry_safe(entry, tmp, &dmubus_cache, list) { + if (difftime(curr_time, entry->last_request) >= hard_limit_g) { + dm_ubus_cache_entry_free(entry); + } + } + } +} + +void dmubus_update_cached_entries() +{ + if (hard_limit_g == 0 || local_ctx_g == true) { + dmubus_free(); + dm_libubus_free(); + } else { + struct dm_ubus_cache_entry *entry; + time_t curr_time = time(NULL); + + list_for_each_entry(entry, &dmubus_cache, list) { + // There could be a case when async call done previously but response still + // not received or the previous ubus call took >= soft_limit_g sec, so in that case no + // need to perform async call again & wait for HARD_LIMIT to delete the entry from cache + + if (entry->async_call_running || entry->failed) + continue; + + double time_elapsed = difftime(curr_time, entry->last_request); + if (time_elapsed >= soft_limit_g && time_elapsed < hard_limit_g) { + dmubus_call_async(entry->obj, entry->method, entry->breq); + } + } + } +} + void dmubus_free() { struct dm_ubus_cache_entry *entry, *tmp; @@ -300,5 +547,13 @@ void dmubus_free() list_for_each_entry_safe(entry, tmp, &dmubus_cache, list) dm_ubus_cache_entry_free(entry); - dm_libubus_free(); +} + +void dmubus_set_caching_time(int seconds) +{ + if (seconds < 2) + return; + + soft_limit_g = seconds/2; + hard_limit_g = seconds; } diff --git a/libbbf_api/dmubus.h b/libbbf_api/dmubus.h index e0b32520..fbbbb9cb 100644 --- a/libbbf_api/dmubus.h +++ b/libbbf_api/dmubus.h @@ -14,6 +14,10 @@ #ifndef __DMUBUS_H #define __DMUBUS_H +#include +#include +#include + #define UBUS_ARGS (struct ubus_arg[]) enum ubus_arg_type { @@ -34,5 +38,9 @@ int dmubus_call_set(char *obj, char *method, struct ubus_arg u_args[], int u_arg int dmubus_operate_blob_set(char *obj, char *method, void *value, json_object **resp); bool dmubus_object_method_exists(const char *obj); void dmubus_free(); +void dmubus_configure(struct ubus_context *ctx); +void dmubus_update_cached_entries(); +void dmubus_clean_endlife_entries(); +void dmubus_set_caching_time(int seconds); #endif diff --git a/test/bbf_test/Makefile b/test/bbf_test/Makefile index f76c80fb..4c9b6b87 100644 --- a/test/bbf_test/Makefile +++ b/test/bbf_test/Makefile @@ -4,8 +4,8 @@ BIN = bbf_dm BIN_OBJ = bbf_dm.o LIB_OBJS = libbbf_test.o LIB_CFLAGS = $(CFLAGS) -Wall -Werror -fPIC -I /usr/local/include/ -LIB_LDFLAGS = $(LDFLAGS) -lbbf_api -BIN_LDFLAGS = $(LDFLAGS) -lbbfdm +LIB_LDFLAGS = $(LDFLAGS) -lbbf_api -lubus +BIN_LDFLAGS = $(LDFLAGS) -lbbfdm -lubus %.o: %.c $(CC) $(LIB_CFLAGS) $(FPIC) -c -o $@ $< diff --git a/test/bbf_test/bbf_dm.c b/test/bbf_test/bbf_dm.c index 9218148e..0e3f0ea0 100644 --- a/test/bbf_test/bbf_dm.c +++ b/test/bbf_test/bbf_dm.c @@ -1,5 +1,6 @@ #include +#include #include #include @@ -88,6 +89,7 @@ int usp_dm_exec(int cmd, char *path, char *arg1, char *arg2) int main(int argc, char *argv[]) { + static struct ubus_context *ubus_ctx = NULL; char *param = NULL, *value = NULL, *version = NULL; int cmd; @@ -95,6 +97,12 @@ int main(int argc, char *argv[]) print_help(argv[0]); } + ubus_ctx = ubus_connect(NULL); + if (ubus_ctx == NULL) + return -1; + + dm_config_ubus(ubus_ctx); + if (strcmp(argv[1], "-c") == 0) g_proto = BBFDM_CWMP; @@ -110,5 +118,6 @@ int main(int argc, char *argv[]) version = argv[5]; usp_dm_exec(cmd, param, value, version); - free_dynamic_arrays(); + bbf_dm_cleanup(); + ubus_free(ubus_ctx); } diff --git a/test/cmocka/Makefile b/test/cmocka/Makefile index 717a452e..fe9d29ba 100644 --- a/test/cmocka/Makefile +++ b/test/cmocka/Makefile @@ -1,7 +1,7 @@ CC = gcc CFLAGS = -g -Wall -Werror -LDFLAGS = -lcmocka -lbbfdm -lbbf_api -LDFLAGS_API_TEST = -lcmocka -lbbf_api +LDFLAGS = -lcmocka -lbbfdm -lbbf_api -lubus +LDFLAGS_API_TEST = -lcmocka -lbbf_api -lubus UNIT_TESTS = unit_test_bbfd FUNCTIONAL_TESTS = functional_test_bbfd FUNCTIONAL_API_TESTS = functional_api_test_bbfd diff --git a/test/cmocka/functional_api_test_bbfd.c b/test/cmocka/functional_api_test_bbfd.c index 52caf08a..fbf59a07 100644 --- a/test/cmocka/functional_api_test_bbfd.c +++ b/test/cmocka/functional_api_test_bbfd.c @@ -3,11 +3,18 @@ #include #include +#include #include #include +static struct ubus_context *ubus_ctx = NULL; static int setup_teardown(void **state) { + ubus_ctx = ubus_connect(NULL); + if (ubus_ctx == NULL) + return -1; + + dmubus_configure(ubus_ctx); bbf_uci_init(); return 0; } @@ -16,6 +23,11 @@ static int group_teardown(void **state) { bbf_uci_exit(); dmubus_free(); + if (ubus_ctx != NULL) { + ubus_free(ubus_ctx); + ubus_ctx = NULL; + } + dmcleanmem(); return 0; } diff --git a/test/cmocka/functional_test_bbfd.c b/test/cmocka/functional_test_bbfd.c index 28c0243e..04662481 100644 --- a/test/cmocka/functional_test_bbfd.c +++ b/test/cmocka/functional_test_bbfd.c @@ -3,9 +3,22 @@ #include #include +#include #include #include +static struct ubus_context *ubus_ctx = NULL; + +static int group_setup(void **state) +{ + ubus_ctx = ubus_connect(NULL); + if (ubus_ctx == NULL) + return -1; + + dm_config_ubus(ubus_ctx); + return 0; +} + static int setup(void **state) { struct dmctx *ctx = calloc(1, sizeof(struct dmctx)); @@ -43,7 +56,12 @@ static int teardown_commit(void **state) static int group_teardown(void **state) { - free_dynamic_arrays(); + bbf_dm_cleanup(); + if (ubus_ctx != NULL) { + ubus_free(ubus_ctx); + ubus_ctx = NULL; + } + return 0; } @@ -1090,7 +1108,7 @@ int main(void) cmocka_unit_test_setup_teardown(test_api_bbfdm_valid_json_event, setup, teardown_commit), }; - return cmocka_run_group_tests(tests, NULL, group_teardown); + return cmocka_run_group_tests(tests, group_setup, group_teardown); } diff --git a/test/cmocka/unit_test_bbfd.c b/test/cmocka/unit_test_bbfd.c index 9a3d4141..e2ea9e5d 100644 --- a/test/cmocka/unit_test_bbfd.c +++ b/test/cmocka/unit_test_bbfd.c @@ -3,6 +3,7 @@ #include #include +#include #include #include @@ -11,6 +12,18 @@ #define LIBBBF_TEST_PATH "/builds/iopsys/bbf/test/bbf_test/libbbf_test.so" #define LIBBBF_TEST_BBFDM_PATH "/usr/lib/bbfdm/libbbf_test.so" +static struct ubus_context *ubus_ctx = NULL; + +static int group_setup(void **state) +{ + ubus_ctx = ubus_connect(NULL); + if (ubus_ctx == NULL) + return -1; + + dm_config_ubus(ubus_ctx); + return 0; +} + static int setup(void **state) { struct dmctx *ctx = calloc(1, sizeof(struct dmctx)); @@ -59,7 +72,12 @@ static int teardown_revert(void **state) static int group_teardown(void **state) { - free_dynamic_arrays(); + bbf_dm_cleanup(); + if (ubus_ctx != NULL) { + ubus_free(ubus_ctx); + ubus_ctx = NULL; + } + return 0; } @@ -803,5 +821,5 @@ int main(void) cmocka_unit_test_setup_teardown(test_api_bbfdm_library_delete_object, setup, teardown_commit), }; - return cmocka_run_group_tests(tests, NULL, group_teardown); + return cmocka_run_group_tests(tests, group_setup, group_teardown); }