// Copyright 2014 The Crashpad Authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "minidump/minidump_memory_writer.h"

#include <utility>

#include "base/format_macros.h"
#include "base/stl_util.h"
#include "base/strings/stringprintf.h"
#include "gtest/gtest.h"
#include "minidump/minidump_extensions.h"
#include "minidump/minidump_file_writer.h"
#include "minidump/test/minidump_file_writer_test_util.h"
#include "minidump/test/minidump_memory_writer_test_util.h"
#include "minidump/test/minidump_writable_test_util.h"
#include "snapshot/test/test_memory_snapshot.h"
#include "util/file/string_file.h"

namespace crashpad {
namespace test {
namespace {

constexpr MinidumpStreamType kBogusStreamType =
    static_cast<MinidumpStreamType>(1234);

// expected_streams is the expected number of streams in the file. The memory
// list must be the last stream. If there is another stream, it must come first,
// have stream type kBogusStreamType, and have zero-length data.
void GetMemoryListStream(const std::string& file_contents,
                         const MINIDUMP_MEMORY_LIST** memory_list,
                         const uint32_t expected_streams) {
  constexpr size_t kDirectoryOffset = sizeof(MINIDUMP_HEADER);
  const size_t kMemoryListStreamOffset =
      kDirectoryOffset + expected_streams * sizeof(MINIDUMP_DIRECTORY);
  const size_t kMemoryDescriptorsOffset =
      kMemoryListStreamOffset + sizeof(MINIDUMP_MEMORY_LIST);

  ASSERT_GE(file_contents.size(), kMemoryDescriptorsOffset);

  const MINIDUMP_DIRECTORY* directory;
  const MINIDUMP_HEADER* header =
      MinidumpHeaderAtStart(file_contents, &directory);
  ASSERT_NO_FATAL_FAILURE(VerifyMinidumpHeader(header, expected_streams, 0));
  ASSERT_TRUE(directory);

  size_t directory_index = 0;
  if (expected_streams > 1) {
    ASSERT_EQ(directory[directory_index].StreamType, kBogusStreamType);
    ASSERT_EQ(directory[directory_index].Location.DataSize, 0u);
    ASSERT_EQ(directory[directory_index].Location.Rva, kMemoryListStreamOffset);
    ++directory_index;
  }

  ASSERT_EQ(directory[directory_index].StreamType,
            kMinidumpStreamTypeMemoryList);
  EXPECT_EQ(directory[directory_index].Location.Rva, kMemoryListStreamOffset);

  *memory_list = MinidumpWritableAtLocationDescriptor<MINIDUMP_MEMORY_LIST>(
      file_contents, directory[directory_index].Location);
  ASSERT_TRUE(memory_list);
}

TEST(MinidumpMemoryWriter, EmptyMemoryList) {
  MinidumpFileWriter minidump_file_writer;
  auto memory_list_writer = std::make_unique<MinidumpMemoryListWriter>();

  ASSERT_TRUE(minidump_file_writer.AddStream(std::move(memory_list_writer)));

  StringFile string_file;
  ASSERT_TRUE(minidump_file_writer.WriteEverything(&string_file));

  ASSERT_EQ(string_file.string().size(),
            sizeof(MINIDUMP_HEADER) + sizeof(MINIDUMP_DIRECTORY) +
                sizeof(MINIDUMP_MEMORY_LIST));

  const MINIDUMP_MEMORY_LIST* memory_list = nullptr;
  ASSERT_NO_FATAL_FAILURE(
      GetMemoryListStream(string_file.string(), &memory_list, 1));

  EXPECT_EQ(memory_list->NumberOfMemoryRanges, 0u);
}

TEST(MinidumpMemoryWriter, OneMemoryRegion) {
  MinidumpFileWriter minidump_file_writer;
  auto memory_list_writer = std::make_unique<MinidumpMemoryListWriter>();

  constexpr uint64_t kBaseAddress = 0xfedcba9876543210;
  constexpr size_t kSize = 0x1000;
  constexpr uint8_t kValue = 'm';

  auto memory_writer =
      std::make_unique<TestMinidumpMemoryWriter>(kBaseAddress, kSize, kValue);
  memory_list_writer->AddMemory(std::move(memory_writer));

  ASSERT_TRUE(minidump_file_writer.AddStream(std::move(memory_list_writer)));

  StringFile string_file;
  ASSERT_TRUE(minidump_file_writer.WriteEverything(&string_file));

  const MINIDUMP_MEMORY_LIST* memory_list = nullptr;
  ASSERT_NO_FATAL_FAILURE(
      GetMemoryListStream(string_file.string(), &memory_list, 1));

  MINIDUMP_MEMORY_DESCRIPTOR expected;
  expected.StartOfMemoryRange = kBaseAddress;
  expected.Memory.DataSize = kSize;
  expected.Memory.Rva =
      sizeof(MINIDUMP_HEADER) + sizeof(MINIDUMP_DIRECTORY) +
      sizeof(MINIDUMP_MEMORY_LIST) +
      memory_list->NumberOfMemoryRanges * sizeof(MINIDUMP_MEMORY_DESCRIPTOR);
  ExpectMinidumpMemoryDescriptorAndContents(&expected,
                                            &memory_list->MemoryRanges[0],
                                            string_file.string(),
                                            kValue,
                                            true);
}

TEST(MinidumpMemoryWriter, TwoMemoryRegions) {
  MinidumpFileWriter minidump_file_writer;
  auto memory_list_writer = std::make_unique<MinidumpMemoryListWriter>();

  constexpr uint64_t kBaseAddress0 = 0xc0ffee;
  constexpr size_t kSize0 = 0x0100;
  constexpr uint8_t kValue0 = '6';
  constexpr uint64_t kBaseAddress1 = 0xfac00fac;
  constexpr size_t kSize1 = 0x0200;
  constexpr uint8_t kValue1 = '!';

  auto memory_writer_0 = std::make_unique<TestMinidumpMemoryWriter>(
      kBaseAddress0, kSize0, kValue0);
  memory_list_writer->AddMemory(std::move(memory_writer_0));
  auto memory_writer_1 = std::make_unique<TestMinidumpMemoryWriter>(
      kBaseAddress1, kSize1, kValue1);
  memory_list_writer->AddMemory(std::move(memory_writer_1));

  ASSERT_TRUE(minidump_file_writer.AddStream(std::move(memory_list_writer)));

  StringFile string_file;
  ASSERT_TRUE(minidump_file_writer.WriteEverything(&string_file));

  const MINIDUMP_MEMORY_LIST* memory_list = nullptr;
  ASSERT_NO_FATAL_FAILURE(
      GetMemoryListStream(string_file.string(), &memory_list, 1));

  EXPECT_EQ(memory_list->NumberOfMemoryRanges, 2u);

  MINIDUMP_MEMORY_DESCRIPTOR expected;

  {
    SCOPED_TRACE("region 0");

    expected.StartOfMemoryRange = kBaseAddress0;
    expected.Memory.DataSize = kSize0;
    expected.Memory.Rva =
        sizeof(MINIDUMP_HEADER) + sizeof(MINIDUMP_DIRECTORY) +
        sizeof(MINIDUMP_MEMORY_LIST) +
        memory_list->NumberOfMemoryRanges * sizeof(MINIDUMP_MEMORY_DESCRIPTOR);
    ExpectMinidumpMemoryDescriptorAndContents(&expected,
                                              &memory_list->MemoryRanges[0],
                                              string_file.string(),
                                              kValue0,
                                              false);
  }

  {
    SCOPED_TRACE("region 1");

    expected.StartOfMemoryRange = kBaseAddress1;
    expected.Memory.DataSize = kSize1;
    expected.Memory.Rva = memory_list->MemoryRanges[0].Memory.Rva +
                          memory_list->MemoryRanges[0].Memory.DataSize;
    ExpectMinidumpMemoryDescriptorAndContents(&expected,
                                              &memory_list->MemoryRanges[1],
                                              string_file.string(),
                                              kValue1,
                                              true);
  }
}

TEST(MinidumpMemoryWriter, RegionReadFails) {
  MinidumpFileWriter minidump_file_writer;
  auto memory_list_writer = std::make_unique<MinidumpMemoryListWriter>();

  constexpr uint64_t kBaseAddress = 0xfedcba9876543210;
  constexpr size_t kSize = 0x1000;
  constexpr uint8_t kValue = 'm';

  auto memory_writer =
      std::make_unique<TestMinidumpMemoryWriter>(kBaseAddress, kSize, kValue);

  // Make the read of that memory fail.
  memory_writer->SetShouldFailRead(true);

  memory_list_writer->AddMemory(std::move(memory_writer));

  ASSERT_TRUE(minidump_file_writer.AddStream(std::move(memory_list_writer)));

  StringFile string_file;
  ASSERT_TRUE(minidump_file_writer.WriteEverything(&string_file));

  const MINIDUMP_MEMORY_LIST* memory_list = nullptr;
  ASSERT_NO_FATAL_FAILURE(
      GetMemoryListStream(string_file.string(), &memory_list, 1));

  MINIDUMP_MEMORY_DESCRIPTOR expected;
  expected.StartOfMemoryRange = kBaseAddress;
  expected.Memory.DataSize = kSize;
  expected.Memory.Rva =
      sizeof(MINIDUMP_HEADER) + sizeof(MINIDUMP_DIRECTORY) +
      sizeof(MINIDUMP_MEMORY_LIST) +
      memory_list->NumberOfMemoryRanges * sizeof(MINIDUMP_MEMORY_DESCRIPTOR);
  ExpectMinidumpMemoryDescriptorAndContents(
      &expected,
      &memory_list->MemoryRanges[0],
      string_file.string(),
      0xfe,  // Not kValue ('m'), but the value that the implementation inserts
             // if memory is unreadable.
      true);
}

class TestMemoryStream final : public internal::MinidumpStreamWriter {
 public:
  TestMemoryStream(uint64_t base_address, size_t size, uint8_t value)
      : MinidumpStreamWriter(), memory_(base_address, size, value) {}

