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