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.
8 #include "base/message_loop/message_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"
14 #include "device/serial/serial.mojom.h"
15 #include "device/serial/serial_connection.h"
16 #include "device/serial/serial_service_impl.h"
17 #include "device/serial/test_serial_io_handler.h"
18 #include "testing/gtest/include/gtest/gtest.h"
19 #include "third_party/mojo/src/mojo/public/cpp/bindings/error_handler.h"
20 #include "third_party/mojo/src/mojo/public/cpp/bindings/interface_ptr.h"
21 #include "third_party/mojo/src/mojo/public/cpp/bindings/interface_request.h"
26 class FakeSerialDeviceEnumerator
: public SerialDeviceEnumerator
{
27 mojo::Array
<serial::DeviceInfoPtr
> GetDevices() override
{
28 mojo::Array
<serial::DeviceInfoPtr
> devices(1);
29 devices
[0] = serial::DeviceInfo::New();
30 devices
[0]->path
= "device";
31 return devices
.Pass();
37 class SerialConnectionTest
: public testing::Test
, public mojo::ErrorHandler
{
43 EVENT_GOT_CONTROL_SIGNALS
,
44 EVENT_SET_CONTROL_SIGNALS
,
46 EVENT_DATA_AT_IO_HANDLER
,
51 EVENT_CANCEL_COMPLETE
,
55 static const uint32_t kBufferSize
;
57 SerialConnectionTest()
61 send_error_(serial::SEND_ERROR_NONE
),
62 receive_error_(serial::RECEIVE_ERROR_NONE
),
63 expected_event_(EVENT_NONE
) {}
65 void SetUp() override
{
66 message_loop_
.reset(new base::MessageLoop
);
67 mojo::InterfacePtr
<serial::SerialService
> service
;
68 new SerialServiceImpl(
69 new SerialConnectionFactory(
70 base::Bind(&SerialConnectionTest::CreateIoHandler
,
71 base::Unretained(this)),
72 base::ThreadTaskRunnerHandle::Get()),
73 scoped_ptr
<SerialDeviceEnumerator
>(new FakeSerialDeviceEnumerator
),
74 mojo::GetProxy(&service
));
75 service
.set_error_handler(this);
76 mojo::InterfacePtr
<serial::DataSink
> sink
;
77 mojo::InterfacePtr
<serial::DataSource
> source
;
78 mojo::InterfacePtr
<serial::DataSourceClient
> source_client
;
79 mojo::InterfaceRequest
<serial::DataSourceClient
> source_client_request
=
80 mojo::GetProxy(&source_client
);
81 service
->Connect("device", serial::ConnectionOptions::New(),
82 mojo::GetProxy(&connection_
), mojo::GetProxy(&sink
),
83 mojo::GetProxy(&source
), source_client
.Pass());
84 sender_
.reset(new DataSender(sink
.Pass(), kBufferSize
,
85 serial::SEND_ERROR_DISCONNECTED
));
87 new DataReceiver(source
.Pass(), source_client_request
.Pass(),
88 kBufferSize
, serial::RECEIVE_ERROR_DISCONNECTED
);
89 connection_
.set_error_handler(this);
91 base::Bind(&SerialConnectionTest::StoreInfo
, base::Unretained(this)));
92 WaitForEvent(EVENT_GOT_INFO
);
93 ASSERT_TRUE(io_handler_
.get());
96 void StoreInfo(serial::ConnectionInfoPtr options
) {
97 info_
= options
.Pass();
98 EventReceived(EVENT_GOT_INFO
);
101 void StoreControlSignals(serial::DeviceControlSignalsPtr signals
) {
102 signals_
= signals
.Pass();
103 EventReceived(EVENT_GOT_CONTROL_SIGNALS
);
106 void StoreSuccess(Event event_to_report
, bool success
) {
108 EventReceived(event_to_report
);
111 void Send(const base::StringPiece
& data
) {
112 ASSERT_TRUE(sender_
->Send(
114 base::Bind(&SerialConnectionTest::OnDataSent
, base::Unretained(this)),
115 base::Bind(&SerialConnectionTest::OnSendError
,
116 base::Unretained(this))));
121 receiver_
->Receive(base::Bind(&SerialConnectionTest::OnDataReceived
,
122 base::Unretained(this)),
123 base::Bind(&SerialConnectionTest::OnReceiveError
,
124 base::Unretained(this))));
127 void WaitForEvent(Event event
) {
128 expected_event_
= event
;
129 base::RunLoop run_loop
;
130 stop_run_loop_
= run_loop
.QuitClosure();
134 void EventReceived(Event event
) {
135 if (event
!= expected_event_
)
137 expected_event_
= EVENT_NONE
;
138 ASSERT_TRUE(message_loop_
);
139 ASSERT_TRUE(!stop_run_loop_
.is_null());
140 message_loop_
->PostTask(FROM_HERE
, stop_run_loop_
);
143 scoped_refptr
<SerialIoHandler
> CreateIoHandler() {
144 io_handler_
= new TestSerialIoHandler
;
148 void OnDataSent(uint32_t bytes_sent
) {
149 bytes_sent_
+= bytes_sent
;
150 send_error_
= serial::SEND_ERROR_NONE
;
151 EventReceived(EVENT_DATA_SENT
);
154 void OnSendError(uint32_t bytes_sent
, int32_t error
) {
155 bytes_sent_
+= bytes_sent
;
156 send_error_
= static_cast<serial::SendError
>(error
);
157 EventReceived(EVENT_SEND_ERROR
);
160 void OnDataReceived(scoped_ptr
<ReadOnlyBuffer
> buffer
) {
161 data_received_
+= std::string(buffer
->GetData(), buffer
->GetSize());
162 buffer
->Done(buffer
->GetSize());
163 receive_error_
= serial::RECEIVE_ERROR_NONE
;
164 EventReceived(EVENT_DATA_RECEIVED
);
167 void OnReceiveError(int32_t error
) {
168 receive_error_
= static_cast<serial::ReceiveError
>(error
);
169 EventReceived(EVENT_RECEIVE_ERROR
);
172 void OnConnectionError() override
{
173 EventReceived(EVENT_ERROR
);
174 FAIL() << "Connection error";
177 mojo::Array
<serial::DeviceInfoPtr
> devices_
;
178 serial::ConnectionInfoPtr info_
;
179 serial::DeviceControlSignalsPtr signals_
;
183 serial::SendError send_error_
;
184 serial::ReceiveError receive_error_
;
185 std::string data_received_
;
186 Event expected_event_
;
188 scoped_ptr
<base::MessageLoop
> message_loop_
;
189 base::Closure stop_run_loop_
;
190 mojo::InterfacePtr
<serial::Connection
> connection_
;
191 scoped_ptr
<DataSender
> sender_
;
192 scoped_refptr
<DataReceiver
> receiver_
;
193 scoped_refptr
<TestSerialIoHandler
> io_handler_
;
196 DISALLOW_COPY_AND_ASSIGN(SerialConnectionTest
);
199 const uint32_t SerialConnectionTest::kBufferSize
= 10;
201 TEST_F(SerialConnectionTest
, GetInfo
) {
202 // |info_| is filled in during SetUp().
204 EXPECT_EQ(9600u, info_
->bitrate
);
205 EXPECT_EQ(serial::DATA_BITS_EIGHT
, info_
->data_bits
);
206 EXPECT_EQ(serial::PARITY_BIT_NO
, info_
->parity_bit
);
207 EXPECT_EQ(serial::STOP_BITS_ONE
, info_
->stop_bits
);
208 EXPECT_FALSE(info_
->cts_flow_control
);
211 TEST_F(SerialConnectionTest
, SetOptions
) {
212 serial::ConnectionOptionsPtr
options(serial::ConnectionOptions::New());
213 options
->bitrate
= 12345;
214 options
->data_bits
= serial::DATA_BITS_SEVEN
;
215 options
->has_cts_flow_control
= true;
216 options
->cts_flow_control
= true;
217 connection_
->SetOptions(options
.Pass(),
218 base::Bind(&SerialConnectionTest::StoreSuccess
,
219 base::Unretained(this),
221 WaitForEvent(EVENT_SET_OPTIONS
);
222 ASSERT_TRUE(success_
);
223 serial::ConnectionInfo
* info
= io_handler_
->connection_info();
224 EXPECT_EQ(12345u, info
->bitrate
);
225 EXPECT_EQ(serial::DATA_BITS_SEVEN
, info
->data_bits
);
226 EXPECT_EQ(serial::PARITY_BIT_NO
, info
->parity_bit
);
227 EXPECT_EQ(serial::STOP_BITS_ONE
, info
->stop_bits
);
228 EXPECT_TRUE(info
->cts_flow_control
);
231 TEST_F(SerialConnectionTest
, GetControlSignals
) {
232 connection_
->GetControlSignals(base::Bind(
233 &SerialConnectionTest::StoreControlSignals
, base::Unretained(this)));
234 serial::DeviceControlSignals
* signals
= io_handler_
->device_control_signals();
238 WaitForEvent(EVENT_GOT_CONTROL_SIGNALS
);
239 ASSERT_TRUE(signals_
);
240 EXPECT_TRUE(signals_
->dcd
);
241 EXPECT_FALSE(signals_
->cts
);
242 EXPECT_FALSE(signals_
->ri
);
243 EXPECT_TRUE(signals_
->dsr
);
246 TEST_F(SerialConnectionTest
, SetControlSignals
) {
247 serial::HostControlSignalsPtr
signals(serial::HostControlSignals::New());
248 signals
->has_dtr
= true;
250 signals
->has_rts
= true;
253 connection_
->SetControlSignals(signals
.Pass(),
254 base::Bind(&SerialConnectionTest::StoreSuccess
,
255 base::Unretained(this),
256 EVENT_SET_CONTROL_SIGNALS
));
257 WaitForEvent(EVENT_SET_CONTROL_SIGNALS
);
258 ASSERT_TRUE(success_
);
259 EXPECT_TRUE(io_handler_
->dtr());
260 EXPECT_TRUE(io_handler_
->rts());
263 TEST_F(SerialConnectionTest
, Flush
) {
264 ASSERT_EQ(0, io_handler_
->flushes());
265 connection_
->Flush(base::Bind(&SerialConnectionTest::StoreSuccess
,
266 base::Unretained(this),
268 WaitForEvent(EVENT_FLUSHED
);
269 ASSERT_TRUE(success_
);
270 EXPECT_EQ(1, io_handler_
->flushes());
273 TEST_F(SerialConnectionTest
, DisconnectWithSend
) {
275 io_handler_
->set_send_callback(base::Bind(base::DoNothing
));
276 ASSERT_NO_FATAL_FAILURE(Send("data"));
277 WaitForEvent(EVENT_SEND_ERROR
);
278 EXPECT_EQ(serial::SEND_ERROR_DISCONNECTED
, send_error_
);
279 EXPECT_EQ(0, bytes_sent_
);
280 EXPECT_TRUE(io_handler_
->HasOneRef());
283 TEST_F(SerialConnectionTest
, DisconnectWithReceive
) {
285 ASSERT_NO_FATAL_FAILURE(Receive());
286 WaitForEvent(EVENT_RECEIVE_ERROR
);
287 EXPECT_EQ(serial::RECEIVE_ERROR_DISCONNECTED
, receive_error_
);
288 EXPECT_EQ("", data_received_
);
289 EXPECT_TRUE(io_handler_
->HasOneRef());
292 TEST_F(SerialConnectionTest
, Echo
) {
293 ASSERT_NO_FATAL_FAILURE(Send("data"));
294 WaitForEvent(EVENT_DATA_SENT
);
295 EXPECT_EQ(serial::SEND_ERROR_NONE
, send_error_
);
296 EXPECT_EQ(4, bytes_sent_
);
297 ASSERT_NO_FATAL_FAILURE(Receive());
298 WaitForEvent(EVENT_DATA_RECEIVED
);
299 EXPECT_EQ("data", data_received_
);
300 EXPECT_EQ(serial::RECEIVE_ERROR_NONE
, receive_error_
);
303 TEST_F(SerialConnectionTest
, Cancel
) {
304 // To test that cancels are correctly passed to the IoHandler, we need a send
305 // to be in progress because otherwise, the DataSinkReceiver would handle the
306 // cancel internally.
307 io_handler_
->set_send_callback(
308 base::Bind(&SerialConnectionTest::EventReceived
,
309 base::Unretained(this),
310 EVENT_DATA_AT_IO_HANDLER
));
311 ASSERT_NO_FATAL_FAILURE(Send("something else"));
312 WaitForEvent(EVENT_DATA_AT_IO_HANDLER
);
313 EXPECT_EQ(0, bytes_sent_
);
315 ASSERT_TRUE(sender_
->Cancel(serial::SEND_ERROR_TIMEOUT
,
316 base::Bind(&SerialConnectionTest::EventReceived
,
317 base::Unretained(this),
318 EVENT_CANCEL_COMPLETE
)));
320 WaitForEvent(EVENT_CANCEL_COMPLETE
);
321 EXPECT_EQ(serial::SEND_ERROR_TIMEOUT
, send_error_
);
323 ASSERT_NO_FATAL_FAILURE(Send("data"));
324 WaitForEvent(EVENT_DATA_SENT
);
325 EXPECT_EQ(serial::SEND_ERROR_NONE
, send_error_
);
326 EXPECT_EQ(4, bytes_sent_
);
327 ASSERT_NO_FATAL_FAILURE(Receive());
328 WaitForEvent(EVENT_DATA_RECEIVED
);
329 EXPECT_EQ("data", data_received_
);
330 EXPECT_EQ(serial::RECEIVE_ERROR_NONE
, receive_error_
);
333 } // namespace device