OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 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 <string> |
| 6 |
5 #include "base/bind.h" | 7 #include "base/bind.h" |
6 #include "base/message_loop/message_loop.h" | 8 #include "base/message_loop/message_loop.h" |
7 #include "base/run_loop.h" | 9 #include "base/run_loop.h" |
| 10 #include "base/strings/string_piece.h" |
| 11 #include "device/serial/data_receiver.h" |
| 12 #include "device/serial/data_sender.h" |
| 13 #include "device/serial/data_stream.mojom.h" |
8 #include "device/serial/serial.mojom.h" | 14 #include "device/serial/serial.mojom.h" |
| 15 #include "device/serial/serial_connection.h" |
9 #include "device/serial/serial_service_impl.h" | 16 #include "device/serial/serial_service_impl.h" |
10 #include "device/serial/test_serial_io_handler.h" | 17 #include "device/serial/test_serial_io_handler.h" |
11 #include "mojo/public/cpp/bindings/error_handler.h" | 18 #include "mojo/public/cpp/bindings/error_handler.h" |
12 #include "mojo/public/cpp/bindings/interface_ptr.h" | 19 #include "mojo/public/cpp/bindings/interface_ptr.h" |
13 #include "mojo/public/cpp/bindings/interface_request.h" | 20 #include "mojo/public/cpp/bindings/interface_request.h" |
14 #include "testing/gtest/include/gtest/gtest.h" | 21 #include "testing/gtest/include/gtest/gtest.h" |
15 | 22 |
16 namespace device { | 23 namespace device { |
17 namespace { | 24 namespace { |
18 | 25 |
19 class FakeSerialDeviceEnumerator : public SerialDeviceEnumerator { | 26 class FakeSerialDeviceEnumerator : public SerialDeviceEnumerator { |
20 virtual mojo::Array<serial::DeviceInfoPtr> GetDevices() OVERRIDE { | 27 virtual mojo::Array<serial::DeviceInfoPtr> GetDevices() OVERRIDE { |
21 mojo::Array<serial::DeviceInfoPtr> devices(1); | 28 mojo::Array<serial::DeviceInfoPtr> devices(1); |
22 devices[0] = serial::DeviceInfo::New(); | 29 devices[0] = serial::DeviceInfo::New(); |
23 devices[0]->path = "device"; | 30 devices[0]->path = "device"; |
24 return devices.Pass(); | 31 return devices.Pass(); |
25 } | 32 } |
26 }; | 33 }; |
27 | 34 |
28 } // namespace | 35 } // namespace |
29 | 36 |
30 class SerialConnectionTest : public testing::Test, public mojo::ErrorHandler { | 37 class SerialConnectionTest : public testing::Test, public mojo::ErrorHandler { |
31 public: | 38 public: |
32 SerialConnectionTest() : connected_(false), success_(false) {} | 39 enum Event { |
| 40 EVENT_NONE, |
| 41 EVENT_GOT_INFO, |
| 42 EVENT_SET_OPTIONS, |
| 43 EVENT_GOT_CONTROL_SIGNALS, |
| 44 EVENT_SET_CONTROL_SIGNALS, |
| 45 EVENT_FLUSHED, |
| 46 EVENT_DATA_AT_IO_HANDLER, |
| 47 EVENT_DATA_SENT, |
| 48 EVENT_SEND_ERROR, |
| 49 EVENT_DATA_RECEIVED, |
| 50 EVENT_RECEIVE_ERROR, |
| 51 EVENT_CANCEL_COMPLETE, |
| 52 EVENT_ERROR, |
| 53 }; |
| 54 |
| 55 static const uint32_t kBufferSize; |
| 56 |
| 57 SerialConnectionTest() |
| 58 : connected_(false), |
| 59 success_(false), |
| 60 bytes_sent_(0), |
| 61 send_error_(serial::SEND_ERROR_NONE), |
| 62 receive_error_(serial::RECEIVE_ERROR_NONE), |
| 63 expected_event_(EVENT_NONE) {} |
33 | 64 |
34 virtual void SetUp() OVERRIDE { | 65 virtual void SetUp() OVERRIDE { |
35 message_loop_.reset(new base::MessageLoop); | 66 message_loop_.reset(new base::MessageLoop); |
36 mojo::InterfacePtr<serial::SerialService> service; | 67 mojo::InterfacePtr<serial::SerialService> service; |
37 mojo::BindToProxy( | 68 mojo::BindToProxy( |
38 new SerialServiceImpl( | 69 new SerialServiceImpl( |
39 new SerialConnectionFactory( | 70 new SerialConnectionFactory( |
40 base::Bind(&SerialConnectionTest::CreateIoHandler, | 71 base::Bind(&SerialConnectionTest::CreateIoHandler, |
41 base::Unretained(this)), | 72 base::Unretained(this)), |
42 base::MessageLoopProxy::current()), | 73 base::MessageLoopProxy::current()), |
43 scoped_ptr<SerialDeviceEnumerator>(new FakeSerialDeviceEnumerator)), | 74 scoped_ptr<SerialDeviceEnumerator>(new FakeSerialDeviceEnumerator)), |
44 &service); | 75 &service); |
45 service.set_error_handler(this); | 76 service.set_error_handler(this); |
46 service->Connect( | 77 mojo::InterfacePtr<serial::DataSink> consumer; |
47 "device", serial::ConnectionOptions::New(), mojo::Get(&connection_)); | 78 mojo::InterfacePtr<serial::DataSource> producer; |
| 79 service->Connect("device", |
| 80 serial::ConnectionOptions::New(), |
| 81 mojo::Get(&connection_), |
| 82 mojo::Get(&consumer), |
| 83 mojo::Get(&producer)); |
| 84 sender_.reset(new DataSender( |
| 85 consumer.Pass(), kBufferSize, serial::SEND_ERROR_DISCONNECTED)); |
| 86 receiver_ = new DataReceiver( |
| 87 producer.Pass(), kBufferSize, serial::RECEIVE_ERROR_DISCONNECTED); |
48 connection_.set_error_handler(this); | 88 connection_.set_error_handler(this); |
49 connection_->GetInfo( | 89 connection_->GetInfo( |
50 base::Bind(&SerialConnectionTest::StoreInfo, base::Unretained(this))); | 90 base::Bind(&SerialConnectionTest::StoreInfo, base::Unretained(this))); |
51 RunMessageLoop(); | 91 WaitForEvent(EVENT_GOT_INFO); |
52 ASSERT_TRUE(io_handler_); | 92 ASSERT_TRUE(io_handler_); |
53 } | 93 } |
54 | 94 |
55 void StoreInfo(serial::ConnectionInfoPtr options) { | 95 void StoreInfo(serial::ConnectionInfoPtr options) { |
56 info_ = options.Pass(); | 96 info_ = options.Pass(); |
57 StopMessageLoop(); | 97 EventReceived(EVENT_GOT_INFO); |
58 } | 98 } |
59 | 99 |
60 void StoreControlSignals(serial::DeviceControlSignalsPtr signals) { | 100 void StoreControlSignals(serial::DeviceControlSignalsPtr signals) { |
61 signals_ = signals.Pass(); | 101 signals_ = signals.Pass(); |
62 StopMessageLoop(); | 102 EventReceived(EVENT_GOT_CONTROL_SIGNALS); |
63 } | 103 } |
64 | 104 |
65 void StoreSuccess(bool success) { | 105 void StoreSuccess(Event event_to_report, bool success) { |
66 success_ = success; | 106 success_ = success; |
67 StopMessageLoop(); | 107 EventReceived(event_to_report); |
68 } | 108 } |
69 | 109 |
70 void RunMessageLoop() { | 110 void Send(const base::StringPiece& data) { |
71 run_loop_.reset(new base::RunLoop); | 111 ASSERT_TRUE(sender_->Send( |
72 run_loop_->Run(); | 112 data, |
| 113 base::Bind(&SerialConnectionTest::OnDataSent, base::Unretained(this)), |
| 114 base::Bind(&SerialConnectionTest::OnSendError, |
| 115 base::Unretained(this)))); |
73 } | 116 } |
74 | 117 |
75 void StopMessageLoop() { | 118 void Receive() { |
| 119 ASSERT_TRUE( |
| 120 receiver_->Receive(base::Bind(&SerialConnectionTest::OnDataReceived, |
| 121 base::Unretained(this)), |
| 122 base::Bind(&SerialConnectionTest::OnReceiveError, |
| 123 base::Unretained(this)))); |
| 124 } |
| 125 |
| 126 void WaitForEvent(Event event) { |
| 127 expected_event_ = event; |
| 128 base::RunLoop run_loop; |
| 129 stop_run_loop_ = run_loop.QuitClosure(); |
| 130 run_loop.Run(); |
| 131 } |
| 132 |
| 133 void EventReceived(Event event) { |
| 134 if (event != expected_event_) |
| 135 return; |
| 136 expected_event_ = EVENT_NONE; |
76 ASSERT_TRUE(message_loop_); | 137 ASSERT_TRUE(message_loop_); |
77 ASSERT_TRUE(run_loop_); | 138 ASSERT_TRUE(!stop_run_loop_.is_null()); |
78 message_loop_->PostTask(FROM_HERE, run_loop_->QuitClosure()); | 139 message_loop_->PostTask(FROM_HERE, stop_run_loop_); |
79 } | 140 } |
80 | 141 |
81 scoped_refptr<SerialIoHandler> CreateIoHandler() { | 142 scoped_refptr<SerialIoHandler> CreateIoHandler() { |
82 io_handler_ = new TestSerialIoHandler; | 143 io_handler_ = new TestSerialIoHandler; |
83 return io_handler_; | 144 return io_handler_; |
84 } | 145 } |
85 | 146 |
| 147 void OnDataSent(uint32_t bytes_sent) { |
| 148 bytes_sent_ += bytes_sent; |
| 149 send_error_ = serial::SEND_ERROR_NONE; |
| 150 EventReceived(EVENT_DATA_SENT); |
| 151 } |
| 152 |
| 153 void OnSendError(uint32_t bytes_sent, int32_t error) { |
| 154 bytes_sent_ += bytes_sent; |
| 155 send_error_ = static_cast<serial::SendError>(error); |
| 156 EventReceived(EVENT_SEND_ERROR); |
| 157 } |
| 158 |
| 159 void OnDataReceived(scoped_ptr<ReadOnlyBuffer> buffer) { |
| 160 data_received_ += std::string(buffer->GetData(), buffer->GetSize()); |
| 161 buffer->Done(buffer->GetSize()); |
| 162 receive_error_ = serial::RECEIVE_ERROR_NONE; |
| 163 EventReceived(EVENT_DATA_RECEIVED); |
| 164 } |
| 165 |
| 166 void OnReceiveError(int32_t error) { |
| 167 receive_error_ = static_cast<serial::ReceiveError>(error); |
| 168 EventReceived(EVENT_RECEIVE_ERROR); |
| 169 } |
| 170 |
86 virtual void OnConnectionError() OVERRIDE { | 171 virtual void OnConnectionError() OVERRIDE { |
87 StopMessageLoop(); | 172 EventReceived(EVENT_ERROR); |
88 FAIL() << "Connection error"; | 173 FAIL() << "Connection error"; |
89 } | 174 } |
90 | 175 |
91 mojo::Array<serial::DeviceInfoPtr> devices_; | 176 mojo::Array<serial::DeviceInfoPtr> devices_; |
92 serial::ConnectionInfoPtr info_; | 177 serial::ConnectionInfoPtr info_; |
93 serial::DeviceControlSignalsPtr signals_; | 178 serial::DeviceControlSignalsPtr signals_; |
94 bool connected_; | 179 bool connected_; |
95 bool success_; | 180 bool success_; |
| 181 int bytes_sent_; |
| 182 serial::SendError send_error_; |
| 183 serial::ReceiveError receive_error_; |
| 184 std::string data_received_; |
| 185 Event expected_event_; |
96 | 186 |
97 scoped_ptr<base::MessageLoop> message_loop_; | 187 scoped_ptr<base::MessageLoop> message_loop_; |
98 scoped_ptr<base::RunLoop> run_loop_; | 188 base::Closure stop_run_loop_; |
99 mojo::InterfacePtr<serial::Connection> connection_; | 189 mojo::InterfacePtr<serial::Connection> connection_; |
| 190 scoped_ptr<DataSender> sender_; |
| 191 scoped_refptr<DataReceiver> receiver_; |
100 scoped_refptr<TestSerialIoHandler> io_handler_; | 192 scoped_refptr<TestSerialIoHandler> io_handler_; |
101 | 193 |
102 private: | 194 private: |
103 DISALLOW_COPY_AND_ASSIGN(SerialConnectionTest); | 195 DISALLOW_COPY_AND_ASSIGN(SerialConnectionTest); |
104 }; | 196 }; |
105 | 197 |
| 198 const uint32_t SerialConnectionTest::kBufferSize = 10; |
| 199 |
106 TEST_F(SerialConnectionTest, GetInfo) { | 200 TEST_F(SerialConnectionTest, GetInfo) { |
107 // |info_| is filled in during SetUp(). | 201 // |info_| is filled in during SetUp(). |
108 ASSERT_TRUE(info_); | 202 ASSERT_TRUE(info_); |
109 EXPECT_EQ(9600u, info_->bitrate); | 203 EXPECT_EQ(9600u, info_->bitrate); |
110 EXPECT_EQ(serial::DATA_BITS_EIGHT, info_->data_bits); | 204 EXPECT_EQ(serial::DATA_BITS_EIGHT, info_->data_bits); |
111 EXPECT_EQ(serial::PARITY_BIT_NO, info_->parity_bit); | 205 EXPECT_EQ(serial::PARITY_BIT_NO, info_->parity_bit); |
112 EXPECT_EQ(serial::STOP_BITS_ONE, info_->stop_bits); | 206 EXPECT_EQ(serial::STOP_BITS_ONE, info_->stop_bits); |
113 EXPECT_FALSE(info_->cts_flow_control); | 207 EXPECT_FALSE(info_->cts_flow_control); |
114 } | 208 } |
115 | 209 |
116 TEST_F(SerialConnectionTest, SetOptions) { | 210 TEST_F(SerialConnectionTest, SetOptions) { |
117 serial::ConnectionOptionsPtr options(serial::ConnectionOptions::New()); | 211 serial::ConnectionOptionsPtr options(serial::ConnectionOptions::New()); |
118 options->bitrate = 12345; | 212 options->bitrate = 12345; |
119 options->data_bits = serial::DATA_BITS_SEVEN; | 213 options->data_bits = serial::DATA_BITS_SEVEN; |
120 options->has_cts_flow_control = true; | 214 options->has_cts_flow_control = true; |
121 options->cts_flow_control = true; | 215 options->cts_flow_control = true; |
122 connection_->SetOptions( | 216 connection_->SetOptions(options.Pass(), |
123 options.Pass(), | 217 base::Bind(&SerialConnectionTest::StoreSuccess, |
124 base::Bind(&SerialConnectionTest::StoreSuccess, base::Unretained(this))); | 218 base::Unretained(this), |
125 RunMessageLoop(); | 219 EVENT_SET_OPTIONS)); |
| 220 WaitForEvent(EVENT_SET_OPTIONS); |
126 ASSERT_TRUE(success_); | 221 ASSERT_TRUE(success_); |
127 serial::ConnectionInfo* info = io_handler_->connection_info(); | 222 serial::ConnectionInfo* info = io_handler_->connection_info(); |
128 EXPECT_EQ(12345u, info->bitrate); | 223 EXPECT_EQ(12345u, info->bitrate); |
129 EXPECT_EQ(serial::DATA_BITS_SEVEN, info->data_bits); | 224 EXPECT_EQ(serial::DATA_BITS_SEVEN, info->data_bits); |
130 EXPECT_EQ(serial::PARITY_BIT_NO, info->parity_bit); | 225 EXPECT_EQ(serial::PARITY_BIT_NO, info->parity_bit); |
131 EXPECT_EQ(serial::STOP_BITS_ONE, info->stop_bits); | 226 EXPECT_EQ(serial::STOP_BITS_ONE, info->stop_bits); |
132 EXPECT_TRUE(info->cts_flow_control); | 227 EXPECT_TRUE(info->cts_flow_control); |
133 } | 228 } |
134 | 229 |
135 TEST_F(SerialConnectionTest, GetControlSignals) { | 230 TEST_F(SerialConnectionTest, GetControlSignals) { |
136 connection_->GetControlSignals(base::Bind( | 231 connection_->GetControlSignals(base::Bind( |
137 &SerialConnectionTest::StoreControlSignals, base::Unretained(this))); | 232 &SerialConnectionTest::StoreControlSignals, base::Unretained(this))); |
138 serial::DeviceControlSignals* signals = io_handler_->device_control_signals(); | 233 serial::DeviceControlSignals* signals = io_handler_->device_control_signals(); |
139 signals->dcd = true; | 234 signals->dcd = true; |
140 signals->dsr = true; | 235 signals->dsr = true; |
141 | 236 |
142 RunMessageLoop(); | 237 WaitForEvent(EVENT_GOT_CONTROL_SIGNALS); |
143 ASSERT_TRUE(signals_); | 238 ASSERT_TRUE(signals_); |
144 EXPECT_TRUE(signals_->dcd); | 239 EXPECT_TRUE(signals_->dcd); |
145 EXPECT_FALSE(signals_->cts); | 240 EXPECT_FALSE(signals_->cts); |
146 EXPECT_FALSE(signals_->ri); | 241 EXPECT_FALSE(signals_->ri); |
147 EXPECT_TRUE(signals_->dsr); | 242 EXPECT_TRUE(signals_->dsr); |
148 } | 243 } |
149 | 244 |
150 TEST_F(SerialConnectionTest, SetControlSignals) { | 245 TEST_F(SerialConnectionTest, SetControlSignals) { |
151 serial::HostControlSignalsPtr signals(serial::HostControlSignals::New()); | 246 serial::HostControlSignalsPtr signals(serial::HostControlSignals::New()); |
152 signals->has_dtr = true; | 247 signals->has_dtr = true; |
153 signals->dtr = true; | 248 signals->dtr = true; |
154 signals->has_rts = true; | 249 signals->has_rts = true; |
155 signals->rts = true; | 250 signals->rts = true; |
156 | 251 |
157 connection_->SetControlSignals( | 252 connection_->SetControlSignals(signals.Pass(), |
158 signals.Pass(), | 253 base::Bind(&SerialConnectionTest::StoreSuccess, |
159 base::Bind(&SerialConnectionTest::StoreSuccess, base::Unretained(this))); | 254 base::Unretained(this), |
160 RunMessageLoop(); | 255 EVENT_SET_CONTROL_SIGNALS)); |
| 256 WaitForEvent(EVENT_SET_CONTROL_SIGNALS); |
161 ASSERT_TRUE(success_); | 257 ASSERT_TRUE(success_); |
162 EXPECT_TRUE(io_handler_->dtr()); | 258 EXPECT_TRUE(io_handler_->dtr()); |
163 EXPECT_TRUE(io_handler_->rts()); | 259 EXPECT_TRUE(io_handler_->rts()); |
164 } | 260 } |
165 | 261 |
166 TEST_F(SerialConnectionTest, Flush) { | 262 TEST_F(SerialConnectionTest, Flush) { |
167 ASSERT_EQ(0, io_handler_->flushes()); | 263 ASSERT_EQ(0, io_handler_->flushes()); |
168 connection_->Flush( | 264 connection_->Flush(base::Bind(&SerialConnectionTest::StoreSuccess, |
169 base::Bind(&SerialConnectionTest::StoreSuccess, base::Unretained(this))); | 265 base::Unretained(this), |
170 RunMessageLoop(); | 266 EVENT_FLUSHED)); |
| 267 WaitForEvent(EVENT_FLUSHED); |
171 ASSERT_TRUE(success_); | 268 ASSERT_TRUE(success_); |
172 EXPECT_EQ(1, io_handler_->flushes()); | 269 EXPECT_EQ(1, io_handler_->flushes()); |
173 } | 270 } |
174 | 271 |
175 TEST_F(SerialConnectionTest, Disconnect) { | 272 TEST_F(SerialConnectionTest, Disconnect) { |
176 connection_.reset(); | 273 connection_.reset(); |
177 message_loop_.reset(); | 274 io_handler_->set_send_callback(base::Bind(base::DoNothing)); |
| 275 ASSERT_NO_FATAL_FAILURE(Send("data")); |
| 276 WaitForEvent(EVENT_SEND_ERROR); |
| 277 EXPECT_EQ(serial::SEND_ERROR_DISCONNECTED, send_error_); |
| 278 EXPECT_EQ(0, bytes_sent_); |
| 279 ASSERT_NO_FATAL_FAILURE(Receive()); |
| 280 WaitForEvent(EVENT_RECEIVE_ERROR); |
| 281 EXPECT_EQ(serial::RECEIVE_ERROR_DISCONNECTED, receive_error_); |
| 282 EXPECT_EQ("", data_received_); |
178 EXPECT_TRUE(io_handler_->HasOneRef()); | 283 EXPECT_TRUE(io_handler_->HasOneRef()); |
179 } | 284 } |
180 | 285 |
| 286 TEST_F(SerialConnectionTest, Echo) { |
| 287 ASSERT_NO_FATAL_FAILURE(Send("data")); |
| 288 WaitForEvent(EVENT_DATA_SENT); |
| 289 EXPECT_EQ(serial::SEND_ERROR_NONE, send_error_); |
| 290 EXPECT_EQ(4, bytes_sent_); |
| 291 ASSERT_NO_FATAL_FAILURE(Receive()); |
| 292 WaitForEvent(EVENT_DATA_RECEIVED); |
| 293 EXPECT_EQ("data", data_received_); |
| 294 EXPECT_EQ(serial::RECEIVE_ERROR_NONE, receive_error_); |
| 295 } |
| 296 |
| 297 TEST_F(SerialConnectionTest, Cancel) { |
| 298 // To test that cancels are correctly passed to the IoHandler, we need a send |
| 299 // to be in progress because otherwise, the DataSinkReceiver would handle the |
| 300 // cancel internally. |
| 301 io_handler_->set_send_callback( |
| 302 base::Bind(&SerialConnectionTest::EventReceived, |
| 303 base::Unretained(this), |
| 304 EVENT_DATA_AT_IO_HANDLER)); |
| 305 ASSERT_NO_FATAL_FAILURE(Send("something else")); |
| 306 WaitForEvent(EVENT_DATA_AT_IO_HANDLER); |
| 307 EXPECT_EQ(0, bytes_sent_); |
| 308 |
| 309 ASSERT_TRUE(sender_->Cancel(serial::SEND_ERROR_TIMEOUT, |
| 310 base::Bind(&SerialConnectionTest::EventReceived, |
| 311 base::Unretained(this), |
| 312 EVENT_CANCEL_COMPLETE))); |
| 313 |
| 314 WaitForEvent(EVENT_CANCEL_COMPLETE); |
| 315 EXPECT_EQ(serial::SEND_ERROR_TIMEOUT, send_error_); |
| 316 |
| 317 ASSERT_NO_FATAL_FAILURE(Send("data")); |
| 318 WaitForEvent(EVENT_DATA_SENT); |
| 319 EXPECT_EQ(serial::SEND_ERROR_NONE, send_error_); |
| 320 EXPECT_EQ(4, bytes_sent_); |
| 321 ASSERT_NO_FATAL_FAILURE(Receive()); |
| 322 WaitForEvent(EVENT_DATA_RECEIVED); |
| 323 EXPECT_EQ("data", data_received_); |
| 324 EXPECT_EQ(serial::RECEIVE_ERROR_NONE, receive_error_); |
| 325 } |
| 326 |
181 } // namespace device | 327 } // namespace device |
OLD | NEW |