Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
======================================================================= test session starts ========================================================================
platform darwin -- Python 3.7.0, pytest-3.3.0, py-1.8.0, pluggy-0.6.0
rootdir: /Users/anubhavujjawal/Desktop/Misc/MongoDB/M220P-mongoDB-for-python-devs/mflix-python, inifile:
plugins: flask-0.10.0
collected 43 items
tests/test_db_connection.py FFFF [100%]
============================================================================= FAILURES =============================================================================
_________________________________________________________________________ test_atlas_setup _________________________________________________________________________
hostname = 'mflix-wgqbw.mongodb.net'
def _get_dns_txt_options(hostname):
try:
> results = resolver.query(hostname, 'TXT')
../mflix/lib/python3.7/site-packages/pymongo/uri_parser.py:296:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
qname = 'mflix-wgqbw.mongodb.net', rdtype = 'TXT', rdclass = 1, tcp = False, source = None, raise_on_no_answer = True, source_port = 0
def query(qname, rdtype=dns.rdatatype.A, rdclass=dns.rdataclass.IN,
tcp=False, source=None, raise_on_no_answer=True,
source_port=0):
"""Query nameservers to find the answer to the question.
This is a convenience function that uses the default resolver
object to make the query.
@see: L{dns.resolver.Resolver.query} for more information on the
parameters."""
return get_default_resolver().query(qname, rdtype, rdclass, tcp, source,
> raise_on_no_answer, source_port)
../mflix/lib/python3.7/site-packages/dns/resolver.py:1132:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <dns.resolver.Resolver object at 0x110a19518>, qname = <DNS name mflix-wgqbw.mongodb.net>, rdtype = 16, rdclass = 1, tcp = False, source = None
raise_on_no_answer = True, source_port = 0
def query(self, qname, rdtype=dns.rdatatype.A, rdclass=dns.rdataclass.IN,
tcp=False, source=None, raise_on_no_answer=True, source_port=0):
"""Query nameservers to find the answer to the question.
The I{qname}, I{rdtype}, and I{rdclass} parameters may be objects
of the appropriate type, or strings that can be converted into objects
of the appropriate type. E.g. For I{rdtype} the integer 2 and the
the string 'NS' both mean to query for records with DNS rdata type NS.
@param qname: the query name
@type qname: dns.name.Name object or string
@param rdtype: the query type
@type rdtype: int or string
@param rdclass: the query class
@type rdclass: int or string
@param tcp: use TCP to make the query (default is False).
@type tcp: bool
@param source: bind to this IP address (defaults to machine default
IP).
@type source: IP address in dotted quad notation
@param raise_on_no_answer: raise NoAnswer if there's no answer
(defaults is True).
@type raise_on_no_answer: bool
@param source_port: The port from which to send the message.
The default is 0.
@type source_port: int
@rtype: dns.resolver.Answer instance
@raises Timeout: no answers could be found in the specified lifetime
@raises NXDOMAIN: the query name does not exist
@raises YXDOMAIN: the query name is too long after DNAME substitution
@raises NoAnswer: the response did not contain an answer and
raise_on_no_answer is True.
@raises NoNameservers: no non-broken nameservers are available to
answer the question."""
if isinstance(qname, string_types):
qname = dns.name.from_text(qname, None)
if isinstance(rdtype, string_types):
rdtype = dns.rdatatype.from_text(rdtype)
if dns.rdatatype.is_metatype(rdtype):
raise NoMetaqueries
if isinstance(rdclass, string_types):
rdclass = dns.rdataclass.from_text(rdclass)
if dns.rdataclass.is_metaclass(rdclass):
raise NoMetaqueries
qnames_to_try = []
if qname.is_absolute():
qnames_to_try.append(qname)
else:
if len(qname) > 1:
qnames_to_try.append(qname.concatenate(dns.name.root))
if self.search:
for suffix in self.search:
qnames_to_try.append(qname.concatenate(suffix))
else:
qnames_to_try.append(qname.concatenate(self.domain))
all_nxdomain = True
nxdomain_responses = {}
start = time.time()
_qname = None # make pylint happy
for _qname in qnames_to_try:
if self.cache:
answer = self.cache.get((_qname, rdtype, rdclass))
if answer is not None:
if answer.rrset is None and raise_on_no_answer:
raise NoAnswer(response=answer.response)
else:
return answer
request = dns.message.make_query(_qname, rdtype, rdclass)
if self.keyname is not None:
request.use_tsig(self.keyring, self.keyname,
algorithm=self.keyalgorithm)
request.use_edns(self.edns, self.ednsflags, self.payload)
if self.flags is not None:
request.flags = self.flags
response = None
#
# make a copy of the servers list so we can alter it later.
#
nameservers = self.nameservers[:]
errors = []
if self.rotate:
random.shuffle(nameservers)
backoff = 0.10
while response is None:
if len(nameservers) == 0:
raise NoNameservers(request=request, errors=errors)
for nameserver in nameservers[:]:
timeout = self._compute_timeout(start)
port = self.nameserver_ports.get(nameserver, self.port)
try:
tcp_attempt = tcp
if tcp:
response = dns.query.tcp(request, nameserver,
timeout, port,
source=source,
source_port=source_port)
else:
response = dns.query.udp(request, nameserver,
timeout, port,
source=source,
source_port=source_port)
if response.flags & dns.flags.TC:
# Response truncated; retry with TCP.
tcp_attempt = True
timeout = self._compute_timeout(start)
response = \
dns.query.tcp(request, nameserver,
timeout, port,
source=source,
source_port=source_port)
except (socket.error, dns.exception.Timeout) as ex:
#
# Communication failure or timeout. Go to the
# next server
#
errors.append((nameserver, tcp_attempt, port, ex,
response))
response = None
continue
except dns.query.UnexpectedSource as ex:
#
# Who knows? Keep going.
#
errors.append((nameserver, tcp_attempt, port, ex,
response))
response = None
continue
except dns.exception.FormError as ex:
#
# We don't understand what this server is
# saying. Take it out of the mix and
# continue.
#
nameservers.remove(nameserver)
errors.append((nameserver, tcp_attempt, port, ex,
response))
response = None
continue
except EOFError as ex:
#
# We're using TCP and they hung up on us.
# Probably they don't support TCP (though
# they're supposed to!). Take it out of the
# mix and continue.
#
nameservers.remove(nameserver)
errors.append((nameserver, tcp_attempt, port, ex,
response))
response = None
continue
rcode = response.rcode()
if rcode == dns.rcode.YXDOMAIN:
ex = YXDOMAIN()
errors.append((nameserver, tcp_attempt, port, ex,
response))
raise ex
if rcode == dns.rcode.NOERROR or \
rcode == dns.rcode.NXDOMAIN:
break
#
# We got a response, but we're not happy with the
# rcode in it. Remove the server from the mix if
# the rcode isn't SERVFAIL.
#
if rcode != dns.rcode.SERVFAIL or not self.retry_servfail:
nameservers.remove(nameserver)
errors.append((nameserver, tcp_attempt, port,
dns.rcode.to_text(rcode), response))
response = None
if response is not None:
break
#
# All nameservers failed!
#
if len(nameservers) > 0:
#
# But we still have servers to try. Sleep a bit
# so we don't pound them!
#
> timeout = self._compute_timeout(start)
../mflix/lib/python3.7/site-packages/dns/resolver.py:1041:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <dns.resolver.Resolver object at 0x110a19518>, start = 1557994804.643714
def _compute_timeout(self, start):
now = time.time()
duration = now - start
if duration < 0:
if duration < -1:
# Time going backwards is bad. Just give up.
raise Timeout(timeout=duration)
else:
# Time went backwards, but only a little. This can
# happen, e.g. under vmware with older linux kernels.
# Pretend it didn't happen.
now = start
if duration >= self.lifetime:
> raise Timeout(timeout=duration)
E dns.exception.Timeout: The DNS operation timed out after 30.005039930343628 seconds
../mflix/lib/python3.7/site-packages/dns/resolver.py:858: Timeout
During handling of the above exception, another exception occurred:
client = <FlaskClient <Flask 'mflix.factory'>>
config = <Config {'DEBUG': False, 'TESTING': False, 'PROPAGATE_EXCEPTIONS': True, 'PRESERVE_CONTEXT_ON_EXCEPTION': None, 'SECRE...ls>.add_claims at 0x1109d7d90>, 'MFLIX_DB_URI': 'mongodb+srv://m220student:m220password@mflix-wgqbw.mongodb.net/test'}>
@pytest.mark.connection
@pytest.mark.usefixtures('config')
def test_atlas_setup(client, config):
> result = get_coll_names(config)
tests/test_db_connection.py:24:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
tests/test_db_connection.py:17: in get_coll_names
db = MongoClient(config['MFLIX_DB_URI'])["mflix"]
../mflix/lib/python3.7/site-packages/pymongo/mongo_client.py:494: in __init__
res = uri_parser.parse_uri(entity, port, warn=True)
../mflix/lib/python3.7/site-packages/pymongo/uri_parser.py:416: in parse_uri
dns_options = _get_dns_txt_options(fqdn)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
hostname = 'mflix-wgqbw.mongodb.net'
def _get_dns_txt_options(hostname):
try:
results = resolver.query(hostname, 'TXT')
except (resolver.NoAnswer, resolver.NXDOMAIN):
# No TXT records
return None
except Exception as exc:
> raise ConfigurationError(str(exc))
E pymongo.errors.ConfigurationError: The DNS operation timed out after 30.005039930343628 seconds
../mflix/lib/python3.7/site-packages/pymongo/uri_parser.py:301: ConfigurationError
________________________________________________________________________ test_basic_movies _________________________________________________________________________
hostname = 'mflix-wgqbw.mongodb.net'
def _get_dns_txt_options(hostname):
try:
> results = resolver.query(hostname, 'TXT')
../mflix/lib/python3.7/site-packages/pymongo/uri_parser.py:296:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
qname = 'mflix-wgqbw.mongodb.net', rdtype = 'TXT', rdclass = 1, tcp = False, source = None, raise_on_no_answer = True, source_port = 0
def query(qname, rdtype=dns.rdatatype.A, rdclass=dns.rdataclass.IN,
tcp=False, source=None, raise_on_no_answer=True,
source_port=0):
"""Query nameservers to find the answer to the question.
This is a convenience function that uses the default resolver
object to make the query.
@see: L{dns.resolver.Resolver.query} for more information on the
parameters."""
return get_default_resolver().query(qname, rdtype, rdclass, tcp, source,
> raise_on_no_answer, source_port)
../mflix/lib/python3.7/site-packages/dns/resolver.py:1132:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <dns.resolver.Resolver object at 0x110a19518>, qname = <DNS name mflix-wgqbw.mongodb.net>, rdtype = 16, rdclass = 1, tcp = False, source = None
raise_on_no_answer = True, source_port = 0
def query(self, qname, rdtype=dns.rdatatype.A, rdclass=dns.rdataclass.IN,
tcp=False, source=None, raise_on_no_answer=True, source_port=0):
"""Query nameservers to find the answer to the question.
The I{qname}, I{rdtype}, and I{rdclass} parameters may be objects
of the appropriate type, or strings that can be converted into objects
of the appropriate type. E.g. For I{rdtype} the integer 2 and the
the string 'NS' both mean to query for records with DNS rdata type NS.
@param qname: the query name
@type qname: dns.name.Name object or string
@param rdtype: the query type
@type rdtype: int or string
@param rdclass: the query class
@type rdclass: int or string
@param tcp: use TCP to make the query (default is False).
@type tcp: bool
@param source: bind to this IP address (defaults to machine default
IP).
@type source: IP address in dotted quad notation
@param raise_on_no_answer: raise NoAnswer if there's no answer
(defaults is True).
@type raise_on_no_answer: bool
@param source_port: The port from which to send the message.
The default is 0.
@type source_port: int
@rtype: dns.resolver.Answer instance
@raises Timeout: no answers could be found in the specified lifetime
@raises NXDOMAIN: the query name does not exist
@raises YXDOMAIN: the query name is too long after DNAME substitution
@raises NoAnswer: the response did not contain an answer and
raise_on_no_answer is True.
@raises NoNameservers: no non-broken nameservers are available to
answer the question."""
if isinstance(qname, string_types):
qname = dns.name.from_text(qname, None)
if isinstance(rdtype, string_types):
rdtype = dns.rdatatype.from_text(rdtype)
if dns.rdatatype.is_metatype(rdtype):
raise NoMetaqueries
if isinstance(rdclass, string_types):
rdclass = dns.rdataclass.from_text(rdclass)
if dns.rdataclass.is_metaclass(rdclass):
raise NoMetaqueries
qnames_to_try = []
if qname.is_absolute():
qnames_to_try.append(qname)
else:
if len(qname) > 1:
qnames_to_try.append(qname.concatenate(dns.name.root))
if self.search:
for suffix in self.search:
qnames_to_try.append(qname.concatenate(suffix))
else:
qnames_to_try.append(qname.concatenate(self.domain))
all_nxdomain = True
nxdomain_responses = {}
start = time.time()
_qname = None # make pylint happy
for _qname in qnames_to_try:
if self.cache:
answer = self.cache.get((_qname, rdtype, rdclass))
if answer is not None:
if answer.rrset is None and raise_on_no_answer:
raise NoAnswer(response=answer.response)
else:
return answer
request = dns.message.make_query(_qname, rdtype, rdclass)
if self.keyname is not None:
request.use_tsig(self.keyring, self.keyname,
algorithm=self.keyalgorithm)
request.use_edns(self.edns, self.ednsflags, self.payload)
if self.flags is not None:
request.flags = self.flags
response = None
#
# make a copy of the servers list so we can alter it later.
#
nameservers = self.nameservers[:]
errors = []
if self.rotate:
random.shuffle(nameservers)
backoff = 0.10
while response is None:
if len(nameservers) == 0:
raise NoNameservers(request=request, errors=errors)
for nameserver in nameservers[:]:
timeout = self._compute_timeout(start)
port = self.nameserver_ports.get(nameserver, self.port)
try:
tcp_attempt = tcp
if tcp:
response = dns.query.tcp(request, nameserver,
timeout, port,
source=source,
source_port=source_port)
else:
response = dns.query.udp(request, nameserver,
timeout, port,
source=source,
source_port=source_port)
if response.flags & dns.flags.TC:
# Response truncated; retry with TCP.
tcp_attempt = True
timeout = self._compute_timeout(start)
response = \
dns.query.tcp(request, nameserver,
timeout, port,
source=source,
source_port=source_port)
except (socket.error, dns.exception.Timeout) as ex:
#
# Communication failure or timeout. Go to the
# next server
#
errors.append((nameserver, tcp_attempt, port, ex,
response))
response = None
continue
except dns.query.UnexpectedSource as ex:
#
# Who knows? Keep going.
#
errors.append((nameserver, tcp_attempt, port, ex,
response))
response = None
continue
except dns.exception.FormError as ex:
#
# We don't understand what this server is
# saying. Take it out of the mix and
# continue.
#
nameservers.remove(nameserver)
errors.append((nameserver, tcp_attempt, port, ex,
response))
response = None
continue
except EOFError as ex:
#
# We're using TCP and they hung up on us.
# Probably they don't support TCP (though
# they're supposed to!). Take it out of the
# mix and continue.
#
nameservers.remove(nameserver)
errors.append((nameserver, tcp_attempt, port, ex,
response))
response = None
continue
rcode = response.rcode()
if rcode == dns.rcode.YXDOMAIN:
ex = YXDOMAIN()
errors.append((nameserver, tcp_attempt, port, ex,
response))
raise ex
if rcode == dns.rcode.NOERROR or \
rcode == dns.rcode.NXDOMAIN:
break
#
# We got a response, but we're not happy with the
# rcode in it. Remove the server from the mix if
# the rcode isn't SERVFAIL.
#
if rcode != dns.rcode.SERVFAIL or not self.retry_servfail:
nameservers.remove(nameserver)
errors.append((nameserver, tcp_attempt, port,
dns.rcode.to_text(rcode), response))
response = None
if response is not None:
break
#
# All nameservers failed!
#
if len(nameservers) > 0:
#
# But we still have servers to try. Sleep a bit
# so we don't pound them!
#
> timeout = self._compute_timeout(start)
../mflix/lib/python3.7/site-packages/dns/resolver.py:1041:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <dns.resolver.Resolver object at 0x110a19518>, start = 1557994835.0560598
def _compute_timeout(self, start):
now = time.time()
duration = now - start
if duration < 0:
if duration < -1:
# Time going backwards is bad. Just give up.
raise Timeout(timeout=duration)
else:
# Time went backwards, but only a little. This can
# happen, e.g. under vmware with older linux kernels.
# Pretend it didn't happen.
now = start
if duration >= self.lifetime:
> raise Timeout(timeout=duration)
E dns.exception.Timeout: The DNS operation timed out after 30.005271196365356 seconds
../mflix/lib/python3.7/site-packages/dns/resolver.py:858: Timeout
During handling of the above exception, another exception occurred:
client = <FlaskClient <Flask 'mflix.factory'>>
@pytest.mark.connection
def test_basic_movies(client):
> (actual, num_found) = get_movies({}, 0, 20)
tests/test_db_connection.py:31:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
mflix/db.py:219: in get_movies
cursor = db.movies.find(query).sort(sort)
../mflix/lib/python3.7/site-packages/werkzeug/local.py:348: in __getattr__
return getattr(self._get_current_object(), name)
../mflix/lib/python3.7/site-packages/werkzeug/local.py:307: in _get_current_object
return self.__local()
mflix/db.py:46: in get_db
MFLIX_DB_URI,
../mflix/lib/python3.7/site-packages/pymongo/mongo_client.py:494: in __init__
res = uri_parser.parse_uri(entity, port, warn=True)
../mflix/lib/python3.7/site-packages/pymongo/uri_parser.py:416: in parse_uri
dns_options = _get_dns_txt_options(fqdn)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
hostname = 'mflix-wgqbw.mongodb.net'
def _get_dns_txt_options(hostname):
try:
results = resolver.query(hostname, 'TXT')
except (resolver.NoAnswer, resolver.NXDOMAIN):
# No TXT records
return None
except Exception as exc:
> raise ConfigurationError(str(exc))
E pymongo.errors.ConfigurationError: The DNS operation timed out after 30.005271196365356 seconds
../mflix/lib/python3.7/site-packages/pymongo/uri_parser.py:301: ConfigurationError
_____________________________________________________________________ test_search_by_movie_id ______________________________________________________________________
client = <FlaskClient <Flask 'mflix.factory'>>
@pytest.mark.connection
def test_search_by_movie_id(client):
actual = get_movie("573a13eff29313caabdd82f3")
> assert actual['title'] == 'The Martian'
E KeyError: 'title'
tests/test_db_connection.py:39: KeyError
_____________________________________________________________________ test_simple_text_search ______________________________________________________________________
hostname = 'mflix-wgqbw.mongodb.net'
def _get_dns_txt_options(hostname):
try:
> results = resolver.query(hostname, 'TXT')
../mflix/lib/python3.7/site-packages/pymongo/uri_parser.py:296:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
qname = 'mflix-wgqbw.mongodb.net', rdtype = 'TXT', rdclass = 1, tcp = False, source = None, raise_on_no_answer = True, source_port = 0
def query(qname, rdtype=dns.rdatatype.A, rdclass=dns.rdataclass.IN,
tcp=False, source=None, raise_on_no_answer=True,
source_port=0):
"""Query nameservers to find the answer to the question.
This is a convenience function that uses the default resolver
object to make the query.
@see: L{dns.resolver.Resolver.query} for more information on the
parameters."""
return get_default_resolver().query(qname, rdtype, rdclass, tcp, source,
> raise_on_no_answer, source_port)
../mflix/lib/python3.7/site-packages/dns/resolver.py:1132:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <dns.resolver.Resolver object at 0x110a19518>, qname = <DNS name mflix-wgqbw.mongodb.net>, rdtype = 16, rdclass = 1, tcp = False, source = None
raise_on_no_answer = True, source_port = 0
def query(self, qname, rdtype=dns.rdatatype.A, rdclass=dns.rdataclass.IN,
tcp=False, source=None, raise_on_no_answer=True, source_port=0):
"""Query nameservers to find the answer to the question.
The I{qname}, I{rdtype}, and I{rdclass} parameters may be objects
of the appropriate type, or strings that can be converted into objects
of the appropriate type. E.g. For I{rdtype} the integer 2 and the
the string 'NS' both mean to query for records with DNS rdata type NS.
@param qname: the query name
@type qname: dns.name.Name object or string
@param rdtype: the query type
@type rdtype: int or string
@param rdclass: the query class
@type rdclass: int or string
@param tcp: use TCP to make the query (default is False).
@type tcp: bool
@param source: bind to this IP address (defaults to machine default
IP).
@type source: IP address in dotted quad notation
@param raise_on_no_answer: raise NoAnswer if there's no answer
(defaults is True).
@type raise_on_no_answer: bool
@param source_port: The port from which to send the message.
The default is 0.
@type source_port: int
@rtype: dns.resolver.Answer instance
@raises Timeout: no answers could be found in the specified lifetime
@raises NXDOMAIN: the query name does not exist
@raises YXDOMAIN: the query name is too long after DNAME substitution
@raises NoAnswer: the response did not contain an answer and
raise_on_no_answer is True.
@raises NoNameservers: no non-broken nameservers are available to
answer the question."""
if isinstance(qname, string_types):
qname = dns.name.from_text(qname, None)
if isinstance(rdtype, string_types):
rdtype = dns.rdatatype.from_text(rdtype)
if dns.rdatatype.is_metatype(rdtype):
raise NoMetaqueries
if isinstance(rdclass, string_types):
rdclass = dns.rdataclass.from_text(rdclass)
if dns.rdataclass.is_metaclass(rdclass):
raise NoMetaqueries
qnames_to_try = []
if qname.is_absolute():
qnames_to_try.append(qname)
else:
if len(qname) > 1:
qnames_to_try.append(qname.concatenate(dns.name.root))
if self.search:
for suffix in self.search:
qnames_to_try.append(qname.concatenate(suffix))
else:
qnames_to_try.append(qname.concatenate(self.domain))
all_nxdomain = True
nxdomain_responses = {}
start = time.time()
_qname = None # make pylint happy
for _qname in qnames_to_try:
if self.cache:
answer = self.cache.get((_qname, rdtype, rdclass))
if answer is not None:
if answer.rrset is None and raise_on_no_answer:
raise NoAnswer(response=answer.response)
else:
return answer
request = dns.message.make_query(_qname, rdtype, rdclass)
if self.keyname is not None:
request.use_tsig(self.keyring, self.keyname,
algorithm=self.keyalgorithm)
request.use_edns(self.edns, self.ednsflags, self.payload)
if self.flags is not None:
request.flags = self.flags
response = None
#
# make a copy of the servers list so we can alter it later.
#
nameservers = self.nameservers[:]
errors = []
if self.rotate:
random.shuffle(nameservers)
backoff = 0.10
while response is None:
if len(nameservers) == 0:
raise NoNameservers(request=request, errors=errors)
for nameserver in nameservers[:]:
timeout = self._compute_timeout(start)
port = self.nameserver_ports.get(nameserver, self.port)
try:
tcp_attempt = tcp
if tcp:
response = dns.query.tcp(request, nameserver,
timeout, port,
source=source,
source_port=source_port)
else:
response = dns.query.udp(request, nameserver,
timeout, port,
source=source,
source_port=source_port)
if response.flags & dns.flags.TC:
# Response truncated; retry with TCP.
tcp_attempt = True
timeout = self._compute_timeout(start)
response = \
dns.query.tcp(request, nameserver,
timeout, port,
source=source,
source_port=source_port)
except (socket.error, dns.exception.Timeout) as ex:
#
# Communication failure or timeout. Go to the
# next server
#
errors.append((nameserver, tcp_attempt, port, ex,
response))
response = None
continue
except dns.query.UnexpectedSource as ex:
#
# Who knows? Keep going.
#
errors.append((nameserver, tcp_attempt, port, ex,
response))
response = None
continue
except dns.exception.FormError as ex:
#
# We don't understand what this server is
# saying. Take it out of the mix and
# continue.
#
nameservers.remove(nameserver)
errors.append((nameserver, tcp_attempt, port, ex,
response))
response = None
continue
except EOFError as ex:
#
# We're using TCP and they hung up on us.
# Probably they don't support TCP (though
# they're supposed to!). Take it out of the
# mix and continue.
#
nameservers.remove(nameserver)
errors.append((nameserver, tcp_attempt, port, ex,
response))
response = None
continue
rcode = response.rcode()
if rcode == dns.rcode.YXDOMAIN:
ex = YXDOMAIN()
errors.append((nameserver, tcp_attempt, port, ex,
response))
raise ex
if rcode == dns.rcode.NOERROR or \
rcode == dns.rcode.NXDOMAIN:
break
#
# We got a response, but we're not happy with the
# rcode in it. Remove the server from the mix if
# the rcode isn't SERVFAIL.
#
if rcode != dns.rcode.SERVFAIL or not self.retry_servfail:
nameservers.remove(nameserver)
errors.append((nameserver, tcp_attempt, port,
dns.rcode.to_text(rcode), response))
response = None
if response is not None:
break
#
# All nameservers failed!
#
if len(nameservers) > 0:
#
# But we still have servers to try. Sleep a bit
# so we don't pound them!
#
> timeout = self._compute_timeout(start)
../mflix/lib/python3.7/site-packages/dns/resolver.py:1041:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <dns.resolver.Resolver object at 0x110a19518>, start = 1557994905.996458
def _compute_timeout(self, start):
now = time.time()
duration = now - start
if duration < 0:
if duration < -1:
# Time going backwards is bad. Just give up.
raise Timeout(timeout=duration)
else:
# Time went backwards, but only a little. This can
# happen, e.g. under vmware with older linux kernels.
# Pretend it didn't happen.
now = start
if duration >= self.lifetime:
> raise Timeout(timeout=duration)
E dns.exception.Timeout: The DNS operation timed out after 30.005558013916016 seconds
../mflix/lib/python3.7/site-packages/dns/resolver.py:858: Timeout
During handling of the above exception, another exception occurred:
client = <FlaskClient <Flask 'mflix.factory'>>
@pytest.mark.connection
def test_simple_text_search(client):
> (actual, _) = get_movies({"$text": {"$search": "The Martian"}}, 0, 20)
tests/test_db_connection.py:44:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
mflix/db.py:219: in get_movies
cursor = db.movies.find(query).sort(sort)
../mflix/lib/python3.7/site-packages/werkzeug/local.py:348: in __getattr__
return getattr(self._get_current_object(), name)
../mflix/lib/python3.7/site-packages/werkzeug/local.py:307: in _get_current_object
return self.__local()
mflix/db.py:46: in get_db
MFLIX_DB_URI,
../mflix/lib/python3.7/site-packages/pymongo/mongo_client.py:494: in __init__
res = uri_parser.parse_uri(entity, port, warn=True)
../mflix/lib/python3.7/site-packages/pymongo/uri_parser.py:416: in parse_uri
dns_options = _get_dns_txt_options(fqdn)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
hostname = 'mflix-wgqbw.mongodb.net'
def _get_dns_txt_options(hostname):
try:
results = resolver.query(hostname, 'TXT')
except (resolver.NoAnswer, resolver.NXDOMAIN):
# No TXT records
return None
except Exception as exc:
> raise ConfigurationError(str(exc))
E pymongo.errors.ConfigurationError: The DNS operation timed out after 30.005558013916016 seconds
../mflix/lib/python3.7/site-packages/pymongo/uri_parser.py:301: ConfigurationError
======================================================================= 39 tests deselected ========================================================================
============================================================ 4 failed, 39 deselected in 132.43 seconds =============================================================
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment