00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 """Test the collection module."""
00018
00019 import itertools
00020 import re
00021 import sys
00022 import time
00023 import unittest
00024 import warnings
00025
00026 from nose.plugins.skip import SkipTest
00027
00028 sys.path[0:0] = [""]
00029
00030 from bson.binary import Binary
00031 from bson.code import Code
00032 from bson.objectid import ObjectId
00033 from bson.son import SON
00034 from pymongo import ASCENDING, DESCENDING
00035 from pymongo.collection import Collection
00036 from pymongo.errors import (DuplicateKeyError,
00037 InvalidDocument,
00038 InvalidName,
00039 InvalidOperation,
00040 OperationFailure,
00041 TimeoutError)
00042 from test.test_connection import get_connection
00043 from test import (qcheck,
00044 version)
00045
00046
00047 class TestCollection(unittest.TestCase):
00048
00049 def setUp(self):
00050 self.connection = get_connection()
00051 self.db = self.connection.pymongo_test
00052
00053 def test_collection(self):
00054 self.assertRaises(TypeError, Collection, self.db, 5)
00055
00056 def make_col(base, name):
00057 return base[name]
00058
00059 self.assertRaises(InvalidName, make_col, self.db, "")
00060 self.assertRaises(InvalidName, make_col, self.db, "te$t")
00061 self.assertRaises(InvalidName, make_col, self.db, ".test")
00062 self.assertRaises(InvalidName, make_col, self.db, "test.")
00063 self.assertRaises(InvalidName, make_col, self.db, "tes..t")
00064 self.assertRaises(InvalidName, make_col, self.db.test, "")
00065 self.assertRaises(InvalidName, make_col, self.db.test, "te$t")
00066 self.assertRaises(InvalidName, make_col, self.db.test, ".test")
00067 self.assertRaises(InvalidName, make_col, self.db.test, "test.")
00068 self.assertRaises(InvalidName, make_col, self.db.test, "tes..t")
00069 self.assertRaises(InvalidName, make_col, self.db.test, "tes\x00t")
00070
00071 self.assert_(isinstance(self.db.test, Collection))
00072 self.assertEqual(self.db.test, self.db["test"])
00073 self.assertEqual(self.db.test, Collection(self.db, "test"))
00074 self.assertEqual(self.db.test.mike, self.db["test.mike"])
00075 self.assertEqual(self.db.test["mike"], self.db["test.mike"])
00076
00077 def test_create_index(self):
00078 db = self.db
00079
00080 self.assertRaises(TypeError, db.test.create_index, 5)
00081 self.assertRaises(TypeError, db.test.create_index, {"hello": 1})
00082 self.assertRaises(ValueError, db.test.create_index, [])
00083
00084 db.test.drop_indexes()
00085 self.assertEqual(db.system.indexes.find({"ns": u"pymongo_test.test"})
00086 .count(), 1)
00087
00088 db.test.create_index("hello")
00089 db.test.create_index([("hello", DESCENDING), ("world", ASCENDING)])
00090
00091 count = 0
00092 for _ in db.system.indexes.find({"ns": u"pymongo_test.test"}):
00093 count += 1
00094 self.assertEqual(count, 3)
00095
00096 db.test.drop_indexes()
00097 ix = db.test.create_index([("hello", DESCENDING),
00098 ("world", ASCENDING)], name="hello_world")
00099 self.assertEquals(ix, "hello_world")
00100
00101 db.test.drop_indexes()
00102 self.assertEqual(db.system.indexes.find({"ns": u"pymongo_test.test"})
00103 .count(), 1)
00104 db.test.create_index("hello")
00105 self.assert_(u"hello_1" in
00106 [a["name"] for a in db.system.indexes
00107 .find({"ns": u"pymongo_test.test"})])
00108
00109 db.test.drop_indexes()
00110 self.assertEqual(db.system.indexes.find({"ns": u"pymongo_test.test"})
00111 .count(), 1)
00112 db.test.create_index([("hello", DESCENDING), ("world", ASCENDING)])
00113 self.assert_(u"hello_-1_world_1" in
00114 [a["name"] for a in db.system.indexes
00115 .find({"ns": u"pymongo_test.test"})])
00116
00117 db.test.drop()
00118 db.test.insert({'a':1})
00119 db.test.insert({'a':1})
00120 self.assertRaises(DuplicateKeyError, db.test.create_index,
00121 'a', unique=True)
00122
00123 def test_ensure_index(self):
00124 db = self.db
00125
00126 self.assertRaises(TypeError, db.test.ensure_index, {"hello": 1})
00127
00128 db.test.drop_indexes()
00129 self.assertEqual("hello_1", db.test.create_index("hello"))
00130 self.assertEqual("hello_1", db.test.create_index("hello"))
00131
00132 self.assertEqual("goodbye_1",
00133 db.test.ensure_index("goodbye"))
00134 self.assertEqual(None, db.test.ensure_index("goodbye"))
00135
00136 db.test.drop_indexes()
00137 self.assertEqual("foo",
00138 db.test.ensure_index("goodbye", name="foo"))
00139 self.assertEqual(None, db.test.ensure_index("goodbye", name="foo"))
00140
00141 db.test.drop_indexes()
00142 self.assertEqual("goodbye_1",
00143 db.test.ensure_index("goodbye"))
00144 self.assertEqual(None, db.test.ensure_index("goodbye"))
00145
00146 db.test.drop_index("goodbye_1")
00147 self.assertEqual("goodbye_1",
00148 db.test.ensure_index("goodbye"))
00149 self.assertEqual(None, db.test.ensure_index("goodbye"))
00150
00151 db.drop_collection("test")
00152 self.assertEqual("goodbye_1",
00153 db.test.ensure_index("goodbye"))
00154 self.assertEqual(None, db.test.ensure_index("goodbye"))
00155
00156 db.test.drop_index("goodbye_1")
00157 self.assertEqual("goodbye_1",
00158 db.test.create_index("goodbye"))
00159 self.assertEqual(None, db.test.ensure_index("goodbye"))
00160
00161 db.test.drop_index("goodbye_1")
00162 self.assertEqual("goodbye_1",
00163 db.test.ensure_index("goodbye", ttl=1))
00164 time.sleep(1.1)
00165 self.assertEqual("goodbye_1",
00166 db.test.ensure_index("goodbye"))
00167
00168 db.test.drop_index("goodbye_1")
00169 self.assertEqual("goodbye_1",
00170 db.test.create_index("goodbye", ttl=1))
00171 time.sleep(1.1)
00172 self.assertEqual("goodbye_1",
00173 db.test.ensure_index("goodbye"))
00174
00175 db.test.drop_indexes()
00176
00177 def test_index_on_binary(self):
00178 db = self.db
00179 db.drop_collection("test")
00180 db.test.save({"bin": Binary("def")})
00181 db.test.save({"bin": Binary("abc")})
00182 db.test.save({"bin": Binary("ghi")})
00183
00184 self.assertEqual(db.test.find({"bin": Binary("abc")})
00185 .explain()["nscanned"], 3)
00186
00187 db.test.create_index("bin")
00188 self.assertEqual(db.test.find({"bin": Binary("abc")})
00189 .explain()["nscanned"], 1)
00190
00191 def test_drop_index(self):
00192 db = self.db
00193 db.test.drop_indexes()
00194 db.test.create_index("hello")
00195 name = db.test.create_index("goodbye")
00196
00197 self.assertEqual(db.system.indexes.find({"ns": u"pymongo_test.test"})
00198 .count(), 3)
00199 self.assertEqual(name, "goodbye_1")
00200 db.test.drop_index(name)
00201 self.assertEqual(db.system.indexes.find({"ns": u"pymongo_test.test"})
00202 .count(), 2)
00203 self.assert_(u"hello_1" in
00204 [a["name"] for a in db.system.indexes
00205 .find({"ns": u"pymongo_test.test"})])
00206
00207 db.test.drop_indexes()
00208 db.test.create_index("hello")
00209 name = db.test.create_index("goodbye")
00210
00211 self.assertEqual(db.system.indexes.find({"ns": u"pymongo_test.test"})
00212 .count(), 3)
00213 self.assertEqual(name, "goodbye_1")
00214 db.test.drop_index([("goodbye", ASCENDING)])
00215 self.assertEqual(db.system.indexes.find({"ns": u"pymongo_test.test"})
00216 .count(), 2)
00217 self.assert_(u"hello_1" in
00218 [a["name"] for a in db.system.indexes
00219 .find({"ns": u"pymongo_test.test"})])
00220
00221 def test_index_info(self):
00222 db = self.db
00223 db.test.drop_indexes()
00224 db.test.remove({})
00225 db.test.save({})
00226 self.assertEqual(len(db.test.index_information()), 1)
00227 self.assert_("_id_" in db.test.index_information())
00228
00229 db.test.create_index("hello")
00230 self.assertEqual(len(db.test.index_information()), 2)
00231 self.assertEqual(db.test.index_information()["hello_1"]["key"],
00232 [("hello", ASCENDING)])
00233
00234 db.test.create_index([("hello", DESCENDING), ("world", ASCENDING)],
00235 unique=True)
00236 self.assertEqual(db.test.index_information()["hello_1"]["key"],
00237 [("hello", ASCENDING)])
00238 self.assertEqual(len(db.test.index_information()), 3)
00239 self.assertEqual([("hello", DESCENDING), ("world", ASCENDING)],
00240 db.test.index_information()["hello_-1_world_1"]["key"])
00241 self.assertEqual(True, db.test.index_information()["hello_-1_world_1"]["unique"])
00242
00243 def test_field_selection(self):
00244 db = self.db
00245 db.drop_collection("test")
00246
00247 doc = {"a": 1, "b": 5, "c": {"d": 5, "e": 10}}
00248 db.test.insert(doc)
00249
00250 self.assertEqual(db.test.find({}, ["_id"]).next().keys(), ["_id"])
00251 l = db.test.find({}, ["a"]).next().keys()
00252 l.sort()
00253 self.assertEqual(l, ["_id", "a"])
00254 l = db.test.find({}, ["b"]).next().keys()
00255 l.sort()
00256 self.assertEqual(l, ["_id", "b"])
00257 l = db.test.find({}, ["c"]).next().keys()
00258 l.sort()
00259 self.assertEqual(l, ["_id", "c"])
00260 self.assertEqual(db.test.find({}, ["a"]).next()["a"], 1)
00261 self.assertEqual(db.test.find({}, ["b"]).next()["b"], 5)
00262 self.assertEqual(db.test.find({}, ["c"]).next()["c"],
00263 {"d": 5, "e": 10})
00264
00265 self.assertEqual(db.test.find({}, ["c.d"]).next()["c"], {"d": 5})
00266 self.assertEqual(db.test.find({}, ["c.e"]).next()["c"], {"e": 10})
00267 self.assertEqual(db.test.find({}, ["b", "c.e"]).next()["c"],
00268 {"e": 10})
00269
00270 l = db.test.find({}, ["b", "c.e"]).next().keys()
00271 l.sort()
00272 self.assertEqual(l, ["_id", "b", "c"])
00273 self.assertEqual(db.test.find({}, ["b", "c.e"]).next()["b"], 5)
00274
00275 def test_options(self):
00276 db = self.db
00277 db.drop_collection("test")
00278 db.test.save({})
00279 self.assertEqual(db.test.options(), {})
00280 self.assertEqual(db.test.doesnotexist.options(), {})
00281
00282 db.drop_collection("test")
00283 db.create_collection("test", capped=True)
00284 self.assertEqual(db.test.options(), {"capped": True})
00285 db.drop_collection("test")
00286
00287 def test_insert_find_one(self):
00288 db = self.db
00289 db.test.remove({})
00290 self.assertEqual(db.test.find().count(), 0)
00291 doc = {"hello": u"world"}
00292 id = db.test.insert(doc)
00293 self.assertEqual(db.test.find().count(), 1)
00294 self.assertEqual(doc, db.test.find_one())
00295 self.assertEqual(doc["_id"], id)
00296 self.assert_(isinstance(id, ObjectId))
00297
00298 def remove_insert_find_one(dict):
00299 db.test.remove({})
00300 db.test.insert(dict)
00301 return db.test.find_one() == dict
00302
00303 qcheck.check_unittest(self, remove_insert_find_one,
00304 qcheck.gen_mongo_dict(3))
00305
00306 def test_remove_all(self):
00307 self.db.test.remove()
00308 self.assertEqual(0, self.db.test.count())
00309
00310 self.db.test.insert({"x": 1})
00311 self.db.test.insert({"y": 1})
00312 self.assertEqual(2, self.db.test.count())
00313
00314 self.db.test.remove()
00315 self.assertEqual(0, self.db.test.count())
00316
00317 def test_find_w_fields(self):
00318 db = self.db
00319 db.test.remove({})
00320
00321 db.test.insert({"x": 1, "mike": "awesome",
00322 "extra thing": "abcdefghijklmnopqrstuvwxyz"})
00323 self.assertEqual(1, db.test.count())
00324 self.assert_("x" in db.test.find({}).next())
00325 self.assert_("mike" in db.test.find({}).next())
00326 self.assert_("extra thing" in db.test.find({}).next())
00327 self.assert_("x" in db.test.find({}, ["x", "mike"]).next())
00328 self.assert_("mike" in db.test.find({}, ["x", "mike"]).next())
00329 self.assertFalse("extra thing" in db.test.find({}, ["x", "mike"]).next())
00330 self.assertFalse("x" in db.test.find({}, ["mike"]).next())
00331 self.assert_("mike" in db.test.find({}, ["mike"]).next())
00332 self.assertFalse("extra thing" in db.test.find({}, ["mike"]).next())
00333
00334 def test_fields_specifier_as_dict(self):
00335 db = self.db
00336 db.test.remove({})
00337
00338 db.test.insert({"x": [1, 2, 3], "mike": "awesome"})
00339
00340 self.assertEqual([1,2,3], db.test.find_one()["x"])
00341 if version.at_least(db.connection, (1, 5, 1)):
00342 self.assertEqual([2,3],
00343 db.test.find_one(fields={"x": {"$slice":
00344 -2}})["x"])
00345 self.assert_("x" not in db.test.find_one(fields={"x": 0}))
00346 self.assert_("mike" in db.test.find_one(fields={"x": 0}))
00347
00348 def test_find_w_regex(self):
00349 db = self.db
00350 db.test.remove({})
00351
00352 db.test.insert({"x": "hello_world"})
00353 db.test.insert({"x": "hello_mike"})
00354 db.test.insert({"x": "hello_mikey"})
00355 db.test.insert({"x": "hello_test"})
00356
00357 self.assertEqual(db.test.find().count(), 4)
00358 self.assertEqual(db.test.find({"x":
00359 re.compile("^hello.*")}).count(), 4)
00360 self.assertEqual(db.test.find({"x":
00361 re.compile("ello")}).count(), 4)
00362 self.assertEqual(db.test.find({"x":
00363 re.compile("^hello$")}).count(), 0)
00364 self.assertEqual(db.test.find({"x":
00365 re.compile("^hello_mi.*$")}).count(), 2)
00366
00367 def test_id_can_be_anything(self):
00368 db = self.db
00369
00370 db.test.remove({})
00371 auto_id = {"hello": "world"}
00372 db.test.insert(auto_id)
00373 self.assert_(isinstance(auto_id["_id"], ObjectId))
00374
00375 numeric = {"_id": 240, "hello": "world"}
00376 db.test.insert(numeric)
00377 self.assertEqual(numeric["_id"], 240)
00378
00379 object = {"_id": numeric, "hello": "world"}
00380 db.test.insert(object)
00381 self.assertEqual(object["_id"], numeric)
00382
00383 for x in db.test.find():
00384 self.assertEqual(x["hello"], u"world")
00385 self.assert_("_id" in x)
00386
00387 def test_iteration(self):
00388 db = self.db
00389
00390 def iterate():
00391 [a for a in db.test]
00392
00393 self.assertRaises(TypeError, iterate)
00394
00395 def test_invalid_key_names(self):
00396 db = self.db
00397 db.test.remove({})
00398
00399 db.test.insert({"hello": "world"})
00400 db.test.insert({"hello": {"hello": "world"}})
00401
00402 self.assertRaises(InvalidDocument, db.test.insert, {"$hello": "world"})
00403 self.assertRaises(InvalidDocument, db.test.insert,
00404 {"hello": {"$hello": "world"}})
00405
00406 db.test.insert({"he$llo": "world"})
00407 db.test.insert({"hello": {"hello$": "world"}})
00408
00409 self.assertRaises(InvalidDocument, db.test.insert,
00410 {".hello": "world"})
00411 self.assertRaises(InvalidDocument, db.test.insert,
00412 {"hello": {".hello": "world"}})
00413 self.assertRaises(InvalidDocument, db.test.insert,
00414 {"hello.": "world"})
00415 self.assertRaises(InvalidDocument, db.test.insert,
00416 {"hello": {"hello.": "world"}})
00417 self.assertRaises(InvalidDocument, db.test.insert,
00418 {"hel.lo": "world"})
00419 self.assertRaises(InvalidDocument, db.test.insert,
00420 {"hello": {"hel.lo": "world"}})
00421
00422 db.test.update({"hello": "world"}, {"$inc": "hello"})
00423
00424 def test_insert_multiple(self):
00425 db = self.db
00426 db.drop_collection("test")
00427 doc1 = {"hello": u"world"}
00428 doc2 = {"hello": u"mike"}
00429 self.assertEqual(db.test.find().count(), 0)
00430 ids = db.test.insert([doc1, doc2])
00431 self.assertEqual(db.test.find().count(), 2)
00432 self.assertEqual(doc1, db.test.find_one({"hello": u"world"}))
00433 self.assertEqual(doc2, db.test.find_one({"hello": u"mike"}))
00434
00435 self.assertEqual(2, len(ids))
00436 self.assertEqual(doc1["_id"], ids[0])
00437 self.assertEqual(doc2["_id"], ids[1])
00438
00439 id = db.test.insert([{"hello": 1}])
00440 self.assert_(isinstance(id, list))
00441 self.assertEqual(1, len(id))
00442
00443 self.assertRaises(InvalidOperation, db.test.insert, [])
00444
00445 def test_insert_iterables(self):
00446 db = self.db
00447
00448 self.assertRaises(TypeError, db.test.insert, 4)
00449 self.assertRaises(TypeError, db.test.insert, None)
00450 self.assertRaises(TypeError, db.test.insert, True)
00451
00452 db.drop_collection("test")
00453 self.assertEqual(db.test.find().count(), 0)
00454 ids = db.test.insert(({"hello": u"world"}, {"hello": u"world"}))
00455 self.assertEqual(db.test.find().count(), 2)
00456
00457 db.drop_collection("test")
00458 self.assertEqual(db.test.find().count(), 0)
00459 ids = db.test.insert(itertools.imap(lambda x: {"hello": "world"}, itertools.repeat(None, 10)))
00460 self.assertEqual(db.test.find().count(), 10)
00461
00462 def test_save(self):
00463 self.db.drop_collection("test")
00464 id = self.db.test.save({"hello": "world"})
00465 self.assertEqual(self.db.test.find_one()["_id"], id)
00466 self.assert_(isinstance(id, ObjectId))
00467
00468 def test_unique_index(self):
00469 db = self.db
00470
00471 db.drop_collection("test")
00472 db.test.create_index("hello")
00473
00474 db.test.save({"hello": "world"})
00475 db.test.save({"hello": "mike"})
00476 db.test.save({"hello": "world"})
00477 self.assertFalse(db.error())
00478
00479 db.drop_collection("test")
00480 db.test.create_index("hello", unique=True)
00481
00482 db.test.save({"hello": "world"})
00483 db.test.save({"hello": "mike"})
00484 db.test.save({"hello": "world"})
00485 self.assert_(db.error())
00486
00487 def test_duplicate_key_error(self):
00488 db = self.db
00489 db.drop_collection("test")
00490
00491 db.test.create_index("x", unique=True)
00492
00493 db.test.insert({"_id": 1, "x": 1}, safe=True)
00494 db.test.insert({"_id": 2, "x": 2}, safe=True)
00495
00496 expected_error = OperationFailure
00497 if version.at_least(db.connection, (1, 3)):
00498 expected_error = DuplicateKeyError
00499
00500 self.assertRaises(expected_error,
00501 db.test.insert, {"_id": 1}, safe=True)
00502 self.assertRaises(expected_error,
00503 db.test.insert, {"x": 1}, safe=True)
00504
00505 self.assertRaises(expected_error,
00506 db.test.save, {"x": 2}, safe=True)
00507 self.assertRaises(expected_error,
00508 db.test.update, {"x": 1}, {"$inc": {"x": 1}}, safe=True)
00509
00510 def test_error_code(self):
00511 try:
00512 self.db.test.update({}, {"$thismodifierdoesntexist": 1}, safe=True)
00513 self.fail()
00514 except OperationFailure, e:
00515 if version.at_least(self.db.connection, (1, 3)):
00516 self.assertEqual(10147, e.code)
00517
00518
00519 def test_index_on_subfield(self):
00520 db = self.db
00521 db.drop_collection("test")
00522
00523 db.test.insert({"hello": {"a": 4, "b": 5}})
00524 db.test.insert({"hello": {"a": 7, "b": 2}})
00525 db.test.insert({"hello": {"a": 4, "b": 10}})
00526 self.assertFalse(db.error())
00527
00528 db.drop_collection("test")
00529 db.test.create_index("hello.a", unique=True)
00530
00531 db.test.insert({"hello": {"a": 4, "b": 5}})
00532 db.test.insert({"hello": {"a": 7, "b": 2}})
00533 db.test.insert({"hello": {"a": 4, "b": 10}})
00534 self.assert_(db.error())
00535
00536 def test_safe_insert(self):
00537 db = self.db
00538 db.drop_collection("test")
00539
00540 a = {"hello": "world"}
00541 db.test.insert(a)
00542 db.test.insert(a)
00543 self.assert_("E11000" in db.error()["err"])
00544
00545 self.assertRaises(OperationFailure, db.test.insert, a, safe=True)
00546
00547 def test_update(self):
00548 db = self.db
00549 db.drop_collection("test")
00550
00551 id1 = db.test.save({"x": 5})
00552 db.test.update({}, {"$inc": {"x": 1}})
00553 self.assertEqual(db.test.find_one(id1)["x"], 6)
00554
00555 id2 = db.test.save({"x": 1})
00556 db.test.update({"x": 6}, {"$inc": {"x": 1}})
00557 self.assertEqual(db.test.find_one(id1)["x"], 7)
00558 self.assertEqual(db.test.find_one(id2)["x"], 1)
00559
00560 def test_multi_update(self):
00561 db = self.db
00562 if not version.at_least(db.connection, (1, 1, 3, -1)):
00563 raise SkipTest()
00564
00565 db.drop_collection("test")
00566
00567 db.test.save({"x": 4, "y": 3})
00568 db.test.save({"x": 5, "y": 5})
00569 db.test.save({"x": 4, "y": 4})
00570
00571 db.test.update({"x": 4}, {"$set": {"y": 5}}, multi=True)
00572
00573 self.assertEqual(3, db.test.count())
00574 for doc in db.test.find():
00575 self.assertEqual(5, doc["y"])
00576
00577 self.assertEqual(2, db.test.update({"x": 4}, {"$set": {"y": 6}},
00578 multi=True, safe=True)["n"])
00579
00580 def test_upsert(self):
00581 db = self.db
00582 db.drop_collection("test")
00583
00584 db.test.update({"page": "/"}, {"$inc": {"count": 1}}, upsert=True)
00585 db.test.update({"page": "/"}, {"$inc": {"count": 1}}, upsert=True)
00586
00587 self.assertEqual(1, db.test.count())
00588 self.assertEqual(2, db.test.find_one()["count"])
00589
00590 def test_safe_update(self):
00591 db = self.db
00592 v113minus = version.at_least(db.connection, (1, 1, 3, -1))
00593
00594 db.drop_collection("test")
00595 db.test.create_index("x", unique=True)
00596
00597 db.test.insert({"x": 5})
00598 id = db.test.insert({"x": 4})
00599
00600 self.assertEqual(None, db.test.update({"_id": id}, {"$inc": {"x": 1}}))
00601 if v113minus:
00602 self.assert_(db.error()["err"].startswith("E11001"))
00603 else:
00604 self.assert_(db.error()["err"].startswith("E12011"))
00605
00606 self.assertRaises(OperationFailure, db.test.update,
00607 {"_id": id}, {"$inc": {"x": 1}}, safe=True)
00608
00609 self.assertEqual(1, db.test.update({"_id": id}, {"$inc": {"x": 2}}, safe=True)["n"])
00610
00611 self.assertEqual(0, db.test.update({"_id": "foo"}, {"$inc": {"x": 2}}, safe=True)["n"])
00612
00613 def test_safe_save(self):
00614 db = self.db
00615 db.drop_collection("test")
00616 db.test.create_index("hello", unique=True)
00617
00618 db.test.save({"hello": "world"})
00619 db.test.save({"hello": "world"})
00620 self.assert_("E11000" in db.error()["err"])
00621
00622 self.assertRaises(OperationFailure, db.test.save, {"hello": "world"}, safe=True)
00623
00624 def test_safe_remove(self):
00625 db = self.db
00626 db.drop_collection("test")
00627 db.create_collection("test", capped=True, size=1000)
00628
00629 db.test.insert({"x": 1})
00630 self.assertEqual(1, db.test.count())
00631
00632 self.assertEqual(None, db.test.remove({"x": 1}))
00633 self.assertEqual(1, db.test.count())
00634
00635 if version.at_least(db.connection, (1, 1, 3, -1)):
00636 self.assertRaises(OperationFailure, db.test.remove, {"x": 1}, safe=True)
00637 else:
00638 db.test.remove({"x": 1}, safe=True)
00639
00640 db.drop_collection("test")
00641 db.test.insert({"x": 1})
00642 db.test.insert({"x": 1})
00643 self.assertEqual(2, db.test.remove({}, safe=True)["n"])
00644 self.assertEqual(0, db.test.remove({}, safe=True)["n"])
00645
00646 def test_last_error_options(self):
00647 if not version.at_least(self.connection, (1, 5, 1)):
00648 raise SkipTest()
00649
00650
00651
00652
00653 if not version.at_least(self.connection, (1, 7, 6)):
00654 self.assertRaises(TimeoutError, self.db.test.save, {"x": 1}, w=2, wtimeout=1)
00655 self.assertRaises(TimeoutError, self.db.test.insert, {"x": 1}, w=2, wtimeout=1)
00656 self.assertRaises(TimeoutError, self.db.test.update, {"x": 1}, {"y": 2}, w=2, wtimeout=1)
00657 self.assertRaises(TimeoutError, self.db.test.remove, {"x": 1}, {"y": 2}, w=2, wtimeout=1)
00658
00659 self.db.test.save({"x": 1}, w=1, wtimeout=1)
00660 self.db.test.insert({"x": 1}, w=1, wtimeout=1)
00661 self.db.test.remove({"x": 1}, w=1, wtimeout=1)
00662 self.db.test.update({"x": 1}, {"y": 2}, w=1, wtimeout=1)
00663
00664 def test_manual_last_error(self):
00665 self.db.test.save({"x": 1})
00666
00667
00668
00669 if not version.at_least(self.connection, (1, 7, 6)):
00670 self.assertRaises(TimeoutError, self.db.command, "getlasterror", w=2, wtimeout=1)
00671 self.db.command("getlasterror", w=1, wtimeout=1)
00672
00673 def test_count(self):
00674 db = self.db
00675 db.drop_collection("test")
00676
00677 self.assertEqual(db.test.count(), 0)
00678 db.test.save({})
00679 db.test.save({})
00680 self.assertEqual(db.test.count(), 2)
00681
00682 def test_group(self):
00683 db = self.db
00684 db.drop_collection("test")
00685
00686 def group_checker(args, expected):
00687 eval = db.test.group(*args)
00688 self.assertEqual(eval, expected)
00689
00690
00691 self.assertEqual([], db.test.group([], {}, {"count": 0},
00692 "function (obj, prev) { prev.count++; }"))
00693
00694 db.test.save({"a": 2})
00695 db.test.save({"b": 5})
00696 db.test.save({"a": 1})
00697
00698 self.assertEqual([{"count": 3}],
00699 db.test.group([], {}, {"count": 0},
00700 "function (obj, prev) { prev.count++; }"))
00701
00702 self.assertEqual([{"count": 1}],
00703 db.test.group([], {"a": {"$gt": 1}}, {"count": 0},
00704 "function (obj, prev) { prev.count++; }"))
00705
00706 db.test.save({"a": 2, "b": 3})
00707
00708 self.assertEqual([{"a": 2, "count": 2},
00709 {"a": None, "count": 1},
00710 {"a": 1, "count": 1}],
00711 db.test.group(["a"], {}, {"count": 0},
00712 "function (obj, prev) { prev.count++; }"))
00713
00714
00715 self.assertEqual([{"a": 2, "count": 3},
00716 {"a": None, "count": 2},
00717 {"a": 1, "count": 2}],
00718 db.test.group(["a"], {}, {"count": 0},
00719 "function (obj, prev) { prev.count++; }",
00720 "function (obj) { obj.count++; }"))
00721
00722
00723 self.assertEqual([2, 1, 1],
00724 db.test.group(["a"], {}, {"count": 0},
00725 "function (obj, prev) { prev.count++; }",
00726 "function (obj) { return obj.count; }"))
00727
00728
00729 self.assertEqual([2, 2],
00730 db.test.group("function (obj) { if (obj.a == 2) { return {a: true} }; "
00731 "return {b: true}; }", {}, {"count": 0},
00732 "function (obj, prev) { prev.count++; }",
00733 "function (obj) { return obj.count; }"))
00734
00735
00736 self.assertEqual([{"count": 4}],
00737 db.test.group(None, {}, {"count": 0},
00738 "function (obj, prev) { prev.count++; }"))
00739
00740 warnings.simplefilter("error")
00741 self.assertRaises(DeprecationWarning,
00742 db.test.group, [], {}, {"count": 0},
00743 "function (obj, prev) { prev.count++; }",
00744 command=False)
00745 warnings.simplefilter("default")
00746
00747 self.assertRaises(OperationFailure, db.test.group, [], {}, {}, "5 ++ 5")
00748
00749 def test_group_with_scope(self):
00750 db = self.db
00751 db.drop_collection("test")
00752 db.test.save({"a": 1})
00753 db.test.save({"b": 1})
00754
00755 reduce_function = "function (obj, prev) { prev.count += inc_value; }"
00756
00757 self.assertEqual(2, db.test.group([], {}, {"count": 0},
00758 Code(reduce_function,
00759 {"inc_value": 1}))[0]['count'])
00760 self.assertEqual(4, db.test.group([], {}, {"count": 0},
00761 Code(reduce_function,
00762 {"inc_value": 2}))[0]['count'])
00763
00764 self.assertEqual(1, db.test.group([], {}, {"count": 0},
00765 Code(reduce_function,
00766 {"inc_value": 0.5}))[0]['count'])
00767
00768 if version.at_least(db.connection, (1, 1)):
00769 self.assertEqual(2, db.test.group([], {}, {"count": 0},
00770 Code(reduce_function,
00771 {"inc_value": 1}),
00772 command=True)[0]['count'])
00773
00774 self.assertEqual(4, db.test.group([], {}, {"count": 0},
00775 Code(reduce_function,
00776 {"inc_value": 2}),
00777 command=True)[0]['count'])
00778
00779 self.assertEqual(1, db.test.group([], {}, {"count": 0},
00780 Code(reduce_function,
00781 {"inc_value": 0.5}),
00782 command=True)[0]['count'])
00783
00784 def test_large_limit(self):
00785 db = self.db
00786 db.drop_collection("test")
00787
00788 for i in range(2000):
00789 db.test.insert({"x": i, "y": "mongomongo" * 1000})
00790
00791 self.assertEqual(2000, db.test.count())
00792
00793 i = 0
00794 y = 0
00795 for doc in db.test.find(limit=1900):
00796 i += 1
00797 y += doc["x"]
00798
00799 self.assertEqual(1900, i)
00800 self.assertEqual(1804050, y)
00801
00802 def test_find_kwargs(self):
00803 db = self.db
00804 db.drop_collection("test")
00805
00806 for i in range(10):
00807 db.test.insert({"x": i})
00808
00809 self.assertEqual(10, db.test.count())
00810
00811 sum = 0
00812 for x in db.test.find({}, skip=4, limit=2):
00813 sum += x["x"]
00814
00815 self.assertEqual(9, sum)
00816
00817 def test_rename(self):
00818 db = self.db
00819 db.drop_collection("test")
00820 db.drop_collection("foo")
00821
00822 self.assertRaises(TypeError, db.test.rename, 5)
00823 self.assertRaises(InvalidName, db.test.rename, "")
00824 self.assertRaises(InvalidName, db.test.rename, "te$t")
00825 self.assertRaises(InvalidName, db.test.rename, ".test")
00826 self.assertRaises(InvalidName, db.test.rename, "test.")
00827 self.assertRaises(InvalidName, db.test.rename, "tes..t")
00828
00829 self.assertEqual(0, db.test.count())
00830 self.assertEqual(0, db.foo.count())
00831
00832 for i in range(10):
00833 db.test.insert({"x": i})
00834
00835 self.assertEqual(10, db.test.count())
00836
00837 db.test.rename("foo")
00838
00839 self.assertEqual(0, db.test.count())
00840 self.assertEqual(10, db.foo.count())
00841
00842 x = 0
00843 for doc in db.foo.find():
00844 self.assertEqual(x, doc["x"])
00845 x += 1
00846
00847 db.test.insert({})
00848 self.assertRaises(OperationFailure, db.foo.rename, "test")
00849 db.foo.rename("test", dropTarget=True)
00850
00851
00852 def test_snapshot(self):
00853 db = self.db
00854
00855 self.assertRaises(TypeError, db.test.find, snapshot=5)
00856
00857 list(db.test.find(snapshot=True))
00858 self.assertRaises(OperationFailure, list, db.test.find(snapshot=True).sort("foo", 1))
00859
00860 def test_find_one(self):
00861 db = self.db
00862 db.drop_collection("test")
00863
00864 id = db.test.save({"hello": "world", "foo": "bar"})
00865
00866 self.assertEqual("world", db.test.find_one()["hello"])
00867 self.assertEqual(db.test.find_one(id), db.test.find_one())
00868 self.assertEqual(db.test.find_one(None), db.test.find_one())
00869 self.assertEqual(db.test.find_one({}), db.test.find_one())
00870 self.assertEqual(db.test.find_one({"hello": "world"}), db.test.find_one())
00871
00872 self.assert_("hello" in db.test.find_one(fields=["hello"]))
00873 self.assert_("hello" not in db.test.find_one(fields=["foo"]))
00874 self.assertEqual(["_id"], db.test.find_one(fields=[]).keys())
00875
00876 self.assertEqual(None, db.test.find_one({"hello": "foo"}))
00877 self.assertEqual(None, db.test.find_one(ObjectId()))
00878
00879 def test_find_one_non_objectid(self):
00880 db = self.db
00881 db.drop_collection("test")
00882
00883 db.test.save({"_id": 5})
00884
00885 self.assert_(db.test.find_one(5))
00886 self.assertFalse(db.test.find_one(6))
00887
00888 def test_remove_non_objectid(self):
00889 db = self.db
00890 db.drop_collection("test")
00891
00892 db.test.save({"_id": 5})
00893
00894 self.assertEqual(1, db.test.count())
00895 db.test.remove(5)
00896 self.assertEqual(0, db.test.count())
00897
00898 def test_find_one_with_find_args(self):
00899 db = self.db
00900 db.drop_collection("test")
00901
00902 db.test.save({"x": 1})
00903 db.test.save({"x": 2})
00904 db.test.save({"x": 3})
00905
00906 self.assertEqual(1, db.test.find_one()["x"])
00907 self.assertEqual(2, db.test.find_one(skip=1, limit=2)["x"])
00908
00909 def test_find_with_sort(self):
00910 db = self.db
00911 db.drop_collection("test")
00912
00913 db.test.save({"x": 2})
00914 db.test.save({"x": 1})
00915 db.test.save({"x": 3})
00916
00917 self.assertEqual(2, db.test.find_one()["x"])
00918 self.assertEqual(1, db.test.find_one(sort=[("x", 1)])["x"])
00919 self.assertEqual(3, db.test.find_one(sort=[("x", -1)])["x"])
00920
00921 def to_list(foo):
00922 return [bar["x"] for bar in foo]
00923
00924 self.assertEqual([2,1,3], to_list(db.test.find()))
00925 self.assertEqual([1,2,3], to_list(db.test.find(sort=[("x", 1)])))
00926 self.assertEqual([3,2,1], to_list(db.test.find(sort=[("x", -1)])))
00927
00928 self.assertRaises(TypeError, db.test.find, sort=5)
00929 self.assertRaises(TypeError, db.test.find, sort="hello")
00930 self.assertRaises(ValueError, db.test.find, sort=["hello", 1])
00931
00932 def test_insert_adds_id(self):
00933 doc = {"hello": "world"}
00934 self.db.test.insert(doc)
00935 self.assert_("_id" in doc)
00936
00937 docs = [{"hello": "world"}, {"hello": "world"}]
00938 self.db.test.insert(docs)
00939 for doc in docs:
00940 self.assert_("_id" in doc)
00941
00942 def test_save_adds_id(self):
00943 doc = {"hello": "world"}
00944 self.db.test.save(doc)
00945 self.assert_("_id" in doc)
00946
00947
00948 def test_cursor_timeout(self):
00949 list(self.db.test.find(timeout=False))
00950 list(self.db.test.find(timeout=True))
00951
00952 def test_distinct(self):
00953 if not version.at_least(self.db.connection, (1, 1)):
00954 raise SkipTest()
00955
00956 self.db.drop_collection("test")
00957
00958 self.db.test.save({"a": 1})
00959 self.db.test.save({"a": 2})
00960 self.db.test.save({"a": 2})
00961 self.db.test.save({"a": 2})
00962 self.db.test.save({"a": 3})
00963
00964 distinct = self.db.test.distinct("a")
00965 distinct.sort()
00966
00967 self.assertEqual([1, 2, 3], distinct)
00968
00969 self.db.drop_collection("test")
00970
00971 self.db.test.save({"a": {"b": "a"}, "c": 12})
00972 self.db.test.save({"a": {"b": "b"}, "c": 12})
00973 self.db.test.save({"a": {"b": "c"}, "c": 12})
00974 self.db.test.save({"a": {"b": "c"}, "c": 12})
00975
00976 distinct = self.db.test.distinct("a.b")
00977 distinct.sort()
00978
00979 self.assertEqual(["a", "b", "c"], distinct)
00980
00981 def test_query_on_query_field(self):
00982 self.db.drop_collection("test")
00983 self.db.test.save({"query": "foo"})
00984 self.db.test.save({"bar": "foo"})
00985
00986 self.assertEqual(1, self.db.test.find({"query": {"$ne": None}}).count())
00987 self.assertEqual(1, len(list(self.db.test.find({"query": {"$ne": None}}))))
00988
00989 def test_min_query(self):
00990 self.db.drop_collection("test")
00991 self.db.test.save({"x": 1})
00992 self.db.test.save({"x": 2})
00993 self.db.test.create_index("x")
00994
00995 self.assertEqual(1, len(list(self.db.test.find({"$min": {"x": 2},
00996 "$query": {}}))))
00997 self.assertEqual(2, self.db.test.find({"$min": {"x": 2},
00998 "$query": {}})[0]["x"])
00999
01000 def test_insert_large_document(self):
01001 max_size = self.db.connection.max_bson_size
01002 half_size = max_size / 2
01003 if version.at_least(self.db.connection, (1, 7, 4)):
01004 self.assertEqual(max_size, 16777216)
01005 self.assertRaises(InvalidDocument, self.db.test.insert,
01006 {"foo": "x" * max_size})
01007 self.assertRaises(InvalidDocument, self.db.test.save,
01008 {"foo": "x" * max_size})
01009 self.assertRaises(InvalidDocument, self.db.test.insert,
01010 [{"x": 1}, {"foo": "x" * max_size}])
01011 self.db.test.insert([{"foo": "x" * half_size},
01012 {"foo": "x" * half_size}], safe=True)
01013
01014 self.db.test.insert({"bar": "x"})
01015 self.assertRaises(InvalidDocument, self.db.test.update,
01016 {"bar": "x"}, {"bar": "x" * (max_size - 14)},
01017 safe=True)
01018 self.db.test.update({"bar": "x"}, {"bar": "x" * (max_size - 15)},
01019 safe=True)
01020
01021 def test_map_reduce(self):
01022 if not version.at_least(self.db.connection, (1, 1, 1)):
01023 raise SkipTest()
01024
01025 db = self.db
01026 db.drop_collection("test")
01027
01028 db.test.insert({"id": 1, "tags": ["dog", "cat"]})
01029 db.test.insert({"id": 2, "tags": ["cat"]})
01030 db.test.insert({"id": 3, "tags": ["mouse", "cat", "dog"]})
01031 db.test.insert({"id": 4, "tags": []})
01032
01033 map = Code("function () {"
01034 " this.tags.forEach(function(z) {"
01035 " emit(z, 1);"
01036 " });"
01037 "}")
01038 reduce = Code("function (key, values) {"
01039 " var total = 0;"
01040 " for (var i = 0; i < values.length; i++) {"
01041 " total += values[i];"
01042 " }"
01043 " return total;"
01044 "}")
01045 result = db.test.map_reduce(map, reduce, out='mrunittests')
01046 self.assertEqual(3, result.find_one({"_id": "cat"})["value"])
01047 self.assertEqual(2, result.find_one({"_id": "dog"})["value"])
01048 self.assertEqual(1, result.find_one({"_id": "mouse"})["value"])
01049
01050 if version.at_least(self.db.connection, (1, 7, 4)):
01051 db.test.insert({"id": 5, "tags": ["hampster"]})
01052 result = db.test.map_reduce(map, reduce, out='mrunittests')
01053 self.assertEqual(1, result.find_one({"_id": "hampster"})["value"])
01054 db.test.remove({"id": 5})
01055 result = db.test.map_reduce(map, reduce,
01056 out='mrunittests', merge_output=True)
01057 self.assertEqual(3, result.find_one({"_id": "cat"})["value"])
01058 self.assertEqual(1, result.find_one({"_id": "hampster"})["value"])
01059
01060 result = db.test.map_reduce(map, reduce,
01061 out='mrunittests', reduce_output=True)
01062 self.assertEqual(6, result.find_one({"_id": "cat"})["value"])
01063 self.assertEqual(4, result.find_one({"_id": "dog"})["value"])
01064 self.assertEqual(2, result.find_one({"_id": "mouse"})["value"])
01065 self.assertEqual(1, result.find_one({"_id": "hampster"})["value"])
01066
01067 self.assertRaises(InvalidOperation,
01068 db.test.map_reduce,
01069 map,
01070 reduce,
01071 out='mrunittests',
01072 merge_output=True,
01073 reduce_output=True)
01074
01075 full_result = db.test.map_reduce(map, reduce,
01076 out='mrunittests', full_response=True)
01077 self.assertEqual(6, full_result["counts"]["emit"])
01078
01079 result = db.test.map_reduce(map, reduce, out='mrunittests', limit=2)
01080 self.assertEqual(2, result.find_one({"_id": "cat"})["value"])
01081 self.assertEqual(1, result.find_one({"_id": "dog"})["value"])
01082 self.assertEqual(None, result.find_one({"_id": "mouse"}))
01083
01084 if version.at_least(self.db.connection, (1, 7, 4)):
01085 result = db.test.inline_map_reduce(map, reduce)
01086 self.assertTrue(isinstance(result, list))
01087 self.assertEqual(3, len(result))
01088 self.assertTrue(result[1]["_id"] in ("cat", "dog", "mouse"))
01089
01090 full_result = db.test.inline_map_reduce(map, reduce,
01091 full_response=True)
01092 self.assertEqual(6, full_result["counts"]["emit"])
01093
01094 def test_messages_with_unicode_collection_names(self):
01095 db = self.db
01096
01097 db[u"Employés"].insert({"x": 1})
01098 db[u"Employés"].update({"x": 1}, {"x": 2})
01099 db[u"Employés"].remove({})
01100 db[u"Employés"].find_one()
01101 list(db[u"Employés"].find())
01102
01103 def test_drop_indexes_non_existant(self):
01104 self.db.drop_collection("test")
01105 self.db.test.drop_indexes()
01106
01107
01108
01109 def test_bad_encode(self):
01110 c = self.db.test
01111 warnings.simplefilter("ignore")
01112 self.assertRaises(InvalidDocument, c.save, {"x": c})
01113 warnings.simplefilter("default")
01114
01115 def test_as_class(self):
01116 c = self.db.test
01117 c.drop()
01118 c.insert({"x": 1})
01119
01120 self.assert_(isinstance(c.find().next(), dict))
01121 self.assertFalse(isinstance(c.find().next(), SON))
01122 self.assert_(isinstance(c.find(as_class=SON).next(), SON))
01123
01124 self.assert_(isinstance(c.find_one(), dict))
01125 self.assertFalse(isinstance(c.find_one(), SON))
01126 self.assert_(isinstance(c.find_one(as_class=SON), SON))
01127
01128 self.assertEqual(1, c.find_one(as_class=SON)["x"])
01129 self.assertEqual(1, c.find(as_class=SON).next()["x"])
01130
01131 def test_find_and_modify(self):
01132 c = self.db.test
01133 c.drop()
01134 c.insert({'_id': 1, 'i':1})
01135
01136 self.assertEqual({'_id': 1, 'i':1},
01137 c.find_and_modify({'_id':1}, {'$inc':{'i':1}}))
01138 self.assertEqual({'_id': 1, 'i':3},
01139 c.find_and_modify({'_id':1}, {'$inc':{'i':1}},
01140 new=True))
01141
01142 self.assertEqual({'_id': 1, 'i':3},
01143 c.find_and_modify({'_id':1}, remove=True))
01144
01145 self.assertEqual(None, c.find_one({'_id':1}))
01146
01147 self.assertEqual(None, c.find_and_modify({'_id':1}, {'$inc':{'i':1}}))
01148 self.assertEqual({}, c.find_and_modify({'_id':1}, {'$inc':{'i':1}},
01149 upsert=True))
01150 self.assertEqual({'_id': 1, 'i':2},
01151 c.find_and_modify({'_id':1}, {'$inc':{'i':1}},
01152 upsert=True, new=True))
01153
01154
01155 if __name__ == "__main__":
01156 unittest.main()