Welcome to mirror list, hosted at ThFree Co, Russian Federation.

async_router_test.cpp « routing_tests « routing - github.com/mapsme/omim.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: db2f89d19235c98343d6e45f705ecf11dc742c80 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
#include "testing/testing.hpp"

#include "routing/routing_tests/tools.hpp"

#include "routing/async_router.hpp"
#include "routing/router.hpp"
#include "routing/routing_callbacks.hpp"
#include "routing/online_absent_fetcher.hpp"

#include "geometry/point2d.hpp"

#include "platform/platform.hpp"

#include "base/timer.hpp"

#include <condition_variable>
#include <cstdint>
#include <memory>
#include <mutex>
#include <string>
#include <vector>

using namespace routing;
using namespace std::placeholders;
using namespace std;

namespace
{
class DummyRouter : public IRouter
{
  RouterResultCode m_result;
  set<string> m_absent;

public:
  DummyRouter(RouterResultCode code, set<string> const & absent) : m_result(code), m_absent(absent) {}
  
  // IRouter overrides:
  string GetName() const override { return "Dummy"; }
  RouterResultCode CalculateRoute(Checkpoints const & checkpoints, m2::PointD const & startDirection,
                            bool adjustToPrevRoute, RouterDelegate const & delegate,
                            Route & route) override
  {
    route = Route("dummy", checkpoints.GetPoints().cbegin(), checkpoints.GetPoints().cend(),
                  0 /* route id */);

    for (auto const & absent : m_absent)
      route.AddAbsentCountry(absent);

    return m_result;
  }
};

class DummyFetcher : public IOnlineFetcher
{
  set<string> m_absent;

public:
  explicit DummyFetcher(set<string> const & absent) : m_absent(absent) {}

  // IOnlineFetcher overrides:
  void GenerateRequest(Checkpoints const &) override {}
  void GetAbsentCountries(set<string> & countries) override { countries = m_absent; }
};

void DummyStatisticsCallback(map<string, string> const &) {}

struct DummyRoutingCallbacks
{
  vector<RouterResultCode> m_codes;
  vector<set<string>> m_absent;
  condition_variable m_cv;
  mutex m_lock;
  uint32_t const m_expected;
  uint32_t m_called;

  explicit DummyRoutingCallbacks(uint32_t expectedCalls) : m_expected(expectedCalls), m_called(0) {}

  // ReadyCallbackOwnership callback
  void operator()(shared_ptr<Route> route, RouterResultCode code)
  {
    CHECK(route, ());
    m_codes.push_back(code);
    m_absent.emplace_back(route->GetAbsentCountries());
    TestAndNotifyReadyCallbacks();
  }

  // NeedMoreMapsCallback callback
  void operator()(uint64_t routeId, set<string> const & absent)
  {
    m_codes.push_back(RouterResultCode::NeedMoreMaps);
    m_absent.emplace_back(absent);
    TestAndNotifyReadyCallbacks();
  }

  void WaitFinish()
  {
    unique_lock<mutex> lk(m_lock);
    return m_cv.wait(lk, [this] { return m_called == m_expected; });
  }

  void TestAndNotifyReadyCallbacks()
  {
    {
      lock_guard<mutex> calledLock(m_lock);
      ++m_called;
      TEST_LESS_OR_EQUAL(m_called, m_expected,
                         ("The result callback called more times than expected."));
    }
    m_cv.notify_all();
  }
};

UNIT_CLASS_TEST(AsyncGuiThreadTest, NeedMoreMapsSignalTest)
{
  set<string> const absentData({"test1", "test2"});
  unique_ptr<IOnlineFetcher> fetcher(new DummyFetcher(absentData));
  unique_ptr<IRouter> router(new DummyRouter(RouterResultCode::NoError, {}));
  DummyRoutingCallbacks resultCallback(2 /* expectedCalls */);
  AsyncRouter async(DummyStatisticsCallback, nullptr /* pointCheckCallback */);
  async.SetRouter(move(router), move(fetcher));
  async.CalculateRoute(Checkpoints({1, 2} /* start */, {5, 6} /* finish */), {3, 4}, false,
                       bind(ref(resultCallback), _1, _2) /* readyCallback */,
                       bind(ref(resultCallback), _1, _2) /* needMoreMapsCallback */,
                       nullptr /* removeRouteCallback */, nullptr /* progressCallback */);

  resultCallback.WaitFinish();

  TEST_EQUAL(resultCallback.m_codes.size(), 2, ());
  TEST_EQUAL(resultCallback.m_codes[0], RouterResultCode::NoError, ());
  TEST_EQUAL(resultCallback.m_codes[1], RouterResultCode::NeedMoreMaps, ());
  TEST_EQUAL(resultCallback.m_absent.size(), 2, ());
  TEST(resultCallback.m_absent[0].empty(), ());
  TEST_EQUAL(resultCallback.m_absent[1].size(), 2, ());
  TEST_EQUAL(resultCallback.m_absent[1], absentData, ());
}

UNIT_CLASS_TEST(AsyncGuiThreadTest, StandardAsyncFogTest)
{
  unique_ptr<IOnlineFetcher> fetcher(new DummyFetcher({}));
  unique_ptr<IRouter> router(new DummyRouter(RouterResultCode::NoError, {}));
  DummyRoutingCallbacks resultCallback(1 /* expectedCalls */);
  AsyncRouter async(DummyStatisticsCallback, nullptr /* pointCheckCallback */);
  async.SetRouter(move(router), move(fetcher));
  async.CalculateRoute(Checkpoints({1, 2} /* start */, {5, 6} /* finish */), {3, 4}, false,
                       bind(ref(resultCallback), _1, _2), nullptr /* needMoreMapsCallback */,
                       nullptr /* progressCallback */, nullptr /* removeRouteCallback */);

  resultCallback.WaitFinish();

  TEST_EQUAL(resultCallback.m_codes.size(), 1, ());
  TEST_EQUAL(resultCallback.m_codes[0], RouterResultCode::NoError, ());
  TEST_EQUAL(resultCallback.m_absent.size(), 1, ());
  TEST(resultCallback.m_absent[0].empty(), ());
}
}  //  namespace