[core] Stop download when tile limit is reached

The tile limit guard (when used) stops a download from continuing
when the tile limit is reached. This wraps the guard in a method
and employs it in both places currently necessary to ensure the
guard has a chance to function. Tests have been updated to
ensure the fix works for a less trivial tile limit scenario.
This commit is contained in:
Jesse Bounds
2016-03-15 21:42:09 -07:00
parent 5130ca8843
commit bcb3bb0931
3 changed files with 80 additions and 11 deletions

View File

@@ -229,12 +229,8 @@ void OfflineDownload::ensureResource(const Resource& resource, std::function<voi
return;
}
if (resource.kind == Resource::Kind::Tile
&& util::mapbox::isMapboxURL(resource.url)
&& offlineDatabase.offlineMapboxTileCountLimitExceeded()) {
observer->mapboxTileCountLimitExceeded(offlineDatabase.getOfflineMapboxTileCountLimit());
setState(OfflineRegionDownloadState::Inactive);
if (checkTileCountLimit(resource)) {
return;
}
@@ -256,6 +252,10 @@ void OfflineDownload::ensureResource(const Resource& resource, std::function<voi
observer->statusChanged(status);
if (checkTileCountLimit(resource)) {
return;
}
if (status.complete()) {
setState(OfflineRegionDownloadState::Inactive);
}
@@ -263,4 +263,16 @@ void OfflineDownload::ensureResource(const Resource& resource, std::function<voi
});
}
bool OfflineDownload::checkTileCountLimit(const Resource& resource) {
if (resource.kind == Resource::Kind::Tile
&& util::mapbox::isMapboxURL(resource.url)
&& offlineDatabase.offlineMapboxTileCountLimitExceeded()) {
observer->mapboxTileCountLimitExceeded(offlineDatabase.getOfflineMapboxTileCountLimit());
setState(OfflineRegionDownloadState::Inactive);
return true;
}
return false;
}
} // namespace mbgl

View File

@@ -49,7 +49,8 @@ private:
*/
void ensureResource(const Resource&, std::function<void (Response)> = {});
void ensureTiles(SourceType, uint16_t, const SourceInfo&);
bool checkTileCountLimit(const Resource& resource);
int64_t id;
OfflineRegionDefinition definition;
OfflineDatabase& offlineDatabase;

View File

@@ -364,7 +364,7 @@ TEST(OfflineDownload, RequestErrorsAreRetried) {
test.loop.run();
}
TEST(OfflineDownload, TileCountLimitExceeded) {
TEST(OfflineDownload, TileCountLimitExceededNoTileResponse) {
OfflineTest test;
OfflineRegion region = test.createRegion();
OfflineDownload download(
@@ -372,7 +372,9 @@ TEST(OfflineDownload, TileCountLimitExceeded) {
OfflineTilePyramidRegionDefinition("http://127.0.0.1:3000/offline/style.json", LatLngBounds::world(), 0.0, 0.0, 1.0),
test.db, test.fileSource);
test.db.setOfflineMapboxTileCountLimit(0);
uint64_t tileLimit = 0;
test.db.setOfflineMapboxTileCountLimit(tileLimit);
test.fileSource.styleResponse = [&] (const Resource& resource) {
EXPECT_EQ("http://127.0.0.1:3000/offline/style.json", resource.url);
@@ -384,18 +386,72 @@ TEST(OfflineDownload, TileCountLimitExceeded) {
observer->mapboxTileCountLimitExceededFn = [&] (uint64_t limit) {
EXPECT_FALSE(mapboxTileCountLimitExceededCalled);
EXPECT_EQ(0, limit);
EXPECT_EQ(tileLimit, limit);
mapboxTileCountLimitExceededCalled = true;
};
observer->statusChangedFn = [&] (OfflineRegionStatus status) {
EXPECT_FALSE(status.complete());
if (!mapboxTileCountLimitExceededCalled) {
EXPECT_FALSE(status.complete());
EXPECT_EQ(OfflineRegionDownloadState::Active, status.downloadState);
} else {
EXPECT_EQ(OfflineRegionDownloadState::Inactive, status.downloadState);
test.loop.stop();
}
};
download.setObserver(std::move(observer));
download.setState(OfflineRegionDownloadState::Active);
test.loop.run();
}
TEST(OfflineDownload, TileCountLimitExceededWithTileResponse) {
OfflineTest test;
OfflineRegion region = test.createRegion();
OfflineDownload download(
region.getID(),
OfflineTilePyramidRegionDefinition("http://127.0.0.1:3000/offline/style.json", LatLngBounds::world(), 0.0, 0.0, 1.0),
test.db, test.fileSource);
uint64_t tileLimit = 1;
test.db.setOfflineMapboxTileCountLimit(tileLimit);
test.fileSource.styleResponse = [&] (const Resource& resource) {
EXPECT_EQ("http://127.0.0.1:3000/offline/style.json", resource.url);
return test.response("offline/mapbox_source.style.json");
};
test.fileSource.tileResponse = [&] (const Resource& resource) {
const Resource::TileData& tile = *resource.tileData;
EXPECT_EQ("mapbox://{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("offline/0-0-0.vector.pbf");
};
auto observer = std::make_unique<MockObserver>();
bool mapboxTileCountLimitExceededCalled = false;
observer->mapboxTileCountLimitExceededFn = [&] (uint64_t limit) {
EXPECT_FALSE(mapboxTileCountLimitExceededCalled);
EXPECT_EQ(tileLimit, limit);
mapboxTileCountLimitExceededCalled = true;
};
observer->statusChangedFn = [&] (OfflineRegionStatus status) {
if (!mapboxTileCountLimitExceededCalled) {
EXPECT_EQ(OfflineRegionDownloadState::Active, status.downloadState);
} else {
EXPECT_EQ(OfflineRegionDownloadState::Inactive, status.downloadState);
test.loop.stop();
}
if (status.completedResourceCount > tileLimit) {
test.loop.stop();
}
};
download.setObserver(std::move(observer));