3 * Copyright 2010, Google Inc.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
8 * 1. Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright notice,
11 * this list of conditions and the following disclaimer in the documentation
12 * and/or other materials provided with the distribution.
13 * 3. The name of the author may not be used to endorse or promote products
14 * derived from this software without specific prior written permission.
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
19 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
22 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 #include "talk/base/gunit.h"
29 #include "talk/base/pathutils.h"
30 #include "talk/base/scoped_ptr.h"
31 #include "talk/base/win32toolhelp.h"
36 // Required to match the toolhelp api struct 'design'.
42 class Win32ToolhelpTest : public testing::Test {
48 return reinterpret_cast<HANDLE>(this);
51 static Win32ToolhelpTest* AsFixture(HANDLE handle) {
52 return reinterpret_cast<Win32ToolhelpTest*>(handle);
55 static bool First(HANDLE handle, TestData* d) {
56 Win32ToolhelpTest* tst = Win32ToolhelpTest::AsFixture(handle);
57 // This method should be called only once for every test.
58 // If it is called more than once it return false which
59 // should break the test.
60 EXPECT_EQ(0, tst->first_called_); // Just to be safe.
61 if (tst->first_called_ > 0) {
67 ++(tst->first_called_);
71 static bool Next(HANDLE handle, TestData* d) {
72 Win32ToolhelpTest* tst = Win32ToolhelpTest::AsFixture(handle);
73 ++(tst->next_called_);
75 if (tst->index_ >= kTestDataSize) {
79 *d = kTestData[tst->index_];
84 static bool Fail(HANDLE handle, TestData* d) {
85 Win32ToolhelpTest* tst = Win32ToolhelpTest::AsFixture(handle);
86 ++(tst->fail_called_);
90 static bool CloseHandle(HANDLE handle) {
91 Win32ToolhelpTest* tst = Win32ToolhelpTest::AsFixture(handle);
92 ++(tst->close_handle_called_);
97 virtual void SetUp() {
101 close_handle_called_ = 0;
105 static bool AllZero(const TestData& data) {
106 return data.dwSize == 0 && data.a == 0 && data.b == 0;
109 static bool Equals(const TestData& expected, const TestData& actual) {
110 return expected.dwSize == actual.dwSize
111 && expected.a == actual.a
112 && expected.b == actual.b;
115 bool CheckCallCounters(int first, int next, int fail, int close) {
116 bool match = first_called_ == first && next_called_ == next
117 && fail_called_ == fail && close_handle_called_ == close;
120 LOG(LS_ERROR) << "Expected: ("
126 LOG(LS_ERROR) << "Actual: ("
127 << first_called_ << ", "
128 << next_called_ << ", "
129 << fail_called_ << ", "
130 << close_handle_called_ << ")";
135 static const int kTestDataSize = 3;
136 static const TestData kTestData[];
141 int close_handle_called_;
144 const TestData Win32ToolhelpTest::kTestData[] = {
145 {1, 1, 1}, {2, 2, 2}, {3, 3, 3}
151 typedef TestData Type;
153 static bool First(HANDLE handle, Type* t) {
154 return Win32ToolhelpTest::First(handle, t);
157 static bool Next(HANDLE handle, Type* t) {
158 return Win32ToolhelpTest::Next(handle, t);
161 static bool CloseHandle(HANDLE handle) {
162 return Win32ToolhelpTest::CloseHandle(handle);
166 class BadFirstTraits {
168 typedef TestData Type;
170 static bool First(HANDLE handle, Type* t) {
171 return Win32ToolhelpTest::Fail(handle, t);
174 static bool Next(HANDLE handle, Type* t) {
175 // This should never be called.
180 static bool CloseHandle(HANDLE handle) {
181 return Win32ToolhelpTest::CloseHandle(handle);
185 class BadNextTraits {
187 typedef TestData Type;
189 static bool First(HANDLE handle, Type* t) {
190 return Win32ToolhelpTest::First(handle, t);
193 static bool Next(HANDLE handle, Type* t) {
194 return Win32ToolhelpTest::Fail(handle, t);
197 static bool CloseHandle(HANDLE handle) {
198 return Win32ToolhelpTest::CloseHandle(handle);
202 // The toolhelp in normally inherited but most of
203 // these tests only excercise the methods from the
204 // traits therefore I use a typedef to make the
205 // test code easier to read.
206 typedef talk_base::ToolhelpEnumeratorBase<TestTraits> EnumeratorForTest;
208 TEST_F(Win32ToolhelpTest, TestNextWithInvalidCtorHandle) {
209 EnumeratorForTest t(INVALID_HANDLE_VALUE);
211 EXPECT_FALSE(t.Next());
212 EXPECT_TRUE(CheckCallCounters(0, 0, 0, 0));
215 // Tests that Next() returns false if the first-pointer
217 TEST_F(Win32ToolhelpTest, TestNextFirstFails) {
218 typedef talk_base::ToolhelpEnumeratorBase<BadFirstTraits> BadEnumerator;
219 talk_base::scoped_ptr<BadEnumerator> t(new BadEnumerator(AsHandle()));
221 // If next ever fails it shall always fail.
222 EXPECT_FALSE(t->Next());
223 EXPECT_FALSE(t->Next());
224 EXPECT_FALSE(t->Next());
226 EXPECT_TRUE(CheckCallCounters(0, 0, 1, 1));
229 // Tests that Next() returns false if the next-pointer
231 TEST_F(Win32ToolhelpTest, TestNextNextFails) {
232 typedef talk_base::ToolhelpEnumeratorBase<BadNextTraits> BadEnumerator;
233 talk_base::scoped_ptr<BadEnumerator> t(new BadEnumerator(AsHandle()));
235 // If next ever fails it shall always fail. No more calls
236 // shall be dispatched to Next(...).
237 EXPECT_TRUE(t->Next());
238 EXPECT_FALSE(t->Next());
239 EXPECT_FALSE(t->Next());
241 EXPECT_TRUE(CheckCallCounters(1, 0, 1, 1));
245 // Tests that current returns an object is all zero's
246 // if Next() hasn't been called.
247 TEST_F(Win32ToolhelpTest, TestCurrentNextNotCalled) {
248 talk_base::scoped_ptr<EnumeratorForTest> t(new EnumeratorForTest(AsHandle()));
249 EXPECT_TRUE(AllZero(t->current()));
251 EXPECT_TRUE(CheckCallCounters(0, 0, 0, 1));
254 // Tests the simple everything works path through the code.
255 TEST_F(Win32ToolhelpTest, TestCurrentNextCalled) {
256 talk_base::scoped_ptr<EnumeratorForTest> t(new EnumeratorForTest(AsHandle()));
258 EXPECT_TRUE(t->Next());
259 EXPECT_TRUE(Equals(t->current(), kTestData[0]));
260 EXPECT_TRUE(t->Next());
261 EXPECT_TRUE(Equals(t->current(), kTestData[1]));
262 EXPECT_TRUE(t->Next());
263 EXPECT_TRUE(Equals(t->current(), kTestData[2]));
264 EXPECT_FALSE(t->Next());
266 EXPECT_TRUE(CheckCallCounters(1, 3, 0, 1));
269 TEST_F(Win32ToolhelpTest, TestCurrentProcess) {
271 GetModuleFileName(NULL, buf, ARRAY_SIZE(buf));
272 std::wstring name = ToUtf16(Pathname(ToUtf8(buf)).filename());
274 talk_base::ProcessEnumerator processes;
276 while (processes.Next()) {
277 if (!name.compare(processes.current().szExeFile)) {
284 talk_base::ModuleEnumerator modules(processes.current().th32ProcessID);
286 while (modules.Next()) {
287 if (!name.compare(modules.current().szModule)) {
295 } // namespace talk_base