d_test_stubs.cc 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327
  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. "\"ip_address\" : \"127.0.0.1\" , "
  22. "\"port\" : 5031, "
  23. "\"tsig_keys\": ["
  24. "{ \"name\": \"d2_key.tmark.org\" , "
  25. " \"algorithm\": \"HMAC-MD5\" ,"
  26. " \"secret\": \"LSWXnfkKZjdPJI5QxlpnfQ==\" "
  27. "} ],"
  28. "\"forward_ddns\" : {"
  29. "\"ddns_domains\": [ "
  30. "{ \"name\": \"tmark.org.\" , "
  31. " \"key_name\": \"d2_key.tmark.org\" , "
  32. " \"dns_servers\" : [ "
  33. " { \"hostname\": \"one.tmark\" } "
  34. "] } ] }, "
  35. "\"reverse_ddns\" : {"
  36. "\"ddns_domains\": [ "
  37. "{ \"name\": \" 0.168.192.in.addr.arpa.\" , "
  38. " \"key_name\": \"d2_key.tmark.org\" , "
  39. " \"dns_servers\" : [ "
  40. " { \"ip_address\": \"127.0.0.101\" , "
  41. " \"port\": 100 } ] } "
  42. "] } }";
  43. // Initialize the static failure flag.
  44. SimFailure::FailureType SimFailure::failure_type_ = SimFailure::ftNoFailure;
  45. // Define custom process command supported by DStubProcess.
  46. const char* DStubProcess::stub_proc_command_("cool_proc_cmd");
  47. DStubProcess::DStubProcess(const char* name, IOServicePtr io_service)
  48. : DProcessBase(name, io_service, DCfgMgrBasePtr(new DStubCfgMgr())) {
  49. };
  50. void
  51. DStubProcess::init() {
  52. if (SimFailure::shouldFailOn(SimFailure::ftProcessInit)) {
  53. // Simulates a failure to instantiate the process.
  54. isc_throw(DProcessBaseError, "DStubProcess simulated init() failure");
  55. }
  56. };
  57. void
  58. DStubProcess::run() {
  59. // Until shut down or an fatal error occurs, wait for and
  60. // execute a single callback. This is a preliminary implementation
  61. // that is likely to evolve as development progresses.
  62. // To use run(), the "managing" layer must issue an io_service::stop
  63. // or the call to run will continue to block, and shutdown will not
  64. // occur.
  65. IOServicePtr& io_service = getIoService();
  66. while (!shouldShutdown()) {
  67. try {
  68. io_service->run_one();
  69. } catch (const std::exception& ex) {
  70. isc_throw (DProcessBaseError,
  71. std::string("Process run method failed:") + ex.what());
  72. }
  73. }
  74. };
  75. isc::data::ConstElementPtr
  76. DStubProcess::shutdown(isc::data::ConstElementPtr /* args */) {
  77. if (SimFailure::shouldFailOn(SimFailure::ftProcessShutdown)) {
  78. // Simulates a failure during shutdown process.
  79. isc_throw(DProcessBaseError, "DStubProcess simulated shutdown failure");
  80. }
  81. setShutdownFlag(true);
  82. stopIOService();
  83. return (isc::config::createAnswer(0, "Shutdown inititiated."));
  84. }
  85. isc::data::ConstElementPtr
  86. DStubProcess::configure(isc::data::ConstElementPtr /*config_set*/) {
  87. if (SimFailure::shouldFailOn(SimFailure::ftProcessConfigure)) {
  88. // Simulates a process configure failure.
  89. return (isc::config::createAnswer(1,
  90. "Simulated process configuration error."));
  91. }
  92. return (isc::config::createAnswer(0, "Configuration accepted."));
  93. }
  94. isc::data::ConstElementPtr
  95. DStubProcess::command(const std::string& command,
  96. isc::data::ConstElementPtr /* args */) {
  97. isc::data::ConstElementPtr answer;
  98. if (SimFailure::shouldFailOn(SimFailure::ftProcessCommand)) {
  99. // Simulates a process command execution failure.
  100. answer = isc::config::createAnswer(COMMAND_ERROR,
  101. "SimFailure::ftProcessCommand");
  102. } else if (command.compare(stub_proc_command_) == 0) {
  103. answer = isc::config::createAnswer(COMMAND_SUCCESS, "Command accepted");
  104. } else {
  105. answer = isc::config::createAnswer(COMMAND_INVALID,
  106. "Unrecognized command:" + command);
  107. }
  108. return (answer);
  109. }
  110. DStubProcess::~DStubProcess() {
  111. };
  112. //************************** DStubController *************************
  113. // Define custom controller command supported by DStubController.
  114. const char* DStubController::stub_ctl_command_("spiffy");
  115. // Define custom command line option command supported by DStubController.
  116. const char* DStubController::stub_option_x_ = "x";
  117. /// @brief Defines the app name used to construct the controller
  118. const char* DStubController::stub_app_name_ = "TestService";
  119. /// @brief Defines the bin name used to construct the controller
  120. const char* DStubController::stub_bin_name_ = "TestBin";
  121. DControllerBasePtr&
  122. DStubController::instance() {
  123. // If the singleton hasn't been created, do it now.
  124. if (!getController()) {
  125. DControllerBasePtr p(new DStubController());
  126. setController(p);
  127. }
  128. return (getController());
  129. }
  130. DStubController::DStubController()
  131. : DControllerBase(stub_app_name_, stub_bin_name_) {
  132. if (getenv("B10_FROM_BUILD")) {
  133. setSpecFileName(std::string(getenv("B10_FROM_BUILD")) +
  134. "/src/bin/d2/dhcp-ddns.spec");
  135. } else {
  136. setSpecFileName(D2_SPECFILE_LOCATION);
  137. }
  138. }
  139. bool
  140. DStubController::customOption(int option, char* /* optarg */)
  141. {
  142. // Check for the custom option supported by DStubController.
  143. if (static_cast<char>(option) == *stub_option_x_) {
  144. return (true);
  145. }
  146. return (false);
  147. }
  148. DProcessBase* DStubController::createProcess() {
  149. if (SimFailure::shouldFailOn(SimFailure::ftCreateProcessException)) {
  150. // Simulates a failure to instantiate the process due to exception.
  151. throw std::runtime_error("SimFailure::ftCreateProcess");
  152. }
  153. if (SimFailure::shouldFailOn(SimFailure::ftCreateProcessNull)) {
  154. // Simulates a failure to instantiate the process.
  155. return (NULL);
  156. }
  157. // This should be a successful instantiation.
  158. return (new DStubProcess(getAppName().c_str(), getIOService()));
  159. }
  160. isc::data::ConstElementPtr
  161. DStubController::customControllerCommand(const std::string& command,
  162. isc::data::ConstElementPtr /* args */) {
  163. isc::data::ConstElementPtr answer;
  164. if (SimFailure::shouldFailOn(SimFailure::ftControllerCommand)) {
  165. // Simulates command failing to execute.
  166. answer = isc::config::createAnswer(COMMAND_ERROR,
  167. "SimFailure::ftControllerCommand");
  168. } else if (command.compare(stub_ctl_command_) == 0) {
  169. answer = isc::config::createAnswer(COMMAND_SUCCESS, "Command accepted");
  170. } else {
  171. answer = isc::config::createAnswer(COMMAND_INVALID,
  172. "Unrecognized command:" + command);
  173. }
  174. return (answer);
  175. }
  176. const std::string DStubController::getCustomOpts() const {
  177. // Return the "list" of custom options supported by DStubController.
  178. return (std::string(stub_option_x_));
  179. }
  180. DStubController::~DStubController() {
  181. }
  182. // Initialize controller wrapper's static instance getter member.
  183. DControllerTest::InstanceGetter DControllerTest::instanceGetter_ = NULL;
  184. //************************** ObjectParser *************************
  185. ObjectParser::ObjectParser(const std::string& param_name,
  186. ObjectStoragePtr& object_values)
  187. : param_name_(param_name), object_values_(object_values) {
  188. }
  189. ObjectParser::~ObjectParser(){
  190. }
  191. void
  192. ObjectParser::build(isc::data::ConstElementPtr new_config) {
  193. if (SimFailure::shouldFailOn(SimFailure::ftElementBuild)) {
  194. // Simulates an error during element data parsing.
  195. isc_throw (DCfgMgrBaseError, "Simulated build exception");
  196. }
  197. value_ = new_config;
  198. }
  199. void
  200. ObjectParser::commit() {
  201. if (SimFailure::shouldFailOn(SimFailure::ftElementCommit)) {
  202. // Simulates an error while committing the parsed element data.
  203. throw std::runtime_error("Simulated commit exception");
  204. }
  205. object_values_->setParam(param_name_, value_,
  206. isc::data::Element::Position());
  207. }
  208. //************************** DStubContext *************************
  209. DStubContext::DStubContext(): object_values_(new ObjectStorage()) {
  210. }
  211. DStubContext::~DStubContext() {
  212. }
  213. void
  214. DStubContext::getObjectParam(const std::string& name,
  215. isc::data::ConstElementPtr& value) {
  216. value = object_values_->getParam(name);
  217. }
  218. ObjectStoragePtr&
  219. DStubContext::getObjectStorage() {
  220. return (object_values_);
  221. }
  222. DCfgContextBasePtr
  223. DStubContext::clone() {
  224. return (DCfgContextBasePtr(new DStubContext(*this)));
  225. }
  226. DStubContext::DStubContext(const DStubContext& rhs): DCfgContextBase(rhs),
  227. object_values_(new ObjectStorage(*(rhs.object_values_))) {
  228. }
  229. //************************** DStubCfgMgr *************************
  230. DStubCfgMgr::DStubCfgMgr()
  231. : DCfgMgrBase(DCfgContextBasePtr(new DStubContext())) {
  232. }
  233. DStubCfgMgr::~DStubCfgMgr() {
  234. }
  235. DCfgContextBasePtr
  236. DStubCfgMgr::createNewContext() {
  237. return (DCfgContextBasePtr (new DStubContext()));
  238. }
  239. isc::dhcp::ParserPtr
  240. DStubCfgMgr::createConfigParser(const std::string& element_id) {
  241. isc::dhcp::ParserPtr parser;
  242. DStubContextPtr context
  243. = boost::dynamic_pointer_cast<DStubContext>(getContext());
  244. if (element_id == "bool_test") {
  245. parser.reset(new isc::dhcp::
  246. BooleanParser(element_id,
  247. context->getBooleanStorage()));
  248. } else if (element_id == "uint32_test") {
  249. parser.reset(new isc::dhcp::Uint32Parser(element_id,
  250. context->getUint32Storage()));
  251. } else if (element_id == "string_test") {
  252. parser.reset(new isc::dhcp::StringParser(element_id,
  253. context->getStringStorage()));
  254. } else {
  255. // Fail only if SimFailure dictates we should. This makes it easier
  256. // to test parse ordering, by permitting a wide range of element ids
  257. // to "succeed" without specifically supporting them.
  258. if (SimFailure::shouldFailOn(SimFailure::ftElementUnknown)) {
  259. isc_throw(DCfgMgrBaseError,
  260. "Configuration parameter not supported: " << element_id);
  261. }
  262. // Going to assume anything else is an object element.
  263. parser.reset(new ObjectParser(element_id, context->getObjectStorage()));
  264. }
  265. parsed_order_.push_back(element_id);
  266. return (parser);
  267. }
  268. }; // namespace isc::d2
  269. }; // namespace isc