diff options
author | Lev Dragunov <l.dragunov@corp.mail.ru> | 2015-07-28 18:11:24 +0300 |
---|---|---|
committer | Alex Zolotarev <alex@maps.me> | 2015-09-23 02:58:39 +0300 |
commit | 1f36eb605532726e00ee75f582bb20df40b8b9b3 (patch) | |
tree | d9edf04d0e3f2921c45de55b9339e3840b055bab /routing | |
parent | 6a6cb45df2c342d821e704cc568f3aa3c4752473 (diff) |
Async router tests.
Diffstat (limited to 'routing')
-rw-r--r-- | routing/async_router.cpp | 22 | ||||
-rw-r--r-- | routing/async_router.hpp | 10 | ||||
-rw-r--r-- | routing/online_absent_fetcher.hpp | 13 | ||||
-rw-r--r-- | routing/routing_tests/async_router_test.cpp | 118 | ||||
-rw-r--r-- | routing/routing_tests/routing_tests.pro | 1 |
5 files changed, 146 insertions, 18 deletions
diff --git a/routing/async_router.cpp b/routing/async_router.cpp index 217138bea2..731b984177 100644 --- a/routing/async_router.cpp +++ b/routing/async_router.cpp @@ -52,8 +52,7 @@ map<string, string> PrepareStatisticsData(string const & routerName, } // namespace -AsyncRouter::AsyncRouter(unique_ptr<IRouter> && router, - unique_ptr<OnlineAbsentCountriesFetcher> && fetcher, +AsyncRouter::AsyncRouter(unique_ptr<IRouter> && router, unique_ptr<IOnlineFetcher> && fetcher, TRoutingStatisticsCallback const & routingStatisticsFn, TPointCheckCallback const & pointCheckCallback) : m_absentFetcher(move(fetcher)), @@ -79,10 +78,10 @@ void AsyncRouter::CalculateRoute(m2::PointD const & startPoint, m2::PointD const m_finalPoint = finalPoint; m_observer.Cancel(); - m_observer.SetTimeout(timeoutSec); + m_observer.SetProgressCallback(progressCallback); } - GetPlatform().RunAsync(bind(&AsyncRouter::CalculateRouteImpl, this, readyCallback, progressCallback)); + GetPlatform().RunAsync(bind(&AsyncRouter::CalculateRouteImpl, this, readyCallback, timeoutSec)); } void AsyncRouter::ClearState() @@ -137,8 +136,7 @@ void AsyncRouter::LogCode(IRouter::ResultCode code, double const elapsedSec) } } -// TODO (ldragunov) write some tests to check this callback logic. -void AsyncRouter::CalculateRouteImpl(TReadyCallback const & readyCallback, TProgressCallback const & progressCallback) +void AsyncRouter::CalculateRouteImpl(TReadyCallback const & readyCallback, uint32_t timeoutSec) { ASSERT(m_router, ()); if (m_isReadyThread.test_and_set()) @@ -160,7 +158,7 @@ void AsyncRouter::CalculateRouteImpl(TReadyCallback const & readyCallback, TProg startDirection = m_startDirection; m_observer.Reset(); - m_observer.SetProgressCallback(progressCallback); + m_observer.SetTimeout(timeoutSec); } my::Timer timer; @@ -184,13 +182,15 @@ void AsyncRouter::CalculateRouteImpl(TReadyCallback const & readyCallback, TProg code = IRouter::InternalError; LOG(LERROR, ("Exception happened while calculating route:", e.Msg())); SendStatistics(startPoint, startDirection, finalPoint, e.Msg()); - GetPlatform().RunOnGuiThread(bind(readyCallback, route, code)); + readyCallback(route, code); return; } + SendStatistics(startPoint, startDirection, finalPoint, code, route, elapsedSec); + //Draw route without waiting network latency. if (code == IRouter::NoError) - GetPlatform().RunOnGuiThread(bind(readyCallback, route, code)); + readyCallback(route, code); bool const needFetchAbsent = (code != IRouter::Cancelled); @@ -208,10 +208,10 @@ void AsyncRouter::CalculateRouteImpl(TReadyCallback const & readyCallback, TProg elapsedSec = timer.ElapsedSeconds(); // routing time + absents fetch time LogCode(code, elapsedSec); - SendStatistics(startPoint, startDirection, finalPoint, code, route, elapsedSec); + // Call callback only if we have some new data. if (code != IRouter::NoError) - GetPlatform().RunOnGuiThread(bind(readyCallback, route, code)); + readyCallback(route, code); } void AsyncRouter::SendStatistics(m2::PointD const & startPoint, m2::PointD const & startDirection, diff --git a/routing/async_router.hpp b/routing/async_router.hpp index 2ed3108654..5e266b8ac7 100644 --- a/routing/async_router.hpp +++ b/routing/async_router.hpp @@ -26,7 +26,7 @@ public: /// AsyncRouter is a wrapper class to run routing routines in the different thread /// @param router pointer to the router implementation. AsyncRouter will take ownership over /// router. - AsyncRouter(unique_ptr<IRouter> && router, unique_ptr<OnlineAbsentCountriesFetcher> && fetcher, + AsyncRouter(unique_ptr<IRouter> && router, unique_ptr<IOnlineFetcher> && fetcher, TRoutingStatisticsCallback const & routingStatisticsFn, TPointCheckCallback const & pointCheckCallback); @@ -48,10 +48,12 @@ public: /// Interrupt routing and clear buffers virtual void ClearState(); + /// Whait routing process. For testing use. + void WaitRouting() { lock_guard<mutex> routingGuard(m_routingMutex); } + private: /// This function is called in async mode - void CalculateRouteImpl(TReadyCallback const & readyCallback, - TProgressCallback const & progressCallback); + void CalculateRouteImpl(TReadyCallback const & readyCallback, uint32_t timeoutSec); /// These functions are called to send statistics about the routing void SendStatistics(m2::PointD const & startPoint, m2::PointD const & startDirection, @@ -75,7 +77,7 @@ private: TimeoutObserver m_observer; - unique_ptr<OnlineAbsentCountriesFetcher> const m_absentFetcher; + unique_ptr<IOnlineFetcher> const m_absentFetcher; unique_ptr<IRouter> const m_router; TRoutingStatisticsCallback const m_routingStatisticsFn; }; diff --git a/routing/online_absent_fetcher.hpp b/routing/online_absent_fetcher.hpp index 2626dfecac..ae2aa49658 100644 --- a/routing/online_absent_fetcher.hpp +++ b/routing/online_absent_fetcher.hpp @@ -15,16 +15,23 @@ namespace routing { using TCountryLocalFileFn = function<shared_ptr<platform::LocalCountryFile>(string const &)>; +class IOnlineFetcher +{ +public: + virtual void GenerateRequest(m2::PointD const & startPoint, m2::PointD const & finalPoint) = 0; + virtual void GetAbsentCountries(vector<string> & countries) = 0; +}; + /*! * \brief The OnlineAbsentCountriesFetcher class incapsulates async fetching the map * names from online OSRM server routines. */ -class OnlineAbsentCountriesFetcher +class OnlineAbsentCountriesFetcher : public IOnlineFetcher { public: OnlineAbsentCountriesFetcher(TCountryFileFn const & countryFileFn, TCountryLocalFileFn const & countryLocalFileFn) : m_countryFileFn(countryFileFn), m_countryLocalFileFn(countryLocalFileFn) {} - void GenerateRequest(m2::PointD const & startPoint, m2::PointD const & finalPoint); - void GetAbsentCountries(vector<string> & countries); + void GenerateRequest(m2::PointD const & startPoint, m2::PointD const & finalPoint) override; + void GetAbsentCountries(vector<string> & countries) override; private: TCountryFileFn const m_countryFileFn; diff --git a/routing/routing_tests/async_router_test.cpp b/routing/routing_tests/async_router_test.cpp new file mode 100644 index 0000000000..d11608343f --- /dev/null +++ b/routing/routing_tests/async_router_test.cpp @@ -0,0 +1,118 @@ +#include "testing/testing.hpp" + +#include "routing/async_router.hpp" +#include "routing/router.hpp" +#include "routing/online_absent_fetcher.hpp" + +#include "geometry/point2d.hpp" + +#include "base/timer.hpp" + +#include "std/string.hpp" +#include "std/vector.hpp" + +using namespace routing; + +using ResultCode = routing::IRouter::ResultCode; + +namespace +{ +class DummyRouter : public IRouter +{ + ResultCode m_result; + vector<string> m_absent; + +public: + DummyRouter(ResultCode code, vector<string> const & absent) : m_result(code), m_absent(absent) {} + + string GetName() const override { return "Dummy"; } + + ResultCode CalculateRoute(m2::PointD const & startPoint, m2::PointD const & startDirection, + m2::PointD const & finalPoint, IRouterObserver const & observer, + Route & route) override + { + vector<m2::PointD> points({startPoint, finalPoint}); + route = Route("dummy", points.begin(), points.end()); + + for (auto const & absent : m_absent) + route.AddAbsentCountry(absent); + + return m_result; + } +}; + +class DummyFetcher : public IOnlineFetcher +{ + vector<string> m_absent; + +public: + DummyFetcher(vector<string> const & absent) : m_absent(absent) {} + void GenerateRequest(m2::PointD const & startPoint, m2::PointD const & finalPoint) override {} + void GetAbsentCountries(vector<string> & countries) override { countries = m_absent; } +}; + +void DummyStatisticsCallback(map<string, string> const &) {} + +struct DummyResultCallback +{ + static vector<ResultCode> m_codes; + static vector<vector<string>> m_absent; + void operator()(Route & route, ResultCode code) + { + m_codes.push_back(code); + auto const & absent = route.GetAbsentCountries(); + m_absent.emplace_back(absent.begin(), absent.end()); + } +}; + +vector<ResultCode> DummyResultCallback::m_codes; +vector<vector<string>> DummyResultCallback::m_absent; + +UNIT_TEST(NeedMoreMapsSignalTest) +{ + unique_ptr<IOnlineFetcher> fetcher(new DummyFetcher({"test1", "test2"})); + unique_ptr<IRouter> router(new DummyRouter(ResultCode::NoError, {})); + DummyResultCallback resultCallback; + AsyncRouter async(move(router), move(fetcher), DummyStatisticsCallback, nullptr); + resultCallback.m_codes.clear(); + resultCallback.m_absent.clear(); + async.CalculateRoute({1, 2}, {3, 4}, {5, 6}, resultCallback, nullptr, 0); + + // Wait async process start. + while (resultCallback.m_codes.empty()) + { + } + + async.WaitRouting(); + + TEST_EQUAL(resultCallback.m_codes.size(), 2, ()); + TEST_EQUAL(resultCallback.m_codes[0], ResultCode::NoError, ()); + TEST_EQUAL(resultCallback.m_codes[1], ResultCode::NeedMoreMaps, ()); + TEST_EQUAL(resultCallback.m_absent.size(), 2, ()); + TEST(resultCallback.m_absent[0].empty(), ()); + TEST_EQUAL(resultCallback.m_absent[1].size(), 2, ()) +} + +UNIT_TEST(StandartAsyncFogTest) +{ + unique_ptr<IOnlineFetcher> fetcher(new DummyFetcher({})); + unique_ptr<IRouter> router(new DummyRouter(ResultCode::NoError, {})); + DummyResultCallback resultCallback; + AsyncRouter async(move(router), move(fetcher), DummyStatisticsCallback, nullptr); + resultCallback.m_codes.clear(); + resultCallback.m_absent.clear(); + async.CalculateRoute({1, 2}, {3, 4}, {5, 6}, resultCallback, nullptr, 0); + + // Wait async process start. + while (resultCallback.m_codes.empty()) + { + } + + async.WaitRouting(); + + TEST_EQUAL(resultCallback.m_codes.size(), 1, ()); + TEST_EQUAL(resultCallback.m_codes[0], ResultCode::NoError, ()); + TEST_EQUAL(resultCallback.m_absent.size(), 1, ()); + TEST(resultCallback.m_absent[0].empty(), ()); +} +} // namespace diff --git a/routing/routing_tests/routing_tests.pro b/routing/routing_tests/routing_tests.pro index 428ac17897..0c85530df4 100644 --- a/routing/routing_tests/routing_tests.pro +++ b/routing/routing_tests/routing_tests.pro @@ -26,6 +26,7 @@ SOURCES += \ astar_algorithm_test.cpp \ astar_progress_test.cpp \ astar_router_test.cpp \ + async_router_test.cpp \ cross_routing_tests.cpp \ nearest_edge_finder_tests.cpp \ online_cross_fetcher_test.cpp \ |