d_test_stubs.h 24 KB

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