Example #1
0
class TypesTestCase(unittest.TestCase):
    def setUp(self):
        self.connection = Connection()
        self.col = self.connection['test']['mongokit']

    def tearDown(self):
        self.connection.drop_database('test')

    def test_authorized_type(self):
        for auth_type in SchemaDocument.authorized_types:
            if auth_type is dict:
                auth_type = {}

            class MyDoc(SchemaDocument):
                structure = {"foo": auth_type}

            if type(auth_type) is dict:
                assert MyDoc() == {"foo": {}}, MyDoc()
            elif auth_type is list:
                assert MyDoc() == {"foo": []}
            else:
                assert MyDoc() == {"foo": None}, auth_type

    def test_not_authorized_type(self):
        for unauth_type in [set, str]:
            failed = False
            try:

                class MyDoc(SchemaDocument):
                    structure = {"foo": [unauth_type]}
            except StructureError, e:
                self.assertEqual(
                    str(e),
                    "MyDoc: %s is not an authorized type" % unauth_type)
                failed = True
            self.assertEqual(failed, True)
            failed = False
            try:

                class MyDoc(SchemaDocument):
                    structure = {"foo": (unauth_type)}
            except StructureError, e:
                self.assertEqual(
                    str(e),
                    "MyDoc: %s is not an authorized type" % unauth_type)
                failed = True
            self.assertEqual(failed, True)
            failed = False
            try:

                class MyDoc2(SchemaDocument):
                    structure = {'foo': [{int: unauth_type}]}
            except StructureError, e:
                self.assertEqual(
                    str(e),
                    "MyDoc2: %s is not an authorized type" % unauth_type)
                failed = True
Example #2
0
class TypesTestCase(unittest.TestCase):

    def setUp(self):
        self.connection = Connection()
        self.col = self.connection['test']['mongokit']
        
    def tearDown(self):
        self.connection.drop_database('test')


    def test_authorized_type(self):
       for auth_type in SchemaDocument.authorized_types:
            if auth_type is dict:
                auth_type = {}
            class MyDoc(SchemaDocument):
                structure = { "foo":auth_type }
            if type(auth_type) is dict:
                assert MyDoc() == {"foo":{}}, MyDoc()
            elif auth_type is list:
                assert MyDoc() == {"foo":[]}
            else:
                assert MyDoc() == {"foo":None}, auth_type
 
    def test_not_authorized_type(self):
        for unauth_type in [set]:
            failed = False
            try:
                class MyDoc(SchemaDocument):
                    structure = { "foo":[unauth_type] }
            except StructureError, e:
                self.assertEqual(str(e), "MyDoc: %s is not an authorized type" % unauth_type)
                failed = True
            self.assertEqual(failed, True)
            failed = False
            try:
                class MyDoc(SchemaDocument):
                    structure = { "foo":(unauth_type) }
            except StructureError, e:
                self.assertEqual(str(e), "MyDoc: %s is not an authorized type" % unauth_type)
                failed = True
            self.assertEqual(failed, True)
            failed = False
            try:
                class MyDoc2(SchemaDocument):
                    structure = { 'foo':[{int:unauth_type }]}
            except StructureError, e:
                self.assertEqual(str(e), "MyDoc2: %s is not an authorized type" % unauth_type)
                failed = True
Example #3
0
def init_db(host=None, port=None, database=None):
    con = Connection(host, port)
    con.drop_database(database)
    con.register([Admin, AdminRole])
    db = Database(con, database)

    generate_index(host, port, database)

    role = db.AdminRole()
    role['name'] = u'管理员'
    role['auth_list'] = get_auth_list()
    role.save()

    user = db.Admin()
    user['email'] = u'*****@*****.**'
    user['name'] = u'admin'
    user['password'] = db.Admin.encode_pwd('123456')
    user['login_time'] = datetime.now()
    user['status'] = True
    user['role'] = role
    user.save()

    return 'success'
Example #4
0
def init_db(host=None, port=None, database=None):
    con = Connection(host, port)
    con.drop_database(database)
    con.register([Admin, AdminRole])
    db = Database(con, database)

    generate_index(host, port, database)

    role = db.AdminRole()
    role['name'] = u'管理员'
    role['auth_list'] = get_auth_list()
    role.save()

    user = db.Admin()
    user['email'] = u'*****@*****.**'
    user['name'] = u'admin'
    user['password'] = db.Admin.encode_pwd('123456')
    user['login_time'] = datetime.now()
    user['status'] = True
    user['role'] = role
    user.save()

    return 'success'
		DBSession.images.insert(tempImage)

def saveVMTypes(vmTypes):

	for vmType in vmTypes['types']:
		DBSession.vmtypes.insert(vmType)

def installPackage(package):
	easy_install.main(["-U", package])

def copyImagesToServer():

	images = DBSession.images.find()
	for image in images:
		location = image['location']
		fileName = "../src/images/" + image['name'] + "__" + str(image['_id'])
		system('scp "%s" "%s" ' % (location , fileName) )


if __name__ == "__main__":

	mongoConnection.drop_database('cloudDB')

	savePhysicalMachines(getPhysicalMachines(argv[1]))
	saveImageFiles(getImageFiles(argv[2]))
	saveVMTypes(getVMTypesDict(argv[3]))

	copyImagesToServer()


Example #6
0
class TypesTestCase(unittest.TestCase):
    def setUp(self):
        self.connection = Connection()
        self.col = self.connection['test']['mongokit']

    def tearDown(self):
        self.connection.drop_database('test')

    def test_authorized_type(self):
        for auth_type in SchemaDocument.authorized_types:
            if auth_type is dict:
                auth_type = {}

            class MyDoc(SchemaDocument):
                structure = {"foo": auth_type}

            if type(auth_type) is dict:
                assert MyDoc() == {"foo": {}}, MyDoc()
            elif auth_type is list:
                assert MyDoc() == {"foo": []}
            else:
                assert MyDoc() == {"foo": None}, auth_type

    def test_not_authorized_type(self):
        for unauth_type in [set]:
            failed = False
            try:

                class MyDoc(SchemaDocument):
                    structure = {"foo": [unauth_type]}
            except StructureError as e:
                self.assertEqual(
                    str(e),
                    "MyDoc: %s is not an authorized type" % unauth_type)
                failed = True
            self.assertEqual(failed, True)
            failed = False
            try:

                class MyDoc(SchemaDocument):
                    structure = {"foo": (unauth_type)}
            except StructureError as e:
                self.assertEqual(
                    str(e),
                    "MyDoc: %s is not an authorized type" % unauth_type)
                failed = True
            self.assertEqual(failed, True)
            failed = False
            try:

                class MyDoc2(SchemaDocument):
                    structure = {'foo': [{int: unauth_type}]}
            except StructureError as e:
                self.assertEqual(
                    str(e),
                    "MyDoc2: %s is not an authorized type" % unauth_type)
                failed = True
            self.assertEqual(failed, True)
            failed = False
            try:

                class MyDoc3(SchemaDocument):
                    structure = {'foo': [{unauth_type: int}]}
            except AuthorizedTypeError as e:
                self.assertEqual(
                    str(e),
                    "MyDoc3: %s is not an authorized type" % unauth_type)
                failed = True
            self.assertEqual(failed, True)

        failed = False
        try:

            class MyDoc4(SchemaDocument):
                structure = {1: six.text_type}
        except StructureError as e:
            self.assertEqual(str(e), "MyDoc4: 1 must be a string or a type")
            failed = True
        self.assertEqual(failed, True)

    def test_type_from_functions(self):
        from datetime import datetime

        class MyDoc(SchemaDocument):
            structure = {
                "foo": datetime,
            }

        assert MyDoc() == {"foo": None}, MyDoc()
        mydoc = MyDoc()
        mydoc['foo'] = datetime.now()
        mydoc.validate()

    def test_non_typed_list(self):
        class MyDoc(SchemaDocument):
            structure = {"foo": []}

        mydoc = MyDoc()
        mydoc.validate()
        assert mydoc['foo'] == []
        mydoc['foo'] = [u"bla", 23]
        mydoc.validate()
        mydoc['foo'] = [set([1, 2]), "bla"]
        self.assertRaises(AuthorizedTypeError, mydoc.validate)
        mydoc['foo'] = u"bla"
        self.assertRaises(SchemaTypeError, mydoc.validate)

