cputest.c 20.9 KB
Newer Older
1 2 3
/*
 * cputest.c: Test the libvirtd internal CPU APIs
 *
4
 * Copyright (C) 2010-2014 Red Hat, Inc.
5 6 7 8 9 10 11 12 13 14 15 16
 *
 * 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
17
 * License along with this library.  If not, see
O
Osier Yang 已提交
18
 * <http://www.gnu.org/licenses/>.
19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
 *
 * Author: Jiri Denemark <jdenemar@redhat.com>
 */

#include <config.h>

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

#include <sys/types.h>
#include <fcntl.h>

#include "internal.h"
34
#include "virxml.h"
35
#include "viralloc.h"
36
#include "virbuffer.h"
37 38 39 40
#include "testutils.h"
#include "cpu_conf.h"
#include "cpu/cpu.h"
#include "cpu/cpu_map.h"
41
#include "virstring.h"
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

#define VIR_FROM_THIS VIR_FROM_CPU

enum cpuTestBoolWithError {
    FAIL    = -1,
    NO      = 0,
    YES     = 1
};

enum api {
    API_COMPARE,
    API_GUEST_DATA,
    API_BASELINE,
    API_UPDATE,
    API_HAS_FEATURE
};

static const char *apis[] = {
    "compare",
    "guest data",
    "baseline",
    "update",
    "has feature"
};

struct data {
    const char *arch;
    enum api api;
    const char *host;
    const char *name;
    const char **models;
    const char *modelsName;
    unsigned int nmodels;
    const char *preferred;
76
    unsigned int flags;
77 78 79 80 81 82 83
    int result;
};


static virCPUDefPtr
cpuTestLoadXML(const char *arch, const char *name)
{
84
    char *xml = NULL;
85 86 87 88
    xmlDocPtr doc = NULL;
    xmlXPathContextPtr ctxt = NULL;
    virCPUDefPtr cpu = NULL;

89 90
    if (virAsprintf(&xml, "%s/cputestdata/%s-%s.xml", abs_srcdir, arch, name) < 0)
        goto cleanup;
91

92
    if (!(doc = virXMLParseFileCtxt(xml, &ctxt)))
93 94 95 96
        goto cleanup;

    cpu = virCPUDefParseXML(ctxt->node, ctxt, VIR_CPU_TYPE_AUTO);

97
 cleanup:
98 99
    xmlXPathFreeContext(ctxt);
    xmlFreeDoc(doc);
100
    VIR_FREE(xml);
101 102 103 104 105 106 107 108 109
    return cpu;
}


static virCPUDefPtr *
cpuTestLoadMultiXML(const char *arch,
                    const char *name,
                    unsigned int *count)
{
110
    char *xml = NULL;
111 112 113 114 115
    xmlDocPtr doc = NULL;
    xmlXPathContextPtr ctxt = NULL;
    xmlNodePtr *nodes = NULL;
    virCPUDefPtr *cpus = NULL;
    int n;
116
    size_t i;
117

118 119
    if (virAsprintf(&xml, "%s/cputestdata/%s-%s.xml", abs_srcdir, arch, name) < 0)
        goto cleanup;
120

121
    if (!(doc = virXMLParseFileCtxt(xml, &ctxt)))
J
Jiri Denemark 已提交
122
        goto cleanup;
123 124

    n = virXPathNodeSet("/cpuTest/cpu", ctxt, &nodes);
125 126
    if (n <= 0 || (VIR_ALLOC_N(cpus, n) < 0)) {
        fprintf(stderr, "\nNo /cpuTest/cpu elements found in %s\n", xml);
J
Jiri Denemark 已提交
127
        goto cleanup;
128
    }
129 130 131 132 133

    for (i = 0; i < n; i++) {
        ctxt->node = nodes[i];
        cpus[i] = virCPUDefParseXML(nodes[i], ctxt, VIR_CPU_TYPE_HOST);
        if (!cpus[i])
J
Jiri Denemark 已提交
134
            goto cleanup_cpus;
135 136 137 138
    }

    *count = n;

139
 cleanup:
140 141
    VIR_FREE(xml);
    VIR_FREE(nodes);
142 143 144 145
    xmlXPathFreeContext(ctxt);
    xmlFreeDoc(doc);
    return cpus;

146
 cleanup_cpus:
J
Jiri Denemark 已提交
147 148 149
    for (i = 0; i < n; i++)
        virCPUDefFree(cpus[i]);
    VIR_FREE(cpus);
150 151 152 153 154 155
    goto cleanup;
}


