<p>George Joseph has uploaded this change for <strong>review</strong>.</p><p><a href="https://gerrit.asterisk.org/6283">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">single_resource_multiple_changes:  Refactor to remove custom python<br><br>This test (and many other rls tests) had a custom python thing<br>that proxied the sip stream between the test and asterisk and<br>resulted in 3 state machines running at the same time.  All for<br>the sole purpose of testing that when rls notifies are batched,<br>the test only gets the last notify.  It was unstable in high<br>stress environments.<br><br>Replaced with a few extra lines of xml in the scenario file and<br>4 new ami-event/ami-action pairs in yaml.<br><br>Change-Id: Ibfb23af16898cd0780f46deca03abb2815c71c96<br>---<br>D tests/channels/pjsip/subscriptions/rls/lists/nominal/presence/batched/single_resource_multiple_changes/driver.py<br>M tests/channels/pjsip/subscriptions/rls/lists/nominal/presence/batched/single_resource_multiple_changes/sipp/subscribe.xml<br>M tests/channels/pjsip/subscriptions/rls/lists/nominal/presence/batched/single_resource_multiple_changes/test-config.yaml<br>3 files changed, 91 insertions(+), 192 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://gerrit.asterisk.org:29418/testsuite refs/changes/83/6283/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">diff --git a/tests/channels/pjsip/subscriptions/rls/lists/nominal/presence/batched/single_resource_multiple_changes/driver.py b/tests/channels/pjsip/subscriptions/rls/lists/nominal/presence/batched/single_resource_multiple_changes/driver.py<br>deleted file mode 100755<br>index af021e7..0000000<br>--- a/tests/channels/pjsip/subscriptions/rls/lists/nominal/presence/batched/single_resource_multiple_changes/driver.py<br>+++ /dev/null<br>@@ -1,159 +0,0 @@<br>-#!/usr/bin/env python<br>-<br>-import time<br>-import logging<br>-<br>-LOGGER = logging.getLogger(__name__)<br>-<br>-# These are the states that are moved through during the tests. They are listed<br>-# here in the order that they occur throughout the test.<br>-<br>-# Initial state before subscription establishment.<br>-UNESTABLISHED = 1<br>-<br>-# This state is entered after initial SUBSCRIBE-NOTIFY exchange has occurred.<br>-ESTABLISHED = 2<br>-<br>-# This state is entered after Alice's device state is changed to INUSE.<br>-ALICE_STATE_INUSE = 3<br>-<br>-# This state is entered after the NOTIFY changing Alice's device state to<br>-# NOT_INUSE is received.<br>-ALICE_STATE_NOT_INUSE = 4<br>-<br>-# This state is entered after the SUBSCRIBE-NOTIFY exchange for subscription<br>-# refresh has occurred.<br>-REFRESHED = 5<br>-<br>-# This state is entered after Bob's device state is changed to INUSE.<br>-BOB_STATE_INUSE = 6<br>-<br>-# This state is entered after the NOTIFY changing Bob's device state to<br>-# NOT_INUSE is received.<br>-BOB_STATE_NOT_INUSE = 7<br>-<br>-# This state is entered after SUBSCRIBE-NOTIFY exchange to terminate<br>-# subscription has occurred.<br>-TERMINATED = 8<br>-<br>-<br>-class TestDriver(object):<br>-    def __init__(self, module_config, test_object):<br>-        self.ami = None<br>-        self.state = UNESTABLISHED<br>-        self.test_object = test_object<br>-        self.alice_time = 0.0<br>-        self.bob_time = 0.0<br>-        test_object.register_ami_observer(self.ami_connect)<br>-<br>-    def fail_test(self):<br>-        self.test_object.set_passed(False)<br>-        self.test_object.stop_reactor()<br>-<br>-    def ami_connect(self, ami):<br>-        self.ami = ami<br>-        self.ami.registerEvent('TestEvent', self.on_test_event)<br>-        self.ami.registerEvent('DeviceStateChange', self.on_devstate_change)<br>-<br>-    def on_devstate_change(self, ami, event):<br>-        if self.state == ESTABLISHED:<br>-            self.state = ALICE_STATE_INUSE<br>-            LOGGER.debug("State change to {0}".format(ALICE_STATE_INUSE))<br>-            message = {<br>-                'Action': 'SetVar',<br>-                'Variable': 'DEVICE_STATE(Custom:alice)',<br>-                'Value': 'NOT_INUSE'<br>-            }<br>-            self.ami.sendMessage(message)<br>-        elif self.state == REFRESHED:<br>-            self.state = BOB_STATE_INUSE<br>-            LOGGER.debug("State change to {0}".format(BOB_STATE_INUSE))<br>-            message = {<br>-                'Action': 'SetVar',<br>-                'Variable': 'DEVICE_STATE(Custom:bob)',<br>-                'Value': 'NOT_INUSE'<br>-            }<br>-            self.ami.sendMessage(message)<br>-        elif (self.state == ALICE_STATE_INUSE or<br>-              self.state == BOB_STATE_INUSE):<br>-            return<br>-        else:<br>-            LOGGER.error("Unexpected state change ... it's complex")<br>-            self.fail_test()<br>-<br>-    def on_test_event(self, ami, event):<br>-        state = event['state']<br>-        if state == 'SUBSCRIPTION_ESTABLISHED':<br>-            self.on_subscription_established()<br>-        elif state == 'SUBSCRIPTION_REFRESHED':<br>-            self.on_subscription_refreshed()<br>-        elif state == 'SUBSCRIPTION_TERMINATED':<br>-            self.on_subscription_terminated()<br>-        elif state == 'SUBSCRIPTION_STATE_CHANGED':<br>-            self.on_subscription_state_change()<br>-<br>-    def on_subscription_established(self):<br>-        if self.state != UNESTABLISHED:<br>-            LOGGER.error("Unexpected state change from {0}. Expected state "<br>-                         "{1}".format(self.state, UNESTABLISHED))<br>-            self.fail_test()<br>-<br>-        LOGGER.debug("State change to {0}".format(ESTABLISHED))<br>-        self.state = ESTABLISHED<br>-        self.alice_time = time.time()<br>-        message = {<br>-            'Action': 'SetVar',<br>-            'Variable': 'DEVICE_STATE(Custom:alice)',<br>-            'Value': 'InUse'<br>-        }<br>-        self.ami.sendMessage(message)<br>-<br>-    def on_subscription_state_change(self):<br>-        if self.state != ALICE_STATE_INUSE and self.state != BOB_STATE_INUSE:<br>-            LOGGER.error("Unexpected state change from {0}. Expected state "<br>-                         "{1} or {2}".format(self.state, ESTABLISHED,<br>-                                             REFRESHED))<br>-            self.fail_test()<br>-<br>-        if self.state == ALICE_STATE_INUSE:<br>-            interval = time.time() - self.alice_time<br>-            if interval < 5.0:<br>-                LOGGER.error("Interval {0} too brief".format(interval))<br>-                self.fail_test()<br>-            LOGGER.debug("State change to {0}".format(ALICE_STATE_NOT_INUSE))<br>-            self.state = ALICE_STATE_NOT_INUSE<br>-        if self.state == BOB_STATE_INUSE:<br>-            interval = time.time() - self.bob_time<br>-            if time.time() - self.bob_time < 5.0:<br>-                LOGGER.error("Interval {0} too brief".format(interval))<br>-                self.fail_test()<br>-            LOGGER.debug("State change to {0}".format(BOB_STATE_NOT_INUSE))<br>-            self.state = BOB_STATE_NOT_INUSE<br>-<br>-    def on_subscription_refreshed(self):<br>-        if self.state != ALICE_STATE_NOT_INUSE:<br>-            LOGGER.error("Unexpected state change from {0}. Expected state "<br>-                         "{1}".format(self.state, ALICE_STATE_NOT_INUSE))<br>-            self.fail_test()<br>-<br>-        LOGGER.debug("State change to {0}".format(REFRESHED))<br>-        self.state = REFRESHED<br>-        self.bob_time = time.time()<br>-        message = {<br>-            'Action': 'SetVar',<br>-            'Variable': 'DEVICE_STATE(Custom:bob)',<br>-            'Value': 'InUse'<br>-        }<br>-        self.ami.sendMessage(message)<br>-<br>-    def on_subscription_terminated(self):<br>-        if self.state != BOB_STATE_NOT_INUSE:<br>-            LOGGER.error("Unexpected state change from {0}. Expected state "<br>-                         "{1}".format(self.state, BOB_STATE_NOT_INUSE))<br>-            self.fail_test()<br>-<br>-        LOGGER.debug("State change to {0}".format(TERMINATED))<br>-        self.state = TERMINATED<br>-        # If we've made it here, then the test has passed!<br>-        self.test_object.set_passed(True)<br>-        self.test_object.stop_reactor()<br>diff --git a/tests/channels/pjsip/subscriptions/rls/lists/nominal/presence/batched/single_resource_multiple_changes/sipp/subscribe.xml b/tests/channels/pjsip/subscriptions/rls/lists/nominal/presence/batched/single_resource_multiple_changes/sipp/subscribe.xml<br>index 2eac2a0..e640ebd 100644<br>--- a/tests/channels/pjsip/subscriptions/rls/lists/nominal/presence/batched/single_resource_multiple_changes/sipp/subscribe.xml<br>+++ b/tests/channels/pjsip/subscriptions/rls/lists/nominal/presence/batched/single_resource_multiple_changes/sipp/subscribe.xml<br>@@ -35,10 +35,14 @@<br>       </action><br>   </recv><br> <br>-  <!-- Initial NOTIFY upon subscribing --><br>+  <!-- Initial NOTIFY upon subscribing.  Should have both alice and bob --><br>   <recv request="NOTIFY" crlf="true"><br>       <action><br>           <ereg regexp="eventlist" search_in="hdr" header="Require:" check_it="true" assign_to="1" /><br>+<br>+          <ereg regexp="<name>pres_list</name>.+<resource uri=\"sip:alice@127.0.0.1:5060\">.+<resource uri=\"sip:bob@127.0.0.1:5060\">"<br>+              search_in="body" check_it="true" assign_to="1" /><br>+<br>       </action><br>   </recv><br> <br>@@ -57,10 +61,14 @@<br>     ]]><br>   </send><br> <br>-  <!-- NOTIFY upon changing Alice's state --><br>+  <!-- NOTIFY upon changing Alice's state to inuse and back again.<br>+      With batching, should have only alice not inuse. --><br>   <recv request="NOTIFY" crlf="true"><br>       <action><br>           <ereg regexp="eventlist" search_in="hdr" header="Require:" check_it="true" assign_to="1" /><br>+<br>+          <ereg regexp="<presence entity=\"sip:alice@127.0.0.1:5060\"[^>]+>[^<]*<note>Ready</note>[^<]*<tuple id=\"alice\">[^<]*<status>[^<]*<basic>open</basic>[^<]*</status>"<br>+            search_in="body" check_it="true" assign_to="1" /><br>       </action><br>   </recv><br> <br>@@ -134,10 +142,14 @@<br>     ]]><br>   </send><br> <br>-  <!--- NOTIFY upon changing Bob's state --><br>+  <!-- NOTIFY upon changing Bob's state to inuse and back again.<br>+      With batching, should have only bob not inuse. --><br>   <recv request="NOTIFY" crlf="true"><br>       <action><br>           <ereg regexp="eventlist" search_in="hdr" header="Require:" check_it="true" assign_to="1" /><br>+<br>+          <ereg regexp="<presence entity=\"sip:bob@127.0.0.1:5060\"[^>]+>[^<]*<note>Ready</note>[^<]*<tuple id=\"bob\">[^<]*<status>[^<]*<basic>open</basic>[^<]*</status>"<br>+            search_in="body" check_it="true" assign_to="1" /><br>       </action><br>   </recv><br> <br>diff --git a/tests/channels/pjsip/subscriptions/rls/lists/nominal/presence/batched/single_resource_multiple_changes/test-config.yaml b/tests/channels/pjsip/subscriptions/rls/lists/nominal/presence/batched/single_resource_multiple_changes/test-config.yaml<br>index bd9bc51..a1b6573 100644<br>--- a/tests/channels/pjsip/subscriptions/rls/lists/nominal/presence/batched/single_resource_multiple_changes/test-config.yaml<br>+++ b/tests/channels/pjsip/subscriptions/rls/lists/nominal/presence/batched/single_resource_multiple_changes/test-config.yaml<br>@@ -13,7 +13,6 @@<br>         - buildoption: 'TEST_FRAMEWORK'<br>         - python: 'twisted'<br>         - python: 'starpy'<br>-        - python: 'lxml'<br>         - asterisk: 'res_pjsip'<br>         - asterisk: 'res_pjsip_pubsub'<br>     tags:<br>@@ -21,43 +20,90 @@<br>         - pjsip<br> <br> test-modules:<br>-    add-test-to-search-path: 'True'<br>-    add-to-search-path:<br>-        -<br>-            'tests/channels/pjsip/subscriptions/rls'<br>     test-object:<br>         config-section: 'test-case-config'<br>         typename: 'sipp.SIPpTestCase'<br>     modules:<br>         -<br>-            config-section: 'test-config'<br>-            typename: 'rls_test.RLSTest'<br>-        -<br>-            typename: 'driver.TestDriver'<br>+            config-section: 'ami-config'<br>+            typename: 'pluggable_modules.EventActionModule'<br> <br> test-case-config:<br>-    stop-after-scenarios: False<br>+    reactor-timeout: 15<br>+    stop-after-scenarios: True<br>     test-iterations:<br>         -<br>             scenarios:<br>-                - { 'target': '127.0.0.1:5061', 'key-args': {'scenario': 'subscribe.xml', '-i': '127.0.0.1', '-p': '5062', '-s': 'pres_list'} }<br>+                - { 'target': '127.0.0.1:5060', 'key-args': {'scenario': 'subscribe.xml', '-i': '127.0.0.1', '-p': '5062', '-s': 'pres_list'} }<br> <br>-test-config:<br>-    stop-test-after-notifys: False<br>-    list-name: 'pres_list'<br>-    packets:<br>-        -<br>-            full-state: True<br>-            resources: { 'alice': {'type': 'PIDF', 'state': 'active'}, 'bob': {'type': 'PIDF', 'state': 'active'}}<br>-        -<br>-            full-state: False<br>-            resources: { 'alice': {'type': 'PIDF', 'state': 'active' } }<br>-        -<br>-            full-state: True<br>-            resources: { 'alice': {'type': 'PIDF', 'state': 'active'}, 'bob': {'type': 'PIDF', 'state': 'active'}}<br>-        -<br>-            full-state: False<br>-            resources: { 'bob': {'type': 'PIDF', 'state': 'active' } }<br>-        -<br>-            full-state: True<br>-            resources: { 'alice': {'type': 'PIDF', 'state': 'terminated'}, 'bob': {'type': 'PIDF', 'state': 'terminated'}}<br>+ami-config:<br>+    -<br>+        ami-events:<br>+            conditions:<br>+                match:<br>+                    Event: 'TestEvent'<br>+                    State: 'SUBSCRIPTION_ESTABLISHED'<br>+                    Resource: 'pres_list'<br>+            count: '1'<br>+        ami-actions:<br>+            action:<br>+                Action: 'SetVar'<br>+                Variable: 'DEVICE_STATE(Custom:alice)'<br>+                Value: 'InUse'<br>+    -<br>+        ami-events:<br>+            conditions:<br>+                match:<br>+                    Event: 'DeviceStateChange'<br>+                    Device: 'Custom:alice'<br>+                    State: 'INUSE'<br>+            count: '1'<br>+        ami-actions:<br>+            action:<br>+                Action: 'SetVar'<br>+                Variable: 'DEVICE_STATE(Custom:alice)'<br>+                Value: 'NOT_INUSE'<br>+    -<br>+        ami-events:<br>+            conditions:<br>+                match:<br>+                    Event: 'DeviceStateChange'<br>+                    Device: 'Custom:alice'<br>+                    State: 'NOT_INUSE'<br>+            count: '1'<br>+    -<br>+        ami-events:<br>+            conditions:<br>+                match:<br>+                    Event: 'TestEvent'<br>+                    State: 'SUBSCRIPTION_REFRESHED'<br>+            requirements:<br>+                match:<br>+                    Resource: 'pres_list'<br>+            count: '1'<br>+        ami-actions:<br>+            action:<br>+                Action: 'SetVar'<br>+                Variable: 'DEVICE_STATE(Custom:bob)'<br>+                Value: 'InUse'<br>+    -<br>+        ami-events:<br>+            conditions:<br>+                match:<br>+                    Event: 'DeviceStateChange'<br>+                    Device: 'Custom:bob'<br>+                    State: 'INUSE'<br>+            count: '1'<br>+        ami-actions:<br>+            action:<br>+                Action: 'SetVar'<br>+                Variable: 'DEVICE_STATE(Custom:bob)'<br>+                Value: 'NOT_INUSE'<br>+    -<br>+        ami-events:<br>+            conditions:<br>+                match:<br>+                    Event: 'DeviceStateChange'<br>+                    Device: 'Custom:bob'<br>+                    State: 'NOT_INUSE'<br>+            count: '1'<br></pre><p>To view, visit <a href="https://gerrit.asterisk.org/6283">change 6283</a>. To unsubscribe, visit <a href="https://gerrit.asterisk.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://gerrit.asterisk.org/6283"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: testsuite </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>
<div style="display:none"> Gerrit-Change-Id: Ibfb23af16898cd0780f46deca03abb2815c71c96 </div>
<div style="display:none"> Gerrit-Change-Number: 6283 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: George Joseph <gjoseph@digium.com> </div>