Upstream version 9.37.197.0
[platform/framework/web/crosswalk.git] / src / third_party / libjingle / source / talk / base / win32toolhelp_unittest.cc
1 /*
2  * libjingle
3  * Copyright 2010, Google Inc.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  *
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.
15  *
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.
26  */
27
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"
32
33 namespace talk_base {
34
35 typedef struct {
36   // Required to match the toolhelp api struct 'design'.
37   DWORD dwSize;
38   int a;
39   uint32 b;
40 } TestData;
41
42 class Win32ToolhelpTest : public testing::Test {
43  public:
44   Win32ToolhelpTest() {
45   }
46
47   HANDLE AsHandle() {
48     return reinterpret_cast<HANDLE>(this);
49   }
50
51   static Win32ToolhelpTest* AsFixture(HANDLE handle) {
52     return reinterpret_cast<Win32ToolhelpTest*>(handle);
53   }
54
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) {
62       return false;
63     }
64
65     *d = kTestData[0];
66     tst->index_ = 1;
67     ++(tst->first_called_);
68     return true;
69   }
70
71   static bool Next(HANDLE handle, TestData* d) {
72     Win32ToolhelpTest* tst = Win32ToolhelpTest::AsFixture(handle);
73     ++(tst->next_called_);
74
75     if (tst->index_ >= kTestDataSize) {
76       return FALSE;
77     }
78
79     *d = kTestData[tst->index_];
80     ++(tst->index_);
81     return true;
82   }
83
84   static bool Fail(HANDLE handle, TestData* d) {
85     Win32ToolhelpTest* tst = Win32ToolhelpTest::AsFixture(handle);
86     ++(tst->fail_called_);
87     return false;
88   }
89
90   static bool CloseHandle(HANDLE handle) {
91     Win32ToolhelpTest* tst = Win32ToolhelpTest::AsFixture(handle);
92     ++(tst->close_handle_called_);
93     return true;
94   }
95
96  protected:
97   virtual void SetUp() {
98     fail_called_ = 0;
99     first_called_ = 0;
100     next_called_ = 0;
101     close_handle_called_ = 0;
102     index_ = 0;
103   }
104
105   static bool AllZero(const TestData& data) {
106     return data.dwSize == 0 && data.a == 0 && data.b == 0;
107   }
108
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;
113   }
114
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;
118
119     if (!match) {
120       LOG(LS_ERROR) << "Expected: ("
121                     << first << ", "
122                     << next << ", "
123                     << fail << ", "
124                     << close << ")";
125
126       LOG(LS_ERROR) << "Actual: ("
127                     << first_called_ << ", "
128                     << next_called_ << ", "
129                     << fail_called_ << ", "
130                     << close_handle_called_ << ")";
131     }
132     return match;
133   }
134
135   static const int kTestDataSize = 3;
136   static const TestData kTestData[];
137   int index_;
138   int first_called_;
139   int fail_called_;
140   int next_called_;
141   int close_handle_called_;
142 };
143
144 const TestData Win32ToolhelpTest::kTestData[] = {
145   {1, 1, 1}, {2, 2, 2}, {3, 3, 3}
146 };
147
148
149 class TestTraits {
150  public:
151   typedef TestData Type;
152
153   static bool First(HANDLE handle, Type* t) {
154     return Win32ToolhelpTest::First(handle, t);
155   }
156
157   static bool Next(HANDLE handle, Type* t) {
158     return Win32ToolhelpTest::Next(handle, t);
159   }
160
161   static bool CloseHandle(HANDLE handle) {
162     return Win32ToolhelpTest::CloseHandle(handle);
163   }
164 };
165
166 class BadFirstTraits {
167  public:
168   typedef TestData Type;
169
170   static bool First(HANDLE handle, Type* t) {
171     return Win32ToolhelpTest::Fail(handle, t);
172   }
173
174   static bool Next(HANDLE handle, Type* t) {
175     // This should never be called.
176     ADD_FAILURE();
177     return false;
178   }
179
180   static bool CloseHandle(HANDLE handle) {
181     return Win32ToolhelpTest::CloseHandle(handle);
182   }
183 };
184
185 class BadNextTraits {
186  public:
187   typedef TestData Type;
188
189   static bool First(HANDLE handle, Type* t) {
190     return Win32ToolhelpTest::First(handle, t);
191   }
192
193   static bool Next(HANDLE handle, Type* t) {
194     return Win32ToolhelpTest::Fail(handle, t);
195   }
196
197   static bool CloseHandle(HANDLE handle) {
198     return Win32ToolhelpTest::CloseHandle(handle);
199   }
200 };
201
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;
207
208 TEST_F(Win32ToolhelpTest, TestNextWithInvalidCtorHandle) {
209   EnumeratorForTest t(INVALID_HANDLE_VALUE);
210
211   EXPECT_FALSE(t.Next());
212   EXPECT_TRUE(CheckCallCounters(0, 0, 0, 0));
213 }
214
215 // Tests that Next() returns false if the first-pointer
216 // function fails.
217 TEST_F(Win32ToolhelpTest, TestNextFirstFails) {
218   typedef talk_base::ToolhelpEnumeratorBase<BadFirstTraits> BadEnumerator;
219   talk_base::scoped_ptr<BadEnumerator> t(new BadEnumerator(AsHandle()));
220
221   // If next ever fails it shall always fail.
222   EXPECT_FALSE(t->Next());
223   EXPECT_FALSE(t->Next());
224   EXPECT_FALSE(t->Next());
225   t.reset();
226   EXPECT_TRUE(CheckCallCounters(0, 0, 1, 1));
227 }
228
229 // Tests that Next() returns false if the next-pointer
230 // function fails.
231 TEST_F(Win32ToolhelpTest, TestNextNextFails) {
232   typedef talk_base::ToolhelpEnumeratorBase<BadNextTraits> BadEnumerator;
233   talk_base::scoped_ptr<BadEnumerator> t(new BadEnumerator(AsHandle()));
234
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());
240   t.reset();
241   EXPECT_TRUE(CheckCallCounters(1, 0, 1, 1));
242 }
243
244
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()));
250   t.reset();
251   EXPECT_TRUE(CheckCallCounters(0, 0, 0, 1));
252 }
253
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()));
257
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());
265   t.reset();
266   EXPECT_TRUE(CheckCallCounters(1, 3, 0, 1));
267 }
268
269 TEST_F(Win32ToolhelpTest, TestCurrentProcess) {
270   WCHAR buf[MAX_PATH];
271   GetModuleFileName(NULL, buf, ARRAY_SIZE(buf));
272   std::wstring name = ToUtf16(Pathname(ToUtf8(buf)).filename());
273
274   talk_base::ProcessEnumerator processes;
275   bool found = false;
276   while (processes.Next()) {
277     if (!name.compare(processes.current().szExeFile)) {
278       found = true;
279       break;
280     }
281   }
282   EXPECT_TRUE(found);
283
284   talk_base::ModuleEnumerator modules(processes.current().th32ProcessID);
285   found = false;
286   while (modules.Next()) {
287     if (!name.compare(modules.current().szModule)) {
288       found = true;
289       break;
290     }
291   }
292   EXPECT_TRUE(found);
293 }
294
295 }  // namespace talk_base