Ejemplo n.º 1
0
    def test_use_schema_resp(
        self,
        api: SpanAPI,
        resp_dump: DumpOptions,
        data_send: Union[Name, dict],
        data_returned: dict,
        error: Optional[Type[errors_api.APIError]],
        bson: bool,
    ):
        @api.route("/test")
        class TestRoute(SpanRoute):
            @api.use_schema(resp=NameSchema(), resp_dump=resp_dump)
            async def on_get(self, req: Request, resp: Response):
                resp.media = data_send

        with api.requests as client:
            if bson:
                headers = {"accept": "application/bson"}
            else:
                headers = {}

            r = client.get("/test", headers=headers)

            if error is not None:
                validate_error(r, error)
            else:
                validate_response(r)

            if error is None:
                if bson:
                    assert dict(RawBSONDocument(r.content)) == dict(
                        RawBSONDocument(BSON.encode(data_returned))
                    )
                else:
                    assert r.json() == data_returned
Ejemplo n.º 2
0
    def test_raw_bson_document_embedded(self):
        doc = {'embedded': self.document}
        db = self.client.pymongo_test
        db.test_raw.insert_one(doc)
        result = db.test_raw.find_one()
        self.assertEqual(decode(self.document.raw), result['embedded'])

        # Make sure that CodecOptions are preserved.
        # {'embedded': [
        #   {'date': datetime.datetime(2015, 6, 3, 18, 40, 50, 826000),
        #    '_id': UUID('026fab8f-975f-4965-9fbf-85ad874c60ff')}
        # ]}
        # encoded with JAVA_LEGACY uuid representation.
        bson_string = (
            b'D\x00\x00\x00\x04embedded\x005\x00\x00\x00\x030\x00-\x00\x00\x00'
            b'\tdate\x00\x8a\xd6\xb9\xbaM\x01\x00\x00\x05_id\x00\x10\x00\x00'
            b'\x00\x03eI_\x97\x8f\xabo\x02\xff`L\x87\xad\x85\xbf\x9f\x00\x00'
            b'\x00'
        )
        rbd = RawBSONDocument(
            bson_string,
            codec_options=CodecOptions(uuid_representation=JAVA_LEGACY,
                                       document_class=RawBSONDocument))

        db.test_raw.drop()
        db.test_raw.insert_one(rbd)
        result = db.get_collection('test_raw', codec_options=CodecOptions(
            uuid_representation=JAVA_LEGACY)).find_one()
        self.assertEqual(rbd['embedded'][0]['_id'],
                         result['embedded'][0]['_id'])
Ejemplo n.º 3
0
    def insert_data_key(self, data_key):
        """Insert a data key into the key vault.

        :Parameters:
          - `data_key`: The data key document to insert.

        :Returns:
          The _id of the inserted data key document.
        """
        raw_doc = RawBSONDocument(data_key)
        data_key_id = raw_doc.get('_id')
        if not isinstance(data_key_id, uuid.UUID):
            raise TypeError('data_key _id must be a UUID')

        self.key_vault_coll.insert_one(raw_doc)
        return Binary(data_key_id.bytes, subtype=UUID_SUBTYPE)
Ejemplo n.º 4
0
def load_file(file_path: str, session: Session) -> None:
    """Loads the file to the databases.

    If there already is a file with the same pk, then nothing is done.

    The json is converted into BSON and it's stored like this in the database
    to avoid problems with dots in the keys.
    """
    try:
        with open(file_path) as f:
            log.info(f"Loading {file_path}")
            chunk = loads(f.read())

            doc_id = chunk["pk"]
            chunk["_id"] = doc_id
            chunk[FETCHED_FIELD_NAME] = False

            chunk = RawBSONDocument(bson.BSON.encode(chunk))

            if session.collection.count_documents({"_id": doc_id}) != 0:
                log.info(
                    f"Skipping - there is already a document with id={doc_id}")
            else:
                session.collection.insert_one(chunk)
    except Exception as e:
        log.error(f"{e}")
Ejemplo n.º 5
0
 def raw_response(self, cursor_id=None, user_fields={}):  # noqa: B006
     """
     cursor_id is ignored
     user_fields is used to determine which fields must not be decoded
     """
     inflated_response = _decode_selective(
         RawBSONDocument(self.payload_document), user_fields,
         DEFAULT_RAW_BSON_OPTIONS)
     return [inflated_response]
