diff --git a/objectstore_middletier/CMakeLists.txt b/objectstore_middletier/CMakeLists.txt index dfdad4cfed5f8a360505f46366301af0a3161387..f573827aee7d5bcc74b61a38dafb9dbb0be45438 100644 --- a/objectstore_middletier/CMakeLists.txt +++ b/objectstore_middletier/CMakeLists.txt @@ -10,6 +10,7 @@ add_library (CTAObjectStoreMiddleTier set(MiddleTierUnitTests MiddleTierAdminAbstractTest.cpp + MiddleTierUserAbstractTest.cpp MiddleTierTest.cpp ) diff --git a/objectstore_middletier/MiddleTierAdminAbstractTest.hpp b/objectstore_middletier/MiddleTierAbstractTest.hpp similarity index 71% rename from objectstore_middletier/MiddleTierAdminAbstractTest.hpp rename to objectstore_middletier/MiddleTierAbstractTest.hpp index 325de740b0055afc8d9f5f57eb20628f8a3abf94..a285c8f722b63d31fbeede1fe58d10ec415539ee 100644 --- a/objectstore_middletier/MiddleTierAdminAbstractTest.hpp +++ b/objectstore_middletier/MiddleTierAbstractTest.hpp @@ -22,13 +22,7 @@ namespace unitTests { localMiddleTier * m_localMiddleTier; }; - class MiddleTierAdminAbstractTest: public ::testing::TestWithParam<MiddleTierFactory*> { - protected: - MiddleTierAdminAbstractTest() {} -// virtual void SetUp() { -// m_middleTierFactory = GetParam(); -// } -// MiddleTierFactory * m_middleTierFactory; + class MiddleTierAbstractTest: public ::testing::TestWithParam<MiddleTierFactory*> { }; } diff --git a/objectstore_middletier/MiddleTierAdminAbstractTest.cpp b/objectstore_middletier/MiddleTierAdminAbstractTest.cpp index 3aeaa809745b903b94bc09730c0f5675d2a652f6..9a68307490c2eaba43236905e357690ba5051eb2 100644 --- a/objectstore_middletier/MiddleTierAdminAbstractTest.cpp +++ b/objectstore_middletier/MiddleTierAdminAbstractTest.cpp @@ -16,15 +16,13 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ -#include "MiddleTierAdminAbstractTest.hpp" -#include "cta/SqliteMiddleTierAdmin.hpp" -#include "cta/SqliteMiddleTierUser.hpp" +#include "MiddleTierAbstractTest.hpp" #include <memory> #include <gtest/gtest.h> namespace unitTests { -TEST_P(MiddleTierAdminAbstractTest, createStorageClass_new) { +TEST_P(MiddleTierAbstractTest, admin_createStorageClass_new) { using namespace cta; const SecurityIdentity requester; @@ -54,8 +52,8 @@ TEST_P(MiddleTierAdminAbstractTest, createStorageClass_new) { } } -TEST_P(MiddleTierAdminAbstractTest, - createStorageClass_already_existing) { +TEST_P(MiddleTierAbstractTest, + admin_createStorageClass_already_existing) { using namespace cta; const SecurityIdentity requester; @@ -87,8 +85,8 @@ TEST_P(MiddleTierAdminAbstractTest, std::exception); } -TEST_P(MiddleTierAdminAbstractTest, - createStorageClass_lexicographical_order) { +TEST_P(MiddleTierAbstractTest, + admin_createStorageClass_lexicographical_order) { using namespace cta; const SecurityIdentity requester; @@ -120,7 +118,7 @@ TEST_P(MiddleTierAdminAbstractTest, } } -TEST_P(MiddleTierAdminAbstractTest, deleteStorageClass_existing) { +TEST_P(MiddleTierAbstractTest, admin_deleteStorageClass_existing) { using namespace cta; const SecurityIdentity requester; @@ -157,8 +155,8 @@ TEST_P(MiddleTierAdminAbstractTest, deleteStorageClass_existing) { } } -TEST_P(MiddleTierAdminAbstractTest, - deleteStorageClass_in_use_by_directory) { +TEST_P(MiddleTierAbstractTest, + admin_deleteStorageClass_in_use_by_directory) { using namespace cta; const SecurityIdentity requester; @@ -215,7 +213,7 @@ TEST_P(MiddleTierAdminAbstractTest, } } -TEST_P(MiddleTierAdminAbstractTest, deleteStorageClass_in_use_by_route) { +TEST_P(MiddleTierAbstractTest, admin_deleteStorageClass_in_use_by_route) { using namespace cta; const SecurityIdentity requester; @@ -307,7 +305,7 @@ TEST_P(MiddleTierAdminAbstractTest, deleteStorageClass_in_use_by_route) { } } -TEST_P(MiddleTierAdminAbstractTest, deleteStorageClass_non_existing) { +TEST_P(MiddleTierAbstractTest, admin_deleteStorageClass_non_existing) { using namespace cta; const SecurityIdentity requester; @@ -329,7 +327,7 @@ TEST_P(MiddleTierAdminAbstractTest, deleteStorageClass_non_existing) { } } -TEST_P(MiddleTierAdminAbstractTest, deleteTapePool_in_use) { +TEST_P(MiddleTierAbstractTest, admin_deleteTapePool_in_use) { using namespace cta; const SecurityIdentity requester; @@ -385,7 +383,7 @@ TEST_P(MiddleTierAdminAbstractTest, deleteTapePool_in_use) { } } -TEST_P(MiddleTierAdminAbstractTest, createArchivalRoute_new) { +TEST_P(MiddleTierAbstractTest, admin_createArchivalRoute_new) { using namespace cta; const SecurityIdentity requester; @@ -427,8 +425,8 @@ TEST_P(MiddleTierAdminAbstractTest, createArchivalRoute_new) { } } -TEST_P(MiddleTierAdminAbstractTest, - createArchivalRoute_already_existing) { +TEST_P(MiddleTierAbstractTest, + admin_createArchivalRoute_already_existing) { using namespace cta; const SecurityIdentity requester; @@ -473,7 +471,7 @@ TEST_P(MiddleTierAdminAbstractTest, copyNb, tapePoolName, comment), std::exception); } -TEST_P(MiddleTierAdminAbstractTest, deleteArchivalRoute_existing) { +TEST_P(MiddleTierAbstractTest, admin_deleteArchivalRoute_existing) { using namespace cta; const SecurityIdentity requester; @@ -524,7 +522,7 @@ TEST_P(MiddleTierAdminAbstractTest, deleteArchivalRoute_existing) { } } -TEST_P(MiddleTierAdminAbstractTest, deleteArchivalRoute_non_existing) { +TEST_P(MiddleTierAbstractTest, admin_deleteArchivalRoute_non_existing) { using namespace cta; const SecurityIdentity requester; @@ -554,7 +552,7 @@ TEST_P(MiddleTierAdminAbstractTest, deleteArchivalRoute_non_existing) { std::exception); } -TEST_P(MiddleTierAdminAbstractTest, createTape_new) { +TEST_P(MiddleTierAbstractTest, admin_createTape_new) { using namespace cta; const SecurityIdentity requester; @@ -630,8 +628,8 @@ TEST_P(MiddleTierAdminAbstractTest, createTape_new) { } } -TEST_P(MiddleTierAdminAbstractTest, - createTape_new_non_existing_library) { +TEST_P(MiddleTierAbstractTest, + admin_createTape_new_non_existing_library) { using namespace cta; const SecurityIdentity requester; @@ -680,7 +678,7 @@ TEST_P(MiddleTierAdminAbstractTest, capacityInBytes, tapeComment), std::exception); } -TEST_P(MiddleTierAdminAbstractTest, createTape_new_non_existing_pool) { +TEST_P(MiddleTierAbstractTest, admin_createTape_new_non_existing_pool) { using namespace cta; const SecurityIdentity requester; diff --git a/objectstore_middletier/MiddleTierTest.cpp b/objectstore_middletier/MiddleTierTest.cpp index 8928497e96213f1388b617e57bd5f881107518f2..f07191c5d059e40c0b42272ca6042f4d7c689d25 100644 --- a/objectstore_middletier/MiddleTierTest.cpp +++ b/objectstore_middletier/MiddleTierTest.cpp @@ -16,7 +16,7 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ -#include "MiddleTierAdminAbstractTest.hpp" +#include "MiddleTierAbstractTest.hpp" #include "ObjectStoreMiddleTierAdmin.hpp" #include "objectstore/BackendRados.hpp" #include "objectstore/BackendVFS.hpp" @@ -38,7 +38,7 @@ unitTests::MiddleTierFull middleTierRados; middleTierRados.admin = &mtaRados; middleTierRados.user = NULL; -INSTANTIATE_TEST_CASE_P(MiddleTierRados, MiddleTierAdminAbstractTest , ::testing::Values(middleTierRados)); +INSTANTIATE_TEST_CASE_P(MiddleTierRados, MiddleTierAbstractTest , ::testing::Values(middleTierRados)); #endif #if TEST_VFS @@ -70,7 +70,7 @@ public: } g_SQLiteMiddleTierFactory; // Macro chokes on implicit casting of pointer so we have to do it ourselves -INSTANTIATE_TEST_CASE_P(MiddleTierSQL, MiddleTierAdminAbstractTest, ::testing::Values( +INSTANTIATE_TEST_CASE_P(MiddleTierSQL, MiddleTierAbstractTest, ::testing::Values( (MiddleTierFactory*)&g_SQLiteMiddleTierFactory)); #endif diff --git a/objectstore_middletier/MiddleTierUserAbstractTest.cpp b/objectstore_middletier/MiddleTierUserAbstractTest.cpp new file mode 100644 index 0000000000000000000000000000000000000000..9f4a05b814ed702ca488a37da8f4f7a0395a1a01 --- /dev/null +++ b/objectstore_middletier/MiddleTierUserAbstractTest.cpp @@ -0,0 +1,928 @@ +/* + * 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 "MiddleTierAbstractTest.hpp" +#include <gtest/gtest.h> +#include <set> +#include <memory> + +namespace unitTests { + +class cta_client_SqliteMiddleTierUserTest: public ::testing::Test { +protected: + + virtual void SetUp() { + } + + virtual void TearDown() { + } +}; + +TEST_P(MiddleTierAbstractTest, + user_getDirContents_root_dir_is_empty) { + using namespace cta; + + std::auto_ptr<localMiddleTier> m_middleTier(GetParam()->allocateLocalMiddleTier()); + const SecurityIdentity requester; + const std::string dirPath = "/"; + + DirIterator itor; + ASSERT_NO_THROW(itor = m_middleTier->user().getDirContents(requester, "/")); + ASSERT_FALSE(itor.hasMore()); +} + +TEST_P(MiddleTierAbstractTest, user_createDir_empty_string) { + using namespace cta; + + std::auto_ptr<localMiddleTier> m_middleTier(GetParam()->allocateLocalMiddleTier()); + const SecurityIdentity requester; + const std::string dirPath = ""; + + ASSERT_THROW(m_middleTier->user().createDir(requester, dirPath), std::exception); +} + +TEST_P(MiddleTierAbstractTest, + user_createDir_consecutive_slashes) { + using namespace cta; + + std::auto_ptr<localMiddleTier> m_middleTier(GetParam()->allocateLocalMiddleTier()); + const SecurityIdentity requester; + const std::string dirPath = "//"; + + ASSERT_THROW(m_middleTier->user().createDir(requester, dirPath), std::exception); +} + +TEST_P(MiddleTierAbstractTest, user_createDir_invalid_chars) { + using namespace cta; + + std::auto_ptr<localMiddleTier> m_middleTier(GetParam()->allocateLocalMiddleTier()); + const SecurityIdentity requester; + const std::string dirPath = "/grandparent/?parent"; + + ASSERT_THROW(m_middleTier->user().createDir(requester, dirPath), std::exception); +} + +TEST_P(MiddleTierAbstractTest, user_createDir_top_level) { + using namespace cta; + + std::auto_ptr<localMiddleTier> m_middleTier(GetParam()->allocateLocalMiddleTier()); + const SecurityIdentity requester; + const std::string dirPath = "/grandparent"; + + ASSERT_NO_THROW(m_middleTier->user().createDir(requester, dirPath)); + + DirIterator itor; + + ASSERT_NO_THROW(itor = m_middleTier->user().getDirContents(requester, "/")); + + ASSERT_TRUE(itor.hasMore()); + + DirEntry entry; + + ASSERT_NO_THROW(entry = itor.next()); + + ASSERT_EQ(std::string("grandparent"), entry.getName()); +} + +TEST_P(MiddleTierAbstractTest, user_createDir_second_level) { + using namespace cta; + + std::auto_ptr<localMiddleTier> m_middleTier(GetParam()->allocateLocalMiddleTier()); + const SecurityIdentity requester; + + ASSERT_TRUE(m_middleTier->user().getDirStorageClass(requester, "/").empty()); + + { + const std::string topLevelDirPath = "/grandparent"; + + ASSERT_NO_THROW(m_middleTier->user().createDir(requester, topLevelDirPath)); + } + + { + DirIterator itor; + + ASSERT_NO_THROW(itor = m_middleTier->user().getDirContents(requester, "/")); + + ASSERT_TRUE(itor.hasMore()); + + DirEntry entry; + + ASSERT_NO_THROW(entry = itor.next()); + + ASSERT_EQ(std::string("grandparent"), entry.getName()); + } + + ASSERT_TRUE(m_middleTier->user().getDirStorageClass(requester, "/grandparent").empty()); + + { + const std::string secondLevelDirPath = "/grandparent/parent"; + + ASSERT_NO_THROW(m_middleTier->user().createDir(requester, secondLevelDirPath)); + } + + { + DirIterator itor; + + ASSERT_NO_THROW(itor = m_middleTier->user().getDirContents(requester, "/")); + + ASSERT_TRUE(itor.hasMore()); + + DirEntry entry; + + ASSERT_NO_THROW(entry = itor.next()); + + ASSERT_EQ(std::string("grandparent"), entry.getName()); + } + + { + DirIterator itor; + + ASSERT_NO_THROW(itor = m_middleTier->user().getDirContents(requester, "/grandparent")); + + ASSERT_TRUE(itor.hasMore()); + + DirEntry entry; + + ASSERT_NO_THROW(entry = itor.next()); + + ASSERT_EQ(std::string("parent"), entry.getName()); + } + + ASSERT_TRUE(m_middleTier->user().getDirStorageClass(requester, + "/grandparent/parent").empty()); +} + +TEST_P(MiddleTierAbstractTest, + user_createDir_inherit_storage_class) { + using namespace cta; + + std::auto_ptr<localMiddleTier> m_middleTier(GetParam()->allocateLocalMiddleTier()); + const SecurityIdentity requester; + + ASSERT_TRUE(m_middleTier->user().getDirStorageClass(requester, "/").empty()); + + { + const std::string name = "TestStorageClass"; + const uint16_t nbCopies = 2; + const std::string comment = "Comment"; + ASSERT_NO_THROW(m_middleTier->admin().createStorageClass(requester, name, nbCopies, comment)); + } + + { + const std::string topLevelDirPath = "/grandparent"; + + ASSERT_NO_THROW(m_middleTier->user().createDir(requester, topLevelDirPath)); + } + + { + DirIterator itor; + + ASSERT_NO_THROW(itor = m_middleTier->user().getDirContents(requester, "/")); + + ASSERT_TRUE(itor.hasMore()); + + DirEntry entry; + + ASSERT_NO_THROW(entry = itor.next()); + + ASSERT_EQ(std::string("grandparent"), entry.getName()); + + ASSERT_TRUE(m_middleTier->user().getDirStorageClass(requester, "/grandparent").empty()); + + ASSERT_NO_THROW(m_middleTier->user().setDirStorageClass(requester, "/grandparent", + "TestStorageClass")); + } + + ASSERT_EQ(std::string("TestStorageClass"), + m_middleTier->user().getDirStorageClass(requester, "/grandparent")); + + { + const std::string secondLevelDirPath = "/grandparent/parent"; + + ASSERT_NO_THROW(m_middleTier->user().createDir(requester, secondLevelDirPath)); + } + + { + DirIterator itor; + + ASSERT_NO_THROW(itor = m_middleTier->user().getDirContents(requester, "/")); + + ASSERT_TRUE(itor.hasMore()); + + DirEntry entry; + + ASSERT_NO_THROW(entry = itor.next()); + + ASSERT_EQ(std::string("grandparent"), entry.getName()); + } + + { + DirIterator itor; + + ASSERT_NO_THROW(itor = m_middleTier->user().getDirContents(requester, "/grandparent")); + + ASSERT_TRUE(itor.hasMore()); + + DirEntry entry; + + ASSERT_NO_THROW(entry = itor.next()); + + ASSERT_EQ(std::string("parent"), entry.getName()); + } + + ASSERT_EQ(std::string("TestStorageClass"), + m_middleTier->user().getDirStorageClass(requester, "/grandparent/parent")); +} + +TEST_P(MiddleTierAbstractTest, user_deleteDir_root) { + using namespace cta; + + std::auto_ptr<localMiddleTier> m_middleTier(GetParam()->allocateLocalMiddleTier()); + const SecurityIdentity requester; + const std::string dirPath = "/"; + + ASSERT_THROW(m_middleTier->user().deleteDir(requester, "/"), std::exception); +} + +TEST_P(MiddleTierAbstractTest, user_deleteDir_existing_top_level) { + using namespace cta; + + std::auto_ptr<localMiddleTier> m_middleTier(GetParam()->allocateLocalMiddleTier()); + const SecurityIdentity requester; + const std::string dirPath = "/grandparent"; + + ASSERT_NO_THROW(m_middleTier->user().createDir(requester, dirPath)); + + { + DirIterator itor; + + ASSERT_NO_THROW(itor = m_middleTier->user().getDirContents(requester, "/")); + + ASSERT_TRUE(itor.hasMore()); + + DirEntry entry; + + ASSERT_NO_THROW(entry = itor.next()); + + ASSERT_EQ(std::string("grandparent"), entry.getName()); + } + + ASSERT_NO_THROW(m_middleTier->user().deleteDir(requester, "/grandparent")); + + { + DirIterator itor; + + ASSERT_NO_THROW(itor = m_middleTier->user().getDirContents(requester, "/")); + + ASSERT_FALSE(itor.hasMore()); + } +} + +TEST_P(MiddleTierAbstractTest, + user_deleteDir_non_empty_top_level) { + using namespace cta; + + std::auto_ptr<localMiddleTier> m_middleTier(GetParam()->allocateLocalMiddleTier()); + const SecurityIdentity requester; + + { + const std::string topLevelDirPath = "/grandparent"; + + ASSERT_NO_THROW(m_middleTier->user().createDir(requester, topLevelDirPath)); + + DirIterator itor; + + ASSERT_NO_THROW(itor = m_middleTier->user().getDirContents(requester, "/")); + + ASSERT_TRUE(itor.hasMore()); + + DirEntry entry; + + ASSERT_NO_THROW(entry = itor.next()); + + ASSERT_EQ(std::string("grandparent"), entry.getName()); + } + + { + const std::string secondLevelDirPath = "/grandparent/parent"; + + ASSERT_NO_THROW(m_middleTier->user().createDir(requester, secondLevelDirPath)); + + DirIterator itor; + + ASSERT_NO_THROW(itor = m_middleTier->user().getDirContents(requester, "/")); + + ASSERT_TRUE(itor.hasMore()); + + DirEntry entry; + + ASSERT_NO_THROW(entry = itor.next()); + + ASSERT_EQ(std::string("grandparent"), entry.getName()); + } + + { + DirIterator itor; + + ASSERT_NO_THROW(itor = m_middleTier->user().getDirContents(requester, "/grandparent")); + + ASSERT_TRUE(itor.hasMore()); + + DirEntry entry; + + ASSERT_NO_THROW(entry = itor.next()); + + ASSERT_EQ(std::string("parent"), entry.getName()); + } + + ASSERT_THROW(m_middleTier->user().deleteDir(requester, "/grandparent"), std::exception); + + { + DirIterator itor; + + ASSERT_NO_THROW(itor = m_middleTier->user().getDirContents(requester, "/grandparent")); + + ASSERT_TRUE(itor.hasMore()); + + DirEntry entry; + + ASSERT_NO_THROW(entry = itor.next()); + + ASSERT_EQ(std::string("parent"), entry.getName()); + } +} + +TEST_P(MiddleTierAbstractTest, + user_deleteDir_non_existing_top_level) { + using namespace cta; + + std::auto_ptr<localMiddleTier> m_middleTier(GetParam()->allocateLocalMiddleTier()); + const SecurityIdentity requester; + + ASSERT_THROW(m_middleTier->user().deleteDir(requester, "/grandparent"), std::exception); +} + +TEST_P(MiddleTierAbstractTest, user_setDirStorageClass_top_level) { + using namespace cta; + + std::auto_ptr<localMiddleTier> m_middleTier(GetParam()->allocateLocalMiddleTier()); + const SecurityIdentity requester; + const std::string dirPath = "/grandparent"; + + ASSERT_NO_THROW(m_middleTier->user().createDir(requester, dirPath)); + + DirIterator itor; + + ASSERT_NO_THROW(itor = m_middleTier->user().getDirContents(requester, "/")); + + ASSERT_TRUE(itor.hasMore()); + + DirEntry entry; + + ASSERT_NO_THROW(entry = itor.next()); + + ASSERT_EQ(std::string("grandparent"), entry.getName()); + + { + std::string name; + ASSERT_NO_THROW(name = m_middleTier->user().getDirStorageClass(requester, dirPath)); + ASSERT_TRUE(name.empty()); + } + + const std::string storageClassName = "TestStorageClass"; + const uint16_t nbCopies = 2; + const std::string comment = "Comment"; + { + ASSERT_NO_THROW(m_middleTier->admin().createStorageClass(requester, storageClassName, + nbCopies, comment)); + } + + ASSERT_NO_THROW(m_middleTier->user().setDirStorageClass(requester, dirPath, + storageClassName)); + + { + std::string name; + ASSERT_NO_THROW(name = m_middleTier->user().getDirStorageClass(requester, dirPath)); + ASSERT_EQ(storageClassName, name); + } +} + +TEST_P(MiddleTierAbstractTest, + user_clearDirStorageClass_top_level) { + using namespace cta; + + std::auto_ptr<localMiddleTier> m_middleTier(GetParam()->allocateLocalMiddleTier()); + const SecurityIdentity requester; + const std::string dirPath = "/grandparent"; + + ASSERT_NO_THROW(m_middleTier->user().createDir(requester, dirPath)); + + DirIterator itor; + + ASSERT_NO_THROW(itor = m_middleTier->user().getDirContents(requester, "/")); + + ASSERT_TRUE(itor.hasMore()); + + DirEntry entry; + + ASSERT_NO_THROW(entry = itor.next()); + + ASSERT_EQ(std::string("grandparent"), entry.getName()); + + { + std::string name; + ASSERT_NO_THROW(name = m_middleTier->user().getDirStorageClass(requester, dirPath)); + ASSERT_TRUE(name.empty()); + } + + const std::string storageClassName = "TestStorageClass"; + const uint16_t nbCopies = 2; + const std::string comment = "Comment"; + ASSERT_NO_THROW(m_middleTier->admin().createStorageClass(requester, storageClassName, + nbCopies, comment)); + + ASSERT_NO_THROW(m_middleTier->user().setDirStorageClass(requester, dirPath, + storageClassName)); + + { + std::string name; + ASSERT_NO_THROW(name = m_middleTier->user().getDirStorageClass(requester, dirPath)); + ASSERT_EQ(storageClassName, name); + } + + ASSERT_THROW(m_middleTier->admin().deleteStorageClass(requester, storageClassName), + std::exception); + + ASSERT_NO_THROW(m_middleTier->user().clearDirStorageClass(requester, dirPath)); + + { + std::string name; + ASSERT_NO_THROW(name = m_middleTier->user().getDirStorageClass(requester, dirPath)); + ASSERT_TRUE(name.empty()); + } + + ASSERT_NO_THROW(m_middleTier->admin().deleteStorageClass(requester, storageClassName)); +} + +TEST_P(MiddleTierAbstractTest, user_archive_to_new_file) { + using namespace cta; + + std::auto_ptr<localMiddleTier> m_middleTier(GetParam()->allocateLocalMiddleTier()); + const SecurityIdentity requester; + + const std::string storageClassName = "TestStorageClass"; + const uint16_t nbCopies = 1; + const std::string storageClassComment = "Storage-class comment"; + ASSERT_NO_THROW(m_middleTier->admin().createStorageClass(requester, storageClassName, + nbCopies, storageClassComment)); + + const std::string dirPath = "/grandparent"; + ASSERT_NO_THROW(m_middleTier->user().createDir(requester, dirPath)); + ASSERT_NO_THROW(m_middleTier->user().setDirStorageClass(requester, dirPath, + storageClassName)); + + const std::string tapePoolName = "TestTapePool"; + const uint16_t nbPartialTapes = 1; + const std::string tapePoolComment = "Tape-pool comment"; + ASSERT_NO_THROW(m_middleTier->admin().createTapePool(requester, tapePoolName, + nbPartialTapes, tapePoolComment)); + + const uint16_t copyNb = 1; + const std::string archivalRouteComment = "Archival-route comment"; + ASSERT_NO_THROW(m_middleTier->admin().createArchivalRoute(requester, storageClassName, + copyNb, tapePoolName, archivalRouteComment)); + + std::list<std::string> srcUrls; + srcUrls.push_back("diskUrl"); + const std::string dstPath = "/grandparent/parent_file"; + ASSERT_NO_THROW(m_middleTier->user().archive(requester, srcUrls, dstPath)); + + { + DirIterator itor; + ASSERT_NO_THROW(itor = m_middleTier->user().getDirContents(requester, "/")); + ASSERT_TRUE(itor.hasMore()); + DirEntry entry; + ASSERT_NO_THROW(entry = itor.next()); + ASSERT_EQ(std::string("grandparent"), entry.getName()); + ASSERT_EQ(DirEntry::ENTRYTYPE_DIRECTORY, entry.getType()); + ASSERT_EQ(storageClassName, entry.getStorageClassName()); + } + + { + DirIterator itor; + ASSERT_NO_THROW(itor = m_middleTier->user().getDirContents(requester, + "/grandparent")); + ASSERT_TRUE(itor.hasMore()); + DirEntry entry; + ASSERT_NO_THROW(entry = itor.next()); + ASSERT_EQ(std::string("parent_file"), entry.getName()); + ASSERT_EQ(DirEntry::ENTRYTYPE_FILE, entry.getType()); + ASSERT_EQ(storageClassName, entry.getStorageClassName()); + } + + { + DirEntry entry; + ASSERT_NO_THROW(entry = m_middleTier->user().stat(requester, dstPath)); + ASSERT_EQ(DirEntry::ENTRYTYPE_FILE, entry.getType()); + ASSERT_EQ(storageClassName, entry.getStorageClassName()); + } + + { + const std::map<TapePool, std::list<ArchivalJob> > allJobs = + m_middleTier->user().getArchivalJobs(requester); + ASSERT_EQ(1, allJobs.size()); + std::map<TapePool, std::list<ArchivalJob> >::const_iterator + poolItor = allJobs.begin(); + ASSERT_FALSE(poolItor == allJobs.end()); + const TapePool &pool = poolItor->first; + ASSERT_TRUE(tapePoolName == pool.getName()); + const std::list<ArchivalJob> &poolJobs = poolItor->second; + ASSERT_EQ(1, poolJobs.size()); + std::set<std::string> srcUrls; + std::set<std::string> dstPaths; + for(std::list<ArchivalJob>::const_iterator jobItor = poolJobs.begin(); + jobItor != poolJobs.end(); jobItor++) { + ASSERT_EQ(ArchivalJobState::PENDING, jobItor->getState()); + srcUrls.insert(jobItor->getSrcUrl()); + dstPaths.insert(jobItor->getDstPath()); + } + ASSERT_EQ(1, srcUrls.size()); + ASSERT_FALSE(srcUrls.find("diskUrl") == srcUrls.end()); + ASSERT_EQ(1, dstPaths.size()); + ASSERT_FALSE(dstPaths.find("/grandparent/parent_file") == dstPaths.end()); + } + + { + const std::list<ArchivalJob> poolJobs = m_middleTier->user().getArchivalJobs(requester, + tapePoolName); + ASSERT_EQ(1, poolJobs.size()); + std::set<std::string> srcUrls; + std::set<std::string> dstPaths; + for(std::list<ArchivalJob>::const_iterator jobItor = poolJobs.begin(); + jobItor != poolJobs.end(); jobItor++) { + ASSERT_EQ(ArchivalJobState::PENDING, jobItor->getState()); + srcUrls.insert(jobItor->getSrcUrl()); + dstPaths.insert(jobItor->getDstPath()); + } + ASSERT_EQ(1, srcUrls.size()); + ASSERT_FALSE(srcUrls.find("diskUrl") == srcUrls.end()); + ASSERT_EQ(1, dstPaths.size()); + ASSERT_FALSE(dstPaths.find("/grandparent/parent_file") == dstPaths.end()); + } +} + +TEST_P(MiddleTierAbstractTest, + user_archive_to_new_file_with_no_storage_class) { + using namespace cta; + + std::auto_ptr<localMiddleTier> m_middleTier(GetParam()->allocateLocalMiddleTier()); + const SecurityIdentity requester; + + const std::string dirPath = "/grandparent"; + ASSERT_NO_THROW(m_middleTier->user().createDir(requester, dirPath)); + + std::list<std::string> srcUrls; + srcUrls.push_back("diskUrl"); + const std::string dstPath = "/grandparent/parent_file"; + ASSERT_THROW(m_middleTier->user().archive(requester, srcUrls, dstPath), std::exception); +} + +TEST_P(MiddleTierAbstractTest, + user_archive_to_new_file_with_zero_copy_storage_class) { + using namespace cta; + + std::auto_ptr<localMiddleTier> m_middleTier(GetParam()->allocateLocalMiddleTier()); + const SecurityIdentity requester; + + const std::string storageClassName = "TestStorageClass"; + const uint16_t nbCopies = 0; + const std::string storageClassComment = "Storage-class comment"; + ASSERT_NO_THROW(m_middleTier->admin().createStorageClass(requester, storageClassName, + nbCopies, storageClassComment)); + + const std::string dirPath = "/grandparent"; + ASSERT_NO_THROW(m_middleTier->user().createDir(requester, dirPath)); + ASSERT_NO_THROW(m_middleTier->user().setDirStorageClass(requester, dirPath, + storageClassName)); + + std::list<std::string> srcUrls; + srcUrls.push_back("diskUrl"); + const std::string dstPath = "/grandparent/parent_file"; + ASSERT_THROW(m_middleTier->user().archive(requester, srcUrls, dstPath), std::exception); +} + +TEST_P(MiddleTierAbstractTest, user_archive_to_new_file_with_no_route) { + using namespace cta; + + std::auto_ptr<localMiddleTier> m_middleTier(GetParam()->allocateLocalMiddleTier()); + const SecurityIdentity requester; + + const std::string storageClassName = "TestStorageClass"; + const uint16_t nbCopies = 1; + const std::string storageClassComment = "Storage-class comment"; + ASSERT_NO_THROW(m_middleTier->admin().createStorageClass(requester, storageClassName, + nbCopies, storageClassComment)); + + const std::string dirPath = "/grandparent"; + ASSERT_NO_THROW(m_middleTier->user().createDir(requester, dirPath)); + ASSERT_NO_THROW(m_middleTier->user().setDirStorageClass(requester, dirPath, + storageClassName)); + + const std::string tapePoolName = "TestTapePool"; + const uint16_t nbPartialTapes = 1; + const std::string tapePoolComment = "Tape-pool comment"; + ASSERT_NO_THROW(m_middleTier->admin().createTapePool(requester, tapePoolName, + nbPartialTapes, tapePoolComment)); + + std::list<std::string> srcUrls; + srcUrls.push_back("diskUrl"); + const std::string dstPath = "/grandparent/parent_file"; + ASSERT_THROW(m_middleTier->user().archive(requester, srcUrls, dstPath), std::exception); +} + +TEST_P(MiddleTierAbstractTest, + user_archive_to_new_file_with_incomplete_routing) { + using namespace cta; + + std::auto_ptr<localMiddleTier> m_middleTier(GetParam()->allocateLocalMiddleTier()); + const SecurityIdentity requester; + + const std::string storageClassName = "TestStorageClass"; + const uint16_t nbCopies = 2; + const std::string storageClassComment = "Storage-class comment"; + ASSERT_NO_THROW(m_middleTier->admin().createStorageClass(requester, storageClassName, + nbCopies, storageClassComment)); + + const std::string dirPath = "/grandparent"; + ASSERT_NO_THROW(m_middleTier->user().createDir(requester, dirPath)); + ASSERT_NO_THROW(m_middleTier->user().setDirStorageClass(requester, dirPath, + storageClassName)); + + const std::string tapePoolName = "TestTapePool"; + const uint16_t nbPartialTapes = 1; + const std::string tapePoolComment = "Tape-pool comment"; + ASSERT_NO_THROW(m_middleTier->admin().createTapePool(requester, tapePoolName, + nbPartialTapes, tapePoolComment)); + + const uint16_t copyNb = 1; + const std::string archivalRouteComment = "Archival-route comment"; + ASSERT_NO_THROW(m_middleTier->admin().createArchivalRoute(requester, storageClassName, + copyNb, tapePoolName, archivalRouteComment)); + + std::list<std::string> srcUrls; + srcUrls.push_back("diskUrl"); + const std::string dstPath = "/grandparent/parent_file"; + ASSERT_THROW(m_middleTier->user().archive(requester, srcUrls, dstPath), std::exception); +} + +TEST_P(MiddleTierAbstractTest, user_archive_to_directory) { + using namespace cta; + + std::auto_ptr<localMiddleTier> m_middleTier(GetParam()->allocateLocalMiddleTier()); + const SecurityIdentity requester; + + const std::string storageClassName = "TestStorageClass"; + const uint16_t nbCopies = 1; + const std::string storageClassComment = "Storage-class comment"; + ASSERT_NO_THROW(m_middleTier->admin().createStorageClass(requester, storageClassName, + nbCopies, storageClassComment)); + + const std::string dirPath = "/grandparent"; + ASSERT_NO_THROW(m_middleTier->user().createDir(requester, dirPath)); + ASSERT_NO_THROW(m_middleTier->user().setDirStorageClass(requester, dirPath, + storageClassName)); + + const std::string tapePoolName = "TestTapePool"; + const uint16_t nbPartialTapes = 1; + const std::string tapePoolComment = "Tape-pool comment"; + ASSERT_NO_THROW(m_middleTier->admin().createTapePool(requester, tapePoolName, + nbPartialTapes, tapePoolComment)); + + const uint16_t copyNb = 1; + const std::string archivalRouteComment = "Archival-route comment"; + ASSERT_NO_THROW(m_middleTier->admin().createArchivalRoute(requester, storageClassName, + copyNb, tapePoolName, archivalRouteComment)); + + std::list<std::string> srcUrls; + srcUrls.push_back("diskUrl1"); + srcUrls.push_back("diskUrl2"); + srcUrls.push_back("diskUrl3"); + srcUrls.push_back("diskUrl4"); + const std::string dstPath = "/grandparent"; + ASSERT_NO_THROW(m_middleTier->user().archive(requester, srcUrls, dstPath)); + + { + DirIterator itor; + ASSERT_NO_THROW(itor = m_middleTier->user().getDirContents(requester, "/")); + ASSERT_TRUE(itor.hasMore()); + DirEntry entry; + ASSERT_NO_THROW(entry = itor.next()); + ASSERT_EQ(std::string("grandparent"), entry.getName()); + ASSERT_EQ(DirEntry::ENTRYTYPE_DIRECTORY, entry.getType()); + ASSERT_EQ(storageClassName, entry.getStorageClassName()); + } + + { + std::set<std::string> archiveFileNames; + DirIterator itor; + ASSERT_NO_THROW(itor = m_middleTier->user().getDirContents(requester, + "/grandparent")); + while(itor.hasMore()) { + const DirEntry entry = itor.next(); + archiveFileNames.insert(entry.getName()); + } + ASSERT_EQ(4, archiveFileNames.size()); + ASSERT_TRUE(archiveFileNames.find("diskUrl1") != archiveFileNames.end()); + ASSERT_TRUE(archiveFileNames.find("diskUrl2") != archiveFileNames.end()); + ASSERT_TRUE(archiveFileNames.find("diskUrl3") != archiveFileNames.end()); + ASSERT_TRUE(archiveFileNames.find("diskUrl4") != archiveFileNames.end()); + } + + { + const std::map<TapePool, std::list<ArchivalJob> > allJobs = + m_middleTier->user().getArchivalJobs(requester); + ASSERT_EQ(1, allJobs.size()); + std::map<TapePool, std::list<ArchivalJob> >::const_iterator + poolItor = allJobs.begin(); + ASSERT_FALSE(poolItor == allJobs.end()); + const TapePool &pool = poolItor->first; + ASSERT_TRUE(tapePoolName == pool.getName()); + const std::list<ArchivalJob> &poolJobs = poolItor->second; + ASSERT_EQ(4, poolJobs.size()); + std::set<std::string> srcUrls; + std::set<std::string> dstPaths; + for(std::list<ArchivalJob>::const_iterator jobItor = poolJobs.begin(); + jobItor != poolJobs.end(); jobItor++) { + ASSERT_EQ(ArchivalJobState::PENDING, jobItor->getState()); + srcUrls.insert(jobItor->getSrcUrl()); + dstPaths.insert(jobItor->getDstPath()); + } + ASSERT_EQ(4, srcUrls.size()); + ASSERT_FALSE(srcUrls.find("diskUrl1") == srcUrls.end()); + ASSERT_FALSE(srcUrls.find("diskUrl2") == srcUrls.end()); + ASSERT_FALSE(srcUrls.find("diskUrl3") == srcUrls.end()); + ASSERT_FALSE(srcUrls.find("diskUrl4") == srcUrls.end()); + ASSERT_EQ(4, dstPaths.size()); + ASSERT_FALSE(dstPaths.find("/grandparent/diskUrl1") == srcUrls.end()); + ASSERT_FALSE(dstPaths.find("/grandparent/diskUrl2") == srcUrls.end()); + ASSERT_FALSE(dstPaths.find("/grandparent/diskUrl3") == srcUrls.end()); + ASSERT_FALSE(dstPaths.find("/grandparent/diskUrl4") == srcUrls.end()); + } + + { + const std::list<ArchivalJob> poolJobs = m_middleTier->user().getArchivalJobs(requester, + tapePoolName); + ASSERT_EQ(4, poolJobs.size()); + std::set<std::string> srcUrls; + std::set<std::string> dstPaths; + for(std::list<ArchivalJob>::const_iterator jobItor = poolJobs.begin(); + jobItor != poolJobs.end(); jobItor++) { + ASSERT_EQ(ArchivalJobState::PENDING, jobItor->getState()); + srcUrls.insert(jobItor->getSrcUrl()); + dstPaths.insert(jobItor->getDstPath()); + } + ASSERT_EQ(4, srcUrls.size()); + ASSERT_FALSE(srcUrls.find("diskUrl1") == srcUrls.end()); + ASSERT_FALSE(srcUrls.find("diskUrl2") == srcUrls.end()); + ASSERT_FALSE(srcUrls.find("diskUrl3") == srcUrls.end()); + ASSERT_FALSE(srcUrls.find("diskUrl4") == srcUrls.end()); + ASSERT_EQ(4, dstPaths.size()); + ASSERT_FALSE(dstPaths.find("/grandparent/diskUrl1") == srcUrls.end()); + ASSERT_FALSE(dstPaths.find("/grandparent/diskUrl2") == srcUrls.end()); + ASSERT_FALSE(dstPaths.find("/grandparent/diskUrl3") == srcUrls.end()); + ASSERT_FALSE(dstPaths.find("/grandparent/diskUrl4") == srcUrls.end()); + } +} + +TEST_P(MiddleTierAbstractTest, + user_archive_to_directory_without_storage_class) { + using namespace cta; + + std::auto_ptr<localMiddleTier> m_middleTier(GetParam()->allocateLocalMiddleTier()); + const SecurityIdentity requester; + + const std::string dirPath = "/grandparent"; + ASSERT_NO_THROW(m_middleTier->user().createDir(requester, dirPath)); + + std::list<std::string> srcUrls; + srcUrls.push_back("diskUrl1"); + srcUrls.push_back("diskUrl2"); + srcUrls.push_back("diskUrl3"); + srcUrls.push_back("diskUrl4"); + const std::string dstPath = "/grandparent"; + ASSERT_THROW(m_middleTier->user().archive(requester, srcUrls, dstPath), std::exception); +} + +TEST_P(MiddleTierAbstractTest, + user_archive_to_directory_with_zero_copy_storage_class) { + using namespace cta; + + std::auto_ptr<localMiddleTier> m_middleTier(GetParam()->allocateLocalMiddleTier()); + const SecurityIdentity requester; + + const std::string storageClassName = "TestStorageClass"; + const uint16_t nbCopies = 0; + const std::string storageClassComment = "Storage-class comment"; + ASSERT_NO_THROW(m_middleTier->admin().createStorageClass(requester, storageClassName, + nbCopies, storageClassComment)); + + const std::string dirPath = "/grandparent"; + ASSERT_NO_THROW(m_middleTier->user().createDir(requester, dirPath)); + ASSERT_NO_THROW(m_middleTier->user().setDirStorageClass(requester, dirPath, + storageClassName)); + + std::list<std::string> srcUrls; + srcUrls.push_back("diskUrl1"); + srcUrls.push_back("diskUrl2"); + srcUrls.push_back("diskUrl3"); + srcUrls.push_back("diskUrl4"); + const std::string dstPath = "/grandparent"; + ASSERT_THROW(m_middleTier->user().archive(requester, srcUrls, dstPath), std::exception); +} + +TEST_P(MiddleTierAbstractTest, user_archive_to_directory_with_no_route) { + using namespace cta; + + std::auto_ptr<localMiddleTier> m_middleTier(GetParam()->allocateLocalMiddleTier()); + const SecurityIdentity requester; + + const std::string storageClassName = "TestStorageClass"; + const uint16_t nbCopies = 1; + const std::string storageClassComment = "Storage-class comment"; + ASSERT_NO_THROW(m_middleTier->admin().createStorageClass(requester, storageClassName, + nbCopies, storageClassComment)); + + const std::string dirPath = "/grandparent"; + ASSERT_NO_THROW(m_middleTier->user().createDir(requester, dirPath)); + ASSERT_NO_THROW(m_middleTier->user().setDirStorageClass(requester, dirPath, + storageClassName)); + + const std::string tapePoolName = "TestTapePool"; + const uint16_t nbPartialTapes = 1; + const std::string tapePoolComment = "Tape-pool comment"; + ASSERT_NO_THROW(m_middleTier->admin().createTapePool(requester, tapePoolName, + nbPartialTapes, tapePoolComment)); + + std::list<std::string> srcUrls; + srcUrls.push_back("diskUrl1"); + srcUrls.push_back("diskUrl2"); + srcUrls.push_back("diskUrl3"); + srcUrls.push_back("diskUrl4"); + const std::string dstPath = "/grandparent"; + ASSERT_THROW(m_middleTier->user().archive(requester, srcUrls, dstPath), std::exception); +} + +TEST_P(MiddleTierAbstractTest, + user_archive_to_directory_with_incomplete_routing) { + using namespace cta; + + std::auto_ptr<localMiddleTier> m_middleTier(GetParam()->allocateLocalMiddleTier()); + const SecurityIdentity requester; + + const std::string storageClassName = "TestStorageClass"; + const uint16_t nbCopies = 2; + const std::string storageClassComment = "Storage-class comment"; + ASSERT_NO_THROW(m_middleTier->admin().createStorageClass(requester, storageClassName, + nbCopies, storageClassComment)); + + const std::string dirPath = "/grandparent"; + ASSERT_NO_THROW(m_middleTier->user().createDir(requester, dirPath)); + ASSERT_NO_THROW(m_middleTier->user().setDirStorageClass(requester, dirPath, + storageClassName)); + + const std::string tapePoolName = "TestTapePool"; + const uint16_t nbPartialTapes = 1; + const std::string tapePoolComment = "Tape-pool comment"; + ASSERT_NO_THROW(m_middleTier->admin().createTapePool(requester, tapePoolName, + nbPartialTapes, tapePoolComment)); + + const uint16_t copyNb = 1; + const std::string archivalRouteComment = "Archival-route comment"; + ASSERT_NO_THROW(m_middleTier->admin().createArchivalRoute(requester, storageClassName, + copyNb, tapePoolName, archivalRouteComment)); + + std::list<std::string> srcUrls; + srcUrls.push_back("diskUrl1"); + srcUrls.push_back("diskUrl2"); + srcUrls.push_back("diskUrl3"); + srcUrls.push_back("diskUrl4"); + const std::string dstPath = "/grandparent"; + ASSERT_THROW(m_middleTier->user().archive(requester, srcUrls, dstPath), std::exception); +} + +} // namespace unitTests