1212# under the License.
1313from os import environ
1414from typing import Optional
15+ from urllib .error import HTTPError , URLError
16+ from urllib .request import urlopen
1517
1618from testcontainers .core .generic import DbContainer
19+ from testcontainers .core .waiting_utils import wait_container_is_ready , wait_for_logs
1720
1821
1922class CockroachDBContainer (DbContainer ):
@@ -32,28 +35,29 @@ class CockroachDBContainer(DbContainer):
3235 >>> import sqlalchemy
3336 >>> from testcontainers.cockroachdb import CockroachDBContainer
3437
35- >>> with CockroachDBContainer('cockroachdb/cockroach:latest ') as crdb:
38+ >>> with CockroachDBContainer('cockroachdb/cockroach:v24.1.1 ') as crdb:
3639 ... engine = sqlalchemy.create_engine(crdb.get_connection_url())
3740 ... with engine.begin() as connection:
3841 ... result = connection.execute(sqlalchemy.text("select version()"))
3942 ... version, = result.fetchone()
4043
4144 """
4245
46+ COCKROACH_DB_PORT : int = 26257
47+ COCKROACH_API_PORT : int = 8080
48+
4349 def __init__ (
4450 self ,
45- image : str = "cockroachdb/cockroach:latest " ,
51+ image : str = "cockroachdb/cockroach:v24.1.1 " ,
4652 username : Optional [str ] = None ,
4753 password : Optional [str ] = None ,
4854 dbname : Optional [str ] = None ,
49- port : int = 26257 ,
5055 dialect = "cockroachdb+psycopg2" ,
5156 ** kwargs ,
5257 ) -> None :
5358 super ().__init__ (image , ** kwargs )
5459
55- self .port = port
56- self .with_exposed_ports (self .port )
60+ self .with_exposed_ports (self .COCKROACH_DB_PORT , self .COCKROACH_API_PORT )
5761 self .username = username or environ .get ("COCKROACH_USER" , "cockroach" )
5862 self .password = password or environ .get ("COCKROACH_PASSWORD" , "arthropod" )
5963 self .dbname = dbname or environ .get ("COCKROACH_DATABASE" , "roach" )
@@ -69,9 +73,25 @@ def _configure(self) -> None:
6973 cmd += " --insecure"
7074 self .with_command (cmd )
7175
76+ @wait_container_is_ready (HTTPError , URLError )
77+ def _connect (self ) -> None :
78+ host = self .get_container_host_ip ()
79+ url = f"http://{ host } :{ self .get_exposed_port (self .COCKROACH_API_PORT )} /health"
80+ self ._wait_for_health (url )
81+ wait_for_logs (self , "finished creating default user*" )
82+
83+ @staticmethod
84+ def _wait_for_health (url ):
85+ with urlopen (url ) as response :
86+ response .read ()
87+
7288 def get_connection_url (self ) -> str :
7389 conn_str = super ()._create_connection_url (
74- dialect = self .dialect , username = self .username , password = self .password , dbname = self .dbname , port = self .port
90+ dialect = self .dialect ,
91+ username = self .username ,
92+ password = self .password ,
93+ dbname = self .dbname ,
94+ port = self .COCKROACH_DB_PORT ,
7595 )
7696
7797 if self .password :
0 commit comments