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";
21 void SetFlagTask(bool* success
) {
26 scoped_refptr
<base::TaskRunner
> task_runner
,
28 task_runner
->PostTask(FROM_HERE
, base::Bind(&SetFlagTask
, success
));
32 void CheckComAptTypeTask(APTTYPE
* apt_type_out
, HRESULT
* hresult
) {
33 typedef HRESULT (WINAPI
* CoGetApartmentTypeFunc
)
34 (APTTYPE
*, APTTYPEQUALIFIER
*);
36 // CoGetApartmentType requires Windows 7 or above.
37 if (base::win::GetVersion() < base::win::VERSION_WIN7
) {
42 // Dynamic link to the API so the same test binary can run on older systems.
43 base::ScopedNativeLibrary
com_library(base::FilePath(L
"ole32.dll"));
44 ASSERT_TRUE(com_library
.is_valid());
45 CoGetApartmentTypeFunc co_get_apartment_type
=
46 reinterpret_cast<CoGetApartmentTypeFunc
>(
47 com_library
.GetFunctionPointer("CoGetApartmentType"));
48 ASSERT_TRUE(co_get_apartment_type
!= NULL
);
50 APTTYPEQUALIFIER apt_type_qualifier
;
51 *hresult
= (*co_get_apartment_type
)(apt_type_out
, &apt_type_qualifier
);
59 class AutoThreadTest
: public testing::Test
{
61 AutoThreadTest() : message_loop_quit_correctly_(false) {
64 void RunMessageLoop() {
65 // Release |main_task_runner_|, then run |message_loop_| until other
66 // references created in tests are gone. We also post a delayed quit
67 // task to |message_loop_| so the test will not hang on failure.
68 main_task_runner_
= NULL
;
69 message_loop_
.PostDelayedTask(FROM_HERE
,
70 base::MessageLoop::QuitClosure(),
71 base::TimeDelta::FromSeconds(5));
75 virtual void SetUp() OVERRIDE
{
76 main_task_runner_
= new AutoThreadTaskRunner(
77 message_loop_
.message_loop_proxy(),
78 base::Bind(&AutoThreadTest::QuitMainMessageLoop
,
79 base::Unretained(this)));
82 virtual void TearDown() OVERRIDE
{
83 // Verify that |message_loop_| was quit by the AutoThreadTaskRunner.
84 EXPECT_TRUE(message_loop_quit_correctly_
);
88 void QuitMainMessageLoop() {
89 message_loop_quit_correctly_
= true;
90 message_loop_
.PostTask(FROM_HERE
, base::MessageLoop::QuitClosure());
93 base::MessageLoop message_loop_
;
94 bool message_loop_quit_correctly_
;
95 scoped_refptr
<AutoThreadTaskRunner
> main_task_runner_
;
98 TEST_F(AutoThreadTest
, StartAndStop
) {
99 // Create an AutoThread joined by our MessageLoop.
100 scoped_refptr
<base::TaskRunner
> task_runner
=
101 AutoThread::Create(kThreadName
, main_task_runner_
);
102 EXPECT_TRUE(task_runner
.get());
108 TEST_F(AutoThreadTest
, ProcessTask
) {
109 // Create an AutoThread joined by our MessageLoop.
110 scoped_refptr
<base::TaskRunner
> task_runner
=
111 AutoThread::Create(kThreadName
, main_task_runner_
);
112 EXPECT_TRUE(task_runner
.get());
114 // Post a task to it.
115 bool success
= false;
116 task_runner
->PostTask(FROM_HERE
, base::Bind(&SetFlagTask
, &success
));
121 EXPECT_TRUE(success
);
124 TEST_F(AutoThreadTest
, ThreadDependency
) {
125 // Create two AutoThreads joined by our MessageLoop.
126 scoped_refptr
<base::TaskRunner
> task_runner1
=
127 AutoThread::Create(kThreadName
, main_task_runner_
);
128 EXPECT_TRUE(task_runner1
.get());
129 scoped_refptr
<base::TaskRunner
> task_runner2
=
130 AutoThread::Create(kThreadName
, main_task_runner_
);
131 EXPECT_TRUE(task_runner2
.get());
133 // Post a task to thread 1 that will post a task to thread 2.
134 bool success
= false;
135 task_runner1
->PostTask(FROM_HERE
,
136 base::Bind(&PostSetFlagTask
, task_runner2
, &success
));
142 EXPECT_TRUE(success
);
146 TEST_F(AutoThreadTest
, ThreadWithComMta
) {
147 scoped_refptr
<base::TaskRunner
> task_runner
=
148 AutoThread::CreateWithLoopAndComInitTypes(kThreadName
,
150 base::MessageLoop::TYPE_DEFAULT
,
151 AutoThread::COM_INIT_MTA
);
152 EXPECT_TRUE(task_runner
.get());
154 // Post a task to query the COM apartment type.
155 HRESULT hresult
= E_FAIL
;
156 APTTYPE apt_type
= APTTYPE_NA
;
157 task_runner
->PostTask(FROM_HERE
,
158 base::Bind(&CheckComAptTypeTask
, &apt_type
, &hresult
));
163 // CoGetApartmentType requires Windows 7 or above.
164 if (base::win::GetVersion() >= base::win::VERSION_WIN7
) {
165 EXPECT_EQ(S_OK
, hresult
);
166 EXPECT_EQ(APTTYPE_MTA
, apt_type
);
168 EXPECT_EQ(E_NOTIMPL
, hresult
);
172 TEST_F(AutoThreadTest
, ThreadWithComSta
) {
173 scoped_refptr
<base::TaskRunner
> task_runner
=
174 AutoThread::CreateWithLoopAndComInitTypes(kThreadName
,
176 base::MessageLoop::TYPE_UI
,
177 AutoThread::COM_INIT_STA
);
178 EXPECT_TRUE(task_runner
.get());
180 // Post a task to query the COM apartment type.
181 HRESULT hresult
= E_FAIL
;
182 APTTYPE apt_type
= APTTYPE_NA
;
183 task_runner
->PostTask(FROM_HERE
,
184 base::Bind(&CheckComAptTypeTask
, &apt_type
, &hresult
));
189 // CoGetApartmentType requires Windows 7 or above.
190 if (base::win::GetVersion() >= base::win::VERSION_WIN7
) {
191 EXPECT_EQ(S_OK
, hresult
);
192 // Whether the thread is the "main" STA apartment depends upon previous
193 // COM activity in this test process, so allow both types here.
194 EXPECT_TRUE(apt_type
== APTTYPE_MAINSTA
|| apt_type
== APTTYPE_STA
);
196 EXPECT_EQ(E_NOTIMPL
, hresult
);
199 #endif // defined(OS_WIN)
201 } // namespace remoting