[asterisk-commits] rmudgett: branch rmudgett/ao2_enhancements r371305 - /team/rmudgett/ao2_enhan...
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Wed Aug 15 17:42:21 CDT 2012
Author: rmudgett
Date: Wed Aug 15 17:42:17 2012
New Revision: 371305
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=371305
Log:
Add astobj2 duplicate object tests
Modified:
team/rmudgett/ao2_enhancements/tests/test_astobj2.c
Modified: team/rmudgett/ao2_enhancements/tests/test_astobj2.c
URL: http://svnview.digium.com/svn/asterisk/team/rmudgett/ao2_enhancements/tests/test_astobj2.c?view=diff&rev=371305&r1=371304&r2=371305
==============================================================================
--- team/rmudgett/ao2_enhancements/tests/test_astobj2.c (original)
+++ team/rmudgett/ao2_enhancements/tests/test_astobj2.c Wed Aug 15 17:42:17 2012
@@ -1160,6 +1160,76 @@
/*!
* \internal
+ * \brief Insert duplicates of number into the given container.
+ * \since 12.0
+ *
+ * \note The given container must not already have the number in it.
+ *
+ * \param container Container to insert the duplicates.
+ * \param destroy_counter What to increment when the object is destroyed.
+ * \param number Number of object to duplicate.
+ * \param prefix Test output prefix string.
+ * \param test Test output controller.
+ *
+ * \retval 0 on success.
+ * \retval -1 on error.
+ */
+static int insert_test_duplicates(struct ao2_container *container, int *destroy_counter, int number, const char *prefix, struct ast_test *test)
+{
+ int count;
+ struct test_obj *obj;
+ struct test_obj *obj_dup;
+
+ /* Check if object already exists in the container. */
+ obj = ao2_find(container, &number, OBJ_KEY);
+ if (obj) {
+ ast_test_status_update(test, "%s: Object %d already exists.\n", prefix, number);
+ ao2_t_ref(obj, -1, "test");
+ return -1;
+ }
+
+ /* Add three duplicate keyed objects. */
+ obj_dup = NULL;
+ for (count = 0; count < 4; ++count) {
+ obj = ao2_alloc(sizeof(struct test_obj), test_obj_destructor);
+ if (!obj) {
+ ast_test_status_update(test, "%s: ao2_alloc failed.\n", prefix);
+ if (obj_dup) {
+ ao2_t_ref(obj_dup, -1, "test");
+ }
+ return -1;
+ }
+ if (destroy_counter) {
+ /* This object ultimately needs to be destroyed. */
+ ++*destroy_counter;
+ }
+ obj->destructor_count = destroy_counter;
+ obj->i = number;
+ obj->dup_number = count;
+ ao2_link(container, obj);
+
+ if (count == 2) {
+ /* Duplicate this object. */
+ obj_dup = obj;
+ } else {
+ ao2_t_ref(obj, -1, "test");
+ }
+ }
+
+ /* Add the duplicate object. */
+ ao2_link(container, obj_dup);
+ ao2_t_ref(obj_dup, -1, "test");
+
+ if (ao2_container_check(container, 0)) {
+ ast_test_status_update(test, "%s: Container integrity check failed\n", prefix);
+ return -1;
+ }
+
+ return 0;
+}
+
+/*!
+ * \internal
* \brief Iterate over the container and compare the objects with the given vector.
* \since 12.0
*
@@ -1241,7 +1311,7 @@
const int *vector, int count, const char *prefix, struct ast_test *test)
{
struct ao2_iterator *mult_iter;
- struct test_obj *obj;
+ struct test_obj *obj = NULL;
int idx;
mult_iter = ao2_callback(container, flags | OBJ_MULTIPLE, cmp_fn, arg);
@@ -1265,12 +1335,79 @@
}
ao2_ref(obj, -1); /* remove ref from iterator */
}
- obj = ao2_iterator_next(mult_iter);
if (obj) {
- ast_test_status_update(test, "%s: Too many objects found. Object %d\n",
- prefix, obj->i);
+ obj = ao2_iterator_next(mult_iter);
+ if (obj) {
+ ast_test_status_update(test, "%s: Too many objects found. Object %d\n",
+ prefix, obj->i);
+ ao2_ref(obj, -1); /* remove ref from iterator */
+ res = AST_TEST_FAIL;
+ }
+ }
+ ao2_iterator_destroy(mult_iter);
+
+ return res;
+}
+
+/*!
+ * \internal
+ * \brief Run an ao2_find() for duplicates and compare the returned vector with the given vector.
+ * \since 12.0
+ *
+ * \param res Passed in enum ast_test_result_state.
+ * \param container Container to traverse.
+ * \param flags Callback flags controlling the traversal.
+ * \param number Number of object to find all duplicates.
+ * \param vector Expected vector to find.
+ * \param count Number of objects in the vector.
+ * \param prefix Test output prefix string.
+ * \param test Test output controller.
+ *
+ * \return enum ast_test_result_state
+ */
+static int test_expected_duplicates(int res, struct ao2_container *container,
+ enum search_flags flags, int number,
+ const int *vector, int count, const char *prefix, struct ast_test *test)
+{
+ struct ao2_iterator *mult_iter;
+ struct test_obj *obj = NULL;
+ int idx;
+
+ mult_iter = ao2_find(container, &number, flags | OBJ_MULTIPLE | OBJ_KEY);
+ if (!mult_iter) {
+ ast_test_status_update(test, "%s: Did not return iterator.\n", prefix);
+ return AST_TEST_FAIL;
+ }
+
+ /* Check matching objects against the given vector. */
+ for (idx = 0; idx < count; ++idx) {
+ obj = ao2_iterator_next(mult_iter);
+ if (!obj) {
+ ast_test_status_update(test, "%s: Too few objects found.\n", prefix);
+ res = AST_TEST_FAIL;
+ break;
+ }
+ if (number != obj->i) {
+ ast_test_status_update(test, "%s: Object %d != %d.\n",
+ prefix, obj->i, number);
+ res = AST_TEST_FAIL;
+ }
+ if (vector[idx] != obj->dup_number) {
+ ast_test_status_update(test, "%s: Object dup id %d != vector[%d] %d.\n",
+ prefix, obj->dup_number, idx, vector[idx]);
+ res = AST_TEST_FAIL;
+ }
ao2_ref(obj, -1); /* remove ref from iterator */
- res = AST_TEST_FAIL;
+ }
+ if (obj) {
+ obj = ao2_iterator_next(mult_iter);
+ if (obj) {
+ ast_test_status_update(test,
+ "%s: Too many objects found. Object %d, dup id %d\n",
+ prefix, obj->i, obj->dup_number);
+ ao2_ref(obj, -1); /* remove ref from iterator */
+ res = AST_TEST_FAIL;
+ }
}
ao2_iterator_destroy(mult_iter);
@@ -1493,6 +1630,7 @@
struct ao2_container *c2 = NULL;
int partial;
int destructor_count = 0;
+ int duplicate_number = 100;
/*! Container object insertion vector. */
static const int test_initial[] = {
@@ -1529,27 +1667,47 @@
7, 6, 5
};
+ /* Duplicate identifier order */
+ static const int test_dup_allow_forward[] = {
+ 0, 1, 2, 3, 2
+ };
+ static const int test_dup_allow_backward[] = {
+ 2, 3, 2, 1, 0
+ };
+ static const int test_dup_reject[] = {
+ 0
+ };
+ static const int test_dup_obj_reject_forward[] = {
+ 0, 1, 2, 3
+ };
+ static const int test_dup_obj_reject_backward[] = {
+ 3, 2, 1, 0
+ };
+ static const int test_dup_replace[] = {
+ 2
+ };
+
ast_test_status_update(test, "Test %d, %s containers.\n",
tst_num, test_container2str(type));
- /* Create container that inserts objects at the end. */
- c1 = test_make_sorted(type, 0);
+ /* Create container that inserts duplicate objects after matching objects. */
+ c1 = test_make_sorted(type, AO2_CONTAINER_ALLOC_OPT_DUPS_ALLOW);
if (!c1) {
res = AST_TEST_FAIL;
goto test_cleanup;
}
- if (insert_test_vector(c1, &destructor_count, test_initial, ARRAY_LEN(test_initial), "c1", test)) {
- res = AST_TEST_FAIL;
- goto test_cleanup;
- }
-
- /* Create container that inserts objects at the beginning. */
- c2 = test_make_sorted(type, AO2_CONTAINER_ALLOC_OPT_INSERT_BEGIN);
+ if (insert_test_vector(c1, &destructor_count, test_initial, ARRAY_LEN(test_initial), "c1(DUPS_ALLOW)", test)) {
+ res = AST_TEST_FAIL;
+ goto test_cleanup;
+ }
+
+ /* Create container that inserts duplicate objects before matching objects. */
+ c2 = test_make_sorted(type, AO2_CONTAINER_ALLOC_OPT_INSERT_BEGIN | AO2_CONTAINER_ALLOC_OPT_DUPS_ALLOW);
if (!c2) {
res = AST_TEST_FAIL;
goto test_cleanup;
}
- if (insert_test_vector(c2, &destructor_count, test_initial, ARRAY_LEN(test_initial), "c2", test)) {
+ if (insert_test_vector(c2, &destructor_count, test_initial, ARRAY_LEN(test_initial), "c2(DUPS_ALLOW)", test)) {
res = AST_TEST_FAIL;
goto test_cleanup;
}
@@ -1620,7 +1778,146 @@
break;
}
- /*! \todo BUGBUG test_traversal_sorted() remining to test duplicate handling. */
+ /* Add duplicates to initial containers that allow duplicates */
+ if (insert_test_duplicates(c1, &destructor_count, duplicate_number, "c1(DUPS_ALLOW)", test)) {
+ res = AST_TEST_FAIL;
+ goto test_cleanup;
+ }
+ if (insert_test_duplicates(c2, &destructor_count, duplicate_number, "c2(DUPS_ALLOW)", test)) {
+ res = AST_TEST_FAIL;
+ goto test_cleanup;
+ }
+
+ /* Check duplicates in containers that allow duplicates. */
+ res = test_expected_duplicates(res, c1, OBJ_ORDER_ASCENDING, duplicate_number,
+ test_dup_allow_forward, ARRAY_LEN(test_dup_allow_forward),
+ "Duplicates (ascending, DUPS_ALLOW)", test);
+ res = test_expected_duplicates(res, c1, OBJ_ORDER_DESCENDING, duplicate_number,
+ test_dup_allow_backward, ARRAY_LEN(test_dup_allow_backward),
+ "Duplicates (descending, DUPS_ALLOW)", test);
+
+ ao2_t_ref(c1, -1, "bye c1");
+ c1 = NULL;
+ ao2_t_ref(c2, -1, "bye c2");
+ c2 = NULL;
+
+ /* Create containers that reject duplicate keyed objects. */
+ c1 = test_make_sorted(type, AO2_CONTAINER_ALLOC_OPT_DUPS_REJECT);
+ if (!c1) {
+ res = AST_TEST_FAIL;
+ goto test_cleanup;
+ }
+ if (insert_test_vector(c1, &destructor_count, test_initial, ARRAY_LEN(test_initial), "c1(DUPS_REJECT)", test)) {
+ res = AST_TEST_FAIL;
+ goto test_cleanup;
+ }
+ if (insert_test_duplicates(c1, &destructor_count, duplicate_number, "c1(DUPS_REJECT)", test)) {
+ res = AST_TEST_FAIL;
+ goto test_cleanup;
+ }
+ c2 = test_make_sorted(type, AO2_CONTAINER_ALLOC_OPT_INSERT_BEGIN | AO2_CONTAINER_ALLOC_OPT_DUPS_REJECT);
+ if (!c2) {
+ res = AST_TEST_FAIL;
+ goto test_cleanup;
+ }
+ if (insert_test_vector(c2, &destructor_count, test_initial, ARRAY_LEN(test_initial), "c2(DUPS_REJECT)", test)) {
+ res = AST_TEST_FAIL;
+ goto test_cleanup;
+ }
+ if (insert_test_duplicates(c2, &destructor_count, duplicate_number, "c2(DUPS_REJECT)", test)) {
+ res = AST_TEST_FAIL;
+ goto test_cleanup;
+ }
+
+ /* Check duplicates in containers that reject duplicate keyed objects. */
+ res = test_expected_duplicates(res, c1, OBJ_ORDER_ASCENDING, duplicate_number,
+ test_dup_reject, ARRAY_LEN(test_dup_reject),
+ "Duplicates (ascending, DUPS_REJECT)", test);
+ res = test_expected_duplicates(res, c1, OBJ_ORDER_DESCENDING, duplicate_number,
+ test_dup_reject, ARRAY_LEN(test_dup_reject),
+ "Duplicates (descending, DUPS_REJECT)", test);
+
+ ao2_t_ref(c1, -1, "bye c1");
+ c1 = NULL;
+ ao2_t_ref(c2, -1, "bye c2");
+ c2 = NULL;
+
+ /* Create containers that reject duplicate objects. */
+ c1 = test_make_sorted(type, AO2_CONTAINER_ALLOC_OPT_DUPS_OBJ_REJECT);
+ if (!c1) {
+ res = AST_TEST_FAIL;
+ goto test_cleanup;
+ }
+ if (insert_test_vector(c1, &destructor_count, test_initial, ARRAY_LEN(test_initial), "c1(DUPS_OBJ_REJECT)", test)) {
+ res = AST_TEST_FAIL;
+ goto test_cleanup;
+ }
+ if (insert_test_duplicates(c1, &destructor_count, duplicate_number, "c1(DUPS_OBJ_REJECT)", test)) {
+ res = AST_TEST_FAIL;
+ goto test_cleanup;
+ }
+ c2 = test_make_sorted(type, AO2_CONTAINER_ALLOC_OPT_INSERT_BEGIN | AO2_CONTAINER_ALLOC_OPT_DUPS_OBJ_REJECT);
+ if (!c2) {
+ res = AST_TEST_FAIL;
+ goto test_cleanup;
+ }
+ if (insert_test_vector(c2, &destructor_count, test_initial, ARRAY_LEN(test_initial), "c2(DUPS_OBJ_REJECT)", test)) {
+ res = AST_TEST_FAIL;
+ goto test_cleanup;
+ }
+ if (insert_test_duplicates(c2, &destructor_count, duplicate_number, "c2(DUPS_OBJ_REJECT)", test)) {
+ res = AST_TEST_FAIL;
+ goto test_cleanup;
+ }
+
+ /* Check duplicates in containers that reject duplicate objects. */
+ res = test_expected_duplicates(res, c1, OBJ_ORDER_ASCENDING, duplicate_number,
+ test_dup_obj_reject_forward, ARRAY_LEN(test_dup_obj_reject_forward),
+ "Duplicates (ascending, DUPS_OBJ_REJECT)", test);
+ res = test_expected_duplicates(res, c1, OBJ_ORDER_DESCENDING, duplicate_number,
+ test_dup_obj_reject_backward, ARRAY_LEN(test_dup_obj_reject_backward),
+ "Duplicates (descending, DUPS_OBJ_REJECT)", test);
+
+ ao2_t_ref(c1, -1, "bye c1");
+ c1 = NULL;
+ ao2_t_ref(c2, -1, "bye c2");
+ c2 = NULL;
+
+ /* Create container that replaces duplicate keyed objects. */
+ c1 = test_make_sorted(type, AO2_CONTAINER_ALLOC_OPT_DUPS_REPLACE);
+ if (!c1) {
+ res = AST_TEST_FAIL;
+ goto test_cleanup;
+ }
+ if (insert_test_vector(c1, &destructor_count, test_initial, ARRAY_LEN(test_initial), "c1(DUPS_REJECT)", test)) {
+ res = AST_TEST_FAIL;
+ goto test_cleanup;
+ }
+ if (insert_test_duplicates(c1, &destructor_count, duplicate_number, "c1(DUPS_REJECT)", test)) {
+ res = AST_TEST_FAIL;
+ goto test_cleanup;
+ }
+ c2 = test_make_sorted(type, AO2_CONTAINER_ALLOC_OPT_INSERT_BEGIN | AO2_CONTAINER_ALLOC_OPT_DUPS_REPLACE);
+ if (!c2) {
+ res = AST_TEST_FAIL;
+ goto test_cleanup;
+ }
+ if (insert_test_vector(c2, &destructor_count, test_initial, ARRAY_LEN(test_initial), "c2(DUPS_REPLACE)", test)) {
+ res = AST_TEST_FAIL;
+ goto test_cleanup;
+ }
+ if (insert_test_duplicates(c2, &destructor_count, duplicate_number, "c2(DUPS_REPLACE)", test)) {
+ res = AST_TEST_FAIL;
+ goto test_cleanup;
+ }
+
+ /* Check duplicates in containers that replaces duplicate keyed objects. */
+ res = test_expected_duplicates(res, c1, OBJ_ORDER_ASCENDING, duplicate_number,
+ test_dup_replace, ARRAY_LEN(test_dup_replace),
+ "Duplicates (ascending, DUPS_REPLACE)", test);
+ res = test_expected_duplicates(res, c1, OBJ_ORDER_DESCENDING, duplicate_number,
+ test_dup_replace, ARRAY_LEN(test_dup_replace),
+ "Duplicates (descending, DUPS_REPLACE)", test);
test_cleanup:
/* destroy containers */
More information about the asterisk-commits
mailing list