Skip to content

Commit 4f97070

Browse files
dabrignSergeyPirogov
authored andcommitted
Added MongoDb container (#47)
* Added MongoDb container * remove comments from test * remove literal for port exposed * added assertion on mongodb test * Removed unnecessary print
1 parent c6ae58d commit 4f97070

File tree

5 files changed

+101
-1
lines changed

5 files changed

+101
-1
lines changed

docs/database.rst

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
Database containers
22
===================
33

4-
Allows to spin up docker database images such as MySQL, PostgreSQL, MariaDB and Oracle XE.
4+
Allows to spin up docker database images such as MySQL, PostgreSQL, MariaDB, Oracle XE and MongoDb.
55

66
MySQL example
77
-------------
@@ -81,3 +81,35 @@ Elasticsearch
8181
with es:
8282
es.get_url() # gives you the http URL to connect to Elasticsearch
8383

84+
MongoDb
85+
-----------
86+
87+
Example of MongoDb database usage:
88+
89+
::
90+
91+
def test_docker_run_mongodb():
92+
mongo_container = MongoDbContainer("mongo:latest")
93+
with mongo_container as mongo:
94+
db = mongo.get_connection_client().test
95+
result = db.restaurants.insert_one(
96+
{
97+
"address": {
98+
"street": "2 Avenue",
99+
"zipcode": "10075",
100+
"building": "1480",
101+
"coord": [-73.9557413, 40.7720266]
102+
},
103+
"borough": "Manhattan",
104+
"cuisine": "Italian",
105+
"name": "Vella",
106+
"restaurant_id": "41704620"
107+
}
108+
)
109+
print(result.inserted_id)
110+
cursor = db.restaurants.find({"borough": "Manhattan"})
111+
for document in cursor:
112+
print(document)
113+
114+
Connection is made using pymongo package and MongoClient class.
115+
Alternatively, you can use get_connection_url method to use the driver that better fits for your use case.

docs/index.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ Currently available features:
1616
- PostgreSQL db container
1717
- Google Cloud PubSub emulator container
1818
- Elasticsearch container
19+
- MongoDb container
1920
- Generic Docker containers
2021

2122
Installation
@@ -33,6 +34,7 @@ and can be installed using pip, depending on which containers you need:
3334
pip install testcontainers[postgresql]
3435
pip install testcontainers[selenium]
3536
pip install testcontainers[google-cloud-pubsub]
37+
pip install testcontainers[mongodb]
3638
# or with multiple
3739
pip install testcontainers[mysql,postgresql,selenium,google-cloud-pubsub]
3840

setup.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@
5353
'postgresql': ['sqlalchemy', 'psycopg2-binary'],
5454
'selenium': ['selenium==2.53.1'],
5555
'google-cloud-pubsub': ['google-cloud-pubsub'],
56+
'mongo': ['pymongo']
5657
},
5758
long_description_content_type="text/markdown",
5859
long_description=long_description,

testcontainers/mongodb.py

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
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+
import os
14+
15+
from pymongo import MongoClient
16+
17+
from testcontainers.core.generic import DockerContainer
18+
19+
20+
class MongoDbContainer(DockerContainer):
21+
MONGO_INITDB_ROOT_USERNAME = os.environ.get("MONGO_INITDB_ROOT_USERNAME", "test")
22+
MONGO_INITDB_ROOT_PASSWORD = os.environ.get("MONGO_INITDB_ROOT_PASSWORD", "test")
23+
MONGO_DB = os.environ.get("MONGO_DB", "test")
24+
25+
def __init__(self, image="mongodb:latest"):
26+
super(MongoDbContainer, self).__init__(image=image)
27+
self.command="mongo"
28+
self.port_to_expose = 27017
29+
self.with_exposed_ports(self.port_to_expose)
30+
31+
def _configure(self):
32+
33+
self.with_env("MONGO_INITDB_ROOT_USERNAME", self.MONGO_INITDB_ROOT_USERNAME)
34+
self.with_env("MONGO_INITDB_ROOT_PASSWORD", self.MONGO_INITDB_ROOT_PASSWORD)
35+
self.with_env("MONGO_DB", self.MONGO_DB)
36+
37+
def get_connection_url(self):
38+
return "mongodb://{}:{}".format(self.get_container_host_ip(), self.get_exposed_port(self.port_to_expose))
39+
40+
def get_connection_client(self):
41+
return MongoClient("mongodb://{}:{}".format(self.get_container_host_ip(),
42+
self.get_exposed_port(self.port_to_expose)))
43+

tests/test_db_containers.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
from testcontainers.mysql import MySqlContainer, MariaDbContainer
88
from testcontainers.oracle import OracleDbContainer
99
from testcontainers.postgres import PostgresContainer
10+
from testcontainers.mongodb import MongoDbContainer
1011

1112

1213
def test_docker_run_mysql():
@@ -50,6 +51,27 @@ def test_docker_run_oracle():
5051
assert {row[0] for row in result} == versions
5152

5253

54+
def test_docker_run_mongodb():
55+
mongo_container = MongoDbContainer("mongo:latest")
56+
with mongo_container as mongo:
57+
db = mongo.get_connection_client().test
58+
doc = {
59+
"address": {
60+
"street": "2 Avenue",
61+
"zipcode": "10075",
62+
"building": "1480",
63+
"coord": [-73.9557413, 40.7720266]
64+
},
65+
"borough": "Manhattan",
66+
"cuisine": "Italian",
67+
"name": "Vella",
68+
"restaurant_id": "41704620"
69+
}
70+
result = db.restaurants.insert_one(doc)
71+
cursor = db.restaurants.find({"borough": "Manhattan"})
72+
assert cursor.next()['restaurant_id'] == doc['restaurant_id']
73+
74+
5375
def test_docker_generic_db():
5476
mongo_container = GenericContainer("mongo:latest")
5577
mongo_container.with_bind_ports(27017, 27017)

0 commit comments

Comments
 (0)