mirror of
https://github.com/samba-team/samba.git
synced 2025-02-26 21:57:41 +03:00
ctdb-common: Add config file parsing code
Signed-off-by: Amitay Isaacs <amitay@gmail.com> Reviewed-by: Martin Schwenke <martin@meltin.net>
This commit is contained in:
parent
77539b479e
commit
702504118f
1259
ctdb/common/conf.c
Normal file
1259
ctdb/common/conf.c
Normal file
File diff suppressed because it is too large
Load Diff
473
ctdb/common/conf.h
Normal file
473
ctdb/common/conf.h
Normal file
@ -0,0 +1,473 @@
|
||||
/*
|
||||
Configuration file handling on top of tini
|
||||
|
||||
Copyright (C) Amitay Isaacs 2017
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __CTDB_CONF_H__
|
||||
#define __CTDB_CONF_H__
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdbool.h>
|
||||
#include <talloc.h>
|
||||
|
||||
/**
|
||||
* @file conf.h
|
||||
*
|
||||
* @brief Configuration file handling with sections and key-value pairs
|
||||
*
|
||||
* CTDB settings can be written in a configuration file ctdb.conf (similar to
|
||||
* samba's smb.conf). Various daemons and tools will consult the configuration
|
||||
* file for runtime settings.
|
||||
*
|
||||
* The configuration will be organized in sections depending on various
|
||||
* components. Each section will have various configuration options in the form
|
||||
* of key-value pairs.
|
||||
*
|
||||
* [section1]
|
||||
* key1 = value1
|
||||
* ...
|
||||
*
|
||||
* [section2]
|
||||
* key2 = value2
|
||||
* ...
|
||||
*
|
||||
* ...
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Abstract data structure holding the configuration options
|
||||
*/
|
||||
struct conf_context;
|
||||
|
||||
/**
|
||||
* @brief configuration option update mode
|
||||
*
|
||||
* When a value of configuration option is changed, update mode is set
|
||||
* appropriately.
|
||||
*
|
||||
* CONF_MODE_API - value modified using set functions
|
||||
* CONF_MODE_LOAD - value modified via conf_load
|
||||
* CONF_MODE_RELOAD - value modified via conf_reload
|
||||
*/
|
||||
enum conf_update_mode {
|
||||
CONF_MODE_API,
|
||||
CONF_MODE_LOAD,
|
||||
CONF_MODE_RELOAD,
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief configuration option type
|
||||
*/
|
||||
enum conf_type {
|
||||
CONF_STRING,
|
||||
CONF_INTEGER,
|
||||
CONF_BOOLEAN,
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Configuration section validation function
|
||||
*
|
||||
* Check if all the configuration options are consistent with each-other
|
||||
*/
|
||||
typedef bool (*conf_validate_section_fn)(struct conf_context *conf,
|
||||
const char *section,
|
||||
enum conf_update_mode mode);
|
||||
|
||||
/**
|
||||
* @brief Configuration option validation function for string
|
||||
*
|
||||
* Check if a configuration option value is valid
|
||||
*/
|
||||
typedef bool (*conf_validate_string_option_fn)(const char *key,
|
||||
const char *old_value,
|
||||
const char *new_value,
|
||||
enum conf_update_mode mode);
|
||||
|
||||
/**
|
||||
* @brief Configuration option validation function for integer
|
||||
*
|
||||
* Check if a configuration option value is valid
|
||||
*/
|
||||
typedef bool (*conf_validate_integer_option_fn)(const char *key,
|
||||
int old_value,
|
||||
int new_value,
|
||||
enum conf_update_mode mode);
|
||||
|
||||
/**
|
||||
* @brief Configuration option validation function for boolean
|
||||
*
|
||||
* Check if a configuration option value is valid
|
||||
*/
|
||||
typedef bool (*conf_validate_boolean_option_fn)(const char *key,
|
||||
bool old_value,
|
||||
bool new_value,
|
||||
enum conf_update_mode mode);
|
||||
|
||||
/**
|
||||
* @brief Initialize configuration option database
|
||||
*
|
||||
* This return a new configuration options context. Freeing this context will
|
||||
* free up all the memory associated with the configuration options.
|
||||
*
|
||||
* @param[in] mem_ctx Talloc memory context
|
||||
* @param[in] result The new configuration options context
|
||||
* @return 0 on success, errno on failure
|
||||
*/
|
||||
int conf_init(TALLOC_CTX *mem_ctx, struct conf_context **result);
|
||||
|
||||
/**
|
||||
* @brief Define a section for organizing configuration options
|
||||
*
|
||||
* This functions creates a section to organize configuration option. The
|
||||
* section names are case-insensitive and are always stored in lower case.
|
||||
*
|
||||
* @param[in] conf The configuration options context
|
||||
* @param[in] section The name of the section
|
||||
* @param[in] validate The validation function for configuration options
|
||||
*/
|
||||
void conf_define_section(struct conf_context *conf,
|
||||
const char *section,
|
||||
conf_validate_section_fn validate);
|
||||
|
||||
/**
|
||||
* @brief Define a configuration option which has a string value
|
||||
*
|
||||
* This functions adds a new configuration option organized under a given
|
||||
* section. Configuration options are case-insensitive and are always stored
|
||||
* in lower case.
|
||||
*
|
||||
* @param[in] conf The configuration options context
|
||||
* @param[in] section The name of the section
|
||||
* @param[in] key The name of the configuration option
|
||||
* @param[in] default_value The default value for the configuration option
|
||||
* @param[in] validate The validation function for the configuration option
|
||||
*/
|
||||
void conf_define_string(struct conf_context *conf,
|
||||
const char *section,
|
||||
const char *key,
|
||||
const char *default_value,
|
||||
conf_validate_string_option_fn validate);
|
||||
|
||||
/**
|
||||
* @brief Define a configuration option which has an integer value
|
||||
*
|
||||
* This functions adds a new configuration option organized under a given
|
||||
* section. Configuration options are case-insensitive and are always stored
|
||||
* in lower case.
|
||||
*
|
||||
* @param[in] conf The configuration options context
|
||||
* @param[in] section The name of the section
|
||||
* @param[in] key The name of the configuration option
|
||||
* @param[in] default_value The default value for the configuration option
|
||||
* @param[in] validate The validation function for the configuration option
|
||||
*/
|
||||
void conf_define_integer(struct conf_context *conf,
|
||||
const char *section,
|
||||
const char *key,
|
||||
const int default_value,
|
||||
conf_validate_integer_option_fn validate);
|
||||
|
||||
/**
|
||||
* @brief Define a configuration option which has an boolean value
|
||||
*
|
||||
* This functions adds a new configuration option organized under a given
|
||||
* section. Configuration options are case-insensitive and are always stored
|
||||
* in lower case.
|
||||
*
|
||||
* @param[in] conf The configuration options context
|
||||
* @param[in] section The name of the section
|
||||
* @param[in] key The name of the configuration option
|
||||
* @param[in] default_value The default value for the configuration option
|
||||
* @param[in] validate The validation function for the configuration option
|
||||
*/
|
||||
void conf_define_boolean(struct conf_context *conf,
|
||||
const char *section,
|
||||
const char *key,
|
||||
const bool default_value,
|
||||
conf_validate_boolean_option_fn validate);
|
||||
|
||||
/**
|
||||
* @brief Assign user-accessible pointer for string option
|
||||
*
|
||||
* This pointer can be used for accessing the value of configuration option
|
||||
* directly without requiring a function call.
|
||||
*
|
||||
* @param[in] conf The configuration options context
|
||||
* @param[in] section The name of the section
|
||||
* @param[in] key The name of the configuration option
|
||||
* @param[in] ptr User-accessible pointer to the value
|
||||
*/
|
||||
void conf_assign_string_pointer(struct conf_context *conf,
|
||||
const char *section,
|
||||
const char *key,
|
||||
const char **ptr);
|
||||
|
||||
/**
|
||||
* @brief Assign user-accessible pointer for integer option
|
||||
*
|
||||
* This pointer can be used for accessing the value of configuration option
|
||||
* directly without requiring a function call.
|
||||
*
|
||||
* @param[in] conf The configuration options context
|
||||
* @param[in] section The name of the section
|
||||
* @param[in] key The name of the configuration option
|
||||
* @param[in] ptr User-accessible pointer to the value
|
||||
*/
|
||||
void conf_assign_integer_pointer(struct conf_context *conf,
|
||||
const char *section,
|
||||
const char *key,
|
||||
int *ptr);
|
||||
|
||||
/**
|
||||
* @brief Assign user-accessible pointer for boolean option
|
||||
*
|
||||
* This pointer can be used for accessing the value of configuration option
|
||||
* directly without requiring a function call.
|
||||
*
|
||||
* @param[in] conf The configuration options context
|
||||
* @param[in] section The name of the section
|
||||
* @param[in] key The name of the configuration option
|
||||
* @param[in] ptr User-accessible pointer to the value
|
||||
* @return true on success, false on failure
|
||||
*/
|
||||
void conf_assign_boolean_pointer(struct conf_context *conf,
|
||||
const char *section,
|
||||
const char *key,
|
||||
bool *ptr);
|
||||
|
||||
/**
|
||||
* @brief Query a configuration option
|
||||
*
|
||||
* This function checks if a configuration option is defined or not.
|
||||
*
|
||||
* @param[in] conf The configuration options context
|
||||
* @param[in] section The name of the section
|
||||
* @param[in] key The name of the configuration option
|
||||
* @param[out] type The type of the configuration option
|
||||
* @return true on success, false if section/option is not defined
|
||||
*/
|
||||
bool conf_query(struct conf_context *conf,
|
||||
const char *section,
|
||||
const char *key,
|
||||
enum conf_type *type);
|
||||
|
||||
/**
|
||||
* @brief Check if the defined configuration options are valid
|
||||
*
|
||||
* This function must be called after creating configuration options
|
||||
* to confirm that all the option definitions are valid.
|
||||
*
|
||||
* @param[in] conf The configuration options context
|
||||
* @return true on success, false on failure
|
||||
*/
|
||||
bool conf_valid(struct conf_context *conf);
|
||||
|
||||
/**
|
||||
* @brief Set the default values for all configuration options
|
||||
*
|
||||
* This function resets all the configuration options to their default values.
|
||||
*
|
||||
* @param[in] conf The connfiguration options context
|
||||
*/
|
||||
void conf_set_defaults(struct conf_context *conf);
|
||||
|
||||
/**
|
||||
* @brief Load the values for configuration option values from a file
|
||||
*
|
||||
* This function will update the values of the configuration options from those
|
||||
* specified in a file. This function will fail in case it encounters an
|
||||
* undefined option. Any sections which are not defined, will be ignored.
|
||||
*
|
||||
* This function will call validation function (if specified) before updating
|
||||
* the value of a configuration option. After updating all the values for a
|
||||
* section, the validation for section (if specified) will be called. If any
|
||||
* of the validation functions return error, then all the configuration
|
||||
* options will be reset to their previous values.
|
||||
*
|
||||
* @param[in] conf The configuration options context
|
||||
* @param[in] filename The configuration file
|
||||
* @param[in] skip_unknown Whether unknown config options should be ignored
|
||||
* @return 0 on success, errno on failure
|
||||
*/
|
||||
int conf_load(struct conf_context *conf,
|
||||
const char *filename,
|
||||
bool ignore_unknown);
|
||||
|
||||
/**
|
||||
* @brief Reload the values for configuration options
|
||||
*
|
||||
* This function will re-load the values of the configuration options. This
|
||||
* function can be called only after succesful call to conf_load().
|
||||
*
|
||||
* @see conf_load
|
||||
*
|
||||
* @param[in] conf The configuration options context
|
||||
* @return 0 on success, errno on failure.
|
||||
*/
|
||||
int conf_reload(struct conf_context *conf);
|
||||
|
||||
/**
|
||||
* @brief Set the string value of a configuration option
|
||||
*
|
||||
* This function can be used to update the value of a configuration option.
|
||||
* This will call the validation function for that option (if defined) and
|
||||
* the section validation function (if defined).
|
||||
*
|
||||
* If a user-defined storage pointer is provided, then the value of a
|
||||
* configuration option should not be changed via that pointer.
|
||||
*
|
||||
* @param[in] conf The configuration options context
|
||||
* @param[in] section The name of a section
|
||||
* @param[in] key The name of a configuration option
|
||||
* @param[in] str_val The string value
|
||||
* @return 0 on success, errno in case of failure
|
||||
*/
|
||||
int conf_set_string(struct conf_context *conf,
|
||||
const char *section,
|
||||
const char *key,
|
||||
const char *str_val);
|
||||
|
||||
/**
|
||||
* @brief Set the integer value of a configuration option
|
||||
*
|
||||
* This function can be used to update the value of a configuration option.
|
||||
* This will call the validation function for that option (if defined) and
|
||||
* the section validation function (if defined).
|
||||
*
|
||||
* If a user-defined storage pointer is provided, then the value of a
|
||||
* configuration option should not be changed via that pointer.
|
||||
*
|
||||
* @param[in] conf The configuration options context
|
||||
* @param[in] section The name of a section
|
||||
* @param[in] key The name of a configuration option
|
||||
* @param[in] int_val The integer value
|
||||
* @return 0 on success, errno in case of failure
|
||||
*/
|
||||
int conf_set_integer(struct conf_context *conf,
|
||||
const char *section,
|
||||
const char *key,
|
||||
int int_val);
|
||||
|
||||
/**
|
||||
* @brief Set the boolean value of a configuration option
|
||||
*
|
||||
* This function can be used to update the value of a configuration option.
|
||||
* This will call the validation function for that option (if defined) and
|
||||
* the section validation function (if defined).
|
||||
*
|
||||
* If a user-defined storage pointer is provided, then the value of a
|
||||
* configuration option should not be changed via that pointer.
|
||||
*
|
||||
* @param[in] conf The configuration options context
|
||||
* @param[in] section The name of a section
|
||||
* @param[in] key The name of a configuration option
|
||||
* @param[in] bool_val The boolean value
|
||||
* @return 0 on success, errno in case of failure
|
||||
*/
|
||||
int conf_set_boolean(struct conf_context *conf,
|
||||
const char *section,
|
||||
const char *key,
|
||||
bool bool_val);
|
||||
|
||||
/**
|
||||
* @brief Get the string value of a configuration option
|
||||
*
|
||||
* This function can be used to fetch the current value of a configuration
|
||||
* option.
|
||||
*
|
||||
* If a user-defined storage pointer is provided, then the value of a
|
||||
* configuration option can be accessed directly via that pointer.
|
||||
*
|
||||
* @param[in] conf The configuration options context
|
||||
* @param[in] section The name of a section
|
||||
* @param[in] key The name of a configuration option
|
||||
* @param[out] str_val The string value of the configuration option
|
||||
* @param[out] is_default True if the value is default value
|
||||
* @return 0 on success, errno in case of failure
|
||||
*/
|
||||
int conf_get_string(struct conf_context *conf,
|
||||
const char *section,
|
||||
const char *key,
|
||||
const char **str_val,
|
||||
bool *is_default);
|
||||
|
||||
/**
|
||||
* @brief Get the integer value of a configuration option
|
||||
*
|
||||
* This function can be used to fetch the current value of a configuration
|
||||
* option.
|
||||
*
|
||||
* If a user-defined storage pointer is provided, then the value of a
|
||||
* configuration option can be accessed directly via that pointer.
|
||||
*
|
||||
* @param[in] conf The configuration options context
|
||||
* @param[in] section The name of a section
|
||||
* @param[in] key The name of a configuration option
|
||||
* @param[out] int_val The integer value of the configuration option
|
||||
* @param[out] is_default True if the value is default value
|
||||
* @return 0 on success, errno in case of failure
|
||||
*/
|
||||
int conf_get_integer(struct conf_context *conf,
|
||||
const char *section,
|
||||
const char *key,
|
||||
int *int_val,
|
||||
bool *is_default);
|
||||
|
||||
/**
|
||||
* @brief Get the boolean value of a configuration option
|
||||
*
|
||||
* This function can be used to fetch the current value of a configuration
|
||||
* option.
|
||||
*
|
||||
* If a user-defined storage pointer is provided, then the value of a
|
||||
* configuration option can be accessed directly via that pointer.
|
||||
*
|
||||
* @param[in] conf The configuration options context
|
||||
* @param[in] section The name of a section
|
||||
* @param[in] key The name of a configuration option
|
||||
* @param[out] bool_val The boolean value of the configuration option
|
||||
* @param[out] is_default True if the value is default value
|
||||
* @return 0 on success, errno in case of failure
|
||||
*/
|
||||
int conf_get_boolean(struct conf_context *conf,
|
||||
const char *section,
|
||||
const char *key,
|
||||
bool *bool_val,
|
||||
bool *is_default);
|
||||
|
||||
/**
|
||||
* @brief Dump the configuration in a file
|
||||
*
|
||||
* All the configuration options are dumped with their current values.
|
||||
* If an option has a default value, then it is commented.
|
||||
*
|
||||
* Here is a sample output:
|
||||
*
|
||||
* [section1]
|
||||
* key1 = value1
|
||||
* key2 = value2
|
||||
* # key3 = default_value3
|
||||
* [section2]
|
||||
* key4 = value4
|
||||
*
|
||||
* @param[in] conf The configuration options context
|
||||
* @param[in] fp File pointer
|
||||
*/
|
||||
void conf_dump(struct conf_context *conf, FILE *fp);
|
||||
|
||||
#endif /* __CTDB_CONF_H__ */
|
124
ctdb/tests/cunit/conf_test_001.sh
Executable file
124
ctdb/tests/cunit/conf_test_001.sh
Executable file
@ -0,0 +1,124 @@
|
||||
#!/bin/sh
|
||||
|
||||
. "${TEST_SCRIPTS_DIR}/unit.sh"
|
||||
|
||||
conffile="${TEST_VAR_DIR}/config.$$"
|
||||
|
||||
remove_files ()
|
||||
{
|
||||
rm -f "$conffile"
|
||||
}
|
||||
|
||||
test_cleanup remove_files
|
||||
|
||||
ok_null
|
||||
unit_test conf_test 1
|
||||
|
||||
ok <<EOF
|
||||
conf: unknown section [section1]
|
||||
EOF
|
||||
unit_test conf_test 2
|
||||
|
||||
ok <<EOF
|
||||
conf: option "key1" already exists
|
||||
EOF
|
||||
unit_test conf_test 3
|
||||
|
||||
ok <<EOF
|
||||
conf: option "key1" already exists
|
||||
EOF
|
||||
unit_test conf_test 4
|
||||
|
||||
ok_null
|
||||
unit_test conf_test 5
|
||||
|
||||
ok_null
|
||||
unit_test conf_test 6
|
||||
|
||||
ok <<EOF
|
||||
conf: validation for option "key1" failed
|
||||
conf: validation for option "key2" failed
|
||||
conf: validation for option "key3" failed
|
||||
EOF
|
||||
unit_test conf_test 7
|
||||
|
||||
cat > "$conffile" <<EOF
|
||||
[section1]
|
||||
EOF
|
||||
|
||||
required_result 22 <<EOF
|
||||
conf: validation for section [section1] failed
|
||||
[section1]
|
||||
# key1 = default
|
||||
EOF
|
||||
unit_test conf_test 8 "$conffile"
|
||||
|
||||
cat > "$conffile" <<EOF
|
||||
[section1]
|
||||
key1 = unknown
|
||||
EOF
|
||||
|
||||
required_result 22 <<EOF
|
||||
conf: validation for section [section1] failed
|
||||
[section1]
|
||||
# key1 = default
|
||||
EOF
|
||||
unit_test conf_test 8 "$conffile"
|
||||
|
||||
cat > "$conffile" <<EOF
|
||||
|
||||
[section1]
|
||||
key1 = value2
|
||||
key2 = 20 # comment
|
||||
key3 = false
|
||||
EOF
|
||||
|
||||
ok <<EOF
|
||||
[section1]
|
||||
key1 = value2
|
||||
key2 = 20
|
||||
key3 = false
|
||||
EOF
|
||||
unit_test conf_test 9 "$conffile"
|
||||
|
||||
cat > "$conffile" <<EOF
|
||||
[section1]
|
||||
key1 = value2
|
||||
EOF
|
||||
|
||||
ok <<EOF
|
||||
[section1]
|
||||
key1 = value2
|
||||
# key2 = 10
|
||||
key3 = false # temporary
|
||||
EOF
|
||||
unit_test conf_test 9 "$conffile"
|
||||
|
||||
cat > "$conffile" <<EOF
|
||||
[section2]
|
||||
foo = bar
|
||||
EOF
|
||||
|
||||
required_result 22 <<EOF
|
||||
conf: unknown section [section2]
|
||||
[section1]
|
||||
# key1 = value1
|
||||
# key2 = 10
|
||||
key3 = false # temporary
|
||||
EOF
|
||||
unit_test conf_test 10 "$conffile"
|
||||
|
||||
cat > "$conffile" <<EOF
|
||||
[section1]
|
||||
key1 = value2
|
||||
foo = bar
|
||||
key2 = 20
|
||||
EOF
|
||||
|
||||
required_result 2 <<EOF
|
||||
[section1]
|
||||
# key1 = value1
|
||||
# key2 = 10
|
||||
key3 = false # temporary
|
||||
EOF
|
||||
unit_test conf_test 10 "$conffile"
|
460
ctdb/tests/src/conf_test.c
Normal file
460
ctdb/tests/src/conf_test.c
Normal file
@ -0,0 +1,460 @@
|
||||
/*
|
||||
Configuration file handling on top of tini
|
||||
|
||||
Copyright (C) Amitay Isaacs 2017
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "replace.h"
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include "common/conf.c"
|
||||
|
||||
static void test1(void)
|
||||
{
|
||||
TALLOC_CTX *mem_ctx = talloc_new(NULL);
|
||||
struct conf_context *conf;
|
||||
int ret;
|
||||
bool status;
|
||||
|
||||
ret = conf_init(mem_ctx, &conf);
|
||||
assert(ret == 0);
|
||||
assert(conf != NULL);
|
||||
|
||||
conf_define_section(conf, "section1", NULL);
|
||||
status = conf_valid(conf);
|
||||
assert(status == true);
|
||||
|
||||
conf_define_section(conf, NULL, NULL);
|
||||
status = conf_valid(conf);
|
||||
assert(status == false);
|
||||
|
||||
talloc_free(mem_ctx);
|
||||
}
|
||||
|
||||
static void test2(void)
|
||||
{
|
||||
TALLOC_CTX *mem_ctx = talloc_new(NULL);
|
||||
struct conf_context *conf;
|
||||
int ret;
|
||||
bool status;
|
||||
|
||||
ret = conf_init(mem_ctx, &conf);
|
||||
assert(ret == 0);
|
||||
assert(conf != NULL);
|
||||
|
||||
conf_define_string(conf, "section1", "key1", "default", NULL);
|
||||
status = conf_valid(conf);
|
||||
assert(status == false);
|
||||
|
||||
talloc_free(mem_ctx);
|
||||
}
|
||||
|
||||
static void test3(void)
|
||||
{
|
||||
TALLOC_CTX *mem_ctx = talloc_new(NULL);
|
||||
struct conf_context *conf;
|
||||
int ret;
|
||||
bool status;
|
||||
|
||||
ret = conf_init(mem_ctx, &conf);
|
||||
assert(ret == 0);
|
||||
assert(conf != NULL);
|
||||
|
||||
conf_define_section(conf, "section1", NULL);
|
||||
status = conf_valid(conf);
|
||||
assert(status == true);
|
||||
|
||||
conf_define_string(conf, "section1", "key1", NULL, NULL);
|
||||
status = conf_valid(conf);
|
||||
assert(status == true);
|
||||
|
||||
conf_define_string(conf, "section1", "key1", "value1", NULL);
|
||||
status = conf_valid(conf);
|
||||
assert(status == false);
|
||||
|
||||
talloc_free(mem_ctx);
|
||||
}
|
||||
|
||||
static void test4(void)
|
||||
{
|
||||
TALLOC_CTX *mem_ctx = talloc_new(NULL);
|
||||
struct conf_context *conf;
|
||||
int ret;
|
||||
bool status;
|
||||
|
||||
ret = conf_init(mem_ctx, &conf);
|
||||
assert(ret == 0);
|
||||
assert(conf != NULL);
|
||||
|
||||
conf_define_section(conf, "section1", NULL);
|
||||
status = conf_valid(conf);
|
||||
assert(status == true);
|
||||
|
||||
conf_define_string(conf, "section1", "key1", NULL, NULL);
|
||||
status = conf_valid(conf);
|
||||
assert(status == true);
|
||||
|
||||
conf_define_integer(conf, "section1", "key1", 10, NULL);
|
||||
status = conf_valid(conf);
|
||||
assert(status == false);
|
||||
|
||||
talloc_free(mem_ctx);
|
||||
}
|
||||
|
||||
static void test5(void)
|
||||
{
|
||||
TALLOC_CTX *mem_ctx = talloc_new(NULL);
|
||||
struct conf_context *conf;
|
||||
enum conf_type type;
|
||||
int ret;
|
||||
bool status;
|
||||
const char *s_val;
|
||||
int i_val;
|
||||
bool b_val;
|
||||
|
||||
ret = conf_init(mem_ctx, &conf);
|
||||
assert(ret == 0);
|
||||
assert(conf != NULL);
|
||||
|
||||
conf_define_section(conf, "section1", NULL);
|
||||
status = conf_valid(conf);
|
||||
assert(status == true);
|
||||
|
||||
conf_define_string(conf, "section1", "key1", "value1", NULL);
|
||||
conf_define_integer(conf, "section1", "key2", 10, NULL);
|
||||
conf_define_boolean(conf, "section1", "key3", true, NULL);
|
||||
|
||||
conf_assign_string_pointer(conf, "section1", "key1", &s_val);
|
||||
conf_assign_integer_pointer(conf, "section1", "key2", &i_val);
|
||||
conf_assign_boolean_pointer(conf, "section1", "key3", &b_val);
|
||||
|
||||
status = conf_valid(conf);
|
||||
assert(status == true);
|
||||
|
||||
status = conf_query(conf, "section1", "key1", &type);
|
||||
assert(status == true);
|
||||
assert(type == CONF_STRING);
|
||||
|
||||
status = conf_query(conf, "section1", "key2", &type);
|
||||
assert(status == true);
|
||||
assert(type == CONF_INTEGER);
|
||||
|
||||
status = conf_query(conf, "section1", "key3", &type);
|
||||
assert(status == true);
|
||||
assert(type == CONF_BOOLEAN);
|
||||
|
||||
assert(strcmp(s_val, "value1") == 0);
|
||||
assert(i_val == 10);
|
||||
assert(b_val == true);
|
||||
|
||||
conf_set_defaults(conf);
|
||||
|
||||
assert(strcmp(s_val, "value1") == 0);
|
||||
assert(i_val == 10);
|
||||
assert(b_val == true);
|
||||
|
||||
talloc_free(mem_ctx);
|
||||
}
|
||||
|
||||
static void test6(void)
|
||||
{
|
||||
TALLOC_CTX *mem_ctx = talloc_new(NULL);
|
||||
struct conf_context *conf;
|
||||
int ret;
|
||||
bool status;
|
||||
const char *s_val, *s2_val;
|
||||
int i_val, i2_val;
|
||||
bool b_val, b2_val, is_default;
|
||||
|
||||
ret = conf_init(mem_ctx, &conf);
|
||||
assert(ret == 0);
|
||||
assert(conf != NULL);
|
||||
|
||||
conf_define_section(conf, "section1", NULL);
|
||||
status = conf_valid(conf);
|
||||
assert(status == true);
|
||||
|
||||
conf_define_string(conf, "section1", "key1", "default", NULL);
|
||||
conf_define_integer(conf, "section1", "key2", 10, NULL);
|
||||
conf_define_boolean(conf, "section1", "key3", true, NULL);
|
||||
|
||||
conf_assign_string_pointer(conf, "section1", "key1", &s_val);
|
||||
conf_assign_integer_pointer(conf, "section1", "key2", &i_val);
|
||||
conf_assign_boolean_pointer(conf, "section1", "key3", &b_val);
|
||||
|
||||
status = conf_valid(conf);
|
||||
assert(status == true);
|
||||
|
||||
is_default = false;
|
||||
ret = conf_get_string(conf, "section1", "key1", &s2_val, &is_default);
|
||||
assert(ret == 0);
|
||||
assert(strcmp(s2_val, "default") == 0);
|
||||
assert(is_default == true);
|
||||
|
||||
is_default = false;
|
||||
ret = conf_get_integer(conf, "section1", "key2", &i2_val, &is_default);
|
||||
assert(ret == 0);
|
||||
assert(i2_val == 10);
|
||||
assert(is_default == true);
|
||||
|
||||
is_default = false;
|
||||
ret = conf_get_boolean(conf, "section1", "key3", &b2_val, &is_default);
|
||||
assert(ret == 0);
|
||||
assert(b2_val == true);
|
||||
assert(is_default == true);
|
||||
|
||||
ret = conf_set_string(conf, "section1", "key1", "foobar");
|
||||
assert(ret == 0);
|
||||
|
||||
ret = conf_set_integer(conf, "section1", "key2", 20);
|
||||
assert(ret == 0);
|
||||
|
||||
ret = conf_set_boolean(conf, "section1", "key3", false);
|
||||
assert(ret == 0);
|
||||
|
||||
assert(strcmp(s_val, "foobar") == 0);
|
||||
assert(i_val == 20);
|
||||
assert(b_val == false);
|
||||
|
||||
is_default = true;
|
||||
ret = conf_get_string(conf, "section1", "key1", &s2_val, &is_default);
|
||||
assert(ret == 0);
|
||||
assert(strcmp(s2_val, "foobar") == 0);
|
||||
assert(is_default == false);
|
||||
|
||||
is_default = true;
|
||||
ret = conf_get_integer(conf, "section1", "key2", &i2_val, &is_default);
|
||||
assert(ret == 0);
|
||||
assert(i2_val == 20);
|
||||
assert(is_default == false);
|
||||
|
||||
is_default = true;
|
||||
ret = conf_get_boolean(conf, "section1", "key3", &b2_val, &is_default);
|
||||
assert(ret == 0);
|
||||
assert(b2_val == false);
|
||||
assert(is_default == false);
|
||||
|
||||
conf_set_defaults(conf);
|
||||
|
||||
assert(strcmp(s_val, "default") == 0);
|
||||
assert(i_val == 10);
|
||||
assert(b_val == true);
|
||||
|
||||
talloc_free(mem_ctx);
|
||||
}
|
||||
|
||||
static bool test7_validate_string(const char *key,
|
||||
const char *old_value, const char *new_value,
|
||||
enum conf_update_mode mode)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool test7_validate_integer(const char *key,
|
||||
int old_value, int new_value,
|
||||
enum conf_update_mode mode)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool test7_validate_boolean(const char *key,
|
||||
bool old_value, bool new_value,
|
||||
enum conf_update_mode mode)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
static void test7(void)
|
||||
{
|
||||
TALLOC_CTX *mem_ctx = talloc_new(NULL);
|
||||
struct conf_context *conf;
|
||||
int ret;
|
||||
bool status;
|
||||
const char *s_val, *s2_val;
|
||||
int i_val, i2_val;
|
||||
bool b_val, b2_val;
|
||||
|
||||
ret = conf_init(mem_ctx, &conf);
|
||||
assert(ret == 0);
|
||||
assert(conf != NULL);
|
||||
|
||||
conf_define_section(conf, "section1", NULL);
|
||||
status = conf_valid(conf);
|
||||
assert(status == true);
|
||||
|
||||
conf_define_string(conf, "section1", "key1", "default",
|
||||
test7_validate_string);
|
||||
conf_define_integer(conf, "section1", "key2", 10,
|
||||
test7_validate_integer);
|
||||
conf_define_boolean(conf, "section1", "key3", true,
|
||||
test7_validate_boolean);
|
||||
|
||||
conf_assign_string_pointer(conf, "section1", "key1", &s_val);
|
||||
conf_assign_integer_pointer(conf, "section1", "key2", &i_val);
|
||||
conf_assign_boolean_pointer(conf, "section1", "key3", &b_val);
|
||||
|
||||
status = conf_valid(conf);
|
||||
assert(status == true);
|
||||
|
||||
ret = conf_set_string(conf, "section1", "key1", "foobar");
|
||||
assert(ret == EINVAL);
|
||||
|
||||
ret = conf_set_integer(conf, "section1", "key2", 20);
|
||||
assert(ret == EINVAL);
|
||||
|
||||
ret = conf_set_boolean(conf, "section1", "key3", false);
|
||||
assert(ret == EINVAL);
|
||||
|
||||
assert(strcmp(s_val, "default") == 0);
|
||||
assert(i_val == 10);
|
||||
assert(b_val == true);
|
||||
|
||||
ret = conf_get_string(conf, "section1", "key2", &s2_val, NULL);
|
||||
assert(ret == EINVAL);
|
||||
|
||||
ret = conf_get_integer(conf, "section1", "key3", &i2_val, NULL);
|
||||
assert(ret == EINVAL);
|
||||
|
||||
ret = conf_get_boolean(conf, "section1", "key1", &b2_val, NULL);
|
||||
assert(ret == EINVAL);
|
||||
|
||||
talloc_free(mem_ctx);
|
||||
}
|
||||
|
||||
static bool test8_validate(struct conf_context *conf,
|
||||
const char *section,
|
||||
enum conf_update_mode mode)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
static void test8(const char *filename)
|
||||
{
|
||||
TALLOC_CTX *mem_ctx = talloc_new(NULL);
|
||||
struct conf_context *conf;
|
||||
int ret;
|
||||
bool status;
|
||||
|
||||
ret = conf_init(mem_ctx, &conf);
|
||||
assert(ret == 0);
|
||||
assert(conf != NULL);
|
||||
|
||||
conf_define_section(conf, "section1", test8_validate);
|
||||
status = conf_valid(conf);
|
||||
assert(status == true);
|
||||
|
||||
conf_define_string(conf, "section1", "key1", "default", NULL);
|
||||
|
||||
status = conf_valid(conf);
|
||||
assert(status == true);
|
||||
|
||||
ret = conf_load(conf, filename, true);
|
||||
conf_dump(conf, stdout);
|
||||
|
||||
talloc_free(mem_ctx);
|
||||
exit(ret);
|
||||
}
|
||||
|
||||
static void test9(const char *filename, bool ignore_unknown)
|
||||
{
|
||||
TALLOC_CTX *mem_ctx = talloc_new(NULL);
|
||||
struct conf_context *conf;
|
||||
int ret;
|
||||
bool status;
|
||||
|
||||
ret = conf_init(mem_ctx, &conf);
|
||||
assert(ret == 0);
|
||||
assert(conf != NULL);
|
||||
|
||||
conf_define_section(conf, "section1", NULL);
|
||||
|
||||
conf_define_string(conf, "section1", "key1", "value1", NULL);
|
||||
conf_define_integer(conf, "section1", "key2", 10, NULL);
|
||||
conf_define_boolean(conf, "section1", "key3", true, NULL);
|
||||
|
||||
status = conf_valid(conf);
|
||||
assert(status == true);
|
||||
|
||||
conf_set_boolean(conf, "section1", "key3", false);
|
||||
|
||||
ret = conf_load(conf, filename, ignore_unknown);
|
||||
conf_dump(conf, stdout);
|
||||
|
||||
talloc_free(mem_ctx);
|
||||
exit(ret);
|
||||
}
|
||||
|
||||
int main(int argc, const char **argv)
|
||||
{
|
||||
int num;
|
||||
|
||||
if (argc < 2) {
|
||||
fprintf(stderr, "Usage: %s <testnum> [<config>]\n", argv[0]);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
num = atoi(argv[1]);
|
||||
if (num > 7 && argc != 3) {
|
||||
fprintf(stderr, "Usage: %s <testnum> [<config>]\n", argv[0]);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
switch (num) {
|
||||
case 1:
|
||||
test1();
|
||||
break;
|
||||
|
||||
case 2:
|
||||
test2();
|
||||
break;
|
||||
|
||||
case 3:
|
||||
test3();
|
||||
break;
|
||||
|
||||
case 4:
|
||||
test4();
|
||||
break;
|
||||
|
||||
case 5:
|
||||
test5();
|
||||
break;
|
||||
|
||||
case 6:
|
||||
test6();
|
||||
break;
|
||||
|
||||
case 7:
|
||||
test7();
|
||||
break;
|
||||
|
||||
case 8:
|
||||
test8(argv[2]);
|
||||
break;
|
||||
|
||||
case 9:
|
||||
test9(argv[2], true);
|
||||
break;
|
||||
|
||||
case 10:
|
||||
test9(argv[2], false);
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
@ -400,7 +400,7 @@ def build(bld):
|
||||
pidfile.c run_proc.c
|
||||
hash_count.c run_event.c
|
||||
sock_client.c version.c
|
||||
cmdline.c path.c
|
||||
cmdline.c path.c conf.c
|
||||
'''),
|
||||
deps='''samba-util sys_rw tevent-util
|
||||
replace talloc tevent tdb popt''')
|
||||
@ -756,7 +756,8 @@ def build(bld):
|
||||
'sock_io_test',
|
||||
'hash_count_test',
|
||||
'run_event_test',
|
||||
'cmdline_test'
|
||||
'cmdline_test',
|
||||
'conf_test',
|
||||
]
|
||||
|
||||
for target in ctdb_unit_tests:
|
||||
|
Loading…
x
Reference in New Issue
Block a user