@@ -71,6 +71,15 @@ func (ep *EmbeddedPostgres) Start() error {
7171 return ErrServerAlreadyStarted
7272 }
7373
74+ if ep .config .port == 0 {
75+ port , err := getFreePort ()
76+ if err != nil {
77+ return err
78+ }
79+
80+ ep .config .port = port
81+ }
82+
7483 if err := ensurePortAvailable (ep .config .port ); err != nil {
7584 return err
7685 }
@@ -147,6 +156,10 @@ func (ep *EmbeddedPostgres) Start() error {
147156 return nil
148157}
149158
159+ func (ep * EmbeddedPostgres ) GetPort () uint32 {
160+ return ep .config .port
161+ }
162+
150163func (ep * EmbeddedPostgres ) downloadAndExtractBinary (cacheExists bool , cacheLocation string ) error {
151164 // lock to prevent collisions with duplicate downloads
152165 mu .Lock ()
@@ -242,6 +255,10 @@ func stopPostgres(ep *EmbeddedPostgres) error {
242255}
243256
244257func ensurePortAvailable (port uint32 ) error {
258+ if port == 0 {
259+
260+ }
261+
245262 conn , err := net .Listen ("tcp" , fmt .Sprintf ("localhost:%d" , port ))
246263 if err != nil {
247264 return fmt .Errorf ("process already listening on port %d" , port )
@@ -254,6 +271,21 @@ func ensurePortAvailable(port uint32) error {
254271 return nil
255272}
256273
274+ func getFreePort () (uint32 , error ) {
275+ addr , err := net .ResolveTCPAddr ("tcp" , "localhost:0" )
276+ if err != nil {
277+ return 0 , fmt .Errorf ("failed to resolve TCP address: %w" , err )
278+ }
279+
280+ l , err := net .ListenTCP ("tcp" , addr )
281+ if err != nil {
282+ return 0 , fmt .Errorf ("failed to listen on TCP: %w" , err )
283+ }
284+ defer l .Close ()
285+
286+ return uint32 (l .Addr ().(* net.TCPAddr ).Port ), nil
287+ }
288+
257289func dataDirIsValid (dataDir string , version PostgresVersion ) bool {
258290 pgVersion := filepath .Join (dataDir , "PG_VERSION" )
259291
0 commit comments