[asterisk-commits] mjordan: testsuite/asterisk/trunk r3719 - in /asterisk/trunk: lib/python/aste...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Fri Apr 19 09:43:07 CDT 2013


Author: mjordan
Date: Fri Apr 19 09:42:58 2013
New Revision: 3719

URL: http://svnview.digium.com/svn/testsuite?view=rev&rev=3719
Log:
Add nominal blind, attended, and blonde transfer tests

This patch adds tests for nominal transfers. This includes blind,
blond, and attended transfers, where:

* Alice calls Bob and Alice initiates the transfer
* Alice calls Bob and Bob initiates the transfer

Review: https://reviewboard.asterisk.org/r/2442/

Added:
    asterisk/trunk/tests/bridge/atxfer_nominal/
    asterisk/trunk/tests/bridge/atxfer_nominal/configs/
    asterisk/trunk/tests/bridge/atxfer_nominal/configs/ast1/
    asterisk/trunk/tests/bridge/atxfer_nominal/configs/ast1/extensions.conf   (with props)
    asterisk/trunk/tests/bridge/atxfer_nominal/configs/ast1/sip-alice.conf   (with props)
    asterisk/trunk/tests/bridge/atxfer_nominal/configs/ast4/
    asterisk/trunk/tests/bridge/atxfer_nominal/configs/ast4/extensions.conf   (with props)
    asterisk/trunk/tests/bridge/atxfer_nominal/configs/ast4/sip.conf   (with props)
    asterisk/trunk/tests/bridge/atxfer_nominal/test-config.yaml   (with props)
    asterisk/trunk/tests/bridge/atxfer_nominal/transfer.py   (with props)
    asterisk/trunk/tests/bridge/blindxfer_nominal/
    asterisk/trunk/tests/bridge/blindxfer_nominal/configs/
    asterisk/trunk/tests/bridge/blindxfer_nominal/configs/ast1/
    asterisk/trunk/tests/bridge/blindxfer_nominal/configs/ast1/extensions.conf   (with props)
    asterisk/trunk/tests/bridge/blindxfer_nominal/configs/ast1/sip-alice.conf   (with props)
    asterisk/trunk/tests/bridge/blindxfer_nominal/configs/ast4/
    asterisk/trunk/tests/bridge/blindxfer_nominal/configs/ast4/extensions.conf   (with props)
    asterisk/trunk/tests/bridge/blindxfer_nominal/configs/ast4/sip.conf   (with props)
    asterisk/trunk/tests/bridge/blindxfer_nominal/test-config.yaml   (with props)
    asterisk/trunk/tests/bridge/blindxfer_nominal/transfer.py   (with props)
    asterisk/trunk/tests/bridge/blonde_nominal/
    asterisk/trunk/tests/bridge/blonde_nominal/configs/
    asterisk/trunk/tests/bridge/blonde_nominal/configs/ast1/
    asterisk/trunk/tests/bridge/blonde_nominal/configs/ast1/extensions.conf   (with props)
    asterisk/trunk/tests/bridge/blonde_nominal/configs/ast1/sip-alice.conf   (with props)
    asterisk/trunk/tests/bridge/blonde_nominal/configs/ast4/
    asterisk/trunk/tests/bridge/blonde_nominal/configs/ast4/extensions.conf   (with props)
    asterisk/trunk/tests/bridge/blonde_nominal/configs/ast4/sip.conf   (with props)
    asterisk/trunk/tests/bridge/blonde_nominal/test-config.yaml   (with props)
    asterisk/trunk/tests/bridge/blonde_nominal/transfer.py   (with props)
Modified:
    asterisk/trunk/lib/python/asterisk/BridgeTestCase.py
    asterisk/trunk/tests/bridge/atxfer_setup/test-config.yaml
    asterisk/trunk/tests/bridge/automixmon/test-config.yaml
    asterisk/trunk/tests/bridge/automon/test-config.yaml
    asterisk/trunk/tests/bridge/blindxfer_setup/test-config.yaml
    asterisk/trunk/tests/bridge/connected_line_update/test-config.yaml
    asterisk/trunk/tests/bridge/dial_LS_options/test-config.yaml
    asterisk/trunk/tests/bridge/disconnect/test-config.yaml
    asterisk/trunk/tests/bridge/parkcall/test-config.yaml
    asterisk/trunk/tests/bridge/parkcall_timeout/comebacktoorigin_no/test-config.yaml
    asterisk/trunk/tests/bridge/parkcall_timeout/comebacktoorigin_yes/test-config.yaml
    asterisk/trunk/tests/bridge/simple_bridge/test-config.yaml
    asterisk/trunk/tests/bridge/tests.yaml
    asterisk/trunk/tests/bridge/transfer_capabilities/test-config.yaml
    asterisk/trunk/tests/bridge/transfer_failure/test-config.yaml

