| from mako.template import Template |
| from mako.lookup import TemplateLookup |
| from mako import lookup |
| import shutil, unittest, os, time |
| from test.util import result_lines |
| from test import TemplateTest, template_base, module_base |
| from test import eq_ |
| |
| try: |
| import beaker |
| import beaker.cache |
| except: |
| from nose import SkipTest |
| raise SkipTest("Beaker is required for these tests.") |
| |
| from mako.cache import register_plugin, CacheImpl |
| |
| class MockCacheImpl(CacheImpl): |
| realcacheimpl = None |
| |
| def __init__(self, cache): |
| self.cache = cache |
| use_beaker = self.cache.\ |
| template.cache_args.\ |
| get('use_beaker', True) |
| if use_beaker: |
| self.realcacheimpl = cache._load_impl("beaker") |
| |
| def get_or_create(self, key, creation_function, **kw): |
| self.key = key |
| self.kwargs = kw.copy() |
| if self.realcacheimpl: |
| return self.realcacheimpl.\ |
| get_or_create(key, creation_function, **kw) |
| else: |
| return creation_function() |
| |
| def put(self, key, value, **kw): |
| self.key = key |
| self.kwargs = kw.copy() |
| if self.realcacheimpl: |
| self.realcacheimpl.put(key, value, **kw) |
| |
| def get(self, key, **kw): |
| self.key = key |
| self.kwargs = kw.copy() |
| if self.realcacheimpl: |
| return self.realcacheimpl.get(key, **kw) |
| |
| def invalidate(self, key, **kw): |
| self.key = key |
| self.kwargs = kw.copy() |
| if self.realcacheimpl: |
| self.realcacheimpl.invalidate(key, **kw) |
| |
| |
| register_plugin("mock", __name__, "MockCacheImpl") |
| |
| class BeakerCacheTest(TemplateTest): |
| def _regions(self): |
| return beaker.cache.CacheManager( |
| cache_regions = { |
| 'short':{ |
| 'expire':1, |
| 'type':'memory' |
| }, |
| 'long':{ |
| 'expire':60, |
| 'type':'memory' |
| } |
| } |
| ) |
| |
| def test_region(self): |
| t = Template(""" |
| <%block name="foo" cached="True" cache_region="short"> |
| short term ${x} |
| </%block> |
| <%block name="bar" cached="True" cache_region="long"> |
| long term ${x} |
| </%block> |
| <%block name="lala"> |
| none ${x} |
| </%block> |
| """, cache_args={"manager":self._regions()}) |
| |
| r1 = result_lines(t.render(x=5)) |
| time.sleep(2) |
| r2 = result_lines(t.render(x=6)) |
| r3 = result_lines(t.render(x=7)) |
| eq_(r1, ["short term 5", "long term 5", "none 5"]) |
| eq_(r2, ["short term 6", "long term 5", "none 6"]) |
| eq_(r3, ["short term 6", "long term 5", "none 7"]) |
| |
| class CacheTest(TemplateTest): |
| def _install_mock_cache(self, template): |
| template.cache_impl = 'mock' |
| return template.cache.impl |
| |
| 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) |
| |
| eq_(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_context(self): |
| t = Template(""" |
| <%block name="foo" cached="True" cache_key="${mykey}"> |
| some block |
| </%block> |
| """) |
| m = self._install_mock_cache(t) |
| t.render(mykey="thekey") |
| t.render(mykey="thekey") |
| eq_( |
| result_lines(t.render(mykey="thekey")), |
| ["some block"] |
| ) |
| eq_(m.key, "thekey") |
| |
| t = Template(""" |
| <%def name="foo()" cached="True" cache_key="${mykey}"> |
| some def |
| </%def> |
| ${foo()} |
| """) |
| m = self._install_mock_cache(t) |
| t.render(mykey="thekey") |
| t.render(mykey="thekey") |
| eq_( |
| result_lines(t.render(mykey="thekey")), |
| ["some def"] |
| ) |
| eq_(m.key, "thekey") |
| |
| |
| 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=module_base) |
| 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]', |
| ] |
| eq_(m.kwargs, {'type':'dbm'}) |
| |
| def test_fileargs_deftag(self): |
| t = Template(""" |
| <%%! |
| callcount = [0] |
| %%> |
| <%%def name="foo()" cached="True" cache_type='file' cache_dir='%s'> |
| this is foo |
| <%% |
| callcount[0] += 1 |
| %%> |
| </%%def> |
| |
| ${foo()} |
| ${foo()} |
| ${foo()} |
| callcount: ${callcount} |
| """ % module_base) |
| 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','dir':module_base} |
| |
| def test_fileargs_pagetag(self): |
| t = Template(""" |
| <%%page cache_dir='%s' cache_type='dbm'/> |
| <%%! |
| callcount = [0] |
| %%> |
| <%%def name="foo()" cached="True"> |
| this is foo |
| <%% |
| callcount[0] += 1 |
| %%> |
| </%%def> |
| |
| ${foo()} |
| ${foo()} |
| ${foo()} |
| callcount: ${callcount} |
| """ % module_base) |
| m = self._install_mock_cache(t) |
| assert result_lines(t.render()) == [ |
| 'this is foo', |
| 'this is foo', |
| 'this is foo', |
| 'callcount: [1]', |
| ] |
| eq_(m.kwargs, {'dir':module_base, 'type':'dbm'}) |
| |
| def test_args_complete(self): |
| t = Template(""" |
| <%%def name="foo()" cached="True" cache_timeout="30" cache_dir="%s" cache_type="file" cache_key='somekey'> |
| this is foo |
| </%%def> |
| |
| ${foo()} |
| """ % module_base) |
| m = self._install_mock_cache(t) |
| t.render() |
| eq_(m.kwargs, {'dir':module_base, 'type':'file', 'timeout':30}) |
| |
| t2 = Template(""" |
| <%%page cached="True" cache_timeout="30" cache_dir="%s" cache_type="file" cache_key='somekey'/> |
| hi |
| """ % module_base) |
| m = self._install_mock_cache(t2) |
| t2.render() |
| eq_(m.kwargs, {'dir':module_base, 'type':'file', 'timeout':30}) |
| |
| def test_fileargs_lookup(self): |
| l = lookup.TemplateLookup(cache_dir=module_base, 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]', |
| ] |
| eq_(m.kwargs, {'dir':module_base, '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> |
| """) |
| |
| 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> |
| """) |
| |
| x1 = t.render(x=1) |
| time.sleep(3) |
| x2 = t.render(x=2) |
| eq_(x1.strip(), "foo: 1") |
| eq_(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_lookup(self): |
| l = TemplateLookup(cache_impl='mock') |
| l.put_string("x", """ |
| <%page cached="True" /> |
| ${y} |
| """) |
| t = l.get_template("x") |
| assert result_lines(t.render(y=5)) == ["5"] |
| assert result_lines(t.render(y=7)) == ["5"] |
| assert isinstance(t.cache.impl, MockCacheImpl) |
| |
| def test_invalidate(self): |
| t = Template(""" |
| <%%def name="foo()" cached="True"> |
| foo: ${x} |
| </%%def> |
| |
| <%%def name="bar()" cached="True" cache_type='dbm' cache_dir='%s'> |
| bar: ${x} |
| </%%def> |
| ${foo()} ${bar()} |
| """ % module_base) |
| 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="%s"/> |
| |
| page: ${x} |
| """ % module_base) |
| 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 test_custom_args_def(self): |
| t = Template(""" |
| <%def name="foo()" cached="True" cache_region="myregion" |
| cache_timeout="50" cache_foo="foob"> |
| </%def> |
| ${foo()} |
| """, cache_args={'use_beaker':False}) |
| m = self._install_mock_cache(t) |
| t.render() |
| eq_(m.kwargs, {'use_beaker':False,'region':'myregion', 'timeout':50, 'foo':'foob'}) |
| |
| def test_custom_args_block(self): |
| t = Template(""" |
| <%block name="foo" cached="True" cache_region="myregion" |
| cache_timeout="50" cache_foo="foob"> |
| </%block> |
| """, cache_args={'use_beaker':False}) |
| m = self._install_mock_cache(t) |
| t.render() |
| eq_(m.kwargs, {'use_beaker':False, 'region':'myregion', 'timeout':50, 'foo':'foob'}) |
| |
| def test_custom_args_page(self): |
| t = Template(""" |
| <%page cached="True" cache_region="myregion" |
| cache_timeout="50" cache_foo="foob"/> |
| """, cache_args={'use_beaker':False}) |
| m = self._install_mock_cache(t) |
| t.render() |
| eq_(m.kwargs, {'use_beaker':False, 'region':'myregion', 'timeout':50, 'foo':'foob'}) |
| |
| def test_pass_context(self): |
| t = Template(""" |
| <%page cached="True"/> |
| """) |
| m = self._install_mock_cache(t) |
| t.render() |
| assert 'context' not in m.kwargs |
| |
| m.pass_context = True |
| t.render(x="bar") |
| assert 'context' in m.kwargs |
| assert m.kwargs['context'].get('x') == 'bar' |
| |