diff options
author | aaron <aaron@10gen.com> | 2012-12-22 13:34:06 -0800 |
---|---|---|
committer | aaron <aaron@10gen.com> | 2012-12-27 12:20:18 -0800 |
commit | f498a5c235e4da255d9cfea336b66b9c30403706 (patch) | |
tree | 169f3cccc648f1e29ca740a1781cb1b75831221c /src/mongo/dbtests/updatetests.cpp | |
parent | 5b24436ec22e8925d921a5f070e5c46132915f6c (diff) | |
download | mongo-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.cpp | 76 |
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 >(); |