1 // Copyright (c) 2017 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.
5 #include "services/device/serial/serial_port_manager_impl.h"
12 #include "base/macros.h"
13 #include "base/message_loop/message_loop.h"
14 #include "base/task/post_task.h"
15 #include "base/test/scoped_task_environment.h"
16 #include "base/threading/thread.h"
17 #include "mojo/public/cpp/bindings/interface_ptr.h"
18 #include "mojo/public/cpp/bindings/strong_binding.h"
19 #include "services/device/device_service_test_base.h"
20 #include "services/device/public/mojom/constants.mojom.h"
21 #include "services/device/public/mojom/serial.mojom.h"
22 #include "services/device/serial/fake_serial_device_enumerator.h"
23 #include "testing/gtest/include/gtest/gtest.h"
29 const base::FilePath kFakeDevicePath1(FILE_PATH_LITERAL("/dev/fakeserialmojo"));
30 const base::FilePath kFakeDevicePath2(FILE_PATH_LITERAL("\\\\COM800\\"));
32 void CreateAndBindOnBlockableRunner(
33 mojom::SerialPortManagerRequest request,
34 scoped_refptr<base::SingleThreadTaskRunner> io_task_runner,
35 scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner) {
36 auto manager = std::make_unique<SerialPortManagerImpl>(
37 std::move(io_task_runner), std::move(ui_task_runner));
38 auto fake_enumerator = std::make_unique<FakeSerialEnumerator>();
39 fake_enumerator->AddDevicePath(kFakeDevicePath1);
40 fake_enumerator->AddDevicePath(kFakeDevicePath2);
41 manager->SetSerialEnumeratorForTesting(std::move(fake_enumerator));
42 mojo::MakeStrongBinding(std::move(manager), std::move(request));
45 void ExpectDevicesAndThen(const std::set<base::FilePath>& expected_paths,
46 base::OnceClosure continuation,
47 std::vector<mojom::SerialPortInfoPtr> results) {
48 EXPECT_EQ(expected_paths.size(), results.size());
49 std::set<base::FilePath> actual_paths;
50 for (size_t i = 0; i < results.size(); ++i)
51 actual_paths.insert(results[i]->path);
52 EXPECT_EQ(expected_paths, actual_paths);
53 std::move(continuation).Run();
56 void OnGotDevicesAndGetPort(mojom::SerialPortManagerPtr port_manager,
57 base::OnceClosure continuation,
58 std::vector<mojom::SerialPortInfoPtr> results) {
59 EXPECT_GT(results.size(), 0u);
61 mojom::SerialPortPtr serial_port;
62 port_manager->GetPort(results[0]->token, mojo::MakeRequest(&serial_port));
63 // Send a message on the pipe and wait for the response to make sure that the
64 // interface request was bound successfully.
65 serial_port.FlushForTesting();
66 EXPECT_FALSE(serial_port.encountered_error());
67 std::move(continuation).Run();
70 void OnGotDevicesForSimpleConnect(
71 mojom::SerialPortManagerPtr port_manager,
72 base::OnceClosure continuation,
73 std::vector<mojom::SerialPortInfoPtr> results) {
74 for (auto& device : results) {
75 mojom::SerialPortPtr serial_port;
76 port_manager->GetPort(device->token, mojo::MakeRequest(&serial_port));
77 // Send a message on the pipe and wait for the response to make sure that
78 // the interface request was bound successfully.
79 serial_port.FlushForTesting();
80 EXPECT_FALSE(serial_port.encountered_error());
82 std::move(continuation).Run();
87 class SerialPortManagerImplTest : public DeviceServiceTestBase {
89 SerialPortManagerImplTest() {
90 blockable_runner_ = base::CreateSequencedTaskRunnerWithTraits(
91 {base::MayBlock(), base::TaskPriority::BEST_EFFORT});
93 ~SerialPortManagerImplTest() override = default;
96 void SetUp() override { DeviceServiceTestBase::SetUp(); }
98 void BindSerialPortManager(mojom::SerialPortManagerRequest request) {
99 blockable_runner_->PostTask(
100 FROM_HERE, base::BindOnce(&CreateAndBindOnBlockableRunner,
101 std::move(request), io_thread_.task_runner(),
102 base::ThreadTaskRunnerHandle::Get()));
105 scoped_refptr<base::SequencedTaskRunner> blockable_runner_;
107 DISALLOW_COPY_AND_ASSIGN(SerialPortManagerImplTest);
110 // This is to simply test that we can enumerate devices on the platform without
111 // hanging or crashing.
112 TEST_F(SerialPortManagerImplTest, SimpleConnectTest) {
113 mojom::SerialPortManagerPtr port_manager;
114 connector()->BindInterface(mojom::kServiceName, &port_manager);
117 auto* manager = port_manager.get();
118 manager->GetDevices(base::BindOnce(&OnGotDevicesForSimpleConnect,
119 std::move(port_manager),
120 loop.QuitClosure()));
124 TEST_F(SerialPortManagerImplTest, GetDevices) {
125 mojom::SerialPortManagerPtr port_manager;
126 BindSerialPortManager(mojo::MakeRequest(&port_manager));
127 std::set<base::FilePath> expected_paths = {kFakeDevicePath1,
131 port_manager->GetDevices(base::BindOnce(&ExpectDevicesAndThen, expected_paths,
132 loop.QuitClosure()));
136 TEST_F(SerialPortManagerImplTest, GetPort) {
137 mojom::SerialPortManagerPtr port_manager;
138 BindSerialPortManager(mojo::MakeRequest(&port_manager));
141 auto* manager = port_manager.get();
142 manager->GetDevices(base::BindOnce(
143 &OnGotDevicesAndGetPort, std::move(port_manager), loop.QuitClosure()));
147 } // namespace device