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