blob: 1f1fde7a41a91ccb21ce30d399960edbc8ff5828 [file] [log] [blame]
Sergey Shepelev0112eff2017-05-05 06:46:43 +03001import email.utils
2import httplib2
3import pytest
4import re
5import tests
6import time
7
Alex Yuaa1b95b2018-07-26 23:23:35 -04008dummy_url = "http://127.0.0.1:1"
Sergey Shepelev0112eff2017-05-05 06:46:43 +03009
10
11def test_get_only_if_cached_cache_hit():
12 # Test that can do a GET with cache and 'only-if-cached'
13 http = httplib2.Http(cache=tests.get_cache_path())
14 with tests.server_const_http(add_etag=True) as uri:
Alex Yuaa1b95b2018-07-26 23:23:35 -040015 http.request(uri, "GET")
16 response, content = http.request(
17 uri, "GET", headers={"cache-control": "only-if-cached"}
18 )
Sergey Shepelev0112eff2017-05-05 06:46:43 +030019 assert response.fromcache
20 assert response.status == 200
21
22
23def test_get_only_if_cached_cache_miss():
24 # Test that can do a GET with no cache with 'only-if-cached'
25 http = httplib2.Http(cache=tests.get_cache_path())
26 with tests.server_const_http(request_count=0) as uri:
Alex Yuaa1b95b2018-07-26 23:23:35 -040027 response, content = http.request(
28 uri, "GET", headers={"cache-control": "only-if-cached"}
29 )
Sergey Shepelev0112eff2017-05-05 06:46:43 +030030 assert not response.fromcache
31 assert response.status == 504
32
33
34def test_get_only_if_cached_no_cache_at_all():
35 # Test that can do a GET with no cache with 'only-if-cached'
36 # Of course, there might be an intermediary beyond us
37 # that responds to the 'only-if-cached', so this
38 # test can't really be guaranteed to pass.
39 http = httplib2.Http()
40 with tests.server_const_http(request_count=0) as uri:
Alex Yuaa1b95b2018-07-26 23:23:35 -040041 response, content = http.request(
42 uri, "GET", headers={"cache-control": "only-if-cached"}
43 )
Sergey Shepelev0112eff2017-05-05 06:46:43 +030044 assert not response.fromcache
45 assert response.status == 504
46
47
Alex Yuaa1b95b2018-07-26 23:23:35 -040048@pytest.mark.skip(reason="was commented in legacy code")
Sergey Shepelev0112eff2017-05-05 06:46:43 +030049def test_TODO_vary_no():
50 pass
51 # when there is no vary, a different Accept header (e.g.) should not
52 # impact if the cache is used
53 # test that the vary header is not sent
54 # uri = urllib.parse.urljoin(base, "vary/no-vary.asis")
55 # response, content = http.request(uri, 'GET', headers={'Accept': 'text/plain'})
56 # assert response.status == 200
57 # assert 'vary' not in response
58 #
59 # response, content = http.request(uri, 'GET', headers={'Accept': 'text/plain'})
60 # assert response.status == 200
61 # assert response.fromcache, "Should be from cache"
62 #
63 # response, content = http.request(uri, 'GET', headers={'Accept': 'text/html'})
64 # assert response.status == 200
65 # assert response.fromcache, "Should be from cache"
66
67
Alex Yuaa1b95b2018-07-26 23:23:35 -040068def test_vary_header_is_sent():
69 # Verifies RFC 2616 13.6.
70 # See https://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html.
Sergey Shepelev0112eff2017-05-05 06:46:43 +030071 http = httplib2.Http(cache=tests.get_cache_path())
72 response = tests.http_response_bytes(
Alex Yuaa1b95b2018-07-26 23:23:35 -040073 headers={"vary": "Accept", "cache-control": "max-age=300"}, add_date=True
Sergey Shepelev0112eff2017-05-05 06:46:43 +030074 )
75 with tests.server_const_bytes(response, request_count=3) as uri:
Alex Yuaa1b95b2018-07-26 23:23:35 -040076 response, content = http.request(uri, "GET", headers={"accept": "text/plain"})
Sergey Shepelev0112eff2017-05-05 06:46:43 +030077 assert response.status == 200
Alex Yuaa1b95b2018-07-26 23:23:35 -040078 assert "vary" in response
Sergey Shepelev0112eff2017-05-05 06:46:43 +030079
80 # get the resource again, from the cache since accept header in this
81 # request is the same as the request
Alex Yuaa1b95b2018-07-26 23:23:35 -040082 response, content = http.request(uri, "GET", headers={"Accept": "text/plain"})
Sergey Shepelev0112eff2017-05-05 06:46:43 +030083 assert response.status == 200
84 assert response.fromcache, "Should be from cache"
85
86 # get the resource again, not from cache since Accept headers does not match
Alex Yuaa1b95b2018-07-26 23:23:35 -040087 response, content = http.request(uri, "GET", headers={"Accept": "text/html"})
Sergey Shepelev0112eff2017-05-05 06:46:43 +030088 assert response.status == 200
89 assert not response.fromcache, "Should not be from cache"
90
91 # get the resource again, without any Accept header, so again no match
Alex Yuaa1b95b2018-07-26 23:23:35 -040092 response, content = http.request(uri, "GET")
Sergey Shepelev0112eff2017-05-05 06:46:43 +030093 assert response.status == 200
94 assert not response.fromcache, "Should not be from cache"
95
96
97def test_vary_header_double():
98 http = httplib2.Http(cache=tests.get_cache_path())
99 response = tests.http_response_bytes(
Alex Yuaa1b95b2018-07-26 23:23:35 -0400100 headers={"vary": "Accept, Accept-Language", "cache-control": "max-age=300"},
Sergey Shepelev0112eff2017-05-05 06:46:43 +0300101 add_date=True,
102 )
103 with tests.server_const_bytes(response, request_count=3) as uri:
Alex Yuaa1b95b2018-07-26 23:23:35 -0400104 response, content = http.request(
105 uri,
106 "GET",
107 headers={
108 "Accept": "text/plain",
109 "Accept-Language": "da, en-gb;q=0.8, en;q=0.7",
110 },
111 )
Sergey Shepelev0112eff2017-05-05 06:46:43 +0300112 assert response.status == 200
Alex Yuaa1b95b2018-07-26 23:23:35 -0400113 assert "vary" in response
Sergey Shepelev0112eff2017-05-05 06:46:43 +0300114
115 # we are from cache
Alex Yuaa1b95b2018-07-26 23:23:35 -0400116 response, content = http.request(
117 uri,
118 "GET",
119 headers={
120 "Accept": "text/plain",
121 "Accept-Language": "da, en-gb;q=0.8, en;q=0.7",
122 },
123 )
Sergey Shepelev0112eff2017-05-05 06:46:43 +0300124 assert response.fromcache, "Should be from cache"
125
Alex Yuaa1b95b2018-07-26 23:23:35 -0400126 response, content = http.request(uri, "GET", headers={"Accept": "text/plain"})
Sergey Shepelev0112eff2017-05-05 06:46:43 +0300127 assert response.status == 200
128 assert not response.fromcache
129
130 # get the resource again, not from cache, varied headers don't match exact
Alex Yuaa1b95b2018-07-26 23:23:35 -0400131 response, content = http.request(uri, "GET", headers={"Accept-Language": "da"})
Sergey Shepelev0112eff2017-05-05 06:46:43 +0300132 assert response.status == 200
133 assert not response.fromcache, "Should not be from cache"
134
135
136def test_vary_unused_header():
137 http = httplib2.Http(cache=tests.get_cache_path())
138 response = tests.http_response_bytes(
Alex Yuaa1b95b2018-07-26 23:23:35 -0400139 headers={"vary": "X-No-Such-Header", "cache-control": "max-age=300"},
Sergey Shepelev0112eff2017-05-05 06:46:43 +0300140 add_date=True,
141 )
142 with tests.server_const_bytes(response, request_count=1) as uri:
143 # A header's value is not considered to vary if it's not used at all.
Alex Yuaa1b95b2018-07-26 23:23:35 -0400144 response, content = http.request(uri, "GET", headers={"Accept": "text/plain"})
Sergey Shepelev0112eff2017-05-05 06:46:43 +0300145 assert response.status == 200
Alex Yuaa1b95b2018-07-26 23:23:35 -0400146 assert "vary" in response
Sergey Shepelev0112eff2017-05-05 06:46:43 +0300147
148 # we are from cache
Alex Yuaa1b95b2018-07-26 23:23:35 -0400149 response, content = http.request(uri, "GET", headers={"Accept": "text/plain"})
Sergey Shepelev0112eff2017-05-05 06:46:43 +0300150 assert response.fromcache, "Should be from cache"
151
152
153def test_get_cache_control_no_cache():
154 # Test Cache-Control: no-cache on requests
155 http = httplib2.Http(cache=tests.get_cache_path())
156 with tests.server_const_http(
Alex Yuaa1b95b2018-07-26 23:23:35 -0400157 add_date=True,
158 add_etag=True,
159 headers={"cache-control": "max-age=300"},
160 request_count=2,
161 ) as uri:
162 response, _ = http.request(uri, "GET", headers={"accept-encoding": "identity"})
Sergey Shepelev0112eff2017-05-05 06:46:43 +0300163 assert response.status == 200
Alex Yuaa1b95b2018-07-26 23:23:35 -0400164 assert response["etag"] != ""
Sergey Shepelev0112eff2017-05-05 06:46:43 +0300165 assert not response.fromcache
Alex Yuaa1b95b2018-07-26 23:23:35 -0400166 response, _ = http.request(uri, "GET", headers={"accept-encoding": "identity"})
Sergey Shepelev0112eff2017-05-05 06:46:43 +0300167 assert response.status == 200
168 assert response.fromcache
Alex Yuaa1b95b2018-07-26 23:23:35 -0400169 response, _ = http.request(
170 uri,
171 "GET",
172 headers={"accept-encoding": "identity", "Cache-Control": "no-cache"},
173 )
Sergey Shepelev0112eff2017-05-05 06:46:43 +0300174 assert response.status == 200
175 assert not response.fromcache
176
177
178def test_get_cache_control_pragma_no_cache():
179 # Test Pragma: no-cache on requests
180 http = httplib2.Http(cache=tests.get_cache_path())
181 with tests.server_const_http(
Alex Yuaa1b95b2018-07-26 23:23:35 -0400182 add_date=True,
183 add_etag=True,
184 headers={"cache-control": "max-age=300"},
185 request_count=2,
186 ) as uri:
187 response, _ = http.request(uri, "GET", headers={"accept-encoding": "identity"})
188 assert response["etag"] != ""
189 response, _ = http.request(uri, "GET", headers={"accept-encoding": "identity"})
Sergey Shepelev0112eff2017-05-05 06:46:43 +0300190 assert response.status == 200
191 assert response.fromcache
Alex Yuaa1b95b2018-07-26 23:23:35 -0400192 response, _ = http.request(
193 uri, "GET", headers={"accept-encoding": "identity", "Pragma": "no-cache"}
194 )
Sergey Shepelev0112eff2017-05-05 06:46:43 +0300195 assert response.status == 200
196 assert not response.fromcache
197
198
199def test_get_cache_control_no_store_request():
200 # A no-store request means that the response should not be stored.
201 http = httplib2.Http(cache=tests.get_cache_path())
202 with tests.server_const_http(
Alex Yuaa1b95b2018-07-26 23:23:35 -0400203 add_date=True,
204 add_etag=True,
205 headers={"cache-control": "max-age=300"},
206 request_count=2,
207 ) as uri:
208 response, _ = http.request(uri, "GET", headers={"Cache-Control": "no-store"})
Sergey Shepelev0112eff2017-05-05 06:46:43 +0300209 assert response.status == 200
210 assert not response.fromcache
Alex Yuaa1b95b2018-07-26 23:23:35 -0400211 response, _ = http.request(uri, "GET", headers={"Cache-Control": "no-store"})
Sergey Shepelev0112eff2017-05-05 06:46:43 +0300212 assert response.status == 200
213 assert not response.fromcache
214
215
216def test_get_cache_control_no_store_response():
217 # A no-store response means that the response should not be stored.
218 http = httplib2.Http(cache=tests.get_cache_path())
219 with tests.server_const_http(
Alex Yuaa1b95b2018-07-26 23:23:35 -0400220 add_date=True,
221 add_etag=True,
222 headers={"cache-control": "max-age=300, no-store"},
223 request_count=2,
224 ) as uri:
225 response, _ = http.request(uri, "GET")
Sergey Shepelev0112eff2017-05-05 06:46:43 +0300226 assert response.status == 200
227 assert not response.fromcache
Alex Yuaa1b95b2018-07-26 23:23:35 -0400228 response, _ = http.request(uri, "GET")
Sergey Shepelev0112eff2017-05-05 06:46:43 +0300229 assert response.status == 200
230 assert not response.fromcache
231
232
233def test_get_cache_control_no_cache_no_store_request():
234 # Test that a no-store, no-cache clears the entry from the cache
235 # even if it was cached previously.
236 http = httplib2.Http(cache=tests.get_cache_path())
237 with tests.server_const_http(
Alex Yuaa1b95b2018-07-26 23:23:35 -0400238 add_date=True,
239 add_etag=True,
240 headers={"cache-control": "max-age=300"},
241 request_count=3,
242 ) as uri:
243 response, _ = http.request(uri, "GET")
244 response, _ = http.request(uri, "GET")
Sergey Shepelev0112eff2017-05-05 06:46:43 +0300245 assert response.fromcache
Alex Yuaa1b95b2018-07-26 23:23:35 -0400246 response, _ = http.request(
247 uri, "GET", headers={"Cache-Control": "no-store, no-cache"}
248 )
Sergey Shepelev0112eff2017-05-05 06:46:43 +0300249 assert response.status == 200
250 assert not response.fromcache
Alex Yuaa1b95b2018-07-26 23:23:35 -0400251 response, _ = http.request(
252 uri, "GET", headers={"Cache-Control": "no-store, no-cache"}
253 )
Sergey Shepelev0112eff2017-05-05 06:46:43 +0300254 assert response.status == 200
255 assert not response.fromcache
256
257
258def test_update_invalidates_cache():
259 # Test that calling PUT or DELETE on a
260 # URI that is cache invalidates that cache.
261 http = httplib2.Http(cache=tests.get_cache_path())
262
263 def handler(request):
Alex Yuaa1b95b2018-07-26 23:23:35 -0400264 if request.method in ("PUT", "PATCH", "DELETE"):
Sergey Shepelev0112eff2017-05-05 06:46:43 +0300265 return tests.http_response_bytes(status=405)
266 return tests.http_response_bytes(
Alex Yuaa1b95b2018-07-26 23:23:35 -0400267 add_date=True, add_etag=True, headers={"cache-control": "max-age=300"}
268 )
Sergey Shepelev0112eff2017-05-05 06:46:43 +0300269
270 with tests.server_request(handler, request_count=3) as uri:
Alex Yuaa1b95b2018-07-26 23:23:35 -0400271 response, _ = http.request(uri, "GET")
272 response, _ = http.request(uri, "GET")
Sergey Shepelev0112eff2017-05-05 06:46:43 +0300273 assert response.fromcache
Alex Yuaa1b95b2018-07-26 23:23:35 -0400274 response, _ = http.request(uri, "DELETE")
Sergey Shepelev0112eff2017-05-05 06:46:43 +0300275 assert response.status == 405
276 assert not response.fromcache
Alex Yuaa1b95b2018-07-26 23:23:35 -0400277 response, _ = http.request(uri, "GET")
Sergey Shepelev0112eff2017-05-05 06:46:43 +0300278 assert not response.fromcache
279
280
281def handler_conditional_update(request):
282 respond = tests.http_response_bytes
Alex Yuaa1b95b2018-07-26 23:23:35 -0400283 if request.method == "GET":
284 if request.headers.get("if-none-match", "") == "12345":
Sergey Shepelev0112eff2017-05-05 06:46:43 +0300285 return respond(status=304)
Alex Yuaa1b95b2018-07-26 23:23:35 -0400286 return respond(
287 add_date=True, headers={"etag": "12345", "cache-control": "max-age=300"}
288 )
289 elif request.method in ("PUT", "PATCH", "DELETE"):
290 if request.headers.get("if-match", "") == "12345":
Sergey Shepelev0112eff2017-05-05 06:46:43 +0300291 return respond(status=200)
292 return respond(status=412)
293 return respond(status=405)
294
295
Alex Yuaa1b95b2018-07-26 23:23:35 -0400296@pytest.mark.parametrize("method", ("PUT", "PATCH"))
Sergey Shepelev0112eff2017-05-05 06:46:43 +0300297def test_update_uses_cached_etag(method):
298 # Test that we natively support http://www.w3.org/1999/04/Editing/
299 http = httplib2.Http(cache=tests.get_cache_path())
300 with tests.server_request(handler_conditional_update, request_count=3) as uri:
Alex Yuaa1b95b2018-07-26 23:23:35 -0400301 response, _ = http.request(uri, "GET")
Sergey Shepelev0112eff2017-05-05 06:46:43 +0300302 assert response.status == 200
303 assert not response.fromcache
Alex Yuaa1b95b2018-07-26 23:23:35 -0400304 response, _ = http.request(uri, "GET")
Sergey Shepelev0112eff2017-05-05 06:46:43 +0300305 assert response.status == 200
306 assert response.fromcache
Alex Yuaa1b95b2018-07-26 23:23:35 -0400307 response, _ = http.request(uri, method, body=b"foo")
Sergey Shepelev0112eff2017-05-05 06:46:43 +0300308 assert response.status == 200
Alex Yuaa1b95b2018-07-26 23:23:35 -0400309 response, _ = http.request(uri, method, body=b"foo")
Sergey Shepelev0112eff2017-05-05 06:46:43 +0300310 assert response.status == 412
311
312
313def test_update_uses_cached_etag_and_oc_method():
314 # Test that we natively support http://www.w3.org/1999/04/Editing/
315 http = httplib2.Http(cache=tests.get_cache_path())
316 with tests.server_request(handler_conditional_update, request_count=2) as uri:
Alex Yuaa1b95b2018-07-26 23:23:35 -0400317 response, _ = http.request(uri, "GET")
Sergey Shepelev0112eff2017-05-05 06:46:43 +0300318 assert response.status == 200
319 assert not response.fromcache
Alex Yuaa1b95b2018-07-26 23:23:35 -0400320 response, _ = http.request(uri, "GET")
Sergey Shepelev0112eff2017-05-05 06:46:43 +0300321 assert response.status == 200
322 assert response.fromcache
Alex Yuaa1b95b2018-07-26 23:23:35 -0400323 http.optimistic_concurrency_methods.append("DELETE")
324 response, _ = http.request(uri, "DELETE")
Sergey Shepelev0112eff2017-05-05 06:46:43 +0300325 assert response.status == 200
326
327
328def test_update_uses_cached_etag_overridden():
329 # Test that we natively support http://www.w3.org/1999/04/Editing/
330 http = httplib2.Http(cache=tests.get_cache_path())
331 with tests.server_request(handler_conditional_update, request_count=2) as uri:
Alex Yuaa1b95b2018-07-26 23:23:35 -0400332 response, content = http.request(uri, "GET")
Sergey Shepelev0112eff2017-05-05 06:46:43 +0300333 assert response.status == 200
334 assert not response.fromcache
Alex Yuaa1b95b2018-07-26 23:23:35 -0400335 response, content = http.request(uri, "GET")
Sergey Shepelev0112eff2017-05-05 06:46:43 +0300336 assert response.status == 200
337 assert response.fromcache
Alex Yuaa1b95b2018-07-26 23:23:35 -0400338 response, content = http.request(
339 uri, "PUT", body=b"foo", headers={"if-match": "fred"}
340 )
Sergey Shepelev0112eff2017-05-05 06:46:43 +0300341 assert response.status == 412
342
343
344@pytest.mark.parametrize(
Alex Yuaa1b95b2018-07-26 23:23:35 -0400345 "data",
346 (
Sergey Shepelev0112eff2017-05-05 06:46:43 +0300347 ({}, {}),
Alex Yuaa1b95b2018-07-26 23:23:35 -0400348 ({"cache-control": " no-cache"}, {"no-cache": 1}),
349 (
350 {"cache-control": " no-store, max-age = 7200"},
351 {"no-store": 1, "max-age": "7200"},
352 ),
353 ({"cache-control": " , "}, {"": 1}), # FIXME
354 (
355 {"cache-control": "Max-age=3600;post-check=1800,pre-check=3600"},
356 {"max-age": "3600;post-check=1800", "pre-check": "3600"},
357 ),
358 ),
359 ids=lambda data: str(data[0]),
360)
Sergey Shepelev0112eff2017-05-05 06:46:43 +0300361def test_parse_cache_control(data):
362 header, expected = data
363 assert httplib2._parse_cache_control(header) == expected
364
365
366def test_normalize_headers():
367 # Test that we normalize headers to lowercase
Alex Yuaa1b95b2018-07-26 23:23:35 -0400368 h = httplib2._normalize_headers({"Cache-Control": "no-cache", "Other": "Stuff"})
369 assert "cache-control" in h
370 assert "other" in h
371 assert h["other"] == "Stuff"
Sergey Shepelev0112eff2017-05-05 06:46:43 +0300372
373
374@pytest.mark.parametrize(
Alex Yuaa1b95b2018-07-26 23:23:35 -0400375 "data",
376 (
377 (
378 {"cache-control": "no-cache"},
379 {"cache-control": "max-age=7200"},
380 "TRANSPARENT",
381 ),
382 ({}, {"cache-control": "max-age=fred, min-fresh=barney"}, "STALE"),
383 ({}, {"date": "{now}", "expires": "{now+3}"}, "FRESH"),
384 (
385 {},
386 {"date": "{now}", "expires": "{now+3}", "cache-control": "no-cache"},
387 "STALE",
388 ),
389 ({"cache-control": "must-revalidate"}, {}, "STALE"),
390 ({}, {"cache-control": "must-revalidate"}, "STALE"),
391 ({}, {"date": "{now}", "cache-control": "max-age=0"}, "STALE"),
392 ({"cache-control": "only-if-cached"}, {}, "FRESH"),
393 ({}, {"date": "{now}", "expires": "0"}, "STALE"),
394 ({}, {"data": "{now+3}"}, "STALE"),
395 (
396 {"cache-control": "max-age=0"},
397 {"date": "{now}", "cache-control": "max-age=2"},
398 "STALE",
399 ),
400 (
401 {"cache-control": "min-fresh=2"},
402 {"date": "{now}", "expires": "{now+2}"},
403 "STALE",
404 ),
405 (
406 {"cache-control": "min-fresh=2"},
407 {"date": "{now}", "expires": "{now+4}"},
408 "FRESH",
409 ),
410 ),
411 ids=lambda data: str(data),
412)
Sergey Shepelev0112eff2017-05-05 06:46:43 +0300413def test_entry_disposition(data):
414 now = time.time()
Alex Yuaa1b95b2018-07-26 23:23:35 -0400415 nowre = re.compile(r"{now([\+\-]\d+)?}")
Sergey Shepelev0112eff2017-05-05 06:46:43 +0300416
417 def render(s):
418 m = nowre.match(s)
419 if m:
Alex Yuaa1b95b2018-07-26 23:23:35 -0400420 offset = int(m.expand(r"\1")) if m.group(1) else 0
Sergey Shepelev0112eff2017-05-05 06:46:43 +0300421 s = email.utils.formatdate(now + offset, usegmt=True)
422 return s
423
424 request, response, expected = data
425 request = {k: render(v) for k, v in request.items()}
426 response = {k: render(v) for k, v in response.items()}
427 assert httplib2._entry_disposition(response, request) == expected
428
429
430def test_expiration_model_fresh():
431 response_headers = {
Alex Yuaa1b95b2018-07-26 23:23:35 -0400432 "date": email.utils.formatdate(usegmt=True),
433 "cache-control": "max-age=2",
Sergey Shepelev0112eff2017-05-05 06:46:43 +0300434 }
Alex Yuaa1b95b2018-07-26 23:23:35 -0400435 assert httplib2._entry_disposition(response_headers, {}) == "FRESH"
Sergey Shepelev0112eff2017-05-05 06:46:43 +0300436 # TODO: add current time as _entry_disposition argument to avoid sleep in tests
437 time.sleep(3)
Alex Yuaa1b95b2018-07-26 23:23:35 -0400438 assert httplib2._entry_disposition(response_headers, {}) == "STALE"
Sergey Shepelev0112eff2017-05-05 06:46:43 +0300439
440
441def test_expiration_model_date_and_expires():
442 now = time.time()
443 response_headers = {
Alex Yuaa1b95b2018-07-26 23:23:35 -0400444 "date": email.utils.formatdate(now, usegmt=True),
445 "expires": email.utils.formatdate(now + 2, usegmt=True),
Sergey Shepelev0112eff2017-05-05 06:46:43 +0300446 }
Alex Yuaa1b95b2018-07-26 23:23:35 -0400447 assert httplib2._entry_disposition(response_headers, {}) == "FRESH"
Sergey Shepelev0112eff2017-05-05 06:46:43 +0300448 time.sleep(3)
Alex Yuaa1b95b2018-07-26 23:23:35 -0400449 assert httplib2._entry_disposition(response_headers, {}) == "STALE"
Sergey Shepelev0112eff2017-05-05 06:46:43 +0300450
451
452# TODO: Repeat all cache tests with memcache. pytest.mark.parametrize
453# cache = memcache.Client(['127.0.0.1:11211'], debug=0)
454# #cache = memcache.Client(['10.0.0.4:11211'], debug=1)
455# http = httplib2.Http(cache)