[svn-commits] mmichelson: branch mmichelson/bridge-tests r3360 - in /asterisk/team/mmichels...

SVN commits to the Digium repositories svn-commits at lists.digium.com
Tue Jul 24 14:11:18 CDT 2012


Author: mmichelson
Date: Tue Jul 24 14:11:13 2012
New Revision: 3360

URL: http://svnview.digium.com/svn/testsuite?view=rev&rev=3360
Log:
Merge changes from trunk and reset automerge.


Added:
    asterisk/team/mmichelson/bridge-tests/contrib/sipp/
      - copied from r3357, asterisk/trunk/contrib/sipp/
    asterisk/team/mmichelson/bridge-tests/contrib/sipp/calls/
      - copied from r3357, asterisk/trunk/contrib/sipp/calls/
    asterisk/team/mmichelson/bridge-tests/contrib/sipp/calls/uac-blind-transfer.xml
      - copied unchanged from r3357, asterisk/trunk/contrib/sipp/calls/uac-blind-transfer.xml
    asterisk/team/mmichelson/bridge-tests/contrib/sipp/calls/uac-hangup.xml
      - copied unchanged from r3357, asterisk/trunk/contrib/sipp/calls/uac-hangup.xml
    asterisk/team/mmichelson/bridge-tests/contrib/sipp/calls/uac-no-hangup.xml
      - copied unchanged from r3357, asterisk/trunk/contrib/sipp/calls/uac-no-hangup.xml
    asterisk/team/mmichelson/bridge-tests/contrib/sipp/calls/uas-blind-transfer.xml
      - copied unchanged from r3357, asterisk/trunk/contrib/sipp/calls/uas-blind-transfer.xml
    asterisk/team/mmichelson/bridge-tests/contrib/sipp/calls/uas-hangup.xml
      - copied unchanged from r3357, asterisk/trunk/contrib/sipp/calls/uas-hangup.xml
    asterisk/team/mmichelson/bridge-tests/contrib/sipp/calls/uas-no-hangup.xml
      - copied unchanged from r3357, asterisk/trunk/contrib/sipp/calls/uas-no-hangup.xml
    asterisk/team/mmichelson/bridge-tests/contrib/sipp/calls/uas-redirect.xml
      - copied unchanged from r3357, asterisk/trunk/contrib/sipp/calls/uas-redirect.xml
    asterisk/team/mmichelson/bridge-tests/contrib/sipp/registration/
      - copied from r3357, asterisk/trunk/contrib/sipp/registration/
    asterisk/team/mmichelson/bridge-tests/contrib/sipp/registration/uac-register.xml
      - copied unchanged from r3357, asterisk/trunk/contrib/sipp/registration/uac-register.xml
    asterisk/team/mmichelson/bridge-tests/contrib/sipp/registration/uac-unregister.xml
      - copied unchanged from r3357, asterisk/trunk/contrib/sipp/registration/uac-unregister.xml
    asterisk/team/mmichelson/bridge-tests/contrib/sipp/subscription/
      - copied from r3357, asterisk/trunk/contrib/sipp/subscription/
    asterisk/team/mmichelson/bridge-tests/contrib/sipp/subscription/uac-subscribe-no-unsubscribe.xml
      - copied unchanged from r3357, asterisk/trunk/contrib/sipp/subscription/uac-subscribe-no-unsubscribe.xml
    asterisk/team/mmichelson/bridge-tests/contrib/sipp/subscription/uac-subscribe-unsubscribe.xml
      - copied unchanged from r3357, asterisk/trunk/contrib/sipp/subscription/uac-subscribe-unsubscribe.xml
    asterisk/team/mmichelson/bridge-tests/contrib/sipp/table_of_contents
      - copied unchanged from r3357, asterisk/trunk/contrib/sipp/table_of_contents
    asterisk/team/mmichelson/bridge-tests/tests/channels/SIP/acl_call/
      - copied from r3357, asterisk/trunk/tests/channels/SIP/acl_call/
    asterisk/team/mmichelson/bridge-tests/tests/channels/SIP/acl_call/configs/
      - copied from r3357, asterisk/trunk/tests/channels/SIP/acl_call/configs/
    asterisk/team/mmichelson/bridge-tests/tests/channels/SIP/acl_call/configs/ast1/
      - copied from r3357, asterisk/trunk/tests/channels/SIP/acl_call/configs/ast1/
    asterisk/team/mmichelson/bridge-tests/tests/channels/SIP/acl_call/configs/ast1/acl.conf
      - copied unchanged from r3357, asterisk/trunk/tests/channels/SIP/acl_call/configs/ast1/acl.conf
    asterisk/team/mmichelson/bridge-tests/tests/channels/SIP/acl_call/configs/ast1/extconfig.conf
      - copied unchanged from r3357, asterisk/trunk/tests/channels/SIP/acl_call/configs/ast1/extconfig.conf
    asterisk/team/mmichelson/bridge-tests/tests/channels/SIP/acl_call/configs/ast1/extensions.conf
      - copied unchanged from r3357, asterisk/trunk/tests/channels/SIP/acl_call/configs/ast1/extensions.conf
    asterisk/team/mmichelson/bridge-tests/tests/channels/SIP/acl_call/configs/ast1/modules.conf
      - copied unchanged from r3357, asterisk/trunk/tests/channels/SIP/acl_call/configs/ast1/modules.conf
    asterisk/team/mmichelson/bridge-tests/tests/channels/SIP/acl_call/configs/ast1/res_config_sqlite3.conf
      - copied unchanged from r3357, asterisk/trunk/tests/channels/SIP/acl_call/configs/ast1/res_config_sqlite3.conf
    asterisk/team/mmichelson/bridge-tests/tests/channels/SIP/acl_call/configs/ast1/sip.conf
      - copied unchanged from r3357, asterisk/trunk/tests/channels/SIP/acl_call/configs/ast1/sip.conf
    asterisk/team/mmichelson/bridge-tests/tests/channels/SIP/acl_call/realtime.sqlite3
      - copied unchanged from r3357, asterisk/trunk/tests/channels/SIP/acl_call/realtime.sqlite3
    asterisk/team/mmichelson/bridge-tests/tests/channels/SIP/acl_call/run-test
      - copied unchanged from r3357, asterisk/trunk/tests/channels/SIP/acl_call/run-test
    asterisk/team/mmichelson/bridge-tests/tests/channels/SIP/acl_call/test-config.yaml
      - copied unchanged from r3357, asterisk/trunk/tests/channels/SIP/acl_call/test-config.yaml
    asterisk/team/mmichelson/bridge-tests/tests/funcs/
      - copied from r3357, asterisk/trunk/tests/funcs/
    asterisk/team/mmichelson/bridge-tests/tests/funcs/func_jitterbuffer/
      - copied from r3357, asterisk/trunk/tests/funcs/func_jitterbuffer/
    asterisk/team/mmichelson/bridge-tests/tests/funcs/func_jitterbuffer/configs/
      - copied from r3357, asterisk/trunk/tests/funcs/func_jitterbuffer/configs/
    asterisk/team/mmichelson/bridge-tests/tests/funcs/func_jitterbuffer/configs/ast1/
      - copied from r3357, asterisk/trunk/tests/funcs/func_jitterbuffer/configs/ast1/
    asterisk/team/mmichelson/bridge-tests/tests/funcs/func_jitterbuffer/configs/ast1/extensions.conf
      - copied unchanged from r3357, asterisk/trunk/tests/funcs/func_jitterbuffer/configs/ast1/extensions.conf
    asterisk/team/mmichelson/bridge-tests/tests/funcs/func_jitterbuffer/configs/ast1/sip.conf
      - copied unchanged from r3357, asterisk/trunk/tests/funcs/func_jitterbuffer/configs/ast1/sip.conf
    asterisk/team/mmichelson/bridge-tests/tests/funcs/func_jitterbuffer/run-test
      - copied unchanged from r3357, asterisk/trunk/tests/funcs/func_jitterbuffer/run-test
    asterisk/team/mmichelson/bridge-tests/tests/funcs/func_jitterbuffer/talking.ulaw
      - copied unchanged from r3357, asterisk/trunk/tests/funcs/func_jitterbuffer/talking.ulaw
    asterisk/team/mmichelson/bridge-tests/tests/funcs/func_jitterbuffer/test-config.yaml
      - copied unchanged from r3357, asterisk/trunk/tests/funcs/func_jitterbuffer/test-config.yaml
    asterisk/team/mmichelson/bridge-tests/tests/funcs/func_presencestate/
      - copied from r3357, asterisk/trunk/tests/funcs/func_presencestate/
    asterisk/team/mmichelson/bridge-tests/tests/funcs/func_presencestate/configs/
      - copied from r3357, asterisk/trunk/tests/funcs/func_presencestate/configs/
    asterisk/team/mmichelson/bridge-tests/tests/funcs/func_presencestate/configs/ast1/
      - copied from r3357, asterisk/trunk/tests/funcs/func_presencestate/configs/ast1/
    asterisk/team/mmichelson/bridge-tests/tests/funcs/func_presencestate/configs/ast1/extensions.conf
      - copied unchanged from r3357, asterisk/trunk/tests/funcs/func_presencestate/configs/ast1/extensions.conf
    asterisk/team/mmichelson/bridge-tests/tests/funcs/func_presencestate/run-test
      - copied unchanged from r3357, asterisk/trunk/tests/funcs/func_presencestate/run-test
    asterisk/team/mmichelson/bridge-tests/tests/funcs/func_presencestate/test-config.yaml
      - copied unchanged from r3357, asterisk/trunk/tests/funcs/func_presencestate/test-config.yaml
    asterisk/team/mmichelson/bridge-tests/tests/funcs/func_srv/
      - copied from r3357, asterisk/trunk/tests/funcs/func_srv/
    asterisk/team/mmichelson/bridge-tests/tests/funcs/func_srv/configs/
      - copied from r3357, asterisk/trunk/tests/funcs/func_srv/configs/
    asterisk/team/mmichelson/bridge-tests/tests/funcs/func_srv/configs/ast1/
      - copied from r3357, asterisk/trunk/tests/funcs/func_srv/configs/ast1/
    asterisk/team/mmichelson/bridge-tests/tests/funcs/func_srv/configs/ast1/extensions.conf
      - copied unchanged from r3357, asterisk/trunk/tests/funcs/func_srv/configs/ast1/extensions.conf
    asterisk/team/mmichelson/bridge-tests/tests/funcs/func_srv/run-test
      - copied unchanged from r3357, asterisk/trunk/tests/funcs/func_srv/run-test
    asterisk/team/mmichelson/bridge-tests/tests/funcs/func_srv/test-config.yaml
      - copied unchanged from r3357, asterisk/trunk/tests/funcs/func_srv/test-config.yaml
    asterisk/team/mmichelson/bridge-tests/tests/funcs/tests.yaml
      - copied unchanged from r3357, asterisk/trunk/tests/funcs/tests.yaml
    asterisk/team/mmichelson/bridge-tests/tests/iax2/acl_call/
      - copied from r3357, asterisk/trunk/tests/iax2/acl_call/
    asterisk/team/mmichelson/bridge-tests/tests/iax2/acl_call/configs/
      - copied from r3357, asterisk/trunk/tests/iax2/acl_call/configs/
    asterisk/team/mmichelson/bridge-tests/tests/iax2/acl_call/configs/ast1/
      - copied from r3357, asterisk/trunk/tests/iax2/acl_call/configs/ast1/
    asterisk/team/mmichelson/bridge-tests/tests/iax2/acl_call/configs/ast1/acl.conf
      - copied unchanged from r3357, asterisk/trunk/tests/iax2/acl_call/configs/ast1/acl.conf
    asterisk/team/mmichelson/bridge-tests/tests/iax2/acl_call/configs/ast1/extconfig.conf
      - copied unchanged from r3357, asterisk/trunk/tests/iax2/acl_call/configs/ast1/extconfig.conf
    asterisk/team/mmichelson/bridge-tests/tests/iax2/acl_call/configs/ast1/extensions.conf
      - copied unchanged from r3357, asterisk/trunk/tests/iax2/acl_call/configs/ast1/extensions.conf
    asterisk/team/mmichelson/bridge-tests/tests/iax2/acl_call/configs/ast1/iax.conf
      - copied unchanged from r3357, asterisk/trunk/tests/iax2/acl_call/configs/ast1/iax.conf
    asterisk/team/mmichelson/bridge-tests/tests/iax2/acl_call/configs/ast1/modules.conf
      - copied unchanged from r3357, asterisk/trunk/tests/iax2/acl_call/configs/ast1/modules.conf
    asterisk/team/mmichelson/bridge-tests/tests/iax2/acl_call/configs/ast1/res_config_sqlite3.conf
      - copied unchanged from r3357, asterisk/trunk/tests/iax2/acl_call/configs/ast1/res_config_sqlite3.conf
    asterisk/team/mmichelson/bridge-tests/tests/iax2/acl_call/realtime.sqlite3
      - copied unchanged from r3357, asterisk/trunk/tests/iax2/acl_call/realtime.sqlite3
    asterisk/team/mmichelson/bridge-tests/tests/iax2/acl_call/run-test
      - copied unchanged from r3357, asterisk/trunk/tests/iax2/acl_call/run-test
    asterisk/team/mmichelson/bridge-tests/tests/iax2/acl_call/test-config.yaml
      - copied unchanged from r3357, asterisk/trunk/tests/iax2/acl_call/test-config.yaml
    asterisk/team/mmichelson/bridge-tests/tests/manager/acl-login/
      - copied from r3357, asterisk/trunk/tests/manager/acl-login/
    asterisk/team/mmichelson/bridge-tests/tests/manager/acl-login/configs/
      - copied from r3357, asterisk/trunk/tests/manager/acl-login/configs/
    asterisk/team/mmichelson/bridge-tests/tests/manager/acl-login/configs/ast1/
      - copied from r3357, asterisk/trunk/tests/manager/acl-login/configs/ast1/
    asterisk/team/mmichelson/bridge-tests/tests/manager/acl-login/configs/ast1/acl.conf
      - copied unchanged from r3357, asterisk/trunk/tests/manager/acl-login/configs/ast1/acl.conf
    asterisk/team/mmichelson/bridge-tests/tests/manager/acl-login/configs/ast1/manager.conf
      - copied unchanged from r3357, asterisk/trunk/tests/manager/acl-login/configs/ast1/manager.conf
    asterisk/team/mmichelson/bridge-tests/tests/manager/acl-login/run-test
      - copied unchanged from r3357, asterisk/trunk/tests/manager/acl-login/run-test
    asterisk/team/mmichelson/bridge-tests/tests/manager/acl-login/test-config.yaml
      - copied unchanged from r3357, asterisk/trunk/tests/manager/acl-login/test-config.yaml
