Skip to content

Commit 940f346

Browse files
Merge branch 'master' into patch-1
2 parents 70ae624 + d9a1137 commit 940f346

21 files changed

+507
-373
lines changed

.travis.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ install:
2222

2323
script:
2424
- pipenv install --dev
25+
- pipenv run flake8
2526
- pipenv run py.test -sv --cov-config .coveragerc --cov-report html:skip-covered --cov-report term:skip-covered --cov=testcontainers --tb=short tests/
2627
- codecov
2728

Pipfile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ verify_ssl = true
44

55
["dev-packages"]
66
codecov = "*"
7+
flake8 = "*"
78

89
[packages]
910
crayons = "*"

Pipfile.lock

Lines changed: 432 additions & 328 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

docs/conf.py

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,3 @@
151151
author, 'testcontainers', 'One line description of project.',
152152
'Miscellaneous'),
153153
]
154-
155-
156-

setup.cfg

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,6 @@ universal = 1
33

44
[metadata]
55
description-file = README.md
6+
7+
[flake8]
8+
max-line-length = 100

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
setuptools.setup(
2020
name='testcontainers',
2121
packages=setuptools.find_packages(exclude=['tests']),
22-
version='2.5',
22+
version='2.5.0',
2323
description=('Library provides lightweight, throwaway '
2424
'instances of common databases, '
2525
'Selenium web browsers, or anything else that can '

testcontainers/compose.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@ def __exit__(self, exc_type, exc_val, exc_tb):
2020

2121
def start(self):
2222
with blindspin.spinner():
23-
subprocess.call(["docker-compose", "-f", self.compose_file_name, "up", "-d"], cwd=self.filepath)
23+
subprocess.call(["docker-compose", "-f", self.compose_file_name, "up", "-d"],
24+
cwd=self.filepath)
2425

2526
def stop(self):
2627
with blindspin.spinner():

testcontainers/core/container.py

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
from testcontainers.core.docker_client import DockerClient
66
from testcontainers.core.exceptions import ContainerStartException
7-
from testcontainers.core.utils import is_windows, inside_container
7+
from testcontainers.core.utils import inside_container
88

99

1010
class DockerContainer(object):
@@ -81,10 +81,7 @@ def get_container_host_ip(self) -> str:
8181
# container's IP address from the dockder "bridge" network
8282
if inside_container():
8383
return self.get_docker_client().bridge_ip(self._container.id)
84-
elif is_windows():
85-
return "localhost"
86-
else:
87-
return "0.0.0.0"
84+
return "localhost"
8885

8986
def get_exposed_port(self, port) -> str:
9087
if inside_container():

testcontainers/core/waiting_utils.py

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@
1212
# under the License.
1313

1414

15-
from time import sleep
15+
import re
16+
import time
1617

1718
import blindspin
1819
import crayons
@@ -40,7 +41,7 @@ def wrapper(wrapped, instance, args, kwargs):
4041
try:
4142
return wrapped(*args, **kwargs)
4243
except Exception as e:
43-
sleep(config.SLEEP_TIME)
44+
time.sleep(config.SLEEP_TIME)
4445
exception = e
4546
raise TimeoutException(
4647
"""Wait time exceeded {0} sec.
@@ -55,3 +56,37 @@ def wrapper(wrapped, instance, args, kwargs):
5556
@wait_container_is_ready()
5657
def wait_for(condition):
5758
return condition()
59+
60+
61+
def wait_for_logs(container, predicate, timeout=None, interval=1):
62+
"""
63+
Wait for the container to emit logs satisfying the predicate.
64+
65+
Parameters
66+
----------
67+
container : DockerContainer
68+
Container whose logs to wait for.
69+
predicate : callable or str
70+
Predicate that should be satisfied by the logs. If a string, the it is used as the pattern
71+
for a multiline regular expression search.
72+
timeout : float or None
73+
Number of seconds to wait for the predicate to be satisfied. Defaults to wait indefinitely.
74+
interval : float
75+
Interval at which to poll the logs.
76+
77+
Returns
78+
-------
79+
duration : float
80+
Number of seconds until the predicate was satisfied.
81+
"""
82+
if isinstance(predicate, str):
83+
predicate = re.compile(predicate, re.MULTILINE).search
84+
start = time.time()
85+
while True:
86+
duration = time.time() - start
87+
if predicate(container._container.logs().decode()):
88+
return duration
89+
if timeout and duration > timeout:
90+
raise TimeoutError("container did not emit logs satisfying predicate in %.3f seconds"
91+
% timeout)
92+
time.sleep(interval)

testcontainers/general.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,11 @@
1111
# License for the specific language governing permissions and limitations
1212
# under the License.
1313
from testcontainers.core.container import DockerContainer
14-
from testcontainers.core.waiting_utils import wait_container_is_ready
1514

1615

1716
class TestContainer(DockerContainer):
1817
def __init__(self, image, port_to_expose=None):
19-
super(RedisContainer, self).__init__(image)
18+
super(TestContainer, self).__init__(image)
2019
if port_to_expose:
21-
self.port_to_expose = port_to_expose
22-
self.with_exposed_ports(self.port_to_expose)
20+
self.port_to_expose = port_to_expose
21+
self.with_exposed_ports(self.port_to_expose)

0 commit comments

Comments
 (0)