2009-02-11 02:50:17 +01:00
/*
Copyright ( c ) 2008 , Arvid Norberg
All rights reserved .
Redistribution and use in source and binary forms , with or without
modification , are permitted provided that the following conditions
are met :
* Redistributions of source code must retain the above copyright
notice , this list of conditions and the following disclaimer .
* Redistributions in binary form must reproduce the above copyright
notice , this list of conditions and the following disclaimer in
the documentation and / or other materials provided with the distribution .
* Neither the name of the author nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission .
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS " AS IS "
AND ANY EXPRESS OR IMPLIED WARRANTIES , INCLUDING , BUT NOT LIMITED TO , THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED . IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT , INDIRECT , INCIDENTAL , SPECIAL , EXEMPLARY , OR
CONSEQUENTIAL DAMAGES ( INCLUDING , BUT NOT LIMITED TO , PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES ; LOSS OF USE , DATA , OR PROFITS ; OR BUSINESS
INTERRUPTION ) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY , WHETHER IN
CONTRACT , STRICT LIABILITY , OR TORT ( INCLUDING NEGLIGENCE OR OTHERWISE )
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE , EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE .
*/
2008-05-27 10:07:59 +02:00
# include "libtorrent/session.hpp"
# include "libtorrent/session_settings.hpp"
2009-11-26 06:45:43 +01:00
# include "libtorrent/time.hpp"
2008-05-27 10:07:59 +02:00
# include "libtorrent/hasher.hpp"
# include "libtorrent/create_torrent.hpp"
2008-12-14 20:47:02 +01:00
# include "libtorrent/alert_types.hpp"
2009-11-02 03:00:41 +01:00
# include "libtorrent/thread.hpp"
2014-11-08 19:36:54 +01:00
# include "libtorrent/torrent.hpp"
2008-05-27 10:07:59 +02:00
# include <boost/tuple/tuple.hpp>
2014-07-06 21:18:00 +02:00
# include <boost/make_shared.hpp>
2009-12-15 14:11:07 +01:00
# include <iostream>
2008-05-27 10:07:59 +02:00
# include "test.hpp"
# include "setup_transfer.hpp"
2008-08-17 13:42:57 +02:00
using namespace libtorrent ;
2014-07-06 21:18:00 +02:00
namespace lt = libtorrent ;
2008-05-27 10:07:59 +02:00
2014-12-03 05:32:50 +01:00
void test_running_torrent ( boost : : shared_ptr < torrent_info > info , boost : : int64_t file_size )
2008-08-17 13:42:57 +02:00
{
2014-07-06 21:18:00 +02:00
settings_pack pack ;
pack . set_int ( settings_pack : : alert_mask , alert : : storage_notification ) ;
pack . set_str ( settings_pack : : listen_interfaces , " 0.0.0.0:48130 " ) ;
pack . set_int ( settings_pack : : max_retry_port_bind , 10 ) ;
2014-12-31 16:51:45 +01:00
lt : : session ses ( pack ) ;
2008-05-27 10:07:59 +02:00
2013-01-28 05:57:35 +01:00
std : : vector < boost : : uint8_t > zeroes ;
zeroes . resize ( 1000 , 0 ) ;
2008-05-27 10:07:59 +02:00
add_torrent_params p ;
2015-06-10 07:22:01 +02:00
p . flags & = ~ add_torrent_params : : flag_paused ;
p . flags & = ~ add_torrent_params : : flag_auto_managed ;
2008-05-27 10:07:59 +02:00
p . ti = info ;
p . save_path = " . " ;
2013-01-28 05:57:35 +01:00
// make sure we correctly handle the case where we pass in
// more values than there are files
2013-07-17 22:21:48 +02:00
p . file_priorities = zeroes ;
2013-01-28 05:57:35 +01:00
2009-12-15 14:11:07 +01:00
error_code ec ;
torrent_handle h = ses . add_torrent ( p , ec ) ;
2014-07-06 21:18:00 +02:00
if ( ec )
{
fprintf ( stderr , " add_torrent: %s \n " , ec . message ( ) . c_str ( ) ) ;
return ;
}
2008-05-27 10:07:59 +02:00
2013-01-28 05:57:35 +01:00
std : : vector < int > ones ( info - > num_files ( ) , 1 ) ;
h . prioritize_files ( ones ) ;
2014-07-06 21:18:00 +02:00
// test_sleep(500);
2008-05-27 10:07:59 +02:00
torrent_status st = h . status ( ) ;
2014-07-06 21:18:00 +02:00
TEST_EQUAL ( st . total_wanted , file_size * 3 ) ;
TEST_EQUAL ( st . total_wanted_done , 0 ) ;
2008-05-27 10:07:59 +02:00
2014-07-06 21:18:00 +02:00
std : : vector < int > prio ( info - > num_files ( ) , 1 ) ;
2008-05-27 10:07:59 +02:00
prio [ 0 ] = 0 ;
h . prioritize_files ( prio ) ;
st = h . status ( ) ;
2014-07-06 21:18:00 +02:00
TEST_EQUAL ( st . total_wanted , file_size * 2 ) ;
TEST_EQUAL ( st . total_wanted_done , 0 ) ;
2015-05-18 01:32:13 +02:00
TEST_EQUAL ( int ( h . file_priorities ( ) . size ( ) ) , info - > num_files ( ) ) ;
2014-07-06 21:18:00 +02:00
if ( ! st . is_seeding )
{
TEST_EQUAL ( h . file_priorities ( ) [ 0 ] , 0 ) ;
if ( info - > num_files ( ) > 1 )
TEST_EQUAL ( h . file_priorities ( ) [ 1 ] , 1 ) ;
if ( info - > num_files ( ) > 2 )
TEST_EQUAL ( h . file_priorities ( ) [ 2 ] , 1 ) ;
}
2008-05-27 10:07:59 +02:00
2014-07-06 21:18:00 +02:00
if ( info - > num_files ( ) > 1 )
{
prio [ 1 ] = 0 ;
h . prioritize_files ( prio ) ;
st = h . status ( ) ;
2008-05-27 10:07:59 +02:00
2014-07-06 21:18:00 +02:00
TEST_EQUAL ( st . total_wanted , file_size ) ;
TEST_EQUAL ( st . total_wanted_done , 0 ) ;
if ( ! st . is_seeding )
{
TEST_EQUAL ( h . file_priorities ( ) . size ( ) , info - > num_files ( ) ) ;
TEST_EQUAL ( h . file_priorities ( ) [ 0 ] , 0 ) ;
if ( info - > num_files ( ) > 1 )
TEST_EQUAL ( h . file_priorities ( ) [ 1 ] , 0 ) ;
if ( info - > num_files ( ) > 2 )
TEST_EQUAL ( h . file_priorities ( ) [ 2 ] , 1 ) ;
}
}
2008-12-07 22:04:19 +01:00
if ( info - > num_pieces ( ) > 0 )
{
h . piece_priority ( 0 , 1 ) ;
st = h . status ( ) ;
2012-04-02 05:32:26 +02:00
TEST_CHECK ( st . pieces . size ( ) > 0 & & st . pieces [ 0 ] = = false ) ;
2008-12-07 22:04:19 +01:00
std : : vector < char > piece ( info - > piece_length ( ) ) ;
for ( int i = 0 ; i < int ( piece . size ( ) ) ; + + i )
piece [ i ] = ( i % 26 ) + ' A ' ;
h . add_piece ( 0 , & piece [ 0 ] ) ;
2014-07-06 21:18:00 +02:00
// wait until the piece is done writing and hashing
// TODO: wait for an alert rather than just waiting 10 seconds. This is kind of silly
test_sleep ( 2000 ) ;
2008-12-07 22:04:19 +01:00
st = h . status ( ) ;
2012-04-02 05:32:26 +02:00
TEST_CHECK ( st . pieces . size ( ) > 0 & & st . pieces [ 0 ] = = true ) ;
2008-12-14 20:47:02 +01:00
std : : cout < < " reading piece 0 " < < std : : endl ;
h . read_piece ( 0 ) ;
2015-04-03 22:15:48 +02:00
alert const * a = wait_for_alert ( ses , read_piece_alert : : alert_type , " read_piece " ) ;
TEST_CHECK ( a ) ;
read_piece_alert const * rpa = alert_cast < read_piece_alert > ( a ) ;
TEST_CHECK ( rpa ) ;
if ( rpa )
2008-12-14 20:47:02 +01:00
{
2015-04-03 22:15:48 +02:00
std : : cout < < " SUCCEEDED! " < < std : : endl ;
TEST_CHECK ( memcmp ( & piece [ 0 ] , rpa - > buffer . get ( ) , piece . size ( ) ) = = 0 ) ;
TEST_CHECK ( rpa - > size = = info - > piece_size ( 0 ) ) ;
TEST_CHECK ( rpa - > piece = = 0 ) ;
TEST_CHECK ( hasher ( & piece [ 0 ] , piece . size ( ) ) . final ( ) = = info - > hash_for_piece ( 0 ) ) ;
2008-12-14 20:47:02 +01:00
}
2008-12-07 22:04:19 +01:00
}
2008-08-17 13:42:57 +02:00
}
2015-08-14 05:06:59 +02:00
TORRENT_TEST ( long_names )
{
entry info ;
info [ " pieces " ] = " aaaaaaaaaaaaaaaaaaaa " ;
info [ " name " ] = " slightly shorter name, it's kind of sad that people started the trend of incorrectly encoding the regular name field and then adding another one with correct encoding " ;
info [ " name.utf-8 " ] = " this is a long ass name in order to try to make make_magnet_uri overflow and hopefully crash. Although, by the time you read this that particular bug should have been fixed " ;
info [ " piece length " ] = 16 * 1024 ;
info [ " length " ] = 3245 ;
entry torrent ;
torrent [ " info " ] = info ;
std : : vector < char > buf ;
bencode ( std : : back_inserter ( buf ) , torrent ) ;
error_code ec ;
boost : : shared_ptr < torrent_info > ti ( boost : : make_shared < torrent_info > ( & buf [ 0 ] , buf . size ( ) , boost : : ref ( ec ) ) ) ;
TEST_CHECK ( ! ec ) ;
}
2015-08-02 21:18:21 +02:00
TORRENT_TEST ( total_wanted )
{
file_storage fs ;
fs . add_file ( " test_torrent_dir4/tmp1 " , 1024 ) ;
fs . add_file ( " test_torrent_dir4/tmp2 " , 1024 ) ;
fs . add_file ( " test_torrent_dir4/tmp3 " , 1024 ) ;
fs . add_file ( " test_torrent_dir4/tmp4 " , 1024 ) ;
libtorrent : : create_torrent t ( fs , 1024 ) ;
std : : vector < char > tmp ;
bencode ( std : : back_inserter ( tmp ) , t . generate ( ) ) ;
error_code ec ;
2015-08-02 21:54:42 +02:00
boost : : shared_ptr < torrent_info > info ( boost : : make_shared < torrent_info > (
& tmp [ 0 ] , tmp . size ( ) , boost : : ref ( ec ) ) ) ;
2015-08-02 21:18:21 +02:00
settings_pack pack ;
pack . set_int ( settings_pack : : alert_mask , alert : : storage_notification ) ;
pack . set_str ( settings_pack : : listen_interfaces , " 0.0.0.0:48130 " ) ;
pack . set_int ( settings_pack : : max_retry_port_bind , 10 ) ;
lt : : session ses ( pack ) ;
add_torrent_params p ;
p . ti = info ;
p . save_path = " . " ;
// we just want 1 out of 4 files, 1024 out of 4096 bytes
p . file_priorities . resize ( 4 , 0 ) ;
p . file_priorities [ 1 ] = 1 ;
p . ti = info ;
torrent_handle h = ses . add_torrent ( p ) ;
torrent_status st = h . status ( ) ;
std : : cout < < " total_wanted: " < < st . total_wanted < < " : " < < 1024 < < std : : endl ;
TEST_EQUAL ( st . total_wanted , 1024 ) ;
std : : cout < < " total_wanted_done: " < < st . total_wanted_done < < " : 0 " < < std : : endl ;
TEST_EQUAL ( st . total_wanted_done , 0 ) ;
}
2015-05-30 06:31:23 +02:00
TORRENT_TEST ( torrent )
2008-08-17 13:42:57 +02:00
{
2014-07-06 21:18:00 +02:00
/* {
2008-12-07 22:04:19 +01:00
remove ( " test_torrent_dir2/tmp1 " ) ;
remove ( " test_torrent_dir2/tmp2 " ) ;
remove ( " test_torrent_dir2/tmp3 " ) ;
2008-08-17 13:42:57 +02:00
file_storage fs ;
2014-12-03 05:32:50 +01:00
boost : : int64_t file_size = 256 * 1024 ;
2008-11-30 07:10:37 +01:00
fs . add_file ( " test_torrent_dir2/tmp1 " , file_size ) ;
fs . add_file ( " test_torrent_dir2/tmp2 " , file_size ) ;
fs . add_file ( " test_torrent_dir2/tmp3 " , file_size ) ;
2013-10-20 10:06:18 +02:00
libtorrent : : create_torrent t ( fs , 128 * 1024 ) ;
2008-08-17 13:42:57 +02:00
t . add_tracker ( " http://non-existing.com/announce " ) ;
2013-10-20 10:06:18 +02:00
std : : vector < char > piece ( 128 * 1024 ) ;
2008-08-17 13:42:57 +02:00
for ( int i = 0 ; i < int ( piece . size ( ) ) ; + + i )
piece [ i ] = ( i % 26 ) + ' A ' ;
2015-05-18 07:04:55 +02:00
2008-08-17 13:42:57 +02:00
// calculate the hash for all pieces
sha1_hash ph = hasher ( & piece [ 0 ] , piece . size ( ) ) . final ( ) ;
int num = t . num_pieces ( ) ;
2008-12-07 22:04:19 +01:00
TEST_CHECK ( t . num_pieces ( ) > 0 ) ;
2008-08-17 13:42:57 +02:00
for ( int i = 0 ; i < num ; + + i )
t . set_hash ( i , ph ) ;
std : : vector < char > tmp ;
std : : back_insert_iterator < std : : vector < char > > out ( tmp ) ;
bencode ( out , t . generate ( ) ) ;
2009-12-15 14:11:07 +01:00
error_code ec ;
2014-07-06 21:18:00 +02:00
boost : : shared_ptr < torrent_info > info ( boost : : make_shared < torrent_info > ( & tmp [ 0 ] , tmp . size ( ) , boost : : ref ( ec ) , 0 ) ) ;
2008-12-07 22:04:19 +01:00
TEST_CHECK ( info - > num_pieces ( ) > 0 ) ;
2008-08-17 13:42:57 +02:00
test_running_torrent ( info , file_size ) ;
}
2014-07-06 21:18:00 +02:00
*/
2008-08-17 13:42:57 +02:00
{
file_storage fs ;
2008-11-30 07:10:37 +01:00
fs . add_file ( " test_torrent_dir2/tmp1 " , 0 ) ;
2013-10-20 10:06:18 +02:00
libtorrent : : create_torrent t ( fs , 128 * 1024 , 6 ) ;
2008-08-17 13:42:57 +02:00
std : : vector < char > tmp ;
std : : back_insert_iterator < std : : vector < char > > out ( tmp ) ;
bencode ( out , t . generate ( ) ) ;
2009-12-15 14:11:07 +01:00
error_code ec ;
2014-07-06 21:18:00 +02:00
boost : : shared_ptr < torrent_info > info ( boost : : make_shared < torrent_info > ( & tmp [ 0 ] , tmp . size ( ) , boost : : ref ( ec ) , 0 ) ) ;
2008-08-17 13:42:57 +02:00
test_running_torrent ( info , 0 ) ;
}
2008-05-27 10:07:59 +02:00
}