12d7799f2SPaolo Bonzini /* 22d7799f2SPaolo Bonzini * String Output Visitor unit-tests. 32d7799f2SPaolo Bonzini * 42d7799f2SPaolo Bonzini * Copyright (C) 2012 Red Hat Inc. 52d7799f2SPaolo Bonzini * 62d7799f2SPaolo Bonzini * Authors: 72d7799f2SPaolo Bonzini * Paolo Bonzini <pbonzini@redhat.com> (based on test-qmp-output-visitor) 82d7799f2SPaolo Bonzini * 92d7799f2SPaolo Bonzini * This work is licensed under the terms of the GNU GPL, version 2 or later. 102d7799f2SPaolo Bonzini * See the COPYING file in the top-level directory. 112d7799f2SPaolo Bonzini */ 122d7799f2SPaolo Bonzini 13681c28a3SPeter Maydell #include "qemu/osdep.h" 142d7799f2SPaolo Bonzini 1579ee7df8SPaolo Bonzini #include "qemu-common.h" 16da34e65cSMarkus Armbruster #include "qapi/error.h" 172d7799f2SPaolo Bonzini #include "qapi/string-output-visitor.h" 182d7799f2SPaolo Bonzini #include "test-qapi-types.h" 192d7799f2SPaolo Bonzini #include "test-qapi-visit.h" 207b1b5d19SPaolo Bonzini #include "qapi/qmp/types.h" 212d7799f2SPaolo Bonzini 222d7799f2SPaolo Bonzini typedef struct TestOutputVisitorData { 232d7799f2SPaolo Bonzini StringOutputVisitor *sov; 242d7799f2SPaolo Bonzini Visitor *ov; 25*23d1705fSEric Blake char *str; 26b4900c0eSHu Tao bool human; 272d7799f2SPaolo Bonzini } TestOutputVisitorData; 282d7799f2SPaolo Bonzini 29a8fff94dSEric Blake static void visitor_output_setup_internal(TestOutputVisitorData *data, 30a8fff94dSEric Blake bool human) 31a8fff94dSEric Blake { 32a8fff94dSEric Blake data->human = human; 33a8fff94dSEric Blake data->sov = string_output_visitor_new(human); 34a8fff94dSEric Blake g_assert(data->sov); 35a8fff94dSEric Blake data->ov = string_output_get_visitor(data->sov); 36a8fff94dSEric Blake g_assert(data->ov); 37a8fff94dSEric Blake } 38a8fff94dSEric Blake 392d7799f2SPaolo Bonzini static void visitor_output_setup(TestOutputVisitorData *data, 402d7799f2SPaolo Bonzini const void *unused) 412d7799f2SPaolo Bonzini { 42a8fff94dSEric Blake return visitor_output_setup_internal(data, false); 43b4900c0eSHu Tao } 44b4900c0eSHu Tao 45b4900c0eSHu Tao static void visitor_output_setup_human(TestOutputVisitorData *data, 46b4900c0eSHu Tao const void *unused) 47b4900c0eSHu Tao { 48a8fff94dSEric Blake return visitor_output_setup_internal(data, true); 492d7799f2SPaolo Bonzini } 502d7799f2SPaolo Bonzini 512d7799f2SPaolo Bonzini static void visitor_output_teardown(TestOutputVisitorData *data, 522d7799f2SPaolo Bonzini const void *unused) 532d7799f2SPaolo Bonzini { 54e7ca5656SEric Blake visit_free(data->ov); 552d7799f2SPaolo Bonzini data->sov = NULL; 562d7799f2SPaolo Bonzini data->ov = NULL; 57*23d1705fSEric Blake g_free(data->str); 58*23d1705fSEric Blake data->str = NULL; 59*23d1705fSEric Blake } 60*23d1705fSEric Blake 61*23d1705fSEric Blake static char *visitor_get(TestOutputVisitorData *data) 62*23d1705fSEric Blake { 63*23d1705fSEric Blake data->str = string_output_get_string(data->sov); 64*23d1705fSEric Blake g_assert(data->str); 65*23d1705fSEric Blake return data->str; 662d7799f2SPaolo Bonzini } 672d7799f2SPaolo Bonzini 68a8fff94dSEric Blake static void visitor_reset(TestOutputVisitorData *data) 69a8fff94dSEric Blake { 70a8fff94dSEric Blake bool human = data->human; 71a8fff94dSEric Blake 72a8fff94dSEric Blake visitor_output_teardown(data, NULL); 73a8fff94dSEric Blake visitor_output_setup_internal(data, human); 74a8fff94dSEric Blake } 75a8fff94dSEric Blake 762d7799f2SPaolo Bonzini static void test_visitor_out_int(TestOutputVisitorData *data, 772d7799f2SPaolo Bonzini const void *unused) 782d7799f2SPaolo Bonzini { 7969e25563SHu Tao int64_t value = 42; 80e940f543SMarkus Armbruster Error *err = NULL; 812d7799f2SPaolo Bonzini char *str; 822d7799f2SPaolo Bonzini 8351e72bc1SEric Blake visit_type_int(data->ov, NULL, &value, &err); 84e940f543SMarkus Armbruster g_assert(!err); 852d7799f2SPaolo Bonzini 86*23d1705fSEric Blake str = visitor_get(data); 87b4900c0eSHu Tao if (data->human) { 88b4900c0eSHu Tao g_assert_cmpstr(str, ==, "42 (0x2a)"); 89b4900c0eSHu Tao } else { 9069e25563SHu Tao g_assert_cmpstr(str, ==, "42"); 91b4900c0eSHu Tao } 922d7799f2SPaolo Bonzini } 932d7799f2SPaolo Bonzini 9469e25563SHu Tao static void test_visitor_out_intList(TestOutputVisitorData *data, 9569e25563SHu Tao const void *unused) 9669e25563SHu Tao { 9769e25563SHu Tao int64_t value[] = {0, 1, 9, 10, 16, 15, 14, 9869e25563SHu Tao 3, 4, 5, 6, 11, 12, 13, 21, 22, INT64_MAX - 1, INT64_MAX}; 9969e25563SHu Tao intList *list = NULL, **tmp = &list; 10069e25563SHu Tao int i; 101533fdaedSMarkus Armbruster Error *err = NULL; 10269e25563SHu Tao char *str; 10369e25563SHu Tao 10469e25563SHu Tao for (i = 0; i < sizeof(value) / sizeof(value[0]); i++) { 10569e25563SHu Tao *tmp = g_malloc0(sizeof(**tmp)); 10669e25563SHu Tao (*tmp)->value = value[i]; 10769e25563SHu Tao tmp = &(*tmp)->next; 10869e25563SHu Tao } 10969e25563SHu Tao 11051e72bc1SEric Blake visit_type_intList(data->ov, NULL, &list, &err); 111533fdaedSMarkus Armbruster g_assert(err == NULL); 11269e25563SHu Tao 113*23d1705fSEric Blake str = visitor_get(data); 114b4900c0eSHu Tao if (data->human) { 115b4900c0eSHu Tao g_assert_cmpstr(str, ==, 116b4900c0eSHu Tao "0-1,3-6,9-16,21-22,9223372036854775806-9223372036854775807 " 117b4900c0eSHu Tao "(0x0-0x1,0x3-0x6,0x9-0x10,0x15-0x16," 118b4900c0eSHu Tao "0x7ffffffffffffffe-0x7fffffffffffffff)"); 119b4900c0eSHu Tao } else { 12069e25563SHu Tao g_assert_cmpstr(str, ==, 12169e25563SHu Tao "0-1,3-6,9-16,21-22,9223372036854775806-9223372036854775807"); 122b4900c0eSHu Tao } 123a8fff94dSEric Blake qapi_free_intList(list); 12469e25563SHu Tao } 12569e25563SHu Tao 1262d7799f2SPaolo Bonzini static void test_visitor_out_bool(TestOutputVisitorData *data, 1272d7799f2SPaolo Bonzini const void *unused) 1282d7799f2SPaolo Bonzini { 129e940f543SMarkus Armbruster Error *err = NULL; 1302d7799f2SPaolo Bonzini bool value = true; 1312d7799f2SPaolo Bonzini char *str; 1322d7799f2SPaolo Bonzini 13351e72bc1SEric Blake visit_type_bool(data->ov, NULL, &value, &err); 134e940f543SMarkus Armbruster g_assert(!err); 1352d7799f2SPaolo Bonzini 136*23d1705fSEric Blake str = visitor_get(data); 1372d7799f2SPaolo Bonzini g_assert_cmpstr(str, ==, "true"); 1382d7799f2SPaolo Bonzini } 1392d7799f2SPaolo Bonzini 1402d7799f2SPaolo Bonzini static void test_visitor_out_number(TestOutputVisitorData *data, 1412d7799f2SPaolo Bonzini const void *unused) 1422d7799f2SPaolo Bonzini { 1432d7799f2SPaolo Bonzini double value = 3.14; 144e940f543SMarkus Armbruster Error *err = NULL; 1452d7799f2SPaolo Bonzini char *str; 1462d7799f2SPaolo Bonzini 14751e72bc1SEric Blake visit_type_number(data->ov, NULL, &value, &err); 148e940f543SMarkus Armbruster g_assert(!err); 1492d7799f2SPaolo Bonzini 150*23d1705fSEric Blake str = visitor_get(data); 151173bbb75SMichael Roth g_assert_cmpstr(str, ==, "3.140000"); 1522d7799f2SPaolo Bonzini } 1532d7799f2SPaolo Bonzini 1542d7799f2SPaolo Bonzini static void test_visitor_out_string(TestOutputVisitorData *data, 1552d7799f2SPaolo Bonzini const void *unused) 1562d7799f2SPaolo Bonzini { 1572d7799f2SPaolo Bonzini char *string = (char *) "Q E M U"; 158b4900c0eSHu Tao const char *string_human = "\"Q E M U\""; 159e940f543SMarkus Armbruster Error *err = NULL; 1602d7799f2SPaolo Bonzini char *str; 1612d7799f2SPaolo Bonzini 16251e72bc1SEric Blake visit_type_str(data->ov, NULL, &string, &err); 163e940f543SMarkus Armbruster g_assert(!err); 1642d7799f2SPaolo Bonzini 165*23d1705fSEric Blake str = visitor_get(data); 166b4900c0eSHu Tao if (data->human) { 167b4900c0eSHu Tao g_assert_cmpstr(str, ==, string_human); 168b4900c0eSHu Tao } else { 1692d7799f2SPaolo Bonzini g_assert_cmpstr(str, ==, string); 170b4900c0eSHu Tao } 1712d7799f2SPaolo Bonzini } 1722d7799f2SPaolo Bonzini 1732d7799f2SPaolo Bonzini static void test_visitor_out_no_string(TestOutputVisitorData *data, 1742d7799f2SPaolo Bonzini const void *unused) 1752d7799f2SPaolo Bonzini { 1762d7799f2SPaolo Bonzini char *string = NULL; 1772d7799f2SPaolo Bonzini char *str; 1782d7799f2SPaolo Bonzini 1792d7799f2SPaolo Bonzini /* A null string should return "" */ 180a8fff94dSEric Blake visit_type_str(data->ov, NULL, &string, &error_abort); 1812d7799f2SPaolo Bonzini 182*23d1705fSEric Blake str = visitor_get(data); 183b4900c0eSHu Tao if (data->human) { 184b4900c0eSHu Tao g_assert_cmpstr(str, ==, "<null>"); 185b4900c0eSHu Tao } else { 1862d7799f2SPaolo Bonzini g_assert_cmpstr(str, ==, ""); 187b4900c0eSHu Tao } 1882d7799f2SPaolo Bonzini } 1892d7799f2SPaolo Bonzini 1902d7799f2SPaolo Bonzini static void test_visitor_out_enum(TestOutputVisitorData *data, 1912d7799f2SPaolo Bonzini const void *unused) 1922d7799f2SPaolo Bonzini { 1932d7799f2SPaolo Bonzini char *str; 1942d7799f2SPaolo Bonzini EnumOne i; 1952d7799f2SPaolo Bonzini 1967fb1cf16SEric Blake for (i = 0; i < ENUM_ONE__MAX; i++) { 197a8fff94dSEric Blake visit_type_EnumOne(data->ov, "unused", &i, &error_abort); 198b4900c0eSHu Tao 199*23d1705fSEric Blake str = visitor_get(data); 200b4900c0eSHu Tao if (data->human) { 201a8fff94dSEric Blake char *str_human = g_strdup_printf("\"%s\"", EnumOne_lookup[i]); 202a8fff94dSEric Blake 203b4900c0eSHu Tao g_assert_cmpstr(str, ==, str_human); 204a8fff94dSEric Blake g_free(str_human); 205b4900c0eSHu Tao } else { 2062d7799f2SPaolo Bonzini g_assert_cmpstr(str, ==, EnumOne_lookup[i]); 207b4900c0eSHu Tao } 208a8fff94dSEric Blake visitor_reset(data); 2092d7799f2SPaolo Bonzini } 2102d7799f2SPaolo Bonzini } 2112d7799f2SPaolo Bonzini 2122d7799f2SPaolo Bonzini static void test_visitor_out_enum_errors(TestOutputVisitorData *data, 2132d7799f2SPaolo Bonzini const void *unused) 2142d7799f2SPaolo Bonzini { 2157fb1cf16SEric Blake EnumOne i, bad_values[] = { ENUM_ONE__MAX, -1 }; 216e940f543SMarkus Armbruster Error *err; 2172d7799f2SPaolo Bonzini 2182d7799f2SPaolo Bonzini for (i = 0; i < ARRAY_SIZE(bad_values) ; i++) { 219e940f543SMarkus Armbruster err = NULL; 22051e72bc1SEric Blake visit_type_EnumOne(data->ov, "unused", &bad_values[i], &err); 221a8fff94dSEric Blake error_free_or_abort(&err); 2222d7799f2SPaolo Bonzini } 2232d7799f2SPaolo Bonzini } 2242d7799f2SPaolo Bonzini 225b4900c0eSHu Tao static void 226b4900c0eSHu Tao output_visitor_test_add(const char *testpath, 2272d7799f2SPaolo Bonzini TestOutputVisitorData *data, 228b4900c0eSHu Tao void (*test_func)(TestOutputVisitorData *data, 229b4900c0eSHu Tao const void *user_data), 230b4900c0eSHu Tao bool human) 2312d7799f2SPaolo Bonzini { 232b4900c0eSHu Tao g_test_add(testpath, TestOutputVisitorData, data, 233b4900c0eSHu Tao human ? visitor_output_setup_human : visitor_output_setup, 2342d7799f2SPaolo Bonzini test_func, visitor_output_teardown); 2352d7799f2SPaolo Bonzini } 2362d7799f2SPaolo Bonzini 2372d7799f2SPaolo Bonzini int main(int argc, char **argv) 2382d7799f2SPaolo Bonzini { 2392d7799f2SPaolo Bonzini TestOutputVisitorData out_visitor_data; 2402d7799f2SPaolo Bonzini 2412d7799f2SPaolo Bonzini g_test_init(&argc, &argv, NULL); 2422d7799f2SPaolo Bonzini 2432d7799f2SPaolo Bonzini output_visitor_test_add("/string-visitor/output/int", 244b4900c0eSHu Tao &out_visitor_data, test_visitor_out_int, false); 245deb847bfSDr. David Alan Gilbert output_visitor_test_add("/string-visitor/output/int-human", 246b4900c0eSHu Tao &out_visitor_data, test_visitor_out_int, true); 2472d7799f2SPaolo Bonzini output_visitor_test_add("/string-visitor/output/bool", 248b4900c0eSHu Tao &out_visitor_data, test_visitor_out_bool, false); 249deb847bfSDr. David Alan Gilbert output_visitor_test_add("/string-visitor/output/bool-human", 250b4900c0eSHu Tao &out_visitor_data, test_visitor_out_bool, true); 2512d7799f2SPaolo Bonzini output_visitor_test_add("/string-visitor/output/number", 252b4900c0eSHu Tao &out_visitor_data, test_visitor_out_number, false); 253deb847bfSDr. David Alan Gilbert output_visitor_test_add("/string-visitor/output/number-human", 254b4900c0eSHu Tao &out_visitor_data, test_visitor_out_number, true); 2552d7799f2SPaolo Bonzini output_visitor_test_add("/string-visitor/output/string", 256b4900c0eSHu Tao &out_visitor_data, test_visitor_out_string, false); 257deb847bfSDr. David Alan Gilbert output_visitor_test_add("/string-visitor/output/string-human", 258b4900c0eSHu Tao &out_visitor_data, test_visitor_out_string, true); 2592d7799f2SPaolo Bonzini output_visitor_test_add("/string-visitor/output/no-string", 260b4900c0eSHu Tao &out_visitor_data, test_visitor_out_no_string, 261b4900c0eSHu Tao false); 262deb847bfSDr. David Alan Gilbert output_visitor_test_add("/string-visitor/output/no-string-human", 263b4900c0eSHu Tao &out_visitor_data, test_visitor_out_no_string, 264b4900c0eSHu Tao true); 2652d7799f2SPaolo Bonzini output_visitor_test_add("/string-visitor/output/enum", 266b4900c0eSHu Tao &out_visitor_data, test_visitor_out_enum, false); 267deb847bfSDr. David Alan Gilbert output_visitor_test_add("/string-visitor/output/enum-human", 268b4900c0eSHu Tao &out_visitor_data, test_visitor_out_enum, true); 2692d7799f2SPaolo Bonzini output_visitor_test_add("/string-visitor/output/enum-errors", 270b4900c0eSHu Tao &out_visitor_data, test_visitor_out_enum_errors, 271b4900c0eSHu Tao false); 272deb847bfSDr. David Alan Gilbert output_visitor_test_add("/string-visitor/output/enum-errors-human", 273b4900c0eSHu Tao &out_visitor_data, test_visitor_out_enum_errors, 274b4900c0eSHu Tao true); 27569e25563SHu Tao output_visitor_test_add("/string-visitor/output/intList", 276b4900c0eSHu Tao &out_visitor_data, test_visitor_out_intList, false); 277deb847bfSDr. David Alan Gilbert output_visitor_test_add("/string-visitor/output/intList-human", 278b4900c0eSHu Tao &out_visitor_data, test_visitor_out_intList, true); 2792d7799f2SPaolo Bonzini 2802d7799f2SPaolo Bonzini g_test_run(); 2812d7799f2SPaolo Bonzini 2822d7799f2SPaolo Bonzini return 0; 2832d7799f2SPaolo Bonzini } 284