#        class MyDoc(SchemaDocument):
#            structure = {
#                "foo":list
#            }
#        mydoc = MyDoc()
#        mydoc.validate()
#        assert mydoc['foo'] == []
#        mydoc['foo'] = [u"bla", 23]
#        mydoc.validate()
#        mydoc['foo'] = [set([1,2]), "bla"]
#        self.assertRaises(AuthorizedTypeError, mydoc.validate)

    def test_typed_list(self):
        class MyDoc(SchemaDocument):
            structure = {"foo": [int]}

        mydoc = MyDoc()
        mydoc.validate()
        assert mydoc['foo'] == []
        mydoc['foo'] = [1, 2, 3]
        mydoc.validate()
        mydoc['foo'] = [u"bla"]
        self.assertRaises(SchemaTypeError, mydoc.validate)

    def test_typed_list_with_dict(self):
        class MyDoc(SchemaDocument):
            structure = {"foo": [{six.text_type: int}]}

        mydoc = MyDoc()
        mydoc['foo'] = [{u"bla": 1}, {u"ble": 2}]
        mydoc.validate()
        mydoc['foo'] = [{u"bla": u"bar"}]
        self.assertRaises(SchemaTypeError, mydoc.validate)

    def test_typed_list_with_list(self):
        class MyDoc(SchemaDocument):
            structure = {"foo": [[six.text_type]]}

        mydoc = MyDoc()
        mydoc['foo'] = [[u"bla", u"blu"], [u"ble", u"bli"]]
        mydoc.validate()
        mydoc['foo'] = [[u"bla", 1]]
        self.assertRaises(SchemaTypeError, mydoc.validate)

    def test_typed_tuple(self):
        class MyDoc(SchemaDocument):
            structure = {"foo": (int, six.text_type, float)}

        mydoc = MyDoc()
        mydoc.validate()
        assert mydoc['foo'] == [None, None, None]
        mydoc['foo'] = [u"bla", 1, 4.0]
        self.assertRaises(SchemaTypeError, mydoc.validate)
        mydoc['foo'] = [1, u"bla"]
        self.assertRaises(SchemaTypeError, mydoc.validate)
        mydoc['foo'] = u"bla"
        self.assertRaises(SchemaTypeError, mydoc.validate)
        mydoc['foo'] = [1, u'bar', 3.2]
        mydoc.validate()
        mydoc['foo'] = [None, u"bla", 3.1]
        mydoc.validate()
        mydoc['foo'][0] = 50
        mydoc.validate()

    def test_nested_typed_tuple(self):
        class MyDoc(SchemaDocument):
            structure = {"foo": {'bar': (int, six.text_type, float)}}

        mydoc = MyDoc()
        mydoc.validate()
        assert mydoc['foo']['bar'] == [None, None, None]
        mydoc['foo']['bar'] = [u"bla", 1, 4.0]
        self.assertRaises(SchemaTypeError, mydoc.validate)
        mydoc['foo']['bar'] = [1, u"bla"]
        self.assertRaises(SchemaTypeError, mydoc.validate)
        mydoc['foo']['bar'] = [1, u'bar', 3.2]
        mydoc.validate()
        mydoc['foo']['bar'] = [None, u"bla", 3.1]
        mydoc.validate()
        mydoc['foo']['bar'][0] = 50
        mydoc.validate()

    def test_saving_tuple(self):
        class MyDoc(Document):
            structure = {'foo': (int, six.text_type, float)}

        self.connection.register([MyDoc])

        mydoc = self.col.MyDoc()
        assert mydoc == {'foo': [None, None, None]}, mydoc
        mydoc['foo'] = (1, u'a', 1.1
                        )  # note that this will be converted to list
        assert mydoc == {'foo': (1, u'a', 1.1000000000000001)}, mydoc
        mydoc.save()
        mydoc = self.col.find_one()

        class MyDoc(Document):
            structure = {'foo': [six.text_type]}

        self.connection.register([])
        self.connection.register([MyDoc])
        mydoc = self.col.MyDoc()
        mydoc['foo'] = (u'bla', u'bli', u'blu', u'bly')
        mydoc.save()
        mydoc = self.col.get_from_id(mydoc['_id'])

    def test_nested_typed_tuple_in_list(self):
        class MyDoc(SchemaDocument):
            structure = {"foo": {'bar': [(int, six.text_type, float)]}}

        mydoc = MyDoc()
        mydoc.validate()
        assert mydoc == {'foo': {'bar': []}}
        mydoc['foo']['bar'].append([u"bla", 1, 4.0])
        self.assertRaises(SchemaTypeError, mydoc.validate)
        mydoc['foo']['bar'] = []
        mydoc['foo']['bar'].append([1, u"bla"])
        self.assertRaises(SchemaTypeError, mydoc.validate)
        mydoc['foo']['bar'] = []
        mydoc['foo']['bar'].append([1, u'bar', 3.2])
        mydoc.validate()
        mydoc['foo']['bar'].append([None, u"bla", 3.1])
        mydoc.validate()
        mydoc['foo']['bar'][1][0] = 50
        mydoc.validate()

    def test_dict_unicode_typed_list(self):
        class MyDoc(SchemaDocument):
            structure = {"foo": {six.text_type: [int]}}

        mydoc = MyDoc()
        mydoc['foo'] = {u"bar": [1, 2, 3]}
        mydoc.validate()
        mydoc['foo'] = {u"bar": [u"bla"]}
        self.assertRaises(SchemaTypeError, mydoc.validate)
        mydoc['foo'] = {3: [1, 2, 3]}
        self.assertRaises(SchemaTypeError, mydoc.validate)

    def test_with_custom_object(self):
        class MyDict(dict):
            pass

        class MyDoc(SchemaDocument):
            structure = {"foo": {six.text_type: int}}

        mydoc = MyDoc()
        mydict = MyDict()
        mydict[u"foo"] = 3
        mydoc["foo"] = mydict
        mydoc.validate()

    def test_custom_object_as_type(self):
        class MyDict(dict):
            pass

        class MyDoc(SchemaDocument):
            structure = {"foo": MyDict({six.text_type: int})}

        mydoc = MyDoc()
        mydict = MyDict()
        mydict[u"foo"] = 3
        mydoc["foo"] = mydict
        mydoc.validate()
        mydoc['foo'] = {u"foo": "7"}
        self.assertRaises(SchemaTypeError, mydoc.validate)

        class MyInt(int):
            pass

        class MyDoc(SchemaDocument):
            structure = {
                "foo": MyInt,
            }

        mydoc = MyDoc()
        mydoc["foo"] = MyInt(3)
        mydoc.validate()
        mydoc['foo'] = 3
        self.assertRaises(SchemaTypeError, mydoc.validate)

    def test_list_instead_of_dict(self):
        class MyDoc(SchemaDocument):
            structure = {"foo": {six.text_type: [six.text_type]}}

        mydoc = MyDoc()
        mydoc['foo'] = [u'bla']
        self.assertRaises(SchemaTypeError, mydoc.validate)

    def _test_big_nested_example(self):
        # XXX TODO
        class MyDoc(SchemaDocument):
            structure = {
                "foo": {
                    six.text_type: [int],
                    u"bar": {
                        "spam": {
                            int: [six.text_type]
                        }
                    }
                },
                "bla": {
                    "blo": {
                        "bli": [{
                            "arf": six.text_type
                        }]
                    }
                },
            }

        mydoc = MyDoc()
        mydoc['foo'].update({u"bir": [1, 2, 3]})
        mydoc['foo'][u'bar'][u'spam'] = {
            1: [u'bla', u'ble'],
            3: [u'foo', u'bar']
        }
        mydoc.validate()
        mydoc['bla']['blo']['bli'] = [{u"bar": [u"bla"]}]
        self.assertRaises(SchemaTypeError, mydoc.validate)
        mydoc['bla']['blo']['bli'] = [{u"arf": [1]}]
        self.assertRaises(SchemaTypeError, mydoc.validate)

    def test_adding_custom_type(self):
        class MyDoc(SchemaDocument):
            structure = {
                "foo": str,
            }
            authorized_types = SchemaDocument.authorized_types + [str]

        mydoc = MyDoc()

    def test_schema_operator(self):
        from mongokit.operators import SchemaOperator

        class OP(SchemaOperator):
            repr = "op"

        op = OP()
        self.assertRaises(NotImplementedError, op.validate, "bla")

    def test_or_operator(self):
        from mongokit import OR
        assert repr(OR(int, str)) == "<int or str>"

        failed = False
        try:

            class BadMyDoc(SchemaDocument):
                structure = {"bla": OR(int, tuple)}
        except StructureError as e:
            self.assertEqual(
                str(e),
                "BadMyDoc: <%s 'tuple'> in <int or tuple> is not an authorized type (type found)"
                % ('type' if six.PY2 else 'class'))
            failed = True
        self.assertEqual(failed, True)

        from datetime import datetime
        if six.PY2:
            string_type = basestring
        else:
            string_type = str

        class MyDoc(SchemaDocument):
            structure = {
                "foo": OR(six.text_type, int),
                "bar": OR(six.text_type, datetime),
                "foobar": OR(string_type, int),
            }

        mydoc = MyDoc()
        assert str(
            mydoc.structure['foo']) == '<%s or int>' % six.text_type.__name__
        assert str(mydoc.structure['bar']
                   ) == '<%s or datetime>' % six.text_type.__name__
        assert str(
            mydoc.structure['foobar']) == '<%s or int>' % string_type.__name__
        assert mydoc == {'foo': None, 'bar': None, 'foobar': None}
        mydoc['foo'] = 3.0
        self.assertRaises(SchemaTypeError, mydoc.validate)
        mydoc['foo'] = six.u("foo")
        mydoc.validate()
        mydoc['foo'] = 3
        mydoc.validate()
        mydoc['foo'] = 'bar'
        if six.PY2:
            self.assertRaises(SchemaTypeError, mydoc.validate)
        else:
            mydoc.validate()
        mydoc['foo'] = datetime.now()
        self.assertRaises(SchemaTypeError, mydoc.validate)
        mydoc['foo'] = six.u("foo")
        mydoc['bar'] = datetime.now()
        mydoc.validate()
        mydoc['bar'] = six.u("today")
        mydoc.validate()
        mydoc['bar'] = 25
        self.assertRaises(SchemaTypeError, mydoc.validate)
        mydoc['bar'] = six.u("bar")
        mydoc["foo"] = six.u("foo")
        mydoc["foobar"] = "foobar"
        mydoc.validate()
        mydoc["foobar"] = datetime.now()
        self.assertRaises(SchemaTypeError, mydoc.validate)
        mydoc["foobar"] = 3
        mydoc.validate()

    def test_not_operator(self):
        from mongokit import NOT
        failed = False
        try:

            class BadMyDoc(SchemaDocument):
                structure = {"bla": NOT(int, tuple)}
        except StructureError as e:
            self.assertEqual(
                str(e),
                "BadMyDoc: <%s 'tuple'> in <not int, not tuple> is not an authorized type (type found)"
                % ('type' if six.PY2 else 'class'))
            failed = True
        self.assertEqual(failed, True)

        from datetime import datetime
        if six.PY2:
            string_type = basestring
        else:
            string_type = str

        class MyDoc(SchemaDocument):
            structure = {
                "foo": NOT(six.text_type, int),
                "bar": NOT(datetime),
                "foobar": NOT(string_type)
            }

        mydoc = MyDoc()
        assert str(mydoc.structure['foo']
                   ) == '<not %s, not int>' % six.text_type.__name__, str(
                       mydoc.structure['foo'])
        assert str(mydoc.structure['bar']) == '<not datetime>'
        assert str(
            mydoc.structure['foobar']) == '<not %s>' % string_type.__name__
        assert mydoc == {'foo': None, 'bar': None, 'foobar': None}
        assert mydoc['foo'] is None
        assert mydoc['bar'] is None
        assert mydoc['foobar'] is None
        mydoc['foo'] = 3
        self.assertRaises(SchemaTypeError, mydoc.validate)
        mydoc['foo'] = u"foo"
        self.assertRaises(SchemaTypeError, mydoc.validate)
        mydoc['foo'] = 3.0
        mydoc.validate()
        mydoc['foo'] = datetime.now()
        mydoc.validate()

        mydoc['bar'] = datetime.now()
        self.assertRaises(SchemaTypeError, mydoc.validate)
        mydoc['bar'] = u"today"
        mydoc.validate()
        mydoc['bar'] = 25
        mydoc.validate()
        mydoc['foobar'] = 'abc'
        self.assertRaises(SchemaTypeError, mydoc.validate)
        mydoc['foobar'] = 1
        mydoc.validate()

    def test_is_operator(self):
        from mongokit import IS
        failed = False
        try:

            class BadMyDoc(SchemaDocument):
                structure = {"bla": IS(('bla', ), 3)}
        except StructureError as e:
            self.assertEqual(
                str(e),
                "BadMyDoc: ('bla',) in <is ('bla',) or is 3> is not an authorized type (tuple found)"
            )
            failed = True
        self.assertEqual(failed, True)

        from datetime import datetime

        class MyDoc(SchemaDocument):
            structure = {"foo": IS(u'spam', u'eggs'), "bar": IS(u'3', 3)}

        mydoc = MyDoc()
        if six.PY2:
            assert str(mydoc.structure['foo']) == "<is u'spam' or is u'eggs'>"
            assert str(mydoc.structure['bar']) == "<is u'3' or is 3>"
        else:
            assert str(mydoc.structure['foo']) == "<is 'spam' or is 'eggs'>"
            assert str(mydoc.structure['bar']) == "<is '3' or is 3>"
        assert mydoc == {'foo': None, 'bar': None}
        assert mydoc['foo'] is None
        assert mydoc['bar'] is None
        mydoc['foo'] = 3
        self.assertRaises(SchemaTypeError, mydoc.validate)
        mydoc['foo'] = u"bla"
        self.assertRaises(SchemaTypeError, mydoc.validate)
        mydoc['foo'] = datetime.now()
        self.assertRaises(SchemaTypeError, mydoc.validate)
        mydoc['foo'] = u"spam"
        mydoc.validate()
        mydoc['foo'] = u"eggs"
        mydoc.validate()

        mydoc['bar'] = datetime.now()
        self.assertRaises(SchemaTypeError, mydoc.validate)
        mydoc['bar'] = u"today"
        self.assertRaises(SchemaTypeError, mydoc.validate)
        mydoc['bar'] = 'foo'
        self.assertRaises(SchemaTypeError, mydoc.validate)
        mydoc['bar'] = 3
        mydoc.validate()
        mydoc['bar'] = u"3"
        mydoc.validate()

    def test_subclassed_type(self):
        """
        accept all subclass of supported type
        """
        class CustomFloat(float):
            def __init__(self, float):
                self = float + 2

        class MyDoc(SchemaDocument):
            structure = {
                "foo": float,
            }

        mydoc = MyDoc()
        mydoc['foo'] = CustomFloat(4)
        mydoc.validate()

    def test_set_type(self):
        from mongokit import Set

        class MyDoc(Document):
            structure = {
                "tags": Set(int),
            }

        self.connection.register([MyDoc])
        mydoc = self.col.MyDoc()
        mydoc['tags'] = set(["1", "1", "2", "3", "4"])
        self.assertRaises(ValueError, mydoc.validate)
        mydoc['tags'] = set([1, 1, 2, 3, 4])
        mydoc.save()

        doc = self.col.MyDoc.find_one()
        assert doc['tags'] == set([1, 2, 3, 4]), doc['tags']

    def test_set_type2(self):
        class MyDoc(Document):
            structure = {
                'title': six.text_type,
                'category': Set(six.text_type)
            }
            required_fields = ['title']

        self.connection.register([MyDoc])
        doc = self.col.MyDoc()
        print(doc)  # {'category': set([]), 'title': None}
        assert isinstance(doc['category'], set)
        try:
            doc.validate()
        except RequireFieldError as e:
            print(e)  # title is required

        print(doc)  # {'category': [], 'title': None}
        assert isinstance(doc['category'], set)
        doc['title'] = u'hello'
        doc.validate()

    def test_int_type(self):
        @self.connection.register
        class MyDoc(Document):
            structure = {
                "foo": int,
            }

        mydoc = self.col.MyDoc()
        mydoc['foo'] = ''
        self.assertRaises(SchemaTypeError, mydoc.validate)
        mydoc['foo'] = 10
        mydoc.save()

    def test_uuid_type(self):
        import uuid

        @self.connection.register
        class MyDoc(Document):
            structure = {
                'uuid': uuid.UUID,
            }

        uid = uuid.uuid4()
        obj = self.col.MyDoc()
        obj['uuid'] = uid
        obj.save()

        assert isinstance(self.col.MyDoc.find_one()['uuid'], uuid.UUID)

    if six.PY2:

        def test_binary_with_str_type(self):
            import bson
            six.text_type

            @self.connection.register
            class MyDoc(Document):
                structure = {
                    'my_binary': basestring,
                }

            obj = self.col.MyDoc()
            # non-utf8 string
            non_utf8 = "\xFF\xFE\xFF"
            obj['my_binary'] = non_utf8

            self.assertRaises(bson.errors.InvalidStringData, obj.validate)

        def test_binary_with_unicode_type(self):
            import bson

            @self.connection.register
            class MyDoc(Document):
                structure = {
                    'my_binary': unicode,
                }

            obj = self.col.MyDoc()
            # non-utf8 string
            non_utf8 = "\xFF\xFE\xFF"
            obj['my_binary'] = non_utf8

            self.assertRaises(bson.errors.InvalidStringData, obj.validate)

    def test_binary_with_binary_type(self):
        import bson

        @self.connection.register
        class MyDoc(Document):
            structure = {
                'my_binary': bson.binary.Binary,
            }

        obj = self.col.MyDoc()
        # non-utf8 string
        string = "\xFF\xFE\xFF"

        if six.PY3:
            bin_obj = bson.binary.Binary(bytes(string, 'utf-8'))
        else:
            bin_obj = bson.binary.Binary(string)

        obj['my_binary'] = bin_obj
        obj.save()
        db_obj = bson.binary.Binary(self.col.MyDoc.find_one()['my_binary'])
        self.assertEquals(db_obj, bin_obj)
