1 // Copyright 2013 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.
5 #ifndef NET_TOOLS_QUIC_TEST_TOOLS_PACKET_DROPPING_TEST_WRITER_H_
6 #define NET_TOOLS_QUIC_TEST_TOOLS_PACKET_DROPPING_TEST_WRITER_H_
11 #include "base/basictypes.h"
12 #include "base/logging.h"
13 #include "base/memory/scoped_ptr.h"
14 #include "base/synchronization/lock.h"
15 #include "net/quic/quic_alarm.h"
16 #include "net/quic/test_tools/quic_test_utils.h"
17 #include "net/tools/quic/quic_epoll_clock.h"
18 #include "net/tools/quic/quic_packet_writer_wrapper.h"
19 #include "net/tools/quic/test_tools/quic_test_client.h"
25 // Simulates a connection that drops packets a configured percentage of the time
26 // and has a blocked socket a configured percentage of the time. Also provides
27 // the options to delay packets and reorder packets if delay is enabled.
28 class PacketDroppingTestWriter
: public QuicPacketWriterWrapper
{
32 virtual ~Delegate() {}
33 virtual void OnPacketSent(WriteResult result
) = 0;
34 virtual void OnCanWrite() = 0;
37 PacketDroppingTestWriter();
39 ~PacketDroppingTestWriter() override
;
41 // Must be called before blocking, reordering or delaying (loss is OK). May be
42 // called after connecting if the helper is not available before.
43 // |on_can_write| will be triggered when fake-unblocking; ownership will be
45 void Initialize(QuicConnectionHelperInterface
* helper
,
46 Delegate
* on_can_write
);
48 // QuicPacketWriter methods:
49 WriteResult
WritePacket(const char* buffer
,
51 const IPAddressNumber
& self_address
,
52 const IPEndPoint
& peer_address
) override
;
54 bool IsWriteBlocked() const override
;
56 void SetWritable() override
;
58 // Writes out any packet which should have been sent by now
59 // to the contained writer and returns the time
60 // for the next delayed packet to be written.
61 QuicTime
ReleaseOldPackets();
65 // The percent of time a packet is simulated as being lost.
66 void set_fake_packet_loss_percentage(int32 fake_packet_loss_percentage
) {
67 base::AutoLock
locked(config_mutex_
);
68 fake_packet_loss_percentage_
= fake_packet_loss_percentage
;
71 // Simulate dropping the first n packets unconditionally.
72 // Subsequent packets will be lost at fake_packet_loss_percentage_ if set.
73 void set_fake_drop_first_n_packets(int32 fake_drop_first_n_packets
) {
74 base::AutoLock
locked(config_mutex_
);
75 fake_drop_first_n_packets_
= fake_drop_first_n_packets
;
78 // The percent of time WritePacket will block and set WriteResult's status
79 // to WRITE_STATUS_BLOCKED.
80 void set_fake_blocked_socket_percentage(
81 int32 fake_blocked_socket_percentage
) {
83 base::AutoLock
locked(config_mutex_
);
84 fake_blocked_socket_percentage_
= fake_blocked_socket_percentage
;
87 // The percent of time a packet is simulated as being reordered.
88 void set_fake_reorder_percentage(int32 fake_packet_reorder_percentage
) {
90 base::AutoLock
locked(config_mutex_
);
91 DCHECK(!fake_packet_delay_
.IsZero());
92 fake_packet_reorder_percentage_
= fake_packet_reorder_percentage
;
95 // The delay before writing this packet.
96 void set_fake_packet_delay(QuicTime::Delta fake_packet_delay
) {
98 base::AutoLock
locked(config_mutex_
);
99 fake_packet_delay_
= fake_packet_delay
;
102 // The maximum bandwidth and buffer size of the connection. When these are
103 // set, packets will be delayed until a connection with that bandwidth would
104 // transmit it. Once the |buffer_size| is reached, all new packets are
106 void set_max_bandwidth_and_buffer_size(QuicBandwidth fake_bandwidth
,
107 QuicByteCount buffer_size
) {
109 base::AutoLock
locked(config_mutex_
);
110 fake_bandwidth_
= fake_bandwidth
;
111 buffer_size_
= buffer_size
;
114 // Useful for reproducing very flaky issues.
115 void set_seed(uint64 seed
) {
116 simple_random_
.set_seed(seed
);
120 // Writes out the next packet to the contained writer and returns the time
121 // for the next delayed packet to be written.
122 QuicTime
ReleaseNextPacket();
124 // A single packet which will be sent at the supplied send_time.
125 struct DelayedWrite
{
127 DelayedWrite(const char* buffer
,
129 const IPAddressNumber
& self_address
,
130 const IPEndPoint
& peer_address
,
135 const IPAddressNumber self_address
;
136 const IPEndPoint peer_address
;
140 typedef std::list
<DelayedWrite
> DelayedPacketList
;
142 const QuicClock
* clock_
;
143 scoped_ptr
<QuicAlarm
> write_unblocked_alarm_
;
144 scoped_ptr
<QuicAlarm
> delay_alarm_
;
145 scoped_ptr
<Delegate
> on_can_write_
;
146 net::test::SimpleRandom simple_random_
;
147 // Stored packets delayed by fake packet delay or bandwidth restrictions.
148 DelayedPacketList delayed_packets_
;
149 QuicByteCount cur_buffer_size_
;
150 uint64 num_calls_to_write_
;
152 base::Lock config_mutex_
;
153 int32 fake_packet_loss_percentage_
;
154 int32 fake_drop_first_n_packets_
;
155 int32 fake_blocked_socket_percentage_
;
156 int32 fake_packet_reorder_percentage_
;
157 QuicTime::Delta fake_packet_delay_
;
158 QuicBandwidth fake_bandwidth_
;
159 QuicByteCount buffer_size_
;
161 DISALLOW_COPY_AND_ASSIGN(PacketDroppingTestWriter
);
168 #endif // NET_TOOLS_QUIC_TEST_TOOLS_PACKET_DROPPING_TEST_WRITER_H_