1 #include "FileEntry.h"
2
3 #include <cppunit/extensions/HelperMacros.h>
4
5 #include "InorderURISelector.h"
6 #include "util.h"
7
8 namespace aria2 {
9
10 class FileEntryTest : public CppUnit::TestFixture {
11
12 CPPUNIT_TEST_SUITE(FileEntryTest);
13 CPPUNIT_TEST(testRemoveURIWhoseHostnameIs);
14 CPPUNIT_TEST(testExtractURIResult);
15 CPPUNIT_TEST(testGetRequest);
16 CPPUNIT_TEST(testGetRequest_withoutUriReuse);
17 CPPUNIT_TEST(testGetRequest_withUniqueProtocol);
18 CPPUNIT_TEST(testGetRequest_withReferer);
19 CPPUNIT_TEST(testReuseUri);
20 CPPUNIT_TEST(testAddUri);
21 CPPUNIT_TEST(testAddUris);
22 CPPUNIT_TEST(testInsertUri);
23 CPPUNIT_TEST(testRemoveUri);
24 CPPUNIT_TEST(testPutBackRequest);
25 CPPUNIT_TEST_SUITE_END();
26
27 public:
setUp()28 void setUp() {}
29
30 void testRemoveURIWhoseHostnameIs();
31 void testExtractURIResult();
32 void testGetRequest();
33 void testGetRequest_withoutUriReuse();
34 void testGetRequest_withUniqueProtocol();
35 void testGetRequest_withReferer();
36 void testReuseUri();
37 void testAddUri();
38 void testAddUris();
39 void testInsertUri();
40 void testRemoveUri();
41 void testPutBackRequest();
42 };
43
44 CPPUNIT_TEST_SUITE_REGISTRATION(FileEntryTest);
45
46 namespace {
createFileEntry()47 std::shared_ptr<FileEntry> createFileEntry()
48 {
49 auto fileEntry = std::make_shared<FileEntry>();
50 fileEntry->setUris(std::vector<std::string>{"http://localhost/aria2.zip",
51 "ftp://localhost/aria2.zip",
52 "http://mirror/aria2.zip"});
53 return fileEntry;
54 }
55 } // namespace
56
testRemoveURIWhoseHostnameIs()57 void FileEntryTest::testRemoveURIWhoseHostnameIs()
58 {
59 auto fileEntry = createFileEntry();
60 fileEntry->removeURIWhoseHostnameIs("localhost");
61 CPPUNIT_ASSERT_EQUAL((size_t)1, fileEntry->getRemainingUris().size());
62 CPPUNIT_ASSERT_EQUAL(std::string("http://mirror/aria2.zip"),
63 fileEntry->getRemainingUris()[0]);
64 }
65
testExtractURIResult()66 void FileEntryTest::testExtractURIResult()
67 {
68 FileEntry fileEntry;
69 fileEntry.addURIResult("http://timeout/file", error_code::TIME_OUT);
70 fileEntry.addURIResult("http://finished/file", error_code::FINISHED);
71 fileEntry.addURIResult("http://timeout/file2", error_code::TIME_OUT);
72 fileEntry.addURIResult("http://unknownerror/file", error_code::UNKNOWN_ERROR);
73
74 std::deque<URIResult> res;
75 fileEntry.extractURIResult(res, error_code::TIME_OUT);
76 CPPUNIT_ASSERT_EQUAL((size_t)2, res.size());
77 CPPUNIT_ASSERT_EQUAL(std::string("http://timeout/file"), res[0].getURI());
78 CPPUNIT_ASSERT_EQUAL(std::string("http://timeout/file2"), res[1].getURI());
79
80 CPPUNIT_ASSERT_EQUAL((size_t)2, fileEntry.getURIResults().size());
81 CPPUNIT_ASSERT_EQUAL(std::string("http://finished/file"),
82 fileEntry.getURIResults()[0].getURI());
83 CPPUNIT_ASSERT_EQUAL(std::string("http://unknownerror/file"),
84 fileEntry.getURIResults()[1].getURI());
85
86 res.clear();
87
88 fileEntry.extractURIResult(res, error_code::TIME_OUT);
89 CPPUNIT_ASSERT(res.empty());
90 CPPUNIT_ASSERT_EQUAL((size_t)2, fileEntry.getURIResults().size());
91 }
92
testGetRequest()93 void FileEntryTest::testGetRequest()
94 {
95 auto fileEntry = createFileEntry();
96 InorderURISelector selector{};
97 std::vector<std::pair<size_t, std::string>> usedHosts;
98 auto req = fileEntry->getRequest(&selector, true, usedHosts);
99 CPPUNIT_ASSERT_EQUAL(std::string("localhost"), req->getHost());
100 CPPUNIT_ASSERT_EQUAL(std::string("http"), req->getProtocol());
101 fileEntry->poolRequest(req);
102
103 auto req2nd = fileEntry->getRequest(&selector, true, usedHosts);
104 CPPUNIT_ASSERT_EQUAL(std::string("localhost"), req2nd->getHost());
105 CPPUNIT_ASSERT_EQUAL(std::string("http"), req2nd->getProtocol());
106
107 auto req3rd = fileEntry->getRequest(&selector, true, usedHosts);
108 CPPUNIT_ASSERT_EQUAL(std::string("mirror"), req3rd->getHost());
109 CPPUNIT_ASSERT_EQUAL(std::string("http"), req3rd->getProtocol());
110
111 auto req4th = fileEntry->getRequest(&selector, true, usedHosts);
112 CPPUNIT_ASSERT(!req4th);
113
114 fileEntry->setMaxConnectionPerServer(2);
115
116 auto req5th = fileEntry->getRequest(&selector, true, usedHosts);
117 CPPUNIT_ASSERT_EQUAL(std::string("localhost"), req5th->getHost());
118 CPPUNIT_ASSERT_EQUAL(std::string("ftp"), req5th->getProtocol());
119
120 auto req6th = fileEntry->getRequest(&selector, true, usedHosts);
121 CPPUNIT_ASSERT_EQUAL(std::string("mirror"), req6th->getHost());
122 CPPUNIT_ASSERT_EQUAL(std::string("http"), req6th->getProtocol());
123
124 auto req7th = fileEntry->getRequest(&selector, true, usedHosts);
125 CPPUNIT_ASSERT(!req7th);
126 }
127
testGetRequest_withoutUriReuse()128 void FileEntryTest::testGetRequest_withoutUriReuse()
129 {
130 std::vector<std::pair<size_t, std::string>> usedHosts;
131 auto fileEntry = createFileEntry();
132 fileEntry->setMaxConnectionPerServer(2);
133 InorderURISelector selector{};
134 auto req = fileEntry->getRequest(&selector, false, usedHosts);
135 CPPUNIT_ASSERT_EQUAL(std::string("localhost"), req->getHost());
136 CPPUNIT_ASSERT_EQUAL(std::string("http"), req->getProtocol());
137
138 auto req2nd = fileEntry->getRequest(&selector, false, usedHosts);
139 CPPUNIT_ASSERT_EQUAL(std::string("localhost"), req2nd->getHost());
140 CPPUNIT_ASSERT_EQUAL(std::string("ftp"), req2nd->getProtocol());
141
142 auto req3rd = fileEntry->getRequest(&selector, false, usedHosts);
143 CPPUNIT_ASSERT_EQUAL(std::string("mirror"), req3rd->getHost());
144 CPPUNIT_ASSERT_EQUAL(std::string("http"), req3rd->getProtocol());
145
146 auto req4th = fileEntry->getRequest(&selector, false, usedHosts);
147 CPPUNIT_ASSERT(!req4th);
148 }
149
testGetRequest_withUniqueProtocol()150 void FileEntryTest::testGetRequest_withUniqueProtocol()
151 {
152 std::vector<std::pair<size_t, std::string>> usedHosts;
153 auto fileEntry = createFileEntry();
154 fileEntry->setUniqueProtocol(true);
155 InorderURISelector selector{};
156 auto req = fileEntry->getRequest(&selector, true, usedHosts);
157 CPPUNIT_ASSERT_EQUAL(std::string("localhost"), req->getHost());
158 CPPUNIT_ASSERT_EQUAL(std::string("http"), req->getProtocol());
159
160 auto req2nd = fileEntry->getRequest(&selector, true, usedHosts);
161 CPPUNIT_ASSERT_EQUAL(std::string("mirror"), req2nd->getHost());
162 CPPUNIT_ASSERT_EQUAL(std::string("http"), req2nd->getProtocol());
163
164 auto req3rd = fileEntry->getRequest(&selector, true, usedHosts);
165 CPPUNIT_ASSERT(!req3rd);
166
167 CPPUNIT_ASSERT_EQUAL((size_t)2, fileEntry->getRemainingUris().size());
168 CPPUNIT_ASSERT_EQUAL(std::string("ftp://localhost/aria2.zip"),
169 fileEntry->getRemainingUris()[0]);
170 CPPUNIT_ASSERT_EQUAL(std::string("http://mirror/aria2.zip"),
171 fileEntry->getRemainingUris()[1]);
172 }
173
testGetRequest_withReferer()174 void FileEntryTest::testGetRequest_withReferer()
175 {
176 auto fileEntry = createFileEntry();
177 InorderURISelector selector{};
178 std::vector<std::pair<size_t, std::string>> usedHosts;
179 auto req =
180 fileEntry->getRequest(&selector, true, usedHosts, "http://referer");
181 CPPUNIT_ASSERT_EQUAL(std::string("http://referer"), req->getReferer());
182 // URI is used as referer if "*" is given.
183 req = fileEntry->getRequest(&selector, true, usedHosts, "*");
184 CPPUNIT_ASSERT_EQUAL(req->getUri(), req->getReferer());
185 }
186
testReuseUri()187 void FileEntryTest::testReuseUri()
188 {
189 InorderURISelector selector{};
190 auto fileEntry = createFileEntry();
191 fileEntry->setMaxConnectionPerServer(3);
192 size_t numUris = fileEntry->getRemainingUris().size();
193 std::vector<std::pair<size_t, std::string>> usedHosts;
194 for (size_t i = 0; i < numUris; ++i) {
195 fileEntry->getRequest(&selector, false, usedHosts);
196 }
197 CPPUNIT_ASSERT_EQUAL((size_t)0, fileEntry->getRemainingUris().size());
198 fileEntry->addURIResult("http://localhost/aria2.zip",
199 error_code::UNKNOWN_ERROR);
200 std::vector<std::string> ignore;
201 fileEntry->reuseUri(ignore);
202 CPPUNIT_ASSERT_EQUAL((size_t)2, fileEntry->getRemainingUris().size());
203 auto uris = fileEntry->getRemainingUris();
204 CPPUNIT_ASSERT_EQUAL(std::string("ftp://localhost/aria2.zip"), uris[0]);
205 CPPUNIT_ASSERT_EQUAL(std::string("http://mirror/aria2.zip"), uris[1]);
206 for (size_t i = 0; i < 2; ++i) {
207 fileEntry->getRequest(&selector, false, usedHosts);
208 }
209 CPPUNIT_ASSERT_EQUAL((size_t)0, fileEntry->getRemainingUris().size());
210 ignore.clear();
211 ignore.push_back("mirror");
212 fileEntry->reuseUri(ignore);
213 CPPUNIT_ASSERT_EQUAL((size_t)1, fileEntry->getRemainingUris().size());
214 uris = fileEntry->getRemainingUris();
215 CPPUNIT_ASSERT_EQUAL(std::string("ftp://localhost/aria2.zip"), uris[0]);
216 }
217
testAddUri()218 void FileEntryTest::testAddUri()
219 {
220 FileEntry file;
221 CPPUNIT_ASSERT(file.addUri("http://good"));
222 CPPUNIT_ASSERT(!file.addUri("bad"));
223 // Test for percent-encode
224 CPPUNIT_ASSERT(file.addUri("http://host:80/file<with%2 %20space/"
225 "file with space;param%?a=/?"));
226
227 CPPUNIT_ASSERT_EQUAL(std::string("http://host:80"
228 "/file%3Cwith%2%20%20space/"
229 "file%20with%20space;param%"
230 "?a=/?"),
231 file.getRemainingUris()[1]);
232 }
233
testAddUris()234 void FileEntryTest::testAddUris()
235 {
236 FileEntry file;
237 std::string uris[] = {"bad", "http://good"};
238 CPPUNIT_ASSERT_EQUAL((size_t)1, file.addUris(&uris[0], &uris[2]));
239 }
240
testInsertUri()241 void FileEntryTest::testInsertUri()
242 {
243 FileEntry file;
244 CPPUNIT_ASSERT(file.insertUri("http://example.org/1", 0));
245 CPPUNIT_ASSERT(file.insertUri("http://example.org/2", 0));
246 CPPUNIT_ASSERT(file.insertUri("http://example.org/3", 1));
247 CPPUNIT_ASSERT(file.insertUri("http://example.org/4", 5));
248 auto& uris = file.getRemainingUris();
249 CPPUNIT_ASSERT_EQUAL(std::string("http://example.org/2"), uris[0]);
250 CPPUNIT_ASSERT_EQUAL(std::string("http://example.org/3"), uris[1]);
251 CPPUNIT_ASSERT_EQUAL(std::string("http://example.org/1"), uris[2]);
252 CPPUNIT_ASSERT_EQUAL(std::string("http://example.org/4"), uris[3]);
253 // Test for percent-encode
254 CPPUNIT_ASSERT(file.insertUri("http://host:80/file<with%2 %20space/"
255 "file with space;param%?a=/?",
256 0));
257
258 CPPUNIT_ASSERT_EQUAL(std::string("http://host:80"
259 "/file%3Cwith%2%20%20space/"
260 "file%20with%20space;param%"
261 "?a=/?"),
262 file.getRemainingUris()[0]);
263 }
264
testRemoveUri()265 void FileEntryTest::testRemoveUri()
266 {
267 std::vector<std::pair<size_t, std::string>> usedHosts;
268 InorderURISelector selector{};
269 FileEntry file;
270 file.addUri("http://example.org/");
271 CPPUNIT_ASSERT(file.removeUri("http://example.org/"));
272 CPPUNIT_ASSERT(file.getRemainingUris().empty());
273 CPPUNIT_ASSERT(!file.removeUri("http://example.org/"));
274
275 file.addUri("http://example.org/");
276 auto exampleOrgReq = file.getRequest(&selector, true, usedHosts);
277 CPPUNIT_ASSERT(!exampleOrgReq->removalRequested());
278 CPPUNIT_ASSERT_EQUAL((size_t)1, file.getSpentUris().size());
279 CPPUNIT_ASSERT(file.removeUri("http://example.org/"));
280 CPPUNIT_ASSERT(file.getSpentUris().empty());
281 CPPUNIT_ASSERT(exampleOrgReq->removalRequested());
282 file.poolRequest(exampleOrgReq);
283 CPPUNIT_ASSERT_EQUAL((size_t)0, file.countPooledRequest());
284
285 file.addUri("http://example.org/");
286 exampleOrgReq = file.getRequest(&selector, true, usedHosts);
287 file.poolRequest(exampleOrgReq);
288 CPPUNIT_ASSERT_EQUAL((size_t)1, file.countPooledRequest());
289 CPPUNIT_ASSERT(file.removeUri("http://example.org/"));
290 CPPUNIT_ASSERT_EQUAL((size_t)0, file.countPooledRequest());
291 CPPUNIT_ASSERT(file.getSpentUris().empty());
292
293 file.addUri("http://example.org/");
294 CPPUNIT_ASSERT(!file.removeUri("http://example.net"));
295 }
296
testPutBackRequest()297 void FileEntryTest::testPutBackRequest()
298 {
299 auto fileEntry = createFileEntry();
300 InorderURISelector selector{};
301 std::vector<std::pair<size_t, std::string>> usedHosts;
302 auto req1 = fileEntry->getRequest(&selector, false, usedHosts);
303 auto req2 = fileEntry->getRequest(&selector, false, usedHosts);
304 CPPUNIT_ASSERT_EQUAL((size_t)1, fileEntry->getRemainingUris().size());
305 fileEntry->poolRequest(req2);
306 fileEntry->putBackRequest();
307 auto& uris = fileEntry->getRemainingUris();
308 CPPUNIT_ASSERT_EQUAL((size_t)3, uris.size());
309 CPPUNIT_ASSERT_EQUAL(std::string("http://localhost/aria2.zip"), uris[0]);
310 CPPUNIT_ASSERT_EQUAL(std::string("http://mirror/aria2.zip"), uris[1]);
311 CPPUNIT_ASSERT_EQUAL(std::string("ftp://localhost/aria2.zip"), uris[2]);
312 }
313
314 } // namespace aria2
315