[asterisk-commits] mjordan: testsuite/asterisk/trunk r3992 - in /asterisk/trunk/tests/bridge: ./...
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Wed Aug 7 18:38:48 CDT 2013
Author: mjordan
Date: Wed Aug 7 18:38:46 2013
New Revision: 3992
URL: http://svnview.digium.com/svn/testsuite?view=rev&rev=3992
Log:
Add a test for the Bridge AMI action
This patch adds a test for the Bridge AMI action. This covers executing Bridge
on the following:
* Two channels running in the dialplan
* One channel running in the dialplan and another in an existing bridge
* Two channels both in existing bridges
(issue AST-1186)
Added:
asterisk/trunk/tests/bridge/bridge_action/
asterisk/trunk/tests/bridge/bridge_action/bridge_action.py (with props)
asterisk/trunk/tests/bridge/bridge_action/configs/
asterisk/trunk/tests/bridge/bridge_action/configs/ast1/
asterisk/trunk/tests/bridge/bridge_action/configs/ast1/extensions.conf (with props)
asterisk/trunk/tests/bridge/bridge_action/test-config.yaml (with props)
Modified:
asterisk/trunk/tests/bridge/tests.yaml
Added: asterisk/trunk/tests/bridge/bridge_action/bridge_action.py
URL: http://svnview.digium.com/svn/testsuite/asterisk/trunk/tests/bridge/bridge_action/bridge_action.py?view=auto&rev=3992
==============================================================================
--- asterisk/trunk/tests/bridge/bridge_action/bridge_action.py (added)
+++ asterisk/trunk/tests/bridge/bridge_action/bridge_action.py Wed Aug 7 18:38:46 2013
@@ -1,0 +1,182 @@
+#!/usr/bin/env python
+'''
+Copyright (C) 2013, Digium, Inc.
+Matt Jordan <mjordan at digium.com>
+
+This program is free software, distributed under the terms of
+the GNU General Public License Version 2.
+'''
+
+import sys
+import logging
+
+LOGGER = logging.getLogger(__name__)
+
+class BridgeAction(object):
+ ''' Pluggable Module object that manipulates channels
+ using the Bridge AMI action
+ '''
+
+ def __init__(self, module_config, test_object):
+ ''' Constructor
+
+ :param module_config This object's YAML derived configuration
+ :param test_object The test object it plugs onto
+ '''
+ self.test_object = test_object
+ self.test_object.register_ami_observer(self._ami_connected_handler)
+ self.test_object.register_stop_observer(self._stop_handler)
+ self.channels = []
+ self.round = 1
+ self.ami = None
+ self.channel_state = {}
+ self.expected_events = {
+ 'channel_0_1_bridged': False,
+ 'channel_2_3_bridged': False,
+ 'channel_3_4_bridged': False,
+ 'channel_1_3_bridged': False, }
+
+ def _ami_connected_handler(self, ami):
+ ''' AMI connected handler
+
+ :param The AMI instance that just connected
+ '''
+ self.ami = ami
+ ami.registerEvent('Newexten', self._new_exten_handler)
+ ami.registerEvent('BridgeEnter', self._bridge_enter_handler)
+ ami.registerEvent('BridgeLeave', self._bridge_leave_handler)
+
+ # Originate some channels
+ LOGGER.debug('Originating channels')
+ for i in range(0, 5):
+ ami.originate(channel='Local/waiting_area at default',
+ context='default',
+ exten='waiting_area',
+ priority=1,
+ async=True).addErrback(self.test_object.handleOriginateFailure)
+
+ def _stop_handler(self, result):
+ ''' A deferred callback called as a result of the test stopping
+
+ :param result The deferred parameter passed from callback to callback
+ '''
+ failed_results = [key for key, value in self.expected_events.items()
+ if not value]
+ if len(failed_results) == 0:
+ self.test_object.set_passed(True)
+ else:
+ self.test_object.set_passed(False)
+ for failure in failed_results:
+ LOGGER.error('Expected event {%s} did not occur!' % failure)
+ return result
+
+ def _new_exten_handler(self, ami, event):
+ ''' AMI Newexten event handler
+
+ :param ami The AMI instance that the event was received from
+ :param event The AMI Newexten event
+
+ Wait until all of the ;2 Local channels are in their Echo
+ applications, then steal them and throw them into Bridges
+ '''
+ if ';2' not in event['channel']:
+ return
+ if event.get('application') != 'Echo':
+ return
+ LOGGER.debug('Tracking channel %s' % event['channel'])
+ self.channels.append(event['channel'])
+ if len(self.channels) == 5:
+ self.execute_round()
+
+ def _bridge_enter_handler(self, ami, event):
+ ''' AMI BridgeEnter event handler
+
+ :param ami The AMI instance that the event was received from
+ :param event The AMI BridgeEnter event
+ '''
+ self.channel_state[event['channel']] = event['bridgeuniqueid']
+
+ # Handle this round's logic
+ if self.round == 1:
+ if ((event['channel'] == self.channels[0] or event['channel'] == self.channels[1]) and
+ self.channel_state.get(self.channels[0]) is not None and
+ self.channel_state.get(self.channels[1]) is not None and
+ self.channel_state.get(self.channels[0]) == self.channel_state.get(self.channels[1])):
+ LOGGER.info('Channel 0 (%s) and 1 (%s) are in a bridge together' %
+ (self.channels[0], self.channels[1]))
+ self.expected_events['channel_0_1_bridged'] = True
+ if ((event['channel'] == self.channels[2] or event['channel'] == self.channels[3]) and
+ self.channel_state.get(self.channels[2]) is not None and
+ self.channel_state.get(self.channels[3]) is not None and
+ self.channel_state.get(self.channels[2]) == self.channel_state.get(self.channels[3])):
+ LOGGER.info('Channel 2 (%s) and 3 (%s) are in a bridge together' %
+ (self.channels[2], self.channels[3]))
+ self.expected_events['channel_2_3_bridged'] = True
+ if (self.expected_events['channel_0_1_bridged'] and
+ self.expected_events['channel_2_3_bridged']):
+ self.round = 2
+ self.execute_round()
+ elif self.round == 2:
+ if (self.channel_state.get(self.channels[3]) is not None and
+ self.channel_state.get(self.channels[4]) is not None and
+ self.channel_state.get(self.channels[3]) == self.channel_state.get(self.channels[4])):
+ self.expected_events['channel_3_4_bridged'] = True
+ LOGGER.info('Channel 3 (%s) and 4 (%s) are in a bridge together' %
+ (self.channels[3], self.channels[4]))
+ self.round = 3
+ self.execute_round()
+ elif self.round == 3:
+ if (self.channel_state.get(self.channels[1]) is not None and
+ self.channel_state.get(self.channels[3]) is not None and
+ self.channel_state.get(self.channels[1]) == self.channel_state.get(self.channels[3])):
+ LOGGER.info('Channel 2 (%s) and 4 (%s) are in a bridge together' %
+ (self.channels[1], self.channels[3]))
+ self.expected_events['channel_1_3_bridged'] = True
+ self.ami.hangup(self.channels[1])
+ self.test_object.stop_reactor()
+
+ def _bridge_leave_handler(self, ami, event):
+ ''' AMI BridgeLeave event handler
+
+ :param ami The AMI instance that the event was received from
+ :param event The AMI BridgeLeave event
+ '''
+ self.channel_state[event['channel']] = None
+
+ def execute_round(self):
+ ''' Execute a round of the test
+
+ This will take 4 of the Local channel halves (operating on the ;2 ends)
+ and throw them into Bridges. Once all four are in two bridges, we will
+ take channel #3 and Bridge it with channel #4. We will then take
+ channel #1 and channel #3 and Bridge them together.
+
+ (Round 1): 0 <-> 1 2 <-> 3
+ (Round 2): 0 <-> 1 3 <-> 4
+ (Round 3): 1 <-> 3
+
+ This results in:
+ * Bridges formed as a result of yanking (channels in dialplan)
+ * Bridges formed from a channel in a bridge and a channel in a dialplan
+ * Bridges formed between channels in bridges
+ '''
+ if self.round == 1:
+ for i in range(0, 4, 2):
+ LOGGER.info('Bridging Channel %d (%s) and Channel %d (%s)' %
+ (i, self.channels[i], i + 1, self.channels[i + 1]))
+ self.ami.sendMessage(message={'Action': 'Bridge',
+ 'Channel1': self.channels[i],
+ 'Channel2': self.channels[i + 1], })
+ elif self.round == 2:
+ LOGGER.info('Bridging Channel %d (%s) and Channel %d (%s)' %
+ (3, self.channels[3], 4, self.channels[4]))
+ self.ami.sendMessage(message={'Action': 'Bridge',
+ 'Channel1': self.channels[3],
+ 'Channel2': self.channels[4], })
+ elif self.round == 3:
+ LOGGER.info('Bridging Channel %d (%s) and Channel %d (%s)' %
+ (1, self.channels[3], 1, self.channels[3]))
+ self.ami.sendMessage(message={'Action': 'Bridge',
+ 'Channel1': self.channels[1],
+ 'Channel2': self.channels[3], })
+
Propchange: asterisk/trunk/tests/bridge/bridge_action/bridge_action.py
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: asterisk/trunk/tests/bridge/bridge_action/bridge_action.py
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision
Propchange: asterisk/trunk/tests/bridge/bridge_action/bridge_action.py
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: asterisk/trunk/tests/bridge/bridge_action/configs/ast1/extensions.conf
URL: http://svnview.digium.com/svn/testsuite/asterisk/trunk/tests/bridge/bridge_action/configs/ast1/extensions.conf?view=auto&rev=3992
==============================================================================
--- asterisk/trunk/tests/bridge/bridge_action/configs/ast1/extensions.conf (added)
+++ asterisk/trunk/tests/bridge/bridge_action/configs/ast1/extensions.conf Wed Aug 7 18:38:46 2013
@@ -1,0 +1,6 @@
+[default]
+
+exten => waiting_area,1,NoOp()
+ same => n,Answer()
+ same => n,Echo()
+ same => n,Hangup()
Propchange: asterisk/trunk/tests/bridge/bridge_action/configs/ast1/extensions.conf
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: asterisk/trunk/tests/bridge/bridge_action/configs/ast1/extensions.conf
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision
Propchange: asterisk/trunk/tests/bridge/bridge_action/configs/ast1/extensions.conf
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: asterisk/trunk/tests/bridge/bridge_action/test-config.yaml
URL: http://svnview.digium.com/svn/testsuite/asterisk/trunk/tests/bridge/bridge_action/test-config.yaml?view=auto&rev=3992
==============================================================================
--- asterisk/trunk/tests/bridge/bridge_action/test-config.yaml (added)
+++ asterisk/trunk/tests/bridge/bridge_action/test-config.yaml Wed Aug 7 18:38:46 2013
@@ -1,0 +1,38 @@
+testinfo:
+ summary: 'Test the Bridge AMI Action'
+ description: |
+ 'This tests the bridge AMI action in the following manner:
+ * Five Local channels are spawned, all into an Echo application
+ * Two pairs of Local channels are chosen and Bridged. This will yank those
+ channels from the Echo application.
+ * Next, one of the pairs is chosen and a channel from it is Bridged with the
+ fifth channel still in the Echo application. This will yank the channel
+ from the Echo application and move the other channel into a newly
+ created Bridge.
+ * Finally, from the remaining original pair a channel is chosen and one of
+ the channels from the second round's Bridge is chosen. These are Bridged
+ as well. This moves the channels from existing bridges into a new
+ Bridge.
+ * If all BridgeEnter events are received, the test passes.'
+
+test-modules:
+ add-test-to-search-path: 'True'
+ test-object:
+ config-section: test-object-config
+ typename: 'TestCase.TestCaseModule'
+ modules:
+ -
+ config-section: bridge-action
+ typename: 'bridge_action.BridgeAction'
+
+test-object-config:
+ asterisk-instances: 1
+ connect-ami: True
+
+bridge-action:
+
+properties:
+ minversion: '12.0.0'
+ tags:
+ - bridge
+
Propchange: asterisk/trunk/tests/bridge/bridge_action/test-config.yaml
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: asterisk/trunk/tests/bridge/bridge_action/test-config.yaml
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision
Propchange: asterisk/trunk/tests/bridge/bridge_action/test-config.yaml
------------------------------------------------------------------------------
svn:mime-type = text/plain
Modified: asterisk/trunk/tests/bridge/tests.yaml
URL: http://svnview.digium.com/svn/testsuite/asterisk/trunk/tests/bridge/tests.yaml?view=diff&rev=3992&r1=3991&r2=3992
==============================================================================
--- asterisk/trunk/tests/bridge/tests.yaml (original)
+++ asterisk/trunk/tests/bridge/tests.yaml Wed Aug 7 18:38:46 2013
@@ -15,3 +15,4 @@
- test: 'connected_line_update'
- test: 'transfer_capabilities'
- test: 'transfer_failure'
+ - test: 'bridge_action'
More information about the asterisk-commits
mailing list