Пример #1
0
    def test_tag_sets_validation(self):
        S = Secondary(tag_sets=[{}])
        self.assertEqual(
            [{}],
            rs_client(read_preference=S).read_preference.tag_sets)

        S = Secondary(tag_sets=[{'k': 'v'}])
        self.assertEqual(
            [{'k': 'v'}],
            rs_client(read_preference=S).read_preference.tag_sets)

        S = Secondary(tag_sets=[{'k': 'v'}, {}])
        self.assertEqual(
            [{'k': 'v'}, {}],
            rs_client(read_preference=S).read_preference.tag_sets)

        self.assertRaises(ValueError, Secondary, tag_sets=[])

        # One dict not ok, must be a list of dicts
        self.assertRaises(TypeError, Secondary, tag_sets={'k': 'v'})

        self.assertRaises(TypeError, Secondary, tag_sets='foo')

        self.assertRaises(TypeError, Secondary, tag_sets=['foo'])
Пример #2
0
    def test_no_secondary(self):
        t = create_mock_topology(replica_set_name='rs')
        got_ismaster(t, address, {
            'ok': 1,
            'ismaster': True,
            'setName': 'rs',
            'hosts': ['a']})

        self.assertMessage(
            'No replica set members match selector'
            ' "Secondary(tag_sets=None, max_staleness=-1)"',
            t, ReadPreference.SECONDARY)

        self.assertMessage(
            "No replica set members match selector"
            " \"Secondary(tag_sets=[{'dc': 'ny'}], max_staleness=-1)\"",
            t, Secondary(tag_sets=[{'dc': 'ny'}]))
Пример #3
0
    def test_get_collection(self):
        codec_options = CodecOptions(tz_aware=True,
                                     uuid_representation=JAVA_LEGACY)
        write_concern = WriteConcern(w=2, j=True)
        coll = self.db.get_collection('foo', codec_options,
                                      ReadPreference.SECONDARY, write_concern)

        self.assertTrue(isinstance(coll, motor.MotorCollection))
        self.assertEqual('foo', coll.name)
        self.assertEqual(codec_options, coll.codec_options)
        self.assertEqual(ReadPreference.SECONDARY, coll.read_preference)
        self.assertEqual(write_concern, coll.write_concern)

        pref = Secondary([{"dc": "sf"}])
        coll = self.db.get_collection('foo', read_preference=pref)
        self.assertEqual(pref, coll.read_preference)
        self.assertEqual(self.db.codec_options, coll.codec_options)
        self.assertEqual(self.db.write_concern, coll.write_concern)
class TestReadPreferenceObjects(unittest.TestCase):
    prefs = [Primary(),
             PrimaryPreferred(),
             Secondary(),
             Nearest(tag_sets=[{'a': 1}, {'b': 2}]),
             SecondaryPreferred(max_staleness=30)]

    def test_pickle(self):
        for pref in self.prefs:
            self.assertEqual(pref, pickle.loads(pickle.dumps(pref)))

    def test_copy(self):
        for pref in self.prefs:
            self.assertEqual(pref, copy.copy(pref))

    def test_deepcopy(self):
        for pref in self.prefs:
            self.assertEqual(pref, copy.deepcopy(pref))
Пример #5
0
    def test_with_options(self):
        coll = self.db.test
        codec_options = CodecOptions(tz_aware=True,
                                     uuid_representation=JAVA_LEGACY)

        write_concern = WriteConcern(w=2, j=True)
        coll2 = coll.with_options(codec_options, ReadPreference.SECONDARY,
                                  write_concern)

        self.assertTrue(isinstance(coll2, motor.MotorCollection))
        self.assertEqual(codec_options, coll2.codec_options)
        self.assertEqual(JAVA_LEGACY, coll2.uuid_subtype)
        self.assertEqual(ReadPreference.SECONDARY, coll2.read_preference)
        self.assertEqual(write_concern.document, coll2.write_concern)

        pref = Secondary([{"dc": "sf"}])
        coll2 = coll.with_options(read_preference=pref)
        self.assertEqual(pref.mode, coll2.read_preference)
        self.assertEqual(pref.tag_sets, coll2.tag_sets)
        self.assertEqual(coll.codec_options, coll2.codec_options)
        self.assertEqual(coll.uuid_subtype, coll2.uuid_subtype)
        self.assertEqual(coll.write_concern, coll2.write_concern)
