diff --git a/Earthfile b/Earthfile index 3ca155ed..8d33e254 100644 --- a/Earthfile +++ b/Earthfile @@ -5,6 +5,9 @@ IMPORT github.com/formancehq/earthly:tags/v0.16.2 AS core FROM core+base-image +postgres: + FROM postgres:15-alpine + sources: WORKDIR src WORKDIR /src @@ -60,11 +63,25 @@ build-image: DO core+SAVE_IMAGE --COMPONENT=payments --REPOSITORY=${REPOSITORY} --TAG=$tag tests: - FROM core+builder-image + FROM +tidy COPY (+sources/*) /src WORKDIR /src - WITH DOCKER --pull=postgres:15-alpine - DO --pass-args core+GO_TESTS + ARG includeIntegrationTests="true" + + ENV CGO_ENABLED=1 # required for -race + + LET goFlags="-race" + IF [ "$includeIntegrationTests" = "true" ] + COPY (+compile-configs/configs.json) /src/internal/connectors/plugins/configs.json + COPY (+compile-plugins/list.go) /src/internal/connectors/plugins/public/list.go + SET goFlags="$goFlags -tags it" + WITH DOCKER --load=postgres:15-alpine=+postgres + RUN go test $goFlags ./... + END + ELSE + WITH DOCKER --pull=postgres:15-alpine + DO --pass-args +GO_TESTS + END END deploy: @@ -104,6 +121,7 @@ tidy: FROM core+builder-image COPY --pass-args (+sources/src) /src WORKDIR /src + COPY --dir test . DO --pass-args core+GO_TIDY generate: diff --git a/go.mod b/go.mod index 4cb2465c..3fc02269 100644 --- a/go.mod +++ b/go.mod @@ -147,11 +147,14 @@ require ( github.com/mailru/easyjson v0.7.7 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.20 // indirect + github.com/minio/highwayhash v1.0.3 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/moby/docker-image-spec v1.3.1 // indirect github.com/moby/term v0.5.0 // indirect github.com/muhlemmer/gu v0.3.1 // indirect github.com/muhlemmer/httpforwarded v0.1.0 // indirect + github.com/nats-io/jwt/v2 v2.7.0 // indirect + github.com/nats-io/nats-server/v2 v2.10.22 // indirect github.com/nats-io/nkeys v0.4.7 // indirect github.com/nats-io/nuid v1.0.1 // indirect github.com/nexus-rpc/sdk-go v0.0.11 // indirect diff --git a/go.sum b/go.sum index 77cabab8..8bc9e18e 100644 --- a/go.sum +++ b/go.sum @@ -1598,6 +1598,7 @@ golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.27.0 h1:wBqf8DvsY9Y/2P8gAfPDEYNuS30J4lPHJxXSb/nJZ+s= golang.org/x/sys v0.27.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= diff --git a/internal/storage/connectors.go b/internal/storage/connectors.go index f2006226..e0715295 100644 --- a/internal/storage/connectors.go +++ b/internal/storage/connectors.go @@ -51,6 +51,11 @@ func (s *store) ListenConnectorsChanges(ctx context.Context, handlers HandlerCon if err != nil { return errors.Wrap(err, "cannot get connection") } + + s.rwMutex.Lock() + s.conns = append(s.conns, conn) + s.rwMutex.Unlock() + if err := conn.Raw(func(driverConn any) error { listener := pgxlisten.Listener{ Connect: func(ctx context.Context) (*pgx.Conn, error) { diff --git a/internal/storage/module.go b/internal/storage/module.go index 8db90ce3..4fd5063a 100644 --- a/internal/storage/module.go +++ b/internal/storage/module.go @@ -1,6 +1,8 @@ package storage import ( + "context" + "github.com/formancehq/go-libs/v2/bun/bunconnect" "github.com/formancehq/go-libs/v2/logging" "github.com/formancehq/go-libs/v2/service" @@ -15,5 +17,12 @@ func Module(cmd *cobra.Command, connectionOptions bunconnect.ConnectionOptions, fx.Provide(func(logger logging.Logger, db *bun.DB) Storage { return newStorage(logger, db, configEncryptionKey) }), + fx.Invoke(func(s Storage, lc fx.Lifecycle) { + lc.Append(fx.Hook{ + OnStop: func(ctx context.Context) error { + return s.Close() + }, + }) + }), ) } diff --git a/internal/storage/storage.go b/internal/storage/storage.go index 479be1e0..85a54431 100644 --- a/internal/storage/storage.go +++ b/internal/storage/storage.go @@ -2,6 +2,7 @@ package storage import ( "context" + "sync" "time" "github.com/formancehq/go-libs/v2/bun/bunpaginate" @@ -142,6 +143,9 @@ type store struct { logger logging.Logger db *bun.DB configEncryptionKey string + + conns []bun.Conn + rwMutex sync.RWMutex } func newStorage(logger logging.Logger, db *bun.DB, configEncryptionKey string) Storage { @@ -153,5 +157,18 @@ func newStorage(logger logging.Logger, db *bun.DB, configEncryptionKey string) S } func (s *store) Close() error { - return s.db.Close() + s.rwMutex.Lock() + defer s.rwMutex.Unlock() + + if err := s.db.Close(); err != nil { + return err + } + + for _, conn := range s.conns { + if err := conn.Close(); err != nil { + return err + } + } + + return nil } diff --git a/pkg/testserver/server.go b/pkg/testserver/server.go index 1901da6c..2d297df9 100644 --- a/pkg/testserver/server.go +++ b/pkg/testserver/server.go @@ -11,6 +11,8 @@ import ( "github.com/nats-io/nats.go" + _ "github.com/formancehq/payments/internal/connectors/plugins/public" + "github.com/formancehq/go-libs/v2/otlp" "github.com/formancehq/go-libs/v2/otlp/otlpmetrics" "github.com/formancehq/go-libs/v2/publish" diff --git a/test/e2e/api_bank_accounts_test.go b/test/e2e/api_bank_accounts_test.go index 3601cf2a..fb67bb32 100644 --- a/test/e2e/api_bank_accounts_test.go +++ b/test/e2e/api_bank_accounts_test.go @@ -12,7 +12,6 @@ import ( "github.com/formancehq/payments/internal/models" "github.com/google/uuid" - "github.com/formancehq/payments/pkg/testserver" . "github.com/formancehq/payments/pkg/testserver" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" @@ -28,10 +27,10 @@ var _ = Context("Payments API Bank Accounts", func() { createRequest v3.BankAccountsCreateRequest v2createRequest v2.BankAccountsCreateRequest - app *utils.Deferred[*testserver.Server] + app *utils.Deferred[*Server] ) - app = testserver.NewTestServer(func() Configuration { + app = NewTestServer(func() Configuration { return Configuration{ Stack: stack, PostgresConfiguration: db.GetValue().ConnectionOptions(),