1 // Copyright 2020 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "base/win/post_async_results.h"
6
7 #include "base/test/async_results_test_values_win.h"
8 #include "base/test/bind.h"
9 #include "base/test/fake_iasync_operation_win.h"
10 #include "base/test/task_environment.h"
11 #include "testing/gtest/include/gtest/gtest.h"
12
13 using ABI::Windows::Foundation::IAsyncOperation;
14 using Microsoft::WRL::ComPtr;
15
16 namespace base {
17 namespace win {
18
19 template <typename T>
20 class PostAsyncResultsTest : public ::testing::Test {};
21
22 TYPED_TEST_SUITE_P(PostAsyncResultsTest);
23
TYPED_TEST_P(PostAsyncResultsTest,GetAsyncResultsT_Success)24 TYPED_TEST_P(PostAsyncResultsTest, GetAsyncResultsT_Success) {
25 auto fake_iasync_op = Microsoft::WRL::Make<FakeIAsyncOperation<TypeParam>>();
26 ComPtr<IAsyncOperation<TypeParam>> async_op;
27 ASSERT_HRESULT_SUCCEEDED(fake_iasync_op.As(&async_op));
28
29 base::test::AsyncResultsTestValues<TypeParam> templated_values;
30 ASSERT_NO_FATAL_FAILURE(
31 fake_iasync_op->CompleteWithResults(templated_values.GetTestValue_T()));
32
33 AsyncStatus async_status;
34 ASSERT_HRESULT_SUCCEEDED(fake_iasync_op->get_Status(&async_status));
35
36 auto value_received = templated_values.GetDefaultValue_AsyncResultsT();
37 ASSERT_HRESULT_SUCCEEDED(internal::GetAsyncResultsT(
38 async_op.Get(), async_status, &value_received));
39 ASSERT_EQ(templated_values.GetTestValue_AsyncResultsT(), value_received);
40 }
41
TYPED_TEST_P(PostAsyncResultsTest,GetAsyncResultsT_Failure)42 TYPED_TEST_P(PostAsyncResultsTest, GetAsyncResultsT_Failure) {
43 auto fake_iasync_op = Microsoft::WRL::Make<FakeIAsyncOperation<TypeParam>>();
44 ComPtr<IAsyncOperation<TypeParam>> async_op;
45 ASSERT_HRESULT_SUCCEEDED(fake_iasync_op.As(&async_op));
46
47 HRESULT test_error = (HRESULT)0x87654321L;
48 ASSERT_NO_FATAL_FAILURE(fake_iasync_op->CompleteWithError(test_error));
49
50 AsyncStatus async_status;
51 ASSERT_HRESULT_SUCCEEDED(fake_iasync_op->get_Status(&async_status));
52
53 base::test::AsyncResultsTestValues<TypeParam> templated_values;
54 auto value_received = templated_values.GetTestValue_AsyncResultsT();
55 ASSERT_EQ(
56 internal::GetAsyncResultsT(async_op.Get(), async_status, &value_received),
57 test_error);
58 ASSERT_EQ(templated_values.GetDefaultValue_AsyncResultsT(), value_received);
59 }
60
TYPED_TEST_P(PostAsyncResultsTest,PostAsyncOperationCompletedHandler_Success)61 TYPED_TEST_P(PostAsyncResultsTest, PostAsyncOperationCompletedHandler_Success) {
62 base::test::SingleThreadTaskEnvironment task_environment;
63 auto fake_iasync_op = Microsoft::WRL::Make<FakeIAsyncOperation<TypeParam>>();
64 ComPtr<IAsyncOperation<TypeParam>> async_op;
65 ASSERT_HRESULT_SUCCEEDED(fake_iasync_op.As(&async_op));
66
67 RunLoop run_loop;
68 auto quit_closure = run_loop.QuitClosure();
69 IAsyncOperation<TypeParam>* async_op_received;
70 AsyncStatus async_status_received = AsyncStatus::Started;
71 internal::IAsyncOperationCompletedHandlerT<TypeParam> completed_handler =
72 base::BindLambdaForTesting(
73 [&](IAsyncOperation<TypeParam>* async_operation,
74 AsyncStatus async_status) {
75 async_op_received = async_operation;
76 async_status_received = async_status;
77 std::move(quit_closure).Run();
78 });
79 ASSERT_HRESULT_SUCCEEDED(internal::PostAsyncOperationCompletedHandler(
80 async_op.Get(), std::move(completed_handler)));
81
82 base::test::AsyncResultsTestValues<TypeParam> templated_values;
83 ASSERT_NO_FATAL_FAILURE(
84 fake_iasync_op->CompleteWithResults(templated_values.GetTestValue_T()));
85 run_loop.Run();
86 ASSERT_EQ(async_op.Get(), async_op_received);
87 ASSERT_EQ(AsyncStatus::Completed, async_status_received);
88 }
89
TYPED_TEST_P(PostAsyncResultsTest,PostAsyncOperationCompletedHandler_Failure)90 TYPED_TEST_P(PostAsyncResultsTest, PostAsyncOperationCompletedHandler_Failure) {
91 base::test::SingleThreadTaskEnvironment task_environment;
92 auto fake_iasync_op = Microsoft::WRL::Make<FakeIAsyncOperation<TypeParam>>();
93 ComPtr<IAsyncOperation<TypeParam>> async_op;
94 ASSERT_HRESULT_SUCCEEDED(fake_iasync_op.As(&async_op));
95
96 RunLoop run_loop;
97 auto quit_closure = run_loop.QuitClosure();
98 IAsyncOperation<TypeParam>* async_op_received;
99 AsyncStatus async_status_received = AsyncStatus::Started;
100 internal::IAsyncOperationCompletedHandlerT<TypeParam> completed_handler =
101 base::BindLambdaForTesting(
102 [&](IAsyncOperation<TypeParam>* async_operation,
103 AsyncStatus async_status) {
104 async_op_received = async_operation;
105 async_status_received = async_status;
106 std::move(quit_closure).Run();
107 });
108 ASSERT_HRESULT_SUCCEEDED(internal::PostAsyncOperationCompletedHandler(
109 async_op.Get(), std::move(completed_handler)));
110
111 ASSERT_NO_FATAL_FAILURE(fake_iasync_op->CompleteWithError(E_FAIL));
112 run_loop.Run();
113 ASSERT_EQ(async_op.Get(), async_op_received);
114 ASSERT_EQ(AsyncStatus::Error, async_status_received);
115 }
116
TYPED_TEST_P(PostAsyncResultsTest,PostAsyncHandlers_OnlySuccessHandler_Success)117 TYPED_TEST_P(PostAsyncResultsTest,
118 PostAsyncHandlers_OnlySuccessHandler_Success) {
119 base::test::SingleThreadTaskEnvironment task_environment;
120 auto fake_iasync_op = Microsoft::WRL::Make<FakeIAsyncOperation<TypeParam>>();
121 ComPtr<IAsyncOperation<TypeParam>> async_op;
122 ASSERT_HRESULT_SUCCEEDED(fake_iasync_op.As(&async_op));
123
124 RunLoop run_loop;
125 auto quit_closure = run_loop.QuitClosure();
126 base::test::AsyncResultsTestValues<TypeParam> templated_values;
127 auto value_received = templated_values.GetDefaultValue_AsyncResultsT();
128 ASSERT_HRESULT_SUCCEEDED(PostAsyncHandlers(
129 async_op.Get(), base::BindLambdaForTesting(
130 [&](internal::AsyncResultsT<TypeParam> result) {
131 value_received = result;
132 std::move(quit_closure).Run();
133 })));
134
135 ASSERT_NO_FATAL_FAILURE(
136 fake_iasync_op->CompleteWithResults(templated_values.GetTestValue_T()));
137 run_loop.Run();
138 ASSERT_EQ(templated_values.GetTestValue_AsyncResultsT(), value_received);
139 }
140
TYPED_TEST_P(PostAsyncResultsTest,PostAsyncHandlers_OnlySuccessHandler_Failure)141 TYPED_TEST_P(PostAsyncResultsTest,
142 PostAsyncHandlers_OnlySuccessHandler_Failure) {
143 base::test::SingleThreadTaskEnvironment task_environment;
144 auto fake_iasync_op = Microsoft::WRL::Make<FakeIAsyncOperation<TypeParam>>();
145 ComPtr<IAsyncOperation<TypeParam>> async_op;
146 ASSERT_HRESULT_SUCCEEDED(fake_iasync_op.As(&async_op));
147
148 RunLoop run_loop;
149 bool success_handler_called = false;
150 ASSERT_HRESULT_SUCCEEDED(PostAsyncHandlers(
151 async_op.Get(), base::BindLambdaForTesting(
152 [&](internal::AsyncResultsT<TypeParam> result) {
153 success_handler_called = true;
154 })));
155
156 HRESULT test_error = (HRESULT)0x87654321L;
157 ASSERT_NO_FATAL_FAILURE(fake_iasync_op->CompleteWithError(test_error));
158 run_loop.RunUntilIdle();
159 ASSERT_FALSE(success_handler_called);
160 }
161
TYPED_TEST_P(PostAsyncResultsTest,PostAsyncHandlers_NoArgsFailureHandler_Success)162 TYPED_TEST_P(PostAsyncResultsTest,
163 PostAsyncHandlers_NoArgsFailureHandler_Success) {
164 base::test::SingleThreadTaskEnvironment task_environment;
165 auto fake_iasync_op = Microsoft::WRL::Make<FakeIAsyncOperation<TypeParam>>();
166 ComPtr<IAsyncOperation<TypeParam>> async_op;
167 ASSERT_HRESULT_SUCCEEDED(fake_iasync_op.As(&async_op));
168
169 RunLoop run_loop;
170 auto quit_closure = run_loop.QuitClosure();
171 base::test::AsyncResultsTestValues<TypeParam> templated_values;
172 auto value_received = templated_values.GetDefaultValue_AsyncResultsT();
173 bool failure_handler_called = false;
174 ASSERT_HRESULT_SUCCEEDED(
175 PostAsyncHandlers(async_op.Get(),
176 base::BindLambdaForTesting(
177 [&](internal::AsyncResultsT<TypeParam> result) {
178 value_received = result;
179 std::move(quit_closure).Run();
180 }),
181 base::BindLambdaForTesting([&]() {
182 failure_handler_called = true;
183 std::move(quit_closure).Run();
184 })));
185
186 ASSERT_NO_FATAL_FAILURE(
187 fake_iasync_op->CompleteWithResults(templated_values.GetTestValue_T()));
188 run_loop.Run();
189 ASSERT_EQ(templated_values.GetTestValue_AsyncResultsT(), value_received);
190 ASSERT_FALSE(failure_handler_called);
191 }
192
TYPED_TEST_P(PostAsyncResultsTest,PostAsyncHandlers_NoArgsFailureHandler_Failure)193 TYPED_TEST_P(PostAsyncResultsTest,
194 PostAsyncHandlers_NoArgsFailureHandler_Failure) {
195 base::test::SingleThreadTaskEnvironment task_environment;
196 auto fake_iasync_op = Microsoft::WRL::Make<FakeIAsyncOperation<TypeParam>>();
197 ComPtr<IAsyncOperation<TypeParam>> async_op;
198 ASSERT_HRESULT_SUCCEEDED(fake_iasync_op.As(&async_op));
199
200 RunLoop run_loop;
201 auto quit_closure = run_loop.QuitClosure();
202 bool failure_handler_called = false;
203 bool success_handler_called = false;
204 ASSERT_HRESULT_SUCCEEDED(
205 PostAsyncHandlers(async_op.Get(),
206 base::BindLambdaForTesting(
207 [&](internal::AsyncResultsT<TypeParam> result) {
208 success_handler_called = true;
209 std::move(quit_closure).Run();
210 }),
211 base::BindLambdaForTesting([&]() {
212 failure_handler_called = true;
213 std::move(quit_closure).Run();
214 })));
215
216 HRESULT test_error = (HRESULT)0x87654321L;
217 ASSERT_NO_FATAL_FAILURE(fake_iasync_op->CompleteWithError(test_error));
218 run_loop.Run();
219 ASSERT_FALSE(success_handler_called);
220 ASSERT_TRUE(failure_handler_called);
221 }
222
TYPED_TEST_P(PostAsyncResultsTest,PostAsyncHandlers_HRESULTFailureHandler_Success)223 TYPED_TEST_P(PostAsyncResultsTest,
224 PostAsyncHandlers_HRESULTFailureHandler_Success) {
225 base::test::SingleThreadTaskEnvironment task_environment;
226 auto fake_iasync_op = Microsoft::WRL::Make<FakeIAsyncOperation<TypeParam>>();
227 ComPtr<IAsyncOperation<TypeParam>> async_op;
228 ASSERT_HRESULT_SUCCEEDED(fake_iasync_op.As(&async_op));
229
230 RunLoop run_loop;
231 auto quit_closure = run_loop.QuitClosure();
232 base::test::AsyncResultsTestValues<TypeParam> templated_values;
233 auto value_received = templated_values.GetDefaultValue_AsyncResultsT();
234 bool failure_handler_called = false;
235 ASSERT_HRESULT_SUCCEEDED(
236 PostAsyncHandlers(async_op.Get(),
237 base::BindLambdaForTesting(
238 [&](internal::AsyncResultsT<TypeParam> result) {
239 value_received = result;
240 std::move(quit_closure).Run();
241 }),
242 base::BindLambdaForTesting([&](HRESULT hr) {
243 failure_handler_called = true;
244 std::move(quit_closure).Run();
245 })));
246
247 ASSERT_NO_FATAL_FAILURE(
248 fake_iasync_op->CompleteWithResults(templated_values.GetTestValue_T()));
249 run_loop.Run();
250 ASSERT_EQ(templated_values.GetTestValue_AsyncResultsT(), value_received);
251 ASSERT_FALSE(failure_handler_called);
252 }
253
TYPED_TEST_P(PostAsyncResultsTest,PostAsyncHandlers_HRESULTFailureHandler_Failure)254 TYPED_TEST_P(PostAsyncResultsTest,
255 PostAsyncHandlers_HRESULTFailureHandler_Failure) {
256 base::test::SingleThreadTaskEnvironment task_environment;
257 auto fake_iasync_op = Microsoft::WRL::Make<FakeIAsyncOperation<TypeParam>>();
258 ComPtr<IAsyncOperation<TypeParam>> async_op;
259 ASSERT_HRESULT_SUCCEEDED(fake_iasync_op.As(&async_op));
260
261 RunLoop run_loop;
262 auto quit_closure = run_loop.QuitClosure();
263 bool success_handler_called = false;
264 HRESULT hr_received = S_OK;
265 ASSERT_HRESULT_SUCCEEDED(
266 PostAsyncHandlers(async_op.Get(),
267 base::BindLambdaForTesting(
268 [&](internal::AsyncResultsT<TypeParam> result) {
269 success_handler_called = true;
270 std::move(quit_closure).Run();
271 }),
272 base::BindLambdaForTesting([&](HRESULT hr) {
273 hr_received = hr;
274 std::move(quit_closure).Run();
275 })));
276
277 HRESULT test_error = (HRESULT)0x87654321L;
278 ASSERT_NO_FATAL_FAILURE(fake_iasync_op->CompleteWithError(test_error));
279 run_loop.Run();
280 ASSERT_FALSE(success_handler_called);
281 ASSERT_EQ(test_error, hr_received);
282 }
283
TYPED_TEST_P(PostAsyncResultsTest,PostAsyncHandlers_HRESULTAndResultFailureHandler_Success)284 TYPED_TEST_P(PostAsyncResultsTest,
285 PostAsyncHandlers_HRESULTAndResultFailureHandler_Success) {
286 base::test::SingleThreadTaskEnvironment task_environment;
287 auto fake_iasync_op = Microsoft::WRL::Make<FakeIAsyncOperation<TypeParam>>();
288 ComPtr<IAsyncOperation<TypeParam>> async_op;
289 ASSERT_HRESULT_SUCCEEDED(fake_iasync_op.As(&async_op));
290
291 RunLoop run_loop;
292 auto quit_closure = run_loop.QuitClosure();
293 base::test::AsyncResultsTestValues<TypeParam> templated_values;
294 auto value_received = templated_values.GetDefaultValue_AsyncResultsT();
295 bool failure_handler_called = false;
296 ASSERT_HRESULT_SUCCEEDED(PostAsyncHandlers(
297 async_op.Get(),
298 base::BindLambdaForTesting(
299 [&](internal::AsyncResultsT<TypeParam> result) {
300 value_received = result;
301 std::move(quit_closure).Run();
302 }),
303 base::BindLambdaForTesting(
304 [&](HRESULT hr, internal::AsyncResultsT<TypeParam> result) {
305 failure_handler_called = true;
306 std::move(quit_closure).Run();
307 })));
308
309 ASSERT_NO_FATAL_FAILURE(
310 fake_iasync_op->CompleteWithResults(templated_values.GetTestValue_T()));
311 run_loop.Run();
312 ASSERT_EQ(templated_values.GetTestValue_AsyncResultsT(), value_received);
313 ASSERT_FALSE(failure_handler_called);
314 }
315
TYPED_TEST_P(PostAsyncResultsTest,PostAsyncHandlers_HRESULTAndResultFailureHandler_Failure)316 TYPED_TEST_P(PostAsyncResultsTest,
317 PostAsyncHandlers_HRESULTAndResultFailureHandler_Failure) {
318 base::test::SingleThreadTaskEnvironment task_environment;
319 auto fake_iasync_op = Microsoft::WRL::Make<FakeIAsyncOperation<TypeParam>>();
320 ComPtr<IAsyncOperation<TypeParam>> async_op;
321 ASSERT_HRESULT_SUCCEEDED(fake_iasync_op.As(&async_op));
322
323 RunLoop run_loop;
324 auto quit_closure = run_loop.QuitClosure();
325 bool success_handler_called = false;
326 HRESULT hr_received = S_OK;
327 base::test::AsyncResultsTestValues<TypeParam> templated_values;
328 auto value_received = templated_values.GetDefaultValue_AsyncResultsT();
329 ASSERT_HRESULT_SUCCEEDED(PostAsyncHandlers(
330 async_op.Get(),
331 base::BindLambdaForTesting(
332 [&](internal::AsyncResultsT<TypeParam> result) {
333 success_handler_called = true;
334 std::move(quit_closure).Run();
335 }),
336 base::BindLambdaForTesting(
337 [&](HRESULT hr, internal::AsyncResultsT<TypeParam> result) {
338 hr_received = hr;
339 value_received = result;
340 std::move(quit_closure).Run();
341 })));
342
343 ASSERT_NO_FATAL_FAILURE(fake_iasync_op->CompleteWithErrorResult(
344 templated_values.GetTestValue_T()));
345 run_loop.Run();
346 ASSERT_FALSE(success_handler_called);
347 ASSERT_HRESULT_SUCCEEDED(hr_received);
348 ASSERT_EQ(templated_values.GetTestValue_AsyncResultsT(), value_received);
349 }
350
TYPED_TEST_P(PostAsyncResultsTest,PostAsyncResults_Success)351 TYPED_TEST_P(PostAsyncResultsTest, PostAsyncResults_Success) {
352 base::test::SingleThreadTaskEnvironment task_environment;
353 auto fake_iasync_op = Microsoft::WRL::Make<FakeIAsyncOperation<TypeParam>>();
354 ComPtr<IAsyncOperation<TypeParam>> async_op;
355 ASSERT_HRESULT_SUCCEEDED(fake_iasync_op.As(&async_op));
356
357 RunLoop run_loop;
358 auto quit_closure = run_loop.QuitClosure();
359 base::test::AsyncResultsTestValues<TypeParam> templated_values;
360 auto value_received = templated_values.GetDefaultValue_AsyncResultsT();
361 ASSERT_HRESULT_SUCCEEDED(PostAsyncResults(
362 async_op, base::BindLambdaForTesting(
363 [&](internal::AsyncResultsT<TypeParam> result) {
364 value_received = result;
365 std::move(quit_closure).Run();
366 })));
367
368 ASSERT_NO_FATAL_FAILURE(
369 fake_iasync_op->CompleteWithResults(templated_values.GetTestValue_T()));
370 run_loop.Run();
371 ASSERT_EQ(templated_values.GetTestValue_AsyncResultsT(), value_received);
372 }
373
TYPED_TEST_P(PostAsyncResultsTest,PostAsyncResults_Failure)374 TYPED_TEST_P(PostAsyncResultsTest, PostAsyncResults_Failure) {
375 base::test::SingleThreadTaskEnvironment task_environment;
376 auto fake_iasync_op = Microsoft::WRL::Make<FakeIAsyncOperation<TypeParam>>();
377 ComPtr<IAsyncOperation<TypeParam>> async_op;
378 ASSERT_HRESULT_SUCCEEDED(fake_iasync_op.As(&async_op));
379
380 RunLoop run_loop;
381 auto quit_closure = run_loop.QuitClosure();
382 base::test::AsyncResultsTestValues<TypeParam> templated_values;
383 auto value_received = templated_values.GetTestValue_AsyncResultsT();
384 ASSERT_HRESULT_SUCCEEDED(PostAsyncResults(
385 async_op, base::BindLambdaForTesting(
386 [&](internal::AsyncResultsT<TypeParam> result) {
387 value_received = result;
388 std::move(quit_closure).Run();
389 })));
390
391 ASSERT_NO_FATAL_FAILURE(fake_iasync_op->CompleteWithError(E_FAIL));
392 run_loop.Run();
393 ASSERT_EQ(templated_values.GetDefaultValue_AsyncResultsT(), value_received);
394 }
395
396 REGISTER_TYPED_TEST_SUITE_P(
397 PostAsyncResultsTest,
398 GetAsyncResultsT_Success,
399 GetAsyncResultsT_Failure,
400 PostAsyncOperationCompletedHandler_Success,
401 PostAsyncOperationCompletedHandler_Failure,
402 PostAsyncHandlers_OnlySuccessHandler_Success,
403 PostAsyncHandlers_OnlySuccessHandler_Failure,
404 PostAsyncHandlers_NoArgsFailureHandler_Success,
405 PostAsyncHandlers_NoArgsFailureHandler_Failure,
406 PostAsyncHandlers_HRESULTFailureHandler_Success,
407 PostAsyncHandlers_HRESULTFailureHandler_Failure,
408 PostAsyncHandlers_HRESULTAndResultFailureHandler_Success,
409 PostAsyncHandlers_HRESULTAndResultFailureHandler_Failure,
410 PostAsyncResults_Success,
411 PostAsyncResults_Failure);
412
413 INSTANTIATE_TYPED_TEST_SUITE_P(Win,
414 PostAsyncResultsTest,
415 base::test::AsyncResultsTestValuesTypes);
416
417 } // namespace win
418 } // namespace base
419