[asterisk-commits] kmoore: branch kmoore/cel_transfers r393691 - /team/kmoore/cel_transfers/tests/

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Thu Jul 4 09:18:02 CDT 2013


Author: kmoore
Date: Thu Jul  4 09:18:00 2013
New Revision: 393691

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=393691
Log:
Add the ability to create up to 6 channels and add tests for merging and linking attended transfers

Modified:
    team/kmoore/cel_transfers/tests/test_cel.c

Modified: team/kmoore/cel_transfers/tests/test_cel.c
URL: http://svnview.digium.com/svn/asterisk/team/kmoore/cel_transfers/tests/test_cel.c?view=diff&rev=393691&r1=393690&r2=393691
==============================================================================
--- team/kmoore/cel_transfers/tests/test_cel.c (original)
+++ team/kmoore/cel_transfers/tests/test_cel.c Thu Jul  4 09:18:00 2013
@@ -78,6 +78,18 @@
 	} \
 	} while (0)
 
+#define APPEND_EVENT_SNAPSHOT(snapshot, ev_type, userevent, extra, peer) do { \
+	if (append_expected_event_snapshot(snapshot, ev_type, userevent, extra, peer)) { \
+		return AST_TEST_FAIL; \
+	} \
+	} while (0)
+
+#define APPEND_DUMMY_EVENT() do { \
+	if (append_dummy_event()) { \
+		return AST_TEST_FAIL; \
+	} \
+	} while (0)
+
 /*! \brief Alice's Caller ID */
 #define ALICE_CALLERID { .id.name.str = "Alice", .id.name.valid = 1, .id.number.str = "100", .id.number.valid = 1, }
 
@@ -89,6 +101,12 @@
 
 /*! \brief David's Caller ID */
 #define DAVID_CALLERID { .id.name.str = "David", .id.name.valid = 1, .id.number.str = "400", .id.number.valid = 1, }
+
+/*! \brief Eve's Caller ID */
+#define EVE_CALLERID { .id.name.str = "Eve", .id.name.valid = 1, .id.number.str = "500", .id.number.valid = 1, }
+
+/*! \brief Fred's Caller ID */
+#define FRED_CALLERID { .id.name.str = "Fred", .id.name.valid = 1, .id.number.str = "600", .id.number.valid = 1, }
 
 /*! \brief Create a \ref test_cel_chan_tech for Alice. */
 #define CREATE_ALICE_CHANNEL(channel_var, caller_id) do { \
@@ -108,9 +126,21 @@
 	APPEND_EVENT(channel_var, AST_CEL_CHANNEL_START, NULL, NULL, NULL); \
 	} while (0)
 
-/*! \brief Create a \ref test_cel_chan_tech for Charlie. */
+/*! \brief Create a \ref test_cel_chan_tech for David. */
 #define CREATE_DAVID_CHANNEL(channel_var, caller_id) do { \
 	(channel_var) = ast_channel_alloc(0, AST_STATE_DOWN, (caller_id)->id.number.str, (caller_id)->id.name.str, "400", "400", "default", NULL, 0, CHANNEL_TECH_NAME "/David"); \
+	APPEND_EVENT(channel_var, AST_CEL_CHANNEL_START, NULL, NULL, NULL); \
+	} while (0)
+
+/*! \brief Create a \ref test_cel_chan_tech for Eve. */
+#define CREATE_EVE_CHANNEL(channel_var, caller_id) do { \
+	(channel_var) = ast_channel_alloc(0, AST_STATE_DOWN, (caller_id)->id.number.str, (caller_id)->id.name.str, "500", "500", "default", NULL, 0, CHANNEL_TECH_NAME "/Eve"); \
+	APPEND_EVENT(channel_var, AST_CEL_CHANNEL_START, NULL, NULL, NULL); \
+	} while (0)
+
+/*! \brief Create a \ref test_cel_chan_tech for Eve. */
+#define CREATE_FRED_CHANNEL(channel_var, caller_id) do { \
+	(channel_var) = ast_channel_alloc(0, AST_STATE_DOWN, (caller_id)->id.number.str, (caller_id)->id.name.str, "600", "600", "default", NULL, 0, CHANNEL_TECH_NAME "/Fred"); \
 	APPEND_EVENT(channel_var, AST_CEL_CHANNEL_START, NULL, NULL, NULL); \
 	} while (0)
 
