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 // A test launcher for tests for the serial API defined in
12 // extensions/test/data/serial_unittest.js. Each C++ test function sets up a
13 // fake DeviceEnumerator or SerialIoHandler expecting or returning particular
14 // values for that test.
16 namespace extensions {
20 class FakeSerialDeviceEnumerator : public device::SerialDeviceEnumerator {
21 virtual mojo::Array<device::serial::DeviceInfoPtr> GetDevices() OVERRIDE {
22 mojo::Array<device::serial::DeviceInfoPtr> result(3);
23 result[0] = device::serial::DeviceInfo::New();
24 result[0]->path = "device";
25 result[0]->vendor_id = 1234;
26 result[0]->has_vendor_id = true;
27 result[0]->product_id = 5678;
28 result[0]->has_product_id = true;
29 result[0]->display_name = "foo";
30 result[1] = device::serial::DeviceInfo::New();
31 result[1]->path = "another_device";
32 // These IDs should be ignored.
33 result[1]->vendor_id = 1234;
34 result[1]->product_id = 5678;
35 result[2] = device::serial::DeviceInfo::New();
37 result[2]->display_name = "";
48 device::serial::HostControlSignals GenerateControlSignals(OptionalValue dtr,
50 device::serial::HostControlSignals result;
52 case OPTIONAL_VALUE_UNSET:
54 case OPTIONAL_VALUE_FALSE:
56 result.has_dtr = true;
58 case OPTIONAL_VALUE_TRUE:
60 result.has_dtr = true;
64 case OPTIONAL_VALUE_UNSET:
66 case OPTIONAL_VALUE_FALSE:
68 result.has_rts = true;
70 case OPTIONAL_VALUE_TRUE:
72 result.has_rts = true;
78 device::serial::ConnectionOptions GenerateConnectionOptions(
80 device::serial::DataBits data_bits,
81 device::serial::ParityBit parity_bit,
82 device::serial::StopBits stop_bits,
83 OptionalValue cts_flow_control) {
84 device::serial::ConnectionOptions result;
85 result.bitrate = bitrate;
86 result.data_bits = data_bits;
87 result.parity_bit = parity_bit;
88 result.stop_bits = stop_bits;
89 switch (cts_flow_control) {
90 case OPTIONAL_VALUE_UNSET:
92 case OPTIONAL_VALUE_FALSE:
93 result.cts_flow_control = false;
94 result.has_cts_flow_control = true;
96 case OPTIONAL_VALUE_TRUE:
97 result.cts_flow_control = true;
98 result.has_cts_flow_control = true;
104 class TestIoHandlerBase : public device::TestSerialIoHandler {
106 TestIoHandlerBase() : calls_(0) {}
108 size_t num_calls() const { return calls_; }
111 virtual ~TestIoHandlerBase() {}
112 void record_call() const { calls_++; }
115 mutable size_t calls_;
117 DISALLOW_COPY_AND_ASSIGN(TestIoHandlerBase);
120 class SetControlSignalsTestIoHandler : public TestIoHandlerBase {
122 SetControlSignalsTestIoHandler() {}
124 virtual bool SetControlSignals(
125 const device::serial::HostControlSignals& signals) OVERRIDE {
126 static const device::serial::HostControlSignals expected_signals[] = {
127 GenerateControlSignals(OPTIONAL_VALUE_UNSET, OPTIONAL_VALUE_UNSET),
128 GenerateControlSignals(OPTIONAL_VALUE_FALSE, OPTIONAL_VALUE_UNSET),
129 GenerateControlSignals(OPTIONAL_VALUE_TRUE, OPTIONAL_VALUE_UNSET),
130 GenerateControlSignals(OPTIONAL_VALUE_UNSET, OPTIONAL_VALUE_FALSE),
131 GenerateControlSignals(OPTIONAL_VALUE_FALSE, OPTIONAL_VALUE_FALSE),
132 GenerateControlSignals(OPTIONAL_VALUE_TRUE, OPTIONAL_VALUE_FALSE),
133 GenerateControlSignals(OPTIONAL_VALUE_UNSET, OPTIONAL_VALUE_TRUE),
134 GenerateControlSignals(OPTIONAL_VALUE_FALSE, OPTIONAL_VALUE_TRUE),
135 GenerateControlSignals(OPTIONAL_VALUE_TRUE, OPTIONAL_VALUE_TRUE),
137 if (num_calls() >= arraysize(expected_signals))
140 EXPECT_EQ(expected_signals[num_calls()].has_dtr, signals.has_dtr);
141 EXPECT_EQ(expected_signals[num_calls()].dtr, signals.dtr);
142 EXPECT_EQ(expected_signals[num_calls()].has_rts, signals.has_rts);
143 EXPECT_EQ(expected_signals[num_calls()].rts, signals.rts);
149 virtual ~SetControlSignalsTestIoHandler() {}
151 DISALLOW_COPY_AND_ASSIGN(SetControlSignalsTestIoHandler);
154 class GetControlSignalsTestIoHandler : public TestIoHandlerBase {
156 GetControlSignalsTestIoHandler() {}
158 virtual device::serial::DeviceControlSignalsPtr GetControlSignals()
160 device::serial::DeviceControlSignalsPtr signals(
161 device::serial::DeviceControlSignals::New());
162 signals->dcd = num_calls() & 1;
163 signals->cts = num_calls() & 2;
164 signals->ri = num_calls() & 4;
165 signals->dsr = num_calls() & 8;
167 return signals.Pass();
171 virtual ~GetControlSignalsTestIoHandler() {}
173 DISALLOW_COPY_AND_ASSIGN(GetControlSignalsTestIoHandler);
176 class ConfigurePortTestIoHandler : public TestIoHandlerBase {
178 ConfigurePortTestIoHandler() {}
179 virtual bool ConfigurePort(
180 const device::serial::ConnectionOptions& options) OVERRIDE {
181 static const device::serial::ConnectionOptions expected_options[] = {
182 GenerateConnectionOptions(9600,
183 device::serial::DATA_BITS_EIGHT,
184 device::serial::PARITY_BIT_NO,
185 device::serial::STOP_BITS_ONE,
186 OPTIONAL_VALUE_FALSE),
187 GenerateConnectionOptions(57600,
188 device::serial::DATA_BITS_NONE,
189 device::serial::PARITY_BIT_NONE,
190 device::serial::STOP_BITS_NONE,
191 OPTIONAL_VALUE_UNSET),
192 GenerateConnectionOptions(0,
193 device::serial::DATA_BITS_SEVEN,
194 device::serial::PARITY_BIT_NONE,
195 device::serial::STOP_BITS_NONE,
196 OPTIONAL_VALUE_UNSET),
197 GenerateConnectionOptions(0,
198 device::serial::DATA_BITS_EIGHT,
199 device::serial::PARITY_BIT_NONE,
200 device::serial::STOP_BITS_NONE,
201 OPTIONAL_VALUE_UNSET),
202 GenerateConnectionOptions(0,
203 device::serial::DATA_BITS_NONE,
204 device::serial::PARITY_BIT_NO,
205 device::serial::STOP_BITS_NONE,
206 OPTIONAL_VALUE_UNSET),
207 GenerateConnectionOptions(0,
208 device::serial::DATA_BITS_NONE,
209 device::serial::PARITY_BIT_ODD,
210 device::serial::STOP_BITS_NONE,
211 OPTIONAL_VALUE_UNSET),
212 GenerateConnectionOptions(0,
213 device::serial::DATA_BITS_NONE,
214 device::serial::PARITY_BIT_EVEN,
215 device::serial::STOP_BITS_NONE,
216 OPTIONAL_VALUE_UNSET),
217 GenerateConnectionOptions(0,
218 device::serial::DATA_BITS_NONE,
219 device::serial::PARITY_BIT_NONE,
220 device::serial::STOP_BITS_ONE,
221 OPTIONAL_VALUE_UNSET),
222 GenerateConnectionOptions(0,
223 device::serial::DATA_BITS_NONE,
224 device::serial::PARITY_BIT_NONE,
225 device::serial::STOP_BITS_TWO,
226 OPTIONAL_VALUE_UNSET),
227 GenerateConnectionOptions(0,
228 device::serial::DATA_BITS_NONE,
229 device::serial::PARITY_BIT_NONE,
230 device::serial::STOP_BITS_NONE,
231 OPTIONAL_VALUE_FALSE),
232 GenerateConnectionOptions(0,
233 device::serial::DATA_BITS_NONE,
234 device::serial::PARITY_BIT_NONE,
235 device::serial::STOP_BITS_NONE,
236 OPTIONAL_VALUE_TRUE),
238 if (num_calls() >= arraysize(expected_options))
241 EXPECT_EQ(expected_options[num_calls()].bitrate, options.bitrate);
242 EXPECT_EQ(expected_options[num_calls()].data_bits, options.data_bits);
243 EXPECT_EQ(expected_options[num_calls()].parity_bit, options.parity_bit);
244 EXPECT_EQ(expected_options[num_calls()].stop_bits, options.stop_bits);
245 EXPECT_EQ(expected_options[num_calls()].has_cts_flow_control,
246 options.has_cts_flow_control);
247 EXPECT_EQ(expected_options[num_calls()].cts_flow_control,
248 options.cts_flow_control);
250 return TestSerialIoHandler::ConfigurePort(options);
254 virtual ~ConfigurePortTestIoHandler() {}
256 DISALLOW_COPY_AND_ASSIGN(ConfigurePortTestIoHandler);
259 class FlushTestIoHandler : public TestIoHandlerBase {
261 FlushTestIoHandler() {}
263 virtual bool Flush() const OVERRIDE {
269 virtual ~FlushTestIoHandler() {}
271 DISALLOW_COPY_AND_ASSIGN(FlushTestIoHandler);
274 class FailToConnectTestIoHandler : public TestIoHandlerBase {
276 FailToConnectTestIoHandler() {}
277 virtual void Open(const std::string& port,
278 const OpenCompleteCallback& callback) OVERRIDE {
284 virtual ~FailToConnectTestIoHandler() {}
286 DISALLOW_COPY_AND_ASSIGN(FailToConnectTestIoHandler);
289 class FailToGetInfoTestIoHandler : public TestIoHandlerBase {
291 explicit FailToGetInfoTestIoHandler(int times_to_succeed)
292 : times_to_succeed_(times_to_succeed) {}
293 virtual device::serial::ConnectionInfoPtr GetPortInfo() const OVERRIDE {
294 if (times_to_succeed_-- > 0)
295 return device::TestSerialIoHandler::GetPortInfo();
296 return device::serial::ConnectionInfoPtr();
300 virtual ~FailToGetInfoTestIoHandler() {}
302 mutable int times_to_succeed_;
304 DISALLOW_COPY_AND_ASSIGN(FailToGetInfoTestIoHandler);
307 class SendErrorTestIoHandler : public TestIoHandlerBase {
309 explicit SendErrorTestIoHandler(device::serial::SendError error)
312 virtual void WriteImpl() OVERRIDE { QueueWriteCompleted(0, error_); }
315 virtual ~SendErrorTestIoHandler() {}
317 device::serial::SendError error_;
319 DISALLOW_COPY_AND_ASSIGN(SendErrorTestIoHandler);
322 class FixedDataReceiveTestIoHandler : public TestIoHandlerBase {
324 explicit FixedDataReceiveTestIoHandler(const std::string& data)
327 virtual void ReadImpl() OVERRIDE {
328 if (pending_read_buffer_len() < data_.size())
330 memcpy(pending_read_buffer(), data_.c_str(), data_.size());
331 QueueReadCompleted(static_cast<uint32_t>(data_.size()),
332 device::serial::RECEIVE_ERROR_NONE);
336 virtual ~FixedDataReceiveTestIoHandler() {}
338 const std::string data_;
340 DISALLOW_COPY_AND_ASSIGN(FixedDataReceiveTestIoHandler);
343 class ReceiveErrorTestIoHandler : public TestIoHandlerBase {
345 explicit ReceiveErrorTestIoHandler(device::serial::ReceiveError error)
348 virtual void ReadImpl() OVERRIDE { QueueReadCompleted(0, error_); }
351 virtual ~ReceiveErrorTestIoHandler() {}
353 device::serial::ReceiveError error_;
355 DISALLOW_COPY_AND_ASSIGN(ReceiveErrorTestIoHandler);
358 class SendDataWithErrorIoHandler : public TestIoHandlerBase {
360 SendDataWithErrorIoHandler() : sent_error_(false) {}
361 virtual void WriteImpl() OVERRIDE {
363 WriteCompleted(pending_write_buffer_len(),
364 device::serial::SEND_ERROR_NONE);
368 // We expect the JS test code to send a 4 byte buffer.
369 ASSERT_LT(2u, pending_write_buffer_len());
370 WriteCompleted(2, device::serial::SEND_ERROR_SYSTEM_ERROR);
374 virtual ~SendDataWithErrorIoHandler() {}
378 DISALLOW_COPY_AND_ASSIGN(SendDataWithErrorIoHandler);
381 class BlockSendsForeverSendIoHandler : public TestIoHandlerBase {
383 BlockSendsForeverSendIoHandler() {}
384 virtual void WriteImpl() OVERRIDE {}
387 virtual ~BlockSendsForeverSendIoHandler() {}
389 DISALLOW_COPY_AND_ASSIGN(BlockSendsForeverSendIoHandler);
394 class SerialApiTest : public ApiTestBase {
398 virtual void SetUp() OVERRIDE {
399 ApiTestBase::SetUp();
400 env()->RegisterModule("async_waiter", IDR_ASYNC_WAITER_JS);
401 env()->RegisterModule("data_receiver", IDR_DATA_RECEIVER_JS);
402 env()->RegisterModule("data_sender", IDR_DATA_SENDER_JS);
403 env()->RegisterModule("serial", IDR_SERIAL_CUSTOM_BINDINGS_JS);
404 env()->RegisterModule("serial_service", IDR_SERIAL_SERVICE_JS);
405 env()->RegisterModule("device/serial/data_stream.mojom",
406 IDR_DATA_STREAM_MOJOM_JS);
407 env()->RegisterModule("device/serial/data_stream_serialization.mojom",
408 IDR_DATA_STREAM_SERIALIZATION_MOJOM_JS);
409 env()->RegisterModule("device/serial/serial.mojom", IDR_SERIAL_MOJOM_JS);
410 service_provider()->AddService<device::serial::SerialService>(base::Bind(
411 &SerialApiTest::CreateSerialService, base::Unretained(this)));
414 scoped_refptr<TestIoHandlerBase> io_handler_;
417 scoped_refptr<device::SerialIoHandler> GetIoHandler() {
418 if (!io_handler_.get())
419 io_handler_ = new TestIoHandlerBase;
423 void CreateSerialService(
424 mojo::InterfaceRequest<device::serial::SerialService> request) {
425 mojo::BindToRequest(new device::SerialServiceImpl(
426 new device::SerialConnectionFactory(
427 base::Bind(&SerialApiTest::GetIoHandler,
428 base::Unretained(this)),
429 base::MessageLoopProxy::current()),
430 scoped_ptr<device::SerialDeviceEnumerator>(
431 new FakeSerialDeviceEnumerator)),
435 DISALLOW_COPY_AND_ASSIGN(SerialApiTest);
438 TEST_F(SerialApiTest, GetDevices) {
439 RunTest("serial_unittest.js", "testGetDevices");
442 TEST_F(SerialApiTest, ConnectFail) {
443 io_handler_ = new FailToConnectTestIoHandler;
444 RunTest("serial_unittest.js", "testConnectFail");
447 TEST_F(SerialApiTest, GetInfoFailOnConnect) {
448 io_handler_ = new FailToGetInfoTestIoHandler(0);
449 RunTest("serial_unittest.js", "testGetInfoFailOnConnect");
452 TEST_F(SerialApiTest, Connect) {
453 RunTest("serial_unittest.js", "testConnect");
456 TEST_F(SerialApiTest, ConnectDefaultOptions) {
457 RunTest("serial_unittest.js", "testConnectDefaultOptions");
460 TEST_F(SerialApiTest, ConnectInvalidBitrate) {
461 RunTest("serial_unittest.js", "testConnectInvalidBitrate");
464 TEST_F(SerialApiTest, GetInfo) {
465 RunTest("serial_unittest.js", "testGetInfo");
468 TEST_F(SerialApiTest, GetInfoFailToGetPortInfo) {
469 io_handler_ = new FailToGetInfoTestIoHandler(1);
470 RunTest("serial_unittest.js", "testGetInfoFailToGetPortInfo");
473 TEST_F(SerialApiTest, GetConnections) {
474 RunTest("serial_unittest.js", "testGetConnections");
477 TEST_F(SerialApiTest, GetControlSignals) {
478 io_handler_ = new GetControlSignalsTestIoHandler;
479 RunTest("serial_unittest.js", "testGetControlSignals");
480 EXPECT_EQ(16u, io_handler_->num_calls());
483 TEST_F(SerialApiTest, SetControlSignals) {
484 io_handler_ = new SetControlSignalsTestIoHandler;
485 RunTest("serial_unittest.js", "testSetControlSignals");
486 EXPECT_EQ(9u, io_handler_->num_calls());
489 TEST_F(SerialApiTest, Update) {
490 io_handler_ = new ConfigurePortTestIoHandler;
491 RunTest("serial_unittest.js", "testUpdate");
492 EXPECT_EQ(11u, io_handler_->num_calls());
495 TEST_F(SerialApiTest, UpdateInvalidBitrate) {
496 io_handler_ = new ConfigurePortTestIoHandler;
497 RunTest("serial_unittest.js", "testUpdateInvalidBitrate");
498 EXPECT_EQ(1u, io_handler_->num_calls());
501 TEST_F(SerialApiTest, Flush) {
502 io_handler_ = new FlushTestIoHandler;
503 RunTest("serial_unittest.js", "testFlush");
504 EXPECT_EQ(1u, io_handler_->num_calls());
507 TEST_F(SerialApiTest, SetPaused) {
508 RunTest("serial_unittest.js", "testSetPaused");
511 TEST_F(SerialApiTest, Echo) {
512 RunTest("serial_unittest.js", "testEcho");
515 TEST_F(SerialApiTest, SendDuringExistingSend) {
516 RunTest("serial_unittest.js", "testSendDuringExistingSend");
519 TEST_F(SerialApiTest, SendAfterSuccessfulSend) {
520 RunTest("serial_unittest.js", "testSendAfterSuccessfulSend");
523 TEST_F(SerialApiTest, SendPartialSuccessWithError) {
524 io_handler_ = new SendDataWithErrorIoHandler();
525 RunTest("serial_unittest.js", "testSendPartialSuccessWithError");
528 TEST_F(SerialApiTest, SendTimeout) {
529 io_handler_ = new BlockSendsForeverSendIoHandler();
530 RunTest("serial_unittest.js", "testSendTimeout");
533 TEST_F(SerialApiTest, DisableSendTimeout) {
534 io_handler_ = new BlockSendsForeverSendIoHandler();
535 RunTest("serial_unittest.js", "testDisableSendTimeout");
538 TEST_F(SerialApiTest, PausedReceive) {
539 io_handler_ = new FixedDataReceiveTestIoHandler("data");
540 RunTest("serial_unittest.js", "testPausedReceive");
543 TEST_F(SerialApiTest, PausedReceiveError) {
545 new ReceiveErrorTestIoHandler(device::serial::RECEIVE_ERROR_DEVICE_LOST);
546 RunTest("serial_unittest.js", "testPausedReceiveError");
549 TEST_F(SerialApiTest, ReceiveTimeout) {
550 RunTest("serial_unittest.js", "testReceiveTimeout");
553 TEST_F(SerialApiTest, DisableReceiveTimeout) {
554 RunTest("serial_unittest.js", "testDisableReceiveTimeout");
557 TEST_F(SerialApiTest, ReceiveErrorDisconnected) {
559 new ReceiveErrorTestIoHandler(device::serial::RECEIVE_ERROR_DISCONNECTED);
560 RunTest("serial_unittest.js", "testReceiveErrorDisconnected");
563 TEST_F(SerialApiTest, ReceiveErrorDeviceLost) {
565 new ReceiveErrorTestIoHandler(device::serial::RECEIVE_ERROR_DEVICE_LOST);
566 RunTest("serial_unittest.js", "testReceiveErrorDeviceLost");
569 TEST_F(SerialApiTest, ReceiveErrorSystemError) {
571 new ReceiveErrorTestIoHandler(device::serial::RECEIVE_ERROR_SYSTEM_ERROR);
572 RunTest("serial_unittest.js", "testReceiveErrorSystemError");
575 TEST_F(SerialApiTest, SendErrorDisconnected) {
577 new SendErrorTestIoHandler(device::serial::SEND_ERROR_DISCONNECTED);
578 RunTest("serial_unittest.js", "testSendErrorDisconnected");
581 TEST_F(SerialApiTest, SendErrorSystemError) {
583 new SendErrorTestIoHandler(device::serial::SEND_ERROR_SYSTEM_ERROR);
584 RunTest("serial_unittest.js", "testSendErrorSystemError");
587 TEST_F(SerialApiTest, DisconnectUnknownConnectionId) {
588 RunTest("serial_unittest.js", "testDisconnectUnknownConnectionId");
591 TEST_F(SerialApiTest, GetInfoUnknownConnectionId) {
592 RunTest("serial_unittest.js", "testGetInfoUnknownConnectionId");
595 TEST_F(SerialApiTest, UpdateUnknownConnectionId) {
596 RunTest("serial_unittest.js", "testUpdateUnknownConnectionId");
599 TEST_F(SerialApiTest, SetControlSignalsUnknownConnectionId) {
600 RunTest("serial_unittest.js", "testSetControlSignalsUnknownConnectionId");
603 TEST_F(SerialApiTest, GetControlSignalsUnknownConnectionId) {
604 RunTest("serial_unittest.js", "testGetControlSignalsUnknownConnectionId");
607 TEST_F(SerialApiTest, FlushUnknownConnectionId) {
608 RunTest("serial_unittest.js", "testFlushUnknownConnectionId");
611 TEST_F(SerialApiTest, SetPausedUnknownConnectionId) {
612 RunTest("serial_unittest.js", "testSetPausedUnknownConnectionId");
615 TEST_F(SerialApiTest, SendUnknownConnectionId) {
616 RunTest("serial_unittest.js", "testSendUnknownConnectionId");
619 } // namespace extensions