[asterisk-commits] jbigelow: testsuite/asterisk/trunk r6491 - in /asterisk/trunk: lib/python/ast...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Fri Mar 6 13:45:22 CST 2015


Author: jbigelow
Date: Fri Mar  6 13:45:17 2015
New Revision: 6491

URL: http://svnview.digium.com/svn/testsuite?view=rev&rev=6491
Log:
Testsuite: Add ARI channel subscription tests.

This adds some local and non-local channel subscription tests for ARI. These
tests ensure ARI events occur and/or don't occur for the appropriate stasis
app(s).

Four tests have been added under
'tests/rest_api/applications/channel-subscriptions/':
* originate_to_dialplan/non_local_channels - Similiar to the existing test that
this patch modifies as mentioned below. This required modifying pjsua_mod.py to
allow more calls.
* originate_to_other_stasis_app/local_channels - Creates two websockets, one
for for each stasis app. Originates a local channel from AppA where half is
sent into AppB and the other half send into the dialplan.
* originate_to_other_stasis_app/non_local_channels - Creates two websockets,
one for for each stasis app. Originates a PJSIP channel from AppA to a pjsua
phone where is is placed into AppB.
* originate_to_stasis_app/local_channels

Note:  The test 'tests/rest_api/applications/subscribe-channel' test has been
renamed to 'basic-subscribe' under the same location as the new tests. 

The following test has been modified to ensure no ARI events are received:
* tests/rest_api/channels/originate_to_dialplan

ASTERISK-24586 #close
Review: https://reviewboard.asterisk.org/r/4452/


Added:
    asterisk/trunk/tests/rest_api/applications/channel-subscriptions/
    asterisk/trunk/tests/rest_api/applications/channel-subscriptions/basic_subscription/
      - copied from r6475, asterisk/trunk/tests/rest_api/applications/subscribe-channel/
    asterisk/trunk/tests/rest_api/applications/channel-subscriptions/originate_to_dialplan/
    asterisk/trunk/tests/rest_api/applications/channel-subscriptions/originate_to_dialplan/non_local_channels/
    asterisk/trunk/tests/rest_api/applications/channel-subscriptions/originate_to_dialplan/non_local_channels/configs/
    asterisk/trunk/tests/rest_api/applications/channel-subscriptions/originate_to_dialplan/non_local_channels/configs/ast1/
    asterisk/trunk/tests/rest_api/applications/channel-subscriptions/originate_to_dialplan/non_local_channels/configs/ast1/extensions.conf   (with props)
    asterisk/trunk/tests/rest_api/applications/channel-subscriptions/originate_to_dialplan/non_local_channels/configs/ast1/pjsip.conf   (with props)
    asterisk/trunk/tests/rest_api/applications/channel-subscriptions/originate_to_dialplan/non_local_channels/test-config.yaml   (with props)
    asterisk/trunk/tests/rest_api/applications/channel-subscriptions/originate_to_dialplan/tests.yaml   (with props)
    asterisk/trunk/tests/rest_api/applications/channel-subscriptions/originate_to_other_stasis_app/
    asterisk/trunk/tests/rest_api/applications/channel-subscriptions/originate_to_other_stasis_app/local_channels/
    asterisk/trunk/tests/rest_api/applications/channel-subscriptions/originate_to_other_stasis_app/local_channels/configs/
    asterisk/trunk/tests/rest_api/applications/channel-subscriptions/originate_to_other_stasis_app/local_channels/configs/ast1/
    asterisk/trunk/tests/rest_api/applications/channel-subscriptions/originate_to_other_stasis_app/local_channels/configs/ast1/extensions.conf   (with props)
    asterisk/trunk/tests/rest_api/applications/channel-subscriptions/originate_to_other_stasis_app/local_channels/configs/ast1/http.conf   (with props)
    asterisk/trunk/tests/rest_api/applications/channel-subscriptions/originate_to_other_stasis_app/local_channels/run-test   (with props)
    asterisk/trunk/tests/rest_api/applications/channel-subscriptions/originate_to_other_stasis_app/local_channels/test-config.yaml   (with props)
    asterisk/trunk/tests/rest_api/applications/channel-subscriptions/originate_to_other_stasis_app/non_local_channels/
    asterisk/trunk/tests/rest_api/applications/channel-subscriptions/originate_to_other_stasis_app/non_local_channels/configs/
    asterisk/trunk/tests/rest_api/applications/channel-subscriptions/originate_to_other_stasis_app/non_local_channels/configs/ast1/
    asterisk/trunk/tests/rest_api/applications/channel-subscriptions/originate_to_other_stasis_app/non_local_channels/configs/ast1/http.conf   (with props)
    asterisk/trunk/tests/rest_api/applications/channel-subscriptions/originate_to_other_stasis_app/non_local_channels/configs/ast1/pjsip.conf   (with props)
    asterisk/trunk/tests/rest_api/applications/channel-subscriptions/originate_to_other_stasis_app/non_local_channels/run-test   (with props)
    asterisk/trunk/tests/rest_api/applications/channel-subscriptions/originate_to_other_stasis_app/non_local_channels/test-config.yaml   (with props)
    asterisk/trunk/tests/rest_api/applications/channel-subscriptions/originate_to_other_stasis_app/tests.yaml   (with props)
    asterisk/trunk/tests/rest_api/applications/channel-subscriptions/originate_to_stasis_app/
    asterisk/trunk/tests/rest_api/applications/channel-subscriptions/originate_to_stasis_app/local_channels/
    asterisk/trunk/tests/rest_api/applications/channel-subscriptions/originate_to_stasis_app/local_channels/configs/
    asterisk/trunk/tests/rest_api/applications/channel-subscriptions/originate_to_stasis_app/local_channels/configs/ast1/
    asterisk/trunk/tests/rest_api/applications/channel-subscriptions/originate_to_stasis_app/local_channels/configs/ast1/extensions.conf   (with props)
    asterisk/trunk/tests/rest_api/applications/channel-subscriptions/originate_to_stasis_app/local_channels/test-config.yaml   (with props)
    asterisk/trunk/tests/rest_api/applications/channel-subscriptions/originate_to_stasis_app/tests.yaml   (with props)
    asterisk/trunk/tests/rest_api/applications/channel-subscriptions/tests.yaml   (with props)
