• 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 "gtest/gtest.h"
22 
23 namespace bluetooth {
24 namespace os {
25 namespace {
26 
27 constexpr int error_ms = 20;
28 
29 class RepeatingAlarmTest : public ::testing::Test {
30  protected:
SetUp()31   void SetUp() override {
32     thread_ = new Thread("test_thread", Thread::Priority::NORMAL);
33     alarm_ = new RepeatingAlarm(thread_);
34   }
35 
TearDown()36   void TearDown() override {
37     delete alarm_;
38     delete thread_;
39   }
40 
VerifyMultipleDelayedTasks(int scheduled_tasks,int task_length_ms,int interval_between_tasks_ms)41   void VerifyMultipleDelayedTasks(int scheduled_tasks, int task_length_ms, int interval_between_tasks_ms) {
42     std::promise<void> promise;
43     auto future = promise.get_future();
44     auto start_time = std::chrono::steady_clock::now();
45     int counter = 0;
46     alarm_->Schedule(
47         [&counter, &promise, start_time, scheduled_tasks, task_length_ms, interval_between_tasks_ms]() {
48           counter++;
49           auto time_now = std::chrono::steady_clock::now();
50           auto time_delta = time_now - start_time;
51           if (counter == scheduled_tasks) {
52             promise.set_value();
53           }
54           ASSERT_NEAR(time_delta.count(), interval_between_tasks_ms * 1000000 * counter, error_ms * 1000000);
55           std::this_thread::sleep_for(std::chrono::milliseconds(task_length_ms));
56         },
57         std::chrono::milliseconds(interval_between_tasks_ms));
58     future.get();
59     alarm_->Cancel();
60   }
61 
62   RepeatingAlarm* alarm_;
63 
64  private:
65   Thread* thread_;
66 };
67 
TEST_F(RepeatingAlarmTest,cancel_while_not_armed)68 TEST_F(RepeatingAlarmTest, cancel_while_not_armed) {
69   alarm_->Cancel();
70 }
71 
TEST_F(RepeatingAlarmTest,schedule)72 TEST_F(RepeatingAlarmTest, schedule) {
73   std::promise<void> promise;
74   auto future = promise.get_future();
75   auto before = std::chrono::steady_clock::now();
76   int period_ms = 10;
77   alarm_->Schedule([&promise]() { promise.set_value(); }, std::chrono::milliseconds(period_ms));
78   future.get();
79   alarm_->Cancel();
80   auto after = std::chrono::steady_clock::now();
81   auto duration = after - before;
82   ASSERT_NEAR(duration.count(), period_ms * 1000000, error_ms * 1000000);
83 }
84 
TEST_F(RepeatingAlarmTest,cancel_alarm)85 TEST_F(RepeatingAlarmTest, cancel_alarm) {
86   alarm_->Schedule([]() { ASSERT_TRUE(false); }, std::chrono::milliseconds(1));
87   alarm_->Cancel();
88   std::this_thread::sleep_for(std::chrono::milliseconds(5));
89 }
90 
TEST_F(RepeatingAlarmTest,cancel_alarm_from_callback)91 TEST_F(RepeatingAlarmTest, cancel_alarm_from_callback) {
92   alarm_->Schedule([this]() { this->alarm_->Cancel(); }, std::chrono::milliseconds(1));
93   std::this_thread::sleep_for(std::chrono::milliseconds(5));
94 }
95 
TEST_F(RepeatingAlarmTest,schedule_while_alarm_armed)96 TEST_F(RepeatingAlarmTest, schedule_while_alarm_armed) {
97   alarm_->Schedule([]() { ASSERT_TRUE(false); }, std::chrono::milliseconds(1));
98   std::promise<void> promise;
99   auto future = promise.get_future();
100   alarm_->Schedule([&promise]() { promise.set_value(); }, std::chrono::milliseconds(10));
101   future.get();
102   alarm_->Cancel();
103 }
104 
TEST_F(RepeatingAlarmTest,delete_while_alarm_armed)105 TEST_F(RepeatingAlarmTest, delete_while_alarm_armed) {
106   alarm_->Schedule([]() { ASSERT_TRUE(false); }, std::chrono::milliseconds(1));
107   delete alarm_;
108   alarm_ = nullptr;
109   std::this_thread::sleep_for(std::chrono::milliseconds(1));
110 }
111 
TEST_F(RepeatingAlarmTest,verify_small)112 TEST_F(RepeatingAlarmTest, verify_small) {
113   VerifyMultipleDelayedTasks(100, 1, 10);
114 }
115 
TEST_F(RepeatingAlarmTest,verify_large)116 TEST_F(RepeatingAlarmTest, verify_large) {
117   VerifyMultipleDelayedTasks(100, 3, 10);
118 }
119 
120 }  // namespace
121 }  // namespace os
122 }  // namespace bluetooth
123