minidump_file_writer_unittest.cc
1 // Copyright 2006 Google LLC 2 // 3 // Redistribution and use in source and binary forms, with or without 4 // modification, are permitted provided that the following conditions are 5 // met: 6 // 7 // * Redistributions of source code must retain the above copyright 8 // notice, this list of conditions and the following disclaimer. 9 // * Redistributions in binary form must reproduce the above 10 // copyright notice, this list of conditions and the following disclaimer 11 // in the documentation and/or other materials provided with the 12 // distribution. 13 // * Neither the name of Google LLC nor the names of its 14 // contributors may be used to endorse or promote products derived from 15 // this software without specific prior written permission. 16 // 17 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 29 // Author: waylonis@google.com (Dan Waylonis) 30 31 /* 32 g++ -I../ ../common/convert_UTF.cc \ 33 ../common/string_conversion.cc \ 34 minidump_file_writer.cc \ 35 minidump_file_writer_unittest.cc \ 36 -o minidump_file_writer_unittest 37 */ 38 39 #ifdef HAVE_CONFIG_H 40 #include <config.h> // Must come first 41 #endif 42 43 #include <fcntl.h> 44 #include <unistd.h> 45 46 #include "minidump_file_writer-inl.h" 47 48 using google_breakpad::MinidumpFileWriter; 49 50 #define ASSERT_TRUE(cond) \ 51 if (!(cond)) { \ 52 fprintf(stderr, "FAILED: %s at %s:%d\n", #cond, __FILE__, __LINE__); \ 53 return false; \ 54 } 55 56 #define ASSERT_EQ(e1, e2) ASSERT_TRUE((e1) == (e2)) 57 #define ASSERT_NE(e1, e2) ASSERT_TRUE((e1) != (e2)) 58 59 struct StringStructure { 60 unsigned long integer_value; 61 MDLocationDescriptor first_string; 62 MDLocationDescriptor second_string; 63 }; 64 65 struct ArrayStructure { 66 unsigned char char_value; 67 unsigned short short_value; 68 unsigned long long_value; 69 }; 70 71 typedef struct { 72 unsigned long count; 73 ArrayStructure array[0]; 74 } ObjectAndArrayStructure; 75 76 static bool WriteFile(const char* path) { 77 MinidumpFileWriter writer; 78 if (writer.Open(path)) { 79 // Test a single structure 80 google_breakpad::TypedMDRVA<StringStructure> strings(&writer); 81 ASSERT_TRUE(strings.Allocate()); 82 strings.get()->integer_value = 0xBEEF; 83 const char* first = "First String"; 84 ASSERT_TRUE(writer.WriteString(first, 0, &strings.get()->first_string)); 85 const wchar_t* second = L"Second String"; 86 ASSERT_TRUE(writer.WriteString(second, 0, &strings.get()->second_string)); 87 88 // Test an array structure 89 google_breakpad::TypedMDRVA<ArrayStructure> array(&writer); 90 unsigned int count = 10; 91 ASSERT_TRUE(array.AllocateArray(count)); 92 for (unsigned char i = 0; i < count; ++i) { 93 ArrayStructure local; 94 local.char_value = i; 95 local.short_value = i + 1; 96 local.long_value = i + 2; 97 ASSERT_TRUE(array.CopyIndex(i, &local)); 98 } 99 100 // Test an object followed by an array 101 google_breakpad::TypedMDRVA<ObjectAndArrayStructure> obj_array(&writer); 102 ASSERT_TRUE(obj_array.AllocateObjectAndArray(count, 103 sizeof(ArrayStructure))); 104 obj_array.get()->count = count; 105 for (unsigned char i = 0; i < count; ++i) { 106 ArrayStructure local; 107 local.char_value = i; 108 local.short_value = i + 1; 109 local.long_value = i + 2; 110 ASSERT_TRUE(obj_array.CopyIndexAfterObject(i, &local, sizeof(local))); 111 } 112 } 113 114 return writer.Close(); 115 } 116 117 static bool CompareFile(const char* path) { 118 unsigned long expected[] = { 119 #if defined(__BIG_ENDIAN__) 120 0x0000beef, 0x0000001e, 0x00000018, 0x00000020, 0x00000038, 0x00000000, 121 0x00000018, 0x00460069, 0x00720073, 0x00740020, 0x00530074, 0x00720069, 122 0x006e0067, 0x00000000, 0x0000001a, 0x00530065, 0x0063006f, 0x006e0064, 123 0x00200053, 0x00740072, 0x0069006e, 0x00670000, 0x00000001, 0x00000002, 124 0x01000002, 0x00000003, 0x02000003, 0x00000004, 0x03000004, 0x00000005, 125 0x04000005, 0x00000006, 0x05000006, 0x00000007, 0x06000007, 0x00000008, 126 0x07000008, 0x00000009, 0x08000009, 0x0000000a, 0x0900000a, 0x0000000b, 127 0x0000000a, 0x00000001, 0x00000002, 0x01000002, 0x00000003, 0x02000003, 128 0x00000004, 0x03000004, 0x00000005, 0x04000005, 0x00000006, 0x05000006, 129 0x00000007, 0x06000007, 0x00000008, 0x07000008, 0x00000009, 0x08000009, 130 0x0000000a, 0x0900000a, 0x0000000b, 0x00000000 131 #else 132 0x0000beef, 0x0000001e, 0x00000018, 0x00000020, 133 0x00000038, 0x00000000, 0x00000018, 0x00690046, 134 0x00730072, 0x00200074, 0x00740053, 0x00690072, 135 0x0067006e, 0x00000000, 0x0000001a, 0x00650053, 136 0x006f0063, 0x0064006e, 0x00530020, 0x00720074, 137 0x006e0069, 0x00000067, 0x00011e00, 0x00000002, 138 0x00021e01, 0x00000003, 0x00031e02, 0x00000004, 139 0x00041e03, 0x00000005, 0x00051e04, 0x00000006, 140 0x00061e05, 0x00000007, 0x00071e06, 0x00000008, 141 0x00081e07, 0x00000009, 0x00091e08, 0x0000000a, 142 0x000a1e09, 0x0000000b, 0x0000000a, 0x00011c00, 143 0x00000002, 0x00021c01, 0x00000003, 0x00031c02, 144 0x00000004, 0x00041c03, 0x00000005, 0x00051c04, 145 0x00000006, 0x00061c05, 0x00000007, 0x00071c06, 146 0x00000008, 0x00081c07, 0x00000009, 0x00091c08, 147 0x0000000a, 0x000a1c09, 0x0000000b, 0x00000000, 148 #endif 149 }; 150 size_t expected_byte_count = sizeof(expected); 151 int fd = open(path, O_RDONLY, 0600); 152 void* buffer = malloc(expected_byte_count); 153 ASSERT_NE(fd, -1); 154 ASSERT_TRUE(buffer); 155 ASSERT_EQ(read(fd, buffer, expected_byte_count), 156 static_cast<ssize_t>(expected_byte_count)); 157 158 char* b1; 159 char* b2; 160 b1 = reinterpret_cast<char*>(buffer); 161 b2 = reinterpret_cast<char*>(expected); 162 while (*b1 == *b2) { 163 b1++; 164 b2++; 165 } 166 167 printf("%p\n", reinterpret_cast<void*>(b1 - (char*)buffer)); 168 169 ASSERT_EQ(memcmp(buffer, expected, expected_byte_count), 0); 170 return true; 171 } 172 173 static bool RunTests() { 174 const char* path = "/tmp/minidump_file_writer_unittest.dmp"; 175 ASSERT_TRUE(WriteFile(path)); 176 ASSERT_TRUE(CompareFile(path)); 177 unlink(path); 178 return true; 179 } 180 181 extern "C" int main(int argc, const char* argv[]) { 182 return RunTests() ? 0 : 1; 183 }