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