1 /* 2 * Copyright (C) 2015 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #include "udp.h" 18 19 #include <gtest/gtest.h> 20 21 #include "socket.h" 22 #include "socket_mock.h" 23 24 using namespace udp; 25 using namespace udp::internal; 26 27 // Some possible corner case sequence numbers we want to check. 28 static const uint16_t kTestSequenceNumbers[] = {0x0000, 0x0001, 0x00FF, 0x0100, 29 0x7FFF, 0x8000, 0xFFFF}; 30 31 // Converts |value| to a binary big-endian string. PacketValue(uint16_t value)32 static std::string PacketValue(uint16_t value) { 33 return std::string{static_cast<char>(value >> 8), static_cast<char>(value)}; 34 } 35 36 // Returns an Error packet. ErrorPacket(uint16_t sequence,const std::string & message="",char flags=kFlagNone)37 static std::string ErrorPacket(uint16_t sequence, const std::string& message = "", 38 char flags = kFlagNone) { 39 return std::string{kIdError, flags} + PacketValue(sequence) + message; 40 } 41 42 // Returns a Query packet with no data. QueryPacket(uint16_t sequence)43 static std::string QueryPacket(uint16_t sequence) { 44 return std::string{kIdDeviceQuery, kFlagNone} + PacketValue(sequence); 45 } 46 47 // Returns a Query packet with a 2-byte |new_sequence|. QueryPacket(uint16_t sequence,uint16_t new_sequence)48 static std::string QueryPacket(uint16_t sequence, uint16_t new_sequence) { 49 return std::string{kIdDeviceQuery, kFlagNone} + PacketValue(sequence) + 50 PacketValue(new_sequence); 51 } 52 53 // Returns an Init packet with a 2-byte |version| and |max_packet_size|. InitPacket(uint16_t sequence,uint16_t version,uint16_t max_packet_size)54 static std::string InitPacket(uint16_t sequence, uint16_t version, uint16_t max_packet_size) { 55 return std::string{kIdInitialization, kFlagNone} + PacketValue(sequence) + 56 PacketValue(version) + PacketValue(max_packet_size); 57 } 58 59 // Returns a Fastboot packet with |data|. FastbootPacket(uint16_t sequence,const std::string & data="",char flags=kFlagNone)60 static std::string FastbootPacket(uint16_t sequence, const std::string& data = "", 61 char flags = kFlagNone) { 62 return std::string{kIdFastboot, flags} + PacketValue(sequence) + data; 63 } 64 65 // Fixture class to test protocol initialization. Usage is to set up the expected calls to the 66 // SocketMock object then call UdpConnect() and check the result. 67 class UdpConnectTest : public ::testing::Test { 68 public: UdpConnectTest()69 UdpConnectTest() : mock_socket_(new SocketMock) {} 70 71 // Run the initialization, return whether it was successful or not. This passes ownership of 72 // the current |mock_socket_| but allocates a new one for re-use. UdpConnect(std::string * error=nullptr)73 bool UdpConnect(std::string* error = nullptr) { 74 std::string local_error; 75 if (error == nullptr) { 76 error = &local_error; 77 } 78 std::unique_ptr<Transport> transport(Connect(std::move(mock_socket_), error)); 79 mock_socket_.reset(new SocketMock); 80 return transport != nullptr && error->empty(); 81 } 82 83 protected: 84 std::unique_ptr<SocketMock> mock_socket_; 85 }; 86 87 // Tests a successful protocol initialization with various starting sequence numbers. TEST_F(UdpConnectTest,InitializationSuccess)88 TEST_F(UdpConnectTest, InitializationSuccess) { 89 for (uint16_t seq : kTestSequenceNumbers) { 90 mock_socket_->ExpectSend(QueryPacket(0)); 91 mock_socket_->AddReceive(QueryPacket(0, seq)); 92 mock_socket_->ExpectSend(InitPacket(seq, kProtocolVersion, kHostMaxPacketSize)); 93 mock_socket_->AddReceive(InitPacket(seq, kProtocolVersion, 1024)); 94 95 EXPECT_TRUE(UdpConnect()); 96 } 97 } 98 99 // Tests continuation packets during initialization. TEST_F(UdpConnectTest,InitializationContinuationSuccess)100 TEST_F(UdpConnectTest, InitializationContinuationSuccess) { 101 mock_socket_->ExpectSend(QueryPacket(0)); 102 mock_socket_->AddReceive(std::string{kIdDeviceQuery, kFlagContinuation, 0, 0, 0x44}); 103 mock_socket_->ExpectSend(std::string{kIdDeviceQuery, kFlagNone, 0, 1}); 104 mock_socket_->AddReceive(std::string{kIdDeviceQuery, kFlagNone, 0, 1, 0x55}); 105 106 mock_socket_->ExpectSend(InitPacket(0x4455, kProtocolVersion, kHostMaxPacketSize)); 107 mock_socket_->AddReceive(std::string{kIdInitialization, kFlagContinuation, 0x44, 0x55, 0}); 108 mock_socket_->ExpectSend(std::string{kIdInitialization, kFlagNone, 0x44, 0x56}); 109 mock_socket_->AddReceive(std::string{kIdInitialization, kFlagContinuation, 0x44, 0x56, 1}); 110 mock_socket_->ExpectSend(std::string{kIdInitialization, kFlagNone, 0x44, 0x57}); 111 mock_socket_->AddReceive(std::string{kIdInitialization, kFlagContinuation, 0x44, 0x57, 2}); 112 mock_socket_->ExpectSend(std::string{kIdInitialization, kFlagNone, 0x44, 0x58}); 113 mock_socket_->AddReceive(std::string{kIdInitialization, kFlagNone, 0x44, 0x58, 0}); 114 115 EXPECT_TRUE(UdpConnect()); 116 } 117 118 119 // Tests a mismatched version number; as long as the minimum of the two versions is supported 120 // we should allow the connection. TEST_F(UdpConnectTest,InitializationVersionMismatch)121 TEST_F(UdpConnectTest, InitializationVersionMismatch) { 122 mock_socket_->ExpectSend(QueryPacket(0)); 123 mock_socket_->AddReceive(QueryPacket(0, 0)); 124 mock_socket_->ExpectSend(InitPacket(0, kProtocolVersion, kHostMaxPacketSize)); 125 mock_socket_->AddReceive(InitPacket(0, 2, 1024)); 126 127 EXPECT_TRUE(UdpConnect()); 128 129 mock_socket_->ExpectSend(QueryPacket(0)); 130 mock_socket_->AddReceive(QueryPacket(0, 0)); 131 mock_socket_->ExpectSend(InitPacket(0, kProtocolVersion, kHostMaxPacketSize)); 132 mock_socket_->AddReceive(InitPacket(0, 0, 1024)); 133 134 EXPECT_FALSE(UdpConnect()); 135 } 136 TEST_F(UdpConnectTest,QueryResponseTimeoutFailure)137 TEST_F(UdpConnectTest, QueryResponseTimeoutFailure) { 138 for (int i = 0; i < kMaxConnectAttempts; ++i) { 139 mock_socket_->ExpectSend(QueryPacket(0)); 140 mock_socket_->AddReceiveTimeout(); 141 } 142 143 EXPECT_FALSE(UdpConnect()); 144 } 145 TEST_F(UdpConnectTest,QueryResponseReceiveFailure)146 TEST_F(UdpConnectTest, QueryResponseReceiveFailure) { 147 mock_socket_->ExpectSend(QueryPacket(0)); 148 mock_socket_->AddReceiveFailure(); 149 150 EXPECT_FALSE(UdpConnect()); 151 } 152 TEST_F(UdpConnectTest,InitResponseTimeoutFailure)153 TEST_F(UdpConnectTest, InitResponseTimeoutFailure) { 154 mock_socket_->ExpectSend(QueryPacket(0)); 155 mock_socket_->AddReceive(QueryPacket(0, 0)); 156 for (int i = 0; i < kMaxTransmissionAttempts; ++i) { 157 mock_socket_->ExpectSend(InitPacket(0, kProtocolVersion, kHostMaxPacketSize)); 158 mock_socket_->AddReceiveTimeout(); 159 } 160 161 EXPECT_FALSE(UdpConnect()); 162 } 163 TEST_F(UdpConnectTest,InitResponseReceiveFailure)164 TEST_F(UdpConnectTest, InitResponseReceiveFailure) { 165 mock_socket_->ExpectSend(QueryPacket(0)); 166 mock_socket_->AddReceive(QueryPacket(0, 0)); 167 mock_socket_->ExpectSend(InitPacket(0, kProtocolVersion, kHostMaxPacketSize)); 168 mock_socket_->AddReceiveFailure(); 169 170 EXPECT_FALSE(UdpConnect()); 171 } 172 173 // Tests that we can recover up to the maximum number of allowed retries. TEST_F(UdpConnectTest,ResponseRecovery)174 TEST_F(UdpConnectTest, ResponseRecovery) { 175 // The device query packet can recover from up to (kMaxConnectAttempts - 1) timeouts. 176 for (int i = 0; i < kMaxConnectAttempts - 1; ++i) { 177 mock_socket_->ExpectSend(QueryPacket(0)); 178 mock_socket_->AddReceiveTimeout(); 179 } 180 mock_socket_->ExpectSend(QueryPacket(0)); 181 mock_socket_->AddReceive(QueryPacket(0, 0)); 182 183 // Subsequent packets try up to (kMaxTransmissionAttempts - 1) times. 184 for (int i = 0; i < kMaxTransmissionAttempts - 1; ++i) { 185 mock_socket_->ExpectSend(InitPacket(0, kProtocolVersion, kHostMaxPacketSize)); 186 mock_socket_->AddReceiveTimeout(); 187 } 188 mock_socket_->ExpectSend(InitPacket(0, kProtocolVersion, kHostMaxPacketSize)); 189 mock_socket_->AddReceive(InitPacket(0, kProtocolVersion, 1024)); 190 191 EXPECT_TRUE(UdpConnect()); 192 } 193 194 // Tests that the host can handle receiving additional bytes for forward compatibility. TEST_F(UdpConnectTest,ExtraResponseDataSuccess)195 TEST_F(UdpConnectTest, ExtraResponseDataSuccess) { 196 mock_socket_->ExpectSend(QueryPacket(0)); 197 mock_socket_->AddReceive(QueryPacket(0, 0) + "foo"); 198 mock_socket_->ExpectSend(InitPacket(0, kProtocolVersion, kHostMaxPacketSize)); 199 mock_socket_->AddReceive(InitPacket(0, kProtocolVersion, 1024) + "bar"); 200 201 EXPECT_TRUE(UdpConnect()); 202 } 203 204 // Tests mismatched response sequence numbers. A wrong sequence number is interpreted as a previous 205 // retransmission and just ignored so we should be able to recover. TEST_F(UdpConnectTest,WrongSequenceRecovery)206 TEST_F(UdpConnectTest, WrongSequenceRecovery) { 207 mock_socket_->ExpectSend(QueryPacket(0)); 208 mock_socket_->AddReceive(QueryPacket(1, 0)); 209 mock_socket_->AddReceive(QueryPacket(0, 0)); 210 211 mock_socket_->ExpectSend(InitPacket(0, kProtocolVersion, kHostMaxPacketSize)); 212 mock_socket_->AddReceive(InitPacket(1, kProtocolVersion, 1024)); 213 mock_socket_->AddReceive(InitPacket(0, kProtocolVersion, 1024)); 214 215 EXPECT_TRUE(UdpConnect()); 216 } 217 218 // Tests mismatched response IDs. This should also be interpreted as a retransmission and ignored. TEST_F(UdpConnectTest,WrongIdRecovery)219 TEST_F(UdpConnectTest, WrongIdRecovery) { 220 mock_socket_->ExpectSend(QueryPacket(0)); 221 mock_socket_->AddReceive(FastbootPacket(0)); 222 mock_socket_->AddReceive(QueryPacket(0, 0)); 223 224 mock_socket_->ExpectSend(InitPacket(0, kProtocolVersion, kHostMaxPacketSize)); 225 mock_socket_->AddReceive(FastbootPacket(0)); 226 mock_socket_->AddReceive(InitPacket(0, kProtocolVersion, 1024)); 227 228 EXPECT_TRUE(UdpConnect()); 229 } 230 231 // Tests an invalid query response. Query responses must have at least 2 bytes of data. TEST_F(UdpConnectTest,InvalidQueryResponseFailure)232 TEST_F(UdpConnectTest, InvalidQueryResponseFailure) { 233 std::string error; 234 235 mock_socket_->ExpectSend(QueryPacket(0)); 236 mock_socket_->AddReceive(QueryPacket(0)); 237 238 EXPECT_FALSE(UdpConnect(&error)); 239 EXPECT_EQ("invalid query response from target", error); 240 241 mock_socket_->ExpectSend(QueryPacket(0)); 242 mock_socket_->AddReceive(QueryPacket(0) + std::string{0x00}); 243 244 EXPECT_FALSE(UdpConnect(&error)); 245 EXPECT_EQ("invalid query response from target", error); 246 } 247 248 // Tests an invalid initialization response. Max packet size must be at least 512 bytes. TEST_F(UdpConnectTest,InvalidInitResponseFailure)249 TEST_F(UdpConnectTest, InvalidInitResponseFailure) { 250 std::string error; 251 252 mock_socket_->ExpectSend(QueryPacket(0)); 253 mock_socket_->AddReceive(QueryPacket(0, 0)); 254 mock_socket_->ExpectSend(InitPacket(0, kProtocolVersion, kHostMaxPacketSize)); 255 mock_socket_->AddReceive(InitPacket(0, kProtocolVersion, 511)); 256 257 EXPECT_FALSE(UdpConnect(&error)); 258 EXPECT_EQ("target reported invalid packet size 511", error); 259 260 mock_socket_->ExpectSend(QueryPacket(0)); 261 mock_socket_->AddReceive(QueryPacket(0, 0)); 262 mock_socket_->ExpectSend(InitPacket(0, kProtocolVersion, kHostMaxPacketSize)); 263 mock_socket_->AddReceive(InitPacket(0, 0, 1024)); 264 265 EXPECT_FALSE(UdpConnect(&error)); 266 EXPECT_EQ("target reported invalid protocol version 0", error); 267 } 268 TEST_F(UdpConnectTest,ErrorResponseFailure)269 TEST_F(UdpConnectTest, ErrorResponseFailure) { 270 std::string error; 271 272 mock_socket_->ExpectSend(QueryPacket(0)); 273 mock_socket_->AddReceive(ErrorPacket(0, "error1")); 274 275 EXPECT_FALSE(UdpConnect(&error)); 276 EXPECT_NE(std::string::npos, error.find("error1")); 277 278 mock_socket_->ExpectSend(QueryPacket(0)); 279 mock_socket_->AddReceive(QueryPacket(0, 0)); 280 mock_socket_->ExpectSend(InitPacket(0, kProtocolVersion, kHostMaxPacketSize)); 281 mock_socket_->AddReceive(ErrorPacket(0, "error2")); 282 283 EXPECT_FALSE(UdpConnect(&error)); 284 EXPECT_NE(std::string::npos, error.find("error2")); 285 } 286 287 // Tests an error response with continuation flag. TEST_F(UdpConnectTest,ErrorContinuationFailure)288 TEST_F(UdpConnectTest, ErrorContinuationFailure) { 289 std::string error; 290 291 mock_socket_->ExpectSend(QueryPacket(0)); 292 mock_socket_->AddReceive(ErrorPacket(0, "error1", kFlagContinuation)); 293 mock_socket_->ExpectSend(ErrorPacket(1)); 294 mock_socket_->AddReceive(ErrorPacket(1, " ", kFlagContinuation)); 295 mock_socket_->ExpectSend(ErrorPacket(2)); 296 mock_socket_->AddReceive(ErrorPacket(2, "error2")); 297 298 EXPECT_FALSE(UdpConnect(&error)); 299 EXPECT_NE(std::string::npos, error.find("error1 error2")); 300 } 301 302 // Fixture class to test UDP Transport read/write functionality. 303 class UdpTest : public ::testing::Test { 304 public: SetUp()305 void SetUp() override { 306 // Create |transport_| starting at sequence 0 with 512 byte max packet size. Tests can call 307 // InitializeTransport() again to change settings. 308 ASSERT_TRUE(InitializeTransport(0, 512)); 309 } 310 311 // Sets up |mock_socket_| to correctly initialize the protocol and creates |transport_|. This 312 // can be called multiple times in a test if needed. InitializeTransport(uint16_t starting_sequence,int device_max_packet_size=512)313 bool InitializeTransport(uint16_t starting_sequence, int device_max_packet_size = 512) { 314 mock_socket_ = new SocketMock; 315 mock_socket_->ExpectSend(QueryPacket(0)); 316 mock_socket_->AddReceive(QueryPacket(0, starting_sequence)); 317 mock_socket_->ExpectSend( 318 InitPacket(starting_sequence, kProtocolVersion, kHostMaxPacketSize)); 319 mock_socket_->AddReceive( 320 InitPacket(starting_sequence, kProtocolVersion, device_max_packet_size)); 321 322 std::string error; 323 transport_ = Connect(std::unique_ptr<Socket>(mock_socket_), &error); 324 return transport_ != nullptr && error.empty(); 325 } 326 327 // Writes |message| to |transport_|, returns true on success. Write(const std::string & message)328 bool Write(const std::string& message) { 329 return transport_->Write(message.data(), message.length()) == 330 static_cast<ssize_t>(message.length()); 331 } 332 333 // Reads from |transport_|, returns true if it matches |message|. Read(const std::string & message)334 bool Read(const std::string& message) { 335 std::string buffer(message.length(), '\0'); 336 return transport_->Read(&buffer[0], buffer.length()) == 337 static_cast<ssize_t>(message.length()) && buffer == message; 338 } 339 340 protected: 341 // |mock_socket_| is a raw pointer here because we transfer ownership to |transport_| but we 342 // need to retain a pointer to set send and receive expectations. 343 SocketMock* mock_socket_ = nullptr; 344 std::unique_ptr<Transport> transport_; 345 }; 346 347 // Tests sequence behavior with various starting sequence numbers. TEST_F(UdpTest,SequenceIncrementCheck)348 TEST_F(UdpTest, SequenceIncrementCheck) { 349 for (uint16_t seq : kTestSequenceNumbers) { 350 ASSERT_TRUE(InitializeTransport(seq)); 351 352 for (int i = 0; i < 10; ++i) { 353 mock_socket_->ExpectSend(FastbootPacket(++seq, "foo")); 354 mock_socket_->AddReceive(FastbootPacket(seq, "")); 355 mock_socket_->ExpectSend(FastbootPacket(++seq, "")); 356 mock_socket_->AddReceive(FastbootPacket(seq, "bar")); 357 358 EXPECT_TRUE(Write("foo")); 359 EXPECT_TRUE(Read("bar")); 360 } 361 } 362 } 363 364 // Tests sending and receiving a few small packets. TEST_F(UdpTest,ReadAndWriteSmallPackets)365 TEST_F(UdpTest, ReadAndWriteSmallPackets) { 366 mock_socket_->ExpectSend(FastbootPacket(1, "foo")); 367 mock_socket_->AddReceive(FastbootPacket(1, "")); 368 mock_socket_->ExpectSend(FastbootPacket(2, "")); 369 mock_socket_->AddReceive(FastbootPacket(2, "bar")); 370 371 EXPECT_TRUE(Write("foo")); 372 EXPECT_TRUE(Read("bar")); 373 374 mock_socket_->ExpectSend(FastbootPacket(3, "12345 67890")); 375 mock_socket_->AddReceive(FastbootPacket(3)); 376 mock_socket_->ExpectSend(FastbootPacket(4, "\x01\x02\x03\x04\x05")); 377 mock_socket_->AddReceive(FastbootPacket(4)); 378 379 EXPECT_TRUE(Write("12345 67890")); 380 EXPECT_TRUE(Write("\x01\x02\x03\x04\x05")); 381 382 // Reads are done by sending empty packets. 383 mock_socket_->ExpectSend(FastbootPacket(5)); 384 mock_socket_->AddReceive(FastbootPacket(5, "foo bar baz")); 385 mock_socket_->ExpectSend(FastbootPacket(6)); 386 mock_socket_->AddReceive(FastbootPacket(6, "\x01\x02\x03\x04\x05")); 387 388 EXPECT_TRUE(Read("foo bar baz")); 389 EXPECT_TRUE(Read("\x01\x02\x03\x04\x05")); 390 } 391 TEST_F(UdpTest,ResponseTimeoutFailure)392 TEST_F(UdpTest, ResponseTimeoutFailure) { 393 for (int i = 0; i < kMaxTransmissionAttempts; ++i) { 394 mock_socket_->ExpectSend(FastbootPacket(1, "foo")); 395 mock_socket_->AddReceiveTimeout(); 396 } 397 398 EXPECT_FALSE(Write("foo")); 399 } 400 TEST_F(UdpTest,ResponseReceiveFailure)401 TEST_F(UdpTest, ResponseReceiveFailure) { 402 mock_socket_->ExpectSend(FastbootPacket(1, "foo")); 403 mock_socket_->AddReceiveFailure(); 404 405 EXPECT_FALSE(Write("foo")); 406 } 407 TEST_F(UdpTest,ResponseTimeoutRecovery)408 TEST_F(UdpTest, ResponseTimeoutRecovery) { 409 for (int i = 0; i < kMaxTransmissionAttempts - 1; ++i) { 410 mock_socket_->ExpectSend(FastbootPacket(1, "foo")); 411 mock_socket_->AddReceiveTimeout(); 412 } 413 mock_socket_->ExpectSend(FastbootPacket(1, "foo")); 414 mock_socket_->AddReceive(FastbootPacket(1, "")); 415 416 EXPECT_TRUE(Write("foo")); 417 } 418 419 // Tests continuation packets for various max packet sizes. 420 // The important part of this test is that regardless of what kind of packet fragmentation happens 421 // at the socket layer, a single call to Transport::Read() and Transport::Write() is all the 422 // fastboot code needs to do. TEST_F(UdpTest,ContinuationPackets)423 TEST_F(UdpTest, ContinuationPackets) { 424 for (uint16_t max_packet_size : {512, 1024, 1200}) { 425 ASSERT_TRUE(InitializeTransport(0, max_packet_size)); 426 427 // Initialize the data we want to send. Use (size - 4) to leave room for the header. 428 size_t max_data_size = max_packet_size - 4; 429 std::string data(max_data_size * 3, '\0'); 430 for (size_t i = 0; i < data.length(); ++i) { 431 data[i] = i; 432 } 433 std::string chunks[] = {data.substr(0, max_data_size), 434 data.substr(max_data_size, max_data_size), 435 data.substr(max_data_size * 2, max_data_size)}; 436 437 // Write data: split into 3 UDP packets, each of which will be ACKed. 438 mock_socket_->ExpectSend(FastbootPacket(1, chunks[0], kFlagContinuation)); 439 mock_socket_->AddReceive(FastbootPacket(1)); 440 mock_socket_->ExpectSend(FastbootPacket(2, chunks[1], kFlagContinuation)); 441 mock_socket_->AddReceive(FastbootPacket(2)); 442 mock_socket_->ExpectSend(FastbootPacket(3, chunks[2])); 443 mock_socket_->AddReceive(FastbootPacket(3)); 444 EXPECT_TRUE(Write(data)); 445 446 // Same thing for reading the data. 447 mock_socket_->ExpectSend(FastbootPacket(4)); 448 mock_socket_->AddReceive(FastbootPacket(4, chunks[0], kFlagContinuation)); 449 mock_socket_->ExpectSend(FastbootPacket(5)); 450 mock_socket_->AddReceive(FastbootPacket(5, chunks[1], kFlagContinuation)); 451 mock_socket_->ExpectSend(FastbootPacket(6)); 452 mock_socket_->AddReceive(FastbootPacket(6, chunks[2])); 453 EXPECT_TRUE(Read(data)); 454 } 455 } 456 457 // Tests that the continuation bit is respected even if the packet isn't max size. TEST_F(UdpTest,SmallContinuationPackets)458 TEST_F(UdpTest, SmallContinuationPackets) { 459 mock_socket_->ExpectSend(FastbootPacket(1)); 460 mock_socket_->AddReceive(FastbootPacket(1, "foo", kFlagContinuation)); 461 mock_socket_->ExpectSend(FastbootPacket(2)); 462 mock_socket_->AddReceive(FastbootPacket(2, "bar")); 463 464 EXPECT_TRUE(Read("foobar")); 465 } 466 467 // Tests receiving an error packet mid-continuation. TEST_F(UdpTest,ContinuationPacketError)468 TEST_F(UdpTest, ContinuationPacketError) { 469 mock_socket_->ExpectSend(FastbootPacket(1)); 470 mock_socket_->AddReceive(FastbootPacket(1, "foo", kFlagContinuation)); 471 mock_socket_->ExpectSend(FastbootPacket(2)); 472 mock_socket_->AddReceive(ErrorPacket(2, "test error")); 473 474 EXPECT_FALSE(Read("foo")); 475 } 476 477 // Tests timeout during a continuation sequence. TEST_F(UdpTest,ContinuationTimeoutRecovery)478 TEST_F(UdpTest, ContinuationTimeoutRecovery) { 479 mock_socket_->ExpectSend(FastbootPacket(1)); 480 mock_socket_->AddReceive(FastbootPacket(1, "foo", kFlagContinuation)); 481 mock_socket_->ExpectSend(FastbootPacket(2)); 482 mock_socket_->AddReceiveTimeout(); 483 mock_socket_->ExpectSend(FastbootPacket(2)); 484 mock_socket_->AddReceive(FastbootPacket(2, "bar")); 485 486 EXPECT_TRUE(Read("foobar")); 487 } 488 489 // Tests read overflow returns -1 to indicate the failure. TEST_F(UdpTest,MultipleReadPacket)490 TEST_F(UdpTest, MultipleReadPacket) { 491 mock_socket_->ExpectSend(FastbootPacket(1)); 492 mock_socket_->AddReceive(FastbootPacket(1, "foobarbaz")); 493 494 char buffer[3]; 495 EXPECT_EQ(-1, transport_->Read(buffer, 3)); 496 } 497 498 // Tests that packets arriving out-of-order are ignored. TEST_F(UdpTest,IgnoreOutOfOrderPackets)499 TEST_F(UdpTest, IgnoreOutOfOrderPackets) { 500 mock_socket_->ExpectSend(FastbootPacket(1)); 501 mock_socket_->AddReceive(FastbootPacket(0, "sequence too low")); 502 mock_socket_->AddReceive(FastbootPacket(2, "sequence too high")); 503 mock_socket_->AddReceive(QueryPacket(1)); 504 mock_socket_->AddReceive(FastbootPacket(1, "correct")); 505 506 EXPECT_TRUE(Read("correct")); 507 } 508 509 // Tests that an error response with the correct sequence number causes immediate failure. TEST_F(UdpTest,ErrorResponse)510 TEST_F(UdpTest, ErrorResponse) { 511 // Error packets with the wrong sequence number should be ignored like any other packet. 512 mock_socket_->ExpectSend(FastbootPacket(1, "foo")); 513 mock_socket_->AddReceive(ErrorPacket(0, "ignored error")); 514 mock_socket_->AddReceive(FastbootPacket(1)); 515 516 EXPECT_TRUE(Write("foo")); 517 518 // Error packets with the correct sequence should abort immediately without retransmission. 519 mock_socket_->ExpectSend(FastbootPacket(2, "foo")); 520 mock_socket_->AddReceive(ErrorPacket(2, "test error")); 521 522 EXPECT_FALSE(Write("foo")); 523 } 524 525 // Tests that attempting to use a closed transport returns -1 without making any socket calls. TEST_F(UdpTest,CloseTransport)526 TEST_F(UdpTest, CloseTransport) { 527 char buffer[32]; 528 EXPECT_EQ(0, transport_->Close()); 529 EXPECT_EQ(-1, transport_->Write("foo", 3)); 530 EXPECT_EQ(-1, transport_->Read(buffer, sizeof(buffer))); 531 } 532