[Asterisk-code-review] Testsuite: batched rls subscription failure (testsuite[master])

Ashley Sanders asteriskteam at digium.com
Wed Oct 14 15:23:47 CDT 2015


Ashley Sanders has uploaded a new change for review.

  https://gerrit.asterisk.org/1442

Change subject: Testsuite: batched rls subscription failure
......................................................................

Testsuite: batched rls subscription failure

While this does not actually correct the issue with the test failure (which
incidentally turns out is not localized to this test), this patch modifies the
the test config structure such that the full_state and resources collections
are now represented by a single collection, packets. Having them disconnected
in the configuration was obscuring the intent.

This is part two (3) of an n-patch series of refactorings to help determine the
root cause of the test failure and correct pylint issues.

ASTERISK-25430
Reported By: Ashley Sanders

Change-Id: I3bc60588b1430d152de608a0c2a733a843411666
---
A tests/channels/pjsip/subscriptions/rls/fix_test_configs.py
M tests/channels/pjsip/subscriptions/rls/lists/nominal/mwi/batched/basic/test-config.yaml
M tests/channels/pjsip/subscriptions/rls/lists/nominal/mwi/batched/multiple_resources_single_change/test-config.yaml
M tests/channels/pjsip/subscriptions/rls/lists/nominal/mwi/batched/resubscription_interruption/test-config.yaml
M tests/channels/pjsip/subscriptions/rls/lists/nominal/mwi/batched/single_resource_multiple_changes/test-config.yaml
M tests/channels/pjsip/subscriptions/rls/lists/nominal/mwi/batched/termination_interruption/test-config.yaml
M tests/channels/pjsip/subscriptions/rls/lists/nominal/mwi/full_state/test-config.yaml
M tests/channels/pjsip/subscriptions/rls/lists/nominal/mwi/initial_notify/test-config.yaml
M tests/channels/pjsip/subscriptions/rls/lists/nominal/mwi/partial_state/test-config.yaml
M tests/channels/pjsip/subscriptions/rls/lists/nominal/mwi/resubscribe_full_state/test-config.yaml
M tests/channels/pjsip/subscriptions/rls/lists/nominal/mwi/termination_full_state/test-config.yaml
M tests/channels/pjsip/subscriptions/rls/lists/nominal/presence/batched/basic/driver.py
M tests/channels/pjsip/subscriptions/rls/lists/nominal/presence/batched/basic/test-config.yaml
M tests/channels/pjsip/subscriptions/rls/lists/nominal/presence/batched/multiple_resources_single_change/test-config.yaml
M tests/channels/pjsip/subscriptions/rls/lists/nominal/presence/batched/resubscription_interruption/test-config.yaml
M tests/channels/pjsip/subscriptions/rls/lists/nominal/presence/batched/single_resource_multiple_changes/test-config.yaml
M tests/channels/pjsip/subscriptions/rls/lists/nominal/presence/batched/termination_interruption/test-config.yaml
M tests/channels/pjsip/subscriptions/rls/lists/nominal/presence/full_state/test-config.yaml
M tests/channels/pjsip/subscriptions/rls/lists/nominal/presence/initial_notify/test-config.yaml
M tests/channels/pjsip/subscriptions/rls/lists/nominal/presence/partial_state/test-config.yaml
M tests/channels/pjsip/subscriptions/rls/lists/nominal/presence/resubscribe_full_state/test-config.yaml
M tests/channels/pjsip/subscriptions/rls/lists/nominal/presence/termination_full_state/test-config.yaml
M tests/channels/pjsip/subscriptions/rls/lists/off_nominal/mwi/resource_duplication/test-config.yaml
M tests/channels/pjsip/subscriptions/rls/lists/off_nominal/mwi/some_list_resources_exist/test-config.yaml
M tests/channels/pjsip/subscriptions/rls/lists/off_nominal/presence/resource_duplication/test-config.yaml
M tests/channels/pjsip/subscriptions/rls/lists/off_nominal/presence/some_list_resources_exist/test-config.yaml
M tests/channels/pjsip/subscriptions/rls/lists_of_lists/nominal/mwi/batched/test-config.yaml
M tests/channels/pjsip/subscriptions/rls/lists_of_lists/nominal/mwi/full_state_alice/test-config.yaml
M tests/channels/pjsip/subscriptions/rls/lists_of_lists/nominal/mwi/full_state_carol/test-config.yaml
M tests/channels/pjsip/subscriptions/rls/lists_of_lists/nominal/mwi/initial_notify/test-config.yaml
M tests/channels/pjsip/subscriptions/rls/lists_of_lists/nominal/mwi/partial_state_alice/test-config.yaml
M tests/channels/pjsip/subscriptions/rls/lists_of_lists/nominal/mwi/partial_state_carol/test-config.yaml
M tests/channels/pjsip/subscriptions/rls/lists_of_lists/nominal/mwi/resubscribe_full_state/test-config.yaml
M tests/channels/pjsip/subscriptions/rls/lists_of_lists/nominal/mwi/termination_full_state/test-config.yaml
M tests/channels/pjsip/subscriptions/rls/lists_of_lists/nominal/presence/batched/test-config.yaml
M tests/channels/pjsip/subscriptions/rls/lists_of_lists/nominal/presence/full_state_alice/test-config.yaml
M tests/channels/pjsip/subscriptions/rls/lists_of_lists/nominal/presence/full_state_carol/test-config.yaml
M tests/channels/pjsip/subscriptions/rls/lists_of_lists/nominal/presence/initial_notify/test-config.yaml
M tests/channels/pjsip/subscriptions/rls/lists_of_lists/nominal/presence/listception_initial_notify/test-config.yaml
M tests/channels/pjsip/subscriptions/rls/lists_of_lists/nominal/presence/partial_state_alice/test-config.yaml
M tests/channels/pjsip/subscriptions/rls/lists_of_lists/nominal/presence/partial_state_carol/test-config.yaml
M tests/channels/pjsip/subscriptions/rls/lists_of_lists/nominal/presence/resubscribe_full_state/test-config.yaml
M tests/channels/pjsip/subscriptions/rls/lists_of_lists/nominal/presence/termination_full_state/test-config.yaml
M tests/channels/pjsip/subscriptions/rls/lists_of_lists/off_nominal/mwi/resource_duplication/test-config.yaml
M tests/channels/pjsip/subscriptions/rls/lists_of_lists/off_nominal/mwi/shared_name_w_list_support/test-config.yaml
M tests/channels/pjsip/subscriptions/rls/lists_of_lists/off_nominal/presence/resource_duplication/test-config.yaml
M tests/channels/pjsip/subscriptions/rls/lists_of_lists/off_nominal/presence/shared_name_w_list_support/test-config.yaml
M tests/channels/pjsip/subscriptions/rls/rls_test.py
48 files changed, 884 insertions(+), 634 deletions(-)


  git pull ssh://gerrit.asterisk.org:29418/testsuite refs/changes/42/1442/1

diff --git a/tests/channels/pjsip/subscriptions/rls/fix_test_configs.py b/tests/channels/pjsip/subscriptions/rls/fix_test_configs.py
new file mode 100755
index 0000000..30e7dd1
--- /dev/null
+++ b/tests/channels/pjsip/subscriptions/rls/fix_test_configs.py
@@ -0,0 +1,163 @@
+#!/usr/bin/env python
+'''
+Copyright (C) 2015, Digium, Inc.
+Ashley Sanders <asanders at digium.com>
+
+This program is free software, distributed under the terms of
+the GNU General Public License Version 2.
+'''
+
+import yaml
+import sys
+import os
+import errno
+import subprocess
+import optparse
+import time
+import yaml
+import shutil
+import xml.dom
+import random
+import select
+import traceback
+
+from collections import OrderedDict
+
+TESTS_CONFIG = "tests.yaml"
+
+def ordered_load(stream, Loader=yaml.Loader, object_pairs_hook=OrderedDict):
+    class OrderedLoader(Loader):
+        pass
+    def construct_mapping(loader, node):
+        loader.flatten_mapping(node)
+        return object_pairs_hook(loader.construct_pairs(node))
+    OrderedLoader.add_constructor(
+        yaml.resolver.BaseResolver.DEFAULT_MAPPING_TAG,
+        construct_mapping)
+    return yaml.load(stream, OrderedLoader)
+
+def ordered_dump(data, stream=None, Dumper=yaml.Dumper, **kwds):
+    class OrderedDumper(Dumper):
+        pass
+    def _dict_representer(dumper, data):
+        return dumper.represent_mapping(
+            yaml.resolver.BaseResolver.DEFAULT_MAPPING_TAG,
+            data.items())
+    OrderedDumper.add_representer(OrderedDict, _dict_representer)
+    return yaml.dump(data, stream, OrderedDumper, **kwds)
+
+
+class TestFixer(object):
+    def __init__(self, test_dir):
+        self.tests = self._parse_test_yaml(test_dir)
+
+    def _parse_test_yaml(self, test_dir):
+        tests = []
+        try:
+            f = open("%s/%s" % (test_dir, TESTS_CONFIG), "r")
+        except IOError:
+            print "Failed to open %s/%s" % (test_dir, TESTS_CONFIG)
+            return tests
+        except:
+            print "Unexpected error: %s" % sys.exc_info()[0]
+            return tests
+
+        config = yaml.load(f)
+        f.close()
+
+        for t in config["tests"]:
+            for val in t:
+                path = "%s/%s" % (test_dir, t[val])
+                if val == "test":
+                    tests.append(path)
+                elif val == "dir":
+                    tests += self._parse_test_yaml(path)
+
+        return tests
+
+    def run(self):
+
+        for t in self.tests:
+            print "--> Fixing test-config.yaml for test '%s' ..." % t
+            my_test_config = "%s/test-config.yaml" % t
+            my_config = self.get_config(my_test_config)
+
+            if not my_config:
+                print "ERROR: Failed to load configuration for test '%s'" % t
+                return
+
+            if not 'test-modules' in my_config:
+                print "No test-modules block in configuration. Nothing to fix."
+                continue
+            if 'modules' not in my_config['test-modules']:
+                print "No modules block in test-modules block. Nothing to fix."
+                continue
+
+            for module in my_config['test-modules']['modules']:
+                if ('config-section' in module
+                    and module['config-section'] in my_config):
+                    if module['typename'] == 'rls_test.RLSTest':
+                        valid = self.check_section(t, my_test_config, my_config, module["config-section"])
+                        if not valid:
+                            return False
+
+        return True
+
+    def check_section(self, test_name, my_test_config, my_config, config_section):
+
+        clean_test_config = my_test_config.replace("external", "clean")
+        clean_config = self.get_config(clean_test_config)
+
+        my_module_config = my_config[config_section]
+        clean_module_config = clean_config[config_section]
+
+        my_packets = my_module_config["packets"]
+        clean_resources = clean_module_config["resources"]
+        clean_full_states = clean_module_config["full_state"]
+
+        if clean_full_states is None:
+            if clean_resources is None:
+                print "DANGER WILL ROBINSON! %s is broken." % test_name
+                return False
+        elif clean_resources is None:
+                print "DANGER WILL ROBINSON! %s is broken." % test_name
+                return False
+
+        if my_packets is None:
+            print "DANGER WILL ROBINSON! %s is broken." % test_name
+            return False
+
+        for (x, packet) in enumerate(my_packets):
+            if len(clean_full_states) <= x:
+                print "DANGER WILL ROBINSON! %s FULLSTATE lengths are different." % test_name
+                return False
+
+            if clean_full_states[x] != packet["full_state"]:
+                print "DANGER WILL ROBINSON! %s FULLSTATE '%s' values are different." % (test_name, x)
+                return False
+
+            if len(clean_resources) <= x:
+                print "DANGER WILL ROBINSON! %s RESOURCES/PACKETS lengths are different." % test_name
+                return False
+
+            if cmp(clean_resources[x], packet["resources"]) != 0:
+                print "DANGER WILL ROBINSON! %s RESOURCE[%s] values are different." % (test_name, x)
+                return False
+
+        return True
+
+    def get_config(self, config_path):
+        config = None
+        with open(config_path, "r") as config_file:
+            config = ordered_load(config_file, yaml.SafeLoader)
+        return config
+
+def main(argv=None):
+    test_fixer = TestFixer(os.path.dirname(os.path.realpath(__file__)))
+    #print "Fixing test-config.yaml files..."
+    if not test_fixer.run():
+        print "Something is very, very wrong. Check the printed statements."
+    print "All clear."
+
+if __name__ == "__main__":
+    sys.exit(main() or 0)
diff --git a/tests/channels/pjsip/subscriptions/rls/lists/nominal/mwi/batched/basic/test-config.yaml b/tests/channels/pjsip/subscriptions/rls/lists/nominal/mwi/batched/basic/test-config.yaml
index 2deddcb..229da31 100644
--- a/tests/channels/pjsip/subscriptions/rls/lists/nominal/mwi/batched/basic/test-config.yaml
+++ b/tests/channels/pjsip/subscriptions/rls/lists/nominal/mwi/batched/basic/test-config.yaml
@@ -42,7 +42,7 @@
     modules:
         -
             config-section: 'test-config'
-            typename: 'rls_test.IntegrityCheck'
+            typename: 'rls_test.RLSTest'
         -
             typename: 'driver.TestDriver'
 
@@ -53,29 +53,20 @@
                 - { 'key-args': {'scenario': 'subscribe.xml', '-i': '127.0.0.1', '-p': '5061', '-s': 'mail_list'} }
 
 test-config:
-    list_name: 'mail_list'
-    resources:
+    list-name: 'mail_list'
+    packets:
         -
-            { 'alice': {'type': 'MWI', 'state': 'active', 'voice_message': '0/0 (0/0)', 'messages_waiting': 'no'},
-              'bob': {'type': 'MWI', 'state': 'active', 'voice_message': '0/0 (0/0)', 'messages_waiting': 'no'} }
+            full-state: True
+            resources: { 'alice': {'type': 'MWI', 'state': 'active', 'voice_message': '0/0 (0/0)', 'messages_waiting': 'no'}, 'bob': {'type': 'MWI', 'state': 'active', 'voice_message': '0/0 (0/0)', 'messages_waiting': 'no'} }
         -
-            { 'alice': {'type': 'MWI', 'state': 'active', 'voice_message': '1/0 (0/0)', 'messages_waiting': 'yes'}}
+            full-state: False
+            resources: { 'alice': {'type': 'MWI', 'state': 'active', 'voice_message': '1/0 (0/0)', 'messages_waiting': 'yes'} }
         -
-            { 'alice': {'type': 'MWI', 'state': 'active', 'voice_message': '1/0 (0/0)', 'messages_waiting': 'yes'},
-              'bob': {'type': 'MWI', 'state': 'active', 'voice_message': '0/0 (0/0)', 'messages_waiting': 'no'} }
+            full-state: True
+            resources: { 'alice': {'type': 'MWI', 'state': 'active', 'voice_message': '1/0 (0/0)', 'messages_waiting': 'yes'}, 'bob': {'type': 'MWI', 'state': 'active', 'voice_message': '0/0 (0/0)', 'messages_waiting': 'no'} }
         -
