[core] Replace time_t with std::chrono::seconds

Added aliases for std::chrono typedefs (eg. 'Seconds' for
std::chrono::seconds). These aliases are used together with templated
helper functions to replace time_t with std::chrono::seconds for most
cases, in particular for 'modified' and 'expires' values in Response.
This commit is contained in:
Bruno de Oliveira Abinader
2015-11-25 13:30:32 +02:00
parent 4475f54860
commit 31fd2822f5
30 changed files with 184 additions and 121 deletions

View File

@@ -1,6 +1,8 @@
#ifndef MBGL_STORAGE_RESPONSE
#define MBGL_STORAGE_RESPONSE
#include <mbgl/util/chrono.hpp>
#include <string>
#include <memory>
@@ -25,8 +27,8 @@ public:
// The actual data of the response. This is guaranteed to never be empty.
std::shared_ptr<const std::string> data;
int64_t modified = 0;
int64_t expires = 0;
Seconds modified = Seconds::zero();
Seconds expires = Seconds::zero();
std::string etag;
};

View File

@@ -8,9 +8,40 @@ namespace mbgl {
using Clock = std::chrono::steady_clock;
using SystemClock = std::chrono::system_clock;
using Seconds = std::chrono::seconds;
using Milliseconds = std::chrono::milliseconds;
using TimePoint = Clock::time_point;
using Duration = Clock::duration;
using SystemTimePoint = SystemClock::time_point;
using SystemDuration = SystemClock::duration;
template <class _Clock, class _Duration>
_Duration toDuration(std::chrono::time_point<_Clock, _Duration> time_point) {
return time_point.time_since_epoch();
}
template <class _Duration>
Seconds asSeconds(_Duration duration) {
return std::chrono::duration_cast<Seconds>(duration);
}
template <class _Clock, class _Duration>
Seconds toSeconds(std::chrono::time_point<_Clock, _Duration> time_point) {
return asSeconds(toDuration<_Clock, _Duration>(time_point));
}
template <class _Duration>
Milliseconds asMilliseconds(_Duration duration) {
return std::chrono::duration_cast<Milliseconds>(duration);
}
template <class _Clock, class _Duration>
Milliseconds toMilliseconds(std::chrono::time_point<_Clock, _Duration> time_point) {
return asMilliseconds(toDuration<_Clock, _Duration>(time_point));
}
}
#endif

View File

