1116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// Copyright 2014 The Chromium Authors. All rights reserved.
2116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// Use of this source code is governed by a BSD-style license that can be
3116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// found in the LICENSE file.
4116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
5116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "base/bind.h"
6116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "base/message_loop/message_loop.h"
7116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "base/run_loop.h"
8116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "device/serial/serial.mojom.h"
9116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "device/serial/serial_service_impl.h"
105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "device/serial/test_serial_io_handler.h"
11116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "mojo/public/cpp/bindings/error_handler.h"
12116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "mojo/public/cpp/bindings/interface_ptr.h"
13116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "mojo/public/cpp/bindings/interface_request.h"
14116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "testing/gtest/include/gtest/gtest.h"
15116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
16116680a4aac90f2aa7413d9095a592090648e557Ben Murdochnamespace device {
175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)namespace {
185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class FakeSerialDeviceEnumerator : public SerialDeviceEnumerator {
205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  virtual mojo::Array<serial::DeviceInfoPtr> GetDevices() OVERRIDE {
215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    mojo::Array<serial::DeviceInfoPtr> devices(1);
225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    devices[0] = serial::DeviceInfo::New();
235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    devices[0]->path = "device";
245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return devices.Pass();
255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)};
275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class FailToOpenIoHandler : public TestSerialIoHandler {
295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) public:
305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  virtual void Open(const std::string& port,
315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                    const OpenCompleteCallback& callback) OVERRIDE {
325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    callback.Run(false);
335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) protected:
365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  virtual ~FailToOpenIoHandler() {}
375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)};
385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}  // namespace
40116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
41116680a4aac90f2aa7413d9095a592090648e557Ben Murdochclass SerialServiceTest : public testing::Test, public mojo::ErrorHandler {
42116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch public:
431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  SerialServiceTest() : connected_(false), expecting_error_(false) {}
44116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
45116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  void StoreDevices(mojo::Array<serial::DeviceInfoPtr> devices) {
46116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    devices_ = devices.Pass();
475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    StopMessageLoop();
48116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
49116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
50116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  virtual void OnConnectionError() OVERRIDE {
515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    StopMessageLoop();
525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    EXPECT_TRUE(expecting_error_);
535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  void RunMessageLoop() {
565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    run_loop_.reset(new base::RunLoop);
575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    run_loop_->Run();
58116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
59116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  void StopMessageLoop() {
615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    ASSERT_TRUE(run_loop_);
625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    message_loop_.PostTask(FROM_HERE, run_loop_->QuitClosure());
635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  void OnGotInfo(serial::ConnectionInfoPtr options) {
661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    connected_ = true;
671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    StopMessageLoop();
681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_refptr<SerialIoHandler> ReturnIoHandler() { return io_handler_; }
711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  void RunConnectTest(const std::string& path, bool expecting_success) {
731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    if (!io_handler_.get())
741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      io_handler_ = new TestSerialIoHandler;
751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    mojo::InterfacePtr<serial::SerialService> service;
761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    mojo::BindToProxy(
771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        new SerialServiceImpl(
781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci            new SerialConnectionFactory(
791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                base::Bind(&SerialServiceTest::ReturnIoHandler,
801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                           base::Unretained(this)),
811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                base::MessageLoopProxy::current()),
821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci            scoped_ptr<SerialDeviceEnumerator>(new FakeSerialDeviceEnumerator)),
831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        &service);
841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    mojo::InterfacePtr<serial::Connection> connection;
851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    mojo::InterfacePtr<serial::DataSink> sink;
861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    mojo::InterfacePtr<serial::DataSource> source;
871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    service->Connect(path,
881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                     serial::ConnectionOptions::New(),
891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                     mojo::Get(&connection),
901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                     mojo::Get(&sink),
911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                     mojo::Get(&source));
921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    connection.set_error_handler(this);
931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    expecting_error_ = !expecting_success;
941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    connection->GetInfo(
951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        base::Bind(&SerialServiceTest::OnGotInfo, base::Unretained(this)));
961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    RunMessageLoop();
971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    EXPECT_EQ(!expecting_success, connection.encountered_error());
981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    EXPECT_EQ(expecting_success, connected_);
991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    connection.reset();
1001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
1015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
102116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  base::MessageLoop message_loop_;
1035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  scoped_ptr<base::RunLoop> run_loop_;
104116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  mojo::Array<serial::DeviceInfoPtr> devices_;
1055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  scoped_refptr<TestSerialIoHandler> io_handler_;
1061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  bool connected_;
1075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  bool expecting_error_;
1085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  serial::ConnectionInfoPtr info_;
109116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
110116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch private:
111116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DISALLOW_COPY_AND_ASSIGN(SerialServiceTest);
112116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch};
113116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
114116680a4aac90f2aa7413d9095a592090648e557Ben MurdochTEST_F(SerialServiceTest, GetDevices) {
115116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  mojo::InterfacePtr<serial::SerialService> service;
1165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  SerialServiceImpl::Create(NULL, mojo::Get(&service));
117116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  service.set_error_handler(this);
118116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  mojo::Array<serial::DeviceInfoPtr> result;
119116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  service->GetDevices(
120116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      base::Bind(&SerialServiceTest::StoreDevices, base::Unretained(this)));
1215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  RunMessageLoop();
122116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
123116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Because we're running on unknown hardware, only check that we received a
124116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // non-null result.
125116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  EXPECT_TRUE(devices_);
126116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
127116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
1285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)TEST_F(SerialServiceTest, Connect) {
1291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  RunConnectTest("device", true);
1305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
1315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)TEST_F(SerialServiceTest, ConnectInvalidPath) {
1331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  RunConnectTest("invalid_path", false);
1345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
1355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)TEST_F(SerialServiceTest, ConnectOpenFailed) {
1371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  io_handler_ = new FailToOpenIoHandler;
1381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  RunConnectTest("device", false);
1395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
1405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
141116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}  // namespace device
142