static int
cpuTestCompareXML(const char *arch,
E
Eric Blake 已提交
156
                  virCPUDef *cpu,
157
                  const char *name,
158
                  bool updateCPU)
159
{
160
    char *xml = NULL;
161 162 163
    char *actual = NULL;
    int ret = -1;

164 165 166
    if (virAsprintf(&xml, "%s/cputestdata/%s-%s.xml",
                    abs_srcdir, arch, name) < 0)
        goto cleanup;
167

168
    if (!(actual = virCPUDefFormat(cpu, NULL, updateCPU)))
169 170
        goto cleanup;

C
Cole Robinson 已提交
171
    if (virtTestCompareToFile(actual, xml) < 0)
172 173 174 175
        goto cleanup;

    ret = 0;

176
 cleanup:
177 178
    VIR_FREE(xml);
    VIR_FREE(actual);
179 180 181 182 183 184 185 186 187 188 189 190
    return ret;
}


static const char *
cpuTestCompResStr(virCPUCompareResult result)
{
    switch (result) {
    case VIR_CPU_COMPARE_ERROR:         return "ERROR";
    case VIR_CPU_COMPARE_INCOMPATIBLE:  return "INCOMPATIBLE";
    case VIR_CPU_COMPARE_IDENTICAL:     return "IDENTICAL";
    case VIR_CPU_COMPARE_SUPERSET:      return "SUPERSET";
191
    case VIR_CPU_COMPARE_LAST:          break;
192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223
    }

    return "unknown";
}


static const char *
cpuTestBoolWithErrorStr(enum cpuTestBoolWithError result)
{
    switch (result) {
    case FAIL:  return "FAIL";
    case NO:    return "NO";
    case YES:   return "YES";
    }

    return "unknown";
}


static int
cpuTestCompare(const void *arg)
{
    const struct data *data = arg;
    int ret = -1;
    virCPUDefPtr host = NULL;
    virCPUDefPtr cpu = NULL;
    virCPUCompareResult result;

    if (!(host = cpuTestLoadXML(data->arch, data->host)) ||
        !(cpu = cpuTestLoadXML(data->arch, data->name)))
        goto cleanup;

224
    result = cpuCompare(host, cpu, false);
225 226 227 228
    if (data->result == VIR_CPU_COMPARE_ERROR)
        virResetLastError();

    if (data->result != result) {
229
        VIR_TEST_VERBOSE("\nExpected result %s, got %s\n",
230 231
                    cpuTestCompResStr(data->result),
                    cpuTestCompResStr(result));
232 233
        /* Pad to line up with test name ... in virTestRun */
        VIR_TEST_VERBOSE("%74s", "... ");
234 235 236 237 238
        goto cleanup;
    }

    ret = 0;

239
 cleanup:
240 241 242 243 244 245 246 247 248 249 250 251 252 253
    virCPUDefFree(host);
    virCPUDefFree(cpu);
    return ret;
}


