aboutsummaryrefslogtreecommitdiff
path: root/src/common/module_unittest.cc
diff options
context:
space:
mode:
authorted.mielczarek <ted.mielczarek@4c0a9323-5329-0410-9bdc-e9ce6186880e>2011-07-06 17:05:59 +0000
committerted.mielczarek <ted.mielczarek@4c0a9323-5329-0410-9bdc-e9ce6186880e>2011-07-06 17:05:59 +0000
commit3ca4a120de8ec3f35e972e4b23f527bb8f65c479 (patch)
tree0186b36bf01d54c7700c00c3c2cec21fbb382268 /src/common/module_unittest.cc
parentDump PUBLIC + CFI records from libraries without debug info on Linux, use .dy... (diff)
downloadbreakpad-3ca4a120de8ec3f35e972e4b23f527bb8f65c479.tar.xz
Add some unit tests for Linux WriteSymbolFile
This patch adds synth_elf::{StringTable,SymbolTable,ELF} classes to produce in-memory ELF files to properly test the Linux symbol dumping code. It also uses those classes to add some basic tests for the WriteSymbolFile function. R=jimb at http://breakpad.appspot.com/277001/show git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@794 4c0a9323-5329-0410-9bdc-e9ce6186880e
Diffstat (limited to 'src/common/module_unittest.cc')
-rw-r--r--src/common/module_unittest.cc136
1 files changed, 32 insertions, 104 deletions
diff --git a/src/common/module_unittest.cc b/src/common/module_unittest.cc
index 63ad5056..4972bbe8 100644
--- a/src/common/module_unittest.cc
+++ b/src/common/module_unittest.cc
@@ -37,6 +37,7 @@
#include <string.h>
#include <algorithm>
+#include <sstream>
#include <string>
#include "breakpad_googletest_includes.h"
@@ -44,53 +45,10 @@
using google_breakpad::Module;
using std::string;
+using std::stringstream;
using std::vector;
using testing::ContainerEq;
-// Return a FILE * referring to a temporary file that will be deleted
-// automatically when the stream is closed or the program exits.
-static FILE *checked_tmpfile() {
- FILE *f = tmpfile();
- if (!f) {
- fprintf(stderr, "error creating temporary file: %s\n", strerror(errno));
- exit(1);
- }
- return f;
-}
-
-// Read from STREAM until end of file, and return the contents as a
-// string.
-static string checked_read(FILE *stream) {
- string contents;
- int c;
- while ((c = getc(stream)) != EOF)
- contents.push_back(c);
- if (ferror(stream)) {
- fprintf(stderr, "error reading temporary file contents: %s\n",
- strerror(errno));
- exit(1);
- }
- return contents;
-}
-
-// Apply 'fflush' to STREAM, and check for errors.
-static void checked_fflush(FILE *stream) {
- if (fflush(stream) == EOF) {
- fprintf(stderr, "error flushing temporary file stream: %s\n",
- strerror(errno));
- exit(1);
- }
-}
-
-// Apply 'fclose' to STREAM, and check for errors.
-static void checked_fclose(FILE *stream) {
- if (fclose(stream) == EOF) {
- fprintf(stderr, "error closing temporary file stream: %s\n",
- strerror(errno));
- exit(1);
- }
-}
-
static Module::Function *generate_duplicate_function(const string &name) {
const Module::Address DUP_ADDRESS = 0xd35402aac7a7ad5cLL;
const Module::Address DUP_SIZE = 0x200b26e605f99071LL;
@@ -110,19 +68,16 @@ static Module::Function *generate_duplicate_function(const string &name) {
#define MODULE_ID "id-string"
TEST(Write, Header) {
- FILE *f = checked_tmpfile();
+ stringstream s;
Module m(MODULE_NAME, MODULE_OS, MODULE_ARCH, MODULE_ID);
- m.Write(f);
- checked_fflush(f);
- rewind(f);
- string contents = checked_read(f);
- checked_fclose(f);
+ m.Write(s);
+ string contents = s.str();
EXPECT_STREQ("MODULE os-name architecture id-string name with spaces\n",
contents.c_str());
}
TEST(Write, OneLineFunc) {
- FILE *f = checked_tmpfile();
+ stringstream s;
Module m(MODULE_NAME, MODULE_OS, MODULE_ARCH, MODULE_ID);
Module::File *file = m.FindFile("file_name.cc");
@@ -136,11 +91,8 @@ TEST(Write, OneLineFunc) {
function->lines.push_back(line);
m.AddFunction(function);
- m.Write(f);
- checked_fflush(f);
- rewind(f);
- string contents = checked_read(f);
- checked_fclose(f);
+ m.Write(s);
+ string contents = s.str();
EXPECT_STREQ("MODULE os-name architecture id-string name with spaces\n"
"FILE 0 file_name.cc\n"
"FUNC e165bf8023b9d9ab 1e4bb0eb1cbf5b09 772beee89114358a"
@@ -150,7 +102,7 @@ TEST(Write, OneLineFunc) {
}
TEST(Write, RelativeLoadAddress) {
- FILE *f = checked_tmpfile();
+ stringstream s;
Module m(MODULE_NAME, MODULE_OS, MODULE_ARCH, MODULE_ID);
// Some source files. We will expect to see them in lexicographic order.
@@ -189,11 +141,8 @@ TEST(Write, RelativeLoadAddress) {
// the module must work fine.
m.SetLoadAddress(0x2ab698b0b6407073LL);
- m.Write(f);
- checked_fflush(f);
- rewind(f);
- string contents = checked_read(f);
- checked_fclose(f);
+ m.Write(s);
+ string contents = s.str();
EXPECT_STREQ("MODULE os-name architecture id-string name with spaces\n"
"FILE 0 filename-a.cc\n"
"FILE 1 filename-b.cc\n"
@@ -247,12 +196,9 @@ TEST(Write, OmitUnusedFiles) {
EXPECT_STREQ("filename3", vec[2]->name.c_str());
EXPECT_NE(-1, vec[2]->source_id);
- FILE *f = checked_tmpfile();
- m.Write(f);
- checked_fflush(f);
- rewind(f);
- string contents = checked_read(f);
- checked_fclose(f);
+ stringstream s;
+ m.Write(s);
+ string contents = s.str();
EXPECT_STREQ("MODULE os-name architecture id-string name with spaces\n"
"FILE 0 filename1\n"
"FILE 1 filename3\n"
@@ -264,7 +210,7 @@ TEST(Write, OmitUnusedFiles) {
}
TEST(Construct, AddFunctions) {
- FILE *f = checked_tmpfile();
+ stringstream s;
Module m(MODULE_NAME, MODULE_OS, MODULE_ARCH, MODULE_ID);
// Two functions.
@@ -287,11 +233,8 @@ TEST(Construct, AddFunctions) {
m.AddFunctions(vec.begin(), vec.end());
- m.Write(f);
- checked_fflush(f);
- rewind(f);
- string contents = checked_read(f);
- checked_fclose(f);
+ m.Write(s);
+ string contents = s.str();
EXPECT_STREQ("MODULE os-name architecture id-string name with spaces\n"
"FUNC 2987743d0b35b13f b369db048deb3010 938e556cb5a79988"
" _and_void\n"
@@ -308,7 +251,7 @@ TEST(Construct, AddFunctions) {
}
TEST(Construct, AddFrames) {
- FILE *f = checked_tmpfile();
+ stringstream s;
Module m(MODULE_NAME, MODULE_OS, MODULE_ARCH, MODULE_ID);
// First STACK CFI entry, with no initial rules or deltas.
@@ -342,11 +285,8 @@ TEST(Construct, AddFrames) {
m.AddStackFrameEntry(entry3);
// Check that Write writes STACK CFI records properly.
- m.Write(f);
- checked_fflush(f);
- rewind(f);
- string contents = checked_read(f);
- checked_fclose(f);
+ m.Write(s);
+ string contents = s.str();
EXPECT_STREQ("MODULE os-name architecture id-string name with spaces\n"
"STACK CFI INIT ddb5f41285aa7757 1486493370dc5073 \n"
"STACK CFI INIT 8064f3af5e067e38 de2a5ee55509407"
@@ -411,7 +351,7 @@ TEST(Construct, UniqueFiles) {
}
TEST(Construct, DuplicateFunctions) {
- FILE *f = checked_tmpfile();
+ stringstream s;
Module m(MODULE_NAME, MODULE_OS, MODULE_ARCH, MODULE_ID);
// Two functions.
@@ -421,11 +361,8 @@ TEST(Construct, DuplicateFunctions) {
m.AddFunction(function1);
m.AddFunction(function2);
- m.Write(f);
- checked_fflush(f);
- rewind(f);
- string contents = checked_read(f);
- checked_fclose(f);
+ m.Write(s);
+ string contents = s.str();
EXPECT_STREQ("MODULE os-name architecture id-string name with spaces\n"
"FUNC d35402aac7a7ad5c 200b26e605f99071 f14ac4fed48c4a99"
" _without_form\n",
@@ -433,7 +370,7 @@ TEST(Construct, DuplicateFunctions) {
}
TEST(Construct, FunctionsWithSameAddress) {
- FILE *f = checked_tmpfile();
+ stringstream s;
Module m(MODULE_NAME, MODULE_OS, MODULE_ARCH, MODULE_ID);
// Two functions.
@@ -443,11 +380,8 @@ TEST(Construct, FunctionsWithSameAddress) {
m.AddFunction(function1);
m.AddFunction(function2);
- m.Write(f);
- checked_fflush(f);
- rewind(f);
- string contents = checked_read(f);
- checked_fclose(f);
+ m.Write(s);
+ string contents = s.str();
EXPECT_STREQ("MODULE os-name architecture id-string name with spaces\n"
"FUNC d35402aac7a7ad5c 200b26e605f99071 f14ac4fed48c4a99"
" _and_void\n"
@@ -459,7 +393,7 @@ TEST(Construct, FunctionsWithSameAddress) {
// Externs should be written out as PUBLIC records, sorted by
// address.
TEST(Construct, Externs) {
- FILE *f = checked_tmpfile();
+ stringstream s;
Module m(MODULE_NAME, MODULE_OS, MODULE_ARCH, MODULE_ID);
// Two externs.
@@ -473,11 +407,8 @@ TEST(Construct, Externs) {
m.AddExtern(extern1);
m.AddExtern(extern2);
- m.Write(f);
- checked_fflush(f);
- rewind(f);
- string contents = checked_read(f);
- checked_fclose(f);
+ m.Write(s);
+ string contents = s.str();
EXPECT_STREQ("MODULE " MODULE_OS " " MODULE_ARCH " "
MODULE_ID " " MODULE_NAME "\n"
@@ -489,7 +420,7 @@ TEST(Construct, Externs) {
// Externs with the same address should only keep the first entry
// added.
TEST(Construct, DuplicateExterns) {
- FILE *f = checked_tmpfile();
+ stringstream s;
Module m(MODULE_NAME, MODULE_OS, MODULE_ARCH, MODULE_ID);
// Two externs.
@@ -503,11 +434,8 @@ TEST(Construct, DuplicateExterns) {
m.AddExtern(extern1);
m.AddExtern(extern2);
- m.Write(f);
- checked_fflush(f);
- rewind(f);
- string contents = checked_read(f);
- checked_fclose(f);
+ m.Write(s);
+ string contents = s.str();
EXPECT_STREQ("MODULE " MODULE_OS " " MODULE_ARCH " "
MODULE_ID " " MODULE_NAME "\n"