From a13734d3ab648b8a21b1bc5542ac3e52d0f38b82 Mon Sep 17 00:00:00 2001 From: Eric Cano <Eric.Cano@cern.ch> Date: Fri, 11 Sep 2015 17:36:27 +0200 Subject: [PATCH] Added full emulation of a tape session in the archive_and_retrieve_new_file unit test for the scheduler. Fixed several bugs. --- common/MountControl.hpp | 11 +++++----- objectstore/TapePool.cpp | 9 ++++++++- scheduler/OStoreDB/OStoreDB.cpp | 1 + scheduler/OStoreDB/OStoreDBFactory.hpp | 10 +++++---- scheduler/Scheduler.cpp | 5 +++-- scheduler/SchedulerTest.cpp | 28 +++++++++++++++++++------- 6 files changed, 44 insertions(+), 20 deletions(-) diff --git a/common/MountControl.hpp b/common/MountControl.hpp index 74b98a7492..23225f74ab 100644 --- a/common/MountControl.hpp +++ b/common/MountControl.hpp @@ -30,18 +30,17 @@ namespace cta { uint64_t maxAge; /**< The maximum age for a request before trigerring * a request (in seconds) */ uint16_t quota; /**< The maximum number of mounts for this tape pool */ - MountCriteria(uint64_t maxFiles, uint64_t maxBytes, uint64_t maxAge, - uint16_t quota): - maxFilesQueued(maxFiles), maxBytesQueued(maxBytesQueued), maxAge(maxAge), - quota(quota) {} + MountCriteria(uint64_t mf, uint64_t mb, uint64_t ma, + uint16_t q): + maxFilesQueued(mf), maxBytesQueued(mb), maxAge(ma), quota(q) {} MountCriteria(): maxFilesQueued(0), maxBytesQueued(0), maxAge(0), quota(0) {} }; struct MountCriteriaByDirection { MountCriteria archive; MountCriteria retrieve; - MountCriteriaByDirection(const MountCriteria& archive, const MountCriteria & retrieve): - archive(archive), retrieve(retrieve) {} + MountCriteriaByDirection(const MountCriteria& a, const MountCriteria & r): + archive(a), retrieve(r) {} MountCriteriaByDirection(): archive(), retrieve() {} }; } \ No newline at end of file diff --git a/objectstore/TapePool.cpp b/objectstore/TapePool.cpp index a5c52bf5af..cf8e2166ec 100644 --- a/objectstore/TapePool.cpp +++ b/objectstore/TapePool.cpp @@ -372,7 +372,14 @@ cta::MountCriteriaByDirection void cta::objectstore::TapePool::setMountCriteriaByDirection( const MountCriteriaByDirection& mountCriteria) { checkPayloadWritable(); - + m_payload.mutable_archivemountcriteria()->set_maxbytesbeforemount(mountCriteria.archive.maxBytesQueued); + m_payload.mutable_archivemountcriteria()->set_maxfilesbeforemount(mountCriteria.archive.maxFilesQueued); + m_payload.mutable_archivemountcriteria()->set_maxsecondsbeforemount(mountCriteria.archive.maxAge); + m_payload.mutable_archivemountcriteria()->set_quota(mountCriteria.archive.quota); + m_payload.mutable_retievemountcriteria()->set_maxbytesbeforemount(mountCriteria.retrieve.maxBytesQueued); + m_payload.mutable_retievemountcriteria()->set_maxfilesbeforemount(mountCriteria.retrieve.maxFilesQueued); + m_payload.mutable_retievemountcriteria()->set_maxsecondsbeforemount(mountCriteria.retrieve.maxAge); + m_payload.mutable_retievemountcriteria()->set_quota(mountCriteria.retrieve.quota); } diff --git a/scheduler/OStoreDB/OStoreDB.cpp b/scheduler/OStoreDB/OStoreDB.cpp index 49a58d52da..d4c1df4210 100644 --- a/scheduler/OStoreDB/OStoreDB.cpp +++ b/scheduler/OStoreDB/OStoreDB.cpp @@ -96,6 +96,7 @@ std::unique_ptr<SchedulerDatabase::TapeMountDecisionInfo> if (tpool.getJobsSummary().files) { tmdi.potentialMounts.push_back(SchedulerDatabase::PotentialMount()); auto & m = tmdi.potentialMounts.back(); + m.tapePool = tpp->tapePool; m.type = cta::MountType::ARCHIVE; m.bytesQueued = tpool.getJobsSummary().bytes; m.filesQueued = tpool.getJobsSummary().files; diff --git a/scheduler/OStoreDB/OStoreDBFactory.hpp b/scheduler/OStoreDB/OStoreDBFactory.hpp index 00f197cc10..8b01c31cfe 100644 --- a/scheduler/OStoreDB/OStoreDBFactory.hpp +++ b/scheduler/OStoreDB/OStoreDBFactory.hpp @@ -69,10 +69,12 @@ public: } virtual ~OStoreDBWrapper() throw() { - m_OStoreDB.setAgent(*((objectstore::Agent*)NULL)); - objectstore::ScopedExclusiveLock agl(m_agent); - m_agent.fetch(); - m_agent.removeAndUnregisterSelf(); + try { + m_OStoreDB.setAgent(*((objectstore::Agent*)NULL)); + objectstore::ScopedExclusiveLock agl(m_agent); + m_agent.fetch(); + m_agent.removeAndUnregisterSelf(); + } catch (cta::exception::Exception &) {} } virtual void assertIsAdminOnAdminHost(const SecurityIdentity& id) const { diff --git a/scheduler/Scheduler.cpp b/scheduler/Scheduler.cpp index 0848149971..e4263d7833 100644 --- a/scheduler/Scheduler.cpp +++ b/scheduler/Scheduler.cpp @@ -817,11 +817,12 @@ std::unique_ptr<cta::TapeMount> cta::Scheduler::getNextMount( mountPassesACriteria = true; if (!existingMounts && ((time(NULL) - m->oldestJobStartTime) > (int64_t)m->mountCriteria.maxAge)) mountPassesACriteria = true; - if (!mountPassesACriteria || existingMounts > m->mountCriteria.quota) { + if (!mountPassesACriteria || existingMounts >= m->mountCriteria.quota) { m = mountInfo->potentialMounts.erase(m); } else { // populate the mount with a weight m->ratioOfMountQuotaUsed = 1.0L * existingMounts / m->mountCriteria.quota; + m++; } } @@ -844,7 +845,7 @@ std::unique_ptr<cta::TapeMount> cta::Scheduler::getNextMount( for (auto t=tapesList.begin(); t!=tapesList.end(); t++) { if (t->logicalLibraryName == logicalLibraryName && t->tapePoolName == m->tapePool && - !t->status.availableToWrite()) { + t->status.availableToWrite()) { // We have our tape. Try to create the session. Prepare a return value // for it. std::unique_ptr<ArchiveMount> internalRet(new ArchiveMount); diff --git a/scheduler/SchedulerTest.cpp b/scheduler/SchedulerTest.cpp index 6c737c4ebb..bf79bdd2bf 100644 --- a/scheduler/SchedulerTest.cpp +++ b/scheduler/SchedulerTest.cpp @@ -25,11 +25,11 @@ #include "scheduler/ArchiveToFileRequest.hpp" #include "scheduler/ArchiveToTapeCopyRequest.hpp" #include "scheduler/LogicalLibrary.hpp" -//#include "scheduler/mockDB/MockSchedulerDatabaseFactory.hpp" #include "scheduler/MountRequest.hpp" #include "scheduler/Scheduler.hpp" #include "scheduler/SchedulerDatabase.hpp" #include "scheduler/TapeMount.hpp" +#include "scheduler/ArchiveMount.hpp" #include "common/SecurityIdentity.hpp" #include "common/archiveNS/StorageClass.hpp" #include "common/archiveNS/Tape.hpp" @@ -2287,8 +2287,8 @@ TEST_P(SchedulerTest, archive_and_retrieve_new_file) { const std::string tapePoolComment = "Tape-pool comment"; ASSERT_NO_THROW(scheduler.createTapePool(s_adminOnAdminHost, tapePoolName, nbPartialTapes, tapePoolComment)); - MountCriteriaByDirection mcbd(MountCriteria(0,0,0,1), MountCriteria(0,0,0,1)); - ASSERT_NO_THROW(scheduler.setTapePoolMountCriteria("TapeTapePool", mcbd)); + MountCriteriaByDirection mcbd(MountCriteria(1,1,0,1), MountCriteria(1,1,0,1)); + ASSERT_NO_THROW(scheduler.setTapePoolMountCriteria("TestTapePool", mcbd)); const std::string libraryName = "TestLogicalLibrary"; const std::string libraryComment = "Library comment"; @@ -2405,10 +2405,24 @@ TEST_P(SchedulerTest, archive_and_retrieve_new_file) { s_remoteFileRawPath1), std::exception); } - // Emulate a tape server by asking for a mount and then a file - std::unique_ptr<cta::TapeMount> mount; - ASSERT_NO_THROW(mount.reset(scheduler.getNextMount(libraryName, "drive0").release())); - ASSERT_NE((cta::TapeMount*)NULL, mount.get()); + { + // Emulate a tape server by asking for a mount and then a file (and succeed + // the transfer) + std::unique_ptr<cta::TapeMount> mount; + ASSERT_NO_THROW(mount.reset(scheduler.getNextMount(libraryName, "drive0").release())); + ASSERT_NE((cta::TapeMount*)NULL, mount.get()); + ASSERT_EQ(cta::MountType::ARCHIVE, mount.get()->getMountType()); + std::unique_ptr<cta::ArchiveMount> archiveMount; + ASSERT_NO_THROW(archiveMount.reset(dynamic_cast<cta::ArchiveMount*>(mount.release()))); + ASSERT_NE((cta::ArchiveMount*)NULL, archiveMount.get()); + std::unique_ptr<cta::ArchiveJob> archiveJob; + ASSERT_NO_THROW(archiveJob.reset(archiveMount->getNextJob().release())); + ASSERT_NE((cta::ArchiveJob*)NULL, archiveJob.get()); + archiveJob->complete(); + ASSERT_NO_THROW(archiveJob.reset(archiveMount->getNextJob().release())); + ASSERT_EQ((cta::ArchiveJob*)NULL, archiveJob.get()); + ASSERT_NO_THROW(archiveMount->complete()); + } { std::list<std::string> archiveFiles; -- GitLab