diff options
Diffstat (limited to 'test/test_cache.py')
-rw-r--r-- | test/test_cache.py | 405 |
1 files changed, 405 insertions, 0 deletions
diff --git a/test/test_cache.py b/test/test_cache.py new file mode 100644 index 0000000..ced515e --- /dev/null +++ b/test/test_cache.py @@ -0,0 +1,405 @@ +from mako.template import Template +from mako.lookup import TemplateLookup +from mako import lookup +import shutil, unittest, os +from util import result_lines + +if not os.access('./test_htdocs', os.F_OK): + os.mkdir('./test_htdocs') +for cache_dir in ('container_dbm', 'container_dbm_lock', 'container_file', + 'container_file_lock'): + fullpath = os.path.join('./test_htdocs', cache_dir) + if os.path.exists(fullpath): + shutil.rmtree(fullpath) + +class MockCache(object): + def __init__(self, realcache): + self.realcache = realcache + def get(self, key, **kwargs): + self.key = key + self.kwargs = kwargs.copy() + self.kwargs.pop('createfunc', None) + self.kwargs.pop('defname', None) + return self.realcache.get(key, **kwargs) + +class CacheTest(unittest.TestCase): + def test_def(self): + t = Template(""" + <%! + callcount = [0] + %> + <%def name="foo()" cached="True"> + this is foo + <% + callcount[0] += 1 + %> + </%def> + + ${foo()} + ${foo()} + ${foo()} + callcount: ${callcount} +""") + m = self._install_mock_cache(t) + assert result_lines(t.render()) == [ + 'this is foo', + 'this is foo', + 'this is foo', + 'callcount: [1]', + ] + assert m.kwargs == {} + + def test_cache_enable(self): + t = Template(""" + <%! + callcount = [0] + %> + <%def name="foo()" cached="True"> + <% callcount[0] += 1 %> + </%def> + ${foo()} + ${foo()} + callcount: ${callcount} + """, cache_enabled=False) + m = self._install_mock_cache(t) + + assert t.render().strip() =="callcount: [2]" + + def test_nested_def(self): + t = Template(""" + <%! + callcount = [0] + %> + <%def name="foo()"> + <%def name="bar()" cached="True"> + this is foo + <% + callcount[0] += 1 + %> + </%def> + ${bar()} + </%def> + + ${foo()} + ${foo()} + ${foo()} + callcount: ${callcount} +""") + m = self._install_mock_cache(t) + assert result_lines(t.render()) == [ + 'this is foo', + 'this is foo', + 'this is foo', + 'callcount: [1]', + ] + assert m.kwargs == {} + + def test_page(self): + t = Template(""" + <%! + callcount = [0] + %> + <%page cached="True"/> + this is foo + <% + callcount[0] += 1 + %> + callcount: ${callcount} +""") + m = self._install_mock_cache(t) + t.render() + t.render() + assert result_lines(t.render()) == [ + "this is foo", + "callcount: [1]" + ] + assert m.kwargs == {} + + def test_dynamic_key_with_funcargs(self): + t = Template(""" + <%def name="foo(num=5)" cached="True" cache_key="foo_${str(num)}"> + hi + </%def> + + ${foo()} + """) + m = self._install_mock_cache(t) + t.render() + t.render() + assert result_lines(t.render()) == ['hi'] + assert m.key == "foo_5" + + t = Template(""" + <%def name="foo(*args, **kwargs)" cached="True" cache_key="foo_${kwargs['bar']}"> + hi + </%def> + + ${foo(1, 2, bar='lala')} + """) + m = self._install_mock_cache(t) + t.render() + assert result_lines(t.render()) == ['hi'] + assert m.key == "foo_lala" + + t = Template(''' + <%page args="bar='hi'" cache_key="foo_${bar}" cached="True"/> + hi + ''') + m = self._install_mock_cache(t) + t.render() + assert result_lines(t.render()) == ['hi'] + assert m.key == "foo_hi" + + + def test_dynamic_key_with_imports(self): + lookup = TemplateLookup() + lookup.put_string("foo.html", """ + <%! + callcount = [0] + %> + <%namespace file="ns.html" import="*"/> + <%page cached="True" cache_key="${foo}"/> + this is foo + <% + callcount[0] += 1 + %> + callcount: ${callcount} +""") + lookup.put_string("ns.html", """""") + t = lookup.get_template("foo.html") + m = self._install_mock_cache(t) + t.render(foo='somekey') + t.render(foo='somekey') + assert result_lines(t.render(foo='somekey')) == [ + "this is foo", + "callcount: [1]" + ] + assert m.kwargs == {} + + def test_fileargs_implicit(self): + l = lookup.TemplateLookup(module_directory='./test_htdocs') + l.put_string("test",""" + <%! + callcount = [0] + %> + <%def name="foo()" cached="True" cache_type='dbm'> + this is foo + <% + callcount[0] += 1 + %> + </%def> + + ${foo()} + ${foo()} + ${foo()} + callcount: ${callcount} + """) + + m = self._install_mock_cache(l.get_template('test')) + assert result_lines(l.get_template('test').render()) == [ + 'this is foo', + 'this is foo', + 'this is foo', + 'callcount: [1]', + ] + assert m.kwargs == {'type':'dbm', 'data_dir':'./test_htdocs'} + + def test_fileargs_deftag(self): + t = Template(""" + <%! + callcount = [0] + %> + <%def name="foo()" cached="True" cache_type='file' cache_dir='./test_htdocs'> + this is foo + <% + callcount[0] += 1 + %> + </%def> + + ${foo()} + ${foo()} + ${foo()} + callcount: ${callcount} +""") + m = self._install_mock_cache(t) + assert result_lines(t.render()) == [ + 'this is foo', + 'this is foo', + 'this is foo', + 'callcount: [1]', + ] + assert m.kwargs == {'type':'file','data_dir':'./test_htdocs'} + + def test_fileargs_pagetag(self): + t = Template(""" + <%page cache_dir='./test_htdocs' cache_type='dbm'/> + <%! + callcount = [0] + %> + <%def name="foo()" cached="True"> + this is foo + <% + callcount[0] += 1 + %> + </%def> + + ${foo()} + ${foo()} + ${foo()} + callcount: ${callcount} +""") + m = self._install_mock_cache(t) + assert result_lines(t.render()) == [ + 'this is foo', + 'this is foo', + 'this is foo', + 'callcount: [1]', + ] + assert m.kwargs == {'data_dir':'./test_htdocs', 'type':'dbm'} + + def test_args_complete(self): + t = Template(""" + <%def name="foo()" cached="True" cache_timeout="30" cache_dir="./test_htdocs" cache_type="file" cache_key='somekey'> + this is foo + </%def> + + ${foo()} +""") + m = self._install_mock_cache(t) + t.render() + assert m.kwargs == {'data_dir':'./test_htdocs', 'type':'file', 'expiretime':30} + + t2 = Template(""" + <%page cached="True" cache_timeout="30" cache_dir="./test_htdocs" cache_type="file" cache_key='somekey'/> + hi + """) + m = self._install_mock_cache(t2) + t2.render() + assert m.kwargs == {'data_dir':'./test_htdocs', 'type':'file', 'expiretime':30} + + def test_fileargs_lookup(self): + l = lookup.TemplateLookup(cache_dir='./test_htdocs', cache_type='file') + l.put_string("test",""" + <%! + callcount = [0] + %> + <%def name="foo()" cached="True"> + this is foo + <% + callcount[0] += 1 + %> + </%def> + + ${foo()} + ${foo()} + ${foo()} + callcount: ${callcount} + """) + + t = l.get_template('test') + m = self._install_mock_cache(t) + assert result_lines(l.get_template('test').render()) == [ + 'this is foo', + 'this is foo', + 'this is foo', + 'callcount: [1]', + ] + assert m.kwargs == {'data_dir':'./test_htdocs', 'type':'file'} + + def test_buffered(self): + t = Template(""" + <%! + def a(text): + return "this is a " + text.strip() + %> + ${foo()} + ${foo()} + <%def name="foo()" cached="True" buffered="True"> + this is a test + </%def> + """, buffer_filters=["a"]) + assert result_lines(t.render()) == ["this is a this is a test", "this is a this is a test"] + + def test_load_from_expired(self): + """test that the cache callable can be called safely after the + originating template has completed rendering. + + """ + t = Template(""" + ${foo()} + <%def name="foo()" cached="True" cache_timeout="2"> + foo + </%def> + """) + + import time + x1 = t.render() + time.sleep(3) + x2 = t.render() + assert x1.strip() == x2.strip() == "foo" + + def test_cache_uses_current_context(self): + t = Template(""" + ${foo()} + <%def name="foo()" cached="True" cache_timeout="2"> + foo: ${x} + </%def> + """) + + import time + x1 = t.render(x=1) + time.sleep(3) + x2 = t.render(x=2) + assert x1.strip() == "foo: 1" + assert x2.strip() == "foo: 2" + + def test_namespace_access(self): + t = Template(""" + <%def name="foo(x)" cached="True"> + foo: ${x} + </%def> + + <% + foo(1) + foo(2) + local.cache.invalidate_def('foo') + foo(3) + foo(4) + %> + """) + assert result_lines(t.render()) == ['foo: 1', 'foo: 1', 'foo: 3', 'foo: 3'] + + def test_invalidate(self): + t = Template(""" + <%def name="foo()" cached="True"> + foo: ${x} + </%def> + + <%def name="bar()" cached="True" cache_type='dbm' cache_dir='./test_htdocs'> + bar: ${x} + </%def> + ${foo()} ${bar()} + """) + assert result_lines(t.render(x=1)) == ["foo: 1", "bar: 1"] + assert result_lines(t.render(x=2)) == ["foo: 1", "bar: 1"] + t.cache.invalidate_def('foo') + assert result_lines(t.render(x=3)) == ["foo: 3", "bar: 1"] + t.cache.invalidate_def('bar') + assert result_lines(t.render(x=4)) == ["foo: 3", "bar: 4"] + + t = Template(""" + <%page cached="True" cache_type="dbm" cache_dir="./test_htdocs"/> + + page: ${x} + """) + assert result_lines(t.render(x=1)) == ["page: 1"] + assert result_lines(t.render(x=2)) == ["page: 1"] + t.cache.invalidate_body() + assert result_lines(t.render(x=3)) == ["page: 3"] + assert result_lines(t.render(x=4)) == ["page: 3"] + + + def _install_mock_cache(self, template): + m = MockCache(template.module._template_cache) + template.module._template_cache = m + return m |