github.com/matrixorigin/matrixone@v1.2.0/pkg/txn/rpc/server_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 rpc 16 17 import ( 18 "context" 19 "os" 20 "testing" 21 "time" 22 23 "github.com/matrixorigin/matrixone/pkg/common/morpc" 24 "github.com/matrixorigin/matrixone/pkg/common/runtime" 25 "github.com/matrixorigin/matrixone/pkg/logutil" 26 "github.com/matrixorigin/matrixone/pkg/pb/metadata" 27 "github.com/matrixorigin/matrixone/pkg/pb/txn" 28 "github.com/matrixorigin/matrixone/pkg/txn/clock" 29 "github.com/matrixorigin/matrixone/pkg/util/toml" 30 "github.com/stretchr/testify/assert" 31 "go.uber.org/zap" 32 ) 33 34 func TestHandleMessageWithSender(t *testing.T) { 35 runTestTxnServer(t, testTN1Addr, func(s *server) { 36 s.RegisterMethodHandler(txn.TxnMethod_Read, func(ctx context.Context, tr1 *txn.TxnRequest, tr2 *txn.TxnResponse) error { 37 return nil 38 }) 39 40 rt := newTestRuntime(newTestClock(), s.rt.Logger().RawLogger()) 41 runtime.SetupProcessLevelRuntime(rt) 42 cli, err := NewSender(Config{EnableCompress: true}, rt) 43 assert.NoError(t, err) 44 defer func() { 45 assert.NoError(t, cli.Close()) 46 }() 47 48 ctx, cancel := context.WithTimeout(context.Background(), time.Hour) 49 defer cancel() 50 51 v, err := cli.Send(ctx, []txn.TxnRequest{{CNRequest: &txn.CNOpRequest{Target: metadata.TNShard{Address: testTN1Addr}}}}) 52 assert.NoError(t, err) 53 assert.Equal(t, 1, len(v.Responses)) 54 }, WithServerEnableCompress(true)) 55 } 56 57 func TestHandleMessageEnableCompressWithSender(t *testing.T) { 58 runTestTxnServer(t, testTN1Addr, func(s *server) { 59 s.RegisterMethodHandler(txn.TxnMethod_Read, func(ctx context.Context, tr1 *txn.TxnRequest, tr2 *txn.TxnResponse) error { 60 return nil 61 }) 62 63 cli, err := NewSender(Config{}, newTestRuntime(newTestClock(), s.rt.Logger().RawLogger())) 64 assert.NoError(t, err) 65 defer func() { 66 assert.NoError(t, cli.Close()) 67 }() 68 69 ctx, cancel := context.WithTimeout(context.Background(), time.Hour) 70 defer cancel() 71 72 v, err := cli.Send(ctx, []txn.TxnRequest{{CNRequest: &txn.CNOpRequest{Target: metadata.TNShard{Address: testTN1Addr}}}}) 73 assert.NoError(t, err) 74 assert.Equal(t, 1, len(v.Responses)) 75 }) 76 } 77 78 func TestHandleLargeMessageWithSender(t *testing.T) { 79 size := 1024 * 1024 * 15 80 runTestTxnServer(t, testTN1Addr, func(s *server) { 81 s.RegisterMethodHandler(txn.TxnMethod_Read, func(ctx context.Context, tr1 *txn.TxnRequest, tr2 *txn.TxnResponse) error { 82 tr2.CNOpResponse = &txn.CNOpResponse{Payload: make([]byte, size)} 83 return nil 84 }) 85 86 cli, err := NewSender(Config{MaxMessageSize: toml.ByteSize(size + 1024)}, 87 newTestRuntime(newTestClock(), s.rt.Logger().RawLogger())) 88 assert.NoError(t, err) 89 defer func() { 90 assert.NoError(t, cli.Close()) 91 }() 92 93 ctx, cancel := context.WithTimeout(context.Background(), time.Hour) 94 defer cancel() 95 96 v, err := cli.Send(ctx, []txn.TxnRequest{{ 97 CNRequest: &txn.CNOpRequest{ 98 Target: metadata.TNShard{Address: testTN1Addr}, 99 Payload: make([]byte, size), 100 }, 101 }}) 102 assert.NoError(t, err) 103 assert.Equal(t, 1, len(v.Responses)) 104 }, WithServerMaxMessageSize(size+1024)) 105 } 106 107 func TestHandleMessage(t *testing.T) { 108 runTestTxnServer(t, testTN1Addr, func(s *server) { 109 s.RegisterMethodHandler(txn.TxnMethod_Read, func(ctx context.Context, tr1 *txn.TxnRequest, tr2 *txn.TxnResponse) error { 110 return nil 111 }) 112 113 c := make(chan morpc.Message, 1) 114 defer close(c) 115 cs := newTestClientSession(c) 116 117 ctx, cancel := context.WithTimeout(context.Background(), time.Hour) 118 defer cancel() 119 assert.NoError(t, s.onMessage(ctx, newMessage(&txn.TxnRequest{RequestID: 1}), 0, cs)) 120 v := <-c 121 assert.Equal(t, uint64(1), v.GetID()) 122 }) 123 } 124 125 func TestHandleMessageWithFilter(t *testing.T) { 126 runTestTxnServer(t, testTN1Addr, func(s *server) { 127 n := 0 128 s.RegisterMethodHandler(txn.TxnMethod_Read, func(_ context.Context, _ *txn.TxnRequest, _ *txn.TxnResponse) error { 129 n++ 130 return nil 131 }) 132 133 ctx, cancel := context.WithTimeout(context.Background(), time.Hour) 134 defer cancel() 135 assert.NoError(t, s.onMessage(ctx, newMessage(&txn.TxnRequest{RequestID: 1}), 136 0, nil)) 137 assert.Equal(t, 0, n) 138 }, WithServerMessageFilter(func(tr *txn.TxnRequest) bool { 139 return false 140 })) 141 } 142 143 func TestHandleInvalidMessageWillPanic(t *testing.T) { 144 runTestTxnServer(t, testTN1Addr, func(s *server) { 145 defer func() { 146 if err := recover(); err != nil { 147 return 148 } 149 assert.Fail(t, "must panic") 150 }() 151 ctx, cancel := context.WithTimeout(context.Background(), time.Hour) 152 defer cancel() 153 assert.NoError(t, s.onMessage(ctx, newMessage(&txn.TxnResponse{}), 0, nil)) 154 }) 155 } 156 157 func TestHandleNotRegisterWillReturnError(t *testing.T) { 158 runTestTxnServer(t, testTN1Addr, func(s *server) { 159 assert.Error(t, s.onMessage(context.Background(), newMessage(&txn.TxnRequest{}), 0, nil)) 160 }) 161 } 162 163 func TestTimeoutRequestCannotHandled(t *testing.T) { 164 runTestTxnServer(t, testTN1Addr, func(s *server) { 165 n := 0 166 s.RegisterMethodHandler(txn.TxnMethod_Read, 167 func(_ context.Context, _ *txn.TxnRequest, _ *txn.TxnResponse) error { 168 n++ 169 return nil 170 }) 171 172 ctx, cancel := context.WithTimeout(context.Background(), 1) 173 cancel() 174 req := &txn.TxnRequest{Method: txn.TxnMethod_Read} 175 assert.NoError(t, s.onMessage(ctx, newMessage(req), 0, nil)) 176 assert.Equal(t, 0, n) 177 }) 178 } 179 180 func runTestTxnServer(t *testing.T, addr string, testFunc func(s *server), opts ...ServerOption) { 181 assert.NoError(t, os.RemoveAll(addr[7:])) 182 opts = append(opts, 183 WithServerQueueBufferSize(100), 184 WithServerQueueWorkers(2)) 185 s, err := NewTxnServer(addr, 186 newTestRuntime(clock.NewHLCClock(func() int64 { return 0 }, 0), logutil.GetPanicLogger()), 187 opts...) 188 assert.NoError(t, err) 189 defer func() { 190 assert.NoError(t, s.Close()) 191 }() 192 assert.NoError(t, s.Start()) 193 194 testFunc(s.(*server)) 195 } 196 197 type testClientSession struct { 198 c chan morpc.Message 199 } 200 201 func newTestClientSession(c chan morpc.Message) *testClientSession { 202 return &testClientSession{ 203 c: c, 204 } 205 } 206 207 func (cs *testClientSession) RemoteAddress() string { 208 return "" 209 } 210 211 func (cs *testClientSession) Close() error { 212 return nil 213 } 214 215 func (cs *testClientSession) Write(ctx context.Context, response morpc.Message) error { 216 cs.c <- response 217 return nil 218 } 219 220 func (cs *testClientSession) AsyncWrite(response morpc.Message) error { 221 return nil 222 } 223 224 func (cs *testClientSession) CreateCache( 225 ctx context.Context, 226 cacheID uint64) (morpc.MessageCache, error) { 227 panic("not implement") 228 } 229 230 func (cs *testClientSession) DeleteCache(cacheID uint64) { 231 panic("not implement") 232 } 233 234 func (cs *testClientSession) GetCache(cacheID uint64) (morpc.MessageCache, error) { 235 panic("not implement") 236 } 237 238 func newTestClock() clock.Clock { 239 return clock.NewHLCClock(func() int64 { return 0 }, 0) 240 } 241 242 func newTestRuntime(clock clock.Clock, logger *zap.Logger) runtime.Runtime { 243 return runtime.NewRuntime(metadata.ServiceType_CN, "", logutil.Adjust(logger), runtime.WithClock(clock)) 244 } 245 246 func newMessage(req morpc.Message) morpc.RPCMessage { 247 ctx, cancel := context.WithCancel(context.Background()) 248 return morpc.RPCMessage{ 249 Ctx: ctx, 250 Cancel: cancel, 251 Message: req, 252 } 253 }