added some tests

This commit is contained in:
Arvid Norberg 2005-08-11 11:06:52 +00:00
parent 713dad845d
commit 8a90767be8
9 changed files with 404 additions and 13 deletions

View File

@ -108,10 +108,9 @@ namespace libtorrent
{
public:
// we need a list here instead of a map, to maintain
// the order of elements. Since the info-hash is
// reconstructed from an entry, it's important that
// the order is preserved.
// the key is always a string. If a generic entry would be allowed
// as a key, sorting would become a problem (e.g. to compare a string
// to a list). The definition doesn't mention such a limit though.
typedef std::list<std::pair<std::string, entry> > dictionary_type;
typedef std::string string_type;
typedef std::list<entry> list_type;
@ -138,11 +137,13 @@ namespace libtorrent
entry(const entry& e);
~entry();
void operator=(const entry& e);
void operator=(const dictionary_type&);
void operator=(const string_type&);
void operator=(const list_type&);
void operator=(const integer_type&);
bool operator==(entry const& e) const;
void operator=(entry const&);
void operator=(dictionary_type const&);
void operator=(string_type const&);
void operator=(list_type const&);
void operator=(integer_type const&);
void sort();

View File

@ -112,8 +112,7 @@ namespace libtorrent
inline std::ostream& operator<<(std::ostream& os, big_number const& peer)
{
for (big_number::const_iterator i = peer.begin();
i != peer.end();
++i)
i != peer.end(); ++i)
{
os << std::hex << std::setw(2) << std::setfill('0')
<< static_cast<unsigned int>(*i);
@ -131,8 +130,12 @@ namespace libtorrent
{
char c[2];
is >> c[0] >> c[1];
if (c[0] < 0 || c[1] < 0
|| c[0] > 'f' || c[1] > 'f'
c[0] = tolower(c[0]);
c[1] = tolower(c[1]);
std::cerr << c[0] << " " << c[1] << "\n";
if (
((c[0] < '0' || c[0] > '9') && (c[0] < 'a' || c[0] > 'f'))
|| ((c[1] < '0' || c[1] > '9') && (c[1] < 'a' || c[1] > 'f'))
|| is.fail())
{
is.setstate(ios_base::failbit);
@ -147,3 +150,4 @@ namespace libtorrent
}
#endif // TORRENT_PEER_ID_HPP_INCLUDED

View File

@ -198,6 +198,25 @@ namespace libtorrent
m_type = int_t;
}
bool entry::operator==(entry const& e) const
{
if (m_type != e.m_type) return false;
switch(m_type)
{
case int_t:
return integer() == e.integer();
case string_t:
return string() == e.string();
case list_t:
return list() == e.list();
case dictionary_t:
return dict() == e.dict();
default:
assert(m_type == undefined_t);
return true;
}
}
void entry::construct(data_type t)
{

18
test/Jamfile Normal file
View File

@ -0,0 +1,18 @@
use-project /torrent : .. ;
project
:
requirements <threading>multi
<library>/torrent
<source>main.cpp
;
test-suite libtorrent :
# [ run test_storage.cpp ]
# [ run test_piece_picker.cpp ]
# [ run test_entry.cpp ]
[ run test_bencoding.cpp ]
[ run test_ip_filter.cpp ]
[ run test_hasher.cpp ]
;

31
test/main.cpp Normal file
View File

@ -0,0 +1,31 @@
#include <iostream>
int test_main();
bool tests_failure = false;
void report_failure(char const* err, char const* file, int line)
{
std::cerr << file << ":" << line << "\"" << err << "\"\n";
tests_failure = true;
}
int main()
{
try
{
test_main();
return tests_failure ? 1 : 0;
}
catch (std::exception const& e)
{
std::cerr << "Terminated with exception: \"" << e.what() << "\"\n";
return 1;
}
catch (...)
{
std::cerr << "Terminated with unknown exception\n";
return 1;
}
}

40
test/test.hpp Normal file
View File

@ -0,0 +1,40 @@
#ifndef TEST_HPP
#define TEST_HPP
void report_failure(char const* str, char const* file, int line);
#if defined(_MSC_VER)
#define COUNTER_GUARD(x)
#else
#define COUNTER_GUARD(type) \
struct BOOST_PP_CAT(type, _counter_guard) \
{ \
~BOOST_PP_CAT(type, _counter_guard()) \
{ \
TEST_CHECK(counted_type<type>::count == 0); \
} \
} BOOST_PP_CAT(type, _guard)
#endif
#define TEST_REPORT_AUX(x, line, file) \
report_failure(x, line, file)
#define TEST_CHECK(x) \
if (!(x)) \
TEST_REPORT_AUX("TEST_CHECK failed: \"" #x "\"", __FILE__, __LINE__)
#define TEST_ERROR(x) \
TEST_REPORT_AUX((std::string("ERROR: \"") + x + "\"").c_str(), __FILE__, __LINE__)
#define TEST_NOTHROW(x) \
try \
{ \
x; \
} \
catch (...) \
{ \
TEST_ERROR("Exception thrown: " #x); \
}
#endif // TEST_HPP

74
test/test_bencoding.cpp Normal file
View File

@ -0,0 +1,74 @@
#include "libtorrent/bencode.hpp"
#include <boost/lexical_cast.hpp>
#include "test.hpp"
using namespace libtorrent;
// test vectors from bittorrent protocol description
// http://www.bittorrent.com/protocol.html
std::string encode(entry const& e)
{
std::string ret;
bencode(std::back_inserter(ret), e);
return ret;
}
entry decode(std::string const& str)
{
return bdecode(str.begin(), str.end());
}
int test_main()
{
using namespace libtorrent;
// ** strings **
{
entry e("spam");
TEST_CHECK(encode(e) == "4:spam");
TEST_CHECK(decode(encode(e)) == e);
}
// ** integers **
{
entry e(3);
TEST_CHECK(encode(e) == "i3e");
TEST_CHECK(decode(encode(e)) == e);
}
{
entry e(-3);
TEST_CHECK(encode(e) == "i-3e");
TEST_CHECK(decode(encode(e)) == e);
}
{
entry e(int(0));
TEST_CHECK(encode(e) == "i0e");
TEST_CHECK(decode(encode(e)) == e);
}
// ** lists **
{
entry::list_type l;
l.push_back(entry("spam"));
l.push_back(entry("eggs"));
entry e(l);
TEST_CHECK(encode(e) == "l4:spam4:eggse");
TEST_CHECK(decode(encode(e)) == e);
}
// ** dictionaries **
{
entry e(entry::dictionary_t);
e["cow"] = entry("moo");
e["spam"] = entry("eggs");
TEST_CHECK(encode(e) == "d3:cow3:moo4:spam4:eggse");
TEST_CHECK(decode(encode(e)) == e);
}
return 0;
}

46
test/test_hasher.cpp Normal file
View File

@ -0,0 +1,46 @@
#include "libtorrent/hasher.hpp"
#include <boost/lexical_cast.hpp>
#include "test.hpp"
using namespace libtorrent;
// test vectors from RFC 3174
// http://www.faqs.org/rfcs/rfc3174.html
char const* test_array[4] =
{
"abc",
"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
"a",
"0123456701234567012345670123456701234567012345670123456701234567"
};
long int repeat_count[4] = { 1, 1, 1000000, 10 };
char const* result_array[4] =
{
"A9993E364706816ABA3E25717850C26C9CD0D89D",
"84983E441C3BD26EBAAE4AA1F95129E5E54670F1",
"34AA973CD4C4DAA4F61EEB2BDBAD27316534016F",
"DEA356A2CDDD90C7A7ECEDC5EBB563934F460452"
};
int test_main()
{
using namespace libtorrent;
for (int test = 0; test < 4; ++test)
{
hasher h;
for (int i = 0; i < repeat_count[test]; ++i)
h.update(test_array[test], std::strlen(test_array[test]));
sha1_hash result = boost::lexical_cast<sha1_hash>(result_array[test]);
TEST_CHECK(result == h.final());
}
return 0;
}

158
test/test_ip_filter.cpp Normal file
View File

@ -0,0 +1,158 @@
#include "libtorrent/ip_filter.hpp"
#include <boost/utility.hpp>
#include "test.hpp"
using namespace libtorrent;
bool compare(ip_filter::ip_range const& lhs
, ip_filter::ip_range const& rhs)
{
return lhs.first == rhs.first
&& lhs.last == rhs.last
&& lhs.flags == rhs.flags;
}
void test_rules_invariant(std::vector<ip_filter::ip_range> const& r, ip_filter const& f)
{
typedef std::vector<ip_filter::ip_range>::const_iterator iterator;
TEST_CHECK(!r.empty());
if (r.empty()) return;
TEST_CHECK(r.front().first == address(0,0,0,0,0));
TEST_CHECK(r.back().last == address(255,255,255,255,0));
iterator i = r.begin();
iterator j = boost::next(i);
for (iterator i(r.begin()), j(boost::next(r.begin()))
, end(r.end()); j != end; ++j, ++i)
{
TEST_CHECK(f.access(i->last) == i->flags);
TEST_CHECK(f.access(j->first) == j->flags);
TEST_CHECK(i->last.ip() + 1 == j->first.ip());
}
}
int test_main()
{
using namespace libtorrent;
std::vector<ip_filter::ip_range> range;
// **** test joining of ranges at the end ****
ip_filter::ip_range expected1[] =
{
{address(0,0,0,0,0), address(0,255,255,255,0), 0}
, {address(1,0,0,0,0), address(3,0,0,0,0), ip_filter::blocked}
, {address(3,0,0,1,0), address(255,255,255,255,0), 0}
};
{
ip_filter f;
f.add_rule(address(1,0,0,0,0), address(2,0,0,0,0), ip_filter::blocked);
f.add_rule(address(2,0,0,1,0), address(3,0,0,0,0), ip_filter::blocked);
range = f.export_filter();
test_rules_invariant(range, f);
TEST_CHECK(range.size() == 3);
TEST_CHECK(std::equal(range.begin(), range.end(), expected1, &compare));
}
// **** test joining of ranges at the start ****
{
ip_filter f;
f.add_rule(address(2,0,0,1,0), address(3,0,0,0,0), ip_filter::blocked);
f.add_rule(address(1,0,0,0,0), address(2,0,0,0,0), ip_filter::blocked);
range = f.export_filter();
test_rules_invariant(range, f);
TEST_CHECK(range.size() == 3);
TEST_CHECK(std::equal(range.begin(), range.end(), expected1, &compare));
}
// **** test joining of overlapping ranges at the start ****
{
ip_filter f;
f.add_rule(address(2,0,0,1,0), address(3,0,0,0,0), ip_filter::blocked);
f.add_rule(address(1,0,0,0,0), address(2,4,0,0,0), ip_filter::blocked);
range = f.export_filter();
test_rules_invariant(range, f);
TEST_CHECK(range.size() == 3);
TEST_CHECK(std::equal(range.begin(), range.end(), expected1, &compare));
}
// **** test joining of overlapping ranges at the end ****
{
ip_filter f;
f.add_rule(address(1,0,0,0,0), address(2,4,0,0,0), ip_filter::blocked);
f.add_rule(address(2,0,0,1,0), address(3,0,0,0,0), ip_filter::blocked);
range = f.export_filter();
test_rules_invariant(range, f);
TEST_CHECK(range.size() == 3);
TEST_CHECK(std::equal(range.begin(), range.end(), expected1, &compare));
}
// **** test joining of multiple overlapping ranges 1 ****
{
ip_filter f;
f.add_rule(address(1,0,0,0,0), address(2,0,0,0,0), ip_filter::blocked);
f.add_rule(address(3,0,0,0,0), address(4,0,0,0,0), ip_filter::blocked);
f.add_rule(address(5,0,0,0,0), address(6,0,0,0,0), ip_filter::blocked);
f.add_rule(address(7,0,0,0,0), address(8,0,0,0,0), ip_filter::blocked);
f.add_rule(address(1,0,1,0,0), address(9,0,0,0,0), ip_filter::blocked);
range = f.export_filter();
test_rules_invariant(range, f);
TEST_CHECK(range.size() == 3);
ip_filter::ip_range expected[] =
{
{address(0,0,0,0,0), address(0,255,255,255,0), 0}
, {address(1,0,0,0,0), address(9,0,0,0,0), ip_filter::blocked}
, {address(9,0,0,1,0), address(255,255,255,255,0), 0}
};
TEST_CHECK(std::equal(range.begin(), range.end(), expected, &compare));
}
// **** test joining of multiple overlapping ranges 2 ****
{
ip_filter f;
f.add_rule(address(1,0,0,0,0), address(2,0,0,0,0), ip_filter::blocked);
f.add_rule(address(3,0,0,0,0), address(4,0,0,0,0), ip_filter::blocked);
f.add_rule(address(5,0,0,0,0), address(6,0,0,0,0), ip_filter::blocked);
f.add_rule(address(7,0,0,0,0), address(8,0,0,0,0), ip_filter::blocked);
f.add_rule(address(0,0,1,0,0), address(7,0,4,0,0), ip_filter::blocked);
range = f.export_filter();
test_rules_invariant(range, f);
TEST_CHECK(range.size() == 3);
ip_filter::ip_range expected[] =
{
{address(0,0,0,0,0), address(0,0,0,255,0), 0}
, {address(0,0,1,0,0), address(8,0,0,0,0), ip_filter::blocked}
, {address(8,0,0,1,0), address(255,255,255,255,0), 0}
};
TEST_CHECK(std::equal(range.begin(), range.end(), expected, &compare));
}
return 0;
}