Re: [libvirt-dbus] [PATCH 2/2] Implement snapshots APIs

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Thu, Oct 10, 2019 at 01:43:10PM +0200, Simon Kobyda wrote:
> Signed-off-by: Simon Kobyda <skobyda@xxxxxxxxxx>
> ---
>  data/org.libvirt.Domain.xml         |  26 ++++
>  data/org.libvirt.DomainSnapshot.xml |  34 +++++
>  src/domain.c                        | 158 +++++++++++++++++++++
>  src/domainsnapshot.c                | 205 +++++++++++++++++++++++++++-
>  tests/libvirttest.py                |  14 ++
>  tests/meson.build                   |   1 +
>  tests/test_domain.py                |   8 ++
>  tests/test_snapshot.py              |  43 ++++++
>  tests/xmldata.py                    |   6 +
>  9 files changed, 494 insertions(+), 1 deletion(-)
>  create mode 100755 tests/test_snapshot.py
> 
> diff --git a/data/org.libvirt.Domain.xml b/data/org.libvirt.Domain.xml
> index b4ed495..f03faf8 100644
> --- a/data/org.libvirt.Domain.xml
> +++ b/data/org.libvirt.Domain.xml
> @@ -350,6 +350,12 @@
>        <arg name="flags" type="u" direction="in"/>
>        <arg name="ifaces" type="a(ssa(isu))" direction="out"/>
>      </method>
> +    <method name="ListDomainSnapshots">
> +      <annotation name="org.gtk.GDBus.DocString"
> +        value="See https://libvirt.org/html/libvirt-libvirt-domain-snapshot.html#virDomainListAllSnapshots"/>
> +      <arg name="flags" type="u" direction="in"/>
> +      <arg name="snaps" type="ao" direction="out"/>

No need to shorten the name, I would use "domainSnapshots".

> +    </method>
>      <method name="ManagedSave">
>        <annotation name="org.gtk.GDBus.DocString"
>          value="See https://libvirt.org/html/libvirt-libvirt-domain.html#virDomainManagedSave"/>
> @@ -589,6 +595,26 @@
>          value="See https://libvirt.org/html/libvirt-libvirt-domain.html#virDomainShutdownFlags"/>
>        <arg name="flags" type="u" direction="in"/>
>      </method>
> +    <method name="SnapshotCurrent">
> +      <annotation name="org.gtk.GDBus.DocString"
> +        value="See https://libvirt.org/html/libvirt-libvirt-domain-snapshot.html#virDomainSnapshotCurrent"/>
> +      <arg name="flags" type="u" direction="in"/>
> +      <arg name="domainSnapshot" type="o" direction="out"/>
> +    </method>
> +    <method name="SnapshotCreateXML">
> +      <annotation name="org.gtk.GDBus.DocString"
> +        value="See https://libvirt.org/html/libvirt-libvirt-domain-snapshot.html#virDomainSnapshotCreateXML"/>
> +      <arg name="xml" type="s" direction="in"/>
> +      <arg name="flags" type="u" direction="in"/>
> +      <arg name="domainSnapshot" type="o" direction="out"/>
> +    </method>
> +    <method name="SnapshotLookupByName">
> +      <annotation name="org.gtk.GDBus.DocString"
> +        value="See https://libvirt.org/html/libvirt-libvirt-domain-snapshot.html#virDomainSnapshotLookupByName"/>
> +      <arg name="name" type="s" direction="in"/>
> +      <arg name="flags" type="u" direction="in"/>
> +      <arg name="domainSnapshot" type="o" direction="out"/>
> +    </method>
>      <method name="Suspend">
>        <annotation name="org.gtk.GDBus.DocString"
>          value="See https://libvirt.org/html/libvirt-libvirt-domain.html#virDomainSuspend"/>
> diff --git a/data/org.libvirt.DomainSnapshot.xml b/data/org.libvirt.DomainSnapshot.xml
> index 80f61c6..463654f 100644
> --- a/data/org.libvirt.DomainSnapshot.xml
> +++ b/data/org.libvirt.DomainSnapshot.xml
> @@ -3,5 +3,39 @@
>  
>  <node name="/org/libvirt/snapshot">
>    <interface name="org.libvirt.DomainSnapshot">
> +    <method name="Delete">
> +      <annotation name="org.gtk.GDBus.DocString"
> +        value="See https://libvirt.org/html/libvirt-libvirt-domain-snapshot.html#virDomainSnapshotDelete"/>
> +      <arg name="flags" type="u" direction="in"/>
> +    </method>
> +    <method name="GetParent">
> +      <annotation name="org.gtk.GDBus.DocString"
> +        value="See https://libvirt.org/html/libvirt-libvirt-domain-snapshot.html#virDomainSnapshotGetParent"/>
> +      <arg name="flags" type="u" direction="in"/>
> +      <arg name="parent" type="o" direction="out"/>