Removed:
    asterisk/trunk/tests/rest_api/applications/subscribe-channel/
Modified:
    asterisk/trunk/lib/python/asterisk/pjsua_mod.py
    asterisk/trunk/tests/rest_api/applications/tests.yaml
    asterisk/trunk/tests/rest_api/channels/originate_to_dialplan/test-config.yaml

Modified: asterisk/trunk/lib/python/asterisk/pjsua_mod.py
URL: http://svnview.digium.com/svn/testsuite/asterisk/trunk/lib/python/asterisk/pjsua_mod.py?view=diff&rev=6491&r1=6490&r2=6491
==============================================================================
--- asterisk/trunk/lib/python/asterisk/pjsua_mod.py (original)
+++ asterisk/trunk/lib/python/asterisk/pjsua_mod.py Fri Mar  6 13:45:17 2015
@@ -116,6 +116,8 @@
         self.ami_connected = 0
         self.callback_module = instance_config.get('callback_module')
         self.callback_method = instance_config.get('callback_method')
+        # Default is 4. Must be lower than PJSUA_MAX_CALLS (default is 32).
+        self.max_calls = 30
 
     def __ami_connect(self, ami):
         """
@@ -131,9 +133,11 @@
                                      len(self.test_object.ami)))
             return
 
+        ua_cfg = pj.UAConfig()
+        ua_cfg.max_calls = self.max_calls
         self.lib = pj.Lib()
         try:
-            self.lib.init()
+            self.lib.init(ua_cfg=ua_cfg)
             self.__create_transports()
             self.lib.set_null_snd_dev()
             self.__create_accounts()

Added: asterisk/trunk/tests/rest_api/applications/channel-subscriptions/originate_to_dialplan/non_local_channels/configs/ast1/extensions.conf
URL: http://svnview.digium.com/svn/testsuite/asterisk/trunk/tests/rest_api/applications/channel-subscriptions/originate_to_dialplan/non_local_channels/configs/ast1/extensions.conf?view=auto&rev=6491
==============================================================================
--- asterisk/trunk/tests/rest_api/applications/channel-subscriptions/originate_to_dialplan/non_local_channels/configs/ast1/extensions.conf (added)
+++ asterisk/trunk/tests/rest_api/applications/channel-subscriptions/originate_to_dialplan/non_local_channels/configs/ast1/extensions.conf Fri Mar  6 13:45:17 2015
@@ -1,0 +1,47 @@
+[default]
+
+exten => dummy,1,Answer
+same => n,Echo()
+same => n,Hangup()
+
+exten => echo,1,Answer()
+same => n,Echo()
+same => n,Hangup()
+
+exten => test,1,UserEvent(${IF($[${location} = ${EXTEN}@${CONTEXT}:${PRIORITY}]?Success:Failed)})
+same => 2,Hangup()
+same => 3,UserEvent(${IF($[${location} = ${EXTEN}@${CONTEXT}:${PRIORITY}]?Success:Failed)})
+same => 4,Hangup()
+same => 5(dopey),UserEvent(${IF($[${location} = ${EXTEN}@${CONTEXT}:${PRIORITY}]?Success:Failed)})
+same => 6,Hangup()
+same => 7(doc),UserEvent(${IF($[${location} = ${EXTEN}@${CONTEXT}:${PRIORITY}]?Success:Failed)})
+same => 8,Hangup()
+same => 9,UserEvent(${IF($[${location} = ${EXTEN}@${CONTEXT}:${PRIORITY}]?Success:Failed)})
+same => 10,Hangup()
+same => 11,UserEvent(${IF($[${location} = ${EXTEN}@${CONTEXT}:${PRIORITY}]?Success:Failed)})
+same => 12,Hangup()
+
+; Having an h extension prevents _. from matching when the channel hangs up
+exten => h,1,NoOp()
+
+exten => _.,1,UserEvent(Failed)
+
+[grumpy]
+exten => test,1,UserEvent(${IF($[${location} = ${EXTEN}@${CONTEXT}:${PRIORITY}]?Success:Failed)})
+same => 2,Hangup()
+same => 3,UserEvent(${IF($[${location} = ${EXTEN}@${CONTEXT}:${PRIORITY}]?Success:Failed)})
+same => 4,Hangup()
+same => 5(sleepy),UserEvent(${IF($[${location} = ${EXTEN}@${CONTEXT}:${PRIORITY}]?Success:Failed)})
+same => 6,Hangup()
+same => 7(bashful),UserEvent(${IF($[${location} = ${EXTEN}@${CONTEXT}:${PRIORITY}]?Success:Failed)})
+same => 8,Hangup()
+same => 9,UserEvent(${IF($[${location} = ${EXTEN}@${CONTEXT}:${PRIORITY}]?Success:Failed)})
+same => 10,Hangup()
+same => 11,UserEvent(${IF($[${location} = ${EXTEN}@${CONTEXT}:${PRIORITY}]?Success:Failed)})
+same => 12,UserEvent(TestSuiteTestEnd)
+same => 13,Hangup()
+
+; Having an h extension prevents _. from matching when the channel hangs up
+exten => h,1,NoOp()
+
+exten => _.,1,UserEvent(Failed)

Propchange: asterisk/trunk/tests/rest_api/applications/channel-subscriptions/originate_to_dialplan/non_local_channels/configs/ast1/extensions.conf
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: asterisk/trunk/tests/rest_api/applications/channel-subscriptions/originate_to_dialplan/non_local_channels/configs/ast1/extensions.conf
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Propchange: asterisk/trunk/tests/rest_api/applications/channel-subscriptions/originate_to_dialplan/non_local_channels/configs/ast1/extensions.conf
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: asterisk/trunk/tests/rest_api/applications/channel-subscriptions/originate_to_dialplan/non_local_channels/configs/ast1/pjsip.conf
URL: http://svnview.digium.com/svn/testsuite/asterisk/trunk/tests/rest_api/applications/channel-subscriptions/originate_to_dialplan/non_local_channels/configs/ast1/pjsip.conf?view=auto&rev=6491
==============================================================================
--- asterisk/trunk/tests/rest_api/applications/channel-subscriptions/originate_to_dialplan/non_local_channels/configs/ast1/pjsip.conf (added)
+++ asterisk/trunk/tests/rest_api/applications/channel-subscriptions/originate_to_dialplan/non_local_channels/configs/ast1/pjsip.conf Fri Mar  6 13:45:17 2015
@@ -1,0 +1,26 @@
+[global]
+type=global
+debug=yes
+
+[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.1:5061\;transport=udp
+

Propchange: asterisk/trunk/tests/rest_api/applications/channel-subscriptions/originate_to_dialplan/non_local_channels/configs/ast1/pjsip.conf
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: asterisk/trunk/tests/rest_api/applications/channel-subscriptions/originate_to_dialplan/non_local_channels/configs/ast1/pjsip.conf
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Propchange: asterisk/trunk/tests/rest_api/applications/channel-subscriptions/originate_to_dialplan/non_local_channels/configs/ast1/pjsip.conf
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: asterisk/trunk/tests/rest_api/applications/channel-subscriptions/originate_to_dialplan/non_local_channels/test-config.yaml
URL: http://svnview.digium.com/svn/testsuite/asterisk/trunk/tests/rest_api/applications/channel-subscriptions/originate_to_dialplan/non_local_channels/test-config.yaml?view=auto&rev=6491
==============================================================================
--- asterisk/trunk/tests/rest_api/applications/channel-subscriptions/originate_to_dialplan/non_local_channels/test-config.yaml (added)
+++ asterisk/trunk/tests/rest_api/applications/channel-subscriptions/originate_to_dialplan/non_local_channels/test-config.yaml Fri Mar  6 13:45:17 2015
@@ -1,0 +1,223 @@
+testinfo:
+    summary: 'Test ARI origination of non-local channels to dialplan locations'
+    description: |
+        'This attempts to test originating non-local channels to the dialplan,
+        using all combinations of extension, context, priority, and label. The
+        originations go in the following order:
+        * Only extension specified
+        * Extension and priority specified
+        * Extension and label specified
+        * Extension, priority, and label specified
+        * Extension and numeric label specified
+        * Extension, priority, and numeric label specified
+        * All of the above repeated, this time specifying a context.
+
+        In total there are 12 originations performed. Each origination sets a
+        channel variable on the channel that specifies where we expect the
+        origination to end up. A user event is emitted from the dialplan to
+        indicate if the results meet expectations. Another user event is
+        emitted only for the last origination to indicate that the test is
+        complete and should be stopped. Additionally ensure that no ARI events
+        are received.'
+
+properties:
+    minversion: '13.2.0'
+    dependencies:
+        - python: autobahn.websocket
+        - python: requests
+        - python: twisted
+        - python: starpy
+        - python: pjsua
+        - asterisk: app_echo
+        - asterisk: app_userevent
+        - asterisk: res_ari_channels
+        - asterisk: res_pjsip
+    tags:
+        - ARI
+        - pjsip
+
+test-modules:
+    test-object:
+        config-section: originate-config
+        typename: ari.AriOriginateTestObject
+    modules:
+        -
+            config-section: pjsua-config
+            typename: phones.PjsuaPhoneController
+        -
+            config-section: pluggable-config
+            typename: pluggable_modules.EventActionModule
+
+pjsua-config:
+    transports:
+        -
+            name: 'local-ipv4-1'
+            bind: '127.0.0.1'
+            bindport: '5061'
+    accounts:
+        -
+            name: 'alice'
+            username: 'alice'
+            domain: '127.0.0.1'
+            transport: 'local-ipv4-1'
+
+originate-config:
+    apps: testsuite
+    test-iterations:
+        -
+            channelId: 'dummy'
+            endpoint: 'Local/dummy at default'
+            context: 'default'
+            extension: 'echo'
+            priority: '1'
+
+pluggable-config:
+    # Upon alice registering, originate the channels.
+    -
+        ami-events:
+            conditions:
+                match:
+                    Event: TestEvent
+                    State: 'AOR_CONTACT_ADDED'
+                    AOR: 'alice'
+            count: 1
+        ari-requests:
+            -
+                method: 'post'
+                uri: 'channels'
+                params:
+                    endpoint: 'PJSIP/alice'
+                    extension: 'test'
+                body: {'variables': {'location': 'test at default:1'}}
+            -
+                method: 'post'
+                uri: 'channels'
+                params:
+                    endpoint: 'PJSIP/alice'
+                    extension: 'test'
+                    priority: '3'
+                body: {'variables': {'location': 'test at default:3'}}
+            -
+                method: 'post'
+                uri: 'channels'
+                params:
+                    endpoint: 'PJSIP/alice'
+                    extension: 'test'
+                    label: 'dopey'
+                body: {'variables': {'location': 'test at default:5'}}
+            -
+                method: 'post'
+                uri: 'channels'
+                params:
+                    endpoint: 'PJSIP/alice'
+                    extension: 'test'
+                    priority: '5'
+                    label: 'doc'
+                body: {'variables': {'location': 'test at default:7'}}
+            -
+                method: 'post'
+                uri: 'channels'
+                params:
+                    endpoint: 'PJSIP/alice'
+                    extension: 'test'
+                    label: '9'
+                body: {'variables': {'location': 'test at default:9'}}
+            -
+                method: 'post'
+                uri: 'channels'
+                params:
+                    endpoint: 'PJSIP/alice'
+                    extension: 'test'
+                    priority: '5'
+                    label: '11'
+                body: {'variables': {'location': 'test at default:11'}}
+            -
+                method: 'post'
+                uri: 'channels'
+                params:
+                    endpoint: 'PJSIP/alice'
+                    context: 'grumpy'
+                    extension: 'test'
+                body: {'variables': {'location': 'test at grumpy:1'}}
+            -
+                method: 'post'
+                uri: 'channels'
+                params:
+                    endpoint: 'PJSIP/alice'
+                    context: 'grumpy'
+                    extension: 'test'
+                    priority: '3'
+                body: {'variables': {'location': 'test at grumpy:3'}}
+            -
+                method: 'post'
+                uri: 'channels'
+                params:
+                    endpoint: 'PJSIP/alice'
+                    context: 'grumpy'
+                    extension: 'test'
+                    label: 'sleepy'
+                body: {'variables': {'location': 'test at grumpy:5'}}
+            -
+                method: 'post'
+                uri: 'channels'
+                params:
+                    endpoint: 'PJSIP/alice'
+                    context: 'grumpy'
+                    extension: 'test'
+                    priority: '5'
+                    label: 'bashful'
+                body: {'variables': {'location': 'test at grumpy:7'}}
+            -
+                method: 'post'
+                uri: 'channels'
+                params:
+                    endpoint: 'PJSIP/alice'
+                    context: 'grumpy'
+                    extension: 'test'
+                    label: '9'
+                body: {'variables': {'location': 'test at grumpy:9'}}
+            -
+                method: 'post'
+                uri: 'channels'
+                params:
+                    endpoint: 'PJSIP/alice'
+                    context: 'grumpy'
+                    extension: 'test'
+                    priority: '5'
+                    label: '11'
+                body: {'variables': {'location': 'test at grumpy:11'}}
+    # Ensure no ARI events are received.
+    -
+        ari-events:
+            match:
+                type: '.*'
+            count: '0'
+    # Ensure we have the correct number of successful results.
+    -
+        ami-events:
+            conditions:
+                match:
+                    Event: 'UserEvent'
+                    UserEvent: 'Success'
+            count: '12'
+    # Ensure we have no failed results.
+    -
+        ami-events:
+            conditions:
+                match:
+                    Event: 'UserEvent'
+                    UserEvent: 'Failed'
+            count: '0'
+    # Ensure indication is received that all calls should have occurred. Then
+    # hang up the kick off dummy channel to end the test.
+    -
+        ami-events:
+            conditions:
+                match:
+                    Event: 'UserEvent'
+                    UserEvent: 'TestSuiteTestEnd'
+            count: '1'
+        ari-requests:
+            method: 'delete'
+            uri: 'channels/dummy'
+

Propchange: asterisk/trunk/tests/rest_api/applications/channel-subscriptions/originate_to_dialplan/non_local_channels/test-config.yaml
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: asterisk/trunk/tests/rest_api/applications/channel-subscriptions/originate_to_dialplan/non_local_channels/test-config.yaml
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Propchange: asterisk/trunk/tests/rest_api/applications/channel-subscriptions/originate_to_dialplan/non_local_channels/test-config.yaml
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: asterisk/trunk/tests/rest_api/applications/channel-subscriptions/originate_to_dialplan/tests.yaml
URL: http://svnview.digium.com/svn/testsuite/asterisk/trunk/tests/rest_api/applications/channel-subscriptions/originate_to_dialplan/tests.yaml?view=auto&rev=6491
==============================================================================
--- asterisk/trunk/tests/rest_api/applications/channel-subscriptions/originate_to_dialplan/tests.yaml (added)
+++ asterisk/trunk/tests/rest_api/applications/channel-subscriptions/originate_to_dialplan/tests.yaml Fri Mar  6 13:45:17 2015
@@ -1,0 +1,3 @@
+# Enter tests here in the order they should be considered for execution:
+tests:
+    - test: 'non_local_channels'

Propchange: asterisk/trunk/tests/rest_api/applications/channel-subscriptions/originate_to_dialplan/tests.yaml
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: asterisk/trunk/tests/rest_api/applications/channel-subscriptions/originate_to_dialplan/tests.yaml
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Propchange: asterisk/trunk/tests/rest_api/applications/channel-subscriptions/originate_to_dialplan/tests.yaml
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: asterisk/trunk/tests/rest_api/applications/channel-subscriptions/originate_to_other_stasis_app/local_channels/configs/ast1/extensions.conf
URL: http://svnview.digium.com/svn/testsuite/asterisk/trunk/tests/rest_api/applications/channel-subscriptions/originate_to_other_stasis_app/local_channels/configs/ast1/extensions.conf?view=auto&rev=6491
==============================================================================
--- asterisk/trunk/tests/rest_api/applications/channel-subscriptions/originate_to_other_stasis_app/local_channels/configs/ast1/extensions.conf (added)
+++ asterisk/trunk/tests/rest_api/applications/channel-subscriptions/originate_to_other_stasis_app/local_channels/configs/ast1/extensions.conf Fri Mar  6 13:45:17 2015
@@ -1,0 +1,10 @@
+[default]
+
+exten => do_stuff,1,NoOp()
+same => n,Answer()
+same => n,Playback(silence/1)
+same => n,Hangup()
+
+exten => h,1,NoOp()
+same => n,Hangup()
+

Propchange: asterisk/trunk/tests/rest_api/applications/channel-subscriptions/originate_to_other_stasis_app/local_channels/configs/ast1/extensions.conf
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: asterisk/trunk/tests/rest_api/applications/channel-subscriptions/originate_to_other_stasis_app/local_channels/configs/ast1/extensions.conf
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Propchange: asterisk/trunk/tests/rest_api/applications/channel-subscriptions/originate_to_other_stasis_app/local_channels/configs/ast1/extensions.conf
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: asterisk/trunk/tests/rest_api/applications/channel-subscriptions/originate_to_other_stasis_app/local_channels/configs/ast1/http.conf
URL: http://svnview.digium.com/svn/testsuite/asterisk/trunk/tests/rest_api/applications/channel-subscriptions/originate_to_other_stasis_app/local_channels/configs/ast1/http.conf?view=auto&rev=6491
==============================================================================
--- asterisk/trunk/tests/rest_api/applications/channel-subscriptions/originate_to_other_stasis_app/local_channels/configs/ast1/http.conf (added)
+++ asterisk/trunk/tests/rest_api/applications/channel-subscriptions/originate_to_other_stasis_app/local_channels/configs/ast1/http.conf Fri Mar  6 13:45:17 2015
@@ -1,0 +1,5 @@
+[general]
+enabled=yes
+bindaddr=127.0.0.1
+bindport=8088
+prefix=

Propchange: asterisk/trunk/tests/rest_api/applications/channel-subscriptions/originate_to_other_stasis_app/local_channels/configs/ast1/http.conf
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: asterisk/trunk/tests/rest_api/applications/channel-subscriptions/originate_to_other_stasis_app/local_channels/configs/ast1/http.conf
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Propchange: asterisk/trunk/tests/rest_api/applications/channel-subscriptions/originate_to_other_stasis_app/local_channels/configs/ast1/http.conf
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: asterisk/trunk/tests/rest_api/applications/channel-subscriptions/originate_to_other_stasis_app/local_channels/run-test
URL: http://svnview.digium.com/svn/testsuite/asterisk/trunk/tests/rest_api/applications/channel-subscriptions/originate_to_other_stasis_app/local_channels/run-test?view=auto&rev=6491
==============================================================================
--- asterisk/trunk/tests/rest_api/applications/channel-subscriptions/originate_to_other_stasis_app/local_channels/run-test (added)
+++ asterisk/trunk/tests/rest_api/applications/channel-subscriptions/originate_to_other_stasis_app/local_channels/run-test Fri Mar  6 13:45:17 2015
@@ -1,0 +1,292 @@
+#!/usr/bin/env python
+# vim: sw=3 et:
+"""A test that verifies ARI app local channel subscriptions
+
+This creates two ARI apps. A local channel is created by the first app where
+half is placed into the second app and the other half is placed into the
+dialplan. This verifies that the ARI events are received by the appropriate app
+and for the appropriate channel half.
+
+Copyright (C) 2015, 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 logging
+
+from twisted.internet import reactor
+
+sys.path.append("lib/python")
+
+from asterisk.test_case import TestCase
+from asterisk.ari import ARI, AriClientFactory
+
+LOGGER = logging.getLogger(__name__)
+
+USERPASS = ('testsuite', 'testsuite')
+
+
+class BaseReceiver(object):
+    """Base class for an ARI protocol receiver"""
+
+    def __init__(self, test_object):
+        """Constructor
+
+        Keyword Arguments:
+        test_object -- our TestCase instance
+        """
+        self.test_object = test_object
+
+    def on_ws_event(self, message):
+        """Handler for WebSocket events
+
+        Keyword Arguments:
+        message -- The WS event payload
+        """
+        msg_type = message.get('type')
+        callback = getattr(self, 'handle_{0}'.format(msg_type.lower()), None)
+        if callback:
+            callback(message)
+
+    def on_ws_open(self, protocol):
+        """Handler for WebSocket Client Protocol opened
+
+        Keyword Arguments:
+        protocol -- The WS Client protocol object
+        """
+        LOGGER.debug("{0}: WebSocket connection made {1}".format(self,
+                                                                 protocol))
+        self.test_object.protocol_connected(protocol)
+
+    def on_ws_closed(self, protocol):
+        """Handler for WebSocket Client Protocol closed
+
+        Keyword Arguments:
+        protocol -- The WS Client protocol object
+        """
+        LOGGER.debug("{0}: WebSocket connection closed {1}".format(self,
+                                                                   protocol))
+
+
+class App(BaseReceiver):
+    """A class that originates a channel
+
+    Originates a channel to a single Asterisk instance. The app name and
+    channel id are verified of any received ARI events and the test is failed
+    if they are not what is expected.
+    """
+
+    def __init__(self, ast, test_object, app_name):
+        """Constructor
+
+        Keyword Arguments:
+        ast         -- our call originating Asterisk instance
+        test_object -- our TestCase object
+        app_name    -- our name
+        """
+        super(App, self).__init__(test_object)
+        self.app_name = app_name
+        self.channels = []
+        self.ari_events = {'channeldialplan': 0, 'stasisstart': 0}
+        self.client = ARI(ast.host, userpass=USERPASS)
+        self.factory = AriClientFactory(receiver=self,
+                                        host=ast.host,
+                                        port=8088,
+                                        apps=app_name,
+                                        userpass=USERPASS)
+        self.factory.connect()
+
+    def originate_call(self):
+        """Make me a call!"""
+        if self.test_object.originate_channel is None:
+            LOGGER.warn('ARI channel origination info not found!')
+            return
+        LOGGER.debug("{0}: Originating channel".format(self.app_name))
+        self.client.post('channels', **self.test_object.originate_channel)
+
+    def event_failure(self, message, item):
+        """Fail the test"""
+        if item == "application":
+            msg = "{0} received event {1} for {2}."
+        if item == "channelid":
+            msg = "{0} received event {1} with unexpected channel {2}."
+        LOGGER.warn(msg.format(self.app_name, message['type'], message[item]))
+        self.test_object.set_passed(False)
+        self.test_object.hangup_all_channels()
+
+    def handle_channeldialplan(self, message):
+        """ChannelDialplan handler
+
+        Keyword Arguments:
+        message -- the JSON message
+        """
+        if message['application'] != self.app_name:
+            self.event_failure(message, "application")
+            return
+        if message['channel']['id'] != \
+                self.test_object.originate_channel['otherChannelId']:
+            self.event_failure(message, "channelid")
+            return
+
+        self.ari_events[message['type'].lower()] += 1
+
+    def handle_stasisend(self, message):
+        """StasisEnd handler
+
+        Keyword Arguments:
+        message -- the JSON message
+        """
+        channel_id = message['channel']['id']
+        self.channels.remove(channel_id)
+
+    def handle_stasisstart(self, message):
+        """StasisStart handler
+
+        Keyword Arguments:
+        message -- the JSON message
+        """
+        channel_id = message['channel']['id']
+        self.channels.append(channel_id)
+        if message['application'] != self.app_name:
+            self.event_failure(message, "application")
+            return
+        if message['channel']['id'] != \
+                self.test_object.originate_channel['channelId']:
+            self.event_failure(message, "channelid")
+            return
+
+        self.ari_events[message['type'].lower()] += 1
+
+    def hangup_channels(self):
+        """Hang up all tracked channels"""
+
+        # We will race between the StasisEnd event being processed
+        # from a BYE from the loaded systems and our attempt to
+        # delete the channel; ignore any HTTP errors
+        self.client.set_allow_errors(True)
+        for channel in self.channels:
+            LOGGER.debug('Hanging up {0}'.format(channel))
+            self.client.delete('channels', channel)
+        self.client.set_allow_errors(False)
+
+
+class OriginateToDifferentApp(TestCase):
+    """A class that manages this test
+
+    This creates ARI apps and will fail the test if the number of ARI events
+    doesn't match the number of expected.
+    """
+
+    def __init__(self):
+        """Constructor"""
+        super(OriginateToDifferentApp, self).__init__()
+        self.create_asterisk(count=1)
+        self.protocols = []
+        # Name of apps to create
+        self.app_names = ('AppA', 'AppB')
+        self.tmp_app_names = None
+        # App name and app object pairs
+        self.apps = {}
+        # The application that will originate the channel.
+        self.orig_src_app = self.app_names[0]
+        # The application that the originated channel will be put into.
+        self.orig_dst_app = self.app_names[1]
+        # Channel info to originate
+        self.originate_channel = {'endpoint': 'Local/do_stuff at default',
+                                  'channelId': 'StasisHalf',
+                                  'otherChannelId': 'DpHalf',
+                                  'app': self.orig_dst_app}
+        # Expected number of ARI events each app receives.
+        self.expected = {self.app_names[0]: {'channeldialplan': 0,
+                                             'stasisstart': 0},
+                         self.app_names[1]: {'channeldialplan': 6,
+                                             'stasisstart': 1}}
+
+    def run(self):
+        """Entry point for the twisted reactor"""
+        super(OriginateToDifferentApp, self).run()
+
+        self.tmp_app_names = list(self.app_names)
+        self.tmp_app_names.reverse()
+        name = self.tmp_app_names.pop()
+        # Create the first ARI app
+        self.apps[name] = App(self.ast[0], self, name)
+
+    def protocol_connected(self, protocol):
+        """Called by the various Apps on protocol connection
+
+        This will create subsequent apps after the first and be called upon
+        protocol connection for each.
+
+        Keyword Arguments:
+        protocol -- the twisted protocol that connected
+        """
+        self.protocols.append(protocol)
+
+        # Creating the apps immediately after one another leads to a random
+        # twisted error. So we create the next app upon the connection of the
+        # previously created app.
+        try:
+            name = self.tmp_app_names.pop()
+            self.apps[name] = App(self.ast[0], self, name)
+        except IndexError:
+            pass
+
+        if len(self.protocols) != 2:
+            return
+
+        LOGGER.info('Originating call!')
+        self.apps[self.orig_src_app].originate_call()
+        reactor.callLater(10, self.hangup_all_channels)
+
+    def hangup_all_channels(self):
+        """Hangs up all channels in each app"""
+        for app in self.apps.values():
+            app.hangup_channels()
+        for protocol in self.protocols:
+            protocol.transport.loseConnection()
+        self.check_results()
+        self.stop_reactor()
+
+    def check_results(self):
+        """Check the number of ARI events received by each app
+
+        This sets a failure if the number of received events doesn't match what
+        was expected.
+        """
+        for name in self.app_names:
+            diff = [k for k in self.expected[name]
+                    if self.apps[name].ari_events[k] != self.expected[name][k]]
+            if not diff:
+                continue
+
+            self.set_passed(False)
+            for event in diff:
+                LOGGER.warn("{0} received {1} {2} events; expected " \
+                        "{3}".format(name, self.apps[name].ari_events[event],
+                                     event, self.expected[name][event]))
+        # Any previously set failures will override this.
+        self.set_passed(True)
+
+
+def main():
+    """Main entry point for the test.
+
+    Returns:
+    0 on test pass
+    1 on test failure
+    """
+
+    test = OriginateToDifferentApp()
+    reactor.run()
+
+    if not test.passed:
+        return 1
+
+    return 0
+
+if __name__ == "__main__":
+    sys.exit(main())

