Package cherrypy :: Package test :: Module test_caching
[hide private]
[frames] | no frames]

Source Code for Module cherrypy.test.test_caching

  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