1 : // Copyright 2015 Google Inc. All Rights Reserved.
2 : //
3 : // Licensed under the Apache License, Version 2.0 (the "License");
4 : // you may not use this file except in compliance with the License.
5 : // You may obtain a copy of the License at
6 : //
7 : // http://www.apache.org/licenses/LICENSE-2.0
8 : //
9 : // Unless required by applicable law or agreed to in writing, software
10 : // distributed under the License is distributed on an "AS IS" BASIS,
11 : // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 : // See the License for the specific language governing permissions and
13 : // limitations under the License.
14 :
15 : #include "syzygy/kasko/client.h"
16 :
17 : #include <Windows.h> // NOLINT
18 : #include <Rpc.h>
19 :
20 : #include <vector>
21 :
22 : #include "base/bind.h"
23 : #include "base/callback.h"
24 : #include "base/callback_helpers.h"
25 : #include "base/process/process_handle.h"
26 : #include "base/strings/string16.h"
27 : #include "base/strings/string_number_conversions.h"
28 : #include "gtest/gtest.h"
29 : #include "syzygy/kasko/minidump_request.h"
30 : #include "syzygy/kasko/service_bridge.h"
31 : #include "syzygy/kasko/testing/mock_service.h"
32 :
33 : namespace kasko {
34 :
35 : namespace {
36 :
37 : const base::char16* const kValidRpcProtocol = L"ncalrpc";
38 : const base::char16* const kTestRpcEndpointPrefix = L"syzygy-kasko-test-svc";
39 :
40 E : base::string16 GetTestEndpoint() {
41 E : return kTestRpcEndpointPrefix + base::UintToString16(::GetCurrentProcessId());
42 E : }
43 :
44 : } // namespace
45 :
46 E : TEST(ClientTest, BasicTest) {
47 E : std::vector<testing::MockService::CallRecord> call_log;
48 :
49 E : base::string16 protocol = kValidRpcProtocol;
50 E : base::string16 endpoint = GetTestEndpoint();
51 : ServiceBridge instance(
52 : protocol, endpoint,
53 E : scoped_ptr<Service>(new testing::MockService(&call_log)));
54 E : ASSERT_TRUE(instance.Run());
55 :
56 : base::ScopedClosureRunner stop_service_bridge(
57 E : base::Bind(&ServiceBridge::Stop, base::Unretained(&instance)));
58 :
59 E : std::string protobuf = "hello world";
60 E : uint32_t kStreamType = 987;
61 E : MinidumpRequest request;
62 : MinidumpRequest::CustomStream custom_stream = {kStreamType, protobuf.data(),
63 E : protobuf.length()};
64 E : request.custom_streams.push_back(custom_stream);
65 :
66 : // Small dump with crash keys.
67 E : request.type = MinidumpRequest::SMALL_DUMP_TYPE;
68 E : request.crash_keys.push_back(MinidumpRequest::CrashKey(L"foo", L"bar"));
69 E : request.crash_keys.push_back(MinidumpRequest::CrashKey(L"hello", L"world"));
70 E : Client(endpoint).SendReport(request);
71 :
72 : // Larger dump without crash keys.
73 E : request.type = MinidumpRequest::LARGER_DUMP_TYPE;
74 E : request.crash_keys.clear();
75 E : MinidumpRequest::MemoryRange memory_range = {0xdeadbeef, 100};
76 E : request.user_selected_memory_ranges.push_back(memory_range);
77 E : Client(endpoint).SendReport(request);
78 :
79 : // Full dump without protobuf.
80 E : request.type = MinidumpRequest::FULL_DUMP_TYPE;
81 E : request.crash_keys.clear();
82 E : request.custom_streams.clear();
83 E : Client(endpoint).SendReport(request);
84 :
85 E : ASSERT_EQ(3u, call_log.size());
86 E : ASSERT_EQ(::GetCurrentProcessId(), call_log[0].client_process_id);
87 E : ASSERT_EQ(1u, call_log[0].custom_streams.size());
88 E : auto custom_streams_entry = call_log[0].custom_streams.find(kStreamType);
89 E : ASSERT_NE(call_log[0].custom_streams.end(), custom_streams_entry);
90 E : ASSERT_EQ(protobuf, custom_streams_entry->second);
91 E : ASSERT_EQ(2u, call_log[0].crash_keys.size());
92 E : auto crash_keys_entry = call_log[0].crash_keys.find(L"foo");
93 E : ASSERT_NE(call_log[0].crash_keys.end(), crash_keys_entry);
94 E : ASSERT_EQ(L"bar", crash_keys_entry->second);
95 E : crash_keys_entry = call_log[0].crash_keys.find(L"hello");
96 E : ASSERT_NE(call_log[0].crash_keys.end(), crash_keys_entry);
97 E : ASSERT_EQ(L"world", crash_keys_entry->second);
98 E : ASSERT_EQ(0u, call_log[0].user_selected_memory_ranges.size());
99 E : ASSERT_EQ(MinidumpRequest::SMALL_DUMP_TYPE, call_log[0].minidump_type);
100 :
101 E : ASSERT_EQ(::GetCurrentProcessId(), call_log[1].client_process_id);
102 E : ASSERT_EQ(0u, call_log[1].crash_keys.size());
103 E : ASSERT_EQ(1u, call_log[1].custom_streams.size());
104 E : custom_streams_entry = call_log[1].custom_streams.find(kStreamType);
105 E : ASSERT_NE(call_log[1].custom_streams.end(), custom_streams_entry);
106 E : ASSERT_EQ(protobuf, custom_streams_entry->second);
107 E : ASSERT_EQ(1u, call_log[1].user_selected_memory_ranges.size());
108 : ASSERT_EQ(memory_range.start(),
109 E : call_log[1].user_selected_memory_ranges[0].start());
110 : ASSERT_EQ(memory_range.size(),
111 E : call_log[1].user_selected_memory_ranges[0].size());
112 E : ASSERT_EQ(MinidumpRequest::LARGER_DUMP_TYPE, call_log[1].minidump_type);
113 :
114 E : ASSERT_EQ(::GetCurrentProcessId(), call_log[2].client_process_id);
115 E : ASSERT_EQ(0u, call_log[2].crash_keys.size());
116 E : ASSERT_EQ(0u, call_log[2].custom_streams.size());
117 E : ASSERT_EQ(MinidumpRequest::FULL_DUMP_TYPE, call_log[2].minidump_type);
118 E : }
119 :
120 : } // namespace kasko
|