Example #7
0
class InheritedQueriesTestCase(unittest.TestCase):
    def setUp(self):
        self.connection = Connection(safe=True)
        self.col = self.connection['test']['mongolite']

    def tearDown(self):
        self.connection.drop_database('test')

    def test_use_inherited_queries(self):
        @self.connection.register
        class A(Document):
            __database__ = 'test'
            __collection__ = 'mongolite'
            structure = {
                '_type': str,
                'a': {
                    'foo': int,
                    'bar': str,
                }
            }

        @self.connection.register
        class B(A):
            structure = {
                'b': {
                    'eggs': float,
                }
            }

        doc_a = self.connection.A()
        self.assertEqual(doc_a['_type'], 'A')
        doc_a['a']['foo'] = 3
        doc_a['a']['bar'] = 'Hello World'
        doc_a.save()

        doc_b = self.connection.B()
        self.assertEqual(doc_b['_type'], 'B')
        doc_b['a']['foo'] = 42
        doc_b['a']['bar'] = 'bye bye'
        doc_b['b']['eggs'] = 3.14
        doc_b.save()

        self.assertTrue(
            isinstance(self.connection.A.find_one({'_id': doc_b['_id']}), B))
        self.assertTrue(
            isinstance(
                self.connection.A.find({
                    '_id': doc_b['_id']
                }).next(), B))
        self.assertTrue(
            isinstance(self.connection.A.find({'_id': doc_b['_id']})[0], B))

    def test_inherited_queries_without___collection__(self):
        @self.connection.register
        class A(Document):
            structure = {
                '_type': str,
                'a': {
                    'foo': int,
                    'bar': str,
                }
            }

        @self.connection.register
        class B(A):
            structure = {
                'b': {
                    'eggs': float,
                }
            }

        doc_a = self.col.A()
        self.assertEqual(doc_a['_type'], 'A')
        doc_a['a']['foo'] = 3
        doc_a['a']['bar'] = 'Hello World'
        doc_a.save()

        doc_b = self.col.B()
        self.assertEqual(doc_b['_type'], 'B')
        doc_b['a']['foo'] = 42
        doc_b['a']['bar'] = 'bye bye'
        doc_b['b']['eggs'] = 3.14
        doc_b.save()

        self.assertTrue(
            isinstance(self.col.A.find_one({'_id': doc_b['_id']}), B))
        self.assertTrue(
            isinstance(self.col.A.find({
                '_id': doc_b['_id']
            }).next(), B))
        self.assertTrue(
            isinstance(self.col.A.find({'_id': doc_b['_id']})[0], B))

    def test_type_field_is_None(self):
        @self.connection.register
        class A(Document):
            type_field = None
            structure = {
                '_type': str,
                'a': {
                    'foo': int,
                    'bar': str,
                }
            }

        @self.connection.register
        class B(A):
            structure = {
                'b': {
                    'eggs': float,
                }
            }

        doc_a = self.col.A()
        self.assertEqual(doc_a['_type'], None)
        doc_a['a']['foo'] = 3
        doc_a['a']['bar'] = 'Hello World'
        doc_a.save()

        doc_b = self.col.B()
        self.assertEqual(doc_b['_type'], None)
        doc_b['a']['foo'] = 42
        doc_b['a']['bar'] = 'bye bye'
        doc_b['b']['eggs'] = 3.14
        doc_b.save()

        self.assertTrue(
            isinstance(self.col.A.find_one({'_id': doc_b['_id']}), A))
        self.assertTrue(
            isinstance(self.col.A.find({
                '_id': doc_b['_id']
            }).next(), A))
        self.assertFalse(
            isinstance(self.col.A.find_one({'_id': doc_b['_id']}), B))
        self.assertFalse(
            isinstance(self.col.A.find({
                '_id': doc_b['_id']
            }).next(), B))

    def test_no__type(self):
        @self.connection.register
        class A(Document):
            structure = {
                'a': {
                    'foo': int,
                    'bar': str,
                }
            }

        @self.connection.register
        class B(A):
            structure = {
                'b': {
                    'eggs': float,
                }
            }

        doc_a = self.col.A()
        self.assertTrue('_type' not in doc_a)
        doc_a['a']['foo'] = 3
        doc_a['a']['bar'] = 'Hello World'
        doc_a.save()

        doc_b = self.col.B()
        self.assertTrue('_type' not in doc_b)
        doc_b['a']['foo'] = 42
        doc_b['a']['bar'] = 'bye bye'
        doc_b['b']['eggs'] = 3.14
        doc_b.save()

        self.assertTrue(
            isinstance(self.col.A.find_one({'_id': doc_b['_id']}), A))
        self.assertTrue(
            isinstance(self.col.A.find({
                '_id': doc_b['_id']
            }).next(), A))
        self.assertFalse(
            isinstance(self.col.A.find_one({'_id': doc_b['_id']}), B))
        self.assertFalse(
            isinstance(self.col.A.find({
                '_id': doc_b['_id']
            }).next(), B))

    def test_change_type_field(self):
        @self.connection.register
        class A(Document):
            type_field = '_t'
            structure = {
                '_type': str,
                '_t': str,
                'a': {
                    'foo': int,
                    'bar': str,
                }
            }

        @self.connection.register
        class B(A):
            structure = {
                'b': {
                    'eggs': float,
                }
            }

        doc_a = self.col.A()
        self.assertEqual(doc_a['_type'], None)
        self.assertEqual(doc_a['_t'], 'A')
        doc_a['a']['foo'] = 3
        doc_a['a']['bar'] = 'Hello World'
        doc_a.save()

        doc_b = self.col.B()
        self.assertEqual(doc_b['_type'], None)
        self.assertEqual(doc_b['_t'], 'B')
        doc_b['a']['foo'] = 42
        doc_b['a']['bar'] = 'bye bye'
        doc_b['b']['eggs'] = 3.14
        doc_b.save()

        self.assertTrue(
            isinstance(self.col.A.find_one({'_id': doc_b['_id']}), A))
        self.assertTrue(
            isinstance(self.col.A.find({
                '_id': doc_b['_id']
            }).next(), A))
        self.assertTrue(
            isinstance(self.col.A.find_one({'_id': doc_b['_id']}), B))
        self.assertTrue(
            isinstance(self.col.A.find({
                '_id': doc_b['_id']
            }).next(), B))
