• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2019 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include "os/repeating_alarm.h"
18 
19 #include <future>
20 
21 #include "common/bind.h"
22 #include "gtest/gtest.h"
23 #include "os/fake_timer/fake_timerfd.h"
24 
25 namespace bluetooth {
26 namespace os {
27 namespace {
28 
29 using fake_timer::fake_timerfd_advance;
30 using fake_timer::fake_timerfd_reset;
31 
32 class RepeatingAlarmTest : public ::testing::Test {
33  protected:
SetUp()34   void SetUp() override {
35     thread_ = new Thread("test_thread", Thread::Priority::NORMAL);
36     handler_ = new Handler(thread_);
37     alarm_ = new RepeatingAlarm(handler_);
38   }
39 
TearDown()40   void TearDown() override {
41     delete alarm_;
42     handler_->Clear();
43     delete handler_;
44     delete thread_;
45     fake_timerfd_reset();
46   }
47 
VerifyMultipleDelayedTasks(int scheduled_tasks,int task_length_ms,int interval_between_tasks_ms)48   void VerifyMultipleDelayedTasks(int scheduled_tasks, int task_length_ms, int interval_between_tasks_ms) {
49     std::promise<void> promise;
50     auto future = promise.get_future();
51     auto start_time = std::chrono::steady_clock::now();
52     int counter = 0;
53     alarm_->Schedule(
54         common::Bind(
55             &RepeatingAlarmTest::verify_delayed_tasks,
56             common::Unretained(this),
57             common::Unretained(&counter),
58             start_time,
59             scheduled_tasks,
60             common::Unretained(&promise),
61             task_length_ms,
62             interval_between_tasks_ms),
63         std::chrono::milliseconds(interval_between_tasks_ms));
64     fake_timer_advance(interval_between_tasks_ms * scheduled_tasks);
65     future.get();
66     alarm_->Cancel();
67   }
68 
verify_delayed_tasks(int * counter,std::chrono::steady_clock::time_point start_time,int scheduled_tasks,std::promise<void> * promise,int task_length_ms,int interval_between_tasks_ms)69   void verify_delayed_tasks(
70       int* counter,
71       std::chrono::steady_clock::time_point start_time,
72       int scheduled_tasks,
73       std::promise<void>* promise,
74       int task_length_ms,
75       int interval_between_tasks_ms) {
76     *counter = *counter + 1;
77     if (*counter == scheduled_tasks) {
78       promise->set_value();
79     }
80   }
81 
fake_timer_advance(uint64_t ms)82   void fake_timer_advance(uint64_t ms) {
83     handler_->Post(common::BindOnce(fake_timerfd_advance, ms));
84   }
85 
86   RepeatingAlarm* alarm_;
87 
__anon1028ff1e0202null88   common::Closure should_not_happen_ = common::Bind([] { ASSERT_TRUE(false); });
89 
90  private:
91   Thread* thread_;
92   Handler* handler_;
93 };
94 
TEST_F(RepeatingAlarmTest,cancel_while_not_armed)95 TEST_F(RepeatingAlarmTest, cancel_while_not_armed) {
96   alarm_->Cancel();
97 }
98 
TEST_F(RepeatingAlarmTest,schedule)99 TEST_F(RepeatingAlarmTest, schedule) {
100   std::promise<void> promise;
101   auto future = promise.get_future();
102   int period_ms = 10;
103   alarm_->Schedule(
104       common::Bind(&std::promise<void>::set_value, common::Unretained(&promise)), std::chrono::milliseconds(period_ms));
105   fake_timer_advance(period_ms);
106   future.get();
107   alarm_->Cancel();
108   ASSERT_FALSE(future.valid());
109 }
110 
TEST_F(RepeatingAlarmTest,cancel_alarm)111 TEST_F(RepeatingAlarmTest, cancel_alarm) {
112   alarm_->Schedule(should_not_happen_, std::chrono::milliseconds(10));
113   alarm_->Cancel();
114   std::this_thread::sleep_for(std::chrono::milliseconds(50));
115 }
116 
TEST_F(RepeatingAlarmTest,cancel_alarm_from_callback)117 TEST_F(RepeatingAlarmTest, cancel_alarm_from_callback) {
118   alarm_->Schedule(
119       common::Bind(&RepeatingAlarm::Cancel, common::Unretained(this->alarm_)), std::chrono::milliseconds(1));
120   std::this_thread::sleep_for(std::chrono::milliseconds(5));
121 }
122 
TEST_F(RepeatingAlarmTest,schedule_while_alarm_armed)123 TEST_F(RepeatingAlarmTest, schedule_while_alarm_armed) {
124   alarm_->Schedule(should_not_happen_, std::chrono::milliseconds(1));
125   std::promise<void> promise;
126   auto future = promise.get_future();
127   alarm_->Schedule(
128       common::Bind(&std::promise<void>::set_value, common::Unretained(&promise)), std::chrono::milliseconds(10));
129   fake_timer_advance(10);
130   future.get();
131   alarm_->Cancel();
132 }
133 
TEST_F(RepeatingAlarmTest,delete_while_alarm_armed)134 TEST_F(RepeatingAlarmTest, delete_while_alarm_armed) {
135   alarm_->Schedule(should_not_happen_, std::chrono::milliseconds(1));
136   delete alarm_;
137   alarm_ = nullptr;
138   std::this_thread::sleep_for(std::chrono::milliseconds(1));
139 }
140 
TEST_F(RepeatingAlarmTest,verify_small)141 TEST_F(RepeatingAlarmTest, verify_small) {
142   VerifyMultipleDelayedTasks(100, 1, 10);
143 }
144 
TEST_F(RepeatingAlarmTest,verify_large)145 TEST_F(RepeatingAlarmTest, verify_large) {
146   VerifyMultipleDelayedTasks(100, 3, 10);
147 }
148 
149 }  // namespace
150 }  // namespace os
151 }  // namespace bluetooth
152