hashtest.c 3.9 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114
#include <config.h>

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "internal.h"
#include "hash.h"
#include "hashdata.h"
#include "testutils.h"


#define testError(...)                                          \
    do {                                                        \
        fprintf(stderr, __VA_ARGS__);                           \
        /* Pad to line up with test name ... in virTestRun */   \
        fprintf(stderr, "%74s", "... ");                        \
    } while (0)


static virHashTablePtr
testHashInit(int size)
{
    virHashTablePtr hash;
    int i;

    if (!(hash = virHashCreate(size, NULL)))
        return NULL;

    /* entires are added in reverse order so that they will be linked in
     * collision list in the same order as in the uuids array
     */
    for (i = ARRAY_CARDINALITY(uuids) - 1; i >= 0; i--) {
        if (virHashAddEntry(hash, uuids[i], (void *) uuids[i]) < 0) {
            virHashFree(hash);
            return NULL;
        }
    }

    return hash;
}


static int
testHashCheckCount(virHashTablePtr hash, int count)
{
    if (virHashSize(hash) != count) {
        testError("\nhash contains %d instead of %d elements\n",
                  virHashSize(hash), count);
        return -1;
    }

    return 0;
}


struct testInfo {
    void *data;
    int count;
};


const int testHashCountRemoveForEachSome =
    ARRAY_CARDINALITY(uuids) - ARRAY_CARDINALITY(uuids_subset);

static void
testHashRemoveForEachSome(void *payload ATTRIBUTE_UNUSED,
                          const void *name,
                          void *data)
{
    virHashTablePtr hash = data;
    int i;

    for (i = 0; i < ARRAY_CARDINALITY(uuids_subset); i++) {
        if (STREQ(uuids_subset[i], name)) {
            if (virHashRemoveEntry(hash, name) < 0 && virTestGetVerbose()) {
                fprintf(stderr, "\nentry \"%s\" could not be removed",
                        uuids_subset[i]);
            }
            break;
        }
    }
}


const int testHashCountRemoveForEachAll = 0;

static void
testHashRemoveForEachAll(void *payload ATTRIBUTE_UNUSED,
                         const void *name,
                         void *data)
{
    virHashTablePtr hash = data;

    virHashRemoveEntry(hash, name);
}


static int
testHashRemoveForEach(const void *data)
{
    const struct testInfo *info = data;
    virHashTablePtr hash;
    int count;
    int ret = -1;

    if (!(hash = testHashInit(0)))
        return -1;

    count = virHashForEach(hash, (virHashIterator) info->data, hash);

    if (count != ARRAY_CARDINALITY(uuids)) {
        if (virTestGetVerbose()) {
            testError("\nvirHashForEach didn't go through all entries,"
E
Eric Blake 已提交
115
                      " %d != %zu\n",
116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157
                      count, ARRAY_CARDINALITY(uuids));
        }
        goto cleanup;
    }

    if (testHashCheckCount(hash, info->count) < 0)
        goto cleanup;

    ret = 0;

cleanup:
    virHashFree(hash);
    return ret;
}


static int
mymain(int argc ATTRIBUTE_UNUSED,
       char **argv ATTRIBUTE_UNUSED)
{
    int ret = 0;

#define DO_TEST_FULL(name, cmd, data, count)                        \
    do {                                                            \
        struct testInfo info = { data, count };                     \
        if (virtTestRun(name, 1, testHash ## cmd, &info) < 0)       \
            ret = -1;                                               \
    } while (0)

#define DO_TEST_DATA(name, cmd, data)                               \
    DO_TEST_FULL(name "(" #data ")",                                \
                 cmd,                                               \
                 testHash ## cmd ## data,                           \
                 testHashCount ## cmd ## data)

    DO_TEST_DATA("Remove in ForEach", RemoveForEach, Some);
    DO_TEST_DATA("Remove in ForEach", RemoveForEach, All);

    return (ret == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
}

VIRT_TEST_MAIN(mymain)