Example #8
0
class DescriptorsTestCase(unittest.TestCase):
    def setUp(self):
        self.connection = Connection()
        self.col = self.connection['test']['mongokit']
        
    def tearDown(self):
        self.connection.drop_database('test')
    
    def test_list_embed_dot_notation(self):
        """Attempt to set a default for a sub element using dot notation

        Either this or test_list_embed_list_notation should pass
        """

        class ListEmbed(Document):
            use_dot_notation = True
            structure = {
                'list': [
                    {
                        'name': basestring,
                        'age': int
                    }
                ]
            }

            default_values = {
                'list.name': 'default'
            }

        self.connection.register([ListEmbed])

        doc = self.col.ListEmbed()
        self.assertDictEqual(doc, {'list': []})

        doc.list.append({'age': 23})

        self.assertDictEqual(
            doc, {
                'list': [
                    {
                        'name': 'default',
                        'age': 23
                    }
                ]
            }
        )
    
    def test_list_embed_list_notation(self):
        """Attempt to set a default for a sub element using list notation

        Either this or test_list_embed_dot_notation should pass
        """

        class ListEmbed(Document):
            use_dot_notation = True
            structure = {
                'list': [
                    {
                        'name': basestring,
                        'age': int
                    }
                ]
            }

            default_values = {
                'list': [
                    {
                        'name': 'default'
                    }
                ]
            }

        self.connection.register([ListEmbed])

        doc = self.col.ListEmbed()
        self.assertDictEqual(doc, {'list': []})

        doc.list.append({'age': 23})

        self.assertDictEqual(
            doc, {
                'list': [
                    {
                        'name': 'default',
                        'age': 23
                    }
                ]
            }
        )

    def test_list_embed_non_required_fields(self):
        """Confirm all fields are not required"""

        class ListEmbed(Document):
            use_dot_notation = True
            structure = {
                'list': [
                    {
                        'name': basestring,
                        'age': int
                    }
                ]
            }

        self.connection.register([ListEmbed])

        doc = self.col.ListEmbed()
        self.assertDictEqual(doc, {'list': []})

        doc.list.append({'age': 23})

        self.assertDictEqual(
            doc, {
                'list': [
                    {
                        'age': 23
                    }
                ]
            }
        )

        # Should validate fine
        doc.validate()

    def test_list_embed_required_fields_dot_notation(self):
        """Confirm list of object required field validation works"""

        class ListEmbed(Document):
            use_dot_notation = True
            structure = {
                'list': [
                    {
                        'name': basestring,
                        'age': int
                    }
                ]
            }

            required_fields = ['list.name']

        self.connection.register([ListEmbed])

        doc = self.col.ListEmbed()
        self.assertDictEqual(doc, {'list': []})

        doc.list = [{'name': 'bob'}]

        self.assertDictEqual(
            doc, {
                'list': [
                    {
                        'name': 'bob'
                    }
                ]
            }
        )

        # Should validate fine
        doc.validate()

        doc.list = [{'age': 23}]

        self.assertDictEqual(
            doc, {
                'list': [
                    {
                        'age': 23
                    }
                ]
            }
        )

        try:
            doc.validate()
            self.fail('Not a valid document')
        except:
            pass
Example #9
0
class TypesTestCase(unittest.TestCase):

    def setUp(self):
        self.connection = Connection()
        self.col = self.connection['test']['mongokit']
        
    def tearDown(self):
        self.connection.drop_database('test')


    def test_authorized_type(self):
       for auth_type in SchemaDocument.authorized_types:
            if auth_type is dict:
                auth_type = {}
            class MyDoc(SchemaDocument):
                structure = { "foo":auth_type }
            if type(auth_type) is dict:
                assert MyDoc() == {"foo":{}}, MyDoc()
            elif auth_type is list:
                assert MyDoc() == {"foo":[]}
            else:
                assert MyDoc() == {"foo":None}, auth_type
 
    def test_not_authorized_type(self):
        for unauth_type in [set, str]:
            class MyDoc(SchemaDocument):
                structure = { "foo":[unauth_type] }
            self.assertRaises( StructureError, MyDoc )
            class MyDoc(SchemaDocument):
                structure = { "foo":(unauth_type) }
            self.assertRaises( StructureError, MyDoc )
            class MyDoc2(SchemaDocument):
                structure = { 'foo':[{int:unauth_type }]}
            self.assertRaises( StructureError, MyDoc2 )
            class MyDoc3(SchemaDocument):
                structure = { 'foo':[{unauth_type:int }]}
            self.assertRaises( AuthorizedTypeError, MyDoc3 )

        class MyDoc4(SchemaDocument):
            structure = {1:unicode}
        self.assertRaises( StructureError, MyDoc4 )


    def test_type_from_functions(self):
        from datetime import datetime
        class MyDoc(SchemaDocument):
            structure = {
                "foo":datetime,
            }
        assert MyDoc() == {"foo":None}, MyDoc()
        mydoc = MyDoc()
        mydoc['foo'] = datetime.now()
        mydoc.validate()

    def test_non_typed_list(self):
        class MyDoc(SchemaDocument):
            structure = {
                "foo":[]
            }
        mydoc = MyDoc()
        mydoc.validate()
        assert mydoc['foo'] == []
        mydoc['foo'] = [u"bla", 23]
        mydoc.validate()
        mydoc['foo'] = [set([1,2]), "bla"]
        self.assertRaises(AuthorizedTypeError, mydoc.validate)
        mydoc['foo'] = u"bla"
        self.assertRaises(SchemaTypeError, mydoc.validate)

