[Asterisk-code-review] sorcery: Add SorceryMemoryCache AMI action tests. (testsuite[master])

Mark Michelson asteriskteam at digium.com
Thu Jun 4 09:47:57 CDT 2015


Mark Michelson has submitted this change and it was merged.

Change subject: sorcery: Add SorceryMemoryCache AMI action tests.
......................................................................


sorcery: Add SorceryMemoryCache AMI action tests.

This change adds tests for the res_sorcery_memory_cache AMI actions.

memory_cache_expire expires all objects within a sorcery
memory cache, confirms removal, and confirms the backend is
queried when retrieved again.

memory_cache_expire_object expires a specific object within a
sorcery memory cache, confirms removal, and confirms the backend
is queried when retrieved again.

memory_cache_stale marks all objects as stale within a
sorcery memory cache, removes them from the backend, performs
a retrieve to force a refresh, waits for a refresh test event,
and confirms that an object can no longer be retrieved.

memory_cache_stale_object marks one object as stale within a
sorcery memory cache, removes it from the backend, performs
a retrieve to force a refresh, waits for a refresh test event,
and confirms that the object can no longer be retrieved.

ASTERISK-25067
Reported by Matt Jordan

Change-Id: I8fc051a92f52ae4e8e064333138157f28fabfa5f
---
A tests/sorcery/memory_cache_expire/configs/ast1/extconfig.conf
A tests/sorcery/memory_cache_expire/configs/ast1/sorcery.conf
A tests/sorcery/memory_cache_expire/memory_cache_expire.py
A tests/sorcery/memory_cache_expire/test-config.yaml
A tests/sorcery/memory_cache_expire_object/configs/ast1/extconfig.conf
A tests/sorcery/memory_cache_expire_object/configs/ast1/sorcery.conf
A tests/sorcery/memory_cache_expire_object/memory_cache_expire_object.py
A tests/sorcery/memory_cache_expire_object/test-config.yaml
A tests/sorcery/memory_cache_stale/configs/ast1/extconfig.conf
A tests/sorcery/memory_cache_stale/configs/ast1/sorcery.conf
A tests/sorcery/memory_cache_stale/memory_cache_stale.py
A tests/sorcery/memory_cache_stale/test-config.yaml
A tests/sorcery/memory_cache_stale_object/configs/ast1/extconfig.conf
A tests/sorcery/memory_cache_stale_object/configs/ast1/sorcery.conf
A tests/sorcery/memory_cache_stale_object/memory_cache_stale_object.py
A tests/sorcery/memory_cache_stale_object/test-config.yaml
A tests/sorcery/tests.yaml
M tests/tests.yaml
18 files changed, 605 insertions(+), 0 deletions(-)

Approvals:
  Kevin Harwell: Looks good to me, but someone else must approve
  Mark Michelson: Looks good to me, approved; Verified
  Samuel Galarneau: Looks good to me, but someone else must approve



