rearrange tests and make more robust
This commit is contained in:
@@ -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
|
||||
|
||||
2
Makefile
2
Makefile
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
96
test/fixtures/fixture_log.cpp
vendored
Normal 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;
|
||||
}
|
||||
|
||||
}
|
||||
98
test/fixtures/fixture_log.hpp
vendored
98
test/fixtures/fixture_log.hpp
vendored
@@ -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
33
test/fixtures/main.cpp
vendored
Normal 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();
|
||||
}
|
||||
51
test/fixtures/server_environment.hpp
vendored
51
test/fixtures/server_environment.hpp
vendored
@@ -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
35
test/fixtures/util.cpp
vendored
Normal 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);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
10
test/util.hpp → test/fixtures/util.hpp
vendored
10
test/util.hpp → test/fixtures/util.hpp
vendored
@@ -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
|
||||
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
#include <iostream>
|
||||
#include "../util.hpp"
|
||||
#include "../fixtures/util.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#include <iostream>
|
||||
#include "../util.hpp"
|
||||
#include "../fixtures/util.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#include <iostream>
|
||||
#include "../util.hpp"
|
||||
#include "../fixtures/util.hpp"
|
||||
|
||||
#include <mbgl/style/function_properties.hpp>
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#include <iostream>
|
||||
#include "../util.hpp"
|
||||
#include "../fixtures/util.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#include "../util.hpp"
|
||||
#include "../fixtures/util.hpp"
|
||||
|
||||
#include <mbgl/style/style.hpp>
|
||||
#include <mbgl/util/io.hpp>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#include <iostream>
|
||||
#include "../util.hpp"
|
||||
#include "../fixtures/util.hpp"
|
||||
|
||||
#include <mbgl/util/utf.hpp>
|
||||
#include <mbgl/platform/platform.hpp>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#include <iostream>
|
||||
#include "../util.hpp"
|
||||
#include "../fixtures/util.hpp"
|
||||
|
||||
#include <mbgl/map/tile.hpp>
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#include <iostream>
|
||||
#include "../util.hpp"
|
||||
#include "../fixtures/util.hpp"
|
||||
|
||||
#include <mbgl/style/value.hpp>
|
||||
#include <mbgl/style/value_comparison.hpp>
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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
13
test/storage/storage.cpp
Normal 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
16
test/storage/storage.hpp
Normal 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
|
||||
@@ -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)' ],
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user