mirror of
https://github.com/Telecominfraproject/OpenCellular.git
synced 2025-11-25 18:55:24 +00:00
The existing library had a bunch of dependencies which are too many to build for the 32-bit platform. So this checkin prunes the dependency list by building only things that are absolutely required for the functionality used in 32-bit Post-Installer. Made the use of libuuid restricted only to cgpt and unit tests so that libcgpt-cc.a doesn't depend on it. BUG=chromium-os:25374 TEST=Built 32-bit and 64-bit. Tested 32-bit post-install. Change-Id: Idd0826fdf507a95728fee8adac9520e26f05d469 Reviewed-on: https://gerrit.chromium.org/gerrit/16433 Reviewed-by: Don Garrett <dgarrett@chromium.org> Reviewed-by: Sonny Rao <sonnyrao@chromium.org> Commit-Ready: Jay Srinivasan <jaysri@chromium.org> Tested-by: Jay Srinivasan <jaysri@chromium.org>
404 lines
14 KiB
C++
404 lines
14 KiB
C++
// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
// found in the LICENSE file.
|
|
|
|
// Unit tests for CgptManager class.
|
|
#include <string>
|
|
|
|
#include "../cgpt/CgptManager.h"
|
|
|
|
// We use some specific GUID constants for some of the tests,
|
|
// so pulling in cgpt.h. Make sure this is included after
|
|
// CgptManager.h so that we can test the actual usage of
|
|
// CgptManager.h as the post-install package would use.
|
|
// Example: this would catch an incorrect usage of a GUID
|
|
// that's defined only in cgpt.h and being accidentally
|
|
// used in CgptManager.h (which should not have any cgpt.h
|
|
// dependencies).
|
|
extern "C" {
|
|
#include "../cgpt/cgpt.h"
|
|
}
|
|
|
|
#include <base/logging.h>
|
|
#include <gflags/gflags.h>
|
|
#include <gtest/gtest.h>
|
|
#include <uuid/uuid.h>
|
|
|
|
using std::string;
|
|
|
|
static const Guid p2guid = {{{0, 1, 2, 3, 4, {2, 2, 2, 2, 2, 2}}}};
|
|
static const Guid p3guid = {{{0, 6, 5, 4, 2, {3, 3, 3, 3, 3, 3}}}};
|
|
|
|
#define EXPECT_SUCCESS(c) EXPECT_EQ(kCgptSuccess, c)
|
|
|
|
// The --v flag controls the log verbosity level.
|
|
DEFINE_int32(v, 0, 0);
|
|
|
|
// This class unit tests the CgptManager class.
|
|
class CgptManagerUnitTest : public ::testing::Test {
|
|
public:
|
|
CgptManagerUnitTest() {
|
|
// Even though the post-installer doesn't use any methods that require
|
|
// uuid_generate, for the unit test we use those methods, so we need to
|
|
// set the uuid_generator.
|
|
uuid_generator = uuid_generate;
|
|
}
|
|
|
|
void SetUp() {
|
|
const string device_name = "/tmp/DummyFileForCgptManagerTests.bin";
|
|
|
|
CreateDummyDevice(device_name);
|
|
|
|
LOG(INFO) << "Initializing cgpt with " << device_name;
|
|
EXPECT_SUCCESS(cgpt_manager.Initialize(device_name));
|
|
EXPECT_SUCCESS(cgpt_manager.ClearAll());
|
|
|
|
CheckPartitionCount(0);
|
|
}
|
|
|
|
virtual ~CgptManagerUnitTest() { }
|
|
|
|
protected:
|
|
CgptManager cgpt_manager;
|
|
|
|
void CreateDummyDevice(const string& dummy_device) {
|
|
FILE* fp = fopen(dummy_device.c_str(), "w");
|
|
|
|
ASSERT_TRUE(fp != NULL);
|
|
|
|
const int kNumSectors = 1000;
|
|
const int kSectorSize = 512;
|
|
const char kFillChar = '7'; // Some character, value doesn't matter.
|
|
|
|
for(int i = 0; i < kNumSectors * kSectorSize; i++) {
|
|
EXPECT_EQ(kFillChar, fputc(kFillChar, fp));
|
|
}
|
|
|
|
fclose(fp);
|
|
}
|
|
|
|
void CheckEquality(string field,
|
|
uint64_t expected,
|
|
uint64_t actual) {
|
|
|
|
|
|
VLOG(1) << field << ":"
|
|
<< "Expected = " << expected
|
|
<< ";Actual = " << actual;
|
|
|
|
EXPECT_EQ(expected, actual);
|
|
}
|
|
|
|
|
|
void CheckGuidEquality(string field,
|
|
const Guid& expected_id,
|
|
const Guid& actual_id) {
|
|
char expected_id_str[GUID_STRLEN];
|
|
GuidToStr(&expected_id, expected_id_str, sizeof(expected_id_str));
|
|
|
|
char actual_id_str[GUID_STRLEN];
|
|
GuidToStr(&actual_id, actual_id_str, sizeof(actual_id_str));
|
|
|
|
VLOG(1) << field << ":"
|
|
<< "Expected = " << expected_id_str
|
|
<< ";Actual = " << actual_id_str;
|
|
|
|
EXPECT_TRUE(GuidEqual(&expected_id, &actual_id));
|
|
}
|
|
|
|
// Checks if the current number of partitions in the device matches
|
|
// the value of expected_num_partitions.
|
|
void CheckPartitionCount(uint8 expected_num_partitions) {
|
|
uint8_t actual_num_partitions;
|
|
EXPECT_SUCCESS(cgpt_manager.GetNumNonEmptyPartitions(
|
|
&actual_num_partitions));
|
|
|
|
CheckEquality("NumPartitions",
|
|
expected_num_partitions,
|
|
actual_num_partitions);
|
|
}
|
|
|
|
void SetAndCheckSuccessfulBit(uint32_t partition_number,
|
|
bool expected_is_successful) {
|
|
EXPECT_SUCCESS(cgpt_manager.SetSuccessful(partition_number,
|
|
expected_is_successful));
|
|
|
|
bool actual_is_successful;
|
|
EXPECT_SUCCESS(cgpt_manager.GetSuccessful(partition_number,
|
|
&actual_is_successful));
|
|
EXPECT_EQ(expected_is_successful, actual_is_successful);
|
|
}
|
|
|
|
|
|
void SetAndCheckNumTriesLeft(uint32_t partition_number,
|
|
int expected_num_tries) {
|
|
EXPECT_SUCCESS(cgpt_manager.SetNumTriesLeft(partition_number,
|
|
expected_num_tries));
|
|
|
|
int actual_num_tries;
|
|
EXPECT_SUCCESS(cgpt_manager.GetNumTriesLeft(partition_number,
|
|
&actual_num_tries));
|
|
CheckEquality("NumTries", expected_num_tries, actual_num_tries);
|
|
}
|
|
|
|
void SetAndCheckPriority(uint32_t partition_number,
|
|
uint8_t expected_priority) {
|
|
EXPECT_SUCCESS(cgpt_manager.SetPriority(partition_number,
|
|
expected_priority));
|
|
|
|
uint8_t actual_priority;
|
|
EXPECT_SUCCESS(cgpt_manager.GetPriority(partition_number,
|
|
&actual_priority));
|
|
CheckEquality("Priority", expected_priority, actual_priority);
|
|
}
|
|
|
|
void CheckPriority(uint32_t partition_number,
|
|
uint8_t expected_priority) {
|
|
uint8_t actual_priority;
|
|
EXPECT_SUCCESS(cgpt_manager.GetPriority(partition_number,
|
|
&actual_priority));
|
|
CheckEquality("Priority", expected_priority, actual_priority);
|
|
}
|
|
|
|
|
|
void CheckBeginningOffset(uint32_t partition_number,
|
|
uint64_t expected_offset) {
|
|
uint64_t actual_offset;
|
|
EXPECT_SUCCESS(cgpt_manager.GetBeginningOffset(partition_number,
|
|
&actual_offset));
|
|
CheckEquality("Beginning Offset", expected_offset, actual_offset);
|
|
}
|
|
|
|
|
|
void CheckNumSectors(uint32_t partition_number,
|
|
uint64_t expected_num_sectors) {
|
|
uint64_t actual_num_sectors;
|
|
EXPECT_SUCCESS(cgpt_manager.GetNumSectors(partition_number,
|
|
&actual_num_sectors));
|
|
CheckEquality("Num Sectors", expected_num_sectors, actual_num_sectors);
|
|
}
|
|
|
|
|
|
void CheckPartitionTypeId(int partition_number,
|
|
const Guid& expected_partition_type_id) {
|
|
// Get the partition type id and check if it matches the expected value.
|
|
Guid actual_partition_type_id;
|
|
EXPECT_SUCCESS(cgpt_manager.GetPartitionTypeId(partition_number,
|
|
&actual_partition_type_id));
|
|
|
|
CheckGuidEquality("PartitionTypeId",
|
|
expected_partition_type_id,
|
|
actual_partition_type_id);
|
|
}
|
|
|
|
void CheckPartitionUniqueId(int partition_number,
|
|
const Guid& expected_partition_unique_id) {
|
|
// Get the partition unique id and check if it matches the expected value.
|
|
Guid actual_partition_unique_id;
|
|
EXPECT_SUCCESS(cgpt_manager.GetPartitionUniqueId(
|
|
partition_number,
|
|
&actual_partition_unique_id));
|
|
|
|
CheckGuidEquality("PartitionUniqueId",
|
|
expected_partition_unique_id,
|
|
actual_partition_unique_id);
|
|
}
|
|
|
|
void CheckPartitionNumberByUniqueId(const Guid& unique_id,
|
|
uint32_t expected_partition_number) {
|
|
// Get the partition number for the unique id and check
|
|
// if it matches the expected value.
|
|
uint32_t actual_partition_number;
|
|
EXPECT_SUCCESS(cgpt_manager.GetPartitionNumberByUniqueId(
|
|
unique_id,
|
|
&actual_partition_number));
|
|
|
|
CheckEquality("PartitionNumberForUniqueId",
|
|
expected_partition_number,
|
|
actual_partition_number);
|
|
}
|
|
|
|
|
|
void CreateBootFile(const string& boot_file_name) {
|
|
FILE* fp = fopen(boot_file_name.c_str(), "w");
|
|
|
|
ASSERT_TRUE(fp != NULL);
|
|
|
|
const int kNumSectors = 1;
|
|
const int kSectorSize = 512;
|
|
const char kFillChar = '8'; // Some character, value doesn't matter.
|
|
|
|
for(int i = 0; i < kNumSectors * kSectorSize; i++) {
|
|
EXPECT_EQ(kFillChar, fputc(kFillChar, fp));
|
|
}
|
|
|
|
fclose(fp);
|
|
}
|
|
|
|
private:
|
|
DISALLOW_COPY_AND_ASSIGN(CgptManagerUnitTest);
|
|
};
|
|
|
|
TEST_F(CgptManagerUnitTest, AutoPrioritizationTest) {
|
|
EXPECT_SUCCESS(cgpt_manager.AddPartition("k1",
|
|
guid_chromeos_kernel,
|
|
guid_unused,
|
|
100,
|
|
10));
|
|
CheckPartitionCount(1);
|
|
|
|
EXPECT_SUCCESS(cgpt_manager.AddPartition("k2",
|
|
guid_chromeos_kernel,
|
|
p2guid,
|
|
200,
|
|
20));
|
|
CheckPartitionCount(2);
|
|
|
|
EXPECT_SUCCESS(cgpt_manager.AddPartition("k3",
|
|
guid_chromeos_kernel,
|
|
p3guid,
|
|
300,
|
|
30));
|
|
CheckPartitionCount(3);
|
|
|
|
uint8_t expectedk1Priority = 1;
|
|
uint8_t expectedk2Priority = 2;
|
|
uint8_t expectedk3Priority = 0;
|
|
|
|
// Calling SetAndCheckPriority will do a set and get of the above priorities.
|
|
SetAndCheckPriority(1, expectedk1Priority);
|
|
SetAndCheckPriority(2, expectedk2Priority);
|
|
SetAndCheckPriority(3, expectedk3Priority);
|
|
|
|
EXPECT_SUCCESS(cgpt_manager.SetHighestPriority(1));
|
|
|
|
expectedk1Priority = 2;
|
|
expectedk2Priority = 1;
|
|
|
|
CheckPriority(1, expectedk1Priority);
|
|
CheckPriority(2, expectedk2Priority);
|
|
CheckPriority(3, expectedk3Priority);
|
|
}
|
|
|
|
|
|
TEST_F(CgptManagerUnitTest, AddPartitionTest) {
|
|
int p2_offset = 200;
|
|
int p2_size = 20;
|
|
int p3_offset = 300;
|
|
int p3_size = 30;
|
|
|
|
VLOG(1) << "Adding various types of partitions ... ";
|
|
EXPECT_SUCCESS(cgpt_manager.AddPartition("data stuff",
|
|
guid_linux_data,
|
|
guid_unused,
|
|
100,
|
|
10));
|
|
CheckPartitionCount(1);
|
|
|
|
EXPECT_SUCCESS(cgpt_manager.AddPartition("kernel stuff",
|
|
guid_chromeos_kernel,
|
|
p2guid,
|
|
p2_offset,
|
|
p2_size));
|
|
CheckPartitionCount(2);
|
|
|
|
EXPECT_SUCCESS(cgpt_manager.AddPartition("rootfs stuff",
|
|
guid_chromeos_rootfs,
|
|
p3guid,
|
|
p3_offset,
|
|
p3_size));
|
|
CheckPartitionCount(3);
|
|
|
|
uint32_t pmbr_boot_partition_number = 4;
|
|
EXPECT_SUCCESS(cgpt_manager.AddPartition("ESP stuff",
|
|
guid_efi,
|
|
guid_unused,
|
|
400,
|
|
40));
|
|
CheckPartitionCount(4);
|
|
|
|
EXPECT_SUCCESS(cgpt_manager.AddPartition("fture stuff",
|
|
guid_chromeos_reserved,
|
|
guid_unused,
|
|
500,
|
|
50));
|
|
CheckPartitionCount(5);
|
|
|
|
Guid guid_random = {{{0x2364a860, 0xbf63, 0x42fb, 0xa8, 0x3d,
|
|
{0x9a, 0xd3, 0xe0, 0x57, 0xfc, 0xf5}}}};
|
|
|
|
EXPECT_SUCCESS(cgpt_manager.AddPartition("random stuff",
|
|
guid_random,
|
|
guid_unused,
|
|
600,
|
|
60));
|
|
|
|
CheckPartitionCount(6);
|
|
|
|
string boot_file_name = "/tmp/BootFileForCgptManagerTests.bin";
|
|
LOG(INFO) << "Adding EFI partition to PMBR with bootfile: "
|
|
<< boot_file_name;
|
|
|
|
CreateBootFile(boot_file_name);
|
|
EXPECT_SUCCESS(cgpt_manager.SetPmbr(pmbr_boot_partition_number,
|
|
boot_file_name,
|
|
true));
|
|
|
|
VLOG(1) << "Checking if contents of GPT match values set in AddPartition.";
|
|
|
|
uint32_t actual_boot_partition_number;
|
|
EXPECT_SUCCESS(cgpt_manager.GetPmbrBootPartitionNumber(
|
|
&actual_boot_partition_number));
|
|
EXPECT_EQ(pmbr_boot_partition_number, actual_boot_partition_number);
|
|
|
|
// Set the successful attribute for some partition to various Values
|
|
// and check if the settings are preserved.
|
|
SetAndCheckSuccessfulBit(2, true);
|
|
SetAndCheckSuccessfulBit(2, false);
|
|
|
|
// Set the number of tries for some partition to various Values
|
|
// and check if the settings are preserved.
|
|
SetAndCheckNumTriesLeft(2, 6);
|
|
SetAndCheckNumTriesLeft(2, 5);
|
|
|
|
// Set the priority for some partition to various Values
|
|
// and check if the settings are preserved.
|
|
SetAndCheckPriority(2, 2);
|
|
SetAndCheckPriority(2, 0);
|
|
|
|
// Check if the beginning offset for some of the partitions
|
|
// are the same as what was set in AddPartition.
|
|
CheckBeginningOffset(2, p2_offset);
|
|
CheckBeginningOffset(3, p3_offset);
|
|
|
|
// Check if the number of sectors for some of the partitions
|
|
// are same as what was set in AddPartition.
|
|
CheckNumSectors(2, p2_size);
|
|
CheckNumSectors(3, p3_size);
|
|
|
|
// Check if the partition type IDs for some of the partitions
|
|
// are same as what was set in AddPartition.
|
|
CheckPartitionTypeId(2, guid_chromeos_kernel);
|
|
CheckPartitionTypeId(4, guid_efi);
|
|
|
|
// Check if the partition unique IDs for some of the partitions
|
|
// same as what was set in AddPartition.
|
|
CheckPartitionUniqueId(2, p2guid);
|
|
CheckPartitionUniqueId(3, p3guid);
|
|
|
|
// Check if the partition numbers for some of the partitions are
|
|
// retrievable by their unique IDs set in AddPartition.
|
|
CheckPartitionNumberByUniqueId(p2guid, 2);
|
|
CheckPartitionNumberByUniqueId(p3guid, 3);
|
|
}
|
|
|
|
int main(int argc, char **argv) {
|
|
google::ParseCommandLineFlags(&argc, &argv, true);
|
|
::testing::InitGoogleTest(&argc, argv);
|
|
|
|
// VLOG(2) logs at level -2. So if user gives --v=2, we should
|
|
// set MinLogLevel to -2, so VLOG(2) and VLOG(1) will show up.
|
|
logging::SetMinLogLevel(-FLAGS_v);
|
|
return RUN_ALL_TESTS();
|
|
}
|