| OLD | NEW |
| (Empty) |
| 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 "device/serial/serial_connection.h" | |
| 6 | |
| 7 #include <stdint.h> | |
| 8 | |
| 9 #include <memory> | |
| 10 #include <string> | |
| 11 #include <utility> | |
| 12 | |
| 13 #include "base/bind.h" | |
| 14 #include "base/macros.h" | |
| 15 #include "base/message_loop/message_loop.h" | |
| 16 #include "base/run_loop.h" | |
| 17 #include "base/strings/string_piece.h" | |
| 18 #include "device/serial/data_receiver.h" | |
| 19 #include "device/serial/data_sender.h" | |
| 20 #include "device/serial/data_stream.mojom.h" | |
| 21 #include "device/serial/serial.mojom.h" | |
| 22 #include "device/serial/serial_service_impl.h" | |
| 23 #include "device/serial/test_serial_io_handler.h" | |
| 24 #include "mojo/public/cpp/bindings/interface_ptr.h" | |
| 25 #include "mojo/public/cpp/bindings/interface_request.h" | |
| 26 #include "mojo/public/cpp/bindings/strong_binding.h" | |
| 27 #include "testing/gtest/include/gtest/gtest.h" | |
| 28 | |
| 29 namespace device { | |
| 30 namespace { | |
| 31 | |
| 32 class FakeSerialDeviceEnumerator : public SerialDeviceEnumerator { | |
| 33 mojo::Array<serial::DeviceInfoPtr> GetDevices() override { | |
| 34 mojo::Array<serial::DeviceInfoPtr> devices(1); | |
| 35 devices[0] = serial::DeviceInfo::New(); | |
| 36 devices[0]->path = "device"; | |
| 37 return devices; | |
| 38 } | |
| 39 }; | |
| 40 | |
| 41 } // namespace | |
| 42 | |
| 43 class SerialConnectionTest : public testing::Test { | |
| 44 public: | |
| 45 enum Event { | |
| 46 EVENT_NONE, | |
| 47 EVENT_GOT_INFO, | |
| 48 EVENT_SET_OPTIONS, | |
| 49 EVENT_GOT_CONTROL_SIGNALS, | |
| 50 EVENT_SET_CONTROL_SIGNALS, | |
| 51 EVENT_FLUSHED, | |
| 52 EVENT_DATA_AT_IO_HANDLER, | |
| 53 EVENT_DATA_SENT, | |
| 54 EVENT_SEND_ERROR, | |
| 55 EVENT_DATA_RECEIVED, | |
| 56 EVENT_RECEIVE_ERROR, | |
| 57 EVENT_CANCEL_COMPLETE, | |
| 58 EVENT_ERROR, | |
| 59 }; | |
| 60 | |
| 61 static const uint32_t kBufferSize; | |
| 62 | |
| 63 SerialConnectionTest() | |
| 64 : connected_(false), | |
| 65 success_(false), | |
| 66 bytes_sent_(0), | |
| 67 send_error_(serial::SendError::NONE), | |
| 68 receive_error_(serial::ReceiveError::NONE), | |
| 69 expected_event_(EVENT_NONE) {} | |
| 70 | |
| 71 void SetUp() override { | |
| 72 message_loop_.reset(new base::MessageLoop); | |
| 73 mojo::InterfacePtr<serial::SerialService> service; | |
| 74 mojo::MakeStrongBinding( | |
| 75 base::MakeUnique<SerialServiceImpl>( | |
| 76 new SerialConnectionFactory( | |
| 77 base::Bind(&SerialConnectionTest::CreateIoHandler, | |
| 78 base::Unretained(this)), | |
| 79 base::ThreadTaskRunnerHandle::Get()), | |
| 80 base::MakeUnique<FakeSerialDeviceEnumerator>()), | |
| 81 mojo::GetProxy(&service)); | |
| 82 service.set_connection_error_handler(base::Bind( | |
| 83 &SerialConnectionTest::OnConnectionError, base::Unretained(this))); | |
| 84 mojo::InterfacePtr<serial::DataSink> sink; | |
| 85 mojo::InterfacePtr<serial::DataSource> source; | |
| 86 mojo::InterfacePtr<serial::DataSourceClient> source_client; | |
| 87 mojo::InterfaceRequest<serial::DataSourceClient> source_client_request = | |
| 88 mojo::GetProxy(&source_client); | |
| 89 service->Connect("device", serial::ConnectionOptions::New(), | |
| 90 mojo::GetProxy(&connection_), mojo::GetProxy(&sink), | |
| 91 mojo::GetProxy(&source), std::move(source_client)); | |
| 92 sender_.reset( | |
| 93 new DataSender(std::move(sink), kBufferSize, | |
| 94 static_cast<int32_t>(serial::SendError::DISCONNECTED))); | |
| 95 receiver_ = new DataReceiver( | |
| 96 std::move(source), std::move(source_client_request), kBufferSize, | |
| 97 static_cast<int32_t>(serial::ReceiveError::DISCONNECTED)); | |
| 98 connection_.set_connection_error_handler(base::Bind( | |
| 99 &SerialConnectionTest::OnConnectionError, base::Unretained(this))); | |
| 100 connection_->GetInfo( | |
| 101 base::Bind(&SerialConnectionTest::StoreInfo, base::Unretained(this))); | |
| 102 WaitForEvent(EVENT_GOT_INFO); | |
| 103 ASSERT_TRUE(io_handler_.get()); | |
| 104 } | |
| 105 | |
| 106 void StoreInfo(serial::ConnectionInfoPtr options) { | |
| 107 info_ = std::move(options); | |
| 108 EventReceived(EVENT_GOT_INFO); | |
| 109 } | |
| 110 | |
| 111 void StoreControlSignals(serial::DeviceControlSignalsPtr signals) { | |
| 112 signals_ = std::move(signals); | |
| 113 EventReceived(EVENT_GOT_CONTROL_SIGNALS); | |
| 114 } | |
| 115 | |
| 116 void StoreSuccess(Event event_to_report, bool success) { | |
| 117 success_ = success; | |
| 118 EventReceived(event_to_report); | |
| 119 } | |
| 120 | |
| 121 void Send(const base::StringPiece& data) { | |
| 122 ASSERT_TRUE(sender_->Send( | |
| 123 data, | |
| 124 base::Bind(&SerialConnectionTest::OnDataSent, base::Unretained(this)), | |
| 125 base::Bind(&SerialConnectionTest::OnSendError, | |
| 126 base::Unretained(this)))); | |
| 127 } | |
| 128 | |
| 129 void Receive() { | |
| 130 ASSERT_TRUE( | |
| 131 receiver_->Receive(base::Bind(&SerialConnectionTest::OnDataReceived, | |
| 132 base::Unretained(this)), | |
| 133 base::Bind(&SerialConnectionTest::OnReceiveError, | |
| 134 base::Unretained(this)))); | |
| 135 } | |
| 136 | |
| 137 void WaitForEvent(Event event) { | |
| 138 expected_event_ = event; | |
| 139 base::RunLoop run_loop; | |
| 140 stop_run_loop_ = run_loop.QuitClosure(); | |
| 141 run_loop.Run(); | |
| 142 } | |
| 143 | |
| 144 void EventReceived(Event event) { | |
| 145 if (event != expected_event_) | |
| 146 return; | |
| 147 expected_event_ = EVENT_NONE; | |
| 148 ASSERT_TRUE(message_loop_); | |
| 149 ASSERT_TRUE(!stop_run_loop_.is_null()); | |
| 150 message_loop_->task_runner()->PostTask(FROM_HERE, stop_run_loop_); | |
| 151 } | |
| 152 | |
| 153 scoped_refptr<SerialIoHandler> CreateIoHandler() { | |
| 154 io_handler_ = new TestSerialIoHandler; | |
| 155 return io_handler_; | |
| 156 } | |
| 157 | |
| 158 void OnDataSent(uint32_t bytes_sent) { | |
| 159 bytes_sent_ += bytes_sent; | |
| 160 send_error_ = serial::SendError::NONE; | |
| 161 EventReceived(EVENT_DATA_SENT); | |
| 162 } | |
| 163 | |
| 164 void OnSendError(uint32_t bytes_sent, int32_t error) { | |
| 165 bytes_sent_ += bytes_sent; | |
| 166 send_error_ = static_cast<serial::SendError>(error); | |
| 167 EventReceived(EVENT_SEND_ERROR); | |
| 168 } | |
| 169 | |
| 170 void OnDataReceived(std::unique_ptr<ReadOnlyBuffer> buffer) { | |
| 171 data_received_ += std::string(buffer->GetData(), buffer->GetSize()); | |
| 172 buffer->Done(buffer->GetSize()); | |
| 173 receive_error_ = serial::ReceiveError::NONE; | |
| 174 EventReceived(EVENT_DATA_RECEIVED); | |
| 175 } | |
| 176 | |
| 177 void OnReceiveError(int32_t error) { | |
| 178 receive_error_ = static_cast<serial::ReceiveError>(error); | |
| 179 EventReceived(EVENT_RECEIVE_ERROR); | |
| 180 } | |
| 181 | |
| 182 void OnConnectionError() { | |
| 183 EventReceived(EVENT_ERROR); | |
| 184 FAIL() << "Connection error"; | |
| 185 } | |
| 186 | |
| 187 mojo::Array<serial::DeviceInfoPtr> devices_; | |
| 188 serial::ConnectionInfoPtr info_; | |
| 189 serial::DeviceControlSignalsPtr signals_; | |
| 190 bool connected_; | |
| 191 bool success_; | |
| 192 int bytes_sent_; | |
| 193 serial::SendError send_error_; | |
| 194 serial::ReceiveError receive_error_; | |
| 195 std::string data_received_; | |
| 196 Event expected_event_; | |
| 197 | |
| 198 std::unique_ptr<base::MessageLoop> message_loop_; | |
| 199 base::Closure stop_run_loop_; | |
| 200 mojo::InterfacePtr<serial::Connection> connection_; | |
| 201 std::unique_ptr<DataSender> sender_; | |
| 202 scoped_refptr<DataReceiver> receiver_; | |
| 203 scoped_refptr<TestSerialIoHandler> io_handler_; | |
| 204 | |
| 205 private: | |
| 206 DISALLOW_COPY_AND_ASSIGN(SerialConnectionTest); | |
| 207 }; | |
| 208 | |
| 209 const uint32_t SerialConnectionTest::kBufferSize = 10; | |
| 210 | |
| 211 TEST_F(SerialConnectionTest, GetInfo) { | |
| 212 // |info_| is filled in during SetUp(). | |
| 213 ASSERT_TRUE(info_); | |
| 214 EXPECT_EQ(9600u, info_->bitrate); | |
| 215 EXPECT_EQ(serial::DataBits::EIGHT, info_->data_bits); | |
| 216 EXPECT_EQ(serial::ParityBit::NO, info_->parity_bit); | |
| 217 EXPECT_EQ(serial::StopBits::ONE, info_->stop_bits); | |
| 218 EXPECT_FALSE(info_->cts_flow_control); | |
| 219 } | |
| 220 | |
| 221 TEST_F(SerialConnectionTest, SetOptions) { | |
| 222 serial::ConnectionOptionsPtr options(serial::ConnectionOptions::New()); | |
| 223 options->bitrate = 12345; | |
| 224 options->data_bits = serial::DataBits::SEVEN; | |
| 225 options->has_cts_flow_control = true; | |
| 226 options->cts_flow_control = true; | |
| 227 connection_->SetOptions( | |
| 228 std::move(options), | |
| 229 base::Bind(&SerialConnectionTest::StoreSuccess, base::Unretained(this), | |
| 230 EVENT_SET_OPTIONS)); | |
| 231 WaitForEvent(EVENT_SET_OPTIONS); | |
| 232 ASSERT_TRUE(success_); | |
| 233 serial::ConnectionInfo* info = io_handler_->connection_info(); | |
| 234 EXPECT_EQ(12345u, info->bitrate); | |
| 235 EXPECT_EQ(serial::DataBits::SEVEN, info->data_bits); | |
| 236 EXPECT_EQ(serial::ParityBit::NO, info->parity_bit); | |
| 237 EXPECT_EQ(serial::StopBits::ONE, info->stop_bits); | |
| 238 EXPECT_TRUE(info->cts_flow_control); | |
| 239 } | |
| 240 | |
| 241 TEST_F(SerialConnectionTest, GetControlSignals) { | |
| 242 connection_->GetControlSignals(base::Bind( | |
| 243 &SerialConnectionTest::StoreControlSignals, base::Unretained(this))); | |
| 244 serial::DeviceControlSignals* signals = io_handler_->device_control_signals(); | |
| 245 signals->dcd = true; | |
| 246 signals->dsr = true; | |
| 247 | |
| 248 WaitForEvent(EVENT_GOT_CONTROL_SIGNALS); | |
| 249 ASSERT_TRUE(signals_); | |
| 250 EXPECT_TRUE(signals_->dcd); | |
| 251 EXPECT_FALSE(signals_->cts); | |
| 252 EXPECT_FALSE(signals_->ri); | |
| 253 EXPECT_TRUE(signals_->dsr); | |
| 254 } | |
| 255 | |
| 256 TEST_F(SerialConnectionTest, SetControlSignals) { | |
| 257 serial::HostControlSignalsPtr signals(serial::HostControlSignals::New()); | |
| 258 signals->has_dtr = true; | |
| 259 signals->dtr = true; | |
| 260 signals->has_rts = true; | |
| 261 signals->rts = true; | |
| 262 | |
| 263 connection_->SetControlSignals( | |
| 264 std::move(signals), | |
| 265 base::Bind(&SerialConnectionTest::StoreSuccess, base::Unretained(this), | |
| 266 EVENT_SET_CONTROL_SIGNALS)); | |
| 267 WaitForEvent(EVENT_SET_CONTROL_SIGNALS); | |
| 268 ASSERT_TRUE(success_); | |
| 269 EXPECT_TRUE(io_handler_->dtr()); | |
| 270 EXPECT_TRUE(io_handler_->rts()); | |
| 271 } | |
| 272 | |
| 273 TEST_F(SerialConnectionTest, Flush) { | |
| 274 ASSERT_EQ(0, io_handler_->flushes()); | |
| 275 connection_->Flush(base::Bind(&SerialConnectionTest::StoreSuccess, | |
| 276 base::Unretained(this), | |
| 277 EVENT_FLUSHED)); | |
| 278 WaitForEvent(EVENT_FLUSHED); | |
| 279 ASSERT_TRUE(success_); | |
| 280 EXPECT_EQ(1, io_handler_->flushes()); | |
| 281 } | |
| 282 | |
| 283 TEST_F(SerialConnectionTest, DisconnectWithSend) { | |
| 284 connection_.reset(); | |
| 285 io_handler_->set_send_callback(base::Bind(base::DoNothing)); | |
| 286 ASSERT_NO_FATAL_FAILURE(Send("data")); | |
| 287 WaitForEvent(EVENT_SEND_ERROR); | |
| 288 EXPECT_EQ(serial::SendError::DISCONNECTED, send_error_); | |
| 289 EXPECT_EQ(0, bytes_sent_); | |
| 290 EXPECT_TRUE(io_handler_->HasOneRef()); | |
| 291 } | |
| 292 | |
| 293 TEST_F(SerialConnectionTest, DisconnectWithReceive) { | |
| 294 connection_.reset(); | |
| 295 ASSERT_NO_FATAL_FAILURE(Receive()); | |
| 296 WaitForEvent(EVENT_RECEIVE_ERROR); | |
| 297 EXPECT_EQ(serial::ReceiveError::DISCONNECTED, receive_error_); | |
| 298 EXPECT_EQ("", data_received_); | |
| 299 EXPECT_TRUE(io_handler_->HasOneRef()); | |
| 300 } | |
| 301 | |
| 302 TEST_F(SerialConnectionTest, Echo) { | |
| 303 ASSERT_NO_FATAL_FAILURE(Send("data")); | |
| 304 WaitForEvent(EVENT_DATA_SENT); | |
| 305 EXPECT_EQ(serial::SendError::NONE, send_error_); | |
| 306 EXPECT_EQ(4, bytes_sent_); | |
| 307 ASSERT_NO_FATAL_FAILURE(Receive()); | |
| 308 WaitForEvent(EVENT_DATA_RECEIVED); | |
| 309 EXPECT_EQ("data", data_received_); | |
| 310 EXPECT_EQ(serial::ReceiveError::NONE, receive_error_); | |
| 311 } | |
| 312 | |
| 313 TEST_F(SerialConnectionTest, Cancel) { | |
| 314 // To test that cancels are correctly passed to the IoHandler, we need a send | |
| 315 // to be in progress because otherwise, the DataSinkReceiver would handle the | |
| 316 // cancel internally. | |
| 317 io_handler_->set_send_callback( | |
| 318 base::Bind(&SerialConnectionTest::EventReceived, | |
| 319 base::Unretained(this), | |
| 320 EVENT_DATA_AT_IO_HANDLER)); | |
| 321 ASSERT_NO_FATAL_FAILURE(Send("something else")); | |
| 322 WaitForEvent(EVENT_DATA_AT_IO_HANDLER); | |
| 323 EXPECT_EQ(0, bytes_sent_); | |
| 324 | |
| 325 ASSERT_TRUE(sender_->Cancel( | |
| 326 static_cast<int32_t>(serial::SendError::TIMEOUT), | |
| 327 base::Bind(&SerialConnectionTest::EventReceived, base::Unretained(this), | |
| 328 EVENT_CANCEL_COMPLETE))); | |
| 329 | |
| 330 WaitForEvent(EVENT_CANCEL_COMPLETE); | |
| 331 EXPECT_EQ(serial::SendError::TIMEOUT, send_error_); | |
| 332 | |
| 333 ASSERT_NO_FATAL_FAILURE(Send("data")); | |
| 334 WaitForEvent(EVENT_DATA_SENT); | |
| 335 EXPECT_EQ(serial::SendError::NONE, send_error_); | |
| 336 EXPECT_EQ(4, bytes_sent_); | |
| 337 ASSERT_NO_FATAL_FAILURE(Receive()); | |
| 338 WaitForEvent(EVENT_DATA_RECEIVED); | |
| 339 EXPECT_EQ("data", data_received_); | |
| 340 EXPECT_EQ(serial::ReceiveError::NONE, receive_error_); | |
| 341 } | |
| 342 | |
| 343 } // namespace device | |
| OLD | NEW |