-            { 'bob': {'type': 'MWI', 'state': 'active', 'voice_message': '1/0 (0/0)', 'messages_waiting': 'yes'} }
+            full-state: False
+            resources: { 'bob': {'type': 'MWI', 'state': 'active', 'voice_message': '1/0 (0/0)', 'messages_waiting': 'yes'} }
         -
-            { 'alice': {'type': 'MWI', 'state': 'terminated', 'voice_message': '1/0 (0/0)', 'messages_waiting': 'yes'},
-              'bob': {'type': 'MWI', 'state': 'terminated', 'voice_message': '1/0 (0/0)', 'messages_waiting': 'yes'} }
-    full_state:
-        -
-            True
-        -
-            False
-        -
-            True
-        -
-            False
-        -
-            True
+            full-state: True
+            resources: { 'alice': {'type': 'MWI', 'state': 'terminated', 'voice_message': '1/0 (0/0)', 'messages_waiting': 'yes'}, 'bob': {'type': 'MWI', 'state': 'terminated', 'voice_message': '1/0 (0/0)', 'messages_waiting': 'yes'} }
diff --git a/tests/channels/pjsip/subscriptions/rls/lists/nominal/mwi/batched/multiple_resources_single_change/test-config.yaml b/tests/channels/pjsip/subscriptions/rls/lists/nominal/mwi/batched/multiple_resources_single_change/test-config.yaml
index 83bf82f..8bf223d 100644
--- a/tests/channels/pjsip/subscriptions/rls/lists/nominal/mwi/batched/multiple_resources_single_change/test-config.yaml
+++ b/tests/channels/pjsip/subscriptions/rls/lists/nominal/mwi/batched/multiple_resources_single_change/test-config.yaml
@@ -36,7 +36,7 @@
     modules:
         -
             config-section: 'test-config'
-            typename: 'rls_test.IntegrityCheck'
+            typename: 'rls_test.RLSTest'
         -
             typename: 'driver.TestDriver'
 
@@ -47,31 +47,20 @@
                 - { 'key-args': {'scenario': 'subscribe.xml', '-i': '127.0.0.1', '-p': '5061', '-s': 'mail_list'} }
 
 test-config:
-    list_name: 'mail_list'
-    resources:
+    list-name: 'mail_list'
+    packets:
         -
-            { 'alice': {'type': 'MWI', 'state': 'active', 'voice_message': '0/0 (0/0)', 'messages_waiting': 'no'},
-              'bob': {'type': 'MWI', 'state': 'active', 'voice_message': '0/0 (0/0)', 'messages_waiting': 'no'} }
+            full-state: True
+            resources: { 'alice': {'type': 'MWI', 'state': 'active', 'voice_message': '0/0 (0/0)', 'messages_waiting': 'no'}, 'bob': {'type': 'MWI', 'state': 'active', 'voice_message': '0/0 (0/0)', 'messages_waiting': 'no'} }
         -
-            { 'alice': {'type': 'MWI', 'state': 'active', 'voice_message': '1/0 (0/0)', 'messages_waiting': 'yes'},
-              'bob': {'type': 'MWI', 'state': 'active', 'voice_message': '1/0 (0/0)', 'messages_waiting': 'yes'} }
+            full-state: False
+            resources: { 'alice': {'type': 'MWI', 'state': 'active', 'voice_message': '1/0 (0/0)', 'messages_waiting': 'yes'}, 'bob': {'type': 'MWI', 'state': 'active', 'voice_message': '1/0 (0/0)', 'messages_waiting': 'yes'} }
         -
-            { 'alice': {'type': 'MWI', 'state': 'active', 'voice_message': '1/0 (0/0)', 'messages_waiting': 'yes'},
-              'bob': {'type': 'MWI', 'state': 'active', 'voice_message': '1/0 (0/0)', 'messages_waiting': 'yes'} }
+            full-state: True
+            resources: { 'alice': {'type': 'MWI', 'state': 'active', 'voice_message': '1/0 (0/0)', 'messages_waiting': 'yes'}, 'bob': {'type': 'MWI', 'state': 'active', 'voice_message': '1/0 (0/0)', 'messages_waiting': 'yes'} }
         -
-            { 'alice': {'type': 'MWI', 'state': 'active', 'voice_message': '2/0 (0/0)', 'messages_waiting': 'yes'},
-              'bob': {'type': 'MWI', 'state': 'active', 'voice_message': '2/0 (0/0)', 'messages_waiting': 'yes'} }
+            full-state: False
+            resources: { 'alice': {'type': 'MWI', 'state': 'active', 'voice_message': '2/0 (0/0)', 'messages_waiting': 'yes'}, 'bob': {'type': 'MWI', 'state': 'active', 'voice_message': '2/0 (0/0)', 'messages_waiting': 'yes'} }
         -
-            { 'alice': {'type': 'MWI', 'state': 'terminated', 'voice_message': '2/0 (0/0)', 'messages_waiting': 'yes'},
-              'bob': {'type': 'MWI', 'state': 'terminated', 'voice_message': '2/0 (0/0)', 'messages_waiting': 'yes'} }
-    full_state:
-        -
-            True
-        -
-            False
-        -
-            True
-        -
-            False
-        -
-            True
+            full-state: True
+            resources: { 'alice': {'type': 'MWI', 'state': 'terminated', 'voice_message': '2/0 (0/0)', 'messages_waiting': 'yes'}, 'bob': {'type': 'MWI', 'state': 'terminated', 'voice_message': '2/0 (0/0)', 'messages_waiting': 'yes'} }
diff --git a/tests/channels/pjsip/subscriptions/rls/lists/nominal/mwi/batched/resubscription_interruption/test-config.yaml b/tests/channels/pjsip/subscriptions/rls/lists/nominal/mwi/batched/resubscription_interruption/test-config.yaml
index dfb7949..d50dc4a 100644
--- a/tests/channels/pjsip/subscriptions/rls/lists/nominal/mwi/batched/resubscription_interruption/test-config.yaml
+++ b/tests/channels/pjsip/subscriptions/rls/lists/nominal/mwi/batched/resubscription_interruption/test-config.yaml
@@ -38,7 +38,7 @@
     modules:
         -
             config-section: 'test-config'
-            typename: 'rls_test.IntegrityCheck'
+            typename: 'rls_test.RLSTest'
         -
             typename: 'driver.TestDriver'
 
@@ -49,17 +49,12 @@
                 - { 'key-args': {'scenario': 'subscribe.xml', '-i': '127.0.0.1', '-p': '5061', '-s': 'mail_list', '-d': '3000'} }
 
 test-config:
-    stop_after_notifys: False
-    list_name: 'mail_list'
-    resources:
+    stop-test-after-notifys: False
+    list-name 'mail_list'
+    packets:
         -
-            { 'alice': {'type': 'MWI', 'state': 'active', 'voice_message': '0/0 (0/0)', 'messages_waiting': 'no'},
-              'bob': {'type': 'MWI', 'state': 'active', 'voice_message': '0/0 (0/0)', 'messages_waiting': 'no'} }
+            full-state: True
+            resources: { 'alice': {'type': 'MWI', 'state': 'active', 'voice_message': '0/0 (0/0)', 'messages_waiting': 'no'}, 'bob': {'type': 'MWI', 'state': 'active', 'voice_message': '0/0 (0/0)', 'messages_waiting': 'no'} }
         -
-            { 'alice': {'type': 'MWI', 'state': 'active', 'voice_message': '1/0 (0/0)', 'messages_waiting': 'yes'},
-              'bob': {'type': 'MWI', 'state': 'active', 'voice_message': '0/0 (0/0)', 'messages_waiting': 'no'} }
-    full_state:
-        -
-            True
-        -
-            True
+            full-state: True
+            resources: { 'alice': {'type': 'MWI', 'state': 'active', 'voice_message': '1/0 (0/0)', 'messages_waiting': 'yes'}, 'bob': {'type': 'MWI', 'state': 'active', 'voice_message': '0/0 (0/0)', 'messages_waiting': 'no'} }
diff --git a/tests/channels/pjsip/subscriptions/rls/lists/nominal/mwi/batched/single_resource_multiple_changes/test-config.yaml b/tests/channels/pjsip/subscriptions/rls/lists/nominal/mwi/batched/single_resource_multiple_changes/test-config.yaml
index 1a7bed0..e5bc39e 100644
--- a/tests/channels/pjsip/subscriptions/rls/lists/nominal/mwi/batched/single_resource_multiple_changes/test-config.yaml
+++ b/tests/channels/pjsip/subscriptions/rls/lists/nominal/mwi/batched/single_resource_multiple_changes/test-config.yaml
@@ -36,7 +36,7 @@
     modules:
         -
             config-section: 'test-config'
-            typename: 'rls_test.IntegrityCheck'
+            typename: 'rls_test.RLSTest'
         -
             typename: 'driver.TestDriver'
 
@@ -47,29 +47,69 @@
                 - { 'key-args': {'scenario': 'subscribe.xml', '-i': '127.0.0.1', '-p': '5061', '-s': 'mail_list'} }
 
 test-config:
-    list_name: 'mail_list'
-    resources:
+    list-name: 'mail_list'
+    packets:
         -
-            { 'alice': {'type': 'MWI', 'state': 'active', 'voice_message': '0/0 (0/0)', 'messages_waiting': 'no'},
-              'bob': {'type': 'MWI', 'state': 'active', 'voice_message': '0/0 (0/0)', 'messages_waiting': 'no'} }
+            full-state: True
+            resources: {
+                'alice': {
+                    'type': 'MWI',
+                    'state': 'active',
+                    'voice_message': '0/0 (0/0)',
+                    'messages_waiting': 'no'},
+                    'bob': {'type': 'MWI',
+                    'state': 'active',
+                    'voice_message': '0/0 (0/0)',
+                    'messages_waiting': 'no'
+                    }
+                }
         -
-            { 'alice': {'type': 'MWI', 'state': 'active', 'voice_message': '2/0 (0/0)', 'messages_waiting': 'yes'}}
+            full-state: False
+            resources: {
+                    'alice': {
+                    'type': 'MWI',
+                    'state': 'active',
+                    'voice_message': '2/0 (0/0)',
+                    'messages_waiting': 'yes'
+                    }
+                }
         -
-            { 'alice': {'type': 'MWI', 'state': 'active', 'voice_message': '2/0 (0/0)', 'messages_waiting': 'yes'},
-              'bob': {'type': 'MWI', 'state': 'active', 'voice_message': '0/0 (0/0)', 'messages_waiting': 'no'} }
+            full-state: True
+            resources: {
+                    'alice': {
+                    'type': 'MWI',
+                    'state': 'active',
+                    'voice_message': '2/0 (0/0)',
+                    'messages_waiting': 'yes'},
+                    'bob': {
+                    'type': 'MWI',
+                    'state': 'active',
+                    'voice_message': '0/0 (0/0)',
+                    'messages_waiting': 'no'
+                    }
+                }
         -
-            { 'bob': {'type': 'MWI', 'state': 'active', 'voice_message': '2/0 (0/0)', 'messages_waiting': 'yes'} }
+            full-state: False
+            resources: {
+                    'bob': {
+                    'type': 'MWI',
+                    'state': 'active',
+                    'voice_message': '2/0 (0/0)',
+                    'messages_waiting': 'yes'
+                    }
+                }
         -
-            { 'alice': {'type': 'MWI', 'state': 'terminated', 'voice_message': '2/0 (0/0)', 'messages_waiting': 'yes'},
-              'bob': {'type': 'MWI', 'state': 'terminated', 'voice_message': '2/0 (0/0)', 'messages_waiting': 'yes'} }
-    full_state:
-        -
-            True
-        -
-            False
-        -
-            True
-        -
-            False
-        -
-            True
+            full-state: True
+            resources: {
+                    'alice': {
+                    'type': 'MWI',
+                    'state': 'terminated',
+                    'voice_message': '2/0 (0/0)',
+                    'messages_waiting': 'yes'},
+                    'bob': {
+                    'type': 'MWI',
+                    'state': 'terminated',
+                    'voice_message': '2/0 (0/0)',
+                    'messages_waiting': 'yes'
+                    }
+                }
diff --git a/tests/channels/pjsip/subscriptions/rls/lists/nominal/mwi/batched/termination_interruption/test-config.yaml b/tests/channels/pjsip/subscriptions/rls/lists/nominal/mwi/batched/termination_interruption/test-config.yaml
index b0cc651..1ec8217 100644
--- a/tests/channels/pjsip/subscriptions/rls/lists/nominal/mwi/batched/termination_interruption/test-config.yaml
+++ b/tests/channels/pjsip/subscriptions/rls/lists/nominal/mwi/batched/termination_interruption/test-config.yaml
@@ -38,7 +38,7 @@
     modules:
         -
             config-section: 'test-config'
-            typename: 'rls_test.IntegrityCheck'
+            typename: 'rls_test.RLSTest'
         -
             typename: 'driver.TestDriver'
 
@@ -49,17 +49,12 @@
                 - { 'key-args': {'scenario': 'subscribe.xml', '-i': '127.0.0.1', '-p': '5061', '-s': 'mail_list', '-d': '3000'} }
 
 test-config:
-    stop_after_notifys: False
-    list_name: 'mail_list'
-    resources:
+    stop-test-after-notifys: False
+    list-name 'mail_list'
+    packets:
         -
-            { 'alice': {'type': 'MWI', 'state': 'active', 'voice_message': '0/0 (0/0)', 'messages_waiting': 'no'},
-              'bob': {'type': 'MWI', 'state': 'active', 'voice_message': '0/0 (0/0)', 'messages_waiting': 'no'} }
+            full-state: True
+            resources: { 'alice': {'type': 'MWI', 'state': 'active', 'voice_message': '0/0 (0/0)', 'messages_waiting': 'no'}, 'bob': {'type': 'MWI', 'state': 'active', 'voice_message': '0/0 (0/0)', 'messages_waiting': 'no'} }
         -
-            { 'alice': {'type': 'MWI', 'state': 'terminated', 'voice_message': '1/0 (0/0)', 'messages_waiting': 'yes'},
-              'bob': {'type': 'MWI', 'state': 'terminated', 'voice_message': '0/0 (0/0)', 'messages_waiting': 'no'} }
-    full_state:
-        -
-            True
-        -
-            True
+            full-state: True
+            resources: { 'alice': {'type': 'MWI', 'state': 'terminated', 'voice_message': '1/0 (0/0)', 'messages_waiting': 'yes'}, 'bob': {'type': 'MWI', 'state': 'terminated', 'voice_message': '0/0 (0/0)', 'messages_waiting': 'no'} }
diff --git a/tests/channels/pjsip/subscriptions/rls/lists/nominal/mwi/full_state/test-config.yaml b/tests/channels/pjsip/subscriptions/rls/lists/nominal/mwi/full_state/test-config.yaml
index c066da5..5425313 100644
--- a/tests/channels/pjsip/subscriptions/rls/lists/nominal/mwi/full_state/test-config.yaml
+++ b/tests/channels/pjsip/subscriptions/rls/lists/nominal/mwi/full_state/test-config.yaml
@@ -35,7 +35,7 @@
     modules:
         -
             config-section: 'test-config'
