blob: f27c1f1cc19369c71583c51d0e732f5a0b0add09 [file] [log] [blame]
John Reckd69089a2015-10-28 15:36:33 -07001/*
2 * Copyright (C) 2015 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include <gtest/gtest.h>
18
19#include <utils/StrongPointer.h>
20#include <utils/RefBase.h>
21
22using namespace android;
23
Steven Morelandda75cef2021-03-31 16:05:04 +000024class SPFoo : virtual public RefBase {
25 public:
Colin Crossfe06c632017-02-23 17:48:08 -080026 explicit SPFoo(bool* deleted_check) : mDeleted(deleted_check) {
John Reckd69089a2015-10-28 15:36:33 -070027 *mDeleted = false;
28 }
29
Colin Crossfe06c632017-02-23 17:48:08 -080030 ~SPFoo() {
John Reckd69089a2015-10-28 15:36:33 -070031 *mDeleted = true;
32 }
Steven Morelandc2dc7cd2021-05-04 21:27:56 +000033
34 private:
John Reckd69089a2015-10-28 15:36:33 -070035 bool* mDeleted;
36};
37
Steven Morelandc2dc7cd2021-05-04 21:27:56 +000038class SPLightFoo : virtual public VirtualLightRefBase {
39 public:
40 explicit SPLightFoo(bool* deleted_check) : mDeleted(deleted_check) { *mDeleted = false; }
41
42 ~SPLightFoo() { *mDeleted = true; }
43
44 private:
45 bool* mDeleted;
46};
47
48template <typename T>
49class StrongPointer : public ::testing::Test {};
50
51using RefBaseTypes = ::testing::Types<SPFoo, SPLightFoo>;
52TYPED_TEST_CASE(StrongPointer, RefBaseTypes);
53
54TYPED_TEST(StrongPointer, move) {
John Reckd69089a2015-10-28 15:36:33 -070055 bool isDeleted;
Steven Morelandc2dc7cd2021-05-04 21:27:56 +000056 sp<TypeParam> sp1 = sp<TypeParam>::make(&isDeleted);
57 TypeParam* foo = sp1.get();
John Reckd69089a2015-10-28 15:36:33 -070058 ASSERT_EQ(1, foo->getStrongCount());
59 {
Steven Morelandc2dc7cd2021-05-04 21:27:56 +000060 sp<TypeParam> sp2 = std::move(sp1);
John Reckd69089a2015-10-28 15:36:33 -070061 ASSERT_EQ(1, foo->getStrongCount()) << "std::move failed, incremented refcnt";
62 ASSERT_EQ(nullptr, sp1.get()) << "std::move failed, sp1 is still valid";
63 // The strong count isn't increasing, let's double check the old object
64 // is properly reset and doesn't early delete
65 sp1 = std::move(sp2);
66 }
67 ASSERT_FALSE(isDeleted) << "deleted too early! still has a reference!";
68 {
69 // Now let's double check it deletes on time
Steven Morelandc2dc7cd2021-05-04 21:27:56 +000070 sp<TypeParam> sp2 = std::move(sp1);
John Reckd69089a2015-10-28 15:36:33 -070071 }
72 ASSERT_TRUE(isDeleted) << "foo was leaked!";
73}
Steven Moreland306f8b52019-12-19 16:32:00 -080074
Steven Morelandc2dc7cd2021-05-04 21:27:56 +000075TYPED_TEST(StrongPointer, NullptrComparison) {
76 sp<TypeParam> foo;
Steven Moreland306f8b52019-12-19 16:32:00 -080077 ASSERT_EQ(foo, nullptr);
78 ASSERT_EQ(nullptr, foo);
79}
80
Steven Morelandc2dc7cd2021-05-04 21:27:56 +000081TYPED_TEST(StrongPointer, PointerComparison) {
Steven Moreland306f8b52019-12-19 16:32:00 -080082 bool isDeleted;
Steven Morelandc2dc7cd2021-05-04 21:27:56 +000083 sp<TypeParam> foo = sp<TypeParam>::make(&isDeleted);
Steven Moreland306f8b52019-12-19 16:32:00 -080084 ASSERT_EQ(foo.get(), foo);
85 ASSERT_EQ(foo, foo.get());
86 ASSERT_NE(nullptr, foo);
87 ASSERT_NE(foo, nullptr);
88}
Steven Morelandda75cef2021-03-31 16:05:04 +000089
Steven Morelandc2dc7cd2021-05-04 21:27:56 +000090TYPED_TEST(StrongPointer, Deleted) {
Steven Morelandda75cef2021-03-31 16:05:04 +000091 bool isDeleted;
Steven Morelandc2dc7cd2021-05-04 21:27:56 +000092 sp<TypeParam> foo = sp<TypeParam>::make(&isDeleted);
Steven Morelandda75cef2021-03-31 16:05:04 +000093
Steven Morelandc2dc7cd2021-05-04 21:27:56 +000094 auto foo2 = sp<TypeParam>::fromExisting(foo.get());
Steven Morelandda75cef2021-03-31 16:05:04 +000095
Steven Morelandc2dc7cd2021-05-04 21:27:56 +000096 EXPECT_FALSE(isDeleted);
97 foo = nullptr;
98 EXPECT_FALSE(isDeleted);
99 foo2 = nullptr;
100 EXPECT_TRUE(isDeleted);
101}
102
103TYPED_TEST(StrongPointer, AssertStrongRefExists) {
104 bool isDeleted;
105 TypeParam* foo = new TypeParam(&isDeleted);
106 EXPECT_DEATH(sp<TypeParam>::fromExisting(foo), "");
Steven Morelandda75cef2021-03-31 16:05:04 +0000107 delete foo;
108}