static int
cpuTestGuestData(const void *arg)
{
    const struct data *data = arg;
    int ret = -1;
    virCPUDefPtr host = NULL;
    virCPUDefPtr cpu = NULL;
    virCPUDefPtr guest = NULL;
254
    virCPUDataPtr guestData = NULL;
255 256 257 258 259 260 261 262
    virCPUCompareResult cmpResult;
    virBuffer buf = VIR_BUFFER_INITIALIZER;
    char *result = NULL;

    if (!(host = cpuTestLoadXML(data->arch, data->host)) ||
        !(cpu = cpuTestLoadXML(data->arch, data->name)))
        goto cleanup;

263
    cmpResult = cpuGuestData(host, cpu, &guestData, NULL);
264 265 266 267
    if (cmpResult == VIR_CPU_COMPARE_ERROR ||
        cmpResult == VIR_CPU_COMPARE_INCOMPATIBLE)
        goto cleanup;

268
    if (VIR_ALLOC(guest) < 0)
269 270
        goto cleanup;

271
    guest->arch = host->arch;
272 273
    guest->type = VIR_CPU_TYPE_GUEST;
    guest->match = VIR_CPU_MATCH_EXACT;
274
    guest->fallback = cpu->fallback;
275 276 277 278 279 280 281 282 283
    if (cpuDecode(guest, guestData, data->models,
                  data->nmodels, data->preferred) < 0) {
        if (data->result < 0) {
            virResetLastError();
            ret = 0;
        }
        goto cleanup;
    }

284
    virBufferAsprintf(&buf, "%s+%s", data->host, data->name);
285
    if (data->nmodels)
286
        virBufferAsprintf(&buf, ",%s", data->modelsName);
287
    if (data->preferred)
288
        virBufferAsprintf(&buf, ",%s", data->preferred);
289 290 291 292 293 294 295 296
    virBufferAddLit(&buf, "-result");

    if (virBufferError(&buf)) {
        virBufferFreeAndReset(&buf);
        goto cleanup;
    }
    result = virBufferContentAndReset(&buf);

297
    ret = cpuTestCompareXML(data->arch, guest, result, false);
298

299
 cleanup:
300
    VIR_FREE(result);
J
Jiri Denemark 已提交
301
    cpuDataFree(guestData);
302 303 304 305 306 307 308 309 310 311 312 313 314 315 316
    virCPUDefFree(host);
    virCPUDefFree(cpu);
    virCPUDefFree(guest);
    return ret;
}


static int
cpuTestBaseline(const void *arg)
{
    const struct data *data = arg;
    int ret = -1;
    virCPUDefPtr *cpus = NULL;
    virCPUDefPtr baseline = NULL;
    unsigned int ncpus = 0;
317
    char *result = NULL;
318
    const char *suffix;
319
    size_t i;
320 321 322 323

    if (!(cpus = cpuTestLoadMultiXML(data->arch, data->name, &ncpus)))
        goto cleanup;

324
    baseline = cpuBaseline(cpus, ncpus, NULL, 0, data->flags);
325 326
    if (data->result < 0) {
        virResetLastError();
327
        if (!baseline) {
328
            ret = 0;
329 330
        } else {
            VIR_TEST_VERBOSE("\n%-70s... ",
331 332 333 334 335 336 337
                    "cpuBaseline was expected to fail but it succeeded");
        }
        goto cleanup;
    }
    if (!baseline)
        goto cleanup;

338 339
    if (data->flags & VIR_CONNECT_BASELINE_CPU_EXPAND_FEATURES)
        suffix = "expanded";
340 341
    else if (data->flags & VIR_CONNECT_BASELINE_CPU_MIGRATABLE)
        suffix = "migratable";
342 343 344
    else
        suffix = "result";
    if (virAsprintf(&result, "%s-%s", data->name, suffix) < 0)
345 346
        goto cleanup;

347
    if (cpuTestCompareXML(data->arch, baseline, result, false) < 0)
348 349 350 351 352
        goto cleanup;

    for (i = 0; i < ncpus; i++) {
        virCPUCompareResult cmp;

353
        cmp = cpuCompare(cpus[i], baseline, false);
354 355
        if (cmp != VIR_CPU_COMPARE_SUPERSET &&
            cmp != VIR_CPU_COMPARE_IDENTICAL) {
356 357 358
            VIR_TEST_VERBOSE("\nbaseline CPU is incompatible with CPU %zu\n",
                             i);
            VIR_TEST_VERBOSE("%74s", "... ");
359 360 361 362 363 364 365
            ret = -1;
            goto cleanup;
        }
    }

    ret = 0;

366
 cleanup:
367 368 369
    if (cpus) {
        for (i = 0; i < ncpus; i++)
            virCPUDefFree(cpus[i]);
370
        VIR_FREE(cpus);
371 372
    }
    virCPUDefFree(baseline);
373
    VIR_FREE(result);
374 375 376 377 378 379 380 381 382 383 384
    return ret;
}


