Metalink2RequestGroupTest.cc 8.62 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
#include "Metalink2RequestGroup.h"

#include <algorithm>

#include <cppunit/extensions/HelperMacros.h>

#include "DownloadContext.h"
#include "prefs.h"
#include "Option.h"
#include "RequestGroup.h"
#include "FileEntry.h"
#include "Signature.h"

namespace aria2 {

16
class Metalink2RequestGroupTest : public CppUnit::TestFixture {
17 18 19

  CPPUNIT_TEST_SUITE(Metalink2RequestGroupTest);
  CPPUNIT_TEST(testGenerate);
20
  CPPUNIT_TEST(testGenerate_with_local_metaurl);
21 22 23
  CPPUNIT_TEST(testGenerate_groupByMetaurl);
  CPPUNIT_TEST(testGenerate_dosDirTraversal);
  CPPUNIT_TEST_SUITE_END();
24

25
private:
26
  std::shared_ptr<Option> option_;
27 28 29 30 31 32 33 34 35

public:
  void setUp()
  {
    option_.reset(new Option());
    option_->put(PREF_SPLIT, "1");
  }

  void testGenerate();
36
  void testGenerate_with_local_metaurl();
37 38 39 40
  void testGenerate_groupByMetaurl();
  void testGenerate_dosDirTraversal();
};

41
CPPUNIT_TEST_SUITE_REGISTRATION(Metalink2RequestGroupTest);
42 43 44

void Metalink2RequestGroupTest::testGenerate()
{
45
  std::vector<std::shared_ptr<RequestGroup>> groups;
46
  option_->put(PREF_DIR, "/tmp");
47
  Metalink2RequestGroup().generate(groups, A2_TEST_DIR "/test.xml", option_);
48 49
  // first file
  {
50
    std::shared_ptr<RequestGroup> rg = groups[0];
51
    auto uris = rg->getDownloadContext()->getFirstFileEntry()->getUris();
52 53
    std::sort(uris.begin(), uris.end());
    CPPUNIT_ASSERT_EQUAL((size_t)2, uris.size());
54 55 56 57
    CPPUNIT_ASSERT_EQUAL(std::string("ftp://ftphost/aria2-0.5.2.tar.bz2"),
                         uris[0]);
    CPPUNIT_ASSERT_EQUAL(std::string("http://httphost/aria2-0.5.2.tar.bz2"),
                         uris[1]);
58

59
    const std::shared_ptr<DownloadContext>& dctx = rg->getDownloadContext();
60 61

    CPPUNIT_ASSERT(dctx);
62
    CPPUNIT_ASSERT_EQUAL((int64_t)0LL, dctx->getTotalLength());
63
    CPPUNIT_ASSERT_EQUAL(std::string("sha-1"), dctx->getHashType());
64 65 66
    CPPUNIT_ASSERT_EQUAL(
        std::string("a96cf3f0266b91d87d5124cf94326422800b627d"),
        util::toHex(dctx->getDigest()));
67 68 69 70 71
    CPPUNIT_ASSERT(dctx->getSignature());
    CPPUNIT_ASSERT_EQUAL(std::string("pgp"), dctx->getSignature()->getType());
  }
  // second file
  {
72
    std::shared_ptr<RequestGroup> rg = groups[1];
73
    auto uris = rg->getDownloadContext()->getFirstFileEntry()->getUris();
74 75
    CPPUNIT_ASSERT_EQUAL((size_t)2, uris.size());

76
    const std::shared_ptr<DownloadContext>& dctx = rg->getDownloadContext();
77 78 79 80 81 82

    CPPUNIT_ASSERT(dctx);
    CPPUNIT_ASSERT_EQUAL(std::string("sha-1"), dctx->getPieceHashType());
    CPPUNIT_ASSERT_EQUAL((size_t)2, dctx->getPieceHashes().size());
    CPPUNIT_ASSERT_EQUAL(262144, dctx->getPieceLength());
    CPPUNIT_ASSERT_EQUAL(std::string("sha-1"), dctx->getHashType());
83 84 85
    CPPUNIT_ASSERT_EQUAL(
        std::string("4c255b0ed130f5ea880f0aa061c3da0487e251cc"),
        util::toHex(dctx->getDigest()));
86 87 88 89 90 91
    CPPUNIT_ASSERT(!dctx->getSignature());
  }

#ifdef ENABLE_BITTORRENT
  // fifth file <- downloading .torrent file
  {
92
    std::shared_ptr<RequestGroup> rg = groups[4];
93
    auto uris = rg->getDownloadContext()->getFirstFileEntry()->getUris();
94
    CPPUNIT_ASSERT_EQUAL((size_t)1, uris.size());
95 96
    CPPUNIT_ASSERT_EQUAL(
        std::string("http://host/torrent-http.integrated.torrent"), uris[0]);
97
    const std::shared_ptr<DownloadContext>& dctx = rg->getDownloadContext();
98 99 100 101 102 103 104 105 106

    CPPUNIT_ASSERT(dctx);
    CPPUNIT_ASSERT_EQUAL(groups[5]->getGID(), rg->belongsTo());
  }
#endif // ENABLE_BITTORRENT

  // sixth file <- depends on fifth file to download .torrent file.
  {
#ifdef ENABLE_BITTORRENT
107
    std::shared_ptr<RequestGroup> rg = groups[5];
108
#else
109
    std::shared_ptr<RequestGroup> rg = groups[4];
110
#endif // ENABLE_BITTORRENT
111
    auto uris = rg->getDownloadContext()->getFirstFileEntry()->getUris();
112
    CPPUNIT_ASSERT_EQUAL((size_t)1, uris.size());
113 114
    CPPUNIT_ASSERT_EQUAL(std::string("http://host/torrent-http.integrated"),
                         uris[0]);
115

116
    const std::shared_ptr<DownloadContext>& dctx = rg->getDownloadContext();
117 118 119 120 121

    CPPUNIT_ASSERT(dctx);
  }
}

122 123
void Metalink2RequestGroupTest::testGenerate_with_local_metaurl()
{
124
  std::vector<std::shared_ptr<RequestGroup>> groups;
125 126 127
  option_->put(PREF_DIR, "/tmp");
  // local metaurl does not work without --metalink-base-uri option.
  // Make sure that it does not crash with local metaurl.
128
  Metalink2RequestGroup().generate(groups, A2_TEST_DIR "/local-metaurl.meta4",
129 130 131
                                   option_);
  CPPUNIT_ASSERT_EQUAL((size_t)1, groups.size());
  CPPUNIT_ASSERT_EQUAL(std::string("http://example.org/README"),
132 133 134 135
                       groups[0]
                           ->getDownloadContext()
                           ->getFirstFileEntry()
                           ->getRemainingUris()[0]);
136 137
}

138 139
void Metalink2RequestGroupTest::testGenerate_groupByMetaurl()
{
140 141 142
  std::vector<std::shared_ptr<RequestGroup>> groups;
  Metalink2RequestGroup().generate(
      groups, A2_TEST_DIR "/metalink4-groupbymetaurl.xml", option_);
143 144 145 146 147
  CPPUNIT_ASSERT_EQUAL((size_t)3, groups.size());

#ifdef ENABLE_BITTORRENT
  // first RequestGroup is torrent for second RequestGroup
  {
148
    std::shared_ptr<RequestGroup> rg = groups[0];
149
    auto uris = rg->getDownloadContext()->getFirstFileEntry()->getUris();
150 151 152 153 154
    CPPUNIT_ASSERT_EQUAL((size_t)1, uris.size());
    CPPUNIT_ASSERT_EQUAL(std::string("http://torrent"), uris[0]);
  }
  // second
  {
155 156
    std::shared_ptr<RequestGroup> rg = groups[1];
    std::shared_ptr<DownloadContext> dctx = rg->getDownloadContext();
157 158
    const std::vector<std::shared_ptr<FileEntry>>& fileEntries =
        dctx->getFileEntries();
159 160
    CPPUNIT_ASSERT_EQUAL((size_t)2, fileEntries.size());
    CPPUNIT_ASSERT_EQUAL(std::string("./file1"), fileEntries[0]->getPath());
161
    CPPUNIT_ASSERT_EQUAL(std::string("file1"),
162 163
                         fileEntries[0]->getOriginalName());
    CPPUNIT_ASSERT_EQUAL(std::string("file1"), fileEntries[0]->getSuffixPath());
164 165 166 167
    CPPUNIT_ASSERT_EQUAL((size_t)1, fileEntries[0]->getRemainingUris().size());
    CPPUNIT_ASSERT_EQUAL(std::string("http://file1p1"),
                         fileEntries[0]->getRemainingUris()[0]);
    CPPUNIT_ASSERT_EQUAL(std::string("./file3"), fileEntries[1]->getPath());
168 169
    CPPUNIT_ASSERT_EQUAL(std::string("file3"),
                         fileEntries[1]->getOriginalName());
170 171 172 173 174 175
    CPPUNIT_ASSERT_EQUAL((size_t)1, fileEntries[1]->getRemainingUris().size());
    CPPUNIT_ASSERT_EQUAL(std::string("http://file3p1"),
                         fileEntries[1]->getRemainingUris()[0]);
  }
  // third
  {
176 177
    std::shared_ptr<RequestGroup> rg = groups[2];
    std::shared_ptr<DownloadContext> dctx = rg->getDownloadContext();
178 179
    const std::vector<std::shared_ptr<FileEntry>>& fileEntries =
        dctx->getFileEntries();
180 181 182 183 184 185 186 187
    CPPUNIT_ASSERT_EQUAL((size_t)1, fileEntries.size());
    CPPUNIT_ASSERT_EQUAL(std::string("./file2"), fileEntries[0]->getPath());
    CPPUNIT_ASSERT_EQUAL((size_t)1, fileEntries[0]->getRemainingUris().size());
    CPPUNIT_ASSERT_EQUAL(std::string("http://file2p1"),
                         fileEntries[0]->getRemainingUris()[0]);
  }
#else // !ENABLE_BITTORRENT
  {
188
    std::shared_ptr<RequestGroup> rg = groups[0];
189
    auto uris = rg->getDownloadContext()->getFirstFileEntry()->getUris();
190 191 192 193
    CPPUNIT_ASSERT_EQUAL((size_t)1, uris.size());
    CPPUNIT_ASSERT_EQUAL(std::string("http://file1p1"), uris[0]);
  }
  {
194
    std::shared_ptr<RequestGroup> rg = groups[1];
195
    auto uris = rg->getDownloadContext()->getFirstFileEntry()->getUris();
196 197 198 199
    CPPUNIT_ASSERT_EQUAL((size_t)1, uris.size());
    CPPUNIT_ASSERT_EQUAL(std::string("http://file2p1"), uris[0]);
  }
  {
200
    std::shared_ptr<RequestGroup> rg = groups[2];
201
    auto uris = rg->getDownloadContext()->getFirstFileEntry()->getUris();
202 203 204
    CPPUNIT_ASSERT_EQUAL((size_t)1, uris.size());
    CPPUNIT_ASSERT_EQUAL(std::string("http://file3p1"), uris[0]);
  }
205

206 207 208 209 210 211 212
#endif // !ENABLE_BITTORRENT
}

void Metalink2RequestGroupTest::testGenerate_dosDirTraversal()
{
#ifdef __MINGW32__
#ifdef ENABLE_BITTORRENT
213
  std::vector<std::shared_ptr<RequestGroup>> groups;
214
  option_->put(PREF_DIR, "/tmp");
215 216
  Metalink2RequestGroup().generate(
      groups, A2_TEST_DIR "/metalink4-dosdirtraversal.xml", option_);
217
  CPPUNIT_ASSERT_EQUAL((size_t)3, groups.size());
218
  std::shared_ptr<RequestGroup> rg = groups[0];
219 220
  std::shared_ptr<FileEntry> file =
      rg->getDownloadContext()->getFirstFileEntry();
221 222
  CPPUNIT_ASSERT_EQUAL(std::string("/tmp/..%5C..%5Cexample.ext"),
                       file->getPath());
223

224 225 226 227 228 229 230 231 232 233 234 235
  rg = groups[2];
  file = rg->getDownloadContext()->getFileEntries()[0];
  CPPUNIT_ASSERT_EQUAL(std::string("/tmp/..%5C..%5Cfile1.ext"),
                       file->getPath());
  file = rg->getDownloadContext()->getFileEntries()[1];
  CPPUNIT_ASSERT_EQUAL(std::string("/tmp/..%5C..%5Cfile2.ext"),
                       file->getPath());
#endif // ENABLE_BITTORRENT
#endif // __MINGW32__
}

} // namespace aria2