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  }