Signed-off-by: Simon Kobyda <skob...@redhat.com>
---
 data/org.libvirt.Domain.xml         |  26 ++++
 data/org.libvirt.DomainSnapshot.xml |  34 +++++
 src/domain.c                        | 154 ++++++++++++++++++++
 src/domainsnapshot.c                | 216 ++++++++++++++++++++++++++++
 tests/libvirttest.py                |  12 ++
 tests/meson.build                   |   1 +
 tests/test_domain.py                |   8 ++
 tests/test_snapshot.py              |  45 ++++++
 tests/xmldata.py                    |   6 +
 9 files changed, 502 insertions(+)
 create mode 100755 tests/test_snapshot.py

diff --git a/data/org.libvirt.Domain.xml b/data/org.libvirt.Domain.xml
index b4ed495..3f108e7 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="domainSnapshots" type="ao" direction="out"/>
+    </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 8ba059f..9e9daac 100644
--- a/data/org.libvirt.DomainSnapshot.xml
+++ b/data/org.libvirt.DomainSnapshot.xml
@@ -3,5 +3,39 @@
 
 <node name="/org/libvirt/domainsnapshot">
   <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="domainSnapshot" type="o" direction="out"/>
+    </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="domainSnapshot" type="b" direction="out"/>
+    </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="domainSnapshots" type="ao" direction="out"/>
+    </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..a656c6a 100644
--- a/src/domain.c
+++ b/src/domain.c
@@ -1857,6 +1857,49 @@ 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);
+    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 +3009,113 @@ 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);
+    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);
+
+    domain = virtDBusDomainGetVirDomain(connect, objectPath, error);
+    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);
+
+    domain = virtDBusDomainGetVirDomain(connect, objectPath, error);
+    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 +3245,7 @@ static virtDBusGDBusMethodTable 
virtDBusDomainMethodTable[] = {
     { "HasManagedSaveImage", virtDBusDomainHasManagedSaveImage },
     { "InjectNMI", virtDBusDomainInjectNMI },
     { "InterfaceAddresses", virtDBusDomainInterfaceAddresses },
+    { "ListDomainSnapshots", virtDBusDomainListDomainSnapshots },
     { "ManagedSave", virtDBusDomainManagedSave },
     { "ManagedSaveRemove", virtDBusDomainManagedSaveRemove },
     { "MemoryPeek", virtDBusDomainMemoryPeek },
@@ -3132,6 +3283,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 c523c9e..f3571a1 100644
--- a/src/domainsnapshot.c
+++ b/src/domainsnapshot.c
@@ -1,13 +1,229 @@
 #include "domainsnapshot.h"
+#include "domain.h"
 #include "util.h"
 
 #include <libvirt/libvirt.h>
 
+static virDomainSnapshotPtr
+virtDBusDomainSnapshotGetVirDomainSnapshot(virtDBusConnect *connect,
+                                           const gchar *objectPath,
+                                           GError **error)
+{
+    virDomainSnapshotPtr domSnap;
+
+    if (!virtDBusConnectOpen(connect, error))
+        return NULL;
+
+    domSnap = virtDBusUtilVirDomainSnapshotFromBusPath(connect->connection,
+                                                       objectPath,
+                                                       
connect->domainSnapshotPath);
+    if (!domSnap) {
+        virtDBusUtilSetLastVirtError(error);
+        return NULL;
+    }
+
+    return domSnap;
+}
+
+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 = virtDBusDomainSnapshotGetVirDomainSnapshot(connect,
+                                                                objectPath,
+                                                                error);
+    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)
+{
+    virtDBusConnect *connect = userData;
+    g_autoptr(virDomainSnapshot) domainSnapshot = NULL;
+    g_autoptr(virDomainSnapshot) parent = NULL;
+    guint flags;
+    g_autoptr(virDomain) domain = NULL;
+    g_autofree gchar *parentPath = NULL;
+
+    g_variant_get(inArgs, "(u)", &flags);
+
+    domainSnapshot = virtDBusDomainSnapshotGetVirDomainSnapshot(connect,
+                                                                objectPath,
+                                                                error);
+    if (!domainSnapshot)
+        return;
+
+    parent = virDomainSnapshotGetParent(domainSnapshot, flags);
+    if (!parent)
+        return virtDBusUtilSetLastVirtError(error);
+
+    domain = virDomainSnapshotGetDomain(domainSnapshot);
+    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 = virtDBusDomainSnapshotGetVirDomainSnapshot(connect,
+                                                                objectPath,
+                                                                error);
+    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 = virtDBusDomainSnapshotGetVirDomainSnapshot(connect,
+                                                                objectPath,
+                                                                error);
+    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_autoptr(virDomain) domain = NULL;
+
+    g_variant_get(inArgs, "(u)", &flags);
+
+    domainSnapshot = virtDBusDomainSnapshotGetVirDomainSnapshot(connect,
+                                                                objectPath,
+                                                                error);
+    if (!domainSnapshot)
+        return;
+
+    if (virDomainSnapshotListAllChildren(domainSnapshot, &snaps, flags) < 0)
+        return virtDBusUtilSetLastVirtError(error);
+
+    g_variant_builder_init(&builder, G_VARIANT_TYPE("ao"));
+
+    domain = virDomainSnapshotGetDomain(domainSnapshot);
+    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 = virtDBusDomainSnapshotGetVirDomainSnapshot(connect,
+                                                                objectPath,
+                                                                error);
+    if (!domainSnapshot)
+        return;
+
+    if (virDomainRevertToSnapshot(domainSnapshot, flags) < 0)
+        return virtDBusUtilSetLastVirtError(error);
+}
+
 static virtDBusGDBusPropertyTable virtDBusDomainSnapshotPropertyTable[] = {
     { 0 }
 };
 
 static virtDBusGDBusMethodTable virtDBusDomainSnapshotMethodTable[] = {
+    { "Delete", virtDBusDomainSnapshotDelete },
+    { "GetParent", virtDBusDomainSnapshotGetParent },
+    { "GetXMLDesc", virtDBusDomainSnapshotGetXMLDesc },
+    { "IsCurrent", virtDBusDomainSnapshotIsCurrent },
+    { "ListChildren", virtDBusDomainSnapshotListAllChildren },
+    { "Revert", virtDBusDomainSnapshotRevert },
     { 0 }
 };
 
diff --git a/tests/libvirttest.py b/tests/libvirttest.py
index a442196..dd181c2 100644
--- a/tests/libvirttest.py
+++ b/tests/libvirttest.py
@@ -112,6 +112,18 @@ class BaseTestClass():
         """
         return self.node_device_create()
 
+    @pytest.fixture
+    def snapshot_create(self):
+        """ Fixture to create simple domain snapshot on the test driver
+
+        This fixture should be used in the setup of every test manipulating
+        with domain snaphots.
+        """
+        _, test_domain = self.get_test_domain()
+        path = test_domain.SnapshotCreateXML(xmldata.minimal_snapshot_xml, 0)
+        obj = self.bus.get_object('org.libvirt', path)
+        return dbus.Interface(obj, 'org.libvirt.DomainSnapshot')
+
     @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..624d25b 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..566f4a6
--- /dev/null
+++ b/tests/test_snapshot.py
@@ -0,0 +1,45 @@
+#!/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>
-- 
2.21.0

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

Reply via email to