fixes bug where priorities where lost when force-rechecking.
[libtorrent.git] / test / test_transfer.cpp
blobe477fd052f6e67d754cbfaa7c98a1a75edfdb6dc
1 /*
3 Copyright (c) 2008, Arvid Norberg
4 All rights reserved.
6 Redistribution and use in source and binary forms, with or without
7 modification, are permitted provided that the following conditions
8 are met:
10 * Redistributions of source code must retain the above copyright
11 notice, this list of conditions and the following disclaimer.
12 * Redistributions in binary form must reproduce the above copyright
13 notice, this list of conditions and the following disclaimer in
14 the documentation and/or other materials provided with the distribution.
15 * Neither the name of the author nor the names of its
16 contributors may be used to endorse or promote products derived
17 from this software without specific prior written permission.
19 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
23 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 POSSIBILITY OF SUCH DAMAGE.
33 #include "libtorrent/session.hpp"
34 #include "libtorrent/session_settings.hpp"
35 #include "libtorrent/hasher.hpp"
36 #include "libtorrent/alert_types.hpp"
37 #include "libtorrent/bencode.hpp"
38 #include <boost/thread.hpp>
39 #include <boost/tuple/tuple.hpp>
40 #include <boost/filesystem/operations.hpp>
42 #include "test.hpp"
43 #include "setup_transfer.hpp"
45 using boost::filesystem::remove_all;
46 using boost::filesystem::exists;
47 using boost::filesystem::create_directory;
48 using namespace libtorrent;
49 using boost::tuples::ignore;
51 // test the maximum transfer rate
52 void test_rate()
54 session ses1(fingerprint("LT", 0, 1, 0, 0), std::make_pair(48575, 49000));
55 session ses2(fingerprint("LT", 0, 1, 0, 0), std::make_pair(49575, 50000));
57 torrent_handle tor1;
58 torrent_handle tor2;
60 create_directory("./tmp1_transfer");
61 std::ofstream file("./tmp1_transfer/temporary");
62 boost::intrusive_ptr<torrent_info> t = ::create_torrent(&file, 4 * 1024 * 1024, 50);
63 file.close();
65 boost::tie(tor1, tor2, ignore) = setup_transfer(&ses1, &ses2, 0
66 , true, false, true, "_transfer", 0, &t);
68 ses1.set_alert_mask(alert::all_categories & ~alert::progress_notification);
69 ses2.set_alert_mask(alert::all_categories & ~alert::progress_notification);
71 ptime start = time_now();
73 for (int i = 0; i < 40; ++i)
75 print_alerts(ses1, "ses1");
76 print_alerts(ses2, "ses2");
78 torrent_status st1 = tor1.status();
79 torrent_status st2 = tor2.status();
81 std::cerr
82 << "up: \033[33m" << st1.upload_payload_rate / 1000000.f << "MB/s "
83 << " down: \033[32m" << st2.download_payload_rate / 1000000.f << "MB/s "
84 << "\033[0m" << int(st2.progress * 100) << "% "
85 << std::endl;
87 if (st1.paused) break;
88 if (tor2.is_seed()) break;
89 test_sleep(1000);
92 TEST_CHECK(tor2.is_seed());
94 time_duration dt = time_now() - start;
96 std::cerr << "downloaded " << t->total_size() << " bytes "
97 "in " << (total_milliseconds(dt) / 1000.f) << " seconds" << std::endl;
99 std::cerr << "average download rate: " << (t->total_size() / total_milliseconds(dt))
100 << " kB/s" << std::endl;
104 void test_transfer()
106 session ses1(fingerprint("LT", 0, 1, 0, 0), std::make_pair(48075, 49000));
107 session ses2(fingerprint("LT", 0, 1, 0, 0), std::make_pair(49075, 50000));
109 #ifndef TORRENT_DISABLE_ENCRYPTION
110 pe_settings pes;
111 pes.out_enc_policy = pe_settings::forced;
112 pes.in_enc_policy = pe_settings::forced;
113 ses1.set_pe_settings(pes);
114 ses2.set_pe_settings(pes);
115 #endif
117 torrent_handle tor1;
118 torrent_handle tor2;
120 create_directory("./tmp1_transfer");
121 std::ofstream file("./tmp1_transfer/temporary");
122 boost::intrusive_ptr<torrent_info> t = ::create_torrent(&file, 16 * 1024);
123 file.close();
125 // test using piece sizes smaller than 16kB
126 boost::tie(tor1, tor2, ignore) = setup_transfer(&ses1, &ses2, 0
127 , true, false, true, "_transfer", 8 * 1024, &t);
129 // set half of the pieces to priority 0
130 int num_pieces = tor2.get_torrent_info().num_pieces();
131 std::vector<int> priorities(num_pieces, 1);
132 std::fill(priorities.begin(), priorities.begin() + num_pieces / 2, 0);
133 tor2.prioritize_pieces(priorities);
135 ses1.set_alert_mask(alert::all_categories & ~alert::progress_notification);
136 ses2.set_alert_mask(alert::all_categories & ~alert::progress_notification);
138 for (int i = 0; i < 30; ++i)
140 print_alerts(ses1, "ses1");
141 print_alerts(ses2, "ses2");
143 torrent_status st1 = tor1.status();
144 torrent_status st2 = tor2.status();
146 std::cerr
147 << "\033[32m" << int(st1.download_payload_rate / 1000.f) << "kB/s "
148 << "\033[33m" << int(st1.upload_payload_rate / 1000.f) << "kB/s "
149 << "\033[0m" << int(st1.progress * 100) << "% "
150 << st1.num_peers
151 << ": "
152 << "\033[32m" << int(st2.download_payload_rate / 1000.f) << "kB/s "
153 << "\033[31m" << int(st2.upload_payload_rate / 1000.f) << "kB/s "
154 << "\033[0m" << int(st2.progress * 100) << "% "
155 << st2.num_peers
156 << std::endl;
158 if (tor2.is_finished()) break;
160 TEST_CHECK(st1.state == torrent_status::seeding);
161 TEST_CHECK(st2.state == torrent_status::downloading);
163 test_sleep(1000);
166 TEST_CHECK(!tor2.is_seed());
167 std::cerr << "torrent is finished (50% complete)" << std::endl;
169 tor2.force_recheck();
171 for (int i = 0; i < 10; ++i)
173 test_sleep(1000);
174 print_alerts(ses2, "ses2");
175 torrent_status st2 = tor2.status();
176 std::cerr << "\033[0m" << int(st2.progress * 100) << "% " << std::endl;
177 if (st2.state != torrent_status::checking_files) break;
180 std::vector<int> priorities2 = tor2.piece_priorities();
181 TEST_CHECK(std::equal(priorities.begin(), priorities.end(), priorities2.begin()));
183 for (int i = 0; i < 5; ++i)
185 print_alerts(ses2, "ses2");
186 torrent_status st2 = tor2.status();
187 std::cerr << "\033[0m" << int(st2.progress * 100) << "% " << std::endl;
188 TEST_CHECK(st2.state == torrent_status::finished);
189 test_sleep(1000);
192 tor2.pause();
193 alert const* a = ses2.wait_for_alert(seconds(10));
194 while (a)
196 std::auto_ptr<alert> holder = ses2.pop_alert();
197 std::cerr << "ses2: " << a->message() << std::endl;
198 if (dynamic_cast<torrent_paused_alert const*>(a)) break;
199 a = ses2.wait_for_alert(seconds(10));
202 tor2.save_resume_data();
204 std::vector<char> resume_data;
205 a = ses2.wait_for_alert(seconds(10));
206 while (a)
208 std::auto_ptr<alert> holder = ses2.pop_alert();
209 std::cerr << "ses2: " << a->message() << std::endl;
210 if (dynamic_cast<save_resume_data_alert const*>(a))
212 bencode(std::back_inserter(resume_data)
213 , *dynamic_cast<save_resume_data_alert const*>(a)->resume_data);
214 break;
216 a = ses2.wait_for_alert(seconds(10));
219 std::cerr << "saved resume data" << std::endl;
221 ses2.remove_torrent(tor2);
223 std::cerr << "removed" << std::endl;
225 test_sleep(1000);
227 std::cout << "re-adding" << std::endl;
228 add_torrent_params p;
229 p.ti = t;
230 p.save_path = "./tmp2_transfer";
231 p.resume_data = &resume_data;
232 tor2 = ses2.add_torrent(p);
233 ses2.set_alert_mask(alert::all_categories & ~alert::progress_notification);
234 tor2.prioritize_pieces(priorities);
235 std::cout << "resetting priorities" << std::endl;
236 tor2.resume();
238 test_sleep(1000);
240 for (int i = 0; i < 5; ++i)
242 print_alerts(ses1, "ses1");
243 print_alerts(ses2, "ses2");
245 torrent_status st1 = tor1.status();
246 torrent_status st2 = tor2.status();
248 TEST_CHECK(st1.state == torrent_status::seeding);
249 TEST_CHECK(st2.state == torrent_status::finished);
251 test_sleep(1000);
254 TEST_CHECK(!tor2.is_seed());
256 std::fill(priorities.begin(), priorities.end(), 1);
257 tor2.prioritize_pieces(priorities);
258 std::cout << "setting priorities to 1" << std::endl;
260 for (int i = 0; i < 130; ++i)
262 print_alerts(ses1, "ses1");
263 print_alerts(ses2, "ses2");
265 torrent_status st1 = tor1.status();
266 torrent_status st2 = tor2.status();
268 std::cerr
269 << "\033[32m" << int(st1.download_payload_rate / 1000.f) << "kB/s "
270 << "\033[33m" << int(st1.upload_payload_rate / 1000.f) << "kB/s "
271 << "\033[0m" << int(st1.progress * 100) << "% "
272 << st1.num_peers
273 << ": "
274 << "\033[32m" << int(st2.download_payload_rate / 1000.f) << "kB/s "
275 << "\033[31m" << int(st2.upload_payload_rate / 1000.f) << "kB/s "
276 << "\033[0m" << int(st2.progress * 100) << "% "
277 << st2.num_peers
278 << std::endl;
280 if (tor2.is_finished()) break;
282 TEST_CHECK(st1.state == torrent_status::seeding);
283 TEST_CHECK(st2.state == torrent_status::downloading);
285 test_sleep(1000);
288 TEST_CHECK(tor2.is_seed());
291 int test_main()
293 using namespace libtorrent;
294 using namespace boost::filesystem;
296 // in case the previous run was terminated
297 try { remove_all("./tmp1_transfer"); } catch (std::exception&) {}
298 try { remove_all("./tmp2_transfer"); } catch (std::exception&) {}
300 #ifdef NDEBUG
301 // test rate only makes sense in release mode
302 test_rate();
304 try { remove_all("./tmp1_transfer"); } catch (std::exception&) {}
305 try { remove_all("./tmp2_transfer"); } catch (std::exception&) {}
306 #endif
308 test_transfer();
310 try { remove_all("./tmp1_transfer"); } catch (std::exception&) {}
311 try { remove_all("./tmp2_transfer"); } catch (std::exception&) {}
313 return 0;