[asterisk-commits] mjordan: branch mjordan/twisted_process r3104 - in /asterisk/team/mjordan/twi...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Mon Mar 19 16:41:03 CDT 2012


Author: mjordan
Date: Mon Mar 19 16:40:59 2012
New Revision: 3104

URL: http://svnview.digium.com/svn/testsuite?view=rev&rev=3104
Log:
Update branch with working SIPp and Asterisk twisted process

SIPp: it now works!  So does Asterisk.  Much thanks to one of the FastAGI
tests for tanking in every way imaginable, such that the shutdown sequence
in Asterisk is now robusto.

Bunch of test updates as well.

Added:
    asterisk/team/mjordan/twisted_process/tests/iax2/basic-call/configs/ast2/cdr.conf   (with props)
Removed:
    asterisk/team/mjordan/twisted_process/tests/chanspy/chanspy_barge/configs/ast1/manager.conf
    asterisk/team/mjordan/twisted_process/tests/iax2/basic-call/configs/ast1/manager.conf
    asterisk/team/mjordan/twisted_process/tests/iax2/basic-call/configs/ast2/manager.conf
Modified:
    asterisk/team/mjordan/twisted_process/lib/python/asterisk/asterisk.py
    asterisk/team/mjordan/twisted_process/lib/python/asterisk/sipp.py
    asterisk/team/mjordan/twisted_process/tests/apps/incomplete/sip_incomplete/run-test
    asterisk/team/mjordan/twisted_process/tests/channels/SIP/handle_response_address_incomplete/run-test
    asterisk/team/mjordan/twisted_process/tests/channels/SIP/info_dtmf/run-test
    asterisk/team/mjordan/twisted_process/tests/channels/SIP/nat_supertest/run-test
    asterisk/team/mjordan/twisted_process/tests/channels/SIP/nat_supertest/sipp/inject.csv
    asterisk/team/mjordan/twisted_process/tests/channels/SIP/nat_supertest/test-config.yaml
    asterisk/team/mjordan/twisted_process/tests/channels/SIP/realtime_nosipregs/run-test
    asterisk/team/mjordan/twisted_process/tests/channels/SIP/realtime_sipregs/run-test
    asterisk/team/mjordan/twisted_process/tests/channels/SIP/sip_hold/run-test
    asterisk/team/mjordan/twisted_process/tests/channels/SIP/sip_hold/test-config.yaml
    asterisk/team/mjordan/twisted_process/tests/channels/SIP/sip_register_domain_acl/run-test
    asterisk/team/mjordan/twisted_process/tests/channels/SIP/sip_register_domain_acl/test-config.yaml
    asterisk/team/mjordan/twisted_process/tests/channels/SIP/sip_tls_register/run-test
    asterisk/team/mjordan/twisted_process/tests/channels/SIP/use_contact_from_200/run-test
    asterisk/team/mjordan/twisted_process/tests/chanspy/chanspy_barge/run-test
    asterisk/team/mjordan/twisted_process/tests/chanspy/chanspy_w_mixmonitor/run-test
    asterisk/team/mjordan/twisted_process/tests/fastagi/get-data/run-test
    asterisk/team/mjordan/twisted_process/tests/fastagi/hangup/run-test
    asterisk/team/mjordan/twisted_process/tests/fastagi/say-alpha/run-test
    asterisk/team/mjordan/twisted_process/tests/fastagi/say-date/run-test
    asterisk/team/mjordan/twisted_process/tests/fastagi/say-datetime/run-test
    asterisk/team/mjordan/twisted_process/tests/fastagi/say-digits/run-test
    asterisk/team/mjordan/twisted_process/tests/fastagi/say-number/run-test
    asterisk/team/mjordan/twisted_process/tests/fastagi/say-phonetic/run-test
    asterisk/team/mjordan/twisted_process/tests/fastagi/say-time/run-test
    asterisk/team/mjordan/twisted_process/tests/feature_attended_transfer/run-test
    asterisk/team/mjordan/twisted_process/tests/feature_blonde_transfer/run-test
    asterisk/team/mjordan/twisted_process/tests/iax2/basic-call/configs/ast1/extensions.conf
    asterisk/team/mjordan/twisted_process/tests/iax2/basic-call/configs/ast2/extensions.conf
    asterisk/team/mjordan/twisted_process/tests/iax2/basic-call/run-test
    asterisk/team/mjordan/twisted_process/tests/mixmonitor/run-test

Modified: asterisk/team/mjordan/twisted_process/lib/python/asterisk/asterisk.py
URL: http://svnview.digium.com/svn/testsuite/asterisk/team/mjordan/twisted_process/lib/python/asterisk/asterisk.py?view=diff&rev=3104&r1=3103&r2=3104
==============================================================================
--- asterisk/team/mjordan/twisted_process/lib/python/asterisk/asterisk.py (original)
+++ asterisk/team/mjordan/twisted_process/lib/python/asterisk/asterisk.py Mon Mar 19 16:40:59 2012
@@ -22,7 +22,7 @@
 from config import ConfigFile
 from version import AsteriskVersion
 
-from twisted.internet import reactor, protocol, defer, utils
+from twisted.internet import reactor, protocol, defer, utils, error
 
 logger = logging.getLogger(__name__)
 
