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) 2011 New Dream Network
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.
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.
19 #include "common/perf_counters_collection.h"
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"
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"
40 #include <sys/socket.h>
41 #include <sys/types.h>
47 #include "common/common_init.h"
51 int main(int argc
, char **argv
) {
52 map
<string
,string
> defaults
= {
53 { "admin_socket", get_rand_socket_path() }
55 std::vector
<const char*> args
;
56 auto cct
= global_init(&defaults
, args
, CEPH_ENTITY_TYPE_CLIENT
,
57 CODE_ENVIRONMENT_UTILITY
,
58 CINIT_FLAG_NO_DEFAULT_CONFIG_FILE
|
59 CINIT_FLAG_NO_CCT_PERF_COUNTERS
);
60 common_init_finish(g_ceph_context
);
61 ::testing::InitGoogleTest(&argc
, argv
);
62 return RUN_ALL_TESTS();
65 TEST(PerfCounters
, SimpleTest
) {
66 AdminSocketClient
client(get_rand_socket_path());
68 ASSERT_EQ("", client
.do_request("{ \"prefix\": \"perf dump\" }", &message
));
69 ASSERT_EQ("{}\n", message
);
73 TEST_PERFCOUNTERS1_ELEMENT_FIRST
= 200,
74 TEST_PERFCOUNTERS1_ELEMENT_1
,
75 TEST_PERFCOUNTERS1_ELEMENT_2
,
76 TEST_PERFCOUNTERS1_ELEMENT_3
,
77 TEST_PERFCOUNTERS1_ELEMENT_LAST
,
80 std::string
sd(const char *c
)
83 std::string::size_type sz
= ret
.size();
84 for (std::string::size_type i
= 0; i
< sz
; ++i
) {
92 static PerfCounters
* setup_test_perfcounters1(CephContext
*cct
)
94 PerfCountersBuilder
bld(cct
, "test_perfcounter_1",
95 TEST_PERFCOUNTERS1_ELEMENT_FIRST
, TEST_PERFCOUNTERS1_ELEMENT_LAST
);
96 bld
.add_u64(TEST_PERFCOUNTERS1_ELEMENT_1
, "element1");
97 bld
.add_time(TEST_PERFCOUNTERS1_ELEMENT_2
, "element2");
98 bld
.add_time_avg(TEST_PERFCOUNTERS1_ELEMENT_3
, "element3");
99 return bld
.create_perf_counters();
102 TEST(PerfCounters
, SinglePerfCounters
) {
103 PerfCountersCollection
*coll
= g_ceph_context
->get_perfcounters_collection();
104 PerfCounters
* fake_pf
= setup_test_perfcounters1(g_ceph_context
);
106 AdminSocketClient
client(get_rand_socket_path());
108 ASSERT_EQ("", client
.do_request("{ \"prefix\": \"perf dump\", \"format\": \"json\" }", &msg
));
109 ASSERT_EQ(sd("{\"test_perfcounter_1\":{\"element1\":0,"
110 "\"element2\":0.000000000,\"element3\":{\"avgcount\":0,\"sum\":0.000000000,\"avgtime\":0.000000000}}}"), msg
);
111 fake_pf
->inc(TEST_PERFCOUNTERS1_ELEMENT_1
);
112 fake_pf
->tset(TEST_PERFCOUNTERS1_ELEMENT_2
, utime_t(0, 500000000));
113 fake_pf
->tinc(TEST_PERFCOUNTERS1_ELEMENT_3
, utime_t(100, 0));
114 ASSERT_EQ("", client
.do_request("{ \"prefix\": \"perf dump\", \"format\": \"json\" }", &msg
));
115 ASSERT_EQ(sd("{\"test_perfcounter_1\":{\"element1\":1,"
116 "\"element2\":0.500000000,\"element3\":{\"avgcount\":1,\"sum\":100.000000000,\"avgtime\":100.000000000}}}"), msg
);
117 fake_pf
->tinc(TEST_PERFCOUNTERS1_ELEMENT_3
, utime_t());
118 fake_pf
->tinc(TEST_PERFCOUNTERS1_ELEMENT_3
, utime_t(20,0));
119 ASSERT_EQ("", client
.do_request("{ \"prefix\": \"perf dump\", \"format\": \"json\" }", &msg
));
120 ASSERT_EQ(sd("{\"test_perfcounter_1\":{\"element1\":1,\"element2\":0.500000000,"
121 "\"element3\":{\"avgcount\":3,\"sum\":120.000000000,\"avgtime\":40.000000000}}}"), msg
);
125 ASSERT_EQ("", client
.do_request("{ \"prefix\": \"perf dump\", \"format\": \"json\" }", &msg
));
126 ASSERT_EQ(sd("{\"test_perfcounter_1\":{\"element1\":1,"
127 "\"element2\":0.000000000,\"element3\":{\"avgcount\":0,\"sum\":0.000000000,\"avgtime\":0.000000000}}}"), msg
);
132 TEST_PERFCOUNTERS2_ELEMENT_FIRST
= 400,
133 TEST_PERFCOUNTERS2_ELEMENT_FOO
,
134 TEST_PERFCOUNTERS2_ELEMENT_BAR
,
135 TEST_PERFCOUNTERS2_ELEMENT_LAST
,
138 static PerfCounters
* setup_test_perfcounter2(CephContext
*cct
)
140 PerfCountersBuilder
bld(cct
, "test_perfcounter_2",
141 TEST_PERFCOUNTERS2_ELEMENT_FIRST
, TEST_PERFCOUNTERS2_ELEMENT_LAST
);
142 bld
.add_u64(TEST_PERFCOUNTERS2_ELEMENT_FOO
, "foo");
143 bld
.add_time(TEST_PERFCOUNTERS2_ELEMENT_BAR
, "bar");
144 return bld
.create_perf_counters();
147 TEST(PerfCounters
, MultiplePerfCounters
) {
148 PerfCountersCollection
*coll
= g_ceph_context
->get_perfcounters_collection();
150 PerfCounters
* fake_pf1
= setup_test_perfcounters1(g_ceph_context
);
151 PerfCounters
* fake_pf2
= setup_test_perfcounter2(g_ceph_context
);
154 AdminSocketClient
client(get_rand_socket_path());
157 ASSERT_EQ("", client
.do_request("{ \"prefix\": \"perf dump\", \"format\": \"json\" }", &msg
));
158 ASSERT_EQ(sd("{\"test_perfcounter_1\":{\"element1\":0,\"element2\":0.000000000,\"element3\":"
159 "{\"avgcount\":0,\"sum\":0.000000000,\"avgtime\":0.000000000}},\"test_perfcounter_2\":{\"foo\":0,\"bar\":0.000000000}}"), msg
);
161 fake_pf1
->inc(TEST_PERFCOUNTERS1_ELEMENT_1
);
162 fake_pf1
->inc(TEST_PERFCOUNTERS1_ELEMENT_1
, 5);
163 ASSERT_EQ("", client
.do_request("{ \"prefix\": \"perf dump\", \"format\": \"json\" }", &msg
));
164 ASSERT_EQ(sd("{\"test_perfcounter_1\":{\"element1\":6,\"element2\":0.000000000,\"element3\":"
165 "{\"avgcount\":0,\"sum\":0.000000000,\"avgtime\":0.000000000}},\"test_perfcounter_2\":{\"foo\":0,\"bar\":0.000000000}}"), msg
);
167 coll
->reset(string("test_perfcounter_1"));
168 ASSERT_EQ("", client
.do_request("{ \"prefix\": \"perf dump\", \"format\": \"json\" }", &msg
));
169 ASSERT_EQ(sd("{\"test_perfcounter_1\":{\"element1\":6,\"element2\":0.000000000,\"element3\":"
170 "{\"avgcount\":0,\"sum\":0.000000000,\"avgtime\":0.000000000}},\"test_perfcounter_2\":{\"foo\":0,\"bar\":0.000000000}}"), msg
);
172 fake_pf1
->inc(TEST_PERFCOUNTERS1_ELEMENT_1
);
173 fake_pf1
->inc(TEST_PERFCOUNTERS1_ELEMENT_1
, 6);
174 ASSERT_EQ("", client
.do_request("{ \"prefix\": \"perf dump\", \"format\": \"json\" }", &msg
));
175 ASSERT_EQ(sd("{\"test_perfcounter_1\":{\"element1\":13,\"element2\":0.000000000,\"element3\":"
176 "{\"avgcount\":0,\"sum\":0.000000000,\"avgtime\":0.000000000}},\"test_perfcounter_2\":{\"foo\":0,\"bar\":0.000000000}}"), msg
);
178 coll
->reset(string("all"));
180 ASSERT_EQ("", client
.do_request("{ \"prefix\": \"perf dump\", \"format\": \"json\" }", &msg
));
181 ASSERT_EQ(sd("{\"test_perfcounter_1\":{\"element1\":13,\"element2\":0.000000000,\"element3\":"
182 "{\"avgcount\":0,\"sum\":0.000000000,\"avgtime\":0.000000000}},\"test_perfcounter_2\":{\"foo\":0,\"bar\":0.000000000}}"), msg
);
184 coll
->remove(fake_pf2
);
185 ASSERT_EQ("", client
.do_request("{ \"prefix\": \"perf dump\", \"format\": \"json\" }", &msg
));
186 ASSERT_EQ(sd("{\"test_perfcounter_1\":{\"element1\":13,\"element2\":0.000000000,"
187 "\"element3\":{\"avgcount\":0,\"sum\":0.000000000,\"avgtime\":0.000000000}}}"), msg
);
188 ASSERT_EQ("", client
.do_request("{ \"prefix\": \"perf schema\", \"format\": \"json\" }", &msg
));
189 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
);
191 ASSERT_EQ("", client
.do_request("{ \"prefix\": \"perf dump\", \"format\": \"json\" }", &msg
));
192 ASSERT_EQ("{}", msg
);
195 TEST(PerfCounters
, ResetPerfCounters
) {
196 AdminSocketClient
client(get_rand_socket_path());
198 PerfCountersCollection
*coll
= g_ceph_context
->get_perfcounters_collection();
200 PerfCounters
* fake_pf1
= setup_test_perfcounters1(g_ceph_context
);
203 ASSERT_EQ("", client
.do_request("{ \"prefix\": \"perf reset\", \"var\": \"all\", \"format\": \"json\" }", &msg
));
204 ASSERT_EQ(sd("{\"success\":\"perf reset all\"}"), msg
);
206 ASSERT_EQ("", client
.do_request("{ \"prefix\": \"perf reset\", \"var\": \"test_perfcounter_1\", \"format\": \"json\" }", &msg
));
207 ASSERT_EQ(sd("{\"success\":\"perf reset test_perfcounter_1\"}"), msg
);
210 ASSERT_EQ("", client
.do_request("{ \"prefix\": \"perf reset\", \"var\": \"test_perfcounter_1\", \"format\": \"json\" }", &msg
));
211 ASSERT_EQ(sd("{\"error\":\"Not find: test_perfcounter_1\"}"), msg
);
215 TEST_PERFCOUNTERS3_ELEMENT_FIRST
= 400,
216 TEST_PERFCOUNTERS3_ELEMENT_READ
,
217 TEST_PERFCOUNTERS3_ELEMENT_LAST
,
220 static std::shared_ptr
<PerfCounters
> setup_test_perfcounter3(CephContext
* cct
) {
221 PerfCountersBuilder
bld(cct
, "test_percounter_3",
222 TEST_PERFCOUNTERS3_ELEMENT_FIRST
, TEST_PERFCOUNTERS3_ELEMENT_LAST
);
223 bld
.add_time_avg(TEST_PERFCOUNTERS3_ELEMENT_READ
, "read_avg");
224 std::shared_ptr
<PerfCounters
> p(bld
.create_perf_counters());
228 static void counters_inc_test(std::shared_ptr
<PerfCounters
> fake_pf
) {
233 t
.set_from_double(0.000000001);
235 // increase by one, make sure data.u64 equal to data.avgcount
236 fake_pf
->tinc(TEST_PERFCOUNTERS3_ELEMENT_READ
, t
);
240 static void counters_readavg_test(std::shared_ptr
<PerfCounters
> fake_pf
) {
244 std::pair
<uint64_t, uint64_t> dat
= fake_pf
->get_tavg_ns(TEST_PERFCOUNTERS3_ELEMENT_READ
);
245 // sum and count should be identical as we increment TEST_PERCOUNTERS_ELEMENT_READ by 1 nsec eveytime
246 ASSERT_EQ(dat
.first
, dat
.second
);
250 TEST(PerfCounters
, read_avg
) {
251 std::shared_ptr
<PerfCounters
> fake_pf
= setup_test_perfcounter3(g_ceph_context
);
253 std::thread
t1(counters_inc_test
, fake_pf
);
254 std::thread
t2(counters_readavg_test
, fake_pf
);