  ~TestMemoryStream() override {}

  TestMinidumpMemoryWriter* memory() {
    return &memory_;
  }

  // MinidumpStreamWriter:
  MinidumpStreamType StreamType() const override {
    return kBogusStreamType;
  }

 protected:
  // MinidumpWritable:
  size_t SizeOfObject() override {
    EXPECT_GE(state(), kStateFrozen);
    return 0;
  }

  std::vector<MinidumpWritable*> Children() override {
    EXPECT_GE(state(), kStateFrozen);
    std::vector<MinidumpWritable*> children(1, memory());
    return children;
  }

  bool WriteObject(FileWriterInterface* file_writer) override {
    EXPECT_EQ(state(), kStateWritable);
    return true;
  }

 private:
  TestMinidumpMemoryWriter memory_;

  DISALLOW_COPY_AND_ASSIGN(TestMemoryStream);
};

TEST(MinidumpMemoryWriter, ExtraMemory) {
  // This tests MinidumpMemoryListWriter::AddExtraMemory(). That method adds
  // a MinidumpMemoryWriter to the MinidumpMemoryListWriter without making the
  // memory writer a child of the memory list writer.
  MinidumpFileWriter minidump_file_writer;

  constexpr uint64_t kBaseAddress0 = 0x1000;
  constexpr size_t kSize0 = 0x0400;
  constexpr uint8_t kValue0 = '1';
  auto test_memory_stream =
      std::make_unique<TestMemoryStream>(kBaseAddress0, kSize0, kValue0);

  auto memory_list_writer = std::make_unique<MinidumpMemoryListWriter>();
  memory_list_writer->AddNonOwnedMemory(test_memory_stream->memory());

  ASSERT_TRUE(minidump_file_writer.AddStream(std::move(test_memory_stream)));

  constexpr uint64_t kBaseAddress1 = 0x2000;
  constexpr size_t kSize1 = 0x0400;
  constexpr uint8_t kValue1 = 'm';

  auto memory_writer = std::make_unique<TestMinidumpMemoryWriter>(
      kBaseAddress1, kSize1, kValue1);
  memory_list_writer->AddMemory(std::move(memory_writer));

  ASSERT_TRUE(minidump_file_writer.AddStream(std::move(memory_list_writer)));

  StringFile string_file;
  ASSERT_TRUE(minidump_file_writer.WriteEverything(&string_file));

  const MINIDUMP_MEMORY_LIST* memory_list = nullptr;
  ASSERT_NO_FATAL_FAILURE(
      GetMemoryListStream(string_file.string(), &memory_list, 2));

  EXPECT_EQ(memory_list->NumberOfMemoryRanges, 2u);

  MINIDUMP_MEMORY_DESCRIPTOR expected;

  {
    SCOPED_TRACE("region 0");

    expected.StartOfMemoryRange = kBaseAddress0;
    expected.Memory.DataSize = kSize0;
    expected.Memory.Rva =
        sizeof(MINIDUMP_HEADER) + 2 * sizeof(MINIDUMP_DIRECTORY) +
        sizeof(MINIDUMP_MEMORY_LIST) +
        memory_list->NumberOfMemoryRanges * sizeof(MINIDUMP_MEMORY_DESCRIPTOR);
    ExpectMinidumpMemoryDescriptorAndContents(&expected,
                                              &memory_list->MemoryRanges[0],
                                              string_file.string(),
                                              kValue0,
                                              false);
  }

  {
    SCOPED_TRACE("region 1");

    expected.StartOfMemoryRange = kBaseAddress1;
    expected.Memory.DataSize = kSize1;
    expected.Memory.Rva = memory_list->MemoryRanges[0].Memory.Rva +
                          memory_list->MemoryRanges[0].Memory.DataSize;
    ExpectMinidumpMemoryDescriptorAndContents(&expected,
                                              &memory_list->MemoryRanges[1],
                                              string_file.string(),
                                              kValue1,
                                              true);
  }
}

TEST(MinidumpMemoryWriter, AddFromSnapshot) {
  MINIDUMP_MEMORY_DESCRIPTOR expect_memory_descriptors[3] = {};
  uint8_t values[base::size(expect_memory_descriptors)] = {};

  expect_memory_descriptors[0].StartOfMemoryRange = 0;
  expect_memory_descriptors[0].Memory.DataSize = 0x1000;
  values[0] = 0x01;

  expect_memory_descriptors[1].StartOfMemoryRange = 0x2000;
  expect_memory_descriptors[1].Memory.DataSize = 0x2000;
  values[1] = 0xf4;

  expect_memory_descriptors[2].StartOfMemoryRange = 0x7654321000000000;
  expect_memory_descriptors[2].Memory.DataSize = 0x800;
  values[2] = 0xa9;

  std::vector<std::unique_ptr<TestMemorySnapshot>> memory_snapshots_owner;
  std::vector<const MemorySnapshot*> memory_snapshots;
  for (size_t index = 0; index < base::size(expect_memory_descriptors);
       ++index) {
    memory_snapshots_owner.push_back(std::make_unique<TestMemorySnapshot>());
    TestMemorySnapshot* memory_snapshot = memory_snapshots_owner.back().get();
    memory_snapshot->SetAddress(
        expect_memory_descriptors[index].StartOfMemoryRange);
    memory_snapshot->SetSize(expect_memory_descriptors[index].Memory.DataSize);
    memory_snapshot->SetValue(values[index]);
    memory_snapshots.push_back(memory_snapshot);
  }

  auto memory_list_writer = std::make_unique<MinidumpMemoryListWriter>();
  memory_list_writer->AddFromSnapshot(memory_snapshots);

  MinidumpFileWriter minidump_file_writer;
  ASSERT_TRUE(minidump_file_writer.AddStream(std::move(memory_list_writer)));

  StringFile string_file;
  ASSERT_TRUE(minidump_file_writer.WriteEverything(&string_file));

  const MINIDUMP_MEMORY_LIST* memory_list = nullptr;
  ASSERT_NO_FATAL_FAILURE(
      GetMemoryListStream(string_file.string(), &memory_list, 1));

  ASSERT_EQ(memory_list->NumberOfMemoryRanges, 3u);

  for (size_t index = 0; index < memory_list->NumberOfMemoryRanges; ++index) {
    SCOPED_TRACE(base::StringPrintf("index %" PRIuS, index));
    ExpectMinidumpMemoryDescriptorAndContents(
        &expect_memory_descriptors[index],
        &memory_list->MemoryRanges[index],
        string_file.string(),
        values[index],
        index == memory_list->NumberOfMemoryRanges - 1);
  }
}

TEST(MinidumpMemoryWriter, CoalesceExplicitMultiple) {
  MINIDUMP_MEMORY_DESCRIPTOR expect_memory_descriptors[4] = {};
  uint8_t values[base::size(expect_memory_descriptors)] = {};

  expect_memory_descriptors[0].StartOfMemoryRange = 0;
  expect_memory_descriptors[0].Memory.DataSize = 1000;
  values[0] = 0x01;

  expect_memory_descriptors[1].StartOfMemoryRange = 10000;
  expect_memory_descriptors[1].Memory.DataSize = 2000;
  values[1] = 0xf4;

  expect_memory_descriptors[2].StartOfMemoryRange = 0x1111111111111111;
  expect_memory_descriptors[2].Memory.DataSize = 1024;
  values[2] = 0x99;

  expect_memory_descriptors[3].StartOfMemoryRange = 0xfedcba9876543210;
  expect_memory_descriptors[3].Memory.DataSize = 1024;
  values[3] = 0x88;

  struct {
    uint64_t base;
    size_t size;
    uint8_t value;
  } snapshots_to_add[] = {
      // Various overlapping.
      {0, 500, 0x01},
      {0, 500, 0x01},
      {250, 500, 0x01},
      {600, 400, 0x01},

      // Empty removed.
      {0, 0, 0xbb},
      {300, 0, 0xcc},
      {1000, 0, 0xdd},
      {12000, 0, 0xee},

      // Abutting.
      {10000, 500, 0xf4},
      {10500, 500, 0xf4},
      {11000, 1000, 0xf4},

      // Large base addresses.
      { 0xfedcba9876543210, 1024, 0x88 },
      { 0x1111111111111111, 1024, 0x99 },
  };

  std::vector<std::unique_ptr<TestMemorySnapshot>> memory_snapshots_owner;
  std::vector<const MemorySnapshot*> memory_snapshots;
  for (const auto& to_add : snapshots_to_add) {
    memory_snapshots_owner.push_back(std::make_unique<TestMemorySnapshot>());
    TestMemorySnapshot* memory_snapshot = memory_snapshots_owner.back().get();
    memory_snapshot->SetAddress(to_add.base);
    memory_snapshot->SetSize(to_add.size);
    memory_snapshot->SetValue(to_add.value);
    memory_snapshots.push_back(memory_snapshot);
  }

  auto memory_list_writer = std::make_unique<MinidumpMemoryListWriter>();
  memory_list_writer->AddFromSnapshot(memory_snapshots);

  MinidumpFileWriter minidump_file_writer;
  minidump_file_writer.AddStream(std::move(memory_list_writer));

  StringFile string_file;
  ASSERT_TRUE(minidump_file_writer.WriteEverything(&string_file));

  const MINIDUMP_MEMORY_LIST* memory_list = nullptr;
  ASSERT_NO_FATAL_FAILURE(
      GetMemoryListStream(string_file.string(), &memory_list, 1));

  ASSERT_EQ(4u, memory_list->NumberOfMemoryRanges);

  for (size_t index = 0; index < memory_list->NumberOfMemoryRanges; ++index) {
    SCOPED_TRACE(base::StringPrintf("index %" PRIuS, index));
    ExpectMinidumpMemoryDescriptorAndContents(
        &expect_memory_descriptors[index],
        &memory_list->MemoryRanges[index],
        string_file.string(),
        values[index],
        index == memory_list->NumberOfMemoryRanges - 1);
  }
}

struct TestRange {
  TestRange(uint64_t base, size_t size) : base(base), size(size) {}

