[asterisk-commits] jbigelow: testsuite/asterisk/trunk r6220 - in /asterisk/trunk/tests/rest_api/...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Fri Jan 9 11:45:11 CST 2015


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 <jbigelow at digium.com>
+
+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:alice at 127.0.0.2: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:bob at 127.0.0.3: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:stasis at 127.0.0.1'
+            transfer_uri: 'sip:1000 at 127.0.0.1'
+        -
+            name: 'bob'
+            username: 'bob'
+            domain: '127.0.0.1'
+            transport: 'local-ipv4-2'
+            call_uri: 'sip:stasis at 127.0.0.1'
+
+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 at 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 at 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 at 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 at 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 at 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 at 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 at 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 at default-.*'
+                    connected:
+                        number: 'bob'
+            count: 1
+        ami-actions:
+            action:
+               action: 'Hangup'
+               channel: '/^Local/s at 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 at 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 at default',
+              context: 'default',
+              extension: '1000',
+              priority: '1' },
+            { channelId: 'alice',
+              endpoint: 'Local/s at 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 at 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 at 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 at default-00000000;2'
+                        name: 'Local/1000 at default-0000000.;1'
+                    replace_channel:
+                        name: 'PJSIP/bob-0000000.'
             count: 1
-        -   conditions:
-                match:
-                    type: ChannelEnteredBridge
-                    channel:
-                        name: 'Local/1000 at 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 at 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 at 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:alice at 127.0.0.2: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:bob at 127.0.0.3: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 ...]



More information about the asterisk-commits mailing list