Home | History | Annotate | Download | only in test
      1 /*
      2  *  Copyright (c) 2015 The WebRTC project authors. All Rights Reserved.
      3  *
      4  *  Use of this source code is governed by a BSD-style license
      5  *  that can be found in the LICENSE file in the root of the source
      6  *  tree. An additional intellectual property rights grant can be found
      7  *  in the file PATENTS.  All contributing project authors may
      8  *  be found in the AUTHORS file in the root of the source tree.
      9  */
     10 
     11 #include "webrtc/modules/remote_bitrate_estimator/test/bwe.h"
     12 
     13 #include <vector>
     14 
     15 #include "testing/gtest/include/gtest/gtest.h"
     16 #include "webrtc/base/arraysize.h"
     17 
     18 namespace webrtc {
     19 namespace testing {
     20 namespace bwe {
     21 
     22 const int kSetCapacity = 1000;
     23 
     24 class LinkedSetTest : public ::testing::Test {
     25  public:
     26   LinkedSetTest() : linked_set_(kSetCapacity) {}
     27 
     28   ~LinkedSetTest() {}
     29 
     30  protected:
     31   LinkedSet linked_set_;
     32 };
     33 
     34 TEST_F(LinkedSetTest, EmptySet) {
     35   EXPECT_EQ(linked_set_.OldestSeqNumber(), 0);
     36   EXPECT_EQ(linked_set_.NewestSeqNumber(), 0);
     37 }
     38 
     39 TEST_F(LinkedSetTest, SinglePacket) {
     40   const uint16_t kSeqNumber = 1;  // Arbitrary.
     41   // Other parameters don't matter here.
     42   linked_set_.Insert(kSeqNumber, 0, 0, 0);
     43 
     44   EXPECT_EQ(linked_set_.OldestSeqNumber(), kSeqNumber);
     45   EXPECT_EQ(linked_set_.NewestSeqNumber(), kSeqNumber);
     46 }
     47 
     48 TEST_F(LinkedSetTest, MultiplePackets) {
     49   const uint16_t kNumberPackets = 100;
     50 
     51   std::vector<uint16_t> sequence_numbers;
     52   for (size_t i = 0; i < kNumberPackets; ++i) {
     53     sequence_numbers.push_back(static_cast<uint16_t>(i + 1));
     54   }
     55   random_shuffle(sequence_numbers.begin(), sequence_numbers.end());
     56 
     57   for (size_t i = 0; i < kNumberPackets; ++i) {
     58     // Other parameters don't matter here.
     59     linked_set_.Insert(static_cast<uint16_t>(i), 0, 0, 0);
     60   }
     61 
     62   // Packets arriving out of order should not affect the following values:
     63   EXPECT_EQ(linked_set_.OldestSeqNumber(), 0);
     64   EXPECT_EQ(linked_set_.NewestSeqNumber(), kNumberPackets - 1);
     65 }
     66 
     67 TEST_F(LinkedSetTest, Overflow) {
     68   const int kFirstSeqNumber = -100;
     69   const int kLastSeqNumber = 100;
     70 
     71   for (int i = kFirstSeqNumber; i <= kLastSeqNumber; ++i) {
     72     // Other parameters don't matter here.
     73     linked_set_.Insert(static_cast<uint16_t>(i), 0, 0, 0);
     74   }
     75 
     76   // Packets arriving out of order should not affect the following values:
     77   EXPECT_EQ(linked_set_.OldestSeqNumber(),
     78             static_cast<uint16_t>(kFirstSeqNumber));
     79   EXPECT_EQ(linked_set_.NewestSeqNumber(),
     80             static_cast<uint16_t>(kLastSeqNumber));
     81 }
     82 
     83 class SequenceNumberOlderThanTest : public ::testing::Test {
     84  public:
     85   SequenceNumberOlderThanTest() {}
     86   ~SequenceNumberOlderThanTest() {}
     87 
     88  protected:
     89   SequenceNumberOlderThan comparator_;
     90 };
     91 
     92 TEST_F(SequenceNumberOlderThanTest, Operator) {
     93   // Operator()(x, y) returns true <==> y is newer than x.
     94   EXPECT_TRUE(comparator_.operator()(0x0000, 0x0001));
     95   EXPECT_TRUE(comparator_.operator()(0x0001, 0x1000));
     96   EXPECT_FALSE(comparator_.operator()(0x0001, 0x0000));
     97   EXPECT_FALSE(comparator_.operator()(0x0002, 0x0002));
     98   EXPECT_TRUE(comparator_.operator()(0xFFF6, 0x000A));
     99   EXPECT_FALSE(comparator_.operator()(0x000A, 0xFFF6));
    100   EXPECT_TRUE(comparator_.operator()(0x0000, 0x8000));
    101   EXPECT_FALSE(comparator_.operator()(0x8000, 0x0000));
    102 }
    103 
    104 class LossAccountTest : public ::testing::Test {
    105  public:
    106   LossAccountTest() {}
    107   ~LossAccountTest() {}
    108 
    109  protected:
    110   LossAccount loss_account_;
    111 };
    112 
    113 TEST_F(LossAccountTest, Operations) {
    114   const size_t kTotal = 100;  // Arbitrary values.
    115   const size_t kLost = 10;
    116 
    117   LossAccount rhs(kTotal, kLost);
    118 
    119   loss_account_.Add(rhs);
    120   EXPECT_EQ(loss_account_.num_total, kTotal);
    121   EXPECT_EQ(loss_account_.num_lost, kLost);
    122   EXPECT_NEAR(loss_account_.LossRatio(), static_cast<float>(kLost) / kTotal,
    123               0.001f);
    124 
    125   loss_account_.Subtract(rhs);
    126   EXPECT_EQ(loss_account_.num_total, 0UL);
    127   EXPECT_EQ(loss_account_.num_lost, 0UL);
    128   EXPECT_NEAR(loss_account_.LossRatio(), 0.0f, 0.001f);
    129 }
    130 
    131 class BweReceiverTest : public ::testing::Test {
    132  public:
    133   BweReceiverTest() : bwe_receiver_(kFlowId) {}
    134   ~BweReceiverTest() {}
    135 
    136  protected:
    137   const int kFlowId = 1;  // Arbitrary.
    138   BweReceiver bwe_receiver_;
    139 };
    140 
    141 TEST_F(BweReceiverTest, ReceivingRateNoPackets) {
    142   EXPECT_EQ(bwe_receiver_.RecentKbps(), static_cast<size_t>(0));
    143 }
    144 
    145 TEST_F(BweReceiverTest, ReceivingRateSinglePacket) {
    146   const size_t kPayloadSizeBytes = 500 * 1000;
    147   const int64_t kSendTimeUs = 300 * 1000;
    148   const int64_t kArrivalTimeMs = kSendTimeUs / 1000 + 100;
    149   const uint16_t kSequenceNumber = 1;
    150   const int64_t kTimeWindowMs = BweReceiver::kReceivingRateTimeWindowMs;
    151 
    152   const MediaPacket media_packet(kFlowId, kSendTimeUs, kPayloadSizeBytes,
    153                                  kSequenceNumber);
    154   bwe_receiver_.ReceivePacket(kArrivalTimeMs, media_packet);
    155 
    156   const size_t kReceivingRateKbps = 8 * kPayloadSizeBytes / kTimeWindowMs;
    157 
    158   EXPECT_NEAR(bwe_receiver_.RecentKbps(), kReceivingRateKbps,
    159               static_cast<float>(kReceivingRateKbps) / 100.0f);
    160 }
    161 
    162 TEST_F(BweReceiverTest, ReceivingRateSmallPackets) {
    163   const size_t kPayloadSizeBytes = 100 * 1000;
    164   const int64_t kTimeGapMs = 50;  // Between each packet.
    165   const int64_t kOneWayDelayMs = 50;
    166 
    167   for (int i = 1; i < 50; ++i) {
    168     int64_t send_time_us = i * kTimeGapMs * 1000;
    169     int64_t arrival_time_ms = send_time_us / 1000 + kOneWayDelayMs;
    170     uint16_t sequence_number = i;
    171     const MediaPacket media_packet(kFlowId, send_time_us, kPayloadSizeBytes,
    172                                    sequence_number);
    173     bwe_receiver_.ReceivePacket(arrival_time_ms, media_packet);
    174   }
    175 
    176   const size_t kReceivingRateKbps = 8 * kPayloadSizeBytes / kTimeGapMs;
    177   EXPECT_NEAR(bwe_receiver_.RecentKbps(), kReceivingRateKbps,
    178               static_cast<float>(kReceivingRateKbps) / 100.0f);
    179 }
    180 
    181 TEST_F(BweReceiverTest, PacketLossNoPackets) {
    182   EXPECT_EQ(bwe_receiver_.RecentPacketLossRatio(), 0.0f);
    183 }
    184 
    185 TEST_F(BweReceiverTest, PacketLossSinglePacket) {
    186   const MediaPacket media_packet(kFlowId, 0, 0, 0);
    187   bwe_receiver_.ReceivePacket(0, media_packet);
    188   EXPECT_EQ(bwe_receiver_.RecentPacketLossRatio(), 0.0f);
    189 }
    190 
    191 TEST_F(BweReceiverTest, PacketLossContiguousPackets) {
    192   const int64_t kTimeWindowMs = BweReceiver::kPacketLossTimeWindowMs;
    193   size_t set_capacity = bwe_receiver_.GetSetCapacity();
    194 
    195   for (int i = 0; i < 10; ++i) {
    196     uint16_t sequence_number = static_cast<uint16_t>(i);
    197     // Sequence_number and flow_id are the only members that matter here.
    198     const MediaPacket media_packet(kFlowId, 0, 0, sequence_number);
    199     // Arrival time = 0, all packets will be considered.
    200     bwe_receiver_.ReceivePacket(0, media_packet);
    201   }
    202   EXPECT_EQ(bwe_receiver_.RecentPacketLossRatio(), 0.0f);
    203 
    204   for (int i = 30; i > 20; i--) {
    205     uint16_t sequence_number = static_cast<uint16_t>(i);
    206     // Sequence_number and flow_id are the only members that matter here.
    207     const MediaPacket media_packet(kFlowId, 0, 0, sequence_number);
    208     // Only the packets sent in this for loop will be considered.
    209     bwe_receiver_.ReceivePacket(2 * kTimeWindowMs, media_packet);
    210   }
    211   EXPECT_EQ(bwe_receiver_.RecentPacketLossRatio(), 0.0f);
    212 
    213   // Should handle uint16_t overflow.
    214   for (int i = 0xFFFF - 10; i < 0xFFFF + 10; ++i) {
    215     uint16_t sequence_number = static_cast<uint16_t>(i);
    216     const MediaPacket media_packet(kFlowId, 0, 0, sequence_number);
    217     // Only the packets sent in this for loop will be considered.
    218     bwe_receiver_.ReceivePacket(4 * kTimeWindowMs, media_packet);
    219   }
    220   EXPECT_EQ(bwe_receiver_.RecentPacketLossRatio(), 0.0f);
    221 
    222   // Should handle set overflow.
    223   for (int i = 0; i < set_capacity * 1.5; ++i) {
    224     uint16_t sequence_number = static_cast<uint16_t>(i);
    225     const MediaPacket media_packet(kFlowId, 0, 0, sequence_number);
    226     // Only the packets sent in this for loop will be considered.
    227     bwe_receiver_.ReceivePacket(6 * kTimeWindowMs, media_packet);
    228   }
    229   EXPECT_EQ(bwe_receiver_.RecentPacketLossRatio(), 0.0f);
    230 }
    231 
    232 // Should handle duplicates.
    233 TEST_F(BweReceiverTest, PacketLossDuplicatedPackets) {
    234   const int64_t kTimeWindowMs = BweReceiver::kPacketLossTimeWindowMs;
    235 
    236   for (int i = 0; i < 10; ++i) {
    237     const MediaPacket media_packet(kFlowId, 0, 0, 0);
    238     // Arrival time = 0, all packets will be considered.
    239     bwe_receiver_.ReceivePacket(0, media_packet);
    240   }
    241   EXPECT_EQ(bwe_receiver_.RecentPacketLossRatio(), 0.0f);
    242 
    243   // Missing the element 5.
    244   const uint16_t kSequenceNumbers[] = {1, 2, 3, 4, 6, 7, 8};
    245   const int kNumPackets = arraysize(kSequenceNumbers);
    246 
    247   // Insert each sequence number twice.
    248   for (int i = 0; i < 2; ++i) {
    249     for (int j = 0; j < kNumPackets; j++) {
    250       const MediaPacket media_packet(kFlowId, 0, 0, kSequenceNumbers[j]);
    251       // Only the packets sent in this for loop will be considered.
    252       bwe_receiver_.ReceivePacket(2 * kTimeWindowMs, media_packet);
    253     }
    254   }
    255 
    256   EXPECT_NEAR(bwe_receiver_.RecentPacketLossRatio(), 1.0f / (kNumPackets + 1),
    257               0.1f / (kNumPackets + 1));
    258 }
    259 
    260 TEST_F(BweReceiverTest, PacketLossLakingPackets) {
    261   size_t set_capacity = bwe_receiver_.GetSetCapacity();
    262   EXPECT_LT(set_capacity, static_cast<size_t>(0xFFFF));
    263 
    264   // Missing every other packet.
    265   for (size_t i = 0; i < set_capacity; ++i) {
    266     if ((i & 1) == 0) {  // Only even sequence numbers.
    267       uint16_t sequence_number = static_cast<uint16_t>(i);
    268       const MediaPacket media_packet(kFlowId, 0, 0, sequence_number);
    269       // Arrival time = 0, all packets will be considered.
    270       bwe_receiver_.ReceivePacket(0, media_packet);
    271     }
    272   }
    273   EXPECT_NEAR(bwe_receiver_.RecentPacketLossRatio(), 0.5f, 0.01f);
    274 }
    275 
    276 TEST_F(BweReceiverTest, PacketLossLakingFewPackets) {
    277   size_t set_capacity = bwe_receiver_.GetSetCapacity();
    278   EXPECT_LT(set_capacity, static_cast<size_t>(0xFFFF));
    279 
    280   const int kPeriod = 100;
    281   // Missing one for each kPeriod packets.
    282   for (size_t i = 0; i < set_capacity; ++i) {
    283     if ((i % kPeriod) != 0) {
    284       uint16_t sequence_number = static_cast<uint16_t>(i);
    285       const MediaPacket media_packet(kFlowId, 0, 0, sequence_number);
    286       // Arrival time = 0, all packets will be considered.
    287       bwe_receiver_.ReceivePacket(0, media_packet);
    288     }
    289   }
    290   EXPECT_NEAR(bwe_receiver_.RecentPacketLossRatio(), 1.0f / kPeriod,
    291               0.1f / kPeriod);
    292 }
    293 
    294 // Packet's sequence numbers greatly apart, expect high loss.
    295 TEST_F(BweReceiverTest, PacketLossWideGap) {
    296   const int64_t kTimeWindowMs = BweReceiver::kPacketLossTimeWindowMs;
    297 
    298   const MediaPacket media_packet1(0, 0, 0, 1);
    299   const MediaPacket media_packet2(0, 0, 0, 1000);
    300   // Only these two packets will be considered.
    301   bwe_receiver_.ReceivePacket(0, media_packet1);
    302   bwe_receiver_.ReceivePacket(0, media_packet2);
    303   EXPECT_NEAR(bwe_receiver_.RecentPacketLossRatio(), 0.998f, 0.0001f);
    304 
    305   const MediaPacket media_packet3(0, 0, 0, 0);
    306   const MediaPacket media_packet4(0, 0, 0, 0x8000);
    307   // Only these two packets will be considered.
    308   bwe_receiver_.ReceivePacket(2 * kTimeWindowMs, media_packet3);
    309   bwe_receiver_.ReceivePacket(2 * kTimeWindowMs, media_packet4);
    310   EXPECT_NEAR(bwe_receiver_.RecentPacketLossRatio(), 0.99994f, 0.00001f);
    311 }
    312 
    313 // Packets arriving unordered should not be counted as losted.
    314 TEST_F(BweReceiverTest, PacketLossUnorderedPackets) {
    315   size_t num_packets = bwe_receiver_.GetSetCapacity() / 2;
    316   std::vector<uint16_t> sequence_numbers;
    317 
    318   for (size_t i = 0; i < num_packets; ++i) {
    319     sequence_numbers.push_back(static_cast<uint16_t>(i + 1));
    320   }
    321 
    322   random_shuffle(sequence_numbers.begin(), sequence_numbers.end());
    323 
    324   for (size_t i = 0; i < num_packets; ++i) {
    325     const MediaPacket media_packet(kFlowId, 0, 0, sequence_numbers[i]);
    326     // Arrival time = 0, all packets will be considered.
    327     bwe_receiver_.ReceivePacket(0, media_packet);
    328   }
    329 
    330   EXPECT_EQ(bwe_receiver_.RecentPacketLossRatio(), 0.0f);
    331 }
    332 
    333 TEST_F(BweReceiverTest, RecentKbps) {
    334   EXPECT_EQ(bwe_receiver_.RecentKbps(), 0U);
    335 
    336   const size_t kPacketSizeBytes = 1200;
    337   const int kNumPackets = 100;
    338 
    339   double window_size_s = bwe_receiver_.BitrateWindowS();
    340 
    341   // Receive packets at the same time.
    342   for (int i = 0; i < kNumPackets; ++i) {
    343     MediaPacket packet(kFlowId, 0L, kPacketSizeBytes, static_cast<uint16_t>(i));
    344     bwe_receiver_.ReceivePacket(0, packet);
    345   }
    346 
    347   EXPECT_NEAR(bwe_receiver_.RecentKbps(),
    348               (8 * kNumPackets * kPacketSizeBytes) / (1000 * window_size_s),
    349               10);
    350 
    351   int64_t time_gap_ms =
    352       2 * 1000 * window_size_s;  // Larger than rate_counter time window.
    353 
    354   MediaPacket packet(kFlowId, time_gap_ms * 1000, kPacketSizeBytes,
    355                      static_cast<uint16_t>(kNumPackets));
    356   bwe_receiver_.ReceivePacket(time_gap_ms, packet);
    357 
    358   EXPECT_NEAR(bwe_receiver_.RecentKbps(),
    359               (8 * kPacketSizeBytes) / (1000 * window_size_s), 10);
    360 }
    361 
    362 TEST_F(BweReceiverTest, Loss) {
    363   EXPECT_NEAR(bwe_receiver_.GlobalReceiverPacketLossRatio(), 0.0f, 0.001f);
    364 
    365   LossAccount loss_account = bwe_receiver_.LinkedSetPacketLossRatio();
    366   EXPECT_NEAR(loss_account.LossRatio(), 0.0f, 0.001f);
    367 
    368   // Insert packets 1-50 and 151-200;
    369   for (int i = 1; i <= 200; ++i) {
    370     // Packet size and timestamp do not matter here.
    371     MediaPacket packet(kFlowId, 0L, 0UL, static_cast<uint16_t>(i));
    372     bwe_receiver_.ReceivePacket(0, packet);
    373     if (i == 50) {
    374       i += 100;
    375     }
    376   }
    377 
    378   loss_account = bwe_receiver_.LinkedSetPacketLossRatio();
    379   EXPECT_NEAR(loss_account.LossRatio(), 0.5f, 0.001f);
    380 
    381   bwe_receiver_.RelieveSetAndUpdateLoss();
    382   EXPECT_EQ(bwe_receiver_.received_packets_.size(), 100U / 10);
    383 
    384   // No packet loss within the preserved packets.
    385   loss_account = bwe_receiver_.LinkedSetPacketLossRatio();
    386   EXPECT_NEAR(loss_account.LossRatio(), 0.0f, 0.001f);
    387 
    388   // RelieveSetAndUpdateLoss automatically updates loss account.
    389   EXPECT_NEAR(bwe_receiver_.GlobalReceiverPacketLossRatio(), 0.5f, 0.001f);
    390 }
    391 
    392 }  // namespace bwe
    393 }  // namespace testing
    394 }  // namespace webrtc
    395