rearrange tests and make more robust

This commit is contained in:
Konstantin Käfer
2015-01-22 12:24:00 +01:00
parent 8a1fce547e
commit aa09aa321b
37 changed files with 347 additions and 359 deletions

View File

@@ -2,9 +2,11 @@ Standard: Cpp11
IndentWidth: 4
AccessModifierOffset: -4
UseTab: Never
BinPackParameters: true
BinPackParameters: false
AllowShortIfStatementsOnASingleLine: false
AllowShortLoopsOnASingleLine: false
AllowShortBlocksOnASingleLine: false
AllowShortFunctionsOnASingleLine: false
ConstructorInitializerAllOnOneLineOrOnePerLine: true
AlwaysBreakTemplateDeclarations: true
NamespaceIndentation: None
@@ -12,5 +14,5 @@ PointerBindsToType: false
SpacesInParentheses: false
BreakBeforeBraces: Attach
ColumnLimit: 100
Cpp11BracedListStyle: true
Cpp11BracedListStyle: false
SpacesBeforeTrailingComments: 1

View File

@@ -110,7 +110,7 @@ test: build/test/Makefile
test-%: build/test/Makefile
$(MAKE) -C build/test BUILDTYPE=$(BUILDTYPE) V=$(V) test
build/$(BUILDTYPE)/test --gtest_filter=$*
./scripts/run_tests.sh --gtest_filter=$*
# build Mac OS X project for Xcode
xtest: build/test/test.xcodeproj

View File

@@ -3,34 +3,34 @@
set -e
set -o pipefail
for TEST in build/${BUILDTYPE:-Release}/test* ; do
# allow writing core files
ulimit -c unlimited -S
echo 'ulimit -c: '`ulimit -c`
if [ -f /proc/sys/kernel/core_pattern ]; then
echo '/proc/sys/kernel/core_pattern: '`cat /proc/sys/kernel/core_pattern`
fi
CMD="build/${BUILDTYPE:-Release}/test"
if [[ ${TRAVIS_OS_NAME} == "linux" ]]; then
sysctl kernel.core_pattern
fi
# allow writing core files
ulimit -c unlimited -S
echo 'ulimit -c: '`ulimit -c`
if [ -f /proc/sys/kernel/core_pattern ]; then
echo '/proc/sys/kernel/core_pattern: '`cat /proc/sys/kernel/core_pattern`
fi
RESULT=0
${TEST} || RESULT=$?
if [[ ${TRAVIS_OS_NAME} == "linux" ]]; then
sysctl kernel.core_pattern
fi
if [[ ${RESULT} != 0 ]]; then
echo "The program crashed with exit code ${RESULT}. We're now trying to output the core dump."
fi
RESULT=0
${CMD} "$@" || RESULT=$?
# output core dump if we got one
for DUMP in $(find ./ -maxdepth 1 -name 'core*' -print); do
gdb ${TEST} ${DUMP} -ex "thread apply all bt" -ex "set pagination 0" -batch
rm -rf ${DUMP}
done
if [[ ${RESULT} != 0 ]]; then
echo "The program crashed with exit code ${RESULT}. We're now trying to output the core dump."
fi
# now we should present travis with the original
# error code so the run cleanly stops
if [[ ${RESULT} != 0 ]]; then
exit $RESULT
fi
# output core dump if we got one
for DUMP in $(find ./ -maxdepth 1 -name 'core*' -print); do
gdb ${CMD} ${DUMP} -ex "thread apply all bt" -ex "set pagination 0" -batch
rm -rf ${DUMP}
done
# now we should present travis with the original
# error code so the run cleanly stops
if [[ ${RESULT} != 0 ]]; then
exit $RESULT
fi

View File

