aboutsummaryrefslogtreecommitdiff
path: root/src/processor/network_source_line_resolver_unittest.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/processor/network_source_line_resolver_unittest.cc')
-rw-r--r--src/processor/network_source_line_resolver_unittest.cc535
1 files changed, 0 insertions, 535 deletions
diff --git a/src/processor/network_source_line_resolver_unittest.cc b/src/processor/network_source_line_resolver_unittest.cc
deleted file mode 100644
index bf0aae78..00000000
--- a/src/processor/network_source_line_resolver_unittest.cc
+++ /dev/null
@@ -1,535 +0,0 @@
-// Copyright (c) 2010, 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 tests for NetworkSourceLineResolver.
-
-#include <string>
-
-#include "breakpad_googletest_includes.h"
-#include "google_breakpad/processor/network_source_line_resolver.h"
-#include "google_breakpad/processor/stack_frame.h"
-#include "google_breakpad/processor/symbol_supplier.h"
-#include "processor/basic_code_module.h"
-#include "processor/binarystream.h"
-#include "processor/cfi_frame_info.h"
-#include "processor/network_interface.h"
-#include "processor/network_source_line_protocol.h"
-#include "processor/windows_frame_info.h"
-
-namespace google_breakpad {
-class MockNetwork : public NetworkInterface {
- public:
- MockNetwork() {}
-
- MOCK_METHOD1(Init, bool(bool listen));
- MOCK_METHOD2(Send, bool(const char *data, size_t length));
- MOCK_METHOD1(WaitToReceive, bool(int timeout));
- MOCK_METHOD3(Receive, bool(char *buffer, size_t buffer_size,
- ssize_t &received));
-};
-}
-
-namespace {
-using std::string;
-using google_breakpad::binarystream;
-using google_breakpad::BasicCodeModule;
-using google_breakpad::CFIFrameInfo;
-using google_breakpad::MockNetwork;
-using google_breakpad::NetworkSourceLineResolver;
-using google_breakpad::StackFrame;
-using google_breakpad::SymbolSupplier;
-using google_breakpad::WindowsFrameInfo;
-using ::testing::_;
-using ::testing::Invoke;
-using ::testing::Return;
-using namespace google_breakpad::source_line_protocol;
-
-class TestNetworkSourceLineResolver : public ::testing::Test {
-public:
- TestNetworkSourceLineResolver() : resolver(NULL) {}
-
- void SetUp() {
- EXPECT_CALL(net, Init(false)).WillOnce(Return(true));
- resolver = new NetworkSourceLineResolver(&net, 0);
- }
-
- NetworkSourceLineResolver *resolver;
- MockNetwork net;
-};
-
-bool GeneratePositiveHasResponse(char *buffer, size_t buffer_size,
- ssize_t &received) {
- binarystream stream;
- stream << u_int16_t(0) << OK << MODULE_LOADED;
- string s = stream.str();
- received = s.length();
- memcpy(buffer, s.c_str(), s.length());
- return true;
-}
-
-bool GenerateNegativeHasResponse(char *buffer, size_t buffer_size,
- ssize_t &received) {
- binarystream stream;
- stream << u_int16_t(1) << OK << MODULE_NOT_LOADED;
- string s = stream.str();
- received = s.length();
- memcpy(buffer, s.c_str(), s.length());
- return true;
-}
-
-TEST_F(TestNetworkSourceLineResolver, TestHasMessages) {
- EXPECT_CALL(net, Send(_,_))
- .WillOnce(Return(true))
- .WillOnce(Return(true));
- EXPECT_CALL(net, WaitToReceive(0))
- .WillOnce(Return(true))
- .WillOnce(Return(true));
- EXPECT_CALL(net, Receive(_,_,_))
- .WillOnce(Invoke(GeneratePositiveHasResponse))
- .WillOnce(Invoke(GenerateNegativeHasResponse));
- ASSERT_NE(resolver, (NetworkSourceLineResolver*)NULL);
- BasicCodeModule module(0x0, 0x0, "test.dll", "test.pdb", "ABCD", "", "");
- EXPECT_TRUE(resolver->HasModule(&module));
- BasicCodeModule module2(0x0, 0x0, "test2.dll", "test2.pdb", "FFFF", "", "");
- EXPECT_FALSE(resolver->HasModule(&module2));
- // calling again should hit the cache, and not the network
- EXPECT_TRUE(resolver->HasModule(&module));
-}
-
-bool GenerateErrorResponse(char *buffer, size_t buffer_size,
- ssize_t &received) {
- binarystream stream;
- stream << u_int16_t(0) << ERROR;
- string s = stream.str();
- received = s.length();
- memcpy(buffer, s.c_str(), s.length());
- return true;
-}
-
-TEST_F(TestNetworkSourceLineResolver, TestHasErrorResponse) {
- EXPECT_CALL(net, Send(_,_))
- .WillOnce(Return(true));
- EXPECT_CALL(net, WaitToReceive(0))
- .WillOnce(Return(true));
- EXPECT_CALL(net, Receive(_,_,_))
- .WillOnce(Invoke(GenerateErrorResponse));
- ASSERT_NE(resolver, (NetworkSourceLineResolver*)NULL);
- BasicCodeModule module(0x0, 0x0, "test.dll", "test.pdb", "ABCD", "", "");
- // error packet should function as a not found
- EXPECT_FALSE(resolver->HasModule(&module));
-}
-
-// GenerateLoadResponse will generate (LOAD_NOT_FOUND, LOAD_INTERRUPT,
-// LOAD_FAIL, LOAD_OK) in order.
-class LoadHelper {
- public:
- LoadHelper() : response(LOAD_NOT_FOUND), sequence(0) {}
- bool GenerateLoadResponse(char *buffer, size_t buffer_size,
- ssize_t &received) {
- binarystream stream;
- stream << sequence << OK << response;
- string s = stream.str();
- received = s.length();
- memcpy(buffer, s.c_str(), s.length());
- ++sequence;
- ++response;
- return true;
- }
- u_int8_t response;
- u_int16_t sequence;
-};
-
-TEST_F(TestNetworkSourceLineResolver, TestLoadMessages) {
- EXPECT_CALL(net, Send(_,_))
- .Times(4)
- .WillRepeatedly(Return(true));
- EXPECT_CALL(net, WaitToReceive(0))
- .Times(4)
- .WillRepeatedly(Return(true));
- LoadHelper helper;
- EXPECT_CALL(net, Receive(_,_,_))
- .Times(4)
- .WillRepeatedly(Invoke(&helper, &LoadHelper::GenerateLoadResponse));
- ASSERT_NE(resolver, (NetworkSourceLineResolver*)NULL);
- BasicCodeModule module(0x0, 0x0, "test.dll", "test.pdb", "ABCD", "", "");
- string s;
- EXPECT_EQ(SymbolSupplier::NOT_FOUND,
- resolver->GetSymbolFile(&module, NULL, &s));
- BasicCodeModule module2(0x0, 0x0, "test2.dll", "test2.pdb", "FFFF", "", "");
- EXPECT_EQ(SymbolSupplier::INTERRUPT,
- resolver->GetSymbolFile(&module2, NULL, &s));
- BasicCodeModule module3(0x0, 0x0, "test3.dll", "test3.pdb", "0000", "", "");
- // a FAIL result from the network should come back as NOT_FOUND
- EXPECT_EQ(SymbolSupplier::NOT_FOUND,
- resolver->GetSymbolFile(&module3, NULL, &s));
- BasicCodeModule module4(0x0, 0x0, "test4.dll", "test4.pdb", "1010", "", "");
- EXPECT_EQ(SymbolSupplier::FOUND,
- resolver->GetSymbolFile(&module4, NULL, &s));
- // calling this should hit the cache, and not the network
- EXPECT_TRUE(resolver->HasModule(&module4));
-}
-
-TEST_F(TestNetworkSourceLineResolver, TestLoadErrorResponse) {
- EXPECT_CALL(net, Send(_,_))
- .WillOnce(Return(true));
- EXPECT_CALL(net, WaitToReceive(0))
- .WillOnce(Return(true));
- EXPECT_CALL(net, Receive(_,_,_))
- .WillOnce(Invoke(GenerateErrorResponse));
- ASSERT_NE(resolver, (NetworkSourceLineResolver*)NULL);
- BasicCodeModule module(0x0, 0x0, "test.dll", "test.pdb", "ABCD", "", "");
- string s;
- // error packet should function as NOT_FOUND response
- EXPECT_EQ(SymbolSupplier::NOT_FOUND,
- resolver->GetSymbolFile(&module, NULL, &s));
-}
-
-class GetHelper {
- public:
- GetHelper() : sequence(1) {}
- bool GenerateGetResponse(char *buffer, size_t buffer_size,
- ssize_t &received) {
- binarystream stream;
- stream << sequence << OK;
- switch(sequence) {
- case 1:
- // return full info
- stream << string("test()") << u_int64_t(0x1000) << string("test.c")
- << u_int32_t(1) << u_int64_t(0x1010);
- break;
- case 2:
- // return full info
- stream << string("test2()") << u_int64_t(0x2000) << string("test2.c")
- << u_int32_t(2) << u_int64_t(0x2020);
- break;
- case 3:
- // return just function name
- stream << string("test3()") << u_int64_t(0x4000) << string("")
- << u_int32_t(0) << u_int64_t(0);
- break;
- }
- string s = stream.str();
- received = s.length();
- memcpy(buffer, s.c_str(), s.length());
- ++sequence;
- return true;
- }
- u_int16_t sequence;
-};
-
-TEST_F(TestNetworkSourceLineResolver, TestGetMessages) {
- EXPECT_CALL(net, Send(_,_))
- .Times(4)
- .WillRepeatedly(Return(true));
- EXPECT_CALL(net, WaitToReceive(0))
- .Times(4)
- .WillRepeatedly(Return(true));
- GetHelper helper;
- EXPECT_CALL(net, Receive(_,_,_))
- .Times(4)
- .WillOnce(Invoke(GeneratePositiveHasResponse))
- .WillRepeatedly(Invoke(&helper, &GetHelper::GenerateGetResponse));
- BasicCodeModule module(0x0, 0x0, "test.dll", "test.pdb", "ABCD", "", "");
- // The resolver has to think the module is loaded before it will respond
- // to GET requests for that module.
- EXPECT_TRUE(resolver->HasModule(&module));
- StackFrame frame;
- frame.module = &module;
- frame.instruction = 0x1010;
- resolver->FillSourceLineInfo(&frame);
- EXPECT_EQ("test()", frame.function_name);
- EXPECT_EQ(0x1000, frame.function_base);
- EXPECT_EQ("test.c", frame.source_file_name);
- EXPECT_EQ(1, frame.source_line);
- EXPECT_EQ(0x1010, frame.source_line_base);
-
- StackFrame frame2;
- frame2.module = &module;
- frame2.instruction = 0x2020;
- resolver->FillSourceLineInfo(&frame2);
- EXPECT_EQ("test2()", frame2.function_name);
- EXPECT_EQ(0x2000, frame2.function_base);
- EXPECT_EQ("test2.c", frame2.source_file_name);
- EXPECT_EQ(2, frame2.source_line);
- EXPECT_EQ(0x2020, frame2.source_line_base);
-
- StackFrame frame3;
- frame3.module = &module;
- frame3.instruction = 0x4040;
- resolver->FillSourceLineInfo(&frame3);
- EXPECT_EQ("test3()", frame3.function_name);
- EXPECT_EQ(0x4000, frame3.function_base);
- EXPECT_EQ("", frame3.source_file_name);
- EXPECT_EQ(0, frame3.source_line);
- EXPECT_EQ(0, frame3.source_line_base);
-
- // this should come from the cache and not hit the network
- StackFrame frame4;
- frame4.module = &module;
- frame4.instruction = 0x1010;
- resolver->FillSourceLineInfo(&frame4);
- EXPECT_EQ("test()", frame4.function_name);
- EXPECT_EQ(0x1000, frame4.function_base);
- EXPECT_EQ("test.c", frame4.source_file_name);
- EXPECT_EQ(1, frame4.source_line);
- EXPECT_EQ(0x1010, frame4.source_line_base);
-
- // this should also be cached
- StackFrame frame5;
- frame5.module = &module;
- frame5.instruction = 0x4040;
- resolver->FillSourceLineInfo(&frame5);
- EXPECT_EQ("test3()", frame5.function_name);
- EXPECT_EQ(0x4000, frame5.function_base);
- EXPECT_EQ("", frame5.source_file_name);
- EXPECT_EQ(0, frame5.source_line);
- EXPECT_EQ(0, frame5.source_line_base);
-}
-
-class GetStackWinHelper {
- public:
- GetStackWinHelper() : sequence(1) {}
- bool GenerateGetStackWinResponse(char *buffer, size_t buffer_size,
- ssize_t &received) {
- binarystream stream;
- stream << sequence << OK;
- switch(sequence) {
- case 1:
- // return full info including program string
- stream << string("0 0 0 1 2 3 a ff f00 1 x y =");
- break;
- case 2:
- // return full info, no program string
- stream << string("0 0 0 1 2 3 a ff f00 0 1");
- break;
- case 3:
- // return empty string
- stream << string("");
- break;
- }
- string s = stream.str();
- received = s.length();
- memcpy(buffer, s.c_str(), s.length());
- ++sequence;
- return true;
- }
- u_int16_t sequence;
-};
-
-TEST_F(TestNetworkSourceLineResolver, TestGetStackWinMessages) {
- EXPECT_CALL(net, Send(_,_))
- .Times(4)
- .WillRepeatedly(Return(true));
- EXPECT_CALL(net, WaitToReceive(0))
- .Times(4)
- .WillRepeatedly(Return(true));
- GetStackWinHelper helper;
- EXPECT_CALL(net, Receive(_,_,_))
- .Times(4)
- .WillOnce(Invoke(GeneratePositiveHasResponse))
- .WillRepeatedly(Invoke(&helper,
- &GetStackWinHelper::GenerateGetStackWinResponse));
-
- BasicCodeModule module(0x0, 0x0, "test.dll", "test.pdb", "ABCD", "", "");
- // The resolver has to think the module is loaded before it will respond
- // to GETSTACKWIN requests for that module.
- EXPECT_TRUE(resolver->HasModule(&module));
- StackFrame frame;
- frame.module = &module;
- frame.instruction = 0x1010;
- WindowsFrameInfo *info = resolver->FindWindowsFrameInfo(&frame);
- ASSERT_NE((WindowsFrameInfo*)NULL, info);
- EXPECT_EQ(0x1, info->prolog_size);
- EXPECT_EQ(0x2, info->epilog_size);
- EXPECT_EQ(0x3, info->parameter_size);
- EXPECT_EQ(0xa, info->saved_register_size);
- EXPECT_EQ(0xff, info->local_size);
- EXPECT_EQ(0xf00, info->max_stack_size);
- EXPECT_EQ("x y =", info->program_string);
- delete info;
-
- StackFrame frame2;
- frame2.module = &module;
- frame2.instruction = 0x2020;
- info = resolver->FindWindowsFrameInfo(&frame2);
- ASSERT_NE((WindowsFrameInfo*)NULL, info);
- EXPECT_EQ(0x1, info->prolog_size);
- EXPECT_EQ(0x2, info->epilog_size);
- EXPECT_EQ(0x3, info->parameter_size);
- EXPECT_EQ(0xa, info->saved_register_size);
- EXPECT_EQ(0xff, info->local_size);
- EXPECT_EQ(0xf00, info->max_stack_size);
- EXPECT_EQ("", info->program_string);
- EXPECT_EQ(true, info->allocates_base_pointer);
- delete info;
-
- StackFrame frame3;
- frame3.module = &module;
- frame3.instruction = 0x4040;
- info = resolver->FindWindowsFrameInfo(&frame3);
- EXPECT_EQ((WindowsFrameInfo*)NULL, info);
-
- // this should come from the cache and not hit the network
- StackFrame frame4;
- frame4.module = &module;
- frame4.instruction = 0x1010;
- info = resolver->FindWindowsFrameInfo(&frame4);
- ASSERT_NE((WindowsFrameInfo*)NULL, info);
- EXPECT_EQ(0x1, info->prolog_size);
- EXPECT_EQ(0x2, info->epilog_size);
- EXPECT_EQ(0x3, info->parameter_size);
- EXPECT_EQ(0xa, info->saved_register_size);
- EXPECT_EQ(0xff, info->local_size);
- EXPECT_EQ(0xf00, info->max_stack_size);
- EXPECT_EQ("x y =", info->program_string);
- delete info;
-
- // this should also be cached
- StackFrame frame5;
- frame5.module = &module;
- frame5.instruction = 0x4040;
- info = resolver->FindWindowsFrameInfo(&frame5);
- EXPECT_EQ((WindowsFrameInfo*)NULL, info);
-}
-
-class GetStackCFIHelper {
- public:
- GetStackCFIHelper() : sequence(1) {}
- bool GenerateGetStackCFIResponse(char *buffer, size_t buffer_size,
- ssize_t &received) {
- binarystream stream;
- stream << sequence << OK;
- switch(sequence) {
- case 1:
- // return .cfa, .ra, registers
- stream << string(".cfa: 1234 .ra: .cfa 5 + r0: abc xyz r2: 10 10");
- break;
- case 2:
- // return just .cfa
- stream << string(".cfa: xyz");
- break;
- case 3:
- // return empty string
- stream << string("");
- break;
- }
- string s = stream.str();
- received = s.length();
- memcpy(buffer, s.c_str(), s.length());
- ++sequence;
- return true;
- }
- u_int16_t sequence;
-};
-
-TEST_F(TestNetworkSourceLineResolver, TestGetStackCFIMessages) {
- EXPECT_CALL(net, Send(_,_))
- .Times(4)
- .WillRepeatedly(Return(true));
- EXPECT_CALL(net, WaitToReceive(0))
- .Times(4)
- .WillRepeatedly(Return(true));
- GetStackCFIHelper helper;
- EXPECT_CALL(net, Receive(_,_,_))
- .Times(4)
- .WillOnce(Invoke(GeneratePositiveHasResponse))
- .WillRepeatedly(Invoke(&helper,
- &GetStackCFIHelper::GenerateGetStackCFIResponse));
-
- BasicCodeModule module(0x0, 0x0, "test.dll", "test.pdb", "ABCD", "", "");
- // The resolver has to think the module is loaded before it will respond
- // to GETSTACKCFI requests for that module.
- EXPECT_TRUE(resolver->HasModule(&module));
- StackFrame frame;
- frame.module = &module;
- frame.instruction = 0x1010;
- CFIFrameInfo *info = resolver->FindCFIFrameInfo(&frame);
- ASSERT_NE((CFIFrameInfo*)NULL, info);
- // Ostensibly we would check the internal data structure, but
- // we'd have to either mock out some other classes or get internal access,
- // so this is easier.
- EXPECT_EQ(".cfa: 1234 .ra: .cfa 5 + r0: abc xyz r2: 10 10",
- info->Serialize());
- delete info;
-
- StackFrame frame2;
- frame2.module = &module;
- frame2.instruction = 0x2020;
- info = resolver->FindCFIFrameInfo(&frame2);
- ASSERT_NE((CFIFrameInfo*)NULL, info);
- EXPECT_EQ(".cfa: xyz", info->Serialize());
- delete info;
-
- StackFrame frame3;
- frame3.module = &module;
- frame3.instruction = 0x4040;
- info = resolver->FindCFIFrameInfo(&frame3);
- EXPECT_EQ((CFIFrameInfo*)NULL, info);
-
- // this should come from the cache and not hit the network
- StackFrame frame4;
- frame4.module = &module;
- frame4.instruction = 0x1010;
- info = resolver->FindCFIFrameInfo(&frame4);
- ASSERT_NE((CFIFrameInfo*)NULL, info);
- EXPECT_EQ(".cfa: 1234 .ra: .cfa 5 + r0: abc xyz r2: 10 10",
- info->Serialize());
- delete info;
-
- // this should also be cached
- StackFrame frame5;
- frame5.module = &module;
- frame5.instruction = 0x4040;
- info = resolver->FindCFIFrameInfo(&frame5);
- EXPECT_EQ((CFIFrameInfo*)NULL, info);
-}
-
-TEST_F(TestNetworkSourceLineResolver, TestBogusData) {
- EXPECT_FALSE(resolver->HasModule(NULL));
-
- StackFrame frame;
- frame.module = NULL;
- frame.instruction = 0x1000;
- resolver->FillSourceLineInfo(&frame);
- EXPECT_EQ("", frame.function_name);
- EXPECT_EQ(0x0, frame.function_base);
- EXPECT_EQ("", frame.source_file_name);
- EXPECT_EQ(0, frame.source_line);
- EXPECT_EQ(0x0, frame.source_line_base);
-
- EXPECT_EQ((WindowsFrameInfo*)NULL, resolver->FindWindowsFrameInfo(&frame));
-}
-
-} // namespace
-
-int main(int argc, char *argv[]) {
- ::testing::InitGoogleTest(&argc, argv);
- return RUN_ALL_TESTS();
-}