summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMikhail Pozdnyakov <mikhail.pozdnyakov@mapbox.com>2019-12-18 16:30:32 +0200
committerMikhail Pozdnyakov <mikhail.pozdnyakov@mapbox.com>2019-12-18 18:57:33 +0200
commit1fcdb2d3b5ee29f8b730f1bbfadb0fe77144dcd4 (patch)
tree5a8c3bf2739f6aab7d85070371028086c2126c38
parenta1baafca98d4d20106b005b85abefdf3af39135b (diff)
downloadqtlocation-mapboxgl-upstream/cp_tequila_mikhail_clear_batch_buffer_at_offline_download.tar.gz
[core] Offline download must clear batch buffer at load interruptupstream/cp_tequila_mikhail_clear_batch_buffer_at_offline_download
Otherwise, the stale buffer data are processed again at the repeated load. It is causing various problems like missing load completion notification or crashes (if the previously used observer instance has been deleted).
-rw-r--r--platform/default/src/mbgl/storage/offline_download.cpp1
-rw-r--r--test/storage/offline_download.test.cpp83
2 files changed, 83 insertions, 1 deletions
diff --git a/platform/default/src/mbgl/storage/offline_download.cpp b/platform/default/src/mbgl/storage/offline_download.cpp
index d5cf7e4fe1..98eb1d3884 100644
--- a/platform/default/src/mbgl/storage/offline_download.cpp
+++ b/platform/default/src/mbgl/storage/offline_download.cpp
@@ -379,6 +379,7 @@ void OfflineDownload::deactivateDownload() {
requiredSourceURLs.clear();
resourcesRemaining.clear();
requests.clear();
+ buffer.clear();
}
void OfflineDownload::queueResource(Resource&& resource) {
diff --git a/test/storage/offline_download.test.cpp b/test/storage/offline_download.test.cpp
index ebe3f82ee9..c1a9bb73f4 100644
--- a/test/storage/offline_download.test.cpp
+++ b/test/storage/offline_download.test.cpp
@@ -757,7 +757,6 @@ TEST(OfflineDownload, Deactivate) {
test.loop.run();
}
-
TEST(OfflineDownload, AllOfflineRequestsHaveLowPriorityAndOfflineUsage) {
OfflineTest test;
auto region = test.createRegion();
@@ -947,3 +946,85 @@ TEST(OfflineDownload, ResourceOfflineUsageUnset) {
test.loop.run();
}
#endif // __QT__
+
+// Test verifies that resource batch buffer is cleared at loading interrupt.
+TEST(OfflineDownload, InterruptAndResume) {
+ OfflineTest test;
+ auto region = test.createRegion();
+ ASSERT_TRUE(region);
+ OfflineDownload download(region->getID(),
+ OfflineTilePyramidRegionDefinition(
+ "http://127.0.0.1:3000/style.json", LatLngBounds::world(), 0.0, 0.0, 1.0, true),
+ test.db,
+ test.fileSource);
+
+ test.fileSource.styleResponse = [&](const Resource& resource) {
+ EXPECT_EQ("http://127.0.0.1:3000/style.json", resource.url);
+ return test.response("style.json");
+ };
+
+ test.fileSource.spriteImageResponse = [&](const Resource& resource) {
+ EXPECT_TRUE(resource.url == "http://127.0.0.1:3000/sprite.png" ||
+ resource.url == "http://127.0.0.1:3000/sprite@2x.png");
+ return test.response("sprite.png");
+ };
+
+ test.fileSource.imageResponse = [&](const Resource& resource) {
+ EXPECT_EQ("http://127.0.0.1:3000/radar.gif", resource.url);
+ return test.response("radar.gif");
+ };
+
+ test.fileSource.spriteJSONResponse = [&](const Resource& resource) {
+ EXPECT_TRUE(resource.url == "http://127.0.0.1:3000/sprite.json" ||
+ resource.url == "http://127.0.0.1:3000/sprite@2x.json");
+ return test.response("sprite.json");
+ };
+
+ test.fileSource.glyphsResponse = [&](const Resource&) { return test.response("glyph.pbf"); };
+
+ test.fileSource.sourceResponse = [&](const Resource& resource) {
+ EXPECT_EQ("http://127.0.0.1:3000/streets.json", resource.url);
+ return test.response("streets.json");
+ };
+
+ test.fileSource.tileResponse = [&](const Resource& resource) {
+ const Resource::TileData& tile = *resource.tileData;
+ EXPECT_EQ("http://127.0.0.1:3000/{z}-{x}-{y}.vector.pbf", tile.urlTemplate);
+ EXPECT_EQ(1, tile.pixelRatio);
+ EXPECT_EQ(0, tile.x);
+ EXPECT_EQ(0, tile.y);
+ EXPECT_EQ(0, tile.z);
+ return test.response("0-0-0.vector.pbf");
+ };
+
+ auto observer = std::make_unique<MockObserver>();
+ bool interrupted = false;
+ observer->statusChangedFn = [&](OfflineRegionStatus status) {
+ if (!interrupted && status.completedResourceCount > 0) {
+ interrupted = true;
+ assert(!status.complete());
+ test.loop.schedule([&]() {
+ download.setState(OfflineRegionDownloadState::Inactive);
+ test.loop.stop();
+ });
+ }
+ };
+
+ download.setObserver(std::move(observer));
+ download.setState(OfflineRegionDownloadState::Active);
+ test.loop.run();
+
+ auto newObserver = std::make_unique<MockObserver>();
+ newObserver->statusChangedFn = [&](OfflineRegionStatus status) {
+ if (status.complete()) {
+ EXPECT_EQ(status.completedTileCount, status.requiredTileCount);
+ EXPECT_EQ(264u, status.completedResourceCount); // 256 glyphs, 2 sprite images, 2 sprite jsons, 1 tile, 1
+ // style, source, image
+ test.loop.stop();
+ }
+ };
+
+ download.setObserver(std::move(newObserver));
+ download.setState(OfflineRegionDownloadState::Active);
+ test.loop.run();
+}