3 Copyright (c) 2008, Arvid Norberg
6 Redistribution and use in source and binary forms, with or without
7 modification, are permitted provided that the following conditions
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>
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
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));
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);
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();
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) << "% "
87 if (st1
.paused
) break;
88 if (tor2
.is_seed()) break;
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
;
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
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
);
120 create_directory("./tmp1_transfer");
121 std::ofstream
file("./tmp1_transfer/temporary");
122 boost::intrusive_ptr
<torrent_info
> t
= ::create_torrent(&file
, 16 * 1024);
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();
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) << "% "
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) << "% "
158 if (tor2
.is_finished()) break;
160 TEST_CHECK(st1
.state
== torrent_status::seeding
);
161 TEST_CHECK(st2
.state
== torrent_status::downloading
);
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
)
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
);
193 alert
const* a
= ses2
.wait_for_alert(seconds(10));
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));
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
);
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
;
227 std::cout
<< "re-adding" << std::endl
;
228 add_torrent_params p
;
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
;
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
);
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();
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) << "% "
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) << "% "
280 if (tor2
.is_finished()) break;
282 TEST_CHECK(st1
.state
== torrent_status::seeding
);
283 TEST_CHECK(st2
.state
== torrent_status::downloading
);
288 TEST_CHECK(tor2
.is_seed());
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
&) {}
301 // test rate only makes sense in release mode
304 try { remove_all("./tmp1_transfer"); } catch (std::exception
&) {}
305 try { remove_all("./tmp2_transfer"); } catch (std::exception
&) {}
310 try { remove_all("./tmp1_transfer"); } catch (std::exception
&) {}
311 try { remove_all("./tmp2_transfer"); } catch (std::exception
&) {}