1 : // Copyright 2012 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/trace/client/client_utils.h"
16 :
17 : #include "base/environment.h"
18 : #include "base/utf_string_conversions.h"
19 : #include "base/memory/scoped_ptr.h"
20 : #include "gtest/gtest.h"
21 : #include "syzygy/core/file_util.h"
22 : #include "syzygy/core/unittest_util.h"
23 : #include "syzygy/trace/client/rpc_session.h"
24 :
25 : // http://blogs.msdn.com/oldnewthing/archive/2004/10/25/247180.aspx
26 : extern "C" IMAGE_DOS_HEADER __ImageBase;
27 :
28 : namespace trace {
29 : namespace client {
30 :
31 : namespace {
32 :
33 : class GetInstanceIdForModuleTest : public testing::Test {
34 : public:
35 E : GetInstanceIdForModuleTest() : path_(L"C:\\path\\foo.exe") { }
36 :
37 E : virtual void SetUp() OVERRIDE {
38 E : testing::Test::SetUp();
39 E : env_.reset(base::Environment::Create());
40 E : }
41 :
42 E : void SetEnvVar(const base::StringPiece& string) {
43 E : ASSERT_TRUE(env_->SetVar(::kSyzygyRpcInstanceIdEnvVar, string.as_string()));
44 E : }
45 :
46 E : void UnsetEnvVar() {
47 E : ASSERT_TRUE(env_->UnSetVar(::kSyzygyRpcInstanceIdEnvVar));
48 E : }
49 :
50 : base::FilePath path_;
51 : scoped_ptr<base::Environment> env_;
52 : };
53 :
54 : class IsRpcSessionMandatoryTest : public testing::Test {
55 : public:
56 E : IsRpcSessionMandatoryTest() : path_(L"C:\\path\\foo.exe") { }
57 :
58 E : virtual void SetUp() OVERRIDE {
59 E : testing::Test::SetUp();
60 E : env_.reset(base::Environment::Create());
61 E : }
62 :
63 E : void SetEnvVar(const base::StringPiece& string) {
64 E : ASSERT_TRUE(env_->SetVar(::kSyzygyRpcSessionMandatoryEnvVar,
65 : string.as_string()));
66 E : }
67 :
68 E : void UnsetEnvVar() {
69 E : ASSERT_TRUE(env_->UnSetVar(::kSyzygyRpcSessionMandatoryEnvVar));
70 E : }
71 :
72 : base::FilePath path_;
73 : scoped_ptr<base::Environment> env_;
74 : };
75 :
76 : } // namespace
77 :
78 E : TEST(GetModuleBaseAddressTest, WorksOnSelf) {
79 E : void* module_base = NULL;
80 E : EXPECT_TRUE(GetModuleBaseAddress(&GetModuleBaseAddress, &module_base));
81 E : EXPECT_EQ(&__ImageBase, module_base);
82 E : }
83 :
84 E : TEST(GetModulePath, WorksOnSelf) {
85 E : void* module_base = NULL;
86 E : ASSERT_TRUE(GetModuleBaseAddress(&GetModuleBaseAddress, &module_base));
87 :
88 E : base::FilePath module_path;
89 E : EXPECT_TRUE(GetModulePath(module_base, &module_path));
90 :
91 : base::FilePath self_path =
92 E : ::testing::GetExeRelativePath(L"rpc_client_lib_unittests.exe");
93 E : EXPECT_SAME_FILE(self_path, module_path);
94 E : }
95 :
96 E : TEST_F(GetInstanceIdForModuleTest, ReturnsEmptyForNoEnvVar) {
97 E : ASSERT_NO_FATAL_FAILURE(UnsetEnvVar());
98 E : EXPECT_EQ(std::string(), GetInstanceIdForModule(path_));
99 E : }
100 :
101 E : TEST_F(GetInstanceIdForModuleTest, ReturnsEmptyForEmptyEnvVar) {
102 E : ASSERT_NO_FATAL_FAILURE(SetEnvVar(""));
103 E : EXPECT_EQ(std::string(), GetInstanceIdForModule(path_));
104 E : }
105 :
106 E : TEST_F(GetInstanceIdForModuleTest, ReturnsEmptyForNoMatch) {
107 E : ASSERT_NO_FATAL_FAILURE(SetEnvVar("bar.exe,1;baz.exe,2"));
108 E : EXPECT_EQ(std::string(""), GetInstanceIdForModule(path_));
109 E : }
110 :
111 E : TEST_F(GetInstanceIdForModuleTest, ReturnsGenericIdWhenNoPathMatches) {
112 E : ASSERT_NO_FATAL_FAILURE(SetEnvVar("1 ;bar.exe,2"));
113 E : EXPECT_EQ(std::string("1"), GetInstanceIdForModule(path_));
114 E : }
115 :
116 E : TEST_F(GetInstanceIdForModuleTest, ReturnsBaseNameId) {
117 E : ASSERT_NO_FATAL_FAILURE(SetEnvVar("1; foo.exe , 2"));
118 E : EXPECT_EQ(std::string("2"), GetInstanceIdForModule(path_));
119 E : }
120 :
121 E : TEST_F(GetInstanceIdForModuleTest, ReturnsExactPathId) {
122 E : ASSERT_NO_FATAL_FAILURE(SetEnvVar("1;foo.exe,2;C:\\path\\foo.exe, 3 "));
123 E : EXPECT_EQ(std::string("3"), GetInstanceIdForModule(path_));
124 E : }
125 :
126 E : TEST(GetInstanceIdForThisModuleTest, WorksAsExpected) {
127 : base::FilePath self_path =
128 E : ::testing::GetExeRelativePath(L"rpc_client_lib_unittests.exe");
129 :
130 E : std::wstring env_var(self_path.value());
131 E : env_var.append(L",1");
132 :
133 E : scoped_ptr<base::Environment> env;
134 E : env.reset(base::Environment::Create());
135 : ASSERT_TRUE(env->SetVar(::kSyzygyRpcInstanceIdEnvVar,
136 E : ::WideToUTF8(env_var)));
137 :
138 E : EXPECT_EQ(std::string("1"), GetInstanceIdForThisModule());
139 E : }
140 :
141 E : TEST_F(IsRpcSessionMandatoryTest, ReturnsFalseForNoEnvVar) {
142 E : ASSERT_NO_FATAL_FAILURE(UnsetEnvVar());
143 E : EXPECT_FALSE(IsRpcSessionMandatory(path_));
144 E : }
145 :
146 E : TEST_F(IsRpcSessionMandatoryTest, ReturnsFalseForEmptyEnvVar) {
147 E : ASSERT_NO_FATAL_FAILURE(SetEnvVar(""));
148 E : EXPECT_FALSE(IsRpcSessionMandatory(path_));
149 E : }
150 :
151 E : TEST_F(IsRpcSessionMandatoryTest, ReturnsFalseForNoMatch) {
152 E : ASSERT_NO_FATAL_FAILURE(SetEnvVar("bar.exe,1;baz.exe,1"));
153 E : EXPECT_FALSE(IsRpcSessionMandatory(path_));
154 E : }
155 :
156 E : TEST_F(IsRpcSessionMandatoryTest, ReturnsGlobalValueWhenNoPathMatches) {
157 E : ASSERT_NO_FATAL_FAILURE(SetEnvVar("1 ; bar.exe,0"));
158 E : EXPECT_TRUE(IsRpcSessionMandatory(path_));
159 E : }
160 :
161 E : TEST_F(IsRpcSessionMandatoryTest, ReturnsBaseNameValue) {
162 E : ASSERT_NO_FATAL_FAILURE(SetEnvVar("0; foo.exe , 1"));
163 E : EXPECT_TRUE(IsRpcSessionMandatory(path_));
164 E : }
165 :
166 E : TEST_F(IsRpcSessionMandatoryTest, ReturnsExactPathValue) {
167 E : ASSERT_NO_FATAL_FAILURE(SetEnvVar("0;foo.exe,0;C:\\path\\foo.exe, 1 "));
168 E : EXPECT_TRUE(IsRpcSessionMandatory(path_));
169 E : }
170 :
171 E : TEST_F(IsRpcSessionMandatoryTest, NonNumericIgnored) {
172 E : ASSERT_NO_FATAL_FAILURE(SetEnvVar("foo.exe,baz;C:\\path\\foo.exe,bar"));
173 E : EXPECT_FALSE(IsRpcSessionMandatory(path_));
174 E : }
175 :
176 E : TEST(IsRpcSessionMandatoryThisModuleTest, WorksAsExpected) {
177 : base::FilePath self_path =
178 E : ::testing::GetExeRelativePath(L"rpc_client_lib_unittests.exe");
179 :
180 E : std::wstring env_var(self_path.value());
181 E : env_var.append(L",1");
182 :
183 E : scoped_ptr<base::Environment> env;
184 E : env.reset(base::Environment::Create());
185 : ASSERT_TRUE(env->SetVar(::kSyzygyRpcSessionMandatoryEnvVar,
186 E : ::WideToUTF8(env_var)));
187 :
188 E : EXPECT_TRUE(IsRpcSessionMandatoryForThisModule());
189 E : }
190 :
191 E : TEST(InitializeRpcSessionTest, FailureSessionNotMandatory) {
192 : base::FilePath self_path =
193 E : ::testing::GetExeRelativePath(L"rpc_client_lib_unittests.exe");
194 :
195 E : scoped_ptr<base::Environment> env;
196 E : env.reset(base::Environment::Create());
197 :
198 E : std::wstring env_var(self_path.value());
199 E : env_var.append(L",0");
200 : ASSERT_TRUE(env->SetVar(::kSyzygyRpcSessionMandatoryEnvVar,
201 E : ::WideToUTF8(env_var)));
202 :
203 E : env_var = self_path.value();
204 E : std::wstring id(L"dummy-id");
205 E : env_var.append(L",");
206 E : env_var.append(id);
207 : ASSERT_TRUE(env->SetVar(::kSyzygyRpcInstanceIdEnvVar,
208 E : ::WideToUTF8(env_var)));
209 :
210 E : RpcSession session;
211 E : TraceFileSegment segment;
212 E : EXPECT_FALSE(InitializeRpcSession(&session, &segment));
213 :
214 E : EXPECT_EQ(id, session.instance_id());
215 E : }
216 :
217 : // TODO(chrisha): A more involved unittest where we launch a child process
218 : // whose RPC connection is mandatory, but unable to be initialized. Make
219 : // sure that it crashes as expected.
220 :
221 : } // namespace client
222 : } // namespace trace
|