static int
cpuTestUpdate(const void *arg)
{
    const struct data *data = arg;
    int ret = -1;
    virCPUDefPtr host = NULL;
    virCPUDefPtr cpu = NULL;
385
    char *result = NULL;
386 387 388 389 390 391 392 393

    if (!(host = cpuTestLoadXML(data->arch, data->host)) ||
        !(cpu = cpuTestLoadXML(data->arch, data->name)))
        goto cleanup;

    if (cpuUpdate(cpu, host) < 0)
        goto cleanup;

394 395 396
    if (virAsprintf(&result, "%s+%s", data->host, data->name) < 0)
        goto cleanup;

397
    ret = cpuTestCompareXML(data->arch, cpu, result, true);
398

399
 cleanup:
400 401
    virCPUDefFree(host);
    virCPUDefFree(cpu);
402
    VIR_FREE(result);
403 404 405 406 407 408 409 410 411 412
    return ret;
}


static int
cpuTestHasFeature(const void *arg)
{
    const struct data *data = arg;
    int ret = -1;
    virCPUDefPtr host = NULL;
413
    virCPUDataPtr hostData = NULL;
414 415 416 417 418 419 420 421 422
    int result;

    if (!(host = cpuTestLoadXML(data->arch, data->host)))
        goto cleanup;

    if (cpuEncode(host->arch, host, NULL, &hostData,
                  NULL, NULL, NULL, NULL) < 0)
        goto cleanup;

J
Jiri Denemark 已提交
423
    result = cpuHasFeature(hostData, data->name);
424 425 426 427
    if (data->result == -1)
        virResetLastError();

    if (data->result != result) {
428 429 430 431 432
        VIR_TEST_VERBOSE("\nExpected result %s, got %s\n",
            cpuTestBoolWithErrorStr(data->result),
            cpuTestBoolWithErrorStr(result));
        /* Pad to line up with test name ... in virTestRun */
        VIR_TEST_VERBOSE("%74s", "... ");
433 434 435 436 437
        goto cleanup;
    }

    ret = 0;

438
 cleanup:
J
Jiri Denemark 已提交
439
    cpuDataFree(hostData);
440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456
    virCPUDefFree(host);
    return ret;
}


static int (*cpuTest[])(const void *) = {
    cpuTestCompare,
    cpuTestGuestData,
    cpuTestBaseline,
    cpuTestUpdate,
    cpuTestHasFeature
};


static int
cpuTestRun(const char *name, const struct data *data)
{
457
    char *label = NULL;
458
    char *tmp;
459

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

463 464
    tmp = virtTestLogContentAndReset();
    VIR_FREE(tmp);
465

466
    if (virtTestRun(label, cpuTest[data->api], data) < 0) {
467 468 469 470
        if (virTestGetDebug()) {
            char *log;
            if ((log = virtTestLogContentAndReset()) &&
                 strlen(log) > 0)
471
                VIR_TEST_DEBUG("\n%s\n", log);
472
            VIR_FREE(log);
473
        }
474

475
        VIR_FREE(label);
476 477 478
        return -1;
    }

479
    VIR_FREE(label);
480 481 482 483 484 485 486
    return 0;
}


static const char *model486[]   = { "486" };
static const char *nomodel[]    = { "nomodel" };
static const char *models[]     = { "qemu64", "core2duo", "Nehalem" };
487
static const char *haswell[]    = { "SandyBridge", "Haswell" };
488
static const char *ppc_models[]     = { "POWER7", "POWER7_v2.1", "POWER8_v1.0"};
489 490

static int
E
Eric Blake 已提交
491
mymain(void)
492 493 494 495
{
    int ret = 0;

#define DO_TEST(arch, api, name, host, cpu,                             \
496
                models, nmodels, preferred, flags, result)              \
497
    do {                                                                \
498
        static struct data data = {                                     \
499 500
            arch, api, host, cpu, models,                               \
            models == NULL ? NULL : #models,                            \
501
            nmodels, preferred, flags, result                           \
502 503 504 505 506 507 508 509
        };                                                              \
        if (cpuTestRun(name, &data) < 0)                                \
            ret = -1;                                                   \
    } while (0)

