added tests for bluetooth adapter and multithread executor

This commit is contained in:
kidfromjupiter
2025-12-27 05:29:14 +00:00
parent 88f8133d90
commit 284a78af0f
4 changed files with 253 additions and 1 deletions
@@ -86,3 +86,48 @@ cc_library(
],
visibility = ["//visibility:public"],
)
cc_library(
name = "multi_thread_executor_hdrs",
hdrs = ["multi_thread_executor.h"],
visibility = ["//visibility:public" ],
deps = [
"//internal/platform/implementation:types"
]
)
cc_test(
name = "bluetooth_adapter_test",
srcs = [
"bluetooth_adapter_test.cc",
],
deps = [
":linux",
":types",
"//internal/platform/implementation:platform",
"//internal/platform:base",
"@com_google_absl//absl/strings",
"@com_google_absl//absl/synchronization",
"@com_google_absl//absl/time",
"@com_google_googletest//:gtest_main",
"@sdbus_cpp//:sdbus_cpp",
"@sdbus_cpp//:libsystemd",
],
)
cc_test(
name = "multi_thread_executor_test",
srcs = [
"multi_thread_executor_test.cc",
],
deps = [
# Depend on the header-only target to pick up the linux header without
# pulling system libraries.
":multi_thread_executor_hdrs",
"@com_google_absl//absl/strings",
"@com_google_absl//absl/synchronization",
"@com_google_absl//absl/time",
"@com_google_googletest//:gtest_main",
],
)
@@ -26,7 +26,10 @@ namespace linux {
{
Powered(true);
}
else
{
Powered(false);
}
return true;
}
bool BluetoothAdapter::IsEnabled() const
@@ -78,7 +81,7 @@ namespace linux {
bool BluetoothAdapter::SetName(absl::string_view name,bool persist)
{
BluetoothAdapter::SetName(name);
return BluetoothAdapter::SetName(name);
}
@@ -0,0 +1,90 @@
// filepath: /workspace/internal/platform/implementation/linux/bluetooth_adapter_test.cc
// Copyright 2024 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/platform/implementation/linux/bluetooth_adapter.h"
#include <memory>
#include <string>
#include "gtest/gtest.h"
#include "absl/strings/string_view.h"
#include "absl/synchronization/notification.h"
#include "internal/platform/implementation/bluetooth_adapter.h"
#include <sdbus-c++/sdbus-c++.h>
namespace nearby {
namespace linux {
namespace {
constexpr absl::string_view kName = "Test Radio Name";
// Tests are disabled because they may interact with the system DBus and
// modify adapter state; they are intended as compile-time and manual-run
// validations to mirror the Windows test suite.
TEST(BluetoothAdapter, DISABLED_SetStatusReturnsTrue) {
auto connection = sdbus::createConnection();
sdbus::ObjectPath object_path{"/org/bluez/hci0"};
BluetoothAdapter adapter(*connection, object_path);
// Our implementation returns bool; assert it returns true on attempted
// enable. This test is disabled by default to avoid changing system state.
EXPECT_TRUE(adapter.SetStatus(api::BluetoothAdapter::Status::kEnabled));
}
TEST(BluetoothAdapter, DISABLED_SetAndGetName) {
auto connection = sdbus::createConnection();
sdbus::ObjectPath object_path{"/org/bluez/hci0"};
BluetoothAdapter adapter(*connection, object_path);
const std::string new_name = "nearby-linux-test-name";
bool ok = adapter.SetName(new_name);
EXPECT_TRUE(ok);
if (ok) {
// If SetName succeeded, GetName should reflect the set value.
EXPECT_EQ(adapter.GetName(), new_name);
}
}
TEST(BluetoothAdapter, DISABLED_GetMacAddressNotEmpty) {
auto connection = sdbus::createConnection();
sdbus::ObjectPath object_path{"/org/bluez/hci0"};
BluetoothAdapter adapter(*connection, object_path);
EXPECT_FALSE(adapter.GetMacAddress().empty());
}
TEST(BluetoothAdapter, DISABLED_SetScanModeWhenEnabled) {
auto connection = sdbus::createConnection();
sdbus::ObjectPath object_path{"/org/bluez/hci0"};
BluetoothAdapter adapter(*connection, object_path);
if (!adapter.IsEnabled()) {
GTEST_SKIP() << "Adapter not enabled on this machine; skipping scan-mode test.";
}
// Try to set discoverable connectable; may be disallowed by system policy.
bool set_ok = adapter.SetScanMode(api::BluetoothAdapter::ScanMode::kConnectableDiscoverable);
if (!set_ok) {
GTEST_SKIP() << "SetScanMode returned false; skipping further scan-mode checks.";
}
auto scan_mode = adapter.GetScanMode();
EXPECT_EQ(scan_mode, api::BluetoothAdapter::ScanMode::kConnectableDiscoverable);
}
} // namespace
} // namespace linux
} // namespace nearby
@@ -0,0 +1,114 @@
// filepath: /workspace/internal/platform/implementation/linux/multi_thread_executor_test.cc
// Copyright 2025 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/platform/implementation/linux/multi_thread_executor.h"
#include <atomic>
#include "gtest/gtest.h"
#include "absl/synchronization/mutex.h"
#include "absl/time/clock.h"
#include "absl/time/time.h"
namespace nearby {
namespace linux {
namespace {
const int kMaxThreads = 4;
}
TEST(LinuxMultiThreadExecutorTest, ConstructorDestructorWorks) {
MultiThreadExecutor executor(kMaxThreads);
}
TEST(LinuxMultiThreadExecutorTest, CanExecute) {
absl::CondVar cond;
std::atomic_bool done = false;
MultiThreadExecutor executor(kMaxThreads);
executor.Execute([&done, &cond]() {
done = true;
cond.SignalAll();
});
absl::Mutex mutex;
{
absl::MutexLock lock(&mutex);
if (!done) {
cond.WaitWithTimeout(&mutex, absl::Seconds(1));
}
}
EXPECT_TRUE(done);
}
TEST(LinuxMultiThreadExecutorTest, JobsExecuteInParallel) {
absl::Mutex mutex;
absl::CondVar thread_cond;
absl::CondVar test_cond;
MultiThreadExecutor executor(kMaxThreads);
int count = 0;
for (int i = 0; i < kMaxThreads; ++i) {
executor.Execute([&]() {
absl::MutexLock lock(&mutex);
count++;
test_cond.Signal();
thread_cond.Wait(&mutex);
count--;
test_cond.Signal();
});
}
{
absl::MutexLock lock(&mutex);
while (count < kMaxThreads) {
if (test_cond.WaitWithTimeout(&mutex, absl::Seconds(30))) break;
}
}
EXPECT_EQ(count, kMaxThreads);
thread_cond.SignalAll();
{
absl::MutexLock lock(&mutex);
while (count > 0) {
if (test_cond.WaitWithTimeout(&mutex, absl::Seconds(30))) break;
}
}
EXPECT_EQ(count, 0);
}
TEST(LinuxMultiThreadExecutorTest, CanScheduleDelayedTask) {
MultiThreadExecutor executor(kMaxThreads);
std::atomic_bool ran = false;
auto start = absl::Now();
executor.Schedule([&ran]() { ran = true; }, absl::Milliseconds(100));
// Busy-wait using absl sleep to allow scheduled task to run
for (int i = 0; i < 20 && !ran; ++i) {
absl::SleepFor(absl::Milliseconds(20));
}
EXPECT_TRUE(ran);
auto elapsed = absl::Now() - start;
EXPECT_GE(absl::ToInt64Milliseconds(elapsed), 80);
}
TEST(LinuxMultiThreadExecutorTest, ShutdownPreventsSubmit) {
MultiThreadExecutor executor(kMaxThreads);
executor.Shutdown();
// After Shutdown, DoSubmit should return false when trying to submit work.
bool submitted = executor.DoSubmit([]() {});
EXPECT_FALSE(submitted);
}
} // namespace linux
} // namespace nearby