Ejemplo n.º 1
0
def test_checking():
    T = BlobTree(strdict())
    T.create_subtree("/sub", "meta")
    T.create_data("/sub/data", "meta")
    assert not T.is_data("/sub")
    assert T.is_dir("/sub")
    assert not T.is_dir("/sub/data")
    assert T.is_data("/sub/data")
Ejemplo n.º 2
0
def test_checking():
	T = BlobTree(strdict())
	T.create_subtree("/sub", "meta")
	T.create_data("/sub/data", "meta")
	assert not T.is_data("/sub")
	assert T.is_dir("/sub")
	assert not T.is_dir("/sub/data")
	assert T.is_data("/sub/data")
Ejemplo n.º 3
0
def test_rename():
	T = BlobTree(strdict())
	T.create_subtree("/sub", "meta")
	T.rename("/sub", "/dir")
	assert "dir" in T.list_dir("/")
	assert not "sub" in T.list_dir("/")
	# and again with changing directory
	T.create_data("/dir/sub", "meta")
	assert "sub" in T.list_dir("/dir")
	T.rename("/dir/sub", "/blub")
	assert "blub" in T.list_dir("/")
	assert not "sub" in T.list_dir("/dir")
Ejemplo n.º 4
0
def test_deletion():
	meta1 = "apple"
	meta2 = "microsoft"
	meta3 = "linux"
	T = BlobTree(strdict())
	T.create_subtree("/sub", meta1)
	T.create_subtree("/sub/sub", meta2)
	T.create_data("/sub/data", meta3)
	T.set_data("/sub/data", "some data")
	assert "sub" in T.list_dir("/")
	T.unlink("/sub")
	assert not "sub" in T.list_dir("/")
Ejemplo n.º 5
0
def test_deletion():
    meta1 = "apple"
    meta2 = "microsoft"
    meta3 = "linux"
    T = BlobTree(strdict())
    T.create_subtree("/sub", meta1)
    T.create_subtree("/sub/sub", meta2)
    T.create_data("/sub/data", meta3)
    T.set_data("/sub/data", "some data")
    assert "sub" in T.list_dir("/")
    T.unlink("/sub")
    assert not "sub" in T.list_dir("/")
Ejemplo n.º 6
0
def test_rename():
    T = BlobTree(strdict())
    T.create_subtree("/sub", "meta")
    T.rename("/sub", "/dir")
    assert "dir" in T.list_dir("/")
    assert not "sub" in T.list_dir("/")
    # and again with changing directory
    T.create_data("/dir/sub", "meta")
    assert "sub" in T.list_dir("/dir")
    T.rename("/dir/sub", "/blub")
    assert "blub" in T.list_dir("/")
    assert not "sub" in T.list_dir("/dir")
Ejemplo n.º 7
0
def test_basic():
	msg = "Hello Wörld! How are you?"
	meta_msg = "Söme meta data"
	T = BlobTree(strdict())
	T.create_data("/blub", meta_msg)
	T.set_data("/blub", msg)
	T.create_data("/second", "more meta data")
	assert meta_msg == T.get_meta_data("/blub")
	assert msg == T.get_data("/blub")
	print T.create_subtree("/sub", meta_msg)
	T.create_data("/sub/blub", meta_msg)
	T.set_data("/sub/blub", "some data")
	assert meta_msg == T.get_meta_data("/sub/blub")
Ejemplo n.º 8
0
def test_basic():
    msg = "Hello Wörld! How are you?"
    meta_msg = "Söme meta data"
    T = BlobTree(strdict())
    T.create_data("/blub", meta_msg)
    T.set_data("/blub", msg)
    T.create_data("/second", "more meta data")
    assert meta_msg == T.get_meta_data("/blub")
    assert msg == T.get_data("/blub")
    print T.create_subtree("/sub", meta_msg)
    T.create_data("/sub/blub", meta_msg)
    T.set_data("/sub/blub", "some data")
    assert meta_msg == T.get_meta_data("/sub/blub")
Ejemplo n.º 9
0
def test_meta_data():
	meta1 = "apple"
	meta2 = "microsoft"
	meta3 = "linux"
	T = BlobTree(strdict())
	T.create_subtree("/sub", meta1)
	T.create_subtree("/sub/sub", meta2)
	T.create_data("/sub/data", meta3)
	T.set_data("/sub/data", "some data")
	assert meta1 == T.get_meta_data("/sub")
	assert meta2 == T.get_meta_data("/sub/sub")
	assert meta3 == T.get_meta_data("/sub/data")

	T.set_meta_data("/sub/data", meta1)
	assert meta1 == T.get_meta_data("/sub/data")
