blob: 490958b3dcbb8f7d805a19e00ed63c43c95c62ec [file] [log] [blame]
// Copyright 2019 The Fuchsia 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 "fuchsia_clock.h"
#include <lib/syslog/cpp/macros.h>
#include <lib/zx/clock.h>
#include <lib/zx/time.h>
#include <optional>
#include <gtest/gtest.h>
#include "src/lib/testing/loop_fixture/test_loop_fixture.h"
#include "src/lib/timekeeper/test_clock.h"
class FuchsiaClockTest : public gtest::TestLoopFixture {
public:
FuchsiaClockTest() {
zx_clock_create_args_v1_t clock_args{.backstop_time = 0};
FX_CHECK(zx::clock::create(ZX_CLOCK_ARGS_VERSION(1), &clock_args,
&clock_handle_) == ZX_OK);
}
protected:
zx::clock clock_handle_;
};
TEST_F(FuchsiaClockTest, BeforeSignalOptionalsAreEmpty) {
std::unique_ptr<timekeeper::TestClock> test_clock =
std::make_unique<timekeeper::TestClock>();
harvester::FuchsiaClock clock(dispatcher(), std::move(test_clock),
zx::unowned_clock(clock_handle_.get_handle()));
EXPECT_EQ(clock.now(), std::nullopt);
EXPECT_EQ(clock.nanoseconds(), std::nullopt);
}
TEST_F(FuchsiaClockTest, BeforeWaitForStartOptionalsAreEmpty) {
std::unique_ptr<timekeeper::TestClock> test_clock =
std::make_unique<timekeeper::TestClock>();
constexpr zx::time start_time(
(zx::hour(9) + zx::min(31) + zx::sec(42)).get());
test_clock->Set(start_time);
harvester::FuchsiaClock clock(dispatcher(), std::move(test_clock),
zx::unowned_clock(clock_handle_.get_handle()));
clock_handle_.update(zx::clock::update_args{}.set_value(start_time));
EXPECT_EQ(clock.now(), std::nullopt);
EXPECT_EQ(clock.nanoseconds(), std::nullopt);
}
TEST_F(FuchsiaClockTest, AfterWaitForStartOptionalsAreStillEmptyIfNotStarted) {
std::unique_ptr<timekeeper::TestClock> test_clock =
std::make_unique<timekeeper::TestClock>();
harvester::FuchsiaClock clock(dispatcher(), std::move(test_clock),
zx::unowned_clock(clock_handle_.get_handle()));
clock.WaitForStart([](zx_status_t status) {});
RunLoopUntilIdle();
EXPECT_EQ(clock.now(), std::nullopt);
EXPECT_EQ(clock.nanoseconds(), std::nullopt);
}
TEST_F(FuchsiaClockTest, AfterWaitForStartHasValuesIfAlreadyStarted) {
std::unique_ptr<timekeeper::TestClock> test_clock =
std::make_unique<timekeeper::TestClock>();
constexpr zx::time start_time(
(zx::hour(9) + zx::min(31) + zx::sec(42)).get());
test_clock->Set(start_time);
harvester::FuchsiaClock clock(dispatcher(), std::move(test_clock),
zx::unowned_clock(clock_handle_.get_handle()));
clock_handle_.update(zx::clock::update_args().set_value(start_time));
bool isCalled = false;
clock.WaitForStart([&isCalled](zx_status_t status) {
isCalled = true;
EXPECT_EQ(status, ZX_OK);
});
EXPECT_TRUE(isCalled);
EXPECT_TRUE(clock.now().has_value());
EXPECT_TRUE(clock.nanoseconds().has_value());
}
TEST_F(FuchsiaClockTest, WaitWorksAsyncAndMakesClockAvailable) {
std::unique_ptr<timekeeper::TestClock> test_clock =
std::make_unique<timekeeper::TestClock>();
constexpr zx::time start_time(
(zx::hour(9) + zx::min(31) + zx::sec(42)).get());
test_clock->Set(start_time);
harvester::FuchsiaClock clock(dispatcher(), std::move(test_clock),
zx::unowned_clock(clock_handle_.get_handle()));
bool isCalled = false;
clock.WaitForStart([&isCalled](zx_status_t status) {
isCalled = true;
EXPECT_EQ(status, ZX_OK);
});
RunLoopUntilIdle();
EXPECT_FALSE(isCalled);
EXPECT_FALSE(clock.now().has_value());
EXPECT_FALSE(clock.nanoseconds().has_value());
EXPECT_EQ(
clock_handle_.update(zx::clock::update_args().set_value(start_time)),
ZX_OK);
RunLoopUntilIdle();
EXPECT_TRUE(isCalled);
EXPECT_TRUE(clock.now().has_value());
EXPECT_TRUE(clock.nanoseconds().has_value());
}