示例#1
0
    def test_repr(self):
        self.assertEqual('Request()', repr(Request()))
        self.assertEqual('Request({})', repr(Request({})))
        self.assertEqual('Request({})', repr(Request([{}])))
        self.assertEqual('Request(flags=4)', repr(Request(flags=4)))

        self.assertEqual('OpQuery({})', repr(OpQuery()))
        self.assertEqual('OpQuery({})', repr(OpQuery({})))
        self.assertEqual('OpQuery({})', repr(OpQuery([{}])))
        self.assertEqual('OpQuery({}, flags=SlaveOkay)',
                         repr(OpQuery(flags=4)))
        self.assertEqual('OpQuery({}, flags=SlaveOkay)',
                         repr(OpQuery({}, flags=4)))
        self.assertEqual('OpQuery({}, flags=TailableCursor|AwaitData)',
                         repr(OpQuery({}, flags=34)))

        self.assertEqual('Command({})', repr(Command()))
        self.assertEqual('Command({"foo": 1})', repr(Command('foo')))
        son = SON([('b', 1), ('a', 1), ('c', 1)])
        self.assertEqual('Command({"b": 1, "a": 1, "c": 1})',
                         repr(Command(son)))
        self.assertEqual('Command({}, flags=SlaveOkay)',
                         repr(Command(flags=4)))

        self.assertEqual('OpInsert({}, {})', repr(OpInsert([{}, {}])))
        self.assertEqual('OpInsert({}, {})', repr(OpInsert({}, {})))
示例#2
0
    def test_bson_classes(self):
        _id = '5a918f9fa08bff9c7688d3e1'

        for a, b in [
            (Binary(b'foo'), mockup_bson.Binary(b'foo')),
            (Code('foo'), mockup_bson.Code('foo')),
            (Code('foo', {'x': 1}), mockup_bson.Code('foo', {'x': 1})),
            (DBRef('coll', 1), mockup_bson.DBRef('coll', 1)),
            (DBRef('coll', 1, 'db'), mockup_bson.DBRef('coll', 1, 'db')),
            (Decimal128('1'), mockup_bson.Decimal128('1')),
            (MaxKey(), mockup_bson.MaxKey()),
            (MinKey(), mockup_bson.MinKey()),
            (ObjectId(_id), mockup_bson.ObjectId(_id)),
            (Regex('foo', 'i'), mockup_bson.Regex('foo', 'i')),
            (Timestamp(1, 2), mockup_bson.Timestamp(1, 2)),
        ]:
            # Basic case.
            self.assertTrue(
                Matcher(Command(y=b)).matches(Command(y=b)),
                "MockupDB %r doesn't equal itself" % (b, ))

            # First Command argument is special, try comparing the second also.
            self.assertTrue(
                Matcher(Command('x', y=b)).matches(Command('x', y=b)),
                "MockupDB %r doesn't equal itself" % (b, ))

            # In practice, users pass PyMongo classes in message specs.
            self.assertTrue(
                Matcher(Command(y=b)).matches(Command(y=a)),
                "PyMongo %r != MockupDB %r" % (a, b))

            self.assertTrue(
                Matcher(Command('x', y=b)).matches(Command('x', y=a)),
                "PyMongo %r != MockupDB %r" % (a, b))
示例#3
0
    def test_projection(self):
        q = {}
        fields = {'foo': True}

        # OP_QUERY,
        server = MockupDB(auto_ismaster=True,
                          min_wire_version=0,
                          max_wire_version=3)
        server.run()
        self.addCleanup(server.stop)
        client = MongoClient(server.uri)
        cursor = client.test.collection.find(q, fields)
        with going(next, cursor):
            request = server.receives(OpQuery(q, fields=fields))
            request.reply([], cursor_id=0)

        # "find" command.
        server = MockupDB(auto_ismaster=True,
                          min_wire_version=0,
                          max_wire_version=4)
        server.run()
        self.addCleanup(server.stop)
        client = MongoClient(server.uri)
        cursor = client.test.collection.find(q, fields)
        cmd = Command(
            SON([('find', 'collection'), ('filter', q),
                 ('projection', fields)]))

        with going(next, cursor):
            request = server.receives(cmd)
            request.ok(cursor={'id': 0, 'firstBatch': []})
示例#4
0
    def test_getDataSource(self):
        # arrange
        id = 1
        future = go(self.app.get, f'/add_icecream_id/{id}')
        request = self.server.receives(
            Command(
                {
                    'find': 'dataSources',
                    'filter': {
                        '_id': id
                    },
                    'limit': 1,
                    'singleBatch': True
                },
                flags=4,
                namespace='app'))
        request.ok(
            cursor={
                'id':
                0,
                'firstBatch': [{
                    "icecream_name": "Rassberry",
                    "icecream_flavour": "Rassberry",
                    "Icecream_type": "Bar",
                    "Icecream_price": "30/-",
                    "description": "Nice"
                }]
            })

        # act
        http_response = future()
        # assert
        self.assertIn('http://google.com/rest/api',
                      http_response.get_data(as_text=True))