I would use "domainSnapshot" here ...

> +    </method>
> +    <method name="GetXMLDesc">
> +      <annotation name="org.gtk.GDBus.DocString"
> +        value="See https://libvirt.org/html/libvirt-libvirt-domain-snapshot.html#virDomainSnapshotGetXMLDesc"/>
> +      <arg name="flags" type="u" direction="in"/>
> +      <arg name="xml" type="s" direction="out"/>
> +    </method>
> +    <method name="IsCurrent">
> +      <annotation name="org.gtk.GDBus.DocString"
> +        value="See https://libvirt.org/html/libvirt-libvirt-domain-snapshot.html#virDomainSnapshotIsCurrent"/>
> +      <arg name="flags" type="u" direction="in"/>
> +      <arg name="current" type="b" direction="out"/>

... here ...

> +    </method>
> +    <method name="ListChildren">
> +      <annotation name="org.gtk.GDBus.DocString"
> +        value="See https://libvirt.org/html/libvirt-libvirt-domain-snapshot.html#virDomainSnapshotListAllChildren"/>
> +      <arg name="flags" type="u" direction="in"/>
> +      <arg name="snaps" type="ao" direction="out"/>

... and here.

> +    </method>
> +    <method name="Revert">
> +      <annotation name="org.gtk.GDBus.DocString"
> +        value="See https://libvirt.org/html/libvirt-libvirt-domain-snapshot.html#virDomainRevertToSnapshot"/>
> +      <arg name="flags" type="u" direction="in"/>
> +    </method>
>    </interface>
>  </node>
> diff --git a/src/domain.c b/src/domain.c
> index 10fa8de..3fc5bab 100644
> --- a/src/domain.c
> +++ b/src/domain.c
> @@ -1857,6 +1857,50 @@ virtDBusDomainInjectNMI(GVariant *inArgs,
>          virtDBusUtilSetLastVirtError(error);
>  }
>  
> +static void
> +virtDBusDomainListDomainSnapshots(GVariant *inArgs,
> +                                  GUnixFDList *inFDs G_GNUC_UNUSED,
> +                                  const gchar *objectPath,
> +                                  gpointer userData,
> +                                  GVariant **outArgs G_GNUC_UNUSED,
> +                                  GUnixFDList **outFDs G_GNUC_UNUSED,
> +                                  GError **error)
> +{
> +    virtDBusConnect *connect = userData;
> +    g_autoptr(virDomain) domain = NULL;
> +    g_autoptr(virDomainSnapshotPtr) domainSnapshots = NULL;
> +    guint flags;
> +    GVariantBuilder builder;
> +    GVariant *gdomainSnapshots;
> +
> +    g_variant_get(inArgs, "(u)", &flags);
> +
> +    domain = virtDBusDomainGetVirDomain(connect, objectPath,
> +                                        error);

This fits into single line.

> +    if (!domain)
> +        return;
> +
> +    if (!virtDBusConnectOpen(connect, error))
> +        return;
> +
> +    if (virDomainListAllSnapshots(domain, &domainSnapshots, flags) < 0)
> +        return virtDBusUtilSetLastVirtError(error);
> +
> +    g_variant_builder_init(&builder, G_VARIANT_TYPE("ao"));
> +
> +    for (gint i = 0; domainSnapshots[i]; i++) {
> +        g_autofree gchar *path = NULL;
> +        path = virtDBusUtilBusPathForVirDomainSnapshot(domain,
> +                                                       domainSnapshots[i],
> +                                                       connect->domainSnapshotPath);
> +
> +        g_variant_builder_add(&builder, "o", path);
> +    }
> +
> +    gdomainSnapshots = g_variant_builder_end(&builder);
> +    *outArgs = g_variant_new_tuple(&gdomainSnapshots, 1);
> +}
> +
>  static void
>  virtDBusDomainInterfaceAddresses(GVariant *inArgs,
>                                   GUnixFDList *inFDs G_GNUC_UNUSED,
> @@ -2966,6 +3010,116 @@ virtDBusDomainShutdown(GVariant *inArgs,
>          virtDBusUtilSetLastVirtError(error);
>  }
>  
> +static void
> +virtDBusDomainSnapshotCurrent(GVariant *inArgs,
> +                              GUnixFDList *inFDs G_GNUC_UNUSED,
> +                              const gchar *objectPath,
> +                              gpointer userData,
> +                              GVariant **outArgs G_GNUC_UNUSED,
> +                              GUnixFDList **outFDs G_GNUC_UNUSED,
> +                              GError **error)
> +{
> +    virtDBusConnect *connect = userData;
> +    g_autofree gchar *path = NULL;
> +    g_autoptr(virDomain) domain = NULL;
> +    g_autoptr(virDomainSnapshot) snapshot = NULL;
> +    guint flags;
> +
> +    g_variant_get(inArgs, "(u)", &flags);
> +
> +    domain = virtDBusDomainGetVirDomain(connect, objectPath,
> +                                        error);

This fits into single line.

> +    if (!domain)
> +        return;
> +
> +    if (!virtDBusConnectOpen(connect, error))
> +        return;
> +
> +    snapshot = virDomainSnapshotCurrent(domain, flags);
> +    if (!snapshot)
> +        return virtDBusUtilSetLastVirtError(error);
> +
> +    path = virtDBusUtilBusPathForVirDomainSnapshot(domain,
> +                                                   snapshot,
> +                                                   connect->domainSnapshotPath);
> +
> +    *outArgs = g_variant_new("(o)", path);
> +}
> +
> +static void
> +virtDBusDomainSnapshotCreateXML(GVariant *inArgs,
> +                                GUnixFDList *inFDs G_GNUC_UNUSED,
> +                                const gchar *objectPath,
> +                                gpointer userData,
> +                                GVariant **outArgs G_GNUC_UNUSED,
> +                                GUnixFDList **outFDs G_GNUC_UNUSED,
> +                                GError **error)
> +{
> +    virtDBusConnect *connect = userData;
> +    g_autofree gchar *path = NULL;
> +    g_autoptr(virDomain) domain = NULL;
> +    g_autoptr(virDomainSnapshot) snapshot = NULL;
> +    guint flags;
> +    const gchar *xml;
> +
> +    g_variant_get(inArgs, "(su)", &xml, &flags);

This would leak `xml`. In order to get pointer to memory and not full
copy of the string you need to use "(&su)".

> +
> +    domain = virtDBusDomainGetVirDomain(connect, objectPath,
> +                                        error);

This fits into single line.

> +    if (!domain)
> +        return;
> +
> +    if (!virtDBusConnectOpen(connect, error))
> +        return;
> +
> +    snapshot = virDomainSnapshotCreateXML(domain, xml, flags);
> +    if (!snapshot)
> +        return virtDBusUtilSetLastVirtError(error);
> +
> +    path = virtDBusUtilBusPathForVirDomainSnapshot(domain,
> +                                                   snapshot,
> +                                                   connect->domainSnapshotPath);
> +
> +    *outArgs = g_variant_new("(o)", path);
> +}
> +
> +static void
> +virtDBusDomainSnapshotLookupByName(GVariant *inArgs,
> +                                   GUnixFDList *inFDs G_GNUC_UNUSED,
> +                                   const gchar *objectPath,
> +                                   gpointer userData,
> +                                   GVariant **outArgs G_GNUC_UNUSED,
> +                                   GUnixFDList **outFDs G_GNUC_UNUSED,
> +                                   GError **error)
> +{
> +    virtDBusConnect *connect = userData;
> +    g_autofree gchar *path = NULL;
> +    g_autoptr(virDomain) domain = NULL;
> +    g_autoptr(virDomainSnapshot) snapshot = NULL;
> +    guint flags;
> +    const gchar *name;
> +
> +    g_variant_get(inArgs, "(su)", &name, &flags);

Same as for the `xml`.  You have to use "(&su)" in order to not get
pointer for the `name`.

> +
> +    domain = virtDBusDomainGetVirDomain(connect, objectPath,
> +                                        error);

This fits into single line.

> +    if (!domain)
> +        return;
> +
> +    if (!virtDBusConnectOpen(connect, error))
> +        return;
> +
> +    snapshot = virDomainSnapshotLookupByName(domain, name, flags);
> +    if (!snapshot)
> +        return virtDBusUtilSetLastVirtError(error);
> +
> +    path = virtDBusUtilBusPathForVirDomainSnapshot(domain,
> +                                                   snapshot,
> +                                                   connect->domainSnapshotPath);
> +
> +    *outArgs = g_variant_new("(o)", path);
> +}
> +
>  static void
>  virtDBusDomainSuspend(GVariant *inArgs G_GNUC_UNUSED,
>                        GUnixFDList *inFDs G_GNUC_UNUSED,
> @@ -3095,6 +3249,7 @@ static virtDBusGDBusMethodTable virtDBusDomainMethodTable[] = {
>      { "HasManagedSaveImage", virtDBusDomainHasManagedSaveImage },
>      { "InjectNMI", virtDBusDomainInjectNMI },
>      { "InterfaceAddresses", virtDBusDomainInterfaceAddresses },
> +    { "ListDomainSnapshots", virtDBusDomainListDomainSnapshots },
>      { "ManagedSave", virtDBusDomainManagedSave },
>      { "ManagedSaveRemove", virtDBusDomainManagedSaveRemove },
>      { "MemoryPeek", virtDBusDomainMemoryPeek },
> @@ -3132,6 +3287,9 @@ static virtDBusGDBusMethodTable virtDBusDomainMethodTable[] = {
>      { "SetSchedulerParameters", virtDBusDomainSetSchedulerParameters },
>      { "SetTime", virtDBusDomainSetTime },
>      { "SetUserPassword", virtDBusDomainSetUserPassword },
> +    { "SnapshotCurrent", virtDBusDomainSnapshotCurrent },
> +    { "SnapshotCreateXML", virtDBusDomainSnapshotCreateXML },
> +    { "SnapshotLookupByName", virtDBusDomainSnapshotLookupByName },
>      { "Shutdown", virtDBusDomainShutdown },
>      { "Suspend", virtDBusDomainSuspend },
>      { "Undefine", virtDBusDomainUndefine },
> diff --git a/src/domainsnapshot.c b/src/domainsnapshot.c
> index 590cbef..3f5f5a3 100644
> --- a/src/domainsnapshot.c
> +++ b/src/domainsnapshot.c
> @@ -1,14 +1,217 @@
>  #include "domainsnapshot.h"
> +#include "domain.h"
>  #include "util.h"
>  
>  #include <libvirt/libvirt.h>
>  
> +static void
> +virtDBusDomainSnapshotDelete(GVariant *inArgs,
> +                             GUnixFDList *inFDs G_GNUC_UNUSED,
> +                             const gchar *objectPath,
> +                             gpointer userData,
> +                             GVariant **outArgs G_GNUC_UNUSED,
> +                             GUnixFDList **outFDs G_GNUC_UNUSED,
> +                             GError **error)
> +{
> +    virtDBusConnect *connect = userData;
> +    g_autoptr(virDomainSnapshot) domainSnapshot = NULL;
> +    guint flags;
> +
> +    g_variant_get(inArgs, "(u)", &flags);
> +
> +    domainSnapshot = virtDBusUtilVirDomainSnapshotFromBusPath(connect->connection,
> +                                                              objectPath,
> +                                                              connect->domainSnapshotPath);
> +    if (!domainSnapshot)
> +        return;
> +
> +    if (virDomainSnapshotDelete(domainSnapshot, flags) < 0)
> +        return virtDBusUtilSetLastVirtError(error);
> +}
> +
> +static void
> +virtDBusDomainSnapshotGetParent(GVariant *inArgs,
> +                                 GUnixFDList *inFDs G_GNUC_UNUSED,
> +                                 const gchar *objectPath,
> +                                 gpointer userData,
> +                                 GVariant **outArgs G_GNUC_UNUSED,
> +                                 GUnixFDList **outFDs G_GNUC_UNUSED,
> +                                 GError **error)

Wrong indentation here.

> +{
> +    virtDBusConnect *connect = userData;
> +    g_autoptr(virDomainSnapshot) domainSnapshot = NULL;
> +    g_autoptr(virDomainSnapshot) parent = NULL;
> +    guint flags;
> +    g_autofree gchar *domainName = NULL;
> +    g_autoptr(virDomain) domain = NULL;
> +    gsize prefixLen = strlen(connect->domainSnapshotPath) + 1;
> +    gchar** strings = g_strsplit(objectPath + prefixLen, "_", 2);
> +    g_autofree gchar *parentPath = NULL;
> +
> +    g_variant_get(inArgs, "(u)", &flags);
> +
> +    domainSnapshot = virtDBusUtilVirDomainSnapshotFromBusPath(connect->connection,
> +                                                              objectPath,
> +                                                              connect->domainSnapshotPath);
> +    if (!domainSnapshot)
> +        return;
> +
> +    parent = virDomainSnapshotGetParent(domainSnapshot, flags);
> +    if (!parent)
> +        return virtDBusUtilSetLastVirtError(error);
> +
> +    domainName = virtDBusUtilDecodeStr(strings[0]);
> +    domain = virDomainLookupByName(connect->connection, domainName);

Why not simply calling virDomainSnapshotGetDomain here?

> +    parentPath = virtDBusUtilBusPathForVirDomainSnapshot(domain,
> +                                                         parent,
> +                                                         connect->domainSnapshotPath);
> +
> +    *outArgs = g_variant_new("(o)", parentPath);
> +}
> +
> +static void
> +virtDBusDomainSnapshotGetXMLDesc(GVariant *inArgs,
> +                                 GUnixFDList *inFDs G_GNUC_UNUSED,
> +                                 const gchar *objectPath,
> +                                 gpointer userData,
> +                                 GVariant **outArgs G_GNUC_UNUSED,
> +                                 GUnixFDList **outFDs G_GNUC_UNUSED,
> +                                 GError **error)
> +{
> +    virtDBusConnect *connect = userData;
> +    g_autoptr(virDomainSnapshot) domainSnapshot = NULL;
> +    guint flags;
> +    g_autofree gchar *xml = NULL;
> +
> +    g_variant_get(inArgs, "(u)", &flags);
> +
> +    domainSnapshot = virtDBusUtilVirDomainSnapshotFromBusPath(connect->connection,
> +                                                              objectPath,
> +                                                              connect->domainSnapshotPath);
> +    if (!domainSnapshot)
> +        return;
> +
> +    xml = virDomainSnapshotGetXMLDesc(domainSnapshot, flags);
> +    if (!xml)
> +        return virtDBusUtilSetLastVirtError(error);
> +
> +    *outArgs = g_variant_new("(s)", xml);
> +}
> +
> +static void
> +virtDBusDomainSnapshotIsCurrent(GVariant *inArgs,
> +                                GUnixFDList *inFDs G_GNUC_UNUSED,
> +                                const gchar *objectPath,
> +                                gpointer userData,
> +                                GVariant **outArgs G_GNUC_UNUSED,
> +                                GUnixFDList **outFDs G_GNUC_UNUSED,
> +                                GError **error)
> +{
> +    virtDBusConnect *connect = userData;
> +    g_autoptr(virDomainSnapshot) domainSnapshot = NULL;
> +    guint flags;
> +    gint isCurrent;
> +
> +    g_variant_get(inArgs, "(u)", &flags);
> +
> +    domainSnapshot = virtDBusUtilVirDomainSnapshotFromBusPath(connect->connection,
> +                                                              objectPath,
> +                                                              connect->domainSnapshotPath);
> +    if (!domainSnapshot)
> +        return;
> +
> +    isCurrent = virDomainSnapshotIsCurrent(domainSnapshot, flags);
> +    if (isCurrent < 0)
> +        return virtDBusUtilSetLastVirtError(error);
> +
> +    *outArgs = g_variant_new("(b)", !!isCurrent);
> +}
> +
> +static void
> +virtDBusDomainSnapshotListAllChildren(GVariant *inArgs,
> +                                      GUnixFDList *inFDs G_GNUC_UNUSED,
> +                                      const gchar *objectPath,
> +                                      gpointer userData,
> +                                      GVariant **outArgs G_GNUC_UNUSED,
> +                                      GUnixFDList **outFDs G_GNUC_UNUSED,
> +                                      GError **error)
> +{
> +    virtDBusConnect *connect = userData;
> +    g_autoptr(virDomainSnapshot) domainSnapshot = NULL;
> +    g_autoptr(virDomainSnapshotPtr) snaps = NULL;
> +    guint flags;
> +    GVariantBuilder builder;
> +    GVariant *gdomainSnapshots;
> +    g_autofree gchar *domainName = NULL;
> +    g_autoptr(virDomain) domain = NULL;
> +    gsize prefixLen = strlen(connect->domainSnapshotPath) + 1;
> +    gchar** strings = g_strsplit(objectPath + prefixLen, "_", 2);
> +
> +    g_variant_get(inArgs, "(u)", &flags);
> +
> +    domainSnapshot = virtDBusUtilVirDomainSnapshotFromBusPath(connect->connection,
> +                                                              objectPath,
> +                                                              connect->domainSnapshotPath);
> +    if (!domainSnapshot)
> +        return;
> +
> +    if (virDomainSnapshotListAllChildren(domainSnapshot, &snaps, flags) < 0)
> +        return virtDBusUtilSetLastVirtError(error);
> +
> +    g_variant_builder_init(&builder, G_VARIANT_TYPE("ao"));
> +
> +    domainName = virtDBusUtilDecodeStr(strings[0]);
> +    domain = virDomainLookupByName(connect->connection, domainName);

Again no need to do this magic, you can simply call
virDomainSnapshotGetDomain here.

> +    for (gint i = 0; snaps[i]; i++) {
> +        g_autofree gchar *path = NULL;
> +        path = virtDBusUtilBusPathForVirDomainSnapshot(domain,
> +                                                       snaps[i],
> +                                                       connect->domainSnapshotPath);
> +
> +        g_variant_builder_add(&builder, "o", path);
> +    }
> +
> +    gdomainSnapshots = g_variant_builder_end(&builder);
> +    *outArgs = g_variant_new_tuple(&gdomainSnapshots, 1);
> +}
> +
> +static void
> +virtDBusDomainSnapshotRevert(GVariant *inArgs,
> +                             GUnixFDList *inFDs G_GNUC_UNUSED,
> +                             const gchar *objectPath,
> +                             gpointer userData,
> +                             GVariant **outArgs G_GNUC_UNUSED,
> +                             GUnixFDList **outFDs G_GNUC_UNUSED,
> +                             GError **error)
> +{
> +    virtDBusConnect *connect = userData;
> +    g_autoptr(virDomainSnapshot) domainSnapshot = NULL;
> +    guint flags;
> +
> +    g_variant_get(inArgs, "(u)", &flags);
> +
> +    domainSnapshot = virtDBusUtilVirDomainSnapshotFromBusPath(connect->connection,
> +                                                              objectPath,
> +                                                              connect->domainSnapshotPath);
> +    if (!domainSnapshot)
> +        return;
> +
> +    if (virDomainRevertToSnapshot(domainSnapshot, flags) < 0)
> +        return virtDBusUtilSetLastVirtError(error);
> +}
> +
>  static virtDBusGDBusPropertyTable virtDBusDomainSnapshotPropertyTable[] = {
>      { 0 }
>  };
>  
>  static virtDBusGDBusMethodTable virtDBusDomainSnapshotMethodTable[] = {
> -    { 0 }
> +    { "Delete", virtDBusDomainSnapshotDelete },
> +    { "GetParent", virtDBusDomainSnapshotGetParent },
> +    { "GetXMLDesc", virtDBusDomainSnapshotGetXMLDesc },
> +    /* Needs to be method since it takes 'flags' parameter */

I don't think we need to have this comment, but I'll leave it up to you
to keep it or not.

> +    { "IsCurrent", virtDBusDomainSnapshotIsCurrent },
> +    { "ListChildren", virtDBusDomainSnapshotListAllChildren },
> +    { "Revert", virtDBusDomainSnapshotRevert },
>  };
>  
>  static gchar **
> diff --git a/tests/libvirttest.py b/tests/libvirttest.py
> index a442196..8462fc3 100644
> --- a/tests/libvirttest.py
> +++ b/tests/libvirttest.py
> @@ -112,6 +112,20 @@ class BaseTestClass():
>          """
>          return self.node_device_create()
>  
> +    @pytest.fixture
> +    def snapshot_create(self):
> +        """ Fixture to create simple snapshot the test driver

This reads weird, there is something missing in that sentence.

> +
> +        This fixture should be used in the setup of every test manipulating
> +        with snaphots.
> +        """
> +        _, test_domain = self.get_test_domain()
> +        interface_obj = dbus.Interface(test_domain, 'org.libvirt.Domain')

This cannot work as the `test_domain` is already an dbus.Interface
object.

> +        path = interface_obj.SnapshotCreateXML(xmldata.minimal_snapshot_xml, 0)

Here you should be able to use test_domain.SnapshotCreateXML() directly.

> +        obj = self.bus.get_object('org.libvirt', path)
> +        interface_obj = dbus.Interface(obj, 'org.libvirt.DomainSnapshot')
> +        return interface_obj

No need to use variable for this, you can return the interface object
directly.

> +
>      @pytest.fixture
>      def storage_volume_create(self):
>          """ Fixture to create dummy storage volume on the test driver
> diff --git a/tests/meson.build b/tests/meson.build
> index b6d4bd5..0ad5cdb 100644
> --- a/tests/meson.build
> +++ b/tests/meson.build
> @@ -22,6 +22,7 @@ test('test_util', test_exec, suite: 'unit')
>  python_tests = [
>      'test_connect.py',
>      'test_domain.py',
> +    'test_snapshot.py',
>      'test_interface.py',
>      'test_network.py',
>      'test_nodedev.py',
> diff --git a/tests/test_domain.py b/tests/test_domain.py
> index b5879b4..fdb5aa4 100755
> --- a/tests/test_domain.py
> +++ b/tests/test_domain.py
> @@ -2,6 +2,7 @@
>  
>  import dbus
>  import libvirttest
> +import xmldata
>  
>  DBUS_EXCEPTION_MISSING_FUNCTION = 'this function is not supported by the connection driver'
>  
> @@ -160,6 +161,13 @@ class TestDomain(libvirttest.BaseTestClass):
>          pinInfo = domain.GetVcpuPinInfo(0)
>          assert pinInfo == pinInfo_expected
>  
> +    def test_snapshot(self):
> +        obj, domain = self.get_test_domain()
> +        domain.SnapshotCreateXML(xmldata.minimal_snapshot_xml, 0)
> +        assert isinstance(domain.SnapshotCurrent(0), dbus.ObjectPath)
> +        assert isinstance(domain.SnapshotLookupByName("my_snapshot", 0), dbus.ObjectPath)
> +        assert isinstance(domain.ListDomainSnapshots(0), dbus.Array)
>  
>  if __name__ == '__main__':
>      libvirttest.run()
> +
> diff --git a/tests/test_snapshot.py b/tests/test_snapshot.py
> new file mode 100755
> index 0000000..e9cc5b9
> --- /dev/null
> +++ b/tests/test_snapshot.py
> @@ -0,0 +1,43 @@
> +#!/usr/bin/env python3
> +
> +import dbus
> +import libvirttest
> +import pytest
> +
> +EXCEPTION_NO_PARENT = 'does not have a parent'
> +
> +@pytest.mark.usefixtures("snapshot_create")
> +class TestSnapshot(libvirttest.BaseTestClass):
> +    """ Tests for methods and properties of the Snapshot snapshot
> +    """
> +
> +    def test_snapshot_delete(self, snapshot_create):
> +        snapshot_obj = snapshot_create
> +        snapshot_obj.Delete(0)
> +
> +    def test_snapshot_get_parent(self, snapshot_create):
> +        snapshot_obj = snapshot_create
> +        try:
> +            snapshot_obj.GetParent(0)
> +        except dbus.exceptions.DBusException as e:
> +            if not any(EXCEPTION_NO_PARENT in arg for arg in e.args):
> +                raise e
> +
> +    def test_snapshot_get_xml(self, snapshot_create):
> +        snapshot_obj = snapshot_create
> +        assert isinstance(snapshot_obj.GetXMLDesc(0), dbus.String)
> +
> +    def test_snapshot_get_is_current(self, snapshot_create):
> +        snapshot_obj = snapshot_create
> +        assert isinstance(snapshot_obj.IsCurrent(0), dbus.Boolean)
> +
> +    def test_snapshot_list_children(self, snapshot_create):
> +        snapshot_obj = snapshot_create
> +        assert isinstance(snapshot_obj.ListChildren(0), dbus.Array)
> +
> +    def test_snapshot_revert(self, snapshot_create):
> +        snapshot_obj = snapshot_create
> +        snapshot_obj.Revert(0)
> +
> +if __name__ == '__main__':
> +    libvirttest.run()
> diff --git a/tests/xmldata.py b/tests/xmldata.py
> index 8075052..0146ccf 100644
> --- a/tests/xmldata.py
> +++ b/tests/xmldata.py
> @@ -54,6 +54,12 @@ minimal_node_device_xml = '''
>  </device>
>  '''
>  
> +minimal_snapshot_xml = '''
> +<domainsnapshot>
> +    <name>my_snapshot</name>
> +</domainsnapshot>
> +'''
> +
>  minimal_storage_pool_xml = '''
>  <pool type='dir'>
>    <name>foo</name>

Otherwise looks good.

Pavel

Attachment: signature.asc
Description: PGP signature

--
libvir-list mailing list
libvir-list@xxxxxxxxxx
https://www.redhat.com/mailman/listinfo/libvir-list

[Index of Archives]     [Virt Tools]     [Libvirt Users]     [Lib OS Info]     [Fedora Users]     [Fedora Desktop]     [Fedora SELinux]     [Big List of Linux Books]     [Yosemite News]     [KDE Users]     [Fedora Tools]

  Powered by Linux