domaincapstest.c 18.0 KB
Newer Older
M
Michal Privoznik 已提交
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
/*
 * Copyright (C) Red Hat, Inc. 2014
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library.  If not, see
 * <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *      Michal Privoznik <mprivozn@redhat.com>
 */

#include <config.h>
#include <stdlib.h>

#include "testutils.h"
#include "domain_capabilities.h"


#define VIR_FROM_THIS VIR_FROM_NONE

31 32
typedef int (*virDomainCapsFill)(virDomainCapsPtr domCaps,
                                 void *opaque);
M
Michal Privoznik 已提交
33 34 35 36

#define SET_ALL_BITS(x) \
    memset(&(x.values), 0xff, sizeof(x.values))

37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
static int ATTRIBUTE_SENTINEL
fillStringValues(virDomainCapsStringValuesPtr values, ...)
{
    int ret = 0;
    va_list list;
    const char *str;

    va_start(list, values);
    while ((str = va_arg(list, const char *))) {
        if (VIR_REALLOC_N(values->values, values->nvalues + 1) < 0 ||
            VIR_STRDUP(values->values[values->nvalues], str) < 0) {
            ret = -1;
            break;
        }
        values->nvalues++;
    }
    va_end(list);

    return ret;
}

58
static int
J
Jiri Denemark 已提交
59
fillAllCaps(virDomainCapsPtr domCaps)
M
Michal Privoznik 已提交
60
{
61 62
    virDomainCapsOSPtr os = &domCaps->os;
    virDomainCapsLoaderPtr loader = &os->loader;
63
    virDomainCapsCPUPtr cpu = &domCaps->cpu;
M
Michal Privoznik 已提交
64
    virDomainCapsDeviceDiskPtr disk = &domCaps->disk;
65
    virDomainCapsDeviceGraphicsPtr graphics = &domCaps->graphics;
66
    virDomainCapsDeviceVideoPtr video = &domCaps->video;
M
Michal Privoznik 已提交
67
    virDomainCapsDeviceHostdevPtr hostdev = &domCaps->hostdev;
68
    virCPUDef host = {
69 70 71 72
        .type = VIR_CPU_TYPE_HOST,
        .arch = VIR_ARCH_X86_64,
        .model = (char *) "host",
        .vendor = (char *) "CPU Vendorrr",
73
    };
M
Michal Privoznik 已提交
74

75
    domCaps->maxvcpus = 255;
76
    os->supported = true;
77

78
    loader->supported = true;
79 80
    SET_ALL_BITS(loader->type);
    SET_ALL_BITS(loader->readonly);
81 82 83 84 85
    if (fillStringValues(&loader->values,
                         "/foo/bar",
                         "/tmp/my_path",
                         NULL) < 0)
        return -1;
86

87
    cpu->hostPassthrough = true;
88
    cpu->hostModel = virCPUDefCopy(&host);
89
    if (!(cpu->custom = virDomainCapsCPUModelsNew(3)) ||
J
Jiri Denemark 已提交
90 91 92 93 94 95
        virDomainCapsCPUModelsAdd(cpu->custom, "Model1", -1,
                                  VIR_DOMCAPS_CPU_USABLE_UNKNOWN) < 0 ||
        virDomainCapsCPUModelsAdd(cpu->custom, "Model2", -1,
                                  VIR_DOMCAPS_CPU_USABLE_NO) < 0 ||
        virDomainCapsCPUModelsAdd(cpu->custom, "Model3", -1,
                                  VIR_DOMCAPS_CPU_USABLE_YES) < 0)
96 97
        return -1;

98
    disk->supported = true;
M
Michal Privoznik 已提交
99 100 101
    SET_ALL_BITS(disk->diskDevice);
    SET_ALL_BITS(disk->bus);

102 103 104
    graphics->supported = true;
    SET_ALL_BITS(graphics->type);

105 106 107
    video->supported = true;
    SET_ALL_BITS(video->modelType);

108
    hostdev->supported = true;
M
Michal Privoznik 已提交
109 110 111 112 113
    SET_ALL_BITS(hostdev->mode);
    SET_ALL_BITS(hostdev->startupPolicy);
    SET_ALL_BITS(hostdev->subsysType);
    SET_ALL_BITS(hostdev->capsType);
    SET_ALL_BITS(hostdev->pciBackend);
114
    return 0;
M
Michal Privoznik 已提交
115 116
}

