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") {
sources = [
"ftl_message_reception_channel_unittest.cc",
"ftl_messaging_client_unittest.cc",
"ftl_registration_manager_unittest.cc",
"ftl_signal_strategy_unittest.cc",
"iq_sender_unittest.cc",
"jid_util_unittest.cc",
......
......@@ -13,6 +13,7 @@
#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_executor.h"
#include "remoting/proto/ftl/v1/ftl_services.grpc.pb.h"
#include "remoting/signaling/ftl_device_id_provider.h"
#include "remoting/signaling/ftl_grpc_context.h"
......@@ -37,14 +38,61 @@ constexpr base::TimeDelta kRefreshBufferTime = base::TimeDelta::FromHours(1);
} // 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(
OAuthTokenGetter* token_getter,
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)),
sign_in_backoff_(&FtlGrpcContext::GetBackoffPolicy()) {
DCHECK(device_id_provider_);
registration_stub_ = Registration::NewStub(FtlGrpcContext::CreateChannel());
}
FtlRegistrationManager::~FtlRegistrationManager() = default;
......@@ -62,7 +110,7 @@ void FtlRegistrationManager::SignOut() {
if (!IsSignedIn()) {
return;
}
executor_->CancelPendingRequests();
registration_client_->CancelPendingRequests();
sign_in_refresh_timer_.Stop();
registration_id_.clear();
ftl_auth_token_.clear();
......@@ -96,14 +144,9 @@ void FtlRegistrationManager::DoSignInGaia(DoneCallback on_done) {
request.mutable_register_data()->add_caps(kFtlCapabilities[i]);
}
auto grpc_request = CreateGrpcAsyncUnaryRequest(
base::BindOnce(&Registration::Stub::AsyncSignInGaia,
base::Unretained(registration_stub_.get())),
request,
base::BindOnce(&FtlRegistrationManager::OnSignInGaiaResponse,
registration_client_->SignInGaia(
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(
......
......@@ -12,13 +12,22 @@
#include "base/macros.h"
#include "base/timer/timer.h"
#include "net/base/backoff_entry.h"
#include "remoting/proto/ftl/v1/ftl_services.grpc.pb.h"
#include "remoting/signaling/registration_manager.h"
namespace grpc {
class Status;
} // namespace grpc
namespace remoting {
namespace ftl {
class SignInGaiaRequest;
class SignInGaiaResponse;
} // namespace ftl
class FtlDeviceIdProvider;
class GrpcExecutor;
class OAuthTokenGetter;
// Class for registering the user with FTL service.
......@@ -39,17 +48,28 @@ class FtlRegistrationManager final : public RegistrationManager {
std::string GetFtlAuthToken() const override;
private:
using Registration =
google::internal::communications::instantmessaging::v1::Registration;
using SignInGaiaResponseCallback =
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 OnSignInGaiaResponse(DoneCallback on_done,
const grpc::Status& status,
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<Registration::Stub> registration_stub_;
base::OneShotTimer sign_in_backoff_timer_;
base::OneShotTimer sign_in_refresh_timer_;
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