Mark //testing/perf target testonly.
[chromium-blink-merge.git] / device / bluetooth / bluetooth_socket_chromeos_unittest.cc
blob8381cdd0b986dc8fe05087c02047f18d4ea06137
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "base/bind.h"
6 #include "base/memory/ref_counted.h"
7 #include "base/message_loop/message_loop.h"
8 #include "chromeos/dbus/dbus_thread_manager.h"
9 #include "chromeos/dbus/fake_bluetooth_adapter_client.h"
10 #include "chromeos/dbus/fake_bluetooth_agent_manager_client.h"
11 #include "chromeos/dbus/fake_bluetooth_device_client.h"
12 #include "chromeos/dbus/fake_bluetooth_gatt_service_client.h"
13 #include "chromeos/dbus/fake_bluetooth_input_client.h"
14 #include "chromeos/dbus/fake_bluetooth_profile_manager_client.h"
15 #include "chromeos/dbus/fake_bluetooth_profile_service_provider.h"
16 #include "device/bluetooth/bluetooth_adapter.h"
17 #include "device/bluetooth/bluetooth_adapter_chromeos.h"
18 #include "device/bluetooth/bluetooth_adapter_factory.h"
19 #include "device/bluetooth/bluetooth_device.h"
20 #include "device/bluetooth/bluetooth_device_chromeos.h"
21 #include "device/bluetooth/bluetooth_socket.h"
22 #include "device/bluetooth/bluetooth_socket_chromeos.h"
23 #include "device/bluetooth/bluetooth_socket_thread.h"
24 #include "device/bluetooth/bluetooth_uuid.h"
25 #include "net/base/io_buffer.h"
26 #include "net/base/net_errors.h"
27 #include "testing/gtest/include/gtest/gtest.h"
29 using device::BluetoothAdapter;
30 using device::BluetoothDevice;
31 using device::BluetoothSocket;
32 using device::BluetoothSocketThread;
33 using device::BluetoothUUID;
35 namespace {
37 void DoNothingDBusErrorCallback(const std::string& error_name,
38 const std::string& error_message) {}
40 } // namespace
42 namespace chromeos {
44 class BluetoothSocketChromeOSTest : public testing::Test {
45 public:
46 BluetoothSocketChromeOSTest()
47 : success_callback_count_(0),
48 error_callback_count_(0),
49 last_bytes_sent_(0),
50 last_bytes_received_(0),
51 last_reason_(BluetoothSocket::kSystemError) {}
53 void SetUp() override {
54 scoped_ptr<DBusThreadManagerSetter> dbus_setter =
55 DBusThreadManager::GetSetterForTesting();
57 dbus_setter->SetBluetoothAdapterClient(
58 scoped_ptr<BluetoothAdapterClient>(new FakeBluetoothAdapterClient));
59 dbus_setter->SetBluetoothAgentManagerClient(
60 scoped_ptr<BluetoothAgentManagerClient>(
61 new FakeBluetoothAgentManagerClient));
62 dbus_setter->SetBluetoothDeviceClient(
63 scoped_ptr<BluetoothDeviceClient>(new FakeBluetoothDeviceClient));
64 dbus_setter->SetBluetoothGattServiceClient(
65 scoped_ptr<BluetoothGattServiceClient>(
66 new FakeBluetoothGattServiceClient));
67 dbus_setter->SetBluetoothInputClient(
68 scoped_ptr<BluetoothInputClient>(new FakeBluetoothInputClient));
69 dbus_setter->SetBluetoothProfileManagerClient(
70 scoped_ptr<BluetoothProfileManagerClient>(
71 new FakeBluetoothProfileManagerClient));
73 BluetoothSocketThread::Get();
75 // Grab a pointer to the adapter.
76 device::BluetoothAdapterFactory::GetAdapter(
77 base::Bind(&BluetoothSocketChromeOSTest::AdapterCallback,
78 base::Unretained(this)));
79 ASSERT_TRUE(adapter_.get() != NULL);
80 ASSERT_TRUE(adapter_->IsInitialized());
81 ASSERT_TRUE(adapter_->IsPresent());
83 // Turn on the adapter.
84 adapter_->SetPowered(
85 true,
86 base::Bind(&base::DoNothing),
87 base::Bind(&base::DoNothing));
88 ASSERT_TRUE(adapter_->IsPowered());
91 void TearDown() override {
92 adapter_ = NULL;
93 BluetoothSocketThread::CleanupForTesting();
94 DBusThreadManager::Shutdown();
97 void AdapterCallback(scoped_refptr<BluetoothAdapter> adapter) {
98 adapter_ = adapter;
101 void SuccessCallback() {
102 ++success_callback_count_;
103 message_loop_.Quit();
106 void ErrorCallback(const std::string& message) {
107 ++error_callback_count_;
108 last_message_ = message;
110 message_loop_.Quit();
113 void ConnectToServiceSuccessCallback(scoped_refptr<BluetoothSocket> socket) {
114 ++success_callback_count_;
115 last_socket_ = socket;
117 message_loop_.Quit();
120 void SendSuccessCallback(int bytes_sent) {
121 ++success_callback_count_;
122 last_bytes_sent_ = bytes_sent;
124 message_loop_.Quit();
127 void ReceiveSuccessCallback(int bytes_received,
128 scoped_refptr<net::IOBuffer> io_buffer) {
129 ++success_callback_count_;
130 last_bytes_received_ = bytes_received;
131 last_io_buffer_ = io_buffer;
133 message_loop_.Quit();
136 void ReceiveErrorCallback(BluetoothSocket::ErrorReason reason,
137 const std::string& error_message) {
138 ++error_callback_count_;
139 last_reason_ = reason;
140 last_message_ = error_message;
142 message_loop_.Quit();
145 void CreateServiceSuccessCallback(scoped_refptr<BluetoothSocket> socket) {
146 ++success_callback_count_;
147 last_socket_ = socket;
149 if (message_loop_.is_running())
150 message_loop_.Quit();
153 void AcceptSuccessCallback(const BluetoothDevice* device,
154 scoped_refptr<BluetoothSocket> socket) {
155 ++success_callback_count_;
156 last_device_ = device;
157 last_socket_ = socket;
159 message_loop_.Quit();
162 void ImmediateSuccessCallback() {
163 ++success_callback_count_;
166 protected:
167 base::MessageLoop message_loop_;
169 scoped_refptr<BluetoothAdapter> adapter_;
171 unsigned int success_callback_count_;
172 unsigned int error_callback_count_;
174 std::string last_message_;
175 scoped_refptr<BluetoothSocket> last_socket_;
176 int last_bytes_sent_;
177 int last_bytes_received_;
178 scoped_refptr<net::IOBuffer> last_io_buffer_;
179 BluetoothSocket::ErrorReason last_reason_;
180 const BluetoothDevice* last_device_;
183 TEST_F(BluetoothSocketChromeOSTest, Connect) {
184 BluetoothDevice* device = adapter_->GetDevice(
185 FakeBluetoothDeviceClient::kPairedDeviceAddress);
186 ASSERT_TRUE(device != NULL);
188 device->ConnectToService(
189 BluetoothUUID(FakeBluetoothProfileManagerClient::kRfcommUuid),
190 base::Bind(&BluetoothSocketChromeOSTest::ConnectToServiceSuccessCallback,
191 base::Unretained(this)),
192 base::Bind(&BluetoothSocketChromeOSTest::ErrorCallback,
193 base::Unretained(this)));
194 message_loop_.Run();
196 EXPECT_EQ(1U, success_callback_count_);
197 EXPECT_EQ(0U, error_callback_count_);
198 EXPECT_TRUE(last_socket_.get() != NULL);
200 // Take ownership of the socket for the remainder of the test.
201 scoped_refptr<BluetoothSocket> socket = last_socket_;
202 last_socket_ = NULL;
203 success_callback_count_ = 0;
204 error_callback_count_ = 0;
206 // Send data to the socket, expect all of the data to be sent.
207 scoped_refptr<net::StringIOBuffer> write_buffer(
208 new net::StringIOBuffer("test"));
210 socket->Send(write_buffer.get(), write_buffer->size(),
211 base::Bind(&BluetoothSocketChromeOSTest::SendSuccessCallback,
212 base::Unretained(this)),
213 base::Bind(&BluetoothSocketChromeOSTest::ErrorCallback,
214 base::Unretained(this)));
215 message_loop_.Run();
217 EXPECT_EQ(1U, success_callback_count_);
218 EXPECT_EQ(0U, error_callback_count_);
219 EXPECT_EQ(last_bytes_sent_, write_buffer->size());
221 success_callback_count_ = 0;
222 error_callback_count_ = 0;
224 // Receive data from the socket, and fetch the buffer from the callback; since
225 // the fake is an echo server, we expect to receive what we wrote.
226 socket->Receive(
227 4096,
228 base::Bind(&BluetoothSocketChromeOSTest::ReceiveSuccessCallback,
229 base::Unretained(this)),
230 base::Bind(&BluetoothSocketChromeOSTest::ReceiveErrorCallback,
231 base::Unretained(this)));
232 message_loop_.Run();
234 EXPECT_EQ(1U, success_callback_count_);
235 EXPECT_EQ(0U, error_callback_count_);
236 EXPECT_EQ(4, last_bytes_received_);
237 EXPECT_TRUE(last_io_buffer_.get() != NULL);
239 // Take ownership of the received buffer.
240 scoped_refptr<net::IOBuffer> read_buffer = last_io_buffer_;
241 last_io_buffer_ = NULL;
242 success_callback_count_ = 0;
243 error_callback_count_ = 0;
245 std::string data = std::string(read_buffer->data(), last_bytes_received_);
246 EXPECT_EQ("test", data);
248 read_buffer = NULL;
250 // Receive data again; the socket will have been closed, this should cause a
251 // disconnected error to be returned via the error callback.
252 socket->Receive(
253 4096,
254 base::Bind(&BluetoothSocketChromeOSTest::ReceiveSuccessCallback,
255 base::Unretained(this)),
256 base::Bind(&BluetoothSocketChromeOSTest::ReceiveErrorCallback,
257 base::Unretained(this)));
258 message_loop_.Run();
260 EXPECT_EQ(0U, success_callback_count_);
261 EXPECT_EQ(1U, error_callback_count_);
262 EXPECT_EQ(BluetoothSocket::kDisconnected, last_reason_);
263 EXPECT_EQ(net::ErrorToString(net::OK), last_message_);
265 success_callback_count_ = 0;
266 error_callback_count_ = 0;
268 // Send data again; since the socket is closed we should get a system error
269 // equivalent to the connection reset error.
270 write_buffer = new net::StringIOBuffer("second test");
272 socket->Send(write_buffer.get(), write_buffer->size(),
273 base::Bind(&BluetoothSocketChromeOSTest::SendSuccessCallback,
274 base::Unretained(this)),
275 base::Bind(&BluetoothSocketChromeOSTest::ErrorCallback,
276 base::Unretained(this)));
277 message_loop_.Run();
279 EXPECT_EQ(0U, success_callback_count_);
280 EXPECT_EQ(1U, error_callback_count_);
281 EXPECT_EQ(net::ErrorToString(net::ERR_CONNECTION_RESET), last_message_);
283 success_callback_count_ = 0;
284 error_callback_count_ = 0;
286 // Close our end of the socket.
287 socket->Disconnect(base::Bind(&BluetoothSocketChromeOSTest::SuccessCallback,
288 base::Unretained(this)));
290 message_loop_.Run();
291 EXPECT_EQ(1U, success_callback_count_);
294 TEST_F(BluetoothSocketChromeOSTest, Listen) {
295 adapter_->CreateRfcommService(
296 BluetoothUUID(FakeBluetoothProfileManagerClient::kRfcommUuid),
297 BluetoothAdapter::ServiceOptions(),
298 base::Bind(&BluetoothSocketChromeOSTest::CreateServiceSuccessCallback,
299 base::Unretained(this)),
300 base::Bind(&BluetoothSocketChromeOSTest::ErrorCallback,
301 base::Unretained(this)));
303 message_loop_.Run();
305 EXPECT_EQ(1U, success_callback_count_);
306 EXPECT_EQ(0U, error_callback_count_);
307 EXPECT_TRUE(last_socket_.get() != NULL);
309 // Take ownership of the socket for the remainder of the test.
310 scoped_refptr<BluetoothSocket> server_socket = last_socket_;
311 last_socket_ = NULL;
312 success_callback_count_ = 0;
313 error_callback_count_ = 0;
315 // Simulate an incoming connection by just calling the ConnectProfile method
316 // of the underlying fake device client (from the BlueZ point of view,
317 // outgoing and incoming look the same).
319 // This is done before the Accept() call to simulate a pending call at the
320 // point that Accept() is called.
321 FakeBluetoothDeviceClient* fake_bluetooth_device_client =
322 static_cast<FakeBluetoothDeviceClient*>(
323 DBusThreadManager::Get()->GetBluetoothDeviceClient());
324 BluetoothDevice* device = adapter_->GetDevice(
325 FakeBluetoothDeviceClient::kPairedDeviceAddress);
326 ASSERT_TRUE(device != NULL);
327 fake_bluetooth_device_client->ConnectProfile(
328 static_cast<BluetoothDeviceChromeOS*>(device)->object_path(),
329 FakeBluetoothProfileManagerClient::kRfcommUuid,
330 base::Bind(&base::DoNothing),
331 base::Bind(&DoNothingDBusErrorCallback));
333 message_loop_.RunUntilIdle();
335 server_socket->Accept(
336 base::Bind(&BluetoothSocketChromeOSTest::AcceptSuccessCallback,
337 base::Unretained(this)),
338 base::Bind(&BluetoothSocketChromeOSTest::ErrorCallback,
339 base::Unretained(this)));
341 message_loop_.Run();
343 EXPECT_EQ(1U, success_callback_count_);
344 EXPECT_EQ(0U, error_callback_count_);
345 EXPECT_TRUE(last_socket_.get() != NULL);
347 // Take ownership of the client socket for the remainder of the test.
348 scoped_refptr<BluetoothSocket> client_socket = last_socket_;
349 last_socket_ = NULL;
350 success_callback_count_ = 0;
351 error_callback_count_ = 0;
353 // Close our end of the client socket.
354 client_socket->Disconnect(
355 base::Bind(&BluetoothSocketChromeOSTest::SuccessCallback,
356 base::Unretained(this)));
358 message_loop_.Run();
360 EXPECT_EQ(1U, success_callback_count_);
361 client_socket = NULL;
362 success_callback_count_ = 0;
363 error_callback_count_ = 0;
365 // Run a second connection test, this time calling Accept() before the
366 // incoming connection comes in.
367 server_socket->Accept(
368 base::Bind(&BluetoothSocketChromeOSTest::AcceptSuccessCallback,
369 base::Unretained(this)),
370 base::Bind(&BluetoothSocketChromeOSTest::ErrorCallback,
371 base::Unretained(this)));
373 message_loop_.RunUntilIdle();
375 fake_bluetooth_device_client->ConnectProfile(
376 static_cast<BluetoothDeviceChromeOS*>(device)->object_path(),
377 FakeBluetoothProfileManagerClient::kRfcommUuid,
378 base::Bind(&base::DoNothing),
379 base::Bind(&DoNothingDBusErrorCallback));
381 message_loop_.Run();
383 EXPECT_EQ(1U, success_callback_count_);
384 EXPECT_EQ(0U, error_callback_count_);
385 EXPECT_TRUE(last_socket_.get() != NULL);
387 // Take ownership of the client socket for the remainder of the test.
388 client_socket = last_socket_;
389 last_socket_ = NULL;
390 success_callback_count_ = 0;
391 error_callback_count_ = 0;
393 // Close our end of the client socket.
394 client_socket->Disconnect(
395 base::Bind(&BluetoothSocketChromeOSTest::SuccessCallback,
396 base::Unretained(this)));
398 message_loop_.Run();
400 EXPECT_EQ(1U, success_callback_count_);
401 client_socket = NULL;
402 success_callback_count_ = 0;
403 error_callback_count_ = 0;
405 // Now close the server socket.
406 server_socket->Disconnect(
407 base::Bind(&BluetoothSocketChromeOSTest::ImmediateSuccessCallback,
408 base::Unretained(this)));
410 message_loop_.RunUntilIdle();
412 EXPECT_EQ(1U, success_callback_count_);
415 TEST_F(BluetoothSocketChromeOSTest, ListenBeforeAdapterStart) {
416 // Start off with an invisible adapter, register the profile, then make
417 // the adapter visible.
418 FakeBluetoothAdapterClient* fake_bluetooth_adapter_client =
419 static_cast<FakeBluetoothAdapterClient*>(
420 DBusThreadManager::Get()->GetBluetoothAdapterClient());
421 fake_bluetooth_adapter_client->SetVisible(false);
423 adapter_->CreateRfcommService(
424 BluetoothUUID(FakeBluetoothProfileManagerClient::kRfcommUuid),
425 BluetoothAdapter::ServiceOptions(),
426 base::Bind(&BluetoothSocketChromeOSTest::CreateServiceSuccessCallback,
427 base::Unretained(this)),
428 base::Bind(&BluetoothSocketChromeOSTest::ErrorCallback,
429 base::Unretained(this)));
430 message_loop_.Run();
432 EXPECT_EQ(1U, success_callback_count_);
433 EXPECT_EQ(0U, error_callback_count_);
434 EXPECT_TRUE(last_socket_.get() != NULL);
436 // Take ownership of the socket for the remainder of the test.
437 scoped_refptr<BluetoothSocket> socket = last_socket_;
438 last_socket_ = NULL;
439 success_callback_count_ = 0;
440 error_callback_count_ = 0;
442 // But there shouldn't be a profile registered yet.
443 FakeBluetoothProfileManagerClient* fake_bluetooth_profile_manager_client =
444 static_cast<FakeBluetoothProfileManagerClient*>(
445 DBusThreadManager::Get()->GetBluetoothProfileManagerClient());
446 FakeBluetoothProfileServiceProvider* profile_service_provider =
447 fake_bluetooth_profile_manager_client->GetProfileServiceProvider(
448 FakeBluetoothProfileManagerClient::kRfcommUuid);
449 EXPECT_TRUE(profile_service_provider == NULL);
451 // Make the adapter visible. This should register a profile.
452 fake_bluetooth_adapter_client->SetVisible(true);
454 message_loop_.RunUntilIdle();
456 profile_service_provider =
457 fake_bluetooth_profile_manager_client->GetProfileServiceProvider(
458 FakeBluetoothProfileManagerClient::kRfcommUuid);
459 EXPECT_TRUE(profile_service_provider != NULL);
461 // Cleanup the socket.
462 socket->Disconnect(
463 base::Bind(&BluetoothSocketChromeOSTest::ImmediateSuccessCallback,
464 base::Unretained(this)));
466 message_loop_.RunUntilIdle();
468 EXPECT_EQ(1U, success_callback_count_);
471 TEST_F(BluetoothSocketChromeOSTest, ListenAcrossAdapterRestart) {
472 // The fake adapter starts off visible by default.
473 FakeBluetoothAdapterClient* fake_bluetooth_adapter_client =
474 static_cast<FakeBluetoothAdapterClient*>(
475 DBusThreadManager::Get()->GetBluetoothAdapterClient());
477 adapter_->CreateRfcommService(
478 BluetoothUUID(FakeBluetoothProfileManagerClient::kRfcommUuid),
479 BluetoothAdapter::ServiceOptions(),
480 base::Bind(&BluetoothSocketChromeOSTest::CreateServiceSuccessCallback,
481 base::Unretained(this)),
482 base::Bind(&BluetoothSocketChromeOSTest::ErrorCallback,
483 base::Unretained(this)));
484 message_loop_.Run();
486 EXPECT_EQ(1U, success_callback_count_);
487 EXPECT_EQ(0U, error_callback_count_);
488 EXPECT_TRUE(last_socket_.get() != NULL);
490 // Take ownership of the socket for the remainder of the test.
491 scoped_refptr<BluetoothSocket> socket = last_socket_;
492 last_socket_ = NULL;
493 success_callback_count_ = 0;
494 error_callback_count_ = 0;
496 // Make sure the profile was registered with the daemon.
497 FakeBluetoothProfileManagerClient* fake_bluetooth_profile_manager_client =
498 static_cast<FakeBluetoothProfileManagerClient*>(
499 DBusThreadManager::Get()->GetBluetoothProfileManagerClient());
500 FakeBluetoothProfileServiceProvider* profile_service_provider =
501 fake_bluetooth_profile_manager_client->GetProfileServiceProvider(
502 FakeBluetoothProfileManagerClient::kRfcommUuid);
503 EXPECT_TRUE(profile_service_provider != NULL);
505 // Make the adapter invisible, and fiddle with the profile fake to unregister
506 // the profile since this doesn't happen automatically.
507 fake_bluetooth_adapter_client->SetVisible(false);
509 message_loop_.RunUntilIdle();
511 // Then make the adapter visible again. This should re-register the profile.
512 fake_bluetooth_adapter_client->SetVisible(true);
514 message_loop_.RunUntilIdle();
516 profile_service_provider =
517 fake_bluetooth_profile_manager_client->GetProfileServiceProvider(
518 FakeBluetoothProfileManagerClient::kRfcommUuid);
519 EXPECT_TRUE(profile_service_provider != NULL);
521 // Cleanup the socket.
522 socket->Disconnect(
523 base::Bind(&BluetoothSocketChromeOSTest::ImmediateSuccessCallback,
524 base::Unretained(this)));
526 message_loop_.RunUntilIdle();
528 EXPECT_EQ(1U, success_callback_count_);
531 TEST_F(BluetoothSocketChromeOSTest, PairedConnectFails) {
532 BluetoothDevice* device = adapter_->GetDevice(
533 FakeBluetoothDeviceClient::kPairedUnconnectableDeviceAddress);
534 ASSERT_TRUE(device != NULL);
536 device->ConnectToService(
537 BluetoothUUID(FakeBluetoothProfileManagerClient::kRfcommUuid),
538 base::Bind(&BluetoothSocketChromeOSTest::ConnectToServiceSuccessCallback,
539 base::Unretained(this)),
540 base::Bind(&BluetoothSocketChromeOSTest::ErrorCallback,
541 base::Unretained(this)));
542 message_loop_.Run();
544 EXPECT_EQ(0U, success_callback_count_);
545 EXPECT_EQ(1U, error_callback_count_);
546 EXPECT_TRUE(last_socket_.get() == NULL);
548 device->ConnectToService(
549 BluetoothUUID(FakeBluetoothProfileManagerClient::kRfcommUuid),
550 base::Bind(&BluetoothSocketChromeOSTest::ConnectToServiceSuccessCallback,
551 base::Unretained(this)),
552 base::Bind(&BluetoothSocketChromeOSTest::ErrorCallback,
553 base::Unretained(this)));
554 message_loop_.Run();
556 EXPECT_EQ(0U, success_callback_count_);
557 EXPECT_EQ(2U, error_callback_count_);
558 EXPECT_TRUE(last_socket_.get() == NULL);
561 } // namespace chromeos