117

J
Jiri Denemark 已提交
118
#if WITH_QEMU
119
# include "testutilsqemu.h"
120

121
static virCPUDef aarch64Cpu = {
122 123 124
    .sockets = 1,
    .cores = 1,
    .threads = 1,
125 126 127
};

static virCPUDef ppc64leCpu = {
128 129 130 131 132 133
    .type = VIR_CPU_TYPE_HOST,
    .arch = VIR_ARCH_PPC64LE,
    .model = (char *) "POWER8",
    .sockets = 1,
    .cores = 1,
    .threads = 1,
134 135 136
};

static virCPUDef x86Cpu = {
137 138 139 140 141 142
    .type = VIR_CPU_TYPE_HOST,
    .arch = VIR_ARCH_X86_64,
    .model = (char *) "Broadwell",
    .sockets = 1,
    .cores = 1,
    .threads = 1,
143 144
};

145
static virCPUDef s390Cpu = {
146 147 148 149 150
    .type = VIR_CPU_TYPE_HOST,
    .arch = VIR_ARCH_S390X,
    .sockets = 1,
    .cores = 1,
    .threads = 1,
151 152
};

153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171
static int
fakeHostCPU(virCapsPtr caps,
            virArch arch)
{
    virCPUDefPtr cpu;

    switch (arch) {
    case VIR_ARCH_AARCH64:
        cpu = &aarch64Cpu;
        break;

    case VIR_ARCH_PPC64LE:
        cpu = &ppc64leCpu;
        break;

    case VIR_ARCH_X86_64:
        cpu = &x86Cpu;
        break;

172 173 174 175
    case VIR_ARCH_S390X:
        cpu = &s390Cpu;
        break;

176 177 178 179 180 181 182 183 184 185 186 187 188
    default:
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       "cannot fake host CPU for arch %s",
                       virArchToString(arch));
        return -1;
    }

    if (!(caps->host.cpu = virCPUDefCopy(cpu)))
        return -1;

    return 0;
}

189
static int
190
fillQemuCaps(virDomainCapsPtr domCaps,
J
Jiri Denemark 已提交
191
             const char *name,
J
Jiri Denemark 已提交
192
             const char *arch,
193
             const char *machine,
J
Jiri Denemark 已提交
194
             virQEMUDriverConfigPtr cfg)
