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