#        class MyDoc(SchemaDocument):
#            structure = {
#                "foo":list
#            }
#        mydoc = MyDoc()
#        mydoc.validate()
#        assert mydoc['foo'] == []
#        mydoc['foo'] = [u"bla", 23]
#        mydoc.validate()
#        mydoc['foo'] = [set([1,2]), "bla"]
#        self.assertRaises(AuthorizedTypeError, mydoc.validate)
  
    def test_typed_list(self):
        class MyDoc(SchemaDocument):
            structure = {
                "foo":[int]
            }
        mydoc = MyDoc()
        mydoc.validate()
        assert mydoc['foo'] == []
        mydoc['foo'] = [1,2,3]
        mydoc.validate()
        mydoc['foo'] = [u"bla"]
        self.assertRaises(SchemaTypeError, mydoc.validate)

    def test_typed_list_with_dict(self):
        class MyDoc(SchemaDocument):
            structure = {
                "foo":[{unicode:int}]
            }
        mydoc = MyDoc()
        mydoc['foo'] = [{u"bla":1},{u"ble":2}]
        mydoc.validate()
        mydoc['foo'] = [{u"bla":u"bar"}]
        self.assertRaises(SchemaTypeError, mydoc.validate)

    def test_typed_list_with_list(self):
        class MyDoc(SchemaDocument):
            structure = {
                "foo":[[unicode]]
            }
        mydoc = MyDoc()
        mydoc['foo'] = [[u"bla",u"blu"],[u"ble",u"bli"]]
        mydoc.validate()
        mydoc['foo'] = [[u"bla",1]]
        self.assertRaises(SchemaTypeError, mydoc.validate)

    def test_typed_tuple(self):
        class MyDoc(SchemaDocument):
            structure = {
                "foo":(int, unicode, float)
            }
        mydoc = MyDoc()
        mydoc.validate()
        assert mydoc['foo'] == [None, None, None]
        mydoc['foo'] = [u"bla", 1, 4.0]
        self.assertRaises(SchemaTypeError, mydoc.validate)
        mydoc['foo'] = [1, u"bla"]
        self.assertRaises(SchemaTypeError, mydoc.validate)
        mydoc['foo'] = u"bla"
        self.assertRaises(SchemaTypeError, mydoc.validate)
        mydoc['foo'] = [1,u'bar',3.2]
        mydoc.validate()
        mydoc['foo'] = [None, u"bla", 3.1]
        mydoc.validate()
        mydoc['foo'][0] = 50
        mydoc.validate()

    def test_nested_typed_tuple(self):
        class MyDoc(SchemaDocument):
            structure = {
                "foo":{'bar':(int, unicode, float)}
            }
        mydoc = MyDoc()
        mydoc.validate()
        assert mydoc['foo']['bar'] == [None, None, None]
        mydoc['foo']['bar'] = [u"bla", 1, 4.0]
        self.assertRaises(SchemaTypeError, mydoc.validate)
        mydoc['foo']['bar'] = [1, u"bla"]
        self.assertRaises(SchemaTypeError, mydoc.validate)
        mydoc['foo']['bar'] = [1,u'bar',3.2]
        mydoc.validate()
        mydoc['foo']['bar'] = [None, u"bla", 3.1]
        mydoc.validate()
        mydoc['foo']['bar'][0] = 50
        mydoc.validate()

    def test_saving_tuple(self):
        class MyDoc(Document):
            structure = { 'foo': (int, unicode, float) }
        self.connection.register([MyDoc])

        mydoc = self.col.MyDoc()
        assert mydoc == {'foo': [None, None, None]}, mydoc
        mydoc['foo'] = (1, u'a', 1.1) # note that this will be converted to list
        assert mydoc == {'foo': (1, u'a', 1.1000000000000001)}, mydoc
        mydoc.save()
        mydoc = self.col.find_one()

        class MyDoc(Document):
            structure = {'foo':[unicode]}
        self.connection.register([])
        self.connection.register([MyDoc])
        mydoc = self.col.MyDoc()
        mydoc['foo'] = (u'bla', u'bli', u'blu', u'bly')
        mydoc.save()
        mydoc = self.col.get_from_id(mydoc['_id'])


    def test_nested_typed_tuple_in_list(self):
        class MyDoc(SchemaDocument):
            structure = {
                "foo":{'bar':[(int, unicode, float)]}
            }
        mydoc = MyDoc()
        mydoc.validate()
        assert mydoc == {'foo': {'bar': []}}
        mydoc['foo']['bar'].append([u"bla", 1, 4.0])
        self.assertRaises(SchemaTypeError, mydoc.validate)
        mydoc['foo']['bar'] = []
        mydoc['foo']['bar'].append([1, u"bla"])
        self.assertRaises(SchemaTypeError, mydoc.validate)
        mydoc['foo']['bar'] = []
        mydoc['foo']['bar'].append([1,u'bar',3.2])
        mydoc.validate()
        mydoc['foo']['bar'].append([None, u"bla", 3.1])
        mydoc.validate()
        mydoc['foo']['bar'][1][0] = 50
        mydoc.validate()

    def test_dict_unicode_typed_list(self):
        class MyDoc(SchemaDocument):
            structure = {
                "foo":{unicode:[int]}
            }
        mydoc = MyDoc()
        mydoc['foo'] = {u"bar":[1,2,3]}
        mydoc.validate()
        mydoc['foo'] = {u"bar":[u"bla"]}
        self.assertRaises(SchemaTypeError, mydoc.validate)
        mydoc['foo'] = {3:[1,2,3]}
        self.assertRaises(SchemaTypeError, mydoc.validate)

    def test_with_custom_object(self):
        class MyDict(dict):
            pass
        class MyDoc(SchemaDocument):
            structure = {
                "foo":{unicode:int}
            }
        mydoc = MyDoc()
        mydict = MyDict()
        mydict[u"foo"] = 3
        mydoc["foo"] = mydict
        mydoc.validate()
 
    def test_custom_object_as_type(self):
        class MyDict(dict):
            pass
        class MyDoc(SchemaDocument):
            structure = {
                "foo":MyDict({unicode:int})
            }
        mydoc = MyDoc()
        mydict = MyDict()
        mydict[u"foo"] = 3
        mydoc["foo"] = mydict
        mydoc.validate()
        mydoc['foo'] = {u"foo":"7"}
        self.assertRaises(SchemaTypeError, mydoc.validate)

        class MyInt(int):
            pass
        class MyDoc(SchemaDocument):
            structure = {
                "foo":MyInt,
            }
        mydoc = MyDoc()
        mydoc["foo"] = MyInt(3)
        mydoc.validate()
        mydoc['foo'] = 3
        self.assertRaises(SchemaTypeError, mydoc.validate)

    def test_list_instead_of_dict(self):
        class MyDoc(SchemaDocument):
            structure = {
                "foo":{unicode:[unicode]}
            }
        mydoc = MyDoc()
        mydoc['foo'] = [u'bla']
        self.assertRaises(SchemaTypeError, mydoc.validate)

    def _test_big_nested_example(self):
        # XXX TODO
        class MyDoc(SchemaDocument):
            structure = {
                "foo":{unicode:[int], u"bar":{"spam":{int:[unicode]}}},
                "bla":{"blo":{"bli":[{"arf":unicode}]}},
            }
        mydoc = MyDoc()
        mydoc['foo'].update({u"bir":[1,2,3]})
        mydoc['foo'][u'bar'][u'spam'] = {1:[u'bla', u'ble'], 3:[u'foo', u'bar']}
        mydoc.validate()
        mydoc['bla']['blo']['bli'] = [{u"bar":[u"bla"]}]
        self.assertRaises(SchemaTypeError, mydoc.validate)
        mydoc['bla']['blo']['bli'] = [{u"arf":[1]}]
        self.assertRaises(SchemaTypeError, mydoc.validate)

        
    def test_adding_custom_type(self):
        class MyDoc(SchemaDocument):
            structure = {
                "foo":str,
            }
            authorized_types = SchemaDocument.authorized_types + [str]
        mydoc = MyDoc()
    
    def test_schema_operator(self):
        from mongokit.operators import SchemaOperator
        class OP(SchemaOperator):
            repr = "op"
        op = OP()
        self.assertRaises(NotImplementedError, op.validate, "bla")
            

    def test_or_operator(self):
        from mongokit import OR
        assert repr(OR(unicode, str)) == "<unicode or str>"

        class BadMyDoc(SchemaDocument):
            structure = {"bla":OR(unicode,str)}
        self.assertRaises(StructureError, BadMyDoc)

        from datetime import datetime
        class MyDoc(SchemaDocument):
            structure = {
                "foo":OR(unicode,int),
                "bar":OR(unicode, datetime)
            }

        mydoc = MyDoc()
        assert str(mydoc.structure['foo']) == '<unicode or int>'
        assert str(mydoc.structure['bar']) == '<unicode or datetime>'
        assert mydoc == {'foo': None, 'bar': None}
        mydoc['foo'] = 3.0
        self.assertRaises(SchemaTypeError, mydoc.validate)
        mydoc['foo'] = u"foo"
        mydoc.validate()
        mydoc['foo'] = 3
        mydoc.validate()
        mydoc['foo'] = 'bar'
        self.assertRaises(SchemaTypeError, mydoc.validate)

        mydoc['foo'] = datetime.now()
        self.assertRaises(SchemaTypeError, mydoc.validate)
        mydoc['foo'] = u"foo"
        mydoc['bar'] = datetime.now()
        mydoc.validate()
        mydoc['bar'] = u"today"
        mydoc.validate()
        mydoc['bar'] = 25
        self.assertRaises(SchemaTypeError, mydoc.validate)

    def test_not_operator(self):
        from mongokit import NOT
        class BadMyDoc(SchemaDocument):
            structure = {"bla":NOT(unicode,str)}
        self.assertRaises(StructureError, BadMyDoc)

        from datetime import datetime
        class MyDoc(SchemaDocument):
            structure = {
                "foo":NOT(unicode,int),
                "bar":NOT(datetime)
            }

        mydoc = MyDoc()
        assert str(mydoc.structure['foo']) == '<not unicode, not int>', str(mydoc.structure['foo'])
        assert str(mydoc.structure['bar']) == '<not datetime>'
        assert mydoc == {'foo': None, 'bar': None}
        assert mydoc['foo'] is None
        assert mydoc['bar'] is None
        mydoc['foo'] = 3
        self.assertRaises(SchemaTypeError, mydoc.validate)
        mydoc['foo'] = u"foo"
        self.assertRaises(SchemaTypeError, mydoc.validate)
        mydoc['foo'] = 3.0
        mydoc.validate()
        mydoc['foo'] = datetime.now()
        mydoc.validate()

        mydoc['bar'] = datetime.now()
        self.assertRaises(SchemaTypeError, mydoc.validate)
        mydoc['bar'] = u"today"
        mydoc.validate()
        mydoc['bar'] = 25
        mydoc.validate()

    def test_is_operator(self):
        from mongokit import IS
        class BadMyDoc(SchemaDocument):
            structure = {"bla":IS('bla',3)}
        self.assertRaises(StructureError, BadMyDoc)

        from datetime import datetime
        class MyDoc(SchemaDocument):
            structure = {
                "foo":IS(u'spam',u'eggs'),
                "bar":IS(u'3', 3)
            }

        mydoc = MyDoc()
        assert str(mydoc.structure['foo']) == "<is u'spam' or is u'eggs'>"
        assert str(mydoc.structure['bar']) == "<is u'3' or is 3>"
        assert mydoc == {'foo': None, 'bar': None}
        assert mydoc['foo'] is None
        assert mydoc['bar'] is None
        mydoc['foo'] = 3
        self.assertRaises(SchemaTypeError, mydoc.validate)
        mydoc['foo'] = u"bla"
        self.assertRaises(SchemaTypeError, mydoc.validate)
        mydoc['foo'] = datetime.now()
        self.assertRaises(SchemaTypeError, mydoc.validate)
        mydoc['foo'] = u"spam"
        mydoc.validate()
        mydoc['foo'] = u"eggs"
        mydoc.validate()

        mydoc['bar'] = datetime.now()
        self.assertRaises(SchemaTypeError, mydoc.validate)
        mydoc['bar'] = u"today"
        self.assertRaises(SchemaTypeError, mydoc.validate)
        mydoc['bar'] = 'foo'
        self.assertRaises(SchemaTypeError, mydoc.validate)
        mydoc['bar'] = 3
        mydoc.validate()
        mydoc['bar'] = u"3"
        mydoc.validate()

    def test_subclassed_type(self):
        """
        accept all subclass of supported type
        """
        class CustomFloat(float):
            def __init__(self, float):
                self = float + 2
        class MyDoc(SchemaDocument):
            structure = {
                "foo":float,
            }
        mydoc = MyDoc()
        mydoc['foo'] = CustomFloat(4)
        mydoc.validate()


    def test_set_type(self):
        from mongokit import Set
        class MyDoc(Document):
            structure = {
                "tags":Set(int),
            }

        self.connection.register([MyDoc])
        mydoc = self.col.MyDoc()
        mydoc['tags'] = set(["1","1","2","3","4"])
        self.assertRaises(ValueError, mydoc.validate)
        mydoc['tags'] = set([1,1,2,3,4])
        mydoc.save()

        doc = self.col.MyDoc.find_one()
        assert doc['tags'] == set([1,2,3,4]), doc['tags']
Example #10
0
class DescriptorsTestCase(unittest.TestCase):
    def setUp(self):
        self.connection = Connection()
        self.col = self.connection["test"]["mongokit"]

    def tearDown(self):
        self.connection.drop_database("test")

    def test_list_embed_dot_notation(self):
        """Attempt to set a default for a sub element using dot notation

        Either this or test_list_embed_list_notation should pass
        """

        class ListEmbed(Document):
            use_dot_notation = True
            structure = {"list": [{"name": basestring, "age": int}]}

            default_values = {"list.name": "default"}

        self.connection.register([ListEmbed])

        doc = self.col.ListEmbed()
        self.assertDictEqual(doc, {"list": []})

        doc.list.append({"age": 23})

        self.assertDictEqual(doc, {"list": [{"name": "default", "age": 23}]})

    def test_list_embed_list_notation(self):
        """Attempt to set a default for a sub element using list notation

        Either this or test_list_embed_dot_notation should pass
        """

        class ListEmbed(Document):
            use_dot_notation = True
            structure = {"list": [{"name": basestring, "age": int}]}

            default_values = {"list": [{"name": "default"}]}

        self.connection.register([ListEmbed])

        doc = self.col.ListEmbed()
        self.assertDictEqual(doc, {"list": [{"name": "default"}]})

        doc.list[0]["age"] = 23

        self.assertDictEqual(doc, {"list": [{"name": "default", "age": 23}]})

    def test_list_embed_non_required_fields(self):
        """Confirm all fields are not required"""

        class ListEmbed(Document):
            use_dot_notation = True
            structure = {"list": [{"name": basestring, "age": int}]}

        self.connection.register([ListEmbed])

        doc = self.col.ListEmbed()
        self.assertDictEqual(doc, {"list": []})

        doc.list.append({"age": 23})

        self.assertDictEqual(doc, {"list": [{"age": 23}]})

        # Should validate fine
        doc.validate()

    def test_list_embed_required_fields_dot_notation(self):
        """Confirm list of object required field validation works"""

        class ListEmbed(Document):
            use_dot_notation = True
            structure = {"list": [{"name": basestring, "age": int}]}

            required_fields = ["list.name"]

        self.connection.register([ListEmbed])

        doc = self.col.ListEmbed()
        self.assertDictEqual(doc, {"list": []})

        doc.list = [{"name": "bob"}]

        self.assertDictEqual(doc, {"list": [{"name": "bob"}]})

        # Should validate fine
        doc.validate()

        doc.list = [{"age": 23}]

        self.assertDictEqual(doc, {"list": [{"age": 23}]})

        try:
            doc.validate()
            self.fail("Not a valid document")
        except:
            pass
