summaryrefslogtreecommitdiffstats
path: root/src/config/test-config-parser.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/config/test-config-parser.c')
-rw-r--r--src/config/test-config-parser.c170
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);
+}