diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index fea2ac35..90c10cda 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -4,12 +4,56 @@ include: stages: - static_code_analysis + - unit_test + - functional_test + - functional_api_test - uspd - + variables: DEBUG: 'TRUE' SOURCE_FOLDER: "." +run_unit_test: + stage: unit_test + image: iopsys/code-analysis-dev:latest + allow_failure: false + script: + - "./gitlab-ci/setup.sh" + - "./gitlab-ci/unit-test.sh" + artifacts: + when: always + paths: + - timestamp.log + - unit-test-coverage.xml + +run_functional_test: + stage: functional_test + image: iopsys/code-analysis-dev:latest + allow_failure: false + script: + - "./gitlab-ci/setup.sh" + - "./gitlab-ci/functional-test.sh" + + artifacts: + when: always + paths: + - timestamp.log + - functional-test-coverage.xml + +run_functional_api_test: + stage: functional_api_test + image: iopsys/code-analysis-dev:latest + allow_failure: false + script: + - "./gitlab-ci/setup.sh" + - "./gitlab-ci/functional-api-test.sh" + + artifacts: + when: always + paths: + - timestamp.log + - functional-api-test-coverage.xml + run_uspd: stage: uspd variables: diff --git a/README.md b/README.md index 01c340cd..20b48e8b 100644 --- a/README.md +++ b/README.md @@ -620,7 +620,7 @@ The application should bring its JSON file under **'/etc/bbfdm/json/'** path wit > Note2: JSON File is not allowed to overwrite objects/parameters -- For more examples on JSON files, you can see these links: [X_IOPSYS_EU_MCPD](https://dev.iopsys.eu/feed/broadcom/-/blob/devel/mcpd/files/etc/bbfdm/json/X_IOPSYS_EU_MCPD.json), [UserInterface](https://dev.iopsys.eu/feed/3rdparty/-/blob/userinterface/sulu/files/etc/bbfdm/json/UserInterface.json) +- For more examples on JSON files, you can see these links: [X_IOPSYS_EU_MCPD](https://dev.iopsys.eu/feed/broadcom/-/blob/devel/mcpd/files/etc/bbfdm/json/X_IOPSYS_EU_MCPD.json), [UserInterface](/test/files/etc/bbfdm/json/UserInterface.json), [X_IOPSYS_EU_Dropbear](/test/files/etc/bbfdm/json/X_IOPSYS_EU_Dropbear.json) ## BBFDM Tools diff --git a/bin/Makefile.am b/bin/Makefile.am index 432fde6d..a074625f 100644 --- a/bin/Makefile.am +++ b/bin/Makefile.am @@ -166,3 +166,11 @@ libbbfdm_la_CFLAGS+=-I../dmtree libbbfdm_la_CFLAGS+=-I../dmtree/tr181 libbbfdm_la_CFLAGS+=-I../dmtree/tr104 libbbfdm_la_CFLAGS+=-I../dmtree/tr143 + +if BBF_TEST +libbbf_api_la_CFLAGS += -fprofile-arcs -ftest-coverage +libbbf_api_la_LDFLAGS += --coverage + +libbbfdm_la_CFLAGS += -fprofile-arcs -ftest-coverage +libbbfdm_la_LDFLAGS += --coverage +endif diff --git a/configure.ac b/configure.ac index e39ca51b..5748d07a 100644 --- a/configure.ac +++ b/configure.ac @@ -18,6 +18,9 @@ AM_CONDITIONAL([LOPENSSL],[test "x$enable_libopenssl" = "xyes"]) AC_ARG_ENABLE(libmbedtls, [AS_HELP_STRING([--enable-libmbedtls], [enable libmbedtls upnp feature])], AC_DEFINE(LMBEDTLS),) AM_CONDITIONAL([LMBEDTLS],[test "x$enable_libmbedtls" = "xyes"]) +AC_ARG_ENABLE(bbf_test, [AS_HELP_STRING([--enable-bbf-test], [enable bbf unit test])], AC_DEFINE(BBF_TEST),) +AM_CONDITIONAL([BBF_TEST],[test "x$enable_bbf_test" = "xyes"]) + AC_ARG_ENABLE(vendor_extension, [AS_HELP_STRING([--enable-vendor-extension], [enable vendor extension])], AC_DEFINE(BBF_VENDOR_EXTENSION),) AM_CONDITIONAL([BBF_VENDOR_EXTENSION],[test "x$enable_vendor_extension" = "xyes"]) diff --git a/dmdynamicjson.c b/dmdynamicjson.c index c9ca034d..f9e25f8f 100644 --- a/dmdynamicjson.c +++ b/dmdynamicjson.c @@ -469,10 +469,13 @@ static bool is_obj(char *object, json_object *jobj) static void parse_mapping_obj(char *object, json_object *mapping, struct list_head *list) { - struct json_object *type, *obj; + if (!mapping) + return; + + struct json_object *type = NULL, *obj = NULL; json_object_object_get_ex(mapping, "type", &type); - if (strcmp(json_object_get_string(type), "uci") == 0) { + if (type && strcmp(json_object_get_string(type), "uci") == 0) { //UCI: arg1=type :: arg2=uci_file :: arg3=uci_section_type :: arg4=uci_dmmap_file :: arg5="" :: arg6="" struct json_object *file, *section, *section_type, *dmmap_file; @@ -485,7 +488,7 @@ static void parse_mapping_obj(char *object, json_object *mapping, struct list_he //Add to list add_json_data_to_list(list, object, "uci", json_object_get_string(file), json_object_get_string(section_type), json_object_get_string(dmmap_file), "", "", "", ""); } - else if (strcmp(json_object_get_string(type), "ubus") == 0) { + else if (type && strcmp(json_object_get_string(type), "ubus") == 0) { //UBUS: arg1=type :: arg2=ubus_object :: arg3=ubus_method :: arg4=ubus_args1 :: arg5=ubus_args2 :: arg6=ubus_key struct json_object *obj1, *method, *key, *args; @@ -506,10 +509,13 @@ static void parse_mapping_obj(char *object, json_object *mapping, struct list_he static void parse_mapping_param(char *parameter, json_object *mapping, struct list_head *list) { - struct json_object *type, *obj; + if (!mapping) + return; + + struct json_object *type = NULL, *obj = NULL; json_object_object_get_ex(mapping, "type", &type); - if (strcmp(json_object_get_string(type), "uci") == 0) { + if (type && strcmp(json_object_get_string(type), "uci") == 0) { //UCI: arg1=type :: arg2=uci_file :: arg3=uci_section_type :: arg4=uci_section_name :: arg5=uci_section_index :: arg6=uci_option_name :: arg7=path :: arg8=ref struct json_object *file, *section, *type, *section_name, *index, *option, *option_name, *path, *ref; @@ -528,7 +534,7 @@ static void parse_mapping_param(char *parameter, json_object *mapping, struct li add_json_data_to_list(list, parameter, "uci", json_object_get_string(file), json_object_get_string(type), json_object_get_string(section_name), json_object_get_string(index), json_object_get_string(option_name), json_object_get_string(path), json_object_get_string(ref)); } - else if (strcmp(json_object_get_string(type), "ubus") == 0) { + else if (type && strcmp(json_object_get_string(type), "ubus") == 0) { //UBUS: arg1=type :: arg2=ubus_object :: arg3=ubus_method :: arg4=ubus_args1 :: arg5=ubus_args2 :: arg6=ubus_key struct json_object *object, *method, *key, *args; @@ -550,36 +556,37 @@ static void parse_mapping_param(char *parameter, json_object *mapping, struct li static void parse_param(char *object, char *param, json_object *jobj, DMLEAF *pleaf, int i, struct list_head *list) { /* PARAM, permission, type, getvalue, setvalue, bbfdm_type(6)*/ - struct json_object *type, *protocols, *proto, *write, *mapping_arr, *mapping; + struct json_object *type = NULL, *protocols = NULL, *write = NULL, *mapping_arr = NULL, *mapping = NULL; char full_param[256] = {0}; size_t n_proto; - if (!pleaf) return; + if (!jobj || !pleaf) + return; //PARAM pleaf[i].parameter = dmstrdupjson(param); //permission json_object_object_get_ex(jobj, "write", &write); - pleaf[i].permission = json_object_get_boolean(write) ? &DMWRITE : &DMREAD; + pleaf[i].permission = (write && json_object_get_boolean(write)) ? &DMWRITE : &DMREAD; //type json_object_object_get_ex(jobj, "type", &type); - if (strcmp(json_object_get_string(type), "boolean") == 0) + if (type && strcmp(json_object_get_string(type), "boolean") == 0) pleaf[i].type = DMT_BOOL; - else if (strcmp(json_object_get_string(type), "unsignedInt") == 0) + else if (type && strcmp(json_object_get_string(type), "unsignedInt") == 0) pleaf[i].type = DMT_UNINT; - else if (strcmp(json_object_get_string(type), "unsignedLong") == 0) + else if (type && strcmp(json_object_get_string(type), "unsignedLong") == 0) pleaf[i].type = DMT_UNLONG; - else if (strcmp(json_object_get_string(type), "hexBinary") == 0) + else if (type && strcmp(json_object_get_string(type), "hexBinary") == 0) pleaf[i].type = DMT_HEXBIN; - else if (strcmp(json_object_get_string(type), "int") == 0) + else if (type && strcmp(json_object_get_string(type), "int") == 0) pleaf[i].type = DMT_INT; - else if (strcmp(json_object_get_string(type), "long") == 0) + else if (type && strcmp(json_object_get_string(type), "long") == 0) pleaf[i].type = DMT_LONG; - else if (strcmp(json_object_get_string(type), "dateTime") == 0) + else if (type && strcmp(json_object_get_string(type), "dateTime") == 0) pleaf[i].type = DMT_TIME; - else if (strcmp(json_object_get_string(type), "base64") == 0) + else if (type && strcmp(json_object_get_string(type), "base64") == 0) pleaf[i].type = DMT_BASE64; else pleaf[i].type = DMT_STRING; @@ -588,18 +595,18 @@ static void parse_param(char *object, char *param, json_object *jobj, DMLEAF *pl pleaf[i].getvalue = getvalue_param; //setvalue - pleaf[i].setvalue = json_object_get_boolean(write) ? setvalue_param : NULL; + pleaf[i].setvalue = (write && json_object_get_boolean(write)) ? setvalue_param : NULL; //bbfdm_type json_object_object_get_ex(jobj, "protocols", &protocols); - n_proto = json_object_array_length(protocols); + n_proto = protocols ? json_object_array_length(protocols) : 0; if (n_proto == 2) pleaf[i].bbfdm_type = BBFDM_BOTH; else if (n_proto == 1) { - proto = json_object_array_get_idx(protocols, 0); - if (strcmp(json_object_get_string(proto), "cwmp") == 0) + struct json_object *proto = protocols ? json_object_array_get_idx(protocols, 0) : NULL; + if (proto && strcmp(json_object_get_string(proto), "cwmp") == 0) pleaf[i].bbfdm_type = BBFDM_CWMP; - else if (strcmp(json_object_get_string(proto), "usp") == 0) + else if (proto && strcmp(json_object_get_string(proto), "usp") == 0) pleaf[i].bbfdm_type = BBFDM_USP; else pleaf[i].bbfdm_type = BBFDM_BOTH; @@ -608,8 +615,10 @@ static void parse_param(char *object, char *param, json_object *jobj, DMLEAF *pl snprintf(full_param, sizeof(full_param), "%s%s", object, param); json_object_object_get_ex(jobj, "mapping", &mapping_arr); - // for now, we have only one case - mapping = json_object_array_get_idx(mapping_arr, 0); + if (mapping_arr && json_object_get_type(mapping_arr) == json_type_array) + mapping = json_object_array_get_idx(mapping_arr, 0); + else + mapping = NULL; parse_mapping_param(full_param, mapping, list); } @@ -668,14 +677,14 @@ static void parse_obj(char *object, json_object *jobj, DMOBJ *pobj, int index, s json_object_object_foreach(jobj, key, json_obj) { //bbfdm_type if (strcmp(key, "protocols") == 0) { - size_t n_proto = json_object_array_length(json_obj); + size_t n_proto = json_obj ? json_object_array_length(json_obj) : 0; if (n_proto == 2) pobj[index].bbfdm_type = BBFDM_BOTH; else if (n_proto == 1) { - struct json_object *proto = json_object_array_get_idx(json_obj, 0); - if (strcmp(json_object_get_string(proto), "cwmp") == 0) + struct json_object *proto = json_obj ? json_object_array_get_idx(json_obj, 0) : NULL; + if (proto && strcmp(json_object_get_string(proto), "cwmp") == 0) pobj[index].bbfdm_type = BBFDM_CWMP; - else if (strcmp(json_object_get_string(proto), "usp") == 0) + else if (proto && strcmp(json_object_get_string(proto), "usp") == 0) pobj[index].bbfdm_type = BBFDM_USP; else pobj[index].bbfdm_type = BBFDM_BOTH; diff --git a/dmdynamiclibrary.c b/dmdynamiclibrary.c index b7740f13..10dafda5 100644 --- a/dmdynamiclibrary.c +++ b/dmdynamiclibrary.c @@ -92,6 +92,8 @@ int load_library_dynamic_arrays(struct dmctx *ctx) void *handle = dlopen(buf, RTLD_LAZY); if (!handle) continue; + dlerror(); /* Clear any existing error */ + //Dynamic Object DM_MAP_OBJ *dynamic_obj = NULL; *(void **) (&dynamic_obj) = dlsym(handle, "tDynamicObj"); diff --git a/dmentry.c b/dmentry.c index 2c1ea4cf..8fb77ca4 100644 --- a/dmentry.c +++ b/dmentry.c @@ -202,14 +202,7 @@ int dm_entry_param_method(struct dmctx *ctx, int cmd, char *inparam, char *arg1, case CMD_SET_NOTIFICATION: if (arg2) err = string_to_bool(arg2, &setnotif); - if (!err && arg1 && - (strcmp(arg1, "0") == 0 || - strcmp(arg1, "1") == 0 || - strcmp(arg1, "2") == 0 || - strcmp(arg1, "3") == 0 || - strcmp(arg1, "4") == 0 || - strcmp(arg1, "5") == 0 || - strcmp(arg1, "6") == 0)) { + if (!err && arg1) { ctx->in_notification = arg1; ctx->setaction = VALUECHECK; ctx->notification_change = setnotif; @@ -219,7 +212,6 @@ int dm_entry_param_method(struct dmctx *ctx, int cmd, char *inparam, char *arg1, } break; case CMD_LIST_NOTIFY: - ctx->in_param = ""; fault = dm_entry_enabled_notify(ctx); break; case CMD_ADD_OBJECT: @@ -247,10 +239,10 @@ int dm_entry_param_method(struct dmctx *ctx, int cmd, char *inparam, char *arg1, fault = dm_entry_get_schema(ctx); break; case CMD_GET_INSTANCES: - if (arg1) - string_to_bool(arg1, &ctx->nextlevel); - - fault = dm_entry_get_instances(ctx); + if (!arg1 || (arg1 && string_to_bool(arg1, &ctx->nextlevel) == 0)) + fault = dm_entry_get_instances(ctx); + else + fault = FAULT_9003; break; } @@ -273,15 +265,11 @@ int dm_entry_apply(struct dmctx *ctx, int cmd, char *arg1, char *arg2) fault = dm_entry_set_value(ctx); if (fault) break; } - if (fault) { - //Should not happen - add_list_fault_param(ctx, ctx->in_param, usp_fault_map(fault)); - } else { + if (!fault) { dmuci_set_value("cwmp", "acs", "ParameterKey", arg1 ? arg1 : ""); dmuci_change_packages(&head_package_change); dmuci_save(); } - free_all_set_list_tmp(ctx); break; case CMD_SET_NOTIFICATION: ctx->setaction = VALUESET; @@ -296,9 +284,10 @@ int dm_entry_apply(struct dmctx *ctx, int cmd, char *arg1, char *arg2) dmuci_change_packages(&head_package_change); dmuci_save(); } - free_all_set_list_tmp(ctx); break; } + free_all_set_list_tmp(ctx); + return usp_fault_map(fault); } diff --git a/dmoperate.c b/dmoperate.c index aeae2b87..a7d4b13a 100644 --- a/dmoperate.c +++ b/dmoperate.c @@ -272,7 +272,7 @@ static void fill_wireless_scan_results(struct dmctx *dmctx, char *radio) if (!json_object_object_get_ex(res,"accesspoints", &obj)) return; - uint8_t len = json_object_array_length(obj); + uint8_t len = obj ? json_object_array_length(obj) : 0; for (uint8_t j = 0; j < len; j++ ) { wifi_neighbor_count++; json_object *array_obj = json_object_array_get_idx(obj, j); diff --git a/dmtree/tr181/security.c b/dmtree/tr181/security.c index e8a48c88..5609a4a5 100644 --- a/dmtree/tr181/security.c +++ b/dmtree/tr181/security.c @@ -25,9 +25,9 @@ struct certificate_profile { struct uci_section *dmmap_sect; }; -/************************************************************ - * Init function - *************************************************************/ +/************************************************************* +* INIT +**************************************************************/ void init_certificate(char *path, #ifdef LOPENSSL X509 *cert, @@ -45,6 +45,9 @@ struct uci_section *dmsect, struct certificate_profile *certprofile) certprofile->dmmap_sect = dmsect; } +/************************************************************* +* COMMON FUNCTIONS +**************************************************************/ #ifdef LOPENSSL static char *get_certificate_sig_alg(int sig_nid) { @@ -151,10 +154,18 @@ static char *get_certificate_pk(mbedtls_pk_type_t sig_pk) } #endif +static char *generate_serial_number(char *text, int length) +{ + int i, j; + char *hex = (char *)dmcalloc(100, sizeof(char)); -/************************************************************* -* ENTRY METHOD -**************************************************************/ + for (i = 0, j = 0; i < length; ++i, j += 3) { + sprintf(hex + j, "%02x", text[i] & 0xff); + if (i < length-1) + sprintf(hex + j + 2, "%c", ':'); + } + return hex; +} static void get_certificate_paths(void) { @@ -206,6 +217,9 @@ static void get_certificate_paths(void) } } +/************************************************************* +* ENTRY METHOD +**************************************************************/ static int browseSecurityCertificateInst(struct dmctx *dmctx, DMNODE *parent_node, void *prev_data, char *prev_instance) { #if defined(LOPENSSL) || defined(LMBEDTLS) @@ -328,10 +342,10 @@ static int get_SecurityCertificate_SerialNumber(char *refparam, struct dmctx *ct #ifdef LOPENSSL struct certificate_profile *cert_profile = (struct certificate_profile*)data; ASN1_INTEGER *serial = X509_get_serialNumber(cert_profile->openssl_cert); - *value = stringToHex((char *)serial->data, serial->length); + *value = generate_serial_number((char *)serial->data, serial->length); #elif LMBEDTLS struct certificate_profile *cert_profile = (struct certificate_profile*)data; - *value = stringToHex(cert_profile->mbdtls_cert.serial.p, cert_profile->mbdtls_cert.serial.len); + *value = generate_serial_number(cert_profile->mbdtls_cert.serial.p, cert_profile->mbdtls_cert.serial.len); #endif return 0; } diff --git a/dmtree/vendor/iopsys/tr181/x_iopsys_eu_igmp.c b/dmtree/vendor/iopsys/tr181/x_iopsys_eu_igmp.c index 31b6331e..75b02147 100644 --- a/dmtree/vendor/iopsys/tr181/x_iopsys_eu_igmp.c +++ b/dmtree/vendor/iopsys/tr181/x_iopsys_eu_igmp.c @@ -283,6 +283,48 @@ int get_mcast_snooping_interface_val(char *value, char *ifname, size_t s_ifname) return 0; } +void del_dmmap_sec_with_opt_eq(char *dmmap_file, char *section, char *option, char *value) +{ + struct uci_section *d_sec = NULL; + struct uci_section *stmp = NULL; + char *opt_val; + + uci_path_foreach_sections_safe(bbfdm, dmmap_file, section, stmp, d_sec) { + dmuci_get_value_by_section_string(d_sec, option, &opt_val); + if (strcmp(opt_val, value) == 0) + dmuci_delete_by_section_unnamed_bbfdm(d_sec, NULL, NULL); + } +} + +void sync_dmmap_bool_to_uci_list(struct uci_section *s, char *section, char *value, bool b) +{ + struct uci_list *v = NULL; + struct uci_element *e = NULL; + char *val = NULL; + + dmuci_get_value_by_section_list(s, section, &v); + if (v != NULL) { + uci_foreach_element(v, e) { + val = dmstrdup(e->name); + if (val && strcmp(val, value) == 0) { + if (!b) { + // remove this entry + dmuci_del_list_value_by_section(s, section, value); + } + + // Further action is not required + return; + } + } + } + + // If control has reached this point, that means, either the entry was not found + // in the list, hence, if b is true, add this entry to the list + if (b) { + dmuci_add_list_value_by_section(s, section, value); + } +} + int del_proxy_obj(void *data, char *proto, unsigned char del_action) { struct uci_section *s = NULL, *ss = NULL, *dmmap_section = NULL; diff --git a/dmtree/vendor/iopsys/tr181/x_iopsys_eu_igmp.h b/dmtree/vendor/iopsys/tr181/x_iopsys_eu_igmp.h index ee107fe0..39421779 100644 --- a/dmtree/vendor/iopsys/tr181/x_iopsys_eu_igmp.h +++ b/dmtree/vendor/iopsys/tr181/x_iopsys_eu_igmp.h @@ -83,6 +83,8 @@ int del_mcasts_filter_obj(char *refparam, struct dmctx *ctx, void *data, char *i void update_snooping_mode(struct uci_section *s); int get_mcast_snooping_interface_val(char *value, char *ifname, size_t s_ifname); int del_proxy_obj(void *data, char *proto, unsigned char del_action); +void del_dmmap_sec_with_opt_eq(char *dmmap_file, char *section, char *option, char *value); +void sync_dmmap_bool_to_uci_list(struct uci_section *s, char *section, char *value, bool b); int del_snooping_obj(void *data, char *proto, unsigned char del_action); void get_mcast_bridge_port_linker(struct dmctx *ctx, char *intf_name, char **value); int browse_proxy_interface_inst(struct dmctx *dmctx, DMNODE *parent_node, void *prev_data, char *proto); diff --git a/dmtree/vendor/openwrt/tr181/qos.c b/dmtree/vendor/openwrt/tr181/qos.c index ed3f2d23..e1040249 100644 --- a/dmtree/vendor/openwrt/tr181/qos.c +++ b/dmtree/vendor/openwrt/tr181/qos.c @@ -31,9 +31,34 @@ struct queuestats int backlog_requeues; }; -/************************************************************************** -* Browse functions -***************************************************************************/ +/************************************************************* +* COMMON FUNCTIONS +**************************************************************/ +int command_exec_output_to_array(const char *cmd, char **output, int *length) +{ + char out[2048]; + int i = 0; + + /* Open the command for reading. */ + FILE *fp = popen(cmd, "r"); + if (fp == NULL) + return -1; + + /* Read the output line by line and store it in output array. */ + while (fgets(out, sizeof(out)-1, fp) != NULL) + dmasprintf(&output[i++], "%s", out); + + *length = i; + + /* close */ + pclose(fp); + + return 0; +} + +/************************************************************* +* ENTRY METHOD +**************************************************************/ /*#Device.QoS.Classification.{i}.!UCI:qos/classify/dmmap_qos*/ static int openwrt__browseQoSClassificationInst(struct dmctx *dmctx, DMNODE *parent_node, void *prev_data, char *prev_instance) { @@ -122,6 +147,9 @@ end: return 0; } +/************************************************************* +* ADD & DEL OBJ +**************************************************************/ static int openwrt__addObjQoSClassification(char *refparam, struct dmctx *ctx, void *data, char **instance) { struct uci_section *s, *dmmap_qclassify; @@ -180,6 +208,9 @@ static int openwrt__delObjQoSQueueStats(char *refparam, struct dmctx *ctx, void return 0; } +/************************************************************* +* GET & SET PARAM +**************************************************************/ /*#Device.QoS.ClassificationNumberOfEntries!UCI:qos/classify/*/ static int openwrt__get_QClassificationNumberOfEntries(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) { diff --git a/gitlab-ci/functional-api-test.sh b/gitlab-ci/functional-api-test.sh new file mode 100755 index 00000000..3b1757c2 --- /dev/null +++ b/gitlab-ci/functional-api-test.sh @@ -0,0 +1,55 @@ +#!/bin/bash + +echo "Functional API Tests" +pwd +source ./gitlab-ci/shared.sh + +# compile and install libbbf +echo "Compiling libbbf" +if [ -f Makefile ]; then + exec_cmd make maintainer-clean + find -name '*.gcno' -exec rm {} -fv \; + find -name '*.gcov' -exec rm {} -fv \; + find -name '*.deps' -exec rm {} -rfv \; + rm -f *.log *.xml +fi + +exec_cmd autoreconf -i +exec_cmd ./configure --enable-tr181 --enable-tr104 --enable-tr143 --enable-bbf-test --enable-vendor-extension BBF_VENDOR_LIST="iopsys" +exec_cmd make CPPFLAGS=-DBBF_VENDOR_LIST=\\\"iopsys\\\" CPPFLAGS+=-DBBF_VENDOR_PREFIX=\\\"X_IOPSYS_EU_\\\" + +echo "installing libbbf" +exec_cmd make install +ldconfig + +echo "configuring libbbf" +mkdir -p /etc/bbfdm/ +mkdir -p /etc/bbfdm/dmmap +mkdir -p /etc/bbfdm/json +mkdir -p /usr/share/bbfdm +mkdir -p /usr/lib/bbfdm +cp -f scripts/* /usr/share/bbfdm + + +supervisorctl status all +supervisorctl update +sleep 3 +supervisorctl status all + + +echo "Running the functional API test cases" +make clean -C test/cmocka/ +make functional-api-test -C test/cmocka/ +check_ret $? + +supervisorctl stop all +supervisorctl status + +#report part +#GitLab-CI output +gcovr -r . 2> /dev/null #throw away stderr +# Artefact +gcovr -r . 2> /dev/null --xml -o ./functional-api-test-coverage.xml +date +%s > timestamp.log + +echo "Functional API Test :: PASS" diff --git a/gitlab-ci/functional-test.sh b/gitlab-ci/functional-test.sh new file mode 100755 index 00000000..6af4db95 --- /dev/null +++ b/gitlab-ci/functional-test.sh @@ -0,0 +1,66 @@ +#!/bin/bash + +echo "Functional Tests" +pwd +source ./gitlab-ci/shared.sh + +# link '/bin/sh' to bash instead of dash +ln -sf bash /bin/sh + +# compile and install libbbf +echo "Compiling libbbf" +if [ -f Makefile ]; then + exec_cmd make maintainer-clean + find -name '*.gcno' -exec rm {} -fv \; + find -name '*.gcov' -exec rm {} -fv \; + find -name '*.deps' -exec rm {} -rfv \; + rm -f *.log *.xml +fi + +exec_cmd autoreconf -i +exec_cmd ./configure --enable-tr181 --enable-tr104 --enable-tr143 --enable-bbf-test --enable-vendor-extension BBF_VENDOR_LIST="iopsys" +exec_cmd make CPPFLAGS=-DBBF_VENDOR_LIST=\\\"iopsys\\\" CPPFLAGS+=-DBBF_VENDOR_PREFIX=\\\"X_IOPSYS_EU_\\\" + +echo "installing libbbf" +exec_cmd make install +ldconfig + +echo "configuring libbbf" +mkdir -p /etc/bbfdm/ +mkdir -p /etc/bbfdm/dmmap +mkdir -p /etc/bbfdm/json +mkdir -p /usr/share/bbfdm +mkdir -p /usr/lib/bbfdm +cp -f scripts/* /usr/share/bbfdm + +# compile and install libbbf_test +echo "Compiling libbbf_test" +make clean -C test/bbf_test/ +make -C test/bbf_test/ + +echo "installing libbbf_test" +cp -f test/bbf_test/libbbf_test.so /usr/lib/bbfdm + + +supervisorctl status all +supervisorctl update +sleep 3 +supervisorctl status all + + +echo "Running the functional test cases" +make clean -C test/cmocka/ +make functional-test -C test/cmocka/ +check_ret $? + +supervisorctl stop all +supervisorctl status + +#report part +#GitLab-CI output +gcovr -r . 2> /dev/null #throw away stderr +# Artefact +gcovr -r . 2> /dev/null --xml -o ./functional-test-coverage.xml +date +%s > timestamp.log + +echo "Functional Test :: PASS" diff --git a/gitlab-ci/iopsys-supervisord.conf b/gitlab-ci/iopsys-supervisord.conf new file mode 100755 index 00000000..122a34d6 --- /dev/null +++ b/gitlab-ci/iopsys-supervisord.conf @@ -0,0 +1,5 @@ +[program:ubusd] +command=/bin/bash -c "/usr/sbin/ubusd" + +[program:rpcd] +command=/bin/bash -c "/usr/sbin/rpcd" diff --git a/gitlab-ci/setup.sh b/gitlab-ci/setup.sh new file mode 100755 index 00000000..9f1f0090 --- /dev/null +++ b/gitlab-ci/setup.sh @@ -0,0 +1,15 @@ +#!/bin/bash + +echo "preparation script" + +pwd + +cp -r ./test/files/etc/* /etc/ +cp -r ./test/files/usr/* /usr/ +cp -r ./test/files/var/* /var/ +cp -r ./test/files/tmp/* /tmp/ + +cp ./gitlab-ci/iopsys-supervisord.conf /etc/supervisor/conf.d/ + +ls /etc/config/ +ls /etc/supervisor/conf.d/ diff --git a/gitlab-ci/shared.sh b/gitlab-ci/shared.sh new file mode 100755 index 00000000..fa9b5d73 --- /dev/null +++ b/gitlab-ci/shared.sh @@ -0,0 +1,23 @@ +#!/bin/bash + +function check_ret() +{ + ret=$1 + if [ "$ret" -ne 0 ]; then + echo "Validation of last command failed, ret(${ret})" + exit $ret + fi + +} + +function exec_cmd() +{ + echo "executing $@" + $@ >/dev/null 2>&1 + + if [ $? -ne 0 ]; then + echo "Failed to execute $@" + exit 1 + fi +} + diff --git a/gitlab-ci/unit-test.sh b/gitlab-ci/unit-test.sh new file mode 100755 index 00000000..41ccc5ee --- /dev/null +++ b/gitlab-ci/unit-test.sh @@ -0,0 +1,66 @@ +#!/bin/bash + +echo "Unit Tests" +pwd +source ./gitlab-ci/shared.sh + +# link '/bin/sh' to bash instead of dash +ln -sf bash /bin/sh + +# compile and install libbbf +echo "Compiling libbbf" +if [ -f Makefile ]; then + exec_cmd make maintainer-clean + find -name '*.gcno' -exec rm {} -fv \; + find -name '*.gcov' -exec rm {} -fv \; + find -name '*.deps' -exec rm {} -rfv \; + rm -f *.log *.xml +fi + +exec_cmd autoreconf -i +exec_cmd ./configure --enable-tr181 --enable-tr104 --enable-tr143 --enable-bbf-test --enable-vendor-extension BBF_VENDOR_LIST="iopsys" +exec_cmd make CPPFLAGS=-DBBF_VENDOR_LIST=\\\"iopsys\\\" CPPFLAGS+=-DBBF_VENDOR_PREFIX=\\\"X_IOPSYS_EU_\\\" + +echo "installing libbbf" +exec_cmd make install +ldconfig + +echo "configuring libbbf" +mkdir -p /etc/bbfdm/ +mkdir -p /etc/bbfdm/dmmap +mkdir -p /etc/bbfdm/json +mkdir -p /usr/share/bbfdm +mkdir -p /usr/lib/bbfdm +cp -f scripts/* /usr/share/bbfdm + +# compile and install libbbf_test +echo "Compiling libbbf_test" +make clean -C test/bbf_test/ +make -C test/bbf_test/ + +echo "installing libbbf_test" +cp -f test/bbf_test/libbbf_test.so /usr/lib/bbfdm + + +supervisorctl status all +supervisorctl update +sleep 3 +supervisorctl status all + + +echo "Running the unit test cases" +make clean -C test/cmocka/ +make unit-test -C test/cmocka/ +check_ret $? + +supervisorctl stop all +supervisorctl status + +#report part +#GitLab-CI output +gcovr -r . 2> /dev/null #throw away stderr +# Artefact +gcovr -r . 2> /dev/null --xml -o ./unit-test-coverage.xml +date +%s > timestamp.log + +echo "Unit test PASS" diff --git a/libbbf_api/dmcommon.c b/libbbf_api/dmcommon.c index c515c624..5647c69e 100644 --- a/libbbf_api/dmcommon.c +++ b/libbbf_api/dmcommon.c @@ -957,28 +957,6 @@ int get_shift_time_time(int shift_time, char *local_time, int size) return 0; } -int command_exec_output_to_array(const char *cmd, char **output, int *length) -{ - char out[2048]; - int i = 0; - - /* Open the command for reading. */ - FILE *fp = popen(cmd, "r"); - if (fp == NULL) - return -1; - - /* Read the output line by line and store it in output array. */ - while (fgets(out, sizeof(out)-1, fp) != NULL) - dmasprintf(&output[i++], "%s", out); - - *length = i; - - /* close */ - pclose(fp); - - return 0; -} - static inline int char_is_valid(char c) { return c >= 0x20 && c < 0x7f; @@ -1463,19 +1441,6 @@ char *decode64(char *enc) return dec; } -char *stringToHex(char *text, int length) -{ - int i, j; - char *hex = (char *)dmcalloc(100, sizeof(char)); - - for (i = 0, j = 0; i < length; ++i, j += 3) { - sprintf(hex + j, "%02x", text[i] & 0xff); - if (i < length-1) - sprintf(hex + j + 2, "%c", ':'); - } - return hex; -} - char *replace_char(char *str, char find, char replace) { char *current_pos = strchr(str, find); @@ -1516,48 +1481,6 @@ char *replace_str(const char *str, const char *substr, const char *replacement) return value; } -void del_dmmap_sec_with_opt_eq(char *dmmap_file, char *section, char *option, char *value) -{ - struct uci_section *d_sec = NULL; - struct uci_section *stmp = NULL; - char *opt_val; - - uci_path_foreach_sections_safe(bbfdm, dmmap_file, section, stmp, d_sec) { - dmuci_get_value_by_section_string(d_sec, option, &opt_val); - if (strcmp(opt_val, value) == 0) - dmuci_delete_by_section_unnamed_bbfdm(d_sec, NULL, NULL); - } -} - -void sync_dmmap_bool_to_uci_list(struct uci_section *s, char *section, char *value, bool b) -{ - struct uci_list *v = NULL; - struct uci_element *e = NULL; - char *val = NULL; - - dmuci_get_value_by_section_list(s, section, &v); - if (v != NULL) { - uci_foreach_element(v, e) { - val = dmstrdup(e->name); - if (val && strcmp(val, value) == 0) { - if (!b) { - // remove this entry - dmuci_del_list_value_by_section(s, section, value); - } - - // Further action is not required - return; - } - } - } - - // If control has reached this point, that means, either the entry was not found - // in the list, hence, if b is true, add this entry to the list - if (b) { - dmuci_add_list_value_by_section(s, section, value); - } -} - int check_browse_section(struct uci_section *s, void *data) { struct browse_args *browse_args = (struct browse_args *)data; diff --git a/libbbf_api/dmcommon.h b/libbbf_api/dmcommon.h index 9da9cca0..343eb524 100644 --- a/libbbf_api/dmcommon.h +++ b/libbbf_api/dmcommon.h @@ -263,7 +263,6 @@ struct uci_section *get_dup_section_in_dmmap_opt(char *dmmap_package, char *sect struct uci_section *get_dup_section_in_dmmap_eq(char *dmmap_package, char* section_type, char*sect_name, char *opt_name, char* opt_value); bool elt_exists_in_array(char **str_array, char *str, int length); int get_shift_time_time(int shift_time, char *local_time, int size); -int command_exec_output_to_array(const char *cmd, char **output, int *length); struct uci_section *is_dmmap_section_exist(char* package, char* section); struct uci_section *is_dmmap_section_exist_eq(char* package, char* section, char* opt, char* value); int dm_read_sysfs_file(const char *file, char *dst, unsigned len); @@ -290,10 +289,7 @@ bool folder_exists(const char *path); bool file_exists(const char *path); bool is_regular_file(const char *path); unsigned long file_system_size(const char *path, const enum fs_size_type_enum type); -char *stringToHex(char *text, int length); char *replace_char(char *str, char find, char replace); char *replace_str(const char *str, const char *substr, const char *replacement); -void sync_dmmap_bool_to_uci_list(struct uci_section *s, char *section, char *value, bool b); -void del_dmmap_sec_with_opt_eq(char *dmmap_file, char *section, char *option, char *value); int check_browse_section(struct uci_section *s, void *data); #endif diff --git a/libbbf_api/dmjson.c b/libbbf_api/dmjson.c index 99677bb6..cfa87ca7 100644 --- a/libbbf_api/dmjson.c +++ b/libbbf_api/dmjson.c @@ -12,6 +12,17 @@ #include "dmjson.h" +static json_object *dmjson_select_obj(json_object *jobj, char *argv[]) +{ + int i; + for (i = 0; argv[i]; i++) { + if (jobj == NULL) + return NULL; + json_object_object_get_ex(jobj, argv[i], &jobj); + } + return jobj; +} + static char *dmjson_print_value(json_object *jobj) { enum json_type type; @@ -34,9 +45,9 @@ static char *dmjson_print_value(json_object *jobj) return ret; } -char *____dmjson_get_value_in_obj(json_object *mainjobj, char *argv[]) +static char *____dmjson_get_value_in_obj(json_object *mainjobj, char *argv[]) { - json_object *jobj = bbf_api_dmjson_select_obj(mainjobj, argv); + json_object *jobj = dmjson_select_obj(mainjobj, argv); return dmjson_print_value(jobj); } @@ -68,26 +79,15 @@ json_object *__dmjson_get_obj(json_object *mainjobj, int argc, ...) } argv[argc] = NULL; va_end(arg); - return bbf_api_dmjson_select_obj(mainjobj, argv); + return dmjson_select_obj(mainjobj, argv); } -json_object *bbf_api_dmjson_select_obj(json_object *jobj, char *argv[]) -{ - int i; - for (i = 0; argv[i]; i++) { - if (jobj == NULL) - return NULL; - json_object_object_get_ex(jobj, argv[i], &jobj); - } - return jobj; -} - -json_object *____dmjson_select_obj_in_array_idx(json_object *mainjobj, json_object **arrobj, int index, char *argv[]) +static json_object *____dmjson_select_obj_in_array_idx(json_object *mainjobj, json_object **arrobj, int index, char *argv[]) { json_object *jobj = NULL; if (arrobj == NULL || *arrobj == NULL) { - jobj = bbf_api_dmjson_select_obj(mainjobj, argv); + jobj = dmjson_select_obj(mainjobj, argv); if (arrobj) *arrobj = jobj; if (jobj && json_object_get_type(jobj) == json_type_array) { @@ -124,13 +124,13 @@ json_object *__dmjson_select_obj_in_array_idx(json_object *mainjobj, json_object return jobj; } -char *____dmjson_get_value_in_array_idx(json_object *mainjobj, json_object **arrobj, int index, char *argv[]) +static char *____dmjson_get_value_in_array_idx(json_object *mainjobj, json_object **arrobj, int index, char *argv[]) { json_object *jobj = NULL; char *value = NULL; if (arrobj == NULL || *arrobj == NULL) { - jobj = bbf_api_dmjson_select_obj(mainjobj, argv); + jobj = dmjson_select_obj(mainjobj, argv); if (arrobj) *arrobj = jobj; if (jobj && json_object_get_type(jobj) == json_type_array) { @@ -169,7 +169,7 @@ char *__dmjson_get_value_in_array_idx(json_object *mainjobj, json_object **arrob return (v ? v : defret) ; } -char *____dmjson_get_value_array_all(json_object *mainjobj, char *delim, char *argv[]) +static char *____dmjson_get_value_array_all(json_object *mainjobj, char *delim, char *argv[]) { json_object *arrobj; char *v, *ret = ""; diff --git a/libbbf_api/dmjson.h b/libbbf_api/dmjson.h index 295751db..b4c57286 100644 --- a/libbbf_api/dmjson.h +++ b/libbbf_api/dmjson.h @@ -27,14 +27,10 @@ struct dmjson_arg { #define DMJSON_ARGS (struct dmjson_arg[]) -json_object *bbf_api_dmjson_select_obj(json_object * jobj, char *argv[]); json_object *__dmjson_get_obj(json_object *mainjobj, int argc, ...); -char *____dmjson_get_value_in_obj(json_object *mainjobj, char *argv[]); char *__dmjson_get_value_in_obj(json_object *mainjobj, int argc, ...); char *__dmjson_get_value_in_array_idx(json_object *mainjobj, json_object **arrobj, char *defret, int index, int argc, ...); json_object *__dmjson_select_obj_in_array_idx(json_object *mainjobj, json_object **arrobj, int index, int argc, ...); - -char *____dmjson_get_value_array_all(json_object *mainjobj, char *delim, char *argv[]); char *__dmjson_get_value_array_all(json_object *mainjobj, char *delim, int argc, ...); #define dmjson_get_value(JOBJ,ARGC,args...) \ @@ -43,9 +39,6 @@ char *__dmjson_get_value_array_all(json_object *mainjobj, char *delim, int argc, #define dmjson_get_obj(JOBJ,ARGC,args...) \ __dmjson_get_obj(JOBJ, ARGC, ##args) -#define dmjson_get_value_in_array_idx(MAINJOBJ,INDEX,ARGC,args...) \ - __dmjson_get_value_in_array_idx(MAINJOBJ, NULL, "", INDEX, ARGC, ##args) - #define dmjson_select_obj_in_array_idx(MAINJOBJ,INDEX,ARGC,args...) \ __dmjson_select_obj_in_array_idx(MAINJOBJ, NULL, INDEX, ARGC, ##args) diff --git a/scripts/bbf_uci_api b/scripts/bbf_uci_api index 7f744f20..3bffbda0 100755 --- a/scripts/bbf_uci_api +++ b/scripts/bbf_uci_api @@ -1,18 +1,18 @@ #!/bin/sh -UCI_GET="/sbin/uci -q get" -UCI_SET="/sbin/uci -q set" -UCI_ADD="/sbin/uci -q add" -UCI_DELETE="/sbin/uci -q delete" -UCI_COMMIT="/sbin/uci -q commit" -UCI_SHOW="/sbin/uci -q show" +UCI_GET="uci -q get" +UCI_SET="uci -q set" +UCI_ADD="uci -q add" +UCI_DELETE="uci -q delete" +UCI_COMMIT="uci -q commit" +UCI_SHOW="uci -q show" -UCI_GET_BBF_DMMAP="/sbin/uci -q -c /etc/bbfdm/dmmap get" -UCI_SET_BBF_DMMAP="/sbin/uci -q -c /etc/bbfdm/dmmap set" -UCI_ADD_BBF_DMMAP="/sbin/uci -q -c /etc/bbfdm/dmmap add" -UCI_DELETE_BBF_DMMAP="/sbin/uci -q -c /etc/bbfdm/dmmap delete" -UCI_COMMIT_BBF_DMMAP="/sbin/uci -q -c /etc/bbfdm/dmmap commit" -UCI_SHOW_BBF_DMMAP="/sbin/uci -q -c /etc/bbfdm/dmmap show" +UCI_GET_BBF_DMMAP="uci -q -c /etc/bbfdm/dmmap get" +UCI_SET_BBF_DMMAP="uci -q -c /etc/bbfdm/dmmap set" +UCI_ADD_BBF_DMMAP="uci -q -c /etc/bbfdm/dmmap add" +UCI_DELETE_BBF_DMMAP="uci -q -c /etc/bbfdm/dmmap delete" +UCI_COMMIT_BBF_DMMAP="uci -q -c /etc/bbfdm/dmmap commit" +UCI_SHOW_BBF_DMMAP="uci -q -c /etc/bbfdm/dmmap show" uci_get() { local val=`$UCI_GET $1` diff --git a/test/bbf_test/Makefile b/test/bbf_test/Makefile new file mode 100644 index 00000000..092dbd4c --- /dev/null +++ b/test/bbf_test/Makefile @@ -0,0 +1,16 @@ +LIB = libbbf_test.so + +LIB_OBJS = libbbf_test.o +LIB_CFLAGS = $(CFLAGS) -Wall -Werror -fPIC +LIB_LDFLAGS = $(LDFLAGS) -lbbf_api + +%.o: %.c + $(CC) $(PROG_CFLAGS) $(FPIC) -c -o $@ $< + +all: $(LIB) + +$(LIB): $(LIB_OBJS) + $(CC) $(LIB_CFLAGS) $(LIB_LDFLAGS) -shared -o $@ $^ + +clean: + rm -fv *.o $(LIB) diff --git a/test/bbf_test/libbbf_test.c b/test/bbf_test/libbbf_test.c new file mode 100644 index 00000000..b1d5b39d --- /dev/null +++ b/test/bbf_test/libbbf_test.c @@ -0,0 +1,365 @@ +/* + * Copyright (C) 2021 iopsys Software Solutions AB + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 2.1 + * as published by the Free Software Foundation + * + * Author: Amin Ben Ramdhane + */ + +#include +#include +#include +#include +#include + +#include "libbbf_test.h" + +/* ********** DynamicObj ********** */ +DM_MAP_OBJ tDynamicObj[] = { +/* parentobj, nextobject, parameter */ +{"Device.ManagementServer.", tDynamicManagementServerObj, tDynamicManagementServerParams}, +{"Device.", tDynamicDeviceObj, NULL}, +{0} +}; + +/* ********** DynamicOperate ********** */ +DM_MAP_OPERATE tDynamicOperate[] = { +/* pathname, operation, type, args */ +{ + "Device.X_IOPSYS_EU_PingTEST.Run", DynamicDevicePingOperate, "async", + { + .in = (const char *[]) { + "Host", + NULL + }, + .out = (const char *[]) { + "AverageResponseTime", + "MinimumResponseTime", + "MaximumResponseTime", + NULL + } + } +}, +{ + "Device.X_IOPSYS_EU_Reboot", DynamicDeviceRebootOperate, "sync" +}, +{0} +}; + +/************************************************************* +* ENTRY METHOD +**************************************************************/ +static int browseManagementServerInformParameterInst(struct dmctx *dmctx, DMNODE *parent_node, void *prev_data, char *prev_instance) +{ + char *inst = NULL, *max_inst = NULL; + struct dmmap_dup *p = NULL; + LIST_HEAD(dup_list); + + synchronize_specific_config_sections_with_dmmap("cwmp", "inform_extra", "dmmap_cwmp", &dup_list); + list_for_each_entry(p, &dup_list, list) { + + inst = handle_update_instance(1, dmctx, &max_inst, update_instance_alias, 3, + p->dmmap_section, "inform_instance", "inform_alias"); + + if (DM_LINK_INST_OBJ(dmctx, parent_node, (void *)p->config_section, inst) == DM_STOP) + break; + } + free_dmmap_config_dup_list(&dup_list); + return 0; +} + +/************************************************************* +* ADD & DEL OBJ +**************************************************************/ +static int addObjManagementServerInformParameter(char *refparam, struct dmctx *ctx, void *data, char **instance) +{ + struct uci_section *s = NULL, *dmmap_s = NULL; + + char *last_inst = get_last_instance_bbfdm("dmmap_cwmp", "inform_extra", "inform_instance"); + + dmuci_add_section("cwmp", "inform_extra", &s); + + dmuci_add_section_bbfdm("dmmap_cwmp", "inform_extra", &dmmap_s); + dmuci_set_value_by_section(dmmap_s, "section_name", section_name(s)); + *instance = update_instance(last_inst, 2, dmmap_s, "inform_instance"); + return 0; +} + +static int delObjManagementServerInformParameter(char *refparam, struct dmctx *ctx, void *data, char *instance, unsigned char del_action) +{ + struct uci_section *s = NULL, *stmp = NULL, *dmmap_s = NULL; + + switch (del_action) { + case DEL_INST: + get_dmmap_section_of_config_section("dmmap_cwmp", "inform_extra", section_name((struct uci_section *)data), &dmmap_s); + dmuci_delete_by_section_unnamed_bbfdm(dmmap_s, NULL, NULL); + + dmuci_delete_by_section((struct uci_section *)data, NULL, NULL); + break; + case DEL_ALL: + uci_foreach_sections_safe("cwmp", "inform_extra", stmp, s) { + get_dmmap_section_of_config_section("dmmap_cwmp", "inform_extra", section_name(s), &dmmap_s); + dmuci_delete_by_section(dmmap_s, NULL, NULL); + + dmuci_delete_by_section(s, NULL, NULL); + + } + break; + } + return 0; +} + +/************************************************************* +* GET & SET PARAM +**************************************************************/ +static int get_ManagementServer_EnableCWMP(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) +{ + *value = dmuci_get_option_value_fallback_def("cwmp", "acs", "enabled", "1"); + return 0; +} + +static int set_ManagementServer_EnableCWMP(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action) +{ + bool b; + + switch (action) { + case VALUECHECK: + if (dm_validate_boolean(value)) + return FAULT_9007; + break; + case VALUESET: + string_to_bool(value, &b); + dmuci_set_value("cwmp", "acs", "enabled", b ? "1" : "0"); + break; + } + return 0; +} + +static int get_ManagementServerInformParameter_Enable(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) +{ + *value = dmuci_get_value_by_section_fallback_def((struct uci_section *)data, "enabled", "1"); + return 0; +} + +static int set_ManagementServerInformParameter_Enable(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action) +{ + bool b; + + switch (action) { + case VALUECHECK: + if (dm_validate_boolean(value)) + return FAULT_9007; + break; + case VALUESET: + string_to_bool(value, &b); + dmuci_set_value_by_section((struct uci_section *)data, "enabled", b ? "1" : "0"); + break; + } + return 0; +} + +static int get_ManagementServerInformParameter_Alias(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) +{ + struct uci_section *dmmap_section = NULL; + + get_dmmap_section_of_config_section("dmmap_cwmp", "inform_extra", section_name((struct uci_section *)data), &dmmap_section); + dmuci_get_value_by_section_string(dmmap_section, "inform_alias", value); + if ((*value)[0] == '\0') + dmasprintf(value, "cpe-%s", instance); + return 0; +} + +static int set_ManagementServerInformParameter_Alias(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action) +{ + struct uci_section *dmmap_section = NULL; + + switch (action) { + case VALUECHECK: + if (dm_validate_string(value, -1, 64, NULL, NULL)) + return FAULT_9007; + break; + case VALUESET: + get_dmmap_section_of_config_section("dmmap_cwmp", "inform_extra", section_name((struct uci_section *)data), &dmmap_section); + dmuci_set_value_by_section(dmmap_section, "inform_alias", value); + break; + } + return 0; +} + +static int get_ManagementServerInformParameter_ParameterName(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) +{ + dmuci_get_value_by_section_string((struct uci_section *)data, "parameter", value); + return 0; +} + +static int set_ManagementServerInformParameter_ParameterName(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action) +{ + switch (action) { + case VALUECHECK: + if (dm_validate_string(value, -1, 256, NULL, NULL)) + return FAULT_9007; + break; + case VALUESET: + dmuci_set_value_by_section((struct uci_section *)data, "parameter", value); + break; + } + return 0; +} + +static int get_ManagementServerInformParameter_EventList(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) +{ + dmuci_get_value_by_section_string((struct uci_section *)data, "events", value); + return 0; +} + +static int set_ManagementServerInformParameter_EventList(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action) +{ + switch (action) { + case VALUECHECK: + if (dm_validate_string_list(value, -1, -1, -1, -1, -1, NULL, NULL)) + return FAULT_9007; + break; + case VALUESET: + dmuci_set_value_by_section((struct uci_section *)data, "events", value); + break; + } + return 0; +} + +static int get_X_IOPSYS_EU_Syslog_ServerIPAddress(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) +{ + dmuci_get_option_value_string("system", "@system[0]", "log_ip", value); + return 0; +} + +static int set_X_IOPSYS_EU_Syslog_ServerIPAddress(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action) +{ + switch (action) { + case VALUECHECK: + return 0; + case VALUESET: + dmuci_set_value("system", "@system[0]", "log_ip", value); + return 0; + } + return 0; +} + +static int get_X_IOPSYS_EU_Syslog_ServerPort(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) +{ + *value = dmuci_get_option_value_fallback_def("system", "@system[0]", "log_port", "514"); + return 0; +} + +static int set_X_IOPSYS_EU_Syslog_ServerPort(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action) +{ + switch (action) { + case VALUECHECK: + return 0; + case VALUESET: + dmuci_set_value("system", "@system[0]", "log_port", value); + return 0; + } + return 0; +} + +static int get_X_IOPSYS_EU_Syslog_ConsoleLogLevel(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) +{ + *value = dmuci_get_option_value_fallback_def("system", "@system[0]", "conloglevel", "7"); + return 0; +} + +static int set_X_IOPSYS_EU_Syslog_ConsoleLogLevel(char *refparam, struct dmctx *ctx, void *data, char *instance, char *value, int action) +{ + switch (action) { + case VALUECHECK: + return 0; + case VALUESET: + dmuci_set_value("system", "@system[0]", "conloglevel", value); + return 0; + } + return 0; +} + +/************************************************************* + * OPERATE + *************************************************************/ +opr_ret_t DynamicDevicePingOperate(struct dmctx *dmctx, char *path, json_object *input) +{ + char *p, *min = NULL, *avg = NULL, *max = NULL, line[512], command[512]; + FILE *log = NULL; + + char *host = dmjson_get_value(input, 1, "Host"); + if(host[0] == '\0') + return UBUS_INVALID_ARGUMENTS; + + snprintf(command, sizeof(command), "ping -c 1 -W 1 %s", host); + + if ((log = popen(command, "r"))) { + while (fgets(line, sizeof(line), log) != NULL) { + if (strstr(line, "rtt")) { + strtok_r(line, "=", &min); + strtok_r(min+1, "/", &avg); + add_list_parameter(dmctx, dmstrdup("MinimumResponseTime"), dmstrdup(min ? min+1 : ""), "xsd:unsignedInt", NULL); + strtok_r(avg, "/", &max); + add_list_parameter(dmctx, dmstrdup("AverageResponseTime"), dmstrdup(avg ? avg : ""), "xsd:unsignedInt", NULL); + strtok_r(max, "/", &p); + add_list_parameter(dmctx, dmstrdup("MaximumResponseTime"), dmstrdup(max ? max : ""), "xsd:unsignedInt", NULL); + break; + } + } + pclose(log); + } + return SUCCESS; +} + +opr_ret_t DynamicDeviceRebootOperate(struct dmctx *dmctx, char *path, json_object *input) +{ + if (0 == dmubus_call_set("system", "reboot", UBUS_ARGS{}, 0)) + return SUCCESS; + else + return FAIL; +} + +/********************************************************************************************************************************** +* OBJ & PARAM DEFINITION +***********************************************************************************************************************************/ +/* *** Device.ManagementServer. *** */ +DMOBJ tDynamicManagementServerObj[] = { +/* OBJ, permission, addobj, delobj, checkdep, browseinstobj, nextdynamicobj, dynamicleaf, nextobj, leaf, linker, bbfdm_type, uniqueKeys*/ +{"InformParameter", &DMWRITE, addObjManagementServerInformParameter, delObjManagementServerInformParameter, NULL, browseManagementServerInformParameterInst, NULL, NULL, NULL, tManagementServerInformParameterParams, NULL, BBFDM_CWMP, LIST_KEY{"Alias", "ParameterName", NULL}}, +{0} +}; + +DMLEAF tDynamicManagementServerParams[] = { +/* PARAM, permission, type, getvalue, setvalue, bbfdm_type*/ +{"EnableCWMP", &DMWRITE, DMT_BOOL, get_ManagementServer_EnableCWMP, set_ManagementServer_EnableCWMP, BBFDM_CWMP}, +{0} +}; + +/* *** Device.ManagementServer.InformParameter.{i}. *** */ +DMLEAF tManagementServerInformParameterParams[] = { +/* PARAM, permission, type, getvalue, setvalue, bbfdm_type*/ +{"Enable", &DMWRITE, DMT_BOOL, get_ManagementServerInformParameter_Enable, set_ManagementServerInformParameter_Enable, BBFDM_CWMP}, +{"Alias", &DMWRITE, DMT_STRING, get_ManagementServerInformParameter_Alias, set_ManagementServerInformParameter_Alias, BBFDM_CWMP}, +{"ParameterName", &DMWRITE, DMT_STRING, get_ManagementServerInformParameter_ParameterName, set_ManagementServerInformParameter_ParameterName, BBFDM_CWMP}, +{"EventList", &DMWRITE, DMT_STRING, get_ManagementServerInformParameter_EventList, set_ManagementServerInformParameter_EventList, BBFDM_CWMP}, +{0} +}; + +/* *** Device. *** */ +DMOBJ tDynamicDeviceObj[] = { +/* OBJ, permission, addobj, delobj, checkdep, browseinstobj, nextdynamicobj, dynamicleaf, nextobj, leaf, linker, bbfdm_type, uniqueKeys*/ +{"X_IOPSYS_EU_Syslog", &DMREAD, NULL, NULL, "file:/etc/config/system", NULL, NULL, NULL, NULL, tX_IOPSYS_EU_SyslogParam, NULL, BBFDM_BOTH}, +{0} +}; + +/*** Device.X_IOPSYS_EU_Syslog. ***/ +DMLEAF tX_IOPSYS_EU_SyslogParam[] = { +/* PARAM, permission, type, getvalue, setvalue, bbfdm_type*/ +{"ServerIPAddress", &DMWRITE, DMT_STRING, get_X_IOPSYS_EU_Syslog_ServerIPAddress, set_X_IOPSYS_EU_Syslog_ServerIPAddress, BBFDM_BOTH}, +{"ServerPort", &DMWRITE, DMT_UNINT, get_X_IOPSYS_EU_Syslog_ServerPort, set_X_IOPSYS_EU_Syslog_ServerPort, BBFDM_BOTH}, +{"ConsoleLogLevel", &DMWRITE, DMT_UNINT, get_X_IOPSYS_EU_Syslog_ConsoleLogLevel, set_X_IOPSYS_EU_Syslog_ConsoleLogLevel, BBFDM_BOTH}, +{0} +}; diff --git a/test/bbf_test/libbbf_test.h b/test/bbf_test/libbbf_test.h new file mode 100644 index 00000000..8861adb4 --- /dev/null +++ b/test/bbf_test/libbbf_test.h @@ -0,0 +1,24 @@ +/* + * Copyright (C) 2021 iopsys Software Solutions AB + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 2.1 + * as published by the Free Software Foundation + * + * Author: Amin Ben Ramdhane + */ + +#ifndef __LIBBBFD_TEST_H +#define __LIBBBFD_TEST_H + +extern DMOBJ tDynamicManagementServerObj[]; +extern DMLEAF tDynamicManagementServerParams[]; +extern DMLEAF tManagementServerInformParameterParams[]; +extern DMOBJ tDynamicDeviceObj[]; +extern DMLEAF tX_IOPSYS_EU_SyslogParam[]; + +opr_ret_t DynamicDevicePingOperate(struct dmctx *dmctx, char *path, json_object *input); +opr_ret_t DynamicDeviceRebootOperate(struct dmctx *dmctx, char *path, json_object *input); + +#endif //__LIBBBFD_TEST_H + diff --git a/test/cmocka/Makefile b/test/cmocka/Makefile new file mode 100644 index 00000000..8d0cdeaf --- /dev/null +++ b/test/cmocka/Makefile @@ -0,0 +1,34 @@ +CC = gcc +CFLAGS = -g -Wall -Werror +LDFLAGS = -lcmocka -lbbfdm -lbbf_api +LDFLAGS_API_TEST = -lcmocka -lbbf_api +UNIT_TESTS = unit_test_bbfd +FUNCTIONAL_TESTS = functional_test_bbfd +FUNCTIONAL_API_TESTS = functional_api_test_bbfd + +VALGRIND = valgrind --show-reachable=yes \ + --show-leak-kinds=all --errors-for-leak-kinds=all \ + --error-exitcode=1 --track-origins=yes + +unit_test_bbfd: unit_test_bbfd.o + $(CC) -o $@ $^ $(LDFLAGS) + +functional_test_bbfd: functional_test_bbfd.o + $(CC) -o $@ $^ $(LDFLAGS) + +functional_api_test_bbfd: functional_api_test_bbfd.o + $(CC) -o $@ $^ $(LDFLAGS_API_TEST) + +unit-test: $(UNIT_TESTS) + $(foreach testprog, $(UNIT_TESTS), sudo $(VALGRIND) ./$(testprog);) + +functional-test: $(FUNCTIONAL_TESTS) + $(foreach testprog, $(FUNCTIONAL_TESTS), sudo $(VALGRIND) ./$(testprog);) + +functional-api-test: $(FUNCTIONAL_API_TESTS) + $(foreach testprog, $(FUNCTIONAL_API_TESTS), sudo $(VALGRIND) ./$(testprog);) + +.PHONY: clean +clean: + rm -fv *.o $(UNIT_TESTS) $(FUNCTIONAL_TESTS) $(FUNCTIONAL_API_TESTS) + diff --git a/test/cmocka/functional_api_test_bbfd.c b/test/cmocka/functional_api_test_bbfd.c new file mode 100644 index 00000000..9a937150 --- /dev/null +++ b/test/cmocka/functional_api_test_bbfd.c @@ -0,0 +1,961 @@ +#include +#include +#include +#include + +#include +#include + +static int setup_teardown(void **state) +{ + bbf_uci_init(); + return 0; +} + +static int group_teardown(void **state) +{ + bbf_uci_exit(); + dmubus_free(); + dmcleanmem(); + return 0; +} + +static void test_bbf_api_uci(void **state) +{ + struct uci_section *uci_s = NULL; + struct uci_list *ulist = NULL; + char *value = NULL; + int uci_res = 0; + + /* + * Test of dmuci_get_section_type function + */ + + // dmuci_get_section_type: test with correct config and wrong section + uci_res = dmuci_get_section_type("cwmp", "@notifications[0]", &value); + assert_int_equal(uci_res, -1); + assert_string_equal(value, ""); + + // dmuci_get_section_type: test with wrong config and correct section + uci_res = dmuci_get_section_type("tett", "@notifications[0]", &value); + assert_int_equal(uci_res, -1); + assert_string_equal(value, ""); + + // dmuci_get_section_type: test with correct config/section + uci_res = dmuci_get_section_type("cwmp", "@inform_extra[0]", &value); + assert_int_equal(uci_res, 0); + assert_string_not_equal(value, ""); + + // dmuci_get_section_type: test with correct config/section + uci_res = dmuci_get_section_type("network", "wan", &value); + assert_int_equal(uci_res, 0); + assert_string_not_equal(value, ""); + + /* + * Test of dmuci_get_option_value_string function + */ + + // dmuci_get_option_value_string: test with correct section/option and wrong config name + uci_res = dmuci_get_option_value_string("netwo", "lann", "vendorid", &value); + assert_int_equal(uci_res, -1); + assert_string_equal(value, ""); + + // dmuci_get_option_value_string: test with correct config/option and wrong section name + uci_res = dmuci_get_option_value_string("network", "lann", "vendorid", &value); + assert_int_equal(uci_res, -1); + assert_string_equal(value, ""); + + // dmuci_get_option_value_string: test with correct config/section and wrong option name + uci_res = dmuci_get_option_value_string("network", "wan", "tetst", &value); + assert_int_equal(uci_res, -1); + assert_string_equal(value, ""); + + // dmuci_get_option_value_string: test correct config/section/option + uci_res = dmuci_get_option_value_string("network", "wan", "vendorid", &value); + assert_int_equal(uci_res, 0); + assert_string_equal(value, "eg400"); + + // dmuci_get_option_value_string: test correct config/section/option + uci_res = dmuci_get_option_value_string("dropbear", "@dropbear[0]", "Port", &value); + assert_int_equal(uci_res, 0); + assert_string_equal(value, "22"); + + /* + * Test of dmuci_get_option_value_list function + */ + + // dmuci_get_option_value_list: test with correct config/section/option + uci_res = dmuci_get_option_value_list("systemm", "ntp", "server", &ulist); + assert_int_equal(uci_res, -1); + assert_null(ulist); + + // dmuci_get_option_value_list: test with correct config/section/option + uci_res = dmuci_get_option_value_list("system", "ntpp", "server", &ulist); + assert_int_equal(uci_res, -1); + assert_null(ulist); + + // dmuci_get_option_value_list: test with correct config/section/option + uci_res = dmuci_get_option_value_list("system", "ntp", "serverr", &ulist); + assert_int_equal(uci_res, -1); + assert_null(ulist); + + // dmuci_get_option_value_list: test with correct section/option and wrong config name + uci_res = dmuci_get_option_value_list("system", "ntp", "server", &ulist); + assert_int_equal(uci_res, 0); + assert_non_null(ulist); + value = dmuci_list_to_string(ulist, ","); + assert_string_equal(value, "ntp1.sth.netnod.se,ntp1.gbg.netnod.se"); + + /* + * Test of db_get_value_string function + */ + + // db_get_value_string: test with correct section/option and wrong config name + uci_res = db_get_value_string("devicee", "deviceinfo", "ProductClass", &value); + assert_int_equal(uci_res, -1); + assert_string_equal(value, ""); + + // db_get_value_string: test with correct config/option and wrong section name + uci_res = db_get_value_string("device", "deviceinfoo", "ProductClass", &value); + assert_int_equal(uci_res, -1); + assert_string_equal(value, ""); + + // db_get_value_string: test with correct config/section and wrong option name + uci_res = db_get_value_string("device", "deviceinfo", "ProductCla", &value); + assert_int_equal(uci_res, -1); + assert_string_equal(value, ""); + + // db_get_value_string: test correct config/section/option + uci_res = db_get_value_string("device", "deviceinfo", "ProductClass", &value); + assert_int_equal(uci_res, 0); + assert_string_equal(value, "FirstClass"); + + /* + * Test of varstate_get_value_string function + */ + + // varstate_get_value_string: test with correct section/option and wrong config name + uci_res = varstate_get_value_string("cwm", "acs", "dhcp_url", &value); + assert_int_equal(uci_res, -1); + assert_string_equal(value, ""); + + // varstate_get_value_string: test with correct config/option and wrong section name + uci_res = varstate_get_value_string("cwmp", "acss", "dhcp_url", &value); + assert_int_equal(uci_res, -1); + assert_string_equal(value, ""); + + // varstate_get_value_string: test with correct config/section and wrong option name + uci_res = varstate_get_value_string("cwmp", "acs", "hcp_url", &value); + assert_int_equal(uci_res, -1); + assert_string_equal(value, ""); + + // varstate_get_value_string: test correct config/section/option + uci_res = varstate_get_value_string("cwmp", "acs", "dhcp_url", &value); + assert_int_equal(uci_res, 0); + assert_string_equal(value, "http://192.168.1.123:8080/openacs"); + + /* + * Test of dmuci_add_list_value function + */ + + // dmuci_add_list_value: test with correct config/section/option + uci_res = dmuci_add_list_value("systemm", "ntp", "server", "ntp2.gbg.netnod.se"); + assert_int_equal(uci_res, -1); + + // dmuci_add_list_value: test with correct config/section/option + uci_res = dmuci_add_list_value("system", "ntpp", "server", "ntp2.gbg.netnod.se"); + assert_int_equal(uci_res, -1); + + // dmuci_add_list_value: test with correct config/section/option + uci_res = dmuci_add_list_value("system", "ntp", "server", "ntp2.gbg.netnod.se"); + assert_int_equal(uci_res, 0); + uci_res = dmuci_commit_package("system"); + assert_int_equal(uci_res, 0); + uci_res = dmuci_get_option_value_list("system", "ntp", "server", &ulist); + assert_int_equal(uci_res, 0); + assert_non_null(ulist); + value = dmuci_list_to_string(ulist, ","); + assert_string_equal(value, "ntp1.sth.netnod.se,ntp1.gbg.netnod.se,ntp2.gbg.netnod.se"); + + /* + * Test of dmuci_del_list_value function + */ + + // dmuci_del_list_value: test with correct config/section/option + uci_res = dmuci_del_list_value("systemm", "ntp", "server", "ntp1.gbg.netnod.se"); + assert_int_equal(uci_res, -1); + + // dmuci_del_list_value: test with correct config/section/option + uci_res = dmuci_del_list_value("system", "ntpp", "server", "ntp1.gbg.netnod.se"); + assert_int_equal(uci_res, -1); + + // dmuci_del_list_value: test with correct config/section/option + uci_res = dmuci_del_list_value("system", "ntp", "server", "ntp1.gbg.netnod.se"); + assert_int_equal(uci_res, 0); + uci_res = dmuci_commit_package("system"); + assert_int_equal(uci_res, 0); + uci_res = dmuci_get_option_value_list("system", "ntp", "server", &ulist); + assert_int_equal(uci_res, 0); + assert_non_null(ulist); + value = dmuci_list_to_string(ulist, ","); + assert_string_equal(value, "ntp1.sth.netnod.se,ntp2.gbg.netnod.se"); + + /* + * Test of dmuci_set_value function + */ + + // dmuci_set_value: test with correct section/option and wrong config name + value = dmuci_set_value("netwo", "wan", "vendorid", "dg400prime"); + assert_string_equal(value, ""); + + // dmuci_set_value: test with correct config/option and wrong section name + value = dmuci_set_value("network", "wann", "vendorid", "dg400prime"); + assert_string_equal(value, ""); + + // dmuci_set_value: test correct config/section/option + value = dmuci_set_value("network", "wan", "vendorid", "dg400prime"); + assert_string_equal(value, "dg400prime"); + uci_res = dmuci_commit_package("network"); + assert_int_equal(uci_res, 0); + uci_res = dmuci_get_option_value_string("network", "wan", "vendorid", &value); + assert_int_equal(uci_res, 0); + assert_string_equal(value, "dg400prime"); + + // dmuci_set_value: test correct config/section/option + value = dmuci_set_value("dropbear", "@dropbear[0]", "Port", "7845"); + assert_string_equal(value, "7845"); + uci_res = dmuci_commit_package("dropbear"); + assert_int_equal(uci_res, 0); + uci_res = dmuci_get_option_value_string("dropbear", "@dropbear[0]", "Port", &value); + assert_int_equal(uci_res, 0); + assert_string_equal(value, "7845"); + + /* + * Test of dmuci_add_section function + */ + + // dmuci_add_section: test with only config name + value = dmuci_add_section("network", "section_test", &uci_s); + assert_string_not_equal(value, ""); + assert_non_null(uci_s); + uci_res = dmuci_commit_package("network"); + assert_int_equal(uci_res, 0); + + + /* + * Test of dmuci_delete function + */ + + // dmuci_delete: test with only config name + uci_res = dmuci_delete("network", "wan", "vendorid", NULL); + assert_int_equal(uci_res, 0); + uci_res = dmuci_commit_package("network"); + assert_int_equal(uci_res, 0); + uci_res = dmuci_get_option_value_string("network", "wan", "vendorid", &value); + assert_int_equal(uci_res, -1); + assert_string_equal(value, ""); + + + /* + * Test of uci_foreach_sections function + */ + + //uci_foreach_sections: test loop objects with wrong config name + uci_s = NULL; + uci_foreach_sections("netwo", "interface", uci_s) { + break; + } + assert_null(uci_s); + + //uci_foreach_sections: test loop objects with wrong option name + uci_s = NULL; + uci_foreach_sections("network", "interfa", uci_s) { + break; + } + assert_null(uci_s); + + //uci_foreach_sections: test loop objects with wrong option name + uci_s = NULL; + uci_foreach_sections("network", "interface", uci_s) { + break; + } + assert_non_null(uci_s); + + + /* + * Test of dmuci_get_value_by_section_string function + */ + + // dmuci_get_value_by_section_string: test with wrong option name + uci_res = dmuci_get_value_by_section_string(uci_s, "vendorid", &value); + assert_int_equal(uci_res, -1); + assert_string_equal(value, ""); + + // dmuci_get_value_by_section_string: test with correct option name + uci_res = dmuci_get_value_by_section_string(uci_s, "ifname", &value); + assert_int_equal(uci_res, 0); + assert_string_equal(value, "lo"); + + /* + * Test of dmuci_set_value_by_section function + */ + + // dmuci_set_value_by_section: test with correct option name + value = dmuci_set_value_by_section(uci_s, "reqopts", "44"); + assert_string_equal(value, "44"); + uci_res = dmuci_get_value_by_section_string(uci_s, "reqopts", &value); + assert_int_equal(uci_res, 0); + assert_string_equal(value, "44"); + + + /* + * Test of dmuci_rename_section_by_section function + */ + + // dmuci_rename_section_by_section: test + assert_string_equal(section_name(uci_s), "loopback"); + uci_res = dmuci_rename_section_by_section(uci_s, "loop_interface"); + assert_int_equal(uci_res, 0); + assert_string_equal(section_name(uci_s), "loop_interface"); + + + /* + * Test of dmuci_delete_by_section function + */ + + // dmuci_delete_by_section: test with correct option name + uci_res = dmuci_delete_by_section(uci_s, "reqopts", NULL); + assert_int_equal(uci_res, 0); + uci_res = dmuci_get_value_by_section_string(uci_s, "reqopts", &value); + assert_int_equal(uci_res, -1); + assert_string_equal(value, ""); + + // dmuci_delete_by_section: test without option name + uci_res = dmuci_delete_by_section(uci_s, NULL, NULL); + assert_int_equal(uci_res, 0); + + + /* + * Test of dmuci_get_value_by_section_list function + */ + + uci_s = NULL; + uci_foreach_sections("system", "timeserver", uci_s) { + break; + } + assert_non_null(uci_s); + + // dmuci_get_value_by_section_list: test with wrong option name + uci_res = dmuci_get_value_by_section_list(uci_s, "serverer", &ulist); + assert_int_equal(uci_res, -1); + assert_null(ulist); + + // dmuci_get_value_by_section_list: test with correct option name + uci_res = dmuci_get_value_by_section_list(uci_s, "server", &ulist); + assert_int_equal(uci_res, 0); + assert_non_null(ulist); + value = dmuci_list_to_string(ulist, ","); + assert_string_equal(value, "ntp1.sth.netnod.se,ntp2.gbg.netnod.se"); + + + /* + * Test of dmuci_add_list_value_by_section function + */ + + // dmuci_add_list_value_by_section: test with correct option name + uci_res = dmuci_add_list_value_by_section(uci_s, "server", "ntp3.gbg.netnod.se"); + assert_int_equal(uci_res, 0); + uci_res = dmuci_get_value_by_section_list(uci_s, "server", &ulist); + assert_int_equal(uci_res, 0); + assert_non_null(ulist); + value = dmuci_list_to_string(ulist, ","); + assert_string_equal(value, "ntp1.sth.netnod.se,ntp2.gbg.netnod.se,ntp3.gbg.netnod.se"); + + + /* + * Test of dmuci_del_list_value_by_section function + */ + + // dmuci_del_list_value_by_section: test with correct config/section/option + uci_res = dmuci_del_list_value_by_section(uci_s, "server", "ntp2.gbg.netnod.se"); + assert_int_equal(uci_res, 0); + uci_res = dmuci_get_value_by_section_list(uci_s, "server", &ulist); + assert_int_equal(uci_res, 0); + assert_non_null(ulist); + value = dmuci_list_to_string(ulist, ","); + assert_string_equal(value, "ntp1.sth.netnod.se,ntp3.gbg.netnod.se"); +} + +static void test_bbf_api_ubus(void **state) +{ + char ubus_name[128] = {'\0'}; + json_object *res = NULL; + bool method_exist = false; + int ubus_res = 0; + + /* + * Test of dmubus_call function + */ + + // dmubus_call: test Wrong obj + dmubus_call("ucii", "configs", UBUS_ARGS{}, 0, &res); + assert_null(res); + + // dmubus_call: test Wrong method + dmubus_call("uci", "configss", UBUS_ARGS{}, 0, &res); + assert_null(res); + + // dmubus_call: test Wrong argument + dmubus_call("uci", "get", UBUS_ARGS{{"confi", "users", String}}, 1, &res); + assert_null(res); + + // dmubus_call: test correct obj/method + dmubus_call("uci", "configs", UBUS_ARGS{}, 0, &res); + assert_non_null(res); + + // dmubus_call: test correct obj/method + dmubus_call("uci", "get", UBUS_ARGS{{"config", "users", String}}, 1, &res); + assert_non_null(res); + + /* + * Test of dmubus_call_set function + */ + + // dmubus_call_set: test Wrong obj + ubus_res = dmubus_call_set("ucii", "configs", UBUS_ARGS{}, 0); + assert_int_not_equal(ubus_res, 0); + + // dmubus_call_set: test Wrong method + ubus_res = dmubus_call_set("uci", "configss", UBUS_ARGS{}, 0); + assert_int_not_equal(ubus_res, 0); + + // dmubus_call_set: test Wrong argument + ubus_res = dmubus_call_set("uci", "get", UBUS_ARGS{{"confi", "users", String}}, 1); + assert_int_not_equal(ubus_res, 0); + + // dmubus_call_set: test correct obj/method + ubus_res = dmubus_call_set("uci", "configs", UBUS_ARGS{}, 0); + assert_int_equal(ubus_res, 0); + + // dmubus_call_set: test correct obj/method + ubus_res = dmubus_call_set("uci", "get", UBUS_ARGS{{"config", "users", String}}, 1); + assert_int_equal(ubus_res, 0); + + /* + * Test of dmubus_object_method_exists function + */ + + // dmubus_object_method_exists: test with correct obj and wrong method + DM_STRNCPY(ubus_name, "uci->configss", sizeof(ubus_name)); + method_exist = dmubus_object_method_exists(ubus_name); + assert_false(method_exist); + + // dmubus_object_method_exists: test with wrong obj and correct method + DM_STRNCPY(ubus_name, "ucii->configs", sizeof(ubus_name)); + method_exist = dmubus_object_method_exists(ubus_name); + assert_false(method_exist); + + // dmubus_object_method_exists: test with wrong obj and without method + DM_STRNCPY(ubus_name, "uciii", sizeof(ubus_name)); + method_exist = dmubus_object_method_exists(ubus_name); + assert_false(method_exist); + + // dmubus_object_method_exists: test with correct obj and without method + DM_STRNCPY(ubus_name, "uci", sizeof(ubus_name)); + method_exist = dmubus_object_method_exists(ubus_name); + assert_true(method_exist); + + // dmubus_object_method_exists: test with correct obj and correct method + DM_STRNCPY(ubus_name, "uci->configs", sizeof(ubus_name)); + method_exist = dmubus_object_method_exists(ubus_name); + assert_true(method_exist); +} + +static void test_bbf_api_json(void **state) +{ + json_object *wifi_status = NULL, *json_obj = NULL, *json_arr = NULL; + char *json_value = NULL; + int idx = 0; + + dmubus_call("wifi.ap.test2", "status", UBUS_ARGS{}, 0, &wifi_status); + assert_non_null(wifi_status); + + /* + * Test of dmjson_get_value function + */ + + // dmjson_get_value: test wrong option + json_value = dmjson_get_value(wifi_status, 1, "testt"); + assert_string_equal(json_value, ""); + + // dmjson_get_value: test correct option + json_value = dmjson_get_value(wifi_status, 1, "ssid"); + assert_string_equal(json_value, "iopsysWrt-002207AB9F80"); + + // dmjson_get_value: test correct option under object + json_value = dmjson_get_value(wifi_status, 2, "capabilities", "dot11h"); + assert_string_equal(json_value, "false"); + + /* + * Test of dmjson_get_obj function + */ + + //dmjson_get_obj: test wrong option + json_obj = dmjson_get_obj(wifi_status, 1, "testt"); + assert_null(json_obj); + + //dmjson_get_obj: test correct option + json_obj = dmjson_get_obj(wifi_status, 1, "capabilities"); + assert_non_null(json_obj); + json_value = dmjson_get_value(json_obj, 1, "dot11v_btm"); + assert_string_equal(json_value, "true"); + + //dmjson_get_obj: test correct option under object + json_obj = dmjson_get_obj(wifi_status, 2, "capabilities", "dot11ac"); + assert_non_null(json_obj); + json_value = dmjson_get_value(json_obj, 1, "dot11ac_mpdu_max"); + assert_string_equal(json_value, "11454"); + + /* + * Test of dmjson_select_obj_in_array_idx function + */ + + //dmjson_select_obj_in_array_idx: test wrong option + json_obj = dmjson_select_obj_in_array_idx(wifi_status, 0, 1, "test"); + assert_null(json_obj); + + //dmjson_select_obj_in_array_idx: test correct option with index 0 + json_obj = dmjson_select_obj_in_array_idx(wifi_status, 0, 1, "wmm_params"); + assert_non_null(json_obj); + json_value = dmjson_get_value(json_obj, 1, "cwmin"); + assert_string_equal(json_value, "21"); + + //dmjson_select_obj_in_array_idx: test correct option with index 3 + json_obj = dmjson_select_obj_in_array_idx(wifi_status, 3, 1, "wmm_params"); + assert_non_null(json_obj); + json_value = dmjson_get_value(json_obj, 1, "cwmax"); + assert_string_equal(json_value, "149"); + + /* + * Test of dmjson_get_value_array_all function + */ + + //dmjson_get_value_array_all: test wrong option with comma separator + json_value = dmjson_get_value_array_all(wifi_status, ",", 1, "testt"); + assert_string_equal(json_value, ""); + + //dmjson_get_value_array_all: test correct option with comma separator + json_value = dmjson_get_value_array_all(wifi_status, ",", 1, "supp_security"); + assert_string_equal(json_value, "NONE,WPA3PSK,WPA2PSK+WPA3PSK,WPA,WPA2,WPA2+WPA3"); + + + //dmjson_get_value_array_all: test correct option with :: separator + json_value = dmjson_get_value_array_all(wifi_status, "::", 1, "supp_security"); + assert_string_equal(json_value, "NONE::WPA3PSK::WPA2PSK+WPA3PSK::WPA::WPA2::WPA2+WPA3"); + + /* + * Test of dmjson_foreach_obj_in_array function + */ + + //dmjson_foreach_obj_in_array: test loop objects + dmjson_foreach_obj_in_array(wifi_status, json_arr, json_obj, idx, 1, "wmm_params") { + + assert_non_null(json_obj); + + json_value = dmjson_get_value(json_obj, 1, "cwmin"); + if (idx == 0) + assert_string_equal(json_value, "21"); + else if (idx == 1) + assert_string_equal(json_value, "3"); + else if (idx == 2) + assert_string_equal(json_value, "78"); + else + assert_string_equal(json_value, "66"); + + idx++; + } + assert_int_equal(idx, 4); + + /* + * Test of dmjson_foreach_value_in_array function + */ + + //dmjson_foreach_value_in_array: test loop values + idx = 0; + dmjson_foreach_value_in_array(wifi_status, json_arr, json_value, idx, 1, "supp_security") { + + assert_non_null(json_value); + + if (idx == 0) + assert_string_equal(json_value, "NONE"); + else if (idx == 1) + assert_string_equal(json_value, "WPA3PSK"); + else if (idx == 2) + assert_string_equal(json_value, "WPA2PSK+WPA3PSK"); + else if (idx == 3) + assert_string_equal(json_value, "WPA"); + else if (idx == 4) + assert_string_equal(json_value, "WPA2"); + else + assert_string_equal(json_value, "WPA2+WPA3"); + + idx++; + } + assert_int_equal(idx, 6); +} + +static void test_bbf_api_validate(void **state) +{ + int validate = 0; + + /* + * Test of dm_validate_string function + */ + + // dm_validate_string: test with wrong min value + validate = dm_validate_string("test", 5, 8, NULL, NULL); + assert_int_equal(validate, -1); + + // dm_validate_string: test with wrong max value + validate = dm_validate_string("test", -1, 2, NULL, NULL); + assert_int_equal(validate, -1); + + // dm_validate_string: test with wrong enumaration value + validate = dm_validate_string("test", -1, -1, DiagnosticsState, NULL); + assert_int_equal(validate, -1); + + // dm_validate_string: test with wrong pattern value + validate = dm_validate_string("test", -1, -1, NULL, IPv4Address); + assert_int_equal(validate, -1); + + // dm_validate_string: test with correct min and max value + validate = dm_validate_string("bbftest", 5, 8, NULL, NULL); + assert_int_equal(validate, 0); + + // dm_validate_string: test with correct enumaration value + validate = dm_validate_string("Requested", -1, -1, DiagnosticsState, NULL); + assert_int_equal(validate, 0); + + // dm_validate_string: test with correct pattern value + validate = dm_validate_string("10.10.9.80", -1, -1, NULL, IPv4Address); + assert_int_equal(validate, 0); + + + /* + * Test of dm_validate_boolean function + */ + + // dm_validate_boolean: test with wrong value + validate = dm_validate_boolean("test"); + assert_int_equal(validate, -1); + + // dm_validate_boolean: test with correct value + validate = dm_validate_boolean("true"); + assert_int_equal(validate, 0); + + + /* + * Test of dm_validate_unsignedInt function + */ + + // dm_validate_unsignedInt: test with wrong value + validate = dm_validate_unsignedInt("12t", RANGE_ARGS{{NULL,NULL}}, 1); + assert_int_equal(validate, -1); + + // dm_validate_unsignedInt: test with wrong min value + validate = dm_validate_unsignedInt("1", RANGE_ARGS{{"12",NULL}}, 1); + assert_int_equal(validate, -1); + + // dm_validate_unsignedInt: test with wrong max value + validate = dm_validate_unsignedInt("112", RANGE_ARGS{{NULL,"50"}}, 1); + assert_int_equal(validate, -1); + + + // dm_validate_unsignedInt: test without min/max value + validate = dm_validate_unsignedInt("112", RANGE_ARGS{{NULL,NULL}}, 1); + assert_int_equal(validate, 0); + + // dm_validate_unsignedInt: test with correct min/max value + validate = dm_validate_unsignedInt("112", RANGE_ARGS{{"10","1000"}}, 1); + assert_int_equal(validate, 0); + + + /* + * Test of dm_validate_int function + */ + + // dm_validate_int: test with wrong value + validate = dm_validate_int("-12t", RANGE_ARGS{{NULL,NULL}}, 1); + assert_int_equal(validate, -1); + + // dm_validate_int: test with wrong min value + validate = dm_validate_int("-1", RANGE_ARGS{{"12",NULL}}, 1); + assert_int_equal(validate, -1); + + // dm_validate_int: test with wrong max value + validate = dm_validate_int("-1", RANGE_ARGS{{NULL,"-5"}}, 1); + assert_int_equal(validate, -1); + + // dm_validate_int: test without min/max value + validate = dm_validate_int("-112", RANGE_ARGS{{NULL,NULL}}, 1); + assert_int_equal(validate, 0); + + // dm_validate_int: test with correct min/max value + validate = dm_validate_int("-2", RANGE_ARGS{{"-10","1000"}}, 1); + assert_int_equal(validate, 0); + + + /* + * Test of dm_validate_unsignedLong function + */ + + // dm_validate_unsignedLong: test with wrong value + validate = dm_validate_unsignedLong("2t", RANGE_ARGS{{NULL,NULL}}, 1); + assert_int_equal(validate, -1); + + // dm_validate_unsignedLong: test with wrong min value + validate = dm_validate_unsignedLong("1", RANGE_ARGS{{"12",NULL}}, 1); + assert_int_equal(validate, -1); + + // dm_validate_unsignedLong: test with wrong max value + validate = dm_validate_unsignedLong("10", RANGE_ARGS{{NULL,"5"}}, 1); + assert_int_equal(validate, -1); + + // dm_validate_unsignedLong: test without min/max value + validate = dm_validate_unsignedLong("112", RANGE_ARGS{{NULL,NULL}}, 1); + assert_int_equal(validate, 0); + + // dm_validate_unsignedLong: test with correct min/max value + validate = dm_validate_unsignedLong("20", RANGE_ARGS{{"10","1000"}}, 1); + assert_int_equal(validate, 0); + + + /* + * Test of dm_validate_long function + */ + + // dm_validate_long: test with wrong value + validate = dm_validate_long("-12t", RANGE_ARGS{{NULL,NULL}}, 1); + assert_int_equal(validate, -1); + + // dm_validate_long: test with wrong min value + validate = dm_validate_long("-1", RANGE_ARGS{{"12",NULL}}, 1); + assert_int_equal(validate, -1); + + // dm_validate_long: test with wrong max value + validate = dm_validate_long("-1", RANGE_ARGS{{NULL,"-5"}}, 1); + assert_int_equal(validate, -1); + + // dm_validate_long: test without min/max value + validate = dm_validate_long("-112", RANGE_ARGS{{NULL,NULL}}, 1); + assert_int_equal(validate, 0); + + // dm_validate_long: test with correct min/max value + validate = dm_validate_long("-2", RANGE_ARGS{{"-10","1000"}}, 1); + assert_int_equal(validate, 0); + + + /* + * Test of dm_validate_dateTime function + */ + + // dm_validate_dateTime: test with wrong value + validate = dm_validate_dateTime("2021-12-31T20:53:99"); + assert_int_equal(validate, -1); + + // dm_validate_dateTime: test with wrong value + validate = dm_validate_dateTime("2021-12-31T20:53:01Z"); + assert_int_equal(validate, 0); + + + /* + * Test of dm_validate_hexBinary function + */ + + // dm_validate_hexBinary: test with wrong value + validate = dm_validate_hexBinary("-12t", RANGE_ARGS{{NULL,NULL}}, 1); + assert_int_equal(validate, -1); + + // dm_validate_hexBinary: test with wrong min value + validate = dm_validate_hexBinary("123bcd", RANGE_ARGS{{"12",NULL}}, 1); + assert_int_equal(validate, -1); + + // dm_validate_hexBinary: test with wrong max value + validate = dm_validate_hexBinary("123bcd", RANGE_ARGS{{NULL,"4"}}, 1); + assert_int_equal(validate, -1); + + // dm_validate_hexBinary: test with wrong value + validate = dm_validate_hexBinary("123b4cd", RANGE_ARGS{{"3","3"}}, 1); + assert_int_equal(validate, -1); + + // dm_validate_hexBinary: test without min/max value + validate = dm_validate_hexBinary("123bcd", RANGE_ARGS{{NULL,NULL}}, 1); + assert_int_equal(validate, 0); + + // dm_validate_hexBinary: test with correct min/max value + validate = dm_validate_hexBinary("123bcd", RANGE_ARGS{{"1","8"}}, 1); + assert_int_equal(validate, 0); + + // dm_validate_hexBinary: test with wrong value + validate = dm_validate_hexBinary("123bcd", RANGE_ARGS{{"3","3"}}, 1); + assert_int_equal(validate, 0); + + + /* + * Test of dm_validate_string_list function + */ + + // dm_validate_string_list: test with wrong min_item value + validate = dm_validate_string_list("test", 2, -1, -1, -1, -1, NULL, NULL); + assert_int_equal(validate, -1); + + // dm_validate_string_list: test with wrong max_item value + validate = dm_validate_string_list("test1,test2,test3", -1, 2, -1, -1, -1, NULL, NULL); + assert_int_equal(validate, -1); + + // dm_validate_string_list: test with wrong max_size value + validate = dm_validate_string_list("test1,test2,test3", -1, -1, 10, -1, -1, NULL, NULL); + assert_int_equal(validate, -1); + + // dm_validate_string_list: test with correct min and max item/size value + validate = dm_validate_string_list("bbftest", -1, -1, -1, -1, -1, NULL, NULL); + assert_int_equal(validate, 0); + + // dm_validate_string_list: test with correct min and max item/size value + validate = dm_validate_string_list("test1,test2,test3", 2, 4, 20, -1, -1, NULL, NULL); + assert_int_equal(validate, 0); +} + +static void test_bbf_api_common(void **state) +{ + char buf[256] = {0}; + char *value = NULL; + bool exist = false; + + /* + * Test of folder_exists function + */ + + // folder_exists: test with wrong file name + exist = folder_exists("/proc/sys/net/ipv"); + assert_false(exist); + + // folder_exists: test with correct file name + exist = folder_exists("/proc/sys/net/ipv4"); + assert_true(exist); + + + /* + * Test of file_exists function + */ + + // file_exists: test with wrong min value + exist = file_exists("/etc/passw"); + assert_false(exist); + + // file_exists: test with correct file name + exist = file_exists("/etc/passwd"); + assert_true(exist); + + + /* + * Test of is_regular_file function + */ + + // is_regular_file: test with wrong file name + exist = is_regular_file("/proc/net/rout"); + assert_false(exist); + + // is_regular_file: test with correct file name + exist = is_regular_file("/proc/net/route"); + assert_true(exist); + + + /* + * Test of replace_char function + */ + + // replace_char: test + DM_STRNCPY(buf, "/path/to/file", sizeof(buf)); + value = replace_char(buf, '/', ' '); + assert_string_equal(value, " path to file"); + + // replace_char: test + DM_STRNCPY(buf, "Device.ATM.Link.{i}.Enable", sizeof(buf)); + value = replace_char(buf, '.', '/'); + assert_string_equal(value, "Device/ATM/Link/{i}/Enable"); + + + /* + * Test of replace_str function + */ + + // replace_str: test + DM_STRNCPY(buf, "Device.IEEE1905.AL.NetworkTopology.IEEE1905Device.{i}.IPv4Address.{i}.", sizeof(buf)); + value = replace_str(buf, ".{i}.", "."); + assert_string_equal(value, "Device.IEEE1905.AL.NetworkTopology.IEEE1905Device.IPv4Address."); + + // replace_str: test + DM_STRNCPY(buf, "Device.IEEE1905.AL.NetworkTopology.IEEE1905Device.{i}.IPv4Address.{i}.", sizeof(buf)); + value = replace_str(buf, ".{i}.", ".*."); + assert_string_equal(value, "Device.IEEE1905.AL.NetworkTopology.IEEE1905Device.*.IPv4Address.*."); + + + /* + * Test of decode64 function + */ + + // decode64: test + value = decode64("YmJmX3VuaXRfdGVzdA"); + assert_string_equal(value, "bbf_unit_test"); + + + /* + * Test of convert_string_to_hex function + */ + + // convert_string_to_hex: test + convert_string_to_hex("bbf_unit_test", buf); + assert_string_equal(buf, "6262665F756E69745F74657374"); + + + /* + * Test of convert_hex_to_string function + */ + + // convert_hex_to_string: test + convert_hex_to_string("6262665f756e69745f74657374", buf); + assert_string_equal(buf, "bbf_unit_test"); + + + /* + * Test of hex_to_ip function + */ + + // hex_to_ip: test + hex_to_ip("0000FEA9", buf); + assert_string_equal(buf, "169.254.0.0"); + +} + +int main(void) +{ + const struct CMUnitTest tests[] = { + // UCI functions test cases + cmocka_unit_test(test_bbf_api_uci), + + // Ubus functions test cases + cmocka_unit_test(test_bbf_api_ubus), + + // JSON functions test cases + cmocka_unit_test(test_bbf_api_json), + + // Validate functions test cases + cmocka_unit_test(test_bbf_api_validate), + + // Common functions test cases + cmocka_unit_test(test_bbf_api_common), + }; + + return cmocka_run_group_tests(tests, setup_teardown, group_teardown); +} diff --git a/test/cmocka/functional_test_bbfd.c b/test/cmocka/functional_test_bbfd.c new file mode 100644 index 00000000..837d40b7 --- /dev/null +++ b/test/cmocka/functional_test_bbfd.c @@ -0,0 +1,422 @@ +#include +#include +#include +#include + +#include +#include + +static int setup(void **state) +{ + struct dmctx *ctx = calloc(1, sizeof(struct dmctx)); + if (!ctx) + return -1; + + dm_ctx_init(ctx, INSTANCE_MODE_NUMBER); + *state = ctx; + + return 0; +} + +static int teardown_commit(void **state) +{ + struct dmctx *ctx = (struct dmctx *) *state; + + dm_entry_restart_services(); + dm_ctx_clean(ctx); + free(ctx); + + return 0; +} + +static int group_teardown(void **state) +{ + free_dynamic_arrays(); + return 0; +} + + +static void validate_parameter(struct dmctx *ctx, const char *name, const char *value, const char *type) +{ + struct dm_parameter *n; + + dm_ctx_clean_sub(ctx); + dm_ctx_init_sub(ctx, INSTANCE_MODE_NUMBER); + + list_for_each_entry(n, &ctx->list_parameter, list) { + + // check the returned path + assert_string_equal(n->name, name); + + // check the returned value + assert_string_equal(n->data, value); + + // check the returned type + assert_string_equal(n->type, type); + } +} + +static void test_api_bbfdm_get_set_standard_parameter(void **state) +{ + struct dmctx *ctx = (struct dmctx *) *state; + int fault = 0; + + // get value ==> expected "0" error + fault = dm_entry_param_method(ctx, CMD_GET_VALUE, "Device.WiFi.Radio.1.Channel", NULL, NULL); + assert_int_equal(fault, 0); + + // validate parameter : name, type, value + validate_parameter(ctx, "Device.WiFi.Radio.1.Channel", "1", "xsd:unsignedInt"); + + // Set Wrong Value ==> expected "9007" error + fault = dm_entry_param_method(ctx, CMD_SET_VALUE, "Device.WiFi.Radio.1.Channel", "64t", NULL); + assert_int_equal(fault, FAULT_9007); + + // set value ==> expected "0" error + fault = dm_entry_param_method(ctx, CMD_SET_VALUE, "Device.WiFi.Radio.1.Channel", "64", NULL); + assert_int_equal(fault, 0); + + // apply value ==> expected "0" error + fault = dm_entry_apply(ctx, CMD_SET_VALUE, "test_key", NULL); + assert_int_equal(fault, 0); + + // get value ==> expected "0" error + fault = dm_entry_param_method(ctx, CMD_GET_VALUE, "Device.WiFi.Radio.1.Channel", NULL, NULL); + assert_int_equal(fault, 0); + + // validate parameter after setting to 64: name, type, value + validate_parameter(ctx, "Device.WiFi.Radio.1.Channel", "64", "xsd:unsignedInt"); +} + +static void test_api_bbfdm_get_set_json_parameter(void **state) +{ + struct dmctx *ctx = (struct dmctx *) *state; + int fault = 0; + + // get value ==> expected "0" error + fault = dm_entry_param_method(ctx, CMD_GET_VALUE, "Device.UserInterface.CurrentLanguage", NULL, NULL); + assert_int_equal(fault, 0); + + // validate parameter : name, type, value + validate_parameter(ctx, "Device.UserInterface.CurrentLanguage", "en", "xsd:string"); + + // set value ==> expected "0" error + fault = dm_entry_param_method(ctx, CMD_SET_VALUE, "Device.UserInterface.CurrentLanguage", "fr", NULL); + assert_int_equal(fault, 0); + + // apply value ==> expected "0" error + fault = dm_entry_apply(ctx, CMD_SET_VALUE, "test_key", NULL); + assert_int_equal(fault, 0); + + // get value ==> expected "0" error + fault = dm_entry_param_method(ctx, CMD_GET_VALUE, "Device.UserInterface.CurrentLanguage", NULL, NULL); + assert_int_equal(fault, 0); + + // validate parameter after setting to fr: name, type, value + validate_parameter(ctx, "Device.UserInterface.CurrentLanguage", "fr", "xsd:string"); +} + +static void test_api_bbfdm_get_set_library_parameter(void **state) +{ + struct dmctx *ctx = (struct dmctx *) *state; + int fault = 0; + + // get value ==> expected "0" error + fault = dm_entry_param_method(ctx, CMD_GET_VALUE, "Device.ManagementServer.EnableCWMP", NULL, NULL); + assert_int_equal(fault, 0); + + // validate parameter : name, type, value + validate_parameter(ctx, "Device.ManagementServer.EnableCWMP", "1", "xsd:boolean"); + + // Set Wrong Value ==> expected "9007" error + fault = dm_entry_param_method(ctx, CMD_SET_VALUE, "Device.ManagementServer.EnableCWMP", "truee", NULL); + assert_int_equal(fault, FAULT_9007); + + // set value ==> expected "0" error + fault = dm_entry_param_method(ctx, CMD_SET_VALUE, "Device.ManagementServer.EnableCWMP", "0", NULL); + assert_int_equal(fault, 0); + + // apply value ==> expected "0" error + fault = dm_entry_apply(ctx, CMD_SET_VALUE, "test_key", NULL); + assert_int_equal(fault, 0); + + // get value ==> expected "0" error + fault = dm_entry_param_method(ctx, CMD_GET_VALUE, "Device.ManagementServer.EnableCWMP", NULL, NULL); + assert_int_equal(fault, 0); + + // validate parameter after setting to 0: name, type, value + validate_parameter(ctx, "Device.ManagementServer.EnableCWMP", "0", "xsd:boolean"); +} + +static void test_api_bbfdm_get_set_notification_standard_parameter(void **state) +{ + struct dmctx *ctx = (struct dmctx *) *state; + int fault = 0; + + // get notification ==> expected "0" error + fault = dm_entry_param_method(ctx, CMD_GET_NOTIFICATION, "Device.WiFi.SSID.1.SSID", NULL, NULL); + assert_int_equal(fault, 0); + + // validate parameter : name, type, value + validate_parameter(ctx, "Device.WiFi.SSID.1.SSID", "0", "xsd:string"); + + // set notification ==> expected "0" error + fault = dm_entry_param_method(ctx, CMD_SET_NOTIFICATION, "Device.WiFi.SSID.1.SSID", "1", NULL); + assert_int_equal(fault, 0); + + // get notification ==> expected "0" error + fault = dm_entry_param_method(ctx, CMD_GET_NOTIFICATION, "Device.WiFi.SSID.1.SSID", NULL, NULL); + assert_int_equal(fault, 0); + + // validate parameter : name, type, value + validate_parameter(ctx, "Device.WiFi.SSID.1.SSID", "1", "xsd:string"); + + // set notification ==> expected "0" error + fault = dm_entry_param_method(ctx, CMD_SET_NOTIFICATION, "Device.WiFi.SSID.1.SSID", "2", NULL); + assert_int_equal(fault, 0); + + // get notification ==> expected "0" error + fault = dm_entry_param_method(ctx, CMD_GET_NOTIFICATION, "Device.WiFi.SSID.1.SSID", NULL, NULL); + assert_int_equal(fault, 0); + + // validate parameter : name, type, value + validate_parameter(ctx, "Device.WiFi.SSID.1.SSID", "2", "xsd:string"); +} + +static void test_api_bbfdm_get_set_notification_json_parameter(void **state) +{ + struct dmctx *ctx = (struct dmctx *) *state; + int fault = 0; + + // get notification ==> expected "0" error + fault = dm_entry_param_method(ctx, CMD_GET_NOTIFICATION, "Device.UserInterface.CurrentLanguage", NULL, NULL); + assert_int_equal(fault, 0); + + // validate parameter : name, type, value + validate_parameter(ctx, "Device.UserInterface.CurrentLanguage", "0", "xsd:string"); + + // set notification ==> expected "0" error + fault = dm_entry_param_method(ctx, CMD_SET_NOTIFICATION, "Device.UserInterface.CurrentLanguage", "1", NULL); + assert_int_equal(fault, 0); + + // get notification ==> expected "0" error + fault = dm_entry_param_method(ctx, CMD_GET_NOTIFICATION, "Device.UserInterface.CurrentLanguage", NULL, NULL); + assert_int_equal(fault, 0); + + // validate parameter : name, type, value + validate_parameter(ctx, "Device.UserInterface.CurrentLanguage", "1", "xsd:string"); + + // set notification ==> expected "0" error + fault = dm_entry_param_method(ctx, CMD_SET_NOTIFICATION, "Device.UserInterface.CurrentLanguage", "2", NULL); + assert_int_equal(fault, 0); + + // get notification ==> expected "0" error + fault = dm_entry_param_method(ctx, CMD_GET_NOTIFICATION, "Device.UserInterface.CurrentLanguage", NULL, NULL); + assert_int_equal(fault, 0); + + // validate parameter : name, type, value + validate_parameter(ctx, "Device.UserInterface.CurrentLanguage", "2", "xsd:string"); +} + +static void test_api_bbfdm_get_set_notification_library_parameter(void **state) +{ + struct dmctx *ctx = (struct dmctx *) *state; + int fault = 0; + + // get notification ==> expected "0" error + fault = dm_entry_param_method(ctx, CMD_GET_NOTIFICATION, "Device.ManagementServer.EnableCWMP", NULL, NULL); + assert_int_equal(fault, 0); + + // validate parameter : name, type, value + validate_parameter(ctx, "Device.ManagementServer.EnableCWMP", "0", "xsd:boolean"); + + // set notification ==> expected "0" error + fault = dm_entry_param_method(ctx, CMD_SET_NOTIFICATION, "Device.ManagementServer.EnableCWMP", "1", NULL); + assert_int_equal(fault, 0); + + // get notification ==> expected "0" error + fault = dm_entry_param_method(ctx, CMD_GET_NOTIFICATION, "Device.ManagementServer.EnableCWMP", NULL, NULL); + assert_int_equal(fault, 0); + + // validate parameter : name, type, value + validate_parameter(ctx, "Device.ManagementServer.EnableCWMP", "1", "xsd:boolean"); + + // set notification ==> expected "0" error + fault = dm_entry_param_method(ctx, CMD_SET_NOTIFICATION, "Device.ManagementServer.EnableCWMP", "2", NULL); + assert_int_equal(fault, 0); + + // get notification ==> expected "0" error + fault = dm_entry_param_method(ctx, CMD_GET_NOTIFICATION, "Device.ManagementServer.EnableCWMP", NULL, NULL); + assert_int_equal(fault, 0); + + // validate parameter : name, type, value + validate_parameter(ctx, "Device.ManagementServer.EnableCWMP", "2", "xsd:boolean"); +} + +static void test_api_bbfdm_add_del_standard_object(void **state) +{ + struct dmctx *ctx = (struct dmctx *) *state; + int fault = 0; + + // Get name object ==> expected "0" error + fault = dm_entry_param_method(ctx, CMD_GET_NAME, "Device.Users.User.", "1", NULL); + assert_int_equal(fault, 0); + + // add object ==> expected "0" error + fault = dm_entry_param_method(ctx, CMD_ADD_OBJECT, "Device.Users.User.", "test_key", NULL); + assert_int_equal(fault, 0); + + // check the new instance + assert_non_null(ctx->addobj_instance); + assert_string_equal(ctx->addobj_instance, "2"); + + // delete object ==> expected "0" error + fault = dm_entry_param_method(ctx, CMD_DEL_OBJECT, "Device.Users.User.2.", "test_key", NULL); + assert_int_equal(fault, 0); + + // Get name object after deleting instance 2 ==> expected "9005" error + fault = dm_entry_param_method(ctx, CMD_GET_NAME, "Device.Users.User.2.", "1", NULL); + assert_int_equal(fault, FAULT_9005); + + // delete all object ==> expected "0" error + fault = dm_entry_param_method(ctx, CMD_DEL_OBJECT, "Device.Users.User.", "test_key", NULL); + assert_int_equal(fault, 0); + + // Get name object after deleting all instances ==> expected "9005" error + fault = dm_entry_param_method(ctx, CMD_GET_NAME, "Device.Users.User.1.", "1", NULL); + assert_int_equal(fault, FAULT_9005); +} + +static void test_api_bbfdm_add_del_json_object(void **state) +{ + struct dmctx *ctx = (struct dmctx *) *state; + int fault = 0; + + // Get name object ==> expected "0" error + fault = dm_entry_param_method(ctx, CMD_GET_NAME, "Device.X_IOPSYS_EU_Dropbear.", "1", NULL); + assert_int_equal(fault, 0); + + // add object ==> expected "0" error + fault = dm_entry_param_method(ctx, CMD_ADD_OBJECT, "Device.X_IOPSYS_EU_Dropbear.", "test_key", NULL); + assert_int_equal(fault, 0); + + // check the new instance + assert_non_null(ctx->addobj_instance); + assert_string_equal(ctx->addobj_instance, "2"); + + // delete object ==> expected "0" error + fault = dm_entry_param_method(ctx, CMD_DEL_OBJECT, "Device.X_IOPSYS_EU_Dropbear.2.", "test_key", NULL); + assert_int_equal(fault, 0); + + // Get name object after deleting instance 2 ==> expected "9005" error + fault = dm_entry_param_method(ctx, CMD_GET_NAME, "Device.X_IOPSYS_EU_Dropbear.2.", "1", NULL); + assert_int_equal(fault, FAULT_9005); + + // delete all object ==> expected "0" error + fault = dm_entry_param_method(ctx, CMD_DEL_OBJECT, "Device.X_IOPSYS_EU_Dropbear.", "test_key", NULL); + assert_int_equal(fault, 0); + + // Get name object after deleting all instances ==> expected "9005" error + fault = dm_entry_param_method(ctx, CMD_GET_NAME, "Device.X_IOPSYS_EU_Dropbear.1.", "1", NULL); + assert_int_equal(fault, FAULT_9005); +} + +static void test_api_bbfdm_add_del_library_object(void **state) +{ + struct dmctx *ctx = (struct dmctx *) *state; + int fault = 0; + + // Get name object ==> expected "0" error + fault = dm_entry_param_method(ctx, CMD_GET_NAME, "Device.ManagementServer.InformParameter.", "1", NULL); + assert_int_equal(fault, 0); + + // add object ==> expected "0" error + fault = dm_entry_param_method(ctx, CMD_ADD_OBJECT, "Device.ManagementServer.InformParameter.", "test_key", NULL); + assert_int_equal(fault, 0); + + // check the new instance + assert_non_null(ctx->addobj_instance); + assert_string_equal(ctx->addobj_instance, "3"); + + // delete object ==> expected "0" error + fault = dm_entry_param_method(ctx, CMD_DEL_OBJECT, "Device.ManagementServer.InformParameter.2.", "test_key", NULL); + assert_int_equal(fault, 0); + + // Get name object after deleting instance 2 ==> expected "9005" error + fault = dm_entry_param_method(ctx, CMD_GET_NAME, "Device.X_IOPSYS_EU_Dropbear.2.", "1", NULL); + assert_int_equal(fault, FAULT_9005); + + // delete all object ==> expected "0" error + fault = dm_entry_param_method(ctx, CMD_DEL_OBJECT, "Device.ManagementServer.InformParameter.", "test_key", NULL); + assert_int_equal(fault, 0); + + // Get name object after deleting all instances ==> expected "9005" error + fault = dm_entry_param_method(ctx, CMD_GET_NAME, "Device.ManagementServer.InformParameter.1.", "1", NULL); + assert_int_equal(fault, FAULT_9005); +} + +static void test_api_bbfdm_valid_standard_operate(void **state) +{ + struct dmctx *ctx = (struct dmctx *) *state; + char *input = "{\"Host\":\"iopsys.eu\",\"NumberOfRepetitions\":\"1\",\"Timeout\":\"5000\",\"DataBlockSize\":\"64\"}"; + struct dm_parameter *n; + int fault = 0; + + fault = dm_entry_param_method(ctx, CMD_USP_OPERATE, "Device.IP.Diagnostics.IPPing", input, NULL); + assert_int_equal(fault, SUCCESS); + + list_for_each_entry(n, &ctx->list_parameter, list) { + if (strcmp(n->name, "SuccessCount") == 0) { + assert_string_equal(n->data, "1"); + } else if (strcmp(n->name, "FailureCount") == 0) { + assert_string_equal(n->data, "0"); + } else { + assert_string_not_equal(n->data, "0"); + } + assert_string_equal(n->type, "xsd:unsignedInt"); + } +} + +static void test_api_bbfdm_valid_library_operate(void **state) +{ + struct dmctx *ctx = (struct dmctx *) *state; + char *input = "{\"Host\":\"iopsys.eu\"}"; + struct dm_parameter *n; + int fault = 0; + + fault = dm_entry_param_method(ctx, CMD_USP_OPERATE, "Device.X_IOPSYS_EU_PingTEST.Run", input, NULL); + assert_int_equal(fault, SUCCESS); + + list_for_each_entry(n, &ctx->list_parameter, list) { + assert_string_not_equal(n->data, "0"); + assert_string_equal(n->type, "xsd:unsignedInt"); + } +} + +int main(void) +{ + const struct CMUnitTest tests[] = { + // Get/Set Value method test cases + cmocka_unit_test_setup_teardown(test_api_bbfdm_get_set_standard_parameter, setup, teardown_commit), + cmocka_unit_test_setup_teardown(test_api_bbfdm_get_set_json_parameter, setup, teardown_commit), + cmocka_unit_test_setup_teardown(test_api_bbfdm_get_set_library_parameter, setup, teardown_commit), + + // Get/Set Notification method test cases + cmocka_unit_test_setup_teardown(test_api_bbfdm_get_set_notification_standard_parameter, setup, teardown_commit), + cmocka_unit_test_setup_teardown(test_api_bbfdm_get_set_notification_json_parameter, setup, teardown_commit), + cmocka_unit_test_setup_teardown(test_api_bbfdm_get_set_notification_library_parameter, setup, teardown_commit), + + // Add/Delete Object method test cases + cmocka_unit_test_setup_teardown(test_api_bbfdm_add_del_standard_object, setup, teardown_commit), + cmocka_unit_test_setup_teardown(test_api_bbfdm_add_del_json_object, setup, teardown_commit), + cmocka_unit_test_setup_teardown(test_api_bbfdm_add_del_library_object, setup, teardown_commit), + + // Operate method test cases + cmocka_unit_test_setup_teardown(test_api_bbfdm_valid_standard_operate, setup, teardown_commit), + cmocka_unit_test_setup_teardown(test_api_bbfdm_valid_library_operate, setup, teardown_commit), + }; + + return cmocka_run_group_tests(tests, NULL, group_teardown); +} + + diff --git a/test/cmocka/unit_test_bbfd.c b/test/cmocka/unit_test_bbfd.c new file mode 100644 index 00000000..a6c9f76d --- /dev/null +++ b/test/cmocka/unit_test_bbfd.c @@ -0,0 +1,909 @@ +#include +#include +#include +#include + +#include +#include + +#define DROPBEAR_FILE_PATH "/builds/iopsys/bbf/test/files/etc/bbfdm/json/X_IOPSYS_EU_Dropbear.json" +#define DROPBEAR_JSON_PATH "/etc/bbfdm/json/X_IOPSYS_EU_Dropbear.json" +#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 int setup(void **state) +{ + struct dmctx *ctx = calloc(1, sizeof(struct dmctx)); + if (!ctx) + return -1; + + dm_ctx_init(ctx, INSTANCE_MODE_NUMBER); + *state = ctx; + + return 0; +} + +static int teardown_commit(void **state) +{ + struct dmctx *ctx = (struct dmctx *) *state; + + dm_entry_restart_services(); + dm_ctx_clean(ctx); + free(ctx); + + return 0; +} + +static int teardown_revert(void **state) +{ + struct dmctx *ctx = (struct dmctx *) *state; + + dm_entry_revert_changes(); + dm_ctx_clean(ctx); + free(ctx); + + return 0; +} + +static int group_teardown(void **state) +{ + free_dynamic_arrays(); + return 0; +} + +static void test_api_bbfdm_get_value_object(void **state) +{ + struct dmctx *ctx = (struct dmctx *) *state; + struct dm_parameter *first_entry; + int fault = 0; + + fault = dm_entry_param_method(ctx, CMD_GET_VALUE, "Device.", NULL, NULL); + assert_int_equal(fault, 0); + + first_entry = list_first_entry(&ctx->list_parameter, struct dm_parameter, list); + assert_true(&first_entry->list != &ctx->list_parameter); +} + +static void test_api_bbfdm_get_value_parameter(void **state) +{ + struct dmctx *ctx = (struct dmctx *) *state; + struct dm_parameter *first_entry; + int fault = 0; + + fault = dm_entry_param_method(ctx, CMD_GET_VALUE, "Device.WiFi.Radio.1.Alias", NULL, NULL); + assert_int_equal(fault, 0); + + first_entry = list_first_entry(&ctx->list_parameter, struct dm_parameter, list); + assert_true(&first_entry->list != &ctx->list_parameter); +} + +static void test_api_bbfdm_get_value_empty(void **state) +{ + struct dmctx *ctx = (struct dmctx *) *state; + struct dm_parameter *first_entry; + int fault = 0; + + fault = dm_entry_param_method(ctx, CMD_GET_VALUE, "", NULL, NULL); + assert_int_equal(fault, 0); + + first_entry = list_first_entry(&ctx->list_parameter, struct dm_parameter, list); + assert_true(&first_entry->list != &ctx->list_parameter); +} + +static void test_api_bbfdm_get_value_wrong_object_path(void **state) +{ + struct dmctx *ctx = (struct dmctx *) *state; + struct dm_parameter *first_entry; + int fault = 0; + + fault = dm_entry_param_method(ctx, CMD_GET_VALUE, "Device.DSLL.", NULL, NULL); + assert_int_equal(fault, FAULT_9005); + + first_entry = list_first_entry(&ctx->list_parameter, struct dm_parameter, list); + assert_true(&first_entry->list == &ctx->list_parameter); +} + +static void test_api_bbfdm_get_value_wrong_parameter_path(void **state) +{ + struct dmctx *ctx = (struct dmctx *) *state; + struct dm_parameter *first_entry; + int fault = 0; + + fault = dm_entry_param_method(ctx, CMD_GET_VALUE, "Device.Users.User.1.Enabl", NULL, NULL); + assert_int_equal(fault, FAULT_9005); + + first_entry = list_first_entry(&ctx->list_parameter, struct dm_parameter, list); + assert_true(&first_entry->list == &ctx->list_parameter); +} + +static void test_api_bbfdm_get_name_object(void **state) +{ + struct dmctx *ctx = (struct dmctx *) *state; + struct dm_parameter *first_entry; + int fault = 0; + + fault = dm_entry_param_method(ctx, CMD_GET_NAME, "Device.", "0", NULL); + assert_int_equal(fault, 0); + + first_entry = list_first_entry(&ctx->list_parameter, struct dm_parameter, list); + assert_true(&first_entry->list != &ctx->list_parameter); +} + +static void test_api_bbfdm_get_name_parameter(void **state) +{ + struct dmctx *ctx = (struct dmctx *) *state; + struct dm_parameter *first_entry; + int fault = 0; + + fault = dm_entry_param_method(ctx, CMD_GET_NAME, "Device.WiFi.Radio.1.Enable", "false", NULL); + assert_int_equal(fault, 0); + + first_entry = list_first_entry(&ctx->list_parameter, struct dm_parameter, list); + assert_true(&first_entry->list != &ctx->list_parameter); +} + +static void test_api_bbfdm_get_name_dot(void **state) +{ + struct dmctx *ctx = (struct dmctx *) *state; + struct dm_parameter *first_entry; + int fault = 0; + + fault = dm_entry_param_method(ctx, CMD_GET_NAME, ".", "0", NULL); + assert_int_equal(fault, FAULT_9005); + + first_entry = list_first_entry(&ctx->list_parameter, struct dm_parameter, list); + assert_true(&first_entry->list == &ctx->list_parameter); +} + +static void test_api_bbfdm_get_name_wrong_object_path(void **state) +{ + struct dmctx *ctx = (struct dmctx *) *state; + struct dm_parameter *first_entry; + int fault = 0; + + fault = dm_entry_param_method(ctx, CMD_GET_NAME, "Device.WiFii.", "0", NULL); + assert_int_equal(fault, FAULT_9005); + + first_entry = list_first_entry(&ctx->list_parameter, struct dm_parameter, list); + assert_true(&first_entry->list == &ctx->list_parameter); +} + +static void test_api_bbfdm_get_name_without_next_level(void **state) +{ + struct dmctx *ctx = (struct dmctx *) *state; + struct dm_parameter *first_entry; + int fault = 0; + + fault = dm_entry_param_method(ctx, CMD_GET_NAME, "Device.", NULL, NULL); + assert_int_equal(fault, FAULT_9003); + + first_entry = list_first_entry(&ctx->list_parameter, struct dm_parameter, list); + assert_true(&first_entry->list == &ctx->list_parameter); +} + +static void test_api_bbfdm_get_name_wrong_next_level(void **state) +{ + struct dmctx *ctx = (struct dmctx *) *state; + struct dm_parameter *first_entry; + int fault = 0; + + fault = dm_entry_param_method(ctx, CMD_GET_NAME, "Device.WiFi.", "test", NULL); + assert_int_equal(fault, FAULT_9003); + + first_entry = list_first_entry(&ctx->list_parameter, struct dm_parameter, list); + assert_true(&first_entry->list == &ctx->list_parameter); +} + +static void test_api_bbfdm_get_notification_object(void **state) +{ + struct dmctx *ctx = (struct dmctx *) *state; + struct dm_parameter *first_entry; + int fault = 0; + + fault = dm_entry_param_method(ctx, CMD_GET_NOTIFICATION, "Device.", NULL, NULL); + assert_int_equal(fault, 0); + + first_entry = list_first_entry(&ctx->list_parameter, struct dm_parameter, list); + assert_true(&first_entry->list != &ctx->list_parameter); +} + +static void test_api_bbfdm_get_notification_parameter(void **state) +{ + struct dmctx *ctx = (struct dmctx *) *state; + struct dm_parameter *first_entry; + int fault = 0; + + fault = dm_entry_param_method(ctx, CMD_GET_NOTIFICATION, "Device.ManagementServer.ConnReqJabberID", NULL, NULL); + assert_int_equal(fault, 0); + + first_entry = list_first_entry(&ctx->list_parameter, struct dm_parameter, list); + assert_true(&first_entry->list != &ctx->list_parameter); +} + +static void test_api_bbfdm_get_notification_dot(void **state) +{ + struct dmctx *ctx = (struct dmctx *) *state; + struct dm_parameter *first_entry; + int fault = 0; + + fault = dm_entry_param_method(ctx, CMD_GET_NOTIFICATION, ".", NULL, NULL); + assert_int_equal(fault, FAULT_9005); + + first_entry = list_first_entry(&ctx->list_parameter, struct dm_parameter, list); + assert_true(&first_entry->list == &ctx->list_parameter); +} + +static void test_api_bbfdm_get_notification_wrong_object_path(void **state) +{ + struct dmctx *ctx = (struct dmctx *) *state; + struct dm_parameter *first_entry; + int fault = 0; + + fault = dm_entry_param_method(ctx, CMD_GET_NOTIFICATION, "Device.User.", NULL, NULL); + assert_int_equal(fault, FAULT_9005); + + first_entry = list_first_entry(&ctx->list_parameter, struct dm_parameter, list); + assert_true(&first_entry->list == &ctx->list_parameter); +} + +static void test_api_bbfdm_get_notification_wrong_parameter_path(void **state) +{ + struct dmctx *ctx = (struct dmctx *) *state; + struct dm_parameter *first_entry; + int fault = 0; + + fault = dm_entry_param_method(ctx, CMD_GET_NOTIFICATION, "Device.Users.User.1.Usename", NULL, NULL); + assert_int_equal(fault, FAULT_9005); + + first_entry = list_first_entry(&ctx->list_parameter, struct dm_parameter, list); + assert_true(&first_entry->list == &ctx->list_parameter); +} + +static void test_api_bbfdm_set_value_object(void **state) +{ + struct dmctx *ctx = (struct dmctx *) *state; + struct param_fault *first_fault; + int fault = 0; + + fault = dm_entry_param_method(ctx, CMD_SET_VALUE, "Device.Users.User.", "test", NULL); + assert_int_equal(fault, FAULT_9005); + + first_fault = list_first_entry(&ctx->list_fault_param, struct param_fault, list); + assert_true(&first_fault->list != &ctx->list_fault_param); +} + +static void test_api_bbfdm_set_value_parameter(void **state) +{ + struct dmctx *ctx = (struct dmctx *) *state; + struct param_fault *first_fault; + int fault = 0; + + fault = dm_entry_param_method(ctx, CMD_SET_VALUE, "Device.Users.User.1.Username", "test", NULL); + assert_int_equal(fault, 0); + + first_fault = list_first_entry(&ctx->list_fault_param, struct param_fault, list); + assert_true(&first_fault->list == &ctx->list_fault_param); + + fault = dm_entry_apply(ctx, CMD_SET_VALUE, "test_key", NULL); + assert_int_equal(fault, 0); +} + +static void test_api_bbfdm_set_value_empty(void **state) +{ + struct dmctx *ctx = (struct dmctx *) *state; + struct param_fault *first_fault; + int fault = 0; + + fault = dm_entry_param_method(ctx, CMD_SET_VALUE, "", "test", NULL); + assert_int_equal(fault, FAULT_9005); + + first_fault = list_first_entry(&ctx->list_fault_param, struct param_fault, list); + assert_true(&first_fault->list != &ctx->list_fault_param); +} + +static void test_api_bbfdm_set_value_wrong_parameter_path(void **state) +{ + struct dmctx *ctx = (struct dmctx *) *state; + struct param_fault *first_fault; + int fault = 0; + + fault = dm_entry_param_method(ctx, CMD_SET_VALUE, "Device.Users.User.Username", "test", NULL); + assert_int_equal(fault, FAULT_9005); + + first_fault = list_first_entry(&ctx->list_fault_param, struct param_fault, list); + assert_true(&first_fault->list != &ctx->list_fault_param); +} + +static void test_api_bbfdm_set_value_parameter_non_writable(void **state) +{ + struct dmctx *ctx = (struct dmctx *) *state; + struct param_fault *first_fault; + int fault = 0; + + fault = dm_entry_param_method(ctx, CMD_SET_VALUE, "Device.WiFi.Radio.1.Status", "Enabled", NULL); + assert_int_equal(fault, FAULT_9008); + + first_fault = list_first_entry(&ctx->list_fault_param, struct param_fault, list); + assert_true(&first_fault->list != &ctx->list_fault_param); +} + +static void test_api_bbfdm_set_value_parameter_wrong_value(void **state) +{ + struct dmctx *ctx = (struct dmctx *) *state; + struct param_fault *first_fault; + int fault = 0; + + fault = dm_entry_param_method(ctx, CMD_SET_VALUE, "Device.WiFi.Radio.1.Enable", "truee", NULL); + assert_int_equal(fault, FAULT_9007); + + first_fault = list_first_entry(&ctx->list_fault_param, struct param_fault, list); + assert_true(&first_fault->list != &ctx->list_fault_param); +} + +static void test_api_bbfdm_set_notification_object(void **state) +{ + struct dmctx *ctx = (struct dmctx *) *state; + int fault = 0; + + fault = dm_entry_param_method(ctx, CMD_SET_NOTIFICATION, "Device.Users.", "1", NULL); + assert_int_equal(fault, 0); +} + +static void test_api_bbfdm_set_notification_parameter(void **state) +{ + struct dmctx *ctx = (struct dmctx *) *state; + int fault = 0; + + fault = dm_entry_param_method(ctx, CMD_SET_NOTIFICATION, "Device.DeviceInfo.UpTime", "2", NULL); + assert_int_equal(fault, 0); +} + +static void test_api_bbfdm_set_notification_empty(void **state) +{ + struct dmctx *ctx = (struct dmctx *) *state; + int fault = 0; + + fault = dm_entry_param_method(ctx, CMD_SET_NOTIFICATION, "Device.", "1", NULL); + assert_int_equal(fault, FAULT_9009); +} + +static void test_api_bbfdm_set_notification_root(void **state) +{ + struct dmctx *ctx = (struct dmctx *) *state; + int fault = 0; + + fault = dm_entry_param_method(ctx, CMD_SET_NOTIFICATION, "", "2", NULL); + assert_int_equal(fault, FAULT_9009); +} + +static void test_api_bbfdm_set_notification_wrong_notif(void **state) +{ + struct dmctx *ctx = (struct dmctx *) *state; + int fault = 0; + + fault = dm_entry_param_method(ctx, CMD_SET_NOTIFICATION, "Device.DeviceInfo.", "12", NULL); + assert_int_equal(fault, FAULT_9003); +} + +static void test_api_bbfdm_set_notification_forced_parameter_notif(void **state) +{ + struct dmctx *ctx = (struct dmctx *) *state; + int fault = 0; + + fault = dm_entry_param_method(ctx, CMD_SET_NOTIFICATION, "Device.DeviceInfo.SoftwareVersion", "1", NULL); + assert_int_equal(fault, FAULT_9009); +} + +static void test_api_bbfdm_set_notification_wrong_object_path(void **state) +{ + struct dmctx *ctx = (struct dmctx *) *state; + int fault = 0; + + fault = dm_entry_param_method(ctx, CMD_SET_NOTIFICATION, "Device.Device.", "1", NULL); + assert_int_equal(fault, FAULT_9005); +} + +static void test_api_bbfdm_set_notification_wrong_parameter_path(void **state) +{ + struct dmctx *ctx = (struct dmctx *) *state; + int fault = 0; + + fault = dm_entry_param_method(ctx, CMD_SET_NOTIFICATION, "Device.Users.1.Username", "1", NULL); + assert_int_equal(fault, FAULT_9005); +} + +static void test_api_bbfdm_set_notification_parameter_in_notification(void **state) +{ + struct dmctx *ctx = (struct dmctx *) *state; + int fault = 0; + + fault = dm_entry_param_method(ctx, CMD_SET_NOTIFICATION, "Device.Users.User.1.Username", "1", "false"); + assert_int_equal(fault, 0); +} + +static void test_api_bbfdm_set_notification_parameter_wrong_in_notification(void **state) +{ + struct dmctx *ctx = (struct dmctx *) *state; + int fault = 0; + + fault = dm_entry_param_method(ctx, CMD_SET_NOTIFICATION, "Device.WiFi.Radio.1.Enable", "1", "test"); + assert_int_equal(fault, FAULT_9003); +} + +static void test_api_bbfdm_add_object(void **state) +{ + struct dmctx *ctx = (struct dmctx *) *state; + int fault = 0; + + fault = dm_entry_param_method(ctx, CMD_ADD_OBJECT, "Device.Users.User.", "test_key", NULL); + assert_int_equal(fault, 0); + + assert_non_null(ctx->addobj_instance); + assert_string_not_equal(ctx->addobj_instance, "0"); +} + +static void test_api_bbfdm_add_wrong_object(void **state) +{ + struct dmctx *ctx = (struct dmctx *) *state; + int fault = 0; + + fault = dm_entry_param_method(ctx, CMD_ADD_OBJECT, "Device.WiFi.Users.", "test_key", NULL); + assert_int_equal(fault, FAULT_9005); + + assert_null(ctx->addobj_instance); +} + +static void test_api_bbfdm_add_object_non_writable(void **state) +{ + struct dmctx *ctx = (struct dmctx *) *state; + int fault = 0; + + fault = dm_entry_param_method(ctx, CMD_ADD_OBJECT, "Device.WiFi.Radio.", "test_key", NULL); + assert_int_equal(fault, FAULT_9005); + + assert_null(ctx->addobj_instance); +} + +static void test_api_bbfdm_add_object_empty(void **state) +{ + struct dmctx *ctx = (struct dmctx *) *state; + int fault = 0; + + fault = dm_entry_param_method(ctx, CMD_ADD_OBJECT, "", "test_key", NULL); + assert_int_equal(fault, FAULT_9005); + + assert_null(ctx->addobj_instance); +} + +static void test_api_bbfdm_delete_object(void **state) +{ + struct dmctx *ctx = (struct dmctx *) *state; + int fault = 0; + + fault = dm_entry_param_method(ctx, CMD_DEL_OBJECT, "Device.WiFi.SSID.1.", "test_key", NULL); + assert_int_equal(fault, 0); +} + +static void test_api_bbfdm_delete_object_all_instances(void **state) +{ + struct dmctx *ctx = (struct dmctx *) *state; + int fault = 0; + + fault = dm_entry_param_method(ctx, CMD_DEL_OBJECT, "Device.Users.User.", "test_key", NULL); + assert_int_equal(fault, 0); +} + +static void test_api_bbfdm_delete_wrong_object(void **state) +{ + struct dmctx *ctx = (struct dmctx *) *state; + int fault = 0; + + fault = dm_entry_param_method(ctx, CMD_DEL_OBJECT, "Device.WiFi.SSID", "test_key", NULL); + assert_int_equal(fault, FAULT_9005); +} + +static void test_api_bbfdm_delete_object_non_writable(void **state) +{ + struct dmctx *ctx = (struct dmctx *) *state; + int fault = 0; + + fault = dm_entry_param_method(ctx, CMD_DEL_OBJECT, "Device.Hosts.Host.", "test_key", NULL); + assert_int_equal(fault, FAULT_9005); +} + +static void test_api_bbfdm_delete_object_empty(void **state) +{ + struct dmctx *ctx = (struct dmctx *) *state; + int fault = 0; + + fault = dm_entry_param_method(ctx, CMD_DEL_OBJECT, "", "test_key", NULL); + assert_int_equal(fault, FAULT_9005); +} + +static void test_api_bbfdm_get_list_notify(void **state) +{ + struct dmctx *ctx = (struct dmctx *) *state; + struct dm_parameter *first_entry; + int fault = 0; + + fault = dm_entry_param_method(ctx, CMD_LIST_NOTIFY, NULL, NULL, NULL); + assert_int_equal(fault, 0); + + first_entry = list_first_entry(&ctx->list_parameter, struct dm_parameter, list); + assert_true(&first_entry->list != &ctx->list_parameter); +} + +static void test_api_bbfdm_valid_operate(void **state) +{ + struct dmctx *ctx = (struct dmctx *) *state; + int fault = 0; + + fault = dm_entry_param_method(ctx, CMD_USP_OPERATE, "Device.DHCPv4.Client.1.Renew", NULL, NULL); + assert_int_equal(fault, SUCCESS); +} + +static void test_api_bbfdm_wrong_operate(void **state) +{ + struct dmctx *ctx = (struct dmctx *) *state; + int fault = 0; + + fault = dm_entry_param_method(ctx, CMD_USP_OPERATE, "Device.IP.Diagnostics.IPing", NULL, NULL); + assert_int_equal(fault, CMD_NOT_FOUND); +} + +static void test_api_bbfdm_get_list_operate(void **state) +{ + struct dmctx *ctx = (struct dmctx *) *state; + struct dm_parameter *first_entry; + int fault = 0; + + fault = dm_entry_param_method(ctx, CMD_USP_LIST_OPERATE, NULL, NULL, NULL); + assert_int_equal(fault, 0); + + first_entry = list_first_entry(&ctx->list_parameter, struct dm_parameter, list); + assert_true(&first_entry->list != &ctx->list_parameter); +} + +static void test_api_bbfdm_get_schema(void **state) +{ + struct dmctx *ctx = (struct dmctx *) *state; + struct dm_parameter *first_entry; + int fault = 0; + + fault = dm_entry_param_method(ctx, CMD_GET_SCHEMA, NULL, NULL, NULL); + assert_int_equal(fault, 0); + + first_entry = list_first_entry(&ctx->list_parameter, struct dm_parameter, list); + assert_true(&first_entry->list != &ctx->list_parameter); +} + +static void test_api_bbfdm_get_instances_object(void **state) +{ + struct dmctx *ctx = (struct dmctx *) *state; + struct dm_parameter *first_entry; + int fault = 0; + + fault = dm_entry_param_method(ctx, CMD_GET_INSTANCES, "Device.", "0", NULL); + assert_int_equal(fault, 0); + + first_entry = list_first_entry(&ctx->list_parameter, struct dm_parameter, list); + assert_true(&first_entry->list != &ctx->list_parameter); +} + +static void test_api_bbfdm_get_instances_wrong_object(void **state) +{ + struct dmctx *ctx = (struct dmctx *) *state; + struct dm_parameter *first_entry; + int fault = 0; + + fault = dm_entry_param_method(ctx, CMD_GET_INSTANCES, "Device.WiFii.", "true", NULL); + assert_int_equal(fault, FAULT_9005); + + first_entry = list_first_entry(&ctx->list_parameter, struct dm_parameter, list); + assert_true(&first_entry->list == &ctx->list_parameter); +} + +static void test_api_bbfdm_get_instances_without_next_level(void **state) +{ + struct dmctx *ctx = (struct dmctx *) *state; + struct dm_parameter *first_entry; + int fault = 0; + + fault = dm_entry_param_method(ctx, CMD_GET_INSTANCES, "Device.WiFi.", NULL, NULL); + assert_int_equal(fault, 0); + + first_entry = list_first_entry(&ctx->list_parameter, struct dm_parameter, list); + assert_true(&first_entry->list != &ctx->list_parameter); +} + +static void test_api_bbfdm_get_instances_wrong_next_level(void **state) +{ + struct dmctx *ctx = (struct dmctx *) *state; + struct dm_parameter *first_entry; + int fault = 0; + + fault = dm_entry_param_method(ctx, CMD_GET_INSTANCES, "Device.WiFi.", "test", NULL); + assert_int_equal(fault, FAULT_9003); + + first_entry = list_first_entry(&ctx->list_parameter, struct dm_parameter, list); + assert_true(&first_entry->list == &ctx->list_parameter); +} + +static void test_api_bbfdm_json_get_value(void **state) +{ + struct dmctx *ctx = (struct dmctx *) *state; + struct dm_parameter *first_entry; + int fault = 0; + + /* + * Test of JSON Object Path + */ + fault = dm_entry_param_method(ctx, CMD_GET_VALUE, "Device.X_IOPSYS_EU_Dropbear.", NULL, NULL); + assert_int_equal(fault, 0); + + first_entry = list_first_entry(&ctx->list_parameter, struct dm_parameter, list); + assert_true(&first_entry->list != &ctx->list_parameter); + + dm_ctx_clean_sub(ctx); + dm_ctx_init_sub(ctx, INSTANCE_MODE_NUMBER); + + /* + * Test of JSON Parameter Path + */ + fault = dm_entry_param_method(ctx, CMD_GET_VALUE, "Device.UserInterface.Enable", NULL, NULL); + assert_int_equal(fault, 0); + + first_entry = list_first_entry(&ctx->list_parameter, struct dm_parameter, list); + assert_true(&first_entry->list != &ctx->list_parameter); + + dm_ctx_clean_sub(ctx); + dm_ctx_init_sub(ctx, INSTANCE_MODE_NUMBER); + + remove(DROPBEAR_JSON_PATH); + + fault = dm_entry_param_method(ctx, CMD_GET_VALUE, "Device.X_IOPSYS_EU_Dropbear.", NULL, NULL); + assert_int_equal(fault, FAULT_9005); + + first_entry = list_first_entry(&ctx->list_parameter, struct dm_parameter, list); + assert_true(&first_entry->list == &ctx->list_parameter); +} + +static void test_api_bbfdm_json_set_value(void **state) +{ + struct dmctx *ctx = (struct dmctx *) *state; + struct param_fault *first_fault; + int fault = 0; + + DMCMD("/bin/cp", 2, DROPBEAR_FILE_PATH, DROPBEAR_JSON_PATH); + + fault = dm_entry_param_method(ctx, CMD_SET_VALUE, "Device.UserInterface.Enable", "true", NULL); + assert_int_equal(fault, 0); + + first_fault = list_first_entry(&ctx->list_fault_param, struct param_fault, list); + assert_true(&first_fault->list == &ctx->list_fault_param); + + fault = dm_entry_apply(ctx, CMD_SET_VALUE, "test_key", NULL); + assert_int_equal(fault, 0); + + fault = dm_entry_param_method(ctx, CMD_SET_VALUE, "Device.X_IOPSYS_EU_Dropbear.1.Port", "9856", NULL); + assert_int_equal(fault, 0); + + first_fault = list_first_entry(&ctx->list_fault_param, struct param_fault, list); + assert_true(&first_fault->list == &ctx->list_fault_param); + + fault = dm_entry_apply(ctx, CMD_SET_VALUE, "test_key", NULL); + assert_int_equal(fault, 0); +} + +static void test_api_bbfdm_json_add_object(void **state) +{ + struct dmctx *ctx = (struct dmctx *) *state; + int fault = 0; + + fault = dm_entry_param_method(ctx, CMD_ADD_OBJECT, "Device.X_IOPSYS_EU_Dropbear.", "test_key", NULL); + assert_int_equal(fault, 0); + + assert_non_null(ctx->addobj_instance); + assert_string_not_equal(ctx->addobj_instance, "0"); +} + +static void test_api_bbfdm_json_delete_object(void **state) +{ + struct dmctx *ctx = (struct dmctx *) *state; + int fault = 0; + + fault = dm_entry_param_method(ctx, CMD_DEL_OBJECT, "Device.X_IOPSYS_EU_Dropbear.1.", "test_key", NULL); + assert_int_equal(fault, 0); + + fault = dm_entry_param_method(ctx, CMD_DEL_OBJECT, "Device.X_IOPSYS_EU_Dropbear.", "test_key", NULL); + assert_int_equal(fault, 0); +} + +static void test_api_bbfdm_library_get_value(void **state) +{ + struct dmctx *ctx = (struct dmctx *) *state; + struct dm_parameter *first_entry; + int fault = 0; + + fault = dm_entry_param_method(ctx, CMD_GET_VALUE, "Device.X_IOPSYS_EU_Syslog.", NULL, NULL); + assert_int_equal(fault, 0); + + first_entry = list_first_entry(&ctx->list_parameter, struct dm_parameter, list); + assert_true(&first_entry->list != &ctx->list_parameter); + + dm_ctx_clean_sub(ctx); + dm_ctx_init_sub(ctx, INSTANCE_MODE_NUMBER); + + fault = dm_entry_param_method(ctx, CMD_GET_VALUE, "Device.ManagementServer.EnableCWMP", NULL, NULL); + assert_int_equal(fault, 0); + + first_entry = list_first_entry(&ctx->list_parameter, struct dm_parameter, list); + assert_true(&first_entry->list != &ctx->list_parameter); + + dm_ctx_clean_sub(ctx); + dm_ctx_init_sub(ctx, INSTANCE_MODE_NUMBER); + + remove(LIBBBF_TEST_BBFDM_PATH); + + fault = dm_entry_param_method(ctx, CMD_GET_VALUE, "Device.X_IOPSYS_EU_Syslog.", NULL, NULL); + assert_int_equal(fault, FAULT_9005); + + first_entry = list_first_entry(&ctx->list_parameter, struct dm_parameter, list); + assert_true(&first_entry->list == &ctx->list_parameter); +} + +static void test_api_bbfdm_library_set_value(void **state) +{ + struct dmctx *ctx = (struct dmctx *) *state; + struct param_fault *first_fault; + int fault = 0; + + DMCMD("/bin/cp", 2, LIBBBF_TEST_PATH, LIBBBF_TEST_BBFDM_PATH); + + fault = dm_entry_param_method(ctx, CMD_SET_VALUE, "Device.ManagementServer.EnableCWMP", "true", NULL); + assert_int_equal(fault, 0); + + first_fault = list_first_entry(&ctx->list_fault_param, struct param_fault, list); + assert_true(&first_fault->list == &ctx->list_fault_param); + + fault = dm_entry_apply(ctx, CMD_SET_VALUE, "test_key", NULL); + assert_int_equal(fault, 0); + + fault = dm_entry_param_method(ctx, CMD_SET_VALUE, "Device.X_IOPSYS_EU_Syslog.ServerPort", "9856", NULL); + assert_int_equal(fault, 0); + + first_fault = list_first_entry(&ctx->list_fault_param, struct param_fault, list); + assert_true(&first_fault->list == &ctx->list_fault_param); + + fault = dm_entry_apply(ctx, CMD_SET_VALUE, "test_key", NULL); + assert_int_equal(fault, 0); +} + +static void test_api_bbfdm_library_add_object(void **state) +{ + struct dmctx *ctx = (struct dmctx *) *state; + int fault = 0; + + fault = dm_entry_param_method(ctx, CMD_ADD_OBJECT, "Device.ManagementServer.InformParameter.", "test_key", NULL); + assert_int_equal(fault, 0); + + assert_non_null(ctx->addobj_instance); + assert_string_not_equal(ctx->addobj_instance, "0"); +} + +static void test_api_bbfdm_library_delete_object(void **state) +{ + struct dmctx *ctx = (struct dmctx *) *state; + int fault = 0; + + fault = dm_entry_param_method(ctx, CMD_DEL_OBJECT, "Device.ManagementServer.InformParameter.1.", "test_key", NULL); + assert_int_equal(fault, 0); + + fault = dm_entry_param_method(ctx, CMD_DEL_OBJECT, "Device.ManagementServer.InformParameter.", "test_key", NULL); + assert_int_equal(fault, 0); +} + +int main(void) +{ + const struct CMUnitTest tests[] = { + // Get Value method test cases + cmocka_unit_test_setup_teardown(test_api_bbfdm_get_value_object, setup, teardown_commit), + cmocka_unit_test_setup_teardown(test_api_bbfdm_get_value_parameter, setup, teardown_commit), + cmocka_unit_test_setup_teardown(test_api_bbfdm_get_value_empty, setup, teardown_commit), + cmocka_unit_test_setup_teardown(test_api_bbfdm_get_value_wrong_object_path, setup, teardown_revert), + cmocka_unit_test_setup_teardown(test_api_bbfdm_get_value_wrong_parameter_path, setup, teardown_revert), + + // Get Name method test cases + cmocka_unit_test_setup_teardown(test_api_bbfdm_get_name_object, setup, teardown_commit), + cmocka_unit_test_setup_teardown(test_api_bbfdm_get_name_parameter, setup, teardown_commit), + cmocka_unit_test_setup_teardown(test_api_bbfdm_get_name_dot, setup, teardown_revert), + cmocka_unit_test_setup_teardown(test_api_bbfdm_get_name_wrong_object_path, setup, teardown_revert), + cmocka_unit_test_setup_teardown(test_api_bbfdm_get_name_without_next_level, setup, teardown_revert), + cmocka_unit_test_setup_teardown(test_api_bbfdm_get_name_wrong_next_level, setup, teardown_revert), + + // Get Notification method test cases + cmocka_unit_test_setup_teardown(test_api_bbfdm_get_notification_object, setup, teardown_commit), + cmocka_unit_test_setup_teardown(test_api_bbfdm_get_notification_parameter, setup, teardown_commit), + cmocka_unit_test_setup_teardown(test_api_bbfdm_get_notification_dot, setup, teardown_revert), + cmocka_unit_test_setup_teardown(test_api_bbfdm_get_notification_wrong_object_path, setup, teardown_revert), + cmocka_unit_test_setup_teardown(test_api_bbfdm_get_notification_wrong_parameter_path, setup, teardown_revert), + + // Set Value method test cases + cmocka_unit_test_setup_teardown(test_api_bbfdm_set_value_object, setup, teardown_revert), + cmocka_unit_test_setup_teardown(test_api_bbfdm_set_value_parameter, setup, teardown_commit), + cmocka_unit_test_setup_teardown(test_api_bbfdm_set_value_empty, setup, teardown_revert), + cmocka_unit_test_setup_teardown(test_api_bbfdm_set_value_wrong_parameter_path, setup, teardown_revert), + cmocka_unit_test_setup_teardown(test_api_bbfdm_set_value_parameter_non_writable, setup, teardown_revert), + cmocka_unit_test_setup_teardown(test_api_bbfdm_set_value_parameter_wrong_value, setup, teardown_revert), + + // Set Notification method test cases + cmocka_unit_test_setup_teardown(test_api_bbfdm_set_notification_object, setup, teardown_commit), + cmocka_unit_test_setup_teardown(test_api_bbfdm_set_notification_parameter, setup, teardown_commit), + cmocka_unit_test_setup_teardown(test_api_bbfdm_set_notification_empty, setup, teardown_revert), + cmocka_unit_test_setup_teardown(test_api_bbfdm_set_notification_root, setup, teardown_revert), + cmocka_unit_test_setup_teardown(test_api_bbfdm_set_notification_wrong_notif, setup, teardown_revert), + cmocka_unit_test_setup_teardown(test_api_bbfdm_set_notification_forced_parameter_notif, setup, teardown_revert), + cmocka_unit_test_setup_teardown(test_api_bbfdm_set_notification_wrong_object_path, setup, teardown_revert), + cmocka_unit_test_setup_teardown(test_api_bbfdm_set_notification_wrong_parameter_path, setup, teardown_revert), + cmocka_unit_test_setup_teardown(test_api_bbfdm_set_notification_parameter_in_notification, setup, teardown_revert), + cmocka_unit_test_setup_teardown(test_api_bbfdm_set_notification_parameter_wrong_in_notification, setup, teardown_revert), + + // Add Object method test cases + cmocka_unit_test_setup_teardown(test_api_bbfdm_add_object, setup, teardown_commit), + cmocka_unit_test_setup_teardown(test_api_bbfdm_add_wrong_object, setup, teardown_revert), + cmocka_unit_test_setup_teardown(test_api_bbfdm_add_object_non_writable, setup, teardown_revert), + cmocka_unit_test_setup_teardown(test_api_bbfdm_add_object_empty, setup, teardown_revert), + + // Delete Object method test cases + cmocka_unit_test_setup_teardown(test_api_bbfdm_delete_object, setup, teardown_revert), + cmocka_unit_test_setup_teardown(test_api_bbfdm_delete_object_all_instances, setup, teardown_commit), + cmocka_unit_test_setup_teardown(test_api_bbfdm_delete_wrong_object, setup, teardown_revert), + cmocka_unit_test_setup_teardown(test_api_bbfdm_delete_object_non_writable, setup, teardown_revert), + cmocka_unit_test_setup_teardown(test_api_bbfdm_delete_object_empty, setup, teardown_revert), + + // Get Instances method test cases + cmocka_unit_test_setup_teardown(test_api_bbfdm_get_instances_object, setup, teardown_commit), + cmocka_unit_test_setup_teardown(test_api_bbfdm_get_instances_wrong_object, setup, teardown_revert), + cmocka_unit_test_setup_teardown(test_api_bbfdm_get_instances_without_next_level, setup, teardown_revert), + cmocka_unit_test_setup_teardown(test_api_bbfdm_get_instances_wrong_next_level, setup, teardown_revert), + + // Get List Notify method test cases + cmocka_unit_test_setup_teardown(test_api_bbfdm_get_list_notify, setup, teardown_commit), + + // Operate method test cases + cmocka_unit_test_setup_teardown(test_api_bbfdm_valid_operate, setup, teardown_commit), + cmocka_unit_test_setup_teardown(test_api_bbfdm_wrong_operate, setup, teardown_commit), + + // Get List Operate method test cases + cmocka_unit_test_setup_teardown(test_api_bbfdm_get_list_operate, setup, teardown_commit), + + // Get Schema method test cases + cmocka_unit_test_setup_teardown(test_api_bbfdm_get_schema, setup, teardown_commit), + + // JSON: Get Value method test cases + cmocka_unit_test_setup_teardown(test_api_bbfdm_json_get_value, setup, teardown_commit), + + // JSON: Set Value method test cases + cmocka_unit_test_setup_teardown(test_api_bbfdm_json_set_value, setup, teardown_commit), + + // JSON: Add Object method test cases + cmocka_unit_test_setup_teardown(test_api_bbfdm_json_add_object, setup, teardown_commit), + + // JSON: Delete Object method test cases + cmocka_unit_test_setup_teardown(test_api_bbfdm_json_delete_object, setup, teardown_commit), + + // Library: Get Value method test cases + cmocka_unit_test_setup_teardown(test_api_bbfdm_library_get_value, setup, teardown_commit), + + // Library: Set Value method test cases + cmocka_unit_test_setup_teardown(test_api_bbfdm_library_set_value, setup, teardown_commit), + + // Library: Add Object method test cases + cmocka_unit_test_setup_teardown(test_api_bbfdm_library_add_object, setup, teardown_commit), + + // Library: Delete Object method test cases + cmocka_unit_test_setup_teardown(test_api_bbfdm_library_delete_object, setup, teardown_commit), + }; + + return cmocka_run_group_tests(tests, NULL, group_teardown); +} diff --git a/test/files/etc/bbfdm/json/UserInterface.json b/test/files/etc/bbfdm/json/UserInterface.json new file mode 100644 index 00000000..9b82190c --- /dev/null +++ b/test/files/etc/bbfdm/json/UserInterface.json @@ -0,0 +1,283 @@ +{ + "Device.UserInterface.": { + "type": "object", + "protocols": [ + "cwmp", + "usp" + ], + "access": false, + "array": false, + "Enable": { + "type": "boolean", + "read": true, + "write": true, + "protocols": [ + "cwmp", + "usp" + ], + "datatype": "boolean", + "mapping": [ + { + "type": "uci", + "uci": { + "file": "userinterface", + "section": { + "name": "global" + }, + "option": { + "name": "enable" + } + } + } + ] + }, + "PasswordRequired": { + "type": "boolean", + "read": true, + "write": true, + "protocols": [ + "cwmp", + "usp" + ], + "datatype": "boolean", + "mapping": [ + { + "type": "uci", + "uci": { + "file": "userinterface", + "section": { + "name": "global" + }, + "option": { + "name": "password_required" + } + } + } + ] + }, + "PasswordUserSelectable": { + "type": "boolean", + "read": true, + "write": true, + "protocols": [ + "cwmp", + "usp" + ], + "datatype": "boolean", + "mapping": [ + { + "type": "uci", + "uci": { + "file": "userinterface", + "section": { + "name": "global" + }, + "option": { + "name": "password_user_selectable" + } + } + } + ] + }, + "TextColor": { + "type": "hexBinary", + "read": true, + "write": true, + "protocols": [ + "cwmp", + "usp" + ], + "datatype": "hexBinary", + "range": [ + { + "min": 3, + "max": 3 + } + ], + "mapping": [ + { + "type": "uci", + "uci": { + "file": "userinterface", + "section": { + "name": "global" + }, + "option": { + "name": "text_color" + } + } + } + ] + }, + "BackgroundColor": { + "type": "hexBinary", + "read": true, + "write": true, + "protocols": [ + "cwmp", + "usp" + ], + "datatype": "hexBinary", + "range": [ + { + "min": 3, + "max": 3 + } + ], + "mapping": [ + { + "type": "uci", + "uci": { + "file": "userinterface", + "section": { + "name": "global" + }, + "option": { + "name": "background_color" + } + } + } + ] + }, + "ButtonColor": { + "type": "hexBinary", + "read": true, + "write": true, + "protocols": [ + "cwmp", + "usp" + ], + "datatype": "hexBinary", + "range": [ + { + "min": 3, + "max": 3 + } + ], + "mapping": [ + { + "type": "uci", + "uci": { + "file": "userinterface", + "section": { + "name": "global" + }, + "option": { + "name": "button_color" + } + } + } + ] + }, + "ButtonTextColor": { + "type": "hexBinary", + "read": true, + "write": true, + "protocols": [ + "cwmp", + "usp" + ], + "datatype": "hexBinary", + "range": [ + { + "min": 3, + "max": 3 + } + ], + "mapping": [ + { + "type": "uci", + "uci": { + "file": "userinterface", + "section": { + "name": "global" + }, + "option": { + "name": "button_text_color" + } + } + } + ] + }, + "AvailableLanguages": { + "type": "string", + "read": true, + "write": false, + "protocols": [ + "cwmp", + "usp" + ], + "list": { + "datatype": "string", + "maxsize": 256 + }, + "mapping": [ + { + "type": "uci", + "uci": { + "file": "userinterface", + "section": { + "name": "global" + }, + "option": { + "name": "available_languages" + } + } + } + ] + }, + "CurrentLanguage": { + "type": "string", + "read": true, + "write": true, + "protocols": [ + "cwmp", + "usp" + ], + "datatype": "string", + "range": [ + { + "max": 16 + } + ], + "mapping": [ + { + "type": "uci", + "uci": { + "file": "userinterface", + "section": { + "name": "global" + }, + "option": { + "name": "current_language" + } + } + } + ] + }, + "X_IOPSYS_EU_Theme": { + "type": "string", + "read": true, + "write": true, + "protocols": [ + "cwmp", + "usp" + ], + "datatype": "string", + "mapping": [ + { + "type": "uci", + "uci": { + "file": "userinterface", + "section": { + "name": "global" + }, + "option": { + "name": "theme" + } + } + } + ] + } + } +} \ No newline at end of file diff --git a/test/files/etc/bbfdm/json/X_IOPSYS_EU_Dropbear.json b/test/files/etc/bbfdm/json/X_IOPSYS_EU_Dropbear.json new file mode 100644 index 00000000..4a2fb033 --- /dev/null +++ b/test/files/etc/bbfdm/json/X_IOPSYS_EU_Dropbear.json @@ -0,0 +1,333 @@ +{ + "Device.X_IOPSYS_EU_Dropbear.": { + "type": "object", + "protocols": [ + "cwmp", + "usp" + ], + "array": true, + "mapping": { + "type": "uci", + "uci": { + "file": "dropbear", + "section": { + "type": "dropbear" + }, + "dmmapfile": "dmmap_dropbear" + } + }, + "Alias": { + "type": "string", + "protocols": [ + "cwmp", + "usp" + ], + "read": true, + "write": true, + "mapping": [ + { + "type": "uci", + "uci": { + "file": "dmmap_dropbear", + "section": { + "type": "dropbear", + "index": "@i-1" + }, + "option": { + "name": "dropbearalias" + }, + "path":"/etc/bbfdm", + } + } + ] + }, + "PasswordAuth": { + "type": "boolean", + "protocols": [ + "cwmp", + "usp" + ], + "read": true, + "write": true, + "mapping": [ + { + "type": "uci", + "uci": { + "file": "dropbear", + "section": { + "type": "dropbear", + "index": "@i-1" + }, + "option": { + "name": "PasswordAuth" + } + } + } + ] + }, + "RootPasswordAuth": { + "type": "boolean", + "protocols": [ + "cwmp", + "usp" + ], + "read": true, + "write": true, + "mapping": [ + { + "type": "uci", + "uci": { + "file": "dropbear", + "section": { + "type": "dropbear", + "index": "@i-1" + }, + "option": { + "name": "RootPasswordAuth" + } + } + } + ] + }, + "Port": { + "type": "unsignedInt", + "protocols": [ + "cwmp", + "usp" + ], + "read": true, + "write": true, + "mapping": [ + { + "type": "uci", + "uci": { + "file": "dropbear", + "section": { + "type": "dropbear", + "index": "@i-1" + }, + "option": { + "name": "Port" + } + } + } + ] + }, + "RootLogin": { + "type": "boolean", + "protocols": [ + "cwmp", + "usp" + ], + "read": true, + "write": true, + "mapping": [ + { + "type": "uci", + "uci": { + "file": "dropbear", + "section": { + "type": "dropbear", + "index": "@i-1" + }, + "option": { + "name": "RootLogin" + } + } + } + ] + }, + "GatewayPorts": { + "type": "boolean", + "protocols": [ + "cwmp", + "usp" + ], + "read": true, + "write": true, + "mapping": [ + { + "type": "uci", + "uci": { + "file": "dropbear", + "section": { + "type": "dropbear", + "index": "@i-1" + }, + "option": { + "name": "GatewayPorts" + } + } + } + ] + }, + "Interface": { + "type": "string", + "protocols": [ + "cwmp", + "usp" + ], + "read": true, + "write": true, + "mapping": [ + { + "type": "uci", + "uci": { + "file": "dropbear", + "section": { + "type": "dropbear", + "index": "@i-1" + }, + "option": { + "name": "Interface" + } + } + } + ] + }, + "RSAKeyFile": { + "type": "string", + "protocols": [ + "cwmp", + "usp" + ], + "read": true, + "write": true, + "mapping": [ + { + "type": "uci", + "uci": { + "file": "dropbear", + "section": { + "type": "dropbear", + "index": "@i-1" + }, + "option": { + "name": "rsakeyfile" + } + } + } + ] + }, + "DSSKeyFile": { + "type": "string", + "protocols": [ + "cwmp", + "usp" + ], + "read": true, + "write": true, + "mapping": [ + { + "type": "uci", + "uci": { + "file": "dropbear", + "section": { + "type": "dropbear", + "index": "@i-1" + }, + "option": { + "name": "dsskeyfile" + } + } + } + ] + }, + "SSHKeepAlive": { + "type": "unsignedInt", + "protocols": [ + "cwmp", + "usp" + ], + "read": true, + "write": true, + "mapping": [ + { + "type": "uci", + "uci": { + "file": "dropbear", + "section": { + "type": "dropbear", + "index": "@i-1" + }, + "option": { + "name": "SSHKeepAlive" + } + } + } + ] + }, + "IdleTimeout": { + "type": "unsignedInt", + "protocols": [ + "cwmp", + "usp" + ], + "read": true, + "write": true, + "mapping": [ + { + "type": "uci", + "uci": { + "file": "dropbear", + "section": { + "type": "dropbear", + "index": "@i-1" + }, + "option": { + "name": "IdleTimeout" + } + } + } + ] + }, + "Verbose": { + "type": "boolean", + "protocols": [ + "cwmp", + "usp" + ], + "read": true, + "write": true, + "mapping": [ + { + "type": "uci", + "uci": { + "file": "dropbear", + "section": { + "type": "dropbear", + "index": "@i-1" + }, + "option": { + "name": "verbose" + } + } + } + ] + }, + "BannerFile": { + "type": "string", + "protocols": [ + "cwmp", + "usp" + ], + "read": true, + "write": true, + "mapping": [ + { + "type": "uci", + "uci": { + "file": "dropbear", + "section": { + "type": "dropbear", + "index": "@i-1" + }, + "option": { + "name": "BannerFile" + } + } + } + ] + } + } +} diff --git a/test/files/etc/board-db/config/device b/test/files/etc/board-db/config/device new file mode 100644 index 00000000..5c60ca11 --- /dev/null +++ b/test/files/etc/board-db/config/device @@ -0,0 +1,11 @@ +config deviceinfo 'deviceinfo' + option Manufacturer 'iopsys' + option ProductClass 'FirstClass' + option SerialNumber '000000001' + option SoftwareVersion 'IOPSYS-CODE-ANALYSIS' + option HardwareVersion '1.0' + option DeviceCategory 'Gateway' + option ModelName 'ModelName' + option Description 'Iopsys code analysis test simulator' + option ManufacturerOUI 'XXX' + option BaseMACAddress 'feeddeadbeef' diff --git a/test/files/etc/config/cwmp b/test/files/etc/config/cwmp new file mode 100644 index 00000000..684e6a7f --- /dev/null +++ b/test/files/etc/config/cwmp @@ -0,0 +1,59 @@ +config acs 'acs' + option enabled '0' + option url '' + option userid '' #$OUI-$SER + option passwd 'iopsys' + option periodic_inform_enable 'true' + option periodic_inform_interval '1800' + option periodic_inform_time '0' + option ParameterKey '' + option dhcp_discovery 'enable' + # compression possible configs: GZIP, Deflate, Disabled + option compression 'Disabled' + #­ possible configs interval :[1:65535] + option retry_min_wait_interval '5' + #­ possible configs interval :[1000:65535] + option retry_interval_multiplier '2000' + option https_ssl_capath '' + option ipv6_enable '0' + +config cpe 'cpe' + option interface 'eth0.1' + option default_wan_interface 'wan' + option log_to_console 'disable' + option log_to_file 'enable' + # log_severity: INFO (Default) + # log_severity possible configs: EMERG, ALERT, CRITIC ,ERROR, WARNING, NOTICE, INFO, DEBUG + option log_severity 'INFO' + option log_file_name '/var/log/icwmpd.log' + option log_max_size '102400' + option userid '' #$OUI-$SER + option passwd 'iopsys' + option port '7547' + option ubus_socket '/var/run/ubus.sock' + option provisioning_code '' + option amd_version '5' + # compression possible configs: InstanceNumber, InstanceAlias + option instance_mode 'InstanceNumber' + option session_timeout '60' + option notification '1' + option datamodel 'tr181' + option exec_download '0' + option periodic_notify_enable '1' + option periodic_notify_interval '10' + +config lwn 'lwn' + option enable '1' + option hostname '' + option port '0' + +config inform_extra + option enabled '0' + option parameter 'Device.DeviceInfo.Manufacturer' + option events '0 BOOTSTRAP,2 PERIODIC' + +config inform_extra + option enabled '0' + option parameter 'Device.DeviceInfo.SerialNumber' + option events '0 BOOTSTRAP' + diff --git a/test/files/etc/config/dropbear b/test/files/etc/config/dropbear new file mode 100644 index 00000000..6151eb39 --- /dev/null +++ b/test/files/etc/config/dropbear @@ -0,0 +1,5 @@ +config dropbear + option PasswordAuth 'on' + option RootPasswordAuth 'on' + option Port '22' +# option BannerFile '/etc/banner' \ No newline at end of file diff --git a/test/files/etc/config/network b/test/files/etc/config/network new file mode 100644 index 00000000..67c7e9bd --- /dev/null +++ b/test/files/etc/config/network @@ -0,0 +1,17 @@ +config interface 'loopback' + option ifname 'lo' + option proto 'static' + option ipaddr '127.0.0.1' + option netmask '255.0.0.0' + +config interface 'wan' + option proto 'dhcp' + option hostname 'iopsysWrt-00220775DC6C' + option vendorid 'eg400' + option ifname 'eth0' + option reqopts '43' + +config interface 'wan6' + option proto 'dhcpv6' + option ifname '@wan' + diff --git a/test/files/etc/config/system b/test/files/etc/config/system new file mode 100644 index 00000000..4deaa5f1 --- /dev/null +++ b/test/files/etc/config/system @@ -0,0 +1,14 @@ +config system + option timezone 'CET-1CEST,M3.5.0,M10.5.0/3' + option zonename 'Europe/Stockholm' + option conloglevel '7' + option cronloglevel '9' + option hostname 'iopsys' + option log_size '200' + option ttylogin 1 + +config timeserver 'ntp' + option enabled 1 + option enable_server '1' + list server 'ntp1.sth.netnod.se' + list server 'ntp1.gbg.netnod.se' diff --git a/test/files/etc/config/userinterface b/test/files/etc/config/userinterface new file mode 100644 index 00000000..d4704c8f --- /dev/null +++ b/test/files/etc/config/userinterface @@ -0,0 +1,11 @@ +config userinterface global + option enable '1' + option password_required '1' + option password_user_selectable '1' + option text_color '52525B' + option background_color 'FFFFFF' + option button_color 'FA4141' + option button_text_color 'FFFFFF' + option available_languages 'en,sv' + option current_language 'en' + option theme 'light' diff --git a/test/files/etc/config/users b/test/files/etc/config/users new file mode 100644 index 00000000..ca728026 --- /dev/null +++ b/test/files/etc/config/users @@ -0,0 +1,7 @@ + +config user 'user' + option enabled '1' + option remote_access '1' + list _access_w 'admin' + list _access_w 'support' + list _access_w 'user' diff --git a/test/files/etc/config/wireless b/test/files/etc/config/wireless new file mode 100644 index 00000000..6bacba1b --- /dev/null +++ b/test/files/etc/config/wireless @@ -0,0 +1,12 @@ +config wifi-device 'test2' + option channel 'auto' + option hwmode 'auto' + option country 'DE' + option band 'a' + option bandwidth '80' + +config wifi-iface 'test2_1' + option device 'test2' + option ifname 'test2' + option mode 'ap' + option encryption 'psk2' diff --git a/test/files/tmp/wifi.ap.status.data b/test/files/tmp/wifi.ap.status.data new file mode 100644 index 00000000..ae40a2e5 --- /dev/null +++ b/test/files/tmp/wifi.ap.status.data @@ -0,0 +1,104 @@ +{ + "ifname": "test2", + "status": "running", + "ssid": "iopsysWrt-002207AB9F80", + "bssid": "00:22:07:aa:91:88", + "security": "WPA2PSK", + "encryption": "CCMP", + "channel": 36, + "bandwidth": 80, + "standard": "802.11", + "num_stations": 0, + "max_stations": 0, + "utilization": 0, + "adm_capacity": 0, + "hidden": true, + "supp_security": [ + "NONE", + "WPA3PSK", + "WPA2PSK+WPA3PSK", + "WPA", + "WPA2", + "WPA2+WPA3" + ], + "capabilities": { + "wmm": false, + "apsd": false, + "shortslot": false, + "dot11h": false, + "2040coex": false, + "psmp": false, + "proxy_arp": false, + "dot11v_btm": true, + "dot11n": { + "dot11n_ldpc": true, + "dot11n_40": true, + "dot11n_ps": true, + "dot11n_sgi20": true, + "dot11n_sgi40": true, + "dot11n_tx_stbc": false, + "dot11n_rx_stbc": false, + "dot11n_supp_max_mcs": 31 + }, + "dot11ac": { + "dot11ac_160": true, + "dot11ac_8080": true, + "dot11ac_mpdu_max": 11454, + "dot11ac_sgi80": true, + "dot11ac_sgi160": false, + "dot11ac_rx_ldpc": true, + "dot11ac_tx_stbc": false, + "dot11ac_rx_stbc_1ss": false, + "dot11ac_rx_stbc_2ss": false, + "dot11ac_rx_stbc_3ss": false, + "dot11ac_rx_stbc_4ss": false, + "dot11ac_su_beamformer": true, + "dot11ac_su_beamformee": true, + "dot11ac_mu_beamformer": false, + "dot11ac_mu_beamformee": false, + "dot11ac_supp_max_rx_mcs": 9, + "dot11ac_supp_max_rx_nss": 4, + "dot11ac_supp_max_tx_mcs": 9, + "dot11ac_supp_max_tx_nss": 4 + }, + "dot11k": { + "dot11k_link_meas": true, + "dot11k_nbr_report": true, + "dot11k_bcn_passive": true, + "dot11k_bcn_active": true, + "dot11k_bcn_table": true, + "dot11k_rcpi": false, + "dot11k_rsni": false + } + }, + "wmm_params": [ + { + "ac": "BE", + "aifsn": 0, + "cwmin": 21, + "cwmax": 741, + "txop": 0 + }, + { + "ac": "BE", + "aifsn": 0, + "cwmin": 3, + "cwmax": 12, + "txop": 0 + }, + { + "ac": "BE", + "aifsn": 0, + "cwmin": 78, + "cwmax": 999, + "txop": 0 + }, + { + "ac": "BE", + "aifsn": 0, + "cwmin": 66, + "cwmax": 149, + "txop": 0 + } + ] +} diff --git a/test/files/usr/libexec/rpcd/wifi.ap.test2 b/test/files/usr/libexec/rpcd/wifi.ap.test2 new file mode 100755 index 00000000..0d3849c7 --- /dev/null +++ b/test/files/usr/libexec/rpcd/wifi.ap.test2 @@ -0,0 +1,17 @@ +#!/bin/sh + +. /usr/share/libubox/jshn.sh + +case "$1" in + list) + echo '{ "status" : {} }' + ;; + call) + case "$2" in + status) + cat /tmp/wifi.ap.status.data 2>/dev/null + ;; + esac + ;; +esac + diff --git a/test/files/var/state/cwmp b/test/files/var/state/cwmp new file mode 100644 index 00000000..74c7ab3c --- /dev/null +++ b/test/files/var/state/cwmp @@ -0,0 +1 @@ +cwmp.acs.dhcp_url='http://192.168.1.123:8080/openacs'