summaryrefslogtreecommitdiffstats
path: root/jingle
diff options
context:
space:
mode:
Diffstat (limited to 'jingle')
-rw-r--r--jingle/glue/pseudotcp_adapter_unittest.cc73
1 files changed, 64 insertions, 9 deletions
diff --git a/jingle/glue/pseudotcp_adapter_unittest.cc b/jingle/glue/pseudotcp_adapter_unittest.cc
index a2117ea..12a6dbe 100644
--- a/jingle/glue/pseudotcp_adapter_unittest.cc
+++ b/jingle/glue/pseudotcp_adapter_unittest.cc
@@ -36,16 +36,57 @@ const int kMessageSize = 1024;
const int kMessages = 100;
const int kTestDataSize = kMessages * kMessageSize;
+class RateLimiter {
+ public:
+ virtual ~RateLimiter() { };
+ // Returns true if the new packet needs to be dropped, false otherwise.
+ virtual bool DropNextPacket() = 0;
+};
+
+class LeakyBucket : public RateLimiter {
+ public:
+ // |rate| is in drops per second.
+ LeakyBucket(double volume, double rate)
+ : volume_(volume),
+ rate_(rate),
+ level_(0.0),
+ last_update_(base::TimeTicks::HighResNow()) {
+ }
+
+ virtual ~LeakyBucket() { }
+
+ virtual bool DropNextPacket() OVERRIDE {
+ base::TimeTicks now = base::TimeTicks::HighResNow();
+ double interval = (now - last_update_).InSecondsF();
+ last_update_ = now;
+ level_ = level_ + 1.0 - interval * rate_;
+ if (level_ > volume_) {
+ level_ = volume_;
+ return true;
+ } else if (level_ < 0.0) {
+ level_ = 0.0;
+ }
+ return false;
+ }
+
+ private:
+ double volume_;
+ double rate_;
+ double level_;
+ base::TimeTicks last_update_;
+};
+
class FakeSocket : public net::Socket {
public:
FakeSocket()
: read_callback_(NULL),
- loss_rate_(0.0) {
+ rate_limiter_(NULL),
+ latency_ms_(0) {
}
virtual ~FakeSocket() { }
void AppendInputPacket(const std::vector<char>& data) {
- if ((static_cast<double>(rand()) / RAND_MAX) < loss_rate_)
+ if (rate_limiter_ && rate_limiter_->DropNextPacket())
return; // Lose the packet.
if (read_callback_) {
@@ -64,7 +105,11 @@ class FakeSocket : public net::Socket {
peer_socket_ = peer_socket;
}
- void set_loss_rate(double value) { loss_rate_ = value; };
+ void set_rate_limiter(RateLimiter* rate_limiter) {
+ rate_limiter_ = rate_limiter;
+ };
+
+ void set_latency(int latency_ms) { latency_ms_ = latency_ms; };
// net::Socket interface.
virtual int Read(net::IOBuffer* buf, int buf_len,
@@ -91,9 +136,9 @@ class FakeSocket : public net::Socket {
net::CompletionCallback* callback) OVERRIDE {
DCHECK(buf);
if (peer_socket_) {
- MessageLoop::current()->PostTask(FROM_HERE, NewRunnableMethod(
+ MessageLoop::current()->PostDelayedTask(FROM_HERE, NewRunnableMethod(
peer_socket_, &FakeSocket::AppendInputPacket,
- std::vector<char>(buf->data(), buf->data() + buf_len)));
+ std::vector<char>(buf->data(), buf->data() + buf_len)), latency_ms_);
}
return buf_len;
@@ -116,7 +161,8 @@ class FakeSocket : public net::Socket {
std::deque<std::vector<char> > incoming_packets_;
FakeSocket* peer_socket_;
- double loss_rate_;
+ RateLimiter* rate_limiter_;
+ int latency_ms_;
};
class TCPChannelTester : public base::RefCountedThreadSafe<TCPChannelTester> {
@@ -298,9 +344,18 @@ TEST_F(PseudoTcpAdapterTest, DataTransfer) {
tester->CheckResults();
}
-TEST_F(PseudoTcpAdapterTest, LossyChannel) {
- host_socket_->set_loss_rate(0.1);
- client_socket_->set_loss_rate(0.1);
+TEST_F(PseudoTcpAdapterTest, LimitedChannel) {
+ const int kLatencyMs = 20;
+ const int kPacketsPerSecond = 400;
+ const int kBurstPackets = 10;
+
+ LeakyBucket host_limiter(kBurstPackets, kPacketsPerSecond);
+ host_socket_->set_latency(kLatencyMs);
+ host_socket_->set_rate_limiter(&host_limiter);
+
+ LeakyBucket client_limiter(kBurstPackets, kPacketsPerSecond);
+ host_socket_->set_latency(kLatencyMs);
+ client_socket_->set_rate_limiter(&client_limiter);
TestCompletionCallback host_connect_cb;
TestCompletionCallback client_connect_cb;