Download Install Tutorial Docs FAQ Tools WikiLicense Team IRC Planet Involvement Shop Book

root/branches/cherrypy-3.0.x/cherrypy/test/test_caching.py

Revision 1704 (checked in by fumanchu, 1 year ago)

3.0.2 bugfix: responses were being gzipped twice when served from cache. Needs port to trunk eventually.

  • Property svn:eol-style set to native
Line 
1 from cherrypy.test import test
2 test.prefer_parent_path()
3
4 import gzip
5 import os
6 curdir = os.path.join(os.getcwd(), os.path.dirname(__file__))
7 import StringIO
8
9 import cherrypy
10
11
12 def setup_server():
13    
14     class Root:
15        
16         _cp_config = {'tools.caching.on': True}
17        
18         def __init__(self):
19             cherrypy.counter = 0
20        
21         def index(self):
22             cherrypy.counter += 1
23             msg = "visit #%s" % cherrypy.counter
24             return msg
25         index.exposed = True
26
27     class UnCached(object):
28         _cp_config = {'tools.expires.on': True,
29                       'tools.staticdir.on': True,
30                       'tools.staticdir.dir': 'static',
31                       'tools.staticdir.root': curdir,
32                       }
33
34         def force(self):
35             self._cp_config['tools.expires.force'] = True
36             return "being forceful"
37         force.exposed = True
38
39         def dynamic(self):
40             cherrypy.response.headers['Cache-Control'] = 'private'
41             return "D-d-d-dynamic!"
42         dynamic.exposed = True
43
44         def cacheable(self):
45             cherrypy.response.headers['Etag'] = 'bibbitybobbityboo'
46             return "Hi, I'm cacheable."
47         cacheable.exposed = True
48
49         def specific(self):
50             return "I am being specific"
51         specific.exposed = True
52         specific._cp_config = {'tools.expires.secs': 86400}
53
54         class Foo(object):pass
55        
56         def wrongtype(self):
57             return "Woops"
58         wrongtype.exposed = True
59         wrongtype._cp_config = {'tools.expires.secs': Foo()}
60    
61     cherrypy.tree.mount(Root())
62     cherrypy.tree.mount(UnCached(), "/expires")
63     cherrypy.config.update({'environment': 'test_suite',
64                             'tools.gzip.on': 'True'})
65
66
67 from cherrypy.test import helper
68
69 class CacheTest(helper.CPWebCase):
70
71     def testCaching(self):
72         elapsed = 0.0
73         for trial in xrange(10):
74             self.getPage("/")
75             # The response should be the same every time,
76             # except for the Age response header.
77             self.assertBody('visit #1')
78             if trial != 0:
79                 age = int(self.assertHeader("Age"))
80                 self.assert_(age >= elapsed)
81                 elapsed = age
82        
83         # POST, PUT, DELETE should not be cached.
84         self.getPage("/", method="POST")
85         self.assertBody('visit #2')
86         # The previous request should have invalidated the cache,
87         # so this request will recalc the response.
88         self.getPage("/", method="GET")
89         self.assertBody('visit #3')
90         # ...but this request should get the cached copy.
91         self.getPage("/", method="GET")
92         self.assertBody('visit #3')
93         self.getPage("/", method="DELETE")
94         self.assertBody('visit #4')
95        
96         # The previous request should have invalidated the cache,
97         # so this request will recalc the response.
98         self.getPage("/", method="GET", headers=[('Accept-Encoding', 'gzip')])
99         self.assertHeader('Content-Encoding', 'gzip')
100         self.assertEqual(cherrypy.lib.encoding.decompress(self.body), "visit #5")
101        
102         # Now check that a second request gets the gzip header and gzipped body.
103         # This also tests a bug in 3.0 to 3.0.2 whereby the cached, gzipped
104         # response body was being gzipped a second time.
105         self.getPage("/", method="GET", headers=[('Accept-Encoding', 'gzip')])
106         self.assertHeader('Content-Encoding', 'gzip')
107         self.assertEqual(cherrypy.lib.encoding.decompress(self.body), "visit #5")
108        
109         # Now check that a third request that doesn't accept gzip
110         # skips the cache (because the 'Vary' header denies it).
111         self.getPage("/", method="GET")
112         self.assertNoHeader('Content-Encoding')
113         self.assertBody("visit #6")
114    
115     def testExpiresTool(self):
116        
117         # test setting an expires header
118         self.getPage("/expires/specific")
119         self.assertStatus("200 OK")
120         self.assertHeader("Expires")
121        
122         # test exceptions for bad time values
123         self.getPage("/expires/wrongtype")
124         self.assertStatus(500)
125         self.assertInBody("TypeError")
126        
127         # static content should not have "cache prevention" headers
128         self.getPage("/expires/index.html")
129         self.assertStatus("200 OK")
130         self.assertNoHeader("Pragma")
131         self.assertNoHeader("Cache-Control")
132        
133         # dynamic content that sets indicators should not have
134         # "cache prevention" headers
135         self.getPage("/expires/cacheable")
136         self.assertStatus("200 OK")
137         self.assertNoHeader("Pragma")
138         self.assertNoHeader("Cache-Control")
139        
140         self.getPage('/expires/dynamic')
141         self.assertBody("D-d-d-dynamic!")
142         # the Cache-Control header should be untouched
143         self.assertHeader("Cache-Control", "private")
144        
145         # configure the tool to ignore indicators and replace existing headers
146         self.getPage("/expires/force")
147         self.assertStatus("200 OK")
148         # This also gives us a chance to test 0 expiry with no other headers
149         self.assertHeader("Pragma", "no-cache")
150         if cherrypy.server.protocol_version == "HTTP/1.1":
151             self.assertHeader("Cache-Control", "no-cache, must-revalidate")
152         d = self.assertHeader("Date")
153         self.assertHeader("Expires", d)
154        
155         # static content should now have "cache prevention" headers
156         self.getPage("/expires/index.html")
157         self.assertStatus("200 OK")
158         self.assertHeader("Pragma", "no-cache")
159         if cherrypy.server.protocol_version == "HTTP/1.1":
160             self.assertHeader("Cache-Control", "no-cache, must-revalidate")
161         d = self.assertHeader("Date")
162         self.assertHeader("Expires", d)
163        
164         # the cacheable handler should now have "cache prevention" headers
165         self.getPage("/expires/cacheable")
166         self.assertStatus("200 OK")
167         self.assertHeader("Pragma", "no-cache")
168         if cherrypy.server.protocol_version == "HTTP/1.1":
169             self.assertHeader("Cache-Control", "no-cache, must-revalidate")
170         d = self.assertHeader("Date")
171         self.assertHeader("Expires", d)
172        
173         self.getPage('/expires/dynamic')
174         self.assertBody("D-d-d-dynamic!")
175         # dynamic sets Cache-Control to private but it should  be
176         # overwritten here ...
177         self.assertHeader("Pragma", "no-cache")
178         if cherrypy.server.protocol_version == "HTTP/1.1":
179             self.assertHeader("Cache-Control", "no-cache, must-revalidate")
180         d = self.assertHeader("Date")
181         self.assertHeader("Expires", d)
182
183 if __name__ == '__main__':
184     setup_server()
185     helper.testmain()
186
Note: See TracBrowser for help on using the browser.

Hosted by WebFaction

Log in as guest/cpguest to create tickets