[asterisk-commits] twilson: branch twilson/config_work r367123 - in /team/twilson/config_work: a...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Mon May 21 11:45:46 CDT 2012


Author: twilson
Date: Mon May 21 11:45:34 2012
New Revision: 367123

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=367123
Log:
Add tests, fix issues found by test

Modified:
    team/twilson/config_work/apps/app_skel.c
    team/twilson/config_work/main/config_options.c
    team/twilson/config_work/main/udptl.c
    team/twilson/config_work/tests/test_config.c

Modified: team/twilson/config_work/apps/app_skel.c
URL: http://svnview.digium.com/svn/asterisk/team/twilson/config_work/apps/app_skel.c?view=diff&rev=367123&r1=367122&r2=367123
==============================================================================
--- team/twilson/config_work/apps/app_skel.c (original)
+++ team/twilson/config_work/apps/app_skel.c Mon May 21 11:45:34 2012
@@ -190,7 +190,7 @@
 	.type = ACO_GLOBAL,
 	.item_offset = offsetof(struct skel_config, global),
 	.category_match = ACO_WHITELIST,
-	.category = "general",
+	.category = "^general$",
 };
 
 /*! \brief An aco_type structure to link the "sounds" category to the skel_global_config type */
@@ -198,14 +198,14 @@
 	.type = ACO_GLOBAL,
 	.item_offset = offsetof(struct skel_config, global),
 	.category_match = ACO_WHITELIST,
-	.category = "sounds",
+	.category = "^sounds$",
 };
 
 /*! \brief An aco_type structure to link the everything but the "general" and "sounds" categories to the skel_level type */
 static struct aco_type level_options = {
 	.type = ACO_ITEM,
 	.category_match = ACO_BLACKLIST,
-	.category = "general|sounds",
+	.category = "^(general|sounds)$",
 	.item_alloc = skel_level_alloc,
 	.item_exists = skel_level_exists,
 	.item_offset = offsetof(struct skel_config, levels),

Modified: team/twilson/config_work/main/config_options.c
URL: http://svnview.digium.com/svn/asterisk/team/twilson/config_work/main/config_options.c?view=diff&rev=367123&r1=367122&r2=367123
==============================================================================
--- team/twilson/config_work/main/config_options.c (original)
+++ team/twilson/config_work/main/config_options.c Mon May 21 11:45:34 2012
@@ -56,7 +56,7 @@
 	aco_option_handler handler;
 	unsigned int flags;
 	size_t argc;
-	size_t args[0];
+	intptr_t args[0];
 };
 
 void *aco_pending_config(struct aco_info *info)
@@ -364,7 +364,7 @@
 	return res;
 
 error:
-	ao2_ref(info->internal->pending, -1);
+	ao2_cleanup(info->internal->pending);
 	return -1;
 }
 
@@ -587,8 +587,9 @@
 
 static int acl_handler_fn(const struct aco_option *opt, struct ast_variable *var, void *obj) {
 	struct ast_ha **ha = (struct ast_ha **)(obj + opt->args[0]);
+	const char *permit = (const char *) opt->args[1];
 	int error = 0;
-	*ha = ast_append_ha(var->name, var->value, *ha, &error);
+	*ha = ast_append_ha(permit, var->value, *ha, &error);
 	return error;
 }
 

