Back to index

moin  1.9.0~rc2
test_cache.py
Go to the documentation of this file.
00001 # -*- coding: iso-8859-1 -*-
00002 """
00003     MoinMoin - tests of cache action functions
00004 
00005     @copyright: 2008 MoinMoin:ThomasWaldmann
00006     @license: GNU GPL, see COPYING for details.
00007 """
00008 
00009 import os, StringIO
00010 
00011 from MoinMoin import caching
00012 from MoinMoin.action import AttachFile, cache
00013 
00014 from MoinMoin._tests import become_trusted, create_page, nuke_page
00015 
00016 class TestSendCached:
00017     """ testing action cache """
00018     pagename = u"AutoCreatedSillyPageToTestAttachments"
00019 
00020     def test_cache_key_content(self):
00021         request = self.request
00022         result1 = cache.key(request, content='foo', secret='bar')
00023         result2 = cache.key(request, content='foo', secret='baz')
00024         assert result1  # not empty
00025         assert result1 != result2  # different for different secret
00026         result3 = cache.key(request, content='foofoo', secret='baz')
00027         assert result3 != result2  # different for different content
00028         result4 = cache.key(request, content='foo'*1000, secret='baz')
00029         assert len(result4) == len(result3)  # same length of key for different input lengths
00030 
00031     def test_cache_key_attachment(self):
00032         request = self.request
00033         pagename = self.pagename
00034         attachname = 'foo.txt'
00035 
00036         become_trusted(request)
00037         create_page(request, pagename, u"Foo!")
00038 
00039         AttachFile.add_attachment(request, pagename, attachname, "Test content1", True)
00040 
00041         result1 = cache.key(request, itemname=pagename, attachname=attachname, secret='bar')
00042         result2 = cache.key(request, itemname=pagename, attachname=attachname, secret='baz')
00043         assert result1  # not empty
00044         assert result1 != result2  # different for different secret
00045 
00046         # test below does not work, because mtime is often same, inode can be same due to how add_attachment
00047         # works, file size is same, attachment name is same, wikiname/pagename is same.
00048         # In practice, this should rather rarely cause problems:
00049         #AttachFile.add_attachment(request, pagename, attachname, "Test content2", True)
00050         #result3 = cache.key(request, itemname=pagename, attachname=attachname, secret='baz')
00051         #assert result3 != result2  # different for different content
00052 
00053         AttachFile.add_attachment(request, pagename, attachname, "Test content33333", True)
00054         result4 = cache.key(request, itemname=pagename, attachname=attachname, secret='baz')
00055         assert len(result4) == len(result2)  # same length of key for different input lengths
00056         nuke_page(request, pagename)
00057 
00058     def test_put_cache_minimal(self):
00059         """Test if put_cache() works"""
00060         request = self.request
00061         key = 'nooneknowsit'
00062         data = "dontcare"
00063         cache.put(request, key, data)
00064         url = cache.url(request, key)
00065 
00066         assert key in url
00067         meta_cache = caching.CacheEntry(request,
00068                                         arena=cache.cache_arena,
00069                                         scope=cache.cache_scope,
00070                                         key=key+'.meta', use_pickle=True)
00071         meta = meta_cache.content()
00072         assert meta['httpdate_last_modified'].endswith(' GMT') # only a very rough check, it has used cache mtime as last_modified
00073         assert ("Content-Type", "application/octet-stream") in meta['headers']
00074         assert ("Content-Length", len(data)) in meta['headers']
00075 
00076     def test_put_cache_guess_ct_give_lm(self):
00077         """Test if put_cache() works, when we give filename (so it guesses content_type) and last_modified"""
00078         request = self.request
00079         key = 'nooneknowsit'
00080         filename = "test.png"
00081         data = "dontcare"
00082         cache.put(request, key, data, filename=filename, last_modified=1)
00083         url = cache.url(request, key)
00084         assert key in url
00085 
00086         meta_cache = caching.CacheEntry(request,
00087                                         arena=cache.cache_arena,
00088                                         scope=cache.cache_scope,
00089                                         key=key+'.meta', use_pickle=True)
00090         meta = meta_cache.content()
00091         assert meta['httpdate_last_modified'] == 'Thu, 01 Jan 1970 00:00:01 GMT'
00092         assert ("Content-Type", "image/png") in meta['headers']
00093         assert ("Content-Length", len(data)) in meta['headers']
00094 
00095     def test_put_cache_file_like_data(self):
00096         """Test if put_cache() works when we give it a file like object for the content"""
00097         request = self.request
00098         key = 'nooneknowsit'
00099         filename = "test.png"
00100         data = "dontcareatall"
00101         data_file = StringIO.StringIO(data)
00102         cache.put(request, key, data_file)
00103         url = cache.url(request, key)
00104 
00105         assert key in url
00106         meta_cache = caching.CacheEntry(request,
00107                                         arena=cache.cache_arena,
00108                                         scope=cache.cache_scope,
00109                                         key=key+'.meta', use_pickle=True)
00110         meta = meta_cache.content()
00111         assert meta['httpdate_last_modified'].endswith(' GMT') # only a very rough check, it has used cache mtime as last_modified
00112         assert ("Content-Type", "application/octet-stream") in meta['headers']
00113         assert ("Content-Length", len(data)) in meta['headers']
00114 
00115         data_cache = caching.CacheEntry(request,
00116                                         arena=cache.cache_arena,
00117                                         scope=cache.cache_scope,
00118                                         key=key+'.data')
00119         cached = data_cache.content()
00120         assert data == cached
00121 
00122     def test_put_cache_complex(self):
00123         """Test if put_cache() works for a more complex, practical scenario:
00124 
00125            As 'source' we just use some random integer as count value.
00126 
00127            The 'rendered representation' of it is just the word "spam" repeated
00128            count times, which we cache.
00129 
00130            The cache key calculation (for the 'non-guessable' keys) is also
00131            rather simple.
00132 
00133            In real world, source would be likely some big image, rendered
00134            representation of it a thumbnail / preview of it. Or some LaTeX
00135            source and its rendered representation as png image.
00136            Key calculation could be some MAC or some other hard to guess and
00137            unique string.
00138         """
00139         import random
00140         request = self.request
00141         render = lambda data: "spam" * data
00142         secret = 4223
00143         keycalc = lambda data: str(data * secret)
00144 
00145         source = random.randint(1, 100)
00146         rendered1 = render(source)
00147         key1 = keycalc(source)
00148 
00149         cache.put(request, key1, rendered1)
00150         url1 = cache.url(request, key1)
00151         assert 'key=%s' % key1 in url1
00152 
00153         data_cache = caching.CacheEntry(request,
00154                                         arena=cache.cache_arena,
00155                                         scope=cache.cache_scope,
00156                                         key=key1+'.data')
00157         cached1 = data_cache.content()
00158 
00159         assert render(source) == cached1
00160         # if that succeeds, we have stored the rendered representation of source in the cache under key1
00161 
00162         # now we use some different source, render it and store it in the cache
00163         source = source * 2
00164         rendered2 = render(source)
00165         key2 = keycalc(source)
00166 
00167         cache.put(request, key2, rendered2)
00168         url2 = cache.url(request, key2)
00169         assert 'key=%s' % key2 in url2
00170 
00171         data_cache = caching.CacheEntry(request,
00172                                         arena=cache.cache_arena,
00173                                         scope=cache.cache_scope,
00174                                         key=key2+'.data')
00175         cached2 = data_cache.content()
00176 
00177         assert render(source) == cached2
00178         # if that succeeds, we have stored the rendered representation of updated source in the cache under key2
00179 
00180         assert url2 != url1  # URLs must be different for different source (implies different keys)
00181 
00182 
00183 coverage_modules = ['MoinMoin.action.cache']
00184