Mercurial > prosody-hg
comparison spec/util_throttle_spec.lua @ 8245:9499db96c032
util.throttle: Fix initial time setting (double accounting the first time) and fractional balance updates (0.1*10 was not the same as 1*1)
| author | Waqas Hussain <waqas20@gmail.com> |
|---|---|
| date | Sun, 17 Sep 2017 13:29:14 -0400 |
| parents | 4878e4159e12 |
| children | ea2667fc6781 |
comparison
equal
deleted
inserted
replaced
| 8244:6a27e5f276f7 | 8245:9499db96c032 |
|---|---|
| 10 } | 10 } |
| 11 | 11 |
| 12 | 12 |
| 13 local throttle = require "util.throttle"; | 13 local throttle = require "util.throttle"; |
| 14 | 14 |
| 15 describe("util.sasl.scram", function() | 15 describe("util.throttle", function() |
| 16 describe("#Hi()", function() | 16 describe("#create", function() |
| 17 it("should work", function() | 17 it("should be created with correct values", function() |
| 18 now = 5; | |
| 18 local a = throttle.create(3, 10); | 19 local a = throttle.create(3, 10); |
| 20 assert.same(a, { balance = 3, max = 3, rate = 0.3, t = 5 }); | |
| 19 | 21 |
| 20 assert.are.equal(a:poll(1), true); -- 3 -> 2 | 22 local a = throttle.create(3, 5); |
| 21 assert.are.equal(a:poll(1), true); -- 2 -> 1 | 23 assert.same(a, { balance = 3, max = 3, rate = 0.6, t = 5 }); |
| 22 assert.are.equal(a:poll(1), true); -- 1 -> 0 | 24 |
| 23 assert.are.equal(a:poll(1), false); -- MEEP, out of credits! | 25 local a = throttle.create(1, 1); |
| 24 later(1); -- ... what about | 26 assert.same(a, { balance = 1, max = 1, rate = 1, t = 5 }); |
| 25 assert.are.equal(a:poll(1), false); -- now? - Still no! | 27 |
| 26 later(9); -- Later that day | 28 local a = throttle.create(10, 10); |
| 27 assert.are.equal(a:poll(1), true); -- Should be back at 3 credits ... 2 | 29 assert.same(a, { balance = 10, max = 10, rate = 1, t = 5 }); |
| 30 | |
| 31 local a = throttle.create(10, 1); | |
| 32 assert.same(a, { balance = 10, max = 10, rate = 10, t = 5 }); | |
| 33 end); | |
| 34 end); | |
| 35 | |
| 36 describe("#update", function() | |
| 37 it("does nothing when no time hase passed, even if balance is not full", function() | |
| 38 now = 5; | |
| 39 local a = throttle.create(10, 10); | |
| 40 for i=1,5 do | |
| 41 a:update(); | |
| 42 assert.same(a, { balance = 10, max = 10, rate = 1, t = 5 }); | |
| 43 end | |
| 44 a.balance = 0; | |
| 45 for i=1,5 do | |
| 46 a:update(); | |
| 47 assert.same(a, { balance = 0, max = 10, rate = 1, t = 5 }); | |
| 48 end | |
| 49 end); | |
| 50 it("updates only time when time passes but balance is full", function() | |
| 51 now = 5; | |
| 52 local a = throttle.create(10, 10); | |
| 53 for i=1,5 do | |
| 54 later(5); | |
| 55 a:update(); | |
| 56 assert.same(a, { balance = 10, max = 10, rate = 1, t = 5 + i*5 }); | |
| 57 end | |
| 58 end); | |
| 59 it("updates balance when balance has room to grow as time passes", function() | |
| 60 now = 5; | |
| 61 local a = throttle.create(10, 10); | |
| 62 a.balance = 0; | |
| 63 assert.same(a, { balance = 0, max = 10, rate = 1, t = 5 }); | |
| 64 | |
| 65 later(1); | |
| 66 a:update(); | |
| 67 assert.same(a, { balance = 1, max = 10, rate = 1, t = 6 }); | |
| 68 | |
| 69 later(3); | |
| 70 a:update(); | |
| 71 assert.same(a, { balance = 4, max = 10, rate = 1, t = 9 }); | |
| 72 | |
| 73 later(10); | |
| 74 a:update(); | |
| 75 assert.same(a, { balance = 10, max = 10, rate = 1, t = 19 }); | |
| 76 end); | |
| 77 it("handles 10 x 0.1s updates the same as 1 x 1s update ", function() | |
| 78 now = 5; | |
| 79 local a = throttle.create(1, 1); | |
| 80 | |
| 81 a.balance = 0; | |
| 82 later(1); | |
| 83 a:update(); | |
| 84 assert.same(a, { balance = 1, max = 1, rate = 1, t = now }); | |
| 85 | |
| 86 a.balance = 0; | |
| 87 for i=1,10 do | |
| 88 later(0.1); | |
| 89 a:update(); | |
| 90 end | |
| 91 assert(math.abs(a.balance - 1) < 0.0001); -- incremental updates cause rouding errors | |
| 92 end); | |
| 93 end); | |
| 94 | |
| 95 -- describe("po") | |
| 96 | |
| 97 describe("#poll()", function() | |
| 98 it("should only allow successful polls until cost is hit", function() | |
| 99 now = 5; | |
| 100 | |
| 101 local a = throttle.create(3, 10); | |
| 102 assert.same(a, { balance = 3, max = 3, rate = 0.3, t = 5 }); | |
| 103 | |
| 104 assert.is_true(a:poll(1)); -- 3 -> 2 | |
| 105 assert.same(a, { balance = 2, max = 3, rate = 0.3, t = 5 }); | |
| 106 | |
| 107 assert.is_true(a:poll(2)); -- 2 -> 1 | |
| 108 assert.same(a, { balance = 0, max = 3, rate = 0.3, t = 5 }); | |
| 109 | |
| 110 assert.is_false(a:poll(1)); -- MEEP, out of credits! | |
| 111 assert.is_false(a:poll(1)); -- MEEP, out of credits! | |
| 112 assert.same(a, { balance = 0, max = 3, rate = 0.3, t = 5 }); | |
| 113 end); | |
| 114 | |
| 115 it("should not allow polls more than the cost", function() | |
| 116 now = 0; | |
| 117 | |
| 118 local a = throttle.create(10, 10); | |
| 119 assert.same(a, { balance = 10, max = 10, rate = 1, t = 0 }); | |
| 120 | |
| 121 assert.is_false(a:poll(11)); | |
| 122 assert.same(a, { balance = 10, max = 10, rate = 1, t = 0 }); | |
| 123 | |
| 124 assert.is_true(a:poll(6)); | |
| 125 assert.same(a, { balance = 4, max = 10, rate = 1, t = 0 }); | |
| 126 | |
| 127 assert.is_false(a:poll(5)); | |
| 128 assert.same(a, { balance = 4, max = 10, rate = 1, t = 0 }); | |
| 129 | |
| 130 -- fractional | |
| 131 assert.is_true(a:poll(3.5)); | |
| 132 assert.same(a, { balance = 0.5, max = 10, rate = 1, t = 0 }); | |
| 133 | |
| 134 assert.is_true(a:poll(0.25)); | |
| 135 assert.same(a, { balance = 0.25, max = 10, rate = 1, t = 0 }); | |
| 136 | |
| 137 assert.is_false(a:poll(0.3)); | |
| 138 assert.same(a, { balance = 0.25, max = 10, rate = 1, t = 0 }); | |
| 139 | |
| 140 assert.is_true(a:poll(0.25)); | |
| 141 assert.same(a, { balance = 0, max = 10, rate = 1, t = 0 }); | |
| 142 | |
| 143 assert.is_false(a:poll(0.1)); | |
| 144 assert.same(a, { balance = 0, max = 10, rate = 1, t = 0 }); | |
| 145 | |
| 146 assert.is_true(a:poll(0)); | |
| 147 assert.same(a, { balance = 0, max = 10, rate = 1, t = 0 }); | |
| 28 end); | 148 end); |
| 29 end); | 149 end); |
| 30 end); | 150 end); |
