Ejemplo n.º 1
0
    def test_post_cached_with_id(self):
        response = post_through_spectre(
            '/post_id_cache/',
            data='{"request_id":123, "vary_id":"abc"}',
            extra_headers={'content-type': 'application/json'})
        assert response.status_code == 200
        assert response.headers['Spectre-Cache-Status'] == 'miss'

        # When calling with different data, we will see a cache miss.
        response = post_through_spectre(
            '/post_id_cache/',
            data='{"request_id":234, "vary_id":"abc"}',
            extra_headers={'content-type': 'application/json'})
        assert response.status_code == 200
        assert response.headers['Spectre-Cache-Status'] == 'miss'

        # When calling with different data with same id, we will see a cache miss.
        response = post_through_spectre(
            '/post_id_cache/',
            data='{"request_id":234, "vary_id":"def"}',
            extra_headers={'content-type': 'application/json'})
        assert response.status_code == 200
        assert response.headers['Spectre-Cache-Status'] == 'miss'

        # Calling again with same request_id should be a cache hit
        assert_is_in_spectre_cache(
            '/post_id_cache/',
            data='{"request_id":234, "vary_id":"abc"}',
            extra_headers={'content-type': 'application/json'})
Ejemplo n.º 2
0
    def test_default_vary_headers(self):
        assert get_through_spectre('/long_ttl/vary').headers['Spectre-Cache-Status'] == 'miss'
        assert assert_is_in_spectre_cache('/long_ttl/vary')

        # namespace vary_headers do not contain X-Mode
        assert assert_is_in_spectre_cache('/long_ttl/vary', {'x-mode': 'ro'})
        assert get_through_spectre('/long_ttl/vary', {'accept-encoding': 'text'}).headers['Spectre-Cache-Status'] == 'miss'
Ejemplo n.º 3
0
    def test_purge_cassandra_by_id(self):
        get_through_spectre('/bulk_requester?ids=1')
        assert_is_in_spectre_cache('/bulk_requester?ids=1')

        # Purge id 1
        purge_resource({'namespace': 'backend.main', 'cache_name': 'bulk_requester_does_not_cache_missing_ids', 'id': '1'})
        get_resp_3 = get_through_spectre('/bulk_requester?ids=1')
        # resp 3 was no longer cached.
        assert get_resp_3.headers['Spectre-Cache-Status'] == 'miss'
Ejemplo n.º 4
0
    def test_post_always_cached_for_extended_json_content_type(self):
        response = post_through_spectre(
            '/post_always_cache/',
            data={},
            extra_headers={'content-type': 'application/json; charset=utf-8'})
        assert response.status_code == 200
        assert response.headers['Spectre-Cache-Status'] == 'miss'

        # When calling again the result should be cached
        assert_is_in_spectre_cache(
            '/post_always_cache/',
            data={},
            extra_headers={'content-type': 'application/json; charset=utf-8'})
Ejemplo n.º 5
0
    def test_post_cache_hit_even_if_body_doesnt_match_without_vary(self):
        response = post_through_spectre(
            '/post_always_cache/',
            data='{"field1":"key1"}',
            extra_headers={'content-type': 'application/json'})
        assert response.status_code == 200
        assert response.headers['Spectre-Cache-Status'] == 'miss'

        # When calling again the result should be cached
        assert_is_in_spectre_cache(
            '/post_always_cache/',
            data='{"field1":"key2"}',
            extra_headers={'content-type': 'application/json'})
Ejemplo n.º 6
0
    def test_post_cached_with_id_ignore_fields(self):
        response = post_through_spectre(
            '/post_id_cache_variable_body/',
            data='{"request_id":234, "ignore_field1":"abc"}',
            extra_headers={'content-type': 'application/json'})
        assert response.status_code == 200
        assert response.headers['Spectre-Cache-Status'] == 'miss'

        # Calling again with more fields in body which are ignored would also be a cache hit
        assert_is_in_spectre_cache(
            '/post_id_cache_variable_body/',
            data=
            '{"request_id":234, "ignore_field1":"xyz", "ignore_field3":"21"}',
            extra_headers={'content-type': 'application/json'})
Ejemplo n.º 7
0
    def test_spectre_status_response_header(self):
        response = get_through_spectre('/not_cacheable')
        assert response.headers['Spectre-Cache-Status'] == 'non-cacheable-uri (backend.main)'

        response = get_through_spectre('/timestamp/spectre_status_header')
        assert response.headers['Spectre-Cache-Status'] == 'miss'

        assert_is_in_spectre_cache('/timestamp/spectre_status_header')

        response = get_through_spectre('/timestamp/spectre_status_header', extra_headers={'Pragma': 'no-cache'})
        assert response.headers['Spectre-Cache-Status'] == 'no-cache-header'

        response = post_through_spectre('/timestamp/spectre_status_header')
        assert response.headers['Spectre-Cache-Status'] == 'non-cacheable-method'
