summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorThiago Marcos P. Santos <thiago@mapbox.com>2015-05-22 13:11:23 +0300
committerThiago Marcos P. Santos <thiago@mapbox.com>2015-05-28 09:43:56 +0300
commit379d7830d9a2cb602e41476a1c0809cca84f532c (patch)
tree7de2bbfe33b7b7faad55347445341434096d5a9e /test
parentf8cc50683ad52cff702fb3b324502c5e792917a0 (diff)
downloadqtlocation-mapboxgl-379d7830d9a2cb602e41476a1c0809cca84f532c.tar.gz
Add tests for handling corrupted data
The MockFileSource will insert garbage on the reply and report as a request done successfully. The network stack cannot detect this kind of errors but the consumer should report it like we do for network problems.
Diffstat (limited to 'test')
-rw-r--r--test/resources/mock_file_source.cpp57
-rw-r--r--test/resources/mock_file_source.hpp10
-rw-r--r--test/resources/resource_loader.cpp63
3 files changed, 98 insertions, 32 deletions
diff --git a/test/resources/mock_file_source.cpp b/test/resources/mock_file_source.cpp
index 0a9d448d45..42067a2a73 100644
--- a/test/resources/mock_file_source.cpp
+++ b/test/resources/mock_file_source.cpp
@@ -1,3 +1,4 @@
+#include "../fixtures/util.hpp"
#include "mock_file_source.hpp"
#include <mbgl/storage/request.hpp>
@@ -8,30 +9,64 @@ namespace mbgl {
class MockFileSource::Impl {
public:
- Impl(uv_loop_t*, const std::string& matchFail) : matchFail_(matchFail) {}
+ Impl(uv_loop_t*, Type type, const std::string& match) : type_(type), match_(match) {}
void handleRequest(Request* req) const;
private:
- std::string matchFail_;
+ void replyWithFailure(Response* res) const;
+ void replyWithCorruptedData(Response* res, const std::string& url) const;
+ void replyWithSuccess(Response* res, const std::string& url) const;
+
+ Type type_;
+ std::string match_;
};
-void MockFileSource::Impl::handleRequest(Request* req) const {
- const Resource& resource = req->resource;
+void MockFileSource::Impl::replyWithFailure(Response* res) const {
+ res->status = Response::Status::Error;
+ res->message = "Failed by the test case";
+}
+void MockFileSource::Impl::replyWithCorruptedData(Response* res, const std::string& url) const {
+ res->status = Response::Status::Successful;
+ res->data = util::read_file(url);
+ res->data.insert(0, "CORRUPTED");
+}
+
+void MockFileSource::Impl::replyWithSuccess(Response* res, const std::string& url) const {
+ res->status = Response::Status::Successful;
+ res->data = util::read_file(url);
+}
+
+void MockFileSource::Impl::handleRequest(Request* req) const {
+ const std::string& url = req->resource.url;
std::shared_ptr<Response> response = std::make_shared<Response>();
- if (matchFail_.empty() || resource.url.find(matchFail_) == std::string::npos) {
- response->status = Response::Status::Successful;
- response->data = util::read_file(resource.url.c_str());
- } else {
- response->message = "Failed by the test case";
+
+ if (url.find(match_) == std::string::npos) {
+ replyWithSuccess(response.get(), url);
+ req->notify(response);
+ return;
+ }
+
+ switch (type_) {
+ case Type::Success:
+ replyWithSuccess(response.get(), url);
+ break;
+ case Type::RequestFail:
+ replyWithFailure(response.get());
+ break;
+ case Type::RequestWithCorruptedData:
+ replyWithCorruptedData(response.get(), url);
+ break;
+ default:
+ EXPECT_TRUE(false) << "Should never be reached.";
}
req->notify(response);
}
-MockFileSource::MockFileSource(const std::string& matchFail)
- : thread_(std::make_unique<util::Thread<Impl>>("FileSource", util::ThreadPriority::Low, matchFail)) {
+MockFileSource::MockFileSource(Type type, const std::string& match)
+ : thread_(std::make_unique<util::Thread<Impl>>("FileSource", util::ThreadPriority::Low, type, match)) {
}
Request* MockFileSource::request(const Resource& resource, uv_loop_t* loop, Callback callback) {
diff --git a/test/resources/mock_file_source.hpp b/test/resources/mock_file_source.hpp
index 55ecd95c13..bb9fb55a30 100644
--- a/test/resources/mock_file_source.hpp
+++ b/test/resources/mock_file_source.hpp
@@ -13,12 +13,18 @@ template <typename T> class Thread;
}
// This mock FileSource will read data from the disk and will fail
-// the request if the URL matches the 'matchFail' string.
+// the request if the URL matches a string.
class MockFileSource : public FileSource {
public:
+ enum Type {
+ Success,
+ RequestFail,
+ RequestWithCorruptedData
+ };
+
class Impl;
- MockFileSource(const std::string& matchFail);
+ MockFileSource(Type type, const std::string& match);
~MockFileSource() override = default;
// FileSource implementation.
diff --git a/test/resources/resource_loader.cpp b/test/resources/resource_loader.cpp
index 83807156ed..7d57f47ee6 100644
--- a/test/resources/resource_loader.cpp
+++ b/test/resources/resource_loader.cpp
@@ -107,18 +107,13 @@ private:
std::function<void(std::exception_ptr error)> callback_;
};
-}
-
-class ResourceLoaderTest : public ::testing::TestWithParam<std::string> {
-};
-
-TEST_P(ResourceLoaderTest, RequestFailure) {
+void runTestCase(MockFileSource::Type type,
+ const std::string& param,
+ const std::string& message) {
util::RunLoop loop(uv_default_loop());
- const std::string param(GetParam());
-
MockView view;
- MockFileSource fileSource(param);
+ MockFileSource fileSource(type, param);
FixtureLogObserver* log = new FixtureLogObserver();
Log::setObserver(std::unique_ptr<Log::Observer>(log));
@@ -127,9 +122,6 @@ TEST_P(ResourceLoaderTest, RequestFailure) {
try {
if (error) {
std::rethrow_exception(error);
- } else {
- // Control test, should succeed.
- EXPECT_TRUE(param.empty());
}
} catch (const util::GlyphRangeLoadingException&) {
EXPECT_EQ(param, "glyphs.pbf");
@@ -156,24 +148,57 @@ TEST_P(ResourceLoaderTest, RequestFailure) {
// join and cease logging after this point.
context.reset();
- std::stringstream message;
- message << "Failed to load [test/fixtures/resources/" << param << "]: Failed by the test case";
-
const FixtureLogObserver::LogMessage logMessage {
EventSeverity::Error,
Event::ResourceLoader,
int64_t(-1),
- message.str(),
+ message,
};
- if (param.empty()) {
+ if (type == MockFileSource::Success) {
EXPECT_EQ(log->count(logMessage), 0u);
} else {
EXPECT_GT(log->count(logMessage), 0u);
}
- EXPECT_EQ(log->unchecked().size(), 0u);
+ // Clear the remaining error messages
+ log->unchecked().size();
+}
+
+}
+
+class ResourceLoaderTest : public ::testing::TestWithParam<std::string> {
+};
+
+TEST_P(ResourceLoaderTest, Success) {
+ runTestCase(MockFileSource::Success, GetParam(), std::string());
+}
+
+TEST_P(ResourceLoaderTest, RequestFail) {
+ std::stringstream message;
+ message << "Failed to load [test/fixtures/resources/" << GetParam() << "]: Failed by the test case";
+
+ runTestCase(MockFileSource::RequestFail, GetParam(), message.str());
+}
+
+TEST_P(ResourceLoaderTest, RequestWithCorruptedData) {
+ const std::string param(GetParam());
+
+ std::stringstream message;
+ message << "Failed to parse ";
+
+ if (param == "vector.pbf") {
+ message << "[15/16384/16384]: pbf unknown field type exception";
+ } else {
+ message << "[test/fixtures/resources/" << param << "]";
+ }
+
+ if (param.find("json") != std::string::npos) {
+ message << ": 0 - Expect either an object or array at root";
+ }
+
+ runTestCase(MockFileSource::RequestWithCorruptedData, GetParam(), message.str());
}
INSTANTIATE_TEST_CASE_P(ResourceLoader, ResourceLoaderTest,
- ::testing::Values("", "source.json", "sprite.json", "sprite.png", "vector.pbf", "glyphs.pbf"));
+ ::testing::Values("source.json", "sprite.json", "sprite.png", "vector.pbf", "glyphs.pbf"));