Add unit test coverage to prove that the new API works in each of C,
Python, OCaml, and Go bindings.

Signed-off-by: Eric Blake <ebl...@redhat.com>
---

v4: new patch, split out from API addition itself
---
 python/t/465-block-status-64.py           |  56 ++++++++++
 ocaml/tests/Makefile.am                   |   1 +
 ocaml/tests/test_465_block_status_64.ml   |  58 +++++++++++
 tests/meta-base-allocation.c              | 104 ++++++++++++++++---
 golang/Makefile.am                        |   1 +
 golang/libnbd_465_block_status_64_test.go | 119 ++++++++++++++++++++++
 6 files changed, 326 insertions(+), 13 deletions(-)
 create mode 100644 python/t/465-block-status-64.py
 create mode 100644 ocaml/tests/test_465_block_status_64.ml
 create mode 100644 golang/libnbd_465_block_status_64_test.go

diff --git a/python/t/465-block-status-64.py b/python/t/465-block-status-64.py
new file mode 100644
index 00000000..a8a8eaea
--- /dev/null
+++ b/python/t/465-block-status-64.py
@@ -0,0 +1,56 @@
+# libnbd Python bindings
+# Copyright Red Hat
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+import os
+
+import nbd
+
+script = "%s/../tests/meta-base-allocation.sh" % os.getenv("srcdir", ".")
+
+h = nbd.NBD()
+h.add_meta_context("base:allocation")
+h.connect_command(["nbdkit", "-s", "--exit-with-parent", "-v", "sh", script])
+
+entries = []
+
+
+def f(user_data, metacontext, offset, e, err):
+    global entries
+    assert user_data == 42
+    assert err.value == 0
+    if metacontext != "base:allocation":
+        return
+    entries = e
+
+
+h.block_status_64(65536, 0, lambda *args: f(42, *args))
+print("entries = %r" % entries)
+assert entries == [(8192, 0),
+                   (8192, 1),
+                   (16384, 3),
+                   (16384, 2),
+                   (16384, 0)]
+
+h.block_status_64(1024, 32256, lambda *args: f(42, *args))
+print("entries = %r" % entries)
+assert entries == [(512, 3),
+                   (16384, 2)]
+
+h.block_status_64(1024, 32256, lambda *args: f(42, *args),
+                  nbd.CMD_FLAG_REQ_ONE)
+print("entries = %r" % entries)
+assert entries == [(512, 3)]
diff --git a/ocaml/tests/Makefile.am b/ocaml/tests/Makefile.am
index 20546350..4ddd0f9f 100644
--- a/ocaml/tests/Makefile.am
+++ b/ocaml/tests/Makefile.am
@@ -40,6 +40,7 @@ ML_TESTS = \
        test_405_pread_structured.ml \
        test_410_pwrite.ml \
        test_460_block_status.ml \
+       test_465_block_status_64.ml \
        test_500_aio_pread.ml \
        test_505_aio_pread_structured_callback.ml \
        test_510_aio_pwrite.ml \
diff --git a/ocaml/tests/test_465_block_status_64.ml 
b/ocaml/tests/test_465_block_status_64.ml
new file mode 100644
index 00000000..0634a025
--- /dev/null
+++ b/ocaml/tests/test_465_block_status_64.ml
@@ -0,0 +1,58 @@
+(* hey emacs, this is OCaml code: -*- tuareg -*- *)
+(* libnbd OCaml test case
+ * Copyright Red Hat
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *)
+
+open Printf
+
+let script =
+  try
+    let srcdir = Sys.getenv "srcdir" in
+    sprintf "%s/../../tests/meta-base-allocation.sh" srcdir
+  with
+    Not_found -> failwith "error: srcdir is not defined"
+
+let entries = ref [||]
+let f user_data metacontext offset e err =
+  assert (user_data = 42);
+  assert (!err = 0);
+  if metacontext = "base:allocation" then
+    entries := e;
+  0
+
+let () =
+  let nbd = NBD.create () in
+  NBD.add_meta_context nbd "base:allocation";
+  NBD.connect_command nbd ["nbdkit"; "-s"; "--exit-with-parent"; "-v";
+                           "sh"; script];
+
+  NBD.block_status_64 nbd 65536_L 0_L (f 42);
+  assert (!entries = [|  8192_L, 0_L;
+                         8192_L, 1_L;
+                        16384_L, 3_L;
+                        16384_L, 2_L;
+                        16384_L, 0_L |]);
+
+  NBD.block_status_64 nbd 1024_L 32256_L (f 42);
+  assert (!entries = [|   512_L, 3_L;
+                        16384_L, 2_L |]);
+
+  let flags = let open NBD.CMD_FLAG in [REQ_ONE] in
+  NBD.block_status_64 nbd 1024_L 32256_L (f 42) ~flags;
+  assert (!entries = [|   512_L, 3_L |])
+
+let () = Gc.compact ()
diff --git a/tests/meta-base-allocation.c b/tests/meta-base-allocation.c
index a7b3af09..7697b5da 100644
--- a/tests/meta-base-allocation.c
+++ b/tests/meta-base-allocation.c
@@ -32,10 +32,13 @@

 #define BOGUS_CONTEXT "x-libnbd:nosuch"

