]> git.proxmox.com Git - ceph.git/blame - ceph/src/test/admin_socket_output.cc
update source to Ceph Pacific 16.2.2
[ceph.git] / ceph / src / test / admin_socket_output.cc
CommitLineData
31f18b77
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) 2017 Red Hat
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
15#include <iostream>
11fdf7f2 16#include <regex> // For regex, regex_search
31f18b77
FG
17
18#include "common/admin_socket_client.h" // For AdminSocketClient
19#include "common/ceph_json.h" // For JSONParser, JSONObjIter
20#include "include/buffer.h" // For bufferlist
21
22#include "admin_socket_output.h"
23
24void AdminSocketOutput::add_target(const std::string& target) {
25 if (target == "all") {
26 add_target("osd");
27 add_target("mon");
28 add_target("mgr");
29 add_target("mds");
30 add_target("client");
31 return;
32 }
33 targets.insert(target);
34}
35
36void AdminSocketOutput::add_command(const std::string& target,
37 const std::string& command) {
38 auto seek = custom_commands.find(target);
39 if (seek != custom_commands.end()) {
40 seek->second.push_back(command);
41 } else {
42 std::vector<std::string> vec;
43 vec.push_back(command);
44 custom_commands.insert(std::make_pair(target, vec));
45 }
46
47}
48
49void AdminSocketOutput::add_test(const std::string &target,
50 const std::string &command,
51 bool (*test)(std::string &)) {
52 auto seek = tests.find(target);
53 if (seek != tests.end()) {
54 seek->second.push_back(std::make_pair(command, test));
55 } else {
56 std::vector<std::pair<std::string, bool (*)(std::string &)>> vec;
57 vec.push_back(std::make_pair(command, test));
58 tests.insert(std::make_pair(target, vec));
59 }
60}
61
62void AdminSocketOutput::postpone(const std::string &target,
63 const std::string& command) {
64 auto seek = postponed_commands.find(target);
65 if (seek != postponed_commands.end()) {
66 seek->second.push_back(command);
67 } else {
68 std::vector<string> vec;
69 vec.push_back(command);
70 postponed_commands.insert(std::make_pair(target, vec));
71 }
72}
73
74bool AdminSocketOutput::init_sockets() {
75 std::cout << "Initialising sockets" << std::endl;
9f95a23c
TL
76 std::string socket_regex = R"(\..*\.asok)";
77 for (const auto &x : fs::recursive_directory_iterator(socketdir)) {
31f18b77 78 std::cout << x.path() << std::endl;
11fdf7f2 79 if (x.path().extension() == ".asok") {
9f95a23c
TL
80 for (auto target = targets.cbegin(); target != targets.cend();) {
81 std::regex reg(prefix + *target + socket_regex);
82 if (std::regex_search(x.path().filename().string(), reg)) {
83 std::cout << "Found " << *target << " socket " << x.path()
31f18b77 84 << std::endl;
9f95a23c
TL
85 sockets.insert(std::make_pair(*target, x.path().string()));
86 target = targets.erase(target);
87 }
88 else {
89 ++target;
31f18b77
FG
90 }
91 }
92 if (targets.empty()) {
93 std::cout << "Found all required sockets" << std::endl;
94 break;
95 }
96 }
97 }
98
99 return !sockets.empty() && targets.empty();
100}
101
102std::pair<std::string, std::string>
103AdminSocketOutput::run_command(AdminSocketClient &client,
11fdf7f2 104 const std::string &raw_command,
31f18b77
FG
105 bool send_untouched) {
106 std::cout << "Sending command \"" << raw_command << "\"" << std::endl;
107 std::string command;
108 std::string output;
109 if (send_untouched) {
110 command = raw_command;
111 } else {
112 command = "{\"prefix\":\"" + raw_command + "\"}";
113 }
11fdf7f2
TL
114 std::string err = client.do_request(command, &output);
115 if (!err.empty()) {
116 std::cerr << __func__ << " AdminSocketClient::do_request errored with: "
117 << err << std::endl;
118 ceph_abort();
119 }
31f18b77
FG
120 return std::make_pair(command, output);
121}
122
123bool AdminSocketOutput::gather_socket_output() {
124
125 std::cout << "Gathering socket output" << std::endl;
126 for (const auto& socket : sockets) {
127 std::string response;
128 AdminSocketClient client(socket.second);
129 std::cout << std::endl
130 << "Sending request to " << socket << std::endl
131 << std::endl;
11fdf7f2
TL
132 std::string err = client.do_request("{\"prefix\":\"help\"}", &response);
133 if (!err.empty()) {
134 std::cerr << __func__ << " AdminSocketClient::do_request errored with: "
135 << err << std::endl;
136 return false;
137 }
31f18b77
FG
138 std::cout << response << '\n';
139
140 JSONParser parser;
141 bool ret = parser.parse(response.c_str(), response.size());
142 if (!ret) {
143 cerr << "parse error" << std::endl;
144 return false;
145 }
146
147 socket_results sresults;
148 JSONObjIter iter = parser.find_first();
149 const auto postponed_iter = postponed_commands.find(socket.first);
150 std::vector<std::string> postponed;
151 if (postponed_iter != postponed_commands.end()) {
152 postponed = postponed_iter->second;
153 }
154 std::cout << "Sending commands to " << socket.first << " socket"
155 << std::endl;
156 for (; !iter.end(); ++iter) {
157 if (std::find(postponed.begin(), postponed.end(), (*iter)->get_name())
158 != std::end(postponed)) {
159 std::cout << "Command \"" << (*iter)->get_name() << "\" postponed"
160 << std::endl;
161 continue;
162 }
163 sresults.insert(run_command(client, (*iter)->get_name()));
164 }
165
166 if (sresults.empty()) {
167 return false;
168 }
169
170 // Custom commands
171 const auto seek = custom_commands.find(socket.first);
172 if (seek != custom_commands.end()) {
173 std::cout << std::endl << "Sending custom commands:" << std::endl;
174 for (const auto& raw_command : seek->second) {
175 sresults.insert(run_command(client, raw_command, true));
176 }
177 }
178
179 // Postponed commands
180 if (!postponed.empty())
181 std::cout << std::endl << "Sending postponed commands" << std::endl;
182 for (const auto& command : postponed) {
183 sresults.insert(run_command(client, command));
184 }
185
186 results.insert(
187 std::pair<std::string, socket_results>(socket.first, sresults));
188
189 }
190
191 return true;
192}
193
11fdf7f2
TL
194std::string AdminSocketOutput::get_result(const std::string &target,
195 const std::string &command) const {
31f18b77
FG
196 const auto& target_results = results.find(target);
197 if (target_results == results.end())
198 return std::string("");
199 else {
200 const auto& result = target_results->second.find(command);
201 if (result == target_results->second.end())
202 return std::string("");
203 else
204 return result->second;
205 }
206}
207
208bool AdminSocketOutput::run_tests() const {
209 for (const auto& socket : sockets) {
210 const auto& seek = tests.find(socket.first);
211 if (seek != tests.end()) {
212 std::cout << std::endl;
213 std::cout << "Running tests for " << socket.first << " socket" << std::endl;
214 for (const auto& test : seek->second) {
215 auto result = get_result(socket.first, test.first);
216 if(result.empty()) {
217 std::cout << "Failed to find result for command: " << test.first << std::endl;
218 return false;
219 } else {
220 std::cout << "Running test for command: " << test.first << std::endl;
221 const auto& test_func = test.second;
222 bool res = test_func(result);
223 if (res == false)
224 return false;
225 else
226 std::cout << "Test passed" << std::endl;
227 }
228 }
229 }
230 }
231
232 return true;
233}
234
235void AdminSocketOutput::exec() {
236 ceph_assert(init_directories());
237 ceph_assert(init_sockets());
238 ceph_assert(gather_socket_output());
239 ceph_assert(run_tests());
240}