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