Modified: asterisk/trunk/lib/python/asterisk/BridgeTestCase.py
URL: http://svnview.digium.com/svn/testsuite/asterisk/trunk/lib/python/asterisk/BridgeTestCase.py?view=diff&rev=3719&r1=3718&r2=3719
==============================================================================
--- asterisk/trunk/lib/python/asterisk/BridgeTestCase.py (original)
+++ asterisk/trunk/lib/python/asterisk/BridgeTestCase.py Fri Apr 19 09:42:58 2013
@@ -40,14 +40,17 @@
         2 : the unit where calls terminate, also known as "Bob"
         '''
         TestCase.__init__(self, test_path)
-        self.create_asterisk(3, "%s/configs/bridge" % os.getcwd())
         self.test_runs = []
         self.current_run = 0
         self.ami_uut = None
         self.ami_alice = None
         self.ami_bob = None
         self.call_end_observers = []
+        self.feature_start_observers = []
+        self.feature_end_observers = []
         self.bridge_fail_token = self.create_fail_token("BridgeTestCase hasn't raised the flag to indicate completion of all expected calls.")
+        self.instances = 3
+        self.connections = 0
 
         if test_config is None:
             LOGGER.error("No configuration provided. Bailing.")
@@ -55,20 +58,48 @@
 
         # Just a quick sanity check so we can die early if
         # the tests are badly misconfigured
-        for test_run in test_config:
+        for test_run in test_config['test-runs']:
             if not 'originate_channel' in test_run:
                 LOGGER.error("No configured originate channel in test run")
                 raise Exception
 
             self.test_runs.append(test_run)
 
+        if 'asterisk-instances' in test_config:
+            self.instances = test_config['asterisk-instances']
+        self.create_asterisk(self.instances, "%s/configs/bridge" % os.getcwd())
         LOGGER.info("Bridge test initialized")
 
     def run(self):
         TestCase.run(self)
-        self.create_ami_factory(3)
+        self.create_ami_factory(self.instances)
+
+    def register_feature_start_observer(self, observer):
+        '''
+        Register an observer to be notified when a feature is started
+
+        Keyword Arguments:
+        observer A callback function to be called when a feature occurs. The
+            callback should take two arguments. This first will be this object;
+            the second will be a dict object describing the feature that just
+            occurred
+        '''
+        self.feature_start_observers.append(observer)
+
+    def register_feature_end_observer(self, observer):
+        '''
+        Register an observer to be notified when a feature is completed
+
+        Keyword Arguments:
+        observer A callback function to be called when a feature occurs. The
+            callback should take two arguments. This first will be this object;
+            the second will be a dict object describing the feature that just
+            occurred
+        '''
+        self.feature_end_observers.append(observer)
 
     def ami_connect(self, ami):
+        self.connections += 1
         self.ast[ami.id].cli_exec("sip set debug on")
         self.ast[ami.id].cli_exec("iax2 set debug on")
         self.ast[ami.id].cli_exec("xmpp set debug on")
@@ -89,19 +120,22 @@
             self.ami_bob.registerEvent('Hangup', self.hangup_callback)
             LOGGER.info("Bob AMI connected")
         else:
-            LOGGER.warning("Unexpected AMI ID %d recieved" % ami.id)
-
-        if self.ami_uut and self.ami_alice and self.ami_bob:
+            LOGGER.info("Unmanaged AMI ID %d received" % ami.id)
+
+        if self.connections == self.instances:
             # We can get started with the test!
             LOGGER.info("Time to run tests!")
             self.run_tests()
 
     def run_tests(self):
         if self.current_run < len(self.test_runs):
+            LOGGER.info('Executing test %d' % self.current_run)
             self.reset_timeout()
+            self.uut_alice_channel = None
+            self.uut_bob_channel = None
             self.start_test(self.test_runs[self.current_run])
-        else:
-            LOGGER.info("All calls executed, stopping")
+        elif self.current_run == len(self.test_runs):
+            LOGGER.info('All calls executed, stopping')
             self.remove_fail_token(self.bridge_fail_token)
             self.set_passed(True)
             self.stop_reactor()
@@ -144,16 +178,19 @@
             if event.get('result') == 'pass':
                 LOGGER.info("Two way audio properly detected between Bob and Alice")
                 self.audio_detected = True
-                self.check_identities()
+                self.check_identities(alice_connected_line=BridgeTestCase.ALICE_CONNECTED,
+                                      bob_connected_line=BridgeTestCase.BOB_CONNECTED,
+                                      bob_bridge_peer=self.uut_alice_channel,
+                                      alice_bridge_peer=self.uut_bob_channel)
             else:
                 LOGGER.warning("Audio issues on bridged call")
                 self.stop_reactor()
 
     def hangup_callback(self, ami, event):
-        if ami is self.ami_bob:
+        if ami is self.ami_bob and event.get('channel') == self.bob_channel:
             LOGGER.info("Bob has hung up")
             self.bob_hungup = True
-        elif ami is self.ami_alice:
+        elif ami is self.ami_alice and event.get('channel') == self.alice_channel:
             LOGGER.info("Alice has hung up")
             self.alice_hungup = True
         elif ami is self.ami_uut:
@@ -173,11 +210,15 @@
             self.run_tests()
 
     def uut_bridge_callback(self, ami, event):
-        LOGGER.debug("Got bridge callback")
-        self.uut_alice_channel = event.get('channel1')
-        self.uut_bob_channel = event.get('channel2')
+        if self.uut_alice_channel is None:
+            self.uut_alice_channel = event.get('channel1')
+            LOGGER.info('UUT Alice Channel: %s' % self.uut_alice_channel)
+        if self.uut_bob_channel is None:
+            self.uut_bob_channel = event.get('channel2')
+            LOGGER.info('UUT Bob Channel: %s' % self.uut_bob_channel)
         if event.get('bridgestate') == 'Link':
-            LOGGER.debug("Bridge is up")
+            LOGGER.debug("Bridge is up between %s and %s"
+                         % (event.get('channel1'), event.get('channel2')))
             LOGGER.debug("Type of bridge is %s" % event.get('bridgetype'))
             self.bridged = True
             if self.issue_hangups_on_bridged:
@@ -186,44 +227,65 @@
             LOGGER.debug("Bridge is down")
             self.bridged = False
 
-    def check_identities(self):
-        def alice_connected(value):
+    def check_identities(self, alice_connected_line=None,
+                         bob_connected_line=None,
+                         alice_bridge_peer=None,
+                         bob_bridge_peer=None):
+        ''' Check the identities of Alice & Bob
+
+        Keyword Arguments:
+        alice_connected_line The expected connected line value for Alice.
+            Default is None
+        bob_connected_line The expected connected line value for Bob. Default is
+            None
+        alice_bridge_peer The expected bridge peer for Alice. Default is None
+        bob_bridge_peer The expected bridge peer for Bob. Default is None
+
+        Note: setting any parameter to None will cause it to not be checked
+        '''
+        def alice_connected(value, expected):
             LOGGER.info("Alice's Connected line is %s" % value)
-            if value != BridgeTestCase.ALICE_CONNECTED:
-                LOGGER.warning("Unexpected Connected line value for Alice: %s" %
-                        value)
-                self.set_passed(False)
-
-        def bob_connected(value):
+            if value != expected:
+                LOGGER.warning("Bad Connected line value for Alice: expected %s, actual %s" %
+                        (expected, value))
+                self.set_passed(False)
+
+        def bob_connected(value, expected):
             LOGGER.info("Bob's Connected line is %s" % value)
-            if value != BridgeTestCase.BOB_CONNECTED:
-                LOGGER.warning("Unexpected Connected line value for Bob: %s" %
-                        value)
-                self.set_passed(False)
-
-        def alice_bridgepeer(value):
+            if value != expected:
+                LOGGER.warning("Bad Connected line value for Bob: expected %s, actual %s" %
+                        (expected, value))
+                self.set_passed(False)
+
+        def alice_bridgepeer(value, expected):
             LOGGER.info("Alice's BRIDGEPEER is %s" % value)
-            if value != self.uut_bob_channel:
-                LOGGER.warning("Unexpected BRIDGEPEER value for Alice: %s" %
-                        value)
-                self.set_passed(False)
-
-        def bob_bridgepeer(value):
+            if value != expected:
+                LOGGER.warning("Bad BRIDGEPEER value for Alice: expected %s, actual %s" %
+                        (expected, value))
+                self.set_passed(False)
+
+        def bob_bridgepeer(value, expected):
             LOGGER.info("Bob's BRIDGEPEER is %s" % value)
-            if value != self.uut_alice_channel:
-                LOGGER.warning("Unexpected BRIDGEPEER value for Bob: %s" %
-                        value)
+            if value != expected:
+                LOGGER.warning("Bad BRIDGEPEER value for Bob: expected %s, actual %s" %
+                        (expected, value))
                 self.set_passed(False)
             self.execute_features()
 
-        self.ami_uut.getVar(self.uut_alice_channel,
-                'CONNECTEDLINE(all)').addCallback(alice_connected)
-        bob_connected = self.ami_uut.getVar(self.uut_bob_channel,
-                'CONNECTEDLINE(all)').addCallback(bob_connected)
-        alice_bridgepeer = self.ami_uut.getVar(self.uut_alice_channel,
-                'BRIDGEPEER').addCallback(alice_bridgepeer)
-        bob_bridgepeer = self.ami_uut.getVar(self.uut_bob_channel,
-                'BRIDGEPEER').addCallback(bob_bridgepeer)
+        if alice_connected_line is not None:
+            self.ami_uut.getVar(self.uut_alice_channel,
+                'CONNECTEDLINE(all)').addCallback(alice_connected,
+                                                  alice_connected_line)
+        if bob_connected_line is not None:
+            self.ami_uut.getVar(self.uut_bob_channel,
+                'CONNECTEDLINE(all)').addCallback(bob_connected,
+                                                  bob_connected_line)
+        if alice_bridge_peer is not None:
+            self.ami_uut.getVar(self.uut_alice_channel,
+                'BRIDGEPEER').addCallback(alice_bridgepeer, alice_bridge_peer)
+        if bob_bridge_peer is not None:
+            self.ami_uut.getVar(self.uut_bob_channel,
+                'BRIDGEPEER').addCallback(bob_bridgepeer, bob_bridge_peer)
 
     def execute_features(self):
         if self.current_feature < len(self.features):
@@ -259,6 +321,9 @@
         else:
             self.feature_success = False
 
+        for observer in self.feature_start_observers:
+            observer(self, self.features[self.current_feature])
+
         LOGGER.info("Sending feature %s from %s" % (feature['what'],
             feature['who']))
         # make sure to put a gap between DTMF digits to ensure that events
@@ -298,6 +363,8 @@
             if self.feature_success:
                 LOGGER.warning("Feature failed when success was expected")
                 self.set_passed(False)
+        for observer in self.feature_end_observers:
+            observer(self, self.features[self.current_feature])
         # Move onto the next feature!
         self.current_feature += 1
         self.execute_features()

Added: asterisk/trunk/tests/bridge/atxfer_nominal/configs/ast1/extensions.conf
URL: http://svnview.digium.com/svn/testsuite/asterisk/trunk/tests/bridge/atxfer_nominal/configs/ast1/extensions.conf?view=auto&rev=3719
==============================================================================
--- asterisk/trunk/tests/bridge/atxfer_nominal/configs/ast1/extensions.conf (added)
+++ asterisk/trunk/tests/bridge/atxfer_nominal/configs/ast1/extensions.conf Fri Apr 19 09:42:58 2013
@@ -1,0 +1,11 @@
+[default]
+
+exten => alice_atxfer,1,Dial(SIP/test_call at bob,,T)
+	same => n,Hangup()
+
+exten => bob_atxfer,1,Dial(SIP/test_call at bob,,t)
+	same => n,Hangup()
+
+exten => 123,1,NoOp(This is our transfer target)
+	same => n,Dial(SIP/transfer at charlie,,Tt)
+	same => n,Hangup()

Propchange: asterisk/trunk/tests/bridge/atxfer_nominal/configs/ast1/extensions.conf
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: asterisk/trunk/tests/bridge/atxfer_nominal/configs/ast1/extensions.conf
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Propchange: asterisk/trunk/tests/bridge/atxfer_nominal/configs/ast1/extensions.conf
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: asterisk/trunk/tests/bridge/atxfer_nominal/configs/ast1/sip-alice.conf
URL: http://svnview.digium.com/svn/testsuite/asterisk/trunk/tests/bridge/atxfer_nominal/configs/ast1/sip-alice.conf?view=auto&rev=3719
==============================================================================
--- asterisk/trunk/tests/bridge/atxfer_nominal/configs/ast1/sip-alice.conf (added)
+++ asterisk/trunk/tests/bridge/atxfer_nominal/configs/ast1/sip-alice.conf Fri Apr 19 09:42:58 2013
@@ -1,0 +1,8 @@
+[alice-extra](!)
+
+[charlie]
+sendrpid=pai
+callerid=Charlie <5678>
+type = peer
+host = 127.0.0.1
+port = 5063

Propchange: asterisk/trunk/tests/bridge/atxfer_nominal/configs/ast1/sip-alice.conf
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: asterisk/trunk/tests/bridge/atxfer_nominal/configs/ast1/sip-alice.conf
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Propchange: asterisk/trunk/tests/bridge/atxfer_nominal/configs/ast1/sip-alice.conf
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: asterisk/trunk/tests/bridge/atxfer_nominal/configs/ast4/extensions.conf
URL: http://svnview.digium.com/svn/testsuite/asterisk/trunk/tests/bridge/atxfer_nominal/configs/ast4/extensions.conf?view=auto&rev=3719
==============================================================================
--- asterisk/trunk/tests/bridge/atxfer_nominal/configs/ast4/extensions.conf (added)
+++ asterisk/trunk/tests/bridge/atxfer_nominal/configs/ast4/extensions.conf Fri Apr 19 09:42:58 2013
@@ -1,0 +1,10 @@
+
+[general]
+
+[default]
+
+exten => transfer,1,NoOp(Incoming call transfer)
+same => n,Answer()
+same => n,Wait(1)
+same => n,UserEvent(Transfer,Result:Connected)
+same => n,Echo()

Propchange: asterisk/trunk/tests/bridge/atxfer_nominal/configs/ast4/extensions.conf
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: asterisk/trunk/tests/bridge/atxfer_nominal/configs/ast4/extensions.conf
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Propchange: asterisk/trunk/tests/bridge/atxfer_nominal/configs/ast4/extensions.conf
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: asterisk/trunk/tests/bridge/atxfer_nominal/configs/ast4/sip.conf
URL: http://svnview.digium.com/svn/testsuite/asterisk/trunk/tests/bridge/atxfer_nominal/configs/ast4/sip.conf?view=auto&rev=3719
==============================================================================
--- asterisk/trunk/tests/bridge/atxfer_nominal/configs/ast4/sip.conf (added)
+++ asterisk/trunk/tests/bridge/atxfer_nominal/configs/ast4/sip.conf Fri Apr 19 09:42:58 2013
@@ -1,0 +1,7 @@
+[general]
+udpbindaddr=127.0.0.1:5063
+
+[uut]
+type=peer
+host=127.0.0.1
+port=5060

Propchange: asterisk/trunk/tests/bridge/atxfer_nominal/configs/ast4/sip.conf
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: asterisk/trunk/tests/bridge/atxfer_nominal/configs/ast4/sip.conf
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Propchange: asterisk/trunk/tests/bridge/atxfer_nominal/configs/ast4/sip.conf
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: asterisk/trunk/tests/bridge/atxfer_nominal/test-config.yaml
URL: http://svnview.digium.com/svn/testsuite/asterisk/trunk/tests/bridge/atxfer_nominal/test-config.yaml?view=auto&rev=3719
==============================================================================
--- asterisk/trunk/tests/bridge/atxfer_nominal/test-config.yaml (added)
+++ asterisk/trunk/tests/bridge/atxfer_nominal/test-config.yaml Fri Apr 19 09:42:58 2013
@@ -1,0 +1,67 @@
+testinfo:
+    summary: 'Test the attended transfer feature'
+    description: |
+        'Set up a bridge between two endpoints and check that the DTMF attended
+        transfer feature is detected and executed properly. Two transfers
+        are performed; one initiated by Alice, and the other by Bob. In both
+        cases, the destination is Charlie.'
+
+test-modules:
+    add-test-to-search-path: 'True'
+    test-object:
+        config-section: bridge-config
+        typename: 'BridgeTestCase.BridgeTestCase'
+    modules:
+        -
+            config-section: 'transfer-config'
+            typename: 'transfer.Transfer'
+        -
+            config-section: 'ami-userevent-checker'
+            typename: 'ami.AMIEventModule'
+
+
+transfer-config:
+    -
+        transferer: 'alice'
+    -
+        transferer: 'bob'
+
+ami-userevent-checker:
+    -
+        type: 'callback'
+        id: '3'
+        conditions:
+            match:
+                Event: 'UserEvent'
+                UserEvent: 'Transfer'
+                Result: 'Connected'
+        callbackModule: 'transfer'
+        callbackMethod: 'complete_attended_transfer'
+
+bridge-config:
+    asterisk-instances: 4
+    test-runs:
+      -
+          originate_channel: 'SIP/alice_atxfer at uut'
+          features:
+              -
+                  who: 'alice'
+                  what: 'atxfer'
+                  success: 'true'
+                  exten: '123'
+      -
+          originate_channel: 'SIP/bob_atxfer at uut'
+          features:
+              -
+                  who: 'bob'
+                  what: 'atxfer'
+                  success: 'true'
+                  exten: '123'
+
+properties:
+    minversion: '12.0.0'
+    dependencies:
+        - python : 'twisted'
+        - python : 'starpy'
+    tags:
+        - bridge

Propchange: asterisk/trunk/tests/bridge/atxfer_nominal/test-config.yaml
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: asterisk/trunk/tests/bridge/atxfer_nominal/test-config.yaml
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Propchange: asterisk/trunk/tests/bridge/atxfer_nominal/test-config.yaml
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: asterisk/trunk/tests/bridge/atxfer_nominal/transfer.py
URL: http://svnview.digium.com/svn/testsuite/asterisk/trunk/tests/bridge/atxfer_nominal/transfer.py?view=auto&rev=3719
==============================================================================
--- asterisk/trunk/tests/bridge/atxfer_nominal/transfer.py (added)
+++ asterisk/trunk/tests/bridge/atxfer_nominal/transfer.py Fri Apr 19 09:42:58 2013
@@ -1,0 +1,114 @@
+#!/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
+
+sys.path.append("lib/python")
+
+LOGGER = logging.getLogger(__name__)
+
+class Transfer(object):
+
+    __singleton_instance = None
+
+    @staticmethod
+    def get_instance():
+        ''' Return the singleton instance of the application test_object
+
+        Keyword Arguments:
+        path The full path to the location of the test
+        test_config The test's YAML configuration object
+        '''
+        if (Transfer.__singleton_instance is None):
+            # Note that the constructor sets the singleton instance.
+            # This is a tad backwards, but is needed for the pluggable
+            # framework. If we get a get_instance call before its been set,
+            # blow up - that really shouldn't ever happen
+            raise Exception()
+        return Transfer.__singleton_instance
+
+    def __init__(self, module_config, test_object):
+        ''' Constructor
+
+        Keyword Arguments:
+        module_config The module configuration
+        test_object The test object. Must be of type BridgeTestCase
+        '''
+        self.module_config = module_config
+        self.test_object = test_object
+        self._current_feature = None
+
+        self.test_object.register_feature_start_observer(self._handle_feature_start)
+        self.test_object.register_feature_end_observer(self._handle_feature_end)
+
+        if (Transfer.__singleton_instance == None):
+            Transfer.__singleton_instance = self
+
+    def _handle_feature_start(self, test_object, feature):
+        ''' Callback for the BridgeTestCase feature detected event
+
+        Keyword Arguments:
+        test_object The BridgeTestCase object
+        feature The specific feature that was executed
+        '''
+        LOGGER.debug('Setting current feature to %s' % str(feature))
+        self._current_feature = feature
+
+    def _handle_feature_end(self, test_object, feature):
+        ''' Callback for the BridgeTestCase feature detected event
+
+        Keyword Arguments:
+        test_object The BridgeTestCase object
+        feature The specific feature that was executed
+        '''
+        if self._current_feature['who'] == 'alice':
+            ami = self.test_object.ami_bob
+            channel = self.test_object.bob_channel
+            self.test_object.check_identities(bob_connected_line='"Charlie" <5678>')
+        elif self._current_feature['who'] == 'bob':
+            ami = self.test_object.ami_alice
+            channel = self.test_object.alice_channel
+            self.test_object.check_identities(alice_connected_line='"Charlie" <5678>')
+        else:
+            raise Exception()
+        LOGGER.info('Hanging up channel %s' % channel)
+        ami.hangup(channel)
+
+    def complete_attended_transfer(self):
+        '''
+        Called when we've detected that the Attended Transfer should
+        complete
+        '''
+        if self._current_feature is None:
+            raise Exception()
+
+        if self._current_feature['who'] == 'alice':
+            ami = self.test_object.ami_alice
+            channel = self.test_object.alice_channel
+        elif self._current_feature['who'] == 'bob':
+            ami = self.test_object.ami_bob
+            channel = self.test_object.bob_channel
+        else:
+            raise Exception()
+        LOGGER.info('Hanging up channel %s' % channel)
+        ami.hangup(channel)
+
+
+
+def complete_attended_transfer(ami, event):
+    '''
+    Callback that occurs during an attended transfer.
+    This callback signals that the test should complete the attended
+    transfer by hanging up the transferer.
+    '''
+
+    transfer = Transfer.get_instance()
+    transfer.complete_attended_transfer()
+    return True

Propchange: asterisk/trunk/tests/bridge/atxfer_nominal/transfer.py
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: asterisk/trunk/tests/bridge/atxfer_nominal/transfer.py
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Propchange: asterisk/trunk/tests/bridge/atxfer_nominal/transfer.py
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: asterisk/trunk/tests/bridge/atxfer_setup/test-config.yaml
URL: http://svnview.digium.com/svn/testsuite/asterisk/trunk/tests/bridge/atxfer_setup/test-config.yaml?view=diff&rev=3719&r1=3718&r2=3719
==============================================================================
--- asterisk/trunk/tests/bridge/atxfer_setup/test-config.yaml (original)
+++ asterisk/trunk/tests/bridge/atxfer_setup/test-config.yaml Fri Apr 19 09:42:58 2013
@@ -18,6 +18,7 @@
             typename: 'cel.CELModule'
 
 bridge-config:
+  test-runs:
     -
         originate_channel: 'SIP/alice_atxfer at uut'
         hangup: 'alice'

Modified: asterisk/trunk/tests/bridge/automixmon/test-config.yaml
URL: http://svnview.digium.com/svn/testsuite/asterisk/trunk/tests/bridge/automixmon/test-config.yaml?view=diff&rev=3719&r1=3718&r2=3719
==============================================================================
--- asterisk/trunk/tests/bridge/automixmon/test-config.yaml (original)
+++ asterisk/trunk/tests/bridge/automixmon/test-config.yaml Fri Apr 19 09:42:58 2013
@@ -18,6 +18,7 @@
             typename: 'cel.CELModule'
 
 bridge-config:
+  test-runs:
     -
         originate_channel: 'SIP/alice_automixmon at uut'
         hangup: 'alice'

Modified: asterisk/trunk/tests/bridge/automon/test-config.yaml
URL: http://svnview.digium.com/svn/testsuite/asterisk/trunk/tests/bridge/automon/test-config.yaml?view=diff&rev=3719&r1=3718&r2=3719
==============================================================================
--- asterisk/trunk/tests/bridge/automon/test-config.yaml (original)
+++ asterisk/trunk/tests/bridge/automon/test-config.yaml Fri Apr 19 09:42:58 2013
@@ -18,6 +18,7 @@
             typename: 'cel.CELModule'
 
 bridge-config:
+  test-runs:
     -
         originate_channel: 'SIP/alice_automon at uut'
         hangup: 'alice'

Added: asterisk/trunk/tests/bridge/blindxfer_nominal/configs/ast1/extensions.conf
URL: http://svnview.digium.com/svn/testsuite/asterisk/trunk/tests/bridge/blindxfer_nominal/configs/ast1/extensions.conf?view=auto&rev=3719
==============================================================================
--- asterisk/trunk/tests/bridge/blindxfer_nominal/configs/ast1/extensions.conf (added)
+++ asterisk/trunk/tests/bridge/blindxfer_nominal/configs/ast1/extensions.conf Fri Apr 19 09:42:58 2013
@@ -1,0 +1,11 @@
+[default]
+
+exten => alice_blindxfer,1,Dial(SIP/test_call at bob,,T)
+	same => n,Hangup()
+
+exten => bob_blindxfer,1,Dial(SIP/test_call at bob,,t)
+	same => n,Hangup()
+
+exten => 123,1,NoOp(This is our transfer target)
+	same => n,Dial(SIP/transfer at charlie,,Tt)
+	same => n,Hangup()

Propchange: asterisk/trunk/tests/bridge/blindxfer_nominal/configs/ast1/extensions.conf
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: asterisk/trunk/tests/bridge/blindxfer_nominal/configs/ast1/extensions.conf
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Propchange: asterisk/trunk/tests/bridge/blindxfer_nominal/configs/ast1/extensions.conf
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: asterisk/trunk/tests/bridge/blindxfer_nominal/configs/ast1/sip-alice.conf
URL: http://svnview.digium.com/svn/testsuite/asterisk/trunk/tests/bridge/blindxfer_nominal/configs/ast1/sip-alice.conf?view=auto&rev=3719
==============================================================================
--- asterisk/trunk/tests/bridge/blindxfer_nominal/configs/ast1/sip-alice.conf (added)
+++ asterisk/trunk/tests/bridge/blindxfer_nominal/configs/ast1/sip-alice.conf Fri Apr 19 09:42:58 2013
@@ -1,0 +1,8 @@
+[alice-extra](!)
+
+[charlie]
+sendrpid=pai
+callerid=Charlie <5678>
+type = peer
+host = 127.0.0.1
+port = 5063

Propchange: asterisk/trunk/tests/bridge/blindxfer_nominal/configs/ast1/sip-alice.conf
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: asterisk/trunk/tests/bridge/blindxfer_nominal/configs/ast1/sip-alice.conf
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Propchange: asterisk/trunk/tests/bridge/blindxfer_nominal/configs/ast1/sip-alice.conf
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: asterisk/trunk/tests/bridge/blindxfer_nominal/configs/ast4/extensions.conf
URL: http://svnview.digium.com/svn/testsuite/asterisk/trunk/tests/bridge/blindxfer_nominal/configs/ast4/extensions.conf?view=auto&rev=3719
==============================================================================
--- asterisk/trunk/tests/bridge/blindxfer_nominal/configs/ast4/extensions.conf (added)
+++ asterisk/trunk/tests/bridge/blindxfer_nominal/configs/ast4/extensions.conf Fri Apr 19 09:42:58 2013
@@ -1,0 +1,10 @@
+
+[general]
+
+[default]
+
+exten => transfer,1,NoOp(Incoming call transfer)
+same => n,Answer()
+same => n,Wait(1)
+same => n,UserEvent(Transfer,Result:Connected)
+same => n,Echo()

Propchange: asterisk/trunk/tests/bridge/blindxfer_nominal/configs/ast4/extensions.conf
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: asterisk/trunk/tests/bridge/blindxfer_nominal/configs/ast4/extensions.conf
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Propchange: asterisk/trunk/tests/bridge/blindxfer_nominal/configs/ast4/extensions.conf
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: asterisk/trunk/tests/bridge/blindxfer_nominal/configs/ast4/sip.conf
URL: http://svnview.digium.com/svn/testsuite/asterisk/trunk/tests/bridge/blindxfer_nominal/configs/ast4/sip.conf?view=auto&rev=3719
==============================================================================
--- asterisk/trunk/tests/bridge/blindxfer_nominal/configs/ast4/sip.conf (added)
+++ asterisk/trunk/tests/bridge/blindxfer_nominal/configs/ast4/sip.conf Fri Apr 19 09:42:58 2013
@@ -1,0 +1,7 @@
+[general]
+udpbindaddr=127.0.0.1:5063
+
+[uut]
+type=peer
+host=127.0.0.1
+port=5060

Propchange: asterisk/trunk/tests/bridge/blindxfer_nominal/configs/ast4/sip.conf
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: asterisk/trunk/tests/bridge/blindxfer_nominal/configs/ast4/sip.conf
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Propchange: asterisk/trunk/tests/bridge/blindxfer_nominal/configs/ast4/sip.conf
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: asterisk/trunk/tests/bridge/blindxfer_nominal/test-config.yaml
URL: http://svnview.digium.com/svn/testsuite/asterisk/trunk/tests/bridge/blindxfer_nominal/test-config.yaml?view=auto&rev=3719
==============================================================================
--- asterisk/trunk/tests/bridge/blindxfer_nominal/test-config.yaml (added)
+++ asterisk/trunk/tests/bridge/blindxfer_nominal/test-config.yaml Fri Apr 19 09:42:58 2013
@@ -1,0 +1,67 @@
+testinfo:
+    summary: 'Test the blind transfer feature'
+    description: |
+        'Set up a bridge between two endpoints and check that the DTMF blind
+        transfer feature is detected and executed properly. Two transfers
+        are performed; one initiated by Alice, and the other by Bob. In both
+        cases, the destination of the transfer is Charlie.'
+
+test-modules:
+    add-test-to-search-path: 'True'
+    test-object:
+        config-section: bridge-config
+        typename: 'BridgeTestCase.BridgeTestCase'
+    modules:
+        -
+            config-section: 'transfer-config'
+            typename: 'transfer.Transfer'
+        -
+            config-section: 'ami-userevent-checker'
+            typename: 'ami.AMIEventModule'
+
+transfer-config:
+    -
+        transferer: 'alice'
+    -
+        transferer: 'bob'
+
+ami-userevent-checker:
+    -
+        type: 'callback'
+        id: '3'
+        conditions:
+            match:
+                Event: 'UserEvent'
+                UserEvent: 'Transfer'
+                Result: 'Connected'
+        callbackModule: 'transfer'
+        callbackMethod: 'check_connected_line'
+
+
+bridge-config:
+    asterisk-instances: 4
+    test-runs:
+      -
+          originate_channel: 'SIP/alice_blindxfer at uut'
+          features:
+              -
+                  who: 'alice'
+                  what: 'blindxfer'
+                  success: 'true'
+                  exten: '123'
+      -
+          originate_channel: 'SIP/bob_blindxfer at uut'
+          features:
+              -
+                  who: 'bob'
+                  what: 'blindxfer'
+                  success: 'true'
+                  exten: '123'
+
+properties:
+    minversion: '12.0.0'
+    dependencies:
+        - python : 'twisted'
+        - python : 'starpy'
+    tags:
+        - bridge

Propchange: asterisk/trunk/tests/bridge/blindxfer_nominal/test-config.yaml
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: asterisk/trunk/tests/bridge/blindxfer_nominal/test-config.yaml
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Propchange: asterisk/trunk/tests/bridge/blindxfer_nominal/test-config.yaml
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: asterisk/trunk/tests/bridge/blindxfer_nominal/transfer.py
URL: http://svnview.digium.com/svn/testsuite/asterisk/trunk/tests/bridge/blindxfer_nominal/transfer.py?view=auto&rev=3719
==============================================================================
--- asterisk/trunk/tests/bridge/blindxfer_nominal/transfer.py (added)
+++ asterisk/trunk/tests/bridge/blindxfer_nominal/transfer.py Fri Apr 19 09:42:58 2013
@@ -1,0 +1,87 @@
+#!/usr/bin/env python
+'''
+Copyright (C) 2013, Digium, Inc.
+Jonathan Rose <jrose at digium.com>
+
+This program is free software, distributed under the terms of
+the GNU General Public License Version 2.
+'''
+
+import sys
+import logging
+
+sys.path.append("lib/python")
+
+LOGGER = logging.getLogger(__name__)
+
+class Transfer(object):
+
+    __singleton_instance = None
+
+    @staticmethod
+    def get_instance():
+        ''' Return the singleton instance of the application test_object
+
+        Keyword Arguments:
+        path The full path to the location of the test
+        test_config The test's YAML configuration object
+        '''
+        if (Transfer.__singleton_instance is None):
+            # Note that the constructor sets the singleton instance.
+            # This is a tad backwards, but is needed for the pluggable
+            # framework. If we get a get_instance call before its been set,
+            # blow up - that really shouldn't ever happen
+            raise Exception()
+        return Transfer.__singleton_instance
+
+    def __init__(self, module_config, test_object):
+        ''' Constructor
+
+        Keyword Arguments:
+        module_config The module configuration
+        test_object The test object. Must be of type BridgeTestCase
+        '''
+        self.module_config = module_config
+        self.test_object = test_object
+        self._current_feature = None
+

[... 520 lines stripped ...]



More information about the asterisk-commits mailing list