Signed-off-by: Michal Privoznik <mprivozn@xxxxxxxxxx> --- 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 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list