[libvirt] [PATCH RFC 7/8] fdstreamtest: Test virStreamRecvOffset

Michal Privoznik mprivozn at redhat.com
Fri Jan 29 13:26:58 UTC 2016


Signed-off-by: Michal Privoznik <mprivozn at redhat.com>
---
 tests/fdstreamtest.c | 62 ++++++++++++++++++++++++++++++++++++++++++----------
 1 file changed, 51 insertions(+), 11 deletions(-)

diff --git a/tests/fdstreamtest.c b/tests/fdstreamtest.c
index f9caebf..5036cec 100644
--- a/tests/fdstreamtest.c
+++ b/tests/fdstreamtest.c
@@ -51,9 +51,11 @@ testFDStreamReadCommon(const char *scratchdir, const unsigned int flags)
     virStreamPtr st = NULL;
     size_t i;
     virConnectPtr conn = NULL;
+    unsigned long long streamOffset;
     bool blocking = !(flags & VIR_STREAM_NONBLOCK);
+    bool sparse = flags & VIR_STREAM_SPARSE;
 
-    virCheckFlags(VIR_STREAM_NONBLOCK, -1);
+    virCheckFlags(VIR_STREAM_NONBLOCK | VIR_STREAM_SPARSE, -1);
 
     if (!(conn = virConnectOpen("test:///default")))
         goto cleanup;
@@ -72,6 +74,10 @@ testFDStreamReadCommon(const char *scratchdir, const unsigned int flags)
         goto cleanup;
 
     for (i = 0; i < 10; i++) {
+        if (i && sparse &&
+            lseek(fd, 8192, SEEK_CUR) < 0)
+            goto cleanup;
+
         if (safewrite(fd, pattern, PATTERN_LEN) != PATTERN_LEN)
             goto cleanup;
     }
@@ -82,17 +88,23 @@ testFDStreamReadCommon(const char *scratchdir, const unsigned int flags)
     if (!(st = virStreamNew(conn, flags)))
         goto cleanup;
 
-    /* Start reading 1/2 way through first pattern
-     * and end 1/2 way through last pattern
+    /* Start reading 1/2 way through first pattern and end 1/2
+     * way through last pattern. In case of sparse file between
+     * each data blocks is one hole.
      */
+    streamOffset = PATTERN_LEN / 2;
     if (virFDStreamOpenFile(st, file,
-                            PATTERN_LEN / 2, PATTERN_LEN * 9,
+                            streamOffset,
+                            sparse ? PATTERN_LEN * 18 : PATTERN_LEN * 9,
                             O_RDONLY) < 0)
         goto cleanup;
 
     for (i = 0; i < 10; i++) {
         size_t offset = 0;
         size_t want;
+        bool data = true;
+        unsigned long long oldStreamOffset = streamOffset;
+
         if (i == 0)
             want = PATTERN_LEN / 2;
         else
@@ -101,7 +113,12 @@ testFDStreamReadCommon(const char *scratchdir, const unsigned int flags)
         while (want > 0) {
             int got;
         reread:
-            got = st->driver->streamRecv(st, buf + offset, want);
+            if (sparse)
+                got = st->driver->streamRecvOffset(st, &oldStreamOffset,
+                                                   buf + offset, want);
+            else
+                got = st->driver->streamRecv(st, buf + offset, want);
+
             if (got < 0) {
                 if (got == -2 && !blocking) {
                     usleep(20 * 1000);
@@ -112,16 +129,33 @@ testFDStreamReadCommon(const char *scratchdir, const unsigned int flags)
                 goto cleanup;
             }
             if (got == 0) {
-                /* Expect EOF 1/2 through last pattern */
-                if (i == 9 && want == (PATTERN_LEN / 2))
-                    break;
-                virFilePrintf(stderr, "Unexpected EOF block %zu want %zu\n",
-                              i, want);
-                goto cleanup;
+                if (sparse &&
+                    oldStreamOffset != streamOffset) {
+                    /* oldStreamOffset points to data position. Re-read. */
+                    if (data) {
+                        virFilePrintf(stderr, "Unexpected hole at offset %llu\n",
+                                      streamOffset);
+                    }
+                    data = !data;
+                    streamOffset = oldStreamOffset;
+                    goto reread;
+                } else {
+                    /* Expect EOF 1/2 through last pattern */
+                    if (i == 9 && want == (PATTERN_LEN / 2))
+                        break;
+                    virFilePrintf(stderr, "Unexpected EOF block %zu want %zu\n",
+                                  i, want);
+                    goto cleanup;
+                }
             }
+            if (i == 0)
+                streamOffset = 8192 + PATTERN_LEN;
+            else
+                streamOffset += 8192 + PATTERN_LEN;
             offset += got;
             want -= got;
         }
+
         if (i == 0) {
             if (memcmp(buf, pattern + (PATTERN_LEN / 2), PATTERN_LEN / 2) != 0) {
                 virFilePrintf(stderr, "Mismatched pattern data iteration %zu\n", i);
@@ -170,6 +204,10 @@ static int testFDStreamReadNonblock(const void *data)
 {
     return testFDStreamReadCommon(data, VIR_STREAM_NONBLOCK);
 }
+static int testFDStreamSparseReadBlock(const void *data)
+{
+    return testFDStreamReadCommon(data, VIR_STREAM_SPARSE);
+}
 
 
 static int testFDStreamWriteCommon(const char *scratchdir, const unsigned int flags)
@@ -334,6 +372,8 @@ mymain(void)
         ret = -1;
     if (virtTestRun("Stream write non-blocking ", testFDStreamWriteNonblock, scratchdir) < 0)
         ret = -1;
+    if (virtTestRun("Sparse stream read blocking ", testFDStreamSparseReadBlock, scratchdir) < 0)
+        ret = -1;
 
     if (getenv("LIBVIRT_SKIP_CLEANUP") == NULL)
         virFileDeleteTree(scratchdir);
-- 
2.4.10




More information about the libvir-list mailing list