@@ -123,9 +123,15 @@
 
     def processEnded(self, reason):
         """ Override of ProcessProtocol.processEnded """
-        logger.debug("Asterisk %s ended with code %d" % (self.__host, reason.value.exitCode,))
-        self.exitcode = reason.value.exitCode
-        self.__stop_deferred.callback("Asterisk %s ended with code %d" % (self.__host, reason.value.exitCode,))
+        try:
+            if reason.value and reason.value.exitCode:
+                logger.debug("Asterisk %s ended with code %d" % (self.__host, reason.value.exitCode,))
+                self.exitcode = reason.value.exitCode
+                self.__stop_deferred.callback("Asterisk %s ended with code %d" % (self.__host, reason.value.exitCode,))
+            else:
+                self.__stop_deferred.callback("Asterisk %s ended" % (self.__host))
+        except defer.AlreadyCalledError:
+            logger.warning("Asterisk stop deferred already called")
         self.exited = True
 
 class Asterisk:
@@ -293,7 +299,7 @@
                 logger.warning("Asterisk graceful stop for %s failed" % self.host)
             else:
                 logger.debug("Asterisk graceful stop failed, attempting again...")
-                self.__stop_attemps += 1
+                self.__stop_attempts += 1
                 __send_stop_gracefully()
 
         def __send_stop_now():
@@ -302,8 +308,9 @@
                 cli_deferred = self.cli_exec("stop now")
             else:
                 cli_deferred = self.cli_exec("core stop now")
-            cli_deferred.addCallback(__stop_now_callback)
-            cli_deferred.addErrback(__stop_now_error)
+            if cli_deferred:
+                cli_deferred.addCallback(__stop_now_callback)
+                cli_deferred.addErrback(__stop_now_error)
 
         def __stop_now_callback(cli_command):
             """ Callback handler for the core stop now CLI command """
@@ -319,14 +326,15 @@
                 logger.debug("Asterisk stop now failed, attempting again...")
                 self.__stop_attempts += 1
                 cli_deferred = __send_stop_now()
-                cli_deferred.addCallback(__stop_now_callback)
-                cli_deferred.addErrback(__stop_now_error)
+                if cli_deferred:
+                    cli_deferred.addCallback(__stop_now_callback)
+                    cli_deferred.addErrback(__stop_now_error)
 
         def __send_term():
             try:
                 logger.info("Sending TERM to Asterisk %s" % self.host)
                 self.process.signalProcess("TERM")
-            except twisted.internet.error.ProcessExitedAlready:
+            except error.ProcessExitedAlready:
                 # Probably that we sent a signal to a process that was already
                 # dead.  Just ignore it.
                 pass
@@ -337,10 +345,10 @@
                 if not self.processProtocol.exited:
                     logger.info("Sending KILL to Asterisk %s" % self.host)
                     self.process.signalProcess("KILL")
-            except twisted.internet.error.ProcessExitedAlready:
+            except error.ProcessExitedAlready:
                 # Pass on this
                 pass
-            # If you kill the process, the ProcessProtocol will never get the note
+            # If you kill the process, the ProcessProtocol may never get the note
             # that its dead.  Call the stop callback to notify everyone that we did
             # indeed kill the Asterisk instance.
             try:
@@ -349,7 +357,10 @@
                 self.process.loseConnection()
             except:
                 pass
-            self.__stop_deferred.errback("Asterisk %s KILLED" % self.host)
+            try:
+                self.__stop_deferred.callback("Asterisk %s KILLED" % self.host)
+            except defer.AlreadyCalledError:
+                logger.warning("Asterisk stop deferred already called")
 
         def __cancel_stops(reason):
             """ Cancel all stop actions - called when the process exits """

Modified: asterisk/team/mjordan/twisted_process/lib/python/asterisk/sipp.py
URL: http://svnview.digium.com/svn/testsuite/asterisk/team/mjordan/twisted_process/lib/python/asterisk/sipp.py?view=diff&rev=3104&r1=3103&r2=3104
==============================================================================
--- asterisk/team/mjordan/twisted_process/lib/python/asterisk/sipp.py (original)
+++ asterisk/team/mjordan/twisted_process/lib/python/asterisk/sipp.py Mon Mar 19 16:40:59 2012
@@ -21,6 +21,66 @@
 from TestCase import TestCase
 
 logger = logging.getLogger(__name__)
