From: José Bollo Date: Tue, 24 Jul 2018 10:53:15 +0000 (+0200) Subject: coverage: Improve coverage test X-Git-Tag: 5.99.3~9 X-Git-Url: https://gerrit.automotivelinux.org/gerrit/gitweb?p=src%2Fapp-framework-binder.git;a=commitdiff_plain;h=4772c5626204f6ab0e26b938f49a6719fb10f88d coverage: Improve coverage test The test now raise an overall coverage rate: lines......: 75.4% (8356 of 11080 lines) functions..: 80.4% (1094 of 1360 functions) Also Improve the documentation and improve parts of code. Change-Id: Ic2b8bc2f85d4181aa0b358a953f95cb105a0eed9 Signed-off-by: José Bollo --- diff --git a/.gitignore b/.gitignore index abc051fe..d7183090 100644 --- a/.gitignore +++ b/.gitignore @@ -9,7 +9,6 @@ CMakeFiles/ CMakeCache.txt nbproject/private/* cmake_install.cmake -*.so .vscode stress-out* node_modules/ diff --git a/bindings/samples/hello3.c b/bindings/samples/hello3.c index 477e47bd..7e54e3a9 100644 --- a/bindings/samples/hello3.c +++ b/bindings/samples/hello3.c @@ -467,6 +467,11 @@ static void setloa (afb_req_t request) afb_req_reply_f(request, NULL, NULL, "LOA set to %d", loa); } +static void ok (afb_req_t request) +{ + afb_req_reply_f(request, NULL, NULL, NULL); +} + static void setctx (afb_req_t request) { struct json_object *x = afb_req_json(request); @@ -530,6 +535,23 @@ static void ref(afb_req_t request) afb_req_unref(request); } +static void mute(afb_req_t request) +{ +} + +void queue_cb(int signum, void *arg) +{ + afb_req_t request = arg; + afb_req_reply(request, NULL, NULL, NULL); + afb_req_unref(request); +} + +static void queue(afb_req_t request) +{ + afb_req_addref(request); + afb_api_queue_job(afb_req_get_api(request), queue_cb, request, NULL, 0); +} + static void rootdir (afb_req_t request) { ssize_t s; @@ -586,6 +608,88 @@ static void locale (afb_req_t request) static void api (afb_req_t request); +/** + * Definition of an authorization entry + */ +static struct afb_auth auths[] = { + { /* 0 */ + .type = afb_auth_Or, + .first = &auths[1], + .next = &auths[9], + }, + { /* 1 */ + .type = afb_auth_And, + .first = &auths[2], + .next = &auths[3], + }, + { /* 2 */ + .type = afb_auth_Yes + }, + { /* 3 */ + .type = afb_auth_And, + .first = &auths[4], + .next = &auths[5], + }, + { /* 4 */ + .type = afb_auth_LOA, + .loa = 0 + }, + { /* 5 */ + .type = afb_auth_Or, + .first = &auths[6], + .next = &auths[7], + }, + { /* 6 */ + .type = afb_auth_No + }, + { /* 7 */ + .type = afb_auth_Not, + .first = &auths[8] + }, + { /* 8 */ + .type = afb_auth_Yes + }, + { /* 9 */ + .type = afb_auth_And, + .first = &auths[10], + .next = &auths[13], + }, + { /* 10 */ + .type = afb_auth_Or, + .first = &auths[12], + .next = &auths[11], + }, + { /* 11 */ + .type = afb_auth_Not, + .first = &auths[13] + }, + { /* 12 */ + .type = afb_auth_Token + }, + { /* 13 */ + .type = afb_auth_And, + .first = &auths[14], + .next = &auths[17], + }, + { /* 14 */ + .type = afb_auth_Or, + .first = &auths[16], + .next = &auths[15], + }, + { /* 15 */ + .type = afb_auth_Not, + .first = &auths[16] + }, + { /* 16 */ + .type = afb_auth_Permission, + .text = "permission" + }, + { /* 17 */ + .type = afb_auth_Yes + } +}; + + // NOTE: this sample does not use session to keep test a basic as possible // in real application most APIs should be protected with AFB_SESSION_CHECK static const struct afb_verb_v3 verbs[]= { @@ -611,11 +715,15 @@ static const struct afb_verb_v3 verbs[]= { { .verb="appid", .callback=appid }, { .verb="uid", .callback=uid }, { .verb="exit", .callback=exitnow }, - { .verb="close", .callback=closess }, - { .verb="set-loa", .callback=setloa }, + { .verb="close", .callback=closess, .session=AFB_SESSION_CLOSE }, + { .verb="set-loa", .callback=setloa, .auth = &auths[0] }, + { .verb="has-loa-1", .callback=ok, .session=AFB_SESSION_LOA_1 }, + { .verb="has-loa-2", .callback=ok, .session=AFB_SESSION_LOA_2 }, + { .verb="has-loa-3", .callback=ok, .session=AFB_SESSION_LOA_3 }, { .verb="setctx", .callback=setctx, .vcbdata = (void*)(intptr_t)1 }, { .verb="setctxif", .callback=setctx, .vcbdata = (void*)(intptr_t)0 }, { .verb="getctx", .callback=getctx }, + { .verb="reftok", .callback=ok, .session=AFB_SESSION_CHECK | AFB_SESSION_REFRESH }, { .verb="info", .callback=info }, { .verb="eventloop", .callback=eventloop }, { .verb="dbus", .callback=dbus }, @@ -625,6 +733,8 @@ static const struct afb_verb_v3 verbs[]= { { .verb="rootdir", .callback=rootdir}, { .verb="locale", .callback=locale}, { .verb="api", .callback=api}, + { .verb="mute", .callback=mute}, + { .verb="queue", .callback=queue}, { .verb=NULL} }; diff --git a/coverage/.gitignore b/coverage/.gitignore index 69f6ea4f..531f1a98 100644 --- a/coverage/.gitignore +++ b/coverage/.gitignore @@ -8,7 +8,7 @@ bin/afb-daemon-cov bin/test-apiset bin/test-session bin/test-wrap-json -*.o -*.so -*.gcda -*.gcno +bin/*.o +bin/*.so +bin/*.gcda +bin/*.gcno diff --git a/coverage/bin/Makefile b/coverage/bin/Makefile index f9d561ed..ef8b68e8 100644 --- a/coverage/bin/Makefile +++ b/coverage/bin/Makefile @@ -62,11 +62,10 @@ cflags = $(ccflags) $(ldflags) defs = -DAGL_DEVEL \ -DWITH_MONITORING_OPTION \ - -DWITH_SUPERVISION \ -DAFB_VERSION=\"cov\" \ -DBINDING_INSTALL_DIR=\"$(shell pwd)/fake\" -afb_lib_src = $(shell ls $(srcdir)/*.c | egrep -v '/afs-|/main-' ) +afb_lib_src = $(shell ls $(srcdir)/*.c | egrep -v '/afs-|/main-|/fdev-epoll.c|/afb-ws-client.c' ) afb_lib_obj = $(patsubst $(srcdir)/%.c,%.o,$(afb_lib_src)) afb_lib = afb-lib.a afb_lib_defs = $(defs) @@ -74,7 +73,7 @@ afb_lib_defs = $(defs) afb_daemon_srcs = $(srcdir)/main-afb-daemon.c $(afb_lib_obj) afb_daemon_defs = $(afb_lib_defs) -afb_client_srcs = $(srcdir)/main-afb-client-demo.c $(afb_lib_src) +afb_client_srcs = $(srcdir)/main-afb-client-demo.c $(srcdir)/afb-ws-client.c $(afb_lib_src) afb_client_defs = $(defs) tst_defs = $(defs) diff --git a/coverage/ldpath/strong/hellov2.so b/coverage/ldpath/strong/hellov2.so new file mode 120000 index 00000000..f60e708b --- /dev/null +++ b/coverage/ldpath/strong/hellov2.so @@ -0,0 +1 @@ +../../bin/hellov2.so \ No newline at end of file diff --git a/coverage/scripts/00-trace.sh b/coverage/scripts/00-trace.sh index 27edc5b1..247be611 100755 --- a/coverage/scripts/00-trace.sh +++ b/coverage/scripts/00-trace.sh @@ -2,6 +2,7 @@ $R/bin/afb-client -k $WSURL <subset) + if (tmp == set) + return -1; + tmp = set->subset; set->subset = afb_apiset_addref(subset); afb_apiset_unref(tmp); + + return 0; } void afb_apiset_onlack_set(struct afb_apiset *set, int (*callback)(void*, struct afb_apiset*, const char*), void *closure, void (*cleanup)(void*)) diff --git a/src/afb-apiset.h b/src/afb-apiset.h index 5aacecc6..1a115fbf 100644 --- a/src/afb-apiset.h +++ b/src/afb-apiset.h @@ -38,7 +38,7 @@ extern void afb_apiset_onlack_set( void *closure, void (*cleanup)(void*closure)); -extern void afb_apiset_subset_set(struct afb_apiset *set, struct afb_apiset *subset); +extern int afb_apiset_subset_set(struct afb_apiset *set, struct afb_apiset *subset); extern struct afb_apiset *afb_apiset_subset_get(struct afb_apiset *set); extern int afb_apiset_add(struct afb_apiset *set, const char *name, struct afb_api_item api); diff --git a/src/main-afb-daemon.c b/src/main-afb-daemon.c index 3f32e879..f1996811 100644 --- a/src/main-afb-daemon.c +++ b/src/main-afb-daemon.c @@ -534,8 +534,7 @@ static void startup_call_unref(struct afb_xreq *xreq) free(sreq->api); free(sreq->verb); json_object_put(sreq->xreq.json); - sreq->index++; - if (sreq->index < sreq->count) + if (++sreq->index < sreq->count) startup_call_current(sreq); else { afb_session_close(sreq->session); diff --git a/src/tests/CMakeLists.txt b/src/tests/CMakeLists.txt index f0349a68..b516a9db 100644 --- a/src/tests/CMakeLists.txt +++ b/src/tests/CMakeLists.txt @@ -24,6 +24,7 @@ if(check_FOUND) add_subdirectory(session) add_subdirectory(apiset) add_subdirectory(apiv3) + add_subdirectory(wrap-json) else(check_FOUND) MESSAGE(WARNING "check not found! no test!") endif(check_FOUND) diff --git a/src/tests/apiset/test-apiset.c b/src/tests/apiset/test-apiset.c index ccab4637..b49ade90 100644 --- a/src/tests/apiset/test-apiset.c +++ b/src/tests/apiset/test-apiset.c @@ -549,6 +549,49 @@ END_TEST /*********************************************************************/ +START_TEST (check_subset) +{ + int rc; + struct afb_apiset *a, *b, *c, *d; + + a = afb_apiset_create_subset_first(NULL, "a", 0); + ck_assert_ptr_nonnull(a); + ck_assert_str_eq("a", afb_apiset_name(a)); + ck_assert_ptr_null(afb_apiset_subset_get(a)); + + b = afb_apiset_create_subset_first(a, "b", 0); + ck_assert_ptr_nonnull(b); + ck_assert_str_eq("b", afb_apiset_name(b)); + ck_assert_ptr_eq(b, afb_apiset_subset_get(a)); + ck_assert_ptr_null(afb_apiset_subset_get(b)); + + c = afb_apiset_create_subset_first(a, "c", 0); + ck_assert_ptr_nonnull(c); + ck_assert_str_eq("c", afb_apiset_name(c)); + ck_assert_ptr_eq(c, afb_apiset_subset_get(a)); + ck_assert_ptr_eq(b, afb_apiset_subset_get(c)); + ck_assert_ptr_null(afb_apiset_subset_get(b)); + + d = afb_apiset_create_subset_last(a, "d", 0); + ck_assert_ptr_nonnull(d); + ck_assert_str_eq("d", afb_apiset_name(d)); + ck_assert_ptr_eq(c, afb_apiset_subset_get(a)); + ck_assert_ptr_eq(b, afb_apiset_subset_get(c)); + ck_assert_ptr_eq(d, afb_apiset_subset_get(b)); + ck_assert_ptr_null(afb_apiset_subset_get(d)); + + rc = afb_apiset_subset_set(a, b); + ck_assert(rc == 0); + ck_assert_ptr_eq(b, afb_apiset_subset_get(a)); + ck_assert_ptr_eq(d, afb_apiset_subset_get(b)); + ck_assert_ptr_null(afb_apiset_subset_get(d)); + + afb_apiset_unref(a); +} +END_TEST + +/*********************************************************************/ + static Suite *suite; static TCase *tcase; @@ -575,5 +618,6 @@ int main(int ac, char **av) addtest(check_onlack); addtest(check_settings); addtest(check_classes); + addtest(check_subset); return !!srun(); } diff --git a/src/tests/wrap-json/test-wrap-json.c b/src/tests/wrap-json/test-wrap-json.c index 8e22433e..651320af 100644 --- a/src/tests/wrap-json/test-wrap-json.c +++ b/src/tests/wrap-json/test-wrap-json.c @@ -41,6 +41,69 @@ void tclone(struct json_object *object) json_object_put(o); } + +void objcb(void *closure, struct json_object *obj, const char *key) +{ + const char *prefix = closure; + printf(" %s {%s} %s\n", prefix ?: "", key ?: "[]", json_object_to_json_string_ext(obj, JSON_C_TO_STRING_NOSLASHESCAPE)); +} + +void arrcb(void *closure, struct json_object *obj) +{ + objcb(closure, obj, NULL); +} + +void tforall(struct json_object *object) +{ + wrap_json_for_all(object, objcb, "wrap_json_for_all"); + wrap_json_optobject_for_all(object, objcb, "wrap_json_optobject_for_all"); + wrap_json_object_for_all(object, objcb, "wrap_json_object_for_all"); + wrap_json_optarray_for_all(object, arrcb, "wrap_json_optarray_for_all"); + wrap_json_array_for_all(object, arrcb, "wrap_json_array_for_all"); +} + +struct mix +{ + int n; + struct json_object *pair[2]; +}; + +void mixcb(void *closure, struct json_object *obj, const char *key) +{ + struct mix *mix = closure; + + if (!mix->n) { + mix->pair[0] = json_object_new_object(); + mix->pair[1] = json_object_new_object(); + } + json_object_object_add(mix->pair[mix->n & 1], key, json_object_get(obj)); + mix->n++; +} + +void tmix(struct json_object *object) +{ + struct json_object *z; + struct mix mix = { .n = 0 }; + + wrap_json_object_for_all(object, mixcb, &mix); + if (mix.n) { + z = wrap_json_object_add(wrap_json_clone(mix.pair[0]), mix.pair[1]); + if (!wrap_json_contains(z, mix.pair[0])) + printf(" ERROR mix/1\n"); + if (!wrap_json_contains(z, mix.pair[1])) + printf(" ERROR mix/2\n"); + if (!wrap_json_contains(z, object)) + printf(" ERROR mix/3\n"); + if (!wrap_json_contains(object, z)) + printf(" ERROR mix/4\n"); + if (!wrap_json_equal(object, z)) + printf(" ERROR mix/5\n"); + json_object_put(z); + json_object_put(mix.pair[0]); + json_object_put(mix.pair[1]); + } +} + void p(const char *desc, ...) { int rc; @@ -66,11 +129,74 @@ struct json_object *xo[10]; size_t xz[10]; uint8_t *xy[10]; +int extrchk(const char *desc, const char **array, int length, va_list args) +{ + unsigned m, k; + int n; + + if (!desc) + return 0; + + n = 0; + k = m = 0; + while(*desc) { + switch(*desc) { + case '{': + case '[': k = !(*desc - '{'); m = (m << 1) | k; break; + case '}': + case ']': m = m >> 1; k = m&1; break; + case 's': + if (!k) + (void)va_arg(args, char**); + else { + if (n > length) + return -1; + array[n++] = va_arg(args, const char*); + } + break; + case '%': (void)va_arg(args, size_t*); k = m&1; break; + case 'n': k = m&1; break; + case 'b': + case 'i': (void)va_arg(args, int*); k = m&1; break; + case 'I': (void)va_arg(args, int64_t*); k = m&1; break; + case 'f': + case 'F': (void)va_arg(args, double*); k = m&1; break; + case 'o': (void)va_arg(args, struct json_object**), k = m&1; break; + case 'O': (void)va_arg(args, struct json_object**); k = m&1; break; + case 'y': + case 'Y': + (void)va_arg(args, uint8_t**); + (void)va_arg(args, size_t*); + k = m&1; + break; + default: + break; + } + desc++; + } + return n; +} + +const char *mkeys[5]; + +void tchk(struct json_object *object, const char *desc, const char **keys, int length, int qrc) +{ + int rm, rc; + + rm = wrap_json_match(object, desc, keys[0], keys[1], keys[2], keys[3], keys[4]); + rc = wrap_json_check(object, desc, keys[0], keys[1], keys[2], keys[3], keys[4]); + if (rc != qrc) + printf(" ERROR DIFFERS[char %d err %d] %s\n", wrap_json_get_error_position(rc), wrap_json_get_error_code(rc), wrap_json_get_error_string(rc)); + if (rm != !rc) + printf(" ERROR OF MATCH\n"); +} + void u(const char *value, const char *desc, ...) { unsigned m, k; - int rc; + int rc, n; va_list args; + const char *d; struct json_object *object, *o; memset(xs, 0, sizeof xs); @@ -85,14 +211,15 @@ void u(const char *value, const char *desc, ...) rc = wrap_json_vunpack(object, desc, args); va_end(args); if (rc) - printf(" ERROR[char %d err %d] %s\n\n", wrap_json_get_error_position(rc), wrap_json_get_error_code(rc), wrap_json_get_error_string(rc)); + printf(" ERROR[char %d err %d] %s", wrap_json_get_error_position(rc), wrap_json_get_error_code(rc), wrap_json_get_error_string(rc)); else { value = NULL; printf(" SUCCESS"); + d = desc; va_start(args, desc); k = m = 0; - while(*desc) { - switch(*desc) { + while(*d) { + switch(*d) { case '{': m = (m << 1) | 1; k = 1; break; case '}': m = m >> 1; k = m&1; break; case '[': m = m << 1; k = 0; break; @@ -102,7 +229,7 @@ void u(const char *value, const char *desc, ...) case 'n': printf(" n"); k = m&1; break; case 'b': printf(" b:%d", *va_arg(args, int*)); k = m&1; break; case 'i': printf(" i:%d", *va_arg(args, int*)); k = m&1; break; - case 'I': printf(" I:%lld", *va_arg(args, int64_t*)); k = m&1; break; + case 'I': printf(" I:%lld", (long long int)*va_arg(args, int64_t*)); k = m&1; break; case 'f': printf(" f:%f", *va_arg(args, double*)); k = m&1; break; case 'F': printf(" F:%f", *va_arg(args, double*)); k = m&1; break; case 'o': printf(" o:%s", json_object_to_json_string_ext(*va_arg(args, struct json_object**), JSON_C_TO_STRING_NOSLASHESCAPE)); k = m&1; break; @@ -112,17 +239,27 @@ void u(const char *value, const char *desc, ...) uint8_t *p = *va_arg(args, uint8_t**); size_t s = *va_arg(args, size_t*); printf(" y/%d:%.*s", (int)s, (int)s, (char*)p); - k ^= m&1; + k = m&1; break; } default: break; } - desc++; + d++; } va_end(args); - printf("\n\n"); } + printf("\n"); + va_start(args, desc); + n = extrchk(desc, mkeys, (int)(sizeof mkeys / sizeof *mkeys), args); + va_end(args); + if (n < 0) + printf(" ERROR: too much keys in %s\n", desc); + else + tchk(object, desc, mkeys, n, rc); tclone(object); + tforall(object); + tmix(object); + printf("\n"); json_object_put(object); } @@ -329,6 +466,6 @@ int main() c("{\"a\":true,\"b\":false}", "{\"a\":true}", 0, 1); c("{\"a\":true,\"b\":false}", "{\"a\":true,\"c\":false}", 0, 0); c("{\"a\":true,\"c\":false}", "{\"a\":true,\"b\":false}", 0, 0); + return 0; } - diff --git a/src/wrap-json.c b/src/wrap-json.c index a1fcb22d..6bf6f4fe 100644 --- a/src/wrap-json.c +++ b/src/wrap-json.c @@ -815,7 +815,7 @@ int wrap_json_check(struct json_object *object, const char *desc, ...) va_list args; va_start(args, desc); - rc = vunpack(object, desc, args, 0); + rc = wrap_json_vcheck(object, desc, args); va_end(args); return rc; } @@ -831,9 +831,9 @@ int wrap_json_match(struct json_object *object, const char *desc, ...) va_list args; va_start(args, desc); - rc = vunpack(object, desc, args, 0); + rc = wrap_json_vmatch(object, desc, args); va_end(args); - return !rc; + return rc; } int wrap_json_vunpack(struct json_object *object, const char *desc, va_list args) @@ -992,9 +992,13 @@ struct json_object *wrap_json_clone_depth(struct json_object *item, int depth) } /** - * Clones the 'object': returns a copy of it. But doen't clones + * Clones the 'object': returns a copy of it. But doesn't clones * the content. Synonym of wrap_json_clone_depth(object, 1). * + * Be aware that this implementation doesn't clones content that is deeper + * than 1 but it does link these contents to the original object and + * increments their use count. So, everything deeper that 1 is still available. + * * @param object the object to clone * * @return a copy of the object.