Skip to content

Commit

Permalink
add more unit tests
Browse files Browse the repository at this point in the history
Signed-off-by: Wojciech Sadowy <wojciech.sadowy@freedomfi.com>
  • Loading branch information
Wojciech Sadowy committed Apr 7, 2022
1 parent 014a4b9 commit e428c9b
Show file tree
Hide file tree
Showing 7 changed files with 281 additions and 25 deletions.
49 changes: 49 additions & 0 deletions dp/cloud/go/services/dp/obsidian/cbsd/handlers_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,30 @@ func (s *HandlersTestSuite) TestCreateCbsd() {
tests.RunUnitTest(s.T(), e, tc)
}

func (s *HandlersTestSuite) TestCreateWithDuplicateUniqueFieldsReturnsConflict() {
e := echo.New()
obsidianHandlers := cbsd.GetHandlers()
payload := createOrUpdateCbsdPayload()
const errMsg = "some error"
s.cbsdServer.err = status.Error(codes.AlreadyExists, errMsg)
s.cbsdServer.expectedCreateRequest = &protos.CreateCbsdRequest{
NetworkId: "n1",
Data: models.CbsdToBackend(payload),
}
createCbsd := tests.GetHandlerByPathAndMethod(s.T(), obsidianHandlers, cbsd.ManageCbsdsPath, obsidian.POST).HandlerFunc
tc := tests.Test{
Method: http.MethodPost,
URL: "/magma/v1/dp/n1/cbsds",
Payload: payload,
ParamNames: []string{"network_id"},
ParamValues: []string{"n1"},
Handler: createCbsd,
ExpectedStatus: http.StatusConflict,
ExpectedErrorSubstring: "some error",
}
tests.RunUnitTest(s.T(), e, tc)
}

