github.com/igggame/nebulas-go@v2.1.0+incompatible/nbre/test/common/ipc/ipc_instance.cpp (about) 1 // Copyright (C) 2018 go-nebulas authors 2 // 3 // This file is part of the go-nebulas library. 4 // 5 // the go-nebulas library is free software: you can redistribute it and/or 6 // modify 7 // it under the terms of the GNU General Public License as published by 8 // the Free Software Foundation, either version 3 of the License, or 9 // (at your option) any later version. 10 // 11 // the go-nebulas library is distributed in the hope that it will be useful, 12 // but WITHOUT ANY WARRANTY; without even the implied warranty of 13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 // GNU General Public License for more details. 15 // 16 // You should have received a copy of the GNU General Public License 17 // along with the go-nebulas library. If not, see 18 // <http://www.gnu.org/licenses/>. 19 // 20 #include "test/common/ipc/ipc_instance.h" 21 #include "common/configuration.h" 22 #include "fs/util.h" 23 #include <boost/asio/ip/host_name.hpp> 24 #include <boost/date_time/posix_time/posix_time.hpp> 25 #include <boost/process/child.hpp> 26 #include <boost/program_options.hpp> 27 #include <chrono> 28 #include <iostream> 29 30 namespace po = boost::program_options; 31 32 namespace neb { 33 ipc_instances::~ipc_instances() {} 34 35 void ipc_instances::init_ipc_instances(int argc, char *argv[]) { 36 po::options_description desc("Do IPC tests"); 37 desc.add_options()("help", "show help message")( 38 "list", "show all IPC instances")("fixture", po::value<std::string>(), 39 "enabled fixure, can be a " 40 "fixture name shown in \"list\" " 41 "option [default: all]")( 42 "instance", po::value<std::string>(), 43 "server | client")("debug", "debug mode without catching exceptions.")( 44 "enable-log", "enable glog to stderr"); 45 46 po::variables_map vm; 47 po::store(po::parse_command_line(argc, argv, desc), vm); 48 po::notify(vm); 49 if (vm.count("help")) { 50 std::cout << desc << std::endl; 51 exit(1); 52 } 53 if (vm.count("list")) { 54 show_all_instances(); 55 exit(1); 56 } 57 58 std::string fixture_name = "all"; 59 if (vm.count("fixture")) { 60 fixture_name = vm["fixture"].as<std::string>(); 61 } 62 m_enabled_fixture_name = fixture_name; 63 if (fixture_name != std::string("all") && !vm.count("instance")) { 64 std::cout << "miss *instance*" << std::endl; 65 std::cout << desc << std::endl; 66 exit(1); 67 } 68 if (vm.count("debug")) { 69 m_debug_mode = true; 70 } else { 71 m_debug_mode = false; 72 } 73 if (vm.count("instance")) { 74 m_enabled_instance_name = vm["instance"].as<std::string>(); 75 } 76 if (vm.count("enable-log")) { 77 FLAGS_logtostderr = true; 78 ::google::SetStderrLogging(google::GLOG_INFO); 79 ::google::SetLogDestination( 80 google::GLOG_INFO, configuration::instance().nbre_root_dir().c_str()); 81 } else { 82 FLAGS_logtostderr = false; 83 ::google::SetLogDestination( 84 google::GLOG_ERROR, configuration::instance().nbre_root_dir().c_str()); 85 } 86 ::google::InitGoogleLogging(argv[0]); 87 LOG(INFO) << argv[0] << " started! "; 88 m_exe_name = 89 neb::fs::join_path(neb::fs::cur_full_path(), std::string(argv[0])); 90 } 91 92 void ipc_instances::show_all_instances() { 93 std::map<std::string, std::vector<std::string>> all; 94 for (auto it = m_all_instances.begin(); it != m_all_instances.end(); ++it) { 95 std::string fixture = (*it)->get_fixture_name(); 96 std::string name = (*it)->get_instance_name(); 97 98 if (all.find(fixture) == all.end()) { 99 all.insert(std::make_pair(fixture, std::vector<std::string>())); 100 } 101 all[fixture].push_back(name); 102 } 103 104 for (decltype(all)::iterator it = all.begin(); it != all.end(); ++it) { 105 std::cout << "|-" << it->first << std::endl; 106 for (size_t i = 0; i < it->second.size(); ++i) { 107 std::cout << "|----" << it->second[i] << std::endl; 108 } 109 } 110 } 111 112 int ipc_instances::run_all_ipc_instances() { 113 std::string fp = m_exe_name; 114 115 LOG(INFO) << "file path: " << fp; 116 std::unordered_set<std::string> done_fixtures; 117 std::unordered_set<std::string> has_prelude_fixtures; 118 119 if (m_enabled_fixture_name == std::string("all")) { 120 int exit_code = 0; 121 for (auto it = m_all_instances.begin(); it != m_all_instances.end(); ++it) { 122 std::string fixture = (*it)->get_fixture_name(); 123 std::string instance = (*it)->get_instance_name(); 124 if (instance == std::string("prelude")) { 125 has_prelude_fixtures.insert(fixture); 126 } 127 } 128 129 for (auto it = m_all_instances.begin(); it != m_all_instances.end(); ++it) { 130 std::string fixture = (*it)->get_fixture_name(); 131 if (done_fixtures.find(fixture) != done_fixtures.end()) 132 continue; 133 done_fixtures.insert(fixture); 134 135 if (has_prelude_fixtures.find(fixture) != has_prelude_fixtures.end()) { 136 boost::process::child prelude(fp, "--fixture", fixture, "--instance", 137 "prelude"); 138 prelude.wait(); 139 } 140 141 boost::process::child server(fp, "--fixture", fixture, "--instance", 142 "server"); 143 boost::process::child client(fp, "--fixture", fixture, "--instance", 144 "client"); 145 146 if (!server.valid()) { 147 std::cout << "invalid server process for " << fixture << std::endl; 148 } 149 if (!client.valid()) { 150 std::cout << "invalid client process for " << fixture << std::endl; 151 } 152 153 int tmp_exit_code = 0; 154 if (server.valid()) { 155 server.join(); 156 tmp_exit_code += server.exit_code(); 157 if (server.exit_code() == 0) { 158 std::cerr << ::neb::tcolor::green << now() << " Success: " << fixture 159 << "." 160 << "server" << ::neb::tcolor::reset << std::endl; 161 } else { 162 std::cerr << ::neb::tcolor::red << now() << " Fail: " << fixture 163 << "." 164 << "server" << ::neb::tcolor::reset << std::endl; 165 } 166 } 167 if (client.valid()) { 168 client.join(); 169 tmp_exit_code += server.exit_code(); 170 if (client.exit_code() == 0) { 171 std::cerr << ::neb::tcolor::green << now() << " Success: " << fixture 172 << "." 173 << "client" << ::neb::tcolor::reset << std::endl; 174 } else { 175 std::cerr << ::neb::tcolor::red << now() << " Fail: " << fixture 176 << "." 177 << "client" << ::neb::tcolor::reset << std::endl; 178 } 179 } 180 exit_code += tmp_exit_code; 181 } 182 return exit_code; 183 } else { 184 return run_one_ipc_instance(m_enabled_fixture_name, 185 m_enabled_instance_name); 186 } 187 } 188 189 int ipc_instances::run_one_ipc_instance(const std::string &fixture, 190 const std::string &instance) { 191 192 bool found = false; 193 for (auto it = m_all_instances.begin(); it != m_all_instances.end(); ++it) { 194 std::string cur_fixture = (*it)->get_fixture_name(); 195 std::string cur_instance = (*it)->get_instance_name(); 196 if (cur_fixture == fixture && cur_instance == instance) { 197 found = true; 198 std::cerr << ::neb::tcolor::reset << now() << " Start " << fixture << "." 199 << instance << ::neb::tcolor::reset << std::endl; 200 if (m_debug_mode) { 201 (*it)->run(); 202 } else { 203 try { 204 (*it)->run(); 205 } catch (const std::exception &e) { 206 std::cerr << ::neb::tcolor::red << now() << " Exception: " << fixture 207 << "." << instance << " " << e.what() 208 << ::neb::tcolor::reset << std::endl; 209 return -1; 210 } 211 } 212 } 213 } 214 if (!found) { 215 std::cout << "cannot find " << instance << " for " << fixture << std::endl; 216 return -1; 217 } 218 return 0; 219 } 220 size_t ipc_instances::register_ipc_instance(const ipc_instance_base_ptr &b) { 221 m_all_instances.push_back(b); 222 return m_all_instances.size(); 223 } 224 } // end namespace neb