summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Morrow <acm@mongodb.com>2015-11-04 13:41:44 -0500
committerAndrew Morrow <acm@mongodb.com>2015-11-05 10:24:54 -0500
commit6c6f74c1d0e05bd14740c33ed703320b3c09d5ae (patch)
tree20869d234b38f486021c32053c027b5320570652
parentc616b481d7c82d3a44feb2e56aa7326446aed567 (diff)
downloadmongo-6c6f74c1d0e05bd14740c33ed703320b3c09d5ae.tar.gz
SERVER-21020 Make BackgroundJob unit tests deterministic
-rw-r--r--src/mongo/util/background_job_test.cpp93
1 files changed, 46 insertions, 47 deletions
diff --git a/src/mongo/util/background_job_test.cpp b/src/mongo/util/background_job_test.cpp
index 9c11cb5b9c2..1bd23d47792 100644
--- a/src/mongo/util/background_job_test.cpp
+++ b/src/mongo/util/background_job_test.cpp
@@ -27,7 +27,7 @@
#include "mongo/platform/basic.h"
-#include "mongo/db/server_options.h"
+#include "mongo/platform/atomic_word.h"
#include "mongo/stdx/mutex.h"
#include "mongo/stdx/thread.h"
#include "mongo/unittest/unittest.h"
@@ -37,6 +37,7 @@
namespace {
+using mongo::AtomicWord;
using mongo::BackgroundJob;
using mongo::MsgAssertionException;
using mongo::stdx::mutex;
@@ -44,69 +45,67 @@ using mongo::Notification;
namespace stdx = mongo::stdx;
-// a global variable that can be accessed independent of the IncTester object below
-// IncTester keeps it up-to-date
-int GLOBAL_val;
-
-class IncTester : public mongo::BackgroundJob {
+class TestJob final : public mongo::BackgroundJob {
public:
- explicit IncTester(long long millis, bool selfDelete = false)
- : mongo::BackgroundJob(selfDelete), _val(0), _millis(millis) {
- GLOBAL_val = 0;
+ TestJob(bool selfDelete,
+ AtomicWord<bool>* flag,
+ Notification* canProceed = nullptr,
+ Notification* destructorInvoked = nullptr)
+ : BackgroundJob(selfDelete),
+ _flag(flag),
+ _canProceed(canProceed),
+ _destructorInvoked(destructorInvoked) {}
+
+ ~TestJob() override {
+ if (_destructorInvoked)
+ _destructorInvoked->notifyOne();
}
- void waitAndInc(long long millis) {
- if (millis)
- mongo::sleepmillis(millis);
- ++_val;
- ++GLOBAL_val;
+ std::string name() const override {
+ return "TestJob";
}
- int getVal() {
- return _val;
- }
-
- /* --- BackgroundJob virtuals --- */
-
- std::string name() const {
- return "IncTester";
- }
-
- void run() {
- waitAndInc(_millis);
+ void run() override {
+ if (_canProceed)
+ _canProceed->waitToBeNotified();
+ _flag->store(true);
}
private:
- int _val;
- long long _millis;
+ AtomicWord<bool>* const _flag;
+ Notification* const _canProceed;
+ Notification* const _destructorInvoked;
};
TEST(BackgroundJobBasic, NormalCase) {
- IncTester tester(0 /* inc without wait */);
- tester.go();
- ASSERT(tester.wait());
- ASSERT_EQUALS(tester.getVal(), 1);
+ AtomicWord<bool> flag(false);
+ TestJob tj(false, &flag);
+ tj.go();
+ ASSERT(tj.wait());
+ ASSERT_EQUALS(true, flag.load());
}
TEST(BackgroundJobBasic, TimeOutCase) {
- IncTester tester(2000 /* wait 2 sec before inc-ing */);
- tester.go();
- ASSERT(!tester.wait(100 /* ms */)); // should time out
- ASSERT_EQUALS(tester.getVal(), 0);
-
- // if we wait longer than the IncTester, we should see the increment
- ASSERT(tester.wait(4000 /* ms */)); // should not time out
- ASSERT_EQUALS(tester.getVal(), 1);
+ AtomicWord<bool> flag(false);
+ Notification canProceed;
+ TestJob tj(false, &flag, &canProceed);
+ tj.go();
+
+ ASSERT(!tj.wait(1000));
+ ASSERT_EQUALS(false, flag.load());
+
+ canProceed.notifyOne();
+ ASSERT(tj.wait());
+ ASSERT_EQUALS(true, flag.load());
}
TEST(BackgroundJobBasic, SelfDeletingCase) {
- mongo::BackgroundJob* j = new IncTester(0 /* inc without wait */, true /* self delete */);
- j->go();
-
- // the background thread should have continued running and this test should pass the
- // heap-checker as well
- mongo::sleepmillis(1000);
- ASSERT_EQUALS(GLOBAL_val, 1);
+ AtomicWord<bool> flag(false);
+ Notification destructorInvoked;
+ // Though it looks like one, this is not a leak since the job is self deleting.
+ (new TestJob(true, &flag, nullptr, &destructorInvoked))->go();
+ destructorInvoked.waitToBeNotified();
+ ASSERT_EQUALS(true, flag.load());
}
TEST(BackgroundJobLifeCycle, Go) {