]>
Commit | Line | Data |
---|---|---|
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 | ||
49 | int 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 | ||
63 | TEST(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 | ||
70 | enum { | |
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 | ||
78 | std::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 | ||
90 | static 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 | ||
100 | TEST(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 | ||
129 | enum { | |
130 | TEST_PERFCOUNTERS2_ELEMENT_FIRST = 400, | |
131 | TEST_PERFCOUNTERS2_ELEMENT_FOO, | |
132 | TEST_PERFCOUNTERS2_ELEMENT_BAR, | |
133 | TEST_PERFCOUNTERS2_ELEMENT_LAST, | |
134 | }; | |
135 | ||
136 | static 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 | ||
145 | TEST(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 |
193 | TEST(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 | |
212 | enum { | |
213 | TEST_PERFCOUNTERS3_ELEMENT_FIRST = 400, | |
214 | TEST_PERFCOUNTERS3_ELEMENT_READ, | |
215 | TEST_PERFCOUNTERS3_ELEMENT_LAST, | |
216 | }; | |
217 | ||
218 | static 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 | ||
226 | static 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 | ||
238 | static 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 | ||
248 | TEST(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 | } |