|
|
1.1 ! root 1: /* ! 2: * QMP Input Visitor unit-tests (strict mode). ! 3: * ! 4: * Copyright (C) 2011-2012 Red Hat Inc. ! 5: * ! 6: * Authors: ! 7: * Luiz Capitulino <[email protected]> ! 8: * Paolo Bonzini <[email protected]> ! 9: * ! 10: * This work is licensed under the terms of the GNU GPL, version 2 or later. ! 11: * See the COPYING file in the top-level directory. ! 12: */ ! 13: ! 14: #include <glib.h> ! 15: #include <stdarg.h> ! 16: ! 17: #include "qapi/qmp-input-visitor.h" ! 18: #include "test-qapi-types.h" ! 19: #include "test-qapi-visit.h" ! 20: #include "qemu-objects.h" ! 21: ! 22: typedef struct TestInputVisitorData { ! 23: QObject *obj; ! 24: QmpInputVisitor *qiv; ! 25: } TestInputVisitorData; ! 26: ! 27: static void validate_teardown(TestInputVisitorData *data, ! 28: const void *unused) ! 29: { ! 30: qobject_decref(data->obj); ! 31: data->obj = NULL; ! 32: ! 33: if (data->qiv) { ! 34: qmp_input_visitor_cleanup(data->qiv); ! 35: data->qiv = NULL; ! 36: } ! 37: } ! 38: ! 39: /* This is provided instead of a test setup function so that the JSON ! 40: string used by the tests are kept in the test functions (and not ! 41: int main()) */ ! 42: static GCC_FMT_ATTR(2, 3) ! 43: Visitor *validate_test_init(TestInputVisitorData *data, ! 44: const char *json_string, ...) ! 45: { ! 46: Visitor *v; ! 47: va_list ap; ! 48: ! 49: va_start(ap, json_string); ! 50: data->obj = qobject_from_jsonv(json_string, &ap); ! 51: va_end(ap); ! 52: ! 53: g_assert(data->obj != NULL); ! 54: ! 55: data->qiv = qmp_input_visitor_new_strict(data->obj); ! 56: g_assert(data->qiv != NULL); ! 57: ! 58: v = qmp_input_get_visitor(data->qiv); ! 59: g_assert(v != NULL); ! 60: ! 61: return v; ! 62: } ! 63: ! 64: typedef struct TestStruct ! 65: { ! 66: int64_t integer; ! 67: bool boolean; ! 68: char *string; ! 69: } TestStruct; ! 70: ! 71: static void visit_type_TestStruct(Visitor *v, TestStruct **obj, ! 72: const char *name, Error **errp) ! 73: { ! 74: visit_start_struct(v, (void **)obj, "TestStruct", name, sizeof(TestStruct), ! 75: errp); ! 76: ! 77: visit_type_int(v, &(*obj)->integer, "integer", errp); ! 78: visit_type_bool(v, &(*obj)->boolean, "boolean", errp); ! 79: visit_type_str(v, &(*obj)->string, "string", errp); ! 80: ! 81: visit_end_struct(v, errp); ! 82: } ! 83: ! 84: static void test_validate_struct(TestInputVisitorData *data, ! 85: const void *unused) ! 86: { ! 87: TestStruct *p = NULL; ! 88: Error *errp = NULL; ! 89: Visitor *v; ! 90: ! 91: v = validate_test_init(data, "{ 'integer': -42, 'boolean': true, 'string': 'foo' }"); ! 92: ! 93: visit_type_TestStruct(v, &p, NULL, &errp); ! 94: g_assert(!error_is_set(&errp)); ! 95: g_free(p->string); ! 96: g_free(p); ! 97: } ! 98: ! 99: static void test_validate_struct_nested(TestInputVisitorData *data, ! 100: const void *unused) ! 101: { ! 102: UserDefNested *udp = NULL; ! 103: Error *errp = NULL; ! 104: Visitor *v; ! 105: ! 106: v = validate_test_init(data, "{ 'string0': 'string0', 'dict1': { 'string1': 'string1', 'dict2': { 'userdef1': { 'integer': 42, 'string': 'string' }, 'string2': 'string2'}}}"); ! 107: ! 108: visit_type_UserDefNested(v, &udp, NULL, &errp); ! 109: g_assert(!error_is_set(&errp)); ! 110: qapi_free_UserDefNested(udp); ! 111: } ! 112: ! 113: static void test_validate_list(TestInputVisitorData *data, ! 114: const void *unused) ! 115: { ! 116: UserDefOneList *head = NULL; ! 117: Error *errp = NULL; ! 118: Visitor *v; ! 119: ! 120: v = validate_test_init(data, "[ { 'string': 'string0', 'integer': 42 }, { 'string': 'string1', 'integer': 43 }, { 'string': 'string2', 'integer': 44 } ]"); ! 121: ! 122: visit_type_UserDefOneList(v, &head, NULL, &errp); ! 123: g_assert(!error_is_set(&errp)); ! 124: qapi_free_UserDefOneList(head); ! 125: } ! 126: ! 127: static void test_validate_union(TestInputVisitorData *data, ! 128: const void *unused) ! 129: { ! 130: UserDefUnion *tmp = NULL; ! 131: Visitor *v; ! 132: Error *errp = NULL; ! 133: ! 134: v = validate_test_init(data, "{ 'type': 'b', 'data' : { 'integer': 42 } }"); ! 135: ! 136: visit_type_UserDefUnion(v, &tmp, NULL, &errp); ! 137: g_assert(!error_is_set(&errp)); ! 138: qapi_free_UserDefUnion(tmp); ! 139: } ! 140: ! 141: static void test_validate_fail_struct(TestInputVisitorData *data, ! 142: const void *unused) ! 143: { ! 144: TestStruct *p = NULL; ! 145: Error *errp = NULL; ! 146: Visitor *v; ! 147: ! 148: v = validate_test_init(data, "{ 'integer': -42, 'boolean': true, 'string': 'foo', 'extra': 42 }"); ! 149: ! 150: visit_type_TestStruct(v, &p, NULL, &errp); ! 151: g_assert(error_is_set(&errp)); ! 152: if (p) { ! 153: g_free(p->string); ! 154: } ! 155: g_free(p); ! 156: } ! 157: ! 158: static void test_validate_fail_struct_nested(TestInputVisitorData *data, ! 159: const void *unused) ! 160: { ! 161: UserDefNested *udp = NULL; ! 162: Error *errp = NULL; ! 163: Visitor *v; ! 164: ! 165: v = validate_test_init(data, "{ 'string0': 'string0', 'dict1': { 'string1': 'string1', 'dict2': { 'userdef1': { 'integer': 42, 'string': 'string', 'extra': [42, 23, {'foo':'bar'}] }, 'string2': 'string2'}}}"); ! 166: ! 167: visit_type_UserDefNested(v, &udp, NULL, &errp); ! 168: g_assert(error_is_set(&errp)); ! 169: qapi_free_UserDefNested(udp); ! 170: } ! 171: ! 172: static void test_validate_fail_list(TestInputVisitorData *data, ! 173: const void *unused) ! 174: { ! 175: UserDefOneList *head = NULL; ! 176: Error *errp = NULL; ! 177: Visitor *v; ! 178: ! 179: v = validate_test_init(data, "[ { 'string': 'string0', 'integer': 42 }, { 'string': 'string1', 'integer': 43 }, { 'string': 'string2', 'integer': 44, 'extra': 'ggg' } ]"); ! 180: ! 181: visit_type_UserDefOneList(v, &head, NULL, &errp); ! 182: g_assert(error_is_set(&errp)); ! 183: qapi_free_UserDefOneList(head); ! 184: } ! 185: ! 186: static void test_validate_fail_union(TestInputVisitorData *data, ! 187: const void *unused) ! 188: { ! 189: UserDefUnion *tmp = NULL; ! 190: Error *errp = NULL; ! 191: Visitor *v; ! 192: ! 193: v = validate_test_init(data, "{ 'type': 'b', 'data' : { 'integer': 42 }, 'extra': 'yyy' }"); ! 194: ! 195: visit_type_UserDefUnion(v, &tmp, NULL, &errp); ! 196: g_assert(error_is_set(&errp)); ! 197: qapi_free_UserDefUnion(tmp); ! 198: } ! 199: ! 200: static void validate_test_add(const char *testpath, ! 201: TestInputVisitorData *data, ! 202: void (*test_func)(TestInputVisitorData *data, const void *user_data)) ! 203: { ! 204: g_test_add(testpath, TestInputVisitorData, data, NULL, test_func, ! 205: validate_teardown); ! 206: } ! 207: ! 208: int main(int argc, char **argv) ! 209: { ! 210: TestInputVisitorData testdata; ! 211: ! 212: g_test_init(&argc, &argv, NULL); ! 213: ! 214: validate_test_add("/visitor/input-strict/pass/struct", ! 215: &testdata, test_validate_struct); ! 216: validate_test_add("/visitor/input-strict/pass/struct-nested", ! 217: &testdata, test_validate_struct_nested); ! 218: validate_test_add("/visitor/input-strict/pass/list", ! 219: &testdata, test_validate_list); ! 220: validate_test_add("/visitor/input-strict/pass/union", ! 221: &testdata, test_validate_union); ! 222: validate_test_add("/visitor/input-strict/fail/struct", ! 223: &testdata, test_validate_fail_struct); ! 224: validate_test_add("/visitor/input-strict/fail/struct-nested", ! 225: &testdata, test_validate_fail_struct_nested); ! 226: validate_test_add("/visitor/input-strict/fail/list", ! 227: &testdata, test_validate_fail_list); ! 228: validate_test_add("/visitor/input-strict/fail/union", ! 229: &testdata, test_validate_fail_union); ! 230: ! 231: g_test_run(); ! 232: ! 233: return 0; ! 234: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.