From 31e00f6ed9eb7b621821937eb4b2e8a3bb90af3d Mon Sep 17 00:00:00 2001 From: Daniele Kruse <dkruse@cern.ch> Date: Wed, 17 Feb 2016 17:10:19 +0100 Subject: [PATCH] More work on the CLI --- common/dataStructures/ReadTestResult.cpp | 20 ----- common/dataStructures/ReadTestResult.hpp | 6 -- common/dataStructures/TestSourceType.hpp | 31 +++++++ common/dataStructures/WriteTestResult.cpp | 20 ----- common/dataStructures/WriteTestResult.hpp | 6 -- scheduler/Scheduler.cpp | 12 ++- scheduler/Scheduler.hpp | 8 +- xroot_plugins/XrdCtaFile.cpp | 103 +++++++++++++++++++++- 8 files changed, 145 insertions(+), 61 deletions(-) create mode 100644 common/dataStructures/TestSourceType.hpp diff --git a/common/dataStructures/ReadTestResult.cpp b/common/dataStructures/ReadTestResult.cpp index ea8ed0ada5..b3a48561a4 100644 --- a/common/dataStructures/ReadTestResult.cpp +++ b/common/dataStructures/ReadTestResult.cpp @@ -26,7 +26,6 @@ cta::common::dataStructures::ReadTestResult::ReadTestResult() { m_checksumsSet = false; m_driveNameSet = false; m_errorsSet = false; - m_noOfFilesReadSet = false; m_totalBytesReadSet = false; m_totalFilesReadSet = false; m_totalTimeInSecondsSet = false; @@ -46,7 +45,6 @@ bool cta::common::dataStructures::ReadTestResult::allFieldsSet() const { return m_checksumsSet && m_driveNameSet && m_errorsSet - && m_noOfFilesReadSet && m_totalBytesReadSet && m_totalFilesReadSet && m_totalTimeInSecondsSet @@ -107,24 +105,6 @@ std::map<int,std::string> cta::common::dataStructures::ReadTestResult::getErrors return m_errors; } -//------------------------------------------------------------------------------ -// setNoOfFilesRead -//------------------------------------------------------------------------------ -void cta::common::dataStructures::ReadTestResult::setNoOfFilesRead(const uint64_t noOfFilesRead) { - m_noOfFilesRead = noOfFilesRead; - m_noOfFilesReadSet = true; -} - -//------------------------------------------------------------------------------ -// getNoOfFilesRead -//------------------------------------------------------------------------------ -uint64_t cta::common::dataStructures::ReadTestResult::getNoOfFilesRead() const { - if(!allFieldsSet()) { - throw cta::exception::Exception(std::string(__FUNCTION__)+" Error: not all fields of the ReadTestResult have been set!"); - } - return m_noOfFilesRead; -} - //------------------------------------------------------------------------------ // setTotalBytesRead //------------------------------------------------------------------------------ diff --git a/common/dataStructures/ReadTestResult.hpp b/common/dataStructures/ReadTestResult.hpp index 42b60d3c58..f338398a0c 100644 --- a/common/dataStructures/ReadTestResult.hpp +++ b/common/dataStructures/ReadTestResult.hpp @@ -51,9 +51,6 @@ public: void setErrors(const std::map<int,std::string> &errors); std::map<int,std::string> getErrors() const; - void setNoOfFilesRead(const uint64_t noOfFilesRead); - uint64_t getNoOfFilesRead() const; - void setTotalBytesRead(const uint64_t totalBytesRead); uint64_t getTotalBytesRead() const; @@ -83,9 +80,6 @@ private: std::map<int,std::string> m_errors; bool m_errorsSet; - uint64_t m_noOfFilesRead; - bool m_noOfFilesReadSet; - uint64_t m_totalBytesRead; bool m_totalBytesReadSet; diff --git a/common/dataStructures/TestSourceType.hpp b/common/dataStructures/TestSourceType.hpp new file mode 100644 index 0000000000..5229357048 --- /dev/null +++ b/common/dataStructures/TestSourceType.hpp @@ -0,0 +1,31 @@ +/* + * 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 + +namespace cta { +namespace common { +namespace dataStructures { +enum TestSourceType { + devzero, + devurandom +}; +} // namespace dataStructures +} // namespace common +} // namespace cta + diff --git a/common/dataStructures/WriteTestResult.cpp b/common/dataStructures/WriteTestResult.cpp index 2d3ba9b18a..c698279de8 100644 --- a/common/dataStructures/WriteTestResult.cpp +++ b/common/dataStructures/WriteTestResult.cpp @@ -26,7 +26,6 @@ cta::common::dataStructures::WriteTestResult::WriteTestResult() { m_checksumsSet = false; m_driveNameSet = false; m_errorsSet = false; - m_noOfFilesWrittenSet = false; m_totalBytesWrittenSet = false; m_totalFilesWrittenSet = false; m_totalTimeInSecondsSet = false; @@ -46,7 +45,6 @@ bool cta::common::dataStructures::WriteTestResult::allFieldsSet() const { return m_checksumsSet && m_driveNameSet && m_errorsSet - && m_noOfFilesWrittenSet && m_totalBytesWrittenSet && m_totalFilesWrittenSet && m_totalTimeInSecondsSet @@ -107,24 +105,6 @@ std::map<int,std::string> cta::common::dataStructures::WriteTestResult::getError return m_errors; } -//------------------------------------------------------------------------------ -// setNoOfFilesWritten -//------------------------------------------------------------------------------ -void cta::common::dataStructures::WriteTestResult::setNoOfFilesWritten(const uint64_t noOfFilesWritten) { - m_noOfFilesWritten = noOfFilesWritten; - m_noOfFilesWrittenSet = true; -} - -//------------------------------------------------------------------------------ -// getNoOfFilesWritten -//------------------------------------------------------------------------------ -uint64_t cta::common::dataStructures::WriteTestResult::getNoOfFilesWritten() const { - if(!allFieldsSet()) { - throw cta::exception::Exception(std::string(__FUNCTION__)+" Error: not all fields of the WriteTestResult have been set!"); - } - return m_noOfFilesWritten; -} - //------------------------------------------------------------------------------ // setTotalBytesWritten //------------------------------------------------------------------------------ diff --git a/common/dataStructures/WriteTestResult.hpp b/common/dataStructures/WriteTestResult.hpp index 82000e9a31..178b767073 100644 --- a/common/dataStructures/WriteTestResult.hpp +++ b/common/dataStructures/WriteTestResult.hpp @@ -51,9 +51,6 @@ public: void setErrors(const std::map<int,std::string> &errors); std::map<int,std::string> getErrors() const; - void setNoOfFilesWritten(const uint64_t noOfFilesWritten); - uint64_t getNoOfFilesWritten() const; - void setTotalBytesWritten(const uint64_t totalBytesWritten); uint64_t getTotalBytesWritten() const; @@ -83,9 +80,6 @@ private: std::map<int,std::string> m_errors; bool m_errorsSet; - uint64_t m_noOfFilesWritten; - bool m_noOfFilesWrittenSet; - uint64_t m_totalBytesWritten; bool m_totalBytesWrittenSet; diff --git a/scheduler/Scheduler.cpp b/scheduler/Scheduler.cpp index bc9b49c5bc..bba7b532bf 100644 --- a/scheduler/Scheduler.cpp +++ b/scheduler/Scheduler.cpp @@ -658,7 +658,7 @@ cta::common::dataStructures::ArchiveFileSummary cta::Scheduler::getArchiveFileSu // readTest //------------------------------------------------------------------------------ cta::common::dataStructures::ReadTestResult cta::Scheduler::readTest(const cta::common::dataStructures::SecurityIdentity &requester, const std::string &driveName, const std::string &vid, - const uint64_t firstFSeq, const uint64_t lastFSeq, const bool checkChecksum, const uint64_t retriesPerFile, const std::string &outputDir, const bool redirectToDevNull, const std::string &tag) const { + const uint64_t firstFSeq, const uint64_t lastFSeq, const bool checkChecksum, const std::string &output, const std::string &tag) const { return cta::common::dataStructures::ReadTestResult(); } @@ -666,7 +666,15 @@ cta::common::dataStructures::ReadTestResult cta::Scheduler::readTest(const cta:: // writeTest //------------------------------------------------------------------------------ cta::common::dataStructures::WriteTestResult cta::Scheduler::writeTest(const cta::common::dataStructures::SecurityIdentity &requester, const std::string &driveName, const std::string &vid, - const uint64_t numberOfFiles, const uint64_t fileSize, const bool randomSize, const bool devZero, const bool devURandom, const std::list<std::string> &inputFiles, const std::string &tag) const { + const std::string &inputFile, const std::string &tag) const { + return cta::common::dataStructures::WriteTestResult(); +} + +//------------------------------------------------------------------------------ +// write_autoTest +//------------------------------------------------------------------------------ +cta::common::dataStructures::WriteTestResult cta::Scheduler::write_autoTest(const cta::common::dataStructures::SecurityIdentity &requester, const std::string &driveName, const std::string &vid, + const uint64_t numberOfFiles, const uint64_t fileSize, const cta::common::dataStructures::TestSourceType testSourceType, const std::string &tag) const { return cta::common::dataStructures::WriteTestResult(); } diff --git a/scheduler/Scheduler.hpp b/scheduler/Scheduler.hpp index 6aae51d0b4..8353d847c2 100644 --- a/scheduler/Scheduler.hpp +++ b/scheduler/Scheduler.hpp @@ -51,6 +51,7 @@ #include "common/dataStructures/Tape.hpp" #include "common/dataStructures/TapeMount.hpp" #include "common/dataStructures/TapePool.hpp" +#include "common/dataStructures/TestSourceType.hpp" #include "common/dataStructures/UpdateFileInfoRequest.hpp" #include "common/dataStructures/UserGroup.hpp" #include "common/dataStructures/User.hpp" @@ -207,9 +208,10 @@ public: const std::string ©nb, const std::string &tapepool, const std::string &vid, const std::string &owner, const std::string &group, const std::string &storageclass, const std::string &path); virtual cta::common::dataStructures::ReadTestResult readTest(const cta::common::dataStructures::SecurityIdentity &requester, const std::string &driveName, const std::string &vid, const uint64_t firstFSeq, const uint64_t lastFSeq, - const bool checkChecksum, const uint64_t retriesPerFile, const std::string &outputDir, const bool redirectToDevNull, const std::string &tag) const; - virtual cta::common::dataStructures::WriteTestResult writeTest(const cta::common::dataStructures::SecurityIdentity &requester, const std::string &driveName, const std::string &vid, const uint64_t numberOfFiles, const uint64_t fileSize, - const bool randomSize, const bool devZero, const bool devURandom, const std::list<std::string> &inputFiles, const std::string &tag) const; + const bool checkChecksum, const std::string &output, const std::string &tag) const; //when output=="null" discard the data read + virtual cta::common::dataStructures::WriteTestResult writeTest(const cta::common::dataStructures::SecurityIdentity &requester, const std::string &driveName, const std::string &vid, const std::string &inputFile, const std::string &tag) const; + virtual cta::common::dataStructures::WriteTestResult write_autoTest(const cta::common::dataStructures::SecurityIdentity &requester, const std::string &driveName, const std::string &vid, const uint64_t numberOfFiles, const uint64_t fileSize, + const cta::common::dataStructures::TestSourceType testSourceType, const std::string &tag) const; virtual void setDriveStatus(const cta::common::dataStructures::SecurityIdentity &requester, const std::string &driveName, const bool up, const bool force); diff --git a/xroot_plugins/XrdCtaFile.cpp b/xroot_plugins/XrdCtaFile.cpp index 16823ecd32..3c4d1bbb6a 100644 --- a/xroot_plugins/XrdCtaFile.cpp +++ b/xroot_plugins/XrdCtaFile.cpp @@ -1579,10 +1579,105 @@ void XrdProFile::xCom_archivefile(const std::vector<std::string> &tokens, const //------------------------------------------------------------------------------ void XrdProFile::xCom_test(const std::vector<std::string> &tokens, const cta::common::dataStructures::SecurityIdentity &requester) { std::stringstream help; - help << tokens[0] << " te/test read/write_rand/write_def (to be run on an empty self-dedicated drive; it is a synchronous command that returns performance stats and errors; all locations are local to the tapeserver):" << std::endl - << "\tread --drive/-d <drive_name> --vid/-v <vid> --firstfseq/-f <first_fseq> --lastfseq/-l <last_fseq> --checkchecksum/-c --retries_per_file/-r <number_of_retries_per_file> [--outputdir/-o <output_dir> or --null/-n] [--tag/-t <tag_name>]" << std::endl - << "\twrite_rand --drive/-d <drive_name> --vid/-v <vid> --number/-n <number_of_files> --size/-s <file_size> [--zero/-z or --urandom/-u] [--tag/-t <tag_name>]" << std::endl - << "\twrite_def --drive/-d <drive_name> --vid/-v <vid> [--file/-f <filename> or --filelist/-f <filename_with_file_list>] [--tag/-t <tag_name>]" << std::endl; + help << tokens[0] << " te/test read/write/write_auto (to be run on an empty self-dedicated drive; it is a synchronous command that returns performance stats and errors; all locations are local to the tapeserver):" << std::endl + << "\tread --drive/-d <drive_name> --vid/-v <vid> --firstfseq/-f <first_fseq> --lastfseq/-l <last_fseq> --checkchecksum/-c --output/-o <\"null\" or output_dir> [--tag/-t <tag_name>]" << std::endl + << "\twrite --drive/-d <drive_name> --vid/-v <vid> --file/-f <filename> [--tag/-t <tag_name>]" << std::endl + << "\twrite_auto --drive/-d <drive_name> --vid/-v <vid> --number/-n <number_of_files> --size/-s <file_size> --input/-i <\"zero\" or \"urandom\"> [--tag/-t <tag_name>]" << std::endl; + std::string drive = getOptionValue(tokens, "-d", "--drive"); + std::string vid = getOptionValue(tokens, "-v", "--vid"); + if(vid.empty() || drive.empty()) { + m_data = help.str(); + return; + } + std::string tag = getOptionValue(tokens, "-t", "--tag"); + if("read" == tokens[2]) { + std::string firstfseq_s = getOptionValue(tokens, "-f", "--firstfseq"); + std::string lastfseq_s = getOptionValue(tokens, "-l", "--lastfseq"); + std::string output = getOptionValue(tokens, "-o", "--output"); + if(firstfseq_s.empty() || lastfseq_s.empty() || output.empty()) { + m_data = help.str(); + return; + } + bool checkchecksum = hasOption(tokens, "-c", "--checkchecksum"); + uint64_t firstfseq; std::stringstream firstfseq_ss; firstfseq_ss << firstfseq_s; firstfseq_ss >> firstfseq; + uint64_t lastfseq; std::stringstream lastfseq_ss; lastfseq_ss << lastfseq_s; lastfseq_ss >> lastfseq; + cta::common::dataStructures::ReadTestResult res = m_scheduler->readTest(requester, drive, vid, firstfseq, lastfseq, checkchecksum, output, tag); + std::vector<std::vector<std::string>> responseTable; + std::vector<std::string> header = {"fseq","checksum type","checksum value","error"}; + responseTable.push_back(header); + for(auto it = res.getChecksums().cbegin(); it != res.getChecksums().cend(); it++) { + std::vector<std::string> currentRow; + currentRow.push_back(std::to_string((unsigned long long)it->first)); + currentRow.push_back(it->second.first); + currentRow.push_back(it->second.second); + if(res.getErrors().find(it->first) != res.getErrors().cend()) { + currentRow.push_back(res.getErrors().at(it->first)); + } + else { + currentRow.push_back("-"); + } + responseTable.push_back(currentRow); + } + m_data = formatResponse(responseTable); + std::stringstream ss; + ss << std::endl << "Drive: " << res.getDriveName() << " Vid: " << res.getVid() << " #Files: " << res.getTotalFilesRead() << " #Bytes: " << res.getTotalBytesRead() + << " Time: " << res.getTotalTimeInSeconds() << " s Speed(avg): " << (long double)res.getTotalBytesRead()/(long double)res.getTotalTimeInSeconds() << " B/s" <<std::endl; + m_data += ss.str(); + } + else if("write" == tokens[2] || "write_auto" == tokens[2]) { + cta::common::dataStructures::WriteTestResult res; + if("write" == tokens[2]) { //write + std::string file = getOptionValue(tokens, "-f", "--file"); + if(file.empty()) { + m_data = help.str(); + return; + } + res = m_scheduler->writeTest(requester, drive, vid, file, tag); + } + else { //write_auto + std::string number_s = getOptionValue(tokens, "-n", "--number"); + std::string size_s = getOptionValue(tokens, "-s", "--size"); + std::string input = getOptionValue(tokens, "-i", "--input"); + if(number_s.empty()||size_s.empty()||(input!="zero"&&input!="urandom")) { + m_data = help.str(); + return; + } + uint64_t number; std::stringstream number_ss; number_ss << number_s; number_ss >> number; + uint64_t size; std::stringstream size_ss; size_ss << size_s; size_ss >> size; + cta::common::dataStructures::TestSourceType type; + if(input=="zero") { //zero + type = cta::common::dataStructures::TestSourceType::devzero; + } + else { //urandom + type = cta::common::dataStructures::TestSourceType::devurandom; + } + res = m_scheduler->write_autoTest(requester, drive, vid, number, size, type, tag); + } + std::vector<std::vector<std::string>> responseTable; + std::vector<std::string> header = {"fseq","checksum type","checksum value","error"}; + responseTable.push_back(header); + for(auto it = res.getChecksums().cbegin(); it != res.getChecksums().cend(); it++) { + std::vector<std::string> currentRow; + currentRow.push_back(std::to_string((unsigned long long)it->first)); + currentRow.push_back(it->second.first); + currentRow.push_back(it->second.second); + if(res.getErrors().find(it->first) != res.getErrors().cend()) { + currentRow.push_back(res.getErrors().at(it->first)); + } + else { + currentRow.push_back("-"); + } + responseTable.push_back(currentRow); + } + m_data = formatResponse(responseTable); + std::stringstream ss; + ss << std::endl << "Drive: " << res.getDriveName() << " Vid: " << res.getVid() << " #Files: " << res.getTotalFilesWritten() << " #Bytes: " << res.getTotalBytesWritten() + << " Time: " << res.getTotalTimeInSeconds() << " s Speed(avg): " << (long double)res.getTotalBytesWritten()/(long double)res.getTotalTimeInSeconds() << " B/s" <<std::endl; + m_data += ss.str(); + } + else { + m_data = help.str(); + } } //------------------------------------------------------------------------------ -- GitLab