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