go.etcd.io/etcd@v3.3.27+incompatible/store/node_test.go (about) 1 // Copyright 2015 The etcd Authors 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 store 16 17 import ( 18 "testing" 19 "time" 20 21 "github.com/jonboulle/clockwork" 22 ) 23 24 var ( 25 key, val = "foo", "bar" 26 val1, val2 = "bar1", "bar2" 27 expiration = time.Minute 28 ) 29 30 func TestNewKVIs(t *testing.T) { 31 nd := newTestNode() 32 33 if nd.IsHidden() { 34 t.Errorf("nd.Hidden() = %v, want = false", nd.IsHidden()) 35 } 36 37 if nd.IsPermanent() { 38 t.Errorf("nd.IsPermanent() = %v, want = false", nd.IsPermanent()) 39 } 40 41 if nd.IsDir() { 42 t.Errorf("nd.IsDir() = %v, want = false", nd.IsDir()) 43 } 44 } 45 46 func TestNewKVReadWriteCompare(t *testing.T) { 47 nd := newTestNode() 48 49 if v, err := nd.Read(); v != val || err != nil { 50 t.Errorf("value = %s and err = %v, want value = %s and err = nil", v, err, val) 51 } 52 53 if err := nd.Write(val1, nd.CreatedIndex+1); err != nil { 54 t.Errorf("nd.Write error = %v, want = nil", err) 55 } else { 56 if v, err := nd.Read(); v != val1 || err != nil { 57 t.Errorf("value = %s and err = %v, want value = %s and err = nil", v, err, val1) 58 } 59 } 60 if err := nd.Write(val2, nd.CreatedIndex+2); err != nil { 61 t.Errorf("nd.Write error = %v, want = nil", err) 62 } else { 63 if v, err := nd.Read(); v != val2 || err != nil { 64 t.Errorf("value = %s and err = %v, want value = %s and err = nil", v, err, val2) 65 } 66 } 67 68 if ok, which := nd.Compare(val2, 2); !ok || which != 0 { 69 t.Errorf("ok = %v and which = %d, want ok = true and which = 0", ok, which) 70 } 71 } 72 73 func TestNewKVExpiration(t *testing.T) { 74 nd := newTestNode() 75 76 if _, ttl := nd.expirationAndTTL(clockwork.NewFakeClock()); ttl > expiration.Nanoseconds() { 77 t.Errorf("ttl = %d, want %d < %d", ttl, ttl, expiration.Nanoseconds()) 78 } 79 80 newExpiration := time.Hour 81 nd.UpdateTTL(time.Now().Add(newExpiration)) 82 if _, ttl := nd.expirationAndTTL(clockwork.NewFakeClock()); ttl > newExpiration.Nanoseconds() { 83 t.Errorf("ttl = %d, want %d < %d", ttl, ttl, newExpiration.Nanoseconds()) 84 } 85 if ns, err := nd.List(); ns != nil || err == nil { 86 t.Errorf("nodes = %v and err = %v, want nodes = nil and err != nil", ns, err) 87 } 88 89 en := nd.Repr(false, false, clockwork.NewFakeClock()) 90 if en.Key != nd.Path { 91 t.Errorf("en.Key = %s, want = %s", en.Key, nd.Path) 92 } 93 if *(en.Value) != nd.Value { 94 t.Errorf("*(en.Key) = %s, want = %s", *(en.Value), nd.Value) 95 } 96 } 97 98 func TestNewKVListReprCompareClone(t *testing.T) { 99 nd := newTestNode() 100 101 if ns, err := nd.List(); ns != nil || err == nil { 102 t.Errorf("nodes = %v and err = %v, want nodes = nil and err != nil", ns, err) 103 } 104 105 en := nd.Repr(false, false, clockwork.NewFakeClock()) 106 if en.Key != nd.Path { 107 t.Errorf("en.Key = %s, want = %s", en.Key, nd.Path) 108 } 109 if *(en.Value) != nd.Value { 110 t.Errorf("*(en.Key) = %s, want = %s", *(en.Value), nd.Value) 111 } 112 113 cn := nd.Clone() 114 if cn.Path != nd.Path { 115 t.Errorf("cn.Path = %s, want = %s", cn.Path, nd.Path) 116 } 117 if cn.Value != nd.Value { 118 t.Errorf("cn.Value = %s, want = %s", cn.Value, nd.Value) 119 } 120 } 121 122 func TestNewKVRemove(t *testing.T) { 123 nd := newTestNode() 124 125 if v, err := nd.Read(); v != val || err != nil { 126 t.Errorf("value = %s and err = %v, want value = %s and err = nil", v, err, val) 127 } 128 129 if err := nd.Write(val1, nd.CreatedIndex+1); err != nil { 130 t.Errorf("nd.Write error = %v, want = nil", err) 131 } else { 132 if v, err := nd.Read(); v != val1 || err != nil { 133 t.Errorf("value = %s and err = %v, want value = %s and err = nil", v, err, val1) 134 } 135 } 136 if err := nd.Write(val2, nd.CreatedIndex+2); err != nil { 137 t.Errorf("nd.Write error = %v, want = nil", err) 138 } else { 139 if v, err := nd.Read(); v != val2 || err != nil { 140 t.Errorf("value = %s and err = %v, want value = %s and err = nil", v, err, val2) 141 } 142 } 143 144 if err := nd.Remove(false, false, nil); err != nil { 145 t.Errorf("nd.Remove err = %v, want = nil", err) 146 } else { 147 // still readable 148 if v, err := nd.Read(); v != val2 || err != nil { 149 t.Errorf("value = %s and err = %v, want value = %s and err = nil", v, err, val2) 150 } 151 if len(nd.store.ttlKeyHeap.array) != 0 { 152 t.Errorf("len(nd.store.ttlKeyHeap.array) = %d, want = 0", len(nd.store.ttlKeyHeap.array)) 153 } 154 if len(nd.store.ttlKeyHeap.keyMap) != 0 { 155 t.Errorf("len(nd.store.ttlKeyHeap.keyMap) = %d, want = 0", len(nd.store.ttlKeyHeap.keyMap)) 156 } 157 } 158 } 159 160 func TestNewDirIs(t *testing.T) { 161 nd, _ := newTestNodeDir() 162 if nd.IsHidden() { 163 t.Errorf("nd.Hidden() = %v, want = false", nd.IsHidden()) 164 } 165 166 if nd.IsPermanent() { 167 t.Errorf("nd.IsPermanent() = %v, want = false", nd.IsPermanent()) 168 } 169 170 if !nd.IsDir() { 171 t.Errorf("nd.IsDir() = %v, want = true", nd.IsDir()) 172 } 173 } 174 175 func TestNewDirReadWriteListReprClone(t *testing.T) { 176 nd, _ := newTestNodeDir() 177 178 if _, err := nd.Read(); err == nil { 179 t.Errorf("err = %v, want err != nil", err) 180 } 181 182 if err := nd.Write(val, nd.CreatedIndex+1); err == nil { 183 t.Errorf("err = %v, want err != nil", err) 184 } 185 186 if ns, err := nd.List(); ns == nil && err != nil { 187 t.Errorf("nodes = %v and err = %v, want nodes = nil and err == nil", ns, err) 188 } 189 190 en := nd.Repr(false, false, clockwork.NewFakeClock()) 191 if en.Key != nd.Path { 192 t.Errorf("en.Key = %s, want = %s", en.Key, nd.Path) 193 } 194 195 cn := nd.Clone() 196 if cn.Path != nd.Path { 197 t.Errorf("cn.Path = %s, want = %s", cn.Path, nd.Path) 198 } 199 } 200 201 func TestNewDirExpirationTTL(t *testing.T) { 202 nd, _ := newTestNodeDir() 203 204 if _, ttl := nd.expirationAndTTL(clockwork.NewFakeClock()); ttl > expiration.Nanoseconds() { 205 t.Errorf("ttl = %d, want %d < %d", ttl, ttl, expiration.Nanoseconds()) 206 } 207 208 newExpiration := time.Hour 209 nd.UpdateTTL(time.Now().Add(newExpiration)) 210 if _, ttl := nd.expirationAndTTL(clockwork.NewFakeClock()); ttl > newExpiration.Nanoseconds() { 211 t.Errorf("ttl = %d, want %d < %d", ttl, ttl, newExpiration.Nanoseconds()) 212 } 213 } 214 215 func TestNewDirChild(t *testing.T) { 216 nd, child := newTestNodeDir() 217 218 if err := nd.Add(child); err != nil { 219 t.Errorf("nd.Add(child) err = %v, want = nil", err) 220 } else { 221 if len(nd.Children) == 0 { 222 t.Errorf("len(nd.Children) = %d, want = 1", len(nd.Children)) 223 } 224 } 225 226 if err := child.Remove(true, true, nil); err != nil { 227 t.Errorf("child.Remove err = %v, want = nil", err) 228 } else { 229 if len(nd.Children) != 0 { 230 t.Errorf("len(nd.Children) = %d, want = 0", len(nd.Children)) 231 } 232 } 233 } 234 235 func newTestNode() *node { 236 nd := newKV(newStore(), key, val, 0, nil, time.Now().Add(expiration)) 237 return nd 238 } 239 240 func newTestNodeDir() (*node, *node) { 241 s := newStore() 242 nd := newDir(s, key, 0, nil, time.Now().Add(expiration)) 243 cKey, cVal := "hello", "world" 244 child := newKV(s, cKey, cVal, 0, nd, time.Now().Add(expiration)) 245 return nd, child 246 }