afb-export: Fix requirement on multiple apis
[src/app-framework-binder.git] / src / tests / apiv3 / test-apiv3.c
1 #include <stdlib.h>
2 #include <stdio.h>
3 #include <stdarg.h>
4 #include <errno.h>
5 #include <string.h>
6
7 #include <check.h>
8
9 #if !defined(ck_assert_ptr_null)
10 # define ck_assert_ptr_null(X)      ck_assert_ptr_eq(X, NULL)
11 # define ck_assert_ptr_nonnull(X)   ck_assert_ptr_ne(X, NULL)
12 #endif
13
14 #define AFB_BINDING_VERSION 0
15 #include <afb/afb-binding.h>
16 #include "afb-api.h"
17 #include "afb-apiset.h"
18 #include "afb-api-v3.h"
19 #include "verbose.h"
20
21 struct inapis {
22         struct afb_binding_v3 desc;
23         struct afb_api_x3 *api;
24         int init;
25 };
26
27 struct inapis inapis[] = {
28         { .desc = {
29                 .api = "ezra",
30                 .provide_class = "e",
31                 .require_class = "c",
32                 .require_api = "armel"
33         }},
34         { .desc = {
35                 .api = "clara",
36                 .provide_class = "c",
37                 .require_class = "a"
38         }},
39         { .desc = {
40                 .api = "amelie",
41                 .provide_class = "a",
42                 .require_api = "albert armel"
43         }},
44         { .desc = {
45                 .api = "chloe",
46                 .provide_class = "c a"
47         }},
48         { .desc = {
49                 .api = "albert",
50                 .provide_class = "a"
51         }},
52         { .desc = {
53                 .api = "armel",
54                 .provide_class = "a",
55                 .require_api = "albert"
56         }},
57         { .desc = { .api = NULL }}
58 };
59
60 int last_in_init;
61
62 int in_init(struct afb_api_x3 *api)
63 {
64         struct inapis *desc = api->userdata;
65
66         ck_assert_str_eq(api->apiname, desc->desc.api);
67         ck_assert_int_eq(desc->init, 0);
68
69         desc->init = ++last_in_init;
70         printf("init %d of %s\n", desc->init, api->apiname);
71         return 0;
72 }
73
74 int in_preinit(void *closure, struct afb_api_x3 *api)
75 {
76         int rc;
77         struct inapis *desc = closure;
78
79         printf("default preinit of %s\n", api->apiname);
80
81         ck_assert_ptr_nonnull(api);
82         ck_assert_ptr_nonnull(desc);
83         ck_assert_ptr_nonnull(api->apiname);
84         ck_assert_ptr_null(api->userdata);
85         ck_assert_str_eq(api->apiname, desc->desc.api);
86         ck_assert_ptr_null(desc->api);
87         ck_assert_int_eq(desc->init, 0);
88
89         rc = afb_api_v3_set_binding_fields(&desc->desc, api);
90         ck_assert_int_eq(rc, 0);
91
92         api->userdata = desc;
93         desc->api = api;
94
95         if (desc->desc.preinit)
96                 desc->desc.preinit(api);
97
98         if (!desc->desc.init) {
99                 rc =  afb_api_x3_on_init(api, in_init);
100                 ck_assert_int_eq(rc, 0);
101         }
102
103         return 0;
104 }
105
106 int out_init(struct afb_api_x3 *api)
107 {
108         return 0;
109 }
110
111 struct afb_apiset *apiset;
112 char out_apiname[] = "out";
113 struct afb_api_v3 *out_v3;
114 struct afb_api_x3 *out_api;
115
116 int out_preinit(void *closure, struct afb_api_x3 *api)
117 {
118         int i;
119         int rc;
120         struct afb_api_x3 *napi;
121
122         ck_assert_ptr_nonnull(api);
123         ck_assert_ptr_eq(closure, out_apiname);
124         ck_assert_ptr_null(api->userdata);
125         ck_assert_str_eq(api->apiname, out_apiname);
126         out_api = api;
127
128         for (i = 0 ; inapis[i].desc.api ; i++) {
129                 ck_assert_ptr_null(inapis[i].api);
130                 napi = afb_api_x3_new_api(
131                                 api,
132                                 inapis[i].desc.api,
133                                 NULL,
134                                 0,
135                                 in_preinit,
136                                 &inapis[i]);
137                 ck_assert_ptr_nonnull(napi);
138                 ck_assert_ptr_nonnull(inapis[i].api);
139                 ck_assert_ptr_eq(inapis[i].api, napi);
140         }
141
142         rc = afb_api_x3_on_init(api, out_init);
143         ck_assert_int_eq(rc, 0);
144
145         return 0;
146 }
147
148 START_TEST (test)
149 {
150         int rc;
151
152         verbosity_set(-1);
153         apiset = afb_apiset_create("test-apiv3", 1);
154         ck_assert_ptr_nonnull(apiset);
155
156         out_v3 = afb_api_v3_create(
157                         apiset,
158                         apiset,
159                         out_apiname,
160                         NULL,
161                         0,
162                         out_preinit,
163                         out_apiname,
164                         0,
165                         NULL,
166                         NULL);
167         ck_assert_ptr_nonnull(out_v3);
168         ck_assert_ptr_nonnull(out_api);
169
170         /* start all services */
171         rc = afb_apiset_start_all_services(apiset);
172         ck_assert_int_eq(rc, 0);
173 }
174 END_TEST
175
176
177 /*********************************************************************/
178
179 static Suite *suite;
180 static TCase *tcase;
181
182 void mksuite(const char *name) { suite = suite_create(name); }
183 void addtcase(const char *name) { tcase = tcase_create(name); suite_add_tcase(suite, tcase); }
184 void addtest(TFun fun) { tcase_add_test(tcase, fun); }
185 int srun()
186 {
187         int nerr;
188         SRunner *srunner = srunner_create(suite);
189         srunner_run_all(srunner, CK_NORMAL);
190         nerr = srunner_ntests_failed(srunner);
191         srunner_free(srunner);
192         return nerr;
193 }
194
195 int main(int ac, char **av)
196 {
197         mksuite("apiv3");
198                 addtcase("apiv3");
199                         addtest(test);
200         return !!srun();
201 }