1// Copyright (c) 2012 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// Common utilities for Quic tests
6
7#ifndef NET_QUIC_TEST_TOOLS_QUIC_TEST_UTILS_H_
8#define NET_QUIC_TEST_TOOLS_QUIC_TEST_UTILS_H_
9
10#include <string>
11#include <vector>
12
13#include "base/strings/string_piece.h"
14#include "net/quic/congestion_control/loss_detection_interface.h"
15#include "net/quic/congestion_control/send_algorithm_interface.h"
16#include "net/quic/quic_ack_notifier.h"
17#include "net/quic/quic_client_session_base.h"
18#include "net/quic/quic_connection.h"
19#include "net/quic/quic_framer.h"
20#include "net/quic/quic_session.h"
21#include "net/quic/test_tools/mock_clock.h"
22#include "net/quic/test_tools/mock_random.h"
23#include "net/spdy/spdy_framer.h"
24#include "testing/gmock/include/gmock/gmock.h"
25
26namespace net {
27
28namespace test {
29
30static const QuicConnectionId kTestConnectionId = 42;
31static const int kTestPort = 123;
32static const uint32 kInitialStreamFlowControlWindowForTest =
33    32 * 1024;  // 32 KB
34static const uint32 kInitialSessionFlowControlWindowForTest =
35    64 * 1024;  // 64 KB
36
37// Data stream IDs start at 5: the crypto stream is 1, headers stream is 3.
38static const QuicStreamId kClientDataStreamId1 = 5;
39static const QuicStreamId kClientDataStreamId2 = 7;
40static const QuicStreamId kClientDataStreamId3 = 9;
41static const QuicStreamId kClientDataStreamId4 = 11;
42
43// Returns the test peer IP address.
44IPAddressNumber TestPeerIPAddress();
45
46// Upper limit on versions we support.
47QuicVersion QuicVersionMax();
48
49// Lower limit on versions we support.
50QuicVersion QuicVersionMin();
51
52// Returns an address for 127.0.0.1.
53IPAddressNumber Loopback4();
54
55// Returns an address for ::1.
56IPAddressNumber Loopback6();
57
58void GenerateBody(std::string* body, int length);
59
60// Create an encrypted packet for testing.
61QuicEncryptedPacket* ConstructEncryptedPacket(
62    QuicConnectionId connection_id,
63    bool version_flag,
64    bool reset_flag,
65    QuicPacketSequenceNumber sequence_number,
66    const std::string& data);
67
68void CompareCharArraysWithHexError(const std::string& description,
69                                   const char* actual,
70                                   const int actual_len,
71                                   const char* expected,
72                                   const int expected_len);
73
74bool DecodeHexString(const base::StringPiece& hex, std::string* bytes);
75
76// Returns the length of a QuicPacket that is capable of holding either a
77// stream frame or a minimal ack frame.  Sets |*payload_length| to the number
78// of bytes of stream data that will fit in such a packet.
79size_t GetPacketLengthForOneStream(
80    QuicVersion version,
81    bool include_version,
82    QuicSequenceNumberLength sequence_number_length,
83    InFecGroup is_in_fec_group,
84    size_t* payload_length);
85
86// Returns QuicConfig set to default values.
87QuicConfig DefaultQuicConfig();
88
89// Returns a version vector consisting of |version|.
90QuicVersionVector SupportedVersions(QuicVersion version);
91
92// Testing convenience method to construct a QuicAckFrame with all packets
93// from least_unacked to largest_observed acked.
94QuicAckFrame MakeAckFrame(QuicPacketSequenceNumber largest_observed,
95                          QuicPacketSequenceNumber least_unacked);
96
97// Testing convenience method to construct a QuicAckFrame with |num_nack_ranges|
98// nack ranges of width 1 packet, starting from |least_unacked|.
99QuicAckFrame MakeAckFrameWithNackRanges(size_t num_nack_ranges,
100                                        QuicPacketSequenceNumber least_unacked);
101
102// Returns a SerializedPacket whose |packet| member is owned by the caller, and
103// is populated with the fields in |header| and |frames|, or is NULL if the
104// packet could not be created.
105SerializedPacket BuildUnsizedDataPacket(QuicFramer* framer,
106                                        const QuicPacketHeader& header,
107                                        const QuicFrames& frames);
108
109template<typename SaveType>
110class ValueRestore {
111 public:
112  ValueRestore(SaveType* name, SaveType value)
113      : name_(name),
114        value_(*name) {
115    *name_ = value;
116  }
117  ~ValueRestore() {
118    *name_ = value_;
119  }
120
121 private:
122  SaveType* name_;
123  SaveType value_;
124
125  DISALLOW_COPY_AND_ASSIGN(ValueRestore);
126};
127
128// Simple random number generator used to compute random numbers suitable
129// for pseudo-randomly dropping packets in tests.  It works by computing
130// the sha1 hash of the current seed, and using the first 64 bits as
131// the next random number, and the next seed.
132class SimpleRandom {
133 public:
134  SimpleRandom() : seed_(0) {}
135
136  // Returns a random number in the range [0, kuint64max].
137  uint64 RandUint64();
138
139  void set_seed(uint64 seed) { seed_ = seed; }
140
141 private:
142  uint64 seed_;
143
144  DISALLOW_COPY_AND_ASSIGN(SimpleRandom);
145};
146
147class MockFramerVisitor : public QuicFramerVisitorInterface {
148 public:
149  MockFramerVisitor();
150  virtual ~MockFramerVisitor();
151
152  MOCK_METHOD1(OnError, void(QuicFramer* framer));
153  // The constructor sets this up to return false by default.
154  MOCK_METHOD1(OnProtocolVersionMismatch, bool(QuicVersion version));
155  MOCK_METHOD0(OnPacket, void());
156  MOCK_METHOD1(OnPublicResetPacket, void(const QuicPublicResetPacket& header));
157  MOCK_METHOD1(OnVersionNegotiationPacket,
158               void(const QuicVersionNegotiationPacket& packet));
159  MOCK_METHOD0(OnRevivedPacket, void());
160  // The constructor sets this up to return true by default.
161  MOCK_METHOD1(OnUnauthenticatedHeader, bool(const QuicPacketHeader& header));
162  // The constructor sets this up to return true by default.
163  MOCK_METHOD1(OnUnauthenticatedPublicHeader, bool(
164      const QuicPacketPublicHeader& header));
165  MOCK_METHOD1(OnDecryptedPacket, void(EncryptionLevel level));
166  MOCK_METHOD1(OnPacketHeader, bool(const QuicPacketHeader& header));
167  MOCK_METHOD1(OnFecProtectedPayload, void(base::StringPiece payload));
168  MOCK_METHOD1(OnStreamFrame, bool(const QuicStreamFrame& frame));
169  MOCK_METHOD1(OnAckFrame, bool(const QuicAckFrame& frame));
170  MOCK_METHOD1(OnCongestionFeedbackFrame,
171               bool(const QuicCongestionFeedbackFrame& frame));
172  MOCK_METHOD1(OnStopWaitingFrame, bool(const QuicStopWaitingFrame& frame));
173  MOCK_METHOD1(OnPingFrame, bool(const QuicPingFrame& frame));
174  MOCK_METHOD1(OnFecData, void(const QuicFecData& fec));
175  MOCK_METHOD1(OnRstStreamFrame, bool(const QuicRstStreamFrame& frame));
176  MOCK_METHOD1(OnConnectionCloseFrame,
177               bool(const QuicConnectionCloseFrame& frame));
178  MOCK_METHOD1(OnGoAwayFrame, bool(const QuicGoAwayFrame& frame));
179  MOCK_METHOD1(OnWindowUpdateFrame, bool(const QuicWindowUpdateFrame& frame));
180  MOCK_METHOD1(OnBlockedFrame, bool(const QuicBlockedFrame& frame));
181  MOCK_METHOD0(OnPacketComplete, void());
182
183 private:
184  DISALLOW_COPY_AND_ASSIGN(MockFramerVisitor);
185};
186
187class NoOpFramerVisitor : public QuicFramerVisitorInterface {
188 public:
189  NoOpFramerVisitor() {}
190
191  virtual void OnError(QuicFramer* framer) OVERRIDE {}
192  virtual void OnPacket() OVERRIDE {}
193  virtual void OnPublicResetPacket(
194      const QuicPublicResetPacket& packet) OVERRIDE {}
195  virtual void OnVersionNegotiationPacket(
196      const QuicVersionNegotiationPacket& packet) OVERRIDE {}
197  virtual void OnRevivedPacket() OVERRIDE {}
198  virtual bool OnProtocolVersionMismatch(QuicVersion version) OVERRIDE;
199  virtual bool OnUnauthenticatedHeader(const QuicPacketHeader& header) OVERRIDE;
200  virtual bool OnUnauthenticatedPublicHeader(
201      const QuicPacketPublicHeader& header) OVERRIDE;
202  virtual void OnDecryptedPacket(EncryptionLevel level) OVERRIDE {}
203  virtual bool OnPacketHeader(const QuicPacketHeader& header) OVERRIDE;
204  virtual void OnFecProtectedPayload(base::StringPiece payload) OVERRIDE {}
205  virtual bool OnStreamFrame(const QuicStreamFrame& frame) OVERRIDE;
206  virtual bool OnAckFrame(const QuicAckFrame& frame) OVERRIDE;
207  virtual bool OnCongestionFeedbackFrame(
208      const QuicCongestionFeedbackFrame& frame) OVERRIDE;
209  virtual bool OnStopWaitingFrame(
210      const QuicStopWaitingFrame& frame) OVERRIDE;
211  virtual bool OnPingFrame(const QuicPingFrame& frame) OVERRIDE;
212  virtual void OnFecData(const QuicFecData& fec) OVERRIDE {}
213  virtual bool OnRstStreamFrame(const QuicRstStreamFrame& frame) OVERRIDE;
214  virtual bool OnConnectionCloseFrame(
215      const QuicConnectionCloseFrame& frame) OVERRIDE;
216  virtual bool OnGoAwayFrame(const QuicGoAwayFrame& frame) OVERRIDE;
217  virtual bool OnWindowUpdateFrame(const QuicWindowUpdateFrame& frame) OVERRIDE;
218  virtual bool OnBlockedFrame(const QuicBlockedFrame& frame) OVERRIDE;
219  virtual void OnPacketComplete() OVERRIDE {}
220
221 private:
222  DISALLOW_COPY_AND_ASSIGN(NoOpFramerVisitor);
223};
224
225class MockConnectionVisitor : public QuicConnectionVisitorInterface {
226 public:
227  MockConnectionVisitor();
228  virtual ~MockConnectionVisitor();
229
230  MOCK_METHOD1(OnStreamFrames, void(const std::vector<QuicStreamFrame>& frame));
231  MOCK_METHOD1(OnWindowUpdateFrames,
232               void(const std::vector<QuicWindowUpdateFrame>& frame));
233  MOCK_METHOD1(OnBlockedFrames,
234               void(const std::vector<QuicBlockedFrame>& frame));
235  MOCK_METHOD1(OnRstStream, void(const QuicRstStreamFrame& frame));
236  MOCK_METHOD1(OnGoAway, void(const QuicGoAwayFrame& frame));
237  MOCK_METHOD2(OnConnectionClosed, void(QuicErrorCode error, bool from_peer));
238  MOCK_METHOD0(OnWriteBlocked, void());
239  MOCK_METHOD0(OnCanWrite, void());
240  MOCK_CONST_METHOD0(WillingAndAbleToWrite, bool());
241  MOCK_CONST_METHOD0(HasPendingHandshake, bool());
242  MOCK_CONST_METHOD0(HasOpenDataStreams, bool());
243  MOCK_METHOD1(OnSuccessfulVersionNegotiation,
244               void(const QuicVersion& version));
245  MOCK_METHOD0(OnConfigNegotiated, void());
246
247 private:
248  DISALLOW_COPY_AND_ASSIGN(MockConnectionVisitor);
249};
250
251class MockHelper : public QuicConnectionHelperInterface {
252 public:
253  MockHelper();
254  virtual ~MockHelper();
255  virtual const QuicClock* GetClock() const OVERRIDE;
256  virtual QuicRandom* GetRandomGenerator() OVERRIDE;
257  virtual QuicAlarm* CreateAlarm(QuicAlarm::Delegate* delegate) OVERRIDE;
258  void AdvanceTime(QuicTime::Delta delta);
259
260 private:
261  MockClock clock_;
262  MockRandom random_generator_;
263
264  DISALLOW_COPY_AND_ASSIGN(MockHelper);
265};
266
267class MockConnection : public QuicConnection {
268 public:
269  // Uses a MockHelper, ConnectionId of 42, and 127.0.0.1:123.
270  explicit MockConnection(bool is_server);
271
272  // Uses a MockHelper, ConnectionId of 42.
273  MockConnection(IPEndPoint address, bool is_server);
274
275  // Uses a MockHelper, and 127.0.0.1:123
276  MockConnection(QuicConnectionId connection_id, bool is_server);
277
278  // Uses a Mock helper, ConnectionId of 42, and 127.0.0.1:123.
279  MockConnection(bool is_server, const QuicVersionVector& supported_versions);
280
281  virtual ~MockConnection();
282
283  // If the constructor that uses a MockHelper has been used then this method
284  // will advance the time of the MockClock.
285  void AdvanceTime(QuicTime::Delta delta);
286
287  MOCK_METHOD3(ProcessUdpPacket, void(const IPEndPoint& self_address,
288                                      const IPEndPoint& peer_address,
289                                      const QuicEncryptedPacket& packet));
290  MOCK_METHOD1(SendConnectionClose, void(QuicErrorCode error));
291  MOCK_METHOD2(SendConnectionCloseWithDetails, void(QuicErrorCode error,
292                                                    const string& details));
293  MOCK_METHOD2(SendConnectionClosePacket, void(QuicErrorCode error,
294                                               const string& details));
295  MOCK_METHOD3(SendRstStream, void(QuicStreamId id,
296                                   QuicRstStreamErrorCode error,
297                                   QuicStreamOffset bytes_written));
298  MOCK_METHOD3(SendGoAway, void(QuicErrorCode error,
299                                QuicStreamId last_good_stream_id,
300                                const string& reason));
301  MOCK_METHOD1(SendBlocked, void(QuicStreamId id));
302  MOCK_METHOD2(SendWindowUpdate, void(QuicStreamId id,
303                                      QuicStreamOffset byte_offset));
304  MOCK_METHOD0(OnCanWrite, void());
305
306  void ProcessUdpPacketInternal(const IPEndPoint& self_address,
307                                const IPEndPoint& peer_address,
308                                const QuicEncryptedPacket& packet) {
309    QuicConnection::ProcessUdpPacket(self_address, peer_address, packet);
310  }
311
312  virtual bool OnProtocolVersionMismatch(QuicVersion version) OVERRIDE {
313    return false;
314  }
315
316 private:
317  scoped_ptr<QuicPacketWriter> writer_;
318  scoped_ptr<QuicConnectionHelperInterface> helper_;
319
320  DISALLOW_COPY_AND_ASSIGN(MockConnection);
321};
322
323class PacketSavingConnection : public MockConnection {
324 public:
325  explicit PacketSavingConnection(bool is_server);
326
327  PacketSavingConnection(bool is_server,
328                         const QuicVersionVector& supported_versions);
329
330  virtual ~PacketSavingConnection();
331
332  virtual bool SendOrQueuePacket(EncryptionLevel level,
333                                 const SerializedPacket& packet,
334                                 TransmissionType transmission_type) OVERRIDE;
335
336  std::vector<QuicPacket*> packets_;
337  std::vector<QuicEncryptedPacket*> encrypted_packets_;
338
339 private:
340  DISALLOW_COPY_AND_ASSIGN(PacketSavingConnection);
341};
342
343class MockSession : public QuicSession {
344 public:
345  explicit MockSession(QuicConnection* connection);
346  virtual ~MockSession();
347  MOCK_METHOD2(OnConnectionClosed, void(QuicErrorCode error, bool from_peer));
348  MOCK_METHOD1(CreateIncomingDataStream, QuicDataStream*(QuicStreamId id));
349  MOCK_METHOD0(GetCryptoStream, QuicCryptoStream*());
350  MOCK_METHOD0(CreateOutgoingDataStream, QuicDataStream*());
351  MOCK_METHOD6(WritevData,
352               QuicConsumedData(QuicStreamId id,
353                                const IOVector& data,
354                                QuicStreamOffset offset,
355                                bool fin,
356                                FecProtection fec_protection,
357                                QuicAckNotifier::DelegateInterface*));
358  MOCK_METHOD2(OnStreamHeaders, void(QuicStreamId stream_id,
359                                     base::StringPiece headers_data));
360  MOCK_METHOD2(OnStreamHeadersPriority, void(QuicStreamId stream_id,
361                                             QuicPriority priority));
362  MOCK_METHOD3(OnStreamHeadersComplete, void(QuicStreamId stream_id,
363                                             bool fin,
364                                             size_t frame_len));
365  MOCK_METHOD3(SendRstStream, void(QuicStreamId stream_id,
366                                   QuicRstStreamErrorCode error,
367                                   QuicStreamOffset bytes_written));
368  MOCK_METHOD0(IsCryptoHandshakeConfirmed, bool());
369
370  using QuicSession::ActivateStream;
371
372 private:
373  DISALLOW_COPY_AND_ASSIGN(MockSession);
374};
375
376class TestSession : public QuicSession {
377 public:
378  TestSession(QuicConnection* connection, const QuicConfig& config);
379  virtual ~TestSession();
380
381  MOCK_METHOD1(CreateIncomingDataStream, QuicDataStream*(QuicStreamId id));
382  MOCK_METHOD0(CreateOutgoingDataStream, QuicDataStream*());
383
384  void SetCryptoStream(QuicCryptoStream* stream);
385
386  virtual QuicCryptoStream* GetCryptoStream() OVERRIDE;
387
388 private:
389  QuicCryptoStream* crypto_stream_;
390
391  DISALLOW_COPY_AND_ASSIGN(TestSession);
392};
393
394class TestClientSession : public QuicClientSessionBase {
395 public:
396  TestClientSession(QuicConnection* connection, const QuicConfig& config);
397  virtual ~TestClientSession();
398
399  // QuicClientSessionBase
400  MOCK_METHOD1(OnProofValid,
401               void(const QuicCryptoClientConfig::CachedState& cached));
402  MOCK_METHOD1(OnProofVerifyDetailsAvailable,
403               void(const ProofVerifyDetails& verify_details));
404
405  // TestClientSession
406  MOCK_METHOD1(CreateIncomingDataStream, QuicDataStream*(QuicStreamId id));
407  MOCK_METHOD0(CreateOutgoingDataStream, QuicDataStream*());
408
409  void SetCryptoStream(QuicCryptoStream* stream);
410
411  virtual QuicCryptoStream* GetCryptoStream() OVERRIDE;
412
413 private:
414  QuicCryptoStream* crypto_stream_;
415
416  DISALLOW_COPY_AND_ASSIGN(TestClientSession);
417};
418
419class MockPacketWriter : public QuicPacketWriter {
420 public:
421  MockPacketWriter();
422  virtual ~MockPacketWriter();
423
424  MOCK_METHOD4(WritePacket,
425               WriteResult(const char* buffer,
426                           size_t buf_len,
427                           const IPAddressNumber& self_address,
428                           const IPEndPoint& peer_address));
429  MOCK_CONST_METHOD0(IsWriteBlockedDataBuffered, bool());
430  MOCK_CONST_METHOD0(IsWriteBlocked, bool());
431  MOCK_METHOD0(SetWritable, void());
432
433 private:
434  DISALLOW_COPY_AND_ASSIGN(MockPacketWriter);
435};
436
437class MockSendAlgorithm : public SendAlgorithmInterface {
438 public:
439  MockSendAlgorithm();
440  virtual ~MockSendAlgorithm();
441
442  MOCK_METHOD2(SetFromConfig, void(const QuicConfig& config, bool is_server));
443  MOCK_METHOD1(SetMaxPacketSize, void(QuicByteCount max_packet_size));
444  MOCK_METHOD2(OnIncomingQuicCongestionFeedbackFrame,
445               void(const QuicCongestionFeedbackFrame&,
446                    QuicTime feedback_receive_time));
447  MOCK_METHOD4(OnCongestionEvent, void(bool rtt_updated,
448                                       QuicByteCount bytes_in_flight,
449                                       const CongestionMap& acked_packets,
450                                       const CongestionMap& lost_packets));
451  MOCK_METHOD5(OnPacketSent,
452               bool(QuicTime, QuicByteCount, QuicPacketSequenceNumber,
453                    QuicByteCount, HasRetransmittableData));
454  MOCK_METHOD1(OnRetransmissionTimeout, void(bool));
455  MOCK_CONST_METHOD3(TimeUntilSend,
456                     QuicTime::Delta(QuicTime now,
457                                     QuicByteCount bytes_in_flight,
458                                     HasRetransmittableData));
459  MOCK_CONST_METHOD0(BandwidthEstimate, QuicBandwidth(void));
460  MOCK_METHOD1(OnRttUpdated, void(QuicPacketSequenceNumber));
461  MOCK_CONST_METHOD0(RetransmissionDelay, QuicTime::Delta(void));
462  MOCK_CONST_METHOD0(GetCongestionWindow, QuicByteCount());
463
464 private:
465  DISALLOW_COPY_AND_ASSIGN(MockSendAlgorithm);
466};
467
468class MockLossAlgorithm : public LossDetectionInterface {
469 public:
470  MockLossAlgorithm();
471  virtual ~MockLossAlgorithm();
472
473  MOCK_CONST_METHOD0(GetLossDetectionType, LossDetectionType());
474  MOCK_METHOD4(DetectLostPackets,
475               SequenceNumberSet(const QuicUnackedPacketMap& unacked_packets,
476                                 const QuicTime& time,
477                                 QuicPacketSequenceNumber largest_observed,
478                                 const RttStats& rtt_stats));
479  MOCK_CONST_METHOD0(GetLossTimeout, QuicTime());
480
481 private:
482  DISALLOW_COPY_AND_ASSIGN(MockLossAlgorithm);
483};
484
485class TestEntropyCalculator :
486      public QuicReceivedEntropyHashCalculatorInterface {
487 public:
488  TestEntropyCalculator();
489  virtual ~TestEntropyCalculator();
490
491  virtual QuicPacketEntropyHash EntropyHash(
492      QuicPacketSequenceNumber sequence_number) const OVERRIDE;
493
494 private:
495  DISALLOW_COPY_AND_ASSIGN(TestEntropyCalculator);
496};
497
498class MockEntropyCalculator : public TestEntropyCalculator {
499 public:
500  MockEntropyCalculator();
501  virtual ~MockEntropyCalculator();
502
503  MOCK_CONST_METHOD1(
504      EntropyHash,
505      QuicPacketEntropyHash(QuicPacketSequenceNumber sequence_number));
506
507 private:
508  DISALLOW_COPY_AND_ASSIGN(MockEntropyCalculator);
509};
510
511class MockAckNotifierDelegate : public QuicAckNotifier::DelegateInterface {
512 public:
513  MockAckNotifierDelegate();
514
515  MOCK_METHOD5(OnAckNotification, void(int num_original_packets,
516                                       int num_original_bytes,
517                                       int num_retransmitted_packets,
518                                       int num_retransmitted_bytes,
519                                       QuicTime::Delta delta_largest_observed));
520
521 protected:
522  // Object is ref counted.
523  virtual ~MockAckNotifierDelegate();
524
525 private:
526  DISALLOW_COPY_AND_ASSIGN(MockAckNotifierDelegate);
527};
528
529}  // namespace test
530}  // namespace net
531
532#endif  // NET_QUIC_TEST_TOOLS_QUIC_TEST_UTILS_H_
533