Пример #6
0
    def test_query_and_read_mode_sharded_op_query(self):
        server = MockupDB()
        server.autoresponds('ismaster', ismaster=True, msg='isdbgrid',
                            minWireVersion=2, maxWireVersion=5)
        server.run()
        self.addCleanup(server.stop)

        client = MongoClient(server.uri)
        self.addCleanup(client.close)

        modes_without_query = (
            Primary(),
            SecondaryPreferred(),)

        modes_with_query = (
            PrimaryPreferred(),
            Secondary(),
            Nearest(),
            SecondaryPreferred([{'tag': 'value'}]),)

        find_command = SON([('find', 'test'), ('filter', {'a': 1})])
        for query in ({'a': 1}, {'$query': {'a': 1}},):
            for mode in modes_with_query + modes_without_query:
                collection = client.db.get_collection('test',
                                                      read_preference=mode)
                cursor = collection.find(query.copy())
                with going(next, cursor):
                    request = server.receives()
                    if mode in modes_without_query:
                        # Filter is hoisted out of $query.
                        request.assert_matches(Command(find_command))
                        self.assertFalse('$readPreference' in request)
                    else:
                        # Command is nested in $query.
                        request.assert_matches(Command(
                            SON([('$query', find_command),
                                 ('$readPreference', mode.document)])))

                    request.replies({'cursor': {'id': 0, 'firstBatch': [{}]}})
    def test_query_and_read_mode_sharded(self):
        server = MockupDB()
        server.autoresponds('ismaster', ismaster=True, msg='isdbgrid')
        server.run()
        self.addCleanup(server.stop)

        client = MongoClient(server.uri)
        self.addCleanup(client.close)

        modes_without_query = (
            Primary(),
            SecondaryPreferred(),)

        modes_with_query = (
            PrimaryPreferred(),
            Secondary(),
            Nearest(),
            SecondaryPreferred([{'tag': 'value'}]),)

        for query in ({'a': 1}, {'$query': {'a': 1}},):
            for mode in modes_with_query + modes_without_query:
                collection = client.db.get_collection('test',
                                                      read_preference=mode)
                cursor = collection.find(query.copy())
                with going(next, cursor):
                    request = server.receives(OpQuery)
                    if mode in modes_without_query:
                        # Query is not edited: {'a': 1} is not nested in $query,
                        # {'$query': {'a': 1}} is not hoisted.
                        request.assert_matches(query)
                        self.assertFalse('$readPreference' in request)
                    else:
                        # {'a': 1} is *always* nested in $query.
                        request.assert_matches({
                            '$query': {'a': 1},
                            '$readPreference': mode.document
                        })

                    request.replies({})
Пример #8
0
    def test_mongos(self):
        shard = client_context.client.config.shards.find_one()['host']
        num_members = shard.count(',') + 1
        if num_members == 1:
            raise SkipTest("Need a replica set shard to test.")
        coll = client_context.client.pymongo_test.get_collection(
            "test", write_concern=WriteConcern(w=num_members))
        coll.drop()
        res = coll.insert_many([{} for _ in range(5)])
        first_id = res.inserted_ids[0]
        last_id = res.inserted_ids[-1]

        # Note - this isn't a perfect test since there's no way to
        # tell what shard member a query ran on.
        for pref in (Primary(), PrimaryPreferred(), Secondary(),
                     SecondaryPreferred(), Nearest()):
            qcoll = coll.with_options(read_preference=pref)
            results = list(qcoll.find().sort([("_id", 1)]))
            self.assertEqual(first_id, results[0]["_id"])
            self.assertEqual(last_id, results[-1]["_id"])
            results = list(qcoll.find().sort([("_id", -1)]))
            self.assertEqual(first_id, results[-1]["_id"])
            self.assertEqual(last_id, results[0]["_id"])
Пример #9
0
    def test_sub_collection(self):
        # Verify that a collection with a dotted name inherits options from its
        # parent collection.
        write_concern = WriteConcern(w=2, j=True)
        read_concern = ReadConcern("majority")
        read_preference = Secondary([{"dc": "sf"}])
        codec_options = CodecOptions(tz_aware=True,
                                     uuid_representation=JAVA_LEGACY)

        coll1 = self.db.get_collection('test',
                                       write_concern=write_concern,
                                       read_concern=read_concern,
                                       read_preference=read_preference,
                                       codec_options=codec_options)

        coll2 = coll1.subcollection
        coll3 = coll1['subcollection']

        for c in [coll1, coll2, coll3]:
            self.assertEqual(write_concern, c.write_concern)
            self.assertEqual(read_concern, c.read_concern)
            self.assertEqual(read_preference, c.read_preference)
            self.assertEqual(codec_options, c.codec_options)
