github.com/matrixorigin/matrixone@v0.7.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/stretchr/testify/assert"
    30  	"go.uber.org/zap"
    31  )
    32  
    33  func TestHandleMessageWithSender(t *testing.T) {
    34  	runTestTxnServer(t, testDN1Addr, func(s *server) {
    35  		s.RegisterMethodHandler(txn.TxnMethod_Read, func(ctx context.Context, tr1 *txn.TxnRequest, tr2 *txn.TxnResponse) error {
    36  			return nil
    37  		})
    38  
    39  		cli, err := NewSender(newTestRuntime(newTestClock(), s.rt.Logger().RawLogger()),
    40  			WithSenderEnableCompress(true))
    41  		assert.NoError(t, err)
    42  		defer func() {
    43  			assert.NoError(t, cli.Close())
    44  		}()
    45  
    46  		ctx, cancel := context.WithTimeout(context.Background(), time.Hour)
    47  		defer cancel()
    48  
    49  		v, err := cli.Send(ctx, []txn.TxnRequest{{CNRequest: &txn.CNOpRequest{Target: metadata.DNShard{Address: testDN1Addr}}}})
    50  		assert.NoError(t, err)
    51  		assert.Equal(t, 1, len(v.Responses))
    52  	}, WithServerEnableCompress(true))
    53  }
    54  
    55  func TestHandleMessageEnableCompressWithSender(t *testing.T) {
    56  	runTestTxnServer(t, testDN1Addr, func(s *server) {
    57  		s.RegisterMethodHandler(txn.TxnMethod_Read, func(ctx context.Context, tr1 *txn.TxnRequest, tr2 *txn.TxnResponse) error {
    58  			return nil
    59  		})
    60  
    61  		cli, err := NewSender(newTestRuntime(newTestClock(), s.rt.Logger().RawLogger()))
    62  		assert.NoError(t, err)
    63  		defer func() {
    64  			assert.NoError(t, cli.Close())
    65  		}()
    66  
    67  		ctx, cancel := context.WithTimeout(context.Background(), time.Hour)
    68  		defer cancel()
    69  
    70  		v, err := cli.Send(ctx, []txn.TxnRequest{{CNRequest: &txn.CNOpRequest{Target: metadata.DNShard{Address: testDN1Addr}}}})
    71  		assert.NoError(t, err)
    72  		assert.Equal(t, 1, len(v.Responses))
    73  	})
    74  }
    75  
    76  func TestHandleLargeMessageWithSender(t *testing.T) {
    77  	size := 1024 * 1024 * 15
    78  	runTestTxnServer(t, testDN1Addr, func(s *server) {
    79  		s.RegisterMethodHandler(txn.TxnMethod_Read, func(ctx context.Context, tr1 *txn.TxnRequest, tr2 *txn.TxnResponse) error {
    80  			tr2.CNOpResponse = &txn.CNOpResponse{Payload: make([]byte, size)}
    81  			return nil
    82  		})
    83  
    84  		cli, err := NewSender(newTestRuntime(newTestClock(), s.rt.Logger().RawLogger()),
    85  			WithSenderMaxMessageSize(size+1024))
    86  		assert.NoError(t, err)
    87  		defer func() {
    88  			assert.NoError(t, cli.Close())
    89  		}()
    90  
    91  		ctx, cancel := context.WithTimeout(context.Background(), time.Hour)
    92  		defer cancel()
    93  
    94  		v, err := cli.Send(ctx, []txn.TxnRequest{{
    95  			CNRequest: &txn.CNOpRequest{
    96  				Target:  metadata.DNShard{Address: testDN1Addr},
    97  				Payload: make([]byte, size),
    98  			},
    99  		}})
   100  		assert.NoError(t, err)
   101  		assert.Equal(t, 1, len(v.Responses))
   102  	}, WithServerMaxMessageSize(size+1024))
   103  }
   104  
   105  func TestHandleMessage(t *testing.T) {
   106  	runTestTxnServer(t, testDN1Addr, func(s *server) {
   107  		s.RegisterMethodHandler(txn.TxnMethod_Read, func(ctx context.Context, tr1 *txn.TxnRequest, tr2 *txn.TxnResponse) error {
   108  			return nil
   109  		})
   110  
   111  		c := make(chan morpc.Message, 1)
   112  		defer close(c)
   113  		cs := newTestClientSession(c)
   114  
   115  		ctx, cancel := context.WithTimeout(context.Background(), time.Hour)
   116  		defer cancel()
   117  		assert.NoError(t, s.onMessage(ctx, &txn.TxnRequest{RequestID: 1}, 0, cs))
   118  		v := <-c
   119  		assert.Equal(t, uint64(1), v.GetID())
   120  	})
   121  }
   122  
   123  func TestHandleMessageWithFilter(t *testing.T) {
   124  	runTestTxnServer(t, testDN1Addr, func(s *server) {
   125  		n := 0
   126  		s.RegisterMethodHandler(txn.TxnMethod_Read, func(_ context.Context, _ *txn.TxnRequest, _ *txn.TxnResponse) error {
   127  			n++
   128  			return nil
   129  		})
   130  
   131  		ctx, cancel := context.WithTimeout(context.Background(), time.Hour)
   132  		defer cancel()
   133  		assert.NoError(t, s.onMessage(ctx, &txn.TxnRequest{RequestID: 1},
   134  			0, nil))
   135  		assert.Equal(t, 0, n)
   136  	}, WithServerMessageFilter(func(tr *txn.TxnRequest) bool {
   137  		return false
   138  	}))
   139  }
   140  
   141  func TestHandleInvalidMessageWillPanic(t *testing.T) {
   142  	runTestTxnServer(t, testDN1Addr, func(s *server) {
   143  		defer func() {
   144  			if err := recover(); err != nil {
   145  				return
   146  			}
   147  			assert.Fail(t, "must panic")
   148  		}()
   149  		ctx, cancel := context.WithTimeout(context.Background(), time.Hour)
   150  		defer cancel()
   151  		assert.NoError(t, s.onMessage(ctx, &txn.TxnResponse{}, 0, nil))
   152  	})
   153  }
   154  
   155  func TestHandleNotRegisterWillPanic(t *testing.T) {
   156  	runTestTxnServer(t, testDN1Addr, func(s *server) {
   157  		defer func() {
   158  			if err := recover(); err != nil {
   159  				return
   160  			}
   161  			assert.Fail(t, "must panic")
   162  		}()
   163  		assert.NoError(t, s.onMessage(context.Background(), &txn.TxnRequest{}, 0, nil))
   164  	})
   165  }
   166  
   167  func TestTimeoutRequestCannotHandled(t *testing.T) {
   168  	runTestTxnServer(t, testDN1Addr, func(s *server) {
   169  		n := 0
   170  		s.RegisterMethodHandler(txn.TxnMethod_Read,
   171  			func(_ context.Context, _ *txn.TxnRequest, _ *txn.TxnResponse) error {
   172  				n++
   173  				return nil
   174  			})
   175  
   176  		ctx, cancel := context.WithTimeout(context.Background(), 1)
   177  		cancel()
   178  		req := &txn.TxnRequest{Method: txn.TxnMethod_Read}
   179  		assert.NoError(t, s.onMessage(ctx, req, 0, nil))
   180  		assert.Equal(t, 0, n)
   181  	})
   182  }
   183  
   184  func runTestTxnServer(t *testing.T, addr string, testFunc func(s *server), opts ...ServerOption) {
   185  	assert.NoError(t, os.RemoveAll(addr[7:]))
   186  	s, err := NewTxnServer(addr,
   187  		newTestRuntime(clock.NewHLCClock(func() int64 { return 0 }, 0), logutil.GetPanicLogger()),
   188  		opts...)
   189  	assert.NoError(t, err)
   190  	defer func() {
   191  		assert.NoError(t, s.Close())
   192  	}()
   193  	assert.NoError(t, s.Start())
   194  
   195  	testFunc(s.(*server))
   196  }
   197  
   198  type testClientSession struct {
   199  	c chan morpc.Message
   200  }
   201  
   202  func newTestClientSession(c chan morpc.Message) *testClientSession {
   203  	return &testClientSession{
   204  		c: c,
   205  	}
   206  }
   207  
   208  func (cs *testClientSession) Close() error {
   209  	return nil
   210  }
   211  
   212  func (cs *testClientSession) Write(ctx context.Context, response morpc.Message) error {
   213  	cs.c <- response
   214  	return nil
   215  }
   216  
   217  func newTestClock() clock.Clock {
   218  	return clock.NewHLCClock(func() int64 { return 0 }, 0)
   219  }
   220  
   221  func newTestRuntime(clock clock.Clock, logger *zap.Logger) runtime.Runtime {
   222  	return runtime.NewRuntime(metadata.ServiceType_CN, "", logutil.Adjust(logger), runtime.WithClock(clock))
   223  }