@@ -129,8 +129,8 @@ HTTPAndroidRequest::HTTPAndroidRequest(HTTPAndroidContext* context_, const Resou
if (existingResponse) {
if (!existingResponse->etag.empty()) {
etagStr = existingResponse->etag;
} else if (existingResponse->modified) {
modifiedStr = util::rfc1123(existingResponse->modified);
} else if (existingResponse->modified != Seconds::zero()) {
modifiedStr = util::rfc1123(existingResponse->modified.count());
}
}
@@ -195,11 +195,11 @@ void HTTPAndroidRequest::onResponse(int code, std::string message, std::string e
response = std::make_unique<Response>();
using Error = Response::Error;
response->modified = parse_date(modified.c_str());
response->modified = Seconds(parse_date(modified.c_str()));
response->etag = etag;
response->expires = parseCacheControl(cacheControl.c_str());
if (!expires.empty()) {
response->expires = parse_date(expires.c_str());
response->expires = Seconds(parse_date(expires.c_str()));
}
response->data = std::make_shared<std::string>(body);

View File

@@ -114,8 +114,8 @@ HTTPNSURLRequest::HTTPNSURLRequest(HTTPNSURLContext* context_,
if (!existingResponse->etag.empty()) {
[req addValue:@(existingResponse->etag.c_str())
forHTTPHeaderField:@"If-None-Match"];
} else if (existingResponse->modified) {
const std::string time = util::rfc1123(existingResponse->modified);
} else if (existingResponse->modified != Seconds::zero()) {
const std::string time = util::rfc1123(existingResponse->modified.count());
[req addValue:@(time.c_str()) forHTTPHeaderField:@"If-Modified-Since"];
}
}
@@ -214,12 +214,12 @@ void HTTPNSURLRequest::handleResult(NSData *data, NSURLResponse *res, NSError *e
NSString *expires = [headers objectForKey:@"Expires"];
if (expires) {
response->expires = parse_date([expires UTF8String]);
response->expires = Seconds(parse_date([expires UTF8String]));
}
NSString *last_modified = [headers objectForKey:@"Last-Modified"];
if (last_modified) {
response->modified = parse_date([last_modified UTF8String]);
response->modified = Seconds(parse_date([last_modified UTF8String]));
}
NSString *etag = [headers objectForKey:@"ETag"];

View File

@@ -130,12 +130,12 @@ void AssetRequest::fileStated(uv_fs_t *req) {
self->response = std::make_unique<Response>();
#if UV_VERSION_MAJOR == 0 && UV_VERSION_MINOR <= 10
#ifdef __APPLE__
self->response->modified = stat->st_mtimespec.tv_sec;
self->response->modified = Seconds(stat->st_mtimespec.tv_sec);
#else
self->response->modified = stat->st_mtime;
self->response->modified = Seconds(stat->st_mtime);
#endif
#else
self->response->modified = stat->st_mtim.tv_sec;
self->response->modified = Seconds(stat->st_mtim.tv_sec);
#endif
self->response->etag = util::toString(stat->st_ino);
const auto size = (unsigned int)(stat->st_size);

View File

@@ -3,6 +3,7 @@
#include <mbgl/storage/resource.hpp>
#include <mbgl/storage/response.hpp>
#include <mbgl/platform/log.hpp>
#include <mbgl/util/chrono.hpp>
#include <mbgl/util/util.hpp>
#include <mbgl/util/uv.hpp>
@@ -187,7 +188,7 @@ void AssetRequest::fileStated(uv_zip_t *zip) {
// Get the modification time in case we have one.
if (zip->stat->valid & ZIP_STAT_MTIME) {
response->modified = zip->stat->mtime;
response->modified = Seconds(zip->stat->mtime);
}
if (zip->stat->valid & ZIP_STAT_INDEX) {

View File

@@ -425,9 +425,9 @@ HTTPCURLRequest::HTTPCURLRequest(HTTPCURLContext* context_, const Resource& reso
if (!existingResponse->etag.empty()) {
const std::string header = std::string("If-None-Match: ") + existingResponse->etag;
headers = curl_slist_append(headers, header.c_str());
} else if (existingResponse->modified) {
} else if (existingResponse->modified != Seconds::zero()) {
const std::string time =
std::string("If-Modified-Since: ") + util::rfc1123(existingResponse->modified);
std::string("If-Modified-Since: ") + util::rfc1123(existingResponse->modified.count());
headers = curl_slist_append(headers, time.c_str());
}
}
@@ -525,7 +525,7 @@ size_t HTTPCURLRequest::headerCallback(char *const buffer, const size_t size, co
// Always overwrite the modification date; We might already have a value here from the
// Date header, but this one is more accurate.
const std::string value { buffer + begin, length - begin - 2 }; // remove \r\n
baton->response->modified = curl_getdate(value.c_str(), nullptr);
baton->response->modified = Seconds(curl_getdate(value.c_str(), nullptr));
} else if ((begin = headerMatches("etag: ", buffer, length)) != std::string::npos) {
baton->response->etag = { buffer + begin, length - begin - 2 }; // remove \r\n
} else if ((begin = headerMatches("cache-control: ", buffer, length)) != std::string::npos) {
@@ -533,7 +533,7 @@ size_t HTTPCURLRequest::headerCallback(char *const buffer, const size_t size, co
baton->response->expires = parseCacheControl(value.c_str());
} else if ((begin = headerMatches("expires: ", buffer, length)) != std::string::npos) {
const std::string value { buffer + begin, length - begin - 2 }; // remove \r\n
baton->response->expires = curl_getdate(value.c_str(), nullptr);
baton->response->expires = Seconds(curl_getdate(value.c_str(), nullptr));
}
return length;

View File

@@ -118,9 +118,9 @@ void SQLiteCache::Impl::get(const Resource &resource, Callback callback) {
// Status codes > 1 indicate an error
response->error = std::make_unique<Response::Error>(Response::Error::Reason(status));
}
response->modified = getStmt->get<int64_t>(1);
response->modified = Seconds(getStmt->get<Seconds::rep>(1));
response->etag = getStmt->get<std::string>(2);
response->expires = getStmt->get<int64_t>(3);
response->expires = Seconds(getStmt->get<Seconds::rep>(3));
response->data = std::make_shared<std::string>(std::move(getStmt->get<std::string>(4)));
if (getStmt->get<int>(5)) { // == compressed
response->data = std::make_shared<std::string>(std::move(util::decompress(*response->data)));
@@ -177,9 +177,9 @@ void SQLiteCache::Impl::put(const Resource& resource, std::shared_ptr<const Resp
putStmt->bind(2 /* status */, 1 /* success */);
}
putStmt->bind(3 /* kind */, int(resource.kind));
putStmt->bind(4 /* modified */, response->modified);
putStmt->bind(4 /* modified */, response->modified.count());
putStmt->bind(5 /* etag */, response->etag.c_str());
putStmt->bind(6 /* expires */, response->expires);
putStmt->bind(6 /* expires */, response->expires.count());
std::string data;
if (resource.kind != Resource::SpriteImage && response->data) {
@@ -208,7 +208,7 @@ void SQLiteCache::Impl::put(const Resource& resource, std::shared_ptr<const Resp
}
}
void SQLiteCache::Impl::refresh(const Resource& resource, int64_t expires) {
void SQLiteCache::Impl::refresh(const Resource& resource, Seconds expires) {
try {
if (!db) {
createDatabase();
@@ -226,7 +226,7 @@ void SQLiteCache::Impl::refresh(const Resource& resource, int64_t expires) {
}
const auto canonicalURL = util::mapbox::canonicalURL(resource.url);
refreshStmt->bind(1, int64_t(expires));
refreshStmt->bind(1, expires.count());
refreshStmt->bind(2, canonicalURL.c_str());
refreshStmt->run();
} catch (mapbox::sqlite::Exception& ex) {

View File

@@ -2,6 +2,7 @@
#define MBGL_STORAGE_DEFAULT_SQLITE_CACHE_IMPL
#include <mbgl/storage/sqlite_cache.hpp>
#include <mbgl/util/chrono.hpp>
namespace mapbox {
namespace sqlite {
@@ -19,7 +20,7 @@ public:
void get(const Resource&, Callback);
void put(const Resource& resource, std::shared_ptr<const Response> response);
void refresh(const Resource& resource, int64_t expires);
void refresh(const Resource& resource, Seconds expires);
private:
void createDatabase();

View File

@@ -1,5 +1,6 @@
#include "node_request.hpp"
#include <mbgl/storage/response.hpp>
#include <mbgl/util/chrono.hpp>
#include <cmath>
#include <iostream>
@@ -43,6 +44,8 @@ v8::Handle<v8::Object> NodeRequest::Create(const mbgl::Resource& resource, mbgl:
NAN_METHOD(NodeRequest::Respond) {
using Error = mbgl::Response::Error;
using Milliseconds = mbgl::Milliseconds;
mbgl::Response response;
if (info.Length() < 1) {
@@ -63,14 +66,14 @@ NAN_METHOD(NodeRequest::Respond) {
if (Nan::Has(res, Nan::New("modified").ToLocalChecked()).FromJust()) {
const double modified = Nan::Get(res, Nan::New("modified").ToLocalChecked()).ToLocalChecked()->ToNumber()->Value();
if (!std::isnan(modified)) {
response.modified = modified / 1000; // JS timestamps are milliseconds
response.modified = mbgl::asSeconds(Milliseconds(Milliseconds::rep(modified)));
}
}
if (Nan::Has(res, Nan::New("expires").ToLocalChecked()).FromJust()) {
const double expires = Nan::Get(res, Nan::New("expires").ToLocalChecked()).ToLocalChecked()->ToNumber()->Value();
if (!std::isnan(expires)) {
response.expires = expires / 1000; // JS timestamps are milliseconds
response.expires = mbgl::asSeconds(Milliseconds(Milliseconds::rep(expires)));
}
}

View File

@@ -231,17 +231,17 @@ void DefaultFileSource::Impl::reschedule(DefaultFileRequestImpl& request) {
return;
}
const auto timeout = request.getRetryTimeout();
const Seconds timeout = request.getRetryTimeout();
if (timeout == 0) {
if (timeout == Seconds::zero()) {
update(request);
} else if (timeout > 0) {
} else if (timeout > Seconds::zero()) {
if (!request.timerRequest) {
request.timerRequest = std::make_unique<uv::timer>(util::RunLoop::getLoop());
}
// timeout is in seconds, but the timer takes milliseconds.
request.timerRequest->start(1000 * timeout, 0, [this, &request] {
request.timerRequest->start(asMilliseconds(timeout).count(), 0, [this, &request] {
assert(!request.realRequest);
startRealRequest(request);
});
@@ -298,14 +298,16 @@ const std::shared_ptr<const Response>& DefaultFileRequestImpl::getResponse() con
return response;
}
int64_t DefaultFileRequestImpl::getRetryTimeout() const {
Seconds DefaultFileRequestImpl::getRetryTimeout() const {
Seconds timeout = Seconds::zero();
if (!response) {
// If we don't have a response, we should retry immediately.
return 0;
return timeout;
}
// A value < 0 means that we should not retry.
int64_t timeout = -1;
timeout = Seconds(-1);
if (response->error) {
assert(failedRequests > 0);
@@ -314,14 +316,14 @@ int64_t DefaultFileRequestImpl::getRetryTimeout() const {
// Retry immediately, unless we have a certain number of attempts already
const int graceRetries = 3;
if (failedRequests <= graceRetries) {
timeout = 1;
timeout = Seconds(1);
} else {
timeout = 1 << std::min(failedRequests - graceRetries, 31);
timeout = Seconds(1 << std::min(failedRequests - graceRetries, 31));
}
} break;
case Response::Error::Reason::Connection: {
// Exponential backoff
timeout = 1 << std::min(failedRequests - 1, 31);
timeout = Seconds(1 << std::min(failedRequests - 1, 31));
} break;
default:
// Do not retry due to error.
@@ -330,14 +332,11 @@ int64_t DefaultFileRequestImpl::getRetryTimeout() const {
}
// Check to see if this response expires earlier than a potential error retry.
if (response->expires > 0) {
const int64_t expires =
response->expires -
std::chrono::duration_cast<std::chrono::seconds>(SystemClock::now().time_since_epoch())
.count();
if (response->expires > Seconds::zero()) {
const Seconds secsToExpire = response->expires - toSeconds(SystemClock::now());
// Only update the timeout if we don't have one yet, and only if the new timeout is shorter
// than the previous one.
timeout = timeout < 0 ? expires : std::min(timeout, std::max<int64_t>(0, expires));
timeout = timeout < Seconds::zero() ? secsToExpire: std::min(timeout, std::max(Seconds::zero(), secsToExpire));
}
return timeout;

View File

@@ -5,6 +5,7 @@
#include <mbgl/storage/asset_context_base.hpp>
#include <mbgl/storage/http_context_base.hpp>
#include <mbgl/util/noncopyable.hpp>
#include <mbgl/util/chrono.hpp>
#include <set>
#include <unordered_map>
@@ -57,7 +58,7 @@ public:
// Returns the seconds we have to wait until we need to redo this request. A value of 0
// means that we need to redo it immediately, and a negative value means that we're not setting
// a timeout at all.
int64_t getRetryTimeout() const;
Seconds getRetryTimeout() const;
// Checks the currently stored response and replaces it with an idential one, except with the
// stale flag set, if the response is expired.

View File

@@ -5,18 +5,15 @@
namespace mbgl {
int64_t HTTPRequestBase::parseCacheControl(const char *value) {
Seconds HTTPRequestBase::parseCacheControl(const char *value) {
if (value) {
const auto cacheControl = http::CacheControl::parse(value);
if (cacheControl.maxAge) {
return std::chrono::duration_cast<std::chrono::seconds>(
std::chrono::system_clock::now().time_since_epoch()).count() +
*cacheControl.maxAge;
return toSeconds(SystemClock::now()) + Seconds(*cacheControl.maxAge);
}
}
return 0;
return Seconds::zero();
}
}

View File

@@ -2,6 +2,7 @@
#define MBGL_STORAGE_HTTP_REQUEST_BASE
#include <mbgl/storage/request_base.hpp>
#include <mbgl/util/chrono.hpp>
namespace mbgl {
@@ -16,7 +17,7 @@ public:
virtual void cancel() override { cancelled = true; };
protected:
static int64_t parseCacheControl(const char *value);
static Seconds parseCacheControl(const char *value);
bool cancelled;
};

View File

@@ -18,11 +18,8 @@ Response& Response::operator=(const Response& res) {
}
bool Response::isExpired() const {
const int64_t now =
std::chrono::duration_cast<std::chrono::seconds>(SystemClock::now().time_since_epoch())
.count();
// Note: expires == 0 also counts as expired!
return expires <= now;
return SystemTimePoint(expires) <= SystemClock::now();
}
Response::Error::Error(Reason reason_, const std::string& message_)

20
src/mbgl/util/chrono.cpp Normal file
View File

@@ -0,0 +1,20 @@
#include <mbgl/util/chrono.hpp>
namespace mbgl {
template Duration toDuration<Clock, Duration>(TimePoint);
template SystemDuration toDuration<SystemClock, SystemDuration>(SystemTimePoint);
template Seconds asSeconds<Duration>(Duration);
template Seconds asSeconds<Milliseconds>(Milliseconds);
template Seconds toSeconds<Clock, Duration>(TimePoint);
template Seconds toSeconds<SystemClock, SystemDuration>(SystemTimePoint);
template Milliseconds asMilliseconds<Duration>(Duration);
template Milliseconds asMilliseconds<Seconds>(Seconds);
template Milliseconds toMilliseconds<Clock, Duration>(TimePoint);
template Milliseconds toMilliseconds<SystemClock, SystemDuration>(SystemTimePoint);
}

View File

@@ -4,6 +4,7 @@
#include <mbgl/storage/default_file_source.hpp>
#include <mbgl/storage/sqlite_cache.hpp>
#include <mbgl/util/chrono.hpp>
#include <mbgl/util/run_loop.hpp>
TEST_F(Storage, CacheResponse) {
@@ -27,8 +28,8 @@ TEST_F(Storage, CacheResponse) {
EXPECT_EQ(false, res.stale);
ASSERT_TRUE(res.data.get());
EXPECT_EQ("Response 1", *res.data);
EXPECT_LT(0, res.expires);
EXPECT_EQ(0, res.modified);
EXPECT_LT(Seconds::zero(), res.expires);
EXPECT_EQ(Seconds::zero(), res.modified);
EXPECT_EQ("", res.etag);
response = res;

View File

@@ -4,6 +4,7 @@
#include <mbgl/storage/default_file_source.hpp>
#include <mbgl/storage/sqlite_cache.hpp>
#include <mbgl/util/chrono.hpp>
#include <mbgl/util/run_loop.hpp>
TEST_F(Storage, CacheRevalidateSame) {
@@ -31,8 +32,8 @@ TEST_F(Storage, CacheRevalidateSame) {
EXPECT_EQ(false, res.stale);
ASSERT_TRUE(res.data.get());
EXPECT_EQ("Response", *res.data);
EXPECT_EQ(0, res.expires);
EXPECT_EQ(0, res.modified);
EXPECT_EQ(Seconds::zero(), res.expires);
EXPECT_EQ(Seconds::zero(), res.modified);
EXPECT_EQ("snowfall", res.etag);
req2 = fs.request(revalidateSame, [&, res](Response res2) {
@@ -53,8 +54,8 @@ TEST_F(Storage, CacheRevalidateSame) {
EXPECT_EQ(res.data, res2.data);
EXPECT_EQ("Response", *res2.data);
// We use this to indicate that a 304 reply came back.
EXPECT_LT(0, res2.expires);
EXPECT_EQ(0, res2.modified);
EXPECT_LT(Seconds::zero(), res2.expires);
EXPECT_EQ(Seconds::zero(), res2.modified);
// We're not sending the ETag in the 304 reply, but it should still be there.
EXPECT_EQ("snowfall", res2.etag);
@@ -92,8 +93,8 @@ TEST_F(Storage, CacheRevalidateModified) {
EXPECT_EQ(false, res.stale);
ASSERT_TRUE(res.data.get());
EXPECT_EQ("Response", *res.data);
EXPECT_EQ(0, res.expires);
EXPECT_EQ(1420070400, res.modified);
EXPECT_EQ(Seconds::zero(), res.expires);
EXPECT_EQ(1420070400, res.modified.count());
EXPECT_EQ("", res.etag);
req2 = fs.request(revalidateModified, [&, res](Response res2) {
@@ -114,8 +115,8 @@ TEST_F(Storage, CacheRevalidateModified) {
EXPECT_EQ("Response", *res2.data);
EXPECT_EQ(res.data, res2.data);
// We use this to indicate that a 304 reply came back.
EXPECT_LT(0, res2.expires);
EXPECT_EQ(1420070400, res2.modified);
EXPECT_LT(Seconds::zero(), res2.expires);
EXPECT_EQ(1420070400, res2.modified.count());
EXPECT_EQ("", res2.etag);
loop.stop();
@@ -151,8 +152,8 @@ TEST_F(Storage, CacheRevalidateEtag) {
EXPECT_EQ(false, res.stale);
ASSERT_TRUE(res.data.get());
EXPECT_EQ("Response 1", *res.data);
EXPECT_EQ(0, res.expires);
EXPECT_EQ(0, res.modified);
EXPECT_EQ(Seconds::zero(), res.expires);
EXPECT_EQ(Seconds::zero(), res.modified);
EXPECT_EQ("response-1", res.etag);
req2 = fs.request(revalidateEtag, [&, res](Response res2) {
@@ -172,8 +173,8 @@ TEST_F(Storage, CacheRevalidateEtag) {
ASSERT_TRUE(res2.data.get());
EXPECT_NE(res.data, res2.data);
EXPECT_EQ("Response 2", *res2.data);
EXPECT_EQ(0, res2.expires);
EXPECT_EQ(0, res2.modified);
EXPECT_EQ(Seconds::zero(), res2.expires);
EXPECT_EQ(Seconds::zero(), res2.modified);
EXPECT_EQ("response-2", res2.etag);
loop.stop();

View File

@@ -3,6 +3,7 @@
#include <uv.h>
#include <mbgl/storage/default_file_source.hpp>
#include <mbgl/util/chrono.hpp>
#include <mbgl/util/run_loop.hpp>
TEST_F(Storage, AssetReadDirectory) {
@@ -24,8 +25,8 @@ TEST_F(Storage, AssetReadDirectory) {
EXPECT_EQ(Response::Error::Reason::NotFound, res.error->reason);
EXPECT_EQ(false, res.stale);
ASSERT_FALSE(res.data.get());
EXPECT_EQ(0, res.expires);
EXPECT_EQ(0, res.modified);
EXPECT_EQ(Seconds::zero(), res.expires);
EXPECT_EQ(Seconds::zero(), res.modified);
EXPECT_EQ("", res.etag);
#ifdef MBGL_ASSET_ZIP
EXPECT_EQ("No such file", res.error->message);

View File

@@ -4,6 +4,7 @@
#include <mbgl/storage/default_file_source.hpp>
#include <mbgl/platform/platform.hpp>
#include <mbgl/util/chrono.hpp>
#include <mbgl/util/run_loop.hpp>
TEST_F(Storage, AssetEmptyFile) {
@@ -25,8 +26,8 @@ TEST_F(Storage, AssetEmptyFile) {
EXPECT_EQ(false, res.stale);
ASSERT_TRUE(res.data.get());
EXPECT_EQ("", *res.data);
EXPECT_EQ(0, res.expires);
EXPECT_LT(1420000000, res.modified);
EXPECT_EQ(Seconds::zero(), res.expires);
EXPECT_LT(1420000000, res.modified.count());
EXPECT_NE("", res.etag);
loop.stop();
EmptyFile.finish();
@@ -54,8 +55,8 @@ TEST_F(Storage, AssetNonEmptyFile) {
EXPECT_EQ(false, res.stale);
ASSERT_TRUE(res.data.get());
EXPECT_EQ("content is here\n", *res.data);
EXPECT_EQ(0, res.expires);
EXPECT_LT(1420000000, res.modified);
EXPECT_EQ(Seconds::zero(), res.expires);
EXPECT_LT(1420000000, res.modified.count());
EXPECT_NE("", res.etag);
ASSERT_TRUE(res.data.get());
EXPECT_EQ("content is here\n", *res.data);
@@ -85,8 +86,8 @@ TEST_F(Storage, AssetNonExistentFile) {
EXPECT_EQ(Response::Error::Reason::NotFound, res.error->reason);
EXPECT_EQ(false, res.stale);
ASSERT_FALSE(res.data.get());
EXPECT_EQ(0, res.expires);
EXPECT_EQ(0, res.modified);
EXPECT_EQ(Seconds::zero(), res.expires);
EXPECT_EQ(Seconds::zero(), res.modified);
EXPECT_EQ("", res.etag);
#ifdef MBGL_ASSET_ZIP
EXPECT_EQ("No such file", res.error->message);

View File

@@ -4,6 +4,7 @@
#include <mbgl/storage/default_file_source.hpp>
#include <mbgl/storage/network_status.hpp>
#include <mbgl/util/chrono.hpp>
#include <mbgl/util/run_loop.hpp>
#include <cmath>
@@ -45,8 +46,8 @@ TEST_F(Storage, HTTPCancelMultiple) {
EXPECT_EQ(false, res.stale);
ASSERT_TRUE(res.data.get());
EXPECT_EQ("Hello World!", *res.data);
EXPECT_EQ(0, res.expires);
EXPECT_EQ(0, res.modified);
EXPECT_EQ(Seconds::zero(), res.expires);
EXPECT_EQ(Seconds::zero(), res.modified);
EXPECT_EQ("", res.etag);
loop.stop();
HTTPCancelMultiple.finish();

View File

@@ -3,6 +3,7 @@
#include <uv.h>
#include <mbgl/storage/default_file_source.hpp>
#include <mbgl/util/chrono.hpp>
#include <mbgl/util/run_loop.hpp>
TEST_F(Storage, HTTPCoalescing) {
@@ -31,8 +32,8 @@ TEST_F(Storage, HTTPCoalescing) {
EXPECT_EQ(nullptr, res.error);
ASSERT_TRUE(res.data.get());
EXPECT_EQ("Hello World!", *res.data);
EXPECT_EQ(0, res.expires);
EXPECT_EQ(0, res.modified);
EXPECT_EQ(Seconds::zero(), res.expires);
EXPECT_EQ(Seconds::zero(), res.modified);
EXPECT_EQ("", res.etag);
if (counter >= total) {
@@ -70,8 +71,8 @@ TEST_F(Storage, HTTPMultiple) {
EXPECT_EQ(nullptr, res.error);
ASSERT_TRUE(res.data.get());
EXPECT_EQ("Hello World!", *res.data);
EXPECT_EQ(2147483647, res.expires);
EXPECT_EQ(0, res.modified);
EXPECT_EQ(2147483647, res.expires.count());
EXPECT_EQ(Seconds::zero(), res.modified);
EXPECT_EQ("", res.etag);
// Start a second request for the same resource after the first one has been completed.
@@ -86,8 +87,8 @@ TEST_F(Storage, HTTPMultiple) {
EXPECT_EQ(nullptr, res2.error);
ASSERT_TRUE(res2.data.get());
EXPECT_EQ("Hello World!", *res2.data);
EXPECT_EQ(2147483647, res2.expires);
EXPECT_EQ(0, res2.modified);
EXPECT_EQ(2147483647, res2.expires.count());
EXPECT_EQ(Seconds::zero(), res2.modified);
EXPECT_EQ("", res2.etag);
loop.stop();
@@ -119,8 +120,8 @@ TEST_F(Storage, HTTPStale) {
ASSERT_TRUE(res.data.get());
EXPECT_EQ("Hello World!", *res.data);
EXPECT_EQ(false, res.stale);
EXPECT_EQ(0, res.expires);
EXPECT_EQ(0, res.modified);
EXPECT_EQ(Seconds::zero(), res.expires);
EXPECT_EQ(Seconds::zero(), res.modified);
EXPECT_EQ("", res.etag);
// Don't start the request twice in case this callback gets fired multiple times.
@@ -135,8 +136,8 @@ TEST_F(Storage, HTTPStale) {
EXPECT_EQ(nullptr, res2.error);
ASSERT_TRUE(res2.data.get());
EXPECT_EQ("Hello World!", *res2.data);
EXPECT_EQ(0, res2.expires);
EXPECT_EQ(0, res2.modified);
EXPECT_EQ(Seconds::zero(), res2.expires);
EXPECT_EQ(Seconds::zero(), res2.modified);
EXPECT_EQ("", res2.etag);
if (res2.stale) {

View File

@@ -4,6 +4,7 @@
#include <mbgl/storage/default_file_source.hpp>
#include <mbgl/storage/network_status.hpp>
#include <mbgl/util/chrono.hpp>
#include <mbgl/util/run_loop.hpp>
#include <cmath>
@@ -30,8 +31,8 @@ TEST_F(Storage, HTTPTemporaryError) {
EXPECT_EQ(false, res.stale);
ASSERT_TRUE(res.data.get());
EXPECT_EQ("", *res.data);
EXPECT_EQ(0, res.expires);
EXPECT_EQ(0, res.modified);
EXPECT_EQ(Seconds::zero(), res.expires);
EXPECT_EQ(Seconds::zero(), res.modified);
EXPECT_EQ("", res.etag);
} break;
case 1: {
@@ -43,8 +44,8 @@ TEST_F(Storage, HTTPTemporaryError) {
EXPECT_EQ(false, res.stale);
ASSERT_TRUE(res.data.get());
EXPECT_EQ("Hello World!", *res.data);
EXPECT_EQ(0, res.expires);
EXPECT_EQ(0, res.modified);
EXPECT_EQ(Seconds::zero(), res.expires);
EXPECT_EQ(Seconds::zero(), res.modified);
EXPECT_EQ("", res.etag);
loop.stop();
HTTPTemporaryError.finish();
@@ -86,8 +87,8 @@ TEST_F(Storage, HTTPConnectionError) {
#endif
EXPECT_EQ(false, res.stale);
ASSERT_FALSE(res.data.get());
EXPECT_EQ(0, res.expires);
EXPECT_EQ(0, res.modified);
EXPECT_EQ(Seconds::zero(), res.expires);
EXPECT_EQ(Seconds::zero(), res.modified);
EXPECT_EQ("", res.etag);
if (counter == 2) {

View File

@@ -24,8 +24,8 @@ TEST_F(Storage, HTTPExpiresParsing) {
EXPECT_EQ(false, res.stale);
ASSERT_TRUE(res.data.get());
EXPECT_EQ("Hello World!", *res.data);
EXPECT_EQ(1420797926, res.expires);
EXPECT_EQ(1420794326, res.modified);
EXPECT_EQ(1420797926, res.expires.count());
EXPECT_EQ(1420794326, res.modified.count());
EXPECT_EQ("foo", res.etag);
loop.stop();
HTTPExpiresTest.finish();
@@ -42,8 +42,7 @@ TEST_F(Storage, HTTPCacheControlParsing) {
DefaultFileSource fs(nullptr);
util::RunLoop loop(uv_default_loop());
int64_t now = std::chrono::duration_cast<std::chrono::seconds>(
SystemClock::now().time_since_epoch()).count();
const Seconds now = toSeconds(SystemClock::now());
std::unique_ptr<FileRequest> req2 = fs.request({ Resource::Unknown, "http://127.0.0.1:3000/test?cachecontrol=max-age=120" },
[&](Response res) {
@@ -52,8 +51,8 @@ TEST_F(Storage, HTTPCacheControlParsing) {
EXPECT_EQ(false, res.stale);
ASSERT_TRUE(res.data.get());
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);
EXPECT_GT(2, std::abs(res.expires.count() - now.count() - 120)) << "Expiration date isn't about 120 seconds in the future";
EXPECT_EQ(Seconds::zero(), res.modified);
EXPECT_EQ("", res.etag);
loop.stop();
HTTPCacheControlTest.finish();

View File

@@ -4,6 +4,7 @@
#include <mbgl/storage/default_file_source.hpp>
#include <mbgl/storage/sqlite_cache.hpp>
#include <mbgl/util/chrono.hpp>
#include <mbgl/util/run_loop.hpp>
// Test for https://github.com/mapbox/mapbox-gl-native/issue/1369
@@ -38,8 +39,8 @@ TEST_F(Storage, HTTPIssue1369) {
EXPECT_EQ(false, res.stale);
ASSERT_TRUE(res.data.get());
EXPECT_EQ("Hello World!", *res.data);
EXPECT_EQ(0, res.expires);
EXPECT_EQ(0, res.modified);
EXPECT_EQ(Seconds::zero(), res.expires);
EXPECT_EQ(Seconds::zero(), res.modified);
EXPECT_EQ("", res.etag);
loop.stop();
HTTPIssue1369.finish();

View File

@@ -3,6 +3,7 @@
#include <uv.h>
#include <mbgl/storage/default_file_source.hpp>
#include <mbgl/util/chrono.hpp>
#include <mbgl/util/run_loop.hpp>
TEST_F(Storage, HTTPLoad) {
@@ -29,8 +30,8 @@ TEST_F(Storage, HTTPLoad) {
EXPECT_EQ(false, res.stale);
ASSERT_TRUE(res.data.get());
EXPECT_EQ(std::string("Request ") + std::to_string(current), *res.data);
EXPECT_EQ(0, res.expires);
EXPECT_EQ(0, res.modified);
EXPECT_EQ(Seconds::zero(), res.expires);
EXPECT_EQ(Seconds::zero(), res.modified);
EXPECT_EQ("", res.etag);
if (number <= max) {

View File

@@ -3,6 +3,7 @@
#include <uv.h>
#include <mbgl/storage/default_file_source.hpp>
#include <mbgl/util/chrono.hpp>
#include <mbgl/util/run_loop.hpp>
TEST_F(Storage, HTTPOtherLoop) {
@@ -21,8 +22,8 @@ TEST_F(Storage, HTTPOtherLoop) {
EXPECT_EQ(false, res.stale);
ASSERT_TRUE(res.data.get());
EXPECT_EQ("Hello World!", *res.data);
EXPECT_EQ(0, res.expires);
EXPECT_EQ(0, res.modified);
EXPECT_EQ(Seconds::zero(), res.expires);
EXPECT_EQ(Seconds::zero(), res.modified);
EXPECT_EQ("", res.etag);
loop.stop();
HTTPOtherLoop.finish();

View File

@@ -4,6 +4,7 @@
#include <mbgl/storage/default_file_source.hpp>
#include <mbgl/util/exception.hpp>
#include <mbgl/util/chrono.hpp>
#include <mbgl/util/run_loop.hpp>
#include <future>
@@ -26,8 +27,8 @@ TEST_F(Storage, HTTPTest) {
EXPECT_EQ(false, res.stale);
ASSERT_TRUE(res.data.get());
EXPECT_EQ("Hello World!", *res.data);
EXPECT_EQ(0, res.expires);
EXPECT_EQ(0, res.modified);
EXPECT_EQ(Seconds::zero(), res.expires);
EXPECT_EQ(Seconds::zero(), res.modified);
EXPECT_EQ("", res.etag);
loop.stop();
HTTPTest.finish();
@@ -56,8 +57,8 @@ TEST_F(Storage, HTTP404) {
ASSERT_TRUE(res.data.get());
EXPECT_EQ("Cannot GET /doesnotexist\n", *res.data);
EXPECT_EQ("HTTP status code 404", res.error->message);
EXPECT_EQ(0, res.expires);
EXPECT_EQ(0, res.modified);
EXPECT_EQ(Seconds::zero(), res.expires);
EXPECT_EQ(Seconds::zero(), res.modified);
EXPECT_EQ("", res.etag);
loop.stop();
HTTP404.finish();
@@ -86,8 +87,8 @@ TEST_F(Storage, HTTP500) {
ASSERT_TRUE(res.data.get());
EXPECT_EQ("Server Error!", *res.data);
EXPECT_EQ("HTTP status code 500", res.error->message);
EXPECT_EQ(0, res.expires);
EXPECT_EQ(0, res.modified);
EXPECT_EQ(Seconds::zero(), res.expires);
EXPECT_EQ(Seconds::zero(), res.modified);
EXPECT_EQ("", res.etag);
loop.stop();
HTTP500.finish();

View File

@@ -4,9 +4,9 @@
#include <mbgl/storage/default_file_source.hpp>
#include <mbgl/storage/network_status.hpp>
#include <mbgl/util/chrono.hpp>
#include <mbgl/util/run_loop.hpp>
// Test for https://github.com/mapbox/mapbox-gl-native/issues/2123
//
// A request is made. While the request is in progress, the network status changes. This should
@@ -30,8 +30,8 @@ TEST_F(Storage, HTTPNetworkStatusChange) {
EXPECT_EQ(false, res.stale);
ASSERT_TRUE(res.data.get());
EXPECT_EQ("Response", *res.data);
EXPECT_EQ(0, res.expires);
EXPECT_EQ(0, res.modified);
EXPECT_EQ(Seconds::zero(), res.expires);
EXPECT_EQ(Seconds::zero(), res.modified);
EXPECT_EQ("", res.etag);
loop.stop();
HTTPNetworkStatusChange.finish();
@@ -90,8 +90,8 @@ TEST_F(Storage, HTTPNetworkStatusChangePreempt) {
#endif
EXPECT_EQ(false, res.stale);
ASSERT_FALSE(res.data.get());
EXPECT_EQ(0, res.expires);
EXPECT_EQ(0, res.modified);
EXPECT_EQ(Seconds::zero(), res.expires);
EXPECT_EQ(Seconds::zero(), res.modified);
EXPECT_EQ("", res.etag);
if (counter++ == 1) {

View File

@@ -4,9 +4,9 @@
#include <mbgl/storage/default_file_source.hpp>
#include <mbgl/storage/network_status.hpp>
#include <mbgl/util/chrono.hpp>
#include <mbgl/util/run_loop.hpp>
TEST_F(Storage, HTTPTimeout) {
SCOPED_TEST(HTTPTimeout)
@@ -24,8 +24,8 @@ TEST_F(Storage, HTTPTimeout) {
EXPECT_EQ(false, res.stale);
ASSERT_TRUE(res.data.get());
EXPECT_EQ("Hello World!", *res.data);
EXPECT_LT(0, res.expires);
EXPECT_EQ(0, res.modified);
EXPECT_LT(Seconds::zero(), res.expires);
EXPECT_EQ(Seconds::zero(), res.modified);
EXPECT_EQ("", res.etag);
if (counter == 4) {
req.reset();