Make castv2 performance test work.
[chromium-blink-merge.git] / device / hid / hid_connection_unittest.cc
blobe474a6259c875d903adfb0e528ac2ed28455b3e2
1 // Copyright (c) 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 <string>
6 #include <vector>
8 #include "base/bind.h"
9 #include "base/callback.h"
10 #include "base/memory/scoped_ptr.h"
11 #include "base/run_loop.h"
12 #include "base/scoped_observer.h"
13 #include "base/test/test_io_thread.h"
14 #include "device/hid/hid_connection.h"
15 #include "device/hid/hid_service.h"
16 #include "device/test/usb_test_gadget.h"
17 #include "net/base/io_buffer.h"
18 #include "testing/gtest/include/gtest/gtest.h"
20 namespace device {
22 namespace {
24 using net::IOBufferWithSize;
26 void ClaimTestDevice(scoped_ptr<UsbTestGadget>* gadget) {
27 base::MessageLoop::ScopedNestableTaskAllower allow(
28 base::MessageLoop::current());
29 *gadget = UsbTestGadget::Claim();
30 ASSERT_TRUE(*gadget);
31 ASSERT_TRUE((*gadget)->SetType(UsbTestGadget::HID_ECHO));
34 void UnclaimTestDevice(scoped_ptr<UsbTestGadget> gadget) {
35 base::MessageLoop::ScopedNestableTaskAllower allow(
36 base::MessageLoop::current());
37 ASSERT_TRUE(gadget->Unclaim());
40 // Helper class that can be used to block until a HID device with a particular
41 // serial number is available. Example usage:
43 // DeviceCatcher device_catcher("ABC123");
44 // HidDeviceId device_id = device_catcher.WaitForDevice();
45 // /* Call HidService::Connect(device_id) to open the device. */
47 class DeviceCatcher : HidService::Observer {
48 public:
49 DeviceCatcher(const std::string& serial_number)
50 : serial_number_(serial_number), observer_(this) {
51 HidService* hid_service = HidService::GetInstance(
52 base::MessageLoop::current()->message_loop_proxy());
53 observer_.Add(hid_service);
54 hid_service->GetDevices(base::Bind(&DeviceCatcher::OnEnumerationComplete,
55 base::Unretained(this)));
58 const HidDeviceId& WaitForDevice() {
59 run_loop_.Run();
60 observer_.RemoveAll();
61 return device_id_;
64 private:
65 void OnEnumerationComplete(
66 const std::vector<scoped_refptr<HidDeviceInfo>>& devices) {
67 for (const scoped_refptr<HidDeviceInfo>& device_info : devices) {
68 if (device_info->serial_number() == serial_number_) {
69 device_id_ = device_info->device_id();
70 run_loop_.Quit();
71 break;
76 void OnDeviceAdded(scoped_refptr<HidDeviceInfo> device_info) override {
77 if (device_info->serial_number() == serial_number_) {
78 device_id_ = device_info->device_id();
79 run_loop_.Quit();
83 std::string serial_number_;
84 ScopedObserver<device::HidService, device::HidService::Observer> observer_;
85 base::RunLoop run_loop_;
86 HidDeviceId device_id_;
89 class TestConnectCallback {
90 public:
91 TestConnectCallback()
92 : callback_(base::Bind(&TestConnectCallback::SetConnection,
93 base::Unretained(this))) {}
94 ~TestConnectCallback() {}
96 void SetConnection(scoped_refptr<HidConnection> connection) {
97 connection_ = connection;
98 run_loop_.Quit();
101 scoped_refptr<HidConnection> WaitForConnection() {
102 run_loop_.Run();
103 return connection_;
106 const HidService::ConnectCallback& callback() { return callback_; }
108 private:
109 HidService::ConnectCallback callback_;
110 base::RunLoop run_loop_;
111 scoped_refptr<HidConnection> connection_;
114 class TestIoCallback {
115 public:
116 TestIoCallback()
117 : read_callback_(
118 base::Bind(&TestIoCallback::SetReadResult, base::Unretained(this))),
119 write_callback_(base::Bind(&TestIoCallback::SetWriteResult,
120 base::Unretained(this))) {}
121 ~TestIoCallback() {}
123 void SetReadResult(bool success,
124 scoped_refptr<net::IOBuffer> buffer,
125 size_t size) {
126 result_ = success;
127 buffer_ = buffer;
128 size_ = size;
129 run_loop_.Quit();
132 void SetWriteResult(bool success) {
133 result_ = success;
134 run_loop_.Quit();
137 bool WaitForResult() {
138 run_loop_.Run();
139 return result_;
142 const HidConnection::ReadCallback& read_callback() { return read_callback_; }
143 const HidConnection::WriteCallback write_callback() {
144 return write_callback_;
146 scoped_refptr<net::IOBuffer> buffer() const { return buffer_; }
147 size_t size() const { return size_; }
149 private:
150 base::RunLoop run_loop_;
151 bool result_;
152 size_t size_;
153 scoped_refptr<net::IOBuffer> buffer_;
154 HidConnection::ReadCallback read_callback_;
155 HidConnection::WriteCallback write_callback_;
158 } // namespace
160 class HidConnectionTest : public testing::Test {
161 protected:
162 void SetUp() override {
163 if (!UsbTestGadget::IsTestEnabled()) return;
165 message_loop_.reset(new base::MessageLoopForUI());
166 io_thread_.reset(new base::TestIOThread(base::TestIOThread::kAutoStart));
168 service_ = HidService::GetInstance(io_thread_->task_runner());
169 ASSERT_TRUE(service_);
171 io_thread_->PostTaskAndWait(FROM_HERE,
172 base::Bind(&ClaimTestDevice, &test_gadget_));
173 ASSERT_TRUE(test_gadget_);
175 DeviceCatcher device_catcher(test_gadget_->GetSerialNumber());
176 device_id_ = device_catcher.WaitForDevice();
177 ASSERT_NE(device_id_, kInvalidHidDeviceId);
180 void TearDown() override {
181 if (io_thread_) {
182 io_thread_->PostTaskAndWait(
183 FROM_HERE,
184 base::Bind(&UnclaimTestDevice, base::Passed(&test_gadget_)));
188 scoped_ptr<base::MessageLoopForUI> message_loop_;
189 scoped_ptr<base::TestIOThread> io_thread_;
190 HidService* service_;
191 scoped_ptr<UsbTestGadget> test_gadget_;
192 HidDeviceId device_id_;
195 TEST_F(HidConnectionTest, ReadWrite) {
196 if (!UsbTestGadget::IsTestEnabled()) return;
198 TestConnectCallback connect_callback;
199 service_->Connect(device_id_, connect_callback.callback());
200 scoped_refptr<HidConnection> conn = connect_callback.WaitForConnection();
201 ASSERT_TRUE(conn.get());
203 const char kBufferSize = 9;
204 for (char i = 0; i < 8; ++i) {
205 scoped_refptr<IOBufferWithSize> buffer(new IOBufferWithSize(kBufferSize));
206 buffer->data()[0] = 0;
207 for (unsigned char j = 1; j < kBufferSize; ++j) {
208 buffer->data()[j] = i + j - 1;
211 TestIoCallback write_callback;
212 conn->Write(buffer, buffer->size(), write_callback.write_callback());
213 ASSERT_TRUE(write_callback.WaitForResult());
215 TestIoCallback read_callback;
216 conn->Read(read_callback.read_callback());
217 ASSERT_TRUE(read_callback.WaitForResult());
218 ASSERT_EQ(9UL, read_callback.size());
219 ASSERT_EQ(0, read_callback.buffer()->data()[0]);
220 for (unsigned char j = 1; j < kBufferSize; ++j) {
221 ASSERT_EQ(i + j - 1, read_callback.buffer()->data()[j]);
225 conn->Close();
228 } // namespace device