// Copyright (c) 2014, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//     * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

// Unit test for MicrodumpProcessor.

#include <fstream>
#include <iostream>
#include <string>
#include <vector>

#include "breakpad_googletest_includes.h"
#include "google_breakpad/processor/basic_source_line_resolver.h"
#include "google_breakpad/processor/call_stack.h"
#include "google_breakpad/processor/microdump_processor.h"
#include "google_breakpad/processor/process_state.h"
#include "google_breakpad/processor/stack_frame.h"
#include "google_breakpad/processor/stack_frame_symbolizer.h"
#include "processor/simple_symbol_supplier.h"
#include "processor/stackwalker_unittest_utils.h"

namespace {

using google_breakpad::BasicSourceLineResolver;
using google_breakpad::MicrodumpProcessor;
using google_breakpad::ProcessState;
using google_breakpad::SimpleSymbolSupplier;
using google_breakpad::StackFrameSymbolizer;

class MicrodumpProcessorTest : public ::testing::Test {
 public:
  MicrodumpProcessorTest()
    : files_path_(string(getenv("srcdir") ? getenv("srcdir") : ".") +
                  "/src/processor/testdata/") {
  }

  void ReadFile(const string& file_name, string* file_contents) {
    assert(file_contents);
    std::ifstream file_stream(file_name.c_str(), std::ios::in);
    ASSERT_TRUE(file_stream.good());
    std::vector<char> bytes;
    file_stream.seekg(0, std::ios_base::end);
    ASSERT_TRUE(file_stream.good());
    bytes.resize(file_stream.tellg());
    file_stream.seekg(0, std::ios_base::beg);
    ASSERT_TRUE(file_stream.good());
    file_stream.read(&bytes[0], bytes.size());
    ASSERT_TRUE(file_stream.good());
    *file_contents = string(&bytes[0], bytes.size());
  }

  google_breakpad::ProcessResult ProcessMicrodump(
      const string& symbols_file,
      const string& microdump_contents,
      ProcessState* state) {
    SimpleSymbolSupplier supplier(symbols_file);
    BasicSourceLineResolver resolver;
    StackFrameSymbolizer frame_symbolizer(&supplier, &resolver);
    MicrodumpProcessor processor(&frame_symbolizer);

    return processor.Process(microdump_contents, state);
  }

  void AnalyzeDump(const string& microdump_file_name, bool omit_symbols,
                   int expected_cpu_count, ProcessState* state) {
    string symbols_file = omit_symbols ? "" : files_path_ + "symbols/microdump";
    string microdump_file_path = files_path_ + microdump_file_name;
    string microdump_contents;
    ReadFile(microdump_file_path, &microdump_contents);

    google_breakpad::ProcessResult result =
        ProcessMicrodump(symbols_file, microdump_contents, state);

    ASSERT_EQ(google_breakpad::PROCESS_OK, result);
    ASSERT_TRUE(state->crashed());
    ASSERT_EQ(0, state->requesting_thread());
    ASSERT_EQ(1U, state->threads()->size());

    ASSERT_EQ(expected_cpu_count, state->system_info()->cpu_count);
    ASSERT_EQ("android", state->system_info()->os_short);
    ASSERT_EQ("Android", state->system_info()->os);
  }

