LCOV - code coverage report
Current view: top level - test - test_token_bucket.c (source / functions) Hit Total Coverage
Test: lcov.info Lines: 76 76 100.0 %
Date: 2021-11-24 03:28:48 Functions: 4 4 100.0 %

          Line data    Source code
       1             : /* Copyright (c) 2018-2021, The Tor Project, Inc. */
       2             : /* See LICENSE for licensing information */
       3             : 
       4             : /**
       5             :  * \file test_bwmgt.c
       6             :  * \brief tests for bandwidth management / token bucket functions
       7             :  */
       8             : 
       9             : #define TOKEN_BUCKET_PRIVATE
      10             : 
      11             : #include "core/or/or.h"
      12             : #include "test/test.h"
      13             : 
      14             : #include "lib/evloop/token_bucket.h"
      15             : 
      16             : // an imaginary time, in timestamp units. Chosen so it will roll over.
      17             : static const uint32_t START_TS = UINT32_MAX - 1000;
      18             : static const uint32_t RATE = 10;
      19             : static const uint32_t BURST = 50;
      20             : 
      21             : static void
      22           1 : test_token_bucket_ctr_init(void *arg)
      23             : {
      24           1 :   (void) arg;
      25           1 :   token_bucket_ctr_t tb;
      26             : 
      27           1 :   token_bucket_ctr_init(&tb, RATE, BURST, START_TS);
      28           1 :   tt_uint_op(tb.cfg.rate, OP_EQ, RATE);
      29           1 :   tt_uint_op(tb.cfg.burst, OP_EQ, BURST);
      30           1 :   tt_uint_op(tb.last_refilled_at_timestamp, OP_EQ, START_TS);
      31           1 :   tt_int_op(tb.counter.bucket, OP_EQ, BURST);
      32             : 
      33           1 :  done:
      34           1 :   ;
      35           1 : }
      36             : 
      37             : static void
      38           1 : test_token_bucket_ctr_adjust(void *arg)
      39             : {
      40           1 :   (void) arg;
      41           1 :   token_bucket_ctr_t tb;
      42             : 
      43           1 :   token_bucket_ctr_init(&tb, RATE, BURST, START_TS);
      44             : 
      45             :   /* Increase burst. */
      46           1 :   token_bucket_ctr_adjust(&tb, RATE, BURST * 2);
      47           1 :   tt_uint_op(tb.cfg.rate, OP_EQ, RATE);
      48           1 :   tt_uint_op(tb.counter.bucket, OP_EQ, BURST);
      49           1 :   tt_uint_op(tb.cfg.burst, OP_EQ, BURST * 2);
      50             : 
      51             :   /* Decrease burst but still above bucket value. */
      52           1 :   token_bucket_ctr_adjust(&tb, RATE, BURST + 10);
      53           1 :   tt_uint_op(tb.cfg.rate, OP_EQ, RATE);
      54           1 :   tt_uint_op(tb.counter.bucket, OP_EQ, BURST);
      55           1 :   tt_uint_op(tb.cfg.burst, OP_EQ, BURST + 10);
      56             : 
      57             :   /* Decrease burst below bucket value. */
      58           1 :   token_bucket_ctr_adjust(&tb, RATE, BURST - 1);
      59           1 :   tt_uint_op(tb.cfg.rate, OP_EQ, RATE);
      60           1 :   tt_uint_op(tb.counter.bucket, OP_EQ, BURST - 1);
      61           1 :   tt_uint_op(tb.cfg.burst, OP_EQ, BURST - 1);
      62             : 
      63             :   /* Change rate. */
      64           1 :   token_bucket_ctr_adjust(&tb, RATE * 2, BURST);
      65           1 :   tt_uint_op(tb.cfg.rate, OP_EQ, RATE * 2);
      66           1 :   tt_uint_op(tb.counter.bucket, OP_EQ, BURST - 1);
      67           1 :   tt_uint_op(tb.cfg.burst, OP_EQ, BURST);
      68             : 
      69           1 :  done:
      70           1 :   ;
      71           1 : }
      72             : 
      73             : static void
      74           1 : test_token_bucket_ctr_dec(void *arg)
      75             : {
      76           1 :   (void) arg;
      77           1 :   token_bucket_ctr_t tb;
      78             : 
      79           1 :   token_bucket_ctr_init(&tb, RATE, BURST, START_TS);
      80             : 
      81             :   /* Simple decrement by one. */
      82           1 :   tt_uint_op(0, OP_EQ, token_bucket_ctr_dec(&tb, 1));
      83           1 :   tt_uint_op(tb.counter.bucket, OP_EQ, BURST - 1);
      84             : 
      85             :   /* Down to 0. Becomes empty. */
      86           1 :   tt_uint_op(true, OP_EQ, token_bucket_ctr_dec(&tb, BURST - 1));
      87           1 :   tt_uint_op(tb.counter.bucket, OP_EQ, 0);
      88             : 
      89             :   /* Reset and try to underflow. */
      90           1 :   token_bucket_ctr_init(&tb, RATE, BURST, START_TS);
      91           1 :   tt_uint_op(true, OP_EQ, token_bucket_ctr_dec(&tb, BURST + 1));
      92           1 :   tt_int_op(tb.counter.bucket, OP_EQ, -1);
      93             : 
      94             :   /* Keep underflowing shouldn't flag the bucket as empty. */
      95           1 :   tt_uint_op(false, OP_EQ, token_bucket_ctr_dec(&tb, BURST));
      96           1 :   tt_int_op(tb.counter.bucket, OP_EQ, - (int32_t) (BURST + 1));
      97             : 
      98           1 :  done:
      99           1 :   ;
     100           1 : }
     101             : 
     102             : static void
     103           1 : test_token_bucket_ctr_refill(void *arg)
     104             : {
     105           1 :   (void) arg;
     106           1 :   token_bucket_ctr_t tb;
     107             : 
     108           1 :   token_bucket_ctr_init(&tb, RATE, BURST, START_TS);
     109             : 
     110             :   /* Reduce of half the bucket and let a single second go before refill. */
     111           1 :   token_bucket_ctr_dec(&tb, BURST / 2);
     112           1 :   tt_int_op(tb.counter.bucket, OP_EQ, BURST / 2);
     113           1 :   token_bucket_ctr_refill(&tb, START_TS + 1);
     114           1 :   tt_int_op(tb.counter.bucket, OP_EQ, (BURST / 2) + RATE);
     115           1 :   tt_int_op(tb.last_refilled_at_timestamp, OP_EQ, START_TS + 1);
     116             : 
     117             :   /* No time change, nothing should move. */
     118           1 :   token_bucket_ctr_refill(&tb, START_TS + 1);
     119           1 :   tt_int_op(tb.counter.bucket, OP_EQ, (BURST / 2) + RATE);
     120           1 :   tt_int_op(tb.last_refilled_at_timestamp, OP_EQ, START_TS + 1);
     121             : 
     122             :   /* Add 99 seconds, bucket should be back to a full BURST. */
     123           1 :   token_bucket_ctr_refill(&tb, START_TS + 99);
     124           1 :   tt_int_op(tb.counter.bucket, OP_EQ, BURST);
     125           1 :   tt_int_op(tb.last_refilled_at_timestamp, OP_EQ, START_TS + 99);
     126             : 
     127             :   /* Empty bucket at once. */
     128           1 :   token_bucket_ctr_dec(&tb, BURST);
     129           1 :   tt_int_op(tb.counter.bucket, OP_EQ, 0);
     130             :   /* On second passes. */
     131           1 :   token_bucket_ctr_refill(&tb, START_TS + 100);
     132           1 :   tt_int_op(tb.last_refilled_at_timestamp, OP_EQ, START_TS + 100);
     133           1 :   tt_int_op(tb.counter.bucket, OP_EQ, RATE);
     134             :   /* A second second passes. */
     135           1 :   token_bucket_ctr_refill(&tb, START_TS + 101);
     136           1 :   tt_int_op(tb.last_refilled_at_timestamp, OP_EQ, START_TS + 101);
     137           1 :   tt_int_op(tb.counter.bucket, OP_EQ, RATE * 2);
     138             : 
     139           1 :  done:
     140           1 :   ;
     141           1 : }
     142             : 
     143             : #define TOKEN_BUCKET(name)                                          \
     144             :   { #name, test_token_bucket_ ## name , 0, NULL, NULL }
     145             : 
     146             : struct testcase_t token_bucket_tests[] = {
     147             :   TOKEN_BUCKET(ctr_init),
     148             :   TOKEN_BUCKET(ctr_adjust),
     149             :   TOKEN_BUCKET(ctr_dec),
     150             :   TOKEN_BUCKET(ctr_refill),
     151             :   END_OF_TESTCASES
     152             : };

Generated by: LCOV version 1.14