1e5dc60822e5938fea2ae892ccddb906641ba174emmentovai// Copyright (c) 2006, Google Inc.
2e5dc60822e5938fea2ae892ccddb906641ba174emmentovai// All rights reserved.
38cc32d3bb84656d7d8ada030ece22f7400461cf9waylonis//
48cc32d3bb84656d7d8ada030ece22f7400461cf9waylonis// Redistribution and use in source and binary forms, with or without
58cc32d3bb84656d7d8ada030ece22f7400461cf9waylonis// modification, are permitted provided that the following conditions are
68cc32d3bb84656d7d8ada030ece22f7400461cf9waylonis// met:
78cc32d3bb84656d7d8ada030ece22f7400461cf9waylonis//
88cc32d3bb84656d7d8ada030ece22f7400461cf9waylonis//     * Redistributions of source code must retain the above copyright
98cc32d3bb84656d7d8ada030ece22f7400461cf9waylonis// notice, this list of conditions and the following disclaimer.
108cc32d3bb84656d7d8ada030ece22f7400461cf9waylonis//     * Redistributions in binary form must reproduce the above
118cc32d3bb84656d7d8ada030ece22f7400461cf9waylonis// copyright notice, this list of conditions and the following disclaimer
128cc32d3bb84656d7d8ada030ece22f7400461cf9waylonis// in the documentation and/or other materials provided with the
138cc32d3bb84656d7d8ada030ece22f7400461cf9waylonis// distribution.
148cc32d3bb84656d7d8ada030ece22f7400461cf9waylonis//     * Neither the name of Google Inc. nor the names of its
158cc32d3bb84656d7d8ada030ece22f7400461cf9waylonis// contributors may be used to endorse or promote products derived from
168cc32d3bb84656d7d8ada030ece22f7400461cf9waylonis// this software without specific prior written permission.
178cc32d3bb84656d7d8ada030ece22f7400461cf9waylonis//
188cc32d3bb84656d7d8ada030ece22f7400461cf9waylonis// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
198cc32d3bb84656d7d8ada030ece22f7400461cf9waylonis// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
208cc32d3bb84656d7d8ada030ece22f7400461cf9waylonis// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
218cc32d3bb84656d7d8ada030ece22f7400461cf9waylonis// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
228cc32d3bb84656d7d8ada030ece22f7400461cf9waylonis// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
238cc32d3bb84656d7d8ada030ece22f7400461cf9waylonis// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
248cc32d3bb84656d7d8ada030ece22f7400461cf9waylonis// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
258cc32d3bb84656d7d8ada030ece22f7400461cf9waylonis// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
268cc32d3bb84656d7d8ada030ece22f7400461cf9waylonis// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
278cc32d3bb84656d7d8ada030ece22f7400461cf9waylonis// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
288cc32d3bb84656d7d8ada030ece22f7400461cf9waylonis// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
298cc32d3bb84656d7d8ada030ece22f7400461cf9waylonis
30e5dc60822e5938fea2ae892ccddb906641ba174emmentovai// Author: waylonis@google.com (Dan Waylonis)
31e5dc60822e5938fea2ae892ccddb906641ba174emmentovai
328cc32d3bb84656d7d8ada030ece22f7400461cf9waylonis/*
338cc32d3bb84656d7d8ada030ece22f7400461cf9waylonis g++ -I../ ../common/convert_UTF.c \
348cc32d3bb84656d7d8ada030ece22f7400461cf9waylonis ../common/string_conversion.cc \
358cc32d3bb84656d7d8ada030ece22f7400461cf9waylonis minidump_file_writer.cc \
368cc32d3bb84656d7d8ada030ece22f7400461cf9waylonis minidump_file_writer_unittest.cc \
378cc32d3bb84656d7d8ada030ece22f7400461cf9waylonis -o minidump_file_writer_unittest
388cc32d3bb84656d7d8ada030ece22f7400461cf9waylonis */
398cc32d3bb84656d7d8ada030ece22f7400461cf9waylonis
408cc32d3bb84656d7d8ada030ece22f7400461cf9waylonis#include <fcntl.h>
418cc32d3bb84656d7d8ada030ece22f7400461cf9waylonis#include <unistd.h>
428cc32d3bb84656d7d8ada030ece22f7400461cf9waylonis
438cc32d3bb84656d7d8ada030ece22f7400461cf9waylonis#include "minidump_file_writer-inl.h"
448cc32d3bb84656d7d8ada030ece22f7400461cf9waylonis
45e5dc60822e5938fea2ae892ccddb906641ba174emmentovaiusing google_breakpad::MinidumpFileWriter;
468cc32d3bb84656d7d8ada030ece22f7400461cf9waylonis
478cc32d3bb84656d7d8ada030ece22f7400461cf9waylonis#define ASSERT_TRUE(cond) \
488cc32d3bb84656d7d8ada030ece22f7400461cf9waylonisif (!(cond)) { \
498cc32d3bb84656d7d8ada030ece22f7400461cf9waylonis  fprintf(stderr, "FAILED: %s at %s:%d\n", #cond, __FILE__, __LINE__); \
508cc32d3bb84656d7d8ada030ece22f7400461cf9waylonis    return false; \
518cc32d3bb84656d7d8ada030ece22f7400461cf9waylonis}
528cc32d3bb84656d7d8ada030ece22f7400461cf9waylonis
538cc32d3bb84656d7d8ada030ece22f7400461cf9waylonis#define ASSERT_EQ(e1, e2) ASSERT_TRUE((e1) == (e2))
548cc32d3bb84656d7d8ada030ece22f7400461cf9waylonis#define ASSERT_NE(e1, e2) ASSERT_TRUE((e1) != (e2))
558cc32d3bb84656d7d8ada030ece22f7400461cf9waylonis
568cc32d3bb84656d7d8ada030ece22f7400461cf9waylonisstruct StringStructure {
578cc32d3bb84656d7d8ada030ece22f7400461cf9waylonis  unsigned long integer_value;
588cc32d3bb84656d7d8ada030ece22f7400461cf9waylonis  MDLocationDescriptor first_string;
598cc32d3bb84656d7d8ada030ece22f7400461cf9waylonis  MDLocationDescriptor second_string;
608cc32d3bb84656d7d8ada030ece22f7400461cf9waylonis};
618cc32d3bb84656d7d8ada030ece22f7400461cf9waylonis
628cc32d3bb84656d7d8ada030ece22f7400461cf9waylonisstruct ArrayStructure {
638cc32d3bb84656d7d8ada030ece22f7400461cf9waylonis  unsigned char char_value;
648cc32d3bb84656d7d8ada030ece22f7400461cf9waylonis  unsigned short short_value;
658cc32d3bb84656d7d8ada030ece22f7400461cf9waylonis  unsigned long long_value;
668cc32d3bb84656d7d8ada030ece22f7400461cf9waylonis};
678cc32d3bb84656d7d8ada030ece22f7400461cf9waylonis
688cc32d3bb84656d7d8ada030ece22f7400461cf9waylonistypedef struct {
698cc32d3bb84656d7d8ada030ece22f7400461cf9waylonis  unsigned long count;
708cc32d3bb84656d7d8ada030ece22f7400461cf9waylonis  ArrayStructure array[0];
718cc32d3bb84656d7d8ada030ece22f7400461cf9waylonis} ObjectAndArrayStructure;
728cc32d3bb84656d7d8ada030ece22f7400461cf9waylonis
738cc32d3bb84656d7d8ada030ece22f7400461cf9waylonisstatic bool WriteFile(const char *path) {
748cc32d3bb84656d7d8ada030ece22f7400461cf9waylonis  MinidumpFileWriter writer;
758cc32d3bb84656d7d8ada030ece22f7400461cf9waylonis  if (writer.Open(path)) {
768cc32d3bb84656d7d8ada030ece22f7400461cf9waylonis    // Test a single structure
77e5dc60822e5938fea2ae892ccddb906641ba174emmentovai    google_breakpad::TypedMDRVA<StringStructure> strings(&writer);
788cc32d3bb84656d7d8ada030ece22f7400461cf9waylonis    ASSERT_TRUE(strings.Allocate());
798cc32d3bb84656d7d8ada030ece22f7400461cf9waylonis    strings.get()->integer_value = 0xBEEF;
808cc32d3bb84656d7d8ada030ece22f7400461cf9waylonis    const char *first = "First String";
818cc32d3bb84656d7d8ada030ece22f7400461cf9waylonis    ASSERT_TRUE(writer.WriteString(first, 0, &strings.get()->first_string));
828cc32d3bb84656d7d8ada030ece22f7400461cf9waylonis    const wchar_t *second = L"Second String";
838cc32d3bb84656d7d8ada030ece22f7400461cf9waylonis    ASSERT_TRUE(writer.WriteString(second, 0, &strings.get()->second_string));
848cc32d3bb84656d7d8ada030ece22f7400461cf9waylonis
858cc32d3bb84656d7d8ada030ece22f7400461cf9waylonis    // Test an array structure
86e5dc60822e5938fea2ae892ccddb906641ba174emmentovai    google_breakpad::TypedMDRVA<ArrayStructure> array(&writer);
878cc32d3bb84656d7d8ada030ece22f7400461cf9waylonis    unsigned int count = 10;
888cc32d3bb84656d7d8ada030ece22f7400461cf9waylonis    ASSERT_TRUE(array.AllocateArray(count));
89486229ba5044ee2e7f49d2f6000e6535f2fca46cqsr@chromium.org    for (unsigned char i = 0; i < count; ++i) {
908cc32d3bb84656d7d8ada030ece22f7400461cf9waylonis      ArrayStructure local;
918cc32d3bb84656d7d8ada030ece22f7400461cf9waylonis      local.char_value = i;
928cc32d3bb84656d7d8ada030ece22f7400461cf9waylonis      local.short_value = i + 1;
938cc32d3bb84656d7d8ada030ece22f7400461cf9waylonis      local.long_value = i + 2;
948cc32d3bb84656d7d8ada030ece22f7400461cf9waylonis      ASSERT_TRUE(array.CopyIndex(i, &local));
958cc32d3bb84656d7d8ada030ece22f7400461cf9waylonis    }
968cc32d3bb84656d7d8ada030ece22f7400461cf9waylonis
978cc32d3bb84656d7d8ada030ece22f7400461cf9waylonis    // Test an object followed by an array
98e5dc60822e5938fea2ae892ccddb906641ba174emmentovai    google_breakpad::TypedMDRVA<ObjectAndArrayStructure> obj_array(&writer);
998cc32d3bb84656d7d8ada030ece22f7400461cf9waylonis    ASSERT_TRUE(obj_array.AllocateObjectAndArray(count,
1008cc32d3bb84656d7d8ada030ece22f7400461cf9waylonis                                                 sizeof(ArrayStructure)));
1018cc32d3bb84656d7d8ada030ece22f7400461cf9waylonis    obj_array.get()->count = count;
102486229ba5044ee2e7f49d2f6000e6535f2fca46cqsr@chromium.org    for (unsigned char i = 0; i < count; ++i) {
1038cc32d3bb84656d7d8ada030ece22f7400461cf9waylonis      ArrayStructure local;
1048cc32d3bb84656d7d8ada030ece22f7400461cf9waylonis      local.char_value = i;
1058cc32d3bb84656d7d8ada030ece22f7400461cf9waylonis      local.short_value = i + 1;
1068cc32d3bb84656d7d8ada030ece22f7400461cf9waylonis      local.long_value = i + 2;
1078cc32d3bb84656d7d8ada030ece22f7400461cf9waylonis      ASSERT_TRUE(obj_array.CopyIndexAfterObject(i, &local, sizeof(local)));
1088cc32d3bb84656d7d8ada030ece22f7400461cf9waylonis    }
1098cc32d3bb84656d7d8ada030ece22f7400461cf9waylonis  }
1108cc32d3bb84656d7d8ada030ece22f7400461cf9waylonis
1118cc32d3bb84656d7d8ada030ece22f7400461cf9waylonis  return writer.Close();
1128cc32d3bb84656d7d8ada030ece22f7400461cf9waylonis}
1138cc32d3bb84656d7d8ada030ece22f7400461cf9waylonis
1148cc32d3bb84656d7d8ada030ece22f7400461cf9waylonisstatic bool CompareFile(const char *path) {
1158cc32d3bb84656d7d8ada030ece22f7400461cf9waylonis  unsigned long expected[] = {
1168cc32d3bb84656d7d8ada030ece22f7400461cf9waylonis#if defined(__BIG_ENDIAN__)
1178cc32d3bb84656d7d8ada030ece22f7400461cf9waylonis    0x0000beef, 0x0000001e, 0x00000018, 0x00000020, 0x00000038, 0x00000000,
1188cc32d3bb84656d7d8ada030ece22f7400461cf9waylonis    0x00000018, 0x00460069, 0x00720073, 0x00740020, 0x00530074, 0x00720069,
1198cc32d3bb84656d7d8ada030ece22f7400461cf9waylonis    0x006e0067, 0x00000000, 0x0000001a, 0x00530065, 0x0063006f, 0x006e0064,
1208cc32d3bb84656d7d8ada030ece22f7400461cf9waylonis    0x00200053, 0x00740072, 0x0069006e, 0x00670000, 0x00000001, 0x00000002,
1218cc32d3bb84656d7d8ada030ece22f7400461cf9waylonis    0x01000002, 0x00000003, 0x02000003, 0x00000004, 0x03000004, 0x00000005,
1228cc32d3bb84656d7d8ada030ece22f7400461cf9waylonis    0x04000005, 0x00000006, 0x05000006, 0x00000007, 0x06000007, 0x00000008,
1238cc32d3bb84656d7d8ada030ece22f7400461cf9waylonis    0x07000008, 0x00000009, 0x08000009, 0x0000000a, 0x0900000a, 0x0000000b,
1248cc32d3bb84656d7d8ada030ece22f7400461cf9waylonis    0x0000000a, 0x00000001, 0x00000002, 0x01000002, 0x00000003, 0x02000003,
1258cc32d3bb84656d7d8ada030ece22f7400461cf9waylonis    0x00000004, 0x03000004, 0x00000005, 0x04000005, 0x00000006, 0x05000006,
1268cc32d3bb84656d7d8ada030ece22f7400461cf9waylonis    0x00000007, 0x06000007, 0x00000008, 0x07000008, 0x00000009, 0x08000009,
1278cc32d3bb84656d7d8ada030ece22f7400461cf9waylonis    0x0000000a, 0x0900000a, 0x0000000b, 0x00000000
1288cc32d3bb84656d7d8ada030ece22f7400461cf9waylonis#else
1293ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid    0x0000beef, 0x0000001e, 0x00000018, 0x00000020,
1303ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid    0x00000038, 0x00000000, 0x00000018, 0x00690046,
1313ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid    0x00730072, 0x00200074, 0x00740053, 0x00690072,
1323ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid    0x0067006e, 0x00000000, 0x0000001a, 0x00650053,
1333ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid    0x006f0063, 0x0064006e, 0x00530020, 0x00720074,
1343ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid    0x006e0069, 0x00000067, 0x00011e00, 0x00000002,
1353ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid    0x00021e01, 0x00000003, 0x00031e02, 0x00000004,
1363ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid    0x00041e03, 0x00000005, 0x00051e04, 0x00000006,
1373ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid    0x00061e05, 0x00000007, 0x00071e06, 0x00000008,
1383ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid    0x00081e07, 0x00000009, 0x00091e08, 0x0000000a,
1393ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid    0x000a1e09, 0x0000000b, 0x0000000a, 0x00011c00,
1403ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid    0x00000002, 0x00021c01, 0x00000003, 0x00031c02,
1413ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid    0x00000004, 0x00041c03, 0x00000005, 0x00051c04,
1423ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid    0x00000006, 0x00061c05, 0x00000007, 0x00071c06,
1433ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid    0x00000008, 0x00081c07, 0x00000009, 0x00091c08,
1443ebdb1bd7ae38bf0fb205dfaa2f5fde3d67ea141nealsid    0x0000000a, 0x000a1c09, 0x0000000b, 0x00000000,
1458cc32d3bb84656d7d8ada030ece22f7400461cf9waylonis#endif
1468cc32d3bb84656d7d8ada030ece22f7400461cf9waylonis  };
1474ac61acb3a7dad6ce722fe07564be8ec92713228dmaclach  size_t expected_byte_count = sizeof(expected);
1488cc32d3bb84656d7d8ada030ece22f7400461cf9waylonis  int fd = open(path, O_RDONLY, 0600);
1498cc32d3bb84656d7d8ada030ece22f7400461cf9waylonis  void *buffer = malloc(expected_byte_count);
1508cc32d3bb84656d7d8ada030ece22f7400461cf9waylonis  ASSERT_NE(fd, -1);
1518cc32d3bb84656d7d8ada030ece22f7400461cf9waylonis  ASSERT_TRUE(buffer);
1524ac61acb3a7dad6ce722fe07564be8ec92713228dmaclach  ASSERT_EQ(read(fd, buffer, expected_byte_count),
1534ac61acb3a7dad6ce722fe07564be8ec92713228dmaclach            static_cast<ssize_t>(expected_byte_count));
1545da03791a71a6c5b3b1ef15ec8882bffa21ceb39nealsid
1555da03791a71a6c5b3b1ef15ec8882bffa21ceb39nealsid  char *b1, *b2;
1564ac61acb3a7dad6ce722fe07564be8ec92713228dmaclach  b1 = reinterpret_cast<char*>(buffer);
1574ac61acb3a7dad6ce722fe07564be8ec92713228dmaclach  b2 = reinterpret_cast<char*>(expected);
1585da03791a71a6c5b3b1ef15ec8882bffa21ceb39nealsid  while (*b1 == *b2) {
1595da03791a71a6c5b3b1ef15ec8882bffa21ceb39nealsid    b1++;
1605da03791a71a6c5b3b1ef15ec8882bffa21ceb39nealsid    b2++;
1615da03791a71a6c5b3b1ef15ec8882bffa21ceb39nealsid  }
1625da03791a71a6c5b3b1ef15ec8882bffa21ceb39nealsid
1634ac61acb3a7dad6ce722fe07564be8ec92713228dmaclach  printf("%p\n", reinterpret_cast<void*>(b1 - (char*)buffer));
1645da03791a71a6c5b3b1ef15ec8882bffa21ceb39nealsid
1658cc32d3bb84656d7d8ada030ece22f7400461cf9waylonis  ASSERT_EQ(memcmp(buffer, expected, expected_byte_count), 0);
1668cc32d3bb84656d7d8ada030ece22f7400461cf9waylonis  return true;
1678cc32d3bb84656d7d8ada030ece22f7400461cf9waylonis}
1688cc32d3bb84656d7d8ada030ece22f7400461cf9waylonis
1698cc32d3bb84656d7d8ada030ece22f7400461cf9waylonisstatic bool RunTests() {
1708cc32d3bb84656d7d8ada030ece22f7400461cf9waylonis  const char *path = "/tmp/minidump_file_writer_unittest.dmp";
1718cc32d3bb84656d7d8ada030ece22f7400461cf9waylonis  ASSERT_TRUE(WriteFile(path));
1728cc32d3bb84656d7d8ada030ece22f7400461cf9waylonis  ASSERT_TRUE(CompareFile(path));
1738cc32d3bb84656d7d8ada030ece22f7400461cf9waylonis  unlink(path);
1748cc32d3bb84656d7d8ada030ece22f7400461cf9waylonis  return true;
1758cc32d3bb84656d7d8ada030ece22f7400461cf9waylonis}
1768cc32d3bb84656d7d8ada030ece22f7400461cf9waylonis
1778cc32d3bb84656d7d8ada030ece22f7400461cf9waylonisextern "C" int main(int argc, const char *argv[]) {
1788cc32d3bb84656d7d8ada030ece22f7400461cf9waylonis  return RunTests() ? 0 : 1;
1798cc32d3bb84656d7d8ada030ece22f7400461cf9waylonis}
180