  string files_path_;
};

TEST_F(MicrodumpProcessorTest, TestProcess_Empty) {
  ProcessState state;
  google_breakpad::ProcessResult result =
      ProcessMicrodump("", "", &state);
  ASSERT_EQ(google_breakpad::PROCESS_ERROR_MINIDUMP_NOT_FOUND, result);
}

TEST_F(MicrodumpProcessorTest, TestProcess_Invalid) {
  ProcessState state;
  google_breakpad::ProcessResult result =
      ProcessMicrodump("", "This is not a valid microdump", &state);
  ASSERT_EQ(google_breakpad::PROCESS_ERROR_NO_THREAD_LIST, result);
}

TEST_F(MicrodumpProcessorTest, TestProcess_MissingSymbols) {
  ProcessState state;
  AnalyzeDump("microdump-arm64.dmp", true /* omit_symbols */,
              2 /* expected_cpu_count */, &state);

  ASSERT_EQ(8U, state.modules()->module_count());
  ASSERT_EQ("arm64", state.system_info()->cpu);
  ASSERT_EQ("OS 64 VERSION INFO", state.system_info()->os_version);
  ASSERT_EQ(1U, state.threads()->size());
  ASSERT_EQ(12U, state.threads()->at(0)->frames()->size());

  ASSERT_EQ("",
            state.threads()->at(0)->frames()->at(0)->function_name);
  ASSERT_EQ("",
            state.threads()->at(0)->frames()->at(3)->function_name);
}

TEST_F(MicrodumpProcessorTest, TestProcess_UnsupportedArch) {
  string microdump_contents =
      "W/google-breakpad(26491): -----BEGIN BREAKPAD MICRODUMP-----\n"
      "W/google-breakpad(26491): O A \"unsupported-arch\"\n"
      "W/google-breakpad(26491): S 0 A48BD840 A48BD000 00002000\n";

  ProcessState state;

  google_breakpad::ProcessResult result =
      ProcessMicrodump("", microdump_contents, &state);

  ASSERT_EQ(google_breakpad::PROCESS_ERROR_NO_THREAD_LIST, result);
}

TEST_F(MicrodumpProcessorTest, TestProcessArm) {
  ProcessState state;
  AnalyzeDump("microdump-arm.dmp", false /* omit_symbols */,
              2 /* expected_cpu_count*/, &state);

  ASSERT_EQ(6U, state.modules()->module_count());
  ASSERT_EQ("arm", state.system_info()->cpu);
  ASSERT_EQ("OpenGL ES 3.0 V@104.0 AU@  (GIT@Id3510ff6dc)",
            state.system_info()->gl_version);
  ASSERT_EQ("Qualcomm", state.system_info()->gl_vendor);
  ASSERT_EQ("Adreno (TM) 330", state.system_info()->gl_renderer);
  ASSERT_EQ("OS VERSION INFO", state.system_info()->os_version);
  ASSERT_EQ(8U, state.threads()->at(0)->frames()->size());
  ASSERT_EQ("MicrodumpWriterTest_Setup_Test::TestBody",
            state.threads()->at(0)->frames()->at(0)->function_name);
  ASSERT_EQ("testing::Test::Run",
            state.threads()->at(0)->frames()->at(1)->function_name);
  ASSERT_EQ("main",
            state.threads()->at(0)->frames()->at(6)->function_name);
  ASSERT_EQ("breakpad_unittests",
            state.threads()->at(0)->frames()->at(6)->module->code_file());
}

TEST_F(MicrodumpProcessorTest, TestProcessArm64) {
  ProcessState state;
  AnalyzeDump("microdump-arm64.dmp", false /* omit_symbols */,
              2 /* expected_cpu_count*/, &state);

  ASSERT_EQ(8U, state.modules()->module_count());
  ASSERT_EQ("arm64", state.system_info()->cpu);
  ASSERT_EQ("OS 64 VERSION INFO", state.system_info()->os_version);
  ASSERT_EQ(9U, state.threads()->at(0)->frames()->size());
  ASSERT_EQ("MicrodumpWriterTest_Setup_Test::TestBody",
            state.threads()->at(0)->frames()->at(0)->function_name);
  ASSERT_EQ("testing::Test::Run",
            state.threads()->at(0)->frames()->at(2)->function_name);
  ASSERT_EQ("main",
            state.threads()->at(0)->frames()->at(7)->function_name);
  ASSERT_EQ("breakpad_unittests",
            state.threads()->at(0)->frames()->at(7)->module->code_file());
}

TEST_F(MicrodumpProcessorTest, TestProcessX86) {
  ProcessState state;
  AnalyzeDump("microdump-x86.dmp", false /* omit_symbols */,
              4 /* expected_cpu_count */, &state);

  ASSERT_EQ(124U, state.modules()->module_count());
  ASSERT_EQ("x86", state.system_info()->cpu);
  ASSERT_EQ("asus/WW_Z00A/Z00A:5.0/LRX21V/2.19.40.22_20150627_5104_user:user/"
      "release-keys", state.system_info()->os_version);
  ASSERT_EQ(56U, state.threads()->at(0)->frames()->size());
  ASSERT_EQ("libc.so",
            state.threads()->at(0)->frames()->at(0)->module->debug_file());
  // TODO(mmandlis): Get symbols for the test X86 microdump and test function
  // names.
}

TEST_F(MicrodumpProcessorTest, TestProcessMultiple) {
  ProcessState state;
  AnalyzeDump("microdump-multiple.dmp", false /* omit_symbols */,
              6 /* expected_cpu_count */, &state);
  ASSERT_EQ(156U, state.modules()->module_count());
  ASSERT_EQ("arm", state.system_info()->cpu);
  ASSERT_EQ("lge/p1_tmo_us/p1:6.0/MRA58K/1603210524c8d:user/release-keys",
            state.system_info()->os_version);
  ASSERT_EQ(5U, state.threads()->at(0)->frames()->size());
}

TEST_F(MicrodumpProcessorTest, TestProcessMips) {
  ProcessState state;
  AnalyzeDump("microdump-mips32.dmp", false /* omit_symbols */,
              2 /* expected_cpu_count */, &state);

  ASSERT_EQ(7U, state.modules()->module_count());
  ASSERT_EQ("mips", state.system_info()->cpu);
  ASSERT_EQ("3.0.8-g893bf16 #7 SMP PREEMPT Fri Jul 10 15:20:59 PDT 2015",
      state.system_info()->os_version);
  ASSERT_EQ(4U, state.threads()->at(0)->frames()->size());

  ASSERT_EQ("blaTest",
            state.threads()->at(0)->frames()->at(0)->function_name);
  ASSERT_EQ("Crash",
            state.threads()->at(0)->frames()->at(1)->function_name);
  ASSERT_EQ("main",
            state.threads()->at(0)->frames()->at(2)->function_name);
  ASSERT_EQ("crash_example",
            state.threads()->at(0)->frames()->at(0)->module->debug_file());
}

TEST_F(MicrodumpProcessorTest, TestProcessMips64) {
  ProcessState state;
  AnalyzeDump("microdump-mips64.dmp", false /* omit_symbols */,
              1 /* expected_cpu_count */, &state);

  ASSERT_EQ(8U, state.modules()->module_count());
  ASSERT_EQ("mips64", state.system_info()->cpu);
  ASSERT_EQ("3.10.0-gf185e20 #112 PREEMPT Mon Oct 5 11:12:49 PDT 2015",
        state.system_info()->os_version);
  ASSERT_EQ(4U, state.threads()->at(0)->frames()->size());

  ASSERT_EQ("blaTest",
            state.threads()->at(0)->frames()->at(0)->function_name);
  ASSERT_EQ("Crash",
            state.threads()->at(0)->frames()->at(1)->function_name);
  ASSERT_EQ("main",
            state.threads()->at(0)->frames()->at(2)->function_name);
  ASSERT_EQ("crash_example",
            state.threads()->at(0)->frames()->at(0)->module->debug_file());
}

}  // namespace

int main(int argc, char* argv[]) {
  ::testing::InitGoogleTest(&argc, argv);
  return RUN_ALL_TESTS();
}
