github.com/kaleido-io/firefly@v0.0.0-20210622132723-8b4b6aacb971/internal/database/sqlcommon/sqlcommon_test.go (about)

     1  // Copyright © 2021 Kaleido, Inc.
     2  //
     3  // SPDX-License-Identifier: Apache-2.0
     4  //
     5  // Licensed under the Apache License, Version 2.0 (the "License");
     6  // you may not use this file except in compliance with the License.
     7  // You may obtain a copy of the License at
     8  //
     9  //     http://www.apache.org/licenses/LICENSE-2.0
    10  //
    11  // Unless required by applicable law or agreed to in writing, software
    12  // distributed under the License is distributed on an "AS IS" BASIS,
    13  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    14  // See the License for the specific language governing permissions and
    15  // limitations under the License.
    16  
    17  package sqlcommon
    18  
    19  import (
    20  	"context"
    21  	"database/sql/driver"
    22  	"fmt"
    23  	"testing"
    24  
    25  	"github.com/DATA-DOG/go-sqlmock"
    26  	sq "github.com/Masterminds/squirrel"
    27  	"github.com/stretchr/testify/assert"
    28  )
    29  
    30  func TestInitSQLCommon(t *testing.T) {
    31  	s := newQLTestProvider(t)
    32  	defer s.Close()
    33  	assert.NotNil(t, s.Capabilities())
    34  	assert.NotNil(t, s.DB())
    35  }
    36  
    37  func TestInitSQLCommonMissingOptions(t *testing.T) {
    38  	s := &SQLCommon{}
    39  	err := s.Init(context.Background(), nil, nil, nil, nil)
    40  	assert.Regexp(t, "FF10112", err)
    41  }
    42  
    43  func TestInitSQLCommonOpenFailed(t *testing.T) {
    44  	mp := newMockProvider()
    45  	mp.openError = fmt.Errorf("pop")
    46  	err := mp.SQLCommon.Init(context.Background(), mp, mp.prefix, mp.callbacks, mp.capabilities)
    47  	assert.Regexp(t, "FF10112.*pop", err)
    48  }
    49  
    50  func TestInitSQLCommonMigrationOpenFailed(t *testing.T) {
    51  	mp := newMockProvider()
    52  	mp.prefix.Set(SQLConfMigrationsAuto, true)
    53  	mp.getMigrationDriverError = fmt.Errorf("pop")
    54  	err := mp.SQLCommon.Init(context.Background(), mp, mp.prefix, mp.callbacks, mp.capabilities)
    55  	assert.Regexp(t, "FF10163.*pop", err)
    56  }
    57  
    58  func TestQueryTxBadSQL(t *testing.T) {
    59  	tp := newQLTestProvider(t)
    60  	_, err := tp.queryTx(context.Background(), nil, sq.SelectBuilder{})
    61  	assert.Regexp(t, "FF10113", err)
    62  }
    63  
    64  func TestInsertTxPostgreSQLReturnedSyntax(t *testing.T) {
    65  	s, mdb := newMockProvider().init()
    66  	mdb.ExpectBegin()
    67  	mdb.ExpectQuery("INSERT.*").WillReturnRows(sqlmock.NewRows([]string{"seq"}).AddRow(12345))
    68  	ctx, tx, _, err := s.beginOrUseTx(context.Background())
    69  	assert.NoError(t, err)
    70  	s.fakePSQLInsert = true
    71  	sb := sq.Insert("table").Columns("col1").Values(("val1"))
    72  	sequence, err := s.insertTx(ctx, tx, sb)
    73  	assert.NoError(t, err)
    74  	assert.Equal(t, int64(12345), sequence)
    75  }
    76  
    77  func TestInsertTxPostgreSQLReturnedSyntaxFail(t *testing.T) {
    78  	s, mdb := newMockProvider().init()
    79  	mdb.ExpectBegin()
    80  	mdb.ExpectQuery("INSERT.*").WillReturnError(fmt.Errorf("pop"))
    81  	ctx, tx, _, err := s.beginOrUseTx(context.Background())
    82  	assert.NoError(t, err)
    83  	s.fakePSQLInsert = true
    84  	sb := sq.Insert("table").Columns("col1").Values(("val1"))
    85  	_, err = s.insertTx(ctx, tx, sb)
    86  	assert.Regexp(t, "FF10116", err)
    87  }
    88  
    89  func TestInsertTxBadSQL(t *testing.T) {
    90  	s, _ := newMockProvider().init()
    91  	_, err := s.insertTx(context.Background(), nil, sq.InsertBuilder{})
    92  	assert.Regexp(t, "FF10113", err)
    93  }
    94  
    95  func TestUpdateTxBadSQL(t *testing.T) {
    96  	s, _ := newMockProvider().init()
    97  	err := s.updateTx(context.Background(), nil, sq.UpdateBuilder{})
    98  	assert.Regexp(t, "FF10113", err)
    99  }
   100  
   101  func TestDeleteTxBadSQL(t *testing.T) {
   102  	s, _ := newMockProvider().init()
   103  	err := s.deleteTx(context.Background(), nil, sq.DeleteBuilder{})
   104  	assert.Regexp(t, "FF10113", err)
   105  }
   106  
   107  func TestDeleteTxZeroRowsAffected(t *testing.T) {
   108  	s, mdb := newMockProvider().init()
   109  	mdb.ExpectBegin()
   110  	mdb.ExpectExec("DELETE.*").WillReturnResult(driver.ResultNoRows)
   111  	ctx, tx, _, err := s.beginOrUseTx(context.Background())
   112  	assert.NoError(t, err)
   113  	s.fakePSQLInsert = true
   114  	sb := sq.Delete("table")
   115  	err = s.deleteTx(ctx, tx, sb)
   116  	assert.Regexp(t, "FF10109", err)
   117  }
   118  
   119  func TestRunAsGroup(t *testing.T) {
   120  	s, mock := newMockProvider().init()
   121  	mock.ExpectBegin()
   122  	mock.ExpectExec("INSERT.*").WillReturnResult(driver.ResultNoRows)
   123  	mock.ExpectExec("INSERT.*").WillReturnResult(driver.ResultNoRows)
   124  	mock.ExpectQuery("SELECT.*").WillReturnRows(sqlmock.NewRows([]string{"id"}))
   125  	mock.ExpectCommit()
   126  
   127  	err := s.RunAsGroup(context.Background(), func(ctx context.Context) (err error) {
   128  		// First insert
   129  		ctx, tx, ac, err := s.beginOrUseTx(ctx)
   130  		assert.NoError(t, err)
   131  		_, err = s.insertTx(ctx, tx, sq.Insert("test").Columns("test").Values("test"))
   132  		assert.NoError(t, err)
   133  		err = s.commitTx(ctx, tx, ac)
   134  		assert.NoError(t, err)
   135  
   136  		// Second insert
   137  		ctx, tx, ac, err = s.beginOrUseTx(ctx)
   138  		assert.NoError(t, err)
   139  		_, err = s.insertTx(ctx, tx, sq.Insert("test").Columns("test").Values("test"))
   140  		assert.NoError(t, err)
   141  		err = s.commitTx(ctx, tx, ac)
   142  		assert.NoError(t, err)
   143  
   144  		// Query, not specifying a transaction
   145  		_, err = s.query(ctx, sq.Select("test").From("test"))
   146  		assert.NoError(t, err)
   147  		return
   148  	})
   149  
   150  	assert.NoError(t, mock.ExpectationsWereMet())
   151  	assert.NoError(t, err)
   152  }
   153  
   154  func TestRunAsGroupBeginFail(t *testing.T) {
   155  	s, mock := newMockProvider().init()
   156  	mock.ExpectBegin().WillReturnError(fmt.Errorf("pop"))
   157  	err := s.RunAsGroup(context.Background(), func(ctx context.Context) (err error) {
   158  		return
   159  	})
   160  	assert.NoError(t, mock.ExpectationsWereMet())
   161  	assert.Regexp(t, "FF10114", err)
   162  }
   163  
   164  func TestRunAsGroupFunctionFails(t *testing.T) {
   165  	s, mock := newMockProvider().init()
   166  	mock.ExpectBegin()
   167  	mock.ExpectExec("INSERT.*").WillReturnResult(driver.ResultNoRows)
   168  	mock.ExpectRollback()
   169  	err := s.RunAsGroup(context.Background(), func(ctx context.Context) (err error) {
   170  		ctx, tx, ac, err := s.beginOrUseTx(ctx)
   171  		assert.NoError(t, err)
   172  		_, err = s.insertTx(ctx, tx, sq.Insert("test").Columns("test").Values("test"))
   173  		assert.NoError(t, err)
   174  		s.rollbackTx(ctx, tx, ac) // won't actually rollback
   175  		assert.NoError(t, err)
   176  
   177  		return fmt.Errorf("pop")
   178  	})
   179  	assert.NoError(t, mock.ExpectationsWereMet())
   180  	assert.Regexp(t, "pop", err)
   181  }
   182  
   183  func TestRunAsGroupCommitFail(t *testing.T) {
   184  	s, mock := newMockProvider().init()
   185  	mock.ExpectBegin()
   186  	mock.ExpectCommit().WillReturnError(fmt.Errorf("pop"))
   187  	err := s.RunAsGroup(context.Background(), func(ctx context.Context) (err error) {
   188  		return
   189  	})
   190  	assert.NoError(t, mock.ExpectationsWereMet())
   191  	assert.Regexp(t, "FF10119", err)
   192  }
   193  
   194  func TestRollbackFail(t *testing.T) {
   195  	s, mock := newMockProvider().init()
   196  	mock.ExpectBegin()
   197  	tx, _ := s.db.Begin()
   198  	mock.ExpectRollback().WillReturnError(fmt.Errorf("pop"))
   199  	s.rollbackTx(context.Background(), &txWrapper{sqlTX: tx}, false)
   200  	assert.NoError(t, mock.ExpectationsWereMet())
   201  }