diff options
author | Martin Pärtel <martin.partel@gmail.com> | 2021-02-13 15:56:57 +0200 |
---|---|---|
committer | Martin Pärtel <martin.partel@gmail.com> | 2021-02-13 15:56:57 +0200 |
commit | bc5313dc583cad9a3949bd798995ab1ee398ecf6 (patch) | |
tree | 3eef96d1b7cbb7a4e05a3ea954b1bc75231c1fd8 /tests | |
parent | 2cf41a75c11472bd6737b48c61f0a3d30cd6f242 (diff) | |
download | bindfs-bc5313dc583cad9a3949bd798995ab1ee398ecf6.tar.gz |
Refactored and unit-tested filter_special_opts. Shaved a bunch of yaks on the way.
Diffstat (limited to 'tests')
-rw-r--r-- | tests/internals/Makefile.am | 2 | ||||
-rw-r--r-- | tests/internals/test_internals.c | 183 | ||||
-rwxr-xr-x | tests/test_bindfs.rb | 6 | ||||
-rw-r--r-- | tests/utimens_nofollow.c | 5 |
4 files changed, 184 insertions, 12 deletions
diff --git a/tests/internals/Makefile.am b/tests/internals/Makefile.am index 3e59f02..f0b86e6 100644 --- a/tests/internals/Makefile.am +++ b/tests/internals/Makefile.am @@ -1,7 +1,7 @@ noinst_HEADERS = test_common.h noinst_PROGRAMS = test_internals test_rate_limiter -test_internals_SOURCES = test_internals.c test_common.c $(top_srcdir)/src/misc.c +test_internals_SOURCES = test_internals.c test_common.c $(top_srcdir)/src/misc.c $(top_srcdir)/src/arena.c test_rate_limiter_SOURCES = test_rate_limiter.c test_common.c $(top_srcdir)/src/rate_limiter.c test_internals_CPPFLAGS = ${my_CPPFLAGS} ${fuse_CFLAGS} ${fuse3_CFLAGS} -I. -I$(top_srcdir)/src diff --git a/tests/internals/test_internals.c b/tests/internals/test_internals.c index f5dbed5..a16b392 100644 --- a/tests/internals/test_internals.c +++ b/tests/internals/test_internals.c @@ -1,10 +1,40 @@ +#define _XOPEN_SOURCE 700 + #include "test_common.h" #include "misc.h" #include <string.h> #include <stdlib.h> -void test_my_dirname(char *arg, const char *expected) +static void arena_suite() +{ + const int iterations = 1000; + struct arena arena; + int** pointers = calloc(iterations, sizeof(int*)); + + arena_init(&arena); + for (int i = 0; i < iterations; ++i) { + int count = 17 * i; + int* p = arena_malloc(&arena, count * sizeof(int)); + pointers[i] = p; + for (int j = 0; j < count; ++j) { + p[j] = j; + } + } + + for (int i = 0; i < iterations; ++i) { + int count = 17 * i; + int* p = pointers[i]; + for (int j = 0; j < count; ++j) { + TEST_ASSERT(p[j] == j); + } + } + + arena_free(&arena); + free(pointers); +} + +static void test_my_dirname(char *arg, const char *expected) { char *orig = strdup(arg); @@ -17,7 +47,7 @@ void test_my_dirname(char *arg, const char *expected) free(orig); } -void my_dirname_suite() +static void my_dirname_suite() { char buf[256]; @@ -52,7 +82,7 @@ void my_dirname_suite() test_my_dirname(buf, ".."); } -void sprintf_new_suite() { +static void sprintf_new_suite() { char *result; result = sprintf_new("Hello %d %s", 123, "World"); @@ -64,9 +94,154 @@ void sprintf_new_suite() { free(result); } -void test_internal_suite() { +static int arg_count(const char **argv) +{ + int i = 0; + while (argv[i] != NULL) { + ++i; + } + return i; +} + +static bool keep_opt(const char *opt) { + return *opt != '\0' && strncmp(opt, "bad", 3) != 0; +} + +static char *join_args(int argc, const char** argv) { + struct memory_block block = MEMORY_BLOCK_INITIALIZER; + for (int i = 0; i < argc; ++i) { + int len = strlen(argv[i]); + append_to_memory_block(&block, argv[i], len); + if (i + 1 < argc) { + append_to_memory_block(&block, " ", 1); + } else { + append_to_memory_block(&block, "\0", 1); + } + } + return block.ptr; +} + +static void filter_o_opts_test(const char **init, const char **expected) { + int argc = arg_count(init); + char *joined_input = join_args(argc, init); + + struct arena arena; + arena_init(&arena); + char **argv; + filter_o_opts(keep_opt, argc, init, &argc, &argv, &arena); + + for (int i = 0; i < argc; ++i) { + if (argv[i] == NULL) { + printf("Expected %s but got end of argv at index %d with input %s\n", expected[i], i, joined_input); + failures++; + break; + } + if (expected[i] == NULL) { + printf("Expected end of args but got %s at index %d with input %s\n", argv[i], i, joined_input); + failures++; + break; + } + if (strcmp(argv[i], expected[i]) != 0) { + printf("Expected %s but got %s at index %d with input %s\n", expected[i], argv[i], i, joined_input); + failures++; + break; + } + } + + arena_free(&arena); + free(joined_input); +} + +static void filter_o_opts_suite() { + { + const char *in[] = {"-obad1", NULL}; + const char *exp[] = {NULL}; + filter_o_opts_test(in, exp); + } + + { + const char *in[] = {"-ogood1", NULL}; + const char *exp[] = {"-ogood1", NULL}; + filter_o_opts_test(in, exp); + } + { + const char *in[] = {"-obad1,good1", NULL}; + const char *exp[] = {"-ogood1", NULL}; + filter_o_opts_test(in, exp); + } + + { + const char *in[] = {"-ogood1,bad", NULL}; + const char *exp[] = {"-ogood1", NULL}; + filter_o_opts_test(in, exp); + } + + { + const char *in[] = {"-obad1,good1,bad2", NULL}; + const char *exp[] = {"-ogood1", NULL}; + filter_o_opts_test(in, exp); + } + + { + const char *in[] = {"-obad1,good1,bad2,good2", NULL}; + const char *exp[] = {"-ogood1,good2", NULL}; + filter_o_opts_test(in, exp); + } + + { + const char *in[] = {"-ogood1,bad1,good2", NULL}; + const char *exp[] = {"-ogood1,good2", NULL}; + filter_o_opts_test(in, exp); + } + + { + const char *in[] = {"-o", "bad1", NULL}; + const char *exp[] = {NULL}; + filter_o_opts_test(in, exp); + } + + { + const char *in[] = {"-o", "good1", NULL}; + const char *exp[] = {"-ogood1", NULL}; + filter_o_opts_test(in, exp); + } + + { + const char *in[] = {"-o", "good1,bad1,good2", NULL}; + const char *exp[] = {"-ogood1,good2", NULL}; + filter_o_opts_test(in, exp); + } + + { + const char *in[] = {"-o", "bad1,good1,bad2", NULL}; + const char *exp[] = {"-ogood1", NULL}; + filter_o_opts_test(in, exp); + } + + { + const char *in[] = {"unrelated1", "-o", "bad1,good1,bad2", "unrelated2", NULL}; + const char *exp[] = {"unrelated1", "-ogood1", "unrelated2", NULL}; + filter_o_opts_test(in, exp); + } + + { + const char *in[] = {"unrelated1", "-o", ",,,bad1,,good1,,bad2,,,", "unrelated2", NULL}; + const char *exp[] = {"unrelated1", "-ogood1", "unrelated2", NULL}; + filter_o_opts_test(in, exp); + } + + { + const char *in[] = {"-o", NULL}; + const char *exp[] = {NULL}; + filter_o_opts_test(in, exp); + } +} + +static void test_internal_suite() { + arena_suite(); my_dirname_suite(); sprintf_new_suite(); + filter_o_opts_suite(); } TEST_MAIN(test_internal_suite); diff --git a/tests/test_bindfs.rb b/tests/test_bindfs.rb index 49f2332..29210b7 100755 --- a/tests/test_bindfs.rb +++ b/tests/test_bindfs.rb @@ -296,7 +296,9 @@ testenv("--chmod-deny --chmod-allow-x") do assert_exception(EPERM) { chmod(0777, 'mnt/file') } assert_exception(EPERM) { chmod(0000, 'mnt/file') } - assert_exception(EPERM) { chmod(01700, 'mnt/file') } # sticky bit + if `uname`.strip != 'FreeBSD' # FreeBSD doesn't let us set the sticky bit on files + assert_exception(EPERM) { chmod(01700, 'mnt/file') } # sticky bit + end chmod(0611, 'mnt/file') # chmod that only changes x-bits should work assert { File.stat('src/file').mode & 07777 == 00611 } @@ -895,7 +897,7 @@ if `uname`.strip != 'FreeBSD' # -o dev is not supported on FreeBSD end # PR #95 -testenv("-ouser -onofail,nouser,delete-deny -o users -o auto,rename-deny,noauto -o chmod-deny,_netdev", :title => "filtering special options") do +testenv("-ouser -onofail,nouser,,,delete-deny -o users -o auto,rename-deny,noauto -o chmod-deny,_netdev,,", :title => "filtering special options") do touch('src/file') assert_exception(EPERM) { rm('mnt/file') } assert_exception(EPERM) { File.rename('mnt/file', 'mnt/file2') } diff --git a/tests/utimens_nofollow.c b/tests/utimens_nofollow.c index 1941c56..668cec4 100644 --- a/tests/utimens_nofollow.c +++ b/tests/utimens_nofollow.c @@ -1,9 +1,4 @@ -/* For atoll and lutimes */ -#define _BSD_SOURCE -/* The new non-deprecated version of _BSD_SOURCE */ -#define _DEFAULT_SOURCE - #include <config.h> #include <stdlib.h> #include <stdio.h> |