* [PATCH v2 liburing] Test consistent file position updates
@ 2022-02-21 14:18 Dylan Yudaken
2022-02-21 16:29 ` Jens Axboe
0 siblings, 1 reply; 3+ messages in thread
From: Dylan Yudaken @ 2022-02-21 14:18 UTC (permalink / raw)
To: Jens Axboe, Pavel Begunkov, io-uring; +Cc: kernel-team, Dylan Yudaken
read(2)/write(2) and friends support sequential reads without giving an
explicit offset. The result of these should leave the file with an
incremented offset.
Add tests for both read and write to check that io_uring behaves
consistently in these scenarios. Expect that if you queue many
reads/writes, and set the IOSQE_IO_LINK flag, that they will behave
similarly to calling read(2)/write(2) in sequence.
Set IOSQE_ASYNC as well in a set of tests. This exacerbates the problem by
forcing work to happen in different threads to submission.
Also add tests for not setting IOSQE_IO_LINK, but allow the file offset to
progress past the end of the file.
Signed-off-by: Dylan Yudaken <[email protected]>
---
v2:
- fixed a bug in how cqe ordering was processed
- enforce sequential reads for !IOSQE_IO_LINK
test/Makefile | 1 +
test/fpos.c | 270 ++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 271 insertions(+)
create mode 100644 test/fpos.c
diff --git a/test/Makefile b/test/Makefile
index 1e318f7..f421f53 100644
--- a/test/Makefile
+++ b/test/Makefile
@@ -78,6 +78,7 @@ test_srcs := \
file-update.c \
file-verify.c \
fixed-link.c \
+ fpos.c \
fsync.c \
hardlink.c \
io-cancel.c \
diff --git a/test/fpos.c b/test/fpos.c
new file mode 100644
index 0000000..2c6c139
--- /dev/null
+++ b/test/fpos.c
@@ -0,0 +1,270 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Description: test io_uring fpos handling
+ *
+ */
+#include <errno.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <fcntl.h>
+#include <assert.h>
+
+#include "helpers.h"
+#include "liburing.h"
+
+#define FILE_SIZE 10000
+#define QUEUE_SIZE 4096
+
+static void create_file(const char *file, size_t size)
+{
+ ssize_t ret;
+ char *buf;
+ size_t idx;
+ int fd;
+
+ buf = t_malloc(size);
+ for (idx = 0; idx < size; ++idx) {
+ /* write 0 or 1 */
+ buf[idx] = (unsigned char)(idx & 0x01);
+ }
+
+ fd = open(file, O_WRONLY | O_CREAT, 0644);
+ assert(fd >= 0);
+
+ ret = write(fd, buf, size);
+ fsync(fd);
+ close(fd);
+ free(buf);
+ assert(ret == size);
+}
+
+static int
+test_read(struct io_uring *ring, bool async, bool link, int blocksize)
+{
+ int ret, fd, i;
+ bool done = false;
+ struct io_uring_sqe *sqe;
+ struct io_uring_cqe *cqe;
+ loff_t current, expected = 0;
+ int count_ok;
+ int count_0 = 0, count_1 = 0;
+ unsigned char buff[QUEUE_SIZE * blocksize];
+ unsigned char reordered[QUEUE_SIZE * blocksize];
+
+ create_file(".test_read", FILE_SIZE);
+ fd = open(".test_read", O_RDONLY);
+ unlink(".test_read");
+ assert(fd >= 0);
+
+ while (!done) {
+ for (i = 0; i < QUEUE_SIZE; ++i) {
+ sqe = io_uring_get_sqe(ring);
+ if (!sqe) {
+ fprintf(stderr, "no sqe\n");
+ return -1;
+ }
+ io_uring_prep_read(sqe, fd,
+ buff + i * blocksize,
+ blocksize, -1);
+ sqe->user_data = i;
+ if (async)
+ sqe->flags |= IOSQE_ASYNC;
+ if (link && i != QUEUE_SIZE - 1)
+ sqe->flags |= IOSQE_IO_LINK;
+ }
+ ret = io_uring_submit_and_wait(ring, QUEUE_SIZE);
+ if (ret != QUEUE_SIZE) {
+ fprintf(stderr, "submit failed: %d\n", ret);
+ return 1;
+ }
+ count_ok = 0;
+ for (i = 0; i < QUEUE_SIZE; ++i) {
+ int res;
+
+ ret = io_uring_peek_cqe(ring, &cqe);
+ if (ret) {
+ fprintf(stderr, "peek failed: %d\n", ret);
+ return ret;
+ }
+ assert(cqe->user_data < QUEUE_SIZE);
+ memcpy(reordered + count_ok
+ , buff + cqe->user_data * blocksize
+ , blocksize);
+ res = cqe->res;
+ io_uring_cqe_seen(ring, cqe);
+ if (res == 0) {
+ done = true;
+ } else if (res == -ECANCELED) {
+ /* cancelled, probably ok */
+ } else if (res < 0 || res > blocksize) {
+ fprintf(stderr, "bad read: %d\n", res);
+ return -1;
+ } else {
+ expected += res;
+ count_ok += res;
+ }
+ }
+ ret = 0;
+ for (i = 0; i < count_ok; i++) {
+ if (reordered[i] == 1) {
+ count_1++;
+ } else if (reordered[i] == 0) {
+ count_0++;
+ } else {
+ fprintf(stderr, "odd read %d\n",
+ (int)reordered[i]);
+ ret = -1;
+ break;
+ }
+ }
+ if (labs(count_1 - count_0) > 1) {
+ fprintf(stderr, "inconsistent reads, got 0s:%d 1s:%d\n",
+ count_0, count_1);
+ ret = -1;
+ }
+ current = lseek(fd, 0, SEEK_CUR);
+ if (current != expected) {
+ bool ignore = current > expected && !link;
+ fprintf(stderr,
+ "f_pos incorrect, expected %ld have %ld%s\n",
+ expected,
+ current,
+ ignore ? ", (ignoring as it is accepted)":"");
+ if (!ignore)
+ ret = -1;
+ }
+ if (ret)
+ return ret;
+ }
+ return 0;
+}
+
+
+static int
+test_write(struct io_uring *ring, bool async, bool link, int blocksize)
+{
+ int ret, fd, i;
+ struct io_uring_sqe *sqe;
+ struct io_uring_cqe *cqe;
+ bool fail = false;
+ loff_t current;
+ char data[blocksize+1];
+ char readbuff[QUEUE_SIZE*blocksize+1];
+
+ fd = open(".test_write", O_RDWR | O_CREAT, 0644);
+ unlink(".test_write");
+ assert(fd >= 0);
+
+ for(i = 0; i < blocksize; i++) {
+ data[i] = 'A' + i;
+ }
+ data[blocksize] = '\0';
+
+ for (i = 0; i < QUEUE_SIZE; ++i) {
+ sqe = io_uring_get_sqe(ring);
+ if (!sqe) {
+ fprintf(stderr, "no sqe\n");
+ return -1;
+ }
+ io_uring_prep_write(sqe, fd, data + (i % blocksize), 1, -1);
+ sqe->user_data = 1;
+ if (async)
+ sqe->flags |= IOSQE_ASYNC;
+ if (link && i != QUEUE_SIZE - 1)
+ sqe->flags |= IOSQE_IO_LINK;
+ }
+ ret = io_uring_submit_and_wait(ring, QUEUE_SIZE);
+ if (ret != QUEUE_SIZE) {
+ fprintf(stderr, "submit failed: %d\n", ret);
+ return 1;
+ }
+ for (i = 0; i < QUEUE_SIZE; ++i) {
+ int res;
+
+ ret = io_uring_peek_cqe(ring, &cqe);
+ res = cqe->res;
+ if (ret) {
+ fprintf(stderr, "peek failed: %d\n", ret);
+ return ret;
+ }
+ io_uring_cqe_seen(ring, cqe);
+ if (!fail && res != 1) {
+ fprintf(stderr, "bad result %d\n", res);
+ fail = true;
+ }
+ }
+ current = lseek(fd, 0, SEEK_CUR);
+ if (current != QUEUE_SIZE) {
+ fprintf(stderr,
+ "f_pos incorrect, expected %ld have %d\n",
+ current,
+ QUEUE_SIZE);
+ fail = true;
+ }
+ current = lseek(fd, 0, SEEK_SET);
+ if (current != 0) {
+ perror("seek to start");
+ return -1;
+ }
+ ret = read(fd, readbuff, QUEUE_SIZE);
+ if (ret != QUEUE_SIZE) {
+ fprintf(stderr, "did not write enough: %d\n", ret);
+ return -1;
+ }
+ i = 0;
+ while (i < QUEUE_SIZE - blocksize) {
+ if (strncmp(readbuff + i, data, blocksize)) {
+ char bad[QUEUE_SIZE+1];
+
+ memcpy(bad, readbuff + i, blocksize);
+ bad[blocksize] = '\0';
+ fprintf(stderr, "unexpected data %s\n", bad);
+ fail = true;
+ }
+ i += blocksize;
+ }
+
+ return fail ? -1 : 0;
+}
+
+
+int main(int argc, char *argv[])
+{
+ struct io_uring ring;
+ int ret;
+ int failed = 0;
+ int blocksizes[] = {1, 8, 15, 0};
+
+ if (argc > 1)
+ return 0;
+
+ ret = io_uring_queue_init(QUEUE_SIZE, &ring, 0);
+ if (ret) {
+ fprintf(stderr, "ring setup failed\n");
+ return 1;
+ }
+
+ for (int *blocksize = blocksizes; *blocksize; blocksize++) {
+ for (int async = 0; async < 2; async++) {
+ for (int link = 0; link < 2; link++) {
+ for (int write = 0; write < 2; write++) {
+ fprintf(stderr, "*********\n");
+ ret = write
+ ? test_write(&ring, !!async, !!link, *blocksize)
+ : test_read(&ring, !!async, !!link, *blocksize);
+ fprintf(stderr, "test %s async=%d link=%d blocksize=%d:\t%s\n",
+ write ? "write":"read",
+ async, link,
+ *blocksize,
+ ret ? "failed" : "passed");
+
+ if (ret)
+ failed = 1;
+ }
+ }
+ }
+ }
+ return failed ? -1 : 0;
+}
base-commit: 20bb37e0f828909742f845b8113b2bb7e1065cd1
--
2.30.2
^ permalink raw reply related [flat|nested] 3+ messages in thread
* Re: [PATCH v2 liburing] Test consistent file position updates
2022-02-21 14:18 [PATCH v2 liburing] Test consistent file position updates Dylan Yudaken
@ 2022-02-21 16:29 ` Jens Axboe
2022-02-21 17:56 ` Dylan Yudaken
0 siblings, 1 reply; 3+ messages in thread
From: Jens Axboe @ 2022-02-21 16:29 UTC (permalink / raw)
To: Dylan Yudaken, Pavel Begunkov, io-uring; +Cc: kernel-team
On 2/21/22 7:18 AM, Dylan Yudaken wrote:
> read(2)/write(2) and friends support sequential reads without giving an
> explicit offset. The result of these should leave the file with an
> incremented offset.
>
> Add tests for both read and write to check that io_uring behaves
> consistently in these scenarios. Expect that if you queue many
> reads/writes, and set the IOSQE_IO_LINK flag, that they will behave
> similarly to calling read(2)/write(2) in sequence.
>
> Set IOSQE_ASYNC as well in a set of tests. This exacerbates the problem by
> forcing work to happen in different threads to submission.
>
> Also add tests for not setting IOSQE_IO_LINK, but allow the file offset to
> progress past the end of the file.
A few style and test output comments below.
> diff --git a/test/fpos.c b/test/fpos.c
> new file mode 100644
> index 0000000..2c6c139
> --- /dev/null
> +++ b/test/fpos.c
> @@ -0,0 +1,270 @@
> +/* SPDX-License-Identifier: MIT */
> +/*
> + * Description: test io_uring fpos handling
> + *
> + */
> +#include <errno.h>
> +#include <stdio.h>
> +#include <unistd.h>
> +#include <stdlib.h>
> +#include <string.h>
> +#include <fcntl.h>
> +#include <assert.h>
> +
> +#include "helpers.h"
> +#include "liburing.h"
> +
> +#define FILE_SIZE 10000
> +#define QUEUE_SIZE 4096
Seems huge?
> +static int
> +test_read(struct io_uring *ring, bool async, bool link, int blocksize)
liburing and the kernel tend to use:
static int test_read(struct io_uring *ring, bool async, bool link,
int blocksize)
{
}
if we go over 80 chars, with the reasoning being that a grep will show
you the return type at least.
> +{
> + int ret, fd, i;
> + bool done = false;
> + struct io_uring_sqe *sqe;
> + struct io_uring_cqe *cqe;
> + loff_t current, expected = 0;
> + int count_ok;
> + int count_0 = 0, count_1 = 0;
> + unsigned char buff[QUEUE_SIZE * blocksize];
> + unsigned char reordered[QUEUE_SIZE * blocksize];
> +
> + create_file(".test_read", FILE_SIZE);
> + fd = open(".test_read", O_RDONLY);
> + unlink(".test_read");
> + assert(fd >= 0);
> +
> + while (!done) {
> + for (i = 0; i < QUEUE_SIZE; ++i) {
> + sqe = io_uring_get_sqe(ring);
> + if (!sqe) {
> + fprintf(stderr, "no sqe\n");
> + return -1;
> + }
> + io_uring_prep_read(sqe, fd,
> + buff + i * blocksize,
> + blocksize, -1);
> + sqe->user_data = i;
> + if (async)
> + sqe->flags |= IOSQE_ASYNC;
> + if (link && i != QUEUE_SIZE - 1)
> + sqe->flags |= IOSQE_IO_LINK;
> + }
> + ret = io_uring_submit_and_wait(ring, QUEUE_SIZE);
> + if (ret != QUEUE_SIZE) {
> + fprintf(stderr, "submit failed: %d\n", ret);
> + return 1;
> + }
> + count_ok = 0;
> + for (i = 0; i < QUEUE_SIZE; ++i) {
> + int res;
> +
> + ret = io_uring_peek_cqe(ring, &cqe);
> + if (ret) {
> + fprintf(stderr, "peek failed: %d\n", ret);
> + return ret;
> + }
> + assert(cqe->user_data < QUEUE_SIZE);
> + memcpy(reordered + count_ok
> + , buff + cqe->user_data * blocksize
> + , blocksize);
memcpy(reordered + count_ok,
buff + cqe->user_data * blocksize, blocksize);
> +static int
> +test_write(struct io_uring *ring, bool async, bool link, int blocksize)
> +{
> + int ret, fd, i;
> + struct io_uring_sqe *sqe;
> + struct io_uring_cqe *cqe;
> + bool fail = false;
> + loff_t current;
> + char data[blocksize+1];
> + char readbuff[QUEUE_SIZE*blocksize+1];
> +
> + fd = open(".test_write", O_RDWR | O_CREAT, 0644);
> + unlink(".test_write");
> + assert(fd >= 0);
> +
> + for(i = 0; i < blocksize; i++) {
> + data[i] = 'A' + i;
> + }
> + data[blocksize] = '\0';
> +
> + for (i = 0; i < QUEUE_SIZE; ++i) {
> + sqe = io_uring_get_sqe(ring);
> + if (!sqe) {
> + fprintf(stderr, "no sqe\n");
> + return -1;
> + }
> + io_uring_prep_write(sqe, fd, data + (i % blocksize), 1, -1);
> + sqe->user_data = 1;
> + if (async)
> + sqe->flags |= IOSQE_ASYNC;
> + if (link && i != QUEUE_SIZE - 1)
> + sqe->flags |= IOSQE_IO_LINK;
> + }
> + ret = io_uring_submit_and_wait(ring, QUEUE_SIZE);
> + if (ret != QUEUE_SIZE) {
> + fprintf(stderr, "submit failed: %d\n", ret);
> + return 1;
> + }
> + for (i = 0; i < QUEUE_SIZE; ++i) {
> + int res;
> +
> + ret = io_uring_peek_cqe(ring, &cqe);
> + res = cqe->res;
> + if (ret) {
> + fprintf(stderr, "peek failed: %d\n", ret);
> + return ret;
> + }
> + io_uring_cqe_seen(ring, cqe);
> + if (!fail && res != 1) {
> + fprintf(stderr, "bad result %d\n", res);
> + fail = true;
> + }
> + }
> + current = lseek(fd, 0, SEEK_CUR);
> + if (current != QUEUE_SIZE) {
> + fprintf(stderr,
> + "f_pos incorrect, expected %ld have %d\n",
> + current,
> + QUEUE_SIZE);
> + fail = true;
fprintf(stderr, "f_pos incorrect, expected %ld have %d\n",
current, QUEUE_SIZE);
> +int main(int argc, char *argv[])
> +{
> + struct io_uring ring;
> + int ret;
> + int failed = 0;
> + int blocksizes[] = {1, 8, 15, 0};
> +
> + if (argc > 1)
> + return 0;
> +
> + ret = io_uring_queue_init(QUEUE_SIZE, &ring, 0);
> + if (ret) {
> + fprintf(stderr, "ring setup failed\n");
> + return 1;
> + }
> +
> + for (int *blocksize = blocksizes; *blocksize; blocksize++) {
> + for (int async = 0; async < 2; async++) {
> + for (int link = 0; link < 2; link++) {
> + for (int write = 0; write < 2; write++) {
> + fprintf(stderr, "*********\n");
> + ret = write
> + ? test_write(&ring, !!async, !!link, *blocksize)
> + : test_read(&ring, !!async, !!link, *blocksize);
> + fprintf(stderr, "test %s async=%d link=%d blocksize=%d:\t%s\n",
> + write ? "write":"read",
> + async, link,
> + *blocksize,
> + ret ? "failed" : "passed");
The normal procedure for tests and printing output is:
- Be silent on success, otherwise it's just noise to look over when
doing runs. There are some ancient tests that don't honor this, but
generally the rest of them do.
- If one test fails, stop further tests.
> + }
> + }
> + }
Indentation is wonky here.
--
Jens Axboe
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH v2 liburing] Test consistent file position updates
2022-02-21 16:29 ` Jens Axboe
@ 2022-02-21 17:56 ` Dylan Yudaken
0 siblings, 0 replies; 3+ messages in thread
From: Dylan Yudaken @ 2022-02-21 17:56 UTC (permalink / raw)
To: [email protected], [email protected], [email protected]
Cc: Kernel Team
On Mon, 2022-02-21 at 09:29 -0700, Jens Axboe wrote:
> On 2/21/22 7:18 AM, Dylan Yudaken wrote:
>
> > +
> > +#define FILE_SIZE 10000
> > +#define QUEUE_SIZE 4096
>
> Seems huge?
>
The problems occur a little bit randomly, but certainly the more in
flight at a time the worse it is. I'll reduce it to maybe 1/4? it's not
particularly slow.
> > +static int
> > +test_read(struct io_uring *ring, bool async, bool link, int
> > blocksize)
>
> liburing and the kernel tend to use:
>
> static int test_read(struct io_uring *ring, bool async, bool link,
> int blocksize)
> {
> }
>
> if we go over 80 chars, with the reasoning being that a grep will
> show
> you the return type at least.
makes sense!
>
> > +{
> > + int ret, fd, i;
> > + bool done = false;
> > + struct io_uring_sqe *sqe;
> > + struct io_uring_cqe *cqe;
> > + loff_t current, expected = 0;
> > + int count_ok;
> > + int count_0 = 0, count_1 = 0;
> > + unsigned char buff[QUEUE_SIZE * blocksize];
> > + unsigned char reordered[QUEUE_SIZE * blocksize];
> > +
> > + create_file(".test_read", FILE_SIZE);
> > + fd = open(".test_read", O_RDONLY);
> > + unlink(".test_read");
> > + assert(fd >= 0);
> > +
> > + while (!done) {
> > + for (i = 0; i < QUEUE_SIZE; ++i) {
> > + sqe = io_uring_get_sqe(ring);
> > + if (!sqe) {
> > + fprintf(stderr, "no sqe\n");
> > + return -1;
> > + }
> > + io_uring_prep_read(sqe, fd,
> > + buff + i * blocksize,
> > + blocksize, -1);
> > + sqe->user_data = i;
> > + if (async)
> > + sqe->flags |= IOSQE_ASYNC;
> > + if (link && i != QUEUE_SIZE - 1)
> > + sqe->flags |= IOSQE_IO_LINK;
> > + }
> > + ret = io_uring_submit_and_wait(ring, QUEUE_SIZE);
> > + if (ret != QUEUE_SIZE) {
> > + fprintf(stderr, "submit failed: %d\n",
> > ret);
> > + return 1;
> > + }
> > + count_ok = 0;
> > + for (i = 0; i < QUEUE_SIZE; ++i) {
> > + int res;
> > +
> > + ret = io_uring_peek_cqe(ring, &cqe);
> > + if (ret) {
> > + fprintf(stderr, "peek failed:
> > %d\n", ret);
> > + return ret;
> > + }
> > + assert(cqe->user_data < QUEUE_SIZE);
> > + memcpy(reordered + count_ok
> > + , buff + cqe->user_data * blocksize
> > + , blocksize);
>
> memcpy(reordered + count_ok,
> buff + cqe->user_data * blocksize,
> blocksize);
>
> > +static int
> > +test_write(struct io_uring *ring, bool async, bool link, int
> > blocksize)
> > +{
> > + int ret, fd, i;
> > + struct io_uring_sqe *sqe;
> > + struct io_uring_cqe *cqe;
> > + bool fail = false;
> > + loff_t current;
> > + char data[blocksize+1];
> > + char readbuff[QUEUE_SIZE*blocksize+1];
> > +
> > + fd = open(".test_write", O_RDWR | O_CREAT, 0644);
> > + unlink(".test_write");
> > + assert(fd >= 0);
> > +
> > + for(i = 0; i < blocksize; i++) {
> > + data[i] = 'A' + i;
> > + }
> > + data[blocksize] = '\0';
> > +
> > + for (i = 0; i < QUEUE_SIZE; ++i) {
> > + sqe = io_uring_get_sqe(ring);
> > + if (!sqe) {
> > + fprintf(stderr, "no sqe\n");
> > + return -1;
> > + }
> > + io_uring_prep_write(sqe, fd, data + (i %
> > blocksize), 1, -1);
> > + sqe->user_data = 1;
> > + if (async)
> > + sqe->flags |= IOSQE_ASYNC;
> > + if (link && i != QUEUE_SIZE - 1)
> > + sqe->flags |= IOSQE_IO_LINK;
> > + }
> > + ret = io_uring_submit_and_wait(ring, QUEUE_SIZE);
> > + if (ret != QUEUE_SIZE) {
> > + fprintf(stderr, "submit failed: %d\n", ret);
> > + return 1;
> > + }
> > + for (i = 0; i < QUEUE_SIZE; ++i) {
> > + int res;
> > +
> > + ret = io_uring_peek_cqe(ring, &cqe);
> > + res = cqe->res;
> > + if (ret) {
> > + fprintf(stderr, "peek failed: %d\n", ret);
> > + return ret;
> > + }
> > + io_uring_cqe_seen(ring, cqe);
> > + if (!fail && res != 1) {
> > + fprintf(stderr, "bad result %d\n", res);
> > + fail = true;
> > + }
> > + }
> > + current = lseek(fd, 0, SEEK_CUR);
> > + if (current != QUEUE_SIZE) {
> > + fprintf(stderr,
> > + "f_pos incorrect, expected %ld have %d\n",
> > + current,
> > + QUEUE_SIZE);
> > + fail = true;
>
> fprintf(stderr, "f_pos incorrect, expected %ld have
> %d\n",
> current, QUEUE_SIZE);
>
> > +int main(int argc, char *argv[])
> > +{
> > + struct io_uring ring;
> > + int ret;
> > + int failed = 0;
> > + int blocksizes[] = {1, 8, 15, 0};
> > +
> > + if (argc > 1)
> > + return 0;
> > +
> > + ret = io_uring_queue_init(QUEUE_SIZE, &ring, 0);
> > + if (ret) {
> > + fprintf(stderr, "ring setup failed\n");
> > + return 1;
> > + }
> > +
> > + for (int *blocksize = blocksizes; *blocksize; blocksize++)
> > {
> > + for (int async = 0; async < 2; async++) {
> > + for (int link = 0; link < 2; link++) {
> > + for (int write = 0; write < 2; write++) {
> > + fprintf(stderr, "*********\n");
> > + ret = write
> > + ? test_write(&ring, !!async, !!link,
> > *blocksize)
> > + : test_read(&ring, !!async, !!link,
> > *blocksize);
> > + fprintf(stderr, "test %s async=%d link=%d
> > blocksize=%d:\t%s\n",
> > + write ? "write":"read",
> > + async, link,
> > + *blocksize,
> > + ret ? "failed" : "passed");
>
> The normal procedure for tests and printing output is:
>
> - Be silent on success, otherwise it's just noise to look over when
> doing runs. There are some ancient tests that don't honor this, but
> generally the rest of them do.
Ok!
>
> - If one test fails, stop further tests.
>
> > + }
> > + }
> > + }
>
> Indentation is wonky here.
>
Yes - on this one I wasn't sure the best approach, as it's 4 nested for
loops in order to generate a large set of test cases. I did not feel
like indenting them was valuable. That being said it's probably worth
it just for the consistency - so I will do that.
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2022-02-21 18:06 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2022-02-21 14:18 [PATCH v2 liburing] Test consistent file position updates Dylan Yudaken
2022-02-21 16:29 ` Jens Axboe
2022-02-21 17:56 ` Dylan Yudaken
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox