diff --git a/configure.sh b/configure.sh index 9679318bbd..c764b0e5eb 100755 --- a/configure.sh +++ b/configure.sh @@ -52,6 +52,10 @@ else #define BOOKING_SECRET "" #define UBER_SERVER_TOKEN "" #define UBER_CLIENT_ID "" +#define TRACKING_REALTIME_HOST "" +#define TRACKING_REALTIME_PORT 0 +#define TRACKING_HISTORICAL_HOST "" +#define TRACKING_HISTORICAL_PORT 0 ' > "$PRIVATE_HEADER" echo 'ext { spropStoreFile = "../tools/android/debug.keystore" diff --git a/map/framework.cpp b/map/framework.cpp index 780c055c89..e9e2320a23 100644 --- a/map/framework.cpp +++ b/map/framework.cpp @@ -156,6 +156,17 @@ void CancelQuery(weak_ptr & handle) queryHandle->Cancel(); handle.reset(); } + +class StubSocket final : public platform::Socket +{ +public: + // Socket overrides + bool Open(string const & host, uint16_t port) override { return false; } + void Close() override {} + bool Read(uint8_t * data, uint32_t count) override { return false; } + bool Write(uint8_t const * data, uint32_t count) override { return false; } + void SetTimeout(uint32_t milliseconds) override {} +}; } // namespace pair Framework::RegisterMap( @@ -236,7 +247,7 @@ bool Framework::IsTrackingReporterEnabled() const return false; bool allowStat = false; - settings::Get(tracking::Reporter::kAllowKey, allowStat); + UNUSED_VALUE(settings::Get(tracking::Reporter::kEnabledSettingsKey, allowStat)); return allowStat; } @@ -330,7 +341,7 @@ Framework::Framework() , m_storage(platform::migrate::NeedMigrate() ? COUNTRIES_OBSOLETE_FILE : COUNTRIES_FILE) , m_bmManager(*this) , m_isRenderingEnabled(true) - , m_trackingReporter(platform::createMockSocket(), tracking::Reporter::kPushDelayMs) + , m_trackingReporter(make_unique(), tracking::Reporter::kPushDelayMs) , m_displacementModeManager([this](bool show) { int const mode = show ? dp::displacement::kHotelMode : dp::displacement::kDefaultMode; CallDrapeFunction(bind(&df::DrapeEngine::SetDisplacementMode, _1, mode)); diff --git a/platform/platform.pro b/platform/platform.pro index c6fb2fd10e..d05cc1f1e4 100644 --- a/platform/platform.pro +++ b/platform/platform.pro @@ -105,4 +105,3 @@ SOURCES += \ preferred_languages.cpp \ servers_list.cpp \ settings.cpp \ - socket.cpp \ diff --git a/platform/platform_tests_support/platform_tests_support.pro b/platform/platform_tests_support/platform_tests_support.pro index f5456cad2c..8408a7bdbc 100644 --- a/platform/platform_tests_support/platform_tests_support.pro +++ b/platform/platform_tests_support/platform_tests_support.pro @@ -10,10 +10,12 @@ SOURCES += \ scoped_dir.cpp \ scoped_file.cpp \ scoped_mwm.cpp \ + test_socket.cpp \ writable_dir_changer.cpp \ HEADERS += \ scoped_dir.hpp \ scoped_file.hpp \ scoped_mwm.hpp \ + test_socket.hpp \ writable_dir_changer.hpp \ diff --git a/platform/platform_tests_support/test_socket.cpp b/platform/platform_tests_support/test_socket.cpp new file mode 100644 index 0000000000..3924da379c --- /dev/null +++ b/platform/platform_tests_support/test_socket.cpp @@ -0,0 +1,67 @@ +#include "test_socket.hpp" + +#include "base/assert.hpp" + +#include "std/algorithm.hpp" +#include "std/chrono.hpp" + +namespace platform +{ +namespace tests_support +{ +TestSocket::~TestSocket() { m_isConnected = false; } + +bool TestSocket::Open(string const & host, uint16_t port) +{ + if (m_isConnected) + return false; + + m_isConnected = true; + return true; +} + +void TestSocket::Close() { m_isConnected = false; } + +bool TestSocket::Read(uint8_t * data, uint32_t count) +{ + if (!m_isConnected) + return false; + + lock_guard lg(m_inputMutex); + + if (m_input.size() < count) + return false; + + copy(m_input.begin(), m_input.end(), data); + m_input.erase(m_input.begin(), m_input.begin() + count); + return true; +} + +bool TestSocket::Write(uint8_t const * data, uint32_t count) +{ + if (!m_isConnected) + return false; + + { + lock_guard lg(m_outputMutex); + m_output.insert(m_output.end(), data, data + count); + } + m_outputCondition.notify_one(); + return true; +} + +void TestSocket::SetTimeout(uint32_t milliseconds) { m_timeoutMs = milliseconds; } + +size_t TestSocket::ReadServer(vector & destination) +{ + unique_lock lock(m_outputMutex); + m_outputCondition.wait_for(lock, milliseconds(m_timeoutMs), + [this]() { return !m_output.empty(); }); + + size_t const outputSize = m_output.size(); + destination.insert(destination.end(), m_output.begin(), m_output.end()); + m_output.clear(); + return outputSize; +} +} // namespace tests_support +} // namespace platform diff --git a/platform/platform_tests_support/test_socket.hpp b/platform/platform_tests_support/test_socket.hpp new file mode 100644 index 0000000000..8d19071121 --- /dev/null +++ b/platform/platform_tests_support/test_socket.hpp @@ -0,0 +1,44 @@ +#pragma once + +#include "platform/socket.hpp" + +#include "std/atomic.hpp" +#include "std/condition_variable.hpp" +#include "std/cstdint.hpp" +#include "std/deque.hpp" +#include "std/mutex.hpp" +#include "std/vector.hpp" + +namespace platform +{ +namespace tests_support +{ +class TestSocket final : public Socket +{ +public: + // Socket overrides: + ~TestSocket(); + bool Open(string const & host, uint16_t port) override; + void Close() override; + bool Read(uint8_t * data, uint32_t count) override; + bool Write(uint8_t const * data, uint32_t count) override; + void SetTimeout(uint32_t milliseconds) override; + + // Simulates server reading. + // Waits for some data or timeout. + // Returns size of read data. + size_t ReadServer(vector & destination); + +private: + atomic m_isConnected = {false}; + atomic m_timeoutMs = {100}; + + deque m_input; + mutex m_inputMutex; + + vector m_output; + mutex m_outputMutex; + condition_variable m_outputCondition; +}; +} // namespace tests_support +} // namespace platform diff --git a/platform/socket.cpp b/platform/socket.cpp deleted file mode 100644 index 59eb1985a8..0000000000 --- a/platform/socket.cpp +++ /dev/null @@ -1,122 +0,0 @@ -#include "socket.hpp" - -#include "base/assert.hpp" - -#include "std/algorithm.hpp" -#include "std/deque.hpp" -#include "std/mutex.hpp" - -namespace -{ -class MockSocket final : public platform::Socket -{ -public: - // Socket overrides - bool Open(string const & host, uint16_t port) override { return false; } - void Close() override {} - bool Read(uint8_t * data, uint32_t count) override { return false; } - bool Write(uint8_t const * data, uint32_t count) override { return false; } - void SetTimeout(uint32_t milliseconds) override {} -}; - -class TestSocketImpl final : public platform::TestSocket -{ -public: - // Socket overrides - ~TestSocketImpl(); - bool Open(string const & host, uint16_t port) override; - void Close() override; - bool Read(uint8_t * data, uint32_t count) override; - bool Write(uint8_t const * data, uint32_t count) override; - void SetTimeout(uint32_t milliseconds) override; - - // TestSocket overrides - bool HasInput() const override; - bool HasOutput() const override; - void WriteServer(uint8_t const * data, uint32_t count) override; - size_t ReadServer(vector & destination) override; - -private: - bool m_isConnected = false; - - deque m_input; - mutable mutex m_inputMutex; - - vector m_output; - mutable mutex m_outputMutex; -}; - -TestSocketImpl::~TestSocketImpl() { m_isConnected = false; } - -bool TestSocketImpl::Open(string const & host, uint16_t port) -{ - m_isConnected = true; - return true; -} - -void TestSocketImpl::Close() { m_isConnected = false; } -bool TestSocketImpl::Read(uint8_t * data, uint32_t count) -{ - if (!m_isConnected) - return false; - - lock_guard lg(m_inputMutex); - - if (m_input.size() < count) - return false; - - copy(m_input.begin(), m_input.end(), data); - m_input.erase(m_input.begin(), m_input.begin() + count); - return true; -} - -bool TestSocketImpl::Write(uint8_t const * data, uint32_t count) -{ - if (!m_isConnected) - return false; - - lock_guard lg(m_outputMutex); - m_output.insert(m_output.end(), data, data + count); - return true; -} - -void TestSocketImpl::SetTimeout(uint32_t milliseconds) {} -bool TestSocketImpl::HasInput() const -{ - lock_guard lg(m_inputMutex); - return !m_input.empty(); -} - -bool TestSocketImpl::HasOutput() const -{ - lock_guard lg(m_outputMutex); - return !m_output.empty(); -} - -void TestSocketImpl::WriteServer(uint8_t const * data, uint32_t count) -{ - ASSERT(m_isConnected, ()); - - lock_guard lg(m_inputMutex); - m_input.insert(m_input.end(), data, data + count); -} - -size_t TestSocketImpl::ReadServer(vector & destination) -{ - lock_guard lg(m_outputMutex); - - size_t const outputSize = m_output.size(); - if (outputSize == 0) - return 0; - - destination.insert(destination.end(), m_output.begin(), m_output.end()); - m_output.clear(); - return outputSize; -} -} // namespace - -namespace platform -{ -unique_ptr createMockSocket() { return make_unique(); } -unique_ptr createTestSocket() { return make_unique(); } -} // namespace platform diff --git a/platform/socket.hpp b/platform/socket.hpp index 41a0d7711e..43083630ee 100644 --- a/platform/socket.hpp +++ b/platform/socket.hpp @@ -2,7 +2,6 @@ #include "std/string.hpp" #include "std/unique_ptr.hpp" -#include "std/vector.hpp" namespace platform { @@ -26,21 +25,5 @@ public: virtual void SetTimeout(uint32_t milliseconds) = 0; }; -class TestSocket : public Socket -{ -public: - virtual bool HasInput() const = 0; - virtual bool HasOutput() const = 0; - - // Simulate server writing - virtual void WriteServer(uint8_t const * data, uint32_t count) = 0; - - // Simulate server reading - // returns size of read data - virtual size_t ReadServer(vector & destination) = 0; -}; - unique_ptr createSocket(); -unique_ptr createMockSocket(); -unique_ptr createTestSocket(); } // namespace platform diff --git a/tracking/connection.cpp b/tracking/connection.cpp index 09a78a1f41..550a797afc 100644 --- a/tracking/connection.cpp +++ b/tracking/connection.cpp @@ -9,15 +9,11 @@ uint32_t constexpr kSocketTimeoutMs = 10000; namespace tracking { -// static -const char Connection::kHost[] = "gps.host"; // TODO change to real host value -uint16_t Connection::kPort = 666; // TODO change to real port value - Connection::Connection(unique_ptr socket, string const & host, uint16_t port, bool isHistorical) - : m_socket(move(socket)), m_host(host), m_port(port) + : m_socket(move(socket)), m_host(host), m_port(port), m_isHistorical(isHistorical) { - ASSERT(m_socket.get() != nullptr, ()); + ASSERT(m_socket.get(), ()); m_socket->SetTimeout(kSocketTimeoutMs); } @@ -35,9 +31,9 @@ bool Connection::Send(boost::circular_buffer const & points) ASSERT(m_buffer.empty(), ()); MemWriter writer(m_buffer); - coding::TrafficGPSEncoder::SerializeDataPoints(coding::TrafficGPSEncoder::kLatestVersion, writer, - points); - bool isSuccess = m_socket->Write(m_buffer.data(), m_buffer.size()); + using coding::TrafficGPSEncoder; + TrafficGPSEncoder::SerializeDataPoints(TrafficGPSEncoder::kLatestVersion, writer, points); + bool const isSuccess = m_socket->Write(m_buffer.data(), m_buffer.size()); m_buffer.clear(); return isSuccess; } diff --git a/tracking/connection.hpp b/tracking/connection.hpp index 117d014903..a87f3dbbf1 100644 --- a/tracking/connection.hpp +++ b/tracking/connection.hpp @@ -1,11 +1,14 @@ #pragma once -#include "boost/circular_buffer.hpp" - #include "coding/traffic.hpp" +#include "std/cstdint.hpp" +#include "std/string.hpp" +#include "std/unique_ptr.hpp" #include "std/vector.hpp" +#include "boost/circular_buffer.hpp" + namespace platform { class Socket; @@ -18,9 +21,6 @@ using DataPoint = coding::TrafficGPSEncoder::DataPoint; class Connection final { public: - static const char kHost[]; - static uint16_t kPort; - Connection(unique_ptr socket, string const & host, uint16_t port, bool isHistorical); bool Reconnect(); @@ -30,6 +30,7 @@ private: unique_ptr m_socket; string const m_host; uint16_t const m_port; + bool const m_isHistorical; vector m_buffer; }; } // namespace tracking diff --git a/tracking/reporter.cpp b/tracking/reporter.cpp index 6021ac5d9c..8e2b9a9991 100644 --- a/tracking/reporter.cpp +++ b/tracking/reporter.cpp @@ -1,87 +1,60 @@ #include "reporter.hpp" -#include "base/logging.hpp" -#include "base/thread.hpp" -#include "base/timer.hpp" - -#include "boost/circular_buffer.hpp" - #include "platform/location.hpp" #include "platform/socket.hpp" -#include "std/mutex.hpp" -#include "std/vector.hpp" +#include "base/logging.hpp" +#include "base/timer.hpp" -#include "tracking/connection.hpp" +#include "std/target_os.hpp" -using namespace tracking; +#include "private.h" namespace { double constexpr kMinDelaySeconds = 1.0; double constexpr kReconnectDelaySeconds = 60.0; size_t constexpr kRealTimeBufferSize = 60; - -class WorkerImpl final : public Reporter::Worker -{ -public: - WorkerImpl(unique_ptr socket, size_t pushDelayMs); - void Run(); - - // Worker overrides - void AddLocation(location::GpsInfo const & info); - void Stop(); - -private: - void FetchInput(); - bool SendPoints(); - - volatile bool m_stop = false; - Connection m_realtimeSender; - size_t m_pushDelayMs; - bool m_wasConnected = false; - double m_lastConnectTryTime = 0.0; - vector m_input; - mutex m_inputMutex; - boost::circular_buffer m_points; - double m_lastGpsTime = 0.0; -}; -} // namespace +} // namespace namespace tracking { // static -const char Reporter::kAllowKey[] = "AllowStat"; +// Apple and Android applications use different keys for settings.ini. +// Keys saved for existing users, so can' fix it easy, need migration. +// Use this hack until change to special traffic key. +#if defined(OMIM_OS_IPHONE) +const char Reporter::kEnabledSettingsKey[] = "StatisticsEnabled"; +#elif defined(OMIM_OS_ANDROID) +const char Reporter::kEnabledSettingsKey[] = "AllowStat"; +#else +const char Reporter::kEnabledSettingsKey[] = "AllowStat"; +#endif -Reporter::Reporter(unique_ptr socket, size_t pushDelayMs) -{ - WorkerImpl * worker = new WorkerImpl(move(socket), pushDelayMs); - m_worker = worker; - threads::SimpleThread thread([worker] - { - worker->Run(); - delete worker; - }); - thread.detach(); -} +// static +milliseconds const Reporter::kPushDelayMs = milliseconds(10000); -Reporter::~Reporter() { m_worker->Stop(); } - -void Reporter::AddLocation(location::GpsInfo const & info) { m_worker->AddLocation(info); } -} // namespace tracking - -namespace -{ -WorkerImpl::WorkerImpl(unique_ptr socket, size_t pushDelayMs) - : m_realtimeSender(move(socket), Connection::kHost, Connection::kPort, false) - , m_pushDelayMs(pushDelayMs) +Reporter::Reporter(unique_ptr socket, milliseconds pushDelay) + : m_realtimeSender(move(socket), TRACKING_REALTIME_HOST, TRACKING_REALTIME_PORT, false) + , m_pushDelay(pushDelay) , m_points(kRealTimeBufferSize) + , m_thread([this]{Run();}) { } -void WorkerImpl::AddLocation(location::GpsInfo const & info) +Reporter::~Reporter() { - lock_guard lg(m_inputMutex); + { + lock_guard lg(m_mutex); + m_isFinished = true; + } + m_cv.notify_one(); + m_thread.join(); +} + +void Reporter::AddLocation(location::GpsInfo const & info) +{ + lock_guard lg(m_mutex); if (info.m_timestamp < m_lastGpsTime + kMinDelaySeconds) return; @@ -90,37 +63,34 @@ void WorkerImpl::AddLocation(location::GpsInfo const & info) m_input.push_back(DataPoint(info.m_timestamp, ms::LatLon(info.m_latitude, info.m_longitude))); } -void WorkerImpl::Run() +void Reporter::Run() { LOG(LINFO, ("Tracking Reporter started")); - my::HighResTimer timer; + unique_lock lock(m_mutex); - while (!m_stop) + while (!m_isFinished) { - uint64_t const startMs = timer.ElapsedMillis(); + auto const startTime = steady_clock::now(); - FetchInput(); + // Fetch input. + m_points.insert(m_points.end(), m_input.begin(), m_input.end()); + m_input.clear(); + + lock.unlock(); if (SendPoints()) m_points.clear(); + lock.lock(); - uint64_t const passedMs = timer.ElapsedMillis() - startMs; - if (passedMs < m_pushDelayMs) - threads::Sleep(m_pushDelayMs - passedMs); + auto const passedMs = duration_cast(steady_clock::now() - startTime); + if (passedMs < m_pushDelay) + m_cv.wait_for(lock, m_pushDelay - passedMs, [this]{return m_isFinished;}); } LOG(LINFO, ("Tracking Reporter finished")); } -void WorkerImpl::Stop() { m_stop = true; } -void WorkerImpl::FetchInput() -{ - lock_guard lg(m_inputMutex); - m_points.insert(m_points.end(), m_input.begin(), m_input.end()); - m_input.clear(); -} - -bool WorkerImpl::SendPoints() +bool Reporter::SendPoints() { if (m_points.empty()) return true; @@ -131,11 +101,11 @@ bool WorkerImpl::SendPoints() if (m_wasConnected) return true; - double currentTime = my::Timer::LocalTime(); - if (currentTime < m_lastConnectTryTime + kReconnectDelaySeconds) + double const currentTime = my::Timer::LocalTime(); + if (currentTime < m_lastConnectionAttempt + kReconnectDelaySeconds) return false; - m_lastConnectTryTime = currentTime; + m_lastConnectionAttempt = currentTime; m_wasConnected = m_realtimeSender.Reconnect(); if (!m_wasConnected) @@ -144,4 +114,4 @@ bool WorkerImpl::SendPoints() m_wasConnected = m_realtimeSender.Send(m_points); return m_wasConnected; } -} // namespace +} // namespace tracking diff --git a/tracking/reporter.hpp b/tracking/reporter.hpp index 13b5ffea7a..2c85b69969 100644 --- a/tracking/reporter.hpp +++ b/tracking/reporter.hpp @@ -1,6 +1,16 @@ #pragma once +#include "tracking/connection.hpp" + +#include "base/thread.hpp" + +#include "std/chrono.hpp" +#include "std/condition_variable.hpp" +#include "std/mutex.hpp" #include "std/unique_ptr.hpp" +#include "std/vector.hpp" + +#include "boost/circular_buffer.hpp" namespace location { @@ -17,22 +27,30 @@ namespace tracking class Reporter final { public: - static size_t constexpr kPushDelayMs = 10000; - static const char kAllowKey[]; + static milliseconds const kPushDelayMs; + static const char kEnabledSettingsKey[]; - Reporter(unique_ptr socket, size_t pushDelayMs); + Reporter(unique_ptr socket, milliseconds pushDelay); ~Reporter(); + void AddLocation(location::GpsInfo const & info); - class Worker - { - public: - virtual void AddLocation(location::GpsInfo const & info) = 0; - virtual void Stop() = 0; - }; - private: - Worker * m_worker; -}; + void Run(); + bool SendPoints(); + Connection m_realtimeSender; + milliseconds m_pushDelay; + bool m_wasConnected = false; + double m_lastConnectionAttempt = 0.0; + // Input buffer for incoming points. Worker thread steals it contents. + vector m_input; + // Last collected points, sends periodically to server. + boost::circular_buffer m_points; + double m_lastGpsTime = 0.0; + bool m_isFinished = false; + mutex m_mutex; + condition_variable m_cv; + threads::SimpleThread m_thread; +}; } // namespace tracking diff --git a/tracking/tracking_tests/reporter_test.cpp b/tracking/tracking_tests/reporter_test.cpp new file mode 100644 index 0000000000..2492f32e9d --- /dev/null +++ b/tracking/tracking_tests/reporter_test.cpp @@ -0,0 +1,57 @@ +#include "tracking/reporter.hpp" + +#include "coding/traffic.hpp" + +#include "platform/location.hpp" +#include "platform/platform_tests_support/test_socket.hpp" +#include "platform/socket.hpp" + +#include "testing/testing.hpp" + +#include "base/math.hpp" +#include "base/thread.hpp" + +#include "std/cmath.hpp" + +using namespace tracking; +using namespace platform::tests_support; + +namespace +{ +void TransferLocation(Reporter & reporter, TestSocket & testSocket, double timestamp, + double latidute, double longtitude) +{ + location::GpsInfo gpsInfo; + gpsInfo.m_timestamp = timestamp; + gpsInfo.m_latitude = latidute; + gpsInfo.m_longitude = longtitude; + reporter.AddLocation(gpsInfo); + + vector buffer; + size_t const readSize = testSocket.ReadServer(buffer); + TEST_GREATER(readSize, 0, ()); + + vector points; + MemReader memReader(buffer.data(), buffer.size()); + ReaderSource src(memReader); + coding::TrafficGPSEncoder::DeserializeDataPoints(coding::TrafficGPSEncoder::kLatestVersion, src, + points); + + TEST_EQUAL(points.size(), 1, ()); + auto const & point = points[0]; + TEST_EQUAL(point.m_timestamp, timestamp, ()); + TEST(my::AlmostEqualAbs(point.m_latLon.lat, latidute, 0.001), ()); + TEST(my::AlmostEqualAbs(point.m_latLon.lon, longtitude, 0.001), ()); +} +} + +UNIT_TEST(Reporter_TransferLocations) +{ + auto socket = make_unique(); + TestSocket & testSocket = *socket.get(); + + Reporter reporter(move(socket), milliseconds(10) /* pushDelay */); + TransferLocation(reporter, testSocket, 1.0, 2.0, 3.0); + TransferLocation(reporter, testSocket, 4.0, 5.0, 6.0); + TransferLocation(reporter, testSocket, 7.0, 8.0, 9.0); +} diff --git a/tracking/tracking_tests/reporter_tests.cpp b/tracking/tracking_tests/reporter_tests.cpp deleted file mode 100644 index f8dc89d38b..0000000000 --- a/tracking/tracking_tests/reporter_tests.cpp +++ /dev/null @@ -1,62 +0,0 @@ -#include "base/thread.hpp" -#include "coding/traffic.hpp" - -#include "platform/location.hpp" -#include "platform/socket.hpp" - -#include "std/cmath.hpp" - -#include "testing/testing.hpp" - -#include "tracking/reporter.hpp" - -namespace -{ -template -bool WaitCondition(Condition condition, size_t durationMs = 1000) -{ - size_t sleepMs = 10; - size_t cyclesLimit = durationMs / sleepMs; - for (size_t i = 0; i < cyclesLimit; ++i) - { - threads::Sleep(sleepMs); - if (condition()) - return true; - } - - return false; -} -} // namespace - -using namespace tracking; - -UNIT_TEST(Reporter_TransferLocation) -{ - unique_ptr socket = platform::createTestSocket(); - platform::TestSocket * testSocket = socket.get(); - - Reporter reporter(move(socket), 10); - - location::GpsInfo gpsInfo; - gpsInfo.m_timestamp = 3.0; - gpsInfo.m_latitude = 4.0; - gpsInfo.m_longitude = 5.0; - reporter.AddLocation(gpsInfo); - - TEST(WaitCondition([testSocket] { return testSocket->HasOutput(); }), ()); - - vector buffer; - testSocket->ReadServer(buffer); - - vector points; - MemReader memReader(buffer.data(), buffer.size()); - ReaderSource src(memReader); - coding::TrafficGPSEncoder::DeserializeDataPoints(coding::TrafficGPSEncoder::kLatestVersion, src, - points); - - TEST_EQUAL(points.size(), 1, ()); - coding::TrafficGPSEncoder::DataPoint const & point = points[0]; - TEST_EQUAL(point.m_timestamp, 3, ()); - TEST(abs(point.m_latLon.lat - 4.0) < 0.001, ()); - TEST(abs(point.m_latLon.lon - 5.0) < 0.001, ()); -} diff --git a/tracking/tracking_tests/tracking_tests.pro b/tracking/tracking_tests/tracking_tests.pro index f37f3fb860..81465b60aa 100644 --- a/tracking/tracking_tests/tracking_tests.pro +++ b/tracking/tracking_tests/tracking_tests.pro @@ -7,7 +7,7 @@ ROOT_DIR = ../.. INCLUDEPATH *= $$ROOT_DIR/3party/jansson/src -DEPENDENCIES = base coding geometry platform routing stats_client tracking +DEPENDENCIES = routing tracking platform_tests_support platform coding geometry base stats_client include($$ROOT_DIR/common.pri) @@ -26,4 +26,4 @@ win*|linux* { SOURCES += \ $$ROOT_DIR/testing/testingmain.cpp \ - reporter_tests.cpp \ + reporter_test.cpp