vitess.io/vitess@v0.16.2/go/vt/throttler/replication_lag_cache_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/discovery" 24 ) 25 26 // TestReplicationLagCache tests that the ring buffer in "replicationLagHistory" 27 // wraps around correctly. 28 // Other parts of the code are already covered by 29 // max_replication_lag_module_test.go. 30 func TestReplicationLagCache(t *testing.T) { 31 c := newReplicationLagCache(2) 32 r1Key := discovery.TabletToMapKey(tabletStats(r1, 1).Tablet) 33 34 // If there is no entry yet, a zero struct is returned. 35 zeroEntry := c.atOrAfter(r1Key, sinceZero(0*time.Second)) 36 if !zeroEntry.isZero() { 37 t.Fatalf("atOrAfter(<non existent key>) should have returned a zero entry but did not: %v", zeroEntry) 38 } 39 40 // First entry at 1s. 41 c.add(lagRecord(sinceZero(1*time.Second), r1, 1)) 42 if got, want := c.latest(r1Key).time, sinceZero(1*time.Second); got != want { 43 t.Fatalf("latest(r1) = %v, want = %v", got, want) 44 } 45 46 // Second entry at 2s makes the cache full. 47 c.add(lagRecord(sinceZero(2*time.Second), r1, 2)) 48 if got, want := c.latest(r1Key).time, sinceZero(2*time.Second); got != want { 49 t.Fatalf("latest(r1) = %v, want = %v", got, want) 50 } 51 if got, want := c.atOrAfter(r1Key, sinceZero(1*time.Second)).time, sinceZero(1*time.Second); got != want { 52 t.Fatalf("atOrAfter(r1) = %v, want = %v", got, want) 53 } 54 55 // Third entry at 3s evicts the 1s entry. 56 c.add(lagRecord(sinceZero(3*time.Second), r1, 3)) 57 if got, want := c.latest(r1Key).time, sinceZero(3*time.Second); got != want { 58 t.Fatalf("latest(r1) = %v, want = %v", got, want) 59 } 60 // Requesting an entry at 1s or after gets us the entry for 2s. 61 if got, want := c.atOrAfter(r1Key, sinceZero(1*time.Second)).time, sinceZero(2*time.Second); got != want { 62 t.Fatalf("atOrAfter(r1) = %v, want = %v", got, want) 63 } 64 65 // Wrap around one more time. Entries at 4s and 5s should be left. 66 c.add(lagRecord(sinceZero(4*time.Second), r1, 4)) 67 c.add(lagRecord(sinceZero(5*time.Second), r1, 5)) 68 if got, want := c.latest(r1Key).time, sinceZero(5*time.Second); got != want { 69 t.Fatalf("latest(r1) = %v, want = %v", got, want) 70 } 71 if got, want := c.atOrAfter(r1Key, sinceZero(1*time.Second)).time, sinceZero(4*time.Second); got != want { 72 t.Fatalf("atOrAfter(r1) = %v, want = %v", got, want) 73 } 74 } 75 76 func TestReplicationLagCache_SortByLag(t *testing.T) { 77 c := newReplicationLagCache(2) 78 r1Key := discovery.TabletToMapKey(tabletStats(r1, 1).Tablet) 79 80 c.add(lagRecord(sinceZero(1*time.Second), r1, 30)) 81 c.sortByLag(1 /* ignoreNSlowestReplicas */, 30 /* minimumReplicationLag */) 82 83 if c.slowReplicas[r1Key] { 84 t.Fatal("the only replica tracked should not get ignored") 85 } 86 87 c.add(lagRecord(sinceZero(1*time.Second), r2, 1)) 88 c.sortByLag(1 /* ignoreNSlowestReplicas */, 1 /* minimumReplicationLag */) 89 90 if !c.slowReplicas[r1Key] { 91 t.Fatal("r1 should be tracked as a slow replica") 92 } 93 }