#include #include "libtorrent/session.hpp" #include "libtorrent/hasher.hpp" #include #include #include #include #include "test.hpp" #include "libtorrent/assert.hpp" using boost::filesystem::remove_all; using boost::filesystem::create_directory; void test_sleep(int millisec) { boost::xtime xt; boost::xtime_get(&xt, boost::TIME_UTC); boost::uint64_t nanosec = (millisec % 1000) * 1000000 + xt.nsec; int sec = millisec / 1000; if (nanosec > 1000000000) { nanosec -= 1000000000; sec++; } xt.nsec = nanosec; xt.sec += sec; boost::thread::sleep(xt); } using namespace libtorrent; template boost::intrusive_ptr clone_ptr(boost::intrusive_ptr const& ptr) { return boost::intrusive_ptr(new T(*ptr)); } boost::intrusive_ptr create_torrent(std::ostream* file) { char const* tracker_url = "http://non-existent-name.com/announce"; using namespace boost::filesystem; boost::intrusive_ptr t(new torrent_info); int total_size = 2 * 1024 * 1024; t->add_file(path("temporary"), total_size); t->set_piece_size(16 * 1024); t->add_tracker(tracker_url); std::vector piece(16 * 1024); for (int i = 0; i < int(piece.size()); ++i) piece[i] = (i % 26) + 'A'; // calculate the hash for all pieces int num = t->num_pieces(); sha1_hash ph = hasher(&piece[0], piece.size()).final(); for (int i = 0; i < num; ++i) t->set_hash(i, ph); t->create_torrent(); if (file) { while (total_size > 0) { file->write(&piece[0], (std::min)(int(piece.size()), total_size)); total_size -= piece.size(); } } return t; } boost::tuple setup_transfer(session* ses1, session* ses2, session* ses3 , bool clear_files, bool use_metadata_transfer, bool connect_peers) { using namespace boost::filesystem; assert(ses1); assert(ses2); assert(ses1->id() != ses2->id()); if (ses3) assert(ses3->id() != ses2->id()); create_directory("./tmp1"); std::ofstream file("./tmp1/temporary"); boost::intrusive_ptr t = create_torrent(&file); file.close(); if (clear_files) remove_all("./tmp2/temporary"); std::cerr << "generated torrent: " << t->info_hash() << std::endl; ses1->set_severity_level(alert::debug); ses2->set_severity_level(alert::debug); // they should not use the same save dir, because the // file pool will complain if two torrents are trying to // use the same files sha1_hash info_hash = t->info_hash(); torrent_handle tor1 = ses1->add_torrent(clone_ptr(t), "./tmp1"); torrent_handle tor2; torrent_handle tor3; if (ses3) tor3 = ses3->add_torrent(clone_ptr(t), "./tmp3"); if (use_metadata_transfer) tor2 = ses2->add_torrent("http://non-existent-name.com/announce" , t->info_hash(), 0, "./tmp2"); else tor2 = ses2->add_torrent(clone_ptr(t), "./tmp2"); assert(ses1->get_torrents().size() == 1); assert(ses2->get_torrents().size() == 1); test_sleep(100); if (connect_peers) { std::cerr << "connecting peer\n"; tor1.connect_peer(tcp::endpoint(address::from_string("127.0.0.1") , ses2->listen_port())); if (ses3) { // give the other peers some time to get an initial // set of pieces before they start sharing with each-other tor3.connect_peer(tcp::endpoint( address::from_string("127.0.0.1") , ses2->listen_port())); tor3.connect_peer(tcp::endpoint( address::from_string("127.0.0.1") , ses1->listen_port())); } } return boost::make_tuple(tor1, tor2, tor3); }