test_cubic.c revision f07b3eae
1/* Copyright (c) 2017 - 2021 LiteSpeed Technologies Inc.  See LICENSE. */
2#include <assert.h>
3#include <stdio.h>
4#include <stdlib.h>
5#include <string.h>
6#include <sys/queue.h>
7#ifndef WIN32
8#include <unistd.h>
9#else
10#include <getopt.h>
11#endif
12
13#include "lsquic.h"
14#include "lsquic_int_types.h"
15#include "lsquic_cong_ctl.h"
16#include "lsquic_cubic.h"
17#include "lsquic_logger.h"
18#include "lsquic_hash.h"
19#include "lsquic_conn.h"
20#include "lsquic_sfcw.h"
21#include "lsquic_conn_flow.h"
22#include "lsquic_varint.h"
23#include "lsquic_hq.h"
24#include "lsquic_stream.h"
25#include "lsquic_rtt.h"
26#include "lsquic_conn_public.h"
27#include "lsquic_packet_common.h"
28#include "lsquic_packet_out.h"
29
30//static const struct cong_ctl_if *const cci = &lsquic_cong_cubic_if; // will not work on MSVC
31#define cci ((const struct cong_ctl_if *const)&lsquic_cong_cubic_if)
32
33static void
34test_post_quiescence_explosion (void)
35{
36    struct lsquic_cubic cubic;
37    lsquic_time_t const rtt = 10000;
38    lsquic_time_t t = 12345600;
39    struct lsquic_conn lconn = LSCONN_INITIALIZER_CIDLEN(lconn, 8);
40    struct lsquic_conn_public conn_pub = { .lconn = &lconn, };
41    int i;
42    struct lsquic_packet_out packet_out; memset(&packet_out, 0, sizeof(packet_out));
43
44    cci->cci_init(&cubic, &conn_pub, 0);
45    cubic.cu_ssthresh = cubic.cu_cwnd = 32 * 1370;
46
47    for (i = 0; i < 10; ++i)
48    {
49        packet_out.po_sent = t - rtt;
50        cci->cci_ack(&cubic, &packet_out, 1370, t, 0);
51    }
52
53    assert(cci->cci_get_cwnd(&cubic) == 47026);
54
55    t += 25 * 1000 * 1000;
56    cci->cci_was_quiet(&cubic, t, 0 /* bytes in flight (unused) */);
57    packet_out.po_sent = t - rtt;
58    cci->cci_ack(&cubic, &packet_out, 1370, t, 0);
59    assert(cci->cci_get_cwnd(&cubic) == 47060);
60
61    t += 2 * 1000 * 1000;
62    packet_out.po_sent = t - rtt;
63    cci->cci_ack(&cubic, &packet_out, 1370, t, 0);
64}
65
66
67static void
68test_post_quiescence_explosion2 (void)
69{
70    struct lsquic_cubic cubic;
71    lsquic_time_t const rtt = 10000;
72    lsquic_time_t t = 12345600;
73    struct lsquic_conn lconn = LSCONN_INITIALIZER_CIDLEN(lconn, 8);
74    struct lsquic_conn_public conn_pub = { .lconn = &lconn, };
75    int i;
76    struct lsquic_packet_out packet_out; memset(&packet_out, 0, sizeof(packet_out));
77
78    cci->cci_init(&cubic, &conn_pub, 0);
79    cubic.cu_ssthresh = cubic.cu_cwnd = 32 * 1370;
80
81    for (i = 0; i < 10; ++i)
82    {
83        packet_out.po_sent = t - rtt;
84        cci->cci_ack(&cubic, &packet_out, 1370, t, 1);
85    }
86
87    assert(cci->cci_get_cwnd(&cubic) == 45300);
88
89    t += 25 * 1000 * 1000;
90    cci->cci_was_quiet(&cubic, t, 0 /* bytes in flight (unused) */);
91    packet_out.po_sent = t - rtt;
92    cci->cci_ack(&cubic, &packet_out, 1370, t, 0);
93    assert(cci->cci_get_cwnd(&cubic) == 46754);
94
95    t += 2 * 1000 * 1000;
96    packet_out.po_sent = t - rtt;
97    cci->cci_ack(&cubic, &packet_out, 1370, t, 1);
98}
99
100
101
102int
103main (int argc, char **argv)
104{
105    int opt;
106
107    lsquic_log_to_fstream(stderr, LLTS_NONE);
108
109    while (-1 != (opt = getopt(argc, argv, "l:")))
110    {
111        switch (opt)
112        {
113        case 'l':
114            lsquic_logger_lopt(optarg);
115            break;
116        default:
117            exit(EXIT_FAILURE);
118            break;
119        }
120    }
121
122    test_post_quiescence_explosion();
123    test_post_quiescence_explosion2();
124
125    exit(EXIT_SUCCESS);
126}
127