github.com/cloudwego/dynamicgo@v0.2.6-0.20240519101509-707f41b6b834/testdata/baseline_j2t_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  //go:generate kitex -module=github.com/cloudwego/dynamicgo idl/baseline.thrift
    18  package testdata
    19  
    20  import (
    21  	"bytes"
    22  	"context"
    23  	ejson "encoding/json"
    24  	"math"
    25  	stdh "net/http"
    26  	"strconv"
    27  	"strings"
    28  	"sync"
    29  	"testing"
    30  
    31  	athrift "github.com/apache/thrift/lib/go/thrift"
    32  	"github.com/bytedance/sonic"
    33  	json "github.com/bytedance/sonic/ast"
    34  	"github.com/cloudwego/dynamicgo/conv"
    35  	"github.com/cloudwego/dynamicgo/conv/j2t"
    36  	"github.com/cloudwego/dynamicgo/http"
    37  	"github.com/cloudwego/dynamicgo/testdata/kitex_gen/baseline"
    38  	"github.com/cloudwego/kitex/pkg/generic"
    39  	"github.com/cloudwego/kitex/pkg/generic/descriptor"
    40  	gthrift "github.com/cloudwego/kitex/pkg/generic/thrift"
    41  	"github.com/cloudwego/kitex/pkg/remote"
    42  	bthrift "github.com/cloudwego/kitex/pkg/remote/codec/thrift"
    43  	"github.com/stretchr/testify/require"
    44  )
    45  
    46  const (
    47  	idlPath = "idl/baseline.thrift"
    48  )
    49  
    50  var (
    51  	simpleJSON  = ""
    52  	nestingJSON = ""
    53  )
    54  
    55  func init() {
    56  	sobj := getSimpleValue()
    57  	sout, err := ejson.Marshal(sobj)
    58  	if err != nil {
    59  		panic(err)
    60  	}
    61  	simpleJSON = string(sout)
    62  	println("small data size: ", len(simpleJSON))
    63  	var out bytes.Buffer
    64  	ejson.Indent(&out, sout, "", "")
    65  	println(out.String())
    66  
    67  	nobj := getNestingValue()
    68  	nout, err := ejson.Marshal(nobj)
    69  	if err != nil {
    70  		panic(err)
    71  	}
    72  	nestingJSON = string(nout)
    73  	println("medium data size: ", len(nestingJSON))
    74  	out.Reset()
    75  
    76  	psobj := getPartialSimpleValue()
    77  	psout, err := ejson.Marshal(psobj)
    78  	if err != nil {
    79  		panic(err)
    80  	}
    81  	println("partial small data size: ", len(psout))
    82  
    83  	pnobj := getPartialNestingValue()
    84  	pnout, err := ejson.Marshal(pnobj)
    85  	if err != nil {
    86  		panic(err)
    87  	}
    88  	println("partial medium data size: ", len(pnout))
    89  }
    90  
    91  type Sample struct {
    92  	name  string
    93  	val   interface{}
    94  	bytes []byte
    95  }
    96  
    97  var samples []Sample
    98  
    99  var (
   100  	bytesCount  int = 2
   101  	stringCount int = 2
   102  	listCount   int = 16
   103  	mapCount    int = 16
   104  )
   105  
   106  func getSamples() []Sample {
   107  	return []Sample{
   108  		{samples[0].name, getSimpleValue(), samples[0].bytes},
   109  		{samples[1].name, getNestingValue(), samples[1].bytes},
   110  		{samples[2].name, getNesting2Value(), samples[2].bytes},
   111  	}
   112  }
   113  
   114  func getString() string {
   115  	return strings.Repeat("你好,\b\n\r\t世界", stringCount)
   116  }
   117  
   118  func getBytes() []byte {
   119  	return bytes.Repeat([]byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}, bytesCount)
   120  }
   121  
   122  func getSimpleValue() *baseline.Simple {
   123  	return &baseline.Simple{
   124  		ByteField:   math.MaxInt8,
   125  		I64Field:    math.MaxInt64,
   126  		DoubleField: math.MaxFloat64,
   127  		I32Field:    math.MaxInt32,
   128  		StringField: getString(),
   129  		BinaryField: getBytes(),
   130  	}
   131  }
   132  
   133  func getPartialSimpleValue() *baseline.PartialSimple {
   134  	return &baseline.PartialSimple{
   135  		ByteField:   math.MaxInt8,
   136  		DoubleField: math.MaxFloat64,
   137  		BinaryField: getBytes(),
   138  	}
   139  }
   140  
   141  func getNestingValue() *baseline.Nesting {
   142  	var ret = &baseline.Nesting{
   143  		String_:         getString(),
   144  		ListSimple:      []*baseline.Simple{},
   145  		Double:          math.MaxFloat64,
   146  		I32:             math.MaxInt32,
   147  		ListI32:         []int32{},
   148  		I64:             math.MaxInt64,
   149  		MapStringString: map[string]string{},
   150  		SimpleStruct:    getSimpleValue(),
   151  		MapI32I64:       map[int32]int64{},
   152  		ListString:      []string{},
   153  		Binary:          getBytes(),
   154  		MapI64String:    map[int64]string{},
   155  		ListI64:         []int64{},
   156  		Byte:            math.MaxInt8,
   157  		MapStringSimple: map[string]*baseline.Simple{},
   158  	}
   159  
   160  	for i := 0; i < listCount; i++ {
   161  		ret.ListSimple = append(ret.ListSimple, getSimpleValue())
   162  		ret.ListI32 = append(ret.ListI32, math.MinInt32)
   163  		ret.ListI64 = append(ret.ListI64, math.MinInt64)
   164  		ret.ListString = append(ret.ListString, getString())
   165  	}
   166  
   167  	for i := 0; i < mapCount; i++ {
   168  		ret.MapStringString[strconv.Itoa(i)] = getString()
   169  		ret.MapI32I64[int32(i)] = math.MinInt64
   170  		ret.MapI64String[int64(i)] = getString()
   171  		ret.MapStringSimple[strconv.Itoa(i)] = getSimpleValue()
   172  	}
   173  
   174  	return ret
   175  }
   176  
   177  func getPartialNestingValue() *baseline.PartialNesting {
   178  	var ret = &baseline.PartialNesting{
   179  		ListSimple:      []*baseline.PartialSimple{},
   180  		SimpleStruct:    getPartialSimpleValue(),
   181  		MapStringSimple: map[string]*baseline.PartialSimple{},
   182  	}
   183  
   184  	for i := 0; i < listCount; i++ {
   185  		ret.ListSimple = append(ret.ListSimple, getPartialSimpleValue())
   186  	}
   187  
   188  	for i := 0; i < mapCount; i++ {
   189  		ret.MapStringSimple[strconv.Itoa(i)] = getPartialSimpleValue()
   190  	}
   191  
   192  	return ret
   193  }
   194  
   195  func getNesting2Value() *baseline.Nesting2 {
   196  	var ret = &baseline.Nesting2{
   197  		MapSimpleNesting: map[*baseline.Simple]*baseline.Nesting{},
   198  		SimpleStruct:     getSimpleValue(),
   199  		Byte:             math.MaxInt8,
   200  		Double:           math.MaxFloat64,
   201  		ListNesting:      []*baseline.Nesting{},
   202  		I64:              math.MaxInt64,
   203  		NestingStruct:    getNestingValue(),
   204  		Binary:           getBytes(),
   205  		String_:          getString(),
   206  		SetNesting:       []*baseline.Nesting{},
   207  		I32:              math.MaxInt32,
   208  	}
   209  	for i := 0; i < mapCount; i++ {
   210  		ret.MapSimpleNesting[getSimpleValue()] = getNestingValue()
   211  	}
   212  	for i := 0; i < listCount; i++ {
   213  		ret.ListNesting = append(ret.ListNesting, getNestingValue())
   214  		x := getNestingValue()
   215  		x.I64 = int64(i)
   216  		ret.SetNesting = append(ret.SetNesting, x)
   217  	}
   218  	return ret
   219  }
   220  
   221  func getSampleHttpRequest(exp *baseline.Nesting, jbody string) *http.HTTPRequest {
   222  	req := http.NewHTTPRequest()
   223  	hr, err := stdh.NewRequest("POST", "localhost:8080", bytes.NewBufferString(jbody))
   224  	if err != nil {
   225  		panic(err)
   226  	}
   227  	hr.Header.Set("Content-Type", "application/json")
   228  	req.Request = hr
   229  	header := "你好"
   230  	req.Request.Header.Set("String", header)
   231  	exp.String_ = header
   232  	// h2 := "abcdefghijklmnopqrstuvwxyz"
   233  	// req.Header.Set("string_field", h2)
   234  	// exp.SimpleStruct.StringField = h2
   235  	// for i := range exp.ListSimple {
   236  	// 	exp.ListSimple[i].StringField = h2
   237  	// }
   238  	// for k := range exp.MapStringSimple {
   239  	// 	exp.MapStringSimple[k].StringField = h2
   240  	// }
   241  
   242  	c := []int64{-1, 0, math.MaxInt64, math.MinInt64}
   243  	cookie := ""
   244  	for i, v := range c {
   245  		cookie += strconv.Itoa(int(v))
   246  		if i != len(c)-1 {
   247  			cookie += ","
   248  		}
   249  	}
   250  	req.AddCookie(&stdh.Cookie{
   251  		Name:  "list_i64",
   252  		Value: cookie,
   253  	})
   254  	exp.ListI64 = c
   255  
   256  	param := math.MaxFloat64
   257  	req.Params.Set("double", strconv.FormatFloat(param, 'f', -1, 64))
   258  	exp.Double = param
   259  
   260  	q := []int32{-1, 0, math.MaxInt32, math.MinInt32}
   261  	query := ""
   262  	for i, v := range q {
   263  		query += strconv.Itoa(int(v))
   264  		if i != len(q)-1 {
   265  			query += ","
   266  		}
   267  	}
   268  	req.Request.URL.RawQuery = "ListI32=" + query
   269  	exp.ListI32 = q
   270  	return req
   271  }
   272  
   273  func getSampleHttpResponse(exp *baseline.Nesting) *http.HTTPResponse {
   274  	req := http.NewHTTPResponse()
   275  
   276  	code := int32(401)
   277  	req.StatusCode = int(code)
   278  	exp.I32 = code
   279  
   280  	header := "你好"
   281  	req.Header.Set("String", header)
   282  	exp.String_ = header
   283  
   284  	c := []int64{-1, 0, math.MaxInt64, math.MinInt64}
   285  	cookie := ""
   286  	for i, v := range c {
   287  		cookie += strconv.Itoa(int(v))
   288  		if i != len(c)-1 {
   289  			cookie += ","
   290  		}
   291  	}
   292  	req.SetCookie("list_i64", cookie)
   293  	exp.ListI64 = c
   294  	return req
   295  }
   296  
   297  // func TestThriftEncodeSimple_Load(t *testing.T) {
   298  // 	_, err := ejson.Marshal(baseline.Simple{})
   299  // 	if err != nil {
   300  // 		t.Fatal(err)
   301  // 	}
   302  // 	simple := getSimpleDesc()
   303  // 	// fmt.Printf("%#v", simple)
   304  // 	root, err := json.NewSearcher(simpleJSON).GetByPath()
   305  // 	if err != nil {
   306  // 		t.Fatal(err)
   307  // 	}
   308  // 	if err := root.LoadAll(); err != nil {
   309  // 		t.Fatal(err)
   310  // 	}
   311  // 	enc := &json.ThriftEncoder{Proto: meta.ThriftBinary, Options: &json.Options{
   312  // 		WriteDefault: true,
   313  // 	}}
   314  // 	out, err := enc.Encode(simple, root)
   315  // 	if err != nil {
   316  // 		t.Fatal(err)
   317  // 	}
   318  // 	spew.Dump(out)
   319  
   320  // 	stru := baseline.NewSimple()
   321  // 	if _, err := stru.FastRead(out); err != nil {
   322  // 		t.Fatal(err)
   323  // 	}
   324  // 	stru2 := baseline.NewSimple()
   325  // 	if err := sonic.UnmarshalString(simpleJSON, stru2); err != nil {
   326  // 		t.Fatal(err)
   327  // 	}
   328  // 	require.Equal(t, stru2, stru)
   329  // }
   330  
   331  func convertI642StringSimple(js string) string {
   332  	n, err := json.NewSearcher(js).GetByPath()
   333  	if err != nil {
   334  		panic(err)
   335  	}
   336  	old := n.Get("I64Field")
   337  	if old.Check() != nil {
   338  		panic(old)
   339  	}
   340  	new, err := old.Int64()
   341  	if err != nil {
   342  		panic(err)
   343  	}
   344  	_, err = n.Set("I64Field", json.NewString(strconv.Itoa(int(new))))
   345  	if err != nil {
   346  		panic(err)
   347  	}
   348  	e, _ := n.Raw()
   349  	return e
   350  }
   351  
   352  func convertStr2I64Simple(js string) string {
   353  	n, err := json.NewSearcher(js).GetByPath()
   354  	if err != nil {
   355  		panic(err)
   356  	}
   357  	old := n.Get("I64Field")
   358  	if old.Check() != nil {
   359  		panic(old)
   360  	}
   361  	s, err := old.String()
   362  	if err != nil {
   363  		panic(err)
   364  	}
   365  	_, err = n.Set("I64Field", json.NewNumber(s[1:len(s)-1]))
   366  	if err != nil {
   367  		panic(err)
   368  	}
   369  	e, _ := n.Raw()
   370  	return e
   371  }
   372  
   373  func convertI642StringNesting(js string, itoa bool) string {
   374  	n, err := json.NewSearcher(js).GetByPath()
   375  	if err != nil {
   376  		panic(err)
   377  	}
   378  	c := n.Get("SimpleStruct")
   379  	r, _ := c.Raw()
   380  	var new string
   381  	if itoa {
   382  		new = convertI642StringSimple(r)
   383  	} else {
   384  		new = convertStr2I64Simple(r)
   385  	}
   386  	_, err = n.Set("SimpleStruct", json.NewRaw(new))
   387  	if err != nil {
   388  		panic(err)
   389  	}
   390  	a := n.Get("ListSimple")
   391  	if a.Check() != nil {
   392  		panic(a)
   393  	}
   394  	a.ForEach(func(path json.Sequence, node *json.Node) bool {
   395  		r, _ := node.Raw()
   396  		var new string
   397  		if itoa {
   398  			new = convertI642StringSimple(r)
   399  		} else {
   400  			new = convertStr2I64Simple(r)
   401  		}
   402  		*node = json.NewRaw(new)
   403  		return true
   404  	})
   405  	b := n.Get("MapStringSimple")
   406  	if b.Check() != nil {
   407  		panic(b)
   408  	}
   409  	b.ForEach(func(path json.Sequence, node *json.Node) bool {
   410  		r, _ := node.Raw()
   411  		var new string
   412  		if itoa {
   413  			new = convertI642StringSimple(r)
   414  		} else {
   415  			new = convertStr2I64Simple(r)
   416  		}
   417  		*node = json.NewRaw(new)
   418  		return true
   419  	})
   420  	e, _ := n.Raw()
   421  	return e
   422  }
   423  
   424  func TestJSON2Thrift_Simple(t *testing.T) {
   425  	_, err := ejson.Marshal(baseline.Simple{})
   426  	if err != nil {
   427  		t.Fatal(err)
   428  	}
   429  	simple := getSimpleDesc()
   430  
   431  	stru2 := baseline.NewSimple()
   432  	if err := sonic.UnmarshalString(simpleJSON, stru2); err != nil {
   433  		t.Fatal(err)
   434  	}
   435  
   436  	nj := convertI642StringSimple(simpleJSON)
   437  	cv := j2t.NewBinaryConv(conv.Options{
   438  		WriteDefaultField:  true,
   439  		EnableValueMapping: true,
   440  	})
   441  	ctx := context.Background()
   442  	out, err := cv.Do(ctx, simple, []byte(nj))
   443  	require.Nil(t, err)
   444  
   445  	stru := baseline.NewSimple()
   446  	if _, err := stru.FastRead(out); err != nil {
   447  		t.Fatal(err)
   448  	}
   449  	require.Equal(t, stru2, stru)
   450  }
   451  
   452  var Concurrency = 1000
   453  
   454  func TestJSON2Thrift_Simple_Parallel(t *testing.T) {
   455  	_, err := ejson.Marshal(baseline.Simple{})
   456  	if err != nil {
   457  		t.Fatal(err)
   458  	}
   459  	desc := getSimpleDesc()
   460  	stru2 := baseline.NewSimple()
   461  	if err := sonic.UnmarshalString(simpleJSON, stru2); err != nil {
   462  		t.Fatal(err)
   463  	}
   464  	nj := convertI642StringSimple(simpleJSON)
   465  
   466  	cv := j2t.NewBinaryConv(conv.Options{
   467  		WriteDefaultField:  true,
   468  		EnableValueMapping: true,
   469  	})
   470  
   471  	wg := sync.WaitGroup{}
   472  	for i := 0; i < Concurrency; i++ {
   473  		wg.Add(1)
   474  		go func(i int) {
   475  			defer func() {
   476  				if r := recover(); r != nil {
   477  					t.Fatalf("panic: %d\n%s", i, nj)
   478  				}
   479  			}()
   480  			defer wg.Done()
   481  			ctx := context.Background()
   482  			out, err := cv.Do(ctx, desc, []byte(nj))
   483  			require.Nil(t, err)
   484  
   485  			stru := baseline.NewSimple()
   486  			if _, err := stru.FastRead(out); err != nil {
   487  				t.Fatal(err)
   488  			}
   489  			require.Equal(t, stru2, stru)
   490  		}(i)
   491  	}
   492  
   493  	wg.Wait()
   494  }
   495  
   496  // func TestThriftEncodeNesting_Load(t *testing.T) {
   497  // 	nesting := getNestingDesc()
   498  // 	// fmt.Printf("%#v", nesting)
   499  // 	root, err := json.NewSearcher(nestingJSON).GetByPath()
   500  // 	if err != nil {
   501  // 		t.Fatal(err)
   502  // 	}
   503  // 	if err := root.LoadAll(); err != nil {
   504  // 		t.Fatal(err)
   505  // 	}
   506  // 	// js, err := root.MarshalJSON()
   507  // 	// println(string(js))
   508  // 	enc := &json.ThriftEncoder{Proto: meta.ThriftBinary, Options: &json.Options{
   509  // 		WriteDefault: true,
   510  // 	}}
   511  // 	out, err := enc.Encode(nesting, root)
   512  // 	if err != nil {
   513  // 		t.Fatal(err)
   514  // 	}
   515  // 	// spew.Dump(out)
   516  
   517  // 	stru := baseline.NewNesting()
   518  // 	if _, err := stru.FastRead(out); err != nil {
   519  // 		t.Fatal(err)
   520  // 	}
   521  // 	stru2 := baseline.NewNesting()
   522  // 	if err := sonic.UnmarshalString(nestingJSON, stru2); err != nil {
   523  // 		t.Fatal(err)
   524  // 	}
   525  // 	require.Equal(t, stru, stru2)
   526  // 	// fmt.Printf("%#v", *stru)
   527  // }
   528  
   529  func TestHTTP2Thrift_Nesting(t *testing.T) {
   530  	nesting := getNestingDesc()
   531  	// fmt.Printf("%#v", nesting)
   532  	stru2 := baseline.NewNesting()
   533  	if err := ejson.Unmarshal([]byte(nestingJSON), stru2); err != nil {
   534  		t.Fatal(err)
   535  	}
   536  
   537  	req := getSampleHttpRequest(stru2, nestingJSON)
   538  	ctx := context.WithValue(context.Background(), conv.CtxKeyHTTPRequest, req)
   539  	cv := j2t.NewBinaryConv(conv.Options{
   540  		WriteDefaultField:            true,
   541  		EnableHttpMapping:            true,
   542  		EnableValueMapping:           true,
   543  		TracebackRequredOrRootFields: true,
   544  		ReadHttpValueFallback:        true,
   545  	})
   546  	nj := convertI642StringNesting(nestingJSON, true)
   547  	out, err := cv.Do(ctx, nesting, []byte(nj))
   548  	require.Nil(t, err)
   549  
   550  	stru := baseline.NewNesting()
   551  	if _, err := stru.FastRead(out); err != nil {
   552  		t.Fatal(err)
   553  	}
   554  
   555  	require.Equal(t, stru2, stru)
   556  	// fmt.Printf("%#v", *stru)
   557  }
   558  
   559  func TestHTTP2Thrift_Nesting_Parallel(t *testing.T) {
   560  	nesting := getNestingDesc()
   561  	// fmt.Printf("%#v", nesting)
   562  
   563  	cv := j2t.NewBinaryConv(conv.Options{
   564  		WriteDefaultField:            true,
   565  		EnableHttpMapping:            true,
   566  		EnableValueMapping:           true,
   567  		TracebackRequredOrRootFields: true,
   568  		ReadHttpValueFallback:        true,
   569  		OmitHttpMappingErrors:        true,
   570  	})
   571  	nj := convertI642StringNesting(nestingJSON, true)
   572  	println(nj)
   573  
   574  	wg := sync.WaitGroup{}
   575  	for i := 0; i < Concurrency; i++ {
   576  		wg.Add(1)
   577  		go func(i int) {
   578  			defer func() {
   579  				if r := recover(); r != nil {
   580  					t.Fatalf("panic: %d\n", i)
   581  				}
   582  			}()
   583  			defer wg.Done()
   584  			stru2 := baseline.NewNesting()
   585  			if err := ejson.Unmarshal([]byte(nestingJSON), stru2); err != nil {
   586  				t.Fatal(err)
   587  			}
   588  			req := getSampleHttpRequest(stru2, nestingJSON)
   589  			ctx := context.WithValue(context.Background(), conv.CtxKeyHTTPRequest, req)
   590  			out, err := cv.Do(ctx, nesting, []byte(nj))
   591  			require.Nil(t, err)
   592  			stru := baseline.NewNesting()
   593  			if _, err := stru.FastRead(out); err != nil {
   594  				t.Fatal(err)
   595  			}
   596  			require.Equal(t, stru2, stru)
   597  		}(i)
   598  	}
   599  	wg.Wait()
   600  }
   601  
   602  // func BenchmarkJSON2Thrift_DynamicGo_Load(b *testing.B) {
   603  // 	b.Run("small", func(b *testing.B) {
   604  // 		simple := getSimpleDesc()
   605  // 		enc := &json.ThriftEncoder{Proto: meta.ThriftBinary, Options: &json.Options{
   606  // 			WriteDefault: true,
   607  // 		}}
   608  // 		jSimple, _ := json.NewSearcher(simpleJSON).GetByPath()
   609  // 		jSimple.LoadAll()
   610  // 		out, err := enc.Encode(simple, jSimple)
   611  // 		if err != nil {
   612  // 			b.Fatal(err)
   613  // 		}
   614  // 		b.SetBytes(int64(len(out)))
   615  // 		b.ResetTimer()
   616  // 		for i := 0; i < b.N; i++ {
   617  // 			jSimple := json.NewRaw(simpleJSON)
   618  // 			jSimple.LoadAll()
   619  // 			_, _ = enc.Encode(simple, jSimple)
   620  // 		}
   621  // 	})
   622  
   623  // 	b.Run("medium", func(b *testing.B) {
   624  // 		nesting := getNestingDesc()
   625  // 		enc := &json.ThriftEncoder{Proto: meta.ThriftBinary, Options: &json.Options{
   626  // 			WriteDefault: true,
   627  // 		}}
   628  // 		jNesting, _ := json.NewSearcher(nestingJSON).GetByPath()
   629  // 		jNesting.LoadAll()
   630  // 		out, err := enc.Encode(nesting, jNesting)
   631  // 		if err != nil {
   632  // 			b.Fatal(err)
   633  // 		}
   634  // 		b.SetBytes(int64(len(out)))
   635  // 		b.ResetTimer()
   636  // 		for i := 0; i < b.N; i++ {
   637  // 			jNesting := json.NewRaw(nestingJSON)
   638  // 			jNesting.LoadAll()
   639  // 			_, _ = enc.Encode(nesting, jNesting)
   640  // 		}
   641  // 	})
   642  // }
   643  
   644  // func BenchmarkJSON2Thrift_DynamicGo_Raw(b *testing.B) {
   645  
   646  // 	b.Run("small", func(b *testing.B) {
   647  // 		simple := getSimpleDesc()
   648  // 		enc := &json.ThriftEncoder{Proto: meta.ThriftBinary, Options: &json.Options{
   649  // 			WriteDefault: true,
   650  // 		}}
   651  // 		jSimple := json.NewRaw(simpleJSON)
   652  // 		out, err := enc.Encode(simple, jSimple)
   653  // 		if err != nil {
   654  // 			b.Fatal(err)
   655  // 		}
   656  // 		b.SetBytes(int64(len(out)))
   657  // 		b.ResetTimer()
   658  // 		for i := 0; i < b.N; i++ {
   659  // 			jSimple := json.NewRaw(simpleJSON)
   660  // 			_, _ = enc.Encode(simple, jSimple)
   661  // 		}
   662  // 	})
   663  
   664  // 	b.Run("medium", func(b *testing.B) {
   665  // 		nesting := getNestingDesc()
   666  // 		enc := &json.ThriftEncoder{Proto: meta.ThriftBinary, Options: &json.Options{
   667  // 			WriteDefault: true,
   668  // 		}}
   669  // 		jNesting, _ := json.NewSearcher(nestingJSON).GetByPath()
   670  // 		out, err := enc.Encode(nesting, jNesting)
   671  // 		if err != nil {
   672  // 			b.Fatal(err)
   673  // 		}
   674  // 		b.SetBytes(int64(len(out)))
   675  // 		b.ResetTimer()
   676  // 		for i := 0; i < b.N; i++ {
   677  // 			jNesting := json.NewRaw(nestingJSON)
   678  // 			_, _ = enc.Encode(nesting, jNesting)
   679  // 		}
   680  // 	})
   681  // }
   682  
   683  const BufferSize = 4096
   684  
   685  func BenchmarkJSON2Thrift_KitexGeneric(b *testing.B) {
   686  	p, err := generic.NewThriftFileProvider(idlPath)
   687  	if err != nil {
   688  		b.Fatal(err)
   689  	}
   690  	svcDsc := <-p.Provide()
   691  
   692  	b.Run("small", func(b *testing.B) {
   693  		var _args generic.Args
   694  		_args.Method = "SimpleMethod"
   695  		_args.Request = simpleJSON
   696  		codec, err := gthrift.NewWriteJSON(svcDsc, "SimpleMethod", true)
   697  		if err != nil {
   698  			b.Fatal(err)
   699  		}
   700  		var mm = athrift.NewTMemoryBuffer()
   701  		bc := athrift.NewTBinaryProtocol(mm, false, true)
   702  		if err := codec.Write(context.Background(), bc, simpleJSON, nil); err != nil {
   703  			b.Fatal(err)
   704  		}
   705  
   706  		b.SetBytes(int64(len(mm.Bytes())))
   707  		b.ResetTimer()
   708  		for i := 0; i < b.N; i++ {
   709  			mm.Reset()
   710  			_ = codec.Write(context.Background(), bc, simpleJSON, nil)
   711  		}
   712  	})
   713  
   714  	b.Run("medium", func(b *testing.B) {
   715  		var _args generic.Args
   716  		_args.Method = "NestingMethod"
   717  		_args.Request = nestingJSON
   718  		codec, err := gthrift.NewWriteJSON(svcDsc, "NestingMethod", true)
   719  		if err != nil {
   720  			b.Fatal(err)
   721  		}
   722  		var mm = athrift.NewTMemoryBuffer()
   723  		bc := athrift.NewTBinaryProtocol(mm, false, true)
   724  		if err := codec.Write(context.Background(), bc, nestingJSON, nil); err != nil {
   725  			b.Fatal(err)
   726  		}
   727  
   728  		b.SetBytes(int64(len(mm.Bytes())))
   729  		b.ResetTimer()
   730  		for i := 0; i < b.N; i++ {
   731  			mm.Reset()
   732  			_ = codec.Write(context.Background(), bc, nestingJSON, nil)
   733  		}
   734  	})
   735  }
   736  
   737  func BenchmarkJSON2Thrift_SonicAndKitex(b *testing.B) {
   738  	b.Run("small", func(b *testing.B) {
   739  		v := baseline.NewSimple()
   740  		if err := sonic.UnmarshalString(simpleJSON, v); err != nil {
   741  			b.Fatal(err)
   742  		}
   743  		var buf = make([]byte, v.BLength())
   744  		if err := v.FastWriteNocopy(buf, nil); err <= 0 {
   745  			b.Fatal(err)
   746  		}
   747  
   748  		b.SetBytes(int64(len(buf)))
   749  		b.ResetTimer()
   750  		for i := 0; i < b.N; i++ {
   751  			v := baseline.NewSimple()
   752  			_ = v.BLength()
   753  			_ = sonic.UnmarshalString(simpleJSON, v)
   754  			v.FastWriteNocopy(buf, nil)
   755  		}
   756  	})
   757  
   758  	b.Run("medium", func(b *testing.B) {
   759  		v := baseline.NewNesting()
   760  		if err := sonic.UnmarshalString(nestingJSON, v); err != nil {
   761  			b.Fatal(err)
   762  		}
   763  		var buf = make([]byte, v.BLength())
   764  		if err := v.FastWriteNocopy(buf, nil); err <= 0 {
   765  			b.Fatal(err)
   766  		}
   767  
   768  		b.SetBytes(int64(len(buf)))
   769  		b.ResetTimer()
   770  		for i := 0; i < b.N; i++ {
   771  			v := baseline.NewNesting()
   772  			_ = v.BLength()
   773  			_ = sonic.UnmarshalString(nestingJSON, v)
   774  			v.FastWriteNocopy(buf, nil)
   775  		}
   776  	})
   777  }
   778  
   779  func BenchmarkHTTP2Thrift_DynamicGo_Raw(b *testing.B) {
   780  	b.Run("small/value_mapping", func(b *testing.B) {
   781  		simple := getSimpleDesc()
   782  		cv := j2t.NewBinaryConv(conv.Options{
   783  			WriteDefaultField:  true,
   784  			EnableValueMapping: true,
   785  		})
   786  		nj := []byte(convertI642StringSimple(simpleJSON))
   787  		ctx := context.Background()
   788  		out, err := cv.Do(ctx, simple, nj)
   789  		require.Nil(b, err)
   790  
   791  		b.SetBytes(int64(len(out)))
   792  		b.ResetTimer()
   793  		for i := 0; i < b.N; i++ {
   794  			_, _ = cv.Do(ctx, simple, nj)
   795  		}
   796  	})
   797  
   798  	b.Run("medium/value_mapping", func(b *testing.B) {
   799  		nesting := getNestingDesc()
   800  		req := getSampleHttpRequest(baseline.NewNesting(), nestingJSON)
   801  		cv := j2t.NewBinaryConv(conv.Options{
   802  			WriteDefaultField:  true,
   803  			EnableValueMapping: true,
   804  		})
   805  		nj := []byte(convertI642StringNesting(nestingJSON, true))
   806  		ctx := context.Background()
   807  		ctx = context.WithValue(ctx, conv.CtxKeyHTTPRequest, req)
   808  		out, err := cv.Do(ctx, nesting, nj)
   809  		require.Nil(b, err)
   810  
   811  		b.SetBytes(int64(len(out)))
   812  		b.ResetTimer()
   813  		for i := 0; i < b.N; i++ {
   814  			_, _ = cv.Do(ctx, nesting, nj)
   815  		}
   816  	})
   817  
   818  	b.Run("medium/http+value_mapping", func(b *testing.B) {
   819  		nesting := getNestingDesc()
   820  		req := getSampleHttpRequest(baseline.NewNesting(), nestingJSON)
   821  		ctx := context.Background()
   822  		ctx = context.WithValue(ctx, conv.CtxKeyHTTPRequest, req)
   823  		cv := j2t.NewBinaryConv(conv.Options{
   824  			WriteDefaultField:  true,
   825  			EnableHttpMapping:  true,
   826  			EnableValueMapping: true,
   827  		})
   828  		nj := []byte(convertI642StringNesting(nestingJSON, true))
   829  		out, err := cv.Do(ctx, nesting, nj)
   830  		require.Nil(b, err)
   831  
   832  		b.SetBytes(int64(len(out)))
   833  		b.ResetTimer()
   834  		for i := 0; i < b.N; i++ {
   835  			_, _ = cv.Do(ctx, nesting, nj)
   836  		}
   837  	})
   838  }
   839  
   840  // func getKitexHttpRequest(req *descriptor.HTTPRequest) {
   841  // 	header := "你好"
   842  // 	req.Header.Set("String", header)
   843  // 	// exp.String_ = header
   844  // 	// h2 := "abcdefghijklmnopqrstuvwxyz"
   845  // 	// req.Header.Set("string_field", h2)
   846  // 	// exp.SimpleStruct.StringField = h2
   847  // 	// for i := range exp.ListSimple {
   848  // 	// 	exp.ListSimple[i].StringField = h2
   849  // 	// }
   850  // 	// for k := range exp.MapStringSimple {
   851  // 	// 	exp.MapStringSimple[k].StringField = h2
   852  // 	// }
   853  
   854  // 	c := []int64{-1, 0, math.MaxInt64, math.MinInt64}
   855  // 	cookie := ""
   856  // 	for i, v := range c {
   857  // 		cookie += strconv.Itoa(int(v))
   858  // 		if i != len(c)-1 {
   859  // 			cookie += ","
   860  // 		}
   861  // 	}
   862  // 	req.Cookies["list_i64"] = cookie
   863  // 	// exp.ListI64 = c
   864  
   865  // 	// param := math.MaxFloat64
   866  // 	// req.Params.Set("double", strconv.FormatFloat(param, 'f', -1, 64))
   867  // 	// exp.Double = param
   868  
   869  // 	q := []int32{-1, 0, math.MaxInt32, math.MinInt32}
   870  // 	query := ""
   871  // 	for i, v := range q {
   872  // 		query += strconv.Itoa(int(v))
   873  // 		if i != len(q)-1 {
   874  // 			query += ","
   875  // 		}
   876  // 	}
   877  // 	req.Query.Set("ListI32", query)
   878  // 	// exp.ListI32 = q
   879  
   880  // 	// exp.I32 = 0
   881  
   882  // 	var helper = func(sim map[string]interface{}) {
   883  // 		sim["I32Field"] = int32(sim["I32Field"].(int64))
   884  // 		sim["ByteField"] = int8(sim["ByteField"].(int64))
   885  // 	}
   886  // 	for _, v := range req.Body["MapStringSimple"].(map[string]interface{}) {
   887  // 		helper(v.(map[string]interface{}))
   888  // 	}
   889  // 	for _, v := range req.Body["ListSimple"].([]interface{}) {
   890  // 		helper(v.(map[string]interface{}))
   891  // 	}
   892  // 	helper(req.Body["SimpleStruct"].(map[string]interface{}))
   893  // 	req.Body["Byte"] = int8(req.Body["Byte"].(int64))
   894  
   895  // }
   896  
   897  func BenchmarkHTTP2Thrift_KitexGeneric(b *testing.B) {
   898  	p, err := generic.NewThriftFileProvider(idlPath)
   899  	if err != nil {
   900  		b.Fatal(err)
   901  	}
   902  	svcDsc := <-p.Provide()
   903  	svcDsc.Functions["NestingMethod"].Request.Struct.FieldsByName["req"].Type.Struct.FieldsByName["Double"].HTTPMapping = nil
   904  
   905  	b.Run("small", func(b *testing.B) {
   906  		codec := gthrift.NewWriteHTTPRequest(svcDsc)
   907  		req := &descriptor.HTTPRequest{}
   908  		req.Request, err = stdh.NewRequest("POST", "/simple", nil)
   909  		if err != nil {
   910  			b.Fatal(err)
   911  		}
   912  		jc := sonic.Config{
   913  			UseInt64: true,
   914  		}.Froze()
   915  		if err := jc.UnmarshalFromString(simpleJSON, &req.Body); err != nil {
   916  			b.Fatal(err)
   917  		}
   918  		req.Body["I32Field"] = int32(req.Body["I32Field"].(int64))
   919  		req.Body["ByteField"] = int8(req.Body["ByteField"].(int64))
   920  
   921  		buf := remote.NewWriterBuffer(BufferSize)
   922  		bc := bthrift.NewBinaryProtocol(buf)
   923  		if err := codec.Write(context.Background(), bc, req, gthrift.NewBase()); err != nil {
   924  			b.Fatal(err)
   925  		}
   926  		out, _ := buf.Bytes()
   927  		exp := baseline.NewSimple()
   928  		if _, err := exp.FastRead(out); err != nil {
   929  			b.Fatal(err)
   930  		}
   931  
   932  		b.SetBytes(int64(len(out)))
   933  		b.ResetTimer()
   934  		for i := 0; i < b.N; i++ {
   935  			buf := remote.NewWriterBuffer(BufferSize)
   936  			bc := bthrift.NewBinaryProtocol(buf)
   937  			if err = codec.Write(context.Background(), bc, req, gthrift.NewBase()); err != nil {
   938  				b.Fatal(err)
   939  			}
   940  		}
   941  	})
   942  
   943  	// b.Run("medium", func(b *testing.B) {
   944  	// 	codec := gthrift.NewWriteHTTPRequest(svcDsc)
   945  	// 	jc := sonic.Config{
   946  	// 		UseInt64: true,
   947  	// 	}.Froze()
   948  	// 	var body map[string]interface{}
   949  	// 	if err := jc.UnmarshalFromString(nestingJSON, &body); err != nil {
   950  	// 		b.Fatal(err)
   951  	// 	}
   952  	// 	req := &descriptor.HTTPRequest{
   953  	// 		Header:  map[string][]string{},
   954  	// 		Query:   map[string][]string{},
   955  	// 		Cookies: map[string]string{},
   956  	// 	}
   957  	// 	req.Body = body
   958  	// 	getKitexHttpRequest(req)
   959  	// 	req.Method = "POST"
   960  	// 	req.Path = "/nesting"
   961  
   962  	// 	buf := remote.NewWriterBuffer(BufferSize)
   963  	// 	bc := bthrift.NewBinaryProtocol(buf)
   964  	// 	if err := codec.Write(context.Background(), bc, req, gthrift.NewBase()); err != nil {
   965  	// 		b.Fatal(err)
   966  	// 	}
   967  	// 	out, _ := buf.Bytes()
   968  	// 	exp := baseline.NewNesting()
   969  	// 	if _, err := exp.FastRead(out); err != nil {
   970  	// 		b.Fatal(err)
   971  	// 	}
   972  
   973  	// 	b.SetBytes(int64(len(out)))
   974  	// 	b.ResetTimer()
   975  	// 	for i := 0; i < b.N; i++ {
   976  	// 		buf := remote.NewWriterBuffer(BufferSize)
   977  	// 		bc := bthrift.NewBinaryProtocol(buf)
   978  	// 		if err = codec.Write(context.Background(), bc, req, gthrift.NewBase()); err != nil {
   979  	// 			b.Fatal(err)
   980  	// 		}
   981  	// 	}
   982  	// })
   983  }