cachepc-qemu

Fork of AMDESE/qemu with changes for cachepc side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-qemu
Log | Files | Refs | Submodules | LICENSE | sfeed.txt

test-forward-visitor.c (6023B)


      1/*
      2 * QAPI Forwarding Visitor unit-tests.
      3 *
      4 * Copyright (C) 2021 Red Hat Inc.
      5 *
      6 * This work is licensed under the terms of the GNU GPL, version 2 or later.
      7 * See the COPYING file in the top-level directory.
      8 */
      9
     10#include "qemu/osdep.h"
     11
     12#include "qemu-common.h"
     13#include "qapi/forward-visitor.h"
     14#include "qapi/qobject-input-visitor.h"
     15#include "qapi/error.h"
     16#include "qapi/qmp/qobject.h"
     17#include "qapi/qmp/qdict.h"
     18#include "test-qapi-visit.h"
     19#include "qemu/option.h"
     20
     21typedef bool GenericVisitor (Visitor *, const char *, void **, Error **);
     22#define CAST_VISIT_TYPE(fn) ((GenericVisitor *)(fn))
     23
     24/*
     25 * Parse @srcstr and wrap it with a ForwardFieldVisitor converting "src" to
     26 * "dst". Check that visiting the result with "src" name fails, and return
     27 * the result of visiting "dst".
     28 */
     29static void *visit_with_forward(const char *srcstr, GenericVisitor *fn)
     30{
     31    bool help = false;
     32    QDict *src = keyval_parse(srcstr, NULL, &help, &error_abort);
     33    Visitor *v, *alias_v;
     34    Error *err = NULL;
     35    void *result = NULL;
     36
     37    v = qobject_input_visitor_new_keyval(QOBJECT(src));
     38    visit_start_struct(v, NULL, NULL, 0, &error_abort);
     39
     40    alias_v = visitor_forward_field(v, "dst", "src");
     41    fn(alias_v, "src", &result, &err);
     42    error_free_or_abort(&err);
     43    assert(!result);
     44    fn(alias_v, "dst", &result, &err);
     45    assert(err == NULL);
     46    visit_free(alias_v);
     47
     48    visit_end_struct(v, NULL);
     49    visit_free(v);
     50    qobject_unref(QOBJECT(src));
     51    return result;
     52}
     53
     54static void test_forward_any(void)
     55{
     56    QObject *src = visit_with_forward("src.integer=42,src.string=Hello,src.enum1=value2",
     57                                      CAST_VISIT_TYPE(visit_type_any));
     58    Visitor *v = qobject_input_visitor_new_keyval(src);
     59    Error *err = NULL;
     60    UserDefOne *dst;
     61
     62    visit_type_UserDefOne(v, NULL, &dst, &err);
     63    assert(err == NULL);
     64    visit_free(v);
     65
     66    g_assert_cmpint(dst->integer, ==, 42);
     67    g_assert_cmpstr(dst->string, ==, "Hello");
     68    g_assert_cmpint(dst->has_enum1, ==, true);
     69    g_assert_cmpint(dst->enum1, ==, ENUM_ONE_VALUE2);
     70    qapi_free_UserDefOne(dst);
     71    qobject_unref(QOBJECT(src));
     72}
     73
     74static void test_forward_size(void)
     75{
     76    /*
     77     * visit_type_size does not return a pointer, so visit_with_forward
     78     * cannot be used.
     79     */
     80    bool help = false;
     81    QDict *src = keyval_parse("src=1.5M", NULL, &help, &error_abort);
     82    Visitor *v, *alias_v;
     83    Error *err = NULL;
     84    uint64_t result = 0;
     85
     86    v = qobject_input_visitor_new_keyval(QOBJECT(src));
     87    visit_start_struct(v, NULL, NULL, 0, &error_abort);
     88
     89    alias_v = visitor_forward_field(v, "dst", "src");
     90    visit_type_size(alias_v, "src", &result, &err);
     91    error_free_or_abort(&err);
     92    visit_type_size(alias_v, "dst", &result, &err);
     93    assert(result == 3 << 19);
     94    assert(err == NULL);
     95    visit_free(alias_v);
     96
     97    visit_end_struct(v, NULL);
     98    visit_free(v);
     99    qobject_unref(QOBJECT(src));
    100}
    101
    102static void test_forward_number(void)
    103{
    104    /*
    105     * visit_type_number does not return a pointer, so visit_with_forward
    106     * cannot be used.
    107     */
    108    bool help = false;
    109    QDict *src = keyval_parse("src=1.5", NULL, &help, &error_abort);
    110    Visitor *v, *alias_v;
    111    Error *err = NULL;
    112    double result = 0.0;
    113
    114    v = qobject_input_visitor_new_keyval(QOBJECT(src));
    115    visit_start_struct(v, NULL, NULL, 0, &error_abort);
    116
    117    alias_v = visitor_forward_field(v, "dst", "src");
    118    visit_type_number(alias_v, "src", &result, &err);
    119    error_free_or_abort(&err);
    120    visit_type_number(alias_v, "dst", &result, &err);
    121    assert(result == 1.5);
    122    assert(err == NULL);
    123    visit_free(alias_v);
    124
    125    visit_end_struct(v, NULL);
    126    visit_free(v);
    127    qobject_unref(QOBJECT(src));
    128}
    129
    130static void test_forward_string(void)
    131{
    132    char *dst = visit_with_forward("src=Hello",
    133                                   CAST_VISIT_TYPE(visit_type_str));
    134
    135    g_assert_cmpstr(dst, ==, "Hello");
    136    g_free(dst);
    137}
    138
    139static void test_forward_struct(void)
    140{
    141    UserDefOne *dst = visit_with_forward("src.integer=42,src.string=Hello",
    142                                         CAST_VISIT_TYPE(visit_type_UserDefOne));
    143
    144    g_assert_cmpint(dst->integer, ==, 42);
    145    g_assert_cmpstr(dst->string, ==, "Hello");
    146    g_assert_cmpint(dst->has_enum1, ==, false);
    147    qapi_free_UserDefOne(dst);
    148}
    149
    150static void test_forward_alternate(void)
    151{
    152    AltStrObj *s_dst = visit_with_forward("src=hello",
    153                                          CAST_VISIT_TYPE(visit_type_AltStrObj));
    154    AltStrObj *o_dst = visit_with_forward("src.integer=42,src.boolean=true,src.string=world",
    155                                          CAST_VISIT_TYPE(visit_type_AltStrObj));
    156
    157    g_assert_cmpint(s_dst->type, ==, QTYPE_QSTRING);
    158    g_assert_cmpstr(s_dst->u.s, ==, "hello");
    159    g_assert_cmpint(o_dst->type, ==, QTYPE_QDICT);
    160    g_assert_cmpint(o_dst->u.o.integer, ==, 42);
    161    g_assert_cmpint(o_dst->u.o.boolean, ==, true);
    162    g_assert_cmpstr(o_dst->u.o.string, ==, "world");
    163
    164    qapi_free_AltStrObj(s_dst);
    165    qapi_free_AltStrObj(o_dst);
    166}
    167
    168static void test_forward_list(void)
    169{
    170    uint8List *dst = visit_with_forward("src.0=1,src.1=2,src.2=3,src.3=4",
    171                                        CAST_VISIT_TYPE(visit_type_uint8List));
    172    uint8List *tmp;
    173    int i;
    174
    175    for (tmp = dst, i = 1; i <= 4; i++) {
    176        g_assert(tmp);
    177        g_assert_cmpint(tmp->value, ==, i);
    178        tmp = tmp->next;
    179    }
    180    g_assert(!tmp);
    181    qapi_free_uint8List(dst);
    182}
    183
    184int main(int argc, char **argv)
    185{
    186    g_test_init(&argc, &argv, NULL);
    187
    188    g_test_add_func("/visitor/forward/struct", test_forward_struct);
    189    g_test_add_func("/visitor/forward/alternate", test_forward_alternate);
    190    g_test_add_func("/visitor/forward/string", test_forward_string);
    191    g_test_add_func("/visitor/forward/size", test_forward_size);
    192    g_test_add_func("/visitor/forward/number", test_forward_number);
    193    g_test_add_func("/visitor/forward/any", test_forward_any);
    194    g_test_add_func("/visitor/forward/list", test_forward_list);
    195
    196    return g_test_run();
    197}