]> git.proxmox.com Git - ceph.git/blame - ceph/src/test/perf_counters.cc
update sources to ceph Nautilus 14.2.1
[ceph.git] / ceph / src / test / perf_counters.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 - scalable distributed file system
5 *
6 * Copyright (C) 2011 New Dream Network
7 *
8 * This is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License version 2.1, as published by the Free Software
11 * Foundation. See file COPYING.
12 *
13 */
14#include "include/int_types.h"
15#include "include/types.h" // FIXME: ordering shouldn't be important, but right
16 // now, this include has to come before the others.
17
18
11fdf7f2 19#include "common/perf_counters_collection.h"
7c673cae
FG
20#include "common/admin_socket_client.h"
21#include "common/ceph_context.h"
22#include "common/config.h"
23#include "common/errno.h"
24#include "common/safe_io.h"
25
26#include "common/code_environment.h"
27#include "global/global_context.h"
28#include "global/global_init.h"
29#include "include/msgr.h" // for CEPH_ENTITY_TYPE_CLIENT
30#include "gtest/gtest.h"
31
32#include <errno.h>
33#include <fcntl.h>
34#include <map>
35#include <poll.h>
36#include <sstream>
37#include <stdint.h>
38#include <string.h>
39#include <string>
40#include <sys/socket.h>
41#include <sys/types.h>
42#include <sys/un.h>
43#include <time.h>
44#include <unistd.h>
11fdf7f2 45#include <thread>
7c673cae
FG
46
47#include "common/common_init.h"
48
49int main(int argc, char **argv) {
11fdf7f2
TL
50 map<string,string> defaults = {
51 { "admin_socket", get_rand_socket_path() }
52 };
7c673cae 53 std::vector<const char*> args;
11fdf7f2 54 auto cct = global_init(&defaults, args, CEPH_ENTITY_TYPE_CLIENT,
7c673cae 55 CODE_ENVIRONMENT_UTILITY,
11fdf7f2
TL
56 CINIT_FLAG_NO_DEFAULT_CONFIG_FILE|
57 CINIT_FLAG_NO_CCT_PERF_COUNTERS);
7c673cae
FG
58 common_init_finish(g_ceph_context);
59 ::testing::InitGoogleTest(&argc, argv);
60 return RUN_ALL_TESTS();
61}
62
63TEST(PerfCounters, SimpleTest) {
64 AdminSocketClient client(get_rand_socket_path());
65 std::string message;
66 ASSERT_EQ("", client.do_request("{ \"prefix\": \"perf dump\" }", &message));
67 ASSERT_EQ("{}\n", message);
68}
69
70enum {
71 TEST_PERFCOUNTERS1_ELEMENT_FIRST = 200,
72 TEST_PERFCOUNTERS1_ELEMENT_1,
73 TEST_PERFCOUNTERS1_ELEMENT_2,
74 TEST_PERFCOUNTERS1_ELEMENT_3,
75 TEST_PERFCOUNTERS1_ELEMENT_LAST,
76};
77
78std::string sd(const char *c)
79{
80 std::string ret(c);
81 std::string::size_type sz = ret.size();
82 for (std::string::size_type i = 0; i < sz; ++i) {
83 if (ret[i] == '\'') {
84 ret[i] = '\"';
85 }
86 }
87 return ret;
88}
89
90static PerfCounters* setup_test_perfcounters1(CephContext *cct)
91{
92 PerfCountersBuilder bld(cct, "test_perfcounter_1",
93 TEST_PERFCOUNTERS1_ELEMENT_FIRST, TEST_PERFCOUNTERS1_ELEMENT_LAST);
94 bld.add_u64(TEST_PERFCOUNTERS1_ELEMENT_1, "element1");
95 bld.add_time(TEST_PERFCOUNTERS1_ELEMENT_2, "element2");
96 bld.add_time_avg(TEST_PERFCOUNTERS1_ELEMENT_3, "element3");
97 return bld.create_perf_counters();
98}
99
100TEST(PerfCounters, SinglePerfCounters) {
101 PerfCountersCollection *coll = g_ceph_context->get_perfcounters_collection();
102 PerfCounters* fake_pf = setup_test_perfcounters1(g_ceph_context);
103 coll->add(fake_pf);
104 AdminSocketClient client(get_rand_socket_path());
105 std::string msg;
106 ASSERT_EQ("", client.do_request("{ \"prefix\": \"perf dump\", \"format\": \"json\" }", &msg));
107 ASSERT_EQ(sd("{\"test_perfcounter_1\":{\"element1\":0,"
31f18b77 108 "\"element2\":0.000000000,\"element3\":{\"avgcount\":0,\"sum\":0.000000000,\"avgtime\":0.000000000}}}"), msg);
7c673cae
FG
109 fake_pf->inc(TEST_PERFCOUNTERS1_ELEMENT_1);
110 fake_pf->tset(TEST_PERFCOUNTERS1_ELEMENT_2, utime_t(0, 500000000));
111 fake_pf->tinc(TEST_PERFCOUNTERS1_ELEMENT_3, utime_t(100, 0));
112 ASSERT_EQ("", client.do_request("{ \"prefix\": \"perf dump\", \"format\": \"json\" }", &msg));
113 ASSERT_EQ(sd("{\"test_perfcounter_1\":{\"element1\":1,"
31f18b77 114 "\"element2\":0.500000000,\"element3\":{\"avgcount\":1,\"sum\":100.000000000,\"avgtime\":100.000000000}}}"), msg);
7c673cae 115 fake_pf->tinc(TEST_PERFCOUNTERS1_ELEMENT_3, utime_t());
31f18b77 116 fake_pf->tinc(TEST_PERFCOUNTERS1_ELEMENT_3, utime_t(20,0));
7c673cae
FG
117 ASSERT_EQ("", client.do_request("{ \"prefix\": \"perf dump\", \"format\": \"json\" }", &msg));
118 ASSERT_EQ(sd("{\"test_perfcounter_1\":{\"element1\":1,\"element2\":0.500000000,"
31f18b77 119 "\"element3\":{\"avgcount\":3,\"sum\":120.000000000,\"avgtime\":40.000000000}}}"), msg);
7c673cae
FG
120
121 fake_pf->reset();
122 msg.clear();
123 ASSERT_EQ("", client.do_request("{ \"prefix\": \"perf dump\", \"format\": \"json\" }", &msg));
124 ASSERT_EQ(sd("{\"test_perfcounter_1\":{\"element1\":1,"
31f18b77 125 "\"element2\":0.000000000,\"element3\":{\"avgcount\":0,\"sum\":0.000000000,\"avgtime\":0.000000000}}}"), msg);
7c673cae
FG
126
127}
128
129enum {
130 TEST_PERFCOUNTERS2_ELEMENT_FIRST = 400,
131 TEST_PERFCOUNTERS2_ELEMENT_FOO,
132 TEST_PERFCOUNTERS2_ELEMENT_BAR,
133 TEST_PERFCOUNTERS2_ELEMENT_LAST,
134};
135
136static PerfCounters* setup_test_perfcounter2(CephContext *cct)
137{
138 PerfCountersBuilder bld(cct, "test_perfcounter_2",
139 TEST_PERFCOUNTERS2_ELEMENT_FIRST, TEST_PERFCOUNTERS2_ELEMENT_LAST);
140 bld.add_u64(TEST_PERFCOUNTERS2_ELEMENT_FOO, "foo");
141 bld.add_time(TEST_PERFCOUNTERS2_ELEMENT_BAR, "bar");
142 return bld.create_perf_counters();
143}
144
145TEST(PerfCounters, MultiplePerfCounters) {
146 PerfCountersCollection *coll = g_ceph_context->get_perfcounters_collection();
147 coll->clear();
148 PerfCounters* fake_pf1 = setup_test_perfcounters1(g_ceph_context);
149 PerfCounters* fake_pf2 = setup_test_perfcounter2(g_ceph_context);
150 coll->add(fake_pf1);
151 coll->add(fake_pf2);
152 AdminSocketClient client(get_rand_socket_path());
153 std::string msg;
154
155 ASSERT_EQ("", client.do_request("{ \"prefix\": \"perf dump\", \"format\": \"json\" }", &msg));
156 ASSERT_EQ(sd("{\"test_perfcounter_1\":{\"element1\":0,\"element2\":0.000000000,\"element3\":"
31f18b77 157 "{\"avgcount\":0,\"sum\":0.000000000,\"avgtime\":0.000000000}},\"test_perfcounter_2\":{\"foo\":0,\"bar\":0.000000000}}"), msg);
7c673cae
FG
158
159 fake_pf1->inc(TEST_PERFCOUNTERS1_ELEMENT_1);
160 fake_pf1->inc(TEST_PERFCOUNTERS1_ELEMENT_1, 5);
161 ASSERT_EQ("", client.do_request("{ \"prefix\": \"perf dump\", \"format\": \"json\" }", &msg));
162 ASSERT_EQ(sd("{\"test_perfcounter_1\":{\"element1\":6,\"element2\":0.000000000,\"element3\":"
31f18b77 163 "{\"avgcount\":0,\"sum\":0.000000000,\"avgtime\":0.000000000}},\"test_perfcounter_2\":{\"foo\":0,\"bar\":0.000000000}}"), msg);
7c673cae
FG
164
165 coll->reset(string("test_perfcounter_1"));
166 ASSERT_EQ("", client.do_request("{ \"prefix\": \"perf dump\", \"format\": \"json\" }", &msg));
167 ASSERT_EQ(sd("{\"test_perfcounter_1\":{\"element1\":6,\"element2\":0.000000000,\"element3\":"
31f18b77 168 "{\"avgcount\":0,\"sum\":0.000000000,\"avgtime\":0.000000000}},\"test_perfcounter_2\":{\"foo\":0,\"bar\":0.000000000}}"), msg);
7c673cae
FG
169
170 fake_pf1->inc(TEST_PERFCOUNTERS1_ELEMENT_1);
171 fake_pf1->inc(TEST_PERFCOUNTERS1_ELEMENT_1, 6);
172 ASSERT_EQ("", client.do_request("{ \"prefix\": \"perf dump\", \"format\": \"json\" }", &msg));
173 ASSERT_EQ(sd("{\"test_perfcounter_1\":{\"element1\":13,\"element2\":0.000000000,\"element3\":"
31f18b77 174 "{\"avgcount\":0,\"sum\":0.000000000,\"avgtime\":0.000000000}},\"test_perfcounter_2\":{\"foo\":0,\"bar\":0.000000000}}"), msg);
7c673cae
FG
175
176 coll->reset(string("all"));
177 msg.clear();
178 ASSERT_EQ("", client.do_request("{ \"prefix\": \"perf dump\", \"format\": \"json\" }", &msg));
179 ASSERT_EQ(sd("{\"test_perfcounter_1\":{\"element1\":13,\"element2\":0.000000000,\"element3\":"
31f18b77 180 "{\"avgcount\":0,\"sum\":0.000000000,\"avgtime\":0.000000000}},\"test_perfcounter_2\":{\"foo\":0,\"bar\":0.000000000}}"), msg);
7c673cae
FG
181
182 coll->remove(fake_pf2);
183 ASSERT_EQ("", client.do_request("{ \"prefix\": \"perf dump\", \"format\": \"json\" }", &msg));
184 ASSERT_EQ(sd("{\"test_perfcounter_1\":{\"element1\":13,\"element2\":0.000000000,"
31f18b77 185 "\"element3\":{\"avgcount\":0,\"sum\":0.000000000,\"avgtime\":0.000000000}}}"), msg);
7c673cae 186 ASSERT_EQ("", client.do_request("{ \"prefix\": \"perf schema\", \"format\": \"json\" }", &msg));
1adf2230 187 ASSERT_EQ(sd("{\"test_perfcounter_1\":{\"element1\":{\"type\":2,\"metric_type\":\"gauge\",\"value_type\":\"integer\",\"description\":\"\",\"nick\":\"\",\"priority\":0,\"units\":\"none\"},\"element2\":{\"type\":1,\"metric_type\":\"gauge\",\"value_type\":\"real\",\"description\":\"\",\"nick\":\"\",\"priority\":0,\"units\":\"none\"},\"element3\":{\"type\":5,\"metric_type\":\"gauge\",\"value_type\":\"real-integer-pair\",\"description\":\"\",\"nick\":\"\",\"priority\":0,\"units\":\"none\"}}}"), msg);
7c673cae
FG
188 coll->clear();
189 ASSERT_EQ("", client.do_request("{ \"prefix\": \"perf dump\", \"format\": \"json\" }", &msg));
190 ASSERT_EQ("{}", msg);
191}
192
7c673cae
FG
193TEST(PerfCounters, ResetPerfCounters) {
194 AdminSocketClient client(get_rand_socket_path());
195 std::string msg;
196 PerfCountersCollection *coll = g_ceph_context->get_perfcounters_collection();
197 coll->clear();
198 PerfCounters* fake_pf1 = setup_test_perfcounters1(g_ceph_context);
199 coll->add(fake_pf1);
200
201 ASSERT_EQ("", client.do_request("{ \"prefix\": \"perf reset\", \"var\": \"all\", \"format\": \"json\" }", &msg));
202 ASSERT_EQ(sd("{\"success\":\"perf reset all\"}"), msg);
203
204 ASSERT_EQ("", client.do_request("{ \"prefix\": \"perf reset\", \"var\": \"test_perfcounter_1\", \"format\": \"json\" }", &msg));
205 ASSERT_EQ(sd("{\"success\":\"perf reset test_perfcounter_1\"}"), msg);
206
207 coll->clear();
208 ASSERT_EQ("", client.do_request("{ \"prefix\": \"perf reset\", \"var\": \"test_perfcounter_1\", \"format\": \"json\" }", &msg));
209 ASSERT_EQ(sd("{\"error\":\"Not find: test_perfcounter_1\"}"), msg);
210}
11fdf7f2
TL
211
212enum {
213 TEST_PERFCOUNTERS3_ELEMENT_FIRST = 400,
214 TEST_PERFCOUNTERS3_ELEMENT_READ,
215 TEST_PERFCOUNTERS3_ELEMENT_LAST,
216};
217
218static std::shared_ptr<PerfCounters> setup_test_perfcounter3(CephContext* cct) {
219 PerfCountersBuilder bld(cct, "test_percounter_3",
220 TEST_PERFCOUNTERS3_ELEMENT_FIRST, TEST_PERFCOUNTERS3_ELEMENT_LAST);
221 bld.add_time_avg(TEST_PERFCOUNTERS3_ELEMENT_READ, "read_avg");
222 std::shared_ptr<PerfCounters> p(bld.create_perf_counters());
223 return p;
224}
225
226static void counters_inc_test(std::shared_ptr<PerfCounters> fake_pf) {
227 int i = 100000;
228 utime_t t;
229
230 // set to 1 nsec
231 t.set_from_double(0.000000001);
232 while (i--) {
233 // increase by one, make sure data.u64 equal to data.avgcount
234 fake_pf->tinc(TEST_PERFCOUNTERS3_ELEMENT_READ, t);
235 }
236}
237
238static void counters_readavg_test(std::shared_ptr<PerfCounters> fake_pf) {
239 int i = 100000;
240
241 while (i--) {
242 std::pair<uint64_t, uint64_t> dat = fake_pf->get_tavg_ns(TEST_PERFCOUNTERS3_ELEMENT_READ);
243 // sum and count should be identical as we increment TEST_PERCOUNTERS_ELEMENT_READ by 1 nsec eveytime
244 ASSERT_EQ(dat.first, dat.second);
245 }
246}
247
248TEST(PerfCounters, read_avg) {
249 std::shared_ptr<PerfCounters> fake_pf = setup_test_perfcounter3(g_ceph_context);
250
251 std::thread t1(counters_inc_test, fake_pf);
252 std::thread t2(counters_readavg_test, fake_pf);
253 t2.join();
254 t1.join();
255}