Modified:
    asterisk/team/mmichelson/bridge-tests/   (props changed)
    asterisk/team/mmichelson/bridge-tests/lib/python/asterisk/TestCase.py
    asterisk/team/mmichelson/bridge-tests/lib/python/asterisk/ami.py
    asterisk/team/mmichelson/bridge-tests/lib/python/asterisk/cdr.py
    asterisk/team/mmichelson/bridge-tests/lib/python/asterisk/cel.py
    asterisk/team/mmichelson/bridge-tests/sample-yaml/ami-config.yaml.sample
    asterisk/team/mmichelson/bridge-tests/tests/cdr/ForkCdrModule.py
    asterisk/team/mmichelson/bridge-tests/tests/channels/SIP/hangupcause/configs/ast2/extensions.conf
    asterisk/team/mmichelson/bridge-tests/tests/channels/SIP/sip_attended_transfer/configs/ast1/sip.conf
    asterisk/team/mmichelson/bridge-tests/tests/channels/SIP/sip_attended_transfer/run-test
    asterisk/team/mmichelson/bridge-tests/tests/channels/SIP/sip_attended_transfer/test-config.yaml
    asterisk/team/mmichelson/bridge-tests/tests/channels/SIP/sip_custom_presence/multiple_state_change/run-test
    asterisk/team/mmichelson/bridge-tests/tests/channels/SIP/sip_custom_presence/nominal_state_change/run-test
    asterisk/team/mmichelson/bridge-tests/tests/channels/SIP/sip_custom_presence/non_digium_state_change/run-test
    asterisk/team/mmichelson/bridge-tests/tests/channels/SIP/sip_custom_presence/resubscribe/run-test
    asterisk/team/mmichelson/bridge-tests/tests/channels/SIP/tests.yaml
    asterisk/team/mmichelson/bridge-tests/tests/iax2/hangupcause/configs/ast2/extensions.conf
    asterisk/team/mmichelson/bridge-tests/tests/iax2/tests.yaml
    asterisk/team/mmichelson/bridge-tests/tests/manager/tests.yaml
    asterisk/team/mmichelson/bridge-tests/tests/tests.yaml