Ejemplo n.º 10
0
def test_meta_data():
    meta1 = "apple"
    meta2 = "microsoft"
    meta3 = "linux"
    T = BlobTree(strdict())
    T.create_subtree("/sub", meta1)
    T.create_subtree("/sub/sub", meta2)
    T.create_data("/sub/data", meta3)
    T.set_data("/sub/data", "some data")
    assert meta1 == T.get_meta_data("/sub")
    assert meta2 == T.get_meta_data("/sub/sub")
    assert meta3 == T.get_meta_data("/sub/data")

    T.set_meta_data("/sub/data", meta1)
    assert meta1 == T.get_meta_data("/sub/data")
Ejemplo n.º 11
0
def test_dir():
	meta1 = "apple"
	T = BlobTree(strdict())
	T.create_subtree("/sub", meta1)
	T.create_subtree("/sub/sub", meta1)
	T.create_subtree("/sub/sub2", meta1)

	assert "sub" in T.list_dir("")
	assert "sub" in T.list_dir("/")
	assert "sub" in T.list_dir("/sub")
	assert "sub2" in T.list_dir("/sub")
Ejemplo n.º 12
0
def test_dir():
    meta1 = "apple"
    T = BlobTree(strdict())
    T.create_subtree("/sub", meta1)
    T.create_subtree("/sub/sub", meta1)
    T.create_subtree("/sub/sub2", meta1)

    assert "sub" in T.list_dir("")
    assert "sub" in T.list_dir("/")
    assert "sub" in T.list_dir("/sub")
    assert "sub2" in T.list_dir("/sub")
Ejemplo n.º 13
0
class KVFS:
    """A Key-Value-File-System
	This class is initialized with a key value store
	and implements a file system on top of it,
	providing methods like mkdir, create, read, write, ...
	
	In a failure case IOError gets raised.
	
	Some features like permissions or hardlinks are not yet supported."""
    def __init__(self, kv_store):
        self._bt = BlobTree(kv_store)
        m = _MetaData()
        m['st_mode'] = m['st_mode'] | stat.S_IFDIR
        self.root_meta = m

    def getattr(self, path):
        """returns the attributes of the object at `path`."""
        if path == "/":
            return self.root_meta
        try:
            return _MetaData(self._bt.get_meta_data(path))
        except KeyError:
            _raise_io(errno.ENOENT, path)

    def setattr(self, path, attr):
        """sets the attributes of the object at `path`."""
        if path == "/":
            _raise_io(errno.EPERM, path)
        try:
            self._bt.set_meta_data(path, attr)
        except (KeyError, IndexError):
            _raise_io(errno.ENOENT, path)

    def create(self, path):
        """create a file"""
        if self._bt.exists(path):
            _raise_io(errno.EEXIST, path)
        m = _MetaData()
        m['st_mode'] = m['st_mode'] | stat.S_IFREG
        m['st_size'] = 0
        self._bt.create_data(path, str(m))

    def mkdir(self, path):
        """creates a directory"""
        if self._bt.exists(path):
            _raise_io(errno.EEXIST, path)
        m = _MetaData()
        m['st_mode'] = m['st_mode'] | stat.S_IFDIR
        self._bt.create_subtree(path, str(m))

    def readdir(self, path):
        """read contents of a directory"""
        try:
            files = self._bt.list_dir(path)
        except KeyError:
            _raise_io(errno.ENOENT, path)
        yield '.'
        yield '..'
        for f in files:
            yield f

    def readlink(self, path):
        """resolves a symbolic link"""
        # TODO recursive?
        meta = self.getattr(path)
        try:
            return meta['symlink']
        except KeyError:
            _raise_io(errno.ENOLINK, path)

    def symlink(self, target, name):
        """create a symbolic link target->name"""
        if self._bt.exists(target):
            _raise_io(errno.EEXIST, target)
        m = _MetaData()
        # use attributes to save target and link property
        m['symlink'] = name
        m['st_mode'] = m['st_mode'] | stat.S_IFLNK
        self._bt.create_data(target, str(m))

    def remove(self, path):
        """removes a file or directory"""
        try:
            self._bt.unlink(path)
        except KeyError:
            _raise_io(errno.ENOENT, path)

    def rename(self, old, new):
        """rename a file (note that directories may change)"""
        try:
            self._bt.rename(old, new)
        except KeyError:
            _raise_io(errno.ENOENT, old)

    def link(self, target, name):
        """create a hardlink"""
        self._bt.create_data(target, self.getattr(name))
        self._bt.set_data(target, self._bt.get_data(name))
        # FIXME this is a copy, not a hardlink!
        # Subsequent changes won't be applied.
        # A transparent link blob type would be needed,
        # but that should rather be called a symlink.

    def _get_data(self, path):
        """get data from path or raise IOERROR"""
        try:
            return self._bt.get_data(path)
        except KeyError:
            _raise_io(errno.ENOENT, path)
        except TypeError:
            _raise_io(errno.EISDIR, path)

    def read(self, path, length=2000000000, offset=0):
        """read data from a file"""
        data = self._get_data(path)
        return data[offset:offset + length]

    def write(self, path, buf, offset=0):
        """write data to a file"""
        meta = self.getattr(path)
        if offset == 0 and len(buf) >= meta['st_size']:
            data = buf
        else:
            data = self._get_data(path)
            data = data[:offset] + buf + data[offset + len(buf):]
        meta['st_mtime'] = time.time()
        meta['st_size'] = len(data)
        self._bt.set_data(path, data, str(meta))

    def flush(self, path="/"):
        """clear all buffers, finish all pending operations"""
        self._bt.flush()

    def truncate(self, path, length):
        """truncate file to given length"""
        data = self._get_data(path)
        self._bt.set_data(path, data[:length])
