d_test_stubs.h 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693
  1. // Copyright (C) 2013-2014 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. #ifndef D_TEST_STUBS_H
  15. #define D_TEST_STUBS_H
  16. #include <cc/data.h>
  17. #include <cc/session.h>
  18. #include <config/ccsession.h>
  19. #include <d2/d2_asio.h>
  20. #include <d2/d_controller.h>
  21. #include <d2/d_cfg_mgr.h>
  22. #include <gtest/gtest.h>
  23. #include <fstream>
  24. #include <iostream>
  25. #include <sstream>
  26. namespace isc {
  27. namespace d2 {
  28. /// @brief Provides a valid DHCP-DDNS configuration for testing basic
  29. /// parsing fundamentals.
  30. extern const char* valid_d2_config;
  31. /// @brief Class is used to set a globally accessible value that indicates
  32. /// a specific type of failure to simulate. Test derivations of base classes
  33. /// can exercise error handling code paths by testing for specific SimFailure
  34. /// values at the appropriate places and then causing the error to "occur".
  35. /// The class consists of an enumerated set of failures, and static methods
  36. /// for getting, setting, and testing the current value.
  37. class SimFailure {
  38. public:
  39. enum FailureType {
  40. ftUnknown = -1,
  41. ftNoFailure = 0,
  42. ftCreateProcessException,
  43. ftCreateProcessNull,
  44. ftProcessInit,
  45. ftProcessConfigure,
  46. ftControllerCommand,
  47. ftProcessCommand,
  48. ftProcessShutdown,
  49. ftElementBuild,
  50. ftElementCommit,
  51. ftElementUnknown
  52. };
  53. /// @brief Sets the SimFailure value to the given value.
  54. ///
  55. /// @param value is the new value to assign to the global value.
  56. static void set(enum FailureType value) {
  57. failure_type_ = value;
  58. }
  59. /// @brief Gets the current global SimFailure value
  60. ///
  61. /// @return returns the current SimFailure value
  62. static enum FailureType get() {
  63. return (failure_type_);
  64. }
  65. /// @brief One-shot test of the SimFailure value. If the global
  66. /// SimFailure value is equal to the given value, clear the global
  67. /// value and return true. This makes it convenient for code to
  68. /// test and react without having to explicitly clear the global
  69. /// value.
  70. ///
  71. /// @param value is the value against which the global value is
  72. /// to be compared.
  73. ///
  74. /// @return returns true if current SimFailure value matches the
  75. /// given value.
  76. static bool shouldFailOn(enum FailureType value) {
  77. if (failure_type_ == value) {
  78. clear();
  79. return (true);
  80. }
  81. return (false);
  82. }
  83. /// @brief Resets the failure type to none.
  84. static void clear() {
  85. failure_type_ = ftNoFailure;
  86. }
  87. /// @brief Static value for holding the failure type to simulate.
  88. static enum FailureType failure_type_;
  89. };
  90. /// @brief Test Derivation of the DProcessBase class.
  91. ///
  92. /// This class is used primarily to server as a test process class for testing
  93. /// DControllerBase. It provides minimal, but sufficient implementation to
  94. /// test the majority of DControllerBase functionality.
  95. class DStubProcess : public DProcessBase {
  96. public:
  97. /// @brief Static constant that defines a custom process command string.
  98. static const char* stub_proc_command_;
  99. /// @brief Constructor
  100. ///
  101. /// @param name name is a text label for the process. Generally used
  102. /// in log statements, but otherwise arbitrary.
  103. /// @param io_service is the io_service used by the caller for
  104. /// asynchronous event handling.
  105. ///
  106. /// @throw DProcessBaseError is io_service is NULL.
  107. DStubProcess(const char* name, IOServicePtr io_service);
  108. /// @brief Invoked after process instantiation to perform initialization.
  109. /// This implementation supports simulating an error initializing the
  110. /// process by throwing a DProcessBaseError if SimFailure is set to
  111. /// ftProcessInit.
  112. virtual void init();
  113. /// @brief Implements the process's event loop.
  114. /// This implementation is quite basic, surrounding calls to
  115. /// io_service->runOne() with a test of the shutdown flag. Once invoked,
  116. /// the method will continue until the process itself is exiting due to a
  117. /// request to shutdown or some anomaly forces an exit.
  118. /// @return returns 0 upon a successful, "normal" termination, non-zero to
  119. /// indicate an abnormal termination.
  120. virtual void run();
  121. /// @brief Implements the process shutdown procedure.
  122. ///
  123. /// This sets the instance shutdown flag monitored by run() and stops
  124. /// the IO service.
  125. virtual isc::data::ConstElementPtr shutdown(isc::data::ConstElementPtr);
  126. /// @brief Processes the given configuration.
  127. ///
  128. /// This implementation fails if SimFailure is set to ftProcessConfigure.
  129. /// Otherwise it will complete successfully. It does not check the content
  130. /// of the inbound configuration.
  131. ///
  132. /// @param config_set a new configuration (JSON) for the process
  133. /// @return an Element that contains the results of configuration composed
  134. /// of an integer status value (0 means successful, non-zero means failure),
  135. /// and a string explanation of the outcome.
  136. virtual isc::data::ConstElementPtr configure(isc::data::ConstElementPtr
  137. config_set);
  138. /// @brief Executes the given command.
  139. ///
  140. /// This implementation will recognizes one "custom" process command,
  141. /// stub_proc_command_. It will fail if SimFailure is set to
  142. /// ftProcessCommand.
  143. ///
  144. /// @param command is a string label representing the command to execute.
  145. /// @param args is a set of arguments (if any) required for the given
  146. /// command.
  147. /// @return an Element that contains the results of command composed
  148. /// of an integer status value and a string explanation of the outcome.
  149. /// The status value is:
  150. /// COMMAND_SUCCESS if the command is recognized and executes successfully.
  151. /// COMMAND_ERROR if the command is recognized but fails to execute.
  152. /// COMMAND_INVALID if the command is not recognized.
  153. virtual isc::data::ConstElementPtr command(const std::string& command,
  154. isc::data::ConstElementPtr args);
  155. // @brief Destructor
  156. virtual ~DStubProcess();
  157. };
  158. /// @brief Test Derivation of the DControllerBase class.
  159. ///
  160. /// DControllerBase is an abstract class and therefore requires a derivation
  161. /// for testing. It allows testing the majority of the base class code
  162. /// without polluting production derivations (e.g. D2Process). It uses
  163. /// DStubProcess as its application process class. It is a full enough
  164. /// implementation to support running both stand alone and integrated.
  165. /// Obviously BIND10 connectivity is not available under unit tests, so
  166. /// testing here is limited to "failures" to communicate with BIND10.
  167. class DStubController : public DControllerBase {
  168. public:
  169. /// @brief Static singleton instance method. This method returns the
  170. /// base class singleton instance member. It instantiates the singleton
  171. /// and sets the base class instance member upon first invocation.
  172. ///
  173. /// @return returns a pointer reference to the singleton instance.
  174. static DControllerBasePtr& instance();
  175. /// @brief Defines a custom controller command string. This is a
  176. /// custom command supported by DStubController.
  177. static const char* stub_ctl_command_;
  178. /// @brief Defines a custom command line option supported by
  179. /// DStubController.
  180. static const char* stub_option_x_;
  181. /// @brief Defines the app name used to construct the controller
  182. static const char* stub_app_name_;
  183. /// @brief Defines the executable name used to construct the controller
  184. static const char* stub_bin_name_;
  185. protected:
  186. /// @brief Handles additional command line options that are supported
  187. /// by DStubController. This implementation supports an option "-x".
  188. ///
  189. /// @param option is the option "character" from the command line, without
  190. /// any prefixing hyphen(s)
  191. /// @optarg optarg is the argument value (if one) associated with the option
  192. ///
  193. /// @return returns true if the option is "x", otherwise ti returns false.
  194. virtual bool customOption(int option, char *optarg);
  195. /// @brief Instantiates an instance of DStubProcess.
  196. ///
  197. /// This implementation will fail if SimFailure is set to
  198. /// ftCreateProcessException OR ftCreateProcessNull.
  199. ///
  200. /// @return returns a pointer to the new process instance (DProcessBase*)
  201. /// or NULL if SimFailure is set to ftCreateProcessNull.
  202. /// @throw throws std::runtime_error if SimFailure is set to
  203. /// ftCreateProcessException.
  204. virtual DProcessBase* createProcess();
  205. /// @brief Executes custom controller commands are supported by
  206. /// DStubController. This implementation supports one custom controller
  207. /// command, stub_ctl_command_. It will fail if SimFailure is set
  208. /// to ftControllerCommand.
  209. ///
  210. /// @param command is a string label representing the command to execute.
  211. /// @param args is a set of arguments (if any) required for the given
  212. /// command.
  213. /// @return an Element that contains the results of command composed
  214. /// of an integer status value and a string explanation of the outcome.
  215. /// The status value is:
  216. /// COMMAND_SUCCESS if the command is recognized and executes successfully.
  217. /// COMMAND_ERROR if the command is recognized but fails to execute.
  218. /// COMMAND_INVALID if the command is not recognized.
  219. virtual isc::data::ConstElementPtr customControllerCommand(
  220. const std::string& command, isc::data::ConstElementPtr args);
  221. /// @brief Provides a string of the additional command line options
  222. /// supported by DStubController. DStubController supports one
  223. /// addition option, stub_option_x_.
  224. ///
  225. /// @return returns a string containing the option letters.
  226. virtual const std::string getCustomOpts() const;
  227. private:
  228. /// @brief Constructor is private to protect singleton integrity.
  229. DStubController();
  230. public:
  231. virtual ~DStubController();
  232. };
  233. /// @brief Abstract Test fixture class that wraps a DControllerBase. This class
  234. /// is a friend class of DControllerBase which allows it access to class
  235. /// content to facilitate testing. It provides numerous wrapper methods for
  236. /// the protected and private methods and member of the base class.
  237. class DControllerTest : public ::testing::Test {
  238. public:
  239. /// @brief Defines a function pointer for controller singleton fetchers.
  240. typedef DControllerBasePtr& (*InstanceGetter)();
  241. /// @brief Static storage of the controller class's singleton fetcher.
  242. /// We need this this statically available for callbacks.
  243. static InstanceGetter instanceGetter_;
  244. /// @brief Constructor
  245. ///
  246. /// @param instance_getter is a function pointer to the static instance
  247. /// method of the DControllerBase derivation under test.
  248. DControllerTest(InstanceGetter instance_getter) {
  249. // Set the static fetcher member, then invoke it via getController.
  250. // This ensures the singleton is instantiated.
  251. instanceGetter_ = instance_getter;
  252. getController();
  253. }
  254. /// @brief Destructor
  255. /// Note the controller singleton is destroyed. This is essential to ensure
  256. /// a clean start between tests.
  257. virtual ~DControllerTest() {
  258. getController().reset();
  259. static_cast<void>(unlink(CFG_TEST_FILE));
  260. }
  261. /// @brief Convenience method that destructs and then recreates the
  262. /// controller singleton under test. This is handy for tests within
  263. /// tests.
  264. void resetController() {
  265. getController().reset();
  266. getController();
  267. }
  268. /// @brief Static method which returns the instance of the controller
  269. /// under test.
  270. /// @return returns a reference to the controller instance.
  271. static DControllerBasePtr& getController() {
  272. return ((*instanceGetter_)());
  273. }
  274. /// @brief Returns true if the Controller's app name matches the
  275. /// given value.
  276. ///
  277. /// @param should_be is the value to compare against.
  278. ///
  279. /// @return returns true if the values are equal.
  280. bool checkAppName(const std::string& should_be) {
  281. return (getController()->getAppName().compare(should_be) == 0);
  282. }
  283. /// @brief Returns true if the Controller's service name matches the
  284. /// given value.
  285. ///
  286. /// @param should_be is the value to compare against.
  287. ///
  288. /// @return returns true if the values are equal.
  289. bool checkBinName(const std::string& should_be) {
  290. return (getController()->getBinName().compare(should_be) == 0);
  291. }
  292. /// @brief Returns true if the Controller's spec file name matches the
  293. /// given value.
  294. ///
  295. /// @param should_be is the value to compare against.
  296. ///
  297. /// @return returns true if the values are equal.
  298. bool checkSpecFileName(const std::string& should_be) {
  299. return (getController()->getSpecFileName().compare(should_be) == 0);
  300. }
  301. /// @brief Tests the existence of the Controller's application process.
  302. ///
  303. /// @return returns true if the process instance exists.
  304. bool checkProcess() {
  305. return (getController()->process_);
  306. }
  307. /// @brief Tests the existence of the Controller's IOService.
  308. ///
  309. /// @return returns true if the IOService exists.
  310. bool checkIOService() {
  311. return (getController()->io_service_);
  312. }
  313. /// @brief Gets the Controller's IOService.
  314. ///
  315. /// @return returns a reference to the IOService
  316. IOServicePtr& getIOService() {
  317. return (getController()->io_service_);
  318. }
  319. /// @brief Compares verbose flag with the given value.
  320. ///
  321. /// @param value
  322. ///
  323. /// @return returns true if the verbose flag is equal to the given value.
  324. bool checkVerbose(bool value) {
  325. return (getController()->isVerbose() == value);
  326. }
  327. /// @brief Compares configuration file name with the given value.
  328. ///
  329. /// @param value file name to compare against
  330. ///
  331. /// @return returns true if the verbose flag is equal to the given value.
  332. bool checkConfigFileName(const std::string& value) {
  333. return (getController()->getConfigFile() == value);
  334. }
  335. /// @Wrapper to invoke the Controller's parseArgs method. Please refer to
  336. /// DControllerBase::parseArgs for details.
  337. void parseArgs(int argc, char* argv[]) {
  338. getController()->parseArgs(argc, argv);
  339. }
  340. /// @Wrapper to invoke the Controller's init method. Please refer to
  341. /// DControllerBase::init for details.
  342. void initProcess() {
  343. getController()->initProcess();
  344. }
  345. /// @Wrapper to invoke the Controller's launch method. Please refer to
  346. /// DControllerBase::launch for details.
  347. void launch(int argc, char* argv[]) {
  348. optind = 1;
  349. getController()->launch(argc, argv, true);
  350. }
  351. /// @Wrapper to invoke the Controller's updateConfig method. Please
  352. /// refer to DControllerBase::updateConfig for details.
  353. isc::data::ConstElementPtr updateConfig(isc::data::ConstElementPtr
  354. new_config) {
  355. return (getController()->updateConfig(new_config));
  356. }
  357. /// @Wrapper to invoke the Controller's executeCommand method. Please
  358. /// refer to DControllerBase::executeCommand for details.
  359. isc::data::ConstElementPtr executeCommand(const std::string& command,
  360. isc::data::ConstElementPtr args){
  361. return (getController()->executeCommand(command, args));
  362. }
  363. /// @brief Callback that will generate shutdown command via the
  364. /// command callback function.
  365. static void genShutdownCallback() {
  366. isc::data::ElementPtr arg_set;
  367. getController()->executeCommand(SHUT_DOWN_COMMAND, arg_set);
  368. }
  369. /// @brief Callback that throws an exception.
  370. static void genFatalErrorCallback() {
  371. isc_throw (DProcessBaseError, "simulated fatal error");
  372. }
  373. /// @brief writes specified content to a well known file
  374. ///
  375. /// Writes given JSON content to CFG_TEST_FILE. It will wrap the
  376. /// content within a JSON element whose name is equal to the controller's
  377. /// app name or the given module name if not blank:
  378. ///
  379. /// @code
  380. /// { "<app_name>" : <content> }
  381. /// @endcod
  382. ///
  383. /// suffix the content within a JSON element with the given module
  384. /// name or wrapped by a JSON
  385. /// element . Tests will
  386. /// attempt to read that file.
  387. ///
  388. /// @param content JSON text to be written to file
  389. /// @param module_name content content to be written to file
  390. void writeFile(const std::string& content,
  391. const std::string& module_name = "") {
  392. std::ofstream out(CFG_TEST_FILE, std::ios::trunc);
  393. ASSERT_TRUE(out.is_open());
  394. out << "{ \"" << (!module_name.empty() ? module_name :
  395. getController()->getAppName())
  396. << "\": " << std::endl;
  397. out << content;
  398. out << " } " << std::endl;
  399. out.close();
  400. }
  401. /// Name of a config file used during tests
  402. static const char* CFG_TEST_FILE;
  403. };
  404. /// @brief a collection of elements that store uint32 values
  405. typedef isc::dhcp::ValueStorage<isc::data::ConstElementPtr> ObjectStorage;
  406. typedef boost::shared_ptr<ObjectStorage> ObjectStoragePtr;
  407. /// @brief Simple parser derivation for parsing object elements.
  408. class ObjectParser : public isc::dhcp::DhcpConfigParser {
  409. public:
  410. /// @brief Constructor
  411. ///
  412. /// See @ref DhcpConfigParser class for details.
  413. ///
  414. /// @param param_name name of the parsed parameter
  415. ObjectParser(const std::string& param_name, ObjectStoragePtr& object_values);
  416. /// @brief Destructor
  417. virtual ~ObjectParser();
  418. /// @brief Builds parameter value.
  419. ///
  420. /// See @ref DhcpConfigParser class for details.
  421. ///
  422. /// @param new_config pointer to the new configuration
  423. /// @throw throws DCfgMgrBaseError if the SimFailure is set to
  424. /// ftElementBuild. This allows for the simulation of an
  425. /// exception during the build portion of parsing an element.
  426. virtual void build(isc::data::ConstElementPtr new_config);
  427. /// @brief Commits the parsed value to storage.
  428. ///
  429. /// See @ref DhcpConfigParser class for details.
  430. ///
  431. /// @throw throws DCfgMgrBaseError if SimFailure is set to ftElementCommit.
  432. /// This allows for the simulation of an exception during the commit
  433. /// portion of parsing an element.
  434. virtual void commit();
  435. private:
  436. /// name of the parsed parameter
  437. std::string param_name_;
  438. /// pointer to the parsed value of the parameter
  439. isc::data::ConstElementPtr value_;
  440. /// Pointer to the storage where committed value is stored.
  441. ObjectStoragePtr object_values_;
  442. };
  443. /// @brief Test Derivation of the DCfgContextBase class.
  444. ///
  445. /// This class is used to test basic functionality of configuration context.
  446. /// It adds an additional storage container "extra values" to mimic an
  447. /// application extension of configuration storage. This permits testing that
  448. /// both the base class content as well as the application content is
  449. /// correctly copied during cloning. This is vital to configuration backup
  450. /// and rollback during configuration parsing.
  451. class DStubContext : public DCfgContextBase {
  452. public:
  453. /// @brief Constructor
  454. DStubContext();
  455. /// @brief Destructor
  456. virtual ~DStubContext();
  457. /// @brief Creates a clone of a DStubContext.
  458. ///
  459. /// @return returns a pointer to the new clone.
  460. virtual DCfgContextBasePtr clone();
  461. /// @brief Fetches the value for a given "extra" configuration parameter
  462. /// from the context.
  463. ///
  464. /// @param name is the name of the parameter to retrieve.
  465. /// @param value is an output parameter in which to return the retrieved
  466. /// value.
  467. /// @throw throws DhcpConfigError if the context does not contain the
  468. /// parameter.
  469. void getObjectParam(const std::string& name,
  470. isc::data::ConstElementPtr& value);
  471. ObjectStoragePtr& getObjectStorage();
  472. protected:
  473. /// @brief Copy constructor
  474. DStubContext(const DStubContext& rhs);
  475. private:
  476. /// @brief Private assignment operator, not implemented.
  477. DStubContext& operator=(const DStubContext& rhs);
  478. /// @brief Stores non-scalar configuration elements
  479. ObjectStoragePtr object_values_;
  480. };
  481. /// @brief Defines a pointer to DStubContext.
  482. typedef boost::shared_ptr<DStubContext> DStubContextPtr;
  483. /// @brief Test Derivation of the DCfgMgrBase class.
  484. ///
  485. /// This class is used to test basic functionality of configuration management.
  486. /// It supports the following configuration elements:
  487. ///
  488. /// "bool_test" - Boolean element, tests parsing and committing a boolean
  489. /// configuration parameter.
  490. /// "uint32_test" - Uint32 element, tests parsing and committing a uint32_t
  491. /// configuration parameter.
  492. /// "string_test" - String element, tests parsing and committing a string
  493. /// configuration parameter.
  494. /// "extra_test" - "Extra" element, tests parsing and committing an extra
  495. /// configuration parameter. (This is used to demonstrate
  496. /// derivation's addition of storage to configuration context.
  497. ///
  498. /// It also keeps track of the element ids that are parsed in the order they
  499. /// are parsed. This is used to test ordered and non-ordered parsing.
  500. class DStubCfgMgr : public DCfgMgrBase {
  501. public:
  502. /// @brief Constructor
  503. DStubCfgMgr();
  504. /// @brief Destructor
  505. virtual ~DStubCfgMgr();
  506. /// @brief Given an element_id returns an instance of the appropriate
  507. /// parser. It supports the element ids as described in the class brief.
  508. ///
  509. /// @param element_id is the string name of the element as it will appear
  510. /// in the configuration set.
  511. ///
  512. /// @return returns a ParserPtr to the parser instance.
  513. /// @throw throws DCfgMgrBaseError if SimFailure is ftElementUnknown.
  514. virtual isc::dhcp::ParserPtr
  515. createConfigParser(const std::string& element_id);
  516. /// @brief A list for remembering the element ids in the order they were
  517. /// parsed.
  518. ElementIdList parsed_order_;
  519. /// @todo
  520. virtual DCfgContextBasePtr createNewContext();
  521. };
  522. /// @brief Defines a pointer to DStubCfgMgr.
  523. typedef boost::shared_ptr<DStubCfgMgr> DStubCfgMgrPtr;
  524. /// @brief Test fixture base class for any fixtures which test parsing.
  525. /// It provides methods for converting JSON strings to configuration element
  526. /// sets and checking parse results
  527. class ConfigParseTest : public ::testing::Test {
  528. public:
  529. /// @brief Constructor
  530. ConfigParseTest(){
  531. }
  532. /// @brief Destructor
  533. ~ConfigParseTest() {
  534. }
  535. /// @brief Converts a given JSON string into an Element set and stores the
  536. /// result the member variable, config_set_.
  537. ///
  538. /// @param json_text contains the configuration text in JSON format to
  539. /// convert.
  540. /// @return returns AssertionSuccess if there were no parsing errors,
  541. /// AssertionFailure otherwise.
  542. ::testing::AssertionResult fromJSON(const std::string& json_text) {
  543. try {
  544. config_set_ = isc::data::Element::fromJSON(json_text);
  545. } catch (const isc::Exception &ex) {
  546. return (::testing::AssertionFailure(::testing::Message() <<
  547. "JSON text failed to parse:"
  548. << ex.what()));
  549. }
  550. return (::testing::AssertionSuccess());
  551. }
  552. /// @brief Compares the status in the parse result stored in member
  553. /// variable answer_ to a given value.
  554. ///
  555. /// @param should_be is an integer against which to compare the status.
  556. ///
  557. /// @return returns AssertionSuccess if there were no parsing errors,
  558. /// AssertionFailure otherwise.
  559. ::testing::AssertionResult checkAnswer(int should_be) {
  560. return (checkAnswer(answer_, should_be));
  561. }
  562. /// @brief Compares the status in the given parse result to a given value.
  563. ///
  564. /// @param answer Element set containing an integer response and string
  565. /// comment.
  566. /// @param should_be is an integer against which to compare the status.
  567. ///
  568. /// @return returns AssertionSuccess if there were no parsing errors,
  569. /// AssertionFailure otherwise.
  570. ::testing::AssertionResult checkAnswer(isc::data::ConstElementPtr answer,
  571. int should_be) {
  572. int rcode = 0;
  573. isc::data::ConstElementPtr comment;
  574. comment = isc::config::parseAnswer(rcode, answer);
  575. if (rcode == should_be) {
  576. return (testing::AssertionSuccess());
  577. }
  578. return (::testing::AssertionFailure(::testing::Message() <<
  579. "checkAnswer rcode:" << rcode
  580. << " comment: " << *comment));
  581. }
  582. /// @brief Configuration set being tested.
  583. isc::data::ElementPtr config_set_;
  584. /// @brief Results of most recent element parsing.
  585. isc::data::ConstElementPtr answer_;
  586. };
  587. /// @brief Defines a small but valid DHCP-DDNS compliant configuration for
  588. /// testing configuration parsing fundamentals.
  589. extern const char* valid_d2_config;
  590. }; // namespace isc::d2
  591. }; // namespace isc
  592. #endif