diff options
Diffstat (limited to 'src/mongo/db/ops/modifier_current_date_test.cpp')
-rw-r--r-- | src/mongo/db/ops/modifier_current_date_test.cpp | 600 |
1 files changed, 298 insertions, 302 deletions
diff --git a/src/mongo/db/ops/modifier_current_date_test.cpp b/src/mongo/db/ops/modifier_current_date_test.cpp index 51eb4a79659..ecb4b86bac8 100644 --- a/src/mongo/db/ops/modifier_current_date_test.cpp +++ b/src/mongo/db/ops/modifier_current_date_test.cpp @@ -39,327 +39,323 @@ namespace { - using mongo::BSONObj; - using mongo::LogBuilder; - using mongo::ModifierCurrentDate; - using mongo::ModifierInterface; - using mongo::Timestamp; - using mongo::Status; - using mongo::StringData; - using mongo::fromjson; - using mongo::mutablebson::ConstElement; - using mongo::mutablebson::Document; - using mongo::mutablebson::Element; - - /** - * Helper to validate oplog entries in the tests below. - */ - void validateOplogEntry(BSONObj& oplogFormat, Document& doc){ - // Ensure that the field is the same - ASSERT_EQUALS(oplogFormat.firstElement().fieldName(), - doc.root().leftChild().getFieldName()); - - // Ensure the field names are the same - ASSERT_EQUALS(oplogFormat.firstElement().embeddedObject().firstElement().fieldName(), - doc.root().leftChild().leftChild().getFieldName()); - - // Ensure the type is the same in the document as the oplog - ASSERT_EQUALS(oplogFormat.firstElement().embeddedObject().firstElement().type(), - doc.root().leftChild().leftChild().getType()); +using mongo::BSONObj; +using mongo::LogBuilder; +using mongo::ModifierCurrentDate; +using mongo::ModifierInterface; +using mongo::Timestamp; +using mongo::Status; +using mongo::StringData; +using mongo::fromjson; +using mongo::mutablebson::ConstElement; +using mongo::mutablebson::Document; +using mongo::mutablebson::Element; + +/** + * Helper to validate oplog entries in the tests below. + */ +void validateOplogEntry(BSONObj& oplogFormat, Document& doc) { + // Ensure that the field is the same + ASSERT_EQUALS(oplogFormat.firstElement().fieldName(), doc.root().leftChild().getFieldName()); + + // Ensure the field names are the same + ASSERT_EQUALS(oplogFormat.firstElement().embeddedObject().firstElement().fieldName(), + doc.root().leftChild().leftChild().getFieldName()); + + // Ensure the type is the same in the document as the oplog + ASSERT_EQUALS(oplogFormat.firstElement().embeddedObject().firstElement().type(), + doc.root().leftChild().leftChild().getType()); +} + +/** Helper to build and manipulate a $currentDate mod. */ +class Mod { +public: + Mod() : _mod() {} + + explicit Mod(BSONObj modObj) : _modObj(modObj), _mod() { + ASSERT_OK(_mod.init(_modObj["$currentDate"].embeddedObject().firstElement(), + ModifierInterface::Options::normal())); } - /** Helper to build and manipulate a $currentDate mod. */ - class Mod { - public: - Mod() : _mod() {} + Status prepare(Element root, StringData matchedField, ModifierInterface::ExecInfo* execInfo) { + return _mod.prepare(root, matchedField, execInfo); + } - explicit Mod(BSONObj modObj) - : _modObj(modObj) - , _mod() { - ASSERT_OK(_mod.init(_modObj["$currentDate"].embeddedObject().firstElement(), - ModifierInterface::Options::normal())); + Status apply() const { + return _mod.apply(); + } - } + Status log(LogBuilder* logBuilder) const { + return _mod.log(logBuilder); + } - Status prepare(Element root, - StringData matchedField, - ModifierInterface::ExecInfo* execInfo) { - return _mod.prepare(root, matchedField, execInfo); - } + ModifierCurrentDate& mod() { + return _mod; + } - Status apply() const { - return _mod.apply(); - } +private: + BSONObj _modObj; + ModifierCurrentDate _mod; +}; - Status log(LogBuilder* logBuilder) const { - return _mod.log(logBuilder); - } +TEST(Init, ValidValues) { + BSONObj modObj; + ModifierCurrentDate mod; - ModifierCurrentDate& mod() { return _mod; } + modObj = fromjson("{ $currentDate : { a : true } }"); + ASSERT_OK(mod.init(modObj["$currentDate"].embeddedObject().firstElement(), + ModifierInterface::Options::normal())); - private: - BSONObj _modObj; - ModifierCurrentDate _mod; - }; + modObj = fromjson("{ $currentDate : { a : {$type : 'timestamp' } } }"); + ASSERT_OK(mod.init(modObj["$currentDate"].embeddedObject().firstElement(), + ModifierInterface::Options::normal())); - TEST(Init, ValidValues) { - BSONObj modObj; - ModifierCurrentDate mod; + modObj = fromjson("{ $currentDate : { a : {$type : 'date' } } }"); + ASSERT_OK(mod.init(modObj["$currentDate"].embeddedObject().firstElement(), + ModifierInterface::Options::normal())); +} - modObj = fromjson("{ $currentDate : { a : true } }"); - ASSERT_OK(mod.init(modObj["$currentDate"].embeddedObject().firstElement(), - ModifierInterface::Options::normal())); +TEST(Init, FailToInitWithInvalidValue) { + BSONObj modObj; + ModifierCurrentDate mod; - modObj = fromjson("{ $currentDate : { a : {$type : 'timestamp' } } }"); - ASSERT_OK(mod.init(modObj["$currentDate"].embeddedObject().firstElement(), + // String is an invalid $currentDate argument + modObj = fromjson("{ $currentDate : { a : 'Oct 11, 2001' } }"); + ASSERT_NOT_OK(mod.init(modObj["$currentDate"].embeddedObject().firstElement(), ModifierInterface::Options::normal())); - modObj = fromjson("{ $currentDate : { a : {$type : 'date' } } }"); - ASSERT_OK(mod.init(modObj["$currentDate"].embeddedObject().firstElement(), + // Array is an invalid $currentDate argument + modObj = fromjson("{ $currentDate : { a : [] } }"); + ASSERT_NOT_OK(mod.init(modObj["$currentDate"].embeddedObject().firstElement(), ModifierInterface::Options::normal())); - } - - TEST(Init, FailToInitWithInvalidValue) { - BSONObj modObj; - ModifierCurrentDate mod; - - // String is an invalid $currentDate argument - modObj = fromjson("{ $currentDate : { a : 'Oct 11, 2001' } }"); - ASSERT_NOT_OK(mod.init(modObj["$currentDate"].embeddedObject().firstElement(), - ModifierInterface::Options::normal())); - - // Array is an invalid $currentDate argument - modObj = fromjson("{ $currentDate : { a : [] } }"); - ASSERT_NOT_OK(mod.init(modObj["$currentDate"].embeddedObject().firstElement(), - ModifierInterface::Options::normal())); - - // Number is an invalid $currentDate argument - modObj = fromjson("{ $currentDate : { a : 1 } }"); - ASSERT_NOT_OK(mod.init(modObj["$currentDate"].embeddedObject().firstElement(), - ModifierInterface::Options::normal())); - - // Regex is an invalid $currentDate argument - modObj = fromjson("{ $currentDate : { a : /1/ } }"); - ASSERT_NOT_OK(mod.init(modObj["$currentDate"].embeddedObject().firstElement(), - ModifierInterface::Options::normal())); - - // An object with missing $type field is an invalid $currentDate argument - modObj = fromjson("{ $currentDate : { a : { foo : 4 } } }"); - ASSERT_NOT_OK(mod.init(modObj["$currentDate"].embeddedObject().firstElement(), - ModifierInterface::Options::normal())); - - // An object with extra fields, including the $type field is bad - modObj = fromjson("{ $currentDate : { a : { $type: 'date', foo : 4 } } }"); - ASSERT_NOT_OK(mod.init(modObj["$currentDate"].embeddedObject().firstElement(), - ModifierInterface::Options::normal())); - - // An object with extra fields, including the $type field is bad - modObj = fromjson("{ $currentDate : { a : { foo: 4, $type : 'date' } } }"); - ASSERT_NOT_OK(mod.init(modObj["$currentDate"].embeddedObject().firstElement(), - ModifierInterface::Options::normal())); - - // An object with non-date/timestamp $type field is an invalid $currentDate argument - modObj = fromjson("{ $currentDate : { a : { $type : 4 } } }"); - ASSERT_NOT_OK(mod.init(modObj["$currentDate"].embeddedObject().firstElement(), - ModifierInterface::Options::normal())); - - // An object with non-date/timestamp $type field is an invalid $currentDate argument - modObj = fromjson("{ $currentDate : { a : { $type : 'foo' } } }"); - ASSERT_NOT_OK(mod.init(modObj["$currentDate"].embeddedObject().firstElement(), - ModifierInterface::Options::normal())); - } - - TEST(BoolInput, EmptyStartDoc) { - Document doc(fromjson("{ }")); - Mod mod(fromjson("{ $currentDate : { a : true } }")); - - ModifierInterface::ExecInfo execInfo; - ASSERT_OK(mod.prepare(doc.root(), "", &execInfo)); - ASSERT_FALSE(execInfo.noOp); - ASSERT_EQUALS("a", execInfo.fieldRef[0]->dottedField()); - - BSONObj olderDateObj = fromjson("{ a : { $date : 0 } }"); - ASSERT_OK(mod.apply()); - ASSERT_LESS_THAN(olderDateObj, doc.getObject()); - ASSERT_FALSE(doc.isInPlaceModeEnabled()); - - Document logDoc; - LogBuilder logBuilder(logDoc.root()); - ASSERT_OK(mod.log(&logBuilder)); - BSONObj oplogFormat = fromjson("{ $set : { a : { $date : 0 } } }"); - validateOplogEntry(oplogFormat, logDoc); - } - - TEST(DateInput, EmptyStartDoc) { - Document doc(fromjson("{ }")); - Mod mod(fromjson("{ $currentDate : { a : {$type: 'date' } } }")); - - ModifierInterface::ExecInfo execInfo; - ASSERT_OK(mod.prepare(doc.root(), "", &execInfo)); - ASSERT_FALSE(execInfo.noOp); - ASSERT_EQUALS("a", execInfo.fieldRef[0]->dottedField()); - - BSONObj olderDateObj = fromjson("{ a : { $date : 0 } }"); - ASSERT_OK(mod.apply()); - ASSERT_LESS_THAN(olderDateObj, doc.getObject()); - ASSERT_FALSE(doc.isInPlaceModeEnabled()); - - Document logDoc; - LogBuilder logBuilder(logDoc.root()); - ASSERT_OK(mod.log(&logBuilder)); - BSONObj oplogFormat = fromjson("{ $set : { a : { $date : 0 } } }"); - validateOplogEntry(oplogFormat, logDoc); - } - TEST(TimestampInput, EmptyStartDoc) { - Document doc(fromjson("{ }")); - Mod mod(fromjson("{ $currentDate : { a : {$type : 'timestamp' } } }")); - - ModifierInterface::ExecInfo execInfo; - ASSERT_OK(mod.prepare(doc.root(), "", &execInfo)); - ASSERT_FALSE(execInfo.noOp); - ASSERT_EQUALS("a", execInfo.fieldRef[0]->dottedField()); - - mongo::Timestamp ts; - BSONObj olderDateObj = BSON("a" << ts); - ASSERT_OK(mod.apply()); - ASSERT_FALSE(doc.isInPlaceModeEnabled()); - ASSERT_LESS_THAN(olderDateObj, doc.getObject()); - - Document logDoc; - LogBuilder logBuilder(logDoc.root()); - ASSERT_OK(mod.log(&logBuilder)); - BSONObj oplogFormat = fromjson("{ $set : { a : { $timestamp : {t:0, i:0} } } }"); - validateOplogEntry(oplogFormat, logDoc); - } - - TEST(BoolInput, ExistingStringDoc) { - Document doc(fromjson("{ a: 'a' }")); - Mod mod(fromjson("{ $currentDate : { a : true } }")); - - ModifierInterface::ExecInfo execInfo; - ASSERT_OK(mod.prepare(doc.root(), "", &execInfo)); - ASSERT_FALSE(execInfo.noOp); - ASSERT_EQUALS("a", execInfo.fieldRef[0]->dottedField()); - - BSONObj olderDateObj = fromjson("{ a : { $date : 0 } }"); - ASSERT_OK(mod.apply()); - ASSERT_LESS_THAN(olderDateObj, doc.getObject()); - ASSERT_FALSE(doc.isInPlaceModeEnabled()); - - Document logDoc; - LogBuilder logBuilder(logDoc.root()); - ASSERT_OK(mod.log(&logBuilder)); - BSONObj oplogFormat = fromjson("{ $set : { a : { $date : 0 } } }"); - validateOplogEntry(oplogFormat, logDoc); - } + // Number is an invalid $currentDate argument + modObj = fromjson("{ $currentDate : { a : 1 } }"); + ASSERT_NOT_OK(mod.init(modObj["$currentDate"].embeddedObject().firstElement(), + ModifierInterface::Options::normal())); - TEST(BoolInput, ExistingDateDoc) { - Document doc(fromjson("{ a: {$date: 0 } }")); - Mod mod(fromjson("{ $currentDate : { a : true } }")); - - ModifierInterface::ExecInfo execInfo; - ASSERT_OK(mod.prepare(doc.root(), "", &execInfo)); - ASSERT_FALSE(execInfo.noOp); - ASSERT_EQUALS("a", execInfo.fieldRef[0]->dottedField()); - - BSONObj olderDateObj = fromjson("{ a : { $date : 0 } }"); - ASSERT_OK(mod.apply()); - ASSERT_LESS_THAN(olderDateObj, doc.getObject()); - ASSERT_TRUE(doc.isInPlaceModeEnabled()); - - Document logDoc; - LogBuilder logBuilder(logDoc.root()); - ASSERT_OK(mod.log(&logBuilder)); - BSONObj oplogFormat = fromjson("{ $set : { a : { $date : 0 } } }"); - validateOplogEntry(oplogFormat, logDoc); - } + // Regex is an invalid $currentDate argument + modObj = fromjson("{ $currentDate : { a : /1/ } }"); + ASSERT_NOT_OK(mod.init(modObj["$currentDate"].embeddedObject().firstElement(), + ModifierInterface::Options::normal())); - TEST(DateInput, ExistingDateDoc) { - Document doc(fromjson("{ a: {$date: 0 } }")); - Mod mod(fromjson("{ $currentDate : { a : {$type: 'date' } } }")); - - ModifierInterface::ExecInfo execInfo; - ASSERT_OK(mod.prepare(doc.root(), "", &execInfo)); - ASSERT_FALSE(execInfo.noOp); - ASSERT_EQUALS("a", execInfo.fieldRef[0]->dottedField()); - - BSONObj olderDateObj = fromjson("{ a : { $date : 0 } }"); - ASSERT_OK(mod.apply()); - ASSERT_LESS_THAN(olderDateObj, doc.getObject()); - ASSERT_TRUE(doc.isInPlaceModeEnabled()); - - Document logDoc; - LogBuilder logBuilder(logDoc.root()); - ASSERT_OK(mod.log(&logBuilder)); - BSONObj oplogFormat = fromjson("{ $set : { a : { $date : 0 } } }"); - validateOplogEntry(oplogFormat, logDoc); - } + // An object with missing $type field is an invalid $currentDate argument + modObj = fromjson("{ $currentDate : { a : { foo : 4 } } }"); + ASSERT_NOT_OK(mod.init(modObj["$currentDate"].embeddedObject().firstElement(), + ModifierInterface::Options::normal())); - TEST(TimestampInput, ExistingDateDoc) { - Document doc(fromjson("{ a: {$date: 0 } }")); - Mod mod(fromjson("{ $currentDate : { a : {$type : 'timestamp' } } }")); - - ModifierInterface::ExecInfo execInfo; - ASSERT_OK(mod.prepare(doc.root(), "", &execInfo)); - ASSERT_FALSE(execInfo.noOp); - ASSERT_EQUALS("a", execInfo.fieldRef[0]->dottedField()); - - mongo::Timestamp ts; - BSONObj olderDateObj = BSON("a" << ts); - ASSERT_OK(mod.apply()); - ASSERT_TRUE(doc.isInPlaceModeEnabled()); //Same Size as Date - ASSERT_LESS_THAN(olderDateObj, doc.getObject()); - - Document logDoc; - LogBuilder logBuilder(logDoc.root()); - ASSERT_OK(mod.log(&logBuilder)); - BSONObj oplogFormat = fromjson("{ $set : { a : { $timestamp : {t:0, i:0} } } }"); - validateOplogEntry(oplogFormat, logDoc); - } + // An object with extra fields, including the $type field is bad + modObj = fromjson("{ $currentDate : { a : { $type: 'date', foo : 4 } } }"); + ASSERT_NOT_OK(mod.init(modObj["$currentDate"].embeddedObject().firstElement(), + ModifierInterface::Options::normal())); - TEST(TimestampInput, ExistingEmbeddedDateDoc) { - Document doc(fromjson("{ a: {b: {$date: 0 } } }")); - Mod mod(fromjson("{ $currentDate : { 'a.b' : {$type : 'timestamp' } } }")); - - ModifierInterface::ExecInfo execInfo; - ASSERT_OK(mod.prepare(doc.root(), "", &execInfo)); - ASSERT_FALSE(execInfo.noOp); - ASSERT_EQUALS("a.b", execInfo.fieldRef[0]->dottedField()); - - mongo::Timestamp ts; - BSONObj olderDateObj = BSON("a" << BSON( "b" << ts)); - ASSERT_OK(mod.apply()); - ASSERT_TRUE(doc.isInPlaceModeEnabled()); //Same Size as Date - ASSERT_LESS_THAN(olderDateObj, doc.getObject()); - - Document logDoc; - LogBuilder logBuilder(logDoc.root()); - ASSERT_OK(mod.log(&logBuilder)); - BSONObj oplogFormat = fromjson("{ $set : { 'a.b' : { $timestamp : {t:0, i:0} } } }"); - validateOplogEntry(oplogFormat, logDoc); - } + // An object with extra fields, including the $type field is bad + modObj = fromjson("{ $currentDate : { a : { foo: 4, $type : 'date' } } }"); + ASSERT_NOT_OK(mod.init(modObj["$currentDate"].embeddedObject().firstElement(), + ModifierInterface::Options::normal())); - TEST(DottedTimestampInput, EmptyStartDoc) { - Document doc(fromjson("{ }")); - Mod mod(fromjson("{ $currentDate : { 'a.b' : {$type : 'timestamp' } } }")); - - ModifierInterface::ExecInfo execInfo; - ASSERT_OK(mod.prepare(doc.root(), "", &execInfo)); - ASSERT_FALSE(execInfo.noOp); - ASSERT_EQUALS("a.b", execInfo.fieldRef[0]->dottedField()); - - mongo::Timestamp ts; - BSONObj olderDateObj = BSON("a" << BSON( "b" << ts)); - ASSERT_OK(mod.apply()); - ASSERT_FALSE(doc.isInPlaceModeEnabled()); - ASSERT_LESS_THAN(olderDateObj, doc.getObject()); - - Document logDoc; - LogBuilder logBuilder(logDoc.root()); - ASSERT_OK(mod.log(&logBuilder)); - BSONObj oplogFormat = fromjson("{ $set : { 'a.b' : { $timestamp : {t:0, i:0} } } }"); - validateOplogEntry(oplogFormat, logDoc); - } + // An object with non-date/timestamp $type field is an invalid $currentDate argument + modObj = fromjson("{ $currentDate : { a : { $type : 4 } } }"); + ASSERT_NOT_OK(mod.init(modObj["$currentDate"].embeddedObject().firstElement(), + ModifierInterface::Options::normal())); -} // namespace + // An object with non-date/timestamp $type field is an invalid $currentDate argument + modObj = fromjson("{ $currentDate : { a : { $type : 'foo' } } }"); + ASSERT_NOT_OK(mod.init(modObj["$currentDate"].embeddedObject().firstElement(), + ModifierInterface::Options::normal())); +} + +TEST(BoolInput, EmptyStartDoc) { + Document doc(fromjson("{ }")); + Mod mod(fromjson("{ $currentDate : { a : true } }")); + + ModifierInterface::ExecInfo execInfo; + ASSERT_OK(mod.prepare(doc.root(), "", &execInfo)); + ASSERT_FALSE(execInfo.noOp); + ASSERT_EQUALS("a", execInfo.fieldRef[0]->dottedField()); + + BSONObj olderDateObj = fromjson("{ a : { $date : 0 } }"); + ASSERT_OK(mod.apply()); + ASSERT_LESS_THAN(olderDateObj, doc.getObject()); + ASSERT_FALSE(doc.isInPlaceModeEnabled()); + + Document logDoc; + LogBuilder logBuilder(logDoc.root()); + ASSERT_OK(mod.log(&logBuilder)); + BSONObj oplogFormat = fromjson("{ $set : { a : { $date : 0 } } }"); + validateOplogEntry(oplogFormat, logDoc); +} + +TEST(DateInput, EmptyStartDoc) { + Document doc(fromjson("{ }")); + Mod mod(fromjson("{ $currentDate : { a : {$type: 'date' } } }")); + + ModifierInterface::ExecInfo execInfo; + ASSERT_OK(mod.prepare(doc.root(), "", &execInfo)); + ASSERT_FALSE(execInfo.noOp); + ASSERT_EQUALS("a", execInfo.fieldRef[0]->dottedField()); + + BSONObj olderDateObj = fromjson("{ a : { $date : 0 } }"); + ASSERT_OK(mod.apply()); + ASSERT_LESS_THAN(olderDateObj, doc.getObject()); + ASSERT_FALSE(doc.isInPlaceModeEnabled()); + + Document logDoc; + LogBuilder logBuilder(logDoc.root()); + ASSERT_OK(mod.log(&logBuilder)); + BSONObj oplogFormat = fromjson("{ $set : { a : { $date : 0 } } }"); + validateOplogEntry(oplogFormat, logDoc); +} + +TEST(TimestampInput, EmptyStartDoc) { + Document doc(fromjson("{ }")); + Mod mod(fromjson("{ $currentDate : { a : {$type : 'timestamp' } } }")); + + ModifierInterface::ExecInfo execInfo; + ASSERT_OK(mod.prepare(doc.root(), "", &execInfo)); + ASSERT_FALSE(execInfo.noOp); + ASSERT_EQUALS("a", execInfo.fieldRef[0]->dottedField()); + + mongo::Timestamp ts; + BSONObj olderDateObj = BSON("a" << ts); + ASSERT_OK(mod.apply()); + ASSERT_FALSE(doc.isInPlaceModeEnabled()); + ASSERT_LESS_THAN(olderDateObj, doc.getObject()); + + Document logDoc; + LogBuilder logBuilder(logDoc.root()); + ASSERT_OK(mod.log(&logBuilder)); + BSONObj oplogFormat = fromjson("{ $set : { a : { $timestamp : {t:0, i:0} } } }"); + validateOplogEntry(oplogFormat, logDoc); +} + +TEST(BoolInput, ExistingStringDoc) { + Document doc(fromjson("{ a: 'a' }")); + Mod mod(fromjson("{ $currentDate : { a : true } }")); + + ModifierInterface::ExecInfo execInfo; + ASSERT_OK(mod.prepare(doc.root(), "", &execInfo)); + ASSERT_FALSE(execInfo.noOp); + ASSERT_EQUALS("a", execInfo.fieldRef[0]->dottedField()); + + BSONObj olderDateObj = fromjson("{ a : { $date : 0 } }"); + ASSERT_OK(mod.apply()); + ASSERT_LESS_THAN(olderDateObj, doc.getObject()); + ASSERT_FALSE(doc.isInPlaceModeEnabled()); + + Document logDoc; + LogBuilder logBuilder(logDoc.root()); + ASSERT_OK(mod.log(&logBuilder)); + BSONObj oplogFormat = fromjson("{ $set : { a : { $date : 0 } } }"); + validateOplogEntry(oplogFormat, logDoc); +} + +TEST(BoolInput, ExistingDateDoc) { + Document doc(fromjson("{ a: {$date: 0 } }")); + Mod mod(fromjson("{ $currentDate : { a : true } }")); + + ModifierInterface::ExecInfo execInfo; + ASSERT_OK(mod.prepare(doc.root(), "", &execInfo)); + ASSERT_FALSE(execInfo.noOp); + ASSERT_EQUALS("a", execInfo.fieldRef[0]->dottedField()); + + BSONObj olderDateObj = fromjson("{ a : { $date : 0 } }"); + ASSERT_OK(mod.apply()); + ASSERT_LESS_THAN(olderDateObj, doc.getObject()); + ASSERT_TRUE(doc.isInPlaceModeEnabled()); + + Document logDoc; + LogBuilder logBuilder(logDoc.root()); + ASSERT_OK(mod.log(&logBuilder)); + BSONObj oplogFormat = fromjson("{ $set : { a : { $date : 0 } } }"); + validateOplogEntry(oplogFormat, logDoc); +} + +TEST(DateInput, ExistingDateDoc) { + Document doc(fromjson("{ a: {$date: 0 } }")); + Mod mod(fromjson("{ $currentDate : { a : {$type: 'date' } } }")); + + ModifierInterface::ExecInfo execInfo; + ASSERT_OK(mod.prepare(doc.root(), "", &execInfo)); + ASSERT_FALSE(execInfo.noOp); + ASSERT_EQUALS("a", execInfo.fieldRef[0]->dottedField()); + + BSONObj olderDateObj = fromjson("{ a : { $date : 0 } }"); + ASSERT_OK(mod.apply()); + ASSERT_LESS_THAN(olderDateObj, doc.getObject()); + ASSERT_TRUE(doc.isInPlaceModeEnabled()); + + Document logDoc; + LogBuilder logBuilder(logDoc.root()); + ASSERT_OK(mod.log(&logBuilder)); + BSONObj oplogFormat = fromjson("{ $set : { a : { $date : 0 } } }"); + validateOplogEntry(oplogFormat, logDoc); +} + +TEST(TimestampInput, ExistingDateDoc) { + Document doc(fromjson("{ a: {$date: 0 } }")); + Mod mod(fromjson("{ $currentDate : { a : {$type : 'timestamp' } } }")); + + ModifierInterface::ExecInfo execInfo; + ASSERT_OK(mod.prepare(doc.root(), "", &execInfo)); + ASSERT_FALSE(execInfo.noOp); + ASSERT_EQUALS("a", execInfo.fieldRef[0]->dottedField()); + + mongo::Timestamp ts; + BSONObj olderDateObj = BSON("a" << ts); + ASSERT_OK(mod.apply()); + ASSERT_TRUE(doc.isInPlaceModeEnabled()); // Same Size as Date + ASSERT_LESS_THAN(olderDateObj, doc.getObject()); + + Document logDoc; + LogBuilder logBuilder(logDoc.root()); + ASSERT_OK(mod.log(&logBuilder)); + BSONObj oplogFormat = fromjson("{ $set : { a : { $timestamp : {t:0, i:0} } } }"); + validateOplogEntry(oplogFormat, logDoc); +} + +TEST(TimestampInput, ExistingEmbeddedDateDoc) { + Document doc(fromjson("{ a: {b: {$date: 0 } } }")); + Mod mod(fromjson("{ $currentDate : { 'a.b' : {$type : 'timestamp' } } }")); + + ModifierInterface::ExecInfo execInfo; + ASSERT_OK(mod.prepare(doc.root(), "", &execInfo)); + ASSERT_FALSE(execInfo.noOp); + ASSERT_EQUALS("a.b", execInfo.fieldRef[0]->dottedField()); + + mongo::Timestamp ts; + BSONObj olderDateObj = BSON("a" << BSON("b" << ts)); + ASSERT_OK(mod.apply()); + ASSERT_TRUE(doc.isInPlaceModeEnabled()); // Same Size as Date + ASSERT_LESS_THAN(olderDateObj, doc.getObject()); + + Document logDoc; + LogBuilder logBuilder(logDoc.root()); + ASSERT_OK(mod.log(&logBuilder)); + BSONObj oplogFormat = fromjson("{ $set : { 'a.b' : { $timestamp : {t:0, i:0} } } }"); + validateOplogEntry(oplogFormat, logDoc); +} + +TEST(DottedTimestampInput, EmptyStartDoc) { + Document doc(fromjson("{ }")); + Mod mod(fromjson("{ $currentDate : { 'a.b' : {$type : 'timestamp' } } }")); + + ModifierInterface::ExecInfo execInfo; + ASSERT_OK(mod.prepare(doc.root(), "", &execInfo)); + ASSERT_FALSE(execInfo.noOp); + ASSERT_EQUALS("a.b", execInfo.fieldRef[0]->dottedField()); + + mongo::Timestamp ts; + BSONObj olderDateObj = BSON("a" << BSON("b" << ts)); + ASSERT_OK(mod.apply()); + ASSERT_FALSE(doc.isInPlaceModeEnabled()); + ASSERT_LESS_THAN(olderDateObj, doc.getObject()); + + Document logDoc; + LogBuilder logBuilder(logDoc.root()); + ASSERT_OK(mod.log(&logBuilder)); + BSONObj oplogFormat = fromjson("{ $set : { 'a.b' : { $timestamp : {t:0, i:0} } } }"); + validateOplogEntry(oplogFormat, logDoc); +} + +} // namespace |