factory_unittest.cc 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240
  1. // Copyright (C) 2011 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 <boost/scoped_ptr.hpp>
  15. #include <datasrc/datasrc_config.h>
  16. #include <datasrc/factory.h>
  17. #include <datasrc/data_source.h>
  18. #include <datasrc/sqlite3_accessor.h>
  19. #include <dns/rrclass.h>
  20. #include <cc/data.h>
  21. #include <gtest/gtest.h>
  22. using namespace isc::datasrc;
  23. using namespace isc::data;
  24. std::string SQLITE_DBFILE_EXAMPLE_ORG = TEST_DATA_DIR "/example.org.sqlite3";
  25. namespace {
  26. // note this helper only checks the error that is received up to the length
  27. // of the expected string. It will always pass if you give it an empty
  28. // expected_error
  29. void
  30. pathtestHelper(const std::string& file, const std::string& expected_error) {
  31. std::string error;
  32. try {
  33. DataSourceClientContainer(file, ElementPtr());
  34. } catch (const DataSourceLibraryError& dsle) {
  35. error = dsle.what();
  36. }
  37. ASSERT_LT(expected_error.size(), error.size());
  38. EXPECT_EQ(expected_error, error.substr(0, expected_error.size()));
  39. }
  40. TEST(FactoryTest, paths) {
  41. // Test whether the paths are made absolute if they are not,
  42. // by inspecting the error that is raised when they are wrong
  43. const std::string error("dlopen failed for ");
  44. // With the current implementation, we can safely assume this has
  45. // been set for this test (as the loader would otherwise also fail
  46. // unless the loadable backend library happens to be installed)
  47. const std::string builddir(getenv("B10_FROM_BUILD"));
  48. // Absolute and ending with .so should have no change
  49. pathtestHelper("/no_such_file.so", error + "/no_such_file.so");
  50. // If no ending in .so, it should get _ds.so
  51. pathtestHelper("/no_such_file", error + "/no_such_file_ds.so");
  52. // If not starting with /, path should be added. For this test that
  53. // means the build directory as set in B10_FROM_BUILD
  54. pathtestHelper("no_such_file.so", error + builddir +
  55. "/src/lib/datasrc/.libs/no_such_file.so");
  56. pathtestHelper("no_such_file", error + builddir +
  57. "/src/lib/datasrc/.libs/no_such_file_ds.so");
  58. // Some tests with '.so' in the name itself
  59. pathtestHelper("no_such_file.so.something", error + builddir +
  60. "/src/lib/datasrc/.libs/no_such_file.so.something_ds.so");
  61. pathtestHelper("/no_such_file.so.something", error +
  62. "/no_such_file.so.something_ds.so");
  63. pathtestHelper("/no_such_file.so.something.so", error +
  64. "/no_such_file.so.something.so");
  65. pathtestHelper("/no_such_file.so.so", error +
  66. "/no_such_file.so.so");
  67. pathtestHelper("no_such_file.so.something", error + builddir +
  68. "/src/lib/datasrc/.libs/no_such_file.so.something_ds.so");
  69. // Temporarily unset B10_FROM_BUILD to see that BACKEND_LIBRARY_PATH
  70. // is used
  71. unsetenv("B10_FROM_BUILD");
  72. pathtestHelper("no_such_file.so", error + BACKEND_LIBRARY_PATH +
  73. "no_such_file.so");
  74. // Put it back just in case
  75. setenv("B10_FROM_BUILD", builddir.c_str(), 1);
  76. // Test some bad input values
  77. ASSERT_THROW(DataSourceClientContainer("", ElementPtr()),
  78. DataSourceLibraryError);
  79. ASSERT_THROW(DataSourceClientContainer(".so", ElementPtr()),
  80. DataSourceLibraryError);
  81. }
  82. TEST(FactoryTest, sqlite3ClientBadConfig) {
  83. // We start out by building the configuration data bit by bit,
  84. // testing each form of 'bad config', until we have a good one.
  85. // Then we do some very basic operation on the client (detailed
  86. // tests are left to the implementation-specific backends)
  87. ElementPtr config;
  88. ASSERT_THROW(DataSourceClientContainer("sqlite3", config),
  89. DataSourceError);
  90. config = Element::create("asdf");
  91. ASSERT_THROW(DataSourceClientContainer("sqlite3", config),
  92. DataSourceError);
  93. config = Element::createMap();
  94. ASSERT_THROW(DataSourceClientContainer("sqlite3", config),
  95. DataSourceError);
  96. config->set("class", ElementPtr());
  97. ASSERT_THROW(DataSourceClientContainer("sqlite3", config),
  98. DataSourceError);
  99. config->set("class", Element::create(1));
  100. ASSERT_THROW(DataSourceClientContainer("sqlite3", config),
  101. DataSourceError);
  102. config->set("class", Element::create("FOO"));
  103. ASSERT_THROW(DataSourceClientContainer("sqlite3", config),
  104. DataSourceError);
  105. config->set("class", Element::create("IN"));
  106. ASSERT_THROW(DataSourceClientContainer("sqlite3", config),
  107. DataSourceError);
  108. config->set("database_file", ElementPtr());
  109. ASSERT_THROW(DataSourceClientContainer("sqlite3", config),
  110. DataSourceError);
  111. config->set("database_file", Element::create(1));
  112. ASSERT_THROW(DataSourceClientContainer("sqlite3", config),
  113. DataSourceError);
  114. config->set("database_file", Element::create("/foo/bar/doesnotexist"));
  115. ASSERT_THROW(DataSourceClientContainer("sqlite3", config),
  116. DataSourceError);
  117. config->set("database_file", Element::create(SQLITE_DBFILE_EXAMPLE_ORG));
  118. DataSourceClientContainer dsc("sqlite3", config);
  119. DataSourceClient::FindResult result1(
  120. dsc.getInstance().findZone(isc::dns::Name("example.org.")));
  121. ASSERT_EQ(result::SUCCESS, result1.code);
  122. DataSourceClient::FindResult result2(
  123. dsc.getInstance().findZone(isc::dns::Name("no.such.zone.")));
  124. ASSERT_EQ(result::NOTFOUND, result2.code);
  125. ZoneIteratorPtr iterator(dsc.getInstance().getIterator(
  126. isc::dns::Name("example.org.")));
  127. ZoneUpdaterPtr updater(dsc.getInstance().getUpdater(
  128. isc::dns::Name("example.org."), false));
  129. }
  130. TEST(FactoryTest, memoryClient) {
  131. // We start out by building the configuration data bit by bit,
  132. // testing each form of 'bad config', until we have a good one.
  133. // Then we do some very basic operation on the client (detailed
  134. // tests are left to the implementation-specific backends)
  135. ElementPtr config;
  136. ASSERT_THROW(DataSourceClientContainer client("memory", config),
  137. DataSourceError);
  138. config = Element::create("asdf");
  139. ASSERT_THROW(DataSourceClientContainer("memory", config),
  140. DataSourceError);
  141. config = Element::createMap();
  142. ASSERT_THROW(DataSourceClientContainer("memory", config),
  143. DataSourceError);
  144. config->set("type", ElementPtr());
  145. ASSERT_THROW(DataSourceClientContainer("memory", config),
  146. DataSourceError);
  147. config->set("type", Element::create(1));
  148. ASSERT_THROW(DataSourceClientContainer("memory", config),
  149. DataSourceError);
  150. config->set("type", Element::create("FOO"));
  151. ASSERT_THROW(DataSourceClientContainer("memory", config),
  152. DataSourceError);
  153. config->set("type", Element::create("memory"));
  154. ASSERT_THROW(DataSourceClientContainer("memory", config),
  155. DataSourceError);
  156. config->set("class", ElementPtr());
  157. ASSERT_THROW(DataSourceClientContainer("memory", config),
  158. DataSourceError);
  159. config->set("class", Element::create(1));
  160. ASSERT_THROW(DataSourceClientContainer("memory", config),
  161. DataSourceError);
  162. config->set("class", Element::create("FOO"));
  163. ASSERT_THROW(DataSourceClientContainer("memory", config),
  164. DataSourceError);
  165. config->set("class", Element::create("IN"));
  166. ASSERT_THROW(DataSourceClientContainer("memory", config),
  167. DataSourceError);
  168. config->set("zones", ElementPtr());
  169. ASSERT_THROW(DataSourceClientContainer("memory", config),
  170. DataSourceError);
  171. config->set("zones", Element::create(1));
  172. ASSERT_THROW(DataSourceClientContainer("memory", config),
  173. DataSourceError);
  174. config->set("zones", Element::createList());
  175. DataSourceClientContainer dsc("memory", config);
  176. // Once it is able to load some zones, we should add a few tests
  177. // here to see that it does.
  178. DataSourceClient::FindResult result(
  179. dsc.getInstance().findZone(isc::dns::Name("no.such.zone.")));
  180. ASSERT_EQ(result::NOTFOUND, result.code);
  181. ASSERT_THROW(dsc.getInstance().getIterator(isc::dns::Name("example.org.")),
  182. DataSourceError);
  183. ASSERT_THROW(dsc.getInstance().getUpdater(isc::dns::Name("no.such.zone."),
  184. false), isc::NotImplemented);
  185. }
  186. TEST(FactoryTest, badType) {
  187. ASSERT_THROW(DataSourceClientContainer("foo", ElementPtr()),
  188. DataSourceError);
  189. }
  190. } // end anonymous namespace