blob: 10c2c741ed864c7778be038cc182191b9fdfa56b [file] [log] [blame]
Davide Pesavento4ad933a2019-06-02 21:15:42 -04001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/*
3 * Copyright (c) 2016-2019, Regents of the University of California,
4 * Colorado State University,
5 * University Pierre & Marie Curie, Sorbonne University.
6 *
7 * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
8 *
9 * ndn-cxx library is free software: you can redistribute it and/or modify it under the
10 * terms of the GNU Lesser General Public License as published by the Free Software
11 * Foundation, either version 3 of the License, or (at your option) any later version.
12 *
13 * ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
14 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
15 * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
16 *
17 * You should have received copies of the GNU General Public License and GNU Lesser
18 * General Public License along with ndn-cxx, e.g., in COPYING.md file. If not, see
19 * <http://www.gnu.org/licenses/>.
20 *
21 * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
22 */
23
24#include "ndn-cxx/util/rtt-estimator.hpp"
25
26#include "tests/boost-test.hpp"
27
28#include <cmath>
29
30namespace ndn {
31namespace util {
32namespace tests {
33
34BOOST_AUTO_TEST_SUITE(Util)
35BOOST_AUTO_TEST_SUITE(TestRttEstimator)
36
Davide Pesavento4ad933a2019-06-02 21:15:42 -040037BOOST_AUTO_TEST_CASE(MinAvgMaxRtt)
38{
39 RttEstimator rttEstimator;
40
41 // check initial values
Davide Pesavento57a32762019-06-24 02:36:21 -040042 BOOST_CHECK_EQUAL(rttEstimator.getMinRtt().count(), std::numeric_limits<time::nanoseconds::rep>::max());
43 BOOST_CHECK_EQUAL(rttEstimator.getAvgRtt().count(), 0);
44 BOOST_CHECK_EQUAL(rttEstimator.getMaxRtt().count(), std::numeric_limits<time::nanoseconds::rep>::min());
Davide Pesavento4ad933a2019-06-02 21:15:42 -040045
46 // start with three samples
Davide Pesavento57a32762019-06-24 02:36:21 -040047 rttEstimator.addMeasurement(100_ms, 1);
48 rttEstimator.addMeasurement(400_ms, 1);
49 rttEstimator.addMeasurement(250_ms, 1);
Davide Pesavento4ad933a2019-06-02 21:15:42 -040050
Davide Pesavento57a32762019-06-24 02:36:21 -040051 BOOST_CHECK_EQUAL(rttEstimator.getMinRtt(), 100_ms);
52 BOOST_CHECK_EQUAL(rttEstimator.getAvgRtt(), 250_ms);
53 BOOST_CHECK_EQUAL(rttEstimator.getMaxRtt(), 400_ms);
Davide Pesavento4ad933a2019-06-02 21:15:42 -040054
55 // add another sample (new minimum)
Davide Pesavento57a32762019-06-24 02:36:21 -040056 rttEstimator.addMeasurement(50_ms, 2);
57 BOOST_CHECK_EQUAL(rttEstimator.getMinRtt(), 50_ms);
58 BOOST_CHECK_EQUAL(rttEstimator.getAvgRtt(), 200_ms);
59 BOOST_CHECK_EQUAL(rttEstimator.getMaxRtt(), 400_ms);
Davide Pesavento4ad933a2019-06-02 21:15:42 -040060
61 // add another sample (new maximum)
Davide Pesavento57a32762019-06-24 02:36:21 -040062 rttEstimator.addMeasurement(700_ms, 1);
63 BOOST_CHECK_EQUAL(rttEstimator.getMinRtt(), 50_ms);
64 BOOST_CHECK_EQUAL(rttEstimator.getAvgRtt(), 300_ms);
65 BOOST_CHECK_EQUAL(rttEstimator.getMaxRtt(), 700_ms);
Davide Pesavento4ad933a2019-06-02 21:15:42 -040066}
67
68BOOST_AUTO_TEST_CASE(EstimatedRto)
69{
70 RttEstimator::Options opts;
Davide Pesavento57a32762019-06-24 02:36:21 -040071 opts.initialRto = 400_ms;
72 opts.maxRto = 2_s;
Davide Pesavento4ad933a2019-06-02 21:15:42 -040073 RttEstimator rttEstimator(opts);
74
75 // check initial values
Davide Pesavento57a32762019-06-24 02:36:21 -040076 BOOST_CHECK_EQUAL(rttEstimator.getSmoothedRtt(), 0_ns);
77 BOOST_CHECK_EQUAL(rttEstimator.getRttVariation(), 0_ns);
78 BOOST_CHECK_EQUAL(rttEstimator.getEstimatedRto(), opts.initialRto);
Davide Pesavento4ad933a2019-06-02 21:15:42 -040079
80 // first measurement
Davide Pesavento57a32762019-06-24 02:36:21 -040081 rttEstimator.addMeasurement(200_ms, 1);
Davide Pesavento4ad933a2019-06-02 21:15:42 -040082
Davide Pesavento57a32762019-06-24 02:36:21 -040083 BOOST_CHECK_EQUAL(rttEstimator.getSmoothedRtt(), 200_ms);
84 BOOST_CHECK_EQUAL(rttEstimator.getRttVariation(), 100_ms);
85 BOOST_CHECK_EQUAL(rttEstimator.getEstimatedRto(), 600_ms);
Davide Pesavento4ad933a2019-06-02 21:15:42 -040086
Davide Pesavento57a32762019-06-24 02:36:21 -040087 rttEstimator.addMeasurement(100_ms, 1);
Davide Pesavento4ad933a2019-06-02 21:15:42 -040088
Davide Pesavento57a32762019-06-24 02:36:21 -040089 BOOST_CHECK_EQUAL(rttEstimator.getSmoothedRtt(), 187500_us);
90 BOOST_CHECK_EQUAL(rttEstimator.getRttVariation(), 100000_us);
91 BOOST_CHECK_EQUAL(rttEstimator.getEstimatedRto(), 587500_us);
Davide Pesavento4ad933a2019-06-02 21:15:42 -040092
93 // expected samples larger than 1
Davide Pesavento57a32762019-06-24 02:36:21 -040094 rttEstimator.addMeasurement(50_ms, 5);
Davide Pesavento4ad933a2019-06-02 21:15:42 -040095
Davide Pesavento57a32762019-06-24 02:36:21 -040096 BOOST_CHECK_EQUAL(rttEstimator.getSmoothedRtt(), 184062500_ns);
97 BOOST_CHECK_EQUAL(rttEstimator.getRttVariation(), 101875000_ns);
98 BOOST_CHECK_EQUAL(rttEstimator.getEstimatedRto(), 591562500_ns);
Davide Pesavento4ad933a2019-06-02 21:15:42 -040099
100 // check if minRto works
Davide Pesavento57a32762019-06-24 02:36:21 -0400101 for (int i = 0; i < 20; i++) {
102 rttEstimator.addMeasurement(10_ms, 1);
103 }
Davide Pesavento4ad933a2019-06-02 21:15:42 -0400104
Davide Pesavento57a32762019-06-24 02:36:21 -0400105 BOOST_CHECK_EQUAL(rttEstimator.getSmoothedRtt(), 22046646_ns);
106 BOOST_CHECK_EQUAL(rttEstimator.getEstimatedRto(), opts.minRto);
Davide Pesavento4ad933a2019-06-02 21:15:42 -0400107
108 // check if maxRto works
Davide Pesavento57a32762019-06-24 02:36:21 -0400109 for (int i = 0; i < 10; i++) {
110 rttEstimator.addMeasurement(1_s, 1);
111 rttEstimator.addMeasurement(10_ms, 1);
112 }
Davide Pesavento4ad933a2019-06-02 21:15:42 -0400113
Davide Pesavento57a32762019-06-24 02:36:21 -0400114 BOOST_CHECK_EQUAL(rttEstimator.getSmoothedRtt(), 440859284_ns);
115 BOOST_CHECK_EQUAL(rttEstimator.getEstimatedRto(), opts.maxRto);
Davide Pesavento4ad933a2019-06-02 21:15:42 -0400116}
117
118BOOST_AUTO_TEST_CASE(BackoffRto)
119{
120 RttEstimator::Options opts;
Davide Pesavento57a32762019-06-24 02:36:21 -0400121 opts.initialRto = 500_ms;
122 opts.maxRto = 4_s;
Davide Pesavento4ad933a2019-06-02 21:15:42 -0400123 RttEstimator rttEstimator(opts);
124
125 rttEstimator.backoffRto();
Davide Pesavento57a32762019-06-24 02:36:21 -0400126 BOOST_CHECK_EQUAL(rttEstimator.getEstimatedRto(), 1_s);
Davide Pesavento4ad933a2019-06-02 21:15:42 -0400127
128 // check if minRto works
Davide Pesavento57a32762019-06-24 02:36:21 -0400129 for (int i = 0; i < 10; i++) {
130 rttEstimator.addMeasurement(5_ms, 1);
131 }
Davide Pesavento4ad933a2019-06-02 21:15:42 -0400132 rttEstimator.backoffRto();
Davide Pesavento57a32762019-06-24 02:36:21 -0400133 BOOST_CHECK_EQUAL(rttEstimator.getEstimatedRto(), 400_ms);
Davide Pesavento4ad933a2019-06-02 21:15:42 -0400134
135 // check if maxRto works
Davide Pesavento57a32762019-06-24 02:36:21 -0400136 for (int i = 0; i < 10; i++) {
137 rttEstimator.addMeasurement(5_s, 1);
138 }
Davide Pesavento4ad933a2019-06-02 21:15:42 -0400139 rttEstimator.backoffRto();
Davide Pesavento57a32762019-06-24 02:36:21 -0400140 BOOST_CHECK_EQUAL(rttEstimator.getEstimatedRto(), 4_s);
Davide Pesavento4ad933a2019-06-02 21:15:42 -0400141}
142
143BOOST_AUTO_TEST_CASE(AfterMeasurement)
144{
145 RttEstimator rttEstimator;
146
147 int nHandlerInvocations = 0;
148 rttEstimator.afterMeasurement.connectSingleShot([&nHandlerInvocations] (const auto& sample) {
149 ++nHandlerInvocations;
Davide Pesavento57a32762019-06-24 02:36:21 -0400150 BOOST_CHECK_EQUAL(sample.rtt, 80_ms);
151 BOOST_CHECK_EQUAL(sample.sRtt, 80_ms);
152 BOOST_CHECK_EQUAL(sample.rttVar, 40_ms);
153 BOOST_CHECK_EQUAL(sample.rto, 240_ms);
Davide Pesavento4ad933a2019-06-02 21:15:42 -0400154 BOOST_CHECK(!sample.segNum.has_value());
155 });
Davide Pesavento57a32762019-06-24 02:36:21 -0400156 rttEstimator.addMeasurement(80_ms, 1);
Davide Pesavento4ad933a2019-06-02 21:15:42 -0400157 BOOST_CHECK_EQUAL(nHandlerInvocations, 1);
158
159 rttEstimator.afterMeasurement.connectSingleShot([&nHandlerInvocations] (const auto& sample) {
160 ++nHandlerInvocations;
Davide Pesavento57a32762019-06-24 02:36:21 -0400161 BOOST_CHECK_EQUAL(sample.rtt, 40_ms);
162 BOOST_CHECK_EQUAL(sample.sRtt, 75_ms);
163 BOOST_CHECK_EQUAL(sample.rttVar, 40_ms);
164 BOOST_CHECK_EQUAL(sample.rto, 235_ms);
Davide Pesavento4ad933a2019-06-02 21:15:42 -0400165 BOOST_CHECK(sample.segNum == 42U);
166 });
Davide Pesavento57a32762019-06-24 02:36:21 -0400167 rttEstimator.addMeasurement(40_ms, 1, 42);
Davide Pesavento4ad933a2019-06-02 21:15:42 -0400168 BOOST_CHECK_EQUAL(nHandlerInvocations, 2);
169}
170
171BOOST_AUTO_TEST_SUITE_END() // TestRttEstimator
172BOOST_AUTO_TEST_SUITE_END() // Util
173
174} // namespace tests
175} // namespace util
176} // namespace ndn