fixes bug where priorities where lost when force-rechecking.
[libtorrent.git] / test / test_primitives.cpp
blobb66a205c905057e44d6824197ef8eb273dc8fed7
1 /*
3 Copyright (c) 2008, Arvid Norberg
4 All rights reserved.
6 Redistribution and use in source and binary forms, with or without
7 modification, are permitted provided that the following conditions
8 are met:
10 * Redistributions of source code must retain the above copyright
11 notice, this list of conditions and the following disclaimer.
12 * Redistributions in binary form must reproduce the above copyright
13 notice, this list of conditions and the following disclaimer in
14 the documentation and/or other materials provided with the distribution.
15 * Neither the name of the author nor the names of its
16 contributors may be used to endorse or promote products derived
17 from this software without specific prior written permission.
19 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
23 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 POSSIBILITY OF SUCH DAMAGE.
33 #include "libtorrent/parse_url.hpp"
34 #include "libtorrent/http_tracker_connection.hpp"
35 #include "libtorrent/buffer.hpp"
36 #include "libtorrent/xml_parse.hpp"
37 #include "libtorrent/upnp.hpp"
38 #include "libtorrent/entry.hpp"
39 #include "libtorrent/bitfield.hpp"
40 #include "libtorrent/torrent_info.hpp"
41 #include "libtorrent/escape_string.hpp"
42 #include "libtorrent/broadcast_socket.hpp"
43 #ifndef TORRENT_DISABLE_DHT
44 #include "libtorrent/kademlia/node_id.hpp"
45 #include "libtorrent/kademlia/routing_table.hpp"
46 #endif
47 #include <boost/tuple/tuple.hpp>
48 #include <boost/tuple/tuple_comparison.hpp>
49 #include <boost/bind.hpp>
51 #include "test.hpp"
53 using namespace libtorrent;
54 using namespace boost::tuples;
55 using boost::bind;
57 tuple<int, int, bool> feed_bytes(http_parser& parser, char const* str)
59 tuple<int, int, bool> ret(0, 0, false);
60 tuple<int, int, bool> prev(0, 0, false);
61 for (int chunks = 1; chunks < 70; ++chunks)
63 ret = make_tuple(0, 0, false);
64 parser.reset();
65 buffer::const_interval recv_buf(str, str);
66 for (; *str;)
68 int chunk_size = (std::min)(chunks, int(strlen(recv_buf.end)));
69 if (chunk_size == 0) break;
70 recv_buf.end += chunk_size;
71 int payload, protocol;
72 bool error = false;
73 tie(payload, protocol) = parser.incoming(recv_buf, error);
74 ret.get<0>() += payload;
75 ret.get<1>() += protocol;
76 ret.get<2>() += error;
77 std::cerr << payload << ", " << protocol << ", " << chunk_size << std::endl;
78 TORRENT_ASSERT(payload + protocol == chunk_size);
80 TEST_CHECK(prev == make_tuple(0, 0, false) || ret == prev);
81 prev = ret;
83 return ret;
86 void parser_callback(std::string& out, int token, char const* s, char const* val)
88 switch (token)
90 case xml_start_tag: out += "B"; break;
91 case xml_end_tag: out += "F"; break;
92 case xml_empty_tag: out += "E"; break;
93 case xml_declaration_tag: out += "D"; break;
94 case xml_comment: out += "C"; break;
95 case xml_string: out += "S"; break;
96 case xml_attribute: out += "A"; break;
97 case xml_parse_error: out += "P"; break;
98 default: TEST_CHECK(false);
100 out += s;
101 if (token == xml_attribute)
103 TEST_CHECK(val != 0);
104 out += "V";
105 out += val;
107 else
109 TEST_CHECK(val == 0);
113 #ifndef TORRENT_DISABLE_DHT
114 void add_and_replace(libtorrent::dht::node_id& dst, libtorrent::dht::node_id const& add)
116 bool carry = false;
117 for (int k = 19; k >= 0; --k)
119 int sum = dst[k] + add[k] + (carry?1:0);
120 dst[k] = sum & 255;
121 carry = sum > 255;
124 #endif
126 int test_main()
128 using namespace libtorrent;
130 TEST_CHECK(parse_url_components("http://foo:bar@host.com:80/path/to/file")
131 == make_tuple("http", "foo:bar", "host.com", 80, "/path/to/file", (char const*)0));
133 TEST_CHECK(parse_url_components("http://host.com/path/to/file")
134 == make_tuple("http", "", "host.com", 80, "/path/to/file", (char const*)0));
136 TEST_CHECK(parse_url_components("ftp://host.com:21/path/to/file")
137 == make_tuple("ftp", "", "host.com", 21, "/path/to/file", (char const*)0));
139 TEST_CHECK(parse_url_components("http://host.com/path?foo:bar@foo:")
140 == make_tuple("http", "", "host.com", 80, "/path?foo:bar@foo:", (char const*)0));
142 TEST_CHECK(parse_url_components("http://192.168.0.1/path/to/file")
143 == make_tuple("http", "", "192.168.0.1", 80, "/path/to/file", (char const*)0));
145 TEST_CHECK(parse_url_components("http://[::1]/path/to/file")
146 == make_tuple("http", "", "[::1]", 80, "/path/to/file", (char const*)0));
148 // base64 test vectors from http://www.faqs.org/rfcs/rfc4648.html
150 TEST_CHECK(base64encode("") == "");
151 TEST_CHECK(base64encode("f") == "Zg==");
152 TEST_CHECK(base64encode("fo") == "Zm8=");
153 TEST_CHECK(base64encode("foo") == "Zm9v");
154 TEST_CHECK(base64encode("foob") == "Zm9vYg==");
155 TEST_CHECK(base64encode("fooba") == "Zm9vYmE=");
156 TEST_CHECK(base64encode("foobar") == "Zm9vYmFy");
158 // base32 test vectors from http://www.faqs.org/rfcs/rfc4648.html
160 TEST_CHECK(base32encode("") == "");
161 TEST_CHECK(base32encode("f") == "MY======");
162 TEST_CHECK(base32encode("fo") == "MZXQ====");
163 TEST_CHECK(base32encode("foo") == "MZXW6===");
164 TEST_CHECK(base32encode("foob") == "MZXW6YQ=");
165 TEST_CHECK(base32encode("fooba") == "MZXW6YTB");
166 TEST_CHECK(base32encode("foobar") == "MZXW6YTBOI======");
168 TEST_CHECK(base32decode("") == "");
169 TEST_CHECK(base32decode("MY======") == "f");
170 TEST_CHECK(base32decode("MZXQ====") == "fo");
171 TEST_CHECK(base32decode("MZXW6===") == "foo");
172 TEST_CHECK(base32decode("MZXW6YQ=") == "foob");
173 TEST_CHECK(base32decode("MZXW6YTB") == "fooba");
174 TEST_CHECK(base32decode("MZXW6YTBOI======") == "foobar");
176 TEST_CHECK(base32decode("MY") == "f");
177 TEST_CHECK(base32decode("MZXW6YQ") == "foob");
178 TEST_CHECK(base32decode("MZXW6YTBOI") == "foobar");
179 TEST_CHECK(base32decode("mZXw6yTBO1======") == "foobar");
181 std::string test;
182 for (int i = 0; i < 255; ++i)
183 test += char(i);
185 TEST_CHECK(base32decode(base32encode(test)) == test);
187 // url_has_argument
189 TEST_CHECK(!url_has_argument("http://127.0.0.1/test", "test"));
190 TEST_CHECK(!url_has_argument("http://127.0.0.1/test?foo=24", "bar"));
191 TEST_CHECK(*url_has_argument("http://127.0.0.1/test?foo=24", "foo") == "24");
192 TEST_CHECK(*url_has_argument("http://127.0.0.1/test?foo=24&bar=23", "foo") == "24");
193 TEST_CHECK(*url_has_argument("http://127.0.0.1/test?foo=24&bar=23", "bar") == "23");
194 TEST_CHECK(*url_has_argument("http://127.0.0.1/test?foo=24&bar=23&a=e", "bar") == "23");
195 TEST_CHECK(*url_has_argument("http://127.0.0.1/test?foo=24&bar=23&a=e", "a") == "e");
196 TEST_CHECK(!url_has_argument("http://127.0.0.1/test?foo=24&bar=23&a=e", "b"));
198 // HTTP request parser
200 http_parser parser;
201 boost::tuple<int, int, bool> received = feed_bytes(parser
202 , "HTTP/1.1 200 OK\r\n"
203 "Content-Length: 4\r\n"
204 "Content-Type: text/plain\r\n"
205 "\r\n"
206 "test");
208 TEST_CHECK(received == make_tuple(4, 64, false));
209 TEST_CHECK(parser.finished());
210 TEST_CHECK(std::equal(parser.get_body().begin, parser.get_body().end, "test"));
211 TEST_CHECK(parser.header("content-type") == "text/plain");
212 TEST_CHECK(atoi(parser.header("content-length").c_str()) == 4);
214 parser.reset();
216 TEST_CHECK(!parser.finished());
218 char const* upnp_response =
219 "HTTP/1.1 200 OK\r\n"
220 "ST:upnp:rootdevice\r\n"
221 "USN:uuid:000f-66d6-7296000099dc::upnp:rootdevice\r\n"
222 "Location: http://192.168.1.1:5431/dyndev/uuid:000f-66d6-7296000099dc\r\n"
223 "Server: Custom/1.0 UPnP/1.0 Proc/Ver\r\n"
224 "EXT:\r\n"
225 "Cache-Control:max-age=180\r\n"
226 "DATE: Fri, 02 Jan 1970 08:10:38 GMT\r\n\r\n";
228 received = feed_bytes(parser, upnp_response);
230 TEST_CHECK(received == make_tuple(0, int(strlen(upnp_response)), false));
231 TEST_CHECK(parser.get_body().left() == 0);
232 TEST_CHECK(parser.header("st") == "upnp:rootdevice");
233 TEST_CHECK(parser.header("location")
234 == "http://192.168.1.1:5431/dyndev/uuid:000f-66d6-7296000099dc");
235 TEST_CHECK(parser.header("ext") == "");
236 TEST_CHECK(parser.header("date") == "Fri, 02 Jan 1970 08:10:38 GMT");
238 parser.reset();
239 TEST_CHECK(!parser.finished());
241 char const* upnp_notify =
242 "NOTIFY * HTTP/1.1\r\n"
243 "Host:239.255.255.250:1900\r\n"
244 "NT:urn:schemas-upnp-org:device:MediaServer:1\r\n"
245 "NTS:ssdp:alive\r\n"
246 "Location:http://10.0.1.15:2353/upnphost/udhisapi.dll?content=uuid:c17f2c31-d19b-4912-af94-651945c8a84e\r\n"
247 "USN:uuid:c17f0c32-d1db-4be8-ae94-25f94583026e::urn:schemas-upnp-org:device:MediaServer:1\r\n"
248 "Cache-Control:max-age=900\r\n"
249 "Server:Microsoft-Windows-NT/5.1 UPnP/1.0 UPnP-Device-Host/1.0\r\n";
251 received = feed_bytes(parser, upnp_notify);
253 TEST_CHECK(received == make_tuple(0, int(strlen(upnp_notify)), false));
254 TEST_CHECK(parser.method() == "notify");
255 TEST_CHECK(parser.path() == "*");
257 parser.reset();
258 TEST_CHECK(!parser.finished());
260 char const* bt_lsd = "BT-SEARCH * HTTP/1.1\r\n"
261 "Host: 239.192.152.143:6771\r\n"
262 "Port: 6881\r\n"
263 "Infohash: 12345678901234567890\r\n"
264 "\r\n\r\n";
266 received = feed_bytes(parser, bt_lsd);
268 TEST_CHECK(received == make_tuple(2, int(strlen(bt_lsd) - 2), false));
269 TEST_CHECK(parser.method() == "bt-search");
270 TEST_CHECK(parser.path() == "*");
271 TEST_CHECK(atoi(parser.header("port").c_str()) == 6881);
272 TEST_CHECK(parser.header("infohash") == "12345678901234567890");
274 TEST_CHECK(!parser.finished());
276 parser.reset();
277 TEST_CHECK(!parser.finished());
279 // make sure we support trackers with incorrect line endings
280 char const* tracker_response =
281 "HTTP/1.1 200 OK\n"
282 "content-length: 5\n"
283 "content-type: test/plain\n"
284 "\n"
285 "\ntest";
287 received = feed_bytes(parser, tracker_response);
289 TEST_CHECK(received == make_tuple(5, int(strlen(tracker_response) - 5), false));
290 TEST_CHECK(parser.get_body().left() == 5);
292 // test xml parser
294 char xml1[] = "<a>foo<b/>bar</a>";
295 std::string out1;
297 xml_parse(xml1, xml1 + sizeof(xml1) - 1, bind(&parser_callback
298 , boost::ref(out1), _1, _2, _3));
299 std::cerr << out1 << std::endl;
300 TEST_CHECK(out1 == "BaSfooEbSbarFa");
302 char xml2[] = "<?xml version = \"1.0\"?><c x=\"1\" \t y=\"3\"/><d foo='bar'></d boo='foo'><!--comment-->";
303 std::string out2;
305 xml_parse(xml2, xml2 + sizeof(xml2) - 1, bind(&parser_callback
306 , boost::ref(out2), _1, _2, _3));
307 std::cerr << out2 << std::endl;
308 TEST_CHECK(out2 == "DxmlAversionV1.0EcAxV1AyV3BdAfooVbarFdAbooVfooCcomment");
310 char xml3[] = "<a f=1>foo</a f='b>";
311 std::string out3;
313 xml_parse(xml3, xml3 + sizeof(xml3) - 1, bind(&parser_callback
314 , boost::ref(out3), _1, _2, _3));
315 std::cerr << out3 << std::endl;
316 TEST_CHECK(out3 == "BaPunquoted attribute valueSfooFaPmissing end quote on attribute");
318 char xml4[] = "<a f>foo</a v >";
319 std::string out4;
321 xml_parse(xml4, xml4 + sizeof(xml4) - 1, bind(&parser_callback
322 , boost::ref(out4), _1, _2, _3));
323 std::cerr << out4 << std::endl;
324 TEST_CHECK(out4 == "BaPgarbage inside element bracketsSfooFaPgarbage inside element brackets");
326 // test network functions
328 error_code ec;
329 TEST_CHECK(is_local(address::from_string("192.168.0.1", ec)));
330 TEST_CHECK(is_local(address::from_string("10.1.1.56", ec)));
331 TEST_CHECK(!is_local(address::from_string("14.14.251.63", ec)));
332 TEST_CHECK(is_loopback(address::from_string("127.0.0.1", ec)));
333 TEST_CHECK(is_loopback(address::from_string("::1", ec)));
334 TEST_CHECK(is_any(address_v6::any()));
335 TEST_CHECK(is_any(address_v4::any()));
336 TEST_CHECK(!is_any(address::from_string("31.53.21.64", ec)));
338 // test torrent parsing
340 entry info;
341 info["pieces"] = "aaaaaaaaaaaaaaaaaaaa";
342 info["name.utf-8"] = "test1";
343 info["name"] = "test__";
344 info["piece length"] = 16 * 1024;
345 info["length"] = 3245;
346 entry torrent;
347 torrent["info"] = info;
349 torrent_info ti(torrent);
350 std::cerr << ti.name() << std::endl;
351 TEST_CHECK(ti.name() == "test1");
353 #ifdef TORRENT_WINDOWS
354 info["name.utf-8"] = "c:/test1/test2/test3";
355 #else
356 info["name.utf-8"] = "/test1/test2/test3";
357 #endif
358 torrent["info"] = info;
359 torrent_info ti2(torrent);
360 std::cerr << ti2.name() << std::endl;
361 TEST_CHECK(ti2.name() == "test3");
363 info["name.utf-8"] = "test2/../test3/.././../../test4";
364 torrent["info"] = info;
365 torrent_info ti3(torrent);
366 std::cerr << ti3.name() << std::endl;
367 TEST_CHECK(ti3.name() == "test2/test3/test4");
369 #ifndef TORRENT_DISABLE_DHT
370 // test kademlia functions
372 using namespace libtorrent::dht;
374 for (int i = 0; i < 160; i += 4)
376 for (int j = 0; j < 160; j += 4)
378 node_id a(0);
379 a[(159-i) / 8] = 1 << (i & 7);
380 node_id b(0);
381 b[(159-j) / 8] = 1 << (j & 7);
382 int dist = distance_exp(a, b);
384 TEST_CHECK(dist >= 0 && dist < 160);
385 TEST_CHECK(dist == ((i == j)?0:(std::max)(i, j)));
387 for (int k = 0; k < 160; k += 4)
389 node_id c(0);
390 c[(159-k) / 8] = 1 << (k & 7);
392 bool cmp = compare_ref(a, b, c);
393 TEST_CHECK(cmp == (distance(a, c) < distance(b, c)));
398 // test kademlia routing table
399 dht_settings s;
400 node_id id = boost::lexical_cast<sha1_hash>("6123456789abcdef01232456789abcdef0123456");
401 dht::routing_table table(id, 10, s);
402 table.node_seen(id, udp::endpoint(address_v4::any(), rand()));
404 node_id tmp;
405 node_id diff = boost::lexical_cast<sha1_hash>("00000f7459456a9453f8719b09547c11d5f34064");
406 std::vector<node_entry> nodes;
407 for (int i = 0; i < 1000000; ++i)
409 table.node_seen(tmp, udp::endpoint(address_v4::any(), rand()));
410 add_and_replace(tmp, diff);
413 std::copy(table.begin(), table.end(), std::back_inserter(nodes));
415 std::cout << "nodes: " << nodes.size() << std::endl;
417 std::vector<node_entry> temp;
419 std::generate(tmp.begin(), tmp.end(), &std::rand);
420 table.find_node(tmp, temp, false, nodes.size() + 1);
421 std::cout << "returned: " << temp.size() << std::endl;
422 TEST_CHECK(temp.size() == nodes.size());
424 std::generate(tmp.begin(), tmp.end(), &std::rand);
425 table.find_node(tmp, temp, true, nodes.size() + 1);
426 std::cout << "returned: " << temp.size() << std::endl;
427 TEST_CHECK(temp.size() == nodes.size() + 1);
429 std::generate(tmp.begin(), tmp.end(), &std::rand);
430 table.find_node(tmp, temp, false, 7);
431 std::cout << "returned: " << temp.size() << std::endl;
432 TEST_CHECK(temp.size() == 7);
434 std::sort(nodes.begin(), nodes.end(), bind(&compare_ref
435 , bind(&node_entry::id, _1)
436 , bind(&node_entry::id, _2), tmp));
438 int hits = 0;
439 for (std::vector<node_entry>::iterator i = temp.begin()
440 , end(temp.end()); i != end; ++i)
442 int hit = std::find_if(nodes.begin(), nodes.end()
443 , bind(&node_entry::id, _1) == i->id) - nodes.begin();
444 std::cerr << hit << std::endl;
445 if (hit < int(temp.size())) ++hits;
447 TEST_CHECK(hits > int(temp.size()) / 2);
449 std::generate(tmp.begin(), tmp.end(), &std::rand);
450 table.find_node(tmp, temp, false, 15);
451 std::cout << "returned: " << temp.size() << std::endl;
452 TEST_CHECK(temp.size() == 15);
454 std::sort(nodes.begin(), nodes.end(), bind(&compare_ref
455 , bind(&node_entry::id, _1)
456 , bind(&node_entry::id, _2), tmp));
458 hits = 0;
459 for (std::vector<node_entry>::iterator i = temp.begin()
460 , end(temp.end()); i != end; ++i)
462 int hit = std::find_if(nodes.begin(), nodes.end()
463 , bind(&node_entry::id, _1) == i->id) - nodes.begin();
464 std::cerr << hit << std::endl;
465 if (hit < int(temp.size())) ++hits;
467 TEST_CHECK(hits > int(temp.size()) / 2);
469 #endif
473 // test peer_id/sha1_hash type
475 sha1_hash h1(0);
476 sha1_hash h2(0);
477 TEST_CHECK(h1 == h2);
478 TEST_CHECK(!(h1 != h2));
479 TEST_CHECK(!(h1 < h2));
480 TEST_CHECK(!(h1 < h2));
481 TEST_CHECK(h1.is_all_zeros());
483 h1 = boost::lexical_cast<sha1_hash>("0123456789012345678901234567890123456789");
484 h2 = boost::lexical_cast<sha1_hash>("0113456789012345678901234567890123456789");
486 TEST_CHECK(h2 < h1);
487 TEST_CHECK(h2 == h2);
488 TEST_CHECK(h1 == h1);
489 h2.clear();
490 TEST_CHECK(h2.is_all_zeros());
492 h2 = boost::lexical_cast<sha1_hash>("ffffffffff0000000000ffffffffff0000000000");
493 h1 = boost::lexical_cast<sha1_hash>("fffff00000fffff00000fffff00000fffff00000");
494 h1 &= h2;
495 TEST_CHECK(h1 == boost::lexical_cast<sha1_hash>("fffff000000000000000fffff000000000000000"));
497 h2 = boost::lexical_cast<sha1_hash>("ffffffffff0000000000ffffffffff0000000000");
498 h1 = boost::lexical_cast<sha1_hash>("fffff00000fffff00000fffff00000fffff00000");
499 h1 |= h2;
500 TEST_CHECK(h1 == boost::lexical_cast<sha1_hash>("fffffffffffffff00000fffffffffffffff00000"));
502 h2 = boost::lexical_cast<sha1_hash>("0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f");
503 h1 ^= h2;
504 std::cerr << h1 << std::endl;
505 TEST_CHECK(h1 == boost::lexical_cast<sha1_hash>("f0f0f0f0f0f0f0ff0f0ff0f0f0f0f0f0f0ff0f0f"));
506 TEST_CHECK(h1 != h2);
508 h2 = sha1_hash(" ");
509 TEST_CHECK(h2 == boost::lexical_cast<sha1_hash>("2020202020202020202020202020202020202020"));
511 // CIDR distance test
512 h1 = boost::lexical_cast<sha1_hash>("0123456789abcdef01232456789abcdef0123456");
513 h2 = boost::lexical_cast<sha1_hash>("0123456789abcdef01232456789abcdef0123456");
514 TEST_CHECK(common_bits(&h1[0], &h2[0], 20) == 160);
515 h2 = boost::lexical_cast<sha1_hash>("0120456789abcdef01232456789abcdef0123456");
516 TEST_CHECK(common_bits(&h1[0], &h2[0], 20) == 14);
517 h2 = boost::lexical_cast<sha1_hash>("012f456789abcdef01232456789abcdef0123456");
518 TEST_CHECK(common_bits(&h1[0], &h2[0], 20) == 12);
519 h2 = boost::lexical_cast<sha1_hash>("0123456789abcdef11232456789abcdef0123456");
520 TEST_CHECK(common_bits(&h1[0], &h2[0], 20) == 16 * 4 + 3);
523 // test bitfield
524 bitfield test1(10, false);
525 TEST_CHECK(test1.count() == 0);
526 test1.set_bit(9);
527 TEST_CHECK(test1.count() == 1);
528 test1.clear_bit(9);
529 TEST_CHECK(test1.count() == 0);
530 test1.set_bit(2);
531 TEST_CHECK(test1.count() == 1);
532 test1.set_bit(1);
533 test1.set_bit(9);
534 TEST_CHECK(test1.count() == 3);
535 test1.clear_bit(2);
536 TEST_CHECK(test1.count() == 2);
537 int distance = std::distance(test1.begin(), test1.end());
538 std::cerr << distance << std::endl;
539 TEST_CHECK(distance == 10);
541 test1.set_all();
542 TEST_CHECK(test1.count() == 10);
544 test1.clear_all();
545 TEST_CHECK(test1.count() == 0);
546 return 0;