summaryrefslogtreecommitdiffstats
path: root/chromium/third_party/webrtc/base/win32toolhelp_unittest.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/third_party/webrtc/base/win32toolhelp_unittest.cc')
-rw-r--r--chromium/third_party/webrtc/base/win32toolhelp_unittest.cc278
1 files changed, 278 insertions, 0 deletions
diff --git a/chromium/third_party/webrtc/base/win32toolhelp_unittest.cc b/chromium/third_party/webrtc/base/win32toolhelp_unittest.cc
new file mode 100644
index 00000000000..280f2ec98d0
--- /dev/null
+++ b/chromium/third_party/webrtc/base/win32toolhelp_unittest.cc
@@ -0,0 +1,278 @@
+/*
+ * Copyright 2010 The WebRTC Project Authors. All rights reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "webrtc/base/gunit.h"
+#include "webrtc/base/pathutils.h"
+#include "webrtc/base/scoped_ptr.h"
+#include "webrtc/base/win32toolhelp.h"
+
+namespace rtc {
+
+typedef struct {
+ // Required to match the toolhelp api struct 'design'.
+ DWORD dwSize;
+ int a;
+ uint32 b;
+} TestData;
+
+class Win32ToolhelpTest : public testing::Test {
+ public:
+ Win32ToolhelpTest() {
+ }
+
+ HANDLE AsHandle() {
+ return reinterpret_cast<HANDLE>(this);
+ }
+
+ static Win32ToolhelpTest* AsFixture(HANDLE handle) {
+ return reinterpret_cast<Win32ToolhelpTest*>(handle);
+ }
+
+ static bool First(HANDLE handle, TestData* d) {
+ Win32ToolhelpTest* tst = Win32ToolhelpTest::AsFixture(handle);
+ // This method should be called only once for every test.
+ // If it is called more than once it return false which
+ // should break the test.
+ EXPECT_EQ(0, tst->first_called_); // Just to be safe.
+ if (tst->first_called_ > 0) {
+ return false;
+ }
+
+ *d = kTestData[0];
+ tst->index_ = 1;
+ ++(tst->first_called_);
+ return true;
+ }
+
+ static bool Next(HANDLE handle, TestData* d) {
+ Win32ToolhelpTest* tst = Win32ToolhelpTest::AsFixture(handle);
+ ++(tst->next_called_);
+
+ if (tst->index_ >= kTestDataSize) {
+ return FALSE;
+ }
+
+ *d = kTestData[tst->index_];
+ ++(tst->index_);
+ return true;
+ }
+
+ static bool Fail(HANDLE handle, TestData* d) {
+ Win32ToolhelpTest* tst = Win32ToolhelpTest::AsFixture(handle);
+ ++(tst->fail_called_);
+ return false;
+ }
+
+ static bool CloseHandle(HANDLE handle) {
+ Win32ToolhelpTest* tst = Win32ToolhelpTest::AsFixture(handle);
+ ++(tst->close_handle_called_);
+ return true;
+ }
+
+ protected:
+ virtual void SetUp() {
+ fail_called_ = 0;
+ first_called_ = 0;
+ next_called_ = 0;
+ close_handle_called_ = 0;
+ index_ = 0;
+ }
+
+ static bool AllZero(const TestData& data) {
+ return data.dwSize == 0 && data.a == 0 && data.b == 0;
+ }
+
+ static bool Equals(const TestData& expected, const TestData& actual) {
+ return expected.dwSize == actual.dwSize
+ && expected.a == actual.a
+ && expected.b == actual.b;
+ }
+
+ bool CheckCallCounters(int first, int next, int fail, int close) {
+ bool match = first_called_ == first && next_called_ == next
+ && fail_called_ == fail && close_handle_called_ == close;
+
+ if (!match) {
+ LOG(LS_ERROR) << "Expected: ("
+ << first << ", "
+ << next << ", "
+ << fail << ", "
+ << close << ")";
+
+ LOG(LS_ERROR) << "Actual: ("
+ << first_called_ << ", "
+ << next_called_ << ", "
+ << fail_called_ << ", "
+ << close_handle_called_ << ")";
+ }
+ return match;
+ }
+
+ static const int kTestDataSize = 3;
+ static const TestData kTestData[];
+ int index_;
+ int first_called_;
+ int fail_called_;
+ int next_called_;
+ int close_handle_called_;
+};
+
+const TestData Win32ToolhelpTest::kTestData[] = {
+ {1, 1, 1}, {2, 2, 2}, {3, 3, 3}
+};
+
+
+class TestTraits {
+ public:
+ typedef TestData Type;
+
+ static bool First(HANDLE handle, Type* t) {
+ return Win32ToolhelpTest::First(handle, t);
+ }
+
+ static bool Next(HANDLE handle, Type* t) {
+ return Win32ToolhelpTest::Next(handle, t);
+ }
+
+ static bool CloseHandle(HANDLE handle) {
+ return Win32ToolhelpTest::CloseHandle(handle);
+ }
+};
+
+class BadFirstTraits {
+ public:
+ typedef TestData Type;
+
+ static bool First(HANDLE handle, Type* t) {
+ return Win32ToolhelpTest::Fail(handle, t);
+ }
+
+ static bool Next(HANDLE handle, Type* t) {
+ // This should never be called.
+ ADD_FAILURE();
+ return false;
+ }
+
+ static bool CloseHandle(HANDLE handle) {
+ return Win32ToolhelpTest::CloseHandle(handle);
+ }
+};
+
+class BadNextTraits {
+ public:
+ typedef TestData Type;
+
+ static bool First(HANDLE handle, Type* t) {
+ return Win32ToolhelpTest::First(handle, t);
+ }
+
+ static bool Next(HANDLE handle, Type* t) {
+ return Win32ToolhelpTest::Fail(handle, t);
+ }
+
+ static bool CloseHandle(HANDLE handle) {
+ return Win32ToolhelpTest::CloseHandle(handle);
+ }
+};
+
+// The toolhelp in normally inherited but most of
+// these tests only excercise the methods from the
+// traits therefore I use a typedef to make the
+// test code easier to read.
+typedef rtc::ToolhelpEnumeratorBase<TestTraits> EnumeratorForTest;
+
+TEST_F(Win32ToolhelpTest, TestNextWithInvalidCtorHandle) {
+ EnumeratorForTest t(INVALID_HANDLE_VALUE);
+
+ EXPECT_FALSE(t.Next());
+ EXPECT_TRUE(CheckCallCounters(0, 0, 0, 0));
+}
+
+// Tests that Next() returns false if the first-pointer
+// function fails.
+TEST_F(Win32ToolhelpTest, TestNextFirstFails) {
+ typedef rtc::ToolhelpEnumeratorBase<BadFirstTraits> BadEnumerator;
+ rtc::scoped_ptr<BadEnumerator> t(new BadEnumerator(AsHandle()));
+
+ // If next ever fails it shall always fail.
+ EXPECT_FALSE(t->Next());
+ EXPECT_FALSE(t->Next());
+ EXPECT_FALSE(t->Next());
+ t.reset();
+ EXPECT_TRUE(CheckCallCounters(0, 0, 1, 1));
+}
+
+// Tests that Next() returns false if the next-pointer
+// function fails.
+TEST_F(Win32ToolhelpTest, TestNextNextFails) {
+ typedef rtc::ToolhelpEnumeratorBase<BadNextTraits> BadEnumerator;
+ rtc::scoped_ptr<BadEnumerator> t(new BadEnumerator(AsHandle()));
+
+ // If next ever fails it shall always fail. No more calls
+ // shall be dispatched to Next(...).
+ EXPECT_TRUE(t->Next());
+ EXPECT_FALSE(t->Next());
+ EXPECT_FALSE(t->Next());
+ t.reset();
+ EXPECT_TRUE(CheckCallCounters(1, 0, 1, 1));
+}
+
+
+// Tests that current returns an object is all zero's
+// if Next() hasn't been called.
+TEST_F(Win32ToolhelpTest, TestCurrentNextNotCalled) {
+ rtc::scoped_ptr<EnumeratorForTest> t(new EnumeratorForTest(AsHandle()));
+ EXPECT_TRUE(AllZero(t->current()));
+ t.reset();
+ EXPECT_TRUE(CheckCallCounters(0, 0, 0, 1));
+}
+
+// Tests the simple everything works path through the code.
+TEST_F(Win32ToolhelpTest, TestCurrentNextCalled) {
+ rtc::scoped_ptr<EnumeratorForTest> t(new EnumeratorForTest(AsHandle()));
+
+ EXPECT_TRUE(t->Next());
+ EXPECT_TRUE(Equals(t->current(), kTestData[0]));
+ EXPECT_TRUE(t->Next());
+ EXPECT_TRUE(Equals(t->current(), kTestData[1]));
+ EXPECT_TRUE(t->Next());
+ EXPECT_TRUE(Equals(t->current(), kTestData[2]));
+ EXPECT_FALSE(t->Next());
+ t.reset();
+ EXPECT_TRUE(CheckCallCounters(1, 3, 0, 1));
+}
+
+TEST_F(Win32ToolhelpTest, TestCurrentProcess) {
+ WCHAR buf[MAX_PATH];
+ GetModuleFileName(NULL, buf, ARRAY_SIZE(buf));
+ std::wstring name = ToUtf16(Pathname(ToUtf8(buf)).filename());
+
+ rtc::ProcessEnumerator processes;
+ bool found = false;
+ while (processes.Next()) {
+ if (!name.compare(processes.current().szExeFile)) {
+ found = true;
+ break;
+ }
+ }
+ EXPECT_TRUE(found);
+
+ rtc::ModuleEnumerator modules(processes.current().th32ProcessID);
+ found = false;
+ while (modules.Next()) {
+ if (!name.compare(modules.current().szModule)) {
+ found = true;
+ break;
+ }
+ }
+ EXPECT_TRUE(found);
+}
+
+} // namespace rtc