[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