Modified: team/twilson/config_work/main/udptl.c
URL: http://svnview.digium.com/svn/asterisk/team/twilson/config_work/main/udptl.c?view=diff&rev=367123&r1=367122&r2=367123
==============================================================================
--- team/twilson/config_work/main/udptl.c (original)
+++ team/twilson/config_work/main/udptl.c Mon May 21 11:45:34 2012
@@ -195,7 +195,7 @@
 static struct aco_type general_options = {
 	.type = ACO_GLOBAL,
 	.category_match = ACO_WHITELIST,
-	.category = "general",
+	.category = "^general$",
 };
 
 CONFIG_INFO_STANDARD(cfg_info, "udptl.conf", globals, udptl_snapshot_alloc,

Modified: team/twilson/config_work/tests/test_config.c
URL: http://svnview.digium.com/svn/asterisk/team/twilson/config_work/tests/test_config.c?view=diff&rev=367123&r1=367122&r2=367123
==============================================================================
--- team/twilson/config_work/tests/test_config.c (original)
+++ team/twilson/config_work/tests/test_config.c Mon May 21 11:45:34 2012
@@ -38,6 +38,11 @@
 #include "asterisk/test.h"
 #include "asterisk/module.h"
 #include "asterisk/config.h"
+#include "asterisk/config_options.h"
+#include "asterisk/netsock2.h"
+#include "asterisk/acl.h"
+#include "asterisk/frame.h"
+#include "asterisk/utils.h"
 #include "asterisk/logger.h"
 
 enum {
@@ -274,15 +279,308 @@
 	return ret;
 }
 
+struct test_item {
+	AST_DECLARE_STRING_FIELDS(
+		AST_STRING_FIELD(name);
+		AST_STRING_FIELD(stropt);
+	);
+	int32_t intopt;
+	uint32_t uintopt;
+	double doubleopt;
+	struct ast_sockaddr sockaddropt;
+	int boolopt;
+	struct ast_ha *aclopt;
+	struct ast_codec_pref codecprefopt;
+	struct ast_format_cap *codeccapopt;
+	unsigned int customopt:1;
+};
+struct test_config {
+	struct test_item *global;
+	struct test_item *global_defaults;
+	struct ao2_container *items;
+};
+
+static int test_item_hash(const void *obj, const int flags)
+{
+	const struct test_item *item = obj;
+	const char *name = (flags & OBJ_KEY) ? obj : item->name;
+	return ast_str_case_hash(name);
+}
+static int test_item_cmp(void *obj, void *arg, int flags)
+{
+	struct test_item *one = obj, *two = arg;
+	const char *match = (flags & OBJ_KEY) ? arg : two->name;
+	return strcasecmp(one->name, match) ? 0 : (CMP_MATCH | CMP_STOP);
+}
+static void test_item_destructor(void *obj)
+{
+	struct test_item *item = obj;
+	ast_string_field_free_memory(item);
+	if (item->codeccapopt) {
+		ast_format_cap_destroy(item->codeccapopt);
+	}
+	if (item->aclopt) {
+		ast_free_ha(item->aclopt);
+	}
+	return;
+}
+static void *test_item_alloc(const char *cat)
+{
+	struct test_item *item;
+	if (!(item = ao2_alloc(sizeof(*item), test_item_destructor))) {
+		return NULL;
+	}
+	if (ast_string_field_init(item, 128)) {
+		ao2_ref(item, -1);
+		return NULL;
+	}
+	if (!(item->codeccapopt = ast_format_cap_alloc())) {
+		ao2_ref(item, -1);
+		return NULL;
+	}
+	ast_string_field_set(item, name, cat);
+	return item;
+}
+static void test_config_destructor(void *obj)
+{
+	struct test_config *cfg = obj;
+	ao2_cleanup(cfg->global);
+	ao2_cleanup(cfg->global_defaults);
+	ao2_cleanup(cfg->items);
+}
+static void *test_config_alloc(void)
+{
+	struct test_config *cfg;
+	if (!(cfg = ao2_alloc(sizeof(*cfg), test_config_destructor))) {
+		goto error;
+	}
+	if (!(cfg->global = test_item_alloc("global"))) {
+		goto error;
+	}
+	if (!(cfg->global_defaults = test_item_alloc("global_defaults"))) {
+		goto error;
+	}
+	if (!(cfg->items = ao2_container_alloc(1, test_item_hash, test_item_cmp))) {
+		goto error;
+	}
+	return cfg;
+error:
+	ao2_cleanup(cfg);
+	return NULL;
+}
+static int test_item_exists(struct ao2_container *container, const char *cat)
+{
+	RAII_VAR(struct test_item *, item, ao2_find(container, cat, OBJ_KEY), ao2_cleanup);
+	return item ? 1 : 0;
+}
+
+static int customopt_handler(const struct aco_option *opt, struct ast_variable *var, void *obj)
+{
+	struct test_item *item = obj;
+	if (!strcasecmp(var->name, "customopt")) {
+		item->customopt = ast_true(var->value);
+	} else {
+		return -1;
+	}
+
+	return 0;
+}
+
+static struct aco_type global = {
+	.type = ACO_GLOBAL,
+	.item_offset = offsetof(struct test_config, global),
+	.category_match = ACO_WHITELIST,
+	.category = "^global$",
+};
+static struct aco_type global_defaults = {
+	.type = ACO_GLOBAL,
+	.item_offset = offsetof(struct test_config, global_defaults),
+	.category_match = ACO_WHITELIST,
+	.category = "^global_defaults$",
+};
+static struct aco_type item = {
+	.type = ACO_ITEM,
+	.category_match = ACO_BLACKLIST,
+	.category = "^(global|global_defaults)$",
+	.item_alloc = test_item_alloc,
+	.item_exists = test_item_exists,
+	.item_offset = offsetof(struct test_config, items),
+};
+static AO2_GLOBAL_OBJ_STATIC(global_obj);
+CONFIG_INFO_STANDARD(cfg_info, "config_test.conf", global_obj, test_config_alloc,
+	.types = ACO_TYPES(&global, &global_defaults, &item),
+);
+
+AST_TEST_DEFINE(config_options_test)
+{
+	int res = AST_TEST_PASS, x, error;
+	struct test_item defaults = { 0, }, configs = { 0, };
+	struct test_item *arr[4];
+	struct ast_sockaddr acl_allow = {{ 0, }}, acl_fail = {{ 0, }};
+	RAII_VAR(struct test_config *, cfg, NULL, ao2_cleanup);
+	RAII_VAR(struct test_item *, item, NULL, ao2_cleanup);
+	RAII_VAR(struct test_item *, item_defaults, NULL, ao2_cleanup);
+		
+	switch (cmd) {
+	case TEST_INIT:
+		info->name = "config_options_test";
+		info->category = "/main/config/";
+		info->summary = "Config opptions unit test";
+		info->description =
+			"Tests the Config Options API";
+		return AST_TEST_NOT_RUN;
+	case TEST_EXECUTE:
+		break;
+	}
+
+#define INT_DEFAULT "-2"
+#define INT_CONFIG "-1"
+#define UINT_DEFAULT "2"
+#define UINT_CONFIG "1"
+#define DOUBLE_DEFAULT "1.1"
+#define DOUBLE_CONFIG "0.1"
+#define SOCKADDR_DEFAULT "4.3.2.1:4321"
+#define SOCKADDR_CONFIG "1.2.3.4:1234"
+#define BOOL_DEFAULT "false"
+#define BOOL_CONFIG "true"
+#define ACL_DEFAULT NULL
+#define ACL_CONFIG_PERMIT "1.2.3.4/32"
+#define ACL_CONFIG_DENY "0.0.0.0/0"
+#define CODEC_DEFAULT "!all,alaw"
+#define CODEC_CONFIG "!all,ulaw,g729"
+#define STR_DEFAULT "default"
+#define STR_CONFIG "test"
+#define CUSTOM_DEFAULT "no"
+#define CUSTOM_CONFIG "yes"
+
+	if (aco_info_init(&cfg_info)) {
+		ast_test_status_update(test, "Could not init cfg info\n");
+		return AST_TEST_FAIL;
+	}
+
+	/* Register all options */
+	for (x = 0; x < 3; x++) {
+		aco_option_register(&cfg_info, "intopt", cfg_info.types[x], INT_DEFAULT, OPT_INT_T, 0, FLDSET(struct test_item, intopt));
+		aco_option_register(&cfg_info, "uintopt", cfg_info.types[x], UINT_DEFAULT, OPT_UINT_T, 0, FLDSET(struct test_item, uintopt));
+		aco_option_register(&cfg_info, "doubleopt", cfg_info.types[x], DOUBLE_DEFAULT, OPT_DOUBLE_T, 0, FLDSET(struct test_item, doubleopt));
+		aco_option_register(&cfg_info, "sockaddropt", cfg_info.types[x], SOCKADDR_DEFAULT, OPT_SOCKADDR_T, 0, FLDSET(struct test_item, sockaddropt));
+		aco_option_register(&cfg_info, "boolopt", cfg_info.types[x], BOOL_DEFAULT, OPT_BOOL_T, 1, FLDSET(struct test_item, boolopt));
+		aco_option_register(&cfg_info, "aclpermitopt", cfg_info.types[x], ACL_DEFAULT, OPT_ACL_T, 1, FLDSET(struct test_item, aclopt), "permit");
+		aco_option_register(&cfg_info, "acldenyopt", cfg_info.types[x], ACL_DEFAULT, OPT_ACL_T, 0, FLDSET(struct test_item, aclopt), "deny");
+		aco_option_register(&cfg_info, "codecopt", cfg_info.types[x], CODEC_DEFAULT, OPT_CODEC_T, 1, FLDSET(struct test_item, codecprefopt, codeccapopt));
+		aco_option_register(&cfg_info, "stropt", cfg_info.types[x], STR_DEFAULT, OPT_STRINGFIELD_T, 0, STRFLDSET(struct test_item, stropt));
+		aco_option_register_custom(&cfg_info, "customopt", cfg_info.types[x], CUSTOM_DEFAULT, customopt_handler, 0);
+	}
+
+	if (aco_process_config(&cfg_info, 0)) {
+		ast_test_status_update(test, "Could not parse config\n");
+		return AST_TEST_FAIL;
+	}
+
+	ast_parse_arg(INT_DEFAULT, PARSE_INT32, &defaults.intopt);
+	ast_parse_arg(INT_CONFIG, PARSE_INT32, &configs.intopt);
+	ast_parse_arg(UINT_DEFAULT, PARSE_UINT32, &defaults.uintopt);
+	ast_parse_arg(UINT_CONFIG, PARSE_UINT32, &configs.uintopt);
+	ast_parse_arg(DOUBLE_DEFAULT, PARSE_DOUBLE, &defaults.doubleopt);
+	ast_parse_arg(DOUBLE_CONFIG, PARSE_DOUBLE, &configs.doubleopt);
+	ast_parse_arg(SOCKADDR_DEFAULT, PARSE_ADDR, &defaults.sockaddropt);
+	ast_parse_arg(SOCKADDR_CONFIG, PARSE_ADDR, &configs.sockaddropt);
+	defaults.boolopt = ast_true(BOOL_DEFAULT);
+	configs.boolopt = ast_true(BOOL_CONFIG);
+
+	defaults.aclopt = NULL;
+	configs.aclopt = ast_append_ha("deny", ACL_CONFIG_DENY, configs.aclopt, &error);
+	configs.aclopt = ast_append_ha("permit", ACL_CONFIG_PERMIT, configs.aclopt, &error);
+	ast_sockaddr_parse(&acl_allow, "1.2.3.4", PARSE_PORT_FORBID);
+	ast_sockaddr_parse(&acl_fail, "1.1.1.1", PARSE_PORT_FORBID);
+
+	defaults.codeccapopt = ast_format_cap_alloc();
+	ast_parse_allow_disallow(&defaults.codecprefopt, defaults.codeccapopt, CODEC_DEFAULT, 1);
+
+	configs.codeccapopt = ast_format_cap_alloc();
+	ast_parse_allow_disallow(&configs.codecprefopt, configs.codeccapopt, CODEC_CONFIG, 1);
+
+	ast_string_field_init(&defaults, 128);
+	ast_string_field_init(&configs, 128);
+	ast_string_field_set(&defaults, stropt, STR_DEFAULT);
+	ast_string_field_set(&configs, stropt, STR_CONFIG);
+
+	defaults.customopt = ast_true(CUSTOM_DEFAULT);
+	configs.customopt = ast_true(CUSTOM_CONFIG);
+
+
+	cfg = ao2_global_obj_ref(global_obj);
+	if (!(item = ao2_find(cfg->items, "item", OBJ_KEY))) {
+		ast_test_status_update(test, "could not look up 'item'\n");
+		return AST_TEST_FAIL;
+	}
+	if (!(item_defaults = ao2_find(cfg->items, "item_defaults", OBJ_KEY))) {
+		ast_test_status_update(test, "could not look up 'item_defaults'\n");
+		return AST_TEST_FAIL;
+	}
+	arr[0] = cfg->global;
+	arr[1] = item;
+	arr[2] = cfg->global_defaults;
+	arr[3] = item_defaults;
+	/* Test global and item against configs, global_defaults and item_defaults against defaults */
+	
+#define NOT_EQUAL_FAIL(field)  \
+	if (arr[x]->field != control->field) { \
+		ast_test_status_update(test, "%s di not match: %d != %d with x = %d\n", #field, arr[x]->field, control->field, x); \
+		res = AST_TEST_FAIL; \
+	}
+	for (x = 0; x < 4; x++) {
+		struct test_item *control = x < 2 ? &configs : &defaults;
+
+		NOT_EQUAL_FAIL(intopt);
+		NOT_EQUAL_FAIL(uintopt);
+		NOT_EQUAL_FAIL(boolopt);
+		NOT_EQUAL_FAIL(customopt);
+		if (fabs(arr[x]->doubleopt - control->doubleopt) > 0.001) {
+			ast_test_status_update(test, "doubleopt did not match: %f vs %f on loop %d\n", arr[x]->doubleopt, control->doubleopt, x);
+			res = AST_TEST_FAIL;
+		}
+		if (ast_sockaddr_cmp(&arr[x]->sockaddropt, &control->sockaddropt)) {
+			ast_test_status_update(test, "sockaddr did not match on loop %d\n", x);
+			res = AST_TEST_FAIL;
+		}
+		if (!ast_format_cap_identical(arr[x]->codeccapopt, control->codeccapopt)) {
+			char buf1[128], buf2[128];
+			ast_getformatname_multiple(buf1, sizeof(buf1), arr[x]->codeccapopt);
+			ast_getformatname_multiple(buf2, sizeof(buf2), control->codeccapopt);
+			ast_test_status_update(test, "format did not match: '%s' vs '%s' on loop %d\n", buf1, buf2, x);
+			res = AST_TEST_FAIL;
+		}
+		if (strcasecmp(arr[x]->stropt, control->stropt)) {
+			ast_test_status_update(test, "stropt did not match: '%s' vs '%s' on loop %d\n", arr[x]->stropt, control->stropt, x);
+			res = AST_TEST_FAIL;
+		}
+		if (arr[x]->aclopt != control->aclopt && (ast_apply_ha(arr[x]->aclopt, &acl_allow) != ast_apply_ha(control->aclopt, &acl_allow) ||
+				ast_apply_ha(arr[x]->aclopt, &acl_fail) != ast_apply_ha(control->aclopt, &acl_fail))) {
+			ast_test_status_update(test, "acl not match: on loop %d\n", x);
+			res = AST_TEST_FAIL;
+		}
+	}
+
+	ast_free_ha(configs.aclopt);
+	ast_format_cap_destroy(defaults.codeccapopt);
+	ast_format_cap_destroy(configs.codeccapopt);
+	ast_string_field_free_memory(&defaults);
+	ast_string_field_free_memory(&configs);
+	return res;
+}
+
 static int unload_module(void)
 {
 	AST_TEST_UNREGISTER(ast_parse_arg_test);
+	AST_TEST_UNREGISTER(config_options_test);
 	return 0;
 }
 
 static int load_module(void)
 {
 	AST_TEST_REGISTER(ast_parse_arg_test);
+	AST_TEST_REGISTER(config_options_test);
 	return AST_MODULE_LOAD_SUCCESS;
 }
 




More information about the asterisk-commits mailing list