Example #11
0
class InheritedQueriesTestCase(unittest.TestCase):
    def setUp(self):
        self.connection = Connection(safe=True)
        self.col = self.connection['test']['mongolite']
        
    def tearDown(self):
        self.connection.drop_database('test')

    def test_use_inherited_queries(self):
        @self.connection.register
        class A(Document):
            __database__ = 'test'
            __collection__ = 'mongolite'
            structure = {
                '_type': unicode,
                'a':{
                    'foo': int,
                    'bar': unicode,
                }
            }

        @self.connection.register
        class B(A):
            structure = {
                'b': {
                    'eggs': float,
                }
            }

        doc_a = self.connection.A()
        self.assertEqual(doc_a['_type'], 'A')
        doc_a['a']['foo'] = 3
        doc_a['a']['bar'] = u'Hello World'
        doc_a.save()

        doc_b = self.connection.B()
        self.assertEqual(doc_b['_type'], 'B')
        doc_b['a']['foo'] = 42
        doc_b['a']['bar'] = u'bye bye'
        doc_b['b']['eggs'] = 3.14
        doc_b.save()

        self.assertTrue(isinstance(self.connection.A.find_one({'_id':doc_b['_id']}), B))
        self.assertTrue(isinstance(self.connection.A.find({'_id':doc_b['_id']}).next(), B))

    def test_inherited_queries_without___collection__(self):
        @self.connection.register
        class A(Document):
            structure = {
                '_type': unicode,
                'a':{
                    'foo': int,
                    'bar': unicode,
                }
            }

        @self.connection.register
        class B(A):
            structure = {
                'b': {
                    'eggs': float,
                }
            }

        doc_a = self.col.A()
        self.assertEqual(doc_a['_type'], 'A')
        doc_a['a']['foo'] = 3
        doc_a['a']['bar'] = u'Hello World'
        doc_a.save()

        doc_b = self.col.B()
        self.assertEqual(doc_b['_type'], 'B')
        doc_b['a']['foo'] = 42
        doc_b['a']['bar'] = u'bye bye'
        doc_b['b']['eggs'] = 3.14
        doc_b.save()

        self.assertTrue(isinstance(self.col.A.find_one({'_id':doc_b['_id']}), B))
        self.assertTrue(isinstance(self.col.A.find({'_id':doc_b['_id']}).next(), B))

    def test_type_field_is_None(self):
        @self.connection.register
        class A(Document):
            type_field = None
            structure = {
                '_type': unicode,
                'a':{
                    'foo': int,
                    'bar': unicode,
                }
            }

        @self.connection.register
        class B(A):
            structure = {
                'b': {
                    'eggs': float,
                }
            }

        doc_a = self.col.A()
        self.assertEqual(doc_a['_type'], None)
        doc_a['a']['foo'] = 3
        doc_a['a']['bar'] = u'Hello World'
        doc_a.save()

        doc_b = self.col.B()
        self.assertEqual(doc_b['_type'], None)
        doc_b['a']['foo'] = 42
        doc_b['a']['bar'] = u'bye bye'
        doc_b['b']['eggs'] = 3.14
        doc_b.save()

        self.assertTrue(isinstance(self.col.A.find_one({'_id':doc_b['_id']}), A))
        self.assertTrue(isinstance(self.col.A.find({'_id':doc_b['_id']}).next(), A))
        self.assertFalse(isinstance(self.col.A.find_one({'_id':doc_b['_id']}), B))
        self.assertFalse(isinstance(self.col.A.find({'_id':doc_b['_id']}).next(), B))

    def test_no__type(self):
        @self.connection.register
        class A(Document):
            structure = {
                'a':{
                    'foo': int,
                    'bar': unicode,
                }
            }

        @self.connection.register
        class B(A):
            structure = {
                'b': {
                    'eggs': float,
                }
            }

        doc_a = self.col.A()
        self.assertTrue('_type' not in doc_a)
        doc_a['a']['foo'] = 3
        doc_a['a']['bar'] = u'Hello World'
        doc_a.save()

        doc_b = self.col.B()
        self.assertTrue('_type' not in doc_b)
        doc_b['a']['foo'] = 42
        doc_b['a']['bar'] = u'bye bye'
        doc_b['b']['eggs'] = 3.14
        doc_b.save()

        self.assertTrue(isinstance(self.col.A.find_one({'_id':doc_b['_id']}), A))
        self.assertTrue(isinstance(self.col.A.find({'_id':doc_b['_id']}).next(), A))
        self.assertFalse(isinstance(self.col.A.find_one({'_id':doc_b['_id']}), B))
        self.assertFalse(isinstance(self.col.A.find({'_id':doc_b['_id']}).next(), B))

    def test_change_type_field(self):
        @self.connection.register
        class A(Document):
            type_field = '_t'
            structure = {
                '_type': unicode,
                '_t': unicode,
                'a':{
                    'foo': int,
                    'bar': unicode,
                }
            }

        @self.connection.register
        class B(A):
            structure = {
                'b': {
                    'eggs': float,
                }
            }

        doc_a = self.col.A()
        self.assertEqual(doc_a['_type'], None)
        self.assertEqual(doc_a['_t'], 'A')
        doc_a['a']['foo'] = 3
        doc_a['a']['bar'] = u'Hello World'
        doc_a.save()

        doc_b = self.col.B()
        self.assertEqual(doc_b['_type'], None)
        self.assertEqual(doc_b['_t'], 'B')
        doc_b['a']['foo'] = 42
        doc_b['a']['bar'] = u'bye bye'
        doc_b['b']['eggs'] = 3.14
        doc_b.save()

        self.assertTrue(isinstance(self.col.A.find_one({'_id':doc_b['_id']}), A))
        self.assertTrue(isinstance(self.col.A.find({'_id':doc_b['_id']}).next(), A))
        self.assertTrue(isinstance(self.col.A.find_one({'_id':doc_b['_id']}), B))
        self.assertTrue(isinstance(self.col.A.find({'_id':doc_b['_id']}).next(), B))
Example #12
0
class DescriptorsTestCase(unittest.TestCase):
    def setUp(self):
        self.connection = Connection()
        self.col = self.connection['test']['mongokit']

    def tearDown(self):
        self.connection.drop_database('test')

    def test_list_embed_dot_notation(self):
        """Attempt to set a default for a sub element using dot notation

        Either this or test_list_embed_list_notation should pass
        """
        class ListEmbed(Document):
            use_dot_notation = True
            structure = {'list': [{'name': basestring, 'age': int}]}

            default_values = {'list.name': 'default'}

        self.connection.register([ListEmbed])

        doc = self.col.ListEmbed()
        self.assertDictEqual(doc, {'list': []})

        doc.list.append({'age': 23})

        self.assertDictEqual(doc, {'list': [{'name': 'default', 'age': 23}]})

    def test_list_embed_list_notation(self):
        """Attempt to set a default for a sub element using list notation

        Either this or test_list_embed_dot_notation should pass
        """
        class ListEmbed(Document):
            use_dot_notation = True
            structure = {'list': [{'name': basestring, 'age': int}]}

            default_values = {'list': [{'name': 'default'}]}

        self.connection.register([ListEmbed])

        doc = self.col.ListEmbed()
        self.assertDictEqual(doc, {'list': [{'name': 'default'}]})

        doc.list[0]['age'] = 23

        self.assertDictEqual(doc, {'list': [{'name': 'default', 'age': 23}]})

    def test_list_embed_non_required_fields(self):
        """Confirm all fields are not required"""
        class ListEmbed(Document):
            use_dot_notation = True
            structure = {'list': [{'name': basestring, 'age': int}]}

        self.connection.register([ListEmbed])

        doc = self.col.ListEmbed()
        self.assertDictEqual(doc, {'list': []})

        doc.list.append({'age': 23})

        self.assertDictEqual(doc, {'list': [{'age': 23}]})

        # Should validate fine
        doc.validate()

    def test_list_embed_required_fields_dot_notation(self):
        """Confirm list of object required field validation works"""
        class ListEmbed(Document):
            use_dot_notation = True
            structure = {'list': [{'name': basestring, 'age': int}]}

            required_fields = ['list.name']

        self.connection.register([ListEmbed])

        doc = self.col.ListEmbed()
        self.assertDictEqual(doc, {'list': []})

        doc.list = [{'name': 'bob'}]

        self.assertDictEqual(doc, {'list': [{'name': 'bob'}]})

        # Should validate fine
        doc.validate()

        doc.list = [{'age': 23}]

        self.assertDictEqual(doc, {'list': [{'age': 23}]})

        try:
            doc.validate()
            self.fail('Not a valid document')
        except:
            pass
Example #13
0
class TypesTestCase(unittest.TestCase):

    def setUp(self):
        self.connection = Connection()
        self.col = self.connection['test']['mongokit']

    def tearDown(self):
        self.connection.drop_database('test')


    def test_authorized_type(self):
       for auth_type in SchemaDocument.authorized_types:
            if auth_type is dict:
                auth_type = {}
            class MyDoc(SchemaDocument):
                structure = { "foo":auth_type }
            if type(auth_type) is dict:
                assert MyDoc() == {"foo":{}}, MyDoc()
            elif auth_type is list:
                assert MyDoc() == {"foo":[]}
            else:
                assert MyDoc() == {"foo":None}, auth_type

    def test_not_authorized_type(self):
        for unauth_type in [set]:
            failed = False
            try:
                class MyDoc(SchemaDocument):
                    structure = { "foo":[unauth_type] }
            except StructureError as e:
                self.assertEqual(str(e), "MyDoc: %s is not an authorized type" % unauth_type)
                failed = True
            self.assertEqual(failed, True)
            failed = False
            try:
                class MyDoc(SchemaDocument):
                    structure = { "foo":(unauth_type) }
            except StructureError as e:
                self.assertEqual(str(e), "MyDoc: %s is not an authorized type" % unauth_type)
                failed = True
            self.assertEqual(failed, True)
            failed = False
            try:
                class MyDoc2(SchemaDocument):
                    structure = { 'foo':[{int:unauth_type }]}
            except StructureError as e:
                self.assertEqual(str(e), "MyDoc2: %s is not an authorized type" % unauth_type)
                failed = True
            self.assertEqual(failed, True)
            failed = False
            try:
                class MyDoc3(SchemaDocument):
                    structure = { 'foo':[{unauth_type:int }]}
            except AuthorizedTypeError as e:
                self.assertEqual(str(e), "MyDoc3: %s is not an authorized type" % unauth_type)
                failed = True
            self.assertEqual(failed, True)

        failed = False
        try:
            class MyDoc4(SchemaDocument):
                structure = {1:str}
        except StructureError as e:
            self.assertEqual(str(e), "MyDoc4: 1 must be a string or a type")
            failed = True
        self.assertEqual(failed, True)


    def test_type_from_functions(self):
        from datetime import datetime
        class MyDoc(SchemaDocument):
            structure = {
                "foo":datetime,
            }
        assert MyDoc() == {"foo":None}, MyDoc()
        mydoc = MyDoc()
        mydoc['foo'] = datetime.now()
        mydoc.validate()

    def test_non_typed_list(self):
        class MyDoc(SchemaDocument):
            structure = {
                "foo":[]
            }
        mydoc = MyDoc()
        mydoc.validate()
        assert mydoc['foo'] == []
        mydoc['foo'] = ["bla", 23]
        mydoc.validate()
        mydoc['foo'] = [set([1,2]), "bla"]
        self.assertRaises(AuthorizedTypeError, mydoc.validate)
        mydoc['foo'] = "bla"
        self.assertRaises(SchemaTypeError, mydoc.validate)

