[Nearby Presence] Create presence client factory and fake

Add a presence client factory and fake_presence_client to help facilitate presence client testing. This testing infrastructure is used in crrev/c/4528575 to test the nearby presence mojom interface.

PiperOrigin-RevId: 535087368
This commit is contained in:
hai007
2023-05-24 20:56:04 -07:00
committed by Copybara-Service
parent 55750a0843
commit 1be7e82b4f
10 changed files with 320 additions and 45 deletions
+20 -1
View File
@@ -18,11 +18,12 @@ package(default_visibility = ["//:__subpackages__"])
cc_library(
name = "presence",
srcs = [
"presence_client.cc",
"presence_client_impl.cc",
"presence_service.cc",
],
hdrs = [
"presence_client.h",
"presence_client_impl.h",
"presence_device_provider.h",
"presence_service.h",
],
@@ -37,6 +38,24 @@ cc_library(
],
)
cc_library(
name = "test_support",
testonly = 1,
srcs = [
"fake_presence_client.cc",
],
hdrs = [
"fake_presence_client.h",
],
compatible_with = ["//buildenv/target:non_prod"],
deps = [
":presence",
":types",
"@com_google_absl//absl/status",
"@com_google_absl//absl/status:statusor",
],
)
cc_library(
name = "types",
srcs = [
+81
View File
@@ -0,0 +1,81 @@
// Copyright 2023 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 "presence/fake_presence_client.h"
#include <algorithm>
#include <utility>
#include <vector>
#include "presence/data_types.h"
#include "presence/presence_device.h"
#include "presence/scan_request.h"
namespace {
::nearby::internal::Metadata BuildTestMetadata() {
::nearby::internal::Metadata metadata;
metadata.set_bluetooth_mac_address("01234567");
metadata.set_device_name("Pepper's device");
return metadata;
}
} // namespace
namespace nearby {
namespace presence {
absl::StatusOr<ScanSessionId> FakePresenceClient::StartScan(
ScanRequest scan_request, ScanCallback callback) {
current_scan_session_id_++;
active_scan_sessions_.push_back(current_scan_session_id_);
absl::StatusOr<ScanSessionId> scan_session_id(current_scan_session_id_);
callback_ = std::move(callback);
return scan_session_id;
}
void FakePresenceClient::StopScan(ScanSessionId id) {
auto position =
std::find(active_scan_sessions_.begin(), active_scan_sessions_.end(), id);
if (position != active_scan_sessions_.end()) {
active_scan_sessions_.erase(position);
}
}
std::vector<uint64_t> FakePresenceClient::GetActiveScanSessions() {
return active_scan_sessions_;
}
void FakePresenceClient::CallStartScanCallback(absl::Status status) {
callback_.start_scan_cb(status);
}
void FakePresenceClient::CallOnDiscovered() {
PresenceDevice device{BuildTestMetadata()};
callback_.on_discovered_cb(std::move(device));
}
void FakePresenceClient::CallOnUpdated() {
PresenceDevice device{BuildTestMetadata()};
callback_.on_updated_cb(std::move(device));
}
void FakePresenceClient::CallOnLost() {
PresenceDevice device{BuildTestMetadata()};
callback_.on_lost_cb(std::move(device));
}
} // namespace presence
} // namespace nearby
+78
View File
@@ -0,0 +1,78 @@
// Copyright 2023 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_PRESENCE_FAKE_PRESENCE_CLIENT_H_
#define THIRD_PARTY_NEARBY_PRESENCE_FAKE_PRESENCE_CLIENT_H_
#include <optional>
#include <vector>
#include "absl/status/statusor.h"
#include "presence/broadcast_request.h"
#include "presence/presence_client.h"
#include "presence/presence_device.h"
#include "presence/scan_request.h"
namespace nearby {
namespace presence {
class FakePresenceClient : public PresenceClient {
public:
FakePresenceClient() = default;
FakePresenceClient(const FakePresenceClient&) = delete;
FakePresenceClient(FakePresenceClient&&) = default;
FakePresenceClient& operator=(const FakePresenceClient&) = delete;
~FakePresenceClient() = default;
absl::StatusOr<ScanSessionId> StartScan(ScanRequest scan_request,
ScanCallback callback) override;
void StopScan(ScanSessionId session_id) override;
// Not Implemented.
absl::StatusOr<BroadcastSessionId> StartBroadcast(
BroadcastRequest broadcast_request, BroadcastCallback callback) override {
return 0;
}
// Not Implemented.
void StopBroadcast(BroadcastSessionId session_id) override {}
// Not Implemented.
std::optional<PresenceDevice> GetLocalDevice() override {
return std::nullopt;
}
void SetNextScanSessionSuccess(bool success) {
next_scan_should_succeed_ = success;
}
std::vector<uint64_t> GetActiveScanSessions();
void CallStartScanCallback(absl::Status status);
void CallOnDiscovered();
void CallOnUpdated();
void CallOnLost();
private:
uint64_t current_scan_session_id_;
ScanCallback callback_;
std::vector<uint64_t> active_scan_sessions_;
bool next_scan_should_succeed_ = true;
};
} // namespace presence
} // namespace nearby
#endif // THIRD_PARTY_NEARBY_PRESENCE_FAKE_PRESENCE_CLIENT_H_
+8 -15
View File
@@ -36,11 +36,7 @@ class PresenceClient {
public:
using BorrowablePresenceService = ::nearby::Borrowable<PresenceService*>;
explicit PresenceClient(BorrowablePresenceService service)
: service_(service) {}
PresenceClient(const PresenceClient&) = delete;
PresenceClient(PresenceClient&&) = default;
PresenceClient& operator=(const PresenceClient&) = delete;
virtual ~PresenceClient() = default;
// Starts a Nearby Presence scan and registers `ScanCallback`
// which will be invoked when a matching `PresenceDevice` is detected,
@@ -53,12 +49,12 @@ class PresenceClient {
// `ScanRequest` contains the options like scan power mode
// and type; the filters including credentials, actions and extended
// properties.
absl::StatusOr<ScanSessionId> StartScan(ScanRequest scan_request,
ScanCallback callback);
virtual absl::StatusOr<ScanSessionId> StartScan(ScanRequest scan_request,
ScanCallback callback) = 0;
// Terminates the scan session. Does nothing if the session is already
// terminated.
void StopScan(ScanSessionId session_id);
virtual void StopScan(ScanSessionId session_id) = 0;
// Starts a Nearby Presence broadcast and registers `BroadcastCallback`
// which will be invoked after broadcast is started.
@@ -70,20 +66,17 @@ class PresenceClient {
// `BroadcastRequest` contains the options like tx_power,
// the credential info like salt and private credential, the actions and
// extended properties.
absl::StatusOr<BroadcastSessionId> StartBroadcast(
BroadcastRequest broadcast_request, BroadcastCallback callback);
virtual absl::StatusOr<BroadcastSessionId> StartBroadcast(
BroadcastRequest broadcast_request, BroadcastCallback callback) = 0;
// Terminates a broadcast session. Does nothing if the session is already
// terminated.
void StopBroadcast(BroadcastSessionId session_id);
virtual void StopBroadcast(BroadcastSessionId session_id) = 0;
// Returns the local PresenceDevice describing the current device's actions,
// connectivity info and unique identifier for use in Connections and
// Presence.
std::optional<PresenceDevice> GetLocalDevice();
private:
BorrowablePresenceService service_;
virtual std::optional<PresenceDevice> GetLocalDevice() = 0;
};
} // namespace presence
@@ -1,4 +1,4 @@
// Copyright 2020 Google LLC
// Copyright 2023 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -12,8 +12,9 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#include "presence/presence_client.h"
#include "presence/presence_client_impl.h"
#include <memory>
#include <optional>
#include <utility>
@@ -26,7 +27,28 @@
namespace nearby {
namespace presence {
absl::StatusOr<ScanSessionId> PresenceClient::StartScan(
// static
PresenceClientImpl::Factory* PresenceClientImpl::Factory::g_test_factory_ =
nullptr;
// static
std::unique_ptr<PresenceClient> PresenceClientImpl::Factory::Create(
BorrowablePresenceService service) {
if (g_test_factory_) {
return g_test_factory_->CreateInstance(service);
}
return absl::WrapUnique(new PresenceClientImpl(service));
}
// static
void PresenceClientImpl::Factory::SetFactoryForTesting(
Factory* g_test_factory) {
g_test_factory_ = g_test_factory;
}
PresenceClientImpl::Factory::~Factory() = default;
absl::StatusOr<ScanSessionId> PresenceClientImpl::StartScan(
ScanRequest scan_request, ScanCallback callback) {
::nearby::Borrowed<PresenceService*> borrowed = service_.Borrow();
if (!borrowed) {
@@ -36,14 +58,14 @@ absl::StatusOr<ScanSessionId> PresenceClient::StartScan(
return (*borrowed)->StartScan(scan_request, std::move(callback));
}
void PresenceClient::StopScan(ScanSessionId id) {
void PresenceClientImpl::StopScan(ScanSessionId id) {
::nearby::Borrowed<PresenceService*> borrowed = service_.Borrow();
if (borrowed) {
(*borrowed)->StopScan(id);
}
}
absl::StatusOr<BroadcastSessionId> PresenceClient::StartBroadcast(
absl::StatusOr<BroadcastSessionId> PresenceClientImpl::StartBroadcast(
BroadcastRequest broadcast_request, BroadcastCallback callback) {
::nearby::Borrowed<PresenceService*> borrowed = service_.Borrow();
if (!borrowed) {
@@ -53,7 +75,7 @@ absl::StatusOr<BroadcastSessionId> PresenceClient::StartBroadcast(
return (*borrowed)->StartBroadcast(broadcast_request, std::move(callback));
}
void PresenceClient::StopBroadcast(BroadcastSessionId session_id) {
void PresenceClientImpl::StopBroadcast(BroadcastSessionId session_id) {
::nearby::Borrowed<PresenceService*> borrowed = service_.Borrow();
if (borrowed) {
(*borrowed)->StopBroadcast(session_id);
@@ -62,7 +84,7 @@ void PresenceClient::StopBroadcast(BroadcastSessionId session_id) {
}
}
std::optional<PresenceDevice> PresenceClient::GetLocalDevice() {
std::optional<PresenceDevice> PresenceClientImpl::GetLocalDevice() {
::nearby::Borrowed<PresenceService*> borrowed = service_.Borrow();
if (borrowed) {
const PresenceDevice* device = static_cast<const PresenceDevice*>(
+75
View File
@@ -0,0 +1,75 @@
// Copyright 2023 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_PRESENCE_PRESENCE_CLIENT_IMPL_H_
#define THIRD_PARTY_NEARBY_PRESENCE_PRESENCE_CLIENT_IMPL_H_
#include <memory>
#include <optional>
#include "absl/status/statusor.h"
#include "internal/platform/borrowable.h"
#include "presence/broadcast_request.h"
#include "presence/data_types.h"
#include "presence/presence_client.h"
#include "presence/presence_device.h"
#include "presence/scan_request.h"
namespace nearby {
namespace presence {
class PresenceClientImpl : public PresenceClient{
public:
using BorrowablePresenceService = ::nearby::Borrowable<PresenceService*>;
class Factory {
public:
static std::unique_ptr<PresenceClient> Create(
BorrowablePresenceService service);
static void SetFactoryForTesting(Factory* test_factory);
protected:
virtual ~Factory();
virtual std::unique_ptr<PresenceClient> CreateInstance(
BorrowablePresenceService service) = 0;
private:
static Factory* g_test_factory_;
};
PresenceClientImpl(const PresenceClientImpl&) = delete;
PresenceClientImpl(PresenceClientImpl&&) = default;
PresenceClientImpl& operator=(const PresenceClientImpl&) = delete;
~PresenceClientImpl() override = default;
// PresenceClient:
absl::StatusOr<ScanSessionId> StartScan(ScanRequest scan_request,
ScanCallback callback) override;
void StopScan(ScanSessionId session_id) override;
absl::StatusOr<BroadcastSessionId> StartBroadcast(
BroadcastRequest broadcast_request, BroadcastCallback callback) override;
void StopBroadcast(BroadcastSessionId session_id) override;
std::optional<PresenceDevice> GetLocalDevice() override;
private:
explicit PresenceClientImpl(BorrowablePresenceService service)
: service_(service) {}
BorrowablePresenceService service_;
};
} // namespace presence
} // namespace nearby
#endif // THIRD_PARTY_NEARBY_PRESENCE_PRESENCE_CLIENT_IMPL_H_
+18 -14
View File
@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#include "presence/presence_client.h"
#include <memory>
#include "gmock/gmock.h"
#include "protobuf-matchers/protocol-buffer-matchers.h"
@@ -34,7 +34,7 @@ constexpr absl::string_view kMacAddr = "\x4C\x8B\x1D\xCE\xBA\xD1";
// Creates a PresenceClient and destroys PresenceService that was used to create
// it.
PresenceClient CreateDefunctPresenceClient() {
std::unique_ptr<PresenceClient> CreateDefunctPresenceClient() {
PresenceService presence_service;
return presence_service.CreatePresenceClient();
}
@@ -60,8 +60,9 @@ TEST_F(PresenceClientTest, StartBroadcastWithDefaultConstructor) {
absl::Status broadcast_result;
PresenceService presence_service;
PresenceClient presence_client = presence_service.CreatePresenceClient();
auto unused = presence_client.StartBroadcast(
std::unique_ptr<PresenceClient> presence_client =
presence_service.CreatePresenceClient();
auto unused = presence_client->StartBroadcast(
{}, {
.start_broadcast_cb =
[&](absl::Status status) { broadcast_result = status; },
@@ -76,7 +77,7 @@ TEST_F(PresenceClientTest, StartBroadcastFailsWhenPresenceServiceIsGone) {
absl::Status broadcast_result = absl::UnknownError("");
absl::StatusOr<BroadcastSessionId> session_id =
CreateDefunctPresenceClient().StartBroadcast(
CreateDefunctPresenceClient()->StartBroadcast(
{}, {
.start_broadcast_cb =
[&](absl::Status status) { broadcast_result = status; },
@@ -95,8 +96,9 @@ TEST_F(PresenceClientTest, StartScanWithDefaultConstructor) {
};
PresenceService presence_service;
PresenceClient presence_client = presence_service.CreatePresenceClient();
EXPECT_OK(presence_client.StartScan({}, std::move(scan_callback)));
std::unique_ptr<PresenceClient> presence_client =
presence_service.CreatePresenceClient();
EXPECT_OK(presence_client->StartScan({}, std::move(scan_callback)));
EXPECT_TRUE(scan_result.Get().ok());
EXPECT_OK(scan_result.Get().GetResult());
@@ -108,7 +110,7 @@ TEST_F(PresenceClientTest, StartScanFailsWhenPresenceServiceIsGone) {
absl::Status scan_result = absl::UnknownError("");
absl::StatusOr<ScanSessionId> session_id =
CreateDefunctPresenceClient().StartScan(
CreateDefunctPresenceClient()->StartScan(
{}, {
.start_scan_cb =
[&](absl::Status status) { scan_result = status; },
@@ -121,19 +123,21 @@ TEST_F(PresenceClientTest, StartScanFailsWhenPresenceServiceIsGone) {
TEST_F(PresenceClientTest, GettingDeviceWorks) {
PresenceService presence_service;
PresenceClient presence_client = presence_service.CreatePresenceClient();
std::unique_ptr<PresenceClient> presence_client =
presence_service.CreatePresenceClient();
presence_service.UpdateLocalDeviceMetadata(CreateTestMetadata(), false, "",
{}, 0, 0, {});
auto device = presence_client.GetLocalDevice();
auto device = presence_client->GetLocalDevice();
ASSERT_NE(device, std::nullopt);
EXPECT_EQ((*device).GetEndpointId().length(), kEndpointIdLength);
EXPECT_EQ((*device).GetMetadata().SerializeAsString(),
EXPECT_EQ(device->GetEndpointId().length(), kEndpointIdLength);
EXPECT_EQ(device->GetMetadata().SerializeAsString(),
CreateTestMetadata().SerializeAsString());
}
TEST_F(PresenceClientTest, TestGettingDeviceDefunct) {
PresenceClient presence_client = CreateDefunctPresenceClient();
auto device = presence_client.GetLocalDevice();
std::unique_ptr<PresenceClient> presence_client =
CreateDefunctPresenceClient();
auto device = presence_client->GetLocalDevice();
EXPECT_EQ(device, std::nullopt);
}
} // namespace
+3 -2
View File
@@ -21,6 +21,7 @@
#include "internal/platform/borrowable.h"
#include "presence/data_types.h"
#include "presence/implementation/service_controller_impl.h"
#include "presence/presence_client_impl.h"
namespace nearby {
namespace presence {
@@ -30,8 +31,8 @@ PresenceService::PresenceService() {
service_controller_->GetLocalDeviceMetadata());
}
PresenceClient PresenceService::CreatePresenceClient() {
return PresenceClient(lender_.GetBorrowable());
std::unique_ptr<PresenceClient> PresenceService::CreatePresenceClient() {
return PresenceClientImpl::Factory::Create(lender_.GetBorrowable());
}
absl::StatusOr<ScanSessionId> PresenceService::StartScan(
+1 -1
View File
@@ -39,7 +39,7 @@ class PresenceService {
PresenceService();
~PresenceService() { lender_.Release(); }
PresenceClient CreatePresenceClient();
std::unique_ptr<PresenceClient> CreatePresenceClient();
absl::StatusOr<ScanSessionId> StartScan(ScanRequest scan_request,
ScanCallback callback);
+7 -5
View File
@@ -14,6 +14,7 @@
#include "presence/presence_service.h"
#include <memory>
#include <string>
#include <utility>
#include <vector>
@@ -67,22 +68,23 @@ TEST_F(PresenceServiceTest, StartThenStopScan) {
.start_scan_cb = [&](absl::Status status) { scan_result = status; },
};
PresenceService presence_service;
PresenceClient client = presence_service.CreatePresenceClient();
std::unique_ptr<PresenceClient> client =
presence_service.CreatePresenceClient();
absl::StatusOr<ScanSessionId> scan_session = client.StartScan(
absl::StatusOr<ScanSessionId> scan_session = client->StartScan(
{},
{
.start_scan_cb = [&](absl::Status status) { scan_result = status; },
});
absl::StatusOr<ScanSessionId> scan_session_with_default_params =
client.StartScan(ScanRequest(), ScanCallback());
client->StartScan(ScanRequest(), ScanCallback());
ASSERT_OK(scan_session);
ASSERT_OK(scan_session_with_default_params);
EXPECT_NE(*scan_session, *scan_session_with_default_params);
client.StopScan(*scan_session);
client.StopScan(*scan_session_with_default_params);
client->StopScan(*scan_session);
client->StopScan(*scan_session_with_default_params);
env_.Stop();
}