Annotation of qemu/tests/test-qmp-output-visitor.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * QMP Output Visitor unit-tests.
        !             3:  *
        !             4:  * Copyright (C) 2011 Red Hat Inc.
        !             5:  *
        !             6:  * Authors:
        !             7:  *  Luiz Capitulino <[email protected]>
        !             8:  *
        !             9:  * This work is licensed under the terms of the GNU GPL, version 2 or later.
        !            10:  * See the COPYING file in the top-level directory.
        !            11:  */
        !            12: 
        !            13: #include <glib.h>
        !            14: 
        !            15: #include "qapi/qmp-output-visitor.h"
        !            16: #include "test-qapi-types.h"
        !            17: #include "test-qapi-visit.h"
        !            18: #include "qemu-objects.h"
        !            19: 
        !            20: typedef struct TestOutputVisitorData {
        !            21:     QmpOutputVisitor *qov;
        !            22:     Visitor *ov;
        !            23: } TestOutputVisitorData;
        !            24: 
        !            25: static void visitor_output_setup(TestOutputVisitorData *data,
        !            26:                                  const void *unused)
        !            27: {
        !            28:     data->qov = qmp_output_visitor_new();
        !            29:     g_assert(data->qov != NULL);
        !            30: 
        !            31:     data->ov = qmp_output_get_visitor(data->qov);
        !            32:     g_assert(data->ov != NULL);
        !            33: }
        !            34: 
        !            35: static void visitor_output_teardown(TestOutputVisitorData *data,
        !            36:                                     const void *unused)
        !            37: {
        !            38:     qmp_output_visitor_cleanup(data->qov);
        !            39:     data->qov = NULL;
        !            40:     data->ov = NULL;
        !            41: }
        !            42: 
        !            43: static void test_visitor_out_int(TestOutputVisitorData *data,
        !            44:                                  const void *unused)
        !            45: {
        !            46:     int64_t value = -42;
        !            47:     Error *errp = NULL;
        !            48:     QObject *obj;
        !            49: 
        !            50:     visit_type_int(data->ov, &value, NULL, &errp);
        !            51:     g_assert(error_is_set(&errp) == 0);
        !            52: 
        !            53:     obj = qmp_output_get_qobject(data->qov);
        !            54:     g_assert(obj != NULL);
        !            55:     g_assert(qobject_type(obj) == QTYPE_QINT);
        !            56:     g_assert_cmpint(qint_get_int(qobject_to_qint(obj)), ==, value);
        !            57: 
        !            58:     qobject_decref(obj);
        !            59: }
        !            60: 
        !            61: static void test_visitor_out_bool(TestOutputVisitorData *data,
        !            62:                                   const void *unused)
        !            63: {
        !            64:     Error *errp = NULL;
        !            65:     bool value = true;
        !            66:     QObject *obj;
        !            67: 
        !            68:     visit_type_bool(data->ov, &value, NULL, &errp);
        !            69:     g_assert(error_is_set(&errp) == 0);
        !            70: 
        !            71:     obj = qmp_output_get_qobject(data->qov);
        !            72:     g_assert(obj != NULL);
        !            73:     g_assert(qobject_type(obj) == QTYPE_QBOOL);
        !            74:     g_assert(qbool_get_int(qobject_to_qbool(obj)) == value);
        !            75: 
        !            76:     qobject_decref(obj);
        !            77: }
        !            78: 
        !            79: static void test_visitor_out_number(TestOutputVisitorData *data,
        !            80:                                     const void *unused)
        !            81: {
        !            82:     double value = 3.14;
        !            83:     Error *errp = NULL;
        !            84:     QObject *obj;
        !            85: 
        !            86:     visit_type_number(data->ov, &value, NULL, &errp);
        !            87:     g_assert(error_is_set(&errp) == 0);
        !            88: 
        !            89:     obj = qmp_output_get_qobject(data->qov);
        !            90:     g_assert(obj != NULL);
        !            91:     g_assert(qobject_type(obj) == QTYPE_QFLOAT);
        !            92:     g_assert(qfloat_get_double(qobject_to_qfloat(obj)) == value);
        !            93: 
        !            94:     qobject_decref(obj);
        !            95: }
        !            96: 
        !            97: static void test_visitor_out_string(TestOutputVisitorData *data,
        !            98:                                     const void *unused)
        !            99: {
        !           100:     char *string = (char *) "Q E M U";
        !           101:     Error *errp = NULL;
        !           102:     QObject *obj;
        !           103: 
        !           104:     visit_type_str(data->ov, &string, NULL, &errp);
        !           105:     g_assert(error_is_set(&errp) == 0);
        !           106: 
        !           107:     obj = qmp_output_get_qobject(data->qov);
        !           108:     g_assert(obj != NULL);
        !           109:     g_assert(qobject_type(obj) == QTYPE_QSTRING);
        !           110:     g_assert_cmpstr(qstring_get_str(qobject_to_qstring(obj)), ==, string);
        !           111: 
        !           112:     qobject_decref(obj);
        !           113: }
        !           114: 
        !           115: static void test_visitor_out_no_string(TestOutputVisitorData *data,
        !           116:                                        const void *unused)
        !           117: {
        !           118:     char *string = NULL;
        !           119:     Error *errp = NULL;
        !           120:     QObject *obj;
        !           121: 
        !           122:     /* A null string should return "" */
        !           123:     visit_type_str(data->ov, &string, NULL, &errp);
        !           124:     g_assert(error_is_set(&errp) == 0);
        !           125: 
        !           126:     obj = qmp_output_get_qobject(data->qov);
        !           127:     g_assert(obj != NULL);
        !           128:     g_assert(qobject_type(obj) == QTYPE_QSTRING);
        !           129:     g_assert_cmpstr(qstring_get_str(qobject_to_qstring(obj)), ==, "");
        !           130: 
        !           131:     qobject_decref(obj);
        !           132: }
        !           133: 
        !           134: static void test_visitor_out_enum(TestOutputVisitorData *data,
        !           135:                                   const void *unused)
        !           136: {
        !           137:     Error *errp = NULL;
        !           138:     QObject *obj;
        !           139:     EnumOne i;
        !           140: 
        !           141:     for (i = 0; i < ENUM_ONE_MAX; i++) {
        !           142:         visit_type_EnumOne(data->ov, &i, "unused", &errp);
        !           143:         g_assert(!error_is_set(&errp));
        !           144: 
        !           145:         obj = qmp_output_get_qobject(data->qov);
        !           146:         g_assert(obj != NULL);
        !           147:         g_assert(qobject_type(obj) == QTYPE_QSTRING);
        !           148:         g_assert_cmpstr(qstring_get_str(qobject_to_qstring(obj)), ==,
        !           149:                         EnumOne_lookup[i]);
        !           150:         qobject_decref(obj);
        !           151:     }
        !           152: }
        !           153: 
        !           154: static void test_visitor_out_enum_errors(TestOutputVisitorData *data,
        !           155:                                          const void *unused)
        !           156: {
        !           157:     EnumOne i, bad_values[] = { ENUM_ONE_MAX, -1 };
        !           158:     Error *errp;
        !           159: 
        !           160:     for (i = 0; i < ARRAY_SIZE(bad_values) ; i++) {
        !           161:         errp = NULL;
        !           162:         visit_type_EnumOne(data->ov, &bad_values[i], "unused", &errp);
        !           163:         g_assert(error_is_set(&errp) == true);
        !           164:         error_free(errp);
        !           165:     }
        !           166: }
        !           167: 
        !           168: typedef struct TestStruct
        !           169: {
        !           170:     int64_t integer;
        !           171:     bool boolean;
        !           172:     char *string;
        !           173: } TestStruct;
        !           174: 
        !           175: static void visit_type_TestStruct(Visitor *v, TestStruct **obj,
        !           176:                                   const char *name, Error **errp)
        !           177: {
        !           178:     visit_start_struct(v, (void **)obj, "TestStruct", name, sizeof(TestStruct),
        !           179:                        errp);
        !           180: 
        !           181:     visit_type_int(v, &(*obj)->integer, "integer", errp);
        !           182:     visit_type_bool(v, &(*obj)->boolean, "boolean", errp);
        !           183:     visit_type_str(v, &(*obj)->string, "string", errp);
        !           184: 
        !           185:     visit_end_struct(v, errp);
        !           186: }
        !           187: 
        !           188: static void test_visitor_out_struct(TestOutputVisitorData *data,
        !           189:                                     const void *unused)
        !           190: {
        !           191:     TestStruct test_struct = { .integer = 42,
        !           192:                                .boolean = false,
        !           193:                                .string = (char *) "foo"};
        !           194:     TestStruct *p = &test_struct;
        !           195:     Error *errp = NULL;
        !           196:     QObject *obj;
        !           197:     QDict *qdict;
        !           198: 
        !           199:     visit_type_TestStruct(data->ov, &p, NULL, &errp);
        !           200:     g_assert(!error_is_set(&errp));
        !           201: 
        !           202:     obj = qmp_output_get_qobject(data->qov);
        !           203:     g_assert(obj != NULL);
        !           204:     g_assert(qobject_type(obj) == QTYPE_QDICT);
        !           205: 
        !           206:     qdict = qobject_to_qdict(obj);
        !           207:     g_assert_cmpint(qdict_size(qdict), ==, 3);
        !           208:     g_assert_cmpint(qdict_get_int(qdict, "integer"), ==, 42);
        !           209:     g_assert_cmpint(qdict_get_bool(qdict, "boolean"), ==, 0);
        !           210:     g_assert_cmpstr(qdict_get_str(qdict, "string"), ==, "foo");
        !           211: 
        !           212:     QDECREF(qdict);
        !           213: }
        !           214: 
        !           215: static void test_visitor_out_struct_nested(TestOutputVisitorData *data,
        !           216:                                            const void *unused)
        !           217: {
        !           218:     int64_t value = 42;
        !           219:     Error *errp = NULL;
        !           220:     UserDefNested *ud2;
        !           221:     QObject *obj;
        !           222:     QDict *qdict, *dict1, *dict2, *dict3, *userdef;
        !           223:     const char *string = "user def string";
        !           224:     const char *strings[] = { "forty two", "forty three", "forty four",
        !           225:                               "forty five" };
        !           226: 
        !           227:     ud2 = g_malloc0(sizeof(*ud2));
        !           228:     ud2->string0 = g_strdup(strings[0]);
        !           229: 
        !           230:     ud2->dict1.string1 = g_strdup(strings[1]);
        !           231:     ud2->dict1.dict2.userdef1 = g_malloc0(sizeof(UserDefOne));
        !           232:     ud2->dict1.dict2.userdef1->string = g_strdup(string);
        !           233:     ud2->dict1.dict2.userdef1->integer = value;
        !           234:     ud2->dict1.dict2.string2 = g_strdup(strings[2]);
        !           235: 
        !           236:     ud2->dict1.has_dict3 = true;
        !           237:     ud2->dict1.dict3.userdef2 = g_malloc0(sizeof(UserDefOne));
        !           238:     ud2->dict1.dict3.userdef2->string = g_strdup(string);
        !           239:     ud2->dict1.dict3.userdef2->integer = value;
        !           240:     ud2->dict1.dict3.string3 = g_strdup(strings[3]);
        !           241: 
        !           242:     visit_type_UserDefNested(data->ov, &ud2, "unused", &errp);
        !           243:     g_assert(!error_is_set(&errp));
        !           244: 
        !           245:     obj = qmp_output_get_qobject(data->qov);
        !           246:     g_assert(obj != NULL);
        !           247:     g_assert(qobject_type(obj) == QTYPE_QDICT);
        !           248: 
        !           249:     qdict = qobject_to_qdict(obj);
        !           250:     g_assert_cmpint(qdict_size(qdict), ==, 2);
        !           251:     g_assert_cmpstr(qdict_get_str(qdict, "string0"), ==, strings[0]);
        !           252: 
        !           253:     dict1 = qdict_get_qdict(qdict, "dict1");
        !           254:     g_assert_cmpint(qdict_size(dict1), ==, 3);
        !           255:     g_assert_cmpstr(qdict_get_str(dict1, "string1"), ==, strings[1]);
        !           256: 
        !           257:     dict2 = qdict_get_qdict(dict1, "dict2");
        !           258:     g_assert_cmpint(qdict_size(dict2), ==, 2);
        !           259:     g_assert_cmpstr(qdict_get_str(dict2, "string2"), ==, strings[2]);
        !           260:     userdef = qdict_get_qdict(dict2, "userdef1");
        !           261:     g_assert_cmpint(qdict_size(userdef), ==, 2);
        !           262:     g_assert_cmpint(qdict_get_int(userdef, "integer"), ==, value);
        !           263:     g_assert_cmpstr(qdict_get_str(userdef, "string"), ==, string);
        !           264: 
        !           265:     dict3 = qdict_get_qdict(dict1, "dict3");
        !           266:     g_assert_cmpint(qdict_size(dict3), ==, 2);
        !           267:     g_assert_cmpstr(qdict_get_str(dict3, "string3"), ==, strings[3]);
        !           268:     userdef = qdict_get_qdict(dict3, "userdef2");
        !           269:     g_assert_cmpint(qdict_size(userdef), ==, 2);
        !           270:     g_assert_cmpint(qdict_get_int(userdef, "integer"), ==, value);
        !           271:     g_assert_cmpstr(qdict_get_str(userdef, "string"), ==, string);
        !           272: 
        !           273:     QDECREF(qdict);
        !           274:     qapi_free_UserDefNested(ud2);
        !           275: }
        !           276: 
        !           277: static void test_visitor_out_struct_errors(TestOutputVisitorData *data,
        !           278:                                            const void *unused)
        !           279: {
        !           280:     EnumOne bad_values[] = { ENUM_ONE_MAX, -1 };
        !           281:     UserDefOne u = { 0 }, *pu = &u;
        !           282:     Error *errp;
        !           283:     int i;
        !           284: 
        !           285:     for (i = 0; i < ARRAY_SIZE(bad_values) ; i++) {
        !           286:         errp = NULL;
        !           287:         u.has_enum1 = true;
        !           288:         u.enum1 = bad_values[i];
        !           289:         visit_type_UserDefOne(data->ov, &pu, "unused", &errp);
        !           290:         g_assert(error_is_set(&errp) == true);
        !           291:         error_free(errp);
        !           292:     }
        !           293: }
        !           294: 
        !           295: typedef struct TestStructList
        !           296: {
        !           297:     TestStruct *value;
        !           298:     struct TestStructList *next;
        !           299: } TestStructList;
        !           300: 
        !           301: static void visit_type_TestStructList(Visitor *v, TestStructList **obj,
        !           302:                                       const char *name, Error **errp)
        !           303: {
        !           304:     GenericList *i, **head = (GenericList **)obj;
        !           305: 
        !           306:     visit_start_list(v, name, errp);
        !           307: 
        !           308:     for (*head = i = visit_next_list(v, head, errp); i; i = visit_next_list(v, &i, errp)) {
        !           309:         TestStructList *native_i = (TestStructList *)i;
        !           310:         visit_type_TestStruct(v, &native_i->value, NULL, errp);
        !           311:     }
        !           312: 
        !           313:     visit_end_list(v, errp);
        !           314: }
        !           315: 
        !           316: static void test_visitor_out_list(TestOutputVisitorData *data,
        !           317:                                   const void *unused)
        !           318: {
        !           319:     char *value_str = (char *) "list value";
        !           320:     TestStructList *p, *head = NULL;
        !           321:     const int max_items = 10;
        !           322:     bool value_bool = true;
        !           323:     int value_int = 10;
        !           324:     Error *errp = NULL;
        !           325:     QListEntry *entry;
        !           326:     QObject *obj;
        !           327:     QList *qlist;
        !           328:     int i;
        !           329: 
        !           330:     for (i = 0; i < max_items; i++) {
        !           331:         p = g_malloc0(sizeof(*p));
        !           332:         p->value = g_malloc0(sizeof(*p->value));
        !           333:         p->value->integer = value_int;
        !           334:         p->value->boolean = value_bool;
        !           335:         p->value->string = value_str;
        !           336: 
        !           337:         p->next = head;
        !           338:         head = p;
        !           339:     }
        !           340: 
        !           341:     visit_type_TestStructList(data->ov, &head, NULL, &errp);
        !           342:     g_assert(!error_is_set(&errp));
        !           343: 
        !           344:     obj = qmp_output_get_qobject(data->qov);
        !           345:     g_assert(obj != NULL);
        !           346:     g_assert(qobject_type(obj) == QTYPE_QLIST);
        !           347: 
        !           348:     qlist = qobject_to_qlist(obj);
        !           349:     g_assert(!qlist_empty(qlist));
        !           350: 
        !           351:     i = 0;
        !           352:     QLIST_FOREACH_ENTRY(qlist, entry) {
        !           353:         QDict *qdict;
        !           354: 
        !           355:         g_assert(qobject_type(entry->value) == QTYPE_QDICT);
        !           356:         qdict = qobject_to_qdict(entry->value);
        !           357:         g_assert_cmpint(qdict_size(qdict), ==, 3);
        !           358:         g_assert_cmpint(qdict_get_int(qdict, "integer"), ==, value_int);
        !           359:         g_assert_cmpint(qdict_get_bool(qdict, "boolean"), ==, value_bool);
        !           360:         g_assert_cmpstr(qdict_get_str(qdict, "string"), ==, value_str);
        !           361:         i++;
        !           362:     }
        !           363:     g_assert_cmpint(i, ==, max_items);
        !           364: 
        !           365:     QDECREF(qlist);
        !           366: 
        !           367:     for (p = head; p;) {
        !           368:         TestStructList *tmp = p->next;
        !           369:         g_free(p->value);
        !           370:         g_free(p);
        !           371:         p = tmp;
        !           372:     }
        !           373: }
        !           374: 
        !           375: static void test_visitor_out_list_qapi_free(TestOutputVisitorData *data,
        !           376:                                             const void *unused)
        !           377: {
        !           378:     UserDefNestedList *p, *head = NULL;
        !           379:     const char string[] = "foo bar";
        !           380:     int i, max_count = 1024;
        !           381: 
        !           382:     for (i = 0; i < max_count; i++) {
        !           383:         p = g_malloc0(sizeof(*p));
        !           384:         p->value = g_malloc0(sizeof(*p->value));
        !           385: 
        !           386:         p->value->string0 = g_strdup(string);
        !           387:         p->value->dict1.string1 = g_strdup(string);
        !           388:         p->value->dict1.dict2.userdef1 = g_malloc0(sizeof(UserDefOne));
        !           389:         p->value->dict1.dict2.userdef1->string = g_strdup(string);
        !           390:         p->value->dict1.dict2.userdef1->integer = 42;
        !           391:         p->value->dict1.dict2.string2 = g_strdup(string);
        !           392:         p->value->dict1.has_dict3 = false;
        !           393: 
        !           394:         p->next = head;
        !           395:         head = p;
        !           396:     }
        !           397: 
        !           398:     qapi_free_UserDefNestedList(head);
        !           399: }
        !           400: 
        !           401: static void test_visitor_out_union(TestOutputVisitorData *data,
        !           402:                                    const void *unused)
        !           403: {
        !           404:     QObject *arg, *qvalue;
        !           405:     QDict *qdict, *value;
        !           406: 
        !           407:     Error *err = NULL;
        !           408: 
        !           409:     UserDefUnion *tmp = g_malloc0(sizeof(UserDefUnion));
        !           410:     tmp->kind = USER_DEF_UNION_KIND_A;
        !           411:     tmp->a = g_malloc0(sizeof(UserDefA));
        !           412:     tmp->a->boolean = true;
        !           413: 
        !           414:     visit_type_UserDefUnion(data->ov, &tmp, NULL, &err);
        !           415:     g_assert(err == NULL);
        !           416:     arg = qmp_output_get_qobject(data->qov);
        !           417: 
        !           418:     g_assert(qobject_type(arg) == QTYPE_QDICT);
        !           419:     qdict = qobject_to_qdict(arg);
        !           420: 
        !           421:     g_assert_cmpstr(qdict_get_str(qdict, "type"), ==, "a");
        !           422: 
        !           423:     qvalue = qdict_get(qdict, "data");
        !           424:     g_assert(data != NULL);
        !           425:     g_assert(qobject_type(qvalue) == QTYPE_QDICT);
        !           426:     value = qobject_to_qdict(qvalue);
        !           427:     g_assert_cmpint(qdict_get_bool(value, "boolean"), ==, true);
        !           428: 
        !           429:     qapi_free_UserDefUnion(tmp);
        !           430:     QDECREF(qdict);
        !           431: }
        !           432: 
        !           433: static void output_visitor_test_add(const char *testpath,
        !           434:                                     TestOutputVisitorData *data,
        !           435:                                     void (*test_func)(TestOutputVisitorData *data, const void *user_data))
        !           436: {
        !           437:     g_test_add(testpath, TestOutputVisitorData, data, visitor_output_setup,
        !           438:                test_func, visitor_output_teardown);
        !           439: }
        !           440: 
        !           441: int main(int argc, char **argv)
        !           442: {
        !           443:     TestOutputVisitorData out_visitor_data;
        !           444: 
        !           445:     g_test_init(&argc, &argv, NULL);
        !           446: 
        !           447:     output_visitor_test_add("/visitor/output/int",
        !           448:                             &out_visitor_data, test_visitor_out_int);
        !           449:     output_visitor_test_add("/visitor/output/bool",
        !           450:                             &out_visitor_data, test_visitor_out_bool);
        !           451:     output_visitor_test_add("/visitor/output/number",
        !           452:                             &out_visitor_data, test_visitor_out_number);
        !           453:     output_visitor_test_add("/visitor/output/string",
        !           454:                             &out_visitor_data, test_visitor_out_string);
        !           455:     output_visitor_test_add("/visitor/output/no-string",
        !           456:                             &out_visitor_data, test_visitor_out_no_string);
        !           457:     output_visitor_test_add("/visitor/output/enum",
        !           458:                             &out_visitor_data, test_visitor_out_enum);
        !           459:     output_visitor_test_add("/visitor/output/enum-errors",
        !           460:                             &out_visitor_data, test_visitor_out_enum_errors);
        !           461:     output_visitor_test_add("/visitor/output/struct",
        !           462:                             &out_visitor_data, test_visitor_out_struct);
        !           463:     output_visitor_test_add("/visitor/output/struct-nested",
        !           464:                             &out_visitor_data, test_visitor_out_struct_nested);
        !           465:     output_visitor_test_add("/visitor/output/struct-errors",
        !           466:                             &out_visitor_data, test_visitor_out_struct_errors);
        !           467:     output_visitor_test_add("/visitor/output/list",
        !           468:                             &out_visitor_data, test_visitor_out_list);
        !           469:     output_visitor_test_add("/visitor/output/list-qapi-free",
        !           470:                             &out_visitor_data, test_visitor_out_list_qapi_free);
        !           471:     output_visitor_test_add("/visitor/output/union",
        !           472:                             &out_visitor_data, test_visitor_out_union);
        !           473: 
        !           474:     g_test_run();
        !           475: 
        !           476:     return 0;
        !           477: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.