X-Git-Url: https://gerrit.opnfv.org/gerrit/gitweb?a=blobdiff_plain;f=src%2Fceph%2Fsrc%2Ftest%2Fmon%2FPGMap.cc;fp=src%2Fceph%2Fsrc%2Ftest%2Fmon%2FPGMap.cc;h=37648b9e52bd7f615ed08d429465abfe0d703369;hb=812ff6ca9fcd3e629e49d4328905f33eee8ca3f5;hp=0000000000000000000000000000000000000000;hpb=15280273faafb77777eab341909a3f495cf248d9;p=stor4nfv.git diff --git a/src/ceph/src/test/mon/PGMap.cc b/src/ceph/src/test/mon/PGMap.cc new file mode 100644 index 0000000..37648b9 --- /dev/null +++ b/src/ceph/src/test/mon/PGMap.cc @@ -0,0 +1,244 @@ +// -*- mode:C; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2014 Inktank + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public + * License version 2, as published by the Free Software + * Foundation. See file COPYING. + */ + +#include "mon/PGMap.h" +#include "gtest/gtest.h" + +#include "include/stringify.h" + +TEST(pgmap, min_last_epoch_clean) +{ + PGMap pg_map; + PGMap::Incremental inc; + osd_stat_t os; + pg_stat_t ps; + + ps.last_epoch_clean = 999; + inc.pg_stat_updates[pg_t(9,9)] = ps; + inc.version = 1; + inc.update_stat(0, 123, os); + pg_map.apply_incremental(g_ceph_context, inc); + ASSERT_EQ(123u, pg_map.get_min_last_epoch_clean()); + + inc = PGMap::Incremental(); + inc.version = 2; + inc.update_stat(1, 222, os); + pg_map.apply_incremental(g_ceph_context, inc); + ASSERT_EQ(123u, pg_map.get_min_last_epoch_clean()); + + inc = PGMap::Incremental(); + inc.version = 3; + inc.update_stat(0, 222, os); + pg_map.apply_incremental(g_ceph_context, inc); + ASSERT_EQ(222u, pg_map.get_min_last_epoch_clean()); + + inc = PGMap::Incremental(); + inc.version = 4; + inc.update_stat(0, 333, os); + inc.update_stat(1, 333, os); + pg_map.apply_incremental(g_ceph_context, inc); + ASSERT_EQ(333u, pg_map.get_min_last_epoch_clean()); + + ps.last_epoch_clean = 222; + inc = PGMap::Incremental(); + inc.version = 5; + inc.pg_stat_updates[pg_t(1,1)] = ps; + pg_map.apply_incremental(g_ceph_context, inc); + ASSERT_EQ(222u, pg_map.get_min_last_epoch_clean()); + + ps.last_epoch_clean = 223; + inc = PGMap::Incremental(); + inc.version = 6; + inc.pg_stat_updates[pg_t(1,1)] = ps; + pg_map.apply_incremental(g_ceph_context, inc); + ASSERT_EQ(223u, pg_map.get_min_last_epoch_clean()); + + ps.last_epoch_clean = 224; + inc = PGMap::Incremental(); + inc.version = 7; + inc.pg_stat_updates[pg_t(2,2)] = ps; + pg_map.apply_incremental(g_ceph_context, inc); + ASSERT_EQ(223u, pg_map.get_min_last_epoch_clean()); + + ps.last_epoch_clean = 225; + inc = PGMap::Incremental(); + inc.version = 8; + inc.pg_stat_updates[pg_t(1,1)] = ps; + pg_map.apply_incremental(g_ceph_context, inc); + ASSERT_EQ(224u, pg_map.get_min_last_epoch_clean()); + +} + +TEST(pgmap, calc_stats) +{ + bufferlist bl; + { + PGMap pg_map; + PGMap::Incremental inc; + osd_stat_t os; + pg_stat_t ps; + + ps.last_epoch_clean = 999; + inc.pg_stat_updates[pg_t(9,9)] = ps; + inc.version = 1; + inc.update_stat(0, 123, os); + pg_map.apply_incremental(g_ceph_context, inc); + ASSERT_EQ(123u, pg_map.get_min_last_epoch_clean()); + pg_map.encode(bl); + } + { + PGMap pg_map; + PGMap::Incremental inc; + osd_stat_t os; + pg_stat_t ps; + + ps.last_epoch_clean = 999; + inc.pg_stat_updates[pg_t(9,9)] = ps; + inc.version = 1; + inc.update_stat(0, 321, os); + pg_map.apply_incremental(g_ceph_context, inc); + ASSERT_EQ(321u, pg_map.get_min_last_epoch_clean()); + bufferlist::iterator p = bl.begin(); + ::decode(pg_map, p); + ASSERT_EQ(123u, pg_map.get_min_last_epoch_clean()); + } +} + +namespace { + class CheckTextTable : public TextTable { + public: + CheckTextTable(bool verbose) { + for (int i = 0; i < 4; i++) { + define_column("", TextTable::LEFT, TextTable::LEFT); + } + if (verbose) { + for (int i = 0; i < 4; i++) { + define_column("", TextTable::LEFT, TextTable::LEFT); + } + } + } + const string& get(unsigned r, unsigned c) const { + assert(r < row.size()); + assert(c < row[r].size()); + return row[r][c]; + } + }; + + // copied from PGMap.cc + string percentify(float a) { + stringstream ss; + if (a < 0.01) + ss << "0"; + else + ss << std::fixed << std::setprecision(2) << a; + return ss.str(); + } +} + +// dump_object_stat_sum() is called by "ceph df" command +// with table, without formatter, verbose = true, not empty, avail > 0 +TEST(pgmap, dump_object_stat_sum_0) +{ + bool verbose = true; + CheckTextTable tbl(verbose); + object_stat_sum_t sum; + sum.num_bytes = 42 * 1024 * 1024; + sum.num_objects = 42; + sum.num_objects_degraded = 13; // there are 13 missings + not_yet_backfilled + sum.num_objects_dirty = 2; + sum.num_rd = 100; + sum.num_rd_kb = 123; + sum.num_wr = 101; + sum.num_wr_kb = 321; + + sum.calc_copies(3); // assuming we have 3 copies for each obj + // nominal amount of space available for new objects in this pool + uint64_t avail = 2016 * 1024 * 1024; + pg_pool_t pool; + pool.quota_max_objects = 2000; + pool.quota_max_bytes = 2000 * 1024 * 1024; + pool.size = 2; + pool.type = pg_pool_t::TYPE_REPLICATED; + PGMap::dump_object_stat_sum(tbl, nullptr, sum, avail, + pool.get_size(), verbose, &pool); + ASSERT_EQ(stringify(si_t(sum.num_bytes)), tbl.get(0, 0)); + float copies_rate = + (static_cast(sum.num_object_copies - sum.num_objects_degraded) / + sum.num_object_copies); + float used_bytes = sum.num_bytes * copies_rate * pool.get_size(); + float used_percent = used_bytes / (used_bytes + avail) * 100; + unsigned col = 0; + ASSERT_EQ(stringify(si_t(sum.num_bytes)), tbl.get(0, col++)); + ASSERT_EQ(percentify(used_percent), tbl.get(0, col++)); + ASSERT_EQ(stringify(si_t(avail/pool.size)), tbl.get(0, col++)); + ASSERT_EQ(stringify(sum.num_objects), tbl.get(0, col++)); + ASSERT_EQ(stringify(si_t(sum.num_objects_dirty)), tbl.get(0, col++)); + ASSERT_EQ(stringify(si_t(sum.num_rd)), tbl.get(0, col++)); + ASSERT_EQ(stringify(si_t(sum.num_wr)), tbl.get(0, col++)); + // we can use pool.size for raw_used_rate if it is a replica pool + uint64_t raw_bytes_used = sum.num_bytes * pool.get_size() * copies_rate; + ASSERT_EQ(stringify(si_t(raw_bytes_used)), tbl.get(0, col++)); +} + +// with table, without formatter, verbose = true, empty, avail > 0 +TEST(pgmap, dump_object_stat_sum_1) +{ + bool verbose = true; + CheckTextTable tbl(verbose); + object_stat_sum_t sum; // zero by default + ASSERT_TRUE(sum.is_zero()); + // nominal amount of space available for new objects in this pool + uint64_t avail = 2016 * 1024 * 1024; + pg_pool_t pool; + pool.quota_max_objects = 2000; + pool.quota_max_bytes = 2000 * 1024 * 1024; + pool.size = 2; + pool.type = pg_pool_t::TYPE_REPLICATED; + PGMap::dump_object_stat_sum(tbl, nullptr, sum, avail, + pool.get_size(), verbose, &pool); + ASSERT_EQ(stringify(si_t(0)), tbl.get(0, 0)); + unsigned col = 0; + ASSERT_EQ(stringify(si_t(0)), tbl.get(0, col++)); + ASSERT_EQ(percentify(0), tbl.get(0, col++)); + ASSERT_EQ(stringify(si_t(avail/pool.size)), tbl.get(0, col++)); + ASSERT_EQ(stringify(0), tbl.get(0, col++)); + ASSERT_EQ(stringify(si_t(0)), tbl.get(0, col++)); + ASSERT_EQ(stringify(si_t(0)), tbl.get(0, col++)); + ASSERT_EQ(stringify(si_t(0)), tbl.get(0, col++)); + ASSERT_EQ(stringify(si_t(0)), tbl.get(0, col++)); +} + +// with table, without formatter, verbose = false, empty, avail = 0 +TEST(pgmap, dump_object_stat_sum_2) +{ + bool verbose = false; + CheckTextTable tbl(verbose); + object_stat_sum_t sum; // zero by default + ASSERT_TRUE(sum.is_zero()); + // nominal amount of space available for new objects in this pool + uint64_t avail = 0; + pg_pool_t pool; + pool.quota_max_objects = 2000; + pool.quota_max_bytes = 2000 * 1024 * 1024; + pool.size = 2; + pool.type = pg_pool_t::TYPE_REPLICATED; + + PGMap::dump_object_stat_sum(tbl, nullptr, sum, avail, + pool.get_size(), verbose, &pool); + ASSERT_EQ(stringify(si_t(0)), tbl.get(0, 0)); + unsigned col = 0; + ASSERT_EQ(stringify(si_t(0)), tbl.get(0, col++)); + ASSERT_EQ(percentify(0), tbl.get(0, col++)); + ASSERT_EQ(stringify(si_t(avail/pool.size)), tbl.get(0, col++)); + ASSERT_EQ(stringify(0), tbl.get(0, col++)); +}