示例#1
0
static int
cpuTestRun(const char *name, const struct data *data)
{
    char *label = NULL;
    char *tmp;

    if (virAsprintf(&label, "CPU %s(%s): %s", apis[data->api], data->arch, name) < 0)
        return -1;

    tmp = virtTestLogContentAndReset();
    VIR_FREE(tmp);

    if (virtTestRun(label, cpuTest[data->api], data) < 0) {
        if (virTestGetDebug()) {
            char *log;
            if ((log = virtTestLogContentAndReset()) &&
                 strlen(log) > 0)
                VIR_TEST_DEBUG("\n%s\n", log);
            VIR_FREE(log);
        }

        VIR_FREE(label);
        return -1;
    }

    VIR_FREE(label);
    return 0;
}
示例#2
0
static int
cpuTestRun(const char *name, const struct data *data)
{
    char *label = NULL;

    if (virAsprintf(&label, "CPU %s(%s): %s", apis[data->api], data->arch, name) < 0)
        return -1;

    free(virtTestLogContentAndReset());

    if (virtTestRun(label, 1, cpuTest[data->api], data) < 0) {
        if (virTestGetDebug()) {
            char *log;
            if ((log = virtTestLogContentAndReset()) &&
                 strlen(log) > 0)
                fprintf(stderr, "\n%s\n", log);
            free(log);
        }

        free(label);
        return -1;
    }

    free(label);
    return 0;
}
示例#3
0
static int
linuxTestCompareFiles(const char *cpuinfofile,
                      char *sysfs_dir,
                      virArch arch,
                      const char *outputfile)
{
    int ret = -1;
    char *actualData = NULL;
    char *expectData = NULL;
    virNodeInfo nodeinfo;
    FILE *cpuinfo;

    if (virtTestLoadFile(outputfile, &expectData) < 0)
        goto fail;

    cpuinfo = fopen(cpuinfofile, "r");
    if (!cpuinfo) {
        fprintf(stderr, "unable to open: %s : %s\n",
                cpuinfofile, strerror(errno));
        goto fail;
    }

    memset(&nodeinfo, 0, sizeof(nodeinfo));
    if (linuxNodeInfoCPUPopulate(cpuinfo, sysfs_dir, arch, &nodeinfo) < 0) {
        if (virTestGetDebug()) {
            virErrorPtr error = virSaveLastError();
            if (error && error->code != VIR_ERR_OK)
                fprintf(stderr, "\n%s\n", error->message);
            virFreeError(error);
        }
        VIR_FORCE_FCLOSE(cpuinfo);
        goto fail;
    }
    VIR_FORCE_FCLOSE(cpuinfo);

    if (virAsprintf(&actualData,
                    "CPUs: %u/%u, MHz: %u, Nodes: %u, Sockets: %u, "
                    "Cores: %u, Threads: %u\n",
                    nodeinfo.cpus, VIR_NODEINFO_MAXCPUS(nodeinfo),
                    nodeinfo.mhz, nodeinfo.nodes, nodeinfo.sockets,
                    nodeinfo.cores, nodeinfo.threads) < 0)
        goto fail;

    if (STRNEQ(actualData, expectData)) {
        virtTestDifference(stderr, expectData, actualData);
        goto fail;
    }

    ret = 0;

 fail:
    VIR_FREE(expectData);
    VIR_FREE(actualData);
    return ret;
}
示例#4
0
static virHashTablePtr
testHashInit(int size)
{
    virHashTablePtr hash;
    ssize_t 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--) {
        ssize_t oldsize = virHashTableSize(hash);
        if (virHashAddEntry(hash, uuids[i], (void *) uuids[i]) < 0) {
            virHashFree(hash);
            return NULL;
        }

        if (virHashTableSize(hash) != oldsize && virTestGetDebug()) {
            VIR_WARN("hash grown from %zd to %zd",
                     (size_t)oldsize, (size_t)virHashTableSize(hash));
        }
    }

    for (i = 0; i < ARRAY_CARDINALITY(uuids); i++) {
        if (!virHashLookup(hash, uuids[i])) {
            if (virTestGetVerbose()) {
                VIR_WARN("\nentry \"%s\" could not be found\n",
                         uuids[i]);
            }
            virHashFree(hash);
            return NULL;
        }
    }

    if (size && size != virHashTableSize(hash) && virTestGetDebug())
        fprintf(stderr, "\n");

    return hash;
}
示例#5
0
文件: statstest.c 项目: avdv/libvirt
static int testDevice(const char *path, int expect)
{
    int actual = xenLinuxDomainDeviceID(1, path);

    if (actual == expect) {
        return 0;
    } else {
        if (virTestGetDebug())
            fprintf(stderr, "Expect %-6d Actual %-6d\n", expect, actual);
        return -1;
    }
}
示例#6
0
static int
testJSONFromString(const void *data)
{
    const struct testInfo *info = data;
    virJSONValuePtr json;
    int ret = -1;

    json = virJSONValueFromString(info->doc);

    if (info->pass) {
        if (!json) {
            if (virTestGetVerbose())
                fprintf(stderr, "Fail to parse %s\n", info->doc);
            ret = -1;
            goto cleanup;
        } else {
            if (virTestGetDebug())
                fprintf(stderr, "Parsed %s\n", info->doc);
        }
    } else {
        if (json) {
            if (virTestGetVerbose())
                fprintf(stderr, "Should not have parsed %s\n", info->doc);
            ret = -1;
            goto cleanup;
        } else {
            if (virTestGetDebug())
                fprintf(stderr, "Fail to parse %s\n", info->doc);
        }
    }

    ret = 0;

cleanup:
    virJSONValueFree(json);
    return ret;
}
示例#7
0
virCapsPtr testQemuCapsInit(void)
{
    virCapsPtr caps;
    virCapsGuestPtr guest;
    virCapsGuestMachinePtr *machines = NULL;
    int nmachines = 0;

    if (!(caps = virCapabilitiesNew(VIR_ARCH_X86_64, false, false)))
        return NULL;

    /* Add dummy 'none' security_driver. This is equal to setting
     * security_driver = "none" in qemu.conf. */
    if (VIR_ALLOC_N(caps->host.secModels, 1) < 0)
        goto cleanup;
    caps->host.nsecModels = 1;

    if (VIR_STRDUP(caps->host.secModels[0].model, "none") < 0 ||
        VIR_STRDUP(caps->host.secModels[0].doi, "0") < 0)
        goto cleanup;

    if (!(cpuDefault = virCPUDefCopy(&cpuDefaultData)) ||
        !(cpuHaswell = virCPUDefCopy(&cpuHaswellData)))
        goto cleanup;

    caps->host.cpu = cpuDefault;

    caps->host.nnumaCell_max = 4;

    if ((machines = testQemuAllocMachines(&nmachines)) == NULL)
        goto cleanup;

    if ((guest = virCapabilitiesAddGuest(caps, VIR_DOMAIN_OSTYPE_HVM, VIR_ARCH_I686,
                                         "/usr/bin/qemu", NULL,
                                         nmachines, machines)) == NULL ||
        !virCapabilitiesAddGuestFeature(guest, "cpuselection", true, false))
        goto cleanup;
    machines = NULL;

    if (virCapabilitiesAddGuestDomain(guest,
                                      VIR_DOMAIN_VIRT_QEMU,
                                      NULL,
                                      NULL,
                                      0,
                                      NULL) == NULL)
        goto cleanup;

    if ((machines = testQemuAllocMachines(&nmachines)) == NULL)
        goto cleanup;

    if (virCapabilitiesAddGuestDomain(guest,
                                      VIR_DOMAIN_VIRT_KVM,
                                      "/usr/bin/qemu-kvm",
                                      NULL,
                                      nmachines,
                                      machines) == NULL)
        goto cleanup;
    machines = NULL;

    if ((machines = testQemuAllocNewerMachines(&nmachines)) == NULL)
        goto cleanup;

    if ((guest = virCapabilitiesAddGuest(caps, VIR_DOMAIN_OSTYPE_HVM, VIR_ARCH_X86_64,
                                         "/usr/bin/qemu-system-x86_64", NULL,
                                         nmachines, machines)) == NULL ||
        !virCapabilitiesAddGuestFeature(guest, "cpuselection", true, false))
        goto cleanup;
    machines = NULL;

    if (virCapabilitiesAddGuestDomain(guest,
                                      VIR_DOMAIN_VIRT_QEMU,
                                      NULL,
                                      NULL,
                                      0,
                                      NULL) == NULL)
        goto cleanup;

    if ((machines = testQemuAllocMachines(&nmachines)) == NULL)
        goto cleanup;

    if (virCapabilitiesAddGuestDomain(guest,
                                      VIR_DOMAIN_VIRT_KVM,
                                      "/usr/bin/kvm",
                                      NULL,
                                      nmachines,
                                      machines) == NULL)
        goto cleanup;
    machines = NULL;

    if (virCapabilitiesAddGuestDomain(guest,
                                      VIR_DOMAIN_VIRT_KVM,
                                      "/usr/bin/kvm",
                                      NULL,
                                      0,
                                      NULL) == NULL)
        goto cleanup;

    if (testQemuAddPPC64Guest(caps))
        goto cleanup;

    if (testQemuAddPPC64LEGuest(caps))
        goto cleanup;

    if (testQemuAddPPCGuest(caps))
        goto cleanup;

    if (testQemuAddS390Guest(caps))
        goto cleanup;

    if (testQemuAddArmGuest(caps))
        goto cleanup;

    if (testQemuAddAARCH64Guest(caps))
        goto cleanup;

    if (virTestGetDebug()) {
        char *caps_str;

        caps_str = virCapabilitiesFormatXML(caps);
        if (!caps_str)
            goto cleanup;

        VIR_TEST_DEBUG("QEMU driver capabilities:\n%s", caps_str);

        VIR_FREE(caps_str);
    }

    return caps;

 cleanup:
    virCapabilitiesFreeMachines(machines, nmachines);
    if (caps->host.cpu != cpuDefault)
        virCPUDefFree(cpuDefault);
    if (caps->host.cpu != cpuHaswell)
        virCPUDefFree(cpuHaswell);
    virObjectUnref(caps);
    return NULL;
}
示例#8
0
virCapsPtr testQemuCapsInit(void) {
    virCapsPtr caps;
    virCapsGuestPtr guest;
    virCapsGuestMachinePtr *machines = NULL;
    int nmachines = 0;
    static const char *const xen_machines[] = {
        "xenner"
    };
    static virCPUFeatureDef host_cpu_features[] = {
        { (char *) "lahf_lm",   -1 },
        { (char *) "xtpr",      -1 },
        { (char *) "cx16",      -1 },
        { (char *) "tm2",       -1 },
        { (char *) "est",       -1 },
        { (char *) "vmx",       -1 },
        { (char *) "ds_cpl",    -1 },
        { (char *) "pbe",       -1 },
        { (char *) "tm",        -1 },
        { (char *) "ht",        -1 },
        { (char *) "ss",        -1 },
        { (char *) "acpi",      -1 },
        { (char *) "ds",        -1 }
    };
    static virCPUDef host_cpu = {
        VIR_CPU_TYPE_HOST,      /* type */
        0,                      /* mode */
        0,                      /* match */
        VIR_ARCH_X86_64,        /* arch */
        (char *) "core2duo",    /* model */
        NULL,                   /* vendor_id */
        0,                      /* fallback */
        (char *) "Intel",       /* vendor */
        1,                      /* sockets */
        2,                      /* cores */
        1,                      /* threads */
        ARRAY_CARDINALITY(host_cpu_features), /* nfeatures */
        ARRAY_CARDINALITY(host_cpu_features), /* nfeatures_max */
        host_cpu_features,      /* features */
        0,                      /* ncells */
        0,                      /* ncells_max */
        NULL,                   /* cells */
        0,                      /* cells_cpus */
    };

    if ((caps = virCapabilitiesNew(host_cpu.arch,
                                   0, 0)) == NULL)
        return NULL;

    if ((caps->host.cpu = virCPUDefCopy(&host_cpu)) == NULL ||
        (machines = testQemuAllocMachines(&nmachines)) == NULL)
        goto cleanup;

    if ((guest = virCapabilitiesAddGuest(caps, "hvm", VIR_ARCH_I686,
                                         "/usr/bin/qemu", NULL,
                                         nmachines, machines)) == NULL ||
        !virCapabilitiesAddGuestFeature(guest, "cpuselection", 1, 0))
        goto cleanup;
    machines = NULL;

    if (virCapabilitiesAddGuestDomain(guest,
                                      "qemu",
                                      NULL,
                                      NULL,
                                      0,
                                      NULL) == NULL)
        goto cleanup;

    if ((machines = testQemuAllocNewerMachines(&nmachines)) == NULL)
        goto cleanup;

    if ((guest = virCapabilitiesAddGuest(caps, "hvm", VIR_ARCH_X86_64,
                                         "/usr/bin/qemu-system-x86_64", NULL,
                                         nmachines, machines)) == NULL ||
        !virCapabilitiesAddGuestFeature(guest, "cpuselection", 1, 0))
        goto cleanup;
    machines = NULL;

    if (virCapabilitiesAddGuestDomain(guest,
                                      "qemu",
                                      NULL,
                                      NULL,
                                      0,
                                      NULL) == NULL)
        goto cleanup;

    if ((machines = testQemuAllocMachines(&nmachines)) == NULL)
        goto cleanup;

    if (virCapabilitiesAddGuestDomain(guest,
                                      "kvm",
                                      "/usr/bin/kvm",
                                      NULL,
                                      nmachines,
                                      machines) == NULL)
        goto cleanup;
    machines = NULL;

    nmachines = ARRAY_CARDINALITY(xen_machines);
    if ((machines = virCapabilitiesAllocMachines(xen_machines, nmachines)) == NULL)
        goto cleanup;

    if ((guest = virCapabilitiesAddGuest(caps, "xen", VIR_ARCH_X86_64,
                                         "/usr/bin/xenner", NULL,
                                         nmachines, machines)) == NULL)
        goto cleanup;
    machines = NULL;

    if (virCapabilitiesAddGuestDomain(guest,
                                      "kvm",
                                      "/usr/bin/kvm",
                                      NULL,
                                      0,
                                      NULL) == NULL)
        goto cleanup;

    if (testQemuAddPPC64Guest(caps))
        goto cleanup;

    if (testQemuAddPPCGuest(caps))
        goto cleanup;

    if (testQemuAddS390Guest(caps))
        goto cleanup;

    if (virTestGetDebug()) {
        char *caps_str;

        caps_str = virCapabilitiesFormatXML(caps);
        if (!caps_str)
            goto cleanup;

        fprintf(stderr, "QEMU driver capabilities:\n%s", caps_str);

        VIR_FREE(caps_str);
    }

    return caps;

cleanup:
    virCapabilitiesFreeMachines(machines, nmachines);
    virObjectUnref(caps);
    return NULL;
}
示例#9
0
文件: statstest.c 项目: avdv/libvirt
static int
mymain(void)
{
    int ret = 0;
    int status;
    virCommandPtr cmd;
    struct utsname ut;

    /* Skip test if xend is not running.  Calling xend on a non-xen
       kernel causes some versions of xend to issue a crash report, so
       we first probe uname results.  */
    uname(&ut);
    if (strstr(ut.release, "xen") == NULL)
        return EXIT_AM_SKIP;
    cmd = virCommandNewArgList("/usr/sbin/xend", "status", NULL);
    if (virCommandRun(cmd, &status) != 0 || status != 0) {
        virCommandFree(cmd);
        return EXIT_AM_SKIP;
    }
    virCommandFree(cmd);

    /* Some of our tests deliberately test failure cases, so
     * register a handler to stop error messages cluttering
     * up display
     */
    if (!virTestGetDebug())
        virSetErrorFunc(NULL, testQuietError);

#define DO_TEST(dev, num)                                              \
    do {                                                               \
        struct testInfo info = { dev, num };                           \
        if (virtTestRun("Device " dev " -> " # num,                    \
                        1, testDeviceHelper, &info) < 0)               \
            ret = -1;                                                  \
    } while (0)

    /********************************
     * Xen paravirt disks
     ********************************/

    DO_TEST("xvd", -1);

    /* first valid disk */
    DO_TEST("xvda", 51712);
    DO_TEST("xvda1", 51713);
    DO_TEST("xvda15", 51727);
    /* Last non-extended disk */
    DO_TEST("xvdp", 51952);
    DO_TEST("xvdp1", 51953);
    DO_TEST("xvdp15", 51967);

    /* First extended disk */
    DO_TEST("xvdq", 268439552);
    DO_TEST("xvdq1", 268439553);
    DO_TEST("xvdq15", 268439567);
    /* Last extended disk */
    DO_TEST("xvdiz", 268501760);
    DO_TEST("xvdiz1", 268501761);
    DO_TEST("xvdiz15", 268501775);

    /* Disk letter too large */
    DO_TEST("xvdja", -1);

    /* missing disk letter */
    DO_TEST("xvd1", -1);
    /* partition too large */
    DO_TEST("xvda16", -1);
    /* partition too small */
    DO_TEST("xvda0", -1);
    /* leading zeros */
    DO_TEST("xvda01", -1);
    /* leading + */
    DO_TEST("xvda+1", -1);
    /* leading - */
    DO_TEST("xvda-1", -1);

    /********************************
     * IDE disks
     ********************************/

    DO_TEST("hd", -1);

    /* first numbered disk */
    DO_TEST("hda", 768);
    DO_TEST("hda1", 769);
    DO_TEST("hda63", 831);
    /* second numbered disk */
    DO_TEST("hdb", 832);
    DO_TEST("hdb1", 833);
    DO_TEST("hdb63", 895);
    /* third numbered disk */
    DO_TEST("hdc", 5632);
    DO_TEST("hdc1", 5633);
    DO_TEST("hdc63", 5695);
    /* fourth numbered disk */
    DO_TEST("hdd", 5696);
    DO_TEST("hdd1", 5697);
    DO_TEST("hdd63", 5759);
    /* last valid disk */
    DO_TEST("hdt", 23360);
    DO_TEST("hdt1", 23361);
    DO_TEST("hdt63", 23423);

    /* Disk letter to large */
    DO_TEST("hdu", -1);
    /* missing disk letter */
    DO_TEST("hd1", -1);
    /* partition too large */
    DO_TEST("hda64", -1);
    /* partition too small */
    DO_TEST("hda0", -1);



    /********************************
     * SCSI disks
     ********************************/

    DO_TEST("sd", -1);

    /* first valid disk */
    DO_TEST("sda", 2048);
    DO_TEST("sda1", 2049);
    DO_TEST("sda15", 2063);
    /* last valid disk of first SCSI major number */
    DO_TEST("sdp", 2288);
    DO_TEST("sdp1", 2289);
    DO_TEST("sdp15", 2303);
    /* first valid disk of second SCSI major number */
    DO_TEST("sdq", 16640);
    DO_TEST("sdq1", 16641);
    DO_TEST("sdq15", 16655);
    /* last valid single letter disk */
    DO_TEST("sdz", 16784);
    DO_TEST("sdz1", 16785);
    DO_TEST("sdz15", 16799);
    /* first valid dual letter disk */
    DO_TEST("sdaa", 16800);
    DO_TEST("sdaa1", 16801);
    DO_TEST("sdaa15", 16815);
    /* second valid dual letter disk */
    DO_TEST("sdab", 16816);
    DO_TEST("sdab1", 16817);
    DO_TEST("sdab15", 16831);
    /* first letter of second sequence of dual letter disk */
    DO_TEST("sdba", 17216);
    DO_TEST("sdba1", 17217);
    DO_TEST("sdba15", 17231);
    /* last valid dual letter disk */
    DO_TEST("sdiv", 34800);
    DO_TEST("sdiv1", 34801);
    DO_TEST("sdiv15", 34815);

    /* Disk letter too large */
    DO_TEST("sdix", -1);
    /* missing disk letter */
    DO_TEST("sd1", -1);
    /* partition too large */
    DO_TEST("sda16", -1);
    /* partition too small */
    DO_TEST("sda0", -1);


    /* Path stripping */
    DO_TEST("/dev", -1);
    DO_TEST("/dev/", -1);
    DO_TEST("/dev/xvd", -1);
    DO_TEST("/dev/xvda", 51712);
    DO_TEST("/dev/xvda1", 51713);
    DO_TEST("/dev/xvda15", 51727);

    return ret==0 ? EXIT_SUCCESS : EXIT_FAILURE;
}
示例#10
0
virCapsPtr testQemuCapsInit(void) {
    struct utsname utsname;
    virCapsPtr caps;
    virCapsGuestPtr guest;
    virCapsGuestMachinePtr *machines = NULL;
    int nmachines = 0;
    static const char *const xen_machines[] = {
        "xenner"
    };
    static virCPUFeatureDef host_cpu_features[] = {
        { (char *) "lahf_lm",   -1 },
        { (char *) "xtpr",      -1 },
        { (char *) "cx16",      -1 },
        { (char *) "tm2",       -1 },
        { (char *) "est",       -1 },
        { (char *) "vmx",       -1 },
        { (char *) "ds_cpl",    -1 },
        { (char *) "pbe",       -1 },
        { (char *) "tm",        -1 },
        { (char *) "ht",        -1 },
        { (char *) "ss",        -1 },
        { (char *) "acpi",      -1 },
        { (char *) "ds",        -1 }
    };
    static virCPUDef host_cpu = {
        VIR_CPU_TYPE_HOST,      /* type */
        0,                      /* match */
        (char *) "x86_64",      /* arch */
        (char *) "core2duo",    /* model */
        (char *) "Intel",       /* vendor */
        1,                      /* sockets */
        2,                      /* cores */
        1,                      /* threads */
        ARRAY_CARDINALITY(host_cpu_features), /* nfeatures */
        host_cpu_features       /* features */
    };

    uname (&utsname);
    if ((caps = virCapabilitiesNew(utsname.machine,
                                   0, 0)) == NULL)
        return NULL;

    if ((caps->host.cpu = virCPUDefCopy(&host_cpu)) == NULL ||
        (machines = testQemuAllocMachines(&nmachines)) == NULL)
        goto cleanup;

    caps->ns.parse = qemuDomainDefNamespaceParse;
    caps->ns.free = qemuDomainDefNamespaceFree;
    caps->ns.format = qemuDomainDefNamespaceFormatXML;
    caps->ns.href = qemuDomainDefNamespaceHref;

    if ((guest = virCapabilitiesAddGuest(caps, "hvm", "i686", 32,
                                         "/usr/bin/qemu", NULL,
                                         nmachines, machines)) == NULL)
        goto cleanup;
    machines = NULL;

    if (virCapabilitiesAddGuestDomain(guest,
                                      "qemu",
                                      NULL,
                                      NULL,
                                      0,
                                      NULL) == NULL)
        goto cleanup;

    if ((machines = testQemuAllocNewerMachines(&nmachines)) == NULL)
        goto cleanup;

    if ((guest = virCapabilitiesAddGuest(caps, "hvm", "x86_64", 64,
                                         "/usr/bin/qemu-system-x86_64", NULL,
                                         nmachines, machines)) == NULL)
        goto cleanup;
    machines = NULL;

    if (virCapabilitiesAddGuestDomain(guest,
                                      "qemu",
                                      NULL,
                                      NULL,
                                      0,
                                      NULL) == NULL)
        goto cleanup;

    if ((machines = testQemuAllocMachines(&nmachines)) == NULL)
        goto cleanup;

    if (virCapabilitiesAddGuestDomain(guest,
                                      "kvm",
                                      "/usr/bin/kvm",
                                      NULL,
                                      nmachines,
                                      machines) == NULL)
        goto cleanup;
    machines = NULL;

    nmachines = ARRAY_CARDINALITY(xen_machines);
    if ((machines = virCapabilitiesAllocMachines(xen_machines, nmachines)) == NULL)
        goto cleanup;

    if ((guest = virCapabilitiesAddGuest(caps, "xen", "x86_64", 64,
                                         "/usr/bin/xenner", NULL,
                                         nmachines, machines)) == NULL)
        goto cleanup;
    machines = NULL;

    if (virCapabilitiesAddGuestDomain(guest,
                                      "kvm",
                                      "/usr/bin/kvm",
                                      NULL,
                                      0,
                                      NULL) == NULL)
        goto cleanup;

    if (virTestGetDebug()) {
        char *caps_str;

        caps_str = virCapabilitiesFormatXML(caps);
        if (!caps_str)
            goto cleanup;

        fprintf(stderr, "QEMU driver capabilities:\n%s", caps_str);

        VIR_FREE(caps_str);
    }

    return caps;

cleanup:
    virCapabilitiesFreeMachines(machines, nmachines);
    virCapabilitiesFree(caps);
    return NULL;
}
示例#11
0
/*
 * Runs test and count average time (if the nloops is grater than 1)
 *
 * returns: -1 = error, 0 = success
 */
