12
12
# under the License.
13
13
from os import environ
14
14
from typing import Optional
15
+ from urllib .error import HTTPError , URLError
16
+ from urllib .request import urlopen
15
17
16
18
from testcontainers .core .generic import DbContainer
19
+ from testcontainers .core .waiting_utils import wait_container_is_ready , wait_for_logs
17
20
18
21
19
22
class CockroachDBContainer (DbContainer ):
@@ -32,28 +35,29 @@ class CockroachDBContainer(DbContainer):
32
35
>>> import sqlalchemy
33
36
>>> from testcontainers.cockroachdb import CockroachDBContainer
34
37
35
- >>> with CockroachDBContainer('cockroachdb/cockroach:latest ') as crdb:
38
+ >>> with CockroachDBContainer('cockroachdb/cockroach:v24.1.1 ') as crdb:
36
39
... engine = sqlalchemy.create_engine(crdb.get_connection_url())
37
40
... with engine.begin() as connection:
38
41
... result = connection.execute(sqlalchemy.text("select version()"))
39
42
... version, = result.fetchone()
40
43
41
44
"""
42
45
46
+ COCKROACH_DB_PORT : int = 26257
47
+ COCKROACH_API_PORT : int = 8080
48
+
43
49
def __init__ (
44
50
self ,
45
- image : str = "cockroachdb/cockroach:latest " ,
51
+ image : str = "cockroachdb/cockroach:v24.1.1 " ,
46
52
username : Optional [str ] = None ,
47
53
password : Optional [str ] = None ,
48
54
dbname : Optional [str ] = None ,
49
- port : int = 26257 ,
50
55
dialect = "cockroachdb+psycopg2" ,
51
56
** kwargs ,
52
57
) -> None :
53
58
super ().__init__ (image , ** kwargs )
54
59
55
- self .port = port
56
- self .with_exposed_ports (self .port )
60
+ self .with_exposed_ports (self .COCKROACH_DB_PORT , self .COCKROACH_API_PORT )
57
61
self .username = username or environ .get ("COCKROACH_USER" , "cockroach" )
58
62
self .password = password or environ .get ("COCKROACH_PASSWORD" , "arthropod" )
59
63
self .dbname = dbname or environ .get ("COCKROACH_DATABASE" , "roach" )
@@ -69,9 +73,25 @@ def _configure(self) -> None:
69
73
cmd += " --insecure"
70
74
self .with_command (cmd )
71
75
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
+
72
88
def get_connection_url (self ) -> str :
73
89
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 ,
75
95
)
76
96
77
97
if self .password :
0 commit comments