Newer
Older
from mako.lookup import TemplateLookup
Mike Bayer
committed
from mako import lookup
import shutil, unittest, os, time
Mike Bayer
committed
from test import TemplateTest, template_base, module_base
Mike Bayer
committed
try:
import beaker
Mike Bayer
committed
except:
from nose import SkipTest
raise SkipTest("Beaker is required for these tests.")
from mako.cache import register_plugin, CacheImpl
class MockCacheImpl(CacheImpl):
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()
return self.realcacheimpl.\
get_or_create(key, creation_function, **kw)
else:
return creation_function()
def put(self, key, value, **kw):
Mike Bayer
committed
self.key = key
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")
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
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"])
Mike Bayer
committed
class CacheTest(TemplateTest):
def _install_mock_cache(self, template):
template.cache_impl = 'mock'
return template.cache.impl
t = Template("""
<%!
callcount = [0]
%>
<%def name="foo()" cached="True">
this is foo
<%
callcount[0] += 1
%>
</%def>
${foo()}
${foo()}
${foo()}
callcount: ${callcount}
""")
Mike Bayer
committed
m = self._install_mock_cache(t)
assert result_lines(t.render()) == [
'this is foo',
'this is foo',
'this is foo',
'callcount: [1]',
]
Mike Bayer
committed
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]")
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
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}
""")
Mike Bayer
committed
m = self._install_mock_cache(t)
t.render()
t.render()
assert result_lines(t.render()) == [
"this is foo",
"callcount: [1]"
]
Mike Bayer
committed
assert m.kwargs == {}
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
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")
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
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 == {}
Mike Bayer
committed
def test_fileargs_implicit(self):
Mike Bayer
committed
l = lookup.TemplateLookup(module_directory=module_base)
Mike Bayer
committed
l.put_string("test","""
<%!
callcount = [0]
%>
<%def name="foo()" cached="True" cache_type='dbm'>
Mike Bayer
committed
this is foo
<%
callcount[0] += 1
%>
</%def>
Mike Bayer
committed
${foo()}
${foo()}
${foo()}
callcount: ${callcount}
""")
Mike Bayer
committed
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'})
Mike Bayer
committed
def test_fileargs_deftag(self):
t = Template("""
Mike Bayer
committed
<%%!
Mike Bayer
committed
callcount = [0]
Mike Bayer
committed
%%>
<%%def name="foo()" cached="True" cache_type='file' cache_dir='%s'>
Mike Bayer
committed
this is foo
Mike Bayer
committed
<%%
Mike Bayer
committed
callcount[0] += 1
Mike Bayer
committed
%%>
</%%def>
Mike Bayer
committed
${foo()}
${foo()}
${foo()}
callcount: ${callcount}
Mike Bayer
committed
""" % module_base)
Mike Bayer
committed
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}
Mike Bayer
committed
def test_fileargs_pagetag(self):
t = Template("""
Mike Bayer
committed
<%%page cache_dir='%s' cache_type='dbm'/>
<%%!
Mike Bayer
committed
callcount = [0]
Mike Bayer
committed
%%>
<%%def name="foo()" cached="True">
Mike Bayer
committed
this is foo
Mike Bayer
committed
<%%
Mike Bayer
committed
callcount[0] += 1
Mike Bayer
committed
%%>
</%%def>
Mike Bayer
committed
${foo()}
${foo()}
${foo()}
callcount: ${callcount}
Mike Bayer
committed
""" % module_base)
Mike Bayer
committed
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'})
Mike Bayer
committed
def test_args_complete(self):
t = Template("""
Mike Bayer
committed
<%%def name="foo()" cached="True" cache_timeout="30" cache_dir="%s" cache_type="file" cache_key='somekey'>
Mike Bayer
committed
</%%def>
Mike Bayer
committed
""" % module_base)
m = self._install_mock_cache(t)
t.render()
eq_(m.kwargs, {'dir':module_base, 'type':'file', 'timeout':30})
Mike Bayer
committed
<%%page cached="True" cache_timeout="30" cache_dir="%s" cache_type="file" cache_key='somekey'/>
Mike Bayer
committed
""" % module_base)
m = self._install_mock_cache(t2)
t2.render()
eq_(m.kwargs, {'dir':module_base, 'type':'file', 'timeout':30})
Mike Bayer
committed
def test_fileargs_lookup(self):
Mike Bayer
committed
l = lookup.TemplateLookup(cache_dir=module_base, cache_type='file')
Mike Bayer
committed
l.put_string("test","""
<%!
callcount = [0]
%>
<%def name="foo()" cached="True">
Mike Bayer
committed
this is foo
<%
callcount[0] += 1
%>
</%def>
${foo()}
${foo()}
${foo()}
callcount: ${callcount}
""")
Mike Bayer
committed
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("""
Mike Bayer
committed
<%%def name="foo()" cached="True">
Mike Bayer
committed
</%%def>
Mike Bayer
committed
<%%def name="bar()" cached="True" cache_type='dbm' cache_dir='%s'>
Mike Bayer
committed
</%%def>
Mike Bayer
committed
""" % 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"]
Mike Bayer
committed
<%%page cached="True" cache_type="dbm" cache_dir="%s"/>
Mike Bayer
committed
""" % 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'