#include <stdlib.h>
#include "testutils.h"
+#include "testutilsqemu.h"
+#include "testutilsqemuschema.h"
#include "virstoragefile.h"
#include "virstring.h"
#include "virlog.h"
#include "qemu/qemu_block.h"
+#include "qemu/qemu_qapi.h"
+
+#include "qemu/qemu_command.h"
#define VIR_FROM_THIS VIR_FROM_NONE
}
+struct testQemuDiskXMLToJSONData {
+ virQEMUDriverPtr driver;
+ virHashTablePtr schema;
+ virJSONValuePtr schemaroot;
+ const char *name;
+ bool fail;
+
+ virJSONValuePtr *props;
+ size_t nprops;
+
+ virQEMUCapsPtr qemuCaps;
+};
+
+
+static void
+testQemuDiskXMLToPropsClear(struct testQemuDiskXMLToJSONData *data)
+{
+ size_t i;
+
+ for (i = 0; i < data->nprops; i++)
+ virJSONValueFree(data->props[i]);
+
+ data->nprops = 0;
+ VIR_FREE(data->props);
+}
+
+
+static const char *testQemuDiskXMLToJSONPath = abs_srcdir "/qemublocktestdata/xml2json/";
+
+static int
+testQemuDiskXMLToProps(const void *opaque)
+{
+ struct testQemuDiskXMLToJSONData *data = (void *) opaque;
+ virDomainDiskDefPtr disk = NULL;
+ virStorageSourcePtr n;
+ virJSONValuePtr props = NULL;
+ char *xmlpath = NULL;
+ char *xmlstr = NULL;
+ int ret = -1;
+
+ if (virAsprintf(&xmlpath, "%s%s.xml",
+ testQemuDiskXMLToJSONPath, data->name) < 0)
+ goto cleanup;
+
+ if (virTestLoadFile(xmlpath, &xmlstr) < 0)
+ goto cleanup;
+
+ /* qemu stores node names in the status XML portion */
+ if (!(disk = virDomainDiskDefParse(xmlstr, NULL, data->driver->xmlopt,
+ VIR_DOMAIN_DEF_PARSE_STATUS)))
+ goto cleanup;
+
+ if (qemuCheckDiskConfig(disk, data->qemuCaps) < 0 ||
+ qemuDomainDeviceDefValidateDisk(disk, data->qemuCaps) < 0) {
+ VIR_TEST_VERBOSE("invalid configuration for disk\n");
+ goto cleanup;
+ }
+
+ if (qemuDomainPrepareDiskSourceChain(disk, NULL, NULL, data->qemuCaps) < 0)
+ goto cleanup;
+
+ for (n = disk->src; virStorageSourceIsBacking(n); n = n->backingStore) {
+ if (!(props = qemuBlockStorageSourceGetBlockdevProps(n))) {
+ if (!data->fail) {
+ VIR_TEST_VERBOSE("failed to generate qemu blockdev props\n");
+ goto cleanup;
+ }
+ } else if (data->fail) {
+ VIR_TEST_VERBOSE("qemu blockdev props should have failed\n");
+ goto cleanup;
+ }
+
+ if (VIR_APPEND_ELEMENT(data->props, data->nprops, props) < 0)
+ goto cleanup;
+ }
+
+ ret = 0;
+
+ cleanup:
+ virDomainDiskDefFree(disk);
+ VIR_FREE(xmlpath);
+ VIR_FREE(xmlstr);
+ return ret;
+}
+
+
+static int
+testQemuDiskXMLToPropsValidateSchema(const void *opaque)
+{
+ struct testQemuDiskXMLToJSONData *data = (void *) opaque;
+ virBuffer debug = VIR_BUFFER_INITIALIZER;
+ char *propsstr = NULL;
+ char *debugmsg = NULL;
+ int ret = 0;
+ size_t i;
+
+ if (data->fail)
+ return EXIT_AM_SKIP;
+
+ for (i = 0; i < data->nprops; i++) {
+ if (testQEMUSchemaValidate(data->props[i], data->schemaroot,
+ data->schema, &debug) < 0) {
+ debugmsg = virBufferContentAndReset(&debug);
+ propsstr = virJSONValueToString(data->props[i], true);
+ VIR_TEST_VERBOSE("json does not conform to QAPI schema");
+ VIR_TEST_DEBUG("json:\n%s\ndoes not match schema. Debug output:\n %s",
+ propsstr, NULLSTR(debugmsg));
+ VIR_FREE(debugmsg);
+ VIR_FREE(propsstr);
+ ret = -1;
+ }
+
+ virBufferFreeAndReset(&debug);
+ }
+ return ret;
+}
+
+
+static int
+testQemuDiskXMLToPropsValidateFile(const void *opaque)
+{
+ struct testQemuDiskXMLToJSONData *data = (void *) opaque;
+ virBuffer buf = VIR_BUFFER_INITIALIZER;
+ char *jsonpath = NULL;
+ char *actual = NULL;
+ int ret = -1;
+ size_t i;
+
+ if (data->fail)
+ return EXIT_AM_SKIP;
+
+ if (virAsprintf(&jsonpath, "%s%s.json",
+ testQemuDiskXMLToJSONPath, data->name) < 0)
+ goto cleanup;
+
+ for (i = 0; i < data->nprops; i++) {
+ char *jsonstr;
+
+ if (!(jsonstr = virJSONValueToString(data->props[i], true)))
+ goto cleanup;
+
+ virBufferAdd(&buf, jsonstr, -1);
+ VIR_FREE(jsonstr);
+ }
+
+ if (virBufferCheckError(&buf) < 0)
+ goto cleanup;
+
+ actual = virBufferContentAndReset(&buf);
+
+ ret = virTestCompareToFile(actual, jsonpath);
+
+ cleanup:
+ VIR_FREE(jsonpath);
+ VIR_FREE(actual);
+ return ret;
+}
+
+
static int
mymain(void)
{
int ret = 0;
+ virQEMUDriver driver;
struct testBackingXMLjsonXMLdata xmljsonxmldata;
+ struct testQemuDiskXMLToJSONData diskxmljsondata;
+ char *capslatest_x86_64 = NULL;
+ virQEMUCapsPtr caps_x86_64 = NULL;
+
+ if (qemuTestDriverInit(&driver) < 0)
+ return EXIT_FAILURE;
+
+ diskxmljsondata.driver = &driver;
+
+ if (!(capslatest_x86_64 = testQemuGetLatestCapsForArch(abs_srcdir "/qemucapabilitiesdata",
+ "x86_64", "xml")))
+ return EXIT_FAILURE;
+
+ VIR_TEST_VERBOSE("\nlatest caps x86_64: %s\n", capslatest_x86_64);
+
+ if (!(caps_x86_64 = qemuTestParseCapabilitiesArch(virArchFromString("x86_64"),
+ capslatest_x86_64)))
+ return EXIT_FAILURE;
+
+ diskxmljsondata.qemuCaps = caps_x86_64;
virTestCounterReset("qemu storage source xml->json->xml ");
" <host name='example.com' port='9999'/>\n"
"</source>\n");
+#define TEST_DISK_TO_JSON_FULL(nme, fl) \
+ do { \
+ diskxmljsondata.name = nme; \
+ diskxmljsondata.props = NULL; \
+ diskxmljsondata.nprops = 0; \
+ diskxmljsondata.fail = fl; \
+ if (virTestRun("disk xml to props " nme, testQemuDiskXMLToProps, \
+ &diskxmljsondata) < 0) \
+ ret = -1; \
+ if (virTestRun("disk xml to props validate schema " nme, \
+ testQemuDiskXMLToPropsValidateSchema, &diskxmljsondata) < 0) \
+ ret = -1; \
+ if (virTestRun("disk xml to props validate file " nme, \
+ testQemuDiskXMLToPropsValidateFile, &diskxmljsondata) < 0) \
+ ret = -1; \
+ testQemuDiskXMLToPropsClear(&diskxmljsondata); \
+ } while (0)
+
+#define TEST_DISK_TO_JSON(nme) TEST_DISK_TO_JSON_FULL(nme, false)
+
+ if (!(diskxmljsondata.schema = testQEMUSchemaLoad())) {
+ ret = -1;
+ goto cleanup;
+ }
+
+ if (virQEMUQAPISchemaPathGet("blockdev-add/arg-type",
+ diskxmljsondata.schema,
+ &diskxmljsondata.schemaroot) < 0 ||
+ !diskxmljsondata.schemaroot) {
+ VIR_TEST_VERBOSE("failed to find schema entry for blockdev-add\n");
+ ret = -1;
+ goto cleanup;
+ }
+
+ TEST_DISK_TO_JSON_FULL("nodename-long-format", true);
+ TEST_DISK_TO_JSON_FULL("nodename-long-protocol", true);
+
+ cleanup:
+ virHashFree(diskxmljsondata.schema);
+ qemuTestDriverFree(&driver);
+ VIR_FREE(capslatest_x86_64);
+ virObjectUnref(caps_x86_64);
+
return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
}