PYTHON-1418 - Update initial DNS seedlist implementation for spec changes

This commit is contained in:
Bernie Hackett 2017-11-15 19:06:40 -08:00
parent b669cd86dc
commit a689aa63ca
21 changed files with 162 additions and 17 deletions

View File

@ -295,8 +295,8 @@ def _get_dns_txt_options(hostname):
return None
except Exception as exc:
raise ConfigurationError(str(exc))
return '&'.join([maybe_decode(val)
for res in results for val in res.strings])
return (
b'&'.join([b''.join(res.strings) for res in results])).decode('utf-8')
def parse_uri(uri, default_port=DEFAULT_PORT, validate=True, warn=False):
@ -386,12 +386,28 @@ def parse_uri(uri, default_port=DEFAULT_PORT, validate=True, warn=False):
raise InvalidURI(
"%s URIs must include one, "
"and only one, hostname" % (SRV_SCHEME,))
hostname, port = nodes[0]
fqdn, port = nodes[0]
if port is not None:
raise InvalidURI(
"%s URIs must not include a port number" % (SRV_SCHEME,))
nodes = _get_dns_srv_hosts(hostname)
dns_options = _get_dns_txt_options(hostname)
nodes = _get_dns_srv_hosts(fqdn)
try:
plist = fqdn.split(".")[1:]
except Exception:
raise ConfigurationError("Invalid URI host")
slen = len(plist)
if slen < 2:
raise ConfigurationError("Invalid URI host")
for node in nodes:
try:
nlist = node[0].split(".")[1:][-slen:]
except Exception:
raise ConfigurationError("Invalid SRV host")
if plist != nlist:
raise ConfigurationError("Invalid SRV host")
dns_options = _get_dns_txt_options(fqdn)
if dns_options:
options = split_options(dns_options, validate, warn)
else:

View File

@ -0,0 +1,12 @@
{
"uri": "mongodb+srv://test18.test.build.10gen.cc/?replicaSet=repl0",
"seeds": [
"localhost.sub.test.build.10gen.cc:27017"
],
"hosts": [
"localhost:27017",
"localhost:27018",
"localhost:27019"
],
"comment": "Is correct, as returned host name shared the URI root \"test.build.10gen.cc\"."
}

View File

@ -1,5 +1,7 @@
{
"uri": "mongodb+srv://test4.test.build.10gen.cc/",
"seeds": [],
"hosts": []
"hosts": [],
"error": true,
"comment": "Should fail because no SRV records are present for this URI."
}

View File

@ -0,0 +1,7 @@
{
"uri": "mongodb+srv://10gen.cc/",
"seeds": [],
"hosts": [],
"error": true,
"comment": "Should fail because host in URI does not have {hostname}, {domainname} and {tld}."
}

View File

