15f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved.
25f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// found in the LICENSE file.
45f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
51320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include <string>
61320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
75f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "base/bind.h"
85f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "base/message_loop/message_loop.h"
95f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "base/run_loop.h"
101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/strings/string_piece.h"
111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "device/serial/data_receiver.h"
121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "device/serial/data_sender.h"
131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "device/serial/data_stream.mojom.h"
145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "device/serial/serial.mojom.h"
151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "device/serial/serial_connection.h"
165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "device/serial/serial_service_impl.h"
175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "device/serial/test_serial_io_handler.h"
185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "mojo/public/cpp/bindings/error_handler.h"
195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "mojo/public/cpp/bindings/interface_ptr.h"
205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "mojo/public/cpp/bindings/interface_request.h"
215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)namespace device {
245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)namespace {
255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class FakeSerialDeviceEnumerator : public SerialDeviceEnumerator {
275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  virtual mojo::Array<serial::DeviceInfoPtr> GetDevices() OVERRIDE {
285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    mojo::Array<serial::DeviceInfoPtr> devices(1);
295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    devices[0] = serial::DeviceInfo::New();
305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    devices[0]->path = "device";
315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return devices.Pass();
325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)};
345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}  // namespace
365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class SerialConnectionTest : public testing::Test, public mojo::ErrorHandler {
385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) public:
391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  enum Event {
401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    EVENT_NONE,
411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    EVENT_GOT_INFO,
421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    EVENT_SET_OPTIONS,
431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    EVENT_GOT_CONTROL_SIGNALS,
441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    EVENT_SET_CONTROL_SIGNALS,
451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    EVENT_FLUSHED,
461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    EVENT_DATA_AT_IO_HANDLER,
471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    EVENT_DATA_SENT,
481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    EVENT_SEND_ERROR,
491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    EVENT_DATA_RECEIVED,
501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    EVENT_RECEIVE_ERROR,
511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    EVENT_CANCEL_COMPLETE,
521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    EVENT_ERROR,
531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  };
541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  static const uint32_t kBufferSize;
561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  SerialConnectionTest()
581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      : connected_(false),
591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        success_(false),
601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        bytes_sent_(0),
611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        send_error_(serial::SEND_ERROR_NONE),
621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        receive_error_(serial::RECEIVE_ERROR_NONE),
631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        expected_event_(EVENT_NONE) {}
645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  virtual void SetUp() OVERRIDE {
665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    message_loop_.reset(new base::MessageLoop);
675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    mojo::InterfacePtr<serial::SerialService> service;
685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    mojo::BindToProxy(
695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        new SerialServiceImpl(
705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            new SerialConnectionFactory(
715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                base::Bind(&SerialConnectionTest::CreateIoHandler,
725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                           base::Unretained(this)),
735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                base::MessageLoopProxy::current()),
745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            scoped_ptr<SerialDeviceEnumerator>(new FakeSerialDeviceEnumerator)),
755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        &service);
765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    service.set_error_handler(this);
771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    mojo::InterfacePtr<serial::DataSink> consumer;
781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    mojo::InterfacePtr<serial::DataSource> producer;
791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    service->Connect("device",
801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                     serial::ConnectionOptions::New(),
811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                     mojo::Get(&connection_),
821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                     mojo::Get(&consumer),
831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                     mojo::Get(&producer));
841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    sender_.reset(new DataSender(
851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        consumer.Pass(), kBufferSize, serial::SEND_ERROR_DISCONNECTED));
861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    receiver_ = new DataReceiver(
871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        producer.Pass(), kBufferSize, serial::RECEIVE_ERROR_DISCONNECTED);
885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    connection_.set_error_handler(this);
895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    connection_->GetInfo(
905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        base::Bind(&SerialConnectionTest::StoreInfo, base::Unretained(this)));
911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    WaitForEvent(EVENT_GOT_INFO);
921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    ASSERT_TRUE(io_handler_.get());
935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  void StoreInfo(serial::ConnectionInfoPtr options) {
965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    info_ = options.Pass();
971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    EventReceived(EVENT_GOT_INFO);
985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  void StoreControlSignals(serial::DeviceControlSignalsPtr signals) {
1015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    signals_ = signals.Pass();
1021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    EventReceived(EVENT_GOT_CONTROL_SIGNALS);
1035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
1045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  void StoreSuccess(Event event_to_report, bool success) {
1065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    success_ = success;
1071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    EventReceived(event_to_report);
1081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
1091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  void Send(const base::StringPiece& data) {
1111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    ASSERT_TRUE(sender_->Send(
1121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        data,
1131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        base::Bind(&SerialConnectionTest::OnDataSent, base::Unretained(this)),
1141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        base::Bind(&SerialConnectionTest::OnSendError,
1151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                   base::Unretained(this))));
1161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
1171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  void Receive() {
1191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    ASSERT_TRUE(
1201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        receiver_->Receive(base::Bind(&SerialConnectionTest::OnDataReceived,
1211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                      base::Unretained(this)),
1221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                           base::Bind(&SerialConnectionTest::OnReceiveError,
1231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                      base::Unretained(this))));
1245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
1255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  void WaitForEvent(Event event) {
1271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    expected_event_ = event;
1281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    base::RunLoop run_loop;
1291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    stop_run_loop_ = run_loop.QuitClosure();
1301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    run_loop.Run();
1315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
1325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  void EventReceived(Event event) {
1341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    if (event != expected_event_)
1351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      return;
1361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    expected_event_ = EVENT_NONE;
1375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    ASSERT_TRUE(message_loop_);
1381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    ASSERT_TRUE(!stop_run_loop_.is_null());
1391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    message_loop_->PostTask(FROM_HERE, stop_run_loop_);
1405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
1415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  scoped_refptr<SerialIoHandler> CreateIoHandler() {
1435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    io_handler_ = new TestSerialIoHandler;
1445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return io_handler_;
1455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
1465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  void OnDataSent(uint32_t bytes_sent) {
1481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    bytes_sent_ += bytes_sent;
1491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    send_error_ = serial::SEND_ERROR_NONE;
1501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    EventReceived(EVENT_DATA_SENT);
1511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
1521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  void OnSendError(uint32_t bytes_sent, int32_t error) {
1541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    bytes_sent_ += bytes_sent;
1551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    send_error_ = static_cast<serial::SendError>(error);
1561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    EventReceived(EVENT_SEND_ERROR);
1571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
1581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  void OnDataReceived(scoped_ptr<ReadOnlyBuffer> buffer) {
1601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    data_received_ += std::string(buffer->GetData(), buffer->GetSize());
1611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    buffer->Done(buffer->GetSize());
1621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    receive_error_ = serial::RECEIVE_ERROR_NONE;
1631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    EventReceived(EVENT_DATA_RECEIVED);
1641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
1651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  void OnReceiveError(int32_t error) {
1671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    receive_error_ = static_cast<serial::ReceiveError>(error);
1681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    EventReceived(EVENT_RECEIVE_ERROR);
1691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
1701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  virtual void OnConnectionError() OVERRIDE {
1721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    EventReceived(EVENT_ERROR);
1735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    FAIL() << "Connection error";
1745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
1755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  mojo::Array<serial::DeviceInfoPtr> devices_;
1775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  serial::ConnectionInfoPtr info_;
1785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  serial::DeviceControlSignalsPtr signals_;
1795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  bool connected_;
1805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  bool success_;
1811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  int bytes_sent_;
1821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  serial::SendError send_error_;
1831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  serial::ReceiveError receive_error_;
1841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  std::string data_received_;
1851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  Event expected_event_;
1865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  scoped_ptr<base::MessageLoop> message_loop_;
1881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  base::Closure stop_run_loop_;
1895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  mojo::InterfacePtr<serial::Connection> connection_;
1901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_ptr<DataSender> sender_;
1911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_refptr<DataReceiver> receiver_;
1925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  scoped_refptr<TestSerialIoHandler> io_handler_;
1935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) private:
1955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(SerialConnectionTest);
1965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)};
1975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciconst uint32_t SerialConnectionTest::kBufferSize = 10;
1991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)TEST_F(SerialConnectionTest, GetInfo) {
2015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // |info_| is filled in during SetUp().
2025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ASSERT_TRUE(info_);
2035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  EXPECT_EQ(9600u, info_->bitrate);
2045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  EXPECT_EQ(serial::DATA_BITS_EIGHT, info_->data_bits);
2055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  EXPECT_EQ(serial::PARITY_BIT_NO, info_->parity_bit);
2065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  EXPECT_EQ(serial::STOP_BITS_ONE, info_->stop_bits);
2075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  EXPECT_FALSE(info_->cts_flow_control);
2085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
2095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)TEST_F(SerialConnectionTest, SetOptions) {
2115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  serial::ConnectionOptionsPtr options(serial::ConnectionOptions::New());
2125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  options->bitrate = 12345;
2135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  options->data_bits = serial::DATA_BITS_SEVEN;
2145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  options->has_cts_flow_control = true;
2155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  options->cts_flow_control = true;
2161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  connection_->SetOptions(options.Pass(),
2171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                          base::Bind(&SerialConnectionTest::StoreSuccess,
2181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                     base::Unretained(this),
2191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                     EVENT_SET_OPTIONS));
2201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  WaitForEvent(EVENT_SET_OPTIONS);
2215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ASSERT_TRUE(success_);
2225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  serial::ConnectionInfo* info = io_handler_->connection_info();
2235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  EXPECT_EQ(12345u, info->bitrate);
2245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  EXPECT_EQ(serial::DATA_BITS_SEVEN, info->data_bits);
2255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  EXPECT_EQ(serial::PARITY_BIT_NO, info->parity_bit);
2265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  EXPECT_EQ(serial::STOP_BITS_ONE, info->stop_bits);
2275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  EXPECT_TRUE(info->cts_flow_control);
2285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
2295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)TEST_F(SerialConnectionTest, GetControlSignals) {
2315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  connection_->GetControlSignals(base::Bind(
2325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      &SerialConnectionTest::StoreControlSignals, base::Unretained(this)));
2335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  serial::DeviceControlSignals* signals = io_handler_->device_control_signals();
2345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  signals->dcd = true;
2355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  signals->dsr = true;
2365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  WaitForEvent(EVENT_GOT_CONTROL_SIGNALS);
2385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ASSERT_TRUE(signals_);
2395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  EXPECT_TRUE(signals_->dcd);
2405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  EXPECT_FALSE(signals_->cts);
2415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  EXPECT_FALSE(signals_->ri);
2425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  EXPECT_TRUE(signals_->dsr);
2435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
2445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)TEST_F(SerialConnectionTest, SetControlSignals) {
2465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  serial::HostControlSignalsPtr signals(serial::HostControlSignals::New());
2475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  signals->has_dtr = true;
2485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  signals->dtr = true;
2495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  signals->has_rts = true;
2505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  signals->rts = true;
2515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  connection_->SetControlSignals(signals.Pass(),
2531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                 base::Bind(&SerialConnectionTest::StoreSuccess,
2541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                            base::Unretained(this),
2551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                            EVENT_SET_CONTROL_SIGNALS));
2561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  WaitForEvent(EVENT_SET_CONTROL_SIGNALS);
2575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ASSERT_TRUE(success_);
2585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  EXPECT_TRUE(io_handler_->dtr());
2595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  EXPECT_TRUE(io_handler_->rts());
2605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
2615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)TEST_F(SerialConnectionTest, Flush) {
2635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ASSERT_EQ(0, io_handler_->flushes());
2641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  connection_->Flush(base::Bind(&SerialConnectionTest::StoreSuccess,
2651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                base::Unretained(this),
2661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                EVENT_FLUSHED));
2671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  WaitForEvent(EVENT_FLUSHED);
2685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ASSERT_TRUE(success_);
2695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  EXPECT_EQ(1, io_handler_->flushes());
2705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
2715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)TEST_F(SerialConnectionTest, Disconnect) {
2735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  connection_.reset();
2741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  io_handler_->set_send_callback(base::Bind(base::DoNothing));
2751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ASSERT_NO_FATAL_FAILURE(Send("data"));
2761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  WaitForEvent(EVENT_SEND_ERROR);
2771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(serial::SEND_ERROR_DISCONNECTED, send_error_);
2781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(0, bytes_sent_);
2791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ASSERT_NO_FATAL_FAILURE(Receive());
2801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  WaitForEvent(EVENT_RECEIVE_ERROR);
2811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(serial::RECEIVE_ERROR_DISCONNECTED, receive_error_);
2821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ("", data_received_);
2835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  EXPECT_TRUE(io_handler_->HasOneRef());
2845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
2855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTEST_F(SerialConnectionTest, Echo) {
2871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ASSERT_NO_FATAL_FAILURE(Send("data"));
2881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  WaitForEvent(EVENT_DATA_SENT);
2891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(serial::SEND_ERROR_NONE, send_error_);
2901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(4, bytes_sent_);
2911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ASSERT_NO_FATAL_FAILURE(Receive());
2921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  WaitForEvent(EVENT_DATA_RECEIVED);
2931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ("data", data_received_);
2941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(serial::RECEIVE_ERROR_NONE, receive_error_);
2951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
2961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTEST_F(SerialConnectionTest, Cancel) {
2981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // To test that cancels are correctly passed to the IoHandler, we need a send
2991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // to be in progress because otherwise, the DataSinkReceiver would handle the
3001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // cancel internally.
3011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  io_handler_->set_send_callback(
3021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      base::Bind(&SerialConnectionTest::EventReceived,
3031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                 base::Unretained(this),
3041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                 EVENT_DATA_AT_IO_HANDLER));
3051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ASSERT_NO_FATAL_FAILURE(Send("something else"));
3061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  WaitForEvent(EVENT_DATA_AT_IO_HANDLER);
3071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(0, bytes_sent_);
3081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
3091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ASSERT_TRUE(sender_->Cancel(serial::SEND_ERROR_TIMEOUT,
3101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                              base::Bind(&SerialConnectionTest::EventReceived,
3111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                         base::Unretained(this),
3121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                         EVENT_CANCEL_COMPLETE)));
3131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
3141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  WaitForEvent(EVENT_CANCEL_COMPLETE);
3151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(serial::SEND_ERROR_TIMEOUT, send_error_);
3161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
3171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ASSERT_NO_FATAL_FAILURE(Send("data"));
3181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  WaitForEvent(EVENT_DATA_SENT);
3191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(serial::SEND_ERROR_NONE, send_error_);
3201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(4, bytes_sent_);
3211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ASSERT_NO_FATAL_FAILURE(Receive());
3221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  WaitForEvent(EVENT_DATA_RECEIVED);
3231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ("data", data_received_);
3241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_EQ(serial::RECEIVE_ERROR_NONE, receive_error_);
3251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
3261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
3275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}  // namespace device
328