Skip to content
Open
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions go.work.sum
Original file line number Diff line number Diff line change
Expand Up @@ -1156,6 +1156,7 @@ github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An
github.com/spiffe/go-spiffe/v2 v2.5.0 h1:N2I01KCUkv1FAjZXJMwh95KK1ZIQLYbPfhaxw8WS0hE=
github.com/spiffe/go-spiffe/v2 v2.5.0/go.mod h1:P+NxobPc6wXhVtINNtFjNWGBTreew1GBUCwT2wPmb7g=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/testcontainers/testcontainers-go v0.28.0 h1:1HLm9qm+J5VikzFDYhOd+Zw12NtOl+8drH2E8nTY1r8=
github.com/testcontainers/testcontainers-go v0.28.0/go.mod h1:COlDpUXbwW3owtpMkEB1zo9gwb1CoKVKlyrVPejF4AU=
github.com/testcontainers/testcontainers-go v0.33.0 h1:zJS9PfXYT5O0ZFXM2xxXfk4J5UMw/kRiISng037Gxdw=
Expand Down Expand Up @@ -1256,6 +1257,8 @@ golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ss
golang.org/x/crypto v0.33.0/go.mod h1:bVdXmD7IV/4GdElGPozy6U7lWdRXA4qyRVGJV57uQ5M=
golang.org/x/crypto v0.36.0/go.mod h1:Y4J0ReaxCR1IMaabaSMugxJES1EpwhBHhv2bDHklZvc=
golang.org/x/crypto v0.38.0/go.mod h1:MvrbAqul58NNYPKnOra203SB9vpuZW0e+RRZV+Ggqjw=
golang.org/x/crypto v0.41.0 h1:WKYxWedPGCTVVl5+WHSSrOBT0O8lx32+zxmHxijgXp4=
golang.org/x/crypto v0.41.0/go.mod h1:pO5AFd7FA68rFak7rOAGVuygIISepHftHnr8dr6+sUc=
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek=
Expand Down Expand Up @@ -1291,6 +1294,8 @@ golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/mod v0.18.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/mod v0.19.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/mod v0.24.0/go.mod h1:IXM97Txy2VM4PJ3gI61r1YEk/gAj6zAHN3AdZt6S9Ww=
golang.org/x/mod v0.25.0/go.mod h1:IXM97Txy2VM4PJ3gI61r1YEk/gAj6zAHN3AdZt6S9Ww=
golang.org/x/mod v0.26.0/go.mod h1:/j6NAhSk8iQ723BGAUyoAcn7SlD7s15Dp9Nd/SfeaFQ=
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
Expand Down Expand Up @@ -1324,6 +1329,8 @@ golang.org/x/net v0.34.0/go.mod h1:di0qlW3YNM5oh6GqDGQr92MyTozJPmybPK4Ev/Gm31k=
golang.org/x/net v0.35.0/go.mod h1:EglIi67kWsHKlRzzVMUD93VMSWGFOMSZgxFjparz1Qk=
golang.org/x/net v0.37.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8=
golang.org/x/net v0.41.0/go.mod h1:B/K4NNqkfmg07DQYrbwvSluqCJOOXwUjeb/5lOisjbA=
golang.org/x/net v0.43.0 h1:lat02VYK2j4aLzMzecihNvTlJNQUq316m2Mr9rnM6YE=
golang.org/x/net v0.43.0/go.mod h1:vhO1fvI4dGsIjh73sWfUVjj3N7CA9WkKJNQm2svM6Jg=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
Expand All @@ -1349,6 +1356,7 @@ golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sync v0.12.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
golang.org/x/sync v0.13.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
golang.org/x/sync v0.14.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
golang.org/x/sync v0.15.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
Expand Down Expand Up @@ -1389,6 +1397,7 @@ golang.org/x/telemetry v0.0.0-20240521205824-bda55230c457 h1:zf5N6UOrA487eEFacMe
golang.org/x/telemetry v0.0.0-20240521205824-bda55230c457/go.mod h1:pRgIJT+bRLFKnoM1ldnzKoxTIn14Yxz928LQRYYgIN0=
golang.org/x/telemetry v0.0.0-20250710130107-8d8967aff50b h1:DU+gwOBXU+6bO0sEyO7o/NeMlxZxCZEvI7v+J4a1zRQ=
golang.org/x/telemetry v0.0.0-20250710130107-8d8967aff50b/go.mod h1:4ZwOYna0/zsOKwuR5X/m0QFOJpSZvAxFfkQT+Erd9D4=
golang.org/x/telemetry v0.0.0-20250807160809-1a19826ec488/go.mod h1:fGb/2+tgXXjhjHsTNdVEEMZNWA0quBnfrO+AfoDSAKw=
golang.org/x/term v0.31.0/go.mod h1:R4BeIy7D95HzImkxGkTW1UQTtP54tio2RyHz7PwK0aw=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
Expand Down Expand Up @@ -1449,6 +1458,8 @@ golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk=
golang.org/x/tools v0.22.0/go.mod h1:aCwcsjqvq7Yqt6TNyX7QMU2enbQ/Gt0bo6krSeEri+c=
golang.org/x/tools v0.23.0/go.mod h1:pnu6ufv6vQkll6szChhK3C3L/ruaIv5eBeztNG8wtsI=
golang.org/x/tools v0.34.0/go.mod h1:pAP9OwEaY1CAW3HOmg3hLZC5Z0CCmzjAF2UQMSqNARg=
golang.org/x/tools v0.35.0/go.mod h1:NKdj5HkL/73byiZSJjqJgKn3ep7KjFkBOkR/Hps3VPw=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da h1:noIWHXmPHxILtqtCOPIhSt0ABwskkZKjD3bXGnZGpNY=
golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da/go.mod h1:NDW/Ps6MPRej6fsCIbMTohpP40sJ/P/vI1MoTEGwX90=
Expand Down
Empty file.
1 change: 1 addition & 0 deletions pkg/gofr/datasource/file/temp.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Name,Age,Email
1 change: 1 addition & 0 deletions pkg/gofr/datasource/file/temp.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
!@#$%^&*
1 change: 1 addition & 0 deletions pkg/gofr/datasource/file/temp.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
some new content
1 change: 1 addition & 0 deletions pkg/gofr/migration/datasource.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ type Datasource struct {
Redis Redis
PubSub PubSub
Clickhouse Clickhouse
Oracle Oracle
Cassandra Cassandra
Mongo Mongo
ArangoDB ArangoDB
Expand Down
7 changes: 7 additions & 0 deletions pkg/gofr/migration/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,13 @@ type Clickhouse interface {
HealthCheck(ctx context.Context) (any, error)
}

type Oracle interface {
Select(ctx context.Context, dest any, query string, args ...any) error
Exec(ctx context.Context, query string, args ...any) error

HealthCheck(ctx context.Context) (any, error)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this method needed for migrations?

Copy link
Contributor Author

@Samar1110 Samar1110 Aug 29, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added the HealthCheck(ctx context.Context) (any, error) method to the Oracle interface in the migration package to align it with the OracleDB interface defined in the container package. Without this method, the *MockOracle generated for testing cannot be used as a container.OracleDB value, causing the compiler error:

"cannot use mockOracle (variable of type *MockOracle) as container.OracleDB value in assignment: *MockOracle does not implement container.OracleDB (missing method HealthCheck)".

As I am using

mockContainer.Oracle = mockOracle

in some functions, it takes the reference from pkg/gofr/container/datasource.go, which requires the HealthCheck method for compatibility. To resolve this, I have added the HealthCheck method in pkg/gofr/migration/interface.go.

By adding the HealthCheck method, the mock satisfies the interface requirements, ensuring type compatibility and eliminating this assignment error.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Samar1110 I agree but if you notice many of the interfaces like SQL, Redis, Mongo, ArrangoDB etc all have HealthCheck() method not implemented yet they align with their interface definition in container.

You can see how their test have been written or implemented.

}

type Cassandra interface {
Exec(query string, args ...any) error
NewBatch(name string, batchType int) error
Expand Down
11 changes: 9 additions & 2 deletions pkg/gofr/migration/migration.go
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,13 @@ func initializeDatasources(c *container.Container, ds *Datasource, mg migrator)
apply: func(m migrator) migrator { return clickHouseDS{ds.Clickhouse}.apply(m) },
logIdentifier: "Clickhouse",
},
{
condition: func() bool { return !isNil(c.Oracle) },
setDS: func() { ds.Oracle = c.Oracle },
apply: func(m migrator) migrator { return oracleDS{c.Oracle}.apply(m) },
logIdentifier: "Oracle",
},

{
condition: func() bool { return c.PubSub != nil },
setDS: func() { ds.PubSub = c.PubSub },
Expand Down Expand Up @@ -223,9 +230,9 @@ func initializeDatasources(c *container.Container, ds *Datasource, mg migrator)
}

func isNil(i any) bool {
// Get the value of the interface
// Get the value of the interface.
val := reflect.ValueOf(i)

// If the interface is not assigned or is nil, return true
// If the interface is not assigned or is nil, return true.
return !val.IsValid() || val.IsNil()
}
128 changes: 128 additions & 0 deletions pkg/gofr/migration/migration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package migration
import (
"database/sql"
"testing"
"time"

"github.com/stretchr/testify/assert"
"go.uber.org/mock/gomock"
Expand Down Expand Up @@ -207,3 +208,130 @@ func initializeClickHouseRunMocks(t *testing.T) (*MockClickhouse, *container.Con

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the method initializeClickHouseRunMocks we need to mark Oracle as nil else it's tests will fail.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure , I will mark it as nil

return mockClickHouse, mockContainer
}

func TestOracleMigration_RunMigrationSuccess(t *testing.T) {
mockOracle, mockContainer := initializeOracleRunMocks(t)

ds := Datasource{Oracle: mockOracle}
od := oracleDS{Oracle: mockOracle}
_ = od.apply(&ds) // apply migrator wrapper.

migrationMap := map[int64]Migrate{
1: {UP: func(d Datasource) error {
return d.Oracle.Exec(t.Context(), "CREATE TABLE test (id INT)")
}},
}

mockOracle.EXPECT().Exec(gomock.Any(), CheckAndCreateOracleMigrationTable).Return(nil)
mockOracle.EXPECT().Select(gomock.Any(), gomock.Any(), getLastOracleGoFrMigration).Return(nil)
mockOracle.EXPECT().Exec(gomock.Any(), "CREATE TABLE test (id INT)").Return(nil)
mockOracle.EXPECT().Exec(gomock.Any(), insertOracleGoFrMigrationRow, int64(1), "UP", gomock.Any(), gomock.Any()).Return(nil)

Run(migrationMap, mockContainer)
}

func TestOracleMigration_FailCreateMigrationTable(t *testing.T) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The tests for Oracle Migration should be placed inside oracle_test.go not here.

Copy link
Contributor Author

@Samar1110 Samar1110 Aug 29, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do I need to shift only this test -> TestOracleMigration_FailCreateMigrationTable or all test related to Oracle migration in this file to oracle_test.go ?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should place all test related to Oracle migration in this file to oracle_test.go

ctrl := gomock.NewController(t)
defer ctrl.Finish()

mockOracle := NewMockOracle(ctrl)
mockContainer, _ := container.NewMockContainer(t)
mockContainer.Oracle = mockOracle

ds := Datasource{Oracle: mockOracle}
od := oracleDS{Oracle: mockOracle}
mg := od.apply(&ds)

mockOracle.EXPECT().Exec(gomock.Any(), CheckAndCreateOracleMigrationTable).Return(sql.ErrConnDone)

err := mg.checkAndCreateMigrationTable(mockContainer)
assert.Equal(t, sql.ErrConnDone, err)
}

func TestOracleMigration_GetLastMigration_ReturnsZeroOnError(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()

mockOracle := NewMockOracle(ctrl)
mockContainer, _ := container.NewMockContainer(t)
mockContainer.Oracle = mockOracle

ds := Datasource{Oracle: mockOracle}
od := oracleDS{Oracle: mockOracle}
mg := od.apply(&ds)

mockOracle.EXPECT().Select(gomock.Any(), gomock.Any(), getLastOracleGoFrMigration).Return(sql.ErrConnDone)

lastMigration := mg.getLastMigration(mockContainer)
assert.Equal(t, int64(0), lastMigration)
}

func TestOracleMigration_CommitMigration(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()

mockOracle := NewMockOracle(ctrl)
mockContainer, _ := container.NewMockContainer(t)
mockContainer.Oracle = mockOracle

ds := Datasource{Oracle: mockOracle}
od := oracleDS{Oracle: mockOracle}
mg := od.apply(&ds)

td := transactionData{
StartTime: time.Now(),
MigrationNumber: 42,
}

mockOracle.EXPECT().
Exec(gomock.Any(), insertOracleGoFrMigrationRow,
td.MigrationNumber, "UP", td.StartTime, gomock.Any()).
Return(nil)

err := mg.commitMigration(mockContainer, td)
assert.NoError(t, err)
}

func TestOracleMigration_BeginTransaction_Logs(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()

mockOracle := NewMockOracle(ctrl)
mockContainer, _ := container.NewMockContainer(t)
mockContainer.Logger = logging.NewLogger(logging.DEBUG)
mockContainer.Oracle = mockOracle

ds := Datasource{Oracle: mockOracle}
od := oracleDS{Oracle: mockOracle}
mg := od.apply(&ds)

// Capture logs or just call method and rely on it not panicking.
mg.beginTransaction(mockContainer)
}

func initializeOracleRunMocks(t *testing.T) (*MockOracle, *container.Container) {
t.Helper()

mockOracle := NewMockOracle(gomock.NewController(t))
mockContainer, _ := container.NewMockContainer(t)

// Disable all other datasources by setting to nil.
mockContainer.SQL = nil
mockContainer.Redis = nil
mockContainer.Mongo = nil
mockContainer.Cassandra = nil
mockContainer.PubSub = nil
mockContainer.ArangoDB = nil
mockContainer.SurrealDB = nil
mockContainer.DGraph = nil
mockContainer.Elasticsearch = nil
mockContainer.OpenTSDB = nil
mockContainer.ScyllaDB = nil
mockContainer.Clickhouse = nil

// Initialize Oracle mock and Logger.
mockContainer.Oracle = mockOracle
mockContainer.Logger = logging.NewMockLogger(logging.DEBUG)

return mockOracle, mockContainer
}
78 changes: 78 additions & 0 deletions pkg/gofr/migration/mock_interface.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading