github.com/aristanetworks/goarista@v0.0.0-20240514173732-cca2755bbd44/key/pointer_test.go (about) 1 // Copyright (c) 2018 Arista Networks, Inc. 2 // Use of this source code is governed by the Apache License 2.0 3 // that can be found in the COPYING file. 4 5 package key_test 6 7 import ( 8 "encoding/json" 9 "fmt" 10 "testing" 11 12 "github.com/aristanetworks/goarista/key" 13 "github.com/aristanetworks/goarista/path" 14 ) 15 16 func TestPointer(t *testing.T) { 17 p := key.NewPointer(path.New("foo")) 18 if expected, actual := path.New("foo"), p.Pointer(); !path.Equal(expected, actual) { 19 t.Errorf("Expected %#v but got %#v", expected, actual) 20 } 21 if expected, actual := "{/foo}", fmt.Sprintf("%s", p); actual != expected { 22 t.Errorf("Expected %q but got %q", expected, actual) 23 } 24 if js, err := json.Marshal(p); err != nil { 25 t.Errorf("JSON marshaling failed: %s", err) 26 } else if expected, actual := `{"_ptr":"/foo"}`, string(js); actual != expected { 27 t.Errorf("Expected %q but got %q", expected, actual) 28 } 29 } 30 31 type pointer string 32 33 func (ptr pointer) Pointer() key.Path { 34 return path.FromString(string(ptr)) 35 } 36 37 func (ptr pointer) ToBuiltin() interface{} { 38 panic("NOT IMPLEMENTED") 39 } 40 41 func (ptr pointer) String() string { 42 panic("NOT IMPLEMENTED") 43 } 44 45 func (ptr pointer) MarshalJSON() ([]byte, error) { 46 panic("NOT IMPLEMENTED") 47 } 48 49 func TestPointerEqual(t *testing.T) { 50 tests := []struct { 51 a key.Pointer 52 b key.Pointer 53 result bool 54 }{{ 55 a: key.NewPointer(nil), 56 b: key.NewPointer(path.New()), 57 result: true, 58 }, { 59 a: key.NewPointer(path.New()), 60 b: key.NewPointer(nil), 61 result: true, 62 }, { 63 a: key.NewPointer(path.New("foo")), 64 b: key.NewPointer(path.New("foo")), 65 result: true, 66 }, { 67 a: key.NewPointer(path.New("foo")), 68 b: key.NewPointer(path.New("bar")), 69 result: false, 70 }, { 71 a: key.NewPointer(path.New(true)), 72 b: key.NewPointer(path.New("true")), 73 result: false, 74 }, { 75 a: key.NewPointer(path.New(int8(0))), 76 b: key.NewPointer(path.New(int16(0))), 77 result: false, 78 }, { 79 a: key.NewPointer(path.New(path.Wildcard, "bar")), 80 b: key.NewPointer(path.New("foo", path.Wildcard)), 81 result: false, 82 }, { 83 a: key.NewPointer(path.New(map[string]interface{}{"a": "x", "b": "y"})), 84 b: key.NewPointer(path.New(map[string]interface{}{"b": "y", "a": "x"})), 85 result: true, 86 }, { 87 a: key.NewPointer(path.New(map[string]interface{}{"a": "x", "b": "y"})), 88 b: key.NewPointer(path.New(map[string]interface{}{"x": "x", "y": "y"})), 89 result: false, 90 }, { 91 a: key.NewPointer(path.New("foo")), 92 b: pointer("/foo"), 93 result: true, 94 }, { 95 a: pointer("/foo"), 96 b: key.NewPointer(path.New("foo")), 97 result: true, 98 }, { 99 a: key.NewPointer(path.New("foo")), 100 b: pointer("/foo/bar"), 101 result: false, 102 }, { 103 a: pointer("/foo/bar"), 104 b: key.NewPointer(path.New("foo")), 105 result: false, 106 }} 107 108 for i, tcase := range tests { 109 if key.New(tcase.a).Equal(key.New(tcase.b)) != tcase.result { 110 t.Errorf("Error in pointer comparison for test %d", i) 111 } 112 } 113 } 114 115 func TestPointerAsKey(t *testing.T) { 116 a := key.NewPointer(path.New("foo", path.Wildcard, map[string]interface{}{ 117 "bar": key.NewMap( 118 // Should be able to embed pointer key. 119 key.New(key.NewPointer(path.New("baz"))), 120 // Should be able to embed pointer value. 121 key.NewPointer(path.New("baz"))), 122 })) 123 m := key.NewMap(key.New(a), "a") 124 if s, ok := m.Get(key.New(a)); !ok { 125 t.Error("pointer to path not keyed in map") 126 } else if s != "a" { 127 t.Errorf("pointer to path not mapped to correct value in map: %s", s) 128 } 129 130 // Ensure that we preserve custom pointer implementations. 131 b := key.New(pointer("/foo/bar")) 132 if _, ok := b.Key().(pointer); !ok { 133 t.Errorf("pointer implementation not preserved: %T", b.Key()) 134 } 135 } 136 137 func BenchmarkPointer(b *testing.B) { 138 benchmarks := []key.Path{ 139 path.New(), 140 path.New("foo"), 141 path.New("foo", "bar"), 142 path.New("foo", "bar", "baz"), 143 path.New("foo", "bar", "baz", "qux"), 144 } 145 for i, benchmark := range benchmarks { 146 b.Run(fmt.Sprintf("%d", i), func(b *testing.B) { 147 for i := 0; i < b.N; i++ { 148 key.NewPointer(benchmark) 149 } 150 }) 151 } 152 } 153 154 func BenchmarkPointerAsKey(b *testing.B) { 155 benchmarks := []key.Pointer{ 156 key.NewPointer(path.New()), 157 key.NewPointer(path.New("foo")), 158 key.NewPointer(path.New("foo", "bar")), 159 key.NewPointer(path.New("foo", "bar", "baz")), 160 key.NewPointer(path.New("foo", "bar", "baz", "qux")), 161 } 162 for i, benchmark := range benchmarks { 163 b.Run(fmt.Sprintf("%d", i), func(b *testing.B) { 164 for i := 0; i < b.N; i++ { 165 key.New(benchmark) 166 } 167 }) 168 } 169 } 170 171 func BenchmarkEmbeddedPointerAsKey(b *testing.B) { 172 benchmarks := [][]interface{}{ 173 []interface{}{key.NewPointer(path.New())}, 174 []interface{}{key.NewPointer(path.New("foo"))}, 175 []interface{}{key.NewPointer(path.New("foo", "bar"))}, 176 []interface{}{key.NewPointer(path.New("foo", "bar", "baz"))}, 177 []interface{}{key.NewPointer(path.New("foo", "bar", "baz", "qux"))}, 178 } 179 for i, benchmark := range benchmarks { 180 b.Run(fmt.Sprintf("%d", i), func(b *testing.B) { 181 for i := 0; i < b.N; i++ { 182 key.New(benchmark) 183 } 184 }) 185 } 186 }