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.
4
5#include <string>
6
7#include "base/bind.h"
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 "mojo/public/cpp/bindings/error_handler.h"
19#include "mojo/public/cpp/bindings/interface_ptr.h"
20#include "mojo/public/cpp/bindings/interface_request.h"
21#include "testing/gtest/include/gtest/gtest.h"
22
23namespace device {
24namespace {
25
26class FakeSerialDeviceEnumerator : public SerialDeviceEnumerator {
27  virtual 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();
32  }
33};
34
35}  // namespace
36
37class SerialConnectionTest : public testing::Test, public mojo::ErrorHandler {
38 public:
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) {}
64
65  virtual void SetUp() OVERRIDE {
66    message_loop_.reset(new base::MessageLoop);
67    mojo::InterfacePtr<serial::SerialService> service;
68    mojo::BindToProxy(
69        new SerialServiceImpl(
70            new SerialConnectionFactory(
71                base::Bind(&SerialConnectionTest::CreateIoHandler,
72                           base::Unretained(this)),
73                base::MessageLoopProxy::current()),
74            scoped_ptr<SerialDeviceEnumerator>(new FakeSerialDeviceEnumerator)),
75        &service);
76    service.set_error_handler(this);
77    mojo::InterfacePtr<serial::DataSink> consumer;
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);
88    connection_.set_error_handler(this);
89    connection_->GetInfo(
90        base::Bind(&SerialConnectionTest::StoreInfo, base::Unretained(this)));
91    WaitForEvent(EVENT_GOT_INFO);
92    ASSERT_TRUE(io_handler_.get());
93  }
94
95  void StoreInfo(serial::ConnectionInfoPtr options) {
96    info_ = options.Pass();
97    EventReceived(EVENT_GOT_INFO);
98  }
99
100  void StoreControlSignals(serial::DeviceControlSignalsPtr signals) {
101    signals_ = signals.Pass();
102    EventReceived(EVENT_GOT_CONTROL_SIGNALS);
103  }
104
105  void StoreSuccess(Event event_to_report, bool success) {
106    success_ = success;
107    EventReceived(event_to_report);
108  }
109
110  void Send(const base::StringPiece& data) {
111    ASSERT_TRUE(sender_->Send(
112        data,
113        base::Bind(&SerialConnectionTest::OnDataSent, base::Unretained(this)),
114        base::Bind(&SerialConnectionTest::OnSendError,
115                   base::Unretained(this))));
116  }
117
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;
137    ASSERT_TRUE(message_loop_);
138    ASSERT_TRUE(!stop_run_loop_.is_null());
139    message_loop_->PostTask(FROM_HERE, stop_run_loop_);
140  }
141
142  scoped_refptr<SerialIoHandler> CreateIoHandler() {
143    io_handler_ = new TestSerialIoHandler;
144    return io_handler_;
145  }
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
171  virtual void OnConnectionError() OVERRIDE {
172    EventReceived(EVENT_ERROR);
173    FAIL() << "Connection error";
174  }
175
176  mojo::Array<serial::DeviceInfoPtr> devices_;
177  serial::ConnectionInfoPtr info_;
178  serial::DeviceControlSignalsPtr signals_;
179  bool connected_;
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_;
186
187  scoped_ptr<base::MessageLoop> message_loop_;
188  base::Closure stop_run_loop_;
189  mojo::InterfacePtr<serial::Connection> connection_;
190  scoped_ptr<DataSender> sender_;
191  scoped_refptr<DataReceiver> receiver_;
192  scoped_refptr<TestSerialIoHandler> io_handler_;
193
194 private:
195  DISALLOW_COPY_AND_ASSIGN(SerialConnectionTest);
196};
197
198const uint32_t SerialConnectionTest::kBufferSize = 10;
199
200TEST_F(SerialConnectionTest, GetInfo) {
201  // |info_| is filled in during SetUp().
202  ASSERT_TRUE(info_);
203  EXPECT_EQ(9600u, info_->bitrate);
204  EXPECT_EQ(serial::DATA_BITS_EIGHT, info_->data_bits);
205  EXPECT_EQ(serial::PARITY_BIT_NO, info_->parity_bit);
206  EXPECT_EQ(serial::STOP_BITS_ONE, info_->stop_bits);
207  EXPECT_FALSE(info_->cts_flow_control);
208}
209
210TEST_F(SerialConnectionTest, SetOptions) {
211  serial::ConnectionOptionsPtr options(serial::ConnectionOptions::New());
212  options->bitrate = 12345;
213  options->data_bits = serial::DATA_BITS_SEVEN;
214  options->has_cts_flow_control = true;
215  options->cts_flow_control = true;
216  connection_->SetOptions(options.Pass(),
217                          base::Bind(&SerialConnectionTest::StoreSuccess,
218                                     base::Unretained(this),
219                                     EVENT_SET_OPTIONS));
220  WaitForEvent(EVENT_SET_OPTIONS);
221  ASSERT_TRUE(success_);
222  serial::ConnectionInfo* info = io_handler_->connection_info();
223  EXPECT_EQ(12345u, info->bitrate);
224  EXPECT_EQ(serial::DATA_BITS_SEVEN, info->data_bits);
225  EXPECT_EQ(serial::PARITY_BIT_NO, info->parity_bit);
226  EXPECT_EQ(serial::STOP_BITS_ONE, info->stop_bits);
227  EXPECT_TRUE(info->cts_flow_control);
228}
229
230TEST_F(SerialConnectionTest, GetControlSignals) {
231  connection_->GetControlSignals(base::Bind(
232      &SerialConnectionTest::StoreControlSignals, base::Unretained(this)));
233  serial::DeviceControlSignals* signals = io_handler_->device_control_signals();
234  signals->dcd = true;
235  signals->dsr = true;
236
237  WaitForEvent(EVENT_GOT_CONTROL_SIGNALS);
238  ASSERT_TRUE(signals_);
239  EXPECT_TRUE(signals_->dcd);
240  EXPECT_FALSE(signals_->cts);
241  EXPECT_FALSE(signals_->ri);
242  EXPECT_TRUE(signals_->dsr);
243}
244
245TEST_F(SerialConnectionTest, SetControlSignals) {
246  serial::HostControlSignalsPtr signals(serial::HostControlSignals::New());
247  signals->has_dtr = true;
248  signals->dtr = true;
249  signals->has_rts = true;
250  signals->rts = true;
251
252  connection_->SetControlSignals(signals.Pass(),
253                                 base::Bind(&SerialConnectionTest::StoreSuccess,
254                                            base::Unretained(this),
255                                            EVENT_SET_CONTROL_SIGNALS));
256  WaitForEvent(EVENT_SET_CONTROL_SIGNALS);
257  ASSERT_TRUE(success_);
258  EXPECT_TRUE(io_handler_->dtr());
259  EXPECT_TRUE(io_handler_->rts());
260}
261
262TEST_F(SerialConnectionTest, Flush) {
263  ASSERT_EQ(0, io_handler_->flushes());
264  connection_->Flush(base::Bind(&SerialConnectionTest::StoreSuccess,
265                                base::Unretained(this),
266                                EVENT_FLUSHED));
267  WaitForEvent(EVENT_FLUSHED);
268  ASSERT_TRUE(success_);
269  EXPECT_EQ(1, io_handler_->flushes());
270}
271
272TEST_F(SerialConnectionTest, Disconnect) {
273  connection_.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_);
283  EXPECT_TRUE(io_handler_->HasOneRef());
284}
285
286TEST_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
297TEST_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
327}  // namespace device
328