Skip to content

Commit 094b447

Browse files
committed
tests and fix for PYTHON-895
1 parent fbda940 commit 094b447

File tree

4 files changed

+58
-23
lines changed

4 files changed

+58
-23
lines changed

cassandra/__init__.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -686,3 +686,13 @@ class UnsupportedOperation(DriverException):
686686
for more details.
687687
"""
688688
pass
689+
690+
691+
class UnresolvableContactPoints(DriverException):
692+
"""
693+
The driver was unable to resolve any provided hostnames.
694+
695+
Note that this is *not* raised when a :class:`.Cluster` is created with no
696+
contact points, only when lookup fails for all hosts
697+
"""
698+
pass

cassandra/cluster.py

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,8 @@
4343

4444
from cassandra import (ConsistencyLevel, AuthenticationFailed,
4545
OperationTimedOut, UnsupportedOperation,
46-
SchemaTargetType, DriverException, ProtocolVersion)
46+
SchemaTargetType, DriverException, ProtocolVersion,
47+
UnresolvableContactPoints)
4748
from cassandra.connection import (ConnectionException, ConnectionShutdown,
4849
ConnectionHeartbeat, ProtocolVersionUnsupported)
4950
from cassandra.cqltypes import UserType
@@ -201,10 +202,26 @@ def _addrinfo_or_none(contact_point, port):
201202
try:
202203
return socket.getaddrinfo(contact_point, port,
203204
socket.AF_UNSPEC, socket.SOCK_STREAM)
204-
except (socket.error, socket.herror, socket.gaierror, socket.timeout):
205+
except socket.gaierror:
206+
log.debug('Could not resolve hostname "{}" '
207+
'with port {}'.format(contact_point, port))
205208
return None
206209

207210

211+
def _resolve_contact_points(contact_points, port):
212+
resolved = tuple(_addrinfo_or_none(p, port)
213+
for p in contact_points)
214+
215+
if resolved and all((x is None for x in resolved)):
216+
raise UnresolvableContactPoints(contact_points, port)
217+
218+
resolved = tuple(r for r in resolved if r is not None)
219+
220+
return [endpoint[4][0]
221+
for addrinfo in resolved
222+
for endpoint in addrinfo]
223+
224+
208225
class ExecutionProfile(object):
209226
load_balancing_policy = None
210227
"""
@@ -837,12 +854,8 @@ def __init__(self,
837854

838855
self.port = port
839856

840-
self.contact_points_resolved = [
841-
endpoint[4][0]
842-
for point in self.contact_points
843-
for endpoint in _addrinfo_or_none(point, self.port)
844-
if endpoint is not None
845-
]
857+
self.contact_points_resolved = _resolve_contact_points(self.contact_points,
858+
self.port)
846859

847860
self.compression = compression
848861

tests/integration/simulacron/__init__.py

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,20 +35,25 @@ def tearDown(self):
3535

3636

3737
class SimulacronCluster(SimulacronBase):
38+
39+
cluster, connect = None, True
40+
3841
@classmethod
3942
def setUpClass(cls):
4043
if SIMULACRON_JAR is None or CASSANDRA_VERSION < Version("2.1"):
4144
return
4245

4346
start_and_prime_singledc()
44-
cls.cluster = Cluster(protocol_version=PROTOCOL_VERSION, compression=False)
45-
cls.session = cls.cluster.connect(wait_for_all_pools=True)
47+
if cls.connect:
48+
cls.cluster = Cluster(protocol_version=PROTOCOL_VERSION, compression=False)
49+
cls.session = cls.cluster.connect(wait_for_all_pools=True)
4650

4751
@classmethod
4852
def tearDownClass(cls):
4953
if SIMULACRON_JAR is None or CASSANDRA_VERSION < Version("2.1"):
5054
return
5155

52-
cls.cluster.shutdown()
56+
if cls.cluster:
57+
cls.cluster.shutdown()
5358
stop_simulacron()
5459

tests/integration/simulacron/test_cluster.py

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@
2020
from tests.integration import (requiressimulacron, PROTOCOL_VERSION)
2121
from tests.integration.simulacron.utils import prime_query
2222

23-
from cassandra import WriteTimeout, WriteType, ConsistencyLevel
23+
from cassandra import (WriteTimeout, WriteType,
24+
ConsistencyLevel, UnresolvableContactPoints)
2425
from cassandra.cluster import Cluster
2526

2627

@@ -56,18 +57,24 @@ def test_writetimeout(self):
5657
self.assertIn(str(received_responses), str(wt))
5758
self.assertIn(str(required_responses), str(wt))
5859

59-
def test_connection_with_one_unresolvable_contact_point(self):
60-
self.cluster.shutdown()
6160

62-
# shouldn't raise anything due to name resolution failures
63-
Cluster(['127.0.0.1', 'doesntresolve.becauseitcant'],
64-
protocol_version=PROTOCOL_VERSION,
65-
compression=False)
61+
@requiressimulacron
62+
class ClusterDNSResolutionTests(SimulacronCluster):
6663

67-
def test_connection_with_only_unresolvable_contact_points(self):
68-
self.cluster.shutdown()
64+
connect = False
6965

66+
def tearDown(self):
67+
if self.cluster:
68+
self.cluster.shutdown()
69+
70+
def test_connection_with_one_unresolvable_contact_point(self):
7071
# shouldn't raise anything due to name resolution failures
71-
Cluster(['doesntresolve.becauseitcant'],
72-
protocol_version=PROTOCOL_VERSION,
73-
compression=False)
72+
self.cluster = Cluster(['127.0.0.1', 'dns.invalid'],
73+
protocol_version=PROTOCOL_VERSION,
74+
compression=False)
75+
76+
def test_connection_with_only_unresolvable_contact_points(self):
77+
with self.assertRaises(UnresolvableContactPoints):
78+
self.cluster = Cluster(['dns.invalid'],
79+
protocol_version=PROTOCOL_VERSION,
80+
compression=False)

0 commit comments

Comments
 (0)