...

Source file src/edge-infra.dev/pkg/sds/emergencyaccess/rules/storage/database/commands_test.go

Documentation: edge-infra.dev/pkg/sds/emergencyaccess/rules/storage/database

     1  package database
     2  
     3  import (
     4  	"context"
     5  	"testing"
     6  
     7  	"github.com/DATA-DOG/go-sqlmock"
     8  	"github.com/jackc/pgconn"
     9  	"github.com/stretchr/testify/assert"
    10  	"github.com/stretchr/testify/require"
    11  
    12  	"edge-infra.dev/pkg/lib/fog"
    13  	rulesengine "edge-infra.dev/pkg/sds/emergencyaccess/rules"
    14  	datasql "edge-infra.dev/pkg/sds/emergencyaccess/rules/storage/database/sql"
    15  )
    16  
    17  func TestAddCommands(t *testing.T) {
    18  	db, mock := initMockDB(t)
    19  	defer db.Close()
    20  	ds := New(fog.New(), db)
    21  
    22  	mock.ExpectBegin()
    23  	mock.ExpectExec(datasql.InsertCommand).WithArgs("ls").WillReturnResult(sqlmock.NewResult(1, 1))
    24  	mock.ExpectExec(datasql.InsertCommand).WithArgs("mv").WillReturnResult(sqlmock.NewResult(2, 1))
    25  	mock.ExpectCommit()
    26  
    27  	res, err := ds.AddCommands(context.Background(), []string{"ls", "mv"})
    28  	assert.NoError(t, err)
    29  	assert.Nil(t, res.Conflicts)
    30  	if err := mock.ExpectationsWereMet(); err != nil {
    31  		t.Errorf("there were unfulfilled expectations: %s", err)
    32  	}
    33  }
    34  
    35  func TestDeleteCommand(t *testing.T) {
    36  	db, mock := initMockDB(t)
    37  	defer db.Close()
    38  	ds := New(fog.New(), db)
    39  
    40  	mock.ExpectExec(datasql.DeleteCommand).WithArgs("ls").WillReturnResult(sqlmock.NewResult(1, 1))
    41  
    42  	_, err := ds.DeleteCommand(context.Background(), "ls")
    43  	assert.NoError(t, err)
    44  	if err := mock.ExpectationsWereMet(); err != nil {
    45  		t.Errorf("there were unfulfilled expectations: %s", err)
    46  	}
    47  }
    48  
    49  func TestDeleteCommandNoChange(t *testing.T) {
    50  	db, mock := initMockDB(t)
    51  	defer db.Close()
    52  	ds := New(fog.New(), db)
    53  
    54  	command := "not-on-db"
    55  	mock.ExpectExec(datasql.DeleteCommand).WithArgs(command).WillReturnResult(sqlmock.NewResult(0, 0))
    56  
    57  	res, err := ds.DeleteCommand(context.Background(), command)
    58  	assert.NoError(t, err)
    59  	if err := mock.ExpectationsWereMet(); err != nil {
    60  		t.Errorf("there were unfulfilled expectations: %s", err)
    61  	}
    62  	assert.NotEmpty(t, res.Errors)
    63  	assert.Equal(t, rulesengine.UnknownCommand, res.Errors[0].Type)
    64  	assert.Equal(t, int64(0), res.RowsAffected)
    65  }
    66  
    67  func TestDeleteCommandConflict(t *testing.T) {
    68  	db, mock := initMockDB(t)
    69  	defer db.Close()
    70  	ds := New(fog.New(), db)
    71  
    72  	command := "ls"
    73  	mock.ExpectExec(datasql.DeleteCommand).WithArgs(command).WillReturnError(&pgconn.PgError{Code: "23503"})
    74  
    75  	res, err := ds.DeleteCommand(context.Background(), command)
    76  	assert.NoError(t, err)
    77  	if err := mock.ExpectationsWereMet(); err != nil {
    78  		t.Errorf("there were unfulfilled expectations: %s", err)
    79  	}
    80  	assert.NotEmpty(t, res.Errors)
    81  	assert.Equal(t, rulesengine.Conflict, res.Errors[0].Type)
    82  	assert.Equal(t, res.RowsAffected, int64(0))
    83  }
    84  
    85  func TestReadCommand(t *testing.T) {
    86  	db, mock := initMockDB(t)
    87  	defer db.Close()
    88  	ds := New(fog.New(), db)
    89  
    90  	mockRow := sqlmock.NewRows([]string{"command_id", "name"}).AddRow("test", "ls")
    91  	mock.ExpectQuery(datasql.SelectCommandByName).WithArgs("ls").WillReturnRows(mockRow)
    92  
    93  	res, err := ds.ReadCommand(context.Background(), "ls")
    94  	assert.NoError(t, err)
    95  	assert.EqualValues(t, rulesengine.Command{Name: "ls", ID: "test"}, res)
    96  	if err := mock.ExpectationsWereMet(); err != nil {
    97  		t.Errorf("there were unfulfilled expectations: %s", err)
    98  	}
    99  }
   100  
   101  func TestReadAllCommands(t *testing.T) {
   102  	db, mock := initMockDB(t)
   103  	defer db.Close()
   104  	ds := New(fog.New(), db)
   105  
   106  	mockRow := sqlmock.NewRows([]string{"command_id", "name"}).AddRow("test", "ls")
   107  	mock.ExpectQuery(datasql.SelectAllCommands).WillReturnRows(mockRow)
   108  
   109  	res, err := ds.ReadAllCommands(context.Background())
   110  	assert.EqualValues(t, []rulesengine.Command{{Name: "ls", ID: "test"}}, res)
   111  	assert.NoError(t, err)
   112  	if err := mock.ExpectationsWereMet(); err != nil {
   113  		t.Errorf("there were unfulfilled expectations: %s", err)
   114  	}
   115  }
   116  
   117  //nolint:dupl
   118  func TestReadCommandsWithFilter(t *testing.T) {
   119  	t.Parallel()
   120  
   121  	tests := map[string]struct {
   122  		args         []string
   123  		mockRowsFunc func(mock sqlmock.Sqlmock) *sqlmock.ExpectedQuery
   124  		expectedRes  []rulesengine.Command
   125  	}{
   126  		"All Valid": {
   127  			args: []string{"name1", "name2", "name3"},
   128  			mockRowsFunc: func(mock sqlmock.Sqlmock) *sqlmock.ExpectedQuery {
   129  				mockRows := sqlmock.NewRows([]string{"command_id", "name"}).AddRow("id1", "name1").AddRow("id2", "name2").AddRow("id3", "name3")
   130  				return mock.ExpectQuery(datasql.SelectCommandsByName).WithArgs([]string{"name1", "name2", "name3"}).WillReturnRows(mockRows)
   131  			},
   132  			expectedRes: []rulesengine.Command{
   133  				{ID: "id1", Name: "name1"},
   134  				{ID: "id2", Name: "name2"},
   135  				{ID: "id3", Name: "name3"},
   136  			},
   137  		},
   138  		"No Rows Returned": {
   139  			args: []string{"nonexistant1", "nonexistant2", "nonexistant3"},
   140  			mockRowsFunc: func(mock sqlmock.Sqlmock) *sqlmock.ExpectedQuery {
   141  				mockRows := sqlmock.NewRows([]string{"command_id", "name"})
   142  				return mock.ExpectQuery(datasql.SelectCommandsByName).WithArgs([]string{"nonexistant1", "nonexistant2", "nonexistant3"}).WillReturnRows(mockRows)
   143  			},
   144  		},
   145  		"Some Valid": {
   146  			args: []string{"name1", "nonexistant2", "name3"},
   147  			mockRowsFunc: func(mock sqlmock.Sqlmock) *sqlmock.ExpectedQuery {
   148  				mockRows := sqlmock.NewRows([]string{"command_id", "name"}).AddRow("id1", "name1").AddRow("id3", "name3")
   149  				return mock.ExpectQuery(datasql.SelectCommandsByName).WithArgs([]string{"name1", "nonexistant2", "name3"}).WillReturnRows(mockRows)
   150  			},
   151  			expectedRes: []rulesengine.Command{
   152  				{ID: "id1", Name: "name1"},
   153  				{ID: "id3", Name: "name3"},
   154  			},
   155  		},
   156  		"No Filter Passed In": {
   157  			mockRowsFunc: func(mock sqlmock.Sqlmock) *sqlmock.ExpectedQuery {
   158  				mockRows := sqlmock.NewRows([]string{"command_id", "name"}).AddRow("all", "all")
   159  				return mock.ExpectQuery(datasql.SelectAllCommands).WillReturnRows(mockRows)
   160  			},
   161  			expectedRes: []rulesengine.Command{
   162  				{ID: "all", Name: "all"},
   163  			},
   164  		},
   165  	}
   166  
   167  	for name, tc := range tests {
   168  		tc := tc
   169  		t.Run(name, func(t *testing.T) {
   170  			t.Parallel()
   171  
   172  			db, mock, err := sqlmock.New(sqlmock.QueryMatcherOption(sqlmock.QueryMatcherEqual), sqlmock.ValueConverterOption(StringSliceValueConverter{}))
   173  			require.NoError(t, err, "an error '%s' was not expected when opening a stub database connection", err)
   174  			defer db.Close()
   175  
   176  			ds := New(fog.New(), db)
   177  			tc.mockRowsFunc(mock)
   178  
   179  			res, err := ds.ReadCommandsWithFilter(context.Background(), tc.args)
   180  
   181  			assert.EqualValues(t, tc.expectedRes, res)
   182  			assert.NoError(t, err)
   183  			if err := mock.ExpectationsWereMet(); err != nil {
   184  				t.Errorf("there were unfulfilled expectations: %s", err)
   185  			}
   186  		})
   187  	}
   188  }
   189  

View as plain text