blob: 29f6bd4bbf4babad435fd32d6c30b02d61250a7a [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 }
33private:
34 bool* mDeleted;
35};
36
37TEST(StrongPointer, move) {
38 bool isDeleted;
Steven Moreland401d69a2020-02-18 14:03:05 -080039 sp<SPFoo> sp1 = sp<SPFoo>::make(&isDeleted);
40 SPFoo* foo = sp1.get();
John Reckd69089a2015-10-28 15:36:33 -070041 ASSERT_EQ(1, foo->getStrongCount());
42 {
Colin Crossfe06c632017-02-23 17:48:08 -080043 sp<SPFoo> sp2 = std::move(sp1);
John Reckd69089a2015-10-28 15:36:33 -070044 ASSERT_EQ(1, foo->getStrongCount()) << "std::move failed, incremented refcnt";
45 ASSERT_EQ(nullptr, sp1.get()) << "std::move failed, sp1 is still valid";
46 // The strong count isn't increasing, let's double check the old object
47 // is properly reset and doesn't early delete
48 sp1 = std::move(sp2);
49 }
50 ASSERT_FALSE(isDeleted) << "deleted too early! still has a reference!";
51 {
52 // Now let's double check it deletes on time
Colin Crossfe06c632017-02-23 17:48:08 -080053 sp<SPFoo> sp2 = std::move(sp1);
John Reckd69089a2015-10-28 15:36:33 -070054 }
55 ASSERT_TRUE(isDeleted) << "foo was leaked!";
56}
Steven Moreland306f8b52019-12-19 16:32:00 -080057
58TEST(StrongPointer, NullptrComparison) {
59 sp<SPFoo> foo;
60 ASSERT_EQ(foo, nullptr);
61 ASSERT_EQ(nullptr, foo);
62}
63
64TEST(StrongPointer, PointerComparison) {
65 bool isDeleted;
Steven Moreland401d69a2020-02-18 14:03:05 -080066 sp<SPFoo> foo = sp<SPFoo>::make(&isDeleted);
Steven Moreland306f8b52019-12-19 16:32:00 -080067 ASSERT_EQ(foo.get(), foo);
68 ASSERT_EQ(foo, foo.get());
69 ASSERT_NE(nullptr, foo);
70 ASSERT_NE(foo, nullptr);
71}
Steven Morelandda75cef2021-03-31 16:05:04 +000072
73TEST(StrongPointer, AssertStrongRefExists) {
74 // uses some other refcounting method, or non at all
75 bool isDeleted;
76 SPFoo* foo = new SPFoo(&isDeleted);
77
78 // can only get a valid sp<> object when you construct it as an sp<> object
79 EXPECT_DEATH(sp<SPFoo>::fromExisting(foo), "");
80
81 delete foo;
82}