qemu/tests/test-string-input-visitor.c
<<
>>
Prefs
   1/*
   2 * String Input Visitor unit-tests.
   3 *
   4 * Copyright (C) 2012 Red Hat Inc.
   5 *
   6 * Authors:
   7 *  Paolo Bonzini <pbonzini@redhat.com> (based on test-qmp-input-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 <glib.h>
  14#include <stdarg.h>
  15
  16#include "qemu-common.h"
  17#include "qapi/string-input-visitor.h"
  18#include "test-qapi-types.h"
  19#include "test-qapi-visit.h"
  20#include "qapi/qmp/types.h"
  21
  22typedef struct TestInputVisitorData {
  23    StringInputVisitor *siv;
  24} TestInputVisitorData;
  25
  26static void visitor_input_teardown(TestInputVisitorData *data,
  27                                   const void *unused)
  28{
  29    if (data->siv) {
  30        string_input_visitor_cleanup(data->siv);
  31        data->siv = NULL;
  32    }
  33}
  34
  35/* This is provided instead of a test setup function so that the JSON
  36   string used by the tests are kept in the test functions (and not
  37   int main()) */
  38static
  39Visitor *visitor_input_test_init(TestInputVisitorData *data,
  40                                 const char *string)
  41{
  42    Visitor *v;
  43
  44    data->siv = string_input_visitor_new(string);
  45    g_assert(data->siv != NULL);
  46
  47    v = string_input_get_visitor(data->siv);
  48    g_assert(v != NULL);
  49
  50    return v;
  51}
  52
  53static void test_visitor_in_int(TestInputVisitorData *data,
  54                                const void *unused)
  55{
  56    int64_t res = 0, value = -42;
  57    Error *err = NULL;
  58    Visitor *v;
  59
  60    v = visitor_input_test_init(data, "-42");
  61
  62    visit_type_int(v, &res, NULL, &err);
  63    g_assert(!err);
  64    g_assert_cmpint(res, ==, value);
  65}
  66
  67static void test_visitor_in_intList(TestInputVisitorData *data,
  68                                    const void *unused)
  69{
  70    int64_t value[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 20};
  71    int16List *res = NULL, *tmp;
  72    Visitor *v;
  73    int i = 0;
  74
  75    v = visitor_input_test_init(data, "1,2,0,2-4,20,5-9,1-8");
  76
  77    visit_type_int16List(v, &res, NULL, &error_abort);
  78    tmp = res;
  79    while (i < sizeof(value) / sizeof(value[0])) {
  80        g_assert(tmp);
  81        g_assert_cmpint(tmp->value, ==, value[i++]);
  82        tmp = tmp->next;
  83    }
  84    g_assert(!tmp);
  85
  86    tmp = res;
  87    while (tmp) {
  88        res = res->next;
  89        g_free(tmp);
  90        tmp = res;
  91    }
  92}
  93
  94static void test_visitor_in_bool(TestInputVisitorData *data,
  95                                 const void *unused)
  96{
  97    Error *err = NULL;
  98    bool res = false;
  99    Visitor *v;
 100
 101    v = visitor_input_test_init(data, "true");
 102
 103    visit_type_bool(v, &res, NULL, &err);
 104    g_assert(!err);
 105    g_assert_cmpint(res, ==, true);
 106    visitor_input_teardown(data, unused);
 107
 108    v = visitor_input_test_init(data, "yes");
 109
 110    visit_type_bool(v, &res, NULL, &err);
 111    g_assert(!err);
 112    g_assert_cmpint(res, ==, true);
 113    visitor_input_teardown(data, unused);
 114
 115    v = visitor_input_test_init(data, "on");
 116
 117    visit_type_bool(v, &res, NULL, &err);
 118    g_assert(!err);
 119    g_assert_cmpint(res, ==, true);
 120    visitor_input_teardown(data, unused);
 121
 122    v = visitor_input_test_init(data, "false");
 123
 124    visit_type_bool(v, &res, NULL, &err);
 125    g_assert(!err);
 126    g_assert_cmpint(res, ==, false);
 127    visitor_input_teardown(data, unused);
 128
 129    v = visitor_input_test_init(data, "no");
 130
 131    visit_type_bool(v, &res, NULL, &err);
 132    g_assert(!err);
 133    g_assert_cmpint(res, ==, false);
 134    visitor_input_teardown(data, unused);
 135
 136    v = visitor_input_test_init(data, "off");
 137
 138    visit_type_bool(v, &res, NULL, &err);
 139    g_assert(!err);
 140    g_assert_cmpint(res, ==, false);
 141}
 142
 143static void test_visitor_in_number(TestInputVisitorData *data,
 144                                   const void *unused)
 145{
 146    double res = 0, value = 3.14;
 147    Error *err = NULL;
 148    Visitor *v;
 149
 150    v = visitor_input_test_init(data, "3.14");
 151
 152    visit_type_number(v, &res, NULL, &err);
 153    g_assert(!err);
 154    g_assert_cmpfloat(res, ==, value);
 155}
 156
 157static void test_visitor_in_string(TestInputVisitorData *data,
 158                                   const void *unused)
 159{
 160    char *res = NULL, *value = (char *) "Q E M U";
 161    Error *err = NULL;
 162    Visitor *v;
 163
 164    v = visitor_input_test_init(data, value);
 165
 166    visit_type_str(v, &res, NULL, &err);
 167    g_assert(!err);
 168    g_assert_cmpstr(res, ==, value);
 169
 170    g_free(res);
 171}
 172
 173static void test_visitor_in_enum(TestInputVisitorData *data,
 174                                 const void *unused)
 175{
 176    Error *err = NULL;
 177    Visitor *v;
 178    EnumOne i;
 179
 180    for (i = 0; EnumOne_lookup[i]; i++) {
 181        EnumOne res = -1;
 182
 183        v = visitor_input_test_init(data, EnumOne_lookup[i]);
 184
 185        visit_type_EnumOne(v, &res, NULL, &err);
 186        g_assert(!err);
 187        g_assert_cmpint(i, ==, res);
 188
 189        visitor_input_teardown(data, NULL);
 190    }
 191
 192    data->siv = NULL;
 193}
 194
 195/* Try to crash the visitors */
 196static void test_visitor_in_fuzz(TestInputVisitorData *data,
 197                                 const void *unused)
 198{
 199    int64_t ires;
 200    intList *ilres;
 201    bool bres;
 202    double nres;
 203    char *sres;
 204    EnumOne eres;
 205    Visitor *v;
 206    unsigned int i;
 207    char buf[10000];
 208
 209    for (i = 0; i < 100; i++) {
 210        unsigned int j;
 211
 212        j = g_test_rand_int_range(0, sizeof(buf) - 1);
 213
 214        buf[j] = '\0';
 215
 216        if (j != 0) {
 217            for (j--; j != 0; j--) {
 218                buf[j - 1] = (char)g_test_rand_int_range(0, 256);
 219            }
 220        }
 221
 222        v = visitor_input_test_init(data, buf);
 223        visit_type_int(v, &ires, NULL, NULL);
 224        visitor_input_teardown(data, NULL);
 225
 226        v = visitor_input_test_init(data, buf);
 227        visit_type_intList(v, &ilres, NULL, NULL);
 228        visitor_input_teardown(data, NULL);
 229
 230        v = visitor_input_test_init(data, buf);
 231        visit_type_bool(v, &bres, NULL, NULL);
 232        visitor_input_teardown(data, NULL);
 233
 234        v = visitor_input_test_init(data, buf);
 235        visit_type_number(v, &nres, NULL, NULL);
 236        visitor_input_teardown(data, NULL);
 237
 238        v = visitor_input_test_init(data, buf);
 239        sres = NULL;
 240        visit_type_str(v, &sres, NULL, NULL);
 241        g_free(sres);
 242        visitor_input_teardown(data, NULL);
 243
 244        v = visitor_input_test_init(data, buf);
 245        visit_type_EnumOne(v, &eres, NULL, NULL);
 246        visitor_input_teardown(data, NULL);
 247    }
 248}
 249
 250static void input_visitor_test_add(const char *testpath,
 251                                   TestInputVisitorData *data,
 252                                   void (*test_func)(TestInputVisitorData *data, const void *user_data))
 253{
 254    g_test_add(testpath, TestInputVisitorData, data, NULL, test_func,
 255               visitor_input_teardown);
 256}
 257
 258int main(int argc, char **argv)
 259{
 260    TestInputVisitorData in_visitor_data;
 261
 262    g_test_init(&argc, &argv, NULL);
 263
 264    input_visitor_test_add("/string-visitor/input/int",
 265                           &in_visitor_data, test_visitor_in_int);
 266    input_visitor_test_add("/string-visitor/input/intList",
 267                           &in_visitor_data, test_visitor_in_intList);
 268    input_visitor_test_add("/string-visitor/input/bool",
 269                           &in_visitor_data, test_visitor_in_bool);
 270    input_visitor_test_add("/string-visitor/input/number",
 271                           &in_visitor_data, test_visitor_in_number);
 272    input_visitor_test_add("/string-visitor/input/string",
 273                            &in_visitor_data, test_visitor_in_string);
 274    input_visitor_test_add("/string-visitor/input/enum",
 275                            &in_visitor_data, test_visitor_in_enum);
 276    input_visitor_test_add("/string-visitor/input/fuzz",
 277                            &in_visitor_data, test_visitor_in_fuzz);
 278
 279    g_test_run();
 280
 281    return 0;
 282}
 283