github.com/angryronald/go-kit@v0.0.0-20240505173814-ff2bd9c79dbf/test/docker/postgres/postgres.go (about) 1 package postgres 2 3 import ( 4 "fmt" 5 "log" 6 "sync" 7 8 "gorm.io/driver/postgres" 9 "gorm.io/gorm" 10 11 "github.com/ory/dockertest" 12 "github.com/ory/dockertest/docker" 13 14 internalDocker "github.com/angryronald/go-kit/test/docker" 15 ) 16 17 // ref: https://jonnylangefeld.com/blog/how-to-write-a-go-api-part-3-testing-with-dockertest 18 19 var dbInstanceLock sync.Mutex 20 21 func GenerateInstance(pool *dockertest.Pool) (*gorm.DB, *dockertest.Resource) { 22 dbInstanceLock.Lock() 23 defer dbInstanceLock.Unlock() 24 25 var db *gorm.DB 26 port := internalDocker.GetAvailablePort(5432) 27 28 // Pull an image, create a container based on it and set all necessary parameters 29 opts := dockertest.RunOptions{ 30 Repository: "mdillon/postgis", 31 Tag: "latest", 32 Env: []string{"POSTGRES_PASSWORD=password"}, 33 ExposedPorts: []string{"5432"}, 34 PortBindings: map[docker.Port][]docker.PortBinding{ 35 "5432": { 36 {HostIP: "0.0.0.0", HostPort: port}, 37 }, 38 }, 39 } 40 41 // Run the Docker container 42 resource, err := pool.RunWithOptions(&opts) 43 if err != nil { 44 log.Fatalf("Could not start resource: %s", err) 45 } 46 47 // Exponential retry to connect to database while it is booting 48 if err := pool.Retry(func() error { 49 databaseConnStr := fmt.Sprintf("host=localhost port=%s user=postgres dbname=postgres password=password sslmode=disable", port) 50 db, err = gorm.Open(postgres.Open(databaseConnStr), &gorm.Config{}) 51 if err != nil { 52 log.Println("Database not ready yet (it is booting up, wait for a few tries)...") 53 return err 54 } 55 56 // Tests if database is reachable 57 dbinstance, err := db.DB() 58 if err != nil { 59 log.Println("Database instance cannot created") 60 return err 61 } 62 return dbinstance.Ping() 63 }); err != nil { 64 log.Fatalf("Could not connect to Docker: %s", err) 65 } 66 67 return db, resource 68 }