From dafd641756cddb584d52faba93a811253f044e32 Mon Sep 17 00:00:00 2001
From: Eric Cano <Eric.Cano@cern.ch>
Date: Fri, 2 Oct 2015 19:20:15 +0200
Subject: [PATCH] Completed support for tape density and add usage of at() in a
 vector access to prevent segfault in unit test. Removed some throw()
 specifications which led to segfaults.

---
 objectstore/Tape.cpp                          | 16 ++++++++-
 objectstore/Tape.hpp                          |  7 ++--
 objectstore/TapePool.cpp                      |  6 ++--
 objectstore/TapePool.hpp                      |  5 +--
 objectstore/TapeTest.cpp                      |  2 +-
 objectstore/cta.proto                         | 33 ++++++++---------
 scheduler/ArchiveMount.cpp                    | 22 ++++++------
 scheduler/ArchiveMount.hpp                    | 12 +++----
 scheduler/OStoreDB/OStoreDB.cpp               |  9 +++--
 scheduler/OStoreDB/OStoreDB.hpp               |  2 +-
 scheduler/OStoreDB/OStoreDBFactory.hpp        |  4 +--
 scheduler/RetrieveMount.cpp                   | 18 ++++++----
 scheduler/RetrieveMount.hpp                   |  8 ++---
 scheduler/Scheduler.cpp                       |  7 ++--
 scheduler/Scheduler.hpp                       |  5 +--
 scheduler/SchedulerDatabase.hpp               |  2 ++
 scheduler/SchedulerDatabaseTest.cpp           | 12 +++----
 scheduler/SchedulerTest.cpp                   | 24 ++++++-------
 scheduler/TapeMount.hpp                       |  8 ++---
 .../daemon/DataTransferSessionTest.cpp        | 36 ++++++++++++-------
 .../daemon/RecallTaskInjectorTest.cpp         |  2 +-
 .../tape/tapeserver/drive/FakeDrive.cpp       |  2 +-
 xroot_plugins/XrdProFile.cpp                  | 17 +++++----
 23 files changed, 150 insertions(+), 109 deletions(-)

diff --git a/objectstore/Tape.cpp b/objectstore/Tape.cpp
index ca8ce93ca4..86f8196972 100644
--- a/objectstore/Tape.cpp
+++ b/objectstore/Tape.cpp
@@ -32,12 +32,14 @@ cta::objectstore::Tape::Tape(GenericObject& go):
 }
 
 void cta::objectstore::Tape::initialize(const std::string &name, 
-    const std::string &logicallibrary, const cta::CreationLog & creationLog) {
+    const std::string &logicallibrary, const std::string & density, 
+    const cta::CreationLog & creationLog) {
   ObjectOps<serializers::Tape>::initialize();
   // Set the reguired fields
   objectstore::CreationLog oscl(creationLog);
   oscl.serialize(*m_payload.mutable_log());
   m_payload.set_vid(name);
+  m_payload.set_density(density);
   m_payload.set_bytesstored(0);
   m_payload.set_lastfseq(0);
   m_payload.set_logicallibrary(logicallibrary);
@@ -117,6 +119,18 @@ std::string cta::objectstore::Tape::getVid() {
   return m_payload.vid();
 }
 
+void cta::objectstore::Tape::setDensity(const std::string& density) {
+  checkPayloadWritable();
+  m_payload.set_density(density);
+}
+
+std::string cta::objectstore::Tape::getDensity() {
+  checkPayloadReadable();
+  return m_payload.density();
+}
+
+
+
 std::string cta::objectstore::Tape::dump() {
   checkPayloadReadable();
   std::stringstream ret;
diff --git a/objectstore/Tape.hpp b/objectstore/Tape.hpp
index 347ef1c85b..f1e51cd8c7 100644
--- a/objectstore/Tape.hpp
+++ b/objectstore/Tape.hpp
@@ -35,7 +35,7 @@ public:
   Tape(const std::string & address, Backend & os);
   Tape(GenericObject & go);
   void initialize(const std::string & vid, const std::string &logicalLibrary, 
-    const cta::CreationLog & creationLog);
+    const std::string & density, const cta::CreationLog & creationLog);
   void garbageCollect();
   bool isEmpty();
   CTA_GENERATE_EXCEPTION_CLASS(NotEmpty);
@@ -89,11 +89,14 @@ public:
   
   // -- Stored data counting ---------------------------------------------------
   uint64_t getStoredData();
-  std::string getVid();
   void setStoredData(uint64_t bytes);
   void addStoredData(uint64_t bytes);
   void setLastFseq(uint64_t lastFseq);
   uint64_t getLastFseq();
+  // -- Generic parameters
+  std::string getVid();
+  std::string getDensity();
+  void setDensity(const std::string &density);
 };
 
 }}