-            typename: 'rls_test.IntegrityCheck'
+            typename: 'rls_test.RLSTest'
 
 test-case-config:
     test-iterations:
@@ -44,19 +44,14 @@
                 - { 'key-args': {'scenario': 'list_subscribe.xml', '-i': '127.0.0.1', '-p': '5061', '-s': 'mail_list'} }
 
 test-config:
-    list_name: 'mail_list'
-    resources:
+    list-name: 'mail_list'
+    packets:
         -
-            { 'alice': {'type': 'MWI', 'state': 'active', 'voice_message': '0/0 (0/0)', 'messages_waiting': 'no'},
-              'bob': {'type': 'MWI', 'state': 'active', 'voice_message': '0/0 (0/0)', 'messages_waiting': 'no'} }
+            full-state: True
+            resources: { 'alice': {'type': 'MWI', 'state': 'active', 'voice_message': '0/0 (0/0)', 'messages_waiting': 'no'}, 'bob': {'type': 'MWI', 'state': 'active', 'voice_message': '0/0 (0/0)', 'messages_waiting': 'no'} }
         -
-            { 'alice': {'type': 'MWI', 'state': 'active', 'voice_message': '1/2 (0/0)', 'messages_waiting': 'yes'},
-              'bob': {'type': 'MWI', 'state': 'active', 'voice_message': '0/0 (0/0)', 'messages_waiting': 'no'} }
-    full_state:
-        -
-            True
-        -
-            True
-    ami_action:
+            full-state: True
+            resources: { 'alice': {'type': 'MWI', 'state': 'active', 'voice_message': '1/2 (0/0)', 'messages_waiting': 'yes'}, 'bob': {'type': 'MWI', 'state': 'active', 'voice_message': '0/0 (0/0)', 'messages_waiting': 'no'} }
+    ami-action:
         -
             { 'action': 'MWIUpdate', 'Mailbox': 'alice at default', 'NewMessages': '1', 'OldMessages': '2' }
diff --git a/tests/channels/pjsip/subscriptions/rls/lists/nominal/mwi/initial_notify/test-config.yaml b/tests/channels/pjsip/subscriptions/rls/lists/nominal/mwi/initial_notify/test-config.yaml
index 694ad41..5a2354b 100644
--- a/tests/channels/pjsip/subscriptions/rls/lists/nominal/mwi/initial_notify/test-config.yaml
+++ b/tests/channels/pjsip/subscriptions/rls/lists/nominal/mwi/initial_notify/test-config.yaml
@@ -48,7 +48,7 @@
     modules:
         -
             config-section: 'test-config'
-            typename: 'rls_test.IntegrityCheck'
+            typename: 'rls_test.RLSTest'
 
 test-case-config:
     test-iterations:
@@ -57,11 +57,8 @@
                 - { 'key-args': {'scenario': 'list_subscribe.xml', '-i': '127.0.0.1', '-p': '5061', '-s': 'mail_list'} }
 
 test-config:
-    list_name: 'mail_list'
-    resources:
+    list-name: 'mail_list'
+    packets:
         -
-            { 'alice': {'type': 'MWI', 'state': 'active', 'voice_message': '0/0 (0/0)', 'messages_waiting': 'no'},
-              'bob': {'type': 'MWI', 'state': 'active', 'voice_message': '0/0 (0/0)', 'messages_waiting': 'no'} }
-    full_state:
-        -
-            True
+            full-state: True
+            resources: { 'alice': {'type': 'MWI', 'state': 'active', 'voice_message': '0/0 (0/0)', 'messages_waiting': 'no'}, 'bob': {'type': 'MWI', 'state': 'active', 'voice_message': '0/0 (0/0)', 'messages_waiting': 'no'} }
diff --git a/tests/channels/pjsip/subscriptions/rls/lists/nominal/mwi/partial_state/test-config.yaml b/tests/channels/pjsip/subscriptions/rls/lists/nominal/mwi/partial_state/test-config.yaml
index 3ba717d..0cac3c3 100644
--- a/tests/channels/pjsip/subscriptions/rls/lists/nominal/mwi/partial_state/test-config.yaml
+++ b/tests/channels/pjsip/subscriptions/rls/lists/nominal/mwi/partial_state/test-config.yaml
@@ -35,7 +35,7 @@
     modules:
         -
             config-section: 'test-config'
-            typename: 'rls_test.IntegrityCheck'
+            typename: 'rls_test.RLSTest'
 
 test-case-config:
     test-iterations:
@@ -44,18 +44,34 @@
                 - { 'key-args': {'scenario': 'list_subscribe.xml', '-i': '127.0.0.1', '-p': '5061', '-s': 'mail_list'} }
 
 test-config:
-    list_name: 'mail_list'
-    resources:
+    list-name: 'mail_list'
+    packets:
         -
-            { 'alice': {'type': 'MWI', 'state': 'active', 'voice_message': '0/0 (0/0)', 'messages_waiting': 'no'},
-              'bob': {'type': 'MWI', 'state': 'active', 'voice_message': '0/0 (0/0)', 'messages_waiting': 'no'} }
+            full-state: True
+            resources: {
+                'alice': {
+                    'type': 'MWI',
+                    'state': 'active',
+                    'voice_message': '0/0 (0/0)',
+                    'messages_waiting': 'no'
+                    },
+                'bob': {
+                    'type': 'MWI',
+                    'state': 'active',
+                    'voice_message': '0/0 (0/0)',
+                    'messages_waiting': 'no'
+                }
+            }
         -
-            { 'alice': {'type': 'MWI', 'state': 'active', 'voice_message': '1/2 (0/0)', 'messages_waiting': 'yes'} }
-    full_state:
-        -
-            True
-        -
-            False
-    ami_action:
+            full-state: False
+            resources: {
+                'alice': {
+                    'type': 'MWI',
+                    'state': 'active',
+                    'voice_message': '1/2 (0/0)',
+                    'messages_waiting': 'yes'
+                }
+            }
+    ami-action:
         -
             { 'action': 'MWIUpdate', 'Mailbox': 'alice at default', 'NewMessages': '1', 'OldMessages': '2' }
diff --git a/tests/channels/pjsip/subscriptions/rls/lists/nominal/mwi/resubscribe_full_state/test-config.yaml b/tests/channels/pjsip/subscriptions/rls/lists/nominal/mwi/resubscribe_full_state/test-config.yaml
index 49bfadd..ba52c53 100644
--- a/tests/channels/pjsip/subscriptions/rls/lists/nominal/mwi/resubscribe_full_state/test-config.yaml
+++ b/tests/channels/pjsip/subscriptions/rls/lists/nominal/mwi/resubscribe_full_state/test-config.yaml
@@ -35,7 +35,7 @@
     modules:
         -
             config-section: 'test-config'
-            typename: 'rls_test.IntegrityCheck'
+            typename: 'rls_test.RLSTest'
 
 test-case-config:
     test-iterations:
@@ -44,16 +44,11 @@
                 - { 'key-args': {'scenario': 'resubscribe.xml', '-i': '127.0.0.1', '-p': '5061', '-s': 'mail_list'} }
 
 test-config:
-    list_name: 'mail_list'
-    resources:
+    list-name: 'mail_list'
+    packets:
         -
-            { 'alice': {'type': 'MWI', 'state': 'active', 'voice_message': '0/0 (0/0)', 'messages_waiting': 'no'},
-              'bob': {'type': 'MWI', 'state': 'active', 'voice_message': '0/0 (0/0)', 'messages_waiting': 'no'} }
+            full-state: True
+            resources: { 'alice': {'type': 'MWI', 'state': 'active', 'voice_message': '0/0 (0/0)', 'messages_waiting': 'no'}, 'bob': {'type': 'MWI', 'state': 'active', 'voice_message': '0/0 (0/0)', 'messages_waiting': 'no'} }
         -
-            { 'alice': {'type': 'MWI', 'state': 'active', 'voice_message': '0/0 (0/0)', 'messages_waiting': 'no'},
-              'bob': {'type': 'MWI', 'state': 'active', 'voice_message': '0/0 (0/0)', 'messages_waiting': 'no'} }
-    full_state:
-        -
-            True
-        -
-            True
+            full-state: True
+            resources: { 'alice': {'type': 'MWI', 'state': 'active', 'voice_message': '0/0 (0/0)', 'messages_waiting': 'no'}, 'bob': {'type': 'MWI', 'state': 'active', 'voice_message': '0/0 (0/0)', 'messages_waiting': 'no'} }
diff --git a/tests/channels/pjsip/subscriptions/rls/lists/nominal/mwi/termination_full_state/test-config.yaml b/tests/channels/pjsip/subscriptions/rls/lists/nominal/mwi/termination_full_state/test-config.yaml
index 90a533f..45875d3 100644
--- a/tests/channels/pjsip/subscriptions/rls/lists/nominal/mwi/termination_full_state/test-config.yaml
+++ b/tests/channels/pjsip/subscriptions/rls/lists/nominal/mwi/termination_full_state/test-config.yaml
@@ -36,7 +36,7 @@
     modules:
         -
             config-section: 'test-config'
-            typename: 'rls_test.IntegrityCheck'
+            typename: 'rls_test.RLSTest'
 
 test-case-config:
     test-iterations:
@@ -45,16 +45,11 @@
                 - { 'key-args': {'scenario': 'termination.xml', '-i': '127.0.0.1', '-p': '5061', '-s': 'mail_list'} }
 
 test-config:
-    list_name: 'mail_list'
-    resources:
+    list-name: 'mail_list'
+    packets:
         -
-            { 'alice': {'type': 'MWI', 'state': 'active', 'voice_message': '0/0 (0/0)', 'messages_waiting': 'no'},
-              'bob': {'type': 'MWI', 'state': 'active', 'voice_message': '0/0 (0/0)', 'messages_waiting': 'no'} }
+            full-state: True
+            resources: { 'alice': {'type': 'MWI', 'state': 'active', 'voice_message': '0/0 (0/0)', 'messages_waiting': 'no'}, 'bob': {'type': 'MWI', 'state': 'active', 'voice_message': '0/0 (0/0)', 'messages_waiting': 'no'} }
         -
-            { 'alice': {'type': 'MWI', 'state': 'terminated', 'voice_message': '0/0 (0/0)', 'messages_waiting': 'no'},
-              'bob': {'type': 'MWI', 'state': 'terminated', 'voice_message': '0/0 (0/0)', 'messages_waiting': 'no'} }
-    full_state:
-        -
-            True
-        -
-            True
+            full-state: True
+            resources: { 'alice': {'type': 'MWI', 'state': 'terminated', 'voice_message': '0/0 (0/0)', 'messages_waiting': 'no'}, 'bob': {'type': 'MWI', 'state': 'terminated', 'voice_message': '0/0 (0/0)', 'messages_waiting': 'no'} }
diff --git a/tests/channels/pjsip/subscriptions/rls/lists/nominal/presence/batched/basic/driver.py b/tests/channels/pjsip/subscriptions/rls/lists/nominal/presence/batched/basic/driver.py
index b961a85..9b46149 100755
--- a/tests/channels/pjsip/subscriptions/rls/lists/nominal/presence/batched/basic/driver.py
+++ b/tests/channels/pjsip/subscriptions/rls/lists/nominal/presence/batched/basic/driver.py
@@ -1,4 +1,11 @@
 #!/usr/bin/env python
+"""
+Copyright (C) 2015, Digium, Inc.
+Mark Michelson <mmichelson at digium.com>
+
+This program is free software, distributed under the terms of
+the GNU General Public License Version 2.
+"""
 
 import time
 import logging
@@ -24,30 +31,218 @@
 # This state is entered after Bob's device state NOTIFY has been received.
 BOB_STATE = 5
 
-# This state is entered after SUBSCRIBE-NOTIFY exchange to terminate
-# subscription has occurred.
-TERMINATED = 6
+def named_constant_to_text(state):
+    """Converts a named state constant to textual representation.
+
+    Keyword Arguments:
+    state                      -- The named state constant.
+
+    Returns:
+    A string representing the named constant.
+    """
+
+    if state == UNESTABLISHED:
+        return 'UNESTABLISHED'
+    elif state == ESTABLISHED:
+        return 'ESTABLISHED'
+    elif state == ALICE_STATE:
+        return 'ALICE_STATE'
+    elif state == REFRESHED:
+        return 'REFRESHED'
+    elif state == BOB_STATE:
+        return 'BOB_STATE'
+    return 'UNKNOWN'
+
+def build_users_list():
+    """Builds the list of users.
+
+    Returns:
+    A list of TestUser objects.
+    """
+
+    users = list()
+
+    for info in [('Alice', ESTABLISHED), ('Bob', REFRESHED)]:
+        name = info[0]
+        user = TestUser(name,
+                        info[1],
+                        globals()[name.upper() + '_STATE'])
+        users.append(user)
+    return users
+
+
+class TestUser(object):
+    """A test user.
+
+    This class is responsbile for keeping track of the start/end states,
+    transition time interval, and current state for a SipPScenario actor.
+    """
+
+    def __init__(self, name, start_state, end_state):
+        """Constructor.
+
+        Keyword Arguments:
+        name                   -- The name for this TestUser instance
+        start_state            -- The state to use when this user is activated.
+        end_state              -- The state to use when this user is
+                                  deactivated.
+        """
+
+        self.name = name
+        self.state = UNESTABLISHED
+        self.__start_state = start_state
+        self.__end_state = end_state
+        self.__start_time = 0.0
+        self.__end_time = 0.0
+
+    def activate(self, ami):
+        """Activates this TestUser.
+
+        This will update the state of the user to the start_state and send an
+        AMI message which triggers the SipPScenario to transition its state."""
+
+        message = "Activating user: {0}."
+        LOGGER.debug(message.format(self.name))
+
+        self.state = self.__start_state
+        self.__start_time = time.time()
+
+        ami_message = {
+            'Action': 'SetVar',
+            'Variable': 'DEVICE_STATE(Custom:{0})'.format(self.name.lower()),
+            'Value': 'InUse'
+        }
+        ami.sendMessage(ami_message)
+
+    def deactivate(self):
+        """Deactivates this TestUser."""
+
+        message = "Deactivating user: {0}."
+        LOGGER.debug(message.format(self.name))
+
+        self.state = self.__end_state
+        self.__end_time = time.time()
+
+    def check_elapsed_time(self):
+        """Checks the elapsed between acitvation and deactivation."""
+
+        message = "Checking time interval for {0}."
+        LOGGER.debug(message.format(self.name))
+
+        message = "Time interval for {0}: {1}. Check {2}."
+        interval = self.__end_time - self.__start_time
+        if interval < 5.0:
+            LOGGER.error(message.format(self.name, interval, "failed"))
+            return False
+
+        LOGGER.debug(message.format(self.name, interval, "passed"))
+        return True
 
 
 class TestDriver(object):
