1 /* 2 * Copyright (c) 2022 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 <cstdint> 17 #include <gtest/gtest.h> 18 #include <variant> 19 #include <vector> 20 21 #include "change_notification.h" 22 #include "iremote_broker.h" 23 #include "iremote_object.h" 24 #include "iremote_proxy.h" 25 #include "iremote_stub.h" 26 #include "itypes_util.h" 27 #include "types.h" 28 29 using namespace testing::ext; 30 using namespace OHOS::DistributedKv; 31 using namespace OHOS; 32 using var_t = std::variant<std::monostate, uint32_t, std::string, int32_t, uint64_t>; 33 namespace OHOS::Test { 34 class TypesUtilTest : public testing::Test { 35 public: 36 class ITestRemoteObject : public IRemoteBroker { 37 public: 38 DECLARE_INTERFACE_DESCRIPTOR(u"OHOS.ITestRemoteObject"); 39 }; 40 class TestRemoteObjectStub : public IRemoteStub<ITestRemoteObject> { 41 public: 42 }; 43 class TestRemoteObjectProxy : public IRemoteProxy<ITestRemoteObject> { 44 public: TestRemoteObjectProxy(const sptr<IRemoteObject> & impl)45 explicit TestRemoteObjectProxy(const sptr<IRemoteObject> &impl) 46 : IRemoteProxy<ITestRemoteObject>(impl) 47 {} 48 ~TestRemoteObjectProxy() = default; 49 private: 50 static inline BrokerDelegator<TestRemoteObjectProxy> delegator_; 51 }; 52 class TestRemoteObjectClient : public TestRemoteObjectStub { 53 public: TestRemoteObjectClient()54 TestRemoteObjectClient() {} ~TestRemoteObjectClient()55 virtual ~TestRemoteObjectClient() {} 56 }; SetUpTestCase(void)57 static void SetUpTestCase(void) {}; TearDownTestCase(void)58 static void TearDownTestCase(void) {}; SetUp()59 void SetUp() {}; TearDown()60 void TearDown() {}; 61 }; 62 63 HWTEST_F(TypesUtilTest, DeviceInfo, TestSize.Level0) 64 { 65 MessageParcel parcel; 66 DeviceInfo clientDev; 67 clientDev.deviceId = "123"; 68 clientDev.deviceName = "rk3568"; 69 clientDev.deviceType = "phone"; 70 ASSERT_TRUE(ITypesUtil::Marshal(parcel, clientDev)); 71 DeviceInfo serverDev; 72 ASSERT_TRUE(ITypesUtil::Unmarshal(parcel, serverDev)); 73 ASSERT_EQ(clientDev.deviceId, serverDev.deviceId); 74 ASSERT_EQ(clientDev.deviceName, serverDev.deviceName); 75 ASSERT_EQ(clientDev.deviceType, serverDev.deviceType); 76 } 77 78 HWTEST_F(TypesUtilTest, Entry, TestSize.Level0) 79 { 80 MessageParcel parcel; 81 Entry entryIn; 82 entryIn.key = "student_name_mali"; 83 entryIn.value = "age:20"; 84 ASSERT_TRUE(ITypesUtil::Marshal(parcel, entryIn)); 85 Entry entryOut; 86 ASSERT_TRUE(ITypesUtil::Unmarshal(parcel, entryOut)); 87 EXPECT_EQ(entryOut.key.ToString(), std::string("student_name_mali")); 88 EXPECT_EQ(entryOut.value.ToString(), std::string("age:20")); 89 } 90 91 HWTEST_F(TypesUtilTest, ChangeNotification, TestSize.Level1) 92 { 93 Entry insert, update, del; 94 insert.key = "insert"; 95 update.key = "update"; 96 del.key = "delete"; 97 insert.value = "insert_value"; 98 update.value = "update_value"; 99 del.value = "delete_value"; 100 std::vector<Entry> inserts, updates, deleteds; 101 inserts.push_back(insert); 102 updates.push_back(update); 103 deleteds.push_back(del); 104 105 ChangeNotification changeIn(std::move(inserts), std::move(updates), std::move(deleteds), std::string(), false); 106 MessageParcel parcel; 107 ASSERT_TRUE(ITypesUtil::Marshal(parcel, changeIn)); 108 ChangeNotification changeOut({}, {}, {}, "", false); 109 ASSERT_TRUE(ITypesUtil::Unmarshal(parcel, changeOut)); 110 ASSERT_EQ(changeOut.GetInsertEntries().size(), 1UL); 111 EXPECT_EQ(changeOut.GetInsertEntries().front().key.ToString(), std::string("insert")); 112 EXPECT_EQ(changeOut.GetInsertEntries().front().value.ToString(), std::string("insert_value")); 113 ASSERT_EQ(changeOut.GetUpdateEntries().size(), 1UL); 114 EXPECT_EQ(changeOut.GetUpdateEntries().front().key.ToString(), std::string("update")); 115 EXPECT_EQ(changeOut.GetUpdateEntries().front().value.ToString(), std::string("update_value")); 116 ASSERT_EQ(changeOut.GetDeleteEntries().size(), 1UL); 117 EXPECT_EQ(changeOut.GetDeleteEntries().front().key.ToString(), std::string("delete")); 118 EXPECT_EQ(changeOut.GetDeleteEntries().front().value.ToString(), std::string("delete_value")); 119 EXPECT_EQ(changeOut.IsClear(), false); 120 } 121 122 123 HWTEST_F(TypesUtilTest, Multiple, TestSize.Level1) 124 { 125 uint32_t input1 = 10; 126 int32_t input2 = -10; 127 std::string input3 = "i test"; 128 Blob input4 = "input 4"; 129 Entry input5; 130 input5.key = "my test"; 131 input5.value = "test value"; 132 DeviceInfo input6 = {.deviceId = "mock deviceId", .deviceName = "mock phone", .deviceType = "0"}; 133 sptr<ITestRemoteObject> input7 = new TestRemoteObjectClient(); 134 MessageParcel parcel; 135 ASSERT_TRUE(ITypesUtil::Marshal(parcel, input1, input2, input3, input4, input5, input6, input7->AsObject())); 136 uint32_t output1 = 0; 137 int32_t output2 = 0; 138 std::string output3 = ""; 139 Blob output4; 140 Entry output5; 141 DeviceInfo output6; 142 sptr<IRemoteObject> output7; 143 ASSERT_TRUE(ITypesUtil::Unmarshal(parcel, output1, output2, output3, output4, output5, output6, output7)); 144 ASSERT_EQ(output1, input1); 145 ASSERT_EQ(output2, input2); 146 ASSERT_EQ(output3, input3); 147 ASSERT_EQ(output4, input4); 148 ASSERT_EQ(output5.key, input5.key); 149 ASSERT_EQ(output5.value, input5.value); 150 ASSERT_EQ(output6.deviceId, input6.deviceId); 151 ASSERT_EQ(output6.deviceName, input6.deviceName); 152 ASSERT_EQ(output6.deviceType, input6.deviceType); 153 ASSERT_EQ(output7, input7->AsObject()); 154 } 155 156 HWTEST_F(TypesUtilTest, Variant, TestSize.Level0) 157 { 158 MessageParcel parcelNull; 159 var_t valueNullIn; 160 ASSERT_TRUE(ITypesUtil::Marshal(parcelNull, valueNullIn)); 161 var_t valueNullOut; 162 ASSERT_TRUE(ITypesUtil::Unmarshal(parcelNull, valueNullOut)); 163 ASSERT_EQ(valueNullOut.index(), 0); 164 165 MessageParcel parcelUint; 166 var_t valueUintIn; 167 valueUintIn.emplace<1>(100); 168 ASSERT_TRUE(ITypesUtil::Marshal(parcelUint, valueUintIn)); 169 var_t valueUintOut; 170 ASSERT_TRUE(ITypesUtil::Unmarshal(parcelUint, valueUintOut)); 171 ASSERT_EQ(valueUintOut.index(), 1); 172 ASSERT_EQ(std::get<uint32_t>(valueUintOut), 100); 173 174 MessageParcel parcelString; 175 var_t valueStringIn; 176 valueStringIn.emplace<2>("valueString"); 177 ASSERT_TRUE(ITypesUtil::Marshal(parcelString, valueStringIn)); 178 var_t valueStringOut; 179 ASSERT_TRUE(ITypesUtil::Unmarshal(parcelString, valueStringOut)); 180 ASSERT_EQ(valueStringOut.index(), 2); 181 ASSERT_EQ(std::get<std::string>(valueStringOut), "valueString"); 182 183 MessageParcel parcelInt; 184 var_t valueIntIn; 185 valueIntIn.emplace<3>(101); 186 ASSERT_TRUE(ITypesUtil::Marshal(parcelInt, valueIntIn)); 187 var_t valueIntOut; 188 ASSERT_TRUE(ITypesUtil::Unmarshal(parcelInt, valueIntOut)); 189 ASSERT_EQ(valueIntOut.index(), 3); 190 ASSERT_EQ(std::get<int32_t>(valueIntOut), 101); 191 192 MessageParcel parcelUint64; 193 var_t valueUint64In; 194 valueUint64In.emplace<4>(110); 195 ASSERT_TRUE(ITypesUtil::Marshal(parcelUint64, valueUint64In)); 196 var_t valueUint64Out; 197 ASSERT_TRUE(ITypesUtil::Unmarshal(parcelUint64, valueUint64Out)); 198 ASSERT_EQ(valueUint64Out.index(), 4); 199 ASSERT_EQ(std::get<uint64_t>(valueUint64Out), 110); 200 } 201 202 /** 203 * @tc.name: MarshalToBufferLimitTest001 204 * @tc.desc: construct a invalid vector and check MarshalToBuffer function. 205 * @tc.type: FUNC 206 * @tc.require: 207 * @tc.author: ht 208 */ 209 HWTEST_F(TypesUtilTest, MarshalToBufferLimitTest001, TestSize.Level1) 210 { 211 MessageParcel parcel; 212 std::vector<Entry> exceedMaxCountInput(ITypesUtil::MAX_COUNT + 1); 213 ASSERT_FALSE(ITypesUtil::MarshalToBuffer(exceedMaxCountInput, sizeof(int) * exceedMaxCountInput.size(), parcel)); 214 } 215 216 /** 217 * @tc.name: MarshalToBufferLimitTest002 218 * @tc.desc: construct a invalid vector and check MarshalToBuffer function. 219 * @tc.type: FUNC 220 * @tc.require: 221 * @tc.author: ht 222 */ 223 HWTEST_F(TypesUtilTest, MarshalToBufferLimitTest002, TestSize.Level1) 224 { 225 MessageParcel parcel; 226 std::vector<Entry> inputNormal(10); 227 ASSERT_FALSE(ITypesUtil::MarshalToBuffer(inputNormal, ITypesUtil::MAX_SIZE + 1, parcel)); 228 ASSERT_FALSE(ITypesUtil::MarshalToBuffer(inputNormal, -1, parcel)); 229 } 230 231 /** 232 * @tc.name: UnmarshalFromBufferLimitTest001 233 * @tc.desc: construct a invalid parcel and check UnmarshalFromBuffer function. 234 * @tc.type: FUNC 235 * @tc.require: 236 * @tc.author: ht 237 */ 238 HWTEST_F(TypesUtilTest, UnmarshalFromBufferLimitTest001, TestSize.Level1) 239 { 240 MessageParcel parcel; 241 int32_t normalSize = 100; 242 parcel.WriteInt32(normalSize); //normal size 243 parcel.WriteInt32(ITypesUtil::MAX_COUNT + 1); //exceed MAX_COUNT 244 std::unique_ptr<uint8_t[]> buffer = std::make_unique<uint8_t[]>(normalSize); 245 parcel.WriteRawData(buffer.get(), normalSize); 246 247 std::vector<Entry> output; 248 ASSERT_FALSE(ITypesUtil::UnmarshalFromBuffer(parcel, output)); 249 ASSERT_TRUE(output.empty()); 250 } 251 252 /** 253 * @tc.name: UnmarshalFromBufferLimitTest002 254 * @tc.desc: construct a invalid parcel and check UnmarshalFromBuffer function. 255 * @tc.type: FUNC 256 * @tc.require: 257 * @tc.author: ht 258 */ 259 HWTEST_F(TypesUtilTest, UnmarshalFromBufferLimitTest002, TestSize.Level1) 260 { 261 MessageParcel parcel; 262 parcel.WriteInt32(ITypesUtil::MAX_SIZE + 1); //exceedMaxSize size 263 std::vector<Entry> output; 264 ASSERT_FALSE(ITypesUtil::UnmarshalFromBuffer(parcel, output)); 265 ASSERT_TRUE(output.empty()); 266 } 267 } 268