2
0
Fork 0
mirror of https://github.com/ii64/sonic.git synced 2026-06-21 00:46:43 +08:00

test: add fuzz test in Go 1.18 (#208)

This commit is contained in:
liu 2022-04-01 15:04:54 +08:00 committed by GitHub
parent cb1702dc8c
commit d9b9980291
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
16 changed files with 16070 additions and 0 deletions

10
fuzz/Makefile Normal file
View file

@ -0,0 +1,10 @@
fuzz:
mkdir -p ./testdata/fuzz/FuzzMain
git clone https://github.com/dvyukov/go-fuzz-corpus.git ./go-fuzz-corpus/
file2fuzz -o ./testdata/fuzz/FuzzMain ./go-fuzz-corpus/json/corpus/* ./corpus/*
go test -fuzz=Fuzz -v
clean:
rm -rf ./go-fuzz-corpus/
rm -rf ./testdata/

76
fuzz/ast_fuzz_test.go Normal file
View file

@ -0,0 +1,76 @@
// +build go1.18
/*
* Copyright 2021 ByteDance Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package sonic_fuzz
import (
`testing`
`github.com/bytedance/sonic`
`github.com/bytedance/sonic/ast`
`github.com/stretchr/testify/require`
)
func fuzzASTGetFromObject(t *testing.T, data []byte, m map[string]interface{}) {
for k, expv := range(m) {
node, err := sonic.Get(data, k)
require.NoErrorf(t, err, "error in ast get key -> %s", k)
assertAstNode(t, node, expv)
}
}
func fuzzASTGetFromArray(t *testing.T, data []byte, a []interface{}) {
var i = 0
for ; i < len(a); i++ {
node, err := sonic.Get(data, i)
require.NoErrorf(t, err, "error in ast get index -> %s", i)
assertAstNode(t, node, a[i])
}
_, err := sonic.Get(data, i)
require.Errorf(t, err, "error in ast get index -> %s", i)
}
func assertAstNode(t *testing.T, node ast.Node, expv interface{}) {
switch node.Type() {
case ast.V_NULL: require.Nilf(t, expv, "wrong in ast null")
case ast.V_TRUE: fallthrough
case ast.V_FALSE:
gotv, err := node.Bool()
require.NoErrorf(t, err, "error in ast get bool")
require.Equalf(t, gotv, expv, "wrong in get bool")
case ast.V_STRING:
gotv, err := node.String()
require.NoErrorf(t, err, "error in ast get string")
require.Equalf(t, gotv, expv, "wrong in get string")
case ast.V_ARRAY:
gotv, err := node.Array()
require.NoErrorf(t, err, "error in ast get array")
require.Equalf(t, gotv, expv, "wrong in get array")
case ast.V_OBJECT:
gotv, err := node.Map()
require.NoErrorf(t, err, "error in ast get object")
require.Equalf(t, gotv, expv, "wrong in get object")
case ast.V_NUMBER:
gotv, err := node.Float64()
require.NoErrorf(t, err, "error in ast get number")
require.Equalf(t, gotv, expv, "wrong in get number")
case ast.V_ANY:
gotv, err := node.Interface()
require.NoErrorf(t, err, "error in ast get any")
require.Equalf(t, gotv, expv, "wrong in get any")
}
}

View file

@ -0,0 +1 @@
"&&&&&&&&&&&&&&&&&&&&&&&\xe2\xe2\xe2\xe2\xe2\xe2\xe2\xe2\xe2\xe2\xe2\xe2\xe2\xe2\xe2\xe2\xe2\xe2\xe2\xe2\xe2\xe2\xe2\xe2\xe2\xe2\xe2\xe2\xe2\xe2\xe2\xe2\xe2\xe2\xe2\xe2\xe2\xe2\xe2\xe2\xe2\xe2\xe2\xe2\xe2\xe2\xe2\xe2\xe2\xe2\xe2\xe2\xe2\xe2\xe2\xe2\xe2\xe2\xe2\xe2\xe2\xe2\xe2\xe2\xe2\xe2\xe2\xe2\xe2\xe2\xe2\xe2\xe2\xe2&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&"

View file

@ -0,0 +1 @@
"{\"\"\u2028\x94\xe2\x00\x00\x00\x00\x00\x00\x00\x00\u2028\x80\u2028\x80\u2028\xe2\u2028\x8a\u2028⑀\xa8\x8a\xa8\xe2\u2028\xe2\u2028\xe2\u2028\xe2\u2000\x8d\xe2\u2028\xe2\u2028\xe2\xe2\xa8\"}"

View file

@ -0,0 +1 @@
"&<>\u2028\u2029"

View file

@ -0,0 +1 @@
"123"

View file

@ -0,0 +1 @@
"-1.23e+1"

50
fuzz/corpus/struct.json Normal file
View file

@ -0,0 +1,50 @@
{
"A": -8111819689795174000,
"B": "fQhhLProOY hello \\\" 你好 😊",
"C": 3.577476171476308e+307,
"D": true,
"E": 101,
"G": null,
"H": {
"xSVe": null
},
"I": {
"ziiOUtpFV": "RfJwBZnEwm"
},
"J": [
null,
true,
[],
{}
],
"K": [
"fSiOMJVJdi",
"CLpA",
"\\",
"123",
""
],
"L": {
"A": -1231349968732903200,
"B": "QUqZKwhY"
},
"M": {
"A": 5011712756157650000,
"B": "hWkae"
},
"N": -8055612484288639000,
"O": -412156671407452740,
"P": "123",
"Q": "-1.23e+1",
"R": 0,
"T": {},
"U": [
7233499441428055000,
3869227355117358600
],
"V": 0,
"W": "0.123456e-123",
"X": {"raw": "json"},
"Y": "abc",
"Z": "123"
}

15482
fuzz/corpus/twitter.json Normal file

File diff suppressed because it is too large Load diff

File diff suppressed because one or more lines are too long

173
fuzz/fuzz_test.go Normal file
View file

@ -0,0 +1,173 @@
// +build go1.18
/*
* Copyright 2021 ByteDance Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package sonic_fuzz
import (
`encoding/json`
`testing`
`unicode/utf8`
`reflect`
`os`
`runtime`
`runtime/debug`
`time`
`github.com/bytedance/sonic`
`github.com/stretchr/testify/require`
)
func FuzzMain(f *testing.F) {
f.Add([]byte(`{
"object": {
"slice": [
1,
2.0,
"3",
[4],
{5: {}}
]
},
"slice": [[]],
"string": ":)",
"int": 1e5,
"float": 3e-9"
}`))
f.Fuzz(fuzzMain)
}
func fuzzMain(t *testing.T, data []byte) {
fuzzValidate(t, data)
fuzzHtmlEscape(t, data)
// Only fuzz the validate json here, because the default configuration does not have validation in SONIC.
if !utf8.Valid(data) || !json.Valid(data) {
return
}
for _, typ := range []func() interface{}{
func() interface{} { return new(interface{}) },
func() interface{} { return new(map[string]interface{}) },
func() interface{} { return new([]interface{}) },
func() interface{} { return new(string) },
func() interface{} { return new(int64) },
func() interface{} { return new(uint64) },
func() interface{} { return new(float64) },
func() interface{} { return new(json.Number) },
func() interface{} { return new(json.RawMessage) },
func() interface{} { return new(S) },
} {
sv, jv := typ(), typ()
serr := sonic.Unmarshal([]byte(data), sv)
jerr := json.Unmarshal([]byte(data), jv)
require.Equalf(t, serr != nil, jerr != nil, "different error in sonic unmarshal %v", reflect.TypeOf(jv))
if jerr != nil {
return
}
require.Equal(t, sv, jv, "different result in sonic unmarshal %v", reflect.TypeOf(jv))
sout, serr := sonic.Marshal(sv)
jout, jerr := json.Marshal(jv)
require.NoError(t, serr, "error in sonic marshal %v", reflect.TypeOf(jv))
require.NoError(t, jerr, "error in json marshal %v", reflect.TypeOf(jv))
// not comparing here because sonic marshal is different from encoding/json, as:
// case 1: 1.23e2 -> `1.23e2` in sonic, but 1.23e2 -> `1.23e+2` in encoding/json
// case 2: "\b" -> `\\b` in sonic, but `\u0008` in encoding/json
// require.Equal(t, sout, jout, "different in sonic marshal %v", reflect.TypeOf(jv))
var _, _ = sout, jout
if m, ok := sv.(*map[string]interface{}); ok {
fuzzDynamicStruct(t, jout, *m)
fuzzASTGetFromObject(t, jout, *m)
}
if a, ok := sv.(*[]interface{}); ok {
fuzzASTGetFromArray(t, jout, *a)
}
}
}
type S struct {
A int `json:",omitempty"`
B string `json:"B1,omitempty"`
C float64
D bool
E uint8
// F []byte // unmarshal []byte is different with encoding/json
G interface{}
H map[string]interface{}
I map[string]string
J []interface{}
K []string
L S1
M *S1
N *int
O **int
P int `json:",string"`
Q float64 `json:",string"`
R int `json:"-"`
T struct {}
U [2]int
V uintptr
W json.Number
X json.RawMessage
Y Marshaller
Z TextMarshaller
}
type S1 struct {
A int
B string
}
type Marshaller struct {
v string
}
func (m *Marshaller) MarshalJSON() ([]byte, error) {
return json.Marshal(m.v)
}
func (m *Marshaller) UnmarshalJSON(data []byte) error {
return json.Unmarshal(data, &m.v)
}
type TextMarshaller struct {
v int
}
func (k *TextMarshaller) MarshalText() ([]byte, error) {
return json.Marshal(k.v)
}
func (k *TextMarshaller) UnmarshalText(data []byte) error {
return json.Unmarshal(data, &k.v)
}
var debugAsyncGC = os.Getenv("SONIC_NO_ASYNC_GC") == ""
func TestMain(m *testing.M) {
go func () {
if !debugAsyncGC {
return
}
println("Begin GC looping...")
for {
runtime.GC()
debug.FreeOSMemory()
}
}()
time.Sleep(time.Millisecond)
m.Run()
}

20
fuzz/go.mod Normal file
View file

@ -0,0 +1,20 @@
module github.com/bytedance/sonic/fuzz
go 1.18
require (
github.com/bytedance/sonic v1.0.0
github.com/stretchr/testify v1.7.0
)
require (
github.com/chenzhuoyu/base64x v0.0.0-20211019084208-fb5309c8db06 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/klauspost/cpuid/v2 v2.0.9 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
golang.org/x/arch v0.0.0-20210923205945-b76863e36670 // indirect
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c // indirect
)
replace github.com/bytedance/sonic => ../.

40
fuzz/go.sum Normal file
View file

@ -0,0 +1,40 @@
github.com/chenzhuoyu/base64x v0.0.0-20211019084208-fb5309c8db06 h1:1sDoSuDPWzhkdzNVxCxtIaKiAe96ESVPv8coGwc1gZ4=
github.com/chenzhuoyu/base64x v0.0.0-20211019084208-fb5309c8db06/go.mod h1:DH46F32mSOjUmXrMHnKwZdA8wcEefY7UVqBKYGjpdQY=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/goccy/go-json v0.9.4 h1:L8MLKG2mvVXiQu07qB6hmfqeSYQdOnqPot2GhsIwIaI=
github.com/goccy/go-json v0.9.4/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
github.com/klauspost/cpuid/v2 v2.0.9 h1:lgaqFMSdTdQYdZ04uHyN2d/eKdOMyi2YLSvlQIBFYa4=
github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/tidwall/gjson v1.12.1/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
github.com/tidwall/gjson v1.13.0 h1:3TFY9yxOQShrvmjdM76K+jc66zJeT6D3/VFFYCGQf7M=
github.com/tidwall/gjson v1.13.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA=
github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM=
github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs=
github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
github.com/tidwall/sjson v1.2.4 h1:cuiLzLnaMeBhRmEv00Lpk3tkYrcxpmbU81tAY4Dw0tc=
github.com/tidwall/sjson v1.2.4/go.mod h1:098SZ494YoMWPmMO6ct4dcFnqxwj9r/gF0Etp19pSNM=
github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI=
github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08=
golang.org/x/arch v0.0.0-20210923205945-b76863e36670 h1:18EFjUmQOcUvxNYSkA6jO9VAiXCnxFY6NyDX0bHDmkU=
golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4=

47
fuzz/other_fuzz_test.go Normal file
View file

@ -0,0 +1,47 @@
// +build go1.18
/*
* Copyright 2021 ByteDance Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package sonic_fuzz
import (
`bytes`
`testing`
`encoding/json`
`unicode/utf8`
`github.com/bytedance/sonic/encoder`
`github.com/stretchr/testify/require`
`github.com/davecgh/go-spew/spew`
)
func fuzzValidate(t *testing.T, data []byte){
jok1 := json.Valid(data)
jok2 := utf8.Valid(data)
jok := jok1 && jok2
sok, _ := encoder.Valid(data)
spew.Dump(data, jok1, jok2, sok)
require.Equalf(t, jok, sok, "different validate results")
}
func fuzzHtmlEscape(t *testing.T, data []byte){
var jdst bytes.Buffer
var sdst []byte
json.HTMLEscape(&jdst, data)
sdst = encoder.HTMLEscape(sdst, data)
require.Equalf(t, string(jdst.Bytes()), string(sdst), "different htmlescape results")
}

165
fuzz/struct_fuzz_test.go Normal file
View file

@ -0,0 +1,165 @@
// +build go1.18
/*
* Copyright 2021 ByteDance Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package sonic_fuzz
import (
`encoding/json`
`math/rand`
`fmt`
`reflect`
`strconv`
`strings`
`testing`
`github.com/bytedance/sonic`
`github.com/stretchr/testify/require`
)
func generateNullType() reflect.Type {
tab := []reflect.Type {
reflect.TypeOf(int(0)),
reflect.TypeOf(uint(0)),
reflect.TypeOf("string"),
reflect.TypeOf(struct{}{}),
reflect.TypeOf(json.Number("0")),
reflect.TypeOf([]interface{}{}),
reflect.TypeOf(map[string]interface{}{}),
}
return tab[int(rand.Int() % len(tab))]
}
func generateNumberType() reflect.Type {
tab := []reflect.Type {
reflect.TypeOf(float64(0)),
reflect.TypeOf(int64(0)),
reflect.TypeOf(uintptr(0)),
reflect.TypeOf(uint64(0)),
reflect.TypeOf(json.Number("0")),
}
return tab[int(rand.Int() % len(tab))]
}
func generatePointerType(ft reflect.Type) reflect.Type {
if ft == nil {
ft = generateNullType()
}
ftp := reflect.TypeOf(reflect.New(ft).Interface())
ftpp := reflect.TypeOf(reflect.New(ftp).Interface())
ftppp := reflect.TypeOf(reflect.New(ftpp).Interface())
tab := []reflect.Type { ft, ftp, ftpp, ftppp }
return tab[int(rand.Int() % len(tab))]
}
func generateJSONTag(name string) reflect.StructTag {
var opt string
name = strings.Split(name, ",")[0] // remove origin "," in tag name
switch int(rand.Int() % 5) {
case 0: return reflect.StructTag(`json:"-"`) // always omitted
case 1: return reflect.StructTag("") // empty tag
case 2: opt = "" // empty opt
case 3: opt = "omitempty"
case 4: opt = "string"
}
return reflect.StructTag(fmt.Sprintf(`json:"%s,%s"`, name, opt))
}
// Map2StructType generate random dynamic Golang Struct by Golang Map
func Map2StructType(m map[string]interface{}, maxDepth int) reflect.Type {
if maxDepth <= 0 {
return reflect.TypeOf(map[string]interface{}{})
}
fields := make([]reflect.StructField, 0)
i := 0
for k, v := range m {
/* skip the empty key */
if k == "" {
continue
}
/* set exported field name */
fn := "F" + strconv.Itoa(i)
/* set field type */
ft := reflect.TypeOf(v)
if ft == nil {
ft = generateNullType()
} else {
switch ft.Kind() {
case reflect.Map: ft = Map2StructType(v.(map[string]interface{}), maxDepth-1)
case reflect.Float64: ft = generateNumberType()
}
}
ft = generatePointerType(ft)
ef := reflect.StructField {
Name: fn,
Type: ft,
Tag : generateJSONTag(k),
}
fields = append(fields, ef)
i += 1
/* insert some private field randomly */
if int(rand.Int() % 3) != 0 {
continue
}
fn = "p" + strconv.Itoa(i)
pf := reflect.StructField {
Name: fn,
Type: ft,
PkgPath: "sonic_fuzz",
}
fields = append(fields, pf)
}
rt := reflect.StructOf(fields)
return rt
}
const _MAX_STRUCT_DEPTH = 30
// fuzzDynamicStruct is schema-based fuzz testing,
// a struct type is a JSON schema.
func fuzzDynamicStruct(t *testing.T, data []byte, v map[string]interface{}) {
typ := Map2StructType(v, _MAX_STRUCT_DEPTH)
sv := reflect.New(typ).Interface()
jv := reflect.New(typ).Interface()
// Pretouch fuzz
err := sonic.Pretouch(typ)
require.NoErrorf(t, err, "error in sonic pretouch struct %v", typ)
// Unmarshal fuzz
serr := sonic.Unmarshal(data, &sv)
jerr := json.Unmarshal(data, &jv)
require.Equalf(t, serr != nil, jerr != nil, "different error in sonic unmarshal %v", typ)
if serr != nil {
return
}
require.Equal(t, sv, jv, "different result in sonic unmarshal %v", typ)
// Marshal fuzz
sout, serr := sonic.Marshal(sv)
jout, jerr := json.Marshal(jv)
require.NoError(t, serr, "error in sonic marshal %v", typ)
require.NoError(t, jerr, "error in json marshal %v", typ)
// not comparing here because sonic marshal is different from encoding/json, as:
// require.Equalf(t, sout, jout, "different in sonic marshal %#v", typ)
var _, _ = sout, jout
}

View file

@ -3,4 +3,5 @@ go 1.18
use (
.
./generic_test
./fuzz
)