1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
4 * Ceph - scalable distributed file system
6 * Copyright (C) 2014 Inktank <info@inktank.com>
8 * This is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public
10 * License version 2, as published by the Free Software
11 * Foundation. See file COPYING.
14 #include "mon/PGMap.h"
15 #include "gtest/gtest.h"
17 #include "include/stringify.h"
22 class CheckTextTable
: public TextTable
{
24 explicit CheckTextTable(bool verbose
) {
25 for (int i
= 0; i
< 5; i
++) {
26 define_column("", TextTable::LEFT
, TextTable::LEFT
);
29 for (int i
= 0; i
< 9; i
++) {
30 define_column("", TextTable::LEFT
, TextTable::LEFT
);
34 const string
& get(unsigned r
, unsigned c
) const {
35 ceph_assert(r
< row
.size());
36 ceph_assert(c
< row
[r
].size());
41 // copied from PGMap.cc
42 string
percentify(float a
) {
47 ss
<< std::fixed
<< std::setprecision(2) << a
;
52 // dump_object_stat_sum() is called by "ceph df" command
53 // with table, without formatter, verbose = true, not empty, avail > 0
54 TEST(pgmap
, dump_object_stat_sum_0
)
57 CheckTextTable
tbl(verbose
);
58 pool_stat_t pool_stat
;
59 object_stat_sum_t
& sum
= pool_stat
.stats
.sum
;
60 sum
.num_bytes
= 42 * 1024 * 1024;
62 sum
.num_objects_degraded
= 13; // there are 13 missings + not_yet_backfilled
63 sum
.num_objects_dirty
= 2;
68 pool_stat
.num_store_stats
= 3;
69 store_statfs_t
&statfs
= pool_stat
.store_stats
;
70 statfs
.data_stored
= 40 * 1024 * 1024;
71 statfs
.allocated
= 41 * 1024 * 1024 * 2;
72 statfs
.data_compressed_allocated
= 4334;
73 statfs
.data_compressed_original
= 1213;
75 sum
.calc_copies(3); // assuming we have 3 copies for each obj
76 // nominal amount of space available for new objects in this pool
77 uint64_t avail
= 2016 * 1024 * 1024;
79 pool
.quota_max_objects
= 2000;
80 pool
.quota_max_bytes
= 2000 * 1024 * 1024;
82 pool
.type
= pg_pool_t::TYPE_REPLICATED
;
84 PGMap::dump_object_stat_sum(tbl
, nullptr, pool_stat
, avail
,
85 pool
.get_size(), verbose
, true, true, &pool
);
87 (static_cast<float>(sum
.num_object_copies
- sum
.num_objects_degraded
) /
88 sum
.num_object_copies
) * pool
.get_size();
89 float used_percent
= (float)statfs
.allocated
/
90 (statfs
.allocated
+ avail
) * 100;
91 uint64_t stored
= statfs
.data_stored
/ copies_rate
;
94 ASSERT_EQ(stringify(byte_u_t(stored
)), tbl
.get(0, col
++));
95 ASSERT_EQ(stringify(byte_u_t(stored
)), tbl
.get(0, col
++));
96 ASSERT_EQ(stringify(byte_u_t(0)), tbl
.get(0, col
++));
97 ASSERT_EQ(stringify(si_u_t(sum
.num_objects
)), tbl
.get(0, col
++));
98 ASSERT_EQ(stringify(byte_u_t(statfs
.allocated
)), tbl
.get(0, col
++));
99 ASSERT_EQ(stringify(byte_u_t(statfs
.allocated
)), tbl
.get(0, col
++));
100 ASSERT_EQ(stringify(byte_u_t(0)), tbl
.get(0, col
++));
101 ASSERT_EQ(percentify(used_percent
), tbl
.get(0, col
++));
102 ASSERT_EQ(stringify(byte_u_t(avail
/copies_rate
)), tbl
.get(0, col
++));
103 ASSERT_EQ(stringify(si_u_t(pool
.quota_max_objects
)), tbl
.get(0, col
++));
104 ASSERT_EQ(stringify(byte_u_t(pool
.quota_max_bytes
)), tbl
.get(0, col
++));
105 ASSERT_EQ(stringify(si_u_t(sum
.num_objects_dirty
)), tbl
.get(0, col
++));
106 ASSERT_EQ(stringify(byte_u_t(statfs
.data_compressed_allocated
)), tbl
.get(0, col
++));
107 ASSERT_EQ(stringify(byte_u_t(statfs
.data_compressed_original
)), tbl
.get(0, col
++));
110 // with table, without formatter, verbose = true, empty, avail > 0
111 TEST(pgmap
, dump_object_stat_sum_1
)
114 CheckTextTable
tbl(verbose
);
115 pool_stat_t pool_stat
;
116 object_stat_sum_t
& sum
= pool_stat
.stats
.sum
; // zero by default
117 ASSERT_TRUE(sum
.is_zero());
118 // nominal amount of space available for new objects in this pool
119 uint64_t avail
= 2016 * 1024 * 1024;
121 pool
.quota_max_objects
= 2000;
122 pool
.quota_max_bytes
= 2000 * 1024 * 1024;
124 pool
.type
= pg_pool_t::TYPE_REPLICATED
;
126 PGMap::dump_object_stat_sum(tbl
, nullptr, pool_stat
, avail
,
127 pool
.get_size(), verbose
, true, true, &pool
);
129 ASSERT_EQ(stringify(byte_u_t(0)), tbl
.get(0, col
++));
130 ASSERT_EQ(stringify(byte_u_t(0)), tbl
.get(0, col
++));
131 ASSERT_EQ(stringify(byte_u_t(0)), tbl
.get(0, col
++));
132 ASSERT_EQ(stringify(si_u_t(0)), tbl
.get(0, col
++));
133 ASSERT_EQ(stringify(byte_u_t(0)), tbl
.get(0, col
++));
134 ASSERT_EQ(stringify(byte_u_t(0)), tbl
.get(0, col
++));
135 ASSERT_EQ(stringify(byte_u_t(0)), tbl
.get(0, col
++));
136 ASSERT_EQ(percentify(0), tbl
.get(0, col
++));
137 ASSERT_EQ(stringify(byte_u_t(avail
/pool
.size
)), tbl
.get(0, col
++));
138 ASSERT_EQ(stringify(si_u_t(pool
.quota_max_objects
)), tbl
.get(0, col
++));
139 ASSERT_EQ(stringify(byte_u_t(pool
.quota_max_bytes
)), tbl
.get(0, col
++));
140 ASSERT_EQ(stringify(si_u_t(0)), tbl
.get(0, col
++));
141 ASSERT_EQ(stringify(byte_u_t(0)), tbl
.get(0, col
++));
142 ASSERT_EQ(stringify(byte_u_t(0)), tbl
.get(0, col
++));
145 // with table, without formatter, verbose = false, empty, avail = 0
146 TEST(pgmap
, dump_object_stat_sum_2
)
148 bool verbose
= false;
149 CheckTextTable
tbl(verbose
);
150 pool_stat_t pool_stat
;
151 object_stat_sum_t
& sum
= pool_stat
.stats
.sum
; // zero by default
152 ASSERT_TRUE(sum
.is_zero());
153 // nominal amount of space available for new objects in this pool
156 pool
.quota_max_objects
= 2000;
157 pool
.quota_max_bytes
= 2000 * 1024 * 1024;
159 pool
.type
= pg_pool_t::TYPE_REPLICATED
;
161 PGMap::dump_object_stat_sum(tbl
, nullptr, pool_stat
, avail
,
162 pool
.get_size(), verbose
, true, true, &pool
);
164 ASSERT_EQ(stringify(byte_u_t(0)), tbl
.get(0, col
++));
165 ASSERT_EQ(stringify(si_u_t(0)), tbl
.get(0, col
++));
166 ASSERT_EQ(stringify(byte_u_t(0)), tbl
.get(0, col
++));
167 ASSERT_EQ(percentify(0), tbl
.get(0, col
++));
168 ASSERT_EQ(stringify(byte_u_t(avail
/pool
.size
)), tbl
.get(0, col
++));