#define DO_TEST_COMPARE(arch, host, cpu, result)                        \
    DO_TEST(arch, API_COMPARE,                                          \
            host "/" cpu " (" #result ")",                              \
510
            host, cpu, NULL, 0, NULL, 0, result)
511 512 513 514 515

#define DO_TEST_UPDATE(arch, host, cpu, result)                         \
    do {                                                                \
        DO_TEST(arch, API_UPDATE,                                       \
                cpu " on " host,                                        \
516
                host, cpu, NULL, 0, NULL, 0, 0);                        \
517 518 519
        DO_TEST_COMPARE(arch, host, host "+" cpu, result);              \
    } while (0)

520
#define DO_TEST_BASELINE(arch, name, flags, result)                     \
521 522 523 524 525
    do {                                                                \
        const char *suffix = "";                                        \
        char *label;                                                    \
        if ((flags) & VIR_CONNECT_BASELINE_CPU_EXPAND_FEATURES)         \
            suffix = " (expanded)";                                     \
526 527
        if ((flags) & VIR_CONNECT_BASELINE_CPU_MIGRATABLE)              \
            suffix = " (migratable)";                                   \
528 529 530 531 532 533 534 535
        if (virAsprintf(&label, "%s%s", name, suffix) < 0) {            \
            ret = -1;                                                   \
        } else {                                                        \
            DO_TEST(arch, API_BASELINE, label, NULL, "baseline-" name,  \
                    NULL, 0, NULL, flags, result);                      \
        }                                                               \
        VIR_FREE(label);                                                \
    } while (0)
536 537 538 539

#define DO_TEST_HASFEATURE(arch, host, feature, result)                 \
    DO_TEST(arch, API_HAS_FEATURE,                                      \
            host "/" feature " (" #result ")",                          \
540
            host, feature, NULL, 0, NULL, 0, result)
541 542 543 544 545 546

#define DO_TEST_GUESTDATA(arch, host, cpu, models, preferred, result)   \
    DO_TEST(arch, API_GUEST_DATA,                                       \
            host "/" cpu " (" #models ", pref=" #preferred ")",         \
            host, cpu, models,                                          \
            models == NULL ? 0 : sizeof(models) / sizeof(char *),       \
547
            preferred, 0, result)
548 549

    /* host to host comparison */
550 551 552 553 554 555 556
    DO_TEST_COMPARE("x86", "host", "host", VIR_CPU_COMPARE_IDENTICAL);
    DO_TEST_COMPARE("x86", "host", "host-better", VIR_CPU_COMPARE_INCOMPATIBLE);
    DO_TEST_COMPARE("x86", "host", "host-worse", VIR_CPU_COMPARE_SUPERSET);
    DO_TEST_COMPARE("x86", "host", "host-amd-fake", VIR_CPU_COMPARE_INCOMPATIBLE);
    DO_TEST_COMPARE("x86", "host", "host-incomp-arch", VIR_CPU_COMPARE_INCOMPATIBLE);
    DO_TEST_COMPARE("x86", "host", "host-no-vendor", VIR_CPU_COMPARE_IDENTICAL);
    DO_TEST_COMPARE("x86", "host-no-vendor", "host", VIR_CPU_COMPARE_INCOMPATIBLE);
557 558

    /* guest to host comparison */
