github.com/maypok86/otter@v1.2.1/internal/expiry/variable_test.go (about) 1 // Copyright (c) 2024 Alexey Mayshev. All rights reserved. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package expiry 16 17 import ( 18 "testing" 19 20 "github.com/maypok86/otter/internal/generated/node" 21 "github.com/maypok86/otter/internal/unixtime" 22 ) 23 24 func contains[K comparable, V any](root, f node.Node[K, V]) bool { 25 n := root.NextExp() 26 for !node.Equals(n, root) { 27 if node.Equals(n, f) { 28 return true 29 } 30 31 n = n.NextExp() 32 } 33 return false 34 } 35 36 func match[K comparable, V any](t *testing.T, nodes []node.Node[K, V], keys []K) { 37 t.Helper() 38 39 if len(nodes) != len(keys) { 40 t.Fatalf("Not equals lengths of nodes (%d) and keys (%d)", len(nodes), len(keys)) 41 } 42 43 for i, k := range keys { 44 if k != nodes[i].Key() { 45 t.Fatalf("Not valid entry found: %+v", nodes[i]) 46 } 47 } 48 } 49 50 func TestVariable_Add(t *testing.T) { 51 nm := node.NewManager[string, string](node.Config{ 52 WithExpiration: true, 53 }) 54 nodes := []node.Node[string, string]{ 55 nm.Create("k1", "", 1, 1), 56 nm.Create("k2", "", 69, 1), 57 nm.Create("k3", "", 4399, 1), 58 } 59 v := NewVariable[string, string](nm) 60 61 for _, n := range nodes { 62 v.Add(n) 63 } 64 65 var found bool 66 for _, root := range v.wheel[0] { 67 if contains(root, nodes[0]) { 68 found = true 69 } 70 } 71 if !found { 72 t.Fatalf("Not found node %+v in timer wheel", nodes[0]) 73 } 74 75 found = false 76 for _, root := range v.wheel[1] { 77 if contains(root, nodes[1]) { 78 found = true 79 } 80 } 81 if !found { 82 t.Fatalf("Not found node %+v in timer wheel", nodes[1]) 83 } 84 85 found = false 86 for _, root := range v.wheel[2] { 87 if contains(root, nodes[2]) { 88 found = true 89 } 90 } 91 if !found { 92 t.Fatalf("Not found node %+v in timer wheel", nodes[2]) 93 } 94 } 95 96 func TestVariable_RemoveExpired(t *testing.T) { 97 nm := node.NewManager[string, string](node.Config{ 98 WithExpiration: true, 99 }) 100 nodes := []node.Node[string, string]{ 101 nm.Create("k1", "", 1, 1), 102 nm.Create("k2", "", 10, 1), 103 nm.Create("k3", "", 30, 1), 104 nm.Create("k4", "", 120, 1), 105 nm.Create("k5", "", 6500, 1), 106 nm.Create("k6", "", 142000, 1), 107 nm.Create("k7", "", 1420000, 1), 108 } 109 v := NewVariable[string, string](nm) 110 111 for _, n := range nodes { 112 v.Add(n) 113 } 114 115 var expired []node.Node[string, string] 116 var keys []string 117 unixtime.SetNow(64) 118 expired = v.RemoveExpired(expired) 119 keys = append(keys, "k1", "k2", "k3") 120 match(t, expired, keys) 121 122 unixtime.SetNow(200) 123 expired = v.RemoveExpired(expired) 124 keys = append(keys, "k4") 125 match(t, expired, keys) 126 127 unixtime.SetNow(12000) 128 expired = v.RemoveExpired(expired) 129 keys = append(keys, "k5") 130 match(t, expired, keys) 131 132 unixtime.SetNow(350000) 133 expired = v.RemoveExpired(expired) 134 keys = append(keys, "k6") 135 match(t, expired, keys) 136 137 unixtime.SetNow(1520000) 138 expired = v.RemoveExpired(expired) 139 keys = append(keys, "k7") 140 match(t, expired, keys) 141 }