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.
5 #include "device/serial/serial_device_enumerator.h"
6 #include "device/serial/serial_service_impl.h"
7 #include "device/serial/test_serial_io_handler.h"
8 #include "extensions/renderer/api_test_base.h"
9 #include "grit/extensions_renderer_resources.h"
11 namespace extensions
{
15 class FakeSerialDeviceEnumerator
: public device::SerialDeviceEnumerator
{
16 virtual mojo::Array
<device::serial::DeviceInfoPtr
> GetDevices() OVERRIDE
{
17 mojo::Array
<device::serial::DeviceInfoPtr
> result(3);
18 result
[0] = device::serial::DeviceInfo::New();
19 result
[0]->path
= "device";
20 result
[0]->vendor_id
= 1234;
21 result
[0]->has_vendor_id
= true;
22 result
[0]->product_id
= 5678;
23 result
[0]->has_product_id
= true;
24 result
[0]->display_name
= "foo";
25 result
[1] = device::serial::DeviceInfo::New();
26 result
[1]->path
= "another_device";
27 // These IDs should be ignored.
28 result
[1]->vendor_id
= 1234;
29 result
[1]->product_id
= 5678;
30 result
[2] = device::serial::DeviceInfo::New();
31 result
[2]->display_name
= "";
42 device::serial::HostControlSignals
GenerateControlSignals(OptionalValue dtr
,
44 device::serial::HostControlSignals result
;
46 case OPTIONAL_VALUE_UNSET
:
48 case OPTIONAL_VALUE_FALSE
:
50 result
.has_dtr
= true;
52 case OPTIONAL_VALUE_TRUE
:
54 result
.has_dtr
= true;
58 case OPTIONAL_VALUE_UNSET
:
60 case OPTIONAL_VALUE_FALSE
:
62 result
.has_rts
= true;
64 case OPTIONAL_VALUE_TRUE
:
66 result
.has_rts
= true;
72 device::serial::ConnectionOptions
GenerateConnectionOptions(
74 device::serial::DataBits data_bits
,
75 device::serial::ParityBit parity_bit
,
76 device::serial::StopBits stop_bits
,
77 OptionalValue cts_flow_control
) {
78 device::serial::ConnectionOptions result
;
79 result
.bitrate
= bitrate
;
80 result
.data_bits
= data_bits
;
81 result
.parity_bit
= parity_bit
;
82 result
.stop_bits
= stop_bits
;
83 switch (cts_flow_control
) {
84 case OPTIONAL_VALUE_UNSET
:
86 case OPTIONAL_VALUE_FALSE
:
87 result
.cts_flow_control
= false;
88 result
.has_cts_flow_control
= true;
90 case OPTIONAL_VALUE_TRUE
:
91 result
.cts_flow_control
= true;
92 result
.has_cts_flow_control
= true;
98 class TestIoHandlerBase
: public device::TestSerialIoHandler
{
100 TestIoHandlerBase() : calls_(0) {}
102 size_t num_calls() const { return calls_
; }
105 virtual ~TestIoHandlerBase() {}
106 void record_call() const { calls_
++; }
109 mutable size_t calls_
;
111 DISALLOW_COPY_AND_ASSIGN(TestIoHandlerBase
);
114 class SetControlSignalsTestIoHandler
: public TestIoHandlerBase
{
116 SetControlSignalsTestIoHandler() {}
118 virtual bool SetControlSignals(
119 const device::serial::HostControlSignals
& signals
) OVERRIDE
{
120 static const device::serial::HostControlSignals expected_signals
[] = {
121 GenerateControlSignals(OPTIONAL_VALUE_UNSET
, OPTIONAL_VALUE_UNSET
),
122 GenerateControlSignals(OPTIONAL_VALUE_FALSE
, OPTIONAL_VALUE_UNSET
),
123 GenerateControlSignals(OPTIONAL_VALUE_TRUE
, OPTIONAL_VALUE_UNSET
),
124 GenerateControlSignals(OPTIONAL_VALUE_UNSET
, OPTIONAL_VALUE_FALSE
),
125 GenerateControlSignals(OPTIONAL_VALUE_FALSE
, OPTIONAL_VALUE_FALSE
),
126 GenerateControlSignals(OPTIONAL_VALUE_TRUE
, OPTIONAL_VALUE_FALSE
),
127 GenerateControlSignals(OPTIONAL_VALUE_UNSET
, OPTIONAL_VALUE_TRUE
),
128 GenerateControlSignals(OPTIONAL_VALUE_FALSE
, OPTIONAL_VALUE_TRUE
),
129 GenerateControlSignals(OPTIONAL_VALUE_TRUE
, OPTIONAL_VALUE_TRUE
),
131 if (num_calls() >= arraysize(expected_signals
))
134 EXPECT_EQ(expected_signals
[num_calls()].has_dtr
, signals
.has_dtr
);
135 EXPECT_EQ(expected_signals
[num_calls()].dtr
, signals
.dtr
);
136 EXPECT_EQ(expected_signals
[num_calls()].has_rts
, signals
.has_rts
);
137 EXPECT_EQ(expected_signals
[num_calls()].rts
, signals
.rts
);
143 virtual ~SetControlSignalsTestIoHandler() {}
145 DISALLOW_COPY_AND_ASSIGN(SetControlSignalsTestIoHandler
);
148 class GetControlSignalsTestIoHandler
: public TestIoHandlerBase
{
150 GetControlSignalsTestIoHandler() {}
152 virtual device::serial::DeviceControlSignalsPtr
GetControlSignals()
154 device::serial::DeviceControlSignalsPtr
signals(
155 device::serial::DeviceControlSignals::New());
156 signals
->dcd
= num_calls() & 1;
157 signals
->cts
= num_calls() & 2;
158 signals
->ri
= num_calls() & 4;
159 signals
->dsr
= num_calls() & 8;
161 return signals
.Pass();
165 virtual ~GetControlSignalsTestIoHandler() {}
167 DISALLOW_COPY_AND_ASSIGN(GetControlSignalsTestIoHandler
);
170 class ConfigurePortTestIoHandler
: public TestIoHandlerBase
{
172 ConfigurePortTestIoHandler() {}
173 virtual bool ConfigurePort(
174 const device::serial::ConnectionOptions
& options
) OVERRIDE
{
175 static const device::serial::ConnectionOptions expected_options
[] = {
176 GenerateConnectionOptions(9600,
177 device::serial::DATA_BITS_EIGHT
,
178 device::serial::PARITY_BIT_NO
,
179 device::serial::STOP_BITS_ONE
,
180 OPTIONAL_VALUE_FALSE
),
181 GenerateConnectionOptions(57600,
182 device::serial::DATA_BITS_NONE
,
183 device::serial::PARITY_BIT_NONE
,
184 device::serial::STOP_BITS_NONE
,
185 OPTIONAL_VALUE_UNSET
),
186 GenerateConnectionOptions(0,
187 device::serial::DATA_BITS_SEVEN
,
188 device::serial::PARITY_BIT_NONE
,
189 device::serial::STOP_BITS_NONE
,
190 OPTIONAL_VALUE_UNSET
),
191 GenerateConnectionOptions(0,
192 device::serial::DATA_BITS_EIGHT
,
193 device::serial::PARITY_BIT_NONE
,
194 device::serial::STOP_BITS_NONE
,
195 OPTIONAL_VALUE_UNSET
),
196 GenerateConnectionOptions(0,
197 device::serial::DATA_BITS_NONE
,
198 device::serial::PARITY_BIT_NO
,
199 device::serial::STOP_BITS_NONE
,
200 OPTIONAL_VALUE_UNSET
),
201 GenerateConnectionOptions(0,
202 device::serial::DATA_BITS_NONE
,
203 device::serial::PARITY_BIT_ODD
,
204 device::serial::STOP_BITS_NONE
,
205 OPTIONAL_VALUE_UNSET
),
206 GenerateConnectionOptions(0,
207 device::serial::DATA_BITS_NONE
,
208 device::serial::PARITY_BIT_EVEN
,
209 device::serial::STOP_BITS_NONE
,
210 OPTIONAL_VALUE_UNSET
),
211 GenerateConnectionOptions(0,
212 device::serial::DATA_BITS_NONE
,
213 device::serial::PARITY_BIT_NONE
,
214 device::serial::STOP_BITS_ONE
,
215 OPTIONAL_VALUE_UNSET
),
216 GenerateConnectionOptions(0,
217 device::serial::DATA_BITS_NONE
,
218 device::serial::PARITY_BIT_NONE
,
219 device::serial::STOP_BITS_TWO
,
220 OPTIONAL_VALUE_UNSET
),
221 GenerateConnectionOptions(0,
222 device::serial::DATA_BITS_NONE
,
223 device::serial::PARITY_BIT_NONE
,
224 device::serial::STOP_BITS_NONE
,
225 OPTIONAL_VALUE_FALSE
),
226 GenerateConnectionOptions(0,
227 device::serial::DATA_BITS_NONE
,
228 device::serial::PARITY_BIT_NONE
,
229 device::serial::STOP_BITS_NONE
,
230 OPTIONAL_VALUE_TRUE
),
232 if (num_calls() >= arraysize(expected_options
))
235 EXPECT_EQ(expected_options
[num_calls()].bitrate
, options
.bitrate
);
236 EXPECT_EQ(expected_options
[num_calls()].data_bits
, options
.data_bits
);
237 EXPECT_EQ(expected_options
[num_calls()].parity_bit
, options
.parity_bit
);
238 EXPECT_EQ(expected_options
[num_calls()].stop_bits
, options
.stop_bits
);
239 EXPECT_EQ(expected_options
[num_calls()].has_cts_flow_control
,
240 options
.has_cts_flow_control
);
241 EXPECT_EQ(expected_options
[num_calls()].cts_flow_control
,
242 options
.cts_flow_control
);
244 return TestSerialIoHandler::ConfigurePort(options
);
248 virtual ~ConfigurePortTestIoHandler() {}
250 DISALLOW_COPY_AND_ASSIGN(ConfigurePortTestIoHandler
);
253 class FlushTestIoHandler
: public TestIoHandlerBase
{
255 FlushTestIoHandler() {}
257 virtual bool Flush() const OVERRIDE
{
263 virtual ~FlushTestIoHandler() {}
265 DISALLOW_COPY_AND_ASSIGN(FlushTestIoHandler
);
268 class FailToConnectTestIoHandler
: public TestIoHandlerBase
{
270 FailToConnectTestIoHandler() {}
271 virtual void Open(const std::string
& port
,
272 const OpenCompleteCallback
& callback
) OVERRIDE
{
278 virtual ~FailToConnectTestIoHandler() {}
280 DISALLOW_COPY_AND_ASSIGN(FailToConnectTestIoHandler
);
283 class FailToGetInfoTestIoHandler
: public TestIoHandlerBase
{
285 explicit FailToGetInfoTestIoHandler(int times_to_succeed
)
286 : times_to_succeed_(times_to_succeed
) {}
287 virtual device::serial::ConnectionInfoPtr
GetPortInfo() const OVERRIDE
{
288 if (times_to_succeed_
-- > 0)
289 return device::TestSerialIoHandler::GetPortInfo();
290 return device::serial::ConnectionInfoPtr();
294 virtual ~FailToGetInfoTestIoHandler() {}
296 mutable int times_to_succeed_
;
298 DISALLOW_COPY_AND_ASSIGN(FailToGetInfoTestIoHandler
);
303 class SerialApiTest
: public ApiTestBase
{
307 virtual void SetUp() OVERRIDE
{
308 ApiTestBase::SetUp();
309 env()->RegisterModule("serial", IDR_SERIAL_CUSTOM_BINDINGS_JS
);
310 env()->RegisterModule("serial_service", IDR_SERIAL_SERVICE_JS
);
311 env()->RegisterModule("device/serial/data_stream.mojom",
312 IDR_DATA_STREAM_MOJOM_JS
);
313 env()->RegisterModule("device/serial/serial.mojom", IDR_SERIAL_MOJOM_JS
);
314 service_provider()->AddService
<device::serial::SerialService
>(base::Bind(
315 &SerialApiTest::CreateSerialService
, base::Unretained(this)));
318 virtual void TearDown() OVERRIDE
{
319 if (io_handler_
.get())
320 EXPECT_TRUE(io_handler_
->HasOneRef());
321 ApiTestBase::TearDown();
324 scoped_refptr
<TestIoHandlerBase
> io_handler_
;
327 scoped_refptr
<device::SerialIoHandler
> GetIoHandler() {
328 if (!io_handler_
.get())
329 io_handler_
= new TestIoHandlerBase
;
333 void CreateSerialService(
334 mojo::InterfaceRequest
<device::serial::SerialService
> request
) {
335 mojo::BindToRequest(new device::SerialServiceImpl(
336 new device::SerialConnectionFactory(
337 base::Bind(&SerialApiTest::GetIoHandler
,
338 base::Unretained(this)),
339 base::MessageLoopProxy::current()),
340 scoped_ptr
<device::SerialDeviceEnumerator
>(
341 new FakeSerialDeviceEnumerator
)),
345 DISALLOW_COPY_AND_ASSIGN(SerialApiTest
);
348 TEST_F(SerialApiTest
, GetDevices
) {
349 RunTest("serial_unittest.js", "testGetDevices");
352 TEST_F(SerialApiTest
, ConnectFail
) {
353 io_handler_
= new FailToConnectTestIoHandler
;
354 RunTest("serial_unittest.js", "testConnectFail");
357 TEST_F(SerialApiTest
, GetInfoFailOnConnect
) {
358 io_handler_
= new FailToGetInfoTestIoHandler(0);
359 RunTest("serial_unittest.js", "testGetInfoFailOnConnect");
362 TEST_F(SerialApiTest
, Connect
) {
363 RunTest("serial_unittest.js", "testConnect");
366 TEST_F(SerialApiTest
, ConnectDefaultOptions
) {
367 RunTest("serial_unittest.js", "testConnectDefaultOptions");
370 TEST_F(SerialApiTest
, ConnectInvalidBitrate
) {
371 RunTest("serial_unittest.js", "testConnectInvalidBitrate");
374 TEST_F(SerialApiTest
, GetInfo
) {
375 RunTest("serial_unittest.js", "testGetInfo");
378 TEST_F(SerialApiTest
, GetInfoFailToGetPortInfo
) {
379 io_handler_
= new FailToGetInfoTestIoHandler(1);
380 RunTest("serial_unittest.js", "testGetInfoFailToGetPortInfo");
383 TEST_F(SerialApiTest
, GetConnections
) {
384 RunTest("serial_unittest.js", "testGetConnections");
387 TEST_F(SerialApiTest
, GetControlSignals
) {
388 io_handler_
= new GetControlSignalsTestIoHandler
;
389 RunTest("serial_unittest.js", "testGetControlSignals");
390 EXPECT_EQ(16u, io_handler_
->num_calls());
393 TEST_F(SerialApiTest
, SetControlSignals
) {
394 io_handler_
= new SetControlSignalsTestIoHandler
;
395 RunTest("serial_unittest.js", "testSetControlSignals");
396 EXPECT_EQ(9u, io_handler_
->num_calls());
399 TEST_F(SerialApiTest
, Update
) {
400 io_handler_
= new ConfigurePortTestIoHandler
;
401 RunTest("serial_unittest.js", "testUpdate");
402 EXPECT_EQ(11u, io_handler_
->num_calls());
405 TEST_F(SerialApiTest
, UpdateInvalidBitrate
) {
406 io_handler_
= new ConfigurePortTestIoHandler
;
407 RunTest("serial_unittest.js", "testUpdateInvalidBitrate");
408 EXPECT_EQ(1u, io_handler_
->num_calls());
411 TEST_F(SerialApiTest
, Flush
) {
412 io_handler_
= new FlushTestIoHandler
;
413 RunTest("serial_unittest.js", "testFlush");
414 EXPECT_EQ(1u, io_handler_
->num_calls());
417 TEST_F(SerialApiTest
, SetPaused
) {
418 RunTest("serial_unittest.js", "testSetPaused");
421 TEST_F(SerialApiTest
, DisconnectUnknownConnectionId
) {
422 RunTest("serial_unittest.js", "testDisconnectUnknownConnectionId");
425 TEST_F(SerialApiTest
, GetInfoUnknownConnectionId
) {
426 RunTest("serial_unittest.js", "testGetInfoUnknownConnectionId");
429 TEST_F(SerialApiTest
, UpdateUnknownConnectionId
) {
430 RunTest("serial_unittest.js", "testUpdateUnknownConnectionId");
433 TEST_F(SerialApiTest
, SetControlSignalsUnknownConnectionId
) {
434 RunTest("serial_unittest.js", "testSetControlSignalsUnknownConnectionId");
437 TEST_F(SerialApiTest
, GetControlSignalsUnknownConnectionId
) {
438 RunTest("serial_unittest.js", "testGetControlSignalsUnknownConnectionId");
441 TEST_F(SerialApiTest
, FlushUnknownConnectionId
) {
442 RunTest("serial_unittest.js", "testFlushUnknownConnectionId");
445 TEST_F(SerialApiTest
, SetPausedUnknownConnectionId
) {
446 RunTest("serial_unittest.js", "testSetPausedUnknownConnectionId");
449 } // namespace extensions