mirror of
https://github.com/etcd-io/etcd.git
synced 2024-09-27 06:25:44 +00:00
store: copy Nodes correctly in NodeExtern.Clone
This commit is contained in:
parent
b59961228b
commit
a910d8ba9f
@ -77,7 +77,7 @@ func (eNode *NodeExtern) Clone() *NodeExtern {
|
|||||||
if eNode == nil {
|
if eNode == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
en := &NodeExtern{
|
nn := &NodeExtern{
|
||||||
Key: eNode.Key,
|
Key: eNode.Key,
|
||||||
Dir: eNode.Dir,
|
Dir: eNode.Dir,
|
||||||
TTL: eNode.TTL,
|
TTL: eNode.TTL,
|
||||||
@ -86,17 +86,19 @@ func (eNode *NodeExtern) Clone() *NodeExtern {
|
|||||||
}
|
}
|
||||||
if eNode.Value != nil {
|
if eNode.Value != nil {
|
||||||
s := *eNode.Value
|
s := *eNode.Value
|
||||||
en.Value = &s
|
nn.Value = &s
|
||||||
}
|
}
|
||||||
if eNode.Expiration != nil {
|
if eNode.Expiration != nil {
|
||||||
t := *eNode.Expiration
|
t := *eNode.Expiration
|
||||||
en.Expiration = &t
|
nn.Expiration = &t
|
||||||
}
|
}
|
||||||
eNode.Nodes = make(NodeExterns, len(en.Nodes))
|
if eNode.Nodes != nil {
|
||||||
for i, n := range en.Nodes {
|
nn.Nodes = make(NodeExterns, len(eNode.Nodes))
|
||||||
eNode.Nodes[i] = n.Clone()
|
for i, n := range eNode.Nodes {
|
||||||
|
nn.Nodes[i] = n.Clone()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return en
|
return nn
|
||||||
}
|
}
|
||||||
|
|
||||||
type NodeExterns []*NodeExtern
|
type NodeExterns []*NodeExtern
|
||||||
|
@ -1,8 +1,10 @@
|
|||||||
package store
|
package store
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"reflect"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
"unsafe"
|
||||||
)
|
)
|
||||||
import "github.com/coreos/etcd/Godeps/_workspace/src/github.com/stretchr/testify/assert"
|
import "github.com/coreos/etcd/Godeps/_workspace/src/github.com/stretchr/testify/assert"
|
||||||
|
|
||||||
@ -19,10 +21,13 @@ func TestNodeExternClone(t *testing.T) {
|
|||||||
mi uint64 = 321
|
mi uint64 = 321
|
||||||
)
|
)
|
||||||
var (
|
var (
|
||||||
val = "some_data"
|
val = "some_data"
|
||||||
valp = &val
|
valp = &val
|
||||||
exp = time.Unix(12345, 67890)
|
exp = time.Unix(12345, 67890)
|
||||||
expp = &exp
|
expp = &exp
|
||||||
|
child = NodeExtern{}
|
||||||
|
childp = &child
|
||||||
|
childs = []*NodeExtern{childp}
|
||||||
)
|
)
|
||||||
|
|
||||||
eNode = &NodeExtern{
|
eNode = &NodeExtern{
|
||||||
@ -32,6 +37,7 @@ func TestNodeExternClone(t *testing.T) {
|
|||||||
ModifiedIndex: mi,
|
ModifiedIndex: mi,
|
||||||
Value: valp,
|
Value: valp,
|
||||||
Expiration: expp,
|
Expiration: expp,
|
||||||
|
Nodes: childs,
|
||||||
}
|
}
|
||||||
|
|
||||||
gNode := eNode.Clone()
|
gNode := eNode.Clone()
|
||||||
@ -43,6 +49,8 @@ func TestNodeExternClone(t *testing.T) {
|
|||||||
// values should be the same
|
// values should be the same
|
||||||
assert.Equal(t, *gNode.Value, val)
|
assert.Equal(t, *gNode.Value, val)
|
||||||
assert.Equal(t, *gNode.Expiration, exp)
|
assert.Equal(t, *gNode.Expiration, exp)
|
||||||
|
assert.Equal(t, len(gNode.Nodes), len(childs))
|
||||||
|
assert.Equal(t, *gNode.Nodes[0], child)
|
||||||
// but pointers should differ
|
// but pointers should differ
|
||||||
if gNode.Value == eNode.Value {
|
if gNode.Value == eNode.Value {
|
||||||
t.Fatalf("expected value pointers to differ, but got same!")
|
t.Fatalf("expected value pointers to differ, but got same!")
|
||||||
@ -50,6 +58,9 @@ func TestNodeExternClone(t *testing.T) {
|
|||||||
if gNode.Expiration == eNode.Expiration {
|
if gNode.Expiration == eNode.Expiration {
|
||||||
t.Fatalf("expected expiration pointers to differ, but got same!")
|
t.Fatalf("expected expiration pointers to differ, but got same!")
|
||||||
}
|
}
|
||||||
|
if sameSlice(gNode.Nodes, eNode.Nodes) {
|
||||||
|
t.Fatalf("expected nodes pointers to differ, but got same!")
|
||||||
|
}
|
||||||
// Original should be the same
|
// Original should be the same
|
||||||
assert.Equal(t, eNode.Key, key)
|
assert.Equal(t, eNode.Key, key)
|
||||||
assert.Equal(t, eNode.TTL, ttl)
|
assert.Equal(t, eNode.TTL, ttl)
|
||||||
@ -57,15 +68,26 @@ func TestNodeExternClone(t *testing.T) {
|
|||||||
assert.Equal(t, eNode.ModifiedIndex, mi)
|
assert.Equal(t, eNode.ModifiedIndex, mi)
|
||||||
assert.Equal(t, eNode.Value, valp)
|
assert.Equal(t, eNode.Value, valp)
|
||||||
assert.Equal(t, eNode.Expiration, expp)
|
assert.Equal(t, eNode.Expiration, expp)
|
||||||
|
if !sameSlice(eNode.Nodes, childs) {
|
||||||
|
t.Fatalf("expected nodes pointer to same, but got different!")
|
||||||
|
}
|
||||||
// Change the clone and ensure the original is not affected
|
// Change the clone and ensure the original is not affected
|
||||||
gNode.Key = "/baz"
|
gNode.Key = "/baz"
|
||||||
gNode.TTL = 0
|
gNode.TTL = 0
|
||||||
|
gNode.Nodes[0].Key = "uno"
|
||||||
assert.Equal(t, eNode.Key, key)
|
assert.Equal(t, eNode.Key, key)
|
||||||
assert.Equal(t, eNode.TTL, ttl)
|
assert.Equal(t, eNode.TTL, ttl)
|
||||||
assert.Equal(t, eNode.CreatedIndex, ci)
|
assert.Equal(t, eNode.CreatedIndex, ci)
|
||||||
assert.Equal(t, eNode.ModifiedIndex, mi)
|
assert.Equal(t, eNode.ModifiedIndex, mi)
|
||||||
|
assert.Equal(t, *eNode.Nodes[0], child)
|
||||||
// Change the original and ensure the clone is not affected
|
// Change the original and ensure the clone is not affected
|
||||||
eNode.Key = "/wuf"
|
eNode.Key = "/wuf"
|
||||||
assert.Equal(t, eNode.Key, "/wuf")
|
assert.Equal(t, eNode.Key, "/wuf")
|
||||||
assert.Equal(t, gNode.Key, "/baz")
|
assert.Equal(t, gNode.Key, "/baz")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func sameSlice(a, b []*NodeExtern) bool {
|
||||||
|
ah := (*reflect.SliceHeader)(unsafe.Pointer(&a))
|
||||||
|
bh := (*reflect.SliceHeader)(unsafe.Pointer(&b))
|
||||||
|
return *ah == *bh
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user