559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579
    DO_TEST_COMPARE("x86", "host", "bogus-model", VIR_CPU_COMPARE_ERROR);
    DO_TEST_COMPARE("x86", "host", "bogus-feature", VIR_CPU_COMPARE_ERROR);
    DO_TEST_COMPARE("x86", "host", "min", VIR_CPU_COMPARE_SUPERSET);
    DO_TEST_COMPARE("x86", "host", "pentium3", VIR_CPU_COMPARE_SUPERSET);
    DO_TEST_COMPARE("x86", "host", "exact", VIR_CPU_COMPARE_SUPERSET);
    DO_TEST_COMPARE("x86", "host", "exact-forbid", VIR_CPU_COMPARE_INCOMPATIBLE);
    DO_TEST_COMPARE("x86", "host", "exact-forbid-extra", VIR_CPU_COMPARE_SUPERSET);
    DO_TEST_COMPARE("x86", "host", "exact-disable", VIR_CPU_COMPARE_SUPERSET);
    DO_TEST_COMPARE("x86", "host", "exact-disable2", VIR_CPU_COMPARE_SUPERSET);
    DO_TEST_COMPARE("x86", "host", "exact-disable-extra", VIR_CPU_COMPARE_SUPERSET);
    DO_TEST_COMPARE("x86", "host", "exact-require", VIR_CPU_COMPARE_SUPERSET);
    DO_TEST_COMPARE("x86", "host", "exact-require-extra", VIR_CPU_COMPARE_INCOMPATIBLE);
    DO_TEST_COMPARE("x86", "host", "exact-force", VIR_CPU_COMPARE_SUPERSET);
    DO_TEST_COMPARE("x86", "host", "strict", VIR_CPU_COMPARE_INCOMPATIBLE);
    DO_TEST_COMPARE("x86", "host", "strict-full", VIR_CPU_COMPARE_IDENTICAL);
    DO_TEST_COMPARE("x86", "host", "strict-disable", VIR_CPU_COMPARE_IDENTICAL);
    DO_TEST_COMPARE("x86", "host", "strict-force-extra", VIR_CPU_COMPARE_IDENTICAL);
    DO_TEST_COMPARE("x86", "host", "guest", VIR_CPU_COMPARE_SUPERSET);
    DO_TEST_COMPARE("x86", "host", "pentium3-amd", VIR_CPU_COMPARE_INCOMPATIBLE);
    DO_TEST_COMPARE("x86", "host-amd", "pentium3-amd", VIR_CPU_COMPARE_SUPERSET);
    DO_TEST_COMPARE("x86", "host-worse", "nehalem-force", VIR_CPU_COMPARE_IDENTICAL);
580
    DO_TEST_COMPARE("x86", "host-SandyBridge", "exact-force-Haswell", VIR_CPU_COMPARE_IDENTICAL);
581

582 583 584
    DO_TEST_COMPARE("ppc64", "host", "strict", VIR_CPU_COMPARE_IDENTICAL);
    DO_TEST_COMPARE("ppc64", "host", "exact", VIR_CPU_COMPARE_INCOMPATIBLE);

585 586
    /* guest updates for migration
     * automatically compares host CPU with the result */
587 588 589 590 591 592
    DO_TEST_UPDATE("x86", "host", "min", VIR_CPU_COMPARE_IDENTICAL);
    DO_TEST_UPDATE("x86", "host", "pentium3", VIR_CPU_COMPARE_IDENTICAL);
    DO_TEST_UPDATE("x86", "host", "guest", VIR_CPU_COMPARE_SUPERSET);
    DO_TEST_UPDATE("x86", "host", "host-model", VIR_CPU_COMPARE_IDENTICAL);
    DO_TEST_UPDATE("x86", "host", "host-model-nofallback", VIR_CPU_COMPARE_IDENTICAL);
    DO_TEST_UPDATE("x86", "host", "host-passthrough", VIR_CPU_COMPARE_IDENTICAL);
593
    DO_TEST_UPDATE("x86", "host-invtsc", "host-model", VIR_CPU_COMPARE_SUPERSET);
594 595

    /* computing baseline CPUs */
596 597 598 599 600
    DO_TEST_BASELINE("x86", "incompatible-vendors", 0, -1);
    DO_TEST_BASELINE("x86", "no-vendor", 0, 0);
    DO_TEST_BASELINE("x86", "some-vendors", 0, 0);
    DO_TEST_BASELINE("x86", "1", 0, 0);
    DO_TEST_BASELINE("x86", "2", 0, 0);
601
    DO_TEST_BASELINE("x86", "3", 0, 0);
602
    DO_TEST_BASELINE("x86", "3", VIR_CONNECT_BASELINE_CPU_EXPAND_FEATURES, 0);
