summaryrefslogtreecommitdiff
path: root/src/mongo/dbtests/updatetests.cpp
diff options
context:
space:
mode:
authoraaron <aaron@10gen.com>2012-12-22 13:34:06 -0800
committeraaron <aaron@10gen.com>2012-12-27 12:20:18 -0800
commitf498a5c235e4da255d9cfea336b66b9c30403706 (patch)
tree169f3cccc648f1e29ca740a1781cb1b75831221c /src/mongo/dbtests/updatetests.cpp
parent5b24436ec22e8925d921a5f070e5c46132915f6c (diff)
downloadmongo-f498a5c235e4da255d9cfea336b66b9c30403706.tar.gz
SERVER-6669 SERVER-4713 Validate that a positional match is found before applying an update mod with the positional operator.
Diffstat (limited to 'src/mongo/dbtests/updatetests.cpp')
-rw-r--r--src/mongo/dbtests/updatetests.cpp76
1 files changed, 76 insertions, 0 deletions
diff --git a/src/mongo/dbtests/updatetests.cpp b/src/mongo/dbtests/updatetests.cpp
index ff7c44264e5..0cf177ace91 100644
--- a/src/mongo/dbtests/updatetests.cpp
+++ b/src/mongo/dbtests/updatetests.cpp
@@ -2157,6 +2157,77 @@ namespace UpdateTests {
modSetState->getOpLogRewrite() );
}
};
+
+ class PositionalWithoutElemMatchKey {
+ public:
+ void run() {
+ BSONObj querySpec = BSONObj();
+ BSONObj modSpec = BSON( "$set" << BSON( "a.$" << 1 ) );
+ ModSet modSet( modSpec );
+
+ // A positional operator must be replaced with an array index before calling
+ // prepare().
+ ASSERT_THROWS( modSet.prepare( querySpec ), UserException );
+ }
+ };
+
+ class PositionalWithoutNestedElemMatchKey {
+ public:
+ void run() {
+ BSONObj querySpec = BSONObj();
+ BSONObj modSpec = BSON( "$set" << BSON( "a.b.c.$.e.f" << 1 ) );
+ ModSet modSet( modSpec );
+
+ // A positional operator must be replaced with an array index before calling
+ // prepare().
+ ASSERT_THROWS( modSet.prepare( querySpec ), UserException );
+ }
+ };
+
+ class DbrefPassesPositionalValidation {
+ public:
+ void run() {
+ BSONObj querySpec = BSONObj();
+ BSONObj modSpec = BSON( "$set" << BSON( "a.$ref" << "foo" << "a.$id" << 0 ) );
+ ModSet modSet( modSpec );
+
+ // A positional operator must be replaced with an array index before calling
+ // prepare(), but $ prefixed fields encoding dbrefs are allowed.
+ modSet.prepare( querySpec ); // Does not throw.
+ }
+ };
+
+ class NoPositionalValidationOnReplication {
+ public:
+ void run() {
+ BSONObj querySpec = BSONObj();
+ BSONObj modSpec = BSON( "$set" << BSON( "a.$" << 1 ) );
+ ModSet modSet( modSpec, set<string>(), NULL, true );
+
+ // No positional operator validation is performed if a ModSet is 'forReplication'.
+ modSet.prepare( querySpec ); // Does not throw.
+ }
+ };
+
+ class NoPositionalValidationOnPartialFixedArrayReplication {
+ public:
+ void run() {
+ BSONObj querySpec = BSONObj( BSON( "a.b" << 1 ) );
+ BSONObj modSpec = BSON( "$set" << BSON( "a.$.b.$" << 1 ) );
+ ModSet modSet( modSpec, set<string>(), NULL, true );
+
+ // Attempt to fix the positional operator fields.
+ scoped_ptr<ModSet> fixedMods( modSet.fixDynamicArray( "0" ) );
+
+ // The first positional field is replaced, but the second is not (until SERVER-831
+ // is implemented).
+ ASSERT( fixedMods->haveModForField( "a.0.b.$" ) );
+
+ // No positional operator validation is performed if a ModSet is 'forReplication',
+ // even after an attempt to fix the positional operator fields.
+ fixedMods->prepare( querySpec ); // Does not throw.
+ }
+ };
};
namespace basic {
@@ -2510,6 +2581,11 @@ namespace UpdateTests {
// add< ModSetTests::BitRewriteNonExistingField >();
add< ModSetTests::SetIsNotRewritten >();
add< ModSetTests::UnsetIsNotRewritten >();
+ add< ModSetTests::PositionalWithoutElemMatchKey >();
+ add< ModSetTests::PositionalWithoutNestedElemMatchKey >();
+ add< ModSetTests::DbrefPassesPositionalValidation >();
+ add< ModSetTests::NoPositionalValidationOnReplication >();
+ add< ModSetTests::NoPositionalValidationOnPartialFixedArrayReplication >();
add< basic::inc1 >();
add< basic::inc2 >();