diff --git a/Makefile b/Makefile index faa0bc30..211b4c72 100644 --- a/Makefile +++ b/Makefile @@ -208,4 +208,12 @@ test-onchain: ${GOBIN} test -v -count 1 -tags="${BUILD_TAGS}" github.com/waku-org/go-waku/waku/v2/protocol/rln test-onchain-with-race: - ${GOBIN} test -race -v -count 1 -tags="${BUILD_TAGS}" github.com/waku-org/go-waku/waku/v2/protocol/rln \ No newline at end of file + ${GOBIN} test -race -v -count 1 -tags="${BUILD_TAGS}" github.com/waku-org/go-waku/waku/v2/protocol/rln + +test-postgres: PG_BUILD_TAGS = ${BUILD_TAGS} include_postgres_tests +test-postgres: + ${GOBIN} test -p 1 -v -count 1 -tags="${PG_BUILD_TAGS}" github.com/waku-org/go-waku/waku/persistence + +test-postgres-with-race: + ${GOBIN} test -race -p 1 -v -count 1 -tags="${PG_BUILD_TAGS}" github.com/waku-org/go-waku/waku/persistence + diff --git a/ci/Jenkinsfile.tests b/ci/Jenkinsfile.tests index 29e9b35e..d5a5e086 100644 --- a/ci/Jenkinsfile.tests +++ b/ci/Jenkinsfile.tests @@ -30,6 +30,8 @@ pipeline { environment { TARGET = 'tests' + DB_CONT = "status-go-test-db-${env.EXECUTOR_NUMBER.toInteger() + 1}" + DB_PORT = "${5432 + env.EXECUTOR_NUMBER.toInteger()}" REPO = "${env.WORKSPACE}/src/github.com/waku-org/go-waku" GOCACHE = "${env.WORKSPACE_TMP}/go-build" GOPATH = "${env.WORKSPACE}/go" @@ -58,6 +60,28 @@ pipeline { } } } } + stage('postgres tests') { + environment { + TEST_DB_PORT = "${env.DB_PORT}" + } + steps { script { + db = docker.image('postgres:9.6-alpine').withRun([ + "--name=${DB_CONT}", + "--env=POSTGRES_HOST_AUTH_METHOD=trust", + "--publish=${DB_PORT}:${DB_PORT}", + ].join(' '), "-p ${DB_PORT}") { c -> + if (params.RACE) { + nix.develop('make test-postgres-with-race', pure: false) + }else { + nix.develop('make test-postgres', pure: false) + } + } + } } + post { cleanup { /* Leftover DB containers. */ + sh "docker rm ${DB_CONT} || true" + } } + } + stage('Ganache') { steps { script { ganache = docker.image( diff --git a/waku/persistence/mock.go b/waku/persistence/mock.go new file mode 100644 index 00000000..183c3a3c --- /dev/null +++ b/waku/persistence/mock.go @@ -0,0 +1,54 @@ +package persistence + +import ( + "database/sql" + "fmt" + "log" + "os" + + _ "github.com/jackc/pgx/v5/stdlib" // Blank import to register the postgres driver +) + +// var dbUrlTemplate = "postgres://postgres@localhost:%s/%s?sslmode=disable" +var dbUrlTemplate = "postgres://harshjain@localhost:%s/%s?sslmode=disable" + +func ResetDefaultTestPostgresDB(dropDBUrl string) error { + db, err := sql.Open("postgres", dropDBUrl) + if err != nil { + return err + } + + deletePrevConnectionsSql := ` + SELECT pid, pg_terminate_backend(pid) + FROM pg_stat_activity + WHERE datname in ('template1', 'postgres') AND pid <> pg_backend_pid();` + _, err = db.Exec(deletePrevConnectionsSql) + if err != nil { + return err + } + + _, err = db.Exec("DROP DATABASE IF EXISTS postgres;") + if err != nil { + return err + } + + _, err = db.Exec("CREATE DATABASE postgres;") + return err +} + +func NewMockPgDB() *sql.DB { + mockPgDBPort := os.Getenv("TEST_DB_PORT") + + // + dropDBUrl := fmt.Sprintf(dbUrlTemplate, mockPgDBPort, "template1") + fmt.Println(dropDBUrl) + if err := ResetDefaultTestPostgresDB(dropDBUrl); err != nil { + log.Fatalf("an error '%s' was not expected when opening a stub database connection", err) + } + mockDBUrl := fmt.Sprintf(dbUrlTemplate, mockPgDBPort, "postgres") + db, err := sql.Open("pgx", mockDBUrl) + if err != nil { + log.Fatalf("an error '%s' was not expected when opening a stub database connection", err) + } + return db +} diff --git a/waku/persistence/postgres/postgres_test.go b/waku/persistence/postgres/postgres_test.go new file mode 100644 index 00000000..32ddc8dc --- /dev/null +++ b/waku/persistence/postgres/postgres_test.go @@ -0,0 +1,52 @@ +//go:build include_postgres_tests +// +build include_postgres_tests + +package postgres + +import ( + "testing" + + "github.com/stretchr/testify/require" + "github.com/waku-org/go-waku/waku/persistence" +) + +func TestQueries(t *testing.T) { + db := persistence.NewMockPgDB() + + queries, err := NewQueries("test_queries", db) + require.NoError(t, err) + + query := queries.Delete() + require.NotEmpty(t, query) + + query = queries.Exists() + require.NotEmpty(t, query) + + query = queries.Get() + require.NotEmpty(t, query) + + query = queries.Put() + require.NotEmpty(t, query) + + query = queries.Query() + require.NotEmpty(t, query) + + query = queries.Prefix() + require.NotEmpty(t, query) + + query = queries.Limit() + require.NotEmpty(t, query) + + query = queries.Offset() + require.NotEmpty(t, query) + + query = queries.GetSize() + require.NotEmpty(t, query) +} + +func TestCreateTable(t *testing.T) { + db := persistence.NewMockPgDB() + + err := CreateTable(db, "test_create_table") + require.NoError(t, err) +} diff --git a/waku/persistence/store_test.go b/waku/persistence/store_test.go index b1ecc52a..249d9772 100644 --- a/waku/persistence/store_test.go +++ b/waku/persistence/store_test.go @@ -1,3 +1,6 @@ +//go:build include_postgres_tests +// +build include_postgres_tests + package persistence import ( @@ -7,41 +10,31 @@ import ( "testing" "time" - "github.com/golang-migrate/migrate/v4/database/sqlite3" + "github.com/golang-migrate/migrate/v4/database/postgres" _ "github.com/mattn/go-sqlite3" // Blank import to register the sqlite3 driver "github.com/prometheus/client_golang/prometheus" "github.com/stretchr/testify/require" "github.com/waku-org/go-waku/tests" "github.com/waku-org/go-waku/waku/persistence/migrate" - sqlitemigrations "github.com/waku-org/go-waku/waku/persistence/sqlite/migrations" + postgresmigration "github.com/waku-org/go-waku/waku/persistence/postgres/migrations" "github.com/waku-org/go-waku/waku/v2/protocol" "github.com/waku-org/go-waku/waku/v2/protocol/store/pb" "github.com/waku-org/go-waku/waku/v2/timesource" "github.com/waku-org/go-waku/waku/v2/utils" - "go.uber.org/zap" ) func Migrate(db *sql.DB) error { - migrationDriver, err := sqlite3.WithInstance(db, &sqlite3.Config{ - MigrationsTable: "gowaku_" + sqlite3.DefaultMigrationsTable, + migrationDriver, err := postgres.WithInstance(db, &postgres.Config{ + MigrationsTable: "gowaku_" + postgres.DefaultMigrationsTable, }) if err != nil { return err } - return migrate.Migrate(db, migrationDriver, sqlitemigrations.AssetNames(), sqlitemigrations.Asset) -} - -func NewMock() *sql.DB { - db, err := sql.Open("sqlite3", ":memory:") - if err != nil { - utils.Logger().Fatal("opening a stub database connection", zap.Error(err)) - } - - return db + return migrate.Migrate(db, migrationDriver, postgresmigration.AssetNames(), postgresmigration.Asset) } func TestDbStore(t *testing.T) { - db := NewMock() + db := NewMockPgDB() store, err := NewDBStore(prometheus.DefaultRegisterer, utils.Logger(), WithDB(db), WithMigrations(Migrate)) require.NoError(t, err) @@ -61,7 +54,7 @@ func TestDbStore(t *testing.T) { } func TestStoreRetention(t *testing.T) { - db := NewMock() + db := NewMockPgDB() store, err := NewDBStore(prometheus.DefaultRegisterer, utils.Logger(), WithDB(db), WithMigrations(Migrate), WithRetentionPolicy(5, 20*time.Second)) require.NoError(t, err) @@ -104,7 +97,8 @@ func TestStoreRetention(t *testing.T) { } func TestQuery(t *testing.T) { - db := NewMock() + db := NewMockPgDB() + store, err := NewDBStore(prometheus.DefaultRegisterer, utils.Logger(), WithDB(db), WithMigrations(Migrate), WithRetentionPolicy(5, 20*time.Second)) require.NoError(t, err)