#        class MyDoc(SchemaDocument):
#            structure = {
#                "foo":list
#            }
#        mydoc = MyDoc()
#        mydoc.validate()
#        assert mydoc['foo'] == []
#        mydoc['foo'] = [u"bla", 23]
#        mydoc.validate()
#        mydoc['foo'] = [set([1,2]), "bla"]
#        self.assertRaises(AuthorizedTypeError, mydoc.validate)

    def test_typed_list(self):
        class MyDoc(SchemaDocument):
            structure = {
                "foo":[int]
            }
        mydoc = MyDoc()
        mydoc.validate()
        assert mydoc['foo'] == []
        mydoc['foo'] = [1,2,3]
        mydoc.validate()
        mydoc['foo'] = ["bla"]
        self.assertRaises(SchemaTypeError, mydoc.validate)

    def test_typed_list_with_dict(self):
        class MyDoc(SchemaDocument):
            structure = {
                "foo":[{str:int}]
            }
        mydoc = MyDoc()
        mydoc['foo'] = [{"bla":1},{"ble":2}]
        mydoc.validate()
        mydoc['foo'] = [{"bla":"bar"}]
        self.assertRaises(SchemaTypeError, mydoc.validate)

    def test_typed_list_with_list(self):
        class MyDoc(SchemaDocument):
            structure = {
                "foo":[[str]]
            }
        mydoc = MyDoc()
        mydoc['foo'] = [["bla","blu"],["ble","bli"]]
        mydoc.validate()
        mydoc['foo'] = [["bla",1]]
        self.assertRaises(SchemaTypeError, mydoc.validate)

    def test_typed_tuple(self):
        class MyDoc(SchemaDocument):
            structure = {
                "foo":(int, str, float)
            }
        mydoc = MyDoc()
        mydoc.validate()
        assert mydoc['foo'] == [None, None, None]
        mydoc['foo'] = ["bla", 1, 4.0]
        self.assertRaises(SchemaTypeError, mydoc.validate)
        mydoc['foo'] = [1, "bla"]
        self.assertRaises(SchemaTypeError, mydoc.validate)
        mydoc['foo'] = "bla"
        self.assertRaises(SchemaTypeError, mydoc.validate)
        mydoc['foo'] = [1,'bar',3.2]
        mydoc.validate()
        mydoc['foo'] = [None, "bla", 3.1]
        mydoc.validate()
        mydoc['foo'][0] = 50
        mydoc.validate()

    def test_nested_typed_tuple(self):
        class MyDoc(SchemaDocument):
            structure = {
                "foo":{'bar':(int, str, float)}
            }
        mydoc = MyDoc()
        mydoc.validate()
        assert mydoc['foo']['bar'] == [None, None, None]
        mydoc['foo']['bar'] = ["bla", 1, 4.0]
        self.assertRaises(SchemaTypeError, mydoc.validate)
        mydoc['foo']['bar'] = [1, "bla"]
        self.assertRaises(SchemaTypeError, mydoc.validate)
        mydoc['foo']['bar'] = [1,'bar',3.2]
        mydoc.validate()
        mydoc['foo']['bar'] = [None, "bla", 3.1]
        mydoc.validate()
        mydoc['foo']['bar'][0] = 50
        mydoc.validate()

    def test_saving_tuple(self):
        class MyDoc(Document):
            structure = { 'foo': (int, str, float) }
        self.connection.register([MyDoc])

        mydoc = self.col.MyDoc()
        assert mydoc == {'foo': [None, None, None]}, mydoc
        mydoc['foo'] = (1, 'a', 1.1) # note that this will be converted to list
        assert mydoc == {'foo': (1, 'a', 1.1000000000000001)}, mydoc
        mydoc.save()
        mydoc = self.col.find_one()

        class MyDoc(Document):
            structure = {'foo':[str]}
        self.connection.register([])
        self.connection.register([MyDoc])
        mydoc = self.col.MyDoc()
        mydoc['foo'] = ('bla', 'bli', 'blu', 'bly')
        mydoc.save()
        mydoc = self.col.get_from_id(mydoc['_id'])


    def test_nested_typed_tuple_in_list(self):
        class MyDoc(SchemaDocument):
            structure = {
                "foo":{'bar':[(int, str, float)]}
            }
        mydoc = MyDoc()
        mydoc.validate()
        assert mydoc == {'foo': {'bar': []}}
        mydoc['foo']['bar'].append(["bla", 1, 4.0])
        self.assertRaises(SchemaTypeError, mydoc.validate)
        mydoc['foo']['bar'] = []
        mydoc['foo']['bar'].append([1, "bla"])
        self.assertRaises(SchemaTypeError, mydoc.validate)
        mydoc['foo']['bar'] = []
        mydoc['foo']['bar'].append([1,'bar',3.2])
        mydoc.validate()
        mydoc['foo']['bar'].append([None, "bla", 3.1])
        mydoc.validate()
        mydoc['foo']['bar'][1][0] = 50
        mydoc.validate()

    def test_dict_unicode_typed_list(self):
        class MyDoc(SchemaDocument):
            structure = {
                "foo":{str:[int]}
            }
        mydoc = MyDoc()
        mydoc['foo'] = {"bar":[1,2,3]}
        mydoc.validate()
        mydoc['foo'] = {"bar":["bla"]}
        self.assertRaises(SchemaTypeError, mydoc.validate)
        mydoc['foo'] = {3:[1,2,3]}
        self.assertRaises(SchemaTypeError, mydoc.validate)

    def test_with_custom_object(self):
        class MyDict(dict):
            pass
        class MyDoc(SchemaDocument):
            structure = {
                "foo":{str:int}
            }
        mydoc = MyDoc()
        mydict = MyDict()
        mydict["foo"] = 3
        mydoc["foo"] = mydict
        mydoc.validate()

    def test_custom_object_as_type(self):
        class MyDict(dict):
            pass
        class MyDoc(SchemaDocument):
            structure = {
                "foo":MyDict({str:int})
            }
        mydoc = MyDoc()
        mydict = MyDict()
        mydict["foo"] = 3
        mydoc["foo"] = mydict
        mydoc.validate()
        mydoc['foo'] = {"foo":"7"}
        self.assertRaises(SchemaTypeError, mydoc.validate)

        class MyInt(int):
            pass
        class MyDoc(SchemaDocument):
            structure = {
                "foo":MyInt,
            }
        mydoc = MyDoc()
        mydoc["foo"] = MyInt(3)
        mydoc.validate()
        mydoc['foo'] = 3
        self.assertRaises(SchemaTypeError, mydoc.validate)

    def test_list_instead_of_dict(self):
        class MyDoc(SchemaDocument):
            structure = {
                "foo":{str:[str]}
            }
        mydoc = MyDoc()
        mydoc['foo'] = ['bla']
        self.assertRaises(SchemaTypeError, mydoc.validate)

    def _test_big_nested_example(self):
        # XXX TODO
        class MyDoc(SchemaDocument):
            structure = {
                "foo":{str:[int], "bar":{"spam":{int:[str]}}},
                "bla":{"blo":{"bli":[{"arf":str}]}},
            }
        mydoc = MyDoc()
        mydoc['foo'].update({"bir":[1,2,3]})
        mydoc['foo']['bar']['spam'] = {1:['bla', 'ble'], 3:['foo', 'bar']}
        mydoc.validate()
        mydoc['bla']['blo']['bli'] = [{"bar":["bla"]}]
        self.assertRaises(SchemaTypeError, mydoc.validate)
        mydoc['bla']['blo']['bli'] = [{"arf":[1]}]
        self.assertRaises(SchemaTypeError, mydoc.validate)


    def test_adding_custom_type(self):
        class MyDoc(SchemaDocument):
            structure = {
                "foo":str,
            }
            authorized_types = SchemaDocument.authorized_types + [str]
        mydoc = MyDoc()

    def test_schema_operator(self):
        from mongokit.operators import SchemaOperator
        class OP(SchemaOperator):
            repr = "op"
        op = OP()
        self.assertRaises(NotImplementedError, op.validate, "bla")


    def test_or_operator(self):
        from mongokit import OR
        assert repr(OR(int, str)) == "<int or str>"

        failed = False
        try:
            class BadMyDoc(SchemaDocument):
                structure = {"bla":OR(int, tuple)}
        except StructureError as e:
            self.assertEqual(str(e), "BadMyDoc: <%s 'tuple'> in <int or tuple> is not an authorized type (type found)" % ('type' if six.PY2 else 'class'))
            failed = True
        self.assertEqual(failed, True)

        from datetime import datetime
        class MyDoc(SchemaDocument):
            structure = {
                "foo":OR(str,int),
                "bar":OR(str, datetime)
            }

        mydoc = MyDoc()
        assert str(mydoc.structure['foo']) == '<%s or int>' % str.__name__
        assert str(mydoc.structure['bar']) == '<%s or datetime>' % str.__name__
        assert mydoc == {'foo': None, 'bar': None}
        mydoc['foo'] = 3.0
        self.assertRaises(SchemaTypeError, mydoc.validate)
        mydoc['foo'] = "foo"
        mydoc.validate()
        mydoc['foo'] = 3
        mydoc.validate()
        mydoc['foo'] = six.b('bar')
        self.assertRaises(SchemaTypeError, mydoc.validate)

        mydoc['foo'] = datetime.now()
        self.assertRaises(SchemaTypeError, mydoc.validate)
        mydoc['foo'] = "foo"
        mydoc['bar'] = datetime.now()
        mydoc.validate()
        mydoc['bar'] = "today"
        mydoc.validate()
        mydoc['bar'] = 25
        self.assertRaises(SchemaTypeError, mydoc.validate)

    def test_not_operator(self):
        from mongokit import NOT
        failed = False
        try:
            class BadMyDoc(SchemaDocument):
                structure = {"bla":NOT(int, tuple)}
        except StructureError as e:
            self.assertEqual(str(e), "BadMyDoc: <%s 'tuple'> in <not int, not tuple> is not an authorized type (type found)" % ('type' if six.PY2 else 'class'))
            failed = True
        self.assertEqual(failed, True)

        from datetime import datetime
        class MyDoc(SchemaDocument):
            structure = {
                "foo":NOT(str,int),
                "bar":NOT(datetime)
            }

        mydoc = MyDoc()
        assert str(mydoc.structure['foo']) == '<not %s, not int>' % str.__name__, str(mydoc.structure['foo'])
        assert str(mydoc.structure['bar']) == '<not datetime>'
        assert mydoc == {'foo': None, 'bar': None}
        assert mydoc['foo'] is None
        assert mydoc['bar'] is None
        mydoc['foo'] = 3
        self.assertRaises(SchemaTypeError, mydoc.validate)
        mydoc['foo'] = "foo"
        self.assertRaises(SchemaTypeError, mydoc.validate)
        mydoc['foo'] = 3.0
        mydoc.validate()
        mydoc['foo'] = datetime.now()
        mydoc.validate()

        mydoc['bar'] = datetime.now()
        self.assertRaises(SchemaTypeError, mydoc.validate)
        mydoc['bar'] = "today"
        mydoc.validate()
        mydoc['bar'] = 25
        mydoc.validate()

    def test_is_operator(self):
        from mongokit import IS
        failed = False
        try:
            class BadMyDoc(SchemaDocument):
                structure = {"bla":IS(('bla',),3)}
        except StructureError as e:
            self.assertEqual(str(e), "BadMyDoc: ('bla',) in <is ('bla',) or is 3> is not an authorized type (tuple found)")
            failed = True
        self.assertEqual(failed, True)

        from datetime import datetime
        class MyDoc(SchemaDocument):
            structure = {
                "foo":IS('spam','eggs'),
                "bar":IS('3', 3)
            }

        mydoc = MyDoc()
        assert str(mydoc.structure['foo']) == "<is 'spam' or is 'eggs'>"
        assert str(mydoc.structure['bar']) == "<is '3' or is 3>"
        assert mydoc == {'foo': None, 'bar': None}
        assert mydoc['foo'] is None
        assert mydoc['bar'] is None
        mydoc['foo'] = 3
        self.assertRaises(SchemaTypeError, mydoc.validate)
        mydoc['foo'] = "bla"
        self.assertRaises(SchemaTypeError, mydoc.validate)
        mydoc['foo'] = datetime.now()
        self.assertRaises(SchemaTypeError, mydoc.validate)
        mydoc['foo'] = "spam"
        mydoc.validate()
        mydoc['foo'] = "eggs"
        mydoc.validate()

        mydoc['bar'] = datetime.now()
        self.assertRaises(SchemaTypeError, mydoc.validate)
        mydoc['bar'] = "today"
        self.assertRaises(SchemaTypeError, mydoc.validate)
        mydoc['bar'] = 'foo'
        self.assertRaises(SchemaTypeError, mydoc.validate)
        mydoc['bar'] = 3
        mydoc.validate()
        mydoc['bar'] = "3"
        mydoc.validate()

    def test_subclassed_type(self):
        """
        accept all subclass of supported type
        """
        class CustomFloat(float):
            def __init__(self, float):
                self = float + 2
        class MyDoc(SchemaDocument):
            structure = {
                "foo":float,
            }
        mydoc = MyDoc()
        mydoc['foo'] = CustomFloat(4)
        mydoc.validate()


    def test_set_type(self):
        from mongokit import Set
        class MyDoc(Document):
            structure = {
                "tags":Set(int),
            }

        self.connection.register([MyDoc])
        mydoc = self.col.MyDoc()
        mydoc['tags'] = set(["1","1","2","3","4"])
        self.assertRaises(ValueError, mydoc.validate)
        mydoc['tags'] = set([1,1,2,3,4])
        mydoc.save()

        doc = self.col.MyDoc.find_one()
        assert doc['tags'] == set([1,2,3,4]), doc['tags']

    def test_set_type2(self):
        class MyDoc(Document):
                structure = {
                        'title':str,
                        'category':Set(str)
                }
                required_fields=['title']
        self.connection.register([MyDoc])
        doc = self.col.MyDoc()
        print(doc) # {'category': set([]), 'title': None}
        assert isinstance(doc['category'], set)
        try:
                doc.validate()
        except RequireFieldError as e:
                print(e) # title is required

        print(doc) # {'category': [], 'title': None}
        assert isinstance(doc['category'], set)
        doc['title']='hello'
        doc.validate()

    def test_int_type(self):
        @self.connection.register
        class MyDoc(Document):
            structure = {
                "foo":int,
            }

        mydoc = self.col.MyDoc()
        mydoc['foo'] = ''
        self.assertRaises(SchemaTypeError, mydoc.validate)
        mydoc['foo'] = 10
        mydoc.save()

    def test_uuid_type(self):
        import uuid
        @self.connection.register
        class MyDoc(Document):
            structure = {
                'uuid': uuid.UUID,
            }
        uid = uuid.uuid4()
        obj = self.col.MyDoc()
        obj['uuid'] = uid
        obj.save()

        assert isinstance(self.col.MyDoc.find_one()['uuid'], uuid.UUID)

    def test_binary_with_bytes_type(self):
        import bson
        @self.connection.register
        class MyDoc(Document):
            structure = {
                'my_binary': bytes,
            }
        obj = self.col.MyDoc()
        # non-utf8 string
        non_utf8 = b"\xFF\xFE\xFF";
        obj['my_binary'] = non_utf8
        obj.save()

        self.assertEquals(self.col.MyDoc.find_one()['my_binary'], non_utf8)

    def test_binary_with_binary_type(self):
        import bson
        @self.connection.register
        class MyDoc(Document):
            structure = {
                'my_binary': bson.binary.Binary,
            }
        obj = self.col.MyDoc()
        # non-utf8 string
        non_utf8 = b"\xFF\xFE\xFF";
        bin_obj = bson.binary.Binary(non_utf8)
        obj['my_binary'] = bin_obj
        obj.save()

        self.assertEquals(self.col.MyDoc.find_one()['my_binary'], non_utf8)
