[asterisk-commits] mmichelson: branch mmichelson/rls-subscribe r417702 - /team/mmichelson/rls-su...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Mon Jun 30 20:04:37 CDT 2014


Author: mmichelson
Date: Mon Jun 30 20:04:32 2014
New Revision: 417702

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=417702
Log:
Create some unit tests for resource tree-building algorithms.

So far, it appears that resource lists are being created properly, but
the real edge case tests are still to come.


Modified:
    team/mmichelson/rls-subscribe/res/res_pjsip_pubsub.c

Modified: team/mmichelson/rls-subscribe/res/res_pjsip_pubsub.c
URL: http://svnview.digium.com/svn/asterisk/team/mmichelson/rls-subscribe/res/res_pjsip_pubsub.c?view=diff&rev=417702&r1=417701&r2=417702
==============================================================================
--- team/mmichelson/rls-subscribe/res/res_pjsip_pubsub.c (original)
+++ team/mmichelson/rls-subscribe/res/res_pjsip_pubsub.c Mon Jun 30 20:04:32 2014
@@ -662,6 +662,9 @@
 static void tree_node_destroy(struct tree_node *node)
 {
 	int i;
+	if (!node) {
+		return;
+	}
 
 	for (i = 0; i < AST_VECTOR_SIZE(&node->children); ++i) {
 		tree_node_destroy(AST_VECTOR_GET(&node->children, i));
@@ -722,7 +725,9 @@
 
 static void resource_tree_destroy(struct resource_tree *tree)
 {
-	tree_node_destroy(tree->root);
+	if (tree) {
+		tree_node_destroy(tree->root);
+	}
 }
 
 static int build_resource_tree(struct ast_sip_endpoint *endpoint, const struct ast_sip_subscription_handler *handler,
@@ -2565,6 +2570,272 @@
 	return 0;
 }
 
+#ifdef TEST_FRAMEWORK
+
+const char *bad_resources[] = {
+	"coconut",
+	"cilantro",
+	"olive",
+	"cheese",
+};
+
+static int test_new_subscribe(struct ast_sip_endpoint *endpoint, const char *resource)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_LEN(bad_resources); ++i) {
+		if (!strcmp(resource, bad_resources[i])) {
+			return 400;
+		}
+	}
+
+	return 200;
+}
+
+struct ast_sip_notifier test_notifier = {
+	.new_subscribe = test_new_subscribe,
+};
+
+struct ast_sip_subscription_handler test_handler = {
+	.notifier = &test_notifier,
+};
+
+static int fill_in_resources(struct resource_list *list, const char **resources, size_t num_resources)
+{
+	int i;
+
+	for (i = 0; i < num_resources; ++i) {
+		if (AST_VECTOR_APPEND(&list->items, resources[i])) {
+			return -1;
+		}
+	}
+	return 0;
+}
+
+static void cleanup_resource_list(struct resource_list *list)
+{
+	if (!list) {
+		return;
+	}
+
+	ast_sorcery_delete(ast_sip_get_sorcery(), list);
+	ao2_cleanup(list);
+}
+
+static struct resource_list *create_resource_list(struct ast_test *test,
+		const char *list_name, const char **resources, size_t size)
+{
+	struct resource_list *list;
+
+	list = ast_sorcery_alloc(ast_sip_get_sorcery(), "resource_list", list_name);
+	if (!list) {
+		ast_test_status_update(test, "Could not allocate resource list in sorcery\n");
+		return NULL;
+	}
+
+	if (ast_sorcery_create(ast_sip_get_sorcery(), list)) {
+		ast_test_status_update(test, "Could not store the resource list and stuff\n");
+		ao2_cleanup(list);
+		return NULL;
+	}
+
+	if (fill_in_resources(list, resources, size)) {
+		ast_test_status_update(test, "Could not add resources to the resource list\n");
+		cleanup_resource_list(list);
+		return NULL;
+	}
+
+	return list;
+}
+
+static int check_node(struct ast_test *test, struct tree_node *node,
+		const char **resources, size_t size)
+{
+	int i;
+
+	if (AST_VECTOR_SIZE(&node->children) != size) {
+		ast_test_status_update(test, "Unexpected number of resources in tree. Expected %d, got %d\n",
+				size, AST_VECTOR_SIZE(&node->children));
+		return -1;
+	}
+
+	for (i = 0; i < size; ++i) {
+		if (strcmp(resources[i], AST_VECTOR_GET(&node->children, i)->resource)) {
+			ast_test_status_update(test, "Mismatched resources\n");
+			return -1;
+		}
+	}
+
+	return 0;
+}
+
+AST_TEST_DEFINE(resource_tree)
+{
+	RAII_VAR(struct resource_list *, list, NULL, cleanup_resource_list);
+	RAII_VAR(struct resource_tree *, tree, NULL, resource_tree_destroy);
+	const char *resources[] = {
+		"huey",
+		"dewey",
+		"louie",
+	};
+	int resp;
+
+	switch (cmd) {
+	case TEST_INIT:
+		info->name = "resource_tree";
+		info->category = "/res/res_pjsip_pubsub/";
+		info->summary = "Basic resource tree integrity check";
+		info->description =
+			"Create a resource list and ensure that our attempt to build a tree works as expected.";
+		return AST_TEST_NOT_RUN;
+	case TEST_EXECUTE:
+		break;
+	}
+
+	list = create_resource_list(test, "foo", resources, ARRAY_LEN(resources));
+	if (!list) {
+		return AST_TEST_FAIL;
+	}
+
+	tree = ast_calloc(1, sizeof(*tree));
+	resp = build_resource_tree(NULL, &test_handler, "foo", tree);
+	if (resp != 200) {
+		ast_test_status_update(test, "Unexpected response %d when building resource tree\n", resp);
+		return AST_TEST_FAIL;
+	}
+
+	if (!tree->root) {
+		ast_test_status_update(test, "Resource tree has no root\n");
+		return AST_TEST_FAIL;
+	}
+
+	if (check_node(test, tree->root, resources, ARRAY_LEN(resources))) {
+		return AST_TEST_FAIL;
+	}
+
+	return AST_TEST_PASS;
+}
+
+AST_TEST_DEFINE(complex_resource_tree)
+{
+	RAII_VAR(struct resource_list *, list_1, NULL, cleanup_resource_list);
+	RAII_VAR(struct resource_list *, list_2, NULL, cleanup_resource_list);
+	RAII_VAR(struct resource_tree *, tree, NULL, resource_tree_destroy);
+	const char *resources_1[] = {
+		"huey",
+		"dewey",
+		"louie",
+		"dwarves",
+	};
+	const char *resources_2[] = {
+		"happy",
+		"grumpy",
+		"doc",
+		"bashful",
+		"dopey",
+		"sneezy",
+		"sleepy",
+	};
+	int resp;
+	struct tree_node *node;
+
+	switch (cmd) {
+	case TEST_INIT:
+		info->name = "complex_resource_tree";
+		info->category = "/res/res_pjsip_pubsub/";
+		info->summary = "Complex resource tree integrity check";
+		info->description =
+			"Create a complex resource list and ensure that our attempt to build a tree works as expected.";
+		return AST_TEST_NOT_RUN;
+	case TEST_EXECUTE:
+		break;
+	}
+	
+	list_1 = create_resource_list(test, "foo", resources_1, ARRAY_LEN(resources_1));
+	if (!list_1) {
+		return AST_TEST_FAIL;
+	}
+
+	list_2 = create_resource_list(test, "dwarves", resources_2, ARRAY_LEN(resources_2));
+	if (!list_2) {
+		return AST_TEST_FAIL;
+	}
+
+	tree = ast_calloc(1, sizeof(*tree));
+	resp = build_resource_tree(NULL, &test_handler, "foo", tree);
+	if (resp != 200) {
+		ast_test_status_update(test, "Unexpected response %d when building resource tree\n", resp);
+		return AST_TEST_FAIL;
+	}
+
+	if (!tree->root) {
+		ast_test_status_update(test, "Resource tree has no root\n");
+		return AST_TEST_FAIL;
+	}
+
+	node = tree->root;
+	if (check_node(test, node, resources_1, ARRAY_LEN(resources_1))) {
+		return AST_TEST_FAIL;
+	}
+
+	node = AST_VECTOR_GET(&node->children, 3);
+	if (check_node(test, node, resources_2, ARRAY_LEN(resources_2))) {
+		return AST_TEST_FAIL;
+	}
+
+	return AST_TEST_PASS;
+}
+
+AST_TEST_DEFINE(bad_resource)
+{
+	RAII_VAR(struct resource_list *, list, NULL, cleanup_resource_list);
+	RAII_VAR(struct resource_tree *, tree, NULL, resource_tree_destroy);
+	const char *resources[] = {
+		"huey",
+		"dewey",
+		"louie",
+		"coconut",
+	};
+	int resp;
+
+	switch (cmd) {
+	case TEST_INIT:
+		info->name = "bad_resource";
+		info->category = "/res/res_pjsip_pubsub/";
+		info->summary = "Ensure bad resources do not end up in the tree";
+		info->description =
+			"Create a resource list with a single bad resource. Ensure the bad resource does not end up in the tree.";
+		return AST_TEST_NOT_RUN;
+	case TEST_EXECUTE:
+		break;
+	}
+
+	list = create_resource_list(test, "foo", resources, ARRAY_LEN(resources));
+	if (!list) {
+		return AST_TEST_FAIL;
+	}
+
+	tree = ast_calloc(1, sizeof(*tree));
+	resp = build_resource_tree(NULL, &test_handler, "foo", tree);
+	if (resp != 200) {
+		ast_test_status_update(test, "Unexpected response %d when building resource tree\n", resp);
+		return AST_TEST_FAIL;
+	}
+
+	if (!tree->root) {
+		ast_test_status_update(test, "Resource tree has no root\n");
+		return AST_TEST_FAIL;
+	}
+
+	if (check_node(test, tree->root, resources, ARRAY_LEN(resources) - 1)) {
+		return AST_TEST_FAIL;
+	}
+
+	return AST_TEST_PASS;
+
+}
+#endif
+
 static int load_module(void)
 {
 	static const pj_str_t str_PUBLISH = { "PUBLISH", 7 };
@@ -2639,6 +2910,10 @@
 	ast_manager_register_xml("PJSIPShowResourceLists", EVENT_FLAG_SYSTEM,
 			ami_show_resource_lists);
 
+	AST_TEST_REGISTER(resource_tree);
+	AST_TEST_REGISTER(complex_resource_tree);
+	AST_TEST_REGISTER(bad_resource);
+
 	return AST_MODULE_LOAD_SUCCESS;
 }
 
@@ -2651,6 +2926,10 @@
 	if (sched) {
 		ast_sched_context_destroy(sched);
 	}
+
+	AST_TEST_UNREGISTER(resource_tree);
+	AST_TEST_UNREGISTER(complex_resource_tree);
+	AST_TEST_UNREGISTER(bad_resource);
 
 	return 0;
 }




More information about the asterisk-commits mailing list