195
{
J
Jiri Denemark 已提交
196 197
    int ret = -1;
    char *path = NULL;
198
    virCapsPtr caps = NULL;
J
Jiri Denemark 已提交
199
    virQEMUCapsPtr qemuCaps = NULL;
200
    virDomainCapsLoaderPtr loader = &domCaps->os.loader;
201

202 203 204 205
    if (!(caps = virCapabilitiesNew(domCaps->arch, false, false)) ||
        fakeHostCPU(caps, domCaps->arch) < 0)
        goto cleanup;

206
    if (virAsprintf(&path, "%s/qemucapabilitiesdata/%s.%s.xml",
J
Jiri Denemark 已提交
207
                    abs_srcdir, name, arch) < 0 ||
208
        !(qemuCaps = qemuTestParseCapabilities(caps, path)))
J
Jiri Denemark 已提交
209 210
        goto cleanup;

211 212 213 214 215 216 217 218 219 220
    if (machine &&
        VIR_STRDUP(domCaps->machine,
                   virQEMUCapsGetCanonicalMachine(qemuCaps, machine)) < 0)
        goto cleanup;

    if (!domCaps->machine &&
        VIR_STRDUP(domCaps->machine,
                   virQEMUCapsGetDefaultMachine(qemuCaps)) < 0)
        goto cleanup;

221
    if (virQEMUCapsFillDomainCaps(caps, domCaps, qemuCaps,
222
                                  cfg->firmwares,
223
                                  cfg->nfirmwares) < 0)
J
Jiri Denemark 已提交
224
        goto cleanup;
225 226 227 228 229 230 231 232 233 234

    /* The function above tries to query host's KVM & VFIO capabilities by
     * calling qemuHostdevHostSupportsPassthroughLegacy() and
     * qemuHostdevHostSupportsPassthroughVFIO() which, however, can't be
     * successfully mocked as they are not exposed as internal APIs. Therefore,
     * instead of mocking set the expected values here by hand. */
    VIR_DOMAIN_CAPS_ENUM_SET(domCaps->hostdev.pciBackend,
                             VIR_DOMAIN_HOSTDEV_PCI_BACKEND_DEFAULT,
                             VIR_DOMAIN_HOSTDEV_PCI_BACKEND_KVM,
                             VIR_DOMAIN_HOSTDEV_PCI_BACKEND_VFIO);
235

J
Jiri Denemark 已提交
236 237
    /* As of f05b6a918e28 we are expecting to see OVMF_CODE.fd file which
     * may not exists everywhere. */
238 239 240 241
    while (loader->values.nvalues)
        VIR_FREE(loader->values.values[--loader->values.nvalues]);

    if (fillStringValues(&loader->values,
242
                         "/usr/share/AAVMF/AAVMF_CODE.fd",
243 244
                         "/usr/share/OVMF/OVMF_CODE.fd",
                         NULL) < 0)
M
Michal Privoznik 已提交
245 246
        goto cleanup;

J
Jiri Denemark 已提交
247
    ret = 0;
M
Michal Privoznik 已提交
248
 cleanup:
249
    virObjectUnref(caps);
J
Jiri Denemark 已提交
250 251
    virObjectUnref(qemuCaps);
    VIR_FREE(path);
252
    return ret;
M
Michal Privoznik 已提交
253
}
J
Jiri Denemark 已提交
254 255 256
#endif /* WITH_QEMU */


257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285
#ifdef WITH_LIBXL
# include "testutilsxen.h"

static int
fillXenCaps(virDomainCapsPtr domCaps)
{
    virFirmwarePtr *firmwares;
    int ret = -1;

    if (VIR_ALLOC_N(firmwares, 2) < 0)
        return ret;

    if (VIR_ALLOC(firmwares[0]) < 0 || VIR_ALLOC(firmwares[1]) < 0)
        goto cleanup;
    if (VIR_STRDUP(firmwares[0]->name, "/usr/lib/xen/boot/hvmloader") < 0 ||
        VIR_STRDUP(firmwares[1]->name, "/usr/lib/xen/boot/ovmf.bin") < 0)
        goto cleanup;

    if (libxlMakeDomainCapabilities(domCaps, firmwares, 2) < 0)
        goto cleanup;

    ret = 0;

 cleanup:
    virFirmwareFreeList(firmwares, 2);
    return ret;
}
#endif /* WITH_LIBXL */

286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309
#ifdef WITH_BHYVE
# include "bhyve/bhyve_capabilities.h"

static int
fillBhyveCaps(virDomainCapsPtr domCaps, unsigned int *bhyve_caps)
{
    virDomainCapsStringValuesPtr firmwares = NULL;
    int ret = -1;

    if (VIR_ALLOC(firmwares) < 0)
        return -1;

    if (fillStringValues(firmwares, "/foo/bar", "/foo/baz", NULL) < 0)
        goto cleanup;

    if (virBhyveDomainCapsFill(domCaps, *bhyve_caps, firmwares) < 0)
        goto cleanup;

    ret = 0;
 cleanup:
    VIR_FREE(firmwares);
    return ret;
}
#endif /* WITH_BHYVE */
310

J
Jiri Denemark 已提交
311 312 313 314
enum testCapsType {
    CAPS_NONE,
    CAPS_ALL,
    CAPS_QEMU,
315
    CAPS_LIBXL,
316
    CAPS_BHYVE,
J
Jiri Denemark 已提交
317
};
M
Michal Privoznik 已提交
318

