From 284a78af0fe4762d315db263256e22da7d9999c3 Mon Sep 17 00:00:00 2001 From: kidfromjupiter Date: Sat, 27 Dec 2025 05:29:14 +0000 Subject: [PATCH] added tests for bluetooth adapter and multithread executor --- internal/platform/implementation/linux/BUILD | 45 +++++++ .../implementation/linux/bluetooth_adapter.cc | 5 +- .../linux/bluetooth_adapter_test.cc | 90 ++++++++++++++ .../linux/multi_thread_executor_test.cc | 114 ++++++++++++++++++ 4 files changed, 253 insertions(+), 1 deletion(-) create mode 100644 internal/platform/implementation/linux/bluetooth_adapter_test.cc create mode 100644 internal/platform/implementation/linux/multi_thread_executor_test.cc diff --git a/internal/platform/implementation/linux/BUILD b/internal/platform/implementation/linux/BUILD index 81d7c97f..bcee965e 100644 --- a/internal/platform/implementation/linux/BUILD +++ b/internal/platform/implementation/linux/BUILD @@ -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", + + ], +) diff --git a/internal/platform/implementation/linux/bluetooth_adapter.cc b/internal/platform/implementation/linux/bluetooth_adapter.cc index 2fbdc58a..9c0c95f7 100644 --- a/internal/platform/implementation/linux/bluetooth_adapter.cc +++ b/internal/platform/implementation/linux/bluetooth_adapter.cc @@ -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); } diff --git a/internal/platform/implementation/linux/bluetooth_adapter_test.cc b/internal/platform/implementation/linux/bluetooth_adapter_test.cc new file mode 100644 index 00000000..72799d3e --- /dev/null +++ b/internal/platform/implementation/linux/bluetooth_adapter_test.cc @@ -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 +#include + +#include "gtest/gtest.h" +#include "absl/strings/string_view.h" +#include "absl/synchronization/notification.h" +#include "internal/platform/implementation/bluetooth_adapter.h" +#include + +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 diff --git a/internal/platform/implementation/linux/multi_thread_executor_test.cc b/internal/platform/implementation/linux/multi_thread_executor_test.cc new file mode 100644 index 00000000..5ce20ed4 --- /dev/null +++ b/internal/platform/implementation/linux/multi_thread_executor_test.cc @@ -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 + +#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