1 | import unittest |
---|
2 | |
---|
3 | from base import CacheFuFunctionalTestCase |
---|
4 | |
---|
5 | from Products.PythonScripts.standard import url_quote |
---|
6 | from Products.CMFCore.utils import getToolByName |
---|
7 | import Products.CacheSetup.config as config |
---|
8 | |
---|
9 | # util for making content in a container |
---|
10 | def makeContent(container, id, portal_type, title=None): |
---|
11 | container.invokeFactory(id=id, type_name=portal_type) |
---|
12 | o = getattr(container, id) |
---|
13 | if title is not None: |
---|
14 | o.setTitle(title) |
---|
15 | return o |
---|
16 | |
---|
17 | |
---|
18 | # This is the test case. You will have to add test_<methods> to your |
---|
19 | # class inorder to assert things about your Product. |
---|
20 | class CacheManagerTest(CacheFuFunctionalTestCase): |
---|
21 | USER1 = 'user1' |
---|
22 | |
---|
23 | def afterSetUp(self): |
---|
24 | CacheFuFunctionalTestCase.afterSetUp(self) |
---|
25 | |
---|
26 | # Add a couple of users |
---|
27 | self.portal.acl_users._doAddUser('manager', 'secret', ['Manager'], []) |
---|
28 | self.portal.acl_users._doAddUser(self.USER1, 'secret', ['Member'], []) |
---|
29 | self.login('manager') |
---|
30 | |
---|
31 | self.portal.portal_quickinstaller.installProducts(['CacheSetup']) |
---|
32 | |
---|
33 | # We have added a skin so we need to rebuild the skin object |
---|
34 | # (since the object is cached in the current request) |
---|
35 | self._refreshSkinData() |
---|
36 | |
---|
37 | pcs = getattr(self.portal, config.CACHE_TOOL_ID) |
---|
38 | pcs.setEnabled(True) |
---|
39 | |
---|
40 | pcs.setCacheConfig('squid') |
---|
41 | |
---|
42 | # turn off the page cache manager |
---|
43 | getattr(self.portal, config.PAGE_CACHE_MANAGER_ID).disable() |
---|
44 | |
---|
45 | def parse_cc(self, st): |
---|
46 | tokens = [s.strip().split('=') for s in st.split(',') if s] |
---|
47 | d = {} |
---|
48 | for t in tokens: |
---|
49 | key = t[0].strip().lower() |
---|
50 | if len(t) > 1: |
---|
51 | value = t[1] |
---|
52 | else: |
---|
53 | value = '' |
---|
54 | try: |
---|
55 | value = int(value) |
---|
56 | except: |
---|
57 | pass |
---|
58 | d[key] = value |
---|
59 | return d |
---|
60 | |
---|
61 | # I'm not sure what we're testing here but |
---|
62 | # cacheConfig is deprecated |
---|
63 | # |
---|
64 | #def test_content_pagecache(self): |
---|
65 | # pcs = getattr(self.portal, config.CACHE_TOOL_ID) |
---|
66 | # pcs.setCacheConfig('zserver') |
---|
67 | # # turn on the page cache manager |
---|
68 | # getattr(self.portal, config.PAGE_CACHE_MANAGER_ID).enable() |
---|
69 | # |
---|
70 | # d = makeContent(self.folder, 'doc', 'Document', 'My document') |
---|
71 | # ob_path = '/'+d.absolute_url(1) |
---|
72 | # response = self.publish(ob_path) |
---|
73 | # xpc = response.headers.get('x-pagecache',None) |
---|
74 | # if xpc is None: |
---|
75 | # # document view has not yet been associated with page cache (depends on order of test execution) |
---|
76 | # response = self.publish(ob_path) |
---|
77 | # # now it should be |
---|
78 | # xpc = response.headers.get('x-pagecache',None) |
---|
79 | # self.failUnless(xpc in ('MISS', 'HIT')) |
---|
80 | # |
---|
81 | # response = self.publish(ob_path) |
---|
82 | # xpc = response.headers.get('x-pagecache',None) |
---|
83 | # self.assertEqual(xpc, 'HIT') |
---|
84 | # |
---|
85 | # # turn off the page cache manager |
---|
86 | # getattr(self.portal, config.PAGE_CACHE_MANAGER_ID).disable() |
---|
87 | |
---|
88 | # The rest of these look like they're testing for specific policies |
---|
89 | # These are always subject to change, so let's not constrain ourselves |
---|
90 | # by forcing us to update tests whenever we improve the policies. |
---|
91 | # |
---|
92 | def test_content(self): |
---|
93 | return |
---|
94 | d = makeContent(self.folder, 'doc', 'Document', 'My document') |
---|
95 | ob_path = '/'+d.absolute_url(1) |
---|
96 | |
---|
97 | # document default view for authenticated should be private and not cached |
---|
98 | response = self.publish(ob_path) |
---|
99 | self.assertEqual(response.headers.get('x-caching-rule-id',None), 'plone-content-types') |
---|
100 | self.assertEqual(response.headers.get('x-header-set-id',None), 'cache-in-proxy-1-hour') |
---|
101 | cc = response.headers.get('cache-control',None) |
---|
102 | self.assertNotEqual(cc, None) |
---|
103 | cc = self.parse_cc(cc) |
---|
104 | self.assertEqual(cc.get('max-age',None), 0) |
---|
105 | self.assertEqual(cc.get('s-maxage',None), 3600) |
---|
106 | self.assertNotEqual(cc.get('must-revalidate',None), None) |
---|
107 | self.assertEqual(cc.get('private',None), None) |
---|
108 | |
---|
109 | response = self.publish(ob_path, basic='%s:%s' % (self.USER1, 'secret')) |
---|
110 | self.assertEqual(response.headers.get('x-caching-rule-id',None), 'plone-content-types') |
---|
111 | self.assertEqual(response.headers.get('x-header-set-id',None), 'cache-with-etag') |
---|
112 | cc = response.headers.get('cache-control',None) |
---|
113 | self.assertNotEqual(cc, None) |
---|
114 | cc = self.parse_cc(cc) |
---|
115 | self.assertEqual(cc.get('max-age',None), 0) |
---|
116 | self.assertEqual(cc.get('s-maxage',None), 0) |
---|
117 | self.assertNotEqual(cc.get('must-revalidate',None), None) |
---|
118 | self.assertNotEqual(cc.get('private',None), None) |
---|
119 | |
---|
120 | # document default view for anonymous should be cached in squid but not on browser |
---|
121 | rule = getattr(getattr(self.portal, config.CACHE_TOOL_ID).getRules(), 'plone-content-types') |
---|
122 | rule.setHeaderSetIdAnon('cache-in-proxy-1-hour') |
---|
123 | response = self.publish(ob_path) |
---|
124 | self.assertEqual(response.headers.get('x-caching-rule-id',None), 'plone-content-types') |
---|
125 | self.assertEqual(response.headers.get('x-header-set-id',None), 'cache-in-proxy-1-hour') |
---|
126 | cc = response.headers.get('cache-control',None) |
---|
127 | self.assertNotEqual(cc, None) |
---|
128 | cc = self.parse_cc(cc) |
---|
129 | self.assertEqual(cc.get('max-age',None), 0) |
---|
130 | self.assertEqual(cc.get('s-maxage',None), 3600) |
---|
131 | self.assertNotEqual(cc.get('must-revalidate',None), None) |
---|
132 | |
---|
133 | def test_content_apache(self): |
---|
134 | return |
---|
135 | pcs = getattr(self.portal, config.CACHE_TOOL_ID) |
---|
136 | pcs.setCacheConfig('apache') |
---|
137 | d = makeContent(self.folder, 'doc', 'Document', 'My document') |
---|
138 | ob_path = '/'+d.absolute_url(1) |
---|
139 | |
---|
140 | # document default view for anonymous should be cached in squid but not on browser |
---|
141 | response = self.publish(ob_path) |
---|
142 | cc = response.headers.get('cache-control',None) |
---|
143 | cc = self.parse_cc(cc) |
---|
144 | self.assertEqual(cc.get('max-age',None), 0) |
---|
145 | self.assertEqual(cc.get('s-maxage',None), None) # no s-maxage for apache |
---|
146 | |
---|
147 | # document default view for authenticated should be private and not cached |
---|
148 | response = self.publish(ob_path, basic='%s:%s' % (self.USER1, 'secret')) |
---|
149 | cc = response.headers.get('cache-control',None) |
---|
150 | cc = self.parse_cc(cc) |
---|
151 | self.assertEqual(cc.get('max-age',None), 0) |
---|
152 | self.assertEqual(cc.get('s-maxage',None), None) # no s-maxage for apache |
---|
153 | |
---|
154 | def test_content_gzip(self): |
---|
155 | return |
---|
156 | pcs = getattr(self.portal, config.CACHE_TOOL_ID) |
---|
157 | pcs.setCacheConfig('apache') |
---|
158 | d = makeContent(self.folder, 'doc', 'Document', 'My document') |
---|
159 | ob_path = '/'+d.absolute_url(1) |
---|
160 | |
---|
161 | # exercise the gzipping code path |
---|
162 | response = self.publish(ob_path, env={'HTTP_ACCEPT_ENCODING': 'gzip'}) |
---|
163 | |
---|
164 | def test_container(self): |
---|
165 | return |
---|
166 | ob_path = '/'+self.folder.absolute_url(1) |
---|
167 | |
---|
168 | # folder default view for anonymous should not be cached |
---|
169 | response = self.publish(ob_path) |
---|
170 | self.assertEqual(response.headers.get('x-caching-rule-id',None), 'plone-containers') |
---|
171 | self.assertEqual(response.headers.get('x-header-set-id',None), 'cache-in-memory') |
---|
172 | cc = response.headers.get('cache-control',None) |
---|
173 | self.assertNotEqual(cc, None) |
---|
174 | cc = self.parse_cc(cc) |
---|
175 | self.assertEqual(cc.get('max-age',None), 0) |
---|
176 | self.assertEqual(cc.get('s-maxage',None), 0) |
---|
177 | self.assertNotEqual(cc.get('must-revalidate',None), None) |
---|
178 | |
---|
179 | # folder default view for authenticated should be private and not cached |
---|
180 | response = self.publish(ob_path, basic='%s:%s' % (self.USER1, 'secret')) |
---|
181 | self.assertEqual(response.headers.get('x-caching-rule-id',None), 'plone-containers') |
---|
182 | self.assertEqual(response.headers.get('x-header-set-id',None), 'cache-with-etag') |
---|
183 | cc = response.headers.get('cache-control',None) |
---|
184 | self.assertNotEqual(cc, None) |
---|
185 | cc = self.parse_cc(cc) |
---|
186 | self.assertEqual(cc.get('max-age',None), 0) |
---|
187 | self.assertEqual(cc.get('s-maxage',None), 0) |
---|
188 | self.assertNotEqual(cc.get('must-revalidate',None), None) |
---|
189 | self.assertNotEqual(cc.get('private',None), None) |
---|
190 | |
---|
191 | def test_http_cache(self): |
---|
192 | return |
---|
193 | ob_path = '/'+self.portal.absolute_url(1)+'/defaultUser.gif' |
---|
194 | |
---|
195 | # folder default view for anonymous should not be cached |
---|
196 | response = self.publish(ob_path) |
---|
197 | self.assertEqual(response.headers.get('x-caching-rule-id',None), 'httpcache') |
---|
198 | self.assertEqual(response.headers.get('x-header-set-id',None), 'cache-in-browser-24-hours') |
---|
199 | cc = response.headers.get('cache-control',None) |
---|
200 | self.assertNotEqual(cc, None) |
---|
201 | cc = self.parse_cc(cc) |
---|
202 | self.assertEqual(cc.get('max-age',None), 24*3600) |
---|
203 | self.assertEqual(cc.get('s-maxage',None), 24*3600) |
---|
204 | self.assertNotEqual(cc.get('must-revalidate',None), None) |
---|
205 | self.assertNotEqual(cc.get('public',None), None) |
---|
206 | self.assertEqual(cc.get('private',None), None) |
---|
207 | |
---|
208 | # folder default view for authenticated should be private and not cached |
---|
209 | response = self.publish(ob_path, basic='%s:%s' % (self.USER1, 'secret')) |
---|
210 | self.assertEqual(response.headers.get('x-caching-rule-id',None), 'httpcache') |
---|
211 | self.assertEqual(response.headers.get('x-header-set-id',None), 'cache-in-browser-24-hours') |
---|
212 | |
---|
213 | def test_templates(self): |
---|
214 | return |
---|
215 | ob_path = '/'+self.portal.absolute_url(1)+'/sitemap' |
---|
216 | # folder default view for anonymous should not be cached |
---|
217 | response = self.publish(ob_path) |
---|
218 | self.assertEqual(response.headers.get('x-caching-rule-id',None), 'plone-templates') |
---|
219 | self.assertEqual(response.headers.get('x-header-set-id',None), 'cache-in-memory') |
---|
220 | |
---|
221 | response = self.publish(ob_path, basic='%s:%s' % (self.USER1, 'secret')) |
---|
222 | self.assertEqual(response.headers.get('x-caching-rule-id',None), 'plone-templates') |
---|
223 | self.assertEqual(response.headers.get('x-header-set-id',None), 'cache-with-etag') |
---|
224 | |
---|
225 | def test_resource_registries(self): |
---|
226 | return |
---|
227 | self.logout() |
---|
228 | stylesheets = self.portal.portal_css.getEvaluatedResources(self.portal) |
---|
229 | skin_name = self.portal.getCurrentSkinName() |
---|
230 | ob_path = '/'+self.portal.portal_css.absolute_url(1)+'/'+skin_name+'/'+stylesheets[0].getId() |
---|
231 | |
---|
232 | response = self.publish(ob_path) |
---|
233 | self.assertEqual(response.headers.get('x-caching-rule-id',None), 'resource-registries') |
---|
234 | self.assertEqual(response.headers.get('x-header-set-id',None), 'cache-in-browser-forever') |
---|
235 | |
---|
236 | response = self.publish(ob_path, basic='%s:%s' % (self.USER1, 'secret')) |
---|
237 | self.assertEqual(response.headers.get('x-caching-rule-id',None), 'resource-registries') |
---|
238 | self.assertEqual(response.headers.get('x-header-set-id',None), 'cache-in-browser-forever') |
---|
239 | |
---|
240 | js = self.portal.portal_javascripts.getEvaluatedResources(self.portal) |
---|
241 | ob_path = '/'+self.portal.portal_javascripts.absolute_url(1)+'/'+skin_name+'/'+js[0].getId() |
---|
242 | |
---|
243 | response = self.publish(ob_path) |
---|
244 | self.assertEqual(response.headers.get('x-caching-rule-id',None), 'resource-registries') |
---|
245 | self.assertEqual(response.headers.get('x-header-set-id',None), 'cache-in-browser-forever') |
---|
246 | |
---|
247 | response = self.publish(ob_path, basic='%s:%s' % (self.USER1, 'secret')) |
---|
248 | self.assertEqual(response.headers.get('x-caching-rule-id',None), 'resource-registries') |
---|
249 | self.assertEqual(response.headers.get('x-header-set-id',None), 'cache-in-browser-forever') |
---|
250 | |
---|
251 | def test_file(self): |
---|
252 | return |
---|
253 | f = makeContent(self.folder, 'file', 'File', 'My file') |
---|
254 | |
---|
255 | # XXX - this doesn't seem to work |
---|
256 | # the problem appears to be (1) that ATFile reports index_html as its default view instead of file_view, |
---|
257 | # and (2) that index_html actually returns a file to be downloaded |
---|
258 | #ob_path = '/'+f.absolute_url(1)+'/file_view' |
---|
259 | ## file default view should be cached with plone-content-types rule |
---|
260 | #response = self.publish(ob_path) |
---|
261 | #self.assertEqual(response.headers.get('x-caching-rule-id',None), 'plone-content-types') |
---|
262 | |
---|
263 | # anonymous download |
---|
264 | ob_path = '/'+f.absolute_url(1)+'/download' |
---|
265 | response = self.publish(ob_path) |
---|
266 | self.assertEqual(response.headers.get('x-caching-rule-id',None), 'downloads') |
---|
267 | self.assertEqual(response.headers.get('x-header-set-id',None), 'cache-in-proxy-24-hours') |
---|
268 | |
---|
269 | # anonymous download, alternate url |
---|
270 | ob_path = '/'+f.absolute_url(1) |
---|
271 | response = self.publish(ob_path) |
---|
272 | self.assertEqual(response.headers.get('x-caching-rule-id',None), 'downloads') |
---|
273 | self.assertEqual(response.headers.get('x-header-set-id',None), 'cache-in-proxy-24-hours') |
---|
274 | |
---|
275 | # authenticated download |
---|
276 | ob_path = '/'+f.absolute_url(1)+'/download' |
---|
277 | response = self.publish(ob_path, basic='%s:%s' % (self.USER1, 'secret')) |
---|
278 | self.assertEqual(response.headers.get('x-caching-rule-id',None), 'downloads') |
---|
279 | self.assertEqual(response.headers.get('x-header-set-id',None), 'cache-in-proxy-24-hours') |
---|
280 | |
---|
281 | # authenticated download, alternate url |
---|
282 | ob_path = '/'+f.absolute_url(1) |
---|
283 | response = self.publish(ob_path, basic='%s:%s' % (self.USER1, 'secret')) |
---|
284 | self.assertEqual(response.headers.get('x-caching-rule-id',None), 'downloads') |
---|
285 | self.assertEqual(response.headers.get('x-header-set-id',None), 'cache-in-proxy-24-hours') |
---|
286 | |
---|
287 | # make file private |
---|
288 | self.portal.portal_workflow.doActionFor(f, 'hide') |
---|
289 | |
---|
290 | # anonymous download |
---|
291 | ob_path = '/'+f.absolute_url(1)+'/download' |
---|
292 | response = self.publish(ob_path) |
---|
293 | self.assertEqual(response.status, 302) |
---|
294 | self.failUnless(response.getHeader('location').find('require_login') != -1) |
---|
295 | |
---|
296 | # anonymous download, alternate url |
---|
297 | ob_path = '/'+f.absolute_url(1) |
---|
298 | response = self.publish(ob_path) |
---|
299 | self.assertEqual(response.status, 302) |
---|
300 | self.failUnless(response.getHeader('location').find('require_login') != -1) |
---|
301 | |
---|
302 | # authenticated download |
---|
303 | ob_path = '/'+f.absolute_url(1)+'/download' |
---|
304 | response = self.publish(ob_path, basic='%s:%s' % ('manager', 'secret')) |
---|
305 | self.assertEqual(response.headers.get('x-caching-rule-id',None), 'downloads') |
---|
306 | self.assertEqual(response.headers.get('x-header-set-id',None), 'no-cache') |
---|
307 | |
---|
308 | # authenticated download, alternate url |
---|
309 | ob_path = '/'+f.absolute_url(1) |
---|
310 | response = self.publish(ob_path, basic='%s:%s' % ('manager', 'secret')) |
---|
311 | self.assertEqual(response.headers.get('x-caching-rule-id',None), 'downloads') |
---|
312 | self.assertEqual(response.headers.get('x-header-set-id',None), 'no-cache') |
---|
313 | |
---|
314 | def test_suite(): |
---|
315 | suite = unittest.TestSuite() |
---|
316 | suite.addTest(unittest.makeSuite(CacheManagerTest)) |
---|
317 | return suite |
---|