Propchange: asterisk/team/mmichelson/bridge-tests/
------------------------------------------------------------------------------
    automerge = *

Propchange: asterisk/team/mmichelson/bridge-tests/
------------------------------------------------------------------------------
--- svnmerge-integrated (original)
+++ svnmerge-integrated Tue Jul 24 14:11:13 2012
@@ -1,1 +1,1 @@
-/asterisk/trunk:1-3320
+/asterisk/trunk:1-3359

Modified: asterisk/team/mmichelson/bridge-tests/lib/python/asterisk/TestCase.py
URL: http://svnview.digium.com/svn/testsuite/asterisk/team/mmichelson/bridge-tests/lib/python/asterisk/TestCase.py?view=diff&rev=3360&r1=3359&r2=3360
==============================================================================
--- asterisk/team/mmichelson/bridge-tests/lib/python/asterisk/TestCase.py (original)
+++ asterisk/team/mmichelson/bridge-tests/lib/python/asterisk/TestCase.py Tue Jul 24 14:11:13 2012
@@ -340,6 +340,7 @@
                 except twisted.internet.error.ReactorNotRunning:
                     # Something stopped it between our checks - at least we're stopped
                     pass
+            return result
         if not self._stopping:
             self._stopping = True
             df = self.__stop_asterisk()

