node_extern_test.go 3.0 KB

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