Index: base/trace_event/memory_usage_estimator_unittest.cc |
diff --git a/base/trace_event/memory_usage_estimator_unittest.cc b/base/trace_event/memory_usage_estimator_unittest.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..b77d5fdc9797f3167131bc01e0520afc6a3b5503 |
--- /dev/null |
+++ b/base/trace_event/memory_usage_estimator_unittest.cc |
@@ -0,0 +1,229 @@ |
+// Copyright 2016 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include "base/trace_event/memory_usage_estimator.h" |
+ |
+#include <stdlib.h> |
+ |
+#include "base/memory/ptr_util.h" |
+#include "base/strings/string16.h" |
+#include "build/build_config.h" |
+#include "testing/gtest/include/gtest/gtest.h" |
+ |
+#if defined(ARCH_CPU_64_BITS) |
+#define EXPECT_EQ_32_64(_, e, a) EXPECT_EQ(e, a) |
+#else |
+#define EXPECT_EQ_32_64(e, _, a) EXPECT_EQ(e, a) |
+#endif |
+ |
+namespace base { |
+namespace trace_event { |
+ |
+namespace { |
+ |
+// Test class with predictable memory usage. |
+class Data { |
+ public: |
+ explicit Data(size_t size = 17): size_(size) { |
+ } |
+ |
+ size_t size() const { return size_; } |
+ |
+ size_t EstimateMemoryUsage() const { |
+ return size_; |
+ } |
+ |
+ bool operator < (const Data& other) const { |
+ return size_ < other.size_; |
+ } |
+ bool operator == (const Data& other) const { |
+ return size_ == other.size_; |
+ } |
+ |
+ struct Hasher { |
+ size_t operator () (const Data& data) const { |
+ return data.size(); |
+ } |
+ }; |
+ |
+ private: |
+ size_t size_; |
+}; |
+ |
+} // namespace |
+ |
+namespace internal { |
+ |
+// This kills variance of bucket_count across STL implementations. |
+template <> |
+size_t HashMapBucketCountForTesting<Data>(size_t) { |
+ return 10; |
+} |
+template <> |
+size_t HashMapBucketCountForTesting<std::pair<const Data, short>>(size_t) { |
+ return 10; |
+} |
+ |
+} // namespace internal |
+ |
+TEST(EstimateMemoryUsageTest, String) { |
+ std::string string(777, 'a'); |
+ EXPECT_EQ(string.capacity() + 1, EstimateMemoryUsage(string)); |
+} |
+ |
+TEST(EstimateMemoryUsageTest, String16) { |
+ string16 string(777, 'a'); |
+ EXPECT_EQ(sizeof(char16) * (string.capacity() + 1), |
+ EstimateMemoryUsage(string)); |
+} |
+ |
+TEST(EstimateMemoryUsageTest, Arrays) { |
+ // std::array |
+ { |
+ std::array<Data, 10> array; |
+ EXPECT_EQ(170u, EstimateMemoryUsage(array)); |
+ } |
+ |
+ // T[N] |
+ { |
+ Data array[10]; |
+ EXPECT_EQ(170u, EstimateMemoryUsage(array)); |
+ } |
+ |
+ // C array |
+ { |
+ struct Item { |
+ char payload[10]; |
+ }; |
+ Item* array = new Item[7]; |
+ EXPECT_EQ(70u, EstimateMemoryUsage(array, 7)); |
+ delete[] array; |
+ } |
+} |
+ |
+TEST(EstimateMemoryUsageTest, UniquePtr) { |
+ // Empty |
+ { |
+ std::unique_ptr<Data> ptr; |
+ EXPECT_EQ(0u, EstimateMemoryUsage(ptr)); |
+ } |
+ |
+ // Not empty |
+ { |
+ std::unique_ptr<Data> ptr(new Data()); |
+ EXPECT_EQ_32_64(21u, 25u, EstimateMemoryUsage(ptr)); |
+ } |
+ |
+ // With a pointer |
+ { |
+ std::unique_ptr<Data*> ptr(new Data*()); |
+ EXPECT_EQ(sizeof(void*), EstimateMemoryUsage(ptr)); |
+ } |
+ |
+ // With an array |
+ { |
+ struct Item { |
+ uint32_t payload[10]; |
+ }; |
+ std::unique_ptr<Item[]> ptr(new Item[7]); |
+ EXPECT_EQ(280u, EstimateMemoryUsage(ptr, 7)); |
+ } |
+} |
+ |
+TEST(EstimateMemoryUsageTest, Vector) { |
+ std::vector<Data> vector; |
+ vector.reserve(1000); |
+ |
+ // For an empty vector we should return memory usage of its buffer |
+ size_t capacity = vector.capacity(); |
+ size_t expected_size = capacity * sizeof(Data); |
+ EXPECT_EQ(expected_size, EstimateMemoryUsage(vector)); |
+ |
+ // If vector is not empty, its size should also include memory usages |
+ // of all elements. |
+ for (size_t i = 0; i != capacity / 2; ++i) { |
+ vector.push_back(Data(i)); |
+ expected_size += EstimateMemoryUsage(vector.back()); |
+ } |
+ EXPECT_EQ(expected_size, EstimateMemoryUsage(vector)); |
+} |
+ |
+TEST(EstimateMemoryUsageTest, List) { |
+ struct POD { |
+ short data; |
+ }; |
+ std::list<POD> list; |
+ for (int i = 0; i != 1000; ++i) { |
+ list.push_back(POD()); |
+ } |
+ EXPECT_EQ_32_64(12000u, 24000u, EstimateMemoryUsage(list)); |
+} |
+ |
+TEST(EstimateMemoryUsageTest, Set) { |
+ std::set<std::pair<int, Data>> set; |
+ for (int i = 0; i != 1000; ++i) { |
+ set.insert({i, Data(i)}); |
+ } |
+ EXPECT_EQ_32_64(523500u, 547500u, EstimateMemoryUsage(set)); |
+} |
+ |
+TEST(EstimateMemoryUsageTest, MultiSet) { |
+ std::multiset<bool> set; |
+ for (int i = 0; i != 1000; ++i) { |
+ set.insert((i & 1) != 0); |
+ } |
+ EXPECT_EQ_32_64(16000u, 32000u, EstimateMemoryUsage(set)); |
+} |
+ |
+TEST(EstimateMemoryUsageTest, Map) { |
+ std::map<Data, int> map; |
+ for (int i = 0; i != 1000; ++i) { |
+ map.insert({Data(i), i}); |
+ } |
+ EXPECT_EQ_32_64(523500u, 547500u, EstimateMemoryUsage(map)); |
+} |
+ |
+TEST(EstimateMemoryUsageTest, MultiMap) { |
+ std::multimap<char, Data> map; |
+ for (int i = 0; i != 1000; ++i) { |
+ map.insert({static_cast<char>(i), Data(i)}); |
+ } |
+ EXPECT_EQ_32_64(523500u, 547500u, EstimateMemoryUsage(map)); |
+} |
+ |
+TEST(EstimateMemoryUsageTest, UnorderedSet) { |
+ std::unordered_set<Data, Data::Hasher> set; |
+ for (int i = 0; i != 1000; ++i) { |
+ set.insert(Data(i)); |
+ } |
+ EXPECT_EQ_32_64(511540u, 523580u, EstimateMemoryUsage(set)); |
+} |
+ |
+TEST(EstimateMemoryUsageTest, UnorderedMultiSet) { |
+ std::unordered_multiset<Data, Data::Hasher> set; |
+ for (int i = 0; i != 500; ++i) { |
+ set.insert(Data(i)); |
+ set.insert(Data(i)); |
+ } |
+ EXPECT_EQ_32_64(261540u, 273580u, EstimateMemoryUsage(set)); |
+} |
+ |
+TEST(EstimateMemoryUsageTest, UnorderedMap) { |
+ std::unordered_map<Data, short, Data::Hasher> map; |
+ for (int i = 0; i != 1000; ++i) { |
+ map.insert({Data(i), static_cast<short>(i)}); |
+ } |
+ EXPECT_EQ_32_64(515540u, 531580u, EstimateMemoryUsage(map)); |
+} |
+ |
+TEST(EstimateMemoryUsageTest, UnorderedMultiMap) { |
+ std::unordered_multimap<Data, short, Data::Hasher> map; |
+ for (int i = 0; i != 1000; ++i) { |
+ map.insert({Data(i), static_cast<short>(i)}); |
+ } |
+ EXPECT_EQ_32_64(515540u, 531580u, EstimateMemoryUsage(map)); |
+} |
+ |
+} // namespace trace_event |
+} // namespace base |