Пример #10
0
    def test_read_preference_document(self):

        pref = Primary()
        self.assertEqual(pref.document, {'mode': 'primary'})

        pref = PrimaryPreferred()
        self.assertEqual(pref.document, {'mode': 'primaryPreferred'})
        pref = PrimaryPreferred(tag_sets=[{'dc': 'sf'}])
        self.assertEqual(pref.document, {
            'mode': 'primaryPreferred',
            'tags': [{
                'dc': 'sf'
            }]
        })
        pref = PrimaryPreferred(tag_sets=[{'dc': 'sf'}], max_staleness=30)
        self.assertEqual(
            pref.document, {
                'mode': 'primaryPreferred',
                'tags': [{
                    'dc': 'sf'
                }],
                'maxStalenessSeconds': 30
            })

        pref = Secondary()
        self.assertEqual(pref.document, {'mode': 'secondary'})
        pref = Secondary(tag_sets=[{'dc': 'sf'}])
        self.assertEqual(pref.document, {
            'mode': 'secondary',
            'tags': [{
                'dc': 'sf'
            }]
        })
        pref = Secondary(tag_sets=[{'dc': 'sf'}], max_staleness=30)
        self.assertEqual(pref.document, {
            'mode': 'secondary',
            'tags': [{
                'dc': 'sf'
            }],
            'maxStalenessSeconds': 30
        })

        pref = SecondaryPreferred()
        self.assertEqual(pref.document, {'mode': 'secondaryPreferred'})
        pref = SecondaryPreferred(tag_sets=[{'dc': 'sf'}])
        self.assertEqual(pref.document, {
            'mode': 'secondaryPreferred',
            'tags': [{
                'dc': 'sf'
            }]
        })
        pref = SecondaryPreferred(tag_sets=[{'dc': 'sf'}], max_staleness=30)
        self.assertEqual(
            pref.document, {
                'mode': 'secondaryPreferred',
                'tags': [{
                    'dc': 'sf'
                }],
                'maxStalenessSeconds': 30
            })

        pref = Nearest()
        self.assertEqual(pref.document, {'mode': 'nearest'})
        pref = Nearest(tag_sets=[{'dc': 'sf'}])
        self.assertEqual(pref.document, {
            'mode': 'nearest',
            'tags': [{
                'dc': 'sf'
            }]
        })
        pref = Nearest(tag_sets=[{'dc': 'sf'}], max_staleness=30)
        self.assertEqual(pref.document, {
            'mode': 'nearest',
            'tags': [{
                'dc': 'sf'
            }],
            'maxStalenessSeconds': 30
        })

        with self.assertRaises(TypeError):
            Nearest(max_staleness=1.5)  # Float is prohibited.

        with self.assertRaises(ValueError):
            Nearest(max_staleness=0)

        with self.assertRaises(ValueError):
            Nearest(max_staleness=-2)
Пример #11
0
    def test_readable_writable(self):
        t = create_mock_topology(replica_set_name='rs')
        got_ismaster(t, ('a', 27017), {
            'ok': 1,
            'ismaster': True,
            'setName': 'rs',
            'hosts': ['a', 'b']
        })

        got_ismaster(
            t, ('b', 27017), {
                'ok': 1,
                'ismaster': False,
                'secondary': True,
                'setName': 'rs',
                'hosts': ['a', 'b']
            })

        self.assertTrue(t.description.topology_type_name,
                        'ReplicaSetWithPrimary')
        self.assertTrue(t.description.has_writable_server())
        self.assertTrue(t.description.has_readable_server())
        self.assertTrue(t.description.has_readable_server(Secondary()))
        self.assertFalse(
            t.description.has_readable_server(
                Secondary(tag_sets=[{
                    'tag': 'exists'
                }])))

        t = create_mock_topology(replica_set_name='rs')
        got_ismaster(
            t, ('a', 27017), {
                'ok': 1,
                'ismaster': False,
                'secondary': False,
                'setName': 'rs',
                'hosts': ['a', 'b']
            })

        got_ismaster(
            t, ('b', 27017), {
                'ok': 1,
                'ismaster': False,
                'secondary': True,
                'setName': 'rs',
                'hosts': ['a', 'b']
            })

        self.assertTrue(t.description.topology_type_name,
                        'ReplicaSetNoPrimary')
        self.assertFalse(t.description.has_writable_server())
        self.assertFalse(t.description.has_readable_server())
        self.assertTrue(t.description.has_readable_server(Secondary()))
        self.assertFalse(
            t.description.has_readable_server(
                Secondary(tag_sets=[{
                    'tag': 'exists'
                }])))

        t = create_mock_topology(replica_set_name='rs')
        got_ismaster(t, ('a', 27017), {
            'ok': 1,
            'ismaster': True,
            'setName': 'rs',
            'hosts': ['a', 'b']
        })

        got_ismaster(
            t, ('b', 27017), {
                'ok': 1,
                'ismaster': False,
                'secondary': True,
                'setName': 'rs',
                'hosts': ['a', 'b'],
                'tags': {
                    'tag': 'exists'
                }
            })

        self.assertTrue(t.description.topology_type_name,
                        'ReplicaSetWithPrimary')
        self.assertTrue(t.description.has_writable_server())
        self.assertTrue(t.description.has_readable_server())
        self.assertTrue(t.description.has_readable_server(Secondary()))
        self.assertTrue(
            t.description.has_readable_server(
                Secondary(tag_sets=[{
                    'tag': 'exists'
                }])))
