module_spec_unittests.cc 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. // Copyright (C) 2009 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. // $Id$
  15. #include <gtest/gtest.h>
  16. #include <config/module_spec.h>
  17. #include <fstream>
  18. #include <config/tests/data_def_unittests_config.h>
  19. using namespace isc::data;
  20. using namespace isc::config;
  21. std::string specfile(const std::string name) {
  22. return std::string(TEST_DATA_PATH) + "/" + name;
  23. }
  24. void
  25. module_spec_error(const std::string& file,
  26. const std::string& error1,
  27. const std::string& error2 = "",
  28. const std::string& error3 = "")
  29. {
  30. EXPECT_THROW(moduleSpecFromFile(specfile(file)), ModuleSpecError);
  31. try {
  32. ModuleSpec dd = moduleSpecFromFile(specfile(file));
  33. } catch (ModuleSpecError dde) {
  34. std::string ddew = dde.what();
  35. EXPECT_EQ(error1 + error2 + error3, ddew);
  36. }
  37. }
  38. TEST(ModuleSpec, ReadingSpecfiles) {
  39. // Tests whether we can open specfiles and if we get the
  40. // right parse errors
  41. ModuleSpec dd = moduleSpecFromFile(specfile("spec1.spec"));
  42. EXPECT_EQ(dd.getFullSpec()->get("module_name")
  43. ->stringValue(), "Spec1");
  44. dd = moduleSpecFromFile(specfile("spec2.spec"));
  45. EXPECT_EQ(dd.getFullSpec()->get("config_data")->size(), 6);
  46. module_spec_error("doesnotexist",
  47. "Error opening ",
  48. specfile("doesnotexist"),
  49. ": No such file or directory");
  50. dd = moduleSpecFromFile(specfile("spec2.spec"));
  51. EXPECT_EQ("[ { \"command_args\": [ { \"item_default\": \"\", \"item_name\": \"message\", \"item_optional\": false, \"item_type\": \"string\" } ], \"command_description\": \"Print the given message to stdout\", \"command_name\": \"print_message\" }, { \"command_args\": [ ], \"command_description\": \"Shut down BIND 10\", \"command_name\": \"shutdown\" } ]", dd.getCommandsSpec()->str());
  52. EXPECT_EQ("Spec2", dd.getModuleName());
  53. EXPECT_EQ("", dd.getModuleDescription());
  54. dd = moduleSpecFromFile(specfile("spec25.spec"));
  55. EXPECT_EQ("Spec25", dd.getModuleName());
  56. EXPECT_EQ("Just an empty module", dd.getModuleDescription());
  57. EXPECT_THROW(moduleSpecFromFile(specfile("spec26.spec")), ModuleSpecError);
  58. std::ifstream file;
  59. file.open(specfile("spec1.spec").c_str());
  60. dd = moduleSpecFromFile(file);
  61. EXPECT_EQ(dd.getFullSpec()->get("module_name")
  62. ->stringValue(), "Spec1");
  63. EXPECT_TRUE(isNull(dd.getCommandsSpec()));
  64. std::ifstream file2;
  65. file2.open(specfile("spec8.spec").c_str());
  66. EXPECT_THROW(moduleSpecFromFile(file2), ModuleSpecError);
  67. }
  68. TEST(ModuleSpec, SpecfileItems) {
  69. module_spec_error("spec3.spec",
  70. "item_name missing in { \"item_default\": 1, \"item_optional\": false, \"item_type\": \"integer\" }");
  71. module_spec_error("spec4.spec",
  72. "item_type missing in { \"item_default\": 1, \"item_name\": \"item1\", \"item_optional\": false }");
  73. module_spec_error("spec5.spec",
  74. "item_optional missing in { \"item_default\": 1, \"item_name\": \"item1\", \"item_type\": \"integer\" }");
  75. module_spec_error("spec6.spec",
  76. "item_default missing in { \"item_name\": \"item1\", \"item_optional\": false, \"item_type\": \"integer\" }");
  77. module_spec_error("spec9.spec",
  78. "item_default not of type integer");
  79. module_spec_error("spec10.spec",
  80. "item_default not of type real");
  81. module_spec_error("spec11.spec",
  82. "item_default not of type boolean");
  83. module_spec_error("spec12.spec",
  84. "item_default not of type string");
  85. module_spec_error("spec13.spec",
  86. "item_default not of type list");
  87. module_spec_error("spec14.spec",
  88. "item_default not of type map");
  89. module_spec_error("spec15.spec",
  90. "badname is not a valid type name");
  91. }
  92. TEST(ModuleSpec, SpecfileConfigData)
  93. {
  94. module_spec_error("spec7.spec",
  95. "module_name missing in { }");
  96. module_spec_error("spec8.spec",
  97. "No module_spec in specification");
  98. module_spec_error("spec16.spec",
  99. "config_data is not a list of elements");
  100. module_spec_error("spec21.spec",
  101. "commands is not a list of elements");
  102. }
  103. TEST(ModuleSpec, SpecfileCommands)
  104. {
  105. module_spec_error("spec17.spec",
  106. "command_name missing in { \"command_args\": [ { \"item_default\": \"\", \"item_name\": \"message\", \"item_optional\": false, \"item_type\": \"string\" } ], \"command_description\": \"Print the given message to stdout\" }");
  107. module_spec_error("spec18.spec",
  108. "command_args missing in { \"command_description\": \"Print the given message to stdout\", \"command_name\": \"print_message\" }");
  109. module_spec_error("spec19.spec",
  110. "command_args not of type list");
  111. module_spec_error("spec20.spec",
  112. "somethingbad is not a valid type name");
  113. /*
  114. module_spec_error("spec22.spec",
  115. "");
  116. */
  117. }
  118. bool
  119. data_test(ModuleSpec dd, const std::string& data_file_name)
  120. {
  121. std::ifstream data_file;
  122. data_file.open(specfile(data_file_name).c_str());
  123. ElementPtr data = Element::fromJSON(data_file, data_file_name);
  124. data_file.close();
  125. return dd.validate_config(data);
  126. }
  127. bool
  128. data_test_with_errors(ModuleSpec dd, const std::string& data_file_name, ElementPtr errors)
  129. {
  130. std::ifstream data_file;
  131. data_file.open(specfile(data_file_name).c_str());
  132. ElementPtr data = Element::fromJSON(data_file, data_file_name);
  133. data_file.close();
  134. return dd.validate_config(data, true, errors);
  135. }
  136. TEST(ModuleSpec, DataValidation) {
  137. ModuleSpec dd = moduleSpecFromFile(specfile("spec22.spec"));
  138. EXPECT_TRUE(data_test(dd, "data22_1.data"));
  139. EXPECT_FALSE(data_test(dd, "data22_2.data"));
  140. EXPECT_FALSE(data_test(dd, "data22_3.data"));
  141. EXPECT_FALSE(data_test(dd, "data22_4.data"));
  142. EXPECT_FALSE(data_test(dd, "data22_5.data"));
  143. EXPECT_TRUE(data_test(dd, "data22_6.data"));
  144. EXPECT_TRUE(data_test(dd, "data22_7.data"));
  145. EXPECT_FALSE(data_test(dd, "data22_8.data"));
  146. ElementPtr errors = Element::createList();
  147. EXPECT_FALSE(data_test_with_errors(dd, "data22_8.data", errors));
  148. EXPECT_EQ("[ \"Type mismatch\" ]", errors->str());
  149. }