Ejemplo n.º 14
0
class KVFS:
	"""A Key-Value-File-System
	This class is initialized with a key value store
	and implements a file system on top of it,
	providing methods like mkdir, create, read, write, ...
	
	In a failure case IOError gets raised.
	
	Some features like permissions or hardlinks are not yet supported."""
	def __init__(self, kv_store):
		self._bt = BlobTree(kv_store)
		m = _MetaData()
		m['st_mode'] = m['st_mode'] | stat.S_IFDIR
		self.root_meta = m

	def getattr(self, path):
		"""returns the attributes of the object at `path`."""
		if path == "/":
			return self.root_meta
		try:
			return _MetaData(self._bt.get_meta_data(path))
		except KeyError:
			_raise_io(errno.ENOENT, path)
			
	def setattr(self, path, attr):
		"""sets the attributes of the object at `path`."""
		if path == "/":
			_raise_io(errno.EPERM, path)
		try:
			self._bt.set_meta_data(path, attr)
		except (KeyError, IndexError):
			_raise_io(errno.ENOENT, path)

	def create(self, path):
		"""create a file"""
		if self._bt.exists(path):
			_raise_io(errno.EEXIST, path)
		m = _MetaData()
		m['st_mode'] = m['st_mode'] | stat.S_IFREG
		m['st_size'] = 0
		self._bt.create_data(path, str(m))

	def mkdir(self, path):
		"""creates a directory"""
		if self._bt.exists(path):
			_raise_io(errno.EEXIST, path)
		m = _MetaData()
		m['st_mode'] = m['st_mode'] | stat.S_IFDIR
		self._bt.create_subtree(path, str(m))

	def readdir(self, path):
		"""read contents of a directory"""
		try:
			files = self._bt.list_dir(path)
		except KeyError:
			_raise_io(errno.ENOENT, path)
		yield '.'
		yield '..'
		for f in files:
			yield f

	def readlink(self, path):
		"""resolves a symbolic link"""
		# TODO recursive?
		meta = self.getattr(path)
		try:
			return meta['symlink']
		except KeyError:
			_raise_io(errno.ENOLINK, path)

	def symlink(self, target, name):
		"""create a symbolic link target->name"""
		if self._bt.exists(target):
			_raise_io(errno.EEXIST, target)
		m = _MetaData()
		# use attributes to save target and link property
		m['symlink'] = name
		m['st_mode'] = m['st_mode'] | stat.S_IFLNK
		self._bt.create_data(target, str(m))
		
	def remove(self, path):
		"""removes a file or directory"""
		try:
			self._bt.unlink(path)
		except KeyError:
			_raise_io(errno.ENOENT, path)

	def rename(self, old, new):
		"""rename a file (note that directories may change)"""
		try:
			self._bt.rename(old, new)
		except KeyError:
			_raise_io(errno.ENOENT, old)

	def link(self, target, name):
		"""create a hardlink"""
		self._bt.create_data(target, self.getattr(name))
		self._bt.set_data(target, self._bt.get_data(name))
		# FIXME this is a copy, not a hardlink!
		# Subsequent changes won't be applied.
		# A transparent link blob type would be needed,
		# but that should rather be called a symlink.

	def _get_data(self, path):
		"""get data from path or raise IOERROR"""
		try:
			return self._bt.get_data(path)
		except KeyError:
			_raise_io(errno.ENOENT, path)
		except TypeError:
			_raise_io(errno.EISDIR, path)

	def read(self, path, length=2000000000, offset=0):
		"""read data from a file"""
		data = self._get_data(path)
		return data[offset:offset+length]

	def write(self, path, buf, offset=0):
		"""write data to a file"""
		meta = self.getattr(path)
		if offset==0 and len(buf) >= meta['st_size']:
			data = buf
		else:
			data = self._get_data(path)
			data = data[:offset] + buf + data[offset+len(buf):]
		meta['st_mtime'] = time.time()
		meta['st_size'] = len(data)
		self._bt.set_data(path, data, str(meta))

	def flush(self, path="/"):
		"""clear all buffers, finish all pending operations"""
		self._bt.flush()

	def truncate(self, path, length):
		"""truncate file to given length"""
		data = self._get_data(path)
		self._bt.set_data(path, data[:length])