Ejemplo n.º 6
0
def bson_decode(
        content: bytes) -> Union[RawBSONDocument, List[RawBSONDocument]]:
    """
    Decodes ``content`` bytes to RawBSONDocument(s)
    """
    if content.startswith(BSON_RECORD_DELIM):
        return bson_decode_list(content)
    else:
        return RawBSONDocument(content)
    def test_preserve_key_ordering(self):
        keyvaluepairs = [
            ('a', 1),
            ('b', 2),
            ('c', 3),
        ]
        rawdoc = RawBSONDocument(encode(SON(keyvaluepairs)))

        for rkey, elt in zip(rawdoc, keyvaluepairs):
            self.assertEqual(rkey, elt[0])
Ejemplo n.º 8
0
def bson_decode_list(content: bytes) -> List[RawBSONDocument]:
    record_raw_list = content.split(BSON_RECORD_DELIM)
    # The first record is always going to be blank.
    record_raw_list.pop(0)
    loaded_list: List[RawBSONDocument] = list()

    for record_raw in record_raw_list:
        loaded_list.append(RawBSONDocument(record_raw))

    return loaded_list
Ejemplo n.º 9
0
    def fetch_keys(self, filter):
        """Yields one or more keys from the key vault.

        :Parameters:
          - `filter`: The filter to pass to find.

        :Returns:
          A generator which yields the requested keys from the key vault.
        """
        with self.key_vault_coll.find(RawBSONDocument(filter)) as cursor:
            for key in cursor:
                yield key.raw
Ejemplo n.º 10
0
    def test_round_trip_raw_uuid(self):
        coll = self.client.get_database('pymongo_test').test_raw
        uid = uuid.uuid4()
        doc = {'_id': 1,
               'bin4': Binary(uid.bytes, 4),
               'bin3': Binary(uid.bytes, 3)}
        raw = RawBSONDocument(encode(doc))
        coll.insert_one(raw)
        self.assertEqual(coll.find_one(), {'_id': 1, 'bin4': uid, 'bin3': uid})

        # Test that the raw bytes haven't changed.
        raw_coll = coll.with_options(codec_options=DEFAULT_RAW_BSON_OPTIONS)
        self.assertEqual(raw_coll.find_one(), raw)
Ejemplo n.º 11
0
 async def on_get(self, req: Request, resp: Response):
     resp.media = RawBSONDocument(
         BSON.encode(
             {
                 "id": uuid_value,
                 "dt": dt_value,
                 # "binary": bytes_value,
                 "info": info_value,
                 "array": array_value,
                 "empty": {},
             }
         )
     )
Ejemplo n.º 12
0
 def test_raw(self):
     """Test with RawBSONDocument."""
     raw_coll = self.coll.with_options(
         codec_options=DEFAULT_RAW_BSON_OPTIONS)
     with raw_coll.watch() as change_stream:
         raw_doc = RawBSONDocument(BSON.encode({'_id': 1}))
         self.coll.insert_one(raw_doc)
         change = next(change_stream)
         self.assertIsInstance(change, RawBSONDocument)
         self.assertEqual(change['operationType'], 'insert')
         self.assertEqual(change['ns']['db'], self.coll.database.name)
         self.assertEqual(change['ns']['coll'], self.coll.name)
         self.assertEqual(change['fullDocument'], raw_doc)
         self.assertEqual(change['_id'], change_stream._resume_token)
Ejemplo n.º 13
0
    def test_with_codec_options(self):
        # {u'date': datetime.datetime(2015, 6, 3, 18, 40, 50, 826000),
        #  u'_id': UUID('026fab8f-975f-4965-9fbf-85ad874c60ff')}
        # encoded with JAVA_LEGACY uuid representation.
        bson_string = (
            b'-\x00\x00\x00\x05_id\x00\x10\x00\x00\x00\x03eI_\x97\x8f\xabo\x02'
            b'\xff`L\x87\xad\x85\xbf\x9f\tdate\x00\x8a\xd6\xb9\xbaM'
            b'\x01\x00\x00\x00')
        document = RawBSONDocument(
            bson_string,
            codec_options=CodecOptions(uuid_representation=JAVA_LEGACY))

        self.assertEqual(uuid.UUID('026fab8f-975f-4965-9fbf-85ad874c60ff'),
                         document['_id'])
Ejemplo n.º 14
0
 def test_round_trip_codec_options(self):
     doc = {
         'date': datetime.datetime(2015, 6, 3, 18, 40, 50, 826000),
         '_id': uuid.UUID('026fab8f-975f-4965-9fbf-85ad874c60ff')
     }
     db = self.client.pymongo_test
     coll = db.get_collection(
         'test_raw',
         codec_options=CodecOptions(uuid_representation=JAVA_LEGACY))
     coll.insert_one(doc)
     raw_java_legacy = CodecOptions(uuid_representation=JAVA_LEGACY,
                                    document_class=RawBSONDocument)
     coll = db.get_collection('test_raw', codec_options=raw_java_legacy)
     self.assertEqual(
         RawBSONDocument(encode(doc, codec_options=raw_java_legacy)),
         coll.find_one())
