diff --git a/v2/ansible/plugins/cache/base.py b/v2/ansible/plugins/cache/base.py
index 6ff3d5ed1e..051f02d0b0 100644
--- a/v2/ansible/plugins/cache/base.py
+++ b/v2/ansible/plugins/cache/base.py
@@ -14,30 +14,42 @@
#
# You should have received a copy of the GNU General Public License
# along with Ansible. If not, see .
+
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
-import exceptions
+from abc import ABCMeta, abstractmethod
-class BaseCacheModule(object):
+from six import add_metaclass
+
+@add_metaclass(ABCMeta)
+class BaseCacheModule:
+
+ @abstractmethod
def get(self, key):
- raise exceptions.NotImplementedError
+ pass
+ @abstractmethod
def set(self, key, value):
- raise exceptions.NotImplementedError
+ pass
+ @abstractmethod
def keys(self):
- raise exceptions.NotImplementedError
+ pass
+ @abstractmethod
def contains(self, key):
- raise exceptions.NotImplementedError
+ pass
+ @abstractmethod
def delete(self, key):
- raise exceptions.NotImplementedError
+ pass
+ @abstractmethod
def flush(self):
- raise exceptions.NotImplementedError
+ pass
+ @abstractmethod
def copy(self):
- raise exceptions.NotImplementedError
+ pass
diff --git a/v2/test-requirements.txt b/v2/test-requirements.txt
index ca5bcae0d9..100bdd01a0 100644
--- a/v2/test-requirements.txt
+++ b/v2/test-requirements.txt
@@ -5,6 +5,8 @@ jinja2
httplib2
passlib
six
+python-memcached
+redis
# Test requirements
unittest2
diff --git a/v2/test/plugins/test_cache.py b/v2/test/plugins/test_cache.py
new file mode 100644
index 0000000000..b1273874cd
--- /dev/null
+++ b/v2/test/plugins/test_cache.py
@@ -0,0 +1,82 @@
+# (c) 2012-2015, Michael DeHaan
+#
+# This file is part of Ansible
+#
+# Ansible is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# Ansible is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with Ansible. If not, see .
+
+# Make coding more python3-ish
+from __future__ import (absolute_import, division, print_function)
+__metaclass__ = type
+
+from ansible.compat.tests import unittest
+from ansible.plugins.cache.base import BaseCacheModule
+from ansible.plugins.cache.memcached import CacheModule as MemcachedCache
+from ansible.plugins.cache.memory import CacheModule as MemoryCache
+from ansible.plugins.cache.redis import CacheModule as RedisCache
+
+
+class TestAbstractClass(unittest.TestCase):
+
+ def setUp(self):
+ pass
+
+ def tearDown(self):
+ pass
+
+ def test_subclass_error(self):
+ class CacheModule1(BaseCacheModule):
+ pass
+ with self.assertRaises(TypeError):
+ CacheModule1()
+
+ class CacheModule2(BaseCacheModule):
+ def get(self, key):
+ super(CacheModule2, self).get(key)
+
+ with self.assertRaises(TypeError):
+ CacheModule2()
+
+ def test_subclass_success(self):
+ class CacheModule3(BaseCacheModule):
+ def get(self, key):
+ super(CacheModule3, self).get(key)
+
+ def set(self, key, value):
+ super(CacheModule3, self).set(key, value)
+
+ def keys(self):
+ super(CacheModule3, self).keys()
+
+ def contains(self, key):
+ super(CacheModule3, self).contains(key)
+
+ def delete(self, key):
+ super(CacheModule3, self).delete(key)
+
+ def flush(self):
+ super(CacheModule3, self).flush()
+
+ def copy(self):
+ super(CacheModule3, self).copy()
+
+ self.assertIsInstance(CacheModule3(), CacheModule3)
+
+ def test_memcached_cachemodule(self):
+ self.assertIsInstance(MemcachedCache(), MemcachedCache)
+
+ def test_memory_cachemodule(self):
+ self.assertIsInstance(MemoryCache(), MemoryCache)
+
+ def test_redis_cachemodule(self):
+ self.assertIsInstance(RedisCache(), RedisCache)