示例#5
0
    def test_getDataSource(self):
        # arrange

        future = go(self.app.get, f'/Login-Page/{username}')
        request = self.server.receives(
            Command(
                {
                    'find': 'dataSources',
                    'filter': {
                        'username': username
                    },
                    'limit': 1,
                    'singleBatch': True
                },
                flags=4,
                namespace='app'))
        request.ok(
            cursor={
                'firstBatch':
                [{
                    "username": "******",
                    "password": "******"["http://http://0.0.0.0:5000/"]
                }]
            })

        # act
        http_response = future()
示例#6
0
 def test_autoresponds_case_insensitive(self):
     server = MockupDB(auto_ismaster=True)
     # Little M. Note this is only case-insensitive because it's a Command.
     server.autoresponds(Command('fooBar'), foo='bar')
     server.run()
     response = MongoClient(server.uri).admin.command('Foobar')
     self.assertEqual('bar', response['foo'])
示例#7
0
    def test_getDataSources(self):
        # arrange
        future = go(self.app.get, '/dataSources')
        request = self.server.receives(
            Command({
                'find': 'dataSources',
                'filter': {}
            },
                    flags=4,
                    namespace='app'))
        request.ok(
            cursor={
                'id':
                0,
                'firstBatch': [{
                    'name': 'Google',
                    'url': 'http://google.com/rest/api'
                }, {
                    'name': 'Rest',
                    'url': 'http://rest.com/rest/api'
                }]
            })

        # act
        http_response = future()

        # assert
        data = http_response.get_data(as_text=True)
        self.assertIn('http://google.com/rest/api', data)
        self.assertIn('http://rest.com/rest/api', data)
示例#8
0
    def test_getDataSource(self):
        # arrange
        id = '5a8f1e368f7936badfbb0cfa'
        future = go(self.app.get, f'/dataSource/{id}')
        request = self.server.receives(
            Command(
                {
                    'find': 'dataSources',
                    'filter': {
                        '_id': mockup_oid(id)
                    },
                    'limit': 1,
                    'singleBatch': True
                },
                flags=4,
                namespace='app'))
        request.ok(
            cursor={
                'id':
                0,
                'firstBatch': [{
                    'name': 'bla',
                    'url': 'http://google.com/rest/api'
                }]
            })

        # act
        http_response = future()

        # assert
        self.assertIn('http://google.com/rest/api',
                      http_response.get_data(as_text=True))
示例#9
0
    def test_deleteDataSource_notFound(self):
        # arrange
        id = '5a8f1e368f7936badfbb0000'
        future = go(self.app.delete, f'/dataSource/{id}')
        request = self.server.receives(
            Command(
                {
                    'delete': 'dataSources',
                    'ordered': True,
                    'deletes': [{
                        'q': {
                            '_id': mockup_oid(id)
                        },
                        'limit': 1
                    }]
                },
                namespace='app'))
        request.ok({'acknowledged': True, 'n': 0})

        # act
        http_response = future()

        # assert
        self.assertIn(f'{id} not found', http_response.get_data(as_text=True))
        self.assertEqual(http_response.status_code, 404)
示例#10
0
    def test_addDataSource(self):
        # arrange
        id = '5a924d7a29a6e5484dcf68be'
        headers = [('Content-Type', 'application/json')]
        #   need to pass _id because pymongo creates one so it's impossible to match insert request without _ids
        toInsert = {'name': 'new', 'url': 'http://google.com', '_id': id}
        future = go(self.app.put,
                    '/dataSource',
                    data=dumps(toInsert),
                    headers=headers)
        request = self.server.receives(
            Command(
                {
                    'insert':
                    'dataSources',
                    'ordered':
                    True,
                    'documents': [{
                        'name': 'new',
                        'url': 'http://google.com',
                        '_id': mockup_oid(id)
                    }]
                },
                namespace='app'))
        request.ok(cursor={'inserted_id': id})

        # act
        http_response = future()

        # assert
        data = http_response.get_data(as_text=True)
        self.assertIn(id, data)
        self.assertEqual(http_response.status_code, 201)
    def test_insert_command_manipulate_false(self):
        # Test same three aspects as test_op_insert_manipulate_false does,
        # with the "insert" command.
        server = MockupDB(auto_ismaster={'maxWireVersion': 2})
        server.run()
        self.addCleanup(server.stop)

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

        doc = {}
        with going(client.db.coll.insert, doc, manipulate=False) as future:
            r = server.receives(Command("insert", "coll", documents=[{}]))
            # MockupDB doesn't understand "absent" in subdocuments yet.
            self.assertFalse('_id' in r.doc['documents'][0])
            r.ok()

        self.assertFalse('_id' in doc)
        self.assertIsNone(future())

        docs = [{}]  # One doc in a list.
        with going(client.db.coll.insert, docs, manipulate=False) as future:
            r = server.receives(Command("insert", "coll", documents=[{}]))
            self.assertFalse('_id' in r.doc['documents'][0])
            r.ok()

        self.assertFalse('_id' in docs[0])
        self.assertEqual(future(), [None])

        docs = [{}, {}]  # Two docs.
        with going(client.db.coll.insert, docs, manipulate=False) as future:
            r = server.receives(Command("insert", "coll", documents=[{}, {}]))
            self.assertFalse('_id' in r.doc['documents'][0])
            self.assertFalse('_id' in r.doc['documents'][1])
            r.ok()

        self.assertFalse('_id' in docs[0])
        self.assertFalse('_id' in docs[1])
        self.assertEqual(future(), [None, None])
