c401cc
From be23459e2202163a2cb2f680dbfbc268e58c4434 Mon Sep 17 00:00:00 2001
c401cc
Message-Id: <be23459e2202163a2cb2f680dbfbc268e58c4434@dist-git>
c401cc
From: Peter Krempa <pkrempa@redhat.com>
c401cc
Date: Wed, 26 Feb 2014 14:54:31 +0100
c401cc
Subject: [PATCH] test: Implement fake storage pool driver in qemuxml2argv test
c401cc
c401cc
https://bugzilla.redhat.com/show_bug.cgi?id=1032370
c401cc
c401cc
To support testing of "volume" disk backing, we need to implement a few
c401cc
disk driver backend functions.
c401cc
c401cc
The fake storage driver uses files in storagepoolxml2xmlout/POOLNAME.xml
c401cc
as XML files for pool definitions and volume names are in format
c401cc
"VOL_TYPE+VOL_PATH". By default type "block" is assumed (for iSCSI test
c401cc
compatibility).
c401cc
c401cc
The choice of this approach along with implemented functions was made so
c401cc
that <disk type='volume'> can be tested in the xml2argv test.
c401cc
c401cc
(cherry picked from commit bae124e40ff2b9d4de75d44510619db2c08d548a)
c401cc
c401cc
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
c401cc
---
c401cc
 tests/qemuxml2argvtest.c | 183 +++++++++++++++++++++++++++++++++++++++++++++++
c401cc
 1 file changed, 183 insertions(+)
c401cc
c401cc
diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c
c401cc
index 0e2435b..3c969e2 100644
c401cc
--- a/tests/qemuxml2argvtest.c
c401cc
+++ b/tests/qemuxml2argvtest.c
c401cc
@@ -18,6 +18,7 @@
c401cc
 # include "qemu/qemu_command.h"
c401cc
 # include "qemu/qemu_domain.h"
c401cc
 # include "datatypes.h"
c401cc
+# include "conf/storage_conf.h"
c401cc
 # include "cpu/cpu_map.h"
c401cc
 # include "virstring.h"
c401cc
 
c401cc
@@ -75,6 +76,182 @@ static virSecretDriver fakeSecretDriver = {
c401cc
     .secretUndefine = NULL,
c401cc
 };
c401cc
 
