From 16d2a447256a7ac36912898377286ed5392d345f Mon Sep 17 00:00:00 2001 From: bohehe Date: Wed, 23 Feb 2022 21:37:32 +0800 Subject: [PATCH 01/13] add unit test for TC and implement test for GetStatus func --- go.mod | 1 + go.sum | 1 + pkg/tc/holder/mock/session_holder.go | 302 ++++++++++++++++++ pkg/tc/holder/session_holder.go | 19 ++ pkg/tc/lock/lock_manager.go | 2 +- pkg/tc/server/transaction_coordinator.go | 2 +- pkg/tc/server/transaction_coordinator_test.go | 91 ++++++ 7 files changed, 416 insertions(+), 2 deletions(-) create mode 100644 pkg/tc/holder/mock/session_holder.go create mode 100644 pkg/tc/server/transaction_coordinator_test.go diff --git a/go.mod b/go.mod index 6dfdbe45d..5f3db913c 100644 --- a/go.mod +++ b/go.mod @@ -7,6 +7,7 @@ require ( github.com/go-sql-driver/mysql v1.5.0 github.com/go-xorm/xorm v0.7.9 github.com/gogo/protobuf v1.3.2 + github.com/golang/mock v1.3.1 github.com/lib/pq v1.0.0 github.com/natefinch/lumberjack v2.0.0+incompatible github.com/pkg/errors v0.9.1 diff --git a/go.sum b/go.sum index e9ccf9962..ec1fb572d 100644 --- a/go.sum +++ b/go.sum @@ -148,6 +148,7 @@ github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4er github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.3.1 h1:qGJ6qTW+x6xX/my+8YUVl4WNpX9B7+/l2tRsHGZ7f2s= github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= diff --git a/pkg/tc/holder/mock/session_holder.go b/pkg/tc/holder/mock/session_holder.go new file mode 100644 index 000000000..606355c78 --- /dev/null +++ b/pkg/tc/holder/mock/session_holder.go @@ -0,0 +1,302 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: pkg/tc/holder/session_holder.go + +// Package mock_holder is a generated GoMock package. +package mock_holder + +import ( + reflect "reflect" + + gomock "github.com/golang/mock/gomock" + apis "github.com/opentrx/seata-golang/v2/pkg/apis" + model "github.com/opentrx/seata-golang/v2/pkg/tc/model" +) + +// MockSessionHolderInterface is a mock of SessionHolderInterface interface. +type MockSessionHolderInterface struct { + ctrl *gomock.Controller + recorder *MockSessionHolderInterfaceMockRecorder +} + +// MockSessionHolderInterfaceMockRecorder is the mock recorder for MockSessionHolderInterface. +type MockSessionHolderInterfaceMockRecorder struct { + mock *MockSessionHolderInterface +} + +// NewMockSessionHolderInterface creates a new mock instance. +func NewMockSessionHolderInterface(ctrl *gomock.Controller) *MockSessionHolderInterface { + mock := &MockSessionHolderInterface{ctrl: ctrl} + mock.recorder = &MockSessionHolderInterfaceMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockSessionHolderInterface) EXPECT() *MockSessionHolderInterfaceMockRecorder { + return m.recorder +} + +// AddGlobalSession mocks base method. +func (m *MockSessionHolderInterface) AddGlobalSession(session *apis.GlobalSession) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "AddGlobalSession", session) + ret0, _ := ret[0].(error) + return ret0 +} + +// AddGlobalSession indicates an expected call of AddGlobalSession. +func (mr *MockSessionHolderInterfaceMockRecorder) AddGlobalSession(session interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddGlobalSession", reflect.TypeOf((*MockSessionHolderInterface)(nil).AddGlobalSession), session) +} + +// FindGlobalSession mocks base method. +func (m *MockSessionHolderInterface) FindGlobalSession(xid string) *apis.GlobalSession { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "FindGlobalSession", xid) + ret0, _ := ret[0].(*apis.GlobalSession) + return ret0 +} + +// FindGlobalSession indicates an expected call of FindGlobalSession. +func (mr *MockSessionHolderInterfaceMockRecorder) FindGlobalSession(xid interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FindGlobalSession", reflect.TypeOf((*MockSessionHolderInterface)(nil).FindGlobalSession), xid) +} + +// FindGlobalTransaction mocks base method. +func (m *MockSessionHolderInterface) FindGlobalTransaction(xid string) *model.GlobalTransaction { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "FindGlobalTransaction", xid) + ret0, _ := ret[0].(*model.GlobalTransaction) + return ret0 +} + +// FindGlobalTransaction indicates an expected call of FindGlobalTransaction. +func (mr *MockSessionHolderInterfaceMockRecorder) FindGlobalTransaction(xid interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FindGlobalTransaction", reflect.TypeOf((*MockSessionHolderInterface)(nil).FindGlobalTransaction), xid) +} + +// FindAsyncCommittingGlobalTransactions mocks base method. +func (m *MockSessionHolderInterface) FindAsyncCommittingGlobalTransactions(addressingIdentities []string) []*model.GlobalTransaction { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "FindAsyncCommittingGlobalTransactions", addressingIdentities) + ret0, _ := ret[0].([]*model.GlobalTransaction) + return ret0 +} + +// FindAsyncCommittingGlobalTransactions indicates an expected call of FindAsyncCommittingGlobalTransactions. +func (mr *MockSessionHolderInterfaceMockRecorder) FindAsyncCommittingGlobalTransactions(addressingIdentities interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FindAsyncCommittingGlobalTransactions", reflect.TypeOf((*MockSessionHolderInterface)(nil).FindAsyncCommittingGlobalTransactions), addressingIdentities) +} + +// FindRetryCommittingGlobalTransactions mocks base method. +func (m *MockSessionHolderInterface) FindRetryCommittingGlobalTransactions(addressingIdentities []string) []*model.GlobalTransaction { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "FindRetryCommittingGlobalTransactions", addressingIdentities) + ret0, _ := ret[0].([]*model.GlobalTransaction) + return ret0 +} + +// FindRetryCommittingGlobalTransactions indicates an expected call of FindRetryCommittingGlobalTransactions. +func (mr *MockSessionHolderInterfaceMockRecorder) FindRetryCommittingGlobalTransactions(addressingIdentities interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FindRetryCommittingGlobalTransactions", reflect.TypeOf((*MockSessionHolderInterface)(nil).FindRetryCommittingGlobalTransactions), addressingIdentities) +} + +// FindRetryRollbackGlobalTransactions mocks base method. +func (m *MockSessionHolderInterface) FindRetryRollbackGlobalTransactions(addressingIdentities []string) []*model.GlobalTransaction { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "FindRetryRollbackGlobalTransactions", addressingIdentities) + ret0, _ := ret[0].([]*model.GlobalTransaction) + return ret0 +} + +// FindRetryRollbackGlobalTransactions indicates an expected call of FindRetryRollbackGlobalTransactions. +func (mr *MockSessionHolderInterfaceMockRecorder) FindRetryRollbackGlobalTransactions(addressingIdentities interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FindRetryRollbackGlobalTransactions", reflect.TypeOf((*MockSessionHolderInterface)(nil).FindRetryRollbackGlobalTransactions), addressingIdentities) +} + +// FindGlobalSessions mocks base method. +func (m *MockSessionHolderInterface) FindGlobalSessions(statuses []apis.GlobalSession_GlobalStatus) []*apis.GlobalSession { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "FindGlobalSessions", statuses) + ret0, _ := ret[0].([]*apis.GlobalSession) + return ret0 +} + +// FindGlobalSessions indicates an expected call of FindGlobalSessions. +func (mr *MockSessionHolderInterfaceMockRecorder) FindGlobalSessions(statuses interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FindGlobalSessions", reflect.TypeOf((*MockSessionHolderInterface)(nil).FindGlobalSessions), statuses) +} + +// AllSessions mocks base method. +func (m *MockSessionHolderInterface) AllSessions() []*apis.GlobalSession { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "AllSessions") + ret0, _ := ret[0].([]*apis.GlobalSession) + return ret0 +} + +// AllSessions indicates an expected call of AllSessions. +func (mr *MockSessionHolderInterfaceMockRecorder) AllSessions() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AllSessions", reflect.TypeOf((*MockSessionHolderInterface)(nil).AllSessions)) +} + +// UpdateGlobalSessionStatus mocks base method. +func (m *MockSessionHolderInterface) UpdateGlobalSessionStatus(session *apis.GlobalSession, status apis.GlobalSession_GlobalStatus) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "UpdateGlobalSessionStatus", session, status) + ret0, _ := ret[0].(error) + return ret0 +} + +// UpdateGlobalSessionStatus indicates an expected call of UpdateGlobalSessionStatus. +func (mr *MockSessionHolderInterfaceMockRecorder) UpdateGlobalSessionStatus(session, status interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateGlobalSessionStatus", reflect.TypeOf((*MockSessionHolderInterface)(nil).UpdateGlobalSessionStatus), session, status) +} + +// InactiveGlobalSession mocks base method. +func (m *MockSessionHolderInterface) InactiveGlobalSession(session *apis.GlobalSession) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "InactiveGlobalSession", session) + ret0, _ := ret[0].(error) + return ret0 +} + +// InactiveGlobalSession indicates an expected call of InactiveGlobalSession. +func (mr *MockSessionHolderInterfaceMockRecorder) InactiveGlobalSession(session interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "InactiveGlobalSession", reflect.TypeOf((*MockSessionHolderInterface)(nil).InactiveGlobalSession), session) +} + +// RemoveGlobalSession mocks base method. +func (m *MockSessionHolderInterface) RemoveGlobalSession(session *apis.GlobalSession) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "RemoveGlobalSession", session) + ret0, _ := ret[0].(error) + return ret0 +} + +// RemoveGlobalSession indicates an expected call of RemoveGlobalSession. +func (mr *MockSessionHolderInterfaceMockRecorder) RemoveGlobalSession(session interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RemoveGlobalSession", reflect.TypeOf((*MockSessionHolderInterface)(nil).RemoveGlobalSession), session) +} + +// RemoveGlobalTransaction mocks base method. +func (m *MockSessionHolderInterface) RemoveGlobalTransaction(globalTransaction *model.GlobalTransaction) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "RemoveGlobalTransaction", globalTransaction) + ret0, _ := ret[0].(error) + return ret0 +} + +// RemoveGlobalTransaction indicates an expected call of RemoveGlobalTransaction. +func (mr *MockSessionHolderInterfaceMockRecorder) RemoveGlobalTransaction(globalTransaction interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RemoveGlobalTransaction", reflect.TypeOf((*MockSessionHolderInterface)(nil).RemoveGlobalTransaction), globalTransaction) +} + +// AddBranchSession mocks base method. +func (m *MockSessionHolderInterface) AddBranchSession(globalSession *apis.GlobalSession, session *apis.BranchSession) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "AddBranchSession", globalSession, session) + ret0, _ := ret[0].(error) + return ret0 +} + +// AddBranchSession indicates an expected call of AddBranchSession. +func (mr *MockSessionHolderInterfaceMockRecorder) AddBranchSession(globalSession, session interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddBranchSession", reflect.TypeOf((*MockSessionHolderInterface)(nil).AddBranchSession), globalSession, session) +} + +// FindBranchSession mocks base method. +func (m *MockSessionHolderInterface) FindBranchSession(xid string) []*apis.BranchSession { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "FindBranchSession", xid) + ret0, _ := ret[0].([]*apis.BranchSession) + return ret0 +} + +// FindBranchSession indicates an expected call of FindBranchSession. +func (mr *MockSessionHolderInterfaceMockRecorder) FindBranchSession(xid interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FindBranchSession", reflect.TypeOf((*MockSessionHolderInterface)(nil).FindBranchSession), xid) +} + +// UpdateBranchSessionStatus mocks base method. +func (m *MockSessionHolderInterface) UpdateBranchSessionStatus(session *apis.BranchSession, status apis.BranchSession_BranchStatus) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "UpdateBranchSessionStatus", session, status) + ret0, _ := ret[0].(error) + return ret0 +} + +// UpdateBranchSessionStatus indicates an expected call of UpdateBranchSessionStatus. +func (mr *MockSessionHolderInterfaceMockRecorder) UpdateBranchSessionStatus(session, status interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateBranchSessionStatus", reflect.TypeOf((*MockSessionHolderInterface)(nil).UpdateBranchSessionStatus), session, status) +} + +// RemoveBranchSession mocks base method. +func (m *MockSessionHolderInterface) RemoveBranchSession(globalSession *apis.GlobalSession, session *apis.BranchSession) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "RemoveBranchSession", globalSession, session) + ret0, _ := ret[0].(error) + return ret0 +} + +// RemoveBranchSession indicates an expected call of RemoveBranchSession. +func (mr *MockSessionHolderInterfaceMockRecorder) RemoveBranchSession(globalSession, session interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RemoveBranchSession", reflect.TypeOf((*MockSessionHolderInterface)(nil).RemoveBranchSession), globalSession, session) +} + +// findGlobalTransactions mocks base method. +func (m *MockSessionHolderInterface) findGlobalTransactions(statuses []apis.GlobalSession_GlobalStatus) []*model.GlobalTransaction { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "findGlobalTransactions", statuses) + ret0, _ := ret[0].([]*model.GlobalTransaction) + return ret0 +} + +// findGlobalTransactions indicates an expected call of findGlobalTransactions. +func (mr *MockSessionHolderInterfaceMockRecorder) findGlobalTransactions(statuses interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "findGlobalTransactions", reflect.TypeOf((*MockSessionHolderInterface)(nil).findGlobalTransactions), statuses) +} + +// findGlobalTransactionsWithAddressingIdentities mocks base method. +func (m *MockSessionHolderInterface) findGlobalTransactionsWithAddressingIdentities(statuses []apis.GlobalSession_GlobalStatus, addressingIdentities []string) []*model.GlobalTransaction { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "findGlobalTransactionsWithAddressingIdentities", statuses, addressingIdentities) + ret0, _ := ret[0].([]*model.GlobalTransaction) + return ret0 +} + +// findGlobalTransactionsWithAddressingIdentities indicates an expected call of findGlobalTransactionsWithAddressingIdentities. +func (mr *MockSessionHolderInterfaceMockRecorder) findGlobalTransactionsWithAddressingIdentities(statuses, addressingIdentities interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "findGlobalTransactionsWithAddressingIdentities", reflect.TypeOf((*MockSessionHolderInterface)(nil).findGlobalTransactionsWithAddressingIdentities), statuses, addressingIdentities) +} + +// findGlobalTransactionsByGlobalSessions mocks base method. +func (m *MockSessionHolderInterface) findGlobalTransactionsByGlobalSessions(sessions []*apis.GlobalSession) []*model.GlobalTransaction { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "findGlobalTransactionsByGlobalSessions", sessions) + ret0, _ := ret[0].([]*model.GlobalTransaction) + return ret0 +} + +// findGlobalTransactionsByGlobalSessions indicates an expected call of findGlobalTransactionsByGlobalSessions. +func (mr *MockSessionHolderInterfaceMockRecorder) findGlobalTransactionsByGlobalSessions(sessions interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "findGlobalTransactionsByGlobalSessions", reflect.TypeOf((*MockSessionHolderInterface)(nil).findGlobalTransactionsByGlobalSessions), sessions) +} diff --git a/pkg/tc/holder/session_holder.go b/pkg/tc/holder/session_holder.go index a3dfe8002..af2c3085d 100644 --- a/pkg/tc/holder/session_holder.go +++ b/pkg/tc/holder/session_holder.go @@ -6,6 +6,25 @@ import ( "github.com/opentrx/seata-golang/v2/pkg/tc/storage" ) +type SessionHolderInterface interface { + AddGlobalSession(session *apis.GlobalSession) error + FindGlobalSession(xid string) *apis.GlobalSession + FindGlobalTransaction(xid string) *model.GlobalTransaction + FindAsyncCommittingGlobalTransactions(addressingIdentities []string) []*model.GlobalTransaction + FindRetryCommittingGlobalTransactions(addressingIdentities []string) []*model.GlobalTransaction + FindRetryRollbackGlobalTransactions(addressingIdentities []string) []*model.GlobalTransaction + FindGlobalSessions(statuses []apis.GlobalSession_GlobalStatus) []*apis.GlobalSession + AllSessions() []*apis.GlobalSession + UpdateGlobalSessionStatus(session *apis.GlobalSession, status apis.GlobalSession_GlobalStatus) error + InactiveGlobalSession(session *apis.GlobalSession) error + RemoveGlobalSession(session *apis.GlobalSession) error + RemoveGlobalTransaction(globalTransaction *model.GlobalTransaction) error + AddBranchSession(globalSession *apis.GlobalSession, session *apis.BranchSession) error + FindBranchSession(xid string) []*apis.BranchSession + UpdateBranchSessionStatus(session *apis.BranchSession, status apis.BranchSession_BranchStatus) error + RemoveBranchSession(globalSession *apis.GlobalSession, session *apis.BranchSession) error +} + type SessionHolder struct { manager storage.SessionManager } diff --git a/pkg/tc/lock/lock_manager.go b/pkg/tc/lock/lock_manager.go index cfcf38a6a..1b2f05b41 100644 --- a/pkg/tc/lock/lock_manager.go +++ b/pkg/tc/lock/lock_manager.go @@ -2,7 +2,7 @@ package lock import ( "encoding/json" - + "github.com/opentrx/seata-golang/v2/pkg/apis" "github.com/opentrx/seata-golang/v2/pkg/tc/model" "github.com/opentrx/seata-golang/v2/pkg/tc/storage" diff --git a/pkg/tc/server/transaction_coordinator.go b/pkg/tc/server/transaction_coordinator.go index dcceadceb..65f9404fb 100644 --- a/pkg/tc/server/transaction_coordinator.go +++ b/pkg/tc/server/transaction_coordinator.go @@ -45,7 +45,7 @@ type TransactionCoordinator struct { streamMessageTimeout time.Duration - holder *holder.SessionHolder + holder holder.SessionHolderInterface resourceDataLocker *lock.LockManager locker GlobalSessionLocker diff --git a/pkg/tc/server/transaction_coordinator_test.go b/pkg/tc/server/transaction_coordinator_test.go new file mode 100644 index 000000000..fd630701e --- /dev/null +++ b/pkg/tc/server/transaction_coordinator_test.go @@ -0,0 +1,91 @@ +package server + +import ( + "context" + "testing" + + "github.com/golang/mock/gomock" + "github.com/opentrx/seata-golang/v2/pkg/apis" + hmock "github.com/opentrx/seata-golang/v2/pkg/tc/holder/mock" + "github.com/stretchr/testify/assert" +) + +func TestTransactionCoordinator_GetStatus(t *testing.T) { + xid := "localhost:123" + tests := []struct { + name string + transactionCoordinator func(ctrl *gomock.Controller) *TransactionCoordinator + ctx context.Context + request *apis.GlobalStatusRequest + expectedResult *apis.GlobalStatusResponse + expectedErr error + }{ + { + name: "test GetStatus with existing XID", + transactionCoordinator: func(ctrl *gomock.Controller) *TransactionCoordinator { + transactionCoordinator := &TransactionCoordinator{} + mockedSessionHolder := hmock.NewMockSessionHolderInterface(ctrl) + + mockedSessionHolder. + EXPECT(). + FindGlobalSession(xid). + Return(&apis.GlobalSession{ + Status: apis.Begin, + }) + + transactionCoordinator.holder = mockedSessionHolder + + return transactionCoordinator + }, + ctx: nil, + request: &apis.GlobalStatusRequest{ + XID: "localhost:123", + }, + expectedResult: &apis.GlobalStatusResponse{ + ResultCode: apis.ResultCodeSuccess, + GlobalStatus: apis.Begin, + }, + expectedErr: nil, + }, + { + name: "test GetStatus with empty XID", + transactionCoordinator: func(ctrl *gomock.Controller) *TransactionCoordinator { + transactionCoordinator := &TransactionCoordinator{} + mockedSessionHolder := hmock.NewMockSessionHolderInterface(ctrl) + + mockedSessionHolder. + EXPECT(). + FindGlobalSession(""). + Return(&apis.GlobalSession{ + Status: apis.Finished, + }) + + transactionCoordinator.holder = mockedSessionHolder + + return transactionCoordinator + }, + ctx: nil, + request: &apis.GlobalStatusRequest{ + XID: "", + }, + expectedResult: &apis.GlobalStatusResponse{ + ResultCode: apis.ResultCodeSuccess, + GlobalStatus: apis.Finished, + }, + expectedErr: nil, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + tc := tt.transactionCoordinator(ctrl) + + actualResp, actualErr := tc.GetStatus(tt.ctx, tt.request) + assert.Equal(t, tt.expectedResult, actualResp) + assert.Equal(t, tt.expectedErr, actualErr) + }) + } +} From 44b0f3e0efc39de0d80e55bf1c58d3ed3fdb6e8d Mon Sep 17 00:00:00 2001 From: bohehe Date: Wed, 23 Feb 2022 21:49:55 +0800 Subject: [PATCH 02/13] update readme --- README.md | 14 +++++++------- docs/README_ZH.md | 14 +++++++------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index 49a8bf757..e9a68ac9e 100644 --- a/README.md +++ b/README.md @@ -4,13 +4,13 @@ ## Introduction | [中文](https://github.com/opentrx/seata-golang/blob/v2/docs/README_ZH.md) seata-golang is a distributed transaction middleware based on Golang. ### difference between seata-glang and [seata](https://github.com/seata/seata) -| feature | seata | seata-golang | remark | - | ---- | :----: | :----: | --- | -| AT mode | √ | √ | | -| TCC mode | √ | √ | | -| SAGA mode | √ | × | | -| rpc | √ | √ | [dev branch](https://github.com/opentrx/seata-golang/tree/dev) | -| grpc | × | √ | [v2 branch](https://github.com/opentrx/seata-golang/tree/v2) | +| feature | seata | seata-golang | remark | +|-----------|:-----:|:------------:|----------------------------------------------------------------| +| AT mode | ✅ | ✅ | | +| TCC mode | ✅ | ✅ | | +| SAGA mode | ✅ | ☑️ | | +| rpc | ✅ | ✅ | [dev branch](https://github.com/opentrx/seata-golang/tree/dev) | +| grpc | ☑️ | ✅ | [v2 branch](https://github.com/opentrx/seata-golang/tree/v2) | ## Architecture seata-flow diff --git a/docs/README_ZH.md b/docs/README_ZH.md index 5e5887128..8b126f7dd 100644 --- a/docs/README_ZH.md +++ b/docs/README_ZH.md @@ -4,13 +4,13 @@ ## 简介 | [English](https://github.com/opentrx/seata-golang/blob/v2/README.md) seata-golang是一个用于解决分布式事务的中间件,是基于Go语言版本的seata。 ### seata-golang与[seata](https://github.com/seata/seata) 的区别 -| 特性 | seata | seata-golang | 备注 | - | ---- | :----: | :----: | --- | -| AT mode | √ | √ | | -| TCC mode | √ | √ | | -| SAGA mode | √ | × | | -| rpc | √ | √ | [dev branch](https://github.com/opentrx/seata-golang/tree/dev) | -| grpc | × | √ | [v2 branch](https://github.com/opentrx/seata-golang/tree/v2) | +| 特性 | seata | seata-golang | 备注 | +|-----------|:-----:|:------------:|----------------------------------------------------------------| +| AT mode | ✅ | ✅ | | +| TCC mode | ✅ | ✅ | | +| SAGA mode | ✅ | ☑️ | | +| rpc | ✅ | ✅ | [dev branch](https://github.com/opentrx/seata-golang/tree/dev) | +| grpc | ☑️ | ✅ | [v2 branch](https://github.com/opentrx/seata-golang/tree/v2) | ## 架构 seata-flow From 8c7a74618d4befd5b97b592cf829dc148981a3b2 Mon Sep 17 00:00:00 2001 From: bohehe Date: Wed, 23 Feb 2022 22:01:49 +0800 Subject: [PATCH 03/13] add TestTransactionCoordinator_BranchReport --- pkg/tc/server/transaction_coordinator_test.go | 56 +++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/pkg/tc/server/transaction_coordinator_test.go b/pkg/tc/server/transaction_coordinator_test.go index fd630701e..7cf4cd9cb 100644 --- a/pkg/tc/server/transaction_coordinator_test.go +++ b/pkg/tc/server/transaction_coordinator_test.go @@ -2,6 +2,7 @@ package server import ( "context" + "fmt" "testing" "github.com/golang/mock/gomock" @@ -89,3 +90,58 @@ func TestTransactionCoordinator_GetStatus(t *testing.T) { }) } } + +func TestTransactionCoordinator_BranchReport(t *testing.T) { + //xid := "localhost:123" + tests := []struct { + name string + transactionCoordinator func(ctrl *gomock.Controller) *TransactionCoordinator + ctx context.Context + request *apis.BranchReportRequest + expectedResult *apis.BranchReportResponse + expectedErr error + }{ + { + name: "test BranchReport with empty XID", + transactionCoordinator: func(ctrl *gomock.Controller) *TransactionCoordinator { + transactionCoordinator := &TransactionCoordinator{} + mockedSessionHolder := hmock.NewMockSessionHolderInterface(ctrl) + + mockedSessionHolder. + EXPECT(). + FindGlobalTransaction(""). + Return(nil) + + transactionCoordinator.holder = mockedSessionHolder + + return transactionCoordinator + }, + ctx: nil, + request: &apis.BranchReportRequest{ + XID: "", + }, + expectedResult: &apis.BranchReportResponse{ + ResultCode: apis.ResultCodeFailed, + ExceptionCode: apis.GlobalTransactionNotExist, + Message: fmt.Sprintf("could not find global transaction xid = %s", ""), + }, + expectedErr: nil, + }, + // todo: test BranchReport with empty branch + // todo: test BranchReport with update branch status error + // todo: test BranchReport success + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + tc := tt.transactionCoordinator(ctrl) + + actualResp, actualErr := tc.BranchReport(tt.ctx, tt.request) + assert.Equal(t, tt.expectedResult, actualResp) + assert.Equal(t, tt.expectedErr, actualErr) + }) + } +} From 74103aa055a1f966c19da93c06ff01671712e18d Mon Sep 17 00:00:00 2001 From: bohehe Date: Thu, 24 Feb 2022 21:44:00 +0800 Subject: [PATCH 04/13] test BranchReport with empty Branch --- pkg/tc/server/transaction_coordinator_test.go | 45 ++++++++++++++++--- 1 file changed, 39 insertions(+), 6 deletions(-) diff --git a/pkg/tc/server/transaction_coordinator_test.go b/pkg/tc/server/transaction_coordinator_test.go index 7cf4cd9cb..37e4eee61 100644 --- a/pkg/tc/server/transaction_coordinator_test.go +++ b/pkg/tc/server/transaction_coordinator_test.go @@ -8,6 +8,7 @@ import ( "github.com/golang/mock/gomock" "github.com/opentrx/seata-golang/v2/pkg/apis" hmock "github.com/opentrx/seata-golang/v2/pkg/tc/holder/mock" + "github.com/opentrx/seata-golang/v2/pkg/tc/model" "github.com/stretchr/testify/assert" ) @@ -92,7 +93,8 @@ func TestTransactionCoordinator_GetStatus(t *testing.T) { } func TestTransactionCoordinator_BranchReport(t *testing.T) { - //xid := "localhost:123" + xid := "localhost:123" + branchID := int64(1) tests := []struct { name string transactionCoordinator func(ctrl *gomock.Controller) *TransactionCoordinator @@ -107,10 +109,7 @@ func TestTransactionCoordinator_BranchReport(t *testing.T) { transactionCoordinator := &TransactionCoordinator{} mockedSessionHolder := hmock.NewMockSessionHolderInterface(ctrl) - mockedSessionHolder. - EXPECT(). - FindGlobalTransaction(""). - Return(nil) + mockedSessionHolder.EXPECT().FindGlobalTransaction("").Return(nil) transactionCoordinator.holder = mockedSessionHolder @@ -127,7 +126,41 @@ func TestTransactionCoordinator_BranchReport(t *testing.T) { }, expectedErr: nil, }, - // todo: test BranchReport with empty branch + { + name: "test BranchReport with empty Branch", + transactionCoordinator: func(ctrl *gomock.Controller) *TransactionCoordinator { + transactionCoordinator := &TransactionCoordinator{} + mockedSessionHolder := hmock.NewMockSessionHolderInterface(ctrl) + + mockedBranchSession := &apis.BranchSession{ + BranchID: branchID + 1, + } + mockedGlobalTransaction := &model.GlobalTransaction{ + GlobalSession: &apis.GlobalSession{ + XID: xid, + }, + BranchSessions: map[*apis.BranchSession]bool{ + mockedBranchSession: true, + }, + } + mockedSessionHolder.EXPECT().FindGlobalTransaction(xid).Return(mockedGlobalTransaction) + + transactionCoordinator.holder = mockedSessionHolder + + return transactionCoordinator + }, + ctx: nil, + request: &apis.BranchReportRequest{ + XID: xid, + BranchID: branchID, + }, + expectedResult: &apis.BranchReportResponse{ + ResultCode: apis.ResultCodeFailed, + ExceptionCode: apis.BranchTransactionNotExist, + Message: fmt.Sprintf("could not find branch session xid = %s branchID = %d", xid, branchID), + }, + expectedErr: nil, + }, // todo: test BranchReport with update branch status error // todo: test BranchReport success } From 75c0c0ae10188c70eda17f6168ffde9c849dd769 Mon Sep 17 00:00:00 2001 From: bohehe Date: Thu, 24 Feb 2022 21:56:15 +0800 Subject: [PATCH 05/13] test BranchReport with update branch status error test BranchReport success --- pkg/tc/server/transaction_coordinator_test.go | 77 ++++++++++++++++++- 1 file changed, 75 insertions(+), 2 deletions(-) diff --git a/pkg/tc/server/transaction_coordinator_test.go b/pkg/tc/server/transaction_coordinator_test.go index 37e4eee61..89ab1cb03 100644 --- a/pkg/tc/server/transaction_coordinator_test.go +++ b/pkg/tc/server/transaction_coordinator_test.go @@ -95,6 +95,7 @@ func TestTransactionCoordinator_GetStatus(t *testing.T) { func TestTransactionCoordinator_BranchReport(t *testing.T) { xid := "localhost:123" branchID := int64(1) + updateBranchSessionErr := fmt.Errorf("test error") tests := []struct { name string transactionCoordinator func(ctrl *gomock.Controller) *TransactionCoordinator @@ -161,8 +162,80 @@ func TestTransactionCoordinator_BranchReport(t *testing.T) { }, expectedErr: nil, }, - // todo: test BranchReport with update branch status error - // todo: test BranchReport success + { + name: "test BranchReport with update branch status error", + transactionCoordinator: func(ctrl *gomock.Controller) *TransactionCoordinator { + transactionCoordinator := &TransactionCoordinator{} + mockedSessionHolder := hmock.NewMockSessionHolderInterface(ctrl) + + mockedBranchSession := &apis.BranchSession{ + BranchID: branchID, + } + mockedGlobalTransaction := &model.GlobalTransaction{ + GlobalSession: &apis.GlobalSession{ + XID: xid, + }, + BranchSessions: map[*apis.BranchSession]bool{ + mockedBranchSession: true, + }, + } + + mockedSessionHolder.EXPECT().FindGlobalTransaction(xid).Return(mockedGlobalTransaction) + mockedSessionHolder.EXPECT().UpdateBranchSessionStatus(mockedBranchSession, apis.Registered).Return(updateBranchSessionErr) + + transactionCoordinator.holder = mockedSessionHolder + + return transactionCoordinator + }, + ctx: nil, + request: &apis.BranchReportRequest{ + XID: xid, + BranchID: branchID, + BranchStatus: apis.Registered, + }, + expectedResult: &apis.BranchReportResponse{ + ResultCode: apis.ResultCodeFailed, + ExceptionCode: apis.BranchReportFailed, + Message: fmt.Sprintf("branch report failed, xid = %s, branchID = %d, err: %s", xid, branchID, updateBranchSessionErr.Error()), + }, + expectedErr: nil, + }, + { + name: "test BranchReport success", + transactionCoordinator: func(ctrl *gomock.Controller) *TransactionCoordinator { + transactionCoordinator := &TransactionCoordinator{} + mockedSessionHolder := hmock.NewMockSessionHolderInterface(ctrl) + + mockedBranchSession := &apis.BranchSession{ + BranchID: branchID, + } + mockedGlobalTransaction := &model.GlobalTransaction{ + GlobalSession: &apis.GlobalSession{ + XID: xid, + }, + BranchSessions: map[*apis.BranchSession]bool{ + mockedBranchSession: true, + }, + } + + mockedSessionHolder.EXPECT().FindGlobalTransaction(xid).Return(mockedGlobalTransaction) + mockedSessionHolder.EXPECT().UpdateBranchSessionStatus(mockedBranchSession, apis.Registered).Return(nil) + + transactionCoordinator.holder = mockedSessionHolder + + return transactionCoordinator + }, + ctx: nil, + request: &apis.BranchReportRequest{ + XID: xid, + BranchID: branchID, + BranchStatus: apis.Registered, + }, + expectedResult: &apis.BranchReportResponse{ + ResultCode: apis.ResultCodeSuccess, + }, + expectedErr: nil, + }, } for _, tt := range tests { From 61cd0c168fff751d710c992d2c2ab7bf414c4f68 Mon Sep 17 00:00:00 2001 From: bohehe Date: Thu, 24 Feb 2022 22:03:01 +0800 Subject: [PATCH 06/13] add todo list --- pkg/tc/server/transaction_coordinator_test.go | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/pkg/tc/server/transaction_coordinator_test.go b/pkg/tc/server/transaction_coordinator_test.go index 89ab1cb03..9d8320a9a 100644 --- a/pkg/tc/server/transaction_coordinator_test.go +++ b/pkg/tc/server/transaction_coordinator_test.go @@ -251,3 +251,23 @@ func TestTransactionCoordinator_BranchReport(t *testing.T) { }) } } + +func TestTransactionCoordinator_Begin(t *testing.T) { + // todo +} + +func TestTransactionCoordinator_BranchRegister(t *testing.T) { + // todo +} + +func TestTransactionCoordinator_Commit(t *testing.T) { + // todo +} + +func TestTransactionCoordinator_Rollback(t *testing.T) { + // todo +} + +func TestTransactionCoordinator_LockQuery(t *testing.T) { + // todo +} From baf249ad78172e2f8d3bba1e5ba55f3cd4a02611 Mon Sep 17 00:00:00 2001 From: bohehe Date: Thu, 24 Feb 2022 22:19:16 +0800 Subject: [PATCH 07/13] test LockQuery --- pkg/tc/lock/lock_manager.go | 7 ++ pkg/tc/lock/mock/lock_manager.go | 92 +++++++++++++++++++ pkg/tc/server/transaction_coordinator.go | 2 +- pkg/tc/server/transaction_coordinator_test.go | 57 +++++++++++- 4 files changed, 153 insertions(+), 5 deletions(-) create mode 100644 pkg/tc/lock/mock/lock_manager.go diff --git a/pkg/tc/lock/lock_manager.go b/pkg/tc/lock/lock_manager.go index 1b2f05b41..7babeeac9 100644 --- a/pkg/tc/lock/lock_manager.go +++ b/pkg/tc/lock/lock_manager.go @@ -9,6 +9,13 @@ import ( "github.com/opentrx/seata-golang/v2/pkg/util/log" ) +type LockManagerInterface interface { + AcquireLock(branchSession *apis.BranchSession) bool + ReleaseLock(branchSession *apis.BranchSession) bool + ReleaseGlobalSessionLock(globalTransaction *model.GlobalTransaction) bool + IsLockable(xid string, resourceID string, lockKey string) bool +} + type LockManager struct { manager storage.LockManager } diff --git a/pkg/tc/lock/mock/lock_manager.go b/pkg/tc/lock/mock/lock_manager.go new file mode 100644 index 000000000..043736a14 --- /dev/null +++ b/pkg/tc/lock/mock/lock_manager.go @@ -0,0 +1,92 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: pkg/tc/lock/lock_manager.go + +// Package mock_lock is a generated GoMock package. +package mock_lock + +import ( + reflect "reflect" + + gomock "github.com/golang/mock/gomock" + apis "github.com/opentrx/seata-golang/v2/pkg/apis" + model "github.com/opentrx/seata-golang/v2/pkg/tc/model" +) + +// MockLockManagerInterface is a mock of LockManagerInterface interface. +type MockLockManagerInterface struct { + ctrl *gomock.Controller + recorder *MockLockManagerInterfaceMockRecorder +} + +// MockLockManagerInterfaceMockRecorder is the mock recorder for MockLockManagerInterface. +type MockLockManagerInterfaceMockRecorder struct { + mock *MockLockManagerInterface +} + +// NewMockLockManagerInterface creates a new mock instance. +func NewMockLockManagerInterface(ctrl *gomock.Controller) *MockLockManagerInterface { + mock := &MockLockManagerInterface{ctrl: ctrl} + mock.recorder = &MockLockManagerInterfaceMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockLockManagerInterface) EXPECT() *MockLockManagerInterfaceMockRecorder { + return m.recorder +} + +// AcquireLock mocks base method. +func (m *MockLockManagerInterface) AcquireLock(branchSession *apis.BranchSession) bool { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "AcquireLock", branchSession) + ret0, _ := ret[0].(bool) + return ret0 +} + +// AcquireLock indicates an expected call of AcquireLock. +func (mr *MockLockManagerInterfaceMockRecorder) AcquireLock(branchSession interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AcquireLock", reflect.TypeOf((*MockLockManagerInterface)(nil).AcquireLock), branchSession) +} + +// ReleaseLock mocks base method. +func (m *MockLockManagerInterface) ReleaseLock(branchSession *apis.BranchSession) bool { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ReleaseLock", branchSession) + ret0, _ := ret[0].(bool) + return ret0 +} + +// ReleaseLock indicates an expected call of ReleaseLock. +func (mr *MockLockManagerInterfaceMockRecorder) ReleaseLock(branchSession interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReleaseLock", reflect.TypeOf((*MockLockManagerInterface)(nil).ReleaseLock), branchSession) +} + +// ReleaseGlobalSessionLock mocks base method. +func (m *MockLockManagerInterface) ReleaseGlobalSessionLock(globalTransaction *model.GlobalTransaction) bool { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ReleaseGlobalSessionLock", globalTransaction) + ret0, _ := ret[0].(bool) + return ret0 +} + +// ReleaseGlobalSessionLock indicates an expected call of ReleaseGlobalSessionLock. +func (mr *MockLockManagerInterfaceMockRecorder) ReleaseGlobalSessionLock(globalTransaction interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReleaseGlobalSessionLock", reflect.TypeOf((*MockLockManagerInterface)(nil).ReleaseGlobalSessionLock), globalTransaction) +} + +// IsLockable mocks base method. +func (m *MockLockManagerInterface) IsLockable(xid, resourceID, lockKey string) bool { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "IsLockable", xid, resourceID, lockKey) + ret0, _ := ret[0].(bool) + return ret0 +} + +// IsLockable indicates an expected call of IsLockable. +func (mr *MockLockManagerInterfaceMockRecorder) IsLockable(xid, resourceID, lockKey interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IsLockable", reflect.TypeOf((*MockLockManagerInterface)(nil).IsLockable), xid, resourceID, lockKey) +} diff --git a/pkg/tc/server/transaction_coordinator.go b/pkg/tc/server/transaction_coordinator.go index 65f9404fb..7c5d94d61 100644 --- a/pkg/tc/server/transaction_coordinator.go +++ b/pkg/tc/server/transaction_coordinator.go @@ -46,7 +46,7 @@ type TransactionCoordinator struct { streamMessageTimeout time.Duration holder holder.SessionHolderInterface - resourceDataLocker *lock.LockManager + resourceDataLocker lock.LockManagerInterface locker GlobalSessionLocker idGenerator *atomic.Uint64 diff --git a/pkg/tc/server/transaction_coordinator_test.go b/pkg/tc/server/transaction_coordinator_test.go index 9d8320a9a..bdee06161 100644 --- a/pkg/tc/server/transaction_coordinator_test.go +++ b/pkg/tc/server/transaction_coordinator_test.go @@ -8,6 +8,7 @@ import ( "github.com/golang/mock/gomock" "github.com/opentrx/seata-golang/v2/pkg/apis" hmock "github.com/opentrx/seata-golang/v2/pkg/tc/holder/mock" + mocklock "github.com/opentrx/seata-golang/v2/pkg/tc/lock/mock" "github.com/opentrx/seata-golang/v2/pkg/tc/model" "github.com/stretchr/testify/assert" ) @@ -252,6 +253,58 @@ func TestTransactionCoordinator_BranchReport(t *testing.T) { } } +func TestTransactionCoordinator_LockQuery(t *testing.T) { + xid := "localhost:123" + resourceID := "test" + lockKey := "table_name:pk1,pk2" + tests := []struct { + name string + transactionCoordinator func(ctrl *gomock.Controller) *TransactionCoordinator + ctx context.Context + request *apis.GlobalLockQueryRequest + expectedResult *apis.GlobalLockQueryResponse + expectedErr error + }{ + { + name: "test LockQuery success", + transactionCoordinator: func(ctrl *gomock.Controller) *TransactionCoordinator { + transactionCoordinator := &TransactionCoordinator{} + mockedLockManager := mocklock.NewMockLockManagerInterface(ctrl) + + mockedLockManager.EXPECT().IsLockable(xid, resourceID, lockKey).Return(true) + + transactionCoordinator.resourceDataLocker = mockedLockManager + + return transactionCoordinator + }, + ctx: nil, + request: &apis.GlobalLockQueryRequest{ + XID: xid, + ResourceID: resourceID, + LockKey: lockKey, + }, + expectedResult: &apis.GlobalLockQueryResponse{ + ResultCode: apis.ResultCodeSuccess, + Lockable: true, + }, + expectedErr: nil, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + tc := tt.transactionCoordinator(ctrl) + + actualResp, actualErr := tc.LockQuery(tt.ctx, tt.request) + assert.Equal(t, tt.expectedResult, actualResp) + assert.Equal(t, tt.expectedErr, actualErr) + }) + } +} + func TestTransactionCoordinator_Begin(t *testing.T) { // todo } @@ -267,7 +320,3 @@ func TestTransactionCoordinator_Commit(t *testing.T) { func TestTransactionCoordinator_Rollback(t *testing.T) { // todo } - -func TestTransactionCoordinator_LockQuery(t *testing.T) { - // todo -} From 9d349afc575800202bb14b9359676777faaa3d9e Mon Sep 17 00:00:00 2001 From: bohehe Date: Sun, 27 Feb 2022 11:20:39 +0800 Subject: [PATCH 08/13] TestTransactionCoordinator_Begin --- pkg/tc/server/transaction_coordinator_test.go | 79 ++++++++++++++++++- 1 file changed, 78 insertions(+), 1 deletion(-) diff --git a/pkg/tc/server/transaction_coordinator_test.go b/pkg/tc/server/transaction_coordinator_test.go index bdee06161..c92b98217 100644 --- a/pkg/tc/server/transaction_coordinator_test.go +++ b/pkg/tc/server/transaction_coordinator_test.go @@ -306,7 +306,84 @@ func TestTransactionCoordinator_LockQuery(t *testing.T) { } func TestTransactionCoordinator_Begin(t *testing.T) { - // todo + addGlobalSessionHolderErr := fmt.Errorf("error add global session") + tests := []struct { + name string + transactionCoordinator func(ctrl *gomock.Controller) *TransactionCoordinator + ctx context.Context + request *apis.GlobalBeginRequest + expectedResult *apis.GlobalBeginResponse + expectedErr error + }{ + { + name: "test Begin error add global session", + transactionCoordinator: func(ctrl *gomock.Controller) *TransactionCoordinator { + transactionCoordinator := &TransactionCoordinator{} + mockedSessionHolder := hmock.NewMockSessionHolderInterface(ctrl) + + mockedSessionHolder.EXPECT().AddGlobalSession(gomock.Any()).Return(addGlobalSessionHolderErr) + + transactionCoordinator.holder = mockedSessionHolder + + return transactionCoordinator + }, + ctx: nil, + request: &apis.GlobalBeginRequest{ + Addressing: "localhost", + TransactionName: "TestTransaction", + Timeout: int32(3), + }, + expectedResult: &apis.GlobalBeginResponse{ + ResultCode: apis.ResultCodeFailed, + ExceptionCode: apis.BeginFailed, + Message: addGlobalSessionHolderErr.Error(), + }, + expectedErr: nil, + }, + { + name: "test Begin success", + transactionCoordinator: func(ctrl *gomock.Controller) *TransactionCoordinator { + transactionCoordinator := &TransactionCoordinator{} + mockedSessionHolder := hmock.NewMockSessionHolderInterface(ctrl) + + mockedSessionHolder.EXPECT().AddGlobalSession(gomock.Any()).Return(nil) + + transactionCoordinator.holder = mockedSessionHolder + + return transactionCoordinator + }, + ctx: nil, + request: &apis.GlobalBeginRequest{ + Addressing: "localhost", + TransactionName: "TestTransaction", + Timeout: int32(3), + }, + expectedResult: &apis.GlobalBeginResponse{ + ResultCode: apis.ResultCodeSuccess, + //XID: xid, + }, + expectedErr: nil, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + tc := tt.transactionCoordinator(ctrl) + + actualResp, actualErr := tc.Begin(tt.ctx, tt.request) + if tt.name == "test Begin success" { + // in case XID unable to mock + assert.Equal(t, tt.expectedResult.ResultCode, actualResp.ResultCode) + assert.Equal(t, tt.expectedErr, actualErr) + } else { + assert.Equal(t, tt.expectedResult, actualResp) + assert.Equal(t, tt.expectedErr, actualErr) + } + }) + } } func TestTransactionCoordinator_BranchRegister(t *testing.T) { From 65b7593d2f2c7f96c60577bf787fbf57d2a410b5 Mon Sep 17 00:00:00 2001 From: bohehe Date: Sun, 27 Feb 2022 13:03:49 +0800 Subject: [PATCH 09/13] TestTransactionCoordinator_BranchRegister --- pkg/tc/server/mock/global_session_locker.go | 63 +++ pkg/tc/server/transaction_coordinator.go | 2 +- pkg/tc/server/transaction_coordinator_test.go | 394 +++++++++++++++++- 3 files changed, 452 insertions(+), 7 deletions(-) create mode 100644 pkg/tc/server/mock/global_session_locker.go diff --git a/pkg/tc/server/mock/global_session_locker.go b/pkg/tc/server/mock/global_session_locker.go new file mode 100644 index 000000000..fe7940acd --- /dev/null +++ b/pkg/tc/server/mock/global_session_locker.go @@ -0,0 +1,63 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: pkg/tc/server/global_session_locker.go + +// Package mock_server is a generated GoMock package. +package mock_server + +import ( + reflect "reflect" + time "time" + + gomock "github.com/golang/mock/gomock" + apis "github.com/opentrx/seata-golang/v2/pkg/apis" +) + +// MockGlobalSessionLocker is a mock of GlobalSessionLocker interface. +type MockGlobalSessionLocker struct { + ctrl *gomock.Controller + recorder *MockGlobalSessionLockerMockRecorder +} + +// MockGlobalSessionLockerMockRecorder is the mock recorder for MockGlobalSessionLocker. +type MockGlobalSessionLockerMockRecorder struct { + mock *MockGlobalSessionLocker +} + +// NewMockGlobalSessionLocker creates a new mock instance. +func NewMockGlobalSessionLocker(ctrl *gomock.Controller) *MockGlobalSessionLocker { + mock := &MockGlobalSessionLocker{ctrl: ctrl} + mock.recorder = &MockGlobalSessionLockerMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockGlobalSessionLocker) EXPECT() *MockGlobalSessionLockerMockRecorder { + return m.recorder +} + +// TryLock mocks base method. +func (m *MockGlobalSessionLocker) TryLock(session *apis.GlobalSession, timeout time.Duration) (bool, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "TryLock", session, timeout) + ret0, _ := ret[0].(bool) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// TryLock indicates an expected call of TryLock. +func (mr *MockGlobalSessionLockerMockRecorder) TryLock(session, timeout interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "TryLock", reflect.TypeOf((*MockGlobalSessionLocker)(nil).TryLock), session, timeout) +} + +// Unlock mocks base method. +func (m *MockGlobalSessionLocker) Unlock(session *apis.GlobalSession) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "Unlock", session) +} + +// Unlock indicates an expected call of Unlock. +func (mr *MockGlobalSessionLockerMockRecorder) Unlock(session interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Unlock", reflect.TypeOf((*MockGlobalSessionLocker)(nil).Unlock), session) +} diff --git a/pkg/tc/server/transaction_coordinator.go b/pkg/tc/server/transaction_coordinator.go index 7c5d94d61..51dfdfbdd 100644 --- a/pkg/tc/server/transaction_coordinator.go +++ b/pkg/tc/server/transaction_coordinator.go @@ -722,7 +722,7 @@ func (tc *TransactionCoordinator) BranchRegister(ctx context.Context, request *a return &apis.BranchRegisterResponse{ ResultCode: apis.ResultCodeFailed, ExceptionCode: apis.FailedLockGlobalTransaction, - Message: fmt.Sprintf("could not find global transaction xid = %s", request.XID), + Message: fmt.Sprintf("could not lock global transaction xid = %s", request.XID), }, nil } if result { diff --git a/pkg/tc/server/transaction_coordinator_test.go b/pkg/tc/server/transaction_coordinator_test.go index c92b98217..ed52ddbf7 100644 --- a/pkg/tc/server/transaction_coordinator_test.go +++ b/pkg/tc/server/transaction_coordinator_test.go @@ -4,12 +4,14 @@ import ( "context" "fmt" "testing" + "time" "github.com/golang/mock/gomock" "github.com/opentrx/seata-golang/v2/pkg/apis" hmock "github.com/opentrx/seata-golang/v2/pkg/tc/holder/mock" mocklock "github.com/opentrx/seata-golang/v2/pkg/tc/lock/mock" "github.com/opentrx/seata-golang/v2/pkg/tc/model" + mock_server "github.com/opentrx/seata-golang/v2/pkg/tc/server/mock" "github.com/stretchr/testify/assert" ) @@ -24,7 +26,7 @@ func TestTransactionCoordinator_GetStatus(t *testing.T) { expectedErr error }{ { - name: "test GetStatus with existing XID", + name: "test GetStatus success", transactionCoordinator: func(ctrl *gomock.Controller) *TransactionCoordinator { transactionCoordinator := &TransactionCoordinator{} mockedSessionHolder := hmock.NewMockSessionHolderInterface(ctrl) @@ -164,7 +166,7 @@ func TestTransactionCoordinator_BranchReport(t *testing.T) { expectedErr: nil, }, { - name: "test BranchReport with update branch status error", + name: "test BranchReport error update branch status ", transactionCoordinator: func(ctrl *gomock.Controller) *TransactionCoordinator { transactionCoordinator := &TransactionCoordinator{} mockedSessionHolder := hmock.NewMockSessionHolderInterface(ctrl) @@ -256,7 +258,7 @@ func TestTransactionCoordinator_BranchReport(t *testing.T) { func TestTransactionCoordinator_LockQuery(t *testing.T) { xid := "localhost:123" resourceID := "test" - lockKey := "table_name:pk1,pk2" + lockKey := "test_table:pk1,pk2" tests := []struct { name string transactionCoordinator func(ctrl *gomock.Controller) *TransactionCoordinator @@ -331,7 +333,7 @@ func TestTransactionCoordinator_Begin(t *testing.T) { request: &apis.GlobalBeginRequest{ Addressing: "localhost", TransactionName: "TestTransaction", - Timeout: int32(3), + Timeout: int32(300), }, expectedResult: &apis.GlobalBeginResponse{ ResultCode: apis.ResultCodeFailed, @@ -356,7 +358,7 @@ func TestTransactionCoordinator_Begin(t *testing.T) { request: &apis.GlobalBeginRequest{ Addressing: "localhost", TransactionName: "TestTransaction", - Timeout: int32(3), + Timeout: int32(300), }, expectedResult: &apis.GlobalBeginResponse{ ResultCode: apis.ResultCodeSuccess, @@ -387,7 +389,387 @@ func TestTransactionCoordinator_Begin(t *testing.T) { } func TestTransactionCoordinator_BranchRegister(t *testing.T) { - // todo + xid := "localhost:123" + resourceID := "test_DB" + lockKey := "test_table:pk1,pk2" + addBranchSessionErr := fmt.Errorf("error add branch session") + tests := []struct { + name string + transactionCoordinator func(ctrl *gomock.Controller) *TransactionCoordinator + ctx context.Context + request *apis.BranchRegisterRequest + expectedResult *apis.BranchRegisterResponse + expectedErr error + }{ + { + name: "test BranchRegister with empty XID", + transactionCoordinator: func(ctrl *gomock.Controller) *TransactionCoordinator { + transactionCoordinator := &TransactionCoordinator{} + mockedSessionHolder := hmock.NewMockSessionHolderInterface(ctrl) + + mockedSessionHolder. + EXPECT(). + FindGlobalTransaction(""). + Return(nil) + + transactionCoordinator.holder = mockedSessionHolder + + return transactionCoordinator + }, + ctx: nil, + request: &apis.BranchRegisterRequest{ + XID: "", + }, + expectedResult: &apis.BranchRegisterResponse{ + ResultCode: apis.ResultCodeFailed, + ExceptionCode: apis.GlobalTransactionNotExist, + Message: fmt.Sprintf("could not find global transaction xid = %s", ""), + }, + expectedErr: nil, + }, + { + name: "test BranchRegister error try lock", + transactionCoordinator: func(ctrl *gomock.Controller) *TransactionCoordinator { + transactionCoordinator := &TransactionCoordinator{} + mockedSessionHolder := hmock.NewMockSessionHolderInterface(ctrl) + + mockedGlobalTransaction := &model.GlobalTransaction{ + GlobalSession: &apis.GlobalSession{ + XID: xid, + Timeout: int32(300), + }, + BranchSessions: nil, + } + mockedGlobalSessionLock := mock_server.NewMockGlobalSessionLocker(ctrl) + + mockedSessionHolder. + EXPECT(). + FindGlobalTransaction(xid). + Return(mockedGlobalTransaction) + + mockedGlobalSessionLock.EXPECT().TryLock( + mockedGlobalTransaction.GlobalSession, + time.Duration(mockedGlobalTransaction.Timeout)*time.Millisecond, + ).Return(false, fmt.Errorf("error try lock")) + + transactionCoordinator.holder = mockedSessionHolder + transactionCoordinator.locker = mockedGlobalSessionLock + + return transactionCoordinator + }, + ctx: nil, + request: &apis.BranchRegisterRequest{ + XID: xid, + }, + expectedResult: &apis.BranchRegisterResponse{ + ResultCode: apis.ResultCodeFailed, + ExceptionCode: apis.FailedLockGlobalTransaction, + Message: fmt.Sprintf("could not lock global transaction xid = %s", xid), + }, + expectedErr: nil, + }, + { + name: "test BranchRegister error global transaction is not active", + transactionCoordinator: func(ctrl *gomock.Controller) *TransactionCoordinator { + transactionCoordinator := &TransactionCoordinator{} + mockedSessionHolder := hmock.NewMockSessionHolderInterface(ctrl) + + mockedGlobalTransaction := &model.GlobalTransaction{ + GlobalSession: &apis.GlobalSession{ + XID: xid, + Timeout: int32(300), + Status: apis.Begin, + Active: false, + }, + BranchSessions: nil, + } + mockedGlobalSessionLock := mock_server.NewMockGlobalSessionLocker(ctrl) + + mockedSessionHolder. + EXPECT(). + FindGlobalTransaction(xid). + Return(mockedGlobalTransaction) + + mockedGlobalSessionLock.EXPECT().TryLock( + mockedGlobalTransaction.GlobalSession, + time.Duration(mockedGlobalTransaction.Timeout)*time.Millisecond, + ).Return(true, nil) + mockedGlobalSessionLock.EXPECT().Unlock(mockedGlobalTransaction.GlobalSession).Return() + + transactionCoordinator.holder = mockedSessionHolder + transactionCoordinator.locker = mockedGlobalSessionLock + + return transactionCoordinator + }, + ctx: nil, + request: &apis.BranchRegisterRequest{ + XID: xid, + }, + expectedResult: &apis.BranchRegisterResponse{ + ResultCode: apis.ResultCodeFailed, + ExceptionCode: apis.GlobalTransactionNotActive, + Message: fmt.Sprintf("could not register branch into global session xid = %s status = %d", xid, apis.Begin), + }, + expectedErr: nil, + }, + { + name: "test BranchRegister error global transaction is not begin status", + transactionCoordinator: func(ctrl *gomock.Controller) *TransactionCoordinator { + transactionCoordinator := &TransactionCoordinator{} + mockedSessionHolder := hmock.NewMockSessionHolderInterface(ctrl) + + mockedGlobalTransaction := &model.GlobalTransaction{ + GlobalSession: &apis.GlobalSession{ + XID: xid, + Timeout: int32(300), + Status: apis.Committed, + Active: true, + }, + BranchSessions: nil, + } + mockedGlobalSessionLock := mock_server.NewMockGlobalSessionLocker(ctrl) + + mockedSessionHolder. + EXPECT(). + FindGlobalTransaction(xid). + Return(mockedGlobalTransaction) + + mockedGlobalSessionLock.EXPECT().TryLock( + mockedGlobalTransaction.GlobalSession, + time.Duration(mockedGlobalTransaction.Timeout)*time.Millisecond, + ).Return(true, nil) + + mockedGlobalSessionLock.EXPECT().Unlock(mockedGlobalTransaction.GlobalSession).Return() + + transactionCoordinator.holder = mockedSessionHolder + transactionCoordinator.locker = mockedGlobalSessionLock + + return transactionCoordinator + }, + ctx: nil, + request: &apis.BranchRegisterRequest{ + XID: xid, + }, + expectedResult: &apis.BranchRegisterResponse{ + ResultCode: apis.ResultCodeFailed, + ExceptionCode: apis.GlobalTransactionStatusInvalid, + Message: fmt.Sprintf("could not register branch into global session xid = %s status = %d while expecting %d", + xid, apis.Committed, apis.Begin), + }, + expectedErr: nil, + }, + { + name: "test BranchRegister error acquire resource data lock", + transactionCoordinator: func(ctrl *gomock.Controller) *TransactionCoordinator { + transactionCoordinator := &TransactionCoordinator{} + mockedSessionHolder := hmock.NewMockSessionHolderInterface(ctrl) + mockedGlobalSessionLock := mock_server.NewMockGlobalSessionLocker(ctrl) + + mockedGlobalTransaction := &model.GlobalTransaction{ + GlobalSession: &apis.GlobalSession{ + XID: xid, + Timeout: int32(300), + Status: apis.Begin, + Active: true, + }, + BranchSessions: nil, + } + mockedSessionHolder.EXPECT().FindGlobalTransaction(xid).Return(mockedGlobalTransaction) + + mockedGlobalSessionLock.EXPECT().TryLock( + mockedGlobalTransaction.GlobalSession, + time.Duration(mockedGlobalTransaction.Timeout)*time.Millisecond, + ).Return(true, nil) + mockedGlobalSessionLock.EXPECT().Unlock(mockedGlobalTransaction.GlobalSession).Return() + + mockedResourceDataLock := mocklock.NewMockLockManagerInterface(ctrl) + mockedResourceDataLock.EXPECT().AcquireLock(gomock.Any()).Return(false) + + transactionCoordinator.holder = mockedSessionHolder + transactionCoordinator.locker = mockedGlobalSessionLock + transactionCoordinator.resourceDataLocker = mockedResourceDataLock + + return transactionCoordinator + }, + ctx: nil, + request: &apis.BranchRegisterRequest{ + XID: xid, + ResourceID: resourceID, + LockKey: lockKey, + }, + expectedResult: &apis.BranchRegisterResponse{ + ResultCode: apis.ResultCodeFailed, + ExceptionCode: apis.LockKeyConflict, + Message: fmt.Sprintf("branch lock acquire failed xid = %s resourceId = %s, lockKey = %s", + xid, resourceID, lockKey), + }, + expectedErr: nil, + }, + { + name: "test BranchRegister error acquire resource data lock", + transactionCoordinator: func(ctrl *gomock.Controller) *TransactionCoordinator { + transactionCoordinator := &TransactionCoordinator{} + mockedSessionHolder := hmock.NewMockSessionHolderInterface(ctrl) + mockedGlobalSessionLock := mock_server.NewMockGlobalSessionLocker(ctrl) + + mockedGlobalTransaction := &model.GlobalTransaction{ + GlobalSession: &apis.GlobalSession{ + XID: xid, + Timeout: int32(300), + Status: apis.Begin, + Active: true, + }, + BranchSessions: nil, + } + mockedSessionHolder.EXPECT().FindGlobalTransaction(xid).Return(mockedGlobalTransaction) + + mockedGlobalSessionLock.EXPECT().TryLock( + mockedGlobalTransaction.GlobalSession, + time.Duration(mockedGlobalTransaction.Timeout)*time.Millisecond, + ).Return(true, nil) + mockedGlobalSessionLock.EXPECT().Unlock(mockedGlobalTransaction.GlobalSession).Return() + + mockedResourceDataLock := mocklock.NewMockLockManagerInterface(ctrl) + mockedResourceDataLock.EXPECT().AcquireLock(gomock.Any()).Return(false) + + transactionCoordinator.holder = mockedSessionHolder + transactionCoordinator.locker = mockedGlobalSessionLock + transactionCoordinator.resourceDataLocker = mockedResourceDataLock + + return transactionCoordinator + }, + ctx: nil, + request: &apis.BranchRegisterRequest{ + XID: xid, + ResourceID: resourceID, + LockKey: lockKey, + }, + expectedResult: &apis.BranchRegisterResponse{ + ResultCode: apis.ResultCodeFailed, + ExceptionCode: apis.LockKeyConflict, + Message: fmt.Sprintf("branch lock acquire failed xid = %s resourceId = %s, lockKey = %s", + xid, resourceID, lockKey), + }, + expectedErr: nil, + }, + { + name: "test BranchRegister error add branch session", + transactionCoordinator: func(ctrl *gomock.Controller) *TransactionCoordinator { + transactionCoordinator := &TransactionCoordinator{} + mockedSessionHolder := hmock.NewMockSessionHolderInterface(ctrl) + mockedGlobalSessionLock := mock_server.NewMockGlobalSessionLocker(ctrl) + + mockedGlobalTransaction := &model.GlobalTransaction{ + GlobalSession: &apis.GlobalSession{ + XID: xid, + Timeout: int32(300), + Status: apis.Begin, + Active: true, + }, + BranchSessions: nil, + } + mockedSessionHolder.EXPECT().FindGlobalTransaction(xid).Return(mockedGlobalTransaction) + mockedSessionHolder.EXPECT().AddBranchSession(mockedGlobalTransaction.GlobalSession, gomock.Any()).Return(addBranchSessionErr) + + mockedGlobalSessionLock.EXPECT().TryLock( + mockedGlobalTransaction.GlobalSession, + time.Duration(mockedGlobalTransaction.Timeout)*time.Millisecond, + ).Return(true, nil) + mockedGlobalSessionLock.EXPECT().Unlock(mockedGlobalTransaction.GlobalSession).Return() + + mockedResourceDataLock := mocklock.NewMockLockManagerInterface(ctrl) + mockedResourceDataLock.EXPECT().AcquireLock(gomock.Any()).Return(true) + + transactionCoordinator.holder = mockedSessionHolder + transactionCoordinator.locker = mockedGlobalSessionLock + transactionCoordinator.resourceDataLocker = mockedResourceDataLock + + return transactionCoordinator + }, + ctx: nil, + request: &apis.BranchRegisterRequest{ + XID: xid, + ResourceID: resourceID, + LockKey: lockKey, + }, + expectedResult: &apis.BranchRegisterResponse{ + ResultCode: apis.ResultCodeFailed, + ExceptionCode: apis.BranchRegisterFailed, + //Message: fmt.Sprintf("branch register failed, xid = %s, branchID = %d, err: %s",xid, branchID, addBranchSessionErr.Error()), + }, + expectedErr: nil, + }, + { + name: "test BranchRegister success", + transactionCoordinator: func(ctrl *gomock.Controller) *TransactionCoordinator { + transactionCoordinator := &TransactionCoordinator{} + mockedSessionHolder := hmock.NewMockSessionHolderInterface(ctrl) + mockedGlobalSessionLock := mock_server.NewMockGlobalSessionLocker(ctrl) + + mockedGlobalTransaction := &model.GlobalTransaction{ + GlobalSession: &apis.GlobalSession{ + XID: xid, + Timeout: int32(300), + Status: apis.Begin, + Active: true, + }, + BranchSessions: nil, + } + mockedSessionHolder.EXPECT().FindGlobalTransaction(xid).Return(mockedGlobalTransaction) + mockedSessionHolder.EXPECT().AddBranchSession(mockedGlobalTransaction.GlobalSession, gomock.Any()).Return(nil) + + mockedGlobalSessionLock.EXPECT().TryLock( + mockedGlobalTransaction.GlobalSession, + time.Duration(mockedGlobalTransaction.Timeout)*time.Millisecond, + ).Return(true, nil) + mockedGlobalSessionLock.EXPECT().Unlock(mockedGlobalTransaction.GlobalSession).Return() + + mockedResourceDataLock := mocklock.NewMockLockManagerInterface(ctrl) + mockedResourceDataLock.EXPECT().AcquireLock(gomock.Any()).Return(true) + + transactionCoordinator.holder = mockedSessionHolder + transactionCoordinator.locker = mockedGlobalSessionLock + transactionCoordinator.resourceDataLocker = mockedResourceDataLock + + return transactionCoordinator + }, + ctx: nil, + request: &apis.BranchRegisterRequest{ + XID: xid, + ResourceID: resourceID, + LockKey: lockKey, + }, + expectedResult: &apis.BranchRegisterResponse{ + ResultCode: apis.ResultCodeSuccess, + //BranchID: branchID, + }, + expectedErr: nil, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + tc := tt.transactionCoordinator(ctrl) + + actualResp, actualErr := tc.BranchRegister(tt.ctx, tt.request) + if tt.name == "test BranchRegister error add branch session" { + // in case branchID unable to mock + assert.Equal(t, tt.expectedResult.ResultCode, actualResp.ResultCode) + assert.Equal(t, tt.expectedResult.ExceptionCode, actualResp.ExceptionCode) + assert.Equal(t, tt.expectedErr, actualErr) + } else if tt.name == "test BranchRegister success" { + // in case branchID unable to mock + assert.Equal(t, tt.expectedResult.ResultCode, actualResp.ResultCode) + assert.Equal(t, tt.expectedErr, actualErr) + } else { + assert.Equal(t, tt.expectedResult, actualResp) + assert.Equal(t, tt.expectedErr, actualErr) + } + }) + } } func TestTransactionCoordinator_Commit(t *testing.T) { From a0bfdb7c5e0a4b1ab08f7c0a1762102680528aea Mon Sep 17 00:00:00 2001 From: bohehe Date: Sun, 27 Feb 2022 13:09:42 +0800 Subject: [PATCH 10/13] lint --- pkg/tc/server/transaction_coordinator_test.go | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/pkg/tc/server/transaction_coordinator_test.go b/pkg/tc/server/transaction_coordinator_test.go index ed52ddbf7..902286c5e 100644 --- a/pkg/tc/server/transaction_coordinator_test.go +++ b/pkg/tc/server/transaction_coordinator_test.go @@ -755,16 +755,18 @@ func TestTransactionCoordinator_BranchRegister(t *testing.T) { tc := tt.transactionCoordinator(ctrl) actualResp, actualErr := tc.BranchRegister(tt.ctx, tt.request) - if tt.name == "test BranchRegister error add branch session" { + + switch tt.name { + case "test BranchRegister error add branch session": // in case branchID unable to mock assert.Equal(t, tt.expectedResult.ResultCode, actualResp.ResultCode) assert.Equal(t, tt.expectedResult.ExceptionCode, actualResp.ExceptionCode) assert.Equal(t, tt.expectedErr, actualErr) - } else if tt.name == "test BranchRegister success" { + case "test BranchRegister success": // in case branchID unable to mock assert.Equal(t, tt.expectedResult.ResultCode, actualResp.ResultCode) assert.Equal(t, tt.expectedErr, actualErr) - } else { + default: assert.Equal(t, tt.expectedResult, actualResp) assert.Equal(t, tt.expectedErr, actualErr) } From 43b82d5ba361e99d5b92567071f81c6dcc3cad07 Mon Sep 17 00:00:00 2001 From: bohehe Date: Mon, 28 Feb 2022 08:49:47 +0800 Subject: [PATCH 11/13] sort import --- pkg/tc/server/transaction_coordinator_test.go | 50 +++++++++---------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/pkg/tc/server/transaction_coordinator_test.go b/pkg/tc/server/transaction_coordinator_test.go index 902286c5e..98c8a3a0b 100644 --- a/pkg/tc/server/transaction_coordinator_test.go +++ b/pkg/tc/server/transaction_coordinator_test.go @@ -8,10 +8,10 @@ import ( "github.com/golang/mock/gomock" "github.com/opentrx/seata-golang/v2/pkg/apis" - hmock "github.com/opentrx/seata-golang/v2/pkg/tc/holder/mock" + mockholder "github.com/opentrx/seata-golang/v2/pkg/tc/holder/mock" mocklock "github.com/opentrx/seata-golang/v2/pkg/tc/lock/mock" "github.com/opentrx/seata-golang/v2/pkg/tc/model" - mock_server "github.com/opentrx/seata-golang/v2/pkg/tc/server/mock" + mockserver "github.com/opentrx/seata-golang/v2/pkg/tc/server/mock" "github.com/stretchr/testify/assert" ) @@ -29,7 +29,7 @@ func TestTransactionCoordinator_GetStatus(t *testing.T) { name: "test GetStatus success", transactionCoordinator: func(ctrl *gomock.Controller) *TransactionCoordinator { transactionCoordinator := &TransactionCoordinator{} - mockedSessionHolder := hmock.NewMockSessionHolderInterface(ctrl) + mockedSessionHolder := mockholder.NewMockSessionHolderInterface(ctrl) mockedSessionHolder. EXPECT(). @@ -56,7 +56,7 @@ func TestTransactionCoordinator_GetStatus(t *testing.T) { name: "test GetStatus with empty XID", transactionCoordinator: func(ctrl *gomock.Controller) *TransactionCoordinator { transactionCoordinator := &TransactionCoordinator{} - mockedSessionHolder := hmock.NewMockSessionHolderInterface(ctrl) + mockedSessionHolder := mockholder.NewMockSessionHolderInterface(ctrl) mockedSessionHolder. EXPECT(). @@ -111,7 +111,7 @@ func TestTransactionCoordinator_BranchReport(t *testing.T) { name: "test BranchReport with empty XID", transactionCoordinator: func(ctrl *gomock.Controller) *TransactionCoordinator { transactionCoordinator := &TransactionCoordinator{} - mockedSessionHolder := hmock.NewMockSessionHolderInterface(ctrl) + mockedSessionHolder := mockholder.NewMockSessionHolderInterface(ctrl) mockedSessionHolder.EXPECT().FindGlobalTransaction("").Return(nil) @@ -134,7 +134,7 @@ func TestTransactionCoordinator_BranchReport(t *testing.T) { name: "test BranchReport with empty Branch", transactionCoordinator: func(ctrl *gomock.Controller) *TransactionCoordinator { transactionCoordinator := &TransactionCoordinator{} - mockedSessionHolder := hmock.NewMockSessionHolderInterface(ctrl) + mockedSessionHolder := mockholder.NewMockSessionHolderInterface(ctrl) mockedBranchSession := &apis.BranchSession{ BranchID: branchID + 1, @@ -169,7 +169,7 @@ func TestTransactionCoordinator_BranchReport(t *testing.T) { name: "test BranchReport error update branch status ", transactionCoordinator: func(ctrl *gomock.Controller) *TransactionCoordinator { transactionCoordinator := &TransactionCoordinator{} - mockedSessionHolder := hmock.NewMockSessionHolderInterface(ctrl) + mockedSessionHolder := mockholder.NewMockSessionHolderInterface(ctrl) mockedBranchSession := &apis.BranchSession{ BranchID: branchID, @@ -207,7 +207,7 @@ func TestTransactionCoordinator_BranchReport(t *testing.T) { name: "test BranchReport success", transactionCoordinator: func(ctrl *gomock.Controller) *TransactionCoordinator { transactionCoordinator := &TransactionCoordinator{} - mockedSessionHolder := hmock.NewMockSessionHolderInterface(ctrl) + mockedSessionHolder := mockholder.NewMockSessionHolderInterface(ctrl) mockedBranchSession := &apis.BranchSession{ BranchID: branchID, @@ -321,7 +321,7 @@ func TestTransactionCoordinator_Begin(t *testing.T) { name: "test Begin error add global session", transactionCoordinator: func(ctrl *gomock.Controller) *TransactionCoordinator { transactionCoordinator := &TransactionCoordinator{} - mockedSessionHolder := hmock.NewMockSessionHolderInterface(ctrl) + mockedSessionHolder := mockholder.NewMockSessionHolderInterface(ctrl) mockedSessionHolder.EXPECT().AddGlobalSession(gomock.Any()).Return(addGlobalSessionHolderErr) @@ -346,7 +346,7 @@ func TestTransactionCoordinator_Begin(t *testing.T) { name: "test Begin success", transactionCoordinator: func(ctrl *gomock.Controller) *TransactionCoordinator { transactionCoordinator := &TransactionCoordinator{} - mockedSessionHolder := hmock.NewMockSessionHolderInterface(ctrl) + mockedSessionHolder := mockholder.NewMockSessionHolderInterface(ctrl) mockedSessionHolder.EXPECT().AddGlobalSession(gomock.Any()).Return(nil) @@ -405,7 +405,7 @@ func TestTransactionCoordinator_BranchRegister(t *testing.T) { name: "test BranchRegister with empty XID", transactionCoordinator: func(ctrl *gomock.Controller) *TransactionCoordinator { transactionCoordinator := &TransactionCoordinator{} - mockedSessionHolder := hmock.NewMockSessionHolderInterface(ctrl) + mockedSessionHolder := mockholder.NewMockSessionHolderInterface(ctrl) mockedSessionHolder. EXPECT(). @@ -431,7 +431,7 @@ func TestTransactionCoordinator_BranchRegister(t *testing.T) { name: "test BranchRegister error try lock", transactionCoordinator: func(ctrl *gomock.Controller) *TransactionCoordinator { transactionCoordinator := &TransactionCoordinator{} - mockedSessionHolder := hmock.NewMockSessionHolderInterface(ctrl) + mockedSessionHolder := mockholder.NewMockSessionHolderInterface(ctrl) mockedGlobalTransaction := &model.GlobalTransaction{ GlobalSession: &apis.GlobalSession{ @@ -440,7 +440,7 @@ func TestTransactionCoordinator_BranchRegister(t *testing.T) { }, BranchSessions: nil, } - mockedGlobalSessionLock := mock_server.NewMockGlobalSessionLocker(ctrl) + mockedGlobalSessionLock := mockserver.NewMockGlobalSessionLocker(ctrl) mockedSessionHolder. EXPECT(). @@ -472,7 +472,7 @@ func TestTransactionCoordinator_BranchRegister(t *testing.T) { name: "test BranchRegister error global transaction is not active", transactionCoordinator: func(ctrl *gomock.Controller) *TransactionCoordinator { transactionCoordinator := &TransactionCoordinator{} - mockedSessionHolder := hmock.NewMockSessionHolderInterface(ctrl) + mockedSessionHolder := mockholder.NewMockSessionHolderInterface(ctrl) mockedGlobalTransaction := &model.GlobalTransaction{ GlobalSession: &apis.GlobalSession{ @@ -483,7 +483,7 @@ func TestTransactionCoordinator_BranchRegister(t *testing.T) { }, BranchSessions: nil, } - mockedGlobalSessionLock := mock_server.NewMockGlobalSessionLocker(ctrl) + mockedGlobalSessionLock := mockserver.NewMockGlobalSessionLocker(ctrl) mockedSessionHolder. EXPECT(). @@ -516,7 +516,7 @@ func TestTransactionCoordinator_BranchRegister(t *testing.T) { name: "test BranchRegister error global transaction is not begin status", transactionCoordinator: func(ctrl *gomock.Controller) *TransactionCoordinator { transactionCoordinator := &TransactionCoordinator{} - mockedSessionHolder := hmock.NewMockSessionHolderInterface(ctrl) + mockedSessionHolder := mockholder.NewMockSessionHolderInterface(ctrl) mockedGlobalTransaction := &model.GlobalTransaction{ GlobalSession: &apis.GlobalSession{ @@ -527,7 +527,7 @@ func TestTransactionCoordinator_BranchRegister(t *testing.T) { }, BranchSessions: nil, } - mockedGlobalSessionLock := mock_server.NewMockGlobalSessionLocker(ctrl) + mockedGlobalSessionLock := mockserver.NewMockGlobalSessionLocker(ctrl) mockedSessionHolder. EXPECT(). @@ -562,8 +562,8 @@ func TestTransactionCoordinator_BranchRegister(t *testing.T) { name: "test BranchRegister error acquire resource data lock", transactionCoordinator: func(ctrl *gomock.Controller) *TransactionCoordinator { transactionCoordinator := &TransactionCoordinator{} - mockedSessionHolder := hmock.NewMockSessionHolderInterface(ctrl) - mockedGlobalSessionLock := mock_server.NewMockGlobalSessionLocker(ctrl) + mockedSessionHolder := mockholder.NewMockSessionHolderInterface(ctrl) + mockedGlobalSessionLock := mockserver.NewMockGlobalSessionLocker(ctrl) mockedGlobalTransaction := &model.GlobalTransaction{ GlobalSession: &apis.GlobalSession{ @@ -609,8 +609,8 @@ func TestTransactionCoordinator_BranchRegister(t *testing.T) { name: "test BranchRegister error acquire resource data lock", transactionCoordinator: func(ctrl *gomock.Controller) *TransactionCoordinator { transactionCoordinator := &TransactionCoordinator{} - mockedSessionHolder := hmock.NewMockSessionHolderInterface(ctrl) - mockedGlobalSessionLock := mock_server.NewMockGlobalSessionLocker(ctrl) + mockedSessionHolder := mockholder.NewMockSessionHolderInterface(ctrl) + mockedGlobalSessionLock := mockserver.NewMockGlobalSessionLocker(ctrl) mockedGlobalTransaction := &model.GlobalTransaction{ GlobalSession: &apis.GlobalSession{ @@ -656,8 +656,8 @@ func TestTransactionCoordinator_BranchRegister(t *testing.T) { name: "test BranchRegister error add branch session", transactionCoordinator: func(ctrl *gomock.Controller) *TransactionCoordinator { transactionCoordinator := &TransactionCoordinator{} - mockedSessionHolder := hmock.NewMockSessionHolderInterface(ctrl) - mockedGlobalSessionLock := mock_server.NewMockGlobalSessionLocker(ctrl) + mockedSessionHolder := mockholder.NewMockSessionHolderInterface(ctrl) + mockedGlobalSessionLock := mockserver.NewMockGlobalSessionLocker(ctrl) mockedGlobalTransaction := &model.GlobalTransaction{ GlobalSession: &apis.GlobalSession{ @@ -703,8 +703,8 @@ func TestTransactionCoordinator_BranchRegister(t *testing.T) { name: "test BranchRegister success", transactionCoordinator: func(ctrl *gomock.Controller) *TransactionCoordinator { transactionCoordinator := &TransactionCoordinator{} - mockedSessionHolder := hmock.NewMockSessionHolderInterface(ctrl) - mockedGlobalSessionLock := mock_server.NewMockGlobalSessionLocker(ctrl) + mockedSessionHolder := mockholder.NewMockSessionHolderInterface(ctrl) + mockedGlobalSessionLock := mockserver.NewMockGlobalSessionLocker(ctrl) mockedGlobalTransaction := &model.GlobalTransaction{ GlobalSession: &apis.GlobalSession{ From f5576598159ba9a135b413cd313b4e38524f0083 Mon Sep 17 00:00:00 2001 From: bohehe Date: Mon, 28 Feb 2022 09:44:19 +0800 Subject: [PATCH 12/13] gofmt --- pkg/tc/server/transaction_coordinator_test.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pkg/tc/server/transaction_coordinator_test.go b/pkg/tc/server/transaction_coordinator_test.go index 98c8a3a0b..db255cbfc 100644 --- a/pkg/tc/server/transaction_coordinator_test.go +++ b/pkg/tc/server/transaction_coordinator_test.go @@ -7,12 +7,13 @@ import ( "time" "github.com/golang/mock/gomock" + "github.com/stretchr/testify/assert" + "github.com/opentrx/seata-golang/v2/pkg/apis" mockholder "github.com/opentrx/seata-golang/v2/pkg/tc/holder/mock" mocklock "github.com/opentrx/seata-golang/v2/pkg/tc/lock/mock" "github.com/opentrx/seata-golang/v2/pkg/tc/model" mockserver "github.com/opentrx/seata-golang/v2/pkg/tc/server/mock" - "github.com/stretchr/testify/assert" ) func TestTransactionCoordinator_GetStatus(t *testing.T) { From e0c01a13da1fdad9b69cca36b65677bac9ecb086 Mon Sep 17 00:00:00 2001 From: bohehe Date: Mon, 28 Feb 2022 20:56:35 +0800 Subject: [PATCH 13/13] vup golangci-lint to v1.44.2 and set disableStutteringCheck rule --- .github/workflows/main.yml | 2 +- .golangci.yml | 9 +++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 6297fce26..346c5bf36 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -41,7 +41,7 @@ jobs: - name: GolangCI Lint run: | - curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(go env GOPATH)/bin v1.39.0 + curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(go env GOPATH)/bin v1.44.2 golangci-lint run ./... - name: Unit Tests diff --git a/.golangci.yml b/.golangci.yml index 5e19633b6..b5ef960b2 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -16,3 +16,12 @@ linters: - goimports - gocritic - revive + +linters-settings: + revive: + rules: + - name: exported + severity: warning + disabled: false + arguments: + - "disableStutteringCheck"