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 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 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 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 87 full_cleanup(void *cbdata) 88 { 89 assert(cbdata == &full_cbdata); 90 } 91 92 static long 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 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 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 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 151 full_free_string(void *cbdata, char *string) 152 { 153 assert(cbdata == &full_cbdata); 154 free(string); 155 } 156 157 static long 158 full_writable(void *cbdata, int *writable) 159 { 160 assert(cbdata == &full_cbdata); 161 *writable = 12; 162 return 0; 163 } 164 165 static long 166 full_modified(void *cbdata, int *modified) 167 { 168 assert(cbdata == &full_cbdata); 169 *modified = 6; 170 return 0; 171 } 172 173 static long 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 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 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 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 235 int 236 main(void) 237 { 238 profile_t profile; 239 char **values, *str, *name, *value; 240 void *iter; 241 int intval; 242 243 assert(profile_init_vtable(&basic_vtable, &basic_cbdata, &profile) == 0); 244 assert(profile_get_values(profile, empty_names, &values) == 0); 245 assert(strcmp(values[0], "one") == 0); 246 assert(strcmp(values[1], "two") == 0); 247 assert(values[2] == NULL); 248 profile_free_list(values); 249 assert(profile_iterator_create(profile, NULL, 0, &iter) == 250 PROF_UNSUPPORTED); 251 assert(profile_is_writable(profile, &intval) == 0); 252 assert(intval == 0); 253 assert(profile_is_modified(profile, &intval) == 0); 254 assert(intval == 0); 255 assert(profile_update_relation(profile, NULL, NULL, NULL) == 256 PROF_UNSUPPORTED); 257 assert(profile_clear_relation(profile, NULL) == PROF_UNSUPPORTED); 258 assert(profile_rename_section(profile, NULL, NULL) == PROF_UNSUPPORTED); 259 assert(profile_add_relation(profile, NULL, NULL) == PROF_UNSUPPORTED); 260 profile_flush(profile); 261 profile_abandon(profile); 262 263 assert(profile_init_vtable(&full_vtable, &full_cbdata, &profile) == 0); 264 assert(profile_get_string(profile, name_string, NULL, NULL, "wrong", 265 &str) == 0); 266 assert(strcmp(str, "string result") == 0); 267 profile_release_string(str); 268 assert(profile_get_integer(profile, name_int, NULL, NULL, 24, 269 &intval) == 0); 270 assert(intval == 23); 271 assert(profile_get_boolean(profile, name_bool, NULL, NULL, 0, 272 &intval) == 0); 273 assert(intval == 1); 274 assert(profile_get_integer(profile, "xxx", NULL, NULL, 62, &intval) == 0); 275 assert(intval == 62); 276 277 assert(profile_iterator_create(profile, empty_names, 126, &iter) == 0); 278 assert(profile_iterator(&iter, &name, &value) == 0); 279 assert(strcmp(name, "name1") == 0); 280 assert(strcmp(value, "value1") == 0); 281 profile_release_string(name); 282 profile_release_string(value); 283 assert(profile_iterator(&iter, &name, &value) == 0); 284 assert(strcmp(name, "name2") == 0); 285 assert(value == NULL); 286 profile_release_string(name); 287 assert(profile_iterator(&iter, &name, &value) == 0); 288 assert(iter == NULL); 289 assert(name == NULL); 290 assert(value == NULL); 291 292 assert(profile_is_writable(profile, &intval) == 0); 293 assert(intval == 12); 294 assert(profile_is_modified(profile, &intval) == 0); 295 assert(intval == 6); 296 assert(profile_update_relation(profile, empty_names, name_string, 297 NULL) == 0); 298 assert(profile_clear_relation(profile, empty_names) == 0); 299 assert(profile_rename_section(profile, empty_names, name_int) == 0); 300 assert(profile_add_relation(profile, empty_names, name_bool) == 0); 301 profile_release(profile); 302 303 return 0; 304 } 305