c401cc
+
c401cc
+# define STORAGE_POOL_XML_PATH "storagepoolxml2xmlout/"
c401cc
+static const unsigned char fakeUUID[VIR_UUID_BUFLEN] = "fakeuuid";
c401cc
+
c401cc
+static virStoragePoolPtr
c401cc
+fakeStoragePoolLookupByName(virConnectPtr conn,
c401cc
+                            const char *name)
c401cc
+{
c401cc
+    char *xmlpath = NULL;
c401cc
+    virStoragePoolPtr ret = NULL;
c401cc
+
c401cc
+    if (STRNEQ(name, "inactive")) {
c401cc
+        if (virAsprintf(&xmlpath, "%s/%s%s.xml",
c401cc
+                        abs_srcdir,
c401cc
+                        STORAGE_POOL_XML_PATH,
c401cc
+                        name) < 0)
c401cc
+            return NULL;
c401cc
+
c401cc
+        if (!virFileExists(xmlpath)) {
c401cc
+            virReportError(VIR_ERR_NO_STORAGE_POOL,
c401cc
+                           "File '%s' not found", xmlpath);
c401cc
+            goto cleanup;
c401cc
+        }
c401cc
+    }
c401cc
+
c401cc
+    ret = virGetStoragePool(conn, name, fakeUUID, NULL, NULL);
c401cc
+
c401cc
+cleanup:
c401cc
+    VIR_FREE(xmlpath);
c401cc
+    return ret;
c401cc
+}
c401cc
+
c401cc
+
c401cc
+static virStorageVolPtr
c401cc
+fakeStorageVolLookupByName(virStoragePoolPtr pool,
c401cc
+                           const char *name)
c401cc
+{
c401cc
+    char **volinfo = NULL;
c401cc
+    virStorageVolPtr ret = NULL;
c401cc
+
c401cc
+    if (STREQ(pool->name, "inactive")) {
c401cc
+        virReportError(VIR_ERR_OPERATION_INVALID,
c401cc
+                       "storage pool '%s' is not active", pool->name);
c401cc
+        return NULL;
c401cc
+    }
c401cc
+
c401cc
+    if (STREQ(name, "nonexistent")) {
c401cc
+        virReportError(VIR_ERR_NO_STORAGE_VOL,
c401cc
+                       "no storage vol with matching name '%s'", name);
c401cc
+        return NULL;
c401cc
+    }
c401cc
+
c401cc
+    if (!strchr(name, '+'))
c401cc
+        goto fallback;
c401cc
+
c401cc
+    if (!(volinfo = virStringSplit(name, "+", 2)))
c401cc
+        return NULL;
c401cc
+
c401cc
+    if (!volinfo[1])
c401cc
+        goto fallback;
c401cc
+
c401cc
+    ret = virGetStorageVol(pool->conn, pool->name, volinfo[1], volinfo[0],
c401cc
+                           NULL, NULL);
c401cc
+
c401cc
+cleanup:
c401cc
+    virStringFreeList(volinfo);
c401cc
+    return ret;
c401cc
+
c401cc
+fallback:
c401cc
+    ret = virGetStorageVol(pool->conn, pool->name, name, "block", NULL, NULL);
c401cc
+    goto cleanup;
c401cc
+}
c401cc
+
c401cc
+static int
c401cc
+fakeStorageVolGetInfo(virStorageVolPtr vol,
c401cc
+                      virStorageVolInfoPtr info)
c401cc
+{
c401cc
+    memset(info, 0, sizeof(*info));
c401cc
+
c401cc
+    info->type = virStorageVolTypeFromString(vol->key);
c401cc
+
c401cc
+    if (info->type < 0) {
c401cc
+        virReportError(VIR_ERR_INTERNAL_ERROR,
c401cc
+                       "Invalid volume type '%s'", vol->key);
c401cc
+        return -1;
c401cc
+    }
c401cc
+
c401cc
+    return 0;
c401cc
+}
c401cc
+
c401cc
+
c401cc
+static char *
c401cc
+fakeStorageVolGetPath(virStorageVolPtr vol)
c401cc
+{
c401cc
+    char *ret = NULL;
c401cc
+
c401cc
+    ignore_value(virAsprintf(&ret, "/some/%s/device/%s", vol->key, vol->name));
c401cc
+
c401cc
+    return ret;
c401cc
+}
c401cc
+
c401cc
+
c401cc
+static char *
c401cc
+fakeStoragePoolGetXMLDesc(virStoragePoolPtr pool,
c401cc
+                          unsigned int flags_unused ATTRIBUTE_UNUSED)
c401cc
+{
c401cc
+    char *xmlpath = NULL;
c401cc
+    char *xmlbuf = NULL;
c401cc
+
c401cc
+    if (STREQ(pool->name, "inactive")) {
c401cc
+        virReportError(VIR_ERR_NO_STORAGE_POOL, NULL);
c401cc
+        return NULL;
c401cc
+    }
c401cc
+
c401cc
+    if (virAsprintf(&xmlpath, "%s/%s%s.xml",
c401cc
+                    abs_srcdir,
c401cc
+                    STORAGE_POOL_XML_PATH,
c401cc
+                    pool->name) < 0)
c401cc
+        return NULL;
c401cc
+
c401cc
+    if (virtTestLoadFile(xmlpath, &xmlbuf) < 0) {
c401cc
+        virReportError(VIR_ERR_INTERNAL_ERROR,
c401cc
+                       "failed to load XML file '%s'",
c401cc
+                       xmlpath);
c401cc
+        goto cleanup;
c401cc
+    }
c401cc
+
c401cc
+cleanup:
c401cc
+    VIR_FREE(xmlpath);
c401cc
+
c401cc
+    return xmlbuf;
c401cc
+}
c401cc
+
c401cc
+static int
c401cc
+fakeStorageClose(virConnectPtr conn ATTRIBUTE_UNUSED)
c401cc
+{
c401cc
+    return 0;
c401cc
+}
c401cc
+
c401cc
+static int
c401cc
+fakeStoragePoolIsActive(virStoragePoolPtr pool)
c401cc
+{
c401cc
+    if (STREQ(pool->name, "inactive"))
c401cc
+        return 0;
c401cc
+
c401cc
+    return 1;
c401cc
+}
c401cc
+
c401cc
+/* Test storage pool implementation
c401cc
+ *
c401cc
+ * These functions aid testing of storage pool related stuff when creating a
c401cc
+ * qemu command .
c401cc
+ *
c401cc
+ * There are a few "magic" values to pass to these functions:
c401cc
+ *
c401cc
+ * 1) "inactive" as
c401cc
+ * a pool name for pool lookup creates a inactive pool. All other names are
c401cc
+ * interpreted as file names for files of storagepooltest and are used as the
c401cc
+ * definition for the pool. If the file doesn't exist the pool doesn't exist.
c401cc
+ *
c401cc
+ * 2) "nonexistent" returns an error while looking up a volume. Otherwise
c401cc
+ * pattern VOLUME_TYPE+VOLUME_PATH can be used to simulate a volume in an pool.
c401cc
+ * This creates a fake path for this volume. If the '+' sign is omitted, block
c401cc
+ * type is assumed.
c401cc
+ */
c401cc
+static virStorageDriver fakeStorageDriver = {
c401cc
+    .name = "fake_storage",
c401cc
+    .storageClose = fakeStorageClose,
c401cc
+    .storagePoolLookupByName = fakeStoragePoolLookupByName,
c401cc
+    .storageVolLookupByName = fakeStorageVolLookupByName,
c401cc
+    .storagePoolGetXMLDesc = fakeStoragePoolGetXMLDesc,
c401cc
+    .storageVolGetPath = fakeStorageVolGetPath,
c401cc
+    .storageVolGetInfo = fakeStorageVolGetInfo,
c401cc
+    .storagePoolIsActive = fakeStoragePoolIsActive,
c401cc
+};
c401cc
+
c401cc
 typedef enum {
c401cc
     FLAG_EXPECT_ERROR       = 1 << 0,
c401cc
     FLAG_EXPECT_FAILURE     = 1 << 1,
c401cc
@@ -103,6 +280,7 @@ static int testCompareXMLToArgvFiles(const char *xml,
c401cc
     if (!(conn = virGetConnect()))
c401cc
         goto out;
c401cc
     conn->secretDriver = &fakeSecretDriver;
c401cc
+    conn->storageDriver = &fakeStorageDriver;
c401cc
 
c401cc
     if (!(vmdef = virDomainDefParseFile(xml, driver.caps, driver.xmlopt,
c401cc
                                         QEMU_EXPECTED_VIRT_TYPES,
c401cc
@@ -165,6 +343,11 @@ static int testCompareXMLToArgvFiles(const char *xml,
c401cc
         }
c401cc
     }
c401cc
 
c401cc
+    for (i = 0; i < vmdef->ndisks; i++) {
c401cc
+        if (qemuTranslateDiskSourcePool(conn, vmdef->disks[i]) < 0)
c401cc
+            goto out;
c401cc
+    }
c401cc
+
c401cc
     if (!(cmd = qemuBuildCommandLine(conn, &driver, vmdef, &monitor_chr,
c401cc
                                      (flags & FLAG_JSON), extraFlags,
c401cc
                                      migrateFrom, migrateFd, NULL,
c401cc
-- 
c401cc
1.9.0
c401cc