Example #14
0
class Database(object):
    """The database connection"""
    @staticmethod
    def get_db():
        """Return the database based on DATABASE_URI env var
        :rtype: Database
        """
        if 'DATABASE_URI' in os.environ:
            uri = os.environ['DATABASE_URI']
            return Database(uri=uri)
        raise EnvironmentError('DATABASE_URI environment variable is missing')

    def __init__(self, uri):
        """Init the Database using given uri
        :param uri: The URI to connect to, such as
                    mongodb://LOGIN:PASSWORD@SERVER:PORT/DB_NAME
        """
        self.uri = uri
        self.connect(uri)
        self.dbname = uri.split('/')[-1]
        logging.info('dbname is %s', self.dbname)

    def connect(self, uri):
        """Connect to given uri
        :param uri: The URI to connect to, such as
                    mongodb://LOGIN:PASSWORD@SERVER:PORT/DB_NAME
        """
        logging.info('Connecting to uri %s', uri)
        self.connection = Connection(host=uri)
        self.connection.register([User, Play])
        return self.connection

    # pylint: disable=C0103
    @property
    def db(self):
        """Return the pymongo's db object using the database name"""
        return self.connection[self.dbname]

    def add_user(self, login, name, passwd, email):
        """Add a user
        :param login: The user login
        :param name: The user complete name
        :param passwd: The user password, will be hashed
        :param email: The user email"""
        # must not already exist
        if self.get_user(login=login):
            msg = 'A user with login "%s" has already been declared' % login
            raise ValueError(msg)
        user = self.db.User()
        user['login'] = login
        user['name'] = name
        user['email'] = email
        user['passwd'] = hash_password(passwd)
        user.save()

    def delete_user(self, login):
        """Delete the user with the given login"""
        user = self.get_user(login=login)
        if user:
            user.delete()

    def drop(self):
        """Drop the database"""
        self.connection.drop_database(self.dbname)

    # pylint: disable=R0201
    def authenticate_user(self, user, passwd):
        """Authenticate the user
        """
        hashed_passwd = hash_password(passwd)
        user.authauthenticate(hashed_passwd)

    def get_user(self, login):
        """Retrieve the user with given login or None"""
        return self.db.User.one({'login': login})

    def add_play(self, date, game, creator):
        """Add a play
        :type date: datetime.datetime
        :type game: basestring
        :rtype: Play"""
        play = self.db.Play()
        play.set_date(date)
        play.set_game(game)
        play.set_created_by(creator)
        play.save()
        return play

    def add_play_from_json(self, json_play):
        """Adds a play from a json definition
        :type json_play: dict|basestring
        :rtype: Play"""
        # TODO: improve typecheck
        if type(json_play) == dict:
            json_play = json.dumps(json_play)
        play = self.db.Play.from_json(json_play)
        play.save()
        return play

    def get_plays(self):
        """Return all plays"""
        return [play for play in self.db.Play.find()]

    def migrate_all(self):
        """Runs the migration rules in bulk"""
        migration_play = PlayMigration(Play)
        migration_play.migrate_all(self.db.plays)  # pylint: disable=E1101

    def dump(self, dump_folder=None):
        """Dump the database in the given dump_file
            Use the archive option to compress
            if uri is None, will use DATABASE_URI env var
            if dump_folder is None, will use a timetagged folder"""
        logging.info('mongodumping')
        info = Database.get_uri_info(uri=self.uri)

        if dump_folder is None:
            timetag = datetime.datetime.now().strftime('%y%m%d_%H%M%S')
            dump_foldername = '{}_{}'.format(timetag, info['db_name'])
            dump_folder = os.path.join('dump', dump_foldername)
        info['dump_folder'] = dump_folder
        info['temp_folder'] = tempfile.mkdtemp()
        logging.info('mongodump on %s', info)
        cmd = '' \
            'mongodump -h {host} --port {port} -u {user} -p {password}' \
            ' --db {db_name} --out={temp_folder}'.format(**info)
        logging.info(cmd)
        if dump_folder != '' and not os.path.exists(dump_folder):
            os.makedirs(dump_folder)
        rcode = subprocess.call(cmd.split(' '))
        if rcode == 0:
            logging.info('dumped to %s', dump_folder)
            os.rename(os.path.join(info['temp_folder'], info['db_name']),
                      dump_folder)
        else:
            logging.fatal('Failed to dump! - return code is %s', rcode)

    def restore(self, dump_folder, delete=False):
        """Restore a dump saved using mongodump in the given database"""
        logging.info('mongorestoring')
        if not os.path.exists(dump_folder):
            raise RuntimeError('dump folder does not exist %s' % dump_folder)
        info = Database.get_uri_info(uri=self.uri)
        info['dump_folder'] = dump_folder
        logging.info('mongorestore on %s', info)

        if delete:
            self.drop()

        cmd = '' \
            'mongorestore -h {host} --port {port} -u {user} -p {password}' \
            ' --db {db_name} {dump_folder}'.format(**info)
        logging.info(cmd)
        rcode = subprocess.call(cmd.split(' '))
        if rcode == 0:
            logging.info('restored from %s', dump_folder)
        else:
            logging.fatal('Failed to restore! - return code is %s', rcode)

    @staticmethod
    def get_uri_info(uri):
        """Return configured UriInfo (host, port, username, password, dbname)
        based on the configured DATABASE_URI env var
        :rtype: tuple
        """
        if uri is None and 'DATABASE_URI' not in os.environ:
            msg = 'Must give uri or have os.environ[\'DATABASE_URI\']'
            raise RuntimeError(msg)
        elif uri is None:
            uri = os.environ['DATABASE_URI']

        return Database.parse_uri(uri)

    @staticmethod
    def parse_uri(uri):
        """Return the elements of the uri:
        (host, port, username, password, dbname)
        """
        match = re.match((r'mongodb://(?P<user>[^:]+):(?P<password>[^@]+)'
                          r'@(?P<host>[^:]+):(?P<port>\d+)/(?P<db_name>\w+)'),
                         uri)
        if match:
            return {
                'host': match.group('host'),
                'port': match.group('port'),
                'user': match.group('user'),
                'password': match.group('password'),
                'db_name': match.group('db_name')
            }
        raise RuntimeError('Failed to parse uri: {}'.format(uri))