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(
71 FROM_HERE
, MessageLoop::QuitClosure(), 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
, MessageLoop::QuitClosure());
93 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(
149 kThreadName
, main_task_runner_
, MessageLoop::TYPE_DEFAULT
,
150 AutoThread::COM_INIT_MTA
);
151 EXPECT_TRUE(task_runner
.get());
153 // Post a task to query the COM apartment type.
154 HRESULT hresult
= E_FAIL
;
155 APTTYPE apt_type
= APTTYPE_NA
;
156 task_runner
->PostTask(FROM_HERE
,
157 base::Bind(&CheckComAptTypeTask
, &apt_type
, &hresult
));
162 // CoGetApartmentType requires Windows 7 or above.
163 if (base::win::GetVersion() >= base::win::VERSION_WIN7
) {
164 EXPECT_EQ(S_OK
, hresult
);
165 EXPECT_EQ(APTTYPE_MTA
, apt_type
);
167 EXPECT_EQ(E_NOTIMPL
, hresult
);
171 TEST_F(AutoThreadTest
, ThreadWithComSta
) {
172 scoped_refptr
<base::TaskRunner
> task_runner
=
173 AutoThread::CreateWithLoopAndComInitTypes(
174 kThreadName
, main_task_runner_
, MessageLoop::TYPE_UI
,
175 AutoThread::COM_INIT_STA
);
176 EXPECT_TRUE(task_runner
.get());
178 // Post a task to query the COM apartment type.
179 HRESULT hresult
= E_FAIL
;
180 APTTYPE apt_type
= APTTYPE_NA
;
181 task_runner
->PostTask(FROM_HERE
,
182 base::Bind(&CheckComAptTypeTask
, &apt_type
, &hresult
));
187 // CoGetApartmentType requires Windows 7 or above.
188 if (base::win::GetVersion() >= base::win::VERSION_WIN7
) {
189 EXPECT_EQ(S_OK
, hresult
);
190 // Whether the thread is the "main" STA apartment depends upon previous
191 // COM activity in this test process, so allow both types here.
192 EXPECT_TRUE(apt_type
== APTTYPE_MAINSTA
|| apt_type
== APTTYPE_STA
);
194 EXPECT_EQ(E_NOTIMPL
, hresult
);
197 #endif // defined(OS_WIN)
199 } // namespace remoting