gitee.com/zhaochuninhefei/gmgo@v0.0.31-0.20240209061119-069254a02979/grpc/rpc_util_test.go (about) 1 /* 2 * 3 * Copyright 2014 gRPC authors. 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 * 17 */ 18 19 package grpc 20 21 import ( 22 "bytes" 23 "compress/gzip" 24 "errors" 25 "io" 26 "math" 27 "reflect" 28 "testing" 29 30 "gitee.com/zhaochuninhefei/gmgo/grpc/codes" 31 "gitee.com/zhaochuninhefei/gmgo/grpc/encoding" 32 protoenc "gitee.com/zhaochuninhefei/gmgo/grpc/encoding/proto" 33 "gitee.com/zhaochuninhefei/gmgo/grpc/internal/testutils" 34 "gitee.com/zhaochuninhefei/gmgo/grpc/internal/transport" 35 "gitee.com/zhaochuninhefei/gmgo/grpc/status" 36 perfpb "gitee.com/zhaochuninhefei/gmgo/grpc/test/codec_perf" 37 "github.com/golang/protobuf/proto" 38 ) 39 40 type fullReader struct { 41 reader io.Reader 42 } 43 44 func (f fullReader) Read(p []byte) (int, error) { 45 return io.ReadFull(f.reader, p) 46 } 47 48 var _ CallOption = EmptyCallOption{} // ensure EmptyCallOption implements the interface 49 50 func (s) TestSimpleParsing(t *testing.T) { 51 bigMsg := bytes.Repeat([]byte{'x'}, 1<<24) 52 for _, test := range []struct { 53 // input 54 p []byte 55 // outputs 56 err error 57 b []byte 58 pt payloadFormat 59 }{ 60 {nil, io.EOF, nil, compressionNone}, 61 {[]byte{0, 0, 0, 0, 0}, nil, nil, compressionNone}, 62 {[]byte{0, 0, 0, 0, 1, 'a'}, nil, []byte{'a'}, compressionNone}, 63 {[]byte{1, 0}, io.ErrUnexpectedEOF, nil, compressionNone}, 64 {[]byte{0, 0, 0, 0, 10, 'a'}, io.ErrUnexpectedEOF, nil, compressionNone}, 65 // Check that messages with length >= 2^24 are parsed. 66 {append([]byte{0, 1, 0, 0, 0}, bigMsg...), nil, bigMsg, compressionNone}, 67 } { 68 buf := fullReader{bytes.NewReader(test.p)} 69 parser := &parser{r: buf} 70 pt, b, err := parser.recvMsg(math.MaxInt32) 71 if !errors.Is(err, test.err) || !bytes.Equal(b, test.b) || pt != test.pt { 72 t.Fatalf("parser{%v}.recvMsg(_) = %v, %v, %v\nwant %v, %v, %v", test.p, pt, b, err, test.pt, test.b, test.err) 73 } 74 } 75 } 76 77 func (s) TestMultipleParsing(t *testing.T) { 78 // Set a byte stream consists of 3 messages with their headers. 79 p := []byte{0, 0, 0, 0, 1, 'a', 0, 0, 0, 0, 2, 'b', 'c', 0, 0, 0, 0, 1, 'd'} 80 b := fullReader{bytes.NewReader(p)} 81 parser := &parser{r: b} 82 83 wantRecvs := []struct { 84 pt payloadFormat 85 data []byte 86 }{ 87 {compressionNone, []byte("a")}, 88 {compressionNone, []byte("bc")}, 89 {compressionNone, []byte("d")}, 90 } 91 for i, want := range wantRecvs { 92 pt, data, err := parser.recvMsg(math.MaxInt32) 93 if err != nil || pt != want.pt || !reflect.DeepEqual(data, want.data) { 94 t.Fatalf("after %d calls, parser{%v}.recvMsg(_) = %v, %v, %v\nwant %v, %v, <nil>", 95 i, p, pt, data, err, want.pt, want.data) 96 } 97 } 98 99 pt, data, err := parser.recvMsg(math.MaxInt32) 100 if err != io.EOF { 101 t.Fatalf("after %d recvMsgs calls, parser{%v}.recvMsg(_) = %v, %v, %v\nwant _, _, %v", 102 len(wantRecvs), p, pt, data, err, io.EOF) 103 } 104 } 105 106 func (s) TestEncode(t *testing.T) { 107 for _, test := range []struct { 108 // input 109 msg proto.Message 110 // outputs 111 hdr []byte 112 data []byte 113 err error 114 }{ 115 {nil, []byte{0, 0, 0, 0, 0}, []byte{}, nil}, 116 } { 117 data, err := encode(encoding.GetCodec(protoenc.Name), test.msg) 118 if !errors.Is(err, test.err) || !bytes.Equal(data, test.data) { 119 t.Errorf("encode(_, %v) = %v, %v; want %v, %v", test.msg, data, err, test.data, test.err) 120 continue 121 } 122 if hdr, _ := msgHeader(data, nil); !bytes.Equal(hdr, test.hdr) { 123 t.Errorf("msgHeader(%v, false) = %v; want %v", data, hdr, test.hdr) 124 } 125 } 126 } 127 128 func (s) TestCompress(t *testing.T) { 129 bestCompressor, err := NewGZIPCompressorWithLevel(gzip.BestCompression) 130 if err != nil { 131 t.Fatalf("Could not initialize gzip compressor with best compression.") 132 } 133 bestSpeedCompressor, err := NewGZIPCompressorWithLevel(gzip.BestSpeed) 134 if err != nil { 135 t.Fatalf("Could not initialize gzip compressor with best speed compression.") 136 } 137 138 defaultCompressor, err := NewGZIPCompressorWithLevel(gzip.BestSpeed) 139 if err != nil { 140 t.Fatalf("Could not initialize gzip compressor with default compression.") 141 } 142 143 level5, err := NewGZIPCompressorWithLevel(5) 144 if err != nil { 145 t.Fatalf("Could not initialize gzip compressor with level 5 compression.") 146 } 147 148 for _, test := range []struct { 149 // input 150 data []byte 151 cp Compressor 152 dc Decompressor 153 // outputs 154 err error 155 }{ 156 {make([]byte, 1024), NewGZIPCompressor(), NewGZIPDecompressor(), nil}, 157 {make([]byte, 1024), bestCompressor, NewGZIPDecompressor(), nil}, 158 {make([]byte, 1024), bestSpeedCompressor, NewGZIPDecompressor(), nil}, 159 {make([]byte, 1024), defaultCompressor, NewGZIPDecompressor(), nil}, 160 {make([]byte, 1024), level5, NewGZIPDecompressor(), nil}, 161 } { 162 b := new(bytes.Buffer) 163 if err := test.cp.Do(b, test.data); !errors.Is(err, test.err) { 164 t.Fatalf("Compressor.Do(_, %v) = %v, want %v", test.data, err, test.err) 165 } 166 if b.Len() >= len(test.data) { 167 t.Fatalf("The compressor fails to compress data.") 168 } 169 if p, err := test.dc.Do(b); err != nil || !bytes.Equal(test.data, p) { 170 t.Fatalf("Decompressor.Do(%v) = %v, %v, want %v, <nil>", b, p, err, test.data) 171 } 172 } 173 } 174 175 func (s) TestToRPCErr(t *testing.T) { 176 for _, test := range []struct { 177 // input 178 errIn error 179 // outputs 180 errOut error 181 }{ 182 {transport.ErrConnClosing, status.Error(codes.Unavailable, transport.ErrConnClosing.Desc)}, 183 {io.ErrUnexpectedEOF, status.Error(codes.Internal, io.ErrUnexpectedEOF.Error())}, 184 } { 185 err := toRPCErr(test.errIn) 186 if _, ok := status.FromError(err); !ok { 187 t.Errorf("toRPCErr{%v} returned type %T, want %T", test.errIn, err, status.Error) 188 } 189 if !testutils.StatusErrEqual(err, test.errOut) { 190 t.Errorf("toRPCErr{%v} = %v \nwant %v", test.errIn, err, test.errOut) 191 } 192 } 193 } 194 195 // bmEncode benchmarks encoding a Protocol Buffer message containing mSize 196 // bytes. 197 func bmEncode(b *testing.B, mSize int) { 198 cdc := encoding.GetCodec(protoenc.Name) 199 msg := &perfpb.Buffer{Body: make([]byte, mSize)} 200 encodeData, _ := encode(cdc, msg) 201 encodedSz := int64(len(encodeData)) 202 b.ReportAllocs() 203 b.ResetTimer() 204 for i := 0; i < b.N; i++ { 205 _, _ = encode(cdc, msg) 206 } 207 b.SetBytes(encodedSz) 208 } 209 210 func BenchmarkEncode1B(b *testing.B) { 211 bmEncode(b, 1) 212 } 213 214 func BenchmarkEncode1KiB(b *testing.B) { 215 bmEncode(b, 1024) 216 } 217 218 func BenchmarkEncode8KiB(b *testing.B) { 219 bmEncode(b, 8*1024) 220 } 221 222 func BenchmarkEncode64KiB(b *testing.B) { 223 bmEncode(b, 64*1024) 224 } 225 226 func BenchmarkEncode512KiB(b *testing.B) { 227 bmEncode(b, 512*1024) 228 } 229 230 func BenchmarkEncode1MiB(b *testing.B) { 231 bmEncode(b, 1024*1024) 232 } 233 234 // bmCompressor benchmarks a compressor of a Protocol Buffer message containing 235 // mSize bytes. 236 func bmCompressor(b *testing.B, mSize int, cp Compressor) { 237 payload := make([]byte, mSize) 238 cBuf := bytes.NewBuffer(make([]byte, mSize)) 239 b.ReportAllocs() 240 b.ResetTimer() 241 for i := 0; i < b.N; i++ { 242 _ = cp.Do(cBuf, payload) 243 cBuf.Reset() 244 } 245 } 246 247 func BenchmarkGZIPCompressor1B(b *testing.B) { 248 bmCompressor(b, 1, NewGZIPCompressor()) 249 } 250 251 func BenchmarkGZIPCompressor1KiB(b *testing.B) { 252 bmCompressor(b, 1024, NewGZIPCompressor()) 253 } 254 255 func BenchmarkGZIPCompressor8KiB(b *testing.B) { 256 bmCompressor(b, 8*1024, NewGZIPCompressor()) 257 } 258 259 func BenchmarkGZIPCompressor64KiB(b *testing.B) { 260 bmCompressor(b, 64*1024, NewGZIPCompressor()) 261 } 262 263 func BenchmarkGZIPCompressor512KiB(b *testing.B) { 264 bmCompressor(b, 512*1024, NewGZIPCompressor()) 265 } 266 267 func BenchmarkGZIPCompressor1MiB(b *testing.B) { 268 bmCompressor(b, 1024*1024, NewGZIPCompressor()) 269 }