github.com/cloudwego/kitex@v0.9.0/pkg/generic/reflect_test/map_test.go (about) 1 /** 2 * Copyright 2023 ByteDance Inc. 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 test 18 19 import ( 20 "context" 21 "errors" 22 "math/rand" 23 "net" 24 "strconv" 25 "testing" 26 "time" 27 28 "github.com/cloudwego/kitex/client" 29 "github.com/cloudwego/kitex/client/callopt" 30 "github.com/cloudwego/kitex/client/genericclient" 31 "github.com/cloudwego/kitex/internal/test" 32 "github.com/cloudwego/kitex/pkg/generic" 33 "github.com/cloudwego/kitex/server" 34 "github.com/cloudwego/kitex/server/genericserver" 35 ) 36 37 var mcli genericclient.Client 38 39 func TestThriftMapExample(t *testing.T) { 40 testThriftMapExample(t) 41 } 42 43 func BenchmarkThriftMapExample(b *testing.B) { 44 for i := 0; i < b.N; i++ { 45 testThriftMapExample(b) 46 } 47 } 48 49 func testThriftMapExample(t testing.TB) { 50 log_id := strconv.Itoa(rand.Int()) 51 52 req := makeExampleReqMap(true, reqMsg, log_id) 53 54 out, err := mcli.GenericCall(context.Background(), method, req, callopt.WithRPCTimeout(100*time.Second)) 55 test.Assert(t, err == nil, err) 56 resp, ok := out.(map[string]interface{}) 57 test.Assert(t, ok) 58 59 msg, ok := resp["Msg"].(string) 60 if !ok || msg != respMsg { 61 t.Fail() 62 } 63 require_field, ok := resp["required_field"].(string) 64 if !ok || require_field != reqMsg { 65 t.Fail() 66 } 67 logid, ok := resp["BaseResp"].(map[string]interface{})["StatusMessage"] 68 if !ok || log_id != logid { 69 t.Fail() 70 } 71 } 72 73 func initThriftMapClient(addr, idl string) genericclient.Client { 74 p, err := generic.NewThriftFileProvider(idl) 75 if err != nil { 76 panic(err) 77 } 78 g, err := generic.MapThriftGeneric(p) 79 if err != nil { 80 panic(err) 81 } 82 cli := newGenericClient("destServiceName", g, addr) 83 if err != nil { 84 panic(err) 85 } 86 return cli 87 } 88 89 func newGenericClient(destService string, g generic.Generic, targetIPPort string) genericclient.Client { 90 var opts []client.Option 91 opts = append(opts, client.WithHostPorts(targetIPPort)) 92 genericCli, _ := genericclient.NewClient(destService, g, opts...) 93 return genericCli 94 } 95 96 func initThriftMapServer(address, idl string, handler generic.Service) server.Server { 97 addr, _ := net.ResolveTCPAddr("tcp", address) 98 p, err := generic.NewThriftFileProvider(idl) 99 if err != nil { 100 panic(err) 101 } 102 g, err := generic.MapThriftGeneric(p) 103 if err != nil { 104 panic(err) 105 } 106 svr := newGenericServer(g, addr, handler) 107 return svr 108 } 109 110 func newGenericServer(g generic.Generic, addr net.Addr, handler generic.Service) server.Server { 111 var opts []server.Option 112 opts = append(opts, server.WithServiceAddr(addr), server.WithExitWaitTime(time.Microsecond*10)) 113 svr := genericserver.NewServer(handler, g, opts...) 114 go func() { 115 err := svr.Run() 116 if err != nil { 117 panic(err) 118 } 119 }() 120 test.WaitServerStart(addr.String()) 121 return svr 122 } 123 124 type exampeServerImpl struct{} 125 126 // GenericCall ... 127 func (g *exampeServerImpl) GenericCall(ctx context.Context, method string, request interface{}) (response interface{}, err error) { 128 buf := request.(map[string]interface{}) 129 130 required_field := "" 131 logid := "" 132 if b, ok := buf["B"].(bool); ok && b { 133 if base, ok := buf["Base"].(map[string]interface{}); !ok { 134 return nil, errors.New("empty base field") 135 } else { 136 logid, _ = base["LogID"].(string) 137 } 138 if testmap, ok := buf["TestMap"].(map[interface{}]interface{}); !ok { 139 return nil, errors.New("empty TestMap") 140 } else if a, ok := testmap["a"].(map[string]interface{}); !ok { 141 return nil, errors.New("key 'a' not found") 142 } else { 143 required_field, _ = a["Bar"].(string) 144 } 145 } 146 147 return makeExampleRespMap(respMsg, required_field, logid) 148 } 149 150 func makeExampleRespMap(msg, require_field, logid string) (map[string]interface{}, error) { 151 return map[string]interface{}{ 152 "Msg": msg, 153 "required_field": require_field, 154 "BaseResp": map[string]interface{}{ 155 "StatusMessage": logid, 156 }, 157 }, nil 158 } 159 160 func makeExampleReqMap(B bool, A, logid string) map[string]interface{} { 161 list := make([]interface{}, SampleListSize+1) 162 list[0] = map[string]interface{}{ 163 "Bar": A, 164 } 165 for i := 1; i < len(list); i++ { 166 list[i] = map[string]interface{}{ 167 "Bar": A, 168 } 169 } 170 m := make(map[string]interface{}, SampleListSize+1) 171 m["a"] = map[string]interface{}{ 172 "Bar": A, 173 } 174 for i := 1; i < len(list); i++ { 175 m[strconv.Itoa(i)] = map[string]interface{}{ 176 "Bar": A, 177 } 178 } 179 return map[string]interface{}{ 180 "Msg": "Hello", 181 "Foo": int32(1), 182 "TestList": list, 183 "TestMap": m, 184 "I64List": []interface{}{ 185 int64(1), int64(2), int64(3), 186 }, 187 "B": B, 188 "Base": map[string]interface{}{ 189 "LogID": logid, 190 "Caller": "d.e.f", 191 "Addr": "127.0.0.1", 192 "Client": "dynamicgo", 193 }, 194 } 195 }