add .gitignore
[swift-upb.git] / tests / congctrltest.cpp
1 /*
2  *  congctrltest.cpp
3  *  p2tp
4  *
5  *  Created by Victor Grishchenko on 7/13/09.
6  *  Copyright 2009 Delft University of Technology. All rights reserved.
7  *
8  */
9 #include <stdint.h>
10 #include <queue>
11 #include <gtest/gtest.h>
12 #include <glog/logging.h>
13 #include "p2tp.h"
14
15 using namespace std;
16 using namespace p2tp;
17
18 class SimPeer;
19
20 struct SimPacket {
21     SimPacket(int from, int to, const SimPacket* toack, bool data) ;
22     int peerfrom, peerto;
23     tint datatime;
24     tint acktime;
25     tint arrivaltime;
26 };
27
28 tint now = 0;
29
30 /** very simplified; uplink is the bottleneck */
31 class SimPeer {
32 public:
33     SimPeer (tint tt, tint lt, int qlen) : travtime(tt), latency(lt), queue_length(qlen) {}
34     int queue_length;
35     int travtime;
36     tint freetime;
37     tint latency;
38     int unackd;
39     int rcvd, sent;
40     queue<SimPacket> packet_queue;
41     queue<SimPacket> dropped_queue;
42     CongestionControl congc;
43     
44     void send(SimPacket pck) {
45         if (packet_queue.size()==queue_length) {
46             dropped_queue.push(pck);
47             return;
48         }
49         tint start = max(now,freetime);
50         tint done = pck.datatime ? start+travtime : start;
51         freetime = done;
52         pck.arrivaltime = done + latency;
53         packet_queue.push(pck);
54     }
55     
56     SimPacket recv () {
57         assert(!packet_queue.empty());
58         SimPacket ret = packet_queue.front();
59         packet_queue.pop();
60         return ret;
61     }
62     
63     tint next_recv_time () const {
64         return packet_queue.empty() ? NEVER : packet_queue.front().arrivaltime;
65     }
66     
67     void    turn () {
68         SimPacket rp = recv();
69         SimPacket reply;
70         now = rp.arrivaltime;
71         if (rp.acktime) {
72             congc.RttSample(rp.arrivaltime-rp.acktime);
73             congc.OnCongestionEvent(CongestionControl::ACK_EV);
74             unackd--;
75             rcvd++;
76         }
77         if (rp.datatime) {
78             congc.OnCongestionEvent(CongestionControl::DATA_EV);
79             reply.acktime = reply.datatime;
80         }
81         if (!dropped_queue.empty() && dropped_queue.top().datatime<now+THR)
82             congc.OnCongestionEvent(CongestionControl::LOSS_EV);
83         if (congc.cwnd()>unackd) {
84             unackd++;
85             reply.datatime = now;
86             sent++;
87         }
88         rp.from->send(reply);
89     }
90 };
91
92 TEST(P2TP, TailDropTest) {
93     // two peers exchange packets over 100ms link with tail-drop discipline
94     // bw 1Mbits => travel time of 1KB is ~10ms
95     SimPeer a(10*MSEC,100*MSEC,20), b(10*MSEC,100*MSEC,20);
96     a.send(SimPacket(&b,now,0,0));
97     while (now<60*60*SEC) 
98         if (a.next_recv_time()<b.next_recv_time())
99             a.turn();
100         else
101             b.turn();
102 }
103
104 int main (int argc, char** argv) {
105         bin::init();
106         bins::init();
107         google::InitGoogleLogging(argv[0]);
108         testing::InitGoogleTest(&argc, argv);
109         return RUN_ALL_TESTS();
110         
111 }