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()