forked from chromium/chromium
-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy paththread_health_checker_unittest.cc
105 lines (90 loc) · 4.11 KB
/
thread_health_checker_unittest.cc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chromecast/base/thread_health_checker.h"
#include "base/memory/ref_counted.h"
#include "base/synchronization/waitable_event.h"
#include "base/test/test_mock_time_task_runner.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace chromecast {
namespace {
const base::TimeDelta kInterval = base::TimeDelta::FromSeconds(3);
const base::TimeDelta kTimeout = base::TimeDelta::FromSeconds(2);
} // namespace
class ThreadHealthCheckerTest : public ::testing::Test {
protected:
ThreadHealthCheckerTest()
: patient_(base::MakeRefCounted<base::TestMockTimeTaskRunner>()),
doctor_(base::MakeRefCounted<base::TestMockTimeTaskRunner>()),
event_(base::WaitableEvent::ResetPolicy::MANUAL,
base::WaitableEvent::InitialState::NOT_SIGNALED) {}
~ThreadHealthCheckerTest() override{};
scoped_refptr<base::TestMockTimeTaskRunner> patient_;
scoped_refptr<base::TestMockTimeTaskRunner> doctor_;
base::WaitableEvent event_;
};
#define CREATE_THREAD_HEALTH_CHECKER(name) \
ThreadHealthChecker name(patient_, doctor_, kInterval, kTimeout, \
base::BindRepeating(&base::WaitableEvent::Signal, \
base::Unretained(&event_)))
TEST_F(ThreadHealthCheckerTest, FiresTimeoutWhenTaskRunnerDoesNotFlush) {
CREATE_THREAD_HEALTH_CHECKER(thc);
// Do not flush the patient, so that the health check sentinel task won't run.
doctor_->FastForwardBy(base::TimeDelta::FromSeconds(6));
EXPECT_TRUE(event_.IsSignaled());
}
TEST_F(ThreadHealthCheckerTest, DoesNotFireTimeoutWhenTaskRunnerFlushesInTime) {
CREATE_THREAD_HEALTH_CHECKER(thc);
// Advance the doctor by enough time to post the health check, but not to time
// out.
doctor_->FastForwardBy(base::TimeDelta::FromSeconds(4));
// Advance the patient to let the sentinel task run.
patient_->FastForwardBy(base::TimeDelta::FromSeconds(4));
// Advance the doctor by enough time such that the sentinel not running would
// cause the failure callback to run.
doctor_->FastForwardBy(base::TimeDelta::FromSeconds(2));
EXPECT_FALSE(event_.IsSignaled());
}
TEST_F(ThreadHealthCheckerTest, FiresTimeoutWhenTaskRunnerFlushesTooLate) {
CREATE_THREAD_HEALTH_CHECKER(thc);
// Advance the doctor before the patient, to simulate a task in the patient
// that takes too long.
doctor_->FastForwardBy(base::TimeDelta::FromSeconds(6));
patient_->FastForwardBy(base::TimeDelta::FromSeconds(6));
// Flush the task runner so the health check sentinel task is run.
EXPECT_TRUE(event_.IsSignaled());
}
TEST_F(ThreadHealthCheckerTest, FiresTimeoutOnLaterIteration) {
CREATE_THREAD_HEALTH_CHECKER(thc);
// Advance the doctor enough to start the check.
doctor_->FastForwardBy(base::TimeDelta::FromSeconds(4));
// Advance the patient enough to run the task.
patient_->FastForwardBy(base::TimeDelta::FromSeconds(4));
// Advance the doctor enough to start the check again.
doctor_->FastForwardBy(base::TimeDelta::FromSeconds(4));
EXPECT_FALSE(event_.IsSignaled());
// Advance the doctor enough for the timeout from the second check to fire.
doctor_->FastForwardBy(base::TimeDelta::FromSeconds(2));
EXPECT_TRUE(event_.IsSignaled());
}
TEST_F(ThreadHealthCheckerTest, NoCrashWhenDestroyed) {
{
CREATE_THREAD_HEALTH_CHECKER(thc);
doctor_->RunUntilIdle();
}
doctor_->RunUntilIdle();
}
TEST_F(ThreadHealthCheckerTest, DropPendingEventsAfterDestruction) {
{
CREATE_THREAD_HEALTH_CHECKER(thc);
// Fast forward by enough time to have scheduled a health check.
doctor_->FastForwardBy(base::TimeDelta::FromSeconds(4));
EXPECT_FALSE(event_.IsSignaled());
}
// Fast forward by enough time for the health check to have executed.
// However, we want all pending events to be dropped after the destructor is
// called, so the event should not be signalled.
doctor_->FastForwardBy(base::TimeDelta::FromSeconds(2));
EXPECT_FALSE(event_.IsSignaled());
}
} // namespace chromecast