#ifndef NET_TOOLS_QUIC_TEST_TOOLS_PACKET_DROPPING_TEST_WRITER_H_
#define NET_TOOLS_QUIC_TEST_TOOLS_PACKET_DROPPING_TEST_WRITER_H_
#include <list>
#include "base/basictypes.h"
#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
#include "base/synchronization/lock.h"
#include "net/quic/quic_alarm.h"
#include "net/tools/quic/quic_epoll_clock.h"
#include "net/tools/quic/quic_packet_writer_wrapper.h"
#include "net/tools/quic/test_tools/quic_test_client.h"
#include "net/tools/quic/test_tools/quic_test_utils.h"
namespace net {
namespace tools {
namespace test {
class PacketDroppingTestWriter : public QuicPacketWriterWrapper {
public:
class Delegate {
public:
virtual ~Delegate() {}
virtual void OnCanWrite() = 0;
};
PacketDroppingTestWriter();
virtual ~PacketDroppingTestWriter();
void Initialize(QuicEpollConnectionHelper* helper, Delegate* on_can_write);
virtual WriteResult WritePacket(
const char* buffer,
size_t buf_len,
const IPAddressNumber& self_address,
const IPEndPoint& peer_address) OVERRIDE;
virtual bool IsWriteBlocked() const OVERRIDE;
virtual void SetWritable() OVERRIDE;
QuicTime ReleaseOldPackets();
void OnCanWrite();
void set_fake_packet_loss_percentage(int32 fake_packet_loss_percentage) {
base::AutoLock locked(config_mutex_);
fake_packet_loss_percentage_ = fake_packet_loss_percentage;
}
void set_fake_blocked_socket_percentage(
int32 fake_blocked_socket_percentage) {
DCHECK(clock_);
base::AutoLock locked(config_mutex_);
fake_blocked_socket_percentage_ = fake_blocked_socket_percentage;
}
void set_fake_reorder_percentage(int32 fake_packet_reorder_percentage) {
DCHECK(clock_);
base::AutoLock locked(config_mutex_);
DCHECK(!fake_packet_delay_.IsZero());
fake_packet_reorder_percentage_ = fake_packet_reorder_percentage;
}
void set_fake_packet_delay(QuicTime::Delta fake_packet_delay) {
DCHECK(clock_);
base::AutoLock locked(config_mutex_);
fake_packet_delay_ = fake_packet_delay;
}
void set_max_bandwidth_and_buffer_size(QuicBandwidth fake_bandwidth,
QuicByteCount buffer_size) {
DCHECK(clock_);
base::AutoLock locked(config_mutex_);
fake_bandwidth_ = fake_bandwidth;
buffer_size_ = buffer_size;
}
void set_seed(uint64 seed) {
simple_random_.set_seed(seed);
}
private:
QuicTime ReleaseNextPacket();
struct DelayedWrite {
public:
DelayedWrite(const char* buffer,
size_t buf_len,
const IPAddressNumber& self_address,
const IPEndPoint& peer_address,
QuicTime send_time);
~DelayedWrite();
string buffer;
const IPAddressNumber self_address;
const IPEndPoint peer_address;
QuicTime send_time;
};
typedef std::list<DelayedWrite> DelayedPacketList;
const QuicClock* clock_;
scoped_ptr<QuicAlarm> write_unblocked_alarm_;
scoped_ptr<QuicAlarm> delay_alarm_;
scoped_ptr<Delegate> on_can_write_;
SimpleRandom simple_random_;
DelayedPacketList delayed_packets_;
QuicByteCount cur_buffer_size_;
base::Lock config_mutex_;
int32 fake_packet_loss_percentage_;
int32 fake_blocked_socket_percentage_;
int32 fake_packet_reorder_percentage_;
QuicTime::Delta fake_packet_delay_;
QuicBandwidth fake_bandwidth_;
QuicByteCount buffer_size_;
DISALLOW_COPY_AND_ASSIGN(PacketDroppingTestWriter);
};
}
}
}
#endif