[asterisk-commits] Testsuite Test 'stasisstatus' Fails During Build (testsuite[master])

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Thu Apr 23 06:30:55 CDT 2015


Matt Jordan has submitted this change and it was merged.

Change subject: Testsuite Test 'stasisstatus' Fails During Build
......................................................................


Testsuite Test 'stasisstatus' Fails During Build

During execution of the test, the first test scenario, [Babs], fails. According
to the logs, the problem begins when the web socket for [Babs] fails to
instantiate on the first try. While it is attempting to reconnect, the TestCase
starts the next TestScenario, [Bugs], and leaves [Babs] orphaned. This hang up
subsequently results in the twisted.reactor timing out. The logic in the test
states if the reactor times out, the test is automatically marked as a failure
(as it should).

This patch attempts to remedy the above situation by adding an observable
event, 'on_start' for the TestScenario class. The observers for this event are
notified when the AriClient has completed creating the web socket. The TestCase
registers itself as an observer of this event and then uses its callback as a
means of scheduling the start of each subsequent TestScenario.

ASTERISK-24995 #close
Reported By: Ashley Sanders

Change-Id: Iad3d6b3a092d8f57dfd7855c79b641096de129aa
---
M tests/rest_api/applications/stasisstatus/test_case.py
M tests/rest_api/applications/stasisstatus/test_scenario.py
2 files changed, 49 insertions(+), 47 deletions(-)

Approvals:
  Mark Michelson: Looks good to me, but someone else must approve
  Matt Jordan: Looks good to me, approved; Verified



diff --git a/tests/rest_api/applications/stasisstatus/test_case.py b/tests/rest_api/applications/stasisstatus/test_case.py
index 1e8c1dd..00f9362 100644
--- a/tests/rest_api/applications/stasisstatus/test_case.py
+++ b/tests/rest_api/applications/stasisstatus/test_case.py
@@ -89,8 +89,12 @@
         self.__iterator = iter(self.__scenarios)
 
         for scenario in self.__scenarios:
-            deferred.addCallback(self.__try_run_scenario)
+            scenario.register_observers('on_start',
+                                        self.__on_scenario_start)
+            scenario.register_observers('on_complete',
+                                        self.__on_scenario_complete)
 
+        deferred.addCallback(self.__try_run_scenario)
         deferred.callback(self.__get_next_scenario())
 
     def on_reactor_timeout(self):
@@ -116,6 +120,18 @@
         LOGGER.debug('{0} Test case execution is complete.'.format(self))
         self.stop_reactor()
 
+    def __on_scenario_start(self, sender, message):
+        """Tries to start the next scenario returned from the iterator.
+
+        Keyword Arguments:
+        sender                 -- The object that raised the event.
+        message                -- The event payload.
+        """
+
+        scenario = self.__get_next_scenario()
+        if scenario is not None:
+            self.__try_run_scenario(scenario)
+
     def run(self):
         """Executes the test case.
 
@@ -124,7 +140,6 @@
 
         LOGGER.debug('{0} Starting test case execution.'.format(self))
         super(StasisStatusTestCase, self).run()
-
         self.create_ami_factory()
 
     def stop_reactor(self):
@@ -147,26 +162,14 @@
 
         Keyword Arguments:
         scenario               -- The scenario to try to start.
-
-        Returns:
-        If the self.__iterator has not yet finished traversing the list,
-        returns the next scenario in self.__scenarios.
-
-        Otherwise,returns None.
         """
 
-        msg = '{0} {1} scenario [{2}]'
+        msg = '{0} {1} scenario [{2}].'
 
-        if scenario is not None:
-            LOGGER.debug((msg + '.').format(self,
-                                            'Starting',
-                                            scenario.name))
-            scenario.start(self.__on_scenario_complete)
-            return self.__get_next_scenario()
+        if scenario is None:
+            LOGGER.warn(msg.format(self, 'Cannot start', type(scenario)))
+            return
 
