aboutsummaryrefslogtreecommitdiff
path: root/util/alarm_unittest.cc
diff options
context:
space:
mode:
authorJordan Bayles <jophba@chromium.org>2019-07-10 14:44:58 -0700
committerCommit Bot <commit-bot@chromium.org>2019-07-10 23:11:04 +0000
commita26582d3cdec49e4fb0bd5c1da924bf7094f0f5e (patch)
treeb34b7153754e0b22e1a1b416291873be07a292a7 /util/alarm_unittest.cc
parentcc47180a8b4f86bcfce44aed3d51e1d302287a22 (diff)
downloadopenscreen-a26582d3cdec49e4fb0bd5c1da924bf7094f0f5e.tar.gz
Delete osp_base and move files to new homes
This patch is the second and major patch in the process of removing the osp_base folder from Open Screen. Based on the design plan here: https://docs.google.com/document/d/1LGV8tXdDeIH38MYlNF2XJNG49pec-64nWkS0jjnJNk4/edit#heading=h.ny8tc2v4ek9m This patch moves most of the files in osp_base to new homes in platform, excepting files that have been moved to the new util/ folder. Change-Id: I6e5f1d13cf20806bcc41185a842eb0b293606306 Reviewed-on: https://chromium-review.googlesource.com/c/openscreen/+/1695736 Reviewed-by: Jordan Bayles <jophba@chromium.org> Reviewed-by: mark a. foltz <mfoltz@chromium.org> Commit-Queue: Jordan Bayles <jophba@chromium.org>
Diffstat (limited to 'util/alarm_unittest.cc')
-rw-r--r--util/alarm_unittest.cc136
1 files changed, 136 insertions, 0 deletions
diff --git a/util/alarm_unittest.cc b/util/alarm_unittest.cc
new file mode 100644
index 00000000..71f570a0
--- /dev/null
+++ b/util/alarm_unittest.cc
@@ -0,0 +1,136 @@
+// Copyright 2019 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 "util/alarm.h"
+
+#include <algorithm>
+
+#include "gtest/gtest.h"
+#include "platform/test/fake_clock.h"
+#include "platform/test/fake_task_runner.h"
+
+namespace openscreen {
+namespace {
+
+class AlarmTest : public testing::Test {
+ public:
+ platform::FakeClock* clock() { return &clock_; }
+ platform::TaskRunner* task_runner() { return &task_runner_; }
+ Alarm* alarm() { return &alarm_; }
+
+ private:
+ platform::FakeClock clock_{platform::Clock::now()};
+ platform::FakeTaskRunner task_runner_{&clock_};
+ Alarm alarm_{&platform::FakeClock::now, &task_runner_};
+};
+
+TEST_F(AlarmTest, RunsTaskAsClockAdvances) {
+ constexpr platform::Clock::duration kDelay = std::chrono::milliseconds(20);
+
+ const platform::Clock::time_point alarm_time =
+ platform::FakeClock::now() + kDelay;
+ platform::Clock::time_point actual_run_time{};
+ alarm()->Schedule([&]() { actual_run_time = platform::FakeClock::now(); },
+ alarm_time);
+ // Confirm the lambda did not run immediately.
+ ASSERT_EQ(platform::Clock::time_point{}, actual_run_time);
+
+ // Confirm the lambda does not run until the necessary delay has elapsed.
+ clock()->Advance(kDelay / 2);
+ ASSERT_EQ(platform::Clock::time_point{}, actual_run_time);
+
+ // Confirm the lambda is called when the necessary delay has elapsed.
+ clock()->Advance(kDelay / 2);
+ ASSERT_EQ(alarm_time, actual_run_time);
+
+ // Confirm the lambda is only run once.
+ clock()->Advance(kDelay * 100);
+ ASSERT_EQ(alarm_time, actual_run_time);
+}
+
+TEST_F(AlarmTest, CancelsTaskWhenGoingOutOfScope) {
+ constexpr platform::Clock::duration kDelay = std::chrono::milliseconds(20);
+ constexpr platform::Clock::time_point kNever{};
+
+ platform::Clock::time_point actual_run_time{};
+ {
+ Alarm scoped_alarm(&platform::FakeClock::now, task_runner());
+ const platform::Clock::time_point alarm_time =
+ platform::FakeClock::now() + kDelay;
+ scoped_alarm.Schedule(
+ [&]() { actual_run_time = platform::FakeClock::now(); }, alarm_time);
+ // |scoped_alarm| is destroyed.
+ }
+
+ // Confirm the lambda has never and will never run.
+ ASSERT_EQ(kNever, actual_run_time);
+ clock()->Advance(kDelay * 100);
+ ASSERT_EQ(kNever, actual_run_time);
+}
+
+TEST_F(AlarmTest, Cancels) {
+ constexpr platform::Clock::duration kDelay = std::chrono::milliseconds(20);
+
+ const platform::Clock::time_point alarm_time =
+ platform::FakeClock::now() + kDelay;
+ platform::Clock::time_point actual_run_time{};
+ alarm()->Schedule([&]() { actual_run_time = platform::FakeClock::now(); },
+ alarm_time);
+
+ // Advance the clock for half the delay, and confirm the lambda has not run
+ // yet.
+ clock()->Advance(kDelay / 2);
+ ASSERT_EQ(platform::Clock::time_point{}, actual_run_time);
+
+ // Cancel and then advance the clock well past the delay, and confirm the
+ // lambda has never run.
+ alarm()->Cancel();
+ clock()->Advance(kDelay * 100);
+ ASSERT_EQ(platform::Clock::time_point{}, actual_run_time);
+}
+
+TEST_F(AlarmTest, CancelsAndRearms) {
+ constexpr platform::Clock::duration kShorterDelay =
+ std::chrono::milliseconds(10);
+ constexpr platform::Clock::duration kLongerDelay =
+ std::chrono::milliseconds(100);
+
+ // Run the test twice: Once when scheduling first with a long delay, then a
+ // shorter delay; and once when scheduling first with a short delay, then a
+ // longer delay. This is to test Alarm's internal scheduling/firing logic.
+ for (int do_longer_then_shorter = 0; do_longer_then_shorter <= 1;
+ ++do_longer_then_shorter) {
+ const auto delay1 = do_longer_then_shorter ? kLongerDelay : kShorterDelay;
+ const auto delay2 = do_longer_then_shorter ? kShorterDelay : kLongerDelay;
+
+ int count1 = 0;
+ alarm()->Schedule([&]() { ++count1; }, platform::FakeClock::now() + delay1);
+
+ // Advance the clock for half of |delay1|, and confirm the lambda that
+ // increments the variable does not run.
+ ASSERT_EQ(0, count1);
+ clock()->Advance(delay1 / 2);
+ ASSERT_EQ(0, count1);
+
+ // Schedule a different lambda, that increments a different variable, to run
+ // after |delay2|.
+ int count2 = 0;
+ alarm()->Schedule([&]() { ++count2; }, platform::FakeClock::now() + delay2);
+
+ // Confirm the second scheduling will fire at the right moment.
+ clock()->Advance(delay2 / 2);
+ ASSERT_EQ(0, count2);
+ clock()->Advance(delay2 / 2);
+ ASSERT_EQ(1, count2);
+
+ // Confirm the second scheduling never fires a second time, and also that
+ // the first one doesn't fire.
+ clock()->Advance(std::max(delay1, delay2) * 100);
+ ASSERT_EQ(0, count1);
+ ASSERT_EQ(1, count2);
+ }
+}
+
+} // namespace
+} // namespace openscreen