Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add tests for generic call using dynamicgo and data size types #59

Open
wants to merge 15 commits into
base: main
Choose a base branch
from
Open
150 changes: 150 additions & 0 deletions generic/data/data.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
/*
* Copyright 2022 CloudWeGo Authors
*
* 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 data

import (
"encoding/json"
"strconv"
"strings"

"github.com/cloudwego/kitex-benchmark/codec/thrift/kitex_gen/echo"
)

var (
SmallReq, MediumReq, LargeReq *echo.ObjReq
SmallMap, MediumMap, LargeMap map[string]interface{}
SmallString, MediumString, LargeString string
actionSidx, msgSidx, actionMidx, msgMidx, actionLidx, msgLidx int
)

type Size int

const (
Small Size = 6
Medium Size = 33
Large Size = 67
)

func init() {
// data size: small 1027B, medium 5035B, large 10101B
SmallReq = getReqValue(int(Small))
MediumReq = getReqValue(int(Medium))
LargeReq = getReqValue(int(Large))
SmallString = reqToString(SmallReq)
MediumString = reqToString(MediumReq)
LargeString = reqToString(LargeReq)
actionSidx = strings.Index(SmallString, `"action":""`) + len(`"action":""`) - 1
actionMidx = strings.Index(MediumString, `"action":""`) + len(`"action":""`) - 1
actionLidx = strings.Index(LargeString, `"action":""`) + len(`"action":""`) - 1
msgSidx = strings.Index(SmallString, `"msg":""`) + len(`"msg":""`) - 1
msgMidx = strings.Index(MediumString, `"msg":""`) + len(`"msg":""`) - 1
msgLidx = strings.Index(LargeString, `"msg":""`) + len(`"msg":""`) - 1
}

func GetJsonString(action, msg string, size Size) string {
switch size {
case Small:
return SmallString[:actionSidx] + action + SmallString[actionSidx:msgSidx] + msg + SmallString[msgSidx:]
case Medium:
return MediumString[:actionMidx] + action + MediumString[actionMidx:msgMidx] + msg + MediumString[msgMidx:]
case Large:
return LargeString[:actionLidx] + action + LargeString[actionLidx:msgLidx] + msg + LargeString[msgLidx:]
}
return ""
}

func reqToString(req *echo.ObjReq) string {
data, err := json.Marshal(req)
if err != nil {
panic(err)
}
return string(data)
}

func getReqValue(size int) *echo.ObjReq {
req := &echo.ObjReq{
Action: "",
Msg: "",
MsgMap: map[string]*echo.SubMessage{},
SubMsgs: []*echo.SubMessage{},
MsgSet: []*echo.Message{},
FlagMsg: &echo.Message{},
}

for i := 0; i < size; i++ {
req.MsgMap[strconv.Itoa(i)] = getSubMessage(int64(i))
req.SubMsgs = append(req.SubMsgs, getSubMessage(int64(i)))
req.MsgSet = append(req.MsgSet, getMessage(int64(i)))
req.FlagMsg = getMessage(int64(i))
}

return req
}

func getSubMessage(i int64) *echo.SubMessage {
value := "hello"
return &echo.SubMessage{
Id: &i,
Value: &value,
}
}

func getMessage(i int64) *echo.Message {
value := "hello"
ret := &echo.Message{
Id: &i,
Value: &value,
SubMessages: []*echo.SubMessage{},
}
ret.SubMessages = append(ret.SubMessages, getSubMessage(1))
ret.SubMessages = append(ret.SubMessages, getSubMessage(2))
return ret
}

func GetReqMap(size int) map[string]interface{} {
msgMap := make(map[interface{}]interface{})
subMsgs := make([]interface{}, 0, size)
msgSet := make([]interface{}, 0, size)
flagMsg := make(map[string]interface{})
for i := 0; i < size; i++ {
msgMap[strconv.Itoa(i)] = getSubMessageMap(int64(i))
subMsgs = append(subMsgs, getSubMessageMap(int64(i)))
msgSet = append(msgSet, getMessageMap(int64(i)))
flagMsg = getMessageMap(int64(i))
}
return map[string]interface{}{
"msgMap": msgMap,
"subMsgs": subMsgs,
"msgSet": msgSet,
"flagMsg": flagMsg,
}
}

func getSubMessageMap(i int64) map[string]interface{} {
return map[string]interface{}{
"id": i,
"value": "hello",
}
}

func getMessageMap(i int64) map[string]interface{} {
return map[string]interface{}{
"id": i,
"value": "hello",
"subMessages": []interface{}{getSubMessageMap(1), getSubMessageMap(2)},
}
}
173 changes: 173 additions & 0 deletions generic/http/client/default/kitex_client.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
/*
* Copyright 2022 CloudWeGo Authors
*
* 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 kclient

import (
"bytes"
"context"
"fmt"
"net/http"
"time"

"github.com/cloudwego/kitex/client"
"github.com/cloudwego/kitex/client/genericclient"
"github.com/cloudwego/kitex/pkg/connpool"
"github.com/cloudwego/kitex/pkg/generic"
"github.com/cloudwego/kitex/pkg/transmeta"
"github.com/cloudwego/kitex/transport"

"github.com/cloudwego/kitex-benchmark/generic/data"
"github.com/cloudwego/kitex-benchmark/runner"
)

var (
p generic.DescriptorProvider
g generic.Generic
)

func init() {
var err error
p, err = generic.NewThriftFileProvider("./codec/thrift/echo.thrift")
if err != nil {
panic(err)
}
// 构造http 请求和返回类型的泛化调用
g, err = generic.HTTPThriftGeneric(p)
if err != nil {
panic(err)
}
}

func NewGenericHTTPSmallClient(opt *runner.Options) runner.Client {
var err error
cli := &genericHTTPSmallClient{}
cli.client, err = genericclient.NewClient("test.echo.kitex", g,
client.WithTransportProtocol(transport.TTHeader),
client.WithHostPorts(opt.Address),
client.WithMetaHandler(transmeta.ClientTTHeaderHandler),
client.WithLongConnection(
connpool.IdleConfig{MaxIdlePerAddress: 1000, MaxIdleGlobal: 1000, MaxIdleTimeout: time.Minute}),
)
if err != nil {
panic(err)
}
return cli
}

type genericHTTPSmallClient struct {
client genericclient.Client
}

func (cli *genericHTTPSmallClient) Echo(action, msg string) error {
customReq, err := createCustomRequest(action, msg, data.SmallString)
if err != nil {
return err
}

// send the request
reply, err := cli.client.GenericCall(context.Background(), "", customReq)
if reply != nil {
resp := reply.(*generic.HTTPResponse)
runner.ProcessResponse(resp.Header.Get("action"), resp.Header.Get("msg"))
}
return err
}

func NewGenericHTTPMediumClient(opt *runner.Options) runner.Client {
var err error
cli := &genericHTTPMediumClient{}
cli.client, err = genericclient.NewClient("test.echo.kitex", g,
client.WithTransportProtocol(transport.TTHeader),
client.WithHostPorts(opt.Address),
client.WithMetaHandler(transmeta.ClientTTHeaderHandler),
client.WithLongConnection(
connpool.IdleConfig{MaxIdlePerAddress: 1000, MaxIdleGlobal: 1000, MaxIdleTimeout: time.Minute}),
)
if err != nil {
panic(err)
}
return cli
}

type genericHTTPMediumClient struct {
client genericclient.Client
}

func (cli *genericHTTPMediumClient) Echo(action, msg string) error {
customReq, err := createCustomRequest(action, msg, data.MediumString)
if err != nil {
return err
}

// send the request
reply, err := cli.client.GenericCall(context.Background(), "", customReq)
if reply != nil {
resp := reply.(*generic.HTTPResponse)
runner.ProcessResponse(resp.Header.Get("action"), resp.Header.Get("msg"))
}
return err
}

func NewGenericHTTPLargeClient(opt *runner.Options) runner.Client {
var err error
cli := &genericHTTPLargeClient{}
cli.client, err = genericclient.NewClient("test.echo.kitex", g,
client.WithTransportProtocol(transport.TTHeader),
client.WithHostPorts(opt.Address),
client.WithMetaHandler(transmeta.ClientTTHeaderHandler),
client.WithLongConnection(
connpool.IdleConfig{MaxIdlePerAddress: 1000, MaxIdleGlobal: 1000, MaxIdleTimeout: time.Minute}),
)
if err != nil {
panic(err)
}
return cli
}

type genericHTTPLargeClient struct {
client genericclient.Client
}

func (cli *genericHTTPLargeClient) Echo(action, msg string) error {
customReq, err := createCustomRequest(action, msg, data.LargeString)
if err != nil {
return err
}

// send the request
reply, err := cli.client.GenericCall(context.Background(), "", customReq)
if reply != nil {
resp := reply.(*generic.HTTPResponse)
runner.ProcessResponse(resp.Header.Get("action"), resp.Header.Get("msg"))
}
return err
}

func createCustomRequest(action, msg, data string) (*generic.HTTPRequest, error) {
url := fmt.Sprintf("http://example.com/test/obj/%s", action)
httpRequest, err := http.NewRequest(http.MethodPost, url, bytes.NewBuffer([]byte(data)))
if err != nil {
return nil, err
}
httpRequest.Header.Set("msg", msg)

customReq, err := generic.FromHTTPRequest(httpRequest)
if err != nil {
return nil, err
}
return customReq, nil
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,11 @@
package main

import (
kclient "github.com/cloudwego/kitex-benchmark/generic/http/client/default"
"github.com/cloudwego/kitex-benchmark/runner"
)

// main is use for routing.
func main() {
runner.Main("GenericJSON", NewGenericJSONClient)
runner.Main("GenericHTTP", kclient.NewGenericHTTPLargeClient)
}
27 changes: 27 additions & 0 deletions generic/http/client/default/medium/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/*
* Copyright 2022 CloudWeGo Authors
*
* 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 main

import (
kclient "github.com/cloudwego/kitex-benchmark/generic/http/client/default"
"github.com/cloudwego/kitex-benchmark/runner"
)

// main is use for routing.
func main() {
runner.Main("GenericHTTP", kclient.NewGenericHTTPMediumClient)
}
27 changes: 27 additions & 0 deletions generic/http/client/default/small/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/*
* Copyright 2022 CloudWeGo Authors
*
* 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 main

import (
kclient "github.com/cloudwego/kitex-benchmark/generic/http/client/default"
"github.com/cloudwego/kitex-benchmark/runner"
)

// main is use for routing.
func main() {
runner.Main("GenericHTTP", kclient.NewGenericHTTPSmallClient)
}
Loading