static int testQemuHotplugAttach(virDomainObjPtr vm, virDomainDeviceDefPtr dev) { int ret = -1; switch (dev->type) { case VIR_DOMAIN_DEVICE_DISK: /* conn in only used for storage pool and secrets lookup so as long * as we don't use any of them, passing NULL should be safe */ ret = qemuDomainAttachDeviceDiskLive(NULL, &driver, vm, dev); break; case VIR_DOMAIN_DEVICE_CHR: ret = qemuDomainAttachChrDevice(&driver, vm, dev->data.chr); break; default: if (virTestGetVerbose()) fprintf(stderr, "device type '%s' cannot be attached\n", virDomainDeviceTypeToString(dev->type)); break; } return ret; }
static int testQemuHotplugCheckResult(virDomainObjPtr vm, const char *expected, bool fail) { char *actual; int ret; actual = virDomainDefFormat(vm->def, VIR_DOMAIN_XML_SECURE); if (!actual) return -1; if (STREQ(expected, actual)) { if (fail && virTestGetVerbose()) fprintf(stderr, "domain XML should not match the expected result\n"); ret = 0; } else { if (!fail) virtTestDifference(stderr, expected, actual); ret = -1; } VIR_FREE(actual); return ret; }
void virtTestResult(const char *name, int ret, const char *msg, ...) { va_list vargs; va_start(vargs, msg); testCounter++; if (virTestGetVerbose()) { fprintf(stderr, "%3d) %-60s ", testCounter, name); if (ret == 0) fprintf(stderr, "OK\n"); else { fprintf(stderr, "FAILED\n"); if (msg) { vfprintf(stderr, msg, vargs); } } } else { if (testCounter != 1 && !((testCounter-1) % 40)) { fprintf(stderr, " %-3d\n", (testCounter-1)); fprintf(stderr, " "); } if (ret == 0) fprintf(stderr, "."); else fprintf(stderr, "!"); } va_end(vargs); }
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; result = cpuCompare(host, cpu); if (data->result == VIR_CPU_COMPARE_ERROR) virResetLastError(); if (data->result != result) { if (virTestGetVerbose()) { fprintf(stderr, "\nExpected result %s, got %s\n", cpuTestCompResStr(data->result), cpuTestCompResStr(result)); /* Pad to line up with test name ... in virTestRun */ fprintf(stderr, "%74s", "... "); } goto cleanup; } ret = 0; cleanup: virCPUDefFree(host); virCPUDefFree(cpu); return ret; }
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; }
static int testQemuHotplugDetach(virDomainObjPtr vm, virDomainDeviceDefPtr dev) { int ret = -1; switch (dev->type) { case VIR_DOMAIN_DEVICE_CHR: ret = qemuDomainDetachChrDevice(&driver, vm, dev->data.chr); break; default: if (virTestGetVerbose()) fprintf(stderr, "device type '%s' cannot be attached", virDomainDeviceTypeToString(dev->type)); break; } return ret; }
static int testSELinuxLabeling(const void *opaque) { const char *testname = opaque; int ret = -1; testSELinuxFile *files = NULL; size_t nfiles = 0; size_t i; virDomainDefPtr def = NULL; if (testSELinuxLoadFileList(testname, &files, &nfiles) < 0) goto cleanup; if (testSELinuxCreateDisks(files, nfiles) < 0) goto cleanup; if (!(def = testSELinuxLoadDef(testname))) goto cleanup; if (virSecurityManagerSetAllLabel(mgr, def, NULL) < 0) goto cleanup; if (testSELinuxCheckLabels(files, nfiles) < 0) goto cleanup; ret = 0; cleanup: if (testSELinuxDeleteDisks(files, nfiles) < 0) goto cleanup; virDomainDefFree(def); for (i = 0 ; i < nfiles; i++) { VIR_FREE(files[i].file); VIR_FREE(files[i].context); } VIR_FREE(files); if (ret < 0 && virTestGetVerbose()) { virErrorPtr err = virGetLastError(); fprintf(stderr, "%s\n", err ? err->message : "<unknown>"); } return ret; }
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; }
static int cpuTestHasFeature(const void *arg) { const struct data *data = arg; int ret = -1; virCPUDefPtr host = NULL; union cpuData *hostData = NULL; 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; result = cpuHasFeature(host->arch, hostData, data->name); if (data->result == -1) virResetLastError(); if (data->result != result) { if (virTestGetVerbose()) { fprintf(stderr, "\nExpected result %s, got %s\n", cpuTestBoolWithErrorStr(data->result), cpuTestBoolWithErrorStr(result)); /* Pad to line up with test name ... in virTestRun */ fprintf(stderr, "%74s", "... "); } goto cleanup; } ret = 0; cleanup: if (host) cpuDataFree(host->arch, hostData); virCPUDefFree(host); return ret; }
static int testQemuHotplugAttach(virDomainObjPtr vm, virDomainDeviceDefPtr dev) { int ret = -1; switch (dev->type) { case VIR_DOMAIN_DEVICE_CHR: ret = qemuDomainAttachChrDevice(&driver, vm, dev->data.chr); if (!ret) { /* vm->def stolen dev->data.chr so we ought to avoid freeing it */ dev->data.chr = NULL; } break; default: if (virTestGetVerbose()) fprintf(stderr, "device type '%s' cannot be attached", virDomainDeviceTypeToString(dev->type)); break; } return ret; }
static int cpuTestCompareXML(const char *arch, const virCPUDefPtr cpu, const char *name, unsigned int flags) { char *xml = NULL; char *expected = NULL; char *actual = NULL; int ret = -1; if (virAsprintf(&xml, "%s/cputestdata/%s-%s.xml", abs_srcdir, arch, name) < 0) goto cleanup; if (virtTestLoadFile(xml, &expected) < 0) goto cleanup; if (!(actual = virCPUDefFormat(cpu, flags))) goto cleanup; if (STRNEQ(expected, actual)) { if (virTestGetVerbose()) fprintf(stderr, "\nCompared to %s-%s.xml", arch, name); virtTestDifference(stderr, expected, actual); goto cleanup; } ret = 0; cleanup: free(xml); free(expected); free(actual); return ret; }
static int testQemuHotplugUpdate(virDomainObjPtr vm, virDomainDeviceDefPtr dev) { int ret = -1; /* XXX Ideally, we would call qemuDomainUpdateDeviceLive here. But that * would require us to provide virConnectPtr and virDomainPtr (they're used * in case of updating a disk device. So for now, we will proceed with * breaking the function into pieces. If we ever learn how to fake those * required object, we can replace this code then. */ switch (dev->type) { case VIR_DOMAIN_DEVICE_GRAPHICS: ret = qemuDomainChangeGraphics(&driver, vm, dev->data.graphics); break; default: if (virTestGetVerbose()) fprintf(stderr, "device type '%s' cannot be updated", virDomainDeviceTypeToString(dev->type)); break; } return ret; }
static int cpuTestCompareXML(const char *arch, virCPUDef *cpu, const char *name, bool updateCPU) { char *xml = NULL; char *expected = NULL; char *actual = NULL; int ret = -1; if (virAsprintf(&xml, "%s/cputestdata/%s-%s.xml", abs_srcdir, arch, name) < 0) goto cleanup; if (virtTestLoadFile(xml, &expected) < 0) goto cleanup; if (!(actual = virCPUDefFormat(cpu, NULL, updateCPU))) goto cleanup; if (STRNEQ(expected, actual)) { if (virTestGetVerbose()) fprintf(stderr, "\nCompared to %s-%s.xml", arch, name); virtTestDifference(stderr, expected, actual); goto cleanup; } ret = 0; cleanup: VIR_FREE(xml); VIR_FREE(expected); VIR_FREE(actual); return ret; }
/* * 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; }
static int cpuTestBaseline(const void *arg) { const struct data *data = arg; int ret = -1; virCPUDefPtr *cpus = NULL; virCPUDefPtr baseline = NULL; unsigned int ncpus = 0; char *result = NULL; unsigned int i; if (!(cpus = cpuTestLoadMultiXML(data->arch, data->name, &ncpus))) goto cleanup; baseline = cpuBaseline(cpus, ncpus, NULL, 0); if (data->result < 0) { virResetLastError(); if (!baseline) ret = 0; else if (virTestGetVerbose()) { fprintf(stderr, "\n%-70s... ", "cpuBaseline was expected to fail but it succeeded"); } goto cleanup; } if (!baseline) goto cleanup; if (virAsprintf(&result, "%s-result", data->name) < 0) goto cleanup; if (cpuTestCompareXML(data->arch, baseline, result) < 0) goto cleanup; for (i = 0; i < ncpus; i++) { virCPUCompareResult cmp; cmp = cpuCompare(cpus[i], baseline); if (cmp != VIR_CPU_COMPARE_SUPERSET && cmp != VIR_CPU_COMPARE_IDENTICAL) { if (virTestGetVerbose()) { fprintf(stderr, "\nbaseline CPU is incompatible with CPU %u\n", i); fprintf(stderr, "%74s", "... "); } ret = -1; goto cleanup; } } ret = 0; cleanup: if (cpus) { for (i = 0; i < ncpus; i++) virCPUDefFree(cpus[i]); free(cpus); } virCPUDefFree(baseline); free(result); 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; char *result = NULL; const char *suffix; size_t i; if (!(cpus = cpuTestLoadMultiXML(data->arch, data->name, &ncpus))) goto cleanup; baseline = cpuBaseline(cpus, ncpus, NULL, 0, data->flags); if (data->result < 0) { virResetLastError(); if (!baseline) { ret = 0; } else if (virTestGetVerbose()) { fprintf(stderr, "\n%-70s... ", "cpuBaseline was expected to fail but it succeeded"); } goto cleanup; } if (!baseline) goto cleanup; if (data->flags & VIR_CONNECT_BASELINE_CPU_EXPAND_FEATURES) suffix = "expanded"; else if (data->flags & VIR_CONNECT_BASELINE_CPU_MIGRATABLE) suffix = "migratable"; else suffix = "result"; if (virAsprintf(&result, "%s-%s", data->name, suffix) < 0) goto cleanup; if (cpuTestCompareXML(data->arch, baseline, result, false) < 0) goto cleanup; for (i = 0; i < ncpus; i++) { virCPUCompareResult cmp; cmp = cpuCompare(cpus[i], baseline, false); if (cmp != VIR_CPU_COMPARE_SUPERSET && cmp != VIR_CPU_COMPARE_IDENTICAL) { if (virTestGetVerbose()) { fprintf(stderr, "\nbaseline CPU is incompatible with CPU %zu\n", i); fprintf(stderr, "%74s", "... "); } ret = -1; goto cleanup; } } ret = 0; cleanup: if (cpus) { for (i = 0; i < ncpus; i++) virCPUDefFree(cpus[i]); VIR_FREE(cpus); } virCPUDefFree(baseline); VIR_FREE(result); return ret; }
static int testJSONCopy(const void *data) { const struct testInfo *info = data; virJSONValuePtr json = NULL; virJSONValuePtr jsonCopy = NULL; char *result = NULL; char *resultCopy = NULL; int ret = -1; json = virJSONValueFromString(info->doc); if (!json) { VIR_TEST_VERBOSE("Failed to parse %s\n", info->doc); goto cleanup; } jsonCopy = virJSONValueCopy(json); if (!jsonCopy) { VIR_TEST_VERBOSE("Failed to copy JSON data\n"); goto cleanup; } result = virJSONValueToString(json, false); if (!result) { VIR_TEST_VERBOSE("Failed to format original JSON data\n"); goto cleanup; } resultCopy = virJSONValueToString(json, false); if (!resultCopy) { VIR_TEST_VERBOSE("Failed to format copied JSON data\n"); goto cleanup; } if (STRNEQ(result, resultCopy)) { if (virTestGetVerbose()) virTestDifference(stderr, result, resultCopy); goto cleanup; } VIR_FREE(result); VIR_FREE(resultCopy); result = virJSONValueToString(json, true); if (!result) { VIR_TEST_VERBOSE("Failed to format original JSON data\n"); goto cleanup; } resultCopy = virJSONValueToString(json, true); if (!resultCopy) { VIR_TEST_VERBOSE("Failed to format copied JSON data\n"); goto cleanup; } if (STRNEQ(result, resultCopy)) { if (virTestGetVerbose()) virTestDifference(stderr, result, resultCopy); goto cleanup; } ret = 0; cleanup: VIR_FREE(result); VIR_FREE(resultCopy); virJSONValueFree(json); virJSONValueFree(jsonCopy); return ret; }
static int testJSONAddRemove(const void *data) { const struct testInfo *info = data; virJSONValuePtr json; virJSONValuePtr name = NULL; char *result = NULL; int ret = -1; json = virJSONValueFromString(info->doc); if (!json) { if (virTestGetVerbose()) fprintf(stderr, "Fail to parse %s\n", info->doc); ret = -1; goto cleanup; } switch (virJSONValueObjectRemoveKey(json, "name", &name)) { case 1: if (!info->pass) { if (virTestGetVerbose()) fprintf(stderr, "should not remove from non-object %s\n", info->doc); goto cleanup; } break; case -1: if (!info->pass) ret = 0; else if (virTestGetVerbose()) fprintf(stderr, "Fail to recognize non-object %s\n", info->doc); goto cleanup; default: if (virTestGetVerbose()) fprintf(stderr, "unexpected result when removing from %s\n", info->doc); goto cleanup; } if (STRNEQ_NULLABLE(virJSONValueGetString(name), "sample")) { if (virTestGetVerbose()) fprintf(stderr, "unexpected value after removing name: %s\n", NULLSTR(virJSONValueGetString(name))); goto cleanup; } if (virJSONValueObjectRemoveKey(json, "name", NULL)) { if (virTestGetVerbose()) fprintf(stderr, "%s", "unexpected success when removing missing key\n"); goto cleanup; } if (virJSONValueObjectAppendString(json, "newname", "foo") < 0) { if (virTestGetVerbose()) fprintf(stderr, "%s", "unexpected failure adding new key\n"); goto cleanup; } if (!(result = virJSONValueToString(json, false))) { if (virTestGetVerbose()) fprintf(stderr, "%s", "failed to stringize result\n"); goto cleanup; } if (STRNEQ(info->expect, result)) { if (virTestGetVerbose()) virtTestDifference(stderr, info->expect, result); goto cleanup; } ret = 0; cleanup: virJSONValueFree(json); virJSONValueFree(name); VIR_FREE(result); return ret; }