J
Jiri Denemark 已提交
319 320 321
struct testData {
    const char *name;
    const char *emulator;
M
Michal Privoznik 已提交
322
    const char *machine;
J
Jiri Denemark 已提交
323
    const char *arch;
M
Michal Privoznik 已提交
324
    virDomainVirtType type;
J
Jiri Denemark 已提交
325 326 327
    enum testCapsType capsType;
    const char *capsName;
    void *capsOpaque;
M
Michal Privoznik 已提交
328 329 330 331 332
};

static int
test_virDomainCapsFormat(const void *opaque)
{
J
Jiri Denemark 已提交
333
    const struct testData *data = opaque;
M
Michal Privoznik 已提交
334 335 336 337 338
    virDomainCapsPtr domCaps = NULL;
    char *path = NULL;
    char *domCapsXML = NULL;
    int ret = -1;

339
    if (virAsprintf(&path, "%s/domaincapsschemadata/%s.xml",
J
Jiri Denemark 已提交
340
                    abs_srcdir, data->name) < 0)
M
Michal Privoznik 已提交
341 342
        goto cleanup;

J
Jiri Denemark 已提交
343 344
    if (!(domCaps = virDomainCapsNew(data->emulator, data->machine,
                                     virArchFromString(data->arch),
J
Jiri Denemark 已提交
345
                                     data->type)))
M
Michal Privoznik 已提交
346 347
        goto cleanup;

J
Jiri Denemark 已提交
348 349 350 351 352 353 354 355 356 357 358
    switch (data->capsType) {
    case CAPS_NONE:
        break;

    case CAPS_ALL:
        if (fillAllCaps(domCaps) < 0)
            goto cleanup;
        break;

    case CAPS_QEMU:
#if WITH_QEMU
359
        if (fillQemuCaps(domCaps, data->capsName, data->arch, data->machine,
360
                         data->capsOpaque) < 0)
J
Jiri Denemark 已提交
361
            goto cleanup;
362 363 364 365 366 367 368
#endif
        break;

    case CAPS_LIBXL:
#if WITH_LIBXL
        if (fillXenCaps(domCaps) < 0)
            goto cleanup;
369 370 371 372 373 374
#endif
        break;
    case CAPS_BHYVE:
#if WITH_BHYVE
        if (fillBhyveCaps(domCaps, data->capsOpaque) < 0)
            goto cleanup;
J
Jiri Denemark 已提交
375 376 377 378
#endif
        break;
    }

M
Michal Privoznik 已提交
379 380 381
    if (!(domCapsXML = virDomainCapsFormat(domCaps)))
        goto cleanup;

382
    if (virTestCompareToFile(domCapsXML, path) < 0)
M
Michal Privoznik 已提交
383 384 385 386 387 388 389 390 391 392 393 394 395 396 397
        goto cleanup;

    ret = 0;
 cleanup:
    VIR_FREE(domCapsXML);
    VIR_FREE(path);
    virObjectUnref(domCaps);
    return ret;
}

