diff options
author | Konstantin Käfer <mail@kkaefer.com> | 2015-10-15 21:30:21 +0200 |
---|---|---|
committer | Konstantin Käfer <mail@kkaefer.com> | 2015-10-26 15:54:27 +0100 |
commit | 6a7334b882a47ca193209f2012843e42aa3ed4e2 (patch) | |
tree | f74bf484c4c53efaa657f524f8c8b01211e15b20 /test | |
parent | 096a3edf39d23fbd4baa134938c16fed4f2e199c (diff) | |
download | qtlocation-mapboxgl-6a7334b882a47ca193209f2012843e42aa3ed4e2.tar.gz |
[core] add support for stale responses
We're now returning stale responses from cache. Those responses will have the `stale` flag set to true. Currently, all requesters in the core code discard stale responses, and cancel the request immediately after they got a non-stale response.
Diffstat (limited to 'test')
-rw-r--r-- | test/storage/cache_response.cpp | 30 | ||||
-rw-r--r-- | test/storage/cache_revalidate.cpp | 139 | ||||
-rw-r--r-- | test/storage/directory_reading.cpp | 1 | ||||
-rw-r--r-- | test/storage/file_reading.cpp | 3 | ||||
-rw-r--r-- | test/storage/http_cancel.cpp | 1 | ||||
-rw-r--r-- | test/storage/http_coalescing.cpp | 105 | ||||
-rw-r--r-- | test/storage/http_error.cpp | 2 | ||||
-rw-r--r-- | test/storage/http_header_parsing.cpp | 2 | ||||
-rw-r--r-- | test/storage/http_issue_1369.cpp | 1 | ||||
-rw-r--r-- | test/storage/http_load.cpp | 1 | ||||
-rw-r--r-- | test/storage/http_other_loop.cpp | 1 | ||||
-rw-r--r-- | test/storage/http_reading.cpp | 3 |
12 files changed, 265 insertions, 24 deletions
diff --git a/test/storage/cache_response.cpp b/test/storage/cache_response.cpp index 0fba2ba5e7..1294513858 100644 --- a/test/storage/cache_response.cpp +++ b/test/storage/cache_response.cpp @@ -14,27 +14,35 @@ TEST_F(Storage, CacheResponse) { DefaultFileSource fs(&cache); const Resource resource { Resource::Unknown, "http://127.0.0.1:3000/cache" }; + Response response; Request* req = fs.request(resource, uv_default_loop(), [&](const Response &res) { fs.cancel(req); EXPECT_EQ(Response::Successful, res.status); + EXPECT_EQ(false, res.stale); EXPECT_EQ("Response 1", res.data); EXPECT_LT(0, res.expires); EXPECT_EQ(0, res.modified); EXPECT_EQ("", res.etag); EXPECT_EQ("", res.message); + response = res; + }); + + uv_run(uv_default_loop(), UV_RUN_DEFAULT); - req = fs.request(resource, uv_default_loop(), [&, res](const Response &res2) { - fs.cancel(req); - EXPECT_EQ(res.status, res2.status); - EXPECT_EQ(res.data, res2.data); - EXPECT_EQ(res.expires, res2.expires); - EXPECT_EQ(res.modified, res2.modified); - EXPECT_EQ(res.etag, res2.etag); - EXPECT_EQ(res.message, res2.message); - - CacheResponse.finish(); - }); + // Now test that we get the same values as in the previous request. If we'd go to the server + // again, we'd get different values. + req = fs.request(resource, uv_default_loop(), [&](const Response &res) { + fs.cancel(req); + EXPECT_EQ(response.status, res.status); + EXPECT_EQ(response.stale, res.stale); + EXPECT_EQ(response.data, res.data); + EXPECT_EQ(response.expires, res.expires); + EXPECT_EQ(response.modified, res.modified); + EXPECT_EQ(response.etag, res.etag); + EXPECT_EQ(response.message, res.message); + + CacheResponse.finish(); }); uv_run(uv_default_loop(), UV_RUN_DEFAULT); diff --git a/test/storage/cache_revalidate.cpp b/test/storage/cache_revalidate.cpp index 8ebedef01b..90633b83ac 100644 --- a/test/storage/cache_revalidate.cpp +++ b/test/storage/cache_revalidate.cpp @@ -5,29 +5,58 @@ #include <mbgl/storage/default_file_source.hpp> #include <mbgl/storage/sqlite_cache.hpp> -TEST_F(Storage, CacheRevalidate) { +TEST_F(Storage, CacheRevalidateSame) { SCOPED_TEST(CacheRevalidateSame) - SCOPED_TEST(CacheRevalidateModified) - SCOPED_TEST(CacheRevalidateEtag) using namespace mbgl; SQLiteCache cache(":memory:"); DefaultFileSource fs(&cache); + const Response *reference = nullptr; + const Resource revalidateSame { Resource::Unknown, "http://127.0.0.1:3000/revalidate-same" }; - Request* req = fs.request(revalidateSame, uv_default_loop(), [&](const Response &res) { - fs.cancel(req); + Request* req1 = nullptr; + Request* req2 = nullptr; + req1 = fs.request(revalidateSame, uv_default_loop(), [&](const Response &res) { + // This callback can get triggered multiple times. We only care about the first invocation. + // It will get triggered again when refreshing the req2 (see below). + static bool first = true; + if (!first) { + return; + } + first = false; + + EXPECT_EQ(nullptr, reference); + reference = &res; + EXPECT_EQ(Response::Successful, res.status); + EXPECT_EQ(false, res.stale); EXPECT_EQ("Response", res.data); EXPECT_EQ(0, res.expires); EXPECT_EQ(0, res.modified); EXPECT_EQ("snowfall", res.etag); EXPECT_EQ("", res.message); - req = fs.request(revalidateSame, uv_default_loop(), [&, res](const Response &res2) { - fs.cancel(req); + req2 = fs.request(revalidateSame, uv_default_loop(), [&, res](const Response &res2) { + // Make sure we get a different object than before, since this request should've been revalidated. + EXPECT_TRUE(reference != &res2); + + if (res2.stale) { + // Discard stale responses, if any. + return; + } + + ASSERT_TRUE(req1); + fs.cancel(req1); + req1 = nullptr; + + ASSERT_TRUE(req2); + fs.cancel(req2); + req2 = nullptr; + EXPECT_EQ(Response::Successful, res2.status); + EXPECT_EQ(false, res.stale); EXPECT_EQ("Response", res2.data); // We use this to indicate that a 304 reply came back. EXPECT_LT(0, res2.expires); @@ -40,11 +69,37 @@ TEST_F(Storage, CacheRevalidate) { }); }); + uv_run(uv_default_loop(), UV_RUN_DEFAULT); +} + +TEST_F(Storage, CacheRevalidateModified) { + SCOPED_TEST(CacheRevalidateModified) + + using namespace mbgl; + + SQLiteCache cache(":memory:"); + DefaultFileSource fs(&cache); + + const Response *reference = nullptr; + const Resource revalidateModified{ Resource::Unknown, "http://127.0.0.1:3000/revalidate-modified" }; - Request* req2 = fs.request(revalidateModified, uv_default_loop(), [&](const Response &res) { - fs.cancel(req2); + Request* req1 = nullptr; + Request* req2 = nullptr; + req1 = fs.request(revalidateModified, uv_default_loop(), [&](const Response& res) { + // This callback can get triggered multiple times. We only care about the first invocation. + // It will get triggered again when refreshing the req2 (see below). + static bool first = true; + if (!first) { + return; + } + first = false; + + EXPECT_EQ(nullptr, reference); + reference = &res; + EXPECT_EQ(Response::Successful, res.status); + EXPECT_EQ(false, res.stale); EXPECT_EQ("Response", res.data); EXPECT_EQ(0, res.expires); EXPECT_EQ(1420070400, res.modified); @@ -52,8 +107,24 @@ TEST_F(Storage, CacheRevalidate) { EXPECT_EQ("", res.message); req2 = fs.request(revalidateModified, uv_default_loop(), [&, res](const Response &res2) { + // Make sure we get a different object than before, since this request should've been revalidated. + EXPECT_TRUE(reference != &res2); + + if (res2.stale) { + // Discard stale responses, if any. + return; + } + + ASSERT_TRUE(req1); + fs.cancel(req1); + req1 = nullptr; + + ASSERT_TRUE(req2); fs.cancel(req2); + req2 = nullptr; + EXPECT_EQ(Response::Successful, res2.status); + EXPECT_EQ(false, res.stale); EXPECT_EQ("Response", res2.data); // We use this to indicate that a 304 reply came back. EXPECT_LT(0, res2.expires); @@ -65,19 +136,61 @@ TEST_F(Storage, CacheRevalidate) { }); }); + uv_run(uv_default_loop(), UV_RUN_DEFAULT); +} + +TEST_F(Storage, CacheRevalidateEtag) { + SCOPED_TEST(CacheRevalidateEtag) + + using namespace mbgl; + + SQLiteCache cache(":memory:"); + DefaultFileSource fs(&cache); + + const Response *reference = nullptr; + const Resource revalidateEtag { Resource::Unknown, "http://127.0.0.1:3000/revalidate-etag" }; - Request* req3 = fs.request(revalidateEtag, uv_default_loop(), [&](const Response &res) { - fs.cancel(req3); + Request* req1 = nullptr; + Request* req2 = nullptr; + req1 = fs.request(revalidateEtag, uv_default_loop(), [&](const Response &res) { + // This callback can get triggered multiple times. We only care about the first invocation. + // It will get triggered again when refreshing the req2 (see below). + static bool first = true; + if (!first) { + return; + } + first = false; + + EXPECT_EQ(nullptr, reference); + reference = &res; + EXPECT_EQ(Response::Successful, res.status); + EXPECT_EQ(false, res.stale); EXPECT_EQ("Response 1", res.data); EXPECT_EQ(0, res.expires); EXPECT_EQ(0, res.modified); EXPECT_EQ("response-1", res.etag); EXPECT_EQ("", res.message); - req3 = fs.request(revalidateEtag, uv_default_loop(), [&, res](const Response &res2) { - fs.cancel(req3); + req2 = fs.request(revalidateEtag, uv_default_loop(), [&, res](const Response &res2) { + // Make sure we get a different object than before, since this request should've been revalidated. + EXPECT_TRUE(reference != &res2); + + if (res2.stale) { + // Discard stale responses, if any. + return; + } + + ASSERT_TRUE(req1); + fs.cancel(req1); + req1 = nullptr; + + ASSERT_TRUE(req2); + fs.cancel(req2); + req2 = nullptr; + EXPECT_EQ(Response::Successful, res2.status); + EXPECT_EQ(false, res.stale); EXPECT_EQ("Response 2", res2.data); EXPECT_EQ(0, res2.expires); EXPECT_EQ(0, res2.modified); diff --git a/test/storage/directory_reading.cpp b/test/storage/directory_reading.cpp index 11298dff8b..f0bc7ea6d2 100644 --- a/test/storage/directory_reading.cpp +++ b/test/storage/directory_reading.cpp @@ -19,6 +19,7 @@ TEST_F(Storage, AssetReadDirectory) { [&](const Response &res) { fs.cancel(req); EXPECT_EQ(Response::Error, res.status); + EXPECT_EQ(false, res.stale); EXPECT_EQ(0ul, res.data.size()); EXPECT_EQ(0, res.expires); EXPECT_EQ(0, res.modified); diff --git a/test/storage/file_reading.cpp b/test/storage/file_reading.cpp index dc0620b78b..434af703f2 100644 --- a/test/storage/file_reading.cpp +++ b/test/storage/file_reading.cpp @@ -20,6 +20,7 @@ TEST_F(Storage, AssetEmptyFile) { [&](const Response &res) { fs.cancel(req); EXPECT_EQ(Response::Successful, res.status); + EXPECT_EQ(false, res.stale); EXPECT_EQ(0ul, res.data.size()); EXPECT_EQ(0, res.expires); EXPECT_LT(1420000000, res.modified); @@ -46,6 +47,7 @@ TEST_F(Storage, AssetNonEmptyFile) { uv_default_loop(), [&](const Response &res) { fs.cancel(req); EXPECT_EQ(Response::Successful, res.status); + EXPECT_EQ(false, res.stale); EXPECT_EQ(16ul, res.data.size()); EXPECT_EQ(0, res.expires); EXPECT_LT(1420000000, res.modified); @@ -73,6 +75,7 @@ TEST_F(Storage, AssetNonExistentFile) { uv_default_loop(), [&](const Response &res) { fs.cancel(req); EXPECT_EQ(Response::Error, res.status); + EXPECT_EQ(false, res.stale); EXPECT_EQ(0ul, res.data.size()); EXPECT_EQ(0, res.expires); EXPECT_EQ(0, res.modified); diff --git a/test/storage/http_cancel.cpp b/test/storage/http_cancel.cpp index 2eb599eeaa..5743ccb8f7 100644 --- a/test/storage/http_cancel.cpp +++ b/test/storage/http_cancel.cpp @@ -39,6 +39,7 @@ TEST_F(Storage, HTTPCancelMultiple) { Request* req = fs.request(resource, uv_default_loop(), [&](const Response &res) { fs.cancel(req); EXPECT_EQ(Response::Successful, res.status); + EXPECT_EQ(false, res.stale); EXPECT_EQ("Hello World!", res.data); EXPECT_EQ(0, res.expires); EXPECT_EQ(0, res.modified); diff --git a/test/storage/http_coalescing.cpp b/test/storage/http_coalescing.cpp index 9dfa855501..8558362034 100644 --- a/test/storage/http_coalescing.cpp +++ b/test/storage/http_coalescing.cpp @@ -50,3 +50,108 @@ TEST_F(Storage, HTTPCoalescing) { uv_run(uv_default_loop(), UV_RUN_DEFAULT); } + +TEST_F(Storage, HTTPMultiple) { + SCOPED_TEST(HTTPMultiple) + + using namespace mbgl; + + DefaultFileSource fs(nullptr); + + const Response *reference = nullptr; + + const Resource resource { Resource::Unknown, "http://127.0.0.1:3000/test?expires=2147483647" }; + Request* req1 = nullptr; + Request* req2 = nullptr; + req1 = fs.request(resource, uv_default_loop(), [&] (const Response &res) { + EXPECT_EQ(nullptr, reference); + reference = &res; + + // Do not cancel the request right away. + EXPECT_EQ(Response::Successful, res.status); + EXPECT_EQ("Hello World!", res.data); + EXPECT_EQ(2147483647, res.expires); + EXPECT_EQ(0, res.modified); + EXPECT_EQ("", res.etag); + EXPECT_EQ("", res.message); + + // Start a second request for the same resource after the first one has been completed. + req2 = fs.request(resource, uv_default_loop(), [&] (const Response &res2) { + // Make sure we get the same object ID as before. + EXPECT_EQ(reference, &res2); + + // Now cancel both requests after both have been notified. + fs.cancel(req1); + fs.cancel(req2); + + EXPECT_EQ(Response::Successful, res2.status); + EXPECT_EQ("Hello World!", res2.data); + EXPECT_EQ(2147483647, res2.expires); + EXPECT_EQ(0, res2.modified); + EXPECT_EQ("", res2.etag); + EXPECT_EQ("", res2.message); + + HTTPMultiple.finish(); + }); + }); + + uv_run(uv_default_loop(), UV_RUN_DEFAULT); +} + +// Tests that we get stale responses from previous requests when requesting the same thing again. +TEST_F(Storage, HTTPStale) { + SCOPED_TEST(HTTPStale) + + using namespace mbgl; + + DefaultFileSource fs(nullptr); + + int updates = 0; + int stale = 0; + + const Resource resource { Resource::Unknown, "http://127.0.0.1:3000/test" }; + Request* req1 = nullptr; + Request* req2 = nullptr; + req1 = fs.request(resource, uv_default_loop(), [&] (const Response &res) { + // Do not cancel the request right away. + EXPECT_EQ(Response::Successful, res.status); + EXPECT_EQ("Hello World!", res.data); + EXPECT_EQ(false, res.stale); + EXPECT_EQ(0, res.expires); + EXPECT_EQ(0, res.modified); + EXPECT_EQ("", res.etag); + EXPECT_EQ("", res.message); + + // Don't start the request twice in case this callback gets fired multiple times. + if (req2) { + return; + } + + updates++; + + // Start a second request for the same resource after the first one has been completed. + req2 = fs.request(resource, uv_default_loop(), [&] (const Response &res2) { + EXPECT_EQ(Response::Successful, res2.status); + EXPECT_EQ("Hello World!", res2.data); + EXPECT_EQ(0, res2.expires); + EXPECT_EQ(0, res2.modified); + EXPECT_EQ("", res2.etag); + EXPECT_EQ("", res2.message); + + if (res2.stale) { + EXPECT_EQ(0, stale); + stale++; + } else { + // Now cancel both requests after both have been notified. + fs.cancel(req1); + fs.cancel(req2); + HTTPStale.finish(); + } + }); + }); + + uv_run(uv_default_loop(), UV_RUN_DEFAULT); + + EXPECT_EQ(1, stale); + EXPECT_EQ(1, updates); +} diff --git a/test/storage/http_error.cpp b/test/storage/http_error.cpp index aebc75405d..50b46a41b8 100644 --- a/test/storage/http_error.cpp +++ b/test/storage/http_error.cpp @@ -37,6 +37,7 @@ TEST_F(Storage, HTTPError) { EXPECT_LT(1, duration) << "Backoff timer didn't wait 1 second"; EXPECT_GT(1.2, duration) << "Backoff timer fired too late"; EXPECT_EQ(Response::Successful, res.status); + EXPECT_EQ(false, res.stale); EXPECT_EQ("Hello World!", res.data); EXPECT_EQ(0, res.expires); EXPECT_EQ(0, res.modified); @@ -54,6 +55,7 @@ TEST_F(Storage, HTTPError) { EXPECT_LT(1.5, duration) << "Resource wasn't retried the correct number of times"; EXPECT_GT(1.7, duration) << "Resource wasn't retried the correct number of times"; EXPECT_EQ(Response::Error, res.status); + EXPECT_EQ(false, res.stale); #ifdef MBGL_HTTP_NSURL EXPECT_TRUE(res.message == "The operation couldn’t be completed. (NSURLErrorDomain error -1004.)" || diff --git a/test/storage/http_header_parsing.cpp b/test/storage/http_header_parsing.cpp index 13eab99125..93fdcb6231 100644 --- a/test/storage/http_header_parsing.cpp +++ b/test/storage/http_header_parsing.cpp @@ -20,6 +20,7 @@ TEST_F(Storage, HTTPHeaderParsing) { uv_default_loop(), [&](const Response &res) { fs.cancel(req1); EXPECT_EQ(Response::Successful, res.status); + EXPECT_EQ(false, res.stale); EXPECT_EQ("Hello World!", res.data); EXPECT_EQ(1420797926, res.expires); EXPECT_EQ(1420794326, res.modified); @@ -35,6 +36,7 @@ TEST_F(Storage, HTTPHeaderParsing) { uv_default_loop(), [&](const Response &res) { fs.cancel(req2); EXPECT_EQ(Response::Successful, res.status); + EXPECT_EQ(false, res.stale); EXPECT_EQ("Hello World!", res.data); EXPECT_GT(2, std::abs(res.expires - now - 120)) << "Expiration date isn't about 120 seconds in the future"; EXPECT_EQ(0, res.modified); diff --git a/test/storage/http_issue_1369.cpp b/test/storage/http_issue_1369.cpp index 954cb3b3f5..ba4e3d3885 100644 --- a/test/storage/http_issue_1369.cpp +++ b/test/storage/http_issue_1369.cpp @@ -33,6 +33,7 @@ TEST_F(Storage, HTTPIssue1369) { req = fs.request(resource, uv_default_loop(), [&](const Response &res) { fs.cancel(req); EXPECT_EQ(Response::Successful, res.status); + EXPECT_EQ(false, res.stale); EXPECT_EQ("Hello World!", res.data); EXPECT_EQ(0, res.expires); EXPECT_EQ(0, res.modified); diff --git a/test/storage/http_load.cpp b/test/storage/http_load.cpp index fa0468a848..092bf2db5a 100644 --- a/test/storage/http_load.cpp +++ b/test/storage/http_load.cpp @@ -25,6 +25,7 @@ TEST_F(Storage, HTTPLoad) { fs.cancel(reqs[i]); reqs[i] = nullptr; EXPECT_EQ(Response::Successful, res.status); + EXPECT_EQ(false, res.stale); EXPECT_EQ(std::string("Request ") + std::to_string(current), res.data); EXPECT_EQ(0, res.expires); EXPECT_EQ(0, res.modified); diff --git a/test/storage/http_other_loop.cpp b/test/storage/http_other_loop.cpp index 43a655fba4..cd9fad95be 100644 --- a/test/storage/http_other_loop.cpp +++ b/test/storage/http_other_loop.cpp @@ -16,6 +16,7 @@ TEST_F(Storage, HTTPOtherLoop) { [&](const Response &res) { fs.cancel(req); EXPECT_EQ(Response::Successful, res.status); + EXPECT_EQ(false, res.stale); EXPECT_EQ("Hello World!", res.data); EXPECT_EQ(0, res.expires); EXPECT_EQ(0, res.modified); diff --git a/test/storage/http_reading.cpp b/test/storage/http_reading.cpp index 84af943025..c5e89b88e8 100644 --- a/test/storage/http_reading.cpp +++ b/test/storage/http_reading.cpp @@ -23,6 +23,7 @@ TEST_F(Storage, HTTPReading) { fs.cancel(req1); EXPECT_EQ(uv_thread_self(), mainThread); EXPECT_EQ(Response::Successful, res.status); + EXPECT_EQ(false, res.stale); EXPECT_EQ("Hello World!", res.data); EXPECT_EQ(0, res.expires); EXPECT_EQ(0, res.modified); @@ -36,6 +37,7 @@ TEST_F(Storage, HTTPReading) { fs.cancel(req2); EXPECT_EQ(uv_thread_self(), mainThread); EXPECT_EQ(Response::NotFound, res.status); + EXPECT_EQ(false, res.stale); EXPECT_EQ("", res.message); EXPECT_EQ(0, res.expires); EXPECT_EQ(0, res.modified); @@ -48,6 +50,7 @@ TEST_F(Storage, HTTPReading) { fs.cancel(req3); EXPECT_EQ(uv_thread_self(), mainThread); EXPECT_EQ(Response::Error, res.status); + EXPECT_EQ(false, res.stale); EXPECT_EQ("HTTP status code 500", res.message); EXPECT_EQ(0, res.expires); EXPECT_EQ(0, res.modified); |