Propchange: asterisk/trunk/tests/rest_api/applications/channel-subscriptions/originate_to_other_stasis_app/local_channels/run-test
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: asterisk/trunk/tests/rest_api/applications/channel-subscriptions/originate_to_other_stasis_app/local_channels/run-test
------------------------------------------------------------------------------
    svn:executable = *

Propchange: asterisk/trunk/tests/rest_api/applications/channel-subscriptions/originate_to_other_stasis_app/local_channels/run-test
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Propchange: asterisk/trunk/tests/rest_api/applications/channel-subscriptions/originate_to_other_stasis_app/local_channels/run-test
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: asterisk/trunk/tests/rest_api/applications/channel-subscriptions/originate_to_other_stasis_app/local_channels/test-config.yaml
URL: http://svnview.digium.com/svn/testsuite/asterisk/trunk/tests/rest_api/applications/channel-subscriptions/originate_to_other_stasis_app/local_channels/test-config.yaml?view=auto&rev=6491
==============================================================================
--- asterisk/trunk/tests/rest_api/applications/channel-subscriptions/originate_to_other_stasis_app/local_channels/test-config.yaml (added)
+++ asterisk/trunk/tests/rest_api/applications/channel-subscriptions/originate_to_other_stasis_app/local_channels/test-config.yaml Fri Mar  6 13:45:17 2015
@@ -1,0 +1,32 @@
+testinfo:
+    summary: |
+        "Test subscriptions when originating a local channel to another Stasis
+        app and dialplan."
+    description: |
+        "This test creates two Stasis apps each with a separate websocket. Once
+        both websockets are established a local channel is originated from AppA
+        with specifying app AppB. Local channel half 'StasisHalf' is placed
+        into Stasis app AppB while the other half 'DpHalf' is put into the
+        dialplan where it executes dialplan applications and eventually hangs
+        up.
+
+        This test verifies that both channel halves have been subscribed to by
+        the AppB Stasis app and AppB receives ARI events from both halves. It
+        ensures AppB receives ChannelDialplan events showing the dialplan
+        progression for 'DpHalf' and a StasisStart event for 'StasisHalf'. It
+        also ensures AppA does not receive any of the ARI events that is
+        expected for AppB to receive."
+
+properties:
+    minversion: '13.2.0'
+    dependencies:
+        - python: autobahn.websocket
+        - python: requests
+        - python: twisted
+        - asterisk: app_playback
+        - asterisk: res_ari_applications
+        - asterisk: res_ari_channels
+        - asterisk: res_pjsip
+    tags:
+        - ARI
+


[... 757 lines stripped ...]



More information about the asterisk-commits mailing list