int
virtTestRun(const char *title, int nloops, int (*body)(const void *data), const void *data)
{
    int i, ret = 0;
    double *ts = NULL;

    if (testCounter == 0 && !virTestGetVerbose())
        fprintf(stderr, "      ");

    testCounter++;

    if (testOOM < 2) {
        if (virTestGetVerbose())
            fprintf(stderr, "%2d) %-65s ... ", testCounter, title);
    }

    if (nloops > 1 && (VIR_ALLOC_N(ts, nloops) < 0))
        return -1;

    for (i=0; i < nloops; i++) {
        struct timeval before, after;

        if (ts)
            GETTIMEOFDAY(&before);

        virResetLastError();
        ret = body(data);
        virErrorPtr err = virGetLastError();
        if (err) {
            if (virTestGetVerbose() || virTestGetDebug())
                virDispatchError(NULL);
        }

        if (ret != 0) {
            break;
        }

        if (ts) {
            GETTIMEOFDAY(&after);
            ts[i] = DIFF_MSEC(&after, &before);
        }
    }
    if (testOOM < 2) {
        if (virTestGetVerbose()) {
            if (ret == 0 && ts)
                fprintf(stderr, "OK     [%.5f ms]\n",
                        virtTestCountAverage(ts, nloops));
            else if (ret == 0)
                fprintf(stderr, "OK\n");
            else if (ret == EXIT_AM_SKIP)
                fprintf(stderr, "SKIP\n");
            else
                fprintf(stderr, "FAILED\n");
        } else {
            if (testCounter != 1 &&
                !((testCounter-1) % 40)) {
                fprintf(stderr, " %-3d\n", (testCounter-1));
                fprintf(stderr, "      ");
            }
            if (ret == 0)
                fprintf(stderr, ".");
            else if (ret == EXIT_AM_SKIP)
                fprintf(stderr, "_");
            else
                fprintf(stderr, "!");
        }
    }

    VIR_FREE(ts);
    return ret;
}
示例#12
0
virCapsPtr testQemuCapsInit(void)
{
    virCapsPtr caps;

    if (!(caps = virCapabilitiesNew(VIR_ARCH_X86_64, false, false)))
        return NULL;

    /* Add dummy 'none' security_driver. This is equal to setting
     * security_driver = "none" in qemu.conf. */
    if (VIR_ALLOC_N(caps->host.secModels, 1) < 0)
        goto cleanup;
    caps->host.nsecModels = 1;

    if (VIR_STRDUP(caps->host.secModels[0].model, "none") < 0 ||
        VIR_STRDUP(caps->host.secModels[0].doi, "0") < 0)
        goto cleanup;

    if (!(cpuDefault = virCPUDefCopy(&cpuDefaultData)) ||
        !(cpuHaswell = virCPUDefCopy(&cpuHaswellData)) ||
        !(cpuPower8 = virCPUDefCopy(&cpuPower8Data)) ||
        !(cpuPower9 = virCPUDefCopy(&cpuPower9Data)))
        goto cleanup;

    qemuTestSetHostCPU(caps, NULL);

    caps->host.nnumaCell_max = 4;

    if (testQemuAddI686Guest(caps) < 0)
        goto cleanup;

    if (testQemuAddX86_64Guest(caps) < 0)
        goto cleanup;

    if (testQemuAddPPC64Guest(caps))
        goto cleanup;

    if (testQemuAddPPC64LEGuest(caps))
        goto cleanup;

    if (testQemuAddPPCGuest(caps))
        goto cleanup;

    if (testQemuAddS390Guest(caps))
        goto cleanup;

    if (testQemuAddArmGuest(caps))
        goto cleanup;

    if (testQemuAddAARCH64Guest(caps))
        goto cleanup;

    if (virTestGetDebug()) {
        char *caps_str;

        caps_str = virCapabilitiesFormatXML(caps);
        if (!caps_str)
            goto cleanup;

        VIR_TEST_DEBUG("QEMU driver capabilities:\n%s", caps_str);

        VIR_FREE(caps_str);
    }

    return caps;

 cleanup:
    caps->host.cpu = NULL;
    virCPUDefFree(cpuDefault);
    virCPUDefFree(cpuHaswell);
    virCPUDefFree(cpuPower8);
    virObjectUnref(caps);
    return NULL;
}
示例#13
0
static int testCompareXMLToArgvFiles(const char *xml,
                                     const char *cmdline,
                                     virQEMUCapsPtr extraFlags,
                                     const char *migrateFrom,
                                     int migrateFd,
                                     virQemuXML2ArgvTestFlags flags)
{
    char *expectargv = NULL;
    int len;
    char *actualargv = NULL;
    int ret = -1;
    virDomainDefPtr vmdef = NULL;
    virDomainChrSourceDef monitor_chr;
    virConnectPtr conn;
    char *log = NULL;
    virCommandPtr cmd = NULL;

    if (!(conn = virGetConnect()))
        goto out;
    conn->secretDriver = &fakeSecretDriver;

    if (!(vmdef = virDomainDefParseFile(xml, driver.caps, driver.xmlopt,
                                        QEMU_EXPECTED_VIRT_TYPES,
                                        VIR_DOMAIN_XML_INACTIVE))) {
        if (flags & FLAG_EXPECT_PARSE_ERROR)
            goto ok;
        goto out;
    }

    if (virQEMUCapsGet(extraFlags, QEMU_CAPS_DOMID))
        vmdef->id = 6;
    else
        vmdef->id = -1;

    memset(&monitor_chr, 0, sizeof(monitor_chr));
    monitor_chr.type = VIR_DOMAIN_CHR_TYPE_UNIX;
    monitor_chr.data.nix.path = (char *)"/tmp/test-monitor";
    monitor_chr.data.nix.listen = true;

    virQEMUCapsSetList(extraFlags,
                       QEMU_CAPS_VNC_COLON,
                       QEMU_CAPS_NO_REBOOT,
                       QEMU_CAPS_NO_ACPI,
                       QEMU_CAPS_LAST);

    if (STREQ(vmdef->os.machine, "pc") &&
        STREQ(vmdef->emulator, "/usr/bin/qemu-system-x86_64")) {
        VIR_FREE(vmdef->os.machine);
        if (VIR_STRDUP(vmdef->os.machine, "pc-0.11") < 0)
            goto out;
    }

    if (virQEMUCapsGet(extraFlags, QEMU_CAPS_DEVICE)) {
        if (qemuDomainAssignAddresses(vmdef, extraFlags, NULL)) {
            if (flags & FLAG_EXPECT_ERROR)
                goto ok;
            goto out;
        }
    }

    log = virtTestLogContentAndReset();
    VIR_FREE(log);
    virResetLastError();

    if (vmdef->os.arch == VIR_ARCH_X86_64 ||
        vmdef->os.arch == VIR_ARCH_I686) {
        virQEMUCapsSet(extraFlags, QEMU_CAPS_PCI_MULTIBUS);
    }

    if (qemuAssignDeviceAliases(vmdef, extraFlags) < 0)
        goto out;

    if (!(cmd = qemuBuildCommandLine(conn, &driver, vmdef, &monitor_chr,
                                     (flags & FLAG_JSON), extraFlags,
                                     migrateFrom, migrateFd, NULL,
                                     VIR_NETDEV_VPORT_PROFILE_OP_NO_OP,
                                     &testCallbacks))) {
        if (flags & FLAG_EXPECT_FAILURE) {
            ret = 0;
            if (virTestGetDebug() > 1)
                fprintf(stderr, "Got expected error: %s\n",
                        virGetLastErrorMessage());
            virResetLastError();
        }
        goto out;
    } else if (flags & FLAG_EXPECT_FAILURE) {
        if (virTestGetDebug())
            fprintf(stderr, "qemuBuildCommandLine should have failed\n");
        goto out;
    }

    if (!!virGetLastError() != !!(flags & FLAG_EXPECT_ERROR)) {
        if (virTestGetDebug() && (log = virtTestLogContentAndReset()))
            fprintf(stderr, "\n%s", log);
        goto out;
    }

    if (!(actualargv = virCommandToString(cmd)))
        goto out;

    len = virtTestLoadFile(cmdline, &expectargv);
    if (len < 0)
        goto out;
    if (len && expectargv[len - 1] == '\n')
        expectargv[len - 1] = '\0';

    if (STRNEQ(expectargv, actualargv)) {
        virtTestDifference(stderr, expectargv, actualargv);
        goto out;
    }

 ok:
    if (flags & FLAG_EXPECT_ERROR) {
        /* need to suppress the errors */
        virResetLastError();
    }

    ret = 0;

out:
    VIR_FREE(log);
    VIR_FREE(expectargv);
    VIR_FREE(actualargv);
    virCommandFree(cmd);
    virDomainDefFree(vmdef);
    virObjectUnref(conn);
    return ret;
}
示例#14
0
static int testCompareXMLToArgvFiles(const char *xml,
                                     const char *cmdfile,
                                     virQemuXML2ArgvTestFlags flags)
{
    char *expectxml = NULL;
    char *actualxml = NULL;
    char *cmd = NULL;
    char *log = NULL;
    int ret = -1;
    virDomainDefPtr vmdef = NULL;

    if (virtTestLoadFile(cmdfile, &cmd) < 0)
        goto fail;
    if (virtTestLoadFile(xml, &expectxml) < 0)
        goto fail;

    if (!(vmdef = qemuParseCommandLineString(driver.caps, driver.xmlopt,
                                             cmd, NULL, NULL, NULL)))
        goto fail;

    if (!virtTestOOMActive()) {
        if ((log = virtTestLogContentAndReset()) == NULL)
            goto fail;
        if (flags & FLAG_EXPECT_WARNING) {
            if (*log) {
                if (virTestGetDebug() > 1)
                    fprintf(stderr,
                            "Got expected warning from "
                            "qemuParseCommandLineString:\n%s",
                            log);
            } else {
                if (virTestGetDebug())
                    fprintf(stderr, "qemuParseCommandLineString "
                            "should have logged a warning\n");
                goto fail;
            }
        } else { /* didn't expect a warning */
            if (*log) {
                if (virTestGetDebug())
                    fprintf(stderr,
                            "Got unexpected warning from "
                            "qemuParseCommandLineString:\n%s",
                            log);
                goto fail;
            }
        }
    }

    if (!virDomainDefCheckABIStability(vmdef, vmdef)) {
        fprintf(stderr, "ABI stability check failed on %s", xml);
        goto fail;
    }

    if (!(actualxml = virDomainDefFormat(vmdef, 0)))
        goto fail;

    if (blankProblemElements(expectxml) < 0 ||
        blankProblemElements(actualxml) < 0)
        goto fail;

    if (STRNEQ(expectxml, actualxml)) {
        virtTestDifference(stderr, expectxml, actualxml);
        goto fail;
    }

    ret = 0;

 fail:
    VIR_FREE(expectxml);
    VIR_FREE(actualxml);
    VIR_FREE(cmd);
    VIR_FREE(log);
    virDomainDefFree(vmdef);
    return ret;
}
示例#15
0
static int testHelpStrParsing(const void *data)
{
    const struct testInfo *info = data;
    char *path = NULL;
    char *help = NULL;
    unsigned int version, kvm_version;
    bool is_kvm;
    virQEMUCapsPtr flags = NULL;
    int ret = -1;
    char *got = NULL;
    char *expected = NULL;

    if (virAsprintf(&path, "%s/qemuhelpdata/%s", abs_srcdir, info->name) < 0)
        return -1;

    if (virTestLoadFile(path, &help) < 0)
        goto cleanup;

    if (!(flags = virQEMUCapsNew()))
        goto cleanup;

    if (virQEMUCapsParseHelpStr("QEMU", help, flags,
                                &version, &is_kvm, &kvm_version, false, NULL) == -1) {
        if (info->error && virGetLastError()->code == info->error)
            ret = 0;
        goto cleanup;
    }

# ifndef WITH_YAJL
    if (virQEMUCapsGet(info->flags, QEMU_CAPS_MONITOR_JSON))
        virQEMUCapsSet(flags, QEMU_CAPS_MONITOR_JSON);
# endif

    VIR_FREE(path);
    VIR_FREE(help);
    if (virAsprintf(&path, "%s/qemuhelpdata/%s-device", abs_srcdir,
                    info->name) < 0)
        goto cleanup;

    if (virTestLoadFile(path, &help) < 0)
        goto cleanup;

    if (virQEMUCapsParseDeviceStr(flags, help) < 0)
        goto cleanup;

    got = virQEMUCapsFlagsString(flags);
    expected = virQEMUCapsFlagsString(info->flags);
    if (!got || !expected)
        goto cleanup;

    if (STRNEQ(got, expected)) {
        VIR_TEST_DEBUG("%s: computed flags do not match: got %s, expected %s\n",
            info->name, got, expected);

        if (virTestGetDebug())
            printMismatchedFlags(flags, info->flags);

        goto cleanup;
    }

    if (version != info->version) {
        fprintf(stderr, "%s: parsed versions do not match: got %u, expected %u\n",
                info->name, version, info->version);
        goto cleanup;
    }

    if (is_kvm != info->is_kvm) {
        fprintf(stderr,
                "%s: parsed is_kvm flag does not match: got %u, expected %u\n",
                info->name, is_kvm, info->is_kvm);
        goto cleanup;
    }

    if (kvm_version != info->kvm_version) {
        fprintf(stderr,
                "%s: parsed KVM versions do not match: got %u, expected %u\n",
                info->name, kvm_version, info->kvm_version);
        goto cleanup;
    }

    ret = 0;
 cleanup:
    VIR_FREE(path);
    VIR_FREE(help);
    virObjectUnref(flags);
    VIR_FREE(got);
    VIR_FREE(expected);
    return ret;
}
示例#16
0
static int testCompareXMLToArgvFiles(const char *xml,
                                     const char *cmdline,
                                     virQEMUCapsPtr extraFlags,
                                     const char *migrateFrom,
                                     int migrateFd,
                                     bool json,
                                     bool expectError)
{
    char *expectargv = NULL;
    int len;
    char *actualargv = NULL;
    int ret = -1;
    virDomainDefPtr vmdef = NULL;
    virDomainChrSourceDef monitor_chr;
    virConnectPtr conn;
    char *log = NULL;
    char *emulator = NULL;
    virCommandPtr cmd = NULL;

    if (!(conn = virGetConnect()))
        goto fail;

    len = virtTestLoadFile(cmdline, &expectargv);
    if (len < 0)
        goto fail;
    if (len && expectargv[len - 1] == '\n')
        expectargv[len - 1] = '\0';

    if (!(vmdef = virDomainDefParseFile(xml, driver.caps, driver.xmlopt,
                                        QEMU_EXPECTED_VIRT_TYPES,
                                        VIR_DOMAIN_XML_INACTIVE)))
        goto fail;

    /*
     * For test purposes, we may want to fake emulator's output by providing
     * our own script instead of a real emulator. For this to work we need to
     * specify a relative path in <emulator/> element, which, however, is not
     * allowed by RelaxNG schema for domain XML. To work around it we add an
     * extra '/' at the beginning of relative emulator path so that it looks
     * like, e.g., "/./qemu.sh" or "/../emulator/qemu.sh" instead of
     * "./qemu.sh" or "../emulator/qemu.sh" respectively. The following code
     * detects such paths, strips the extra '/' and makes the path absolute.
     */
    if (vmdef->emulator && STRPREFIX(vmdef->emulator, "/.")) {
        if (VIR_STRDUP(emulator, vmdef->emulator + 1) < 0)
            goto fail;
        VIR_FREE(vmdef->emulator);
        vmdef->emulator = NULL;
        if (virAsprintf(&vmdef->emulator, "%s/qemuxml2argvdata/%s",
                        abs_srcdir, emulator) < 0)
            goto fail;
    }

    if (virQEMUCapsGet(extraFlags, QEMU_CAPS_DOMID))
        vmdef->id = 6;
    else
        vmdef->id = -1;

    memset(&monitor_chr, 0, sizeof(monitor_chr));
    monitor_chr.type = VIR_DOMAIN_CHR_TYPE_UNIX;
    monitor_chr.data.nix.path = (char *)"/tmp/test-monitor";
    monitor_chr.data.nix.listen = true;

    virQEMUCapsSetList(extraFlags,
                       QEMU_CAPS_VNC_COLON,
                       QEMU_CAPS_NO_REBOOT,
                       QEMU_CAPS_NO_ACPI,
                       QEMU_CAPS_LAST);

    if (virQEMUCapsGet(extraFlags, QEMU_CAPS_DEVICE))
        qemuDomainAssignAddresses(vmdef, extraFlags, NULL);

    log = virtTestLogContentAndReset();
    VIR_FREE(log);
    virResetLastError();

    if (vmdef->os.arch == VIR_ARCH_X86_64 ||
        vmdef->os.arch == VIR_ARCH_I686) {
        virQEMUCapsSet(extraFlags, QEMU_CAPS_PCI_MULTIBUS);
    }

    if (qemuAssignDeviceAliases(vmdef, extraFlags) < 0)
        goto fail;

    if (!(cmd = qemuBuildCommandLine(conn, &driver,
                                     vmdef, &monitor_chr, json, extraFlags,
                                     migrateFrom, migrateFd, NULL,
                                     VIR_NETDEV_VPORT_PROFILE_OP_NO_OP,
                                     &testCallbacks)))
        goto fail;

    if (!!virGetLastError() != expectError) {
        if (virTestGetDebug() && (log = virtTestLogContentAndReset()))
            fprintf(stderr, "\n%s", log);
        goto fail;
    }

    if (expectError) {
        /* need to suppress the errors */
        virResetLastError();
    }

    if (!(actualargv = virCommandToString(cmd)))
        goto fail;

    if (emulator) {
        /* Skip the abs_srcdir portion of replacement emulator.  */
        char *start_skip = strstr(actualargv, abs_srcdir);
        char *end_skip = strstr(actualargv, emulator);
        if (!start_skip || !end_skip)
            goto fail;
        memmove(start_skip, end_skip, strlen(end_skip) + 1);
    }

    if (STRNEQ(expectargv, actualargv)) {
        virtTestDifference(stderr, expectargv, actualargv);
        goto fail;
    }

    ret = 0;

 fail:
    VIR_FREE(log);
    VIR_FREE(emulator);
    VIR_FREE(expectargv);
    VIR_FREE(actualargv);
    virCommandFree(cmd);
    virDomainDefFree(vmdef);
    virObjectUnref(conn);
    return ret;
}
示例#17
0
static int testCompareXMLToArgvFiles(const char *xml,
                                     const char *cmdline,
                                     virBitmapPtr extraFlags,
                                     const char *migrateFrom,
                                     int migrateFd,
                                     bool json,
                                     bool expectError)
{
    char *expectargv = NULL;
    int len;
    char *actualargv = NULL;
    int ret = -1;
    virDomainDefPtr vmdef = NULL;
    virDomainChrSourceDef monitor_chr;
    virConnectPtr conn;
    char *log = NULL;
    char *emulator = NULL;
    virCommandPtr cmd = NULL;

    if (!(conn = virGetConnect()))
        goto fail;

    len = virtTestLoadFile(cmdline, &expectargv);
    if (len < 0)
        goto fail;
    if (len && expectargv[len - 1] == '\n')
        expectargv[len - 1] = '\0';

    if (!(vmdef = virDomainDefParseFile(driver.caps, xml,
                                        QEMU_EXPECTED_VIRT_TYPES,
                                        VIR_DOMAIN_XML_INACTIVE)))
        goto fail;

    /*
     * For test purposes, we may want to fake emulator's output by providing
     * our own script instead of a real emulator. For this to work we need to
     * specify a relative path in <emulator/> element, which, however, is not
     * allowed by RelaxNG schema for domain XML. To work around it we add an
     * extra '/' at the beginning of relative emulator path so that it looks
     * like, e.g., "/./qemu.sh" or "/../emulator/qemu.sh" instead of
     * "./qemu.sh" or "../emulator/qemu.sh" respectively. The following code
     * detects such paths, strips the extra '/' and makes the path absolute.
     */
    if (vmdef->emulator && STRPREFIX(vmdef->emulator, "/.")) {
        if (!(emulator = strdup(vmdef->emulator + 1)))
            goto fail;
        free(vmdef->emulator);
        vmdef->emulator = NULL;
        if (virAsprintf(&vmdef->emulator, "%s/qemuxml2argvdata/%s",
                        abs_srcdir, emulator) < 0)
            goto fail;
    }

    if (qemuCapsGet(extraFlags, QEMU_CAPS_DOMID))
        vmdef->id = 6;
    else
        vmdef->id = -1;

    memset(&monitor_chr, 0, sizeof(monitor_chr));
    monitor_chr.type = VIR_DOMAIN_CHR_TYPE_UNIX;
    monitor_chr.data.nix.path = (char *)"/tmp/test-monitor";
    monitor_chr.data.nix.listen = true;

    qemuCapsSetList(extraFlags,
                    QEMU_CAPS_VNC_COLON,
                    QEMU_CAPS_NO_REBOOT,
                    QEMU_CAPS_LAST);

    if (qemudCanonicalizeMachine(&driver, vmdef) < 0)
        goto fail;

    if (qemuCapsGet(extraFlags, QEMU_CAPS_DEVICE)) {
        qemuDomainPCIAddressSetPtr pciaddrs;
        if (!(pciaddrs = qemuDomainPCIAddressSetCreate(vmdef)))
            goto fail;

        if (qemuAssignDevicePCISlots(vmdef, pciaddrs) < 0)
            goto fail;

        qemuDomainPCIAddressSetFree(pciaddrs);
    }


    free(virtTestLogContentAndReset());
    virResetLastError();

    /* We do not call qemuCapsExtractVersionInfo() before calling
     * qemuBuildCommandLine(), so we should set QEMU_CAPS_PCI_MULTIBUS for
     * x86_64 and i686 architectures here.
     */
    if (STREQLEN(vmdef->os.arch, "x86_64", 6) ||
        STREQLEN(vmdef->os.arch, "i686", 4)) {
        qemuCapsSet(extraFlags, QEMU_CAPS_PCI_MULTIBUS);
    }

    if (qemuAssignDeviceAliases(vmdef, extraFlags) < 0)
        goto fail;

    if (!(cmd = qemuBuildCommandLine(conn, &driver,
                                     vmdef, &monitor_chr, json, extraFlags,
                                     migrateFrom, migrateFd, NULL,
                                     VIR_VM_OP_NO_OP)))
        goto fail;

    if (!!virGetLastError() != expectError) {
        if (virTestGetDebug() && (log = virtTestLogContentAndReset()))
            fprintf(stderr, "\n%s", log);
        goto fail;
    }

    if (expectError) {
        /* need to suppress the errors */
        virResetLastError();
    }

    if (!(actualargv = virCommandToString(cmd)))
        goto fail;

    if (emulator) {
        /* Skip the abs_srcdir portion of replacement emulator.  */
        char *start_skip = strstr(actualargv, abs_srcdir);
        char *end_skip = strstr(actualargv, emulator);
        if (!start_skip || !end_skip)
            goto fail;
        memmove(start_skip, end_skip, strlen(end_skip) + 1);
    }

    if (STRNEQ(expectargv, actualargv)) {
        virtTestDifference(stderr, expectargv, actualargv);
        goto fail;
    }

    ret = 0;

 fail:
    free(log);
    free(emulator);
    free(expectargv);
    free(actualargv);
    virCommandFree(cmd);
    virDomainDefFree(vmdef);
    virUnrefConnect(conn);
    return ret;
}
示例#18
0
static int
mymain(void)
{
    int ret = 0;
    /* Some of our tests deliberately test failure cases, so
     * register a handler to stop error messages cluttering
     * up display
     */
    if (!virTestGetDebug())
        virSetErrorFunc(NULL, testQuietError);

#define DO_TEST_PARSE(addrstr, family, pass)                            \
    do {                                                                \
        virSocketAddr addr;                                             \
        struct testParseData data = { &addr, addrstr, family, pass };   \
        memset(&addr, 0, sizeof(addr));                                 \
        if (virtTestRun("Test parse " addrstr,                          \
                        1, testParseHelper, &data) < 0)                 \
            ret = -1;                                                   \
    } while (0)

#define DO_TEST_PARSE_AND_FORMAT(addrstr, family, pass)                 \
    do {                                                                \
        virSocketAddr addr;                                             \
        struct testParseData data = { &addr, addrstr, family, pass };   \
        memset(&addr, 0, sizeof(addr));                                 \
        if (virtTestRun("Test parse " addrstr " family " #family,       \
                        1, testParseHelper, &data) < 0)                 \
            ret = -1;                                                   \
        struct testFormatData data2 = { &addr, addrstr, pass };         \
        if (virtTestRun("Test format " addrstr " family " #family,      \
                        1, testFormatHelper, &data2) < 0)               \
            ret = -1;                                                   \
    } while (0)

#define DO_TEST_RANGE(saddr, eaddr, size, pass)                         \
    do {                                                                \
        struct testRangeData data = { saddr, eaddr, size, pass };       \
        if (virtTestRun("Test range " saddr " -> " eaddr " size " #size, \
                        1, testRangeHelper, &data) < 0)                 \
            ret = -1;                                                   \
    } while (0)

#define DO_TEST_NETMASK(addr1, addr2, netmask, pass)                    \
    do {                                                                \
        struct testNetmaskData data = { addr1, addr2, netmask, pass };  \
        if (virtTestRun("Test netmask " addr1 " + " addr2 " in " netmask, \
                        1, testNetmaskHelper, &data) < 0)               \
            ret = -1;                                                   \
    } while (0)


    DO_TEST_PARSE_AND_FORMAT("127.0.0.1", AF_UNSPEC, true);
    DO_TEST_PARSE_AND_FORMAT("127.0.0.1", AF_INET, true);
    DO_TEST_PARSE_AND_FORMAT("127.0.0.1", AF_INET6, false);
    DO_TEST_PARSE_AND_FORMAT("127.0.0.1", AF_UNIX, false);
    DO_TEST_PARSE_AND_FORMAT("127.0.0.256", AF_UNSPEC, false);

    DO_TEST_PARSE_AND_FORMAT("::1", AF_UNSPEC, true);
    DO_TEST_PARSE_AND_FORMAT("::1", AF_INET, false);
    DO_TEST_PARSE_AND_FORMAT("::1", AF_INET6, true);
    DO_TEST_PARSE_AND_FORMAT("::1", AF_UNIX, false);
    DO_TEST_PARSE_AND_FORMAT("::ffff", AF_UNSPEC, true);

    DO_TEST_RANGE("192.168.122.1", "192.168.122.1", 1, true);
    DO_TEST_RANGE("192.168.122.1", "192.168.122.20", 20, true);
    DO_TEST_RANGE("192.168.122.0", "192.168.122.255", 256, true);
    DO_TEST_RANGE("192.168.122.20", "192.168.122.1", -1, false);
    DO_TEST_RANGE("10.0.0.1", "192.168.122.20", -1, false);
    DO_TEST_RANGE("192.168.122.20", "10.0.0.1", -1, false);

    DO_TEST_RANGE("2000::1", "2000::1", 1, true);
    DO_TEST_RANGE("2000::1", "2000::2", 2, true);
    DO_TEST_RANGE("2000::2", "2000::1", -1, false);
    DO_TEST_RANGE("2000::1", "9001::1", -1, false);

    DO_TEST_NETMASK("192.168.122.1", "192.168.122.2",
                    "255.255.255.0", true);
    DO_TEST_NETMASK("192.168.122.1", "192.168.122.4",
                    "255.255.255.248", true);
    DO_TEST_NETMASK("192.168.122.1", "192.168.123.2",
                    "255.255.255.0", false);
    DO_TEST_NETMASK("192.168.122.1", "192.168.123.2",
                    "255.255.0.0", true);

    DO_TEST_NETMASK("2000::1:1", "2000::1:1",
                    "ffff:ffff:ffff:ffff:ffff:ffff:ffff:0", true);
    DO_TEST_NETMASK("2000::1:1", "2000::2:1",
                    "ffff:ffff:ffff:ffff:ffff:ffff:ffff:0", false);
    DO_TEST_NETMASK("2000::1:1", "2000::2:1",
                    "ffff:ffff:ffff:ffff:ffff:ffff:fff8:0", true);
    DO_TEST_NETMASK("2000::1:1", "9000::1:1",
                    "ffff:ffff:ffff:ffff:ffff:ffff:ffff:0", false);

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