aboutsummaryrefslogtreecommitdiffstats
path: root/test/test_cache.py
diff options
context:
space:
mode:
Diffstat (limited to 'test/test_cache.py')
-rw-r--r--test/test_cache.py405
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