diff options
author | Matthew Saltz <matthew.saltz@mongodb.com> | 2018-12-06 17:58:28 -0500 |
---|---|---|
committer | Charlie Swanson <charlie.swanson@mongodb.com> | 2019-01-11 18:28:22 -0500 |
commit | c48f6c22e5a8013bbcd6e08cb489b1e809dbbfed (patch) | |
tree | d10a9536e65d015c6014a6b5c0d7a093466ee01f | |
parent | eef9ac3727d949d05f25d16ed3e6f87444e06838 (diff) | |
download | mongo-c48f6c22e5a8013bbcd6e08cb489b1e809dbbfed.tar.gz |
SERVER-38445 Fix Date_t addition with Duration
(cherry picked from commit d899a205ef66d916b071dd42fbb619775561a523)
-rw-r--r-- | src/mongo/db/s/collection_range_deleter.cpp | 4 | ||||
-rw-r--r-- | src/mongo/db/s/collection_sharding_runtime.cpp | 4 | ||||
-rw-r--r-- | src/mongo/db/session.cpp | 2 | ||||
-rw-r--r-- | src/mongo/db/session_test.cpp | 4 | ||||
-rw-r--r-- | src/mongo/util/time_support.h | 6 | ||||
-rw-r--r-- | src/mongo/util/time_support_test.cpp | 36 |
6 files changed, 45 insertions, 11 deletions
diff --git a/src/mongo/db/s/collection_range_deleter.cpp b/src/mongo/db/s/collection_range_deleter.cpp index c86d8630988..3832d495e88 100644 --- a/src/mongo/db/s/collection_range_deleter.cpp +++ b/src/mongo/db/s/collection_range_deleter.cpp @@ -288,7 +288,7 @@ boost::optional<Date_t> CollectionRangeDeleter::cleanUpNextRange( << redact(self->_orphans.front().range.toString()) << " next."; } - return Date_t::now() + stdx::chrono::milliseconds{rangeDeleterBatchDelayMS.load()}; + return Date_t::now() + Milliseconds(rangeDeleterBatchDelayMS.load()); } invariant(range); @@ -296,7 +296,7 @@ boost::optional<Date_t> CollectionRangeDeleter::cleanUpNextRange( invariant(wrote.getValue() > 0); notification.abandon(); - return Date_t::now() + stdx::chrono::milliseconds{rangeDeleterBatchDelayMS.load()}; + return Date_t::now() + Milliseconds(rangeDeleterBatchDelayMS.load()); } bool CollectionRangeDeleter::_checkCollectionMetadataStillValid( diff --git a/src/mongo/db/s/collection_sharding_runtime.cpp b/src/mongo/db/s/collection_sharding_runtime.cpp index 473206d40d9..80a006c61bb 100644 --- a/src/mongo/db/s/collection_sharding_runtime.cpp +++ b/src/mongo/db/s/collection_sharding_runtime.cpp @@ -81,8 +81,8 @@ void CollectionShardingRuntime::forgetReceive(const ChunkRange& range) { auto CollectionShardingRuntime::cleanUpRange(ChunkRange const& range, CleanWhen when) -> CleanupNotification { - Date_t time = (when == kNow) ? Date_t{} : Date_t::now() + - stdx::chrono::seconds{orphanCleanupDelaySecs.load()}; + Date_t time = + (when == kNow) ? Date_t{} : Date_t::now() + Seconds(orphanCleanupDelaySecs.load()); return _metadataManager->cleanUpRange(range, time); } diff --git a/src/mongo/db/session.cpp b/src/mongo/db/session.cpp index b20f1141496..0dac6a9d2ce 100644 --- a/src/mongo/db/session.cpp +++ b/src/mongo/db/session.cpp @@ -629,7 +629,7 @@ void Session::_beginOrContinueTxn(WithLock wl, const auto now = curTimeMicros64(); _transactionExpireDate = Date_t::fromMillisSinceEpoch(now / 1000) + - stdx::chrono::seconds{transactionLifetimeLimitSeconds.load()}; + Seconds{transactionLifetimeLimitSeconds.load()}; // Tracks various transactions metrics. { stdx::lock_guard<stdx::mutex> ls(_statsMutex); diff --git a/src/mongo/db/session_test.cpp b/src/mongo/db/session_test.cpp index ebfbf50b84a..6b23812169d 100644 --- a/src/mongo/db/session_test.cpp +++ b/src/mongo/db/session_test.cpp @@ -766,7 +766,7 @@ TEST_F(SessionTest, ReportStashedResources) { ASSERT_EQ( dateFromISOString(transactionDocument.getField("expiryTime").valueStringData()).getValue(), Date_t::fromMillisSinceEpoch(session.getSingleTransactionStats()->getStartTime() / 1000) + - stdx::chrono::seconds{transactionLifetimeLimitSeconds.load()}); + Seconds{transactionLifetimeLimitSeconds.load()}); ASSERT_EQ(stashedState.getField("client").valueStringData().toString(), ""); ASSERT_EQ(stashedState.getField("connectionId").numberLong(), 0); ASSERT_EQ(stashedState.getField("appName").valueStringData().toString(), "appName"); @@ -843,7 +843,7 @@ TEST_F(SessionTest, ReportUnstashedResources) { ASSERT_EQ( dateFromISOString(transactionDocument.getField("expiryTime").valueStringData()).getValue(), Date_t::fromMillisSinceEpoch(session.getSingleTransactionStats()->getStartTime() / 1000) + - stdx::chrono::seconds{transactionLifetimeLimitSeconds.load()}); + Seconds{transactionLifetimeLimitSeconds.load()}); // For the following time metrics, we are only verifying that the transaction sub-document is // being constructed correctly with proper types because we have other tests to verify that the // values are being tracked correctly. diff --git a/src/mongo/util/time_support.h b/src/mongo/util/time_support.h index f42c81567c8..457ff516469 100644 --- a/src/mongo/util/time_support.h +++ b/src/mongo/util/time_support.h @@ -178,7 +178,7 @@ public: template <typename Duration> Date_t& operator+=(Duration d) { - millis += duration_cast<Milliseconds>(d).count(); + *this = *this + d; return *this; } @@ -189,9 +189,7 @@ public: template <typename Duration> Date_t operator+(Duration d) const { - Date_t result = *this; - result += d; - return result; + return Date_t::fromDurationSinceEpoch(toDurationSinceEpoch() + d); } template <typename Duration> diff --git a/src/mongo/util/time_support_test.cpp b/src/mongo/util/time_support_test.cpp index 0dcd341ae9a..b827da75867 100644 --- a/src/mongo/util/time_support_test.cpp +++ b/src/mongo/util/time_support_test.cpp @@ -857,5 +857,41 @@ TEST(SystemTime, ConvertDateToSystemTime) { ASSERT_EQUALS(aDate, Date_t(aTimePoint)); } +TEST(DateTArithmetic, AdditionNoOverflowSucceeds) { + auto dateFromMillis = [](long long ms) { + return Date_t::fromDurationSinceEpoch(Milliseconds{ms}); + }; + + // Test operator+ + ASSERT_EQ(dateFromMillis(1001), dateFromMillis(1000) + Milliseconds{1}); + // Test operator+= + auto dateToIncrement = dateFromMillis(1000); + dateToIncrement += Milliseconds(1); + ASSERT_EQ(dateFromMillis(1001), dateToIncrement); +} + +TEST(DateTArithmetic, AdditionOverflowThrows) { + // Test operator+ + ASSERT_THROWS_CODE(Date_t::max() + Milliseconds(1), DBException, ErrorCodes::DurationOverflow); + // Test operator+= + auto dateToIncrement = Date_t::max(); + ASSERT_THROWS_CODE( + dateToIncrement += Milliseconds(1), DBException, ErrorCodes::DurationOverflow); + + // TODO (SERVER-38442): Can change Date_t::fromDurationSinceEpoch(Milliseconds::min()) to + // Date_t::min() once it's correct. + ASSERT_THROWS_CODE(Date_t::fromDurationSinceEpoch(Milliseconds::min()) + Milliseconds(-1), + DBException, + ErrorCodes::DurationOverflow); +} + +TEST(DateTArithmetic, SubtractionOverflowThrows) { + // TODO (SERVER-38442): Can change Date_t::fromDurationSinceEpoch(Milliseconds::min()) to + // Date_t::min() once it's correct. + ASSERT_THROWS_CODE(Date_t::fromDurationSinceEpoch(Milliseconds::min()) - Milliseconds(1), + DBException, + ErrorCodes::DurationOverflow); + ASSERT_THROWS_CODE(Date_t::max() - Milliseconds(-1), DBException, ErrorCodes::DurationOverflow); +} } // namespace } // namespace mongo |