blob: d74425dc2d749ea54e143ac5850e7048fb77d323 [file] [log] [blame]
// Copyright 2022 The ChromiumOS Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "missive/missive/missive_impl.h"
#include <memory>
#include <utility>
#include <vector>
#include <base/bind.h>
#include <base/memory/scoped_refptr.h>
#include <base/test/task_environment.h>
#include <brillo/dbus/mock_dbus_method_response.h>
#include <dbus/bus.h>
#include <dbus/mock_bus.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include "missive/analytics/resource_collector_cpu.h"
#include "missive/analytics/resource_collector_memory.h"
#include "missive/analytics/resource_collector_storage.h"
#include "missive/dbus/mock_upload_client.h"
#include "missive/storage/storage_module_interface.h"
#include "missive/storage/storage_uploader_interface.h"
#include "missive/storage/test_storage_module.h"
#include "missive/util/test_support_callbacks.h"
using ::testing::_;
using ::testing::Eq;
using ::testing::NiceMock;
using ::testing::StrEq;
using ::testing::WithArg;
namespace reporting {
namespace {
MATCHER_P(EqualsProto,
message,
"Match a proto Message equal to the matcher's argument.") {
std::string expected_serialized, actual_serialized;
message.SerializeToString(&expected_serialized);
arg.SerializeToString(&actual_serialized);
return expected_serialized == actual_serialized;
}
class MissiveImplTest : public ::testing::Test {
public:
MissiveImplTest() = default;
protected:
void SetUp() override {
missive_ = std::make_unique<MissiveImpl>(
std::make_unique<MissiveArgs>("", "", "", ""),
base::BindOnce(
[](MissiveImplTest* self, scoped_refptr<dbus::Bus> bus,
base::OnceCallback<void(StatusOr<scoped_refptr<UploadClient>>)>
callback) {
self->upload_client_ =
base::MakeRefCounted<test::MockUploadClient>();
std::move(callback).Run(self->upload_client_);
},
base::Unretained(this)),
base::BindOnce(
[](MissiveImplTest* self, MissiveImpl* missive,
StorageOptions storage_options,
base::OnceCallback<void(
StatusOr<scoped_refptr<StorageModuleInterface>>)> callback) {
self->storage_module_ =
base::MakeRefCounted<test::TestStorageModule>();
std::move(callback).Run(self->storage_module_);
},
base::Unretained(this)));
dbus::Bus::Options options;
options.bus_type = dbus::Bus::SYSTEM;
test::TestEvent<Status> started;
missive_->StartUp(base::MakeRefCounted<NiceMock<dbus::MockBus>>(options),
started.cb());
ASSERT_OK(started.result());
}
void TearDown() override {
if (missive_) {
EXPECT_OK(missive_->ShutDown());
}
// Let everything ongoing to finish.
task_environment_.RunUntilIdle();
}
base::test::TaskEnvironment task_environment_;
scoped_refptr<UploadClient> upload_client_;
scoped_refptr<test::TestStorageModule> storage_module_;
std::unique_ptr<MissiveImpl> missive_;
};
TEST_F(MissiveImplTest, AsyncStartUploadTest) {
test::TestEvent<StatusOr<std::unique_ptr<UploaderInterface>>> uploader_event;
missive_->AsyncStartUpload(UploaderInterface::UploadReason::IMMEDIATE_FLUSH,
uploader_event.cb());
auto response_result = uploader_event.result();
EXPECT_OK(response_result) << response_result.status();
response_result.ValueOrDie()->Completed(
Status(error::INTERNAL, "Failing for tests"));
}
TEST_F(MissiveImplTest, EnqueueRecordTest) {
EnqueueRecordRequest request;
request.mutable_record()->set_data("DATA");
request.mutable_record()->set_destination(HEARTBEAT_EVENTS);
request.set_priority(FAST_BATCH);
EXPECT_CALL(*storage_module_, AddRecord(Eq(request.priority()),
EqualsProto(request.record()), _))
.WillOnce(
WithArg<2>([](StorageModuleInterface::EnqueueCallback callback) {
std::move(callback).Run(Status::StatusOK());
}));
auto response = std::make_unique<
brillo::dbus_utils::MockDBusMethodResponse<EnqueueRecordResponse>>();
test::TestEvent<const EnqueueRecordResponse&> response_event;
response->set_return_callback(response_event.cb());
missive_->EnqueueRecord(request, std::move(response));
const auto& response_result = response_event.ref_result();
EXPECT_THAT(response_result.status().code(), Eq(error::OK));
}
TEST_F(MissiveImplTest, FlushPriorityTest) {
FlushPriorityRequest request;
request.set_priority(MANUAL_BATCH);
EXPECT_CALL(*storage_module_, Flush(Eq(request.priority()), _))
.WillOnce(WithArg<1>([](StorageModuleInterface::FlushCallback callback) {
std::move(callback).Run(Status::StatusOK());
}));
auto response = std::make_unique<
brillo::dbus_utils::MockDBusMethodResponse<FlushPriorityResponse>>();
test::TestEvent<const FlushPriorityResponse&> response_event;
response->set_return_callback(response_event.cb());
missive_->FlushPriority(request, std::move(response));
const auto& response_result = response_event.ref_result();
EXPECT_THAT(response_result.status().code(), Eq(error::OK));
}
TEST_F(MissiveImplTest, ConfirmRecordUploadTest) {
ConfirmRecordUploadRequest request;
request.mutable_sequence_information()->set_sequencing_id(1234L);
request.mutable_sequence_information()->set_generation_id(9876L);
request.mutable_sequence_information()->set_priority(IMMEDIATE);
request.set_force_confirm(true);
EXPECT_CALL(*storage_module_,
ReportSuccess(EqualsProto(request.sequence_information()),
Eq(request.force_confirm())))
.Times(1);
auto response = std::make_unique<brillo::dbus_utils::MockDBusMethodResponse<
ConfirmRecordUploadResponse>>();
test::TestEvent<const ConfirmRecordUploadResponse&> response_event;
response->set_return_callback(response_event.cb());
missive_->ConfirmRecordUpload(request, std::move(response));
const auto& response_result = response_event.ref_result();
EXPECT_THAT(response_result.status().code(), Eq(error::OK));
}
TEST_F(MissiveImplTest, UpdateEncryptionKeyTest) {
UpdateEncryptionKeyRequest request;
request.mutable_signed_encryption_info()->set_public_asymmetric_key(
"PUBLIC_KEY");
request.mutable_signed_encryption_info()->set_public_key_id(555666);
request.mutable_signed_encryption_info()->set_signature("SIGNATURE");
EXPECT_CALL(
*storage_module_,
UpdateEncryptionKey(EqualsProto(request.signed_encryption_info())))
.Times(1);
auto response = std::make_unique<brillo::dbus_utils::MockDBusMethodResponse<
UpdateEncryptionKeyResponse>>();
test::TestEvent<const UpdateEncryptionKeyResponse&> response_event;
response->set_return_callback(response_event.cb());
missive_->UpdateEncryptionKey(request, std::move(response));
const auto& response_result = response_event.ref_result();
EXPECT_THAT(response_result.status().code(), Eq(error::OK));
}
TEST_F(MissiveImplTest, ResponseWithErrorTest) {
const Status error{error::INTERNAL, "Test generated error"};
FlushPriorityRequest request;
request.set_priority(SLOW_BATCH);
EXPECT_CALL(*storage_module_, Flush(Eq(request.priority()), _))
.WillOnce(
WithArg<1>([&error](StorageModuleInterface::FlushCallback callback) {
std::move(callback).Run(error);
}));
auto response = std::make_unique<
brillo::dbus_utils::MockDBusMethodResponse<FlushPriorityResponse>>();
test::TestEvent<const FlushPriorityResponse&> response_event;
response->set_return_callback(response_event.cb());
missive_->FlushPriority(request, std::move(response));
const auto& response_result = response_event.ref_result();
EXPECT_THAT(response_result.status().code(), Eq(error.error_code()));
EXPECT_THAT(response_result.status().error_message(),
StrEq(std::string(error.error_message())));
}
} // namespace
} // namespace reporting