func (s *HandlersTestSuite) TestCreateCbsdWithoutAllRequiredParams() {
e := echo.New()
obsidianHandlers := cbsd.GetHandlers()
Expand Down Expand Up @@ -407,6 +431,31 @@ func (s *HandlersTestSuite) TestUpdateNonexistentCbsd() {
tests.RunUnitTest(s.T(), e, tc)
}

func (s *HandlersTestSuite) TestUpdateCbsdWithDuplicateUniqueFieldsReturnsConflict() {
e := echo.New()
obsidianHandlers := cbsd.GetHandlers()
payload := createOrUpdateCbsdPayload()
const errMsg = "some error"
s.cbsdServer.err = status.Error(codes.AlreadyExists, errMsg)
s.cbsdServer.expectedUpdateRequest = &protos.UpdateCbsdRequest{
NetworkId: "n1",
Id: 1,
Data: models.CbsdToBackend(payload),
}
updateCbsd := tests.GetHandlerByPathAndMethod(s.T(), obsidianHandlers, cbsd.ManageCbsdPath, obsidian.PUT).HandlerFunc
tc := tests.Test{
Method: http.MethodPost,
URL: "/magma/v1/dp/n1/cbsds/1",
Payload: payload,
ParamNames: []string{"network_id", "cbsd_id"},
ParamValues: []string{"n1", "1"},
Handler: updateCbsd,
ExpectedStatus: http.StatusConflict,
ExpectedErrorSubstring: "some error",
}
tests.RunUnitTest(s.T(), e, tc)
}

func (s *HandlersTestSuite) TestGetPagination() {
testCases := []struct {
testName string
Expand Down
29 changes: 29 additions & 0 deletions dp/cloud/go/services/dp/servicers/cbsd_manager_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,20 @@ func (s *CbsdManagerTestSuite) TestCreateCbsd() {
s.Assert().Equal(getDBCbsd(), s.store.data)
}

func (s *CbsdManagerTestSuite) TestCreateWithDuplicateData() {
s.store.err = merrors.ErrAlreadyExists

request := &protos.CreateCbsdRequest{
NetworkId: networkId,
Data: getProtoCbsd(),
}
_, err := s.manager.CreateCbsd(context.Background(), request)
s.Require().Error(err)

errStatus, _ := status.FromError(err)
s.Assert().Equal(codes.AlreadyExists, errStatus.Code())
}

func (s *CbsdManagerTestSuite) TestUpdateCbsd() {
request := &protos.UpdateCbsdRequest{
NetworkId: networkId,
Expand Down Expand Up @@ -101,6 +115,21 @@ func (s *CbsdManagerTestSuite) TestUpdateNonexistentCbsd() {
s.Assert().Equal(codes.NotFound, errStatus.Code())
}

func (s *CbsdManagerTestSuite) TestUpdateWithDuplicateData() {
s.store.err = merrors.ErrAlreadyExists

request := &protos.UpdateCbsdRequest{
NetworkId: networkId,
Id: cbsdId,
Data: getProtoCbsd(),
}
_, err := s.manager.UpdateCbsd(context.Background(), request)
s.Require().Error(err)

errStatus, _ := status.FromError(err)
s.Assert().Equal(codes.AlreadyExists, errStatus.Code())
}

func (s *CbsdManagerTestSuite) TestDeleteCbsd() {
request := &protos.DeleteCbsdRequest{
NetworkId: networkId,
Expand Down
46 changes: 45 additions & 1 deletion dp/cloud/go/services/dp/storage/db/query_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ func (s *QueryTestSuite) SetupSuite() {
database, err := sqorc.Open("sqlite3", ":memory:")
s.Require().NoError(err)
s.resourceManager = dbtest.NewResourceManager(s.T(), database, builder)
err = s.resourceManager.CreateTables(&someModel{}, &otherModel{}, &anotherModel{})
err = s.resourceManager.CreateTables(&someModel{}, &otherModel{}, &anotherModel{}, &modelWithUniqueFields{})
s.Require().NoError(err)
}

Expand Down Expand Up @@ -75,6 +75,11 @@ func (s *QueryTestSuite) TestCreate() {
fieldMask: db.NewExcludeMask("default_value"),
input: &anotherModel{id: db.MakeInt(id * 3)},
expected: &anotherModel{id: db.MakeInt(id * 3), defaultValue: db.MakeInt(defaultValue)},
}, {
name: "Should create resource with unique fields",
fieldMask: db.NewExcludeMask(),
input: getModelWithUniqueFields(),
expected: getModelWithUniqueFields(),
}}
for _, tt := range testCases {
s.Run(tt.name, s.inTransaction(func() {
Expand Down Expand Up @@ -616,6 +621,45 @@ func (a *anotherModel) Fields() db.FieldMap {
}
}

func getModelWithUniqueFields() *modelWithUniqueFields {
return &modelWithUniqueFields{
id: db.MakeInt(id),
uniqueField: db.MakeInt(id + 1),
anotherUniqueFied: db.MakeInt(id + 2),
}
}

type modelWithUniqueFields struct {
id sql.NullInt64
uniqueField sql.NullInt64
anotherUniqueFied sql.NullInt64
}

func (m *modelWithUniqueFields) GetMetadata() *db.ModelMetadata {
return &db.ModelMetadata{
Table: "unique_table",
CreateObject: func() db.Model {
return &modelWithUniqueFields{}
},
}
}

func (m *modelWithUniqueFields) Fields() db.FieldMap {
return db.FieldMap{
"id": &db.Field{
BaseType: db.IntType{X: &m.id},
},
"unique_field": &db.Field{
BaseType: db.IntType{X: &m.uniqueField},
Unique: true,
},
"another_unique_fied": &db.Field{
BaseType: db.IntType{X: &m.anotherUniqueFied},
Unique: true,
},
}
}

func makeRelationsMap(table string) map[string]string {
return map[string]string{table: table + "_id"}
}
11 changes: 7 additions & 4 deletions dp/cloud/python/magma/test_runner/tests/test_dp_with_orc8r.py
Original file line number Diff line number Diff line change
Expand Up @@ -126,10 +126,8 @@ def test_creating_cbsd_with_the_same_unique_fields_returns_409(self):
def test_updating_cbsd_returns_409_when_setting_existing_serial_num(self):
builder = CbsdAPIDataBuilder()

cbsd1_payload = builder.build_post_data()
cbsd2_payload = builder.build_post_data()
cbsd1_payload["serial_number"] = "foo"
cbsd2_payload["serial_number"] = "bar"
cbsd1_payload = builder.build_post_data_with_serial_number("foo")
cbsd2_payload = builder.build_post_data_with_serial_number("bar")
self.when_cbsd_is_created(cbsd1_payload) # cbsd_id = 1
self.when_cbsd_is_created(cbsd2_payload) # cbsd_id = 2
self.when_cbsd_is_updated(
Expand Down Expand Up @@ -404,6 +402,11 @@ def build_post_data(self) -> Dict[str, Any]:
'user_id': USER_ID,
}

def build_post_data_with_serial_number(self, serial_number) -> Dict[str, Any]:
data = self.build_post_data()
data["serial_number"] = serial_number
return data

def build_unregistered_data(self) -> Dict[str, Any]:
data = self.build_post_data()
data.update({
Expand Down
19 changes: 0 additions & 19 deletions orc8r/cloud/go/sqorc/builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,25 +52,6 @@ func GetSqlBuilder() StatementBuilder {
}
}

// GetErrorChecker returns a squirrel Builder for the configured SQL dialect as
// found in the SQL_DIALECT env var.
func GetErrorChecker() ErrorChecker {
dialect, envFound := os.LookupEnv(SQLDialectEnv)
// Default to postgresql
if !envFound {
return PostgresErrorChecker{}
}

switch strings.ToLower(dialect) {
case PostgresDialect:
return PostgresErrorChecker{}
case SQLiteDialect:
return SQLiteErrorChecker{}
default:
panic(fmt.Sprintf("unsupported sql dialect %s", dialect))
}
}

// StatementBuilder is an interface which tracks squirrel's
// StatementBuilderType with the difference that Insert returns this package's
// InsertBuilder interface type.
Expand Down
25 changes: 24 additions & 1 deletion orc8r/cloud/go/sqorc/error_checker.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
package sqorc

import (
"magma/orc8r/lib/go/merrors"
"fmt"
"os"
"strings"

"github.com/lib/pq"
"github.com/mattn/go-sqlite3"

"magma/orc8r/lib/go/merrors"
)

const (
Expand All @@ -19,6 +23,25 @@ type SQLiteErrorChecker struct{}

type PostgresErrorChecker struct{}

// GetErrorChecker returns a squirrel Builder for the configured SQL dialect as
// found in the SQL_DIALECT env var.
func GetErrorChecker() ErrorChecker {
dialect, envFound := os.LookupEnv(SQLDialectEnv)
// Default to postgresql
if !envFound {
return PostgresErrorChecker{}
}

switch strings.ToLower(dialect) {
case PostgresDialect:
return PostgresErrorChecker{}
case SQLiteDialect:
return SQLiteErrorChecker{}
default:
panic(fmt.Sprintf("unsupported sql dialect %s", dialect))
}
}

func (c SQLiteErrorChecker) GetError(err error) error {
if e, ok := err.(sqlite3.Error); ok {
switch e.Code {
Expand Down
127 changes: 127 additions & 0 deletions orc8r/cloud/go/sqorc/error_checker_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
package sqorc

import (
"os"
"testing"

"github.com/lib/pq"
"github.com/mattn/go-sqlite3"
"github.com/stretchr/testify/assert"

"magma/orc8r/lib/go/merrors"
)

const (
uniqueViolationNum = "23505"
otherPsqlErrorNum = "22011"
)

type customError struct{}

var _ error = customError{}

func (c customError) Error() string {
return "custom error message"
}

type sqliteGetErrorTestCase struct {
name string
checker ErrorChecker
err error
expectedError error
}

type psqlGetErrorTestCase struct {
name string
checker ErrorChecker
err error
expectedError error
}

func TestSQLiteErrorCheckerCreation(t *testing.T) {
_ = os.Setenv(SQLDialectEnv, SQLiteDialect)
c := GetErrorChecker()
assert.IsType(t, SQLiteErrorChecker{}, c)
}

func TestPostgresErrorCheckerCreation(t *testing.T) {
_ = os.Setenv(SQLDialectEnv, PostgresDialect)
c := GetErrorChecker()
assert.IsType(t, PostgresErrorChecker{}, c)
}

func TestErrorCheckerNotCreatedWithUnknownDialect(t *testing.T) {
_ = os.Setenv(SQLDialectEnv, "someOtherDialect")
assert.Panics(t, func() { GetErrorChecker() })
}

func TestErrorCheckerDefaultsToPostgres(t *testing.T) {
c := GetErrorChecker()
assert.IsType(t, PostgresErrorChecker{}, c)
}

func TestSQLiteGetError(t *testing.T) {
testCases := []sqliteGetErrorTestCase{
{
name: "test sqlite constraint error with SQLiteErrorChecker",
checker: SQLiteErrorChecker{},
err: sqlite3.Error{
Code: sqlite3.ErrConstraint,
},
expectedError: merrors.ErrAlreadyExists,
},
{
name: "test other sqlite error with SQLiteErrorChecker",
checker: SQLiteErrorChecker{},
err: sqlite3.Error{
Code: sqlite3.ErrNotFound,
},
expectedError: sqlite3.Error{},
},
{
name: "test any other error with SQLiteErrorChecker",
checker: SQLiteErrorChecker{},
err: customError{},
expectedError: customError{},
},
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
err := tc.checker.GetError(tc.err)
assert.IsType(t, tc.expectedError, err)
})
}
}

func TestPostgresGetError(t *testing.T) {
testCases := []psqlGetErrorTestCase{
{
name: "test postgres constraint error with PostgresErrorChecker",
checker: PostgresErrorChecker{},
err: &pq.Error{
Code: uniqueViolationNum,
},
expectedError: merrors.ErrAlreadyExists,
},
{
name: "test other postgres error with PostgresErrorChecker",
checker: PostgresErrorChecker{},
err: &pq.Error{
Code: otherPsqlErrorNum,
},
expectedError: &pq.Error{},
},
{
name: "test any other error with PostgresErrorChecker",
checker: PostgresErrorChecker{},
err: customError{},
expectedError: customError{},
},
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
err := tc.checker.GetError(tc.err)
assert.IsType(t, tc.expectedError, err)
})
}
}

0 comments on commit e428c9b

Please sign in to comment.