• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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