diff options
Diffstat (limited to 'src/config/test-config-parser.c')
-rw-r--r-- | src/config/test-config-parser.c | 170 |
1 files changed, 170 insertions, 0 deletions
diff --git a/src/config/test-config-parser.c b/src/config/test-config-parser.c new file mode 100644 index 0000000..baf91a1 --- /dev/null +++ b/src/config/test-config-parser.c @@ -0,0 +1,170 @@ +/* Copyright (c) 2021 Dovecot authors, see the included COPYING file */ + +#include "lib.h" +#include "ostream.h" +#include "service-settings.h" +#include "settings-parser.h" +#include "config-filter.h" +#include "test-common.h" +#include "all-settings.h" +#include "config-parser.h" + +#define TEST_CONFIG_FILE ".test-config" + +static ARRAY_TYPE(service_settings) services = ARRAY_INIT; +ARRAY_TYPE(service_settings) *default_services = &services; + +struct test_settings { + const char *key; + const char *key2; + const char *key3; + const char *key4; + const char *key5; + const char *pop3_deleted_flag; + const char *env_key; + const char *env_key2; + const char *env_key3; + const char *env_key4; + const char *env_key5; + const char *protocols; +}; + +static const struct setting_define test_settings_defs[] = { + SETTING_DEFINE_STRUCT_STR("key", key, struct test_settings), + SETTING_DEFINE_STRUCT_STR("key2", key2, struct test_settings), + SETTING_DEFINE_STRUCT_STR("key3", key3, struct test_settings), + SETTING_DEFINE_STRUCT_STR("key4", key4, struct test_settings), + SETTING_DEFINE_STRUCT_STR("key5", key5, struct test_settings), + SETTING_DEFINE_STRUCT_STR("pop3_deleted_flag", pop3_deleted_flag, struct test_settings), + SETTING_DEFINE_STRUCT_STR("env_key", env_key, struct test_settings), + SETTING_DEFINE_STRUCT_STR("env_key2", env_key2, struct test_settings), + SETTING_DEFINE_STRUCT_STR("env_key3", env_key3, struct test_settings), + SETTING_DEFINE_STRUCT_STR("env_key4", env_key4, struct test_settings), + SETTING_DEFINE_STRUCT_STR("env_key5", env_key5, struct test_settings), + SETTING_DEFINE_STRUCT_STR("protocols", protocols, struct test_settings), + SETTING_DEFINE_LIST_END +}; + +static const struct test_settings test_settings_defaults = { + .key = "", + .key2 = "", + .key3 = "", + .key4 = "", + .key5 = "", + .pop3_deleted_flag = "", + .env_key = "", + .env_key2 = "", + .env_key3 = "", + .env_key4 = "", + .env_key5 = "", + .protocols = "pop3", +}; + +const struct setting_parser_info test_settings_root = { + .module_name = "test", + .defines = test_settings_defs, + .defaults = &test_settings_defaults, + + .type_offset = SIZE_MAX, + .struct_size = sizeof(struct test_settings), + + .parent_offset = SIZE_MAX, + .parent = NULL, +}; + +static const struct setting_parser_info *const roots[] = { + &test_settings_root, + NULL +}; + +const struct setting_parser_info *const *all_roots = roots; + +static void write_config_file(const char *contents) +{ + struct ostream *os = o_stream_create_file(TEST_CONFIG_FILE, 0, 0600, 0); + o_stream_nsend_str(os, contents); + test_assert(o_stream_finish(os) == 1); + o_stream_unref(&os); +} + +static void test_config_parser(void) +{ + const char *error = NULL; + + test_begin("config_parse_file"); + + write_config_file( +"# comment\n" +"key=value\n" +"key2 = \\$escape \\escape \\\"escape\\\"\n" +"key3 = value\n" +"key3 = $key3 nothervalue\n" +"key3 = yetanother value $key3 right here\n" +"key4 = \" $key3 \"\n" +"key5 = ' $key4 '\n" +"pop3_deleted_flag = \"$Deleted\"\n" +"env_key=$ENV:foo\n" +"env_key=$env_key $ENV:bar\n" +"env_key=$env_key \"$env_key\"\n" +"env_key2 = foo$ENV:FOO bar\n" +"env_key3 = $ENV:FOO$ENV:FOO bar\n" +"env_key4 = $ENV:foo $ENV:bar $key\n" +"env_key5 = $ENV:foo $ENV:foo\n" +"protocols = $protocols imap\n" + ); + + putenv("foo=test1"); + putenv("bar=test2"); + putenv("FOO$ENV:FOO=works"); + + test_assert(config_parse_file(TEST_CONFIG_FILE, TRUE, NULL, &error) == 1); + if (error != NULL) + i_error("config_parse_file(): %s", error); + + /* get the parsed output */ + const struct test_settings *set = + settings_parser_get(config_module_parsers[0].parser); + test_assert_strcmp(set->key, "value"); + test_assert_strcmp(set->key2, "\\$escape \\escape \\\"escape\\\""); + test_assert_strcmp(set->key3, "yetanother value value nothervalue right here"); + test_assert_strcmp(set->key4, " $key3 "); + test_assert_strcmp(set->key5, " $key4 "); + test_assert_strcmp(set->pop3_deleted_flag, "$Deleted"); + test_assert_strcmp(set->env_key, "test1 test2 \"$env_key\""); + test_assert_strcmp(set->env_key2, "foo$ENV:FOO bar"); + test_assert_strcmp(set->env_key3, "works bar"); + test_assert_strcmp(set->env_key4, "test1 test2 value"); + test_assert_strcmp(set->env_key5, "test1 test1"); + test_assert_strcmp(set->protocols, "pop3 imap"); + + /* try again unexpanded */ + test_assert(config_parse_file(TEST_CONFIG_FILE, FALSE, NULL, &error) == 1); + set = settings_parser_get(config_module_parsers[0].parser); + + test_assert_strcmp(set->key, "value"); + test_assert_strcmp(set->key2, "\\$escape \\escape \\\"escape\\\""); + test_assert_strcmp(set->key3, "yetanother value value nothervalue right here"); + test_assert_strcmp(set->key4, " $key3 "); + test_assert_strcmp(set->key5, " $key4 "); + test_assert_strcmp(set->pop3_deleted_flag, "$Deleted"); + test_assert_strcmp(set->env_key, "$ENV:foo $ENV:bar \"$env_key\""); + test_assert_strcmp(set->env_key2, "foo$ENV:FOO bar"); + test_assert_strcmp(set->env_key3, "$ENV:FOO$ENV:FOO bar"); + test_assert_strcmp(set->env_key4, "$ENV:foo $ENV:bar $key"); + test_assert_strcmp(set->env_key5, "$ENV:foo $ENV:foo"); + test_assert_strcmp(set->protocols, "pop3 imap"); + + config_filter_deinit(&config_filter); + config_parser_deinit(); + i_unlink_if_exists(TEST_CONFIG_FILE); + test_end(); +} + +int main(void) +{ + static void (*const test_functions[])(void) = { + test_config_parser, + NULL + }; + return test_run(test_functions); +} |