go.etcd.io/etcd@v3.3.27+incompatible/store/node_extern_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 "reflect" 19 "testing" 20 "time" 21 "unsafe" 22 23 "github.com/coreos/etcd/pkg/testutil" 24 ) 25 26 func TestNodeExternClone(t *testing.T) { 27 var eNode *NodeExtern 28 if g := eNode.Clone(); g != nil { 29 t.Fatalf("nil.Clone=%v, want nil", g) 30 } 31 32 const ( 33 key string = "/foo/bar" 34 ttl int64 = 123456789 35 ci uint64 = 123 36 mi uint64 = 321 37 ) 38 var ( 39 val = "some_data" 40 valp = &val 41 exp = time.Unix(12345, 67890) 42 expp = &exp 43 child = NodeExtern{} 44 childp = &child 45 childs = []*NodeExtern{childp} 46 ) 47 48 eNode = &NodeExtern{ 49 Key: key, 50 TTL: ttl, 51 CreatedIndex: ci, 52 ModifiedIndex: mi, 53 Value: valp, 54 Expiration: expp, 55 Nodes: childs, 56 } 57 58 gNode := eNode.Clone() 59 // Check the clone is as expected 60 testutil.AssertEqual(t, gNode.Key, key) 61 testutil.AssertEqual(t, gNode.TTL, ttl) 62 testutil.AssertEqual(t, gNode.CreatedIndex, ci) 63 testutil.AssertEqual(t, gNode.ModifiedIndex, mi) 64 // values should be the same 65 testutil.AssertEqual(t, *gNode.Value, val) 66 testutil.AssertEqual(t, *gNode.Expiration, exp) 67 testutil.AssertEqual(t, len(gNode.Nodes), len(childs)) 68 testutil.AssertEqual(t, *gNode.Nodes[0], child) 69 // but pointers should differ 70 if gNode.Value == eNode.Value { 71 t.Fatalf("expected value pointers to differ, but got same!") 72 } 73 if gNode.Expiration == eNode.Expiration { 74 t.Fatalf("expected expiration pointers to differ, but got same!") 75 } 76 if sameSlice(gNode.Nodes, eNode.Nodes) { 77 t.Fatalf("expected nodes pointers to differ, but got same!") 78 } 79 // Original should be the same 80 testutil.AssertEqual(t, eNode.Key, key) 81 testutil.AssertEqual(t, eNode.TTL, ttl) 82 testutil.AssertEqual(t, eNode.CreatedIndex, ci) 83 testutil.AssertEqual(t, eNode.ModifiedIndex, mi) 84 testutil.AssertEqual(t, eNode.Value, valp) 85 testutil.AssertEqual(t, eNode.Expiration, expp) 86 if !sameSlice(eNode.Nodes, childs) { 87 t.Fatalf("expected nodes pointer to same, but got different!") 88 } 89 // Change the clone and ensure the original is not affected 90 gNode.Key = "/baz" 91 gNode.TTL = 0 92 gNode.Nodes[0].Key = "uno" 93 testutil.AssertEqual(t, eNode.Key, key) 94 testutil.AssertEqual(t, eNode.TTL, ttl) 95 testutil.AssertEqual(t, eNode.CreatedIndex, ci) 96 testutil.AssertEqual(t, eNode.ModifiedIndex, mi) 97 testutil.AssertEqual(t, *eNode.Nodes[0], child) 98 // Change the original and ensure the clone is not affected 99 eNode.Key = "/wuf" 100 testutil.AssertEqual(t, eNode.Key, "/wuf") 101 testutil.AssertEqual(t, gNode.Key, "/baz") 102 } 103 104 func sameSlice(a, b []*NodeExtern) bool { 105 ah := (*reflect.SliceHeader)(unsafe.Pointer(&a)) 106 bh := (*reflect.SliceHeader)(unsafe.Pointer(&b)) 107 return *ah == *bh 108 }