github.com/ydb-platform/ydb-go-sdk/v3@v3.57.0/internal/query/transaction_test.go (about) 1 package query 2 3 import ( 4 "testing" 5 6 "github.com/stretchr/testify/require" 7 "github.com/ydb-platform/ydb-go-genproto/protos/Ydb" 8 "github.com/ydb-platform/ydb-go-genproto/protos/Ydb_Query" 9 "go.uber.org/mock/gomock" 10 "google.golang.org/grpc" 11 grpcCodes "google.golang.org/grpc/codes" 12 grpcStatus "google.golang.org/grpc/status" 13 14 "github.com/ydb-platform/ydb-go-sdk/v3/internal/allocator" 15 "github.com/ydb-platform/ydb-go-sdk/v3/internal/params" 16 "github.com/ydb-platform/ydb-go-sdk/v3/internal/xerrors" 17 "github.com/ydb-platform/ydb-go-sdk/v3/internal/xtest" 18 "github.com/ydb-platform/ydb-go-sdk/v3/query" 19 ) 20 21 func TestCommitTx(t *testing.T) { 22 t.Run("HappyWay", func(t *testing.T) { 23 ctx := xtest.Context(t) 24 ctrl := gomock.NewController(t) 25 service := NewMockQueryServiceClient(ctrl) 26 service.EXPECT().CommitTransaction(gomock.Any(), gomock.Any()).Return( 27 &Ydb_Query.CommitTransactionResponse{ 28 Status: Ydb.StatusIds_SUCCESS, 29 }, nil, 30 ) 31 t.Log("commit") 32 err := commitTx(ctx, service, "123", "456") 33 require.NoError(t, err) 34 }) 35 t.Run("TransportError", func(t *testing.T) { 36 ctx := xtest.Context(t) 37 ctrl := gomock.NewController(t) 38 service := NewMockQueryServiceClient(ctrl) 39 service.EXPECT().CommitTransaction(gomock.Any(), gomock.Any()).Return( 40 nil, grpcStatus.Error(grpcCodes.Unavailable, ""), 41 ) 42 t.Log("commit") 43 err := commitTx(ctx, service, "123", "456") 44 require.Error(t, err) 45 require.True(t, xerrors.IsTransportError(err, grpcCodes.Unavailable)) 46 }) 47 t.Run("OperationError", func(t *testing.T) { 48 ctx := xtest.Context(t) 49 ctrl := gomock.NewController(t) 50 service := NewMockQueryServiceClient(ctrl) 51 service.EXPECT().CommitTransaction(gomock.Any(), gomock.Any()).Return( 52 &Ydb_Query.CommitTransactionResponse{ 53 Status: Ydb.StatusIds_UNAVAILABLE, 54 }, nil, 55 ) 56 t.Log("commit") 57 err := commitTx(ctx, service, "123", "456") 58 require.Error(t, err) 59 require.True(t, xerrors.IsOperationError(err, Ydb.StatusIds_UNAVAILABLE)) 60 }) 61 } 62 63 func TestRollback(t *testing.T) { 64 t.Run("HappyWay", func(t *testing.T) { 65 ctx := xtest.Context(t) 66 ctrl := gomock.NewController(t) 67 service := NewMockQueryServiceClient(ctrl) 68 service.EXPECT().RollbackTransaction(gomock.Any(), gomock.Any()).Return( 69 &Ydb_Query.RollbackTransactionResponse{ 70 Status: Ydb.StatusIds_SUCCESS, 71 }, nil, 72 ) 73 t.Log("rollback") 74 err := rollback(ctx, service, "123", "456") 75 require.NoError(t, err) 76 }) 77 t.Run("TransportError", func(t *testing.T) { 78 ctx := xtest.Context(t) 79 ctrl := gomock.NewController(t) 80 service := NewMockQueryServiceClient(ctrl) 81 service.EXPECT().RollbackTransaction(gomock.Any(), gomock.Any()).Return( 82 nil, grpcStatus.Error(grpcCodes.Unavailable, ""), 83 ) 84 t.Log("rollback") 85 err := rollback(ctx, service, "123", "456") 86 require.Error(t, err) 87 require.True(t, xerrors.IsTransportError(err, grpcCodes.Unavailable)) 88 }) 89 t.Run("OperationError", func(t *testing.T) { 90 ctx := xtest.Context(t) 91 ctrl := gomock.NewController(t) 92 service := NewMockQueryServiceClient(ctrl) 93 service.EXPECT().RollbackTransaction(gomock.Any(), gomock.Any()).Return( 94 &Ydb_Query.RollbackTransactionResponse{ 95 Status: Ydb.StatusIds_UNAVAILABLE, 96 }, nil, 97 ) 98 t.Log("rollback") 99 err := rollback(ctx, service, "123", "456") 100 require.Error(t, err) 101 require.True(t, xerrors.IsOperationError(err, Ydb.StatusIds_UNAVAILABLE)) 102 }) 103 } 104 105 type testExecuteSettings struct { 106 execMode query.ExecMode 107 statsMode query.StatsMode 108 txControl *query.TransactionControl 109 syntax query.Syntax 110 params *params.Parameters 111 callOptions []grpc.CallOption 112 } 113 114 func (s testExecuteSettings) ExecMode() query.ExecMode { 115 return s.execMode 116 } 117 118 func (s testExecuteSettings) StatsMode() query.StatsMode { 119 return s.statsMode 120 } 121 122 func (s testExecuteSettings) TxControl() *query.TransactionControl { 123 return s.txControl 124 } 125 126 func (s testExecuteSettings) Syntax() query.Syntax { 127 return s.syntax 128 } 129 130 func (s testExecuteSettings) Params() *params.Parameters { 131 return s.params 132 } 133 134 func (s testExecuteSettings) CallOptions() []grpc.CallOption { 135 return s.callOptions 136 } 137 138 var _ executeConfig = testExecuteSettings{} 139 140 func TestTxExecuteSettings(t *testing.T) { 141 for _, tt := range []struct { 142 name string 143 txID string 144 txOpts []query.TxExecuteOption 145 settings executeConfig 146 }{ 147 { 148 name: "WithTxID", 149 txID: "test", 150 txOpts: nil, 151 settings: testExecuteSettings{ 152 execMode: query.ExecModeExecute, 153 statsMode: query.StatsModeNone, 154 txControl: query.TxControl(query.WithTxID("test")), 155 syntax: query.SyntaxYQL, 156 }, 157 }, 158 { 159 name: "WithStats", 160 txOpts: []query.TxExecuteOption{ 161 query.WithStatsMode(query.StatsModeFull), 162 }, 163 settings: testExecuteSettings{ 164 execMode: query.ExecModeExecute, 165 statsMode: query.StatsModeFull, 166 txControl: query.TxControl(query.WithTxID("")), 167 syntax: query.SyntaxYQL, 168 }, 169 }, 170 { 171 name: "WithExecMode", 172 txOpts: []query.TxExecuteOption{ 173 query.WithExecMode(query.ExecModeExplain), 174 }, 175 settings: testExecuteSettings{ 176 execMode: query.ExecModeExplain, 177 statsMode: query.StatsModeNone, 178 txControl: query.TxControl(query.WithTxID("")), 179 syntax: query.SyntaxYQL, 180 }, 181 }, 182 { 183 name: "WithSyntax", 184 txOpts: []query.TxExecuteOption{ 185 query.WithSyntax(query.SyntaxPostgreSQL), 186 }, 187 settings: testExecuteSettings{ 188 execMode: query.ExecModeExecute, 189 statsMode: query.StatsModeNone, 190 txControl: query.TxControl(query.WithTxID("")), 191 syntax: query.SyntaxPostgreSQL, 192 }, 193 }, 194 { 195 name: "WithGrpcOptions", 196 txOpts: []query.TxExecuteOption{ 197 query.WithCallOptions(grpc.CallContentSubtype("test")), 198 }, 199 settings: testExecuteSettings{ 200 execMode: query.ExecModeExecute, 201 statsMode: query.StatsModeNone, 202 txControl: query.TxControl(query.WithTxID("")), 203 syntax: query.SyntaxYQL, 204 callOptions: []grpc.CallOption{ 205 grpc.CallContentSubtype("test"), 206 }, 207 }, 208 }, 209 { 210 name: "WithParams", 211 txOpts: []query.TxExecuteOption{ 212 query.WithParameters( 213 params.Builder{}.Param("$a").Text("A").Build(), 214 ), 215 }, 216 settings: testExecuteSettings{ 217 execMode: query.ExecModeExecute, 218 statsMode: query.StatsModeNone, 219 txControl: query.TxControl(query.WithTxID("")), 220 syntax: query.SyntaxYQL, 221 params: params.Builder{}.Param("$a").Text("A").Build(), 222 }, 223 }, 224 } { 225 t.Run(tt.name, func(t *testing.T) { 226 a := allocator.New() 227 settings := query.TxExecuteSettings(tt.txID, tt.txOpts...).ExecuteSettings 228 require.Equal(t, tt.settings.Syntax(), settings.Syntax()) 229 require.Equal(t, tt.settings.ExecMode(), settings.ExecMode()) 230 require.Equal(t, tt.settings.StatsMode(), settings.StatsMode()) 231 require.Equal(t, tt.settings.TxControl().ToYDB(a).String(), settings.TxControl().ToYDB(a).String()) 232 require.Equal(t, tt.settings.Params().ToYDB(a), settings.Params().ToYDB(a)) 233 require.Equal(t, tt.settings.CallOptions(), settings.CallOptions()) 234 }) 235 } 236 }