[svn-commits] mmichelson: branch mmichelson/rls-subscribe r417727 - /team/mmichelson/rls-su...
SVN commits to the Digium repositories
svn-commits at lists.digium.com
Tue Jul 1 14:19:17 CDT 2014
Author: mmichelson
Date: Tue Jul 1 14:19:14 2014
New Revision: 417727
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=417727
Log:
Add some more unit tests.
These tests mostly test off-nominal paths, and they even
uncovered some bugs!
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=417727&r1=417726&r2=417727
==============================================================================
--- team/mmichelson/rls-subscribe/res/res_pjsip_pubsub.c (original)
+++ team/mmichelson/rls-subscribe/res/res_pjsip_pubsub.c Tue Jul 1 14:19:14 2014
@@ -640,12 +640,26 @@
char resource[0];
};
-static struct resource_list *retrieve_resource_list(const char *resource)
-{
- return ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), "resource_list", resource);
-}
-
-static struct tree_node *tree_node_alloc(const char *resource)
+static struct resource_list *retrieve_resource_list(const char *resource, const char *event)
+{
+ struct resource_list *list;
+
+ list = ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), "resource_list", resource);
+ if (!list) {
+ return NULL;
+ }
+
+ if (strcmp(list->event, event)) {
+ ast_log(LOG_WARNING, "Found resource list %s, but its event type (%s) does not match SUBSCRIBE's (%s)\n",
+ resource, list->event, event);
+ ao2_cleanup(list);
+ return NULL;
+ }
+
+ return list;
+}
+
+static struct tree_node *tree_node_alloc(const char *resource, struct resources *visited)
{
struct tree_node *node;
@@ -656,6 +670,10 @@
strcpy(node->resource, resource);
AST_VECTOR_INIT(&node->children, 4);
+
+ if (visited) {
+ AST_VECTOR_APPEND(visited, resource);
+ }
return node;
}
@@ -700,21 +718,22 @@
continue;
}
- child_list = retrieve_resource_list(resource);
+ child_list = retrieve_resource_list(resource, list->event);
if (!child_list) {
int resp = handler->notifier->new_subscribe(endpoint, resource);
if (PJSIP_IS_STATUS_IN_CLASS(resp, 200)) {
- current = tree_node_alloc(resource);
+ current = tree_node_alloc(resource, visited);
AST_VECTOR_APPEND(&parent->children, current);
}
} else {
- current = tree_node_alloc(resource);
+ current = tree_node_alloc(resource, visited);
recurse_list(endpoint, handler, child_list, current, visited);
if (AST_VECTOR_SIZE(¤t->children) > 0) {
AST_VECTOR_APPEND(&parent->children, current);
} else {
tree_node_destroy(current);
}
+ ao2_cleanup(child_list);
}
}
}
@@ -736,18 +755,17 @@
struct resource_list *list;
struct resources visited;
- list = retrieve_resource_list(resource);
-
- tree->root = tree_node_alloc(resource);
-
- /* Simple shortcut in case the requested resource is not a list */
+ list = retrieve_resource_list(resource, handler->event_name);
if (!list) {
+ tree->root = tree_node_alloc(resource, NULL);
return handler->notifier->new_subscribe(endpoint, resource);
}
AST_VECTOR_INIT(&visited, AST_VECTOR_SIZE(&list->items));
+ tree->root = tree_node_alloc(resource, &visited);
recurse_list(endpoint, handler, list, tree->root, &visited);
AST_VECTOR_FREE(&visited);
+ ao2_cleanup(list);
if (AST_VECTOR_SIZE(&tree->root->children) > 0) {
return 200;
@@ -2597,15 +2615,18 @@
};
struct ast_sip_subscription_handler test_handler = {
+ .event_name = "test",
.notifier = &test_notifier,
};
-static int fill_in_resources(struct resource_list *list, const char **resources, size_t num_resources)
+static int populate_list(struct resource_list *list, const char *event, const char **resources, size_t num_resources)
{
int i;
+ ast_copy_string(list->event, event, sizeof(list->event));
+
for (i = 0; i < num_resources; ++i) {
- if (AST_VECTOR_APPEND(&list->items, resources[i])) {
+ if (AST_VECTOR_APPEND(&list->items, ast_strdup(resources[i]))) {
return -1;
}
}
@@ -2623,7 +2644,7 @@
}
static struct resource_list *create_resource_list(struct ast_test *test,
- const char *list_name, const char **resources, size_t size)
+ const char *list_name, const char *event,const char **resources, size_t size)
{
struct resource_list *list;
@@ -2634,12 +2655,12 @@
}
if (ast_sorcery_create(ast_sip_get_sorcery(), list)) {
- ast_test_status_update(test, "Could not store the resource list and stuff\n");
+ ast_test_status_update(test, "Could not store the resource list in sorcery\n");
ao2_cleanup(list);
return NULL;
}
- if (fill_in_resources(list, resources, size)) {
+ if (populate_list(list, event, resources, size)) {
ast_test_status_update(test, "Could not add resources to the resource list\n");
cleanup_resource_list(list);
return NULL;
@@ -2692,7 +2713,7 @@
break;
}
- list = create_resource_list(test, "foo", resources, ARRAY_LEN(resources));
+ list = create_resource_list(test, "foo", "test", resources, ARRAY_LEN(resources));
if (!list) {
return AST_TEST_FAIL;
}
@@ -2751,12 +2772,12 @@
break;
}
- list_1 = create_resource_list(test, "foo", resources_1, ARRAY_LEN(resources_1));
+ list_1 = create_resource_list(test, "foo", "test", 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));
+ list_2 = create_resource_list(test, "dwarves", "test", resources_2, ARRAY_LEN(resources_2));
if (!list_2) {
return AST_TEST_FAIL;
}
@@ -2810,7 +2831,7 @@
break;
}
- list = create_resource_list(test, "foo", resources, ARRAY_LEN(resources));
+ list = create_resource_list(test, "foo", "test", resources, ARRAY_LEN(resources));
if (!list) {
return AST_TEST_FAIL;
}
@@ -2867,11 +2888,11 @@
break;
}
- list_1 = create_resource_list(test, "foo", resources_1, ARRAY_LEN(resources_1));
+ list_1 = create_resource_list(test, "foo", "test", resources_1, ARRAY_LEN(resources_1));
if (!list_1) {
return AST_TEST_FAIL;
}
- list_2 = create_resource_list(test, "gross", resources_2, ARRAY_LEN(resources_2));
+ list_2 = create_resource_list(test, "gross", "test", resources_2, ARRAY_LEN(resources_2));
if (!list_2) {
return AST_TEST_FAIL;
}
@@ -2894,6 +2915,173 @@
return AST_TEST_PASS;
+}
+
+AST_TEST_DEFINE(duplicate_resource)
+{
+ 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",
+ "ducks",
+ "dewey",
+ "louie",
+ };
+ const char *resources_2[] = {
+ "donald",
+ "daisy",
+ "scrooge",
+ "dewey",
+ "louie",
+ "huey",
+ };
+ int resp;
+ struct tree_node *node;
+
+ switch (cmd) {
+ case TEST_INIT:
+ info->name = "duplicate_resource";
+ info->category = "/res/res_pjsip_pubsub/";
+ info->summary = "Ensure duplicated resources do not end up in the tree";
+ info->description =
+ "Create a resource list with a single duplicated resource. Ensure the duplicated resource does not end up in the tree.";
+ return AST_TEST_NOT_RUN;
+ case TEST_EXECUTE:
+ break;
+ }
+
+ list_1 = create_resource_list(test, "foo", "test", resources_1, ARRAY_LEN(resources_1));
+ if (!list_1) {
+ return AST_TEST_FAIL;
+ }
+
+ list_2 = create_resource_list(test, "ducks", "test", 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;
+ /* This node should have "huey" and "ducks". "dewey" and "louie" should not
+ * be present since they were found in the "ducks" list.
+ */
+ if (check_node(test, node, resources_1, ARRAY_LEN(resources_1) - 2)) {
+ return AST_TEST_FAIL;
+ }
+
+ /* This node should have "donald", "daisy", "scrooge", "dewey", and "louie".
+ * "huey" is not here since that was already encountered in the parent list */
+ node = AST_VECTOR_GET(&node->children, 1);
+ if (check_node(test, node, resources_2, ARRAY_LEN(resources_2) - 1)) {
+ return AST_TEST_FAIL;
+ }
+
+ return AST_TEST_PASS;
+}
+
+AST_TEST_DEFINE(loop)
+{
+ 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[] = {
+ "derp",
+ };
+ const char *resources_2[] = {
+ "herp",
+ };
+ int resp;
+
+ switch (cmd) {
+ case TEST_INIT:
+ info->name = "loop";
+ info->category = "/res/res_pjsip_pubsub/";
+ info->summary = "Test that loops are properly detected.";
+ info->description =
+ "Create two resource lists that refer to each other. Ensure that attempting to build a tree\n"
+ "results in an empty tree.";
+ return AST_TEST_NOT_RUN;
+ case TEST_EXECUTE:
+ break;
+ }
+
+ list_1 = create_resource_list(test, "herp", "test", resources_1, ARRAY_LEN(resources_1));
+ if (!list_1) {
+ return AST_TEST_FAIL;
+ }
+ list_2 = create_resource_list(test, "derp", "test", 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, "herp", tree);
+ if (resp == 200) {
+ ast_test_status_update(test, "Unexpected response %d when building resource tree\n", resp);
+ return AST_TEST_FAIL;
+ }
+
+ return AST_TEST_PASS;
+}
+
+AST_TEST_DEFINE(bad_event)
+{
+ 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 = "bad_event";
+ info->category = "/res/res_pjsip_pubsub/";
+ info->summary = "Ensure that list with wrong event specified is not retrieved";
+ info->description =
+ "Create a simple resource list for event 'tsetse'. Ensure that trying to retrieve the list for event 'test' fails.";
+ return AST_TEST_NOT_RUN;
+ case TEST_EXECUTE:
+ break;
+ }
+
+ list = create_resource_list(test, "foo", "tsetse", 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 (strcmp(tree->root->resource, "foo")) {
+ ast_test_status_update(test, "Unexpected resource %s found in tree\n", tree->root->resource);
+ return AST_TEST_FAIL;
+ }
+
+ return AST_TEST_PASS;
}
#endif
@@ -2976,6 +3164,9 @@
AST_TEST_REGISTER(complex_resource_tree);
AST_TEST_REGISTER(bad_resource);
AST_TEST_REGISTER(bad_branch);
+ AST_TEST_REGISTER(duplicate_resource);
+ AST_TEST_REGISTER(loop);
+ AST_TEST_REGISTER(bad_event);
return AST_MODULE_LOAD_SUCCESS;
}
@@ -2994,6 +3185,9 @@
AST_TEST_UNREGISTER(complex_resource_tree);
AST_TEST_UNREGISTER(bad_resource);
AST_TEST_UNREGISTER(bad_branch);
+ AST_TEST_UNREGISTER(duplicate_resource);
+ AST_TEST_UNREGISTER(loop);
+ AST_TEST_UNREGISTER(bad_event);
return 0;
}
More information about the svn-commits
mailing list