@@ -1,103 +0,0 @@
#include <iostream>
#include "../util.hpp"
#include <mbgl/map/vector_tile.hpp>
#include <mbgl/style/filter_expression.hpp>
#include <mbgl/style/filter_expression_private.hpp>
#include <map>
using namespace mbgl;
typedef std::multimap<std::string, mbgl::Value> Properties;
class Extractor {
public:
inline Extractor(const Properties& properties_, FeatureType type_)
: properties(properties_)
, type(type_)
{}
mapbox::util::optional<Value> getValue(const std::string &key) const {
if (key == "$type")
return Value(uint64_t(type));
auto it = properties.find(key);
if (it == properties.end())
return mapbox::util::optional<Value>();
return it->second;
}
FeatureType getType() const {
return type;
}
private:
const Properties properties;
FeatureType type;
};
FilterExpression parse(const char * expression) {
rapidjson::Document doc;
doc.Parse<0>(expression);
return parseFilterExpression(doc);
}
bool evaluate(const FilterExpression& expression, const Properties& properties, FeatureType type = FeatureType::Unknown) {
return mbgl::evaluate(expression, Extractor(properties, type));
}
TEST(FilterComparison, EqualsString) {
FilterExpression f = parse("[\"==\", \"foo\", \"bar\"]");
ASSERT_TRUE(evaluate(f, {{ "foo", std::string("bar") }}));
ASSERT_FALSE(evaluate(f, {{ "foo", std::string("baz") }}));
};
TEST(FilterComparison, EqualsNumber) {
FilterExpression f = parse("[\"==\", \"foo\", 0]");
ASSERT_TRUE(evaluate(f, {{ "foo", int64_t(0) }}));
ASSERT_TRUE(evaluate(f, {{ "foo", uint64_t(0) }}));
ASSERT_TRUE(evaluate(f, {{ "foo", double(0) }}));
ASSERT_FALSE(evaluate(f, {{ "foo", int64_t(1) }}));
ASSERT_FALSE(evaluate(f, {{ "foo", uint64_t(1) }}));
ASSERT_FALSE(evaluate(f, {{ "foo", double(1) }}));
ASSERT_FALSE(evaluate(f, {{ "foo", std::string("0") }}));
ASSERT_FALSE(evaluate(f, {{ "foo", false }}));
ASSERT_FALSE(evaluate(f, {{ "foo", true }}));
ASSERT_FALSE(evaluate(f, {{}}));
}
TEST(FilterComparison, EqualsType) {
FilterExpression f = parse("[\"==\", \"$type\", \"LineString\"]");
ASSERT_FALSE(evaluate(f, {{}}, FeatureType::Point));
ASSERT_TRUE(evaluate(f, {{}}, FeatureType::LineString));
}
TEST(FilterComparison, Any) {
ASSERT_FALSE(evaluate(parse("[\"any\"]"), {{}}));
ASSERT_TRUE(evaluate(parse("[\"any\", [\"==\", \"foo\", 1]]"),
{{ std::string("foo"), int64_t(1) }}));
ASSERT_FALSE(evaluate(parse("[\"any\", [\"==\", \"foo\", 0]]"),
{{ std::string("foo"), int64_t(1) }}));
ASSERT_TRUE(evaluate(parse("[\"any\", [\"==\", \"foo\", 0], [\"==\", \"foo\", 1]]"),
{{ std::string("foo"), int64_t(1) }}));
}
TEST(FilterComparison, All) {
ASSERT_TRUE(evaluate(parse("[\"all\"]"), {{}}));
ASSERT_TRUE(evaluate(parse("[\"all\", [\"==\", \"foo\", 1]]"),
{{ std::string("foo"), int64_t(1) }}));
ASSERT_FALSE(evaluate(parse("[\"all\", [\"==\", \"foo\", 0]]"),
{{ std::string("foo"), int64_t(1) }}));
ASSERT_FALSE(evaluate(parse("[\"all\", [\"==\", \"foo\", 0], [\"==\", \"foo\", 1]]"),
{{ std::string("foo"), int64_t(1) }}));
}
TEST(FilterComparison, None) {
ASSERT_TRUE(evaluate(parse("[\"none\"]"), {{}}));
ASSERT_FALSE(evaluate(parse("[\"none\", [\"==\", \"foo\", 1]]"),
{{ std::string("foo"), int64_t(1) }}));
ASSERT_TRUE(evaluate(parse("[\"none\", [\"==\", \"foo\", 0]]"),
{{ std::string("foo"), int64_t(1) }}));
ASSERT_FALSE(evaluate(parse("[\"none\", [\"==\", \"foo\", 0], [\"==\", \"foo\", 1]]"),
{{ std::string("foo"), int64_t(1) }}));
}

96
test/fixtures/fixture_log.cpp vendored Normal file
View File

@@ -0,0 +1,96 @@
#include "fixture_log.hpp"
namespace mbgl {
FixtureLogBackend::LogMessage::LogMessage(EventSeverity severity_, Event event_, int64_t code_,
const std::string &msg_)
: severity(severity_), event(event_), code(code_), msg(msg_) {
}
FixtureLogBackend::LogMessage::LogMessage(EventSeverity severity_, Event event_, int64_t code_)
: severity(severity_), event(event_), code(code_), msg() {
}
FixtureLogBackend::LogMessage::LogMessage(EventSeverity severity_, Event event_,
const std::string &msg_)
: severity(severity_), event(event_), code(), msg(msg_) {
}
FixtureLogBackend::LogMessage::LogMessage(EventSeverity severity_, Event event_)
: severity(severity_), event(event_), code(), msg() {
}
bool FixtureLogBackend::LogMessage::operator==(const LogMessage &rhs) const {
return (!severity || !rhs.severity || severity.get() == rhs.severity.get()) &&
(!event || !rhs.event || event.get() == rhs.event.get()) &&
(!code || !rhs.code || code.get() == rhs.code.get()) &&
(!msg || !rhs.msg || msg.get() == rhs.msg.get());
}
FixtureLogBackend::~FixtureLogBackend() {
std::cerr << unchecked();
}
void FixtureLogBackend::record(EventSeverity severity, Event event, const std::string &msg) {
messages.emplace_back(severity, event, msg);
}
void FixtureLogBackend::record(EventSeverity severity, Event event, const char *format, ...) {
va_list args;
va_start(args, format);
const size_t len = vsnprintf(NULL, 0, format, args);
va_end(args);
std::unique_ptr<char[]> buffer(new char[len + 1]);
va_start(args, format);
vsnprintf(buffer.get(), len + 1, format, args);
va_end(args);
messages.emplace_back(severity, event, std::string{ buffer.get(), len });
}
void FixtureLogBackend::record(EventSeverity severity, Event event, int64_t code) {
messages.emplace_back(severity, event, code);
}
void FixtureLogBackend::record(EventSeverity severity, Event event, int64_t code,
const std::string &msg) {
messages.emplace_back(severity, event, code, msg);
}
size_t FixtureLogBackend::count(const LogMessage &message) const {
size_t message_count = 0;
for (const LogMessage &msg : messages) {
if (msg == message) {
message_count++;
msg.checked = true;
}
}
return message_count;
}
std::vector<FixtureLogBackend::LogMessage> FixtureLogBackend::unchecked() const {
std::vector<LogMessage> unchecked_messages;
for (const LogMessage &msg : messages) {
if (!msg.checked) {
unchecked_messages.push_back(msg);
msg.checked = true;
}
}
return unchecked_messages;
}
::std::ostream &operator<<(::std::ostream &os,
const std::vector<FixtureLogBackend::LogMessage> &messages) {
for (const FixtureLogBackend::LogMessage &message : messages) {
os << "- " << message;
}
return os;
}
::std::ostream &operator<<(::std::ostream &os, const FixtureLogBackend::LogMessage &message) {
os << "[\"" << message.severity.get() << "\", \"" << message.event.get() << "\"";
if (message.code)
os << ", " << message.code.get();
if (message.msg)
os << ", \"" << message.msg.get() << "\"";
return os << "]" << std::endl;
}
}

View File

