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 <gtest/gtest.h>
17
18 #include <meta/interface/object_macros.h>
19
20 #include "src/test_runner.h"
21
22 using namespace testing::ext;
23
24 META_BEGIN_NAMESPACE()
25
26 class PointerTest : public testing::Test {
27 public:
SetUpTestSuite()28 static void SetUpTestSuite()
29 {
30 SetTest();
31 }
TearDownTestSuite()32 static void TearDownTestSuite()
33 {
34 ResetTest();
35 }
36 void SetUp() override {}
37 void TearDown() override {}
38 };
39
40 namespace {
41 struct PtrTestData {
PtrTestData__anon9807::PtrTestData42 PtrTestData(int& constructCount, int& destructCount)
43 : constructCount(constructCount), destructCount(destructCount)
44 {
45 constructCount++;
46 }
~PtrTestData__anon9807::PtrTestData47 ~PtrTestData()
48 {
49 destructCount++;
50 }
51
52 int data { 0 };
53 int& constructCount;
54 int& destructCount;
55
56 static constexpr int dataValue = 42;
57 };
58 }
59
60 /**
61 * @tc.name: PointerTest
62 * @tc.desc: test SharedPtr function
63 * @tc.type: FUNC
64 * @tc.require: I7DMS1
65 */
HWTEST_F(PointerTest, SharedPtr, TestSize.Level1)66 HWTEST_F(PointerTest, SharedPtr, TestSize.Level1)
67 {
68 int constructCount = 0, destructCount = 0;
69 ASSERT_NE(ptr.get(), nullptr);
70
71 EXPECT_EQ(ptr->data, 0);
72 EXPECT_EQ(constructCount, 1);
73
74 EXPECT_EQ(constructCount, 2);
75 ptr2->data = PtrTestData::dataValue;
76 EXPECT_NE(ptr->data, ptr2->data);
77
78 EXPECT_EQ(destructCount, 0);
79
80 ptr = ptr2;
81 EXPECT_EQ(destructCount, 1);
82 EXPECT_EQ(ptr->data, ptr2->data);
83 ptr.reset();
84 ptr2.reset();
85 EXPECT_EQ(destructCount, 2);
86 }
87
88 /**
89 * @tc.name: PointerTest
90 * @tc.desc: test WeakPtr function
91 * @tc.type: FUNC
92 * @tc.require: I7DMS1
93 */
HWTEST_F(PointerTest, WeakPtr, TestSize.Level1)94 HWTEST_F(PointerTest, WeakPtr, TestSize.Level1)
95 {
96 int constructCount = 0, destructCount = 0;
97 ptr->data = PtrTestData::dataValue;
98 EXPECT_EQ(ptr->data, PtrTestData::dataValue);
99 EXPECT_EQ(constructCount, 1);
100
101 BASE_NS::weak_ptr<PtrTestData> wptr(ptr);
102 EXPECT_EQ(constructCount, 1);
103
104 {
105 auto p = wptr.lock();
106 ASSERT_NE(p.get(), nullptr);
107 EXPECT_EQ(constructCount, 1);
108 EXPECT_EQ(p->data, PtrTestData::dataValue);
109 }
110
111 ptr.reset();
112 EXPECT_EQ(destructCount, 1);
113
114 auto p = wptr.lock();
115 EXPECT_EQ(p.get(), nullptr);
116 }
117
118 class IBase : public CORE_NS::IInterface {
119 public:
120 static constexpr BASE_NS::Uid UID { "00000000-0000-0000-0000-000000000001" };
121 virtual void AmBase() = 0;
122 virtual void Identify() = 0;
123 };
124
125 class IBase2 : public IBase {
126 public:
127 static constexpr BASE_NS::Uid UID { "00000000-0000-0000-0000-000000000002" };
128 virtual uint32_t NonConstCount() const = 0;
129 virtual uint32_t ConstCount() const = 0;
130 virtual void B2() = 0;
131 virtual void DoIt() const = 0;
132 virtual void DoIt() = 0;
133
134 virtual void NonConstOnlyDoIt() = 0;
135 virtual void ConstOnlyDoIt() const = 0;
136 };
137
138 class IBase3 : public IBase {
139 public:
140 static constexpr BASE_NS::Uid UID { "00000000-0000-0000-0000-000000000003" };
141 virtual void B3() = 0;
142 virtual void Identify() const = 0;
143 virtual void Narf() const = 0;
144 using IBase::Identify;
145 };
146
147 class DualBase : private IBase2, private IBase3 {
148 public:
Construct()149 static BASE_NS::shared_ptr<CORE_NS::IInterface> Construct()
150 {
151 return interface_pointer_cast<CORE_NS::IInterface>(ptr);
152 }
153 mutable int ncc = 0;
154 mutable int cc = 0;
155 void Narf() const override
156 {
157 printf("Narf");
158 }
159 uint32_t NonConstCount() const override
160 {
161 return ncc;
162 }
163 uint32_t ConstCount() const override
164 {
165 return cc;
166 }
167 void NonConstOnlyDoIt() override
168 {
169 ncc++;
170 printf("Non Const Only DoIt\n");
171 }
172 void ConstOnlyDoIt() const override
173 {
174 cc++;
175 printf("Const Only DoIt\n");
176 }
177 void DoIt() const override
178 {
179 cc++;
180 printf("Const DoIt\n");
181 }
182 void DoIt() override
183 {
184 ncc++;
185 printf("Non const DoIt\n");
186 }
187 void AmBase() override
188 {
189 printf("DualBase %p\n", this);
190 }
191 void Identify() const override
192 {
193 printf("I am CONST DualBase %p\n", this);
194 }
195 void Identify() override
196 {
197 printf("I am DualBase %p\n", this);
198 }
199 void B2() override
200 {
201 printf("DualBase (B2) %p\n", this);
202 }
203 void B3() override
204 {
205 printf("DualBase (B3) %p\n", this);
206 }
207
208 const IInterface* GetInterface(const BASE_NS::Uid& uid) const override
209 {
210 return const_cast<DualBase*>(this)->GetInterface(uid);
211 }
212
213 IInterface* GetInterface(const BASE_NS::Uid& uid) override
214 {
215 if (uid == IInterface::UID) {
216 return static_cast<IBase2*>(this);
217 }
218 if (uid == IBase::UID) {
219 return static_cast<IBase2*>(this);
220 }
221 if (uid == IBase2::UID) {
222 return static_cast<IBase2*>(this);
223 }
224 if (uid == IBase3::UID) {
225 return static_cast<IBase3*>(this);
226 }
227 return nullptr;
228 }
229 META_IMPLEMENT_REF_COUNT()
230 };
231
232 /**
233 * @tc.name: PointerTest
234 * @tc.desc: test AliasTest function
235 * @tc.type: FUNC
236 * @tc.require: I7DMS1
237 */
HWTEST_F(PointerTest, AliasTest, TestSize.Level1)238 HWTEST_F(PointerTest, AliasTest, TestSize.Level1)
239 {
240 {
241 IBase2* ap = (IBase2*)dd->GetInterface(IBase2::UID);
242 IBase3* bp = (IBase3*)dd->GetInterface(IBase3::UID);
243 BASE_NS::shared_ptr<IBase> orig(ap);
244 {
245 BASE_NS::shared_ptr<IBase> alias(orig, bp);
246 }
247 }
248 {
249 BASE_NS::shared_ptr b3(interface_pointer_cast<IBase3>(t));
250 BASE_NS::shared_ptr b2(interface_pointer_cast<IBase2>(t));
251
252 EXPECT_TRUE(t == b3);
253 EXPECT_TRUE((void*)b3.get() != (void*)b2.get());
254
255 BASE_NS::shared_ptr ib3(interface_pointer_cast<CORE_NS::IInterface>(t));
256 BASE_NS::shared_ptr ib2(interface_pointer_cast<CORE_NS::IInterface>(t));
257
258 EXPECT_TRUE(ib2 == b2);
259 EXPECT_TRUE(ib3 == b3);
260 EXPECT_TRUE(ib3 == ib2);
261 EXPECT_TRUE((void*)ib3.get() == (void*)ib2.get());
262 }
263
264 BASE_NS::weak_ptr<IBase> wp2;
265 {
266 BASE_NS::shared_ptr<IBase3> b3(interface_pointer_cast<IBase3>(t));
267 wp2 = b3;
268 ASSERT_TRUE(wp2.lock());
269 ASSERT_FALSE(wp2.Compare(b3));
270 ASSERT_TRUE(wp2.lock() == b3);
271 ASSERT_TRUE(b3 == interface_pointer_cast<IBase3>(wp2.lock()));
272 b3.reset();
273 ASSERT_TRUE(wp2.lock());
274 ASSERT_FALSE(wp2.Compare(b3));
275 ASSERT_FALSE(b3 == interface_pointer_cast<IBase3>(wp2.lock()));
276 }
277
278 BASE_NS::weak_ptr wp(t);
279 ASSERT_TRUE(wp.lock());
280 ASSERT_TRUE(wp.Compare(t));
281 ASSERT_TRUE(t == wp.lock());
282
283 ASSERT_TRUE(wp2.lock());
284 ASSERT_TRUE(wp2.lock() == t);
285 ASSERT_TRUE(t == wp2.lock());
286
287 t.reset();
288
289 ASSERT_FALSE(wp.Compare(t));
290 ASSERT_TRUE(t == wp.lock());
291
292 ASSERT_FALSE(wp.lock());
293 ASSERT_TRUE(wp.lock() == nullptr);
294 ASSERT_TRUE(t == nullptr);
295
296 ASSERT_TRUE(wp2.lock() == t);
297 ASSERT_TRUE(t == wp2.lock());
298
299 ASSERT_FALSE(wp2.lock());
300 ASSERT_TRUE(wp2.lock() == nullptr);
301 }
302
303 /**
304 * @tc.name: PointerTest
305 * @tc.desc: test NullTests function
306 * @tc.type: FUNC
307 * @tc.require: I7DMS1
308 */
HWTEST_F(PointerTest, NullTests, TestSize.Level1)309 HWTEST_F(PointerTest, NullTests, TestSize.Level1)
310 {
311 int constructCount = 0, destructCount = 0;
312 BASE_NS::weak_ptr<PtrTestData> ptr2 = ptr;
313 BASE_NS::weak_ptr<PtrTestData> ptr22 = ptr;
314 ASSERT_FALSE(ptr.get() == nullptr);
315 ASSERT_FALSE(ptr == nullptr);
316
317 ASSERT_FALSE(ptr2.lock().get() == nullptr);
318 ASSERT_FALSE(ptr2.lock() == nullptr);
319
320 ASSERT_TRUE(ptr.get() != nullptr);
321 ASSERT_TRUE(ptr != nullptr);
322
323 ASSERT_TRUE(ptr2.lock().get() != nullptr);
324 ASSERT_TRUE(ptr2.lock() != nullptr);
325
326 ptr.reset();
327
328 ASSERT_FALSE(ptr.get() != nullptr);
329 ASSERT_FALSE(ptr != nullptr);
330
331 ASSERT_FALSE(ptr2.lock().get() != nullptr);
332 ASSERT_FALSE(ptr2.lock() != nullptr);
333
334 ASSERT_TRUE(ptr.get() == nullptr);
335 ASSERT_TRUE(ptr == nullptr);
336
337 ASSERT_TRUE(ptr2.lock().get() == nullptr);
338 ASSERT_TRUE(ptr2.lock() == nullptr);
339
340 BASE_NS::shared_ptr<PtrTestData> ptr3;
341 BASE_NS::weak_ptr<PtrTestData> ptr4;
342
343 ASSERT_TRUE(ptr3 == ptr4.lock());
344 ASSERT_TRUE(ptr4.Compare(ptr3));
345
346 ASSERT_FALSE(ptr4.Compare(ptr2));
347 ASSERT_TRUE(ptr3 == ptr);
348
349 ASSERT_TRUE(ptr2.Compare(ptr22));
350
351 {
352 BASE_NS::weak_ptr<PtrTestData> empty;
353 BASE_NS::weak_ptr<PtrTestData> ptrAW = ptrA;
354
355 BASE_NS::weak_ptr<PtrTestData> ptrBW = ptrB;
356
357 ptrA.reset();
358 ptrB.reset();
359
360 ASSERT_FALSE(ptrAW.Compare(empty));
361 ASSERT_FALSE(ptrAW.Compare(ptrBW));
362 ASSERT_TRUE(ptrAW.lock() == ptrBW.lock());
363 ASSERT_TRUE(empty.lock() == ptrBW.lock());
364 }
365 }
366
367 /**
368 * @tc.name: PointerTest
369 * @tc.desc: test AliasTest2 function
370 * @tc.type: FUNC
371 * @tc.require: I7DMS1
372 */
HWTEST_F(PointerTest, AliasTest2, TestSize.Level1)373 HWTEST_F(PointerTest, AliasTest2, TestSize.Level1)
374 {
375 BASE_NS::shared_ptr<CORE_NS::IInterface> t((IBase*)(db)->GetInterface(CORE_NS::IInterface::UID));
376 BASE_NS::shared_ptr ib1(interface_pointer_cast<CORE_NS::IInterface>(t));
377 BASE_NS::shared_ptr ib2(interface_pointer_cast<IBase>(t));
378 BASE_NS::shared_ptr ib3(interface_pointer_cast<IBase2>(t));
379 BASE_NS::shared_ptr ib4(interface_pointer_cast<IBase3>(t));
380
381 ASSERT_TRUE(t == ib1);
382 ASSERT_TRUE(t == ib2);
383 ASSERT_TRUE(t == ib3);
384 ASSERT_TRUE(t == ib4);
385 ASSERT_TRUE(ib2 == ib3);
386 ASSERT_TRUE(ib2 == ib4);
387
388 ib4 = nullptr;
389 t = nullptr;
390 ib1 = nullptr;
391 ib2 = nullptr;
392 ib3 = nullptr;
393 }
394
395 /**
396 * @tc.name: PointerTest
397 * @tc.desc: test WeakTest2 function
398 * @tc.type: FUNC
399 * @tc.require: I7DMS1
400 */
HWTEST_F(PointerTest, WeakTest2, TestSize.Level1)401 HWTEST_F(PointerTest, WeakTest2, TestSize.Level1)
402 {
403 BASE_NS::shared_ptr<CORE_NS::IInterface> t((IBase*)(db)->GetInterface(CORE_NS::IInterface::UID));
404 BASE_NS::shared_ptr ib1(interface_pointer_cast<CORE_NS::IInterface>(t));
405 BASE_NS::shared_ptr ib2(interface_pointer_cast<IBase>(t));
406 BASE_NS::shared_ptr ib3(interface_pointer_cast<IBase2>(t));
407 BASE_NS::shared_ptr ib4(interface_pointer_cast<IBase3>(t));
408
409 BASE_NS::weak_ptr wt(t);
410 BASE_NS::weak_ptr wb1(ib1);
411 BASE_NS::weak_ptr wb2(ib2);
412 BASE_NS::weak_ptr wb3(ib3);
413 BASE_NS::weak_ptr wb4(ib4);
414
415 ASSERT_TRUE(wt.Compare(t));
416 ASSERT_TRUE(wt.Compare(wb1));
417 ASSERT_TRUE(wt.Compare(wb2));
418 ASSERT_TRUE(wt.Compare(wb3));
419 ASSERT_FALSE(wt.Compare(wb4));
420 ASSERT_TRUE(wt.CompareOwner(wb4));
421 ASSERT_TRUE(wb2.Compare(wb3));
422
423 ASSERT_TRUE(wb2.CompareOwner(wb4));
424 ASSERT_FALSE(wb2.Compare(wb4));
425
426 ASSERT_FALSE(wt.Compare(wb4));
427 ASSERT_TRUE(wt.CompareOwner(wb4));
428 ASSERT_TRUE(wt.lock() == wb4.lock());
429
430 t = nullptr;
431
432 ASSERT_FALSE(wt.Compare(t));
433 ASSERT_TRUE(wt.lock());
434 ASSERT_TRUE(t == nullptr);
435
436 ASSERT_TRUE(wt.Compare(wb1));
437 ASSERT_TRUE(wt.Compare(wb2));
438 ASSERT_TRUE(wt.Compare(wb3));
439
440 ib1 = nullptr;
441 ib2 = nullptr;
442 ib3 = nullptr;
443
444 ASSERT_TRUE(wt.Compare(wb1));
445 ASSERT_TRUE(wt.Compare(wb2));
446 ASSERT_TRUE(wt.Compare(wb3));
447 ASSERT_FALSE(wt.Compare(wb4));
448 ASSERT_TRUE(wt.CompareOwner(wb4));
449 ASSERT_TRUE(wb2.Compare(wb3));
450 ASSERT_TRUE(wb2.CompareOwner(wb4));
451 ASSERT_FALSE(wb2.Compare(wb4));
452
453 wt = nullptr;
454 wb1 = nullptr;
455 wb2 = nullptr;
456 wb3 = nullptr;
457
458 ASSERT_TRUE(wt.lock() == nullptr);
459 ASSERT_TRUE(wb1.lock() == nullptr);
460 ASSERT_TRUE(wb2.lock() == nullptr);
461 ASSERT_TRUE(wb3.lock() == nullptr);
462 ASSERT_TRUE(wb2.Compare(wb3));
463 ASSERT_TRUE(!wb2.Compare(wb4));
464
465 auto* ptr = ib4.get();
466 auto* ptr2 = wb4.lock().get();
467
468 ib4 = nullptr;
469
470 ASSERT_TRUE(wb4.lock() == nullptr);
471 ASSERT_FALSE(wt.Compare(wb4));
472 }
473
474 /**
475 * @tc.name: PointerTest
476 * @tc.desc: test ImplicitConversions function
477 * @tc.type: FUNC
478 * @tc.require: I7DMS1
479 */
HWTEST_F(PointerTest, ImplicitConversions, TestSize.Level1)480 HWTEST_F(PointerTest, ImplicitConversions, TestSize.Level1)
481 {
482 auto db = DualBase::Construct();
483 BASE_NS::shared_ptr<IBase3> ib4(interface_pointer_cast<IBase3>(db));
484 BASE_NS::shared_ptr<CORE_NS::IInterface> a(ib4);
485
486 ASSERT_TRUE(db.get() != ib4.get());
487 ASSERT_TRUE(db.get() == a.get());
488
489 BASE_NS::weak_ptr<CORE_NS::IInterface> aa(ib4);
490
491 BASE_NS::weak_ptr<CORE_NS::IInterface> b;
492 b = ib4;
493
494 BASE_NS::weak_ptr<IBase3> ba(ib4);
495
496 BASE_NS::weak_ptr<CORE_NS::IInterface> d(ba);
497
498 BASE_NS::weak_ptr<CORE_NS::IInterface> dd;
499 dd = ba;
500
501 BASE_NS::weak_ptr<CORE_NS::IInterface> c(BASE_NS::move(ba));
502 }
503
504 /**
505 * @tc.name: PointerTest
506 * @tc.desc: test CusTomDeleter function
507 * @tc.type: FUNC
508 * @tc.require: I7DMS1
509 */
510 int g_customDeleterCalled = 0;
HWTEST_F(PointerTest, CustomDeleter, TestSize.Level1)511 HWTEST_F(PointerTest, CustomDeleter, TestSize.Level1)
512 {
513 int value = 42;
514 auto deleter = [](void* p) {
515 g_customDeleterCalled++;
516 printf("Last reference for %p gone\n", p);
517 };
518 {
519 BASE_NS::shared_ptr<int> sb2;
520 {
521 BASE_NS::shared_ptr<int> custom(&value, deleter);
522 BASE_NS::weak_ptr wb = custom;
523 BASE_NS::shared_ptr sb = custom;
524 sb2 = custom;
525 custom = nullptr;
526 sb = nullptr;
527 }
528 ASSERT_TRUE(g_customDeleterCalled == 0);
529 }
530 ASSERT_TRUE(g_customDeleterCalled == 1);
531 }
532
533 /**
534 * @tc.name: PointerTest
535 * @tc.desc: test ConstConversion function
536 * @tc.type: FUNC
537 * @tc.require: I7DMS1
538 */
HWTEST_F(PointerTest, ConstConversion, TestSize.Level1)539 HWTEST_F(PointerTest, ConstConversion, TestSize.Level1)
540 {
541 auto db = interface_pointer_cast<IBase2>(DualBase::Construct());
542
543 BASE_NS::shared_ptr<IBase2> a(db);
544 BASE_NS::shared_ptr<const IBase2> ca(db);
545
546 EXPECT_EQ(db->NonConstCount(), 0);
547 EXPECT_EQ(db->ConstCount(), 0);
548
549 a->DoIt();
550 EXPECT_EQ(db->NonConstCount(), 1);
551 EXPECT_EQ(db->ConstCount(), 0);
552
553 ca->DoIt();
554 EXPECT_EQ(db->NonConstCount(), 1);
555 EXPECT_EQ(db->ConstCount(), 1);
556 ca->DoIt();
557 EXPECT_EQ(db->NonConstCount(), 1);
558 EXPECT_EQ(db->ConstCount(), 2);
559
560 a->ConstOnlyDoIt();
561 EXPECT_EQ(db->NonConstCount(), 1);
562 EXPECT_EQ(db->ConstCount(), 3);
563 ca->ConstOnlyDoIt();
564 EXPECT_EQ(db->NonConstCount(), 1);
565 EXPECT_EQ(db->ConstCount(), 4);
566
567 a->NonConstOnlyDoIt();
568 EXPECT_EQ(db->NonConstCount(), 2);
569 EXPECT_EQ(db->ConstCount(), 4);
570
571 BASE_NS::shared_ptr<const IBase3> da;
572
573 da = interface_pointer_cast<const IBase3>(db);
574 da->Identify();
575
576 auto* p = interface_cast<const IBase3>(a);
577
578 auto* po = interface_cast<const IBase2>(a);
579 auto* ppo = interface_cast<const IBase2>(ca);
580
581 p->Narf();
582 }
583
584 /**
585 * @tc.name: PointerTest
586 * @tc.desc: test ConstConversion2 function
587 * @tc.type: FUNC
588 * @tc.require: I7DMS1
589 */
HWTEST_F(PointerTest, ConstConversion2, TestSize.Level1)590 HWTEST_F(PointerTest, ConstConversion2, TestSize.Level1)
591 {
592 auto db = interface_pointer_cast<IBase2>(DualBase::Construct());
593
594 BASE_NS::weak_ptr<IBase2> a(db);
595 BASE_NS::weak_ptr<const IBase2> ca(db);
596
597 EXPECT_EQ(db->NonConstCount(), 0);
598 EXPECT_EQ(db->ConstCount(), 0);
599
600 a.lock()->DoIt();
601 EXPECT_EQ(db->NonConstCount(), 1);
602 EXPECT_EQ(db->ConstCount(), 0);
603
604 ca.lock()->DoIt();
605 EXPECT_EQ(db->NonConstCount(), 1);
606 EXPECT_EQ(db->ConstCount(), 1);
607 ca.lock()->DoIt();
608 EXPECT_EQ(db->NonConstCount(), 1);
609 EXPECT_EQ(db->ConstCount(), 2);
610
611 a.lock()->ConstOnlyDoIt();
612 EXPECT_EQ(db->NonConstCount(), 1);
613 EXPECT_EQ(db->ConstCount(), 3);
614 ca.lock()->ConstOnlyDoIt();
615 EXPECT_EQ(db->NonConstCount(), 1);
616 EXPECT_EQ(db->ConstCount(), 4);
617
618 a.lock()->NonConstOnlyDoIt();
619 EXPECT_EQ(db->NonConstCount(), 2);
620 EXPECT_EQ(db->ConstCount(), 4);
621
622 BASE_NS::weak_ptr<const IBase3> da;
623
624 da = interface_pointer_cast<const IBase3>(db);
625 da.lock()->Identify();
626 }
627 META_END_NAMESPACE()