forked from premiere/premiere-libtorrent
extend test_alert_manager and clean up test_fast_extension and extend a little bit
This commit is contained in:
parent
6f839a6d66
commit
55a9e98dd0
|
@ -35,6 +35,8 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
#include "libtorrent/torrent_handle.hpp"
|
||||
#include "libtorrent/alert_types.hpp"
|
||||
#include "libtorrent/extensions.hpp"
|
||||
#include "libtorrent/thread.hpp"
|
||||
#include "setup_transfer.hpp"
|
||||
|
||||
#include <boost/bind.hpp>
|
||||
#include <boost/make_shared.hpp>
|
||||
|
@ -223,6 +225,12 @@ void test_extensions()
|
|||
#endif
|
||||
}
|
||||
|
||||
void post_torrent_added(alert_manager* mgr)
|
||||
{
|
||||
test_sleep(10);
|
||||
mgr->emplace_alert<torrent_added_alert>(torrent_handle());
|
||||
}
|
||||
|
||||
void test_wait_for_alert()
|
||||
{
|
||||
alert_manager mgr(100, 0xffffffff);
|
||||
|
@ -243,30 +251,54 @@ void test_wait_for_alert()
|
|||
end = clock_type::now();
|
||||
TEST_CHECK(end - start < milliseconds(1));
|
||||
TEST_CHECK(a->type() == torrent_added_alert::alert_type);
|
||||
|
||||
std::vector<alert*> alerts;
|
||||
int num_resume = 0;
|
||||
mgr.get_all(alerts, num_resume);
|
||||
|
||||
start = clock_type::now();
|
||||
thread posting_thread(boost::bind(&post_torrent_added, &mgr));
|
||||
|
||||
a = mgr.wait_for_alert(seconds(10));
|
||||
end = clock_type::now();
|
||||
TEST_CHECK(end - start < milliseconds(500));
|
||||
TEST_CHECK(a->type() == torrent_added_alert::alert_type);
|
||||
|
||||
posting_thread.join();
|
||||
}
|
||||
|
||||
void test_queued_resume()
|
||||
{
|
||||
alert_manager mgr(100, 0xffffffff);
|
||||
|
||||
TEST_EQUAL(mgr.num_queued_resume(), 0);
|
||||
|
||||
for (int i = 0; i < 17; ++i)
|
||||
mgr.emplace_alert<torrent_added_alert>(torrent_handle());
|
||||
|
||||
TEST_EQUAL(mgr.num_queued_resume(), 0);
|
||||
|
||||
std::vector<alert*> alerts;
|
||||
int num_resume = 0;
|
||||
mgr.get_all(alerts, num_resume);
|
||||
TEST_EQUAL(num_resume, 0);
|
||||
TEST_EQUAL(alerts.size(), 17);
|
||||
|
||||
TEST_EQUAL(mgr.num_queued_resume(), 0);
|
||||
|
||||
error_code ec(boost::system::errc::no_such_file_or_directory
|
||||
, generic_category());
|
||||
|
||||
for (int i = 0; i < 2; ++i)
|
||||
mgr.emplace_alert<save_resume_data_failed_alert>(torrent_handle(), ec);
|
||||
|
||||
TEST_EQUAL(mgr.num_queued_resume(), 2);
|
||||
|
||||
mgr.get_all(alerts, num_resume);
|
||||
TEST_EQUAL(num_resume, 2);
|
||||
TEST_EQUAL(alerts.size(), 2);
|
||||
|
||||
TEST_EQUAL(mgr.num_queued_resume(), 0);
|
||||
}
|
||||
|
||||
void test_alert_mask()
|
||||
|
|
|
@ -47,12 +47,25 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
using namespace libtorrent;
|
||||
namespace lt = libtorrent;
|
||||
|
||||
void log(char const* fmt, ...)
|
||||
{
|
||||
va_list v;
|
||||
va_start(v, fmt);
|
||||
|
||||
char buf[1024];
|
||||
vsnprintf(buf, sizeof(buf), fmt, v);
|
||||
va_end(v);
|
||||
|
||||
fprintf(stderr, "\x1b[1m\x1b[36m%s: %s\x1b[0m\n"
|
||||
, aux::time_now_string(), buf);
|
||||
}
|
||||
|
||||
void print_session_log(lt::session& ses)
|
||||
{
|
||||
print_alerts(ses, "ses", true, true);
|
||||
}
|
||||
|
||||
int read_message(stream_socket& s, char* buffer)
|
||||
int read_message(stream_socket& s, char* buffer, int max_size)
|
||||
{
|
||||
using namespace libtorrent::detail;
|
||||
error_code ec;
|
||||
|
@ -65,6 +78,12 @@ int read_message(stream_socket& s, char* buffer)
|
|||
}
|
||||
char* ptr = buffer;
|
||||
int length = read_int32(ptr);
|
||||
if (length > max_size)
|
||||
{
|
||||
log("message size: %d", length);
|
||||
TEST_ERROR("message size exceeds max limt");
|
||||
return -1;
|
||||
}
|
||||
|
||||
libtorrent::asio::read(s, libtorrent::asio::buffer(buffer, length)
|
||||
, libtorrent::asio::transfer_all(), ec);
|
||||
|
@ -127,6 +146,11 @@ void print_message(char const* buffer, int len)
|
|||
int index = detail::read_int32(ptr);
|
||||
snprintf(extra, sizeof(extra), "p: %d", index);
|
||||
}
|
||||
else if (msg == 20 && len > 4 && buffer[1] == 0 )
|
||||
{
|
||||
snprintf(extra, sizeof(extra), "%s"
|
||||
, bdecode(buffer + 2, buffer + len).to_string().c_str());
|
||||
}
|
||||
}
|
||||
|
||||
log("<== %s %s", message, extra);
|
||||
|
@ -134,7 +158,7 @@ void print_message(char const* buffer, int len)
|
|||
|
||||
void send_allow_fast(stream_socket& s, int piece)
|
||||
{
|
||||
log(" ==> allow fast: %d", piece);
|
||||
log("==> allow fast: %d", piece);
|
||||
using namespace libtorrent::detail;
|
||||
char msg[] = "\0\0\0\x05\x11\0\0\0\0";
|
||||
char* ptr = msg + 5;
|
||||
|
@ -147,7 +171,7 @@ void send_allow_fast(stream_socket& s, int piece)
|
|||
|
||||
void send_suggest_piece(stream_socket& s, int piece)
|
||||
{
|
||||
log(" ==> suggest piece: %d", piece);
|
||||
log("==> suggest piece: %d", piece);
|
||||
using namespace libtorrent::detail;
|
||||
char msg[] = "\0\0\0\x05\x0d\0\0\0\0";
|
||||
char* ptr = msg + 5;
|
||||
|
@ -160,7 +184,7 @@ void send_suggest_piece(stream_socket& s, int piece)
|
|||
|
||||
void send_keepalive(stream_socket& s)
|
||||
{
|
||||
log(" ==> keepalive");
|
||||
log("==> keepalive");
|
||||
char msg[] = "\0\0\0\0";
|
||||
error_code ec;
|
||||
libtorrent::asio::write(s, libtorrent::asio::buffer(msg, 4)
|
||||
|
@ -170,7 +194,7 @@ void send_keepalive(stream_socket& s)
|
|||
|
||||
void send_unchoke(stream_socket& s)
|
||||
{
|
||||
log(" ==> unchoke");
|
||||
log("==> unchoke");
|
||||
char msg[] = "\0\0\0\x01\x01";
|
||||
error_code ec;
|
||||
libtorrent::asio::write(s, libtorrent::asio::buffer(msg, 5)
|
||||
|
@ -180,7 +204,7 @@ void send_unchoke(stream_socket& s)
|
|||
|
||||
void send_have_all(stream_socket& s)
|
||||
{
|
||||
log(" ==> have_all");
|
||||
log("==> have_all");
|
||||
char msg[] = "\0\0\0\x01\x0e"; // have_all
|
||||
error_code ec;
|
||||
libtorrent::asio::write(s, libtorrent::asio::buffer(msg, 5)
|
||||
|
@ -190,7 +214,7 @@ void send_have_all(stream_socket& s)
|
|||
|
||||
void send_have_none(stream_socket& s)
|
||||
{
|
||||
log(" ==> have_none");
|
||||
log("==> have_none");
|
||||
char msg[] = "\0\0\0\x01\x0f"; // have_none
|
||||
error_code ec;
|
||||
libtorrent::asio::write(s, libtorrent::asio::buffer(msg, 5)
|
||||
|
@ -209,7 +233,7 @@ void send_bitfield(stream_socket& s, char const* bits)
|
|||
char* ptr = msg;
|
||||
write_int32(packet_size-4, ptr);
|
||||
write_int8(5, ptr);
|
||||
log(" ==> bitfield [%s]");
|
||||
log("==> bitfield [%s]");
|
||||
for (int i = 0; i < num_pieces; ++i)
|
||||
{
|
||||
ptr[i/8] |= (bits[i] == '1' ? 1 : 0) << i % 8;
|
||||
|
@ -225,7 +249,7 @@ void do_handshake(stream_socket& s, sha1_hash const& ih, char* buffer)
|
|||
char handshake[] = "\x13" "BitTorrent protocol\0\0\0\0\0\x10\0\x04"
|
||||
" " // space for info-hash
|
||||
"aaaaaaaaaaaaaaaaaaaa"; // peer-id
|
||||
log(" ==> handshake");
|
||||
log("==> handshake");
|
||||
error_code ec;
|
||||
std::memcpy(handshake + 28, ih.begin(), 20);
|
||||
libtorrent::asio::write(s, libtorrent::asio::buffer(handshake, sizeof(handshake) - 1)
|
||||
|
@ -244,7 +268,7 @@ void do_handshake(stream_socket& s, sha1_hash const& ih, char* buffer)
|
|||
TEST_ERROR(ec.message());
|
||||
return;
|
||||
}
|
||||
log(" <== handshake");
|
||||
log("<== handshake");
|
||||
|
||||
TEST_CHECK(buffer[0] == 19);
|
||||
TEST_CHECK(std::memcmp(buffer + 1, "BitTorrent protocol", 19) == 0);
|
||||
|
@ -291,6 +315,80 @@ void send_extension_handshake(stream_socket& s, entry const& e)
|
|||
if (ec) TEST_ERROR(ec.message());
|
||||
}
|
||||
|
||||
entry read_extension_handshake(stream_socket& s, char* recv_buffer, int size)
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
int len = read_message(s, recv_buffer, size);
|
||||
if (len == -1)
|
||||
{
|
||||
TEST_ERROR("failed to read message");
|
||||
return entry();
|
||||
}
|
||||
print_message(recv_buffer, len);
|
||||
|
||||
if (len < 4) continue;
|
||||
int msg = recv_buffer[0];
|
||||
if (msg != 20) continue;
|
||||
int extmsg = recv_buffer[1];
|
||||
if (extmsg != 0) continue;
|
||||
|
||||
return bdecode(recv_buffer + 2, recv_buffer + len);
|
||||
}
|
||||
}
|
||||
|
||||
void send_ut_metadata_msg(stream_socket& s, int ut_metadata_msg, int type, int piece)
|
||||
{
|
||||
std::vector<char> buf;
|
||||
|
||||
// reserve space for the message header
|
||||
// uint32: packet-length
|
||||
// uint8: 20 (extension message)
|
||||
// uint8: <ut_metadata_msg> (ut_metadata)
|
||||
buf.resize(4 + 1 + 1);
|
||||
|
||||
entry e;
|
||||
e["msg_type"] = type;
|
||||
e["piece"] = piece;
|
||||
bencode(std::back_inserter(buf), e);
|
||||
|
||||
using namespace libtorrent::detail;
|
||||
|
||||
char* ptr = &buf[0];
|
||||
write_uint32(buf.size() - 4, ptr);
|
||||
write_uint8(20, ptr);
|
||||
write_uint8(ut_metadata_msg, ptr);
|
||||
|
||||
log("==> ut_metadata [ type: %d piece: %d ]", type, piece);
|
||||
|
||||
error_code ec;
|
||||
libtorrent::asio::write(s, libtorrent::asio::buffer(&buf[0], buf.size())
|
||||
, libtorrent::asio::transfer_all(), ec);
|
||||
if (ec) TEST_ERROR(ec.message());
|
||||
}
|
||||
|
||||
entry read_ut_metadata_msg(stream_socket& s, char* recv_buffer, int size)
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
int len = read_message(s, recv_buffer, size);
|
||||
if (len == -1)
|
||||
{
|
||||
TEST_ERROR("failed to read message");
|
||||
return entry();
|
||||
}
|
||||
print_message(recv_buffer, len);
|
||||
|
||||
if (len < 4) continue;
|
||||
int msg = recv_buffer[0];
|
||||
if (msg != 20) continue;
|
||||
int extmsg = recv_buffer[1];
|
||||
if (extmsg != 1) continue;
|
||||
|
||||
return bdecode(recv_buffer + 2, recv_buffer + len);
|
||||
}
|
||||
}
|
||||
|
||||
boost::shared_ptr<torrent_info> setup_peer(stream_socket& s, sha1_hash& ih
|
||||
, boost::shared_ptr<lt::session>& ses, torrent_handle* th = NULL)
|
||||
{
|
||||
|
@ -328,7 +426,7 @@ boost::shared_ptr<torrent_info> setup_peer(stream_socket& s, sha1_hash& ih
|
|||
// rejected aren't requested again
|
||||
void test_reject_fast()
|
||||
{
|
||||
std::cerr << " === test reject ===" << std::endl;
|
||||
std::cerr << "\n === test reject ===\n" << std::endl;
|
||||
|
||||
sha1_hash ih;
|
||||
boost::shared_ptr<lt::session> ses;
|
||||
|
@ -355,7 +453,7 @@ void test_reject_fast()
|
|||
while (!allowed_fast.empty())
|
||||
{
|
||||
print_session_log(*ses);
|
||||
int len = read_message(s, recv_buffer);
|
||||
int len = read_message(s, recv_buffer, sizeof(recv_buffer));
|
||||
print_message(recv_buffer, len);
|
||||
int msg = recv_buffer[0];
|
||||
if (msg != 0x6) continue;
|
||||
|
@ -372,7 +470,7 @@ void test_reject_fast()
|
|||
// send reject request
|
||||
recv_buffer[0] = 0x10;
|
||||
error_code ec;
|
||||
log(" ==> reject");
|
||||
log("==> reject");
|
||||
libtorrent::asio::write(s, libtorrent::asio::buffer("\0\0\0\x0d", 4)
|
||||
, libtorrent::asio::transfer_all(), ec);
|
||||
if (ec)
|
||||
|
@ -396,7 +494,7 @@ void test_reject_fast()
|
|||
|
||||
void test_respect_suggest()
|
||||
{
|
||||
std::cerr << " === test suggest ===" << std::endl;
|
||||
std::cerr << "\n === test suggest ===\n" << std::endl;
|
||||
|
||||
sha1_hash ih;
|
||||
boost::shared_ptr<lt::session> ses;
|
||||
|
@ -430,7 +528,7 @@ void test_respect_suggest()
|
|||
while (!suggested.empty() && fail_counter > 0)
|
||||
{
|
||||
print_session_log(*ses);
|
||||
int len = read_message(s, recv_buffer);
|
||||
int len = read_message(s, recv_buffer, sizeof(recv_buffer));
|
||||
print_message(recv_buffer, len);
|
||||
int msg = recv_buffer[0];
|
||||
fail_counter--;
|
||||
|
@ -448,7 +546,7 @@ void test_respect_suggest()
|
|||
// send reject request
|
||||
recv_buffer[0] = 0x10;
|
||||
error_code ec;
|
||||
log(" ==> reject");
|
||||
log("==> reject");
|
||||
libtorrent::asio::write(s, libtorrent::asio::buffer("\0\0\0\x0d", 4)
|
||||
, libtorrent::asio::transfer_all(), ec);
|
||||
if (ec)
|
||||
|
@ -474,7 +572,7 @@ void test_respect_suggest()
|
|||
|
||||
void test_multiple_bitfields()
|
||||
{
|
||||
std::cerr << " === test multiple bitfields ===" << std::endl;
|
||||
std::cerr << "\n === test multiple bitfields ===\n" << std::endl;
|
||||
|
||||
sha1_hash ih;
|
||||
boost::shared_ptr<lt::session> ses;
|
||||
|
@ -508,7 +606,7 @@ void test_multiple_bitfields()
|
|||
|
||||
void test_multiple_have_all()
|
||||
{
|
||||
std::cerr << " === test multiple have_all ===" << std::endl;
|
||||
std::cerr << "\n === test multiple have_all ===\n" << std::endl;
|
||||
|
||||
sha1_hash ih;
|
||||
boost::shared_ptr<lt::session> ses;
|
||||
|
@ -541,7 +639,7 @@ void test_dont_have()
|
|||
{
|
||||
using namespace libtorrent::detail;
|
||||
|
||||
std::cerr << " === test dont_have ===" << std::endl;
|
||||
std::cerr << "\n === test dont_have ===\n" << std::endl;
|
||||
|
||||
sha1_hash ih;
|
||||
torrent_handle th;
|
||||
|
@ -574,7 +672,7 @@ void test_dont_have()
|
|||
{
|
||||
print_session_log(*ses);
|
||||
|
||||
int len = read_message(s, recv_buffer);
|
||||
int len = read_message(s, recv_buffer, sizeof(recv_buffer));
|
||||
print_message(recv_buffer, len);
|
||||
if (len == 0) continue;
|
||||
int msg = recv_buffer[0];
|
||||
|
@ -643,7 +741,7 @@ void test_invalid_metadata_requests()
|
|||
{
|
||||
using namespace libtorrent::detail;
|
||||
|
||||
std::cerr << " === test invalid metadata ===" << std::endl;
|
||||
std::cerr << "\n === test invalid metadata ===\n" << std::endl;
|
||||
|
||||
sha1_hash ih;
|
||||
boost::shared_ptr<lt::session> ses;
|
||||
|
@ -661,13 +759,37 @@ void test_invalid_metadata_requests()
|
|||
extensions["m"]["ut_metadata"] = 1;
|
||||
send_extension_handshake(s, extensions);
|
||||
|
||||
#error read messages until we get the extension handshake back. extract the \
|
||||
message code for ut_metadata
|
||||
extensions = read_extension_handshake(s, recv_buffer, sizeof(recv_buffer));
|
||||
|
||||
int ut_metadata = extensions["m"]["ut_metadata"].integer();
|
||||
|
||||
log("ut_metadata: %d", ut_metadata);
|
||||
|
||||
// 0 = request
|
||||
// 1 = piece
|
||||
// 2 = dont-have
|
||||
// first send an invalid request
|
||||
send_ut_metadata_msg(s, ut_metadata, 0, 1);
|
||||
|
||||
// then send a valid one. If we get a response to the second one,
|
||||
// we assume we were not disconnected because of the invalid one
|
||||
send_ut_metadata_msg(s, ut_metadata, 0, 0);
|
||||
|
||||
entry ut_metadata_msg = read_ut_metadata_msg(s, recv_buffer
|
||||
, sizeof(recv_buffer));
|
||||
|
||||
// the first response should be "dont-have"
|
||||
TEST_EQUAL(ut_metadata_msg["msg_type"].integer(), 2);
|
||||
TEST_EQUAL(ut_metadata_msg["piece"].integer(), 1);
|
||||
|
||||
ut_metadata_msg = read_ut_metadata_msg(s, recv_buffer
|
||||
, sizeof(recv_buffer));
|
||||
|
||||
// the second response should be the payload
|
||||
TEST_EQUAL(ut_metadata_msg["msg_type"].integer(), 1);
|
||||
TEST_EQUAL(ut_metadata_msg["piece"].integer(), 0);
|
||||
|
||||
test_sleep(1000);
|
||||
print_session_log(*ses);
|
||||
|
||||
TEST_ERROR("test");
|
||||
}
|
||||
|
||||
int test_main()
|
||||
|
|
Loading…
Reference in New Issue