aboutsummaryrefslogtreecommitdiff
path: root/src/processor/network_source_line_server_unittest.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/processor/network_source_line_server_unittest.cc')
-rw-r--r--src/processor/network_source_line_server_unittest.cc963
1 files changed, 0 insertions, 963 deletions
diff --git a/src/processor/network_source_line_server_unittest.cc b/src/processor/network_source_line_server_unittest.cc
deleted file mode 100644
index c45f19cc..00000000
--- a/src/processor/network_source_line_server_unittest.cc
+++ /dev/null
@@ -1,963 +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 NetworkSourceLineServer.
-
-#include <ios>
-#include <set>
-#include <string>
-
-#include "breakpad_googletest_includes.h"
-#include "google_breakpad/processor/code_module.h"
-#include "google_breakpad/processor/source_line_resolver_interface.h"
-#include "google_breakpad/processor/stack_frame.h"
-#include "google_breakpad/processor/symbol_supplier.h"
-#include "processor/binarystream.h"
-#include "processor/cfi_frame_info.h"
-#include "processor/network_source_line_server.h"
-#include "processor/network_source_line_protocol.h"
-#include "processor/windows_frame_info.h"
-
-namespace {
-using std::ios_base;
-using std::set;
-using std::string;
-using google_breakpad::CFIFrameInfo;
-using google_breakpad::CodeModule;
-using google_breakpad::binarystream;
-using google_breakpad::NetworkInterface;
-using google_breakpad::NetworkSourceLineServer;
-using google_breakpad::SourceLineResolverInterface;
-using google_breakpad::StackFrame;
-using google_breakpad::SymbolSupplier;
-using google_breakpad::SystemInfo;
-using google_breakpad::WindowsFrameInfo;
-using ::testing::_;
-using ::testing::DoAll;
-using ::testing::Invoke;
-using ::testing::Property;
-using ::testing::Return;
-using ::testing::SetArgumentPointee;
-// Style guide forbids "using namespace", so at least shorten it.
-namespace P = google_breakpad::source_line_protocol;
-
-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));
-};
-
-class MockSymbolSupplier : public SymbolSupplier {
-public:
- MockSymbolSupplier() {}
-
- MOCK_METHOD3(GetSymbolFile, SymbolResult(const CodeModule *module,
- const SystemInfo *system_info,
- string *symbol_file));
- MOCK_METHOD4(GetSymbolFile, SymbolResult(const CodeModule *module,
- const SystemInfo *system_info,
- string *symbol_file,
- string *symbol_data));
- MOCK_METHOD4(GetCStringSymbolData, SymbolResult(const CodeModule *module,
- const SystemInfo *system_info,
- string *symbol_file,
- char **symbol_data));
- MOCK_METHOD1(FreeSymbolData, void(const CodeModule *module));
-};
-
-class MockSourceLineResolver : public SourceLineResolverInterface {
- public:
- MockSourceLineResolver() {}
- virtual ~MockSourceLineResolver() {}
-
- MOCK_METHOD2(LoadModule, bool(const CodeModule *module,
- const string &map_file));
- MOCK_METHOD2(LoadModuleUsingMapBuffer, bool(const CodeModule *module,
- const string &map_buffer));
- MOCK_METHOD2(LoadModuleUsingMemoryBuffer, bool(const CodeModule *module,
- char *memory_buffer));
- MOCK_METHOD0(ShouldDeleteMemoryBufferAfterLoadModule, bool());
- MOCK_METHOD1(UnloadModule, void(const CodeModule *module));
- MOCK_METHOD1(HasModule, bool(const CodeModule *module));
- MOCK_METHOD1(FillSourceLineInfo, void(StackFrame *frame));
- MOCK_METHOD1(FindWindowsFrameInfo,
- WindowsFrameInfo*(const StackFrame *frame));
- MOCK_METHOD1(FindCFIFrameInfo,
- CFIFrameInfo*(const StackFrame *frame));
-};
-
-class TestNetworkSourceLineServer : public NetworkSourceLineServer {
- public:
- // Override visibility for testing. It's a lot easier to just
- // call into this method and verify the result than it would be
- // to mock out the calls to the NetworkInterface, even though
- // that would ostensibly be more correct and test the code more
- // thoroughly. Perhaps if someone has time and figures out a
- // clean way to do it this could be changed.
- using NetworkSourceLineServer::HandleRequest;
-
- TestNetworkSourceLineServer(SymbolSupplier *supplier,
- SourceLineResolverInterface *resolver,
- NetworkInterface *net,
- u_int64_t max_symbol_lines = 0)
- : NetworkSourceLineServer(supplier, resolver, net, max_symbol_lines)
-
- {}
-};
-
-class NetworkSourceLineServerTest : public ::testing::Test {
- public:
- MockSymbolSupplier supplier;
- MockSourceLineResolver resolver;
- MockNetwork net;
- TestNetworkSourceLineServer *server;
-
- NetworkSourceLineServerTest() : server(NULL) {}
-
- void SetUp() {
- server = new TestNetworkSourceLineServer(&supplier, &resolver, &net);
- }
-};
-
-TEST_F(NetworkSourceLineServerTest, TestInit) {
- EXPECT_CALL(net, Init(true)).WillOnce(Return(true));
- EXPECT_CALL(net, WaitToReceive(0)).WillOnce(Return(false));
- ASSERT_TRUE(server->Initialize());
- EXPECT_FALSE(server->RunOnce(0));
-}
-
-TEST_F(NetworkSourceLineServerTest, TestMalformedRequest) {
- binarystream request;
- // send a request without a full sequence number
- request << u_int8_t(1);
- binarystream response;
- EXPECT_FALSE(server->HandleRequest(request, response));
- request.rewind();
- // send a request without a command
- request << u_int16_t(1);
- EXPECT_FALSE(server->HandleRequest(request, response));
-}
-
-TEST_F(NetworkSourceLineServerTest, TestUnknownCommand) {
- binarystream request;
- // send a request with an unknown command
- request << u_int16_t(1) << u_int8_t(100);
- binarystream response;
- ASSERT_TRUE(server->HandleRequest(request, response));
- u_int16_t response_sequence;
- u_int8_t response_status;
- response >> response_sequence >> response_status;
- ASSERT_FALSE(response.eof());
- EXPECT_EQ(u_int16_t(1), response_sequence);
- EXPECT_EQ(P::ERROR, int(response_status));
-}
-
-TEST_F(NetworkSourceLineServerTest, TestHasBasic) {
- EXPECT_CALL(resolver, HasModule(_))
- .WillOnce(Return(false))
- .WillOnce(Return(true));
-
- binarystream request;
- const u_int16_t sequence = 0xA0A0;
- // first request should come back as not loaded
- request << sequence << P::HAS << string("test.dll") << string("test.pdb")
- << string("ABCD1234");
- binarystream response;
- ASSERT_TRUE(server->HandleRequest(request, response));
- u_int16_t response_sequence;
- u_int8_t response_status, response_data;
- response >> response_sequence >> response_status >> response_data;
- ASSERT_FALSE(response.eof());
- EXPECT_EQ(sequence, response_sequence);
- EXPECT_EQ(P::OK, int(response_status));
- EXPECT_EQ(P::MODULE_NOT_LOADED, int(response_data));
- // second request should come back as loaded
- binarystream request2;
- request2 << sequence << P::HAS << string("loaded.dll") << string("loaded.pdb")
- << string("ABCD1234");
- ASSERT_TRUE(server->HandleRequest(request2, response));
- response >> response_sequence >> response_status >> response_data;
- ASSERT_FALSE(response.eof());
- EXPECT_EQ(sequence, response_sequence);
- EXPECT_EQ(P::OK, int(response_status));
- EXPECT_EQ(P::MODULE_LOADED, int(response_data));
-}
-
-TEST_F(NetworkSourceLineServerTest, TestMalformedHasRequest) {
- binarystream request;
- // send request with just command, missing all data
- const u_int16_t sequence = 0xA0A0;
- request << sequence << P::HAS;
- binarystream response;
- ASSERT_TRUE(server->HandleRequest(request, response));
- u_int16_t response_sequence;
- u_int8_t response_status;
- response >> response_sequence >> response_status;
- ASSERT_FALSE(response.eof());
- EXPECT_EQ(sequence, response_sequence);
- EXPECT_EQ(P::ERROR, int(response_status));
- // send request with just module name
- binarystream request2;
- request2 << sequence << P::HAS << string("test.dll");
- ASSERT_TRUE(server->HandleRequest(request2, response));
- response >> response_sequence >> response_status;
- ASSERT_FALSE(response.eof());
- EXPECT_EQ(sequence, response_sequence);
- EXPECT_EQ(P::ERROR, int(response_status));
- // send request with module name, debug file, missing debug id
- binarystream request3;
- request3 << sequence << P::HAS << string("test.dll") << string("test.pdb");
- ASSERT_TRUE(server->HandleRequest(request3, response));
- response >> response_sequence >> response_status;
- ASSERT_FALSE(response.eof());
- EXPECT_EQ(sequence, response_sequence);
- EXPECT_EQ(P::ERROR, int(response_status));
-}
-
-TEST_F(NetworkSourceLineServerTest, TestHasLoad) {
- EXPECT_CALL(resolver, HasModule(_))
- .WillOnce(Return(false))
- .WillOnce(Return(false))
- .WillOnce(Return(true));
- EXPECT_CALL(resolver, LoadModuleUsingMapBuffer(_,_))
- .WillOnce(Return(true));
- EXPECT_CALL(supplier, GetSymbolFile(_,_,_,_))
- .WillOnce(Return(SymbolSupplier::FOUND));
-
- // verify that the module is not loaded, with a HAS request
- binarystream request;
- const u_int16_t sequence = 0xA0A0;
- request << sequence << P::HAS << string("found.dll") << string("found.pdb")
- << string("ABCD1234");
- binarystream response;
- ASSERT_TRUE(server->HandleRequest(request, response));
- u_int16_t response_sequence;
- u_int8_t response_status, response_data;
- response >> response_sequence >> response_status >> response_data;
- ASSERT_FALSE(response.eof());
- EXPECT_EQ(sequence, response_sequence);
- EXPECT_EQ(P::OK, int(response_status));
- ASSERT_EQ(P::MODULE_NOT_LOADED, int(response_data));
- // now send a load request for this module
- binarystream request2;
- const u_int16_t sequence2 = 0xB0B0;
- request2 << sequence2 << P::LOAD << string("found.dll") << string("found.pdb")
- << string("ABCD1234");
- ASSERT_TRUE(server->HandleRequest(request2, response));
- response >> response_sequence >> response_status >> response_data;
- ASSERT_FALSE(response.eof());
- EXPECT_EQ(sequence2, response_sequence);
- EXPECT_EQ(P::OK, int(response_status));
- ASSERT_EQ(int(P::LOAD_OK), int(response_data));
- // sending another HAS message should now show it as loaded
- binarystream request3;
- const u_int16_t sequence3 = 0xC0C0;
- request3 << sequence3 << P::HAS << string("found.dll") << string("found.pdb")
- << string("ABCD1234");
- ASSERT_TRUE(server->HandleRequest(request3, response));
- response >> response_sequence >> response_status >> response_data;
- ASSERT_FALSE(response.eof());
- EXPECT_EQ(sequence3, response_sequence);
- EXPECT_EQ(P::OK, int(response_status));
- EXPECT_EQ(P::MODULE_LOADED, int(response_data));
-}
-
-TEST_F(NetworkSourceLineServerTest, TestLoad) {
- EXPECT_CALL(resolver, HasModule(_))
- .Times(3)
- .WillRepeatedly(Return(false));
- EXPECT_CALL(resolver, LoadModuleUsingMapBuffer(_,_))
- .WillOnce(Return(false));
- EXPECT_CALL(supplier, GetSymbolFile(_,_,_,_))
- .WillOnce(Return(SymbolSupplier::NOT_FOUND))
- .WillOnce(Return(SymbolSupplier::INTERRUPT))
- .WillOnce(Return(SymbolSupplier::FOUND));
-
- // notfound.dll should return LOAD_NOT_FOUND
- binarystream request;
- const u_int16_t sequence = 0xA0A0;
- request << sequence << P::LOAD << string("notfound.dll")
- << string("notfound.pdb") << string("ABCD1234");
- binarystream response;
- ASSERT_TRUE(server->HandleRequest(request, response));
- u_int16_t response_sequence;
- u_int8_t response_status, response_data;
- response >> response_sequence >> response_status >> response_data;
- ASSERT_FALSE(response.eof());
- EXPECT_EQ(sequence, response_sequence);
- EXPECT_EQ(P::OK, int(response_status));
- EXPECT_EQ(int(P::LOAD_NOT_FOUND), int(response_data));
- // interrupt.dll should return LOAD_INTERRUPT
- binarystream request2;
- const u_int16_t sequence2 = 0xB0B0;
- request2 << sequence2 << P::LOAD << string("interrupt.dll")
- << string("interrupt.pdb") << string("0000");
- ASSERT_TRUE(server->HandleRequest(request2, response));
- response >> response_sequence >> response_status >> response_data;
- ASSERT_FALSE(response.eof());
- EXPECT_EQ(sequence2, response_sequence);
- EXPECT_EQ(P::OK, int(response_status));
- EXPECT_EQ(int(P::LOAD_INTERRUPT), int(response_data));
- // fail.dll should return LOAD_FAIL
- binarystream request3;
- const u_int16_t sequence3 = 0xC0C0;
- request3 << sequence3 << P::LOAD << string("fail.dll") << string("fail.pdb")
- << string("FFFFFFFF");
- ASSERT_TRUE(server->HandleRequest(request3, response));
- response >> response_sequence >> response_status >> response_data;
- ASSERT_FALSE(response.eof());
- EXPECT_EQ(sequence3, response_sequence);
- EXPECT_EQ(P::OK, int(response_status));
- EXPECT_EQ(int(P::LOAD_FAIL), int(response_data));
-}
-
-TEST_F(NetworkSourceLineServerTest, TestMalformedLoadRequest) {
- binarystream request;
- // send request with just command, missing all data
- const u_int16_t sequence = 0xA0A0;
- request << sequence << P::LOAD;
- binarystream response;
- ASSERT_TRUE(server->HandleRequest(request, response));
- u_int16_t response_sequence;
- u_int8_t response_status;
- response >> response_sequence >> response_status;
- ASSERT_FALSE(response.eof());
- EXPECT_EQ(sequence, response_sequence);
- EXPECT_EQ(P::ERROR, int(response_status));
- // send request with just module name
- binarystream request2;
- request2 << sequence << P::LOAD << string("test.dll");
- ASSERT_TRUE(server->HandleRequest(request2, response));
- response >> response_sequence >> response_status;
- ASSERT_FALSE(response.eof());
- EXPECT_EQ(sequence, response_sequence);
- EXPECT_EQ(P::ERROR, int(response_status));
- // send request with module name, debug file, missing debug id
- binarystream request3;
- request3 << sequence << P::LOAD << string("test.dll") << string("test.pdb");
- ASSERT_TRUE(server->HandleRequest(request3, response));
- response >> response_sequence >> response_status;
- ASSERT_FALSE(response.eof());
- EXPECT_EQ(sequence, response_sequence);
- EXPECT_EQ(P::ERROR, int(response_status));
-}
-
-void FillFullSourceLineInfo(StackFrame *frame) {
- frame->function_name = "function1";
- frame->function_base = 0x1200;
- frame->source_file_name = "function1.cc";
- frame->source_line = 1;
- frame->source_line_base = 0x1230;
-}
-
-void FillPartialSourceLineInfo(StackFrame *frame) {
- frame->function_name = "function2";
- frame->function_base = 0xFFF0;
-}
-
-TEST_F(NetworkSourceLineServerTest, TestGet) {
- EXPECT_CALL(resolver, FillSourceLineInfo(_))
- .WillOnce(Invoke(FillFullSourceLineInfo))
- .WillOnce(Invoke(FillPartialSourceLineInfo));
-
- binarystream request;
- const u_int16_t sequence = 0xA0A0;
- request << sequence << P::GET << string("loaded.dll")
- << string("loaded.pdb") << string("ABCD1234")
- << u_int64_t(0x1000) << u_int64_t(0x1234);
- binarystream response;
- ASSERT_TRUE(server->HandleRequest(request, response));
- u_int16_t response_sequence;
- u_int8_t response_status;
- string function, source_file;
- u_int32_t source_line;
- u_int64_t function_base, source_line_base;
- response >> response_sequence >> response_status >> function
- >> function_base >> source_file >> source_line >> source_line_base;
- ASSERT_FALSE(response.eof());
- EXPECT_EQ(sequence, response_sequence);
- EXPECT_EQ(P::OK, int(response_status));
- EXPECT_EQ("function1", function);
- EXPECT_EQ(0x1200, function_base);
- EXPECT_EQ("function1.cc", source_file);
- EXPECT_EQ(1, source_line);
- EXPECT_EQ(0x1230, source_line_base);
-
- binarystream request2;
- const u_int16_t sequence2 = 0xC0C0;
- request2 << sequence2 << P::GET << string("loaded.dll")
- << string("loaded.pdb") << string("ABCD1234")
- << u_int64_t(0x1000) << u_int64_t(0xFFFF);
- ASSERT_TRUE(server->HandleRequest(request2, response));
- response >> response_sequence >> response_status >> function
- >> function_base >> source_file >> source_line >> source_line_base;
- ASSERT_FALSE(response.eof());
- EXPECT_EQ(sequence2, response_sequence);
- EXPECT_EQ(P::OK, int(response_status));
- EXPECT_EQ("function2", function);
- EXPECT_EQ(0xFFF0, function_base);
- EXPECT_EQ("", source_file);
- EXPECT_EQ(0, source_line);
- EXPECT_EQ(0, source_line_base);
-}
-
-WindowsFrameInfo* GetFullWindowsFrameInfo(const StackFrame *frame) {
- // return frame info with program string
- return new WindowsFrameInfo(1, 2, 3, 0xA, 0xFF, 0xF00,
- true,
- "x y =");
-}
-
-WindowsFrameInfo* GetPartialWindowsFrameInfo(const StackFrame *frame) {
- // return frame info, no program string
- return new WindowsFrameInfo(1, 2, 3, 4, 5, 6, true, "");
-}
-
-TEST_F(NetworkSourceLineServerTest, TestGetStackWin) {
- EXPECT_CALL(resolver, FindWindowsFrameInfo(_))
- .WillOnce(Invoke(GetFullWindowsFrameInfo))
- .WillOnce(Invoke(GetPartialWindowsFrameInfo))
- .WillOnce(Return((WindowsFrameInfo*)NULL));
-
- binarystream request;
- const u_int16_t sequence = 0xA0A0;
- request << sequence << P::GETSTACKWIN << string("loaded.dll")
- << string("loaded.pdb") << string("ABCD1234")
- << u_int64_t(0x1000) << u_int64_t(0x1234);
- binarystream response;
- ASSERT_TRUE(server->HandleRequest(request, response));
- u_int16_t response_sequence;
- u_int8_t response_status;
- string stack_info;
- response >> response_sequence >> response_status
- >> stack_info;
- ASSERT_FALSE(response.eof());
- EXPECT_EQ(sequence, response_sequence);
- EXPECT_EQ(P::OK, int(response_status));
- EXPECT_EQ("0 0 0 1 2 3 a ff f00 1 x y =", stack_info);
-
- binarystream request2;
- const u_int16_t sequence2 = 0xB0B0;
- request2 << sequence2 << P::GETSTACKWIN << string("loaded.dll")
- << string("loaded.pdb") << string("ABCD1234")
- << u_int64_t(0x1000) << u_int64_t(0xABCD);
- ASSERT_TRUE(server->HandleRequest(request2, response));
- response >> response_sequence >> response_status
- >> stack_info;
- ASSERT_FALSE(response.eof());
- EXPECT_EQ(sequence2, response_sequence);
- EXPECT_EQ(P::OK, int(response_status));
- EXPECT_EQ("0 0 0 1 2 3 4 5 6 0 1", stack_info);
-
- binarystream request3;
- const u_int16_t sequence3 = 0xC0C0;
- request3 << sequence3 << P::GETSTACKWIN << string("loaded.dll")
- << string("loaded.pdb") << string("ABCD1234")
- << u_int64_t(0x1000) << u_int64_t(0xFFFF);
- ASSERT_TRUE(server->HandleRequest(request3, response));
- response >> response_sequence >> response_status
- >> stack_info;
- ASSERT_FALSE(response.eof());
- EXPECT_EQ(sequence3, response_sequence);
- EXPECT_EQ(P::OK, int(response_status));
- EXPECT_EQ("", stack_info);
-}
-
-
-CFIFrameInfo* GetCFIFrameInfoJustCFA(const StackFrame *frame) {
- CFIFrameInfo* cfi = new CFIFrameInfo();
- cfi->SetCFARule("12345678");
- return cfi;
-}
-
-CFIFrameInfo* GetCFIFrameInfoCFARA(const StackFrame *frame) {
- CFIFrameInfo* cfi = new CFIFrameInfo();
- cfi->SetCFARule("12345678");
- cfi->SetRARule("abcdefgh");
- return cfi;
-}
-
-CFIFrameInfo* GetCFIFrameInfoLots(const StackFrame *frame) {
- CFIFrameInfo* cfi = new CFIFrameInfo();
- cfi->SetCFARule("12345678");
- cfi->SetRARule("abcdefgh");
- cfi->SetRegisterRule("r0", "foo bar");
- cfi->SetRegisterRule("b0", "123 abc +");
- return cfi;
-}
-
-TEST_F(NetworkSourceLineServerTest, TestGetStackCFI) {
- EXPECT_CALL(resolver, FindCFIFrameInfo(_))
- .WillOnce(Return((CFIFrameInfo*)NULL))
- .WillOnce(Invoke(GetCFIFrameInfoJustCFA))
- .WillOnce(Invoke(GetCFIFrameInfoCFARA))
- .WillOnce(Invoke(GetCFIFrameInfoLots));
-
- binarystream request;
- const u_int16_t sequence = 0xA0A0;
- request << sequence << P::GETSTACKCFI << string("loaded.dll")
- << string("loaded.pdb") << string("ABCD1234")
- << u_int64_t(0x1000) << u_int64_t(0x1234);
- binarystream response;
- ASSERT_TRUE(server->HandleRequest(request, response));
- u_int16_t response_sequence;
- u_int8_t response_status;
- string stack_info;
- response >> response_sequence >> response_status
- >> stack_info;
- ASSERT_FALSE(response.eof());
- EXPECT_EQ(sequence, response_sequence);
- EXPECT_EQ(P::OK, int(response_status));
- EXPECT_EQ("", stack_info);
-
- binarystream request2;
- const u_int16_t sequence2 = 0xB0B0;
- request2 << sequence2 << P::GETSTACKCFI << string("loaded.dll")
- << string("loaded.pdb") << string("ABCD1234")
- << u_int64_t(0x1000) << u_int64_t(0xABCD);
- ASSERT_TRUE(server->HandleRequest(request2, response));
- response >> response_sequence >> response_status
- >> stack_info;
- ASSERT_FALSE(response.eof());
- EXPECT_EQ(sequence2, response_sequence);
- EXPECT_EQ(P::OK, int(response_status));
- EXPECT_EQ(".cfa: 12345678", stack_info);
-
- binarystream request3;
- const u_int16_t sequence3 = 0xC0C0;
- request3 << sequence3 << P::GETSTACKCFI << string("loaded.dll")
- << string("loaded.pdb") << string("ABCD1234")
- << u_int64_t(0x1000) << u_int64_t(0xFFFF);
- ASSERT_TRUE(server->HandleRequest(request3, response));
- response >> response_sequence >> response_status
- >> stack_info;
- ASSERT_FALSE(response.eof());
- EXPECT_EQ(sequence3, response_sequence);
- EXPECT_EQ(P::OK, int(response_status));
- EXPECT_EQ(".cfa: 12345678 .ra: abcdefgh", stack_info);
-
- binarystream request4;
- const u_int16_t sequence4 = 0xD0D0;
- request4 << sequence4 << P::GETSTACKCFI << string("loaded.dll")
- << string("loaded.pdb") << string("ABCD1234")
- << u_int64_t(0x1000) << u_int64_t(0xFFFF);
- ASSERT_TRUE(server->HandleRequest(request4, response));
- response >> response_sequence >> response_status
- >> stack_info;
- ASSERT_FALSE(response.eof());
- EXPECT_EQ(sequence4, response_sequence);
- EXPECT_EQ(P::OK, int(response_status));
- EXPECT_EQ(".cfa: 12345678 .ra: abcdefgh b0: 123 abc + r0: foo bar",
- stack_info);
-}
-
-TEST_F(NetworkSourceLineServerTest, TestMalformedGetRequest) {
- //TODO
-}
-
-TEST(TestMissingMembers, TestServerWithoutSymbolSupplier) {
- // Should provide reasonable responses without a SymbolSupplier
- MockSourceLineResolver resolver;
- MockNetwork net;
- TestNetworkSourceLineServer server(NULL, &resolver, &net);
-
- // All LOAD requests should return LOAD_NOT_FOUND
- binarystream request;
- binarystream response;
- const u_int16_t sequence = 0xB0B0;
- u_int16_t response_sequence;
- u_int8_t response_status, response_data;
- request << sequence << P::LOAD << string("found.dll") << string("found.pdb")
- << string("ABCD1234");
- ASSERT_TRUE(server.HandleRequest(request, response));
- response >> response_sequence >> response_status >> response_data;
- ASSERT_FALSE(response.eof());
- EXPECT_EQ(sequence, response_sequence);
- EXPECT_EQ(P::OK, int(response_status));
- ASSERT_EQ(int(P::LOAD_NOT_FOUND), int(response_data));
-}
-
-TEST(TestMissingMembers, TestServerWithoutResolver) {
- // Should provide reasonable responses without a SourceLineResolver
- MockSymbolSupplier supplier;
- MockNetwork net;
- TestNetworkSourceLineServer server(&supplier, NULL, &net);
-
- // GET requests should return empty info
- binarystream request;
- binarystream response;
- const u_int16_t sequence = 0xA0A0;
- u_int16_t response_sequence;
- u_int8_t response_status;
- request << sequence << P::GET << string("loaded.dll")
- << string("loaded.pdb") << string("ABCD1234")
- << u_int64_t(0x1000) << u_int64_t(0x1234);
- ASSERT_TRUE(server.HandleRequest(request, response));
- string function, source_file;
- u_int32_t source_line;
- u_int64_t function_base, source_line_base;
- response >> response_sequence >> response_status >> function
- >> function_base >> source_file >> source_line >> source_line_base;
- ASSERT_FALSE(response.eof());
- EXPECT_EQ(sequence, response_sequence);
- EXPECT_EQ(P::OK, int(response_status));
- EXPECT_EQ("", function);
- EXPECT_EQ(0x0, function_base);
- EXPECT_EQ("", source_file);
- EXPECT_EQ(0, source_line);
- EXPECT_EQ(0x0, source_line_base);
-
- // GETSTACKWIN requests should return an empty string
- binarystream request2;
- const u_int16_t sequence2 = 0xB0B0;
- request << sequence2 << P::GETSTACKWIN << string("loaded.dll")
- << string("loaded.pdb") << string("ABCD1234")
- << u_int64_t(0x1000) << u_int64_t(0x1234);
- ASSERT_TRUE(server.HandleRequest(request, response));
- string response_string;
- response >> response_sequence >> response_status >> response_string;
- EXPECT_EQ(sequence2, response_sequence);
- EXPECT_EQ(P::OK, int(response_status));
- EXPECT_EQ("", response_string);
-}
-
-class TestModuleManagement : public ::testing::Test {
-public:
- MockSymbolSupplier supplier;
- MockSourceLineResolver resolver;
- MockNetwork net;
- TestNetworkSourceLineServer server;
-
- // Init server with symbol line limit of 25
- TestModuleManagement() : server(&supplier, &resolver, &net, 25) {}
-};
-
-TEST_F(TestModuleManagement, TestModuleUnloading) {
- EXPECT_CALL(supplier, GetSymbolFile(_,_,_,_))
- .Times(3)
- .WillRepeatedly(DoAll(SetArgumentPointee<3>(string("1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n")),
- Return(SymbolSupplier::FOUND)));
- EXPECT_CALL(resolver, HasModule(_))
- .Times(3)
- .WillRepeatedly(Return(false));
- EXPECT_CALL(resolver, LoadModuleUsingMapBuffer(_,_))
- .Times(3)
- .WillRepeatedly(Return(true));
- EXPECT_CALL(resolver, UnloadModule(Property(&CodeModule::code_file,
- string("one.dll|one.pdb|1111"))))
- .Times(1);
-
- // load three modules, each with 10 lines of symbols.
- // the third module will overflow the server's symbol line limit,
- // and should cause the first module to be unloaded.
- binarystream request;
- const u_int16_t sequence = 0x1010;
- request << sequence << P::LOAD << string("one.dll") << string("one.pdb")
- << string("1111");
- binarystream response;
- ASSERT_TRUE(server.HandleRequest(request, response));
- u_int16_t response_sequence;
- u_int8_t response_status, response_data;
- response >> response_sequence >> response_status >> response_data;
- ASSERT_FALSE(response.eof());
- EXPECT_EQ(sequence, response_sequence);
- EXPECT_EQ(P::OK, int(response_status));
- ASSERT_EQ(int(P::LOAD_OK), int(response_data));
-
- binarystream request2;
- const u_int16_t sequence2 = 0x2020;
- request2 << sequence2 << P::LOAD << string("two.dll") << string("two.pdb")
- << string("2222");
- ASSERT_TRUE(server.HandleRequest(request2, response));
- response >> response_sequence >> response_status >> response_data;
- ASSERT_FALSE(response.eof());
- EXPECT_EQ(sequence2, response_sequence);
- EXPECT_EQ(P::OK, int(response_status));
- ASSERT_EQ(int(P::LOAD_OK), int(response_data));
-
- binarystream request3;
- const u_int16_t sequence3 = 0x3030;
- request3 << sequence3 << P::LOAD << string("three.dll") << string("three.pdb")
- << string("3333");
- ASSERT_TRUE(server.HandleRequest(request3, response));
- response >> response_sequence >> response_status >> response_data;
- ASSERT_FALSE(response.eof());
- EXPECT_EQ(sequence3, response_sequence);
- EXPECT_EQ(P::OK, int(response_status));
- ASSERT_EQ(int(P::LOAD_OK), int(response_data));
-}
-
-TEST_F(TestModuleManagement, TestSymbolLimitTooLow) {
- // load module with symbol count > limit,
- // ensure that it doesn't get unloaded even though it's the only module
- EXPECT_CALL(supplier, GetSymbolFile(_,_,_,_))
- .WillOnce(DoAll(SetArgumentPointee<3>(string("1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n11\n12\n13\n14\n15\n16\n17\n18\n19\n20\n21\n22\n23\n24\n25\n26\n")),
- Return(SymbolSupplier::FOUND)));
- EXPECT_CALL(resolver, HasModule(_))
- .WillOnce(Return(false));
- EXPECT_CALL(resolver, LoadModuleUsingMapBuffer(_,_))
- .WillOnce(Return(true));
- EXPECT_CALL(resolver, UnloadModule(_))
- .Times(0);
-
- binarystream request;
- const u_int16_t sequence = 0x1010;
- request << sequence << P::LOAD << string("one.dll") << string("one.pdb")
- << string("1111");
- binarystream response;
- ASSERT_TRUE(server.HandleRequest(request, response));
- u_int16_t response_sequence;
- u_int8_t response_status, response_data;
- response >> response_sequence >> response_status >> response_data;
- ASSERT_FALSE(response.eof());
- EXPECT_EQ(sequence, response_sequence);
- EXPECT_EQ(P::OK, int(response_status));
- ASSERT_EQ(int(P::LOAD_OK), int(response_data));
-}
-
-TEST_F(TestModuleManagement, TestModuleLoadLRU) {
- // load 2 modules, then re-load the first one,
- // then load a third one, causing the second one to be unloaded
- EXPECT_CALL(supplier, GetSymbolFile(_,_,_,_))
- .Times(3)
- .WillRepeatedly(DoAll(SetArgumentPointee<3>(string("1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n")),
- Return(SymbolSupplier::FOUND)));
- EXPECT_CALL(resolver, HasModule(_))
- .WillOnce(Return(false)) // load module 1
- .WillOnce(Return(false)) // load module 2
- .WillOnce(Return(true)) // module 1 already loaded
- .WillOnce(Return(false)); // load module 3
- EXPECT_CALL(resolver, LoadModuleUsingMapBuffer(_,_))
- .Times(3)
- .WillRepeatedly(Return(true));
- EXPECT_CALL(resolver, UnloadModule(Property(&CodeModule::code_file,
- string("two.dll|two.pdb|2222"))))
- .Times(1);
-
- binarystream request;
- const u_int16_t sequence = 0x1010;
- request << sequence << P::LOAD << string("one.dll") << string("one.pdb")
- << string("1111");
- binarystream response;
- ASSERT_TRUE(server.HandleRequest(request, response));
- u_int16_t response_sequence;
- u_int8_t response_status, response_data;
- response >> response_sequence >> response_status >> response_data;
- ASSERT_FALSE(response.eof());
- EXPECT_EQ(sequence, response_sequence);
- EXPECT_EQ(P::OK, int(response_status));
- ASSERT_EQ(int(P::LOAD_OK), int(response_data));
-
- binarystream request2;
- const u_int16_t sequence2 = 0x2020;
- request2 << sequence2 << P::LOAD << string("two.dll") << string("two.pdb")
- << string("2222");
- ASSERT_TRUE(server.HandleRequest(request2, response));
- response >> response_sequence >> response_status >> response_data;
- ASSERT_FALSE(response.eof());
- EXPECT_EQ(sequence2, response_sequence);
- EXPECT_EQ(P::OK, int(response_status));
- ASSERT_EQ(int(P::LOAD_OK), int(response_data));
-
- binarystream request3;
- const u_int16_t sequence3 = 0x3030;
- request3 << sequence3 << P::LOAD << string("one.dll") << string("one.pdb")
- << string("1111");
- ASSERT_TRUE(server.HandleRequest(request3, response));
- response >> response_sequence >> response_status >> response_data;
- ASSERT_FALSE(response.eof());
- EXPECT_EQ(sequence3, response_sequence);
- EXPECT_EQ(P::OK, int(response_status));
- ASSERT_EQ(int(P::LOAD_OK), int(response_data));
-
- binarystream request4;
- const u_int16_t sequence4 = 0x4040;
- request4 << sequence4 << P::LOAD << string("three.dll") << string("three.pdb")
- << string("3333");
- ASSERT_TRUE(server.HandleRequest(request4, response));
- response >> response_sequence >> response_status >> response_data;
- ASSERT_FALSE(response.eof());
- EXPECT_EQ(sequence4, response_sequence);
- EXPECT_EQ(P::OK, int(response_status));
- ASSERT_EQ(int(P::LOAD_OK), int(response_data));
-}
-
-TEST_F(TestModuleManagement, TestModuleGetLRU) {
- // load 2 modules, then issue a GET for the first one,
- // then load a third one, causing the second one to be unloaded
- EXPECT_CALL(supplier, GetSymbolFile(_,_,_,_))
- .Times(3)
- .WillRepeatedly(DoAll(SetArgumentPointee<3>(string("1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n")),
- Return(SymbolSupplier::FOUND)));
- EXPECT_CALL(resolver, HasModule(_))
- .Times(3)
- .WillRepeatedly(Return(false));
- EXPECT_CALL(resolver, LoadModuleUsingMapBuffer(_,_))
- .Times(3)
- .WillRepeatedly(Return(true));
- EXPECT_CALL(resolver, FillSourceLineInfo(_))
- .Times(1);
- EXPECT_CALL(resolver, UnloadModule(Property(&CodeModule::code_file,
- string("two.dll|two.pdb|2222"))))
- .Times(1);
-
- binarystream request;
- const u_int16_t sequence = 0x1010;
- request << sequence << P::LOAD << string("one.dll") << string("one.pdb")
- << string("1111");
- binarystream response;
- ASSERT_TRUE(server.HandleRequest(request, response));
- u_int16_t response_sequence;
- u_int8_t response_status, response_data;
- response >> response_sequence >> response_status >> response_data;
- ASSERT_FALSE(response.eof());
- EXPECT_EQ(sequence, response_sequence);
- EXPECT_EQ(P::OK, int(response_status));
- ASSERT_EQ(int(P::LOAD_OK), int(response_data));
-
- binarystream request2;
- const u_int16_t sequence2 = 0x2020;
- request2 << sequence2 << P::LOAD << string("two.dll") << string("two.pdb")
- << string("2222");
- ASSERT_TRUE(server.HandleRequest(request2, response));
- response >> response_sequence >> response_status >> response_data;
- ASSERT_FALSE(response.eof());
- EXPECT_EQ(sequence2, response_sequence);
- EXPECT_EQ(P::OK, int(response_status));
- ASSERT_EQ(int(P::LOAD_OK), int(response_data));
-
- binarystream request3;
- const u_int16_t sequence3 = 0x3030;
- request3 << sequence3 << P::GET << string("one.dll")
- << string("one.pdb") << string("1111")
- << u_int64_t(0x1000) << u_int64_t(0x1234);
- ASSERT_TRUE(server.HandleRequest(request3, response));
- string function, source_file;
- u_int32_t source_line;
- u_int64_t function_base, source_line_base;
- response >> response_sequence >> response_status >> function
- >> function_base >> source_file >> source_line >> source_line_base;
- ASSERT_FALSE(response.eof());
- EXPECT_EQ(sequence3, response_sequence);
- EXPECT_EQ(P::OK, int(response_status));
- // Don't care about the rest of the response, really.
-
- binarystream request4;
- const u_int16_t sequence4 = 0x4040;
- request4 << sequence4 << P::LOAD << string("three.dll") << string("three.pdb")
- << string("3333");
- ASSERT_TRUE(server.HandleRequest(request4, response));
- response >> response_sequence >> response_status >> response_data;
- ASSERT_FALSE(response.eof());
- EXPECT_EQ(sequence4, response_sequence);
- EXPECT_EQ(P::OK, int(response_status));
- ASSERT_EQ(int(P::LOAD_OK), int(response_data));
-}
-
-TEST_F(TestModuleManagement, TestModuleGetStackWinLRU) {
- // load 2 modules, then issue a GETSTACKWIN for the first one,
- // then load a third one, causing the second one to be unloaded
- EXPECT_CALL(supplier, GetSymbolFile(_,_,_,_))
- .Times(3)
- .WillRepeatedly(DoAll(SetArgumentPointee<3>(string("1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n")),
- Return(SymbolSupplier::FOUND)));
- EXPECT_CALL(resolver, HasModule(_))
- .Times(3)
- .WillRepeatedly(Return(false));
- EXPECT_CALL(resolver, LoadModuleUsingMapBuffer(_,_))
- .Times(3)
- .WillRepeatedly(Return(true));
- EXPECT_CALL(resolver, FindWindowsFrameInfo(_))
- .WillOnce(Return((WindowsFrameInfo*)NULL));
- EXPECT_CALL(resolver, UnloadModule(Property(&CodeModule::code_file,
- string("two.dll|two.pdb|2222"))))
- .Times(1);
-
- binarystream request;
- const u_int16_t sequence = 0x1010;
- request << sequence << P::LOAD << string("one.dll") << string("one.pdb")
- << string("1111");
- binarystream response;
- ASSERT_TRUE(server.HandleRequest(request, response));
- u_int16_t response_sequence;
- u_int8_t response_status, response_data;
- response >> response_sequence >> response_status >> response_data;
- ASSERT_FALSE(response.eof());
- EXPECT_EQ(sequence, response_sequence);
- EXPECT_EQ(P::OK, int(response_status));
- ASSERT_EQ(int(P::LOAD_OK), int(response_data));
-
- binarystream request2;
- const u_int16_t sequence2 = 0x2020;
- request2 << sequence2 << P::LOAD << string("two.dll") << string("two.pdb")
- << string("2222");
- ASSERT_TRUE(server.HandleRequest(request2, response));
- response >> response_sequence >> response_status >> response_data;
- ASSERT_FALSE(response.eof());
- EXPECT_EQ(sequence2, response_sequence);
- EXPECT_EQ(P::OK, int(response_status));
- ASSERT_EQ(int(P::LOAD_OK), int(response_data));
-
- binarystream request3;
- const u_int16_t sequence3 = 0x3030;
- request3 << sequence3 << P::GETSTACKWIN << string("one.dll")
- << string("one.pdb") << string("1111")
- << u_int64_t(0x1000) << u_int64_t(0x1234);
- ASSERT_TRUE(server.HandleRequest(request3, response));
- string stack_info;
- response >> response_sequence >> response_status
- >> stack_info;
- ASSERT_FALSE(response.eof());
- EXPECT_EQ(sequence3, response_sequence);
- EXPECT_EQ(P::OK, int(response_status));
- // Don't care about the rest of the response, really.
-
- binarystream request4;
- const u_int16_t sequence4 = 0x4040;
- request4 << sequence4 << P::LOAD << string("three.dll") << string("three.pdb")
- << string("3333");
- ASSERT_TRUE(server.HandleRequest(request4, response));
- response >> response_sequence >> response_status >> response_data;
- ASSERT_FALSE(response.eof());
- EXPECT_EQ(sequence4, response_sequence);
- EXPECT_EQ(P::OK, int(response_status));
- ASSERT_EQ(int(P::LOAD_OK), int(response_data));
-}
-
-} // namespace
-
-int main(int argc, char *argv[]) {
- ::testing::InitGoogleTest(&argc, argv);
- return RUN_ALL_TESTS();
-}