Ejemplo n.º 15
0
    def collection_info(self, database, filter):
        """Get the collection info for a namespace.

        The returned collection info is passed to libmongocrypt which reads
        the JSON schema.

        :Parameters:
          - `database`: The database on which to run listCollections.
          - `filter`: The filter to pass to listCollections.

        :Returns:
          The first document from the listCollections command response as BSON.
        """
        with self.client_ref()[database].list_collections(
                filter=RawBSONDocument(filter)) as cursor:
            for doc in cursor:
                return _dict_to_bson(doc, False, _DATA_KEY_OPTS)
Ejemplo n.º 16
0
    def test_req_load_schema(
        self,
        api: SpanAPI,
        req_load: LoadOptions,
        data_post: dict,
        data_passed: Union[Name, dict],
        error: Optional[Type[errors_api.APIError]],
        bson: bool,
    ):
        if bson and isinstance(data_passed, dict):
            data_passed = RawBSONDocument(BSON.encode(data_passed))

        @api.route("/test")
        class TestRoute(SpanRoute):
            @api.use_schema(req=NameSchema(), req_load=req_load)
            async def on_post(
                self, req: Request[dict, Union[Name, dict]], resp: Response
            ):
                data = await req.media_loaded()
                if req_load is LoadOptions.IGNORE:
                    assert data == data_passed
                    assert await req.media() == data_passed
                else:
                    assert isinstance(data, type(data_passed))
                    assert data == data_passed

        with api.requests as client:
            if bson:
                if isinstance(data_post, dict):
                    data_post = BSON.encode(data_post)

                r = client.post(
                    "/test",
                    data=data_post,
                    headers={"Content-Type": "application/bson"},
                )
            else:
                r = client.post("/test", json=data_post)

            if error is not None:
                validate_error(r, error)
            else:
                validate_response(r)
Ejemplo n.º 17
0
    def test_dump_bson_compatible_objects(
        self, mimetype, feed_bson: bool, feed_list: bool
    ):
        data = {
            "uuid": uuid.uuid4(),
            "datetime": dt_factory(),
            "bytes": b"Some Bin Data",
            "raw_bson": RawBSONDocument(
                BSON.encode({"key": "value", "nested": {"key": "value"}})
            ),
            "raw_bson_list": [
                RawBSONDocument(
                    BSON.encode({"key": "value", "nested": {"key": "value"}})
                ),
                RawBSONDocument(
                    BSON.encode({"key": "value", "nested": {"key": "value"}})
                ),
            ],
        }
        if feed_bson:
            data = RawBSONDocument(BSON.encode(data))
        if feed_list:
            data = [data, data]
        headers = dict()

        encoded = encode_content(data, mimetype=mimetype, headers=headers)
        try:
            print("ENCODED:", encoded.decode(), "", sep="\n")
        except BaseException:
            print("ENCODED:", encoded, "", sep="\n")

        loaded, decoded = decode_content(encoded, mimetype=mimetype)

        print("DECODED:", loaded, sep="\n")

        if feed_list:
            loaded = loaded[0]
            data = data[0]
            data = dict(data)
            data["raw_bson"] = dict(data["raw_bson"])
            data["raw_bson"]["nested"] = dict(data["raw_bson"]["nested"])

        assert str(loaded["uuid"]) == str(data["uuid"])
        assert set(loaded.keys()) == set(data.keys())
     # noqa: E501

    :param body: ${KEY} to be created
    :type body: dict | bytes

    :rtype: str
    """
    if connexion.request.is_json:
        body = connexion.request.get_json()  # noqa: E501

    doc_id = str(uuid.uuid4())
    body['_id'] = doc_id
    body['_sys'] = {'created_ts': int(time.time()), 'created_by': connexion.request.headers['x-api-user']}
    body_str = json.dumps(body)
    collection.insert_one(RawBSONDocument(bsonjs.loads(body_str)))

    qKey='{}{}'.format(KEY, dpath(body))
    publisher(body_str, routing_key='{}.create'.format(qKey), retry=True, declare=createQueues(qKey), headers={'_id':doc_id})

    skey = '{}|{}'.format(KEY, doc_id)
    r.set(skey, body_str, ex=3)
    r.delete(KEY)

    return doc_id


def delete${KEY}(ID):  # noqa: E501
    """Delete the ${KEY} instance based on ID

     # noqa: E501