示例#12
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': [{}]}})
示例#13
0
    def setUp(self):
        self.loop = asyncio.new_event_loop()
        asyncio.set_event_loop(self.loop)

        self.server = MockupDB(auto_ismaster={"maxWireVersion": 6})
        self.server.run()
        self.server.autoresponds(
            Command("find", "switch_collection",
                    namespace="topology_database"),
            {
                "cursor": {
                    "id":
                    0,
                    "firstBatch": [{
                        **d, "_id": i
                    } for i, d in enumerate(TOPOLOGY_DATABASE_DATA)],
                }
            },
        )

        self._stack = AsyncExitStack()

        td = self._stack.enter_context(tempfile.TemporaryDirectory())
        self.rpc_unix_sock = os.path.join(td, "l.sock")

        self._stack.enter_context(
            patch.object(settings, "REMOTE_DATABASE_MONGO_URI",
                         self.server.uri))
        self._stack.enter_context(
            patch.object(settings, "NEGOTIATOR_RPC_UNIX_SOCK_PATH",
                         self.rpc_unix_sock))
        self._stack.enter_context(
            patch("agile_mesh_network.ryu.amn_manager.OVSManager",
                  DummyOVSManager))
        self._stack.enter_context(
            # To avoid automatic connection to a relay.
            patch.object(settings, "IS_RELAY", True))

        self._stack.enter_context(
            patch.object(events_scheduler, "RyuAppEventLoopScheduler"))
        self.ryu_ev_loop_scheduler = events_scheduler.RyuAppEventLoopScheduler(
        )
        self._stack.enter_context(self.ryu_ev_loop_scheduler)

        async def command_cb(session, msg):
            assert isinstance(msg, RPCCommand)
            await self._rpc_command_cb(msg)

        self.rpc_server = self.loop.run_until_complete(
            self._stack.enter_async_context(
                RPCUnixServer(self.rpc_unix_sock, command_cb)))
示例#14
0
    def test_find_command(self):
        server = MockupDB(auto_ismaster={'maxWireVersion': 4})
        server.run()
        self.addCleanup(server.stop)
        client = MongoClient(server.uri)
        with going(list, client.test.collection.find()) as docs:
            server.receives(Command).reply({'cursor': {
                'id': 123,
                'firstBatch': [{'a': 1}]}})

            request = server.receives(Command("getMore", 123))
            request.reply({'cursor': {
                'id': 0,
                'nextBatch': [{'a': 2}]}},
                starting_from=-3)

        self.assertEqual([{'a': 1}, {'a': 2}], docs())
示例#15
0
    def test_getDataSource_404(self):
        id = '5a8f1e368f7936badfbb0cfb'
        future = go(self.app.get, f'/dataSource/{id}')
        request = self.server.receives(
            Command(
                {
                    'find': 'dataSources',
                    'filter': {
                        '_id': mockup_oid(id)
                    },
                    'limit': 1,
                    'singleBatch': True
                },
                flags=4,
                namespace='app'))
        request.ok(cursor={'id': 0, 'firstBatch': []})

        # act
        http_response = future()

        # assert
        self.assertEqual(http_response.status_code, 404)
示例#16
0
    def test_command_fields(self):
        self.assertTrue(Matcher(Command('a', b=1)).matches(Command('a', b=1)))

        self.assertFalse(Matcher(Command('a', b=1)).matches(Command('a', b=2)))
示例#17
0
 def test_command_first_arg(self):
     self.assertFalse(
         Matcher(Command(ismaster=1)).matches(Command(ismaster=2)))
示例#18
0
 def test_command_name_case_insensitive(self):
     self.assertTrue(
         Matcher(Command('ismaster')).matches(Command('IsMaster')))
