<p>Jenkins2 <strong>merged</strong> this change.</p><p><a href="https://gerrit.asterisk.org/6283">View Change</a></p><div style="white-space:pre-wrap">Approvals:
Joshua Colp: Looks good to me, but someone else must approve
Kevin Harwell: Looks good to me, approved
Jenkins2: Approved for Submit
</div><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;">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: merged </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>
<div style="display:none"> Gerrit-Reviewer: Jenkins2 </div>
<div style="display:none"> Gerrit-Reviewer: Joshua Colp <jcolp@digium.com> </div>
<div style="display:none"> Gerrit-Reviewer: Kevin Harwell <kharwell@digium.com> </div>