qemu/tests/test-string-output-visitor.c
<<
>>
Prefs
   1/*
   2 * String Output Visitor unit-tests.
   3 *
   4 * Copyright (C) 2012 Red Hat Inc.
   5 *
   6 * Authors:
   7 *  Paolo Bonzini <pbonzini@redhat.com> (based on test-qobject-output-visitor)
   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 "qemu/osdep.h"
  14
  15#include "qemu-common.h"
  16#include "qapi/error.h"
  17#include "qapi/string-output-visitor.h"
  18#include "test-qapi-types.h"
  19#include "test-qapi-visit.h"
  20#include "qapi/qmp/types.h"
  21
  22typedef struct TestOutputVisitorData {
  23    Visitor *ov;
  24    char *str;
  25    bool human;
  26} TestOutputVisitorData;
  27
  28static void visitor_output_setup_internal(TestOutputVisitorData *data,
  29                                          bool human)
  30{
  31    data->human = human;
  32    data->ov = string_output_visitor_new(human, &data->str);
  33    g_assert(data->ov);
  34}
  35
  36static void visitor_output_setup(TestOutputVisitorData *data,
  37                                 const void *unused)
  38{
  39    return visitor_output_setup_internal(data, false);
  40}
  41
  42static void visitor_output_setup_human(TestOutputVisitorData *data,
  43                                       const void *unused)
  44{
  45    return visitor_output_setup_internal(data, true);
  46}
  47
  48static void visitor_output_teardown(TestOutputVisitorData *data,
  49                                    const void *unused)
  50{
  51    visit_free(data->ov);
  52    data->ov = NULL;
  53    g_free(data->str);
  54    data->str = NULL;
  55}
  56
  57static char *visitor_get(TestOutputVisitorData *data)
  58{
  59    visit_complete(data->ov, &data->str);
  60    g_assert(data->str);
  61    return data->str;
  62}
  63
  64static void visitor_reset(TestOutputVisitorData *data)
  65{
  66    bool human = data->human;
  67
  68    visitor_output_teardown(data, NULL);
  69    visitor_output_setup_internal(data, human);
  70}
  71
  72static void test_visitor_out_int(TestOutputVisitorData *data,
  73                                 const void *unused)
  74{
  75    int64_t value = 42;
  76    Error *err = NULL;
  77    char *str;
  78
  79    visit_type_int(data->ov, NULL, &value, &err);
  80    g_assert(!err);
  81
  82    str = visitor_get(data);
  83    if (data->human) {
  84        g_assert_cmpstr(str, ==, "42 (0x2a)");
  85    } else {
  86        g_assert_cmpstr(str, ==, "42");
  87    }
  88}
  89
  90static void test_visitor_out_intList(TestOutputVisitorData *data,
  91                                     const void *unused)
  92{
  93    int64_t value[] = {0, 1, 9, 10, 16, 15, 14,
  94        3, 4, 5, 6, 11, 12, 13, 21, 22, INT64_MAX - 1, INT64_MAX};
  95    intList *list = NULL, **tmp = &list;
  96    int i;
  97    Error *err = NULL;
  98    char *str;
  99
 100    for (i = 0; i < sizeof(value) / sizeof(value[0]); i++) {
 101        *tmp = g_malloc0(sizeof(**tmp));
 102        (*tmp)->value = value[i];
 103        tmp = &(*tmp)->next;
 104    }
 105
 106    visit_type_intList(data->ov, NULL, &list, &err);
 107    g_assert(err == NULL);
 108
 109    str = visitor_get(data);
 110    if (data->human) {
 111        g_assert_cmpstr(str, ==,
 112            "0-1,3-6,9-16,21-22,9223372036854775806-9223372036854775807 "
 113            "(0x0-0x1,0x3-0x6,0x9-0x10,0x15-0x16,"
 114            "0x7ffffffffffffffe-0x7fffffffffffffff)");
 115    } else {
 116        g_assert_cmpstr(str, ==,
 117            "0-1,3-6,9-16,21-22,9223372036854775806-9223372036854775807");
 118    }
 119    qapi_free_intList(list);
 120}
 121
 122static void test_visitor_out_bool(TestOutputVisitorData *data,
 123                                  const void *unused)
 124{
 125    Error *err = NULL;
 126    bool value = true;
 127    char *str;
 128
 129    visit_type_bool(data->ov, NULL, &value, &err);
 130    g_assert(!err);
 131
 132    str = visitor_get(data);
 133    g_assert_cmpstr(str, ==, "true");
 134}
 135
 136static void test_visitor_out_number(TestOutputVisitorData *data,
 137                                    const void *unused)
 138{
 139    double value = 3.14;
 140    Error *err = NULL;
 141    char *str;
 142
 143    visit_type_number(data->ov, NULL, &value, &err);
 144    g_assert(!err);
 145
 146    str = visitor_get(data);
 147    g_assert_cmpstr(str, ==, "3.140000");
 148}
 149
 150static void test_visitor_out_string(TestOutputVisitorData *data,
 151                                    const void *unused)
 152{
 153    char *string = (char *) "Q E M U";
 154    const char *string_human = "\"Q E M U\"";
 155    Error *err = NULL;
 156    char *str;
 157
 158    visit_type_str(data->ov, NULL, &string, &err);
 159    g_assert(!err);
 160
 161    str = visitor_get(data);
 162    if (data->human) {
 163        g_assert_cmpstr(str, ==, string_human);
 164    } else {
 165        g_assert_cmpstr(str, ==, string);
 166    }
 167}
 168
 169static void test_visitor_out_no_string(TestOutputVisitorData *data,
 170                                       const void *unused)
 171{
 172    char *string = NULL;
 173    char *str;
 174
 175    /* A null string should return "" */
 176    visit_type_str(data->ov, NULL, &string, &error_abort);
 177
 178    str = visitor_get(data);
 179    if (data->human) {
 180        g_assert_cmpstr(str, ==, "<null>");
 181    } else {
 182        g_assert_cmpstr(str, ==, "");
 183    }
 184}
 185
 186static void test_visitor_out_enum(TestOutputVisitorData *data,
 187                                  const void *unused)
 188{
 189    char *str;
 190    EnumOne i;
 191
 192    for (i = 0; i < ENUM_ONE__MAX; i++) {
 193        visit_type_EnumOne(data->ov, "unused", &i, &error_abort);
 194
 195        str = visitor_get(data);
 196        if (data->human) {
 197            char *str_human = g_strdup_printf("\"%s\"", EnumOne_lookup[i]);
 198
 199            g_assert_cmpstr(str, ==, str_human);
 200            g_free(str_human);
 201        } else {
 202            g_assert_cmpstr(str, ==, EnumOne_lookup[i]);
 203        }
 204        visitor_reset(data);
 205    }
 206}
 207
 208static void test_visitor_out_enum_errors(TestOutputVisitorData *data,
 209                                         const void *unused)
 210{
 211    EnumOne i, bad_values[] = { ENUM_ONE__MAX, -1 };
 212    Error *err;
 213
 214    for (i = 0; i < ARRAY_SIZE(bad_values) ; i++) {
 215        err = NULL;
 216        visit_type_EnumOne(data->ov, "unused", &bad_values[i], &err);
 217        error_free_or_abort(&err);
 218    }
 219}
 220
 221static void
 222output_visitor_test_add(const char *testpath,
 223                        TestOutputVisitorData *data,
 224                        void (*test_func)(TestOutputVisitorData *data,
 225                                          const void *user_data),
 226                        bool human)
 227{
 228    g_test_add(testpath, TestOutputVisitorData, data,
 229               human ? visitor_output_setup_human : visitor_output_setup,
 230               test_func, visitor_output_teardown);
 231}
 232
 233int main(int argc, char **argv)
 234{
 235    TestOutputVisitorData out_visitor_data;
 236
 237    g_test_init(&argc, &argv, NULL);
 238
 239    output_visitor_test_add("/string-visitor/output/int",
 240                            &out_visitor_data, test_visitor_out_int, false);
 241    output_visitor_test_add("/string-visitor/output/int-human",
 242                            &out_visitor_data, test_visitor_out_int, true);
 243    output_visitor_test_add("/string-visitor/output/bool",
 244                            &out_visitor_data, test_visitor_out_bool, false);
 245    output_visitor_test_add("/string-visitor/output/bool-human",
 246                            &out_visitor_data, test_visitor_out_bool, true);
 247    output_visitor_test_add("/string-visitor/output/number",
 248                            &out_visitor_data, test_visitor_out_number, false);
 249    output_visitor_test_add("/string-visitor/output/number-human",
 250                            &out_visitor_data, test_visitor_out_number, true);
 251    output_visitor_test_add("/string-visitor/output/string",
 252                            &out_visitor_data, test_visitor_out_string, false);
 253    output_visitor_test_add("/string-visitor/output/string-human",
 254                            &out_visitor_data, test_visitor_out_string, true);
 255    output_visitor_test_add("/string-visitor/output/no-string",
 256                            &out_visitor_data, test_visitor_out_no_string,
 257                            false);
 258    output_visitor_test_add("/string-visitor/output/no-string-human",
 259                            &out_visitor_data, test_visitor_out_no_string,
 260                            true);
 261    output_visitor_test_add("/string-visitor/output/enum",
 262                            &out_visitor_data, test_visitor_out_enum, false);
 263    output_visitor_test_add("/string-visitor/output/enum-human",
 264                            &out_visitor_data, test_visitor_out_enum, true);
 265    output_visitor_test_add("/string-visitor/output/enum-errors",
 266                            &out_visitor_data, test_visitor_out_enum_errors,
 267                            false);
 268    output_visitor_test_add("/string-visitor/output/enum-errors-human",
 269                            &out_visitor_data, test_visitor_out_enum_errors,
 270                            true);
 271    output_visitor_test_add("/string-visitor/output/intList",
 272                            &out_visitor_data, test_visitor_out_intList, false);
 273    output_visitor_test_add("/string-visitor/output/intList-human",
 274                            &out_visitor_data, test_visitor_out_intList, true);
 275
 276    g_test_run();
 277
 278    return 0;
 279}
 280