1494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org// Copyright 2010, Google Inc.
2494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org// All rights reserved.
3494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org//
4494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org// Redistribution and use in source and binary forms, with or without
5494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org// modification, are permitted provided that the following conditions are
6494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org// met:
7494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org//
8494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org//     * Redistributions of source code must retain the above copyright
9494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org// notice, this list of conditions and the following disclaimer.
10494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org//     * Redistributions in binary form must reproduce the above
11494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org// copyright notice, this list of conditions and the following disclaimer
12494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org// in the documentation and/or other materials provided with the
13494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org// distribution.
14494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org//     * Neither the name of Google Inc. nor the names of its
15494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org// contributors may be used to endorse or promote products derived from
16494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org// this software without specific prior written permission.
17494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org//
18494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org
30494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org
31494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org#include "testing/gtest/include/gtest/gtest.h"
32494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org#include "testing/include/gmock/gmock.h"
33494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org
34494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org#include "client/windows/crash_generation/crash_generation_server.h"
35494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org#include "client/windows/common/ipc_protocol.h"
36494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org
37494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.orgusing testing::_;
38494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org
39494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.orgnamespace {
40494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org
41494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.orgconst wchar_t kPipeName[] =
42494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org  L"\\\\.\\pipe\\CrashGenerationServerTest\\TestCaseServer";
43494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org
44494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.orgconst DWORD kPipeDesiredAccess = FILE_READ_DATA |
45494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org                                 FILE_WRITE_DATA |
46494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org                                 FILE_WRITE_ATTRIBUTES;
47494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org
48494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.orgconst DWORD kPipeFlagsAndAttributes = SECURITY_IDENTIFICATION |
49494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org                                      SECURITY_SQOS_PRESENT;
50494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org
51494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.orgconst DWORD kPipeMode = PIPE_READMODE_MESSAGE;
52494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org
53494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.orgint kCustomInfoCount = 2;
54494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org
55494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.orggoogle_breakpad::CustomInfoEntry kCustomInfoEntries[] = {
56494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org    google_breakpad::CustomInfoEntry(L"prod", L"CrashGenerationServerTest"),
57494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org    google_breakpad::CustomInfoEntry(L"ver", L"1.0"),
58494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org};
59494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org
60494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.orgclass CrashGenerationServerTest : public ::testing::Test {
61494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org public:
62494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org  CrashGenerationServerTest()
63494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org      : crash_generation_server_(kPipeName,
64494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org                                 NULL,
65494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org                                 CallOnClientConnected, &mock_callbacks_,
66494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org                                 CallOnClientDumpRequested, &mock_callbacks_,
67494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org                                 CallOnClientExited, &mock_callbacks_,
68eb991531e31b7c001200cf23ce07efc5a32b41aecdn@chromium.org                                 CallOnClientUploadRequested, &mock_callbacks_,
69494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org                                 false,
70494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org                                 NULL),
71494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org        thread_id_(0),
72494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org        exception_pointers_(NULL) {
73494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org    memset(&assert_info_, 0, sizeof(assert_info_));
74494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org  }
75494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org
76494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org protected:
77494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org  class MockCrashGenerationServerCallbacks {
78494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org   public:
79494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org    MOCK_METHOD1(OnClientConnected,
80494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org                 void(const google_breakpad::ClientInfo* client_info));
81664e4d769163108ebdcff580c214b978579ce5a3mark@chromium.org    MOCK_METHOD2(OnClientDumpRequested,
82494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org                 void(const google_breakpad::ClientInfo* client_info,
83494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org                      const std::wstring* file_path));
84494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org    MOCK_METHOD1(OnClientExited,
85494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org                 void(const google_breakpad::ClientInfo* client_info));
86eb991531e31b7c001200cf23ce07efc5a32b41aecdn@chromium.org    MOCK_METHOD1(OnClientUploadRequested,
87eb991531e31b7c001200cf23ce07efc5a32b41aecdn@chromium.org                 void(const DWORD crash_id));
88494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org  };
89494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org
90494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org  enum ClientFault {
91494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org    NO_FAULT,
92494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org    CLOSE_AFTER_CONNECT,
93494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org    SEND_INVALID_REGISTRATION,
94494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org    TRUNCATE_REGISTRATION,
95494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org    CLOSE_AFTER_REGISTRATION,
96494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org    RESPONSE_BUFFER_TOO_SMALL,
97494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org    CLOSE_AFTER_RESPONSE,
98494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org    SEND_INVALID_ACK
99494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org  };
100494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org
101494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org  void SetUp() {
102494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org    ASSERT_TRUE(crash_generation_server_.Start());
103494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org  }
104494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org
105494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org  void FaultyClient(ClientFault fault_type) {
106494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org    HANDLE pipe = CreateFile(kPipeName,
107494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org                             kPipeDesiredAccess,
108494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org                             0,
109494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org                             NULL,
110494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org                             OPEN_EXISTING,
111494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org                             kPipeFlagsAndAttributes,
112494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org                             NULL);
113494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org
114494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org    if (pipe == INVALID_HANDLE_VALUE) {
115494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org      ASSERT_EQ(ERROR_PIPE_BUSY, GetLastError());
116494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org
117494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org      // Cannot continue retrying if wait on pipe fails.
118494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org      ASSERT_TRUE(WaitNamedPipe(kPipeName, 500));
119494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org
120494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org      pipe = CreateFile(kPipeName,
121494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org                        kPipeDesiredAccess,
122494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org                        0,
123494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org                        NULL,
124494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org                        OPEN_EXISTING,
125494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org                        kPipeFlagsAndAttributes,
126494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org                        NULL);
127494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org    }
128494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org
129494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org    ASSERT_NE(pipe, INVALID_HANDLE_VALUE);
130494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org
131494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org    DWORD mode = kPipeMode;
132494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org    ASSERT_TRUE(SetNamedPipeHandleState(pipe, &mode, NULL, NULL));
133494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org
134494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org    DoFaultyClient(fault_type, pipe);
135494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org
136494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org    CloseHandle(pipe);
137494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org  }
138494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org
139494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org  void DoTestFault(ClientFault fault) {
140494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org    EXPECT_CALL(mock_callbacks_, OnClientConnected(_)).Times(0);
141494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org    ASSERT_NO_FATAL_FAILURE(FaultyClient(fault));
142494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org    ASSERT_NO_FATAL_FAILURE(FaultyClient(fault));
143494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org    ASSERT_NO_FATAL_FAILURE(FaultyClient(fault));
144494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org
145494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org    EXPECT_CALL(mock_callbacks_, OnClientConnected(_));
146494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org
147494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org    ASSERT_NO_FATAL_FAILURE(FaultyClient(NO_FAULT));
148494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org
149494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org    // Slight hack. The OnClientConnected is only invoked after the ack is
150494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org    // received by the server. At that point, the FaultyClient call has already
151494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org    // returned. The best way to wait until the server is done handling that is
152494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org    // to send one more ping, whose processing will be blocked by delivery of
153494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org    // the OnClientConnected message.
154494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org    ASSERT_NO_FATAL_FAILURE(FaultyClient(CLOSE_AFTER_CONNECT));
155494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org  }
156494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org
157494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org  MockCrashGenerationServerCallbacks mock_callbacks_;
158494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org
159494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org private:
160494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org  // Depends on the caller to successfully open the pipe before invocation and
161494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org  // to close it immediately afterwards.
162494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org  void DoFaultyClient(ClientFault fault_type, HANDLE pipe) {
163494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org    if (fault_type == CLOSE_AFTER_CONNECT) {
164494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org      return;
165494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org    }
166494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org
167494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org    google_breakpad::CustomClientInfo custom_info = {kCustomInfoEntries,
168494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org                                                     kCustomInfoCount};
169494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org
170494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org    google_breakpad::ProtocolMessage msg(
171494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org      fault_type == SEND_INVALID_REGISTRATION ?
172494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org        google_breakpad::MESSAGE_TAG_NONE :
173494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org        google_breakpad::MESSAGE_TAG_REGISTRATION_REQUEST,
174494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org      GetCurrentProcessId(),
175494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org      MiniDumpNormal,
176494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org      &thread_id_,
177494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org      &exception_pointers_,
178494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org      &assert_info_,
179494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org      custom_info,
180494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org      NULL,
181494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org      NULL,
182494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org      NULL);
183494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org
184494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org    DWORD bytes_count = 0;
185494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org
186494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org    ASSERT_TRUE(WriteFile(pipe,
187494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org                          &msg,
188494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org                          fault_type == TRUNCATE_REGISTRATION ?
189494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org                            sizeof(msg) / 2 : sizeof(msg),
190494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org                          &bytes_count,
191494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org                          NULL));
192494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org
193494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org    if (fault_type == CLOSE_AFTER_REGISTRATION) {
194494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org      return;
195494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org    }
196494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org
197494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org    google_breakpad::ProtocolMessage reply;
198494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org
199494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org    if (!ReadFile(pipe,
200494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org                  &reply,
201494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org                  fault_type == RESPONSE_BUFFER_TOO_SMALL ?
202494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org                    sizeof(google_breakpad::ProtocolMessage) / 2 :
203494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org                    sizeof(google_breakpad::ProtocolMessage),
204494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org                  &bytes_count,
205494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org                  NULL)) {
206494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org      switch (fault_type) {
207494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org        case TRUNCATE_REGISTRATION:
208494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org        case RESPONSE_BUFFER_TOO_SMALL:
209494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org        case SEND_INVALID_REGISTRATION:
210494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org          return;
211494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org
212494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org        default:
213494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org          FAIL() << "Unexpectedly failed to register.";
214494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org      }
215494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org    }
216494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org
217494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org    if (fault_type == CLOSE_AFTER_RESPONSE) {
218494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org      return;
219494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org    }
220494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org
221494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org    google_breakpad::ProtocolMessage ack_msg;
222494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org    ack_msg.tag = google_breakpad::MESSAGE_TAG_REGISTRATION_ACK;
223494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org
224494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org    ASSERT_TRUE(WriteFile(pipe,
225494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org                          &ack_msg,
226494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org                          SEND_INVALID_ACK ?
227494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org                            sizeof(ack_msg) : sizeof(ack_msg) / 2,
228494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org                          &bytes_count,
229494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org                          NULL));
230494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org
231494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org    return;
232494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org  }
233494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org
234494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org  static void CallOnClientConnected(
235494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org    void* context, const google_breakpad::ClientInfo* client_info) {
236494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org    static_cast<MockCrashGenerationServerCallbacks*>(context)->
237494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org      OnClientConnected(client_info);
238494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org  }
239494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org
240494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org  static void CallOnClientDumpRequested(
241494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org    void* context,
242494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org    const google_breakpad::ClientInfo* client_info,
243494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org    const std::wstring* file_path) {
244494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org    static_cast<MockCrashGenerationServerCallbacks*>(context)->
245664e4d769163108ebdcff580c214b978579ce5a3mark@chromium.org      OnClientDumpRequested(client_info, file_path);
246494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org  }
247494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org
248494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org  static void CallOnClientExited(
249494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org    void* context, const google_breakpad::ClientInfo* client_info) {
250494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org    static_cast<MockCrashGenerationServerCallbacks*>(context)->
251494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org      OnClientExited(client_info);
252494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org  }
253494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org
254eb991531e31b7c001200cf23ce07efc5a32b41aecdn@chromium.org  static void CallOnClientUploadRequested(void* context, const DWORD crash_id) {
255eb991531e31b7c001200cf23ce07efc5a32b41aecdn@chromium.org    static_cast<MockCrashGenerationServerCallbacks*>(context)->
256eb991531e31b7c001200cf23ce07efc5a32b41aecdn@chromium.org      OnClientUploadRequested(crash_id);
257eb991531e31b7c001200cf23ce07efc5a32b41aecdn@chromium.org  }
258eb991531e31b7c001200cf23ce07efc5a32b41aecdn@chromium.org
259494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org  DWORD thread_id_;
260494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org  EXCEPTION_POINTERS* exception_pointers_;
261494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org  MDRawAssertionInfo assert_info_;
262494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org
263494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org  google_breakpad::CrashGenerationServer crash_generation_server_;
264494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org};
265494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org
266494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.orgTEST_F(CrashGenerationServerTest, PingServerTest) {
267494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org  DoTestFault(CLOSE_AFTER_CONNECT);
268494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org}
269494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org
270494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.orgTEST_F(CrashGenerationServerTest, InvalidRegistration) {
271494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org  DoTestFault(SEND_INVALID_REGISTRATION);
272494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org}
273494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org
274494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.orgTEST_F(CrashGenerationServerTest, TruncateRegistration) {
275494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org  DoTestFault(TRUNCATE_REGISTRATION);
276494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org}
277494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org
278494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.orgTEST_F(CrashGenerationServerTest, CloseAfterRegistration) {
279494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org  DoTestFault(CLOSE_AFTER_REGISTRATION);
280494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org}
281494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org
282494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.orgTEST_F(CrashGenerationServerTest, ResponseBufferTooSmall) {
283494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org  DoTestFault(RESPONSE_BUFFER_TOO_SMALL);
284494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org}
285494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org
286494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.orgTEST_F(CrashGenerationServerTest, CloseAfterResponse) {
287494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org  DoTestFault(CLOSE_AFTER_RESPONSE);
288494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org}
289494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org
290494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org// It turns out that, as long as you send one byte, the ACK is accepted and
291494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org// registration succeeds.
292494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.orgTEST_F(CrashGenerationServerTest, SendInvalidAck) {
293494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org  EXPECT_CALL(mock_callbacks_, OnClientConnected(_));
294494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org  ASSERT_NO_FATAL_FAILURE(FaultyClient(SEND_INVALID_ACK));
295494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org
296494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org  // See DoTestFault for an explanation of this line
297494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org  ASSERT_NO_FATAL_FAILURE(FaultyClient(CLOSE_AFTER_CONNECT));
298494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org
299494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org  EXPECT_CALL(mock_callbacks_, OnClientConnected(_));
300494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org  ASSERT_NO_FATAL_FAILURE(FaultyClient(NO_FAULT));
301494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org
302494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org  // See DoTestFault for an explanation of this line
303494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org  ASSERT_NO_FATAL_FAILURE(FaultyClient(CLOSE_AFTER_CONNECT));
304494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org}
305494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org
306494fa838866d3718da99717b5ed1e0732c565e2emark@chromium.org}  // anonymous namespace
307