Added unit test for validating quota exception behavior, fixed up the validation write within the driver itself.

This commit is contained in:
Kieran Brantner-Magee 2018-02-05 23:32:08 -08:00
Родитель 5f22817673
Коммит 86ca235ae2
2 изменённых файлов: 45 добавлений и 15 удалений

Просмотреть файл

@ -35,8 +35,6 @@ from requests import Session
executor = concurrent.futures.ThreadPoolExecutor(multiprocessing.cpu_count())
_prior_write_failure = False;
#import ptvsd
#ptvsd.enable_attach(secret='my_secret')
@ -101,8 +99,10 @@ class WriteInfo:
#logger.debug('updating %s range %d to %d', path, self.offset, self.offset+data_length-1)
self.files._files_service.update_range(self.files._azure_file_share_name, self.directory, self.filename, self.data, start_range=self.offset, end_range=self.offset+data_length-1)
except AzureHttpError as ahe:
self.files._prior_write_failure = True
raise
except Exception as e:
_prior_write_failure = True
logger.warning('error writing %s', str(e))
class FileCache:
@ -135,6 +135,8 @@ class AzureFiles(LoggingMixIn, Operations):
self._sas_token = sas_token.lstrip("?")
self._files_service = file.FileService(self._azure_storage_account_name, sas_token=self._sas_token, request_session=Session())
self._prior_write_failure = False
self.writes = deque()
self.dir_cache = {}
@ -500,7 +502,7 @@ class AzureFiles(LoggingMixIn, Operations):
# Take the write lock to see if we can coalesce
with self.file_cache[orig_path].append_write_lock:
found = False
if self.file_cache[orig_path].writes and not _prior_write_failure:
if self.file_cache[orig_path].writes and not self._prior_write_failure:
last = self.file_cache[orig_path].writes[-1]
if (not last.processing and
(last.offset + len(last.data)) == offset and
@ -515,16 +517,17 @@ class AzureFiles(LoggingMixIn, Operations):
# If we failed at some point (potentially in an async write) do this one immediately
# to see if the remote FS is functional and not hide the failure from the OS.
if _prior_write_failure:
wi.write()
_prior_write_failure = False
return data_length
if not self._prior_write_failure:
future = executor.submit(wi.write)
self.file_cache[orig_path].pending_writes.add(future)
def done(future):
self.file_cache[orig_path].pending_writes.remove(future)
future.add_done_callback(done)
future = executor.submit(wi.write)
self.file_cache[orig_path].pending_writes.add(future)
def done(future):
self.file_cache[orig_path].pending_writes.remove(future)
future.add_done_callback(done)
#Gotta do the "validation" write outside the append lock block.
if self._prior_write_failure:
wi.write()
self._prior_write_failure = False
# TODO: if we ever try to cache attrs, we would have to update the st_mtime.
return data_length

Просмотреть файл

@ -12,7 +12,6 @@ import azure.storage.file as file
from azure.storage.file import models
import os
# USEFUL LINKS FOR THESE TESTS:
# ERRNO http://man7.org/linux/man-pages/man3/errno.3.html
# requests status codes:https://github.com/kennethreitz/requests/blob/5524472cc76ea00d64181505f1fbb7f93f11cc2b/requests/status_codes.py
@ -55,7 +54,7 @@ with mock.patch.object(ctypes.util, 'find_library', side_effect=find_library_moc
class Test_azfilesfuse(unittest.TestCase):
STORAGE_ACCOUNT_NAME='crwilcoxmsftplayground'
STORAGE_ACCOUNT_SHARE='fusetests'
STORAGE_ACCOUNT_SAS_TOKEN=None
STORAGE_ACCOUNT_SAS_TOKEN='None'
def setUp(self):
# TODO: Verify Settings provided
@ -345,6 +344,34 @@ class Test_azfilesfuse(unittest.TestCase):
# TODO: verify fails if file handle isn't open for write. (RESPECT
# ATTRIBUTES OF OPEN, CURRENTLY WE DON'T
# For this test, set "quota" to be the size of the quota you've created.
def test_quota(self):
quota = 1250000000
delta = int(quota / 5) # an arbitrary amount to go under and then over the quota threshold to test it.
size = quota - delta
contents = b'a' * size
self.azure_fs.create_file_from_bytes(
self.STORAGE_ACCOUNT_SHARE, '', 'file.txt', b'best file content')
fd = self.fuse_driver.open('file.txt', 'w')
self.fuse_driver.write('file.txt', b'a', size - 1, fd)
self.fuse_driver.flush('file.txt')
self.assertEqual(
len(self.azure_fs.get_file_to_bytes(self.STORAGE_ACCOUNT_SHARE, '', 'file.txt').content),
size)
self.fuse_driver.write('file.txt', b'b', size + delta * 2, fd)
time.sleep(1)
# We expect the second write to fail visibly once the first async write has exceeded quota and failed silently.
with self.assertRaisesRegex(Exception, '\[Errno 28\] No space left on device'):
self.fuse_driver.write('file.txt', b'b', size + delta * 2, fd)
self.assertEqual(
len(self.azure_fs.get_file_to_bytes(self.STORAGE_ACCOUNT_SHARE, '', 'file.txt').content),
size)
def test_write_getattr_read(self):
# Created after https://github.com/crwilcox/AzureFilesFUSE/issues/10
self.fuse_driver.create('file.txt', None)