Line data Source code
1 : // Copyright (c) 2019 Made to Order Software Corp. All Rights Reserved
2 : //
3 : // https://snapwebsites.org/project/snapdatabase
4 : // contact@m2osw.com
5 : //
6 : // This program is free software; you can redistribute it and/or modify
7 : // it under the terms of the GNU General Public License as published by
8 : // the Free Software Foundation; either version 2 of the License, or
9 : // (at your option) any later version.
10 : //
11 : // This program is distributed in the hope that it will be useful,
12 : // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 : // GNU General Public License for more details.
15 : //
16 : // You should have received a copy of the GNU General Public License along
17 : // with this program; if not, write to the Free Software Foundation, Inc.,
18 : // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 :
20 : // self
21 : //
22 : #include "main.h"
23 :
24 :
25 : // snapdatabase lib
26 : //
27 : #include <snapdatabase/data/structure.h>
28 :
29 :
30 : // advgetopt lib
31 : //
32 : #include <advgetopt/options.h>
33 :
34 :
35 : namespace
36 : {
37 :
38 :
39 :
40 : constexpr snapdatabase::struct_description_t g_description1[] =
41 : {
42 : snapdatabase::define_description(
43 : snapdatabase::FieldName("magic")
44 : , snapdatabase::FieldType(snapdatabase::struct_type_t::STRUCT_TYPE_UINT32)
45 : ),
46 : snapdatabase::define_description(
47 : snapdatabase::FieldName("count")
48 : , snapdatabase::FieldType(snapdatabase::struct_type_t::STRUCT_TYPE_UINT32)
49 : ),
50 : snapdatabase::define_description(
51 : snapdatabase::FieldName("size")
52 : , snapdatabase::FieldType(snapdatabase::struct_type_t::STRUCT_TYPE_UINT32)
53 : ),
54 : snapdatabase::define_description(
55 : snapdatabase::FieldName("next")
56 : , snapdatabase::FieldType(snapdatabase::struct_type_t::STRUCT_TYPE_REFERENCE)
57 : ),
58 : snapdatabase::define_description(
59 : snapdatabase::FieldName("previous")
60 : , snapdatabase::FieldType(snapdatabase::struct_type_t::STRUCT_TYPE_REFERENCE)
61 : ),
62 : snapdatabase::end_descriptions()
63 : };
64 :
65 :
66 :
67 : constexpr snapdatabase::struct_description_t g_description2[] =
68 : {
69 : snapdatabase::define_description(
70 : snapdatabase::FieldName("magic")
71 : , snapdatabase::FieldType(snapdatabase::struct_type_t::STRUCT_TYPE_UINT32)
72 : ),
73 : snapdatabase::define_description(
74 : snapdatabase::FieldName("flags")
75 : , snapdatabase::FieldType(snapdatabase::struct_type_t::STRUCT_TYPE_UINT32)
76 : ),
77 : snapdatabase::define_description(
78 : snapdatabase::FieldName("name")
79 : , snapdatabase::FieldType(snapdatabase::struct_type_t::STRUCT_TYPE_P8STRING)
80 : ),
81 : snapdatabase::define_description(
82 : snapdatabase::FieldName("size")
83 : , snapdatabase::FieldType(snapdatabase::struct_type_t::STRUCT_TYPE_UINT64)
84 : ),
85 : snapdatabase::define_description(
86 : snapdatabase::FieldName("model")
87 : , snapdatabase::FieldType(snapdatabase::struct_type_t::STRUCT_TYPE_UINT16)
88 : ),
89 : snapdatabase::end_descriptions()
90 : };
91 :
92 :
93 :
94 :
95 : }
96 : // no name namespace
97 :
98 :
99 3 : CATCH_TEST_CASE("Structure Valid Version", "[structure] [version]")
100 : {
101 2 : CATCH_START_SECTION("version conversion")
102 : {
103 101 : for(int n(0); n < 100; ++n)
104 : {
105 100 : int const major_version(rand() & 0xFFFF);
106 100 : int const minor_version(rand() & 0xFFFF);
107 :
108 100 : uint32_t const binary((major_version << 16) + minor_version);
109 :
110 100 : snapdatabase::version_t v1(major_version, minor_version);
111 100 : CATCH_REQUIRE(v1.get_major() == major_version);
112 100 : CATCH_REQUIRE(v1.get_minor() == minor_version);
113 100 : CATCH_REQUIRE(v1.to_binary() == binary);
114 :
115 100 : snapdatabase::version_t v2;
116 100 : CATCH_REQUIRE(v2.get_major() == 0);
117 100 : CATCH_REQUIRE(v2.get_minor() == 0);
118 100 : CATCH_REQUIRE(v2.is_null());
119 100 : CATCH_REQUIRE(v2 != v1);
120 100 : v2.from_binary(binary);
121 100 : CATCH_REQUIRE(v2.get_major() == major_version);
122 100 : CATCH_REQUIRE(v2.get_minor() == minor_version);
123 100 : CATCH_REQUIRE(v2.to_binary() == binary);
124 100 : CATCH_REQUIRE(v2 == v1);
125 :
126 100 : v2.next_revision();
127 :
128 100 : if(minor_version == 0xFFFF)
129 : {
130 0 : CATCH_REQUIRE(v2.get_major() == major_version + 1);
131 0 : CATCH_REQUIRE(v2.get_minor() == 0);
132 : }
133 : else
134 : {
135 100 : CATCH_REQUIRE(v2.get_major() == major_version);
136 100 : CATCH_REQUIRE(v2.get_minor() == minor_version + 1);
137 : }
138 :
139 100 : v2 = v1;
140 100 : int const new_major_version(rand() & 0xFFFF);
141 100 : v2.set_major(new_major_version);
142 100 : CATCH_REQUIRE(v2.get_major() == new_major_version);
143 100 : CATCH_REQUIRE(v2.get_minor() == minor_version);
144 100 : CATCH_REQUIRE(v2 != v1);
145 :
146 100 : int const new_minor_version(rand() & 0xFFFF);
147 100 : v2.set_minor(new_minor_version);
148 100 : CATCH_REQUIRE(v2.get_major() == new_major_version);
149 100 : CATCH_REQUIRE(v2.get_minor() == new_minor_version);
150 100 : CATCH_REQUIRE(v2 != v1);
151 :
152 100 : v2 = v1;
153 100 : CATCH_REQUIRE(v2.get_major() == major_version);
154 100 : CATCH_REQUIRE(v2.get_minor() == minor_version);
155 100 : CATCH_REQUIRE(v2.to_binary() == binary);
156 100 : CATCH_REQUIRE(v2 == v1);
157 :
158 100 : snapdatabase::version_t v3(v1);
159 100 : CATCH_REQUIRE_FALSE(v3.is_null());
160 100 : CATCH_REQUIRE(v3.get_major() == major_version);
161 100 : CATCH_REQUIRE(v3.get_minor() == minor_version);
162 100 : CATCH_REQUIRE(v3.to_binary() == binary);
163 100 : CATCH_REQUIRE(v3 == v1);
164 100 : CATCH_REQUIRE_FALSE(v3 > v1);
165 100 : CATCH_REQUIRE(v3 >= v1);
166 100 : CATCH_REQUIRE_FALSE(v3 < v1);
167 100 : CATCH_REQUIRE(v3 <= v1);
168 :
169 200 : std::string v3_str(v3.to_string());
170 200 : std::string version_str;
171 100 : version_str += std::to_string(major_version);
172 100 : version_str += '.';
173 100 : version_str += std::to_string(minor_version);
174 100 : CATCH_REQUIRE(v3_str == version_str);
175 :
176 100 : v3.next_branch();
177 100 : CATCH_REQUIRE(v3.get_major() == major_version + 1);
178 100 : CATCH_REQUIRE(v3.get_minor() == 0);
179 100 : CATCH_REQUIRE(v3.to_binary() == ((major_version + 1) << 16));
180 : }
181 : }
182 : CATCH_END_SECTION()
183 1 : }
184 :
185 3 : CATCH_TEST_CASE("Structure Overflown Version", "[structure] [version]")
186 : {
187 2 : CATCH_START_SECTION("version overflow")
188 : {
189 101 : for(int n(0); n < 100; ++n)
190 : {
191 100 : int major_version(0);
192 100 : int minor_version(0);
193 43 : do
194 : {
195 143 : major_version = rand() ^ rand() * 65536;
196 143 : minor_version = rand() ^ rand() * 65536;
197 : }
198 : while(major_version < 65536
199 143 : && minor_version < 65536);
200 :
201 100 : CATCH_REQUIRE_THROWS_MATCHES(
202 : snapdatabase::version_t(major_version, minor_version)
203 : , snapdatabase::invalid_parameter
204 : , Catch::Matchers::ExceptionMessage(
205 : "snapdatabase_error: major/minor version must be between 0 and 65535 inclusive, "
206 : + std::to_string(major_version)
207 : + "."
208 : + std::to_string(minor_version)
209 : + " is incorrect."));
210 : }
211 : }
212 : CATCH_END_SECTION()
213 1 : }
214 :
215 3 : CATCH_TEST_CASE("Structure Overflow Version", "[structure] [version]")
216 : {
217 2 : CATCH_START_SECTION("version compare")
218 : {
219 101 : for(int n(0); n < 100; ++n)
220 : {
221 100 : int major_version(rand() & 0xFFFF);
222 100 : int minor_version(rand() & 0xFFFF);
223 100 : int major_version2(rand() & 0xFFFF);
224 100 : while(major_version == major_version2)
225 : {
226 0 : major_version2 = rand() & 0xFFFF;
227 : }
228 :
229 100 : snapdatabase::version_t v1(major_version, minor_version);
230 100 : snapdatabase::version_t v2(major_version2, minor_version);
231 100 : if(major_version < major_version2)
232 : {
233 57 : CATCH_REQUIRE_FALSE(v1 == v2);
234 57 : CATCH_REQUIRE(v1 != v2);
235 57 : CATCH_REQUIRE(v1 < v2);
236 57 : CATCH_REQUIRE(v1 <= v2);
237 57 : CATCH_REQUIRE(v2 > v1);
238 57 : CATCH_REQUIRE(v2 >= v1);
239 : }
240 : else
241 : {
242 43 : CATCH_REQUIRE_FALSE(v1 == v2);
243 43 : CATCH_REQUIRE(v1 != v2);
244 43 : CATCH_REQUIRE(v1 > v2);
245 43 : CATCH_REQUIRE(v1 >= v2);
246 43 : CATCH_REQUIRE(v2 < v1);
247 43 : CATCH_REQUIRE(v2 <= v1);
248 : }
249 : }
250 : }
251 : CATCH_END_SECTION()
252 1 : }
253 :
254 :
255 4 : CATCH_TEST_CASE("Structure", "[structure]")
256 : {
257 4 : CATCH_START_SECTION("simple structure")
258 : {
259 2 : snapdatabase::structure::pointer_t description(std::make_shared<snapdatabase::structure>(g_description1));
260 :
261 1 : description->init_buffer();
262 :
263 1 : description->set_uinteger("magic", static_cast<uint32_t>(snapdatabase::dbtype_t::BLOCK_TYPE_BLOB));
264 :
265 1 : std::uint32_t count(123);
266 1 : description->set_uinteger("count", count);
267 :
268 1 : std::uint32_t size(900000);
269 1 : description->set_uinteger("size", size);
270 :
271 1 : snapdatabase::reference_t next(0xff00ff00ff00);
272 1 : description->set_uinteger("next", next);
273 :
274 1 : snapdatabase::reference_t previous(0xff11ff11ff11);
275 1 : description->set_uinteger("previous", previous);
276 :
277 1 : CATCH_REQUIRE(description->get_uinteger("magic") == static_cast<uint32_t>(snapdatabase::dbtype_t::BLOCK_TYPE_BLOB));
278 1 : CATCH_REQUIRE(description->get_uinteger("count") == count);
279 1 : CATCH_REQUIRE(description->get_uinteger("size") == size);
280 1 : CATCH_REQUIRE(description->get_uinteger("next") == next);
281 1 : CATCH_REQUIRE(description->get_uinteger("previous") == previous);
282 : }
283 : CATCH_END_SECTION()
284 :
285 4 : CATCH_START_SECTION("structure with a string")
286 : {
287 2 : snapdatabase::structure::pointer_t description(std::make_shared<snapdatabase::structure>(g_description2));
288 :
289 1 : description->init_buffer();
290 :
291 1 : description->set_uinteger("magic", static_cast<uint32_t>(snapdatabase::dbtype_t::BLOCK_TYPE_DATA));
292 :
293 1 : std::uint32_t flags(0x100105);
294 1 : description->set_uinteger("flags", flags);
295 :
296 2 : std::string const name("this is the name we want to include here");
297 1 : description->set_string("name", name);
298 :
299 1 : uint64_t size(1LL << 53);
300 1 : description->set_uinteger("size", size);
301 :
302 1 : uint16_t model(33);
303 1 : description->set_uinteger("model", model);
304 :
305 1 : CATCH_REQUIRE(description->get_uinteger("magic") == static_cast<uint32_t>(snapdatabase::dbtype_t::BLOCK_TYPE_DATA));
306 1 : CATCH_REQUIRE(description->get_uinteger("flags") == flags);
307 1 : CATCH_REQUIRE(description->get_string("name") == name);
308 1 : CATCH_REQUIRE(description->get_uinteger("size") == size);
309 1 : CATCH_REQUIRE(description->get_uinteger("model") == model);
310 : }
311 : CATCH_END_SECTION()
312 8 : }
313 :
314 :
315 : // vim: ts=4 sw=4 et
|