Commit ba7cb07b authored by Steven Murray's avatar Steven Murray
Browse files

Replaced application-level cursor over archive file listings with a database cursor

parent ae06de9d
/*
* The CERN Tape Archive (CTA) project
* Copyright (C) 2015 CERN
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "catalogue/ArchiveFileBuilder.hpp"
#include "common/exception/Exception.hpp"
namespace cta {
namespace catalogue {
//------------------------------------------------------------------------------
// append
//------------------------------------------------------------------------------
std::unique_ptr<common::dataStructures::ArchiveFile> ArchiveFileBuilder::append(
const common::dataStructures::ArchiveFile &tapeFile) {
// If there is currently no ArchiveFile object under construction
if(nullptr == m_archiveFile.get()) {
// If the tape file represents an ArchiveFile object with no tape files
if(tapeFile.tapeFiles.empty()) {
// Archive file is already complete
return std::unique_ptr<common::dataStructures::ArchiveFile>(new common::dataStructures::ArchiveFile(tapeFile));
}
// If the tape file exists then it must be alone
if(tapeFile.tapeFiles.size() != 1) {
exception::Exception ex;
ex.getMessage() << __FUNCTION__ << " failed: Expected exactly one tape file to be appended at a time: actual=" <<
tapeFile.tapeFiles.size();
throw ex;
}
// Start constructing one
m_archiveFile.reset(new common::dataStructures::ArchiveFile(tapeFile));
// There could be more tape files so return incomplete
return std::unique_ptr<common::dataStructures::ArchiveFile>();
}
// If the tape file represents an ArchiveFile object with no tape files
if(tapeFile.tapeFiles.empty()) {
// The ArchiveFile object under construction is complete,
// therefore return it and start the construction of the next
std::unique_ptr<common::dataStructures::ArchiveFile> tmp;
tmp = std::move(m_archiveFile);
m_archiveFile.reset(new common::dataStructures::ArchiveFile(tapeFile));
return tmp;
}
// If the tape file to be appended belongs to the ArchiveFile object
// currently under construction
if(tapeFile.archiveFileID == m_archiveFile->archiveFileID) {
// The tape file must exist and must be alone
if(tapeFile.tapeFiles.size() != 1) {
exception::Exception ex;
ex.getMessage() << __FUNCTION__ << " failed: Expected exactly one tape file to be appended at a time: actual=" <<
tapeFile.tapeFiles.size() << " archiveFileID=" << tapeFile.archiveFileID;
throw ex;
}
// Append the tape file
const auto tapeFileMapItor = tapeFile.tapeFiles.begin();
const auto copyNbOfTapeFileToAppend = tapeFileMapItor->first;
if(m_archiveFile->tapeFiles.find(copyNbOfTapeFileToAppend) != m_archiveFile->tapeFiles.end()) {
exception::Exception ex;
ex.getMessage() << __FUNCTION__ << " failed: Found two tape files for the same archive file with the same copy"
" numbers: archiveFileID=" << tapeFile.archiveFileID << " copyNb=" << copyNbOfTapeFileToAppend;
throw ex;
}
m_archiveFile->tapeFiles[copyNbOfTapeFileToAppend] = tapeFileMapItor->second;
// There could be more tape files so return incomplete
return std::unique_ptr<common::dataStructures::ArchiveFile>();
}
// Reaching this point means the tape file to be appended belongs to the next
// ArchiveFile to be constructed.
// ArchiveFile object under construction is complete,
// therefore return it and start the construction of the next
std::unique_ptr<common::dataStructures::ArchiveFile> tmp;
tmp = std::move(m_archiveFile);
m_archiveFile.reset(new common::dataStructures::ArchiveFile(tapeFile));
return tmp;
}
//------------------------------------------------------------------------------
// getArchiveFile
//------------------------------------------------------------------------------
common::dataStructures::ArchiveFile *ArchiveFileBuilder::getArchiveFile() {
return m_archiveFile.get();
}
//------------------------------------------------------------------------------
// clear
//------------------------------------------------------------------------------
void ArchiveFileBuilder::clear() {
m_archiveFile.reset();
}
} // namespace catalogue
} // namespace cta
/*
* The CERN Tape Archive (CTA) project
* Copyright (C) 2015 CERN
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include "common/dataStructures/ArchiveFile.hpp"
#include <memory>
namespace cta {
namespace catalogue {
/**
* Builds ArchiveFile objects from a stream of tape files ordered by archive ID
* and then copy number.
*/
class ArchiveFileBuilder {
public:
/**
* Appends the specified tape file to the ArchiveFile object currently
* construction.
*
* If this append method is called with the tape file of the next ArchiveFile
* to be constructed then this means the current ArchiveFile under
* construction is complete and this method will therefore return the current
* and complete ArchiveFile object. The appened tape file will be remembered
* by this builder object and used to start the construction of the next
* ArchiveFile object.
*
* If this append method is called with an ArchiveFile with no tape files at
* all then this means the current ArchiveFile under
* construction is complete and this method will therefore return the current
* and complete ArchiveFile object. The appened tape file will be remembered
* by this builder object and used to start the construction of the next
* ArchiveFile object.
*
* If the call to this append does not complete the ArchiveFile object
* currently under construction then this method will returns an empty unique
* pointer.
*
* @param tapeFile The tape file to be appended or an archive file with no
* tape files at all.
*/
std::unique_ptr<common::dataStructures::ArchiveFile> append(const common::dataStructures::ArchiveFile &tapeFile);
/**
* Returns a pointer to the ArchiveFile object currently under construction.
* A return value of nullptr means there there is no ArchiveFile object
* currently under construction.
*
* @return The ArchiveFile object currently under construction or nullptr
* if there isn't one.
*/
common::dataStructures::ArchiveFile *getArchiveFile();
/**
* If there is an ArchiveFile under construction then it is forgotten.
*/
void clear();
private:
/**
* The Archivefile object currently under construction.
*/
std::unique_ptr<common::dataStructures::ArchiveFile> m_archiveFile;
}; // class ArchiveFileBuilder
} // namespace catalogue
} // namespace cta
......@@ -67,7 +67,7 @@ ArchiveFileItor &ArchiveFileItor::operator=(ArchiveFileItor &&rhs) {
//------------------------------------------------------------------------------
// hasMore
//------------------------------------------------------------------------------
bool ArchiveFileItor::hasMore() const {
bool ArchiveFileItor::hasMore() {
if(nullptr == m_impl) {
throw exception::Exception(std::string(__FUNCTION__) + " failed: "
"This iterator is invalid");
......
......@@ -84,7 +84,7 @@ public:
/**
* Returns true if a call to next would return another archive file.
*/
bool hasMore() const;
bool hasMore();
/**
* Returns the next archive or throws an exception if there isn't one.
......
......@@ -38,7 +38,7 @@ public:
/**
* Returns true if a call to next would return another archive file.
*/
virtual bool hasMore() const = 0;
virtual bool hasMore() = 0;
/**
* Returns the next archive or throws an exception if there isn't one.
......
......@@ -34,6 +34,7 @@ endif(OCCI_SUPPORT)
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wshadow")
set (CATALOGUE_LIB_SRC_FILES
ArchiveFileBuilder.cpp
ArchiveFileRow.cpp
ArchiveFileItor.cpp
ArchiveFileItorImpl.cpp
......
......@@ -448,23 +448,14 @@ public:
virtual void modifyMountPolicyComment(const common::dataStructures::SecurityIdentity &admin, const std::string &name, const std::string &comment) = 0;
/**
* Returns an iterator over the list of archive files that meet the specified
* search criteria.
*
* Please note that the list is ordered by archive file ID.
*
* Please note that this method will throw an exception if the
* nbArchiveFilesToPrefetch parameter is set to 0. The parameter must be set
* to a value greater than or equal to 1.
* Returns the specified archive files. Please note that the list of files
* is ordered by archive file ID.
*
* @param searchCriteria The search criteria.
* @param nbArchiveFilesToPrefetch The number of archive files to prefetch.
* This parameter must be set to a value equal to or greater than 1.
* @return An iterator over the list of archive files.
* @return The archive files.
*/
virtual ArchiveFileItor getArchiveFileItor(
const TapeFileSearchCriteria &searchCriteria = TapeFileSearchCriteria(),
const uint64_t nbArchiveFilesToPrefetch = 1000) const = 0;
virtual ArchiveFileItor getArchiveFiles(
const TapeFileSearchCriteria &searchCriteria = TapeFileSearchCriteria()) const = 0;
/**
* Returns a summary of the tape files that meet the specified search
......
......@@ -29,15 +29,17 @@ namespace catalogue {
//------------------------------------------------------------------------------
// create
//------------------------------------------------------------------------------
std::unique_ptr<Catalogue> CatalogueFactory::create(const rdbms::Login &login, const uint64_t nbConns) {
std::unique_ptr<Catalogue> CatalogueFactory::create(const rdbms::Login &login, const uint64_t nbConns,
const uint64_t nbArchiveFileListingConns) {
try {
switch(login.dbType) {
case rdbms::Login::DBTYPE_IN_MEMORY:
return cta::make_unique<InMemoryCatalogue>(nbConns);
return cta::make_unique<InMemoryCatalogue>(nbConns, nbArchiveFileListingConns);
case rdbms::Login::DBTYPE_ORACLE:
return cta::make_unique<OracleCatalogue>(login.username, login.password, login.database, nbConns);
return cta::make_unique<OracleCatalogue>(login.username, login.password, login.database, nbConns,
nbArchiveFileListingConns);
case rdbms::Login::DBTYPE_SQLITE:
return cta::make_unique<SqliteCatalogue>(login.database, nbConns);
return cta::make_unique<SqliteCatalogue>(login.database, nbConns, nbArchiveFileListingConns);
case rdbms::Login::DBTYPE_NONE:
throw exception::Exception("Cannot create a catalogue without a database type");
default:
......
......@@ -43,11 +43,16 @@ public:
*
* @param login The database connection details.
* @param nbConns The maximum number of concurrent connections to the
* underlying relational database.
* underlying relational database for all operations accept listing archive
* files which can be relatively long operations.
* @param nbArchiveFileListingConns The maximum number of concurrent
* connections to the underlying relational database for the sole purpose of
* listing archive files.
* @return The newly created CTA catalogue object. Please note that it is the
* responsibility of the caller to delete the returned CTA catalogue object.
*/
static std::unique_ptr<Catalogue> create(const rdbms::Login &login, const uint64_t nbConns);
static std::unique_ptr<Catalogue> create(const rdbms::Login &login, const uint64_t nbConns,
const uint64_t nbArchiveFileListingConns = 5);
}; // class CatalogueFactory
......
......@@ -91,7 +91,7 @@ void cta_catalogue_CatalogueTest::SetUp() {
}
}
{
auto itor = m_catalogue->getArchiveFileItor();
auto itor = m_catalogue->getArchiveFiles();
while(itor.hasMore()) {
const auto archiveFile = itor.next();
m_catalogue->deleteArchiveFile(archiveFile.diskInstance, archiveFile.archiveFileID);
......@@ -4722,7 +4722,7 @@ TEST_P(cta_catalogue_CatalogueTest, prepareToRetrieveFile) {
const uint64_t archiveFileId = 1234;
ASSERT_FALSE(m_catalogue->getArchiveFileItor().hasMore());
ASSERT_FALSE(m_catalogue->getArchiveFiles().hasMore());
ASSERT_THROW(m_catalogue->getArchiveFileById(archiveFileId), exception::Exception);
common::dataStructures::StorageClass storageClass;
......@@ -4895,112 +4895,106 @@ TEST_P(cta_catalogue_CatalogueTest, prepareToRetrieveFile) {
exception::UserError);
}
TEST_P(cta_catalogue_CatalogueTest, getArchiveFileItor_zero_prefetch) {
TEST_P(cta_catalogue_CatalogueTest, getArchiveFiles_non_existance_archiveFileId) {
using namespace cta;
ASSERT_THROW(m_catalogue->getArchiveFileItor(catalogue::TapeFileSearchCriteria(), 0), exception::Exception);
}
TEST_P(cta_catalogue_CatalogueTest, getArchiveFileItor_non_existance_archiveFileId) {
using namespace cta;
ASSERT_FALSE(m_catalogue->getArchiveFileItor().hasMore());
ASSERT_FALSE(m_catalogue->getArchiveFiles().hasMore());
catalogue::TapeFileSearchCriteria searchCriteria;
searchCriteria.archiveFileId = 1234;
ASSERT_THROW(m_catalogue->getArchiveFileItor(searchCriteria, 1), exception::UserError);
ASSERT_THROW(m_catalogue->getArchiveFiles(searchCriteria), exception::UserError);
}
TEST_P(cta_catalogue_CatalogueTest, getArchiveFileItor_disk_file_group_without_instance) {
TEST_P(cta_catalogue_CatalogueTest, getArchiveFiles_disk_file_group_without_instance) {
using namespace cta;
ASSERT_FALSE(m_catalogue->getArchiveFileItor().hasMore());
ASSERT_FALSE(m_catalogue->getArchiveFiles().hasMore());
catalogue::TapeFileSearchCriteria searchCriteria;
searchCriteria.diskFileGroup = "disk_file_group";
ASSERT_THROW(m_catalogue->getArchiveFileItor(searchCriteria, 1), exception::UserError);
ASSERT_THROW(m_catalogue->getArchiveFiles(searchCriteria), exception::UserError);
}
TEST_P(cta_catalogue_CatalogueTest, getArchiveFileItor_non_existant_disk_file_group) {
TEST_P(cta_catalogue_CatalogueTest, getArchiveFiles_non_existant_disk_file_group) {
using namespace cta;
ASSERT_FALSE(m_catalogue->getArchiveFileItor().hasMore());
ASSERT_FALSE(m_catalogue->getArchiveFiles().hasMore());
catalogue::TapeFileSearchCriteria searchCriteria;
searchCriteria.diskInstance = "non_existant_disk_instance";
searchCriteria.diskFileGroup = "non_existant_disk_file_group";
ASSERT_THROW(m_catalogue->getArchiveFileItor(searchCriteria, 1), exception::UserError);
ASSERT_THROW(m_catalogue->getArchiveFiles(searchCriteria), exception::UserError);
}
TEST_P(cta_catalogue_CatalogueTest, getArchiveFileItor_disk_file_id_without_instance) {
TEST_P(cta_catalogue_CatalogueTest, getArchiveFiles_disk_file_id_without_instance) {
using namespace cta;
ASSERT_FALSE(m_catalogue->getArchiveFileItor().hasMore());
ASSERT_FALSE(m_catalogue->getArchiveFiles().hasMore());
catalogue::TapeFileSearchCriteria searchCriteria;
searchCriteria.diskFileId = "disk_file_id";
ASSERT_THROW(m_catalogue->getArchiveFileItor(searchCriteria, 1), exception::UserError);
ASSERT_THROW(m_catalogue->getArchiveFiles(searchCriteria), exception::UserError);
}
TEST_P(cta_catalogue_CatalogueTest, getArchiveFileItor_non_existant_disk_file_id) {
TEST_P(cta_catalogue_CatalogueTest, getArchiveFiles_non_existant_disk_file_id) {
using namespace cta;
ASSERT_FALSE(m_catalogue->getArchiveFileItor().hasMore());
ASSERT_FALSE(m_catalogue->getArchiveFiles().hasMore());
catalogue::TapeFileSearchCriteria searchCriteria;
searchCriteria.diskInstance = "non_existant_disk_instance";
searchCriteria.diskFileId = "non_existant_disk_file_id";
ASSERT_THROW(m_catalogue->getArchiveFileItor(searchCriteria, 1), exception::UserError);
ASSERT_THROW(m_catalogue->getArchiveFiles(searchCriteria), exception::UserError);
}
TEST_P(cta_catalogue_CatalogueTest, getArchiveFileItor_disk_file_path_without_instance) {
TEST_P(cta_catalogue_CatalogueTest, getArchiveFiles_disk_file_path_without_instance) {
using namespace cta;
ASSERT_FALSE(m_catalogue->getArchiveFileItor().hasMore());
ASSERT_FALSE(m_catalogue->getArchiveFiles().hasMore());
catalogue::TapeFileSearchCriteria searchCriteria;
searchCriteria.diskFilePath = "disk_file_path";
ASSERT_THROW(m_catalogue->getArchiveFileItor(searchCriteria, 1), exception::UserError);
ASSERT_THROW(m_catalogue->getArchiveFiles(searchCriteria), exception::UserError);
}
TEST_P(cta_catalogue_CatalogueTest, getArchiveFileItor_non_existant_disk_file_path) {
TEST_P(cta_catalogue_CatalogueTest, getArchiveFiles_non_existant_disk_file_path) {
using namespace cta;
ASSERT_FALSE(m_catalogue->getArchiveFileItor().hasMore());
ASSERT_FALSE(m_catalogue->getArchiveFiles().hasMore());
catalogue::TapeFileSearchCriteria searchCriteria;
searchCriteria.diskInstance = "non_existant_disk_instance";
searchCriteria.diskFilePath = "non_existant_disk_file_path";
ASSERT_THROW(m_catalogue->getArchiveFileItor(searchCriteria, 1), exception::UserError);
ASSERT_THROW(m_catalogue->getArchiveFiles(searchCriteria), exception::UserError);
}
TEST_P(cta_catalogue_CatalogueTest, getArchiveFileItor_disk_file_user_without_instance) {
TEST_P(cta_catalogue_CatalogueTest, getArchiveFiles_disk_file_user_without_instance) {
using namespace cta;
ASSERT_FALSE(m_catalogue->getArchiveFileItor().hasMore());
ASSERT_FALSE(m_catalogue->getArchiveFiles().hasMore());
catalogue::TapeFileSearchCriteria searchCriteria;
searchCriteria.diskFileUser = "disk_file_user";
ASSERT_THROW(m_catalogue->getArchiveFileItor(searchCriteria, 1), exception::UserError);
ASSERT_THROW(m_catalogue->getArchiveFiles(searchCriteria), exception::UserError);
}
TEST_P(cta_catalogue_CatalogueTest, getArchiveFileItor_non_existant_disk_file_user) {
TEST_P(cta_catalogue_CatalogueTest, getArchiveFiles_non_existant_disk_file_user) {
using namespace cta;
ASSERT_FALSE(m_catalogue->getArchiveFileItor().hasMore());
ASSERT_FALSE(m_catalogue->getArchiveFiles().hasMore());
catalogue::TapeFileSearchCriteria searchCriteria;
searchCriteria.diskInstance = "non_existant_disk_instance";
searchCriteria.diskFileUser = "non_existant_disk_file_user";
ASSERT_THROW(m_catalogue->getArchiveFileItor(searchCriteria, 1), exception::UserError);
ASSERT_THROW(m_catalogue->getArchiveFiles(searchCriteria), exception::UserError);
}
TEST_P(cta_catalogue_CatalogueTest, getArchiveFileItor_existant_storage_class_without_disk_instance) {
TEST_P(cta_catalogue_CatalogueTest, getArchiveFiles_existant_storage_class_without_disk_instance) {
using namespace cta;
ASSERT_TRUE(m_catalogue->getStorageClasses().empty());
......@@ -5032,46 +5026,46 @@ TEST_P(cta_catalogue_CatalogueTest, getArchiveFileItor_existant_storage_class_wi
ASSERT_EQ(creationLog, lastModificationLog);
}
ASSERT_FALSE(m_catalogue->getArchiveFileItor().hasMore());
ASSERT_FALSE(m_catalogue->getArchiveFiles().hasMore());
catalogue::TapeFileSearchCriteria searchCriteria;
searchCriteria.storageClass = storageClass.name;
ASSERT_THROW(m_catalogue->getArchiveFileItor(searchCriteria, 1), exception::UserError);
ASSERT_THROW(m_catalogue->getArchiveFiles(searchCriteria), exception::UserError);
}
TEST_P(cta_catalogue_CatalogueTest, getArchiveFileItor_non_existant_storage_class) {
TEST_P(cta_catalogue_CatalogueTest, getArchiveFiles_non_existant_storage_class) {
using namespace cta;
ASSERT_FALSE(m_catalogue->getArchiveFileItor().hasMore());
ASSERT_FALSE(m_catalogue->getArchiveFiles().hasMore());
catalogue::TapeFileSearchCriteria searchCriteria;
searchCriteria.diskInstance = "non_existant_disk_instance";
searchCriteria.storageClass = "non_existant_storage_class";
ASSERT_THROW(m_catalogue->getArchiveFileItor(searchCriteria, 1), exception::UserError);
ASSERT_THROW(m_catalogue->getArchiveFiles(searchCriteria), exception::UserError);
}
TEST_P(cta_catalogue_CatalogueTest, getArchiveFileItor_non_existant_tape_pool) {
TEST_P(cta_catalogue_CatalogueTest, getArchiveFiles_non_existant_tape_pool) {
using namespace cta;
ASSERT_FALSE(m_catalogue->getArchiveFileItor().hasMore());
ASSERT_FALSE(m_catalogue->getArchiveFiles().hasMore());
catalogue::TapeFileSearchCriteria searchCriteria;
searchCriteria.tapePool = "non_existant_tape_pool";
ASSERT_THROW(m_catalogue->getArchiveFileItor(searchCriteria, 1), exception::UserError);
ASSERT_THROW(m_catalogue->getArchiveFiles(searchCriteria), exception::UserError);
}
TEST_P(cta_catalogue_CatalogueTest, getArchiveFileItor_non_existant_vid) {
TEST_P(cta_catalogue_CatalogueTest, getArchiveFiles_non_existant_vid) {
using namespace cta;
ASSERT_FALSE(m_catalogue->getArchiveFileItor().hasMore());
ASSERT_FALSE(m_catalogue->getArchiveFiles().hasMore());
catalogue::TapeFileSearchCriteria searchCriteria;
searchCriteria.vid = "non_existant_vid";
ASSERT_THROW(m_catalogue->getArchiveFileItor(searchCriteria, 1), exception::UserError);
ASSERT_THROW(m_catalogue->getArchiveFiles(searchCriteria), exception::UserError);
}
TEST_P(cta_catalogue_CatalogueTest, fileWrittenToTape_many_archive_files) {
......@@ -5160,7 +5154,7 @@ TEST_P(cta_catalogue_CatalogueTest, fileWrittenToTape_many_archive_files) {
const std::string checksumValue = "checksum_value";
const std::string tapeDrive = "tape_drive";
ASSERT_FALSE(m_catalogue->getArchiveFileItor().hasMore());
ASSERT_FALSE(m_catalogue->getArchiveFiles().hasMore());
const uint64_t nbArchiveFiles = 10;
const uint64_t archiveFileSize = 1000;
const uint64_t compressedFileSize = 800;
......@@ -5261,279 +5255,276 @@ TEST_P(cta_catalogue_CatalogueTest, fileWrittenToTape_many_archive_files) {
}
}
std::list<uint64_t> prefetches = {1, 2, 3, nbArchiveFiles - 1, nbArchiveFiles, nbArchiveFiles+1, nbArchiveFiles*2};
for(auto prefetch: prefetches) {
{
catalogue::TapeFileSearchCriteria searchCriteria;
searchCriteria.archiveFileId = 1;
searchCriteria.diskInstance = storageClass.diskInstance;
searchCriteria.diskFileId = std::to_string(12345678);
searchCriteria.diskFilePath = "/public_dir/public_file_1";
searchCriteria.diskFileUser = "public_disk_user";
searchCriteria.diskFileGroup = "public_disk_group";
searchCriteria.storageClass = storageClass.name;
searchCriteria.vid = vid1;
searchCriteria.tapeFileCopyNb = 1;
searchCriteria.tapePool = tapePoolName;
auto archiveFileItor = m_catalogue->getArchiveFileItor(searchCriteria, prefetch);
std::map<uint64_t, common::dataStructures::ArchiveFile> m = archiveFileItorToMap(archiveFileItor);
ASSERT_EQ(1, m.size());
const auto idAndFile = m.find(1);
{
catalogue::TapeFileSearchCriteria searchCriteria;
searchCriteria.archiveFileId = 1;
searchCriteria.diskInstance = storageClass.diskInstance;
searchCriteria.diskFileId = std::to_string(12345678);
searchCriteria.diskFilePath = "/public_dir/public_file_1";
searchCriteria.diskFileUser = "public_disk_user";
searchCriteria.diskFileGroup = "public_disk_group";
searchCriteria.storageClass = storageClass.name;
searchCriteria.vid = vid1;
searchCriteria.tapeFileCopyNb = 1;
searchCriteria.tapePool = tapePoolName;
auto archiveFileItor = m_catalogue->getArchiveFiles(searchCriteria);
std::map<uint64_t, common::dataStructures::ArchiveFile> m = archiveFileItorToMap(archiveFileItor);
ASSERT_EQ(1, m.size());
const auto idAndFile = m.find(1);
ASSERT_FALSE(m.end() == idAndFile);
const common::dataStructures::ArchiveFile archiveFile = idAndFile->second;
ASSERT_EQ(searchCriteria.archiveFileId, archiveFile.archiveFileID);
ASSERT_EQ(searchCriteria.diskInstance, archiveFile.diskInstance);
ASSERT_EQ(searchCriteria.diskFileId, archiveFile.diskFileId);
ASSERT_EQ(searchCriteria.diskFilePath, archiveFile.diskFileInfo.path);
ASSERT_EQ(searchCriteria.diskFileUser, archiveFile.diskFileInfo.owner);
ASSERT_EQ(searchCriteria.diskFileGroup, archiveFile.diskFileInfo.group);
ASSERT_EQ(searchCriteria.storageClass, archiveFile.storageClass);
ASSERT_EQ(1, archiveFile.tapeFiles.size());
ASSERT_EQ(searchCriteria.vid, archiveFile.tapeFiles.begin()->second.vid);
}
{
auto archiveFileItor = m_catalogue->getArchiveFiles();
std::map<uint64_t, common::dataStructures::ArchiveFile> m = archiveFileItorToMap(archiveFileItor);
ASSERT_EQ(nbArchiveFiles, m.size());