Ejemplo n.º 8
0
    def test_different_vary_headers(self):
        # same vary header
        val1 = get_through_spectre('/timestamp/cached', {'accept-encoding': 'testzip, deflate, custom'})
        assert val1.headers['Spectre-Cache-Status'] == 'miss'
        assert_is_in_spectre_cache('/timestamp/cached', {'accept-encoding': 'testzip, deflate, custom'})

        # different vary headers --> val3 is a miss
        val3 = get_through_spectre('/timestamp/cached', {'accept-encoding': 'none'})
        assert val3.headers['Spectre-Cache-Status'] == 'miss'

        # contains x-mode --> miss
        val4 = get_through_spectre('/timestamp/cached', {'X-Mode': 'ro'})
        assert val4.headers['Spectre-Cache-Status'] == 'miss'

        # Host is not a Vary header --> hit
        assert_is_in_spectre_cache('/timestamp/cached', {'X-Mode': 'ro', 'Host': 'localhost'})
Ejemplo n.º 9
0
    def test_caching_works_with_id_extraction(self):
        response = get_through_spectre('/biz?foo=bar&business_id=1234')
        assert response.headers['Spectre-Cache-Status'] == 'miss'

        # ensure extracting the id is not messing up the caching logic
        assert_is_in_spectre_cache('/biz?foo=bar&business_id=1234')

        # check that invalidation is actually supported
        purge_resource({
            'namespace': 'backend.main',
            'cache_name': 'url_with_id_extraction',
            'id': '1234',
        })

        # now this should be a cache miss
        response = get_through_spectre('/biz?foo=bar&business_id=1234')
        assert response.headers['Spectre-Cache-Status'] == 'miss'
Ejemplo n.º 10
0
    def test_post_cached_with_id_can_be_purged(self):
        response = post_through_spectre(
            '/post_id_cache/',
            data='{"request_id":123, "vary_id":"abc"}',
            extra_headers={'content-type': 'application/json'})
        assert response.status_code == 200
        assert response.headers['Spectre-Cache-Status'] == 'miss'

        # When calling with different data with same id, we will see a cache miss.
        response = post_through_spectre(
            '/post_id_cache/',
            data='{"request_id":123, "vary_id":"def"}',
            extra_headers={'content-type': 'application/json'})
        assert response.status_code == 200
        assert response.headers['Spectre-Cache-Status'] == 'miss'

        # Calling again with same request_id should be a cache hit
        assert_is_in_spectre_cache(
            '/post_id_cache/',
            data='{"request_id":123, "vary_id":"abc"}',
            extra_headers={'content-type': 'application/json'})

        # Purge all resources with same id.
        purge_resource({
            'namespace': 'backend.main',
            'cache_name': 'post_with_id',
            'id': '123'
        })

        # All resources with same id should be a miss now.
        response = post_through_spectre(
            '/post_id_cache/',
            data='{"request_id":123, "vary_id":"def"}',
            extra_headers={'content-type': 'application/json'})
        assert response.status_code == 200
        assert response.headers['Spectre-Cache-Status'] == 'miss'

        response = post_through_spectre(
            '/post_id_cache/',
            data='{"request_id":123, "vary_id":"abc"}',
            extra_headers={'content-type': 'application/json'})
        assert response.status_code == 200
        assert response.headers['Spectre-Cache-Status'] == 'miss'
Ejemplo n.º 11
0
    def test_response_headers_passed_back(self):
        response = get_through_spectre('/not_cacheable')
        assert response.headers['Some-Header'] == 'abc'
        assert response.headers['Spectre-Cache-Status'] == 'non-cacheable-uri (backend.main)'

        response = get_through_spectre('/timestamp/response_header')
        assert response.headers['Spectre-Cache-Status'] == 'miss'
        assert response.headers['Some-Header'] == 'abc'

        response = assert_is_in_spectre_cache('/timestamp/response_header')
        assert response.headers['Some-Header'] == 'abc'
Ejemplo n.º 12
0
    def test_with_invalid_id_when_cache_missing_ids_is_true(self):
        path = '/bulk_requester_2/{ids}/v1?k1=v1'

        # 0 < ids < 1000 are valid
        response = get_through_spectre(path.format(ids='10,5000,11'))
        assert len(response.json()) == 2
        assert response.headers['Spectre-Cache-Status'] == 'miss'

        # "5000" is an invalid id; but by default cache_missing_ids is set to true, so the
        # empty response would've been cached from the above request
        hit_response = assert_is_in_spectre_cache(path.format(ids='5000'))
        assert hit_response.json() == []
Ejemplo n.º 13
0
    def test_with_invalid_id_when_cache_missing_ids_is_true(self):
        base_path = '/bulk_requester_2'

        # 0 < ids < 1000 are valid
        resp1 = get_through_spectre("{}/{}/v1?k1=v2".format(base_path, '10,5000,11'))
        headers1, body1 = resp1.headers, resp1.json()
        assert len(body1) == 2
        assert headers1['Spectre-Cache-Status'] == 'miss'

        # "5000" is an invalid id; but by default cache_missing_ids is set to true, so the
        # empty response would've been cached from the above request
        resp2 = assert_is_in_spectre_cache("{}/{}/v1?k1=v2".format(base_path, '5000'))
        resp2.json() == []
