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