aboutsummaryrefslogtreecommitdiff
path: root/src/trace_processor/ref_counted_unittest.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/trace_processor/ref_counted_unittest.cc')
-rw-r--r--src/trace_processor/ref_counted_unittest.cc161
1 files changed, 161 insertions, 0 deletions
diff --git a/src/trace_processor/ref_counted_unittest.cc b/src/trace_processor/ref_counted_unittest.cc
new file mode 100644
index 000000000..541b49a14
--- /dev/null
+++ b/src/trace_processor/ref_counted_unittest.cc
@@ -0,0 +1,161 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include "perfetto/trace_processor/ref_counted.h"
+
+#include "test/gtest_and_gmock.h"
+
+namespace perfetto {
+namespace trace_processor {
+namespace {
+
+int g_instances = 0;
+
+class RObj : public RefCounted {
+ public:
+ RObj() { ++g_instances; }
+ ~RObj() { --g_instances; }
+};
+
+TEST(RefCountedTest, CreateAndReset) {
+ RefPtr<RObj> ptr;
+ EXPECT_FALSE(ptr);
+ EXPECT_EQ(ptr.get(), nullptr);
+
+ g_instances = 0;
+
+ for (int i = 0; i < 3; i++) {
+ ptr.reset(new RObj());
+ EXPECT_TRUE(ptr);
+ EXPECT_NE(ptr.get(), nullptr);
+ EXPECT_EQ(g_instances, 1);
+ }
+
+ ptr.reset();
+ EXPECT_EQ(g_instances, 0);
+ EXPECT_FALSE(ptr);
+
+ ptr.reset(new RObj());
+ ptr.reset(nullptr);
+ EXPECT_EQ(g_instances, 0);
+ EXPECT_FALSE(ptr);
+
+ // Test RAII.
+ {
+ RefPtr<RObj> ptr1(new RObj());
+ EXPECT_EQ(g_instances, 1);
+ {
+ RefPtr<RObj> ptr2(new RObj());
+ EXPECT_EQ(g_instances, 2);
+ }
+ EXPECT_EQ(g_instances, 1);
+ }
+ EXPECT_EQ(g_instances, 0);
+}
+
+TEST(RefCountedTest, CopyOperators) {
+ g_instances = 0;
+
+ RefPtr<RObj> x1(new RObj());
+ RefPtr<RObj> y1(new RObj());
+ EXPECT_EQ(g_instances, 2);
+
+ auto x2 = x1;
+ EXPECT_EQ(g_instances, 2);
+
+ auto y2 = y1;
+ EXPECT_EQ(g_instances, 2);
+
+ EXPECT_EQ(x1.get(), x2.get());
+ EXPECT_EQ(&*y1, &*y2);
+
+ x1.reset();
+ y2.reset();
+ EXPECT_EQ(g_instances, 2);
+
+ x2.reset();
+ EXPECT_EQ(g_instances, 1);
+
+ y1 = x2;
+ EXPECT_EQ(g_instances, 0);
+
+ {
+ RefPtr<RObj> nested1(new RObj());
+ EXPECT_EQ(g_instances, 1);
+ {
+ RefPtr<RObj> nested2(new RObj());
+ EXPECT_EQ(g_instances, 2);
+ nested1 = nested2;
+ EXPECT_EQ(g_instances, 1);
+ }
+ EXPECT_EQ(g_instances, 1);
+ }
+ EXPECT_EQ(g_instances, 0);
+}
+
+TEST(RefCountedTest, MoveOperators) {
+ g_instances = 0;
+
+ RefPtr<RObj> x1(new RObj());
+ RefPtr<RObj> y1(new RObj());
+ EXPECT_EQ(g_instances, 2);
+
+ auto x2 = std::move(x1);
+ EXPECT_EQ(g_instances, 2);
+ EXPECT_FALSE(x1);
+
+ auto y2 = std::move(y1);
+ EXPECT_EQ(g_instances, 2);
+ EXPECT_FALSE(y1);
+
+ // Test recycling.
+ x1 = RefPtr<RObj>(new RObj());
+ EXPECT_EQ(g_instances, 3);
+
+ // y1 is still null;
+ y2 = std::move(y1);
+ EXPECT_FALSE(y1);
+ EXPECT_FALSE(y2);
+ EXPECT_EQ(g_instances, 2); // y2 goes away.
+
+ // We are left with x1 and x2.
+ EXPECT_TRUE(x1);
+ EXPECT_TRUE(x2);
+ EXPECT_NE(&*x1, &*x2);
+
+ x1 = std::move(x2); // Now only x1 is left.
+ EXPECT_EQ(g_instances, 1);
+ EXPECT_FALSE(x2);
+
+ x1 = std::move(x2);
+ EXPECT_EQ(g_instances, 0);
+
+ {
+ RefPtr<RObj> nested1(new RObj());
+ EXPECT_EQ(g_instances, 1);
+ {
+ RefPtr<RObj> nested2(new RObj());
+ EXPECT_EQ(g_instances, 2);
+ nested1 = std::move(nested2);
+ EXPECT_EQ(g_instances, 1);
+ }
+ EXPECT_EQ(g_instances, 1);
+ }
+ EXPECT_EQ(g_instances, 0);
+}
+
+} // namespace
+} // namespace trace_processor
+} // namespace perfetto