Ejemplo n.º 14
0
    def test_bulk_ids_in_path(self):
        base_path = '/bulk_requester_2'

        resp_1 = get_through_spectre("{}/{}/v1?k1=v2".format(base_path, '1,2,3'))
        # Bulk was a miss
        bulk_headers, bulk_body = resp_1.headers, resp_1.json()
        assert bulk_headers['Spectre-Cache-Status'] == 'miss'

        resp_2 = assert_is_in_spectre_cache("{}/{}/v1?k1=v2".format(base_path, '2'))
        _, body = resp_2.headers, resp_2.json()

        # Check for correctness
        assert len(body) == 1
        assert bulk_body[1] == body[0]
Ejemplo n.º 15
0
    def test_purge_cassandra_by_id_backward_compatible(self):
        # Delete after PERF-2453 is done
        get_through_spectre('/bulk_requester?ids=1')
        assert_is_in_spectre_cache('/bulk_requester?ids=1')

        # Purge id 1
        res = requests.request(
            'PURGE',
            util.SPECTRE_BASE_URL +
            '?cache_name=bulk_requester_does_not_cache_missing_ids&id=1',
            headers=util.HAPROXY_ADDED_HEADERS)
        assert res.status_code == 200

        get_resp_3 = get_through_spectre('/bulk_requester?ids=1')
        # resp 3 was no longer cached.
        assert get_resp_3.headers['Spectre-Cache-Status'] == 'miss'

        res = requests.request(
            'PURGE',
            util.SPECTRE_BASE_URL +
            '?cache_name=bulk_requester_does_not_cache_missing_ids',
            headers=util.HAPROXY_ADDED_HEADERS)
        assert res.status_code == 200
Ejemplo n.º 16
0
    def test_uncacheable_headers_not_passed_back(self):
        """Spectre doesn't store uncacheable headers in the cache, but it always
        passes back all response headers in the uncached (or uncacheable) case.
        """
        response = get_through_spectre('/not_cacheable')
        assert response.headers['Spectre-Cache-Status'] == 'non-cacheable-uri (backend.main)'
        assert 'Uncacheable-Header' in response.headers

        response = get_through_spectre('/timestamp/uncacheable_header')
        assert response.headers['Spectre-Cache-Status'] == 'miss'
        assert 'Uncacheable-Header' in response.headers

        # This is the cached case, where the uncacheable header isn't expected
        # in the response.
        response = assert_is_in_spectre_cache('/timestamp/uncacheable_header')
        assert 'Uncacheable-Header' not in response.headers
Ejemplo n.º 17
0
    def make_request(self, ids, cache=True, extra_headers=None, assert_hit=False):
        base_path = '/bulk_requester'
        ids = [str(i) for i in ids]
        ids = "%2C".join(ids)
        if not cache:
            cache_headers = {'Cache-Control': 'no-cache'}
            if extra_headers is None:
                extra_headers = {}
            extra_headers.update(cache_headers)

        if assert_hit:
            resp = assert_is_in_spectre_cache("{}?ids={}".format(base_path, ids), extra_headers)
        else:
            resp = get_through_spectre("{}?ids={}".format(base_path, ids), extra_headers)

        return resp.headers, resp.json()
Ejemplo n.º 18
0
    def test_different_params_same_id(self):
        base_path = '/bulk_requester'

        resp1 = get_through_spectre("{}?ids={}&data=false".format(base_path, '5%2C6'))
        assert resp1.headers['Spectre-Cache-Status'] == 'miss'
        resp2 = get_through_spectre("{}?ids={}&data=true".format(base_path, '5'))
        assert resp2.headers['Spectre-Cache-Status'] == 'miss'

        assert_is_in_spectre_cache("{}?data=false&ids={}".format(base_path, '5'))
        assert_is_in_spectre_cache("{}?data=false&ids={}".format(base_path, '6'))
        assert_is_in_spectre_cache("{}?ids={}&data=false".format(base_path, '6'))
Ejemplo n.º 19
0
 def test_gzipped_responses_work(self):
     assert get_through_spectre(
         '/gzipped').headers['Spectre-Cache-Status'] == 'miss'
     assert_is_in_spectre_cache('/gzipped')
Ejemplo n.º 20
0
 def test_query_params_ordering(self):
     val1 = get_through_spectre('/happy/?k1=v1&k2=v2')
     assert val1.headers['Spectre-Cache-Status'] == 'miss'
     assert_is_in_spectre_cache('/happy/?k1=v1&k2=v2')
     assert_is_in_spectre_cache('/happy/?k2=v2&k1=v1')