#include <stdio.h>
#include <iostream>
+#define BOOST_TEST_MODULE fetcher_test
#include <boost/test/auto_unit_test.hpp>
#include <boost/test/parameterized_test.hpp>
#include <boost/test/unit_test_log.hpp>
#define DATADIR (Pathname(TESTS_SRC_DIR) + "/zypp/data/Fetcher/remote-site")
+BOOST_AUTO_TEST_SUITE( fetcher_test );
+
BOOST_AUTO_TEST_CASE(fetcher_enqueuedir_noindex)
{
MediaSetAccess media( ( DATADIR).asUrl(), "/" );
}
-BOOST_AUTO_TEST_CASE(fetcher_enqueue_digested_brokendir_with_index)
+BOOST_AUTO_TEST_CASE(fetcher_enqueue_digesteddir_brokendir_with_index)
{
MediaSetAccess media( ( DATADIR).asUrl(), "/" );
// do the test by trusting the SHA1SUMS file signature key but with a broken file
}
}
+BOOST_AUTO_TEST_CASE(fetcher_enqueue_digested_broken_with_autoindex)
+{
+ MediaSetAccess media( ( DATADIR).asUrl(), "/" );
+ // do the test by trusting the SHA1SUMS file signature key but with a broken file
+ {
+ filesystem::TmpDir dest;
+ Fetcher fetcher;
+ // add the key as trusted
+ getZYpp()->keyRing()->importKey(PublicKey(DATADIR + "/complexdir-broken/subdir1/SHA1SUMS.key"), true);
+ fetcher.setOptions( Fetcher::AutoAddIndexes );
+ fetcher.enqueueDigested(OnMediaLocation("/complexdir-broken/subdir1/subdir1-file1.txt"));
+ BOOST_CHECK_THROW( fetcher.start( dest.path(), media ), Exception);
+ fetcher.reset();
+ }
+}
+
+BOOST_AUTO_TEST_CASE(fetcher_enqueue_digested_with_autoindex)
+{
+ MediaSetAccess media( ( DATADIR).asUrl(), "/" );
+ // do the test by trusting the SHA1SUMS file signature key with a good file
+ // checksum in auto discovered index
+ {
+ filesystem::TmpDir dest;
+ Fetcher fetcher;
+ // add the key as trusted
+ getZYpp()->keyRing()->importKey(PublicKey(DATADIR + "/complexdir/subdir1/SHA1SUMS.key"), true);
+ fetcher.setOptions( Fetcher::AutoAddIndexes );
+ fetcher.enqueueDigested(OnMediaLocation("/complexdir/subdir1/subdir1-file1.txt"));
+ fetcher.start( dest.path(), media );
+ fetcher.reset();
+ }
+}
+
BOOST_AUTO_TEST_CASE(fetcher_enqueuefile_noindex)
{
{
MediaSetAccess media( ( DATADIR).asUrl(), "/" );
Fetcher fetcher;
-
+ filesystem::TmpDir dest;
{
- filesystem::TmpDir dest;
OnMediaLocation loc("/contentindex-broken-digest/subdir1/subdir1-file1.txt",1);
// key was already imported as trusted
fetcher.addIndex(OnMediaLocation("/contentindex-broken-digest/content", 1));
// now retrieve a file that is modified, so the checksum has to fail
loc = OnMediaLocation("/contentindex-broken-digest/subdir1/subdir1-file2.txt",1);
- fetcher.enqueue(loc);
- BOOST_CHECK_THROW( fetcher.start( dest.path(), media ), Exception);
- fetcher.reset();
- }
-}
-
-BOOST_AUTO_TEST_CASE(enqueue_digested_broken_content_index)
-{
- MediaSetAccess media( ( DATADIR).asUrl(), "/" );
- Fetcher fetcher;
-
- {
- filesystem::TmpDir dest;
- OnMediaLocation loc("/contentindex-broken-digest/subdir1/subdir1-file1.txt",1);
- // key was already imported as trusted
fetcher.addIndex(OnMediaLocation("/contentindex-broken-digest/content", 1));
- fetcher.enqueueDigested(loc);
- fetcher.start(dest.path(), media);
- fetcher.reset();
- // now retrieve a file that is modified, so the checksum has to fail
- loc = OnMediaLocation("/contentindex-broken-digest/subdir1/subdir1-file2.txt",1);
- fetcher.enqueueDigested(loc);
+ fetcher.enqueue(loc);
BOOST_CHECK_THROW( fetcher.start( dest.path(), media ), Exception);
fetcher.reset();
}
}
}
+BOOST_AUTO_TEST_SUITE_END();
// vim: set ts=2 sts=2 sw=2 ai et:
/**
* download the indexes and reads them
*/
- void readIndexes( MediaSetAccess &media, const Pathname &dest_dir);
+ void downloadAndReadIndexList( MediaSetAccess &media, const Pathname &dest_dir);
/**
* reads a downloaded index file and updates internal
/** specific version of \ref readIndex for SHA1SUMS file */
void readContentFileIndex( const Pathname &index, const Pathname &basedir );
+ /** reads the content of a directory but keeps a cache **/
+ void getDirectoryContent( MediaSetAccess &media, const OnMediaLocation &resource, filesystem::DirContent &content );
+
/**
* tries to provide the file represented by job into dest_dir by
* looking at the cache. If success, returns true, and the desired
list<Pathname> _caches;
// checksums read from the indexes
map<string, CheckSum> _checksums;
+ // cache of dir contents
+ map<string, filesystem::DirContent> _dircontent;
+
Fetcher::Options _options;
};
///////////////////////////////////////////////////////////////////
{
_resources.clear();
_indexes.clear();
+ _checksums.clear();
+ _dircontent.clear();
}
void Fetcher::Impl::addCachePath( const Pathname &cache_dir )
indexloc.changeFilename(resource.filename() + "SHA1SUMS");
addIndex(indexloc);
// we need to read it now
- readIndexes(media, dest_dir);
+ downloadAndReadIndexList(media, dest_dir);
}
}
if ( _options & AutoAddContentFileIndexes )
indexloc.changeFilename(resource.filename() + "content");
addIndex(indexloc);
// we need to read it now
- readIndexes(media, dest_dir);
+ downloadAndReadIndexList(media, dest_dir);
}
}
}
+
+ void Fetcher::Impl::getDirectoryContent( MediaSetAccess &media,
+ const OnMediaLocation &resource,
+ filesystem::DirContent &content )
+ {
+ if ( _dircontent.find(resource.filename().asString())
+ != _dircontent.end() )
+ {
+ filesystem::DirContent filled(_dircontent[resource.filename().asString()]);
+
+ std::copy(filled.begin(), filled.end(), std::back_inserter(content));
+ }
+ else
+ {
+ filesystem::DirContent tofill;
+ media.dirInfo( tofill,
+ resource.filename(),
+ false /* dots */,
+ resource.medianr());
+ std::copy(tofill.begin(), tofill.end(), std::back_inserter(content));
+ _dircontent[resource.filename().asString()] = tofill;
+ }
+ }
void Fetcher::Impl::addDirJobs( MediaSetAccess &media,
const OnMediaLocation &resource,
// individual transfer jobs
MIL << "Adding directory " << resource.filename() << endl;
filesystem::DirContent content;
- media.dirInfo( content, resource.filename(), false /* dots */, resource.medianr());
+ getDirectoryContent(media, resource, content);
// this method test for the option flags so indexes are added
// only if the options are enabled
}
else
WAR << "Resource " << filename << " has no checksum in the index either." << endl;
+
if ( flags & FetcherJob::AlwaysVerifyChecksum )
enqueueDigested(OnMediaLocation(filename, resource.medianr()).setChecksum(chksm));
else
ZYPP_THROW( Exception("Can't create " + dest_full_path.dirname().asString()));
if ( filesystem::copy(tmp_file, dest_full_path ) != 0 )
{
+ if ( ! PathInfo(tmp_file).isExist() )
+ ERR << tmp_file << " does not exist" << endl;
+ if ( ! PathInfo(dest_full_path.dirname()).isExist() )
+ ERR << dest_full_path.dirname() << " does not exist" << endl;
+
+ media.releaseFile(resource); //not needed anymore, only eat space
ZYPP_THROW( Exception("Can't copy " + tmp_file.asString() + " to " + dest_dir.asString()));
}
// this method takes all the user pointed indexes, gets them and also tries to
// download their signature, and verify them. After that, its parses each one
// to fill the checksum cache.
- void Fetcher::Impl::readIndexes( MediaSetAccess &media, const Pathname &dest_dir)
+ void Fetcher::Impl::downloadAndReadIndexList( MediaSetAccess &media, const Pathname &dest_dir)
{
// if there is no indexes, then just return to avoid
// the directory listing
ProgressData progress(_resources.size());
progress.sendTo(progress_receiver);
- readIndexes(media, dest_dir);
+ downloadAndReadIndexList(media, dest_dir);
for ( list<FetcherJob_Ptr>::const_iterator it_res = _resources.begin(); it_res != _resources.end(); ++it_res )
{
continue;
}
+ // may be this code can be factored out
+ // together with the autodiscovery of indexes
+ // of addDirJobs
+ if ( ( _options & AutoAddSha1sumsIndexes ) ||
+ ( _options & AutoAddContentFileIndexes ) )
+ {
+ // if auto indexing is enabled, then we need to read the
+ // index for each file. We look only in the directory
+ // where the file is. this is expensive of course.
+ filesystem::DirContent content;
+ getDirectoryContent(media, (*it_res)->location.filename().dirname(), content);
+ // this method test for the option flags so indexes are added
+ // only if the options are enabled
+ MIL << "Autodiscovering signed indexes on '"
+ << (*it_res)->location.filename().dirname() << "' for '"
+ << (*it_res)->location.filename() << "'" << endl;
+
+ autoaddIndexes(content, media, (*it_res)->location.filename().dirname(), dest_dir);
+ }
+
provideToDest(media, (*it_res)->location, dest_dir);
// if the checksum is empty, but the checksum is in one of the