Message ID | 8dd7d15176ca1e947054dd6891e478cdf7902f7e.1601639563.git.qemu_oss@crudebyte.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | 9pfs: add tests using local fs driver | expand |
On Freitag, 2. Oktober 2020 13:51:54 CEST Christian Schoenebeck wrote: > This patch introduces 9pfs test cases using the 9pfs 'local' > filesystem driver which reads/writes/creates/deletes real files > and directories. > > In this initial version, there is only one local test which actually > only checks if the 9pfs 'local' device was created successfully. > > Before the 9pfs 'local' tests are run, a test directory 'qtest-9p-local' > is created (with world rwx permissions) under the current working > directory. At this point that test directory is not auto deleted yet. > > Signed-off-by: Christian Schoenebeck <qemu_oss@crudebyte.com> > --- > tests/qtest/libqos/virtio-9p.c | 100 +++++++++++++++++++++++++++++++++ > tests/qtest/libqos/virtio-9p.h | 5 ++ > tests/qtest/virtio-9p-test.c | 44 ++++++++++----- > 3 files changed, 135 insertions(+), 14 deletions(-) > > diff --git a/tests/qtest/libqos/virtio-9p.c b/tests/qtest/libqos/virtio-9p.c > index 2e300063e3..86e40e5d56 100644 > --- a/tests/qtest/libqos/virtio-9p.c > +++ b/tests/qtest/libqos/virtio-9p.c > @@ -24,6 +24,63 @@ > #include "qgraph.h" > > static QGuestAllocator *alloc; > +static char *local_test_path; > + > +static char *strpr(const char* format, ...) GCC_FMT_ATTR(1, 2); > + > +/* Concatenates the passed 2 pathes. Returned result must be freed. */ > +static char *concat_path(const char* a, const char* b) > +{ > + const int len = strlen(a) + strlen("/") + strlen(b); > + char *path = g_malloc0(len + 1); > + snprintf(path, len + 1, "%s/%s", a, b); > + g_assert(strlen(path) == len); > + return path; > +} Ok, but maybe I could make that concat_path() function wrap g_strconcat(). > + > +/* > + * Lazy sprintf() implementation which auto allocates buffer. Returned > result + * must be freed. > + */ > +static char *strpr(const char* format, ...) > +{ > + va_list argp; > + > + va_start(argp, format); > + const int sz = vsnprintf(NULL, 0, format, argp) + 1; > + va_end(argp); > + > + g_assert(sz > 0); > + char *s = g_malloc0(sz); > + > + va_start(argp, format); > + const int len = vsnprintf(s, sz, format, argp); > + va_end(argp); > + > + g_assert(len + 1 == sz); > + return s; > +} And this strpr() function entirely be replaced by g_strdup_printf(). > + > +static void init_local_test_path(void) > +{ > + char *pwd = get_current_dir_name(); > + local_test_path = concat_path(pwd, "qtest-9p-local"); > + free(pwd); > +} > + > +/* Creates the directory for the 9pfs 'local' filesystem driver to access. > */ +static void create_local_test_dir(void) > +{ > + struct stat st; > + > + g_assert(local_test_path != NULL); > + mkdir(local_test_path, 0777); > + > + /* ensure test directory exists now ... */ > + g_assert(stat(local_test_path, &st) == 0); > + /* ... and is actually a directory */ > + g_assert((st.st_mode & S_IFMT) == S_IFDIR); > +} > > static void virtio_9p_cleanup(QVirtio9P *interface) > { > @@ -146,11 +203,54 @@ static void *virtio_9p_pci_create(void *pci_bus, > QGuestAllocator *t_alloc, return obj; > } > > +void virtio_9p_assign_local_driver(GString *cmd_line, const char *args) > +{ > + GRegex *regex; > + char *s, *arg_repl; > + > + g_assert_nonnull(local_test_path); > + > + /* replace 'synth' driver by 'local' driver */ > + regex = g_regex_new("-fsdev synth,", 0, 0, NULL); > + s = g_regex_replace_literal( > + regex, cmd_line->str, -1, 0, "-fsdev local,", 0, NULL > + ); > + g_string_assign(cmd_line, s); > + g_free(s); > + g_regex_unref(regex); > + > + /* add 'path=...' to '-fsdev ...' group */ > + regex = g_regex_new("(-fsdev \\w+)(\\s*)", 0, 0, NULL); > + arg_repl = strpr("\\1\\2,path='%s'", local_test_path); > + s = g_regex_replace( > + regex, cmd_line->str, -1, 0, arg_repl, 0, NULL > + ); > + g_string_assign(cmd_line, s); > + g_free(arg_repl); > + g_free(s); > + g_regex_unref(regex); > + > + /* add passed args to '-fsdev ...' group */ > + regex = g_regex_new("(-fsdev \\w+)(\\s*)", 0, 0, NULL); > + arg_repl = strpr("\\1\\2,%s", args); > + s = g_regex_replace( > + regex, cmd_line->str, -1, 0, arg_repl, 0, NULL > + ); > + g_string_assign(cmd_line, s); > + g_free(arg_repl); > + g_free(s); > + g_regex_unref(regex); > +} > + > static void virtio_9p_register_nodes(void) > { > const char *str_simple = "fsdev=fsdev0,mount_tag=" MOUNT_TAG; > const char *str_addr = "fsdev=fsdev0,addr=04.0,mount_tag=" MOUNT_TAG; > > + /* make sure test dir for the 'local' tests exists and is clean */ > + init_local_test_path(); > + create_local_test_dir(); > + > QPCIAddress addr = { > .devfn = QPCI_DEVFN(4, 0), > }; > diff --git a/tests/qtest/libqos/virtio-9p.h b/tests/qtest/libqos/virtio-9p.h > index b1e6badc4a..326a603f72 100644 > --- a/tests/qtest/libqos/virtio-9p.h > +++ b/tests/qtest/libqos/virtio-9p.h > @@ -44,4 +44,9 @@ struct QVirtio9PDevice { > QVirtio9P v9p; > }; > > +/** > + * Prepares QEMU command line for 9pfs tests using the 'local' fs driver. > + */ > +void virtio_9p_assign_local_driver(GString *cmd_line, const char *args); > + > #endif > diff --git a/tests/qtest/virtio-9p-test.c b/tests/qtest/virtio-9p-test.c > index 3281153b9c..af7e169d3a 100644 > --- a/tests/qtest/virtio-9p-test.c > +++ b/tests/qtest/virtio-9p-test.c > @@ -895,29 +895,45 @@ static void fs_readdir_split_512(void *obj, void > *data, fs_readdir_split(obj, data, t_alloc, 512); > } > > +static void *assign_9p_local_driver(GString *cmd_line, void *arg) > +{ > + virtio_9p_assign_local_driver(cmd_line, "security_model=mapped-xattr"); > + return arg; > +} > + > static void register_virtio_9p_test(void) > { > - qos_add_test("synth/config", "virtio-9p", pci_config, NULL); > - qos_add_test("synth/version/basic", "virtio-9p", fs_version, NULL); > - qos_add_test("synth/attach/basic", "virtio-9p", fs_attach, NULL); > - qos_add_test("synth/walk/basic", "virtio-9p", fs_walk, NULL); > + > + QOSGraphTestOptions opts = { > + }; > + > + /* 9pfs test cases using the 'synth' filesystem driver */ > + qos_add_test("synth/config", "virtio-9p", pci_config, &opts); > + qos_add_test("synth/version/basic", "virtio-9p", fs_version, &opts); > + qos_add_test("synth/attach/basic", "virtio-9p", fs_attach, &opts); > + qos_add_test("synth/walk/basic", "virtio-9p", fs_walk, &opts); > qos_add_test("synth/walk/no_slash", "virtio-9p", fs_walk_no_slash, > - NULL); > + &opts); > qos_add_test("synth/walk/dotdot_from_root", "virtio-9p", > - fs_walk_dotdot, NULL); > - qos_add_test("synth/lopen/basic", "virtio-9p", fs_lopen, NULL); > - qos_add_test("synth/write/basic", "virtio-9p", fs_write, NULL); > + fs_walk_dotdot, &opts); > + qos_add_test("synth/lopen/basic", "virtio-9p", fs_lopen, &opts); > + qos_add_test("synth/write/basic", "virtio-9p", fs_write, &opts); > qos_add_test("synth/flush/success", "virtio-9p", fs_flush_success, > - NULL); > + &opts); > qos_add_test("synth/flush/ignored", "virtio-9p", fs_flush_ignored, > - NULL); > - qos_add_test("synth/readdir/basic", "virtio-9p", fs_readdir, NULL); > + &opts); > + qos_add_test("synth/readdir/basic", "virtio-9p", fs_readdir, &opts); > qos_add_test("synth/readdir/split_512", "virtio-9p", > - fs_readdir_split_512, NULL); > + fs_readdir_split_512, &opts); > qos_add_test("synth/readdir/split_256", "virtio-9p", > - fs_readdir_split_256, NULL); > + fs_readdir_split_256, &opts); > qos_add_test("synth/readdir/split_128", "virtio-9p", > - fs_readdir_split_128, NULL); > + fs_readdir_split_128, &opts); > + > + > + /* 9pfs test cases using the 'local' filesystem driver */ > + opts.before = assign_9p_local_driver; > + qos_add_test("local/config", "virtio-9p", pci_config, &opts); > } > > libqos_init(register_virtio_9p_test); Best regards, Christian Schoenebeck
On Fri, Oct 02, 2020 at 04:26:48PM +0200, Christian Schoenebeck wrote: > On Freitag, 2. Oktober 2020 13:51:54 CEST Christian Schoenebeck wrote: > > This patch introduces 9pfs test cases using the 9pfs 'local' > > filesystem driver which reads/writes/creates/deletes real files > > and directories. > > > > In this initial version, there is only one local test which actually > > only checks if the 9pfs 'local' device was created successfully. > > > > Before the 9pfs 'local' tests are run, a test directory 'qtest-9p-local' > > is created (with world rwx permissions) under the current working > > directory. At this point that test directory is not auto deleted yet. > > > > Signed-off-by: Christian Schoenebeck <qemu_oss@crudebyte.com> > > --- > > tests/qtest/libqos/virtio-9p.c | 100 +++++++++++++++++++++++++++++++++ > > tests/qtest/libqos/virtio-9p.h | 5 ++ > > tests/qtest/virtio-9p-test.c | 44 ++++++++++----- > > 3 files changed, 135 insertions(+), 14 deletions(-) > > > > diff --git a/tests/qtest/libqos/virtio-9p.c b/tests/qtest/libqos/virtio-9p.c > > index 2e300063e3..86e40e5d56 100644 > > --- a/tests/qtest/libqos/virtio-9p.c > > +++ b/tests/qtest/libqos/virtio-9p.c > > @@ -24,6 +24,63 @@ > > #include "qgraph.h" > > > > static QGuestAllocator *alloc; > > +static char *local_test_path; > > + > > +static char *strpr(const char* format, ...) GCC_FMT_ATTR(1, 2); > > + > > +/* Concatenates the passed 2 pathes. Returned result must be freed. */ > > +static char *concat_path(const char* a, const char* b) > > +{ > > + const int len = strlen(a) + strlen("/") + strlen(b); > > + char *path = g_malloc0(len + 1); > > + snprintf(path, len + 1, "%s/%s", a, b); > > + g_assert(strlen(path) == len); > > + return path; > > +} > > Ok, but maybe I could make that concat_path() function wrap g_strconcat(). Or even one of g_build_path or g_build_filename may be useful > > +/* > > + * Lazy sprintf() implementation which auto allocates buffer. Returned > > result + * must be freed. > > + */ > > +static char *strpr(const char* format, ...) > > +{ > > + va_list argp; > > + > > + va_start(argp, format); > > + const int sz = vsnprintf(NULL, 0, format, argp) + 1; > > + va_end(argp); > > + > > + g_assert(sz > 0); > > + char *s = g_malloc0(sz); > > + > > + va_start(argp, format); > > + const int len = vsnprintf(s, sz, format, argp); > > + va_end(argp); > > + > > + g_assert(len + 1 == sz); > > + return s; > > +} > > And this strpr() function entirely be replaced by g_strdup_printf(). Yep, its preferrable to use g_strdup_printf instead of manually allocating. Regards, Daniel
diff --git a/tests/qtest/libqos/virtio-9p.c b/tests/qtest/libqos/virtio-9p.c index 2e300063e3..86e40e5d56 100644 --- a/tests/qtest/libqos/virtio-9p.c +++ b/tests/qtest/libqos/virtio-9p.c @@ -24,6 +24,63 @@ #include "qgraph.h" static QGuestAllocator *alloc; +static char *local_test_path; + +static char *strpr(const char* format, ...) GCC_FMT_ATTR(1, 2); + +/* Concatenates the passed 2 pathes. Returned result must be freed. */ +static char *concat_path(const char* a, const char* b) +{ + const int len = strlen(a) + strlen("/") + strlen(b); + char *path = g_malloc0(len + 1); + snprintf(path, len + 1, "%s/%s", a, b); + g_assert(strlen(path) == len); + return path; +} + +/* + * Lazy sprintf() implementation which auto allocates buffer. Returned result + * must be freed. + */ +static char *strpr(const char* format, ...) +{ + va_list argp; + + va_start(argp, format); + const int sz = vsnprintf(NULL, 0, format, argp) + 1; + va_end(argp); + + g_assert(sz > 0); + char *s = g_malloc0(sz); + + va_start(argp, format); + const int len = vsnprintf(s, sz, format, argp); + va_end(argp); + + g_assert(len + 1 == sz); + return s; +} + +static void init_local_test_path(void) +{ + char *pwd = get_current_dir_name(); + local_test_path = concat_path(pwd, "qtest-9p-local"); + free(pwd); +} + +/* Creates the directory for the 9pfs 'local' filesystem driver to access. */ +static void create_local_test_dir(void) +{ + struct stat st; + + g_assert(local_test_path != NULL); + mkdir(local_test_path, 0777); + + /* ensure test directory exists now ... */ + g_assert(stat(local_test_path, &st) == 0); + /* ... and is actually a directory */ + g_assert((st.st_mode & S_IFMT) == S_IFDIR); +} static void virtio_9p_cleanup(QVirtio9P *interface) { @@ -146,11 +203,54 @@ static void *virtio_9p_pci_create(void *pci_bus, QGuestAllocator *t_alloc, return obj; } +void virtio_9p_assign_local_driver(GString *cmd_line, const char *args) +{ + GRegex *regex; + char *s, *arg_repl; + + g_assert_nonnull(local_test_path); + + /* replace 'synth' driver by 'local' driver */ + regex = g_regex_new("-fsdev synth,", 0, 0, NULL); + s = g_regex_replace_literal( + regex, cmd_line->str, -1, 0, "-fsdev local,", 0, NULL + ); + g_string_assign(cmd_line, s); + g_free(s); + g_regex_unref(regex); + + /* add 'path=...' to '-fsdev ...' group */ + regex = g_regex_new("(-fsdev \\w+)(\\s*)", 0, 0, NULL); + arg_repl = strpr("\\1\\2,path='%s'", local_test_path); + s = g_regex_replace( + regex, cmd_line->str, -1, 0, arg_repl, 0, NULL + ); + g_string_assign(cmd_line, s); + g_free(arg_repl); + g_free(s); + g_regex_unref(regex); + + /* add passed args to '-fsdev ...' group */ + regex = g_regex_new("(-fsdev \\w+)(\\s*)", 0, 0, NULL); + arg_repl = strpr("\\1\\2,%s", args); + s = g_regex_replace( + regex, cmd_line->str, -1, 0, arg_repl, 0, NULL + ); + g_string_assign(cmd_line, s); + g_free(arg_repl); + g_free(s); + g_regex_unref(regex); +} + static void virtio_9p_register_nodes(void) { const char *str_simple = "fsdev=fsdev0,mount_tag=" MOUNT_TAG; const char *str_addr = "fsdev=fsdev0,addr=04.0,mount_tag=" MOUNT_TAG; + /* make sure test dir for the 'local' tests exists and is clean */ + init_local_test_path(); + create_local_test_dir(); + QPCIAddress addr = { .devfn = QPCI_DEVFN(4, 0), }; diff --git a/tests/qtest/libqos/virtio-9p.h b/tests/qtest/libqos/virtio-9p.h index b1e6badc4a..326a603f72 100644 --- a/tests/qtest/libqos/virtio-9p.h +++ b/tests/qtest/libqos/virtio-9p.h @@ -44,4 +44,9 @@ struct QVirtio9PDevice { QVirtio9P v9p; }; +/** + * Prepares QEMU command line for 9pfs tests using the 'local' fs driver. + */ +void virtio_9p_assign_local_driver(GString *cmd_line, const char *args); + #endif diff --git a/tests/qtest/virtio-9p-test.c b/tests/qtest/virtio-9p-test.c index 3281153b9c..af7e169d3a 100644 --- a/tests/qtest/virtio-9p-test.c +++ b/tests/qtest/virtio-9p-test.c @@ -895,29 +895,45 @@ static void fs_readdir_split_512(void *obj, void *data, fs_readdir_split(obj, data, t_alloc, 512); } +static void *assign_9p_local_driver(GString *cmd_line, void *arg) +{ + virtio_9p_assign_local_driver(cmd_line, "security_model=mapped-xattr"); + return arg; +} + static void register_virtio_9p_test(void) { - qos_add_test("synth/config", "virtio-9p", pci_config, NULL); - qos_add_test("synth/version/basic", "virtio-9p", fs_version, NULL); - qos_add_test("synth/attach/basic", "virtio-9p", fs_attach, NULL); - qos_add_test("synth/walk/basic", "virtio-9p", fs_walk, NULL); + + QOSGraphTestOptions opts = { + }; + + /* 9pfs test cases using the 'synth' filesystem driver */ + qos_add_test("synth/config", "virtio-9p", pci_config, &opts); + qos_add_test("synth/version/basic", "virtio-9p", fs_version, &opts); + qos_add_test("synth/attach/basic", "virtio-9p", fs_attach, &opts); + qos_add_test("synth/walk/basic", "virtio-9p", fs_walk, &opts); qos_add_test("synth/walk/no_slash", "virtio-9p", fs_walk_no_slash, - NULL); + &opts); qos_add_test("synth/walk/dotdot_from_root", "virtio-9p", - fs_walk_dotdot, NULL); - qos_add_test("synth/lopen/basic", "virtio-9p", fs_lopen, NULL); - qos_add_test("synth/write/basic", "virtio-9p", fs_write, NULL); + fs_walk_dotdot, &opts); + qos_add_test("synth/lopen/basic", "virtio-9p", fs_lopen, &opts); + qos_add_test("synth/write/basic", "virtio-9p", fs_write, &opts); qos_add_test("synth/flush/success", "virtio-9p", fs_flush_success, - NULL); + &opts); qos_add_test("synth/flush/ignored", "virtio-9p", fs_flush_ignored, - NULL); - qos_add_test("synth/readdir/basic", "virtio-9p", fs_readdir, NULL); + &opts); + qos_add_test("synth/readdir/basic", "virtio-9p", fs_readdir, &opts); qos_add_test("synth/readdir/split_512", "virtio-9p", - fs_readdir_split_512, NULL); + fs_readdir_split_512, &opts); qos_add_test("synth/readdir/split_256", "virtio-9p", - fs_readdir_split_256, NULL); + fs_readdir_split_256, &opts); qos_add_test("synth/readdir/split_128", "virtio-9p", - fs_readdir_split_128, NULL); + fs_readdir_split_128, &opts); + + + /* 9pfs test cases using the 'local' filesystem driver */ + opts.before = assign_9p_local_driver; + qos_add_test("local/config", "virtio-9p", pci_config, &opts); } libqos_init(register_virtio_9p_test);
This patch introduces 9pfs test cases using the 9pfs 'local' filesystem driver which reads/writes/creates/deletes real files and directories. In this initial version, there is only one local test which actually only checks if the 9pfs 'local' device was created successfully. Before the 9pfs 'local' tests are run, a test directory 'qtest-9p-local' is created (with world rwx permissions) under the current working directory. At this point that test directory is not auto deleted yet. Signed-off-by: Christian Schoenebeck <qemu_oss@crudebyte.com> --- tests/qtest/libqos/virtio-9p.c | 100 +++++++++++++++++++++++++++++++++ tests/qtest/libqos/virtio-9p.h | 5 ++ tests/qtest/virtio-9p-test.c | 44 ++++++++++----- 3 files changed, 135 insertions(+), 14 deletions(-)