Modified: asterisk/team/mmichelson/bridge-tests/lib/python/asterisk/ami.py
URL: http://svnview.digium.com/svn/testsuite/asterisk/team/mmichelson/bridge-tests/lib/python/asterisk/ami.py?view=diff&rev=3360&r1=3359&r2=3360
==============================================================================
--- asterisk/team/mmichelson/bridge-tests/lib/python/asterisk/ami.py (original)
+++ asterisk/team/mmichelson/bridge-tests/lib/python/asterisk/ami.py Tue Jul 24 14:11:13 2012
@@ -8,7 +8,7 @@
 logger = logging.getLogger(__name__)
 
 class AMIEventInstance(object):
-    ''' 
+    '''
     Base class for specific instances of AMI event observers
 
     This handles common elements for both headermatch and callback
@@ -149,6 +149,57 @@
         self.test_object.set_passed(self.passed)
         return callback_param
 
+class AMIOrderedHeaderMatchInstance(AMIEventInstance):
+    '''
+    A subclass of AMIEventInstance that operates by matching headers of
+    AMI events to expected values. If a header does not match its expected
+    value, then the test will fail. This differs from AMIHeaderMatchInstance
+    in that the order of specification is used to define an expected order
+    for the events to arrive in which must be matched in order for the test
+    to pass.
+    '''
+    def __init__(self, instance_config, test_object):
+        super(AMIOrderedHeaderMatchInstance, self).__init__(instance_config, test_object)
+        logger.debug("Initializing an AMIOrderedHeaderMatchInstance")
+        self.match_index = 0
+        self.match_requirements = []
+        self.nonmatch_requirements = []
+        for instance in instance_config['requirements']:
+            self.match_requirements.append(
+                    instance.get('match', {}))
+            self.nonmatch_requirements.append(
+                    instance.get('nomatch', {}))
+
+    def event_callback(self, ami, event):
+        if self.match_index >= len(self.match_requirements):
+            logger.debug("Event received and not defined: %s" % event)
+            return
+
+        for k,v in self.match_requirements[self.match_index].items():
+            if not re.match(v, event.get(k.lower())):
+                logger.warning("Requirement %s: %s does not match %s: %s in event" %
+                        (k, v, k, event.get(k.lower())))
+                self.passed = False
+            else:
+                logger.debug("Requirement %s: %s matches %s: %s in event" %
+                        (k, v, k, event.get(k.lower())))
+
+        for k,v in self.nonmatch_requirements[self.match_index].items():
+            if re.match(v, event.get(k.lower(), '')):
+                logger.warning("Requirement %s: %s matches %s: %s in event" %
+                        (k, v, k, event.get(k.lower(), '')))
+                self.passed = False
+            else:
+                logger.debug("Requirement %s: %s does not match %s: %s in event" %
+                        (k, v, k, event.get(k.lower(), '')))
+
+        self.match_index += 1
+        return (ami, event)
+
+    def check_result(self, callback_param):
+        self.test_object.set_passed(self.passed)
+        return callback_param
+
 class AMICallbackInstance(AMIEventInstance):
     '''
     Subclass of AMIEventInstance that operates by calling a user-defined
@@ -178,6 +229,9 @@
         if instance_type == "headermatch":
             logger.debug("instance type is 'headermatch'")
             return AMIHeaderMatchInstance(instance_config, test_object)
+        elif instance_type == "orderedheadermatch":
+            logger.debug("instance type is 'orderedheadermatch'")
+            return AMIOrderedHeaderMatchInstance(instance_config, test_object)
         elif instance_type == "callback":
             logger.debug("instance type is 'callback'")
             return AMICallbackInstance(instance_config, test_object)

Modified: asterisk/team/mmichelson/bridge-tests/lib/python/asterisk/cdr.py
URL: http://svnview.digium.com/svn/testsuite/asterisk/team/mmichelson/bridge-tests/lib/python/asterisk/cdr.py?view=diff&rev=3360&r1=3359&r2=3360
==============================================================================
--- asterisk/team/mmichelson/bridge-tests/lib/python/asterisk/cdr.py (original)
+++ asterisk/team/mmichelson/bridge-tests/lib/python/asterisk/cdr.py Tue Jul 24 14:11:13 2012
@@ -47,16 +47,7 @@
                 dict_record = dict((k, None) for k in AsteriskCSVCDRLine.fields)
                 dict_record.update(csv_line)
 
-                self.cdr_records[file_name].append(AsteriskCSVCDRLine(
-                    accountcode=dict_record['accountcode'], source=dict_record['source'],
-                    destination=dict_record['destination'], dcontext=dict_record['dcontext'],
-                    callerid=dict_record['callerid'], channel=dict_record['channel'],
-                    dchannel=dict_record['dchannel'], lastapp=dict_record['lastapp'],
-                    lastarg=dict_record['lastarg'], start=dict_record['start'],
-                    answer=dict_record['answer'], end=dict_record['end'],
-                    duration=dict_record['duration'], billsec=dict_record['billsec'],
-                    disposition=dict_record['disposition'], amaflags=dict_record['amaflags'],
-                    uniqueid=dict_record['uniqueid'], userfield=dict_record['userfield']))
+                self.cdr_records[file_name].append(AsteriskCSVCDRLine(**dict_record))
 
         # Hook ourselves onto the test object
         test_object.register_stop_observer(self._check_cdr_records)

Modified: asterisk/team/mmichelson/bridge-tests/lib/python/asterisk/cel.py
URL: http://svnview.digium.com/svn/testsuite/asterisk/team/mmichelson/bridge-tests/lib/python/asterisk/cel.py?view=diff&rev=3360&r1=3359&r2=3360
==============================================================================
--- asterisk/team/mmichelson/bridge-tests/lib/python/asterisk/cel.py (original)
+++ asterisk/team/mmichelson/bridge-tests/lib/python/asterisk/cel.py Tue Jul 24 14:11:13 2012
@@ -18,7 +18,70 @@
 import logging
 import time
 
-logger = logging.getLogger(__name__)
+LOGGER = logging.getLogger(__name__)
+
+class CELModule(object):
+    ''' A module that checks a test for expected CEL results '''
+
+
+    def __init__(self, module_config, test_object):
+        ''' Constructor
+
+        Parameters:
+        module_config The yaml loaded configuration for the CEL Module
+        test_object A concrete implementation of TestClass
+        '''
+        self.test_object = test_object
+
+        # Build our expected CEL records
+        self.cel_records = {}
+        for record in module_config:
+            file_name = record['file']
+            if file_name not in self.cel_records:
+                self.cel_records[file_name] = []
+            for csv_line in record['lines']:
+                # Set the record to the default fields, then update with what
+                # was passed in to us
+                dict_record = dict((k, None) for k in AsteriskCSVCELLine.fields)
+                dict_record.update(csv_line)
+
+                self.cel_records[file_name].append(AsteriskCSVCELLine(**dict_record))
+
+        # Hook ourselves onto the test object
+        test_object.register_stop_observer(self._check_cel_records)
+
+    def _check_cel_records(self, callback_param):
+        ''' A deferred callback method that is called by the TestCase
+        derived object when all Asterisk instances have stopped
+
+        Parameters:
+        callback_param
+        '''
+        LOGGER.debug("Checking CEL records...")
+        self.match_cels()
+        return callback_param
+
+
+    def match_cels(self):
+        ''' Called when all instances of Asterisk have exited.  Derived
+        classes can override this to provide their own behavior for CEL
+        matching.
+        '''
+        expectations_met = True
+        for key in self.cel_records:
+            cel_expect = AsteriskCSVCEL(records=self.cel_records[key])
+            cel_file = AsteriskCSVCEL(fn="%s/%s/cel-custom/%s.csv" %
+                (self.test_object.ast[0].base,
+                 self.test_object.ast[0].directories['astlogdir'],
+                 key))
+            if cel_expect.match(cel_file):
+                LOGGER.debug("%s.csv - CEL results met expectations" % key)
+            else:
+                LOGGER.error("%s.csv - CEL results did not meet expectations.  Test Failed." % key)
+                expectations_met = False
+
+        self.test_object.set_passed(expectations_met)
+
 
 class AsteriskCSVCELLine(astcsv.AsteriskCSVLine):
     "A single Asterisk Call Event Log record"

Modified: asterisk/team/mmichelson/bridge-tests/sample-yaml/ami-config.yaml.sample
URL: http://svnview.digium.com/svn/testsuite/asterisk/team/mmichelson/bridge-tests/sample-yaml/ami-config.yaml.sample?view=diff&rev=3360&r1=3359&r2=3360
==============================================================================
--- asterisk/team/mmichelson/bridge-tests/sample-yaml/ami-config.yaml.sample (original)
+++ asterisk/team/mmichelson/bridge-tests/sample-yaml/ami-config.yaml.sample Tue Jul 24 14:11:13 2012
@@ -47,6 +47,46 @@
         # must occur 3 or more times.
         count: '>3'
     -
+        # The "orderedheadermatch" type indicates that when a condition match is
+        # made, there is a list of ordered requirements. The first time the match
+        # occurs, the first requirement in the list is expected and if it doesn't
+        # match, then the test is failed. If it succeeded, it will expect the
+        # second requirement in the requirements list and it will continue until
+        # either a mismatch occurs and the test fails or the list or requirements
+        # is exhausted.
+        type: 'orderedheadermatch'
+
+        # Conditions are handled exactly the same as for "headermatch" types.
+        conditions:
+            match:
+                Event: 'Bridge'
+                BridgeState: 'Link'
+            nomatch:
+                CallerID1: 'Bob.*'
+
+        # If the parameters in the "conditions" section match, then
+        # the first item in the list in the "requirements" section will be checked.
+        # If any of the requirements should fail, then the test has failed. If they
+        # all succeed, the next time the event is handled the next requirement list
+        # item will be used instead. If a condition matches and the requirements
+        # list is already exhausted, then the event will be allowed without
+        # affecting success or failure of the test.
+        requirements:
+            -
+                match:
+                    uniqueid1: '1234.*'
+                    BridgeType: 'core'
+            -
+                match:
+                    uniqueid1: '5678.*'
+                    BridgeType: 'core'
+
+        # The number of times this event is expected. If just a number is
+        # provided, then the event must happen exactly that number of times.
+        # Normally, this should probably be the number of requirements specified
+        # above.
+        count: '2'
+	-
         # The "callback" type indicates that when event conditions are fulfilled
         # A callback should be called into. This is useful if pass/fail conditions
         # depend on more than just having specific headers match what is expected.

Modified: asterisk/team/mmichelson/bridge-tests/tests/cdr/ForkCdrModule.py
URL: http://svnview.digium.com/svn/testsuite/asterisk/team/mmichelson/bridge-tests/tests/cdr/ForkCdrModule.py?view=diff&rev=3360&r1=3359&r2=3360
==============================================================================
--- asterisk/team/mmichelson/bridge-tests/tests/cdr/ForkCdrModule.py (original)
+++ asterisk/team/mmichelson/bridge-tests/tests/cdr/ForkCdrModule.py Tue Jul 24 14:11:13 2012
@@ -12,6 +12,7 @@
 
 sys.path.append("lib/python")
 from cdr import CDRModule
+from cdr import AsteriskCSVCDR
 
 logger = logging.getLogger(__name__)
 

Modified: asterisk/team/mmichelson/bridge-tests/tests/channels/SIP/hangupcause/configs/ast2/extensions.conf
URL: http://svnview.digium.com/svn/testsuite/asterisk/team/mmichelson/bridge-tests/tests/channels/SIP/hangupcause/configs/ast2/extensions.conf?view=diff&rev=3360&r1=3359&r2=3360
==============================================================================
--- asterisk/team/mmichelson/bridge-tests/tests/channels/SIP/hangupcause/configs/ast2/extensions.conf (original)
+++ asterisk/team/mmichelson/bridge-tests/tests/channels/SIP/hangupcause/configs/ast2/extensions.conf Tue Jul 24 14:11:13 2012
@@ -8,8 +8,8 @@
 exten => 3333,1,Set(TEST=local)
 exten => 3333,2,Dial(local/3333 at isolated)
 
-exten => _XXXX,3,Set(ARRAY(C1,C2)=${HASHKEYS(HANGUPCAUSE)})
-exten => _XXXX,4,UserEvent(HUCStatus,status: ${TEST},chan1: ${C1},chan2: ${C2},res1: ${HASH(HANGUPCAUSE,${C1})},res2: ${HASH(HANGUPCAUSE,${C2})},hangupcause: ${HANGUPCAUSE})
+exten => _XXXX,3,Set(ARRAY(C1,C2)=${HANGUPCAUSE_KEYS()})
+exten => _XXXX,4,UserEvent(HUCStatus,status: ${TEST},chan1: ${C1},chan2: ${C2},res1: ${HANGUPCAUSE(${C1},tech)},res2: ${HANGUPCAUSE(${C2},tech)},hangupcause: ${HANGUPCAUSE})
 
 [isolated]
 exten => 3333,1,Dial(sip/bob&sip/alice)

Modified: asterisk/team/mmichelson/bridge-tests/tests/channels/SIP/sip_attended_transfer/configs/ast1/sip.conf
URL: http://svnview.digium.com/svn/testsuite/asterisk/team/mmichelson/bridge-tests/tests/channels/SIP/sip_attended_transfer/configs/ast1/sip.conf?view=diff&rev=3360&r1=3359&r2=3360
==============================================================================
--- asterisk/team/mmichelson/bridge-tests/tests/channels/SIP/sip_attended_transfer/configs/ast1/sip.conf (original)
+++ asterisk/team/mmichelson/bridge-tests/tests/channels/SIP/sip_attended_transfer/configs/ast1/sip.conf Tue Jul 24 14:11:13 2012
@@ -4,26 +4,14 @@
 [end_a]
 context=transfertest
 type=friend
-host=127.0.0.1
-port=5065
 insecure=invite
-disallow=all
-allow=ulaw
 
 [end_b]
-context=transfertest
 type=friend
-host=127.0.0.1
-port=5066
+host=dynamic
 insecure=invite
-disallow=all
-allow=ulaw
 
 [end_c]
-context=transfertest
 type=friend
-host=127.0.0.1
-port=5067
+host=dynamic
 insecure=invite
-disallow=all
-allow=ulaw

Modified: asterisk/team/mmichelson/bridge-tests/tests/channels/SIP/sip_attended_transfer/run-test
URL: http://svnview.digium.com/svn/testsuite/asterisk/team/mmichelson/bridge-tests/tests/channels/SIP/sip_attended_transfer/run-test?view=diff&rev=3360&r1=3359&r2=3360
==============================================================================
--- asterisk/team/mmichelson/bridge-tests/tests/channels/SIP/sip_attended_transfer/run-test (original)
+++ asterisk/team/mmichelson/bridge-tests/tests/channels/SIP/sip_attended_transfer/run-test Tue Jul 24 14:11:13 2012
@@ -9,144 +9,130 @@
 
 import sys
 import os
-import signal
-import subprocess
-from twisted.application import service, internet
-from twisted.internet import reactor, defer
-from starpy import manager
+from twisted.internet import reactor
+import pjsua as pj
+import threading
 
 sys.path.append("lib/python")
-from asterisk.asterisk import Asterisk
+from asterisk.TestCase import TestCase
+import logging
 
-workingdir = "sip_attended_transfer"
-testdir = "tests/%s" % workingdir
+LOGGER = logging.getLogger(__name__)
 
-class AttTransferTest:
+class AutoAnswerCallback(pj.AccountCallback):
+    def __init__(self, account):
+        self.sem = threading.Semaphore(0)
+        pj.AccountCallback.__init__(self, account)
+
+    def wait(self):
+        if self.sem:
+            self.sem.acquire()
+
+    def on_reg_state(self):
+        if self.sem:
+            if self.account.info().reg_status >= 200:
+                self.sem.release()
+                self.sem = None
+
+    def on_incoming_call(self, call):
+        call.answer(200)
+
+class AttTransferTest(TestCase):
     def __init__(self):
-        self.last_step = ""
-        self.passed = False
-
-        reactor.callWhenRunning(self.run)
-
-        self.ast1 = Asterisk(base=workingdir)
-        self.ast1.install_configs("%s/configs/ast1" % (testdir))
-
-    def readResult(self):
-        self.logLastStep("Reading results")
-        self.ast1.cli_exec("core show locks")   # get lock output in case of deadlock before tearing down.
-        self.ast1.cli_exec("core show channels")# if channels are still up for some reason, we want to know that as well
-        self.stopProcesses()
-
-        if self.passed == True:
-            print 'SIP Attended Transfer Test Passed!'
-        else:
-            print 'SIP Attended Transfer Test Failed'
-
-        if reactor.running:
-            print "Stopping Reactor ..."
-            reactor.stop()
-
-    def amiOnConnect(self, ami):
-        self.logLastStep("Connected to the AMI")
-        self.ami = ami
-
-    def amiLoginError(self, ami):
-        self.logLastStep("AMI login failed")
-        reactor.callLater(1, self.readResult)
-
-    def amiLogin(self):
-        self.logLastStep("Logging in to the AMI")
-        self.ami_factory = manager.AMIFactory("user", "mysecret")
-        self.ami_factory.login('127.0.0.1', 5038).addCallbacks(self.amiOnConnect, self.amiLoginError)
-
-    def checkBridgeResult(self, result):
-        print 'Result', result
-        if "bridgedchannel" not in result[0]:
-            print "bridgedchannel was not a valid key."
-        elif result[0]['bridgedchannel'] == 'SIP/end_b-00000001':
-            self.passed = True
-
-        if "link" not in result[0]:
-            print "'link' was not a valid key."
-        elif result[0]['link'] == 'SIP/end_b-00000001': # check link for older versions of asterisk
-            self.passed = True
-
-        if self.passed == True:
-            self.logLastStep("Found Bridge!!!")
-        else:
-            self.logLastStep("Detecting Bridge failed")
-
-    def checkBridgeError(self, reason):
-        print reason.getTraceback()
-        self.logLastStep("Checking Bridge failed.  Channel did not exist.")
-        reactor.callLater(1, self.readResult)
-
-    def amiCheckBridge(self):
-        self.logLastStep("Get AMI results")
-        self.ami.status('SIP/end_c-00000003').addCallbacks(self.checkBridgeResult, self.checkBridgeError)
-
-    def aCallB(self):
-        self.logLastStep("A Calling B")
-        self.pja.stdin.write("m\n")
-        self.pja.stdin.write("sip:call_b at 127.0.0.1:5060\n")
-
-    def aCallC(self):
-        self.logLastStep("A Calling C")
-        self.pja.stdin.write("m\n")
-        self.pja.stdin.write("sip:call_c at 127.0.0.1:5060\n")
-
-    def aTransferBToC(self):
-        self.logLastStep("A Transfering B to C")
-        self.pja.stdin.write("X\n")
-        self.pja.stdin.write("1\n")
-
-    def startProcesses(self):
-        self.logLastStep("Starting Processes")
-        self.ast1.start()
-        self.pja = subprocess.Popen(['pjsua', '--local-port=5065',
-                                     '--auto-answer=200', '--null-audio'],
-                                     stdin=subprocess.PIPE)
-        self.pjb = subprocess.Popen(['pjsua', '--local-port=5066',
-                                     '--auto-answer=200', '--null-audio'],
-                                     stdin=subprocess.PIPE,
-                                     stdout=subprocess.PIPE)
-        self.pjc = subprocess.Popen(['pjsua', '--local-port=5067',
-                                     '--auto-answer=200', '--null-audio'],
-                                     stdin=subprocess.PIPE,
-                                     stdout=subprocess.PIPE)
-
-    def stopProcesses(self):
-        self.logLastStep("Stopping Processes")
-        self.ast1.stop()
-        os.kill(self.pja.pid, signal.SIGKILL)
-        os.kill(self.pjb.pid, signal.SIGKILL)
-        os.kill(self.pjc.pid, signal.SIGKILL)
-
-    def logLastStep(self, step):
-        print step
-        self.lastStep = step
+        TestCase.__init__(self)
+        #self.reactor_timeout = 60
+        self.create_asterisk()
+	self.chans = []
+        self.final_bridge = 0
+        self.lib = None
+        self.ext_a = None
+        self.ext_b = None
+        self.ext_c = None
+        self.callToB = None
+        self.callToC = None
 
     def run(self):
+        TestCase.run(self)
+        self.create_ami_factory()
 
-        # start up the processes
-        self.startProcesses()
+    def ami_connect(self, ami):
+        # start pjsua clients
+        self.lib = pj.Lib()
+        try:
+            self.lib.init()
+            self.lib.create_transport(pj.TransportType.UDP, pj.TransportConfig())
+            self.lib.set_null_snd_dev()
+            self.lib.start()
 
-        # call extensions
-        self.amiLogin()
-        reactor.callLater(5, self.aCallB)
-        reactor.callLater(10, self.aCallC)
-        reactor.callLater(15, self.aTransferBToC)
-        reactor.callLater(20, self.amiCheckBridge)
+            # we'll need this for later...
+            self.ext_a = self.lib.create_account(pj.AccountConfig("127.0.0.1", "end_a"))
+            self.ext_b = self.lib.create_account(pj.AccountConfig("127.0.0.1", "end_b"))
+            self.ext_c = self.lib.create_account(pj.AccountConfig("127.0.0.1", "end_c"))
+            # only legs B and C receive calls, so only those two need to register and autoanswer
+            ext_b_cb = AutoAnswerCallback(self.ext_b)
+            ext_c_cb = AutoAnswerCallback(self.ext_c)
+            self.ext_b.set_callback(ext_b_cb)
+            self.ext_c.set_callback(ext_c_cb)
+            # wait for registration
+            ext_b_cb.wait()
+            ext_c_cb.wait()
 
-        # stop and read results after timeout
-        reactor.callLater(25, self.readResult)
+        except pj.Error, e:
+            LOGGER.error("Exception: " + str(e))
+            self.doCleanup()
+            return
+
+
+        # register callbacks required to handle call completion events
+        self.ami[0].registerEvent('Bridge', self.bridge_callback)
+        self.ami[0].registerEvent('VarSet', self.bridgepeer_callback)
+
+        # kick off first call from A to B
+        LOGGER.info("Kicking off A-to-B call")
+        self.callToB = self.ext_a.make_call("sip:call_b at 127.0.0.1:5060")
+
+    def bridge_callback(self, ami, event):
+	self.chans.append(event['channel2'])
+        numchans = len(self.chans)
+        if numchans == 1:
+            # kick off second call from A to C
+            LOGGER.info("Kicking off A-to-C call")
+            self.callToC = self.ext_a.make_call("sip:call_c at 127.0.0.1:5060")
+        elif numchans == 2:
+            # both channels are now up, so initiate the transfer
+            LOGGER.info("Kicking off transfer")
+            self.callToC.transfer_to_call(self.callToB)
+
+    def bridgepeer_callback(self, ami, event):
+        if event['variable'] != "BRIDGEPEER" or len(self.chans) < 2:
+            return
+
+        LOGGER.info("Inspecting BRIDGEPEER VarSet")
+
+        # we should get 2 bridgepeers with swapped channel and value headers indicating the bridged channels
+        if self.chans[:2] == [event['channel'], event['value']] or\
+            self.chans[:2] == [event['value'], event['channel']]:
+            LOGGER.info("Got expected VarSet")
+            self.final_bridge += 1
+            if self.final_bridge == 2:
+                LOGGER.info("Transfer successful!")
+                # success!
+                self.passed = True
+                self.doCleanup()
+
+    def doCleanup(self):
+        #self.ami[0].hangup(self.chans[0])
+        self.ast[0].cli_exec("core show locks")   # get lock output in case of deadlock before tearing down.
+        self.ast[0].cli_exec("core show channels")# if channels are still up for some reason, we want to know that as well
+        self.lib.destroy()
+        self.lib = None
+        reactor.stop()
 
 def main():
     # Run Attended Transfer Test
-    att_transfer_test = AttTransferTest()
+    test = AttTransferTest()
     reactor.run()
-    att_transfer_test.stopProcesses()
-    if att_transfer_test.passed != True:
+    if test.passed != True:
         return 1
     return 0
 

Modified: asterisk/team/mmichelson/bridge-tests/tests/channels/SIP/sip_attended_transfer/test-config.yaml
URL: http://svnview.digium.com/svn/testsuite/asterisk/team/mmichelson/bridge-tests/tests/channels/SIP/sip_attended_transfer/test-config.yaml?view=diff&rev=3360&r1=3359&r2=3360
==============================================================================
--- asterisk/team/mmichelson/bridge-tests/tests/channels/SIP/sip_attended_transfer/test-config.yaml (original)
+++ asterisk/team/mmichelson/bridge-tests/tests/channels/SIP/sip_attended_transfer/test-config.yaml Tue Jul 24 14:11:13 2012
@@ -1,5 +1,4 @@
 testinfo:
-    skip: 'Skip while failures are debugged'
     summary:     'Test SIP Attended Transfer'
     description: |
         'This test verifies the SIP_REFER with Replaces attended transfer routine.'
@@ -9,7 +8,7 @@
     dependencies:
         - python : 'twisted'
         - python : 'starpy'

[... 145 lines stripped ...]



More information about the svn-commits mailing list