1 /*
2  * Copyright 2021 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 "common/sync_map_count.h"
18 
19 #include <gmock/gmock.h>
20 #include <gtest/gtest.h>
21 
22 #include <cstddef>
23 #include <cstring>
24 #include <vector>
25 
26 namespace testing {
27 
28 const char* data[] = {
29         "One", "Two", "Two", "Three", "Three", "Three", "AAA", "ZZZ", nullptr,
30 };
31 
32 namespace {
LoadStringMap(SyncMapCount<std::string> & map)33 void LoadStringMap(SyncMapCount<std::string>& map) {
34   for (const char** p = data; *p != nullptr; p++) {
35     map.Put(*p);
36   }
37 }
38 }  // namespace
39 
TEST(SyncMapCount,simple)40 TEST(SyncMapCount, simple) {
41   SyncMapCount<std::string> map;
42   LoadStringMap(map);
43 
44   ASSERT_EQ(5ul, map.Size());
45 
46   auto m = map.Get();
47   ASSERT_EQ(3ul, m["Three"]);
48   ASSERT_EQ(2ul, m["Two"]);
49   ASSERT_EQ(1ul, m["One"]);
50 }
51 
TEST(SyncMapCount,sized)52 TEST(SyncMapCount, sized) {
53   SyncMapCount<std::string> map(2);
54   LoadStringMap(map);
55 
56   ASSERT_EQ(2ul, map.Size());
57 }
58 
TEST(SyncMapCount,sorted_string_value_low_to_high)59 TEST(SyncMapCount, sorted_string_value_low_to_high) {
60   SyncMapCount<std::string> map;
61   LoadStringMap(map);
62 
63   auto entries = map.GetSortedLowToHigh();
64   ASSERT_EQ(3ul, entries[entries.size() - 1].count);
65   ASSERT_EQ(2ul, entries[entries.size() - 2].count);
66 }
67 
TEST(SyncMapCount,sorted_string_value_high_to_low)68 TEST(SyncMapCount, sorted_string_value_high_to_low) {
69   SyncMapCount<std::string> map;
70   LoadStringMap(map);
71 
72   auto entries = map.GetSortedHighToLow();
73   ASSERT_EQ(3ul, entries[0].count);
74   ASSERT_EQ(2ul, entries[1].count);
75 }
76 
77 struct TestString {
TestStringtesting::TestString78   TestString(std::string string) : string_(string) {}
Stringtesting::TestString79   std::string String() const { return string_; }
80 
operator <testing::TestString81   bool operator<(const TestString& other) const { return other.string_ > string_; }
operator ==testing::TestString82   bool operator==(const TestString& other) const { return other.string_ == string_; }
83 
84 private:
85   std::string string_;
86 };
87 
88 namespace {
LoadTestStringMap(SyncMapCount<TestString> & map)89 void LoadTestStringMap(SyncMapCount<TestString>& map) {
90   for (const char** p = data; *p != nullptr; p++) {
91     map.Put(TestString(*p));
92   }
93 }
94 }  // namespace
95 
TEST(SyncMapCount,simple_struct)96 TEST(SyncMapCount, simple_struct) {
97   SyncMapCount<TestString> map;
98   LoadTestStringMap(map);
99 
100   ASSERT_EQ(5ul, map.Size());
101 
102   auto m = map.Get();
103   ASSERT_EQ(3ul, m[TestString("Three")]);
104   ASSERT_EQ(2ul, m[TestString("Two")]);
105   ASSERT_EQ(1ul, m[TestString("One")]);
106 }
107 
TEST(SyncMapCount,sorted_string_struct_value_low_to_high)108 TEST(SyncMapCount, sorted_string_struct_value_low_to_high) {
109   SyncMapCount<TestString> map;
110   LoadTestStringMap(map);
111 
112   auto entries = map.GetSortedLowToHigh();
113   ASSERT_EQ(3ul, entries[entries.size() - 1].count);
114   ASSERT_EQ(2ul, entries[entries.size() - 2].count);
115 }
116 
TEST(SyncMapCount,sorted_string_struct_value_high_to_low)117 TEST(SyncMapCount, sorted_string_struct_value_high_to_low) {
118   SyncMapCount<TestString> map;
119   LoadTestStringMap(map);
120 
121   auto entries = map.GetSortedHighToLow();
122   ASSERT_EQ(3ul, entries[0].count);
123   ASSERT_EQ(2ul, entries[1].count);
124 }
125 
TEST(SyncMapCount,locked_for_map_copy)126 TEST(SyncMapCount, locked_for_map_copy) {
127   SyncMapCount<TestString> map;
128   LoadTestStringMap(map);
129 
130   ASSERT_EQ(5ul, map.Size());
131   std::vector<SyncMapCount<TestString>::Item> vec;
132   for (auto& it : map.Get()) {
133     map.Clear();
134     vec.push_back(SyncMapCount<TestString>::Item{it.first, it.second});
135   }
136   ASSERT_EQ(0ul, map.Size());
137   ASSERT_EQ(5ul, vec.size());
138 }
139 
140 }  // namespace testing
141