Home | History | Annotate | Download | only in serial
      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.
      4 
      5 #include <string>
      6 
      7 #include "chrome/browser/extensions/extension_apitest.h"
      8 #include "device/serial/test_serial_io_handler.h"
      9 #include "extensions/browser/api/serial/serial_api.h"
     10 #include "extensions/browser/api/serial/serial_connection.h"
     11 #include "extensions/browser/extension_function.h"
     12 #include "extensions/common/api/serial.h"
     13 #include "extensions/test/result_catcher.h"
     14 #include "testing/gmock/include/gmock/gmock.h"
     15 
     16 using testing::_;
     17 using testing::Return;
     18 
     19 namespace {
     20 
     21 class SerialApiTest : public ExtensionApiTest {
     22  public:
     23   SerialApiTest() {}
     24 };
     25 
     26 }  // namespace
     27 
     28 namespace extensions {
     29 
     30 class FakeSerialGetDevicesFunction : public AsyncExtensionFunction {
     31  public:
     32   virtual bool RunAsync() OVERRIDE {
     33     base::ListValue* devices = new base::ListValue();
     34     base::DictionaryValue* device0 = new base::DictionaryValue();
     35     device0->SetString("path", "/dev/fakeserial");
     36     base::DictionaryValue* device1 = new base::DictionaryValue();
     37     device1->SetString("path", "\\\\COM800\\");
     38     devices->Append(device0);
     39     devices->Append(device1);
     40     SetResult(devices);
     41     SendResponse(true);
     42     return true;
     43   }
     44 
     45  protected:
     46   virtual ~FakeSerialGetDevicesFunction() {}
     47 };
     48 
     49 class FakeEchoSerialIoHandler : public device::TestSerialIoHandler {
     50  public:
     51   explicit FakeEchoSerialIoHandler() {
     52     device_control_signals()->dcd = true;
     53     device_control_signals()->cts = true;
     54     device_control_signals()->ri = true;
     55     device_control_signals()->dsr = true;
     56   }
     57 
     58   MOCK_METHOD1(SetControlSignals,
     59                bool(const device::serial::HostControlSignals&));
     60 
     61  protected:
     62   virtual ~FakeEchoSerialIoHandler() {}
     63 
     64  private:
     65   DISALLOW_COPY_AND_ASSIGN(FakeEchoSerialIoHandler);
     66 };
     67 
     68 class FakeSerialConnectFunction : public core_api::SerialConnectFunction {
     69  protected:
     70   virtual SerialConnection* CreateSerialConnection(
     71       const std::string& port,
     72       const std::string& owner_extension_id) const OVERRIDE {
     73     scoped_refptr<FakeEchoSerialIoHandler> io_handler =
     74         new FakeEchoSerialIoHandler;
     75     EXPECT_CALL(*io_handler.get(), SetControlSignals(_)).Times(1).WillOnce(
     76         Return(true));
     77     SerialConnection* serial_connection =
     78         new SerialConnection(port, owner_extension_id);
     79     serial_connection->SetIoHandlerForTest(io_handler);
     80     return serial_connection;
     81   }
     82 
     83  protected:
     84   virtual ~FakeSerialConnectFunction() {}
     85 };
     86 
     87 }  // namespace extensions
     88 
     89 ExtensionFunction* FakeSerialGetDevicesFunctionFactory() {
     90   return new extensions::FakeSerialGetDevicesFunction();
     91 }
     92 
     93 ExtensionFunction* FakeSerialConnectFunctionFactory() {
     94   return new extensions::FakeSerialConnectFunction();
     95 }
     96 
     97 // Disable SIMULATE_SERIAL_PORTS only if all the following are true:
     98 //
     99 // 1. You have an Arduino or compatible board attached to your machine and
    100 // properly appearing as the first virtual serial port ("first" is very loosely
    101 // defined as whichever port shows up in serial.getPorts). We've tested only
    102 // the Atmega32u4 Breakout Board and Arduino Leonardo; note that both these
    103 // boards are based on the Atmel ATmega32u4, rather than the more common
    104 // Arduino '328p with either FTDI or '8/16u2 USB interfaces. TODO: test more
    105 // widely.
    106 //
    107 // 2. Your user has permission to read/write the port. For example, this might
    108 // mean that your user is in the "tty" or "uucp" group on Ubuntu flavors of
    109 // Linux, or else that the port's path (e.g., /dev/ttyACM0) has global
    110 // read/write permissions.
    111 //
    112 // 3. You have uploaded a program to the board that does a byte-for-byte echo
    113 // on the virtual serial port at 57600 bps. An example is at
    114 // chrome/test/data/extensions/api_test/serial/api/serial_arduino_test.ino.
    115 //
    116 #define SIMULATE_SERIAL_PORTS (1)
    117 IN_PROC_BROWSER_TEST_F(SerialApiTest, SerialFakeHardware) {
    118   extensions::ResultCatcher catcher;
    119   catcher.RestrictToBrowserContext(browser()->profile());
    120 
    121 #if SIMULATE_SERIAL_PORTS
    122   ASSERT_TRUE(extensions::ExtensionFunctionDispatcher::OverrideFunction(
    123       "serial.getDevices", FakeSerialGetDevicesFunctionFactory));
    124   ASSERT_TRUE(extensions::ExtensionFunctionDispatcher::OverrideFunction(
    125       "serial.connect", FakeSerialConnectFunctionFactory));
    126 #endif
    127 
    128   ASSERT_TRUE(RunExtensionTest("serial/api")) << message_;
    129 }
    130 
    131 IN_PROC_BROWSER_TEST_F(SerialApiTest, SerialRealHardware) {
    132   extensions::ResultCatcher catcher;
    133   catcher.RestrictToBrowserContext(browser()->profile());
    134 
    135   ASSERT_TRUE(RunExtensionTest("serial/real_hardware")) << message_;
    136 }
    137