blob: 65a27545235b30cc85164d0e7db0736d769dc99e [file] [log] [blame]
// 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/remoting_log_to_server.h"
#include "base/test/mock_callback.h"
#include "base/test/task_environment.h"
#include "remoting/base/fake_oauth_token_getter.h"
#include "remoting/proto/remoting/v1/telemetry_service.grpc.pb.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace remoting {
namespace {
using testing::_;
} // namespace
class RemotingLogToServerTest : public testing::Test {
public:
RemotingLogToServerTest() {
EXPECT_EQ(ServerLogEntry::ME2ME, log_to_server_.mode());
log_to_server_.create_log_entry_ = mock_create_log_entry_.Get();
}
~RemotingLogToServerTest() override {
task_environment_.FastForwardUntilNoTasksRemain();
}
protected:
const net::BackoffEntry& GetBackoffEntry() const {
return log_to_server_.backoff_;
}
int GetMaxSendLogAttempts() const {
return log_to_server_.kMaxSendLogAttempts;
}
using CreateLogEntryResponseCallback =
RemotingLogToServer::CreateLogEntryResponseCallback;
base::test::TaskEnvironment task_environment_{
base::test::TaskEnvironment::TimeSource::MOCK_TIME};
base::MockCallback<RemotingLogToServer::CreateLogEntryCallback>
mock_create_log_entry_;
RemotingLogToServer log_to_server_{
ServerLogEntry::ME2ME,
std::make_unique<FakeOAuthTokenGetter>(OAuthTokenGetter::SUCCESS,
"fake_email",
"fake_access_token")};
};
TEST_F(RemotingLogToServerTest, SuccessfullySendOneLog) {
EXPECT_CALL(mock_create_log_entry_, Run(_, _))
.WillOnce([&](const apis::v1::CreateLogEntryRequest& request,
CreateLogEntryResponseCallback callback) {
ASSERT_EQ(1, request.payload().entry().field_size());
ASSERT_EQ("test-key", request.payload().entry().field(0).key());
ASSERT_EQ("test-value", request.payload().entry().field(0).value());
std::move(callback).Run(grpc::Status::OK, {});
});
ServerLogEntry entry;
entry.Set("test-key", "test-value");
log_to_server_.Log(entry);
task_environment_.FastForwardUntilNoTasksRemain();
ASSERT_EQ(0, GetBackoffEntry().failure_count());
}
TEST_F(RemotingLogToServerTest, FailedToSend_RetryWithBackoff) {
EXPECT_CALL(mock_create_log_entry_, Run(_, _))
.Times(GetMaxSendLogAttempts())
.WillRepeatedly([&](const apis::v1::CreateLogEntryRequest& request,
CreateLogEntryResponseCallback callback) {
ASSERT_EQ(1, request.payload().entry().field_size());
ASSERT_EQ("test-key", request.payload().entry().field(0).key());
ASSERT_EQ("test-value", request.payload().entry().field(0).value());
std::move(callback).Run(
grpc::Status(grpc::StatusCode::UNAVAILABLE, "unavailable"), {});
});
ServerLogEntry entry;
entry.Set("test-key", "test-value");
log_to_server_.Log(entry);
for (int i = 1; i <= GetMaxSendLogAttempts(); i++) {
task_environment_.FastForwardBy(GetBackoffEntry().GetTimeUntilRelease());
ASSERT_EQ(i, GetBackoffEntry().failure_count());
}
}
TEST_F(RemotingLogToServerTest, FailedToSendTwoLogs_RetryThenSucceeds) {
CreateLogEntryResponseCallback response_callback_1;
CreateLogEntryResponseCallback response_callback_2;
EXPECT_CALL(mock_create_log_entry_, Run(_, _))
.WillOnce([&](const apis::v1::CreateLogEntryRequest& request,
CreateLogEntryResponseCallback callback) {
ASSERT_EQ(1, request.payload().entry().field_size());
ASSERT_EQ("test-key-1", request.payload().entry().field(0).key());
ASSERT_EQ("test-value-1", request.payload().entry().field(0).value());
response_callback_1 = std::move(callback);
})
.WillOnce([&](const apis::v1::CreateLogEntryRequest& request,
CreateLogEntryResponseCallback callback) {
ASSERT_EQ(1, request.payload().entry().field_size());
ASSERT_EQ("test-key-2", request.payload().entry().field(0).key());
ASSERT_EQ("test-value-2", request.payload().entry().field(0).value());
response_callback_2 = std::move(callback);
})
.WillOnce([&](const apis::v1::CreateLogEntryRequest& request,
CreateLogEntryResponseCallback callback) {
ASSERT_EQ(1, request.payload().entry().field_size());
ASSERT_EQ("test-key-1", request.payload().entry().field(0).key());
ASSERT_EQ("test-value-1", request.payload().entry().field(0).value());
response_callback_1 = std::move(callback);
})
.WillOnce([&](const apis::v1::CreateLogEntryRequest& request,
CreateLogEntryResponseCallback callback) {
ASSERT_EQ(1, request.payload().entry().field_size());
ASSERT_EQ("test-key-2", request.payload().entry().field(0).key());
ASSERT_EQ("test-value-2", request.payload().entry().field(0).value());
response_callback_2 = std::move(callback);
});
ServerLogEntry entry_1;
entry_1.Set("test-key-1", "test-value-1");
log_to_server_.Log(entry_1);
task_environment_.FastForwardUntilNoTasksRemain();
ServerLogEntry entry_2;
entry_2.Set("test-key-2", "test-value-2");
log_to_server_.Log(entry_2);
task_environment_.FastForwardUntilNoTasksRemain();
ASSERT_EQ(0, GetBackoffEntry().failure_count());
std::move(response_callback_1)
.Run(grpc::Status(grpc::StatusCode::UNAVAILABLE, "unavailable"), {});
task_environment_.FastForwardUntilNoTasksRemain();
std::move(response_callback_2)
.Run(grpc::Status(grpc::StatusCode::UNAVAILABLE, "unavailable"), {});
task_environment_.FastForwardUntilNoTasksRemain();
ASSERT_EQ(2, GetBackoffEntry().failure_count());
std::move(response_callback_1).Run(grpc::Status::OK, {});
std::move(response_callback_2).Run(grpc::Status::OK, {});
task_environment_.FastForwardUntilNoTasksRemain();
ASSERT_EQ(0, GetBackoffEntry().failure_count());
}
} // namespace remoting