github.com/matrixorigin/matrixone@v1.2.0/pkg/txn/service/service_dn_handler_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 service
    16  
    17  import (
    18  	"context"
    19  	"testing"
    20  
    21  	"github.com/matrixorigin/matrixone/pkg/common/moerr"
    22  	"github.com/matrixorigin/matrixone/pkg/pb/txn"
    23  	"github.com/matrixorigin/matrixone/pkg/txn/rpc"
    24  	"github.com/matrixorigin/matrixone/pkg/txn/storage/mem"
    25  	"github.com/stretchr/testify/assert"
    26  )
    27  
    28  func TestPrepare(t *testing.T) {
    29  	sender := NewTestSender()
    30  	defer func() {
    31  		assert.NoError(t, sender.Close())
    32  	}()
    33  
    34  	s := NewTestTxnService(t, 1, sender, NewTestClock(1)).(*service)
    35  	assert.NoError(t, s.Start())
    36  	defer func() {
    37  		assert.NoError(t, s.Close(false))
    38  	}()
    39  	sender.AddTxnService(s)
    40  
    41  	wTxn := NewTestTxn(1, 1, 1, 2)
    42  	checkResponses(t, writeTestData(t, sender, 1, wTxn, 1))
    43  	checkResponses(t, prepareTestTxn(t, sender, wTxn, 1))
    44  
    45  	value := s.storage.(*mem.KVTxnStorage).GetUncommittedTxn(wTxn.ID)
    46  	assert.NotNil(t, value)
    47  	assert.Equal(t, txn.TxnStatus_Prepared, value.Status)
    48  	assert.Equal(t, s.getTxnContext(wTxn.ID).getTxn(), *value)
    49  }
    50  
    51  func TestPrepareWithAlreadyPreparedTxn(t *testing.T) {
    52  	sender := NewTestSender()
    53  	defer func() {
    54  		assert.NoError(t, sender.Close())
    55  	}()
    56  
    57  	s := NewTestTxnService(t, 1, sender, NewTestClock(1)).(*service)
    58  	assert.NoError(t, s.Start())
    59  	defer func() {
    60  		assert.NoError(t, s.Close(false))
    61  	}()
    62  	sender.AddTxnService(s)
    63  
    64  	wTxn := NewTestTxn(1, 1, 1, 2)
    65  	checkResponses(t, writeTestData(t, sender, 1, wTxn, 1))
    66  	checkResponses(t, prepareTestTxn(t, sender, wTxn, 1))
    67  	checkResponses(t, prepareTestTxn(t, sender, wTxn, 1))
    68  
    69  	value := s.storage.(*mem.KVTxnStorage).GetUncommittedTxn(wTxn.ID)
    70  	assert.NotNil(t, value)
    71  	assert.Equal(t, txn.TxnStatus_Prepared, value.Status)
    72  	assert.Equal(t, s.getTxnContext(wTxn.ID).getTxn(), *value)
    73  }
    74  
    75  func TestPrepareWithTxnNotExist(t *testing.T) {
    76  	sender := NewTestSender()
    77  	defer func() {
    78  		assert.NoError(t, sender.Close())
    79  	}()
    80  
    81  	s := NewTestTxnService(t, 1, sender, NewTestClock(1))
    82  	assert.NoError(t, s.Start())
    83  	defer func() {
    84  		assert.NoError(t, s.Close(false))
    85  	}()
    86  	sender.AddTxnService(s)
    87  
    88  	wTxn := NewTestTxn(1, 1, 1, 2)
    89  	checkResponses(t, prepareTestTxn(t, sender, wTxn, 1),
    90  		txn.WrapError(moerr.NewTxnNotFound(context.TODO()), 0))
    91  }
    92  
    93  func TestGetStatus(t *testing.T) {
    94  	sender := NewTestSender()
    95  	defer func() {
    96  		assert.NoError(t, sender.Close())
    97  	}()
    98  
    99  	s := NewTestTxnService(t, 1, sender, NewTestClock(1)).(*service)
   100  	assert.NoError(t, s.Start())
   101  	defer func() {
   102  		assert.NoError(t, s.Close(false))
   103  	}()
   104  	sender.AddTxnService(s)
   105  
   106  	wTxn := NewTestTxn(1, 1, 1, 2)
   107  	responses := getTestTxnStatus(t, sender, wTxn, 1)
   108  	assert.Nil(t, responses[0].Txn)
   109  	assert.Nil(t, responses[0].TxnError)
   110  
   111  	checkResponses(t, writeTestData(t, sender, 1, wTxn, 1))
   112  	responses = getTestTxnStatus(t, sender, wTxn, 1)
   113  	assert.NotNil(t, responses[0].Txn)
   114  	assert.Equal(t, s.getTxnContext(wTxn.ID).getTxn(), *responses[0].Txn)
   115  	assert.Nil(t, responses[0].TxnError)
   116  
   117  	checkResponses(t, prepareTestTxn(t, sender, wTxn, 1))
   118  	responses = getTestTxnStatus(t, sender, wTxn, 1)
   119  	assert.NotNil(t, responses[0].Txn)
   120  	assert.Equal(t, s.getTxnContext(wTxn.ID).getTxn(), *responses[0].Txn)
   121  	assert.Nil(t, responses[0].TxnError)
   122  
   123  	wTxn2 := NewTestTxn(2, 1, 1)
   124  	checkResponses(t, writeTestData(t, sender, 1, wTxn2, 2))
   125  	checkResponses(t, commitWriteData(t, sender, wTxn2))
   126  	responses = getTestTxnStatus(t, sender, wTxn2, 1)
   127  	assert.Nil(t, responses[0].Txn)
   128  	assert.Nil(t, responses[0].TxnError)
   129  }
   130  
   131  func prepareTestTxn(t *testing.T, sender rpc.TxnSender, wTxn txn.TxnMeta, shard uint64) []txn.TxnResponse {
   132  	result, err := sender.Send(context.Background(), []txn.TxnRequest{NewTestPrepareRequest(wTxn, shard)})
   133  	assert.NoError(t, err)
   134  	return result.Responses
   135  }
   136  
   137  func getTestTxnStatus(t *testing.T, sender rpc.TxnSender, wTxn txn.TxnMeta, shard uint64) []txn.TxnResponse {
   138  	result, err := sender.Send(context.Background(), []txn.TxnRequest{NewTestGetStatusRequest(wTxn, shard)})
   139  	assert.NoError(t, err)
   140  	return result.Responses
   141  }