]>
git.proxmox.com Git - ceph.git/blob - ceph/src/test/admin_socket_output.cc
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) 2017 Red Hat
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.
16 #include <regex> // For regex, regex_search
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
22 #include "admin_socket_output.h"
26 void AdminSocketOutput::add_target(const std::string
& target
) {
27 if (target
== "all") {
35 targets
.insert(target
);
38 void AdminSocketOutput::add_command(const std::string
& target
,
39 const std::string
& command
) {
40 auto seek
= custom_commands
.find(target
);
41 if (seek
!= custom_commands
.end()) {
42 seek
->second
.push_back(command
);
44 std::vector
<std::string
> vec
;
45 vec
.push_back(command
);
46 custom_commands
.insert(std::make_pair(target
, vec
));
51 void AdminSocketOutput::add_test(const std::string
&target
,
52 const std::string
&command
,
53 bool (*test
)(std::string
&)) {
54 auto seek
= tests
.find(target
);
55 if (seek
!= tests
.end()) {
56 seek
->second
.push_back(std::make_pair(command
, test
));
58 std::vector
<std::pair
<std::string
, bool (*)(std::string
&)>> vec
;
59 vec
.push_back(std::make_pair(command
, test
));
60 tests
.insert(std::make_pair(target
, vec
));
64 void AdminSocketOutput::postpone(const std::string
&target
,
65 const std::string
& command
) {
66 auto seek
= postponed_commands
.find(target
);
67 if (seek
!= postponed_commands
.end()) {
68 seek
->second
.push_back(command
);
70 std::vector
<string
> vec
;
71 vec
.push_back(command
);
72 postponed_commands
.insert(std::make_pair(target
, vec
));
76 bool AdminSocketOutput::init_sockets() {
77 std::cout
<< "Initialising sockets" << std::endl
;
78 std::string socket_regex
= R
"(\..*\.asok)";
79 for (const auto &x
: fs::recursive_directory_iterator(socketdir
)) {
80 std::cout
<< x
.path() << std::endl
;
81 if (x
.path().extension() == ".asok") {
82 for (auto target
= targets
.cbegin(); target
!= targets
.cend();) {
83 std::regex
reg(prefix
+ *target
+ socket_regex
);
84 if (std::regex_search(x
.path().filename().string(), reg
)) {
85 std::cout
<< "Found " << *target
<< " socket " << x
.path()
87 sockets
.insert(std::make_pair(*target
, x
.path().string()));
88 target
= targets
.erase(target
);
94 if (targets
.empty()) {
95 std::cout
<< "Found all required sockets" << std::endl
;
101 return !sockets
.empty() && targets
.empty();
104 std::pair
<std::string
, std::string
>
105 AdminSocketOutput::run_command(AdminSocketClient
&client
,
106 const std::string
&raw_command
,
107 bool send_untouched
) {
108 std::cout
<< "Sending command \"" << raw_command
<< "\"" << std::endl
;
111 if (send_untouched
) {
112 command
= raw_command
;
114 command
= "{\"prefix\":\"" + raw_command
+ "\"}";
116 std::string err
= client
.do_request(command
, &output
);
118 std::cerr
<< __func__
<< " AdminSocketClient::do_request errored with: "
122 return std::make_pair(command
, output
);
125 bool AdminSocketOutput::gather_socket_output() {
127 std::cout
<< "Gathering socket output" << std::endl
;
128 for (const auto& socket
: sockets
) {
129 std::string response
;
130 AdminSocketClient
client(socket
.second
);
131 std::cout
<< std::endl
132 << "Sending request to " << socket
<< std::endl
134 std::string err
= client
.do_request("{\"prefix\":\"help\"}", &response
);
136 std::cerr
<< __func__
<< " AdminSocketClient::do_request errored with: "
140 std::cout
<< response
<< '\n';
143 bool ret
= parser
.parse(response
.c_str(), response
.size());
145 cerr
<< "parse error" << std::endl
;
149 socket_results sresults
;
150 JSONObjIter iter
= parser
.find_first();
151 const auto postponed_iter
= postponed_commands
.find(socket
.first
);
152 std::vector
<std::string
> postponed
;
153 if (postponed_iter
!= postponed_commands
.end()) {
154 postponed
= postponed_iter
->second
;
156 std::cout
<< "Sending commands to " << socket
.first
<< " socket"
158 for (; !iter
.end(); ++iter
) {
159 if (std::find(postponed
.begin(), postponed
.end(), (*iter
)->get_name())
160 != std::end(postponed
)) {
161 std::cout
<< "Command \"" << (*iter
)->get_name() << "\" postponed"
165 sresults
.insert(run_command(client
, (*iter
)->get_name()));
168 if (sresults
.empty()) {
173 const auto seek
= custom_commands
.find(socket
.first
);
174 if (seek
!= custom_commands
.end()) {
175 std::cout
<< std::endl
<< "Sending custom commands:" << std::endl
;
176 for (const auto& raw_command
: seek
->second
) {
177 sresults
.insert(run_command(client
, raw_command
, true));
181 // Postponed commands
182 if (!postponed
.empty())
183 std::cout
<< std::endl
<< "Sending postponed commands" << std::endl
;
184 for (const auto& command
: postponed
) {
185 sresults
.insert(run_command(client
, command
));
189 std::pair
<std::string
, socket_results
>(socket
.first
, sresults
));
196 std::string
AdminSocketOutput::get_result(const std::string
&target
,
197 const std::string
&command
) const {
198 const auto& target_results
= results
.find(target
);
199 if (target_results
== results
.end())
200 return std::string("");
202 const auto& result
= target_results
->second
.find(command
);
203 if (result
== target_results
->second
.end())
204 return std::string("");
206 return result
->second
;
210 bool AdminSocketOutput::run_tests() const {
211 for (const auto& socket
: sockets
) {
212 const auto& seek
= tests
.find(socket
.first
);
213 if (seek
!= tests
.end()) {
214 std::cout
<< std::endl
;
215 std::cout
<< "Running tests for " << socket
.first
<< " socket" << std::endl
;
216 for (const auto& test
: seek
->second
) {
217 auto result
= get_result(socket
.first
, test
.first
);
219 std::cout
<< "Failed to find result for command: " << test
.first
<< std::endl
;
222 std::cout
<< "Running test for command: " << test
.first
<< std::endl
;
223 const auto& test_func
= test
.second
;
224 bool res
= test_func(result
);
228 std::cout
<< "Test passed" << std::endl
;
237 void AdminSocketOutput::exec() {
238 ceph_assert(init_directories());
239 ceph_assert(init_sockets());
240 ceph_assert(gather_socket_output());
241 ceph_assert(run_tests());