From 6d7450a347178a1656096203160968558cfcaf3e Mon Sep 17 00:00:00 2001 From: Shane Harvey Date: Thu, 29 Apr 2021 16:51:27 -0700 Subject: [PATCH 1/2] PYTHON-2678 Resync SRV spec tests Add support for validating parsed_options and running non-TLS tests. --- .../srv_seedlist/encoded-userinfo-and-db.json | 21 ++++++++++++ .../txt-record-not-allowed-option.json | 7 ++++ ...txt-record-with-overridden-ssl-option.json | 16 +++++++++ .../srv_seedlist/uri-with-admin-database.json | 19 +++++++++++ test/srv_seedlist/uri-with-auth.json | 17 ++++++++++ test/test_dns.py | 34 +++++++++++++++---- 6 files changed, 107 insertions(+), 7 deletions(-) create mode 100644 test/srv_seedlist/encoded-userinfo-and-db.json create mode 100644 test/srv_seedlist/txt-record-not-allowed-option.json create mode 100644 test/srv_seedlist/txt-record-with-overridden-ssl-option.json create mode 100644 test/srv_seedlist/uri-with-admin-database.json create mode 100644 test/srv_seedlist/uri-with-auth.json diff --git a/test/srv_seedlist/encoded-userinfo-and-db.json b/test/srv_seedlist/encoded-userinfo-and-db.json new file mode 100644 index 0000000000..70c6c23a39 --- /dev/null +++ b/test/srv_seedlist/encoded-userinfo-and-db.json @@ -0,0 +1,21 @@ +{ + "uri": "mongodb+srv://b*b%40f3tt%3D:%244to%40L8%3DMC@test3.test.build.10gen.cc/mydb%3F?replicaSet=repl0", + "seeds": [ + "localhost.test.build.10gen.cc:27017" + ], + "hosts": [ + "localhost:27017", + "localhost:27018", + "localhost:27019" + ], + "options": { + "replicaSet": "repl0", + "ssl": true + }, + "parsed_options": { + "user": "b*b@f3tt=", + "password": "$4to@L8=MC", + "db": "mydb?" + }, + "comment": "Encoded user, pass, and DB parse correctly" +} diff --git a/test/srv_seedlist/txt-record-not-allowed-option.json b/test/srv_seedlist/txt-record-not-allowed-option.json new file mode 100644 index 0000000000..2a5cf2f007 --- /dev/null +++ b/test/srv_seedlist/txt-record-not-allowed-option.json @@ -0,0 +1,7 @@ +{ + "uri": "mongodb+srv://test10.test.build.10gen.cc/?replicaSet=repl0", + "seeds": [], + "hosts": [], + "error": true, + "comment": "Should fail because socketTimeoutMS is not an allowed option." +} diff --git a/test/srv_seedlist/txt-record-with-overridden-ssl-option.json b/test/srv_seedlist/txt-record-with-overridden-ssl-option.json new file mode 100644 index 0000000000..0ebc737bd5 --- /dev/null +++ b/test/srv_seedlist/txt-record-with-overridden-ssl-option.json @@ -0,0 +1,16 @@ +{ + "uri": "mongodb+srv://test5.test.build.10gen.cc/?ssl=false", + "seeds": [ + "localhost.test.build.10gen.cc:27017" + ], + "hosts": [ + "localhost:27017", + "localhost:27018", + "localhost:27019" + ], + "options": { + "replicaSet": "repl0", + "authSource": "thisDB", + "ssl": false + } +} diff --git a/test/srv_seedlist/uri-with-admin-database.json b/test/srv_seedlist/uri-with-admin-database.json new file mode 100644 index 0000000000..32710d75f7 --- /dev/null +++ b/test/srv_seedlist/uri-with-admin-database.json @@ -0,0 +1,19 @@ +{ + "uri": "mongodb+srv://test1.test.build.10gen.cc/adminDB?replicaSet=repl0", + "seeds": [ + "localhost.test.build.10gen.cc:27017", + "localhost.test.build.10gen.cc:27018" + ], + "hosts": [ + "localhost:27017", + "localhost:27018", + "localhost:27019" + ], + "options": { + "replicaSet": "repl0", + "ssl": true + }, + "parsed_options": { + "auth_database": "adminDB" + } +} diff --git a/test/srv_seedlist/uri-with-auth.json b/test/srv_seedlist/uri-with-auth.json new file mode 100644 index 0000000000..cc7257d85b --- /dev/null +++ b/test/srv_seedlist/uri-with-auth.json @@ -0,0 +1,17 @@ +{ + "uri": "mongodb+srv://auser:apass@test1.test.build.10gen.cc/?replicaSet=repl0", + "seeds": [ + "localhost.test.build.10gen.cc:27017", + "localhost.test.build.10gen.cc:27018" + ], + "hosts": [ + "localhost:27017", + "localhost:27018", + "localhost:27019" + ], + "parsed_options": { + "user": "auser", + "password": "apass" + }, + "comment": "Should preserve auth credentials" +} diff --git a/test/test_dns.py b/test/test_dns.py index fc5f98e3b6..62e862d5b3 100644 --- a/test/test_dns.py +++ b/test/test_dns.py @@ -30,7 +30,7 @@ from test.utils import wait_until -_TEST_PATH = os.path.join( +TEST_PATH = os.path.join( os.path.dirname(os.path.realpath(__file__)), 'srv_seedlist') class TestDNS(unittest.TestCase): @@ -40,7 +40,6 @@ class TestDNS(unittest.TestCase): def create_test(test_case): @client_context.require_replica_set - @client_context.require_tls def run_test(self): if not _HAVE_DNSPYTHON: raise unittest.SkipTest("DNS tests require the dnspython module") @@ -48,6 +47,15 @@ def run_test(self): seeds = test_case['seeds'] hosts = test_case['hosts'] options = test_case.get('options') + parsed_options = test_case.get('parsed_options') + # See DRIVERS-1324, unless tls is explicitly set to False we need TLS. + needs_tls = not (options and (options.get('ssl') == False or + options.get('tls') == False)) + if needs_tls and not client_context.tls: + self.skipTest('this test requires a TLS cluster') + if not needs_tls and client_context.tls: + self.skipTest('this test requires a non-TLS cluster') + if seeds: seeds = split_hosts(','.join(seeds)) if hosts: @@ -63,18 +71,30 @@ def run_test(self): 'readPreferenceTags', opts.pop('readpreferencetags')) opts['readPreferenceTags'] = rpts self.assertEqual(result['options'], options) + if parsed_options: + for opt in parsed_options: + if opt == 'user': + self.assertEqual(result['username'], + parsed_options[opt]) + elif opt == 'password': + self.assertEqual(result['password'], + parsed_options[opt]) + elif opt == 'auth_database' or opt == 'db': + self.assertEqual(result['database'], + parsed_options[opt]) hostname = next(iter(client_context.client.nodes))[0] # The replica set members must be configured as 'localhost'. if hostname == 'localhost': copts = client_context.default_client_options.copy() + # Remove tls since SRV parsing should add it automatically. + copts.pop('tls', None) if client_context.tls is True: - # Our test certs don't support the SRV hosts used in these tests. - copts['ssl_match_hostname'] = False + # Our test certs don't support the SRV hosts used in these + # tests. + copts['tlsAllowInvalidHostnames'] = True client = MongoClient(uri, **copts) - # Force server selection - client.admin.command('ismaster') wait_until( lambda: hosts == client.nodes, 'match test hosts to client nodes') @@ -90,7 +110,7 @@ def run_test(self): def create_tests(): - for filename in glob.glob(os.path.join(_TEST_PATH, '*.json')): + for filename in glob.glob(os.path.join(TEST_PATH, '*.json')): test_suffix, _ = os.path.splitext(os.path.basename(filename)) with open(filename) as dns_test_file: test_method = create_test(json.load(dns_test_file)) From f851c3596dba5e4402eb2e7496c73ee72c15f785 Mon Sep 17 00:00:00 2001 From: Shane Harvey Date: Mon, 3 May 2021 17:19:40 -0700 Subject: [PATCH 2/2] PYTHON-2678 Better style --- test/test_dns.py | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/test/test_dns.py b/test/test_dns.py index 62e862d5b3..c4c1b00733 100644 --- a/test/test_dns.py +++ b/test/test_dns.py @@ -72,16 +72,13 @@ def run_test(self): opts['readPreferenceTags'] = rpts self.assertEqual(result['options'], options) if parsed_options: - for opt in parsed_options: + for opt, expected in parsed_options.items(): if opt == 'user': - self.assertEqual(result['username'], - parsed_options[opt]) + self.assertEqual(result['username'], expected) elif opt == 'password': - self.assertEqual(result['password'], - parsed_options[opt]) + self.assertEqual(result['password'], expected) elif opt == 'auth_database' or opt == 'db': - self.assertEqual(result['database'], - parsed_options[opt]) + self.assertEqual(result['database'], expected) hostname = next(iter(client_context.client.nodes))[0] # The replica set members must be configured as 'localhost'. @@ -89,7 +86,7 @@ def run_test(self): copts = client_context.default_client_options.copy() # Remove tls since SRV parsing should add it automatically. copts.pop('tls', None) - if client_context.tls is True: + if client_context.tls: # Our test certs don't support the SRV hosts used in these # tests. copts['tlsAllowInvalidHostnames'] = True