github.com/cloudwego/dynamicgo@v0.2.6-0.20240519101509-707f41b6b834/thrift/generic/error_test.go (about) 1 /** 2 * Copyright 2023 CloudWeGo Authors. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package generic 18 19 import ( 20 "testing" 21 "unsafe" 22 23 "github.com/cloudwego/dynamicgo/meta" 24 "github.com/cloudwego/dynamicgo/thrift" 25 "github.com/stretchr/testify/require" 26 ) 27 28 func setWrongData(v Value, pathes ...Path) { 29 c := v.GetByPath(pathes...) 30 if c.Check() != nil { 31 panic(c.Error()) 32 } 33 34 switch c.Type() { 35 case thrift.STRUCT: 36 p := (*[3]byte)(unsafe.Pointer(uintptr(c.v))) 37 *p = [3]byte{0xff, 0xff, 0xff} 38 case thrift.MAP: 39 p := (*[6]byte)(unsafe.Pointer(uintptr(c.v))) 40 *p = [6]byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff} 41 case thrift.LIST, thrift.SET: 42 p := (*[5]byte)(unsafe.Pointer(uintptr(c.v))) 43 *p = [5]byte{0xff, 0xff, 0xff, 0xff, 0xff} 44 default: 45 panic("not implement yet") 46 } 47 } 48 49 func TestError(t *testing.T) { 50 desc := getExampleDesc() 51 data := getExampleData() 52 53 errRead1 := meta.NewError(meta.ErrRead, "", nil) 54 errRead2 := errNode(meta.ErrRead, "", nil) 55 errUnsupportedType := errValue(meta.ErrUnsupportedType, "", nil) 56 errNode := NewNode(thrift.ERROR, nil) 57 errUnknownField := errValue(meta.ErrUnknownField, "", nil) 58 59 t.Run("struct", func(t *testing.T) { 60 opts := &Options{} 61 cases := []testAPICase{ 62 {name: "", api: "Field", args: []interface{}{thrift.FieldID(1)}, exp: nil, err: errRead2}, 63 {name: "", api: "FieldByName", args: []interface{}{"xx"}, exp: nil, err: errUnknownField}, 64 {name: "", api: "Index", args: []interface{}{1}, exp: nil, err: errUnsupportedType}, 65 {name: "", api: "GetByStr", args: []interface{}{"xx"}, exp: nil, err: errUnsupportedType}, 66 {name: "", api: "GetByInt", args: []interface{}{1}, exp: nil, err: errUnsupportedType}, 67 {name: "", api: "Interface", args: []interface{}{opts}, exp: nil, err: errNode}, 68 {name: "", api: "Children", args: []interface{}{&[]PathNode{}, false, opts}, exp: nil, err: errRead1}, 69 } 70 data := []byte(string(data)) 71 v := NewValue(desc, data) 72 n := v.GetByPath(PathInnerBase) 73 setWrongData(v, PathInnerBase) 74 for _, c := range cases { 75 t.Run(c.api, func(t *testing.T) { 76 c.path = []Path{PathInnerBase} 77 APIHelper(t, nil, &n, c) 78 }) 79 } 80 }) 81 82 t.Run("strmap", func(t *testing.T) { 83 opts := &Options{} 84 cases := []testAPICase{ 85 {name: "", api: "Field", args: []interface{}{thrift.FieldID(1)}, exp: nil, err: errUnsupportedType}, 86 {name: "", api: "FieldByName", args: []interface{}{"xx"}, exp: nil, err: errUnsupportedType}, 87 {name: "", api: "Index", args: []interface{}{1}, exp: nil, err: errUnsupportedType}, 88 {name: "", api: "GetByStr", args: []interface{}{"a"}, exp: nil, err: errRead2}, 89 {name: "", api: "GetByInt", args: []interface{}{1}, exp: nil, err: errUnsupportedType}, 90 {name: "", api: "Interface", args: []interface{}{opts}, exp: map[string]interface{}(nil), err: errRead1}, 91 {name: "", api: "Children", args: []interface{}{&[]PathNode{}, false, opts}, exp: nil, err: errRead1}, 92 } 93 data := []byte(string(data)) 94 v := NewValue(desc, data) 95 n := v.GetByPath(PathExampleMapStringString...) 96 setWrongData(v, PathExampleMapStringString...) 97 for _, c := range cases { 98 t.Run(c.api, func(t *testing.T) { 99 c.path = []Path{PathInnerBase} 100 APIHelper(t, nil, &n, c) 101 }) 102 } 103 }) 104 105 t.Run("intmap", func(t *testing.T) { 106 opts := &Options{} 107 cases := []testAPICase{ 108 {name: "", api: "Field", args: []interface{}{thrift.FieldID(1)}, exp: nil, err: errUnsupportedType}, 109 {name: "", api: "FieldByName", args: []interface{}{"xx"}, exp: nil, err: errUnsupportedType}, 110 {name: "", api: "Index", args: []interface{}{1}, exp: nil, err: errUnsupportedType}, 111 {name: "", api: "GetByStr", args: []interface{}{"a"}, exp: nil, err: errUnsupportedType}, 112 {name: "", api: "GetByInt", args: []interface{}{1}, exp: nil, err: errRead2}, 113 {name: "", api: "Interface", args: []interface{}{opts}, exp: map[int]interface{}(nil), err: errRead1}, 114 {name: "", api: "Children", args: []interface{}{&[]PathNode{}, false, opts}, exp: nil, err: errRead1}, 115 } 116 data := []byte(string(data)) 117 v := NewValue(desc, data) 118 n := v.GetByPath(PathExampleMapInt32String...) 119 setWrongData(v, PathExampleMapInt32String...) 120 for _, c := range cases { 121 t.Run(c.api, func(t *testing.T) { 122 c.path = []Path{PathInnerBase} 123 APIHelper(t, nil, &n, c) 124 }) 125 } 126 }) 127 128 t.Run("list", func(t *testing.T) { 129 opts := &Options{} 130 cases := []testAPICase{ 131 {name: "", api: "Field", args: []interface{}{thrift.FieldID(1)}, exp: nil, err: errUnsupportedType}, 132 {name: "", api: "FieldByName", args: []interface{}{"xx"}, exp: nil, err: errUnsupportedType}, 133 {name: "", api: "Index", args: []interface{}{1}, exp: nil, err: errRead2}, 134 {name: "", api: "GetByStr", args: []interface{}{"a"}, exp: nil, err: errUnsupportedType}, 135 {name: "", api: "GetByInt", args: []interface{}{1}, exp: nil, err: errUnsupportedType}, 136 {name: "", api: "Interface", args: []interface{}{opts}, exp: []interface{}(nil), err: errRead1}, 137 {name: "", api: "Children", args: []interface{}{&[]PathNode{}, false, opts}, exp: nil, err: errRead1}, 138 } 139 data := []byte(string(data)) 140 v := NewValue(desc, data) 141 n := v.GetByPath(PathExampleListInt32...) 142 setWrongData(v, PathExampleListInt32...) 143 for _, c := range cases { 144 t.Run(c.api, func(t *testing.T) { 145 c.path = []Path{PathInnerBase} 146 APIHelper(t, nil, &n, c) 147 }) 148 } 149 }) 150 } 151 152 func TestWrapError(t *testing.T) { 153 desc := getExampleDesc() 154 data := getExampleData() 155 opts := Options{} 156 v := NewValue(desc, data) 157 tree := PathNode{ 158 Path: NewPathFieldName("root"), 159 Node: v.Node, 160 Next: []PathNode{ 161 { 162 Path: NewPathFieldId(3), 163 Node: v.GetByPath(PathInnerBase).Node, 164 Next: []PathNode{ 165 { 166 Path: NewPathFieldId(9), 167 Node: v.GetByPath(PathExampleMapStringString...).Node, 168 }, 169 { 170 Path: NewPathFieldId(12), 171 Node: v.GetByPath(PathExampleMapInt32String...).Node, 172 }, 173 { 174 Path: NewPathFieldId(8), 175 Node: v.GetByPath(PathExampleListInt32...).Node, 176 }, 177 }, 178 }, 179 }, 180 } 181 e := meta.NewError(meta.NewErrorCode(meta.ErrNotFound, meta.THRIFT), "", nil) 182 ev := errNode(meta.ErrRead, "", e) 183 t.Run("struct", func(t *testing.T) { 184 tree := tree.Fork() 185 tree.Next[0].Node = ev 186 out, err := tree.Marshal(&opts) 187 require.Nil(t, out) 188 require.NotNil(t, err) 189 require.Equal(t, meta.ErrRead, err.(meta.Error).Code.Behavior()) 190 }) 191 192 t.Run("strmap", func(t *testing.T) { 193 tree := tree.Fork() 194 tree.Next[0].Next[0].Next = []PathNode{{Path: NewPathStrKey("x"), Node: ev}} 195 out, err := tree.Marshal(&opts) 196 require.Nil(t, out) 197 require.NotNil(t, err) 198 require.Equal(t, meta.ErrRead, err.(meta.Error).Code.Behavior()) 199 }) 200 201 t.Run("intmap", func(t *testing.T) { 202 tree := tree.Fork() 203 tree.Next[0].Next[1].Next = []PathNode{{Path: NewPathIntKey(999), Node: ev}} 204 out, err := tree.Marshal(&opts) 205 require.Nil(t, out) 206 require.NotNil(t, err) 207 require.Equal(t, meta.ErrRead, err.(meta.Error).Code.Behavior()) 208 }) 209 210 t.Run("list", func(t *testing.T) { 211 tree := tree.Fork() 212 tree.Next[0].Next[2].Next = []PathNode{{Path: NewPathIndex(999), Node: ev}} 213 out, err := tree.Marshal(&opts) 214 require.Nil(t, out) 215 require.NotNil(t, err) 216 require.Equal(t, meta.ErrRead, err.(meta.Error).Code.Behavior()) 217 }) 218 }