def test_create_and_delete_folder(self): """Test default functionality of create_folder and delete_folder methods. """ store = DefaultObjectStore() self.assertEqual(store.create_folder(BASE_DIRECTORY, identifier='A'), 'A') self.assertTrue(store.exists(store.join(BASE_DIRECTORY, 'A'))) self.assertTrue(os.path.isdir(os.path.join(BASE_DIRECTORY, 'A'))) identifier = store.create_folder(BASE_DIRECTORY) self.assertTrue(store.exists(store.join(BASE_DIRECTORY, identifier))) self.assertTrue(os.path.isdir(os.path.join(BASE_DIRECTORY, identifier))) # New store with short identifier factory store = DefaultObjectStore(identifier_factory=get_short_identifier) short_id = store.create_folder(BASE_DIRECTORY) self.assertTrue(store.exists(store.join(BASE_DIRECTORY, short_id))) self.assertTrue(os.path.isdir(os.path.join(BASE_DIRECTORY, short_id))) # Delete folder with identifier store.delete_folder(store.join(BASE_DIRECTORY, identifier)) self.assertFalse(store.exists(store.join(BASE_DIRECTORY, identifier))) self.assertFalse( os.path.isdir(os.path.join(BASE_DIRECTORY, identifier))) # Delete folder with short_id when the keep_deleted_files flag is True store = DefaultObjectStore(keep_deleted_files=True) store.delete_folder(store.join(BASE_DIRECTORY, short_id)) self.assertTrue(store.exists(store.join(BASE_DIRECTORY, short_id))) self.assertTrue(os.path.isdir(os.path.join(BASE_DIRECTORY, short_id))) # Delete folder 'A' overriding the keep_deleted_files flag self.assertTrue(store.exists(store.join(BASE_DIRECTORY, 'A'))) self.assertTrue(os.path.isdir(os.path.join(BASE_DIRECTORY, 'A'))) store.delete_folder(store.join(BASE_DIRECTORY, 'A'), force_delete=True) self.assertFalse(store.exists(store.join(BASE_DIRECTORY, 'A'))) self.assertFalse(os.path.isdir(os.path.join(BASE_DIRECTORY, 'A')))
def test_create_folder_repeat(self): """Test create folder with identifier factory that not always returns a unique identifier. """ store = DefaultObjectStore(identifier_factory=IdFactory( max_attempts=MAX_ATTEMPS - 1)) id1 = store.create_folder(BASE_DIRECTORY) id2 = store.create_folder(BASE_DIRECTORY) self.assertNotEqual(id1, id2) self.assertTrue(store.exists(store.join(BASE_DIRECTORY, id1))) self.assertTrue(store.exists(store.join(BASE_DIRECTORY, id2))) store.delete_folder(store.join(BASE_DIRECTORY, id1)) store.delete_folder(store.join(BASE_DIRECTORY, id2)) store = DefaultObjectStore(identifier_factory=IdFactory( max_attempts=MAX_ATTEMPS + 1)) id1 = store.create_folder(BASE_DIRECTORY) with self.assertRaises(RuntimeError): store.create_folder(BASE_DIRECTORY)
class OSViztrailRepository(ViztrailRepository): """Repository for viztrails. This implementation maintains all resources that are managed by the repository as objects in an object store. The base path is the identifier prefix for all managed resources. By default all resources are mantained as directories and files on the local file system. The viztrails index is a list object that contains the identifier of active viztrails. Folders and Resources --------------------- viztrails : List of active viztrails <vt-identifier>/ : Folder with resources for individual viztrail """ def __init__(self, base_path, object_store=None): """Initialize the repository from a configuration dictionary. Expects a dictionary that contains at least the base path for the repository. The definition of the object store is optional. If none is given the default object store will be used. Parameters --------- base_path: string Path to the base directory for viztrail resources object_store: vizier.core.io.base.ObjectStore, optional Store for objects that represent viztrail resources not """ # Raise an exception if the base directory argument is not given if base_path is None: raise ValueError('missing path for base directory') # Create the base directory if it does not exist self.base_path = base_path if not os.path.isdir(self.base_path): os.makedirs(self.base_path) # The object store element is optional. If not given the default object # store is used. if not object_store is None: self.object_store = object_store else: self.object_store = DefaultObjectStore() # Initialize the viztrails index. Create the index file if it does not # exist. self.viztrails_index = self.object_store.join(self.base_path, OBJ_VIZTRAILINDEX) if not self.object_store.exists(self.viztrails_index): self.object_store.create_object(parent_folder=self.base_path, identifier=OBJ_VIZTRAILINDEX, content=list()) # Load viztrails and intialize the remaining instance variables by # calling the constructor of the super class self.viztrails = dict() for identifier in self.object_store.read_object(self.viztrails_index): vt = OSViztrailHandle.load_viztrail( base_path=self.object_store.join(self.base_path, identifier), object_store=self.object_store) self.viztrails[vt.identifier] = vt def create_viztrail(self, properties=None): """Create a new viztrail. The initial set of properties is an optional dictionary of (key,value)-pairs where all values are expected to either be scalar values or a list of scalar values. Parameters ---------- properties: dict, optional Set of properties for the new viztrail Returns ------- vizier.viztrail.objectstore.viztrail.OSViztrailHandle """ # Get unique identifier for new viztrail and viztrail directory. Raise # runtime error if the returned identifier is not unique. identifier = self.object_store.create_folder( parent_folder=self.base_path) viztrail_path = self.object_store.join(self.base_path, identifier) # Create materialized viztrail resource vt = OSViztrailHandle.create_viztrail(identifier=identifier, properties=properties, base_path=viztrail_path, object_store=self.object_store) # Add the new resource to the viztrails index. Write updated index to # object store before returning the new viztrail handle self.viztrails[vt.identifier] = vt self.object_store.write_object( object_path=self.viztrails_index, content=[vt_id for vt_id in self.viztrails]) return vt def delete_viztrail(self, viztrail_id): """Delete the viztrail with given identifier. The result is True if a viztrail with the given identifier existed, False otherwise. Parameters ---------- viztrail_id : string Unique viztrail identifier Returns ------- bool """ # Get the viztrail handle if it exists if viztrail_id in self.viztrails: # Call the delete method of the OSViztrailHandle to delete the # files that are associated with the viztrail self.viztrails[viztrail_id].delete_viztrail() # Remove viztrail from the internal cache and write the updated # viztrails index del self.viztrails[viztrail_id] self.object_store.write_object( object_path=self.viztrails_index, content=[vt for vt in self.viztrails]) return True else: return False def get_viztrail(self, viztrail_id): """Retrieve the viztrail with the given identifier. The result is None if no viztrail with given identifier exists. Parameters ---------- viztrail_id : string Unique viztrail identifier Returns ------- vizier.viztrail.base.ViztrailHandle """ if viztrail_id in self.viztrails: return self.viztrails[viztrail_id] else: return None def list_viztrails(self): """List handles for all viztrails in the repository. Returns ------- list(vizier.viztrail.base.ViztrailHandle) """ return list(self.viztrails.values())