00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 """Test the database module."""
00016
00017 import datetime
00018 import random
00019 import sys
00020 sys.path[0:0] = [""]
00021 import unittest
00022
00023 from bson.code import Code
00024 from bson.dbref import DBRef
00025 from bson.objectid import ObjectId
00026 from bson.son import SON
00027 from pymongo import (ALL,
00028 ASCENDING,
00029 DESCENDING,
00030 helpers,
00031 OFF,
00032 SLOW_ONLY)
00033 from pymongo.collection import Collection
00034 from pymongo.connection import Connection
00035 from pymongo.database import Database
00036 from pymongo.errors import (CollectionInvalid,
00037 InvalidName,
00038 InvalidOperation,
00039 OperationFailure)
00040 from pymongo.son_manipulator import (AutoReference,
00041 NamespaceInjector)
00042 from test import version
00043 from test.test_connection import get_connection
00044
00045
00046 class TestDatabase(unittest.TestCase):
00047
00048 def setUp(self):
00049 self.connection = get_connection()
00050
00051 def test_name(self):
00052 self.assertRaises(TypeError, Database, self.connection, 4)
00053 self.assertRaises(InvalidName, Database, self.connection, "my db")
00054 self.assertEqual("name", Database(self.connection, "name").name)
00055
00056 def test_cmp(self):
00057 self.assertNotEqual(Database(self.connection, "test"),
00058 Database(self.connection, "mike"))
00059 self.assertEqual(Database(self.connection, "test"),
00060 Database(self.connection, "test"))
00061
00062 def test_repr(self):
00063 self.assertEqual(repr(Database(self.connection, "pymongo_test")),
00064 "Database(%r, u'pymongo_test')" % self.connection)
00065
00066 def test_get_coll(self):
00067 db = Database(self.connection, "pymongo_test")
00068 self.assertEqual(db.test, db["test"])
00069 self.assertEqual(db.test, Collection(db, "test"))
00070 self.assertNotEqual(db.test, Collection(db, "mike"))
00071 self.assertEqual(db.test.mike, db["test.mike"])
00072
00073 def test_create_collection(self):
00074 db = Database(self.connection, "pymongo_test")
00075
00076 db.test.insert({"hello": "world"})
00077 self.assertRaises(CollectionInvalid, db.create_collection, "test")
00078
00079 db.drop_collection("test")
00080
00081 self.assertRaises(TypeError, db.create_collection, 5)
00082 self.assertRaises(TypeError, db.create_collection, None)
00083 self.assertRaises(InvalidName, db.create_collection, "coll..ection")
00084
00085 test = db.create_collection("test")
00086 test.save({"hello": u"world"})
00087 self.assertEqual(db.test.find_one()["hello"], "world")
00088 self.assert_(u"test" in db.collection_names())
00089
00090 db.drop_collection("test.foo")
00091 db.create_collection("test.foo")
00092 self.assert_(u"test.foo" in db.collection_names())
00093 self.assertEqual(db.test.foo.options(), {})
00094 self.assertRaises(CollectionInvalid, db.create_collection, "test.foo")
00095
00096 def test_collection_names(self):
00097 db = Database(self.connection, "pymongo_test")
00098 db.test.save({"dummy": u"object"})
00099 db.test.mike.save({"dummy": u"object"})
00100
00101 colls = db.collection_names()
00102 self.assert_("test" in colls)
00103 self.assert_("test.mike" in colls)
00104 for coll in colls:
00105 self.assert_("$" not in coll)
00106
00107 def test_drop_collection(self):
00108 db = Database(self.connection, "pymongo_test")
00109
00110 self.assertRaises(TypeError, db.drop_collection, 5)
00111 self.assertRaises(TypeError, db.drop_collection, None)
00112
00113 db.test.save({"dummy": u"object"})
00114 self.assert_("test" in db.collection_names())
00115 db.drop_collection("test")
00116 self.assertFalse("test" in db.collection_names())
00117
00118 db.test.save({"dummy": u"object"})
00119 self.assert_("test" in db.collection_names())
00120 db.drop_collection(u"test")
00121 self.assertFalse("test" in db.collection_names())
00122
00123 db.test.save({"dummy": u"object"})
00124 self.assert_("test" in db.collection_names())
00125 db.drop_collection(db.test)
00126 self.assertFalse("test" in db.collection_names())
00127
00128 db.test.save({"dummy": u"object"})
00129 self.assert_("test" in db.collection_names())
00130 db.test.drop()
00131 self.assertFalse("test" in db.collection_names())
00132 db.test.drop()
00133
00134 db.drop_collection(db.test.doesnotexist)
00135
00136 def test_validate_collection(self):
00137 db = self.connection.pymongo_test
00138
00139 self.assertRaises(TypeError, db.validate_collection, 5)
00140 self.assertRaises(TypeError, db.validate_collection, None)
00141
00142 db.test.save({"dummy": u"object"})
00143
00144 self.assertRaises(OperationFailure, db.validate_collection,
00145 "test.doesnotexist")
00146 self.assertRaises(OperationFailure, db.validate_collection,
00147 db.test.doesnotexist)
00148
00149 self.assert_(db.validate_collection("test"))
00150 self.assert_(db.validate_collection(db.test))
00151
00152 def test_profiling_levels(self):
00153 db = self.connection.pymongo_test
00154 self.assertEqual(db.profiling_level(), OFF)
00155
00156 self.assertRaises(ValueError, db.set_profiling_level, 5.5)
00157 self.assertRaises(ValueError, db.set_profiling_level, None)
00158 self.assertRaises(ValueError, db.set_profiling_level, -1)
00159
00160 db.set_profiling_level(SLOW_ONLY)
00161 self.assertEqual(db.profiling_level(), SLOW_ONLY)
00162
00163 db.set_profiling_level(ALL)
00164 self.assertEqual(db.profiling_level(), ALL)
00165
00166 db.set_profiling_level(OFF)
00167 self.assertEqual(db.profiling_level(), OFF)
00168
00169 def test_profiling_info(self):
00170 db = self.connection.pymongo_test
00171
00172 db.set_profiling_level(ALL)
00173 db.test.find()
00174 db.set_profiling_level(OFF)
00175
00176 info = db.profiling_info()
00177 self.assert_(isinstance(info, list))
00178 self.assert_(len(info) >= 1)
00179 self.assert_(isinstance(info[0]["info"], basestring))
00180 self.assert_(isinstance(info[0]["ts"], datetime.datetime))
00181 self.assert_(isinstance(info[0]["millis"], float))
00182
00183 def test_iteration(self):
00184 db = self.connection.pymongo_test
00185
00186 def iterate():
00187 [a for a in db]
00188
00189 self.assertRaises(TypeError, iterate)
00190
00191 def test_errors(self):
00192 db = self.connection.pymongo_test
00193
00194 db.reset_error_history()
00195 self.assertEqual(None, db.error())
00196 self.assertEqual(None, db.previous_error())
00197
00198 db.command("forceerror", check=False)
00199 self.assert_(db.error())
00200 self.assert_(db.previous_error())
00201
00202 db.command("forceerror", check=False)
00203 self.assert_(db.error())
00204 prev_error = db.previous_error()
00205 self.assertEqual(prev_error["nPrev"], 1)
00206 del prev_error["nPrev"]
00207 prev_error.pop("lastOp", None)
00208 error = db.error()
00209 error.pop("lastOp", None)
00210
00211
00212 error.pop("connectionId", None)
00213 self.assertEqual(error, prev_error)
00214
00215 db.test.find_one()
00216 self.assertEqual(None, db.error())
00217 self.assert_(db.previous_error())
00218 self.assertEqual(db.previous_error()["nPrev"], 2)
00219
00220 db.reset_error_history()
00221 self.assertEqual(None, db.error())
00222 self.assertEqual(None, db.previous_error())
00223
00224 def test_command(self):
00225 db = self.connection.admin
00226
00227 self.assertEqual(db.command("buildinfo"), db.command({"buildinfo": 1}))
00228
00229 def test_last_status(self):
00230 db = self.connection.pymongo_test
00231
00232 db.test.remove({})
00233 db.test.save({"i": 1})
00234
00235 db.test.update({"i": 1}, {"$set": {"i": 2}})
00236 self.assert_(db.last_status()["updatedExisting"])
00237
00238 db.test.update({"i": 1}, {"$set": {"i": 500}})
00239 self.assertFalse(db.last_status()["updatedExisting"])
00240
00241 def test_password_digest(self):
00242 self.assertRaises(TypeError, helpers._password_digest, 5)
00243 self.assertRaises(TypeError, helpers._password_digest, True)
00244 self.assertRaises(TypeError, helpers._password_digest, None)
00245
00246 self.assert_(isinstance(helpers._password_digest("mike", "password"),
00247 unicode))
00248 self.assertEqual(helpers._password_digest("mike", "password"),
00249 u"cd7e45b3b2767dc2fa9b6b548457ed00")
00250 self.assertEqual(helpers._password_digest("mike", "password"),
00251 helpers._password_digest(u"mike", u"password"))
00252 self.assertEqual(helpers._password_digest("Gustave", u"Dor\xe9"),
00253 u"81e0e2364499209f466e75926a162d73")
00254
00255 def test_authenticate_add_remove_user(self):
00256 db = self.connection.pymongo_test
00257 db.system.users.remove({})
00258 db.remove_user("mike")
00259 db.add_user("mike", "password")
00260
00261 self.assertRaises(TypeError, db.authenticate, 5, "password")
00262 self.assertRaises(TypeError, db.authenticate, "mike", 5)
00263
00264 self.assertFalse(db.authenticate("mike", "not a real password"))
00265 self.assertFalse(db.authenticate("faker", "password"))
00266 self.assert_(db.authenticate("mike", "password"))
00267 self.assert_(db.authenticate(u"mike", u"password"))
00268
00269 db.remove_user("mike")
00270 self.assertFalse(db.authenticate("mike", "password"))
00271
00272 self.assertFalse(db.authenticate("Gustave", u"Dor\xe9"))
00273 db.add_user("Gustave", u"Dor\xe9")
00274 self.assert_(db.authenticate("Gustave", u"Dor\xe9"))
00275
00276 db.add_user("Gustave", "password")
00277 self.assertFalse(db.authenticate("Gustave", u"Dor\xe9"))
00278 self.assert_(db.authenticate("Gustave", u"password"))
00279
00280
00281 db.logout()
00282 db.logout()
00283
00284 def test_id_ordering(self):
00285 db = self.connection.pymongo_test
00286 db.test.remove({})
00287
00288 db.test.insert({"hello": "world", "_id": 5})
00289 db.test.insert(SON([("hello", "world"),
00290 ("_id", 5)]))
00291 for x in db.test.find():
00292 for (k, v) in x.items():
00293 self.assertEqual(k, "_id")
00294 break
00295
00296 def test_deref(self):
00297 db = self.connection.pymongo_test
00298 db.test.remove({})
00299
00300 self.assertRaises(TypeError, db.dereference, 5)
00301 self.assertRaises(TypeError, db.dereference, "hello")
00302 self.assertRaises(TypeError, db.dereference, None)
00303
00304 self.assertEqual(None, db.dereference(DBRef("test", ObjectId())))
00305 obj = {"x": True}
00306 key = db.test.save(obj)
00307 self.assertEqual(obj, db.dereference(DBRef("test", key)))
00308 self.assertEqual(obj, db.dereference(DBRef("test", key, "pymongo_test")))
00309 self.assertRaises(ValueError, db.dereference, DBRef("test", key, "foo"))
00310
00311 self.assertEqual(None, db.dereference(DBRef("test", 4)))
00312 obj = {"_id": 4}
00313 db.test.save(obj)
00314 self.assertEqual(obj, db.dereference(DBRef("test", 4)))
00315
00316 def test_eval(self):
00317 db = self.connection.pymongo_test
00318 db.test.remove({})
00319
00320 self.assertRaises(TypeError, db.eval, None)
00321 self.assertRaises(TypeError, db.eval, 5)
00322 self.assertRaises(TypeError, db.eval, [])
00323
00324 self.assertEqual(3, db.eval("function (x) {return x;}", 3))
00325 self.assertEqual(3, db.eval(u"function (x) {return x;}", 3))
00326
00327 self.assertEqual(None,
00328 db.eval("function (x) {db.test.save({y:x});}", 5))
00329 self.assertEqual(db.test.find_one()["y"], 5)
00330
00331 self.assertEqual(5, db.eval("function (x, y) {return x + y;}", 2, 3))
00332 self.assertEqual(5, db.eval("function () {return 5;}"))
00333 self.assertEqual(5, db.eval("2 + 3;"))
00334
00335 self.assertEqual(5, db.eval(Code("2 + 3;")))
00336 self.assertRaises(OperationFailure, db.eval, Code("return i;"))
00337 self.assertEqual(2, db.eval(Code("return i;", {"i": 2})))
00338 self.assertEqual(5, db.eval(Code("i + 3;", {"i": 2})))
00339
00340 self.assertRaises(OperationFailure, db.eval, "5 ++ 5;")
00341
00342
00343 def test_save_find_one(self):
00344 db = Database(self.connection, "pymongo_test")
00345 db.test.remove({})
00346
00347 a_doc = SON({"hello": u"world"})
00348 a_key = db.test.save(a_doc)
00349 self.assert_(isinstance(a_doc["_id"], ObjectId))
00350 self.assertEqual(a_doc["_id"], a_key)
00351 self.assertEqual(a_doc, db.test.find_one({"_id": a_doc["_id"]}))
00352 self.assertEqual(a_doc, db.test.find_one(a_key))
00353 self.assertEqual(None, db.test.find_one(ObjectId()))
00354 self.assertEqual(a_doc, db.test.find_one({"hello": u"world"}))
00355 self.assertEqual(None, db.test.find_one({"hello": u"test"}))
00356
00357 b = db.test.find_one()
00358 b["hello"] = u"mike"
00359 db.test.save(b)
00360
00361 self.assertNotEqual(a_doc, db.test.find_one(a_key))
00362 self.assertEqual(b, db.test.find_one(a_key))
00363 self.assertEqual(b, db.test.find_one())
00364
00365 count = 0
00366 for _ in db.test.find():
00367 count += 1
00368 self.assertEqual(count, 1)
00369
00370 def test_long(self):
00371 db = self.connection.pymongo_test
00372 db.test.remove({})
00373 db.test.save({"x": 9223372036854775807L})
00374 self.assertEqual(9223372036854775807L, db.test.find_one()["x"])
00375
00376 def test_remove(self):
00377 db = self.connection.pymongo_test
00378 db.test.remove({})
00379
00380 one = db.test.save({"x": 1})
00381 db.test.save({"x": 2})
00382 db.test.save({"x": 3})
00383 length = 0
00384 for _ in db.test.find():
00385 length += 1
00386 self.assertEqual(length, 3)
00387
00388 db.test.remove(one)
00389 length = 0
00390 for _ in db.test.find():
00391 length += 1
00392 self.assertEqual(length, 2)
00393
00394 db.test.remove(db.test.find_one())
00395 db.test.remove(db.test.find_one())
00396 self.assertEqual(db.test.find_one(), None)
00397
00398 one = db.test.save({"x": 1})
00399 db.test.save({"x": 2})
00400 db.test.save({"x": 3})
00401
00402 self.assert_(db.test.find_one({"x": 2}))
00403 db.test.remove({"x": 2})
00404 self.assertFalse(db.test.find_one({"x": 2}))
00405
00406 self.assert_(db.test.find_one())
00407 db.test.remove({})
00408 self.assertFalse(db.test.find_one())
00409
00410 def test_save_a_bunch(self):
00411 db = self.connection.pymongo_test
00412 db.test.remove({})
00413
00414 for i in xrange(1000):
00415 db.test.save({"x": i})
00416
00417 count = 0
00418 for _ in db.test.find():
00419 count += 1
00420
00421 self.assertEqual(1000, count)
00422
00423
00424 for _ in xrange(62):
00425 for _ in db.test.find():
00426 break
00427
00428 def test_auto_ref_and_deref(self):
00429 db = self.connection.pymongo_test
00430 db.add_son_manipulator(AutoReference(db))
00431 db.add_son_manipulator(NamespaceInjector())
00432
00433 db.test.a.remove({})
00434 db.test.b.remove({})
00435 db.test.c.remove({})
00436
00437 a = {"hello": u"world"}
00438 db.test.a.save(a)
00439
00440 b = {"test": a}
00441 db.test.b.save(b)
00442
00443 c = {"another test": b}
00444 db.test.c.save(c)
00445
00446 a["hello"] = "mike"
00447 db.test.a.save(a)
00448
00449 self.assertEqual(db.test.a.find_one(), a)
00450 self.assertEqual(db.test.b.find_one()["test"], a)
00451 self.assertEqual(db.test.c.find_one()["another test"]["test"], a)
00452 self.assertEqual(db.test.b.find_one(), b)
00453 self.assertEqual(db.test.c.find_one()["another test"], b)
00454 self.assertEqual(db.test.c.find_one(), c)
00455
00456
00457 def test_marc(self):
00458 db = self.connection.pymongo_test
00459 db.add_son_manipulator(AutoReference(db))
00460 db.add_son_manipulator(NamespaceInjector())
00461
00462 db.drop_collection("users")
00463 db.drop_collection("messages")
00464
00465 message_1 = {"title": "foo"}
00466 db.messages.save(message_1)
00467 message_2 = {"title": "bar"}
00468 db.messages.save(message_2)
00469
00470 user = {"name": "marc",
00471 "messages": [message_1, message_2]}
00472 db.users.save(user)
00473
00474 message = db.messages.find_one()
00475 db.messages.update(message, {"title": "buzz"})
00476
00477 self.assertEqual("buzz", db.users.find_one()["messages"][0]["title"])
00478 self.assertEqual("bar", db.users.find_one()["messages"][1]["title"])
00479
00480 def test_system_js(self):
00481 db = self.connection.pymongo_test
00482 db.system.js.remove()
00483
00484 self.assertEqual(0, db.system.js.count())
00485 db.system_js.add = "function(a, b) { return a + b; }"
00486 self.assertEqual(1, db.system.js.count())
00487 self.assertEqual(6, db.system_js.add(1, 5))
00488
00489 del db.system_js.add
00490 self.assertEqual(0, db.system.js.count())
00491 if version.at_least(db.connection, (1, 3, 2, -1)):
00492 self.assertRaises(OperationFailure, db.system_js.add, 1, 5)
00493
00494
00495
00496
00497
00498 self.assertRaises(OperationFailure, db.system_js.non_existant)
00499
00500 db.system_js.no_param = Code("return 5;")
00501 self.assertEqual(5, db.system_js.no_param())
00502
00503 def test_system_js_list(self):
00504 db = self.connection.pymongo_test
00505 db.system.js.remove()
00506 self.assertEqual([], db.system_js.list())
00507
00508 db.system_js.foo = "blah"
00509 self.assertEqual(["foo"], db.system_js.list())
00510
00511 db.system_js.bar = "baz"
00512 self.assertEqual(set(["foo", "bar"]), set(db.system_js.list()))
00513
00514 del db.system_js.foo
00515 self.assertEqual(["bar"], db.system_js.list())
00516
00517
00518 if __name__ == "__main__":
00519 unittest.main()