""" test File Plugin """ from __future__ import print_function from __future__ import absolute_import from __future__ import division import mock import unittest import tempfile import os import shutil import errno from DIRAC import S_OK from DIRAC.Resources.Storage.StorageElement import StorageElementItem def mock_StorageFactory_getConfigStorageName(storageName, referenceType, seConfigPath=None): resolvedName = storageName return S_OK(resolvedName) def mock_StorageFactory_getConfigStorageOptions(storageName, derivedStorageName=None, seConfigPath=None): """Get the options associated to the StorageElement as defined in the CS""" optionsDict = { "BackendType": "local", "ReadAccess": "Active", "WriteAccess": "Active", "AccessProtocols": ["file"], "WriteProtocols": ["file"], } return S_OK(optionsDict) def mock_StorageFactory_getConfigStorageProtocols(storageName, derivedStorageName=None, seConfigPath=None): """Protocol specific information is present as sections in the Storage configuration""" protocolDetails = { "Section": { "Host": "", "Path": "/tmp/se", "PluginName": "File", "Port": "", "Protocol": "file", "SpaceToken": "", "WSUrl": "", } } return S_OK(protocolDetails) class TestBase(unittest.TestCase): """Base test class. Defines all the method to test""" @mock.patch( "DIRAC.Resources.Storage.StorageFactory.StorageFactory._getConfigStorageName", side_effect=mock_StorageFactory_getConfigStorageName, ) @mock.patch( "DIRAC.Resources.Storage.StorageFactory.StorageFactory._getConfigStorageOptions", side_effect=mock_StorageFactory_getConfigStorageOptions, ) @mock.patch( "DIRAC.Resources.Storage.StorageFactory.StorageFactory._getConfigStorageProtocols", side_effect=mock_StorageFactory_getConfigStorageProtocols, ) @mock.patch( "DIRAC.Resources.Storage.StorageElement.StorageElementItem._StorageElementItem__isLocalSE", return_value=S_OK(True), ) # Pretend it's local @mock.patch( "DIRAC.Resources.Storage.StorageElement.StorageElementItem.addAccountingOperation", return_value=None ) # Don't send accounting def setUp( self, mk_getConfigStorageName, mk_getConfigStorageOptions, mk_getConfigStorageProtocols, mk_isLocalSE, mk_addAccountingOperation, ): self.se = StorageElementItem("FAKE") self.se.vo = "test" self.basePath = tempfile.mkdtemp(dir="/tmp") # Update the basePath of the plugin self.se.storages[0].basePath = self.basePath self.srcPath = tempfile.mkdtemp(dir="/tmp") self.destPath = tempfile.mkdtemp(dir="/tmp") self.existingFile = "/test/file.txt" self.existingFileSize = 0 self.nonExistingFile = "/test/nonExistingFile.txt" self.subDir = "/test/subDir" self.subFile = os.path.join(self.subDir, "subFile.txt") self.subFileSize = 0 self.FILES = [self.existingFile, self.nonExistingFile, self.subFile] self.DIRECTORIES = [self.subDir] self.ALL = self.FILES + self.DIRECTORIES with open(os.path.join(self.srcPath, self.existingFile.replace("/test/", "")), "w") as f: f.write("I put something in the file so that it has a size\n") self.existingFileSize = os.path.getsize(os.path.join(self.srcPath, self.existingFile.replace("/test/", ""))) assert self.existingFileSize os.mkdir(os.path.join(self.srcPath, os.path.basename(self.subDir))) with open(os.path.join(self.srcPath, self.subFile.replace("/test/", "")), "w") as f: f.write("This one should have a size as well\n") self.subFileSize = os.path.getsize(os.path.join(self.srcPath, self.subFile.replace("/test/", ""))) assert self.subFileSize def tearDown(self): shutil.rmtree(self.basePath) shutil.rmtree(self.srcPath) shutil.rmtree(self.destPath) pass def walkAll(self): for dirname in [self.basePath, self.destPath]: self.walkPath(dirname) def walkPath(self, path): for root, dirs, files in os.walk(path): print(root) print(" dirs") for d in dirs: print(" ", os.path.join(root, d)) print(" files") for f in files: print(" ", os.path.join(root, f)) @mock.patch( "DIRAC.Resources.Storage.StorageElement.StorageElementItem._StorageElementItem__isLocalSE", return_value=S_OK(True), ) # Pretend it's local @mock.patch( "DIRAC.Resources.Storage.StorageElement.StorageElementItem.addAccountingOperation", return_value=None ) # Don't send accounting def test_01_getURL(self, mk_isLocalSE, mk_addAccounting): """Testing getURL""" # Testing the getURL res = self.se.getURL(self.ALL) self.assertTrue(res["OK"], res) self.assertTrue(not res["Value"]["Failed"], res["Value"]["Failed"]) self.assertTrue(len(res["Value"]["Successful"]) == len(self.ALL)) for lfn, url in res["Value"]["Successful"].items(): self.assertEqual(url, self.basePath.rstrip("/") + lfn) @mock.patch( "DIRAC.Resources.Storage.StorageElement.StorageElementItem._StorageElementItem__isLocalSE", return_value=S_OK(True), ) # Pretend it's local @mock.patch( "DIRAC.Resources.Storage.StorageElement.StorageElementItem.addAccountingOperation", return_value=None ) # Don't send accounting def test_02_FileTest(self, mk_isLocalSE, mk_addAccounting): """Testing createDirectory""" # Putting the files def localPutFile(fn, size=0): """If fn is '/test/fn.txt', it calls { '/test/fn.txt' : /tmp/generatedPath/fn.txt} """ transfDic = {fn: os.path.join(self.srcPath, fn.replace("/test/", ""))} return self.se.putFile(transfDic, sourceSize=size) # wrong size res = localPutFile(self.existingFile, size=-1) self.assertTrue(res["OK"], res) self.assertTrue(self.existingFile in res["Value"]["Failed"], res) self.assertTrue("not match" in res["Value"]["Failed"][self.existingFile], res) self.assertTrue(not os.path.exists(self.basePath + self.existingFile)) # Correct size res = localPutFile(self.existingFile, size=self.existingFileSize) self.assertTrue(res["OK"], res) self.assertTrue(self.existingFile in res["Value"]["Successful"], res) self.assertTrue(os.path.exists(self.basePath + self.existingFile)) # No size res = localPutFile(self.existingFile) self.assertTrue(res["OK"], res) self.assertTrue(self.existingFile in res["Value"]["Successful"], res) self.assertTrue(os.path.exists(self.basePath + self.existingFile)) # No existing source file res = localPutFile(self.nonExistingFile) self.assertTrue(res["OK"], res) self.assertTrue(self.nonExistingFile in res["Value"]["Failed"], res) self.assertTrue(os.strerror(errno.ENOENT) in res["Value"]["Failed"][self.nonExistingFile], res) # sub file res = localPutFile(self.subFile) self.assertTrue(res["OK"], res) self.assertTrue(self.subFile in res["Value"]["Successful"], res) self.assertTrue(os.path.exists(self.basePath + self.subFile)) # Directory res = localPutFile(self.subDir) self.assertTrue(res["OK"], res) self.assertTrue(self.subDir in res["Value"]["Failed"]) self.assertTrue( os.strerror(errno.EISDIR) in res["Value"]["Failed"][self.subDir] or # Python 3.9.7+ improved the Exception that is raised "Directory does not exist" in res["Value"]["Failed"][self.subDir], res, ) res = self.se.exists(self.FILES) self.assertTrue(res["OK"], res) self.assertTrue(not res["Value"]["Failed"], res) self.assertTrue(res["Value"]["Successful"][self.existingFile], res) self.assertTrue(not res["Value"]["Successful"][self.nonExistingFile], res) res = self.se.getFileSize(self.ALL) self.assertTrue(res["OK"], res) self.assertEqual(res["Value"]["Successful"][self.existingFile], self.existingFileSize) self.assertTrue(os.strerror(errno.ENOENT) in res["Value"]["Failed"][self.nonExistingFile], res) self.assertTrue(os.strerror(errno.EISDIR) in res["Value"]["Failed"][self.subDir], res) res = self.se.getFileMetadata(self.ALL) self.assertTrue(res["OK"], res) self.assertTrue(self.existingFile in res["Value"]["Successful"]) self.assertTrue(os.strerror(errno.ENOENT) in res["Value"]["Failed"][self.nonExistingFile], res) self.assertTrue(os.strerror(errno.EISDIR) in res["Value"]["Failed"][self.subDir], res) res = self.se.isFile(self.ALL) self.assertTrue(res["OK"], res) self.assertTrue(res["Value"]["Successful"][self.existingFile], res) self.assertTrue(not res["Value"]["Successful"][self.subDir], res) self.assertTrue(os.strerror(errno.ENOENT) in res["Value"]["Failed"][self.nonExistingFile], res) res = self.se.getFile(self.ALL, localPath=self.destPath) self.assertTrue(res["OK"], res) self.assertEqual(res["Value"]["Successful"][self.existingFile], self.existingFileSize) self.assertTrue(os.path.exists(os.path.join(self.destPath, os.path.basename(self.existingFile)))) self.assertEqual(res["Value"]["Successful"][self.subFile], self.subFileSize) self.assertTrue(os.path.exists(os.path.join(self.destPath, os.path.basename(self.subFile)))) self.assertTrue(os.strerror(errno.ENOENT) in res["Value"]["Failed"][self.nonExistingFile], res) self.assertTrue( os.strerror(errno.EISDIR) in res["Value"]["Failed"][self.subDir] or # Python 3.9.7+ improved the Exception that is raised "Directory does not exist" in res["Value"]["Failed"][self.subDir], res, ) res = self.se.removeFile(self.ALL) self.assertTrue(res["OK"], res) self.assertTrue(res["Value"]["Successful"][self.existingFile]) self.assertTrue(not os.path.exists(self.basePath + self.existingFile)) self.assertTrue(res["Value"]["Successful"][self.subFile]) self.assertTrue(not os.path.exists(self.basePath + self.subFile)) self.assertTrue(res["Value"]["Successful"][self.nonExistingFile]) self.assertTrue(os.strerror(errno.EISDIR) in res["Value"]["Failed"][self.subDir]) @mock.patch( "DIRAC.Resources.Storage.StorageElement.StorageElementItem._StorageElementItem__isLocalSE", return_value=S_OK(True), ) # Pretend it's local @mock.patch( "DIRAC.Resources.Storage.StorageElement.StorageElementItem.addAccountingOperation", return_value=None ) # Don't send accounting def test_03_createDirectory(self, mk_isLocalSE, mk_addAccounting): """Testing creating directories""" res = self.se.createDirectory(self.subDir) self.assertTrue(res["OK"], res) self.assertTrue(self.subDir in res["Value"]["Successful"]) self.assertTrue(os.path.exists(self.basePath + self.subDir)) @mock.patch( "DIRAC.Resources.Storage.StorageElement.StorageElementItem._StorageElementItem__isLocalSE", return_value=S_OK(True), ) # Pretend it's local @mock.patch( "DIRAC.Resources.Storage.StorageElement.StorageElementItem.addAccountingOperation", return_value=None ) # Don't send accounting def test_04_putDirectory(self, mk_isLocalSE, mk_addAccounting): """Testing putDirectory""" nonExistingDir = "/test/forsuredoesnotexist" localdirs = ["/test", nonExistingDir] # Correct size res = self.se.putDirectory({"/test": self.srcPath}) self.assertTrue(res["OK"], res) self.assertTrue("/test" in res["Value"]["Successful"], res) self.assertEqual( res["Value"]["Successful"]["/test"], {"Files": 2, "Size": self.existingFileSize + self.subFileSize} ) self.assertTrue(os.path.exists(self.basePath + "/test")) self.assertTrue(os.path.exists(self.basePath + self.existingFile)) self.assertTrue(os.path.exists(self.basePath + self.subFile)) # No existing source directory res = self.se.putDirectory({"/test": nonExistingDir}) self.assertTrue(res["OK"], res) self.assertTrue("/test" in res["Value"]["Failed"], res) self.assertEqual(res["Value"]["Failed"]["/test"], {"Files": 0, "Size": 0}) # sub file res = self.se.putDirectory({"/test": self.existingFile}) self.assertTrue(res["OK"], res) self.assertTrue("/test" in res["Value"]["Failed"], res) self.assertEqual(res["Value"]["Failed"]["/test"], {"Files": 0, "Size": 0}) res = self.se.exists(self.DIRECTORIES + localdirs) self.assertTrue(res["OK"], res) self.assertTrue(not res["Value"]["Failed"], res) self.assertTrue(res["Value"]["Successful"][self.subDir], res) self.assertTrue(not res["Value"]["Successful"][nonExistingDir], res) res = self.se.getDirectorySize(self.ALL + localdirs) self.assertTrue(res["OK"], res) self.assertEqual(res["Value"]["Successful"][self.subDir], {"Files": 1, "Size": self.subFileSize, "SubDirs": 0}) self.assertEqual(res["Value"]["Successful"]["/test"], {"Files": 1, "Size": self.existingFileSize, "SubDirs": 1}) self.assertTrue(os.strerror(errno.ENOENT) in res["Value"]["Failed"][self.nonExistingFile], res) self.assertTrue(os.strerror(errno.ENOTDIR) in res["Value"]["Failed"][self.existingFile], res) self.assertTrue(os.strerror(errno.ENOENT) in res["Value"]["Failed"][nonExistingDir], res) res = self.se.getDirectoryMetadata(self.ALL + localdirs) self.assertTrue(res["OK"], res) self.assertTrue(self.subDir in res["Value"]["Successful"]) self.assertTrue(os.strerror(errno.ENOENT) in res["Value"]["Failed"][self.nonExistingFile], res) self.assertTrue(os.strerror(errno.ENOENT) in res["Value"]["Failed"][nonExistingDir], res) self.assertTrue(os.strerror(errno.ENOTDIR) in res["Value"]["Failed"][self.existingFile], res) res = self.se.isDirectory(self.ALL + localdirs) self.assertTrue(res["OK"], res) self.assertTrue(not res["Value"]["Successful"][self.existingFile]) self.assertTrue(res["Value"]["Successful"][self.subDir], res) self.assertTrue(os.strerror(errno.ENOENT) in res["Value"]["Failed"][self.nonExistingFile], res) self.assertTrue(os.strerror(errno.ENOENT) in res["Value"]["Failed"][nonExistingDir], res) res = self.se.listDirectory(self.ALL + localdirs) self.assertTrue(res["OK"], res) self.assertEqual(res["Value"]["Successful"][self.subDir], {"Files": [self.subFile], "SubDirs": []}) self.assertEqual(res["Value"]["Successful"]["/test"], {"Files": [self.existingFile], "SubDirs": [self.subDir]}) self.assertTrue(os.strerror(errno.ENOENT) in res["Value"]["Failed"][self.nonExistingFile], res) self.assertTrue(os.strerror(errno.ENOTDIR) in res["Value"]["Failed"][self.existingFile], res) self.assertTrue(os.strerror(errno.ENOENT) in res["Value"]["Failed"][nonExistingDir], res) res = self.se.getDirectory(self.ALL + localdirs, localPath=self.destPath) self.assertTrue(res["OK"], res) self.assertEqual( res["Value"]["Successful"]["/test"], {"Files": 2, "Size": self.existingFileSize + self.subFileSize} ) self.assertTrue(os.path.exists(self.destPath + self.existingFile)) self.assertTrue(os.path.exists(self.destPath + self.subFile)) self.assertEqual(res["Value"]["Successful"][self.subDir], {"Files": 1, "Size": self.subFileSize}) self.assertTrue(os.path.exists(self.destPath + self.subFile.replace("/test", ""))) self.assertEqual(res["Value"]["Failed"][self.nonExistingFile], {"Files": 0, "Size": 0}) self.assertEqual(res["Value"]["Failed"][self.existingFile], {"Files": 0, "Size": 0}) self.assertEqual(res["Value"]["Failed"][nonExistingDir], {"Files": 0, "Size": 0}) res = self.se.removeDirectory(nonExistingDir, recursive=False) self.assertTrue(res["OK"], res) self.assertEqual(res["Value"]["Successful"][nonExistingDir], True) res = self.se.removeDirectory(nonExistingDir, recursive=True) self.assertTrue(res["OK"], res) self.assertEqual(res["Value"]["Failed"][nonExistingDir], {"FilesRemoved": 0, "SizeRemoved": 0}) res = self.se.removeDirectory(self.nonExistingFile, recursive=False) self.assertTrue(res["OK"], res) self.assertEqual(res["Value"]["Successful"][self.nonExistingFile], True) res = self.se.removeDirectory(self.nonExistingFile, recursive=True) self.assertTrue(res["OK"], res) self.assertEqual(res["Value"]["Failed"][self.nonExistingFile], {"FilesRemoved": 0, "SizeRemoved": 0}) res = self.se.removeDirectory(self.existingFile, recursive=False) self.assertTrue(res["OK"], res) self.assertTrue(os.strerror(errno.ENOTDIR) in res["Value"]["Failed"][self.existingFile], res) res = self.se.removeDirectory(self.existingFile, recursive=True) self.assertTrue(res["OK"], res) self.assertEqual(res["Value"]["Failed"][self.existingFile], {"FilesRemoved": 0, "SizeRemoved": 0}) res = self.se.removeDirectory("/test", recursive=False) self.assertTrue(res["OK"], res) self.assertEqual(res["Value"]["Successful"]["/test"], True) self.assertTrue(not os.path.exists(self.basePath + self.existingFile)) self.assertTrue(os.path.exists(self.basePath + self.subFile)) res = self.se.removeDirectory("/test", recursive=True) self.assertTrue(res["OK"], res) self.assertEqual(res["Value"]["Successful"]["/test"], {"FilesRemoved": 1, "SizeRemoved": self.subFileSize}) self.assertTrue(not os.path.exists(self.basePath + "/test")) if __name__ == "__main__": suite = unittest.defaultTestLoader.loadTestsFromTestCase(TestBase) unittest.TextTestRunner(verbosity=2).run(suite)