blob: d530496715e12b9aa26e9cb4acb52dc6d7363ac0 [file] [log] [blame]
// Copyright 2021 The Fuchsia 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 <lib/efi/testing/stub_boot_services.h>
#include <stdio.h>
#include <efi/protocol/block-io.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>
namespace efi {
namespace {
using testing::_;
using testing::Return;
// Creating a second is OK as long as the first has gone out of scope.
TEST(StubBootServices, CreateTwice) {
StubBootServices();
StubBootServices();
}
// Creating a second while the first is still up is a fatal error.
TEST(StubBootServicesDeathTest, CreateDuplicate) {
StubBootServices stub;
ASSERT_DEATH(StubBootServices(), "");
}
TEST(StubBootServices, AllocateAndFreePool) {
StubBootServices stub;
void* memory = nullptr;
ASSERT_EQ(EFI_SUCCESS, stub.services()->AllocatePool(EfiConventionalMemory, 16, &memory));
ASSERT_NE(nullptr, memory);
ASSERT_EQ(EFI_SUCCESS, stub.services()->FreePool(memory));
}
// Make sure mocking out the class works as expected. This ensures our code to
// bounce the C callback into the C++ class is working properly.
class MockBootServices : public StubBootServices {
public:
MOCK_METHOD(efi_status, OpenProtocol,
(efi_handle handle, efi_guid* protocol, void** intf, efi_handle agent_handle,
efi_handle controller_handle, uint32_t attributes),
(override));
MOCK_METHOD(efi_status, CloseProtocol,
(efi_handle handle, efi_guid* protocol, efi_handle agent_handle,
efi_handle controller_handle),
(override));
MOCK_METHOD(efi_status, LocateHandleBuffer,
(efi_locate_search_type search_type, efi_guid* protocol, void* search_key,
size_t* num_handles, efi_handle** buf),
(override));
};
const efi_handle kTestHandle1 = reinterpret_cast<efi_handle>(0x1);
const efi_handle kTestHandle2 = reinterpret_cast<efi_handle>(0x2);
const efi_handle kTestHandle3 = reinterpret_cast<efi_handle>(0x3);
TEST(StubBootServices, OpenProtocol) {
MockBootServices mock;
efi_guid protocol_guid = EFI_BLOCK_IO_PROTOCOL_GUID;
// Expect any non-zero return value so we can check that it worked.
EXPECT_CALL(mock,
OpenProtocol(kTestHandle1, &protocol_guid, _, kTestHandle2, kTestHandle3, 0xABCD))
.WillOnce(Return(EFI_TIMEOUT));
void* arg = nullptr;
EXPECT_EQ(EFI_TIMEOUT, mock.services()->OpenProtocol(kTestHandle1, &protocol_guid, &arg,
kTestHandle2, kTestHandle3, 0xABCD));
}
TEST(StubBootServices, CloseProtocol) {
MockBootServices mock;
efi_guid protocol_guid = EFI_BLOCK_IO_PROTOCOL_GUID;
EXPECT_CALL(mock, CloseProtocol(kTestHandle1, &protocol_guid, kTestHandle2, kTestHandle3))
.WillOnce(Return(EFI_TIMEOUT));
EXPECT_EQ(EFI_TIMEOUT, mock.services()->CloseProtocol(kTestHandle1, &protocol_guid, kTestHandle2,
kTestHandle3));
}
TEST(StubBootServices, LocateHandleBuffer) {
MockBootServices mock;
efi_guid protocol_guid = EFI_BLOCK_IO_PROTOCOL_GUID;
EXPECT_CALL(mock, LocateHandleBuffer(ByProtocol, &protocol_guid, _, _, _))
.WillOnce(Return(EFI_TIMEOUT));
EXPECT_EQ(EFI_TIMEOUT, mock.services()->LocateHandleBuffer(ByProtocol, &protocol_guid, nullptr,
nullptr, nullptr));
}
} // namespace
} // namespace efi