Ejemplo n.º 19
0
 def insert(self, document):
     self.inserted_items.append(document)
     return InsertOneResult(RawBSONDocument(BSON.encode(document)), True)
Ejemplo n.º 20
0
 def test_invalid_bson_eoo(self):
     invalid_bson_eoo = encode({'a': 1})[:-1] + b'\x01'
     with self.assertRaisesRegex(InvalidBSON, 'bad eoo'):
         RawBSONDocument(invalid_bson_eoo)
Ejemplo n.º 21
0
 def test_invalid_bson_sequence(self):
     bson_byte_sequence = encode({'a': 1})+encode({})
     with self.assertRaisesRegex(InvalidBSON, 'invalid object length'):
         RawBSONDocument(bson_byte_sequence)
Ejemplo n.º 22
0
 def test_empty_doc(self):
     doc = RawBSONDocument(encode({}))
     with self.assertRaises(KeyError):
         doc['does-not-exist']
Ejemplo n.º 23
0
class TestRawBSONDocument(IntegrationTest):

    # {'_id': ObjectId('556df68b6e32ab21a95e0785'),
    #  'name': 'Sherlock',
    #  'addresses': [{'street': 'Baker Street'}]}
    bson_string = (
        b'Z\x00\x00\x00\x07_id\x00Um\xf6\x8bn2\xab!\xa9^\x07\x85\x02name\x00\t'
        b'\x00\x00\x00Sherlock\x00\x04addresses\x00&\x00\x00\x00\x030\x00\x1e'
        b'\x00\x00\x00\x02street\x00\r\x00\x00\x00Baker Street\x00\x00\x00\x00'
    )
    document = RawBSONDocument(bson_string)

    @classmethod
    def setUpClass(cls):
        super(TestRawBSONDocument, cls).setUpClass()
        client_context.client = rs_or_single_client()
        cls.client = client_context.client

    def tearDown(self):
        if client_context.connected:
            self.client.pymongo_test.test_raw.drop()

    def test_decode(self):
        self.assertEqual('Sherlock', self.document['name'])
        first_address = self.document['addresses'][0]
        self.assertIsInstance(first_address, RawBSONDocument)
        self.assertEqual('Baker Street', first_address['street'])

    def test_raw(self):
        self.assertEqual(self.bson_string, self.document.raw)

    def test_empty_doc(self):
        doc = RawBSONDocument(encode({}))
        with self.assertRaises(KeyError):
            doc['does-not-exist']

    def test_invalid_bson_sequence(self):
        bson_byte_sequence = encode({'a': 1})+encode({})
        with self.assertRaisesRegex(InvalidBSON, 'invalid object length'):
            RawBSONDocument(bson_byte_sequence)

    def test_invalid_bson_eoo(self):
        invalid_bson_eoo = encode({'a': 1})[:-1] + b'\x01'
        with self.assertRaisesRegex(InvalidBSON, 'bad eoo'):
            RawBSONDocument(invalid_bson_eoo)

    @client_context.require_connection
    def test_round_trip(self):
        db = self.client.get_database(
            'pymongo_test',
            codec_options=CodecOptions(document_class=RawBSONDocument))
        db.test_raw.insert_one(self.document)
        result = db.test_raw.find_one(self.document['_id'])
        self.assertIsInstance(result, RawBSONDocument)
        self.assertEqual(dict(self.document.items()), dict(result.items()))

    @client_context.require_connection
    def test_round_trip_raw_uuid(self):
        coll = self.client.get_database('pymongo_test').test_raw
        uid = uuid.uuid4()
        doc = {'_id': 1,
               'bin4': Binary(uid.bytes, 4),
               'bin3': Binary(uid.bytes, 3)}
        raw = RawBSONDocument(encode(doc))
        coll.insert_one(raw)
        self.assertEqual(coll.find_one(), doc)
        uuid_coll = coll.with_options(
            codec_options=coll.codec_options.with_options(
                uuid_representation=UuidRepresentation.STANDARD))
        self.assertEqual(uuid_coll.find_one(),
                         {'_id': 1, 'bin4': uid, 'bin3': Binary(uid.bytes, 3)})

        # Test that the raw bytes haven't changed.
        raw_coll = coll.with_options(codec_options=DEFAULT_RAW_BSON_OPTIONS)
        self.assertEqual(raw_coll.find_one(), raw)

    def test_with_codec_options(self):
        # {'date': datetime.datetime(2015, 6, 3, 18, 40, 50, 826000),
        #  '_id': UUID('026fab8f-975f-4965-9fbf-85ad874c60ff')}
        # encoded with JAVA_LEGACY uuid representation.
        bson_string = (
            b'-\x00\x00\x00\x05_id\x00\x10\x00\x00\x00\x03eI_\x97\x8f\xabo\x02'
            b'\xff`L\x87\xad\x85\xbf\x9f\tdate\x00\x8a\xd6\xb9\xbaM'
            b'\x01\x00\x00\x00'
        )
        document = RawBSONDocument(
            bson_string,
            codec_options=CodecOptions(uuid_representation=JAVA_LEGACY,
                                       document_class=RawBSONDocument))

        self.assertEqual(uuid.UUID('026fab8f-975f-4965-9fbf-85ad874c60ff'),
                         document['_id'])

    @client_context.require_connection
    def test_round_trip_codec_options(self):
        doc = {
            'date': datetime.datetime(2015, 6, 3, 18, 40, 50, 826000),
            '_id': uuid.UUID('026fab8f-975f-4965-9fbf-85ad874c60ff')
        }
        db = self.client.pymongo_test
        coll = db.get_collection(
            'test_raw',
            codec_options=CodecOptions(uuid_representation=JAVA_LEGACY))
        coll.insert_one(doc)
        raw_java_legacy = CodecOptions(uuid_representation=JAVA_LEGACY,
                                       document_class=RawBSONDocument)
        coll = db.get_collection('test_raw', codec_options=raw_java_legacy)
        self.assertEqual(
            RawBSONDocument(encode(doc, codec_options=raw_java_legacy)),
            coll.find_one())

    @client_context.require_connection
    def test_raw_bson_document_embedded(self):
        doc = {'embedded': self.document}
        db = self.client.pymongo_test
        db.test_raw.insert_one(doc)
        result = db.test_raw.find_one()
        self.assertEqual(decode(self.document.raw), result['embedded'])

        # Make sure that CodecOptions are preserved.
        # {'embedded': [
        #   {'date': datetime.datetime(2015, 6, 3, 18, 40, 50, 826000),
        #    '_id': UUID('026fab8f-975f-4965-9fbf-85ad874c60ff')}
        # ]}
        # encoded with JAVA_LEGACY uuid representation.
        bson_string = (
            b'D\x00\x00\x00\x04embedded\x005\x00\x00\x00\x030\x00-\x00\x00\x00'
            b'\tdate\x00\x8a\xd6\xb9\xbaM\x01\x00\x00\x05_id\x00\x10\x00\x00'
            b'\x00\x03eI_\x97\x8f\xabo\x02\xff`L\x87\xad\x85\xbf\x9f\x00\x00'
            b'\x00'
        )
        rbd = RawBSONDocument(
            bson_string,
            codec_options=CodecOptions(uuid_representation=JAVA_LEGACY,
                                       document_class=RawBSONDocument))

        db.test_raw.drop()
        db.test_raw.insert_one(rbd)
        result = db.get_collection('test_raw', codec_options=CodecOptions(
            uuid_representation=JAVA_LEGACY)).find_one()
        self.assertEqual(rbd['embedded'][0]['_id'],
                         result['embedded'][0]['_id'])

    @client_context.require_connection
    def test_write_response_raw_bson(self):
        coll = self.client.get_database(
            'pymongo_test',
            codec_options=CodecOptions(document_class=RawBSONDocument)).test_raw

        # No Exceptions raised while handling write response.
        coll.insert_one(self.document)
        coll.delete_one(self.document)
        coll.insert_many([self.document])
        coll.delete_many(self.document)
        coll.update_one(self.document, {'$set': {'a': 'b'}}, upsert=True)
        coll.update_many(self.document, {'$set': {'b': 'c'}})

    def test_preserve_key_ordering(self):
        keyvaluepairs = [('a', 1), ('b', 2), ('c', 3),]
        rawdoc = RawBSONDocument(encode(SON(keyvaluepairs)))

        for rkey, elt in zip(rawdoc, keyvaluepairs):
            self.assertEqual(rkey, elt[0])