@ -1,7 +1,7 @@
{
"uri": "mongodb+srv://test3.test.build.10gen.cc/?replicaSet=repl0",
"seeds": [
"localhost.build.10gen.cc:27017"
"localhost.test.build.10gen.cc:27017"
],
"hosts": [
"localhost:27017",

View File

@ -0,0 +1,16 @@
{
"uri": "mongodb+srv://test11.test.build.10gen.cc/?replicaSet=repl0",
"seeds": [
"localhost.test.build.10gen.cc:27017"
],
"hosts": [
"localhost:27017",
"localhost:27018",
"localhost:27019"
],
"options": {
"connectTimeoutMS": 150000,
"replicaSet": "repl0",
"socketTimeoutMS": 250000
}
}

View File

@ -1,7 +1,7 @@
{
"uri": "mongodb+srv://test5.test.build.10gen.cc/?replicaSet=repl0",
"seeds": [
"localhost.build.10gen.cc:27017"
"localhost.test.build.10gen.cc:27017"
],
"hosts": [
"localhost:27017",

View File

@ -0,0 +1,7 @@
{
"uri": "mongodb+srv://test14.test.build.10gen.cc/",
"seeds": [],
"hosts": [],
"error": true,
"comment": "Should fail because returned host name's part \"not-test\" mismatches URI parent part \"test\"."
}

View File

@ -0,0 +1,7 @@
{
"uri": "mongodb+srv://test15.test.build.10gen.cc/",
"seeds": [],
"hosts": [],
"error": true,
"comment": "Should fail because returned host name's part \"not-build\" mismatches URI parent part \"build\"."
}

View File

@ -0,0 +1,7 @@
{
"uri": "mongodb+srv://test16.test.build.10gen.cc/",
"seeds": [],
"hosts": [],
"error": true,
"comment": "Should fail because returned host name's part \"not-10gen\" mismatches URI parent part \"10gen\"."
}

View File

@ -0,0 +1,7 @@
{
"uri": "mongodb+srv://test17.test.build.10gen.cc/",
"seeds": [],
"hosts": [],
"error": true,
"comment": "Should fail because returned host name's TLD \"not-cc\" mismatches URI TLD \"cc\"."
}

View File

@ -0,0 +1,7 @@
{
"uri": "mongodb+srv://test13.test.build.10gen.cc/",
"seeds": [],
"hosts": [],
"error": true,
"comment": "Should fail because returned host name's parent (build.10gen.cc) misses \"test.\""
}

View File

@ -1,8 +1,8 @@
{
"uri": "mongodb+srv://test1.test.build.10gen.cc/?replicaSet=repl0",
"seeds": [
"localhost.build.10gen.cc:27017",
"localhost.build.10gen.cc:27018"
"localhost.test.build.10gen.cc:27017",
"localhost.test.build.10gen.cc:27018"
],
"hosts": [
"localhost:27017",

View File

@ -1,8 +1,8 @@
{
"uri": "mongodb+srv://test2.test.build.10gen.cc/?replicaSet=repl0",
"seeds": [
"localhost.build.10gen.cc:27018",
"localhost.build.10gen.cc:27019"
"localhost.test.build.10gen.cc:27018",
"localhost.test.build.10gen.cc:27019"
],
"hosts": [
"localhost:27017",

View File

@ -1,7 +1,7 @@
{
"uri": "mongodb+srv://test6.test.build.10gen.cc/?replicaSet=repl0&connectTimeoutMS=250000",
"seeds": [
"localhost.build.10gen.cc:27017"
"localhost.test.build.10gen.cc:27017"
],
"hosts": [
"localhost:27017",

View File

@ -1,7 +1,7 @@
{
"uri": "mongodb+srv://test6.test.build.10gen.cc/?replicaSet=repl0",
"seeds": [
"localhost.build.10gen.cc:27017"
"localhost.test.build.10gen.cc:27017"
],
"hosts": [
"localhost:27017",

View File

@ -0,0 +1,25 @@
{
"uri": "mongodb+srv://test7.test.build.10gen.cc/?replicaSet=repl0&readPreferenceTags=dc:fr,item:cheese&readPreferenceTags=dc:de,item:hotdog",
"seeds": [
"localhost.test.build.10gen.cc:27017"
],
"hosts": [
"localhost:27017",
"localhost:27018",
"localhost:27019"
],
"options": {
"replicaSet": "repl0",
"readPreference": "secondaryPreferred",
"readPreferenceTags": [
{
"dc": "fr",
"item": "cheese"
},
{
"dc": "de",
"item": "hotdog"
}
]
}
}

View File

@ -0,0 +1,7 @@
{
"uri": "mongodb+srv://test10.test.build.10gen.cc/?replicaSet=repl0",
"seeds": [],
"hosts": [],
"error": true,
"comment": "Should fail because the value of socketTimeoutMS is not an integer."
}

View File

@ -0,0 +1,7 @@
{
"uri": "mongodb+srv://test5.test.build.10gen.cc:8123/?replicaSet=repl0",
"seeds": [],
"hosts": [],
"error": true,
"comment": "Should fail because the mongodb+srv URI includes a port."
}

View File

@ -0,0 +1,7 @@
{
"uri": "mongodb+srv://test5.test.build.10gen.cc,test6.test.build.10gen.cc/?replicaSet=repl0",
"seeds": [],
"hosts": [],
"error": true,
"comment": "Should fail because the mongodb+srv URI includes two host names."
}

View File

@ -21,6 +21,7 @@ import sys
sys.path[0:0] = [""]
from pymongo.common import validate_read_preference_tags
from pymongo.errors import ConfigurationError
from pymongo.mongo_client import MongoClient
from pymongo.uri_parser import parse_uri, split_hosts, _HAVE_DNSPYTHON
@ -57,12 +58,18 @@ def create_test(test_case):
if options:
for key, value in options.items():
# Convert numbers to strings for comparison
options[key] = str(value)
if isinstance(value, (int, float)):
options[key] = str(value)
if seeds:
result = parse_uri(uri, validate=False)
self.assertEqual(sorted(result['nodelist']), sorted(seeds))
if options:
opts = result['options']
if 'readpreferencetags' in opts:
rpts = validate_read_preference_tags(
'readPreferenceTags', opts.pop('readpreferencetags'))
opts['readPreferenceTags'] = rpts
self.assertEqual(result['options'], options)
hostname = next(iter(client_context.client.nodes))[0]
@ -75,8 +82,12 @@ def create_test(test_case):
lambda: hosts == client.nodes,
'match test hosts to client nodes')
else:
self.assertRaises(
ConfigurationError, parse_uri, uri, validate=False)
try:
parse_uri(uri)
except (ConfigurationError, ValueError):
pass
else:
self.fail("failed to raise an exception")
return run_test