+
+class SIPpScenarioSequence:
+    """ Execute a sequence of SIPp Scenarios in sequence.
+
+    This class manages the execution of multiple SIPpScenarios in sequence.
+    """
+
+    def __init__(self, test_case, sipp_scenarios = [], fail_on_any = False, intermediate_callback = None, final_deferred = None):
+        """ Create a new sequence of scenarios
+
+        Keyword Arguments:
+        test_case - the TestCase derived object to pass to the SIPpScenario objects
+        sipp_scenarios - a list of SIPpScenario objects to execute
+        fail_on_any - if any scenario fails, stop the reactor and kill the test.
+        intermediate_callback - a deferred callback that will be added to each test
+        final_deferred - a deferred object that will be called when all tests have
+        executed, but before the reactor is stopped
+        """
+        self.__sipp_scenarios = sipp_scenarios
+        self.__test_case = test_case
+        self.__fail_on_any = fail_on_any
+        self.__test_counter = 0
+        self.__intermediate_callback = intermediate_callback
+        self.__final_deferred = final_deferred
+
+    def register_scenario(self, sipp_scenario):
+        """ Register a new scenario with the sequence
+
+        Registers a SIPpScenario object with the sequence of scenarios to execute
+
+        Keyword Arguments:
+        sipp_scenario - the SIPpScenario object to execute
+        """
+        self.__sipp_scenarios.append(sipp_scenario)
+
+    def execute(self):
+        """ Execute the tests in sequence
+        """
+        def __execute_next(result):
+            # Only evaluate for failure if we're responsible for failing the test case -
+            # otherwise the SIPpScenario will do it for us
+            if not self.__fail_on_any and not result.passed:
+                logger.warning("SIPp Scenario %s Failed" % result.scenario['scenario'])
+                self.__test_case.passed = False
+            self.__test_counter += 1
+            if self.__test_counter < len(self.__sipp_scenarios):
+                self.execute()
+            else:
+                if self.__final_deferred:
+                    self.__final_deferred.callback(self)
+                self.__test_case.stop_reactor()
+            return result
+
+        if self.__fail_on_any:
+            df = self.__sipp_scenarios[self.__test_counter].run(self.__test_case)
+        else:
+            df = self.__sipp_scenarios[self.__test_counter].run(None)
+        df.addCallback(__execute_next)
+        if self.__intermediate_callback:
+            df.addCallback(self.__intermediate_callback)
 
 class SIPpScenario:
     """
@@ -66,10 +126,15 @@
         self.sipp = TestSuiteUtils.which("sipp")
         self.passed = False
 
-    def run(self):
+    def run(self, test_case = None):
         """ Execute a SIPp scenario
 
         Execute the SIPp scenario that was passed to this object
+
+        Keyword Arguments:
+        test_case - if not None, the scenario will automatically evaluate its pass/fail status
+        at the end of the run.  In the event of a failure, it will fail the test case scenario
+        and call stop_reactor.
 
         Returns:
         A deferred that can be used to determine when the SIPp Scenario
@@ -82,25 +147,31 @@
             logger.debug(out)
             logger.debug("Launching SIPp Scenario %s exited %d"
                 % (self.scenario['scenario'], code))
-            if (code == 0 or code != 99):
+            if (code == 0):
                 self.passed = True
-                logger.info("SIPp Scenario %s Started" % (self.scenario['scenario']))
-                self.__exit_deferred.callback(self)
+                logger.info("SIPp Scenario %s Exited" % (self.scenario['scenario']))
             else:
-                logger.warning("Launching SIPp Scenario %s Failed" % (self.scenario['scenario']))
-                self.__exit_deferred.errback(self)
+                logger.warning("SIPp Scenario %s Failed [%d, %s]" % (self.scenario['scenario'], code, err))
+            self.__exit_deferred.callback(self)
 
         def __error_callback(result):
             """ Errback from getProcessOutputAndValue """
             out, err, code = result
-            logger.warning("Launching of SIPp Scenario %s exited %d with error: %s"
-                % (self.scenario['scenario'], code, err))
-            self.__exit_deferred.errback(self)
+            logger.warning("SIPp Scenario %s Failed [%d, %s]" % (self.scenario['scenario'], code, err))
+            self.__exit_deferred.callback(self)
+
+        def __evalute_scenario_results(result):
+            """ Convenience function.  If the test case is injected into this method,
+            then auto-fail the test if the scenario fails. """
+            if not self.passed:
+                logger.warning("SIPp Scenario %s Failed" % self.scenario['scenario'])
+                self.__test_case.passed = False
+                self.__test_case.stop_reactor()
 
         sipp_args = [
                 self.sipp, '127.0.0.1',
                 '-sf', '%s/sipp/%s' % (self.test_dir, self.scenario['scenario']),
-                '-nostdin', '-bg', '-trace_msg',
+                '-nostdin',
                 '-skip_rlimit',
         ]
         default_args = {
@@ -123,9 +194,13 @@
 
         self.__exit_deferred = defer.Deferred()
 
-        df = utils.getProcessOutputAndValue(sipp_args[0], sipp_args)
+        df = utils.getProcessOutputAndValue(sipp_args[0], sipp_args, {"TERM" : "vt100",}, None, None)
         df.addCallback(__output_callback)
         df.addErrback(__error_callback)
+        if test_case:
+            self.__test_case = test_case
+            df.addCallback(__evalute_scenario_results)
+
         return self.__exit_deferred
 
 class SIPpTest(TestCase):
@@ -149,8 +224,7 @@
 
         Arguments:
 
-        working_dir - A path to the working directory to use for the temporary
-            Asterisk instance.  This is typically a path to somewhere in /tmp.
+        working_dir - Deprecated.  No longer used.
 
         test_dir - The path to the directory containing the run-test file.
 
@@ -172,74 +246,34 @@
                 -timeout 20s - Set a global test timeout of 20 seconds.
         """
         TestCase.__init__(self)
-        self.working_dir = working_dir
         self.test_dir = test_dir
         self.scenarios = scenarios
-        self.sipp = []
-        self.stdout = []
-        self.stderr = []
         self.result = []
-
         self.create_asterisk()
 
-    def __run_sipp(self, scenario, default_port):
-        sipp_args = [
-                'sipp', '127.0.0.1',
-                '-sf', '%s/sipp/%s' % (self.test_dir, scenario['scenario']),
-                '-nostdin'
-        ]
-        default_args = {
-            '-p' : default_port,
-            '-m' : '1',
-            '-i' : '127.0.0.1',
-            '-timeout' : '20s'
-        }
-
-        # Override and extend defaults
-        default_args.update(scenario)
-        del default_args['scenario']
-
-        for (key, val) in default_args.items():
-            sipp_args.extend([ key, val ])
-
-        logger.debug("Executing SIPp scenario: %s" % scenario['scenario'])
-        logger.debug(sipp_args)
-
-        return subprocess.Popen(sipp_args,
-                                stdout=subprocess.PIPE, stderr=subprocess.PIPE)
-
     def run(self):
         """
         Run the test.
 
         Returns 0 for success, 1 for failure.
         """
-        self.start_asterisk()
+        def __check_result(result):
+            self.result.append(result.passed)
+
+        def __set_pass_fail(result):
+            self.passed = (self.result.count(False) == 0)
 
         TestCase.run(self)
 
+        fin = defer.Deferred()
+        fin.addCallback(__set_pass_fail)
+        sequence = SIPpScenarioSequence(test_case = self, intermediate_callback = __check_result, final_deferred = fin)
+        i = 0
         for s in self.scenarios:
-            default_port = 5060 + len(self.sipp) + 1
-            self.sipp.append(self.__run_sipp(s, str(default_port)))
-
-        self.passed = True
-        for i in range(len(self.sipp)):
-            (out, err) = self.sipp[i].communicate()
-            self.stdout.append(out)
-            self.stderr.append(err)
-            self.result.append(self.sipp[i].wait())
-            logger.debug(self.stdout[i])
-            if self.result[i]:
-                logger.warn("SIPp scenario #%d (%s) FAILED" % (i, self.scenarios[i]['scenario']))
-                logger.warn(self.stderr[i])
-                self.passed = False
-            else:
-                logger.info("SIPp scenario #%d (%s) PASSED" % (i,  self.scenarios[i]['scenario']))
-
-        self.stop_asterisk()
-        self.stop_reactor()
-        if self.passed:
-            return 0
-        else:
-            return 1
-
+            default_port = 5060 + i + 1
+            i += 1
+            s['-p'] = str(default_port)
+            sequence.register_scenario(SIPpScenario(self.test_dir, s))
+
+        sequence.execute()
+

Modified: asterisk/team/mjordan/twisted_process/tests/apps/incomplete/sip_incomplete/run-test
URL: http://svnview.digium.com/svn/testsuite/asterisk/team/mjordan/twisted_process/tests/apps/incomplete/sip_incomplete/run-test?view=diff&rev=3104&r1=3103&r2=3104
==============================================================================
--- asterisk/team/mjordan/twisted_process/tests/apps/incomplete/sip_incomplete/run-test (original)
+++ asterisk/team/mjordan/twisted_process/tests/apps/incomplete/sip_incomplete/run-test Mon Mar 19 16:40:59 2012
@@ -40,19 +40,12 @@
     def ami_connect(self, ami):
         TestCase.ami_connect(self, ami)
 
-        def __check_sipp_results(self, result):
-            logger.debug("Checking results for %s" % str(result))
-            if not result.passed:
-                self.passed = False
-
         self.ast[ami.id].cli_exec("sip set debug on")
         ami.registerEvent('UserEvent', self.user_event)
 
         logger.debug("Starting SIP scenarios")
-        dr = self.receiverTest.run()
-        ds = self.senderTest.run()
-        dr.addCallback(__check_sipp_results)
-        ds.addCallback(__check_sipp_results)
+        dr = self.receiverTest.run(self)
+        ds = self.senderTest.run(self)
 
     def user_event(self, ami, event):
         if event['userevent'] != 'TestResult':

Modified: asterisk/team/mjordan/twisted_process/tests/channels/SIP/handle_response_address_incomplete/run-test
URL: http://svnview.digium.com/svn/testsuite/asterisk/team/mjordan/twisted_process/tests/channels/SIP/handle_response_address_incomplete/run-test?view=diff&rev=3104&r1=3103&r2=3104
==============================================================================
--- asterisk/team/mjordan/twisted_process/tests/channels/SIP/handle_response_address_incomplete/run-test (original)
+++ asterisk/team/mjordan/twisted_process/tests/channels/SIP/handle_response_address_incomplete/run-test Mon Mar 19 16:40:59 2012
@@ -32,7 +32,6 @@
         self.create_asterisk()
         self.sipTest = SIPpScenario(TEST_DIR, SIPP_SCENARIO)
 
-
     def ami_connect(self, ami):
         TestCase.ami_connect(self, ami)
 
@@ -40,7 +39,7 @@
         ami.registerEvent('UserEvent', self.user_event)
 
         logger.debug("Starting SIP scenario")
-        result = self.sipTest.run()
+        self.sipTest.run(self)
 
         logger.debug("Originating call from local channel to SIPp peer")
         df = ami.originate("Local/1234 at default", "default", "1234", 1, None, "CallId", None, None, None, {}, True)
@@ -60,15 +59,6 @@
             self.passed = False
 
         self.stop_reactor()
-
-    def stop_asterisk(self):
-        TestCase.stop_asterisk(self)
-
-        """ Wait for SIPp to exit """
-        logger.debug("Waiting for SIPp to end")
-        result = self.sipTest.waitAndEvaluate()
-        if not result:
-            self.passed = False
 
     def run(self):
         TestCase.run(self)

Modified: asterisk/team/mjordan/twisted_process/tests/channels/SIP/info_dtmf/run-test
URL: http://svnview.digium.com/svn/testsuite/asterisk/team/mjordan/twisted_process/tests/channels/SIP/info_dtmf/run-test?view=diff&rev=3104&r1=3103&r2=3104
==============================================================================
--- asterisk/team/mjordan/twisted_process/tests/channels/SIP/info_dtmf/run-test (original)
+++ asterisk/team/mjordan/twisted_process/tests/channels/SIP/info_dtmf/run-test Mon Mar 19 16:40:59 2012
@@ -17,7 +17,7 @@
 
 sys.path.append("lib/python")
 
-from asterisk.sipp import SIPpScenario
+from asterisk.sipp import SIPpScenario, SIPpScenarioSequence
 from asterisk.TestCase import TestCase
 
 """
@@ -54,18 +54,12 @@
         ami    -    The StarPY manager object that connected
         """
         ami.registerEvent('DTMF', self.handle_dtmf_event)
-        sipp_scenario_params = [{'scenario':'dtmf-relay.xml','-p':'5061'}, {'scenario':'dtmf.xml','-p':'5061'}]
-        for scenario_param in sipp_scenario_params:
-            sipp_scenario = SIPpScenario(TEST_DIR, scenario_param)
-            logger.info("Starting SIPp Scenario (%s)" % scenario_param['scenario'])
-            sipp_scenario.run()
-            sipp_result = sipp_scenario.waitAndEvaluate()
+        self.sipp_scenario_params = [{'scenario':'dtmf-relay.xml','-p':'5061'}, {'scenario':'dtmf.xml','-p':'5061'}]
+        sequence = SIPpScenarioSequence(test_case = self)
+        for scenario_param in self.sipp_scenario_params:
+            sequence.register_scenario(SIPpScenario(TEST_DIR, scenario_param))
 
-            self.reset_timeout()
-            if (not sipp_result):
-                logger.warn("SIPp Scenario (%s) failed" % scenario_param['scenario'])
-                self.passed = False
-                self.stop_reactor()
+        sequence.execute()
 
     def handle_dtmf_event(self, ami, event):
         """

Modified: asterisk/team/mjordan/twisted_process/tests/channels/SIP/nat_supertest/run-test
URL: http://svnview.digium.com/svn/testsuite/asterisk/team/mjordan/twisted_process/tests/channels/SIP/nat_supertest/run-test?view=diff&rev=3104&r1=3103&r2=3104
==============================================================================
--- asterisk/team/mjordan/twisted_process/tests/channels/SIP/nat_supertest/run-test (original)
+++ asterisk/team/mjordan/twisted_process/tests/channels/SIP/nat_supertest/run-test Mon Mar 19 16:40:59 2012
@@ -14,9 +14,9 @@
 sys.path.append("lib/python")
 
 from asterisk.TestCase import TestCase
-from asterisk.sipp import SIPpScenario
+from asterisk.sipp import SIPpScenario, SIPpScenarioSequence
 from asterisk.syncami import SyncAMI, InvalidAMIResponse
-from twisted.internet import reactor
+from twisted.internet import reactor, defer
 from qm import QM
 
 TEST_DIR = os.path.dirname(os.path.realpath(__file__))
@@ -55,6 +55,8 @@
         self.passed = False
         self.create_asterisk()
         self.failures = []
+        self.__existing_executed = False
+        self.__nonexisting_executed = False
 
     def run(self):
         super(SIPNatTest, self).run()
@@ -99,43 +101,66 @@
         f.close()
 
     def run_combos(self):
-        scenario_def = {'scenario': 'register.xml', '-p': '5061', '-recv_timeout': '1000', '-inf': INJECT_FILE}
+        def __check_intermediate_result(result):
+            if (result.scenario['-s'] == "existing"):
+                self.__existing_result = result.passed
+                self.__existing_executed = True
+            elif (result.scenario['-s'] == "nonexisting"):
+                self.__nonexisting_result = result.passed
+                self.__nonexisting_executed = True
+            if (self.__existing_executed and self.__nonexisting_executed):
+                self.__existing_executed = False
+                self.__nonexisting_executed = False
+                if self.__nonexisting_result != self.__existing_result:
+                    values = self.__scenario_values[self.__test_counter]
+                    logger.debug("Failed global_nat=%s peer_nat=%s rport_sepcified=%s port_matches_via=%s"
+                        % (self.get_nat_value(values[0]),self.get_nat_value(values[1]), str(values[2]), str(values[2])))
+                    self.failures.append(compute_value(values))
+
+            self.__test_counter += 1
+            values = self.__scenario_values[0]
+            self.reset_timeout()
+            self.update_config(values[0], values[1])
+            self.update_inject_file(values[2], values[3])
+            return result
+
+        def __check_failures(result):
+            # Only evaluate if this is the last test executed
+            logger.info("Checking Failures")
+            if (self.__test_counter == len(self.__scenario_values)):
+                # order of variables is least significant first!
+                qm = QM(["port_matches_via", "rport_specified", "peer_nat", "general_nat"])
+                logger.debug("Failures: %s" % (self.failures,))
+                try:
+                    if self.failures == expected_failures[self.ast[0].ast_version.branch]:
+                        self.passed = True
+                        logger.info(qm.get_function(qm.solve(self.failures, [])[1]))
+                    else:
+                        logger.warn(qm.get_function(qm.solve(self.failures, [])[1]))
+                except KeyError:
+                    log.error("We don't know the expected failures for branch: %s\n" % (self.ast[0].ast_version.branch,))
+                    self.passed = True
+            return result
+
+        self.__test_counter = 0
+        self.__scenario_values = []
+        fin = defer.Deferred()
+        fin.addCallback(__check_failures)
+        sequence = SIPpScenarioSequence(test_case = self, intermediate_callback = __check_intermediate_result, final_deferred = fin)
+
         for general_nat in [False, True]:
             for peer_nat in [False, True]:
-                self.update_config(general_nat, peer_nat)
                 for rport_specified in [False, True]:
                     for port_matches_via in [False, True]:
-                        existing_result = None
-                        nonexisting_result = None
-                        self.update_inject_file(rport_specified, port_matches_via)
                         for peer_name in ["existing", "nonexisting"]:
-                            scenario_def['-s'] = peer_name
-                            scenario = SIPpScenario(TEST_DIR, scenario_def)
-                            scenario.run()
-                            if peer_name == "existing":
-                                existing_result = scenario.waitAndEvaluate()
-                            else:
-                                nonexisting_result = scenario.waitAndEvaluate()
-                            self.reset_timeout()
-                        if nonexisting_result != existing_result:
-                            values = [general_nat, peer_nat, rport_specified, port_matches_via]
-                            logger.debug("Failed global_nat=%s peer_nat=%s rport_sepcified=%s port_matches_via=%s" % (self.get_nat_value(general_nat),self. get_nat_value(peer_nat), rport_specified, port_matches_via))
-                            self.failures.append(compute_value(values))
+                            scenario_def = {'-s': peer_name, 'scenario': 'register.xml', '-p': '5061', '-recv_timeout': '1000', '-inf': INJECT_FILE}
+                            sequence.register_scenario(SIPpScenario(TEST_DIR, scenario_def))
+                            self.__scenario_values.append([general_nat, peer_nat, rport_specified, port_matches_via])
 
-        # order of variables is least significant first!
-        qm = QM(["port_matches_via", "rport_specified", "peer_nat", "general_nat"])
-        logger.debug("Failures: %s" % (self.failures,))
-        try:
-            if self.failures == expected_failures[self.ast[0].ast_version.branch]:
-                self.passed = True
-                logger.info(qm.get_function(qm.solve(self.failures, [])[1]))
-            else:
-                logger.warn(qm.get_function(qm.solve(self.failures, [])[1]))
-        except KeyError:
-            log.error("We don't know the expected failures for branch: %s\n" % (self.ast[0].ast_version.branch,))
-            self.passed = True
-
-        reactor.stop()
+        values = self.__scenario_values[0]
+        self.update_config(values[0], values[1])
+        self.update_inject_file(values[2], values[3])
+        sequence.execute()
 
     def ami_connect(self, ami):
         logger.debug("Connected to AMI")

Modified: asterisk/team/mjordan/twisted_process/tests/channels/SIP/nat_supertest/sipp/inject.csv
URL: http://svnview.digium.com/svn/testsuite/asterisk/team/mjordan/twisted_process/tests/channels/SIP/nat_supertest/sipp/inject.csv?view=diff&rev=3104&r1=3103&r2=3104
==============================================================================
--- asterisk/team/mjordan/twisted_process/tests/channels/SIP/nat_supertest/sipp/inject.csv (original)
+++ asterisk/team/mjordan/twisted_process/tests/channels/SIP/nat_supertest/sipp/inject.csv Mon Mar 19 16:40:59 2012
@@ -1,2 +1,2 @@
 SEQUENTIAL
-5061;rport
+5062;ignored

Modified: asterisk/team/mjordan/twisted_process/tests/channels/SIP/nat_supertest/test-config.yaml
URL: http://svnview.digium.com/svn/testsuite/asterisk/team/mjordan/twisted_process/tests/channels/SIP/nat_supertest/test-config.yaml?view=diff&rev=3104&r1=3103&r2=3104
==============================================================================
--- asterisk/team/mjordan/twisted_process/tests/channels/SIP/nat_supertest/test-config.yaml (original)
+++ asterisk/team/mjordan/twisted_process/tests/channels/SIP/nat_supertest/test-config.yaml Mon Mar 19 16:40:59 2012
@@ -1,4 +1,5 @@
 testinfo:
+    skip: 'See ASTERISK-xxxxx'
     summary:    'Test SIP realtime peer matching'
     description: |
         'Make sure that realtime peers are matched properly'

Modified: asterisk/team/mjordan/twisted_process/tests/channels/SIP/realtime_nosipregs/run-test
URL: http://svnview.digium.com/svn/testsuite/asterisk/team/mjordan/twisted_process/tests/channels/SIP/realtime_nosipregs/run-test?view=diff&rev=3104&r1=3103&r2=3104
==============================================================================
--- asterisk/team/mjordan/twisted_process/tests/channels/SIP/realtime_nosipregs/run-test (original)
+++ asterisk/team/mjordan/twisted_process/tests/channels/SIP/realtime_nosipregs/run-test Mon Mar 19 16:40:59 2012
@@ -17,7 +17,7 @@
 logging.basicConfig()
 
 from asterisk.TestCase import TestCase
-from asterisk.sipp import SIPpScenario
+from asterisk.sipp import SIPpScenario, SIPpScenarioSequence
 from twisted.internet import reactor
 from starpy import manager
 
@@ -60,11 +60,11 @@
     def ami_connect(self, ami):
         logger.debug("Connected to AMI")
         ami.registerEvent("UserEvent", self.ami_test)
-        for scenario_def in SIPP_SCENARIOS:
-            scenario = SIPpScenario(TEST_DIR, scenario_def)
-            scenario.run()
-            if scenario.waitAndEvaluate() == False:
-                self.stop_reactor()
+        sequence = SIPpScenarioSequence(test_case = self)
+        for scenario_param in SIPP_SCENARIOS:
+            sequence.register_scenario(SIPpScenario(TEST_DIR, scenario_param))
+
+        sequence.execute()
 
     def ami_test(self, ami, event):
         if event.get("userevent") != "CallFromPeer":

Modified: asterisk/team/mjordan/twisted_process/tests/channels/SIP/realtime_sipregs/run-test
URL: http://svnview.digium.com/svn/testsuite/asterisk/team/mjordan/twisted_process/tests/channels/SIP/realtime_sipregs/run-test?view=diff&rev=3104&r1=3103&r2=3104
==============================================================================
--- asterisk/team/mjordan/twisted_process/tests/channels/SIP/realtime_sipregs/run-test (original)
+++ asterisk/team/mjordan/twisted_process/tests/channels/SIP/realtime_sipregs/run-test Mon Mar 19 16:40:59 2012
@@ -17,7 +17,7 @@
 logging.basicConfig()
 
 from asterisk.TestCase import TestCase
-from asterisk.sipp import SIPpScenario
+from asterisk.sipp import SIPpScenario, SIPpScenarioSequence
 from twisted.internet import reactor
 from starpy import manager
 
@@ -53,11 +53,11 @@
     def ami_connect(self, ami):
         logger.debug("Connected to AMI")
         ami.registerEvent("UserEvent", self.ami_test)
-        for scenario_def in SIPP_SCENARIOS:
-            scenario = SIPpScenario(TEST_DIR, scenario_def)
-            scenario.run()
-            if scenario.waitAndEvaluate() == False:
-                self.stop_reactor()
+        sequence = SIPpScenarioSequence(test_case = self)
+        for scenario_param in SIPP_SCENARIOS:
+            sequence.register_scenario(SIPpScenario(TEST_DIR, scenario_param))
+
+        sequence.execute()
 
     def ami_test(self, ami, event):
         if event.get("userevent") != "CallFromPeer":

Modified: asterisk/team/mjordan/twisted_process/tests/channels/SIP/sip_hold/run-test
URL: http://svnview.digium.com/svn/testsuite/asterisk/team/mjordan/twisted_process/tests/channels/SIP/sip_hold/run-test?view=diff&rev=3104&r1=3103&r2=3104
==============================================================================
--- asterisk/team/mjordan/twisted_process/tests/channels/SIP/sip_hold/run-test (original)
+++ asterisk/team/mjordan/twisted_process/tests/channels/SIP/sip_hold/run-test Mon Mar 19 16:40:59 2012
@@ -44,6 +44,7 @@
         self.moh_start_events = 0
         self.moh_stop_events = 0
         self.user_events = 0
+        self.__test_counter = 0
 
     def ami_connect(self, ami):
         TestCase.ami_connect(self, ami)
@@ -53,30 +54,38 @@
         self.execute_scenarios()
 
     def execute_scenarios(self):
-        for i in range(len(self.sipp_phone_a_scenarios)):
-            sipp_a = SIPpScenario(TEST_DIR, self.sipp_phone_a_scenarios[i])
-            sipp_b = SIPpScenario(TEST_DIR, self.sipp_phone_b_scenarios[i])
+        def __check_scenario_a(result):
+            self.__a_finished = True
+            return result
 
-            """ Start up the listener first - Phone A calls Phone B """
-            sipp_b.run()
-            sipp_a.run()
+        def __check_scenario_b(result):
+            self.__b_finished = True
+            return result
 
-            sipp_a_result = sipp_a.waitAndEvaluate()
-            sipp_b_result = sipp_b.waitAndEvaluate()
+        def __execute_next_scenario(result):
+            if self.__a_finished and self.__b_finished:
+                self.__test_counter += 1
+                self.reset_timeout()
+                self.execute_scenarios()
+            return result
 
-            if (not sipp_a_result):
-                logger.warn("SIPp Scenario Phone A (%s) failed" % self.sipp_phone_a_scenarios[i]['scenario'])
-                self.passed = False
-            if (not sipp_b_result):
-                logger.warn("SIPp Scenario Phone B (%s) failed" % self.sipp_phone_b_scenarios[i]['scenario'])
-                self.passed = False
-            self.reset_timeout()
+        if self.__test_counter == len(self.sipp_phone_a_scenarios):
+            logger.info("All scenarios executed")
+            return
 
-        logger.info("All scenarios executed")
-        """
-        Note: you can't stop the reactor here, as the AMI events will be pooled up.  Let the AMI events
-        determine when the reactor is stopped
-        """
+        sipp_a = SIPpScenario(TEST_DIR, self.sipp_phone_a_scenarios[self.__test_counter])
+        sipp_b = SIPpScenario(TEST_DIR, self.sipp_phone_b_scenarios[self.__test_counter])
+
+        # Start up the listener first - Phone A calls Phone B
+        self.__a_finished = False
+        self.__b_finished = False
+        db = sipp_b.run(self)
+        da = sipp_a.run(self)
+
+        da.addCallback(__check_scenario_a)
+        da.addCallback(__execute_next_scenario)
+        db.addCallback(__check_scenario_b)
+        db.addCallback(__execute_next_scenario)
 
     def user_event_handler(self, ami, event):
         self.user_events += 1

Modified: asterisk/team/mjordan/twisted_process/tests/channels/SIP/sip_hold/test-config.yaml
URL: http://svnview.digium.com/svn/testsuite/asterisk/team/mjordan/twisted_process/tests/channels/SIP/sip_hold/test-config.yaml?view=diff&rev=3104&r1=3103&r2=3104
==============================================================================
--- asterisk/team/mjordan/twisted_process/tests/channels/SIP/sip_hold/test-config.yaml (original)
+++ asterisk/team/mjordan/twisted_process/tests/channels/SIP/sip_hold/test-config.yaml Mon Mar 19 16:40:59 2012
@@ -7,7 +7,7 @@
         is tested both for a local RTP bridge, and a non-bridged scenario.
 
 properties:
-    minversion: '1.8.9'
+    minversion: '1.8'
     dependencies:
         - sipp :
             version : 'v3.0'

Modified: asterisk/team/mjordan/twisted_process/tests/channels/SIP/sip_register_domain_acl/run-test
URL: http://svnview.digium.com/svn/testsuite/asterisk/team/mjordan/twisted_process/tests/channels/SIP/sip_register_domain_acl/run-test?view=diff&rev=3104&r1=3103&r2=3104
==============================================================================
--- asterisk/team/mjordan/twisted_process/tests/channels/SIP/sip_register_domain_acl/run-test (original)
+++ asterisk/team/mjordan/twisted_process/tests/channels/SIP/sip_register_domain_acl/run-test Mon Mar 19 16:40:59 2012
@@ -14,7 +14,7 @@
 sys.path.append("lib/python")
 
 from asterisk.TestCase import TestCase
-from asterisk.sipp import SIPpScenario
+from asterisk.sipp import SIPpScenario, SIPpScenarioSequence
 from twisted.internet import reactor
 from starpy import manager
 
@@ -66,7 +66,8 @@
                 '-key', 'useraddr', scenario['USERADDR'],
             )))
 