Ejemplo n.º 24
0
class TestUseSchemaReq:
    @pytest.mark.parametrize(
        "req_load,data_post,data_passed,error",
        [
            # Tests normal loading to dataclass object
            (LoadOptions.VALIDATE_AND_LOAD, HARRY_DUMPED, HARRY, None),
            # Tests validation error on loading bad data
            (
                LoadOptions.VALIDATE_AND_LOAD,
                HARRY_BAD_ID,
                None,
                errors_api.RequestValidationError,
            ),
            # Tests validation error on loading bad data
            (
                LoadOptions.VALIDATE_AND_LOAD,
                DRACO_DUMPED,
                None,
                errors_api.RequestValidationError,
            ),
            # Tests validation error on load for not a json
            (
                LoadOptions.VALIDATE_AND_LOAD,
                "notajson",
                None,
                errors_api.RequestValidationError,
            ),
            # Tests successful validation of incoming data without a load
            (LoadOptions.VALIDATE_ONLY, HARRY_DUMPED, HARRY_DUMPED, None),
            # Tests validation error on validate-only bad data.
            (
                LoadOptions.VALIDATE_ONLY,
                HARRY_BAD_ID,
                None,
                errors_api.RequestValidationError,
            ),
            # Tests validation error on validate-only bad data.
            (
                LoadOptions.VALIDATE_ONLY,
                DRACO_DUMPED,
                None,
                errors_api.RequestValidationError,
            ),
            # Tests validation error on validate for not a json
            (
                LoadOptions.VALIDATE_ONLY,
                "notajson",
                None,
                errors_api.RequestValidationError,
            ),
            # Tests successful ignore of good data
            (LoadOptions.IGNORE, HARRY_DUMPED, HARRY_DUMPED, None),
            # Tests successful ignore of bad data
            (LoadOptions.IGNORE, HARRY_BAD_ID, HARRY_BAD_ID, None),
            # Tests successful ignore of bad data
            (LoadOptions.IGNORE, DRACO_DUMPED, DRACO_DUMPED, None),
        ],
    )
    @pytest.mark.parametrize("bson", [True, False])
    def test_req_load_schema(
        self,
        api: SpanAPI,
        req_load: LoadOptions,
        data_post: dict,
        data_passed: Union[Name, dict],
        error: Optional[Type[errors_api.APIError]],
        bson: bool,
    ):
        if bson and isinstance(data_passed, dict):
            data_passed = RawBSONDocument(BSON.encode(data_passed))

        @api.route("/test")
        class TestRoute(SpanRoute):
            @api.use_schema(req=NameSchema(), req_load=req_load)
            async def on_post(
                self, req: Request[dict, Union[Name, dict]], resp: Response
            ):
                data = await req.media_loaded()
                if req_load is LoadOptions.IGNORE:
                    assert data == data_passed
                    assert await req.media() == data_passed
                else:
                    assert isinstance(data, type(data_passed))
                    assert data == data_passed

        with api.requests as client:
            if bson:
                if isinstance(data_post, dict):
                    data_post = BSON.encode(data_post)

                r = client.post(
                    "/test",
                    data=data_post,
                    headers={"Content-Type": "application/bson"},
                )
            else:
                r = client.post("/test", json=data_post)

            if error is not None:
                validate_error(r, error)
            else:
                validate_response(r)

    def test_req_load_schema_class(self, api: SpanAPI):
        @api.route("/test")
        class TestRoute(SpanRoute):
            @api.use_schema(req=NameSchema)
            async def on_post(self, req: Request, resp: Response):
                assert await req.media_loaded() == HARRY

        with api.requests as client:
            r = client.post("/test", json=HARRY_DUMPED)
            validate_response(r)

    @pytest.mark.parametrize(
        "data",
        [
            [HARRY_DUMPED, HARRY_DUMPED],
            [
                RawBSONDocument(BSON.encode(HARRY_DUMPED)),
                RawBSONDocument(BSON.encode(HARRY_DUMPED)),
            ],
        ],
    )
    def test_req_load_bson_list(self, api: SpanAPI, data):
        @api.route("/test")
        class TestRoute(SpanRoute):
            @api.use_schema(req=NameSchema(many=True))
            async def on_post(self, req: Request, resp: Response):
                assert await req.media_loaded() == [HARRY, HARRY]

        with api.requests as client:
            headers = {"Content-Type": "application/bson"}
            r = client.post("/test", data=encode_bson(data), headers=headers)
            validate_response(r)

    def test_req_schema_class_marshmallow(self, api: SpanAPI):
        class NameSchemaM(marshmallow.Schema):
            id = marshmallow.fields.UUID()
            first = marshmallow.fields.Str()
            last = marshmallow.fields.Str()

        harry_loaded = NameSchemaM().load(HARRY_DUMPED)

        @api.route("/test")
        class TestRoute(SpanRoute):
            @api.use_schema(req=NameSchemaM())
            async def on_post(self, req: Request, resp: Response):
                assert await req.media_loaded() == harry_loaded

        with api.requests as client:
            r = client.post("/test", json=HARRY_DUMPED)
            validate_response(r)

    def test_req_load_text(self, api: SpanAPI):
        @api.route("/test")
        class TestRoute(SpanRoute):
            @api.use_schema(req=MimeType.TEXT)
            async def on_post(self, req: Request, resp: Response):
                assert await req.media_loaded() == "test_text"

        with api.requests as client:
            r = client.post("/test", data="test_text")
            validate_response(r)

    def test_error_not_a_json(self, api: SpanAPI):
        @api.route("/test")
        class TestRoute(SpanRoute):
            @api.use_schema(req=NameSchema())
            async def on_post(self, req: Request, resp: Response):
                await req.media()

        with api.requests as client:
            r = client.post("/test", data=bytes(14))
            validate_error(r, errors_api.RequestValidationError)
