blob: d7710dcfadee6520f4f0d943b4ee2e8f10cca431 [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/base/protobuf_http_status.h"
#include "remoting/proto/remoting/v1/telemetry_messages.pb.h"
#include "services/network/public/cpp/shared_url_loader_factory.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"),
nullptr};
};
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(
ProtobufHttpStatus::OK(),
std::make_unique<apis::v1::CreateLogEntryResponse>());
});
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(
ProtobufHttpStatus(ProtobufHttpStatus::Code::UNAVAILABLE,
"unavailable"),
nullptr);
});
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(ProtobufHttpStatus(ProtobufHttpStatus::Code::UNAVAILABLE,
"unavailable"),
nullptr);
task_environment_.FastForwardUntilNoTasksRemain();
std::move(response_callback_2)
.Run(ProtobufHttpStatus(ProtobufHttpStatus::Code::UNAVAILABLE,
"unavailable"),
nullptr);
task_environment_.FastForwardUntilNoTasksRemain();
ASSERT_EQ(2, GetBackoffEntry().failure_count());
std::move(response_callback_1)
.Run(ProtobufHttpStatus::OK(),
std::make_unique<apis::v1::CreateLogEntryResponse>());
std::move(response_callback_2)
.Run(ProtobufHttpStatus::OK(),
std::make_unique<apis::v1::CreateLogEntryResponse>());
task_environment_.FastForwardUntilNoTasksRemain();
ASSERT_EQ(0, GetBackoffEntry().failure_count());
}
} // namespace remoting