Skip to content

Commit

Permalink
Add main smoke test
Browse files Browse the repository at this point in the history
  • Loading branch information
yasuflatland-lf committed Jul 15, 2024
1 parent b95f33d commit 91c058d
Show file tree
Hide file tree
Showing 7 changed files with 178 additions and 65 deletions.
4 changes: 2 additions & 2 deletions backend/graph/schema.resolvers_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,13 +36,13 @@ func TestMain(m *testing.M) {
// Set up the test database
pg, cleanup, err := testutils.SetupTestDB(ctx, config.Cfg.PGUser, config.Cfg.PGPassword, config.Cfg.PGDBName)
if err != nil {
log.Fatalf("Failed to setup test database: %v", err)
log.Fatalf("Failed to setup test database: %+v", err)
}
defer cleanup(migrationFilePath)

// Run migrations
if err := pg.RunGooseMigrationsUp(migrationFilePath); err != nil {
log.Fatalf("failed to run migrations: %v", err)
log.Fatalf("failed to run migrations: %+v", err)
}

// Setup Echo server
Expand Down
61 changes: 10 additions & 51 deletions backend/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@ import (
"backend/pkg/repository"
"log"
"net/http"
"os"
"path/filepath"
"strconv"

"github.com/99designs/gqlgen/graphql/handler"
Expand All @@ -16,7 +14,6 @@ import (
"github.com/gorilla/websocket"
"github.com/labstack/echo/v4"
"github.com/labstack/echo/v4/middleware"
"gorm.io/gorm"
)

var migrationFilePath = "./db/migrations"
Expand All @@ -28,7 +25,16 @@ func main() {
e.Use(middleware.Recover())

// Initialize the database
db := initializeDatabase()
dbConfig := repository.DBConfig{
Host: config.Cfg.PGHost,
User: config.Cfg.PGUser,
Password: config.Cfg.PGPassword,
DBName: config.Cfg.PGDBName,
Port: config.Cfg.PGPort,
SSLMode: config.Cfg.PGSSLMode,
MigrationFilePath: migrationFilePath,
}
db := repository.InitializeDatabase(dbConfig)

// Create a new resolver with the database connection
resolver := &graph.Resolver{
Expand Down Expand Up @@ -65,50 +71,3 @@ func main() {

log.Printf("connect to http://localhost:%d/ for GraphQL playground", config.Cfg.Port)
}

// initializeDatabase encapsulates the database configuration and initialization logic
func initializeDatabase() *gorm.DB {
// Database configuration
dbConfig := repository.DBConfig{
Host: config.Cfg.PGHost,
User: config.Cfg.PGUser,
Password: config.Cfg.PGPassword,
DBName: config.Cfg.PGDBName,
Port: config.Cfg.PGPort,
SSLMode: config.Cfg.PGSSLMode,
}

// Initialize the Postgres instance
pg := repository.NewPostgres(dbConfig)

// Open the database connection
if err := pg.Open(); err != nil {
log.Fatalf("failed to connect to the database: %v", err)
}

// Get Full path to the migration DB file.
fullPath, err := getFullPath(migrationFilePath)
if err != nil {
log.Fatalf("Failed to get full path to the migration db file : %+v", err)
}

// Run migrations
log.Printf("Data Migration start ===============")
if err := pg.RunGooseMigrationsUp(fullPath); err != nil {
log.Fatalf("failed to run migrations: %v", err)
}
log.Printf("Data Migration Done ===============")

return pg.DB
}

// getFullPath takes a relative path and returns the full absolute path
func getFullPath(migrationFilePath string) (string, error) {
cleanedPath := filepath.Clean(migrationFilePath)
currentDir, err := os.Getwd()
if err != nil {
return "", err
}
fullPath := filepath.Join(currentDir, cleanedPath)
return fullPath, nil
}
97 changes: 97 additions & 0 deletions backend/main_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
package main

import (
"backend/graph"
"context"
"github.com/99designs/gqlgen/graphql/handler"
"github.com/99designs/gqlgen/graphql/handler/transport"
"github.com/99designs/gqlgen/graphql/playground"
"github.com/gorilla/websocket"
"github.com/labstack/echo/v4/middleware"
"net/http"
"net/http/httptest"
"os"
"testing"

"backend/pkg/config"
"backend/testutils"

"github.com/labstack/echo/v4"
"github.com/stretchr/testify/assert"
)

func TestMain(m *testing.M) {
// Set up the test environment
code := m.Run()
os.Exit(code)
}

func TestGraphQLServer(t *testing.T) {
ctx := context.Background()
user := "test"
password := "test"
dbName := "test"

// Setup the test database
pg, cleanup, err := testutils.SetupTestDB(ctx, user, password, dbName)
if err != nil {
t.Fatalf("Failed to set up test database: %+v", err)
}
defer cleanup(migrationFilePath)

// Run migrations
if err := pg.RunGooseMigrationsUp(migrationFilePath); err != nil {
t.Fatalf("failed to run migrations: %+v", err)
}

// Override the config values for testing
config.Cfg.PGHost = pg.Config.Host
config.Cfg.PGUser = pg.Config.User
config.Cfg.PGPassword = pg.Config.Password
config.Cfg.PGDBName = pg.Config.DBName
config.Cfg.PGPort = pg.Config.Port
config.Cfg.PGSSLMode = "disable"
config.Cfg.Port = 8080

// Initialize Echo
e := echo.New()
e.Use(middleware.Logger())
e.Use(middleware.Recover())

// Create a new resolver with the database connection
resolver := &graph.Resolver{
DB: pg.DB,
}

srv := handler.NewDefaultServer(graph.NewExecutableSchema(graph.Config{Resolvers: resolver}))

// Setup WebSocket for subscriptions
srv.AddTransport(&transport.Websocket{
Upgrader: websocket.Upgrader{
ReadBufferSize: 1024,
WriteBufferSize: 1024,
CheckOrigin: func(r *http.Request) bool {
return true
},
},
})

e.GET("/", func(c echo.Context) error {
playground.Handler("GraphQL playground", "/query").ServeHTTP(c.Response(), c.Request())
return nil
})

e.POST("/query", func(c echo.Context) error {
srv.ServeHTTP(c.Response(), c.Request())
return nil
})

// Create a test server
ts := httptest.NewServer(e)
defer ts.Close()

// Make a simple GET request to the playground
res, err := http.Get(ts.URL)
assert.NoError(t, err)
assert.Equal(t, http.StatusOK, res.StatusCode)
}
58 changes: 49 additions & 9 deletions backend/pkg/repository/postgres.go
Original file line number Diff line number Diff line change
@@ -1,39 +1,51 @@
package repository

import (
"backend/pkg/utils"
"fmt"
"os"
"os/exec"

"gorm.io/driver/postgres"
"gorm.io/gorm"
"log"
"os"
"os/exec"
)

// DBConfig holds the database configuration details.
type DBConfig struct {
Host string
User string
Password string
DBName string
Port string
SSLMode string
Host string
User string
Password string
DBName string
Port string
SSLMode string
MigrationFilePath string
}

// Postgres represents a PostgreSQL database connection.
type Postgres struct {
Config DBConfig
DB *gorm.DB
}

// NewPostgres creates a new instance of Postgres with the given configuration.
func NewPostgres(config DBConfig) *Postgres {
return &Postgres{Config: config}
}

// GetDB returns the underlying gorm.DB instance.
func (pg *Postgres) GetDB() *gorm.DB {
return pg.DB
}

// DSN returns the Data Source Name for the PostgreSQL connection.
func (pg *Postgres) DSN() string {
return fmt.Sprintf(
"host=%s user=%s password=%s dbname=%s port=%s sslmode=%s",
pg.Config.Host, pg.Config.User, pg.Config.Password, pg.Config.DBName, pg.Config.Port, pg.Config.SSLMode,
)
}

// Open establishes a database connection.
func (pg *Postgres) Open() error {
dsn := pg.DSN()
db, err := gorm.Open(postgres.Open(dsn), &gorm.Config{})
Expand All @@ -44,6 +56,7 @@ func (pg *Postgres) Open() error {
return nil
}

// RunGooseMigrationsUp runs the Goose migrations to upgrade the database schema.
func (pg *Postgres) RunGooseMigrationsUp(path string) error {
dsn := pg.DSN()
cmd := exec.Command("goose", "-dir", path, "postgres", dsn, "up")
Expand All @@ -55,6 +68,7 @@ func (pg *Postgres) RunGooseMigrationsUp(path string) error {
return nil
}

// RunGooseMigrationsDown runs the Goose migrations to downgrade the database schema.
func (pg *Postgres) RunGooseMigrationsDown(path string) error {
dsn := pg.DSN()
cmd := exec.Command("goose", "-dir", path, "postgres", dsn, "down")
Expand All @@ -65,3 +79,29 @@ func (pg *Postgres) RunGooseMigrationsDown(path string) error {
}
return nil
}

// InitializeDatabase encapsulates the database configuration and initialization logic
func InitializeDatabase(config DBConfig) *gorm.DB {
// Initialize the Postgres instance
pg := NewPostgres(config)

// Open the database connection
if err := pg.Open(); err != nil {
log.Fatalf("failed to connect to the database: %v", err)
}

// Get Full path to the migration DB file.
fullPath, err := utils.GetFullPath(config.MigrationFilePath)
if err != nil {
log.Fatalf("Failed to get full path to the migration db file : %+v", err)
}

// Run migrations
log.Printf("Data Migration start ===============")
if err := pg.RunGooseMigrationsUp(fullPath); err != nil {
log.Fatalf("failed to run migrations: %v", err)
}
log.Printf("Data Migration Done ===============")

return pg.DB
}
4 changes: 2 additions & 2 deletions backend/pkg/repository/postgres_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,8 @@ func setupTestDB(ctx context.Context, dbName string) (*Postgres, func(), error)
}

cleanup := func() {
// Run migrations
if err := pg.RunGooseMigrationsUp(migrationFilePath); err != nil {
// Cleanup database
if err := pg.RunGooseMigrationsDown(migrationFilePath); err != nil {
log.Fatalf("failed to run migrations: %v", err)
}

Expand Down
17 changes: 17 additions & 0 deletions backend/pkg/utils/utils.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package utils

import (
"os"
"path/filepath"
)

// GetFullPath takes a relative path and returns the full absolute path
func GetFullPath(path string) (string, error) {
cleanedPath := filepath.Clean(path)
currentDir, err := os.Getwd()
if err != nil {
return "", err
}
fullPath := filepath.Join(currentDir, cleanedPath)
return fullPath, nil
}
2 changes: 1 addition & 1 deletion backend/testutils/database.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ func SetupTestDB(ctx context.Context, user, password, dbName string) (*repositor
}

cleanup := func(migrationFilePath string) {
// Run migrations
// Clean up database
if err := pg.RunGooseMigrationsDown(migrationFilePath); err != nil {
log.Fatalf("failed to run migrations: %v", err)
}
Expand Down

0 comments on commit 91c058d

Please sign in to comment.