github.com/matrixorigin/matrixone@v0.7.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, mpool.Small) 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 p, err := mpool.NewMPool("test", 0, mpool.Small) 112 require.NoError(t, err) 113 114 ctx, cancel := context.WithTimeout(context.TODO(), time.Hour*10) 115 defer cancel() 116 117 codec := newTestCodec(WithCodecEnableCompress(p)) 118 buf1 := buf.NewByteBuf(32) 119 buf2 := buf.NewByteBuf(32) 120 121 msg := RPCMessage{Ctx: ctx, Message: newTestMessage(1)} 122 msg.Message.(*testMessage).payload = []byte(strings.Repeat("payload", 100)) 123 err = codec.Encode(msg, buf1, buf2) 124 assert.NoError(t, err) 125 126 v, ok, err := codec.Decode(buf2) 127 assert.True(t, ok) 128 assert.Equal(t, msg.Message, v.(RPCMessage).Message) 129 assert.NoError(t, err) 130 assert.NotNil(t, v.(RPCMessage).Ctx) 131 assert.NotNil(t, v.(RPCMessage).cancel) 132 } 133 134 func TestEncodeAndDecodeAndChecksumMismatch(t *testing.T) { 135 ctx, cancel := context.WithTimeout(context.TODO(), time.Hour*10) 136 defer cancel() 137 138 codec := newTestCodec(WithCodecEnableChecksum()) 139 buf1 := buf.NewByteBuf(32) 140 141 msg := RPCMessage{Ctx: ctx, Message: newTestMessage(1)} 142 err := codec.Encode(msg, buf1, nil) 143 assert.NoError(t, err) 144 145 buf.Uint64ToBytesTo(0, buf1.RawSlice(5, 5+8)) 146 147 v, ok, err := codec.Decode(buf1) 148 assert.False(t, ok) 149 assert.Error(t, err) 150 assert.Nil(t, v) 151 } 152 153 func TestEncodeAndDecodeWithPayload(t *testing.T) { 154 ctx, cancel := context.WithTimeout(context.TODO(), time.Hour*10) 155 defer cancel() 156 157 codec := newTestCodec() 158 buf1 := buf.NewByteBuf(32) 159 buf2 := buf.NewByteBuf(32) 160 161 msg := RPCMessage{Ctx: ctx, Message: newTestMessage(1)} 162 msg.Message.(*testMessage).payload = []byte("payload") 163 err := codec.Encode(msg, buf1, buf2) 164 assert.NoError(t, err) 165 166 v, ok, err := codec.Decode(buf2) 167 assert.True(t, ok) 168 assert.Equal(t, msg.Message, v.(RPCMessage).Message) 169 assert.NoError(t, err) 170 assert.NotNil(t, v.(RPCMessage).Ctx) 171 assert.NotNil(t, v.(RPCMessage).cancel) 172 } 173 174 func TestEncodeAndDecodeWithPayloadAndChecksum(t *testing.T) { 175 ctx, cancel := context.WithTimeout(context.TODO(), time.Hour*10) 176 defer cancel() 177 178 codec := newTestCodec(WithCodecEnableChecksum()) 179 buf1 := buf.NewByteBuf(32) 180 buf2 := buf.NewByteBuf(32) 181 182 msg := RPCMessage{Ctx: ctx, Message: newTestMessage(1)} 183 msg.Message.(*testMessage).payload = []byte("payload") 184 err := codec.Encode(msg, buf1, buf2) 185 assert.NoError(t, err) 186 187 v, ok, err := codec.Decode(buf2) 188 assert.True(t, ok) 189 assert.Equal(t, msg.Message, v.(RPCMessage).Message) 190 assert.NoError(t, err) 191 assert.NotNil(t, v.(RPCMessage).Ctx) 192 assert.NotNil(t, v.(RPCMessage).cancel) 193 } 194 195 func TestEncodeAndDecodeWithEmptyPayloadAndChecksum(t *testing.T) { 196 ctx, cancel := context.WithTimeout(context.TODO(), time.Hour*10) 197 defer cancel() 198 199 codec := newTestCodec(WithCodecEnableChecksum()) 200 buf1 := buf.NewByteBuf(32) 201 buf2 := buf.NewByteBuf(32) 202 203 msg := RPCMessage{Ctx: ctx, Message: newTestMessage(1)} 204 err := codec.Encode(msg, buf1, buf2) 205 assert.NoError(t, err) 206 io.Copy(buf2, buf1) 207 208 v, ok, err := codec.Decode(buf2) 209 assert.True(t, ok) 210 assert.Equal(t, msg.Message, v.(RPCMessage).Message) 211 assert.NoError(t, err) 212 assert.NotNil(t, v.(RPCMessage).Ctx) 213 assert.NotNil(t, v.(RPCMessage).cancel) 214 } 215 216 func TestEncodeAndDecodeWithEmptyPayloadAndChecksumMismatch(t *testing.T) { 217 ctx, cancel := context.WithTimeout(context.TODO(), time.Hour*10) 218 defer cancel() 219 220 codec := newTestCodec(WithCodecEnableChecksum()) 221 buf1 := buf.NewByteBuf(32) 222 buf2 := buf.NewByteBuf(32) 223 224 msg := RPCMessage{Ctx: ctx, Message: newTestMessage(1)} 225 err := codec.Encode(msg, buf1, buf2) 226 assert.NoError(t, err) 227 io.Copy(buf2, buf1) 228 229 buf.Uint64ToBytesTo(0, buf2.RawSlice(5, 5+8)) 230 _, ok, err := codec.Decode(buf2) 231 assert.False(t, ok) 232 assert.Error(t, err) 233 } 234 235 func TestNewWithMaxBodySize(t *testing.T) { 236 ctx, cancel := context.WithTimeout(context.TODO(), time.Hour*10) 237 defer cancel() 238 239 maxBodySize := 1024 * 1024 * 20 240 codec := newTestCodec(WithCodecMaxBodySize(maxBodySize + 1024)) 241 buf1 := buf.NewByteBuf(32) 242 buf2 := buf.NewByteBuf(32) 243 244 msg := RPCMessage{Ctx: ctx, Message: newTestMessage(1)} 245 msg.Message.(*testMessage).payload = make([]byte, 1024*1024*11) 246 err := codec.Encode(msg, buf1, buf2) 247 assert.NoError(t, err) 248 249 v, ok, err := codec.Decode(buf2) 250 assert.True(t, ok) 251 assert.Equal(t, msg.Message, v.(RPCMessage).Message) 252 assert.NoError(t, err) 253 assert.NotNil(t, v.(RPCMessage).Ctx) 254 assert.NotNil(t, v.(RPCMessage).cancel) 255 } 256 257 func TestBufferScale(t *testing.T) { 258 stopper := stopper.NewStopper("") 259 defer stopper.Stop() 260 261 ctx, cancel := context.WithTimeout(context.TODO(), time.Hour*10) 262 defer cancel() 263 c1 := newTestCodec(WithCodecEnableChecksum(), 264 WithCodecIntegrationHLC(clock.NewUnixNanoHLCClockWithStopper(stopper, 0)), 265 WithCodecPayloadCopyBufferSize(16*1024)) 266 c2 := newTestCodec(WithCodecEnableChecksum(), 267 WithCodecIntegrationHLC(clock.NewUnixNanoHLCClockWithStopper(stopper, 0)), 268 WithCodecPayloadCopyBufferSize(16*1024)) 269 out := buf.NewByteBuf(32) 270 conn := buf.NewByteBuf(32) 271 272 n := 100 273 var messages []RPCMessage 274 for i := 0; i < n; i++ { 275 msg := RPCMessage{Ctx: ctx, Message: newTestMessage(uint64(i))} 276 payload := make([]byte, 1024*1024) 277 payload[len(payload)-1] = byte(i) 278 msg.Message.(*testMessage).payload = payload 279 messages = append(messages, msg) 280 281 require.NoError(t, c1.Encode(msg, out, conn)) 282 } 283 _, err := out.WriteTo(conn) 284 if err != nil { 285 require.Equal(t, io.EOF, err) 286 } 287 288 for i := 0; i < n; i++ { 289 msg, ok, err := c2.Decode(conn) 290 require.NoError(t, err) 291 require.True(t, ok) 292 require.Equal(t, messages[i].Message, msg.(RPCMessage).Message) 293 } 294 } 295 296 func TestEncodeAndDecodeInternal(t *testing.T) { 297 codec := newTestCodec() 298 buf := buf.NewByteBuf(1) 299 300 ctx, cancel := context.WithTimeout(context.TODO(), time.Hour*10) 301 defer cancel() 302 303 msg := RPCMessage{Ctx: ctx, Message: &flagOnlyMessage{flag: flagPing}, internal: true} 304 err := codec.Encode(msg, buf, nil) 305 assert.NoError(t, err) 306 307 v, ok, err := codec.Decode(buf) 308 assert.True(t, ok) 309 assert.Equal(t, msg.Message, v.(RPCMessage).Message) 310 assert.NoError(t, err) 311 assert.NotNil(t, v.(RPCMessage).Ctx) 312 assert.NotNil(t, v.(RPCMessage).cancel) 313 }