static int testStorageChain(const void *args) { const struct testChainData *data = args; int ret = -1; virStorageSourcePtr meta; virStorageSourcePtr elt; size_t i = 0; char *broken = NULL; bool isAbs = !!(data->flags & ABS_START); meta = testStorageFileGetMetadata(data->start, data->format, -1, -1, (data->flags & ALLOW_PROBE) != 0); if (!meta) { if (data->flags & EXP_FAIL) { virResetLastError(); ret = 0; } goto cleanup; } else if (data->flags & EXP_FAIL) { fprintf(stderr, "call should have failed\n"); goto cleanup; } if (data->flags & EXP_WARN) { if (!virGetLastError()) { fprintf(stderr, "call should have warned\n"); goto cleanup; } virResetLastError(); if (virStorageFileChainGetBroken(meta, &broken) || !broken) { fprintf(stderr, "call should identify broken part of chain\n"); goto cleanup; } } else { if (virGetLastError()) { fprintf(stderr, "call should not have warned\n"); goto cleanup; } if (virStorageFileChainGetBroken(meta, &broken) || broken) { fprintf(stderr, "chain should not be identified as broken\n"); goto cleanup; } } elt = meta; while (elt) { char *expect = NULL; char *actual = NULL; const char *expPath; const char *expRelDir; if (i == data->nfiles) { fprintf(stderr, "probed chain was too long\n"); goto cleanup; } expPath = isAbs ? data->files[i]->pathAbs : data->files[i]->pathRel; expRelDir = isAbs ? data->files[i]->relDirAbs : data->files[i]->relDirRel; if (virAsprintf(&expect, "store:%s\nraw:%s\nother:%lld %d\n" "relPath:%s\npath:%s\nrelDir:%s\ntype:%d %d\n", NULLSTR(data->files[i]->expBackingStore), NULLSTR(data->files[i]->expBackingStoreRaw), data->files[i]->expCapacity, data->files[i]->expEncrypted, NULLSTR(expPath), NULLSTR(data->files[i]->path), NULLSTR(expRelDir), data->files[i]->type, data->files[i]->format) < 0 || virAsprintf(&actual, "store:%s\nraw:%s\nother:%lld %d\n" "relPath:%s\npath:%s\nrelDir:%s\ntype:%d %d\n", NULLSTR(elt->backingStore ? elt->backingStore->path : NULL), NULLSTR(elt->backingStoreRaw), elt->capacity, !!elt->encryption, NULLSTR(elt->relPath), NULLSTR(elt->path), NULLSTR(elt->relDir), elt->type, elt->format) < 0) { VIR_FREE(expect); VIR_FREE(actual); goto cleanup; } if (STRNEQ(expect, actual)) { fprintf(stderr, "chain member %zu", i); virtTestDifference(stderr, expect, actual); VIR_FREE(expect); VIR_FREE(actual); goto cleanup; } VIR_FREE(expect); VIR_FREE(actual); elt = elt->backingStore; i++; } if (i != data->nfiles) { fprintf(stderr, "probed chain was too short\n"); goto cleanup; } ret = 0; cleanup: VIR_FREE(broken); virStorageSourceFree(meta); return ret; }
static int testStorageChain(const void *args) { const struct testChainData *data = args; int ret = -1; virStorageSourcePtr meta; virStorageSourcePtr elt; size_t i = 0; char *broken = NULL; meta = testStorageFileGetMetadata(data->start, data->format, -1, -1, (data->flags & ALLOW_PROBE) != 0); if (!meta) { if (data->flags & EXP_FAIL) { virResetLastError(); ret = 0; } goto cleanup; } else if (data->flags & EXP_FAIL) { fprintf(stderr, "call should have failed\n"); goto cleanup; } if (data->flags & EXP_WARN) { if (!virGetLastError()) { fprintf(stderr, "call should have warned\n"); goto cleanup; } virResetLastError(); if (virStorageFileChainGetBroken(meta, &broken) || !broken) { fprintf(stderr, "call should identify broken part of chain\n"); goto cleanup; } } else { if (virGetLastError()) { fprintf(stderr, "call should not have warned\n"); goto cleanup; } if (virStorageFileChainGetBroken(meta, &broken) || broken) { fprintf(stderr, "chain should not be identified as broken\n"); goto cleanup; } } elt = meta; while (elt) { char *expect = NULL; char *actual = NULL; if (i == data->nfiles) { fprintf(stderr, "probed chain was too long\n"); goto cleanup; } if (virAsprintf(&expect, testStorageChainFormat, i, NULLSTR(data->files[i]->path), NULLSTR(data->files[i]->expBackingStoreRaw), data->files[i]->expCapacity, data->files[i]->expEncrypted, NULLSTR(data->files[i]->pathRel), data->files[i]->type, data->files[i]->format, virStorageNetProtocolTypeToString(data->files[i]->protocol), NULLSTR(data->files[i]->hostname), NULLSTR(data->files[i]->secret)) < 0 || virAsprintf(&actual, testStorageChainFormat, i, NULLSTR(elt->path), NULLSTR(elt->backingStoreRaw), elt->capacity, !!elt->encryption, NULLSTR(elt->relPath), elt->type, elt->format, virStorageNetProtocolTypeToString(elt->protocol), NULLSTR(elt->nhosts ? elt->hosts[0].name : NULL), NULLSTR(elt->auth ? elt->auth->username : NULL)) < 0) { VIR_FREE(expect); VIR_FREE(actual); goto cleanup; } if (STRNEQ(expect, actual)) { virtTestDifference(stderr, expect, actual); VIR_FREE(expect); VIR_FREE(actual); goto cleanup; } VIR_FREE(expect); VIR_FREE(actual); elt = elt->backingStore; i++; } if (i != data->nfiles) { fprintf(stderr, "probed chain was too short\n"); goto cleanup; } ret = 0; cleanup: VIR_FREE(broken); virStorageSourceFree(meta); return ret; }