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