github.com/matrixorigin/matrixone@v0.7.0/pkg/vm/engine/tae/logtail/service/service_test.go (about) 1 // Copyright 2021 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 service 16 17 import ( 18 "context" 19 "math" 20 "testing" 21 "time" 22 23 "github.com/stretchr/testify/require" 24 25 "github.com/matrixorigin/matrixone/pkg/common/morpc" 26 "github.com/matrixorigin/matrixone/pkg/common/mpool" 27 "github.com/matrixorigin/matrixone/pkg/common/runtime" 28 "github.com/matrixorigin/matrixone/pkg/logutil" 29 "github.com/matrixorigin/matrixone/pkg/pb/api" 30 "github.com/matrixorigin/matrixone/pkg/pb/logtail" 31 "github.com/matrixorigin/matrixone/pkg/pb/metadata" 32 "github.com/matrixorigin/matrixone/pkg/pb/timestamp" 33 "github.com/matrixorigin/matrixone/pkg/tests" 34 "github.com/matrixorigin/matrixone/pkg/txn/clock" 35 taelogtail "github.com/matrixorigin/matrixone/pkg/vm/engine/tae/logtail" 36 "github.com/matrixorigin/matrixone/pkg/vm/engine/tae/options" 37 ) 38 39 func TestService(t *testing.T) { 40 tableA := mockTable(1, 1, 1) 41 tableB := mockTable(2, 2, 2) 42 tableC := mockTable(3, 3, 3) 43 44 addrs, err := tests.GetAddressBatch("127.0.0.1", 1) 45 require.NoError(t, err) 46 47 address := addrs[0] 48 logtailer := mockLocktailer(tableA, tableB, tableC) 49 rt := mockRuntime() 50 51 /* ---- construct logtail server ---- */ 52 logtailServer, err := NewLogtailServer( 53 address, options.NewDefaultLogtailServerCfg(), logtailer, rt, 54 WithServerCollectInterval(500*time.Millisecond), 55 WithServerSendTimeout(5*time.Second), 56 WithServerEnableChecksum(true), 57 WithServerMaxMessageSize(32+7), 58 WithServerPayloadCopyBufferSize(16*mpool.KB), 59 WithServerMaxLogtailFetchFailure(5), 60 ) 61 require.NoError(t, err) 62 63 /* ---- start logtail server ---- */ 64 err = logtailServer.Start() 65 require.NoError(t, err) 66 defer func() { 67 err := logtailServer.Close() 68 require.NoError(t, err) 69 }() 70 71 /* ---- construct logtail client ---- */ 72 codec := morpc.NewMessageCodec(func() morpc.Message { return &LogtailResponseSegment{} }, 73 morpc.WithCodecPayloadCopyBufferSize(16*mpool.KB), 74 morpc.WithCodecEnableChecksum(), 75 morpc.WithCodecMaxBodySize(16*mpool.KB), 76 ) 77 bf := morpc.NewGoettyBasedBackendFactory(codec) 78 rpcClient, err := morpc.NewClient(bf, morpc.WithClientMaxBackendPerHost(1)) 79 require.NoError(t, err) 80 81 rpcStream, err := rpcClient.NewStream(address, false) 82 require.NoError(t, err) 83 84 logtailClient, err := NewLogtailClient(rpcStream, WithClientRequestPerSecond(100)) 85 require.NoError(t, err) 86 defer func() { 87 err := logtailClient.Close() 88 require.NoError(t, err) 89 }() 90 91 /* ---- send subscription request via logtail client ---- */ 92 { 93 t.Log("send subscription request via logtail client") 94 ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) 95 defer cancel() 96 err := logtailClient.Subscribe(ctx, tableA) 97 require.NoError(t, err) 98 } 99 100 /* ---- wait subscription response via logtail client ---- */ 101 { 102 t.Log("wait subscription response via logtail client") 103 resp, err := logtailClient.Receive() 104 require.NoError(t, err) 105 require.NotNil(t, resp.GetSubscribeResponse()) 106 require.Equal(t, tableA.String(), resp.GetSubscribeResponse().Logtail.Table.String()) 107 } 108 109 /* ---- wait update response via logtail client ---- */ 110 { 111 t.Log("wait update response via logtail client") 112 resp, err := logtailClient.Receive() 113 require.NoError(t, err) 114 require.NotNil(t, resp.GetUpdateResponse()) 115 require.Equal(t, 1, len(resp.GetUpdateResponse().LogtailList)) 116 require.Equal(t, tableA.String(), resp.GetUpdateResponse().LogtailList[0].Table.String()) 117 } 118 119 /* ---- send unsubscription request via logtail client ---- */ 120 { 121 t.Log("send unsubscription request via logtail client") 122 ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) 123 defer cancel() 124 err := logtailClient.Unsubscribe(ctx, tableA) 125 require.NoError(t, err) 126 } 127 128 /* ---- wait subscription response via logtail client ---- */ 129 { 130 t.Log("wait unsubscription response via logtail client") 131 for { 132 resp, err := logtailClient.Receive() 133 require.NoError(t, err) 134 if resp.GetUnsubscribeResponse() != nil { 135 require.Equal(t, tableA.String(), resp.GetUnsubscribeResponse().Table.String()) 136 break 137 } 138 } 139 } 140 141 /* ---- wait update response via logtail client ---- */ 142 { 143 t.Log("wait update response via logtail client") 144 resp, err := logtailClient.Receive() 145 require.NoError(t, err) 146 require.NotNil(t, resp.GetUpdateResponse()) 147 require.Equal(t, 0, len(resp.GetUpdateResponse().LogtailList)) 148 } 149 } 150 151 type logtailer struct { 152 tables []api.TableID 153 } 154 155 func mockLocktailer(tables ...api.TableID) taelogtail.Logtailer { 156 return &logtailer{ 157 tables: tables, 158 } 159 } 160 161 func (m *logtailer) RangeLogtail( 162 ctx context.Context, from, to timestamp.Timestamp, 163 ) ([]logtail.TableLogtail, error) { 164 tails := make([]logtail.TableLogtail, 0, len(m.tables)) 165 for _, table := range m.tables { 166 tails = append(tails, mockLogtail(table)) 167 } 168 return tails, nil 169 } 170 171 func (m *logtailer) TableLogtail( 172 ctx context.Context, table api.TableID, from, to timestamp.Timestamp, 173 ) (logtail.TableLogtail, error) { 174 for _, t := range m.tables { 175 if t.String() == table.String() { 176 return mockLogtail(table), nil 177 } 178 } 179 return logtail.TableLogtail{CkpLocation: "checkpoint", Table: &table, Ts: &to}, nil 180 } 181 182 func mockRuntime() runtime.Runtime { 183 return runtime.NewRuntime( 184 metadata.ServiceType_DN, 185 "uuid", 186 logutil.GetLogger(), 187 runtime.WithClock( 188 clock.NewHLCClock( 189 func() int64 { return time.Now().UTC().UnixNano() }, 190 time.Duration(math.MaxInt64), 191 ), 192 ), 193 ) 194 }