Commit a77193b5 authored by Yuwei Huang's avatar Yuwei Huang Committed by Commit Bot

[remoting][FTL] Add unittest for FtlRegistrationManager

Bug: 965746
Change-Id: I0d9b31fea543ee0b9e661f2025bc9133863f9dce
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1643786Reviewed-by: default avatarJoe Downing <joedow@chromium.org>
Commit-Queue: Joe Downing <joedow@chromium.org>
Cr-Commit-Position: refs/heads/master@{#666271}
parent f12810a0
...@@ -134,6 +134,7 @@ source_set("unit_tests") { ...@@ -134,6 +134,7 @@ source_set("unit_tests") {
sources = [ sources = [
"ftl_message_reception_channel_unittest.cc", "ftl_message_reception_channel_unittest.cc",
"ftl_messaging_client_unittest.cc", "ftl_messaging_client_unittest.cc",
"ftl_registration_manager_unittest.cc",
"ftl_signal_strategy_unittest.cc", "ftl_signal_strategy_unittest.cc",
"iq_sender_unittest.cc", "iq_sender_unittest.cc",
"jid_util_unittest.cc", "jid_util_unittest.cc",
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
#include "remoting/base/grpc_support/grpc_async_unary_request.h" #include "remoting/base/grpc_support/grpc_async_unary_request.h"
#include "remoting/base/grpc_support/grpc_authenticated_executor.h" #include "remoting/base/grpc_support/grpc_authenticated_executor.h"
#include "remoting/base/grpc_support/grpc_executor.h" #include "remoting/base/grpc_support/grpc_executor.h"
#include "remoting/proto/ftl/v1/ftl_services.grpc.pb.h"
#include "remoting/signaling/ftl_device_id_provider.h" #include "remoting/signaling/ftl_device_id_provider.h"
#include "remoting/signaling/ftl_grpc_context.h" #include "remoting/signaling/ftl_grpc_context.h"
...@@ -37,14 +38,61 @@ constexpr base::TimeDelta kRefreshBufferTime = base::TimeDelta::FromHours(1); ...@@ -37,14 +38,61 @@ constexpr base::TimeDelta kRefreshBufferTime = base::TimeDelta::FromHours(1);
} // namespace } // namespace
class FtlRegistrationManager::RegistrationClientImpl final
: public FtlRegistrationManager::RegistrationClient {
public:
explicit RegistrationClientImpl(OAuthTokenGetter* token_getter);
~RegistrationClientImpl() override;
// RegistrationClient implementations.
void SignInGaia(const ftl::SignInGaiaRequest& request,
SignInGaiaResponseCallback on_done) override;
void CancelPendingRequests() override;
private:
using Registration =
google::internal::communications::instantmessaging::v1::Registration;
GrpcAuthenticatedExecutor executor_;
std::unique_ptr<Registration::Stub> registration_stub_;
DISALLOW_COPY_AND_ASSIGN(RegistrationClientImpl);
};
FtlRegistrationManager::RegistrationClientImpl::RegistrationClientImpl(
OAuthTokenGetter* token_getter)
: executor_(token_getter),
registration_stub_(
Registration::NewStub(FtlGrpcContext::CreateChannel())) {}
FtlRegistrationManager::RegistrationClientImpl::~RegistrationClientImpl() =
default;
void FtlRegistrationManager::RegistrationClientImpl::SignInGaia(
const ftl::SignInGaiaRequest& request,
SignInGaiaResponseCallback on_done) {
auto grpc_request = CreateGrpcAsyncUnaryRequest(
base::BindOnce(&Registration::Stub::AsyncSignInGaia,
base::Unretained(registration_stub_.get())),
request, std::move(on_done));
FtlGrpcContext::FillClientContext(grpc_request->context());
executor_.ExecuteRpc(std::move(grpc_request));
}
void FtlRegistrationManager::RegistrationClientImpl::CancelPendingRequests() {
executor_.CancelPendingRequests();
}
// End of RegistrationClientImplImpl
FtlRegistrationManager::FtlRegistrationManager( FtlRegistrationManager::FtlRegistrationManager(
OAuthTokenGetter* token_getter, OAuthTokenGetter* token_getter,
std::unique_ptr<FtlDeviceIdProvider> device_id_provider) std::unique_ptr<FtlDeviceIdProvider> device_id_provider)
: executor_(std::make_unique<GrpcAuthenticatedExecutor>(token_getter)), : registration_client_(
std::make_unique<RegistrationClientImpl>(token_getter)),
device_id_provider_(std::move(device_id_provider)), device_id_provider_(std::move(device_id_provider)),
sign_in_backoff_(&FtlGrpcContext::GetBackoffPolicy()) { sign_in_backoff_(&FtlGrpcContext::GetBackoffPolicy()) {
DCHECK(device_id_provider_); DCHECK(device_id_provider_);
registration_stub_ = Registration::NewStub(FtlGrpcContext::CreateChannel());
} }
FtlRegistrationManager::~FtlRegistrationManager() = default; FtlRegistrationManager::~FtlRegistrationManager() = default;
...@@ -62,7 +110,7 @@ void FtlRegistrationManager::SignOut() { ...@@ -62,7 +110,7 @@ void FtlRegistrationManager::SignOut() {
if (!IsSignedIn()) { if (!IsSignedIn()) {
return; return;
} }
executor_->CancelPendingRequests(); registration_client_->CancelPendingRequests();
sign_in_refresh_timer_.Stop(); sign_in_refresh_timer_.Stop();
registration_id_.clear(); registration_id_.clear();
ftl_auth_token_.clear(); ftl_auth_token_.clear();
...@@ -96,14 +144,9 @@ void FtlRegistrationManager::DoSignInGaia(DoneCallback on_done) { ...@@ -96,14 +144,9 @@ void FtlRegistrationManager::DoSignInGaia(DoneCallback on_done) {
request.mutable_register_data()->add_caps(kFtlCapabilities[i]); request.mutable_register_data()->add_caps(kFtlCapabilities[i]);
} }
auto grpc_request = CreateGrpcAsyncUnaryRequest( registration_client_->SignInGaia(
base::BindOnce(&Registration::Stub::AsyncSignInGaia, request, base::BindOnce(&FtlRegistrationManager::OnSignInGaiaResponse,
base::Unretained(registration_stub_.get())), base::Unretained(this), std::move(on_done)));
request,
base::BindOnce(&FtlRegistrationManager::OnSignInGaiaResponse,
base::Unretained(this), std::move(on_done)));
FtlGrpcContext::FillClientContext(grpc_request->context());
executor_->ExecuteRpc(std::move(grpc_request));
} }
void FtlRegistrationManager::OnSignInGaiaResponse( void FtlRegistrationManager::OnSignInGaiaResponse(
......
...@@ -12,13 +12,22 @@ ...@@ -12,13 +12,22 @@
#include "base/macros.h" #include "base/macros.h"
#include "base/timer/timer.h" #include "base/timer/timer.h"
#include "net/base/backoff_entry.h" #include "net/base/backoff_entry.h"
#include "remoting/proto/ftl/v1/ftl_services.grpc.pb.h"
#include "remoting/signaling/registration_manager.h" #include "remoting/signaling/registration_manager.h"
namespace grpc {
class Status;
} // namespace grpc
namespace remoting { namespace remoting {
namespace ftl {
class SignInGaiaRequest;
class SignInGaiaResponse;
} // namespace ftl
class FtlDeviceIdProvider; class FtlDeviceIdProvider;
class GrpcExecutor;
class OAuthTokenGetter; class OAuthTokenGetter;
// Class for registering the user with FTL service. // Class for registering the user with FTL service.
...@@ -39,17 +48,28 @@ class FtlRegistrationManager final : public RegistrationManager { ...@@ -39,17 +48,28 @@ class FtlRegistrationManager final : public RegistrationManager {
std::string GetFtlAuthToken() const override; std::string GetFtlAuthToken() const override;
private: private:
using Registration = using SignInGaiaResponseCallback =
google::internal::communications::instantmessaging::v1::Registration; base::OnceCallback<void(const grpc::Status&,
const ftl::SignInGaiaResponse&)>;
friend class FtlRegistrationManagerTest;
class RegistrationClient {
public:
virtual ~RegistrationClient() = default;
virtual void SignInGaia(const ftl::SignInGaiaRequest& request,
SignInGaiaResponseCallback on_done) = 0;
virtual void CancelPendingRequests() = 0;
};
class RegistrationClientImpl;
void DoSignInGaia(DoneCallback on_done); void DoSignInGaia(DoneCallback on_done);
void OnSignInGaiaResponse(DoneCallback on_done, void OnSignInGaiaResponse(DoneCallback on_done,
const grpc::Status& status, const grpc::Status& status,
const ftl::SignInGaiaResponse& response); const ftl::SignInGaiaResponse& response);
std::unique_ptr<GrpcExecutor> executor_; std::unique_ptr<RegistrationClient> registration_client_;
std::unique_ptr<FtlDeviceIdProvider> device_id_provider_; std::unique_ptr<FtlDeviceIdProvider> device_id_provider_;
std::unique_ptr<Registration::Stub> registration_stub_;
base::OneShotTimer sign_in_backoff_timer_; base::OneShotTimer sign_in_backoff_timer_;
base::OneShotTimer sign_in_refresh_timer_; base::OneShotTimer sign_in_refresh_timer_;
std::string registration_id_; std::string registration_id_;
......
// Copyright 2019 The Chromium 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 "remoting/signaling/ftl_registration_manager.h"
#include "base/guid.h"
#include "base/test/mock_callback.h"
#include "base/test/scoped_task_environment.h"
#include "base/time/time.h"
#include "remoting/base/fake_oauth_token_getter.h"
#include "remoting/proto/ftl/v1/ftl_messages.pb.h"
#include "remoting/signaling/ftl_client_uuid_device_id_provider.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace remoting {
namespace {
using testing::_;
using SignInGaiaResponseCallback =
base::OnceCallback<void(const grpc::Status&,
const ftl::SignInGaiaResponse&)>;
constexpr char kAuthToken[] = "auth_token";
constexpr int64_t kAuthTokenExpiresInMicroseconds = 86400000000; // = 1 day
constexpr base::TimeDelta kAuthTokenExpiration =
base::TimeDelta::FromMicroseconds(kAuthTokenExpiresInMicroseconds);
MATCHER_P(HasErrorCode, error_code, "") {
return arg.error_code() == error_code;
}
MATCHER(IsStatusOk, "") {
return arg.ok();
}
void VerifySignInGaiaRequest(const ftl::SignInGaiaRequest& request) {
ASSERT_EQ(ftl::SignInGaiaMode_Value_DEFAULT_CREATE_ACCOUNT, request.mode());
ASSERT_TRUE(base::IsValidGUID(request.register_data().device_id().id()));
ASSERT_LT(0, request.register_data().caps_size());
}
decltype(auto) RespondOkToSignInGaia(const std::string& registration_id) {
return [registration_id](const ftl::SignInGaiaRequest& request,
SignInGaiaResponseCallback on_done) {
VerifySignInGaiaRequest(request);
ftl::SignInGaiaResponse response;
response.set_registration_id(registration_id);
response.mutable_auth_token()->set_payload(kAuthToken);
response.mutable_auth_token()->set_expires_in(
kAuthTokenExpiresInMicroseconds);
std::move(on_done).Run(grpc::Status::OK, response);
};
}
} // namespace
class FtlRegistrationManagerTest : public testing::Test {
public:
FtlRegistrationManagerTest() {
auto registration_client = std::make_unique<MockRegistrationClient>();
registration_client_ = registration_client.get();
registration_manager_.registration_client_ = std::move(registration_client);
}
~FtlRegistrationManagerTest() override = default;
protected:
class MockRegistrationClient
: public FtlRegistrationManager::RegistrationClient {
public:
MOCK_METHOD2(SignInGaia,
void(const ftl::SignInGaiaRequest&,
SignInGaiaResponseCallback));
MOCK_METHOD0(CancelPendingRequests, void());
};
const net::BackoffEntry& GetBackoff() const {
return registration_manager_.sign_in_backoff_;
}
base::test::ScopedTaskEnvironment scoped_task_environment_{
base::test::ScopedTaskEnvironment::MainThreadType::MOCK_TIME,
base::test::ScopedTaskEnvironment::NowSource::MAIN_THREAD_MOCK_TIME};
FakeOAuthTokenGetter token_getter{OAuthTokenGetter::SUCCESS, "fake_email",
"access_token"};
FtlRegistrationManager registration_manager_{
&token_getter, std::make_unique<FtlClientUuidDeviceIdProvider>()};
MockRegistrationClient* registration_client_ = nullptr;
base::MockCallback<base::RepeatingCallback<void(const grpc::Status& status)>>
done_callback_;
};
TEST_F(FtlRegistrationManagerTest, SignInGaiaAndAutorefresh) {
ASSERT_FALSE(registration_manager_.IsSignedIn());
ASSERT_TRUE(registration_manager_.GetRegistrationId().empty());
ASSERT_TRUE(registration_manager_.GetFtlAuthToken().empty());
EXPECT_CALL(*registration_client_, SignInGaia(_, _))
.WillOnce(RespondOkToSignInGaia("registration_id_1"))
.WillOnce(RespondOkToSignInGaia("registration_id_2"));
EXPECT_CALL(done_callback_, Run(IsStatusOk())).Times(1);
registration_manager_.SignInGaia(done_callback_.Get());
scoped_task_environment_.FastForwardBy(GetBackoff().GetTimeUntilRelease());
ASSERT_TRUE(registration_manager_.IsSignedIn());
ASSERT_EQ("registration_id_1", registration_manager_.GetRegistrationId());
ASSERT_EQ(kAuthToken, registration_manager_.GetFtlAuthToken());
scoped_task_environment_.FastForwardBy(kAuthTokenExpiration);
scoped_task_environment_.FastForwardBy(GetBackoff().GetTimeUntilRelease());
ASSERT_EQ("registration_id_2", registration_manager_.GetRegistrationId());
}
TEST_F(FtlRegistrationManagerTest, FailedToSignIn_Backoff) {
ASSERT_FALSE(registration_manager_.IsSignedIn());
ASSERT_TRUE(registration_manager_.GetRegistrationId().empty());
ASSERT_TRUE(registration_manager_.GetFtlAuthToken().empty());
ASSERT_EQ(0, GetBackoff().failure_count());
EXPECT_CALL(*registration_client_, SignInGaia(_, _))
.WillOnce([](const ftl::SignInGaiaRequest& request,
SignInGaiaResponseCallback on_done) {
VerifySignInGaiaRequest(request);
std::move(on_done).Run(
grpc::Status(grpc::StatusCode::UNAVAILABLE, "unavailable"), {});
})
.WillOnce([](const ftl::SignInGaiaRequest& request,
SignInGaiaResponseCallback on_done) {
VerifySignInGaiaRequest(request);
std::move(on_done).Run(
grpc::Status(grpc::StatusCode::UNAUTHENTICATED, "unauthenticated"),
{});
})
.WillOnce(RespondOkToSignInGaia("registration_id"));
EXPECT_CALL(done_callback_, Run(HasErrorCode(grpc::StatusCode::UNAVAILABLE)))
.Times(1);
registration_manager_.SignInGaia(done_callback_.Get());
scoped_task_environment_.FastForwardBy(GetBackoff().GetTimeUntilRelease());
ASSERT_FALSE(registration_manager_.IsSignedIn());
ASSERT_EQ(1, GetBackoff().failure_count());
EXPECT_CALL(done_callback_,
Run(HasErrorCode(grpc::StatusCode::UNAUTHENTICATED)))
.Times(1);
registration_manager_.SignInGaia(done_callback_.Get());
scoped_task_environment_.FastForwardBy(GetBackoff().GetTimeUntilRelease());
ASSERT_FALSE(registration_manager_.IsSignedIn());
ASSERT_EQ(2, GetBackoff().failure_count());
EXPECT_CALL(done_callback_, Run(IsStatusOk())).Times(1);
registration_manager_.SignInGaia(done_callback_.Get());
scoped_task_environment_.FastForwardBy(GetBackoff().GetTimeUntilRelease());
ASSERT_TRUE(registration_manager_.IsSignedIn());
ASSERT_EQ("registration_id", registration_manager_.GetRegistrationId());
ASSERT_EQ(0, GetBackoff().failure_count());
}
TEST_F(FtlRegistrationManagerTest, SignOut) {
ASSERT_FALSE(registration_manager_.IsSignedIn());
ASSERT_TRUE(registration_manager_.GetRegistrationId().empty());
ASSERT_TRUE(registration_manager_.GetFtlAuthToken().empty());
EXPECT_CALL(*registration_client_, SignInGaia(_, _))
.WillOnce(RespondOkToSignInGaia("registration_id"));
EXPECT_CALL(done_callback_, Run(IsStatusOk())).Times(1);
registration_manager_.SignInGaia(done_callback_.Get());
scoped_task_environment_.FastForwardBy(GetBackoff().GetTimeUntilRelease());
ASSERT_TRUE(registration_manager_.IsSignedIn());
ASSERT_EQ("registration_id", registration_manager_.GetRegistrationId());
ASSERT_EQ(kAuthToken, registration_manager_.GetFtlAuthToken());
EXPECT_CALL(*registration_client_, CancelPendingRequests()).Times(1);
registration_manager_.SignOut();
ASSERT_FALSE(registration_manager_.IsSignedIn());
ASSERT_TRUE(registration_manager_.GetRegistrationId().empty());
ASSERT_TRUE(registration_manager_.GetFtlAuthToken().empty());
scoped_task_environment_.FastForwardUntilNoTasksRemain();
ASSERT_FALSE(registration_manager_.IsSignedIn());
}
} // namespace remoting
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment