mirror of
https://github.com/kidfromjupiter/nearby.git
synced 2026-09-14 14:46:12 -04:00
Migrate fake functions to third_party/nearby to help unit test
PiperOrigin-RevId: 517433481
This commit is contained in:
committed by
Copybara-Service
parent
94ff506d1e
commit
86ca85b85a
@@ -422,6 +422,7 @@ let package = Package(
|
||||
"internal/flags/BUILD",
|
||||
"internal/network/BUILD",
|
||||
"internal/base/BUILD",
|
||||
"internal/test/BUILD",
|
||||
// tests
|
||||
"connections/listeners_test.cc",
|
||||
"connections/strategy_test.cc",
|
||||
@@ -538,6 +539,10 @@ let package = Package(
|
||||
"internal/network/http_request_test.cc",
|
||||
"internal/network/http_client_impl_test.cc",
|
||||
"internal/network/http_status_code_test.cc",
|
||||
"internal/test/fake_clock_test.cc",
|
||||
"internal/test/fake_timer_test.cc",
|
||||
"internal/test/fake_device_info_test.cc",
|
||||
"internal/test/fake_task_runner_test.cc",
|
||||
// simulation
|
||||
"connections/implementation/offline_simulation_user.cc",
|
||||
"connections/implementation/simulation_user.cc",
|
||||
|
||||
@@ -354,6 +354,7 @@ cc_library(
|
||||
"//fastpair:__subpackages__",
|
||||
"//internal/flags:__subpackages__",
|
||||
"//internal/platform/implementation/windows:__subpackages__",
|
||||
"//internal/test:__subpackages__",
|
||||
"//location/nearby/cpp:__subpackages__",
|
||||
"//location/nearby/testing/nearby_native:__subpackages__",
|
||||
"//presence:__subpackages__",
|
||||
|
||||
@@ -42,6 +42,7 @@ cc_library(
|
||||
"//fastpair:__subpackages__",
|
||||
"//internal/platform:__pkg__",
|
||||
"//internal/platform/implementation:__subpackages__",
|
||||
"//internal/test:__subpackages__",
|
||||
"//location/nearby/analytics/cpp:__subpackages__",
|
||||
"//presence:__subpackages__",
|
||||
],
|
||||
|
||||
@@ -132,6 +132,7 @@ cc_library(
|
||||
"//internal/network:__subpackages__",
|
||||
"//internal/platform:__subpackages__",
|
||||
"//internal/proto/analytics:__subpackages__",
|
||||
"//internal/test:__subpackages__",
|
||||
"//location/nearby/cpp:__subpackages__",
|
||||
"//presence:__subpackages__",
|
||||
],
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
licenses(["notice"])
|
||||
|
||||
cc_library(
|
||||
name = "test",
|
||||
srcs = [
|
||||
"fake_clock.cc",
|
||||
"fake_task_runner.cc",
|
||||
"fake_timer.cc",
|
||||
],
|
||||
hdrs = [
|
||||
"fake_clock.h",
|
||||
"fake_device_info.h",
|
||||
"fake_task_runner.h",
|
||||
"fake_timer.h",
|
||||
],
|
||||
copts = [
|
||||
"-Ithird_party",
|
||||
],
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//internal/base:bluetooth_address",
|
||||
"//internal/platform:types",
|
||||
"//internal/platform/implementation:types",
|
||||
"@com_google_absl//absl/base:core_headers",
|
||||
"@com_google_absl//absl/container:flat_hash_map",
|
||||
"@com_google_absl//absl/strings",
|
||||
"@com_google_absl//absl/synchronization",
|
||||
"@com_google_absl//absl/time",
|
||||
"@com_google_absl//absl/types:span", # fixdeps: keep
|
||||
],
|
||||
)
|
||||
|
||||
cc_test(
|
||||
name = "test_test",
|
||||
size = "small",
|
||||
timeout = "short",
|
||||
srcs = [
|
||||
"fake_clock_test.cc",
|
||||
"fake_device_info_test.cc",
|
||||
"fake_task_runner_test.cc",
|
||||
"fake_timer_test.cc",
|
||||
],
|
||||
copts = [
|
||||
"-Ithird_party",
|
||||
],
|
||||
shard_count = 8,
|
||||
deps = [
|
||||
":test",
|
||||
"//internal/platform:types",
|
||||
"//internal/platform/implementation:types",
|
||||
"//internal/platform/implementation/g3",
|
||||
"@com_github_protobuf_matchers//protobuf-matchers",
|
||||
"@com_google_absl//absl/time",
|
||||
"@com_google_googletest//:gtest_main",
|
||||
],
|
||||
)
|
||||
@@ -0,0 +1,71 @@
|
||||
// Copyright 2021 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "internal/test/fake_clock.h"
|
||||
|
||||
#include <functional>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
namespace nearby {
|
||||
|
||||
absl::Time FakeClock::Now() const { return now_; }
|
||||
|
||||
void FakeClock::AddObserver(absl::string_view name,
|
||||
std::function<void()> observer) {
|
||||
absl::MutexLock lock(&mutex_);
|
||||
observers_.emplace(name, std::move(observer));
|
||||
}
|
||||
|
||||
void FakeClock::RemoveObserver(absl::string_view name) {
|
||||
absl::MutexLock lock(&mutex_);
|
||||
observers_.erase(name);
|
||||
}
|
||||
|
||||
void FakeClock::FastForward(absl::Duration duration) {
|
||||
std::vector<std::string> timer_callback_ids;
|
||||
now_ += duration;
|
||||
{
|
||||
absl::MutexLock lock(&mutex_);
|
||||
for (const auto& observer : observers_) {
|
||||
timer_callback_ids.push_back(observer.first);
|
||||
}
|
||||
}
|
||||
|
||||
for (const auto& timer_callback_id : timer_callback_ids) {
|
||||
// Timer may be closed during other timer running, so only run callback
|
||||
// on available timers.
|
||||
bool is_alive_timer = true;
|
||||
std::function<void()> callback;
|
||||
|
||||
{
|
||||
absl::MutexLock lock(&mutex_);
|
||||
is_alive_timer = observers_.contains(timer_callback_id);
|
||||
if (!is_alive_timer) {
|
||||
continue;
|
||||
}
|
||||
callback = observers_[timer_callback_id];
|
||||
}
|
||||
|
||||
callback();
|
||||
}
|
||||
}
|
||||
|
||||
int FakeClock::GetObserversCount() {
|
||||
absl::MutexLock lock(&mutex_);
|
||||
return observers_.size();
|
||||
}
|
||||
|
||||
} // namespace nearby
|
||||
@@ -0,0 +1,55 @@
|
||||
// Copyright 2021 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef THIRD_PARTY_NEARBY_INTERNAL_TEST_FAKE_CLOCK_H_
|
||||
#define THIRD_PARTY_NEARBY_INTERNAL_TEST_FAKE_CLOCK_H_
|
||||
|
||||
#include <functional>
|
||||
#include <string>
|
||||
|
||||
#include "absl/base/thread_annotations.h"
|
||||
#include "absl/container/flat_hash_map.h"
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "absl/synchronization/mutex.h"
|
||||
#include "absl/time/clock.h"
|
||||
#include "absl/time/time.h"
|
||||
#include "internal/platform/clock.h"
|
||||
|
||||
namespace nearby {
|
||||
|
||||
class FakeClock : public Clock {
|
||||
public:
|
||||
FakeClock() { now_ = absl::Now(); }
|
||||
FakeClock(FakeClock&&) = default;
|
||||
FakeClock& operator=(FakeClock&&) = default;
|
||||
|
||||
absl::Time Now() const override;
|
||||
|
||||
void AddObserver(absl::string_view name, std::function<void()> observer)
|
||||
ABSL_LOCKS_EXCLUDED(mutex_);
|
||||
void RemoveObserver(absl::string_view name) ABSL_LOCKS_EXCLUDED(mutex_);
|
||||
|
||||
void FastForward(absl::Duration duration);
|
||||
|
||||
int GetObserversCount() ABSL_LOCKS_EXCLUDED(mutex_);
|
||||
|
||||
private:
|
||||
absl::Time now_;
|
||||
mutable absl::Mutex mutex_;
|
||||
absl::flat_hash_map<std::string, std::function<void()>> observers_
|
||||
ABSL_GUARDED_BY(mutex_);
|
||||
};
|
||||
} // namespace nearby
|
||||
|
||||
#endif // THIRD_PARTY_NEARBY_INTERNAL_TEST_FAKE_CLOCK_H_
|
||||
@@ -0,0 +1,53 @@
|
||||
// Copyright 2021 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "internal/test/fake_clock.h"
|
||||
|
||||
#include "gmock/gmock.h"
|
||||
#include "protobuf-matchers/protocol-buffer-matchers.h"
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
namespace nearby {
|
||||
namespace {
|
||||
|
||||
TEST(FakeClock, TestGetCurrentTime) {
|
||||
FakeClock clock;
|
||||
EXPECT_GT(absl::ToUnixNanos(clock.Now()), 0);
|
||||
}
|
||||
|
||||
TEST(FakeClock, TestFastForward) {
|
||||
FakeClock clock;
|
||||
absl::Time time1 = clock.Now();
|
||||
clock.FastForward(absl::Nanoseconds(1500));
|
||||
absl::Time time2 = clock.Now();
|
||||
EXPECT_EQ(absl::ToUnixNanos(time1) + 1500, absl::ToUnixNanos(time2));
|
||||
EXPECT_EQ(clock.GetObserversCount(), 0);
|
||||
}
|
||||
|
||||
TEST(FakeClock, TestObserver) {
|
||||
FakeClock clock;
|
||||
int count = 0;
|
||||
auto observer = [&count]() { count++; };
|
||||
clock.AddObserver("test", observer);
|
||||
clock.FastForward(absl::Nanoseconds(1500));
|
||||
EXPECT_EQ(count, 1);
|
||||
clock.FastForward(absl::Nanoseconds(1500));
|
||||
EXPECT_EQ(count, 2);
|
||||
clock.RemoveObserver("test");
|
||||
clock.FastForward(absl::Nanoseconds(1500));
|
||||
EXPECT_EQ(count, 2);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace nearby
|
||||
@@ -0,0 +1,179 @@
|
||||
// Copyright 2022 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef THIRD_PARTY_NEARBY_INTERNAL_TEST_FAKE_DEVICE_INFO_H_
|
||||
#define THIRD_PARTY_NEARBY_INTERNAL_TEST_FAKE_DEVICE_INFO_H_
|
||||
|
||||
#include <filesystem>
|
||||
#include <functional>
|
||||
#include <limits>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
|
||||
#include "absl/container/flat_hash_map.h"
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "internal/base/bluetooth_address.h"
|
||||
#include "internal/platform/device_info.h"
|
||||
#include "internal/platform/implementation/device_info.h"
|
||||
|
||||
namespace nearby {
|
||||
|
||||
class FakeDeviceInfo : public DeviceInfo {
|
||||
public:
|
||||
std::u16string GetOsDeviceName() const override { return device_name_; }
|
||||
|
||||
api::DeviceInfo::DeviceType GetDeviceType() const override {
|
||||
return device_type_;
|
||||
}
|
||||
|
||||
api::DeviceInfo::OsType GetOsType() const override { return os_type_; }
|
||||
|
||||
std::optional<std::u16string> GetFullName() const override {
|
||||
return full_name_;
|
||||
}
|
||||
std::optional<std::u16string> GetGivenName() const override {
|
||||
return given_name_;
|
||||
}
|
||||
std::optional<std::u16string> GetLastName() const override {
|
||||
return last_name_;
|
||||
}
|
||||
std::optional<std::string> GetProfileUserName() const override {
|
||||
return profile_user_name_;
|
||||
}
|
||||
|
||||
std::filesystem::path GetDownloadPath() const override {
|
||||
return download_path_;
|
||||
}
|
||||
|
||||
std::filesystem::path GetAppDataPath() const override {
|
||||
return app_data_path_;
|
||||
}
|
||||
|
||||
std::filesystem::path GetTemporaryPath() const override { return temp_path_; }
|
||||
|
||||
std::optional<size_t> GetAvailableDiskSpaceInBytes(
|
||||
const std::filesystem::path& path) const override {
|
||||
std::wstring path_key = path.wstring();
|
||||
auto it = available_space_map_.find(path_key);
|
||||
if (it != available_space_map_.end()) {
|
||||
return it->second;
|
||||
}
|
||||
return std::numeric_limits<int64_t>::max();
|
||||
}
|
||||
|
||||
bool IsScreenLocked() const override { return is_screen_locked_; }
|
||||
|
||||
void RegisterScreenLockedListener(
|
||||
absl::string_view listener_name,
|
||||
std::function<void(api::DeviceInfo::ScreenStatus)> callback) override {
|
||||
screen_locked_listeners_.emplace(listener_name, callback);
|
||||
}
|
||||
|
||||
void UnregisterScreenLockedListener(
|
||||
absl::string_view listener_name) override {
|
||||
screen_locked_listeners_.erase(listener_name);
|
||||
}
|
||||
|
||||
int GetScreenLockedListenerCount() { return screen_locked_listeners_.size(); }
|
||||
|
||||
// Mock methods.
|
||||
void SetOsDeviceName(std::u16string_view device_name) {
|
||||
device_name_ = device_name;
|
||||
}
|
||||
|
||||
void SetDeviceType(api::DeviceInfo::DeviceType device_type) {
|
||||
device_type_ = device_type;
|
||||
}
|
||||
|
||||
void SetOsType(api::DeviceInfo::OsType os_type) { os_type_ = os_type; }
|
||||
|
||||
void SetFullName(std::optional<std::u16string> full_name) {
|
||||
if (full_name.has_value() && !full_name->empty()) {
|
||||
full_name_ = full_name;
|
||||
} else {
|
||||
full_name_ = std::nullopt;
|
||||
}
|
||||
}
|
||||
|
||||
void SetGivenName(std::optional<std::u16string> given_name) {
|
||||
if (given_name.has_value() && !given_name->empty()) {
|
||||
given_name_ = given_name;
|
||||
} else {
|
||||
given_name_ = std::nullopt;
|
||||
}
|
||||
}
|
||||
|
||||
void SetLastName(std::optional<std::u16string> last_name) {
|
||||
if (last_name.has_value() && !last_name->empty()) {
|
||||
last_name_ = last_name;
|
||||
} else {
|
||||
last_name_ = std::nullopt;
|
||||
}
|
||||
}
|
||||
|
||||
void SetProfileUserName(std::optional<std::string> profile_user_name) {
|
||||
if (profile_user_name.has_value() && !profile_user_name->empty()) {
|
||||
profile_user_name_ = profile_user_name;
|
||||
} else {
|
||||
profile_user_name_ = std::nullopt;
|
||||
}
|
||||
}
|
||||
|
||||
void SetDownloadPath(std::filesystem::path path) { download_path_ = path; }
|
||||
|
||||
void SetAppDataPath(std::filesystem::path path) { app_data_path_ = path; }
|
||||
|
||||
void SetTemporaryPath(std::filesystem::path path) { temp_path_ = path; }
|
||||
|
||||
void SetAvailableDiskSpaceInBytes(const std::filesystem::path& path,
|
||||
size_t available_bytes) {
|
||||
available_space_map_.emplace(path.wstring(), available_bytes);
|
||||
}
|
||||
|
||||
void ResetDiskSpace() { available_space_map_.clear(); }
|
||||
|
||||
void SetScreenLocked(bool locked) {
|
||||
is_screen_locked_ = locked;
|
||||
for (auto& listener : screen_locked_listeners_) {
|
||||
if (locked) {
|
||||
listener.second(api::DeviceInfo::ScreenStatus::kLocked);
|
||||
} else {
|
||||
listener.second(api::DeviceInfo::ScreenStatus::kUnlocked);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
std::u16string device_name_ = u"nearby";
|
||||
api::DeviceInfo::DeviceType device_type_ =
|
||||
api::DeviceInfo::DeviceType::kLaptop;
|
||||
api::DeviceInfo::OsType os_type_ = api::DeviceInfo::OsType::kWindows;
|
||||
std::optional<std::u16string> full_name_ = u"Nearby";
|
||||
std::optional<std::u16string> given_name_ = u"Nearby";
|
||||
std::optional<std::u16string> last_name_ = u"Nearby";
|
||||
std::optional<std::string> profile_user_name_ = "nearby";
|
||||
std::filesystem::path download_path_ = std::filesystem::temp_directory_path();
|
||||
std::filesystem::path app_data_path_ = std::filesystem::temp_directory_path();
|
||||
std::filesystem::path temp_path_ = std::filesystem::temp_directory_path();
|
||||
absl::flat_hash_map<std::wstring, size_t> available_space_map_;
|
||||
absl::flat_hash_map<std::string,
|
||||
std::function<void(api::DeviceInfo::ScreenStatus)>>
|
||||
screen_locked_listeners_;
|
||||
bool is_screen_locked_ = false;
|
||||
};
|
||||
|
||||
} // namespace nearby
|
||||
|
||||
#endif // THIRD_PARTY_NEARBY_INTERNAL_TEST_FAKE_DEVICE_INFO_H_
|
||||
@@ -0,0 +1,192 @@
|
||||
// Copyright 2021 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "internal/test/fake_device_info.h"
|
||||
|
||||
#include <array>
|
||||
#include <filesystem>
|
||||
#include <functional>
|
||||
#include <optional>
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
#include "internal/platform/implementation/device_info.h"
|
||||
|
||||
namespace nearby {
|
||||
namespace {
|
||||
|
||||
TEST(FakeDeviceInfo, DeviceName) {
|
||||
FakeDeviceInfo device_info;
|
||||
device_info.SetOsDeviceName(u"windows");
|
||||
EXPECT_EQ(device_info.GetOsDeviceName(), u"windows");
|
||||
}
|
||||
|
||||
TEST(FakeDeviceInfo, DeviceType) {
|
||||
FakeDeviceInfo device_info;
|
||||
device_info.SetDeviceType(api::DeviceInfo::DeviceType::kPhone);
|
||||
EXPECT_EQ(device_info.GetDeviceType(), api::DeviceInfo::DeviceType::kPhone);
|
||||
}
|
||||
|
||||
TEST(FakeDeviceInfo, OsType) {
|
||||
FakeDeviceInfo device_info;
|
||||
device_info.SetOsType(api::DeviceInfo::OsType::kWindows);
|
||||
EXPECT_EQ(device_info.GetOsType(), api::DeviceInfo::OsType::kWindows);
|
||||
}
|
||||
|
||||
TEST(FakeDeviceInfo, FullName) {
|
||||
FakeDeviceInfo device_info;
|
||||
device_info.SetFullName(u"windows");
|
||||
EXPECT_EQ(device_info.GetFullName(), u"windows");
|
||||
device_info.SetFullName(std::nullopt);
|
||||
EXPECT_FALSE(device_info.GetFullName().has_value());
|
||||
}
|
||||
|
||||
TEST(FakeDeviceInfo, GivenName) {
|
||||
FakeDeviceInfo device_info;
|
||||
device_info.SetGivenName(u"windows");
|
||||
EXPECT_EQ(device_info.GetGivenName(), u"windows");
|
||||
device_info.SetGivenName(std::nullopt);
|
||||
EXPECT_FALSE(device_info.GetGivenName().has_value());
|
||||
}
|
||||
|
||||
TEST(FakeDeviceInfo, LastName) {
|
||||
FakeDeviceInfo device_info;
|
||||
device_info.SetLastName(u"windows");
|
||||
EXPECT_EQ(device_info.GetLastName(), u"windows");
|
||||
device_info.SetLastName(std::nullopt);
|
||||
EXPECT_FALSE(device_info.GetLastName().has_value());
|
||||
}
|
||||
|
||||
TEST(FakeDeviceInfo, ProfileUserName) {
|
||||
FakeDeviceInfo device_info;
|
||||
device_info.SetProfileUserName("windows");
|
||||
EXPECT_EQ(device_info.GetProfileUserName(), "windows");
|
||||
device_info.SetProfileUserName(std::nullopt);
|
||||
EXPECT_FALSE(device_info.GetProfileUserName().has_value());
|
||||
}
|
||||
|
||||
TEST(FakeDeviceInfo, GetDownloadPath) {
|
||||
FakeDeviceInfo device_info;
|
||||
EXPECT_EQ(device_info.GetDownloadPath(),
|
||||
std::filesystem::temp_directory_path());
|
||||
device_info.SetDownloadPath(std::filesystem::temp_directory_path() / "test");
|
||||
EXPECT_EQ(device_info.GetDownloadPath(),
|
||||
std::filesystem::temp_directory_path() / "test");
|
||||
}
|
||||
|
||||
TEST(FakeDeviceInfo, GetAppDataPath) {
|
||||
FakeDeviceInfo device_info;
|
||||
EXPECT_EQ(device_info.GetAppDataPath(),
|
||||
std::filesystem::temp_directory_path());
|
||||
device_info.SetAppDataPath(std::filesystem::temp_directory_path() / "test");
|
||||
EXPECT_EQ(device_info.GetAppDataPath(),
|
||||
std::filesystem::temp_directory_path() / "test");
|
||||
}
|
||||
|
||||
TEST(FakeDeviceInfo, GetTemporaryPath) {
|
||||
FakeDeviceInfo device_info;
|
||||
EXPECT_EQ(device_info.GetTemporaryPath(),
|
||||
std::filesystem::temp_directory_path());
|
||||
device_info.SetTemporaryPath(std::filesystem::temp_directory_path() / "test");
|
||||
EXPECT_EQ(device_info.GetTemporaryPath(),
|
||||
std::filesystem::temp_directory_path() / "test");
|
||||
}
|
||||
|
||||
TEST(FakeDeviceInfo, GetAvailableDiskSpaceInBytes) {
|
||||
FakeDeviceInfo device_info;
|
||||
device_info.SetDownloadPath("download");
|
||||
device_info.SetAppDataPath("appdata");
|
||||
device_info.SetTemporaryPath("temp");
|
||||
|
||||
device_info.SetAvailableDiskSpaceInBytes(device_info.GetDownloadPath(), 10);
|
||||
device_info.SetAvailableDiskSpaceInBytes(device_info.GetAppDataPath(), 100);
|
||||
device_info.SetAvailableDiskSpaceInBytes(device_info.GetTemporaryPath(),
|
||||
1000);
|
||||
|
||||
EXPECT_EQ(
|
||||
device_info.GetAvailableDiskSpaceInBytes(device_info.GetDownloadPath()),
|
||||
10);
|
||||
EXPECT_EQ(
|
||||
device_info.GetAvailableDiskSpaceInBytes(device_info.GetAppDataPath()),
|
||||
100);
|
||||
EXPECT_EQ(
|
||||
device_info.GetAvailableDiskSpaceInBytes(device_info.GetTemporaryPath()),
|
||||
1000);
|
||||
}
|
||||
|
||||
TEST(FakeDeviceInfo, RegisterScreenLockedListener) {
|
||||
std::function<void(api::DeviceInfo::ScreenStatus)> listener_1 =
|
||||
[](api::DeviceInfo::ScreenStatus) {};
|
||||
std::function<void(api::DeviceInfo::ScreenStatus)> listener_2 =
|
||||
[](api::DeviceInfo::ScreenStatus) {};
|
||||
|
||||
FakeDeviceInfo device_info;
|
||||
EXPECT_EQ(device_info.GetScreenLockedListenerCount(), 0);
|
||||
|
||||
device_info.RegisterScreenLockedListener("listener_1", listener_1);
|
||||
EXPECT_EQ(device_info.GetScreenLockedListenerCount(), 1);
|
||||
|
||||
device_info.RegisterScreenLockedListener("listener_2", listener_2);
|
||||
EXPECT_EQ(device_info.GetScreenLockedListenerCount(), 2);
|
||||
}
|
||||
|
||||
TEST(FakeDeviceInfo, UnregisterScreenLockedListener) {
|
||||
std::function<void(api::DeviceInfo::ScreenStatus)> listener_1 =
|
||||
[](api::DeviceInfo::ScreenStatus) {};
|
||||
std::function<void(api::DeviceInfo::ScreenStatus)> listener_2 =
|
||||
[](api::DeviceInfo::ScreenStatus) {};
|
||||
|
||||
FakeDeviceInfo device_info;
|
||||
EXPECT_EQ(device_info.GetScreenLockedListenerCount(), 0);
|
||||
|
||||
device_info.RegisterScreenLockedListener("listener_1", listener_1);
|
||||
device_info.RegisterScreenLockedListener("listener_2", listener_2);
|
||||
EXPECT_EQ(device_info.GetScreenLockedListenerCount(), 2);
|
||||
|
||||
device_info.UnregisterScreenLockedListener("listener_1");
|
||||
EXPECT_EQ(device_info.GetScreenLockedListenerCount(), 1);
|
||||
|
||||
device_info.UnregisterScreenLockedListener("listener_2");
|
||||
EXPECT_EQ(device_info.GetScreenLockedListenerCount(), 0);
|
||||
}
|
||||
|
||||
TEST(FakeDeviceInfo, UpdateScreenLockedListener) {
|
||||
api::DeviceInfo::ScreenStatus screen_locked_tracker_1 =
|
||||
api::DeviceInfo::ScreenStatus::kUndetermined;
|
||||
api::DeviceInfo::ScreenStatus screen_locked_tracker_2 =
|
||||
api::DeviceInfo::ScreenStatus::kUndetermined;
|
||||
|
||||
std::function<void(api::DeviceInfo::ScreenStatus)> listener_1 =
|
||||
[&screen_locked_tracker_1](api::DeviceInfo::ScreenStatus status) {
|
||||
screen_locked_tracker_1 = status;
|
||||
};
|
||||
std::function<void(api::DeviceInfo::ScreenStatus)> listener_2 =
|
||||
[&screen_locked_tracker_2](api::DeviceInfo::ScreenStatus status) {
|
||||
screen_locked_tracker_2 = status;
|
||||
};
|
||||
|
||||
FakeDeviceInfo device_info;
|
||||
device_info.RegisterScreenLockedListener("listener_1", listener_1);
|
||||
device_info.RegisterScreenLockedListener("listener_2", listener_2);
|
||||
|
||||
device_info.SetScreenLocked(true);
|
||||
EXPECT_EQ(screen_locked_tracker_1, api::DeviceInfo::ScreenStatus::kLocked);
|
||||
EXPECT_EQ(screen_locked_tracker_2, api::DeviceInfo::ScreenStatus::kLocked);
|
||||
|
||||
device_info.SetScreenLocked(false);
|
||||
EXPECT_EQ(screen_locked_tracker_1, api::DeviceInfo::ScreenStatus::kUnlocked);
|
||||
EXPECT_EQ(screen_locked_tracker_2, api::DeviceInfo::ScreenStatus::kUnlocked);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace nearby
|
||||
@@ -0,0 +1,123 @@
|
||||
// Copyright 2022 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "internal/test/fake_task_runner.h"
|
||||
|
||||
#include <functional>
|
||||
#include <future> // NOLINT
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "absl/time/time.h"
|
||||
|
||||
namespace nearby {
|
||||
|
||||
std::atomic_uint FakeTaskRunner::running_thread_count_ = 0;
|
||||
|
||||
bool FakeTaskRunner::PostTask(absl::AnyInvocable<void()> task) {
|
||||
if (mode_ == Mode::kNoPending) {
|
||||
run(std::move(task));
|
||||
return true;
|
||||
}
|
||||
pending_tasks_.push_back(std::move(task));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool FakeTaskRunner::PostDelayedTask(absl::Duration delay,
|
||||
absl::AnyInvocable<void()> task) {
|
||||
std::unique_ptr<Timer> timer = std::make_unique<FakeTimer>(clock_);
|
||||
Timer* timer_ptr = timer.get();
|
||||
uint32_t id = GenerateId();
|
||||
pending_delayed_tasks_.emplace(id, std::move(timer));
|
||||
timer_ptr->Start(delay / absl::Milliseconds(1), 0,
|
||||
[this, task = std::move(task), id]() mutable {
|
||||
PostTask(std::move(task));
|
||||
completed_delayed_tasks_.push_back(id);
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
void FakeTaskRunner::RunNextTask() {
|
||||
if (pending_tasks_.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
run(std::move(pending_tasks_.front()));
|
||||
pending_tasks_.erase(pending_tasks_.begin());
|
||||
}
|
||||
|
||||
void FakeTaskRunner::RunAllPendingTasks() {
|
||||
while (!pending_tasks_.empty()) {
|
||||
RunNextTask();
|
||||
}
|
||||
}
|
||||
|
||||
const std::vector<absl::AnyInvocable<void()>>& FakeTaskRunner::GetPendingTasks()
|
||||
const {
|
||||
return pending_tasks_;
|
||||
}
|
||||
|
||||
const absl::flat_hash_map<uint32_t, std::unique_ptr<Timer>>&
|
||||
FakeTaskRunner::GetPendingDelayedTask() {
|
||||
if (!completed_delayed_tasks_.empty()) {
|
||||
for (uint32_t id : completed_delayed_tasks_) {
|
||||
pending_delayed_tasks_.erase(id);
|
||||
}
|
||||
}
|
||||
return pending_delayed_tasks_;
|
||||
}
|
||||
|
||||
bool FakeTaskRunner::WaitForRunningTasksWithTimeout(absl::Duration timeout) {
|
||||
int i = (timeout / absl::Milliseconds(1)) / 50;
|
||||
while (running_thread_count_ != 0 && i > 0) {
|
||||
absl::SleepFor(absl::Milliseconds(50));
|
||||
--i;
|
||||
}
|
||||
|
||||
return running_thread_count_ == 0;
|
||||
}
|
||||
|
||||
uint32_t FakeTaskRunner::GenerateId() {
|
||||
++current_id_;
|
||||
return current_id_;
|
||||
}
|
||||
|
||||
void FakeTaskRunner::CleanThreads() {
|
||||
auto it = threads_.begin();
|
||||
while (it != threads_.end()) {
|
||||
// Delete the thread if it is ready
|
||||
auto status = it->wait_for(std::chrono::seconds(0));
|
||||
if (status == std::future_status::ready) {
|
||||
it = threads_.erase(it);
|
||||
} else {
|
||||
++it;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void FakeTaskRunner::run(absl::AnyInvocable<void()> task) {
|
||||
absl::MutexLock lock(&mutex_);
|
||||
CleanThreads();
|
||||
++running_thread_count_;
|
||||
// Run the task in a new thread, to simulate the real environment.
|
||||
std::future<void> thread =
|
||||
std::async(std::launch::async, [&, task = std::move(task)]() mutable {
|
||||
task();
|
||||
--running_thread_count_;
|
||||
});
|
||||
threads_.push_back(std::move(thread));
|
||||
}
|
||||
|
||||
} // namespace nearby
|
||||
@@ -0,0 +1,87 @@
|
||||
// Copyright 2022 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef THIRD_PARTY_NEARBY_INTERNAL_TEST_FAKE_TASK_RUNNER_H_
|
||||
#define THIRD_PARTY_NEARBY_INTERNAL_TEST_FAKE_TASK_RUNNER_H_
|
||||
|
||||
#include <atomic>
|
||||
#include <cstdint>
|
||||
#include <future> //NOLINT
|
||||
#include <memory>
|
||||
#include <thread> //NOLINT
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "absl/base/thread_annotations.h"
|
||||
#include "absl/container/flat_hash_map.h"
|
||||
#include "absl/time/time.h"
|
||||
#include "internal/platform/task_runner.h"
|
||||
#include "internal/test/fake_clock.h"
|
||||
#include "internal/test/fake_timer.h"
|
||||
|
||||
namespace nearby {
|
||||
|
||||
class FakeTaskRunner : public TaskRunner {
|
||||
public:
|
||||
enum class Mode { kNoPending, kPending };
|
||||
|
||||
FakeTaskRunner(FakeClock* clock, uint32_t count)
|
||||
: clock_(clock), count_(count) {}
|
||||
~FakeTaskRunner() override = default;
|
||||
|
||||
bool PostTask(absl::AnyInvocable<void()> task) override;
|
||||
|
||||
// No matter the mode is pending or not, always put the task in timer control.
|
||||
// Caller can move forward time to trigger it.
|
||||
bool PostDelayedTask(absl::Duration delay,
|
||||
absl::AnyInvocable<void()> task) override;
|
||||
|
||||
// Mocked methods.
|
||||
void SetMode(Mode mode) { mode_ = mode; }
|
||||
Mode GetMode() const { return mode_; }
|
||||
|
||||
void RunNextTask();
|
||||
void RunAllPendingTasks();
|
||||
|
||||
const std::vector<absl::AnyInvocable<void()>>& GetPendingTasks() const;
|
||||
const absl::flat_hash_map<uint32_t, std::unique_ptr<Timer>>&
|
||||
GetPendingDelayedTask();
|
||||
|
||||
int GetConcurrentCount() const { return count_; }
|
||||
|
||||
// In some testcases, we needs to make sure all running tasks completion
|
||||
// before go to next task. This method can be used for the purpose.
|
||||
static bool WaitForRunningTasksWithTimeout(absl::Duration timeout);
|
||||
|
||||
private:
|
||||
uint32_t GenerateId();
|
||||
void CleanThreads() ABSL_SHARED_LOCKS_REQUIRED(mutex_);
|
||||
void run(absl::AnyInvocable<void()> task) ABSL_LOCKS_EXCLUDED(mutex_);
|
||||
|
||||
Mode mode_ = Mode::kNoPending;
|
||||
std::atomic_uint current_id_ = 0;
|
||||
FakeClock* clock_ = nullptr;
|
||||
uint32_t count_;
|
||||
std::vector<absl::AnyInvocable<void()>> pending_tasks_;
|
||||
std::vector<uint32_t> completed_delayed_tasks_;
|
||||
absl::flat_hash_map<uint32_t, std::unique_ptr<Timer>> pending_delayed_tasks_;
|
||||
absl::Mutex mutex_;
|
||||
std::vector<std::future<void>> threads_ ABSL_GUARDED_BY(mutex_);
|
||||
|
||||
static std::atomic_uint running_thread_count_;
|
||||
};
|
||||
|
||||
} // namespace nearby
|
||||
|
||||
#endif // THIRD_PARTY_NEARBY_INTERNAL_TEST_FAKE_TASK_RUNNER_H_
|
||||
@@ -0,0 +1,115 @@
|
||||
// Copyright 2022 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "internal/test/fake_task_runner.h"
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
#include "absl/time/time.h"
|
||||
#include "internal/test/fake_clock.h"
|
||||
|
||||
namespace nearby {
|
||||
namespace {
|
||||
|
||||
TEST(FakeTaskRunner, PostTask) {
|
||||
FakeClock clock;
|
||||
int count = 0;
|
||||
FakeTaskRunner task_runner{&clock, 1};
|
||||
task_runner.PostTask([&count] { ++count; });
|
||||
ASSERT_TRUE(
|
||||
FakeTaskRunner::WaitForRunningTasksWithTimeout(absl::Milliseconds(100)));
|
||||
EXPECT_EQ(task_runner.GetPendingTasks().size(), 0);
|
||||
EXPECT_EQ(count, 1);
|
||||
}
|
||||
|
||||
TEST(FakeTaskRunner, PostDelayedTask) {
|
||||
FakeClock clock;
|
||||
int count = 0;
|
||||
FakeTaskRunner task_runner{&clock, 1};
|
||||
task_runner.PostDelayedTask(absl::Seconds(10), [&count] { ++count; });
|
||||
EXPECT_EQ(task_runner.GetPendingTasks().size(), 0);
|
||||
EXPECT_EQ(task_runner.GetPendingDelayedTask().size(), 1);
|
||||
EXPECT_EQ(count, 0);
|
||||
clock.FastForward(absl::Seconds(10));
|
||||
ASSERT_TRUE(
|
||||
FakeTaskRunner::WaitForRunningTasksWithTimeout(absl::Milliseconds(100)));
|
||||
EXPECT_EQ(count, 1);
|
||||
EXPECT_EQ(task_runner.GetPendingDelayedTask().size(), 0);
|
||||
}
|
||||
|
||||
TEST(FakeTaskRunner, PostTasksInPendingMode) {
|
||||
FakeClock clock;
|
||||
FakeTaskRunner task_runner{&clock, 1};
|
||||
task_runner.SetMode(FakeTaskRunner::Mode::kPending);
|
||||
EXPECT_EQ(task_runner.GetConcurrentCount(), 1);
|
||||
task_runner.PostTask([]() {});
|
||||
task_runner.PostTask([]() {});
|
||||
EXPECT_EQ(task_runner.GetPendingTasks().size(), 2);
|
||||
task_runner.RunNextTask();
|
||||
EXPECT_EQ(task_runner.GetPendingTasks().size(), 1);
|
||||
task_runner.RunNextTask();
|
||||
EXPECT_EQ(task_runner.GetPendingTasks().size(), 0);
|
||||
}
|
||||
|
||||
TEST(FakeTaskRunner, RunAllPostedTasksInPendingMode) {
|
||||
FakeClock clock;
|
||||
FakeTaskRunner task_runner{&clock, 1};
|
||||
task_runner.SetMode(FakeTaskRunner::Mode::kPending);
|
||||
task_runner.PostTask([]() {});
|
||||
task_runner.PostTask([]() {});
|
||||
EXPECT_EQ(task_runner.GetPendingTasks().size(), 2);
|
||||
task_runner.RunAllPendingTasks();
|
||||
ASSERT_TRUE(
|
||||
FakeTaskRunner::WaitForRunningTasksWithTimeout(absl::Milliseconds(100)));
|
||||
EXPECT_EQ(task_runner.GetPendingTasks().size(), 0);
|
||||
}
|
||||
|
||||
TEST(FakeTaskRunner, PostDelayedTaskInPendingMode) {
|
||||
FakeClock clock;
|
||||
bool called = false;
|
||||
FakeTaskRunner task_runner{&clock, 1};
|
||||
task_runner.SetMode(FakeTaskRunner::Mode::kPending);
|
||||
task_runner.PostDelayedTask(absl::Seconds(1), [&called]() { called = true; });
|
||||
EXPECT_EQ(task_runner.GetPendingDelayedTask().size(), 1);
|
||||
clock.FastForward(absl::Seconds(1));
|
||||
EXPECT_EQ(task_runner.GetPendingDelayedTask().size(), 0);
|
||||
EXPECT_EQ(task_runner.GetPendingTasks().size(), 1);
|
||||
task_runner.RunAllPendingTasks();
|
||||
ASSERT_TRUE(
|
||||
FakeTaskRunner::WaitForRunningTasksWithTimeout(absl::Milliseconds(100)));
|
||||
EXPECT_EQ(task_runner.GetPendingTasks().size(), 0);
|
||||
EXPECT_TRUE(called);
|
||||
}
|
||||
|
||||
TEST(FakeTaskRunner, PostDelayedTaskInDelayedTask) {
|
||||
FakeClock clock;
|
||||
int called_count = 0;
|
||||
FakeTaskRunner task_runner{&clock, 1};
|
||||
task_runner.PostDelayedTask(
|
||||
absl::Seconds(1), [&called_count, &task_runner]() {
|
||||
++called_count;
|
||||
task_runner.PostDelayedTask(absl::Seconds(1),
|
||||
[&called_count]() { ++called_count; });
|
||||
});
|
||||
clock.FastForward(absl::Seconds(1));
|
||||
ASSERT_TRUE(
|
||||
FakeTaskRunner::WaitForRunningTasksWithTimeout(absl::Milliseconds(100)));
|
||||
EXPECT_EQ(called_count, 1);
|
||||
clock.FastForward(absl::Seconds(1));
|
||||
ASSERT_TRUE(
|
||||
FakeTaskRunner::WaitForRunningTasksWithTimeout(absl::Milliseconds(100)));
|
||||
EXPECT_EQ(called_count, 2);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace nearby
|
||||
@@ -0,0 +1,93 @@
|
||||
// Copyright 2021 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "internal/test/fake_timer.h"
|
||||
|
||||
#include <functional>
|
||||
#include <future> // NOLINT
|
||||
#include <string>
|
||||
#include <thread> // NOLINT
|
||||
#include <utility>
|
||||
|
||||
#include "absl/time/clock.h"
|
||||
#include "absl/time/time.h"
|
||||
|
||||
namespace nearby {
|
||||
|
||||
FakeTimer::FakeTimer(FakeClock* clock) : clock_(clock) {
|
||||
id_ = std::to_string(absl::ToUnixNanos(absl::Now()));
|
||||
clock_->AddObserver(id_, [this]() { ClockUpdated(); });
|
||||
}
|
||||
|
||||
FakeTimer::~FakeTimer() { clock_->RemoveObserver(id_); }
|
||||
|
||||
bool FakeTimer::Start(int delay, int period,
|
||||
absl::AnyInvocable<void()> callback) {
|
||||
if (is_started_ || delay < 0 || period < 0) {
|
||||
return false;
|
||||
}
|
||||
delay_ = delay;
|
||||
period_ = period;
|
||||
callback_ = std::move(callback);
|
||||
start_time_ = clock_->Now();
|
||||
fired_count_ = 0;
|
||||
is_started_ = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool FakeTimer::Stop() {
|
||||
is_started_ = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool FakeTimer::IsRunning() { return is_started_; }
|
||||
|
||||
void FakeTimer::ClockUpdated() {
|
||||
if (!is_started_) {
|
||||
return;
|
||||
}
|
||||
|
||||
absl::Time now = clock_->Now();
|
||||
int64_t duration = absl::ToInt64Milliseconds(now - start_time_);
|
||||
FakeClock* clock = clock_;
|
||||
|
||||
if (duration >= delay_ && fired_count_ == 0) {
|
||||
++fired_count_;
|
||||
callback_();
|
||||
}
|
||||
|
||||
if (period_ == 0 || duration < delay_ ||
|
||||
((clock_ != nullptr) && (clock_ != clock))) {
|
||||
return;
|
||||
}
|
||||
|
||||
int count = (duration - delay_) / period_;
|
||||
int should_fire_count = count - fired_count_ + 1;
|
||||
for (int i = 0; i < should_fire_count; ++i) {
|
||||
++fired_count_;
|
||||
callback_();
|
||||
}
|
||||
}
|
||||
|
||||
bool FakeTimer::FireNow() {
|
||||
if (IsRunning() && callback_) {
|
||||
callback_();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace nearby
|
||||
@@ -0,0 +1,52 @@
|
||||
// Copyright 2021 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef THIRD_PARTY_NEARBY_INTERNAL_TEST_FAKE_TIMER_H_
|
||||
#define THIRD_PARTY_NEARBY_INTERNAL_TEST_FAKE_TIMER_H_
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "internal/platform/timer.h"
|
||||
#include "internal/test/fake_clock.h"
|
||||
|
||||
namespace nearby {
|
||||
class FakeTimer : public Timer {
|
||||
public:
|
||||
explicit FakeTimer(FakeClock* clock);
|
||||
~FakeTimer() override;
|
||||
FakeTimer(FakeTimer&&) = default;
|
||||
FakeTimer& operator=(FakeTimer&&) = default;
|
||||
|
||||
bool Start(int delay, int period,
|
||||
absl::AnyInvocable<void()> callback) override;
|
||||
bool Stop() override;
|
||||
bool IsRunning() override;
|
||||
bool FireNow() override;
|
||||
|
||||
private:
|
||||
void ClockUpdated();
|
||||
|
||||
std::string id_;
|
||||
int delay_ = 0;
|
||||
int period_ = false;
|
||||
int fired_count_ = 0;
|
||||
absl::Time start_time_;
|
||||
bool is_started_ = false;
|
||||
absl::AnyInvocable<void()> callback_;
|
||||
FakeClock* clock_ = nullptr;
|
||||
};
|
||||
|
||||
} // namespace nearby
|
||||
|
||||
#endif // THIRD_PARTY_NEARBY_INTERNAL_TEST_FAKE_TIMER_H_
|
||||
@@ -0,0 +1,164 @@
|
||||
// Copyright 2021 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "internal/test/fake_timer.h"
|
||||
|
||||
#include "gmock/gmock.h"
|
||||
#include "protobuf-matchers/protocol-buffer-matchers.h"
|
||||
#include "gtest/gtest.h"
|
||||
#include "absl/time/time.h"
|
||||
|
||||
namespace nearby {
|
||||
namespace {
|
||||
|
||||
TEST(FakeTimer, TestOneTimeTimer) {
|
||||
FakeClock clock;
|
||||
FakeTimer timer(&clock);
|
||||
int count = 0;
|
||||
auto callback = [&count]() { ++count; };
|
||||
timer.Start(100, 0, callback);
|
||||
EXPECT_TRUE(timer.IsRunning());
|
||||
clock.FastForward(absl::Milliseconds(1000));
|
||||
EXPECT_EQ(count, 1);
|
||||
EXPECT_TRUE(timer.Stop());
|
||||
EXPECT_FALSE(timer.IsRunning());
|
||||
}
|
||||
|
||||
TEST(FakeTimer, TestRepeatTimer) {
|
||||
FakeClock clock;
|
||||
FakeTimer timer(&clock);
|
||||
int count = 0;
|
||||
auto callback = [&count]() { ++count; };
|
||||
timer.Start(100, 100, callback);
|
||||
EXPECT_TRUE(timer.IsRunning());
|
||||
clock.FastForward(absl::Milliseconds(1000));
|
||||
EXPECT_EQ(count, 10);
|
||||
EXPECT_TRUE(timer.Stop());
|
||||
EXPECT_FALSE(timer.IsRunning());
|
||||
}
|
||||
|
||||
TEST(FakeTimer, TestInvalidInput) {
|
||||
FakeClock clock;
|
||||
FakeTimer timer(&clock);
|
||||
int count = 0;
|
||||
auto callback = [&count]() { ++count; };
|
||||
timer.Start(-100, 100, callback);
|
||||
EXPECT_FALSE(timer.IsRunning());
|
||||
EXPECT_TRUE(timer.Stop());
|
||||
}
|
||||
|
||||
TEST(FakeTimer, TestStopTimerBeforeClockUpdate) {
|
||||
FakeClock clock;
|
||||
FakeTimer timer(&clock);
|
||||
int count = 0;
|
||||
auto callback = [&count]() { ++count; };
|
||||
timer.Start(100, 100, callback);
|
||||
EXPECT_TRUE(timer.IsRunning());
|
||||
EXPECT_TRUE(timer.Stop());
|
||||
EXPECT_FALSE(timer.IsRunning());
|
||||
clock.FastForward(absl::Milliseconds(1000));
|
||||
EXPECT_EQ(count, 0);
|
||||
}
|
||||
|
||||
TEST(FakeTimer, TestUpdateMultipleTimesClockForOnetimeTimer) {
|
||||
FakeClock clock;
|
||||
FakeTimer timer(&clock);
|
||||
int count = 0;
|
||||
auto callback = [&count]() { ++count; };
|
||||
timer.Start(100, 0, callback);
|
||||
EXPECT_TRUE(timer.IsRunning());
|
||||
clock.FastForward(absl::Nanoseconds(50));
|
||||
EXPECT_EQ(count, 0);
|
||||
clock.FastForward(absl::Milliseconds(1000));
|
||||
EXPECT_EQ(count, 1);
|
||||
clock.FastForward(absl::Milliseconds(1000));
|
||||
EXPECT_EQ(count, 1);
|
||||
EXPECT_TRUE(timer.Stop());
|
||||
EXPECT_FALSE(timer.IsRunning());
|
||||
}
|
||||
|
||||
TEST(FakeTimer, TestInstantRunTimer) {
|
||||
FakeClock clock;
|
||||
FakeTimer timer(&clock);
|
||||
int count = 0;
|
||||
auto callback = [&count]() { ++count; };
|
||||
timer.Start(0, 100, callback);
|
||||
EXPECT_TRUE(timer.IsRunning());
|
||||
clock.FastForward(absl::Milliseconds(1000));
|
||||
EXPECT_EQ(count, 11);
|
||||
EXPECT_TRUE(timer.Stop());
|
||||
EXPECT_FALSE(timer.IsRunning());
|
||||
}
|
||||
|
||||
TEST(FakeTimer, TestTimerDestructor) {
|
||||
FakeClock clock;
|
||||
{
|
||||
FakeTimer timer(&clock);
|
||||
EXPECT_EQ(clock.GetObserversCount(), 1);
|
||||
int count = 0;
|
||||
auto callback = [&count]() { ++count; };
|
||||
timer.Start(100, 0, callback);
|
||||
EXPECT_TRUE(timer.IsRunning());
|
||||
EXPECT_EQ(count, 0);
|
||||
EXPECT_TRUE(timer.Stop());
|
||||
EXPECT_FALSE(timer.IsRunning());
|
||||
}
|
||||
EXPECT_EQ(clock.GetObserversCount(), 0);
|
||||
}
|
||||
|
||||
TEST(FakeTimer, TestTimerFireNow) {
|
||||
FakeClock clock;
|
||||
int count = 0;
|
||||
FakeTimer timer(&clock);
|
||||
auto callback = [&count]() { ++count; };
|
||||
timer.Start(200, 100, callback);
|
||||
timer.FireNow();
|
||||
timer.Stop();
|
||||
EXPECT_EQ(count, 1);
|
||||
}
|
||||
|
||||
TEST(FakeTimer, CloseTimerInTimerProc) {
|
||||
int count = 0;
|
||||
FakeClock clock;
|
||||
FakeTimer timer1(&clock);
|
||||
FakeTimer timer2(&clock);
|
||||
timer1.Start(100, 0, [&]() { ++count; });
|
||||
timer2.Start(50, 0, [&]() {
|
||||
++count;
|
||||
timer1.Stop();
|
||||
});
|
||||
|
||||
clock.FastForward(absl::Milliseconds(50));
|
||||
EXPECT_EQ(count, 1);
|
||||
clock.FastForward(absl::Milliseconds(50));
|
||||
EXPECT_EQ(count, 1);
|
||||
}
|
||||
|
||||
TEST(FakeTimer, StartTimerInTimerProc) {
|
||||
int count = 0;
|
||||
FakeClock clock;
|
||||
FakeTimer timer1(&clock);
|
||||
timer1.Start(1000, 0, [&]() {
|
||||
++count;
|
||||
timer1.Stop();
|
||||
timer1.Start(1000, 0, [&]() { ++count; });
|
||||
});
|
||||
clock.FastForward(absl::Milliseconds(1000));
|
||||
EXPECT_EQ(count, 1);
|
||||
clock.FastForward(absl::Milliseconds(1000));
|
||||
EXPECT_EQ(count, 2);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace nearby
|
||||
Reference in New Issue
Block a user