@@ -9,27 +9,17 @@
#include <cstdarg>
#include <iostream>
namespace mbgl {
class FixtureLogBackend : public LogBackend, private util::noncopyable {
public:
struct LogMessage {
inline LogMessage(EventSeverity severity_, Event event_, int64_t code_, const std::string &msg_)
: severity(severity_), event(event_), code(code_), msg(msg_) {}
inline LogMessage(EventSeverity severity_, Event event_, int64_t code_)
: severity(severity_), event(event_), code(code_), msg() {}
inline LogMessage(EventSeverity severity_, Event event_, const std::string &msg_)
: severity(severity_), event(event_), code(), msg(msg_) {}
inline LogMessage(EventSeverity severity_, Event event_)
: severity(severity_), event(event_), code(), msg() {}
LogMessage(EventSeverity severity_, Event event_, int64_t code_, const std::string &msg_);
LogMessage(EventSeverity severity_, Event event_, int64_t code_);
LogMessage(EventSeverity severity_, Event event_, const std::string &msg_);
LogMessage(EventSeverity severity_, Event event_);
inline bool operator==(const LogMessage &rhs) const {
return (!severity || !rhs.severity || severity.get() == rhs.severity.get()) &&
(!event || !rhs.event || event.get() == rhs.event.get()) &&
(!code || !rhs.code || code.get() == rhs.code.get()) &&
(!msg || !rhs.msg || msg.get() == rhs.msg.get());
}
bool operator==(const LogMessage &rhs) const;
const mapbox::util::optional<EventSeverity> severity;
const mapbox::util::optional<Event> event;
@@ -39,81 +29,23 @@ public:
mutable bool checked = false;
};
inline ~FixtureLogBackend();
~FixtureLogBackend();
inline void record(EventSeverity severity, Event event, const std::string &msg) {
messages.emplace_back(severity, event, msg);
}
inline void record(EventSeverity severity, Event event, const std::string &msg);
inline void record(EventSeverity severity, Event event, const char *format, ...);
inline void record(EventSeverity severity, Event event, int64_t code);
inline void record(EventSeverity severity, Event event, int64_t code, const std::string &msg);
inline void record(EventSeverity severity, Event event, const char* format, ...) {
va_list args;
va_start(args, format);
const size_t len = vsnprintf(NULL, 0, format, args);
va_end(args);
std::unique_ptr<char[]> buffer(new char[len + 1]);
va_start(args, format);
vsnprintf(buffer.get(), len + 1, format, args);
va_end(args);
messages.emplace_back(severity, event, std::string { buffer.get(), len });
}
inline void record(EventSeverity severity, Event event, int64_t code) {
messages.emplace_back(severity, event, code);
}
inline void record(EventSeverity severity, Event event, int64_t code, const std::string &msg) {
messages.emplace_back(severity, event, code, msg);
}
inline size_t count(const LogMessage &message) const;
inline std::vector<LogMessage> unchecked() const;
size_t count(const LogMessage &message) const;
std::vector<LogMessage> unchecked() const;
public:
std::vector<LogMessage> messages;
};
inline ::std::ostream& operator<<(::std::ostream& os, const std::vector<FixtureLogBackend::LogMessage>& messages);
inline ::std::ostream& operator<<(::std::ostream& os, const FixtureLogBackend::LogMessage& message);
FixtureLogBackend::~FixtureLogBackend() {
std::cerr << unchecked();
}
size_t FixtureLogBackend::count(const LogMessage &message) const {
size_t message_count = 0;
for (const LogMessage &msg : messages) {
if (msg == message) {
message_count++;
msg.checked = true;
}
}
return message_count;
}
std::vector<FixtureLogBackend::LogMessage> FixtureLogBackend::unchecked() const {
std::vector<LogMessage> unchecked_messages;
for (const LogMessage &msg : messages) {
if (!msg.checked) {
unchecked_messages.push_back(msg);
msg.checked = true;
}
}
return unchecked_messages;
}
::std::ostream& operator<<(::std::ostream& os, const std::vector<FixtureLogBackend::LogMessage>& messages) {
for (const FixtureLogBackend::LogMessage &message : messages) {
os << "- " << message;
}
return os;
}
::std::ostream& operator<<(::std::ostream& os, const FixtureLogBackend::LogMessage& message) {
os << "[\"" << message.severity.get() << "\", \"" << message.event.get() << "\"";
if (message.code) os << ", " << message.code.get();
if (message.msg) os << ", \"" << message.msg.get() << "\"";
return os << "]" << std::endl;
}
::std::ostream &operator<<(::std::ostream &os,
const std::vector<FixtureLogBackend::LogMessage> &messages);
::std::ostream &operator<<(::std::ostream &os, const FixtureLogBackend::LogMessage &message);
}

33
test/fixtures/main.cpp vendored Normal file
View File

@@ -0,0 +1,33 @@
#include "util.hpp"
#include <libgen.h>
std::string baseDirectory;
namespace mbgl {
namespace test {
const std::string &getBaseDirectory() {
return baseDirectory;
}
}
}
GTEST_API_ int main(int argc, char *argv[]) {
// Note: glibc's dirname() **modifies** the argument and can't handle static strings.
std::string file { __FILE__ };
file = dirname(const_cast<char *>(file.c_str()));
if (file[0] == '/') {
// If __FILE__ is an absolute path, we don't have to guess from the argv 0.
baseDirectory = file + "/..";
} else {
std::string argv0 { argv[0] }; argv0 = dirname(const_cast<char *>(argv0.c_str()));
baseDirectory = argv0 + "/" + file + "/..";
}
fprintf(stderr, "basedir: %s\n", mbgl::test::getBaseDirectory().c_str());
testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}

View File

