1 /*
2  * Copyright (C) 2018 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 "src/profiling/common/interner.h"
18 
19 #include "test/gtest_and_gmock.h"
20 
21 namespace perfetto {
22 namespace profiling {
23 namespace {
24 
TEST(InternerStringTest,Basic)25 TEST(InternerStringTest, Basic) {
26   Interner<std::string> interner;
27   {
28     Interned<std::string> interned_str = interner.Intern("foo");
29     ASSERT_EQ(interned_str.data(), "foo");
30   }
31   ASSERT_EQ(interner.entry_count_for_testing(), 0u);
32 }
33 
TEST(InternerStringTest,TwoStrings)34 TEST(InternerStringTest, TwoStrings) {
35   Interner<std::string> interner;
36   {
37     Interned<std::string> interned_str = interner.Intern("foo");
38     Interned<std::string> other_interned_str = interner.Intern("bar");
39     ASSERT_EQ(interned_str.data(), "foo");
40     ASSERT_EQ(other_interned_str.data(), "bar");
41   }
42   ASSERT_EQ(interner.entry_count_for_testing(), 0u);
43 }
44 
TEST(InternerStringTest,TwoReferences)45 TEST(InternerStringTest, TwoReferences) {
46   Interner<std::string> interner;
47   {
48     Interned<std::string> interned_str = interner.Intern("foo");
49     ASSERT_EQ(interned_str.data(), "foo");
50     Interned<std::string> interned_str2 = interner.Intern("foo");
51     ASSERT_EQ(interner.entry_count_for_testing(), 1u);
52     ASSERT_EQ(interned_str2.data(), "foo");
53   }
54   ASSERT_EQ(interner.entry_count_for_testing(), 0u);
55 }
56 
TEST(InternerStringTest,Move)57 TEST(InternerStringTest, Move) {
58   Interner<std::string> interner;
59   {
60     Interned<std::string> interned_str = interner.Intern("foo");
61     {
62       Interned<std::string> interned_str2(std::move(interned_str));
63       ASSERT_EQ(interner.entry_count_for_testing(), 1u);
64       ASSERT_EQ(interned_str2.data(), "foo");
65     }
66     ASSERT_EQ(interner.entry_count_for_testing(), 0u);
67   }
68 }
69 
TEST(InternerStringTest,Copy)70 TEST(InternerStringTest, Copy) {
71   Interner<std::string> interner;
72   {
73     Interned<std::string> interned_str = interner.Intern("foo");
74     {
75       Interned<std::string> interned_str2(interned_str);
76       ASSERT_EQ(interner.entry_count_for_testing(), 1u);
77       ASSERT_EQ(interned_str2.data(), "foo");
78     }
79     ASSERT_EQ(interner.entry_count_for_testing(), 1u);
80     ASSERT_EQ(interned_str.data(), "foo");
81   }
82 }
83 
TEST(InternerStringTest,MoveAssign)84 TEST(InternerStringTest, MoveAssign) {
85   Interner<std::string> interner;
86   {
87     Interned<std::string> interned_str = interner.Intern("foo");
88     {
89       Interned<std::string> interned_str2 = std::move(interned_str);
90       ASSERT_EQ(interner.entry_count_for_testing(), 1u);
91       ASSERT_EQ(interned_str2.data(), "foo");
92     }
93     ASSERT_EQ(interner.entry_count_for_testing(), 0u);
94   }
95 }
96 
TEST(InternerStringTest,CopyAssign)97 TEST(InternerStringTest, CopyAssign) {
98   Interner<std::string> interner;
99   {
100     Interned<std::string> interned_str = interner.Intern("foo");
101     {
102       Interned<std::string> interned_str2 = interned_str;
103       ASSERT_EQ(interner.entry_count_for_testing(), 1u);
104       ASSERT_EQ(interned_str2.data(), "foo");
105     }
106     ASSERT_EQ(interner.entry_count_for_testing(), 1u);
107     ASSERT_EQ(interned_str.data(), "foo");
108   }
109 }
110 
TEST(InternerStringTest,IDsUnique)111 TEST(InternerStringTest, IDsUnique) {
112   Interner<std::string> interner;
113   Interned<std::string> interned_str = interner.Intern("foo");
114   Interned<std::string> same_interned_str = interner.Intern("foo");
115   Interned<std::string> other_interned_str = interner.Intern("bar");
116   EXPECT_EQ(interned_str.id(), same_interned_str.id());
117   EXPECT_NE(interned_str.id(), other_interned_str.id());
118 }
119 
TEST(InternerStringTest,IdsConsecutive)120 TEST(InternerStringTest, IdsConsecutive) {
121   Interner<std::string> interner;
122   {
123     Interned<std::string> interned_str = interner.Intern("foo");
124     interner.Intern("foo");
125     Interned<std::string> other_interned_str = interner.Intern("bar");
126     ASSERT_EQ(interned_str.id() + 1, other_interned_str.id());
127   }
128   ASSERT_EQ(interner.entry_count_for_testing(), 0u);
129 }
130 
131 }  // namespace
132 }  // namespace profiling
133 }  // namespace perfetto
134