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 #include <glib.h> 152d7799f2SPaolo Bonzini 1679ee7df8SPaolo Bonzini #include "qemu-common.h" 17*da34e65cSMarkus Armbruster #include "qapi/error.h" 182d7799f2SPaolo Bonzini #include "qapi/string-output-visitor.h" 192d7799f2SPaolo Bonzini #include "test-qapi-types.h" 202d7799f2SPaolo Bonzini #include "test-qapi-visit.h" 217b1b5d19SPaolo Bonzini #include "qapi/qmp/types.h" 222d7799f2SPaolo Bonzini 232d7799f2SPaolo Bonzini typedef struct TestOutputVisitorData { 242d7799f2SPaolo Bonzini StringOutputVisitor *sov; 252d7799f2SPaolo Bonzini Visitor *ov; 26b4900c0eSHu Tao bool human; 272d7799f2SPaolo Bonzini } TestOutputVisitorData; 282d7799f2SPaolo Bonzini 292d7799f2SPaolo Bonzini static void visitor_output_setup(TestOutputVisitorData *data, 302d7799f2SPaolo Bonzini const void *unused) 312d7799f2SPaolo Bonzini { 32b4900c0eSHu Tao data->human = false; 33b4900c0eSHu Tao data->sov = string_output_visitor_new(data->human); 34b4900c0eSHu Tao g_assert(data->sov != NULL); 35b4900c0eSHu Tao 36b4900c0eSHu Tao data->ov = string_output_get_visitor(data->sov); 37b4900c0eSHu Tao g_assert(data->ov != NULL); 38b4900c0eSHu Tao } 39b4900c0eSHu Tao 40b4900c0eSHu Tao static void visitor_output_setup_human(TestOutputVisitorData *data, 41b4900c0eSHu Tao const void *unused) 42b4900c0eSHu Tao { 43b4900c0eSHu Tao data->human = true; 44b4900c0eSHu Tao data->sov = string_output_visitor_new(data->human); 452d7799f2SPaolo Bonzini g_assert(data->sov != NULL); 462d7799f2SPaolo Bonzini 472d7799f2SPaolo Bonzini data->ov = string_output_get_visitor(data->sov); 482d7799f2SPaolo Bonzini g_assert(data->ov != NULL); 492d7799f2SPaolo Bonzini } 502d7799f2SPaolo Bonzini 512d7799f2SPaolo Bonzini static void visitor_output_teardown(TestOutputVisitorData *data, 522d7799f2SPaolo Bonzini const void *unused) 532d7799f2SPaolo Bonzini { 542d7799f2SPaolo Bonzini string_output_visitor_cleanup(data->sov); 552d7799f2SPaolo Bonzini data->sov = NULL; 562d7799f2SPaolo Bonzini data->ov = NULL; 572d7799f2SPaolo Bonzini } 582d7799f2SPaolo Bonzini 592d7799f2SPaolo Bonzini static void test_visitor_out_int(TestOutputVisitorData *data, 602d7799f2SPaolo Bonzini const void *unused) 612d7799f2SPaolo Bonzini { 6269e25563SHu Tao int64_t value = 42; 63e940f543SMarkus Armbruster Error *err = NULL; 642d7799f2SPaolo Bonzini char *str; 652d7799f2SPaolo Bonzini 6651e72bc1SEric Blake visit_type_int(data->ov, NULL, &value, &err); 67e940f543SMarkus Armbruster g_assert(!err); 682d7799f2SPaolo Bonzini 692d7799f2SPaolo Bonzini str = string_output_get_string(data->sov); 702d7799f2SPaolo Bonzini g_assert(str != NULL); 71b4900c0eSHu Tao if (data->human) { 72b4900c0eSHu Tao g_assert_cmpstr(str, ==, "42 (0x2a)"); 73b4900c0eSHu Tao } else { 7469e25563SHu Tao g_assert_cmpstr(str, ==, "42"); 75b4900c0eSHu Tao } 762d7799f2SPaolo Bonzini g_free(str); 772d7799f2SPaolo Bonzini } 782d7799f2SPaolo Bonzini 7969e25563SHu Tao static void test_visitor_out_intList(TestOutputVisitorData *data, 8069e25563SHu Tao const void *unused) 8169e25563SHu Tao { 8269e25563SHu Tao int64_t value[] = {0, 1, 9, 10, 16, 15, 14, 8369e25563SHu Tao 3, 4, 5, 6, 11, 12, 13, 21, 22, INT64_MAX - 1, INT64_MAX}; 8469e25563SHu Tao intList *list = NULL, **tmp = &list; 8569e25563SHu Tao int i; 86533fdaedSMarkus Armbruster Error *err = NULL; 8769e25563SHu Tao char *str; 8869e25563SHu Tao 8969e25563SHu Tao for (i = 0; i < sizeof(value) / sizeof(value[0]); i++) { 9069e25563SHu Tao *tmp = g_malloc0(sizeof(**tmp)); 9169e25563SHu Tao (*tmp)->value = value[i]; 9269e25563SHu Tao tmp = &(*tmp)->next; 9369e25563SHu Tao } 9469e25563SHu Tao 9551e72bc1SEric Blake visit_type_intList(data->ov, NULL, &list, &err); 96533fdaedSMarkus Armbruster g_assert(err == NULL); 9769e25563SHu Tao 9869e25563SHu Tao str = string_output_get_string(data->sov); 9969e25563SHu Tao g_assert(str != NULL); 100b4900c0eSHu Tao if (data->human) { 101b4900c0eSHu Tao g_assert_cmpstr(str, ==, 102b4900c0eSHu Tao "0-1,3-6,9-16,21-22,9223372036854775806-9223372036854775807 " 103b4900c0eSHu Tao "(0x0-0x1,0x3-0x6,0x9-0x10,0x15-0x16," 104b4900c0eSHu Tao "0x7ffffffffffffffe-0x7fffffffffffffff)"); 105b4900c0eSHu Tao } else { 10669e25563SHu Tao g_assert_cmpstr(str, ==, 10769e25563SHu Tao "0-1,3-6,9-16,21-22,9223372036854775806-9223372036854775807"); 108b4900c0eSHu Tao } 10969e25563SHu Tao g_free(str); 11069e25563SHu Tao while (list) { 11169e25563SHu Tao intList *tmp2; 11269e25563SHu Tao tmp2 = list->next; 11369e25563SHu Tao g_free(list); 11469e25563SHu Tao list = tmp2; 11569e25563SHu Tao } 11669e25563SHu Tao } 11769e25563SHu Tao 1182d7799f2SPaolo Bonzini static void test_visitor_out_bool(TestOutputVisitorData *data, 1192d7799f2SPaolo Bonzini const void *unused) 1202d7799f2SPaolo Bonzini { 121e940f543SMarkus Armbruster Error *err = NULL; 1222d7799f2SPaolo Bonzini bool value = true; 1232d7799f2SPaolo Bonzini char *str; 1242d7799f2SPaolo Bonzini 12551e72bc1SEric Blake visit_type_bool(data->ov, NULL, &value, &err); 126e940f543SMarkus Armbruster g_assert(!err); 1272d7799f2SPaolo Bonzini 1282d7799f2SPaolo Bonzini str = string_output_get_string(data->sov); 1292d7799f2SPaolo Bonzini g_assert(str != NULL); 1302d7799f2SPaolo Bonzini g_assert_cmpstr(str, ==, "true"); 1312d7799f2SPaolo Bonzini g_free(str); 1322d7799f2SPaolo Bonzini } 1332d7799f2SPaolo Bonzini 1342d7799f2SPaolo Bonzini static void test_visitor_out_number(TestOutputVisitorData *data, 1352d7799f2SPaolo Bonzini const void *unused) 1362d7799f2SPaolo Bonzini { 1372d7799f2SPaolo Bonzini double value = 3.14; 138e940f543SMarkus Armbruster Error *err = NULL; 1392d7799f2SPaolo Bonzini char *str; 1402d7799f2SPaolo Bonzini 14151e72bc1SEric Blake visit_type_number(data->ov, NULL, &value, &err); 142e940f543SMarkus Armbruster g_assert(!err); 1432d7799f2SPaolo Bonzini 1442d7799f2SPaolo Bonzini str = string_output_get_string(data->sov); 1452d7799f2SPaolo Bonzini g_assert(str != NULL); 146173bbb75SMichael Roth g_assert_cmpstr(str, ==, "3.140000"); 1472d7799f2SPaolo Bonzini g_free(str); 1482d7799f2SPaolo Bonzini } 1492d7799f2SPaolo Bonzini 1502d7799f2SPaolo Bonzini static void test_visitor_out_string(TestOutputVisitorData *data, 1512d7799f2SPaolo Bonzini const void *unused) 1522d7799f2SPaolo Bonzini { 1532d7799f2SPaolo Bonzini char *string = (char *) "Q E M U"; 154b4900c0eSHu Tao const char *string_human = "\"Q E M U\""; 155e940f543SMarkus Armbruster Error *err = NULL; 1562d7799f2SPaolo Bonzini char *str; 1572d7799f2SPaolo Bonzini 15851e72bc1SEric Blake visit_type_str(data->ov, NULL, &string, &err); 159e940f543SMarkus Armbruster g_assert(!err); 1602d7799f2SPaolo Bonzini 1612d7799f2SPaolo Bonzini str = string_output_get_string(data->sov); 1622d7799f2SPaolo Bonzini g_assert(str != NULL); 163b4900c0eSHu Tao if (data->human) { 164b4900c0eSHu Tao g_assert_cmpstr(str, ==, string_human); 165b4900c0eSHu Tao } else { 1662d7799f2SPaolo Bonzini g_assert_cmpstr(str, ==, string); 167b4900c0eSHu Tao } 1682d7799f2SPaolo Bonzini g_free(str); 1692d7799f2SPaolo Bonzini } 1702d7799f2SPaolo Bonzini 1712d7799f2SPaolo Bonzini static void test_visitor_out_no_string(TestOutputVisitorData *data, 1722d7799f2SPaolo Bonzini const void *unused) 1732d7799f2SPaolo Bonzini { 1742d7799f2SPaolo Bonzini char *string = NULL; 175e940f543SMarkus Armbruster Error *err = NULL; 1762d7799f2SPaolo Bonzini char *str; 1772d7799f2SPaolo Bonzini 1782d7799f2SPaolo Bonzini /* A null string should return "" */ 17951e72bc1SEric Blake visit_type_str(data->ov, NULL, &string, &err); 180e940f543SMarkus Armbruster g_assert(!err); 1812d7799f2SPaolo Bonzini 1822d7799f2SPaolo Bonzini str = string_output_get_string(data->sov); 1832d7799f2SPaolo Bonzini g_assert(str != NULL); 184b4900c0eSHu Tao if (data->human) { 185b4900c0eSHu Tao g_assert_cmpstr(str, ==, "<null>"); 186b4900c0eSHu Tao } else { 1872d7799f2SPaolo Bonzini g_assert_cmpstr(str, ==, ""); 188b4900c0eSHu Tao } 1892d7799f2SPaolo Bonzini g_free(str); 1902d7799f2SPaolo Bonzini } 1912d7799f2SPaolo Bonzini 1922d7799f2SPaolo Bonzini static void test_visitor_out_enum(TestOutputVisitorData *data, 1932d7799f2SPaolo Bonzini const void *unused) 1942d7799f2SPaolo Bonzini { 195e940f543SMarkus Armbruster Error *err = NULL; 1962d7799f2SPaolo Bonzini char *str; 1972d7799f2SPaolo Bonzini EnumOne i; 1982d7799f2SPaolo Bonzini 1997fb1cf16SEric Blake for (i = 0; i < ENUM_ONE__MAX; i++) { 200b4900c0eSHu Tao char *str_human; 201b4900c0eSHu Tao 20251e72bc1SEric Blake visit_type_EnumOne(data->ov, "unused", &i, &err); 203e940f543SMarkus Armbruster g_assert(!err); 2042d7799f2SPaolo Bonzini 2059e99c5fdSAndreas Färber str_human = g_strdup_printf("\"%s\"", EnumOne_lookup[i]); 206b4900c0eSHu Tao 2072d7799f2SPaolo Bonzini str = string_output_get_string(data->sov); 2082d7799f2SPaolo Bonzini g_assert(str != NULL); 209b4900c0eSHu Tao if (data->human) { 210b4900c0eSHu Tao g_assert_cmpstr(str, ==, str_human); 211b4900c0eSHu Tao } else { 2122d7799f2SPaolo Bonzini g_assert_cmpstr(str, ==, EnumOne_lookup[i]); 213b4900c0eSHu Tao } 214b4900c0eSHu Tao g_free(str_human); 2152d7799f2SPaolo Bonzini g_free(str); 2162d7799f2SPaolo Bonzini } 2172d7799f2SPaolo Bonzini } 2182d7799f2SPaolo Bonzini 2192d7799f2SPaolo Bonzini static void test_visitor_out_enum_errors(TestOutputVisitorData *data, 2202d7799f2SPaolo Bonzini const void *unused) 2212d7799f2SPaolo Bonzini { 2227fb1cf16SEric Blake EnumOne i, bad_values[] = { ENUM_ONE__MAX, -1 }; 223e940f543SMarkus Armbruster Error *err; 2242d7799f2SPaolo Bonzini 2252d7799f2SPaolo Bonzini for (i = 0; i < ARRAY_SIZE(bad_values) ; i++) { 226e940f543SMarkus Armbruster err = NULL; 22751e72bc1SEric Blake visit_type_EnumOne(data->ov, "unused", &bad_values[i], &err); 228e940f543SMarkus Armbruster g_assert(err); 229e940f543SMarkus Armbruster error_free(err); 2302d7799f2SPaolo Bonzini } 2312d7799f2SPaolo Bonzini } 2322d7799f2SPaolo Bonzini 233b4900c0eSHu Tao static void 234b4900c0eSHu Tao output_visitor_test_add(const char *testpath, 2352d7799f2SPaolo Bonzini TestOutputVisitorData *data, 236b4900c0eSHu Tao void (*test_func)(TestOutputVisitorData *data, 237b4900c0eSHu Tao const void *user_data), 238b4900c0eSHu Tao bool human) 2392d7799f2SPaolo Bonzini { 240b4900c0eSHu Tao g_test_add(testpath, TestOutputVisitorData, data, 241b4900c0eSHu Tao human ? visitor_output_setup_human : visitor_output_setup, 2422d7799f2SPaolo Bonzini test_func, visitor_output_teardown); 2432d7799f2SPaolo Bonzini } 2442d7799f2SPaolo Bonzini 2452d7799f2SPaolo Bonzini int main(int argc, char **argv) 2462d7799f2SPaolo Bonzini { 2472d7799f2SPaolo Bonzini TestOutputVisitorData out_visitor_data; 2482d7799f2SPaolo Bonzini 2492d7799f2SPaolo Bonzini g_test_init(&argc, &argv, NULL); 2502d7799f2SPaolo Bonzini 2512d7799f2SPaolo Bonzini output_visitor_test_add("/string-visitor/output/int", 252b4900c0eSHu Tao &out_visitor_data, test_visitor_out_int, false); 253deb847bfSDr. David Alan Gilbert output_visitor_test_add("/string-visitor/output/int-human", 254b4900c0eSHu Tao &out_visitor_data, test_visitor_out_int, true); 2552d7799f2SPaolo Bonzini output_visitor_test_add("/string-visitor/output/bool", 256b4900c0eSHu Tao &out_visitor_data, test_visitor_out_bool, false); 257deb847bfSDr. David Alan Gilbert output_visitor_test_add("/string-visitor/output/bool-human", 258b4900c0eSHu Tao &out_visitor_data, test_visitor_out_bool, true); 2592d7799f2SPaolo Bonzini output_visitor_test_add("/string-visitor/output/number", 260b4900c0eSHu Tao &out_visitor_data, test_visitor_out_number, false); 261deb847bfSDr. David Alan Gilbert output_visitor_test_add("/string-visitor/output/number-human", 262b4900c0eSHu Tao &out_visitor_data, test_visitor_out_number, true); 2632d7799f2SPaolo Bonzini output_visitor_test_add("/string-visitor/output/string", 264b4900c0eSHu Tao &out_visitor_data, test_visitor_out_string, false); 265deb847bfSDr. David Alan Gilbert output_visitor_test_add("/string-visitor/output/string-human", 266b4900c0eSHu Tao &out_visitor_data, test_visitor_out_string, true); 2672d7799f2SPaolo Bonzini output_visitor_test_add("/string-visitor/output/no-string", 268b4900c0eSHu Tao &out_visitor_data, test_visitor_out_no_string, 269b4900c0eSHu Tao false); 270deb847bfSDr. David Alan Gilbert output_visitor_test_add("/string-visitor/output/no-string-human", 271b4900c0eSHu Tao &out_visitor_data, test_visitor_out_no_string, 272b4900c0eSHu Tao true); 2732d7799f2SPaolo Bonzini output_visitor_test_add("/string-visitor/output/enum", 274b4900c0eSHu Tao &out_visitor_data, test_visitor_out_enum, false); 275deb847bfSDr. David Alan Gilbert output_visitor_test_add("/string-visitor/output/enum-human", 276b4900c0eSHu Tao &out_visitor_data, test_visitor_out_enum, true); 2772d7799f2SPaolo Bonzini output_visitor_test_add("/string-visitor/output/enum-errors", 278b4900c0eSHu Tao &out_visitor_data, test_visitor_out_enum_errors, 279b4900c0eSHu Tao false); 280deb847bfSDr. David Alan Gilbert output_visitor_test_add("/string-visitor/output/enum-errors-human", 281b4900c0eSHu Tao &out_visitor_data, test_visitor_out_enum_errors, 282b4900c0eSHu Tao true); 28369e25563SHu Tao output_visitor_test_add("/string-visitor/output/intList", 284b4900c0eSHu Tao &out_visitor_data, test_visitor_out_intList, false); 285deb847bfSDr. David Alan Gilbert output_visitor_test_add("/string-visitor/output/intList-human", 286b4900c0eSHu Tao &out_visitor_data, test_visitor_out_intList, true); 2872d7799f2SPaolo Bonzini 2882d7799f2SPaolo Bonzini g_test_run(); 2892d7799f2SPaolo Bonzini 2902d7799f2SPaolo Bonzini return 0; 2912d7799f2SPaolo Bonzini } 292