Clean up module_unittest

This change rewrites the tests to have `Module` as a prefix and
rearranges them a little. This is prep for adding this file to
breakpad_unittests Chromium-side.

Bug: google-breakpad:751
Change-Id: I8a77f60a0080d06af13dd30d9cf7627dce045d90
Reviewed-on: https://chromium-review.googlesource.com/c/breakpad/breakpad/+/3915004
Reviewed-by: Mark Mentovai <mark@chromium.org>
This commit is contained in:
Leonard Grey 2022-09-22 19:33:12 +00:00
parent 28cf16bc34
commit e3af4457b8

View file

@ -67,7 +67,7 @@ static Module::Function* generate_duplicate_function(StringView name) {
#define MODULE_ID "id-string" #define MODULE_ID "id-string"
#define MODULE_CODE_ID "code-id-string" #define MODULE_CODE_ID "code-id-string"
TEST(Write, Header) { TEST(Module, WriteHeader) {
stringstream s; stringstream s;
Module m(MODULE_NAME, MODULE_OS, MODULE_ARCH, MODULE_ID); Module m(MODULE_NAME, MODULE_OS, MODULE_ARCH, MODULE_ID);
m.Write(s, ALL_SYMBOL_DATA); m.Write(s, ALL_SYMBOL_DATA);
@ -76,7 +76,7 @@ TEST(Write, Header) {
contents.c_str()); contents.c_str());
} }
TEST(Write, HeaderCodeId) { TEST(Module, WriteHeaderCodeId) {
stringstream s; stringstream s;
Module m(MODULE_NAME, MODULE_OS, MODULE_ARCH, MODULE_ID, MODULE_CODE_ID); Module m(MODULE_NAME, MODULE_OS, MODULE_ARCH, MODULE_ID, MODULE_CODE_ID);
m.Write(s, ALL_SYMBOL_DATA); m.Write(s, ALL_SYMBOL_DATA);
@ -86,7 +86,7 @@ TEST(Write, HeaderCodeId) {
contents.c_str()); contents.c_str());
} }
TEST(Write, OneLineFunc) { TEST(Module, WriteOneLineFunc) {
stringstream s; stringstream s;
Module m(MODULE_NAME, MODULE_OS, MODULE_ARCH, MODULE_ID); Module m(MODULE_NAME, MODULE_OS, MODULE_ARCH, MODULE_ID);
@ -111,7 +111,7 @@ TEST(Write, OneLineFunc) {
contents.c_str()); contents.c_str());
} }
TEST(Write, RelativeLoadAddress) { TEST(Module, WriteRelativeLoadAddress) {
stringstream s; stringstream s;
Module m(MODULE_NAME, MODULE_OS, MODULE_ARCH, MODULE_ID); Module m(MODULE_NAME, MODULE_OS, MODULE_ARCH, MODULE_ID);
@ -169,7 +169,7 @@ TEST(Write, RelativeLoadAddress) {
contents.c_str()); contents.c_str());
} }
TEST(Write, OmitUnusedFiles) { TEST(Module, WriteOmitUnusedFiles) {
Module m(MODULE_NAME, MODULE_OS, MODULE_ARCH, MODULE_ID); Module m(MODULE_NAME, MODULE_OS, MODULE_ARCH, MODULE_ID);
// Create some source files. // Create some source files.
@ -220,7 +220,7 @@ TEST(Write, OmitUnusedFiles) {
contents.c_str()); contents.c_str());
} }
TEST(Write, NoCFI) { TEST(Module, WriteNoCFI) {
stringstream s; stringstream s;
Module m(MODULE_NAME, MODULE_OS, MODULE_ARCH, MODULE_ID); Module m(MODULE_NAME, MODULE_OS, MODULE_ARCH, MODULE_ID);
@ -266,7 +266,7 @@ TEST(Write, NoCFI) {
contents.c_str()); contents.c_str());
} }
TEST(Construct, AddFunction) { TEST(Module, ConstructAddFunction) {
stringstream s; stringstream s;
Module m(MODULE_NAME, MODULE_OS, MODULE_ARCH, MODULE_ID); Module m(MODULE_NAME, MODULE_OS, MODULE_ARCH, MODULE_ID);
@ -308,7 +308,62 @@ TEST(Construct, AddFunction) {
EXPECT_EQ((size_t) 2, vec.size()); EXPECT_EQ((size_t) 2, vec.size());
} }
TEST(Construct, AddFrames) { TEST(Module, WriteOutOfRangeAddresses) {
stringstream s;
Module m(MODULE_NAME, MODULE_OS, MODULE_ARCH, MODULE_ID);
// Specify an allowed address range, representing a PT_LOAD segment in a
// module.
vector<Module::Range> address_ranges = {
Module::Range(0x2000ULL, 0x1000ULL),
};
m.SetAddressRanges(address_ranges);
// Add three stack frames (one lower, one in, and one higher than the allowed
// address range). Only the middle frame should be captured.
Module::StackFrameEntry* entry1 = new Module::StackFrameEntry();
entry1->address = 0x1000ULL;
entry1->size = 0x100ULL;
m.AddStackFrameEntry(entry1);
Module::StackFrameEntry* entry2 = new Module::StackFrameEntry();
entry2->address = 0x2000ULL;
entry2->size = 0x100ULL;
m.AddStackFrameEntry(entry2);
Module::StackFrameEntry* entry3 = new Module::StackFrameEntry();
entry3->address = 0x3000ULL;
entry3->size = 0x100ULL;
m.AddStackFrameEntry(entry3);
// Add a function outside the allowed range.
Module::File* file = m.FindFile("file_name.cc");
Module::Function* function = new Module::Function(
"function_name", 0x4000ULL);
Module::Range range(0x4000ULL, 0x1000ULL);
function->ranges.push_back(range);
function->parameter_size = 0x100ULL;
Module::Line line = { 0x4000ULL, 0x100ULL, file, 67519080 };
function->lines.push_back(line);
m.AddFunction(function);
// Add an extern outside the allowed range.
Module::Extern* extern1 = new Module::Extern(0x5000ULL);
extern1->name = "_xyz";
m.AddExtern(extern1);
m.Write(s, ALL_SYMBOL_DATA);
EXPECT_STREQ("MODULE os-name architecture id-string name with spaces\n"
"STACK CFI INIT 2000 100 \n",
s.str().c_str());
// Cleanup - Prevent Memory Leak errors.
delete (extern1);
delete (function);
delete (entry3);
delete (entry1);
}
TEST(Module, ConstructAddFrames) {
stringstream s; stringstream s;
Module m(MODULE_NAME, MODULE_OS, MODULE_ARCH, MODULE_ID); Module m(MODULE_NAME, MODULE_OS, MODULE_ARCH, MODULE_ID);
@ -395,7 +450,7 @@ TEST(Construct, AddFrames) {
EXPECT_THAT(entries[2]->rule_changes, ContainerEq(entry3_changes)); EXPECT_THAT(entries[2]->rule_changes, ContainerEq(entry3_changes));
} }
TEST(Construct, UniqueFiles) { TEST(Module, ConstructUniqueFiles) {
Module m(MODULE_NAME, MODULE_OS, MODULE_ARCH, MODULE_ID); Module m(MODULE_NAME, MODULE_OS, MODULE_ARCH, MODULE_ID);
Module::File* file1 = m.FindFile("foo"); Module::File* file1 = m.FindFile("foo");
Module::File* file2 = m.FindFile(string("bar")); Module::File* file2 = m.FindFile(string("bar"));
@ -408,7 +463,7 @@ TEST(Construct, UniqueFiles) {
EXPECT_TRUE(m.FindExistingFile("baz") == NULL); EXPECT_TRUE(m.FindExistingFile("baz") == NULL);
} }
TEST(Construct, DuplicateFunctions) { TEST(Module, ConstructDuplicateFunctions) {
stringstream s; stringstream s;
Module m(MODULE_NAME, MODULE_OS, MODULE_ARCH, MODULE_ID); Module m(MODULE_NAME, MODULE_OS, MODULE_ARCH, MODULE_ID);
@ -430,7 +485,7 @@ TEST(Construct, DuplicateFunctions) {
contents.c_str()); contents.c_str());
} }
TEST(Construct, FunctionsWithSameAddress) { TEST(Module, ConstructFunctionsWithSameAddress) {
stringstream s; stringstream s;
Module m(MODULE_NAME, MODULE_OS, MODULE_ARCH, MODULE_ID); Module m(MODULE_NAME, MODULE_OS, MODULE_ARCH, MODULE_ID);
@ -453,7 +508,7 @@ TEST(Construct, FunctionsWithSameAddress) {
// Externs should be written out as PUBLIC records, sorted by // Externs should be written out as PUBLIC records, sorted by
// address. // address.
TEST(Construct, Externs) { TEST(Module, ConstructExterns) {
stringstream s; stringstream s;
Module m(MODULE_NAME, MODULE_OS, MODULE_ARCH, MODULE_ID); Module m(MODULE_NAME, MODULE_OS, MODULE_ARCH, MODULE_ID);
@ -478,7 +533,7 @@ TEST(Construct, Externs) {
// Externs with the same address should only keep the first entry // Externs with the same address should only keep the first entry
// added. // added.
TEST(Construct, DuplicateExterns) { TEST(Module, ConstructDuplicateExterns) {
stringstream s; stringstream s;
Module m(MODULE_NAME, MODULE_OS, MODULE_ARCH, MODULE_ID); Module m(MODULE_NAME, MODULE_OS, MODULE_ARCH, MODULE_ID);
@ -502,7 +557,7 @@ TEST(Construct, DuplicateExterns) {
// If there exists an extern and a function at the same address, only write // If there exists an extern and a function at the same address, only write
// out the FUNC entry. // out the FUNC entry.
TEST(Construct, FunctionsAndExternsWithSameAddress) { TEST(Module, ConstructFunctionsAndExternsWithSameAddress) {
stringstream s; stringstream s;
Module m(MODULE_NAME, MODULE_OS, MODULE_ARCH, MODULE_ID); Module m(MODULE_NAME, MODULE_OS, MODULE_ARCH, MODULE_ID);
@ -534,7 +589,7 @@ TEST(Construct, FunctionsAndExternsWithSameAddress) {
// If there exists an extern and a function at the same address, only write // If there exists an extern and a function at the same address, only write
// out the FUNC entry. For ARM THUMB, the extern that comes from the ELF // out the FUNC entry. For ARM THUMB, the extern that comes from the ELF
// symbol section has bit 0 set. // symbol section has bit 0 set.
TEST(Construct, FunctionsAndThumbExternsWithSameAddress) { TEST(Module, ConstructFunctionsAndThumbExternsWithSameAddress) {
stringstream s; stringstream s;
Module m(MODULE_NAME, MODULE_OS, "arm", MODULE_ID); Module m(MODULE_NAME, MODULE_OS, "arm", MODULE_ID);
@ -569,58 +624,3 @@ TEST(Construct, FunctionsAndThumbExternsWithSameAddress) {
"PUBLIC cc00 0 arm_func\n", "PUBLIC cc00 0 arm_func\n",
contents.c_str()); contents.c_str());
} }
TEST(Write, OutOfRangeAddresses) {
stringstream s;
Module m(MODULE_NAME, MODULE_OS, MODULE_ARCH, MODULE_ID);
// Specify an allowed address range, representing a PT_LOAD segment in a
// module.
vector<Module::Range> address_ranges = {
Module::Range(0x2000ULL, 0x1000ULL),
};
m.SetAddressRanges(address_ranges);
// Add three stack frames (one lower, one in, and one higher than the allowed
// address range). Only the middle frame should be captured.
Module::StackFrameEntry* entry1 = new Module::StackFrameEntry();
entry1->address = 0x1000ULL;
entry1->size = 0x100ULL;
m.AddStackFrameEntry(entry1);
Module::StackFrameEntry* entry2 = new Module::StackFrameEntry();
entry2->address = 0x2000ULL;
entry2->size = 0x100ULL;
m.AddStackFrameEntry(entry2);
Module::StackFrameEntry* entry3 = new Module::StackFrameEntry();
entry3->address = 0x3000ULL;
entry3->size = 0x100ULL;
m.AddStackFrameEntry(entry3);
// Add a function outside the allowed range.
Module::File* file = m.FindFile("file_name.cc");
Module::Function* function = new Module::Function(
"function_name", 0x4000ULL);
Module::Range range(0x4000ULL, 0x1000ULL);
function->ranges.push_back(range);
function->parameter_size = 0x100ULL;
Module::Line line = { 0x4000ULL, 0x100ULL, file, 67519080 };
function->lines.push_back(line);
m.AddFunction(function);
// Add an extern outside the allowed range.
Module::Extern* extern1 = new Module::Extern(0x5000ULL);
extern1->name = "_xyz";
m.AddExtern(extern1);
m.Write(s, ALL_SYMBOL_DATA);
EXPECT_STREQ("MODULE os-name architecture id-string name with spaces\n"
"STACK CFI INIT 2000 100 \n",
s.str().c_str());
// Cleanup - Prevent Memory Leak errors.
delete (extern1);
delete (function);
delete (entry3);
delete (entry1);
}