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/test/fake_iasync_operation_win.h"
6
7 #include <asyncinfo.h>
8 #include <wrl/event.h>
9 #include <wrl/implements.h>
10
11 #include "base/test/async_results_test_values_win.h"
12 #include "testing/gtest/include/gtest/gtest-spi.h"
13 #include "testing/gtest/include/gtest/gtest.h"
14
15 using ABI::Windows::Foundation::IAsyncOperation;
16 using ABI::Windows::Foundation::IAsyncOperationCompletedHandler;
17 using Microsoft::WRL::Callback;
18 using Microsoft::WRL::Make;
19
20 namespace base {
21 namespace win {
22 namespace {
23 constexpr HRESULT kTestError = 0x87654321;
24 }
25
26 template <typename T>
27 class FakeIAsyncOperationTest : public ::testing::Test {};
28
29 TYPED_TEST_SUITE_P(FakeIAsyncOperationTest);
30
TYPED_TEST_P(FakeIAsyncOperationTest,MultipleCompletedHandlers)31 TYPED_TEST_P(FakeIAsyncOperationTest, MultipleCompletedHandlers) {
32 auto operation = Make<FakeIAsyncOperation<TypeParam>>();
33 auto handler = Callback<IAsyncOperationCompletedHandler<TypeParam>>(
34 [](auto async_operation, AsyncStatus async_status) { return S_OK; });
35 ASSERT_HRESULT_SUCCEEDED(operation->put_Completed(handler.Get()));
36 EXPECT_NONFATAL_FAILURE(
37 ASSERT_HRESULT_SUCCEEDED(operation->put_Completed(handler.Get()));
38 , "put_Completed");
39 }
40
TYPED_TEST_P(FakeIAsyncOperationTest,MultipleCompletions)41 TYPED_TEST_P(FakeIAsyncOperationTest, MultipleCompletions) {
42 auto operation = Make<FakeIAsyncOperation<TypeParam>>();
43 base::test::AsyncResultsTestValues<TypeParam> test_values;
44 ASSERT_NO_FATAL_FAILURE(
45 operation->CompleteWithResults(test_values.GetTestValue_T()));
46 // EXPECT_FATAL_FAILURE() can only reference globals and statics.
47 // https://github.com/google/googletest/blob/main/docs/advanced.md#catching-failures
48 static auto test_value_t = test_values.GetTestValue_T();
49 static auto& static_operation = operation;
50 EXPECT_FATAL_FAILURE(static_operation->CompleteWithResults(test_value_t),
51 "already completed");
52
53 operation = Make<FakeIAsyncOperation<TypeParam>>();
54 static_operation = operation;
55 ASSERT_NO_FATAL_FAILURE(operation->CompleteWithError(E_FAIL));
56 EXPECT_FATAL_FAILURE(static_operation->CompleteWithError(E_FAIL),
57 "already completed");
58
59 operation = Make<FakeIAsyncOperation<TypeParam>>();
60 static_operation = operation;
61 ASSERT_NO_FATAL_FAILURE(operation->CompleteWithError(E_FAIL));
62 EXPECT_FATAL_FAILURE(static_operation->CompleteWithResults(test_value_t),
63 "already completed");
64
65 operation = Make<FakeIAsyncOperation<TypeParam>>();
66 static_operation = operation;
67 ASSERT_NO_FATAL_FAILURE(
68 operation->CompleteWithResults(test_values.GetTestValue_T()));
69 EXPECT_FATAL_FAILURE(static_operation->CompleteWithError(E_FAIL),
70 "already completed");
71 }
72
TYPED_TEST_P(FakeIAsyncOperationTest,CompleteWithResults_WithHandler)73 TYPED_TEST_P(FakeIAsyncOperationTest, CompleteWithResults_WithHandler) {
74 auto operation = Make<FakeIAsyncOperation<TypeParam>>();
75
76 bool completed_handler_called = false;
77 ASSERT_HRESULT_SUCCEEDED(operation->put_Completed(
78 Callback<IAsyncOperationCompletedHandler<TypeParam>>(
79 [operation, &completed_handler_called](auto async_operation,
80 AsyncStatus async_status) {
81 completed_handler_called = true;
82 EXPECT_EQ(operation.Get(), async_operation);
83 EXPECT_EQ(async_status, AsyncStatus::Completed);
84 return S_OK;
85 })
86 .Get()));
87 ASSERT_FALSE(completed_handler_called);
88 AsyncStatus async_status;
89 ASSERT_HRESULT_SUCCEEDED(operation->get_Status(&async_status));
90 ASSERT_EQ(async_status, AsyncStatus::Started);
91 HRESULT error_code;
92 ASSERT_HRESULT_SUCCEEDED(operation->get_ErrorCode(&error_code));
93 ASSERT_EQ(error_code, S_OK);
94 base::test::AsyncResultsTestValues<TypeParam> test_values;
95 auto results = test_values.GetDefaultValue_AsyncResultsT();
96 EXPECT_NONFATAL_FAILURE(
97 ASSERT_HRESULT_FAILED(operation->GetResults(&results)), "GetResults");
98
99 operation->CompleteWithResults(test_values.GetTestValue_AsyncResultsT());
100 ASSERT_TRUE(completed_handler_called);
101 ASSERT_HRESULT_SUCCEEDED(operation->get_Status(&async_status));
102 ASSERT_EQ(async_status, AsyncStatus::Completed);
103 ASSERT_HRESULT_SUCCEEDED(operation->get_ErrorCode(&error_code));
104 ASSERT_EQ(error_code, S_OK);
105 ASSERT_HRESULT_SUCCEEDED(operation->GetResults(&results));
106 ASSERT_EQ(results, test_values.GetTestValue_AsyncResultsT());
107 }
108
TYPED_TEST_P(FakeIAsyncOperationTest,CompleteWithResults_WithoutHandler)109 TYPED_TEST_P(FakeIAsyncOperationTest, CompleteWithResults_WithoutHandler) {
110 auto operation = Make<FakeIAsyncOperation<TypeParam>>();
111
112 AsyncStatus async_status;
113 ASSERT_HRESULT_SUCCEEDED(operation->get_Status(&async_status));
114 ASSERT_EQ(async_status, AsyncStatus::Started);
115 HRESULT error_code;
116 ASSERT_HRESULT_SUCCEEDED(operation->get_ErrorCode(&error_code));
117 ASSERT_EQ(error_code, S_OK);
118 base::test::AsyncResultsTestValues<TypeParam> test_values;
119 auto results = test_values.GetDefaultValue_AsyncResultsT();
120 EXPECT_NONFATAL_FAILURE(
121 ASSERT_HRESULT_FAILED(operation->GetResults(&results)), "GetResults");
122
123 operation->CompleteWithResults(test_values.GetTestValue_AsyncResultsT());
124 ASSERT_HRESULT_SUCCEEDED(operation->get_Status(&async_status));
125 ASSERT_EQ(async_status, AsyncStatus::Completed);
126 ASSERT_HRESULT_SUCCEEDED(operation->get_ErrorCode(&error_code));
127 ASSERT_EQ(error_code, S_OK);
128 ASSERT_HRESULT_SUCCEEDED(operation->GetResults(&results));
129 ASSERT_EQ(results, test_values.GetTestValue_AsyncResultsT());
130 }
131
TYPED_TEST_P(FakeIAsyncOperationTest,CompleteWithError_WithHandler)132 TYPED_TEST_P(FakeIAsyncOperationTest, CompleteWithError_WithHandler) {
133 auto operation = Make<FakeIAsyncOperation<TypeParam>>();
134
135 bool completed_handler_called = false;
136 ASSERT_HRESULT_SUCCEEDED(operation->put_Completed(
137 Callback<IAsyncOperationCompletedHandler<TypeParam>>(
138 [operation, &completed_handler_called](auto async_operation,
139 AsyncStatus async_status) {
140 completed_handler_called = true;
141 EXPECT_EQ(operation.Get(), async_operation);
142 EXPECT_EQ(async_status, AsyncStatus::Error);
143 return S_OK;
144 })
145 .Get()));
146 ASSERT_FALSE(completed_handler_called);
147 AsyncStatus async_status;
148 ASSERT_HRESULT_SUCCEEDED(operation->get_Status(&async_status));
149 ASSERT_EQ(async_status, AsyncStatus::Started);
150 HRESULT error_code;
151 ASSERT_HRESULT_SUCCEEDED(operation->get_ErrorCode(&error_code));
152 ASSERT_EQ(error_code, S_OK);
153 base::test::AsyncResultsTestValues<TypeParam> test_values;
154 auto results = test_values.GetDefaultValue_AsyncResultsT();
155 EXPECT_NONFATAL_FAILURE(
156 ASSERT_HRESULT_FAILED(operation->GetResults(&results)), "GetResults");
157
158 operation->CompleteWithError(kTestError);
159 ASSERT_TRUE(completed_handler_called);
160 ASSERT_HRESULT_SUCCEEDED(operation->get_Status(&async_status));
161 ASSERT_EQ(async_status, AsyncStatus::Error);
162 ASSERT_HRESULT_SUCCEEDED(operation->get_ErrorCode(&error_code));
163 ASSERT_EQ(error_code, kTestError);
164 ASSERT_HRESULT_FAILED(operation->GetResults(&results));
165 }
166
TYPED_TEST_P(FakeIAsyncOperationTest,CompleteWithError_WithoutHandler)167 TYPED_TEST_P(FakeIAsyncOperationTest, CompleteWithError_WithoutHandler) {
168 auto operation = Make<FakeIAsyncOperation<TypeParam>>();
169
170 AsyncStatus async_status;
171 ASSERT_HRESULT_SUCCEEDED(operation->get_Status(&async_status));
172 ASSERT_EQ(async_status, AsyncStatus::Started);
173 HRESULT error_code;
174 ASSERT_HRESULT_SUCCEEDED(operation->get_ErrorCode(&error_code));
175 ASSERT_EQ(error_code, S_OK);
176 base::test::AsyncResultsTestValues<TypeParam> test_values;
177 auto results = test_values.GetDefaultValue_AsyncResultsT();
178 EXPECT_NONFATAL_FAILURE(
179 ASSERT_HRESULT_FAILED(operation->GetResults(&results)), "GetResults");
180
181 operation->CompleteWithError(kTestError);
182 ASSERT_HRESULT_SUCCEEDED(operation->get_Status(&async_status));
183 ASSERT_EQ(async_status, AsyncStatus::Error);
184 ASSERT_HRESULT_SUCCEEDED(operation->get_ErrorCode(&error_code));
185 ASSERT_EQ(error_code, kTestError);
186 ASSERT_HRESULT_FAILED(operation->GetResults(&results));
187 }
188
189 REGISTER_TYPED_TEST_SUITE_P(FakeIAsyncOperationTest,
190 MultipleCompletedHandlers,
191 MultipleCompletions,
192 CompleteWithResults_WithHandler,
193 CompleteWithResults_WithoutHandler,
194 CompleteWithError_WithHandler,
195 CompleteWithError_WithoutHandler);
196
197 INSTANTIATE_TYPED_TEST_SUITE_P(Win,
198 FakeIAsyncOperationTest,
199 base::test::AsyncResultsTestValuesTypes);
200
201 } // namespace win
202 } // namespace base
203