diff --git a/tests/sorcery/memory_cache_expire/configs/ast1/extconfig.conf b/tests/sorcery/memory_cache_expire/configs/ast1/extconfig.conf
new file mode 100644
index 0000000..adfe518
--- /dev/null
+++ b/tests/sorcery/memory_cache_expire/configs/ast1/extconfig.conf
@@ -0,0 +1,2 @@
+[settings]
+endpoints => curl,http://localhost:46821/endpoint
diff --git a/tests/sorcery/memory_cache_expire/configs/ast1/sorcery.conf b/tests/sorcery/memory_cache_expire/configs/ast1/sorcery.conf
new file mode 100644
index 0000000..51e79e6
--- /dev/null
+++ b/tests/sorcery/memory_cache_expire/configs/ast1/sorcery.conf
@@ -0,0 +1,3 @@
+[res_pjsip]
+endpoint/cache=memory_cache
+endpoint=realtime,endpoints
diff --git a/tests/sorcery/memory_cache_expire/memory_cache_expire.py b/tests/sorcery/memory_cache_expire/memory_cache_expire.py
new file mode 100644
index 0000000..6267279
--- /dev/null
+++ b/tests/sorcery/memory_cache_expire/memory_cache_expire.py
@@ -0,0 +1,90 @@
+#!/usr/bin/env python
+
+'''
+Copyright (C) 2015, Digium, Inc.
+Joshua Colp <jcolp at digium.com>
+
+This program is free software, distributed under the terms of
+the GNU General Public License Version 2.
+'''
+
+import logging
+
+LOGGER = logging.getLogger(__name__)
+ENDPOINT = 'test'
+CACHE = 'res_pjsip/endpoint'
+
+class MemoryCacheExpireTest(object):
+    def __init__(self, rt_data, test_object, ami):
+        self.rt_data = rt_data
+        self.test_object = test_object
+        self.ami = ami
+        self.endpoint_retrieved = 0
+
+    def fail_test(self):
+        self.test_object.set_passed(False)
+        self.test_object.stop_reactor()
+
+    def pass_test(self):
+        self.test_object.set_passed(True)
+        self.test_object.stop_reactor()
+
+    def retrieve_endpoint(self):
+        message = {
+            'Action': 'PJSIPShowEndpoint',
+            'Endpoint': ENDPOINT,
+        }
+        self.ami.sendMessage(message)
+
+    def expire_cache(self):
+        def _expect_error(message):
+            if type(message) is not dict:
+                return 0
+
+            if message.get('response') != 'Error':
+                self.fail_test()
+            else:
+                self.rt_data.add_row('endpoint', { 'id': ENDPOINT })
+                self.retrieve_endpoint()
+
+            return 0
+
+        def _expired_cache(message):
+            if type(message) is not dict:
+                return 0
+
+            if message.get('response') != 'Success':
+                self.fail_test()
+                return 0
+
+            action = {
+                'Action': 'PJSIPShowEndpoint',
+                'Endpoint': ENDPOINT,
+            }
+            self.ami.sendMessage(action, responseCallback=_expect_error)
+
+            return 0
+
+        message = {
+            'Action': 'SorceryMemoryCacheExpire',
+            'Cache': CACHE,
+        }
+        self.ami.sendMessage(message, responseCallback=_expired_cache)
+
+    def endpoint_detail_complete_callback(self, ami, event):
+        self.endpoint_retrieved += int(event.get('listitems'))
+
+        if self.endpoint_retrieved == 1:
+             self.rt_data.delete_rows('endpoint', { 'id': ENDPOINT })
+             self.retrieve_endpoint()
+        elif self.endpoint_retrieved == 2:
+             self.expire_cache()
+        elif self.endpoint_retrieved == 3:
+             self.pass_test()
+
+def check_it(rt_data, test_object, ami):
+    test = MemoryCacheExpireTest(rt_data, test_object, ami)
+
+    ami.registerEvent('EndpointDetailComplete', test.endpoint_detail_complete_callback)
+
+    test.retrieve_endpoint()
diff --git a/tests/sorcery/memory_cache_expire/test-config.yaml b/tests/sorcery/memory_cache_expire/test-config.yaml
new file mode 100644
index 0000000..53086be
--- /dev/null
+++ b/tests/sorcery/memory_cache_expire/test-config.yaml
@@ -0,0 +1,54 @@
+testinfo:
+    summary:     'Sorcery Memory Cache AMI SorceryMemoryCacheExpire Test'
+    description: |
+        'This tests that the SorceryMemoryCacheExpire AMI action successfully expires
+         and removes an object from the cache upon invocation. The test works by doing
+         the following:
+         1. PJSIP endpoints are configured with a memory cache and realtime.
+         2. A PJSIP endpoint is defined in realtime at the start of the test.
+         3. The PJSIPShowEndpoint AMI action is invoked which populates the memory cache.
+         4. The PJSIP endpoint is removed from realtime.
+         5. The PJSIPShowEndpoint AMI action is invoked to confirm the endpoint
+            is retrieved from the cache.
+         6. The SorceryMemoryCacheExpire AMI action is invoked on the memory cache.
+         7. The PJSIPShowEndpoint AMI action is invoked to confirm the endpoint
+            CAN NOT be retrieved as it does not exist in realtime or the cache.
+         8. The PJSIP endpoint is added back into realtime.
+         9. The PJSIPShowEndpoint AMI action is invoked to confirm the endpoint is
+            retrieved from realtime.'
+
+
+properties:
+    minversion: '14.0.0'
+    dependencies:
+        - python: 'twisted'
+        - python: 'starpy'
+        - asterisk: 'res_pjsip'
+        - asterisk: 'res_config_curl'
+        - asterisk: 'func_curl'
+        - asterisk: 'res_sorcery_realtime'
+        - asterisk: 'res_sorcery_memory_cache'
+    tags:
+        - realtime
+        - pjsip
+
+test-modules:
+    add-test-to-search-path: 'True'
+    test-object:
+        config-section: test-case-config
+        typename: 'test_case.TestCaseModule'
+    modules:
+        -
+            config-section: 'realtime-config'
+            typename: 'realtime_test_module.RealtimeTestModule'
+
+test-case-config:
+    connect-ami: 'True'
+
+realtime-config:
+    entry_module: 'memory_cache_expire'
+    entry_method: 'check_it'
+    data:
+        endpoint:
+            -
+                id: 'test'
diff --git a/tests/sorcery/memory_cache_expire_object/configs/ast1/extconfig.conf b/tests/sorcery/memory_cache_expire_object/configs/ast1/extconfig.conf
new file mode 100644
index 0000000..adfe518
--- /dev/null
+++ b/tests/sorcery/memory_cache_expire_object/configs/ast1/extconfig.conf
@@ -0,0 +1,2 @@
+[settings]
+endpoints => curl,http://localhost:46821/endpoint
diff --git a/tests/sorcery/memory_cache_expire_object/configs/ast1/sorcery.conf b/tests/sorcery/memory_cache_expire_object/configs/ast1/sorcery.conf
new file mode 100644
index 0000000..51e79e6
--- /dev/null
+++ b/tests/sorcery/memory_cache_expire_object/configs/ast1/sorcery.conf
@@ -0,0 +1,3 @@
+[res_pjsip]
+endpoint/cache=memory_cache
+endpoint=realtime,endpoints
diff --git a/tests/sorcery/memory_cache_expire_object/memory_cache_expire_object.py b/tests/sorcery/memory_cache_expire_object/memory_cache_expire_object.py
new file mode 100644
index 0000000..243bc6c
--- /dev/null
+++ b/tests/sorcery/memory_cache_expire_object/memory_cache_expire_object.py
@@ -0,0 +1,91 @@
+#!/usr/bin/env python
+
+'''
+Copyright (C) 2015, Digium, Inc.
+Joshua Colp <jcolp at digium.com>
+
+This program is free software, distributed under the terms of
+the GNU General Public License Version 2.
+'''
+
+import logging
+
+LOGGER = logging.getLogger(__name__)
+ENDPOINT = 'test'
+CACHE = 'res_pjsip/endpoint'
+
+class MemoryCacheExpireObjectTest(object):
+    def __init__(self, rt_data, test_object, ami):
+        self.rt_data = rt_data
+        self.test_object = test_object
+        self.ami = ami
+        self.endpoint_retrieved = 0
+
+    def fail_test(self):
+        self.test_object.set_passed(False)
+        self.test_object.stop_reactor()
+
+    def pass_test(self):
+        self.test_object.set_passed(True)
+        self.test_object.stop_reactor()
+
+    def retrieve_endpoint(self):
+        message = {
+            'Action': 'PJSIPShowEndpoint',
+            'Endpoint': ENDPOINT,
+        }
+        self.ami.sendMessage(message)
+
+    def expire_cache(self):
+        def _expect_error(message):
+            if type(message) is not dict:
+                return 0
+
+            if message.get('response') != 'Error':
+                self.fail_test()
+            else:
+                self.rt_data.add_row('endpoint', { 'id': ENDPOINT })
+                self.retrieve_endpoint()
+
+            return 0
+
+        def _expired_cache(message):
+            if type(message) is not dict:
+                return 0
+
+            if message.get('response') != 'Success':
+                self.fail_test()
+                return 0
+
+            action = {
+                'Action': 'PJSIPShowEndpoint',
+                'Endpoint': ENDPOINT,
+            }
+            self.ami.sendMessage(action, responseCallback=_expect_error)
+
+            return 0
+
+        message = {
+            'Action': 'SorceryMemoryCacheExpireObject',
+            'Cache': CACHE,
+            'Object': ENDPOINT,
+        }
+        self.ami.sendMessage(message, responseCallback=_expired_cache)
+
+    def endpoint_detail_complete_callback(self, ami, event):
+        self.endpoint_retrieved += int(event.get('listitems'))
+
+        if self.endpoint_retrieved == 1:
+             self.rt_data.delete_rows('endpoint', { 'id': ENDPOINT })
+             self.retrieve_endpoint()
+        elif self.endpoint_retrieved == 2:
+             self.expire_cache()
+        elif self.endpoint_retrieved == 3:
+             self.pass_test()
+
+def check_it(rt_data, test_object, ami):
+    test = MemoryCacheExpireObjectTest(rt_data, test_object, ami)
+
+    ami.registerEvent('EndpointDetailComplete', test.endpoint_detail_complete_callback)
+
+    test.retrieve_endpoint()
diff --git a/tests/sorcery/memory_cache_expire_object/test-config.yaml b/tests/sorcery/memory_cache_expire_object/test-config.yaml
new file mode 100644
index 0000000..4e2f62a
--- /dev/null
+++ b/tests/sorcery/memory_cache_expire_object/test-config.yaml
@@ -0,0 +1,54 @@
+testinfo:
+    summary:     'Sorcery Memory Cache AMI SorceryMemoryCacheExpireObject Test'
+    description: |
+        'This tests that the SorceryMemoryCacheExpireObject AMI action successfully expires
+         and removes an object from the cache upon invocation. The test works by doing
+         the following:
+         1. PJSIP endpoints are configured with a memory cache and realtime.
+         2. A PJSIP endpoint is defined in realtime at the start of the test.
+         3. The PJSIPShowEndpoint AMI action is invoked which populates the memory cache.
+         4. The PJSIP endpoint is removed from realtime.
+         5. The PJSIPShowEndpoint AMI action is invoked to confirm the endpoint
+            is retrieved from the cache.
+         6. The SorceryMemoryCacheExpireObject AMI action is invoked on the memory cache.
+         7. The PJSIPShowEndpoint AMI action is invoked to confirm the endpoint
+            CAN NOT be retrieved as it does not exist in realtime or the cache.
+         8. The PJSIP endpoint is added back into realtime.
+         9. The PJSIPShowEndpoint AMI action is invoked to confirm the endpoint is
+            retrieved from realtime.'
+
+
+properties:
+    minversion: '14.0.0'
+    dependencies:
+        - python: 'twisted'
+        - python: 'starpy'
+        - asterisk: 'res_pjsip'
+        - asterisk: 'res_config_curl'
+        - asterisk: 'func_curl'
+        - asterisk: 'res_sorcery_realtime'
+        - asterisk: 'res_sorcery_memory_cache'
+    tags:
+        - realtime
+        - pjsip
+
+test-modules:
+    add-test-to-search-path: 'True'
+    test-object:
+        config-section: test-case-config
+        typename: 'test_case.TestCaseModule'
+    modules:
+        -
+            config-section: 'realtime-config'
+            typename: 'realtime_test_module.RealtimeTestModule'
+
+test-case-config:
+    connect-ami: 'True'
+
+realtime-config:
+    entry_module: 'memory_cache_expire_object'
+    entry_method: 'check_it'
+    data:
+        endpoint:
+            -
+                id: 'test'
diff --git a/tests/sorcery/memory_cache_stale/configs/ast1/extconfig.conf b/tests/sorcery/memory_cache_stale/configs/ast1/extconfig.conf
new file mode 100644
index 0000000..adfe518
--- /dev/null
+++ b/tests/sorcery/memory_cache_stale/configs/ast1/extconfig.conf
@@ -0,0 +1,2 @@
+[settings]
+endpoints => curl,http://localhost:46821/endpoint
diff --git a/tests/sorcery/memory_cache_stale/configs/ast1/sorcery.conf b/tests/sorcery/memory_cache_stale/configs/ast1/sorcery.conf
new file mode 100644
index 0000000..04e5154
--- /dev/null
+++ b/tests/sorcery/memory_cache_stale/configs/ast1/sorcery.conf
@@ -0,0 +1,3 @@
+[res_pjsip]
+endpoint/cache=memory_cache,object_lifetime_stale=60
+endpoint=realtime,endpoints
diff --git a/tests/sorcery/memory_cache_stale/memory_cache_stale.py b/tests/sorcery/memory_cache_stale/memory_cache_stale.py
new file mode 100644
index 0000000..fb2bf57
--- /dev/null
+++ b/tests/sorcery/memory_cache_stale/memory_cache_stale.py
@@ -0,0 +1,93 @@
+#!/usr/bin/env python
+
+'''
+Copyright (C) 2015, Digium, Inc.
+Joshua Colp <jcolp at digium.com>
+
+This program is free software, distributed under the terms of
+the GNU General Public License Version 2.
+'''
+
+import logging
+
+LOGGER = logging.getLogger(__name__)
+ENDPOINT = 'test'
+CACHE = 'res_pjsip/endpoint'
+
+class MemoryCacheStaleTest(object):
+    def __init__(self, rt_data, test_object, ami):
+        self.rt_data = rt_data
+        self.test_object = test_object
+        self.ami = ami
+        self.endpoint_retrieved = 0
+
+    def fail_test(self):
+        self.test_object.set_passed(False)
+        self.test_object.stop_reactor()
+
+    def pass_test(self):
+        self.test_object.set_passed(True)
+        self.test_object.stop_reactor()
+
+    def retrieve_endpoint(self):
+        message = {
+            'Action': 'PJSIPShowEndpoint',
+            'Endpoint': ENDPOINT,
+        }
+        self.ami.sendMessage(message)
+
+    def retrieve_endpoint_and_fail(self, ami, event):
+        def _expect_error(message):
+            if type(message) is not dict:
+                return 0
+
+            if message.get('response') != 'Error':
+                self.fail_test()
+                return 0
+
+            self.pass_test()
+
+            return 0
+
+        message = {
+            'Action': 'PJSIPShowEndpoint',
+            'Endpoint': ENDPOINT,
+        }
+        self.ami.sendMessage(message, responseCallback=_expect_error)
+
+    def stale_cache(self):
+        def _cache_marked_as_stale(message):
+            if type(message) is not dict:
+                return 0
+
+            if message.get('response') != 'Success':
+                self.fail_test()
+                return 0
+
+            self.ami.registerEvent('TestEvent', self.retrieve_endpoint_and_fail)
+
+            self.retrieve_endpoint()
+
+            return 0
+
+        message = {
+            'Action': 'SorceryMemoryCacheStale',
+            'Cache': CACHE,
+        }
+        self.ami.sendMessage(message, responseCallback=_cache_marked_as_stale)
+
+    def endpoint_detail_complete_callback(self, ami, event):
+        self.endpoint_retrieved += int(event.get('listitems'))
+
+        if self.endpoint_retrieved == 1:
+             self.rt_data.delete_rows('endpoint', { 'id': ENDPOINT })
+             self.stale_cache()
+        elif self.endpoint_retrieved == 3:
+             self.fail_test()
+
+def check_it(rt_data, test_object, ami):
+    test = MemoryCacheStaleTest(rt_data, test_object, ami)
+
+    ami.registerEvent('EndpointDetailComplete', test.endpoint_detail_complete_callback)
+
+    test.retrieve_endpoint()
diff --git a/tests/sorcery/memory_cache_stale/test-config.yaml b/tests/sorcery/memory_cache_stale/test-config.yaml
new file mode 100644
index 0000000..c0d8558
--- /dev/null
+++ b/tests/sorcery/memory_cache_stale/test-config.yaml
@@ -0,0 +1,51 @@
+testinfo:
+    summary:     'Sorcery Memory Cache AMI SorceryMemoryCacheStale Test'
+    description: |
+        'This tests that the SorceryMemoryCacheStale AMI action successfully marks an
+         object as stale and refreshes it upon the next retrieval. The test works by
+         doing the following:
+         1. PJSIP endpoints are configured with a memory cache and realtime.
+         2. A PJSIP endpoint is defined in realtime at the start of the test.
+         3. The PJSIPShowEndpoint AMI action is invoked which populates the memory cache.
+         4. The PJSIP endpoint is removed from realtime.
+         5. The SorceryMemoryCacheStale AMI action is invoked on the memory cache.
+         6. The PJSIPShowEndpoint AMI action is invoked to force a refresh of the object.
+         7. The test waits for 5 seconds for the fresh to occur.
+         6. The PJSIPShowEndpoint AMI action is invoked to confirm the endpoint
+            CAN NOT be retrieved as it should not exist in realtime or the cache.'
+
+
+properties:
+    minversion: '14.0.0'
+    dependencies:
+        - python: 'twisted'
+        - python: 'starpy'
+        - asterisk: 'res_pjsip'
+        - asterisk: 'res_config_curl'
+        - asterisk: 'func_curl'
+        - asterisk: 'res_sorcery_realtime'
+        - asterisk: 'res_sorcery_memory_cache'
+    tags:
+        - realtime
+        - pjsip
+
+test-modules:
+    add-test-to-search-path: 'True'
+    test-object:
+        config-section: test-case-config
+        typename: 'test_case.TestCaseModule'
+    modules:
+        -
+            config-section: 'realtime-config'
+            typename: 'realtime_test_module.RealtimeTestModule'
+
+test-case-config:
+    connect-ami: 'True'
+
+realtime-config:
+    entry_module: 'memory_cache_stale'
+    entry_method: 'check_it'
+    data:
+        endpoint:
+            -
+                id: 'test'
diff --git a/tests/sorcery/memory_cache_stale_object/configs/ast1/extconfig.conf b/tests/sorcery/memory_cache_stale_object/configs/ast1/extconfig.conf
new file mode 100644
index 0000000..adfe518
--- /dev/null
+++ b/tests/sorcery/memory_cache_stale_object/configs/ast1/extconfig.conf
@@ -0,0 +1,2 @@
+[settings]
+endpoints => curl,http://localhost:46821/endpoint
diff --git a/tests/sorcery/memory_cache_stale_object/configs/ast1/sorcery.conf b/tests/sorcery/memory_cache_stale_object/configs/ast1/sorcery.conf
new file mode 100644
index 0000000..04e5154
--- /dev/null
+++ b/tests/sorcery/memory_cache_stale_object/configs/ast1/sorcery.conf
@@ -0,0 +1,3 @@
+[res_pjsip]
+endpoint/cache=memory_cache,object_lifetime_stale=60
+endpoint=realtime,endpoints
diff --git a/tests/sorcery/memory_cache_stale_object/memory_cache_stale_object.py b/tests/sorcery/memory_cache_stale_object/memory_cache_stale_object.py
new file mode 100644
index 0000000..87b0715
--- /dev/null
+++ b/tests/sorcery/memory_cache_stale_object/memory_cache_stale_object.py
@@ -0,0 +1,94 @@
+#!/usr/bin/env python
+
+'''
+Copyright (C) 2015, Digium, Inc.
+Joshua Colp <jcolp at digium.com>
+
+This program is free software, distributed under the terms of
+the GNU General Public License Version 2.
+'''
+
+import logging
+
+LOGGER = logging.getLogger(__name__)
+ENDPOINT = 'test'
+CACHE = 'res_pjsip/endpoint'
+
+class MemoryCacheStaleObjectTest(object):
+    def __init__(self, rt_data, test_object, ami):
+        self.rt_data = rt_data
+        self.test_object = test_object
+        self.ami = ami
+        self.endpoint_retrieved = 0
+
+    def fail_test(self):
+        self.test_object.set_passed(False)
+        self.test_object.stop_reactor()
+
+    def pass_test(self):
+        self.test_object.set_passed(True)
+        self.test_object.stop_reactor()
+
+    def retrieve_endpoint(self):
+        message = {
+            'Action': 'PJSIPShowEndpoint',
+            'Endpoint': ENDPOINT,
+        }
+        self.ami.sendMessage(message)
+
+    def retrieve_endpoint_and_fail(self, ami, event):
+        def _expect_error(message):
+            if type(message) is not dict:
+                return 0
+
+            if message.get('response') != 'Error':
+                self.fail_test()
+                return 0
+
+            self.pass_test()
+
+            return 0
+
+        message = {
+            'Action': 'PJSIPShowEndpoint',
+            'Endpoint': ENDPOINT,
+        }
+        self.ami.sendMessage(message, responseCallback=_expect_error)
+
+    def stale_cache_object(self):
+        def _object_marked_as_stale(message):
+            if type(message) is not dict:
+                return 0
+
+            if message.get('response') != 'Success':
+                self.fail_test()
+                return 0
+
+            self.ami.registerEvent('TestEvent', self.retrieve_endpoint_and_fail)
+
+            self.retrieve_endpoint()
+
+            return 0
+
+        message = {
+            'Action': 'SorceryMemoryCacheStaleObject',
+            'Cache': CACHE,
+            'Object': ENDPOINT,
+        }
+        self.ami.sendMessage(message, responseCallback=_object_marked_as_stale)
+
+    def endpoint_detail_complete_callback(self, ami, event):
+        self.endpoint_retrieved += int(event.get('listitems'))
+
+        if self.endpoint_retrieved == 1:
+             self.rt_data.delete_rows('endpoint', { 'id': ENDPOINT })
+             self.stale_cache_object()
+        elif self.endpoint_retrieved == 3:
+             self.fail_test()
+
+def check_it(rt_data, test_object, ami):
+    test = MemoryCacheStaleObjectTest(rt_data, test_object, ami)
+
+    ami.registerEvent('EndpointDetailComplete', test.endpoint_detail_complete_callback)
+
+    test.retrieve_endpoint()
diff --git a/tests/sorcery/memory_cache_stale_object/test-config.yaml b/tests/sorcery/memory_cache_stale_object/test-config.yaml
new file mode 100644
index 0000000..d1743f8
--- /dev/null
+++ b/tests/sorcery/memory_cache_stale_object/test-config.yaml
@@ -0,0 +1,51 @@
+testinfo:
+    summary:     'Sorcery Memory Cache AMI SorceryMemoryCacheStaleObject Test'
+    description: |
+        'This tests that the SorceryMemoryCacheStaleObject AMI action successfully marks an
+         object as stale and refreshes it upon the next retrieval. The test works by
+         doing the following:
+         1. PJSIP endpoints are configured with a memory cache and realtime.
+         2. A PJSIP endpoint is defined in realtime at the start of the test.
+         3. The PJSIPShowEndpoint AMI action is invoked which populates the memory cache.
+         4. The PJSIP endpoint is removed from realtime.
+         5. The SorceryMemoryCacheStaleObject AMI action is invoked on the memory cache.
+         6. The PJSIPShowEndpoint AMI action is invoked to force a refresh of the object.
+         7. The test waits for 5 seconds for the fresh to occur.
+         6. The PJSIPShowEndpoint AMI action is invoked to confirm the endpoint
+            CAN NOT be retrieved as it should not exist in realtime or the cache.'
+
+
+properties:
+    minversion: '14.0.0'
+    dependencies:
+        - python: 'twisted'
+        - python: 'starpy'
+        - asterisk: 'res_pjsip'
+        - asterisk: 'res_config_curl'
+        - asterisk: 'func_curl'
+        - asterisk: 'res_sorcery_realtime'
+        - asterisk: 'res_sorcery_memory_cache'
+    tags:
+        - realtime
+        - pjsip
+
+test-modules:
+    add-test-to-search-path: 'True'
+    test-object:
+        config-section: test-case-config
+        typename: 'test_case.TestCaseModule'
+    modules:
+        -
+            config-section: 'realtime-config'
+            typename: 'realtime_test_module.RealtimeTestModule'
+
+test-case-config:
+    connect-ami: 'True'
+
+realtime-config:
+    entry_module: 'memory_cache_stale_object'
+    entry_method: 'check_it'
+    data:
+        endpoint:
+            -
+                id: 'test'
diff --git a/tests/sorcery/tests.yaml b/tests/sorcery/tests.yaml
new file mode 100644
index 0000000..6a44f51
--- /dev/null
+++ b/tests/sorcery/tests.yaml
@@ -0,0 +1,5 @@
+tests:
+    - test: 'memory_cache_expire'
+    - test: 'memory_cache_expire_object'
+    - test: 'memory_cache_stale'
+    - test: 'memory_cache_stale_object'
diff --git a/tests/tests.yaml b/tests/tests.yaml
index 52b63aa..1a92254 100644
--- a/tests/tests.yaml
+++ b/tests/tests.yaml
@@ -33,3 +33,5 @@
     - dir: 'hep'
     - dir: 'realtime'
     - dir: 'http_server'
+    - dir: 'sorcery'
+

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

Gerrit-MessageType: merged
Gerrit-Change-Id: I8fc051a92f52ae4e8e064333138157f28fabfa5f
Gerrit-PatchSet: 2
Gerrit-Project: testsuite
Gerrit-Branch: master
Gerrit-Owner: Joshua Colp <jcolp at digium.com>
Gerrit-Reviewer: Joshua Colp <jcolp at digium.com>
Gerrit-Reviewer: Kevin Harwell <kharwell at digium.com>
Gerrit-Reviewer: Mark Michelson <mmichelson at digium.com>
Gerrit-Reviewer: Samuel Galarneau <sgalarneau at digium.com>



More information about the asterisk-code-review mailing list