data_unittests.cc 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278
  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 <boost/foreach.hpp>
  17. #include <boost/assign/std/vector.hpp>
  18. #include <data.h>
  19. using namespace isc::data;
  20. #include <iostream>
  21. using std::oct;
  22. #include <iomanip>
  23. using std::setfill;
  24. using std::setw;
  25. TEST(Element, type) {
  26. // this tests checks whether the getType() function returns the
  27. // correct type
  28. IntElement int_el = IntElement(1);
  29. EXPECT_EQ(int_el.getType(), Element::integer);
  30. DoubleElement double_el = DoubleElement(1.0);
  31. EXPECT_EQ(double_el.getType(), Element::real);
  32. BoolElement bool_el = BoolElement(true);
  33. EXPECT_EQ(bool_el.getType(), Element::boolean);
  34. StringElement str_el = StringElement("foo");
  35. EXPECT_EQ(str_el.getType(), Element::string);
  36. std::vector<ElementPtr> v;
  37. ListElement list_el = ListElement(v);
  38. EXPECT_EQ(list_el.getType(), Element::list);
  39. std::map<std::string, ElementPtr> m;
  40. MapElement map_el = MapElement(m);
  41. EXPECT_EQ(map_el.getType(), Element::map);
  42. }
  43. TEST(Element, from_and_to_str) {
  44. // this test checks whether the str() method returns the same
  45. // string that was used for creation
  46. ElementPtr el;
  47. std::vector<std::string> sv;
  48. sv.push_back("12");
  49. sv.push_back("1.1");
  50. sv.push_back("True");
  51. sv.push_back("False");
  52. sv.push_back("\"asdf\"");
  53. sv.push_back("[ 1, 2, 3, 4 ]");
  54. sv.push_back("{\"name\": \"foo\", \"value\": 47806}");
  55. sv.push_back("[ {\"a\": 1, \"b\": \"c\"}, {\"a\": 2, \"b\": \"d\"} ]");
  56. BOOST_FOREACH(std::string s, sv) {
  57. // also test << operator, which uses Element::str()
  58. std::ostringstream stream;
  59. el = Element::createFromString(s);
  60. stream << el;
  61. EXPECT_EQ(stream.str(), s);
  62. }
  63. // some parse errors
  64. try {
  65. Element::createFromString("{1}");
  66. } catch (isc::data::ParseError pe) {
  67. std::string s = std::string(pe.what());
  68. EXPECT_EQ(s, "String expected in <string>:1:3");
  69. }
  70. sv.clear();
  71. sv.push_back("{1}");
  72. //ElementPtr ep = Element::createFromString("\"aaa\nbbb\"err");
  73. //std::cout << ep << std::endl;
  74. sv.push_back("\n\nTru");
  75. sv.push_back("{ \n \"aaa\nbbb\"err:");
  76. sv.push_back("{ \t\n \"aaa\nbbb\"\t\n\n:\n True, \"\\\"");
  77. sv.push_back("{ \"a\": None}");
  78. sv.push_back("");
  79. BOOST_FOREACH(std::string s, sv) {
  80. EXPECT_THROW(el = Element::createFromString(s), isc::data::ParseError);
  81. }
  82. }
  83. TEST(Element, create_and_value_throws) {
  84. // this test checks whether elements throw exceptions if the
  85. // incorrect type is requested
  86. ElementPtr el;
  87. el = Element::create(1);
  88. EXPECT_THROW(el->doubleValue(), TypeError);
  89. EXPECT_THROW(el->boolValue(), TypeError);
  90. EXPECT_THROW(el->stringValue(), TypeError);
  91. EXPECT_THROW(el->listValue(), TypeError);
  92. EXPECT_THROW(el->mapValue(), TypeError);
  93. el = Element::create(1.1);
  94. EXPECT_THROW(el->intValue(), TypeError);
  95. EXPECT_THROW(el->boolValue(), TypeError);
  96. EXPECT_THROW(el->stringValue(), TypeError);
  97. EXPECT_THROW(el->listValue(), TypeError);
  98. EXPECT_THROW(el->mapValue(), TypeError);
  99. el = Element::create(true);
  100. EXPECT_THROW(el->intValue(), TypeError);
  101. EXPECT_THROW(el->doubleValue(), TypeError);
  102. EXPECT_THROW(el->stringValue(), TypeError);
  103. EXPECT_THROW(el->listValue(), TypeError);
  104. EXPECT_THROW(el->mapValue(), TypeError);
  105. el = Element::create("foo");
  106. EXPECT_THROW(el->intValue(), TypeError);
  107. EXPECT_THROW(el->doubleValue(), TypeError);
  108. EXPECT_THROW(el->boolValue(), TypeError);
  109. EXPECT_THROW(el->listValue(), TypeError);
  110. EXPECT_THROW(el->mapValue(), TypeError);
  111. std::vector<ElementPtr> v;
  112. el = Element::create(v);
  113. EXPECT_THROW(el->intValue(), TypeError);
  114. EXPECT_THROW(el->doubleValue(), TypeError);
  115. EXPECT_THROW(el->boolValue(), TypeError);
  116. EXPECT_THROW(el->stringValue(), TypeError);
  117. EXPECT_THROW(el->mapValue(), TypeError);
  118. std::map<std::string, ElementPtr> m;
  119. el = Element::create(m);
  120. EXPECT_THROW(el->intValue(), TypeError);
  121. EXPECT_THROW(el->doubleValue(), TypeError);
  122. EXPECT_THROW(el->boolValue(), TypeError);
  123. EXPECT_THROW(el->stringValue(), TypeError);
  124. EXPECT_THROW(el->listValue(), TypeError);
  125. }
  126. TEST(Element, ListElement) {
  127. // this function checks the specific functions for ListElements
  128. ElementPtr el = Element::createFromString("[ 1, \"bar\", 3 ]");
  129. EXPECT_EQ(el->get(0)->intValue(), 1);
  130. EXPECT_EQ(el->get(1)->stringValue(), "bar");
  131. EXPECT_EQ(el->get(2)->intValue(), 3);
  132. el->set(0, Element::createFromString("\"foo\""));
  133. EXPECT_EQ(el->get(0)->stringValue(), "foo");
  134. el->add(Element::create(47806));
  135. EXPECT_EQ(el->get(3)->intValue(), 47806);
  136. el->remove(1);
  137. el->remove(1);
  138. EXPECT_EQ(el->str(), "[ \"foo\", 47806 ]");
  139. // hmm, it errors on EXPECT_THROW(el->get(3), std::out_of_range)
  140. EXPECT_ANY_THROW(el->get(3));
  141. el->add(Element::create(32));
  142. EXPECT_EQ(el->get(2)->intValue(), 32);
  143. }
  144. TEST(Element, MapElement) {
  145. // this function checks the specific functions for ListElements
  146. ElementPtr el = Element::createFromString("{ \"name\": \"foo\", \"value1\": \"bar\", \"value2\": { \"number\": 42 } }");
  147. ElementPtr el2;
  148. EXPECT_EQ(el->get("name")->stringValue(), "foo");
  149. EXPECT_EQ(el->get("value2")->getType(), Element::map);
  150. EXPECT_TRUE(isNull(el->get("value3")));
  151. el->set("value3", Element::create(47806));
  152. EXPECT_EQ(el->get("value3")->intValue(), 47806);
  153. el->remove("value3");
  154. EXPECT_TRUE(isNull(el->get("value3")));
  155. EXPECT_EQ(el->find("value2/number")->intValue(), 42);
  156. EXPECT_TRUE(isNull(el->find("value2/nothing/")));
  157. EXPECT_EQ(el->find("value1")->stringValue(), "bar");
  158. EXPECT_EQ(el->find("value1/")->stringValue(), "bar");
  159. EXPECT_TRUE(el->find("value1", el2));
  160. EXPECT_FALSE(el->find("name/error", el2));
  161. }
  162. TEST(Element, to_and_from_wire) {
  163. ElementPtr el, decoded_el;
  164. std::string wire;
  165. std::vector<std::string> sv;
  166. std::vector<std::string> sw;
  167. std::stringstream bigstring, bigstring2;
  168. std::stringstream bigwire, bigwire2;
  169. sv.push_back("{\"name\": \"foo\"}");
  170. sw.push_back("Skan\004name\050\003foo");
  171. sv.push_back("{\"value2\": {\"number\": 42}}");
  172. sw.push_back("Skan\006value2\042\013\006number\046\00242");
  173. sv.push_back("{\"bool\": False, \"bool2\": True, \"real\": 2.34, \"string\": \"foo\"}");
  174. sw.push_back("Skan\004bool\045\0010\005bool2\045\0011\004real\047\0042\05634\006string\050\003foo");
  175. sv.push_back("{\"list\": [ 1, 2, 3, 4 ]}");
  176. sw.push_back("Skan\004list\043\014\046\0011\046\0012\046\0013\046\0014");
  177. // some big ones
  178. bigstring << "{\"bigstring\": \"";
  179. bigwire << "Skan\011bigstring\030\001\001";
  180. for (size_t i = 0; i < 257; i++) {
  181. bigstring << "x";
  182. bigwire << "x";
  183. }
  184. bigstring << "\"}";
  185. sv.push_back(bigstring.str());
  186. sw.push_back(bigwire.str());
  187. bigstring2 << "{\"bigstring2\": \"";
  188. bigwire2 << "Skan\012bigstring2\010";
  189. bigwire2 << '\000' << '\001' << '\000' << '\001';
  190. for (size_t i = 0; i < 65537; i++) {
  191. bigstring2 << "x";
  192. bigwire2 << "x";
  193. }
  194. bigstring2 << "\"}";
  195. sv.push_back(bigstring2.str());
  196. sw.push_back(bigwire2.str());
  197. BOOST_FOREACH(std::string s, sv) {
  198. // also test << operator, which uses Element::str()
  199. el = Element::createFromString(s);
  200. EXPECT_EQ(s, el->str());
  201. wire = el->toWire();
  202. /*
  203. std::cout << "Encoded wire format:" << std::endl;
  204. my_print(wire);
  205. std::cout << "Expecting:" << std::endl;
  206. my_print(sw.at(0));
  207. */
  208. EXPECT_EQ(sw.at(0), wire);
  209. sw.erase(sw.begin());
  210. decoded_el = Element::fromWire(wire);
  211. EXPECT_EQ(s, decoded_el->str());
  212. }
  213. //EXPECT_THROW(Element::fromWire("Skan\004name\050\003foo"), DecodeError);
  214. EXPECT_THROW(Element::fromWire("Skan\004name\050"), DecodeError);
  215. EXPECT_THROW(Element::fromWire("Skan\004na"), DecodeError);
  216. EXPECT_THROW(Element::fromWire("Skan\004name\050\003fo"), DecodeError);
  217. EXPECT_NO_THROW(Element::fromWire("Skan\004name\041\003foo"));
  218. EXPECT_THROW(Element::fromWire("Skan\004name\041\003fo"), DecodeError);
  219. EXPECT_NO_THROW(Element::fromWire("Skan\004name\044\001a"));
  220. EXPECT_THROW(Element::fromWire("Skab\004name\050\003foo"), DecodeError);
  221. //EXPECT_EQ("\047\0031.2", Element::create(1.2)->toWire(0));
  222. EXPECT_EQ("\046\0011", Element::createFromString("[ 1 ]")->toWire(1));
  223. std::string ddef = "{\"data_specification\": {\"config_data\": [ {\"item_default\": \"Hello, world!\", \"item_name\": \"default_name\", \"item_optional\": False, \"item_type\": \"string\"}, {\"item_default\": [ ], \"item_name\": \"zone_list\", \"item_optional\": False, \"item_type\": \"list\", \"list_item_spec\": {\"item_name\": \"zone_name\", \"item_optional\": True, \"item_type\": \"string\"}} ], \"module_name\": \"Auth\"}}";
  224. //std::string ddef = "{\"aaa\": 123, \"test\": [ ], \"zzz\": 123}";
  225. ElementPtr ddef_el = Element::createFromString(ddef);
  226. std::string ddef_wire = ddef_el->toWire();
  227. ElementPtr ddef_el2 = Element::fromWire(ddef_wire);
  228. std::string ddef2 = ddef_el2->str();
  229. EXPECT_EQ(ddef, ddef2);
  230. }