@@ -1,51 +0,0 @@
#ifndef MBGL_TEST_FIXTURES_SERVER_ENVIRONMENT
#define MBGL_TEST_FIXTURES_SERVER_ENVIRONMENT
#include <gtest/gtest.h>
#include <dirent.h>
#include <signal.h>
#include <libgen.h>
class ServerEnvironment : public ::testing::Environment {
public:
inline ServerEnvironment(const std::string &executable);
inline virtual void SetUp();
inline virtual void TearDown();
private:
const std::string executable;
const std::string parent_pid = std::to_string(getpid());
pid_t pid = 0;
};
ServerEnvironment::ServerEnvironment(const std::string &executable_) : executable(executable_) {}
void ServerEnvironment::SetUp() {
pid = fork();
if (pid < 0) {
throw std::runtime_error("Cannot create server process");
} else if (pid == 0) {
char *arg[] = {
const_cast<char *>(executable.c_str()),
const_cast<char *>(parent_pid.c_str()),
nullptr
};
int ret = execv(executable.c_str(), arg);
// This call should not return. In case execve failed, we exit anyway.
if (ret < 0) {
fprintf(stderr, "Failed to start server: %s\n", strerror(errno));
}
exit(0);
} else {
// Wait until the server process sends SIGCONT.
raise(SIGSTOP);
}
}
void ServerEnvironment::TearDown() {
ASSERT_TRUE(pid);
kill(pid, SIGHUP);
}
#endif

35
test/fixtures/util.cpp vendored Normal file
View File

@@ -0,0 +1,35 @@
#include "util.hpp"
#include <csignal>
namespace mbgl {
namespace test {
pid_t startServer(const char *executable) {
const std::string parent_pid = std::to_string(getpid());
pid_t pid = fork();
if (pid < 0) {
throw std::runtime_error("Cannot create server process");
} else if (pid == 0) {
char *args[] = { const_cast<char *>(executable),
const_cast<char *>(parent_pid.c_str()),
nullptr };
int ret = execv(executable, args);
// This call should not return. In case execve failed, we exit anyway.
if (ret < 0) {
fprintf(stderr, "Failed to start server: %s\n", strerror(errno));
}
exit(0);
} else {
// Wait until the server process sends SIGCONT.
raise(SIGSTOP);
}
return pid;
}
void stopServer(pid_t pid) {
kill(pid, SIGTERM);
}
}
}

View File

@@ -11,4 +11,14 @@
~name() { if (!completed) ADD_FAILURE() << #name " didn't complete."; } \
} name;
namespace mbgl {
namespace test {
const std::string &getBaseDirectory();
pid_t startServer(const char *executable);
void stopServer(pid_t pid);
}
}
#endif

View File

