From e8393217fb51e4f6df3cc37bd8dad9a55f2edddb Mon Sep 17 00:00:00 2001
From: Eric Cano <Eric.Cano@cern.ch>
Date: Wed, 16 Sep 2015 14:36:24 +0200
Subject: [PATCH] Finished implementation of Scheduler::queueRetrieveRequest()
 and adapter unit tests.

---
 scheduler/Scheduler.cpp                       | 23 +++++++++++++++
 scheduler/SchedulerTest.cpp                   | 28 +++++++++++++++++--
 .../daemon/DataTransferSessionTest.cpp        | 12 ++++----
 3 files changed, 54 insertions(+), 9 deletions(-)

diff --git a/scheduler/Scheduler.cpp b/scheduler/Scheduler.cpp
index 06c855db49..e7ab15bc6c 100644
--- a/scheduler/Scheduler.cpp
+++ b/scheduler/Scheduler.cpp
@@ -733,6 +733,8 @@ void cta::Scheduler::queueRetrieveRequest(
   const std::string &remoteFileOrDir) {
 
   const auto remoteStat = m_remoteNS.statFile(remoteFileOrDir);
+  // If the target does not exist or is a directory, we are retrieving to 
+  // directory
   const bool retrieveToDir = remoteStat.get() && S_ISDIR(remoteStat->mode);
   if(retrieveToDir) {
     const std::string &remoteDir = remoteFileOrDir;
@@ -744,12 +746,33 @@ void cta::Scheduler::queueRetrieveRequest(
   } else {
     const std::string &remoteFile = remoteFileOrDir;
 
+    // The remote file should not exist
     if(remoteStat.get()) {
       std::ostringstream msg;
       msg << "Failed to queue request to retrieve to the single file " <<
         remoteFile << " because the remote file already exists";
       throw exception::Exception(msg.str());
     }
+    // We should only try to retrieve one file
+    if (archiveFiles.size() != 1)
+      throw exception::Exception("Failed to queue request to retrieve to single file: trying to retrieve several files");
+    // Check the validity of the source
+    auto sourceStat = m_ns.statFile(requester, archiveFiles.front());
+    if (!sourceStat.get())
+      throw exception::Exception("Failed to queue request to retrieve to single file: source file does not exist");
+    auto tapeCopies = m_ns.getTapeFiles(requester, archiveFiles.front());
+    if (!tapeCopies.size())
+      throw exception::Exception("Failed to queue request to retrieve to single file: source file has no copy on tape");
+    // Generate the requests and enqueue them in the database
+    CreationLog cl (requester.getUser(), requester.getHost(), time(NULL), 
+        "Retrieve request queueing");
+    std::list<TapeFileLocation> tcl;
+    for (auto nstf = tapeCopies.begin(); nstf != tapeCopies.end(); nstf++) {
+      tcl.push_back(nstf->tapeFileLocation);
+    }
+    RetrieveToFileRequest rtfr (archiveFiles.front(), sourceStat->size,
+        tcl, remoteFile, 0, cl);
+    m_db.queue(rtfr);
   }
 }
 
diff --git a/scheduler/SchedulerTest.cpp b/scheduler/SchedulerTest.cpp
index 5b8547bb3f..ec556ea679 100644
--- a/scheduler/SchedulerTest.cpp
+++ b/scheduler/SchedulerTest.cpp
@@ -155,6 +155,16 @@ public:
   static const std::string s_remoteFileRawPath3;
   static const std::string s_remoteFileRawPath4;
 
+  static const std::string s_remoteTargetFilename1;
+  static const std::string s_remoteTargetFilename2;
+  static const std::string s_remoteTargetFilename3;
+  static const std::string s_remoteTargetFilename4;
+
+  static const std::string s_remoteTargetRawPath1;
+  static const std::string s_remoteTargetRawPath2;
+  static const std::string s_remoteTargetRawPath3;
+  static const std::string s_remoteTargetRawPath4;
+
 private:
 
   // Prevent copying
@@ -197,6 +207,16 @@ const std::string SchedulerTest::s_remoteFileRawPath2(std::string("mock:") + s_r
 const std::string SchedulerTest::s_remoteFileRawPath3(std::string("mock:") + s_remoteFilename3);
 const std::string SchedulerTest::s_remoteFileRawPath4(std::string("mock:") + s_remoteFilename4);
 
+const std::string SchedulerTest::s_remoteTargetFilename1("remoteFileForWrite1");
+const std::string SchedulerTest::s_remoteTargetFilename2("remoteFileForWrite2");
+const std::string SchedulerTest::s_remoteTargetFilename3("remoteFileForWrite3");
+const std::string SchedulerTest::s_remoteTargetFilename4("remoteFileForWrite4");
+
+const std::string SchedulerTest::s_remoteTargetRawPath1(std::string("mock:") + s_remoteTargetFilename1);
+const std::string SchedulerTest::s_remoteTargetRawPath2(std::string("mock:") + s_remoteTargetFilename2);
+const std::string SchedulerTest::s_remoteTargetRawPath3(std::string("mock:") + s_remoteTargetFilename3);
+const std::string SchedulerTest::s_remoteTargetRawPath4(std::string("mock:") + s_remoteTargetFilename4);
+
 TEST_P(SchedulerTest, createStorageClass_new_as_adminOnAdminHost) {
   using namespace cta;
 
@@ -2402,7 +2422,7 @@ TEST_P(SchedulerTest, archive_and_retrieve_new_file) {
     std::list<std::string> archiveFiles;
     archiveFiles.push_back("/grandparent/parent_file");
     ASSERT_THROW(scheduler.queueRetrieveRequest(s_userOnUserHost, archiveFiles,
-      s_remoteFileRawPath1), std::exception);
+      s_remoteTargetRawPath1), std::exception);
   }
 
   {
@@ -2429,14 +2449,16 @@ TEST_P(SchedulerTest, archive_and_retrieve_new_file) {
   }
 
   {
+    
     std::list<std::string> archiveFiles;
     archiveFiles.push_back("/grandparent/parent_file");
     ASSERT_NO_THROW(scheduler.queueRetrieveRequest(s_userOnUserHost,
-      archiveFiles, s_remoteFileRawPath1));
+      archiveFiles, s_remoteTargetRawPath1));
   }
 
   {
-    const auto rqsts = scheduler.getRetrieveRequests(s_userOnUserHost);
+    decltype(scheduler.getRetrieveRequests(s_userOnUserHost)) rqsts;
+    ASSERT_NO_THROW(rqsts = scheduler.getRetrieveRequests(s_userOnUserHost));
     ASSERT_EQ(1, rqsts.size());
     auto tapeItor = rqsts.cbegin();
     ASSERT_FALSE(tapeItor == rqsts.cend());
diff --git a/tapeserver/castor/tape/tapeserver/daemon/DataTransferSessionTest.cpp b/tapeserver/castor/tape/tapeserver/daemon/DataTransferSessionTest.cpp
index cbc3a97145..ee602264bc 100644
--- a/tapeserver/castor/tape/tapeserver/daemon/DataTransferSessionTest.cpp
+++ b/tapeserver/castor/tape/tapeserver/daemon/DataTransferSessionTest.cpp
@@ -262,10 +262,10 @@ TEST_F(castor_tape_tapeserver_daemon_DataTransferSessionTest, DataTransferSessio
       // Schedule the retrieval of the file
       std::list<std::string> archiveFilePaths;
       archiveFilePaths.push_back(archiveFilePath.str());
-      scheduler. queueRetrieveRequest(
+      ASSERT_NO_THROW(scheduler. queueRetrieveRequest(
         requester,
         archiveFilePaths,
-        remoteFilePath.str());
+        remoteFilePath.str()));
     }
   }
 
@@ -408,10 +408,10 @@ TEST_F(castor_tape_tapeserver_daemon_DataTransferSessionTest, DataTransferSessio
       // Schedule the retrieval of the file
       std::list<std::string> archiveFilePaths;
       archiveFilePaths.push_back(archiveFilePath.str());
-      scheduler. queueRetrieveRequest(
+      ASSERT_NO_THROW(scheduler. queueRetrieveRequest(
         requester,
         archiveFilePaths,
-        remoteFilePath.str());
+        remoteFilePath.str()));
     }
   }
 
@@ -603,10 +603,10 @@ TEST_F(castor_tape_tapeserver_daemon_DataTransferSessionTest, DataTransferSessio
       // Schedule the retrieval of the file
       std::list<std::string> archiveFilePaths;
       archiveFilePaths.push_back(archiveFilePath.str());
-      scheduler. queueRetrieveRequest(
+      ASSERT_NO_THROW(scheduler. queueRetrieveRequest(
         requester,
         archiveFilePaths,
-        remoteFilePath.str());
+        remoteFilePath.str()));
     }
   }
   DriveConfig driveConfig("T10D6116", "T10KD6", "/dev/tape_T10D6116", "manual");
-- 
GitLab