salt/tests/unit/cache/test_cache.py
2018-08-14 13:53:29 -05:00

220 lines
8.7 KiB
Python

# -*- coding: utf-8 -*-
'''
unit tests for salt.cache
'''
# Import Python libs
from __future__ import absolute_import, print_function, unicode_literals
# Import Salt Testing libs
# import integration
from tests.support.unit import skipIf, TestCase
from tests.support.mock import (
NO_MOCK,
NO_MOCK_REASON,
patch,
)
# Import Salt libs
import salt.payload
import salt.cache
class CacheFunctionsTest(TestCase):
'''
Validate the cache package functions.
'''
def setUp(self):
self.opts = {'cache': 'localfs',
'memcache_expire_seconds': 0,
'memcache_max_items': 0,
'memcache_full_cleanup': False,
'memcache_debug': False}
def test_factory_cache(self):
ret = salt.cache.factory(self.opts)
self.assertIsInstance(ret, salt.cache.Cache)
def test_factory_memcache(self):
self.opts['memcache_expire_seconds'] = 10
ret = salt.cache.factory(self.opts)
self.assertIsInstance(ret, salt.cache.MemCache)
@skipIf(NO_MOCK, NO_MOCK_REASON)
class MemCacheTest(TestCase):
'''
Validate Cache class methods
'''
@patch('salt.payload.Serial')
def setUp(self, serial_mock): # pylint: disable=W0221
salt.cache.MemCache.data = {}
self.opts = {'cache': 'fake_driver',
'memcache_expire_seconds': 10,
'memcache_max_items': 3,
'memcache_full_cleanup': False,
'memcache_debug': False}
self.cache = salt.cache.factory(self.opts)
@patch('salt.cache.Cache.fetch', return_value='fake_data')
@patch('salt.loader.cache', return_value={})
def test_fetch(self, loader_mock, cache_fetch_mock):
# Fetch value, it will be kept in cache.
with patch('time.time', return_value=0):
ret = self.cache.fetch('bank', 'key')
self.assertEqual(ret, 'fake_data')
self.assertDictEqual(salt.cache.MemCache.data, {
'fake_driver': {
('bank', 'key'): [0, 'fake_data'],
}})
cache_fetch_mock.assert_called_once_with('bank', 'key')
cache_fetch_mock.reset_mock()
# Fetch again, cached value is used, time updated.
with patch('time.time', return_value=1):
ret = self.cache.fetch('bank', 'key')
self.assertEqual(ret, 'fake_data')
self.assertDictEqual(salt.cache.MemCache.data, {
'fake_driver': {
('bank', 'key'): [1, 'fake_data'],
}})
cache_fetch_mock.assert_not_called()
# Fetch after expire
with patch('time.time', return_value=12):
ret = self.cache.fetch('bank', 'key')
self.assertEqual(ret, 'fake_data')
self.assertDictEqual(salt.cache.MemCache.data, {
'fake_driver': {
('bank', 'key'): [12, 'fake_data'],
}})
cache_fetch_mock.assert_called_once_with('bank', 'key')
cache_fetch_mock.reset_mock()
@patch('salt.cache.Cache.store')
@patch('salt.loader.cache', return_value={})
def test_store(self, loader_mock, cache_store_mock):
# Fetch value, it will be kept in cache.
with patch('time.time', return_value=0):
self.cache.store('bank', 'key', 'fake_data')
self.assertDictEqual(salt.cache.MemCache.data, {
'fake_driver': {
('bank', 'key'): [0, 'fake_data'],
}})
cache_store_mock.assert_called_once_with('bank', 'key', 'fake_data')
cache_store_mock.reset_mock()
# Store another value.
with patch('time.time', return_value=1):
self.cache.store('bank', 'key2', 'fake_data2')
self.assertDictEqual(salt.cache.MemCache.data, {
'fake_driver': {
('bank', 'key'): [0, 'fake_data'],
('bank', 'key2'): [1, 'fake_data2'],
}})
cache_store_mock.assert_called_once_with('bank', 'key2', 'fake_data2')
@patch('salt.cache.Cache.store')
@patch('salt.cache.Cache.flush')
@patch('salt.loader.cache', return_value={})
def test_flush(self, loader_mock, cache_flush_mock, cache_store_mock):
# Flush non-existing bank
self.cache.flush('bank')
self.assertDictEqual(salt.cache.MemCache.data, {'fake_driver': {}})
cache_flush_mock.assert_called_once_with('bank', None)
cache_flush_mock.reset_mock()
# Flush non-existing key
self.cache.flush('bank', 'key')
self.assertDictEqual(salt.cache.MemCache.data, {'fake_driver': {}})
cache_flush_mock.assert_called_once_with('bank', 'key')
cache_flush_mock.reset_mock()
# Flush existing key
with patch('time.time', return_value=0):
self.cache.store('bank', 'key', 'fake_data')
self.assertEqual(salt.cache.MemCache.data['fake_driver'][('bank', 'key')],
[0, 'fake_data'])
self.assertDictEqual(salt.cache.MemCache.data, {
'fake_driver': {
('bank', 'key'): [0, 'fake_data'],
}})
self.cache.flush('bank', 'key')
self.assertDictEqual(salt.cache.MemCache.data, {'fake_driver': {}})
cache_flush_mock.assert_called_once_with('bank', 'key')
cache_flush_mock.reset_mock()
@patch('salt.cache.Cache.store')
@patch('salt.loader.cache', return_value={})
def test_max_items(self, loader_mock, cache_store_mock):
# Put MAX=3 values
with patch('time.time', return_value=0):
self.cache.store('bank1', 'key1', 'fake_data11')
with patch('time.time', return_value=1):
self.cache.store('bank1', 'key2', 'fake_data12')
with patch('time.time', return_value=2):
self.cache.store('bank2', 'key1', 'fake_data21')
self.assertDictEqual(salt.cache.MemCache.data['fake_driver'], {
('bank1', 'key1'): [0, 'fake_data11'],
('bank1', 'key2'): [1, 'fake_data12'],
('bank2', 'key1'): [2, 'fake_data21'],
})
# Put one more and check the oldest was removed
with patch('time.time', return_value=3):
self.cache.store('bank2', 'key2', 'fake_data22')
self.assertDictEqual(salt.cache.MemCache.data['fake_driver'], {
('bank1', 'key2'): [1, 'fake_data12'],
('bank2', 'key1'): [2, 'fake_data21'],
('bank2', 'key2'): [3, 'fake_data22'],
})
@patch('salt.cache.Cache.store')
@patch('salt.loader.cache', return_value={})
def test_full_cleanup(self, loader_mock, cache_store_mock):
# Enable full cleanup
self.cache.cleanup = True
# Put MAX=3 values
with patch('time.time', return_value=0):
self.cache.store('bank1', 'key1', 'fake_data11')
with patch('time.time', return_value=1):
self.cache.store('bank1', 'key2', 'fake_data12')
with patch('time.time', return_value=2):
self.cache.store('bank2', 'key1', 'fake_data21')
self.assertDictEqual(salt.cache.MemCache.data['fake_driver'], {
('bank1', 'key1'): [0, 'fake_data11'],
('bank1', 'key2'): [1, 'fake_data12'],
('bank2', 'key1'): [2, 'fake_data21'],
})
# Put one more and check all expired was removed
with patch('time.time', return_value=12):
self.cache.store('bank2', 'key2', 'fake_data22')
self.assertDictEqual(salt.cache.MemCache.data['fake_driver'], {
('bank2', 'key1'): [2, 'fake_data21'],
('bank2', 'key2'): [12, 'fake_data22'],
})
@patch('salt.cache.Cache.fetch', return_value='fake_data')
@patch('salt.loader.cache', return_value={})
def test_fetch_debug(self, loader_mock, cache_fetch_mock):
# Recreate cache with debug enabled
self.opts['memcache_debug'] = True
self.cache = salt.cache.factory(self.opts)
# Fetch 2 values (no cache hit)
with patch('time.time', return_value=0):
ret = self.cache.fetch('bank', 'key1')
with patch('time.time', return_value=1):
ret = self.cache.fetch('bank', 'key2')
# Fetch 3 times (cache hit)
with patch('time.time', return_value=2):
ret = self.cache.fetch('bank', 'key2')
with patch('time.time', return_value=3):
ret = self.cache.fetch('bank', 'key1')
with patch('time.time', return_value=4):
ret = self.cache.fetch('bank', 'key1')
# Fetch an expired value (no cache hit)
with patch('time.time', return_value=13):
ret = self.cache.fetch('bank', 'key2')
# Check debug data
self.assertEqual(self.cache.call, 6)
self.assertEqual(self.cache.hit, 3)