forked from premiere/premiere-libtorrent
added some tests
This commit is contained in:
parent
713dad845d
commit
8a90767be8
|
@ -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();
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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 ]
|
||||
;
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue