1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
6 #include "base/files/file_path.h"
7 #include "base/memory/ref_counted.h"
8 #include "base/scoped_native_library.h"
9 #include "remoting/base/auto_thread.h"
10 #include "testing/gtest/include/gtest/gtest.h"
14 #include "base/win/windows_version.h"
19 const char kThreadName
[] = "Test thread";
20 const char kThreadName2
[] = "Test thread 2";
22 void SetFlagTask(bool* success
) {
27 scoped_refptr
<base::TaskRunner
> task_runner
,
29 task_runner
->PostTask(FROM_HERE
, base::Bind(&SetFlagTask
, success
));
33 void CheckComAptTypeTask(APTTYPE
* apt_type_out
, HRESULT
* hresult
) {
34 typedef HRESULT (WINAPI
* CoGetApartmentTypeFunc
)
35 (APTTYPE
*, APTTYPEQUALIFIER
*);
37 // CoGetApartmentType requires Windows 7 or above.
38 if (base::win::GetVersion() < base::win::VERSION_WIN7
) {
43 // Dynamic link to the API so the same test binary can run on older systems.
44 base::ScopedNativeLibrary
com_library(base::FilePath(L
"ole32.dll"));
45 ASSERT_TRUE(com_library
.is_valid());
46 CoGetApartmentTypeFunc co_get_apartment_type
=
47 static_cast<CoGetApartmentTypeFunc
>(
48 com_library
.GetFunctionPointer("CoGetApartmentType"));
49 ASSERT_TRUE(co_get_apartment_type
!= NULL
);
51 APTTYPEQUALIFIER apt_type_qualifier
;
52 *hresult
= (*co_get_apartment_type
)(apt_type_out
, &apt_type_qualifier
);
60 class AutoThreadTest
: public testing::Test
{
62 AutoThreadTest() : message_loop_quit_correctly_(false) {
65 void RunMessageLoop() {
66 // Release |main_task_runner_|, then run |message_loop_| until other
67 // references created in tests are gone. We also post a delayed quit
68 // task to |message_loop_| so the test will not hang on failure.
69 main_task_runner_
= NULL
;
70 message_loop_
.PostDelayedTask(FROM_HERE
,
71 base::MessageLoop::QuitClosure(),
72 base::TimeDelta::FromSeconds(5));
76 virtual void SetUp() OVERRIDE
{
77 main_task_runner_
= new AutoThreadTaskRunner(
78 message_loop_
.message_loop_proxy(),
79 base::Bind(&AutoThreadTest::QuitMainMessageLoop
,
80 base::Unretained(this)));
83 virtual void TearDown() OVERRIDE
{
84 // Verify that |message_loop_| was quit by the AutoThreadTaskRunner.
85 EXPECT_TRUE(message_loop_quit_correctly_
);
89 void QuitMainMessageLoop() {
90 message_loop_quit_correctly_
= true;
91 message_loop_
.PostTask(FROM_HERE
, base::MessageLoop::QuitClosure());
94 base::MessageLoop message_loop_
;
95 bool message_loop_quit_correctly_
;
96 scoped_refptr
<AutoThreadTaskRunner
> main_task_runner_
;
99 TEST_F(AutoThreadTest
, StartAndStop
) {
100 // Create an AutoThread joined by our MessageLoop.
101 scoped_refptr
<base::TaskRunner
> task_runner
=
102 AutoThread::Create(kThreadName
, main_task_runner_
);
103 EXPECT_TRUE(task_runner
.get());
109 TEST_F(AutoThreadTest
, ProcessTask
) {
110 // Create an AutoThread joined by our MessageLoop.
111 scoped_refptr
<base::TaskRunner
> task_runner
=
112 AutoThread::Create(kThreadName
, main_task_runner_
);
113 EXPECT_TRUE(task_runner
.get());
115 // Post a task to it.
116 bool success
= false;
117 task_runner
->PostTask(FROM_HERE
, base::Bind(&SetFlagTask
, &success
));
122 EXPECT_TRUE(success
);
125 TEST_F(AutoThreadTest
, ThreadDependency
) {
126 // Create two AutoThreads joined by our MessageLoop.
127 scoped_refptr
<base::TaskRunner
> task_runner1
=
128 AutoThread::Create(kThreadName
, main_task_runner_
);
129 EXPECT_TRUE(task_runner1
.get());
130 scoped_refptr
<base::TaskRunner
> task_runner2
=
131 AutoThread::Create(kThreadName
, main_task_runner_
);
132 EXPECT_TRUE(task_runner2
.get());
134 // Post a task to thread 1 that will post a task to thread 2.
135 bool success
= false;
136 task_runner1
->PostTask(FROM_HERE
,
137 base::Bind(&PostSetFlagTask
, task_runner2
, &success
));
143 EXPECT_TRUE(success
);
147 TEST_F(AutoThreadTest
, ThreadWithComMta
) {
148 scoped_refptr
<base::TaskRunner
> task_runner
=
149 AutoThread::CreateWithLoopAndComInitTypes(kThreadName
,
151 base::MessageLoop::TYPE_DEFAULT
,
152 AutoThread::COM_INIT_MTA
);
153 EXPECT_TRUE(task_runner
.get());
155 // Post a task to query the COM apartment type.
156 HRESULT hresult
= E_FAIL
;
157 APTTYPE apt_type
= APTTYPE_NA
;
158 task_runner
->PostTask(FROM_HERE
,
159 base::Bind(&CheckComAptTypeTask
, &apt_type
, &hresult
));
164 // CoGetApartmentType requires Windows 7 or above.
165 if (base::win::GetVersion() >= base::win::VERSION_WIN7
) {
166 EXPECT_EQ(S_OK
, hresult
);
167 EXPECT_EQ(APTTYPE_MTA
, apt_type
);
169 EXPECT_EQ(E_NOTIMPL
, hresult
);
173 TEST_F(AutoThreadTest
, ThreadWithComSta
) {
174 scoped_refptr
<base::TaskRunner
> task_runner
=
175 AutoThread::CreateWithLoopAndComInitTypes(kThreadName
,
177 base::MessageLoop::TYPE_UI
,
178 AutoThread::COM_INIT_STA
);
179 EXPECT_TRUE(task_runner
.get());
181 // Post a task to query the COM apartment type.
182 HRESULT hresult
= E_FAIL
;
183 APTTYPE apt_type
= APTTYPE_NA
;
184 task_runner
->PostTask(FROM_HERE
,
185 base::Bind(&CheckComAptTypeTask
, &apt_type
, &hresult
));
190 // CoGetApartmentType requires Windows 7 or above.
191 if (base::win::GetVersion() >= base::win::VERSION_WIN7
) {
192 EXPECT_EQ(S_OK
, hresult
);
193 // Whether the thread is the "main" STA apartment depends upon previous
194 // COM activity in this test process, so allow both types here.
195 EXPECT_TRUE(apt_type
== APTTYPE_MAINSTA
|| apt_type
== APTTYPE_STA
);
197 EXPECT_EQ(E_NOTIMPL
, hresult
);
200 #endif // defined(OS_WIN)
202 } // namespace remoting