1 | /* |
---|
2 | * This file Copyright (C) 2013-2014 Mnemosyne LLC |
---|
3 | * |
---|
4 | * It may be used under the GNU GPL versions 2 or 3 |
---|
5 | * or any future license endorsed by Mnemosyne LLC. |
---|
6 | * |
---|
7 | * $Id: rename-test.c 14366 2014-12-07 10:42:12Z mikedld $ |
---|
8 | */ |
---|
9 | |
---|
10 | #include <assert.h> |
---|
11 | #include <errno.h> |
---|
12 | #include <stdio.h> /* fopen() */ |
---|
13 | #include <string.h> /* strcmp() */ |
---|
14 | |
---|
15 | #include <unistd.h> /* sync() */ |
---|
16 | |
---|
17 | #include "transmission.h" |
---|
18 | #include "crypto-utils.h" |
---|
19 | #include "file.h" |
---|
20 | #include "resume.h" |
---|
21 | #include "torrent.h" /* tr_isTorrent() */ |
---|
22 | #include "variant.h" |
---|
23 | |
---|
24 | #include "libtransmission-test.h" |
---|
25 | |
---|
26 | /*** |
---|
27 | **** |
---|
28 | ***/ |
---|
29 | |
---|
30 | static tr_session * session = NULL; |
---|
31 | |
---|
32 | #define check_have_none(tor, totalSize) \ |
---|
33 | do { \ |
---|
34 | const tr_stat * st = tr_torrentStat(tor); \ |
---|
35 | check_int_eq (TR_STATUS_STOPPED, st->activity); \ |
---|
36 | check_int_eq (TR_STAT_OK, st->error); \ |
---|
37 | check_int_eq (totalSize, st->sizeWhenDone); \ |
---|
38 | check_int_eq (totalSize, st->leftUntilDone); \ |
---|
39 | check_int_eq (totalSize, tor->info.totalSize); \ |
---|
40 | check_int_eq (0, st->haveValid); \ |
---|
41 | } while (0) |
---|
42 | |
---|
43 | static bool |
---|
44 | testFileExistsAndConsistsOfThisString (const tr_torrent * tor, tr_file_index_t fileIndex, const char * str) |
---|
45 | { |
---|
46 | char * path; |
---|
47 | const size_t str_len = strlen (str); |
---|
48 | bool success = false; |
---|
49 | |
---|
50 | path = tr_torrentFindFile (tor, fileIndex); |
---|
51 | if (path != NULL) |
---|
52 | { |
---|
53 | uint8_t * contents; |
---|
54 | size_t contents_len; |
---|
55 | |
---|
56 | assert (tr_sys_path_exists (path, NULL)); |
---|
57 | |
---|
58 | contents = tr_loadFile (path, &contents_len); |
---|
59 | |
---|
60 | success = (str_len == contents_len) |
---|
61 | && (!memcmp (contents, str, contents_len)); |
---|
62 | |
---|
63 | tr_free (contents); |
---|
64 | tr_free (path); |
---|
65 | } |
---|
66 | |
---|
67 | return success; |
---|
68 | } |
---|
69 | |
---|
70 | static void |
---|
71 | onRenameDone (tr_torrent * tor UNUSED, const char * oldpath UNUSED, const char * newname UNUSED, int error, void * user_data) |
---|
72 | { |
---|
73 | *(int*)user_data = error; |
---|
74 | } |
---|
75 | |
---|
76 | static int |
---|
77 | torrentRenameAndWait (tr_torrent * tor, |
---|
78 | const char * oldpath, |
---|
79 | const char * newname) |
---|
80 | { |
---|
81 | int error = -1; |
---|
82 | tr_torrentRenamePath (tor, oldpath, newname, onRenameDone, &error); |
---|
83 | do { |
---|
84 | tr_wait_msec (10); |
---|
85 | } while (error == -1); |
---|
86 | return error; |
---|
87 | } |
---|
88 | |
---|
89 | /*** |
---|
90 | **** |
---|
91 | ***/ |
---|
92 | |
---|
93 | static void |
---|
94 | create_single_file_torrent_contents (const char * top) |
---|
95 | { |
---|
96 | char * path = tr_buildPath (top, "hello-world.txt", NULL); |
---|
97 | libtest_create_file_with_string_contents (path, "hello, world!\n"); |
---|
98 | tr_free (path); |
---|
99 | } |
---|
100 | |
---|
101 | static tr_torrent * |
---|
102 | create_torrent_from_base64_metainfo (tr_ctor * ctor, const char * metainfo_base64) |
---|
103 | { |
---|
104 | int err; |
---|
105 | size_t metainfo_len; |
---|
106 | char * metainfo; |
---|
107 | tr_torrent * tor; |
---|
108 | |
---|
109 | /* create the torrent ctor */ |
---|
110 | metainfo = tr_base64_decode_str (metainfo_base64, &metainfo_len); |
---|
111 | assert (metainfo != NULL); |
---|
112 | assert (metainfo_len > 0); |
---|
113 | tr_ctorSetMetainfo (ctor, (uint8_t*)metainfo, metainfo_len); |
---|
114 | tr_ctorSetPaused (ctor, TR_FORCE, true); |
---|
115 | |
---|
116 | /* create the torrent */ |
---|
117 | err = 0; |
---|
118 | tor = tr_torrentNew (ctor, &err, NULL); |
---|
119 | assert (!err); |
---|
120 | |
---|
121 | /* cleanup */ |
---|
122 | tr_free (metainfo); |
---|
123 | return tor; |
---|
124 | } |
---|
125 | |
---|
126 | static int |
---|
127 | test_single_filename_torrent (void) |
---|
128 | { |
---|
129 | uint64_t loaded; |
---|
130 | tr_torrent * tor; |
---|
131 | char * tmpstr; |
---|
132 | const size_t totalSize = 14; |
---|
133 | tr_ctor * ctor; |
---|
134 | const tr_stat * st; |
---|
135 | |
---|
136 | /* this is a single-file torrent whose file is hello-world.txt, holding the string "hello, world!" */ |
---|
137 | ctor = tr_ctorNew (session); |
---|
138 | tor = create_torrent_from_base64_metainfo (ctor, |
---|
139 | "ZDEwOmNyZWF0ZWQgYnkyNTpUcmFuc21pc3Npb24vMi42MSAoMTM0MDcpMTM6Y3JlYXRpb24gZGF0" |
---|
140 | "ZWkxMzU4NTQ5MDk4ZTg6ZW5jb2Rpbmc1OlVURi04NDppbmZvZDY6bGVuZ3RoaTE0ZTQ6bmFtZTE1" |
---|
141 | "OmhlbGxvLXdvcmxkLnR4dDEyOnBpZWNlIGxlbmd0aGkzMjc2OGU2OnBpZWNlczIwOukboJcrkFUY" |
---|
142 | "f6LvqLXBVvSHqCk6Nzpwcml2YXRlaTBlZWU="); |
---|
143 | check (tr_isTorrent (tor)); |
---|
144 | |
---|
145 | /* sanity check the info */ |
---|
146 | check_int_eq (1, tor->info.fileCount); |
---|
147 | check_streq ("hello-world.txt", tor->info.files[0].name); |
---|
148 | check (!tor->info.files[0].is_renamed); |
---|
149 | |
---|
150 | /* sanity check the (empty) stats */ |
---|
151 | libttest_blockingTorrentVerify (tor); |
---|
152 | check_have_none (tor, totalSize); |
---|
153 | |
---|
154 | create_single_file_torrent_contents (tor->currentDir); |
---|
155 | |
---|
156 | /* sanity check the stats again, now that we've added the file */ |
---|
157 | libttest_blockingTorrentVerify (tor); |
---|
158 | st = tr_torrentStat (tor); |
---|
159 | check_int_eq (TR_STATUS_STOPPED, st->activity); |
---|
160 | check_int_eq (TR_STAT_OK, st->error); |
---|
161 | check_int_eq (0, st->leftUntilDone); |
---|
162 | check_int_eq (0, st->haveUnchecked); |
---|
163 | check_int_eq (0, st->desiredAvailable); |
---|
164 | check_int_eq (totalSize, st->sizeWhenDone); |
---|
165 | check_int_eq (totalSize, st->haveValid); |
---|
166 | |
---|
167 | /** |
---|
168 | *** okay! we've finally put together all the scaffolding to test |
---|
169 | *** renaming a single-file torrent |
---|
170 | **/ |
---|
171 | |
---|
172 | /* confirm that bad inputs get caught */ |
---|
173 | |
---|
174 | check_int_eq (EINVAL, torrentRenameAndWait (tor, "hello-world.txt", NULL)); |
---|
175 | check_int_eq (EINVAL, torrentRenameAndWait (tor, "hello-world.txt", "")); |
---|
176 | check_int_eq (EINVAL, torrentRenameAndWait (tor, "hello-world.txt", ".")); |
---|
177 | check_int_eq (EINVAL, torrentRenameAndWait (tor, "hello-world.txt", "..")); |
---|
178 | check_int_eq (0, torrentRenameAndWait (tor, "hello-world.txt", "hello-world.txt")); |
---|
179 | check_int_eq (EINVAL, torrentRenameAndWait (tor, "hello-world.txt", "hello/world.txt")); |
---|
180 | |
---|
181 | check (!tor->info.files[0].is_renamed); |
---|
182 | check_streq ("hello-world.txt", tor->info.files[0].name); |
---|
183 | |
---|
184 | /*** |
---|
185 | **** Now try a rename that should succeed |
---|
186 | ***/ |
---|
187 | |
---|
188 | tmpstr = tr_buildPath (tor->currentDir, "hello-world.txt", NULL); |
---|
189 | check (tr_sys_path_exists (tmpstr, NULL)); |
---|
190 | check_streq ("hello-world.txt", tr_torrentName(tor)); |
---|
191 | check_int_eq (0, torrentRenameAndWait (tor, tor->info.name, "foobar")); |
---|
192 | check (!tr_sys_path_exists (tmpstr, NULL)); /* confirm the old filename can't be found */ |
---|
193 | tr_free (tmpstr); |
---|
194 | check (tor->info.files[0].is_renamed); /* confirm the file's 'renamed' flag is set */ |
---|
195 | check_streq ("foobar", tr_torrentName(tor)); /* confirm the torrent's name is now 'foobar' */ |
---|
196 | check_streq ("foobar", tor->info.files[0].name); /* confirm the file's name is now 'foobar' in our struct */ |
---|
197 | check (strstr (tor->info.torrent, "foobar") == NULL); /* confirm the name in the .torrent file hasn't changed */ |
---|
198 | tmpstr = tr_buildPath (tor->currentDir, "foobar", NULL); |
---|
199 | check (tr_sys_path_exists (tmpstr, NULL)); /* confirm the file's name is now 'foobar' on the disk */ |
---|
200 | tr_free (tmpstr); |
---|
201 | check (testFileExistsAndConsistsOfThisString (tor, 0, "hello, world!\n")); /* confirm the contents are right */ |
---|
202 | |
---|
203 | /* (while it's renamed: confirm that the .resume file remembers the changes) */ |
---|
204 | tr_torrentSaveResume (tor); |
---|
205 | sync (); |
---|
206 | loaded = tr_torrentLoadResume (tor, ~0, ctor); |
---|
207 | check_streq ("foobar", tr_torrentName(tor)); |
---|
208 | check ((loaded & TR_FR_NAME) != 0); |
---|
209 | |
---|
210 | /*** |
---|
211 | **** ...and rename it back again |
---|
212 | ***/ |
---|
213 | |
---|
214 | tmpstr = tr_buildPath (tor->currentDir, "foobar", NULL); |
---|
215 | check (tr_sys_path_exists (tmpstr, NULL)); |
---|
216 | check_int_eq (0, torrentRenameAndWait (tor, "foobar", "hello-world.txt")); |
---|
217 | check (!tr_sys_path_exists (tmpstr, NULL)); |
---|
218 | check (tor->info.files[0].is_renamed); |
---|
219 | check_streq ("hello-world.txt", tor->info.files[0].name); |
---|
220 | check_streq ("hello-world.txt", tr_torrentName(tor)); |
---|
221 | tr_free (tmpstr); |
---|
222 | check (testFileExistsAndConsistsOfThisString (tor, 0, "hello, world!\n")); |
---|
223 | |
---|
224 | /* cleanup */ |
---|
225 | tr_ctorFree (ctor); |
---|
226 | tr_torrentRemove (tor, false, NULL); |
---|
227 | return 0; |
---|
228 | } |
---|
229 | |
---|
230 | /*** |
---|
231 | **** |
---|
232 | **** |
---|
233 | **** |
---|
234 | ***/ |
---|
235 | |
---|
236 | static void |
---|
237 | create_multifile_torrent_contents (const char * top) |
---|
238 | { |
---|
239 | char * path; |
---|
240 | |
---|
241 | path = tr_buildPath (top, "Felidae", "Felinae", "Acinonyx", "Cheetah", "Chester", NULL); |
---|
242 | libtest_create_file_with_string_contents (path, "It ain't easy bein' cheesy.\n"); |
---|
243 | tr_free (path); |
---|
244 | |
---|
245 | path = tr_buildPath (top, "Felidae", "Pantherinae", "Panthera", "Tiger", "Tony", NULL); |
---|
246 | libtest_create_file_with_string_contents (path, "Theyâre Grrrrreat!\n"); |
---|
247 | tr_free (path); |
---|
248 | |
---|
249 | path = tr_buildPath (top, "Felidae", "Felinae", "Felis", "catus", "Kyphi", NULL); |
---|
250 | libtest_create_file_with_string_contents (path, "Inquisitive\n"); |
---|
251 | tr_free (path); |
---|
252 | |
---|
253 | path = tr_buildPath (top, "Felidae", "Felinae", "Felis", "catus", "Saffron", NULL); |
---|
254 | libtest_create_file_with_string_contents (path, "Tough\n"); |
---|
255 | tr_free (path); |
---|
256 | |
---|
257 | sync (); |
---|
258 | } |
---|
259 | |
---|
260 | static int |
---|
261 | test_multifile_torrent (void) |
---|
262 | { |
---|
263 | tr_file_index_t i; |
---|
264 | uint64_t loaded; |
---|
265 | tr_torrent * tor; |
---|
266 | tr_ctor * ctor; |
---|
267 | char * str; |
---|
268 | char * tmp; |
---|
269 | static const size_t totalSize = 67; |
---|
270 | const tr_stat * st; |
---|
271 | const tr_file * files; |
---|
272 | const char * strings[4]; |
---|
273 | const char * expected_files[4] = { |
---|
274 | "Felidae/Felinae/Acinonyx/Cheetah/Chester", |
---|
275 | "Felidae/Felinae/Felis/catus/Kyphi", |
---|
276 | "Felidae/Felinae/Felis/catus/Saffron", |
---|
277 | "Felidae/Pantherinae/Panthera/Tiger/Tony" |
---|
278 | }; |
---|
279 | const char * expected_contents[4] = { |
---|
280 | "It ain't easy bein' cheesy.\n", |
---|
281 | "Inquisitive\n", |
---|
282 | "Tough\n", |
---|
283 | "Theyâre Grrrrreat!\n" |
---|
284 | }; |
---|
285 | |
---|
286 | ctor = tr_ctorNew (session); |
---|
287 | tor = create_torrent_from_base64_metainfo (ctor, |
---|
288 | "ZDEwOmNyZWF0ZWQgYnkyNTpUcmFuc21pc3Npb24vMi42MSAoMTM0MDcpMTM6Y3JlYXRpb24gZGF0" |
---|
289 | "ZWkxMzU4NTU1NDIwZTg6ZW5jb2Rpbmc1OlVURi04NDppbmZvZDU6ZmlsZXNsZDY6bGVuZ3RoaTI4" |
---|
290 | "ZTQ6cGF0aGw3OkZlbGluYWU4OkFjaW5vbnl4NzpDaGVldGFoNzpDaGVzdGVyZWVkNjpsZW5ndGhp" |
---|
291 | "MTJlNDpwYXRobDc6RmVsaW5hZTU6RmVsaXM1OmNhdHVzNTpLeXBoaWVlZDY6bGVuZ3RoaTZlNDpw" |
---|
292 | "YXRobDc6RmVsaW5hZTU6RmVsaXM1OmNhdHVzNzpTYWZmcm9uZWVkNjpsZW5ndGhpMjFlNDpwYXRo" |
---|
293 | "bDExOlBhbnRoZXJpbmFlODpQYW50aGVyYTU6VGlnZXI0OlRvbnllZWU0Om5hbWU3OkZlbGlkYWUx" |
---|
294 | "MjpwaWVjZSBsZW5ndGhpMzI3NjhlNjpwaWVjZXMyMDp27buFkmy8ICfNX4nsJmt0Ckm2Ljc6cHJp" |
---|
295 | "dmF0ZWkwZWVl"); |
---|
296 | check (tr_isTorrent (tor)); |
---|
297 | files = tor->info.files; |
---|
298 | |
---|
299 | /* sanity check the info */ |
---|
300 | check_streq (tor->info.name, "Felidae"); |
---|
301 | check_int_eq (totalSize, tor->info.totalSize); |
---|
302 | check_int_eq (4, tor->info.fileCount); |
---|
303 | for (i=0; i<4; ++i) |
---|
304 | check_streq (expected_files[i], files[i].name); |
---|
305 | |
---|
306 | /* sanity check the (empty) stats */ |
---|
307 | libttest_blockingTorrentVerify (tor); |
---|
308 | check_have_none (tor, totalSize); |
---|
309 | |
---|
310 | /* build the local data */ |
---|
311 | create_multifile_torrent_contents (tor->currentDir); |
---|
312 | |
---|
313 | /* sanity check the (full) stats */ |
---|
314 | libttest_blockingTorrentVerify (tor); |
---|
315 | st = tr_torrentStat (tor); |
---|
316 | check_int_eq (TR_STATUS_STOPPED, st->activity); |
---|
317 | check_int_eq (TR_STAT_OK, st->error); |
---|
318 | check_int_eq (0, st->leftUntilDone); |
---|
319 | check_int_eq (0, st->haveUnchecked); |
---|
320 | check_int_eq (0, st->desiredAvailable); |
---|
321 | check_int_eq (totalSize, st->sizeWhenDone); |
---|
322 | check_int_eq (totalSize, st->haveValid); |
---|
323 | |
---|
324 | |
---|
325 | /** |
---|
326 | *** okay! let's test renaming. |
---|
327 | **/ |
---|
328 | |
---|
329 | /* rename a leaf... */ |
---|
330 | check_int_eq (0, torrentRenameAndWait (tor, "Felidae/Felinae/Felis/catus/Kyphi", "placeholder")); |
---|
331 | check_streq (files[1].name, "Felidae/Felinae/Felis/catus/placeholder"); |
---|
332 | check (testFileExistsAndConsistsOfThisString (tor, 1, "Inquisitive\n")); |
---|
333 | |
---|
334 | /* ...and back again */ |
---|
335 | check_int_eq (0, torrentRenameAndWait (tor, "Felidae/Felinae/Felis/catus/placeholder", "Kyphi")); |
---|
336 | check_streq (files[1].name, "Felidae/Felinae/Felis/catus/Kyphi"); |
---|
337 | testFileExistsAndConsistsOfThisString (tor, 1, "Inquisitive\n"); |
---|
338 | |
---|
339 | /* rename a branch... */ |
---|
340 | check_int_eq (0, torrentRenameAndWait (tor, "Felidae/Felinae/Felis/catus", "placeholder")); |
---|
341 | check_streq (expected_files[0], files[0].name); |
---|
342 | check_streq ("Felidae/Felinae/Felis/placeholder/Kyphi", files[1].name); |
---|
343 | check_streq ("Felidae/Felinae/Felis/placeholder/Saffron", files[2].name); |
---|
344 | check_streq (expected_files[3], files[3].name); |
---|
345 | check (testFileExistsAndConsistsOfThisString (tor, 1, expected_contents[1])); |
---|
346 | check (testFileExistsAndConsistsOfThisString (tor, 2, expected_contents[2])); |
---|
347 | check (files[0].is_renamed == false); |
---|
348 | check (files[1].is_renamed == true); |
---|
349 | check (files[2].is_renamed == true); |
---|
350 | check (files[3].is_renamed == false); |
---|
351 | |
---|
352 | /* (while the branch is renamed: confirm that the .resume file remembers the changes) */ |
---|
353 | tr_torrentSaveResume (tor); |
---|
354 | /* this is a bit dodgy code-wise, but let's make sure the .resume file got the name */ |
---|
355 | tr_free (files[1].name); |
---|
356 | tor->info.files[1].name = tr_strdup ("gabba gabba hey"); |
---|
357 | loaded = tr_torrentLoadResume (tor, ~0, ctor); |
---|
358 | check ((loaded & TR_FR_FILENAMES) != 0); |
---|
359 | check_streq (expected_files[0], files[0].name); |
---|
360 | check_streq ("Felidae/Felinae/Felis/placeholder/Kyphi", files[1].name); |
---|
361 | check_streq ("Felidae/Felinae/Felis/placeholder/Saffron", files[2].name); |
---|
362 | check_streq (expected_files[3], files[3].name); |
---|
363 | |
---|
364 | /* ...and back again */ |
---|
365 | check_int_eq (0, torrentRenameAndWait (tor, "Felidae/Felinae/Felis/placeholder", "catus")); |
---|
366 | for (i=0; i<4; ++i) |
---|
367 | { |
---|
368 | check_streq (expected_files[i], files[i].name); |
---|
369 | check (testFileExistsAndConsistsOfThisString (tor, i, expected_contents[i])); |
---|
370 | } |
---|
371 | check (files[0].is_renamed == false); |
---|
372 | check (files[1].is_renamed == true); |
---|
373 | check (files[2].is_renamed == true); |
---|
374 | check (files[3].is_renamed == false); |
---|
375 | |
---|
376 | /*** |
---|
377 | **** Test it an incomplete torrent... |
---|
378 | ***/ |
---|
379 | |
---|
380 | /* remove the directory Felidae/Felinae/Felis/catus */ |
---|
381 | str = tr_torrentFindFile (tor, 1); |
---|
382 | check (str != NULL); |
---|
383 | tr_sys_path_remove (str, NULL); |
---|
384 | tr_free (str); |
---|
385 | str = tr_torrentFindFile (tor, 2); |
---|
386 | check (str != NULL); |
---|
387 | tr_sys_path_remove (str, NULL); |
---|
388 | tmp = tr_sys_path_dirname (str, NULL); |
---|
389 | tr_sys_path_remove (tmp, NULL); |
---|
390 | tr_free (tmp); |
---|
391 | tr_free (str); |
---|
392 | sync (); |
---|
393 | libttest_blockingTorrentVerify (tor); |
---|
394 | testFileExistsAndConsistsOfThisString (tor, 0, expected_contents[0]); |
---|
395 | for (i=1; i<=2; ++i) |
---|
396 | { |
---|
397 | str = tr_torrentFindFile (tor, i); |
---|
398 | check_streq (NULL, str); |
---|
399 | tr_free (str); |
---|
400 | } |
---|
401 | testFileExistsAndConsistsOfThisString (tor, 3, expected_contents[3]); |
---|
402 | |
---|
403 | /* rename a branch... */ |
---|
404 | check_int_eq (0, torrentRenameAndWait (tor, "Felidae/Felinae/Felis/catus", "foo")); |
---|
405 | check_streq (expected_files[0], files[0].name); |
---|
406 | check_streq ("Felidae/Felinae/Felis/foo/Kyphi", files[1].name); |
---|
407 | check_streq ("Felidae/Felinae/Felis/foo/Saffron", files[2].name); |
---|
408 | check_streq (expected_files[3], files[3].name); |
---|
409 | |
---|
410 | /* ...and back again */ |
---|
411 | check_int_eq (0, torrentRenameAndWait (tor, "Felidae/Felinae/Felis/foo", "catus")); |
---|
412 | for (i=0; i<4; ++i) |
---|
413 | check_streq (expected_files[i], files[i].name); |
---|
414 | |
---|
415 | check_int_eq (0, torrentRenameAndWait (tor, "Felidae", "gabba")); |
---|
416 | strings[0] = "gabba/Felinae/Acinonyx/Cheetah/Chester"; |
---|
417 | strings[1] = "gabba/Felinae/Felis/catus/Kyphi"; |
---|
418 | strings[2] = "gabba/Felinae/Felis/catus/Saffron"; |
---|
419 | strings[3] = "gabba/Pantherinae/Panthera/Tiger/Tony"; |
---|
420 | for (i=0; i<4; ++i) |
---|
421 | { |
---|
422 | check_streq (strings[i], files[i].name); |
---|
423 | testFileExistsAndConsistsOfThisString (tor, i, expected_contents[i]); |
---|
424 | } |
---|
425 | |
---|
426 | /* rename the root, then a branch, and then a leaf... */ |
---|
427 | check_int_eq (0, torrentRenameAndWait (tor, "gabba", "Felidae")); |
---|
428 | check_int_eq (0, torrentRenameAndWait (tor, "Felidae/Pantherinae/Panthera/Tiger", "Snow Leopard")); |
---|
429 | check_int_eq (0, torrentRenameAndWait (tor, "Felidae/Pantherinae/Panthera/Snow Leopard/Tony", "10.6")); |
---|
430 | strings[0] = "Felidae/Felinae/Acinonyx/Cheetah/Chester"; |
---|
431 | strings[1] = "Felidae/Felinae/Felis/catus/Kyphi"; |
---|
432 | strings[2] = "Felidae/Felinae/Felis/catus/Saffron"; |
---|
433 | strings[3] = "Felidae/Pantherinae/Panthera/Snow Leopard/10.6"; |
---|
434 | for (i=0; i<4; ++i) |
---|
435 | { |
---|
436 | check_streq (strings[i], files[i].name); |
---|
437 | testFileExistsAndConsistsOfThisString (tor, i, expected_contents[i]); |
---|
438 | } |
---|
439 | |
---|
440 | /** |
---|
441 | *** Test renaming prefixes (shouldn't work) |
---|
442 | **/ |
---|
443 | |
---|
444 | tr_ctorFree (ctor); |
---|
445 | tr_torrentRemove (tor, false, NULL); |
---|
446 | do { |
---|
447 | tr_wait_msec (10); |
---|
448 | } while (0); |
---|
449 | ctor = tr_ctorNew (session); |
---|
450 | tor = create_torrent_from_base64_metainfo (ctor, |
---|
451 | "ZDEwOmNyZWF0ZWQgYnkyNTpUcmFuc21pc3Npb24vMi42MSAoMTM0MDcpMTM6Y3JlYXRpb24gZGF0" |
---|
452 | "ZWkxMzU4NTU1NDIwZTg6ZW5jb2Rpbmc1OlVURi04NDppbmZvZDU6ZmlsZXNsZDY6bGVuZ3RoaTI4" |
---|
453 | "ZTQ6cGF0aGw3OkZlbGluYWU4OkFjaW5vbnl4NzpDaGVldGFoNzpDaGVzdGVyZWVkNjpsZW5ndGhp" |
---|
454 | "MTJlNDpwYXRobDc6RmVsaW5hZTU6RmVsaXM1OmNhdHVzNTpLeXBoaWVlZDY6bGVuZ3RoaTZlNDpw" |
---|
455 | "YXRobDc6RmVsaW5hZTU6RmVsaXM1OmNhdHVzNzpTYWZmcm9uZWVkNjpsZW5ndGhpMjFlNDpwYXRo" |
---|
456 | "bDExOlBhbnRoZXJpbmFlODpQYW50aGVyYTU6VGlnZXI0OlRvbnllZWU0Om5hbWU3OkZlbGlkYWUx" |
---|
457 | "MjpwaWVjZSBsZW5ndGhpMzI3NjhlNjpwaWVjZXMyMDp27buFkmy8ICfNX4nsJmt0Ckm2Ljc6cHJp" |
---|
458 | "dmF0ZWkwZWVl"); |
---|
459 | check (tr_isTorrent (tor)); |
---|
460 | files = tor->info.files; |
---|
461 | |
---|
462 | /* rename prefix of top */ |
---|
463 | check_int_eq (EINVAL, torrentRenameAndWait (tor, "Feli", "FelidaeX")); |
---|
464 | check_streq (tor->info.name, "Felidae"); |
---|
465 | check (files[0].is_renamed == false); |
---|
466 | check (files[1].is_renamed == false); |
---|
467 | check (files[2].is_renamed == false); |
---|
468 | check (files[3].is_renamed == false); |
---|
469 | |
---|
470 | /* rename false path */ |
---|
471 | check_int_eq (EINVAL, torrentRenameAndWait (tor, "Felidae/FelinaeX", "Genus Felinae")); |
---|
472 | check_streq (tor->info.name, "Felidae"); |
---|
473 | check (files[0].is_renamed == false); |
---|
474 | check (files[1].is_renamed == false); |
---|
475 | check (files[2].is_renamed == false); |
---|
476 | check (files[3].is_renamed == false); |
---|
477 | |
---|
478 | /*** |
---|
479 | **** |
---|
480 | ***/ |
---|
481 | |
---|
482 | /* cleanup */ |
---|
483 | tr_ctorFree (ctor); |
---|
484 | tr_torrentRemove (tor, false, NULL); |
---|
485 | return 0; |
---|
486 | } |
---|
487 | |
---|
488 | /*** |
---|
489 | **** |
---|
490 | ***/ |
---|
491 | |
---|
492 | static int |
---|
493 | test_partial_file (void) |
---|
494 | { |
---|
495 | tr_file_index_t i; |
---|
496 | tr_torrent * tor; |
---|
497 | const tr_stat * st; |
---|
498 | tr_file_stat * fst; |
---|
499 | const uint32_t pieceCount = 33; |
---|
500 | const uint32_t pieceSize = 32768; |
---|
501 | const uint32_t length[] = { 1048576, 4096, 512 }; |
---|
502 | const uint64_t totalSize = length[0] + length[1] + length[2]; |
---|
503 | const char * strings[3]; |
---|
504 | |
---|
505 | /*** |
---|
506 | **** create our test torrent with an incomplete .part file |
---|
507 | ***/ |
---|
508 | |
---|
509 | tor = libttest_zero_torrent_init (session); |
---|
510 | check_int_eq (totalSize, tor->info.totalSize); |
---|
511 | check_int_eq (pieceSize, tor->info.pieceSize); |
---|
512 | check_int_eq (pieceCount, tor->info.pieceCount); |
---|
513 | check_streq ("files-filled-with-zeroes/1048576", tor->info.files[0].name); |
---|
514 | check_streq ("files-filled-with-zeroes/4096", tor->info.files[1].name); |
---|
515 | check_streq ("files-filled-with-zeroes/512", tor->info.files[2].name); |
---|
516 | |
---|
517 | libttest_zero_torrent_populate (tor, false); |
---|
518 | fst = tr_torrentFiles (tor, NULL); |
---|
519 | check_int_eq (length[0] - pieceSize, fst[0].bytesCompleted); |
---|
520 | check_int_eq (length[1], fst[1].bytesCompleted); |
---|
521 | check_int_eq (length[2], fst[2].bytesCompleted); |
---|
522 | tr_torrentFilesFree (fst, tor->info.fileCount); |
---|
523 | st = tr_torrentStat (tor); |
---|
524 | check_int_eq (totalSize, st->sizeWhenDone); |
---|
525 | check_int_eq (pieceSize, st->leftUntilDone); |
---|
526 | |
---|
527 | /*** |
---|
528 | **** |
---|
529 | ***/ |
---|
530 | |
---|
531 | check_int_eq (0, torrentRenameAndWait (tor, "files-filled-with-zeroes", "foo")); |
---|
532 | check_int_eq (0, torrentRenameAndWait (tor, "foo/1048576", "bar")); |
---|
533 | strings[0] = "foo/bar"; |
---|
534 | strings[1] = "foo/4096"; |
---|
535 | strings[2] = "foo/512"; |
---|
536 | for (i=0; i<3; ++i) |
---|
537 | { |
---|
538 | check_streq (strings[i], tor->info.files[i].name); |
---|
539 | } |
---|
540 | |
---|
541 | strings[0] = "foo/bar.part"; |
---|
542 | for (i=0; i<3; ++i) |
---|
543 | { |
---|
544 | char * expected = tr_buildPath (tor->currentDir, strings[i], NULL); |
---|
545 | char * path = tr_torrentFindFile (tor, i); |
---|
546 | check_streq (expected, path); |
---|
547 | tr_free (path); |
---|
548 | tr_free (expected); |
---|
549 | } |
---|
550 | |
---|
551 | tr_torrentRemove (tor, false, NULL); |
---|
552 | return 0; |
---|
553 | } |
---|
554 | |
---|
555 | /*** |
---|
556 | **** |
---|
557 | ***/ |
---|
558 | |
---|
559 | int |
---|
560 | main (void) |
---|
561 | { |
---|
562 | int ret; |
---|
563 | const testFunc tests[] = { test_single_filename_torrent, |
---|
564 | test_multifile_torrent, |
---|
565 | test_partial_file }; |
---|
566 | |
---|
567 | session = libttest_session_init (NULL); |
---|
568 | ret = runTests (tests, NUM_TESTS (tests)); |
---|
569 | libttest_session_close (session); |
---|
570 | |
---|
571 | return ret; |
---|
572 | } |
---|