示例#19
0
    def test_assert_matches(self):
        request = OpQuery({'x': 17}, flags=QUERY_FLAGS['SlaveOkay'])
        request.assert_matches(request)

        with self.assertRaises(AssertionError):
            request.assert_matches(Command('foo'))
示例#20
0
    def test_client_handshake_data(self):
        primary, secondary = MockupDB(), MockupDB()
        for server in primary, secondary:
            server.run()
            self.addCleanup(server.stop)

        hosts = [server.address_string for server in (primary, secondary)]
        primary_response = OpReply('ismaster', True,
                                   setName='rs', hosts=hosts,
                                   minWireVersion=2, maxWireVersion=6)
        error_response = OpReply(
            0, errmsg='Cache Reader No keys found for HMAC ...', code=211)

        secondary_response = OpReply('ismaster', False,
                                     setName='rs', hosts=hosts,
                                     secondary=True,
                                     minWireVersion=2, maxWireVersion=6)

        client = MongoClient(primary.uri,
                             replicaSet='rs',
                             appname='my app',
                             heartbeatFrequencyMS=500)  # Speed up the test.

        self.addCleanup(client.close)

        # New monitoring sockets send data during handshake.
        heartbeat = primary.receives('ismaster')
        _check_handshake_data(heartbeat)
        heartbeat.ok(primary_response)

        heartbeat = secondary.receives('ismaster')
        _check_handshake_data(heartbeat)
        heartbeat.ok(secondary_response)

        # Subsequent heartbeats have no client data.
        primary.receives('ismaster', 1, client=absent).ok(error_response)
        secondary.receives('ismaster', 1, client=absent).ok(error_response)
        # The heartbeat retry has no client data after a command failure.
        primary.receives('ismaster', 1, client=absent).ok(error_response)
        secondary.receives('ismaster', 1, client=absent).ok(error_response)
        # Still no client data.
        primary.receives('ismaster', 1, client=absent).ok(primary_response)
        secondary.receives('ismaster', 1, client=absent).ok(secondary_response)

        # After a disconnect, next ismaster has client data again.
        primary.receives('ismaster', 1, client=absent).hangup()
        heartbeat = primary.receives('ismaster')
        _check_handshake_data(heartbeat)
        heartbeat.ok(primary_response)

        secondary.autoresponds('ismaster', secondary_response)

        # Start a command, so the client opens an application socket.
        future = go(client.db.command, 'whatever')

        for request in primary:
            if request.matches(Command('ismaster')):
                if request.client_port == heartbeat.client_port:
                    # This is the monitor again, keep going.
                    request.ok(primary_response)
                else:
                    # Handshaking a new application socket.
                    _check_handshake_data(request)
                    request.ok(primary_response)
            else:
                # Command succeeds.
                if version_tuple >= (3, 7):
                    request.assert_matches(OpMsg('whatever'))
                else:
                    request.assert_matches(Command('whatever'))
                request.ok()
                assert future()
                return
示例#21
0
    def test_client_handshake_data(self):
        primary, secondary = MockupDB(), MockupDB()
        for server in primary, secondary:
            server.run()
            self.addCleanup(server.stop)

        hosts = [server.address_string for server in primary, secondary]
        primary_response = OpReply('ismaster', True, setName='rs', hosts=hosts)

        secondary_response = OpReply('ismaster',
                                     False,
                                     setName='rs',
                                     hosts=hosts,
                                     secondary=True)

        client = MongoClient(primary.uri,
                             replicaSet='rs',
                             appname='my app',
                             heartbeatFrequencyMS=500)  # Speed up the test.

        self.addCleanup(client.close)

        # New monitoring sockets send data during handshake.
        heartbeat = primary.receives('ismaster')
        _check_handshake_data(heartbeat)
        heartbeat.ok(primary_response)

        heartbeat = secondary.receives('ismaster')
        _check_handshake_data(heartbeat)
        heartbeat.ok(secondary_response)

        # Subsequent heartbeats have no client data.
        primary.receives('ismaster', 1, client=absent).ok(primary_response)
        secondary.receives('ismaster', 1, client=absent).ok(secondary_response)

        # After a disconnect, next ismaster has client data again.
        primary.receives('ismaster', 1, client=absent).hangup()
        heartbeat = primary.receives('ismaster')
        _check_handshake_data(heartbeat)
        heartbeat.ok(primary_response)

        secondary.autoresponds('ismaster', secondary_response)

        # Start a command, so the client opens an application socket.
        future = go(client.db.command, 'whatever')

        for request in primary:
            if request.matches(Command('ismaster')):
                if request.client_port == heartbeat.client_port:
                    # This is the monitor again, keep going.
                    request.ok(primary_response)
                else:
                    # Handshaking a new application socket.
                    _check_handshake_data(heartbeat)
                    request.ok(primary_response)
            else:
                # Command succeeds.
                request.assert_matches(Command('whatever'))
                request.ok()
                assert future()
                return