// proxy: 0=none, 1=socks4, 2=socks5, 3=socks5_pw 4=http 5=http_pw void test_transfer(session& ses, boost::intrusive_ptr<torrent_info> torrent_file , int proxy, int port, char const* protocol, bool url_seed , bool chunked_encoding, bool test_ban, bool keepalive, bool proxy_peers) { using namespace libtorrent; std::string save_path = "tmp2_web_seed"; save_path += proxy_name[proxy]; error_code ec; remove_all(save_path, ec); static char const* test_name[] = {"no", "SOCKS4", "SOCKS5", "SOCKS5 password", "HTTP", "HTTP password"}; fprintf(stderr, "\n\n ==== TESTING === proxy: %s ==== protocol: %s " "==== seed: %s === transfer-encoding: %s === corruption: %s " "==== keepalive: %s\n\n\n" , test_name[proxy], protocol, url_seed ? "URL seed" : "HTTP seed" , chunked_encoding ? "chunked": "none", test_ban ? "yes" : "no" , keepalive ? "yes" : "no"); proxy_settings ps; if (proxy) { ps.port = start_proxy(proxy); ps.hostname = "127.0.0.1"; ps.username = "******"; ps.password = "******"; ps.type = (proxy_settings::proxy_type)proxy; ps.proxy_peer_connections = proxy_peers; ses.set_proxy(ps); } else { ps.port = 0; ps.hostname.clear(); ps.username.clear(); ps.password.clear(); ps.type = proxy_settings::none; ps.proxy_peer_connections = proxy_peers; ses.set_proxy(ps); } add_torrent_params p; p.flags &= ~add_torrent_params::flag_paused; p.flags &= ~add_torrent_params::flag_auto_managed; p.ti = torrent_file; p.save_path = save_path; #ifndef TORRENT_NO_DEPRECATE p.storage_mode = storage_mode_compact; #endif torrent_handle th = ses.add_torrent(p, ec); std::vector<announce_entry> empty; th.replace_trackers(empty); const size_type total_size = torrent_file->total_size(); float rate_sum = 0.f; float ses_rate_sum = 0.f; cache_status cs; file_storage const& fs = torrent_file->files(); int pad_file_size = 0; for (int i = 0; i < fs.num_files(); ++i) { file_entry f = fs.at(i); if (f.pad_file) pad_file_size += f.size; } peer_disconnects = 0; for (int i = 0; i < 40; ++i) { torrent_status s = th.status(); session_status ss = ses.status(); rate_sum += s.download_payload_rate; ses_rate_sum += ss.payload_download_rate; cs = ses.get_cache_status(); if (cs.blocks_read < 1) cs.blocks_read = 1; if (cs.blocks_written < 1) cs.blocks_written = 1; print_ses_rate(i / 10.f, &s, NULL); print_alerts(ses, " >> ses", test_ban, false, false, &on_alert); if (test_ban && th.url_seeds().empty() && th.http_seeds().empty()) { // when we don't have any web seeds left, we know we successfully banned it break; } // if the web seed connection is disconnected, we're going to fail // the test. make sure to do so quickly if (keepalive && peer_disconnects >= 1) break; if (s.is_seeding /* && ss.download_rate == 0.f*/) { TEST_EQUAL(s.total_payload_download - s.total_redundant_bytes, total_size - pad_file_size); break; } test_sleep(100); } // for test_ban tests, make sure we removed // the url seed (i.e. banned it) TEST_CHECK(!test_ban || (th.url_seeds().empty() && th.http_seeds().empty())); if (!test_ban) { torrent_status st = th.status(); TEST_EQUAL(st.is_seeding, true); if (st.is_seeding) { for (int i = 0; i < 50; ++i) { cs = ses.get_cache_status(); if (cs.read_cache_size == 0 && cs.total_used_buffers == 0) break; fprintf(stderr, "cache_size: %d/%d\n", int(cs.read_cache_size), int(cs.total_used_buffers)); test_sleep(100); } TEST_EQUAL(cs.read_cache_size, 0); TEST_EQUAL(cs.total_used_buffers, 0); } } std::cerr << "total_size: " << total_size << " rate_sum: " << rate_sum << " session_rate_sum: " << ses_rate_sum << " session total download: " << ses.status().total_payload_download << " torrent total download: " << th.status().total_payload_download << " redundant: " << th.status().total_redundant_bytes << std::endl; // the rates for each second should sum up to the total, with a 10% error margin // TEST_CHECK(fabs(rate_sum - total_size) < total_size * .1f); // TEST_CHECK(fabs(ses_rate_sum - total_size) < total_size * .1f); // if test_ban is true, we're not supposed to have completed the download // otherwise, we are supposed to have TEST_CHECK(th.status().is_seeding == !test_ban); if (proxy) stop_proxy(ps.port); ses.remove_torrent(th); // call this to synchronize with the network thread ses.status(); print_alerts(ses, " >> ses", true, true, false, &on_alert, true); TEST_CHECK(exists(combine_path(save_path, torrent_file->files().file_path(0))) || test_ban); remove_all(save_path, ec); }