+    """The driver for the test.
+
+    This class is responsbile for initiating the state changes for the
+    SipPScenario actors.
+    """
+
     def __init__(self, module_config, test_object):
+        """Constructor.
+
+        Keyword Arguments:
+        module_config          -- The YAML configuration for this test.
+        test_object            -- The TestCaseModule instance for this test.
+        """
+
         self.ami = None
-        self.state = UNESTABLISHED
         self.test_object = test_object
-        self.alice_time = 0.0
-        self.bob_time = 0.0
-        test_object.register_ami_observer(self.ami_connect)
+
+        self.__current_user = None
+        self.__users = build_users_list()
+        self.__iterator = iter(self.__users)
+
+        test_object.register_ami_observer(self.on_ami_connect)
+
+    def check_state(self, valid_states):
+        """Checks the state of the test.
+
+        Keyword Arguments:
+        valid_states           -- A list of states that are valid.
+
+        Returns:
+        True if the test state matches at least one of the valid states.
+        Otherwise, returns False.
+        """
+
+        current_state = self.get_state()
+        message = "Checking that the test state: {0} is valid."
+        LOGGER.debug(message.format(current_state))
+
+        for state in valid_states:
+            if state == current_state:
+                LOGGER.debug("Test state is valid.")
+                return True
+
+        states = \
+            ', or '.join([named_constant_to_text(x) for x in valid_states])
+        LOGGER.error("Unexpected test state. Expected: {0}.".format(states))
+        return False
 
     def fail_test(self):
+        """Fails the test."""
+
+        LOGGER.error("Failing the test.")
         self.test_object.set_passed(False)
         self.test_object.stop_reactor()
 
-    def ami_connect(self, ami):
-        self.ami = ami
-        self.ami.registerEvent('TestEvent', self.on_test_event)
+    def get_state(self):
+        """Gets the test state.
 
-    def on_test_event(self, ami, event):
+        Returns:
+        If the current user is None, this will return UNESTABLISHED. Otherwise,
+        the state of the current user is returned.
+        """
+
+        if self.__current_user is None:
+            return UNESTABLISHED
+
+        return self.__current_user.state
+
+    def log_state(self, caller):
+        """Logs the state of the test for a given caller.
+
+        Keyword Arguments:
+        caller                 -- The caller requesting the state to be logged.
+        """
+
+        message = "In {0}. self.state={1}."
+        LOGGER.debug(message.format(caller.__name__,
+                                    named_constant_to_text(self.get_state())))
+
+    def on_ami_connect(self, ami):
+        """Handles the AMI connect event.
+
+        Keyword Arguments:
+        ami                    -- The AMI instance that raised this event.
+        """
+
+        self.ami = ami
+        self.ami.registerEvent('TestEvent', self.on_ami_test_event)
+
+    def on_ami_test_event(self, ami, event):
+        """Handles an AMI TestEvent.
+
+        Routes the test data according to the state of the AMI event.
+
+        Keyword Arguments:
+        sender                 -- The ami instance that raised the event.
+        event                  -- The event payload.
+        """
+
         state = event['state']
+        message = "In self.on_test_event. event[state]={0}."
+        LOGGER.debug(message.format(state))
+
         if state == 'SUBSCRIPTION_ESTABLISHED':
             self.on_subscription_established()
         elif state == 'SUBSCRIPTION_REFRESHED':
@@ -55,70 +250,74 @@
         elif state == 'SUBSCRIPTION_TERMINATED':
             self.on_subscription_terminated()
         elif state == 'SUBSCRIPTION_STATE_CHANGED':
-            self.on_subscription_state_change()
+            self.on_subscription_state_changed()
 
     def on_subscription_established(self):
-        if self.state != UNESTABLISHED:
-            LOGGER.error("Unexpected state change from {0}. Expected state "
-                         "{1}".format(self.state, UNESTABLISHED))
+        """Handles an AMI 'SUBSCRIPTION_ESTABLISHED' TestEvent.
+
+        Verifies the current state matches the expected state and transitions
+        the TestUser.
+        """
+
+        self.log_state(self.on_subscription_established)
+        if not self.check_state([UNESTABLISHED]):
             self.fail_test()
-
-        LOGGER.debug("State change to {0}".format(ESTABLISHED))
-        self.state = ESTABLISHED
-        self.alice_time = time.time()
-        message = {
-            'Action': 'SetVar',
-            'Variable': 'DEVICE_STATE(Custom:alice)',
-            'Value': 'InUse'
-        }
-        self.ami.sendMessage(message)
-
-    def on_subscription_state_change(self):
-        if self.state != ESTABLISHED and self.state != REFRESHED:
-            LOGGER.error("Unexpected state change from {0}. Expected state "
-                         "{1} or {2}".format(self.state, ESTABLISHED,
-                                             REFRESHED))
-            self.fail_test()
-
-        if self.state == ESTABLISHED:
-            interval = time.time() - self.alice_time
-            if interval < 5.0:
-                LOGGER.error("Interval {0} too brief".format(interval))
-                self.fail_test()
-            LOGGER.debug("State change to {0}".format(ALICE_STATE))
-            self.state = ALICE_STATE
-        if self.state == REFRESHED:
-            interval = time.time() - self.bob_time
-            if time.time() - self.bob_time < 5.0:
-                LOGGER.error("Interval {0} too brief".format(interval))
-                self.fail_test()
-            LOGGER.debug("State change to {0}".format(BOB_STATE))
-            self.state = BOB_STATE
+        self.transition_user()
 
     def on_subscription_refreshed(self):
-        if self.state != ALICE_STATE:
-            LOGGER.error("Unexpected state change from {0}. Expected state "
-                         "{1}".format(self.state, ALICE_STATE))
+        """Handles an AMI 'SUBSCRIPTION_REFRESHED' TestEvent.
+
+        Verifies the current state matches the expected state and transitions
+        the TestUser.
+        """
+
+        self.log_state(self.on_subscription_refreshed)
+        if not self.check_state([ALICE_STATE]):
+            self.fail_test()
+        self.transition_user()
+
+    def on_subscription_state_changed(self):
+        """Handles an AMI 'SUBSCRIPTION_STATE_CHANGED' TestEvent.
+
+        Deactivates the current user and verifies that its time inteval
+        is greater than the tolerance level (5 seconds).
+        """
+
+        self.log_state(self.on_subscription_state_changed)
+        if not self.check_state([ESTABLISHED, REFRESHED]):
             self.fail_test()
 
-        LOGGER.debug("State change to {0}".format(REFRESHED))
-        self.state = REFRESHED
-        self.bob_time = time.time()
-        message = {
-            'Action': 'SetVar',
-            'Variable': 'DEVICE_STATE(Custom:bob)',
-            'Value': 'InUse'
-        }
-        self.ami.sendMessage(message)
+        self.__current_user.deactivate()
+        if not self.__current_user.check_elapsed_time():
+            self.fail_test()
 
     def on_subscription_terminated(self):
-        if self.state != BOB_STATE:
-            LOGGER.error("Unexpected state change from {0}. Expected state "
-                         "{1}".format(self.state, BOB_STATE))
+        """Handles an AMI SUBSCRIPTION_TERMINATED TestEvent.
+
+        Verifies that the final state matches the expected state (BOB_STATE)
+        and marks the test as passed or failed."""
+
+        self.log_state(self.on_subscription_terminated)
+        if not self.check_state([BOB_STATE]):
             self.fail_test()
 
-        LOGGER.debug("State change to {0}".format(TERMINATED))
-        self.state = TERMINATED
         # If we've made it here, then the test has passed!
         self.test_object.set_passed(True)
         self.test_object.stop_reactor()
+
+    def transition_user(self):
+        """ Transitions the current user to the next user in the list.
+
+        This will set the value of current_user to the next available user in
+        the list, or None, if we are at the end of the list. If we are at the
+        end of the list, nothing else is done. Otherwise, the current_user is
+        activated.
+        """
+
+        try:
+            self.__current_user = self.__iterator.next()
+        except StopIteration:
+            self.__current_user = None
+            return
+
+        self.__current_user.activate(self.ami)
diff --git a/tests/channels/pjsip/subscriptions/rls/lists/nominal/presence/batched/basic/test-config.yaml b/tests/channels/pjsip/subscriptions/rls/lists/nominal/presence/batched/basic/test-config.yaml
index e10c845..fafac44 100644
--- a/tests/channels/pjsip/subscriptions/rls/lists/nominal/presence/batched/basic/test-config.yaml
+++ b/tests/channels/pjsip/subscriptions/rls/lists/nominal/presence/batched/basic/test-config.yaml
@@ -32,13 +32,15 @@
     add-to-search-path:
         -
             'tests/channels/pjsip/subscriptions/rls'
+    reactor-timeout: 25
+    fail-on-any: 'True'
     test-object:
         config-section: 'test-case-config'
         typename: 'sipp.SIPpTestCase'
     modules:
         -
             config-section: 'test-config'
-            typename: 'rls_test.IntegrityCheck'
+            typename: 'rls_test.RLSTest'
         -
             typename: 'driver.TestDriver'
 
@@ -49,29 +51,24 @@
                 - { 'key-args': {'scenario': 'subscribe.xml', '-i': '127.0.0.1', '-p': '5061', '-s': 'pres_list'} }
 
 test-config:
-    list_name: 'pres_list'
-    resources:
+    stop-test-after-notifys: False
+    list-name: 'pres_list'
+    packets:
         -
