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  }