Author: jbigelow Date: Fri Jan 9 11:44:59 2015 New Revision: 6220 URL: http://svnview.digium.com/svn/testsuite?view=rev&rev=6220 Log: Testsuite: Add blind transfer tests for Stasis application interaction.
This adds the remaining blind transfer tests 1.9 & 1.10 as described on the StasisStart/StasisEnd Test Plan at: https://wiki.asterisk.org/wiki/pages/viewpage.action?pageId=30279826 This additionally updates the existing test 'stasis_bridge_to_non_stasis_app' (1.8) to verify the StasisEnd events of the channels per the test plan. The two new tests use the 'call_transfer.py' module which is a modified copy of tests/channels/pjsip/transfers/blind_transfer/caller_refer_only/transfer.py for these two new tests. The module uses the pjsua python library to place calls into Asterisk and perform the blind transfer. Note: The bug ASTERISK-24649 was found during the development of the new tests and will likely cause them to fail every so often. (closes issue ASTERISK-24581) Review: https://reviewboard.asterisk.org/r/4267/ Added: asterisk/trunk/tests/rest_api/external_interaction/blind_transfer/call_transfer.py (with props) asterisk/trunk/tests/rest_api/external_interaction/blind_transfer/stasis_bridge_to_different_stasis_app/ asterisk/trunk/tests/rest_api/external_interaction/blind_transfer/stasis_bridge_to_different_stasis_app/configs/ asterisk/trunk/tests/rest_api/external_interaction/blind_transfer/stasis_bridge_to_different_stasis_app/configs/ast1/ asterisk/trunk/tests/rest_api/external_interaction/blind_transfer/stasis_bridge_to_different_stasis_app/configs/ast1/extensions.conf (with props) asterisk/trunk/tests/rest_api/external_interaction/blind_transfer/stasis_bridge_to_different_stasis_app/configs/ast1/pjsip.conf (with props) asterisk/trunk/tests/rest_api/external_interaction/blind_transfer/stasis_bridge_to_different_stasis_app/test-config.yaml (with props) asterisk/trunk/tests/rest_api/external_interaction/blind_transfer/stasis_bridge_to_same_stasis_app/ asterisk/trunk/tests/rest_api/external_interaction/blind_transfer/stasis_bridge_to_same_stasis_app/configs/ asterisk/trunk/tests/rest_api/external_interaction/blind_transfer/stasis_bridge_to_same_stasis_app/configs/ast1/ asterisk/trunk/tests/rest_api/external_interaction/blind_transfer/stasis_bridge_to_same_stasis_app/configs/ast1/extensions.conf (with props) asterisk/trunk/tests/rest_api/external_interaction/blind_transfer/stasis_bridge_to_same_stasis_app/configs/ast1/pjsip.conf (with props) asterisk/trunk/tests/rest_api/external_interaction/blind_transfer/stasis_bridge_to_same_stasis_app/test-config.yaml (with props) Modified: asterisk/trunk/tests/rest_api/external_interaction/blind_transfer/stasis_bridge_to_non_stasis_app/blind_transfer.py asterisk/trunk/tests/rest_api/external_interaction/blind_transfer/stasis_bridge_to_non_stasis_app/configs/ast1/extensions.conf asterisk/trunk/tests/rest_api/external_interaction/blind_transfer/stasis_bridge_to_non_stasis_app/test-config.yaml asterisk/trunk/tests/rest_api/external_interaction/blind_transfer/tests.yaml Added: asterisk/trunk/tests/rest_api/external_interaction/blind_transfer/call_transfer.py URL: http://svnview.digium.com/svn/testsuite/asterisk/trunk/tests/rest_api/external_interaction/blind_transfer/call_transfer.py?view=auto&rev=6220 ============================================================================== --- asterisk/trunk/tests/rest_api/external_interaction/blind_transfer/call_transfer.py (added) +++ asterisk/trunk/tests/rest_api/external_interaction/blind_transfer/call_transfer.py Fri Jan 9 11:44:59 2015 @@ -1,0 +1,222 @@ +#!/usr/bin/env python +"""Pluggable module and callback methods. + +Note: Nothing here sets a pass/fail result. + +Copyright (C) 2014, Digium, Inc. +John Bigelow <[email protected]> + +This program is free software, distributed under the terms of +the GNU General Public License Version 2. +""" + +import sys +import os +import logging +import pjsua as pj +from twisted.internet import reactor + +sys.path.append("lib/python/asterisk") +import pjsua_mod + +LOGGER = logging.getLogger(__name__) +THIS_FILE = os.path.basename(__file__) +URI = None +PJSUA_ACCOUNTS = None + + +class InitMod(object): + """Pluggable module class to override & extend pjsua_mod.PJsua YAML config + + This provides the ability to configure SIP URI's within YAML configuration + files for dialing from PJSUA accounts. It also overrides the + callback_module & callback_method YAML config options pointing them to this + module and the 'pjsua_initialized' method for when all endpoints have + registered. + """ + + def __init__(self, instance_config, test_object): + """Constructor""" + global URI + instance_config['callback_module'] = os.path.splitext(THIS_FILE)[0] + instance_config['callback_method'] = 'pjsua_initialized' + pjsua_mod.PJsua(instance_config, test_object) + self.test_object = test_object + self.config = instance_config + URI = {} + for account in self.config['accounts']: + if 'call_uri' not in account and 'transfer_uri' not in account: + continue + URI[account['name']] = {} + if account.get('call_uri') is not None: + URI[account['name']]['call_uri'] = account.get('call_uri') + if account.get('transfer_uri') is not None: + URI[account['name']]['transfer_uri'] = \ + account.get('transfer_uri') + LOGGER.info("Pluggable module initialized.") + + +class AlicePhoneCallCallback(pj.CallCallback): + """Derived callback class for Alice's call.""" + + def __init__(self, call=None): + pj.CallCallback.__init__(self, call) + + def on_state(self): + """Callback for call state changes.""" + log_call_info(self.call.info()) + if self.call.info().state == pj.CallState.CONFIRMED: + LOGGER.info("Call is up: '%s'" % self.call) + if self.call.info().state == pj.CallState.DISCONNECTED: + LOGGER.info("Call disconnected: '%s'" % self.call) + + def transfer_call(self): + """Transfer the call.""" + try: + LOGGER.info("'%s' is blind transfering the call to '%s'." % + (self.call.info().uri, URI['alice']['transfer_uri'])) + self.call.transfer(URI['alice']['transfer_uri']) + except: + LOGGER.warn("Failed to transfer the call! Retrying...") + reactor.callLater(.2, self.transfer_call) + + def on_transfer_status(self, code, reason, final, cont): + """Callback for the status of a previous call transfer request.""" + log_call_info(self.call.info()) + if code == 200 and reason == "OK" and final == 1 and cont == 0: + LOGGER.info("Transfer target answered the call.") + LOGGER.debug("Call uri: '%s'; remote uri: '%s'" % + (self.call.info().uri, + self.call.info().remote_uri)) + LOGGER.info("Hanging up Alice") + self.call.hangup(code=200, reason="Q.850;cause=16") + return cont + + +class BobPhoneCallCallback(pj.CallCallback): + """Derived callback class for Bob's call.""" + + def __init__(self, call=None): + pj.CallCallback.__init__(self, call) + + def on_state(self): + """Callback for call state changes.""" + log_call_info(self.call.info()) + if self.call.info().state == pj.CallState.DISCONNECTED: + LOGGER.info("Call disconnected: '%s'" % self.call) + if self.call.info().state == pj.CallState.DISCONNECTED: + LOGGER.info("Call disconnected: '%s'" % self.call) + + def hangup_call(self): + """Hang up the call.""" + LOGGER.info("Hanging up Bob") + self.call.hangup(code=200, reason="Q.850;cause=16") + + +class AMICallback(object): + """Class to register AMI events and callbacks.""" + + def __init__(self, test_object): + self.test_object = test_object + self.ami = self.test_object.ami[0] + self.ami.registerEvent('Hangup', self.hangup_event_handler) + self.ami.registerEvent('BridgeEnter', self.bridge_enter_handler) + self.ami.registerEvent('BridgeLeave', self.bridge_leave_handler) + self.alice_in_bridge = False + self.bob_in_bridge = False + self.alice_phone_call = None + self.bob_phone_call = None + + def bridge_enter_handler(self, ami, event): + """AMI bridge enter event callback.""" + channel = event.get('channel') + if 'bob' in channel: + self.bob_in_bridge = True + elif 'alice' in channel: + self.alice_in_bridge = True + if self.bob_in_bridge and self.alice_in_bridge: + # Prevent multiple transfers if other channels join + if 'alice' not in channel and 'bob' not in channel: + return + LOGGER.info('Both Alice and Bob are in bridge; starting transfer') + self.alice_phone_call.transfer_call() + + def bridge_leave_handler(self, ami, event): + """AMI bridge leave event callback.""" + channel = event.get('channel') + if 'bob' in channel: + self.bob_in_bridge = False + elif 'alice' in channel: + self.alice_in_bridge = False + + def hangup_event_handler(self, ami, event): + """AMI hang up event callback.""" + LOGGER.debug("Hangup detected for channel '%s'" % event['channel']) + + +def make_call(obj, acc, uri): + """Place a call. + + Keyword Arguments: + obj AMICallback object + acc The pjsua_mod.PJsuaAccount object to make the call from + uri String of SIP URI to dial + """ + try: + if 'alice' in acc._obj_name: + LOGGER.info("Alice is calling '%s'" % uri) + obj.alice_phone_call = AlicePhoneCallCallback() + acc.make_call(uri, cb=obj.alice_phone_call) + elif 'bob' in acc._obj_name: + LOGGER.info("Bob is calling '%s'" % uri) + obj.bob_phone_call = BobPhoneCallCallback() + acc.make_call(uri, cb=obj.bob_phone_call) + except pj.Error, err: + LOGGER.error("Exception: %s" % str(err)) + +def log_call_info(call_info): + """Log call info.""" + LOGGER.debug("Call '%s' <-> '%s'" % (call_info.uri, call_info.remote_uri)) + LOGGER.debug("Call state: '%s'; last code: '%s'; last reason: '%s'" % + (call_info.state_text, + call_info.last_code, + call_info.last_reason)) + +def exec_pjsua(test_object, triggered_by, ari, events): + """Callback method upon ARI event trigger. + + Keyword Arguments: + test_object The test object + triggered_by Object that triggered a call to this method + ari Object of ari.ARI + events Dictionary containing ARI event that triggered this callback + """ + LOGGER.info("Executing PJSUA.") + alice = PJSUA_ACCOUNTS.get('alice') + bob = PJSUA_ACCOUNTS.get('bob') + obj = AMICallback(test_object) + if URI['alice'].get('call_uri'): + lock = alice.pj_lib.auto_lock() + make_call(obj, alice.account, URI['alice']['call_uri']) + del lock + if URI['bob'].get('call_uri'): + lock = bob.pj_lib.auto_lock() + make_call(obj, bob.account, URI['bob']['call_uri']) + del lock + + return True + +def pjsua_initialized(test_object, accounts): + """Callback method upon all PJSUA endpoints being registered. + + Keyword Arguments: + test_object The test object + accounts Dictionary of PJSUA account names and pjsua_mod.PJsuaAccount + objects + """ + global PJSUA_ACCOUNTS + PJSUA_ACCOUNTS = accounts + LOGGER.info("PJSUA Initialized.") + + +# vim:sw=4:ts=4:expandtab:textwidth=79 Propchange: asterisk/trunk/tests/rest_api/external_interaction/blind_transfer/call_transfer.py ------------------------------------------------------------------------------ svn:eol-style = native Propchange: asterisk/trunk/tests/rest_api/external_interaction/blind_transfer/call_transfer.py ------------------------------------------------------------------------------ svn:executable = * Propchange: asterisk/trunk/tests/rest_api/external_interaction/blind_transfer/call_transfer.py ------------------------------------------------------------------------------ svn:keywords = Author Date Id Revision Propchange: asterisk/trunk/tests/rest_api/external_interaction/blind_transfer/call_transfer.py ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: asterisk/trunk/tests/rest_api/external_interaction/blind_transfer/stasis_bridge_to_different_stasis_app/configs/ast1/extensions.conf URL: http://svnview.digium.com/svn/testsuite/asterisk/trunk/tests/rest_api/external_interaction/blind_transfer/stasis_bridge_to_different_stasis_app/configs/ast1/extensions.conf?view=auto&rev=6220 ============================================================================== --- asterisk/trunk/tests/rest_api/external_interaction/blind_transfer/stasis_bridge_to_different_stasis_app/configs/ast1/extensions.conf (added) +++ asterisk/trunk/tests/rest_api/external_interaction/blind_transfer/stasis_bridge_to_different_stasis_app/configs/ast1/extensions.conf Fri Jan 9 11:44:59 2015 @@ -1,0 +1,16 @@ +[default] + +exten => s,1,NoOp() + same => n,Answer() + same => n,Stasis(testsuite) + same => n,Hangup() + +exten => 1000,1,Answer + same => n,Stasis(otherapp) + same => n,Hangup + +exten => stasis,1,NoOp() + same => n,Answer() + same => n,Stasis(testsuite,test) + same => n,Hangup + Propchange: asterisk/trunk/tests/rest_api/external_interaction/blind_transfer/stasis_bridge_to_different_stasis_app/configs/ast1/extensions.conf ------------------------------------------------------------------------------ svn:eol-style = native Propchange: asterisk/trunk/tests/rest_api/external_interaction/blind_transfer/stasis_bridge_to_different_stasis_app/configs/ast1/extensions.conf ------------------------------------------------------------------------------ svn:keywords = Author Date Id Revision Propchange: asterisk/trunk/tests/rest_api/external_interaction/blind_transfer/stasis_bridge_to_different_stasis_app/configs/ast1/extensions.conf ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: asterisk/trunk/tests/rest_api/external_interaction/blind_transfer/stasis_bridge_to_different_stasis_app/configs/ast1/pjsip.conf URL: http://svnview.digium.com/svn/testsuite/asterisk/trunk/tests/rest_api/external_interaction/blind_transfer/stasis_bridge_to_different_stasis_app/configs/ast1/pjsip.conf?view=auto&rev=6220 ============================================================================== --- asterisk/trunk/tests/rest_api/external_interaction/blind_transfer/stasis_bridge_to_different_stasis_app/configs/ast1/pjsip.conf (added) +++ asterisk/trunk/tests/rest_api/external_interaction/blind_transfer/stasis_bridge_to_different_stasis_app/configs/ast1/pjsip.conf Fri Jan 9 11:44:59 2015 @@ -1,0 +1,40 @@ +[global] +type=global +debug=no + +[system] +type=system + +[local] +type=transport +protocol=udp +bind=127.0.0.1:5060 + +[alice] +type=endpoint +context=default +disallow=all +allow=ulaw +direct_media=no +media_address=127.0.0.1 +aors=alice + +[alice] +type=aor +max_contacts=1 +contact=sip:[email protected]:5060\;transport=udp + +[bob] +type=endpoint +context=default +disallow=all +allow=ulaw +direct_media=no +media_address=127.0.0.1 +aors=bob + +[bob] +type=aor +max_contacts=1 +contact=sip:[email protected]:5060\;transport=udp + Propchange: asterisk/trunk/tests/rest_api/external_interaction/blind_transfer/stasis_bridge_to_different_stasis_app/configs/ast1/pjsip.conf ------------------------------------------------------------------------------ svn:eol-style = native Propchange: asterisk/trunk/tests/rest_api/external_interaction/blind_transfer/stasis_bridge_to_different_stasis_app/configs/ast1/pjsip.conf ------------------------------------------------------------------------------ svn:keywords = Author Date Id Revision Propchange: asterisk/trunk/tests/rest_api/external_interaction/blind_transfer/stasis_bridge_to_different_stasis_app/configs/ast1/pjsip.conf ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: asterisk/trunk/tests/rest_api/external_interaction/blind_transfer/stasis_bridge_to_different_stasis_app/test-config.yaml URL: http://svnview.digium.com/svn/testsuite/asterisk/trunk/tests/rest_api/external_interaction/blind_transfer/stasis_bridge_to_different_stasis_app/test-config.yaml?view=auto&rev=6220 ============================================================================== --- asterisk/trunk/tests/rest_api/external_interaction/blind_transfer/stasis_bridge_to_different_stasis_app/test-config.yaml (added) +++ asterisk/trunk/tests/rest_api/external_interaction/blind_transfer/stasis_bridge_to_different_stasis_app/test-config.yaml Fri Jan 9 11:44:59 2015 @@ -1,0 +1,234 @@ +testinfo: + summary: | + "Verify StasisStart and StasisEnd events when a channel in a Stasis + bridge is blind transfered to a different Stasis application." + description: | + "Upon the kick off local channel entering into the Stasis(testsuite) + app, a Stasis bridge is created and two calls are placed using PJSUA + accounts ('alice' & 'bob') with both dialing into the + Stasis(testsuite,test) app. The alice & bob channels are placed into + the Stasis bridge. + + Alice blind transfers bob to the Stasis(otherapp) application via + dial plan extension 1000. The local channel half replacing Alice's + channel is added to the bridge with Bob. The other local channel half + executes the Stasis(otherapp) application and is not added to a + bridge. The StasisStart events for all channels along with the + StasisEnd event for Alice's channel are verified by this point in time + + A StasisEnd event for Alice's channel triggers an AMI hangup of Bob's + channel. A StasisEnd event for Bob's channel then triggers an AMI + hangup of the local channels halves used for the transfer, the local + channel halves for kicking off the test, and destruction of the bridge. + The StasisEnd events are verified for Bob's channel and the local + channel halves used for the transfer." + +test-modules: + add-test-to-search-path: True + add-relative-to-search-path: ['..'] + test-object: + config-section: test-object-config + typename: 'ari.AriTestObject' + modules: + - + config-section: 'pjsua-config' + typename: 'call_transfer.InitMod' + - + config-section: pluggable-config + typename: 'pluggable_modules.EventActionModule' + +test-object-config: + apps: testsuite,otherapp + +pjsua-config: + transports: + - + name: 'local-ipv4-1' + bind: '127.0.0.1' + bindport: '5061' + - + name: 'local-ipv4-2' + bind: '127.0.0.1' + bindport: '5062' + accounts: + - + name: 'alice' + username: 'alice' + domain: '127.0.0.1' + transport: 'local-ipv4-1' + call_uri: 'sip:[email protected]' + transfer_uri: 'sip:[email protected]' + - + name: 'bob' + username: 'bob' + domain: '127.0.0.1' + transport: 'local-ipv4-2' + call_uri: 'sip:[email protected]' + +pluggable-config: + # Upon kickoff channel entering Stasis app: create a bridge, don't add + # kickoff channel to bridge, initiate SIPp calls. + - + ari-events: + match: + type: StasisStart + application: testsuite + args: [] + channel: + name: 'Local/s@default-.*' + count: 1 + ari-requests: + method: 'post' + uri: 'bridges/test_bridge' + callback: + module: call_transfer + method: exec_pjsua + # Upon alice & bob entering Stasis app: add the channels to the bridge. + - + ari-events: + match: + type: StasisStart + application: testsuite + args: ['test'] + channel: + name: 'PJSIP/(alice|bob)-.*' + count: 2 + ari-requests: + method: 'post' + uri: 'bridges/test_bridge/addChannel' + params: + channel: '{channel.id}' + # Ensure the blind transfer is occurring how it should. + - + ari-events: + match: + type: BridgeBlindTransfer + application: testsuite + channel: + name: 'PJSIP/alice-.*' + transferee: + name: 'PJSIP/bob-.*' + replace_channel: + name: "Local/1000@default-.*" + result: 'Success' + count: 1 + # Ensure the local channel half for the transfer that is not replacing + # Alice's channel enters the Stasis(otherapp) application. + - + ari-events: + match: + type: StasisStart + application: otherapp + args: [] + channel: + name: 'Local/1000@default-.*' + count: 1 + # Ensure the local channel half for the transfer that is replacing Alice's + # channel enters the Stasis(testsuite,test) application and then add it to + # the bridge. + - + ari-events: + match: + type: StasisStart + application: testsuite + args: [] + channel: + name: 'Local/1000@default-.*' + replace_channel: + name: 'PJSIP/alice-.*' + count: 1 + ari-requests: + method: 'post' + uri: 'bridges/test_bridge/addChannel' + params: + channel: '{channel.id}' + # Ensure the local channel half entering the bridge is the one that + # replaced alice's channel. + - + ari-events: + match: + type: ChannelEnteredBridge + application: testsuite + channel: + name: 'Local/1000@default-.*' + state: 'Up' + connected: + number: 'bob' + count: 1 + # Ensure the alice channel exits the Stasis app. + - + ari-events: + match: + type: StasisEnd + application: testsuite + channel: + name: 'PJSIP/alice-.*' + count: 1 + ami-actions: + action: + action: 'Hangup' + channel: '/^PJSIP/bob-.*$/' + # Upon bob hanging up: Ensure the bob channel exits the Stasis app, hang up + # both local channel halves used for the transfer. + - + ari-events: + match: + type: StasisEnd + application: testsuite + channel: + name: 'PJSIP/bob-.*' + count: 1 + ami-actions: + action: + action: 'Hangup' + channel: '/^Local/1000@default-.*$/' + # Ensure the non-bridged local channel half used for the transfer exits + # the Stasis(otherapp) app. + - + ari-events: + match: + type: StasisEnd + application: otherapp + channel: + name: 'Local/1000@default-.*' + nomatch: + channel: + connected: + number: 'bob' + count: 1 + # Ensure the bridged local channel half used for the transfer exits the + # Stasis app. Additionally hang up the kickoff local channel halves and + # destroy the bridge. + - + ari-events: + match: + type: StasisEnd + application: testsuite + channel: + name: 'Local/1000@default-.*' + connected: + number: 'bob' + count: 1 + ami-actions: + action: + action: 'Hangup' + channel: '/^Local/s@default-.*;1$/' + ari-requests: + method: 'delete' + uri: 'bridges/test_bridge' + +properties: + minversion: '12.8.0' + dependencies: + - python : autobahn.websocket + - python : requests + - python : twisted + - python : starpy + - python : pjsua + - asterisk : app_stasis + - asterisk : res_ari_channels + - asterisk : res_ari_bridges + - asterisk : res_pjsip + tags: + - ARI + - pjsip Propchange: asterisk/trunk/tests/rest_api/external_interaction/blind_transfer/stasis_bridge_to_different_stasis_app/test-config.yaml ------------------------------------------------------------------------------ svn:eol-style = native Propchange: asterisk/trunk/tests/rest_api/external_interaction/blind_transfer/stasis_bridge_to_different_stasis_app/test-config.yaml ------------------------------------------------------------------------------ svn:keywords = Author Date Id Revision Propchange: asterisk/trunk/tests/rest_api/external_interaction/blind_transfer/stasis_bridge_to_different_stasis_app/test-config.yaml ------------------------------------------------------------------------------ svn:mime-type = text/plain Modified: asterisk/trunk/tests/rest_api/external_interaction/blind_transfer/stasis_bridge_to_non_stasis_app/blind_transfer.py URL: http://svnview.digium.com/svn/testsuite/asterisk/trunk/tests/rest_api/external_interaction/blind_transfer/stasis_bridge_to_non_stasis_app/blind_transfer.py?view=diff&rev=6220&r1=6219&r2=6220 ============================================================================== --- asterisk/trunk/tests/rest_api/external_interaction/blind_transfer/stasis_bridge_to_non_stasis_app/blind_transfer.py (original) +++ asterisk/trunk/tests/rest_api/external_interaction/blind_transfer/stasis_bridge_to_non_stasis_app/blind_transfer.py Fri Jan 9 11:44:59 2015 @@ -55,22 +55,29 @@ return True def on_replace_channel_enter(ari, event, test_object): - ari.delete('channels', event['channel']['id']) + ari.delete('channels', TEST.originated_id) + ari.delete('bridges', TEST.bridge_id) return True def on_blind_transfer(ari, event, test_object): LOGGER.debug("on_blind_transfer(%r)" % event) - ari.delete('bridges', TEST.bridge_id) - ari.delete('channels', TEST.originated_id) if event.get('result') != 'Success': LOGGER.error('Blind transfer failed: %s' % event.get('result')) return False + # Transferer if not event['channel']['name'].startswith('PJSIP/bob-'): + return False + # Transferee + elif event['transferee']['id'] != TEST.originated_id: + return False + # Channel replacing the transferer's channel + elif not event['replace_channel']['name'].startswith('Local/1000@default-'): return False elif event['bridge']['id'] != TEST.bridge_id: return False return True + Modified: asterisk/trunk/tests/rest_api/external_interaction/blind_transfer/stasis_bridge_to_non_stasis_app/configs/ast1/extensions.conf URL: http://svnview.digium.com/svn/testsuite/asterisk/trunk/tests/rest_api/external_interaction/blind_transfer/stasis_bridge_to_non_stasis_app/configs/ast1/extensions.conf?view=diff&rev=6220&r1=6219&r2=6220 ============================================================================== --- asterisk/trunk/tests/rest_api/external_interaction/blind_transfer/stasis_bridge_to_non_stasis_app/configs/ast1/extensions.conf (original) +++ asterisk/trunk/tests/rest_api/external_interaction/blind_transfer/stasis_bridge_to_non_stasis_app/configs/ast1/extensions.conf Fri Jan 9 11:44:59 2015 @@ -12,3 +12,8 @@ exten => stasis,1,NoOp() same => n,Answer() same => n,Stasis(testsuite,test) + +exten => dummy,1,Answer + same => n,Stasis(testsuite,dummy) + same => n,Hangup + Modified: asterisk/trunk/tests/rest_api/external_interaction/blind_transfer/stasis_bridge_to_non_stasis_app/test-config.yaml URL: http://svnview.digium.com/svn/testsuite/asterisk/trunk/tests/rest_api/external_interaction/blind_transfer/stasis_bridge_to_non_stasis_app/test-config.yaml?view=diff&rev=6220&r1=6219&r2=6220 ============================================================================== --- asterisk/trunk/tests/rest_api/external_interaction/blind_transfer/stasis_bridge_to_non_stasis_app/test-config.yaml (original) +++ asterisk/trunk/tests/rest_api/external_interaction/blind_transfer/stasis_bridge_to_non_stasis_app/test-config.yaml Fri Jan 9 11:44:59 2015 @@ -1,26 +1,70 @@ testinfo: - summary: Test originating calls to a Stasis application using ARI and then blind transferring. + summary: | + "Verify StasisStart and StasisEnd events when channels are put into a + Stasis application, bridged, and one channel is blind transferred to + a non-stasis application." description: | - Originate two external SIP calls into Stasis and then have one blind transfer the other. + "A dummy local channel is created with half the channel placed into the + Stasis(testsuite,dummy) application and the other half placed into the + Echo() application. This sole purpose of this dummy channel is to have + a channel up preventing the test from immediately ending and thus + keeping the websocket connected, to allow StasisEnd events for all + other channels to be verified. + + The kick off local channel ('Alice') is entered into the + Stasis(testsuite) app and a Stasis bridge is created. A SIP channel + ('Bob') is then entered into the Stasis(testsuite,test) app and added + to the bridge with alice. Bob blind transfers Alice to the Echo() app + via extension 1000. The local channel half replacing Bob's is added to + the bridge with Alice. The other local channel half executes the Echo() + app. The StasisStart events for all channels (except the dummy halves) + are verified. + + Upon the local channel half entering the bridge replacing Bob's + channel, the channel and Alice's channel are hung up. The bridge is + then also destroyed. Once all StasisEnd events have been verified, + the dummy channel halves are hung up thus ending the test." test-modules: add-test-to-search-path: True test-object: - typename: ari.AriTestObject + config-section: test-object-config + typename: ari.AriOriginateTestObject modules: - config-section: ari-config typename: ari.WebSocketEventModule +test-object-config: + apps: testsuite + test-iterations: + - [ { channelId: 'dummy', + endpoint: 'Local/dummy@default', + context: 'default', + extension: '1000', + priority: '1' }, + { channelId: 'alice', + endpoint: 'Local/s@default', + context: 'default', + extension: '1000', + priority: '1' } ] + ari-config: - apps: testsuite events: + - conditions: + match: + type: StasisStart + application: testsuite + args: ['dummy'] + channel: + id: 'dummy;2' + count: 1 - conditions: match: type: StasisStart application: testsuite args: [] channel: - name: 'Local/s@default-00000000;2' + id: 'alice;2' count: 1 callback: module: blind_transfer @@ -29,21 +73,19 @@ match: type: StasisStart application: testsuite - args: [] + args: ['test'] channel: - name: 'Local/1000@default-00000001;1' - replace_channel: name: 'PJSIP/bob-0000000.' - count: 1 - - conditions: - match: - type: StasisStart - application: testsuite - args: ['test'] count: 1 callback: module: blind_transfer method: on_test_start + - conditions: + match: + type: ChannelEnteredBridge + channel: + id: 'alice;2' + count: 1 - conditions: match: type: ChannelEnteredBridge @@ -55,19 +97,14 @@ method: on_channel_entered_bridge - conditions: match: - type: ChannelEnteredBridge + type: StasisStart + application: testsuite + args: [] channel: - name: 'Local/s@default-00000000;2' + name: 'Local/1000@default-0000000.;1' + replace_channel: + name: 'PJSIP/bob-0000000.' count: 1 - - conditions: - match: - type: ChannelEnteredBridge - channel: - name: 'Local/1000@default-.*' - count: 1 - callback: - module: blind_transfer - method: on_replace_channel_enter - conditions: match: type: BridgeBlindTransfer @@ -76,6 +113,40 @@ callback: module: blind_transfer method: on_blind_transfer + - conditions: + match: + type: ChannelEnteredBridge + channel: + name: 'Local/1000@default-0000000.;1' + count: 1 + callback: + module: blind_transfer + method: on_replace_channel_enter + - conditions: + match: + type: StasisEnd + application: testsuite + channel: + name: 'PJSIP/bob-0000000.' + count: 1 + - conditions: + match: + type: StasisEnd + application: testsuite + channel: + id: 'alice;2' + count: 1 + - conditions: + match: + type: StasisEnd + application: testsuite + channel: + name: 'Local/1000@default-0000000.;1' + count: 1 + requests: + - + method: 'delete' + uri: 'channels/dummy;2' properties: minversion: '12.8.0' @@ -84,7 +155,11 @@ - python : requests - python : twisted - python : starpy + - app : pjsua + - asterisk : app_stasis + - asterisk : app_echo - asterisk : res_ari_channels - - asterisk : app_echo + - asterisk : res_ari_bridges + - asterisk : res_pjsip tags: - ARI Added: asterisk/trunk/tests/rest_api/external_interaction/blind_transfer/stasis_bridge_to_same_stasis_app/configs/ast1/extensions.conf URL: http://svnview.digium.com/svn/testsuite/asterisk/trunk/tests/rest_api/external_interaction/blind_transfer/stasis_bridge_to_same_stasis_app/configs/ast1/extensions.conf?view=auto&rev=6220 ============================================================================== --- asterisk/trunk/tests/rest_api/external_interaction/blind_transfer/stasis_bridge_to_same_stasis_app/configs/ast1/extensions.conf (added) +++ asterisk/trunk/tests/rest_api/external_interaction/blind_transfer/stasis_bridge_to_same_stasis_app/configs/ast1/extensions.conf Fri Jan 9 11:44:59 2015 @@ -1,0 +1,16 @@ +[default] + +exten => s,1,NoOp() + same => n,Answer() + same => n,Stasis(testsuite) + same => n,Hangup() + +exten => 1000,1,Answer + same => n,Stasis(testsuite,transferee) + same => n,Hangup + +exten => stasis,1,NoOp() + same => n,Answer() + same => n,Stasis(testsuite,test) + same => n,Hangup + Propchange: asterisk/trunk/tests/rest_api/external_interaction/blind_transfer/stasis_bridge_to_same_stasis_app/configs/ast1/extensions.conf ------------------------------------------------------------------------------ svn:eol-style = native Propchange: asterisk/trunk/tests/rest_api/external_interaction/blind_transfer/stasis_bridge_to_same_stasis_app/configs/ast1/extensions.conf ------------------------------------------------------------------------------ svn:keywords = Author Date Id Revision Propchange: asterisk/trunk/tests/rest_api/external_interaction/blind_transfer/stasis_bridge_to_same_stasis_app/configs/ast1/extensions.conf ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: asterisk/trunk/tests/rest_api/external_interaction/blind_transfer/stasis_bridge_to_same_stasis_app/configs/ast1/pjsip.conf URL: http://svnview.digium.com/svn/testsuite/asterisk/trunk/tests/rest_api/external_interaction/blind_transfer/stasis_bridge_to_same_stasis_app/configs/ast1/pjsip.conf?view=auto&rev=6220 ============================================================================== --- asterisk/trunk/tests/rest_api/external_interaction/blind_transfer/stasis_bridge_to_same_stasis_app/configs/ast1/pjsip.conf (added) +++ asterisk/trunk/tests/rest_api/external_interaction/blind_transfer/stasis_bridge_to_same_stasis_app/configs/ast1/pjsip.conf Fri Jan 9 11:44:59 2015 @@ -1,0 +1,40 @@ +[global] +type=global +debug=no + +[system] +type=system + +[local] +type=transport +protocol=udp +bind=127.0.0.1:5060 + +[alice] +type=endpoint +context=default +disallow=all +allow=ulaw +direct_media=no +media_address=127.0.0.1 +aors=alice + +[alice] +type=aor +max_contacts=1 +contact=sip:[email protected]:5060\;transport=udp + +[bob] +type=endpoint +context=default +disallow=all +allow=ulaw +direct_media=no +media_address=127.0.0.1 +aors=bob + +[bob] +type=aor +max_contacts=1 +contact=sip:[email protected]:5060\;transport=udp + Propchange: asterisk/trunk/tests/rest_api/external_interaction/blind_transfer/stasis_bridge_to_same_stasis_app/configs/ast1/pjsip.conf ------------------------------------------------------------------------------ svn:eol-style = native Propchange: asterisk/trunk/tests/rest_api/external_interaction/blind_transfer/stasis_bridge_to_same_stasis_app/configs/ast1/pjsip.conf ------------------------------------------------------------------------------ svn:keywords = Author Date Id Revision Propchange: asterisk/trunk/tests/rest_api/external_interaction/blind_transfer/stasis_bridge_to_same_stasis_app/configs/ast1/pjsip.conf ------------------------------------------------------------------------------ svn:mime-type = text/plain [... 259 lines stripped ...] -- _____________________________________________________________________ -- Bandwidth and Colocation Provided by http://www.api-digital.com -- svn-commits mailing list To UNSUBSCRIBE or update options visit: http://lists.digium.com/mailman/listinfo/svn-commits
