Fix some bugs when testing opensds ansible
[stor4nfv.git] / src / ceph / src / test / perf_counters.cc
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
19 #include "common/perf_counters.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"
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>
45
46 #include "common/common_init.h"
47
48 int main(int argc, char **argv) {
49   std::vector<const char *> preargs;
50   preargs.push_back("--admin-socket");
51   preargs.push_back(get_rand_socket_path());
52   std::vector<const char*> args;
53   auto cct = global_init(&preargs, args, CEPH_ENTITY_TYPE_CLIENT,
54                          CODE_ENVIRONMENT_UTILITY,
55                          CINIT_FLAG_NO_DEFAULT_CONFIG_FILE);
56   common_init_finish(g_ceph_context);
57   ::testing::InitGoogleTest(&argc, argv);
58   return RUN_ALL_TESTS();
59 }
60
61 TEST(PerfCounters, SimpleTest) {
62   AdminSocketClient client(get_rand_socket_path());
63   std::string message;
64   ASSERT_EQ("", client.do_request("{ \"prefix\": \"perf dump\" }", &message));
65   ASSERT_EQ("{}\n", message);
66 }
67
68 enum {
69   TEST_PERFCOUNTERS1_ELEMENT_FIRST = 200,
70   TEST_PERFCOUNTERS1_ELEMENT_1,
71   TEST_PERFCOUNTERS1_ELEMENT_2,
72   TEST_PERFCOUNTERS1_ELEMENT_3,
73   TEST_PERFCOUNTERS1_ELEMENT_LAST,
74 };
75
76 std::string sd(const char *c)
77 {
78   std::string ret(c);
79   std::string::size_type sz = ret.size();
80   for (std::string::size_type i = 0; i < sz; ++i) {
81     if (ret[i] == '\'') {
82       ret[i] = '\"';
83     }
84   }
85   return ret;
86 }
87
88 static PerfCounters* setup_test_perfcounters1(CephContext *cct)
89 {
90   PerfCountersBuilder bld(cct, "test_perfcounter_1",
91           TEST_PERFCOUNTERS1_ELEMENT_FIRST, TEST_PERFCOUNTERS1_ELEMENT_LAST);
92   bld.add_u64(TEST_PERFCOUNTERS1_ELEMENT_1, "element1");
93   bld.add_time(TEST_PERFCOUNTERS1_ELEMENT_2, "element2");
94   bld.add_time_avg(TEST_PERFCOUNTERS1_ELEMENT_3, "element3");
95   return bld.create_perf_counters();
96 }
97
98 TEST(PerfCounters, SinglePerfCounters) {
99   PerfCountersCollection *coll = g_ceph_context->get_perfcounters_collection();
100   PerfCounters* fake_pf = setup_test_perfcounters1(g_ceph_context);
101   coll->add(fake_pf);
102   AdminSocketClient client(get_rand_socket_path());
103   std::string msg;
104   ASSERT_EQ("", client.do_request("{ \"prefix\": \"perf dump\", \"format\": \"json\" }", &msg));
105   ASSERT_EQ(sd("{\"test_perfcounter_1\":{\"element1\":0,"
106             "\"element2\":0.000000000,\"element3\":{\"avgcount\":0,\"sum\":0.000000000,\"avgtime\":0.000000000}}}"), msg);
107   fake_pf->inc(TEST_PERFCOUNTERS1_ELEMENT_1);
108   fake_pf->tset(TEST_PERFCOUNTERS1_ELEMENT_2, utime_t(0, 500000000));
109   fake_pf->tinc(TEST_PERFCOUNTERS1_ELEMENT_3, utime_t(100, 0));
110   ASSERT_EQ("", client.do_request("{ \"prefix\": \"perf dump\", \"format\": \"json\" }", &msg));
111   ASSERT_EQ(sd("{\"test_perfcounter_1\":{\"element1\":1,"
112             "\"element2\":0.500000000,\"element3\":{\"avgcount\":1,\"sum\":100.000000000,\"avgtime\":100.000000000}}}"), msg);
113   fake_pf->tinc(TEST_PERFCOUNTERS1_ELEMENT_3, utime_t());
114   fake_pf->tinc(TEST_PERFCOUNTERS1_ELEMENT_3, utime_t(20,0));
115   ASSERT_EQ("", client.do_request("{ \"prefix\": \"perf dump\", \"format\": \"json\" }", &msg));
116   ASSERT_EQ(sd("{\"test_perfcounter_1\":{\"element1\":1,\"element2\":0.500000000,"
117             "\"element3\":{\"avgcount\":3,\"sum\":120.000000000,\"avgtime\":40.000000000}}}"), msg);
118
119   fake_pf->reset();
120   msg.clear();
121   ASSERT_EQ("", client.do_request("{ \"prefix\": \"perf dump\", \"format\": \"json\" }", &msg));
122   ASSERT_EQ(sd("{\"test_perfcounter_1\":{\"element1\":1,"
123             "\"element2\":0.000000000,\"element3\":{\"avgcount\":0,\"sum\":0.000000000,\"avgtime\":0.000000000}}}"), msg);
124
125 }
126
127 enum {
128   TEST_PERFCOUNTERS2_ELEMENT_FIRST = 400,
129   TEST_PERFCOUNTERS2_ELEMENT_FOO,
130   TEST_PERFCOUNTERS2_ELEMENT_BAR,
131   TEST_PERFCOUNTERS2_ELEMENT_LAST,
132 };
133
134 static PerfCounters* setup_test_perfcounter2(CephContext *cct)
135 {
136   PerfCountersBuilder bld(cct, "test_perfcounter_2",
137           TEST_PERFCOUNTERS2_ELEMENT_FIRST, TEST_PERFCOUNTERS2_ELEMENT_LAST);
138   bld.add_u64(TEST_PERFCOUNTERS2_ELEMENT_FOO, "foo");
139   bld.add_time(TEST_PERFCOUNTERS2_ELEMENT_BAR, "bar");
140   return bld.create_perf_counters();
141 }
142
143 TEST(PerfCounters, MultiplePerfCounters) {
144   PerfCountersCollection *coll = g_ceph_context->get_perfcounters_collection();
145   coll->clear();
146   PerfCounters* fake_pf1 = setup_test_perfcounters1(g_ceph_context);
147   PerfCounters* fake_pf2 = setup_test_perfcounter2(g_ceph_context);
148   coll->add(fake_pf1);
149   coll->add(fake_pf2);
150   AdminSocketClient client(get_rand_socket_path());
151   std::string msg;
152
153   ASSERT_EQ("", client.do_request("{ \"prefix\": \"perf dump\", \"format\": \"json\" }", &msg));
154   ASSERT_EQ(sd("{\"test_perfcounter_1\":{\"element1\":0,\"element2\":0.000000000,\"element3\":"
155             "{\"avgcount\":0,\"sum\":0.000000000,\"avgtime\":0.000000000}},\"test_perfcounter_2\":{\"foo\":0,\"bar\":0.000000000}}"), msg);
156
157   fake_pf1->inc(TEST_PERFCOUNTERS1_ELEMENT_1);
158   fake_pf1->inc(TEST_PERFCOUNTERS1_ELEMENT_1, 5);
159   ASSERT_EQ("", client.do_request("{ \"prefix\": \"perf dump\", \"format\": \"json\" }", &msg));
160   ASSERT_EQ(sd("{\"test_perfcounter_1\":{\"element1\":6,\"element2\":0.000000000,\"element3\":"
161             "{\"avgcount\":0,\"sum\":0.000000000,\"avgtime\":0.000000000}},\"test_perfcounter_2\":{\"foo\":0,\"bar\":0.000000000}}"), msg);
162
163   coll->reset(string("test_perfcounter_1"));
164   ASSERT_EQ("", client.do_request("{ \"prefix\": \"perf dump\", \"format\": \"json\" }", &msg));
165   ASSERT_EQ(sd("{\"test_perfcounter_1\":{\"element1\":6,\"element2\":0.000000000,\"element3\":"
166             "{\"avgcount\":0,\"sum\":0.000000000,\"avgtime\":0.000000000}},\"test_perfcounter_2\":{\"foo\":0,\"bar\":0.000000000}}"), msg);
167
168   fake_pf1->inc(TEST_PERFCOUNTERS1_ELEMENT_1);
169   fake_pf1->inc(TEST_PERFCOUNTERS1_ELEMENT_1, 6);
170   ASSERT_EQ("", client.do_request("{ \"prefix\": \"perf dump\", \"format\": \"json\" }", &msg));
171   ASSERT_EQ(sd("{\"test_perfcounter_1\":{\"element1\":13,\"element2\":0.000000000,\"element3\":"
172             "{\"avgcount\":0,\"sum\":0.000000000,\"avgtime\":0.000000000}},\"test_perfcounter_2\":{\"foo\":0,\"bar\":0.000000000}}"), msg);
173
174   coll->reset(string("all"));
175   msg.clear();
176   ASSERT_EQ("", client.do_request("{ \"prefix\": \"perf dump\", \"format\": \"json\" }", &msg));
177   ASSERT_EQ(sd("{\"test_perfcounter_1\":{\"element1\":13,\"element2\":0.000000000,\"element3\":"
178             "{\"avgcount\":0,\"sum\":0.000000000,\"avgtime\":0.000000000}},\"test_perfcounter_2\":{\"foo\":0,\"bar\":0.000000000}}"), msg);
179
180   coll->remove(fake_pf2);
181   ASSERT_EQ("", client.do_request("{ \"prefix\": \"perf dump\", \"format\": \"json\" }", &msg));
182   ASSERT_EQ(sd("{\"test_perfcounter_1\":{\"element1\":13,\"element2\":0.000000000,"
183             "\"element3\":{\"avgcount\":0,\"sum\":0.000000000,\"avgtime\":0.000000000}}}"), msg);
184   ASSERT_EQ("", client.do_request("{ \"prefix\": \"perf schema\", \"format\": \"json\" }", &msg));
185   ASSERT_EQ(sd("{\"test_perfcounter_1\":{\"element1\":{\"type\":2,\"metric_type\":\"gauge\",\"value_type\":\"integer\",\"description\":\"\",\"nick\":\"\",\"priority\":0},\"element2\":{\"type\":1,\"metric_type\":\"gauge\",\"value_type\":\"real\",\"description\":\"\",\"nick\":\"\",\"priority\":0},\"element3\":{\"type\":5,\"metric_type\":\"gauge\",\"value_type\":\"real-integer-pair\",\"description\":\"\",\"nick\":\"\",\"priority\":0}}}"), msg);
186   coll->clear();
187   ASSERT_EQ("", client.do_request("{ \"prefix\": \"perf dump\", \"format\": \"json\" }", &msg));
188   ASSERT_EQ("{}", msg);
189 }
190
191 TEST(PerfCounters, CephContextPerfCounters) {
192   // Enable the perf counter
193   g_ceph_context->enable_perf_counter();
194   AdminSocketClient client(get_rand_socket_path());
195   std::string msg;
196
197   ASSERT_EQ("", client.do_request("{ \"prefix\": \"perf dump\", \"format\": \"json\" }", &msg));
198   ASSERT_EQ(sd("{\"cct\":{\"total_workers\":0,\"unhealthy_workers\":0}}"), msg);
199
200   // Restore to avoid impact to other test cases
201   g_ceph_context->disable_perf_counter();
202 }
203
204 TEST(PerfCounters, ResetPerfCounters) {
205   AdminSocketClient client(get_rand_socket_path());
206   std::string msg;
207   PerfCountersCollection *coll = g_ceph_context->get_perfcounters_collection();
208   coll->clear();
209   PerfCounters* fake_pf1 = setup_test_perfcounters1(g_ceph_context);
210   coll->add(fake_pf1);
211
212   ASSERT_EQ("", client.do_request("{ \"prefix\": \"perf reset\", \"var\": \"all\", \"format\": \"json\" }", &msg));
213   ASSERT_EQ(sd("{\"success\":\"perf reset all\"}"), msg);
214
215   ASSERT_EQ("", client.do_request("{ \"prefix\": \"perf reset\", \"var\": \"test_perfcounter_1\", \"format\": \"json\" }", &msg));
216   ASSERT_EQ(sd("{\"success\":\"perf reset test_perfcounter_1\"}"), msg);
217
218   coll->clear();
219   ASSERT_EQ("", client.do_request("{ \"prefix\": \"perf reset\", \"var\": \"test_perfcounter_1\", \"format\": \"json\" }", &msg));
220   ASSERT_EQ(sd("{\"error\":\"Not find: test_perfcounter_1\"}"), msg);
221 }