github.com/matrixorigin/matrixone@v1.2.0/pkg/txn/service/service_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 service 16 17 import ( 18 "context" 19 "testing" 20 "time" 21 22 "github.com/matrixorigin/matrixone/pkg/common/moerr" 23 "github.com/matrixorigin/matrixone/pkg/pb/txn" 24 "github.com/stretchr/testify/assert" 25 ) 26 27 func TestGCZombie(t *testing.T) { 28 sender := NewTestSender() 29 defer func() { 30 assert.NoError(t, sender.Close()) 31 }() 32 33 zombie := time.Millisecond * 100 34 s := NewTestTxnServiceWithLogAndZombie(t, 1, sender, NewTestClock(1), nil, zombie).(*service) 35 assert.NoError(t, s.Start()) 36 defer func() { 37 assert.NoError(t, s.Close(false)) 38 }() 39 40 sender.AddTxnService(s) 41 42 wTxn := NewTestTxn(1, 1, 1) 43 checkResponses(t, writeTestData(t, sender, 1, wTxn, 1)) 44 45 w1 := addTestWaiter(t, s, wTxn, txn.TxnStatus_Aborted) 46 defer w1.close() 47 48 checkWaiter(t, w1, txn.TxnStatus_Aborted) 49 checkData(t, wTxn, s, 0, 0, false) 50 } 51 52 func TestGCZombieWithDistributedTxn(t *testing.T) { 53 sender := NewTestSender() 54 defer func() { 55 assert.NoError(t, sender.Close()) 56 }() 57 58 zombie := time.Millisecond * 100 59 s1 := NewTestTxnServiceWithLogAndZombie(t, 1, sender, NewTestClock(1), nil, zombie).(*service) 60 assert.NoError(t, s1.Start()) 61 defer func() { 62 assert.NoError(t, s1.Close(false)) 63 }() 64 65 s2 := NewTestTxnServiceWithLogAndZombie(t, 2, sender, NewTestClock(1), nil, zombie).(*service) 66 assert.NoError(t, s2.Start()) 67 defer func() { 68 assert.NoError(t, s2.Close(false)) 69 }() 70 71 sender.AddTxnService(s1) 72 sender.AddTxnService(s2) 73 74 // 1 is coordinator 75 wTxn := NewTestTxn(1, 1, 1, 2) 76 checkResponses(t, writeTestData(t, sender, 1, wTxn, 1)) 77 checkResponses(t, writeTestData(t, sender, 2, wTxn, 2)) 78 79 w1 := addTestWaiter(t, s1, wTxn, txn.TxnStatus_Aborted) 80 defer w1.close() 81 82 w2 := addTestWaiter(t, s2, wTxn, txn.TxnStatus_Aborted) 83 defer w2.close() 84 85 checkWaiter(t, w1, txn.TxnStatus_Aborted) 86 checkWaiter(t, w2, txn.TxnStatus_Aborted) 87 88 checkData(t, wTxn, s1, 0, 0, false) 89 checkData(t, wTxn, s2, 0, 0, false) 90 } 91 92 func TestGCZombieNonCoordinatorTxn(t *testing.T) { 93 sender := NewTestSender() 94 defer func() { 95 assert.NoError(t, sender.Close()) 96 }() 97 98 zombie := time.Millisecond * 100 99 s := NewTestTxnServiceWithLogAndZombie(t, 1, sender, NewTestClock(1), nil, zombie).(*service) 100 assert.NoError(t, s.Start()) 101 defer func() { 102 assert.NoError(t, s.Close(false)) 103 }() 104 105 sender.AddTxnService(s) 106 107 wTxn := NewTestTxn(1, 1, 1) 108 wTxn.TNShards = append(wTxn.TNShards, NewTestTNShard(2)) 109 // make shard 2 is coordinator 110 wTxn.TNShards[0], wTxn.TNShards[1] = wTxn.TNShards[1], wTxn.TNShards[0] 111 112 checkResponses(t, writeTestData(t, sender, 1, wTxn, 1)) 113 114 w1 := addTestWaiter(t, s, wTxn, txn.TxnStatus_Aborted) 115 defer w1.close() 116 117 ctx, cancel := context.WithTimeout(context.Background(), zombie*5) 118 defer cancel() 119 _, err := w1.wait(ctx) 120 assert.Error(t, err) 121 assert.Equal(t, moerr.ConvertGoError(ctx, ctx.Err()), err) 122 }