static int
mymain(void)
{
    int ret = 0;

398 399 400 401
#if WITH_BHYVE
    unsigned int bhyve_caps = 0;
#endif

J
Jiri Denemark 已提交
402
#if WITH_QEMU
403 404
    virQEMUDriverConfigPtr cfg = virQEMUDriverConfigNew(false);

405 406
    if (!cfg)
        return EXIT_FAILURE;
J
Jiri Denemark 已提交
407 408 409 410 411 412 413 414 415 416 417 418
#endif

#define DO_TEST(Name, Emulator, Machine, Arch, Type, CapsType)          \
    do {                                                                \
        struct testData data = {                                        \
            .name = Name,                                               \
            .emulator = Emulator,                                       \
            .machine = Machine,                                         \
            .arch = Arch,                                               \
            .type = Type,                                               \
            .capsType = CapsType,                                       \
        };                                                              \
419
        if (virTestRun(Name, test_virDomainCapsFormat, &data) < 0)      \
J
Jiri Denemark 已提交
420 421
            ret = -1;                                                   \
    } while (0)
422

J
Jiri Denemark 已提交
423 424
#define DO_TEST_QEMU(Name, CapsName, Emulator, Machine, Arch, Type)     \
    do {                                                                \
425 426 427 428 429 430 431 432
        char *name = NULL;                                              \
        if (virAsprintf(&name, "qemu_%s%s%s.%s",                        \
                        Name,                                           \
                        Machine ? "-" : "", Machine ? Machine : "",     \
                        Arch) < 0) {                                    \
            ret = -1;                                                   \
            break;                                                      \
        }                                                               \
J
Jiri Denemark 已提交
433
        struct testData data = {                                        \
434
            .name = name,                                               \
J
Jiri Denemark 已提交
435 436 437 438 439 440 441 442
            .emulator = Emulator,                                       \
            .machine = Machine,                                         \
            .arch = Arch,                                               \
            .type = Type,                                               \
            .capsType = CAPS_QEMU,                                      \
            .capsName = CapsName,                                       \
            .capsOpaque = cfg,                                          \
        };                                                              \
443
        if (virTestRun(name, test_virDomainCapsFormat, &data) < 0)      \
J
Jiri Denemark 已提交
444
            ret = -1;                                                   \
445
        VIR_FREE(name);                                                 \
446 447
    } while (0)

448 449 450 451 452 453 454 455 456 457 458 459 460 461
#define DO_TEST_LIBXL(Name, Emulator, Machine, Arch, Type)              \
    do {                                                                \
        struct testData data = {                                        \
            .name = Name,                                               \
            .emulator = Emulator,                                       \
            .machine = Machine,                                         \
            .arch = Arch,                                               \
            .type = Type,                                               \
            .capsType = CAPS_LIBXL,                                     \
        };                                                              \
        if (virTestRun(Name, test_virDomainCapsFormat, &data) < 0)     \
            ret = -1;                                                   \
    } while (0)

J
Jiri Denemark 已提交
462
    DO_TEST("basic", "/bin/emulatorbin", "my-machine-type",
J
Jiri Denemark 已提交
463
            "x86_64", VIR_DOMAIN_VIRT_UML, CAPS_NONE);
J
Jiri Denemark 已提交
464
    DO_TEST("full", "/bin/emulatorbin", "my-machine-type",
J
Jiri Denemark 已提交
465
            "x86_64", VIR_DOMAIN_VIRT_KVM, CAPS_ALL);
J
Jiri Denemark 已提交
466

467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486
#define DO_TEST_BHYVE(Name, Emulator, BhyveCaps, Type) \
    do {                                                                \
        char *name = NULL;                                              \
        if (virAsprintf(&name, "bhyve_%s.x86_64", Name) < 0) {          \
             ret = -1;                                                  \
             break;                                                     \
        }                                                               \
        struct testData data = {                                        \
            .name = name,                                               \
            .emulator = Emulator,                                       \
            .arch = "x86_64",                                           \
            .type = Type,                                               \
            .capsType = CAPS_BHYVE,                                     \
            .capsOpaque = BhyveCaps,                                    \
        };                                                              \
        if (virTestRun(name, test_virDomainCapsFormat, &data) < 0)      \
            ret = -1;                                                   \
        VIR_FREE(name);                                                 \
    } while (0)

J
Jiri Denemark 已提交
487 488
#if WITH_QEMU

489
    DO_TEST_QEMU("1.7.0", "caps_1.7.0",
490
                 "/usr/bin/qemu-system-x86_64", NULL,
491
                 "x86_64", VIR_DOMAIN_VIRT_KVM);
492

493
    DO_TEST_QEMU("2.6.0", "caps_2.6.0",
494
                 "/usr/bin/qemu-system-x86_64", NULL,
495
                 "x86_64", VIR_DOMAIN_VIRT_KVM);
496

497
    DO_TEST_QEMU("2.6.0", "caps_2.6.0-gicv2",
498
                 "/usr/bin/qemu-system-aarch64", NULL,
499
                 "aarch64", VIR_DOMAIN_VIRT_KVM);
500

501
    DO_TEST_QEMU("2.6.0-gicv2", "caps_2.6.0-gicv2",
502
                 "/usr/bin/qemu-system-aarch64", "virt",
503
                 "aarch64", VIR_DOMAIN_VIRT_KVM);
504

505
    DO_TEST_QEMU("2.6.0-gicv3", "caps_2.6.0-gicv3",
506
                 "/usr/bin/qemu-system-aarch64", "virt",
507
                 "aarch64", VIR_DOMAIN_VIRT_KVM);
508

509
    DO_TEST_QEMU("2.6.0", "caps_2.6.0",
510
                 "/usr/bin/qemu-system-ppc64", NULL,
511
                 "ppc64le", VIR_DOMAIN_VIRT_KVM);
512

513 514 515 516 517 518 519 520
    DO_TEST_QEMU("2.8.0", "caps_2.8.0",
                 "/usr/bin/qemu-system-x86_64", NULL,
                 "x86_64", VIR_DOMAIN_VIRT_KVM);

    DO_TEST_QEMU("2.8.0-tcg", "caps_2.8.0",
                 "/usr/bin/qemu-system-x86_64", NULL,
                 "x86_64", VIR_DOMAIN_VIRT_QEMU);

521 522 523 524 525 526 527 528
    DO_TEST_QEMU("2.9.0", "caps_2.9.0",
                 "/usr/bin/qemu-system-x86_64", NULL,
                 "x86_64", VIR_DOMAIN_VIRT_KVM);

    DO_TEST_QEMU("2.9.0-tcg", "caps_2.9.0",
                 "/usr/bin/qemu-system-x86_64", NULL,
                 "x86_64", VIR_DOMAIN_VIRT_QEMU);

529 530 531 532 533 534 535 536
    DO_TEST_QEMU("2.7.0", "caps_2.7.0",
                 "/usr/bin/qemu-system-s390x", NULL,
                 "s390x", VIR_DOMAIN_VIRT_KVM);

    DO_TEST_QEMU("2.8.0", "caps_2.8.0",
                 "/usr/bin/qemu-system-s390x", NULL,
                 "s390x", VIR_DOMAIN_VIRT_KVM);

537 538
#endif /* WITH_QEMU */

539 540
#if WITH_LIBXL

541 542 543 544 545 546 547 548 549
# ifdef LIBXL_HAVE_PVUSB
#  define LIBXL_XENPV_CAPS "libxl-xenpv-usb"
#  define LIBXL_XENFV_CAPS "libxl-xenfv-usb"
# else
#  define LIBXL_XENPV_CAPS "libxl-xenpv"
#  define LIBXL_XENFV_CAPS "libxl-xenfv"
# endif

    DO_TEST_LIBXL(LIBXL_XENPV_CAPS, "/usr/bin/qemu-system-x86_64",
550
                  "xenpv", "x86_64", VIR_DOMAIN_VIRT_XEN);
551
    DO_TEST_LIBXL(LIBXL_XENFV_CAPS, "/usr/bin/qemu-system-x86_64",
552 553 554 555
                  "xenfv", "x86_64", VIR_DOMAIN_VIRT_XEN);

#endif /* WITH_LIBXL */

556 557 558 559 560 561 562 563 564 565
#if WITH_BHYVE
    DO_TEST_BHYVE("basic", "/usr/sbin/bhyve", &bhyve_caps, VIR_DOMAIN_VIRT_BHYVE);

    bhyve_caps |= BHYVE_CAP_LPC_BOOTROM;
    DO_TEST_BHYVE("uefi", "/usr/sbin/bhyve", &bhyve_caps, VIR_DOMAIN_VIRT_BHYVE);

    bhyve_caps |= BHYVE_CAP_FBUF;
    DO_TEST_BHYVE("fbuf", "/usr/sbin/bhyve", &bhyve_caps, VIR_DOMAIN_VIRT_BHYVE);
#endif /* WITH_BHYVE */

M
Michal Privoznik 已提交
566 567 568
    return ret;
}

569
#if WITH_QEMU
570
VIR_TEST_MAIN_PRELOAD(mymain,
571 572 573
                       abs_builddir "/.libs/domaincapsmock.so",
                       abs_builddir "/.libs/qemucpumock.so")
#else
574
VIR_TEST_MAIN_PRELOAD(mymain, abs_builddir "/.libs/domaincapsmock.so")
575
#endif