1 /* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2 /* util/profile/test_vtable.c - Test program for vtable-backed profiles */
3 /*
4 * Copyright (C) 2011 by the Massachusetts Institute of Technology.
5 * All rights reserved.
6 *
7 * Export of this software from the United States of America may
8 * require a specific license from the United States Government.
9 * It is the responsibility of any person or organization contemplating
10 * export to obtain such a license before exporting.
11 *
12 * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
13 * distribute this software and its documentation for any purpose and
14 * without fee is hereby granted, provided that the above copyright
15 * notice appear in all copies and that both that copyright notice and
16 * this permission notice appear in supporting documentation, and that
17 * the name of M.I.T. not be used in advertising or publicity pertaining
18 * to distribution of the software without specific, written prior
19 * permission. Furthermore if you modify this software you must label
20 * your software as modified software and not distribute it in such a
21 * fashion that it might be confused with the original M.I.T. software.
22 * M.I.T. makes no representations about the suitability of
23 * this software for any purpose. It is provided "as is" without express
24 * or implied warranty.
25 */
26
27 /*
28 * This test program exercises vtable profile functionality using two vtables,
29 * one which implements just the basic methods and one which implements all of
30 * the methods. The program doesn't attempt to create a working profile
31 * implementation; it just verifies the expected control flow into the vtable
32 * and back out to the caller.
33 */
34
35 #include <k5-platform.h>
36 #include "profile.h"
37
38 static int basic_cbdata;
39 static int full_cbdata;
40 static const char *empty_names[] = { NULL };
41 static const char *name_string = "get_string";
42 static const char *name_int = "get_int";
43 static const char *name_bool = "get_bool";
44
45 static long
basic_get_values(void * cbdata,const char * const * names,char *** ret_values)46 basic_get_values(void *cbdata, const char *const *names, char ***ret_values)
47 {
48 assert(cbdata == &basic_cbdata);
49 assert(names == empty_names);
50 *ret_values = calloc(3, sizeof(*ret_values));
51 (*ret_values)[0] = strdup("one");
52 (*ret_values)[1] = strdup("two");
53 (*ret_values)[2] = NULL;
54 return 0;
55 }
56
57 static void
free_values(void * cbdata,char ** values)58 free_values(void *cbdata, char **values)
59 {
60 char **v;
61
62 for (v = values; *v; v++)
63 free(*v);
64 free(values);
65 }
66
67 static long
full_get_values(void * cbdata,const char * const * names,char *** ret_values)68 full_get_values(void *cbdata, const char *const *names, char ***ret_values)
69 {
70 assert(cbdata == &full_cbdata);
71 *ret_values = calloc(2, sizeof(*ret_values));
72 if (names[0] == name_string)
73 (*ret_values)[0] = strdup("string result");
74 else if (names[0] == name_int)
75 (*ret_values)[0] = strdup("23");
76 else if (names[0] == name_bool)
77 (*ret_values)[0] = strdup("on");
78 else {
79 free(*ret_values);
80 return PROF_NO_RELATION;
81 }
82 (*ret_values)[1] = NULL;
83 return 0;
84 }
85
86 static void
full_cleanup(void * cbdata)87 full_cleanup(void *cbdata)
88 {
89 assert(cbdata == &full_cbdata);
90 }
91
92 static long
full_copy(void * cbdata,void ** ret_cbdata)93 full_copy(void *cbdata, void **ret_cbdata)
94 {
95 assert(cbdata == &full_cbdata);
96 *ret_cbdata = &full_cbdata;
97 return 0;
98 }
99
100 struct iterator {
101 int count;
102 };
103
104 static long
full_iterator_create(void * cbdata,const char * const * names,int flags,void ** ret_iter)105 full_iterator_create(void *cbdata, const char *const *names, int flags,
106 void **ret_iter)
107 {
108 struct iterator *iter;
109
110 assert(cbdata == &full_cbdata);
111 assert(names == empty_names);
112 assert(flags == 126);
113 iter = malloc(sizeof(*iter));
114 iter->count = 0;
115 *ret_iter = iter;
116 return 0;
117 }
118
119 static long
full_iterator(void * cbdata,void * iter_arg,char ** ret_name,char ** ret_value)120 full_iterator(void *cbdata, void *iter_arg, char **ret_name, char **ret_value)
121 {
122 struct iterator *iter = iter_arg;
123
124 assert(cbdata == &full_cbdata);
125 assert(iter->count >= 0 && iter->count <= 2);
126 if (iter->count == 0) {
127 *ret_name = strdup("name1");
128 *ret_value = strdup("value1");
129 } else if (iter->count == 1) {
130 *ret_name = strdup("name2");
131 *ret_value = NULL;
132 } else {
133 *ret_name = NULL;
134 *ret_value = NULL;
135 }
136 iter->count++;
137 return 0;
138 }
139
140 static void
full_iterator_free(void * cbdata,void * iter_arg)141 full_iterator_free(void *cbdata, void *iter_arg)
142 {
143 struct iterator *iter = iter_arg;
144
145 assert(cbdata == &full_cbdata);
146 assert(iter->count == 3);
147 free(iter);
148 }
149
150 static void
full_free_string(void * cbdata,char * string)151 full_free_string(void *cbdata, char *string)
152 {
153 assert(cbdata == &full_cbdata);
154 free(string);
155 }
156
157 static long
full_writable(void * cbdata,int * writable)158 full_writable(void *cbdata, int *writable)
159 {
160 assert(cbdata == &full_cbdata);
161 *writable = 12;
162 return 0;
163 }
164
165 static long
full_modified(void * cbdata,int * modified)166 full_modified(void *cbdata, int *modified)
167 {
168 assert(cbdata == &full_cbdata);
169 *modified = 6;
170 return 0;
171 }
172
173 static long
full_update_relation(void * cbdata,const char ** names,const char * old_value,const char * new_value)174 full_update_relation(void *cbdata, const char **names,
175 const char *old_value, const char *new_value)
176 {
177 assert(cbdata == &full_cbdata);
178 assert(names == empty_names);
179 assert(old_value == name_string || old_value == NULL);
180 assert(new_value == NULL);
181 return 0;
182 }
183
184 static long
full_rename_section(void * cbdata,const char ** names,const char * new_name)185 full_rename_section(void *cbdata, const char **names, const char *new_name)
186 {
187 assert(cbdata == &full_cbdata);
188 assert(names == empty_names);
189 assert(new_name == name_int);
190 return 0;
191 }
192
193 static long
full_add_relation(void * cbdata,const char ** names,const char * new_value)194 full_add_relation(void *cbdata, const char **names, const char *new_value)
195 {
196 assert(cbdata == &full_cbdata);
197 assert(names == empty_names);
198 assert(new_value == name_bool);
199 return 0;
200 }
201
202 static long
full_flush(void * cbdata)203 full_flush(void *cbdata)
204 {
205 assert(cbdata == &full_cbdata);
206 return 0;
207 }
208
209 struct profile_vtable basic_vtable = {
210 1,
211 basic_get_values,
212 free_values,
213 };
214
215 struct profile_vtable full_vtable = {
216 1,
217 full_get_values,
218 free_values,
219 full_cleanup,
220 full_copy,
221
222 full_iterator_create,
223 full_iterator,
224 full_iterator_free,
225 full_free_string,
226
227 full_writable,
228 full_modified,
229 full_update_relation,
230 full_rename_section,
231 full_add_relation,
232 full_flush
233 };
234
main()235 int main()
236 {
237 profile_t profile;
238 char **values, *str, *name, *value;
239 void *iter;
240 int intval;
241
242 assert(profile_init_vtable(&basic_vtable, &basic_cbdata, &profile) == 0);
243 assert(profile_get_values(profile, empty_names, &values) == 0);
244 assert(strcmp(values[0], "one") == 0);
245 assert(strcmp(values[1], "two") == 0);
246 assert(values[2] == NULL);
247 profile_free_list(values);
248 assert(profile_iterator_create(profile, NULL, 0, &iter) ==
249 PROF_UNSUPPORTED);
250 assert(profile_is_writable(profile, &intval) == 0);
251 assert(intval == 0);
252 assert(profile_is_modified(profile, &intval) == 0);
253 assert(intval == 0);
254 assert(profile_update_relation(profile, NULL, NULL, NULL) ==
255 PROF_UNSUPPORTED);
256 assert(profile_clear_relation(profile, NULL) == PROF_UNSUPPORTED);
257 assert(profile_rename_section(profile, NULL, NULL) == PROF_UNSUPPORTED);
258 assert(profile_add_relation(profile, NULL, NULL) == PROF_UNSUPPORTED);
259 profile_flush(profile);
260 profile_abandon(profile);
261
262 assert(profile_init_vtable(&full_vtable, &full_cbdata, &profile) == 0);
263 assert(profile_get_string(profile, name_string, NULL, NULL, "wrong",
264 &str) == 0);
265 assert(strcmp(str, "string result") == 0);
266 profile_release_string(str);
267 assert(profile_get_integer(profile, name_int, NULL, NULL, 24,
268 &intval) == 0);
269 assert(intval == 23);
270 assert(profile_get_boolean(profile, name_bool, NULL, NULL, 0,
271 &intval) == 0);
272 assert(intval == 1);
273 assert(profile_get_integer(profile, "xxx", NULL, NULL, 62, &intval) == 0);
274 assert(intval == 62);
275
276 assert(profile_iterator_create(profile, empty_names, 126, &iter) == 0);
277 assert(profile_iterator(&iter, &name, &value) == 0);
278 assert(strcmp(name, "name1") == 0);
279 assert(strcmp(value, "value1") == 0);
280 profile_release_string(name);
281 profile_release_string(value);
282 assert(profile_iterator(&iter, &name, &value) == 0);
283 assert(strcmp(name, "name2") == 0);
284 assert(value == NULL);
285 profile_release_string(name);
286 assert(profile_iterator(&iter, &name, &value) == 0);
287 assert(iter == NULL);
288 assert(name == NULL);
289 assert(value == NULL);
290
291 assert(profile_is_writable(profile, &intval) == 0);
292 assert(intval == 12);
293 assert(profile_is_modified(profile, &intval) == 0);
294 assert(intval == 6);
295 assert(profile_update_relation(profile, empty_names, name_string,
296 NULL) == 0);
297 assert(profile_clear_relation(profile, empty_names) == 0);
298 assert(profile_rename_section(profile, empty_names, name_int) == 0);
299 assert(profile_add_relation(profile, empty_names, name_bool) == 0);
300 profile_release(profile);
301
302 return 0;
303 }
304