-        self.passed = False
+        # If any of the tests fails, they'll automatically set the passed result to False
+        self.passed = True
         self.create_asterisk()
 
     def run(self):
@@ -77,17 +78,10 @@
         super(SIPRegisterDomainAclTest, self).ami_connect(ami)
 
         logger.debug("Connected to AMI")
-        passed = True
+        sequence = SIPpScenarioSequence(test_case = self)
         for scenario_def in self.scenario_defs:
-            scenario = SIPpScenario(TEST_DIR, scenario_def[0], scenario_def[1])
-            scenario.run()
-            if scenario.waitAndEvaluate() == False:
-                passed = False
-
-        # All done
-        self.passed = passed
-        self.stop_reactor()
-
+            sequence.register_scenario(SIPpScenario(TEST_DIR, scenario_def[0], scenario_def[1]))
+        sequence.execute()
 
 def main():
     test = SIPRegisterDomainAclTest()

Modified: asterisk/team/mjordan/twisted_process/tests/channels/SIP/sip_register_domain_acl/test-config.yaml
URL: http://svnview.digium.com/svn/testsuite/asterisk/team/mjordan/twisted_process/tests/channels/SIP/sip_register_domain_acl/test-config.yaml?view=diff&rev=3104&r1=3103&r2=3104

[... 1181 lines stripped ...]



More information about the asterisk-commits mailing list