github.com/matrixorigin/matrixone@v1.2.0/pkg/common/morpc/codec_test.go (about) 1 // Copyright 2021 - 2022 Matrix Origin 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package morpc 16 17 import ( 18 "context" 19 "io" 20 "strings" 21 "testing" 22 "time" 23 24 "github.com/fagongzi/goetty/v2/buf" 25 "github.com/matrixorigin/matrixone/pkg/common/mpool" 26 "github.com/matrixorigin/matrixone/pkg/common/stopper" 27 "github.com/matrixorigin/matrixone/pkg/txn/clock" 28 "github.com/stretchr/testify/assert" 29 "github.com/stretchr/testify/require" 30 ) 31 32 func TestEncodeAndDecode(t *testing.T) { 33 codec := newTestCodec() 34 buf := buf.NewByteBuf(1) 35 36 ctx, cancel := context.WithTimeout(context.TODO(), time.Hour*10) 37 defer cancel() 38 39 msg := RPCMessage{Ctx: ctx, Message: newTestMessage(1)} 40 err := codec.Encode(msg, buf, nil) 41 assert.NoError(t, err) 42 43 v, ok, err := codec.Decode(buf) 44 assert.True(t, ok) 45 assert.Equal(t, msg.Message, v.(RPCMessage).Message) 46 assert.NoError(t, err) 47 assert.NotNil(t, v.(RPCMessage).Ctx) 48 assert.NotNil(t, v.(RPCMessage).Cancel) 49 } 50 51 func TestEncodeAndDecodeWithStream(t *testing.T) { 52 codec := newTestCodec() 53 buf := buf.NewByteBuf(1) 54 55 ctx, cancel := context.WithTimeout(context.TODO(), time.Hour*10) 56 defer cancel() 57 58 msg := RPCMessage{Ctx: ctx, Message: newTestMessage(1), stream: true, streamSequence: 1} 59 err := codec.Encode(msg, buf, nil) 60 assert.NoError(t, err) 61 62 v, ok, err := codec.Decode(buf) 63 assert.True(t, ok) 64 assert.Equal(t, msg.Message, v.(RPCMessage).Message) 65 assert.True(t, v.(RPCMessage).stream) 66 assert.Equal(t, uint32(1), v.(RPCMessage).streamSequence) 67 assert.NoError(t, err) 68 assert.NotNil(t, v.(RPCMessage).Ctx) 69 assert.NotNil(t, v.(RPCMessage).Cancel) 70 } 71 72 func TestEncodeAndDecodeWithChecksum(t *testing.T) { 73 ctx, cancel := context.WithTimeout(context.TODO(), time.Hour*10) 74 defer cancel() 75 codec := newTestCodec(WithCodecEnableChecksum(), 76 WithCodecIntegrationHLC(clock.NewHLCClock(func() int64 { return 0 }, 0))) 77 buf1 := buf.NewByteBuf(32) 78 79 msg := newTestMessage(1) 80 err := codec.Encode(RPCMessage{Ctx: ctx, Message: msg}, buf1, nil) 81 assert.NoError(t, err) 82 83 buf.Uint64ToBytesTo(0, buf1.RawSlice(5, 5+8)) 84 _, ok, err := codec.Decode(buf1) 85 assert.False(t, ok) 86 assert.Error(t, err) 87 } 88 89 func TestEncodeAndDecodeWithCompress(t *testing.T) { 90 p, err := mpool.NewMPool("test", 0, 0) 91 require.NoError(t, err) 92 93 ctx, cancel := context.WithTimeout(context.TODO(), time.Hour*10) 94 defer cancel() 95 codec := newTestCodec(WithCodecEnableCompress(p)) 96 buf1 := buf.NewByteBuf(32) 97 98 msg := newTestMessage(1) 99 err = codec.Encode(RPCMessage{Ctx: ctx, Message: msg}, buf1, nil) 100 assert.NoError(t, err) 101 102 buf.Uint64ToBytesTo(0, buf1.RawSlice(5, 5+8)) 103 resp, ok, err := codec.Decode(buf1) 104 assert.NoError(t, err) 105 assert.True(t, ok) 106 107 assert.Equal(t, msg, resp.(RPCMessage).Message) 108 } 109 110 func TestEncodeAndDecodeWithCompressAndHasPayload(t *testing.T) { 111 // XXX Zhang Xu 112 // 113 // in codec, readMessage, dstPayload is freed c.pool.Free(dstPayload) 114 // but it is returned again in SetPayloadField 115 // We have to enable the NoFixed flag so that mpool Free does not 116 // really destroy the memory. 117 p, err := mpool.NewMPool("test", 0, mpool.NoFixed) 118 require.NoError(t, err) 119 120 ctx, cancel := context.WithTimeout(context.TODO(), time.Hour*10) 121 defer cancel() 122 123 codec := newTestCodec(WithCodecEnableCompress(p)) 124 buf1 := buf.NewByteBuf(32) 125 buf2 := buf.NewByteBuf(32) 126 127 msg := RPCMessage{Ctx: ctx, Message: newTestMessage(1)} 128 msg.Message.(*testMessage).payload = []byte(strings.Repeat("payload", 100)) 129 err = codec.Encode(msg, buf1, buf2) 130 assert.NoError(t, err) 131 132 v, ok, err := codec.Decode(buf2) 133 assert.True(t, ok) 134 assert.Equal(t, msg.Message, v.(RPCMessage).Message) 135 assert.NoError(t, err) 136 assert.NotNil(t, v.(RPCMessage).Ctx) 137 assert.NotNil(t, v.(RPCMessage).Cancel) 138 } 139 140 func TestEncodeAndDecodeAndChecksumMismatch(t *testing.T) { 141 ctx, cancel := context.WithTimeout(context.TODO(), time.Hour*10) 142 defer cancel() 143 144 codec := newTestCodec(WithCodecEnableChecksum()) 145 buf1 := buf.NewByteBuf(32) 146 147 msg := RPCMessage{Ctx: ctx, Message: newTestMessage(1)} 148 err := codec.Encode(msg, buf1, nil) 149 assert.NoError(t, err) 150 151 buf.Uint64ToBytesTo(0, buf1.RawSlice(5, 5+8)) 152 153 v, ok, err := codec.Decode(buf1) 154 assert.False(t, ok) 155 assert.Error(t, err) 156 assert.Nil(t, v) 157 } 158 159 func TestEncodeAndDecodeWithPayload(t *testing.T) { 160 ctx, cancel := context.WithTimeout(context.TODO(), time.Hour*10) 161 defer cancel() 162 163 codec := newTestCodec() 164 buf1 := buf.NewByteBuf(32) 165 buf2 := buf.NewByteBuf(32) 166 167 msg := RPCMessage{Ctx: ctx, Message: newTestMessage(1)} 168 msg.Message.(*testMessage).payload = []byte("payload") 169 err := codec.Encode(msg, buf1, buf2) 170 assert.NoError(t, err) 171 172 v, ok, err := codec.Decode(buf2) 173 assert.True(t, ok) 174 assert.Equal(t, msg.Message, v.(RPCMessage).Message) 175 assert.NoError(t, err) 176 assert.NotNil(t, v.(RPCMessage).Ctx) 177 assert.NotNil(t, v.(RPCMessage).Cancel) 178 } 179 180 func TestEncodeAndDecodeWithPayloadAndChecksum(t *testing.T) { 181 ctx, cancel := context.WithTimeout(context.TODO(), time.Hour*10) 182 defer cancel() 183 184 codec := newTestCodec(WithCodecEnableChecksum()) 185 buf1 := buf.NewByteBuf(32) 186 buf2 := buf.NewByteBuf(32) 187 188 msg := RPCMessage{Ctx: ctx, Message: newTestMessage(1)} 189 msg.Message.(*testMessage).payload = []byte("payload") 190 err := codec.Encode(msg, buf1, buf2) 191 assert.NoError(t, err) 192 193 v, ok, err := codec.Decode(buf2) 194 assert.True(t, ok) 195 assert.Equal(t, msg.Message, v.(RPCMessage).Message) 196 assert.NoError(t, err) 197 assert.NotNil(t, v.(RPCMessage).Ctx) 198 assert.NotNil(t, v.(RPCMessage).Cancel) 199 } 200 201 func TestEncodeAndDecodeWithEmptyPayloadAndChecksum(t *testing.T) { 202 ctx, cancel := context.WithTimeout(context.TODO(), time.Hour*10) 203 defer cancel() 204 205 codec := newTestCodec(WithCodecEnableChecksum()) 206 buf1 := buf.NewByteBuf(32) 207 buf2 := buf.NewByteBuf(32) 208 209 msg := RPCMessage{Ctx: ctx, Message: newTestMessage(1)} 210 err := codec.Encode(msg, buf1, buf2) 211 assert.NoError(t, err) 212 io.Copy(buf2, buf1) 213 214 v, ok, err := codec.Decode(buf2) 215 assert.True(t, ok) 216 assert.Equal(t, msg.Message, v.(RPCMessage).Message) 217 assert.NoError(t, err) 218 assert.NotNil(t, v.(RPCMessage).Ctx) 219 assert.NotNil(t, v.(RPCMessage).Cancel) 220 } 221 222 func TestEncodeAndDecodeWithEmptyPayloadAndChecksumMismatch(t *testing.T) { 223 ctx, cancel := context.WithTimeout(context.TODO(), time.Hour*10) 224 defer cancel() 225 226 codec := newTestCodec(WithCodecEnableChecksum()) 227 buf1 := buf.NewByteBuf(32) 228 buf2 := buf.NewByteBuf(32) 229 230 msg := RPCMessage{Ctx: ctx, Message: newTestMessage(1)} 231 err := codec.Encode(msg, buf1, buf2) 232 assert.NoError(t, err) 233 io.Copy(buf2, buf1) 234 235 buf.Uint64ToBytesTo(0, buf2.RawSlice(5, 5+8)) 236 _, ok, err := codec.Decode(buf2) 237 assert.False(t, ok) 238 assert.Error(t, err) 239 } 240 241 func TestNewWithMaxBodySize(t *testing.T) { 242 ctx, cancel := context.WithTimeout(context.TODO(), time.Hour*10) 243 defer cancel() 244 245 maxBodySize := 1024 * 1024 * 20 246 codec := newTestCodec(WithCodecMaxBodySize(maxBodySize + 1024)) 247 buf1 := buf.NewByteBuf(32) 248 buf2 := buf.NewByteBuf(32) 249 250 msg := RPCMessage{Ctx: ctx, Message: newTestMessage(1)} 251 msg.Message.(*testMessage).payload = make([]byte, 1024*1024*11) 252 err := codec.Encode(msg, buf1, buf2) 253 assert.NoError(t, err) 254 255 v, ok, err := codec.Decode(buf2) 256 assert.True(t, ok) 257 assert.Equal(t, msg.Message, v.(RPCMessage).Message) 258 assert.NoError(t, err) 259 assert.NotNil(t, v.(RPCMessage).Ctx) 260 assert.NotNil(t, v.(RPCMessage).Cancel) 261 } 262 263 func TestBufferScale(t *testing.T) { 264 stopper := stopper.NewStopper("") 265 defer stopper.Stop() 266 267 ctx, cancel := context.WithTimeout(context.TODO(), time.Hour*10) 268 defer cancel() 269 c1 := newTestCodec(WithCodecEnableChecksum(), 270 WithCodecIntegrationHLC(clock.NewUnixNanoHLCClockWithStopper(stopper, 0)), 271 WithCodecPayloadCopyBufferSize(16*1024)) 272 c2 := newTestCodec(WithCodecEnableChecksum(), 273 WithCodecIntegrationHLC(clock.NewUnixNanoHLCClockWithStopper(stopper, 0)), 274 WithCodecPayloadCopyBufferSize(16*1024)) 275 out := buf.NewByteBuf(32) 276 conn := buf.NewByteBuf(32) 277 278 n := 100 279 var messages []RPCMessage 280 for i := 0; i < n; i++ { 281 msg := RPCMessage{Ctx: ctx, Message: newTestMessage(uint64(i))} 282 payload := make([]byte, 1024*1024) 283 payload[len(payload)-1] = byte(i) 284 msg.Message.(*testMessage).payload = payload 285 messages = append(messages, msg) 286 287 require.NoError(t, c1.Encode(msg, out, conn)) 288 } 289 _, err := out.WriteTo(conn) 290 if err != nil { 291 require.Equal(t, io.EOF, err) 292 } 293 294 for i := 0; i < n; i++ { 295 msg, ok, err := c2.Decode(conn) 296 require.NoError(t, err) 297 require.True(t, ok) 298 require.Equal(t, messages[i].Message, msg.(RPCMessage).Message) 299 } 300 } 301 302 func TestEncodeAndDecodeInternal(t *testing.T) { 303 codec := newTestCodec() 304 buf := buf.NewByteBuf(1) 305 306 ctx, cancel := context.WithTimeout(context.TODO(), time.Hour*10) 307 defer cancel() 308 309 msg := RPCMessage{Ctx: ctx, Message: &flagOnlyMessage{flag: flagPing}, internal: true} 310 err := codec.Encode(msg, buf, nil) 311 assert.NoError(t, err) 312 313 v, ok, err := codec.Decode(buf) 314 assert.True(t, ok) 315 assert.Equal(t, msg.Message, v.(RPCMessage).Message) 316 assert.NoError(t, err) 317 assert.NotNil(t, v.(RPCMessage).Ctx) 318 assert.NotNil(t, v.(RPCMessage).Cancel) 319 }