@@ -160,6 +190,14 @@
 	const char *userdefevname,
 	const char *extra, const char *peer);
 
+static int append_expected_event_snapshot(
+	struct ast_channel_snapshot *snapshot,
+	enum ast_cel_event_type type,
+	const char *userdefevname,
+	const char *extra, const char *peer);
+
+static int append_dummy_event(void);
+
 static void safe_channel_release(struct ast_channel *chan)
 {
 	if (!chan) {
@@ -1052,18 +1090,19 @@
 	return AST_TEST_PASS;
 }
 
-AST_TEST_DEFINE(test_cel_attended_transfer_bridges)
+AST_TEST_DEFINE(test_cel_attended_transfer_bridges_swap)
 {
 	RAII_VAR(struct ast_channel *, chan_alice, NULL, safe_channel_release);
 	RAII_VAR(struct ast_channel *, chan_bob, NULL, safe_channel_release);
 	RAII_VAR(struct ast_channel *, chan_charlie, NULL, safe_channel_release);
-	RAII_VAR(struct ast_channel *, chan_alice2, NULL, safe_channel_release);
+	RAII_VAR(struct ast_channel *, chan_fred, NULL, safe_channel_release);
 	RAII_VAR(struct ast_bridge *, bridge1, NULL, ao2_cleanup);
 	RAII_VAR(struct ast_bridge *, bridge2, NULL, ao2_cleanup);
 	RAII_VAR(struct ast_str *, extra, ast_str_create(32), ast_free);
 	struct ast_party_caller alice_caller = ALICE_CALLERID;
 	struct ast_party_caller bob_caller = BOB_CALLERID;
 	struct ast_party_caller charlie_caller = CHARLIE_CALLERID;
+	struct ast_party_caller fred_caller = ALICE_CALLERID;
 
 	switch (cmd) {
 	case TEST_INIT:
@@ -1100,27 +1139,27 @@
 	bridge2 = ast_bridge_basic_new();
 	ast_test_validate(test, bridge2 != NULL);
 
-	CREATE_ALICE_CHANNEL(chan_alice2, &alice_caller);
+	CREATE_FRED_CHANNEL(chan_fred, &fred_caller);
 	CREATE_CHARLIE_CHANNEL(chan_charlie, &charlie_caller);
-	ANSWER_NO_APP(chan_alice2);
+	ANSWER_NO_APP(chan_fred);
 	ANSWER_NO_APP(chan_charlie);
 
 	ast_test_validate(test, 0 == ast_bridge_impart(bridge2, chan_charlie, NULL, NULL, 0));
 	do_sleep();
 
-	ast_test_validate(test, 0 == ast_bridge_impart(bridge2, chan_alice2, NULL, NULL, 0));
-	do_sleep();
-	APPEND_EVENT(chan_charlie, AST_CEL_BRIDGE_START, NULL, NULL, ast_channel_name(chan_alice2));
+	ast_test_validate(test, 0 == ast_bridge_impart(bridge2, chan_fred, NULL, NULL, 0));
+	do_sleep();
+	APPEND_EVENT(chan_charlie, AST_CEL_BRIDGE_START, NULL, NULL, ast_channel_name(chan_fred));
 
 	/* Perform attended transfer */
 	APPEND_EVENT(chan_bob, AST_CEL_BRIDGE_END, NULL, NULL, ast_channel_name(chan_alice));
 
-	ast_bridge_transfer_attended(chan_alice, chan_alice2);
-	do_sleep();
-	APPEND_EVENT(chan_charlie, AST_CEL_BRIDGE_TO_CONF, NULL, ast_channel_name(chan_bob), ast_channel_name(chan_alice2));
-	APPEND_EVENT(chan_alice2, AST_CEL_CONF_EXIT, NULL, NULL, NULL);
-
-	ast_str_set(&extra, 0, "%s,%s,bridge:%s", bridge1->uniqueid, ast_channel_name(chan_alice2), bridge2->uniqueid);
+	ast_bridge_transfer_attended(chan_alice, chan_fred);
+	do_sleep();
+	APPEND_EVENT(chan_charlie, AST_CEL_BRIDGE_TO_CONF, NULL, ast_channel_name(chan_bob), ast_channel_name(chan_fred));
+	APPEND_EVENT(chan_fred, AST_CEL_CONF_EXIT, NULL, NULL, NULL);
+
+	ast_str_set(&extra, 0, "%s,%s,bridge:%s", bridge1->uniqueid, ast_channel_name(chan_fred), bridge2->uniqueid);
 	APPEND_EVENT(chan_alice, AST_CEL_ATTENDEDTRANSFER, NULL, ast_str_buffer(extra), NULL);
 
 
@@ -1132,8 +1171,255 @@
 	do_sleep();
 	HANGUP_CHANNEL(chan_alice, AST_CAUSE_NORMAL, "16,,");
 	HANGUP_CHANNEL(chan_bob, AST_CAUSE_NORMAL, "16,,");
-	HANGUP_CHANNEL(chan_alice2, AST_CAUSE_NORMAL, "16,,");
+	HANGUP_CHANNEL(chan_fred, AST_CAUSE_NORMAL, "16,,");
 	HANGUP_CHANNEL(chan_charlie, AST_CAUSE_NORMAL, "16,,");
+
+	return AST_TEST_PASS;
+}
+
+AST_TEST_DEFINE(test_cel_attended_transfer_bridges_merge)
+{
+	RAII_VAR(struct ast_channel *, chan_alice, NULL, safe_channel_release);
+	RAII_VAR(struct ast_channel *, chan_bob, NULL, safe_channel_release);
+	RAII_VAR(struct ast_channel *, chan_charlie, NULL, safe_channel_release);
+	RAII_VAR(struct ast_channel *, chan_david, NULL, safe_channel_release);
+	RAII_VAR(struct ast_channel *, chan_eve, NULL, safe_channel_release);
+	RAII_VAR(struct ast_channel *, chan_fred, NULL, safe_channel_release);
+	RAII_VAR(struct ast_bridge *, bridge1, NULL, ao2_cleanup);
+	RAII_VAR(struct ast_bridge *, bridge2, NULL, ao2_cleanup);
+	RAII_VAR(struct ast_channel_snapshot *, eve_tmp_snapshot, NULL, ao2_cleanup);
+	RAII_VAR(struct ast_str *, extra, ast_str_create(32), ast_free);
+	struct ast_party_caller alice_caller = ALICE_CALLERID;
+	struct ast_party_caller bob_caller = BOB_CALLERID;
+	struct ast_party_caller charlie_caller = CHARLIE_CALLERID;
+	struct ast_party_caller david_caller = DAVID_CALLERID;
+	struct ast_party_caller eve_caller = EVE_CALLERID;
+	struct ast_party_caller fred_caller = EVE_CALLERID;
+
+	switch (cmd) {
+	case TEST_INIT:
+		info->name = __func__;
+		info->category = TEST_CATEGORY;
+		info->summary = "Test attended transfers between two pairs of"
+			" bridged parties that results in a bridge merge";
+		info->description =
+			"This test creates six channels, places each triplet"
+			" in a bridge, and then attended transfers the bridges"
+			" together causing a bridge merge.\n";
+		return AST_TEST_NOT_RUN;
+	case TEST_EXECUTE:
+		break;
+	}
+	ast_test_validate(test, extra != NULL);
+
+	/* Create first set of bridged parties */
+	bridge1 = ast_bridge_basic_new();
+	ast_test_validate(test, bridge1 != NULL);
+
+	CREATE_ALICE_CHANNEL(chan_alice, &alice_caller);
+	CREATE_BOB_CHANNEL(chan_bob, &bob_caller);
+	CREATE_DAVID_CHANNEL(chan_david, &david_caller);
+	ANSWER_NO_APP(chan_alice);
+	ANSWER_NO_APP(chan_bob);
+	ANSWER_NO_APP(chan_david);
+
+	ast_test_validate(test, 0 == ast_bridge_impart(bridge1, chan_bob, NULL, NULL, 0));
+	do_sleep();
+
+	ast_test_validate(test, 0 == ast_bridge_impart(bridge1, chan_alice, NULL, NULL, 0));
+	do_sleep();
+	APPEND_EVENT(chan_bob, AST_CEL_BRIDGE_START, NULL, NULL, ast_channel_name(chan_alice));
+
+	ast_test_validate(test, 0 == ast_bridge_impart(bridge1, chan_david, NULL, NULL, 0));
+	do_sleep();
+	APPEND_EVENT(chan_bob, AST_CEL_BRIDGE_TO_CONF, NULL, ast_channel_name(chan_david), ast_channel_name(chan_alice));
+
+	/* Create second set of bridged parties */
+	bridge2 = ast_bridge_basic_new();
+	ast_test_validate(test, bridge2 != NULL);
+
+	CREATE_FRED_CHANNEL(chan_fred, &fred_caller);
+	CREATE_CHARLIE_CHANNEL(chan_charlie, &charlie_caller);
+	CREATE_EVE_CHANNEL(chan_eve, &eve_caller);
+	ANSWER_NO_APP(chan_fred);
+	ANSWER_NO_APP(chan_charlie);
+	ANSWER_NO_APP(chan_eve);
+
+	ast_test_validate(test, 0 == ast_bridge_impart(bridge2, chan_charlie, NULL, NULL, 0));
+	do_sleep();
+
+	ast_test_validate(test, 0 == ast_bridge_impart(bridge2, chan_fred, NULL, NULL, 0));
+	do_sleep();
+	APPEND_EVENT(chan_charlie, AST_CEL_BRIDGE_START, NULL, NULL, ast_channel_name(chan_fred));
+
+	ast_test_validate(test, 0 == ast_bridge_impart(bridge2, chan_eve, NULL, NULL, 0));
+	do_sleep();
+	APPEND_EVENT(chan_charlie, AST_CEL_BRIDGE_TO_CONF, NULL, ast_channel_name(chan_eve), ast_channel_name(chan_fred));
+
+	/* Perform attended transfer */
+	APPEND_EVENT(chan_charlie, AST_CEL_CONF_EXIT, NULL, NULL, NULL);
+	eve_tmp_snapshot = ast_channel_snapshot_create(chan_eve);
+	ast_bridge_transfer_attended(chan_alice, chan_fred);
+	do_sleep();
+	APPEND_EVENT(chan_charlie, AST_CEL_CONF_ENTER, NULL, NULL, NULL);
+
+	/* Fred goes away */
+	APPEND_EVENT(chan_fred, AST_CEL_CONF_EXIT, NULL, NULL, NULL);
+	APPEND_EVENT_SNAPSHOT(eve_tmp_snapshot, AST_CEL_CONF_EXIT, NULL, NULL, NULL);
+	APPEND_EVENT(chan_eve, AST_CEL_CONF_ENTER, NULL, NULL, NULL);
+
+	/* Alice goes away */
+	APPEND_EVENT(chan_alice, AST_CEL_CONF_EXIT, NULL, NULL, NULL);
+
+	ast_str_set(&extra, 0, "%s,%s,bridge:%s", bridge1->uniqueid, ast_channel_name(chan_fred), bridge2->uniqueid);
+	APPEND_EVENT(chan_alice, AST_CEL_ATTENDEDTRANSFER, NULL, ast_str_buffer(extra), NULL);
+
+
+	ast_test_validate(test, 0 == ast_bridge_depart(chan_bob));
+	APPEND_EVENT(chan_bob, AST_CEL_CONF_EXIT, NULL, NULL, NULL);
+	ast_test_validate(test, 0 == ast_bridge_depart(chan_charlie));
+	APPEND_EVENT(chan_charlie, AST_CEL_CONF_EXIT, NULL, NULL, NULL);
+	ast_test_validate(test, 0 == ast_bridge_depart(chan_david));
+	APPEND_EVENT(chan_david, AST_CEL_CONF_EXIT, NULL, NULL, NULL);
+	ast_test_validate(test, 0 == ast_bridge_depart(chan_eve));
+	APPEND_EVENT(chan_eve, AST_CEL_CONF_EXIT, NULL, NULL, NULL);
+
+	do_sleep();
+	HANGUP_CHANNEL(chan_alice, AST_CAUSE_NORMAL, "16,,");
+	HANGUP_CHANNEL(chan_bob, AST_CAUSE_NORMAL, "16,,");
+	HANGUP_CHANNEL(chan_fred, AST_CAUSE_NORMAL, "16,,");
+	HANGUP_CHANNEL(chan_charlie, AST_CAUSE_NORMAL, "16,,");
+	HANGUP_CHANNEL(chan_david, AST_CAUSE_NORMAL, "16,,");
+	HANGUP_CHANNEL(chan_eve, AST_CAUSE_NORMAL, "16,,");
+
+	return AST_TEST_PASS;
+}
+
+AST_TEST_DEFINE(test_cel_attended_transfer_bridges_link)
+{
+	RAII_VAR(struct ast_channel *, chan_alice, NULL, safe_channel_release);
+	RAII_VAR(struct ast_channel *, chan_bob, NULL, safe_channel_release);
+	RAII_VAR(struct ast_channel *, chan_charlie, NULL, safe_channel_release);
+	RAII_VAR(struct ast_channel *, chan_david, NULL, safe_channel_release);
+	RAII_VAR(struct ast_channel *, chan_eve, NULL, safe_channel_release);
+	RAII_VAR(struct ast_channel *, chan_fred, NULL, safe_channel_release);
+	RAII_VAR(struct ast_bridge *, bridge1, NULL, ao2_cleanup);
+	RAII_VAR(struct ast_bridge *, bridge2, NULL, ao2_cleanup);
+	RAII_VAR(struct ast_channel_snapshot *, eve_tmp_snapshot, NULL, ao2_cleanup);
+	RAII_VAR(struct ast_str *, extra, ast_str_create(32), ast_free);
+	struct ast_party_caller alice_caller = ALICE_CALLERID;
+	struct ast_party_caller bob_caller = BOB_CALLERID;
+	struct ast_party_caller charlie_caller = CHARLIE_CALLERID;
+	struct ast_party_caller david_caller = DAVID_CALLERID;
+	struct ast_party_caller eve_caller = EVE_CALLERID;
+	struct ast_party_caller fred_caller = EVE_CALLERID;
+
+	switch (cmd) {
+	case TEST_INIT:
+		info->name = __func__;
+		info->category = TEST_CATEGORY;
+		info->summary = "Test attended transfers between two pairs of"
+			" bridged parties that results in a bridge merge";
+		info->description =
+			"This test creates six channels, places each triplet"
+			" in a bridge, and then attended transfers the bridges"
+			" together causing a bridge merge.\n";
+		return AST_TEST_NOT_RUN;
+	case TEST_EXECUTE:
+		break;
+	}
+	ast_test_validate(test, extra != NULL);
+
+	/* Create first set of bridged parties */
+	bridge1 = ast_bridge_base_new(AST_BRIDGE_CAPABILITY_1TO1MIX | AST_BRIDGE_CAPABILITY_NATIVE | AST_BRIDGE_CAPABILITY_MULTIMIX,
+		AST_BRIDGE_FLAG_MERGE_INHIBIT_TO | AST_BRIDGE_FLAG_MERGE_INHIBIT_FROM
+		| AST_BRIDGE_FLAG_SWAP_INHIBIT_FROM | AST_BRIDGE_FLAG_TRANSFER_PROHIBITED | AST_BRIDGE_FLAG_SMART);
+	ast_test_validate(test, bridge1 != NULL);
+
+	CREATE_ALICE_CHANNEL(chan_alice, &alice_caller);
+	CREATE_BOB_CHANNEL(chan_bob, &bob_caller);
+	CREATE_DAVID_CHANNEL(chan_david, &david_caller);
+	ANSWER_NO_APP(chan_alice);
+	ANSWER_NO_APP(chan_bob);
+	ANSWER_NO_APP(chan_david);
+
+	ast_test_validate(test, 0 == ast_bridge_impart(bridge1, chan_bob, NULL, NULL, 0));
+	do_sleep();
+
+	ast_test_validate(test, 0 == ast_bridge_impart(bridge1, chan_alice, NULL, NULL, 0));
+	do_sleep();
+	APPEND_EVENT(chan_bob, AST_CEL_BRIDGE_START, NULL, NULL, ast_channel_name(chan_alice));
+
+	ast_test_validate(test, 0 == ast_bridge_impart(bridge1, chan_david, NULL, NULL, 0));
+	do_sleep();
+	APPEND_EVENT(chan_bob, AST_CEL_BRIDGE_TO_CONF, NULL, ast_channel_name(chan_david), ast_channel_name(chan_alice));
+
+	/* Create second set of bridged parties */
+	bridge2 = ast_bridge_basic_new();
+	ast_test_validate(test, bridge2 != NULL);
+
+	CREATE_FRED_CHANNEL(chan_fred, &fred_caller);
+	CREATE_CHARLIE_CHANNEL(chan_charlie, &charlie_caller);
+	CREATE_EVE_CHANNEL(chan_eve, &eve_caller);
+	ANSWER_NO_APP(chan_fred);
+	ANSWER_NO_APP(chan_charlie);
+	ANSWER_NO_APP(chan_eve);
+
+	ast_test_validate(test, 0 == ast_bridge_impart(bridge2, chan_charlie, NULL, NULL, 0));
+	do_sleep();
+
+	ast_test_validate(test, 0 == ast_bridge_impart(bridge2, chan_fred, NULL, NULL, 0));
+	do_sleep();
+	APPEND_EVENT(chan_charlie, AST_CEL_BRIDGE_START, NULL, NULL, ast_channel_name(chan_fred));
+
+	ast_test_validate(test, 0 == ast_bridge_impart(bridge2, chan_eve, NULL, NULL, 0));
+	do_sleep();
+	APPEND_EVENT(chan_charlie, AST_CEL_BRIDGE_TO_CONF, NULL, ast_channel_name(chan_eve), ast_channel_name(chan_fred));
+
+	/* Perform attended transfer */
+	ast_bridge_transfer_attended(chan_alice, chan_fred);
+	do_sleep();
+
+	/* Append dummy event for the link channel ;1 start */
+	APPEND_DUMMY_EVENT();
+
+	/* Append dummy events for the link channel ;2 start, answer */
+	APPEND_DUMMY_EVENT();
+	APPEND_DUMMY_EVENT();
+
+	ast_str_set(&extra, 0, "%s,%s,bridge:%s", bridge1->uniqueid, ast_channel_name(chan_fred), bridge2->uniqueid);
+	APPEND_EVENT(chan_alice, AST_CEL_ATTENDEDTRANSFER, NULL, ast_str_buffer(extra), NULL);
+
+	/* Append dummy event for the link channel ;1 enter */
+	APPEND_DUMMY_EVENT();
+
+	/* Append dummy event for the link channel ;2 enter and Alice's exit,
+	 * must both be dummies since they're racing */
+	APPEND_DUMMY_EVENT();
+	APPEND_DUMMY_EVENT();
+
+	/* Fred goes away */
+	APPEND_EVENT(chan_fred, AST_CEL_CONF_EXIT, NULL, NULL, NULL);
+
+	/* Append dummy event for the link channel ;1 answer */
+	APPEND_DUMMY_EVENT();
+
+	ast_test_validate(test, 0 == ast_bridge_depart(chan_bob));
+	APPEND_EVENT(chan_bob, AST_CEL_CONF_EXIT, NULL, NULL, NULL);
+	ast_test_validate(test, 0 == ast_bridge_depart(chan_charlie));
+	APPEND_EVENT(chan_charlie, AST_CEL_CONF_EXIT, NULL, NULL, NULL);
+	ast_test_validate(test, 0 == ast_bridge_depart(chan_david));
+	APPEND_EVENT(chan_david, AST_CEL_CONF_EXIT, NULL, NULL, NULL);
+	ast_test_validate(test, 0 == ast_bridge_depart(chan_eve));
+	APPEND_EVENT(chan_eve, AST_CEL_CONF_EXIT, NULL, NULL, NULL);
+
+	do_sleep();
+	HANGUP_CHANNEL(chan_alice, AST_CAUSE_NORMAL, "16,,");
+	HANGUP_CHANNEL(chan_bob, AST_CAUSE_NORMAL, "16,,");
+	HANGUP_CHANNEL(chan_fred, AST_CAUSE_NORMAL, "16,,");
+	HANGUP_CHANNEL(chan_charlie, AST_CAUSE_NORMAL, "16,,");
+	HANGUP_CHANNEL(chan_david, AST_CAUSE_NORMAL, "16,,");
+	HANGUP_CHANNEL(chan_eve, AST_CAUSE_NORMAL, "16,,");
 
 	return AST_TEST_PASS;
 }
@@ -1162,6 +1448,46 @@
 	memcpy(event_dup, event, event_len);
 
 	return event_dup;
+}
+
+static int append_event(struct ast_event *ev)
+{
+	RAII_VAR(struct ast_event *, ao2_ev, NULL, ao2_cleanup);
+	ao2_ev = ao2_dup_event(ev);
+	if (!ao2_ev) {
+		return -1;
+	}
+
+	ao2_link(cel_expected_events, ao2_ev);
+	return 0;
+}
+
+static int append_dummy_event(void)
+{
+	RAII_VAR(struct ast_event *, ev, NULL, ast_free);
+	RAII_VAR(struct ast_event *, ao2_ev, NULL, ao2_cleanup);
+
+	ev = ast_event_new(AST_EVENT_CUSTOM, AST_EVENT_IE_END);
+	if (!ev) {
+		return -1;
+	}
+
+	return append_event(ev);
+}
+
+static int append_expected_event_snapshot(
+	struct ast_channel_snapshot *snapshot,
+	enum ast_cel_event_type type,
+	const char *userdefevname,
+	const char *extra, const char *peer)
+{
+	RAII_VAR(struct ast_event *, ev, NULL, ast_free);
+	ev = ast_cel_create_event(snapshot, type, userdefevname, extra, peer);
+	if (!ev) {
+		return -1;
+	}
+
+	return append_event(ev);
 }
 
 static int append_expected_event(
@@ -1171,25 +1497,12 @@
 	const char *extra, const char *peer)
 {
 	RAII_VAR(struct ast_channel_snapshot *, snapshot, NULL, ao2_cleanup);
-	RAII_VAR(struct ast_event *, ev, NULL, ast_free);
-	RAII_VAR(struct ast_event *, ao2_ev, NULL, ao2_cleanup);
 	snapshot = ast_channel_snapshot_create(chan);
 	if (!snapshot) {
 		return -1;
 	}
 
-	ev = ast_cel_create_event(snapshot, type, userdefevname, extra, peer);
-	if (!ev) {
-		return -1;
-	}
-
-	ao2_ev = ao2_dup_event(ev);
-	if (!ao2_ev) {
-		return -1;
-	}
-
-	ao2_link(cel_expected_events, ao2_ev);
-	return 0;
+	return append_expected_event_snapshot(snapshot, type, userdefevname, extra, peer);
 }
 
 ast_mutex_t sync_lock;
@@ -1291,19 +1604,24 @@
 	return 0;
 }
 
