summaryrefslogtreecommitdiffstats
path: root/src/tests/apiset/test-apiset.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/tests/apiset/test-apiset.c')
-rw-r--r--src/tests/apiset/test-apiset.c579
1 files changed, 579 insertions, 0 deletions
diff --git a/src/tests/apiset/test-apiset.c b/src/tests/apiset/test-apiset.c
new file mode 100644
index 00000000..bdc84137
--- /dev/null
+++ b/src/tests/apiset/test-apiset.c
@@ -0,0 +1,579 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <errno.h>
+#include <string.h>
+
+#include <check.h>
+#if !defined(ck_assert_ptr_null)
+# define ck_assert_ptr_null(X) ck_assert_ptr_eq(X, NULL)
+# define ck_assert_ptr_nonnull(X) ck_assert_ptr_ne(X, NULL)
+#endif
+
+#include "afb-api.h"
+#include "afb-apiset.h"
+
+const char *names[] = {
+ "Sadie",
+ "Milford",
+ "Yvette",
+ "Carma",
+ "Cory",
+ "Clarence",
+ "Jeffery",
+ "Molly",
+ "Sheba",
+ "Tasha",
+ "Corey",
+ "Gerry",
+ NULL
+};
+
+const char *aliases[] = {
+ "Rich", "Molly",
+ "Alicia", "Carma",
+ "Drema", "YVETTE",
+ "Pablo", "Sheba",
+ "Wendell", "Sadie",
+ "Cathrine", "CarMa",
+ "Allen", "Corey",
+ "Tori", "Drema",
+ NULL
+};
+
+const char *extras[] = {
+ "Meta",
+ "Delia",
+ "Pearlie",
+ "Hank",
+ "Vena",
+ "Terrance",
+ "Gloria",
+ "Tobi",
+ "Mack",
+ "Rosalee",
+ NULL
+};
+
+struct afb_api_itf api_itf_null = {
+ .call = NULL,
+ .service_start = NULL,
+ .update_hooks = NULL,
+ .get_logmask = NULL,
+ .set_logmask = NULL,
+ .describe = NULL,
+ .unref = NULL
+};
+
+
+/*********************************************************************/
+/* check the initialisation */
+START_TEST (check_initialisation)
+{
+ const char name[] = "name";
+ const char noname[] = "";
+ int to = 3600;
+ int noto = -1;
+ struct afb_apiset *a, *b;
+
+ a = afb_apiset_create(NULL, noto);
+ ck_assert_ptr_nonnull(a);
+ ck_assert_str_eq(noname, afb_apiset_name(a));
+ ck_assert_int_eq(noto, afb_apiset_timeout_get(a));
+ afb_apiset_timeout_set(a, to);
+ ck_assert_int_eq(to, afb_apiset_timeout_get(a));
+ b = afb_apiset_addref(a);
+ ck_assert_ptr_eq(a, b);
+ afb_apiset_unref(b);
+ afb_apiset_unref(a);
+
+ a = afb_apiset_create(name, to);
+ ck_assert_ptr_nonnull(a);
+ ck_assert_str_eq(name, afb_apiset_name(a));
+ ck_assert_int_eq(to, afb_apiset_timeout_get(a));
+ afb_apiset_timeout_set(a, noto);
+ ck_assert_int_eq(noto, afb_apiset_timeout_get(a));
+ b = afb_apiset_addref(a);
+ ck_assert_ptr_eq(a, b);
+ afb_apiset_unref(b);
+ afb_apiset_unref(a);
+}
+END_TEST
+
+/*********************************************************************/
+/* check that NULL is a valid value for addref/unref */
+START_TEST (check_sanity)
+{
+ struct afb_apiset *a;
+
+ a = afb_apiset_addref(NULL);
+ ck_assert_ptr_null(a);
+ afb_apiset_unref(NULL);
+ ck_assert(1);
+}
+END_TEST
+
+/*********************************************************************/
+/* check creation and retrieval of apis */
+
+START_TEST (check_creation)
+{
+ int i, j, nn, na;
+ struct afb_apiset *a;
+ struct afb_api_item sa;
+ const char *x, *y, **set;
+ const struct afb_api_item *pa;
+
+ /* create a apiset */
+ a = afb_apiset_create(NULL, 0);
+ ck_assert_ptr_nonnull(a);
+
+ /* add apis */
+ for (i = 0 ; names[i] != NULL ; i++) {
+ sa.itf = &api_itf_null;
+ sa.closure = (void*)names[i];
+ sa.group = names[i];
+ ck_assert_int_eq(0, afb_apiset_add(a, names[i], sa));
+ pa = afb_apiset_lookup(a, names[i], 1);
+ ck_assert_ptr_nonnull(pa);
+ ck_assert_ptr_eq(sa.itf, pa->itf);
+ ck_assert_ptr_eq(sa.closure, pa->closure);
+ ck_assert_ptr_eq(sa.group, pa->group);
+ ck_assert_int_eq(0, afb_apiset_is_alias(a, names[i]));
+ ck_assert_str_eq(names[i], afb_apiset_unalias(a, names[i]));
+ ck_assert_int_eq(-1, afb_apiset_add(a, names[i], sa));
+ ck_assert_int_eq(errno, EEXIST);
+ }
+ nn = i;
+
+ /* add aliases */
+ for (i = 0 ; aliases[i] != NULL ; i += 2) {
+ ck_assert_int_eq(-1, afb_apiset_add_alias(a, extras[0], aliases[i]));
+ ck_assert_int_eq(errno, ENOENT);
+ ck_assert_int_eq(0, afb_apiset_add_alias(a, aliases[i + 1], aliases[i]));
+ ck_assert_ptr_nonnull(afb_apiset_lookup(a, aliases[i], 1));
+ ck_assert_int_eq(1, afb_apiset_is_alias(a, aliases[i]));
+ x = afb_apiset_unalias(a, aliases[i]);
+ y = afb_apiset_unalias(a, aliases[i + 1]);
+ ck_assert_int_eq(0, strcasecmp(x, y));
+ ck_assert_int_eq(-1, afb_apiset_add_alias(a, aliases[i + 1], aliases[i]));
+ ck_assert_int_eq(errno, EEXIST);
+ }
+ na = i / 2;
+
+ /* check extras */
+ for (i = 0 ; extras[i] != NULL ; i++) {
+ pa = afb_apiset_lookup(a, extras[i], 1);
+ ck_assert_ptr_null(pa);
+ ck_assert_int_eq(errno, ENOENT);
+ }
+
+ /* get the names */
+ set = afb_apiset_get_names(a, 0, 1);
+ ck_assert_ptr_nonnull(set);
+ for (i = 0 ; set[i] != NULL ; i++) {
+ ck_assert_ptr_nonnull(afb_apiset_lookup(a, set[i], 0));
+ ck_assert_int_eq(0, afb_apiset_is_alias(a, set[i]));
+ if (i)
+ ck_assert_int_gt(0, strcasecmp(set[i-1], set[i]));
+ }
+ ck_assert_int_eq(i, nn);
+ free(set);
+ set = afb_apiset_get_names(a, 0, 2);
+ ck_assert_ptr_nonnull(set);
+ for (i = 0 ; set[i] != NULL ; i++) {
+ ck_assert_ptr_nonnull(afb_apiset_lookup(a, set[i], 0));
+ ck_assert_int_eq(1, afb_apiset_is_alias(a, set[i]));
+ if (i)
+ ck_assert_int_gt(0, strcasecmp(set[i-1], set[i]));
+ }
+ ck_assert_int_eq(i, na);
+ free(set);
+ set = afb_apiset_get_names(a, 0, 3);
+ ck_assert_ptr_nonnull(set);
+ for (i = 0 ; set[i] != NULL ; i++) {
+ ck_assert_ptr_nonnull(afb_apiset_lookup(a, set[i], 0));
+ if (i)
+ ck_assert_int_gt(0, strcasecmp(set[i-1], set[i]));
+ }
+ ck_assert_int_eq(i, nn + na);
+
+ /* removes the apis to check deletion */
+ for (i = 0 ; i < nn + na ; i++) {
+ if (!set[i])
+ continue;
+
+ /* should be present */
+ ck_assert_ptr_nonnull(afb_apiset_lookup(a, set[i], 0));
+
+ /* deleting a non aliased api removes the aliases! */
+ if (!afb_apiset_is_alias(a, set[i])) {
+ for (j = i + 1 ; j < nn + na ; j++) {
+ if (!set[j])
+ continue;
+ ck_assert_ptr_nonnull(afb_apiset_lookup(a, set[j], 0));
+ if (afb_apiset_is_alias(a, set[j])
+ && afb_apiset_lookup(a, set[i], 0) == afb_apiset_lookup(a, set[j], 0)) {
+ ck_assert(set[j][0] > 0);
+ ((char*)set[j])[0] = (char)-set[j][0];
+ }
+ }
+ }
+
+ /* delete now */
+ ck_assert_int_eq(0, afb_apiset_del(a, set[i]));
+ ck_assert_ptr_null(afb_apiset_lookup(a, set[i], 0));
+
+ /* check other not removed except aliases */
+ for (j = i + 1 ; j < nn + na ; j++) {
+ if (!set[j])
+ continue;
+ if (set[j][0] > 0)
+ ck_assert_ptr_nonnull(afb_apiset_lookup(a, set[j], 0));
+ else {
+ ((char*)set[j])[0] = (char)-set[j][0];
+ ck_assert_ptr_null(afb_apiset_lookup(a, set[j], 0));
+ set[j] = NULL;
+ }
+ }
+ }
+ free(set);
+
+ afb_apiset_unref(a);
+}
+END_TEST
+
+/*********************************************************************/
+/* check onlack behaviour */
+
+int onlackcount;
+
+static void onlackcleanup(void *closure)
+{
+ int *count = closure;
+ ck_assert_ptr_eq(count, &onlackcount);
+ *count = 0;
+}
+static int onlack(void *closure, struct afb_apiset *a, const char *name)
+{
+ int *count = closure;
+ struct afb_api_item sa;
+
+ ck_assert_ptr_eq(count, &onlackcount);
+ (*count)++;
+
+ sa.itf = &api_itf_null;
+ sa.closure = (void*)name;
+ sa.group = name;
+
+ ck_assert_int_eq(0, afb_apiset_add(a, name, sa));
+ return 1;
+}
+
+START_TEST (check_onlack)
+{
+ int i;
+ struct afb_apiset *a;
+ struct afb_api_item sa;
+ const char *x, *y;
+ const struct afb_api_item *pa;
+
+ /* create a apiset */
+ a = afb_apiset_create(NULL, 0);
+ ck_assert_ptr_nonnull(a);
+
+ /* add apis */
+ for (i = 0 ; names[i] != NULL ; i++) {
+ sa.itf = &api_itf_null;
+ sa.closure = (void*)names[i];
+ sa.group = names[i];
+ ck_assert_int_eq(0, afb_apiset_add(a, names[i], sa));
+ pa = afb_apiset_lookup(a, names[i], 1);
+ ck_assert_ptr_nonnull(pa);
+ ck_assert_ptr_eq(sa.itf, pa->itf);
+ ck_assert_ptr_eq(sa.closure, pa->closure);
+ ck_assert_ptr_eq(sa.group, pa->group);
+ ck_assert_int_eq(0, afb_apiset_is_alias(a, names[i]));
+ ck_assert_str_eq(names[i], afb_apiset_unalias(a, names[i]));
+ ck_assert_int_eq(-1, afb_apiset_add(a, names[i], sa));
+ ck_assert_int_eq(errno, EEXIST);
+ }
+
+ /* add aliases */
+ for (i = 0 ; aliases[i] != NULL ; i += 2) {
+ ck_assert_int_eq(-1, afb_apiset_add_alias(a, extras[0], aliases[i]));
+ ck_assert_int_eq(errno, ENOENT);
+ ck_assert_int_eq(0, afb_apiset_add_alias(a, aliases[i + 1], aliases[i]));
+ ck_assert_ptr_nonnull(afb_apiset_lookup(a, aliases[i], 1));
+ ck_assert_int_eq(1, afb_apiset_is_alias(a, aliases[i]));
+ x = afb_apiset_unalias(a, aliases[i]);
+ y = afb_apiset_unalias(a, aliases[i + 1]);
+ ck_assert_int_eq(0, strcasecmp(x, y));
+ ck_assert_int_eq(-1, afb_apiset_add_alias(a, aliases[i + 1], aliases[i]));
+ ck_assert_int_eq(errno, EEXIST);
+ }
+
+ /* check extras */
+ for (i = 0 ; extras[i] != NULL ; i++) {
+ pa = afb_apiset_lookup(a, extras[i], 1);
+ ck_assert_ptr_null(pa);
+ ck_assert_int_eq(errno, ENOENT);
+ }
+
+ /* put the onlack feature */
+ afb_apiset_onlack_set(a, onlack, &onlackcount, onlackcleanup);
+
+ /* check extras */
+ onlackcount = 0;
+ for (i = 0 ; extras[i] != NULL ; i++) {
+ ck_assert_int_eq(onlackcount, i);
+ pa = afb_apiset_lookup(a, extras[i], 1);
+ ck_assert_int_eq(onlackcount, i + 1);
+ ck_assert_ptr_nonnull(pa);
+ ck_assert_ptr_eq(&api_itf_null, pa->itf);
+ ck_assert_ptr_eq(extras[i], pa->closure);
+ ck_assert_ptr_eq(extras[i], pa->group);
+ }
+
+ ck_assert_int_eq(onlackcount, i);
+ afb_apiset_unref(a);
+ ck_assert_int_eq(onlackcount, 0);
+}
+END_TEST
+
+/*********************************************************************/
+
+struct set_api {
+ const char *name;
+ int init;
+ int mask;
+} set_apis[] = {
+ { "Sadie", 0, 0 },
+ { "Milford", 0, 0 },
+ { "Yvette", 0, 0 },
+ { "Carma", 0, 0 },
+ { "Cory", 0, 0 },
+ { "Clarence", 0, 0 },
+ { "Jeffery", 0, 0 },
+ { "Molly", 0, 0 },
+ { "Sheba", 0, 0 },
+ { "Tasha", 0, 0 },
+ { "Corey", 0, 0 },
+ { "Gerry", 0, 0 },
+ { NULL, 0, 0 }
+};
+
+int set_count;
+struct set_api *set_last_api;
+
+void set_cb0(void *closure)
+{
+ set_last_api = closure;
+ set_count++;
+}
+
+void set_cb_setmask(void *closure, int mask)
+{
+ set_cb0(closure);
+ set_last_api->mask = mask;
+}
+
+int set_cb_getmask(void *closure)
+{
+ set_cb0(closure);
+ return set_last_api->mask;
+}
+
+int set_cb_start(void *closure, int share_session, int onneed)
+{
+ set_cb0(closure);
+ ck_assert_int_eq(0, set_last_api->init);
+ set_last_api->init = 1;
+ return 0;
+}
+
+struct afb_api_itf set_api_itf = {
+ .call = NULL,
+ .service_start = set_cb_start,
+ .update_hooks = set_cb0,
+ .get_logmask = set_cb_getmask,
+ .set_logmask = set_cb_setmask,
+ .describe = NULL,
+ .unref = set_cb0
+};
+
+START_TEST (check_settings)
+{
+ int i, nn, mask;
+ struct afb_apiset *a;
+ struct afb_api_item sa;
+
+ /* create a apiset */
+ a = afb_apiset_create(NULL, 0);
+ ck_assert_ptr_nonnull(a);
+
+ /* add apis */
+ for (i = 0 ; set_apis[i].name != NULL ; i++) {
+ sa.itf = &set_api_itf;
+ sa.closure = &set_apis[i];
+ sa.group = NULL;
+ ck_assert_int_eq(0, afb_apiset_add(a, set_apis[i].name, sa));
+ }
+ nn = i;
+
+ set_count = 0;
+ afb_apiset_start_all_services(a, 1);
+ ck_assert_int_eq(nn, set_count);
+
+ set_count = 0;
+ afb_apiset_update_hooks(a, NULL);
+ ck_assert_int_eq(nn, set_count);
+
+ for (mask = 1 ; !(mask >> 10) ; mask <<= 1) {
+ set_count = 0;
+ afb_apiset_set_logmask(a, NULL, mask);
+ ck_assert_int_eq(nn, set_count);
+ set_count = 0;
+ for (i = 0 ; set_apis[i].name != NULL ; i++) {
+ ck_assert_int_eq(mask, afb_apiset_get_logmask(a, set_apis[i].name));
+ ck_assert_ptr_eq(set_last_api, &set_apis[i]);
+ ck_assert_int_eq(i + 1, set_count);
+ }
+ }
+
+ set_count = 0;
+ afb_apiset_unref(a);
+ ck_assert_int_eq(nn, set_count);
+}
+END_TEST
+
+/*********************************************************************/
+
+struct clacl {
+ const char *name;
+ int count;
+} clacl[] = {
+ { "Sadie", 0 },
+ { "Milford", 0 },
+ { "Yvette", 0 },
+};
+
+struct clapi {
+ const char *name;
+ const char *provides;
+ const char *requires;
+ const char *apireq;
+ int init;
+ int expect;
+} clapi[] = {
+ { "Carma", "", "Sadie", "", 0, 9 },
+ { "Cory", "Milford", "", "Clarence", 0, 3 },
+ { "Clarence", "Milford", "", "Jeffery", 0, 2 },
+ { "Jeffery", "Milford", "", "", 0, 1 },
+ { "Molly", "Yvette", "", "Corey", 0, 6 },
+ { "Sheba", "Yvette", "Milford", "Molly", 0, 7 },
+ { "Tasha", "Sadie", "Yvette", "", 0, 8 },
+ { "Corey", "Sadie", "Milford", "Gerry", 0, 5 },
+ { "Gerry", "Sadie", "Milford", "", 0, 4 },
+ { NULL, NULL, NULL, NULL, 0, 0 }
+};
+
+int clorder;
+
+int clacb_start(void *closure, int share_session, int onneed)
+{
+ struct clapi *a = closure;
+ int i;
+
+ ck_assert_int_eq(0, a->init);
+
+ for (i = 0 ; clapi[i].name ; i++) {
+ if (a->requires && a->requires[0]
+ && clapi[i].provides && clapi[i].provides[0]
+ && !strcmp(a->requires, clapi[i].provides))
+ ck_assert_int_ne(0, clapi[i].init);
+ if (a->apireq && a->apireq[0]
+ && !strcmp(a->apireq, clapi[i].name))
+ ck_assert_int_ne(0, clapi[i].init);
+ }
+ a->init = ++clorder;
+ ck_assert_int_eq(a->init, a->expect);
+
+ return 0;
+}
+
+struct afb_api_itf clitf = {
+ .call = NULL,
+ .service_start = clacb_start,
+ .update_hooks = NULL,
+ .get_logmask = NULL,
+ .set_logmask = NULL,
+ .describe = NULL,
+ .unref = NULL
+};
+
+START_TEST (check_classes)
+{
+ int i;
+ struct afb_apiset *a;
+ struct afb_api_item sa;
+
+ /* create a apiset */
+ a = afb_apiset_create(NULL, 0);
+ ck_assert_ptr_nonnull(a);
+
+ /* add apis */
+ for (i = 0 ; clapi[i].name != NULL ; i++) {
+ sa.itf = &clitf;
+ sa.closure = &clapi[i];
+ sa.group = NULL;
+ ck_assert_int_eq(0, afb_apiset_add(a, clapi[i].name, sa));
+ }
+
+ /* add constraints */
+ for (i = 0 ; clapi[i].name != NULL ; i++) {
+ if (clapi[i].provides && clapi[i].provides[0])
+ ck_assert_int_eq(0, afb_apiset_provide_class(a, clapi[i].name, clapi[i].provides));
+ if (clapi[i].requires && clapi[i].requires[0])
+ ck_assert_int_eq(0, afb_apiset_require_class(a, clapi[i].name, clapi[i].requires));
+ if (clapi[i].apireq && clapi[i].apireq[0])
+ ck_assert_int_eq(0, afb_apiset_require(a, clapi[i].name, clapi[i].apireq));
+ }
+
+ /* start all */
+ ck_assert_int_eq(0, afb_apiset_start_all_services(a, 0));
+
+ afb_apiset_unref(a);
+}
+END_TEST
+
+/*********************************************************************/
+
+static Suite *suite;
+static TCase *tcase;
+
+void mksuite(const char *name) { suite = suite_create(name); }
+void addtcase(const char *name) { tcase = tcase_create(name); suite_add_tcase(suite, tcase); }
+void addtest(TFun fun) { tcase_add_test(tcase, fun); }
+int srun()
+{
+ int nerr;
+ SRunner *srunner = srunner_create(suite);
+ srunner_run_all(srunner, CK_NORMAL);
+ nerr = srunner_ntests_failed(srunner);
+ srunner_free(srunner);
+ return nerr;
+}
+
+int main(int ac, char **av)
+{
+ mksuite("apiset");
+ addtcase("apiset");
+ addtest(check_initialisation);
+ addtest(check_sanity);
+ addtest(check_creation);
+ addtest(check_onlack);
+ addtest(check_settings);
+ addtest(check_classes);
+ return !!srun();
+}