Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(801)

Side by Side Diff: content/browser/geolocation/gps_location_provider_unittest_linux.cc

Issue 8463022: Make chrome communicate with gpsd through libgps/shared memory (Closed) Base URL: http://git.chromium.org/git/chromium.git@trunk
Patch Set: addressing joth@ 's comments Created 9 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/browser/browser_thread_impl.h" 5 #include "content/browser/browser_thread_impl.h"
6 #include "content/browser/geolocation/gps_location_provider_linux.h" 6 #include "content/browser/geolocation/gps_location_provider_linux.h"
7 #include "content/browser/geolocation/libgps_wrapper_linux.h" 7 #include "content/browser/geolocation/libgps_wrapper_linux.h"
8 #include "testing/gtest/include/gtest/gtest.h" 8 #include "testing/gtest/include/gtest/gtest.h"
9 9
10 #include "base/bind.h"
11
10 using content::BrowserThread; 12 using content::BrowserThread;
11 using content::BrowserThreadImpl; 13 using content::BrowserThreadImpl;
12 14
13 struct gps_data_t {
14 };
15
16 namespace { 15 namespace {
17 class MockLibGps : public LibGps { 16 class MockLibGps : public LibGps {
18 public: 17 public:
19 MockLibGps(); 18 MockLibGps();
20 ~MockLibGps(); 19 ~MockLibGps();
21 20
22 virtual bool StartStreaming() {
23 ++start_streaming_calls_;
24 return start_streaming_ret_;
25 }
26 virtual bool DataWaiting() {
27 EXPECT_GT(start_streaming_calls_, 0);
28 ++data_waiting_calls_;
29 // Toggle the return value, so the poll loop will exit once per test step.
30 return (data_waiting_calls_ & 1) != 0;
31 }
32 virtual bool GetPositionIfFixed(Geoposition* position) { 21 virtual bool GetPositionIfFixed(Geoposition* position) {
33 CHECK(position); 22 CHECK(position);
34 EXPECT_GT(start_streaming_calls_, 0);
35 EXPECT_GT(data_waiting_calls_, 0);
36 ++get_position_calls_; 23 ++get_position_calls_;
37 *position = get_position_; 24 *position = get_position_;
38 return get_position_ret_; 25 return get_position_ret_;
26 }
39 27
28 static int gps_open_stub(const char*, const char*, struct gps_data_t*) {
29 CHECK(g_instance_);
30 g_instance_->gps_open_calls_++;
31 return g_instance_->gps_open_ret_;
40 } 32 }
41 int start_streaming_calls_; 33
42 bool start_streaming_ret_; 34 static int gps_close_stub(struct gps_data_t*) {
43 int data_waiting_calls_; 35 return 0;
36 }
37
38 static int gps_read_stub(struct gps_data_t*) {
39 CHECK(g_instance_);
40 g_instance_->gps_read_calls_++;
41 return g_instance_->gps_read_ret_;
42 }
43
44 int get_position_calls_; 44 int get_position_calls_;
45 bool get_position_ret_;
46 int gps_open_calls_;
47 int gps_open_ret_;
48 int gps_read_calls_;
49 int gps_read_ret_;
45 Geoposition get_position_; 50 Geoposition get_position_;
46 bool get_position_ret_;
47 static MockLibGps* g_instance_; 51 static MockLibGps* g_instance_;
48 }; 52 };
49 53
50 class LocaionProviderListenerLoopQuitter 54 class LocaionProviderListenerLoopQuitter
51 : public LocationProviderBase::ListenerInterface { 55 : public LocationProviderBase::ListenerInterface {
52 // LocationProviderBase::ListenerInterface 56 // LocationProviderBase::ListenerInterface
53 virtual void LocationUpdateAvailable(LocationProviderBase* provider) { 57 virtual void LocationUpdateAvailable(LocationProviderBase* provider) {
54 MessageLoop::current()->Quit(); 58 MessageLoop::current()->Quit();
55 } 59 }
56 }; 60 };
57 61
58 class GeolocationGpsProviderLinuxTests : public testing::Test { 62 class GeolocationGpsProviderLinuxTests : public testing::Test {
59 public: 63 public:
60 GeolocationGpsProviderLinuxTests(); 64 GeolocationGpsProviderLinuxTests();
61 ~GeolocationGpsProviderLinuxTests(); 65 ~GeolocationGpsProviderLinuxTests();
62 66
63 static LibGps* NewMockLibGps() { 67 static LibGps* NewMockLibGps() {
64 return new MockLibGps; 68 return new MockLibGps();
65 } 69 }
66 static LibGps* NoLibGpsFactory() { 70 static LibGps* NoLibGpsFactory() {
67 return NULL; 71 return NULL;
68 } 72 }
69 73
70 protected: 74 protected:
71 MessageLoop message_loop_; 75 MessageLoop message_loop_;
72 BrowserThreadImpl ui_thread_; 76 BrowserThreadImpl ui_thread_;
73 LocaionProviderListenerLoopQuitter location_listener_; 77 LocaionProviderListenerLoopQuitter location_listener_;
74 scoped_ptr<GpsLocationProviderLinux> provider_; 78 scoped_ptr<GpsLocationProviderLinux> provider_;
75 }; 79 };
76 80
77 gps_data_t* gps_open_stub(const char*, const char*) {
78 // Need to return a non-NULL value here to indicate success, however we don't
79 // need (or want) a valid pointer as it should never be dereferenced.
80 return static_cast<gps_data_t*>(NULL) + 1;
81 }
82 int gps_close_stub(gps_data_t*) {
83 return 0;
84 }
85 int gps_poll_stub(gps_data_t*) {
86 return 0;
87 }
88 // v2.90+
89 int gps_stream_stub(gps_data_t*, unsigned int, void*) {
90 return 0;
91 }
92 bool gps_waiting_stub(gps_data_t*) {
93 return 0;
94 }
95
96 void CheckValidPosition(const Geoposition& expected, 81 void CheckValidPosition(const Geoposition& expected,
97 const Geoposition& actual) { 82 const Geoposition& actual) {
98 EXPECT_TRUE(actual.IsValidFix()); 83 EXPECT_TRUE(actual.IsValidFix());
99 EXPECT_DOUBLE_EQ(expected.latitude, actual.latitude); 84 EXPECT_DOUBLE_EQ(expected.latitude, actual.latitude);
100 EXPECT_DOUBLE_EQ(expected.longitude, actual.longitude); 85 EXPECT_DOUBLE_EQ(expected.longitude, actual.longitude);
101 EXPECT_DOUBLE_EQ(expected.accuracy, actual.accuracy); 86 EXPECT_DOUBLE_EQ(expected.accuracy, actual.accuracy);
102 } 87 }
103 88
104 MockLibGps* MockLibGps::g_instance_ = NULL; 89 MockLibGps* MockLibGps::g_instance_ = NULL;
105 90
106 MockLibGps::MockLibGps() 91 MockLibGps::MockLibGps()
107 : LibGps(new LibGpsLibraryWrapper(NULL, 92 : LibGps(NULL, gps_open_stub, gps_close_stub, gps_read_stub),
108 gps_open_stub,
109 gps_close_stub,
110 gps_poll_stub,
111 gps_stream_stub,
112 gps_waiting_stub)),
113 start_streaming_calls_(0),
114 start_streaming_ret_(true),
115 data_waiting_calls_(0),
116 get_position_calls_(0), 93 get_position_calls_(0),
117 get_position_ret_(true) { 94 get_position_ret_(true),
95 gps_open_calls_(0),
96 gps_open_ret_(0),
97 gps_read_calls_(0),
98 gps_read_ret_(0) {
118 get_position_.error_code = Geoposition::ERROR_CODE_POSITION_UNAVAILABLE; 99 get_position_.error_code = Geoposition::ERROR_CODE_POSITION_UNAVAILABLE;
119 EXPECT_FALSE(g_instance_); 100 EXPECT_FALSE(g_instance_);
120 g_instance_ = this; 101 g_instance_ = this;
121 } 102 }
122 103
123 MockLibGps::~MockLibGps() { 104 MockLibGps::~MockLibGps() {
124 EXPECT_EQ(this, g_instance_); 105 EXPECT_EQ(this, g_instance_);
125 g_instance_ = NULL; 106 g_instance_ = NULL;
126 } 107 }
127 108
(...skipping 12 matching lines...) Expand all
140 ASSERT_TRUE(provider_.get()); 121 ASSERT_TRUE(provider_.get());
141 const bool ok = provider_->StartProvider(true); 122 const bool ok = provider_->StartProvider(true);
142 EXPECT_FALSE(ok); 123 EXPECT_FALSE(ok);
143 Geoposition position; 124 Geoposition position;
144 provider_->GetPosition(&position); 125 provider_->GetPosition(&position);
145 EXPECT_TRUE(position.IsInitialized()); 126 EXPECT_TRUE(position.IsInitialized());
146 EXPECT_FALSE(position.IsValidFix()); 127 EXPECT_FALSE(position.IsValidFix());
147 EXPECT_EQ(Geoposition::ERROR_CODE_POSITION_UNAVAILABLE, position.error_code); 128 EXPECT_EQ(Geoposition::ERROR_CODE_POSITION_UNAVAILABLE, position.error_code);
148 } 129 }
149 130
131 #if defined(OS_CHROMEOS)
132
150 TEST_F(GeolocationGpsProviderLinuxTests, GetPosition) { 133 TEST_F(GeolocationGpsProviderLinuxTests, GetPosition) {
151 ASSERT_TRUE(provider_.get()); 134 ASSERT_TRUE(provider_.get());
152 const bool ok = provider_->StartProvider(true); 135 const bool ok = provider_->StartProvider(true);
153 EXPECT_TRUE(ok); 136 EXPECT_TRUE(ok);
154 ASSERT_TRUE(MockLibGps::g_instance_); 137 ASSERT_TRUE(MockLibGps::g_instance_);
155 EXPECT_EQ(0, MockLibGps::g_instance_->start_streaming_calls_);
156 EXPECT_EQ(0, MockLibGps::g_instance_->data_waiting_calls_);
157 EXPECT_EQ(0, MockLibGps::g_instance_->get_position_calls_); 138 EXPECT_EQ(0, MockLibGps::g_instance_->get_position_calls_);
139 EXPECT_EQ(0, MockLibGps::g_instance_->gps_open_calls_);
140 EXPECT_EQ(0, MockLibGps::g_instance_->gps_read_calls_);
158 Geoposition position; 141 Geoposition position;
159 provider_->GetPosition(&position); 142 provider_->GetPosition(&position);
160 EXPECT_TRUE(position.IsInitialized()); 143 EXPECT_TRUE(position.IsInitialized());
161 EXPECT_FALSE(position.IsValidFix()); 144 EXPECT_FALSE(position.IsValidFix());
162 EXPECT_EQ(Geoposition::ERROR_CODE_POSITION_UNAVAILABLE, position.error_code); 145 EXPECT_EQ(Geoposition::ERROR_CODE_POSITION_UNAVAILABLE, position.error_code);
163 MockLibGps::g_instance_->get_position_.error_code = 146 MockLibGps::g_instance_->get_position_.error_code =
164 Geoposition::ERROR_CODE_NONE; 147 Geoposition::ERROR_CODE_NONE;
165 MockLibGps::g_instance_->get_position_.latitude = 4.5; 148 MockLibGps::g_instance_->get_position_.latitude = 4.5;
166 MockLibGps::g_instance_->get_position_.longitude = -34.1; 149 MockLibGps::g_instance_->get_position_.longitude = -34.1;
167 MockLibGps::g_instance_->get_position_.accuracy = 345; 150 MockLibGps::g_instance_->get_position_.accuracy = 345;
168 MockLibGps::g_instance_->get_position_.timestamp = 151 MockLibGps::g_instance_->get_position_.timestamp =
169 base::Time::FromDoubleT(200); 152 base::Time::FromDoubleT(200);
170 EXPECT_TRUE(MockLibGps::g_instance_->get_position_.IsValidFix()); 153 EXPECT_TRUE(MockLibGps::g_instance_->get_position_.IsValidFix());
171
172 MessageLoop::current()->Run(); 154 MessageLoop::current()->Run();
173 EXPECT_GT(MockLibGps::g_instance_->start_streaming_calls_, 0);
174 EXPECT_GT(MockLibGps::g_instance_->data_waiting_calls_, 0);
175 EXPECT_EQ(1, MockLibGps::g_instance_->get_position_calls_); 155 EXPECT_EQ(1, MockLibGps::g_instance_->get_position_calls_);
156 EXPECT_EQ(1, MockLibGps::g_instance_->gps_open_calls_);
157 EXPECT_EQ(1, MockLibGps::g_instance_->gps_read_calls_);
176 provider_->GetPosition(&position); 158 provider_->GetPosition(&position);
177 CheckValidPosition(MockLibGps::g_instance_->get_position_, position); 159 CheckValidPosition(MockLibGps::g_instance_->get_position_, position);
178 160
179 // Movement. This will block for up to half a second. 161 // Movement. This will block for up to half a second.
180 MockLibGps::g_instance_->get_position_.latitude += 0.01; 162 MockLibGps::g_instance_->get_position_.latitude += 0.01;
181 MessageLoop::current()->Run(); 163 MessageLoop::current()->Run();
182 provider_->GetPosition(&position); 164 provider_->GetPosition(&position);
183 EXPECT_EQ(2, MockLibGps::g_instance_->get_position_calls_); 165 EXPECT_EQ(2, MockLibGps::g_instance_->get_position_calls_);
166 EXPECT_EQ(1, MockLibGps::g_instance_->gps_open_calls_);
167 EXPECT_EQ(2, MockLibGps::g_instance_->gps_read_calls_);
184 CheckValidPosition(MockLibGps::g_instance_->get_position_, position); 168 CheckValidPosition(MockLibGps::g_instance_->get_position_, position);
185 } 169 }
186 170
187 // TODO(joth): Add a test for LibGps::Start() returning false (i.e. gpsd not 171 class EnableGpsOpenTask : public Task {
188 // running). Need to work around the 10s reconnect delay (either by injecting 172 public:
189 // a shorter retry interval, or adapt MessageLoop / Time::Now to be more test 173 virtual void Run() {
190 // friendly). 174 CHECK(MockLibGps::g_instance_);
175 MockLibGps::g_instance_->gps_open_ret_ = 0;
176 }
177 };
178
179 TEST_F(GeolocationGpsProviderLinuxTests, LibGpsReconnect) {
180 // Setup gpsd reconnect interval to be 1000ms to speed up test.
181 provider_->SetGpsdReconnectIntervalMillis(1000);
182 provider_->SetPollPeriodMovingMillis(200);
183 const bool ok = provider_->StartProvider(true);
184 EXPECT_TRUE(ok);
185 ASSERT_TRUE(MockLibGps::g_instance_);
186 // Let gps_open() fails, and so will LibGps::Start().
187 // Reconnect will happen in 1000ms.
188 MockLibGps::g_instance_->gps_open_ret_ = 1;
189 Geoposition position;
190 MockLibGps::g_instance_->get_position_.error_code =
191 Geoposition::ERROR_CODE_NONE;
192 MockLibGps::g_instance_->get_position_.latitude = 4.5;
193 MockLibGps::g_instance_->get_position_.longitude = -34.1;
194 MockLibGps::g_instance_->get_position_.accuracy = 345;
195 MockLibGps::g_instance_->get_position_.timestamp =
196 base::Time::FromDoubleT(200);
197 EXPECT_TRUE(MockLibGps::g_instance_->get_position_.IsValidFix());
198 // This task makes gps_open() and LibGps::Start() to succeed after
199 // 1500ms.
200 MessageLoop::current()->PostDelayedTask(
201 FROM_HERE, new EnableGpsOpenTask(), 1500);
202 MessageLoop::current()->Run();
203 provider_->GetPosition(&position);
204 EXPECT_TRUE(position.IsInitialized());
205 EXPECT_TRUE(position.IsValidFix());
206 // 3 gps_open() calls are expected (2 failures and 1 success)
207 EXPECT_EQ(1, MockLibGps::g_instance_->get_position_calls_);
208 EXPECT_EQ(3, MockLibGps::g_instance_->gps_open_calls_);
209 EXPECT_EQ(1, MockLibGps::g_instance_->gps_read_calls_);
210 }
211
212 #endif // #if defined(OS_CHROMEOS)
191 213
192 } // namespace 214 } // namespace
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698