-static int events_are_equal(struct ast_event *event1, struct ast_event *event2)
+static int events_are_equal(struct ast_event *received, struct ast_event *expected)
 {
 	struct ast_event_iterator iterator;
 	int res;
 
-	for (res = ast_event_iterator_init(&iterator, event1); !res; res = ast_event_iterator_next(&iterator)) {
+	if (ast_event_get_type(expected) == AST_EVENT_CUSTOM) {
+		/* this event is flagged as a wildcard match */
+		return 1;
+	}
+
+	for (res = ast_event_iterator_init(&iterator, received); !res; res = ast_event_iterator_next(&iterator)) {
 		/* XXX ignore sec/usec for now */
 		/* ignore EID */
 		int ie_type = ast_event_iterator_get_ie_type(&iterator);
 		if (ie_type != AST_EVENT_IE_CEL_EVENT_TIME_USEC
 			&& ie_type != AST_EVENT_IE_EID
 			&& ie_type != AST_EVENT_IE_CEL_EVENT_TIME
-			&& !match_ie_val(event1, event2, ie_type)) {
+			&& !match_ie_val(received, expected, ie_type)) {
 			ast_log(LOG_ERROR, "Failed matching on field %s\n", ast_event_get_ie_type_name(ie_type));
 			return 0;
 		}
@@ -1386,8 +1704,8 @@
 			return -1;
 		}
 		if (debug) {
-			ast_log(LOG_ERROR, "Compared events successfully\n");
-			dump_event(ex_event);
+			ast_log(LOG_ERROR, "Compared events successfully%s\n", ast_event_get_type(ex_event) == AST_EVENT_CUSTOM ? " (wildcard match)" : "");
+			dump_event(rx_event);
 		}
 		ao2_cleanup(rx_event);
 		ao2_cleanup(ex_event);
@@ -1509,7 +1827,9 @@
 	AST_TEST_UNREGISTER(test_cel_dial_answer_multiparty);
 
 	AST_TEST_UNREGISTER(test_cel_blind_transfer);
-	AST_TEST_UNREGISTER(test_cel_attended_transfer_bridges);
+	AST_TEST_UNREGISTER(test_cel_attended_transfer_bridges_swap);
+	AST_TEST_UNREGISTER(test_cel_attended_transfer_bridges_merge);
+	AST_TEST_UNREGISTER(test_cel_attended_transfer_bridges_link);
 
 	ast_channel_unregister(&test_cel_chan_tech);
 
@@ -1572,7 +1892,9 @@
 	AST_TEST_REGISTER(test_cel_dial_answer_multiparty);
 
 	AST_TEST_REGISTER(test_cel_blind_transfer);
-	AST_TEST_REGISTER(test_cel_attended_transfer_bridges);
+	AST_TEST_REGISTER(test_cel_attended_transfer_bridges_swap);
+	AST_TEST_REGISTER(test_cel_attended_transfer_bridges_merge);
+	AST_TEST_REGISTER(test_cel_attended_transfer_bridges_link);
 
 	ast_test_register_init(TEST_CATEGORY, test_cel_init_cb);
 	ast_test_register_cleanup(TEST_CATEGORY, test_cel_cleanup_cb);




More information about the asterisk-commits mailing list