-            { 'alice': {'type': 'PIDF', 'state': 'active'},
+            full-state: True
+            resources: { 'alice': {'type': 'PIDF', 'state': 'active'},
               'bob': {'type': 'PIDF', 'state': 'active'}}
         -
-            { 'alice': {'type': 'PIDF', 'state': 'active'}}
+            full-state: False
+            resources: { 'alice': {'type': 'PIDF', 'state': 'active'}}
         -
-            { 'alice': {'type': 'PIDF', 'state': 'active'},
+            full-state: True
+            resources: { 'alice': {'type': 'PIDF', 'state': 'active'},
               'bob': {'type': 'PIDF', 'state': 'active'}}
         -
-            { 'bob': {'type': 'PIDF', 'state': 'active'}}
+            full-state: False
+            resources: { 'bob': {'type': 'PIDF', 'state': 'active'}}
         -
-            { 'alice': {'type': 'PIDF', 'state': 'terminated'},
+            full-state: True
+            resources: { 'alice': {'type': 'PIDF', 'state': 'terminated'},
               'bob': {'type': 'PIDF', 'state': 'terminated'}}
-    full_state:
-        -
-            True
-        -
-            False
-        -
-            True
-        -
-            False
-        -
-            True
diff --git a/tests/channels/pjsip/subscriptions/rls/lists/nominal/presence/batched/multiple_resources_single_change/test-config.yaml b/tests/channels/pjsip/subscriptions/rls/lists/nominal/presence/batched/multiple_resources_single_change/test-config.yaml
index 58d275d..e978669 100644
--- a/tests/channels/pjsip/subscriptions/rls/lists/nominal/presence/batched/multiple_resources_single_change/test-config.yaml
+++ b/tests/channels/pjsip/subscriptions/rls/lists/nominal/presence/batched/multiple_resources_single_change/test-config.yaml
@@ -32,7 +32,7 @@
     modules:
         -
             config-section: 'test-config'
-            typename: 'rls_test.IntegrityCheck'
+            typename: 'rls_test.RLSTest'
         -
             typename: 'driver.TestDriver'
 
@@ -43,31 +43,20 @@
                 - { 'key-args': {'scenario': 'subscribe.xml', '-i': '127.0.0.1', '-p': '5061', '-s': 'pres_list'} }
 
 test-config:
-    list_name: 'pres_list'
-    resources:
+    list-name: 'pres_list'
+    packets:
         -
-            { 'alice': {'type': 'PIDF', 'state': 'active'},
-              'bob': {'type': 'PIDF', 'state': 'active'}}
+            full-state: True
+            resources: { 'alice': {'type': 'PIDF', 'state': 'active'}, 'bob': {'type': 'PIDF', 'state': 'active'}}
         -
-            { 'alice': {'type': 'PIDF', 'state': 'active'},
-              'bob': {'type': 'PIDF', 'state': 'active'}}
+            full-state: False
+            resources: { 'alice': {'type': 'PIDF', 'state': 'active'}, 'bob': {'type': 'PIDF', 'state': 'active'}}
         -
-            { 'alice': {'type': 'PIDF', 'state': 'active'},
-              'bob': {'type': 'PIDF', 'state': 'active'}}
+            full-state: True
+            resources: { 'alice': {'type': 'PIDF', 'state': 'active'}, 'bob': {'type': 'PIDF', 'state': 'active'}}
         -
-            { 'alice': {'type': 'PIDF', 'state': 'active'},
-              'bob': {'type': 'PIDF', 'state': 'active'}}
+            full-state: False
+            resources: { 'alice': {'type': 'PIDF', 'state': 'active'}, 'bob': {'type': 'PIDF', 'state': 'active'}}
         -
-            { 'alice': {'type': 'PIDF', 'state': 'terminated'},
-              'bob': {'type': 'PIDF', 'state': 'terminated'}}
-    full_state:
-        -
-            True
-        -
-            False
-        -
-            True
-        -
-            False
-        -
-            True
+            full-state: True
+            resources: { 'alice': {'type': 'PIDF', 'state': 'terminated'}, 'bob': {'type': 'PIDF', 'state': 'terminated'}}
diff --git a/tests/channels/pjsip/subscriptions/rls/lists/nominal/presence/batched/resubscription_interruption/test-config.yaml b/tests/channels/pjsip/subscriptions/rls/lists/nominal/presence/batched/resubscription_interruption/test-config.yaml
index 30d9b48..9044540 100644
--- a/tests/channels/pjsip/subscriptions/rls/lists/nominal/presence/batched/resubscription_interruption/test-config.yaml
+++ b/tests/channels/pjsip/subscriptions/rls/lists/nominal/presence/batched/resubscription_interruption/test-config.yaml
@@ -34,7 +34,7 @@
     modules:
         -
             config-section: 'test-config'
-            typename: 'rls_test.IntegrityCheck'
+            typename: 'rls_test.RLSTest'
         -
             typename: 'driver.TestDriver'
 
@@ -45,17 +45,12 @@
                 - { 'key-args': {'scenario': 'subscribe.xml', '-i': '127.0.0.1', '-p': '5061', '-s': 'pres_list', '-d': '3000'} }
 
 test-config:
-    stop_after_notifys: False
-    list_name: 'pres_list'
-    resources:
+    stop-test-after-notifys: False
+    list-name 'pres_list'
+    packets:
         -
-            { 'alice': {'type': 'PIDF', 'state': 'active'},
-              'bob': {'type': 'PIDF', 'state': 'active'}}
+            full-state: True
+            resources: { 'alice': {'type': 'PIDF', 'state': 'active'}, 'bob': {'type': 'PIDF', 'state': 'active'}}
         -
-            { 'alice': {'type': 'PIDF', 'state': 'active'},
-              'bob': {'type': 'PIDF', 'state': 'active'}}
-    full_state:
-        -
-            True
-        -
-            True
+            full-state: True
+            resources: { 'alice': {'type': 'PIDF', 'state': 'active'}, 'bob': {'type': 'PIDF', 'state': 'active'}}
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
index 642b378..ba63fb4 100644
--- 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
@@ -32,7 +32,7 @@
     modules:
         -
             config-section: 'test-config'
-            typename: 'rls_test.IntegrityCheck'
+            typename: 'rls_test.RLSTest'
         -
             typename: 'driver.TestDriver'
 
@@ -43,29 +43,20 @@
                 - { 'key-args': {'scenario': 'subscribe.xml', '-i': '127.0.0.1', '-p': '5061', '-s': 'pres_list'} }
 
 test-config:
-    list_name: 'pres_list'
-    resources:
+    list-name: 'pres_list'
+    packets:
         -
-            { 'alice': {'type': 'PIDF', 'state': 'active'},
-              'bob': {'type': 'PIDF', 'state': 'active'}}
+            full-state: True
+            resources: { 'alice': {'type': 'PIDF', 'state': 'active'}, 'bob': {'type': 'PIDF', 'state': 'active'}}
         -
-            { 'alice': {'type': 'PIDF', 'state': 'active'}}
+            full-state: False
+            resources: { 'alice': {'type': 'PIDF', 'state': 'active' } }
         -
-            { 'alice': {'type': 'PIDF', 'state': 'active'},
-              'bob': {'type': 'PIDF', 'state': 'active'}}
+            full-state: True
+            resources: { 'alice': {'type': 'PIDF', 'state': 'active'}, 'bob': {'type': 'PIDF', 'state': 'active'}}
         -
-            { 'bob': {'type': 'PIDF', 'state': 'active'}}
+            full-state: False
+            resources: { 'bob': {'type': 'PIDF', 'state': 'active' } }
         -
-            { 'alice': {'type': 'PIDF', 'state': 'terminated'},
-              'bob': {'type': 'PIDF', 'state': 'terminated'}}
-    full_state:
-        -
-            True
-        -
-            False
-        -
-            True
-        -
-            False
-        -
-            True
+            full-state: True
+            resources: { 'alice': {'type': 'PIDF', 'state': 'terminated'}, 'bob': {'type': 'PIDF', 'state': 'terminated'}}
diff --git a/tests/channels/pjsip/subscriptions/rls/lists/nominal/presence/batched/termination_interruption/test-config.yaml b/tests/channels/pjsip/subscriptions/rls/lists/nominal/presence/batched/termination_interruption/test-config.yaml
index a4220d6..5ff90ec 100644
--- a/tests/channels/pjsip/subscriptions/rls/lists/nominal/presence/batched/termination_interruption/test-config.yaml
+++ b/tests/channels/pjsip/subscriptions/rls/lists/nominal/presence/batched/termination_interruption/test-config.yaml
@@ -34,7 +34,7 @@
     modules:
         -
             config-section: 'test-config'
-            typename: 'rls_test.IntegrityCheck'
+            typename: 'rls_test.RLSTest'
         -
             typename: 'driver.TestDriver'
 
@@ -45,17 +45,12 @@
                 - { 'key-args': {'scenario': 'subscribe.xml', '-i': '127.0.0.1', '-p': '5061', '-s': 'pres_list', '-d': '3000'} }
 
 test-config:
-    stop_after_notifys: False
-    list_name: 'pres_list'
-    resources:
+    stop-test-after-notifys: False
+    list-name 'pres_list'
+    packets:
         -
-            { 'alice': {'type': 'PIDF', 'state': 'active'},
-              'bob': {'type': 'PIDF', 'state': 'active'}}
+            full-state: True
+            resources: { 'alice': {'type': 'PIDF', 'state': 'active'}, 'bob': {'type': 'PIDF', 'state': 'active'}}
         -
-            { 'alice': {'type': 'PIDF', 'state': 'terminated'},
-              'bob': {'type': 'PIDF', 'state': 'terminated'}}
-    full_state:
-        -
-            True
-        -
-            True
+            full-state: True
+            resources: { 'alice': {'type': 'PIDF', 'state': 'terminated'}, 'bob': {'type': 'PIDF', 'state': 'terminated'}}
diff --git a/tests/channels/pjsip/subscriptions/rls/lists/nominal/presence/full_state/test-config.yaml b/tests/channels/pjsip/subscriptions/rls/lists/nominal/presence/full_state/test-config.yaml
index 9d32a89..541e33f 100644
--- a/tests/channels/pjsip/subscriptions/rls/lists/nominal/presence/full_state/test-config.yaml
+++ b/tests/channels/pjsip/subscriptions/rls/lists/nominal/presence/full_state/test-config.yaml
@@ -32,7 +32,7 @@
     modules:
         -
             config-section: 'test-config'
-            typename: 'rls_test.IntegrityCheck'
+            typename: 'rls_test.RLSTest'
 
 test-case-config:
     test-iterations:
@@ -41,19 +41,14 @@
                 - { 'key-args': {'scenario': 'list_subscribe.xml', '-i': '127.0.0.1', '-p': '5061', '-s': 'pres_list'} }
 
 test-config:
-    list_name: 'pres_list'
-    resources:
+    list-name: 'pres_list'
+    packets:
         -
-            { 'alice': {'type': 'PIDF', 'state': 'active'},
-              'bob': {'type': 'PIDF', 'state': 'active'} }
+            full-state: True
+            resources: { 'alice': {'type': 'PIDF', 'state': 'active'}, 'bob': {'type': 'PIDF', 'state': 'active'} }
         -
-            { 'alice': {'type': 'PIDF', 'state': 'active'},
-              'bob': {'type': 'PIDF', 'state': 'active'} }
-    full_state:
-        -
-            True
-        -
-            True
-    ami_action:
+            full-state: True
+            resources: { 'alice': {'type': 'PIDF', 'state': 'active'}, 'bob': {'type': 'PIDF', 'state': 'active'} }
+    ami-action:
         -
             { 'Action': 'SetVar', 'Variable': 'DEVICE_STATE(Custom:alice)', 'Value': 'INUSE' }
diff --git a/tests/channels/pjsip/subscriptions/rls/lists/nominal/presence/initial_notify/test-config.yaml b/tests/channels/pjsip/subscriptions/rls/lists/nominal/presence/initial_notify/test-config.yaml
index a4df4c9..10a9ff4 100644
--- a/tests/channels/pjsip/subscriptions/rls/lists/nominal/presence/initial_notify/test-config.yaml
+++ b/tests/channels/pjsip/subscriptions/rls/lists/nominal/presence/initial_notify/test-config.yaml
@@ -45,7 +45,7 @@
     modules:
         -
             config-section: 'test-config'
-            typename: 'rls_test.IntegrityCheck'
+            typename: 'rls_test.RLSTest'
 
 test-case-config:
     test-iterations:
@@ -54,11 +54,8 @@
                 - { 'key-args': {'scenario': 'list_subscribe.xml', '-i': '127.0.0.1', '-p': '5061', '-s': 'pres_list'} }
 
 test-config:
-    list_name: 'pres_list'
-    resources:
+    list-name: 'pres_list'
+    packets:
         -
-            { 'alice': {'type': 'PIDF', 'state': 'active'},
-              'bob': {'type': 'PIDF', 'state': 'active'} }
-    full_state:
-        -
-            True
+            full-state: True
+            resources: { 'alice': {'type': 'PIDF', 'state': 'active'}, 'bob': {'type': 'PIDF', 'state': 'active'} }
diff --git a/tests/channels/pjsip/subscriptions/rls/lists/nominal/presence/partial_state/test-config.yaml b/tests/channels/pjsip/subscriptions/rls/lists/nominal/presence/partial_state/test-config.yaml
index 0b09c6b..c9989a4 100644
--- a/tests/channels/pjsip/subscriptions/rls/lists/nominal/presence/partial_state/test-config.yaml
+++ b/tests/channels/pjsip/subscriptions/rls/lists/nominal/presence/partial_state/test-config.yaml
@@ -33,7 +33,7 @@
     modules:
         -
             config-section: 'test-config'
-            typename: 'rls_test.IntegrityCheck'
+            typename: 'rls_test.RLSTest'
 
 test-case-config:
     test-iterations:
@@ -42,18 +42,14 @@
                 - { 'key-args': {'scenario': 'list_subscribe.xml', '-i': '127.0.0.1', '-p': '5061', '-s': 'pres_list'} }
 
 test-config:
-    list_name: 'pres_list'
-    resources:
+    list-name: 'pres_list'
+    packets:
         -
-            { 'alice': {'type': 'PIDF', 'state': 'active'},
-              'bob': {'type': 'PIDF', 'state': 'active'} }
+            full-state: True
+            resources: { 'alice': {'type': 'PIDF', 'state': 'active'}, 'bob': {'type': 'PIDF', 'state': 'active'} }
         -
-            { 'alice': {'type': 'PIDF', 'state': 'active'} }
-    full_state:
-        -
-            True
-        -
-            False
-    ami_action:
+            full-state: False
+            resources: { 'alice': {'type': 'PIDF', 'state': 'active' } }
+    ami-action:
         -
             { 'Action': 'SetVar', 'Variable': 'DEVICE_STATE(Custom:alice)', 'Value': 'INUSE' }
diff --git a/tests/channels/pjsip/subscriptions/rls/lists/nominal/presence/resubscribe_full_state/test-config.yaml b/tests/channels/pjsip/subscriptions/rls/lists/nominal/presence/resubscribe_full_state/test-config.yaml
index cd942c8..4010042 100644
--- a/tests/channels/pjsip/subscriptions/rls/lists/nominal/presence/resubscribe_full_state/test-config.yaml
+++ b/tests/channels/pjsip/subscriptions/rls/lists/nominal/presence/resubscribe_full_state/test-config.yaml
@@ -33,7 +33,7 @@
     modules:
         -
             config-section: 'test-config'
-            typename: 'rls_test.IntegrityCheck'
+            typename: 'rls_test.RLSTest'
 
 test-case-config:
     test-iterations:
@@ -42,16 +42,11 @@
                 - { 'key-args': {'scenario': 'resubscribe.xml', '-i': '127.0.0.1', '-p': '5061', '-s': 'pres_list'} }
 
 test-config:
-    list_name: 'pres_list'
-    resources:
+    list-name: 'pres_list'
+    packets:
         -
-            { 'alice': {'type': 'PIDF', 'state': 'active'},
-              'bob': {'type': 'PIDF', 'state': 'active'} }
+            full-state: True
+            resources: { 'alice': {'type': 'PIDF', 'state': 'active'}, 'bob': {'type': 'PIDF', 'state': 'active'} }
         -
-            { 'alice': {'type': 'PIDF', 'state': 'active'},
-              'bob': {'type': 'PIDF', 'state': 'active'} }
-    full_state:
-        -
-            True
-        -
-            True
+            full-state: True
+            resources: { 'alice': {'type': 'PIDF', 'state': 'active'}, 'bob': {'type': 'PIDF', 'state': 'active'} }
diff --git a/tests/channels/pjsip/subscriptions/rls/lists/nominal/presence/termination_full_state/test-config.yaml b/tests/channels/pjsip/subscriptions/rls/lists/nominal/presence/termination_full_state/test-config.yaml
index 6ebcba8..e824eee 100644
--- a/tests/channels/pjsip/subscriptions/rls/lists/nominal/presence/termination_full_state/test-config.yaml
+++ b/tests/channels/pjsip/subscriptions/rls/lists/nominal/presence/termination_full_state/test-config.yaml
@@ -34,7 +34,7 @@
     modules:
         -
             config-section: 'test-config'
-            typename: 'rls_test.IntegrityCheck'
+            typename: 'rls_test.RLSTest'
 
 test-case-config:
     test-iterations:
@@ -43,16 +43,11 @@
                 - { 'key-args': {'scenario': 'termination.xml', '-i': '127.0.0.1', '-p': '5061', '-s': 'pres_list'} }
 
 test-config:
-    list_name: 'pres_list'
-    resources:
+    list-name: 'pres_list'
+    packets:
         -
-            { 'alice': {'type': 'PIDF', 'state': 'active'},
-              'bob': {'type': 'PIDF', 'state': 'active'} }
+            full-state: True
+            resources: { 'alice': {'type': 'PIDF', 'state': 'active'}, 'bob': {'type': 'PIDF', 'state': 'active'} }
         -
-            { 'alice': {'type': 'PIDF', 'state': 'terminated'},
-              'bob': {'type': 'PIDF', 'state': 'terminated'} }
-    full_state:
-        -
-            True
-        -
-            True
+            full-state: True
+            resources: { 'alice': {'type': 'PIDF', 'state': 'terminated'}, 'bob': {'type': 'PIDF', 'state': 'terminated'} }
diff --git a/tests/channels/pjsip/subscriptions/rls/lists/off_nominal/mwi/resource_duplication/test-config.yaml b/tests/channels/pjsip/subscriptions/rls/lists/off_nominal/mwi/resource_duplication/test-config.yaml
index 967e065..0f68b57 100644
--- a/tests/channels/pjsip/subscriptions/rls/lists/off_nominal/mwi/resource_duplication/test-config.yaml
+++ b/tests/channels/pjsip/subscriptions/rls/lists/off_nominal/mwi/resource_duplication/test-config.yaml
@@ -30,7 +30,7 @@
     modules:
         -
             config-section: 'test-config'
-            typename: 'rls_test.IntegrityCheck'
+            typename: 'rls_test.RLSTest'
 
 test-case-config:
     test-iterations:
@@ -39,11 +39,8 @@
                 - { 'key-args': {'scenario': 'list_subscribe.xml', '-i': '127.0.0.1', '-p': '5061', '-s': 'mail_list'} }
 
 test-config:
-    list_name: 'mail_list'
-    resources:
+    list-name: 'mail_list'
+    packets:
         -
-            { 'alice': {'type': 'MWI', 'state': 'active', 'voice_message': '0/0 (0/0)', 'messages_waiting': 'no'}}
-    full_state:
-        -
-            True
-
+            full-state: True
+            resources: { 'alice': {'type': 'MWI', 'state': 'active', 'voice_message': '0/0 (0/0)', 'messages_waiting': 'no' } }
diff --git a/tests/channels/pjsip/subscriptions/rls/lists/off_nominal/mwi/some_list_resources_exist/test-config.yaml b/tests/channels/pjsip/subscriptions/rls/lists/off_nominal/mwi/some_list_resources_exist/test-config.yaml
index 2f14b57..17c4e95 100644
--- a/tests/channels/pjsip/subscriptions/rls/lists/off_nominal/mwi/some_list_resources_exist/test-config.yaml
+++ b/tests/channels/pjsip/subscriptions/rls/lists/off_nominal/mwi/some_list_resources_exist/test-config.yaml
@@ -31,7 +31,7 @@
     modules:
         -
             config-section: 'test-config'
-            typename: 'rls_test.IntegrityCheck'
+            typename: 'rls_test.RLSTest'
 
 test-case-config:
     test-iterations:
@@ -40,11 +40,8 @@
                 - { 'key-args': {'scenario': 'list_subscribe.xml', '-i': '127.0.0.1', '-p': '5061', '-s': 'mail_list'} }
 
 test-config:
-    list_name: 'mail_list'
-    resources:
+    list-name: 'mail_list'
+    packets:
         -
-            { 'alice': {'type': 'MWI', 'state': 'active', 'voice_message': '0/0 (0/0)', 'messages_waiting': 'no'}}
-    full_state:
-        -
-            True
-
+            full-state: True
+            resources: { 'alice': {'type': 'MWI', 'state': 'active', 'voice_message': '0/0 (0/0)', 'messages_waiting': 'no' } }
diff --git a/tests/channels/pjsip/subscriptions/rls/lists/off_nominal/presence/resource_duplication/test-config.yaml b/tests/channels/pjsip/subscriptions/rls/lists/off_nominal/presence/resource_duplication/test-config.yaml
index 024e3ce..8e9035a 100644
--- a/tests/channels/pjsip/subscriptions/rls/lists/off_nominal/presence/resource_duplication/test-config.yaml
+++ b/tests/channels/pjsip/subscriptions/rls/lists/off_nominal/presence/resource_duplication/test-config.yaml
@@ -28,7 +28,7 @@
     modules:
         -
             config-section: 'test-config'
-            typename: 'rls_test.IntegrityCheck'
+            typename: 'rls_test.RLSTest'
 
 test-case-config:
     test-iterations:
@@ -37,11 +37,8 @@
                 - { 'key-args': {'scenario': 'list_subscribe.xml', '-i': '127.0.0.1', '-p': '5061', '-s': 'pres_list'} }
 
 test-config:
-    list_name: 'pres_list'
-    resources:
+    list-name: 'pres_list'
+    packets:
         -
-            { 'alice': {'type': 'PIDF', 'state': 'active'} }
-    full_state:
-        -
-            True
-
+            full-state: True
+            resources: { 'alice': {'type': 'PIDF', 'state': 'active' } }
diff --git a/tests/channels/pjsip/subscriptions/rls/lists/off_nominal/presence/some_list_resources_exist/test-config.yaml b/tests/channels/pjsip/subscriptions/rls/lists/off_nominal/presence/some_list_resources_exist/test-config.yaml
index 80b3294..cf51b04 100644
--- a/tests/channels/pjsip/subscriptions/rls/lists/off_nominal/presence/some_list_resources_exist/test-config.yaml
+++ b/tests/channels/pjsip/subscriptions/rls/lists/off_nominal/presence/some_list_resources_exist/test-config.yaml
@@ -29,7 +29,7 @@
     modules:
         -
             config-section: 'test-config'
-            typename: 'rls_test.IntegrityCheck'
+            typename: 'rls_test.RLSTest'
 
 test-case-config:
     test-iterations:
@@ -38,11 +38,8 @@
                 - { 'key-args': {'scenario': 'list_subscribe.xml', '-i': '127.0.0.1', '-p': '5061', '-s': 'pres_list'} }
 
 test-config:
-    list_name: 'pres_list'
-    resources:
+    list-name: 'pres_list'
+    packets:
         -
-            { 'bob': {'type': 'PIDF', 'state': 'active'} }
-    full_state:
-        -
-            True
-
+            full-state: True
+            resources: { 'bob': {'type': 'PIDF', 'state': 'active' } }
diff --git a/tests/channels/pjsip/subscriptions/rls/lists_of_lists/nominal/mwi/batched/test-config.yaml b/tests/channels/pjsip/subscriptions/rls/lists_of_lists/nominal/mwi/batched/test-config.yaml
index 83b4d7e..149094a 100644
--- a/tests/channels/pjsip/subscriptions/rls/lists_of_lists/nominal/mwi/batched/test-config.yaml
+++ b/tests/channels/pjsip/subscriptions/rls/lists_of_lists/nominal/mwi/batched/test-config.yaml
@@ -37,7 +37,7 @@
     modules:
         -
             config-section: 'test-config'
-            typename: 'rls_test.IntegrityCheck'
+            typename: 'rls_test.RLSTest'
         -
             typename: 'driver.TestDriver'
 
@@ -48,19 +48,21 @@
                 - { 'key-args': {'scenario': 'subscribe.xml', '-i': '127.0.0.1', '-p': '5061', '-s': 'mail_list_a'} }
 
 test-config:
-    list_name: 'mail_list_a'
-    resources:
+    list-name: 'mail_list_a'
+    packets:
         -
-            {
+            full-state: True
+            resources: {
                 'mail_list_b': {
                     'type': 'Multipart', 'state': 'active', 'sublist': {
                         'alice': {'type': 'MWI', 'state': 'active', 'voice_message': '0/0 (0/0)', 'messages_waiting': 'no'},
-                        'bob': {'type': 'MWI', 'state': 'active', 'voice_message': '0/0 (0/0)', 'messages_waiting': 'no'} 
+                        'bob': {'type': 'MWI', 'state': 'active', 'voice_message': '0/0 (0/0)', 'messages_waiting': 'no'}
                     }
                 }
             }
         -
-            {
+            full-state: False
+            resources: {
                 'mail_list_b': {
                     'type': 'Multipart', 'state': 'active', 'sublist': {
                         'alice': {'type': 'MWI', 'state': 'active', 'voice_message': '1/0 (0/0)', 'messages_waiting': 'yes'},
@@ -68,17 +70,11 @@
                 }
             }
         -
-            {
+            full-state: False
+            resources: {
                 'mail_list_b': {
                     'type': 'Multipart', 'state': 'active', 'sublist': {
-                        'bob': {'type': 'MWI', 'state': 'active', 'voice_message': '1/0 (0/0)', 'messages_waiting': 'yes'} 
+                        'bob': {'type': 'MWI', 'state': 'active', 'voice_message': '1/0 (0/0)', 'messages_waiting': 'yes'}
                     }
                 }
             }
-    full_state:
-        -
-            True
-        -
-            False
-        -
-            False
diff --git a/tests/channels/pjsip/subscriptions/rls/lists_of_lists/nominal/mwi/full_state_alice/test-config.yaml b/tests/channels/pjsip/subscriptions/rls/lists_of_lists/nominal/mwi/full_state_alice/test-config.yaml
index 65a031e..202320a 100644
--- a/tests/channels/pjsip/subscriptions/rls/lists_of_lists/nominal/mwi/full_state_alice/test-config.yaml
+++ b/tests/channels/pjsip/subscriptions/rls/lists_of_lists/nominal/mwi/full_state_alice/test-config.yaml
@@ -35,7 +35,7 @@
     modules:
         -
             config-section: 'test-config'
-            typename: 'rls_test.IntegrityCheck'
+            typename: 'rls_test.RLSTest'
 
 test-case-config:
     test-iterations:
@@ -44,10 +44,11 @@
                 - { 'key-args': {'scenario': 'list_subscribe.xml', '-i': '127.0.0.1', '-p': '5061', '-s': 'mail_list'} }
 
 test-config:
-    list_name: 'mail_list'
-    resources:
+    list-name: 'mail_list'
+    packets:
         -
-            {
+            full-state: True
+            resources: {
                 'mail_sublist': {
                     'type': 'Multipart',
                     'state': 'active',
@@ -74,7 +75,8 @@
                 }
             }
         -
-            {
+            full-state: True
+            resources: {
                 'mail_sublist': {
                     'type': 'Multipart',
                     'state': 'active',
@@ -101,12 +103,6 @@
                 }
             }
 
-    full_state:
-        -
-            True
-        -
-            True
-
-    ami_action:
+    ami-action:
         -
             { 'action': 'MWIUpdate', 'Mailbox': 'alice at default', 'NewMessages': '1', 'OldMessages': '2' }
diff --git a/tests/channels/pjsip/subscriptions/rls/lists_of_lists/nominal/mwi/full_state_carol/test-config.yaml b/tests/channels/pjsip/subscriptions/rls/lists_of_lists/nominal/mwi/full_state_carol/test-config.yaml
index 6d73d45..ffcab9f 100644
--- a/tests/channels/pjsip/subscriptions/rls/lists_of_lists/nominal/mwi/full_state_carol/test-config.yaml
+++ b/tests/channels/pjsip/subscriptions/rls/lists_of_lists/nominal/mwi/full_state_carol/test-config.yaml
@@ -35,7 +35,7 @@
     modules:
         -
             config-section: 'test-config'
-            typename: 'rls_test.IntegrityCheck'
+            typename: 'rls_test.RLSTest'
 
 test-case-config:
     test-iterations:
@@ -44,10 +44,11 @@
                 - { 'key-args': {'scenario': 'list_subscribe.xml', '-i': '127.0.0.1', '-p': '5061', '-s': 'mail_list'} }
 
 test-config:
-    list_name: 'mail_list'
-    resources:
+    list-name: 'mail_list'
+    packets:
         -
-            {
+            full-state: True
+            resources: {
                 'mail_sublist': {
                     'type': 'Multipart',
                     'state': 'active',
@@ -74,7 +75,8 @@
                 }
             }
         -
-            {
+            full-state: True
+            resources: {
                 'mail_sublist': {
                     'type': 'Multipart',
                     'state': 'active',
@@ -101,12 +103,6 @@
                 }
             }
 
-    full_state:
-        -
-            True
-        -
-            True
-
-    ami_action:
+    ami-action:
         -
             { 'action': 'MWIUpdate', 'Mailbox': 'carol at default', 'NewMessages': '1', 'OldMessages': '2' }
diff --git a/tests/channels/pjsip/subscriptions/rls/lists_of_lists/nominal/mwi/initial_notify/test-config.yaml b/tests/channels/pjsip/subscriptions/rls/lists_of_lists/nominal/mwi/initial_notify/test-config.yaml
index ecb178a..ccd2001 100644
--- a/tests/channels/pjsip/subscriptions/rls/lists_of_lists/nominal/mwi/initial_notify/test-config.yaml
+++ b/tests/channels/pjsip/subscriptions/rls/lists_of_lists/nominal/mwi/initial_notify/test-config.yaml
@@ -49,7 +49,7 @@
     modules:
         -
             config-section: 'test-config'
-            typename: 'rls_test.IntegrityCheck'
+            typename: 'rls_test.RLSTest'
 
 test-case-config:
     test-iterations:
@@ -58,10 +58,11 @@
                 - { 'key-args': {'scenario': 'list_subscribe.xml', '-i': '127.0.0.1', '-p': '5061', '-s': 'mail_list'} }
 
 test-config:
-    list_name: 'mail_list'
-    resources:
+    list-name: 'mail_list'
+    packets:
         -
-            {
+            full-state: True
+            resources: {
                 'mail_sublist': {
                     'type': 'Multipart',
                     'state': 'active',
@@ -87,6 +88,3 @@
                     'messages_waiting': 'no'
                 }
             }
-    full_state:
-        -
-            True
diff --git a/tests/channels/pjsip/subscriptions/rls/lists_of_lists/nominal/mwi/partial_state_alice/test-config.yaml b/tests/channels/pjsip/subscriptions/rls/lists_of_lists/nominal/mwi/partial_state_alice/test-config.yaml
index 22bc0c2..ec99e76 100644
--- a/tests/channels/pjsip/subscriptions/rls/lists_of_lists/nominal/mwi/partial_state_alice/test-config.yaml
+++ b/tests/channels/pjsip/subscriptions/rls/lists_of_lists/nominal/mwi/partial_state_alice/test-config.yaml
@@ -35,7 +35,7 @@
     modules:
         -
             config-section: 'test-config'
-            typename: 'rls_test.IntegrityCheck'
+            typename: 'rls_test.RLSTest'
 
 test-case-config:
     test-iterations:
@@ -44,10 +44,11 @@
                 - { 'key-args': {'scenario': 'list_subscribe.xml', '-i': '127.0.0.1', '-p': '5061', '-s': 'mail_list'} }
 
 test-config:
-    list_name: 'mail_list'
-    resources:
+    list-name: 'mail_list'
+    packets:
         -
-            {
+            full-state: True
+            resources: {
                 'mail_sublist': {
                     'type': 'Multipart',
                     'state': 'active',
@@ -74,7 +75,8 @@
                 }
             }
         -
-            {
+            full-state: False
+            resources: {
                 'mail_sublist': {
                     'type': 'Multipart',
                     'state': 'active',
@@ -89,12 +91,6 @@
                 }
             }
 
-    full_state:
-        -
-            True
-        -
-            False
-
-    ami_action:
+    ami-action:
         -
             { 'action': 'MWIUpdate', 'Mailbox': 'alice at default', 'NewMessages': '1', 'OldMessages': '2' }
diff --git a/tests/channels/pjsip/subscriptions/rls/lists_of_lists/nominal/mwi/partial_state_carol/test-config.yaml b/tests/channels/pjsip/subscriptions/rls/lists_of_lists/nominal/mwi/partial_state_carol/test-config.yaml
index 85ec420..7111d97 100644
--- a/tests/channels/pjsip/subscriptions/rls/lists_of_lists/nominal/mwi/partial_state_carol/test-config.yaml
+++ b/tests/channels/pjsip/subscriptions/rls/lists_of_lists/nominal/mwi/partial_state_carol/test-config.yaml
@@ -35,7 +35,7 @@
     modules:
         -
             config-section: 'test-config'
-            typename: 'rls_test.IntegrityCheck'
+            typename: 'rls_test.RLSTest'
 
 test-case-config:
     test-iterations:
@@ -44,10 +44,11 @@
                 - { 'key-args': {'scenario': 'list_subscribe.xml', '-i': '127.0.0.1', '-p': '5061', '-s': 'mail_list'} }
 
 test-config:
-    list_name: 'mail_list'
-    resources:
+    list-name: 'mail_list'
+    packets:
         -
-            {
+            full-state: True
+            resources: {
                 'mail_sublist': {
                     'type': 'Multipart',
                     'state': 'active',
@@ -74,7 +75,8 @@
                 }
             }
         -
-            {
+            full-state: False
+            resources: {
                 'carol': {
                     'type': 'MWI',
                     'state': 'active',
@@ -83,12 +85,6 @@
                 }
             }
 
-    full_state:
-        -
-            True
-        -
-            False
-
-    ami_action:
+    ami-action:
         -
             { 'action': 'MWIUpdate', 'Mailbox': 'carol at default', 'NewMessages': '1', 'OldMessages': '2' }
diff --git a/tests/channels/pjsip/subscriptions/rls/lists_of_lists/nominal/mwi/resubscribe_full_state/test-config.yaml b/tests/channels/pjsip/subscriptions/rls/lists_of_lists/nominal/mwi/resubscribe_full_state/test-config.yaml
index db704b4..08eb1b4 100644
--- a/tests/channels/pjsip/subscriptions/rls/lists_of_lists/nominal/mwi/resubscribe_full_state/test-config.yaml
+++ b/tests/channels/pjsip/subscriptions/rls/lists_of_lists/nominal/mwi/resubscribe_full_state/test-config.yaml
@@ -35,7 +35,7 @@
     modules:
         -
             config-section: 'test-config'
-            typename: 'rls_test.IntegrityCheck'
+            typename: 'rls_test.RLSTest'
 
 test-case-config:
     test-iterations:
@@ -44,10 +44,11 @@
                 - { 'key-args': {'scenario': 'resubscribe.xml', '-i': '127.0.0.1', '-p': '5061', '-s': 'mail_list'} }
 
 test-config:
-    list_name: 'mail_list'
-    resources:
+    list-name: 'mail_list'
+    packets:
         -
-            {
+            full-state: True
+            resources: {
                 'mail_sublist': {
                     'type': 'Multipart',
                     'state': 'active',
@@ -74,7 +75,8 @@
                 }
             }
         -
-            {
+            full-state: True
+            resources: {
                 'mail_sublist': {
                     'type': 'Multipart',
                     'state': 'active',
@@ -100,9 +102,3 @@
                     'messages_waiting': 'no'
                 }
             }
-
-    full_state:
-        -
-            True
-        -
-            True
diff --git a/tests/channels/pjsip/subscriptions/rls/lists_of_lists/nominal/mwi/termination_full_state/test-config.yaml b/tests/channels/pjsip/subscriptions/rls/lists_of_lists/nominal/mwi/termination_full_state/test-config.yaml
index 2a54f24..54e7c11 100644
--- a/tests/channels/pjsip/subscriptions/rls/lists_of_lists/nominal/mwi/termination_full_state/test-config.yaml
+++ b/tests/channels/pjsip/subscriptions/rls/lists_of_lists/nominal/mwi/termination_full_state/test-config.yaml
@@ -37,7 +37,7 @@
     modules:
         -
             config-section: 'test-config'
-            typename: 'rls_test.IntegrityCheck'
+            typename: 'rls_test.RLSTest'
 
 test-case-config:
     test-iterations:
@@ -46,10 +46,11 @@
                 - { 'key-args': {'scenario': 'termination.xml', '-i': '127.0.0.1', '-p': '5061', '-s': 'mail_list'} }
 
 test-config:
-    list_name: 'mail_list'
-    resources:
+    list-name: 'mail_list'
+    packets:
         -
-            {
+            full-state: True
+            resources: {
                 'mail_sublist': {
                     'type': 'Multipart',
                     'state': 'active',
@@ -76,7 +77,8 @@
                 }
             }
         -
-            {
+            full-state: True
+            resources: {
                 'mail_sublist': {
                     'type': 'Multipart',
                     'state': 'terminated',
@@ -102,9 +104,3 @@
                     'messages_waiting': 'no'
                 }
             }
-
-    full_state:
-        -
-            True
-        -
-            True
diff --git a/tests/channels/pjsip/subscriptions/rls/lists_of_lists/nominal/presence/batched/test-config.yaml b/tests/channels/pjsip/subscriptions/rls/lists_of_lists/nominal/presence/batched/test-config.yaml
index c5884dc..f633b7e 100644
--- a/tests/channels/pjsip/subscriptions/rls/lists_of_lists/nominal/presence/batched/test-config.yaml
+++ b/tests/channels/pjsip/subscriptions/rls/lists_of_lists/nominal/presence/batched/test-config.yaml
@@ -34,7 +34,7 @@
     modules:
         -
             config-section: 'test-config'
-            typename: 'rls_test.IntegrityCheck'
+            typename: 'rls_test.RLSTest'
         -
             typename: 'driver.TestDriver'
 
@@ -45,10 +45,11 @@
                 - { 'key-args': {'scenario': 'subscribe.xml', '-i': '127.0.0.1', '-p': '5061', '-s': 'pres_list_a'} }
 
 test-config:
-    list_name: 'pres_list_a'
-    resources:
+    list-name: 'pres_list_a'
+    packets:
         -
-            {
+            full-state: True
+            resources: {
                 'pres_list_b': {
                     'type': 'Multipart', 'state': 'active', 'sublist': {
                         'alice': {'type': 'PIDF', 'state': 'active'},
@@ -57,7 +58,8 @@
                 }
             }
         -
-            {
+            full-state: False
+            resources: {
                 'pres_list_b': {
                     'type': 'Multipart', 'state': 'active', 'sublist': {
                         'alice': {'type': 'PIDF', 'state': 'active'},
@@ -65,17 +67,11 @@
                 }
             }
         -
-            {
+            full-state: False
+            resources: {
                 'pres_list_b': {
                     'type': 'Multipart', 'state': 'active', 'sublist': {
                         'bob': {'type': 'PIDF', 'state': 'active'}
                     }
                 }
             }
-    full_state:
-        -
-            True
-        -
-            False
-        -
-            False
diff --git a/tests/channels/pjsip/subscriptions/rls/lists_of_lists/nominal/presence/full_state_alice/test-config.yaml b/tests/channels/pjsip/subscriptions/rls/lists_of_lists/nominal/presence/full_state_alice/test-config.yaml
index 424e9ee..77bf85e 100644
--- a/tests/channels/pjsip/subscriptions/rls/lists_of_lists/nominal/presence/full_state_alice/test-config.yaml
+++ b/tests/channels/pjsip/subscriptions/rls/lists_of_lists/nominal/presence/full_state_alice/test-config.yaml
@@ -32,7 +32,7 @@
     modules:
         -
             config-section: 'test-config'
-            typename: 'rls_test.IntegrityCheck'
+            typename: 'rls_test.RLSTest'
 
 test-case-config:
     test-iterations:
@@ -41,10 +41,11 @@
                 - { 'key-args': {'scenario': 'list_subscribe.xml', '-i': '127.0.0.1', '-p': '5061', '-s': 'pres_list'} }
 
 test-config:
-    list_name: 'pres_list'
-    resources:
+    list-name: 'pres_list'
+    packets:
         -
-            {
+            full-state: True
+            resources: {
                 'pres_sublist': {
                     'type': 'Multipart', 'state': 'active', 'sublist': {
                         'alice': {'type': 'PIDF', 'state': 'active'},
@@ -54,7 +55,8 @@
                 'carol': {'type': 'PIDF', 'state': 'active'}
             }
         -
-            {
+            full-state: True
+            resources: {
                 'pres_sublist': {
                     'type': 'Multipart', 'state': 'active', 'sublist': {
                         'alice': {'type': 'PIDF', 'state': 'active'},
@@ -63,11 +65,6 @@
                 },
                 'carol': {'type': 'PIDF', 'state': 'active'}
             }
-    full_state:
-        -
-            True
-        -
-            True
-    ami_action:
+    ami-action:
         -
             { 'Action': 'SetVar', 'Variable': 'DEVICE_STATE(Custom:alice)', 'Value': 'INUSE' }
diff --git a/tests/channels/pjsip/subscriptions/rls/lists_of_lists/nominal/presence/full_state_carol/test-config.yaml b/tests/channels/pjsip/subscriptions/rls/lists_of_lists/nominal/presence/full_state_carol/test-config.yaml
index 89594b9..92e17a5 100644
--- a/tests/channels/pjsip/subscriptions/rls/lists_of_lists/nominal/presence/full_state_carol/test-config.yaml
+++ b/tests/channels/pjsip/subscriptions/rls/lists_of_lists/nominal/presence/full_state_carol/test-config.yaml
@@ -32,7 +32,7 @@
     modules:
         -
             config-section: 'test-config'
-            typename: 'rls_test.IntegrityCheck'
+            typename: 'rls_test.RLSTest'
 
 test-case-config:
     test-iterations:
@@ -41,10 +41,11 @@
                 - { 'key-args': {'scenario': 'list_subscribe.xml', '-i': '127.0.0.1', '-p': '5061', '-s': 'pres_list'} }
 
 test-config:
-    list_name: 'pres_list'
-    resources:
+    list-name: 'pres_list'
+    packets:
         -
-            {
+            full-state: True
+            resources: {
                 'pres_sublist': {
                     'type': 'Multipart', 'state': 'active', 'sublist': {
                         'alice': {'type': 'PIDF', 'state': 'active'},
@@ -54,7 +55,8 @@
                 'carol': {'type': 'PIDF', 'state': 'active'}
             }
         -
-            {
+            full-state: True
+            resources: {
                 'pres_sublist': {
                     'type': 'Multipart', 'state': 'active', 'sublist': {
                         'alice': {'type': 'PIDF', 'state': 'active'},
@@ -63,11 +65,6 @@
                 },
                 'carol': {'type': 'PIDF', 'state': 'active'}
             }
-    full_state:
-        -
-            True
-        -
-            True
-    ami_action:
+    ami-action:
         -
             { 'Action': 'SetVar', 'Variable': 'DEVICE_STATE(Custom:carol)', 'Value': 'INUSE' }
diff --git a/tests/channels/pjsip/subscriptions/rls/lists_of_lists/nominal/presence/initial_notify/test-config.yaml b/tests/channels/pjsip/subscriptions/rls/lists_of_lists/nominal/presence/initial_notify/test-config.yaml
index ae1730c..aa405e0 100644
--- a/tests/channels/pjsip/subscriptions/rls/lists_of_lists/nominal/presence/initial_notify/test-config.yaml
+++ b/tests/channels/pjsip/subscriptions/rls/lists_of_lists/nominal/presence/initial_notify/test-config.yaml
@@ -46,7 +46,7 @@
     modules:
         -
             config-section: 'test-config'
-            typename: 'rls_test.IntegrityCheck'
+            typename: 'rls_test.RLSTest'
 
 test-case-config:
     test-iterations:
@@ -55,10 +55,11 @@
                 - { 'key-args': {'scenario': 'list_subscribe.xml', '-i': '127.0.0.1', '-p': '5061', '-s': 'pres_list'} }
 
 test-config:
-    list_name: 'pres_list'
-    resources:
+    list-name: 'pres_list'
+    packets:
         -
-            {
+            full-state: True
+            resources: {
                 'pres_sublist': {
                     'type': 'Multipart', 'state': 'active', 'sublist': {
                         'alice': {'type': 'PIDF', 'state': 'active'},
@@ -67,6 +68,3 @@
                 },
                 'carol': {'type': 'PIDF', 'state': 'active'}
             }
-    full_state:
-        -
-            True
diff --git a/tests/channels/pjsip/subscriptions/rls/lists_of_lists/nominal/presence/listception_initial_notify/test-config.yaml b/tests/channels/pjsip/subscriptions/rls/lists_of_lists/nominal/presence/listception_initial_notify/test-config.yaml
index a188564..80a0542 100644
--- a/tests/channels/pjsip/subscriptions/rls/lists_of_lists/nominal/presence/listception_initial_notify/test-config.yaml
+++ b/tests/channels/pjsip/subscriptions/rls/lists_of_lists/nominal/presence/listception_initial_notify/test-config.yaml
@@ -27,7 +27,7 @@
     modules:
         -
             config-section: 'test-config'
-            typename: 'rls_test.IntegrityCheck'
+            typename: 'rls_test.RLSTest'
 
 test-case-config:
     test-iterations:
@@ -36,10 +36,11 @@
                 - { 'key-args': {'scenario': 'list_subscribe.xml', '-i': '127.0.0.1', '-p': '5061', '-s': 'pres_list'} }
 
 test-config:
-    list_name: 'pres_list'
-    resources:
+    list-name: 'pres_list'
+    packets:
         -
-            {
+            full-state: True
+            resources: {
                 'pres_sublist': {
                     'type': 'Multipart', 'state': 'active', 'sublist': {
                         'alice': {'type': 'PIDF', 'state': 'active'},
@@ -53,6 +54,3 @@
                 },
                 'carol': {'type': 'PIDF', 'state': 'active'}
             }
-    full_state:
-        -
-            True
diff --git a/tests/channels/pjsip/subscriptions/rls/lists_of_lists/nominal/presence/partial_state_alice/test-config.yaml b/tests/channels/pjsip/subscriptions/rls/lists_of_lists/nominal/presence/partial_state_alice/test-config.yaml
index 9772f8e..c1c9f66 100644
--- a/tests/channels/pjsip/subscriptions/rls/lists_of_lists/nominal/presence/partial_state_alice/test-config.yaml
+++ b/tests/channels/pjsip/subscriptions/rls/lists_of_lists/nominal/presence/partial_state_alice/test-config.yaml
@@ -33,7 +33,7 @@
     modules:
         -
             config-section: 'test-config'
-            typename: 'rls_test.IntegrityCheck'
+            typename: 'rls_test.RLSTest'
 
 test-case-config:
     test-iterations:
@@ -42,10 +42,11 @@
                 - { 'key-args': {'scenario': 'list_subscribe.xml', '-i': '127.0.0.1', '-p': '5061', '-s': 'pres_list'} }
 
 test-config:
-    list_name: 'pres_list'
-    resources:
+    list-name: 'pres_list'
+    packets:
         -
-            {
+            full-state: True
+            resources: {
                 'pres_sublist': {
                     'type': 'Multipart', 'state': 'active', 'sublist': {
                         'alice': {'type': 'PIDF', 'state': 'active'},
@@ -55,18 +56,14 @@
                 'carol': {'type': 'PIDF', 'state': 'active'}
             }
         -
-            {
+            full-state: False
+            resources: {
                 'pres_sublist': {
                     'type': 'Multipart', 'state': 'active', 'sublist': {
                         'alice': {'type': 'PIDF', 'state': 'active'},
                     }
                 }
             }
-    full_state:
-        -
-            True
-        -
-            False
-    ami_action:
+    ami-action:
         -
             { 'Action': 'SetVar', 'Variable': 'DEVICE_STATE(Custom:alice)', 'Value': 'INUSE' }
diff --git a/tests/channels/pjsip/subscriptions/rls/lists_of_lists/nominal/presence/partial_state_carol/test-config.yaml b/tests/channels/pjsip/subscriptions/rls/lists_of_lists/nominal/presence/partial_state_carol/test-config.yaml
index f3a4c40..38f6dec 100644
--- a/tests/channels/pjsip/subscriptions/rls/lists_of_lists/nominal/presence/partial_state_carol/test-config.yaml
+++ b/tests/channels/pjsip/subscriptions/rls/lists_of_lists/nominal/presence/partial_state_carol/test-config.yaml
@@ -33,7 +33,7 @@
     modules:
         -
             config-section: 'test-config'
-            typename: 'rls_test.IntegrityCheck'
+            typename: 'rls_test.RLSTest'
 
 test-case-config:
     test-iterations:
@@ -42,10 +42,11 @@
                 - { 'key-args': {'scenario': 'list_subscribe.xml', '-i': '127.0.0.1', '-p': '5061', '-s': 'pres_list'} }
 
 test-config:
-    list_name: 'pres_list'
-    resources:
+    list-name: 'pres_list'
+    packets:
         -
-            {
+            full-state: True
+            resources: {
                 'pres_sublist': {
                     'type': 'Multipart', 'state': 'active', 'sublist': {
                         'alice': {'type': 'PIDF', 'state': 'active'},
@@ -55,14 +56,10 @@
                 'carol': {'type': 'PIDF', 'state': 'active'}
             }
         -
-            {
+            full-state: False
+            resources: {
                 'carol': {'type': 'PIDF', 'state': 'active'}
             }
-    full_state:
-        -
-            True
-        -
-            False
-    ami_action:
+    ami-action:
         -
             { 'Action': 'SetVar', 'Variable': 'DEVICE_STATE(Custom:carol)', 'Value': 'INUSE' }
diff --git a/tests/channels/pjsip/subscriptions/rls/lists_of_lists/nominal/presence/resubscribe_full_state/test-config.yaml b/tests/channels/pjsip/subscriptions/rls/lists_of_lists/nominal/presence/resubscribe_full_state/test-config.yaml
index 47cb6ca..3100564 100644
--- a/tests/channels/pjsip/subscriptions/rls/lists_of_lists/nominal/presence/resubscribe_full_state/test-config.yaml
+++ b/tests/channels/pjsip/subscriptions/rls/lists_of_lists/nominal/presence/resubscribe_full_state/test-config.yaml
@@ -33,7 +33,7 @@
     modules:
         -
             config-section: 'test-config'
-            typename: 'rls_test.IntegrityCheck'
+            typename: 'rls_test.RLSTest'
 
 test-case-config:
     test-iterations:
@@ -42,10 +42,11 @@
                 - { 'key-args': {'scenario': 'resubscribe.xml', '-i': '127.0.0.1', '-p': '5061', '-s': 'pres_list'} }
 
 test-config:
-    list_name: 'pres_list'
-    resources:
+    list-name: 'pres_list'
+    packets:
         -
-            {
+            full-state: True
+            resources: {
                 'pres_sublist': {
                     'type': 'Multipart', 'state': 'active', 'sublist': {
                         'alice': {'type': 'PIDF', 'state': 'active'},
@@ -55,7 +56,8 @@
                 'carol': {'type': 'PIDF', 'state': 'active'}
             }
         -
-            {
+            full-state: True
+            resources: {
                 'pres_sublist': {
                     'type': 'Multipart', 'state': 'active', 'sublist': {
                         'alice': {'type': 'PIDF', 'state': 'active'},
@@ -64,9 +66,3 @@
                 },
                 'carol': {'type': 'PIDF', 'state': 'active'}
             }
-
-    full_state:
-        -
-            True
-        -
-            True
diff --git a/tests/channels/pjsip/subscriptions/rls/lists_of_lists/nominal/presence/termination_full_state/test-config.yaml b/tests/channels/pjsip/subscriptions/rls/lists_of_lists/nominal/presence/termination_full_state/test-config.yaml
index 8754c7d..d0c5a76 100644
--- a/tests/channels/pjsip/subscriptions/rls/lists_of_lists/nominal/presence/termination_full_state/test-config.yaml
+++ b/tests/channels/pjsip/subscriptions/rls/lists_of_lists/nominal/presence/termination_full_state/test-config.yaml
@@ -34,7 +34,7 @@
     modules:
         -
             config-section: 'test-config'
-            typename: 'rls_test.IntegrityCheck'
+            typename: 'rls_test.RLSTest'
 
 test-case-config:
     test-iterations:
@@ -43,10 +43,11 @@
                 - { 'key-args': {'scenario': 'termination.xml', '-i': '127.0.0.1', '-p': '5061', '-s': 'pres_list'} }
 
 test-config:
-    list_name: 'pres_list'
-    resources:
+    list-name: 'pres_list'
+    packets:
         -
-            {
+            full-state: True
+            resources: {
                 'pres_sublist': {
                     'type': 'Multipart', 'state': 'active', 'sublist': {
                         'alice': {'type': 'PIDF', 'state': 'active'},
@@ -56,7 +57,8 @@
                 'carol': {'type': 'PIDF', 'state': 'active'}
             }
         -
-            {
+            full-state: True
+            resources: {
                 'pres_sublist': {
                     'type': 'Multipart', 'state': 'terminated', 'sublist': {
                         'alice': {'type': 'PIDF', 'state': 'terminated'},
@@ -65,9 +67,3 @@
                 },
                 'carol': {'type': 'PIDF', 'state': 'terminated'}
             }
-
-    full_state:
-        -
-            True
-        -
-            True
diff --git a/tests/channels/pjsip/subscriptions/rls/lists_of_lists/off_nominal/mwi/resource_duplication/test-config.yaml b/tests/channels/pjsip/subscriptions/rls/lists_of_lists/off_nominal/mwi/resource_duplication/test-config.yaml
index ad46a48..275712f 100644
--- a/tests/channels/pjsip/subscriptions/rls/lists_of_lists/off_nominal/mwi/resource_duplication/test-config.yaml
+++ b/tests/channels/pjsip/subscriptions/rls/lists_of_lists/off_nominal/mwi/resource_duplication/test-config.yaml
@@ -52,7 +52,7 @@
     modules:
         -
             config-section: 'test-config'
-            typename: 'rls_test.IntegrityCheck'
+            typename: 'rls_test.RLSTest'
 
 test-case-config:
     test-iterations:
@@ -61,10 +61,11 @@
                 - { 'key-args': {'scenario': 'list_subscribe.xml', '-i': '127.0.0.1', '-p': '5061', '-s': 'mail_list'} }
 
 test-config:
-    list_name: 'mail_list'
-    resources:
+    list-name: 'mail_list'
+    packets:
         -
-            {
+            full-state: True
+            resources: {
                 # Primary list carol wins because it was listed before mail_sublist
                 'carol': {
                     'type': 'MWI',
@@ -91,6 +92,3 @@
                     }
                 }
             }
-    full_state:
-        -
-            True
diff --git a/tests/channels/pjsip/subscriptions/rls/lists_of_lists/off_nominal/mwi/shared_name_w_list_support/test-config.yaml b/tests/channels/pjsip/subscriptions/rls/lists_of_lists/off_nominal/mwi/shared_name_w_list_support/test-config.yaml
index 40c6b41..45ddead 100644
--- a/tests/channels/pjsip/subscriptions/rls/lists_of_lists/off_nominal/mwi/shared_name_w_list_support/test-config.yaml
+++ b/tests/channels/pjsip/subscriptions/rls/lists_of_lists/off_nominal/mwi/shared_name_w_list_support/test-config.yaml
@@ -51,7 +51,7 @@
     modules:
         -
             config-section: 'test-config'
-            typename: 'rls_test.IntegrityCheck'
+            typename: 'rls_test.RLSTest'
 
 test-case-config:
     test-iterations:
@@ -60,10 +60,11 @@
                 - { 'key-args': {'scenario': 'list_subscribe.xml', '-i': '127.0.0.1', '-p': '5061', '-s': 'carol'} }
 
 test-config:
-    list_name: 'carol'
-    resources:
+    list-name: 'carol'
+    packets:
         -
-            {
+            full-state: True
+            resources: {
                 'alice': {
                     'type': 'MWI',
                     'state': 'active',
@@ -83,6 +84,3 @@
                     }
                 }
             }
-    full_state:
-        -
-            True
diff --git a/tests/channels/pjsip/subscriptions/rls/lists_of_lists/off_nominal/presence/resource_duplication/test-config.yaml b/tests/channels/pjsip/subscriptions/rls/lists_of_lists/off_nominal/presence/resource_duplication/test-config.yaml
index 81cf5b7..ec23387 100644
--- a/tests/channels/pjsip/subscriptions/rls/lists_of_lists/off_nominal/presence/resource_duplication/test-config.yaml
+++ b/tests/channels/pjsip/subscriptions/rls/lists_of_lists/off_nominal/presence/resource_duplication/test-config.yaml
@@ -50,7 +50,7 @@
     modules:
         -
             config-section: 'test-config'
-            typename: 'rls_test.IntegrityCheck'
+            typename: 'rls_test.RLSTest'
 
 test-case-config:
     test-iterations:
@@ -59,10 +59,11 @@
                 - { 'key-args': {'scenario': 'list_subscribe.xml', '-i': '127.0.0.1', '-p': '5061', '-s': 'pres_list'} }
 
 test-config:
-    list_name: 'pres_list'
-    resources:
+    list-name: 'pres_list'
+    packets:
         -
-            {
+            full-state: True
+            resources: {
                 'pres_sublist': {
                     'type': 'Multipart', 'state': 'active', 'sublist': {
                         'alice': {'type': 'PIDF', 'state': 'active'},
@@ -71,6 +72,3 @@
                     }
                 },
             }
-    full_state:
-        -
-            True
diff --git a/tests/channels/pjsip/subscriptions/rls/lists_of_lists/off_nominal/presence/shared_name_w_list_support/test-config.yaml b/tests/channels/pjsip/subscriptions/rls/lists_of_lists/off_nominal/presence/shared_name_w_list_support/test-config.yaml
index d1a65b1..f750a40 100644
--- a/tests/channels/pjsip/subscriptions/rls/lists_of_lists/off_nominal/presence/shared_name_w_list_support/test-config.yaml
+++ b/tests/channels/pjsip/subscriptions/rls/lists_of_lists/off_nominal/presence/shared_name_w_list_support/test-config.yaml
@@ -46,7 +46,7 @@
     modules:
         -
             config-section: 'test-config'
-            typename: 'rls_test.IntegrityCheck'
+            typename: 'rls_test.RLSTest'
 
 test-case-config:
     test-iterations:
@@ -55,10 +55,11 @@
                 - { 'key-args': {'scenario': 'list_subscribe.xml', '-i': '127.0.0.1', '-p': '5061', '-s': 'carol'} }
 
 test-config:
-    list_name: 'carol'
-    resources:
+    list-name: 'carol'
+    packets:
         -
-            {
+            full-state: True
+            resources: {
                 'pres_sublist': {
                     'type': 'Multipart', 'state': 'active', 'sublist': {
                         'bob': {'type': 'PIDF', 'state': 'active'},
@@ -66,6 +67,3 @@
                 },
                 'alice': {'type': 'PIDF', 'state': 'active'}
             }
-    full_state:
-        -
-            True
diff --git a/tests/channels/pjsip/subscriptions/rls/rls_test.py b/tests/channels/pjsip/subscriptions/rls/rls_test.py
index b06c3da..f0b64e2 100755
--- a/tests/channels/pjsip/subscriptions/rls/rls_test.py
+++ b/tests/channels/pjsip/subscriptions/rls/rls_test.py
@@ -20,20 +20,22 @@
 LOGGER = logging.getLogger(__name__)
 
 
-class IntegrityCheck(VOIPListener):
-    """Verifies that SIP notifies contain expected updates
+class RLSTest(VOIPListener):
+    """Verifies that SIP notifies contain expected updates.
 
        A test module that observes incoming SIP notifies and compares them
        to a set of expected results. Tests may optionally specify for an
        arbitrary number of AMI actions to be executed in order at 2 second
        intervals from the start of the test.
     """
-    def __init__(self, module_config, test_object):
-        """Constructor
 
-        Arguments:
-        module_config Dictionary containing test configuration
-        test_object used to manipulate reactor and set/remove failure tokens
+    def __init__(self, module_config, test_object):
+        """Constructor.
+
+        Keyword Arguments:
+        module_config          -- Dictionary containing test configuration.
+        test_object            -- Used to manipulate reactor and set/remove
+                                  failure tokens.
         """
         self.set_pcap_defaults(module_config)
         VOIPListener.__init__(self, module_config, test_object)
@@ -42,14 +44,17 @@
         self.token = test_object.create_fail_token("Haven't handled all "
                                                    "expected NOTIFY packets.")
 
-        self.resources = module_config['resources']
-        self.list_name = module_config['list_name']
-        self.full_state = module_config['full_state']
-        self.ami_action = module_config.get('ami_action')
-        self.stop_after_notifys = module_config.get('stop_after_notifys', True)
 
-        self.version = 0
+        self.list_name = module_config['list-name']
+        self.log_packets = module_config.get("log-packets", False)
+        self.packets = module_config['packets']
+        self.ami_action = module_config.get('ami-action')
+        self.stop_test_after_notifys = \
+            module_config.get("stop-test-after-notifys", True)
+
+
         self.ami = None
+        self.packets_idx = 0
         self.test_object.register_ami_observer(self.ami_connect)
         if hasattr(self.test_object, 'register_scenario_started_observer'):
             self.test_object.register_scenario_started_observer(
@@ -76,8 +81,8 @@
         the packet that will verify that the contents of the NOTIFY match the
         expectations set for NOTIFY in the test configuration.
 
-        Arguments:
-        packet Incoming SIP Packet
+        Keyword Arguments:
+        packet                 -- Incoming SIP Packet
         """
 
         LOGGER.debug('Received SIP packet')
@@ -91,34 +96,38 @@
                          'multipart body')
             return
 
-        if self.version >= len(self.resources):
+        if self.packets_idx >= len(self.packets):
             LOGGER.debug('Ignoring packet, version is higher than count of ' +
                          'test expectations')
             return
 
+        resources = self.packets[self.packets_idx]["resources"]
+        full_state = self.packets[self.packets_idx]["full-state"]
+
         validator = RLSValidator(test_object=self.test_object,
                                  packet=packet,
-                                 version=self.version,
-                                 full_state=self.full_state[self.version],
+                                 version=self.packets_idx,
+                                 full_state=full_state,
                                  list_name=self.list_name,
-                                 resources=self.resources[self.version])
+                                 resources=resources)
 
         debug_msg = "validating packet -- expecting {0}"
-        LOGGER.debug(debug_msg.format(self.resources[self.version]))
+        LOGGER.debug(debug_msg.format(self.packets[self.packets_idx]))
         if not validator.check_integrity():
             LOGGER.error('Integrity Check Failed.')
             return
 
         info_msg = "Packet validated successfully. Test Phase {0} Completed."
-        LOGGER.info(info_msg.format(self.version))
-        self.version += 1
+        LOGGER.info(info_msg.format(self.packets_idx))
+        self.packets_idx += 1
 
-        if self.version == len(self.resources):
+        if self.packets_idx == len(self.packets):
             info_msg = "All test phases completed. RLS verification complete."
             LOGGER.info(info_msg)
             self.test_object.remove_fail_token(self.token)
             if self.stop_after_notifys:
-                # We only deal with as many NOTIFIES as we have resources
+                # We only deal with as many NOTIFIES as we have defined in our
+                # test-config.yaml
                 self.test_object.set_passed(True)
                 self.test_object.stop_reactor()
 
@@ -134,10 +143,14 @@
 
         Note: Overrides scenario_started from VOIPListener
 
-        Arguments:
-        scenario Not actually used, just part of the signature.
+        Keyword Arguments:
+        scenario               -- The event payload. (Not actually used, just
+                                  part of the signature.)
         """
+
         def _perform_ami_action():
+            """Helper function to loop executing an ami action."""
+
             action = self.ami_action.pop(0)
             debug_msg = "Sending AMI action: {0}"
             LOGGER.debug(debug_msg.format(action))

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

Gerrit-MessageType: newchange
Gerrit-Change-Id: I3bc60588b1430d152de608a0c2a733a843411666
Gerrit-PatchSet: 1
Gerrit-Project: testsuite
Gerrit-Branch: master
Gerrit-Owner: Ashley Sanders <asanders at digium.com>



More information about the asterisk-code-review mailing list