vitess.io/vitess@v0.16.2/go/vt/throttler/memory_test.go (about) 1 /* 2 Copyright 2019 The Vitess Authors. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package throttler 18 19 import ( 20 "testing" 21 "time" 22 23 "vitess.io/vitess/go/vt/log" 24 ) 25 26 func TestMemory(t *testing.T) { 27 m := newMemory(5, 1*time.Second, 0.10) 28 29 // Add several good rates. 30 if err := m.markGood(201); err != nil { 31 log.Errorf("m.markGood(201) failed :%v ", err) 32 } 33 34 want200 := int64(200) 35 if got := m.highestGood(); got != want200 { 36 t.Fatalf("memory with one good entry: got = %v, want = %v", got, want200) 37 } 38 39 //log error 40 if err := m.markGood(101); err != nil { 41 log.Errorf("m.markGood(101) failed :%v ", err) 42 } 43 44 if got := m.highestGood(); got != want200 { 45 t.Fatalf("wrong order within memory: got = %v, want = %v", got, want200) 46 } 47 48 //log error 49 if err := m.markGood(301); err != nil { 50 log.Errorf(" m.markGood(301) failed :%v ", err) 51 } 52 53 want300 := int64(300) 54 if got := m.highestGood(); got != want300 { 55 t.Fatalf("wrong order within memory: got = %v, want = %v", got, want300) 56 } 57 m.markGood(306) 58 want305 := int64(305) 59 if got := m.highestGood(); got != want305 { 60 t.Fatalf("wrong order within memory: got = %v, want = %v", got, want305) 61 } 62 63 // 300 and 305 will turn from good to bad. 64 if got := m.lowestBad(); got != 0 { 65 t.Fatalf("lowestBad should return zero value when no bad rate is recorded yet: got = %v", got) 66 } 67 68 //log error 69 if err := m.markBad(300, sinceZero(0)); err != nil { 70 log.Errorf(" m.markBad(300, sinceZero(0)) failed :%v ", err) 71 } 72 73 if got, want := m.lowestBad(), want300; got != want { 74 t.Fatalf("bad rate was not recorded: got = %v, want = %v", got, want) 75 } 76 if got := m.highestGood(); got != want200 { 77 t.Fatalf("new lower bad rate did not invalidate previous good rates: got = %v, want = %v", got, want200) 78 } 79 80 //log error 81 if err := m.markBad(311, sinceZero(0)); err != nil { 82 log.Errorf(" m.markBad(311, sinceZero(0)) failed :%v ", err) 83 } 84 85 if got := m.lowestBad(); got != want300 { 86 t.Fatalf("bad rates higher than the current one should be ignored: got = %v, want = %v", got, want300) 87 } 88 89 // a good 601 will be ignored because the first bad is at 300. 90 if err := m.markGood(601); err == nil { 91 t.Fatal("good rates cannot go beyond the lowest bad rate: should have returned an error") 92 } 93 if got := m.lowestBad(); got != want300 { 94 t.Fatalf("good rates cannot go beyond the lowest bad rate: got = %v, want = %v", got, want300) 95 } 96 if got := m.highestGood(); got != want200 { 97 t.Fatalf("good rates beyond the lowest bad rate must be ignored: got = %v, want = %v", got, want200) 98 } 99 100 // 199 will be rounded up to 200. 101 err := m.markBad(199, sinceZero(0)) 102 103 if err != nil { 104 t.Fatalf(" m.markBad(199, sinceZero(0)) failed :%v ", err) 105 } 106 107 if got := m.lowestBad(); got != want200 { 108 t.Fatalf("bad rate was not updated: got = %v, want = %v", got, want200) 109 } 110 want100 := int64(100) 111 if got := m.highestGood(); got != want100 { 112 t.Fatalf("previous highest good rate was not marked as bad: got = %v, want = %v", got, want100) 113 } 114 } 115 116 func TestMemory_markDownIgnoresDrasticBadValues(t *testing.T) { 117 m := newMemory(1, 1*time.Second, 0.10) 118 good := int64(1000) 119 bad := int64(1001) 120 m.markGood(good) 121 m.markBad(bad, sinceZero(0)) 122 if got := m.highestGood(); got != good { 123 t.Fatalf("good rate was not correctly inserted: got = %v, want = %v", got, good) 124 } 125 if got := m.lowestBad(); got != bad { 126 t.Fatalf("bad rate was not correctly inserted: got = %v, want = %v", got, bad) 127 } 128 129 if err := m.markBad(500, sinceZero(0)); err == nil { 130 t.Fatal("bad rate should have been ignored and an error should have been returned") 131 } 132 if got := m.highestGood(); got != good { 133 t.Fatalf("bad rate should have been ignored: got = %v, want = %v", got, good) 134 } 135 if got := m.lowestBad(); got != bad { 136 t.Fatalf("bad rate should have been ignored: got = %v, want = %v", got, bad) 137 } 138 } 139 140 func TestMemory_Aging(t *testing.T) { 141 m := newMemory(1, 2*time.Second, 0.10) 142 143 m.markBad(100, sinceZero(0)) 144 if got, want := m.lowestBad(), int64(100); got != want { 145 t.Fatalf("bad rate was not correctly inserted: got = %v, want = %v", got, want) 146 } 147 148 // Bad rate successfully ages by 10%. 149 m.ageBadRate(sinceZero(2 * time.Second)) 150 if got, want := m.lowestBad(), int64(110); got != want { 151 t.Fatalf("bad rate should have been increased due to its age: got = %v, want = %v", got, want) 152 } 153 154 // A recent aging resets the age timer. 155 m.ageBadRate(sinceZero(2 * time.Second)) 156 if got, want := m.lowestBad(), int64(110); got != want { 157 t.Fatalf("a bad rate should not age again until the age is up again: got = %v, want = %v", got, want) 158 } 159 160 // The age timer will be reset if the bad rate changes. 161 m.markBad(100, sinceZero(3*time.Second)) 162 m.ageBadRate(sinceZero(4 * time.Second)) 163 if got, want := m.lowestBad(), int64(100); got != want { 164 t.Fatalf("bad rate must not age yet: got = %v, want = %v", got, want) 165 } 166 167 // The age timer won't be reset when the rate stays the same. 168 m.markBad(100, sinceZero(4*time.Second)) 169 m.ageBadRate(sinceZero(5 * time.Second)) 170 if got, want := m.lowestBad(), int64(110); got != want { 171 t.Fatalf("bad rate should have aged again: got = %v, want = %v", got, want) 172 } 173 174 // Update the aging config. It will be effective immediately. 175 m.updateAgingConfiguration(1*time.Second, 0.05) 176 m.ageBadRate(sinceZero(6 * time.Second)) 177 if got, want := m.lowestBad(), int64(115); got != want { 178 t.Fatalf("bad rate should have aged after the configuration update: got = %v, want = %v", got, want) 179 } 180 181 // If the new bad rate is not higher, it should increase by the memory granularity at least. 182 m.markBad(5, sinceZero(10*time.Second)) 183 m.ageBadRate(sinceZero(11 * time.Second)) 184 if got, want := m.lowestBad(), int64(5+memoryGranularity); got != want { 185 t.Fatalf("bad rate should have aged after the configuration update: got = %v, want = %v", got, want) 186 } 187 }