• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2024 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "softbus_conn_async_helper.h"
17 
18 #include <future>
19 
20 #include <gtest/gtest.h>
21 
22 #include "conn_log.h"
23 
24 #include "softbus_conn_common_mock.h"
25 
26 using namespace testing::ext;
27 using namespace testing;
28 
29 namespace OHOS::SoftBus {
30 class ConnAsyncTest : public testing::Test {
31 public:
SetUpTestCase()32     static void SetUpTestCase() { }
33 
TearDownTestCase()34     static void TearDownTestCase() { }
35 
SetUp()36     void SetUp() override { }
37 
TearDown()38     void TearDown() override { }
39 };
40 
41 /*
42  * @tc.name: CreateDestroyAsyncTest
43  * @tc.desc: test create and destroy async instance
44  * @tc.type: FUNC
45  * @tc.require:
46  */
47 HWTEST_F(ConnAsyncTest, CreateDestroyAsyncTest, TestSize.Level1)
48 {
49     auto ret = ConnAsyncConstruct(nullptr, nullptr, nullptr);
50     EXPECT_EQ(ret, SOFTBUS_INVALID_PARAM);
51 
52     ret = ConnAsyncConstruct("test async", nullptr, nullptr);
53     EXPECT_EQ(ret, SOFTBUS_INVALID_PARAM);
54 
55     ConnAsync async {};
56     ret = ConnAsyncConstruct("test async", &async, nullptr);
57     EXPECT_EQ(ret, SOFTBUS_INVALID_PARAM);
58 
59     auto looper = CreateNewLooper("test_Lp");
60     ret = ConnAsyncConstruct("test async", &async, looper);
61     EXPECT_EQ(ret, SOFTBUS_OK);
62     ConnAsyncDestruct(&async);
63     DestroyLooper(looper);
64 }
65 
66 struct TestCase {
67     std::string name;
68     int64_t delayMs;
69     bool cancel;
70 };
71 
72 /*
73  * @tc.name: AsyncOperationTest
74  * @tc.desc: test async call and cancel
75  * @tc.type: FUNC
76  * @tc.require:
77  */
78 HWTEST_F(ConnAsyncTest, AsyncOperationTest, TestSize.Level1)
79 {
80     ConnCommonTestMock mock;
81 
82     ConnAsync async {};
83     auto looper = CreateNewLooper("test_Lp");
84     auto ret = ConnAsyncConstruct("test async", &async, looper);
85     EXPECT_EQ(ret, SOFTBUS_OK);
86 
87     TestCase testcases[] = {
88         {
89          .name = "timeout_0_no_cancel",
90          .delayMs = 0,
91          .cancel = false,
92          },
93         {
94          .name = "timeout_500_no_cancel",
95          .delayMs = 500,
96          .cancel = false,
97          },
98         {
99          .name = "timeout_500_cancel",
100          .delayMs = 500,
101          .cancel = true,
102          }
103     };
104 
105     for (auto &tc : testcases) {
106         std::promise<int32_t> wait;
__anon972a0bee0102(int32_t callId, void *arg) 107         EXPECT_CALL(mock, AsyncFunctionHook).Times(AtMost(1)).WillOnce([&wait, tc](int32_t callId, void *arg) {
108             wait.set_value(callId);
109             CONN_LOGI(CONN_TEST, "async function hook enter, tc name: %{public}s", tc.name.c_str());
110         });
111 
112         auto start = std::chrono::system_clock::now();
113         auto arg = std::make_shared<int>(0);
114         auto callId = ConnAsyncCall(&async, ConnCommonTestMock::asyncFunction_, arg.get(), tc.delayMs);
115         EXPECT_TRUE(callId > 0) << "test case:" << tc.name;
116         if (tc.cancel) {
117             EXPECT_CALL(mock, FreeAsyncArgHook).Times(1);
118             ConnAsyncCancel(&async, callId, ConnCommonTestMock::asyncFreeHook_);
119         }
120         auto future = wait.get_future();
121         auto status = future.wait_for(std::chrono::milliseconds(tc.delayMs + 100));
122         if (tc.cancel) {
123             EXPECT_NE(status, std::future_status::ready) << "test case:" << tc.name;
124         } else {
125             if (status == std::future_status::ready) {
126                 EXPECT_EQ(callId, future.get()) << "test case:" << tc.name;
127             } else {
128                 ADD_FAILURE() << "test case:" << tc.name << ", async function not called";
129             }
130             auto end = std::chrono::system_clock::now();
131             auto pastedMs = std::chrono::duration_cast<std::chrono::duration<int, std::milli>>(end - start).count();
132             EXPECT_GE(pastedMs, tc.delayMs) << "test case:" << tc.name;
133         }
134         testing::Mock::VerifyAndClearExpectations(&mock);
135     }
136 
137     ConnAsyncDestruct(&async);
138     DestroyLooper(looper);
139 }
140 
141 } // namespace OHOS::SoftBus