Пример #12
0
    def test_direct_connection(self):
        for server_type, ismaster_response in [
            (SERVER_TYPE.RSPrimary, {
                'ok': 1,
                'ismaster': True,
                'hosts': ['a'],
                'setName': 'rs',
                'maxWireVersion': 6
            }),
            (SERVER_TYPE.RSSecondary, {
                'ok': 1,
                'ismaster': False,
                'secondary': True,
                'hosts': ['a'],
                'setName': 'rs',
                'maxWireVersion': 6
            }),
            (SERVER_TYPE.Mongos, {
                'ok': 1,
                'ismaster': True,
                'msg': 'isdbgrid',
                'maxWireVersion': 6
            }),
            (SERVER_TYPE.RSArbiter, {
                'ok': 1,
                'ismaster': False,
                'arbiterOnly': True,
                'hosts': ['a'],
                'setName': 'rs',
                'maxWireVersion': 6
            }),
            (SERVER_TYPE.Standalone, {
                'ok': 1,
                'ismaster': True,
                'maxWireVersion': 6
            }),

                # Slave.
            (SERVER_TYPE.Standalone, {
                'ok': 1,
                'ismaster': False,
                'maxWireVersion': 6
            }),
        ]:
            t = create_mock_topology()

            # Can't select a server while the only server is of type Unknown.
            with self.assertRaisesRegex(ConnectionFailure,
                                        'No servers found yet'):
                t.select_servers(any_server_selector,
                                 server_selection_timeout=0)

            got_ismaster(t, address, ismaster_response)

            # Topology type never changes.
            self.assertEqual(TOPOLOGY_TYPE.Single, t.description.topology_type)

            # No matter whether the server is writable,
            # select_servers() returns it.
            s = t.select_server(writable_server_selector)
            self.assertEqual(server_type, s.description.server_type)

            # Topology type single is always readable and writable regardless
            # of server type or state.
            self.assertEqual(t.description.topology_type_name, 'Single')
            self.assertTrue(t.description.has_writable_server())
            self.assertTrue(t.description.has_readable_server())
            self.assertTrue(t.description.has_readable_server(Secondary()))
            self.assertTrue(
                t.description.has_readable_server(
                    Secondary(tag_sets=[{
                        'tag': 'does-not-exist'
                    }])))
