Skip to content

Commit

Permalink
Adding support for Cassandra and Scylla
Browse files Browse the repository at this point in the history
This add the support for those cassandra based dbs
and their drivers, cassandra-driver, scylla-driver

Ref: https://cassandra.apache.org/
Ref: https://www.scylladb.com/
Ref: https://pypi.org/project/cassandra-driver/
Ref: https://pypi.org/project/scylla-driver/
  • Loading branch information
fruch committed Sep 18, 2022
1 parent f899846 commit 74ac112
Show file tree
Hide file tree
Showing 8 changed files with 124 additions and 1 deletion.
2 changes: 2 additions & 0 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ jobs:
- webdriver.py
- keycloak.py
- arangodb.py
- scylladb.py
- cassandra.py
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
Expand Down
2 changes: 2 additions & 0 deletions docs/database.rst
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,5 @@ Allows to spin up database images such as MySQL, PostgreSQL, MariaDB, Oracle XE,
.. autoclass:: testcontainers.clickhouse.ClickHouseContainer
.. autoclass:: testcontainers.neo4j.Neo4jContainer
.. autoclass:: testcontainers.arangodb.ArangoDbContainer
.. autoclass:: testcontainers.cassandra.CassandraContainer
.. autoclass:: testcontainers.scylla.ScyllaContainer
2 changes: 1 addition & 1 deletion requirements.in
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
-e file:.[docker-compose,mysql,oracle,postgresql,selenium,google-cloud-pubsub,mongo,redis,mssqlserver,neo4j,kafka,rabbitmq,clickhouse,keycloak,arangodb]
-e file:.[docker-compose,mysql,oracle,postgresql,selenium,google-cloud-pubsub,mongo,redis,mssqlserver,neo4j,kafka,rabbitmq,clickhouse,keycloak,arangodb,cassandra,scylla]
codecov>=2.1.0
cryptography<37
flake8<3.8.0 # 3.8.0 adds a dependency on importlib-metadata which conflicts with other packages.
Expand Down
2 changes: 2 additions & 0 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,8 @@
'clickhouse': ['clickhouse-driver'],
'keycloak': ['python-keycloak'],
'arangodb': ['python-arango'],
'cassandra': ['cassandra-driver'],
'scylla': ['scylla-driver']
},
long_description_content_type="text/x-rst",
long_description=long_description,
Expand Down
40 changes: 40 additions & 0 deletions testcontainers/cassandra.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
from testcontainers.core.generic import DockerContainer
from testcontainers.core.waiting_utils import wait_container_is_ready


class CassandraContainer(DockerContainer):
"""
Cassandra database container.
Example
-------
::
with CassandraContainer() as cassandra:
cluster = cassandra.get_cluster()
with cluster.connect() as session:
session.execute(
"CREATE KEYSPACE keyspace1 WITH replication = "
"{'class': 'SimpleStrategy', 'replication_factor': '1'};")
"""
def __init__(self, image="rinscy/cassandra:latest", ports_to_expose=[9042]):
super(CassandraContainer, self).__init__(image)
self.ports_to_expose = ports_to_expose
self.with_exposed_ports(*self.ports_to_expose)

@wait_container_is_ready()
def _connect(self):
cluster = self.get_cluster()
cluster.connect()

def start(self):
super(CassandraContainer, self).start()
self._connect()
return self

def get_cluster(self, **kwargs):
from cassandra.cluster import Cluster
hostname = self.get_container_host_ip()
port = self.get_exposed_port(9042)
return Cluster(contact_points=[hostname], port=port, **kwargs)
41 changes: 41 additions & 0 deletions testcontainers/scylla.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
from testcontainers.core.generic import DockerContainer
from testcontainers.core.waiting_utils import wait_container_is_ready


class ScyllaContainer(DockerContainer):
"""
Scylla database container.
Example
-------
::
with ScyllaContainer() as scylla:
cluster = scylla.get_cluster()
with cluster.connect() as session:
session.execute(
"CREATE KEYSPACE keyspace1 WITH replication "
"= {'class': 'SimpleStrategy', 'replication_factor': '1'};")
"""
def __init__(self, image="scylladb/scylla:4.6.rc1", ports_to_expose=[9042]):
super(ScyllaContainer, self).__init__(image)
self.ports_to_expose = ports_to_expose
self.with_exposed_ports(*self.ports_to_expose)
self.with_command("--skip-wait-for-gossip-to-settle=0")

@wait_container_is_ready()
def _connect(self):
cluster = self.get_cluster()
cluster.connect()

def start(self):
super(ScyllaContainer, self).start()
self._connect()
return self

def get_cluster(self, **kwargs):
from cassandra.cluster import Cluster
hostname = self.get_container_host_ip()
port = self.get_exposed_port(9042)
return Cluster(contact_points=[hostname], port=port, **kwargs)
18 changes: 18 additions & 0 deletions tests/test_cassandra.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
from testcontainers.cassandra import CassandraContainer


def test_docker_run_cassandra():
with CassandraContainer() as cassandra:
cluster = cassandra.get_cluster()
with cluster.connect() as session:
session.execute(
"CREATE KEYSPACE keyspace1 WITH replication = "
"{'class': 'SimpleStrategy', 'replication_factor': '1'};")
session.execute(
"CREATE TABLE keyspace1.table1 (key1 int, key2 int, PRIMARY KEY (key1));")
session.execute("INSERT INTO keyspace1.table1 (key1,key2) values (1,2);")

response = session.execute("SELECT * FROM keyspace1.table1")

assert response.one().key1 == 1
assert response.one().key2 == 2
18 changes: 18 additions & 0 deletions tests/test_scylla.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
from testcontainers.scylla import ScyllaContainer


def test_docker_run_scylla():
with ScyllaContainer() as scylla:
cluster = scylla.get_cluster()
with cluster.connect() as session:
session.execute(
"CREATE KEYSPACE keyspace1 WITH replication = "
"{'class': 'SimpleStrategy', 'replication_factor': '1'};")
session.execute(
"CREATE TABLE keyspace1.table1 (key1 int, key2 int, PRIMARY KEY (key1));")
session.execute("INSERT INTO keyspace1.table1 (key1,key2) values (1,2);")

response = session.execute("SELECT * FROM keyspace1.table1")

assert response.one().key1 == 1
assert response.one().key2 == 2

0 comments on commit 74ac112

Please sign in to comment.