data_unittests.cc 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281
  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. BOOST_FOREACH(std::string s, sv) {
  56. // also test << operator, which uses Element::str()
  57. std::ostringstream stream;
  58. el = Element::createFromString(s);
  59. stream << el;
  60. EXPECT_EQ(stream.str(), s);
  61. }
  62. // some parse errors
  63. try {
  64. Element::createFromString("{1}");
  65. } catch (isc::data::ParseError pe) {
  66. std::string s = std::string(pe.what());
  67. EXPECT_EQ(s, "String expected line 1 pos 3");
  68. }
  69. sv.clear();
  70. sv.push_back("{1}");
  71. //ElementPtr ep = Element::createFromString("\"aaa\nbbb\"err");
  72. //std::cout << ep << std::endl;
  73. sv.push_back("\n\nTru");
  74. sv.push_back("{ \n \"aaa\nbbb\"err:");
  75. sv.push_back("{ \t\n \"aaa\nbbb\"\t\n\n:\n True, \"\\\"");
  76. sv.push_back("{ \"a\": None}");
  77. sv.push_back("");
  78. BOOST_FOREACH(std::string s, sv) {
  79. EXPECT_THROW(el = Element::createFromString(s), isc::data::ParseError);
  80. }
  81. }
  82. TEST(Element, create_and_value_throws) {
  83. // this test checks whether elements throw exceptions if the
  84. // incorrect type is requested
  85. ElementPtr el;
  86. el = Element::create(1);
  87. EXPECT_THROW(el->doubleValue(), TypeError);
  88. EXPECT_THROW(el->boolValue(), TypeError);
  89. EXPECT_THROW(el->stringValue(), TypeError);
  90. EXPECT_THROW(el->listValue(), TypeError);
  91. EXPECT_THROW(el->mapValue(), TypeError);
  92. el = Element::create(1.1);
  93. EXPECT_THROW(el->intValue(), TypeError);
  94. EXPECT_THROW(el->boolValue(), TypeError);
  95. EXPECT_THROW(el->stringValue(), TypeError);
  96. EXPECT_THROW(el->listValue(), TypeError);
  97. EXPECT_THROW(el->mapValue(), TypeError);
  98. el = Element::create(true);
  99. EXPECT_THROW(el->intValue(), TypeError);
  100. EXPECT_THROW(el->doubleValue(), TypeError);
  101. EXPECT_THROW(el->stringValue(), TypeError);
  102. EXPECT_THROW(el->listValue(), TypeError);
  103. EXPECT_THROW(el->mapValue(), TypeError);
  104. el = Element::create("foo");
  105. EXPECT_THROW(el->intValue(), TypeError);
  106. EXPECT_THROW(el->doubleValue(), TypeError);
  107. EXPECT_THROW(el->boolValue(), TypeError);
  108. EXPECT_THROW(el->listValue(), TypeError);
  109. EXPECT_THROW(el->mapValue(), TypeError);
  110. std::vector<ElementPtr> v;
  111. el = Element::create(v);
  112. EXPECT_THROW(el->intValue(), TypeError);
  113. EXPECT_THROW(el->doubleValue(), TypeError);
  114. EXPECT_THROW(el->boolValue(), TypeError);
  115. EXPECT_THROW(el->stringValue(), TypeError);
  116. EXPECT_THROW(el->mapValue(), TypeError);
  117. std::map<std::string, ElementPtr> m;
  118. el = Element::create(m);
  119. EXPECT_THROW(el->intValue(), TypeError);
  120. EXPECT_THROW(el->doubleValue(), TypeError);
  121. EXPECT_THROW(el->boolValue(), TypeError);
  122. EXPECT_THROW(el->stringValue(), TypeError);
  123. EXPECT_THROW(el->listValue(), TypeError);
  124. }
  125. TEST(Element, ListElement) {
  126. // this function checks the specific functions for ListElements
  127. ElementPtr el = Element::createFromString("[ 1, \"bar\", 3 ]");
  128. EXPECT_EQ(el->get(0)->intValue(), 1);
  129. EXPECT_EQ(el->get(1)->stringValue(), "bar");
  130. EXPECT_EQ(el->get(2)->intValue(), 3);
  131. el->set(0, Element::createFromString("\"foo\""));
  132. EXPECT_EQ(el->get(0)->stringValue(), "foo");
  133. el->add(Element::create(47806));
  134. EXPECT_EQ(el->get(3)->intValue(), 47806);
  135. el->remove(1);
  136. el->remove(1);
  137. EXPECT_EQ(el->str(), "[ \"foo\", 47806 ]");
  138. // hmm, it errors on EXPECT_THROW(el->get(3), std::out_of_range)
  139. EXPECT_ANY_THROW(el->get(3));
  140. el->add(Element::create(32));
  141. EXPECT_EQ(el->get(2)->intValue(), 32);
  142. }
  143. TEST(Element, MapElement) {
  144. // this function checks the specific functions for ListElements
  145. ElementPtr el = Element::createFromString("{ \"name\": \"foo\", \"value1\": \"bar\", \"value2\": { \"number\": 42 } }");
  146. ElementPtr el2;
  147. EXPECT_EQ(el->get("name")->stringValue(), "foo");
  148. EXPECT_EQ(el->get("value2")->getType(), Element::map);
  149. EXPECT_TRUE(isNull(el->get("value3")));
  150. el->set("value3", Element::create(47806));
  151. EXPECT_EQ(el->get("value3")->intValue(), 47806);
  152. el->remove("value3");
  153. EXPECT_TRUE(isNull(el->get("value3")));
  154. EXPECT_EQ(el->find("value2/number")->intValue(), 42);
  155. EXPECT_TRUE(isNull(el->find("value2/nothing/")));
  156. EXPECT_EQ(el->find("value1")->stringValue(), "bar");
  157. EXPECT_EQ(el->find("value1/")->stringValue(), "bar");
  158. EXPECT_TRUE(el->find("value1", el2));
  159. EXPECT_FALSE(el->find("name/error", el2));
  160. }
  161. void my_print(std::string &s) {
  162. int i;
  163. for (i = 0; i < s.size(); i++) {
  164. if (isalnum(s.at(i))) {
  165. std::cout << s.at(i);
  166. } else {
  167. std::cout << "\\" << setfill('0') << setw(3) << oct << int(s.at(i));
  168. }
  169. }
  170. std::cout << std::endl;
  171. }
  172. TEST(Element, to_and_from_wire) {
  173. ElementPtr el, decoded_el;
  174. std::string wire;
  175. std::vector<std::string> sv;
  176. std::vector<std::string> sw;
  177. std::stringstream bigstring, bigstring2;
  178. std::stringstream bigwire, bigwire2;
  179. sv.push_back("{\"name\": \"foo\"}");
  180. sw.push_back("Skan\004name\050\003foo");
  181. sv.push_back("{\"value2\": {\"number\": 42}}");
  182. sw.push_back("Skan\006value2\042\013\006number\046\00242");
  183. sv.push_back("{\"bool\": False, \"bool2\": True, \"real\": 2.34, \"string\": \"foo\"}");
  184. sw.push_back("Skan\004bool\045\0010\005bool2\045\0011\004real\047\0042\05634\006string\050\003foo");
  185. sv.push_back("{\"list\": [ 1, 2, 3, 4 ]}");
  186. sw.push_back("Skan\004list\043\014\046\0011\046\0012\046\0013\046\0014");
  187. // some big ones
  188. bigstring << "{\"bigstring\": \"";
  189. bigwire << "Skan\011bigstring\030\001\001";
  190. for (size_t i = 0; i < 257; i++) {
  191. bigstring << "x";
  192. bigwire << "x";
  193. }
  194. bigstring << "\"}";
  195. sv.push_back(bigstring.str());
  196. sw.push_back(bigwire.str());
  197. bigstring2 << "{\"bigstring2\": \"";
  198. bigwire2 << "Skan\012bigstring2\010";
  199. bigwire2 << '\000' << '\001' << '\000' << '\001';
  200. for (size_t i = 0; i < 65537; i++) {
  201. bigstring2 << "x";
  202. bigwire2 << "x";
  203. }
  204. bigstring2 << "\"}";
  205. sv.push_back(bigstring2.str());
  206. sw.push_back(bigwire2.str());
  207. BOOST_FOREACH(std::string s, sv) {
  208. // also test << operator, which uses Element::str()
  209. el = Element::createFromString(s);
  210. EXPECT_EQ(s, el->str());
  211. wire = el->toWire();
  212. /*
  213. std::cout << "Encoded wire format:" << std::endl;
  214. my_print(wire);
  215. std::cout << "Expecting:" << std::endl;
  216. my_print(sw.at(0));
  217. */
  218. EXPECT_EQ(sw.at(0), wire);
  219. sw.erase(sw.begin());
  220. decoded_el = Element::fromWire(wire);
  221. EXPECT_EQ(s, decoded_el->str());
  222. }
  223. //EXPECT_THROW(Element::fromWire("Skan\004name\050\003foo"), DecodeError);
  224. EXPECT_THROW(Element::fromWire("Skan\004name\050"), DecodeError);
  225. EXPECT_THROW(Element::fromWire("Skan\004na"), DecodeError);
  226. EXPECT_THROW(Element::fromWire("Skan\004name\050\003fo"), DecodeError);
  227. EXPECT_NO_THROW(Element::fromWire("Skan\004name\041\003foo"));
  228. EXPECT_THROW(Element::fromWire("Skan\004name\041\003fo"), DecodeError);
  229. EXPECT_NO_THROW(Element::fromWire("Skan\004name\044\001a"));
  230. EXPECT_THROW(Element::fromWire("Skab\004name\050\003foo"), DecodeError);
  231. //EXPECT_EQ("\047\0031.2", Element::create(1.2)->toWire(0));
  232. EXPECT_EQ("\046\0011", Element::createFromString("[ 1 ]")->toWire(1));
  233. }