Skip to content

Commit 507e466

Browse files
fix: Add CassandraContainer (#476)
Co-authored-by: David Ankin <[email protected]>
1 parent 0729bf4 commit 507e466

File tree

7 files changed

+162
-1
lines changed

7 files changed

+162
-1
lines changed

.github/settings.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ labels:
6363
- { name: '🐧 linux', color: '#3ED4D',, description: '' }
6464
- { name: '👀 requires attention', color: '#fef2c0', description: '' }
6565
- { name: '📖 documentation', color: '#d93f0b', description: '' }
66+
- { name: '📦 package: cassandra', color: '#0052CC', description: '' }
6667
- { name: '📦 package: clickhouse', color: '#0052CC', description: '' }
6768
- { name: '📦 package: compose', color: '#0052CC', description: '' }
6869
- { name: '📦 package: core', color: '#0052CC', description: '' }

index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ testcontainers-python facilitates the use of Docker containers for functional an
1717
core/README
1818
modules/arangodb/README
1919
modules/azurite/README
20+
modules/cassandra/README
2021
modules/chroma/README
2122
modules/clickhouse/README
2223
modules/elasticsearch/README

modules/cassandra/README.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
.. autoclass:: testcontainers.cassandra.CassandraContainer
2+
.. title:: testcontainers.cassandra.CassandraContainer
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
#
2+
# Licensed under the Apache License, Version 2.0 (the "License"); you may
3+
# not use this file except in compliance with the License. You may obtain
4+
# a copy of the License at
5+
#
6+
# http://www.apache.org/licenses/LICENSE-2.0
7+
#
8+
# Unless required by applicable law or agreed to in writing, software
9+
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
10+
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
11+
# License for the specific language governing permissions and limitations
12+
# under the License.
13+
from testcontainers.core.container import DockerContainer
14+
from testcontainers.core.waiting_utils import wait_for_logs
15+
16+
17+
class CassandraContainer(DockerContainer):
18+
"""
19+
Cassandra database container.
20+
21+
Example:
22+
23+
.. doctest::
24+
25+
>>> from testcontainers.cassandra import CassandraContainer
26+
>>> from cassandra.cluster import Cluster, DCAwareRoundRobinPolicy
27+
28+
>>> with CassandraContainer("cassandra:4.1.4") as cassandra, Cluster(
29+
... cassandra.get_contact_points(),
30+
... load_balancing_policy=DCAwareRoundRobinPolicy(cassandra.get_local_datacenter()),
31+
... ) as cluster:
32+
... session = cluster.connect()
33+
... result = session.execute("SELECT release_version FROM system.local;")
34+
... result.one().release_version
35+
'4.1.4'
36+
"""
37+
38+
CQL_PORT = 9042
39+
DEFAULT_LOCAL_DATACENTER = "datacenter1"
40+
41+
def __init__(self, image: str = "cassandra:latest", **kwargs) -> None:
42+
super().__init__(image=image, **kwargs)
43+
self.with_exposed_ports(self.CQL_PORT)
44+
self.with_env("JVM_OPTS", "-Dcassandra.skip_wait_for_gossip_to_settle=0 -Dcassandra.initial_token=0")
45+
self.with_env("HEAP_NEWSIZE", "128M")
46+
self.with_env("MAX_HEAP_SIZE", "1024M")
47+
self.with_env("CASSANDRA_ENDPOINT_SNITCH", "GossipingPropertyFileSnitch")
48+
self.with_env("CASSANDRA_DC", self.DEFAULT_LOCAL_DATACENTER)
49+
50+
def _connect(self):
51+
wait_for_logs(self, "Startup complete")
52+
53+
def start(self) -> "CassandraContainer":
54+
super().start()
55+
self._connect()
56+
return self
57+
58+
def get_contact_points(self) -> list[tuple[str, int]]:
59+
return [(self.get_container_host_ip(), int(self.get_exposed_port(self.CQL_PORT)))]
60+
61+
def get_local_datacenter(self) -> str:
62+
return self.env.get("CASSANDRA_DC", self.DEFAULT_LOCAL_DATACENTER)
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
from cassandra.cluster import Cluster, DCAwareRoundRobinPolicy
2+
3+
from testcontainers.cassandra import CassandraContainer
4+
5+
6+
def test_docker_run_cassandra():
7+
with CassandraContainer("cassandra:4.1.4") as cassandra:
8+
cluster = Cluster(
9+
cassandra.get_contact_points(),
10+
load_balancing_policy=DCAwareRoundRobinPolicy(cassandra.get_local_datacenter()),
11+
)
12+
session = cluster.connect()
13+
result = session.execute("SELECT release_version FROM system.local;")
14+
assert result.one().release_version == "4.1.4"

poetry.lock

Lines changed: 78 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pyproject.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ packages = [
3030
{ include = "testcontainers", from = "core" },
3131
{ include = "testcontainers", from = "modules/arangodb" },
3232
{ include = "testcontainers", from = "modules/azurite" },
33+
{ include = "testcontainers", from = "modules/cassandra" },
3334
{ include = "testcontainers", from = "modules/chroma" },
3435
{ include = "testcontainers", from = "modules/clickhouse" },
3536
{ include = "testcontainers", from = "modules/elasticsearch" },
@@ -93,6 +94,7 @@ chromadb-client = { version = "*", optional = true }
9394
[tool.poetry.extras]
9495
arangodb = ["python-arango"]
9596
azurite = ["azure-storage-blob"]
97+
cassandra = ["cassandra-driver"]
9698
clickhouse = ["clickhouse-driver"]
9799
elasticsearch = []
98100
google = ["google-cloud-pubsub", "google-cloud-datastore"]
@@ -130,6 +132,7 @@ pg8000 = "*"
130132
sqlalchemy = "*"
131133
psycopg = "*"
132134
kafka-python = "^2.0.2"
135+
cassandra-driver = "*"
133136

134137
[[tool.poetry.source]]
135138
name = "PyPI"
@@ -228,6 +231,7 @@ mypy_path = [
228231
"core",
229232
# "modules/arangodb",
230233
# "modules/azurite",
234+
# "modules/cassandra",
231235
# "modules/clickhouse",
232236
# "modules/elasticsearch",
233237
# "modules/google",

0 commit comments

Comments
 (0)