d_test_stubs.cc 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319
  1. // Copyright (C) 2013 Internet Systems Consortium, Inc. ("ISC")
  2. //
  3. // Permission to use, copy, modify, and/or distribute this software for any
  4. // purpose with or without fee is hereby granted, provided that the above
  5. // copyright notice and this permission notice appear in all copies.
  6. //
  7. // THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
  8. // REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
  9. // AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
  10. // INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
  11. // LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
  12. // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  13. // PERFORMANCE OF THIS SOFTWARE.
  14. #include <d2/d2_log.h>
  15. #include <d2/spec_config.h>
  16. #include <d2/tests/d_test_stubs.h>
  17. using namespace asio;
  18. namespace isc {
  19. namespace d2 {
  20. const char* valid_d2_config = "{ "
  21. "\"interface\" : \"eth1\" , "
  22. "\"ip_address\" : \"127.0.0.1\" , "
  23. "\"port\" : 5031, "
  24. "\"tsig_keys\": ["
  25. "{ \"name\": \"d2_key.tmark.org\" , "
  26. " \"algorithm\": \"md5\" ,"
  27. " \"secret\": \"0123456989\" "
  28. "} ],"
  29. "\"forward_ddns\" : {"
  30. "\"ddns_domains\": [ "
  31. "{ \"name\": \"tmark.org\" , "
  32. " \"key_name\": \"d2_key.tmark.org\" , "
  33. " \"dns_servers\" : [ "
  34. " { \"hostname\": \"one.tmark\" } "
  35. "] } ] }, "
  36. "\"reverse_ddns\" : {"
  37. "\"ddns_domains\": [ "
  38. "{ \"name\": \" 0.168.192.in.addr.arpa.\" , "
  39. " \"key_name\": \"d2_key.tmark.org\" , "
  40. " \"dns_servers\" : [ "
  41. " { \"ip_address\": \"127.0.0.101\" , "
  42. " \"port\": 100 } ] } "
  43. "] } }";
  44. // Initialize the static failure flag.
  45. SimFailure::FailureType SimFailure::failure_type_ = SimFailure::ftNoFailure;
  46. // Define custom process command supported by DStubProcess.
  47. const char* DStubProcess::stub_proc_command_("cool_proc_cmd");
  48. DStubProcess::DStubProcess(const char* name, IOServicePtr io_service)
  49. : DProcessBase(name, io_service, DCfgMgrBasePtr(new DStubCfgMgr())) {
  50. };
  51. void
  52. DStubProcess::init() {
  53. if (SimFailure::shouldFailOn(SimFailure::ftProcessInit)) {
  54. // Simulates a failure to instantiate the process.
  55. isc_throw(DProcessBaseError, "DStubProcess simulated init() failure");
  56. }
  57. };
  58. void
  59. DStubProcess::run() {
  60. // Until shut down or an fatal error occurs, wait for and
  61. // execute a single callback. This is a preliminary implementation
  62. // that is likely to evolve as development progresses.
  63. // To use run(), the "managing" layer must issue an io_service::stop
  64. // or the call to run will continue to block, and shutdown will not
  65. // occur.
  66. IOServicePtr& io_service = getIoService();
  67. while (!shouldShutdown()) {
  68. try {
  69. io_service->run_one();
  70. } catch (const std::exception& ex) {
  71. isc_throw (DProcessBaseError,
  72. std::string("Process run method failed:") + ex.what());
  73. }
  74. }
  75. };
  76. isc::data::ConstElementPtr
  77. DStubProcess::shutdown(isc::data::ConstElementPtr /* args */) {
  78. if (SimFailure::shouldFailOn(SimFailure::ftProcessShutdown)) {
  79. // Simulates a failure during shutdown process.
  80. isc_throw(DProcessBaseError, "DStubProcess simulated shutdown failure");
  81. }
  82. setShutdownFlag(true);
  83. stopIOService();
  84. return (isc::config::createAnswer(0, "Shutdown inititiated."));
  85. }
  86. isc::data::ConstElementPtr
  87. DStubProcess::configure(isc::data::ConstElementPtr /*config_set*/) {
  88. if (SimFailure::shouldFailOn(SimFailure::ftProcessConfigure)) {
  89. // Simulates a process configure failure.
  90. return (isc::config::createAnswer(1,
  91. "Simulated process configuration error."));
  92. }
  93. return (isc::config::createAnswer(0, "Configuration accepted."));
  94. }
  95. isc::data::ConstElementPtr
  96. DStubProcess::command(const std::string& command,
  97. isc::data::ConstElementPtr /* args */) {
  98. isc::data::ConstElementPtr answer;
  99. if (SimFailure::shouldFailOn(SimFailure::ftProcessCommand)) {
  100. // Simulates a process command execution failure.
  101. answer = isc::config::createAnswer(COMMAND_ERROR,
  102. "SimFailure::ftProcessCommand");
  103. } else if (command.compare(stub_proc_command_) == 0) {
  104. answer = isc::config::createAnswer(COMMAND_SUCCESS, "Command accepted");
  105. } else {
  106. answer = isc::config::createAnswer(COMMAND_INVALID,
  107. "Unrecognized command:" + command);
  108. }
  109. return (answer);
  110. }
  111. DStubProcess::~DStubProcess() {
  112. };
  113. //************************** DStubController *************************
  114. // Define custom controller command supported by DStubController.
  115. const char* DStubController::stub_ctl_command_("spiffy");
  116. // Define custom command line option command supported by DStubController.
  117. const char* DStubController::stub_option_x_ = "x";
  118. /// @brief Defines the app name used to construct the controller
  119. const char* DStubController::stub_app_name_ = "TestService";
  120. /// @brief Defines the bin name used to construct the controller
  121. const char* DStubController::stub_bin_name_ = "TestBin";
  122. DControllerBasePtr&
  123. DStubController::instance() {
  124. // If the singleton hasn't been created, do it now.
  125. if (!getController()) {
  126. DControllerBasePtr p(new DStubController());
  127. setController(p);
  128. }
  129. return (getController());
  130. }
  131. DStubController::DStubController()
  132. : DControllerBase(stub_app_name_, stub_bin_name_) {
  133. if (getenv("B10_FROM_BUILD")) {
  134. setSpecFileName(std::string(getenv("B10_FROM_BUILD")) +
  135. "/src/bin/d2/dhcp-ddns.spec");
  136. } else {
  137. setSpecFileName(D2_SPECFILE_LOCATION);
  138. }
  139. }
  140. bool
  141. DStubController::customOption(int option, char* /* optarg */)
  142. {
  143. // Check for the custom option supported by DStubController.
  144. if (static_cast<char>(option) == *stub_option_x_) {
  145. return (true);
  146. }
  147. return (false);
  148. }
  149. DProcessBase* DStubController::createProcess() {
  150. if (SimFailure::shouldFailOn(SimFailure::ftCreateProcessException)) {
  151. // Simulates a failure to instantiate the process due to exception.
  152. throw std::runtime_error("SimFailure::ftCreateProcess");
  153. }
  154. if (SimFailure::shouldFailOn(SimFailure::ftCreateProcessNull)) {
  155. // Simulates a failure to instantiate the process.
  156. return (NULL);
  157. }
  158. // This should be a successful instantiation.
  159. return (new DStubProcess(getAppName().c_str(), getIOService()));
  160. }
  161. isc::data::ConstElementPtr
  162. DStubController::customControllerCommand(const std::string& command,
  163. isc::data::ConstElementPtr /* args */) {
  164. isc::data::ConstElementPtr answer;
  165. if (SimFailure::shouldFailOn(SimFailure::ftControllerCommand)) {
  166. // Simulates command failing to execute.
  167. answer = isc::config::createAnswer(COMMAND_ERROR,
  168. "SimFailure::ftControllerCommand");
  169. } else if (command.compare(stub_ctl_command_) == 0) {
  170. answer = isc::config::createAnswer(COMMAND_SUCCESS, "Command accepted");
  171. } else {
  172. answer = isc::config::createAnswer(COMMAND_INVALID,
  173. "Unrecognized command:" + command);
  174. }
  175. return (answer);
  176. }
  177. const std::string DStubController::getCustomOpts() const {
  178. // Return the "list" of custom options supported by DStubController.
  179. return (std::string(stub_option_x_));
  180. }
  181. DStubController::~DStubController() {
  182. }
  183. // Initialize controller wrapper's static instance getter member.
  184. DControllerTest::InstanceGetter DControllerTest::instanceGetter_ = NULL;
  185. //************************** TestParser *************************
  186. TestParser::TestParser(const std::string& param_name):param_name_(param_name) {
  187. }
  188. TestParser::~TestParser(){
  189. }
  190. void
  191. TestParser::build(isc::data::ConstElementPtr new_config) {
  192. if (SimFailure::shouldFailOn(SimFailure::ftElementBuild)) {
  193. // Simulates an error during element data parsing.
  194. isc_throw (DCfgMgrBaseError, "Simulated build exception");
  195. }
  196. value_ = new_config;
  197. }
  198. void
  199. TestParser::commit() {
  200. if (SimFailure::shouldFailOn(SimFailure::ftElementCommit)) {
  201. // Simulates an error while committing the parsed element data.
  202. throw std::runtime_error("Simulated commit exception");
  203. }
  204. }
  205. //************************** DStubContext *************************
  206. DStubContext::DStubContext(): extra_values_(new isc::dhcp::Uint32Storage()) {
  207. }
  208. DStubContext::~DStubContext() {
  209. }
  210. void
  211. DStubContext::getExtraParam(const std::string& name, uint32_t& value) {
  212. value = extra_values_->getParam(name);
  213. }
  214. isc::dhcp::Uint32StoragePtr
  215. DStubContext::getExtraStorage() {
  216. return (extra_values_);
  217. }
  218. DCfgContextBasePtr
  219. DStubContext::clone() {
  220. return (DCfgContextBasePtr(new DStubContext(*this)));
  221. }
  222. DStubContext::DStubContext(const DStubContext& rhs): DCfgContextBase(rhs),
  223. extra_values_(new isc::dhcp::Uint32Storage(*(rhs.extra_values_))) {
  224. }
  225. //************************** DStubCfgMgr *************************
  226. DStubCfgMgr::DStubCfgMgr()
  227. : DCfgMgrBase(DCfgContextBasePtr(new DStubContext())) {
  228. }
  229. DStubCfgMgr::~DStubCfgMgr() {
  230. }
  231. isc::dhcp::ParserPtr
  232. DStubCfgMgr::createConfigParser(const std::string& element_id) {
  233. isc::dhcp::DhcpConfigParser* parser = NULL;
  234. DStubContextPtr context =
  235. boost::dynamic_pointer_cast<DStubContext>(getContext());
  236. if (element_id == "bool_test") {
  237. parser = new isc::dhcp::BooleanParser(element_id,
  238. context->getBooleanStorage());
  239. } else if (element_id == "uint32_test") {
  240. parser = new isc::dhcp::Uint32Parser(element_id,
  241. context->getUint32Storage());
  242. } else if (element_id == "string_test") {
  243. parser = new isc::dhcp::StringParser(element_id,
  244. context->getStringStorage());
  245. } else if (element_id == "extra_test") {
  246. parser = new isc::dhcp::Uint32Parser(element_id,
  247. context->getExtraStorage());
  248. } else {
  249. // Fail only if SimFailure dictates we should. This makes it easier
  250. // to test parse ordering, by permitting a wide range of element ids
  251. // to "succeed" without specifically supporting them.
  252. if (SimFailure::shouldFailOn(SimFailure::ftElementUnknown)) {
  253. isc_throw(DCfgMgrBaseError, "Configuration parameter not supported: "
  254. << element_id);
  255. }
  256. parsed_order_.push_back(element_id);
  257. parser = new TestParser(element_id);
  258. }
  259. return (isc::dhcp::ParserPtr(parser));
  260. }
  261. }; // namespace isc::d2
  262. }; // namespace isc