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  }