@@ -1,5 +1,5 @@
#include "../util.hpp"
#include "../fixtures/server_environment.hpp"
#include "../fixtures/util.hpp"
#include "../fixtures/fixture_log.hpp"
#include <mbgl/map/map.hpp>
#include <mbgl/util/image.hpp>
@@ -14,9 +14,7 @@
#include <mbgl/platform/default/headless_display.hpp>
#include <mbgl/storage/default/default_file_source.hpp>
#include "../fixtures/fixture_log.hpp"
std::shared_ptr<mbgl::HeadlessDisplay> display;
#include <dirent.h>
void rewriteLocalScheme(rapidjson::Value &value, rapidjson::Document::AllocatorType &allocator) {
ASSERT_TRUE(value.IsString());
@@ -27,7 +25,27 @@ void rewriteLocalScheme(rapidjson::Value &value, rapidjson::Document::AllocatorT
}
}
class HeadlessTest : public ::testing::TestWithParam<std::string> {};
class HeadlessTest : public ::testing::TestWithParam<std::string> {
public:
static void SetUpTestCase() {
const auto server = mbgl::test::getBaseDirectory() + "/headless/server.js";
pid = mbgl::test::startServer(server.c_str());
display = std::make_shared<mbgl::HeadlessDisplay>();
}
static void TearDownTestCase() {
display.reset();
mbgl::test::stopServer(pid);
}
protected:
static pid_t pid;
static std::shared_ptr<mbgl::HeadlessDisplay> display;
};
pid_t HeadlessTest::pid = 0;
std::shared_ptr<mbgl::HeadlessDisplay> HeadlessTest::display;
TEST_P(HeadlessTest, render) {
using namespace mbgl;
@@ -119,10 +137,6 @@ TEST_P(HeadlessTest, render) {
}
}
if (!display) {
display = std::make_shared<mbgl::HeadlessDisplay>();
}
HeadlessView view(display);
mbgl::DefaultFileSource fileSource(nullptr);
Map map(view, fileSource);
@@ -151,7 +165,8 @@ TEST_P(HeadlessTest, render) {
INSTANTIATE_TEST_CASE_P(Headless, HeadlessTest, ::testing::ValuesIn([] {
std::vector<std::string> names;
DIR *dir = opendir("test/suite/tests");
const auto tests = mbgl::test::getBaseDirectory() + "/suite/tests";
DIR *dir = opendir(tests.c_str());
if (dir != nullptr) {
for (dirent *dp = nullptr; (dp = readdir(dir)) != nullptr;) {
const std::string name = dp->d_name;

View File

@@ -1,10 +0,0 @@
#include "util.hpp"
#include "fixtures/server_environment.hpp"
GTEST_API_ int main(int argc, char *argv[]) {
testing::AddGlobalTestEnvironment(new ServerEnvironment("test/headless/server.js"));
testing::AddGlobalTestEnvironment(new ServerEnvironment("test/storage/server.js"));
testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}

View File

@@ -1,5 +1,5 @@
#include <iostream>
#include "../util.hpp"
#include "../fixtures/util.hpp"
#include <algorithm>

View File

@@ -1,5 +1,5 @@
#include <iostream>
#include "../util.hpp"
#include "../fixtures/util.hpp"
#include <mbgl/map/vector_tile.hpp>
#include <mbgl/style/filter_expression.hpp>

View File

@@ -1,5 +1,5 @@
#include <iostream>
#include "../util.hpp"
#include "../fixtures/util.hpp"
#include <algorithm>

View File

@@ -1,5 +1,5 @@
#include <iostream>
#include "../util.hpp"
#include "../fixtures/util.hpp"
#include <mbgl/style/function_properties.hpp>

View File

@@ -1,5 +1,5 @@
#include <iostream>
#include "../util.hpp"
#include "../fixtures/util.hpp"
#include <algorithm>

View File

@@ -1,4 +1,4 @@
#include "../util.hpp"
#include "../fixtures/util.hpp"
#include <mbgl/style/style.hpp>
#include <mbgl/util/io.hpp>

View File

@@ -1,5 +1,5 @@
#include <iostream>
#include "../util.hpp"
#include "../fixtures/util.hpp"
#include <mbgl/util/utf.hpp>
#include <mbgl/platform/platform.hpp>

View File

@@ -1,5 +1,5 @@
#include <iostream>
#include "../util.hpp"
#include "../fixtures/util.hpp"
#include <mbgl/map/tile.hpp>

View File

@@ -1,5 +1,5 @@
#include <iostream>
#include "../util.hpp"
#include "../fixtures/util.hpp"
#include <mbgl/style/value.hpp>
#include <mbgl/style/value_comparison.hpp>

View File

@@ -1,11 +1,11 @@
#include "../util.hpp"
#include "storage.hpp"
#include <uv.h>
#include <mbgl/storage/default/default_file_source.hpp>
#include <mbgl/storage/default/sqlite_cache.hpp>
TEST(Storage, CacheResponse) {
TEST_F(Storage, CacheResponse) {
SCOPED_TEST(CacheResponse);
using namespace mbgl;

View File

@@ -1,11 +1,11 @@
#include "../util.hpp"
#include "storage.hpp"
#include <uv.h>
#include <mbgl/storage/default/default_file_source.hpp>
#include <mbgl/storage/default/sqlite_cache.hpp>
TEST(Storage, CacheRevalidate) {
TEST_F(Storage, CacheRevalidate) {
SCOPED_TEST(CacheRevalidateSame)
SCOPED_TEST(CacheRevalidateModified)
SCOPED_TEST(CacheRevalidateEtag)

View File

@@ -1,17 +1,18 @@
#include "../util.hpp"
#include "storage.hpp"
#include <uv.h>
#include <mbgl/storage/default/default_file_source.hpp>
TEST(Storage, ReadDirectory) {
TEST_F(Storage, ReadDirectory) {
SCOPED_TEST(ReadDirectory)
using namespace mbgl;
DefaultFileSource fs(nullptr, uv_default_loop());
fs.request({ Resource::Unknown, "asset://test/fixtures/storage" }, uv_default_loop(), [&](const Response &res) {
const auto dir = std::string { "asset://" } + mbgl::test::getBaseDirectory() + "/fixtures/storage";
fs.request({ Resource::Unknown, dir }, uv_default_loop(), [&](const Response &res) {
EXPECT_EQ(res.status, Response::Error);
EXPECT_EQ(res.data.size(), 0ul);
EXPECT_EQ(res.expires, 0);

View File

@@ -1,17 +1,18 @@
#include "../util.hpp"
#include "storage.hpp"
#include <uv.h>
#include <mbgl/storage/default/default_file_source.hpp>
TEST(Storage, EmptyFile) {
TEST_F(Storage, EmptyFile) {
SCOPED_TEST(EmptyFile)
using namespace mbgl;
DefaultFileSource fs(nullptr, uv_default_loop());
fs.request({ Resource::Unknown, "asset://test/fixtures/storage/empty" }, uv_default_loop(), [&](const Response &res) {
const auto file = std::string { "asset://" } + mbgl::test::getBaseDirectory() + "/fixtures/storage/empty";
fs.request({ Resource::Unknown, file }, uv_default_loop(), [&](const Response &res) {
EXPECT_EQ(res.status, Response::Successful);
EXPECT_EQ(res.data.size(), 0ul);
EXPECT_EQ(res.expires, 0);
@@ -24,14 +25,15 @@ TEST(Storage, EmptyFile) {
uv_run(uv_default_loop(), UV_RUN_DEFAULT);
}
TEST(Storage, NonExistentFile) {
TEST_F(Storage, NonExistentFile) {
SCOPED_TEST(NonExistentFile)
using namespace mbgl;
DefaultFileSource fs(nullptr, uv_default_loop());
fs.request({ Resource::Unknown, "asset://test/fixtures/storage/does_not_exist" }, uv_default_loop(), [&](const Response &res) {
const auto file = std::string { "asset://" } + mbgl::test::getBaseDirectory() + "/fixtures/storage/does_not_exist";
fs.request({ Resource::Unknown, file }, uv_default_loop(), [&](const Response &res) {
EXPECT_EQ(res.status, Response::Error);
EXPECT_EQ(res.data.size(), 0ul);
EXPECT_EQ(res.expires, 0);

View File

@@ -1,4 +1,4 @@
#include "../util.hpp"
#include "storage.hpp"
#include <uv.h>
@@ -7,7 +7,7 @@
#include <cmath>
TEST(Storage, HTTPCancel) {
TEST_F(Storage, HTTPCancel) {
SCOPED_TEST(HTTPCancel)
using namespace mbgl;
@@ -24,7 +24,7 @@ TEST(Storage, HTTPCancel) {
uv_run(uv_default_loop(), UV_RUN_DEFAULT);
}
TEST(Storage, HTTPCancelMultiple) {
TEST_F(Storage, HTTPCancelMultiple) {
SCOPED_TEST(HTTPCancelMultiple)
using namespace mbgl;

View File

@@ -1,10 +1,10 @@
#include "../util.hpp"
#include "storage.hpp"
#include <uv.h>
#include <mbgl/storage/default/default_file_source.hpp>
TEST(Storage, HTTPCoalescing) {
TEST_F(Storage, HTTPCoalescing) {
SCOPED_TEST(HTTPCoalescing)
static int counter = 0;

View File

@@ -1,4 +1,4 @@
#include "../util.hpp"
#include "storage.hpp"
#include <uv.h>
@@ -7,7 +7,7 @@
#include <cmath>
TEST(Storage, HTTPError) {
TEST_F(Storage, HTTPError) {
SCOPED_TEST(HTTPTemporaryError)
SCOPED_TEST(HTTPConnectionError)

View File

@@ -1,4 +1,4 @@
#include "../util.hpp"
#include "storage.hpp"
#include <uv.h>
@@ -6,7 +6,7 @@
#include <cmath>
TEST(Storage, HTTPHeaderParsing) {
TEST_F(Storage, HTTPHeaderParsing) {
SCOPED_TEST(HTTPExpiresTest)
SCOPED_TEST(HTTPCacheControlTest)

View File

@@ -1,12 +1,10 @@
#include "../util.hpp"
#include "storage.hpp"
#include <uv.h>
#include <mbgl/storage/default/default_file_source.hpp>
TEST(Storage, HTTPLoad) {
TEST_F(Storage, HTTPLoad) {
SCOPED_TEST(HTTPLoad)
using namespace mbgl;

View File

@@ -1,11 +1,11 @@
#include "../util.hpp"
#include "storage.hpp"
#include <uv.h>
#include <mbgl/storage/default/default_file_source.hpp>
#include <mbgl/util/uv.hpp>
TEST(Storage, HTTPNoLoop) {
TEST_F(Storage, HTTPNoLoop) {
SCOPED_TEST(HTTPNoLoop)
using namespace mbgl;

View File

@@ -1,10 +1,10 @@
#include "../util.hpp"
#include "storage.hpp"
#include <uv.h>
#include <mbgl/storage/default/default_file_source.hpp>
TEST(Storage, HTTPOtherLoop) {
TEST_F(Storage, HTTPOtherLoop) {
SCOPED_TEST(HTTPOtherLoop)
using namespace mbgl;

View File

@@ -1,10 +1,10 @@
#include "../util.hpp"
#include "storage.hpp"
#include <uv.h>
#include <mbgl/storage/default/default_file_source.hpp>
TEST(Storage, HTTPReading) {
TEST_F(Storage, HTTPReading) {
SCOPED_TEST(HTTPTest)
SCOPED_TEST(HTTP404)

View File

@@ -92,7 +92,7 @@ app.get('/load/:number(\\d+)', function(req, res) {
var server = app.listen(3000, function () {
var host = server.address().address;
var port = server.address().port;
console.log('Test server listening at http://%s:%s', host, port);
console.warn('Storage test server listening at http://%s:%s', host, port);
if (process.argv[2]) {
// Allow the test to continue running.

13
test/storage/storage.cpp Normal file
View File

@@ -0,0 +1,13 @@
#include "storage.hpp"
pid_t Storage::pid = 0;
void Storage::SetUpTestCase() {
const auto server = mbgl::test::getBaseDirectory() + "/storage/server.js";
fprintf(stderr, "server: %s\n", server.c_str());
pid = mbgl::test::startServer(server.c_str());
}
void Storage::TearDownTestCase() {
mbgl::test::stopServer(pid);
}

16
test/storage/storage.hpp Normal file
View File

@@ -0,0 +1,16 @@
#ifndef MBGL_TEST_STORAGE_STORAGE
#define MBGL_TEST_STORAGE_STORAGE
#include "../fixtures/util.hpp"
#include <uv.h>
class Storage : public testing::Test {
public:
static void SetUpTestCase();
static void TearDownTestCase();
protected:
static pid_t pid;
};
#endif

View File

@@ -1,49 +1,21 @@
{
'includes': [
'../gyp/common.gypi',
'../gyp/version.gypi',
'../gyp/mbgl-platform.gypi',
],
'targets': [
{ 'target_name': 'test_base',
'type': 'none',
'direct_dependent_settings': {
'include_dirs': [ '../include', '../src' ],
},
'link_settings': {
'libraries': [
'<@(uv_static_libs)',
'<@(glfw3_static_libs)',
'<@(sqlite3_static_libs)',
'<@(zlib_static_libs)',
],
'xcode_settings': {
'OTHER_LDFLAGS': [
'<@(uv_ldflags)',
'<@(glfw3_ldflags)',
'<@(sqlite3_ldflags)',
'<@(zlib_ldflags)',
],
'OTHER_CFLAGS': [ '<@(uv_cflags)' ],
'OTHER_CPLUSPLUSFLAGS': [ '<@(uv_cflags)' ],
},
'cflags': [ '<@(uv_cflags)' ],
'cxxflags': [ '<@(uv_cflags)' ],
},
},
# Build all targets
{ 'target_name': 'test',
'type': 'executable',
'include_dirs': [ '../include', '../src' ],
'dependencies': [
'test_base',
'../mapboxgl.gyp:mbgl-core',
'../mapboxgl.gyp:mbgl-<(platform)',
'../mapboxgl.gyp:mbgl-headless',
'../deps/gtest/gtest.gyp:gtest'
],
'sources': [
'main.cpp',
'fixtures/main.cpp',
'fixtures/util.cpp',
'fixtures/fixture_log.cpp',
'headless/headless.cpp',
@@ -58,6 +30,7 @@
'miscellaneous/tile.cpp',
'miscellaneous/variant.cpp',
'storage/storage.cpp',
'storage/cache_response.cpp',
'storage/cache_revalidate.cpp',
'storage/directory_reading.cpp',
@@ -71,6 +44,32 @@
'storage/http_other_loop.cpp',
'storage/http_reading.cpp',
],
'libraries': [
'<@(uv_static_libs)',
'<@(glfw3_static_libs)',
'<@(sqlite3_static_libs)',
'<@(zlib_static_libs)',
],
'variables': {
'cxxflags': [
'<@(uv_cflags)',
'-I<(boost_root)/include',
],
'ldflags': [
'<@(uv_ldflags)',
'<@(glfw3_ldflags)',
'<@(sqlite3_ldflags)',
'<@(zlib_ldflags)',
],
},
'xcode_settings': {
'OTHER_CFLAGS': [ '<@(cxxflags)' ],
'OTHER_CPLUSPLUSFLAGS': [ '<@(cxxflags)' ],
'OTHER_LDFLAGS': [ '<@(ldflags)' ],
},
'cflags': [ '<@(cxxflags)' ],
'cxxflags': [ '<@(cxxflags)' ],
'ldflags': [ '<@(ldflags)' ],
},
]
}