]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/property_tree/test/test_utils.hpp
update ceph source to reef 18.1.2
[ceph.git] / ceph / src / boost / libs / property_tree / test / test_utils.hpp
1 // ----------------------------------------------------------------------------
2 // Copyright (C) 2002-2005 Marcin Kalicinski
3 //
4 // Distributed under the Boost Software License, Version 1.0.
5 // (See accompanying file LICENSE_1_0.txt or copy at
6 // http://www.boost.org/LICENSE_1_0.txt)
7 //
8 // For more information, see www.boost.org
9 // ----------------------------------------------------------------------------
10 #ifndef BOOST_PROPERTY_TREE_TEST_UTILS_INCLUDED
11 #define BOOST_PROPERTY_TREE_TEST_UTILS_INCLUDED
12
13 #define BOOST_PROPERTY_TREE_DEBUG // Enable ptree debugging
14 #include <boost/property_tree/ptree.hpp>
15
16 // Do not deprecate insecure CRT calls on VC8
17 #if (defined(BOOST_MSVC) && (BOOST_MSVC >= 1400) && !defined(_CRT_SECURE_NO_DEPRECATE))
18 # define _CRT_SECURE_NO_DEPRECATE
19 #endif
20
21 #include <boost/core/lightweight_test.hpp>
22 #include <boost/property_tree/detail/ptree_utils.hpp>
23 #include <fstream>
24 #include <cstring>
25 #include <sstream>
26
27 template<class Ptree>
28 typename Ptree::size_type total_size(const Ptree &pt)
29 {
30 typename Ptree::size_type size = 1;
31 for (typename Ptree::const_iterator it = pt.begin(); it != pt.end(); ++it)
32 size += total_size(it->second);
33 return size;
34 }
35
36 template<class Ptree>
37 typename Ptree::size_type total_keys_size(const Ptree &pt)
38 {
39 typename Ptree::size_type size = 0;
40 for (typename Ptree::const_iterator it = pt.begin(); it != pt.end(); ++it)
41 {
42 size += it->first.size();
43 size += total_keys_size(it->second);
44 }
45 return size;
46 }
47
48 template<class Ptree>
49 typename Ptree::size_type total_data_size(const Ptree &pt)
50 {
51 typename Ptree::size_type size = pt.data().size();
52 for (typename Ptree::const_iterator it = pt.begin(); it != pt.end(); ++it)
53 size += total_data_size(it->second);
54 return size;
55 }
56
57 class test_file
58 {
59 public:
60 test_file(const char *test_data, const char *filename)
61 {
62 if (test_data && filename)
63 {
64 name = filename;
65 std::ofstream stream(name.c_str());
66 using namespace std;
67 stream.write(test_data, strlen(test_data));
68 BOOST_TEST(stream.good());
69 }
70 }
71 ~test_file()
72 {
73 if (!name.empty())
74 remove(name.c_str());
75 }
76 private:
77 std::string name;
78 };
79
80 template<class Ptree>
81 Ptree get_test_ptree()
82 {
83 using namespace boost::property_tree;
84 typedef typename Ptree::key_type Str;
85 Ptree pt;
86 pt.put_value(detail::widen<Str>("data0"));
87 pt.put(detail::widen<Str>("key1"), detail::widen<Str>("data1"));
88 pt.put(detail::widen<Str>("key1.key"), detail::widen<Str>("data2"));
89 pt.put(detail::widen<Str>("key2"), detail::widen<Str>("data3"));
90 pt.put(detail::widen<Str>("key2.key"), detail::widen<Str>("data4"));
91 return pt;
92 }
93
94 // Generic test for file parser
95 template<class Ptree, class ReadFunc, class WriteFunc>
96 void generic_parser_test(Ptree &pt,
97 ReadFunc rf,
98 WriteFunc wf,
99 const char *test_data_1,
100 const char *test_data_2,
101 const char *filename_1,
102 const char *filename_2,
103 const char *filename_out)
104 {
105
106 using namespace boost::property_tree;
107
108 // Create test files
109 test_file file_1(test_data_1, filename_1);
110 test_file file_2(test_data_2, filename_2);
111 test_file file_out("", filename_out);
112
113 rf(filename_1, pt); // Read file
114 wf(filename_out, pt); // Write file
115 Ptree pt2;
116 rf(filename_out, pt2); // Read file again
117
118 // Compare original with read
119 BOOST_TEST(pt == pt2);
120
121 }
122
123 // Generic test for file parser with expected success
124 template<class Ptree, class ReadFunc, class WriteFunc>
125 void generic_parser_test_ok(ReadFunc rf,
126 WriteFunc wf,
127 const char *test_data_1,
128 const char *test_data_2,
129 const char *filename_1,
130 const char *filename_2,
131 const char *filename_out,
132 unsigned int total_size,
133 unsigned int total_data_size,
134 unsigned int total_keys_size)
135 {
136
137 using namespace boost::property_tree;
138
139 std::cerr << "(progress) Starting generic parser test with test file \"" << filename_1 << "\"\n";
140
141 // Make sure no instances exist
142 //BOOST_CHECK(Ptree::debug_get_instances_count() == 0);
143
144 try
145 {
146
147 // Read file
148 Ptree pt;
149 generic_parser_test<Ptree, ReadFunc, WriteFunc>(pt, rf, wf,
150 test_data_1, test_data_2,
151 filename_1, filename_2, filename_out);
152
153 // Determine total sizes
154 typename Ptree::size_type actual_total_size = ::total_size(pt);
155 typename Ptree::size_type actual_data_size = ::total_data_size(pt);
156 typename Ptree::size_type actual_keys_size = ::total_keys_size(pt);
157 if (actual_total_size != total_size ||
158 actual_data_size != total_data_size ||
159 actual_keys_size != total_keys_size)
160 std::cerr << "Sizes: " << (unsigned)::total_size(pt) << ", " << (unsigned)::total_data_size(pt) << ", " << (unsigned)::total_keys_size(pt) << "\n";
161
162 // Check total sizes
163 BOOST_TEST(actual_total_size == total_size);
164 BOOST_TEST(actual_data_size == total_data_size);
165 BOOST_TEST(actual_keys_size == total_keys_size);
166
167 }
168 catch (std::runtime_error &e)
169 {
170 BOOST_ERROR(e.what());
171 }
172
173 // Test for leaks
174 //BOOST_CHECK(Ptree::debug_get_instances_count() == 0);
175
176 }
177
178 // Generic test for file parser with expected error
179 template<class Ptree, class ReadFunc, class WriteFunc, class Error>
180 void generic_parser_test_error(ReadFunc rf,
181 WriteFunc wf,
182 const char *test_data_1,
183 const char *test_data_2,
184 const char *filename_1,
185 const char *filename_2,
186 const char *filename_out,
187 unsigned long expected_error_line)
188 {
189
190 std::cerr << "(progress) Starting generic parser test with test file \"" << filename_1 << "\"\n";
191
192 // Make sure no instances exist
193 //BOOST_CHECK(Ptree::debug_get_instances_count() == 0);
194
195 {
196
197 // Create ptree as a copy of test ptree (to test if read failure does not damage ptree)
198 Ptree pt(get_test_ptree<Ptree>());
199 try
200 {
201 generic_parser_test<Ptree, ReadFunc, WriteFunc>(pt, rf, wf,
202 test_data_1, test_data_2,
203 filename_1, filename_2, filename_out);
204 BOOST_ERROR("No required exception thrown");
205 }
206 catch (Error &e)
207 {
208 BOOST_TEST(e.line() == expected_error_line); // Test line number
209 BOOST_TEST(pt == get_test_ptree<Ptree>()); // Test if error damaged contents
210 }
211 catch (...)
212 {
213 BOOST_ERROR("Invalid exception type thrown");
214 throw;
215 }
216
217 }
218
219 // Test for leaks
220 //BOOST_CHECK(Ptree::debug_get_instances_count() == 0);
221
222 }
223
224 template <typename Ch> std::basic_ostream<Ch>& errstream();
225 template <> inline
226 std::basic_ostream<char>& errstream() { return std::cerr; }
227 #ifndef BOOST_NO_CWCHAR
228 template <> inline
229 std::basic_ostream<wchar_t>& errstream() { return std::wcerr; }
230 #endif
231
232 template <class Ptree, class ReadFunc, class WriteFunc>
233 void check_exact_roundtrip(ReadFunc rf, WriteFunc wf, const char *test_data) {
234 std::cerr << "(progress) Starting exact roundtrip test with test data:\n"
235 << test_data << "\n-----\n";
236 using namespace boost::property_tree;
237 typedef typename Ptree::key_type::value_type Ch;
238 typedef typename Ptree::key_type Str;
239 Str native_test_data = detail::widen<Str>(test_data);
240
241 std::basic_istringstream<Ch> in_stream(native_test_data);
242 std::basic_ostringstream<Ch> out_stream;
243 Ptree tree;
244 rf(in_stream, tree);
245 wf(out_stream, tree);
246 std::cerr << "(progress) Roundtripped data:\n";
247 errstream<Ch>() << out_stream.str();
248 std::cerr << "\n-----\n";
249 BOOST_TEST(native_test_data == out_stream.str());
250 }
251
252 #endif