-static int check_extent (void *data,
-                         const char *metacontext,
-                         uint64_t offset,
-                         uint32_t *entries, size_t nr_entries, int *error);
+static int check_extent32 (void *data, const char *metacontext,
+                           uint64_t offset,
+                           uint32_t *entries, size_t nr_entries, int *error);
+
+static int check_extent64 (void *data, const char *metacontext,
+                           uint64_t offset,
+                           nbd_extent *entries, size_t nr_entries, int *error);

 int
 main (int argc, char *argv[])
@@ -43,8 +46,10 @@ main (int argc, char *argv[])
   struct nbd_handle *nbd;
   char plugin_path[256];
   int id;
-  nbd_extent_callback extent_callback = { .callback = check_extent,
-                                          .user_data = &id };
+  nbd_extent_callback extent32_callback = { .callback = check_extent32,
+                                            .user_data = &id };
+  nbd_extent64_callback extent64_callback = { .callback = check_extent64,
+                                              .user_data = &id };
   int r;
   const char *s;
   char *tmp;
@@ -150,23 +155,36 @@ main (int argc, char *argv[])

   /* Read the block status. */
   id = 1;
-  if (nbd_block_status (nbd, 65536, 0, extent_callback, 0) == -1) {
+  if (nbd_block_status (nbd, 65536, 0, extent32_callback, 0) == -1) {
+    fprintf (stderr, "%s\n", nbd_get_error ());
+    exit (EXIT_FAILURE);
+  }
+  if (nbd_block_status_64 (nbd, 65536, 0, extent64_callback, 0) == -1) {
     fprintf (stderr, "%s\n", nbd_get_error ());
     exit (EXIT_FAILURE);
   }

   id = 2;
-  if (nbd_block_status (nbd, 1024, 32768-512, extent_callback, 0) == -1) {
+  if (nbd_block_status (nbd, 1024, 32768-512, extent32_callback, 0) == -1) {
+    fprintf (stderr, "%s\n", nbd_get_error ());
+    exit (EXIT_FAILURE);
+  }
+  if (nbd_block_status_64 (nbd, 1024, 32768-512, extent64_callback, 0) == -1) {
     fprintf (stderr, "%s\n", nbd_get_error ());
     exit (EXIT_FAILURE);
   }

   id = 3;
-  if (nbd_block_status (nbd, 1024, 32768-512, extent_callback,
+  if (nbd_block_status (nbd, 1024, 32768-512, extent32_callback,
                         LIBNBD_CMD_FLAG_REQ_ONE) == -1) {
     fprintf (stderr, "%s\n", nbd_get_error ());
     exit (EXIT_FAILURE);
   }
+  if (nbd_block_status_64 (nbd, 1024, 32768-512, extent64_callback,
+                           LIBNBD_CMD_FLAG_REQ_ONE) == -1) {
+    fprintf (stderr, "%s\n", nbd_get_error ());
+    exit (EXIT_FAILURE);
+  }

   if (nbd_shutdown (nbd, 0) == -1) {
     fprintf (stderr, "%s\n", nbd_get_error ());
@@ -178,10 +196,8 @@ main (int argc, char *argv[])
 }

 static int
-check_extent (void *data,
-              const char *metacontext,
-              uint64_t offset,
-              uint32_t *entries, size_t nr_entries, int *error)
+check_extent32 (void *data, const char *metacontext, uint64_t offset,
+                uint32_t *entries, size_t nr_entries, int *error)
 {
   size_t i;
   int id;
@@ -235,3 +251,65 @@ check_extent (void *data,

   return 0;
 }
+
+static int
+check_extent64 (void *data, const char *metacontext, uint64_t offset,
+                nbd_extent *entries, size_t nr_entries, int *error)
+{
+  size_t i;
+  int id;
+
+  id = * (int *)data;
+
+  printf ("extent: id=%d, metacontext=%s, offset=%" PRIu64 ", "
+          "nr_entries=%zu, error=%d\n",
+          id, metacontext, offset, nr_entries, *error);
+
+  assert (*error == 0);
+  if (strcmp (metacontext, LIBNBD_CONTEXT_BASE_ALLOCATION) == 0) {
+    for (i = 0; i < nr_entries; i++) {
+      printf ("\t%zu\tlength=%" PRIu64 ", status=%" PRIu64 "\n",
+              i, entries[i].length, entries[i].flags);
+    }
+    fflush (stdout);
+
+    switch (id) {
+    case 1:
+      assert (nr_entries == 5);
+      assert (entries[0].length == 8192);
+      assert (entries[0].flags == 0);
+      assert (entries[1].length == 8192);
+      assert (entries[1].flags == LIBNBD_STATE_HOLE);
+      assert (entries[2].length == 16384);
+      assert (entries[2].flags == (LIBNBD_STATE_HOLE|LIBNBD_STATE_ZERO));
+      assert (entries[3].length == 16384);
+      assert (entries[3].flags == LIBNBD_STATE_ZERO);
+      assert (entries[4].length == 16384);
+      assert (entries[4].flags == 0);
+      break;
+
+    case 2:
+      assert (nr_entries == 2);
+      assert (entries[0].length == 512);
+      assert (entries[0].flags == (LIBNBD_STATE_HOLE|LIBNBD_STATE_ZERO));
+      assert (entries[1].length == 16384);
+      assert (entries[1].flags == LIBNBD_STATE_ZERO);
+      break;
+
+    case 3:
+      assert (nr_entries == 1);
+      assert (entries[0].length == 512);
+      assert (entries[0].flags == (LIBNBD_STATE_HOLE|LIBNBD_STATE_ZERO));
+      break;
+
+    default:
+      abort ();
+    }
+
+  }
+  else
+    fprintf (stderr, "warning: ignored unexpected meta context %s\n",
+             metacontext);
+
+  return 0;
+}
diff --git a/golang/Makefile.am b/golang/Makefile.am
index fac65248..b4151250 100644
--- a/golang/Makefile.am
+++ b/golang/Makefile.am
@@ -43,6 +43,7 @@ source_files = \
        libnbd_405_pread_structured_test.go \
        libnbd_410_pwrite_test.go \
        libnbd_460_block_status_test.go \
+       libnbd_465_block_status_64_test.go \
        libnbd_500_aio_pread_test.go \
        libnbd_510_aio_pwrite_test.go \
        libnbd_590_aio_copy_test.go \
diff --git a/golang/libnbd_465_block_status_64_test.go 
b/golang/libnbd_465_block_status_64_test.go
new file mode 100644
index 00000000..7659a21d
--- /dev/null
+++ b/golang/libnbd_465_block_status_64_test.go
@@ -0,0 +1,119 @@
+/* libnbd golang tests
+ * Copyright Red Hat
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+package libnbd
+
+import (
+       "fmt"
+       "os"
+       "strings"
+       "testing"
+)
+
+var entries64 []LibnbdExtent
+
+func mcf64(metacontext string, offset uint64, e []LibnbdExtent, error *int) 
int {
+       if *error != 0 {
+               panic("expected *error == 0")
+       }
+       if metacontext == "base:allocation" {
+               entries64 = e
+       }
+       return 0
+}
+
+// Seriously WTF?
+func mc64_compare(a1 []LibnbdExtent, a2 []LibnbdExtent) bool {
+       if len(a1) != len(a2) {
+               return false
+       }
+       for i := 0; i < len(a1); i++ {
+               if a1[i] != a2[i] {
+                       return false
+               }
+       }
+       return true
+}
+
+func mc64_to_string(a []LibnbdExtent) string {
+       ss := make([]string, len(a))
+       for i := 0; i < len(a); i++ {
+               ss[i] = fmt.Sprintf("%#v", a[i])
+       }
+       return strings.Join(ss, ", ")
+}
+
+func Test465BlockStatus64(t *testing.T) {
+       srcdir := os.Getenv("abs_top_srcdir")
+       script := srcdir + "/tests/meta-base-allocation.sh"
+
+       h, err := Create()
+       if err != nil {
+               t.Fatalf("could not create handle: %s", err)
+       }
+       defer h.Close()
+
+       err = h.AddMetaContext("base:allocation")
+       if err != nil {
+               t.Fatalf("%s", err)
+       }
+       err = h.ConnectCommand([]string{
+               "nbdkit", "-s", "--exit-with-parent", "-v",
+               "sh", script,
+       })
+       if err != nil {
+               t.Fatalf("%s", err)
+       }
+
+       err = h.BlockStatus64(65536, 0, mcf64, nil)
+       if err != nil {
+               t.Fatalf("%s", err)
+       }
+       if !mc64_compare(entries64, []LibnbdExtent{
+               {8192, 0},
+               {8192, 1},
+               {16384, 3},
+               {16384, 2},
+               {16384, 0},
+       }) {
+               t.Fatalf("unexpected entries (1): %s", 
mc64_to_string(entries64))
+       }
+
+       err = h.BlockStatus64(1024, 32256, mcf64, nil)
+       if err != nil {
+               t.Fatalf("%s", err)
+       }
+       if !mc64_compare(entries64, []LibnbdExtent{
+               {512, 3},
+               {16384, 2},
+       }) {
+               t.Fatalf("unexpected entries (2): %s", 
mc64_to_string(entries64))
+       }
+
+       var optargs BlockStatus64Optargs
+       optargs.FlagsSet = true
+       optargs.Flags = CMD_FLAG_REQ_ONE
+       err = h.BlockStatus64(1024, 32256, mcf64, &optargs)
+       if err != nil {
+               t.Fatalf("%s", err)
+       }
+       if !mc64_compare(entries64, []LibnbdExtent{{512, 3}}) {
+               t.Fatalf("unexpected entries (3): %s", 
mc64_to_string(entries64))
+       }
+
+}
-- 
2.41.0

_______________________________________________
Libguestfs mailing list
Libguestfs@redhat.com
https://listman.redhat.com/mailman/listinfo/libguestfs

Reply via email to