]> git.proxmox.com Git - ceph.git/blame - ceph/src/test/test_mempool.cc
update sources to v12.1.0
[ceph.git] / ceph / src / test / test_mempool.cc
CommitLineData
7c673cae
FG
1// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2// vim: ts=8 sw=2 smarttab
3/*
4 * Ceph distributed storage system
5 *
6 * Copyright (C) 2016 Western Digital Corporation
7 *
8 * Author: Allen Samuels <allen.samuels@sandisk.com>
9 *
10 * This library is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU Lesser General Public
12 * License as published by the Free Software Foundation; either
13 * version 2.1 of the License, or (at your option) any later version.
14 *
15 */
16
17#include <stdio.h>
18
19#include "global/global_init.h"
20#include "common/ceph_argparse.h"
21#include "global/global_context.h"
22#include "gtest/gtest.h"
23#include "include/mempool.h"
24
25void check_usage(mempool::pool_index_t ix)
26{
27 mempool::pool_t *pool = &mempool::get_pool(ix);
28 mempool::stats_t total;
29 map<std::string,mempool::stats_t> m;
30 pool->get_stats(&total, &m);
31 size_t usage = pool->allocated_bytes();
32 size_t sum = 0;
33 for (auto& p : m) {
34 sum += p.second.bytes;
35 }
36 if (sum != usage) {
37 ceph::TableFormatter jf;
38 pool->dump(&jf);
39 jf.flush(std::cout);
40 }
41 EXPECT_EQ(sum, usage);
42}
43
44template<typename A, typename B>
45void eq_elements(const A& a, const B& b)
46{
47 auto lhs = a.begin();
48 auto rhs = b.begin();
49 while (lhs != a.end()) {
50 EXPECT_EQ(*lhs,*rhs);
51 lhs++;
52 rhs++;
53 }
54 EXPECT_EQ(rhs,b.end());
55}
56
57template<typename A, typename B>
58void eq_pairs(const A& a, const B& b)
59{
60 auto lhs = a.begin();
61 auto rhs = b.begin();
62 while (lhs != a.end()) {
63 EXPECT_EQ(lhs->first,rhs->first);
64 EXPECT_EQ(lhs->second,rhs->second);
65 lhs++;
66 rhs++;
67 }
68 EXPECT_EQ(rhs,b.end());
69}
70
71#define MAKE_INSERTER(inserter) \
72 template<typename A,typename B> \
73void do_##inserter(A& a, B& b, int count, int base) { \
74 for (int i = 0; i < count; ++i) { \
75 a.inserter(base + i); \
76 b.inserter(base + i); \
77 } \
78}
79
80MAKE_INSERTER(push_back);
81MAKE_INSERTER(insert);
82
83template<typename A,typename B>
84void do_insert_key(A& a, B& b, int count, int base)
85{
86 for (int i = 0; i < count; ++i) {
87 a.insert(make_pair(base+i,base+i));
88 b.insert(make_pair(base+i,base+i));
31f18b77 89 check_usage(mempool::osd::id);
7c673cae
FG
90 }
91}
92
93TEST(mempool, vector_context)
94{
31f18b77
FG
95 check_usage(mempool::osd::id);
96 EXPECT_EQ(mempool::osd::allocated_bytes(), 0u);
97 EXPECT_EQ(mempool::osd::allocated_items(), 0u);
7c673cae
FG
98 for (unsigned i = 0; i < 10; ++i) {
99 vector<int> a;
31f18b77 100 mempool::osd::vector<int> b,c;
7c673cae
FG
101 eq_elements(a,b);
102 do_push_back(a,b,i,i);
103 eq_elements(a,b);
31f18b77 104 check_usage(mempool::osd::id);
7c673cae
FG
105
106 mempool::stats_t total;
107 map<std::string,mempool::stats_t> by_type;
31f18b77
FG
108 mempool::get_pool(mempool::osd::id).get_stats(&total, &by_type);
109 EXPECT_GE(mempool::osd::allocated_bytes(), i * 4u);
110 EXPECT_GE(mempool::osd::allocated_items(), i);
7c673cae
FG
111
112 c.swap(b);
113 eq_elements(a,c);
31f18b77 114 check_usage(mempool::osd::id);
7c673cae
FG
115 a.clear();
116 b.clear();
117 c.clear();
118 }
119}
120
121TEST(mempool, list_context)
122{
123 for (unsigned i = 1; i < 10; ++i) {
124 list<int> a;
31f18b77 125 mempool::osd::list<int> b,c;
7c673cae
FG
126 eq_elements(a,b);
127 do_push_back(a,b,i,i);
128 eq_elements(a,b);
129 c.swap(b);
130 eq_elements(a,c);
131 a.erase(a.begin());
132 c.erase(c.begin());
133 eq_elements(a,c);
134 a.clear();
135 b.clear();
136 c.clear();
137 do_push_back(a,b,i,i);
138 c.splice(c.begin(),b,b.begin(),b.end());
139
140 mempool::stats_t total;
141 map<std::string,mempool::stats_t> by_type;
31f18b77
FG
142 mempool::get_pool(mempool::osd::id).get_stats(&total, &by_type);
143 EXPECT_GE(mempool::osd::allocated_bytes(), i * 4u);
144 EXPECT_EQ(mempool::osd::allocated_items(), i);
7c673cae
FG
145
146 eq_elements(a,c);
31f18b77 147 check_usage(mempool::osd::id);
7c673cae
FG
148 }
149}
150
151TEST(mempool, set_context)
152{
153 for (int i = 0; i < 10; ++i) {
154 set<int> a;
31f18b77 155 mempool::osd::set<int> b;
7c673cae
FG
156 do_insert(a,b,i,i);
157 eq_elements(a,b);
31f18b77 158 check_usage(mempool::osd::id);
7c673cae
FG
159 }
160
161 for (int i = 1; i < 10; ++i) {
162 set<int> a;
31f18b77 163 mempool::osd::set<int> b;
7c673cae
FG
164 do_insert(a,b,i,0);
165 EXPECT_NE(a.find(i/2),a.end());
166 EXPECT_NE(b.find(i/2),b.end());
167 a.erase(a.find(i/2));
168 b.erase(b.find(i/2));
169 eq_elements(a,b);
31f18b77 170 check_usage(mempool::osd::id);
7c673cae
FG
171 }
172}
173
174struct obj {
175 MEMPOOL_CLASS_HELPERS();
176 int a;
177 int b;
178 obj() : a(1), b(1) {}
179 obj(int _a) : a(_a), b(2) {}
180 obj(int _a,int _b) : a(_a), b(_b) {}
181 friend inline bool operator<(const obj& l, const obj& r) {
182 return l.a < r.a;
183 }
184};
31f18b77 185MEMPOOL_DEFINE_OBJECT_FACTORY(obj, obj, osdmap);
7c673cae
FG
186
187TEST(mempool, test_factory)
188{
189 obj *o1 = new obj();
190 obj *o2 = new obj(10);
191 obj *o3 = new obj(20,30);
31f18b77 192 check_usage(mempool::osdmap::id);
7c673cae
FG
193 EXPECT_NE(o1,nullptr);
194 EXPECT_EQ(o1->a,1);
195 EXPECT_EQ(o1->b,1);
196 EXPECT_EQ(o2->a,10);
197 EXPECT_EQ(o2->b,2);
198 EXPECT_EQ(o3->a,20);
199 EXPECT_EQ(o3->b,30);
200
201 delete o1;
202 delete o2;
203 delete o3;
31f18b77 204 check_usage(mempool::osdmap::id);
7c673cae
FG
205}
206
207TEST(mempool, vector)
208{
209 {
31f18b77 210 mempool::osd::vector<int> v;
7c673cae
FG
211 v.push_back(1);
212 v.push_back(2);
213 }
214 {
31f18b77 215 mempool::osdmap::vector<obj> v;
7c673cae
FG
216 v.push_back(obj());
217 v.push_back(obj(1));
218 }
219}
220
221TEST(mempool, set)
222{
31f18b77 223 mempool::osd::set<int> set_int;
7c673cae
FG
224 set_int.insert(1);
225 set_int.insert(2);
31f18b77 226 mempool::osdmap::set<obj> set_obj;
7c673cae
FG
227 set_obj.insert(obj());
228 set_obj.insert(obj(1));
229 set_obj.insert(obj(1, 2));
230}
231
232TEST(mempool, map)
233{
234 {
31f18b77 235 mempool::osd::map<int,int> v;
7c673cae
FG
236 v[1] = 2;
237 v[3] = 4;
238 }
239 {
31f18b77 240 mempool::osdmap::map<int,obj> v;
7c673cae
FG
241 v[1] = obj();
242 v[2] = obj(2);
243 v[3] = obj(2, 3);
244 }
245}
246
247TEST(mempool, list)
248{
249 {
31f18b77 250 mempool::osd::list<int> v;
7c673cae
FG
251 v.push_back(1);
252 v.push_back(2);
253 }
254 {
31f18b77 255 mempool::osdmap::list<obj> v;
7c673cae
FG
256 v.push_back(obj());
257 v.push_back(obj(1));
258 }
259}
260
261TEST(mempool, unordered_map)
262{
31f18b77 263 mempool::osdmap::unordered_map<int,obj> h;
7c673cae
FG
264 h[1] = obj();
265 h[2] = obj(1);
266}
267
31f18b77
FG
268TEST(mempool, string_test)
269{
270 mempool::osdmap::string s;
271 s.reserve(100);
272 EXPECT_GE(mempool::osdmap::allocated_items(), s.capacity() + 1u); // +1 for zero-byte termination :
273 for (size_t i = 0; i < 10; ++i) {
274 s += '1';
275 s.append(s);
276 EXPECT_GE(mempool::osdmap::allocated_items(), s.capacity() + 1u);
277 }
278}
279
7c673cae
FG
280TEST(mempool, bufferlist)
281{
282 bufferlist bl;
283 int len = 1048576;
31f18b77 284 size_t before = mempool::buffer_anon::allocated_bytes();
7c673cae
FG
285 cout << "before " << before << std::endl;
286 bl.append(buffer::create_aligned(len, 4096));
31f18b77 287 size_t after = mempool::buffer_anon::allocated_bytes();
7c673cae
FG
288 cout << "after " << after << std::endl;
289 ASSERT_GE(after, before + len);
290}
291
31f18b77 292TEST(mempool, bufferlist_reassign)
7c673cae 293{
31f18b77
FG
294 bufferlist bl;
295 size_t items_before = mempool::buffer_anon::allocated_items();
296 size_t bytes_before = mempool::buffer_anon::allocated_bytes();
297 bl.append("fooo");
298 ASSERT_EQ(items_before + 1, mempool::buffer_anon::allocated_items());
299 ASSERT_LT(bytes_before, mempool::buffer_anon::allocated_bytes());
300
301 // move existing bl
302 bl.reassign_to_mempool(mempool::mempool_osd);
303 ASSERT_EQ(items_before, mempool::buffer_anon::allocated_items());
304 ASSERT_EQ(bytes_before, mempool::buffer_anon::allocated_bytes());
305
306 // additional appends should go to the same pool
307 items_before = mempool::osd::allocated_items();
308 bytes_before = mempool::osd::allocated_bytes();
309 cout << "anon b " << mempool::buffer_anon::allocated_bytes() << std::endl;
310 for (unsigned i = 0; i < 1000; ++i) {
311 bl.append("asdfddddddddddddddddddddddasfdasdfasdfasdfasdfasdf");
7c673cae 312 }
31f18b77
FG
313 cout << "anon a " << mempool::buffer_anon::allocated_bytes() << std::endl;
314 ASSERT_LT(items_before, mempool::osd::allocated_items());
315 ASSERT_LT(bytes_before, mempool::osd::allocated_bytes());
316
317 // try_.. won't
318 items_before = mempool::osd::allocated_items();
319 bytes_before = mempool::osd::allocated_bytes();
320 bl.try_assign_to_mempool(mempool::mempool_bloom_filter);
321 ASSERT_EQ(items_before, mempool::osd::allocated_items());
322 ASSERT_EQ(bytes_before, mempool::osd::allocated_bytes());
7c673cae
FG
323}
324
325int main(int argc, char **argv)
326{
327 vector<const char*> args;
328 argv_to_vec(argc, (const char **)argv, args);
329
330 auto cct = global_init(NULL, args, CEPH_ENTITY_TYPE_CLIENT,
331 CODE_ENVIRONMENT_UTILITY, 0);
332 common_init_finish(g_ceph_context);
333
334 // enable debug mode for the tests
335 mempool::set_debug_mode(true);
336
337 ::testing::InitGoogleTest(&argc, argv);
338 return RUN_ALL_TESTS();
339}
340
341
342/*
343 * Local Variables:
344 * compile-command: "cd ../../build ; make -j4 &&
345 * make unittest_mempool &&
346 * valgrind --tool=memcheck ./unittest_mempool --gtest_filter=*.*"
347 * End:
348 */