-        msg = msg + '; {3}.'
-        LOGGER.warn(msg.format(self,
-                               'Cannot connect',
-                               None,
-                               'scenario has not been assigned a value.'))
-        return None
+        LOGGER.debug(msg.format(self, 'Starting', scenario.name))
+        scenario.start()
+        return
diff --git a/tests/rest_api/applications/stasisstatus/test_scenario.py b/tests/rest_api/applications/stasisstatus/test_scenario.py
index 57e16d4..be284db 100644
--- a/tests/rest_api/applications/stasisstatus/test_scenario.py
+++ b/tests/rest_api/applications/stasisstatus/test_scenario.py
@@ -44,6 +44,7 @@
         """
 
         super(TestScenario, self).__init__(name, ['on_complete',
+                                                  'on_start',
                                                   'on_stop'])
         self.__ami = ami
         self.__ari_client = ari_client
@@ -51,7 +52,7 @@
         self.__expected_value = expected
         self.__monitor = monitor
         self.__passed = None
-
+        self.__delayed = False
         self.__monitor.suspend()
         self.ari_client.register_observers('on_client_start',
                                            self.on_ari_client_start)
@@ -97,9 +98,8 @@
         """
 
         LOGGER.debug('{0} AriClient started successfully.'.format(self))
-        if not self.suspended:
-            LOGGER.debug('{0} Running scenario.'.format(self))
-            self.run_strategy()
+        self.notify_observers('on_start', None, True)
+        self.__try_run()
 
     def on_ari_client_stop(self, sender, message):
         """Handler for the AriClient on_client_stop event.
@@ -137,11 +137,13 @@
         """Overrides the default behavior of resetting the value of the
         suspended flag."""
 
-        if not self.suspended:
-            return
+        #Run the 'resume' logic first, then do the delayed check.
+        if self.suspended:
+            super(TestScenario, self).resume()
+            self.__monitor.resume()
 
-        super(TestScenario, self).resume()
-        self.__monitor.resume()
+        if not self.suspended and self.__delayed:
+            self.__try_run()
 
     @abstractmethod
     def run_strategy(self):
@@ -149,33 +151,19 @@
 
         return
 
-    def start(self, on_scenario_complete=None):
-        """Starts the test scenario.
-
-        Keyword Arguments:
-        on_scenario_complete   -- A callback (or a list of callbacks) to invoke
-                                  after the scenario completes (optional)
-                                  (default None).
-        """
+    def start(self):
+        """Starts the test scenario."""
 
         LOGGER.debug('{0} Starting scenario.'.format(self))
-        self.register_observers('on_complete', on_scenario_complete)
         self.ari_client.start()
 
-    def stop(self, on_scenario_stop=None):
-        """Stops the scenario execution and tears down its state.
-
-        Keyword Arguments:
-        on_scenario_stop       -- A callback (or a list of callbacks) to invoke
-                                  after the scenario stops (optional)
-                                  (default None).
-        """
+    def stop(self):
+        """Stops the scenario execution and tears down its state."""
 
         if self.ari_client.suspended:
             return
 
         LOGGER.debug('{0} Stopping the scenario.'.format(self))
-        self.register_observers('on_stop', on_scenario_stop)
         self.suspend()
         self.ari_client.stop()
 
@@ -189,6 +177,17 @@
         super(TestScenario, self).suspend()
         self.__monitor.suspend()
 
+    def __try_run(self):
+        """Runs this strategy. Only to be called when this scenario is not
+        suspended and after the ARI client has connected."""
+
+        if not self.suspended:
+            self.__delayed = False
+            LOGGER.debug('{0} Running scenario.'.format(self))
+            self.run_strategy()
+        else:
+            self.__delayed = True
+
     @property
     def actual_value(self):
         """The actual value for this TestScenario."""

-- 
To view, visit https://gerrit.asterisk.org/196
To unsubscribe, visit https://gerrit.asterisk.org/settings

Gerrit-MessageType: merged
Gerrit-Change-Id: Iad3d6b3a092d8f57dfd7855c79b641096de129aa
Gerrit-PatchSet: 1
Gerrit-Project: testsuite
Gerrit-Branch: master
Gerrit-Owner: Ashley Sanders <asanders at digium.com>
Gerrit-Reviewer: Mark Michelson <mmichelson at digium.com>
Gerrit-Reviewer: Matt Jordan <mjordan at digium.com>



More information about the asterisk-commits mailing list