Ejemplo n.º 25
0
class TestRawBSONDocument(unittest.TestCase):

    # {u'_id': ObjectId('556df68b6e32ab21a95e0785'),
    #  u'name': u'Sherlock',
    #  u'addresses': [{u'street': u'Baker Street'}]}
    bson_string = (
        b'Z\x00\x00\x00\x07_id\x00Um\xf6\x8bn2\xab!\xa9^\x07\x85\x02name\x00\t'
        b'\x00\x00\x00Sherlock\x00\x04addresses\x00&\x00\x00\x00\x030\x00\x1e'
        b'\x00\x00\x00\x02street\x00\r\x00\x00\x00Baker Street\x00\x00\x00\x00'
    )
    document = RawBSONDocument(bson_string)

    @classmethod
    def setUpClass(cls):
        cls.client = client_context.client

    def tearDown(self):
        if client_context.connected:
            self.client.pymongo_test.test_raw.drop()

    def test_decode(self):
        self.assertEqual('Sherlock', self.document['name'])
        first_address = self.document['addresses'][0]
        self.assertIsInstance(first_address, RawBSONDocument)
        self.assertEqual('Baker Street', first_address['street'])

    def test_raw(self):
        self.assertEqual(self.bson_string, self.document.raw)

    @client_context.require_connection
    def test_round_trip(self):
        db = self.client.get_database(
            'pymongo_test',
            codec_options=CodecOptions(document_class=RawBSONDocument))
        db.test_raw.insert_one(self.document)
        result = db.test_raw.find_one(self.document['_id'])
        self.assertIsInstance(result, RawBSONDocument)
        self.assertEqual(dict(self.document.items()), dict(result.items()))

    def test_with_codec_options(self):
        # {u'date': datetime.datetime(2015, 6, 3, 18, 40, 50, 826000),
        #  u'_id': UUID('026fab8f-975f-4965-9fbf-85ad874c60ff')}
        # encoded with JAVA_LEGACY uuid representation.
        bson_string = (
            b'-\x00\x00\x00\x05_id\x00\x10\x00\x00\x00\x03eI_\x97\x8f\xabo\x02'
            b'\xff`L\x87\xad\x85\xbf\x9f\tdate\x00\x8a\xd6\xb9\xbaM'
            b'\x01\x00\x00\x00')
        document = RawBSONDocument(bson_string,
                                   codec_options=CodecOptions(
                                       uuid_representation=JAVA_LEGACY,
                                       document_class=RawBSONDocument))

        self.assertEqual(uuid.UUID('026fab8f-975f-4965-9fbf-85ad874c60ff'),
                         document['_id'])

    @client_context.require_connection
    def test_round_trip_codec_options(self):
        doc = {
            'date': datetime.datetime(2015, 6, 3, 18, 40, 50, 826000),
            '_id': uuid.UUID('026fab8f-975f-4965-9fbf-85ad874c60ff')
        }
        db = self.client.pymongo_test
        coll = db.get_collection(
            'test_raw',
            codec_options=CodecOptions(uuid_representation=JAVA_LEGACY))
        coll.insert_one(doc)
        raw_java_legacy = CodecOptions(uuid_representation=JAVA_LEGACY,
                                       document_class=RawBSONDocument)
        coll = db.get_collection('test_raw', codec_options=raw_java_legacy)
        self.assertEqual(
            RawBSONDocument(BSON.encode(doc, codec_options=raw_java_legacy)),
            coll.find_one())

    @client_context.require_connection
    def test_raw_bson_document_embedded(self):
        doc = {'embedded': self.document}
        db = self.client.pymongo_test
        db.test_raw.insert_one(doc)
        result = db.test_raw.find_one()
        self.assertEqual(BSON(self.document.raw).decode(), result['embedded'])

        # Make sure that CodecOptions are preserved.
        # {'embedded': [
        #   {u'date': datetime.datetime(2015, 6, 3, 18, 40, 50, 826000),
        #    u'_id': UUID('026fab8f-975f-4965-9fbf-85ad874c60ff')}
        # ]}
        # encoded with JAVA_LEGACY uuid representation.
        bson_string = (
            b'D\x00\x00\x00\x04embedded\x005\x00\x00\x00\x030\x00-\x00\x00\x00'
            b'\tdate\x00\x8a\xd6\xb9\xbaM\x01\x00\x00\x05_id\x00\x10\x00\x00'
            b'\x00\x03eI_\x97\x8f\xabo\x02\xff`L\x87\xad\x85\xbf\x9f\x00\x00'
            b'\x00')
        rbd = RawBSONDocument(bson_string,
                              codec_options=CodecOptions(
                                  uuid_representation=JAVA_LEGACY,
                                  document_class=RawBSONDocument))

        db.test_raw.drop()
        db.test_raw.insert_one(rbd)
        result = db.get_collection(
            'test_raw',
            codec_options=CodecOptions(
                uuid_representation=JAVA_LEGACY)).find_one()
        self.assertEqual(rbd['embedded'][0]['_id'],
                         result['embedded'][0]['_id'])

    @client_context.require_connection
    def test_write_response_raw_bson(self):
        coll = self.client.get_database(
            'pymongo_test',
            codec_options=CodecOptions(
                document_class=RawBSONDocument)).test_raw

        # No Exceptions raised while handling write response.
        coll.insert_one(self.document)
        coll.delete_one(self.document)
        coll.insert_many([self.document])
        coll.delete_many(self.document)
        coll.update_one(self.document, {'$set': {'a': 'b'}}, upsert=True)
        coll.update_many(self.document, {'$set': {'b': 'c'}})
