• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2025 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_rc_collection.h"
17 
18 #include <gtest/gtest.h>
19 
20 #include "softbus_conn_common_mock.h"
21 
22 using namespace testing::ext;
23 using namespace testing;
24 
25 extern "C" {
26 struct DummyObject {
27     SOFT_BUS_RC_OBJECT_BASE;
28     int32_t payload;
29 };
30 }
31 
32 namespace OHOS::SoftBus {
33 class SoftbusRcTest : public testing::Test {
34 public:
SetUpTestCase()35     static void SetUpTestCase() { }
36 
TearDownTestCase()37     static void TearDownTestCase() { }
38 
SetUp()39     void SetUp() override { }
40 
TearDown()41     void TearDown() override { }
42 };
43 
44 /*
45  * @tc.name: ConstructDestructTest
46  * @tc.desc: construct and destruct test
47  * @tc.type: FUNC
48  * @tc.require:
49  */
50 HWTEST_F(SoftbusRcTest, ConstructDestructTest, TestSize.Level1)
51 {
52     ConnCommonTestMock mock;
53 
54     auto ret = SoftBusRcCollectionConstruct(nullptr, nullptr, nullptr);
55     ASSERT_EQ(ret, SOFTBUS_INVALID_PARAM);
56 
57     ret = SoftBusRcCollectionConstruct("nullptr-collection", nullptr, nullptr);
58     ASSERT_EQ(ret, SOFTBUS_INVALID_PARAM);
59 
60     SoftBusRcCollection foo = {};
61     ret = SoftBusRcCollectionConstruct("foo-collection", &foo, nullptr);
62     ASSERT_EQ(ret, SOFTBUS_OK);
63     SoftBusRcCollectionDestruct(&foo);
64 
65     SoftBusRcCollection bar = {};
66     ret = SoftBusRcCollectionConstruct("bar-collection", &bar, ConnCommonTestMock::idGenerator_);
67     ASSERT_EQ(ret, SOFTBUS_OK);
68     SoftBusRcCollectionDestruct(&bar);
69 }
70 
71 /*
72  * @tc.name: ObjectOperationTest
73  * @tc.desc: save, remove and get operation test
74  * @tc.type: FUNC
75  * @tc.require:
76  */
77 HWTEST_F(SoftbusRcTest, ObjectOperationTest, TestSize.Level1)
78 {
79     ConnCommonTestMock mock;
__anon65fd881a0102(const SoftBusRcObject *object, uint16_t index) 80     EXPECT_CALL(mock, IdGeneratorHook).Times(1).WillRepeatedly(([](const SoftBusRcObject *object, uint16_t index) {
81         return (uint32_t)index;
82     }));
83     EXPECT_CALL(mock, FreeObjectHook).Times(0);
84 
85     SoftBusRcCollection collection = {};
86     auto ret = SoftBusRcCollectionConstruct("foo-collection", &collection, ConnCommonTestMock::idGenerator_);
87     ASSERT_EQ(ret, SOFTBUS_OK);
88 
89     auto arf = std::make_shared<DummyObject>();
90     auto foo = arf.get();
91     ret =
92         SoftBusRcObjectConstruct("foo-object", reinterpret_cast<SoftBusRcObject *>(foo), ConnCommonTestMock::freeHook_);
93     EXPECT_EQ(ret, SOFTBUS_OK);
94     const int32_t payload = 100;
95     foo->payload = payload;
96     ret = SoftBusRcSave(&collection, reinterpret_cast<SoftBusRcObject *>(foo));
97     EXPECT_EQ(ret, SOFTBUS_OK);
98 
99     auto object = SoftBusRcGetById(&collection, foo->id);
100     EXPECT_EQ(object, reinterpret_cast<SoftBusRcObject *>(foo));
101     object->Dereference(&object);
102     EXPECT_EQ(object, nullptr);
103 
__anon65fd881a0202(const SoftBusRcObject *object, const void *arg) 104     SoftBusRcObjectMatcher matcher = [](const SoftBusRcObject *object, const void *arg) {
105         return ((const DummyObject *)object)->payload == *(const int32_t *)(arg);
106     };
107     object = SoftBusRcGetCommon(&collection, matcher, &payload);
108     EXPECT_EQ(object, reinterpret_cast<SoftBusRcObject *>(foo));
109     object->Dereference(&object);
110     EXPECT_EQ(object, nullptr);
111 
112     SoftBusRcRemove(&collection, reinterpret_cast<SoftBusRcObject *>(foo));
113     object = SoftBusRcGetById(&collection, foo->id);
114     EXPECT_EQ(object, nullptr);
115     // verify expectations of FreeObjectHook, which should never be called, as object is reference by 'foo'
116     testing::Mock::VerifyAndClearExpectations(&mock);
117 
118     // only release object after last dereference call
__anon65fd881a0302(SoftBusRcObject *object) 119     EXPECT_CALL(mock, FreeObjectHook).Times(1).WillRepeatedly([](SoftBusRcObject *object) {
120         SoftBusRcObjectDestruct(object);
121     });
122     foo->Dereference(reinterpret_cast<SoftBusRcObject **>(&foo));
123     EXPECT_EQ(foo, nullptr);
124     testing::Mock::VerifyAndClearExpectations(&mock);
125 
126     SoftBusRcCollectionDestruct(&collection);
127 }
128 
129 /*
130  * @tc.name: ReleaseObjectWhenDestructTest
131  * @tc.desc: release object, which is not removed, when collection destruct
132  * @tc.type: FUNC
133  * @tc.require:
134  */
135 HWTEST_F(SoftbusRcTest, ReleaseObjectInDestructProgressTest, TestSize.Level1)
136 {
137     ConnCommonTestMock mock;
__anon65fd881a0402(const SoftBusRcObject *object, uint16_t index) 138     EXPECT_CALL(mock, IdGeneratorHook).WillRepeatedly([](const SoftBusRcObject *object, uint16_t index) {
139         return (uint32_t)index;
140     });
141     EXPECT_CALL(mock, FreeObjectHook).Times(0);
142 
143     SoftBusRcCollection collection = {};
144     auto ret = SoftBusRcCollectionConstruct("bar-collection", &collection, ConnCommonTestMock::idGenerator_);
145     ASSERT_EQ(ret, SOFTBUS_OK);
146 
147     auto arb = std::make_shared<DummyObject>();
148     auto bar = arb.get();
149     ret = SoftBusRcObjectConstruct(
150         "bar-object ", reinterpret_cast<SoftBusRcObject *>(bar), ConnCommonTestMock::freeHook_);
151     ASSERT_EQ(ret, SOFTBUS_OK);
152     ret = SoftBusRcSave(&collection, reinterpret_cast<SoftBusRcObject *>(bar));
153     ASSERT_EQ(ret, SOFTBUS_OK);
154     // object will deference in connection destruct
155     SoftBusRcCollectionDestruct(&collection);
156     // verify expectations of FreeObjectHook, which should never be called, as object is reference by 'foo'
157     testing::Mock::VerifyAndClearExpectations(&mock);
158 
159     // object will deference in destruct
__anon65fd881a0502(SoftBusRcObject *object) 160     EXPECT_CALL(mock, FreeObjectHook).Times(1).WillRepeatedly([](SoftBusRcObject *object) {
161         SoftBusRcObjectDestruct(object);
162     });
163     bar->Dereference(reinterpret_cast<SoftBusRcObject **>(&bar));
164     EXPECT_EQ(bar, nullptr);
165 }
166 
167 } // namespace OHOS::SoftBus