mirror of
https://github.com/valitydev/salt.git
synced 2024-11-09 01:36:48 +00:00
221 lines
8.6 KiB
Python
221 lines
8.6 KiB
Python
# -*- coding: utf-8 -*-
|
|
'''
|
|
unit tests for the localfs cache
|
|
'''
|
|
|
|
# Import Python libs
|
|
from __future__ import absolute_import
|
|
|
|
# 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.utils
|
|
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)
|