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  }