  uint64_t base;
  size_t size;
};

// Parses a string spec to build a list of ranges suitable for CoalesceTest().
std::vector<TestRange> ParseCoalesceSpec(const char* spec) {
  std::vector<TestRange> result;
  enum { kNone, kSpace, kDot } state = kNone;
  const char* range_started_at = nullptr;
  for (const char* p = spec;; ++p) {
    EXPECT_TRUE(*p == ' ' || *p == '.' || *p == 0);
    if (*p == ' ' || *p == 0) {
      if (state == kDot) {
        result.push_back(
            TestRange(range_started_at - spec, p - range_started_at));
      }
      state = kSpace;
      range_started_at = nullptr;
    } else if (*p == '.') {
      if (state != kDot) {
        range_started_at = p;
        state = kDot;
      }
    }

    if (*p == 0)
      break;
  }

  return result;
}

TEST(MinidumpMemoryWriter, CoalesceSpecHelperParse) {
  const auto empty = ParseCoalesceSpec("");
  ASSERT_EQ(empty.size(), 0u);

  const auto a = ParseCoalesceSpec("...");
  ASSERT_EQ(a.size(), 1u);
  EXPECT_EQ(a[0].base, 0u);
  EXPECT_EQ(a[0].size, 3u);

  const auto b = ParseCoalesceSpec("  ...");
  ASSERT_EQ(b.size(), 1u);
  EXPECT_EQ(b[0].base, 2u);
  EXPECT_EQ(b[0].size, 3u);

  const auto c = ParseCoalesceSpec("  ...  ");
  ASSERT_EQ(c.size(), 1u);
  EXPECT_EQ(c[0].base, 2u);
  EXPECT_EQ(c[0].size, 3u);

  const auto d = ParseCoalesceSpec("  ...  ....");
  ASSERT_EQ(d.size(), 2u);
  EXPECT_EQ(d[0].base, 2u);
  EXPECT_EQ(d[0].size, 3u);
  EXPECT_EQ(d[1].base, 7u);
  EXPECT_EQ(d[1].size, 4u);

  const auto e = ParseCoalesceSpec("  ...  ...... ... ");
  ASSERT_EQ(e.size(), 3u);
  EXPECT_EQ(e[0].base, 2u);
  EXPECT_EQ(e[0].size, 3u);
  EXPECT_EQ(e[1].base, 7u);
  EXPECT_EQ(e[1].size, 6u);
  EXPECT_EQ(e[2].base, 14u);
  EXPECT_EQ(e[2].size, 3u);
}

constexpr uint8_t kMemoryValue = 0xcd;

// Builds a coalesce test out of specs of ' ' and '.'. Tests that when the two
// ranges are added and coalesced, the result is equal to expected.
void CoalesceTest(const char* r1_spec,
                  const char* r2_spec,
                  const char* expected_spec) {
  auto r1 = ParseCoalesceSpec(r1_spec);
  auto r2 = ParseCoalesceSpec(r2_spec);
  auto expected = ParseCoalesceSpec(expected_spec);

  std::vector<MINIDUMP_MEMORY_DESCRIPTOR> expect_memory_descriptors;
  for (const auto& range : expected) {
    MINIDUMP_MEMORY_DESCRIPTOR mmd = {};
    mmd.StartOfMemoryRange = range.base;
    mmd.Memory.DataSize = static_cast<uint32_t>(range.size);
    expect_memory_descriptors.push_back(mmd);
  }

  std::vector<std::unique_ptr<TestMemorySnapshot>> memory_snapshots_owner;
  std::vector<const MemorySnapshot*> memory_snapshots;

  const auto add_test_memory_snapshots = [&memory_snapshots_owner,
                                          &memory_snapshots](
                                             std::vector<TestRange> ranges) {
    for (const auto& r : ranges) {
      memory_snapshots_owner.push_back(std::make_unique<TestMemorySnapshot>());
      TestMemorySnapshot* memory_snapshot = memory_snapshots_owner.back().get();
      memory_snapshot->SetAddress(r.base);
      memory_snapshot->SetSize(r.size);
      memory_snapshot->SetValue(kMemoryValue);
      memory_snapshots.push_back(memory_snapshot);
    }
  };
  add_test_memory_snapshots(r1);
  add_test_memory_snapshots(r2);

  auto memory_list_writer = std::make_unique<MinidumpMemoryListWriter>();
  memory_list_writer->AddFromSnapshot(memory_snapshots);

  MinidumpFileWriter minidump_file_writer;
  minidump_file_writer.AddStream(std::move(memory_list_writer));

  StringFile string_file;
  ASSERT_TRUE(minidump_file_writer.WriteEverything(&string_file));

  const MINIDUMP_MEMORY_LIST* memory_list = nullptr;
  ASSERT_NO_FATAL_FAILURE(
      GetMemoryListStream(string_file.string(), &memory_list, 1));

  ASSERT_EQ(expected.size(), memory_list->NumberOfMemoryRanges);

  for (size_t index = 0; index < memory_list->NumberOfMemoryRanges; ++index) {
    SCOPED_TRACE(base::StringPrintf("index %" PRIuS, index));
    ExpectMinidumpMemoryDescriptorAndContents(
        &expect_memory_descriptors[index],
        &memory_list->MemoryRanges[index],
        string_file.string(),
        kMemoryValue,
        index == memory_list->NumberOfMemoryRanges - 1);
  }
}

TEST(MinidumpMemoryWriter, CoalescePairsVariousCases) {
  // clang-format off

  CoalesceTest("  .........",
               "         .......",
  /* result */ "  ..............");

  CoalesceTest("         .......",
               "  .........",
  /* result */ "  ..............");

  CoalesceTest("     ...",
               "  .........",
  /* result */ "  .........");

  CoalesceTest("  .........",
               "    ......",
  /* result */ "  .........");

  CoalesceTest("  ...",
               "  ........",
  /* result */ "  ........");

  CoalesceTest("  ........",
               "  ...",
  /* result */ "  ........");

  CoalesceTest("       ...",
               "  ........",
  /* result */ "  ........");

  CoalesceTest("  ........",
               "       ...",
  /* result */ "  ........");

  CoalesceTest("  ...     ",
               "       ...",
  /* result */ "  ...  ...");

  CoalesceTest("       ...",
               "  ...     ",
  /* result */ "  ...  ...");

  CoalesceTest("...",
               ".....",
  /* result */ ".....");

  CoalesceTest("...",
               "   ..",
  /* result */ ".....");

  CoalesceTest("   .....",
               " ..",
  /* result */ " .......");

  CoalesceTest("  .........   ......",
               "         .......",
  /* result */ "  ..................");

  CoalesceTest("         .......",
               "  .........   ......",
  /* result */ "  ..................");

  CoalesceTest("      .....",
               "  .........   ......",
  /* result */ "  .........   ......");

  CoalesceTest("      .........      ....... ....  .",
               "  .........    ......           ....",
  /* result */ "  .......................... .......");

  // clang-format on
}

}  // namespace
}  // namespace test
}  // namespace crashpad
