quic_test_utils.h revision 6e8cce623b6e4fe0c9e4af605d675dd9d0338c38
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_sent_packet_manager.h"
21#include "net/quic/quic_session.h"
22#include "net/quic/test_tools/mock_clock.h"
23#include "net/quic/test_tools/mock_random.h"
24#include "net/spdy/spdy_framer.h"
25#include "testing/gmock/include/gmock/gmock.h"
26
27namespace net {
28
29namespace test {
30
31static const QuicConnectionId kTestConnectionId = 42;
32static const int kTestPort = 123;
33static const uint32 kInitialStreamFlowControlWindowForTest =
34    32 * 1024;  // 32 KB
35static const uint32 kInitialSessionFlowControlWindowForTest =
36    64 * 1024;  // 64 KB
37
38// Data stream IDs start at 5: the crypto stream is 1, headers stream is 3.
39static const QuicStreamId kClientDataStreamId1 = 5;
40static const QuicStreamId kClientDataStreamId2 = 7;
41static const QuicStreamId kClientDataStreamId3 = 9;
42static const QuicStreamId kClientDataStreamId4 = 11;
43
44// Returns the test peer IP address.
45IPAddressNumber TestPeerIPAddress();
46
47// Upper limit on versions we support.
48QuicVersion QuicVersionMax();
49
50// Lower limit on versions we support.
51QuicVersion QuicVersionMin();
52
53// Returns an address for 127.0.0.1.
54IPAddressNumber Loopback4();
55
56// Returns an address for ::1.
57IPAddressNumber Loopback6();
58
59void GenerateBody(std::string* body, int length);
60
61// Create an encrypted packet for testing.
62QuicEncryptedPacket* ConstructEncryptedPacket(
63    QuicConnectionId connection_id,
64    bool version_flag,
65    bool reset_flag,
66    QuicPacketSequenceNumber sequence_number,
67    const std::string& data);
68
69void CompareCharArraysWithHexError(const std::string& description,
70                                   const char* actual,
71                                   const int actual_len,
72                                   const char* expected,
73                                   const int expected_len);
74
75bool DecodeHexString(const base::StringPiece& hex, std::string* bytes);
76
77// Returns the length of a QuicPacket that is capable of holding either a
78// stream frame or a minimal ack frame.  Sets |*payload_length| to the number
79// of bytes of stream data that will fit in such a packet.
80size_t GetPacketLengthForOneStream(
81    QuicVersion version,
82    bool include_version,
83    QuicSequenceNumberLength sequence_number_length,
84    InFecGroup is_in_fec_group,
85    size_t* payload_length);
86
87// Returns QuicConfig set to default values.
88QuicConfig DefaultQuicConfig();
89
90// Returns a version vector consisting of |version|.
91QuicVersionVector SupportedVersions(QuicVersion version);
92
93// Testing convenience method to construct a QuicAckFrame with entropy_hash set
94// to 0 and largest_observed from peer set to |largest_observed|.
95QuicAckFrame MakeAckFrame(QuicPacketSequenceNumber largest_observed);
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<QuicConnectionHelperInterface> helper_;
318
319  DISALLOW_COPY_AND_ASSIGN(MockConnection);
320};
321
322class PacketSavingConnection : public MockConnection {
323 public:
324  explicit PacketSavingConnection(bool is_server);
325
326  PacketSavingConnection(bool is_server,
327                         const QuicVersionVector& supported_versions);
328
329  virtual ~PacketSavingConnection();
330
331  virtual bool SendOrQueuePacket(EncryptionLevel level,
332                                 const SerializedPacket& packet,
333                                 TransmissionType transmission_type) OVERRIDE;
334
335  std::vector<QuicPacket*> packets_;
336  std::vector<QuicEncryptedPacket*> encrypted_packets_;
337
338 private:
339  DISALLOW_COPY_AND_ASSIGN(PacketSavingConnection);
340};
341
342class MockSession : public QuicSession {
343 public:
344  explicit MockSession(QuicConnection* connection);
345  virtual ~MockSession();
346  MOCK_METHOD2(OnConnectionClosed, void(QuicErrorCode error, bool from_peer));
347  MOCK_METHOD1(CreateIncomingDataStream, QuicDataStream*(QuicStreamId id));
348  MOCK_METHOD0(GetCryptoStream, QuicCryptoStream*());
349  MOCK_METHOD0(CreateOutgoingDataStream, QuicDataStream*());
350  MOCK_METHOD6(WritevData,
351               QuicConsumedData(QuicStreamId id,
352                                const IOVector& data,
353                                QuicStreamOffset offset,
354                                bool fin,
355                                FecProtection fec_protection,
356                                QuicAckNotifier::DelegateInterface*));
357  MOCK_METHOD2(OnStreamHeaders, void(QuicStreamId stream_id,
358                                     base::StringPiece headers_data));
359  MOCK_METHOD2(OnStreamHeadersPriority, void(QuicStreamId stream_id,
360                                             QuicPriority priority));
361  MOCK_METHOD3(OnStreamHeadersComplete, void(QuicStreamId stream_id,
362                                             bool fin,
363                                             size_t frame_len));
364  MOCK_METHOD3(SendRstStream, void(QuicStreamId stream_id,
365                                   QuicRstStreamErrorCode error,
366                                   QuicStreamOffset bytes_written));
367  MOCK_METHOD0(IsCryptoHandshakeConfirmed, bool());
368
369  using QuicSession::ActivateStream;
370
371 private:
372  DISALLOW_COPY_AND_ASSIGN(MockSession);
373};
374
375class TestSession : public QuicSession {
376 public:
377  TestSession(QuicConnection* connection, const QuicConfig& config);
378  virtual ~TestSession();
379
380  MOCK_METHOD1(CreateIncomingDataStream, QuicDataStream*(QuicStreamId id));
381  MOCK_METHOD0(CreateOutgoingDataStream, QuicDataStream*());
382
383  void SetCryptoStream(QuicCryptoStream* stream);
384
385  virtual QuicCryptoStream* GetCryptoStream() OVERRIDE;
386
387 private:
388  QuicCryptoStream* crypto_stream_;
389
390  DISALLOW_COPY_AND_ASSIGN(TestSession);
391};
392
393class TestClientSession : public QuicClientSessionBase {
394 public:
395  TestClientSession(QuicConnection* connection, const QuicConfig& config);
396  virtual ~TestClientSession();
397
398  // QuicClientSessionBase
399  MOCK_METHOD1(OnProofValid,
400               void(const QuicCryptoClientConfig::CachedState& cached));
401  MOCK_METHOD1(OnProofVerifyDetailsAvailable,
402               void(const ProofVerifyDetails& verify_details));
403
404  // TestClientSession
405  MOCK_METHOD1(CreateIncomingDataStream, QuicDataStream*(QuicStreamId id));
406  MOCK_METHOD0(CreateOutgoingDataStream, QuicDataStream*());
407
408  void SetCryptoStream(QuicCryptoStream* stream);
409
410  virtual QuicCryptoStream* GetCryptoStream() OVERRIDE;
411
412 private:
413  QuicCryptoStream* crypto_stream_;
414
415  DISALLOW_COPY_AND_ASSIGN(TestClientSession);
416};
417
418class MockPacketWriter : public QuicPacketWriter {
419 public:
420  MockPacketWriter();
421  virtual ~MockPacketWriter();
422
423  MOCK_METHOD4(WritePacket,
424               WriteResult(const char* buffer,
425                           size_t buf_len,
426                           const IPAddressNumber& self_address,
427                           const IPEndPoint& peer_address));
428  MOCK_CONST_METHOD0(IsWriteBlockedDataBuffered, bool());
429  MOCK_CONST_METHOD0(IsWriteBlocked, bool());
430  MOCK_METHOD0(SetWritable, void());
431
432 private:
433  DISALLOW_COPY_AND_ASSIGN(MockPacketWriter);
434};
435
436class MockSendAlgorithm : public SendAlgorithmInterface {
437 public:
438  MockSendAlgorithm();
439  virtual ~MockSendAlgorithm();
440
441  MOCK_METHOD2(SetFromConfig, void(const QuicConfig& config, bool is_server));
442  MOCK_METHOD1(SetMaxPacketSize, void(QuicByteCount max_packet_size));
443  MOCK_METHOD2(OnIncomingQuicCongestionFeedbackFrame,
444               void(const QuicCongestionFeedbackFrame&,
445                    QuicTime feedback_receive_time));
446  MOCK_METHOD4(OnCongestionEvent, void(bool rtt_updated,
447                                       QuicByteCount bytes_in_flight,
448                                       const CongestionMap& acked_packets,
449                                       const CongestionMap& lost_packets));
450  MOCK_METHOD5(OnPacketSent,
451               bool(QuicTime, QuicByteCount, QuicPacketSequenceNumber,
452                    QuicByteCount, HasRetransmittableData));
453  MOCK_METHOD1(OnRetransmissionTimeout, void(bool));
454  MOCK_METHOD0(RevertRetransmissionTimeout, void());
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_CONST_METHOD0(HasReliableBandwidthEstimate, bool());
461  MOCK_METHOD1(OnRttUpdated, void(QuicPacketSequenceNumber));
462  MOCK_CONST_METHOD0(RetransmissionDelay, QuicTime::Delta(void));
463  MOCK_CONST_METHOD0(GetCongestionWindow, QuicByteCount());
464  MOCK_CONST_METHOD0(InSlowStart, bool());
465  MOCK_CONST_METHOD0(GetSlowStartThreshold, QuicByteCount());
466  MOCK_CONST_METHOD0(GetCongestionControlType, CongestionControlType());
467
468 private:
469  DISALLOW_COPY_AND_ASSIGN(MockSendAlgorithm);
470};
471
472class MockLossAlgorithm : public LossDetectionInterface {
473 public:
474  MockLossAlgorithm();
475  virtual ~MockLossAlgorithm();
476
477  MOCK_CONST_METHOD0(GetLossDetectionType, LossDetectionType());
478  MOCK_METHOD4(DetectLostPackets,
479               SequenceNumberSet(const QuicUnackedPacketMap& unacked_packets,
480                                 const QuicTime& time,
481                                 QuicPacketSequenceNumber largest_observed,
482                                 const RttStats& rtt_stats));
483  MOCK_CONST_METHOD0(GetLossTimeout, QuicTime());
484
485 private:
486  DISALLOW_COPY_AND_ASSIGN(MockLossAlgorithm);
487};
488
489class TestEntropyCalculator :
490      public QuicReceivedEntropyHashCalculatorInterface {
491 public:
492  TestEntropyCalculator();
493  virtual ~TestEntropyCalculator();
494
495  virtual QuicPacketEntropyHash EntropyHash(
496      QuicPacketSequenceNumber sequence_number) const OVERRIDE;
497
498 private:
499  DISALLOW_COPY_AND_ASSIGN(TestEntropyCalculator);
500};
501
502class MockEntropyCalculator : public TestEntropyCalculator {
503 public:
504  MockEntropyCalculator();
505  virtual ~MockEntropyCalculator();
506
507  MOCK_CONST_METHOD1(
508      EntropyHash,
509      QuicPacketEntropyHash(QuicPacketSequenceNumber sequence_number));
510
511 private:
512  DISALLOW_COPY_AND_ASSIGN(MockEntropyCalculator);
513};
514
515class MockAckNotifierDelegate : public QuicAckNotifier::DelegateInterface {
516 public:
517  MockAckNotifierDelegate();
518
519  MOCK_METHOD5(OnAckNotification, void(int num_original_packets,
520                                       int num_original_bytes,
521                                       int num_retransmitted_packets,
522                                       int num_retransmitted_bytes,
523                                       QuicTime::Delta delta_largest_observed));
524
525 protected:
526  // Object is ref counted.
527  virtual ~MockAckNotifierDelegate();
528
529 private:
530  DISALLOW_COPY_AND_ASSIGN(MockAckNotifierDelegate);
531};
532
533class MockNetworkChangeVisitor :
534      public QuicSentPacketManager::NetworkChangeVisitor {
535 public:
536  MockNetworkChangeVisitor();
537  virtual ~MockNetworkChangeVisitor();
538
539  MOCK_METHOD1(OnCongestionWindowChange, void(QuicByteCount));
540
541 private:
542  DISALLOW_COPY_AND_ASSIGN(MockNetworkChangeVisitor);
543};
544
545}  // namespace test
546}  // namespace net
547
548#endif  // NET_QUIC_TEST_TOOLS_QUIC_TEST_UTILS_H_
549