github.com/matrixorigin/matrixone@v0.7.0/pkg/txn/client/client_test.go (about) 1 // Copyright 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 client 16 17 import ( 18 "context" 19 "fmt" 20 "sync" 21 "testing" 22 23 "github.com/matrixorigin/matrixone/pkg/common/runtime" 24 "github.com/matrixorigin/matrixone/pkg/logutil" 25 "github.com/matrixorigin/matrixone/pkg/pb/metadata" 26 "github.com/matrixorigin/matrixone/pkg/pb/timestamp" 27 "github.com/matrixorigin/matrixone/pkg/pb/txn" 28 "github.com/matrixorigin/matrixone/pkg/txn/clock" 29 "github.com/matrixorigin/matrixone/pkg/txn/rpc" 30 "github.com/stretchr/testify/assert" 31 ) 32 33 func TestAdjustClient(t *testing.T) { 34 c := &txnClient{rt: runtime.DefaultRuntime()} 35 c.adjust() 36 assert.NotNil(t, c.generator) 37 assert.NotNil(t, c.generator) 38 assert.NotNil(t, c.rt) 39 } 40 41 func TestNewTxn(t *testing.T) { 42 rt := runtime.NewRuntime(metadata.ServiceType_CN, "", 43 logutil.GetPanicLogger(), 44 runtime.WithClock(clock.NewHLCClock(func() int64 { 45 return 1 46 }, 0))) 47 c := NewTxnClient(rt, newTestTxnSender()) 48 tx, err := c.New() 49 assert.Nil(t, err) 50 txnMeta := tx.(*txnOperator).mu.txn 51 assert.Equal(t, timestamp.Timestamp{PhysicalTime: 1}, txnMeta.SnapshotTS) 52 assert.NotEmpty(t, txnMeta.ID) 53 assert.Equal(t, txn.TxnStatus_Active, txnMeta.Status) 54 } 55 56 func TestNewTxnWithSnapshotTS(t *testing.T) { 57 rt := runtime.NewRuntime(metadata.ServiceType_CN, "", 58 logutil.GetPanicLogger(), 59 runtime.WithClock(clock.NewHLCClock(func() int64 { 60 return 1 61 }, 0))) 62 c := NewTxnClient(rt, newTestTxnSender()) 63 tx, err := c.New(WithSnapshotTS(timestamp.Timestamp{PhysicalTime: 10})) 64 assert.Nil(t, err) 65 txnMeta := tx.(*txnOperator).mu.txn 66 assert.Equal(t, timestamp.Timestamp{PhysicalTime: 10}, txnMeta.SnapshotTS) 67 assert.NotEmpty(t, txnMeta.ID) 68 assert.Equal(t, txn.TxnStatus_Active, txnMeta.Status) 69 } 70 71 func newTestTxnSender() *testTxnSender { 72 return &testTxnSender{auto: true} 73 } 74 75 type testTxnSender struct { 76 sync.Mutex 77 lastRequests []txn.TxnRequest 78 auto bool 79 manualFunc func(*rpc.SendResult, error) (*rpc.SendResult, error) 80 } 81 82 func (ts *testTxnSender) Close() error { 83 return nil 84 } 85 86 func (ts *testTxnSender) Send(ctx context.Context, requests []txn.TxnRequest) (*rpc.SendResult, error) { 87 ts.Lock() 88 defer ts.Unlock() 89 ts.lastRequests = requests 90 91 responses := make([]txn.TxnResponse, 0, len(requests)) 92 for _, req := range requests { 93 resp := txn.TxnResponse{ 94 Txn: &req.Txn, 95 Method: req.Method, 96 Flag: req.Flag, 97 } 98 switch resp.Method { 99 case txn.TxnMethod_Read: 100 resp.CNOpResponse = &txn.CNOpResponse{Payload: []byte(fmt.Sprintf("r-%d", req.CNRequest.OpCode))} 101 case txn.TxnMethod_Write: 102 resp.CNOpResponse = &txn.CNOpResponse{Payload: []byte(fmt.Sprintf("w-%d", req.CNRequest.OpCode))} 103 case txn.TxnMethod_DEBUG: 104 resp.CNOpResponse = &txn.CNOpResponse{Payload: req.CNRequest.Payload} 105 case txn.TxnMethod_Rollback: 106 resp.Txn.Status = txn.TxnStatus_Aborted 107 case txn.TxnMethod_Commit: 108 resp.Txn.Status = txn.TxnStatus_Committed 109 } 110 111 responses = append(responses, resp) 112 } 113 114 result := &rpc.SendResult{Responses: responses} 115 if !ts.auto { 116 return ts.manualFunc(result, nil) 117 } 118 return result, nil 119 } 120 121 func (ts *testTxnSender) setManual(manualFunc func(*rpc.SendResult, error) (*rpc.SendResult, error)) { 122 ts.Lock() 123 defer ts.Unlock() 124 ts.manualFunc = manualFunc 125 ts.auto = false 126 } 127 128 func (ts *testTxnSender) getLastRequests() []txn.TxnRequest { 129 ts.Lock() 130 defer ts.Unlock() 131 return ts.lastRequests 132 }