1 | #include <assert.h> |
---|
2 | #include <errno.h> |
---|
3 | #include <stdio.h> /* remove() */ |
---|
4 | #include <string.h> /* strcmp() */ |
---|
5 | #include <stdio.h> |
---|
6 | |
---|
7 | #include <sys/types.h> /* stat() */ |
---|
8 | #include <sys/stat.h> /* stat() */ |
---|
9 | #include <unistd.h> /* stat(), sync() */ |
---|
10 | |
---|
11 | #include <event2/buffer.h> |
---|
12 | |
---|
13 | #include "transmission.h" |
---|
14 | #include "cache.h" |
---|
15 | #include "resume.h" |
---|
16 | #include "trevent.h" |
---|
17 | #include "torrent.h" /* tr_isTorrent() */ |
---|
18 | #include "utils.h" /* tr_mkdirp() */ |
---|
19 | #include "variant.h" |
---|
20 | |
---|
21 | #include "libtransmission-test.h" |
---|
22 | |
---|
23 | /*** |
---|
24 | **** |
---|
25 | ***/ |
---|
26 | |
---|
27 | #define verify_and_block_until_done(tor) \ |
---|
28 | do { \ |
---|
29 | do { tr_wait_msec (10); } while (tor->verifyState != TR_VERIFY_NONE); \ |
---|
30 | tr_torrentVerify (tor); \ |
---|
31 | do { tr_wait_msec (10); } while (tor->verifyState != TR_VERIFY_NONE); \ |
---|
32 | } while (0) |
---|
33 | |
---|
34 | static void |
---|
35 | zeroes_completeness_func (tr_torrent * torrent UNUSED, |
---|
36 | tr_completeness completeness, |
---|
37 | bool wasRunning UNUSED, |
---|
38 | void * user_data) |
---|
39 | { |
---|
40 | *(tr_completeness*)user_data = completeness; |
---|
41 | } |
---|
42 | |
---|
43 | #define check_file_location(tor, i, expected_path) \ |
---|
44 | do { \ |
---|
45 | char * path = tr_torrentFindFile (tor, i); \ |
---|
46 | char * expected = expected_path; \ |
---|
47 | check_streq (expected, path); \ |
---|
48 | tr_free (expected); \ |
---|
49 | tr_free (path); \ |
---|
50 | } while (0) |
---|
51 | |
---|
52 | struct test_incomplete_dir_is_subdir_of_download_dir_data |
---|
53 | { |
---|
54 | tr_torrent * tor; |
---|
55 | tr_block_index_t block; |
---|
56 | tr_piece_index_t pieceIndex; |
---|
57 | uint32_t offset; |
---|
58 | struct evbuffer * buf; |
---|
59 | bool done; |
---|
60 | }; |
---|
61 | |
---|
62 | static void |
---|
63 | test_incomplete_dir_is_subdir_of_download_dir_threadfunc (void * vdata) |
---|
64 | { |
---|
65 | struct test_incomplete_dir_is_subdir_of_download_dir_data * data = vdata; |
---|
66 | tr_cacheWriteBlock (session->cache, data->tor, 0, data->offset, data->tor->blockSize, data->buf); |
---|
67 | tr_torrentGotBlock (data->tor, data->block); |
---|
68 | data->done = true; |
---|
69 | } |
---|
70 | |
---|
71 | |
---|
72 | static int |
---|
73 | test_incomplete_dir_is_subdir_of_download_dir (void) |
---|
74 | { |
---|
75 | size_t i; |
---|
76 | char * incomplete_dir; |
---|
77 | tr_torrent * tor; |
---|
78 | tr_completeness completeness; |
---|
79 | const tr_completeness completeness_unset = -1; |
---|
80 | const time_t deadline = time(NULL) + 5; |
---|
81 | |
---|
82 | /* init the session */ |
---|
83 | libtransmission_test_session_init (); |
---|
84 | incomplete_dir = tr_buildPath (downloadDir, "incomplete", NULL); |
---|
85 | tr_sessionSetIncompleteDir (session, incomplete_dir); |
---|
86 | tr_sessionSetIncompleteDirEnabled (session, true); |
---|
87 | |
---|
88 | /* init an incomplete torrent. |
---|
89 | the test zero_torrent will be missing its first piece */ |
---|
90 | tor = libtransmission_test_zero_torrent_init (); |
---|
91 | libtransmission_test_zero_torrent_populate (tor, false); |
---|
92 | check (tr_torrentStat(tor)->leftUntilDone == tor->info.pieceSize); |
---|
93 | check_file_location (tor, 0, tr_strdup_printf("%s/%s.part", incomplete_dir, tor->info.files[0].name)); |
---|
94 | check_file_location (tor, 1, tr_buildPath(incomplete_dir, tor->info.files[1].name, NULL)); |
---|
95 | check_int_eq (tor->info.pieceSize, tr_torrentStat(tor)->leftUntilDone); |
---|
96 | |
---|
97 | completeness = completeness_unset; |
---|
98 | tr_torrentSetCompletenessCallback (tor, zeroes_completeness_func, &completeness); |
---|
99 | |
---|
100 | /* now finish writing it */ |
---|
101 | { |
---|
102 | tr_block_index_t first, last; |
---|
103 | char * zero_block = tr_new0 (char, tor->blockSize); |
---|
104 | struct test_incomplete_dir_is_subdir_of_download_dir_data data; |
---|
105 | |
---|
106 | data.tor = tor; |
---|
107 | data.pieceIndex = 0; |
---|
108 | data.buf = evbuffer_new (); |
---|
109 | |
---|
110 | tr_torGetPieceBlockRange (tor, data.pieceIndex, &first, &last); |
---|
111 | for (i=first; i<=last; ++i) |
---|
112 | { |
---|
113 | evbuffer_add (data.buf, zero_block, tor->blockSize); |
---|
114 | data.block = i; |
---|
115 | data.done = false; |
---|
116 | data.offset = data.block * tor->blockSize; |
---|
117 | tr_runInEventThread (session, test_incomplete_dir_is_subdir_of_download_dir_threadfunc, &data); |
---|
118 | do { tr_wait_msec(50); } while (!data.done); |
---|
119 | } |
---|
120 | |
---|
121 | evbuffer_free (data.buf); |
---|
122 | tr_free (zero_block); |
---|
123 | } |
---|
124 | |
---|
125 | verify_and_block_until_done (tor); |
---|
126 | check_int_eq (0, tr_torrentStat(tor)->leftUntilDone); |
---|
127 | |
---|
128 | while ((completeness==completeness_unset) && (time(NULL)<=deadline)) |
---|
129 | tr_wait_msec (50); |
---|
130 | |
---|
131 | check_int_eq (TR_SEED, completeness); |
---|
132 | for (i=0; i<tor->info.fileCount; ++i) |
---|
133 | check_file_location (tor, i, tr_buildPath (downloadDir, tor->info.files[i].name, NULL)); |
---|
134 | |
---|
135 | /* cleanup */ |
---|
136 | tr_torrentRemove (tor, true, remove); |
---|
137 | libtransmission_test_session_close (); |
---|
138 | tr_free (incomplete_dir); |
---|
139 | return 0; |
---|
140 | } |
---|
141 | |
---|
142 | |
---|
143 | /*** |
---|
144 | **** |
---|
145 | ***/ |
---|
146 | |
---|
147 | int |
---|
148 | main (void) |
---|
149 | { |
---|
150 | const testFunc tests[] = { test_incomplete_dir_is_subdir_of_download_dir }; |
---|
151 | |
---|
152 | return runTests (tests, NUM_TESTS (tests)); |
---|
153 | } |
---|
154 | |
---|
155 | |
---|