diff options
Diffstat (limited to 'src/lib-dict-extra/test-dict-fs.c')
-rw-r--r-- | src/lib-dict-extra/test-dict-fs.c | 106 |
1 files changed, 106 insertions, 0 deletions
diff --git a/src/lib-dict-extra/test-dict-fs.c b/src/lib-dict-extra/test-dict-fs.c new file mode 100644 index 0000000..a7b9905 --- /dev/null +++ b/src/lib-dict-extra/test-dict-fs.c @@ -0,0 +1,106 @@ +#include <errno.h> +#include <sys/stat.h> +#include "lib.h" +#include "unlink-directory.h" +#include "test-common.h" +#include "dict-private.h" + +static void test_dict_set_get(struct dict *dict, const char *key, + const char *value) +{ + const char *got_value, *error; + struct dict_op_settings set = { + .username = "testuser", + }; + struct dict_transaction_context *t = dict_transaction_begin(dict, &set); + dict_set(t, key, value); + if (dict_transaction_commit(&t, &error) < 0) + i_fatal("dict_transaction_commit(%s) failed: %s", key, error); + if (dict_lookup(dict, &set, pool_datastack_create(), key, &got_value, + &error) < 0) + i_fatal("dict_lookup(%s) failed: %s", key, error); + test_assert_strcmp(got_value, value); +} + +static bool test_file_exists(const char *path) +{ + struct stat st; + if (stat(path, &st) < 0) { + if (ENOTFOUND(errno)) return FALSE; + i_fatal("stat(%s) failed: %m", path); + } + return TRUE; +} + +static void test_dict_fs_set_get(void) +{ + test_begin("dict-fs get/set"); + const char *error; + struct dict *dict; + struct dict_settings set = { + .base_dir = ".", + }; + if (dict_init("fs:posix:prefix=.test-dict/", &set, &dict, &error) < 0) + i_fatal("dict_init() failed: %s", error); + + /* shared paths */ + struct { + const char *key; + const char *path; + } test_cases[] = { + { "shared/./key", ".test-dict/.../key" }, + { "shared/../key", ".test-dict/..../key" }, + { "shared/.../key", ".test-dict/...../key" }, + { "shared/..../key", ".test-dict/....../key" }, + { "shared/...../key", ".test-dict/......./key" }, + { "shared/key/.", ".test-dict/key/..." }, + { "shared/key/..", ".test-dict/key/...." }, + { "shared/key/...", ".test-dict/key/....." }, + { "shared/key/....", ".test-dict/key/......" }, + { "shared/key/.....", ".test-dict/key/......." }, + { "shared/key/.key", ".test-dict/key/.key" }, + { "shared/key/..key", ".test-dict/key/..key" }, + { "shared/key/...key", ".test-dict/key/...key" }, + { "shared/.key/key", ".test-dict/.key/key" }, + { "shared/..key/key", ".test-dict/..key/key" }, + { "shared/...key/key", ".test-dict/...key/key" }, + }; + for (size_t i = 0; i < N_ELEMENTS(test_cases); i++) { + test_dict_set_get(dict, test_cases[i].key, "1"); + test_assert(test_file_exists(test_cases[i].path)); + } + + /* per user paths */ + test_dict_set_get(dict, "priv/value", "priv1"); + test_assert(test_file_exists(".test-dict/testuser/value")); + test_dict_set_get(dict, "priv/path/with/value", "priv2"); + test_assert(test_file_exists(".test-dict/testuser/path/with/value")); + + /* check that dots work correctly */ + test_dict_set_get(dict, "shared/../test-dict-fs.c", "3"); + test_assert(test_file_exists(".test-dict/..../test-dict-fs.c")); + test_dict_set_get(dict, "shared/./test", "4"); + test_assert(test_file_exists(".test-dict/.../test")); + test_dict_set_get(dict, "shared/.test", "5"); + test_assert(test_file_exists(".test-dict/.test")); + test_dict_set_get(dict, "shared/..test", "6"); + test_assert(test_file_exists(".test-dict/..test")); + dict_deinit(&dict); + + if (unlink_directory(".test-dict", UNLINK_DIRECTORY_FLAG_RMDIR, &error) < 0) + i_fatal("unlink_directory(.test_dict) failed: %s", error); + test_end(); +} + +int main(void) +{ + static void (*const test_functions[])(void) = { + test_dict_fs_set_get, + NULL + }; + int ret; + dict_driver_register(&dict_driver_fs); + ret = test_run(test_functions); + dict_driver_unregister(&dict_driver_fs); + return ret; +} |