Index: remoting/host/breakpad_win_unittest.cc |
diff --git a/remoting/host/breakpad_win_unittest.cc b/remoting/host/breakpad_win_unittest.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..349363b7cbec4fb8f6f9a993f5a200fe08e8af9a |
--- /dev/null |
+++ b/remoting/host/breakpad_win_unittest.cc |
@@ -0,0 +1,134 @@ |
+// Copyright (c) 2012 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include <stdio.h> |
+ |
+#include "base/compiler_specific.h" |
+#include "base/logging.h" |
+#include "base/memory/scoped_ptr.h" |
+#include "base/string16.h" |
+#include "breakpad/src/client/windows/crash_generation/client_info.h" |
+#include "breakpad/src/client/windows/crash_generation/crash_generation_server.h" |
+#include "testing/gmock/include/gmock/gmock.h" |
+#include "testing/gtest/include/gtest/gtest.h" |
+ |
+namespace remoting { |
+ |
+namespace { |
+ |
+// The crash server pipe name. It was generated using uuidgen for the sole |
+// purpose of being unique. |
+const wchar_t kPipeName[] = L"\\\\.\\pipe\\16b7918a4019425b96e5d6c8c2ae7fe2"; |
+ |
+class MockCrashServerCallbacks { |
+ public: |
+ MockCrashServerCallbacks() {} |
+ virtual ~MockCrashServerCallbacks() {} |
+ |
+ MOCK_METHOD0(OnClientConnected, void()); |
+ MOCK_METHOD0(OnClientDumpRequested, void()); |
+ MOCK_METHOD0(OnClientExited, void()); |
+ |
+ static void OnClientConnectedCallback( |
+ void* context, |
+ const google_breakpad::ClientInfo* client_info) { |
+ reinterpret_cast<MockCrashServerCallbacks*>(context)->OnClientConnected(); |
+ } |
+ |
+ static void OnClientDumpRequestCallback( |
+ void* context, |
+ const google_breakpad::ClientInfo* client_info, |
+ const string16* file_path) { |
+ reinterpret_cast<MockCrashServerCallbacks*>(context)-> |
+ OnClientDumpRequested(); |
+ } |
+ |
+ static void OnClientExitedCallback( |
+ void* context, |
+ const google_breakpad::ClientInfo* client_info) { |
+ reinterpret_cast<MockCrashServerCallbacks*>(context)->OnClientExited(); |
+ } |
+}; |
+ |
+} // namespace |
+ |
+void InitializeCrashReportingForTest(const wchar_t*); |
+ |
+class BreakpadWinDeathTest : public testing::Test { |
+ public: |
+ BreakpadWinDeathTest() {} |
+ virtual void SetUp() OVERRIDE { |
+ if (::testing::internal::InDeathTestChild()) { |
+ // Initialize crash dump reporting to the dummy crash dump server. |
+ ::remoting::InitializeCrashReportingForTest(kPipeName); |
+ } else { |
+ // Setup a dummy crash dump server. |
+ callbacks_.reset(new MockCrashServerCallbacks()); |
+ crash_server_.reset( |
+ new google_breakpad::CrashGenerationServer( |
+ kPipeName, NULL, |
+ MockCrashServerCallbacks::OnClientConnectedCallback, |
+ callbacks_.get(), |
+ MockCrashServerCallbacks::OnClientDumpRequestCallback, |
+ callbacks_.get(), |
+ MockCrashServerCallbacks::OnClientExitedCallback, |
+ callbacks_.get(), |
+ false, NULL)); |
+ |
+ bool result = crash_server_->Start(); |
+ ASSERT_TRUE(result); |
+ } |
+ } |
+ |
+ protected: |
+ scoped_ptr<google_breakpad::CrashGenerationServer> crash_server_; |
+ scoped_ptr<MockCrashServerCallbacks> callbacks_; |
+}; |
+ |
+TEST_F(BreakpadWinDeathTest, TestAccessViolation) { |
+ if (callbacks_.get()) { |
+ ::testing::Sequence s; |
+ EXPECT_CALL(*callbacks_, OnClientConnected()) |
+ .InSequence(s); |
+ EXPECT_CALL(*callbacks_, OnClientDumpRequested()) |
+ .InSequence(s); |
+ EXPECT_CALL(*callbacks_, OnClientExited()) |
+ .InSequence(s); |
+ } |
+ |
+ // Generate access violation exception. |
+ ASSERT_DEATH(*reinterpret_cast<int*>(0) = 1, ""); |
+} |
+ |
+TEST_F(BreakpadWinDeathTest, TestInvalidParameter) { |
+ if (callbacks_.get()) { |
+ ::testing::Sequence s; |
+ EXPECT_CALL(*callbacks_, OnClientConnected()) |
+ .InSequence(s); |
+ EXPECT_CALL(*callbacks_, OnClientDumpRequested()) |
+ .InSequence(s); |
+ EXPECT_CALL(*callbacks_, OnClientExited()) |
+ .InSequence(s); |
+ } |
+ |
+ // Cause the invalid parameter callback to be called. |
+ ASSERT_EXIT(printf(NULL), ::testing::ExitedWithCode(0), ""); |
+} |
+ |
+TEST_F(BreakpadWinDeathTest, TestDebugbreak) { |
+ if (callbacks_.get()) { |
+ ::testing::Sequence s; |
+ EXPECT_CALL(*callbacks_, OnClientConnected()) |
+ .InSequence(s); |
+ EXPECT_CALL(*callbacks_, OnClientDumpRequested()) |
+ .InSequence(s); |
+ EXPECT_CALL(*callbacks_, OnClientExited()) |
+ .InSequence(s); |
+ } |
+ |
+ // See if __debugbreak() is intercepted. |
+ ASSERT_DEATH(__debugbreak(), ""); |
+} |
+ |
+} // namespace remoting |