\ No newline at end of file
diff --git a/objectstore/TapePool.cpp b/objectstore/TapePool.cpp
index 46146da2c8..613892aa26 100644
--- a/objectstore/TapePool.cpp
+++ b/objectstore/TapePool.cpp
@@ -73,8 +73,8 @@ namespace {
 }
 
 std::string cta::objectstore::TapePool::addOrGetTapeAndCommit(const std::string& vid, 
-  const std::string& logicalLibraryName, const uint64_t capacityInBytes, 
-  Agent& agent, const cta::CreationLog& creationLog) {
+  const std::string& logicalLibraryName, const uint64_t capacityInBytes,
+  const std::string &density, Agent& agent, const cta::CreationLog& creationLog) {
   checkPayloadWritable();
   // Check the tape already exists
   try {
@@ -90,7 +90,7 @@ std::string cta::objectstore::TapePool::addOrGetTapeAndCommit(const std::string&
   agent.commit();
   // The create the tape object
   Tape t(tapeAddress, ObjectOps<serializers::TapePool>::m_objectStore);
-  t.initialize(vid, logicalLibraryName, creationLog);
+  t.initialize(vid, logicalLibraryName, density, creationLog);
   t.setOwner(agent.getAddressIfSet());
   t.setBackupOwner(getAddressIfSet());
   t.insert();
diff --git a/objectstore/TapePool.hpp b/objectstore/TapePool.hpp
index dd438f2910..fb123b89b7 100644
--- a/objectstore/TapePool.hpp
+++ b/objectstore/TapePool.hpp
@@ -50,8 +50,9 @@ public:
   
   // Tapes management ==========================================================
   std::string addOrGetTapeAndCommit(const std::string &vid, 
-    const std::string &logicalLibraryName, const uint64_t capacityInBytes, 
-    Agent & agent, const cta::CreationLog & CreationLog);
+    const std::string &logicalLibraryName, const uint64_t capacityInBytes,
+    const std::string &density, Agent & agent,
+    const cta::CreationLog & CreationLog);
   CTA_GENERATE_EXCEPTION_CLASS(NoSuchTape);
   CTA_GENERATE_EXCEPTION_CLASS(WrongTape);
   void removeTapeAndCommit(const std::string &vid);
diff --git a/objectstore/TapeTest.cpp b/objectstore/TapeTest.cpp
index 334627fccd..dc545e5b02 100644
--- a/objectstore/TapeTest.cpp
+++ b/objectstore/TapeTest.cpp
@@ -32,7 +32,7 @@ TEST(ObjectStore, TapeBasicAccess) {
     // Try to create the tape entry
     cta::objectstore::Tape t(tapeAddress, be);
     cta::CreationLog cl(cta::UserIdentity(123,456), "testHost", time(NULL), "Unit test");
-    t.initialize("V12345", "LIB0", cl);
+    t.initialize("V12345", "LIB0", "8000GC", cl);
     t.insert();
   }
   {
diff --git a/objectstore/cta.proto b/objectstore/cta.proto
index afeb41b766..1ceeeab41b 100644
--- a/objectstore/cta.proto
+++ b/objectstore/cta.proto
@@ -240,28 +240,29 @@ message MountInfo {
 message Tape {
   required string vid = 4300;
   required string logicallibrary = 4301;
+  required string density = 4302;
   // Statistics about what is stored in the tape
-  required uint64 lastfseq = 4302;
-  required uint64 bytesstored = 4303;
+  required uint64 lastfseq = 4303;
+  required uint64 bytesstored = 4304;
   // Tape lifetime statistics
-  repeated MountInfo readmounts = 4304;
-  repeated MountInfo writemounts = 4305;
+  repeated MountInfo readmounts = 4305;
+  repeated MountInfo writemounts = 4306;
   // Information about retrive jobs queued on this tape
-  repeated RetrieveJobPointer retrievejobs = 4306;
-  required uint64 retrievejobstotalsize = 4307;
-  required uint64 oldestjobtime = 4308;
-  required uint64 priority = 4309;
+  repeated RetrieveJobPointer retrievejobs = 4307;
+  required uint64 retrievejobstotalsize = 4308;
+  required uint64 oldestjobtime = 4309;
+  required uint64 priority = 4310;
   // There are no per tape mount criteria/quotas (they are per tape pool).
   // Tape status
-  required bool busy = 4310;
-  required MountType currentmounttype = 4311;
-  required MountInfo currentmount = 4312;
-  required bool archived = 4313;
-  required bool disabled = 4314;
-  required bool readonly = 4315;
-  required bool full = 4316;
+  required bool busy = 4311;
+  required MountType currentmounttype = 4312;
+  required MountInfo currentmount = 4313;
+  required bool archived = 4314;
+  required bool disabled = 4315;
+  required bool readonly = 4316;
+  required bool full = 4317;
   // Creation log
-  required CreationLog log = 4317;
+  required CreationLog log = 4318;
 }
 
 // ------------- Archive Jobs --------------------------------------------------
diff --git a/scheduler/ArchiveMount.cpp b/scheduler/ArchiveMount.cpp
index 4051916337..effa56a6e2 100644
--- a/scheduler/ArchiveMount.cpp
+++ b/scheduler/ArchiveMount.cpp
@@ -41,43 +41,43 @@ cta::ArchiveMount::ArchiveMount(NameServer & ns,
 //------------------------------------------------------------------------------
 // getMountType
 //------------------------------------------------------------------------------
-cta::MountType::Enum cta::ArchiveMount::getMountType() const throw() {
+cta::MountType::Enum cta::ArchiveMount::getMountType() const {
   return MountType::ARCHIVE;
 }
 
 //------------------------------------------------------------------------------
 // getVid
 //------------------------------------------------------------------------------
-std::string cta::ArchiveMount::getVid() const throw() {
-  return "UNKNOWN_VID_FOR_ARCHIVE_MOUNT";
+std::string cta::ArchiveMount::getVid() const {
+  throw exception::Exception("UNKNOWN_VID_FOR_ARCHIVE_MOUNT");
 }
 
 //------------------------------------------------------------------------------
 // getDensity
 //------------------------------------------------------------------------------
-std::string cta::ArchiveMount::getDensity() const throw() {
-  return "UNKNOWN_DENSITY_FOR_ARCHIVE_MOUNT";
+std::string cta::ArchiveMount::getDensity() const {
+  throw exception::Exception("UNKNOWN_DENSITY_FOR_ARCHIVE_MOUNT");
 }
 
 //------------------------------------------------------------------------------
 // getPoolName
 //------------------------------------------------------------------------------
-std::string cta::ArchiveMount::getPoolName() const throw() {
-  return "UNKNOWN_POOL_FOR_ARCHIVE_MOUNT";
+std::string cta::ArchiveMount::getPoolName() const {
+  throw exception::Exception("UNKNOWN_POOL_FOR_ARCHIVE_MOUNT");
 }
 
 //------------------------------------------------------------------------------
 // getCopyNumber
 //------------------------------------------------------------------------------
-int cta::ArchiveMount::getCopyNumber() const throw() {
-  return 1;
+int cta::ArchiveMount::getCopyNumber() const {
+  throw exception::Exception("UNKNOWN_COPY_NUMBER_ARCHIVE_MOUNT");
 }
 
 //------------------------------------------------------------------------------
 // getMountTransactionId
 //------------------------------------------------------------------------------
-std::string cta::ArchiveMount::getMountTransactionId() const throw(){
-  return "UNKNOWN_MOUNTTRANSACTIONID_FOR_ARCHIVE_MOUNT";
+std::string cta::ArchiveMount::getMountTransactionId() const {
+  throw exception::Exception("UNKNOWN_MOUNTTRANSACTIONID_FOR_ARCHIVE_MOUNT");
 }
 
 //------------------------------------------------------------------------------
diff --git a/scheduler/ArchiveMount.hpp b/scheduler/ArchiveMount.hpp
index 6b70df7901..9611bbb3f7 100644
--- a/scheduler/ArchiveMount.hpp
+++ b/scheduler/ArchiveMount.hpp
@@ -59,28 +59,28 @@ namespace cta {
      *
      * @return The type of this tape mount.
      */
-    virtual MountType::Enum getMountType() const throw();
+    virtual MountType::Enum getMountType() const;
 
     /**
      * Returns the volume identifier of the tape to be mounted.
      *
      * @return The volume identifier of the tape to be mounted.
      */
-    virtual std::string getVid() const throw();
+    virtual std::string getVid() const;
     
     /**
      * Returns the density of the tape to be mounted.
      *
      * @return The density of the tape to be mounted.
      */
-    virtual std::string getDensity() const throw();
+    virtual std::string getDensity() const;
     
     /**
      * Returns the mount transaction id.
      *
      * @return The mount transaction id.
      */
-    virtual std::string getMountTransactionId() const throw();
+    virtual std::string getMountTransactionId() const;
 
     /**
      * Indicates that the mount was completed.
@@ -106,14 +106,14 @@ namespace cta {
      *
      * @return The tape pool of the tape to be mounted.
      */
-    virtual std::string getPoolName() const throw();
+    virtual std::string getPoolName() const;
     
     /**
      * Returns the copy number of the tape to be mounted.
      *
      * @return The copy number of the tape to be mounted.
      */
-    virtual int getCopyNumber() const throw();
+    virtual int getCopyNumber() const;
     
     /**
      * Destructor.
diff --git a/scheduler/OStoreDB/OStoreDB.cpp b/scheduler/OStoreDB/OStoreDB.cpp
index c9c476f42c..a98359de90 100644
--- a/scheduler/OStoreDB/OStoreDB.cpp
+++ b/scheduler/OStoreDB/OStoreDB.cpp
@@ -515,8 +515,8 @@ void OStoreDB::deleteTapePool(const SecurityIdentity& requester,
 
 void OStoreDB::createTape(const std::string& vid, 
   const std::string& logicalLibraryName, 
-  const std::string& tapePoolName, const uint64_t capacityInBytes, 
-  const cta::CreationLog& creationLog) {
+  const std::string& tapePoolName, const uint64_t capacityInBytes,
+  const std::string & density, const cta::CreationLog& creationLog) {
   // To create a tape, we have to
   // - Find the storage class and lock for write.
   // - Create the tape object.
@@ -549,7 +549,7 @@ void OStoreDB::createTape(const std::string& vid,
     throw TapeAlreadyExists("In OStoreDB::createTape: trying to create an existing tape.");
   } catch (cta::exception::Exception &) {}
   // Create the tape. The tape pool method takes care of the gory details for us.
-  tp.addOrGetTapeAndCommit(vid, logicalLibraryName, capacityInBytes, 
+  tp.addOrGetTapeAndCommit(vid, logicalLibraryName, capacityInBytes, density,
       *m_agent, creationLog);
   tp.commit();
 }
@@ -1229,6 +1229,7 @@ std::unique_ptr<SchedulerDatabase::RetrieveMount>
   std::unique_ptr<OStoreDB::RetrieveMount> privateRet(
     new OStoreDB::RetrieveMount(m_objectStore, m_agent));
   auto &rm = *privateRet;
+  std::string tapeDensity;
   // Check we hold the scheduling lock
   if (!m_lockTaken)
     throw SchedulingLockNotHeld("In OStoreDB::TapeMountDecisionInfo::createRetrieveMount: "
@@ -1282,6 +1283,7 @@ std::unique_ptr<SchedulerDatabase::RetrieveMount>
     }
     t.setBusy(driveName, objectstore::Tape::MountType::Archive, hostName, startTime, 
       m_agent.getAddressIfSet());
+    tapeDensity = t.getDensity();
     t.commit();
   }
   // Fill up the mount info
@@ -1290,6 +1292,7 @@ std::unique_ptr<SchedulerDatabase::RetrieveMount>
   rm.mountInfo.logicalLibrary = logicalLibrary;
   rm.mountInfo.mountId = m_schedulerGlobalLock->getIncreaseCommitMountId();
   rm.mountInfo.tapePool = tapePool;
+  rm.mountInfo.density = tapeDensity;
   // Update the status of the drive in the registry
   {
     // Get hold of the drive registry
diff --git a/scheduler/OStoreDB/OStoreDB.hpp b/scheduler/OStoreDB/OStoreDB.hpp
index 3a93ac3d01..a4275ee5c4 100644
--- a/scheduler/OStoreDB/OStoreDB.hpp
+++ b/scheduler/OStoreDB/OStoreDB.hpp
@@ -212,7 +212,7 @@ public:
   CTA_GENERATE_EXCEPTION_CLASS(NoSuchTape);
   virtual void createTape(const std::string& vid, const std::string& logicalLibraryName, 
     const std::string& tapePoolName, const uint64_t capacityInBytes, 
-    const cta::CreationLog& creationLog);
+    const std::string& density, const cta::CreationLog& creationLog);
 
   virtual Tape getTape(const std::string &vid) const;
 
diff --git a/scheduler/OStoreDB/OStoreDBFactory.hpp b/scheduler/OStoreDB/OStoreDBFactory.hpp
index 21f07ef839..44e2dbc376 100644
--- a/scheduler/OStoreDB/OStoreDBFactory.hpp
+++ b/scheduler/OStoreDB/OStoreDBFactory.hpp
@@ -101,8 +101,8 @@ public:
     m_OStoreDB.createStorageClass(name, nbCopies, creationLog);
   }
 
-  virtual void createTape(const std::string& vid, const std::string& logicalLibraryName, const std::string& tapePoolName, const uint64_t capacityInBytes, const cta::CreationLog & creationLog) {
-    m_OStoreDB.createTape(vid, logicalLibraryName, tapePoolName, capacityInBytes, creationLog);
+  virtual void createTape(const std::string& vid, const std::string& logicalLibraryName, const std::string& tapePoolName, const uint64_t capacityInBytes, const std::string & density, const cta::CreationLog & creationLog) {
+    m_OStoreDB.createTape(vid, logicalLibraryName, tapePoolName, capacityInBytes, density, creationLog);
   }
 
   virtual void createTapePool(const std::string& name, const uint32_t nbPartialTapes, const CreationLog& creationLog) {
diff --git a/scheduler/RetrieveMount.cpp b/scheduler/RetrieveMount.cpp
index ad28549013..62da966f86 100644
--- a/scheduler/RetrieveMount.cpp
+++ b/scheduler/RetrieveMount.cpp
@@ -36,29 +36,33 @@ cta::RetrieveMount::RetrieveMount(
 //------------------------------------------------------------------------------
 // getMountType
 //------------------------------------------------------------------------------
-cta::MountType::Enum cta::RetrieveMount::getMountType() const throw() {
+cta::MountType::Enum cta::RetrieveMount::getMountType() const{
   return MountType::RETRIEVE;
 }
 
 //------------------------------------------------------------------------------
 // getVid
 //------------------------------------------------------------------------------
-std::string cta::RetrieveMount::getVid() const throw() {
-  return "UNKNOWN_VID_FOR_RETRIEVE_MOUNT";
+std::string cta::RetrieveMount::getVid() const{
+  return m_dbMount->mountInfo.vid;
 }
 
 //------------------------------------------------------------------------------
 // getDensity
 //------------------------------------------------------------------------------
-std::string cta::RetrieveMount::getDensity() const throw() {
-  return "UNKNOWN_DENSITY_FOR_RETRIEVE_MOUNT";
+std::string cta::RetrieveMount::getDensity() const{
+  return m_dbMount->mountInfo.density;
 }
 
 //------------------------------------------------------------------------------
 // getMountTransactionId
 //------------------------------------------------------------------------------
-std::string cta::RetrieveMount::getMountTransactionId() const throw(){
-  return "UNKNOWN_MOUNTTRANSACTIONID_FOR_RETRIEVE_MOUNT";
+std::string cta::RetrieveMount::getMountTransactionId() const{
+  std::stringstream id;
+  if (!m_dbMount.get())
+    throw exception::Exception("In cta::RetrieveMount::getMountTransactionId(): got NULL dbMount");
+  id << m_dbMount->mountInfo.mountId;
+  return id.str();
 }
 
 //------------------------------------------------------------------------------
diff --git a/scheduler/RetrieveMount.hpp b/scheduler/RetrieveMount.hpp
index 8895e8390d..cd38899921 100644
--- a/scheduler/RetrieveMount.hpp
+++ b/scheduler/RetrieveMount.hpp
@@ -58,28 +58,28 @@ namespace cta {
      *
      * @return The type of this tape mount.
      */
-    virtual MountType::Enum getMountType() const throw();
+    virtual MountType::Enum getMountType() const;
 
     /**
      * Returns the volume identifier of the tape to be mounted.
      *
      * @return The volume identifier of the tape to be mounted.
      */
-    virtual std::string getVid() const throw();
+    virtual std::string getVid() const;
     
     /**
      * Returns the density of the tape to be mounted.
      *
      * @return The density of the tape to be mounted.
      */
-    virtual std::string getDensity() const throw();
+    virtual std::string getDensity() const;
     
     /**
      * Returns the mount transaction id.
      *
      * @return The mount transaction id.
      */
-    virtual std::string getMountTransactionId() const throw();
+    virtual std::string getMountTransactionId() const;
 
     /**
      * Indicates that the mount was completed.
diff --git a/scheduler/Scheduler.cpp b/scheduler/Scheduler.cpp
index c639acc85d..d9733cf775 100644
--- a/scheduler/Scheduler.cpp
+++ b/scheduler/Scheduler.cpp
@@ -27,6 +27,7 @@
 #include "common/Utils.hpp"
 #include "common/SecurityIdentity.hpp"
 #include "common/TapePool.hpp"
+#include "common/CreationLog.hpp"
 #include "nameserver/NameServer.hpp"
 #include "remotens/RemoteNS.hpp"
 #include "scheduler/ArchiveMount.hpp"
@@ -400,10 +401,12 @@ void cta::Scheduler::createTape(
   const std::string &logicalLibraryName,
   const std::string &tapePoolName,
   const uint64_t capacityInBytes,
-  const CreationLog &creationLog) {
+  const std::string &density,
+  const std::string & comment) {
   m_db.assertIsAdminOnAdminHost(requester);
+  cta::CreationLog cl (requester.getUser(), requester.getHost(), time(NULL), comment);
   m_db.createTape(vid, logicalLibraryName, tapePoolName,
-    capacityInBytes, creationLog);
+    capacityInBytes, density, cl);
 }
 
 //------------------------------------------------------------------------------
diff --git a/scheduler/Scheduler.hpp b/scheduler/Scheduler.hpp
index 13467d6adb..deed684d0d 100644
--- a/scheduler/Scheduler.hpp
+++ b/scheduler/Scheduler.hpp
@@ -439,7 +439,7 @@ public:
    * belongs.
    * @param tapePoolName The name of the tape pool to which the tape belongs.
    * @param capacityInBytes The capacity of the tape.
-   * @param creationLog The who, where, when an why of this modification.
+   * @param comment reason for the creation of the tape
    */
   virtual void createTape(
     const SecurityIdentity &requester,
@@ -447,7 +447,8 @@ public:
     const std::string &logicalLibraryName,
     const std::string &tapePoolName,
     const uint64_t capacityInBytes,
-    const CreationLog &creationLog);
+    const std::string &density,
+    const std::string & comment);
 
   /**
    * Deletes the tape with the specified volume identifier.
diff --git a/scheduler/SchedulerDatabase.hpp b/scheduler/SchedulerDatabase.hpp
index cc1a00735e..458ca1144a 100644
--- a/scheduler/SchedulerDatabase.hpp
+++ b/scheduler/SchedulerDatabase.hpp
@@ -244,6 +244,7 @@ public:
       std::string tapePool;
       std::string drive;
       uint64_t mountId;
+      std::string density;
     } mountInfo;
     virtual const MountInfo & getMountInfo() = 0;
     virtual std::unique_ptr<RetrieveJob> getNextJob() = 0;
@@ -594,6 +595,7 @@ public:
     const std::string &logicalLibraryName,
     const std::string &tapePoolName,
     const uint64_t capacityInBytes,
+    const std::string &density,
     const CreationLog &creationLog) = 0;
 
   /**
diff --git a/scheduler/SchedulerDatabaseTest.cpp b/scheduler/SchedulerDatabaseTest.cpp
index 1b2a729e57..8a84ebeb4f 100644
--- a/scheduler/SchedulerDatabaseTest.cpp
+++ b/scheduler/SchedulerDatabaseTest.cpp
@@ -466,16 +466,16 @@ TEST_P(SchedulerDatabaseTest, getMountInfo) {
     ASSERT_EQ(cl.time, tmdi.potentialMounts.front().oldestJobStartTime);
   }
   // Add 2 tapes
-  ASSERT_THROW(db.createTape("Tape2", "Lib2", "pool2", 10L*1000*1000*1000*1000*1000, cl), 
+  ASSERT_THROW(db.createTape("Tape2", "Lib2", "pool2", 10L*1000*1000*1000*1000*1000, "8000GC", cl), 
     cta::exception::Exception);
   db.createLogicalLibrary("Lib2", cl);
-  ASSERT_THROW(db.createTape("Tape2", "Lib2", "pool2", 10L*1000*1000*1000*1000*1000, cl), 
+  ASSERT_THROW(db.createTape("Tape2", "Lib2", "pool2", 10L*1000*1000*1000*1000*1000, "8000GC", cl), 
     cta::exception::Exception);
   db.createTapePool("pool2", 5, cl);
-  ASSERT_NO_THROW(db.createTape("Tape2", "Lib2", "pool2", 10L*1000*1000*1000*1000*1000, cl));
+  ASSERT_NO_THROW(db.createTape("Tape2", "Lib2", "pool2", 10L*1000*1000*1000*1000*1000, "8000GC", cl));
   db.createLogicalLibrary("Lib3", cl);
   db.createTapePool("pool3", 5, cl);
-  ASSERT_NO_THROW(db.createTape("Tape3", "Lib3", "pool3", 10L*1000*1000*1000*1000*1000, cl));
+  ASSERT_NO_THROW(db.createTape("Tape3", "Lib3", "pool3", 10L*1000*1000*1000*1000*1000, "8000GC", cl));
   // Add retrieve jobs
   std::list<TapeFileLocation> tcl;
   tcl.push_back(TapeFileLocation());
@@ -598,9 +598,9 @@ TEST_P(SchedulerDatabaseTest, createArchiveMountAndGetJob) {
         "drive1", "lib1", "host1", time(NULL)), cta::OStoreDB::NoSuchTape);
   }
   // Add the tape (and library)
-  ASSERT_THROW(db.createTape("Tape1", "lib1", "pool1", 10L*1000*1000*1000*1000, cl), cta::OStoreDB::NoSuchLibrary);
+  ASSERT_THROW(db.createTape("Tape1", "lib1", "pool1", 10L*1000*1000*1000*1000, "8000GC", cl), cta::OStoreDB::NoSuchLibrary);
   db.createLogicalLibrary("lib1", cl);
-  ASSERT_NO_THROW(db.createTape("Tape1", "lib1", "pool1", 10L*1000*1000*1000*1000, cl));
+  ASSERT_NO_THROW(db.createTape("Tape1", "lib1", "pool1", 10L*1000*1000*1000*1000, "8000GC", cl));
   // This should go through
   {
     auto mountInfo = db.getMountInfo();
diff --git a/scheduler/SchedulerTest.cpp b/scheduler/SchedulerTest.cpp
index dab644cf66..80d6901989 100644
--- a/scheduler/SchedulerTest.cpp
+++ b/scheduler/SchedulerTest.cpp
@@ -886,11 +886,10 @@ TEST_P(SchedulerTest, admin_createTape_new) {
 
   const std::string vid = "TestVid";
   const uint64_t capacityInBytes = 12345678;
+  const std::string tapeDensity = "8000GC";
   const std::string tapeComment = "Tape comment";
-  CreationLog log(s_adminOnAdminHost.getUser(), s_adminOnAdminHost.getHost(), 
-    time(NULL), tapeComment);
   ASSERT_NO_THROW(scheduler.createTape(s_adminOnAdminHost, vid, libraryName, tapePoolName,
-    capacityInBytes, log));
+    capacityInBytes, tapeDensity, tapeComment));
   {
     std::list<Tape> tapes;
     ASSERT_NO_THROW(tapes = scheduler.getTapes(s_adminOnAdminHost));
@@ -964,11 +963,10 @@ TEST_P(SchedulerTest,
 
   const std::string vid = "TestVid";
   const uint64_t capacityInBytes = 12345678;
+  const std::string tapeDensity = "8000GC";
   const std::string tapeComment = "Tape comment";
-  CreationLog log(s_adminOnAdminHost.getUser(), s_adminOnAdminHost.getHost(), 
-    time(NULL), tapeComment);
   ASSERT_THROW(scheduler.createTape(s_adminOnAdminHost, vid, libraryName, tapePoolName,
-    capacityInBytes, log), std::exception);
+    capacityInBytes, tapeDensity, tapeComment), std::exception);
 }
 
 TEST_P(SchedulerTest, admin_createTape_new_non_existing_pool) {
@@ -1014,11 +1012,10 @@ TEST_P(SchedulerTest, admin_createTape_new_non_existing_pool) {
 
   const std::string vid = "TestVid";
   const uint64_t capacityInBytes = 12345678;
+  const std::string tapeDensity = "8000GC";
   const std::string tapeComment = "Tape comment";
-  CreationLog log(s_adminOnAdminHost.getUser(), s_adminOnAdminHost.getHost(), 
-    time(NULL), tapeComment);
   ASSERT_THROW(scheduler.createTape(s_adminOnAdminHost, vid, libraryName, tapePoolName,
-    capacityInBytes, log), std::exception);
+    capacityInBytes, tapeDensity, tapeComment), std::exception);
 }
 
 TEST_P(SchedulerTest, getDirContents_root_dir_is_empty) {
@@ -2329,11 +2326,10 @@ TEST_P(SchedulerTest, archive_and_retrieve_new_file) {
 
   const std::string vid = "TestVid";
   const uint64_t capacityInBytes = 12345678;
-  const std::string tapeComment = "Tape comment";
-  CreationLog log(s_adminOnAdminHost.getUser(), s_adminOnAdminHost.getHost(), 
-    time(NULL), tapeComment);
+  const std::string tapeDensity = "8000GC";
+  const std::string tapeComment = "Tape comment";  
   ASSERT_NO_THROW(scheduler.createTape(s_adminOnAdminHost, vid, libraryName,
-    tapePoolName, capacityInBytes, log));
+    tapePoolName, capacityInBytes, tapeDensity, tapeComment));
 
   const uint16_t copyNb = 1;
   const std::string archiveRouteComment = "Archive-route comment";
@@ -2527,7 +2523,7 @@ TEST_P(SchedulerTest, setOwner_getOwner_root) {
   Scheduler &scheduler = getScheduler();
   const std::string dirPath = "/";
 
-  ASSERT_NO_THROW(scheduler.getOwner(s_adminOnAdminHost, dirPath));
+  ASSERT_NO_THROW(scheduler.getOwner(s_adminOnAdminHost, dirPath) );
   ASSERT_NO_THROW(scheduler.setOwner(s_adminOnAdminHost, dirPath, s_user));
 
   {
diff --git a/scheduler/TapeMount.hpp b/scheduler/TapeMount.hpp
index 8030ae24c6..226528e277 100644
--- a/scheduler/TapeMount.hpp
+++ b/scheduler/TapeMount.hpp
@@ -35,28 +35,28 @@ namespace cta {
      *
      * @return The type of this tape mount.
      */
-    virtual MountType::Enum getMountType() const throw() = 0;
+    virtual MountType::Enum getMountType() const = 0;
 
     /**
      * Returns the volume identifier of the tape to be mounted.
      *
      * @return The volume identifier of the tape to be mounted.
      */
-    virtual std::string getVid() const throw() = 0;
+    virtual std::string getVid() const = 0;
     
     /**
      * Returns the density of the tape to be mounted.
      *
      * @return The density of the tape to be mounted.
      */
-    virtual std::string getDensity() const throw() = 0;
+    virtual std::string getDensity() const = 0;
     
     /**
      * Returns the mount transaction id.
      *
      * @return The mount transaction id.
      */
-    virtual std::string getMountTransactionId() const throw() = 0;
+    virtual std::string getMountTransactionId() const = 0;
 
     /**
      * Indicates that the mount was completed.
diff --git a/tapeserver/castor/tape/tapeserver/daemon/DataTransferSessionTest.cpp b/tapeserver/castor/tape/tapeserver/daemon/DataTransferSessionTest.cpp
index 2ecfbef13a..21c54f436d 100644
--- a/tapeserver/castor/tape/tapeserver/daemon/DataTransferSessionTest.cpp
+++ b/tapeserver/castor/tape/tapeserver/daemon/DataTransferSessionTest.cpp
@@ -195,6 +195,20 @@ TEST_F(castor_tape_tapeserver_daemon_DataTransferSessionTest, DataTransferSessio
   // files can be tested for at the end of the test
   std::list<std::string> remoteFilePaths;
   
+  // 5) Create the tapepool, library and tape for the scheduler.
+  // Make mounts immediate.
+  ASSERT_NO_THROW(scheduler.createAdminUserWithoutAuthorizingRequester(requester, requester.getUser(), ""));
+  ASSERT_NO_THROW(scheduler.createAdminHostWithoutAuthorizingRequester(requester, requester.getHost(), ""));
+  ASSERT_NO_THROW(scheduler.createTapePool(requester, "TapePool", 1, ""));
+  cta::MountCriteria immediateMount;
+  immediateMount.maxAge = 0;
+  immediateMount.maxBytesQueued = 1;
+  immediateMount.maxFilesQueued = 1;
+  immediateMount.quota = 10;
+  ASSERT_NO_THROW(scheduler.setTapePoolMountCriteria("TapePool", cta::MountCriteriaByDirection(immediateMount, immediateMount)));                   
+  ASSERT_NO_THROW(scheduler.createLogicalLibrary(requester, "T10KD6", ""));
+  ASSERT_NO_THROW(scheduler.createTape(requester, "V12345", "T10KD6", "TapePool", 10*1000*1000, "8000GC", ""));
+  
   // 5) Prepare files for reading by writing them to the mock system
   {
     // Label the tape
@@ -263,7 +277,7 @@ TEST_F(castor_tape_tapeserver_daemon_DataTransferSessionTest, DataTransferSessio
       // Schedule the retrieval of the file
       std::list<std::string> archiveFilePaths;
       archiveFilePaths.push_back(archiveFilePath.str());
-      ASSERT_NO_THROW(scheduler. queueRetrieveRequest(
+      /*ASSERT_NO_THROW*/(scheduler. queueRetrieveRequest(
         requester,
         archiveFilePaths,
         remoteFilePath.str()));
@@ -730,9 +744,8 @@ TEST_F(castor_tape_tapeserver_daemon_DataTransferSessionTest, DataTransferSessio
   ASSERT_NO_THROW(scheduler.createArchiveRoute(requester, "SINGLE", 1, "swimmingpool", "iArchive"));
   
   // create the tape
-  cta::CreationLog log;
-  log.comment = "the magic tape";
-  ASSERT_NO_THROW(scheduler.createTape(requester, "V12345", "illogical", "swimmingpool", 100000, log));
+  std::string comment = "the magic tape";
+  ASSERT_NO_THROW(scheduler.createTape(requester, "V12345", "illogical", "swimmingpool", 100000, "8000GC", comment));
   
   // List to remember the path of each remote file so that the existence of the
   // files can be tested for at the end of the test
@@ -847,9 +860,8 @@ TEST_F(castor_tape_tapeserver_daemon_DataTransferSessionTest, DataTransferSessio
   ASSERT_NO_THROW(scheduler.createArchiveRoute(requester, "SINGLE", 1, "swimmingpool", "iArchive"));
   
   // create the tape
-  cta::CreationLog log;
-  log.comment = "the magic tape";
-  ASSERT_NO_THROW(scheduler.createTape(requester, "V12345", "illogical", "swimmingpool", 100000, log));
+  std::string comment = "the magic tape";
+  ASSERT_NO_THROW(scheduler.createTape(requester, "V12345", "illogical", "swimmingpool", 100000, "8000GC", comment));
   
   // List to remember the path of each remote file so that the existence of the
   // files can be tested for at the end of the test
@@ -952,9 +964,8 @@ TEST_F(castor_tape_tapeserver_daemon_DataTransferSessionTest, DataTransferSessio
   ASSERT_NO_THROW(scheduler.createArchiveRoute(requester, "SINGLE", 1, "swimmingpool", "iArchive"));
   
   // create the tape
-  cta::CreationLog log;
-  log.comment = "the magic tape";
-  ASSERT_NO_THROW(scheduler.createTape(requester, "V12345", "illogical", "swimmingpool", 100000, log));
+  std::string comment = "the magic tape";
+  ASSERT_NO_THROW(scheduler.createTape(requester, "V12345", "illogical", "swimmingpool", 100000, "8000GC", comment));
   
   // List to remember the path of each remote file so that the existence of the
   // files can be tested for at the end of the test
@@ -1068,9 +1079,8 @@ TEST_F(castor_tape_tapeserver_daemon_DataTransferSessionTest, DataTransferSessio
   ASSERT_NO_THROW(scheduler.createArchiveRoute(requester, "SINGLE", 1, "swimmingpool", "iArchive"));
   
   // create the tape
-  cta::CreationLog log;
-  log.comment = "the magic tape";
-  ASSERT_NO_THROW(scheduler.createTape(requester, "V12345", "illogical", "swimmingpool", 100000, log));
+  std::string comment = "the magic tape";
+  ASSERT_NO_THROW(scheduler.createTape(requester, "V12345", "illogical", "swimmingpool", 100000, "8000GC", comment));
   
   // List to remember the path of each remote file so that the existence of the
   // files can be tested for at the end of the test
diff --git a/tapeserver/castor/tape/tapeserver/daemon/RecallTaskInjectorTest.cpp b/tapeserver/castor/tape/tapeserver/daemon/RecallTaskInjectorTest.cpp
index 4f690cc143..43589af0a1 100644
--- a/tapeserver/castor/tape/tapeserver/daemon/RecallTaskInjectorTest.cpp
+++ b/tapeserver/castor/tape/tapeserver/daemon/RecallTaskInjectorTest.cpp
@@ -181,7 +181,7 @@ namespace unitTests
     rti.requestInjection(false);
     rti.requestInjection(true);
     rti.finish();
-    rti.waitThreads();
+    ASSERT_NO_THROW(rti.waitThreads());
 
     //pushed nbFile*2 files + 1 end of work
     ASSERT_EQ(nbJobs+1, diskWrite.m_tasks.size());
diff --git a/tapeserver/castor/tape/tapeserver/drive/FakeDrive.cpp b/tapeserver/castor/tape/tapeserver/drive/FakeDrive.cpp
index 1700c47bea..bb7241d3ae 100644
--- a/tapeserver/castor/tape/tapeserver/drive/FakeDrive.cpp
+++ b/tapeserver/castor/tape/tapeserver/drive/FakeDrive.cpp
@@ -210,7 +210,7 @@ std::string castor::tape::tapeserver::drive::FakeDrive::contentToString() throw(
   return exc.str();
 }
 void castor::tape::tapeserver::drive::FakeDrive::readExactBlock(void *data, size_t count, std::string context)  {
-  if(count != m_tape[m_currentPosition].data.size()) {
+  if(count != m_tape.at(m_currentPosition).data.size()) {
     std::stringstream exc;
     exc << "Wrong block size in FakeDrive::readExactBlock. Expected: " << count 
         << " Found: " << m_tape[m_currentPosition].data.size() 
diff --git a/xroot_plugins/XrdProFile.cpp b/xroot_plugins/XrdProFile.cpp
index 17b5a4242a..bef2659263 100644
--- a/xroot_plugins/XrdProFile.cpp
+++ b/xroot_plugins/XrdProFile.cpp
@@ -780,8 +780,10 @@ void XrdProFile::xCom_logicallibrary(const std::vector<std::string> &tokens, con
 void XrdProFile::xCom_tape(const std::vector<std::string> &tokens, const cta::SecurityIdentity &requester) {
   std::stringstream help;
   help << tokens[0] << " ta/tape add/ch/rm/reclaim/ls:" << std::endl;
-  help << "\tadd     --vid/-v <vid> --logicallibrary/-l <logical_library_name> --tapepool/-t <tapepool_name> --capacity/-c <capacity_in_bytes> --comment/-m <\"comment\">" << std::endl;
-  help << "\tch      --vid/-v <vid> --logicallibrary/-l <logical_library_name> --tapepool/-t <tapepool_name> --capacity/-c <capacity_in_bytes> --comment/-m <\"comment\">" << std::endl;
+  help << "\tadd     --vid/-v <vid> --logicallibrary/-l <logical_library_name> --tapepool/-t <tapepool_name> \\"<<std::endl
+       <<"\t\t--capacity/-c <capacity_in_bytes> --density/-d <density code> --comment/-m <\"comment\">" << std::endl;
+  help << "\tch      --vid/-v <vid> --logicallibrary/-l <logical_library_name> --tapepool/-t <tapepool_name> \\"<<std::endl
+       <<"\t\t--capacity/-c <capacity_in_bytes> --density/-d <density code> --comment/-m <\"comment\">" << std::endl;
   help << "\trm      --vid/-v <vid>" << std::endl;
   help << "\treclaim --vid/-v <vid>" << std::endl;
   help << "\tls" << std::endl;
@@ -795,15 +797,15 @@ void XrdProFile::xCom_tape(const std::vector<std::string> &tokens, const cta::Se
     std::string tapePool = getOptionValue(tokens, "-t", "--tapepool");
     std::string capacity_s = getOptionValue(tokens, "-c", "--capacity");
     std::string comment = getOptionValue(tokens, "-m", "--comment");
-    if(logicalLibrary.empty()||tapePool.empty()||comment.empty()||capacity_s.empty()||vid.empty()) {
+    std::string density = getOptionValue(tokens, "-d", "--density");
+    if(logicalLibrary.empty()||tapePool.empty()||comment.empty()||capacity_s.empty()||vid.empty()||density.empty()) {
       m_data = help.str();
       return;
     }
     std::istringstream capacity_ss(capacity_s);
     uint64_t capacity = 0;
     capacity_ss >> capacity;
-    cta::CreationLog log(requester.getUser(), requester.getHost(), time(NULL), comment);
-    m_scheduler->createTape(requester, vid, logicalLibrary, tapePool, capacity, log);
+    m_scheduler->createTape(requester, vid, logicalLibrary, tapePool, capacity, density, comment);
   }
   else if("ch" == tokens[2]) {
     std::string vid = getOptionValue(tokens, "-v", "--vid");
@@ -811,14 +813,15 @@ void XrdProFile::xCom_tape(const std::vector<std::string> &tokens, const cta::Se
     std::string tapePool = getOptionValue(tokens, "-t", "--tapepool");
     std::string capacity_s = getOptionValue(tokens, "-c", "--capacity");
     std::string comment = getOptionValue(tokens, "-m", "--comment");
-    if(logicalLibrary.empty()||tapePool.empty()||comment.empty()||capacity_s.empty()||vid.empty()) {
+    std::string density = getOptionValue(tokens, "-d", "--density");
+    if(logicalLibrary.empty()||tapePool.empty()||comment.empty()||capacity_s.empty()||vid.empty()||density.empty()) {
       m_data = help.str();
       return;
     }
     std::istringstream capacity_ss(capacity_s);
     uint64_t capacity = 0;
     capacity_ss >> capacity;
-//    m_scheduler->modifyTape(requester, vid, logicalLibrary, tapePool, capacity, comment);
+//    m_scheduler->modifyTape(requester, vid, logicalLibrary, tapePool, capacity, density, comment);
   }
   else if("rm" == tokens[2]) {
     std::string vid = getOptionValue(tokens, "-v", "--vid");
-- 
GitLab