diff options
author | Konstantin Käfer <mail@kkaefer.com> | 2017-08-01 18:00:48 +0200 |
---|---|---|
committer | Konstantin Käfer <mail@kkaefer.com> | 2017-08-08 12:40:38 +0200 |
commit | f0a7c45064c3ce3f509b1c2035fcaa07ccc35a99 (patch) | |
tree | 5813cfe2fd8e72cbf06f45990351b7412146c398 /test/storage | |
parent | 68f470fdda4e31d7704fba3e41bb2f899db39541 (diff) | |
download | qtlocation-mapboxgl-f0a7c45064c3ce3f509b1c2035fcaa07ccc35a99.tar.gz |
[core] finish must-revalidate support
Diffstat (limited to 'test/storage')
-rw-r--r-- | test/storage/default_file_source.test.cpp | 110 | ||||
-rw-r--r-- | test/storage/http_file_source.test.cpp | 9 | ||||
-rw-r--r-- | test/storage/offline_database.test.cpp | 69 | ||||
-rw-r--r-- | test/storage/online_file_source.test.cpp | 10 | ||||
-rwxr-xr-x | test/storage/server.js | 6 |
5 files changed, 154 insertions, 50 deletions
diff --git a/test/storage/default_file_source.test.cpp b/test/storage/default_file_source.test.cpp index 41e305a692..b8aebae7e7 100644 --- a/test/storage/default_file_source.test.cpp +++ b/test/storage/default_file_source.test.cpp @@ -22,6 +22,7 @@ TEST(DefaultFileSource, TEST_REQUIRES_SERVER(CacheResponse)) { ASSERT_TRUE(res.data.get()); EXPECT_EQ("Response 1", *res.data); EXPECT_TRUE(bool(res.expires)); + EXPECT_FALSE(res.mustRevalidate); EXPECT_FALSE(bool(res.modified)); EXPECT_FALSE(bool(res.etag)); response = res; @@ -34,6 +35,7 @@ TEST(DefaultFileSource, TEST_REQUIRES_SERVER(CacheResponse)) { ASSERT_TRUE(res2.data.get()); EXPECT_EQ(*response.data, *res2.data); EXPECT_EQ(response.expires, res2.expires); + EXPECT_EQ(response.mustRevalidate, res2.mustRevalidate); EXPECT_EQ(response.modified, res2.modified); EXPECT_EQ(response.etag, res2.etag); @@ -51,35 +53,53 @@ TEST(DefaultFileSource, TEST_REQUIRES_SERVER(CacheRevalidateSame)) { const Resource revalidateSame { Resource::Unknown, "http://127.0.0.1:3000/revalidate-same" }; std::unique_ptr<AsyncRequest> req1; std::unique_ptr<AsyncRequest> req2; - uint16_t counter = 0; + bool gotResponse = false; // First request causes the response to get cached. req1 = fs.request(revalidateSame, [&](Response res) { req1.reset(); EXPECT_EQ(nullptr, res.error); + EXPECT_FALSE(res.notModified); ASSERT_TRUE(res.data.get()); EXPECT_EQ("Response", *res.data); EXPECT_FALSE(bool(res.expires)); + EXPECT_TRUE(res.mustRevalidate); EXPECT_FALSE(bool(res.modified)); EXPECT_EQ("snowfall", *res.etag); - // Second request returns the cached response, then immediately revalidates. - req2 = fs.request(revalidateSame, [&, res](Response res2) { - if (counter == 0) { - ++counter; + // The first response is stored in the cache, but it has 'must-revalidate' set. This means + // it can't return the cached response right away and we must wait for the revalidation + // request to complete. We can distinguish the cached response from the revalided response + // because the latter has an expiration date, while the cached response doesn't. + req2 = fs.request(revalidateSame, [&](Response res2) { + if (!gotResponse) { + // Even though we could find the response in the database, we send a revalidation + // request and get a 304 response. Since we haven't sent a reply yet, we're forcing + // notModified to be false so that implementations can continue to use the + // notModified flag to skip parsing new data. + gotResponse = true; + EXPECT_EQ(nullptr, res2.error); EXPECT_FALSE(res2.notModified); + ASSERT_TRUE(res2.data.get()); + EXPECT_EQ("Response", *res2.data); + EXPECT_TRUE(bool(res2.expires)); + EXPECT_TRUE(res2.mustRevalidate); + EXPECT_FALSE(bool(res2.modified)); + EXPECT_EQ("snowfall", *res2.etag); } else { + // The test server sends a Cache-Control header with a max-age of 1 second. This + // means that our OnlineFileSource implementation will request the tile again after + // 1 second. This time, our request already had a prior response, so we don't need + // to send the data again, and instead can actually forward the notModified flag. req2.reset(); - EXPECT_EQ(nullptr, res2.error); EXPECT_TRUE(res2.notModified); - ASSERT_FALSE(res2.data.get()); + EXPECT_FALSE(res2.data.get()); EXPECT_TRUE(bool(res2.expires)); + EXPECT_TRUE(res2.mustRevalidate); EXPECT_FALSE(bool(res2.modified)); - // We're not sending the ETag in the 304 reply, but it should still be there. EXPECT_EQ("snowfall", *res2.etag); - loop.stop(); } }); @@ -96,34 +116,53 @@ TEST(DefaultFileSource, TEST_REQUIRES_SERVER(CacheRevalidateModified)) { "http://127.0.0.1:3000/revalidate-modified" }; std::unique_ptr<AsyncRequest> req1; std::unique_ptr<AsyncRequest> req2; - uint16_t counter = 0; + bool gotResponse = false; // First request causes the response to get cached. req1 = fs.request(revalidateModified, [&](Response res) { req1.reset(); EXPECT_EQ(nullptr, res.error); + EXPECT_FALSE(res.notModified); ASSERT_TRUE(res.data.get()); EXPECT_EQ("Response", *res.data); EXPECT_FALSE(bool(res.expires)); + EXPECT_TRUE(res.mustRevalidate); EXPECT_EQ(Timestamp{ Seconds(1420070400) }, *res.modified); EXPECT_FALSE(res.etag); - // Second request returns the cached response, then immediately revalidates. + // The first response is stored in the cache, but it has 'must-revalidate' set. This means + // it can't return the cached response right away and we must wait for the revalidation + // request to complete. We can distinguish the cached response from the revalided response + // because the latter has an expiration date, while the cached response doesn't. req2 = fs.request(revalidateModified, [&, res](Response res2) { - if (counter == 0) { - ++counter; + if (!gotResponse) { + // Even though we could find the response in the database, we send a revalidation + // request and get a 304 response. Since we haven't sent a reply yet, we're forcing + // notModified to be false so that implementations can continue to use the + // notModified flag to skip parsing new data. + gotResponse = true; + EXPECT_EQ(nullptr, res2.error); EXPECT_FALSE(res2.notModified); + ASSERT_TRUE(res2.data.get()); + EXPECT_EQ("Response", *res2.data); + EXPECT_TRUE(bool(res2.expires)); + EXPECT_TRUE(res2.mustRevalidate); + EXPECT_EQ(Timestamp{ Seconds(1420070400) }, *res2.modified); + EXPECT_FALSE(res2.etag); } else { + // The test server sends a Cache-Control header with a max-age of 1 second. This + // means that our OnlineFileSource implementation will request the tile again after + // 1 second. This time, our request already had a prior response, so we don't need + // to send the data again, and instead can actually forward the notModified flag. req2.reset(); - EXPECT_EQ(nullptr, res2.error); EXPECT_TRUE(res2.notModified); - ASSERT_FALSE(res2.data.get()); + EXPECT_FALSE(res2.data.get()); EXPECT_TRUE(bool(res2.expires)); + EXPECT_TRUE(res2.mustRevalidate); EXPECT_EQ(Timestamp{ Seconds(1420070400) }, *res2.modified); EXPECT_FALSE(res2.etag); - loop.stop(); } }); @@ -139,7 +178,6 @@ TEST(DefaultFileSource, TEST_REQUIRES_SERVER(CacheRevalidateEtag)) { const Resource revalidateEtag { Resource::Unknown, "http://127.0.0.1:3000/revalidate-etag" }; std::unique_ptr<AsyncRequest> req1; std::unique_ptr<AsyncRequest> req2; - uint16_t counter = 0; // First request causes the response to get cached. req1 = fs.request(revalidateEtag, [&](Response res) { @@ -149,27 +187,24 @@ TEST(DefaultFileSource, TEST_REQUIRES_SERVER(CacheRevalidateEtag)) { ASSERT_TRUE(res.data.get()); EXPECT_EQ("Response 1", *res.data); EXPECT_FALSE(bool(res.expires)); + EXPECT_TRUE(res.mustRevalidate); EXPECT_FALSE(bool(res.modified)); EXPECT_EQ("response-1", *res.etag); - // Second request returns the cached response, then immediately revalidates. + // Second request does not return the cached response, since it had Cache-Control: must-revalidate set. req2 = fs.request(revalidateEtag, [&, res](Response res2) { - if (counter == 0) { - ++counter; - EXPECT_FALSE(res2.notModified); - } else { - req2.reset(); + req2.reset(); - EXPECT_EQ(nullptr, res2.error); - ASSERT_TRUE(res2.data.get()); - EXPECT_NE(res.data, res2.data); - EXPECT_EQ("Response 2", *res2.data); - EXPECT_FALSE(bool(res2.expires)); - EXPECT_FALSE(bool(res2.modified)); - EXPECT_EQ("response-2", *res2.etag); + EXPECT_EQ(nullptr, res2.error); + ASSERT_TRUE(res2.data.get()); + EXPECT_NE(res.data, res2.data); + EXPECT_EQ("Response 2", *res2.data); + EXPECT_FALSE(bool(res2.expires)); + EXPECT_TRUE(res2.mustRevalidate); + EXPECT_FALSE(bool(res2.modified)); + EXPECT_EQ("response-2", *res2.etag); - loop.stop(); - } + loop.stop(); }); }); @@ -203,6 +238,7 @@ TEST(DefaultFileSource, TEST_REQUIRES_SERVER(HTTPIssue1369)) { ASSERT_TRUE(res.data.get()); EXPECT_EQ("Hello World!", *res.data); EXPECT_FALSE(bool(res.expires)); + EXPECT_FALSE(res.mustRevalidate); EXPECT_FALSE(bool(res.modified)); EXPECT_FALSE(bool(res.etag)); loop.stop(); @@ -232,6 +268,7 @@ TEST(DefaultFileSource, OptionalNonExpired) { EXPECT_EQ("Cached value", *res.data); ASSERT_TRUE(bool(res.expires)); EXPECT_EQ(*response.expires, *res.expires); + EXPECT_FALSE(res.mustRevalidate); EXPECT_FALSE(bool(res.modified)); EXPECT_FALSE(bool(res.etag)); loop.stop(); @@ -261,6 +298,7 @@ TEST(DefaultFileSource, OptionalExpired) { EXPECT_EQ("Cached value", *res.data); ASSERT_TRUE(bool(res.expires)); EXPECT_EQ(*response.expires, *res.expires); + EXPECT_FALSE(res.mustRevalidate); EXPECT_FALSE(bool(res.modified)); EXPECT_FALSE(bool(res.etag)); loop.stop(); @@ -301,6 +339,7 @@ TEST(DefaultFileSource, OptionalNotFound) { EXPECT_EQ("Not found in offline database", res.error->message); EXPECT_FALSE(res.data); EXPECT_FALSE(bool(res.expires)); + EXPECT_FALSE(res.mustRevalidate); EXPECT_FALSE(bool(res.modified)); EXPECT_FALSE(bool(res.etag)); loop.stop(); @@ -334,6 +373,7 @@ TEST(DefaultFileSource, TEST_REQUIRES_SERVER(NoCacheRefreshEtagNotModified)) { EXPECT_FALSE(res.data.get()); ASSERT_TRUE(bool(res.expires)); EXPECT_LT(util::now(), *res.expires); + EXPECT_TRUE(res.mustRevalidate); EXPECT_FALSE(bool(res.modified)); ASSERT_TRUE(bool(res.etag)); EXPECT_EQ("snowfall", *res.etag); @@ -368,6 +408,7 @@ TEST(DefaultFileSource, TEST_REQUIRES_SERVER(NoCacheRefreshEtagModified)) { ASSERT_TRUE(res.data.get()); EXPECT_EQ("Response", *res.data); EXPECT_FALSE(bool(res.expires)); + EXPECT_TRUE(res.mustRevalidate); EXPECT_FALSE(bool(res.modified)); ASSERT_TRUE(bool(res.etag)); EXPECT_EQ("snowfall", *res.etag); @@ -403,6 +444,7 @@ TEST(DefaultFileSource, TEST_REQUIRES_SERVER(NoCacheFull)) { ASSERT_TRUE(res.data.get()); EXPECT_EQ("Response", *res.data); EXPECT_FALSE(bool(res.expires)); + EXPECT_TRUE(res.mustRevalidate); EXPECT_FALSE(bool(res.modified)); ASSERT_TRUE(bool(res.etag)); EXPECT_EQ("snowfall", *res.etag); @@ -437,6 +479,7 @@ TEST(DefaultFileSource, TEST_REQUIRES_SERVER(NoCacheRefreshModifiedNotModified)) EXPECT_FALSE(res.data.get()); ASSERT_TRUE(bool(res.expires)); EXPECT_LT(util::now(), *res.expires); + EXPECT_TRUE(res.mustRevalidate); ASSERT_TRUE(bool(res.modified)); EXPECT_EQ(Timestamp{ Seconds(1420070400) }, *res.modified); EXPECT_FALSE(bool(res.etag)); @@ -471,6 +514,7 @@ TEST(DefaultFileSource, TEST_REQUIRES_SERVER(NoCacheRefreshModifiedModified)) { ASSERT_TRUE(res.data.get()); EXPECT_EQ("Response", *res.data); EXPECT_FALSE(bool(res.expires)); + EXPECT_TRUE(res.mustRevalidate); EXPECT_EQ(Timestamp{ Seconds(1420070400) }, *res.modified); EXPECT_FALSE(res.etag); loop.stop(); @@ -502,6 +546,7 @@ TEST(DefaultFileSource, TEST_REQUIRES_SERVER(SetResourceTransform)) { ASSERT_TRUE(res.data.get()); EXPECT_EQ("Hello World!", *res.data); EXPECT_FALSE(bool(res.expires)); + EXPECT_FALSE(res.mustRevalidate); EXPECT_FALSE(bool(res.modified)); EXPECT_FALSE(bool(res.etag)); loop.stop(); @@ -518,6 +563,7 @@ TEST(DefaultFileSource, TEST_REQUIRES_SERVER(SetResourceTransform)) { ASSERT_TRUE(res.data.get()); EXPECT_EQ("Hello World!", *res.data); EXPECT_FALSE(bool(res.expires)); + EXPECT_FALSE(res.mustRevalidate); EXPECT_FALSE(bool(res.modified)); EXPECT_FALSE(bool(res.etag)); loop.stop(); diff --git a/test/storage/http_file_source.test.cpp b/test/storage/http_file_source.test.cpp index 5b081d7d57..006b7a0fb3 100644 --- a/test/storage/http_file_source.test.cpp +++ b/test/storage/http_file_source.test.cpp @@ -26,6 +26,7 @@ TEST(HTTPFileSource, TEST_REQUIRES_SERVER(HTTP200)) { ASSERT_TRUE(res.data.get()); EXPECT_EQ("Hello World!", *res.data); EXPECT_FALSE(bool(res.expires)); + EXPECT_FALSE(res.mustRevalidate); EXPECT_FALSE(bool(res.modified)); EXPECT_FALSE(bool(res.etag)); loop.stop(); @@ -44,6 +45,7 @@ TEST(HTTPFileSource, TEST_REQUIRES_SERVER(HTTP404)) { EXPECT_EQ("HTTP status code 404", res.error->message); EXPECT_FALSE(bool(res.data)); EXPECT_FALSE(bool(res.expires)); + EXPECT_FALSE(res.mustRevalidate); EXPECT_FALSE(bool(res.modified)); EXPECT_FALSE(bool(res.etag)); loop.stop(); @@ -61,6 +63,7 @@ TEST(HTTPFileSource, TEST_REQUIRES_SERVER(HTTPTile404)) { EXPECT_FALSE(bool(res.error)); EXPECT_FALSE(bool(res.data)); EXPECT_FALSE(bool(res.expires)); + EXPECT_FALSE(res.mustRevalidate); EXPECT_FALSE(bool(res.modified)); EXPECT_FALSE(bool(res.etag)); loop.stop(); @@ -78,6 +81,7 @@ TEST(HTTPFileSource, TEST_REQUIRES_SERVER(HTTP200EmptyData)) { EXPECT_FALSE(bool(res.error)); EXPECT_EQ(*res.data, std::string()); EXPECT_FALSE(bool(res.expires)); + EXPECT_FALSE(res.mustRevalidate); EXPECT_FALSE(bool(res.modified)); EXPECT_FALSE(bool(res.etag)); loop.stop(); @@ -95,6 +99,7 @@ TEST(HTTPFileSource, TEST_REQUIRES_SERVER(HTTP204)) { EXPECT_FALSE(bool(res.error)); EXPECT_FALSE(bool(res.data)); EXPECT_FALSE(bool(res.expires)); + EXPECT_FALSE(res.mustRevalidate); EXPECT_FALSE(bool(res.modified)); EXPECT_FALSE(bool(res.etag)); loop.stop(); @@ -113,6 +118,7 @@ TEST(HTTPFileSource, TEST_REQUIRES_SERVER(HTTP500)) { EXPECT_EQ("HTTP status code 500", res.error->message); EXPECT_FALSE(bool(res.data)); EXPECT_FALSE(bool(res.expires)); + EXPECT_FALSE(res.mustRevalidate); EXPECT_FALSE(bool(res.modified)); EXPECT_FALSE(bool(res.etag)); loop.stop(); @@ -131,6 +137,7 @@ TEST(HTTPFileSource, TEST_REQUIRES_SERVER(ExpiresParsing)) { ASSERT_TRUE(res.data.get()); EXPECT_EQ("Hello World!", *res.data); EXPECT_EQ(Timestamp{ Seconds(1420797926) }, res.expires); + EXPECT_FALSE(res.mustRevalidate); EXPECT_EQ(Timestamp{ Seconds(1420794326) }, res.modified); EXPECT_EQ("foo", *res.etag); loop.stop(); @@ -148,6 +155,7 @@ TEST(HTTPFileSource, TEST_REQUIRES_SERVER(CacheControlParsing)) { ASSERT_TRUE(res.data.get()); EXPECT_EQ("Hello World!", *res.data); EXPECT_GT(Seconds(2), util::abs(*res.expires - util::now() - Seconds(120))) << "Expiration date isn't about 120 seconds in the future"; + EXPECT_FALSE(res.mustRevalidate); EXPECT_FALSE(bool(res.modified)); EXPECT_FALSE(bool(res.etag)); loop.stop(); @@ -176,6 +184,7 @@ TEST(HTTPFileSource, TEST_REQUIRES_SERVER(Load)) { ASSERT_TRUE(res.data.get()); EXPECT_EQ(std::string("Request ") + std::to_string(current), *res.data); EXPECT_FALSE(bool(res.expires)); + EXPECT_FALSE(res.mustRevalidate); EXPECT_FALSE(bool(res.modified)); EXPECT_FALSE(bool(res.etag)); diff --git a/test/storage/offline_database.test.cpp b/test/storage/offline_database.test.cpp index 872310e46f..c196107639 100644 --- a/test/storage/offline_database.test.cpp +++ b/test/storage/offline_database.test.cpp @@ -634,24 +634,35 @@ static int databaseSyncMode(const std::string& path) { return stmt.get<int>(0); } +static std::vector<std::string> databaseTableColumns(const std::string& path, const std::string& name) { + mapbox::sqlite::Database db(path, mapbox::sqlite::ReadOnly); + const auto sql = std::string("pragma table_info(") + name + ")"; + mapbox::sqlite::Statement stmt = db.prepare(sql.c_str()); + std::vector<std::string> columns; + while (stmt.run()) { + columns.push_back(stmt.get<std::string>(1)); + } + return columns; +} + TEST(OfflineDatabase, MigrateFromV2Schema) { using namespace mbgl; // v2.db is a v2 database containing a single offline region with a small number of resources. - deleteFile("test/fixtures/offline_database/v5.db"); - writeFile("test/fixtures/offline_database/v5.db", util::read_file("test/fixtures/offline_database/v2.db")); + deleteFile("test/fixtures/offline_database/migrated.db"); + writeFile("test/fixtures/offline_database/migrated.db", util::read_file("test/fixtures/offline_database/v2.db")); { - OfflineDatabase db("test/fixtures/offline_database/v5.db", 0); + OfflineDatabase db("test/fixtures/offline_database/migrated.db", 0); auto regions = db.listRegions(); for (auto& region : regions) { db.deleteRegion(std::move(region)); } } - EXPECT_EQ(5, databaseUserVersion("test/fixtures/offline_database/v5.db")); - EXPECT_LT(databasePageCount("test/fixtures/offline_database/v5.db"), + EXPECT_EQ(6, databaseUserVersion("test/fixtures/offline_database/migrated.db")); + EXPECT_LT(databasePageCount("test/fixtures/offline_database/migrated.db"), databasePageCount("test/fixtures/offline_database/v2.db")); } @@ -660,18 +671,18 @@ TEST(OfflineDatabase, MigrateFromV3Schema) { // v3.db is a v3 database, migrated from v2. - deleteFile("test/fixtures/offline_database/v5.db"); - writeFile("test/fixtures/offline_database/v5.db", util::read_file("test/fixtures/offline_database/v3.db")); + deleteFile("test/fixtures/offline_database/migrated.db"); + writeFile("test/fixtures/offline_database/migrated.db", util::read_file("test/fixtures/offline_database/v3.db")); { - OfflineDatabase db("test/fixtures/offline_database/v5.db", 0); + OfflineDatabase db("test/fixtures/offline_database/migrated.db", 0); auto regions = db.listRegions(); for (auto& region : regions) { db.deleteRegion(std::move(region)); } } - EXPECT_EQ(5, databaseUserVersion("test/fixtures/offline_database/v5.db")); + EXPECT_EQ(6, databaseUserVersion("test/fixtures/offline_database/migrated.db")); } TEST(OfflineDatabase, MigrateFromV4Schema) { @@ -679,22 +690,50 @@ TEST(OfflineDatabase, MigrateFromV4Schema) { // v4.db is a v4 database, migrated from v2 & v3. This database used `journal_mode = WAL` and `synchronous = NORMAL`. - deleteFile("test/fixtures/offline_database/v5.db"); - writeFile("test/fixtures/offline_database/v5.db", util::read_file("test/fixtures/offline_database/v4.db")); + deleteFile("test/fixtures/offline_database/migrated.db"); + writeFile("test/fixtures/offline_database/migrated.db", util::read_file("test/fixtures/offline_database/v4.db")); { - OfflineDatabase db("test/fixtures/offline_database/v5.db", 0); + OfflineDatabase db("test/fixtures/offline_database/migrated.db", 0); auto regions = db.listRegions(); for (auto& region : regions) { db.deleteRegion(std::move(region)); } } - EXPECT_EQ(5, databaseUserVersion("test/fixtures/offline_database/v5.db")); + EXPECT_EQ(6, databaseUserVersion("test/fixtures/offline_database/migrated.db")); // Journal mode should be DELETE after migration to v5. - EXPECT_EQ("delete", databaseJournalMode("test/fixtures/offline_database/v5.db")); + EXPECT_EQ("delete", databaseJournalMode("test/fixtures/offline_database/migrated.db")); // Synchronous setting should be FULL (2) after migration to v5. - EXPECT_EQ(2, databaseSyncMode("test/fixtures/offline_database/v5.db")); + EXPECT_EQ(2, databaseSyncMode("test/fixtures/offline_database/migrated.db")); +} + + +TEST(OfflineDatabase, MigrateFromV5Schema) { + using namespace mbgl; + + // v5.db is a v5 database, migrated from v2, v3 & v4. + + deleteFile("test/fixtures/offline_database/migrated.db"); + writeFile("test/fixtures/offline_database/migrated.db", util::read_file("test/fixtures/offline_database/v5.db")); + + { + OfflineDatabase db("test/fixtures/offline_database/migrated.db", 0); + auto regions = db.listRegions(); + for (auto& region : regions) { + db.deleteRegion(std::move(region)); + } + } + + EXPECT_EQ(6, databaseUserVersion("test/fixtures/offline_database/migrated.db")); + + EXPECT_EQ((std::vector<std::string>{ "id", "url_template", "pixel_ratio", "z", "x", "y", + "expires", "modified", "etag", "data", "compressed", + "accessed", "must_revalidate" }), + databaseTableColumns("test/fixtures/offline_database/migrated.db", "tiles")); + EXPECT_EQ((std::vector<std::string>{ "id", "url", "kind", "expires", "modified", "etag", "data", + "compressed", "accessed", "must_revalidate" }), + databaseTableColumns("test/fixtures/offline_database/migrated.db", "resources")); } diff --git a/test/storage/online_file_source.test.cpp b/test/storage/online_file_source.test.cpp index 1a1d2d42f8..70bfe3ac95 100644 --- a/test/storage/online_file_source.test.cpp +++ b/test/storage/online_file_source.test.cpp @@ -36,6 +36,7 @@ TEST(OnlineFileSource, TEST_REQUIRES_SERVER(CancelMultiple)) { ASSERT_TRUE(res.data.get()); EXPECT_EQ("Hello World!", *res.data); EXPECT_FALSE(bool(res.expires)); + EXPECT_FALSE(res.mustRevalidate); EXPECT_FALSE(bool(res.modified)); EXPECT_FALSE(bool(res.etag)); loop.stop(); @@ -62,6 +63,7 @@ TEST(OnlineFileSource, TEST_REQUIRES_SERVER(TemporaryError)) { EXPECT_EQ("HTTP status code 500", res.error->message); ASSERT_FALSE(bool(res.data)); EXPECT_FALSE(bool(res.expires)); + EXPECT_FALSE(res.mustRevalidate); EXPECT_FALSE(bool(res.modified)); EXPECT_FALSE(bool(res.etag)); } break; @@ -73,6 +75,7 @@ TEST(OnlineFileSource, TEST_REQUIRES_SERVER(TemporaryError)) { ASSERT_TRUE(res.data.get()); EXPECT_EQ("Hello World!", *res.data); EXPECT_FALSE(bool(res.expires)); + EXPECT_FALSE(res.mustRevalidate); EXPECT_FALSE(bool(res.modified)); EXPECT_FALSE(bool(res.etag)); loop.stop(); @@ -99,6 +102,7 @@ TEST(OnlineFileSource, TEST_REQUIRES_SERVER(ConnectionError)) { EXPECT_EQ(Response::Error::Reason::Connection, res.error->reason); ASSERT_FALSE(res.data.get()); EXPECT_FALSE(bool(res.expires)); + EXPECT_FALSE(res.mustRevalidate); EXPECT_FALSE(bool(res.modified)); EXPECT_FALSE(bool(res.etag)); @@ -126,6 +130,7 @@ TEST(OnlineFileSource, TEST_REQUIRES_SERVER(Timeout)) { ASSERT_TRUE(res.data.get()); EXPECT_EQ("Hello World!", *res.data); EXPECT_TRUE(bool(res.expires)); + EXPECT_FALSE(res.mustRevalidate); EXPECT_FALSE(bool(res.modified)); EXPECT_FALSE(bool(res.etag)); if (counter == 4) { @@ -150,6 +155,7 @@ TEST(OnlineFileSource, TEST_REQUIRES_SERVER(RetryDelayOnExpiredTile)) { counter++; EXPECT_EQ(nullptr, res.error); EXPECT_GT(util::now(), *res.expires); + EXPECT_FALSE(res.mustRevalidate); }); util::Timer timer; @@ -170,6 +176,7 @@ TEST(OnlineFileSource, TEST_REQUIRES_SERVER(RetryOnClockSkew)) { const Resource resource { Resource::Unknown, "http://127.0.0.1:3000/clockskew" }; std::unique_ptr<AsyncRequest> req1 = fs.request(resource, [&](Response res) { + EXPECT_FALSE(res.mustRevalidate); switch (counter++) { case 0: { EXPECT_EQ(nullptr, res.error); @@ -240,6 +247,7 @@ TEST(OnlineFileSource, TEST_REQUIRES_SERVER(Load)) { ASSERT_TRUE(res.data.get()); EXPECT_EQ(std::string("Request ") + std::to_string(current), *res.data); EXPECT_FALSE(bool(res.expires)); + EXPECT_FALSE(res.mustRevalidate); EXPECT_FALSE(bool(res.modified)); EXPECT_FALSE(bool(res.etag)); @@ -277,6 +285,7 @@ TEST(OnlineFileSource, TEST_REQUIRES_SERVER(NetworkStatusChange)) { ASSERT_TRUE(res.data.get()); EXPECT_EQ("Response", *res.data); EXPECT_FALSE(bool(res.expires)); + EXPECT_FALSE(res.mustRevalidate); EXPECT_FALSE(bool(res.modified)); EXPECT_FALSE(bool(res.etag)); loop.stop(); @@ -315,6 +324,7 @@ TEST(OnlineFileSource, TEST_REQUIRES_SERVER(NetworkStatusChangePreempt)) { EXPECT_EQ(Response::Error::Reason::Connection, res.error->reason); ASSERT_FALSE(res.data.get()); EXPECT_FALSE(bool(res.expires)); + EXPECT_FALSE(res.mustRevalidate); EXPECT_FALSE(bool(res.modified)); EXPECT_FALSE(bool(res.etag)); diff --git a/test/storage/server.js b/test/storage/server.js index b54ff835ec..d6429e4635 100755 --- a/test/storage/server.js +++ b/test/storage/server.js @@ -44,8 +44,8 @@ app.get('/cache', function(req, res) { app.get('/revalidate-same', function(req, res) { if (req.headers['if-none-match'] == 'snowfall') { - // Second request can be cached for 30 seconds. - res.setHeader('Cache-Control', 'max-age=30'); + // Second request can be cached for 1 second. + res.setHeader('Cache-Control', 'max-age=1, must-revalidate'); res.status(304).end(); } else { // First request must always be revalidated. @@ -67,7 +67,7 @@ app.get('/revalidate-modified', function(req, res) { if (req.headers['if-modified-since']) { var modified_since = new Date(req.headers['if-modified-since']); if (modified_since >= jan1) { - res.setHeader('Cache-Control', 'max-age=30'); + res.setHeader('Cache-Control', 'max-age=1, must-revalidate'); res.status(304).end(); return; } |