Пример #13
0
    def test_read_preference_document(self):

        pref = Primary()
        self.assertEqual(pref.document, {'mode': 'primary'})

        pref = PrimaryPreferred()
        self.assertEqual(pref.document, {'mode': 'primaryPreferred'})
        pref = PrimaryPreferred(tag_sets=[{'dc': 'sf'}])
        self.assertEqual(pref.document, {
            'mode': 'primaryPreferred',
            'tags': [{
                'dc': 'sf'
            }]
        })
        pref = PrimaryPreferred(tag_sets=[{'dc': 'sf'}], max_staleness=30)
        self.assertEqual(
            pref.document, {
                'mode': 'primaryPreferred',
                'tags': [{
                    'dc': 'sf'
                }],
                'maxStalenessMS': 30000
            })

        pref = Secondary()
        self.assertEqual(pref.document, {'mode': 'secondary'})
        pref = Secondary(tag_sets=[{'dc': 'sf'}])
        self.assertEqual(pref.document, {
            'mode': 'secondary',
            'tags': [{
                'dc': 'sf'
            }]
        })
        pref = Secondary(tag_sets=[{'dc': 'sf'}], max_staleness=30)
        self.assertEqual(pref.document, {
            'mode': 'secondary',
            'tags': [{
                'dc': 'sf'
            }],
            'maxStalenessMS': 30000
        })

        pref = SecondaryPreferred()
        self.assertEqual(pref.document, {'mode': 'secondaryPreferred'})
        pref = SecondaryPreferred(tag_sets=[{'dc': 'sf'}])
        self.assertEqual(pref.document, {
            'mode': 'secondaryPreferred',
            'tags': [{
                'dc': 'sf'
            }]
        })
        pref = SecondaryPreferred(tag_sets=[{'dc': 'sf'}], max_staleness=30)
        self.assertEqual(
            pref.document, {
                'mode': 'secondaryPreferred',
                'tags': [{
                    'dc': 'sf'
                }],
                'maxStalenessMS': 30000
            })

        pref = Nearest()
        self.assertEqual(pref.document, {'mode': 'nearest'})
        pref = Nearest(tag_sets=[{'dc': 'sf'}])
        self.assertEqual(pref.document, {
            'mode': 'nearest',
            'tags': [{
                'dc': 'sf'
            }]
        })
        pref = Nearest(tag_sets=[{'dc': 'sf'}], max_staleness=30)
        self.assertEqual(pref.document, {
            'mode': 'nearest',
            'tags': [{
                'dc': 'sf'
            }],
            'maxStalenessMS': 30000
        })
    def test_maybe_add_read_preference(self):

        # Primary doesn't add $readPreference
        out = _maybe_add_read_preference({}, Primary())
        self.assertEqual(out, {})

        pref = PrimaryPreferred()
        out = _maybe_add_read_preference({}, pref)
        self.assertEqual(
            out, SON([("$query", {}), ("$readPreference", pref.document)]))
        pref = PrimaryPreferred(tag_sets=[{'dc': 'nyc'}])
        out = _maybe_add_read_preference({}, pref)
        self.assertEqual(
            out, SON([("$query", {}), ("$readPreference", pref.document)]))

        pref = Secondary()
        out = _maybe_add_read_preference({}, pref)
        self.assertEqual(
            out, SON([("$query", {}), ("$readPreference", pref.document)]))
        pref = Secondary(tag_sets=[{'dc': 'nyc'}])
        out = _maybe_add_read_preference({}, pref)
        self.assertEqual(
            out, SON([("$query", {}), ("$readPreference", pref.document)]))

        # SecondaryPreferred without tag_sets or max_staleness doesn't add
        # $readPreference
        pref = SecondaryPreferred()
        out = _maybe_add_read_preference({}, pref)
        self.assertEqual(out, {})
        pref = SecondaryPreferred(tag_sets=[{'dc': 'nyc'}])
        out = _maybe_add_read_preference({}, pref)
        self.assertEqual(
            out, SON([("$query", {}), ("$readPreference", pref.document)]))
        pref = SecondaryPreferred(max_staleness=120)
        out = _maybe_add_read_preference({}, pref)
        self.assertEqual(
            out, SON([("$query", {}), ("$readPreference", pref.document)]))

        pref = Nearest()
        out = _maybe_add_read_preference({}, pref)
        self.assertEqual(
            out, SON([("$query", {}), ("$readPreference", pref.document)]))
        pref = Nearest(tag_sets=[{'dc': 'nyc'}])
        out = _maybe_add_read_preference({}, pref)
        self.assertEqual(
            out, SON([("$query", {}), ("$readPreference", pref.document)]))

        criteria = SON([("$query", {}), ("$orderby", SON([("_id", 1)]))])
        pref = Nearest()
        out = _maybe_add_read_preference(criteria, pref)
        self.assertEqual(
            out,
            SON([("$query", {}),
                 ("$orderby", SON([("_id", 1)])),
                 ("$readPreference", pref.document)]))
        pref = Nearest(tag_sets=[{'dc': 'nyc'}])
        out = _maybe_add_read_preference(criteria, pref)
        self.assertEqual(
            out,
            SON([("$query", {}),
                 ("$orderby", SON([("_id", 1)])),
                 ("$readPreference", pref.document)]))