Commit 11d08f4e authored by Steven Murray's avatar Steven Murray
Browse files

Implemented first version of MockMiddleTierUser::archive() for single files

parent 1ac1bd50
......@@ -63,6 +63,20 @@ public:
const SecurityIdentity &requester,
const std::string &dirPath) const = 0;
/**
* Returns the directory entry information for the specified directory or file
* within the archive namespace.
*
* @param requester The identity of the user requesting the directory entry.
* @param path The absolute path of the directory or file within the archive
* namespace.
* @return The directory entry information for the specified directory or file
* within the archive namespace.
*/
virtual DirectoryEntry stat(
const SecurityIdentity &requester,
const std::string path) const = 0;
/**
* Sets the storage class of the specified directory to the specified value.
*
......@@ -116,12 +130,13 @@ public:
*
* @param requester The identity of the user requesting the archival.
* @param srcUrls List of one or more source files.
* @param dst Destination file or directory within the archive namespace.
* @param dstPath The absolute path of the destination file or directory
* within the archive namespace.
*/
virtual void archive(
const SecurityIdentity &requester,
const std::list<std::string> &srcUrls,
const std::string &dst) = 0;
const std::string &dstPath) = 0;
/**
* Returns all of the existing archival jobs grouped by tape pool and then
......@@ -152,7 +167,8 @@ public:
*
* @param requester The identity of the user requesting the deletion of the
* tape.
* @param dstPath The full path of the destination file within the archive.
* @param dstPath The absolute path of the destination file within the
* archive namespace.
*/
virtual void deleteArchivalJob(
const SecurityIdentity &requester,
......
......@@ -148,6 +148,18 @@ cta::DirectoryIterator cta::MockMiddleTierUser::getDirectoryContents(
return DirectoryIterator(dirNode.getDirectoryEntries());
}
//------------------------------------------------------------------------------
// stat
//------------------------------------------------------------------------------
cta::DirectoryEntry cta::MockMiddleTierUser::stat(
const SecurityIdentity &requester,
const std::string path) const {
Utils::checkAbsolutePathSyntax(path);
const FileSystemNode &node = getFileSystemNode(path);
return node.getFileSystemEntry().getEntry();
}
//------------------------------------------------------------------------------
// setDirectoryStorageClass
//------------------------------------------------------------------------------
......@@ -206,12 +218,12 @@ std::string cta::MockMiddleTierUser::getDirectoryStorageClass(
// archive
//------------------------------------------------------------------------------
void cta::MockMiddleTierUser::archive(const SecurityIdentity &requester,
const std::list<std::string> &srcUrls, const std::string &dst) {
Utils::checkAbsolutePathSyntax(dst);
if(isAnExistingDirectory(dst)) {
return archiveToDirectory(requester, srcUrls, dst);
const std::list<std::string> &srcUrls, const std::string &dstPath) {
Utils::checkAbsolutePathSyntax(dstPath);
if(isAnExistingDirectory(dstPath)) {
return archiveToDirectory(requester, srcUrls, dstPath);
} else {
return archiveToFile(requester, srcUrls, dst);
return archiveToFile(requester, srcUrls, dstPath);
}
}
......@@ -258,8 +270,22 @@ void cta::MockMiddleTierUser::archiveToFile(
"archiving to a single destination file");
}
FileSystemNode &enclosingDirNode = getFileSystemNode(dstFile);
checkUserIsAuthorisedToArchive(requester, enclosingDirNode);
const std::string enclosingDir = Utils::getEnclosingDirPath(dstFile);
const std::string enclosedName = Utils::getEnclosedName(dstFile);
FileSystemNode &enclosingNode = getFileSystemNode(enclosingDir);
checkUserIsAuthorisedToArchive(requester, enclosingNode);
if(enclosingNode.childExists(enclosedName)) {
std::ostringstream message;
message << "A file or directory with the name " << enclosedName <<
" already exists";
throw Exception(message.str());
}
const std::string inheritedStorageClassName =
enclosingNode.getFileSystemEntry().getEntry().getStorageClassName();
DirectoryEntry dirEntry(DirectoryEntry::ENTRYTYPE_FILE, enclosedName,
inheritedStorageClassName);
enclosingNode.addChild(new FileSystemNode(m_db.storageClasses, dirEntry));
}
//------------------------------------------------------------------------------
......
......@@ -31,7 +31,7 @@ public:
*
* @param requester The identity of the user requesting the creation of the
* directory.
* @param dirPath The full path of the directory.
* @param dirPath The absolute path of the directory.
*/
void createDirectory(
const SecurityIdentity &requester,
......@@ -42,7 +42,7 @@ public:
*
* @param requester The identity of the user requesting the deletion of the
* directory.
* @param dirPath The full path of the directory.
* @param dirPath The absolute path of the directory.
*/
void deleteDirectory(
const SecurityIdentity &requester,
......@@ -53,13 +53,27 @@ public:
*
* @param requester The identity of the user requesting the contents of the
* directory.
* @param dirPath The full path of the directory.
* @param dirPath The absolute path of the directory.
* @return An iterator over the contents of the directory.
*/
DirectoryIterator getDirectoryContents(
const SecurityIdentity &requester,
const std::string &dirPath) const;
/**
* Returns the directory entry information for the specified directory or file
* within the archive namespace.
*
* @param requester The identity of the user requesting the directory entry.
* @param path The absolute path of the directory or file within the archive
* namespace.
* @return The directory entry information for the specified directory or file
* within the archive namespace.
*/
DirectoryEntry stat(
const SecurityIdentity &requester,
const std::string path) const;
/**
* Sets the storage class of the specified directory to the specified value.
*
......@@ -113,12 +127,13 @@ public:
*
* @param requester The identity of the user requesting the archival.
* @param srcUrls List of one or more source files.
* @param dst Destination file or directory within the archive namespace.
* @param dstPath The absolute path of the destination file or directory
* within the archive namespace.
*/
void archive(
const SecurityIdentity &requester,
const std::list<std::string> &srcUrls,
const std::string &dst);
const std::string &dstPath);
/**
* Returns all of the existing archival jobs grouped by tape pool and then
......@@ -149,7 +164,8 @@ public:
*
* @param requester The identity of the user requesting the deletion of the
* job.
* @param dstPath The full path of the destination file within the archive.
* @param dstPath The absolute path of the destination file within the
* archive namespace.
*/
void deleteArchivalJob(
const SecurityIdentity &requester,
......
......@@ -20,12 +20,12 @@ TEST_F(cta_client_MockMiddleTierUserTest,
using namespace cta;
MockDatabase db;
MockMiddleTierUser api(db);
MockMiddleTierUser userApi(db);
const SecurityIdentity requester;
const std::string dirPath = "/";
DirectoryIterator itor;
ASSERT_NO_THROW(itor = api.getDirectoryContents(requester, "/"));
ASSERT_NO_THROW(itor = userApi.getDirectoryContents(requester, "/"));
ASSERT_FALSE(itor.hasMore());
}
......@@ -33,11 +33,11 @@ TEST_F(cta_client_MockMiddleTierUserTest, createDirectory_empty_string) {
using namespace cta;
MockDatabase db;
MockMiddleTierUser api(db);
MockMiddleTierUser userApi(db);
const SecurityIdentity requester;
const std::string dirPath = "";
ASSERT_THROW(api.createDirectory(requester, dirPath), std::exception);
ASSERT_THROW(userApi.createDirectory(requester, dirPath), std::exception);
}
TEST_F(cta_client_MockMiddleTierUserTest,
......@@ -45,37 +45,37 @@ TEST_F(cta_client_MockMiddleTierUserTest,
using namespace cta;
MockDatabase db;
MockMiddleTierUser api(db);
MockMiddleTierUser userApi(db);
const SecurityIdentity requester;
const std::string dirPath = "//";
ASSERT_THROW(api.createDirectory(requester, dirPath), std::exception);
ASSERT_THROW(userApi.createDirectory(requester, dirPath), std::exception);
}
TEST_F(cta_client_MockMiddleTierUserTest, createDirectory_invalid_chars) {
using namespace cta;
MockDatabase db;
MockMiddleTierUser api(db);
MockMiddleTierUser userApi(db);
const SecurityIdentity requester;
const std::string dirPath = "/grandparent/?parent";
ASSERT_THROW(api.createDirectory(requester, dirPath), std::exception);
ASSERT_THROW(userApi.createDirectory(requester, dirPath), std::exception);
}
TEST_F(cta_client_MockMiddleTierUserTest, createDirectory_top_level) {
using namespace cta;
MockDatabase db;
MockMiddleTierUser api(db);
MockMiddleTierUser userApi(db);
const SecurityIdentity requester;
const std::string dirPath = "/grandparent";
ASSERT_NO_THROW(api.createDirectory(requester, dirPath));
ASSERT_NO_THROW(userApi.createDirectory(requester, dirPath));
DirectoryIterator itor;
ASSERT_NO_THROW(itor = api.getDirectoryContents(requester, "/"));
ASSERT_NO_THROW(itor = userApi.getDirectoryContents(requester, "/"));
ASSERT_TRUE(itor.hasMore());
......@@ -90,21 +90,21 @@ TEST_F(cta_client_MockMiddleTierUserTest, createDirectory_second_level) {
using namespace cta;
MockDatabase db;
MockMiddleTierUser api(db);
MockMiddleTierUser userApi(db);
const SecurityIdentity requester;
ASSERT_TRUE(api.getDirectoryStorageClass(requester, "/").empty());
ASSERT_TRUE(userApi.getDirectoryStorageClass(requester, "/").empty());
{
const std::string topLevelDirPath = "/grandparent";
ASSERT_NO_THROW(api.createDirectory(requester, topLevelDirPath));
ASSERT_NO_THROW(userApi.createDirectory(requester, topLevelDirPath));
}
{
DirectoryIterator itor;
ASSERT_NO_THROW(itor = api.getDirectoryContents(requester, "/"));
ASSERT_NO_THROW(itor = userApi.getDirectoryContents(requester, "/"));
ASSERT_TRUE(itor.hasMore());
......@@ -115,18 +115,18 @@ TEST_F(cta_client_MockMiddleTierUserTest, createDirectory_second_level) {
ASSERT_EQ(std::string("grandparent"), entry.getName());
}
ASSERT_TRUE(api.getDirectoryStorageClass(requester, "/grandparent").empty());
ASSERT_TRUE(userApi.getDirectoryStorageClass(requester, "/grandparent").empty());
{
const std::string secondLevelDirPath = "/grandparent/parent";
ASSERT_NO_THROW(api.createDirectory(requester, secondLevelDirPath));
ASSERT_NO_THROW(userApi.createDirectory(requester, secondLevelDirPath));
}
{
DirectoryIterator itor;
ASSERT_NO_THROW(itor = api.getDirectoryContents(requester, "/"));
ASSERT_NO_THROW(itor = userApi.getDirectoryContents(requester, "/"));
ASSERT_TRUE(itor.hasMore());
......@@ -140,7 +140,7 @@ TEST_F(cta_client_MockMiddleTierUserTest, createDirectory_second_level) {
{
DirectoryIterator itor;
ASSERT_NO_THROW(itor = api.getDirectoryContents(requester, "/grandparent"));
ASSERT_NO_THROW(itor = userApi.getDirectoryContents(requester, "/grandparent"));
ASSERT_TRUE(itor.hasMore());
......@@ -151,7 +151,7 @@ TEST_F(cta_client_MockMiddleTierUserTest, createDirectory_second_level) {
ASSERT_EQ(std::string("parent"), entry.getName());
}
ASSERT_TRUE(api.getDirectoryStorageClass(requester,
ASSERT_TRUE(userApi.getDirectoryStorageClass(requester,
"/grandparent/parent").empty());
}
......@@ -243,27 +243,27 @@ TEST_F(cta_client_MockMiddleTierUserTest, deleteDirectory_root) {
using namespace cta;
MockDatabase db;
MockMiddleTierUser api(db);
MockMiddleTierUser userApi(db);
const SecurityIdentity requester;
const std::string dirPath = "/";
ASSERT_THROW(api.deleteDirectory(requester, "/"), std::exception);
ASSERT_THROW(userApi.deleteDirectory(requester, "/"), std::exception);
}
TEST_F(cta_client_MockMiddleTierUserTest, deleteDirectory_existing_top_level) {
using namespace cta;
MockDatabase db;
MockMiddleTierUser api(db);
MockMiddleTierUser userApi(db);
const SecurityIdentity requester;
const std::string dirPath = "/grandparent";
ASSERT_NO_THROW(api.createDirectory(requester, dirPath));
ASSERT_NO_THROW(userApi.createDirectory(requester, dirPath));
{
DirectoryIterator itor;
ASSERT_NO_THROW(itor = api.getDirectoryContents(requester, "/"));
ASSERT_NO_THROW(itor = userApi.getDirectoryContents(requester, "/"));
ASSERT_TRUE(itor.hasMore());
......@@ -274,12 +274,12 @@ TEST_F(cta_client_MockMiddleTierUserTest, deleteDirectory_existing_top_level) {
ASSERT_EQ(std::string("grandparent"), entry.getName());
}
ASSERT_NO_THROW(api.deleteDirectory(requester, "/grandparent"));
ASSERT_NO_THROW(userApi.deleteDirectory(requester, "/grandparent"));
{
DirectoryIterator itor;
ASSERT_NO_THROW(itor = api.getDirectoryContents(requester, "/"));
ASSERT_NO_THROW(itor = userApi.getDirectoryContents(requester, "/"));
ASSERT_FALSE(itor.hasMore());
}
......@@ -290,17 +290,17 @@ TEST_F(cta_client_MockMiddleTierUserTest,
using namespace cta;
MockDatabase db;
MockMiddleTierUser api(db);
MockMiddleTierUser userApi(db);
const SecurityIdentity requester;
{
const std::string topLevelDirPath = "/grandparent";
ASSERT_NO_THROW(api.createDirectory(requester, topLevelDirPath));
ASSERT_NO_THROW(userApi.createDirectory(requester, topLevelDirPath));
DirectoryIterator itor;
ASSERT_NO_THROW(itor = api.getDirectoryContents(requester, "/"));
ASSERT_NO_THROW(itor = userApi.getDirectoryContents(requester, "/"));
ASSERT_TRUE(itor.hasMore());
......@@ -314,11 +314,11 @@ TEST_F(cta_client_MockMiddleTierUserTest,
{
const std::string secondLevelDirPath = "/grandparent/parent";
ASSERT_NO_THROW(api.createDirectory(requester, secondLevelDirPath));
ASSERT_NO_THROW(userApi.createDirectory(requester, secondLevelDirPath));
DirectoryIterator itor;
ASSERT_NO_THROW(itor = api.getDirectoryContents(requester, "/"));
ASSERT_NO_THROW(itor = userApi.getDirectoryContents(requester, "/"));
ASSERT_TRUE(itor.hasMore());
......@@ -332,7 +332,7 @@ TEST_F(cta_client_MockMiddleTierUserTest,
{
DirectoryIterator itor;
ASSERT_NO_THROW(itor = api.getDirectoryContents(requester, "/grandparent"));
ASSERT_NO_THROW(itor = userApi.getDirectoryContents(requester, "/grandparent"));
ASSERT_TRUE(itor.hasMore());
......@@ -343,12 +343,12 @@ TEST_F(cta_client_MockMiddleTierUserTest,
ASSERT_EQ(std::string("parent"), entry.getName());
}
ASSERT_THROW(api.deleteDirectory(requester, "/grandparent"), std::exception);
ASSERT_THROW(userApi.deleteDirectory(requester, "/grandparent"), std::exception);
{
DirectoryIterator itor;
ASSERT_NO_THROW(itor = api.getDirectoryContents(requester, "/grandparent"));
ASSERT_NO_THROW(itor = userApi.getDirectoryContents(requester, "/grandparent"));
ASSERT_TRUE(itor.hasMore());
......@@ -365,25 +365,25 @@ TEST_F(cta_client_MockMiddleTierUserTest,
using namespace cta;
MockDatabase db;
MockMiddleTierUser api(db);
MockMiddleTierUser userApi(db);
const SecurityIdentity requester;
ASSERT_THROW(api.deleteDirectory(requester, "/grandparent"), std::exception);
ASSERT_THROW(userApi.deleteDirectory(requester, "/grandparent"), std::exception);
}
TEST_F(cta_client_MockMiddleTierUserTest, setDirectoryStorageClass_top_level) {
using namespace cta;
MockDatabase db;
MockMiddleTierUser api(db);
MockMiddleTierUser userApi(db);
const SecurityIdentity requester;
const std::string dirPath = "/grandparent";
ASSERT_NO_THROW(api.createDirectory(requester, dirPath));
ASSERT_NO_THROW(userApi.createDirectory(requester, dirPath));
DirectoryIterator itor;
ASSERT_NO_THROW(itor = api.getDirectoryContents(requester, "/"));
ASSERT_NO_THROW(itor = userApi.getDirectoryContents(requester, "/"));
ASSERT_TRUE(itor.hasMore());
......@@ -395,7 +395,7 @@ TEST_F(cta_client_MockMiddleTierUserTest, setDirectoryStorageClass_top_level) {
{
std::string name;
ASSERT_NO_THROW(name = api.getDirectoryStorageClass(requester, dirPath));
ASSERT_NO_THROW(name = userApi.getDirectoryStorageClass(requester, dirPath));
ASSERT_TRUE(name.empty());
}
......@@ -408,12 +408,12 @@ TEST_F(cta_client_MockMiddleTierUserTest, setDirectoryStorageClass_top_level) {
nbCopies, comment));
}
ASSERT_NO_THROW(api.setDirectoryStorageClass(requester, dirPath,
ASSERT_NO_THROW(userApi.setDirectoryStorageClass(requester, dirPath,
storageClassName));
{
std::string name;
ASSERT_NO_THROW(name = api.getDirectoryStorageClass(requester, dirPath));
ASSERT_NO_THROW(name = userApi.getDirectoryStorageClass(requester, dirPath));
ASSERT_EQ(storageClassName, name);
}
}
......@@ -423,15 +423,15 @@ TEST_F(cta_client_MockMiddleTierUserTest,
using namespace cta;
MockDatabase db;
MockMiddleTierUser api(db);
MockMiddleTierUser userApi(db);
const SecurityIdentity requester;
const std::string dirPath = "/grandparent";
ASSERT_NO_THROW(api.createDirectory(requester, dirPath));
ASSERT_NO_THROW(userApi.createDirectory(requester, dirPath));
DirectoryIterator itor;
ASSERT_NO_THROW(itor = api.getDirectoryContents(requester, "/"));
ASSERT_NO_THROW(itor = userApi.getDirectoryContents(requester, "/"));
ASSERT_TRUE(itor.hasMore());
......@@ -443,7 +443,7 @@ TEST_F(cta_client_MockMiddleTierUserTest,
{
std::string name;
ASSERT_NO_THROW(name = api.getDirectoryStorageClass(requester, dirPath));
ASSERT_NO_THROW(name = userApi.getDirectoryStorageClass(requester, dirPath));
ASSERT_TRUE(name.empty());
}
......@@ -454,27 +454,124 @@ TEST_F(cta_client_MockMiddleTierUserTest,
ASSERT_NO_THROW(adminApi.createStorageClass(requester, storageClassName,
nbCopies, comment));
ASSERT_NO_THROW(api.setDirectoryStorageClass(requester, dirPath,
ASSERT_NO_THROW(userApi.setDirectoryStorageClass(requester, dirPath,
storageClassName));
{
std::string name;
ASSERT_NO_THROW(name = api.getDirectoryStorageClass(requester, dirPath));
ASSERT_NO_THROW(name = userApi.getDirectoryStorageClass(requester, dirPath));
ASSERT_EQ(storageClassName, name);
}
ASSERT_THROW(adminApi.deleteStorageClass(requester, storageClassName),
std::exception);
ASSERT_NO_THROW(api.clearDirectoryStorageClass(requester, dirPath));
ASSERT_NO_THROW(userApi.clearDirectoryStorageClass(requester, dirPath));
{
std::string name;
ASSERT_NO_THROW(name = api.getDirectoryStorageClass(requester, dirPath));
ASSERT_NO_THROW(name = userApi.getDirectoryStorageClass(requester, dirPath));
ASSERT_TRUE(name.empty());
}
ASSERT_NO_THROW(adminApi.deleteStorageClass(requester, storageClassName));
}
TEST_F(cta_client_MockMiddleTierUserTest, archive_new_file) {
using namespace cta;
MockDatabase db;
MockMiddleTierAdmin adminApi(db);
MockMiddleTierUser userApi(db);
const SecurityIdentity requester;
const std::string storageClassName = "TestStorageClass";
const uint8_t nbCopies = 1;
const std::string storageClassComment = "Storage-class omment";
ASSERT_NO_THROW(adminApi.createStorageClass(requester, storageClassName,
nbCopies, storageClassComment));
const std::string dirPath = "/grandparent";
ASSERT_NO_THROW(userApi.createDirectory(requester, dirPath));
{
DirectoryIterator itor;
ASSERT_NO_THROW(itor = userApi.getDirectoryContents(requester, "/"));
ASSERT_TRUE(itor.hasMore());
DirectoryEntry entry;
ASSERT_NO_THROW(entry = itor.next());
ASSERT_EQ(std::string("grandparent"), entry.getName());
}
{
std::string name;
ASSERT_NO_THROW(name = userApi.getDirectoryStorageClass(requester,
dirPath));
ASSERT_TRUE(name.empty());
}
ASSERT_NO_THROW(userApi.setDirectoryStorageClass(requester, dirPath,
storageClassName));
{
std::string name;
ASSERT_NO_THROW(name = userApi.getDirectoryStorageClass(requester,
dirPath));
ASSERT_EQ(storageClassName, name);
}
const std::string tapePoolName = "TestTapePool";
const uint16_t nbDrives = 1;
const uint16_t nbPartialTapes = 1;
const std::string tapePoolComment = "Tape-pool comment";
ASSERT_NO_THROW(adminApi.createTapePool(requester, tapePoolName, nbDrives,
nbPartialTapes, tapePoolComment));
const uint8_t copyNb = 1;
const std::string migrationRouteComment = "Migration-route comment";
ASSERT_NO_THROW(adminApi.createMigrationRoute(requester, storageClassName,
copyNb, tapePoolName, migrationRouteComment));
{
std::list<MigrationRoute> migrationRoutes;
ASSERT_NO_THROW(migrationRoutes = adminApi.getMigrationRoutes(requester));
ASSERT_EQ(1, migrationRoutes.size());
MigrationRoute migrationRoute;
ASSERT_NO_THROW(migrationRoute = migrationRoutes.front());
ASSERT_EQ(storageClassName, migrationRoute.getStorageClassName());
ASSERT_EQ(copyNb, migrationRoute.getCopyNb());
ASSERT_EQ(tapePoolName, migrationRoute.getTapePoolName());
}
std::list<std::string> srcUrls;
srcUrls.push_back("diskUrl");
const std::string dstPath = "/grandparent/parent_file";
ASSERT_NO_THROW(userApi.archive(requester, srcUrls, dstPath));
{
DirectoryIterator itor;
ASSERT_NO_THROW(itor = userApi.getDirectoryContents(requester, "/"));
ASSERT_TRUE(itor.hasMore());
DirectoryEntry entry;
ASSERT_NO_THROW(entry = itor.next());
ASSERT_EQ(std::string("grandparent"), entry.getName());
ASSERT_EQ(DirectoryEntry::ENTRYTYPE_DIRECTORY, entry.getType());
ASSERT_EQ(storageClassName, entry.getStorageClassName());
}
{