Ejemplo n.º 26
0
    def _test_auto_encrypt(self, opts):
        client = rs_or_single_client(auto_encryption_opts=opts)
        self.addCleanup(client.close)

        # Create the encrypted field's data key.
        key_vault = self.client.admin.get_collection('datakeys',
                                                     codec_options=OPTS)
        data_key = RawBSONDocument(
            bson_data('custom', 'key-document-local.json'))
        key_vault.insert_one(data_key)
        self.addCleanup(key_vault.drop)

        # Collection.insert_one/insert_many auto encrypts.
        docs = [{
            '_id': 0,
            'ssn': '000'
        }, {
            '_id': 1,
            'ssn': '111'
        }, {
            '_id': 2,
            'ssn': '222'
        }, {
            '_id': 3,
            'ssn': '333'
        }, {
            '_id': 4,
            'ssn': '444'
        }, {
            '_id': 5,
            'ssn': '555'
        }]
        encrypted_coll = client.pymongo_test.test
        encrypted_coll.insert_one(docs[0])
        encrypted_coll.insert_many(docs[1:3])
        unack = encrypted_coll.with_options(write_concern=WriteConcern(w=0))
        unack.insert_one(docs[3])
        unack.insert_many(docs[4:], ordered=False)
        wait_until(lambda: self.db.test.count_documents({}) == len(docs),
                   'insert documents with w=0')

        # Database.command auto decrypts.
        res = client.pymongo_test.command('find',
                                          'test',
                                          filter={'ssn': '000'})
        decrypted_docs = res['cursor']['firstBatch']
        self.assertEqual(decrypted_docs, [{'_id': 0, 'ssn': '000'}])

        # Collection.find auto decrypts.
        decrypted_docs = list(encrypted_coll.find())
        self.assertEqual(decrypted_docs, docs)

        # Collection.find auto decrypts getMores.
        decrypted_docs = list(encrypted_coll.find(batch_size=1))
        self.assertEqual(decrypted_docs, docs)

        # Collection.aggregate auto decrypts.
        decrypted_docs = list(encrypted_coll.aggregate([]))
        self.assertEqual(decrypted_docs, docs)

        # Collection.aggregate auto decrypts getMores.
        decrypted_docs = list(encrypted_coll.aggregate([], batchSize=1))
        self.assertEqual(decrypted_docs, docs)

        # Collection.distinct auto decrypts.
        decrypted_ssns = encrypted_coll.distinct('ssn')
        self.assertEqual(decrypted_ssns, [d['ssn'] for d in docs])

        # Make sure the field is actually encrypted.
        for encrypted_doc in self.db.test.find():
            self.assertIsInstance(encrypted_doc['_id'], int)
            self.assertEncrypted(encrypted_doc['ssn'])

        # Attempt to encrypt an unencodable object.
        with self.assertRaises(BSONError):
            encrypted_coll.insert_one({'unencodeable': object()})
Ejemplo n.º 27
0
 async def on_get(self, req: Request, resp: Response):
     resp.media = RawBSONDocument(BSON.encode(HARRY_DUMPED))