603 604 605 606
    DO_TEST_BASELINE("x86", "4", 0, 0);
    DO_TEST_BASELINE("x86", "4", VIR_CONNECT_BASELINE_CPU_EXPAND_FEATURES, 0);
    DO_TEST_BASELINE("x86", "5", 0, 0);
    DO_TEST_BASELINE("x86", "5", VIR_CONNECT_BASELINE_CPU_EXPAND_FEATURES, 0);
607 608
    DO_TEST_BASELINE("x86", "6", 0, 0);
    DO_TEST_BASELINE("x86", "6", VIR_CONNECT_BASELINE_CPU_MIGRATABLE, 0);
609 610
    DO_TEST_BASELINE("x86", "7", 0, 0);
    DO_TEST_BASELINE("x86", "8", 0, 0);
611

612 613
    DO_TEST_BASELINE("ppc64", "incompatible-vendors", 0, -1);
    DO_TEST_BASELINE("ppc64", "no-vendor", 0, 0);
614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634
    /* CPU features */
    DO_TEST_HASFEATURE("x86", "host", "vmx", YES);
    DO_TEST_HASFEATURE("x86", "host", "lm", YES);
    DO_TEST_HASFEATURE("x86", "host", "sse4.1", YES);
    DO_TEST_HASFEATURE("x86", "host", "3dnowext", NO);
    DO_TEST_HASFEATURE("x86", "host", "skinit", NO);
    DO_TEST_HASFEATURE("x86", "host", "foo", FAIL);

    /* computing guest data and decoding the data into a guest CPU XML */
    DO_TEST_GUESTDATA("x86", "host", "guest", NULL, NULL, 0);
    DO_TEST_GUESTDATA("x86", "host-better", "pentium3", NULL, NULL, 0);
    DO_TEST_GUESTDATA("x86", "host-better", "pentium3", NULL, "pentium3", 0);
    DO_TEST_GUESTDATA("x86", "host-better", "pentium3", NULL, "core2duo", 0);
    DO_TEST_GUESTDATA("x86", "host-worse", "guest", NULL, NULL, 0);
    DO_TEST_GUESTDATA("x86", "host", "strict-force-extra", NULL, NULL, 0);
    DO_TEST_GUESTDATA("x86", "host", "nehalem-force", NULL, NULL, 0);
    DO_TEST_GUESTDATA("x86", "host", "guest", model486, NULL, 0);
    DO_TEST_GUESTDATA("x86", "host", "guest", models, NULL, 0);
    DO_TEST_GUESTDATA("x86", "host", "guest", models, "Penryn", 0);
    DO_TEST_GUESTDATA("x86", "host", "guest", models, "qemu64", 0);
    DO_TEST_GUESTDATA("x86", "host", "guest", nomodel, NULL, -1);
635
    DO_TEST_GUESTDATA("x86", "host", "guest-nofallback", models, "Penryn", -1);
636 637 638
    DO_TEST_GUESTDATA("x86", "host", "host+host-model", models, "Penryn", 0);
    DO_TEST_GUESTDATA("x86", "host", "host+host-model-nofallback",
                      models, "Penryn", -1);
639 640 641 642 643 644 645 646
    DO_TEST_GUESTDATA("x86", "host-Haswell-noTSX", "Haswell",
                      haswell, "Haswell", 0);
    DO_TEST_GUESTDATA("x86", "host-Haswell-noTSX", "Haswell-noTSX",
                      haswell, "Haswell-noTSX", 0);
    DO_TEST_GUESTDATA("x86", "host-Haswell-noTSX", "Haswell-noTSX-nofallback",
                      haswell, "Haswell-noTSX", -1);
    DO_TEST_GUESTDATA("x86", "host-Haswell-noTSX", "Haswell-noTSX",
                      NULL, "Haswell-noTSX", 0);
647

648 649 650
    DO_TEST_GUESTDATA("ppc64", "host", "guest", ppc_models, NULL, 0);
    DO_TEST_GUESTDATA("ppc64", "host", "guest-nofallback", ppc_models, "POWER7_v2.1", -1);

651
    return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
652 653 654
}

VIRT_TEST_MAIN(mymain)