diff options
author | Vladimir Byko-Ianko <v.bykoianko@corp.mail.ru> | 2020-01-20 16:32:54 +0300 |
---|---|---|
committer | gmoryes <gmoryes@gmail.com> | 2020-01-21 13:02:02 +0300 |
commit | bba3e1c2494353521fabccc4cb890db5b6ecf36e (patch) | |
tree | 7f5455082f69d1d1035b7fc7a9e7bd92216a2c15 /routing | |
parent | 70a475a97b4a372721d1c121cdbb5b88b4459e52 (diff) |
[routing] Bugfixing in infrastructure of routing session state tests adding a test on changing states.
Diffstat (limited to 'routing')
-rw-r--r-- | routing/routing_tests/routing_session_test.cpp | 294 |
1 files changed, 230 insertions, 64 deletions
diff --git a/routing/routing_tests/routing_session_test.cpp b/routing/routing_tests/routing_session_test.cpp index b77270e1fa..9c3d5c0277 100644 --- a/routing/routing_tests/routing_session_test.cpp +++ b/routing/routing_tests/routing_session_test.cpp @@ -19,13 +19,23 @@ #include <string> #include <vector> -namespace routing +namespace { +using namespace routing; using namespace std; using chrono::seconds; using chrono::steady_clock; +vector<m2::PointD> kTestRoute = {{0., 1.}, {0., 2.}, {0., 3.}, {0., 4.}}; +vector<Segment> const kTestSegments({{0, 0, 0, true}, {0, 0, 1, true}, {0, 0, 2, true}}); +Route::TTurns const kTestTurns = {turns::TurnItem(3, turns::CarDirection::ReachedYourDestination)}; +Route::TTimes const kTestTimes({Route::TTimeItem(1, 5), Route::TTimeItem(2, 10), + Route::TTimeItem(3, 15)}); +auto const kRouteBuildingMaxDuration = seconds(30); + +void FillSubroutesInfo(Route & route); + // Simple router. It returns route given to him on creation. class DummyRouter : public IRouter { @@ -52,14 +62,34 @@ public: } }; -static vector<m2::PointD> kTestRoute = {{0., 1.}, {0., 2.}, {0., 3.}, {0., 4.}}; -static vector<Segment> const kTestSegments({{0, 0, 0, true}, {0, 0, 1, true}, {0, 0, 2, true}}); -static Route::TTurns const kTestTurns = { - turns::TurnItem(3, turns::CarDirection::ReachedYourDestination)}; -static Route::TTimes const kTestTimes({Route::TTimeItem(1, 5), Route::TTimeItem(2, 10), - Route::TTimeItem(3, 15)}); +// Router which every next call of CalculateRoute() method return different return codes. +class ReturnCodesRouter : public IRouter +{ +public: + ReturnCodesRouter(initializer_list<RouterResultCode> const & returnCodes, + vector<m2::PointD> const & route) + : m_returnCodes(returnCodes), m_route(route) + { + } + + // IRouter overrides: + string GetName() const override { return "return codes router"; } + void ClearState() override {} + RouterResultCode CalculateRoute(Checkpoints const & /* checkpoints */, + m2::PointD const & /* startDirection */, bool /* adjust */, + RouterDelegate const & /* delegate */, Route & route) override + { + TEST_LESS(m_returnCodesIdx, m_returnCodes.size(), ()); + route = Route(GetName(), m_route.begin(), m_route.end(), 0 /* route id */); + FillSubroutesInfo(route); + return m_returnCodes[m_returnCodesIdx++]; + } -static auto kRouteBuildingMaxDuration = seconds(30); +private: + vector<RouterResultCode> m_returnCodes; + vector<m2::PointD> m_route; + size_t m_returnCodesIdx = 0; +}; class TimedSignal { @@ -96,12 +126,34 @@ public: SessionStateTest(initializer_list<SessionState> expectedStates, RoutingSession & routingSession) : m_expectedStates(expectedStates), m_session(routingSession) { - m_session.SetChangeSessionStateCallback([this](SessionState previous, SessionState current) { - TestChangeSessionStateCallbackCall(previous, current); + for (size_t i = 1; i < expectedStates.size(); ++i) + { + // Note. Change session state callback is called only if the state is change. + if (m_expectedStates[i - 1] != m_expectedStates[i]) + ++m_expectedNumberOfStateChanging; + } + + TimedSignal timedSignal; + GetPlatform().RunTask(Platform::Thread::Gui, [this, &timedSignal]() { + m_session.SetChangeSessionStateCallback([this](SessionState previous, SessionState current) { + TestChangeSessionStateCallbackCall(previous, current); + }); + timedSignal.Signal(); }); + TEST(timedSignal.WaitUntil(steady_clock::now() + kRouteBuildingMaxDuration), ("Callback is not set.")); } - ~SessionStateTest() { m_session.SetChangeSessionStateCallback(nullptr); } + ~SessionStateTest() + { + TEST_EQUAL(m_numberOfTestCalls, m_expectedNumberOfStateChanging, + ("Wrong number of calls of SetState() callback.", m_expectedStates)); + TimedSignal timedSignal; + GetPlatform().RunTask(Platform::Thread::Gui, [this, &timedSignal]() { + m_session.SetChangeSessionStateCallback(nullptr); + timedSignal.Signal(); + }); + TEST(timedSignal.WaitUntil(steady_clock::now() + kRouteBuildingMaxDuration), ("Callback is not set.")); + } private: void TestChangeSessionStateCallbackCall(SessionState previous, SessionState current) @@ -116,6 +168,7 @@ private: size_t m_numberOfTestCalls = 0; vector<SessionState> const m_expectedStates; + size_t m_expectedNumberOfStateChanging = 0; RoutingSession & m_session; }; @@ -133,6 +186,36 @@ void FillSubroutesInfo(Route & route) {Route::SubrouteAttrs(junctions.front(), junctions.back(), 0, kTestSegments.size())})); } +void TestMovingByUpdatingLat(SessionStateTest const & sessionState, vector<double> const & lats, + location::GpsInfo const & info, RoutingSession & session) +{ + location::GpsInfo uptInfo(info); + TimedSignal signal; + GetPlatform().RunTask(Platform::Thread::Gui, [&session, &signal, &lats, &uptInfo]() { + for (auto const lat : lats) + { + uptInfo.m_latitude = lat; + session.OnLocationPositionChanged(uptInfo); + } + + signal.Signal(); + }); + TEST(signal.WaitUntil(steady_clock::now() + kRouteBuildingMaxDuration), + ("Along route moving timeout.")); +} + +void TestLeavingRoute(RoutingSession & session, location::GpsInfo const & info) +{ + vector<double> const latitudes = {0.0, -0.001, -0.002, -0.003, -0.004, -0.005, + -0.006, -0.007, -0.008, -0.009, -0.01, -0.011}; + SessionStateTest sessionStateTest({SessionState::OnRoute, SessionState::RouteNeedRebuild}, + session); + TestMovingByUpdatingLat(sessionStateTest, latitudes, info, session); +} +} // namespace + +namespace routing +{ UNIT_CLASS_TEST(AsyncGuiThreadTestWithRoutingSession, TestRouteBuilding) { // Multithreading synchronization note. |counter| and |session| are constructed on the main thread, @@ -169,7 +252,6 @@ UNIT_CLASS_TEST(AsyncGuiThreadTestWithRoutingSession, TestRouteBuilding) UNIT_CLASS_TEST(AsyncGuiThreadTestWithRoutingSession, TestRouteRebuildingMovingAway) { location::GpsInfo info; - FrozenDataSource dataSource; size_t counter = 0; TimedSignal alongTimedSignal; @@ -193,40 +275,40 @@ UNIT_CLASS_TEST(AsyncGuiThreadTestWithRoutingSession, TestRouteRebuildingMovingA TEST(alongTimedSignal.WaitUntil(steady_clock::now() + kRouteBuildingMaxDuration), ("Route was not built.")); TEST_EQUAL(counter, 1, ()); - TimedSignal oppositeTimedSignal; - GetPlatform().RunTask(Platform::Thread::Gui, [&oppositeTimedSignal, &info, this]() { - info.m_horizontalAccuracy = 0.01; - info.m_verticalAccuracy = 0.01; - info.m_longitude = 0.; - info.m_latitude = 1.; - SessionState code = SessionState::NoValidRoute; + { + SessionStateTest sessionStateTest( + {SessionState::RouteNotStarted, SessionState::OnRoute, SessionState::RouteBuilding, + SessionState::RouteNotStarted}, + *m_session); + TimedSignal oppositeTimedSignal; + GetPlatform().RunTask(Platform::Thread::Gui, [&oppositeTimedSignal, &info, this]() { + info.m_horizontalAccuracy = 0.01; + info.m_verticalAccuracy = 0.01; + info.m_longitude = 0.; + info.m_latitude = 1.; + SessionState code = SessionState::NoValidRoute; - { - SessionStateTest sessionStateTest({SessionState::RouteNotStarted, SessionState::OnRoute}, - *m_session); - while (info.m_latitude < kTestRoute.back().y) { - code = m_session->OnLocationPositionChanged(info); - TEST_EQUAL(code, SessionState::OnRoute, ()); - info.m_latitude += 0.01; + while (info.m_latitude < kTestRoute.back().y) + { + code = m_session->OnLocationPositionChanged(info); + TEST_EQUAL(code, SessionState::OnRoute, ()); + info.m_latitude += 0.01; + } } - } - // Rebuild route and go in opposite direction. So initiate a route rebuilding flag. - m_session->SetRoutingCallbacks( - [&oppositeTimedSignal](Route const &, RouterResultCode) { oppositeTimedSignal.Signal(); }, - nullptr /* rebuildReadyCallback */, nullptr /* needMoreMapsCallback */, - nullptr /* removeRouteCallback */); - { - SessionStateTest sessionStateTest( - {SessionState::OnRoute, SessionState::RouteBuilding}, - *m_session); - - m_session->BuildRoute(Checkpoints(kTestRoute.front(), kTestRoute.back()), - RouterDelegate::kNoTimeout); - } - }); - TEST(oppositeTimedSignal.WaitUntil(steady_clock::now() + kRouteBuildingMaxDuration), ("Route was not built.")); + // Rebuild route and go in opposite direction. So initiate a route rebuilding flag. + m_session->SetRoutingCallbacks( + [&oppositeTimedSignal](Route const &, RouterResultCode) { oppositeTimedSignal.Signal(); }, + nullptr /* rebuildReadyCallback */, nullptr /* needMoreMapsCallback */, + nullptr /* removeRouteCallback */); + { + m_session->BuildRoute(Checkpoints(kTestRoute.front(), kTestRoute.back()), + RouterDelegate::kNoTimeout); + } + }); + TEST(oppositeTimedSignal.WaitUntil(steady_clock::now() + kRouteBuildingMaxDuration), ("Route was not built.")); + } // Going away from route to set rebuilding flag. TimedSignal checkTimedSignal; @@ -252,7 +334,6 @@ UNIT_CLASS_TEST(AsyncGuiThreadTestWithRoutingSession, TestRouteRebuildingMovingA UNIT_CLASS_TEST(AsyncGuiThreadTestWithRoutingSession, TestRouteRebuildingMovingToRoute) { location::GpsInfo info; - FrozenDataSource dataSource; size_t counter = 0; TimedSignal alongTimedSignal; @@ -276,33 +357,34 @@ UNIT_CLASS_TEST(AsyncGuiThreadTestWithRoutingSession, TestRouteRebuildingMovingT TEST_EQUAL(counter, 1, ()); // Going starting far from the route and moving to the route but rebuild flag still is set. - TimedSignal checkTimedSignalAway; - GetPlatform().RunTask(Platform::Thread::Gui, [&checkTimedSignalAway, &info, this]() { - info.m_longitude = 0.0; - info.m_latitude = 0.0; - info.m_speedMpS = routing::KMPH2MPS(60); - SessionState code = SessionState::NoValidRoute; - { - SessionStateTest sessionStateTest( - {SessionState::RouteNotStarted, SessionState::RouteNeedRebuild}, - *m_session); - for (size_t i = 0; i < 8; ++i) + { + SessionStateTest sessionStateTest( + {SessionState::RouteNotStarted, SessionState::RouteNeedRebuild}, + *m_session); + TimedSignal checkTimedSignalAway; + GetPlatform().RunTask(Platform::Thread::Gui, [&checkTimedSignalAway, &info, this]() { + info.m_longitude = 0.0; + info.m_latitude = 0.0; + info.m_speedMpS = routing::KMPH2MPS(60); + SessionState code = SessionState::NoValidRoute; { - code = m_session->OnLocationPositionChanged(info); - info.m_latitude += 0.1; + for (size_t i = 0; i < 8; ++i) + { + code = m_session->OnLocationPositionChanged(info); + info.m_latitude += 0.1; + } } - } - TEST_EQUAL(code, SessionState::RouteNeedRebuild, ()); - checkTimedSignalAway.Signal(); - }); - TEST(checkTimedSignalAway.WaitUntil(steady_clock::now() + kRouteBuildingMaxDuration), - ("Route was not rebuilt.")); + TEST_EQUAL(code, SessionState::RouteNeedRebuild, ()); + checkTimedSignalAway.Signal(); + }); + TEST(checkTimedSignalAway.WaitUntil(steady_clock::now() + kRouteBuildingMaxDuration), + ("Route was not rebuilt.")); + } } UNIT_CLASS_TEST(AsyncGuiThreadTestWithRoutingSession, TestFollowRouteFlagPersistence) { location::GpsInfo info; - FrozenDataSource dataSource; size_t counter = 0; TimedSignal alongTimedSignal; @@ -389,7 +471,6 @@ UNIT_CLASS_TEST(AsyncGuiThreadTestWithRoutingSession, TestFollowRouteFlagPersist UNIT_CLASS_TEST(AsyncGuiThreadTestWithRoutingSession, TestFollowRoutePercentTest) { - FrozenDataSource dataSource; TimedSignal alongTimedSignal; GetPlatform().RunTask(Platform::Thread::Gui, [&alongTimedSignal, this]() { InitRoutingSession(); @@ -451,4 +532,89 @@ UNIT_CLASS_TEST(AsyncGuiThreadTestWithRoutingSession, TestFollowRoutePercentTest TEST(checkTimedSignal.WaitUntil(steady_clock::now() + kRouteBuildingMaxDuration), ("Route checking timeout.")); } + +UNIT_CLASS_TEST(AsyncGuiThreadTestWithRoutingSession, TestRouteRebuildingError) +{ + vector<m2::PointD> const kRoute = {{0.0, 0.001}, {0.0, 0.002}, {0.0, 0.003}, {0.0, 0.004}}; + // Creation RoutingSession. + TimedSignal createTimedSignal; + GetPlatform().RunTask(Platform::Thread::Gui, [this, &kRoute, &createTimedSignal]() { + InitRoutingSession(); + unique_ptr<ReturnCodesRouter> router = make_unique<ReturnCodesRouter>(initializer_list< + RouterResultCode>{RouterResultCode::NoError, RouterResultCode::InternalError}, kRoute); + m_session->SetRouter(move(router), nullptr); + createTimedSignal.Signal(); + }); + TEST(createTimedSignal.WaitUntil(steady_clock::now() + kRouteBuildingMaxDuration), + ("RouteSession was not created.")); + + // Building a route. + { + SessionStateTest sessionStateTest( + {SessionState::NoValidRoute, SessionState::RouteBuilding, SessionState::RouteNotStarted}, + *m_session); + TimedSignal buildTimedSignal; + GetPlatform().RunTask(Platform::Thread::Gui, [this, &kRoute, &buildTimedSignal]() { + m_session->SetRoutingCallbacks( + [&buildTimedSignal](Route const &, RouterResultCode) { buildTimedSignal.Signal(); }, + nullptr /* rebuildReadyCallback */, nullptr /* needMoreMapsCallback */, + nullptr /* removeRouteCallback */); + + m_session->BuildRoute(Checkpoints(kRoute.front(), kRoute.back()), + RouterDelegate::kNoTimeout); + }); + TEST(buildTimedSignal + .WaitUntil(steady_clock::now() + kRouteBuildingMaxDuration), ("Route was not built.")); + } + + location::GpsInfo info; + info.m_horizontalAccuracy = 5.0; // meters + info.m_verticalAccuracy = 5.0; // meters + info.m_longitude = 0.0; + + // Moving along route. + { + SessionStateTest sessionStateTest({SessionState::RouteNotStarted, SessionState::OnRoute}, + *m_session); + vector<double> const latitudes = {0.001, 0.0015, 0.002}; + TestMovingByUpdatingLat(sessionStateTest, latitudes, info, *m_session); + } + + // Leaving the route until switching to |SessionState::RouteNeedRebuild| state. + TestLeavingRoute(*m_session, info); + + // Continue moving along the route. + { + SessionStateTest sessionStateTest({SessionState::RouteNeedRebuild, SessionState::OnRoute}, + *m_session); + vector<double> const latitudes = {0.002, 0.0025, 0.003}; + TestMovingByUpdatingLat(sessionStateTest, latitudes, info, *m_session); + } + + // Leaving the route until switching to |SessionState::RouteRebuilding| state. + TestLeavingRoute(*m_session, info); + { + SessionStateTest sessionStateTest( + {SessionState::RouteNeedRebuild, SessionState::RouteRebuilding, + SessionState::RouteNotStarted + }, + *m_session); + TimedSignal signal; + GetPlatform().RunTask(Platform::Thread::Gui, [this, &signal]() { + m_session->SetState(SessionState::RouteRebuilding); + m_session->SetState(SessionState::RouteNotStarted); + signal.Signal(); + }); + TEST(signal.WaitUntil(steady_clock::now() + kRouteBuildingMaxDuration), + ("State was not set.")); + } + + // Continue moving along the route again. + { + SessionStateTest sessionStateTest({SessionState::RouteNotStarted, SessionState::OnRoute}, + *m_session); + vector<double> const latitudes = {0.003, 0.0035, 0.004}; + TestMovingByUpdatingLat(sessionStateTest, latitudes, info, *m_session); + } +} } // namespace routing |